diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000000..663bd28c4d --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +/target +/.project +/.settings +/.classpath +/.idea +*.iml + diff --git a/README.md b/README.md new file mode 100755 index 0000000000..a82fded8aa --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# fastjson + +Fast JSON Processor + +![](logo.jpg) + +## Documentation +https://github.com/alibaba/fastjson/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98 + +## Benchmark +https://github.com/eishay/jvm-serializers/wiki + + +## Download +http://repo1.maven.org/maven2/com/alibaba/fastjson/ + + +## Maven + + + com.alibaba + fastjson + x.x.x + + diff --git a/license.txt b/license.txt new file mode 100644 index 0000000000..696c2a748c --- /dev/null +++ b/license.txt @@ -0,0 +1,13 @@ +Copyright 1999-2013 Alibaba Group Holding Ltd. + +Licensed 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. \ No newline at end of file diff --git a/logo.jpg b/logo.jpg new file mode 100644 index 0000000000..4686206f2f Binary files /dev/null and b/logo.jpg differ diff --git a/pom.xml b/pom.xml old mode 100644 new mode 100755 index c2a4409664..863c1af631 --- a/pom.xml +++ b/pom.xml @@ -1,181 +1,309 @@ - - 4.0.0 - com.alibaba - fastjson - 1.1.2-SNAPSHOT - fastjson - - - UTF-8 - - - - - wenshao - wenshao - szujobs@hotmail.com - - - - - - opensesame - dav:http://code.alibabatech.com/mvn/releases/ - - - opensesame - dav:http://code.alibabatech.com/mvn/snapshots/ - - - - - Alibaba Group - http://code.alibabatech.com/ - - - - - org.apache.maven.wagon - wagon-webdav - 1.0-beta-2 - - - - - org.apache.maven.plugins - maven-compiler-plugin - - UTF-8 - 1.5 - 1.5 - - - - - org.apache.maven.plugins - maven-source-plugin - 2.1.1 - - - attach-sources - - jar-no-fork - - - - - true - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - **/bvt/**/*.java - - - - - - - - - central - released internal lib - http://repo2.maven.org/maven2/ - - false - - - - gson - gson - http://google-gson.googlecode.com/svn/mavenrepo - - false - - - - jackson - jackson - http://repository.codehaus.org/ - - false - - - - maven2-repository.java.net - Java.net Repository for Maven - http://download.java.net/maven/2/ - default - - - - - - - org.codehaus.jackson - jackson-core-lgpl - 1.8.1 - test - - - org.codehaus.jackson - jackson-mapper-lgpl - 1.8.1 - test - - - org.codehaus.jackson - jackson-jaxrs - 1.8.1 - test - - - org.codehaus.jackson - jackson-smile - 1.8.1 - test - - - commons-io - commons-io - 1.4 - test - - - com.googlecode.json-simple - json-simple - 1.1 - test - - - net.sf.json-lib - json-lib - 2.4 - jdk15 - test - - - junit - junit - 4.5 - test - - - com.google.code.gson - gson - 1.6 - test - - - net.minidev - json-smart - 1.0.6.3 - test - - - \ No newline at end of file + + + 4.0.0 + + + com.alibaba + fastjson + 1.2.4 + + jar + fastjson + Fastjson is a JSON processor (JSON parser + JSON generator) written in Java + + https://github.com/alibaba/fastjson + 2012 + + + 4.11 + false + false + UTF-8 + 1.5 + + + + + wenshao + wenshao + szujobs@hotmail.com + + + axmanwang + axmanwang + iamaxman@hotmail.com + + + + + https://wenshao@github.com/alibaba/fastjson.git + scm:git:https://wenshao@github.com/alibaba/fastjson.git + + + + + + Alibaba Group + http://code.alibabatech.com/ + + + + + Apache 2 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + A business-friendly OSS license + + + + + + + org.apache.maven.wagon + wagon-webdav + 1.0-beta-2 + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 2.5.1 + + UTF-8 + ${jdk.version} + ${jdk.version} + + + + org.codehaus.plexus + plexus-compiler-javac + 1.8.1 + + + + + + org.apache.maven.plugins + maven-source-plugin + 2.1.1 + + + attach-sources + + jar-no-fork + + + + + true + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/bvt/**/*.java + + + + + + maven-javadoc-plugin + + + attach-javadoc + + jar + + + + + ${javadoc.skip} + public + UTF-8 + UTF-8 + UTF-8 + + http://docs.oracle.com/javase/6/docs/api + + + + + + maven-gpg-plugin + + ${gpg.skip} + + + + sign-artifacts + verify + + sign + + + + + + + + + + javax.servlet + servlet-api + 2.5 + provided + true + + + javax.ws.rs + jsr311-api + 1.1.1 + provided + true + + + org.springframework + spring-webmvc + 3.2.2.RELEASE + provided + true + + + com.aliyun.odps + odps-sdk-udf + 0.13.0 + provided + true + + + + junit + junit + ${junit.version} + test + + + + com.fasterxml.jackson.core + jackson-databind + 2.4.2 + test + + + + cglib + cglib-nodep + 2.2.2 + test + + + + org.codehaus.jackson + jackson-jaxrs + 1.9.13 + test + + + org.codehaus.jackson + jackson-smile + 1.9.13 + test + + + com.googlecode.json-simple + json-simple + 1.1 + test + + + + commons-io + commons-io + 1.4 + test + + + + net.sf.json-lib + json-lib + 2.4 + jdk15 + test + + + xom + xom + 1.2.5 + test + + + + com.google.code.gson + gson + 2.3 + test + + + net.minidev + json-smart + 1.1.1 + test + + + com.owlike + genson + 0.97 + test + + + + org.clojure + clojure + 1.5.1 + test + + + org.codehaus.groovy + groovy + 2.1.5 + test + + + + org.springframework + spring-test + 3.2.3.RELEASE + test + + + org.javassist + javassist + 3.18.0-GA + test + + + + diff --git a/rfc4627.txt b/rfc4627.txt old mode 100644 new mode 100755 diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100755 index 0000000000..b8c791063b --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.1.35 +Class-Path: + diff --git a/src/main/java/com/alibaba/fastjson/JSON.java b/src/main/java/com/alibaba/fastjson/JSON.java old mode 100644 new mode 100755 index ddbb6c3c79..510184f411 --- a/src/main/java/com/alibaba/fastjson/JSON.java +++ b/src/main/java/com/alibaba/fastjson/JSON.java @@ -1,463 +1,741 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson; - -import java.io.IOException; -import java.lang.reflect.Array; -import java.lang.reflect.Method; -import java.lang.reflect.Type; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.CharsetDecoder; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.DefaultJSONParser; -import com.alibaba.fastjson.parser.Feature; -import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.serializer.JSONSerializer; -import com.alibaba.fastjson.serializer.JavaBeanSerializer; -import com.alibaba.fastjson.serializer.SerializeConfig; -import com.alibaba.fastjson.serializer.SerializeWriter; -import com.alibaba.fastjson.serializer.SerializerFeature; -import com.alibaba.fastjson.util.FieldInfo; -import com.alibaba.fastjson.util.IOUtils; -import com.alibaba.fastjson.util.ThreadLocalCache; -import com.alibaba.fastjson.util.TypeUtils; -import com.alibaba.fastjson.util.UTF8Decoder; - -/** - * @author wenshao - */ -public abstract class JSON implements JSONStreamAware, JSONAware { - - public static final int DEFAULT_PARSER_FEATURE; - static { - int features = 0; - features |= Feature.AutoCloseSource.getMask(); - features |= Feature.InternFieldNames.getMask(); - features |= Feature.UseBigDecimal.getMask(); - features |= Feature.AllowUnQuotedFieldNames.getMask(); - features |= Feature.AllowSingleQuotes.getMask(); - features |= Feature.AllowArbitraryCommas.getMask(); - features |= Feature.SortFeidFastMatch.getMask(); - features |= Feature.IgnoreNotMatch.getMask(); - DEFAULT_PARSER_FEATURE = features; - } - - public static final int DEFAULT_GENERATE_FEATURE; - static { - int features = 0; - features |= com.alibaba.fastjson.serializer.SerializerFeature.QuoteFieldNames.getMask(); - features |= com.alibaba.fastjson.serializer.SerializerFeature.SkipTransientField.getMask(); - features |= com.alibaba.fastjson.serializer.SerializerFeature.SortField.getMask(); - DEFAULT_GENERATE_FEATURE = features; - } - - public static final Object parse(String text) { - return parse(text, DEFAULT_PARSER_FEATURE); - } - - public static final Object parse(String text, int features) { - if (text == null) { - return null; - } - - DefaultJSONParser parser = new DefaultJSONParser(text, ParserConfig.getGlobalInstance(), features); - Object value = parser.parse(); - - parser.close(); - - return value; - } - - public static final Object parse(byte[] input, Feature... features) { - return parse(input, 0, input.length, UTF8_CharsetEncoder, features); - } - - public static final Object parse(byte[] input, int off, int len, CharsetDecoder charsetDecoder, Feature... features) { - if (input == null || input.length == 0) { - return null; - } - - int featureValues = DEFAULT_PARSER_FEATURE; - for (Feature featrue : features) { - featureValues = Feature.config(featureValues, featrue, true); - } - - return parse(input, off, len, charsetDecoder, featureValues); - } - - public static final Object parse(byte[] input, int off, int len, CharsetDecoder charsetDecoder, int features) { - charsetDecoder.reset(); - - int scaleLength = (int) (len * (double) charsetDecoder.maxCharsPerByte()); - char[] chars = ThreadLocalCache.getChars(scaleLength); - - ByteBuffer byteBuf = ByteBuffer.wrap(input, off, len); - CharBuffer charBuf = CharBuffer.wrap(chars); - IOUtils.decode(charsetDecoder, byteBuf, charBuf); - - int position = charBuf.position(); - - DefaultJSONParser parser = new DefaultJSONParser(chars, position, ParserConfig.getGlobalInstance(), features); - Object value = parser.parse(); - - parser.close(); - - return value; - } - - public static final Object parse(String text, Feature... features) { - int featureValues = DEFAULT_PARSER_FEATURE; - for (Feature featrue : features) { - featureValues = Feature.config(featureValues, featrue, true); - } - - return parse(text, featureValues); - } - - public static final JSONObject parseObject(String text, Feature... features) { - return (JSONObject) parse(text, features); - } - - public static final JSONObject parseObject(String text) { - return (JSONObject) parse(text); - } - - @SuppressWarnings("unchecked") - public static final T parseObject(String text, TypeReference type, Feature... features) { - return (T) parseObject(text, type.getType(), ParserConfig.getGlobalInstance(), DEFAULT_PARSER_FEATURE, features); - } - - @SuppressWarnings("unchecked") - public static final T parseObject(String text, Class clazz, Feature... features) { - return (T) parseObject(text, (Type) clazz, ParserConfig.getGlobalInstance(), DEFAULT_PARSER_FEATURE, features); - } - - @SuppressWarnings("unchecked") - public static final T parseObject(String input, Type clazz, Feature... features) { - return (T) parseObject(input, clazz, ParserConfig.getGlobalInstance(), DEFAULT_PARSER_FEATURE, features); - } - - @SuppressWarnings("unchecked") - public static final T parseObject(String input, Type clazz, int featureValues, Feature... features) { - if (input == null) { - return null; - } - - for (Feature featrue : features) { - featureValues = Feature.config(featureValues, featrue, true); - } - - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), featureValues); - T value = (T) parser.parseObject(clazz); - - parser.close(); - - return (T) value; - } - - @SuppressWarnings("unchecked") - public static final T parseObject(String input, Type clazz, ParserConfig config, int featureValues, - Feature... features) { - if (input == null) { - return null; - } - - for (Feature featrue : features) { - featureValues = Feature.config(featureValues, featrue, true); - } - - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, config, featureValues); - T value = (T) parser.parseObject(clazz); - - if (clazz != JSONArray.class) { - parser.close(); - } - - return (T) value; - } - - @SuppressWarnings("unchecked") - public static final T parseObject(byte[] input, Type clazz, Feature... features) { - return (T) parseObject(input, 0, input.length, UTF8_CharsetEncoder, clazz, features); - } - - public static CharsetDecoder UTF8_CharsetEncoder = new UTF8Decoder(); // = - // Charset.forName("UTF-8").newDecoder(); - - @SuppressWarnings("unchecked") - public static final T parseObject(byte[] input, int off, int len, CharsetDecoder charsetDecoder, Type clazz, - Feature... features) { - charsetDecoder.reset(); - - int scaleLength = (int) (len * (double) charsetDecoder.maxCharsPerByte()); - char[] chars = ThreadLocalCache.getChars(scaleLength); - - ByteBuffer byteBuf = ByteBuffer.wrap(input, off, len); - CharBuffer charByte = CharBuffer.wrap(chars); - IOUtils.decode(charsetDecoder, byteBuf, charByte); - - int position = charByte.position(); - - return (T) parseObject(chars, position, clazz, features); - } - - @SuppressWarnings("unchecked") - public static final T parseObject(char[] input, int length, Type clazz, Feature... features) { - if (input == null || input.length == 0) { - return null; - } - - int featureValues = DEFAULT_PARSER_FEATURE; - for (Feature featrue : features) { - featureValues = Feature.config(featureValues, featrue, true); - } - - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, length, ParserConfig.getGlobalInstance(), - featureValues); - T value = (T) parser.parseObject(clazz); - - parser.close(); - - return (T) value; - } - - public static final T parseObject(String text, Class clazz) { - return parseObject(text, clazz, new Feature[0]); - } - - public static final JSONArray parseArray(String text) { - return (JSONArray) parse(text); - } - - public static final List parseArray(String text, Class clazz) { - if (text == null) { - return null; - } - - List list = new ArrayList(); - - DefaultExtJSONParser parser = new DefaultExtJSONParser(text, ParserConfig.getGlobalInstance()); - parser.parseArray(clazz, list); - - parser.close(); - - return list; - } - - public static final List parseArray(String text, Type[] types) { - if (text == null) { - return null; - } - - List list; - - DefaultExtJSONParser parser = new DefaultExtJSONParser(text, ParserConfig.getGlobalInstance()); - list = Arrays.asList(parser.parseArray(types)); - - parser.close(); - - return list; - } - - // ====================== - - public static final String toJSONString(Object object) { - return toJSONString(object, new SerializerFeature[0]); - } - - public static final String toJSONString(Object object, SerializerFeature... features) { - SerializeWriter out = new SerializeWriter(); - - try { - JSONSerializer serializer = new JSONSerializer(out); - for (com.alibaba.fastjson.serializer.SerializerFeature feature : features) { - serializer.config(feature, true); - } - - serializer.write(object); - - return out.toString(); - } catch (StackOverflowError e) { - throw new JSONException("maybe circular references", e); - } finally { - out.close(); - } - } - - public static final String toJSONString(Object object, SerializeConfig config, SerializerFeature... features) { - SerializeWriter out = new SerializeWriter(); - - try { - JSONSerializer serializer = new JSONSerializer(out, config); - for (com.alibaba.fastjson.serializer.SerializerFeature feature : features) { - serializer.config(feature, true); - } - - serializer.write(object); - - return out.toString(); - } catch (StackOverflowError e) { - throw new JSONException("maybe circular references", e); - } finally { - out.close(); - } - } - - public static final String toJSONStringZ(Object object, SerializeConfig mapping, SerializerFeature... features) { - SerializeWriter out = new SerializeWriter(features); - - try { - JSONSerializer serializer = new JSONSerializer(out, mapping); - - serializer.write(object); - - return out.toString(); - } catch (StackOverflowError e) { - throw new JSONException("maybe circular references", e); - } finally { - out.close(); - } - } - - public static final String toJSONString(Object object, boolean prettyFormat) { - if (!prettyFormat) { - return toJSONString(object); - } - - return toJSONString(object, SerializerFeature.PrettyFormat); - } - - // ====================================== - - @Override - public String toString() { - return toJSONString(); - } - - public String toJSONString() { - SerializeWriter out = new SerializeWriter(); - try { - new JSONSerializer(out).write(this); - return out.toString(); - } finally { - out.close(); - } - } - - public void writeJSONString(Appendable appendable) { - SerializeWriter out = new SerializeWriter(); - try { - new JSONSerializer(out).write(this); - appendable.append(out.toString()); - } catch (IOException e) { - throw new JSONException(e.getMessage(), e); - } finally { - out.close(); - } - } - - // /////// - - public static final Object toJSON(Object javaObject) { - return toJSON(javaObject, ParserConfig.getGlobalInstance()); - } - - @SuppressWarnings("unchecked") - public static final Object toJSON(Object javaObject, ParserConfig mapping) { - if (javaObject == null) { - return null; - } - - if (javaObject instanceof JSON) { - return (JSON) javaObject; - } - - if (javaObject instanceof Map) { - Map map = (Map) javaObject; - - JSONObject json = new JSONObject(map.size()); - - for (Map.Entry entry : map.entrySet()) { - Object jsonValue = toJSON(entry.getValue()); - json.put(entry.getKey(), jsonValue); - } - - return json; - } - - if (javaObject instanceof Collection) { - Collection collection = (Collection) javaObject; - - JSONArray array = new JSONArray(collection.size()); - - for (Object item : collection) { - Object jsonValue = toJSON(item); - array.add(jsonValue); - } - - return array; - } - - Class clazz = javaObject.getClass(); - - if (clazz.isArray()) { - int len = Array.getLength(javaObject); - - JSONArray array = new JSONArray(len); - - for (int i = 0; i < len; ++i) { - Object item = Array.get(javaObject, i); - Object jsonValue = toJSON(item); - array.add(jsonValue); - } - - return array; - } - - if (mapping.isPrimitive(clazz)) { - return javaObject; - } - - try { - List getters = JavaBeanSerializer.computeGetters(clazz, null); - - JSONObject json = new JSONObject(getters.size()); - - for (FieldInfo field : getters) { - Method method = field.getMethod(); - Object value = method.invoke(javaObject, new Object[0]); - Object jsonValue = toJSON(value); - - json.put(field.getName(), jsonValue); - } - - return json; - } catch (Exception e) { - throw new JSONException("toJSON error", e); - } - } - - public static final T toJavaObject(JSON json, Class clazz) { - return TypeUtils.cast(json, clazz, ParserConfig.getGlobalInstance()); - } -} +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson; + +import java.io.IOException; +import java.io.Writer; +import java.lang.reflect.Array; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Type; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharsetDecoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.ExtraProcessor; +import com.alibaba.fastjson.parser.deserializer.ExtraTypeProvider; +import com.alibaba.fastjson.parser.deserializer.ParseProcess; +import com.alibaba.fastjson.serializer.AfterFilter; +import com.alibaba.fastjson.serializer.BeforeFilter; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.NameFilter; +import com.alibaba.fastjson.serializer.PropertyFilter; +import com.alibaba.fastjson.serializer.PropertyPreFilter; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializeFilter; +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.serializer.ValueFilter; +import com.alibaba.fastjson.util.FieldInfo; +import com.alibaba.fastjson.util.IOUtils; +import com.alibaba.fastjson.util.ThreadLocalCache; +import com.alibaba.fastjson.util.TypeUtils; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public abstract class JSON implements JSONStreamAware, JSONAware { + + public static String DEFAULT_TYPE_KEY = "@type"; + + public static int DEFAULT_PARSER_FEATURE; + + /** + * asm生成代码dump路径 + */ + public static String DUMP_CLASS = null; + + static { + int features = 0; + features |= Feature.AutoCloseSource.getMask(); + features |= Feature.InternFieldNames.getMask(); + features |= Feature.UseBigDecimal.getMask(); + features |= Feature.AllowUnQuotedFieldNames.getMask(); + features |= Feature.AllowSingleQuotes.getMask(); + features |= Feature.AllowArbitraryCommas.getMask(); + features |= Feature.SortFeidFastMatch.getMask(); + features |= Feature.IgnoreNotMatch.getMask(); + DEFAULT_PARSER_FEATURE = features; + } + + public static String DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; + + public static int DEFAULT_GENERATE_FEATURE; + + static { + int features = 0; + features |= SerializerFeature.QuoteFieldNames.getMask(); + features |= SerializerFeature.SkipTransientField.getMask(); + features |= SerializerFeature.WriteEnumUsingToString.getMask(); + features |= SerializerFeature.SortField.getMask(); + // features |= + // com.alibaba.fastjson.serializer.SerializerFeature.WriteSlashAsSpecial.getMask(); + DEFAULT_GENERATE_FEATURE = features; + } + + public static final Object parse(String text) { + return parse(text, DEFAULT_PARSER_FEATURE); + } + + public static final Object parse(String text, int features) { + if (text == null) { + return null; + } + + DefaultJSONParser parser = new DefaultJSONParser(text, ParserConfig.getGlobalInstance(), features); + Object value = parser.parse(); + + parser.handleResovleTask(value); + + parser.close(); + + return value; + } + + public static final Object parse(byte[] input, Feature... features) { + return parse(input, 0, input.length, ThreadLocalCache.getUTF8Decoder(), features); + } + + public static final Object parse(byte[] input, int off, int len, CharsetDecoder charsetDecoder, Feature... features) { + if (input == null || input.length == 0) { + return null; + } + + int featureValues = DEFAULT_PARSER_FEATURE; + for (Feature featrue : features) { + featureValues = Feature.config(featureValues, featrue, true); + } + + return parse(input, off, len, charsetDecoder, featureValues); + } + + public static final Object parse(byte[] input, int off, int len, CharsetDecoder charsetDecoder, int features) { + charsetDecoder.reset(); + + int scaleLength = (int) (len * (double) charsetDecoder.maxCharsPerByte()); + char[] chars = ThreadLocalCache.getChars(scaleLength); + + ByteBuffer byteBuf = ByteBuffer.wrap(input, off, len); + CharBuffer charBuf = CharBuffer.wrap(chars); + IOUtils.decode(charsetDecoder, byteBuf, charBuf); + + int position = charBuf.position(); + + DefaultJSONParser parser = new DefaultJSONParser(chars, position, ParserConfig.getGlobalInstance(), features); + Object value = parser.parse(); + + parser.handleResovleTask(value); + + parser.close(); + + return value; + } + + public static final Object parse(String text, Feature... features) { + int featureValues = DEFAULT_PARSER_FEATURE; + for (Feature featrue : features) { + featureValues = Feature.config(featureValues, featrue, true); + } + + return parse(text, featureValues); + } + + public static final JSONObject parseObject(String text, Feature... features) { + return (JSONObject) parse(text, features); + } + + public static final JSONObject parseObject(String text) { + Object obj = parse(text); + if (obj instanceof JSONObject) { + return (JSONObject) obj; + } + + return (JSONObject) JSON.toJSON(obj); + } + + @SuppressWarnings("unchecked") + public static final T parseObject(String text, TypeReference type, Feature... features) { + return (T) parseObject(text, type.getType(), ParserConfig.getGlobalInstance(), DEFAULT_PARSER_FEATURE, features); + } + + @SuppressWarnings("unchecked") + public static final T parseObject(String text, Class clazz, Feature... features) { + return (T) parseObject(text, (Type) clazz, ParserConfig.getGlobalInstance(), DEFAULT_PARSER_FEATURE, features); + } + + @SuppressWarnings("unchecked") + public static final T parseObject(String text, Class clazz, ParseProcess processor, Feature... features) { + return (T) parseObject(text, (Type) clazz, ParserConfig.getGlobalInstance(), processor, DEFAULT_PARSER_FEATURE, + features); + } + + @SuppressWarnings("unchecked") + public static final T parseObject(String input, Type clazz, Feature... features) { + return (T) parseObject(input, clazz, ParserConfig.getGlobalInstance(), DEFAULT_PARSER_FEATURE, features); + } + + @SuppressWarnings("unchecked") + public static final T parseObject(String input, Type clazz, ParseProcess processor, Feature... features) { + return (T) parseObject(input, clazz, ParserConfig.getGlobalInstance(), DEFAULT_PARSER_FEATURE, features); + } + + @SuppressWarnings("unchecked") + public static final T parseObject(String input, Type clazz, int featureValues, Feature... features) { + if (input == null) { + return null; + } + + for (Feature featrue : features) { + featureValues = Feature.config(featureValues, featrue, true); + } + + DefaultJSONParser parser = new DefaultJSONParser(input, ParserConfig.getGlobalInstance(), featureValues); + T value = (T) parser.parseObject(clazz); + + parser.handleResovleTask(value); + + parser.close(); + + return (T) value; + } + + public static final T parseObject(String input, Type clazz, ParserConfig config, int featureValues, + Feature... features) { + return parseObject(input, clazz, config, null, featureValues, features); + } + + @SuppressWarnings("unchecked") + public static final T parseObject(String input, Type clazz, ParserConfig config, ParseProcess processor, + int featureValues, Feature... features) { + if (input == null) { + return null; + } + + for (Feature featrue : features) { + featureValues = Feature.config(featureValues, featrue, true); + } + + DefaultJSONParser parser = new DefaultJSONParser(input, config, featureValues); + + if (processor instanceof ExtraTypeProvider) { + parser.getExtraTypeProviders().add((ExtraTypeProvider) processor); + } + + if (processor instanceof ExtraProcessor) { + parser.getExtraProcessors().add((ExtraProcessor) processor); + } + + T value = (T) parser.parseObject(clazz); + + parser.handleResovleTask(value); + + parser.close(); + + return (T) value; + } + + @SuppressWarnings("unchecked") + public static final T parseObject(byte[] input, Type clazz, Feature... features) { + return (T) parseObject(input, 0, input.length, ThreadLocalCache.getUTF8Decoder(), clazz, features); + } + + @SuppressWarnings("unchecked") + public static final T parseObject(byte[] input, int off, int len, CharsetDecoder charsetDecoder, Type clazz, + Feature... features) { + charsetDecoder.reset(); + + int scaleLength = (int) (len * (double) charsetDecoder.maxCharsPerByte()); + char[] chars = ThreadLocalCache.getChars(scaleLength); + + ByteBuffer byteBuf = ByteBuffer.wrap(input, off, len); + CharBuffer charByte = CharBuffer.wrap(chars); + IOUtils.decode(charsetDecoder, byteBuf, charByte); + + int position = charByte.position(); + + return (T) parseObject(chars, position, clazz, features); + } + + @SuppressWarnings("unchecked") + public static final T parseObject(char[] input, int length, Type clazz, Feature... features) { + if (input == null || input.length == 0) { + return null; + } + + int featureValues = DEFAULT_PARSER_FEATURE; + for (Feature featrue : features) { + featureValues = Feature.config(featureValues, featrue, true); + } + + DefaultJSONParser parser = new DefaultJSONParser(input, length, ParserConfig.getGlobalInstance(), featureValues); + T value = (T) parser.parseObject(clazz); + + parser.handleResovleTask(value); + + parser.close(); + + return (T) value; + } + + public static final T parseObject(String text, Class clazz) { + return parseObject(text, clazz, new Feature[0]); + } + + public static final JSONArray parseArray(String text) { + if (text == null) { + return null; + } + + DefaultJSONParser parser = new DefaultJSONParser(text, ParserConfig.getGlobalInstance()); + + JSONArray array; + + JSONLexer lexer = parser.getLexer(); + if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(); + array = null; + } else if (lexer.token() == JSONToken.EOF) { + array = null; + } else { + array = new JSONArray(); + parser.parseArray(array); + + parser.handleResovleTask(array); + } + + parser.close(); + + return array; + } + + public static final List parseArray(String text, Class clazz) { + if (text == null) { + return null; + } + + List list; + + DefaultJSONParser parser = new DefaultJSONParser(text, ParserConfig.getGlobalInstance()); + JSONLexer lexer = parser.getLexer(); + if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(); + list = null; + } else { + list = new ArrayList(); + parser.parseArray(clazz, list); + + parser.handleResovleTask(list); + } + + parser.close(); + + return list; + } + + public static final List parseArray(String text, Type[] types) { + if (text == null) { + return null; + } + + List list; + + DefaultJSONParser parser = new DefaultJSONParser(text, ParserConfig.getGlobalInstance()); + Object[] objectArray = parser.parseArray(types); + if (objectArray == null) { + list = null; + } else { + list = Arrays.asList(objectArray); + } + + parser.handleResovleTask(list); + + parser.close(); + + return list; + } + + // ====================== + public static final String toJSONString(Object object) { + return toJSONString(object, new SerializerFeature[0]); + } + + public static final String toJSONString(Object object, SerializerFeature... features) { + SerializeWriter out = new SerializeWriter(); + + try { + JSONSerializer serializer = new JSONSerializer(out); + for (com.alibaba.fastjson.serializer.SerializerFeature feature : features) { + serializer.config(feature, true); + } + + serializer.write(object); + + return out.toString(); + } finally { + out.close(); + } + } + + /** + * @since 1.1.14 + */ + public static final String toJSONStringWithDateFormat(Object object, String dateFormat, + SerializerFeature... features) { + SerializeWriter out = new SerializeWriter(); + + try { + JSONSerializer serializer = new JSONSerializer(out); + for (SerializerFeature feature : features) { + serializer.config(feature, true); + } + + serializer.config(SerializerFeature.WriteDateUseDateFormat, true); + + if (dateFormat != null) { + serializer.setDateFormat(dateFormat); + } + + serializer.write(object); + + return out.toString(); + } finally { + out.close(); + } + } + + public static final String toJSONString(Object object, SerializeFilter filter, SerializerFeature... features) { + SerializeWriter out = new SerializeWriter(); + + try { + JSONSerializer serializer = new JSONSerializer(out); + for (com.alibaba.fastjson.serializer.SerializerFeature feature : features) { + serializer.config(feature, true); + } + + serializer.config(SerializerFeature.WriteDateUseDateFormat, true); + + setFilter(serializer, filter); + + serializer.write(object); + + return out.toString(); + } finally { + out.close(); + } + } + + public static final String toJSONString(Object object, SerializeFilter[] filters, SerializerFeature... features) { + SerializeWriter out = new SerializeWriter(); + + try { + JSONSerializer serializer = new JSONSerializer(out); + for (com.alibaba.fastjson.serializer.SerializerFeature feature : features) { + serializer.config(feature, true); + } + + serializer.config(SerializerFeature.WriteDateUseDateFormat, true); + + setFilter(serializer, filters); + + serializer.write(object); + + return out.toString(); + } finally { + out.close(); + } + } + + public static final byte[] toJSONBytes(Object object, SerializerFeature... features) { + SerializeWriter out = new SerializeWriter(); + + try { + JSONSerializer serializer = new JSONSerializer(out); + for (com.alibaba.fastjson.serializer.SerializerFeature feature : features) { + serializer.config(feature, true); + } + + serializer.write(object); + + return out.toBytes("UTF-8"); + } finally { + out.close(); + } + } + + public static final String toJSONString(Object object, SerializeConfig config, SerializerFeature... features) { + return toJSONString(object, config, (SerializeFilter) null, features); + } + + public static final String toJSONString(Object object, SerializeConfig config, SerializeFilter filter, + SerializerFeature... features) { + SerializeWriter out = new SerializeWriter(); + + try { + JSONSerializer serializer = new JSONSerializer(out, config); + for (com.alibaba.fastjson.serializer.SerializerFeature feature : features) { + serializer.config(feature, true); + } + + setFilter(serializer, filter); + + serializer.write(object); + + return out.toString(); + } finally { + out.close(); + } + } + + public static final String toJSONString(Object object, SerializeConfig config, SerializeFilter[] filters, + SerializerFeature... features) { + SerializeWriter out = new SerializeWriter(); + + try { + JSONSerializer serializer = new JSONSerializer(out, config); + for (com.alibaba.fastjson.serializer.SerializerFeature feature : features) { + serializer.config(feature, true); + } + + setFilter(serializer, filters); + + serializer.write(object); + + return out.toString(); + } finally { + out.close(); + } + } + + public static final String toJSONStringZ(Object object, SerializeConfig mapping, SerializerFeature... features) { + SerializeWriter out = new SerializeWriter(features); + + try { + JSONSerializer serializer = new JSONSerializer(out, mapping); + + serializer.write(object); + + return out.toString(); + } finally { + out.close(); + } + } + + public static final byte[] toJSONBytes(Object object, SerializeConfig config, SerializerFeature... features) { + SerializeWriter out = new SerializeWriter(); + + try { + JSONSerializer serializer = new JSONSerializer(out, config); + for (com.alibaba.fastjson.serializer.SerializerFeature feature : features) { + serializer.config(feature, true); + } + + serializer.write(object); + + return out.toBytes("UTF-8"); + } finally { + out.close(); + } + } + + public static final String toJSONString(Object object, boolean prettyFormat) { + if (!prettyFormat) { + return toJSONString(object); + } + + return toJSONString(object, SerializerFeature.PrettyFormat); + } + + public static final void writeJSONStringTo(Object object, Writer writer, SerializerFeature... features) { + SerializeWriter out = new SerializeWriter(writer); + + try { + JSONSerializer serializer = new JSONSerializer(out); + for (com.alibaba.fastjson.serializer.SerializerFeature feature : features) { + serializer.config(feature, true); + } + + serializer.write(object); + } finally { + out.close(); + } + } + + // ====================================== + @Override + public String toString() { + return toJSONString(); + } + + public String toJSONString() { + SerializeWriter out = new SerializeWriter(); + try { + new JSONSerializer(out).write(this); + return out.toString(); + } finally { + out.close(); + } + } + + public void writeJSONString(Appendable appendable) { + SerializeWriter out = new SerializeWriter(); + try { + new JSONSerializer(out).write(this); + appendable.append(out.toString()); + } catch (IOException e) { + throw new JSONException(e.getMessage(), e); + } finally { + out.close(); + } + } + + // /////// + public static final Object toJSON(Object javaObject) { + return toJSON(javaObject, ParserConfig.getGlobalInstance()); + } + + @SuppressWarnings("unchecked") + public static final Object toJSON(Object javaObject, ParserConfig mapping) { + if (javaObject == null) { + return null; + } + + if (javaObject instanceof JSON) { + return (JSON) javaObject; + } + + if (javaObject instanceof Map) { + Map map = (Map) javaObject; + + JSONObject json = new JSONObject(map.size()); + + for (Map.Entry entry : map.entrySet()) { + Object key = entry.getKey(); + String jsonKey = TypeUtils.castToString(key); + Object jsonValue = toJSON(entry.getValue()); + json.put(jsonKey, jsonValue); + } + + return json; + } + + if (javaObject instanceof Collection) { + Collection collection = (Collection) javaObject; + + JSONArray array = new JSONArray(collection.size()); + + for (Object item : collection) { + Object jsonValue = toJSON(item); + array.add(jsonValue); + } + + return array; + } + + Class clazz = javaObject.getClass(); + + if (clazz.isEnum()) { + return ((Enum) javaObject).name(); + } + + if (clazz.isArray()) { + int len = Array.getLength(javaObject); + + JSONArray array = new JSONArray(len); + + for (int i = 0; i < len; ++i) { + Object item = Array.get(javaObject, i); + Object jsonValue = toJSON(item); + array.add(jsonValue); + } + + return array; + } + + if (mapping.isPrimitive(clazz)) { + return javaObject; + } + + try { + List getters = TypeUtils.computeGetters(clazz, null); + + JSONObject json = new JSONObject(getters.size()); + + for (FieldInfo field : getters) { + Object value = field.get(javaObject); + Object jsonValue = toJSON(value); + + json.put(field.getName(), jsonValue); + } + + return json; + } catch (IllegalAccessException e) { + throw new JSONException("toJSON error", e); + } catch (InvocationTargetException e) { + throw new JSONException("toJSON error", e); + } + } + + public static final T toJavaObject(JSON json, Class clazz) { + return TypeUtils.cast(json, clazz, ParserConfig.getGlobalInstance()); + } + + private static void setFilter(JSONSerializer serializer, SerializeFilter... filters) { + for (SerializeFilter filter : filters) { + setFilter(serializer, filter); + } + } + + private static void setFilter(JSONSerializer serializer, SerializeFilter filter) { + if (filter == null) { + return; + } + + if (filter instanceof PropertyPreFilter) { + serializer.getPropertyPreFilters().add((PropertyPreFilter) filter); + } + + if (filter instanceof NameFilter) { + serializer.getNameFilters().add((NameFilter) filter); + } + + if (filter instanceof ValueFilter) { + serializer.getValueFilters().add((ValueFilter) filter); + } + + if (filter instanceof PropertyFilter) { + serializer.getPropertyFilters().add((PropertyFilter) filter); + } + + if (filter instanceof BeforeFilter) { + serializer.getBeforeFilters().add((BeforeFilter) filter); + } + + if (filter instanceof AfterFilter) { + serializer.getAfterFilters().add((AfterFilter) filter); + } + } + + public final static String VERSION = "1.2.4"; +} diff --git a/src/main/java/com/alibaba/fastjson/JSONArray.java b/src/main/java/com/alibaba/fastjson/JSONArray.java old mode 100644 new mode 100755 index f80155505c..01c7746fcc --- a/src/main/java/com/alibaba/fastjson/JSONArray.java +++ b/src/main/java/com/alibaba/fastjson/JSONArray.java @@ -30,6 +30,7 @@ import static com.alibaba.fastjson.util.TypeUtils.castToTimestamp; import java.io.Serializable; +import java.lang.reflect.Type; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; @@ -42,12 +43,14 @@ import com.alibaba.fastjson.util.TypeUtils; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ -public class JSONArray extends JSON implements List, JSONAware, Cloneable, RandomAccess, Serializable { +public class JSONArray extends JSON implements List, Cloneable, RandomAccess, Serializable { private static final long serialVersionUID = 1L; private final List list; + protected transient Object relatedArray; + protected transient Type componentType; public JSONArray(){ this.list = new ArrayList(10); @@ -61,6 +64,26 @@ public JSONArray(int initialCapacity){ this.list = new ArrayList(initialCapacity); } + /** + * @since 1.1.16 + * @return + */ + public Object getRelatedArray() { + return relatedArray; + } + + public void setRelatedArray(Object relatedArray) { + this.relatedArray = relatedArray; + } + + public Type getComponentType() { + return componentType; + } + + public void setComponentType(Type componentType) { + this.componentType = componentType; + } + public int size() { return list.size(); } @@ -291,7 +314,7 @@ public double getDoubleValue(int index) { return 0D; } - return castToDouble(value).floatValue(); + return castToDouble(value); } public BigDecimal getBigDecimal(int index) { @@ -334,11 +357,11 @@ public java.sql.Timestamp getTimestamp(int index) { public Object clone() { return new JSONArray(new ArrayList(list)); } - + public boolean equals(Object obj) { return this.list.equals(obj); } - + public int hashCode() { return this.list.hashCode(); } diff --git a/src/main/java/com/alibaba/fastjson/JSONAware.java b/src/main/java/com/alibaba/fastjson/JSONAware.java old mode 100644 new mode 100755 index b388a4414d..2bd23d52a0 --- a/src/main/java/com/alibaba/fastjson/JSONAware.java +++ b/src/main/java/com/alibaba/fastjson/JSONAware.java @@ -18,7 +18,7 @@ /** * Beans that support customized output of JSON text shall implement this interface. * - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public interface JSONAware { diff --git a/src/main/java/com/alibaba/fastjson/JSONException.java b/src/main/java/com/alibaba/fastjson/JSONException.java old mode 100644 new mode 100755 index 4a27ee2dec..8f60dcbab7 --- a/src/main/java/com/alibaba/fastjson/JSONException.java +++ b/src/main/java/com/alibaba/fastjson/JSONException.java @@ -16,7 +16,7 @@ package com.alibaba.fastjson; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class JSONException extends RuntimeException { diff --git a/src/main/java/com/alibaba/fastjson/JSONObject.java b/src/main/java/com/alibaba/fastjson/JSONObject.java old mode 100644 new mode 100755 index b58db975f6..92f7af1b20 --- a/src/main/java/com/alibaba/fastjson/JSONObject.java +++ b/src/main/java/com/alibaba/fastjson/JSONObject.java @@ -19,6 +19,7 @@ import static com.alibaba.fastjson.util.TypeUtils.castToBigInteger; import static com.alibaba.fastjson.util.TypeUtils.castToBoolean; import static com.alibaba.fastjson.util.TypeUtils.castToByte; +import static com.alibaba.fastjson.util.TypeUtils.castToBytes; import static com.alibaba.fastjson.util.TypeUtils.castToDate; import static com.alibaba.fastjson.util.TypeUtils.castToDouble; import static com.alibaba.fastjson.util.TypeUtils.castToFloat; @@ -29,6 +30,8 @@ import static com.alibaba.fastjson.util.TypeUtils.castToTimestamp; import java.io.Serializable; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collection; @@ -38,12 +41,14 @@ import java.util.Map; import java.util.Set; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.util.TypeUtils; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ -public class JSONObject extends JSON implements Map, JSONAware, Cloneable, Serializable { +public class JSONObject extends JSON implements Map, Cloneable, Serializable, InvocationHandler { private static final long serialVersionUID = 1L; private static final int DEFAULT_INITIAL_CAPACITY = 16; @@ -129,6 +134,16 @@ public Boolean getBoolean(String key) { return castToBoolean(value); } + public byte[] getBytes(String key) { + Object value = get(key); + + if (value == null) { + return null; + } + + return castToBytes(value); + } + public boolean getBooleanValue(String key) { Object value = get(key); @@ -232,7 +247,7 @@ public double getDoubleValue(String key) { return 0D; } - return castToDouble(value).floatValue(); + return castToDouble(value); } public BigDecimal getBigDecimal(String key) { @@ -274,7 +289,7 @@ public java.sql.Timestamp getTimestamp(String key) { return castToTimestamp(value); } - + public Object put(String key, Object value) { return map.put(key, value); } @@ -307,12 +322,94 @@ public Set> entrySet() { public Object clone() { return new JSONObject(new HashMap(map)); } - + public boolean equals(Object obj) { return this.map.equals(obj); } - + public int hashCode() { return this.map.hashCode(); } + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + Class[] parameterTypes = method.getParameterTypes(); + if (parameterTypes.length == 1) { + if (method.getName().equals("equals")) { + return this.equals(args[0]); + } + + Class returnType = method.getReturnType(); + if (returnType != void.class) { + throw new JSONException("illegal setter"); + } + + String name = null; + JSONField annotation = method.getAnnotation(JSONField.class); + if (annotation != null) { + if (annotation.name().length() != 0) { + name = annotation.name(); + } + } + + if (name == null) { + name = method.getName(); + + if (!name.startsWith("set")) { + throw new JSONException("illegal setter"); + } + + name = name.substring(3); + if (name.length() == 0) { + throw new JSONException("illegal setter"); + } + name = Character.toLowerCase(name.charAt(0)) + name.substring(1); + } + + map.put(name, args[0]); + return null; + } + + if (parameterTypes.length == 0) { + Class returnType = method.getReturnType(); + if (returnType == void.class) { + throw new JSONException("illegal getter"); + } + + String name = null; + JSONField annotation = method.getAnnotation(JSONField.class); + if (annotation != null) { + if (annotation.name().length() != 0) { + name = annotation.name(); + } + } + + if (name == null) { + name = method.getName(); + if (name.startsWith("get")) { + name = name.substring(3); + if (name.length() == 0) { + throw new JSONException("illegal getter"); + } + name = Character.toLowerCase(name.charAt(0)) + name.substring(1); + } else if (name.startsWith("is")) { + name = name.substring(2); + if (name.length() == 0) { + throw new JSONException("illegal getter"); + } + name = Character.toLowerCase(name.charAt(0)) + name.substring(1); + } else if (name.startsWith("hashCode")) { + return this.hashCode(); + } else if (name.startsWith("toString")) { + return this.toString(); + } else { + throw new JSONException("illegal getter"); + } + } + + Object value = map.get(name); + return TypeUtils.cast(value, method.getGenericReturnType(), ParserConfig.getGlobalInstance()); + } + + throw new UnsupportedOperationException(method.toGenericString()); + } } diff --git a/src/main/java/com/alibaba/fastjson/JSONPObject.java b/src/main/java/com/alibaba/fastjson/JSONPObject.java new file mode 100644 index 0000000000..2821719276 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/JSONPObject.java @@ -0,0 +1,62 @@ +package com.alibaba.fastjson; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.fastjson.serializer.JSONSerializable; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializeWriter; + +public class JSONPObject implements JSONSerializable { + + private String function; + + private final List parameters = new ArrayList(); + + public JSONPObject() { + + } + + public JSONPObject(String function) { + this.function = function; + } + + public String getFunction() { + return function; + } + + public void setFunction(String function) { + this.function = function; + } + + public List getParameters() { + return parameters; + } + + public void addParameter(Object parameter) { + this.parameters.add(parameter); + } + + public String toJSONString() { + return null; + } + + public void write(JSONSerializer serializer, Object fieldName, Type fieldType, int features) throws IOException { + SerializeWriter writer = serializer.getWriter(); + writer.write(function); + writer.write('('); + for (int i = 0; i < parameters.size(); ++i) { + if (i != 0) { + writer.write(','); + } + serializer.write(parameters.get(i)); + } + writer.write(')'); + } + + public String toString() { + return JSON.toJSONString(this); + } +} diff --git a/src/main/java/com/alibaba/fastjson/JSONPath.java b/src/main/java/com/alibaba/fastjson/JSONPath.java new file mode 100644 index 0000000000..c990780b45 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/JSONPath.java @@ -0,0 +1,1774 @@ +package com.alibaba.fastjson; + +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer; +import com.alibaba.fastjson.parser.deserializer.FieldDeserializer; +import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.serializer.ASMJavaBeanSerializer; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.JavaBeanSerializer; +import com.alibaba.fastjson.serializer.ObjectSerializer; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.util.IOUtils; + +/** + * @author wenshao[szujobs@hotmail.com] + * @since 1.2.0 + */ +public class JSONPath implements ObjectSerializer { + + private static int CACHE_SIZE = 1024; + private static ConcurrentMap pathCache = new ConcurrentHashMap(128, 0.75f, 1); + + private final String path; + private Segement[] segments; + + private SerializeConfig serializeConfig; + private ParserConfig parserConfig; + + public JSONPath(String path){ + this(path, SerializeConfig.getGlobalInstance(), ParserConfig.getGlobalInstance()); + } + + public JSONPath(String path, SerializeConfig serializeConfig, ParserConfig parserConfig){ + if (path == null || path.isEmpty()) { + throw new IllegalArgumentException(); + } + + this.path = path; + this.serializeConfig = serializeConfig; + this.parserConfig = parserConfig; + } + + protected void init() { + if (segments != null) { + return; + } + + if ("*".equals(path)) { + this.segments = new Segement[] { WildCardSegement.instance }; + } else { + JSONPathParser parser = new JSONPathParser(path); + this.segments = parser.explain(); + } + } + + public Object eval(Object rootObject) { + if (rootObject == null) { + return null; + } + + init(); + + Object currentObject = rootObject; + for (int i = 0; i < segments.length; ++i) { + currentObject = segments[i].eval(this, rootObject, currentObject); + } + return currentObject; + } + + public boolean contains(Object rootObject) { + if (rootObject == null) { + return false; + } + + init(); + + Object currentObject = rootObject; + for (int i = 0; i < segments.length; ++i) { + currentObject = segments[i].eval(this, rootObject, currentObject); + if (currentObject == null) { + return false; + } + } + + return true; + } + + @SuppressWarnings("rawtypes") + public boolean containsValue(Object rootObject, Object value) { + Object currentObject = eval(rootObject); + + if (currentObject == value) { + return true; + } + + if (currentObject == null) { + return false; + } + + if (currentObject instanceof Iterable) { + Iterator it = ((Iterable) currentObject).iterator(); + while (it.hasNext()) { + Object item = it.next(); + if (eq(item, value)) { + return true; + } + } + + return false; + } + + return eq(currentObject, value); + } + + public int size(Object rootObject) { + if (rootObject == null) { + return -1; + } + + init(); + + Object currentObject = rootObject; + for (int i = 0; i < segments.length; ++i) { + currentObject = segments[i].eval(this, rootObject, currentObject); + } + + return evalSize(currentObject); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void arrayAdd(Object rootObject, Object... values) { + if (values == null || values.length == 0) { + return; + } + + if (rootObject == null) { + return; + } + + init(); + + Object currentObject = rootObject; + Object parentObject = null; + for (int i = 0; i < segments.length; ++i) { + if (i == segments.length - 1) { + parentObject = currentObject; + } + currentObject = segments[i].eval(this, rootObject, currentObject); + } + + Object result = currentObject; + + if (result == null) { + throw new JSONPathException("value not found in path " + path); + } + + if (result instanceof Collection) { + Collection collection = (Collection) result; + for (Object value : values) { + collection.add(value); + } + return; + } + + Class resultClass = result.getClass(); + + Object newResult; + if (resultClass.isArray()) { + int length = Array.getLength(result); + Object descArray = Array.newInstance(resultClass.getComponentType(), length + values.length); + + System.arraycopy(result, 0, descArray, 0, length); + for (int i = 0; i < values.length; ++i) { + Array.set(descArray, length + i, values[i]); + + } + newResult = descArray; + } else { + throw new UnsupportedOperationException(); + } + + Segement lastSegement = segments[segments.length - 1]; + if (lastSegement instanceof PropertySegement) { + PropertySegement propertySegement = (PropertySegement) lastSegement; + propertySegement.setValue(this, parentObject, newResult); + return; + } + + if (lastSegement instanceof ArrayAccessSegement) { + ((ArrayAccessSegement) lastSegement).setValue(this, parentObject, newResult); + return; + } + + throw new UnsupportedOperationException(); + } + + public boolean set(Object rootObject, Object value) { + if (rootObject == null) { + return false; + } + + init(); + + Object currentObject = rootObject; + Object parentObject = null; + for (int i = 0; i < segments.length; ++i) { + if (i == segments.length - 1) { + parentObject = currentObject; + break; + } + currentObject = segments[i].eval(this, rootObject, currentObject); + if (currentObject == null) { + break; + } + } + + if (parentObject == null) { + return false; + } + + Segement lastSegement = segments[segments.length - 1]; + if (lastSegement instanceof PropertySegement) { + PropertySegement propertySegement = (PropertySegement) lastSegement; + propertySegement.setValue(this, parentObject, value); + return true; + } + + if (lastSegement instanceof ArrayAccessSegement) { + return ((ArrayAccessSegement) lastSegement).setValue(this, parentObject, value); + } + + throw new UnsupportedOperationException(); + } + + public static Object eval(Object rootObject, String path) { + JSONPath jsonpath = compile(path); + return jsonpath.eval(rootObject); + } + + public static int size(Object rootObject, String path) { + JSONPath jsonpath = compile(path); + Object result = jsonpath.eval(rootObject); + return jsonpath.evalSize(result); + } + + public static boolean contains(Object rootObject, String path) { + if (rootObject == null) { + return false; + } + + JSONPath jsonpath = compile(path); + return jsonpath.contains(rootObject); + } + + public static boolean containsValue(Object rootObject, String path, Object value) { + JSONPath jsonpath = compile(path); + return jsonpath.containsValue(rootObject, value); + } + + public static void arrayAdd(Object rootObject, String path, Object... values) { + JSONPath jsonpath = compile(path); + jsonpath.arrayAdd(rootObject, values); + } + + public static void set(Object rootObject, String path, Object value) { + JSONPath jsonpath = compile(path); + jsonpath.set(rootObject, value); + } + + public static JSONPath compile(String path) { + JSONPath jsonpath = pathCache.get(path); + if (jsonpath == null) { + jsonpath = new JSONPath(path); + if (pathCache.size() < CACHE_SIZE) { + pathCache.putIfAbsent(path, jsonpath); + jsonpath = pathCache.get(path); + } + } + return jsonpath; + } + + public String getPath() { + return path; + } + + static class JSONPathParser { + + private final String path; + private int pos; + private char ch; + private int level; + + public JSONPathParser(String path){ + this.path = path; + next(); + } + + void next() { + ch = path.charAt(pos++); + } + + boolean isEOF() { + return pos >= path.length(); + } + + Segement readSegement() { + while (!isEOF()) { + skipWhitespace(); + + if (ch == '@') { + next(); + return SelfSegement.instance; + } + + if (ch == '$') { + next(); + continue; + } + + if (ch == '.') { + next(); + if (ch == '*') { + if (!isEOF()) { + next(); + } + + return WildCardSegement.instance; + } + + String propertyName = readName(); + if (ch == '(') { + next(); + if (ch == ')') { + if (!isEOF()) { + next(); + } + + if ("size".equals(propertyName)) { + return SizeSegement.instance; + } + + throw new UnsupportedOperationException(); + } + + throw new UnsupportedOperationException(); + } + + return new PropertySegement(propertyName); + } + + if (ch == '[') { + return parseArrayAccess(); + } + + if (level == 0) { + String propertyName = readName(); + + return new PropertySegement(propertyName); + } + + throw new UnsupportedOperationException(); + } + + return null; + } + + public final void skipWhitespace() { + for (;;) { + if (ch < IOUtils.whitespaceFlags.length && IOUtils.whitespaceFlags[ch]) { + next(); + continue; + } else { + break; + } + } + } + + Segement parseArrayAccess() { + accept('['); + + boolean predicateFlag = false; + + if (ch == '?') { + next(); + accept('('); + if (ch == '@') { + next(); + accept('.'); + } + + predicateFlag = true; + } + + if (predicateFlag || IOUtils.firstIdentifier(ch)) { + String propertyName = readName(); + + skipWhitespace(); + + if (predicateFlag && ch == ')') { + next(); + accept(']'); + + return new FilterSegement(new NotNullSegement(propertyName)); + } + + if (ch == ']') { + next(); + return new FilterSegement(new NotNullSegement(propertyName)); + } + + Operator op = readOp(); + + skipWhitespace(); + + if (op == Operator.BETWEEN || op == Operator.NOT_BETWEEN) { + final boolean not = (op == Operator.NOT_BETWEEN); + + Object startValue = readValue(); + + String name = readName(); + + if (!"and".equalsIgnoreCase(name)) { + throw new JSONPathException(path); + } + + Object endValue = readValue(); + + if (startValue == null || endValue == null) { + throw new JSONPathException(path); + } + + if (isInt(startValue.getClass()) && isInt(endValue.getClass())) { + Filter filter = new IntBetweenSegement(propertyName, ((Number) startValue).longValue(), + ((Number) endValue).longValue(), not); + return new FilterSegement(filter); + } + + throw new JSONPathException(path); + } + + if (op == Operator.IN || op == Operator.NOT_IN) { + final boolean not = (op == Operator.NOT_IN); + accept('('); + + List valueList = new ArrayList(); + { + Object value = readValue(); + valueList.add(value); + + for (;;) { + skipWhitespace(); + if (ch != ',') { + break; + } + next(); + + value = readValue(); + valueList.add(value); + } + + accept(')'); + if (predicateFlag) { + accept(')'); + } + accept(']'); + } + + boolean isInt = true; + boolean isIntObj = true; + boolean isString = true; + for (Object item : valueList) { + if (item == null) { + if (isInt) { + isInt = false; + } + continue; + } + + Class clazz = item.getClass(); + if (isInt + && !(clazz == Byte.class || clazz == Short.class || clazz == Integer.class || clazz == Long.class)) { + isInt = false; + isIntObj = false; + } + + if (isString && clazz != String.class) { + isString = false; + } + } + + if (valueList.size() == 1 && valueList.get(0) == null) { + if (not) { + return new FilterSegement(new NotNullSegement(propertyName)); + } else { + return new FilterSegement(new NullSegement(propertyName)); + } + } + + if (isInt) { + if (valueList.size() == 1) { + long value = ((Number) valueList.get(0)).longValue(); + Operator intOp = not ? Operator.NE : Operator.EQ; + return new FilterSegement(new IntOpSegement(propertyName, value, intOp)); + } + + long[] values = new long[valueList.size()]; + for (int i = 0; i < values.length; ++i) { + values[i] = ((Number) valueList.get(i)).longValue(); + } + + return new FilterSegement(new IntInSegement(propertyName, values, not)); + } + + if (isString) { + if (valueList.size() == 1) { + String value = (String) valueList.get(0); + + Operator intOp = not ? Operator.NE : Operator.EQ; + return new FilterSegement(new StringOpSegement(propertyName, value, intOp)); + } + + String[] values = new String[valueList.size()]; + valueList.toArray(values); + + return new FilterSegement(new StringInSegement(propertyName, values, not)); + } + + if (isIntObj) { + Long[] values = new Long[valueList.size()]; + for (int i = 0; i < values.length; ++i) { + Number item = (Number) valueList.get(i); + if (item != null) { + values[i] = item.longValue(); + } + } + + return new FilterSegement(new IntObjInSegement(propertyName, values, not)); + } + + throw new UnsupportedOperationException(); + } + + if (ch == '\'' || ch == '"') { + String strValue = readString(); + if (predicateFlag) { + accept(')'); + } + accept(']'); + + if (op == Operator.RLIKE) { + return new FilterSegement(new RlikeSegement(propertyName, strValue, false)); + } + + if (op == Operator.NOT_RLIKE) { + return new FilterSegement(new RlikeSegement(propertyName, strValue, true)); + } + + if (op == Operator.LIKE || op == Operator.NOT_LIKE) { + while (strValue.indexOf("%%") != -1) { + strValue = strValue.replaceAll("%%", "%"); + } + + final boolean not = (op == Operator.NOT_LIKE); + + int p0 = strValue.indexOf('%'); + if (p0 == -1) { + if (op == Operator.LIKE) { + op = Operator.EQ; + } else { + op = Operator.NE; + } + } else { + String[] items = strValue.split("%"); + + String startsWithValue = null; + String endsWithValue = null; + String[] containsValues = null; + if (p0 == 0) { + if (strValue.charAt(strValue.length() - 1) == '%') { + containsValues = new String[items.length - 1]; + System.arraycopy(items, 1, containsValues, 0, containsValues.length); + } else { + endsWithValue = items[items.length - 1]; + if (items.length > 2) { + containsValues = new String[items.length - 2]; + System.arraycopy(items, 1, containsValues, 0, containsValues.length); + } + } + } else if (strValue.charAt(strValue.length() - 1) == '%') { + containsValues = items; + } else { + if (items.length == 1) { + startsWithValue = items[0]; + } else if (items.length == 2) { + startsWithValue = items[0]; + endsWithValue = items[1]; + } else { + startsWithValue = items[0]; + endsWithValue = items[items.length - 1]; + containsValues = new String[items.length - 2]; + System.arraycopy(items, 1, containsValues, 0, containsValues.length); + } + } + + return new FilterSegement(new MatchSegement(propertyName, startsWithValue, endsWithValue, + containsValues, not)); + + } + } + + return new FilterSegement(new StringOpSegement(propertyName, strValue, op)); + } + + if (isDigitFirst(ch)) { + long value = readLongValue(); + + if (predicateFlag) { + accept(')'); + } + accept(']'); + + return new FilterSegement(new IntOpSegement(propertyName, value, op)); + } + + if (ch == 'n') { + String name = readName(); + if ("null".equals(name)) { + if (predicateFlag) { + accept(')'); + } + accept(']'); + + if (op == Operator.EQ) { + return new FilterSegement(new NullSegement(propertyName)); + } + + if (op == Operator.NE) { + return new FilterSegement(new NotNullSegement(propertyName)); + } + + throw new UnsupportedOperationException(); + } + } + + throw new UnsupportedOperationException(); + // accept(')'); + } + + int start = pos - 1; + while (ch != ']' && !isEOF()) { + next(); + } + + String text = path.substring(start, pos - 1); + + if (!isEOF()) { + accept(']'); + } + + return buildArraySegement(text); + } + + protected long readLongValue() { + int beginIndex = pos - 1; + if (ch == '+' || ch == '-') { + next(); + } + + while (ch >= '0' && ch <= '9') { + next(); + } + + int endIndex = pos - 1; + String text = path.substring(beginIndex, endIndex); + long value = Long.parseLong(text); + return value; + } + + protected Object readValue() { + skipWhitespace(); + + if (isDigitFirst(ch)) { + return readLongValue(); + } + + if (ch == '"' || ch == '\'') { + return readString(); + } + + if (ch == 'n') { + String name = readName(); + + if ("null".equals(name)) { + return null; + } else { + throw new JSONPathException(path); + } + } + + throw new UnsupportedOperationException(); + } + + static boolean isDigitFirst(char ch) { + return ch == '-' || ch == '+' || (ch >= '0' && ch <= '9'); + } + + protected Operator readOp() { + Operator op = null; + if (ch == '=') { + next(); + op = Operator.EQ; + } else if (ch == '!') { + next(); + accept('='); + op = Operator.NE; + } else if (ch == '<') { + next(); + if (ch == '=') { + next(); + op = Operator.LE; + } else { + op = Operator.LT; + } + } else if (ch == '>') { + next(); + if (ch == '=') { + next(); + op = Operator.GE; + } else { + op = Operator.GT; + } + } + + if (op == null) { + String name = readName(); + + if ("not".equalsIgnoreCase(name)) { + skipWhitespace(); + + name = readName(); + + if ("like".equalsIgnoreCase(name)) { + op = Operator.NOT_LIKE; + } else if ("rlike".equalsIgnoreCase(name)) { + op = Operator.NOT_RLIKE; + } else if ("in".equalsIgnoreCase(name)) { + op = Operator.NOT_IN; + } else if ("between".equalsIgnoreCase(name)) { + op = Operator.NOT_BETWEEN; + } else { + throw new UnsupportedOperationException(); + } + } else { + if ("like".equalsIgnoreCase(name)) { + op = Operator.LIKE; + } else if ("rlike".equalsIgnoreCase(name)) { + op = Operator.RLIKE; + } else if ("in".equalsIgnoreCase(name)) { + op = Operator.IN; + } else if ("between".equalsIgnoreCase(name)) { + op = Operator.BETWEEN; + } else { + throw new UnsupportedOperationException(); + } + } + } + return op; + } + + String readName() { + skipWhitespace(); + + if (!IOUtils.firstIdentifier(ch)) { + throw new JSONPathException("illeal jsonpath syntax. " + path); + } + + StringBuffer buf = new StringBuffer(); + while (!isEOF()) { + if (ch == '\\') { + next(); + buf.append(ch); + next(); + continue; + } + + boolean identifierFlag = IOUtils.isIdent(ch); + if (!identifierFlag) { + break; + } + buf.append(ch); + next(); + } + + if (isEOF() && IOUtils.isIdent(ch)) { + buf.append(ch); + } + + String propertyName = buf.toString(); + + return propertyName; + } + + String readString() { + char quoate = ch; + next(); + + int beginIndex = pos - 1; + while (ch != quoate && !isEOF()) { + next(); + } + + String strValue = path.substring(beginIndex, isEOF() ? pos : pos - 1); + + accept(quoate); + + return strValue; + } + + void accept(char expect) { + if (ch != expect) { + throw new JSONPathException("expect '" + expect + ", but '" + ch + "'"); + } + + if (!isEOF()) { + next(); + } + } + + public Segement[] explain() { + if (path == null || path.isEmpty()) { + throw new IllegalArgumentException(); + } + + Segement[] segements = new Segement[8]; + + for (;;) { + Segement segment = readSegement(); + if (segment == null) { + break; + } + segements[level++] = segment; + } + + if (level == segements.length) { + return segements; + } + + Segement[] result = new Segement[level]; + System.arraycopy(segements, 0, result, 0, level); + return result; + } + + Segement buildArraySegement(String indexText) { + final int indexTextLen = indexText.length(); + final char firstChar = indexText.charAt(0); + final char lastChar = indexText.charAt(indexTextLen - 1); + + int commaIndex = indexText.indexOf(','); + + if (indexText.length() > 2 && firstChar == '\'' && lastChar == '\'') { + + if (commaIndex == -1) { + String propertyName = indexText.substring(1, indexTextLen - 1); + return new PropertySegement(propertyName); + } + + String[] indexesText = indexText.split(","); + String[] propertyNames = new String[indexesText.length]; + for (int i = 0; i < indexesText.length; ++i) { + String indexesTextItem = indexesText[i]; + propertyNames[i] = indexesTextItem.substring(1, indexesTextItem.length() - 1); + } + + return new MultiPropertySegement(propertyNames); + } + + int colonIndex = indexText.indexOf(':'); + if (commaIndex == -1 && colonIndex == -1) { + int index = Integer.parseInt(indexText); + return new ArrayAccessSegement(index); + } + + if (commaIndex != -1) { + String[] indexesText = indexText.split(","); + int[] indexes = new int[indexesText.length]; + for (int i = 0; i < indexesText.length; ++i) { + indexes[i] = Integer.parseInt(indexesText[i]); + } + return new MultiIndexSegement(indexes); + } + + if (colonIndex != -1) { + String[] indexesText = indexText.split(":"); + int[] indexes = new int[indexesText.length]; + for (int i = 0; i < indexesText.length; ++i) { + String str = indexesText[i]; + if (str.isEmpty()) { + if (i == 0) { + indexes[i] = 0; + } else { + throw new UnsupportedOperationException(); + } + } else { + indexes[i] = Integer.parseInt(str); + } + } + + int start = indexes[0]; + int end; + if (indexes.length > 1) { + end = indexes[1]; + } else { + end = -1; + } + int step; + if (indexes.length == 3) { + step = indexes[2]; + } else { + step = 1; + } + + if (end >= 0 && end < start) { + throw new UnsupportedOperationException("end must greater than or equals start. start " + start + + ", end " + end); + } + + if (step <= 0) { + throw new UnsupportedOperationException("step must greater than zero : " + step); + } + return new RangeSegement(start, end, step); + } + + throw new UnsupportedOperationException(); + } + } + + static interface Segement { + + Object eval(JSONPath path, Object rootObject, Object currentObject); + } + + // static class RootSegement implements Segement { + // + // public final static RootSegement instance = new RootSegement(); + // + // public Object eval(JSONPath path, Object rootObject, Object currentObject) { + // return rootObject; + // } + // } + + static class SelfSegement implements Segement { + + public final static SelfSegement instance = new SelfSegement(); + + public Object eval(JSONPath path, Object rootObject, Object currentObject) { + return currentObject; + } + } + + static class SizeSegement implements Segement { + + public final static SizeSegement instance = new SizeSegement(); + + public Integer eval(JSONPath path, Object rootObject, Object currentObject) { + return path.evalSize(currentObject); + } + } + + static class PropertySegement implements Segement { + + private final String propertyName; + + public PropertySegement(String propertyName){ + this.propertyName = propertyName; + } + + public Object eval(JSONPath path, Object rootObject, Object currentObject) { + return path.getPropertyValue(currentObject, propertyName, true); + } + + public void setValue(JSONPath path, Object parent, Object value) { + path.setPropertyValue(parent, propertyName, value); + } + } + + static class MultiPropertySegement implements Segement { + + private final String[] propertyNames; + + public MultiPropertySegement(String[] propertyNames){ + this.propertyNames = propertyNames; + } + + public Object eval(JSONPath path, Object rootObject, Object currentObject) { + List fieldValues = new ArrayList(propertyNames.length); + + for (String propertyName : propertyNames) { + Object fieldValue = path.getPropertyValue(currentObject, propertyName, true); + fieldValues.add(fieldValue); + } + + return fieldValues; + } + } + + static class WildCardSegement implements Segement { + + public static WildCardSegement instance = new WildCardSegement(); + + public Object eval(JSONPath path, Object rootObject, Object currentObject) { + return path.getPropertyValues(currentObject); + } + + } + + static class ArrayAccessSegement implements Segement { + + private final int index; + + public ArrayAccessSegement(int index){ + this.index = index; + } + + public Object eval(JSONPath path, Object rootObject, Object currentObject) { + return path.getArrayItem(currentObject, index); + } + + public boolean setValue(JSONPath path, Object currentObject, Object value) { + return path.setArrayItem(path, currentObject, index, value); + } + } + + static class MultiIndexSegement implements Segement { + + private final int[] indexes; + + public MultiIndexSegement(int[] indexes){ + this.indexes = indexes; + } + + public Object eval(JSONPath path, Object rootObject, Object currentObject) { + List items = new ArrayList(indexes.length); + for (int i = 0; i < indexes.length; ++i) { + Object item = path.getArrayItem(currentObject, indexes[i]); + items.add(item); + } + return items; + } + } + + static class RangeSegement implements Segement { + + private final int start; + private final int end; + private final int step; + + public RangeSegement(int start, int end, int step){ + this.start = start; + this.end = end; + this.step = step; + } + + public Object eval(JSONPath path, Object rootObject, Object currentObject) { + int size = SizeSegement.instance.eval(path, rootObject, currentObject); + int start = this.start >= 0 ? this.start : this.start + size; + int end = this.end >= 0 ? this.end : this.end + size; + + List items = new ArrayList((end - start) / step + 1); + for (int i = start; i <= end && i < size; i += step) { + Object item = path.getArrayItem(currentObject, i); + items.add(item); + } + return items; + } + } + + static class NotNullSegement implements Filter { + + private final String propertyName; + + public NotNullSegement(String propertyName){ + this.propertyName = propertyName; + } + + public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { + Object propertyValue = path.getPropertyValue(item, propertyName, false); + + return propertyValue != null; + } + } + + static class NullSegement implements Filter { + + private final String propertyName; + + public NullSegement(String propertyName){ + this.propertyName = propertyName; + } + + public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { + Object propertyValue = path.getPropertyValue(item, propertyName, false); + + return propertyValue == null; + } + } + + static class IntInSegement implements Filter { + + private final String propertyName; + private final long[] values; + private final boolean not; + + public IntInSegement(String propertyName, long[] values, boolean not){ + this.propertyName = propertyName; + this.values = values; + this.not = not; + } + + public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { + Object propertyValue = path.getPropertyValue(item, propertyName, false); + + if (propertyValue == null) { + return false; + } + + if (propertyValue instanceof Number) { + long longPropertyValue = ((Number) propertyValue).longValue(); + for (long value : values) { + if (value == longPropertyValue) { + return !not; + } + } + } + + return not; + } + } + + static class IntBetweenSegement implements Filter { + + private final String propertyName; + private final long startValue; + private final long endValue; + private final boolean not; + + public IntBetweenSegement(String propertyName, long startValue, long endValue, boolean not){ + this.propertyName = propertyName; + this.startValue = startValue; + this.endValue = endValue; + this.not = not; + } + + public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { + Object propertyValue = path.getPropertyValue(item, propertyName, false); + + if (propertyValue == null) { + return false; + } + + if (propertyValue instanceof Number) { + long longPropertyValue = ((Number) propertyValue).longValue(); + if (longPropertyValue >= startValue && longPropertyValue <= endValue) { + return !not; + } + } + + return not; + } + } + + static class IntObjInSegement implements Filter { + + private final String propertyName; + private final Long[] values; + private final boolean not; + + public IntObjInSegement(String propertyName, Long[] values, boolean not){ + this.propertyName = propertyName; + this.values = values; + this.not = not; + } + + public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { + Object propertyValue = path.getPropertyValue(item, propertyName, false); + + if (propertyValue == null) { + for (Long value : values) { + if (value == null) { + return !not; + } + } + + return not; + } + + if (propertyValue instanceof Number) { + long longPropertyValue = ((Number) propertyValue).longValue(); + for (Long value : values) { + if (value == null) { + continue; + } + + if (value.longValue() == longPropertyValue) { + return !not; + } + } + } + + return not; + } + } + + static class StringInSegement implements Filter { + + private final String propertyName; + private final String[] values; + private final boolean not; + + public StringInSegement(String propertyName, String[] values, boolean not){ + this.propertyName = propertyName; + this.values = values; + this.not = not; + } + + public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { + Object propertyValue = path.getPropertyValue(item, propertyName, false); + + for (String value : values) { + if (value == propertyValue) { + return !not; + } else if (value != null && value.equals(propertyValue)) { + return !not; + } + } + + return not; + } + } + + static class IntOpSegement implements Filter { + + private final String propertyName; + private final long value; + private final Operator op; + + public IntOpSegement(String propertyName, long value, Operator op){ + this.propertyName = propertyName; + this.value = value; + this.op = op; + } + + public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { + Object propertyValue = path.getPropertyValue(item, propertyName, false); + + if (propertyValue == null) { + return false; + } + + if (!(propertyValue instanceof Number)) { + return false; + } + + long longValue = ((Number) propertyValue).longValue(); + + if (op == Operator.EQ) { + return longValue == value; + } else if (op == Operator.NE) { + return longValue != value; + } else if (op == Operator.GE) { + return longValue >= value; + } else if (op == Operator.GT) { + return longValue > value; + } else if (op == Operator.LE) { + return longValue <= value; + } else if (op == Operator.LT) { + return longValue < value; + } + + return false; + } + + } + + static class MatchSegement implements Filter { + + private final String propertyName; + private final String startsWithValue; + private final String endsWithValue; + private final String[] containsValues; + private final int minLength; + private final boolean not; + + public MatchSegement(String propertyName, String startsWithValue, String endsWithValue, + String[] containsValues, boolean not){ + this.propertyName = propertyName; + this.startsWithValue = startsWithValue; + this.endsWithValue = endsWithValue; + this.containsValues = containsValues; + this.not = not; + + int len = 0; + if (startsWithValue != null) { + len += startsWithValue.length(); + } + + if (endsWithValue != null) { + len += endsWithValue.length(); + } + + if (containsValues != null) { + for (String item : containsValues) { + len += item.length(); + } + } + + this.minLength = len; + } + + public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { + Object propertyValue = path.getPropertyValue(item, propertyName, false); + + if (propertyValue == null) { + return false; + } + + final String strPropertyValue = propertyValue.toString(); + + if (strPropertyValue.length() < minLength) { + return not; + } + + int start = 0; + if (startsWithValue != null) { + if (!strPropertyValue.startsWith(startsWithValue)) { + return not; + } + start += startsWithValue.length(); + } + + if (containsValues != null) { + for (String containsValue : containsValues) { + int index = strPropertyValue.indexOf(containsValue, start); + if (index == -1) { + return not; + } + start = index + containsValue.length(); + } + } + + if (endsWithValue != null) { + if (!strPropertyValue.endsWith(endsWithValue)) { + return not; + } + } + + return !not; + } + } + + static class RlikeSegement implements Filter { + + private final String propertyName; + private final Pattern pattern; + private final boolean not; + + public RlikeSegement(String propertyName, String pattern, boolean not){ + this.propertyName = propertyName; + this.pattern = Pattern.compile(pattern); + this.not = not; + } + + public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { + Object propertyValue = path.getPropertyValue(item, propertyName, false); + + if (propertyValue == null) { + return false; + } + + String strPropertyValue = propertyValue.toString(); + Matcher m = pattern.matcher(strPropertyValue); + boolean match = m.matches(); + + if (not) { + match = !match; + } + + return match; + } + } + + static class StringOpSegement implements Filter { + + private final String propertyName; + private final String value; + private final Operator op; + + public StringOpSegement(String propertyName, String value, Operator op){ + this.propertyName = propertyName; + this.value = value; + this.op = op; + } + + public boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item) { + Object propertyValue = path.getPropertyValue(item, propertyName, false); + + if (op == Operator.EQ) { + return value.equals(propertyValue); + } else if (op == Operator.NE) { + return !value.equals(propertyValue); + } + + if (propertyValue == null) { + return false; + } + + int compareResult = value.compareTo(propertyValue.toString()); + if (op == Operator.GE) { + return compareResult <= 0; + } else if (op == Operator.GT) { + return compareResult < 0; + } else if (op == Operator.LE) { + return compareResult >= 0; + } else if (op == Operator.LT) { + return compareResult > 0; + } + + return false; + } + } + + static enum Operator { + EQ, NE, GT, GE, LT, LE, LIKE, NOT_LIKE, RLIKE, NOT_RLIKE, IN, NOT_IN, BETWEEN, NOT_BETWEEN + } + + static public class FilterSegement implements Segement { + + private final Filter filter; + + public FilterSegement(Filter filter){ + super(); + this.filter = filter; + } + + @SuppressWarnings("rawtypes") + public Object eval(JSONPath path, Object rootObject, Object currentObject) { + if (currentObject == null) { + return null; + } + + List items = new ArrayList(); + + if (currentObject instanceof Iterable) { + Iterator it = ((Iterable) currentObject).iterator(); + while (it.hasNext()) { + Object item = it.next(); + + if (filter.apply(path, rootObject, currentObject, item)) { + items.add(item); + } + } + + return items; + } + + if (filter.apply(path, rootObject, currentObject, currentObject)) { + return currentObject; + } + + return null; + } + } + + static interface Filter { + + boolean apply(JSONPath path, Object rootObject, Object currentObject, Object item); + } + + @SuppressWarnings("rawtypes") + protected Object getArrayItem(final Object currentObject, int index) { + if (currentObject == null) { + return null; + } + + if (currentObject instanceof List) { + List list = (List) currentObject; + + if (index >= 0) { + if (index < list.size()) { + return list.get(index); + } + return null; + } else { + if (Math.abs(index) <= list.size()) { + return list.get(list.size() + index); + } + return null; + } + } + + if (currentObject.getClass().isArray()) { + int arrayLenth = Array.getLength(currentObject); + + if (index >= 0) { + if (index < arrayLenth) { + return Array.get(currentObject, index); + } + return null; + } else { + if (Math.abs(index) <= arrayLenth) { + return Array.get(currentObject, arrayLenth + index); + } + return null; + } + } + + throw new UnsupportedOperationException(); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public boolean setArrayItem(JSONPath path, Object currentObject, int index, Object value) { + if (currentObject instanceof List) { + List list = (List) currentObject; + if (index >= 0) { + list.set(index, value); + } else { + list.set(list.size() + index, value); + } + return true; + } + + if (currentObject.getClass().isArray()) { + int arrayLenth = Array.getLength(currentObject); + + if (index >= 0) { + if (index < arrayLenth) { + Array.set(currentObject, index, value); + } + } else { + if (Math.abs(index) <= arrayLenth) { + Array.set(currentObject, arrayLenth + index, value); + } + } + + return true; + } + + throw new UnsupportedOperationException(); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected Collection getPropertyValues(final Object currentObject) { + final Class currentClass = currentObject.getClass(); + + JavaBeanSerializer beanSerializer = getJavaBeanSerializer(currentClass); + + if (beanSerializer != null) { + try { + return beanSerializer.getFieldValues(currentObject); + } catch (Exception e) { + throw new JSONPathException("jsonpath error, path " + path, e); + } + } + + if (currentObject instanceof Map) { + Map map = (Map) currentObject; + return map.values(); + } + + throw new UnsupportedOperationException(); + } + + static boolean eq(Object a, Object b) { + if (a == b) { + return true; + } + + if (a == null || b == null) { + return false; + } + + if (a.getClass() == b.getClass()) { + return a.equals(b); + } + + if (a instanceof Number) { + if (b instanceof Number) { + return eqNotNull((Number) a, (Number) b); + } + + return false; + } + + return a.equals(b); + } + + @SuppressWarnings("rawtypes") + static boolean eqNotNull(Number a, Number b) { + Class clazzA = a.getClass(); + boolean isIntA = isInt(clazzA); + + Class clazzB = a.getClass(); + boolean isIntB = isInt(clazzB); + + if (isIntA && isIntB) { + return a.longValue() == b.longValue(); + } + + boolean isDoubleA = isDouble(clazzA); + boolean isDoubleB = isDouble(clazzB); + + if ((isDoubleA && isDoubleB) || (isDoubleA && isIntA) || (isDoubleB && isIntA)) { + return a.doubleValue() == b.doubleValue(); + } + + return false; + } + + protected static boolean isDouble(Class clazzA) { + return clazzA == Float.class || clazzA == Double.class; + } + + protected static boolean isInt(Class clazzA) { + return clazzA == Byte.class || clazzA == Short.class || clazzA == Integer.class || clazzA == Long.class; + } + + @SuppressWarnings("rawtypes") + protected Object getPropertyValue(final Object currentObject, final String propertyName, boolean strictMode) { + if (currentObject == null) { + return null; + } + + if (currentObject instanceof Map) { + Map map = (Map) currentObject; + return map.get(propertyName); + } + + final Class currentClass = currentObject.getClass(); + + JavaBeanSerializer beanSerializer = getJavaBeanSerializer(currentClass); + if (beanSerializer != null) { + try { + return beanSerializer.getFieldValue(currentObject, propertyName); + } catch (Exception e) { + throw new JSONPathException("jsonpath error, path " + path + ", segement " + propertyName, e); + } + } + + if (currentObject instanceof List) { + List list = (List) currentObject; + + List fieldValues = new ArrayList(list.size()); + + for (int i = 0; i < list.size(); ++i) { + Object obj = list.get(i); + Object itemValue = getPropertyValue(obj, propertyName, strictMode); + fieldValues.add(itemValue); + } + + return fieldValues; + } + throw new JSONPathException("jsonpath error, path " + path + ", segement " + propertyName); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected boolean setPropertyValue(Object parent, String name, Object value) { + if (parent instanceof Map) { + ((Map) parent).put(name, value); + return true; + } + + ObjectDeserializer derializer = parserConfig.getDeserializer(parent.getClass()); + + JavaBeanDeserializer beanDerializer = null; + if (derializer instanceof JavaBeanDeserializer) { + beanDerializer = (JavaBeanDeserializer) derializer; + } else if (derializer instanceof ASMJavaBeanDeserializer) { + beanDerializer = ((ASMJavaBeanDeserializer) derializer).getInnterSerializer(); + } + + if (beanDerializer != null) { + FieldDeserializer fieldDeserializer = beanDerializer.getFieldDeserializer(name); + if (fieldDeserializer == null) { + return false; + } + + fieldDeserializer.setValue(parent, value); + return true; + } + + throw new UnsupportedOperationException(); + } + + protected JavaBeanSerializer getJavaBeanSerializer(final Class currentClass) { + JavaBeanSerializer beanSerializer = null; + { + ObjectSerializer serializer = serializeConfig.getObjectWriter(currentClass); + if (serializer instanceof JavaBeanSerializer) { + beanSerializer = (JavaBeanSerializer) serializer; + } else if (serializer instanceof ASMJavaBeanSerializer) { + beanSerializer = ((ASMJavaBeanSerializer) serializer).getJavaBeanSerializer(); + } + } + return beanSerializer; + } + + @SuppressWarnings("rawtypes") + int evalSize(Object currentObject) { + if (currentObject == null) { + return -1; + } + + if (currentObject instanceof Collection) { + return ((Collection) currentObject).size(); + } + + if (currentObject instanceof Object[]) { + return ((Object[]) currentObject).length; + } + + if (currentObject.getClass().isArray()) { + return Array.getLength(currentObject); + } + + if (currentObject instanceof Map) { + int count = 0; + + for (Object value : ((Map) currentObject).values()) { + if (value != null) { + count++; + } + } + return count; + } + + JavaBeanSerializer beanSerializer = getJavaBeanSerializer(currentObject.getClass()); + + if (beanSerializer == null) { + return -1; + } + + try { + List values = beanSerializer.getFieldValues(currentObject); + + int count = 0; + for (int i = 0; i < values.size(); ++i) { + if (values.get(i) != null) { + count++; + } + } + return count; + } catch (Exception e) { + throw new JSONException("evalSize error : " + path, e); + } + } + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) + throws IOException { + serializer.write(path); + } +} diff --git a/src/main/java/com/alibaba/fastjson/JSONPathException.java b/src/main/java/com/alibaba/fastjson/JSONPathException.java new file mode 100644 index 0000000000..4e403f8a20 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/JSONPathException.java @@ -0,0 +1,14 @@ +package com.alibaba.fastjson; + +public class JSONPathException extends JSONException { + + private static final long serialVersionUID = 1L; + + public JSONPathException(String message){ + super(message); + } + + public JSONPathException(String message, Throwable cause){ + super(message, cause); + } +} diff --git a/src/main/java/com/alibaba/fastjson/JSONReader.java b/src/main/java/com/alibaba/fastjson/JSONReader.java new file mode 100644 index 0000000000..f0064fb677 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/JSONReader.java @@ -0,0 +1,301 @@ +package com.alibaba.fastjson; + +import static com.alibaba.fastjson.JSONStreamContext.ArrayValue; +import static com.alibaba.fastjson.JSONStreamContext.PropertyKey; +import static com.alibaba.fastjson.JSONStreamContext.PropertyValue; +import static com.alibaba.fastjson.JSONStreamContext.StartArray; +import static com.alibaba.fastjson.JSONStreamContext.StartObject; + +import java.io.Closeable; +import java.io.Reader; +import java.lang.reflect.Type; +import java.util.Map; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONReaderScanner; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.util.IOUtils; +import com.alibaba.fastjson.util.TypeUtils; + +public class JSONReader implements Closeable { + + private final DefaultJSONParser parser; + private JSONStreamContext context; + + public JSONReader(Reader reader){ + this(new JSONReaderScanner(reader)); + } + + public JSONReader(JSONLexer lexer){ + this(new DefaultJSONParser(lexer)); + } + + public JSONReader(DefaultJSONParser parser){ + this.parser = parser; + } + + public void config(Feature feature, boolean state) { + this.parser.config(feature, state); + } + + public void startObject() { + if (context == null) { + context = new JSONStreamContext(null, JSONStreamContext.StartObject); + } else { + startStructure(); + context = new JSONStreamContext(context, JSONStreamContext.StartObject); + } + + this.parser.accept(JSONToken.LBRACE, JSONToken.IDENTIFIER); + } + + public void endObject() { + this.parser.accept(JSONToken.RBRACE); + endStructure(); + } + + public void startArray() { + if (context == null) { + context = new JSONStreamContext(null, StartArray); + } else { + startStructure(); + + context = new JSONStreamContext(context, StartArray); + } + this.parser.accept(JSONToken.LBRACKET); + } + + public void endArray() { + this.parser.accept(JSONToken.RBRACKET); + endStructure(); + } + + private void startStructure() { + final int state = context.getState(); + switch (state) { + case PropertyKey: + parser.accept(JSONToken.COLON); + break; + case PropertyValue: + case ArrayValue: + parser.accept(JSONToken.COMMA); + break; + case StartArray: + case StartObject: + break; + default: + throw new JSONException("illegal state : " + context.getState()); + } + } + + private void endStructure() { + context = context.getParent(); + + if (context == null) { + return; + } + + final int state = context.getState(); + int newState = -1; + switch (state) { + case PropertyKey: + newState = PropertyValue; + break; + case StartArray: + newState = ArrayValue; + break; + case PropertyValue: + case StartObject: + newState = PropertyKey; + break; + default: + break; + } + if (newState != -1) { + context.setState(newState); + } + } + + public boolean hasNext() { + if (context == null) { + throw new JSONException("context is null"); + } + + final int token = parser.getLexer().token(); + final int state = context.getState(); + switch (state) { + case StartArray: + case ArrayValue: + return token != JSONToken.RBRACKET; + case StartObject: + case PropertyValue: + return token != JSONToken.RBRACE; + default: + throw new JSONException("illegal state : " + state); + } + } + + public void close() { + IOUtils.close(parser); + } + + public Integer readInteger() { + Object object; + if (context == null) { + object = parser.parse(); + } else { + readBefore(); + object = parser.parse(); + readAfter(); + } + + return TypeUtils.castToInt(object); + } + + public Long readLong() { + Object object; + if (context == null) { + object = parser.parse(); + } else { + readBefore(); + object = parser.parse(); + readAfter(); + } + + return TypeUtils.castToLong(object); + } + + public String readString() { + Object object; + if (context == null) { + object = parser.parse(); + } else { + readBefore(); + object = parser.parse(); + readAfter(); + } + + return TypeUtils.castToString(object); + } + + public T readObject(TypeReference typeRef) { + return readObject(typeRef.getType()); + } + + public T readObject(Type type) { + if (context == null) { + return parser.parseObject(type); + } + + readBefore(); + T object = parser.parseObject(type); + readAfter(); + return object; + } + + public T readObject(Class type) { + if (context == null) { + return parser.parseObject(type); + } + + readBefore(); + T object = parser.parseObject(type); + readAfter(); + return object; + } + + public void readObject(Object object) { + if (context == null) { + parser.parseObject(object); + return; + } + + readBefore(); + parser.parseObject(object); + readAfter(); + } + + public Object readObject() { + if (context == null) { + return parser.parse(); + } + + readBefore(); + Object object; + switch (context.getState()) { + case StartObject: + case PropertyValue: + object = parser.parseKey(); + break; + default: + object = parser.parse(); + break; + } + + readAfter(); + return object; + } + + @SuppressWarnings("rawtypes") + public Object readObject(Map object) { + if (context == null) { + return parser.parseObject(object); + } + + readBefore(); + Object value = parser.parseObject(object); + readAfter(); + return value; + } + + private void readBefore() { + int state = context.getState(); + // before + switch (state) { + case PropertyKey: + parser.accept(JSONToken.COLON); + break; + case PropertyValue: + parser.accept(JSONToken.COMMA, JSONToken.IDENTIFIER); + break; + case ArrayValue: + parser.accept(JSONToken.COMMA); + break; + case StartObject: + break; + case StartArray: + break; + default: + throw new JSONException("illegal state : " + state); + } + } + + private void readAfter() { + int state = context.getState(); + int newStat = -1; + switch (state) { + case StartObject: + newStat = PropertyKey; + break; + case PropertyKey: + newStat = PropertyValue; + break; + case PropertyValue: + newStat = PropertyKey; + break; + case ArrayValue: + break; + case StartArray: + newStat = ArrayValue; + break; + default: + throw new JSONException("illegal state : " + state); + } + if (newStat != -1) { + context.setState(newStat); + } + } + +} diff --git a/src/main/java/com/alibaba/fastjson/JSONStreamAware.java b/src/main/java/com/alibaba/fastjson/JSONStreamAware.java old mode 100644 new mode 100755 index 99ae8f4af9..e889e6cfff --- a/src/main/java/com/alibaba/fastjson/JSONStreamAware.java +++ b/src/main/java/com/alibaba/fastjson/JSONStreamAware.java @@ -20,7 +20,7 @@ /** * Beans that support customized output of JSON text to a writer shall implement this interface. * - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public interface JSONStreamAware { diff --git a/src/main/java/com/alibaba/fastjson/JSONStreamContext.java b/src/main/java/com/alibaba/fastjson/JSONStreamContext.java new file mode 100644 index 0000000000..78f71ebb1c --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/JSONStreamContext.java @@ -0,0 +1,32 @@ +package com.alibaba.fastjson; + +class JSONStreamContext { + + final static int StartObject = 1001; + final static int PropertyKey = 1002; + final static int PropertyValue = 1003; + final static int StartArray = 1004; + final static int ArrayValue = 1005; + + private final JSONStreamContext parent; + + private int state; + + public JSONStreamContext(JSONStreamContext parent, int state){ + this.parent = parent; + this.state = state; + } + + public JSONStreamContext getParent() { + return parent; + } + + public int getState() { + return state; + } + + public void setState(int state) { + this.state = state; + } + +} diff --git a/src/main/java/com/alibaba/fastjson/JSONWriter.java b/src/main/java/com/alibaba/fastjson/JSONWriter.java new file mode 100755 index 0000000000..9972b7b0d1 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/JSONWriter.java @@ -0,0 +1,205 @@ +package com.alibaba.fastjson; + +import java.io.Closeable; +import java.io.Flushable; +import java.io.IOException; +import java.io.Writer; + +import static com.alibaba.fastjson.JSONStreamContext.*; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class JSONWriter implements Closeable, Flushable { + + private SerializeWriter writer; + + private JSONSerializer serializer; + + private JSONStreamContext context; + + public JSONWriter(Writer out){ + writer = new SerializeWriter(out); + serializer = new JSONSerializer(writer); + } + + public void config(SerializerFeature feature, boolean state) { + this.writer.config(feature, state); + } + + public void startObject() { + if (context != null) { + beginStructure(); + } + context = new JSONStreamContext(context, JSONStreamContext.StartObject); + writer.write('{'); + } + + public void endObject() { + writer.write('}'); + endStructure(); + } + + public void writeKey(String key) { + writeObject(key); + } + + public void writeValue(Object object) { + writeObject(object); + } + + public void writeObject(String object) { + beforeWrite(); + + serializer.write(object); + + afterWriter(); + } + + public void writeObject(Object object) { + beforeWrite(); + serializer.write(object); + afterWriter(); + } + + public void startArray() { + if (context != null) { + beginStructure(); + } + + context = new JSONStreamContext(context, StartArray); + writer.write('['); + } + + private void beginStructure() { + final int state = context.getState(); + switch (state) { + case PropertyKey: + writer.write(':'); + break; + case ArrayValue: + writer.write(','); + break; + case StartObject: + break; + case StartArray: + break; + default: + throw new JSONException("illegal state : " + state); + } + } + + public void endArray() { + writer.write(']'); + endStructure(); + } + + private void endStructure() { + context = context.getParent(); + + if (context == null) { + return; + } + + final int state = context.getState(); + int newState = -1; + switch (state) { + case PropertyKey: + newState = PropertyValue; + break; + case StartArray: + newState = ArrayValue; + break; + case ArrayValue: + break; + case StartObject: + newState = PropertyKey; + break; + default: + break; + } + if (newState != -1) { + context.setState(newState); + } + } + + private void beforeWrite() { + if (context == null) { + return; + } + + switch (context.getState()) { + case StartObject: + case StartArray: + break; + case PropertyKey: + writer.write(':'); + break; + case PropertyValue: + writer.write(','); + break; + case ArrayValue: + writer.write(','); + break; + default: + break; + } + } + + private void afterWriter() { + if (context == null) { + return; + } + + final int state = context.getState(); + int newState = -1; + switch (state) { + case PropertyKey: + newState = PropertyValue; + break; + case StartObject: + case PropertyValue: + newState = PropertyKey; + break; + case StartArray: + newState = ArrayValue; + break; + case ArrayValue: + break; + default: + break; + } + + if (newState != -1) { + context.setState(newState); + } + } + + public void flush() throws IOException { + writer.flush(); + } + + public void close() throws IOException { + writer.close(); + } + + @Deprecated + public void writeStartObject() { + startObject(); + } + + @Deprecated + public void writeEndObject() { + endObject(); + } + + @Deprecated + public void writeStartArray() { + startArray(); + } + + @Deprecated + public void writeEndArray() { + endArray(); + } +} diff --git a/src/main/java/com/alibaba/fastjson/TypeReference.java b/src/main/java/com/alibaba/fastjson/TypeReference.java old mode 100644 new mode 100755 diff --git a/src/main/java/com/alibaba/fastjson/annotation/JSONCreator.java b/src/main/java/com/alibaba/fastjson/annotation/JSONCreator.java new file mode 100755 index 0000000000..10224689d0 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/annotation/JSONCreator.java @@ -0,0 +1,12 @@ +package com.alibaba.fastjson.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.CONSTRUCTOR, ElementType.METHOD }) +public @interface JSONCreator { + +} diff --git a/src/main/java/com/alibaba/fastjson/annotation/JSONField.java b/src/main/java/com/alibaba/fastjson/annotation/JSONField.java old mode 100644 new mode 100755 index 2078031a6c..669bd3b81c --- a/src/main/java/com/alibaba/fastjson/annotation/JSONField.java +++ b/src/main/java/com/alibaba/fastjson/annotation/JSONField.java @@ -24,11 +24,17 @@ import com.alibaba.fastjson.serializer.SerializerFeature; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ @Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.METHOD, ElementType.FIELD }) +@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER }) public @interface JSONField { + /** + * config encode/decode ordinal + * @since 1.1.42 + * @return + */ + int ordinal() default 0; String name() default ""; diff --git a/src/main/java/com/alibaba/fastjson/annotation/JSONType.java b/src/main/java/com/alibaba/fastjson/annotation/JSONType.java new file mode 100755 index 0000000000..6d0374072e --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/annotation/JSONType.java @@ -0,0 +1,30 @@ +package com.alibaba.fastjson.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE }) +public @interface JSONType { + + boolean asm() default true; + + String[] orders() default {}; + + String[] ignores() default {}; + + SerializerFeature[] serialzeFeatures() default {}; + Feature[] parseFeatures() default {}; + + boolean alphabetic() default true; + + Class mappingTo() default Void.class; +} diff --git a/src/main/java/com/alibaba/fastjson/asm/ASMException.java b/src/main/java/com/alibaba/fastjson/asm/ASMException.java new file mode 100755 index 0000000000..350f9aff6a --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/asm/ASMException.java @@ -0,0 +1,12 @@ +package com.alibaba.fastjson.asm; + +import com.alibaba.fastjson.JSONException; + +public class ASMException extends JSONException { + + private static final long serialVersionUID = 1L; + + public ASMException(String message){ + super(message); + } +} diff --git a/src/main/java/com/alibaba/fastjson/asm/ByteVector.java b/src/main/java/com/alibaba/fastjson/asm/ByteVector.java old mode 100644 new mode 100755 diff --git a/src/main/java/com/alibaba/fastjson/asm/ClassWriter.java b/src/main/java/com/alibaba/fastjson/asm/ClassWriter.java old mode 100644 new mode 100755 index 08edae65fc..1c93e0883d --- a/src/main/java/com/alibaba/fastjson/asm/ClassWriter.java +++ b/src/main/java/com/alibaba/fastjson/asm/ClassWriter.java @@ -30,9 +30,6 @@ package com.alibaba.fastjson.asm; /** - * A {@link ClassVisitor} that generates classes in bytecode form. More precisely this visitor generates a byte array - * conforming to the Java class file format. It can be used alone, to generate a Java class "from scratch", or with one - * or more and adapter class visitor to generate a modified class from one or more existing Java classes. * * @author Eric Bruneton */ @@ -50,8 +47,8 @@ public class ClassWriter { /** * Flag to automatically compute the stack map frames of methods from scratch. If this flag is set, then the calls - * to the {@link MethodVisitor#visitFrame} method are ignored, and the stack map frames are recomputed from the - * methods bytecode. The arguments of the {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and + * to the MethodVisitor#visitFrame method are ignored, and the stack map frames are recomputed from the + * methods bytecode. The arguments of the MethodVisitor#visitMaxs method are also ignored and * recomputed from the bytecode. In other words, computeFrames implies computeMaxs. * * @see #ClassWriter(int) @@ -467,9 +464,6 @@ public MethodVisitor visitMethod(final int access, final String name, final Stri return new MethodWriter(this, access, name, desc, signature, exceptions); } - public void visitEnd() { - } - // ------------------------------------------------------------------------ // Other public methods // ------------------------------------------------------------------------ @@ -538,7 +532,10 @@ public byte[] toByteArray() { * @return a new or already existing constant item with the given value. */ Item newConstItem(final Object cst) { - if (cst instanceof String) { + if (cst instanceof Integer) { + int val = ((Integer) cst).intValue(); + return newInteger(val); + } else if (cst instanceof String) { return newString((String) cst); } else if (cst instanceof Type) { Type t = (Type) cst; @@ -547,6 +544,17 @@ Item newConstItem(final Object cst) { throw new IllegalArgumentException("value " + cst); } } + + Item newInteger(final int value) { + key.set(value); + Item result = get(key); + if (result == null) { + pool.putByte(INT).putInt(value); + result = new Item(index++, key); + put(result); + } + return result; + } public int newUTF8(final String value) { key.set(UTF8, value, null, null); diff --git a/src/main/java/com/alibaba/fastjson/asm/FieldVisitor.java b/src/main/java/com/alibaba/fastjson/asm/FieldVisitor.java old mode 100644 new mode 100755 diff --git a/src/main/java/com/alibaba/fastjson/asm/FieldWriter.java b/src/main/java/com/alibaba/fastjson/asm/FieldWriter.java old mode 100644 new mode 100755 diff --git a/src/main/java/com/alibaba/fastjson/asm/Item.java b/src/main/java/com/alibaba/fastjson/asm/Item.java old mode 100644 new mode 100755 index 1b1a559892..a7ae9f3153 --- a/src/main/java/com/alibaba/fastjson/asm/Item.java +++ b/src/main/java/com/alibaba/fastjson/asm/Item.java @@ -141,6 +141,17 @@ void set(final int type, final String strVal1, final String strVal2, final Strin hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() * strVal2.hashCode() * strVal3.hashCode()); } } + + /** + * Sets this item to an integer item. + * + * @param intVal the value of this item. + */ + void set(final int intVal) { + this.type = ClassWriter.INT; + this.intVal = intVal; + this.hashCode = 0x7FFFFFFF & (type + intVal); + } /** * Indicates if the given item is equal to this one. This method assumes that the two items have the same @@ -163,8 +174,6 @@ boolean isEqualTo(final Item i) { case ClassWriter.INT: case ClassWriter.FLOAT: return i.intVal == intVal; - case ClassWriter.TYPE_UNINIT: - return i.intVal == intVal && i.strVal1.equals(strVal1); case ClassWriter.NAME_TYPE: return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2); // case ClassWriter.FIELD: diff --git a/src/main/java/com/alibaba/fastjson/asm/Label.java b/src/main/java/com/alibaba/fastjson/asm/Label.java old mode 100644 new mode 100755 index 5adbd03e1c..0d1119c0c2 --- a/src/main/java/com/alibaba/fastjson/asm/Label.java +++ b/src/main/java/com/alibaba/fastjson/asm/Label.java @@ -47,7 +47,7 @@ public class Label { /** * Field used to associate user information to a label. Warning: this field is used by the ASM tree package. In * order to use it with the ASM tree package you must override the - * {@link com.alibaba.fastjson.asm.tree.MethodNode#getLabelNode} method. + *com.alibaba.fastjson.asm.tree.MethodNode#getLabelNode method. */ public Object info; @@ -74,7 +74,7 @@ public class Label { * reference, while the second is the position of the first byte of the forward reference itself. In fact the sign * of the first integer indicates if this reference uses 2 or 4 bytes, and its absolute value gives the position of * the bytecode instruction. This array is also used as a bitset to store the subroutines to which a basic block - * belongs. This information is needed in {@linked MethodWriter#visitMaxs}, after all forward references have been + * belongs. This information is needed in MethodWriter#visitMaxs, after all forward references have been * resolved. Hence the same array can be used for both purposes without problems. */ private int[] srcAndRefPositions; @@ -90,7 +90,7 @@ public class Label { * stack map frames are similar and use two steps. The first step, during the visit of each instruction, builds * information about the state of the local variables and the operand stack at the end of each basic block, called * the "output frame", relatively to the frame state at the beginning of the basic block, which is called the - * "input frame", and which is unknown during this step. The second step, in {@link MethodWriter#visitMaxs}, + * "input frame", and which is unknown during this step. The second step, in link MethodWriter#visitMaxs, * is a fix point algorithm that computes information about the input frame of each basic block, from the input * state of the first basic block (known from the method signature), and by the using the previously computed * relative output frames. The algorithm used to compute the maximum stack size only computes the relative output @@ -117,7 +117,7 @@ public class Label { /** * The successor of this label, in the order they are visited. This linked list does not include labels used for - * debug info only. If {@link ClassWriter#COMPUTE_FRAMES} option is used then, in addition, it does not contain + * debug info only. If ClassWriter#COMPUTE_FRAMES option is used then, in addition, it does not contain * successive labels that denote the same bytecode position (in this case only the first label appears in this * list). */ @@ -204,45 +204,18 @@ private void addReference(final int sourcePosition, final int referencePosition) * @throws IllegalArgumentException if this label has already been resolved, or if it has not been created by the * given code writer. */ - boolean resolve(final MethodWriter owner, final int position, final byte[] data) { - boolean needUpdate = false; + void resolve(final MethodWriter owner, final int position, final byte[] data) { this.status |= RESOLVED; this.position = position; int i = 0; while (i < referenceCount) { int source = srcAndRefPositions[i++]; int reference = srcAndRefPositions[i++]; - int offset; - if (source >= 0) { - offset = position - source; - if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE) { - /* - * changes the opcode of the jump instruction, in order to be able to find it later (see - * resizeInstructions in MethodWriter). These temporary opcodes are similar to jump instruction - * opcodes, except that the 2 bytes offset is unsigned (and can therefore represent values from 0 to - * 65535, which is sufficient since the size of a method is limited to 65535 bytes). - */ - int opcode = data[reference - 1] & 0xFF; - if (opcode <= Opcodes.JSR) { - // changes IFEQ ... JSR to opcodes 202 to 217 - data[reference - 1] = (byte) (opcode + 49); - } else { - // changes IFNULL and IFNONNULL to opcodes 218 and 219 - data[reference - 1] = (byte) (opcode + 20); - } - needUpdate = true; - } - data[reference++] = (byte) (offset >>> 8); - data[reference] = (byte) offset; - } else { - offset = position + source + 1; - data[reference++] = (byte) (offset >>> 24); - data[reference++] = (byte) (offset >>> 16); - data[reference++] = (byte) (offset >>> 8); - data[reference] = (byte) offset; - } + int offset = position - source; + data[reference++] = (byte) (offset >>> 8); + data[reference] = (byte) offset; + } - return needUpdate; } } diff --git a/src/main/java/com/alibaba/fastjson/asm/MethodVisitor.java b/src/main/java/com/alibaba/fastjson/asm/MethodVisitor.java old mode 100644 new mode 100755 index 1c916ddd16..cd45660d59 --- a/src/main/java/com/alibaba/fastjson/asm/MethodVisitor.java +++ b/src/main/java/com/alibaba/fastjson/asm/MethodVisitor.java @@ -30,15 +30,6 @@ package com.alibaba.fastjson.asm; /** - * A visitor to visit a Java method. The methods of this interface must be called in the following order: [ - * visitAnnotationDefault ] ( visitAnnotation | visitParameterAnnotation | - * visitAttribute )* [ visitCode ( visitFrame | visitXInsn | - * visitLabel | visitTryCatchBlock | visitLocalVariable | visitLineNumber)* - * visitMaxs ] visitEnd. In addition, the visitXInsn and visitLabel - * methods must be called in the sequential order of the bytecode instructions of the visited code, - * visitTryCatchBlock must be called before the labels passed as arguments have been visited, and the - * visitLocalVariable and visitLineNumber methods must be called after the labels passed as - * arguments have been visited. * * @author Eric Bruneton */ diff --git a/src/main/java/com/alibaba/fastjson/asm/MethodWriter.java b/src/main/java/com/alibaba/fastjson/asm/MethodWriter.java old mode 100644 new mode 100755 index 4ec9776ce0..4cb3fd364d --- a/src/main/java/com/alibaba/fastjson/asm/MethodWriter.java +++ b/src/main/java/com/alibaba/fastjson/asm/MethodWriter.java @@ -144,11 +144,6 @@ class MethodWriter implements MethodVisitor { */ private int maxLocals; - /** - * Indicates if some jump instructions are too small and need to be resized. - */ - private boolean resize; - // ------------------------------------------------------------------------ /* @@ -286,7 +281,7 @@ public void visitJumpInsn(final int opcode, final Label label) { public void visitLabel(final Label label) { // resolves previous forward references to label, if any - resize |= label.resolve(this, code.length, code.data); + label.resolve(this, code.length, code.data); } public void visitLdcInsn(final Object cst) { @@ -305,11 +300,11 @@ public void visitLdcInsn(final Object cst) { public void visitIincInsn(final int var, final int increment) { // adds the instruction to the bytecode of the method - if ((var > 255) || (increment > 127) || (increment < -128)) { - code.putByte(196 /* WIDE */).put12(Opcodes.IINC, var).putShort(increment); - } else { +// if ((var > 255) || (increment > 127) || (increment < -128)) { +// code.putByte(196 /* WIDE */).put12(Opcodes.IINC, var).putShort(increment); +// } else { code.putByte(Opcodes.IINC).put11(var, increment); - } +// } } public void visitMaxs(final int maxStack, final int maxLocals) { @@ -338,10 +333,6 @@ public void visitEnd() { * @return the size of the bytecode of this method. */ final int getSize() { - if (resize) { - // replaces the temporary jump opcodes introduced by Label.resolve. - throw new UnsupportedOperationException(); - } int size = 8; if (code.length > 0) { cw.newUTF8("Code"); diff --git a/src/main/java/com/alibaba/fastjson/asm/Opcodes.java b/src/main/java/com/alibaba/fastjson/asm/Opcodes.java old mode 100644 new mode 100755 index cc9e9b6ac5..3126e5e5fb --- a/src/main/java/com/alibaba/fastjson/asm/Opcodes.java +++ b/src/main/java/com/alibaba/fastjson/asm/Opcodes.java @@ -54,6 +54,8 @@ public interface Opcodes { int ACC_PUBLIC = 0x0001; // class, field, method int ACC_PRIVATE = 0x0002; // class, field, method + int ACC_STATIC = 0x0008; // field, method + int ACC_FINAL = 0x0010; // class, field, method int ACC_SUPER = 0x0020; // class int ACC_SYNTHETIC = 0x1000; // class, field, method @@ -104,7 +106,7 @@ public interface Opcodes { int DCONST_0 = 14; // - int DCONST_1 = 15; // - int BIPUSH = 16; // visitIntInsn -// int SIPUSH = 17; // - + // int SIPUSH = 17; // - int LDC = 18; // visitLdcInsn // int LDC_W = 19; // - // int LDC2_W = 20; // - @@ -166,72 +168,72 @@ public interface Opcodes { // int ASTORE_1 = 76; // - // int ASTORE_2 = 77; // - // int ASTORE_3 = 78; // - - // int IASTORE = 79; // visitInsn - // int LASTORE = 80; // - - // int FASTORE = 81; // - - // int DASTORE = 82; // - - // int AASTORE = 83; // - - // int BASTORE = 84; // - - // int CASTORE = 85; // - - // int SASTORE = 86; // - + // int IASTORE = 79; // visitInsn + // int LASTORE = 80; // - + // int FASTORE = 81; // - + // int DASTORE = 82; // - + // int AASTORE = 83; // - + // int BASTORE = 84; // - + // int CASTORE = 85; // - + // int SASTORE = 86; // - int POP = 87; // - int POP2 = 88; // - int DUP = 89; // - -// int DUP_X1 = 90; // - -// int DUP_X2 = 91; // - -// int DUP2 = 92; // - -// int DUP2_X1 = 93; // - -// int DUP2_X2 = 94; // - -// int SWAP = 95; // - + // int DUP_X1 = 90; // - + // int DUP_X2 = 91; // - + // int DUP2 = 92; // - + // int DUP2_X1 = 93; // - + // int DUP2_X2 = 94; // - + // int SWAP = 95; // - int IADD = 96; // - int LADD = 97; // - -// int FADD = 98; // - -// int DADD = 99; // - + // int FADD = 98; // - + // int DADD = 99; // - int ISUB = 100; // - -// int LSUB = 101; // - -// int FSUB = 102; // - -// int DSUB = 103; // - -// int IMUL = 104; // - -// int LMUL = 105; // - -// int FMUL = 106; // - -// int DMUL = 107; // - -// int IDIV = 108; // - -// int LDIV = 109; // - -// int FDIV = 110; // - -// int DDIV = 111; // - -// int IREM = 112; // - -// int LREM = 113; // - -// int FREM = 114; // - -// int DREM = 115; // - -// int INEG = 116; // - -// int LNEG = 117; // - -// int FNEG = 118; // - -// int DNEG = 119; // - -// int ISHL = 120; // - -// int LSHL = 121; // - -// int ISHR = 122; // - -// int LSHR = 123; // - -// int IUSHR = 124; // - -// int LUSHR = 125; // - -// int IAND = 126; // - -// int LAND = 127; // - -// int IOR = 128; // - -// int LOR = 129; // - -// int IXOR = 130; // - -// int LXOR = 131; // - + // int LSUB = 101; // - + // int FSUB = 102; // - + // int DSUB = 103; // - + // int IMUL = 104; // - + // int LMUL = 105; // - + // int FMUL = 106; // - + // int DMUL = 107; // - + // int IDIV = 108; // - + // int LDIV = 109; // - + // int FDIV = 110; // - + // int DDIV = 111; // - + // int IREM = 112; // - + // int LREM = 113; // - + // int FREM = 114; // - + // int DREM = 115; // - + // int INEG = 116; // - + // int LNEG = 117; // - + // int FNEG = 118; // - + // int DNEG = 119; // - + // int ISHL = 120; // - + // int LSHL = 121; // - + // int ISHR = 122; // - + // int LSHR = 123; // - + // int IUSHR = 124; // - + // int LUSHR = 125; // - + int IAND = 126; // - + // int LAND = 127; // - + int IOR = 128; // - + // int LOR = 129; // - + // int IXOR = 130; // - + // int LXOR = 131; // - int IINC = 132; // visitIincInsn -// int I2L = 133; // visitInsn -// int I2F = 134; // - -// int I2D = 135; // - -// int L2I = 136; // - -// int L2F = 137; // - -// int L2D = 138; // - -// int F2I = 139; // - -// int F2L = 140; // - -// int F2D = 141; // - -// int D2I = 142; // - -// int D2L = 143; // - -// int D2F = 144; // - + // int I2L = 133; // visitInsn + // int I2F = 134; // - + // int I2D = 135; // - + // int L2I = 136; // - + // int L2F = 137; // - + // int L2D = 138; // - + // int F2I = 139; // - + // int F2L = 140; // - + // int F2D = 141; // - + // int D2I = 142; // - + // int D2L = 143; // - + // int D2F = 144; // - int I2B = 145; // - int I2C = 146; // - int I2S = 147; // - @@ -257,12 +259,12 @@ public interface Opcodes { int GOTO = 167; // - int JSR = 168; // - int RET = 169; // visitVarInsn -// int TABLESWITCH = 170; // visiTableSwitchInsn -// int LOOKUPSWITCH = 171; // visitLookupSwitch + // int TABLESWITCH = 170; // visiTableSwitchInsn + // int LOOKUPSWITCH = 171; // visitLookupSwitch int IRETURN = 172; // visitInsn -// int LRETURN = 173; // - -// int FRETURN = 174; // - -// int DRETURN = 175; // - + // int LRETURN = 173; // - + // int FRETURN = 174; // - + // int DRETURN = 175; // - int ARETURN = 176; // - int RETURN = 177; // - int GETSTATIC = 178; // visitFieldInsn @@ -275,16 +277,16 @@ public interface Opcodes { int INVOKEINTERFACE = 185; // - // int INVOKEDYNAMIC = 186; // - int NEW = 187; // visitTypeInsn -// int NEWARRAY = 188; // visitIntInsn -// int ANEWARRAY = 189; // visitTypeInsn -// int ARRAYLENGTH = 190; // visitInsn -// int ATHROW = 191; // - + // int NEWARRAY = 188; // visitIntInsn + // int ANEWARRAY = 189; // visitTypeInsn + // int ARRAYLENGTH = 190; // visitInsn + // int ATHROW = 191; // - int CHECKCAST = 192; // visitTypeInsn int INSTANCEOF = 193; // - -// int MONITORENTER = 194; // visitInsn -// int MONITOREXIT = 195; // - - // int WIDE = 196; // NOT VISITED -// int MULTIANEWARRAY = 197; // visitMultiANewArrayInsn + // int MONITORENTER = 194; // visitInsn + // int MONITOREXIT = 195; // - + // int WIDE = 196; // NOT VISITED + // int MULTIANEWARRAY = 197; // visitMultiANewArrayInsn int IFNULL = 198; // visitJumpInsn int IFNONNULL = 199; // - // int GOTO_W = 200; // - diff --git a/src/main/java/com/alibaba/fastjson/asm/Type.java b/src/main/java/com/alibaba/fastjson/asm/Type.java old mode 100644 new mode 100755 index cfc0751724..3be38c3d77 --- a/src/main/java/com/alibaba/fastjson/asm/Type.java +++ b/src/main/java/com/alibaba/fastjson/asm/Type.java @@ -38,57 +38,57 @@ public class Type { /** - * The sort of the void type. See {@link #getSort getSort}. + * The sort of the void type. */ public static final int VOID = 0; /** - * The sort of the boolean type. See {@link #getSort getSort}. + * The sort of the boolean type. */ public static final int BOOLEAN = 1; /** - * The sort of the char type. See {@link #getSort getSort}. + * The sort of the char type. */ public static final int CHAR = 2; /** - * The sort of the byte type. See {@link #getSort getSort}. + * The sort of the byte type. */ public static final int BYTE = 3; /** - * The sort of the short type. See {@link #getSort getSort}. + * The sort of the short type. */ public static final int SHORT = 4; /** - * The sort of the int type. See {@link #getSort getSort}. + * The sort of the int type. */ public static final int INT = 5; /** - * The sort of the float type. See {@link #getSort getSort}. + * The sort of the float type. */ public static final int FLOAT = 6; /** - * The sort of the long type. See {@link #getSort getSort}. + * The sort of the long type. */ public static final int LONG = 7; /** - * The sort of the double type. See {@link #getSort getSort}. + * The sort of the double type. */ public static final int DOUBLE = 8; /** - * The sort of array reference types. See {@link #getSort getSort}. + * The sort of array reference types. */ public static final int ARRAY = 9; /** - * The sort of object reference type. See {@link #getSort getSort}. + * The sort of object reference type. */ public static final int OBJECT = 10; @@ -192,14 +192,6 @@ public static Type getType(final String typeDescriptor) { return getType(typeDescriptor.toCharArray(), 0); } - /** - * Computes the size of the arguments and of the return value of a method. - * - * @param desc the descriptor of a method. - * @return the size of the arguments of the method (plus one for the implicit this argument), argSize, and the size - * of its return value, retSize, packed into a single int i = (argSize << 2) | retSize (argSize is - * therefore equal to i >> 2, and retSize to i & 0x03). - */ public static int getArgumentsAndReturnSizes(final String desc) { int n = 1; int c = 1; @@ -212,13 +204,13 @@ public static int getArgumentsAndReturnSizes(final String desc) { while (desc.charAt(c++) != ';') { } n += 1; - } else if (car == '[') { - while ((car = desc.charAt(c)) == '[') { - ++c; - } - if (car == 'D' || car == 'J') { - n -= 1; - } +// } else if (car == '[') { +// while ((car = desc.charAt(c)) == '[') { +// ++c; +// } +// if (car == 'D' || car == 'J') { +// n -= 1; +// } } else if (car == 'D' || car == 'J') { n += 2; } else { @@ -312,20 +304,7 @@ public String getInternalName() { * * @return the descriptor corresponding to this Java type. */ - public String getDescriptor() { - StringBuffer buf = new StringBuffer(); - - if (this.buf == null) { - // descriptor is in byte 3 of 'off' for primitive types (buf == null) - buf.append((char) ((off & 0xFF000000) >>> 24)); - } else if (sort == ARRAY) { - buf.append(this.buf, off, len); - } else { // sort == OBJECT - buf.append('L'); - buf.append(this.buf, off, len); - buf.append(';'); - } - - return buf.toString(); + String getDescriptor() { + return new String(this.buf, off, len); } } diff --git a/src/main/java/com/alibaba/fastjson/asm/package.html b/src/main/java/com/alibaba/fastjson/asm/package.html deleted file mode 100644 index fd6caf73f6..0000000000 --- a/src/main/java/com/alibaba/fastjson/asm/package.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - Provides a small and fast bytecode manipulation framework. - -

- The ASM framework is - organized around the {@link org.objectweb.asm.ClassVisitor - ClassVisitor}, {@link org.objectweb.asm.FieldVisitor FieldVisitor} and - {@link org.objectweb.asm.MethodVisitor MethodVisitor} interfaces, - which allow one to visit the fields and methods of a class, including - the bytecode instructions of each method. -

In addition to these main interfaces, ASM provides a {@link - org.objectweb.asm.ClassReader ClassReader} class, that can parse an - existing class and make a given visitor visit it. ASM also provides a - {@link org.objectweb.asm.ClassWriter ClassWriter} class, which is a - visitor that generates Java class files. -

- In order to generate a class from scratch, only the {@link - org.objectweb.asm.ClassWriter ClassWriter} class is necessary. Indeed, - in order to generate a class, one must just call its visitXXX - methods with the appropriate arguments to generate the desired fields - and methods. See the "helloworld" example in the ASM distribution for - more details about class generation. -

In order to modify existing classes, one must use a {@link - org.objectweb.asm.ClassReader ClassReader} class to analyze the - original class, a class modifier, and a {@link - org.objectweb.asm.ClassWriter ClassWriter} to construct the modified - class. The class modifier is just a {@link - org.objectweb.asm.ClassVisitor ClassVisitor} that delegates most of - the work to another {@link org.objectweb.asm.ClassVisitor - ClassVisitor}, but that sometimes changes some parameter values, or - call additional methods, in order to implement the desired - modification process. In order to make it easier to implement such - class modifiers, ASM provides the {@link - org.objectweb.asm.ClassAdapter ClassAdapter} and {@link - org.objectweb.asm.MethodAdapter MethodAdapter} classes, which - implement the {@link org.objectweb.asm.ClassVisitor ClassVisitor} and - {@link org.objectweb.asm.MethodVisitor MethodVisitor} interfaces by - delegating all work to other visitors. See the "adapt" example in the - ASM distribution for more details about class modification. -

- The size of the core ASM library, - asm.jar - , is only 42KB, which is much smaller than the size of the BCEL library (504KB), and - than the size of the SERP - library (150KB). ASM is also much faster than these tools. Indeed the - overhead of a load time class transformation process is of the order - of 60% with ASM, 700% or more with BCEL, and 1100% or more with SERP - (see the - test/perf - directory in the ASM distribution)! @since ASM 1.3 - - diff --git a/src/main/java/com/alibaba/fastjson/parser/AbstractJSONParser.java b/src/main/java/com/alibaba/fastjson/parser/AbstractJSONParser.java old mode 100644 new mode 100755 index e6e084653a..0de9a99082 --- a/src/main/java/com/alibaba/fastjson/parser/AbstractJSONParser.java +++ b/src/main/java/com/alibaba/fastjson/parser/AbstractJSONParser.java @@ -1,224 +1,5 @@ package com.alibaba.fastjson.parser; -import static com.alibaba.fastjson.parser.JSONToken.EOF; -import static com.alibaba.fastjson.parser.JSONToken.FALSE; -import static com.alibaba.fastjson.parser.JSONToken.LBRACE; -import static com.alibaba.fastjson.parser.JSONToken.LBRACKET; -import static com.alibaba.fastjson.parser.JSONToken.LITERAL_FLOAT; -import static com.alibaba.fastjson.parser.JSONToken.LITERAL_INT; -import static com.alibaba.fastjson.parser.JSONToken.LITERAL_STRING; -import static com.alibaba.fastjson.parser.JSONToken.NEW; -import static com.alibaba.fastjson.parser.JSONToken.NULL; -import static com.alibaba.fastjson.parser.JSONToken.RBRACKET; -import static com.alibaba.fastjson.parser.JSONToken.TRUE; - -import java.util.Collection; -import java.util.Date; -import java.util.Map; - -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.JSONObject; - public abstract class AbstractJSONParser { - @SuppressWarnings("rawtypes") - public abstract void parseObject(final Map object); - - public JSONObject parseObject() { - JSONObject object = new JSONObject(); - parseObject(object); - return object; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public final void parseArray(final Collection array) { - final JSONLexer lexer = getLexer(); - - if (lexer.token() != JSONToken.LBRACKET) { - throw new JSONException("syntax error, expect [, actual " - + JSONToken.name(lexer.token())); - } - - lexer.nextToken(JSONToken.LITERAL_STRING); - - for (;;) { - if (isEnabled(Feature.AllowArbitraryCommas)) { - while (lexer.token() == JSONToken.COMMA) { - lexer.nextToken(); - continue; - } - } - - Object value; - switch (lexer.token()) { - case LITERAL_INT: - value = lexer.integerValue(); - lexer.nextToken(JSONToken.COMMA); - break; - case LITERAL_FLOAT: - if (lexer.isEnabled(Feature.UseBigDecimal)) { - value = lexer.decimalValue(); - } else { - value = lexer.doubleValue(); - } - lexer.nextToken(JSONToken.COMMA); - break; - case LITERAL_STRING: - String stringLiteral = lexer.stringVal(); - lexer.nextToken(JSONToken.COMMA); - - if (lexer.isEnabled(Feature.AllowISO8601DateFormat)) { - JSONScanner iso8601Lexer = new JSONScanner(stringLiteral); - if (iso8601Lexer.scanISO8601DateIfMatch()) { - value = iso8601Lexer.getCalendar().getTime(); - } else { - value = stringLiteral; - } - } else { - value = stringLiteral; - } - - break; - case TRUE: - value = Boolean.TRUE; - lexer.nextToken(JSONToken.COMMA); - break; - case FALSE: - value = Boolean.FALSE; - lexer.nextToken(JSONToken.COMMA); - break; - case LBRACE: - JSONObject object = new JSONObject(); - parseObject(object); - value = object; - break; - case LBRACKET: - Collection items = new JSONArray(); - parseArray(items); - value = items; - break; - case NULL: - value = null; - lexer.nextToken(JSONToken.LITERAL_STRING); - break; - case RBRACKET: - lexer.nextToken(JSONToken.COMMA); - return; - default: - value = parse(); - break; - } - - array.add(value); - - if (lexer.token() == JSONToken.COMMA) { - lexer.nextToken(JSONToken.LITERAL_STRING); - continue; - } - } - } - - public Object parse() { - final JSONLexer lexer = getLexer(); - switch (lexer.token()) { - case LBRACKET: - JSONArray array = new JSONArray(); - parseArray(array); - return array; - case LBRACE: - JSONObject object = new JSONObject(); - parseObject(object); - return object; - case LITERAL_INT: - Number intValue = lexer.integerValue(); - lexer.nextToken(); - return intValue; - case LITERAL_FLOAT: - - Object value; - if (isEnabled(Feature.UseBigDecimal)) { - value = lexer.decimalValue(); - } else { - value = lexer.doubleValue(); - } - lexer.nextToken(); - return value; - case LITERAL_STRING: - String stringLiteral = lexer.stringVal(); - lexer.nextToken(JSONToken.COMMA); - - if (lexer.isEnabled(Feature.AllowISO8601DateFormat)) { - JSONScanner iso8601Lexer = new JSONScanner(stringLiteral); - if (iso8601Lexer.scanISO8601DateIfMatch()) { - return iso8601Lexer.getCalendar().getTime(); - } - } - - return stringLiteral; - case NULL: - lexer.nextToken(); - return null; - case TRUE: - lexer.nextToken(); - return Boolean.TRUE; - case FALSE: - lexer.nextToken(); - return Boolean.FALSE; - case NEW: - lexer.nextToken(JSONToken.IDENTIFIER); - - if (lexer.token() != JSONToken.IDENTIFIER) { - throw new JSONException("syntax error"); - } - lexer.nextToken(JSONToken.LPAREN); - - accept(JSONToken.LPAREN); - long time = ((Number) lexer.integerValue()).longValue(); - accept(JSONToken.LITERAL_INT); - - accept(JSONToken.RPAREN); - - return new Date(time); - case EOF: - if (lexer.isBlankInput()) { - return null; - } - default: - throw new JSONException("TODO " + JSONToken.name(lexer.token()) - + " " + lexer.stringVal()); - } - } - - public void config(Feature feature, boolean state) { - getLexer().config(feature, state); - } - - public boolean isEnabled(Feature feature) { - return getLexer().isEnabled(feature); - } - - public abstract JSONLexer getLexer(); - - public final void accept(final int token) { - final JSONLexer lexer = getLexer(); - if (lexer.token() == token) { - lexer.nextToken(); - } else { - throw new JSONException("syntax error, expect " - + JSONToken.name(token) + ", actual " - + JSONToken.name(lexer.token())); - } - } - - public void close() { - final JSONLexer lexer = getLexer(); - - if (isEnabled(Feature.AutoCloseSource)) { - if (!lexer.isEOF()) { - throw new JSONException("not close json text, token : " - + JSONToken.name(lexer.token())); - } - } - } } diff --git a/src/main/java/com/alibaba/fastjson/parser/CharTypes.java b/src/main/java/com/alibaba/fastjson/parser/CharTypes.java deleted file mode 100644 index c3ab3df2b2..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/CharTypes.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.parser; - -/** - * @author wenshao - */ -public final class CharTypes { - - public final static boolean[] firstIdentifierFlags = new boolean[256]; - static { - for (char c = 0; c < firstIdentifierFlags.length; ++c) { - if (c >= 'A' && c <= 'Z') { - firstIdentifierFlags[c] = true; - } else if (c >= 'a' && c <= 'z') { - firstIdentifierFlags[c] = true; - } else if (c == '_') { - firstIdentifierFlags[c] = true; - } - } - } - - public final static boolean[] identifierFlags = new boolean[256]; - - static { - for (char c = 0; c < identifierFlags.length; ++c) { - if (c >= 'A' && c <= 'Z') { - identifierFlags[c] = true; - } else if (c >= 'a' && c <= 'z') { - identifierFlags[c] = true; - } else if (c == '_') { - identifierFlags[c] = true; - } else if (c >= '0' && c <= '9') { - identifierFlags[c] = true; - } - } - } - - public final static boolean[] specicalFlags_doubleQuotes = new boolean[((int) '\\' + 1)]; - public final static boolean[] specicalFlags_singleQuotes = new boolean[((int) '\\' + 1)]; - - public static boolean isSpecial_doubleQuotes(char ch) { - return ch < specicalFlags_doubleQuotes.length && specicalFlags_doubleQuotes[ch]; - } - - public final static char[] replaceChars = new char[((int) '\\' + 1)]; - static { - specicalFlags_doubleQuotes['\b'] = true; - specicalFlags_doubleQuotes['\n'] = true; - specicalFlags_doubleQuotes['\f'] = true; - specicalFlags_doubleQuotes['\r'] = true; - specicalFlags_doubleQuotes['\"'] = true; - specicalFlags_doubleQuotes['\\'] = true; - - specicalFlags_singleQuotes['\b'] = true; - specicalFlags_singleQuotes['\n'] = true; - specicalFlags_singleQuotes['\f'] = true; - specicalFlags_singleQuotes['\r'] = true; - specicalFlags_singleQuotes['\''] = true; - specicalFlags_singleQuotes['\\'] = true; - - replaceChars['\b'] = 'b'; - replaceChars['\n'] = 'n'; - replaceChars['\f'] = 'f'; - replaceChars['\r'] = 'r'; - replaceChars['\"'] = '"'; - replaceChars['\''] = '\''; - replaceChars['\\'] = '\\'; - replaceChars['\t'] = 't'; - } - -} diff --git a/src/main/java/com/alibaba/fastjson/parser/DefaultExtJSONParser.java b/src/main/java/com/alibaba/fastjson/parser/DefaultExtJSONParser.java old mode 100644 new mode 100755 index 35dc417784..0fe28d94da --- a/src/main/java/com/alibaba/fastjson/parser/DefaultExtJSONParser.java +++ b/src/main/java/com/alibaba/fastjson/parser/DefaultExtJSONParser.java @@ -15,56 +15,13 @@ */ package com.alibaba.fastjson.parser; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; -import java.lang.reflect.WildcardType; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.deserializer.DefaultObjectDeserializer; -import com.alibaba.fastjson.parser.deserializer.IntegerDeserializer; -import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; -import com.alibaba.fastjson.parser.deserializer.StringDeserializer; -import com.alibaba.fastjson.util.TypeUtils; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ -@SuppressWarnings("rawtypes") +@Deprecated public class DefaultExtJSONParser extends DefaultJSONParser { - private DefaultObjectDeserializer derializer = new DefaultObjectDeserializer(); - - private final static Set> primitiveClasses = new HashSet>(); - static { - primitiveClasses.add(boolean.class); - primitiveClasses.add(byte.class); - primitiveClasses.add(short.class); - primitiveClasses.add(int.class); - primitiveClasses.add(long.class); - primitiveClasses.add(float.class); - primitiveClasses.add(double.class); - - primitiveClasses.add(Boolean.class); - primitiveClasses.add(Byte.class); - primitiveClasses.add(Short.class); - primitiveClasses.add(Integer.class); - primitiveClasses.add(Long.class); - primitiveClasses.add(Float.class); - primitiveClasses.add(Double.class); - - primitiveClasses.add(BigInteger.class); - primitiveClasses.add(BigDecimal.class); - primitiveClasses.add(String.class); - } - public DefaultExtJSONParser(String input){ this(input, ParserConfig.getGlobalInstance()); } @@ -81,292 +38,5 @@ public DefaultExtJSONParser(char[] input, int length, ParserConfig mapping, int super(input, length, mapping, features); } - public ParserConfig getConfig() { - return config; - } - - public void setConfig(ParserConfig config) { - this.config = config; - } - - // compatible - @SuppressWarnings("unchecked") - public T parseObject(Class clazz) { - return (T) parseObject((Type) clazz); - } - - @SuppressWarnings("unchecked") - public T parseObject(Type type) { - if (lexer.token() == JSONToken.NULL) { - lexer.nextToken(); - return null; - } - - ObjectDeserializer derializer = config.getDeserializer(type); - - try { - return (T) derializer.deserialze(this, type); - } catch (JSONException e) { - throw e; - } catch (Throwable e) { - throw new JSONException(e.getMessage(), e); - } - } - - public List parseArray(Class clazz) { - List array = new ArrayList(); - parseArray(clazz, array); - return array; - } - - public void parseArray(Class clazz, Collection array) { - parseArray((Type) clazz, array); - } - - @SuppressWarnings({ "unchecked" }) - public void parseArray(Type type, Collection array) { - if (lexer.token() != JSONToken.LBRACKET) { - throw new JSONException("exepct '[', but " + JSONToken.name(lexer.token())); - } - - ObjectDeserializer deserializer = null; - if (int.class == type) { - deserializer = IntegerDeserializer.instance; - lexer.nextToken(JSONToken.LITERAL_INT); - } else if (String.class == type) { - deserializer = StringDeserializer.instance; - lexer.nextToken(JSONToken.LITERAL_STRING); - } else { - deserializer = config.getDeserializer(type); - lexer.nextToken(deserializer.getFastMatchToken()); - } - - for (;;) { - if (isEnabled(Feature.AllowArbitraryCommas)) { - while (lexer.token() == JSONToken.COMMA) { - lexer.nextToken(); - continue; - } - } - - if (lexer.token() == JSONToken.RBRACKET) { - break; - } - - if (int.class == type) { - Object val = IntegerDeserializer.deserialze(this); - array.add(val); - } else if (String.class == type) { - String value; - if (lexer.token() == JSONToken.LITERAL_STRING) { - value = lexer.stringVal(); - lexer.nextToken(JSONToken.COMMA); - } else { - Object obj = this.parse(); - if (obj == null) { - value = null; - } else { - value = obj.toString(); - } - } - - array.add(value); - } else { - Object val = deserializer.deserialze(this, type); - array.add(val); - } - - if (lexer.token() == JSONToken.COMMA) { - lexer.nextToken(deserializer.getFastMatchToken()); - continue; - } - } - - lexer.nextToken(JSONToken.COMMA); - } - - public Object[] parseArray(Type[] types) { - - if (lexer.token() != JSONToken.LBRACKET) { - throw new JSONException("syntax error"); - } - - Object[] list = new Object[types.length]; - if (types.length == 0) { - lexer.nextToken(JSONToken.RBRACKET); - - if (lexer.token() != JSONToken.RBRACKET) { - throw new JSONException("syntax error"); - } - - lexer.nextToken(JSONToken.COMMA); - return new Object[0]; - } - - lexer.nextToken(JSONToken.LITERAL_INT); - - for (int i = 0; i < types.length; ++i) { - Object value; - - if (lexer.token() == JSONToken.NULL) { - value = null; - lexer.nextToken(JSONToken.COMMA); - } else { - Type type = types[i]; - if (type == int.class || type == Integer.class) { - if (lexer.token() == JSONToken.LITERAL_INT) { - value = Integer.valueOf(lexer.intValue()); - lexer.nextToken(JSONToken.COMMA); - } else { - value = this.parse(); - value = TypeUtils.cast(value, type, config); - } - } else if (type == String.class) { - if (lexer.token() == JSONToken.LITERAL_STRING) { - value = lexer.stringVal(); - lexer.nextToken(JSONToken.COMMA); - } else { - value = this.parse(); - value = TypeUtils.cast(value, type, config); - } - } else { - boolean isArray = false; - Class componentType = null; - if (i == types.length - 1) { - if (type instanceof Class) { - Class clazz = (Class) type; - isArray = clazz.isArray(); - componentType = clazz.getComponentType(); - } - } - - // support varArgs - if (isArray && lexer.token() != JSONToken.LBRACKET) { - List varList = new ArrayList(); - - ObjectDeserializer derializer = config.getDeserializer(componentType); - int fastMatch = derializer.getFastMatchToken(); - - if (lexer.token() != JSONToken.RBRACKET) { - for (;;) { - Object item = derializer.deserialze(this, type); - varList.add(item); - - if (lexer.token() == JSONToken.COMMA) { - lexer.nextToken(fastMatch); - } else if (lexer.token() == JSONToken.RBRACKET) { - break; - } else { - throw new JSONException("syntax error :" + JSONToken.name(lexer.token())); - } - } - } - - value = TypeUtils.cast(varList, type, config); - } else { - ObjectDeserializer derializer = config.getDeserializer(type); - value = derializer.deserialze(this, type); - } - } - } - list[i] = value; - - if (lexer.token() == JSONToken.RBRACKET) { - break; - } - - if (lexer.token() != JSONToken.COMMA) { - throw new JSONException("syntax error :" + JSONToken.name(lexer.token())); - } - - if (i == types.length - 1) { - lexer.nextToken(JSONToken.RBRACKET); - } else { - lexer.nextToken(JSONToken.LITERAL_INT); - } - } - - if (lexer.token() != JSONToken.RBRACKET) { - throw new JSONException("syntax error"); - } - - lexer.nextToken(JSONToken.COMMA); - - return list; - } - - public void parseObject(Object object) { - derializer.parseObject(this, object); - } - - public Object parseArrayWithType(Type collectionType) { - if (lexer.token() == JSONToken.NULL) { - lexer.nextToken(); - return null; - } - - Type[] actualTypes = ((ParameterizedType) collectionType).getActualTypeArguments(); - - if (actualTypes.length != 1) { - throw new JSONException("not support type " + collectionType); - } - - Type actualTypeArgument = actualTypes[0]; - - if (actualTypeArgument instanceof Class) { - List array = new ArrayList(); - this.parseArray((Class) actualTypeArgument, array); - return array; - } - - if (actualTypeArgument instanceof WildcardType) { - WildcardType wildcardType = (WildcardType) actualTypeArgument; - - // assert wildcardType.getUpperBounds().length == 1; - Type upperBoundType = wildcardType.getUpperBounds()[0]; - - // assert upperBoundType instanceof Class; - if (Object.class.equals(upperBoundType)) { - if (wildcardType.getLowerBounds().length == 0) { - // Collection - return parse(); - } else { - throw new JSONException("not support type : " + collectionType); - } - } - - List array = new ArrayList(); - this.parseArray((Class) upperBoundType, array); - return array; - - // throw new JSONException("not support type : " + - // collectionType);return parse(); - } - - if (actualTypeArgument instanceof TypeVariable) { - TypeVariable typeVariable = (TypeVariable) actualTypeArgument; - Type[] bounds = typeVariable.getBounds(); - - if (bounds.length != 1) { - throw new JSONException("not support : " + typeVariable); - } - - Type boundType = bounds[0]; - if (boundType instanceof Class) { - List array = new ArrayList(); - this.parseArray((Class) boundType, array); - return array; - } - } - - if (actualTypeArgument instanceof ParameterizedType) { - ParameterizedType parameterizedType = (ParameterizedType) actualTypeArgument; - - List array = new ArrayList(); - this.parseArray(parameterizedType, array); - return array; - } - - throw new JSONException("TODO : " + collectionType); - } + } diff --git a/src/main/java/com/alibaba/fastjson/parser/DefaultJSONParser.java b/src/main/java/com/alibaba/fastjson/parser/DefaultJSONParser.java old mode 100644 new mode 100755 index cfd587fa3b..e64e9a67f7 --- a/src/main/java/com/alibaba/fastjson/parser/DefaultJSONParser.java +++ b/src/main/java/com/alibaba/fastjson/parser/DefaultJSONParser.java @@ -15,24 +15,133 @@ */ package com.alibaba.fastjson.parser; -import static com.alibaba.fastjson.parser.JSONScanner.EOI; +import static com.alibaba.fastjson.parser.JSONLexer.EOI; +import static com.alibaba.fastjson.parser.JSONToken.EOF; +import static com.alibaba.fastjson.parser.JSONToken.ERROR; +import static com.alibaba.fastjson.parser.JSONToken.FALSE; +import static com.alibaba.fastjson.parser.JSONToken.LBRACE; +import static com.alibaba.fastjson.parser.JSONToken.LBRACKET; +import static com.alibaba.fastjson.parser.JSONToken.LITERAL_FLOAT; +import static com.alibaba.fastjson.parser.JSONToken.LITERAL_INT; +import static com.alibaba.fastjson.parser.JSONToken.LITERAL_STRING; +import static com.alibaba.fastjson.parser.JSONToken.NEW; +import static com.alibaba.fastjson.parser.JSONToken.NULL; +import static com.alibaba.fastjson.parser.JSONToken.RBRACKET; +import static com.alibaba.fastjson.parser.JSONToken.SET; +import static com.alibaba.fastjson.parser.JSONToken.TREE_SET; +import static com.alibaba.fastjson.parser.JSONToken.TRUE; +import static com.alibaba.fastjson.parser.JSONToken.UNDEFINED; +import java.io.Closeable; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.lang.reflect.WildcardType; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.TreeSet; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer; +import com.alibaba.fastjson.parser.deserializer.CollectionResolveFieldDeserializer; +import com.alibaba.fastjson.parser.deserializer.ExtraProcessor; +import com.alibaba.fastjson.parser.deserializer.ExtraTypeProvider; +import com.alibaba.fastjson.parser.deserializer.FieldDeserializer; +import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer; +import com.alibaba.fastjson.parser.deserializer.ListResolveFieldDeserializer; +import com.alibaba.fastjson.parser.deserializer.MapResolveFieldDeserializer; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.serializer.IntegerCodec; +import com.alibaba.fastjson.serializer.LongCodec; +import com.alibaba.fastjson.serializer.StringCodec; +import com.alibaba.fastjson.util.TypeUtils; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ -public class DefaultJSONParser extends AbstractJSONParser { +public class DefaultJSONParser extends AbstractJSONParser implements Closeable { - protected final JSONLexer lexer; - protected final Object input; - protected final SymbolTable symbolTable; - protected ParserConfig config; + protected final Object input; + protected final SymbolTable symbolTable; + protected ParserConfig config; + + private final static Set> primitiveClasses = new HashSet>(); + + private String dateFormatPattern = JSON.DEFFAULT_DATE_FORMAT; + private DateFormat dateFormat; + + protected final JSONLexer lexer; + + protected ParseContext context; + + private ParseContext[] contextArray = new ParseContext[8]; + private int contextArrayIndex = 0; + + private List resolveTaskList; + + public final static int NONE = 0; + public final static int NeedToResolve = 1; + public final static int TypeNameRedirect = 2; + + private int resolveStatus = NONE; + + private List extraTypeProviders = null; + private List extraProcessors = null; + + static { + primitiveClasses.add(boolean.class); + primitiveClasses.add(byte.class); + primitiveClasses.add(short.class); + primitiveClasses.add(int.class); + primitiveClasses.add(long.class); + primitiveClasses.add(float.class); + primitiveClasses.add(double.class); + + primitiveClasses.add(Boolean.class); + primitiveClasses.add(Byte.class); + primitiveClasses.add(Short.class); + primitiveClasses.add(Integer.class); + primitiveClasses.add(Long.class); + primitiveClasses.add(Float.class); + primitiveClasses.add(Double.class); + + primitiveClasses.add(BigInteger.class); + primitiveClasses.add(BigDecimal.class); + primitiveClasses.add(String.class); + } + + public String getDateFomartPattern() { + return dateFormatPattern; + } + + public DateFormat getDateFormat() { + if (dateFormat == null) { + dateFormat = new SimpleDateFormat(dateFormatPattern); + } + return dateFormat; + } + + public void setDateFormat(String dateFormat) { + this.dateFormatPattern = dateFormat; + this.dateFormat = null; + } + + public void setDateFomrat(DateFormat dateFormat) { + this.dateFormat = dateFormat; + } public DefaultJSONParser(String input){ this(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); @@ -50,9 +159,17 @@ public DefaultJSONParser(final char[] input, int length, final ParserConfig conf this(input, new JSONScanner(input, length, features), config); } + public DefaultJSONParser(final JSONLexer lexer){ + this(lexer, ParserConfig.getGlobalInstance()); + } + + public DefaultJSONParser(final JSONLexer lexer, final ParserConfig config){ + this(null, lexer, config); + } + public DefaultJSONParser(final Object input, final JSONLexer lexer, final ParserConfig config){ - this.input = input; this.lexer = lexer; + this.input = input; this.config = config; this.symbolTable = config.getSymbolTable(); @@ -63,10 +180,6 @@ public SymbolTable getSymbolTable() { return symbolTable; } - public JSONLexer getLexer() { - return lexer; - } - public String getInput() { if (input instanceof char[]) { return new String((char[]) input); @@ -74,250 +187,1227 @@ public String getInput() { return input.toString(); } - // public final void parseObject2(final Map map) { - // JSONScanner lexer = (JSONScanner) this.lexer; - // - // if (lexer.token() != JSONToken.LBRACE) { - // throw new JSONException("syntax error, expect {, actual " + lexer.token()); - // } - // - // for (;;) { - // // lexer.scanSymbol - // String key = lexer.scanSymbol(getSymbolTable()); - // - // if (key == null) { - // if (lexer.token() == JSONToken.RBRACE) { - // lexer.nextToken(JSONToken.COMMA); - // return; - // } - // if (lexer.token() == JSONToken.COMMA) { - // if (lexer.isEnabled(Feature.AllowArbitraryCommas)) { - // continue; - // } - // } - // } - // - // Object value; - // - // lexer.nextTokenWithColon(JSONToken.LITERAL_STRING); - // switch (lexer.token()) { - // case LITERAL_INT: - // value = lexer.integerValue(); - // lexer.nextToken(JSONToken.COMMA); - // break; - // case LITERAL_FLOAT: - // if (lexer.isEnabled(Feature.UseBigDecimal)) { - // value = lexer.decimalValue(); - // } else { - // value = Double.parseDouble(lexer.numberString()); - // } - // lexer.nextToken(JSONToken.COMMA); - // break; - // case LITERAL_STRING: - // String stringLiteral = lexer.stringVal(); - // lexer.nextToken(JSONToken.COMMA); - // - // if (lexer.isEnabled(Feature.AllowISO8601DateFormat)) { - // JSONScanner iso8601Lexer = new JSONScanner(stringLiteral); - // if (iso8601Lexer.scanISO8601DateIfMatch()) { - // value = iso8601Lexer.getCalendar().getTime(); - // } else { - // value = stringLiteral; - // } - // } else { - // value = stringLiteral; - // } - // - // break; - // case TRUE: - // value = Boolean.TRUE; - // lexer.nextToken(JSONToken.COMMA); - // break; - // case FALSE: - // value = Boolean.FALSE; - // lexer.nextToken(JSONToken.COMMA); - // break; - // case LBRACE: - // JSONObject object = new JSONObject(); - // parseObject(object); - // value = object; - // break; - // case LBRACKET: - // Collection array = new ArrayList(); - // parseArray(array); - // value = array; - // break; - // case NULL: - // value = null; - // lexer.nextToken(); - // break; - // default: - // value = parse(); - // break; - // } - // - // map.put(key, value); - // - // if (lexer.token() == JSONToken.COMMA) { - // continue; - // } - // - // if (lexer.token() == JSONToken.RBRACE) { - // lexer.nextToken(JSONToken.COMMA); - // return; - // } - // } - // - // } - @SuppressWarnings({ "unchecked", "rawtypes" }) - public final void parseObject(final Map object) { - JSONScanner lexer = (JSONScanner) this.lexer; - if (lexer.token() != JSONToken.LBRACE) { - throw new JSONException("syntax error, expect {, actual " + lexer.token()); + public final Object parseObject(final Map object, Object fieldName) { + final JSONLexer lexer = this.lexer; + + if (lexer.token() == JSONToken.NULL) { + lexer.next(); + return null; } - for (;;) { - lexer.skipWhitespace(); - char ch = lexer.getCurrent(); - if (isEnabled(Feature.AllowArbitraryCommas)) { - while (ch == ',') { - lexer.incrementBufferPosition(); + if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) { + throw new JSONException("syntax error, expect {, actual " + lexer.tokenName()); + } + + ParseContext context = this.getContext(); + try { + boolean setContextFlag = false; + for (;;) { + lexer.skipWhitespace(); + char ch = lexer.getCurrent(); + if (isEnabled(Feature.AllowArbitraryCommas)) { + while (ch == ',') { + lexer.next(); + lexer.skipWhitespace(); + ch = lexer.getCurrent(); + } + } + + boolean isObjectKey = false; + Object key; + if (ch == '"') { + key = lexer.scanSymbol(symbolTable, '"'); + lexer.skipWhitespace(); + ch = lexer.getCurrent(); + if (ch != ':') { + throw new JSONException("expect ':' at " + lexer.pos() + ", name " + key); + } + } else if (ch == '}') { + lexer.next(); + lexer.resetStringPosition(); + lexer.nextToken(); + return object; + } else if (ch == '\'') { + if (!isEnabled(Feature.AllowSingleQuotes)) { + throw new JSONException("syntax error"); + } + + key = lexer.scanSymbol(symbolTable, '\''); lexer.skipWhitespace(); ch = lexer.getCurrent(); + if (ch != ':') { + throw new JSONException("expect ':' at " + lexer.pos()); + } + } else if (ch == EOI) { + throw new JSONException("syntax error"); + } else if (ch == ',') { + throw new JSONException("syntax error"); + } else if ((ch >= '0' && ch <= '9') || ch == '-') { + lexer.resetStringPosition(); + lexer.scanNumber(); + if (lexer.token() == JSONToken.LITERAL_INT) { + key = lexer.integerValue(); + } else { + key = lexer.decimalValue(true); + } + ch = lexer.getCurrent(); + if (ch != ':') { + throw new JSONException("expect ':' at " + lexer.pos() + ", name " + key); + } + } else if (ch == '{' || ch == '[') { + lexer.nextToken(); + key = parse(); + isObjectKey = true; + } else { + if (!isEnabled(Feature.AllowUnQuotedFieldNames)) { + throw new JSONException("syntax error"); + } + + key = lexer.scanSymbolUnQuoted(symbolTable); + lexer.skipWhitespace(); + ch = lexer.getCurrent(); + if (ch != ':') { + throw new JSONException("expect ':' at " + lexer.pos() + ", actual " + ch); + } } - } - String key; - if (ch == '"') { - key = lexer.scanSymbol(symbolTable, '"'); - lexer.skipWhitespace(); - ch = lexer.getCurrent(); - if (ch != ':') { - throw new JSONException("expect ':' at " + lexer.pos() + ", name " + key); + if (!isObjectKey) { + lexer.next(); + lexer.skipWhitespace(); } - } else if (ch == '}') { - lexer.incrementBufferPosition(); + + ch = lexer.getCurrent(); + lexer.resetStringPosition(); - lexer.nextToken(); - return; - } else if (ch == '\'') { - if (!isEnabled(Feature.AllowSingleQuotes)) { - throw new JSONException("syntax error"); + + if (key == JSON.DEFAULT_TYPE_KEY) { + String typeName = lexer.scanSymbol(symbolTable, '"'); + Class clazz = TypeUtils.loadClass(typeName); + + if (clazz == null) { + object.put(JSON.DEFAULT_TYPE_KEY, typeName); + continue; + } + + lexer.nextToken(JSONToken.COMMA); + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(JSONToken.COMMA); + try { + Object instance = null; + ObjectDeserializer deserializer = this.config.getDeserializer(clazz); + if (deserializer instanceof ASMJavaBeanDeserializer) { + instance = ((ASMJavaBeanDeserializer) deserializer).createInstance(this, clazz); + } else if (deserializer instanceof JavaBeanDeserializer) { + instance = ((JavaBeanDeserializer) deserializer).createInstance(this, clazz); + } + + if (instance == null) { + if (clazz == Cloneable.class) { + instance = new HashMap(); + } else { + instance = clazz.newInstance(); + } + } + + return instance; + } catch (Exception e) { + throw new JSONException("create instance error", e); + } + } + + this.setResolveStatus(TypeNameRedirect); + + if (this.context != null && !(fieldName instanceof Integer)) { + this.popContext(); + } + + ObjectDeserializer deserializer = config.getDeserializer(clazz); + return deserializer.deserialze(this, clazz, fieldName); } - key = lexer.scanSymbol(symbolTable, '\''); - lexer.skipWhitespace(); - ch = lexer.getCurrent(); - if (ch != ':') { - throw new JSONException("expect ':' at " + lexer.pos()); + if (key == "$ref") { + lexer.nextToken(JSONToken.LITERAL_STRING); + if (lexer.token() == JSONToken.LITERAL_STRING) { + String ref = lexer.stringVal(); + lexer.nextToken(JSONToken.RBRACE); + + Object refValue = null; + if ("@".equals(ref)) { + if (this.getContext() != null) { + ParseContext thisContext = this.getContext(); + Object thisObj = thisContext.getObject(); + if (thisObj instanceof Object[] || thisObj instanceof Collection) { + refValue = thisObj; + } else if (thisContext.getParentContext() != null) { + refValue = thisContext.getParentContext().getObject(); + } + } + } else if ("..".equals(ref)) { + ParseContext parentContext = context.getParentContext(); + if (parentContext.getObject() != null) { + refValue = parentContext.getObject(); + } else { + addResolveTask(new ResolveTask(parentContext, ref)); + setResolveStatus(DefaultJSONParser.NeedToResolve); + } + } else if ("$".equals(ref)) { + ParseContext rootContext = context; + while (rootContext.getParentContext() != null) { + rootContext = rootContext.getParentContext(); + } + + if (rootContext.getObject() != null) { + refValue = rootContext.getObject(); + } else { + addResolveTask(new ResolveTask(rootContext, ref)); + setResolveStatus(DefaultJSONParser.NeedToResolve); + } + } else { + addResolveTask(new ResolveTask(context, ref)); + setResolveStatus(DefaultJSONParser.NeedToResolve); + } + + if (lexer.token() != JSONToken.RBRACE) { + throw new JSONException("syntax error"); + } + lexer.nextToken(JSONToken.COMMA); + + return refValue; + } else { + throw new JSONException("illegal ref, " + JSONToken.name(lexer.token())); + } } - } else if (ch == EOI) { - throw new JSONException("syntax error"); - } else if (ch == ',') { - throw new JSONException("syntax error"); - } else { - if (!isEnabled(Feature.AllowUnQuotedFieldNames)) { - throw new JSONException("syntax error"); + + if (!setContextFlag) { + setContext(object, fieldName); + setContextFlag = true; + } + + if (object.getClass() == JSONObject.class) { + key = (key == null) ? "null" : key.toString(); + } + + Object value; + if (ch == '"') { + lexer.scanString(); + String strValue = lexer.stringVal(); + value = strValue; + + if (lexer.isEnabled(Feature.AllowISO8601DateFormat)) { + JSONScanner iso8601Lexer = new JSONScanner(strValue); + if (iso8601Lexer.scanISO8601DateIfMatch()) { + value = iso8601Lexer.getCalendar().getTime(); + } + iso8601Lexer.close(); + } + + object.put(key, value); + } else if (ch >= '0' && ch <= '9' || ch == '-') { + lexer.scanNumber(); + if (lexer.token() == JSONToken.LITERAL_INT) { + value = lexer.integerValue(); + } else { + value = lexer.decimalValue(isEnabled(Feature.UseBigDecimal)); + } + + object.put(key, value); + } else if (ch == '[') { // 减少嵌套,兼容android + lexer.nextToken(); + JSONArray list = new JSONArray(); + this.parseArray(list, key); + value = list; + object.put(key, value); + + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(); + return object; + } else if (lexer.token() == JSONToken.COMMA) { + continue; + } else { + throw new JSONException("syntax error"); + } + } else if (ch == '{') { // 减少嵌套,兼容android + lexer.nextToken(); + + final boolean parentIsArray = fieldName != null && fieldName.getClass() == Integer.class; + + JSONObject input = new JSONObject(isEnabled(Feature.OrderedField)); + ParseContext ctxLocal = null; + + if (!parentIsArray) { + ctxLocal = setContext(context, input, key); + } + + Object obj = this.parseObject(input, key); + if (ctxLocal != null && input != obj) { + ctxLocal.setObject(object); + } + + checkMapResolve(object, key.toString()); + + if (object.getClass() == JSONObject.class) { + object.put(key.toString(), obj); + } else { + object.put(key, obj); + } + + if (parentIsArray) { + setContext(context, obj, key); + } + + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(); + + setContext(context); + return object; + } else if (lexer.token() == JSONToken.COMMA) { + continue; + } else { + throw new JSONException("syntax error, " + lexer.tokenName()); + } + } else { + lexer.nextToken(); + value = parse(); + + if (object.getClass() == JSONObject.class) { + key = key.toString(); + } + object.put(key, value); + + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(); + return object; + } else if (lexer.token() == JSONToken.COMMA) { + continue; + } else { + throw new JSONException("syntax error, position at " + lexer.pos() + ", name " + key); + } } - key = lexer.scanSymbolUnQuoted(symbolTable); lexer.skipWhitespace(); ch = lexer.getCurrent(); - if (ch != ':') { - throw new JSONException("expect ':' at " + lexer.pos() + ", actual " + ch); + if (ch == ',') { + lexer.next(); + continue; + } else if (ch == '}') { + lexer.next(); + lexer.resetStringPosition(); + lexer.nextToken(); + + this.setContext(object, fieldName); + + return object; + } else { + throw new JSONException("syntax error, position at " + lexer.pos() + ", name " + key); } + } + } finally { + this.setContext(context); + } + + } - lexer.incrementBufferPosition(); - lexer.skipWhitespace(); - ch = lexer.getCurrent(); + public ParserConfig getConfig() { + return config; + } - lexer.resetStringPosition(); + public void setConfig(ParserConfig config) { + this.config = config; + } - Object value; - if (ch == '"') { - lexer.scanString(); - String strValue = lexer.stringVal(); - value = strValue; + // compatible + @SuppressWarnings("unchecked") + public T parseObject(Class clazz) { + return (T) parseObject((Type) clazz); + } - if (lexer.isEnabled(Feature.AllowISO8601DateFormat)) { - JSONScanner iso8601Lexer = new JSONScanner(strValue); - if (iso8601Lexer.scanISO8601DateIfMatch()) { - value = iso8601Lexer.getCalendar().getTime(); + @SuppressWarnings("unchecked") + public T parseObject(Type type) { + if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(); + return null; + } + + if (lexer.token() == JSONToken.LITERAL_STRING) { + type = TypeUtils.unwrap(type); + if (type == byte[].class) { + byte[] bytes = lexer.bytesValue(); + lexer.nextToken(); + return (T) bytes; + } + + if (type == char[].class) { + String strVal = lexer.stringVal(); + lexer.nextToken(); + return (T) strVal.toCharArray(); + } + } + + ObjectDeserializer derializer = config.getDeserializer(type); + + try { + return (T) derializer.deserialze(this, type, null); + } catch (JSONException e) { + throw e; + } catch (Throwable e) { + throw new JSONException(e.getMessage(), e); + } + } + + public List parseArray(Class clazz) { + List array = new ArrayList(); + parseArray(clazz, array); + return array; + } + + public void parseArray(Class clazz, @SuppressWarnings("rawtypes") Collection array) { + parseArray((Type) clazz, array); + } + + @SuppressWarnings("rawtypes") + public void parseArray(Type type, Collection array) { + parseArray(type, array, null); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void parseArray(Type type, Collection array, Object fieldName) { + if (lexer.token() == JSONToken.SET || lexer.token() == JSONToken.TREE_SET) { + lexer.nextToken(); + } + + if (lexer.token() != JSONToken.LBRACKET) { + throw new JSONException("exepct '[', but " + JSONToken.name(lexer.token())); + } + + ObjectDeserializer deserializer = null; + if (int.class == type) { + deserializer = IntegerCodec.instance; + lexer.nextToken(JSONToken.LITERAL_INT); + } else if (String.class == type) { + deserializer = StringCodec.instance; + lexer.nextToken(JSONToken.LITERAL_STRING); + } else { + deserializer = config.getDeserializer(type); + lexer.nextToken(deserializer.getFastMatchToken()); + } + + ParseContext context = this.getContext(); + this.setContext(array, fieldName); + try { + for (int i = 0;; ++i) { + if (isEnabled(Feature.AllowArbitraryCommas)) { + while (lexer.token() == JSONToken.COMMA) { + lexer.nextToken(); + continue; } } - object.put(key, value); - } else if (ch >= '0' && ch <= '9' || ch == '-') { - lexer.scanNumber(); - if (lexer.token() == JSONToken.LITERAL_INT) { - value = lexer.integerValue(); - } else { - value = lexer.decimalValue(); + if (lexer.token() == JSONToken.RBRACKET) { + break; } - object.put(key, value); - } else if (ch == '[') { // 减少潜套,兼容android - lexer.nextToken(); - JSONArray list = new JSONArray(); - this.parseArray(list); - value = list; - object.put(key, value); + if (int.class == type) { + Object val = IntegerCodec.instance.deserialze(this, null, null); + array.add(val); + } else if (String.class == type) { + String value; + if (lexer.token() == JSONToken.LITERAL_STRING) { + value = lexer.stringVal(); + lexer.nextToken(JSONToken.COMMA); + } else { + Object obj = this.parse(); + if (obj == null) { + value = null; + } else { + value = obj.toString(); + } + } - if (lexer.token() == JSONToken.RBRACE) { - lexer.nextToken(); - return; - } else if (lexer.token() == JSONToken.COMMA) { - continue; + array.add(value); } else { - throw new JSONException("syntax error"); + Object val; + if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(); + val = null; + } else { + val = deserializer.deserialze(this, type, i); + } + array.add(val); + checkListResolve(array); } - } else if (ch == '{') { // 减少潜套,兼容android - lexer.nextToken(); - JSONObject obj = new JSONObject(); - this.parseObject(obj); - object.put(key, obj); - if (lexer.token() == JSONToken.RBRACE) { - lexer.nextToken(); - return; - } else if (lexer.token() == JSONToken.COMMA) { + if (lexer.token() == JSONToken.COMMA) { + lexer.nextToken(deserializer.getFastMatchToken()); continue; + } + } + } finally { + this.setContext(context); + } + + lexer.nextToken(JSONToken.COMMA); + } + + public Object[] parseArray(Type[] types) { + if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(JSONToken.COMMA); + return null; + } + + if (lexer.token() != JSONToken.LBRACKET) { + throw new JSONException("syntax error : " + lexer.tokenName()); + } + + Object[] list = new Object[types.length]; + if (types.length == 0) { + lexer.nextToken(JSONToken.RBRACKET); + + if (lexer.token() != JSONToken.RBRACKET) { + throw new JSONException("syntax error"); + } + + lexer.nextToken(JSONToken.COMMA); + return new Object[0]; + } + + lexer.nextToken(JSONToken.LITERAL_INT); + + for (int i = 0; i < types.length; ++i) { + Object value; + + if (lexer.token() == JSONToken.NULL) { + value = null; + lexer.nextToken(JSONToken.COMMA); + } else { + Type type = types[i]; + if (type == int.class || type == Integer.class) { + if (lexer.token() == JSONToken.LITERAL_INT) { + value = Integer.valueOf(lexer.intValue()); + lexer.nextToken(JSONToken.COMMA); + } else { + value = this.parse(); + value = TypeUtils.cast(value, type, config); + } + } else if (type == String.class) { + if (lexer.token() == JSONToken.LITERAL_STRING) { + value = lexer.stringVal(); + lexer.nextToken(JSONToken.COMMA); + } else { + value = this.parse(); + value = TypeUtils.cast(value, type, config); + } } else { - throw new JSONException("syntax error"); + boolean isArray = false; + Class componentType = null; + if (i == types.length - 1) { + if (type instanceof Class) { + Class clazz = (Class) type; + isArray = clazz.isArray(); + componentType = clazz.getComponentType(); + } + } + + // support varArgs + if (isArray && lexer.token() != JSONToken.LBRACKET) { + List varList = new ArrayList(); + + ObjectDeserializer derializer = config.getDeserializer(componentType); + int fastMatch = derializer.getFastMatchToken(); + + if (lexer.token() != JSONToken.RBRACKET) { + for (;;) { + Object item = derializer.deserialze(this, type, null); + varList.add(item); + + if (lexer.token() == JSONToken.COMMA) { + lexer.nextToken(fastMatch); + } else if (lexer.token() == JSONToken.RBRACKET) { + break; + } else { + throw new JSONException("syntax error :" + JSONToken.name(lexer.token())); + } + } + } + + value = TypeUtils.cast(varList, type, config); + } else { + ObjectDeserializer derializer = config.getDeserializer(type); + value = derializer.deserialze(this, type, null); + } } + } + list[i] = value; + + if (lexer.token() == JSONToken.RBRACKET) { + break; + } + + if (lexer.token() != JSONToken.COMMA) { + throw new JSONException("syntax error :" + JSONToken.name(lexer.token())); + } + + if (i == types.length - 1) { + lexer.nextToken(JSONToken.RBRACKET); } else { - lexer.nextToken(); - value = parse(); - object.put(key, value); + lexer.nextToken(JSONToken.LITERAL_INT); + } + } + + if (lexer.token() != JSONToken.RBRACKET) { + throw new JSONException("syntax error"); + } + + lexer.nextToken(JSONToken.COMMA); + + return list; + } + + public void parseObject(Object object) { + Class clazz = object.getClass(); + Map setters = config.getFieldDeserializers(clazz); + + if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) { + throw new JSONException("syntax error, expect {, actual " + lexer.tokenName()); + } + + for (;;) { + // lexer.scanSymbol + String key = lexer.scanSymbol(symbolTable); + + if (key == null) { + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(JSONToken.COMMA); + break; + } + if (lexer.token() == JSONToken.COMMA) { + if (isEnabled(Feature.AllowArbitraryCommas)) { + continue; + } + } + } + + FieldDeserializer fieldDeser = setters.get(key); + + if (fieldDeser == null && key != null) { + for (Map.Entry entry : setters.entrySet()) { + if (key.equalsIgnoreCase((entry.getKey()))) { + fieldDeser = entry.getValue(); + break; + } + } + } + + if (fieldDeser == null) { + if (!isEnabled(Feature.IgnoreNotMatch)) { + throw new JSONException("setter not found, class " + clazz.getName() + ", property " + key); + } + + lexer.nextTokenWithColon(); + parse(); // skip if (lexer.token() == JSONToken.RBRACE) { lexer.nextToken(); return; - } else if (lexer.token() == JSONToken.COMMA) { - continue; + } + + continue; + } else { + Class fieldClass = fieldDeser.getFieldClass(); + Type fieldType = fieldDeser.getFieldType(); + Object fieldValue; + if (fieldClass == int.class) { + lexer.nextTokenWithColon(JSONToken.LITERAL_INT); + fieldValue = IntegerCodec.instance.deserialze(this, fieldType, null); + } else if (fieldClass == String.class) { + lexer.nextTokenWithColon(JSONToken.LITERAL_STRING); + fieldValue = StringCodec.deserialze(this); + } else if (fieldClass == long.class) { + lexer.nextTokenWithColon(JSONToken.LITERAL_INT); + fieldValue = LongCodec.instance.deserialze(this, fieldType, null); } else { - throw new JSONException("syntax error, position at " + lexer.pos() + ", name " + key); + ObjectDeserializer fieldValueDeserializer = config.getDeserializer(fieldClass, fieldType); + + lexer.nextTokenWithColon(fieldValueDeserializer.getFastMatchToken()); + fieldValue = fieldValueDeserializer.deserialze(this, fieldType, null); } + + fieldDeser.setValue(object, fieldValue); } - lexer.skipWhitespace(); - ch = lexer.getCurrent(); - if (ch == ',') { - lexer.incrementBufferPosition(); + if (lexer.token() == JSONToken.COMMA) { continue; - } else if (ch == '}') { - lexer.incrementBufferPosition(); - lexer.resetStringPosition(); - lexer.nextToken(); + } + + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(JSONToken.COMMA); return; + } + } + } + + public Object parseArrayWithType(Type collectionType) { + if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(); + return null; + } + + Type[] actualTypes = ((ParameterizedType) collectionType).getActualTypeArguments(); + + if (actualTypes.length != 1) { + throw new JSONException("not support type " + collectionType); + } + + Type actualTypeArgument = actualTypes[0]; + + if (actualTypeArgument instanceof Class) { + List array = new ArrayList(); + this.parseArray((Class) actualTypeArgument, array); + return array; + } + + if (actualTypeArgument instanceof WildcardType) { + WildcardType wildcardType = (WildcardType) actualTypeArgument; + + // assert wildcardType.getUpperBounds().length == 1; + Type upperBoundType = wildcardType.getUpperBounds()[0]; + + // assert upperBoundType instanceof Class; + if (Object.class.equals(upperBoundType)) { + if (wildcardType.getLowerBounds().length == 0) { + // Collection + return parse(); + } else { + throw new JSONException("not support type : " + collectionType); + } + } + + List array = new ArrayList(); + this.parseArray((Class) upperBoundType, array); + return array; + + // throw new JSONException("not support type : " + + // collectionType);return parse(); + } + + if (actualTypeArgument instanceof TypeVariable) { + TypeVariable typeVariable = (TypeVariable) actualTypeArgument; + Type[] bounds = typeVariable.getBounds(); + + if (bounds.length != 1) { + throw new JSONException("not support : " + typeVariable); + } + + Type boundType = bounds[0]; + if (boundType instanceof Class) { + List array = new ArrayList(); + this.parseArray((Class) boundType, array); + return array; + } + } + + if (actualTypeArgument instanceof ParameterizedType) { + ParameterizedType parameterizedType = (ParameterizedType) actualTypeArgument; + + List array = new ArrayList(); + this.parseArray(parameterizedType, array); + return array; + } + + throw new JSONException("TODO : " + collectionType); + } + + public void acceptType(String typeName) { + JSONLexer lexer = this.lexer; + + lexer.nextTokenWithColon(); + + if (lexer.token() != JSONToken.LITERAL_STRING) { + throw new JSONException("type not match error"); + } + + if (typeName.equals(lexer.stringVal())) { + lexer.nextToken(); + if (lexer.token() == JSONToken.COMMA) { + lexer.nextToken(); + } + } else { + throw new JSONException("type not match error"); + } + } + + public int getResolveStatus() { + return resolveStatus; + } + + public void setResolveStatus(int resolveStatus) { + this.resolveStatus = resolveStatus; + } + + public Object getObject(String path) { + for (int i = 0; i < contextArrayIndex; ++i) { + if (path.equals(contextArray[i].getPath())) { + return contextArray[i].getObject(); + } + } + + return null; + } + + @SuppressWarnings("rawtypes") + public void checkListResolve(Collection array) { + if (resolveStatus == NeedToResolve) { + if (array instanceof List) { + final int index = array.size() - 1; + final List list = (List) array; + ResolveTask task = getLastResolveTask(); + task.setFieldDeserializer(new ListResolveFieldDeserializer(this, list, index)); + task.setOwnerContext(context); + setResolveStatus(DefaultJSONParser.NONE); } else { - throw new JSONException("syntax error, position at " + lexer.pos() + ", name " + key); + ResolveTask task = getLastResolveTask(); + task.setFieldDeserializer(new CollectionResolveFieldDeserializer(this, array)); + task.setOwnerContext(context); + setResolveStatus(DefaultJSONParser.NONE); + } + } + } + + @SuppressWarnings("rawtypes") + public void checkMapResolve(Map object, String fieldName) { + if (resolveStatus == NeedToResolve) { + MapResolveFieldDeserializer fieldResolver = new MapResolveFieldDeserializer(object, fieldName); + ResolveTask task = getLastResolveTask(); + task.setFieldDeserializer(fieldResolver); + task.setOwnerContext(context); + setResolveStatus(DefaultJSONParser.NONE); + } + } + + @SuppressWarnings("rawtypes") + public Object parseObject(final Map object) { + return parseObject(object, null); + } + + public JSONObject parseObject() { + JSONObject object = new JSONObject(isEnabled(Feature.OrderedField)); + parseObject(object); + return object; + } + + @SuppressWarnings("rawtypes") + public final void parseArray(final Collection array) { + parseArray(array, null); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public final void parseArray(final Collection array, Object fieldName) { + final JSONLexer lexer = getLexer(); + + if (lexer.token() == JSONToken.SET || lexer.token() == JSONToken.TREE_SET) { + lexer.nextToken(); + } + + if (lexer.token() != JSONToken.LBRACKET) { + throw new JSONException("syntax error, expect [, actual " + JSONToken.name(lexer.token()) + ", pos " + + lexer.pos()); + } + + lexer.nextToken(JSONToken.LITERAL_STRING); + + ParseContext context = this.getContext(); + this.setContext(array, fieldName); + try { + for (int i = 0;; ++i) { + if (isEnabled(Feature.AllowArbitraryCommas)) { + while (lexer.token() == JSONToken.COMMA) { + lexer.nextToken(); + continue; + } + } + + Object value; + switch (lexer.token()) { + case LITERAL_INT: + value = lexer.integerValue(); + lexer.nextToken(JSONToken.COMMA); + break; + case LITERAL_FLOAT: + if (lexer.isEnabled(Feature.UseBigDecimal)) { + value = lexer.decimalValue(true); + } else { + value = lexer.decimalValue(false); + } + lexer.nextToken(JSONToken.COMMA); + break; + case LITERAL_STRING: + String stringLiteral = lexer.stringVal(); + lexer.nextToken(JSONToken.COMMA); + + if (lexer.isEnabled(Feature.AllowISO8601DateFormat)) { + JSONScanner iso8601Lexer = new JSONScanner(stringLiteral); + if (iso8601Lexer.scanISO8601DateIfMatch()) { + value = iso8601Lexer.getCalendar().getTime(); + } else { + value = stringLiteral; + } + iso8601Lexer.close(); + } else { + value = stringLiteral; + } + + break; + case TRUE: + value = Boolean.TRUE; + lexer.nextToken(JSONToken.COMMA); + break; + case FALSE: + value = Boolean.FALSE; + lexer.nextToken(JSONToken.COMMA); + break; + case LBRACE: + JSONObject object = new JSONObject(isEnabled(Feature.OrderedField)); + value = parseObject(object, i); + break; + case LBRACKET: + Collection items = new JSONArray(); + parseArray(items, i); + value = items; + break; + case NULL: + value = null; + lexer.nextToken(JSONToken.LITERAL_STRING); + break; + case UNDEFINED: + value = null; + lexer.nextToken(JSONToken.LITERAL_STRING); + break; + case RBRACKET: + lexer.nextToken(JSONToken.COMMA); + return; + case EOF: + throw new JSONException("unclosed jsonArray"); + default: + value = parse(); + break; + } + + array.add(value); + checkListResolve(array); + + if (lexer.token() == JSONToken.COMMA) { + lexer.nextToken(JSONToken.LITERAL_STRING); + continue; + } } + } finally { + this.setContext(context); + } + } + public ParseContext getContext() { + return context; + } + + public List getResolveTaskList() { + if (resolveTaskList == null) { + resolveTaskList = new ArrayList(2); } + return resolveTaskList; + } + + public List getResolveTaskListDirect() { + return resolveTaskList; } + public void addResolveTask(ResolveTask task) { + if (resolveTaskList == null) { + resolveTaskList = new ArrayList(2); + } + resolveTaskList.add(task); + } + + public ResolveTask getLastResolveTask() { + return resolveTaskList.get(resolveTaskList.size() - 1); + } + + public List getExtraProcessors() { + if (extraProcessors == null) { + extraProcessors = new ArrayList(2); + } + return extraProcessors; + } + + public List getExtraProcessorsDirect() { + return extraProcessors; + } + + public List getExtraTypeProviders() { + if (extraTypeProviders == null) { + extraTypeProviders = new ArrayList(2); + } + return extraTypeProviders; + } + + public List getExtraTypeProvidersDirect() { + return extraTypeProviders; + } + + public void setContext(ParseContext context) { + if (isEnabled(Feature.DisableCircularReferenceDetect)) { + return; + } + this.context = context; + } + + public void popContext() { + if (isEnabled(Feature.DisableCircularReferenceDetect)) { + return; + } + + this.context = this.context.getParentContext(); + contextArray[contextArrayIndex - 1] = null; + contextArrayIndex--; + } + + public ParseContext setContext(Object object, Object fieldName) { + if (isEnabled(Feature.DisableCircularReferenceDetect)) { + return null; + } + + return setContext(this.context, object, fieldName); + } + + public ParseContext setContext(ParseContext parent, Object object, Object fieldName) { + if (isEnabled(Feature.DisableCircularReferenceDetect)) { + return null; + } + + this.context = new ParseContext(parent, object, fieldName); + addContext(this.context); + + return this.context; + } + + private void addContext(ParseContext context) { + int i = contextArrayIndex++; + if (i >= contextArray.length) { + int newLen = (contextArray.length * 3) / 2; + ParseContext[] newArray = new ParseContext[newLen]; + System.arraycopy(contextArray, 0, newArray, 0, contextArray.length); + contextArray = newArray; + } + contextArray[i] = context; + } + + public Object parse() { + return parse(null); + } + + public Object parseKey() { + if (lexer.token() == JSONToken.IDENTIFIER) { + String value = lexer.stringVal(); + lexer.nextToken(JSONToken.COMMA); + return value; + } + return parse(null); + } + + public Object parse(Object fieldName) { + final JSONLexer lexer = getLexer(); + switch (lexer.token()) { + case SET: + lexer.nextToken(); + HashSet set = new HashSet(); + parseArray(set, fieldName); + return set; + case TREE_SET: + lexer.nextToken(); + TreeSet treeSet = new TreeSet(); + parseArray(treeSet, fieldName); + return treeSet; + case LBRACKET: + JSONArray array = new JSONArray(); + parseArray(array, fieldName); + return array; + case LBRACE: + JSONObject object = new JSONObject(isEnabled(Feature.OrderedField)); + return parseObject(object, fieldName); + case LITERAL_INT: + Number intValue = lexer.integerValue(); + lexer.nextToken(); + return intValue; + case LITERAL_FLOAT: + Object value = lexer.decimalValue(isEnabled(Feature.UseBigDecimal)); + lexer.nextToken(); + return value; + case LITERAL_STRING: + String stringLiteral = lexer.stringVal(); + lexer.nextToken(JSONToken.COMMA); + + if (lexer.isEnabled(Feature.AllowISO8601DateFormat)) { + JSONScanner iso8601Lexer = new JSONScanner(stringLiteral); + try { + if (iso8601Lexer.scanISO8601DateIfMatch()) { + return iso8601Lexer.getCalendar().getTime(); + } + } finally { + iso8601Lexer.close(); + } + } + + return stringLiteral; + case NULL: + lexer.nextToken(); + return null; + case UNDEFINED: + lexer.nextToken(); + return null; + case TRUE: + lexer.nextToken(); + return Boolean.TRUE; + case FALSE: + lexer.nextToken(); + return Boolean.FALSE; + case NEW: + lexer.nextToken(JSONToken.IDENTIFIER); + + if (lexer.token() != JSONToken.IDENTIFIER) { + throw new JSONException("syntax error"); + } + lexer.nextToken(JSONToken.LPAREN); + + accept(JSONToken.LPAREN); + long time = ((Number) lexer.integerValue()).longValue(); + accept(JSONToken.LITERAL_INT); + + accept(JSONToken.RPAREN); + + return new Date(time); + case EOF: + if (lexer.isBlankInput()) { + return null; + } + throw new JSONException("unterminated json string, pos " + lexer.getBufferPosition()); + case ERROR: + default: + throw new JSONException("syntax error, pos " + lexer.getBufferPosition()); + } + } + + public void config(Feature feature, boolean state) { + getLexer().config(feature, state); + } + + public boolean isEnabled(Feature feature) { + return getLexer().isEnabled(feature); + } + + public JSONLexer getLexer() { + return lexer; + } + + public final void accept(final int token) { + final JSONLexer lexer = getLexer(); + if (lexer.token() == token) { + lexer.nextToken(); + } else { + throw new JSONException("syntax error, expect " + JSONToken.name(token) + ", actual " + + JSONToken.name(lexer.token())); + } + } + + public final void accept(final int token, int nextExpectToken) { + final JSONLexer lexer = getLexer(); + if (lexer.token() == token) { + lexer.nextToken(nextExpectToken); + } else { + throw new JSONException("syntax error, expect " + JSONToken.name(token) + ", actual " + + JSONToken.name(lexer.token())); + } + } + + public void close() { + final JSONLexer lexer = getLexer(); + + try { + if (isEnabled(Feature.AutoCloseSource)) { + if (lexer.token() != JSONToken.EOF) { + throw new JSONException("not close json text, token : " + JSONToken.name(lexer.token())); + } + } + } finally { + lexer.close(); + } + } + + public void handleResovleTask(Object value) { + if (resolveTaskList == null) { + return; + } + + int size = resolveTaskList.size(); + for (int i = 0; i < size; ++i) { + ResolveTask task = resolveTaskList.get(i); + FieldDeserializer fieldDeser = task.getFieldDeserializer(); + + if (fieldDeser == null) { + continue; + } + + Object object = null; + if (task.getOwnerContext() != null) { + object = task.getOwnerContext().getObject(); + } + + String ref = task.getReferenceValue(); + Object refValue; + if (ref.startsWith("$")) { + refValue = getObject(ref); + } else { + refValue = task.getContext().getObject(); + } + fieldDeser.setValue(object, refValue); + } + } + + public static class ResolveTask { + + private final ParseContext context; + private final String referenceValue; + private FieldDeserializer fieldDeserializer; + private ParseContext ownerContext; + + public ResolveTask(ParseContext context, String referenceValue){ + this.context = context; + this.referenceValue = referenceValue; + } + + public ParseContext getContext() { + return context; + } + + public String getReferenceValue() { + return referenceValue; + } + + public FieldDeserializer getFieldDeserializer() { + return fieldDeserializer; + } + + public void setFieldDeserializer(FieldDeserializer fieldDeserializer) { + this.fieldDeserializer = fieldDeserializer; + } + + public ParseContext getOwnerContext() { + return ownerContext; + } + + public void setOwnerContext(ParseContext ownerContext) { + this.ownerContext = ownerContext; + } + + } } diff --git a/src/main/java/com/alibaba/fastjson/parser/Feature.java b/src/main/java/com/alibaba/fastjson/parser/Feature.java old mode 100644 new mode 100755 index 19585e2241..507c4c0ed4 --- a/src/main/java/com/alibaba/fastjson/parser/Feature.java +++ b/src/main/java/com/alibaba/fastjson/parser/Feature.java @@ -15,8 +15,9 @@ */ package com.alibaba.fastjson.parser; + /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public enum Feature { /** @@ -60,14 +61,36 @@ public enum Feature { IgnoreNotMatch, /** - * + * @since 1.1.3 */ SortFeidFastMatch, /** + * @since 1.1.3 + */ + DisableASM, + + /** + * @since 1.1.7 + */ + DisableCircularReferenceDetect, + + /** + * @since 1.1.10 + */ + InitStringFieldAsEmpty, + + /** + * @since 1.1.35 + * + */ + SupportArrayToBean, + + /** + * @since 1.2.3 * */ - DisableASM + OrderedField ; private Feature(){ @@ -93,4 +116,18 @@ public static int config(int features, Feature feature, boolean state) { return features; } + + public static int of(Feature[] features) { + if (features == null) { + return 0; + } + + int value = 0; + + for (Feature feature: features) { + value |= feature.getMask(); + } + + return value; + } } diff --git a/src/main/java/com/alibaba/fastjson/parser/JSONLexer.java b/src/main/java/com/alibaba/fastjson/parser/JSONLexer.java index d4f19874b8..0afa3938e7 100644 --- a/src/main/java/com/alibaba/fastjson/parser/JSONLexer.java +++ b/src/main/java/com/alibaba/fastjson/parser/JSONLexer.java @@ -1,83 +1,91 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.parser; - -import java.math.BigDecimal; -import java.util.Calendar; - -/** - * @author wenshao - */ -public interface JSONLexer { - - void nextToken(); - - void nextToken(int expect); - - int token(); - - int pos(); - - String stringVal(); - - Number integerValue(); - - void nextTokenWithColon(int expect); - - BigDecimal decimalValue(); - - double doubleValue(); - - float floatValue(); - - void config(Feature feature, boolean state); - - boolean isEnabled(Feature feature); - - String numberString(); - - boolean isEOF(); - - String symbol(SymbolTable symbolTable); - - boolean isBlankInput(); - - char getCurrent(); - - void skipWhitespace(); - - void incrementBufferPosition(); - - String scanSymbol(final SymbolTable symbolTable); - - String scanSymbol(final SymbolTable symbolTable, final char quote); - - void resetStringPosition(); - - String scanSymbolUnQuoted(final SymbolTable symbolTable); - - void scanString(); - - void scanNumber(); - - boolean scanISO8601DateIfMatch(); - - Calendar getCalendar(); - - int intValue() throws NumberFormatException; - - long longValue() throws NumberFormatException; -} +package com.alibaba.fastjson.parser; + +import java.math.BigDecimal; +import java.util.Collection; + +public interface JSONLexer { + + public final static byte EOI = 0x1A; + public final static int NOT_MATCH = -1; + public final static int NOT_MATCH_NAME = -2; + public final static int UNKOWN = 0; + public final static int OBJECT = 1; + public final static int ARRAY = 2; + public final static int VALUE = 3; + public final static int END = 4; + + int token(); + + String tokenName(); + + void skipWhitespace(); + + void nextToken(); + + void nextToken(int expect); + + char getCurrent(); + + char next(); + + String scanSymbol(final SymbolTable symbolTable); + + String scanSymbol(final SymbolTable symbolTable, final char quote); + + void resetStringPosition(); + + void scanNumber(); + + int pos(); + + Number integerValue(); + + BigDecimal decimalValue(); + + Number decimalValue(boolean decimal); + + String scanSymbolUnQuoted(final SymbolTable symbolTable); + + String stringVal(); + + boolean isEnabled(Feature feature); + + void config(Feature feature, boolean state); + + void scanString(); + + int intValue(); + + void nextTokenWithColon(); + + void nextTokenWithColon(int expect); + + boolean isBlankInput(); + + int getBufferPosition(); + + void close(); + + long longValue(); + + boolean isRef(); + + String numberString(); + + byte[] bytesValue(); + + float floatValue(); + + long scanLong(char expectNextChar); + + int scanInt(char expectNext); + + String scanString(char expectNextChar); + + Enum scanEnum(Class enumClass, final SymbolTable symbolTable, char serperator); + + String scanSymbolWithSeperator(final SymbolTable symbolTable, char serperator); + + Collection scanStringArray(Class type, char seperator); + +} diff --git a/src/main/java/com/alibaba/fastjson/parser/JSONLexerBase.java b/src/main/java/com/alibaba/fastjson/parser/JSONLexerBase.java new file mode 100755 index 0000000000..cccd363f78 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/parser/JSONLexerBase.java @@ -0,0 +1,3009 @@ +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.parser; + +import static com.alibaba.fastjson.parser.JSONToken.COLON; +import static com.alibaba.fastjson.parser.JSONToken.COMMA; +import static com.alibaba.fastjson.parser.JSONToken.EOF; +import static com.alibaba.fastjson.parser.JSONToken.ERROR; +import static com.alibaba.fastjson.parser.JSONToken.LBRACE; +import static com.alibaba.fastjson.parser.JSONToken.LBRACKET; +import static com.alibaba.fastjson.parser.JSONToken.LITERAL_STRING; +import static com.alibaba.fastjson.parser.JSONToken.LPAREN; +import static com.alibaba.fastjson.parser.JSONToken.RBRACE; +import static com.alibaba.fastjson.parser.JSONToken.RBRACKET; +import static com.alibaba.fastjson.parser.JSONToken.RPAREN; + +import java.io.Closeable; +import java.lang.ref.SoftReference; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.util.IOUtils; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public abstract class JSONLexerBase implements JSONLexer, Closeable { + + private final static Map DEFAULT_KEYWORDS; + + static { + Map map = new HashMap(); + map.put("null", JSONToken.NULL); + map.put("new", JSONToken.NEW); + map.put("true", JSONToken.TRUE); + map.put("false", JSONToken.FALSE); + map.put("undefined", JSONToken.UNDEFINED); + DEFAULT_KEYWORDS = map; + } + + protected void lexError(String key, Object... args) { + token = ERROR; + } + + protected int token; + protected int pos; + protected int features = JSON.DEFAULT_PARSER_FEATURE; + + protected char ch; + protected int bp; + + protected int eofPos; + + /** + * A character buffer for literals. + */ + protected char[] sbuf; + protected int sp; + + /** + * number start position + */ + protected int np; + + protected boolean hasSpecial; + + protected Calendar calendar = null; + + public int matchStat = UNKOWN; + + private final static ThreadLocal> SBUF_REF_LOCAL = new ThreadLocal>(); + protected Map keywods = DEFAULT_KEYWORDS; + + public JSONLexerBase(){ + SoftReference sbufRef = SBUF_REF_LOCAL.get(); + + if (sbufRef != null) { + sbuf = sbufRef.get(); + SBUF_REF_LOCAL.set(null); + } + + if (sbuf == null) { + sbuf = new char[64]; + } + } + + public final int matchStat() { + return matchStat; + } + + public final void nextToken() { + sp = 0; + + for (;;) { + pos = bp; + + if (ch == '"') { + scanString(); + return; + } + + if (ch == ',') { + next(); + token = COMMA; + return; + } + + if (ch >= '0' && ch <= '9') { + scanNumber(); + return; + } + + if (ch == '-') { + scanNumber(); + return; + } + + switch (ch) { + case '\'': + if (!isEnabled(Feature.AllowSingleQuotes)) { + throw new JSONException("Feature.AllowSingleQuotes is false"); + } + scanStringSingleQuote(); + return; + case ' ': + case '\t': + case '\b': + case '\f': + case '\n': + case '\r': + next(); + break; + case 't': // true + scanTrue(); + return; + case 'T': // true + scanTreeSet(); + return; + case 'S': // set + scanSet(); + return; + case 'f': // false + scanFalse(); + return; + case 'n': // new,null + scanNullOrNew(); + return; + case 'N': // new,null + scanNULL(); + return; + case 'u': // new,null + scanUndefined(); + return; + case '(': + next(); + token = LPAREN; + return; + case ')': + next(); + token = RPAREN; + return; + case '[': + next(); + token = LBRACKET; + return; + case ']': + next(); + token = RBRACKET; + return; + case '{': + next(); + token = LBRACE; + return; + case '}': + next(); + token = RBRACE; + return; + case ':': + next(); + token = COLON; + return; + default: + if (isEOF()) { // JLS + if (token == EOF) { + throw new JSONException("EOF error"); + } + + token = EOF; + pos = bp = eofPos; + } else { + lexError("illegal.char", String.valueOf((int) ch)); + next(); + } + + return; + } + } + + } + + public final void nextToken(int expect) { + sp = 0; + + for (;;) { + switch (expect) { + case JSONToken.LBRACE: + if (ch == '{') { + token = JSONToken.LBRACE; + next(); + return; + } + if (ch == '[') { + token = JSONToken.LBRACKET; + next(); + return; + } + break; + case JSONToken.COMMA: + if (ch == ',') { + token = JSONToken.COMMA; + next(); + return; + } + + if (ch == '}') { + token = JSONToken.RBRACE; + next(); + return; + } + + if (ch == ']') { + token = JSONToken.RBRACKET; + next(); + return; + } + + if (ch == EOI) { + token = JSONToken.EOF; + return; + } + break; + case JSONToken.LITERAL_INT: + if (ch >= '0' && ch <= '9') { + pos = bp; + scanNumber(); + return; + } + + if (ch == '"') { + pos = bp; + scanString(); + return; + } + + if (ch == '[') { + token = JSONToken.LBRACKET; + next(); + return; + } + + if (ch == '{') { + token = JSONToken.LBRACE; + next(); + return; + } + + break; + case JSONToken.LITERAL_STRING: + if (ch == '"') { + pos = bp; + scanString(); + return; + } + + if (ch >= '0' && ch <= '9') { + pos = bp; + scanNumber(); + return; + } + + if (ch == '[') { + token = JSONToken.LBRACKET; + next(); + return; + } + + if (ch == '{') { + token = JSONToken.LBRACE; + next(); + return; + } + break; + case JSONToken.LBRACKET: + if (ch == '[') { + token = JSONToken.LBRACKET; + next(); + return; + } + + if (ch == '{') { + token = JSONToken.LBRACE; + next(); + return; + } + break; + case JSONToken.RBRACKET: + if (ch == ']') { + token = JSONToken.RBRACKET; + next(); + return; + } + case JSONToken.EOF: + if (ch == EOI) { + token = JSONToken.EOF; + return; + } + break; + case JSONToken.IDENTIFIER: + nextIdent(); + return; + default: + break; + } + + if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b') { + next(); + continue; + } + + nextToken(); + break; + } + } + + public final void nextIdent() { + while (isWhitespace(ch)) { + next(); + } + if (ch == '_' || Character.isLetter(ch)) { + scanIdent(); + } else { + nextToken(); + } + } + + public final void nextTokenWithColon() { + nextTokenWithChar(':'); + } + + public final void nextTokenWithComma() { + nextTokenWithChar(':'); + } + + public final void nextTokenWithChar(char expect) { + sp = 0; + + for (;;) { + if (ch == expect) { + next(); + nextToken(); + return; + } + + if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b') { + next(); + continue; + } + + throw new JSONException("not match " + expect + " - " + ch); + } + } + + public final int token() { + return token; + } + + public final String tokenName() { + return JSONToken.name(token); + } + + public final int pos() { + return pos; + } + + public final int getBufferPosition() { + return bp; + } + + public final String stringDefaultValue() { + if (this.isEnabled(Feature.InitStringFieldAsEmpty)) { + return ""; + } + return null; + } + + public final Number integerValue() throws NumberFormatException { + long result = 0; + boolean negative = false; + if (np == -1) { + np = 0; + } + int i = np, max = np + sp; + long limit; + long multmin; + int digit; + + char type = ' '; + + switch (charAt(max - 1)) { + case 'L': + max--; + type = 'L'; + break; + case 'S': + max--; + type = 'S'; + break; + case 'B': + max--; + type = 'B'; + break; + default: + break; + } + + if (charAt(np) == '-') { + negative = true; + limit = Long.MIN_VALUE; + i++; + } else { + limit = -Long.MAX_VALUE; + } + multmin = negative ? MULTMIN_RADIX_TEN : N_MULTMAX_RADIX_TEN; + if (i < max) { + digit = digits[charAt(i++)]; + result = -digit; + } + while (i < max) { + // Accumulating negatively avoids surprises near MAX_VALUE + digit = digits[charAt(i++)]; + if (result < multmin) { + return new BigInteger(numberString()); + } + result *= 10; + if (result < limit + digit) { + return new BigInteger(numberString()); + } + result -= digit; + } + + if (negative) { + if (i > np + 1) { + if (result >= Integer.MIN_VALUE && type != 'L') { + if (type == 'S') { + return (short) result; + } + + if (type == 'B') { + return (byte) result; + } + + return (int) result; + } + return result; + } else { /* Only got "-" */ + throw new NumberFormatException(numberString()); + } + } else { + result = -result; + if (result <= Integer.MAX_VALUE && type != 'L') { + if (type == 'S') { + return (short) result; + } + + if (type == 'B') { + return (byte) result; + } + + return (int) result; + } + return result; + } + } + + public final void nextTokenWithColon(int expect) { + nextTokenWithChar(':'); + } + + public final void nextTokenWithComma(int expect) { + nextTokenWithChar(','); + } + + public final void nextTokenWithChar(char seperator, int expect) { + sp = 0; + + for (;;) { + if (ch == seperator) { + next(); + break; + } + + if (isWhitespace(ch)) { + next(); + continue; + } + + throw new JSONException("not match " + expect + " - " + ch); + } + + for (;;) { + if (expect == JSONToken.LITERAL_INT) { + if (ch >= '0' && ch <= '9') { + pos = bp; + scanNumber(); + return; + } + + if (ch == '"') { + pos = bp; + scanString(); + return; + } + } else if (expect == JSONToken.LITERAL_STRING) { + if (ch == '"') { + pos = bp; + scanString(); + return; + } + + if (ch >= '0' && ch <= '9') { + pos = bp; + scanNumber(); + return; + } + + } else if (expect == JSONToken.LBRACE) { + if (ch == '{') { + token = JSONToken.LBRACE; + next(); + return; + } + if (ch == '[') { + token = JSONToken.LBRACKET; + next(); + return; + } + } else if (expect == JSONToken.LBRACKET) { + if (ch == '[') { + token = JSONToken.LBRACKET; + next(); + return; + } + + if (ch == '{') { + token = JSONToken.LBRACE; + next(); + return; + } + } + + if (isWhitespace(ch)) { + next(); + continue; + } + + nextToken(); + break; + } + } + + public float floatValue() { + return Float.parseFloat(numberString()); + } + + public double doubleValue() { + return Double.parseDouble(numberString()); + } + + public void config(Feature feature, boolean state) { + features = Feature.config(features, feature, state); + } + + public final boolean isEnabled(Feature feature) { + return Feature.isEnabled(this.features, feature); + } + + public abstract String numberString(); + + public abstract boolean isEOF(); + + public final char getCurrent() { + return ch; + } + + public abstract char charAt(int index); + + public abstract char next(); + + public final String scanSymbol(final SymbolTable symbolTable) { + skipWhitespace(); + + if (ch == '"') { + return scanSymbol(symbolTable, '"'); + } + + if (ch == '\'') { + if (!isEnabled(Feature.AllowSingleQuotes)) { + throw new JSONException("syntax error"); + } + + return scanSymbol(symbolTable, '\''); + } + + if (ch == '}') { + next(); + token = JSONToken.RBRACE; + return null; + } + + if (ch == ',') { + next(); + token = JSONToken.COMMA; + return null; + } + + if (ch == EOI) { + token = JSONToken.EOF; + return null; + } + + if (!isEnabled(Feature.AllowUnQuotedFieldNames)) { + throw new JSONException("syntax error"); + } + + return scanSymbolUnQuoted(symbolTable); + } + + // public abstract String scanSymbol(final SymbolTable symbolTable, final char quote); + + protected abstract void arrayCopy(int srcPos, char[] dest, int destPos, int length); + + public final String scanSymbol(final SymbolTable symbolTable, final char quote) { + int hash = 0; + + np = bp; + sp = 0; + boolean hasSpecial = false; + char chLocal; + for (;;) { + chLocal = next(); + + if (chLocal == quote) { + break; + } + + if (chLocal == EOI) { + throw new JSONException("unclosed.str"); + } + + if (chLocal == '\\') { + if (!hasSpecial) { + hasSpecial = true; + + if (sp >= sbuf.length) { + int newCapcity = sbuf.length * 2; + if (sp > newCapcity) { + newCapcity = sp; + } + char[] newsbuf = new char[newCapcity]; + System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length); + sbuf = newsbuf; + } + + // text.getChars(np + 1, np + 1 + sp, sbuf, 0); + // System.arraycopy(this.buf, np + 1, sbuf, 0, sp); + arrayCopy(np + 1, sbuf, 0, sp); + } + + chLocal = next(); + + switch (chLocal) { + case '0': + hash = 31 * hash + (int) chLocal; + putChar('\0'); + break; + case '1': + hash = 31 * hash + (int) chLocal; + putChar('\1'); + break; + case '2': + hash = 31 * hash + (int) chLocal; + putChar('\2'); + break; + case '3': + hash = 31 * hash + (int) chLocal; + putChar('\3'); + break; + case '4': + hash = 31 * hash + (int) chLocal; + putChar('\4'); + break; + case '5': + hash = 31 * hash + (int) chLocal; + putChar('\5'); + break; + case '6': + hash = 31 * hash + (int) chLocal; + putChar('\6'); + break; + case '7': + hash = 31 * hash + (int) chLocal; + putChar('\7'); + break; + case 'b': // 8 + hash = 31 * hash + (int) '\b'; + putChar('\b'); + break; + case 't': // 9 + hash = 31 * hash + (int) '\t'; + putChar('\t'); + break; + case 'n': // 10 + hash = 31 * hash + (int) '\n'; + putChar('\n'); + break; + case 'v': // 11 + hash = 31 * hash + (int) '\u000B'; + putChar('\u000B'); + break; + case 'f': // 12 + case 'F': + hash = 31 * hash + (int) '\f'; + putChar('\f'); + break; + case 'r': // 13 + hash = 31 * hash + (int) '\r'; + putChar('\r'); + break; + case '"': // 34 + hash = 31 * hash + (int) '"'; + putChar('"'); + break; + case '\'': // 39 + hash = 31 * hash + (int) '\''; + putChar('\''); + break; + case '/': // 47 + hash = 31 * hash + (int) '/'; + putChar('/'); + break; + case '\\': // 92 + hash = 31 * hash + (int) '\\'; + putChar('\\'); + break; + case 'x': + char x1 = ch = next(); + char x2 = ch = next(); + + int x_val = digits[x1] * 16 + digits[x2]; + char x_char = (char) x_val; + hash = 31 * hash + (int) x_char; + putChar(x_char); + break; + case 'u': + char c1 = chLocal = next(); + char c2 = chLocal = next(); + char c3 = chLocal = next(); + char c4 = chLocal = next(); + int val = Integer.parseInt(new String(new char[] { c1, c2, c3, c4 }), 16); + hash = 31 * hash + val; + putChar((char) val); + break; + default: + this.ch = chLocal; + throw new JSONException("unclosed.str.lit"); + } + continue; + } + + hash = 31 * hash + chLocal; + + if (!hasSpecial) { + sp++; + continue; + } + + if (sp == sbuf.length) { + putChar(chLocal); + } else { + sbuf[sp++] = chLocal; + } + } + + token = LITERAL_STRING; + + String value; + if (!hasSpecial) { + // return this.text.substring(np + 1, np + 1 + sp).intern(); + int offset; + if (np == -1) { + offset = 0; + } else { + offset = np + 1; + } + value = addSymbol(offset, sp, hash, symbolTable); + } else { + value = symbolTable.addSymbol(sbuf, 0, sp, hash); + } + + sp = 0; + this.next(); + + return value; + } + + public final void resetStringPosition() { + this.sp = 0; + } + + public final String scanSymbolUnQuoted(final SymbolTable symbolTable) { + final boolean[] firstIdentifierFlags = IOUtils.firstIdentifierFlags; + final char first = ch; + + final boolean firstFlag = ch >= firstIdentifierFlags.length || firstIdentifierFlags[first]; + if (!firstFlag) { + throw new JSONException("illegal identifier : " + ch); + } + + final boolean[] identifierFlags = IOUtils.identifierFlags; + + int hash = first; + + np = bp; + sp = 1; + char chLocal; + for (;;) { + chLocal = next(); + + if (chLocal < identifierFlags.length) { + if (!identifierFlags[chLocal]) { + break; + } + } + + hash = 31 * hash + chLocal; + + sp++; + continue; + } + + this.ch = charAt(bp); + token = JSONToken.IDENTIFIER; + + final int NULL_HASH = 3392903; + if (sp == 4 && hash == NULL_HASH && charAt(np) == 'n' && charAt(np + 1) == 'u' && charAt(np + 2) == 'l' + && charAt(np + 3) == 'l') { + return null; + } + + // return text.substring(np, np + sp).intern(); + + return this.addSymbol(np, sp, hash, symbolTable); + // return symbolTable.addSymbol(buf, np, sp, hash); + } + + protected abstract void copyTo(int offset, int count, char[] dest); + + public final void scanString() { + np = bp; + hasSpecial = false; + char ch; + for (;;) { + ch = next(); + + if (ch == '\"') { + break; + } + + if (ch == EOI) { + throw new JSONException("unclosed string : " + ch); + } + + if (ch == '\\') { + if (!hasSpecial) { + hasSpecial = true; + + if (sp >= sbuf.length) { + int newCapcity = sbuf.length * 2; + if (sp > newCapcity) { + newCapcity = sp; + } + char[] newsbuf = new char[newCapcity]; + System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length); + sbuf = newsbuf; + } + + copyTo(np + 1, sp, sbuf); + // text.getChars(np + 1, np + 1 + sp, sbuf, 0); + // System.arraycopy(buf, np + 1, sbuf, 0, sp); + } + + ch = next(); + + switch (ch) { + case '0': + putChar('\0'); + break; + case '1': + putChar('\1'); + break; + case '2': + putChar('\2'); + break; + case '3': + putChar('\3'); + break; + case '4': + putChar('\4'); + break; + case '5': + putChar('\5'); + break; + case '6': + putChar('\6'); + break; + case '7': + putChar('\7'); + break; + case 'b': // 8 + putChar('\b'); + break; + case 't': // 9 + putChar('\t'); + break; + case 'n': // 10 + putChar('\n'); + break; + case 'v': // 11 + putChar('\u000B'); + break; + case 'f': // 12 + case 'F': + putChar('\f'); + break; + case 'r': // 13 + putChar('\r'); + break; + case '"': // 34 + putChar('"'); + break; + case '\'': // 39 + putChar('\''); + break; + case '/': // 47 + putChar('/'); + break; + case '\\': // 92 + putChar('\\'); + break; + case 'x': + char x1 = ch = next(); + char x2 = ch = next(); + + int x_val = digits[x1] * 16 + digits[x2]; + char x_char = (char) x_val; + putChar(x_char); + break; + case 'u': + char u1 = ch = next(); + char u2 = ch = next(); + char u3 = ch = next(); + char u4 = ch = next(); + int val = Integer.parseInt(new String(new char[] { u1, u2, u3, u4 }), 16); + putChar((char) val); + break; + default: + this.ch = ch; + throw new JSONException("unclosed string : " + ch); + } + continue; + } + + if (!hasSpecial) { + sp++; + continue; + } + + if (sp == sbuf.length) { + putChar(ch); + } else { + sbuf[sp++] = ch; + } + } + + token = JSONToken.LITERAL_STRING; + this.ch = next(); + } + + public Calendar getCalendar() { + return this.calendar; + } + + public final int intValue() { + if (np == -1) { + np = 0; + } + + int result = 0; + boolean negative = false; + int i = np, max = np + sp; + int limit; + int multmin; + int digit; + + if (charAt(np) == '-') { + negative = true; + limit = Integer.MIN_VALUE; + i++; + } else { + limit = -Integer.MAX_VALUE; + } + multmin = negative ? INT_MULTMIN_RADIX_TEN : INT_N_MULTMAX_RADIX_TEN; + if (i < max) { + digit = digits[charAt(i++)]; + result = -digit; + } + while (i < max) { + // Accumulating negatively avoids surprises near MAX_VALUE + char chLocal = charAt(i++); + + if (chLocal == 'L' || chLocal == 'S' || chLocal == 'B') { + break; + } + + digit = digits[chLocal]; + + if (result < multmin) { + throw new NumberFormatException(numberString()); + } + result *= 10; + if (result < limit + digit) { + throw new NumberFormatException(numberString()); + } + result -= digit; + } + + if (negative) { + if (i > np + 1) { + return result; + } else { /* Only got "-" */ + throw new NumberFormatException(numberString()); + } + } else { + return -result; + } + } + + public abstract byte[] bytesValue(); + + public void close() { + if (sbuf.length <= 1024 * 8) { + SBUF_REF_LOCAL.set(new SoftReference(sbuf)); + } + this.sbuf = null; + } + + public final boolean isRef() { + if (sp != 4) { + return false; + } + + return charAt(np + 1) == '$' && charAt(np + 2) == 'r' && charAt(np + 3) == 'e' && charAt(np + 4) == 'f'; + } + + protected final static char[] typeFieldName = ("\"" + JSON.DEFAULT_TYPE_KEY + "\":\"").toCharArray(); + + public int scanType(String type) { + matchStat = UNKOWN; + + if (!charArrayCompare(typeFieldName)) { + return NOT_MATCH_NAME; + } + + int bpLocal = this.bp + typeFieldName.length; + + final int typeLength = type.length(); + for (int i = 0; i < typeLength; ++i) { + if (type.charAt(i) != charAt(bpLocal + i)) { + return NOT_MATCH; + } + } + bpLocal += typeLength; + if (charAt(bpLocal) != '"') { + return NOT_MATCH; + } + + this.ch = charAt(++bpLocal); + + if (ch == ',') { + this.ch = charAt(++bpLocal); + this.bp = bpLocal; + token = JSONToken.COMMA; + return VALUE; + } else if (ch == '}') { + ch = charAt(++bpLocal); + if (ch == ',') { + token = JSONToken.COMMA; + this.ch = charAt(++bpLocal); + } else if (ch == ']') { + token = JSONToken.RBRACKET; + this.ch = charAt(++bpLocal); + } else if (ch == '}') { + token = JSONToken.RBRACE; + this.ch = charAt(++bpLocal); + } else if (ch == EOI) { + token = JSONToken.EOF; + } else { + return NOT_MATCH; + } + matchStat = END; + } + + this.bp = bpLocal; + return matchStat; + } + + public final boolean matchField(char[] fieldName) { + if (!charArrayCompare(fieldName)) { + return false; + } + + bp = bp + fieldName.length; + ch = charAt(bp); + + if (ch == '{') { + next(); + token = JSONToken.LBRACE; + } else if (ch == '[') { + next(); + token = JSONToken.LBRACKET; + } else { + nextToken(); + } + + return true; + } + + public abstract int indexOf(char ch, int startIndex); + + public abstract String addSymbol(int offset, int len, int hash, final SymbolTable symbolTable); + + public String scanFieldString(char[] fieldName) { + matchStat = UNKOWN; + + if (!charArrayCompare(fieldName)) { + matchStat = NOT_MATCH_NAME; + return stringDefaultValue(); + } + + // int index = bp + fieldName.length; + + int offset = fieldName.length; + char chLocal = charAt(bp + (offset++)); + + if (chLocal != '"') { + matchStat = NOT_MATCH; + + return stringDefaultValue(); + } + + boolean hasSpecial = false; + final String strVal; + { + int startIndex = bp + fieldName.length + 1; + int endIndex = indexOf('"', startIndex); + if (endIndex == -1) { + throw new JSONException("unclosed str"); + } + + int startIndex2 = bp + fieldName.length + 1; // must re compute + String stringVal = subString(startIndex2, endIndex - startIndex2); + for (int i = bp + fieldName.length + 1; i < endIndex; ++i) { + if (charAt(i) == '\\') { + hasSpecial = true; + break; + } + } + + if (hasSpecial) { + matchStat = NOT_MATCH; + + return stringDefaultValue(); + } + + offset += (endIndex - (bp + fieldName.length + 1) + 1); + chLocal = charAt(bp + (offset++)); + strVal = stringVal; + } + + if (chLocal == ',') { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + return strVal; + } + + if (chLocal == '}') { + chLocal = charAt(bp + (offset++)); + if (chLocal == ',') { + token = JSONToken.COMMA; + bp += (offset - 1); + this.next(); + } else if (chLocal == ']') { + token = JSONToken.RBRACKET; + bp += (offset - 1); + this.next(); + } else if (chLocal == '}') { + token = JSONToken.RBRACE; + bp += (offset - 1); + this.next(); + } else if (chLocal == EOI) { + token = JSONToken.EOF; + bp += (offset - 1); + ch = EOI; + } else { + matchStat = NOT_MATCH; + return stringDefaultValue(); + } + matchStat = END; + } else { + matchStat = NOT_MATCH; + return stringDefaultValue(); + } + + return strVal; + } + + public String scanString(char expectNextChar) { + matchStat = UNKOWN; + + int offset = 0; + char chLocal = charAt(bp + (offset++)); + + if (chLocal == 'n') { + if (charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l') { + offset += 3; + chLocal = charAt(bp + (offset++)); + } else { + matchStat = NOT_MATCH; + return null; + } + + if (chLocal == expectNextChar) { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + return null; + } else { + matchStat = NOT_MATCH; + return null; + } + } + + if (chLocal != '"') { + matchStat = NOT_MATCH; + + return stringDefaultValue(); + } + + boolean hasSpecial = false; + final String strVal; + { + int startIndex = bp + 1; + int endIndex = indexOf('"', startIndex); + if (endIndex == -1) { + throw new JSONException("unclosed str"); + } + + String stringVal = subString(bp + 1, endIndex - startIndex); + for (int i = bp + 1; i < endIndex; ++i) { + if (charAt(i) == '\\') { + hasSpecial = true; + break; + } + } + + if (hasSpecial) { + matchStat = NOT_MATCH; + + return stringDefaultValue(); + } + + offset += (endIndex - (bp + 1) + 1); + chLocal = charAt(bp + (offset++)); + strVal = stringVal; + } + + if (chLocal == expectNextChar) { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + return strVal; + } else { + matchStat = NOT_MATCH; + return strVal; + } + } + + public String scanFieldSymbol(char[] fieldName, final SymbolTable symbolTable) { + matchStat = UNKOWN; + + if (!charArrayCompare(fieldName)) { + matchStat = NOT_MATCH_NAME; + return null; + } + + int offset = fieldName.length; + char chLocal = charAt(bp + (offset++)); + + if (chLocal != '"') { + matchStat = NOT_MATCH; + return null; + } + + String strVal; + // int start = index; + int hash = 0; + for (;;) { + chLocal = charAt(bp + (offset++)); + if (chLocal == '\"') { + // bp = index; + // this.ch = chLocal = charAt(bp); + int start = bp + fieldName.length + 1; + int len = bp + offset - start - 1; + strVal = addSymbol(start, len, hash, symbolTable); + chLocal = charAt(bp + (offset++)); + break; + } + + hash = 31 * hash + chLocal; + + if (chLocal == '\\') { + matchStat = NOT_MATCH; + return null; + } + } + + if (chLocal == ',') { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + return strVal; + } + + if (chLocal == '}') { + chLocal = charAt(bp + (offset++)); + if (chLocal == ',') { + token = JSONToken.COMMA; + bp += (offset - 1); + this.next(); + } else if (chLocal == ']') { + token = JSONToken.RBRACKET; + bp += (offset - 1); + this.next(); + } else if (chLocal == '}') { + token = JSONToken.RBRACE; + bp += (offset - 1); + this.next(); + } else if (chLocal == EOI) { + token = JSONToken.EOF; + bp += (offset - 1); + ch = EOI; + } else { + matchStat = NOT_MATCH; + return null; + } + matchStat = END; + } else { + matchStat = NOT_MATCH; + return null; + } + + return strVal; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public Enum scanEnum(Class enumClass, final SymbolTable symbolTable, char serperator) { + String name = scanSymbolWithSeperator(symbolTable, serperator); + if (name == null) { + return null; + } + return Enum.valueOf((Class) enumClass, name); + } + + public String scanSymbolWithSeperator(final SymbolTable symbolTable, char serperator) { + matchStat = UNKOWN; + + int offset = 0; + char chLocal = charAt(bp + (offset++)); + + if (chLocal == 'n') { + if (charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l') { + offset += 3; + chLocal = charAt(bp + (offset++)); + } else { + matchStat = NOT_MATCH; + return null; + } + + if (chLocal == serperator) { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + return null; + } else { + matchStat = NOT_MATCH; + return null; + } + } + + if (chLocal != '"') { + matchStat = NOT_MATCH; + return null; + } + + String strVal; + // int start = index; + int hash = 0; + for (;;) { + chLocal = charAt(bp + (offset++)); + if (chLocal == '\"') { + // bp = index; + // this.ch = chLocal = charAt(bp); + int start = bp + 0 + 1; + int len = bp + offset - start - 1; + strVal = addSymbol(start, len, hash, symbolTable); + chLocal = charAt(bp + (offset++)); + break; + } + + hash = 31 * hash + chLocal; + + if (chLocal == '\\') { + matchStat = NOT_MATCH; + return null; + } + } + + if (chLocal == serperator) { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + return strVal; + } else { + matchStat = NOT_MATCH; + return strVal; + } + } + + @SuppressWarnings("unchecked") + public Collection scanFieldStringArray(char[] fieldName, Class type) { + matchStat = UNKOWN; + + if (!charArrayCompare(fieldName)) { + matchStat = NOT_MATCH_NAME; + return null; + } + + Collection list; + + if (type.isAssignableFrom(HashSet.class)) { + list = new HashSet(); + } else if (type.isAssignableFrom(ArrayList.class)) { + list = new ArrayList(); + } else { + try { + list = (Collection) type.newInstance(); + } catch (Exception e) { + throw new JSONException(e.getMessage(), e); + } + } + + // int index = bp + fieldName.length; + + int offset = fieldName.length; + char chLocal = charAt(bp + (offset++)); + + if (chLocal != '[') { + matchStat = NOT_MATCH; + return null; + } + + chLocal = charAt(bp + (offset++)); + + for (;;) { + if (chLocal != '"') { + matchStat = NOT_MATCH; + return null; + } + + String strVal; + // int start = index; + int startOffset = offset; + for (;;) { + chLocal = charAt(bp + (offset++)); + if (chLocal == '\"') { + int start = bp + startOffset; + int len = bp + offset - start - 1; + strVal = subString(start, len); + list.add(strVal); + + chLocal = charAt(bp + (offset++)); + break; + } + + if (chLocal == '\\') { + matchStat = NOT_MATCH; + return null; + } + } + + if (chLocal == ',') { + chLocal = charAt(bp + (offset++)); + continue; + } + + if (chLocal == ']') { + chLocal = charAt(bp + (offset++)); + break; + } + + matchStat = NOT_MATCH; + return null; + } + + if (chLocal == ',') { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + return list; + } + + if (chLocal == '}') { + chLocal = charAt(bp + (offset++)); + if (chLocal == ',') { + token = JSONToken.COMMA; + bp += (offset - 1); + this.next(); + } else if (chLocal == ']') { + token = JSONToken.RBRACKET; + bp += (offset - 1); + this.next(); + } else if (chLocal == '}') { + token = JSONToken.RBRACE; + bp += (offset - 1); + this.next(); + } else if (chLocal == EOI) { + bp += (offset - 1); + token = JSONToken.EOF; + this.ch = EOI; + } else { + matchStat = NOT_MATCH; + return null; + } + matchStat = END; + } else { + matchStat = NOT_MATCH; + return null; + } + + return list; + } + + @SuppressWarnings("unchecked") + public Collection scanStringArray(Class type, char seperator) { + matchStat = UNKOWN; + + Collection list; + + if (type.isAssignableFrom(HashSet.class)) { + list = new HashSet(); + } else if (type.isAssignableFrom(ArrayList.class)) { + list = new ArrayList(); + } else { + try { + list = (Collection) type.newInstance(); + } catch (Exception e) { + throw new JSONException(e.getMessage(), e); + } + } + + int offset = 0; + char chLocal = charAt(bp + (offset++)); + + if (chLocal == 'n') { + if (charAt(bp + offset) == 'u' && charAt(bp + offset + 1) == 'l' && charAt(bp + offset + 2) == 'l') { + offset += 3; + chLocal = charAt(bp + (offset++)); + } else { + matchStat = NOT_MATCH; + return null; + } + + if (chLocal == seperator) { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + return null; + } else { + matchStat = NOT_MATCH; + return null; + } + } + + if (chLocal != '[') { + matchStat = NOT_MATCH; + return null; + } + + chLocal = charAt(bp + (offset++)); + + for (;;) { + if (chLocal == 'n' // + && charAt(bp + offset) == 'u' // + && charAt(bp + offset + 1) == 'l' // + && charAt(bp + offset + 2) == 'l') { + offset += 3; + chLocal = charAt(bp + (offset++)); + } else if (chLocal != '"') { + matchStat = NOT_MATCH; + return null; + } else { + + String strVal; + // int start = index; + int startOffset = offset; + for (;;) { + chLocal = charAt(bp + (offset++)); + if (chLocal == '\"') { + int start = bp + startOffset; + int len = bp + offset - start - 1; + strVal = subString(start, len); + list.add(strVal); + + chLocal = charAt(bp + (offset++)); + break; + } + + if (chLocal == '\\') { + matchStat = NOT_MATCH; + return null; + } + } + } + + if (chLocal == ',') { + chLocal = charAt(bp + (offset++)); + continue; + } + + if (chLocal == ']') { + chLocal = charAt(bp + (offset++)); + break; + } + + matchStat = NOT_MATCH; + return null; + } + + if (chLocal == seperator) { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + return list; + } else { + matchStat = NOT_MATCH; + return list; + } + } + + public int scanFieldInt(char[] fieldName) { + matchStat = UNKOWN; + + if (!charArrayCompare(fieldName)) { + matchStat = NOT_MATCH_NAME; + return 0; + } + + int offset = fieldName.length; + char chLocal = charAt(bp + (offset++)); + + int value; + if (chLocal >= '0' && chLocal <= '9') { + value = digits[chLocal]; + for (;;) { + chLocal = charAt(bp + (offset++)); + if (chLocal >= '0' && chLocal <= '9') { + value = value * 10 + digits[chLocal]; + } else if (chLocal == '.') { + matchStat = NOT_MATCH; + return 0; + } else { + break; + } + } + if (value < 0) { + matchStat = NOT_MATCH; + return 0; + } + } else { + matchStat = NOT_MATCH; + return 0; + } + + if (chLocal == ',') { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + token = JSONToken.COMMA; + return value; + } + + if (chLocal == '}') { + chLocal = charAt(bp + (offset++)); + if (chLocal == ',') { + token = JSONToken.COMMA; + bp += (offset - 1); + this.next(); + } else if (chLocal == ']') { + token = JSONToken.RBRACKET; + bp += (offset - 1); + this.next(); + } else if (chLocal == '}') { + token = JSONToken.RBRACE; + bp += (offset - 1); + this.next(); + } else if (chLocal == EOI) { + token = JSONToken.EOF; + bp += (offset - 1); + ch = EOI; + } else { + matchStat = NOT_MATCH; + return 0; + } + matchStat = END; + } else { + matchStat = NOT_MATCH; + return 0; + } + + return value; + } + + public boolean scanBoolean(char expectNext) { + matchStat = UNKOWN; + + int offset = 0; + char chLocal = charAt(bp + (offset++)); + + boolean value = false; + if (chLocal == 't') { + if (charAt(bp + offset) == 'r' // + && charAt(bp + offset + 1) == 'u' // + && charAt(bp + offset + 2) == 'e') { + offset += 3; + chLocal = charAt(bp + (offset++)); + value = true; + } else { + matchStat = NOT_MATCH; + return false; + } + } else if (chLocal == 'f') { + if (charAt(bp + offset) == 'a' // + && charAt(bp + offset + 1) == 'l' // + && charAt(bp + offset + 2) == 's' // + && charAt(bp + offset + 3) == 'e') { + offset += 4; + chLocal = charAt(bp + (offset++)); + value = false; + } else { + matchStat = NOT_MATCH; + return false; + } + } + + if (chLocal == expectNext) { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + return value; + } else { + matchStat = NOT_MATCH; + return value; + } + } + + public int scanInt(char expectNext) { + matchStat = UNKOWN; + + int offset = 0; + char chLocal = charAt(bp + (offset++)); + + int value; + if (chLocal >= '0' && chLocal <= '9') { + value = digits[chLocal]; + for (;;) { + chLocal = charAt(bp + (offset++)); + if (chLocal >= '0' && chLocal <= '9') { + value = value * 10 + digits[chLocal]; + } else if (chLocal == '.') { + matchStat = NOT_MATCH; + return 0; + } else { + break; + } + } + if (value < 0) { + matchStat = NOT_MATCH; + return 0; + } + } else { + matchStat = NOT_MATCH; + return 0; + } + + if (chLocal == expectNext) { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + token = JSONToken.COMMA; + return value; + } else { + matchStat = NOT_MATCH; + return value; + } + } + + public boolean scanFieldBoolean(char[] fieldName) { + matchStat = UNKOWN; + + if (!charArrayCompare(fieldName)) { + matchStat = NOT_MATCH_NAME; + return false; + } + + int offset = fieldName.length; + char chLocal = charAt(bp + (offset++)); + + boolean value; + if (chLocal == 't') { + if (charAt(bp + (offset++)) != 'r') { + matchStat = NOT_MATCH; + return false; + } + if (charAt(bp + (offset++)) != 'u') { + matchStat = NOT_MATCH; + return false; + } + if (charAt(bp + (offset++)) != 'e') { + matchStat = NOT_MATCH; + return false; + } + + value = true; + } else if (chLocal == 'f') { + if (charAt(bp + (offset++)) != 'a') { + matchStat = NOT_MATCH; + return false; + } + if (charAt(bp + (offset++)) != 'l') { + matchStat = NOT_MATCH; + return false; + } + if (charAt(bp + (offset++)) != 's') { + matchStat = NOT_MATCH; + return false; + } + if (charAt(bp + (offset++)) != 'e') { + matchStat = NOT_MATCH; + return false; + } + + value = false; + } else { + matchStat = NOT_MATCH; + return false; + } + + chLocal = charAt(bp + offset++); + if (chLocal == ',') { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + token = JSONToken.COMMA; + + return value; + } + + if (chLocal == '}') { + chLocal = charAt(bp + (offset++)); + if (chLocal == ',') { + token = JSONToken.COMMA; + bp += (offset - 1); + this.next(); + } else if (chLocal == ']') { + token = JSONToken.RBRACKET; + bp += (offset - 1); + this.next(); + } else if (chLocal == '}') { + token = JSONToken.RBRACE; + bp += (offset - 1); + this.next(); + } else if (chLocal == EOI) { + token = JSONToken.EOF; + bp += (offset - 1); + ch = EOI; + } else { + matchStat = NOT_MATCH; + return false; + } + matchStat = END; + } else { + matchStat = NOT_MATCH; + return false; + } + + return value; + } + + public long scanFieldLong(char[] fieldName) { + matchStat = UNKOWN; + + if (!charArrayCompare(fieldName)) { + matchStat = NOT_MATCH_NAME; + return 0; + } + + int offset = fieldName.length; + char chLocal = charAt(bp + (offset++)); + + long value; + if (chLocal >= '0' && chLocal <= '9') { + value = digits[chLocal]; + for (;;) { + chLocal = charAt(bp + (offset++)); + if (chLocal >= '0' && chLocal <= '9') { + value = value * 10 + digits[chLocal]; + } else if (chLocal == '.') { + matchStat = NOT_MATCH; + return 0; + } else { + break; + } + } + if (value < 0) { + matchStat = NOT_MATCH; + return 0; + } + } else { + matchStat = NOT_MATCH; + return 0; + } + + if (chLocal == ',') { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + token = JSONToken.COMMA; + return value; + } + + if (chLocal == '}') { + chLocal = charAt(bp + (offset++)); + if (chLocal == ',') { + token = JSONToken.COMMA; + bp += (offset - 1); + this.next(); + } else if (chLocal == ']') { + token = JSONToken.RBRACKET; + bp += (offset - 1); + this.next(); + } else if (chLocal == '}') { + token = JSONToken.RBRACE; + bp += (offset - 1); + this.next(); + } else if (chLocal == EOI) { + token = JSONToken.EOF; + bp += (offset - 1); + ch = EOI; + } else { + matchStat = NOT_MATCH; + return 0; + } + matchStat = END; + } else { + matchStat = NOT_MATCH; + return 0; + } + + return value; + } + + public long scanLong(char expectNextChar) { + matchStat = UNKOWN; + + int offset = 0; + char chLocal = charAt(bp + (offset++)); + + long value; + if (chLocal >= '0' && chLocal <= '9') { + value = digits[chLocal]; + for (;;) { + chLocal = charAt(bp + (offset++)); + if (chLocal >= '0' && chLocal <= '9') { + value = value * 10 + digits[chLocal]; + } else if (chLocal == '.') { + matchStat = NOT_MATCH; + return 0; + } else { + break; + } + } + if (value < 0) { + matchStat = NOT_MATCH; + return 0; + } + } else { + matchStat = NOT_MATCH; + return 0; + } + + if (chLocal == expectNextChar) { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + token = JSONToken.COMMA; + return value; + } else { + matchStat = NOT_MATCH; + return value; + } + } + + public final float scanFieldFloat(char[] fieldName) { + matchStat = UNKOWN; + + if (!charArrayCompare(fieldName)) { + matchStat = NOT_MATCH_NAME; + return 0; + } + + int offset = fieldName.length; + char chLocal = charAt(bp + (offset++)); + + float value; + if (chLocal >= '0' && chLocal <= '9') { + for (;;) { + chLocal = charAt(bp + (offset++)); + if (chLocal >= '0' && chLocal <= '9') { + continue; + } else { + break; + } + } + + if (chLocal == '.') { + chLocal = charAt(bp + (offset++)); + if (chLocal >= '0' && chLocal <= '9') { + for (;;) { + chLocal = charAt(bp + (offset++)); + if (chLocal >= '0' && chLocal <= '9') { + continue; + } else { + break; + } + } + } else { + matchStat = NOT_MATCH; + return 0; + } + } + + int start = bp + fieldName.length; + int count = bp + offset - start - 1; + String text = this.subString(start, count); + value = Float.parseFloat(text); + } else { + matchStat = NOT_MATCH; + return 0; + } + + if (chLocal == ',') { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + token = JSONToken.COMMA; + return value; + } + + if (chLocal == '}') { + chLocal = charAt(bp + (offset++)); + if (chLocal == ',') { + token = JSONToken.COMMA; + bp += (offset - 1); + this.next(); + } else if (chLocal == ']') { + token = JSONToken.RBRACKET; + bp += (offset - 1); + this.next(); + } else if (chLocal == '}') { + token = JSONToken.RBRACE; + bp += (offset - 1); + this.next(); + } else if (chLocal == EOI) { + bp += (offset - 1); + token = JSONToken.EOF; + ch = EOI; + } else { + matchStat = NOT_MATCH; + return 0; + } + matchStat = END; + } else { + matchStat = NOT_MATCH; + return 0; + } + + return value; + } + + public final float scanFloat(char seperator) { + matchStat = UNKOWN; + + int offset = 0; + char chLocal = charAt(bp + (offset++)); + + float value; + if (chLocal >= '0' && chLocal <= '9') { + for (;;) { + chLocal = charAt(bp + (offset++)); + if (chLocal >= '0' && chLocal <= '9') { + continue; + } else { + break; + } + } + + if (chLocal == '.') { + chLocal = charAt(bp + (offset++)); + if (chLocal >= '0' && chLocal <= '9') { + for (;;) { + chLocal = charAt(bp + (offset++)); + if (chLocal >= '0' && chLocal <= '9') { + continue; + } else { + break; + } + } + } else { + matchStat = NOT_MATCH; + return 0; + } + } + + int start = bp; + int count = bp + offset - start - 1; + String text = this.subString(start, count); + value = Float.parseFloat(text); + } else { + matchStat = NOT_MATCH; + return 0; + } + + if (chLocal == seperator) { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + token = JSONToken.COMMA; + return value; + } else { + matchStat = NOT_MATCH; + return value; + } + } + + public final double scanFieldDouble(char[] fieldName) { + matchStat = UNKOWN; + + if (!charArrayCompare(fieldName)) { + matchStat = NOT_MATCH_NAME; + return 0; + } + + int offset = fieldName.length; + char chLocal = charAt(bp + (offset++)); + + double value; + if (chLocal >= '0' && chLocal <= '9') { + for (;;) { + chLocal = charAt(bp + (offset++)); + if (chLocal >= '0' && chLocal <= '9') { + continue; + } else { + break; + } + } + + if (chLocal == '.') { + chLocal = charAt(bp + (offset++)); + if (chLocal >= '0' && chLocal <= '9') { + for (;;) { + chLocal = charAt(bp + (offset++)); + if (chLocal >= '0' && chLocal <= '9') { + continue; + } else { + break; + } + } + } else { + matchStat = NOT_MATCH; + return 0; + } + } + + if (chLocal == 'e' || chLocal == 'E') { + chLocal = charAt(bp + (offset++)); + if (chLocal == '+' || chLocal == '-') { + chLocal = charAt(bp + (offset++)); + } + for (;;) { + if (chLocal >= '0' && chLocal <= '9') { + chLocal = charAt(bp + (offset++)); + } else { + break; + } + } + } + + int start = bp + fieldName.length; + int count = bp + offset - start - 1; + String text = this.subString(start, count); + value = Double.parseDouble(text); + } else { + matchStat = NOT_MATCH; + return 0; + } + + if (chLocal == ',') { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + token = JSONToken.COMMA; + return value; + } + + if (chLocal == '}') { + chLocal = charAt(bp + (offset++)); + if (chLocal == ',') { + token = JSONToken.COMMA; + bp += (offset - 1); + this.next(); + } else if (chLocal == ']') { + token = JSONToken.RBRACKET; + bp += (offset - 1); + this.next(); + } else if (chLocal == '}') { + token = JSONToken.RBRACE; + bp += (offset - 1); + this.next(); + } else if (chLocal == EOI) { + token = JSONToken.EOF; + bp += (offset - 1); + ch = EOI; + } else { + matchStat = NOT_MATCH; + return 0; + } + matchStat = END; + } else { + matchStat = NOT_MATCH; + return 0; + } + + return value; + } + + public final double scanFieldDouble(char seperator) { + matchStat = UNKOWN; + + int offset = 0; + char chLocal = charAt(bp + (offset++)); + + double value; + if (chLocal >= '0' && chLocal <= '9') { + for (;;) { + chLocal = charAt(bp + (offset++)); + if (chLocal >= '0' && chLocal <= '9') { + continue; + } else { + break; + } + } + + if (chLocal == '.') { + chLocal = charAt(bp + (offset++)); + if (chLocal >= '0' && chLocal <= '9') { + for (;;) { + chLocal = charAt(bp + (offset++)); + if (chLocal >= '0' && chLocal <= '9') { + continue; + } else { + break; + } + } + } else { + matchStat = NOT_MATCH; + return 0; + } + } + + if (chLocal == 'e' || chLocal == 'E') { + chLocal = charAt(bp + (offset++)); + if (chLocal == '+' || chLocal == '-') { + chLocal = charAt(bp + (offset++)); + } + for (;;) { + if (chLocal >= '0' && chLocal <= '9') { + chLocal = charAt(bp + (offset++)); + } else { + break; + } + } + } + + int start = bp; + int count = bp + offset - start - 1; + String text = this.subString(start, count); + value = Double.parseDouble(text); + } else { + matchStat = NOT_MATCH; + return 0; + } + + if (chLocal == seperator) { + bp += (offset - 1); + this.next(); + matchStat = VALUE; + token = JSONToken.COMMA; + return value; + } else { + matchStat = NOT_MATCH; + return value; + } + } + + public final void scanTrue() { + if (ch != 't') { + throw new JSONException("error parse true"); + } + next(); + + if (ch != 'r') { + throw new JSONException("error parse true"); + } + next(); + + if (ch != 'u') { + throw new JSONException("error parse true"); + } + next(); + + if (ch != 'e') { + throw new JSONException("error parse true"); + } + next(); + + if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI + || ch == '\f' || ch == '\b' || ch == ':') { + token = JSONToken.TRUE; + } else { + throw new JSONException("scan true error"); + } + } + + public final void scanTreeSet() { + if (ch != 'T') { + throw new JSONException("error parse true"); + } + next(); + + if (ch != 'r') { + throw new JSONException("error parse true"); + } + next(); + + if (ch != 'e') { + throw new JSONException("error parse true"); + } + next(); + + if (ch != 'e') { + throw new JSONException("error parse true"); + } + next(); + + if (ch != 'S') { + throw new JSONException("error parse true"); + } + next(); + + if (ch != 'e') { + throw new JSONException("error parse true"); + } + next(); + + if (ch != 't') { + throw new JSONException("error parse true"); + } + next(); + + if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b' || ch == '[' || ch == '(') { + token = JSONToken.TREE_SET; + } else { + throw new JSONException("scan set error"); + } + } + + public final void scanNullOrNew() { + if (ch != 'n') { + throw new JSONException("error parse null or new"); + } + next(); + + if (ch == 'u') { + next(); + if (ch != 'l') { + throw new JSONException("error parse l"); + } + next(); + + if (ch != 'l') { + throw new JSONException("error parse l"); + } + next(); + + if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI + || ch == '\f' || ch == '\b') { + token = JSONToken.NULL; + } else { + throw new JSONException("scan true error"); + } + return; + } + + if (ch != 'e') { + throw new JSONException("error parse e"); + } + next(); + + if (ch != 'w') { + throw new JSONException("error parse w"); + } + next(); + + if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI + || ch == '\f' || ch == '\b') { + token = JSONToken.NEW; + } else { + throw new JSONException("scan true error"); + } + } + + public final void scanNULL() { + if (ch != 'N') { + throw new JSONException("error parse NULL"); + } + next(); + + if (ch == 'U') { + next(); + if (ch != 'L') { + throw new JSONException("error parse U"); + } + next(); + + if (ch != 'L') { + throw new JSONException("error parse NULL"); + } + next(); + + if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI + || ch == '\f' || ch == '\b') { + token = JSONToken.NULL; + } else { + throw new JSONException("scan NULL error"); + } + return; + } + } + + public final void scanUndefined() { + if (ch != 'u') { + throw new JSONException("error parse false"); + } + next(); + + if (ch != 'n') { + throw new JSONException("error parse false"); + } + next(); + + if (ch != 'd') { + throw new JSONException("error parse false"); + } + next(); + + if (ch != 'e') { + throw new JSONException("error parse false"); + } + next(); + + if (ch != 'f') { + throw new JSONException("error parse false"); + } + next(); + + if (ch != 'i') { + throw new JSONException("error parse false"); + } + next(); + + if (ch != 'n') { + throw new JSONException("error parse false"); + } + next(); + + if (ch != 'e') { + throw new JSONException("error parse false"); + } + next(); + if (ch != 'd') { + throw new JSONException("error parse false"); + } + next(); + + if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI + || ch == '\f' || ch == '\b') { + token = JSONToken.UNDEFINED; + } else { + throw new JSONException("scan false error"); + } + } + + public final void scanFalse() { + if (ch != 'f') { + throw new JSONException("error parse false"); + } + next(); + + if (ch != 'a') { + throw new JSONException("error parse false"); + } + next(); + + if (ch != 'l') { + throw new JSONException("error parse false"); + } + next(); + + if (ch != 's') { + throw new JSONException("error parse false"); + } + next(); + + if (ch != 'e') { + throw new JSONException("error parse false"); + } + next(); + + if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI + || ch == '\f' || ch == '\b' || ch == ':') { + token = JSONToken.FALSE; + } else { + throw new JSONException("scan false error"); + } + } + + public final void scanIdent() { + np = bp - 1; + hasSpecial = false; + + for (;;) { + sp++; + + next(); + if (Character.isLetterOrDigit(ch)) { + continue; + } + + String ident = stringVal(); + + Integer tok = keywods.get(ident); + if (tok != null) { + token = tok; + } else { + token = JSONToken.IDENTIFIER; + } + return; + } + } + + public abstract String stringVal(); + + public abstract String subString(int offset, int count); + + protected abstract boolean charArrayCompare(char[] chars); + + public final boolean isBlankInput() { + for (int i = 0;; ++i) { + char chLocal = charAt(i); + if (chLocal == EOI) { + break; + } + + if (!isWhitespace(chLocal)) { + return false; + } + } + + return true; + } + + public final void skipWhitespace() { + for (;;) { + if (ch < IOUtils.whitespaceFlags.length && IOUtils.whitespaceFlags[ch]) { + next(); + continue; + } else { + break; + } + } + } + + private final void scanStringSingleQuote() { + np = bp; + hasSpecial = false; + char chLocal; + for (;;) { + chLocal = next(); + + if (chLocal == '\'') { + break; + } + + if (chLocal == EOI) { + throw new JSONException("unclosed single-quote string"); + } + + if (chLocal == '\\') { + if (!hasSpecial) { + hasSpecial = true; + + if (sp > sbuf.length) { + char[] newsbuf = new char[sp * 2]; + System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length); + sbuf = newsbuf; + } + + // text.getChars(offset, offset + count, dest, 0); + this.copyTo(np + 1, sp, sbuf); + // System.arraycopy(buf, np + 1, sbuf, 0, sp); + } + + chLocal = next(); + + switch (chLocal) { + case '0': + putChar('\0'); + break; + case '1': + putChar('\1'); + break; + case '2': + putChar('\2'); + break; + case '3': + putChar('\3'); + break; + case '4': + putChar('\4'); + break; + case '5': + putChar('\5'); + break; + case '6': + putChar('\6'); + break; + case '7': + putChar('\7'); + break; + case 'b': // 8 + putChar('\b'); + break; + case 't': // 9 + putChar('\t'); + break; + case 'n': // 10 + putChar('\n'); + break; + case 'v': // 11 + putChar('\u000B'); + break; + case 'f': // 12 + case 'F': + putChar('\f'); + break; + case 'r': // 13 + putChar('\r'); + break; + case '"': // 34 + putChar('"'); + break; + case '\'': // 39 + putChar('\''); + break; + case '/': // 47 + putChar('/'); + break; + case '\\': // 92 + putChar('\\'); + break; + case 'x': + char x1 = chLocal = next(); + char x2 = chLocal = next(); + + int x_val = digits[x1] * 16 + digits[x2]; + char x_char = (char) x_val; + putChar(x_char); + break; + case 'u': + char c1 = chLocal = next(); + char c2 = chLocal = next(); + char c3 = chLocal = next(); + char c4 = chLocal = next(); + int val = Integer.parseInt(new String(new char[] { c1, c2, c3, c4 }), 16); + putChar((char) val); + break; + default: + this.ch = chLocal; + throw new JSONException("unclosed single-quote string"); + } + continue; + } + + if (!hasSpecial) { + sp++; + continue; + } + + if (sp == sbuf.length) { + putChar(chLocal); + } else { + sbuf[sp++] = chLocal; + } + } + + token = LITERAL_STRING; + this.next(); + } + + public final void scanSet() { + if (ch != 'S') { + throw new JSONException("error parse true"); + } + next(); + + if (ch != 'e') { + throw new JSONException("error parse true"); + } + next(); + + if (ch != 't') { + throw new JSONException("error parse true"); + } + next(); + + if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b' || ch == '[' || ch == '(') { + token = JSONToken.SET; + } else { + throw new JSONException("scan set error"); + } + } + + /** + * Append a character to sbuf. + */ + protected final void putChar(char ch) { + if (sp == sbuf.length) { + char[] newsbuf = new char[sbuf.length * 2]; + System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length); + sbuf = newsbuf; + } + sbuf[sp++] = ch; + } + + public final void scanNumber() { + np = bp; + + if (ch == '-') { + sp++; + next(); + } + + for (;;) { + if (ch >= '0' && ch <= '9') { + sp++; + } else { + break; + } + next(); + } + + boolean isDouble = false; + + if (ch == '.') { + sp++; + next(); + isDouble = true; + + for (;;) { + if (ch >= '0' && ch <= '9') { + sp++; + } else { + break; + } + next(); + } + } + + if (ch == 'L') { + sp++; + next(); + } else if (ch == 'S') { + sp++; + next(); + } else if (ch == 'B') { + sp++; + next(); + } else if (ch == 'F') { + sp++; + next(); + isDouble = true; + } else if (ch == 'D') { + sp++; + next(); + isDouble = true; + } else if (ch == 'e' || ch == 'E') { + sp++; + next(); + + if (ch == '+' || ch == '-') { + sp++; + next(); + } + + for (;;) { + if (ch >= '0' && ch <= '9') { + sp++; + } else { + break; + } + next(); + } + + if (ch == 'D' || ch == 'F') { + sp++; + next(); + } + + isDouble = true; + } + + if (isDouble) { + token = JSONToken.LITERAL_FLOAT; + } else { + token = JSONToken.LITERAL_INT; + } + } + + public final long longValue() throws NumberFormatException { + long result = 0; + boolean negative = false; + int i = np, max = np + sp; + long limit; + long multmin; + int digit; + + if (charAt(np) == '-') { + negative = true; + limit = Long.MIN_VALUE; + i++; + } else { + limit = -Long.MAX_VALUE; + } + multmin = negative ? MULTMIN_RADIX_TEN : N_MULTMAX_RADIX_TEN; + if (i < max) { + digit = digits[charAt(i++)]; + result = -digit; + } + while (i < max) { + // Accumulating negatively avoids surprises near MAX_VALUE + char chLocal = charAt(i++); + + if (chLocal == 'L' || chLocal == 'S' || chLocal == 'B') { + break; + } + + digit = digits[chLocal]; + if (result < multmin) { + throw new NumberFormatException(numberString()); + } + result *= 10; + if (result < limit + digit) { + throw new NumberFormatException(numberString()); + } + result -= digit; + } + + if (negative) { + if (i > np + 1) { + return result; + } else { /* Only got "-" */ + throw new NumberFormatException(numberString()); + } + } else { + return -result; + } + } + + public final Number decimalValue(boolean decimal) { + char chLocal = charAt(np + sp - 1); + if (chLocal == 'F') { + return Float.parseFloat(numberString()); + // return Float.parseFloat(new String(buf, np, sp - 1)); + } + + if (chLocal == 'D') { + return Double.parseDouble(numberString()); + // return Double.parseDouble(new String(buf, np, sp - 1)); + } + + if (decimal) { + return decimalValue(); + } else { + return doubleValue(); + } + } + + public final BigDecimal decimalValue() { + return new BigDecimal(numberString()); + } + + public static final boolean isWhitespace(char ch) { + // 专门调整了判断顺序 + return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b'; + } + + protected static final long MULTMIN_RADIX_TEN = Long.MIN_VALUE / 10; + protected static final long N_MULTMAX_RADIX_TEN = -Long.MAX_VALUE / 10; + + protected static final int INT_MULTMIN_RADIX_TEN = Integer.MIN_VALUE / 10; + protected static final int INT_N_MULTMAX_RADIX_TEN = -Integer.MAX_VALUE / 10; + + protected final static int[] digits = new int[(int) 'f' + 1]; + + static { + for (int i = '0'; i <= '9'; ++i) { + digits[i] = i - '0'; + } + + for (int i = 'a'; i <= 'f'; ++i) { + digits[i] = (i - 'a') + 10; + } + for (int i = 'A'; i <= 'F'; ++i) { + digits[i] = (i - 'A') + 10; + } + } +} diff --git a/src/main/java/com/alibaba/fastjson/parser/JSONReaderScanner.java b/src/main/java/com/alibaba/fastjson/parser/JSONReaderScanner.java new file mode 100644 index 0000000000..7ceea21497 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/parser/JSONReaderScanner.java @@ -0,0 +1,272 @@ +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.parser; + +import java.io.CharArrayReader; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.lang.ref.SoftReference; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.util.Base64; +import com.alibaba.fastjson.util.IOUtils; + +//这个类,为了性能优化做了很多特别处理,一切都是为了性能!!! + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public final class JSONReaderScanner extends JSONLexerBase { + + public static int BUF_INIT_LEN = 8192; + + private final static ThreadLocal> BUF_REF_LOCAL = new ThreadLocal>(); + + private Reader reader; + private char[] buf; + private int bufLength; + + public JSONReaderScanner(String input){ + this(input, JSON.DEFAULT_PARSER_FEATURE); + } + + public JSONReaderScanner(String input, int features){ + this(new StringReader(input), features); + } + + public JSONReaderScanner(char[] input, int inputLength){ + this(input, inputLength, JSON.DEFAULT_PARSER_FEATURE); + } + + public JSONReaderScanner(Reader reader){ + this(reader, JSON.DEFAULT_PARSER_FEATURE); + } + + public JSONReaderScanner(Reader reader, int features){ + this.reader = reader; + this.features = features; + + SoftReference bufRef = BUF_REF_LOCAL.get(); + if (bufRef != null) { + this.buf = bufRef.get(); + BUF_REF_LOCAL.set(null); + } + + if (this.buf == null) { + this.buf = new char[BUF_INIT_LEN]; + } + + try { + bufLength = reader.read(buf); + } catch (IOException e) { + throw new JSONException(e.getMessage(), e); + } + + bp = -1; + + next(); + if (ch == 65279) { + next(); + } + } + + public JSONReaderScanner(char[] input, int inputLength, int features){ + this(new CharArrayReader(input, 0, inputLength), features); + } + + public final char charAt(int index) { + if (index >= bufLength) { + if (bufLength == -1) { + if (index < sp) { + return buf[index]; + } + return EOI; + } + + int rest = bufLength - bp; + if (rest > 0) { + System.arraycopy(buf, bp, buf, 0, rest); + } + + try { + bufLength = reader.read(buf, rest, buf.length - rest); + } catch (IOException e) { + throw new JSONException(e.getMessage(), e); + } + + if (bufLength == 0) { + throw new JSONException("illegal stat, textLength is zero"); + } + + if (bufLength == -1) { + return EOI; + } + + bufLength += rest; + index -= bp; + np -= bp; + bp = 0; + } + + return buf[index]; + } + + public final int indexOf(char ch, int startIndex) { + int offset = startIndex - bp; + for (;; ++offset) { + final int index = bp + offset; + if (ch == charAt(index)) { + return offset + bp; + } + if (ch == EOI) { + return -1; + } + } + } + + public final String addSymbol(int offset, int len, int hash, final SymbolTable symbolTable) { + return symbolTable.addSymbol(buf, offset, len, hash); + } + + public final char next() { + int index = ++bp; + + if (index >= bufLength) { + if (bufLength == -1) { + return EOI; + } + + if (sp > 0) { + int offset; + offset = bufLength - sp; + if (ch == '"') { + offset--; + } + System.arraycopy(buf, offset, buf, 0, sp); + } + np = -1; + + index = bp = sp; + + try { + int startPos = bp; + int readLength = buf.length - startPos; + if (readLength == 0) { + char[] newBuf = new char[buf.length * 2]; + System.arraycopy(buf, 0, newBuf, 0, buf.length); + buf = newBuf; + readLength = buf.length - startPos; + } + bufLength = reader.read(buf, bp, readLength); + } catch (IOException e) { + throw new JSONException(e.getMessage(), e); + } + + if (bufLength == 0) { + throw new JSONException("illegal stat, textLength is zero"); + } + + if (bufLength == -1) { + return ch = EOI; + } + + bufLength += bp; + } + + return ch = buf[index]; + } + + protected final void copyTo(int offset, int count, char[] dest) { + System.arraycopy(buf, offset, dest, 0, count); + } + + public final boolean charArrayCompare(char[] chars) { + for (int i = 0; i < chars.length; ++i) { + if (charAt(bp + i) != chars[i]) { + return false; + } + } + + return true; + } + + public byte[] bytesValue() { + return Base64.decodeFast(buf, np + 1, sp); + } + + protected final void arrayCopy(int srcPos, char[] dest, int destPos, int length) { + System.arraycopy(buf, srcPos, dest, destPos, length); + } + + /** + * The value of a literal token, recorded as a string. For integers, leading 0x and 'l' suffixes are suppressed. + */ + public final String stringVal() { + if (!hasSpecial) { + int offset = np + 1; + if (offset < 0) { + throw new IllegalStateException(); + } + if (offset > buf.length - sp) { + throw new IllegalStateException(); + } + return new String(buf, offset, sp); + // return text.substring(np + 1, np + 1 + sp); + } else { + return new String(sbuf, 0, sp); + } + } + + public final String subString(int offset, int count) { + if (count < 0) { + throw new StringIndexOutOfBoundsException(count); + } + return new String(buf, offset, count); + // return text.substring(offset, offset + count); + } + + public final String numberString() { + int offset = np; + if (offset == -1) { + offset = 0; + } + char chLocal = charAt(offset + sp - 1); + + int sp = this.sp; + if (chLocal == 'L' || chLocal == 'S' || chLocal == 'B' || chLocal == 'F' || chLocal == 'D') { + sp--; + } + + String value = new String(buf, offset, sp); + return value; + } + + public void close() { + super.close(); + + BUF_REF_LOCAL.set(new SoftReference(buf)); + this.buf = null; + + IOUtils.close(reader); + } + + @Override + public boolean isEOF() { + return bufLength == -1 || bp == buf.length || ch == EOI && bp + 1 == buf.length; + } +} diff --git a/src/main/java/com/alibaba/fastjson/parser/JSONScanner.java b/src/main/java/com/alibaba/fastjson/parser/JSONScanner.java old mode 100644 new mode 100755 index e1eba1fe3a..4651920ad0 --- a/src/main/java/com/alibaba/fastjson/parser/JSONScanner.java +++ b/src/main/java/com/alibaba/fastjson/parser/JSONScanner.java @@ -15,80 +15,55 @@ */ package com.alibaba.fastjson.parser; -import static com.alibaba.fastjson.parser.JSONToken.COLON; -import static com.alibaba.fastjson.parser.JSONToken.COMMA; -import static com.alibaba.fastjson.parser.JSONToken.EOF; -import static com.alibaba.fastjson.parser.JSONToken.ERROR; -import static com.alibaba.fastjson.parser.JSONToken.LBRACE; -import static com.alibaba.fastjson.parser.JSONToken.LBRACKET; -import static com.alibaba.fastjson.parser.JSONToken.LITERAL_STRING; -import static com.alibaba.fastjson.parser.JSONToken.LPAREN; -import static com.alibaba.fastjson.parser.JSONToken.RBRACE; -import static com.alibaba.fastjson.parser.JSONToken.RBRACKET; -import static com.alibaba.fastjson.parser.JSONToken.RPAREN; - -import java.math.BigDecimal; -import java.math.BigInteger; import java.util.ArrayList; import java.util.Calendar; +import java.util.Collection; +import java.util.HashSet; +import java.util.Locale; +import java.util.TimeZone; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.util.ASMUtils; +import com.alibaba.fastjson.util.Base64; //这个类,为了性能优化做了很多特别处理,一切都是为了性能!!! /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ -public class JSONScanner implements JSONLexer { +public final class JSONScanner extends JSONLexerBase { - public final static byte EOI = 0x1A; - - private final char[] buf; - private int bp; - private final int buflen; - private int eofPos; - - /** - * The current character. - */ - private char ch; - - /** - * The token's position, 0-based offset from beginning of text. - */ - private int pos; - - /** - * A character buffer for literals. - */ - private char[] sbuf; - private int sp; - - /** - * number start position - */ - private int np; + private final String text; + + private boolean isAndroid = ASMUtils.isAndroid(); - /** - * The token, set by nextToken(). - */ - private int token; + public JSONScanner(String input){ + this(input, JSON.DEFAULT_PARSER_FEATURE); + } - private Keywords keywods = Keywords.DEFAULT_KEYWORDS; + public JSONScanner(String input, int features){ + this.features = features; - private final static ThreadLocal sbufRef = new ThreadLocal(); + text = input; + bp = -1; - private int features = JSON.DEFAULT_PARSER_FEATURE; + next(); + if (ch == 65279) { + next(); + } + } - private Calendar calendar = null; + public final char charAt(int index) { + if (index >= text.length()) { + return EOI; + } - public JSONScanner(String input){ - this(input, JSON.DEFAULT_PARSER_FEATURE); + return text.charAt(index); } - public JSONScanner(String input, int features){ - this(input.toCharArray(), input.length(), features); + public final char next() { + return ch = charAt(++bp); } public JSONScanner(char[] input, int inputLength){ @@ -96,46 +71,73 @@ public JSONScanner(char[] input, int inputLength){ } public JSONScanner(char[] input, int inputLength, int features){ - this.features = features; + this(new String(input, 0, inputLength), features); + } + + protected final void copyTo(int offset, int count, char[] dest) { + text.getChars(offset, offset + count, dest, 0); + } - sbuf = sbufRef.get(); // new char[1024]; - if (sbuf == null) { - sbuf = new char[64]; - sbufRef.set(sbuf); + protected final static char[] typeFieldName = ("\"" + JSON.DEFAULT_TYPE_KEY + "\":\"").toCharArray(); + + public final int scanType(String type) { + matchStat = UNKOWN; + + if (!charArrayCompare(text, bp, typeFieldName)) { + return NOT_MATCH_NAME; } - eofPos = inputLength; + int bpLocal = this.bp + typeFieldName.length; - if (inputLength == input.length) { - if (input.length > 0 && isWhitespace(input[input.length - 1])) { - inputLength--; - } else { - char[] newInput = new char[inputLength + 1]; - System.arraycopy(input, 0, newInput, 0, input.length); - input = newInput; + final int typeLength = type.length(); + for (int i = 0; i < typeLength; ++i) { + if (type.charAt(i) != charAt(bpLocal + i)) { + return NOT_MATCH; } } - buf = input; - buflen = inputLength; - buf[buflen] = EOI; - bp = -1; + bpLocal += typeLength; + if (charAt(bpLocal) != '"') { + return NOT_MATCH; + } - ch = buf[++bp]; - } + this.ch = charAt(++bpLocal); - public final int getBufferPosition() { - return bp; - } + if (ch == ',') { + this.ch = charAt(++bpLocal); + this.bp = bpLocal; + token = JSONToken.COMMA; + return VALUE; + } else if (ch == '}') { + ch = charAt(++bpLocal); + if (ch == ',') { + token = JSONToken.COMMA; + this.ch = charAt(++bpLocal); + } else if (ch == ']') { + token = JSONToken.RBRACKET; + this.ch = charAt(++bpLocal); + } else if (ch == '}') { + token = JSONToken.RBRACE; + this.ch = charAt(++bpLocal); + } else if (ch == EOI) { + token = JSONToken.EOF; + } else { + return NOT_MATCH; + } + matchStat = END; + } - public void reset(int mark, char mark_ch, int token) { - this.bp = mark; - this.ch = mark_ch; - this.token = token; + this.bp = bpLocal; + return matchStat; } - public boolean isBlankInput() { - for (int i = 0; i < buflen; ++i) { - if (!isWhitespace(buf[i])) { + static final boolean charArrayCompare(String src, int offset, char[] dest) { + final int destLen = dest.length; + if (destLen + offset > src.length()) { + return false; + } + + for (int i = 0; i < destLen; ++i) { + if (dest[i] != src.charAt(offset + i)) { return false; } } @@ -143,727 +145,661 @@ public boolean isBlankInput() { return true; } - public static final boolean isWhitespace(char ch) { - // 专门调整了判断顺序 - return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b'; + public final boolean charArrayCompare(char[] chars) { + return charArrayCompare(text, bp, chars); } - /** - * Report an error at the current token position using the provided arguments. - */ - private void lexError(String key, Object... args) { - token = ERROR; + public final int indexOf(char ch, int startIndex) { + return text.indexOf(ch, startIndex); } - /** - * Return the current token, set by nextToken(). - */ - public final int token() { - return token; + public final String addSymbol(int offset, int len, int hash, final SymbolTable symbolTable) { + return symbolTable.addSymbol(text, offset, len, hash); } - private static boolean[] whitespaceFlags = new boolean[256]; - static { - whitespaceFlags[' '] = true; - whitespaceFlags['\n'] = true; - whitespaceFlags['\r'] = true; - whitespaceFlags['\t'] = true; - whitespaceFlags['\f'] = true; - whitespaceFlags['\b'] = true; + public byte[] bytesValue() { + return Base64.decodeFast(text, np + 1, sp); } - public final void skipWhitespace() { - for (;;) { - if (whitespaceFlags[ch]) { - ch = buf[++bp]; - continue; - } else { - break; - } - } - } + // public int scanField2(char[] fieldName, Object object, FieldDeserializer fieldDeserializer) { + // return NOT_MATCH; + // } - public final char getCurrent() { - return ch; + /** + * The value of a literal token, recorded as a string. For integers, leading 0x and 'l' suffixes are suppressed. + */ + public final String stringVal() { + if (!hasSpecial) { + // return text.substring(np + 1, np + 1 + sp); + return this.subString(np + 1, sp); + } else { + return new String(sbuf, 0, sp); + } } - public final void nextTokenWithColon() { - for (;;) { - if (ch == ':') { - ch = buf[++bp]; - nextToken(); - return; - } - - if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b') { - ch = buf[++bp]; - continue; + public final String subString(int offset, int count) { + if (isAndroid) { + char[] chars = new char[count]; + for (int i = offset; i < offset + count; ++i) { + chars[i - offset] = text.charAt(i); } - - throw new JSONException("not match ':'"); + return new String(chars); + } else { + return text.substring(offset, offset + count); } } + + public final String numberString() { + char chLocal = charAt(np + sp - 1); - public final void nextTokenWithColon(int expect) { - for (;;) { - if (ch == ':') { - ch = buf[++bp]; - break; - } - - if (isWhitespace(ch)) { - ch = buf[++bp]; - continue; - } - - throw new JSONException("not match ':'"); + int sp = this.sp; + if (chLocal == 'L' || chLocal == 'S' || chLocal == 'B' || chLocal == 'F' || chLocal == 'D') { + sp--; } - for (;;) { - if (expect == JSONToken.LITERAL_INT) { - if (ch >= '0' && ch <= '9') { - sp = 0; - pos = bp; - scanNumber(); - return; - } + // return text.substring(np, np + sp); + return this.subString(np, sp); + } - if (ch == '"') { - sp = 0; - pos = bp; - scanString(); - return; - } - } else if (expect == JSONToken.LITERAL_STRING) { - if (ch == '"') { - sp = 0; - pos = bp; - scanString(); - return; - } + public final int ISO8601_LEN_0 = "0000-00-00".length(); + public final int ISO8601_LEN_1 = "0000-00-00T00:00:00".length(); + public final int ISO8601_LEN_2 = "0000-00-00T00:00:00.000".length(); - if (ch >= '0' && ch <= '9') { - sp = 0; - pos = bp; - scanNumber(); - return; - } + public boolean scanISO8601DateIfMatch() { + return scanISO8601DateIfMatch(true); + } - } else if (expect == JSONToken.LBRACE) { - if (ch == '{') { - token = JSONToken.LBRACE; - ch = buf[++bp]; - return; - } - if (ch == '[') { - token = JSONToken.LBRACKET; - ch = buf[++bp]; - return; + public boolean scanISO8601DateIfMatch(boolean strict) { + int rest = text.length() - bp; + + if ((!strict) && rest > 13) { + char c0 = charAt(bp); + char c1 = charAt(bp + 1); + char c2 = charAt(bp + 2); + char c3 = charAt(bp + 3); + char c4 = charAt(bp + 4); + char c5 = charAt(bp + 5); + + char c_r0 = charAt(bp + rest - 1); + char c_r1 = charAt(bp + rest - 2); + if (c0 == '/' && c1 == 'D' && c2 == 'a' && c3 == 't' && c4 == 'e' && c5 == '(' && c_r0 == '/' + && c_r1 == ')') { + int plusIndex = -1; + for (int i = 6; i < rest; ++i) { + char c = charAt(bp + i); + if (c == '+') { + plusIndex = i; + } else if (c < '0' || c > '9') { + break; + } } - } else if (expect == JSONToken.LBRACKET) { - if (ch == '[') { - token = JSONToken.LBRACKET; - ch = buf[++bp]; - return; + if (plusIndex == -1) { + return false; } + int offset = bp + 6; + String numberText = this.subString(offset, plusIndex - offset); + long millis = Long.parseLong(numberText); - if (ch == '{') { - token = JSONToken.LBRACE; - ch = buf[++bp]; - return; - } - } + Locale local = Locale.getDefault(); + calendar = Calendar.getInstance(TimeZone.getDefault(), local); + calendar.setTimeInMillis(millis); - if (isWhitespace(ch)) { - ch = buf[++bp]; - continue; + token = JSONToken.LITERAL_ISO8601_DATE; + return true; } - - nextToken(); - break; } - } - - public final void incrementBufferPosition() { - ch = buf[++bp]; - } - - public final void resetStringPosition() { - this.sp = 0; - } - - public void nextToken(int expect) { - for (;;) { - switch (expect) { - case JSONToken.LBRACE: - if (ch == '{') { - token = JSONToken.LBRACE; - ch = buf[++bp]; - return; - } - if (ch == '[') { - token = JSONToken.LBRACKET; - ch = buf[++bp]; - return; - } - break; - case JSONToken.COMMA: - if (ch == ',') { - token = JSONToken.COMMA; - ch = buf[++bp]; - return; - } - if (ch == '}') { - token = JSONToken.RBRACE; - ch = buf[++bp]; - return; - } + if (rest == 8 || rest == 14 || rest == 17) { + if (strict) { + return false; + } - if (ch == ']') { - token = JSONToken.RBRACKET; - ch = buf[++bp]; - return; - } + char y0 = charAt(bp); + char y1 = charAt(bp + 1); + char y2 = charAt(bp + 2); + char y3 = charAt(bp + 3); + char M0 = charAt(bp + 4); + char M1 = charAt(bp + 5); + char d0 = charAt(bp + 6); + char d1 = charAt(bp + 7); - if (ch == EOI) { - token = JSONToken.EOF; - return; - } - break; - case JSONToken.LITERAL_INT: - if (ch >= '0' && ch <= '9') { - sp = 0; - pos = bp; - scanNumber(); - return; - } + if (!checkDate(y0, y1, y2, y3, M0, M1, d0, d1)) { + return false; + } - if (ch == '"') { - sp = 0; - pos = bp; - scanString(); - return; - } + setCalendar(y0, y1, y2, y3, M0, M1, d0, d1); - if (ch == '[') { - token = JSONToken.LBRACKET; - ch = buf[++bp]; - return; - } + int hour, minute, seconds, millis; + if (rest != 8) { + char h0 = charAt(bp + 8); + char h1 = charAt(bp + 9); + char m0 = charAt(bp + 10); + char m1 = charAt(bp + 11); + char s0 = charAt(bp + 12); + char s1 = charAt(bp + 13); - if (ch == '{') { - token = JSONToken.LBRACE; - ch = buf[++bp]; - return; - } + if (!checkTime(h0, h1, m0, m1, s0, s1)) { + return false; + } - break; - case JSONToken.LITERAL_STRING: - if (ch == '"') { - sp = 0; - pos = bp; - scanString(); - return; + if (rest == 17) { + char S0 = charAt(bp + 14); + char S1 = charAt(bp + 15); + char S2 = charAt(bp + 16); + if (S0 < '0' || S0 > '9') { + return false; } - - if (ch >= '0' && ch <= '9') { - sp = 0; - pos = bp; - scanNumber(); - return; + if (S1 < '0' || S1 > '9') { + return false; } - - if (ch == '[') { - token = JSONToken.LBRACKET; - ch = buf[++bp]; - return; + if (S2 < '0' || S2 > '9') { + return false; } - if (ch == '{') { - token = JSONToken.LBRACE; - ch = buf[++bp]; - return; - } - break; - case JSONToken.LBRACKET: - if (ch == '[') { - token = JSONToken.LBRACKET; - ch = buf[++bp]; - return; - } + millis = digits[S0] * 100 + digits[S1] * 10 + digits[S2]; + } else { + millis = 0; + } - if (ch == '{') { - token = JSONToken.LBRACE; - ch = buf[++bp]; - return; - } - break; - case JSONToken.RBRACKET: - if (ch == ']') { - token = JSONToken.RBRACKET; - ch = buf[++bp]; - return; - } - case JSONToken.EOF: - if (ch == EOI) { - token = JSONToken.EOF; - return; - } - break; - default: - break; + hour = digits[h0] * 10 + digits[h1]; + minute = digits[m0] * 10 + digits[m1]; + seconds = digits[s0] * 10 + digits[s1]; + } else { + hour = 0; + minute = 0; + seconds = 0; + millis = 0; } - if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b') { - ch = buf[++bp]; - continue; - } + calendar.set(Calendar.HOUR_OF_DAY, hour); + calendar.set(Calendar.MINUTE, minute); + calendar.set(Calendar.SECOND, seconds); + calendar.set(Calendar.MILLISECOND, millis); - nextToken(); - break; + token = JSONToken.LITERAL_ISO8601_DATE; + return true; } - } - public final void nextToken() { - sp = 0; - - for (;;) { - pos = bp; + if (rest < ISO8601_LEN_0) { + return false; + } - if (ch == '"') { - scanString(); - return; - } + if (charAt(bp + 4) != '-') { + return false; + } + if (charAt(bp + 7) != '-') { + return false; + } - if (ch == ',') { - ch = buf[++bp]; - token = COMMA; - return; - } + char y0 = charAt(bp); + char y1 = charAt(bp + 1); + char y2 = charAt(bp + 2); + char y3 = charAt(bp + 3); + char M0 = charAt(bp + 5); + char M1 = charAt(bp + 6); + char d0 = charAt(bp + 8); + char d1 = charAt(bp + 9); + if (!checkDate(y0, y1, y2, y3, M0, M1, d0, d1)) { + return false; + } - if (ch >= '0' && ch <= '9') { - scanNumber(); - return; - } + setCalendar(y0, y1, y2, y3, M0, M1, d0, d1); - if (ch == '-') { - scanNumber(); - return; + char t = charAt(bp + 10); + if (t == 'T' || (t == ' ' && !strict)) { + if (rest < ISO8601_LEN_1) { + return false; } + } else if (t == '"' || t == EOI) { + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); - switch (ch) { - case '\'': - if (!isEnabled(Feature.AllowSingleQuotes)) { - throw new JSONException("Feature.AllowSingleQuotes is false"); - } - scanStringSingleQuote(); - return; - case ' ': - case '\t': - case '\b': - case '\f': - case '\n': - case '\r': - ch = buf[++bp]; - break; - case 't': // true - scanTrue(); - return; - case 'f': // false - scanFalse(); - return; - case 'n': // new,null - scanNullOrNew(); - return; - case 'D': // Date - scanIdent(); - return; - case '(': - ch = buf[++bp]; - token = LPAREN; - return; - case ')': - ch = buf[++bp]; - token = RPAREN; - return; - case '[': - ch = buf[++bp]; - token = LBRACKET; - return; - case ']': - ch = buf[++bp]; - token = RBRACKET; - return; - case '{': - ch = buf[++bp]; - token = LBRACE; - return; - case '}': - ch = buf[++bp]; - token = RBRACE; - return; - case ':': - ch = buf[++bp]; - token = COLON; - return; - default: - if (bp == buflen || ch == EOI && bp + 1 == buflen) { // JLS - if (token == EOF) { - throw new JSONException("EOF error"); - } - - token = EOF; - pos = bp = eofPos; - } else { - lexError("illegal.char", String.valueOf((int) ch)); - ch = buf[++bp]; - } + ch = charAt(bp += 10); - return; - } + token = JSONToken.LITERAL_ISO8601_DATE; + return true; + } else { + return false; } - } + if (charAt(bp + 13) != ':') { + return false; + } + if (charAt(bp + 16) != ':') { + return false; + } - boolean hasSpecial; + char h0 = charAt(bp + 11); + char h1 = charAt(bp + 12); + char m0 = charAt(bp + 14); + char m1 = charAt(bp + 15); + char s0 = charAt(bp + 17); + char s1 = charAt(bp + 18); - public final void scanStringSingleQuote() { - np = bp; - hasSpecial = false; - char ch; - for (;;) { - ch = buf[++bp]; + if (!checkTime(h0, h1, m0, m1, s0, s1)) { + return false; + } - if (ch == '\'') { - break; - } + int hour = digits[h0] * 10 + digits[h1]; + int minute = digits[m0] * 10 + digits[m1]; + int seconds = digits[s0] * 10 + digits[s1]; + calendar.set(Calendar.HOUR_OF_DAY, hour); + calendar.set(Calendar.MINUTE, minute); + calendar.set(Calendar.SECOND, seconds); - if (ch == EOI) { - throw new JSONException("unclosed single-quote string"); + char dot = charAt(bp + 19); + if (dot == '.') { + if (rest < ISO8601_LEN_2) { + return false; } + } else { + calendar.set(Calendar.MILLISECOND, 0); - if (ch == '\\') { - if (!hasSpecial) { - hasSpecial = true; - - if (sp > sbuf.length) { - char[] newsbuf = new char[sp * 2]; - System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length); - sbuf = newsbuf; - } - - System.arraycopy(buf, np + 1, sbuf, 0, sp); - } + ch = charAt(bp += 19); - ch = buf[++bp]; + token = JSONToken.LITERAL_ISO8601_DATE; + return true; + } - switch (ch) { - case '"': - putChar('"'); - break; - case '\\': - putChar('\\'); - break; - case '/': - putChar('/'); - break; - case '\'': - putChar('\''); - break; - case 'b': - putChar('\b'); - break; - case 'f': - case 'F': - putChar('\f'); - break; - case 'n': - putChar('\n'); - break; - case 'r': - putChar('\r'); - break; - case 't': - putChar('\t'); - break; - case 'u': - char c1 = ch = buf[++bp]; - char c2 = ch = buf[++bp]; - char c3 = ch = buf[++bp]; - char c4 = ch = buf[++bp]; - int val = Integer.parseInt(new String(new char[] { c1, c2, c3, c4 }), 16); - putChar((char) val); - break; - default: - this.ch = ch; - throw new JSONException("unclosed single-quote string"); - } - continue; + + char S0 = charAt(bp + 20); + if (S0 < '0' || S0 > '9') { + return false; + } + int millis = digits[S0]; + int millisLen = 1; + + { + char S1 = charAt(bp + 21); + if (S1 >= '0' && S1 <= '9') { + millis = millis * 10 + digits[S1]; + millisLen = 2; } + } - if (!hasSpecial) { - sp++; - continue; + if (millisLen == 2) { + char S2 = charAt(bp + 22); + if (S2 >= '0' && S2 <= '9') { + millis = millis * 10 + digits[S2]; + millisLen = 3; } + } - if (sp == sbuf.length) { - putChar(ch); - } else { - sbuf[sp++] = ch; + calendar.set(Calendar.MILLISECOND, millis); + + int timzeZoneLength = 0; + char timeZoneFlag = charAt(bp + 20 + millisLen); + if (timeZoneFlag == '+' || timeZoneFlag == '-') { + char t0 = charAt(bp + 20 + millisLen + 1); + if (t0 < '0' || t0 > '1') { + return false; + } + + char t1 = charAt(bp + 20 + millisLen + 2); + if (t1 < '0' || t1 > '9') { + return false; + } + + char t2 = charAt(bp + 20 + millisLen + 3); + if (t2 == ':') { // ThreeLetterISO8601TimeZone + char t3 = charAt(bp + 20 + millisLen + 4); + if (t3 != '0') { + return false; + } + + char t4 = charAt(bp + 20 + millisLen + 5); + if (t4 != '0') { + return false; + } + timzeZoneLength = 6; + } else if (t2 == '0') { //TwoLetterISO8601TimeZone + char t3 = charAt(bp + 20 + millisLen + 4); + if (t3 != '0') { + return false; + } + timzeZoneLength = 5; + } else { + timzeZoneLength = 3; + } + + int timeZoneOffset = (digits[t0] * 10 + digits[t1]) * 3600 * 1000; + if (timeZoneFlag == '-') { + timeZoneOffset = -timeZoneOffset; + } + + if (calendar.getTimeZone().getRawOffset() != timeZoneOffset) { + String[] timeZoneIDs = TimeZone.getAvailableIDs(timeZoneOffset); + if (timeZoneIDs.length > 0) { + TimeZone timeZone = TimeZone.getTimeZone(timeZoneIDs[0]); + calendar.setTimeZone(timeZone); + } + } + + } else if (timeZoneFlag == 'Z') {// UTC + timzeZoneLength = 1; + if (calendar.getTimeZone().getRawOffset() != 0) { + String[] timeZoneIDs = TimeZone.getAvailableIDs(0); + if (timeZoneIDs.length > 0) { + TimeZone timeZone = TimeZone.getTimeZone(timeZoneIDs[0]); + calendar.setTimeZone(timeZone); + } } } + + char end = charAt(bp + (20 + millisLen + timzeZoneLength)) ; + if (end != EOI && end != '"') { + return false; + } + ch = charAt(bp += (20 + millisLen + timzeZoneLength)); - token = LITERAL_STRING; - this.ch = buf[++bp]; + token = JSONToken.LITERAL_ISO8601_DATE; + return true; } - public final void scanString() { - np = bp; - hasSpecial = false; - char ch; - for (;;) { - ch = buf[++bp]; - - if (ch == '\"') { - break; + private boolean checkTime(char h0, char h1, char m0, char m1, char s0, char s1) { + if (h0 == '0') { + if (h1 < '0' || h1 > '9') { + return false; } - - if (ch == '\\') { - if (!hasSpecial) { - hasSpecial = true; - - if (sp >= sbuf.length) { - int newCapcity = sbuf.length * 2; - if (sp > newCapcity) { - newCapcity = sp; - } - char[] newsbuf = new char[newCapcity]; - System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length); - sbuf = newsbuf; - } - - System.arraycopy(buf, np + 1, sbuf, 0, sp); - } - - ch = buf[++bp]; - - switch (ch) { - case '"': - putChar('"'); - break; - case '\\': - putChar('\\'); - break; - case '/': - putChar('/'); - break; - case 'b': - putChar('\b'); - break; - case 'f': - case 'F': - putChar('\f'); - break; - case 'n': - putChar('\n'); - break; - case 'r': - putChar('\r'); - break; - case 't': - putChar('\t'); - break; - case 'x': - char x1 = ch = buf[++bp]; - char x2 = ch = buf[++bp]; - - int x_val = digits[x1] * 16 + digits[x2]; - char x_char = (char) x_val; - putChar(x_char); - break; - case 'u': - char u1 = ch = buf[++bp]; - char u2 = ch = buf[++bp]; - char u3 = ch = buf[++bp]; - char u4 = ch = buf[++bp]; - int val = Integer.parseInt(new String(new char[] { u1, u2, u3, u4 }), 16); - putChar((char) val); - break; - default: - this.ch = ch; - throw new JSONException("unclosed string : " + ch); - } - continue; + } else if (h0 == '1') { + if (h1 < '0' || h1 > '9') { + return false; + } + } else if (h0 == '2') { + if (h1 < '0' || h1 > '4') { + return false; } + } else { + return false; + } - if (!hasSpecial) { - sp++; - continue; + if (m0 >= '0' && m0 <= '5') { + if (m1 < '0' || m1 > '9') { + return false; } + } else if (m0 == '6') { + if (m1 != '0') { + return false; + } + } else { + return false; + } - if (sp == sbuf.length) { - putChar(ch); - } else { - sbuf[sp++] = ch; + if (s0 >= '0' && s0 <= '5') { + if (s1 < '0' || s1 > '9') { + return false; + } + } else if (s0 == '6') { + if (s1 != '0') { + return false; } + } else { + return false; } - token = LITERAL_STRING; - this.ch = buf[++bp]; + return true; } - public final String scanSymbolUnQuoted(final SymbolTable symbolTable) { - final boolean[] firstIdentifierFlags = CharTypes.firstIdentifierFlags; - final char first = ch; + private void setCalendar(char y0, char y1, char y2, char y3, char M0, char M1, char d0, char d1) { + Locale local = Locale.getDefault(); + calendar = Calendar.getInstance(TimeZone.getDefault(), local); + int year = digits[y0] * 1000 + digits[y1] * 100 + digits[y2] * 10 + digits[y3]; + int month = digits[M0] * 10 + digits[M1] - 1; + int day = digits[d0] * 10 + digits[d1]; + calendar.set(Calendar.YEAR, year); + calendar.set(Calendar.MONTH, month); + calendar.set(Calendar.DAY_OF_MONTH, day); + } - final boolean firstFlag = ch >= firstIdentifierFlags.length || firstIdentifierFlags[first]; - if (!firstFlag) { - throw new JSONException("illegal identifier : " + ch); + static boolean checkDate(char y0, char y1, char y2, char y3, char M0, char M1, int d0, int d1) { + if (y0 != '1' && y0 != '2') { + return false; + } + if (y1 < '0' || y1 > '9') { + return false; + } + if (y2 < '0' || y2 > '9') { + return false; + } + if (y3 < '0' || y3 > '9') { + return false; } - final boolean[] identifierFlags = CharTypes.identifierFlags; + if (M0 == '0') { + if (M1 < '1' || M1 > '9') { + return false; + } + } else if (M0 == '1') { + if (M1 != '0' && M1 != '1' && M1 != '2') { + return false; + } + } else { + return false; + } - int hash = first; + if (d0 == '0') { + if (d1 < '1' || d1 > '9') { + return false; + } + } else if (d0 == '1' || d0 == '2') { + if (d1 < '0' || d1 > '9') { + return false; + } + } else if (d0 == '3') { + if (d1 != '0' && d1 != '1') { + return false; + } + } else { + return false; + } - np = bp; - sp = 1; - char ch; - for (;;) { - ch = buf[++bp]; + return true; + } - if (ch < identifierFlags.length) { - if (!identifierFlags[ch]) { - break; - } - } + @Override + public boolean isEOF() { + return bp == text.length() || ch == EOI && bp + 1 == text.length(); + } - hash = 31 * hash + ch; + public int scanFieldInt(char[] fieldName) { + matchStat = UNKOWN; + int startPos = this.bp; + char startChar = this.ch; - sp++; - continue; + if (!charArrayCompare(text, bp, fieldName)) { + matchStat = NOT_MATCH_NAME; + return 0; } - this.ch = buf[bp]; - token = JSONToken.IDENTIFIER; + int index = bp + fieldName.length; - return symbolTable.addSymbol(buf, np, sp, hash); - } + char ch = charAt(index++); - public final static int NOT_MATCH = -1; - public final static int NOT_MATCH_NAME = -2; - public final static int UNKOWN = 0; - public final static int OBJECT = 1; - public final static int ARRAY = 2; - public final static int VALUE = 3; - public final static int END = 4; - - public boolean matchField(char[] fieldName) { - final int fieldNameLength = fieldName.length; - for (int i = 0; i < fieldNameLength; ++i) { - if (fieldName[i] != buf[bp + i]) { - return false; + int value; + if (ch >= '0' && ch <= '9') { + value = digits[ch]; + for (;;) { + ch = charAt(index++); + if (ch >= '0' && ch <= '9') { + value = value * 10 + digits[ch]; + } else if (ch == '.') { + matchStat = NOT_MATCH; + return 0; + } else { + bp = index - 1; + break; + } + } + if (value < 0) { + matchStat = NOT_MATCH; + return 0; } + } else { + matchStat = NOT_MATCH; + return 0; } - bp = bp + fieldNameLength; - ch = buf[bp]; + if (ch == ',') { + this.ch = charAt(++bp); + matchStat = VALUE; + token = JSONToken.COMMA; + return value; + } - if (ch == '{') { - ch = buf[++bp]; - token = JSONToken.LBRACE; - } else if (ch == '[') { - ch = buf[++bp]; - token = JSONToken.LBRACKET; - } else { - nextToken(); + if (ch == '}') { + ch = charAt(++bp); + if (ch == ',') { + token = JSONToken.COMMA; + this.ch = charAt(++bp); + } else if (ch == ']') { + token = JSONToken.RBRACKET; + this.ch = charAt(++bp); + } else if (ch == '}') { + token = JSONToken.RBRACE; + this.ch = charAt(++bp); + } else if (ch == EOI) { + token = JSONToken.EOF; + } else { + this.bp = startPos; + this.ch = startChar; + matchStat = NOT_MATCH; + return 0; + } + matchStat = END; } - return true; + return value; } - public int matchStat = UNKOWN; - public String scanFieldString(char[] fieldName) { matchStat = UNKOWN; + int startPos = this.bp; + char startChar = this.ch; - final int fieldNameLength = fieldName.length; - for (int i = 0; i < fieldNameLength; ++i) { - if (fieldName[i] != buf[bp + i]) { - matchStat = NOT_MATCH_NAME; - return null; - } + // final int fieldNameLength = fieldName.length; + // for (int i = 0; i < fieldNameLength; ++i) { + // if (fieldName[i] != buf[bp + i]) { + // matchStat = NOT_MATCH_NAME; + // + // return stringDefaultValue(); + // } + // } + + if (!charArrayCompare(text, bp, fieldName)) { + matchStat = NOT_MATCH_NAME; + return stringDefaultValue(); } - int index = bp + fieldNameLength; + int index = bp + fieldName.length; - char ch = buf[index++]; + char ch = charAt(index++); if (ch != '"') { matchStat = NOT_MATCH; - return null; + + return stringDefaultValue(); } - String strVal; - int start = index; - for (;;) { - ch = buf[index++]; - if (ch == '\"') { - bp = index; - this.ch = ch = buf[bp]; - strVal = new String(buf, start, index - start - 1); - break; + boolean hasSpecial = false; + final String strVal; + { + int startIndex = index; + int endIndex = text.indexOf('"', startIndex); + if (endIndex == -1) { + throw new JSONException("unclosed str"); } - if (ch == '\\') { - matchStat = NOT_MATCH; - return null; + String stringVal = subString(startIndex, endIndex - startIndex); + for (int i = 0; i < stringVal.length(); ++i) { + if (stringVal.charAt(i) == '\\') { + hasSpecial = true; + break; + } } - } + + if (hasSpecial) { + matchStat = NOT_MATCH; + + return stringDefaultValue(); + } + + bp = endIndex + 1; + this.ch = ch = charAt(bp); + strVal = stringVal; + // this.stringVal = stringVal; + // int pos = endIndex + 1; + // char ch = charAt(pos); + // if (ch != '\'') { + // this.pos = pos; + // this.ch = ch; + // token = LITERAL_CHARS; + // return; + // } + } + + // final int start = index; + // for (;;) { + // ch = charAt(index++); + // if (ch == '\"') { + // bp = index; + // this.ch = ch = charAt(bp); + // strVal = text.substring(start, index - 1); + // // strVal = new String(buf, start, index - start - 1); + // break; + // } + // + // if (ch == '\\') { + // matchStat = NOT_MATCH; + // + // return stringDefaultValue(); + // } + // } if (ch == ',') { - this.ch = buf[++bp]; + this.ch = charAt(++bp); matchStat = VALUE; return strVal; } else if (ch == '}') { - ch = buf[++bp]; + ch = charAt(++bp); if (ch == ',') { token = JSONToken.COMMA; - this.ch = buf[++bp]; + this.ch = charAt(++bp); } else if (ch == ']') { token = JSONToken.RBRACKET; - this.ch = buf[++bp]; + this.ch = charAt(++bp); } else if (ch == '}') { token = JSONToken.RBRACE; - this.ch = buf[++bp]; + this.ch = charAt(++bp); } else if (ch == EOI) { token = JSONToken.EOF; } else { + this.bp = startPos; + this.ch = startChar; matchStat = NOT_MATCH; - return null; + return stringDefaultValue(); } matchStat = END; } else { matchStat = NOT_MATCH; - return null; + + return stringDefaultValue(); } return strVal; } - + public String scanFieldSymbol(char[] fieldName, final SymbolTable symbolTable) { matchStat = UNKOWN; - final int fieldNameLength = fieldName.length; - for (int i = 0; i < fieldNameLength; ++i) { - if (fieldName[i] != buf[bp + i]) { - matchStat = NOT_MATCH_NAME; - return null; - } + if (!charArrayCompare(text, bp, fieldName)) { + matchStat = NOT_MATCH_NAME; + return null; } - int index = bp + fieldNameLength; + int index = bp + fieldName.length; - char ch = buf[index++]; + char ch = charAt(index++); if (ch != '"') { matchStat = NOT_MATCH; return null; @@ -873,14 +809,15 @@ public String scanFieldSymbol(char[] fieldName, final SymbolTable symbolTable) { int start = index; int hash = 0; for (;;) { - ch = buf[index++]; + ch = charAt(index++); if (ch == '\"') { bp = index; - this.ch = ch = buf[bp]; - strVal = symbolTable.addSymbol(buf, start, index - start - 1, hash); + this.ch = ch = charAt(bp); + // strVal = text.substring(start, index - 1).intern(); + strVal = symbolTable.addSymbol(text, start, index - start - 1, hash); break; } - + hash = 31 * hash + ch; if (ch == '\\') { @@ -890,20 +827,20 @@ public String scanFieldSymbol(char[] fieldName, final SymbolTable symbolTable) { } if (ch == ',') { - this.ch = buf[++bp]; + this.ch = charAt(++bp); matchStat = VALUE; return strVal; } else if (ch == '}') { - ch = buf[++bp]; + ch = charAt(++bp); if (ch == ',') { token = JSONToken.COMMA; - this.ch = buf[++bp]; + this.ch = charAt(++bp); } else if (ch == ']') { token = JSONToken.RBRACKET; - this.ch = buf[++bp]; + this.ch = charAt(++bp); } else if (ch == '}') { token = JSONToken.RBRACE; - this.ch = buf[++bp]; + this.ch = charAt(++bp); } else if (ch == EOI) { token = JSONToken.EOF; } else { @@ -919,29 +856,39 @@ public String scanFieldSymbol(char[] fieldName, final SymbolTable symbolTable) { return strVal; } - public ArrayList scanFieldStringArray(char[] fieldName) { + @SuppressWarnings("unchecked") + public Collection scanFieldStringArray(char[] fieldName, Class type) { matchStat = UNKOWN; - ArrayList list = new ArrayList(); + if (!charArrayCompare(text, bp, fieldName)) { + matchStat = NOT_MATCH_NAME; + return null; + } + + Collection list; - final int fieldNameLength = fieldName.length; - for (int i = 0; i < fieldNameLength; ++i) { - if (fieldName[i] != buf[bp + i]) { - matchStat = NOT_MATCH_NAME; - return null; + if (type.isAssignableFrom(HashSet.class)) { + list = new HashSet(); + } else if (type.isAssignableFrom(ArrayList.class)) { + list = new ArrayList(); + } else { + try { + list = (Collection) type.newInstance(); + } catch (Exception e) { + throw new JSONException(e.getMessage(), e); } } - int index = bp + fieldNameLength; + int index = bp + fieldName.length; - char ch = buf[index++]; + char ch = charAt(index++); if (ch != '[') { matchStat = NOT_MATCH; return null; } - ch = buf[index++]; + ch = charAt(index++); for (;;) { if (ch != '"') { @@ -952,11 +899,12 @@ public ArrayList scanFieldStringArray(char[] fieldName) { String strVal; int start = index; for (;;) { - ch = buf[index++]; + ch = charAt(index++); if (ch == '\"') { - strVal = new String(buf, start, index - start - 1); + // strVal = text.substring(start, index - 1); + strVal = this.subString(start, index - start - 1); list.add(strVal); - ch = buf[index++]; + ch = charAt(index++); break; } @@ -967,12 +915,12 @@ public ArrayList scanFieldStringArray(char[] fieldName) { } if (ch == ',') { - ch = buf[index++]; + ch = charAt(index++); continue; } if (ch == ']') { - ch = buf[index++]; + ch = charAt(index++); break; } @@ -982,20 +930,20 @@ public ArrayList scanFieldStringArray(char[] fieldName) { bp = index; if (ch == ',') { - this.ch = buf[bp]; + this.ch = charAt(bp); matchStat = VALUE; return list; } else if (ch == '}') { - ch = buf[bp]; + ch = charAt(bp); if (ch == ',') { token = JSONToken.COMMA; - this.ch = buf[++bp]; + this.ch = charAt(++bp); } else if (ch == ']') { token = JSONToken.RBRACKET; - this.ch = buf[++bp]; + this.ch = charAt(++bp); } else if (ch == '}') { token = JSONToken.RBRACE; - this.ch = buf[++bp]; + this.ch = charAt(++bp); } else if (ch == EOI) { token = JSONToken.EOF; this.ch = ch; @@ -1012,26 +960,25 @@ public ArrayList scanFieldStringArray(char[] fieldName) { return list; } - public int scanFieldInt(char[] fieldName) { + public long scanFieldLong(char[] fieldName) { matchStat = UNKOWN; + int startPos = this.bp; + char startChar = this.ch; - final int fieldNameLength = fieldName.length; - for (int i = 0; i < fieldNameLength; ++i) { - if (fieldName[i] != buf[bp + i]) { - matchStat = NOT_MATCH_NAME; - return 0; - } + if (!charArrayCompare(text, bp, fieldName)) { + matchStat = NOT_MATCH_NAME; + return 0; } - int index = bp + fieldNameLength; + int index = bp + fieldName.length; - char ch = buf[index++]; + char ch = charAt(index++); - int value; + long value; if (ch >= '0' && ch <= '9') { value = digits[ch]; for (;;) { - ch = buf[index++]; + ch = charAt(index++); if (ch >= '0' && ch <= '9') { value = value * 10 + digits[ch]; } else if (ch == '.') { @@ -1043,39 +990,46 @@ public int scanFieldInt(char[] fieldName) { } } if (value < 0) { + this.bp = startPos; + this.ch = startChar; matchStat = NOT_MATCH; return 0; } } else { + this.bp = startPos; + this.ch = startChar; matchStat = NOT_MATCH; return 0; } if (ch == ',') { - ch = buf[++bp]; + this.ch = charAt(++bp); matchStat = VALUE; token = JSONToken.COMMA; return value; - } - - if (ch == '}') { - ch = buf[++bp]; + } else if (ch == '}') { + ch = charAt(++bp); if (ch == ',') { token = JSONToken.COMMA; - this.ch = buf[++bp]; + this.ch = charAt(++bp); } else if (ch == ']') { token = JSONToken.RBRACKET; - this.ch = buf[++bp]; + this.ch = charAt(++bp); } else if (ch == '}') { token = JSONToken.RBRACE; - this.ch = buf[++bp]; + this.ch = charAt(++bp); } else if (ch == EOI) { token = JSONToken.EOF; } else { + this.bp = startPos; + this.ch = startChar; matchStat = NOT_MATCH; return 0; } matchStat = END; + } else { + matchStat = NOT_MATCH; + return 0; } return value; @@ -1084,56 +1038,53 @@ public int scanFieldInt(char[] fieldName) { public boolean scanFieldBoolean(char[] fieldName) { matchStat = UNKOWN; - final int fieldNameLength = fieldName.length; - for (int i = 0; i < fieldNameLength; ++i) { - if (fieldName[i] != buf[bp + i]) { - matchStat = NOT_MATCH_NAME; - return false; - } + if (!charArrayCompare(text, bp, fieldName)) { + matchStat = NOT_MATCH_NAME; + return false; } - int index = bp + fieldNameLength; + int index = bp + fieldName.length; - char ch = buf[index++]; + char ch = charAt(index++); boolean value; if (ch == 't') { - if (buf[index++] != 'r') { + if (charAt(index++) != 'r') { matchStat = NOT_MATCH; return false; } - if (buf[index++] != 'u') { + if (charAt(index++) != 'u') { matchStat = NOT_MATCH; return false; } - if (buf[index++] != 'e') { + if (charAt(index++) != 'e') { matchStat = NOT_MATCH; return false; } bp = index; - ch = buf[bp]; + ch = charAt(bp); value = true; } else if (ch == 'f') { - if (buf[index++] != 'a') { + if (charAt(index++) != 'a') { matchStat = NOT_MATCH; return false; } - if (buf[index++] != 'l') { + if (charAt(index++) != 'l') { matchStat = NOT_MATCH; return false; } - if (buf[index++] != 's') { + if (charAt(index++) != 's') { matchStat = NOT_MATCH; return false; } - if (buf[index++] != 'e') { + if (charAt(index++) != 'e') { matchStat = NOT_MATCH; return false; } bp = index; - ch = buf[bp]; + ch = charAt(bp); value = false; } else { matchStat = NOT_MATCH; @@ -1141,20 +1092,20 @@ public boolean scanFieldBoolean(char[] fieldName) { } if (ch == ',') { - ch = buf[++bp]; + this.ch = charAt(++bp); matchStat = VALUE; token = JSONToken.COMMA; } else if (ch == '}') { - ch = buf[++bp]; + ch = charAt(++bp); if (ch == ',') { token = JSONToken.COMMA; - this.ch = buf[++bp]; + this.ch = charAt(++bp); } else if (ch == ']') { token = JSONToken.RBRACKET; - this.ch = buf[++bp]; + this.ch = charAt(++bp); } else if (ch == '}') { token = JSONToken.RBRACE; - this.ch = buf[++bp]; + this.ch = charAt(++bp); } else if (ch == EOI) { token = JSONToken.EOF; } else { @@ -1170,1014 +1121,7 @@ public boolean scanFieldBoolean(char[] fieldName) { return value; } - public long scanFieldLong(char[] fieldName) { - matchStat = UNKOWN; - - final int fieldNameLength = fieldName.length; - for (int i = 0; i < fieldNameLength; ++i) { - if (fieldName[i] != buf[bp + i]) { - matchStat = NOT_MATCH_NAME; - return 0; - } - } - - int index = bp + fieldNameLength; - - char ch = buf[index++]; - - long value; - if (ch >= '0' && ch <= '9') { - value = digits[ch]; - for (;;) { - ch = buf[index++]; - if (ch >= '0' && ch <= '9') { - value = value * 10 + digits[ch]; - } else if (ch == '.') { - token = NOT_MATCH; - return 0; - } else { - bp = index - 1; - break; - } - } - if (value < 0) { - matchStat = NOT_MATCH; - return 0; - } - } else { - matchStat = NOT_MATCH; - return 0; - } - - if (ch == ',') { - ch = buf[++bp]; - matchStat = VALUE; - token = JSONToken.COMMA; - return value; - } else if (ch == '}') { - ch = buf[++bp]; - if (ch == ',') { - token = JSONToken.COMMA; - this.ch = buf[++bp]; - } else if (ch == ']') { - token = JSONToken.RBRACKET; - this.ch = buf[++bp]; - } else if (ch == '}') { - token = JSONToken.RBRACE; - this.ch = buf[++bp]; - } else if (ch == EOI) { - token = JSONToken.EOF; - } else { - matchStat = NOT_MATCH; - return 0; - } - matchStat = END; - } else { - matchStat = NOT_MATCH; - return 0; - } - - return value; - } - - public float scanFieldFloat(char[] fieldName) { - matchStat = UNKOWN; - - final int fieldNameLength = fieldName.length; - for (int i = 0; i < fieldNameLength; ++i) { - if (fieldName[i] != buf[bp + i]) { - matchStat = NOT_MATCH_NAME; - return 0; - } - } - - int index = bp + fieldNameLength; - - char ch = buf[index++]; - - float value; - if (ch >= '0' && ch <= '9') { - int start = index - 1; - for (;;) { - ch = buf[index++]; - if (ch >= '0' && ch <= '9') { - continue; - } else { - break; - } - } - - if (ch == '.') { - ch = buf[index++]; - if (ch >= '0' && ch <= '9') { - for (;;) { - ch = buf[index++]; - if (ch >= '0' && ch <= '9') { - continue; - } else { - break; - } - } - } else { - matchStat = NOT_MATCH; - return 0; - } - } - - bp = index - 1; - String text = new String(buf, start, index - start - 1); - value = Float.parseFloat(text); - } else { - matchStat = NOT_MATCH; - return 0; - } - - if (ch == ',') { - ch = buf[++bp]; - matchStat = VALUE; - token = JSONToken.COMMA; - return value; - } else if (ch == '}') { - ch = buf[++bp]; - if (ch == ',') { - token = JSONToken.COMMA; - this.ch = buf[++bp]; - } else if (ch == ']') { - token = JSONToken.RBRACKET; - this.ch = buf[++bp]; - } else if (ch == '}') { - token = JSONToken.RBRACE; - this.ch = buf[++bp]; - } else if (ch == EOI) { - token = JSONToken.EOF; - } else { - matchStat = NOT_MATCH; - return 0; - } - matchStat = END; - } else { - matchStat = NOT_MATCH; - return 0; - } - - return value; - } - - public double scanFieldDouble(char[] fieldName) { - matchStat = UNKOWN; - - final int fieldNameLength = fieldName.length; - for (int i = 0; i < fieldNameLength; ++i) { - if (fieldName[i] != buf[bp + i]) { - matchStat = NOT_MATCH_NAME; - return 0; - } - } - - int index = bp + fieldNameLength; - - char ch = buf[index++]; - - double value; - if (ch >= '0' && ch <= '9') { - int start = index - 1; - for (;;) { - ch = buf[index++]; - if (ch >= '0' && ch <= '9') { - continue; - } else { - break; - } - } - - if (ch == '.') { - ch = buf[index++]; - if (ch >= '0' && ch <= '9') { - for (;;) { - ch = buf[index++]; - if (ch >= '0' && ch <= '9') { - continue; - } else { - break; - } - } - } else { - matchStat = NOT_MATCH; - return 0; - } - } - - bp = index - 1; - String text = new String(buf, start, index - start - 1); - value = Double.parseDouble(text); - } else { - matchStat = NOT_MATCH; - return 0; - } - - if (ch == ',') { - ch = buf[++bp]; - matchStat = VALUE; - token = JSONToken.COMMA; - } else if (ch == '}') { - ch = buf[++bp]; - if (ch == ',') { - token = JSONToken.COMMA; - this.ch = buf[++bp]; - } else if (ch == ']') { - token = JSONToken.RBRACKET; - this.ch = buf[++bp]; - } else if (ch == '}') { - token = JSONToken.RBRACE; - this.ch = buf[++bp]; - } else if (ch == EOI) { - token = JSONToken.EOF; - } else { - matchStat = NOT_MATCH; - return 0; - } - matchStat = END; - } else { - matchStat = NOT_MATCH; - return 0; - } - - return value; - } - - // public int scanField2(char[] fieldName, Object object, FieldDeserializer fieldDeserializer) { - // return NOT_MATCH; - // } - - public String scanSymbol(final SymbolTable symbolTable) { - skipWhitespace(); - - if (ch == '"') { - return scanSymbol(symbolTable, '"'); - } - - if (ch == '\'') { - if (!isEnabled(Feature.AllowSingleQuotes)) { - throw new JSONException("syntax error"); - } - - return scanSymbol(symbolTable, '\''); - } - - if (ch == '}') { - ch = buf[++bp]; - token = JSONToken.RBRACE; - return null; - } - - if (ch == ',') { - ch = buf[++bp]; - token = JSONToken.COMMA; - return null; - } - - if (ch == EOI) { - token = JSONToken.EOF; - return null; - } - - if (!isEnabled(Feature.AllowUnQuotedFieldNames)) { - throw new JSONException("syntax error"); - } - - return scanSymbolUnQuoted(symbolTable); - } - - public final String scanSymbol(final SymbolTable symbolTable, final char quote) { - int hash = 0; - - np = bp; - sp = 0; - boolean hasSpecial = false; - char ch; - for (;;) { - ch = buf[++bp]; - - if (ch == quote) { - break; - } - - if (ch == EOI) { - throw new JSONException("unclosed.str"); - } - - if (ch == '\\') { - if (!hasSpecial) { - hasSpecial = true; - - if (sp >= sbuf.length) { - int newCapcity = sbuf.length * 2; - if (sp > newCapcity) { - newCapcity = sp; - } - char[] newsbuf = new char[newCapcity]; - System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length); - sbuf = newsbuf; - } - - System.arraycopy(buf, np + 1, sbuf, 0, sp); - } - - ch = buf[++bp]; - - switch (ch) { - case '"': - hash = 31 * hash + (int) '"'; - putChar('"'); - break; - case '\\': - hash = 31 * hash + (int) '\\'; - putChar('\\'); - break; - case '/': - hash = 31 * hash + (int) '/'; - putChar('/'); - break; - case 'b': - hash = 31 * hash + (int) '\b'; - putChar('\b'); - break; - case 'f': - case 'F': - hash = 31 * hash + (int) '\f'; - putChar('\f'); - break; - case 'n': - hash = 31 * hash + (int) '\n'; - putChar('\n'); - break; - case 'r': - hash = 31 * hash + (int) '\r'; - putChar('\r'); - break; - case 't': - hash = 31 * hash + (int) '\t'; - putChar('\t'); - break; - case 'u': - char c1 = ch = buf[++bp]; - char c2 = ch = buf[++bp]; - char c3 = ch = buf[++bp]; - char c4 = ch = buf[++bp]; - int val = Integer.parseInt(new String(new char[] { c1, c2, c3, c4 }), 16); - hash = 31 * hash + val; - putChar((char) val); - break; - default: - this.ch = ch; - throw new JSONException("unclosed.str.lit"); - } - continue; - } - - hash = 31 * hash + ch; - - if (!hasSpecial) { - sp++; - continue; - } - - if (sp == sbuf.length) { - putChar(ch); - } else { - sbuf[sp++] = ch; - } - } - - token = LITERAL_STRING; - this.ch = buf[++bp]; - - if (!hasSpecial) { - return symbolTable.addSymbol(buf, np + 1, sp, hash); - } else { - return symbolTable.addSymbol(sbuf, 0, sp, hash); - } - } - - public void scanTrue() { - if (buf[bp++] != 't') { - throw new JSONException("error parse true"); - } - if (buf[bp++] != 'r') { - throw new JSONException("error parse true"); - } - if (buf[bp++] != 'u') { - throw new JSONException("error parse true"); - } - if (buf[bp++] != 'e') { - throw new JSONException("error parse true"); - } - - ch = buf[bp]; - - if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI || ch == '\f' || ch == '\b') { - token = JSONToken.TRUE; - } else { - throw new JSONException("scan true error"); - } - } - - public void scanNullOrNew() { - if (buf[bp++] != 'n') { - throw new JSONException("error parse null or new"); - } - - if (buf[bp] == 'u') { - bp++; - if (buf[bp++] != 'l') { - throw new JSONException("error parse true"); - } - if (buf[bp++] != 'l') { - throw new JSONException("error parse true"); - } - ch = buf[bp]; - - if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI || ch == '\f' || ch == '\b') { - token = JSONToken.NULL; - } else { - throw new JSONException("scan true error"); - } - return; - } - - if (buf[bp] != 'e') { - throw new JSONException("error parse e"); - } - - bp++; - if (buf[bp++] != 'w') { - throw new JSONException("error parse w"); - } - ch = buf[bp]; - - if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI || ch == '\f' || ch == '\b') { - token = JSONToken.NEW; - } else { - throw new JSONException("scan true error"); - } - } - - public void scanFalse() { - if (buf[bp++] != 'f') { - throw new JSONException("error parse false"); - } - if (buf[bp++] != 'a') { - throw new JSONException("error parse false"); - } - if (buf[bp++] != 'l') { - throw new JSONException("error parse false"); - } - if (buf[bp++] != 's') { - throw new JSONException("error parse false"); - } - if (buf[bp++] != 'e') { - throw new JSONException("error parse false"); - } - - ch = buf[bp]; - - if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI || ch == '\f' || ch == '\b') { - token = JSONToken.FALSE; - } else { - throw new JSONException("scan false error"); - } - } - - public void scanIdent() { - np = bp - 1; - hasSpecial = false; - - for (;;) { - sp++; - - ch = buf[++bp]; - if (Character.isLetterOrDigit(ch)) { - continue; - } - - String ident = stringVal(); - - Integer tok = keywods.getKeyword(ident); - if (tok != null) { - token = tok; - } else { - token = JSONToken.IDENTIFIER; - } - return; - } - } - - public void scanNumber() { - np = bp; - - if (ch == '-') { - sp++; - ch = buf[++bp]; - } - - for (;;) { - if (ch >= '0' && ch <= '9') { - sp++; - } else { - break; - } - ch = buf[++bp]; - } - - boolean isDouble = false; - - if (ch == '.') { - sp++; - ch = buf[++bp]; - isDouble = true; - - for (;;) { - if (ch >= '0' && ch <= '9') { - sp++; - } else { - break; - } - ch = buf[++bp]; - } - } - - if (ch == 'e' || ch == 'E') { - sp++; - ch = buf[++bp]; - - if (ch == '+' || ch == '-') { - sp++; - ch = buf[++bp]; - } - - for (;;) { - if (ch >= '0' && ch <= '9') { - sp++; - } else { - break; - } - ch = buf[++bp]; - } - - isDouble = true; - } - - if (isDouble) { - token = JSONToken.LITERAL_FLOAT; - } else { - token = JSONToken.LITERAL_INT; - } - } - - /** - * Append a character to sbuf. - */ - private final void putChar(char ch) { - if (sp == sbuf.length) { - char[] newsbuf = new char[sbuf.length * 2]; - System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length); - sbuf = newsbuf; - } - sbuf[sp++] = ch; - } - - /** - * Return the current token's position: a 0-based offset from beginning of the raw input stream (before unicode - * translation) - */ - public final int pos() { - return pos; - } - - /** - * The value of a literal token, recorded as a string. For integers, leading 0x and 'l' suffixes are suppressed. - */ - public final String stringVal() { - if (!hasSpecial) { - return new String(buf, np + 1, sp); - } else { - return new String(sbuf, 0, sp); - } - } - - public final String symbol(SymbolTable symbolTable) { - if (symbolTable == null) { - if (!hasSpecial) { - return new String(buf, np + 1, sp); - } else { - return new String(sbuf, 0, sp); - } - } - - if (!hasSpecial) { - return symbolTable.addSymbol(buf, np + 1, sp); - } else { - return symbolTable.addSymbol(sbuf, 0, sp); - } - } - - private static final long MULTMIN_RADIX_TEN = Long.MIN_VALUE / 10; - private static final long N_MULTMAX_RADIX_TEN = -Long.MAX_VALUE / 10; - - private static final int INT_MULTMIN_RADIX_TEN = Integer.MIN_VALUE / 10; - private static final int INT_N_MULTMAX_RADIX_TEN = -Integer.MAX_VALUE / 10; - - private final static int[] digits = new int[(int) 'f' + 1]; - - static { - for (int i = '0'; i <= '9'; ++i) { - digits[i] = i - '0'; - } - - for (int i = 'a'; i <= 'f'; ++i) { - digits[i] = (i - 'a') + 10; - } - for (int i = 'A'; i <= 'F'; ++i) { - digits[i] = (i - 'A') + 10; - } - } - - public Number integerValue() throws NumberFormatException { - long result = 0; - boolean negative = false; - int i = np, max = np + sp; - long limit; - long multmin; - int digit; - - if (buf[np] == '-') { - negative = true; - limit = Long.MIN_VALUE; - i++; - } else { - limit = -Long.MAX_VALUE; - } - multmin = negative ? MULTMIN_RADIX_TEN : N_MULTMAX_RADIX_TEN; - if (i < max) { - digit = digits[buf[i++]]; - result = -digit; - } - while (i < max) { - // Accumulating negatively avoids surprises near MAX_VALUE - digit = digits[buf[i++]]; - if (result < multmin) { - return new BigInteger(numberString()); - } - result *= 10; - if (result < limit + digit) { - return new BigInteger(numberString()); - } - result -= digit; - } - - if (negative) { - if (i > np + 1) { - if (result >= Integer.MIN_VALUE) { - return (int) result; - } - return result; - } else { /* Only got "-" */ - throw new NumberFormatException(numberString()); - } - } else { - result = -result; - if (result <= Integer.MAX_VALUE) { - return (int) result; - } - return result; - } - } - - public long longValue() throws NumberFormatException { - long result = 0; - boolean negative = false; - int i = np, max = np + sp; - long limit; - long multmin; - int digit; - - if (buf[np] == '-') { - negative = true; - limit = Long.MIN_VALUE; - i++; - } else { - limit = -Long.MAX_VALUE; - } - multmin = negative ? MULTMIN_RADIX_TEN : N_MULTMAX_RADIX_TEN; - if (i < max) { - digit = digits[buf[i++]]; - result = -digit; - } - while (i < max) { - // Accumulating negatively avoids surprises near MAX_VALUE - digit = digits[buf[i++]]; - if (result < multmin) { - throw new NumberFormatException(numberString()); - } - result *= 10; - if (result < limit + digit) { - throw new NumberFormatException(numberString()); - } - result -= digit; - } - - if (negative) { - if (i > np + 1) { - return result; - } else { /* Only got "-" */ - throw new NumberFormatException(numberString()); - } - } else { - return -result; - } - } - - public int intValue() { - int result = 0; - boolean negative = false; - int i = np, max = np + sp; - int limit; - int multmin; - int digit; - - if (buf[np] == '-') { - negative = true; - limit = Integer.MIN_VALUE; - i++; - } else { - limit = -Integer.MAX_VALUE; - } - multmin = negative ? INT_MULTMIN_RADIX_TEN : INT_N_MULTMAX_RADIX_TEN; - if (i < max) { - digit = digits[buf[i++]]; - result = -digit; - } - while (i < max) { - // Accumulating negatively avoids surprises near MAX_VALUE - digit = digits[buf[i++]]; - if (result < multmin) { - throw new NumberFormatException(numberString()); - } - result *= 10; - if (result < limit + digit) { - throw new NumberFormatException(numberString()); - } - result -= digit; - } - - if (negative) { - if (i > np + 1) { - return result; - } else { /* Only got "-" */ - throw new NumberFormatException(numberString()); - } - } else { - return -result; - } - } - - public final String numberString() { - return new String(buf, np, sp); - } - - public float floatValue() { - return Float.parseFloat(numberString()); - } - - public double doubleValue() { - return Double.parseDouble(numberString()); - } - - public BigDecimal decimalValue() { - return new BigDecimal(buf, np, sp); - } - - public void config(Feature feature, boolean state) { - features = Feature.config(features, feature, state); - } - - public boolean isEnabled(Feature feature) { - return Feature.isEnabled(this.features, feature); - } - - public final int ISO8601_LEN_0 = "0000-00-00".length(); - public final int ISO8601_LEN_1 = "0000-00-00T00:00:00".length(); - public final int ISO8601_LEN_2 = "0000-00-00T00:00:00.000".length(); - - public boolean scanISO8601DateIfMatch() { - int rest = buflen - bp; - - if (rest < ISO8601_LEN_0) { - return false; - } - - char y0 = buf[bp]; - char y1 = buf[bp + 1]; - char y2 = buf[bp + 2]; - char y3 = buf[bp + 3]; - if (y0 != '1' && y0 != '2') { - return false; - } - if (y1 < '0' || y1 > '9') { - return false; - } - if (y2 < '0' || y2 > '9') { - return false; - } - if (y3 < '0' || y3 > '9') { - return false; - } - - if (buf[bp + 4] != '-') { - return false; - } - - char M0 = buf[bp + 5]; - char M1 = buf[bp + 6]; - if (M0 == '0') { - if (M1 < '1' || M1 > '9') { - return false; - } - } else if (M0 == '1') { - if (M1 != '0' && M1 != '1' && M1 != '2') { - return false; - } - } else { - return false; - } - - if (buf[bp + 7] != '-') { - return false; - } - - char d0 = buf[bp + 8]; - char d1 = buf[bp + 9]; - if (d0 == '0') { - if (d1 < '1' || d1 > '9') { - return false; - } - } else if (d0 == '1' || d0 == '2') { - if (d1 < '0' || d1 > '9') { - return false; - } - } else if (d0 == '3') { - if (d1 != '0' && d1 != '1') { - return false; - } - } else { - return false; - } - - calendar = Calendar.getInstance(); - int year = digits[y0] * 1000 + digits[y1] * 100 + digits[y2] * 10 + digits[y3]; - int month = digits[M0] * 10 + digits[M1] - 1; - int day = digits[d0] * 10 + digits[d1]; - calendar.set(Calendar.YEAR, year); - calendar.set(Calendar.MONTH, month); - calendar.set(Calendar.DAY_OF_MONTH, day); - - char t = buf[bp + 10]; - if (t == 'T') { - if (rest < ISO8601_LEN_1) { - return false; - } - } else { - calendar.set(Calendar.HOUR_OF_DAY, 0); - calendar.set(Calendar.MINUTE, 0); - calendar.set(Calendar.SECOND, 0); - calendar.set(Calendar.MILLISECOND, 0); - - ch = buf[bp += 10]; - - token = JSONToken.LITERAL_ISO8601_DATE; - return true; - } - - char h0 = buf[bp + 11]; - char h1 = buf[bp + 12]; - if (h0 == '0') { - if (h1 < '0' || h1 > '9') { - return false; - } - } else if (h0 == '1') { - if (h1 < '0' || h1 > '9') { - return false; - } - } else if (h0 == '2') { - if (h1 < '0' || h1 > '4') { - return false; - } - } else { - return false; - } - - if (buf[bp + 13] != ':') { - return false; - } - - char m0 = buf[bp + 14]; - char m1 = buf[bp + 15]; - if (m0 >= '0' && m0 <= '5') { - if (m1 < '0' || m1 > '9') { - return false; - } - } else if (m0 == '6') { - if (m1 != '0') { - return false; - } - } else { - return false; - } - - if (buf[bp + 16] != ':') { - return false; - } - - char s0 = buf[bp + 17]; - char s1 = buf[bp + 18]; - if (s0 >= '0' && s0 <= '5') { - if (s1 < '0' || s1 > '9') { - return false; - } - } else if (s0 == '6') { - if (s1 != '0') { - return false; - } - } else { - return false; - } - - int hour = digits[h0] * 10 + digits[h1]; - int minute = digits[m0] * 10 + digits[m1]; - int seconds = digits[s0] * 10 + digits[s1]; - calendar.set(Calendar.HOUR_OF_DAY, hour); - calendar.set(Calendar.MINUTE, minute); - calendar.set(Calendar.SECOND, seconds); - - char dot = buf[bp + 19]; - if (dot == '.') { - if (rest < ISO8601_LEN_2) { - return false; - } - } else { - calendar.set(Calendar.MILLISECOND, 0); - - ch = buf[bp += 19]; - - token = JSONToken.LITERAL_ISO8601_DATE; - return true; - } - - char S0 = buf[bp + 20]; - char S1 = buf[bp + 21]; - char S2 = buf[bp + 22]; - if (S0 < '0' || S0 > '9') { - return false; - } - if (S1 < '0' || S1 > '9') { - return false; - } - if (S2 < '0' || S2 > '9') { - return false; - } - - int millis = digits[S0] * 100 + digits[S1] * 10 + digits[S2]; - calendar.set(Calendar.MILLISECOND, millis); - - ch = buf[bp += 23]; - - token = JSONToken.LITERAL_ISO8601_DATE; - return true; - } - - public Calendar getCalendar() { - return this.calendar; - } - - public boolean isEOF() { - switch (token) { - case JSONToken.EOF: - return true; - case JSONToken.ERROR: - return false; - case JSONToken.RBRACE: - return false; - default: - return false; - } - - // for (int i = bp; i < buflen; ++i) { - // char ch = buf[i]; - // if (!isWhitespace(ch)) { - // return false; - // } - // } - // - // return true; + protected final void arrayCopy(int srcPos, char[] dest, int destPos, int length) { + text.getChars(srcPos, srcPos + length, dest, destPos); } } diff --git a/src/main/java/com/alibaba/fastjson/parser/JSONToken.java b/src/main/java/com/alibaba/fastjson/parser/JSONToken.java old mode 100644 new mode 100755 index 86451e4faf..ea9f9ad3fe --- a/src/main/java/com/alibaba/fastjson/parser/JSONToken.java +++ b/src/main/java/com/alibaba/fastjson/parser/JSONToken.java @@ -16,11 +16,10 @@ package com.alibaba.fastjson.parser; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class JSONToken { - // public final static int ERROR = 1; // @@ -59,9 +58,14 @@ public class JSONToken { public final static int IDENTIFIER = 18; // public final static int FIELD_NAME = 19; - + public final static int EOF = 20; + public final static int SET = 21; + public final static int TREE_SET = 22; + + public final static int UNDEFINED = 23; // undefined + public static String name(int value) { switch (value) { case ERROR: @@ -104,6 +108,12 @@ public static String name(int value) { return "fieldName"; case EOF: return "EOF"; + case SET: + return "Set"; + case TREE_SET: + return "TreeSet"; + case UNDEFINED: + return "undefined"; default: return "Unkown"; } diff --git a/src/main/java/com/alibaba/fastjson/parser/JavaBeanMapping.java b/src/main/java/com/alibaba/fastjson/parser/JavaBeanMapping.java old mode 100644 new mode 100755 diff --git a/src/main/java/com/alibaba/fastjson/parser/Keywords.java b/src/main/java/com/alibaba/fastjson/parser/Keywords.java deleted file mode 100644 index 56c52c2016..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/Keywords.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.parser; - -import java.util.HashMap; -import java.util.Map; - -/** - * @author wenshao - */ -public class Keywords { - - private final Map keywords; - - public static Keywords DEFAULT_KEYWORDS; - - static { - Map map = new HashMap(); - map.put("null", JSONToken.NULL); - map.put("new", JSONToken.NEW); - map.put("true", JSONToken.TRUE); - map.put("false", JSONToken.FALSE); - DEFAULT_KEYWORDS = new Keywords(map); - } - - public Keywords(Map keywords){ - this.keywords = keywords; - } - - public Integer getKeyword(String key) { - return keywords.get(key); - } - -} diff --git a/src/main/java/com/alibaba/fastjson/parser/ParseContext.java b/src/main/java/com/alibaba/fastjson/parser/ParseContext.java new file mode 100755 index 0000000000..6f8af89c00 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/parser/ParseContext.java @@ -0,0 +1,55 @@ +package com.alibaba.fastjson.parser; + +import java.lang.reflect.Type; + +public class ParseContext { + + private Object object; + private final ParseContext parent; + private final Object fieldName; + private Type type; + + public ParseContext(ParseContext parent, Object object, Object fieldName){ + super(); + this.parent = parent; + this.object = object; + this.fieldName = fieldName; + } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + public Object getObject() { + return object; + } + + public void setObject(Object object) { + this.object = object; + } + + public ParseContext getParentContext() { + return parent; + } + + public String getPath() { + if (parent == null) { + return "$"; + } else { + if (fieldName instanceof Integer) { + return parent.getPath() + "[" + fieldName + "]"; + } else { + return parent.getPath() + "." + fieldName; + } + + } + } + + public String toString() { + return this.getPath(); + } +} diff --git a/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java b/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java old mode 100644 new mode 100755 index 32a2ec6610..006a37bfdb --- a/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java +++ b/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java @@ -1,424 +1,639 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.parser; - -import java.io.File; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.URI; -import java.net.URL; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.TimeZone; -import java.util.TreeMap; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicIntegerArray; -import java.util.concurrent.atomic.AtomicLongArray; -import java.util.regex.Pattern; - -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.parser.deserializer.ASMDeserializerFactory; -import com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer; -import com.alibaba.fastjson.parser.deserializer.ArrayDeserializer; -import com.alibaba.fastjson.parser.deserializer.ArrayListStringDeserializer; -import com.alibaba.fastjson.parser.deserializer.ArrayListStringFieldDeserializer; -import com.alibaba.fastjson.parser.deserializer.ArrayListTypeDeserializer; -import com.alibaba.fastjson.parser.deserializer.ArrayListTypeFieldDeserializer; -import com.alibaba.fastjson.parser.deserializer.AtomicIntegerArrayDeserializer; -import com.alibaba.fastjson.parser.deserializer.AtomicLongArrayDeserializer; -import com.alibaba.fastjson.parser.deserializer.AutowiredObjectDeserializer; -import com.alibaba.fastjson.parser.deserializer.BigDecimalDeserializer; -import com.alibaba.fastjson.parser.deserializer.BigIntegerDeserializer; -import com.alibaba.fastjson.parser.deserializer.BooleanDeserializer; -import com.alibaba.fastjson.parser.deserializer.BooleanFieldDeserializer; -import com.alibaba.fastjson.parser.deserializer.ByteDeserializer; -import com.alibaba.fastjson.parser.deserializer.CharacterDeserializer; -import com.alibaba.fastjson.parser.deserializer.CharsetDeserializer; -import com.alibaba.fastjson.parser.deserializer.CollectionDeserializer; -import com.alibaba.fastjson.parser.deserializer.ConcurrentHashMapDeserializer; -import com.alibaba.fastjson.parser.deserializer.DateDeserializer; -import com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer; -import com.alibaba.fastjson.parser.deserializer.DefaultObjectDeserializer; -import com.alibaba.fastjson.parser.deserializer.DoubleDeserializer; -import com.alibaba.fastjson.parser.deserializer.EnumDeserializer; -import com.alibaba.fastjson.parser.deserializer.FieldDeserializer; -import com.alibaba.fastjson.parser.deserializer.FileDeserializer; -import com.alibaba.fastjson.parser.deserializer.FloatDeserializer; -import com.alibaba.fastjson.parser.deserializer.HashMapDeserializer; -import com.alibaba.fastjson.parser.deserializer.InetAddressDeserializer; -import com.alibaba.fastjson.parser.deserializer.InetSocketAddressDeserializer; -import com.alibaba.fastjson.parser.deserializer.IntegerDeserializer; -import com.alibaba.fastjson.parser.deserializer.IntegerFieldDeserializer; -import com.alibaba.fastjson.parser.deserializer.JSONArrayDeserializer; -import com.alibaba.fastjson.parser.deserializer.JSONObjectDeserializer; -import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer; -import com.alibaba.fastjson.parser.deserializer.JavaObjectDeserializer; -import com.alibaba.fastjson.parser.deserializer.LinkedHashMapDeserializer; -import com.alibaba.fastjson.parser.deserializer.LocaleDeserializer; -import com.alibaba.fastjson.parser.deserializer.LongDeserializer; -import com.alibaba.fastjson.parser.deserializer.LongFieldDeserializer; -import com.alibaba.fastjson.parser.deserializer.NumberDeserializer; -import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; -import com.alibaba.fastjson.parser.deserializer.PatternDeserializer; -import com.alibaba.fastjson.parser.deserializer.ShortDeserializer; -import com.alibaba.fastjson.parser.deserializer.SqlDateDeserializer; -import com.alibaba.fastjson.parser.deserializer.StringDeserializer; -import com.alibaba.fastjson.parser.deserializer.StringFieldDeserializer; -import com.alibaba.fastjson.parser.deserializer.ThrowableDeserializer; -import com.alibaba.fastjson.parser.deserializer.TimeZoneDeserializer; -import com.alibaba.fastjson.parser.deserializer.TimestampDeserializer; -import com.alibaba.fastjson.parser.deserializer.TreeMapDeserializer; -import com.alibaba.fastjson.parser.deserializer.URIDeserializer; -import com.alibaba.fastjson.parser.deserializer.URLDeserializer; -import com.alibaba.fastjson.parser.deserializer.UUIDDeserializer; -import com.alibaba.fastjson.util.FieldInfo; -import com.alibaba.fastjson.util.IdentityHashMap; -import com.alibaba.fastjson.util.ServiceLoader; - -/** - * @author wenshao - */ -public class ParserConfig { - - public static ParserConfig getGlobalInstance() { - return global; - } - - private final Set> primitiveClasses = new HashSet>(); - - private static ParserConfig global = new ParserConfig(); - - private final IdentityHashMap derializers = new IdentityHashMap(); - - private DefaultObjectDeserializer defaultSerializer = new DefaultObjectDeserializer(); - - private boolean asmEnable = true; - - protected final SymbolTable symbolTable = new SymbolTable(); - - public DefaultObjectDeserializer getDefaultSerializer() { - return defaultSerializer; - } - - public ParserConfig(){ - primitiveClasses.add(boolean.class); - primitiveClasses.add(Boolean.class); - - primitiveClasses.add(char.class); - primitiveClasses.add(Character.class); - - primitiveClasses.add(byte.class); - primitiveClasses.add(Byte.class); - - primitiveClasses.add(short.class); - primitiveClasses.add(Short.class); - - primitiveClasses.add(int.class); - primitiveClasses.add(Integer.class); - - primitiveClasses.add(long.class); - primitiveClasses.add(Long.class); - - primitiveClasses.add(float.class); - primitiveClasses.add(Float.class); - - primitiveClasses.add(double.class); - primitiveClasses.add(Double.class); - - primitiveClasses.add(BigInteger.class); - primitiveClasses.add(BigDecimal.class); - - primitiveClasses.add(String.class); - primitiveClasses.add(java.util.Date.class); - primitiveClasses.add(java.sql.Date.class); - primitiveClasses.add(java.sql.Time.class); - primitiveClasses.add(java.sql.Timestamp.class); - - derializers.put(java.sql.Timestamp.class, TimestampDeserializer.instance); - derializers.put(java.sql.Date.class, SqlDateDeserializer.instance); - derializers.put(java.util.Date.class, DateDeserializer.instance); - - derializers.put(JSONObject.class, JSONObjectDeserializer.instance); - derializers.put(JSONArray.class, JSONArrayDeserializer.instance); - - derializers.put(Map.class, HashMapDeserializer.instance); - derializers.put(HashMap.class, HashMapDeserializer.instance); - derializers.put(LinkedHashMap.class, LinkedHashMapDeserializer.instance); - derializers.put(TreeMap.class, TreeMapDeserializer.instance); - derializers.put(ConcurrentMap.class, ConcurrentHashMapDeserializer.instance); - derializers.put(ConcurrentHashMap.class, ConcurrentHashMapDeserializer.instance); - - derializers.put(Collection.class, CollectionDeserializer.instance); - derializers.put(List.class, CollectionDeserializer.instance); - derializers.put(ArrayList.class, CollectionDeserializer.instance); - - derializers.put(Object.class, JavaObjectDeserializer.instance); - derializers.put(String.class, StringDeserializer.instance); - derializers.put(char.class, CharacterDeserializer.instance); - derializers.put(Character.class, CharacterDeserializer.instance); - derializers.put(byte.class, ByteDeserializer.instance); - derializers.put(Byte.class, ByteDeserializer.instance); - derializers.put(short.class, ShortDeserializer.instance); - derializers.put(Short.class, ShortDeserializer.instance); - derializers.put(int.class, IntegerDeserializer.instance); - derializers.put(Integer.class, IntegerDeserializer.instance); - derializers.put(long.class, LongDeserializer.instance); - derializers.put(Long.class, LongDeserializer.instance); - derializers.put(BigInteger.class, BigIntegerDeserializer.instance); - derializers.put(BigDecimal.class, BigDecimalDeserializer.instance); - derializers.put(float.class, FloatDeserializer.instance); - derializers.put(Float.class, FloatDeserializer.instance); - derializers.put(double.class, DoubleDeserializer.instance); - derializers.put(Double.class, DoubleDeserializer.instance); - derializers.put(boolean.class, BooleanDeserializer.instance); - derializers.put(Boolean.class, BooleanDeserializer.instance); - - derializers.put(UUID.class, UUIDDeserializer.instance); - derializers.put(TimeZone.class, TimeZoneDeserializer.instance); - derializers.put(Locale.class, LocaleDeserializer.instance); - derializers.put(InetAddress.class, InetAddressDeserializer.instance); - derializers.put(Inet4Address.class, InetAddressDeserializer.instance); - derializers.put(Inet6Address.class, InetAddressDeserializer.instance); - derializers.put(InetSocketAddress.class, InetSocketAddressDeserializer.instance); - derializers.put(File.class, FileDeserializer.instance); - derializers.put(URI.class, URIDeserializer.instance); - derializers.put(URL.class, URLDeserializer.instance); - derializers.put(Pattern.class, PatternDeserializer.instance); - derializers.put(Charset.class, CharsetDeserializer.instance); - derializers.put(Number.class, NumberDeserializer.instance); - derializers.put(AtomicIntegerArray.class, AtomicIntegerArrayDeserializer.instance); - derializers.put(AtomicLongArray.class, AtomicLongArrayDeserializer.instance); - - - } - - public boolean isAsmEnable() { - return asmEnable; - } - - public void setAsmEnable(boolean asmEnable) { - this.asmEnable = asmEnable; - } - - public SymbolTable getSymbolTable() { - return symbolTable; - } - - public IdentityHashMap getDerializers() { - return derializers; - } - - public ObjectDeserializer getDeserializer(Type type) { - ObjectDeserializer derializer = this.derializers.get(type); - if (derializer != null) { - return derializer; - } - - if (type instanceof Class) { - return getDeserializer((Class) type, type); - } - - if (type instanceof ParameterizedType) { - Type rawType = ((ParameterizedType) type).getRawType(); - return getDeserializer((Class) rawType, type); - } - - return this.defaultSerializer; - } - - public ObjectDeserializer getDeserializer(Class clazz, Type type) { - ObjectDeserializer derializer = derializers.get(type); - if (derializer != null) { - return derializer; - } - - final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - for (AutowiredObjectDeserializer autowired : ServiceLoader.load(AutowiredObjectDeserializer.class, classLoader)) { - for (Type forType : autowired.getAutowiredFor()) { - derializers.put(forType, autowired); - } - } - - derializer = derializers.get(type); - if (derializer != null) { - return derializer; - } - - if (clazz.isEnum()) { - derializer = new EnumDeserializer(clazz); - } else if (clazz.isArray()) { - return ArrayDeserializer.instance; - } else if (clazz == Set.class || clazz == Collection.class || clazz == List.class || clazz == ArrayList.class) { - if (type instanceof ParameterizedType) { - Type itemType = ((ParameterizedType) type).getActualTypeArguments()[0]; - if (itemType == String.class) { - derializer = ArrayListStringDeserializer.instance; - } else { - derializer = new ArrayListTypeDeserializer(itemType); - } - } else { - derializer = CollectionDeserializer.instance; - } - } else if (Collection.class.isAssignableFrom(clazz)) { - derializer = CollectionDeserializer.instance; - } else if (Map.class.isAssignableFrom(clazz)) { - derializer = this.defaultSerializer; - } else if (Throwable.class.isAssignableFrom(clazz)) { - derializer = new ThrowableDeserializer(this, clazz); - } else { - derializer = createJavaBeanDeserializer(clazz); - } - - putDeserializer(type, derializer); - - return derializer; - } - - public ObjectDeserializer createJavaBeanDeserializer(Class clazz) { - if (clazz == Class.class) { - return this.defaultSerializer; - } - - if (!Modifier.isPublic(clazz.getModifiers())) { - return new JavaBeanDeserializer(this, clazz); - } - - if (!asmEnable) { - return new JavaBeanDeserializer(this, clazz); - } - - try { - return ASMDeserializerFactory.getInstance().createJavaBeanDeserializer(this, clazz); - } catch (Exception e) { - throw new JSONException("create asm deserializer error, " + clazz.getName(), e); - } - } - - public FieldDeserializer createFieldDeserializer(ParserConfig mapping, Class clazz, FieldInfo fieldInfo) { - boolean asmEnable = this.asmEnable; - - Method method = fieldInfo.getMethod(); - - if (!Modifier.isPublic(clazz.getModifiers())) { - asmEnable = false; - } - - if (method.getParameterTypes()[0] == Class.class) { - asmEnable = false; - } - - if (!asmEnable) { - return createFieldDeserializerWithoutASM(mapping, clazz, fieldInfo); - } - - try { - return ASMDeserializerFactory.getInstance().createFieldDeserializer(mapping, clazz, fieldInfo); - } catch (Throwable e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - return createFieldDeserializerWithoutASM(mapping, clazz, fieldInfo); - } - - public FieldDeserializer createFieldDeserializerWithoutASM(ParserConfig mapping, Class clazz, FieldInfo fieldInfo) { - Method method = fieldInfo.getMethod(); - Class fieldClass = method.getParameterTypes()[0]; - - if (fieldClass == boolean.class || fieldClass == Boolean.class) { - return new BooleanFieldDeserializer(mapping, clazz, fieldInfo); - } - - if (fieldClass == int.class || fieldClass == Integer.class) { - return new IntegerFieldDeserializer(mapping, clazz, fieldInfo); - } - - if (fieldClass == long.class || fieldClass == Long.class) { - return new LongFieldDeserializer(mapping, clazz, fieldInfo); - } - - if (fieldClass == String.class) { - return new StringFieldDeserializer(mapping, clazz, fieldInfo); - } - - if (fieldClass == List.class || fieldClass == ArrayList.class) { - Type fieldType = method.getGenericParameterTypes()[0]; - Type itemType = ((ParameterizedType) fieldType).getActualTypeArguments()[0]; - if (itemType == String.class) { - return new ArrayListStringFieldDeserializer(mapping, clazz, fieldInfo); - } - - return new ArrayListTypeFieldDeserializer(mapping, clazz, fieldInfo); - } - - return new DefaultFieldDeserializer(mapping, clazz, fieldInfo); - } - - public void putDeserializer(Type type, ObjectDeserializer deserializer) { - derializers.put(type, deserializer); - } - - public ObjectDeserializer getDeserializer(FieldInfo fieldInfo) { - return getDeserializer(fieldInfo.getFieldClass(), fieldInfo.getFieldType()); - } - - public boolean isPrimitive(Class clazz) { - return primitiveClasses.contains(clazz); - } - - public static Field getField(Class clazz, String fieldName) { - try { - return clazz.getDeclaredField(fieldName); - } catch (Exception e) { - return null; - } - } - - public Map getFieldDeserializers(Class clazz) { - ObjectDeserializer deserizer = getDeserializer(clazz); - - if (deserizer instanceof JavaBeanDeserializer) { - return ((JavaBeanDeserializer) deserizer).getFieldDeserializerMap(); - } else if (deserizer instanceof ASMJavaBeanDeserializer) { - return ((ASMJavaBeanDeserializer) deserizer).getInnterSerializer().getFieldDeserializerMap(); - } else { - return Collections.emptyMap(); - } - } - -} +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.parser; + +import java.io.Closeable; +import java.io.File; +import java.io.Serializable; +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.lang.reflect.WildcardType; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.URL; +import java.nio.charset.Charset; +import java.security.AccessControlException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Currency; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.TimeZone; +import java.util.TreeMap; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicIntegerArray; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicLongArray; +import java.util.concurrent.atomic.AtomicReference; +import java.util.regex.Pattern; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.asm.ASMException; +import com.alibaba.fastjson.parser.deserializer.ASMDeserializerFactory; +import com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer; +import com.alibaba.fastjson.parser.deserializer.ArrayDeserializer; +import com.alibaba.fastjson.parser.deserializer.ArrayListTypeFieldDeserializer; +import com.alibaba.fastjson.parser.deserializer.AutowiredObjectDeserializer; +import com.alibaba.fastjson.parser.deserializer.BooleanFieldDeserializer; +import com.alibaba.fastjson.parser.deserializer.CharArrayDeserializer; +import com.alibaba.fastjson.parser.deserializer.ClassDerializer; +import com.alibaba.fastjson.parser.deserializer.CollectionDeserializer; +import com.alibaba.fastjson.parser.deserializer.DateDeserializer; +import com.alibaba.fastjson.parser.deserializer.DateFormatDeserializer; +import com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer; +import com.alibaba.fastjson.parser.deserializer.EnumDeserializer; +import com.alibaba.fastjson.parser.deserializer.FieldDeserializer; +import com.alibaba.fastjson.parser.deserializer.IntegerFieldDeserializer; +import com.alibaba.fastjson.parser.deserializer.JSONArrayDeserializer; +import com.alibaba.fastjson.parser.deserializer.JSONObjectDeserializer; +import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer; +import com.alibaba.fastjson.parser.deserializer.JavaObjectDeserializer; +import com.alibaba.fastjson.parser.deserializer.Jdk8DateCodec; +import com.alibaba.fastjson.parser.deserializer.LongFieldDeserializer; +import com.alibaba.fastjson.parser.deserializer.MapDeserializer; +import com.alibaba.fastjson.parser.deserializer.NumberDeserializer; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.parser.deserializer.SqlDateDeserializer; +import com.alibaba.fastjson.parser.deserializer.StackTraceElementDeserializer; +import com.alibaba.fastjson.parser.deserializer.StringFieldDeserializer; +import com.alibaba.fastjson.parser.deserializer.ThrowableDeserializer; +import com.alibaba.fastjson.parser.deserializer.TimeDeserializer; +import com.alibaba.fastjson.parser.deserializer.TimestampDeserializer; +import com.alibaba.fastjson.serializer.AtomicIntegerArrayCodec; +import com.alibaba.fastjson.serializer.AtomicLongArrayCodec; +import com.alibaba.fastjson.serializer.BigDecimalCodec; +import com.alibaba.fastjson.serializer.BigIntegerCodec; +import com.alibaba.fastjson.serializer.BooleanCodec; +import com.alibaba.fastjson.serializer.CalendarCodec; +import com.alibaba.fastjson.serializer.CharacterCodec; +import com.alibaba.fastjson.serializer.CharsetCodec; +import com.alibaba.fastjson.serializer.ColorCodec; +import com.alibaba.fastjson.serializer.CurrencyCodec; +import com.alibaba.fastjson.serializer.FileCodec; +import com.alibaba.fastjson.serializer.FloatCodec; +import com.alibaba.fastjson.serializer.FontCodec; +import com.alibaba.fastjson.serializer.InetAddressCodec; +import com.alibaba.fastjson.serializer.InetSocketAddressCodec; +import com.alibaba.fastjson.serializer.IntegerCodec; +import com.alibaba.fastjson.serializer.LocaleCodec; +import com.alibaba.fastjson.serializer.LongCodec; +import com.alibaba.fastjson.serializer.PatternCodec; +import com.alibaba.fastjson.serializer.PointCodec; +import com.alibaba.fastjson.serializer.RectangleCodec; +import com.alibaba.fastjson.serializer.ReferenceCodec; +import com.alibaba.fastjson.serializer.StringCodec; +import com.alibaba.fastjson.serializer.TimeZoneCodec; +import com.alibaba.fastjson.serializer.URICodec; +import com.alibaba.fastjson.serializer.URLCodec; +import com.alibaba.fastjson.serializer.UUIDCodec; +import com.alibaba.fastjson.util.ASMUtils; +import com.alibaba.fastjson.util.DeserializeBeanInfo; +import com.alibaba.fastjson.util.FieldInfo; +import com.alibaba.fastjson.util.IdentityHashMap; +import com.alibaba.fastjson.util.ServiceLoader; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public class ParserConfig { + + public static ParserConfig getGlobalInstance() { + return global; + } + + private final Set> primitiveClasses = new HashSet>(); + + private static ParserConfig global = new ParserConfig(); + + private final IdentityHashMap derializers = new IdentityHashMap(); + + private boolean asmEnable = !ASMUtils.isAndroid(); + + protected final SymbolTable symbolTable = new SymbolTable(); + + protected ASMDeserializerFactory asmFactory; + + public ParserConfig() { + this(null, null); + } + + public ParserConfig(ClassLoader parentClassLoader){ + this(null, parentClassLoader); + } + + public ParserConfig(ASMDeserializerFactory asmFactory){ + this(asmFactory, null); + } + + private ParserConfig(ASMDeserializerFactory asmFactory, ClassLoader parentClassLoader){ + if (asmFactory == null) { + try { + if (parentClassLoader == null) { + asmFactory = ASMDeserializerFactory.getInstance(); + } else { + asmFactory = new ASMDeserializerFactory(parentClassLoader); + } + } catch (ExceptionInInitializerError error) { + // skip + } catch (AccessControlException error) { + // skip + } catch (NoClassDefFoundError error) { + // skip + } + } + + this.asmFactory = asmFactory; + + if (asmFactory == null) { + asmEnable = false; + } + + primitiveClasses.add(boolean.class); + primitiveClasses.add(Boolean.class); + + primitiveClasses.add(char.class); + primitiveClasses.add(Character.class); + + primitiveClasses.add(byte.class); + primitiveClasses.add(Byte.class); + + primitiveClasses.add(short.class); + primitiveClasses.add(Short.class); + + primitiveClasses.add(int.class); + primitiveClasses.add(Integer.class); + + primitiveClasses.add(long.class); + primitiveClasses.add(Long.class); + + primitiveClasses.add(float.class); + primitiveClasses.add(Float.class); + + primitiveClasses.add(double.class); + primitiveClasses.add(Double.class); + + primitiveClasses.add(BigInteger.class); + primitiveClasses.add(BigDecimal.class); + + primitiveClasses.add(String.class); + primitiveClasses.add(java.util.Date.class); + primitiveClasses.add(java.sql.Date.class); + primitiveClasses.add(java.sql.Time.class); + primitiveClasses.add(java.sql.Timestamp.class); + + derializers.put(SimpleDateFormat.class, DateFormatDeserializer.instance); + derializers.put(java.sql.Timestamp.class, TimestampDeserializer.instance); + derializers.put(java.sql.Date.class, SqlDateDeserializer.instance); + derializers.put(java.sql.Time.class, TimeDeserializer.instance); + derializers.put(java.util.Date.class, DateDeserializer.instance); + derializers.put(Calendar.class, CalendarCodec.instance); + + derializers.put(JSONObject.class, JSONObjectDeserializer.instance); + derializers.put(JSONArray.class, JSONArrayDeserializer.instance); + + derializers.put(Map.class, MapDeserializer.instance); + derializers.put(HashMap.class, MapDeserializer.instance); + derializers.put(LinkedHashMap.class, MapDeserializer.instance); + derializers.put(TreeMap.class, MapDeserializer.instance); + derializers.put(ConcurrentMap.class, MapDeserializer.instance); + derializers.put(ConcurrentHashMap.class, MapDeserializer.instance); + + derializers.put(Collection.class, CollectionDeserializer.instance); + derializers.put(List.class, CollectionDeserializer.instance); + derializers.put(ArrayList.class, CollectionDeserializer.instance); + + derializers.put(Object.class, JavaObjectDeserializer.instance); + derializers.put(String.class, StringCodec.instance); + derializers.put(char.class, CharacterCodec.instance); + derializers.put(Character.class, CharacterCodec.instance); + derializers.put(byte.class, NumberDeserializer.instance); + derializers.put(Byte.class, NumberDeserializer.instance); + derializers.put(short.class, NumberDeserializer.instance); + derializers.put(Short.class, NumberDeserializer.instance); + derializers.put(int.class, IntegerCodec.instance); + derializers.put(Integer.class, IntegerCodec.instance); + derializers.put(long.class, LongCodec.instance); + derializers.put(Long.class, LongCodec.instance); + derializers.put(BigInteger.class, BigIntegerCodec.instance); + derializers.put(BigDecimal.class, BigDecimalCodec.instance); + derializers.put(float.class, FloatCodec.instance); + derializers.put(Float.class, FloatCodec.instance); + derializers.put(double.class, NumberDeserializer.instance); + derializers.put(Double.class, NumberDeserializer.instance); + derializers.put(boolean.class, BooleanCodec.instance); + derializers.put(Boolean.class, BooleanCodec.instance); + derializers.put(Class.class, ClassDerializer.instance); + derializers.put(char[].class, CharArrayDeserializer.instance); + + derializers.put(AtomicBoolean.class, BooleanCodec.instance); + derializers.put(AtomicInteger.class, IntegerCodec.instance); + derializers.put(AtomicLong.class, LongCodec.instance); + derializers.put(AtomicReference.class, ReferenceCodec.instance); + + derializers.put(WeakReference.class, ReferenceCodec.instance); + derializers.put(SoftReference.class, ReferenceCodec.instance); + + derializers.put(UUID.class, UUIDCodec.instance); + derializers.put(TimeZone.class, TimeZoneCodec.instance); + derializers.put(Locale.class, LocaleCodec.instance); + derializers.put(Currency.class, CurrencyCodec.instance); + derializers.put(InetAddress.class, InetAddressCodec.instance); + derializers.put(Inet4Address.class, InetAddressCodec.instance); + derializers.put(Inet6Address.class, InetAddressCodec.instance); + derializers.put(InetSocketAddress.class, InetSocketAddressCodec.instance); + derializers.put(File.class, FileCodec.instance); + derializers.put(URI.class, URICodec.instance); + derializers.put(URL.class, URLCodec.instance); + derializers.put(Pattern.class, PatternCodec.instance); + derializers.put(Charset.class, CharsetCodec.instance); + derializers.put(Number.class, NumberDeserializer.instance); + derializers.put(AtomicIntegerArray.class, AtomicIntegerArrayCodec.instance); + derializers.put(AtomicLongArray.class, AtomicLongArrayCodec.instance); + derializers.put(StackTraceElement.class, StackTraceElementDeserializer.instance); + + derializers.put(Serializable.class, JavaObjectDeserializer.instance); + derializers.put(Cloneable.class, JavaObjectDeserializer.instance); + derializers.put(Comparable.class, JavaObjectDeserializer.instance); + derializers.put(Closeable.class, JavaObjectDeserializer.instance); + + try { + derializers.put(Class.forName("java.awt.Point"), PointCodec.instance); + derializers.put(Class.forName("java.awt.Font"), FontCodec.instance); + derializers.put(Class.forName("java.awt.Rectangle"), RectangleCodec.instance); + derializers.put(Class.forName("java.awt.Color"), ColorCodec.instance); + } catch (Throwable e) { + // skip + } + + try { + derializers.put(Class.forName("java.time.LocalDateTime"), Jdk8DateCodec.instance); + derializers.put(Class.forName("java.time.LocalDate"), Jdk8DateCodec.instance); + derializers.put(Class.forName("java.time.LocalTime"), Jdk8DateCodec.instance); + derializers.put(Class.forName("java.time.ZonedDateTime"), Jdk8DateCodec.instance); + derializers.put(Class.forName("java.time.OffsetDateTime"), Jdk8DateCodec.instance); + derializers.put(Class.forName("java.time.OffsetTime"), Jdk8DateCodec.instance); + derializers.put(Class.forName("java.time.ZoneOffset"), Jdk8DateCodec.instance); + derializers.put(Class.forName("java.time.ZoneRegion"), Jdk8DateCodec.instance); + derializers.put(Class.forName("java.time.ZoneId"), Jdk8DateCodec.instance); + derializers.put(Class.forName("java.time.Period"), Jdk8DateCodec.instance); + derializers.put(Class.forName("java.time.Duration"), Jdk8DateCodec.instance); + derializers.put(Class.forName("java.time.Instant"), Jdk8DateCodec.instance); + } catch (Throwable e) { + + } + } + + public boolean isAsmEnable() { + return asmEnable; + } + + public void setAsmEnable(boolean asmEnable) { + this.asmEnable = asmEnable; + } + + public SymbolTable getSymbolTable() { + return symbolTable; + } + + public IdentityHashMap getDerializers() { + return derializers; + } + + public ObjectDeserializer getDeserializer(Type type) { + ObjectDeserializer derializer = this.derializers.get(type); + if (derializer != null) { + return derializer; + } + + if (type instanceof Class) { + return getDeserializer((Class) type, type); + } + + if (type instanceof ParameterizedType) { + Type rawType = ((ParameterizedType) type).getRawType(); + if (rawType instanceof Class) { + return getDeserializer((Class) rawType, type); + } else { + return getDeserializer(rawType); + } + } + + return JavaObjectDeserializer.instance; + } + + public ObjectDeserializer getDeserializer(Class clazz, Type type) { + ObjectDeserializer derializer = derializers.get(type); + if (derializer != null) { + return derializer; + } + + if (type == null) { + type = clazz; + } + + derializer = derializers.get(type); + if (derializer != null) { + return derializer; + } + + { + JSONType annotation = clazz.getAnnotation(JSONType.class); + if (annotation != null) { + Class mappingTo = annotation.mappingTo(); + if (mappingTo != Void.class) { + return getDeserializer(mappingTo, mappingTo); + } + } + } + + if (type instanceof WildcardType || type instanceof TypeVariable || type instanceof ParameterizedType) { + derializer = derializers.get(clazz); + } + + if (derializer != null) { + return derializer; + } + + final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + try { + for (AutowiredObjectDeserializer autowired : ServiceLoader.load(AutowiredObjectDeserializer.class, + classLoader)) { + for (Type forType : autowired.getAutowiredFor()) { + derializers.put(forType, autowired); + } + } + } catch (Exception ex) { + // skip + } + + derializer = derializers.get(type); + if (derializer != null) { + return derializer; + } + + if (clazz.isEnum()) { + derializer = new EnumDeserializer(clazz); + } else if (clazz.isArray()) { + derializer = ArrayDeserializer.instance; + } else if (clazz == Set.class || clazz == HashSet.class || clazz == Collection.class || clazz == List.class + || clazz == ArrayList.class) { + derializer = CollectionDeserializer.instance; + } else if (Collection.class.isAssignableFrom(clazz)) { + derializer = CollectionDeserializer.instance; + } else if (Map.class.isAssignableFrom(clazz)) { + derializer = MapDeserializer.instance; + } else if (Throwable.class.isAssignableFrom(clazz)) { + derializer = new ThrowableDeserializer(this, clazz); + } else { + derializer = createJavaBeanDeserializer(clazz, type); + } + + putDeserializer(type, derializer); + + return derializer; + } + + public ObjectDeserializer createJavaBeanDeserializer(Class clazz, Type type) { + boolean asmEnable = this.asmEnable; + if (asmEnable) { + Class superClass = clazz; + + for (;;) { + if (!Modifier.isPublic(superClass.getModifiers())) { + asmEnable = false; + break; + } + + superClass = superClass.getSuperclass(); + if (superClass == Object.class || superClass == null) { + break; + } + } + } + + if (clazz.getTypeParameters().length != 0) { + asmEnable = false; + } + + if (asmEnable && asmFactory != null && asmFactory.isExternalClass(clazz)) { + asmEnable = false; + } + + if (asmEnable) { + asmEnable = ASMUtils.checkName(clazz.getName()); + } + + if (asmEnable) { + if (clazz.isInterface()) { + asmEnable = false; + } + DeserializeBeanInfo beanInfo = DeserializeBeanInfo.computeSetters(clazz, type); + if (beanInfo.getFieldList().size() > 200) { + asmEnable = false; + } + + Constructor defaultConstructor = beanInfo.getDefaultConstructor(); + if (defaultConstructor == null && !clazz.isInterface()) { + asmEnable = false; + } + + for (FieldInfo fieldInfo : beanInfo.getFieldList()) { + if (fieldInfo.isGetOnly()) { + asmEnable = false; + break; + } + + Class fieldClass = fieldInfo.getFieldClass(); + if (!Modifier.isPublic(fieldClass.getModifiers())) { + asmEnable = false; + break; + } + + if (fieldClass.isMemberClass() && !Modifier.isStatic(fieldClass.getModifiers())) { + asmEnable = false; + } + + if (!ASMUtils.checkName(fieldInfo.getMember().getName())) { + asmEnable = false; + } + } + } + + if (asmEnable) { + if (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers())) { + asmEnable = false; + } + } + + if (!asmEnable) { + return new JavaBeanDeserializer(this, clazz, type); + } + + try { + return asmFactory.createJavaBeanDeserializer(this, clazz, type); + // } catch (VerifyError e) { + // e.printStackTrace(); + // return new JavaBeanDeserializer(this, clazz, type); + } catch (NoSuchMethodException ex) { + return new JavaBeanDeserializer(this, clazz, type); + } catch (ASMException asmError) { + return new JavaBeanDeserializer(this, clazz, type); + } catch (Exception e) { + throw new JSONException("create asm deserializer error, " + clazz.getName(), e); + } + } + + public FieldDeserializer createFieldDeserializer(ParserConfig mapping, Class clazz, FieldInfo fieldInfo) { + boolean asmEnable = this.asmEnable; + + if (asmEnable) { + Class superClass = clazz; + + for (;;) { + if (!Modifier.isPublic(superClass.getModifiers())) { + asmEnable = false; + break; + } + + superClass = superClass.getSuperclass(); + if (superClass == Object.class || superClass == null) { + break; + } + } + } + + if (fieldInfo.getFieldClass() == Class.class) { + asmEnable = false; + } + + if (asmEnable && asmFactory != null && asmFactory.isExternalClass(clazz)) { + asmEnable = false; + } + + if (!asmEnable) { + return createFieldDeserializerWithoutASM(mapping, clazz, fieldInfo); + } + + try { + return asmFactory.createFieldDeserializer(mapping, clazz, fieldInfo); + } catch (Throwable e) { + // skip + } + + return createFieldDeserializerWithoutASM(mapping, clazz, fieldInfo); + } + + public FieldDeserializer createFieldDeserializerWithoutASM(ParserConfig mapping, Class clazz, FieldInfo fieldInfo) { + Class fieldClass = fieldInfo.getFieldClass(); + + if (fieldClass == boolean.class || fieldClass == Boolean.class) { + return new BooleanFieldDeserializer(mapping, clazz, fieldInfo); + } + + if (fieldClass == int.class || fieldClass == Integer.class) { + return new IntegerFieldDeserializer(mapping, clazz, fieldInfo); + } + + if (fieldClass == long.class || fieldClass == Long.class) { + return new LongFieldDeserializer(mapping, clazz, fieldInfo); + } + + if (fieldClass == String.class) { + return new StringFieldDeserializer(mapping, clazz, fieldInfo); + } + + if (fieldClass == List.class || fieldClass == ArrayList.class) { + return new ArrayListTypeFieldDeserializer(mapping, clazz, fieldInfo); + } + + return new DefaultFieldDeserializer(mapping, clazz, fieldInfo); + } + + public void putDeserializer(Type type, ObjectDeserializer deserializer) { + derializers.put(type, deserializer); + } + + public ObjectDeserializer getDeserializer(FieldInfo fieldInfo) { + return getDeserializer(fieldInfo.getFieldClass(), fieldInfo.getFieldType()); + } + + public boolean isPrimitive(Class clazz) { + return primitiveClasses.contains(clazz); + } + + public static Field getField(Class clazz, String fieldName) { + Field field = getField0(clazz, fieldName); + if (field == null) { + field = getField0(clazz, "_" + fieldName); + } + if (field == null) { + field = getField0(clazz, "m_" + fieldName); + } + return field; + } + + private static Field getField0(Class clazz, String fieldName) { + for (Field item : clazz.getDeclaredFields()) { + if (fieldName.equals(item.getName())) { + return item; + } + } + if (clazz.getSuperclass() != null && clazz.getSuperclass() != Object.class) { + return getField(clazz.getSuperclass(), fieldName); + } + + return null; + } + + public Map getFieldDeserializers(Class clazz) { + ObjectDeserializer deserizer = getDeserializer(clazz); + + if (deserizer instanceof JavaBeanDeserializer) { + return ((JavaBeanDeserializer) deserizer).getFieldDeserializerMap(); + } else if (deserizer instanceof ASMJavaBeanDeserializer) { + return ((ASMJavaBeanDeserializer) deserizer).getInnterSerializer().getFieldDeserializerMap(); + } else { + return Collections.emptyMap(); + } + } + +} diff --git a/src/main/java/com/alibaba/fastjson/parser/SymbolTable.java b/src/main/java/com/alibaba/fastjson/parser/SymbolTable.java old mode 100644 new mode 100755 index c7e7fdcc4d..831a08c3c2 --- a/src/main/java/com/alibaba/fastjson/parser/SymbolTable.java +++ b/src/main/java/com/alibaba/fastjson/parser/SymbolTable.java @@ -1,151 +1,253 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.parser; - -/** - * @author wenshao - */ -public class SymbolTable { - - public static final int DEFAULT_TABLE_SIZE = 128; - - private final Entry[] buckets; - private final String[] symbols; - private final char[][] symbols_char; - - private final int indexMask; - - public SymbolTable(){ - this(DEFAULT_TABLE_SIZE); - } - - public SymbolTable(int tableSize){ - this.indexMask = tableSize - 1; - this.buckets = new Entry[tableSize]; - this.symbols = new String[tableSize]; - this.symbols_char = new char[tableSize][]; - } - - /** - * Adds the specified symbol to the symbol table and returns a reference to the unique symbol. If the symbol already - * exists, the previous symbol reference is returned instead, in order guarantee that symbol references remain - * unique. - * - * @param symbol The new symbol. - */ - public String addSymbol(String symbol) { - return addSymbol(symbol.toCharArray(), 0, symbol.length(), symbol.hashCode()); - } - - - public String addSymbol(char[] buffer, int offset, int len) { - // search for identical symbol - int hash = hash(buffer, offset, len); - return addSymbol(buffer, offset, len, hash); - } - - /** - * Adds the specified symbol to the symbol table and returns a reference to the unique symbol. If the symbol already - * exists, the previous symbol reference is returned instead, in order guarantee that symbol references remain - * unique. - * - * @param buffer The buffer containing the new symbol. - * @param offset The offset into the buffer of the new symbol. - * @param len The length of the new symbol in the buffer. - */ - public String addSymbol(char[] buffer, int offset, int len, int hash) { - // int bucket = indexFor(hash, tableSize); - final int bucket = hash & indexMask; - - String sym = symbols[bucket]; - - boolean match = true; - - if (sym != null) { - if (sym.length() == len) { - char[] characters = symbols_char[bucket]; - - for (int i = 0; i < len; i++) { - if (buffer[offset + i] != characters[i]) { - match = false; - break; - } - } - - if (match) { - return sym; - } - } else { - match = false; - } - } - - OUTER: for (Entry entry = buckets[bucket]; entry != null; entry = entry.next) { - char[] characters = entry.characters; - if (len == characters.length && hash == entry.hashCode) { - for (int i = 0; i < len; i++) { - if (buffer[offset + i] != characters[i]) { - continue OUTER; - } - } - return entry.symbol; - } - } - - Entry entry = new Entry(buffer, offset, len, hash, buckets[bucket]); - buckets[bucket] = entry; // 并发是处理时会导致缓存丢失,但不影响正确性 - if (match) { - symbols[bucket] = entry.symbol; - symbols_char[bucket] = entry.characters; - } - return entry.symbol; - } - - public static final int hash(char[] buffer, int offset, int len) { - int h = 0; - int off = offset; - - for (int i = 0; i < len; i++) { - h = 31 * h + buffer[off++]; - } - return h; - } - - protected static final class Entry { - - public final String symbol; - public final int hashCode; - - public final char[] characters; - public final byte[] bytes; - - public Entry next; - - /** - * Constructs a new entry from the specified symbol information and next entry reference. - */ - public Entry(char[] ch, int offset, int length, int hash, Entry next){ - characters = new char[length]; - System.arraycopy(ch, offset, characters, 0, length); - symbol = new String(characters).intern(); - this.next = next; - this.hashCode = hash; - this.bytes = null; - } - - } - -} +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.parser; + +import com.alibaba.fastjson.JSON; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public class SymbolTable { + + public static final int DEFAULT_TABLE_SIZE = 512; + public static final int MAX_BUCKET_LENTH = 8; + public static final int MAX_SIZE = 4096; + + private final Entry[] buckets; + private final String[] symbols; + private final char[][] symbols_char; + + private final int indexMask; + + private int size = 0; + + public SymbolTable(){ + this(DEFAULT_TABLE_SIZE); + this.addSymbol("$ref", 0, 4, "$ref".hashCode()); + this.addSymbol(JSON.DEFAULT_TYPE_KEY, 0, 5, JSON.DEFAULT_TYPE_KEY.hashCode()); + } + + public SymbolTable(int tableSize){ + this.indexMask = tableSize - 1; + this.buckets = new Entry[tableSize]; + this.symbols = new String[tableSize]; + this.symbols_char = new char[tableSize][]; + } + + public String addSymbol(char[] buffer, int offset, int len) { + // search for identical symbol + int hash = hash(buffer, offset, len); + return addSymbol(buffer, offset, len, hash); + } + + /** + * Adds the specified symbol to the symbol table and returns a reference to the unique symbol. If the symbol already + * exists, the previous symbol reference is returned instead, in order guarantee that symbol references remain + * unique. + * + * @param buffer The buffer containing the new symbol. + * @param offset The offset into the buffer of the new symbol. + * @param len The length of the new symbol in the buffer. + */ + public String addSymbol(char[] buffer, int offset, int len, int hash) { + // int bucket = indexFor(hash, tableSize); + final int bucket = hash & indexMask; + + String sym = symbols[bucket]; + + boolean match = true; + + if (sym != null) { + if (sym.length() == len) { + char[] characters = symbols_char[bucket]; + + for (int i = 0; i < len; i++) { + if (buffer[offset + i] != characters[i]) { + match = false; + break; + } + } + + if (match) { + return sym; + } + } else { + match = false; + } + } + + { + int entryIndex = 0; + for (Entry entry = buckets[bucket]; entry != null; entry = entry.next) { + char[] characters = entry.characters; + if (len == characters.length && hash == entry.hashCode) { + boolean eq = true; + for (int i = 0; i < len; i++) { + if (buffer[offset + i] != characters[i]) { + eq = false; + break; + } + } + + if (!eq) { + entryIndex++; + continue; + } + return entry.symbol; + } + } + if (entryIndex >= MAX_BUCKET_LENTH) { + return new String(buffer, offset, len); + } + } + + if (size >= MAX_SIZE) { + return new String(buffer, offset, len); + } + + Entry entry = new Entry(buffer, offset, len, hash, buckets[bucket]); + buckets[bucket] = entry; // 并发是处理时会导致缓存丢失,但不影响正确性 + if (match) { + symbols[bucket] = entry.symbol; + symbols_char[bucket] = entry.characters; + } + size++; + return entry.symbol; + } + + public String addSymbol(String buffer, int offset, int len, int hash) { + // int bucket = indexFor(hash, tableSize); + final int bucket = hash & indexMask; + + String sym = symbols[bucket]; + + boolean match = true; + + if (sym != null) { + if (sym.length() == len) { + char[] characters = symbols_char[bucket]; + + for (int i = 0; i < len; i++) { + if (buffer.charAt(offset + i) != characters[i]) { + match = false; + break; + } + } + + if (match) { + return sym; + } + } else { + match = false; + } + } + + { + int entryIndex = 0; + for (Entry entry = buckets[bucket]; entry != null; entry = entry.next) { + char[] characters = entry.characters; + if (len == characters.length && hash == entry.hashCode) { + boolean eq = true; + for (int i = 0; i < len; i++) { + if (buffer.charAt(offset + i) != characters[i]) { + eq = false; + break; + } + } + + if (!eq) { + entryIndex++; + continue; + } + return entry.symbol; + } + } + if (entryIndex >= MAX_BUCKET_LENTH) { + // return buffer.substring(offset, offset + len); + return subString(buffer, offset, len); + } + } + + if (size >= MAX_SIZE) { + // return buffer.substring(offset, offset + len); + return subString(buffer, offset, len); + } + + Entry entry = new Entry(buffer, offset, len, hash, buckets[bucket]); + buckets[bucket] = entry; // 并发是处理时会导致缓存丢失,但不影响正确性 + if (match) { + symbols[bucket] = entry.symbol; + symbols_char[bucket] = entry.characters; + } + size++; + return entry.symbol; + } + + private static String subString(String src, int offset, int len) { + char[] chars = new char[len]; + for (int i = offset; i < offset + len; ++i) { + chars[i - offset] = src.charAt(i); + } + return new String(chars); + } + + public int size() { + return size; + } + + public static final int hash(char[] buffer, int offset, int len) { + int h = 0; + int off = offset; + + for (int i = 0; i < len; i++) { + h = 31 * h + buffer[off++]; + } + return h; + } + + protected static final class Entry { + + public final String symbol; + public final int hashCode; + + public final char[] characters; + public final byte[] bytes; + + public Entry next; + + /** + * Constructs a new entry from the specified symbol information and next entry reference. + */ + public Entry(char[] ch, int offset, int length, int hash, Entry next){ + characters = new char[length]; + System.arraycopy(ch, offset, characters, 0, length); + symbol = new String(characters).intern(); + this.next = next; + this.hashCode = hash; + this.bytes = null; + } + + public Entry(String text, int offset, int length, int hash, Entry next){ + // symbol = text.substring(offset, offset + length).intern(); + symbol = subString(text, offset, length).intern(); + characters = symbol.toCharArray(); + this.next = next; + this.hashCode = hash; + this.bytes = null; + } + } + +} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ASMDeserializerFactory.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ASMDeserializerFactory.java old mode 100644 new mode 100755 index 292ac56d51..e6355259d5 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/ASMDeserializerFactory.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/ASMDeserializerFactory.java @@ -3,61 +3,75 @@ import static com.alibaba.fastjson.util.ASMUtils.getDesc; import static com.alibaba.fastjson.util.ASMUtils.getType; +import java.io.File; +import java.io.FileOutputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.TreeSet; import java.util.concurrent.atomic.AtomicLong; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.asm.ClassWriter; import com.alibaba.fastjson.asm.FieldVisitor; import com.alibaba.fastjson.asm.Label; import com.alibaba.fastjson.asm.MethodVisitor; import com.alibaba.fastjson.asm.Opcodes; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.Feature; -import com.alibaba.fastjson.parser.JSONLexer; -import com.alibaba.fastjson.parser.JSONScanner; -import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.SymbolTable; -import com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer.InnerJavaBeanDeserializer; import com.alibaba.fastjson.util.ASMClassLoader; +import com.alibaba.fastjson.util.ASMUtils; +import com.alibaba.fastjson.util.DeserializeBeanInfo; import com.alibaba.fastjson.util.FieldInfo; +import com.alibaba.fastjson.util.TypeUtils; public class ASMDeserializerFactory implements Opcodes { - private static final ASMDeserializerFactory instance = new ASMDeserializerFactory(); + private static final ASMDeserializerFactory instance = new ASMDeserializerFactory(); - private ASMClassLoader classLoader = new ASMClassLoader(); + private final ASMClassLoader classLoader; - private final AtomicLong seed = new AtomicLong(); + private final AtomicLong seed = new AtomicLong(); public String getGenClassName(Class clazz) { return "Fastjson_ASM_" + clazz.getSimpleName() + "_" + seed.incrementAndGet(); } public String getGenFieldDeserializer(Class clazz, FieldInfo fieldInfo) { - Method method = fieldInfo.getMethod(); - return "Fastjson_ASM__Field_" + clazz.getSimpleName() + "_" + method.getName() + "_" + seed.incrementAndGet(); + String name = "Fastjson_ASM__Field_" + clazz.getSimpleName(); + name += "_" + fieldInfo.getName() + "_" + seed.incrementAndGet(); + + return name; } public ASMDeserializerFactory(){ + classLoader = new ASMClassLoader(); + } + public ASMDeserializerFactory(ClassLoader parentClassLoader){ + classLoader = new ASMClassLoader(parentClassLoader); } public final static ASMDeserializerFactory getInstance() { return instance; } - public ObjectDeserializer createJavaBeanDeserializer(ParserConfig config, Class clazz) throws Exception { + public boolean isExternalClass(Class clazz) { + return classLoader.isExternalClass(clazz); + } + + public ObjectDeserializer createJavaBeanDeserializer(ParserConfig config, Class clazz, Type type) + throws Exception { if (clazz.isPrimitive()) { throw new IllegalArgumentException("not support type :" + clazz.getName()); } @@ -65,20 +79,30 @@ public ObjectDeserializer createJavaBeanDeserializer(ParserConfig config, Class< String className = getGenClassName(clazz); ClassWriter cw = new ClassWriter(); - cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, className, getType(ASMJavaBeanDeserializer.class), null); - - List fieldInfoList = new ArrayList(); - JavaBeanDeserializer.computeSetters(clazz, fieldInfoList); + cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, className, "com/alibaba/fastjson/parser/deserializer/ASMJavaBeanDeserializer", null); - _init(cw, new Context(fieldInfoList, className, config, clazz, 3)); - _createInstance(cw, new Context(fieldInfoList, className, config, clazz, 3)); - _parseField(cw, new Context(fieldInfoList, className, config, clazz, 4)); - _deserialze(cw, new Context(fieldInfoList, className, config, clazz, 3)); + DeserializeBeanInfo beanInfo = DeserializeBeanInfo.computeSetters(clazz, type); + _init(cw, new Context(className, config, beanInfo, 3)); + _createInstance(cw, new Context(className, config, beanInfo, 3)); + _deserialze(cw, new Context(className, config, beanInfo, 4)); + _deserialzeArrayMapping(cw, new Context(className, config, beanInfo, 4)); byte[] code = cw.toByteArray(); - // org.apache.commons.io.IOUtils.write(code, new - // java.io.FileOutputStream("/usr/alibaba/workspace/fastjson-asm/target/classes/" + className + ".class")); + if(JSON.DUMP_CLASS != null){ + FileOutputStream fos=null; + try { + fos=new FileOutputStream(JSON.DUMP_CLASS+ File.separator + + className + ".class"); + fos.write(code); + }catch (Exception ex){ + System.err.println("FASTJSON dump class:"+className+"失败:"+ex.getMessage()); + }finally { + if(fos!=null){ + fos.close(); + } + } + } Class exampleClass = classLoader.defineClassPublic(className, code, 0, code.length); @@ -88,14 +112,171 @@ public ObjectDeserializer createJavaBeanDeserializer(ParserConfig config, Class< return (ObjectDeserializer) instance; } + void _setFlag(MethodVisitor mw, Context context, int i) { + String varName = "_asm_flag_" + (i / 32); + + mw.visitVarInsn(ILOAD, context.var(varName)); + mw.visitLdcInsn(1 << i); + mw.visitInsn(IOR); + mw.visitVarInsn(ISTORE, context.var(varName)); + } + + void _isFlag(MethodVisitor mw, Context context, int i, Label label) { + mw.visitVarInsn(ILOAD, context.var("_asm_flag_" + (i / 32))); + mw.visitLdcInsn(1 << i); + mw.visitInsn(IAND); + + mw.visitJumpInsn(IFEQ, label); + } + + void _deserialzeArrayMapping(ClassWriter cw, Context context) { + MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "deserialzeArrayMapping" + , "(Lcom/alibaba/fastjson/parser/DefaultJSONParser;Ljava/lang/reflect/Type;Ljava/lang/Object;)Ljava/lang/Object;" + , null, null); + + defineVarLexer(context, mw); + + _createInstance(context, mw); + + List sortedFieldInfoList = context.getBeanInfo().getSortedFieldList(); + int fieldListSize = sortedFieldInfoList.size(); + for (int i = 0; i < fieldListSize; ++i) { + final boolean last = (i == fieldListSize - 1); + final char seperator = last ? ']' : ','; + + FieldInfo fieldInfo = sortedFieldInfoList.get(i); + Class fieldClass = fieldInfo.getFieldClass(); + Type fieldType = fieldInfo.getFieldType(); + if (fieldClass == byte.class // + || fieldClass == short.class // + || fieldClass == int.class) { + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanInt", "(C)I"); + mw.visitVarInsn(ISTORE, context.var(fieldInfo.getName() + "_asm")); + } else if (fieldClass == long.class) { + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanLong", "(C)J"); + mw.visitVarInsn(LSTORE, context.var(fieldInfo.getName() + "_asm", 2)); + } else if (fieldClass == boolean.class) { + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanBoolean", "(C)Z"); + mw.visitVarInsn(ISTORE, context.var(fieldInfo.getName() + "_asm")); + } else if (fieldClass == float.class) { + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanFloat", "(C)F"); + mw.visitVarInsn(FSTORE, context.var(fieldInfo.getName() + "_asm")); + } else if (fieldClass == double.class) { + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanDouble", "(C)D"); + mw.visitVarInsn(DSTORE, context.var(fieldInfo.getName() + "_asm", 2)); + } else if (fieldClass == char.class) { + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanString", "(C)Ljava/lang/String;"); + mw.visitInsn(ICONST_0); + mw.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C"); + mw.visitVarInsn(ISTORE, context.var(fieldInfo.getName() + "_asm")); + } else if (fieldClass == String.class) { + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanString", "(C)Ljava/lang/String;"); + mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm")); + } else if (fieldClass.isEnum()) { + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(fieldClass))); + mw.visitVarInsn(ALOAD, 1); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "getSymbolTable", + "()Lcom/alibaba/fastjson/parser/SymbolTable;"); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanEnum", + "(Ljava/lang/Class;Lcom/alibaba/fastjson/parser/SymbolTable;C)Ljava/lang/Enum;"); + mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast + mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm")); + } else if (Collection.class.isAssignableFrom(fieldClass)) { + Class itemClass = TypeUtils.getCollectionItemClass(fieldType); + if (itemClass == String.class) { + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(fieldClass))); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanStringArray", + "(Ljava/lang/Class;C)Ljava/util/Collection;"); + mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm")); + + } else { + mw.visitVarInsn(ALOAD, 1); + if (i == 0) { + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "LBRACKET", "I"); + } else { + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "COMMA", "I"); + } + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "LBRACKET", "I"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "accept", "(II)V"); + + _newCollection(mw, fieldClass); + mw.visitInsn(DUP); + mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm")); + _getCollectionFieldItemDeser(context, mw, fieldInfo, itemClass); + mw.visitVarInsn(ALOAD, 1); + mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(itemClass))); + mw.visitVarInsn(ALOAD, 3); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/util/ASMUtils", "parseArray", + "(Ljava/util/Collection;" // + + "Lcom/alibaba/fastjson/parser/deserializer/ObjectDeserializer;" // + + "Lcom/alibaba/fastjson/parser/DefaultJSONParser;" // + + "Ljava/lang/reflect/Type;Ljava/lang/Object;)V"); + } + + } else { + mw.visitVarInsn(ALOAD, 1); + if (i == 0) { + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "LBRACKET", "I"); + } else { + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "COMMA", "I"); + } + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "LBRACKET", "I"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "accept", "(II)V"); + + _deserObject(context, mw, fieldInfo, fieldClass); + + mw.visitVarInsn(ALOAD, 1); + if (!last) { + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "COMMA", "I"); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "LBRACKET", "I"); + } else { + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "RBRACKET", "I"); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "EOF", "I"); + } + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "accept", "(II)V"); + continue; + } + } + + _batchSet(context, mw, false); + + // lexer.nextToken(JSONToken.COMMA); + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "COMMA", "I"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "nextToken", "(I)V"); + + mw.visitVarInsn(ALOAD, context.var("instance")); + mw.visitInsn(ARETURN); + mw.visitMaxs(5, context.getVariantCount()); + mw.visitEnd(); + } + void _deserialze(ClassWriter cw, Context context) { if (context.getFieldInfoList().size() == 0) { return; } for (FieldInfo fieldInfo : context.getFieldInfoList()) { - Class fieldClass = fieldInfo.getMethod().getParameterTypes()[0]; - Type fieldType = fieldInfo.getMethod().getGenericParameterTypes()[0]; + Class fieldClass = fieldInfo.getFieldClass(); + Type fieldType = fieldInfo.getFieldType(); if (fieldClass == char.class) { return; @@ -117,90 +298,212 @@ void _deserialze(ClassWriter cw, Context context) { Collections.sort(context.getFieldInfoList()); - MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "deserialze", "(" + getDesc(DefaultExtJSONParser.class) - + getDesc(Type.class) + ")Ljava/lang/Object;", - null, null); + MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "deserialze" + , "(Lcom/alibaba/fastjson/parser/DefaultJSONParser;Ljava/lang/reflect/Type;Ljava/lang/Object;)Ljava/lang/Object;" + , null, null); Label reset_ = new Label(); Label super_ = new Label(); + Label return_ = new Label(); Label end_ = new Label(); - mw.visitVarInsn(ALOAD, 1); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "getLexer", "()" + getDesc(JSONLexer.class)); - mw.visitTypeInsn(CHECKCAST, getType(JSONScanner.class)); // cast - mw.visitVarInsn(ASTORE, context.var("lexer")); + defineVarLexer(context, mw); - mw.visitVarInsn(ALOAD, context.var("lexer")); - mw.visitFieldInsn(GETSTATIC, getType(Feature.class), "SortFeidFastMatch", "L" + getType(Feature.class) + ";"); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "isEnabled", "(" + "L" + getType(Feature.class) - + ";" + ")Z"); + _isEnable(context, mw, Feature.SortFeidFastMatch); mw.visitJumpInsn(IFEQ, super_); - mw.visitVarInsn(ALOAD, context.var("lexer")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "getBufferPosition", "()I"); - mw.visitVarInsn(ISTORE, context.var("mark")); + { + Label next_ = new Label(); + + mw.visitVarInsn(ALOAD, 0); + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitMethodInsn(INVOKESPECIAL, "com/alibaba/fastjson/parser/deserializer/ASMJavaBeanDeserializer", "isSupportArrayToBean", + "(Lcom/alibaba/fastjson/parser/JSONLexer;)Z"); + mw.visitJumpInsn(IFEQ, next_); + //isSupportArrayToBean + + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "token", "()I"); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "LBRACKET", "I"); + mw.visitJumpInsn(IF_ICMPNE, next_); + + mw.visitVarInsn(ALOAD, 0); + mw.visitVarInsn(ALOAD, 1); + mw.visitVarInsn(ALOAD, 2); + mw.visitVarInsn(ALOAD, 3); + mw.visitMethodInsn(INVOKESPECIAL, context.getClassName(), "deserialzeArrayMapping", + "(Lcom/alibaba/fastjson/parser/DefaultJSONParser;Ljava/lang/reflect/Type;Ljava/lang/Object;)Ljava/lang/Object;"); + mw.visitInsn(ARETURN); + + mw.visitLabel(next_); + // deserialzeArrayMapping + } mw.visitVarInsn(ALOAD, context.var("lexer")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "getCurrent", "()C"); - mw.visitVarInsn(ISTORE, context.var("mark_ch")); + mw.visitLdcInsn(context.getClazz().getName()); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanType", "(Ljava/lang/String;)I"); + + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONLexerBase", "NOT_MATCH", "I"); + mw.visitJumpInsn(IF_ICMPEQ, super_); + + mw.visitVarInsn(ALOAD, 1); // parser + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "getContext", + "()Lcom/alibaba/fastjson/parser/ParseContext;"); + mw.visitVarInsn(ASTORE, context.var("mark_context")); + + // ParseContext context = parser.getContext(); + mw.visitInsn(ICONST_0); + mw.visitVarInsn(ISTORE, context.var("matchedCount")); + + _createInstance(context, mw); + + { + mw.visitVarInsn(ALOAD, 1); // parser + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "getContext", + "()Lcom/alibaba/fastjson/parser/ParseContext;"); + mw.visitVarInsn(ASTORE, context.var("context")); + + mw.visitVarInsn(ALOAD, 1); // parser + mw.visitVarInsn(ALOAD, context.var("context")); + mw.visitVarInsn(ALOAD, context.var("instance")); + mw.visitVarInsn(ALOAD, 3); // fieldName + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "setContext", + "(Lcom/alibaba/fastjson/parser/ParseContext;Ljava/lang/Object;Ljava/lang/Object;)Lcom/alibaba/fastjson/parser/ParseContext;"); + mw.visitVarInsn(ASTORE, context.var("childContext")); + } mw.visitVarInsn(ALOAD, context.var("lexer")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "token", "()I"); - mw.visitVarInsn(ISTORE, context.var("mark_token")); + mw.visitFieldInsn(GETFIELD, "com/alibaba/fastjson/parser/JSONLexerBase", "matchStat", "I"); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONLexerBase", "END", "I"); + mw.visitJumpInsn(IF_ICMPEQ, return_); - for (int i = 0, size = context.getFieldInfoList().size(); i < size; ++i) { + mw.visitInsn(ICONST_0); // UNKOWN + mw.visitIntInsn(ISTORE, context.var("matchStat")); + + int fieldListSize = context.getFieldInfoList().size(); + for (int i = 0; i < fieldListSize; i += 32) { + mw.visitInsn(ICONST_0); + mw.visitVarInsn(ISTORE, context.var("_asm_flag_" + (i / 32))); + } + + // declare and init + for (int i = 0; i < fieldListSize; ++i) { FieldInfo fieldInfo = context.getFieldInfoList().get(i); - Class fieldClass = fieldInfo.getMethod().getParameterTypes()[0]; - Type fieldType = fieldInfo.getMethod().getGenericParameterTypes()[0]; + Class fieldClass = fieldInfo.getFieldClass(); - mw.visitVarInsn(ALOAD, context.var("lexer")); - mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C"); - if (fieldClass == boolean.class) { - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldBoolean", "([C)Z"); + if (fieldClass == boolean.class // + || fieldClass == byte.class // + || fieldClass == short.class // + || fieldClass == int.class) { + mw.visitInsn(ICONST_0); mw.visitVarInsn(ISTORE, context.var(fieldInfo.getName() + "_asm")); + } else if (fieldClass == long.class) { + mw.visitInsn(LCONST_0); + mw.visitVarInsn(LSTORE, context.var(fieldInfo.getName() + "_asm", 2)); + } else if (fieldClass == float.class) { + mw.visitInsn(FCONST_0); + mw.visitVarInsn(FSTORE, context.var(fieldInfo.getName() + "_asm")); + } else if (fieldClass == double.class) { + mw.visitInsn(DCONST_0); + mw.visitVarInsn(DSTORE, context.var(fieldInfo.getName() + "_asm", 2)); + } else { + if (fieldClass == String.class) { + Label flagEnd_ = new Label(); + _isEnable(context, mw, Feature.InitStringFieldAsEmpty); + mw.visitJumpInsn(IFEQ, flagEnd_); + _setFlag(mw, context, i); + mw.visitLabel(flagEnd_); + + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "stringDefaultValue", + "()Ljava/lang/String;"); + } else { + mw.visitInsn(ACONST_NULL); + } + + mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast + mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm")); + } + } + + for (int i = 0; i < fieldListSize; ++i) { + FieldInfo fieldInfo = context.getFieldInfoList().get(i); + Class fieldClass = fieldInfo.getFieldClass(); + Type fieldType = fieldInfo.getFieldType(); + + Label notMatch_ = new Label(); + if (fieldClass == boolean.class) { + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanFieldBoolean", "([C)Z"); + mw.visitVarInsn(ISTORE, context.var(fieldInfo.getName() + "_asm")); } else if (fieldClass == byte.class) { - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldInt", "([C)I"); + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanFieldInt", "([C)I"); mw.visitVarInsn(ISTORE, context.var(fieldInfo.getName() + "_asm")); } else if (fieldClass == short.class) { - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldInt", "([C)I"); + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanFieldInt", "([C)I"); mw.visitVarInsn(ISTORE, context.var(fieldInfo.getName() + "_asm")); } else if (fieldClass == int.class) { - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldInt", "([C)I"); + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanFieldInt", "([C)I"); mw.visitVarInsn(ISTORE, context.var(fieldInfo.getName() + "_asm")); } else if (fieldClass == long.class) { - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldLong", "([C)J"); + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanFieldLong", "([C)J"); mw.visitVarInsn(LSTORE, context.var(fieldInfo.getName() + "_asm", 2)); } else if (fieldClass == float.class) { - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldFloat", "([C)F"); + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanFieldFloat", "([C)F"); mw.visitVarInsn(FSTORE, context.var(fieldInfo.getName() + "_asm")); } else if (fieldClass == double.class) { - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldDouble", "([C)D"); + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanFieldDouble", "([C)D"); mw.visitVarInsn(DSTORE, context.var(fieldInfo.getName() + "_asm", 2)); } else if (fieldClass == String.class) { - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldString", + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanFieldString", "([C)Ljava/lang/String;"); mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm")); } else if (fieldClass.isEnum()) { + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C"); Label enumNull_ = new Label(); mw.visitInsn(ACONST_NULL); mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm")); mw.visitVarInsn(ALOAD, 1); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultExtJSONParser.class), "getSymbolTable", - "()" + getDesc(SymbolTable.class)); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "getSymbolTable", + "()Lcom/alibaba/fastjson/parser/SymbolTable;"); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldSymbol", - "([C" + getDesc(SymbolTable.class) + ")Ljava/lang/String;"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanFieldSymbol", + "([CLcom/alibaba/fastjson/parser/SymbolTable;)Ljava/lang/String;"); mw.visitInsn(DUP); mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm_enumName")); @@ -212,24 +515,29 @@ void _deserialze(ClassWriter cw, Context context) { mw.visitLabel(enumNull_); } else if (Collection.class.isAssignableFrom(fieldClass)) { - Class itemType = (Class) ((ParameterizedType) fieldType).getActualTypeArguments()[0]; - if (itemType == String.class) { - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "scanFieldStringArray", - "([C)" + getDesc(ArrayList.class)); + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C"); + + Class itemClass = TypeUtils.getCollectionItemClass(fieldType); + + if (itemClass == String.class) { + mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(fieldClass))); // cast + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "scanFieldStringArray", + "([CLjava/lang/Class;)" + getDesc(Collection.class)); mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm")); } else { - _deserialze_list_obj(context, mw, reset_, fieldInfo, fieldClass, itemType); + _deserialze_list_obj(context, mw, reset_, fieldInfo, fieldClass, itemClass, i); - if (i == size - 1) { + if (i == fieldListSize - 1) { _deserialize_endCheck(context, mw, reset_); } continue; } - } else { - _deserialze_obj(context, mw, reset_, fieldInfo, fieldClass); + _deserialze_obj(context, mw, reset_, fieldInfo, fieldClass, i); - if (i == size - 1) { + if (i == fieldListSize - 1) { _deserialize_endCheck(context, mw, reset_); } @@ -237,173 +545,337 @@ void _deserialze(ClassWriter cw, Context context) { } mw.visitVarInsn(ALOAD, context.var("lexer")); - mw.visitFieldInsn(GETFIELD, getType(JSONScanner.class), "matchStat", "I"); - mw.visitFieldInsn(GETSTATIC, getType(JSONScanner.class), "NOT_MATCH", "I"); + mw.visitFieldInsn(GETFIELD, "com/alibaba/fastjson/parser/JSONLexerBase", "matchStat", "I"); + Label flag_ = new Label(); + // mw.visitInsn(DUP); + mw.visitJumpInsn(IFLE, flag_); + _setFlag(mw, context, i); + mw.visitLabel(flag_); + + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitFieldInsn(GETFIELD, "com/alibaba/fastjson/parser/JSONLexerBase", "matchStat", "I"); + mw.visitInsn(DUP); + mw.visitVarInsn(ISTORE, context.var("matchStat")); + + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONLexerBase", "NOT_MATCH", "I"); mw.visitJumpInsn(IF_ICMPEQ, reset_); - if (i == size - 1) { + // mw.visitFieldInsn(GETSTATIC, getType(System.class), "out", "Ljava/io/PrintStream;"); + // mw.visitVarInsn(ALOAD, context.var("lexer")); + // mw.visitFieldInsn(GETFIELD, "com/alibaba/fastjson/parser/JSONLexerBase", "matchStat", "I"); + // mw.visitMethodInsn(INVOKEVIRTUAL, getType(java.io.PrintStream.class), "println", "(I)V"); + + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitFieldInsn(GETFIELD, "com/alibaba/fastjson/parser/JSONLexerBase", "matchStat", "I"); + mw.visitJumpInsn(IFLE, notMatch_); + + // increment matchedCount + mw.visitVarInsn(ILOAD, context.var("matchedCount")); + mw.visitInsn(ICONST_1); + mw.visitInsn(IADD); + mw.visitVarInsn(ISTORE, context.var("matchedCount")); + + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitFieldInsn(GETFIELD, "com/alibaba/fastjson/parser/JSONLexerBase", "matchStat", "I"); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONLexerBase", "END", "I"); + mw.visitJumpInsn(IF_ICMPEQ, end_); + + // mw.visitFieldInsn(GETSTATIC, getType(System.class), "out", "Ljava/io/PrintStream;"); + // mw.visitVarInsn(ILOAD, context.var("matchedCount")); + // mw.visitMethodInsn(INVOKEVIRTUAL, getType(java.io.PrintStream.class), "println", "(I)V"); + + mw.visitLabel(notMatch_); + + if (i == fieldListSize - 1) { mw.visitVarInsn(ALOAD, context.var("lexer")); - mw.visitFieldInsn(GETFIELD, getType(JSONScanner.class), "matchStat", "I"); - mw.visitFieldInsn(GETSTATIC, getType(JSONScanner.class), "END", "I"); + mw.visitFieldInsn(GETFIELD, "com/alibaba/fastjson/parser/JSONLexerBase", "matchStat", "I"); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONLexerBase", "END", "I"); mw.visitJumpInsn(IF_ICMPNE, reset_); } + } // endFor + + mw.visitLabel(end_); + + if (!context.getClazz().isInterface() && !Modifier.isAbstract(context.getClazz().getModifiers())) { + _batchSet(context, mw); } - mw.visitTypeInsn(NEW, getType(context.getClazz())); - mw.visitInsn(DUP); - mw.visitMethodInsn(INVOKESPECIAL, getType(context.getClazz()), "", "()V"); - mw.visitVarInsn(ASTORE, context.var("instance")); + mw.visitLabel(return_); + + _setContext(context, mw); + mw.visitVarInsn(ALOAD, context.var("instance")); + mw.visitInsn(ARETURN); + + mw.visitLabel(reset_); + _batchSet(context, mw); + mw.visitVarInsn(ALOAD, 0); + mw.visitVarInsn(ALOAD, 1); + mw.visitVarInsn(ALOAD, 2); + mw.visitVarInsn(ALOAD, 3); + mw.visitVarInsn(ALOAD, context.var("instance")); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/deserializer/ASMJavaBeanDeserializer", "parseRest", + "(Lcom/alibaba/fastjson/parser/DefaultJSONParser;Ljava/lang/reflect/Type;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + mw.visitTypeInsn(CHECKCAST, getType(context.getClazz())); // cast + mw.visitInsn(ARETURN); + + mw.visitLabel(super_); + mw.visitVarInsn(ALOAD, 0); + mw.visitVarInsn(ALOAD, 1); + mw.visitVarInsn(ALOAD, 2); + mw.visitVarInsn(ALOAD, 3); + mw.visitMethodInsn(INVOKESPECIAL, "com/alibaba/fastjson/parser/deserializer/ASMJavaBeanDeserializer", "deserialze", + "(Lcom/alibaba/fastjson/parser/DefaultJSONParser;Ljava/lang/reflect/Type;Ljava/lang/Object;)Ljava/lang/Object;"); + mw.visitInsn(ARETURN); + + mw.visitMaxs(5, context.getVariantCount()); + mw.visitEnd(); + } + + private void _isEnable(Context context, MethodVisitor mw, Feature feature) { + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/Feature", feature.name(), "Lcom/alibaba/fastjson/parser/Feature;"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "isEnabled", "(Lcom/alibaba/fastjson/parser/Feature;)Z"); + } + + private void defineVarLexer(Context context, MethodVisitor mw) { + mw.visitVarInsn(ALOAD, 1); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "getLexer", "()Lcom/alibaba/fastjson/parser/JSONLexer;"); + mw.visitTypeInsn(CHECKCAST, "com/alibaba/fastjson/parser/JSONLexerBase"); // cast + mw.visitVarInsn(ASTORE, context.var("lexer")); + } + + private void _createInstance(Context context, MethodVisitor mw) { + Constructor defaultConstructor = context.getBeanInfo().getDefaultConstructor(); + if (Modifier.isPublic(defaultConstructor.getModifiers())) { + mw.visitTypeInsn(NEW, getType(context.getClazz())); + mw.visitInsn(DUP); + mw.visitMethodInsn(INVOKESPECIAL, getType(context.getClazz()), "", "()V"); + + mw.visitVarInsn(ASTORE, context.var("instance")); + } else { + mw.visitVarInsn(ALOAD, 0); + mw.visitVarInsn(ALOAD, 1); + mw.visitMethodInsn(INVOKESPECIAL, "com/alibaba/fastjson/parser/deserializer/ASMJavaBeanDeserializer", "createInstance", + "(Lcom/alibaba/fastjson/parser/DefaultJSONParser;)Ljava/lang/Object;"); + mw.visitTypeInsn(CHECKCAST, getType(context.getClazz())); // cast + mw.visitVarInsn(ASTORE, context.var("instance")); + } + } + + private void _batchSet(Context context, MethodVisitor mw) { + _batchSet(context, mw, true); + } + + private void _batchSet(Context context, MethodVisitor mw, boolean flag) { for (int i = 0, size = context.getFieldInfoList().size(); i < size; ++i) { + Label notSet_ = new Label(); + + if (flag) { + _isFlag(mw, context, i, notSet_); + } + FieldInfo fieldInfo = context.getFieldInfoList().get(i); - Class fieldClass = fieldInfo.getMethod().getParameterTypes()[0]; - Type fieldType = fieldInfo.getMethod().getGenericParameterTypes()[0]; + _loadAndSet(context, mw, fieldInfo); + if (flag) { + mw.visitLabel(notSet_); + } + } + } + + private void _loadAndSet(Context context, MethodVisitor mw, FieldInfo fieldInfo) { + Class fieldClass = fieldInfo.getFieldClass(); + Type fieldType = fieldInfo.getFieldType(); + + if (fieldClass == boolean.class) { mw.visitVarInsn(ALOAD, context.var("instance")); - if (fieldClass == boolean.class) { - mw.visitVarInsn(ILOAD, context.var(fieldInfo.getName() + "_asm")); - } else if (fieldClass == byte.class) { - mw.visitVarInsn(ILOAD, context.var(fieldInfo.getName() + "_asm")); - } else if (fieldClass == short.class) { - mw.visitVarInsn(ILOAD, context.var(fieldInfo.getName() + "_asm")); - } else if (fieldClass == int.class) { - mw.visitVarInsn(ILOAD, context.var(fieldInfo.getName() + "_asm")); - } else if (fieldClass == long.class) { - mw.visitVarInsn(LLOAD, context.var(fieldInfo.getName() + "_asm")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(context.getClazz()), fieldInfo.getMethod().getName(), "(J)V"); - continue; - } else if (fieldClass == float.class) { - mw.visitVarInsn(FLOAD, context.var(fieldInfo.getName() + "_asm")); - } else if (fieldClass == double.class) { - mw.visitVarInsn(DLOAD, context.var(fieldInfo.getName() + "_asm", 2)); - } else if (fieldClass == String.class) { - mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm")); - } else if (fieldClass.isEnum()) { - mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm")); - } else if (Collection.class.isAssignableFrom(fieldClass)) { - Type itemType = ((ParameterizedType) fieldType).getActualTypeArguments()[0]; - if (itemType == String.class) { - mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm")); - mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast - } else { - mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm")); + mw.visitVarInsn(ILOAD, context.var(fieldInfo.getName() + "_asm")); + _set(context, mw, fieldInfo); + } else if (fieldClass == byte.class // + || fieldClass == short.class // + || fieldClass == int.class // + || fieldClass == char.class) { + mw.visitVarInsn(ALOAD, context.var("instance")); + mw.visitVarInsn(ILOAD, context.var(fieldInfo.getName() + "_asm")); + _set(context, mw, fieldInfo); + } else if (fieldClass == long.class) { + mw.visitVarInsn(ALOAD, context.var("instance")); + mw.visitVarInsn(LLOAD, context.var(fieldInfo.getName() + "_asm", 2)); + if (fieldInfo.getMethod() != null) { + mw.visitMethodInsn(INVOKEVIRTUAL, getType(context.getClazz()), fieldInfo.getMethod().getName(), + getDesc(fieldInfo.getMethod())); + if (!fieldInfo.getMethod().getReturnType().equals(Void.TYPE)) { + mw.visitInsn(POP); } + } else { + mw.visitFieldInsn(PUTFIELD, getType(fieldInfo.getDeclaringClass()), fieldInfo.getField().getName(), + getDesc(fieldInfo.getFieldClass())); + } + } else if (fieldClass == float.class) { + mw.visitVarInsn(ALOAD, context.var("instance")); + mw.visitVarInsn(FLOAD, context.var(fieldInfo.getName() + "_asm")); + _set(context, mw, fieldInfo); + } else if (fieldClass == double.class) { + mw.visitVarInsn(ALOAD, context.var("instance")); + mw.visitVarInsn(DLOAD, context.var(fieldInfo.getName() + "_asm", 2)); + _set(context, mw, fieldInfo); + } else if (fieldClass == String.class) { + mw.visitVarInsn(ALOAD, context.var("instance")); + mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm")); + _set(context, mw, fieldInfo); + } else if (fieldClass.isEnum()) { + mw.visitVarInsn(ALOAD, context.var("instance")); + mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm")); + _set(context, mw, fieldInfo); + } else if (Collection.class.isAssignableFrom(fieldClass)) { + mw.visitVarInsn(ALOAD, context.var("instance")); + Type itemType = TypeUtils.getCollectionItemClass(fieldType); + if (itemType == String.class) { + mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm")); + mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast } else { mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm")); } - mw.visitMethodInsn(INVOKEVIRTUAL, getType(fieldInfo.getMethod().getDeclaringClass()), - fieldInfo.getMethod().getName(), getDesc(fieldInfo.getMethod())); + _set(context, mw, fieldInfo); + + } else { + // mw.visitFieldInsn(GETSTATIC, getType(System.class), "out", "Ljava/io/PrintStream;"); + // mw.visitIntInsn(ILOAD, context.var(fieldInfo.getName() + "_asm_flag")); + // mw.visitMethodInsn(INVOKEVIRTUAL, getType(java.io.PrintStream.class), "println", "(I)V"); + + // _isFlag(mw, context, i, notSet_); + + mw.visitVarInsn(ALOAD, context.var("instance")); + mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm")); + _set(context, mw, fieldInfo); + } + } - mw.visitVarInsn(ALOAD, context.var("instance")); - mw.visitInsn(ARETURN); + private void _set(Context context, MethodVisitor mw, FieldInfo fieldInfo) { + if (fieldInfo.getMethod() != null) { + mw.visitMethodInsn(INVOKEVIRTUAL, getType(fieldInfo.getDeclaringClass()), fieldInfo.getMethod().getName(), + getDesc(fieldInfo.getMethod())); - mw.visitLabel(reset_); + if (!fieldInfo.getMethod().getReturnType().equals(Void.TYPE)) { + mw.visitInsn(POP); + } + } else { + mw.visitFieldInsn(PUTFIELD, getType(fieldInfo.getDeclaringClass()), fieldInfo.getField().getName(), + getDesc(fieldInfo.getFieldClass())); + } + } - // void reset(int mark, char mark_ch) - mw.visitVarInsn(ALOAD, context.var("lexer")); - mw.visitVarInsn(ILOAD, context.var("mark")); - mw.visitVarInsn(ILOAD, context.var("mark_ch")); - mw.visitVarInsn(ILOAD, context.var("mark_token")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "reset", "(ICI)V"); + private void _setContext(Context context, MethodVisitor mw) { + mw.visitVarInsn(ALOAD, 1); // parser + mw.visitVarInsn(ALOAD, context.var("context")); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "setContext", + "(Lcom/alibaba/fastjson/parser/ParseContext;)V"); - mw.visitLabel(super_); - mw.visitVarInsn(ALOAD, 0); - mw.visitVarInsn(ALOAD, 1); - mw.visitVarInsn(ALOAD, 2); - mw.visitMethodInsn(INVOKESPECIAL, getType(ASMJavaBeanDeserializer.class), "deserialze", - "(" + getDesc(DefaultExtJSONParser.class) + getDesc(Type.class) + ")Ljava/lang/Object;"); - mw.visitInsn(ARETURN); + Label endIf_ = new Label(); + mw.visitVarInsn(ALOAD, context.var("childContext")); + mw.visitJumpInsn(IFNULL, endIf_); - mw.visitLabel(end_); + mw.visitVarInsn(ALOAD, context.var("childContext")); + mw.visitVarInsn(ALOAD, context.var("instance")); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/ParseContext", "setObject", "(Ljava/lang/Object;)V"); - mw.visitMaxs(4, context.getVariantCount()); - mw.visitEnd(); + mw.visitLabel(endIf_); } private void _deserialize_endCheck(Context context, MethodVisitor mw, Label reset_) { + // Label nextToken_ = new Label(); + + // mw.visitFieldInsn(GETSTATIC, getType(System.class), "out", "Ljava/io/PrintStream;"); + // mw.visitIntInsn(ILOAD, context.var("matchedCount")); + // mw.visitMethodInsn(INVOKEVIRTUAL, getType(java.io.PrintStream.class), "println", "(I)V"); + + mw.visitIntInsn(ILOAD, context.var("matchedCount")); + mw.visitJumpInsn(IFLE, reset_); + + // mw.visitFieldInsn(GETSTATIC, getType(System.class), "out", "Ljava/io/PrintStream;"); + // mw.visitVarInsn(ALOAD, context.var("lexer")); + // mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "token", "()I"); + // mw.visitMethodInsn(INVOKEVIRTUAL, getType(java.io.PrintStream.class), "println", "(I)V"); + mw.visitVarInsn(ALOAD, context.var("lexer")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "token", "()I"); - mw.visitFieldInsn(GETSTATIC, getType(JSONToken.class), "RBRACE", "I"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "token", "()I"); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "RBRACE", "I"); mw.visitJumpInsn(IF_ICMPNE, reset_); + // mw.visitLabel(nextToken_); mw.visitVarInsn(ALOAD, context.var("lexer")); - mw.visitFieldInsn(GETSTATIC, getType(JSONToken.class), "COMMA", "I"); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "nextToken", "(I)V"); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "COMMA", "I"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "nextToken", "(I)V"); } private void _deserialze_list_obj(Context context, MethodVisitor mw, Label reset_, FieldInfo fieldInfo, - Class fieldClass, Class itemType) { - // _asm_list_item_deser__ + Class fieldClass, Class itemType, int i) { + Label _end_if = new Label(); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "matchField", "([C)Z"); - mw.visitJumpInsn(IFEQ, reset_); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "matchField", "([C)Z"); + mw.visitJumpInsn(IFEQ, _end_if); - Label notNull_ = new Label(); - mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_list_item_deser__", - getDesc(ObjectDeserializer.class)); - mw.visitJumpInsn(IFNONNULL, notNull_); - - mw.visitVarInsn(ALOAD, 0); + _setFlag(mw, context, i); - mw.visitVarInsn(ALOAD, 1); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultExtJSONParser.class), "getConfig", - "()" + getDesc(ParserConfig.class)); - mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(itemType))); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(ParserConfig.class), "getDeserializer", - "(" + getDesc(Type.class) + ")" + getDesc(ObjectDeserializer.class)); + Label valueNotNull_ = new Label(); + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "token", "()I"); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "NULL", "I"); + mw.visitJumpInsn(IF_ICMPNE, valueNotNull_); - mw.visitFieldInsn(PUTFIELD, context.getClassName(), fieldInfo.getName() + "_asm_list_item_deser__", - getDesc(ObjectDeserializer.class)); + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "COMMA", "I"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "nextToken", "(I)V"); - mw.visitLabel(notNull_); + // loop_end_ + mw.visitLabel(valueNotNull_); // if (lexer.token() != JSONToken.LBRACKET) reset mw.visitVarInsn(ALOAD, context.var("lexer")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "token", "()I"); - mw.visitFieldInsn(GETSTATIC, getType(JSONToken.class), "LBRACKET", "I"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "token", "()I"); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "LBRACKET", "I"); + mw.visitJumpInsn(IF_ICMPNE, reset_); - mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_list_item_deser__", - getDesc(ObjectDeserializer.class)); - mw.visitMethodInsn(INVOKEINTERFACE, getType(ObjectDeserializer.class), "getFastMatchToken", "()I"); + _getCollectionFieldItemDeser(context, mw, fieldInfo, itemType); + mw.visitMethodInsn(INVOKEINTERFACE, "com/alibaba/fastjson/parser/deserializer/ObjectDeserializer", "getFastMatchToken", "()I"); mw.visitVarInsn(ISTORE, context.var("fastMatchToken")); mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ILOAD, context.var("fastMatchToken")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "nextToken", "(I)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "nextToken", "(I)V"); + + _newCollection(mw, fieldClass); - mw.visitTypeInsn(NEW, getType(ArrayList.class)); - mw.visitInsn(DUP); - mw.visitMethodInsn(INVOKESPECIAL, getType(ArrayList.class), "", "()V"); - mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm")); + { // setContext + mw.visitVarInsn(ALOAD, 1); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "getContext", + "()Lcom/alibaba/fastjson/parser/ParseContext;"); + mw.visitVarInsn(ASTORE, context.var("listContext")); + + mw.visitVarInsn(ALOAD, 1); // parser + mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm")); + mw.visitLdcInsn(fieldInfo.getName()); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "setContext", + "(Ljava/lang/Object;Ljava/lang/Object;)Lcom/alibaba/fastjson/parser/ParseContext;"); + mw.visitInsn(POP); + } + Label loop_ = new Label(); Label loop_end_ = new Label(); // for (;;) { + mw.visitInsn(ICONST_0); + mw.visitVarInsn(ISTORE, context.var("i")); mw.visitLabel(loop_); - // if (lexer.isEnabled(Feature.AllowArbitraryCommas)) { - // while (lexer.token() == JSONToken.COMMA) { - // lexer.nextToken(); - // continue; - // } - // } - // mw.visitVarInsn(ALOAD, context.var("lexer")); - // mw.visitFieldInsn(GETSTATIC, getType(Feature.class), "AllowArbitraryCommas", "L" + getType(Feature.class) + - // ";"); - // mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "isEnabled", "(" + "L" + getType(Feature.class) - // + ";" + ")Z"); - // if (lexer.token() == JSONToken.RBRACKET) { - // break; - // } mw.visitVarInsn(ALOAD, context.var("lexer")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "token", "()I"); - mw.visitFieldInsn(GETSTATIC, getType(JSONToken.class), "RBRACKET", "I"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "token", "()I"); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "RBRACKET", "I"); mw.visitJumpInsn(IF_ICMPEQ, loop_end_); // Object value = itemDeserializer.deserialze(parser, null); @@ -411,13 +883,17 @@ private void _deserialze_list_obj(Context context, MethodVisitor mw, Label reset mw.visitVarInsn(ALOAD, 0); mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_list_item_deser__", - getDesc(ObjectDeserializer.class)); + "Lcom/alibaba/fastjson/parser/deserializer/ObjectDeserializer;"); mw.visitVarInsn(ALOAD, 1); - mw.visitInsn(ACONST_NULL); - mw.visitMethodInsn(INVOKEINTERFACE, getType(ObjectDeserializer.class), "deserialze", - "(Lcom/alibaba/fastjson/parser/DefaultExtJSONParser;Ljava/lang/reflect/Type;)Ljava/lang/Object;"); + mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(itemType))); + mw.visitVarInsn(ILOAD, context.var("i")); + mw.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); + mw.visitMethodInsn(INVOKEINTERFACE, "com/alibaba/fastjson/parser/deserializer/ObjectDeserializer", "deserialze", + "(Lcom/alibaba/fastjson/parser/DefaultJSONParser;Ljava/lang/reflect/Type;Ljava/lang/Object;)Ljava/lang/Object;"); mw.visitVarInsn(ASTORE, context.var("list_item_value")); + mw.visitIincInsn(context.var("i"), 1); + mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm")); mw.visitVarInsn(ALOAD, context.var("list_item_value")); if (fieldClass.isInterface()) { @@ -427,69 +903,207 @@ private void _deserialze_list_obj(Context context, MethodVisitor mw, Label reset } mw.visitInsn(POP); + mw.visitVarInsn(ALOAD, 1); + mw.visitVarInsn(ALOAD, context.var(fieldInfo.getName() + "_asm")); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "checkListResolve", + "(Ljava/util/Collection;)V"); + // if (lexer.token() == JSONToken.COMMA) { // lexer.nextToken(itemDeserializer.getFastMatchToken()); // continue; // } mw.visitVarInsn(ALOAD, context.var("lexer")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "token", "()I"); - mw.visitFieldInsn(GETSTATIC, getType(JSONToken.class), "COMMA", "I"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "token", "()I"); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "COMMA", "I"); mw.visitJumpInsn(IF_ICMPNE, loop_); mw.visitVarInsn(ALOAD, context.var("lexer")); mw.visitVarInsn(ILOAD, context.var("fastMatchToken")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "nextToken", "(I)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "nextToken", "(I)V"); mw.visitJumpInsn(GOTO, loop_); mw.visitLabel(loop_end_); + // mw.visitVarInsn(ASTORE, context.var("context")); + // parser.setContext(context); + { // setContext + mw.visitVarInsn(ALOAD, 1); // parser + mw.visitVarInsn(ALOAD, context.var("listContext")); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "setContext", + "(Lcom/alibaba/fastjson/parser/ParseContext;)V"); + } + mw.visitVarInsn(ALOAD, context.var("lexer")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "token", "()I"); - mw.visitFieldInsn(GETSTATIC, getType(JSONToken.class), "RBRACKET", "I"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "token", "()I"); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "RBRACKET", "I"); mw.visitJumpInsn(IF_ICMPNE, reset_); mw.visitVarInsn(ALOAD, context.var("lexer")); - mw.visitFieldInsn(GETSTATIC, getType(JSONToken.class), "COMMA", "I"); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "nextToken", "(I)V"); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/JSONToken", "COMMA", "I"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "nextToken", "(I)V"); // lexer.nextToken(JSONToken.COMMA); + mw.visitLabel(_end_if); + } + + private void _getCollectionFieldItemDeser(Context context, MethodVisitor mw, FieldInfo fieldInfo, Class itemType) { + Label notNull_ = new Label(); + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_list_item_deser__", + "Lcom/alibaba/fastjson/parser/deserializer/ObjectDeserializer;"); + mw.visitJumpInsn(IFNONNULL, notNull_); + + mw.visitVarInsn(ALOAD, 0); + + mw.visitVarInsn(ALOAD, 1); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "getConfig", "()" + + "Lcom/alibaba/fastjson/parser/ParserConfig;"); + mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(itemType))); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/ParserConfig", "getDeserializer", + "(Ljava/lang/reflect/Type;)Lcom/alibaba/fastjson/parser/deserializer/ObjectDeserializer;"); + + mw.visitFieldInsn(PUTFIELD, context.getClassName(), fieldInfo.getName() + "_asm_list_item_deser__", + "Lcom/alibaba/fastjson/parser/deserializer/ObjectDeserializer;"); + + mw.visitLabel(notNull_); + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_list_item_deser__", + "Lcom/alibaba/fastjson/parser/deserializer/ObjectDeserializer;"); + } + + private void _newCollection(MethodVisitor mw, Class fieldClass) { + if (fieldClass.isAssignableFrom(ArrayList.class)) { + mw.visitTypeInsn(NEW, "java/util/ArrayList"); + mw.visitInsn(DUP); + mw.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList", "", "()V"); + } else if (fieldClass.isAssignableFrom(LinkedList.class)) { + mw.visitTypeInsn(NEW, getType(LinkedList.class)); + mw.visitInsn(DUP); + mw.visitMethodInsn(INVOKESPECIAL, getType(LinkedList.class), "", "()V"); + } else if (fieldClass.isAssignableFrom(HashSet.class)) { + mw.visitTypeInsn(NEW, getType(HashSet.class)); + mw.visitInsn(DUP); + mw.visitMethodInsn(INVOKESPECIAL, getType(HashSet.class), "", "()V"); + } else if (fieldClass.isAssignableFrom(TreeSet.class)) { + mw.visitTypeInsn(NEW, getType(TreeSet.class)); + mw.visitInsn(DUP); + mw.visitMethodInsn(INVOKESPECIAL, getType(TreeSet.class), "", "()V"); + } else { + mw.visitTypeInsn(NEW, getType(fieldClass)); + mw.visitInsn(DUP); + mw.visitMethodInsn(INVOKESPECIAL, getType(fieldClass), "", "()V"); + } + mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast } private void _deserialze_obj(Context context, MethodVisitor mw, Label reset_, FieldInfo fieldInfo, - Class fieldClass) { - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONScanner.class), "matchField", "([C)Z"); - mw.visitJumpInsn(IFEQ, reset_); + Class fieldClass, int i) { + Label matched_ = new Label(); + Label _end_if = new Label(); + + mw.visitVarInsn(ALOAD, context.var("lexer")); + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/JSONLexerBase", "matchField", "([C)Z"); + mw.visitJumpInsn(IFNE, matched_); + mw.visitInsn(ACONST_NULL); + mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm")); + + mw.visitJumpInsn(GOTO, _end_if); + + mw.visitLabel(matched_); + + _setFlag(mw, context, i); + + // increment matchedCount + mw.visitVarInsn(ILOAD, context.var("matchedCount")); + mw.visitInsn(ICONST_1); + mw.visitInsn(IADD); + mw.visitVarInsn(ISTORE, context.var("matchedCount")); + + _deserObject(context, mw, fieldInfo, fieldClass); + + mw.visitVarInsn(ALOAD, 1); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "getResolveStatus", "()I"); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/DefaultJSONParser", "NeedToResolve", "I"); + mw.visitJumpInsn(IF_ICMPNE, _end_if); + + // ResolveTask task = parser.getLastResolveTask(); + // task.setFieldDeserializer(this); + // task.setOwnerContext(parser.getContext()); + + mw.visitVarInsn(ALOAD, 1); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "getLastResolveTask", + "()Lcom/alibaba/fastjson/parser/DefaultJSONParser$ResolveTask;"); + mw.visitVarInsn(ASTORE, context.var("resolveTask")); + + mw.visitVarInsn(ALOAD, context.var("resolveTask")); + mw.visitVarInsn(ALOAD, 1); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "getContext", "()" + + "Lcom/alibaba/fastjson/parser/ParseContext;"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser$ResolveTask" + , "setOwnerContext" + , "(Lcom/alibaba/fastjson/parser/ParseContext;)V"); + + mw.visitVarInsn(ALOAD, context.var("resolveTask")); + mw.visitVarInsn(ALOAD, 0); + mw.visitLdcInsn(fieldInfo.getName()); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/deserializer/ASMJavaBeanDeserializer", "getFieldDeserializer", + "(Ljava/lang/String;)Lcom/alibaba/fastjson/parser/deserializer/FieldDeserializer;"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser$ResolveTask", "setFieldDeserializer", + "(Lcom/alibaba/fastjson/parser/deserializer/FieldDeserializer;)V"); + + mw.visitVarInsn(ALOAD, 1); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/parser/DefaultJSONParser", "NONE", "I"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "setResolveStatus", "(I)V"); + + mw.visitLabel(_end_if); + + } + + private void _deserObject(Context context, MethodVisitor mw, FieldInfo fieldInfo, Class fieldClass) { + _getFieldDeser(context, mw, fieldInfo); + + mw.visitVarInsn(ALOAD, 1); + if (fieldInfo.getFieldType() instanceof Class) { + mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(fieldInfo.getFieldClass()))); + } else { + mw.visitVarInsn(ALOAD, 0); + mw.visitLdcInsn(fieldInfo.getName()); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/deserializer/ASMJavaBeanDeserializer", "getFieldType", + "(Ljava/lang/String;)Ljava/lang/reflect/Type;"); + } + mw.visitLdcInsn(fieldInfo.getName()); + mw.visitMethodInsn(INVOKEINTERFACE, "com/alibaba/fastjson/parser/deserializer/ObjectDeserializer", "deserialze", + "(Lcom/alibaba/fastjson/parser/DefaultJSONParser;Ljava/lang/reflect/Type;Ljava/lang/Object;)Ljava/lang/Object;"); + mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast + mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm")); + } + private void _getFieldDeser(Context context, MethodVisitor mw, FieldInfo fieldInfo) { Label notNull_ = new Label(); mw.visitVarInsn(ALOAD, 0); mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_deser__", - getDesc(ObjectDeserializer.class)); + "Lcom/alibaba/fastjson/parser/deserializer/ObjectDeserializer;"); mw.visitJumpInsn(IFNONNULL, notNull_); mw.visitVarInsn(ALOAD, 0); mw.visitVarInsn(ALOAD, 1); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultExtJSONParser.class), "getConfig", - "()" + getDesc(ParserConfig.class)); - mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(fieldInfo.getMethod().getParameterTypes()[0]))); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(ParserConfig.class), "getDeserializer", - "(" + getDesc(Type.class) + ")" + getDesc(ObjectDeserializer.class)); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/DefaultJSONParser", "getConfig", "()" + + "Lcom/alibaba/fastjson/parser/ParserConfig;"); + mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(fieldInfo.getFieldClass()))); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/ParserConfig", "getDeserializer", + "(Ljava/lang/reflect/Type;)Lcom/alibaba/fastjson/parser/deserializer/ObjectDeserializer;"); mw.visitFieldInsn(PUTFIELD, context.getClassName(), fieldInfo.getName() + "_asm_deser__", - getDesc(ObjectDeserializer.class)); + "Lcom/alibaba/fastjson/parser/deserializer/ObjectDeserializer;"); mw.visitLabel(notNull_); mw.visitVarInsn(ALOAD, 0); mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_deser__", - getDesc(ObjectDeserializer.class)); - mw.visitVarInsn(ALOAD, 1); - mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(fieldInfo.getMethod().getParameterTypes()[0]))); - mw.visitMethodInsn(INVOKEINTERFACE, getType(ObjectDeserializer.class), "deserialze", - "(" + getDesc(DefaultExtJSONParser.class) + getDesc(Type.class) + ")Ljava/lang/Object;"); - mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast - mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm")); - + "Lcom/alibaba/fastjson/parser/deserializer/ObjectDeserializer;"); } public FieldDeserializer createFieldDeserializer(ParserConfig mapping, Class clazz, FieldInfo fieldInfo) @@ -521,59 +1135,70 @@ public FieldDeserializer createStringFieldDeserializer(ParserConfig mapping, Cla superClass = StringFieldDeserializer.class; } + int INVAKE_TYPE; + if (clazz.isInterface()) { + INVAKE_TYPE = INVOKEINTERFACE; + } else { + INVAKE_TYPE = INVOKEVIRTUAL; + } + cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, className, getType(superClass), null); { - MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "", "(" + getDesc(ParserConfig.class) - + getDesc(Class.class) + getDesc(FieldInfo.class) - + ")V", null, null); + MethodVisitor mw = cw.visitMethod(ACC_PUBLIC // + , "" // + , "(Lcom/alibaba/fastjson/parser/ParserConfig;Ljava/lang/Class;Lcom/alibaba/fastjson/util/FieldInfo;)V", null, null); mw.visitVarInsn(ALOAD, 0); mw.visitVarInsn(ALOAD, 1); mw.visitVarInsn(ALOAD, 2); mw.visitVarInsn(ALOAD, 3); - mw.visitMethodInsn(INVOKESPECIAL, getType(superClass), "", "(" + getDesc(ParserConfig.class) - + getDesc(Class.class) - + getDesc(FieldInfo.class) + ")V"); + mw.visitMethodInsn(INVOKESPECIAL, getType(superClass), "" + , "(Lcom/alibaba/fastjson/parser/ParserConfig;Ljava/lang/Class;Lcom/alibaba/fastjson/util/FieldInfo;)V"); mw.visitInsn(RETURN); mw.visitMaxs(4, 6); mw.visitEnd(); } - if (fieldClass == int.class) { - MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "setValue", "(" + getDesc(Object.class) + "I)V", null, null); - mw.visitVarInsn(ALOAD, 1); - mw.visitTypeInsn(CHECKCAST, getType(method.getDeclaringClass())); // cast - mw.visitVarInsn(ILOAD, 2); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(method.getDeclaringClass()), method.getName(), "(I)V"); - - mw.visitInsn(RETURN); - mw.visitMaxs(3, 3); - mw.visitEnd(); - } else if (fieldClass == long.class) { - MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "setValue", "(" + getDesc(Object.class) + "J)V", null, null); - mw.visitVarInsn(ALOAD, 1); - mw.visitTypeInsn(CHECKCAST, getType(method.getDeclaringClass())); // cast - mw.visitVarInsn(LLOAD, 2); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(method.getDeclaringClass()), method.getName(), "(J)V"); - - mw.visitInsn(RETURN); - mw.visitMaxs(3, 4); - mw.visitEnd(); - } else { - // public void setValue(Object object, Object value) - MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "setValue", "(" + getDesc(Object.class) - + getDesc(Object.class) + ")V", null, null); - mw.visitVarInsn(ALOAD, 1); - mw.visitTypeInsn(CHECKCAST, getType(method.getDeclaringClass())); // cast - mw.visitVarInsn(ALOAD, 2); - mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast - mw.visitMethodInsn(INVOKEVIRTUAL, getType(method.getDeclaringClass()), method.getName(), - "(" + getDesc(fieldClass) + ")V"); + if (method != null) { + if (fieldClass == int.class) { + MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "setValue", "(Ljava/lang/Object;I)V", null, + null); + mw.visitVarInsn(ALOAD, 1); + mw.visitTypeInsn(CHECKCAST, getType(method.getDeclaringClass())); // cast + mw.visitVarInsn(ILOAD, 2); + mw.visitMethodInsn(INVAKE_TYPE, getType(method.getDeclaringClass()), method.getName(), + ASMUtils.getDesc(method)); + + mw.visitInsn(RETURN); + mw.visitMaxs(3, 3); + mw.visitEnd(); + } else if (fieldClass == long.class) { + MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "setValue", "(Ljava/lang/Object;J)V", null, + null); + mw.visitVarInsn(ALOAD, 1); + mw.visitTypeInsn(CHECKCAST, getType(method.getDeclaringClass())); // cast + mw.visitVarInsn(LLOAD, 2); + mw.visitMethodInsn(INVAKE_TYPE, getType(method.getDeclaringClass()), method.getName(), + ASMUtils.getDesc(method)); + + mw.visitInsn(RETURN); + mw.visitMaxs(3, 4); + mw.visitEnd(); + } else { + // public void setValue(Object object, Object value) + MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "setValue", "(Ljava/lang/Object;Ljava/lang/Object;)V", null, null); + mw.visitVarInsn(ALOAD, 1); + mw.visitTypeInsn(CHECKCAST, getType(method.getDeclaringClass())); // cast + mw.visitVarInsn(ALOAD, 2); + mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast + mw.visitMethodInsn(INVAKE_TYPE, getType(method.getDeclaringClass()), method.getName(), + ASMUtils.getDesc(method)); - mw.visitInsn(RETURN); - mw.visitMaxs(3, 3); - mw.visitEnd(); + mw.visitInsn(RETURN); + mw.visitMaxs(3, 3); + mw.visitEnd(); + } } byte[] code = cw.toByteArray(); @@ -588,20 +1213,21 @@ public FieldDeserializer createStringFieldDeserializer(ParserConfig mapping, Cla static class Context { - private int variantIndex = 4; + private int variantIndex = 5; - private Map variants = new HashMap(); + private Map variants = new HashMap(); - private Class clazz; - private List fieldInfoList; - private String className; + private Class clazz; + private final DeserializeBeanInfo beanInfo; + private String className; + private List fieldInfoList; - public Context(List fieldInfoList, String className, ParserConfig config, Class clazz, - int initVariantIndex){ + public Context(String className, ParserConfig config, DeserializeBeanInfo beanInfo, int initVariantIndex){ this.className = className; - this.fieldInfoList = fieldInfoList; - this.clazz = clazz; + this.clazz = beanInfo.getClazz(); this.variantIndex = initVariantIndex; + this.beanInfo = beanInfo; + fieldInfoList = new ArrayList(beanInfo.getFieldList()); } public String getClassName() { @@ -612,6 +1238,10 @@ public List getFieldInfoList() { return fieldInfoList; } + public DeserializeBeanInfo getBeanInfo() { + return beanInfo; + } + public Class getClazz() { return clazz; } @@ -652,38 +1282,39 @@ private void _init(ClassWriter cw, Context context) { for (int i = 0, size = context.getFieldInfoList().size(); i < size; ++i) { FieldInfo fieldInfo = context.getFieldInfoList().get(i); - Class fieldClass = fieldInfo.getMethod().getParameterTypes()[0]; + Class fieldClass = fieldInfo.getFieldClass(); if (fieldClass.isPrimitive()) { continue; } if (fieldClass.isEnum()) { + continue; + } - } else if (Collection.class.isAssignableFrom(fieldClass)) { + if (Collection.class.isAssignableFrom(fieldClass)) { FieldVisitor fw = cw.visitField(ACC_PUBLIC, fieldInfo.getName() + "_asm_list_item_deser__", - getDesc(ObjectDeserializer.class)); + "Lcom/alibaba/fastjson/parser/deserializer/ObjectDeserializer;"); fw.visitEnd(); } else { FieldVisitor fw = cw.visitField(ACC_PUBLIC, fieldInfo.getName() + "_asm_deser__", - getDesc(ObjectDeserializer.class)); + "Lcom/alibaba/fastjson/parser/deserializer/ObjectDeserializer;"); fw.visitEnd(); } } - MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "", "(" + getDesc(ParserConfig.class) - + getDesc(Class.class) + ")V", null, null); + MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "", "(Lcom/alibaba/fastjson/parser/ParserConfig;Ljava/lang/Class;)V", null, null); mw.visitVarInsn(ALOAD, 0); mw.visitVarInsn(ALOAD, 1); mw.visitVarInsn(ALOAD, 2); - mw.visitMethodInsn(INVOKESPECIAL, getType(ASMJavaBeanDeserializer.class), "", - "(" + getDesc(ParserConfig.class) + getDesc(Class.class) + ")V"); + mw.visitMethodInsn(INVOKESPECIAL, "com/alibaba/fastjson/parser/deserializer/ASMJavaBeanDeserializer", "", + "(Lcom/alibaba/fastjson/parser/ParserConfig;Ljava/lang/Class;)V"); mw.visitVarInsn(ALOAD, 0); - mw.visitFieldInsn(GETFIELD, getType(ASMJavaBeanDeserializer.class), "serializer", - getDesc(InnerJavaBeanDeserializer.class)); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JavaBeanDeserializer.class), "getFieldDeserializerMap", - "()" + getDesc(Map.class)); + mw.visitFieldInsn(GETFIELD, "com/alibaba/fastjson/parser/deserializer/ASMJavaBeanDeserializer", "serializer", + "Lcom/alibaba/fastjson/parser/deserializer/ASMJavaBeanDeserializer$InnerJavaBeanDeserializer;"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/parser/deserializer/JavaBeanDeserializer", "getFieldDeserializerMap", + "()Ljava/util/Map;"); mw.visitInsn(POP); // init fieldNamePrefix @@ -692,7 +1323,7 @@ private void _init(ClassWriter cw, Context context) { mw.visitVarInsn(ALOAD, 0); mw.visitLdcInsn("\"" + fieldInfo.getName() + "\":"); // public char[] toCharArray() - mw.visitMethodInsn(INVOKEVIRTUAL, getType(String.class), "toCharArray", "()" + getDesc(char[].class)); + mw.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "toCharArray", "()[C"); mw.visitFieldInsn(PUTFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C"); } @@ -703,35 +1334,17 @@ private void _init(ClassWriter cw, Context context) { } private void _createInstance(ClassWriter cw, Context context) { - MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "createInstance", "(" + getDesc(DefaultExtJSONParser.class) - + getDesc(Type.class) + ")Ljava/lang/Object;", + MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "createInstance" + , "(Lcom/alibaba/fastjson/parser/DefaultJSONParser;Ljava/lang/reflect/Type;)Ljava/lang/Object;", null, null); + mw.visitTypeInsn(NEW, getType(context.getClazz())); mw.visitInsn(DUP); mw.visitMethodInsn(INVOKESPECIAL, getType(context.getClazz()), "", "()V"); + mw.visitInsn(ARETURN); mw.visitMaxs(3, 3); mw.visitEnd(); } - private void _parseField(ClassWriter cw, Context context) { - // public boolean parseField(DefaultExtJSONParser parser, String key, Object object) { - - MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "parseField", "(" + getDesc(DefaultExtJSONParser.class) - + getDesc(String.class) + getDesc(Object.class) - + ")Z", null, null); - - mw.visitVarInsn(ALOAD, 0); - mw.visitVarInsn(ALOAD, 1); - mw.visitVarInsn(ALOAD, 2); - mw.visitVarInsn(ALOAD, 3); - mw.visitMethodInsn(INVOKESPECIAL, getType(ASMJavaBeanDeserializer.class), "parseField", - "(" + getDesc(DefaultExtJSONParser.class) + getDesc(String.class) + getDesc(Object.class) - + ")Z"); - mw.visitInsn(IRETURN); - mw.visitMaxs(5, context.getVariantCount() + 1); - mw.visitEnd(); - - } - } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ASMJavaBeanDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ASMJavaBeanDeserializer.java old mode 100644 new mode 100755 index 1a2efeb96e..42b0780759 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/ASMJavaBeanDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/ASMJavaBeanDeserializer.java @@ -1,11 +1,10 @@ package com.alibaba.fastjson.parser.deserializer; import java.lang.reflect.Type; +import java.util.Map; -import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.Feature; -import com.alibaba.fastjson.parser.JSONScanner; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.util.FieldInfo; @@ -19,43 +18,60 @@ public ASMJavaBeanDeserializer(ParserConfig mapping, Class clazz){ serializer.getFieldDeserializerMap(); } - public abstract Object createInstance(DefaultExtJSONParser parser, Type type); + public abstract Object createInstance(DefaultJSONParser parser, Type type); public InnerJavaBeanDeserializer getInnterSerializer() { return serializer; } @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type type) { - return (T) serializer.deserialze(parser, type); + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + return (T) serializer.deserialze(parser, type, fieldName); } public int getFastMatchToken() { return serializer.getFastMatchToken(); } + public Object createInstance(DefaultJSONParser parser) { + return serializer.createInstance(parser, serializer.getClazz()); + } + public FieldDeserializer createFieldDeserializer(ParserConfig mapping, Class clazz, FieldInfo fieldInfo) { return mapping.createFieldDeserializer(mapping, clazz, fieldInfo); } - public boolean parseField(DefaultExtJSONParser parser, String key, Object object) { - JSONScanner lexer = (JSONScanner) parser.getLexer(); // xxx + public FieldDeserializer getFieldDeserializer(String name) { + return serializer.getFieldDeserializerMap().get(name); + } + + public Type getFieldType(String name) { + return serializer.getFieldDeserializerMap().get(name).getFieldType(); + } + + public boolean parseField(DefaultJSONParser parser, String key, Object object, Type objectType, + Map fieldValues) { + JSONLexer lexer = parser.getLexer(); // xxx - FieldDeserializer fieldDeserializer = serializer.getFieldDeserializerMap().get(key); + Map feildDeserializerMap = serializer.getFieldDeserializerMap(); + FieldDeserializer fieldDeserializer = feildDeserializerMap.get(key); if (fieldDeserializer == null) { - if (!parser.isEnabled(Feature.IgnoreNotMatch)) { - throw new JSONException("setter not found, class " + serializer.getClass() + ", property " + key); + for (Map.Entry entry : feildDeserializerMap.entrySet()) { + if (entry.getKey().equalsIgnoreCase(key)) { + fieldDeserializer = entry.getValue(); + break; + } } + } - lexer.nextTokenWithColon(); - parser.parse(); // skip - + if (fieldDeserializer == null) { + this.serializer.parseExtra(parser, object, key); return false; } lexer.nextTokenWithColon(fieldDeserializer.getFastMatchToken()); - fieldDeserializer.parseField(parser, object); + fieldDeserializer.parseField(parser, object, objectType, fieldValues); return true; } @@ -65,13 +81,24 @@ private InnerJavaBeanDeserializer(ParserConfig mapping, Class clazz){ super(mapping, clazz); } - public boolean parseField(DefaultExtJSONParser parser, String key, Object object) { - return ASMJavaBeanDeserializer.this.parseField(parser, key, object); + public boolean parseField(DefaultJSONParser parser, String key, Object object, Type objectType, + Map fieldValues) { + return ASMJavaBeanDeserializer.this.parseField(parser, key, object, objectType, fieldValues); } public FieldDeserializer createFieldDeserializer(ParserConfig mapping, Class clazz, FieldInfo fieldInfo) { return ASMJavaBeanDeserializer.this.createFieldDeserializer(mapping, clazz, fieldInfo); } } + + public boolean isSupportArrayToBean(JSONLexer lexer) { + return serializer.isSupportArrayToBean(lexer); + } + public Object parseRest(DefaultJSONParser parser, Type type, Object fieldName, Object instance) { +// serializer.parseField(parser, key, object, objectType, fieldValues) + Object value = serializer.deserialze(parser, type, fieldName, instance); + + return value; + } } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/AbstractDateDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/AbstractDateDeserializer.java new file mode 100755 index 0000000000..f44441196a --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/AbstractDateDeserializer.java @@ -0,0 +1,102 @@ +package com.alibaba.fastjson.parser.deserializer; + +import java.lang.reflect.Type; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONScanner; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.util.TypeUtils; + +public abstract class AbstractDateDeserializer implements ObjectDeserializer { + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + JSONLexer lexer = parser.getLexer(); + + Object val; + if (lexer.token() == JSONToken.LITERAL_INT) { + val = lexer.longValue(); + lexer.nextToken(JSONToken.COMMA); + } else if (lexer.token() == JSONToken.LITERAL_STRING) { + String strVal = lexer.stringVal(); + val = strVal; + lexer.nextToken(JSONToken.COMMA); + + if (lexer.isEnabled(Feature.AllowISO8601DateFormat)) { + JSONScanner iso8601Lexer = new JSONScanner(strVal); + if (iso8601Lexer.scanISO8601DateIfMatch()) { + val = iso8601Lexer.getCalendar().getTime(); + } + iso8601Lexer.close(); + } + } else if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(); + val = null; + } else if (lexer.token() == JSONToken.LBRACE) { + lexer.nextToken(); + + String key; + if (lexer.token() == JSONToken.LITERAL_STRING) { + key = lexer.stringVal(); + + if (JSON.DEFAULT_TYPE_KEY.equals(key)) { + lexer.nextToken(); + parser.accept(JSONToken.COLON); + + String typeName = lexer.stringVal(); + Class type = TypeUtils.loadClass(typeName); + if (type != null) { + clazz = type; + } + + parser.accept(JSONToken.LITERAL_STRING); + parser.accept(JSONToken.COMMA); + } + + lexer.nextTokenWithColon(JSONToken.LITERAL_INT); + } else { + throw new JSONException("syntax error"); + } + + long timeMillis; + if (lexer.token() == JSONToken.LITERAL_INT) { + timeMillis = lexer.longValue(); + lexer.nextToken(); + } else { + throw new JSONException("syntax error : " + lexer.tokenName()); + } + + val = timeMillis; + + parser.accept(JSONToken.RBRACE); + } else if (parser.getResolveStatus() == DefaultJSONParser.TypeNameRedirect) { + parser.setResolveStatus(DefaultJSONParser.NONE); + parser.accept(JSONToken.COMMA); + + if (lexer.token() == JSONToken.LITERAL_STRING) { + if (!"val".equals(lexer.stringVal())) { + throw new JSONException("syntax error"); + } + lexer.nextToken(); + } else { + throw new JSONException("syntax error"); + } + + parser.accept(JSONToken.COLON); + + val = parser.parse(); + + parser.accept(JSONToken.RBRACE); + } else { + val = parser.parse(); + } + + return (T) cast(parser, clazz, fieldName, val); + } + + protected abstract T cast(DefaultJSONParser parser, Type clazz, Object fieldName, Object value); +} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayDeserializer.java old mode 100644 new mode 100755 index e3c86459a3..81996ca832 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayDeserializer.java @@ -1,10 +1,14 @@ package com.alibaba.fastjson.parser.deserializer; import java.lang.reflect.Array; +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.util.TypeUtils; @@ -12,36 +16,115 @@ public class ArrayDeserializer implements ObjectDeserializer { public final static ArrayDeserializer instance = new ArrayDeserializer(); - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - if (parser.getLexer().token() == JSONToken.NULL) { - parser.getLexer().nextToken(JSONToken.COMMA); + @SuppressWarnings({ "unchecked", "rawtypes" }) + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + final JSONLexer lexer = parser.getLexer(); + if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(JSONToken.COMMA); return null; } - + + if (lexer.token() == JSONToken.LITERAL_STRING) { + byte[] bytes = lexer.bytesValue(); + lexer.nextToken(JSONToken.COMMA); + return (T) bytes; + } + + Class componentClass; + Type componentType; + if (type instanceof GenericArrayType) { + GenericArrayType clazz = (GenericArrayType) type; + componentType = clazz.getGenericComponentType(); + if (componentType instanceof TypeVariable) { + TypeVariable typeVar = (TypeVariable) componentType; + Type objType = parser.getContext().getType(); + if (objType instanceof ParameterizedType) { + ParameterizedType objParamType = (ParameterizedType) objType; + Type objRawType = objParamType.getRawType(); + Type actualType = null; + if (objRawType instanceof Class) { + TypeVariable[] objTypeParams = ((Class) objRawType).getTypeParameters(); + for (int i = 0; i < objTypeParams.length; ++i) { + if (objTypeParams[i].getName().equals(typeVar.getName())) { + actualType = objParamType.getActualTypeArguments()[i]; + } + } + } + if (actualType instanceof Class) { + componentClass = (Class) actualType; + } else { + componentClass = Object.class; + } + } else { + componentClass = Object.class; + } + } else { + componentClass = (Class) componentType; + } + } else { + Class clazz = (Class) type; + componentType = componentClass = clazz.getComponentType(); + } JSONArray array = new JSONArray(); - parser.parseArray(array); + parser.parseArray(componentClass, array, fieldName); - return toObjectArray(parser, (Class) clazz, array); + return (T) toObjectArray(parser, componentClass, array); } @SuppressWarnings("unchecked") - private T toObjectArray(DefaultExtJSONParser parser, Class clazz, JSONArray array) { + private T toObjectArray(DefaultJSONParser parser, Class componentType, JSONArray array) { + if (array == null) { + return null; + } + int size = array.size(); - Class componentType = clazz.getComponentType(); Object objArray = Array.newInstance(componentType, size); for (int i = 0; i < size; ++i) { Object value = array.get(i); + if (value == array) { + Array.set(objArray, i, objArray); + continue; + } + if (componentType.isArray()) { - Object element = toObjectArray(parser, componentType, (JSONArray) value); + Object element; + if (componentType.isInstance(value)) { + element = value; + } else { + element = toObjectArray(parser, componentType, (JSONArray) value); + } + Array.set(objArray, i, element); } else { - Object element = TypeUtils.cast(value, componentType, parser.getConfig()); + Object element = null; + if (value instanceof JSONArray) { + boolean contains = false; + JSONArray valueArray = (JSONArray) value; + int valueArraySize = valueArray.size(); + for (int y = 0; y < valueArraySize; ++y) { + Object valueItem = valueArray.get(y); + if (valueItem == array) { + valueArray.set(i, objArray); + contains = true; + } + } + if (contains) { + element = valueArray.toArray(); + } + } + + if (element == null) { + element = TypeUtils.cast(value, componentType, parser.getConfig()); + } Array.set(objArray, i, element); + } } + + array.setRelatedArray(objArray); + array.setComponentType(componentType); return (T) objArray; // TODO } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListStringDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListStringDeserializer.java deleted file mode 100644 index e07c130dc1..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListStringDeserializer.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Collection; - -import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.Feature; -import com.alibaba.fastjson.parser.JSONLexer; -import com.alibaba.fastjson.parser.JSONToken; - -public class ArrayListStringDeserializer implements ObjectDeserializer { - - public final static ArrayListStringDeserializer instance = new ArrayListStringDeserializer(); - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public T deserialze(DefaultExtJSONParser parser, Type type) { - ArrayList list = new ArrayList(); - - parseArray(parser, list); - - return (T) list; - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public static void parseArray(DefaultExtJSONParser parser, Collection array) { - JSONLexer lexer = parser.getLexer(); - - if (lexer.token() != JSONToken.LBRACKET) { - throw new JSONException("exepct '[', but " + lexer.token()); - } - - lexer.nextToken(JSONToken.LITERAL_STRING); - - for (;;) { - if (lexer.isEnabled(Feature.AllowArbitraryCommas)) { - while (lexer.token() == JSONToken.COMMA) { - lexer.nextToken(); - continue; - } - } - - if (lexer.token() == JSONToken.RBRACKET) { - break; - } - - String value; - if (lexer.token() == JSONToken.LITERAL_STRING) { - value = lexer.stringVal(); - lexer.nextToken(JSONToken.COMMA); - } else { - Object obj = parser.parse(); - if (obj == null) { - value = null; - } else { - value = obj.toString(); - } - } - - array.add(value); - - if (lexer.token() == JSONToken.COMMA) { - lexer.nextToken(JSONToken.LITERAL_STRING); - continue; - } - } - - lexer.nextToken(JSONToken.COMMA); - } - - public int getFastMatchToken() { - return JSONToken.LBRACKET; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListStringFieldDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListStringFieldDeserializer.java deleted file mode 100644 index 583e920c9e..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListStringFieldDeserializer.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.util.ArrayList; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.util.FieldInfo; - -public class ArrayListStringFieldDeserializer extends FieldDeserializer { - - public ArrayListStringFieldDeserializer(ParserConfig mapping, Class clazz, FieldInfo fieldInfo){ - super(clazz, fieldInfo); - - } - - public int getFastMatchToken() { - return JSONToken.LBRACKET; - } - - @Override - public void parseField(DefaultExtJSONParser parser, Object object) { - ArrayList list = new ArrayList(); - - ArrayListStringDeserializer.parseArray(parser, list); - - setValue(object, list); - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListTypeDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListTypeDeserializer.java deleted file mode 100644 index 903e175814..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListTypeDeserializer.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.util.ArrayList; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; - -public class ArrayListTypeDeserializer implements ObjectDeserializer { - - private Type itemType; - - public ArrayListTypeDeserializer(Type type){ - this.itemType = type; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public T deserialze(DefaultExtJSONParser parser, Type type) { - ArrayList list = new ArrayList(); - - parser.parseArray(itemType, list); - - return (T) list; - } - - public int getFastMatchToken() { - return JSONToken.LBRACKET; - } - -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListTypeFieldDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListTypeFieldDeserializer.java old mode 100644 new mode 100755 index bc91445b3b..cc0d623b3a --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListTypeFieldDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListTypeFieldDeserializer.java @@ -2,14 +2,17 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; import java.util.ArrayList; import java.util.Collection; +import java.util.Map; import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.ParseContext; import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.util.FieldInfo; @@ -22,8 +25,12 @@ public class ArrayListTypeFieldDeserializer extends FieldDeserializer { public ArrayListTypeFieldDeserializer(ParserConfig mapping, Class clazz, FieldInfo fieldInfo){ super(clazz, fieldInfo); - this.itemType = ((ParameterizedType) getFieldType()).getActualTypeArguments()[0]; - + Type fieldType = getFieldType(); + if (fieldType instanceof ParameterizedType) { + this.itemType = ((ParameterizedType) getFieldType()).getActualTypeArguments()[0]; + } else { + this.itemType = Object.class; + } } public int getFastMatchToken() { @@ -32,7 +39,7 @@ public int getFastMatchToken() { @SuppressWarnings("rawtypes") @Override - public void parseField(DefaultExtJSONParser parser, Object object) { + public void parseField(DefaultJSONParser parser, Object object, Type objectType, Map fieldValues) { if (parser.getLexer().token() == JSONToken.NULL) { setValue(object, null); return; @@ -40,27 +47,71 @@ public void parseField(DefaultExtJSONParser parser, Object object) { ArrayList list = new ArrayList(); - parseArray(parser, list); + ParseContext context = parser.getContext(); - setValue(object, list); + parser.setContext(context, object, fieldInfo.getName()); + parseArray(parser, objectType, list); + parser.setContext(context); + + if (object == null) { + fieldValues.put(fieldInfo.getName(), list); + } else { + setValue(object, list); + } } @SuppressWarnings({ "unchecked", "rawtypes" }) - public final void parseArray(DefaultExtJSONParser parser, Collection array) { + public final void parseArray(DefaultJSONParser parser, Type objectType, Collection array) { + Type itemType = this.itemType; + ObjectDeserializer itemTypeDeser = this.deserializer; + + if (itemType instanceof TypeVariable // + && objectType instanceof ParameterizedType) { + TypeVariable typeVar = (TypeVariable) itemType; + ParameterizedType paramType = (ParameterizedType) objectType; + + Class objectClass = null; + if (paramType.getRawType() instanceof Class) { + objectClass = (Class) paramType.getRawType(); + } + + int paramIndex = -1; + if (objectClass != null) { + for (int i = 0, size = objectClass.getTypeParameters().length; i < size; ++i) { + TypeVariable item = objectClass.getTypeParameters()[i]; + if (item.getName().equals(typeVar.getName())) { + paramIndex = i; + break; + } + } + } + + if (paramIndex != -1) { + itemType = paramType.getActualTypeArguments()[paramIndex]; + if (!itemType.equals(this.itemType)) { + itemTypeDeser = parser.getConfig().getDeserializer(itemType); + } + } + } + final JSONLexer lexer = parser.getLexer(); if (lexer.token() != JSONToken.LBRACKET) { - throw new JSONException("exepct '[', but " + JSONToken.name(lexer.token())); + String errorMessage = "exepct '[', but " + JSONToken.name(lexer.token()); + if (objectType != null) { + errorMessage += ", type : " + objectType; + } + throw new JSONException(errorMessage); } - if (deserializer == null) { - deserializer = parser.getConfig().getDeserializer(itemType); + if (itemTypeDeser == null) { + itemTypeDeser = deserializer = parser.getConfig().getDeserializer(itemType); itemFastMatchToken = deserializer.getFastMatchToken(); } lexer.nextToken(itemFastMatchToken); - for (;;) { + for (int i = 0;; ++i) { if (lexer.isEnabled(Feature.AllowArbitraryCommas)) { while (lexer.token() == JSONToken.COMMA) { lexer.nextToken(); @@ -72,9 +123,11 @@ public final void parseArray(DefaultExtJSONParser parser, Collection array) { break; } - Object val = deserializer.deserialze(parser, itemType); + Object val = itemTypeDeser.deserialze(parser, itemType, i); array.add(val); + parser.checkListResolve(array); + if (lexer.token() == JSONToken.COMMA) { lexer.nextToken(itemFastMatchToken); continue; @@ -83,4 +136,5 @@ public final void parseArray(DefaultExtJSONParser parser, Collection array) { lexer.nextToken(JSONToken.COMMA); } + } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/AtomicIntegerArrayDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/AtomicIntegerArrayDeserializer.java deleted file mode 100644 index 3e3f3bcfaf..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/AtomicIntegerArrayDeserializer.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.util.concurrent.atomic.AtomicIntegerArray; - -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; - -public class AtomicIntegerArrayDeserializer implements ObjectDeserializer { - - public final static AtomicIntegerArrayDeserializer instance = new AtomicIntegerArrayDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - if (parser.getLexer().token() == JSONToken.NULL) { - parser.getLexer().nextToken(JSONToken.COMMA); - return null; - } - - JSONArray array = new JSONArray(); - parser.parseArray(array); - - AtomicIntegerArray atomicArray = new AtomicIntegerArray(array.size()); - for (int i = 0; i < array.size(); ++i) { - atomicArray.set(i, array.getInteger(i)); - } - - return (T) atomicArray; - } - - public int getFastMatchToken() { - return JSONToken.LBRACKET; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/AtomicLongArrayDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/AtomicLongArrayDeserializer.java deleted file mode 100644 index d1815466b5..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/AtomicLongArrayDeserializer.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.util.concurrent.atomic.AtomicLongArray; - -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; - -public class AtomicLongArrayDeserializer implements ObjectDeserializer { - - public final static AtomicLongArrayDeserializer instance = new AtomicLongArrayDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - if (parser.getLexer().token() == JSONToken.NULL) { - parser.getLexer().nextToken(JSONToken.COMMA); - return null; - } - - JSONArray array = new JSONArray(); - parser.parseArray(array); - - AtomicLongArray atomicArray = new AtomicLongArray(array.size()); - for (int i = 0; i < array.size(); ++i) { - atomicArray.set(i, array.getLong(i)); - } - - return (T) atomicArray; - } - - public int getFastMatchToken() { - return JSONToken.LBRACKET; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/AutowiredObjectDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/AutowiredObjectDeserializer.java old mode 100644 new mode 100755 diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/BigDecimalDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/BigDecimalDeserializer.java deleted file mode 100644 index 46e68b011d..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/BigDecimalDeserializer.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.math.BigDecimal; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONLexer; -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.util.TypeUtils; - -public class BigDecimalDeserializer implements ObjectDeserializer { - - public final static BigDecimalDeserializer instance = new BigDecimalDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - return (T) deserialze(parser); - } - - @SuppressWarnings("unchecked") - public static T deserialze(DefaultExtJSONParser parser) { - final JSONLexer lexer = parser.getLexer(); - if (lexer.token() == JSONToken.LITERAL_INT) { - long val = lexer.longValue(); - lexer.nextToken(JSONToken.COMMA); - return (T) new BigDecimal(val); - } - - if (lexer.token() == JSONToken.LITERAL_FLOAT) { - BigDecimal val = lexer.decimalValue(); - lexer.nextToken(JSONToken.COMMA); - return (T) val; - } - - Object value = parser.parse(); - - if (value == null) { - return null; - } - - return (T) TypeUtils.castToBigDecimal(value); - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_INT; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/BigIntegerDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/BigIntegerDeserializer.java deleted file mode 100644 index a388f79c29..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/BigIntegerDeserializer.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.math.BigInteger; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONLexer; -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.util.TypeUtils; - -public class BigIntegerDeserializer implements ObjectDeserializer { - - public final static BigIntegerDeserializer instance = new BigIntegerDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - return (T) deserialze(parser); - } - - @SuppressWarnings("unchecked") - public static T deserialze(DefaultExtJSONParser parser) { - final JSONLexer lexer = parser.getLexer(); - if (lexer.token() == JSONToken.LITERAL_INT) { - String val = lexer.numberString(); - lexer.nextToken(JSONToken.COMMA); - return (T) new BigInteger(val); - } - - Object value = parser.parse(); - - if (value == null) { - return null; - } - - return (T) TypeUtils.castToBigInteger(value); - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_INT; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/BooleanDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/BooleanDeserializer.java deleted file mode 100644 index 8343f796a8..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/BooleanDeserializer.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONLexer; -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.util.TypeUtils; - -public class BooleanDeserializer implements ObjectDeserializer { - public final static BooleanDeserializer instance = new BooleanDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - return (T) deserialze(parser); - } - - @SuppressWarnings("unchecked") - public static T deserialze(DefaultExtJSONParser parser) { - final JSONLexer lexer = parser.getLexer(); - - if (lexer.token() == JSONToken.TRUE) { - lexer.nextToken(JSONToken.COMMA); - return (T) Boolean.TRUE; - } - - if (lexer.token() == JSONToken.FALSE) { - lexer.nextToken(JSONToken.COMMA); - return (T) Boolean.FALSE; - } - - if (lexer.token() == JSONToken.LITERAL_INT) { - int intValue = lexer.intValue(); - lexer.nextToken(JSONToken.COMMA); - - if (intValue == 1) { - return (T) Boolean.TRUE; - } else { - return (T) Boolean.FALSE; - } - } - - Object value = parser.parse(); - - if (value == null) { - return null; - } - - return (T) TypeUtils.castToBoolean(value); - } - - public int getFastMatchToken() { - return JSONToken.TRUE; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/BooleanFieldDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/BooleanFieldDeserializer.java old mode 100644 new mode 100755 index b323479327..3805c13334 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/BooleanFieldDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/BooleanFieldDeserializer.java @@ -1,6 +1,9 @@ package com.alibaba.fastjson.parser.deserializer; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import java.lang.reflect.Type; +import java.util.Map; + +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; @@ -14,23 +17,28 @@ public BooleanFieldDeserializer(ParserConfig mapping, Class clazz, FieldInfo } @Override - public void parseField(DefaultExtJSONParser parser, Object object) { + public void parseField(DefaultJSONParser parser, Object object, Type objectType, Map fieldValues) { Boolean value; final JSONLexer lexer = parser.getLexer(); if (lexer.token() == JSONToken.TRUE) { lexer.nextToken(JSONToken.COMMA); - setValue(object, true); + if (object == null) { + fieldValues.put(fieldInfo.getName(), Boolean.TRUE); + } else { + setValue(object, true); + } return; } if (lexer.token() == JSONToken.LITERAL_INT) { int val = lexer.intValue(); lexer.nextToken(JSONToken.COMMA); - if (val == 1) { - setValue(object, true); + boolean booleanValue = val == 1; + if (object == null) { + fieldValues.put(fieldInfo.getName(), booleanValue); } else { - setValue(object, false); + setValue(object, booleanValue); } return; } @@ -44,13 +52,19 @@ public void parseField(DefaultExtJSONParser parser, Object object) { return; } - setValue(object, null); + if (object != null) { + setValue(object, null); + } return; } if (lexer.token() == JSONToken.FALSE) { lexer.nextToken(JSONToken.COMMA); - setValue(object, false); + if (object == null) { + fieldValues.put(fieldInfo.getName(), Boolean.FALSE); + } else { + setValue(object, false); + } return; } @@ -63,7 +77,11 @@ public void parseField(DefaultExtJSONParser parser, Object object) { return; } - setValue(object, value); + if (object == null) { + fieldValues.put(fieldInfo.getName(), value); + } else { + setValue(object, value); + } } public int getFastMatchToken() { diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ByteDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ByteDeserializer.java deleted file mode 100644 index 6ae28b0fdd..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/ByteDeserializer.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.util.TypeUtils; - -public class ByteDeserializer implements ObjectDeserializer { - public final static ByteDeserializer instance = new ByteDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - Object value = parser.parse(); - - if (value == null) { - return null; - } - - return (T) TypeUtils.castToByte(value); - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_INT; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/StringDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/CharArrayDeserializer.java old mode 100644 new mode 100755 similarity index 58% rename from src/main/java/com/alibaba/fastjson/parser/deserializer/StringDeserializer.java rename to src/main/java/com/alibaba/fastjson/parser/deserializer/CharArrayDeserializer.java index 3d3be4cbfb..ba5a191882 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/StringDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/CharArrayDeserializer.java @@ -2,32 +2,33 @@ import java.lang.reflect.Type; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; -public class StringDeserializer implements ObjectDeserializer { +public class CharArrayDeserializer implements ObjectDeserializer { - public final static StringDeserializer instance = new StringDeserializer(); + public final static CharArrayDeserializer instance = new CharArrayDeserializer(); @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { return (T) deserialze(parser); } @SuppressWarnings("unchecked") - public static T deserialze(DefaultExtJSONParser parser) { + public static T deserialze(DefaultJSONParser parser) { final JSONLexer lexer = parser.getLexer(); if (lexer.token() == JSONToken.LITERAL_STRING) { String val = lexer.stringVal(); lexer.nextToken(JSONToken.COMMA); - return (T) val; + return (T) val.toCharArray(); } if (lexer.token() == JSONToken.LITERAL_INT) { - String val = lexer.numberString(); + Number val = lexer.integerValue(); lexer.nextToken(JSONToken.COMMA); - return (T) val; + return (T) val.toString().toCharArray(); } Object value = parser.parse(); @@ -36,7 +37,7 @@ public static T deserialze(DefaultExtJSONParser parser) { return null; } - return (T) value.toString(); + return (T) JSON.toJSONString(value).toCharArray(); } public int getFastMatchToken() { diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/CharacterDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/CharacterDeserializer.java deleted file mode 100644 index 5edc71c918..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/CharacterDeserializer.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.util.TypeUtils; - -public class CharacterDeserializer implements ObjectDeserializer { - public final static CharacterDeserializer instance = new CharacterDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - Object value = parser.parse(); - - if (value == null) { - return null; - } - - return (T) TypeUtils.castToChar(value); - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_STRING; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/CharsetDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/CharsetDeserializer.java deleted file mode 100644 index fda770293f..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/CharsetDeserializer.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.nio.charset.Charset; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; - -public class CharsetDeserializer implements ObjectDeserializer { - public final static CharsetDeserializer instance = new CharsetDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - Object value = parser.parse(); - - if (value == null) { - return null; - } - - String charset = (String) value; - - return (T) Charset.forName(charset); - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_STRING; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ClassDerializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ClassDerializer.java new file mode 100755 index 0000000000..b8669827c3 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/ClassDerializer.java @@ -0,0 +1,40 @@ +package com.alibaba.fastjson.parser.deserializer; + +import java.lang.reflect.Type; + +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.util.TypeUtils; + +public class ClassDerializer implements ObjectDeserializer { + + public final static ClassDerializer instance = new ClassDerializer(); + + public ClassDerializer(){ + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + JSONLexer lexer = parser.getLexer(); + + if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(); + return null; + } + + if (lexer.token() != JSONToken.LITERAL_STRING) { + throw new JSONException("expect className"); + } + String className = lexer.stringVal(); + lexer.nextToken(JSONToken.COMMA); + + return (T) TypeUtils.loadClass(className); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } + +} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/CollectionDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/CollectionDeserializer.java old mode 100644 new mode 100755 index edd52ea698..9b14f1f5c8 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/CollectionDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/CollectionDeserializer.java @@ -2,12 +2,16 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.util.AbstractCollection; import java.util.ArrayList; import java.util.Collection; +import java.util.EnumSet; import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.TreeSet; import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONToken; public class CollectionDeserializer implements ObjectDeserializer { @@ -15,30 +19,39 @@ public class CollectionDeserializer implements ObjectDeserializer { public final static CollectionDeserializer instance = new CollectionDeserializer(); @SuppressWarnings({ "unchecked", "rawtypes" }) - public T deserialze(DefaultExtJSONParser parser, Type type) { + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { if (parser.getLexer().token() == JSONToken.NULL) { parser.getLexer().nextToken(JSONToken.COMMA); return null; } - Collection list = null; - if (type instanceof Class) { - Class clazz = (Class) type; - if (clazz.isAssignableFrom(HashSet.class)) { - list = new HashSet(); - } else if (clazz.isAssignableFrom(ArrayList.class)) { - list = new ArrayList(); + Class rawClass = getRawClass(type); + + Collection list; + if (rawClass == AbstractCollection.class) { + list = new ArrayList(); + } else if (rawClass.isAssignableFrom(HashSet.class)) { + list = new HashSet(); + } else if (rawClass.isAssignableFrom(LinkedHashSet.class)) { + list = new LinkedHashSet(); + } else if (rawClass.isAssignableFrom(TreeSet.class)) { + list = new TreeSet(); + } else if (rawClass.isAssignableFrom(ArrayList.class)) { + list = new ArrayList(); + } else if (rawClass.isAssignableFrom(EnumSet.class)) { + Type itemType; + if (type instanceof ParameterizedType) { + itemType = ((ParameterizedType) type).getActualTypeArguments()[0]; } else { - try { - list = (Collection) clazz.newInstance(); - } catch (Exception e) { - throw new JSONException("create instane error, class " + clazz.getName()); - } + itemType = Object.class; + } + list = EnumSet.noneOf((Class)itemType); + } else { + try { + list = (Collection) rawClass.newInstance(); + } catch (Exception e) { + throw new JSONException("create instane error, class " + rawClass.getName()); } - } - - if (list == null) { - list = new ArrayList(); } Type itemType; @@ -47,11 +60,22 @@ public T deserialze(DefaultExtJSONParser parser, Type type) { } else { itemType = Object.class; } - parser.parseArray(itemType, list); + parser.parseArray(itemType, list, fieldName); return (T) list; } + public Class getRawClass(Type type) { + + if (type instanceof Class) { + return (Class) type; + } else if (type instanceof ParameterizedType) { + return getRawClass(((ParameterizedType) type).getRawType()); + } else { + throw new JSONException("TODO"); + } + } + public int getFastMatchToken() { return JSONToken.LBRACKET; } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/CollectionResolveFieldDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/CollectionResolveFieldDeserializer.java new file mode 100644 index 0000000000..d5c96e1b90 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/CollectionResolveFieldDeserializer.java @@ -0,0 +1,28 @@ +package com.alibaba.fastjson.parser.deserializer; + +import java.lang.reflect.Type; +import java.util.Collection; +import java.util.Map; + +import com.alibaba.fastjson.parser.DefaultJSONParser; + +@SuppressWarnings("rawtypes") +public final class CollectionResolveFieldDeserializer extends FieldDeserializer { + + private final Collection collection; + + public CollectionResolveFieldDeserializer(DefaultJSONParser parser, Collection collection){ + super(null, null); + this.collection = collection; + } + + @SuppressWarnings("unchecked") + public void setValue(Object object, Object value) { + collection.add(value); + } + + public void parseField(DefaultJSONParser parser, Object object, Type objectType, Map fieldValues) { + + } + +} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ConcurrentHashMapDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ConcurrentHashMapDeserializer.java deleted file mode 100644 index f716d6e901..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/ConcurrentHashMapDeserializer.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; - -public class ConcurrentHashMapDeserializer implements ObjectDeserializer { - public final static ConcurrentHashMapDeserializer instance = new ConcurrentHashMapDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - Map map = new ConcurrentHashMap(); - parser.parseObject(map); - return (T) map; - } - - public int getFastMatchToken() { - return JSONToken.LBRACE; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/DateDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/DateDeserializer.java old mode 100644 new mode 100755 index f313144630..aa3003604b --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/DateDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/DateDeserializer.java @@ -1,19 +1,21 @@ package com.alibaba.fastjson.parser.deserializer; import java.lang.reflect.Type; +import java.text.DateFormat; +import java.text.ParseException; +import java.util.Calendar; import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONScanner; import com.alibaba.fastjson.parser.JSONToken; -public class DateDeserializer implements ObjectDeserializer { +public class DateDeserializer extends AbstractDateDeserializer implements ObjectDeserializer { public final static DateDeserializer instance = new DateDeserializer(); @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - Object val = parser.parse(); + protected T cast(DefaultJSONParser parser, Type clazz, Object fieldName, Object val) { if (val == null) { return null; @@ -28,16 +30,33 @@ public T deserialze(DefaultExtJSONParser parser, Type clazz) { if (strVal.length() == 0) { return null; } - + JSONScanner dateLexer = new JSONScanner(strVal); - if (dateLexer.scanISO8601DateIfMatch()) { - return (T) dateLexer.getCalendar().getTime(); + try { + if (dateLexer.scanISO8601DateIfMatch(false)) { + Calendar calendar = dateLexer.getCalendar(); + + if (clazz == Calendar.class) { + return (T) calendar; + } + + return (T) calendar.getTime(); + } + } finally { + dateLexer.close(); + } + + DateFormat dateFormat = parser.getDateFormat(); + try { + return (T) dateFormat.parse(strVal); + } catch (ParseException e) { + // skip } long longVal = Long.parseLong(strVal); return (T) new java.util.Date(longVal); } - + throw new JSONException("parse error"); } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/DateFormatDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/DateFormatDeserializer.java new file mode 100755 index 0000000000..5657cf045f --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/DateFormatDeserializer.java @@ -0,0 +1,36 @@ +package com.alibaba.fastjson.parser.deserializer; + +import java.lang.reflect.Type; +import java.text.SimpleDateFormat; + +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; + +public class DateFormatDeserializer extends AbstractDateDeserializer implements ObjectDeserializer { + + public final static DateFormatDeserializer instance = new DateFormatDeserializer(); + + @SuppressWarnings("unchecked") + protected T cast(DefaultJSONParser parser, Type clazz, Object fieldName, Object val) { + + if (val == null) { + return null; + } + + if (val instanceof String) { + String strVal = (String) val; + if (strVal.length() == 0) { + return null; + } + + return (T) new SimpleDateFormat(strVal); + } + + throw new JSONException("parse error"); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } +} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/DefaultFieldDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/DefaultFieldDeserializer.java old mode 100644 new mode 100755 index 4af4afe682..14e9cf1bd4 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/DefaultFieldDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/DefaultFieldDeserializer.java @@ -1,7 +1,13 @@ package com.alibaba.fastjson.parser.deserializer; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Map; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser.ResolveTask; import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.ParseContext; import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.util.FieldInfo; @@ -14,20 +20,36 @@ public DefaultFieldDeserializer(ParserConfig mapping, Class clazz, FieldInfo } @Override - public void parseField(DefaultExtJSONParser parser, Object object) { + public void parseField(DefaultJSONParser parser, Object object, Type objectType, Map fieldValues) { if (fieldValueDeserilizer == null) { fieldValueDeserilizer = parser.getConfig().getDeserializer(fieldInfo); } - Object value = fieldValueDeserilizer.deserialze(parser, getFieldType()); - setValue(object, value); + if (objectType instanceof ParameterizedType) { + ParseContext objContext = parser.getContext(); + objContext.setType(objectType); + } + + Object value = fieldValueDeserilizer.deserialze(parser, getFieldType(), fieldInfo.getName()); + if (parser.getResolveStatus() == DefaultJSONParser.NeedToResolve) { + ResolveTask task = parser.getLastResolveTask(); + task.setFieldDeserializer(this); + task.setOwnerContext(parser.getContext()); + parser.setResolveStatus(DefaultJSONParser.NONE); + } else { + if (object == null) { + fieldValues.put(fieldInfo.getName(), value); + } else { + setValue(object, value); + } + } } public int getFastMatchToken() { if (fieldValueDeserilizer != null) { - return fieldValueDeserilizer.getFastMatchToken(); + return fieldValueDeserilizer.getFastMatchToken(); } - + return JSONToken.LITERAL_INT; } } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/DefaultObjectDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/DefaultObjectDeserializer.java deleted file mode 100644 index 19af17fdf8..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/DefaultObjectDeserializer.java +++ /dev/null @@ -1,293 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; -import java.lang.reflect.WildcardType; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.Feature; -import com.alibaba.fastjson.parser.JSONScanner; -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.util.ASMClassLoader; - -public class DefaultObjectDeserializer implements ObjectDeserializer { - - public DefaultObjectDeserializer(){ - } - - public void parseMap(DefaultExtJSONParser parser, Map map, Type valueType) { - JSONScanner lexer = (JSONScanner) parser.getLexer(); - - if (lexer.token() != JSONToken.LBRACE) { - throw new JSONException("syntax error, expect {, actual " + lexer.token()); - } - - for (;;) { - lexer.skipWhitespace(); - char ch = lexer.getCurrent(); - if (parser.isEnabled(Feature.AllowArbitraryCommas)) { - while (ch == ',') { - lexer.incrementBufferPosition(); - lexer.skipWhitespace(); - ch = lexer.getCurrent(); - } - } - - String key; - if (ch == '"') { - key = lexer.scanSymbol(parser.getSymbolTable(), '"'); - lexer.skipWhitespace(); - ch = lexer.getCurrent(); - if (ch != ':') { - throw new JSONException("expect ':' at " + lexer.pos()); - } - } else if (ch == '}') { - lexer.incrementBufferPosition(); - lexer.resetStringPosition(); - return; - } else if (ch == '\'') { - if (!parser.isEnabled(Feature.AllowSingleQuotes)) { - throw new JSONException("syntax error"); - } - - key = lexer.scanSymbol(parser.getSymbolTable(), '\''); - lexer.skipWhitespace(); - ch = lexer.getCurrent(); - if (ch != ':') { - throw new JSONException("expect ':' at " + lexer.pos()); - } - } else { - if (!parser.isEnabled(Feature.AllowUnQuotedFieldNames)) { - throw new JSONException("syntax error"); - } - - key = lexer.scanSymbolUnQuoted(parser.getSymbolTable()); - lexer.skipWhitespace(); - ch = lexer.getCurrent(); - if (ch != ':') { - throw new JSONException("expect ':' at " + lexer.pos() + ", actual " + ch); - } - } - - lexer.incrementBufferPosition(); - lexer.skipWhitespace(); - ch = lexer.getCurrent(); - - lexer.resetStringPosition(); - - Object value; - lexer.nextToken(); - - if (lexer.token() == JSONToken.NULL) { - value = null; - lexer.nextToken(); - } else { - value = parser.parseObject(valueType); - } - - map.put(key, value); - - if (lexer.token() == JSONToken.RBRACE) { - lexer.nextToken(); - return; - } - } - } - - public void parseObject(DefaultExtJSONParser parser, Object object) { - Class clazz = object.getClass(); - Map setters = parser.getConfig().getFieldDeserializers(clazz); - - JSONScanner lexer = (JSONScanner) parser.getLexer(); // xxx - - if (lexer.token() != JSONToken.LBRACE) { - throw new JSONException("syntax error, expect {, actual " + lexer.token()); - } - - final Object[] args = new Object[1]; - - for (;;) { - // lexer.scanSymbol - String key = lexer.scanSymbol(parser.getSymbolTable()); - - if (key == null) { - if (lexer.token() == JSONToken.RBRACE) { - lexer.nextToken(JSONToken.COMMA); - break; - } - if (lexer.token() == JSONToken.COMMA) { - if (parser.isEnabled(Feature.AllowArbitraryCommas)) { - continue; - } - } - } - - FieldDeserializer fieldDeser = setters.get(key); - if (fieldDeser == null) { - if (!parser.isEnabled(Feature.IgnoreNotMatch)) { - throw new JSONException("setter not found, class " + clazz.getName() + ", property " + key); - } - - lexer.nextTokenWithColon(); - parser.parse(); // skip - - if (lexer.token() == JSONToken.RBRACE) { - lexer.nextToken(); - return; - } - - continue; - } else { - Method method = fieldDeser.getMethod(); - Class fieldClass = method.getParameterTypes()[0]; - Type fieldType = method.getGenericParameterTypes()[0]; - if (fieldClass == int.class) { - lexer.nextTokenWithColon(JSONToken.LITERAL_INT); - args[0] = IntegerDeserializer.deserialze(parser); - } else if (fieldClass == String.class) { - lexer.nextTokenWithColon(JSONToken.LITERAL_STRING); - args[0] = StringDeserializer.deserialze(parser); - } else if (fieldClass == long.class) { - lexer.nextTokenWithColon(JSONToken.LITERAL_INT); - args[0] = LongDeserializer.deserialze(parser); - } else if (fieldClass == List.class) { - lexer.nextTokenWithColon(JSONToken.LBRACE); - args[0] = CollectionDeserializer.instance.deserialze(parser, fieldType); - } else { - ObjectDeserializer fieldValueDeserializer = parser.getConfig().getDeserializer(fieldClass, fieldType); - - lexer.nextTokenWithColon(fieldValueDeserializer.getFastMatchToken()); - args[0] = fieldValueDeserializer.deserialze(parser, fieldType); - } - - try { - method.invoke(object, args); - } catch (Exception e) { - throw new JSONException("set proprety error, " + method.getName(), e); - } - } - - if (lexer.token() == JSONToken.COMMA) { - continue; - } - - if (lexer.token() == JSONToken.RBRACE) { - lexer.nextToken(JSONToken.COMMA); - return; - } - } - } - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type type) { - if (type instanceof Class) { - return deserialze(parser, (Class) type); - } - - if (type instanceof ParameterizedType) { - return (T) deserialze(parser, (ParameterizedType) type); - } - - if (type instanceof TypeVariable) { - return (T) parser.parse(); - } - - if (type instanceof WildcardType) { - return (T) parser.parse(); - } - - throw new JSONException("not support type : " + type); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public T deserialze(DefaultExtJSONParser parser, ParameterizedType type) { - try { - Type rawType = type.getRawType(); - if (rawType instanceof Class) { - Class rawClass = (Class) rawType; - - if (Map.class.isAssignableFrom(rawClass)) { - Map map; - - if (Modifier.isAbstract(rawClass.getModifiers())) { - if (rawClass == Map.class) { - map = new HashMap(); - } else if (rawClass == SortedMap.class) { - map = new TreeMap(); - } else if (rawClass == ConcurrentMap.class) { - map = new ConcurrentHashMap(); - } else { - throw new JSONException("can not create instance : " + rawClass); - } - } else { - if (rawClass == HashMap.class) { - map = new HashMap(); - } else { - map = (Map) rawClass.newInstance(); - } - } - - Type valueType = type.getActualTypeArguments()[1]; - - parseMap(parser, map, valueType); - - return (T) map; - } - - } - - throw new JSONException("not support type : " + type); - } catch (JSONException e) { - throw e; - } catch (Throwable e) { - throw new JSONException(e.getMessage(), e); - } - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public T deserialze(DefaultExtJSONParser parser, Class clazz) { - Object value = null; - if (clazz.isAssignableFrom(HashMap.class)) { - value = new HashMap(); - } else if (clazz.isAssignableFrom(TreeMap.class)) { - value = new TreeMap(); - } else if (clazz.isAssignableFrom(ConcurrentHashMap.class)) { - value = new ConcurrentHashMap(); - } - - if (clazz == Class.class) { - Object classValue = parser.parse(); - if (classValue == null) { - return null; - } - - if (classValue instanceof String) { - return (T) ASMClassLoader.forName((String) classValue); - } - } - - try { - parseObject(parser, value); - return (T) value; - } catch (JSONException e) { - throw e; - } catch (Throwable e) { - throw new JSONException(e.getMessage(), e); - } - } - - public int getFastMatchToken() { - return JSONToken.LBRACE; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/DoubleDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/DoubleDeserializer.java deleted file mode 100644 index 6141755561..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/DoubleDeserializer.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONLexer; -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.util.TypeUtils; - -public class DoubleDeserializer implements ObjectDeserializer { - - public final static DoubleDeserializer instance = new DoubleDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - return (T) deserialze(parser); - } - - @SuppressWarnings("unchecked") - public static T deserialze(DefaultExtJSONParser parser) { - final JSONLexer lexer = parser.getLexer(); - if (lexer.token() == JSONToken.LITERAL_INT) { - String val = lexer.numberString(); - lexer.nextToken(JSONToken.COMMA); - return (T) Double.valueOf(Double.parseDouble(val)); - } - - if (lexer.token() == JSONToken.LITERAL_FLOAT) { - String val = lexer.numberString(); - lexer.nextToken(JSONToken.COMMA); - return (T) Double.valueOf(Double.parseDouble(val)); - } - - Object value = parser.parse(); - - if (value == null) { - return null; - } - - return (T) TypeUtils.castToDouble(value); - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_INT; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/EnumDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/EnumDeserializer.java old mode 100644 new mode 100755 index cf2dffd20c..dae6d7dfa1 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/EnumDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/EnumDeserializer.java @@ -6,7 +6,7 @@ import java.util.Map; import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; @@ -35,7 +35,7 @@ public EnumDeserializer(Class enumClass){ } @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type type) { + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { try { Object value; final JSONLexer lexer = parser.getLexer(); diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ExtraProcessor.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ExtraProcessor.java new file mode 100644 index 0000000000..9dcb7645f7 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/ExtraProcessor.java @@ -0,0 +1,11 @@ +package com.alibaba.fastjson.parser.deserializer; + +/** + * + * @author wenshao[szujobs@hotmail.com] + * @since 1.1.34 + */ +public interface ExtraProcessor extends ParseProcess { + + void processExtra(Object object, String key, Object value); +} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ExtraTypeProvider.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ExtraTypeProvider.java new file mode 100644 index 0000000000..4b03794181 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/ExtraTypeProvider.java @@ -0,0 +1,12 @@ +package com.alibaba.fastjson.parser.deserializer; + +import java.lang.reflect.Type; + +/** + * @author wenshao[szujobs@hotmail.com] + * @since 1.1.34 + */ +public interface ExtraTypeProvider extends ParseProcess { + + Type getExtraType(Object object, String key); +} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/FieldDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/FieldDeserializer.java old mode 100644 new mode 100755 index c1451c15a9..30954503f7 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/FieldDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/FieldDeserializer.java @@ -1,61 +1,123 @@ package com.alibaba.fastjson.parser.deserializer; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Type; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.util.FieldInfo; public abstract class FieldDeserializer { - protected final FieldInfo fieldInfo; - - protected final Class clazz; - - public FieldDeserializer(Class clazz, FieldInfo fieldInfo) { - this.clazz = clazz; - this.fieldInfo = fieldInfo; - } - - public Method getMethod() { - return fieldInfo.getMethod(); - } - - public Class getFieldClass() { - return fieldInfo.getFieldClass(); - } - - public Type getFieldType() { - return fieldInfo.getFieldType(); - } - - public abstract void parseField(DefaultExtJSONParser parser, Object object); - - public abstract int getFastMatchToken(); - - public void setValue(Object object, boolean value) { - setValue(object, Boolean.valueOf(value)); - } - - public void setValue(Object object, int value) { - setValue(object, Integer.valueOf(value)); - } - - public void setValue(Object object, long value) { - setValue(object, Long.valueOf(value)); - } - - public void setValue(Object object, String value) { - setValue(object, (Object) value); - } - - public void setValue(Object object, Object value) { - try { - fieldInfo.getMethod().invoke(object, value); - } catch (Exception e) { - throw new JSONException("set property error, " - + fieldInfo.getMethod().toString(), e); - } - } + protected final FieldInfo fieldInfo; + + protected final Class clazz; + + public FieldDeserializer(Class clazz, FieldInfo fieldInfo){ + this.clazz = clazz; + this.fieldInfo = fieldInfo; + } + + public FieldInfo getFieldInfo() { + return fieldInfo; + } + + public Method getMethod() { + return fieldInfo.getMethod(); + } + + public Field getField() { + return fieldInfo.getField(); + } + + public Class getFieldClass() { + return fieldInfo.getFieldClass(); + } + + public Type getFieldType() { + return fieldInfo.getFieldType(); + } + + public abstract void parseField(DefaultJSONParser parser, Object object, Type objectType, + Map fieldValues); + + public int getFastMatchToken() { + return 0; + } + + public void setValue(Object object, boolean value) { + setValue(object, Boolean.valueOf(value)); + } + + public void setValue(Object object, int value) { + setValue(object, Integer.valueOf(value)); + } + + public void setValue(Object object, long value) { + setValue(object, Long.valueOf(value)); + } + + public void setValue(Object object, String value) { + setValue(object, (Object) value); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void setValue(Object object, Object value) { + Method method = fieldInfo.getMethod(); + if (method != null) { + try { + if (fieldInfo.isGetOnly()) { + if (fieldInfo.getFieldClass() == AtomicInteger.class) { + AtomicInteger atomic = (AtomicInteger) method.invoke(object); + if (atomic != null) { + atomic.set(((AtomicInteger) value).get()); + } + } else if (fieldInfo.getFieldClass() == AtomicLong.class) { + AtomicLong atomic = (AtomicLong) method.invoke(object); + if (atomic != null) { + atomic.set(((AtomicLong) value).get()); + } + } else if (fieldInfo.getFieldClass() == AtomicBoolean.class) { + AtomicBoolean atomic = (AtomicBoolean) method.invoke(object); + if (atomic != null) { + atomic.set(((AtomicBoolean) value).get()); + } + } else if (Map.class.isAssignableFrom(method.getReturnType())) { + Map map = (Map) method.invoke(object); + if (map != null) { + map.putAll((Map) value); + } + } else { + Collection collection = (Collection) method.invoke(object); + if (collection != null) { + collection.addAll((Collection) value); + } + } + } else { + if (value == null && fieldInfo.getFieldClass().isPrimitive()) { + return; + } + method.invoke(object, value); + } + } catch (Exception e) { + throw new JSONException("set property error, " + fieldInfo.getName(), e); + } + return; + } + + final Field field = fieldInfo.getField(); + if (field != null) { + try { + field.set(object, value); + } catch (Exception e) { + throw new JSONException("set property error, " + fieldInfo.getName(), e); + } + } + } } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/FileDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/FileDeserializer.java deleted file mode 100644 index 47d708213e..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/FileDeserializer.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.io.File; -import java.lang.reflect.Type; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; - -public class FileDeserializer implements ObjectDeserializer { - public final static FileDeserializer instance = new FileDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - Object value = parser.parse(); - - if (value == null) { - return null; - } - - String path = (String) value; - - return (T) new File(path); - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_STRING; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/FloatDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/FloatDeserializer.java deleted file mode 100644 index 8c06de002e..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/FloatDeserializer.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONLexer; -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.util.TypeUtils; - -public class FloatDeserializer implements ObjectDeserializer { - - public final static FloatDeserializer instance = new FloatDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - return (T) deserialze(parser); - } - - @SuppressWarnings("unchecked") - public static T deserialze(DefaultExtJSONParser parser) { - final JSONLexer lexer = parser.getLexer(); - if (lexer.token() == JSONToken.LITERAL_INT) { - String val = lexer.numberString(); - lexer.nextToken(JSONToken.COMMA); - return (T) Float.valueOf(Float.parseFloat(val)); - } - - if (lexer.token() == JSONToken.LITERAL_FLOAT) { - float val = lexer.floatValue(); - lexer.nextToken(JSONToken.COMMA); - return (T) Float.valueOf(val); - } - - Object value = parser.parse(); - - if (value == null) { - return null; - } - - return (T) TypeUtils.castToFloat(value); - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_INT; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/HashMapDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/HashMapDeserializer.java deleted file mode 100644 index 726c92a867..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/HashMapDeserializer.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.Map; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONLexer; -import com.alibaba.fastjson.parser.JSONToken; - -public class HashMapDeserializer implements ObjectDeserializer { - - public final static HashMapDeserializer instance = new HashMapDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type type) { - final JSONLexer lexer = parser.getLexer(); - if (lexer.token() == JSONToken.NULL) { - lexer.nextToken(JSONToken.COMMA); - return null; - } - - Map map = new HashMap(); - parser.parseObject(map); - return (T) map; - } - - public int getFastMatchToken() { - return JSONToken.LBRACE; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/InetAddressDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/InetAddressDeserializer.java deleted file mode 100644 index f19ec8701f..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/InetAddressDeserializer.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.net.InetAddress; -import java.net.UnknownHostException; - -import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; - -public class InetAddressDeserializer implements ObjectDeserializer { - - public final static InetAddressDeserializer instance = new InetAddressDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - - String host = (String) parser.parse(); - - if (host == null) { - return null; - } - - if (host.length() == 0) { - return null; - } - - try { - return (T) InetAddress.getByName(host); - } catch (UnknownHostException e) { - throw new JSONException("deserialize error", e); - } - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_STRING; - } - -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/IntegerDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/IntegerDeserializer.java deleted file mode 100644 index 5559737cc3..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/IntegerDeserializer.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.math.BigDecimal; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONLexer; -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.util.TypeUtils; - -public class IntegerDeserializer implements ObjectDeserializer { - public final static IntegerDeserializer instance = new IntegerDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - return (T) deserialze(parser); - } - - @SuppressWarnings("unchecked") - public static T deserialze(DefaultExtJSONParser parser) { - final JSONLexer lexer = parser.getLexer(); - if (lexer.token() == JSONToken.LITERAL_INT) { - int val = lexer.intValue(); - lexer.nextToken(JSONToken.COMMA); - return (T) Integer.valueOf(val); - } - - if (lexer.token() == JSONToken.LITERAL_FLOAT) { - BigDecimal decimalValue = lexer.decimalValue(); - lexer.nextToken(JSONToken.COMMA); - return (T) Integer.valueOf(decimalValue.intValue()); - } - - Object value = parser.parse(); - - if (value == null) { - return null; - } - - return (T) TypeUtils.castToInt(value); - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_INT; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/IntegerFieldDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/IntegerFieldDeserializer.java old mode 100644 new mode 100755 index 7b2ce0f821..3d51173055 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/IntegerFieldDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/IntegerFieldDeserializer.java @@ -1,6 +1,9 @@ package com.alibaba.fastjson.parser.deserializer; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import java.lang.reflect.Type; +import java.util.Map; + +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; @@ -14,14 +17,18 @@ public IntegerFieldDeserializer(ParserConfig mapping, Class clazz, FieldInfo } @Override - public void parseField(DefaultExtJSONParser parser, Object object) { + public void parseField(DefaultJSONParser parser, Object object, Type objectType, Map fieldValues) { Integer value; final JSONLexer lexer = parser.getLexer(); if (lexer.token() == JSONToken.LITERAL_INT) { int val = lexer.intValue(); lexer.nextToken(JSONToken.COMMA); - setValue(object, val); + if (object == null) { + fieldValues.put(fieldInfo.getName(), val); + } else { + setValue(object, val); + } return; } else if (lexer.token() == JSONToken.NULL) { value = null; @@ -37,7 +44,11 @@ public void parseField(DefaultExtJSONParser parser, Object object) { return; } - setValue(object, value); + if (object == null) { + fieldValues.put(fieldInfo.getName(), value); + } else { + setValue(object, value); + } } public int getFastMatchToken() { diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/JSONArrayDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/JSONArrayDeserializer.java old mode 100644 new mode 100755 index 7f0fbadde4..23edbdb343 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/JSONArrayDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/JSONArrayDeserializer.java @@ -3,14 +3,14 @@ import java.lang.reflect.Type; import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONToken; public class JSONArrayDeserializer implements ObjectDeserializer { public final static JSONArrayDeserializer instance = new JSONArrayDeserializer(); @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { JSONArray array = new JSONArray(); parser.parseArray(array); return (T) array; diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/JSONObjectDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/JSONObjectDeserializer.java old mode 100644 new mode 100755 index 5870971ca5..3d69a02a79 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/JSONObjectDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/JSONObjectDeserializer.java @@ -2,14 +2,14 @@ import java.lang.reflect.Type; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONToken; public class JSONObjectDeserializer implements ObjectDeserializer { public final static JSONObjectDeserializer instance = new JSONObjectDeserializer(); @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { return (T) parser.parseObject(); } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/JavaBeanDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/JavaBeanDeserializer.java old mode 100644 new mode 100755 index 38d21331bd..3883ab6827 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/JavaBeanDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/JavaBeanDeserializer.java @@ -1,119 +1,87 @@ package com.alibaba.fastjson.parser.deserializer; import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; +import java.lang.reflect.Proxy; import java.lang.reflect.Type; import java.util.ArrayList; +import java.util.HashMap; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.annotation.JSONField; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser.ResolveTask; import com.alibaba.fastjson.parser.Feature; -import com.alibaba.fastjson.parser.JSONScanner; +import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.ParseContext; import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.FilterUtils; +import com.alibaba.fastjson.util.DeserializeBeanInfo; import com.alibaba.fastjson.util.FieldInfo; +import com.alibaba.fastjson.util.TypeUtils; public class JavaBeanDeserializer implements ObjectDeserializer { - private final Map setters = new IdentityHashMap(); - - private final List fieldDeserializers = new ArrayList(); + private final Map feildDeserializerMap = new IdentityHashMap(); + private final List fieldDeserializers = new ArrayList(); + private final List sortedFieldDeserializers = new ArrayList(); private final Class clazz; - private Constructor constructor; + private DeserializeBeanInfo beanInfo; - public Map getFieldDeserializerMap() { - return setters; + public JavaBeanDeserializer(ParserConfig config, Class clazz){ + this(config, clazz, clazz); } - public JavaBeanDeserializer(ParserConfig mapping, Class clazz){ + public JavaBeanDeserializer(ParserConfig config, Class clazz, Type type){ this.clazz = clazz; - if (!Modifier.isAbstract(clazz.getModifiers())) { - try { - constructor = clazz.getDeclaredConstructor(); - constructor.setAccessible(true); - } catch (NoSuchMethodException e) { - throw new JSONException("class not has default constructor : " + clazz.getName()); - } - } - - List fieldInfoList = new ArrayList(); + beanInfo = DeserializeBeanInfo.computeSetters(clazz, type); - computeSetters(clazz, fieldInfoList); + for (FieldInfo fieldInfo : beanInfo.getFieldList()) { + addFieldDeserializer(config, clazz, fieldInfo); + } - for (FieldInfo fieldInfo : fieldInfoList) { - addFieldDeserializer(mapping, clazz, fieldInfo); + for (FieldInfo fieldInfo : beanInfo.getSortedFieldList()) { + FieldDeserializer fieldDeserializer = feildDeserializerMap.get(fieldInfo.getName().intern()); + sortedFieldDeserializers.add(fieldDeserializer); } } - public static void computeSetters(Class clazz, List fieldInfoList) { - for (Method method : clazz.getMethods()) { - String methodName = method.getName(); - if (methodName.length() < 4) { - continue; - } - - if (Modifier.isStatic(method.getModifiers())) { - continue; - } - - if (!method.getReturnType().equals(Void.TYPE)) { - continue; - } - - if (method.getParameterTypes().length != 1) { - continue; - } - - JSONField annotation = method.getAnnotation(JSONField.class); - - if (annotation != null) { - if (!annotation.deserialize()) { - continue; - } - - if (annotation.name().length() != 0) { - String propertyName = annotation.name(); - fieldInfoList.add(new FieldInfo(propertyName, method, null)); - method.setAccessible(true); - continue; - } - } - - if (methodName.startsWith("set") && Character.isUpperCase(methodName.charAt(3))) { - String propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4); - - Field field = getField(clazz, propertyName); - if (field != null) { - - JSONField fieldAnnotation = field.getAnnotation(JSONField.class); - - if (fieldAnnotation != null && fieldAnnotation.name().length() != 0) { - propertyName = fieldAnnotation.name(); - - fieldInfoList.add(new FieldInfo(propertyName, method, field)); - continue; - } - } - - fieldInfoList.add(new FieldInfo(propertyName, method, null)); - method.setAccessible(true); + public Map getFieldDeserializerMap() { + return feildDeserializerMap; + } + + public FieldDeserializer getFieldDeserializer(String name) { + FieldDeserializer feildDeser = feildDeserializerMap.get(name); + + if (feildDeser != null) { + return feildDeser; + } + + for (Map.Entry entry : feildDeserializerMap.entrySet()) { + if (name.equals(entry.getKey())) { + return entry.getValue(); } } + + return null; + } + + public Class getClazz() { + return clazz; } private void addFieldDeserializer(ParserConfig mapping, Class clazz, FieldInfo fieldInfo) { + String interName = fieldInfo.getName().intern(); FieldDeserializer fieldDeserializer = createFieldDeserializer(mapping, clazz, fieldInfo); - setters.put(fieldInfo.getName().intern(), fieldDeserializer); + feildDeserializerMap.put(interName, fieldDeserializer); fieldDeserializers.add(fieldDeserializer); } @@ -121,107 +89,367 @@ public FieldDeserializer createFieldDeserializer(ParserConfig mapping, Class return mapping.createFieldDeserializer(mapping, clazz, fieldInfo); } - public static Field getField(Class clazz, String fieldName) { - try { - return clazz.getDeclaredField(fieldName); - } catch (Exception e) { - return null; + public Object createInstance(DefaultJSONParser parser, Type type) { + if (type instanceof Class) { + if (clazz.isInterface()) { + Class clazz = (Class) type; + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + final JSONObject obj = new JSONObject(); + Object proxy = Proxy.newProxyInstance(loader, new Class[] { clazz }, obj); + return proxy; + } } - } - public Object createInstance(DefaultExtJSONParser parser, Type type) { + if (beanInfo.getDefaultConstructor() == null) { + return null; + } Object object; try { - object = constructor.newInstance(); + Constructor constructor = beanInfo.getDefaultConstructor(); + if (constructor.getParameterTypes().length == 0) { + object = constructor.newInstance(); + } else { + object = constructor.newInstance(parser.getContext().getObject()); + } } catch (Exception e) { throw new JSONException("create instance error, class " + clazz.getName(), e); } + if (parser.isEnabled(Feature.InitStringFieldAsEmpty)) { + for (FieldInfo fieldInfo : beanInfo.getFieldList()) { + if (fieldInfo.getFieldClass() == String.class) { + try { + fieldInfo.set(object, ""); + } catch (Exception e) { + throw new JSONException("create instance error, class " + clazz.getName(), e); + } + } + } + } + return object; } + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + return deserialze(parser, type, fieldName, null); + } + + @SuppressWarnings({ "unchecked" }) + public T deserialzeArrayMapping(DefaultJSONParser parser, Type type, Object fieldName, Object object) { + final JSONLexer lexer = parser.getLexer(); // xxx + if (lexer.token() != JSONToken.LBRACKET) { + throw new JSONException("error"); + } + + object = createInstance(parser, type); + + int size = sortedFieldDeserializers.size(); + for (int i = 0; i < size; ++i) { + final char seperator = (i == size - 1) ? ']' : ','; + FieldDeserializer fieldDeser = sortedFieldDeserializers.get(i); + Class fieldClass = fieldDeser.getFieldClass(); + if (fieldClass == int.class) { + int value = lexer.scanInt(seperator); + fieldDeser.setValue(object, value); + } else if (fieldClass == String.class) { + String value = lexer.scanString(seperator); + fieldDeser.setValue(object, value); + } else if (fieldClass == long.class) { + long value = lexer.scanLong(seperator); + fieldDeser.setValue(object, value); + } else if (fieldClass.isEnum()) { + Enum value = lexer.scanEnum(fieldClass, parser.getSymbolTable(), seperator); + fieldDeser.setValue(object, value); + } else { + lexer.nextToken(JSONToken.LBRACKET); + Object value = parser.parseObject(fieldDeser.getFieldType()); + fieldDeser.setValue(object, value); + + if (seperator == ']') { + if (lexer.token() != JSONToken.RBRACKET) { + throw new JSONException("syntax error"); + } + lexer.nextToken(JSONToken.COMMA); + } else if (seperator == ',') { + if (lexer.token() != JSONToken.COMMA) { + throw new JSONException("syntax error"); + } + } + } + } + lexer.nextToken(JSONToken.COMMA); + + return (T) object; + } + @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type type) { - JSONScanner lexer = (JSONScanner) parser.getLexer(); // xxx + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName, Object object) { + if (type == JSON.class || type == JSONObject.class) { + return (T) parser.parse(); + } + + final JSONLexer lexer = parser.getLexer(); // xxx if (lexer.token() == JSONToken.NULL) { lexer.nextToken(JSONToken.COMMA); return null; } - Object object = createInstance(parser, type); - - if (lexer.token() != JSONToken.LBRACE) { - throw new JSONException("syntax error, expect {, actual " + JSONToken.name(lexer.token())); + ParseContext context = parser.getContext(); + if (object != null && context != null) { + context = context.getParentContext(); } + ParseContext childContext = null; - for (;;) { + try { + Map fieldValues = null; - String key = lexer.scanSymbol(parser.getSymbolTable()); + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(JSONToken.COMMA); + if (object == null) { + object = createInstance(parser, type); + } + return (T) object; + } - if (key == null) { - if (lexer.token() == JSONToken.RBRACE) { + if (lexer.token() == JSONToken.LBRACKET && isSupportArrayToBean(lexer)) { + return deserialzeArrayMapping(parser, type, fieldName, object); + } + + if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) { + StringBuffer buf = (new StringBuffer()) // + .append("syntax error, expect {, actual ") // + .append(lexer.tokenName()) // + .append(", pos ") // + .append(lexer.pos()) // + ; + if (fieldName instanceof String) { + buf // + .append(", fieldName ") // + .append(fieldName); + } + throw new JSONException(buf.toString()); + } + + if (parser.getResolveStatus() == DefaultJSONParser.TypeNameRedirect) { + parser.setResolveStatus(DefaultJSONParser.NONE); + } + + for (;;) { + + String key = lexer.scanSymbol(parser.getSymbolTable()); + + if (key == null) { + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(JSONToken.COMMA); + break; + } + if (lexer.token() == JSONToken.COMMA) { + if (parser.isEnabled(Feature.AllowArbitraryCommas)) { + continue; + } + } + } + + if ("$ref" == key) { + lexer.nextTokenWithColon(JSONToken.LITERAL_STRING); + if (lexer.token() == JSONToken.LITERAL_STRING) { + String ref = lexer.stringVal(); + if ("@".equals(ref)) { + object = context.getObject(); + } else if ("..".equals(ref)) { + ParseContext parentContext = context.getParentContext(); + if (parentContext.getObject() != null) { + object = parentContext.getObject(); + } else { + parser.addResolveTask(new ResolveTask(parentContext, ref)); + parser.setResolveStatus(DefaultJSONParser.NeedToResolve); + } + } else if ("$".equals(ref)) { + ParseContext rootContext = context; + while (rootContext.getParentContext() != null) { + rootContext = rootContext.getParentContext(); + } + + if (rootContext.getObject() != null) { + object = rootContext.getObject(); + } else { + parser.addResolveTask(new ResolveTask(rootContext, ref)); + parser.setResolveStatus(DefaultJSONParser.NeedToResolve); + } + } else { + parser.addResolveTask(new ResolveTask(context, ref)); + parser.setResolveStatus(DefaultJSONParser.NeedToResolve); + } + } else { + throw new JSONException("illegal ref, " + JSONToken.name(lexer.token())); + } + + lexer.nextToken(JSONToken.RBRACE); + if (lexer.token() != JSONToken.RBRACE) { + throw new JSONException("illegal ref"); + } lexer.nextToken(JSONToken.COMMA); - break; + + parser.setContext(context, object, fieldName); + + return (T) object; } - if (lexer.token() == JSONToken.COMMA) { - if (parser.isEnabled(Feature.AllowArbitraryCommas)) { - continue; + + if (JSON.DEFAULT_TYPE_KEY == key) { + lexer.nextTokenWithColon(JSONToken.LITERAL_STRING); + if (lexer.token() == JSONToken.LITERAL_STRING) { + String typeName = lexer.stringVal(); + lexer.nextToken(JSONToken.COMMA); + + if (type instanceof Class && typeName.equals(((Class) type).getName())) { + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(); + break; + } + continue; + } + + Class userType = TypeUtils.loadClass(typeName); + ObjectDeserializer deserizer = parser.getConfig().getDeserializer(userType); + return (T) deserizer.deserialze(parser, userType, fieldName); + } else { + throw new JSONException("syntax error"); } } - } - boolean match = parseField(parser, key, object); - if (!match) { + if (object == null && fieldValues == null) { + object = createInstance(parser, type); + if (object == null) { + fieldValues = new HashMap(this.fieldDeserializers.size()); + } + childContext = parser.setContext(context, object, fieldName); + } + + boolean match = parseField(parser, key, object, type, fieldValues); + if (!match) { + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(); + break; + } + + continue; + } + + if (lexer.token() == JSONToken.COMMA) { + continue; + } + if (lexer.token() == JSONToken.RBRACE) { - lexer.nextToken(); - return (T) object; + lexer.nextToken(JSONToken.COMMA); + break; } - continue; + if (lexer.token() == JSONToken.IDENTIFIER || lexer.token() == JSONToken.ERROR) { + throw new JSONException("syntax error, unexpect token " + JSONToken.name(lexer.token())); + } } - if (lexer.token() == JSONToken.COMMA) { - continue; - } + if (object == null) { + if (fieldValues == null) { + object = createInstance(parser, type); + if (childContext == null) { + childContext = parser.setContext(context, object, fieldName); + } + return (T) object; + } - if (lexer.token() == JSONToken.RBRACE) { - lexer.nextToken(JSONToken.COMMA); - return (T) object; - } + List fieldInfoList = beanInfo.getFieldList(); + int size = fieldInfoList.size(); + Object[] params = new Object[size]; + for (int i = 0; i < size; ++i) { + FieldInfo fieldInfo = fieldInfoList.get(i); + params[i] = fieldValues.get(fieldInfo.getName()); + } - if (lexer.token() == JSONToken.IDENTIFIER || lexer.token() == JSONToken.ERROR) { - throw new JSONException("syntax error, unexpect token " + JSONToken.name(lexer.token())); + if (beanInfo.getCreatorConstructor() != null) { + try { + object = beanInfo.getCreatorConstructor().newInstance(params); + } catch (Exception e) { + throw new JSONException("create instance error, " + + beanInfo.getCreatorConstructor().toGenericString(), e); + } + } else if (beanInfo.getFactoryMethod() != null) { + try { + object = beanInfo.getFactoryMethod().invoke(null, params); + } catch (Exception e) { + throw new JSONException("create factory method error, " + + beanInfo.getFactoryMethod().toString(), e); + } + } } + return (T) object; + } finally { + if (childContext != null) { + childContext.setObject(object); + } + parser.setContext(context); } - - return (T) object; } - public boolean parseField(DefaultExtJSONParser parser, String key, Object object) { - JSONScanner lexer = (JSONScanner) parser.getLexer(); // xxx + public boolean parseField(DefaultJSONParser parser, String key, Object object, Type objectType, + Map fieldValues) { + JSONLexer lexer = parser.getLexer(); // xxx + + FieldDeserializer fieldDeserializer = feildDeserializerMap.get(key); - FieldDeserializer fieldDeserializer = setters.get(key); if (fieldDeserializer == null) { - if (!parser.isEnabled(Feature.IgnoreNotMatch)) { - throw new JSONException("setter not found, class " + clazz.getName() + ", property " + key); + for (Map.Entry entry : feildDeserializerMap.entrySet()) { + if (entry.getKey().equalsIgnoreCase(key)) { + fieldDeserializer = entry.getValue(); + break; + } } + } - lexer.nextTokenWithColon(); - parser.parse(); // skip + if (fieldDeserializer == null) { + parseExtra(parser, object, key); return false; } lexer.nextTokenWithColon(fieldDeserializer.getFastMatchToken()); - fieldDeserializer.parseField(parser, object); + + fieldDeserializer.parseField(parser, object, objectType, fieldValues); + return true; } + void parseExtra(DefaultJSONParser parser, Object object, String key) { + final JSONLexer lexer = parser.getLexer(); // xxx + if (!lexer.isEnabled(Feature.IgnoreNotMatch)) { + throw new JSONException("setter not found, class " + clazz.getName() + ", property " + key); + } + + lexer.nextTokenWithColon(); + Type type = FilterUtils.getExtratype(parser, object, key); + Object value; + if (type == null) { + value = parser.parse(); // skip + } else { + value = parser.parseObject(type); + } + + FilterUtils.processExtra(parser, object, key, value); + } + public int getFastMatchToken() { return JSONToken.LBRACE; } + + public List getSortedFieldDeserializers() { + return sortedFieldDeserializers; + } + + public final boolean isSupportArrayToBean(JSONLexer lexer) { + return Feature.isEnabled(beanInfo.getParserFeatures(), Feature.SupportArrayToBean) || lexer.isEnabled(Feature.SupportArrayToBean); + } } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/JavaObjectDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/JavaObjectDeserializer.java index ebc39c26b8..184e7af67f 100644 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/JavaObjectDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/JavaObjectDeserializer.java @@ -1,17 +1,58 @@ package com.alibaba.fastjson.parser.deserializer; +import java.lang.reflect.Array; +import java.lang.reflect.GenericArrayType; import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.util.ArrayList; +import java.util.List; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.util.TypeUtils; public class JavaObjectDeserializer implements ObjectDeserializer { public final static JavaObjectDeserializer instance = new JavaObjectDeserializer(); @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - return (T) parser.parse(); + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + if (type instanceof GenericArrayType) { + Type componentType = ((GenericArrayType) type).getGenericComponentType(); + if (componentType instanceof TypeVariable) { + TypeVariable componentVar = (TypeVariable) componentType; + componentType = componentVar.getBounds()[0]; + } + + List list = new ArrayList(); + parser.parseArray(componentType, list); + Class componentClass; + if (componentType instanceof Class) { + componentClass = (Class) componentType; + if (componentClass == boolean.class) { + return (T) TypeUtils.cast(list, boolean[].class, parser.getConfig()); + } else if (componentClass == short.class) { + return (T) TypeUtils.cast(list, short[].class, parser.getConfig()); + } else if (componentClass == int.class) { + return (T) TypeUtils.cast(list, int[].class, parser.getConfig()); + } else if (componentClass == long.class) { + return (T) TypeUtils.cast(list, long[].class, parser.getConfig()); + } else if (componentClass == float.class) { + return (T) TypeUtils.cast(list, float[].class, parser.getConfig()); + } else if (componentClass == double.class) { + return (T) TypeUtils.cast(list, double[].class, parser.getConfig()); + } + + Object[] array = (Object[]) Array.newInstance(componentClass, list.size()); + list.toArray(array); + return (T) array; + } else { + return (T) list.toArray(); + } + + } + + return (T) parser.parse(fieldName); } public int getFastMatchToken() { diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/Jdk8DateCodec.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/Jdk8DateCodec.java new file mode 100644 index 0000000000..0e4e2d4293 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/Jdk8DateCodec.java @@ -0,0 +1,96 @@ +package com.alibaba.fastjson.parser.deserializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.Period; +import java.time.ZoneId; +import java.time.ZonedDateTime; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.ObjectSerializer; +import com.alibaba.fastjson.serializer.SerializeWriter; + +public class Jdk8DateCodec implements ObjectSerializer, ObjectDeserializer { + + public static final Jdk8DateCodec instance = new Jdk8DateCodec(); + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + JSONLexer lexer = parser.getLexer(); + if (lexer.token() == JSONToken.LITERAL_STRING) { + String text = lexer.stringVal(); + lexer.nextToken(); + + if (type == LocalDateTime.class) { + LocalDateTime localDateTime = LocalDateTime.parse(text); + + return (T) localDateTime; + } else if (type == LocalDate.class) { + LocalDate localDate = LocalDate.parse(text); + + return (T) localDate; + } else if (type == LocalTime.class) { + LocalTime localDate = LocalTime.parse(text); + + return (T) localDate; + } else if (type == ZonedDateTime.class) { + ZonedDateTime zonedDateTime = ZonedDateTime.parse(text); + + return (T) zonedDateTime; + } else if (type == OffsetDateTime.class) { + OffsetDateTime offsetDateTime = OffsetDateTime.parse(text); + + return (T) offsetDateTime; + } else if (type == OffsetTime.class) { + OffsetTime offsetTime = OffsetTime.parse(text); + + return (T) offsetTime; + } else if (type == ZoneId.class) { + ZoneId offsetTime = ZoneId.of(text); + + return (T) offsetTime; + } else if (type == Period.class) { + Period period = Period.parse(text); + + return (T) period; + } else if (type == Duration.class) { + Duration duration = Duration.parse(text); + + return (T) duration; + } else if (type == Instant.class) { + Instant instant = Instant.parse(text); + + return (T) instant; + } + } else { + throw new UnsupportedOperationException(); + } + return null; + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + SerializeWriter out = serializer.getWriter(); + + if (object == null) { + out.writeNull(); + return; + } + + out.writeString(object.toString()); + } + +} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/LinkedHashMapDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/LinkedHashMapDeserializer.java deleted file mode 100644 index a90a656600..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/LinkedHashMapDeserializer.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.util.LinkedHashMap; -import java.util.Map; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; - -public class LinkedHashMapDeserializer implements ObjectDeserializer { - public final static LinkedHashMapDeserializer instance = new LinkedHashMapDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - Map map = new LinkedHashMap(); - parser.parseObject(map); - return (T) map; - } - - public int getFastMatchToken() { - return JSONToken.LBRACE; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ListResolveFieldDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ListResolveFieldDeserializer.java new file mode 100755 index 0000000000..c712393c79 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/ListResolveFieldDeserializer.java @@ -0,0 +1,54 @@ +package com.alibaba.fastjson.parser.deserializer; + +import java.lang.reflect.Array; +import java.lang.reflect.Type; +import java.util.List; +import java.util.Map; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.util.TypeUtils; + +@SuppressWarnings("rawtypes") +public final class ListResolveFieldDeserializer extends FieldDeserializer { + + private final int index; + private final List list; + private final DefaultJSONParser parser; + + public ListResolveFieldDeserializer(DefaultJSONParser parser, List list, int index){ + super(null, null); + this.parser = parser; + this.index = index; + this.list = list; + } + + @SuppressWarnings("unchecked") + public void setValue(Object object, Object value) { + list.set(index, value); + + if (list instanceof JSONArray) { + JSONArray jsonArray = (JSONArray) list; + Object array = jsonArray.getRelatedArray(); + + if (array != null) { + int arrayLength = Array.getLength(array); + + if (arrayLength > index) { + Object item; + if (jsonArray.getComponentType() != null) { + item = TypeUtils.cast(value, jsonArray.getComponentType(), parser.getConfig()); + } else { + item = value; + } + Array.set(array, index, item); + } + } + } + } + + public void parseField(DefaultJSONParser parser, Object object, Type objectType, Map fieldValues) { + + } + +} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/LocaleDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/LocaleDeserializer.java deleted file mode 100644 index b8057a44a9..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/LocaleDeserializer.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.util.Locale; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; - -public class LocaleDeserializer implements ObjectDeserializer { - public final static LocaleDeserializer instance = new LocaleDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - String text = (String) parser.parse(); - - if (text == null) { - return null; - } - - String[] items = text.split("_"); - - if (items.length == 1) { - return (T) new Locale(items[0]); - } - - if (items.length == 2) { - return (T) new Locale(items[0], items[1]); - } - - return (T) new Locale(items[0], items[1], items[2]); - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_STRING; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/LongDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/LongDeserializer.java deleted file mode 100644 index 55a34b2276..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/LongDeserializer.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONLexer; -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.util.TypeUtils; - -public class LongDeserializer implements ObjectDeserializer { - - public final static LongDeserializer instance = new LongDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - return (T) deserialze(parser); - } - - @SuppressWarnings("unchecked") - public static T deserialze(DefaultExtJSONParser parser) { - final JSONLexer lexer = parser.getLexer(); - if (lexer.token() == JSONToken.LITERAL_INT) { - long longValue = lexer.longValue(); - lexer.nextToken(JSONToken.COMMA); - return (T) Long.valueOf(longValue); - } - - Object value = parser.parse(); - - if (value == null) { - return null; - } - - return (T) TypeUtils.castToLong(value); - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_INT; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/LongFieldDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/LongFieldDeserializer.java old mode 100644 new mode 100755 index b2e5b23138..1aecab215d --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/LongFieldDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/LongFieldDeserializer.java @@ -1,6 +1,9 @@ package com.alibaba.fastjson.parser.deserializer; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import java.lang.reflect.Type; +import java.util.Map; + +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; @@ -18,14 +21,18 @@ public LongFieldDeserializer(ParserConfig mapping, Class clazz, FieldInfo fie } @Override - public void parseField(DefaultExtJSONParser parser, Object object) { + public void parseField(DefaultJSONParser parser, Object object, Type objectType, Map fieldValues) { Long value; final JSONLexer lexer = parser.getLexer(); if (lexer.token() == JSONToken.LITERAL_INT) { long val = lexer.longValue(); lexer.nextToken(JSONToken.COMMA); - setValue(object, val); + if (object == null) { + fieldValues.put(fieldInfo.getName(), val); + } else { + setValue(object, val); + } return; } else if (lexer.token() == JSONToken.NULL) { value = null; @@ -42,7 +49,11 @@ public void parseField(DefaultExtJSONParser parser, Object object) { return; } - setValue(object, value); + if (object == null) { + fieldValues.put(fieldInfo.getName(), value); + } else { + setValue(object, value); + } } public int getFastMatchToken() { diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/MapDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/MapDeserializer.java new file mode 100755 index 0000000000..7de1b4f75a --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/MapDeserializer.java @@ -0,0 +1,330 @@ +package com.alibaba.fastjson.parser.deserializer; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.IdentityHashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Properties; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser.ResolveTask; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.ParseContext; +import com.alibaba.fastjson.util.TypeUtils; + +public class MapDeserializer implements ObjectDeserializer { + + public final static MapDeserializer instance = new MapDeserializer(); + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + final JSONLexer lexer = parser.getLexer(); + if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(JSONToken.COMMA); + return null; + } + + Map map = createMap(type); + + ParseContext context = parser.getContext(); + + try { + parser.setContext(context, map, fieldName); + return (T) deserialze(parser, type, fieldName, map); + } finally { + parser.setContext(context); + } + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected Object deserialze(DefaultJSONParser parser, Type type, Object fieldName, Map map) { + if (type instanceof ParameterizedType) { + ParameterizedType parameterizedType = (ParameterizedType) type; + Type keyType = parameterizedType.getActualTypeArguments()[0]; + Type valueType = parameterizedType.getActualTypeArguments()[1]; + + if (String.class == keyType) { + return parseMap(parser, (Map) map, valueType, fieldName); + } else { + return parseMap(parser, map, keyType, valueType, fieldName); + } + } else { + return parser.parseObject(map, fieldName); + } + } + + @SuppressWarnings("rawtypes") + public static Map parseMap(DefaultJSONParser parser, Map map, Type valueType, Object fieldName) { + JSONLexer lexer = parser.getLexer(); + + if (lexer.token() != JSONToken.LBRACE) { + throw new JSONException("syntax error, expect {, actual " + lexer.token()); + } + + ParseContext context = parser.getContext(); + try { + for (;;) { + lexer.skipWhitespace(); + char ch = lexer.getCurrent(); + if (parser.isEnabled(Feature.AllowArbitraryCommas)) { + while (ch == ',') { + lexer.next(); + lexer.skipWhitespace(); + ch = lexer.getCurrent(); + } + } + + String key; + if (ch == '"') { + key = lexer.scanSymbol(parser.getSymbolTable(), '"'); + lexer.skipWhitespace(); + ch = lexer.getCurrent(); + if (ch != ':') { + throw new JSONException("expect ':' at " + lexer.pos()); + } + } else if (ch == '}') { + lexer.next(); + lexer.resetStringPosition(); + lexer.nextToken(JSONToken.COMMA); + return map; + } else if (ch == '\'') { + if (!parser.isEnabled(Feature.AllowSingleQuotes)) { + throw new JSONException("syntax error"); + } + + key = lexer.scanSymbol(parser.getSymbolTable(), '\''); + lexer.skipWhitespace(); + ch = lexer.getCurrent(); + if (ch != ':') { + throw new JSONException("expect ':' at " + lexer.pos()); + } + } else { + if (!parser.isEnabled(Feature.AllowUnQuotedFieldNames)) { + throw new JSONException("syntax error"); + } + + key = lexer.scanSymbolUnQuoted(parser.getSymbolTable()); + lexer.skipWhitespace(); + ch = lexer.getCurrent(); + if (ch != ':') { + throw new JSONException("expect ':' at " + lexer.pos() + ", actual " + ch); + } + } + + lexer.next(); + lexer.skipWhitespace(); + ch = lexer.getCurrent(); + + lexer.resetStringPosition(); + + if (key == JSON.DEFAULT_TYPE_KEY) { + String typeName = lexer.scanSymbol(parser.getSymbolTable(), '"'); + Class clazz = TypeUtils.loadClass(typeName); + + if (Map.class.isAssignableFrom(clazz) ) { + lexer.nextToken(JSONToken.COMMA); + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(JSONToken.COMMA); + return map; + } + continue; + } + + ObjectDeserializer deserializer = parser.getConfig().getDeserializer(clazz); + + lexer.nextToken(JSONToken.COMMA); + + parser.setResolveStatus(DefaultJSONParser.TypeNameRedirect); + + if (context != null && !(fieldName instanceof Integer)) { + parser.popContext(); + } + + return (Map) deserializer.deserialze(parser, clazz, fieldName); + } + + Object value; + lexer.nextToken(); + + if (lexer.token() == JSONToken.NULL) { + value = null; + lexer.nextToken(); + } else { + value = parser.parseObject(valueType); + } + + map.put(key, value); + parser.checkMapResolve(map, key); + + parser.setContext(context, value, key); + + final int tok = lexer.token(); + if (tok == JSONToken.EOF || tok == JSONToken.RBRACKET) { + return map; + } + + if (tok == JSONToken.RBRACE) { + lexer.nextToken(); + return map; + } + } + } finally { + parser.setContext(context); + } + + } + + public static Object parseMap(DefaultJSONParser parser, Map map, Type keyType, Type valueType, + Object fieldName) { + JSONLexer lexer = parser.getLexer(); + + if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) { + throw new JSONException("syntax error, expect {, actual " + lexer.tokenName()); + } + + ObjectDeserializer keyDeserializer = parser.getConfig().getDeserializer(keyType); + ObjectDeserializer valueDeserializer = parser.getConfig().getDeserializer(valueType); + lexer.nextToken(keyDeserializer.getFastMatchToken()); + + ParseContext context = parser.getContext(); + try { + for (;;) { + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(JSONToken.COMMA); + break; + } + + if (lexer.token() == JSONToken.LITERAL_STRING && lexer.isRef()) { + Object object = null; + + lexer.nextTokenWithColon(JSONToken.LITERAL_STRING); + if (lexer.token() == JSONToken.LITERAL_STRING) { + String ref = lexer.stringVal(); + if ("..".equals(ref)) { + ParseContext parentContext = context.getParentContext(); + object = parentContext.getObject(); + } else if ("$".equals(ref)) { + ParseContext rootContext = context; + while (rootContext.getParentContext() != null) { + rootContext = rootContext.getParentContext(); + } + + object = rootContext.getObject(); + } else { + parser.addResolveTask(new ResolveTask(context, ref)); + parser.setResolveStatus(DefaultJSONParser.NeedToResolve); + } + } else { + throw new JSONException("illegal ref, " + JSONToken.name(lexer.token())); + } + + lexer.nextToken(JSONToken.RBRACE); + if (lexer.token() != JSONToken.RBRACE) { + throw new JSONException("illegal ref"); + } + lexer.nextToken(JSONToken.COMMA); + + // parser.setContext(context, map, fieldName); + // parser.setContext(context); + + return object; + } + + if (map.size() == 0 // + && lexer.token() == JSONToken.LITERAL_STRING // + && JSON.DEFAULT_TYPE_KEY.equals(lexer.stringVal())) { + lexer.nextTokenWithColon(JSONToken.LITERAL_STRING); + lexer.nextToken(JSONToken.COMMA); + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(); + return map; + } + lexer.nextToken(keyDeserializer.getFastMatchToken()); + } + + Object key = keyDeserializer.deserialze(parser, keyType, null); + + if (lexer.token() != JSONToken.COLON) { + throw new JSONException("syntax error, expect :, actual " + lexer.token()); + } + + lexer.nextToken(valueDeserializer.getFastMatchToken()); + + Object value = valueDeserializer.deserialze(parser, valueType, key); + + map.put(key, value); + + if (lexer.token() == JSONToken.COMMA) { + lexer.nextToken(keyDeserializer.getFastMatchToken()); + } + } + } finally { + parser.setContext(context); + } + + return map; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected Map createMap(Type type) { + if (type == Properties.class) { + return new Properties(); + } + + if (type == Hashtable.class) { + return new Hashtable(); + } + + if (type == IdentityHashMap.class) { + return new IdentityHashMap(); + } + + if (type == SortedMap.class || type == TreeMap.class) { + return new TreeMap(); + } + + if (type == ConcurrentMap.class || type == ConcurrentHashMap.class) { + return new ConcurrentHashMap(); + } + + if (type == Map.class || type == HashMap.class) { + return new HashMap(); + } + + if (type == LinkedHashMap.class) { + return new LinkedHashMap(); + } + + if (type instanceof ParameterizedType) { + ParameterizedType parameterizedType = (ParameterizedType) type; + + return createMap(parameterizedType.getRawType()); + } + + Class clazz = (Class) type; + if (clazz.isInterface()) { + throw new JSONException("unsupport type " + type); + } + + try { + return (Map) clazz.newInstance(); + } catch (Exception e) { + throw new JSONException("unsupport type " + type, e); + } + } + + public int getFastMatchToken() { + return JSONToken.LBRACE; + } +} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/MapResolveFieldDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/MapResolveFieldDeserializer.java new file mode 100755 index 0000000000..9a249a799e --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/MapResolveFieldDeserializer.java @@ -0,0 +1,30 @@ +package com.alibaba.fastjson.parser.deserializer; + +import java.lang.reflect.Type; +import java.util.Map; + +import com.alibaba.fastjson.parser.DefaultJSONParser; + +@SuppressWarnings("rawtypes") +public final class MapResolveFieldDeserializer extends FieldDeserializer { + + private final String key; + private final Map map; + + public MapResolveFieldDeserializer(Map map, String index){ + super(null, null); + this.key = index; + this.map = map; + } + + @SuppressWarnings("unchecked") + public void setValue(Object object, Object value) { + map.put(key, value); + } + + + @Override + public void parseField(DefaultJSONParser parser, Object object, Type objectType, Map fieldValues) { + + } +} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/NumberDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/NumberDeserializer.java old mode 100644 new mode 100755 index c56708f02c..fddb97545a --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/NumberDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/NumberDeserializer.java @@ -3,7 +3,7 @@ import java.lang.reflect.Type; import java.math.BigDecimal; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.util.TypeUtils; @@ -13,26 +13,50 @@ public class NumberDeserializer implements ObjectDeserializer { public final static NumberDeserializer instance = new NumberDeserializer(); @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - return (T) deserialze(parser); - } - - @SuppressWarnings("unchecked") - public static T deserialze(DefaultExtJSONParser parser) { + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { final JSONLexer lexer = parser.getLexer(); if (lexer.token() == JSONToken.LITERAL_INT) { + if (clazz == double.class || clazz == Double.class) { + String val = lexer.numberString(); + lexer.nextToken(JSONToken.COMMA); + return (T) Double.valueOf(Double.parseDouble(val)); + } + long val = lexer.longValue(); lexer.nextToken(JSONToken.COMMA); - + + if (clazz == short.class || clazz == Short.class) { + return (T) Short.valueOf((short) val); + } + + if (clazz == byte.class || clazz == Byte.class) { + return (T) Byte.valueOf((byte) val); + } + if (val >= Integer.MIN_VALUE && val <= Integer.MAX_VALUE) { - return (T) Integer.valueOf((int) val); + return (T) Integer.valueOf((int) val); } return (T) Long.valueOf(val); } if (lexer.token() == JSONToken.LITERAL_FLOAT) { + if (clazz == double.class || clazz == Double.class) { + String val = lexer.numberString(); + lexer.nextToken(JSONToken.COMMA); + return (T) Double.valueOf(Double.parseDouble(val)); + } + BigDecimal val = lexer.decimalValue(); lexer.nextToken(JSONToken.COMMA); + + if (clazz == short.class || clazz == Short.class) { + return (T) Short.valueOf(val.shortValue()); + } + + if (clazz == byte.class || clazz == Byte.class) { + return (T) Byte.valueOf(val.byteValue()); + } + return (T) val; } @@ -42,6 +66,18 @@ public static T deserialze(DefaultExtJSONParser parser) { return null; } + if (clazz == double.class || clazz == Double.class) { + return (T) TypeUtils.castToDouble(value); + } + + if (clazz == short.class || clazz == Short.class) { + return (T) TypeUtils.castToShort(value); + } + + if (clazz == byte.class || clazz == Byte.class) { + return (T) TypeUtils.castToByte(value); + } + return (T) TypeUtils.castToBigDecimal(value); } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ObjectDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ObjectDeserializer.java old mode 100644 new mode 100755 index 1c29402d01..fe923d2284 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/ObjectDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/ObjectDeserializer.java @@ -2,10 +2,10 @@ import java.lang.reflect.Type; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; public interface ObjectDeserializer { - T deserialze(DefaultExtJSONParser parser, Type type); + T deserialze(DefaultJSONParser parser, Type type, Object fieldName); int getFastMatchToken(); } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ParseProcess.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ParseProcess.java new file mode 100644 index 0000000000..c2273f6d0c --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/ParseProcess.java @@ -0,0 +1,6 @@ +package com.alibaba.fastjson.parser.deserializer; + + +public interface ParseProcess { + +} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/PatternDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/PatternDeserializer.java deleted file mode 100644 index 61b92b8727..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/PatternDeserializer.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.util.regex.Pattern; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; - -public class PatternDeserializer implements ObjectDeserializer { - public final static PatternDeserializer instance = new PatternDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - Object value = parser.parse(); - - if (value == null) { - return null; - } - - String pattern = (String) value; - - return (T) Pattern.compile(pattern); - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_STRING; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ShortDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ShortDeserializer.java deleted file mode 100644 index 76866b12a0..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/ShortDeserializer.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.util.TypeUtils; - -public class ShortDeserializer implements ObjectDeserializer { - public final static ShortDeserializer instance = new ShortDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - Object value = parser.parse(); - - if (value == null) { - return null; - } - - return (T) TypeUtils.castToShort(value); - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_INT; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/SqlDateDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/SqlDateDeserializer.java old mode 100644 new mode 100755 index 58ed55cf02..62dac77d5f --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/SqlDateDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/SqlDateDeserializer.java @@ -1,22 +1,25 @@ package com.alibaba.fastjson.parser.deserializer; import java.lang.reflect.Type; +import java.text.DateFormat; +import java.text.ParseException; import java.util.Date; import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONScanner; import com.alibaba.fastjson.parser.JSONToken; -public class SqlDateDeserializer implements ObjectDeserializer { +public class SqlDateDeserializer extends AbstractDateDeserializer implements ObjectDeserializer { + public final static SqlDateDeserializer instance = new SqlDateDeserializer(); @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - Object val = parser.parse(); + protected T cast(DefaultJSONParser parser, Type clazz, Object fieldName, Object val) { if (val == null) { return null; } - + if (val instanceof java.util.Date) { val = new java.sql.Date(((Date) val).getTime()); } else if (val instanceof Number) { @@ -26,8 +29,29 @@ public T deserialze(DefaultExtJSONParser parser, Type clazz) { if (strVal.length() == 0) { return null; } - - long longVal = Long.parseLong(strVal); + + long longVal; + + JSONScanner dateLexer = new JSONScanner(strVal); + try { + if (dateLexer.scanISO8601DateIfMatch()) { + longVal = dateLexer.getCalendar().getTimeInMillis(); + } else { + + DateFormat dateFormat = parser.getDateFormat(); + try { + java.util.Date date = (java.util.Date) dateFormat.parse(strVal); + java.sql.Date sqlDate = new java.sql.Date(date.getTime()); + return (T) sqlDate; + } catch (ParseException e) { + // skip + } + + longVal = Long.parseLong(strVal); + } + } finally { + dateLexer.close(); + } return (T) new java.sql.Date(longVal); } else { throw new JSONException("parse error : " + val); diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/StackTraceElementDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/StackTraceElementDeserializer.java new file mode 100755 index 0000000000..826e9d8756 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/StackTraceElementDeserializer.java @@ -0,0 +1,118 @@ +package com.alibaba.fastjson.parser.deserializer; + +import java.lang.reflect.Type; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; + +public class StackTraceElementDeserializer implements ObjectDeserializer { + + public final static StackTraceElementDeserializer instance = new StackTraceElementDeserializer(); + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + JSONLexer lexer = parser.getLexer(); + if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(); + return null; + } + + if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) { + throw new JSONException("syntax error: " + JSONToken.name(lexer.token())); + } + + String declaringClass = null; + String methodName = null; + String fileName = null; + int lineNumber = 0; + + for (;;) { + // lexer.scanSymbol + String key = lexer.scanSymbol(parser.getSymbolTable()); + + if (key == null) { + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(JSONToken.COMMA); + break; + } + if (lexer.token() == JSONToken.COMMA) { + if (lexer.isEnabled(Feature.AllowArbitraryCommas)) { + continue; + } + } + } + + lexer.nextTokenWithColon(JSONToken.LITERAL_STRING); + if ("className".equals(key)) { + if (lexer.token() == JSONToken.NULL) { + declaringClass = null; + } else if (lexer.token() == JSONToken.LITERAL_STRING) { + declaringClass = lexer.stringVal(); + } else { + throw new JSONException("syntax error"); + } + } else if ("methodName".equals(key)) { + if (lexer.token() == JSONToken.NULL) { + methodName = null; + } else if (lexer.token() == JSONToken.LITERAL_STRING) { + methodName = lexer.stringVal(); + } else { + throw new JSONException("syntax error"); + } + } else if ("fileName".equals(key)) { + if (lexer.token() == JSONToken.NULL) { + fileName = null; + } else if (lexer.token() == JSONToken.LITERAL_STRING) { + fileName = lexer.stringVal(); + } else { + throw new JSONException("syntax error"); + } + } else if ("lineNumber".equals(key)) { + if (lexer.token() == JSONToken.NULL) { + lineNumber = 0; + } else if (lexer.token() == JSONToken.LITERAL_INT) { + lineNumber = lexer.intValue(); + } else { + throw new JSONException("syntax error"); + } + } else if ("nativeMethod".equals(key)) { + if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(JSONToken.COMMA); + } else if (lexer.token() == JSONToken.TRUE) { + lexer.nextToken(JSONToken.COMMA); + } else if (lexer.token() == JSONToken.FALSE) { + lexer.nextToken(JSONToken.COMMA); + } else { + throw new JSONException("syntax error"); + } + } else if (key == JSON.DEFAULT_TYPE_KEY) { + if (lexer.token() == JSONToken.LITERAL_STRING) { + String elementType = lexer.stringVal(); + if (!elementType.equals("java.lang.StackTraceElement")) { + throw new JSONException("syntax error : " + elementType); + } + } else { + if (lexer.token() != JSONToken.NULL) { + throw new JSONException("syntax error"); + } + } + } else { + throw new JSONException("syntax error : " + key); + } + + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(JSONToken.COMMA); + break; + } + } + return (T) new StackTraceElement(declaringClass, methodName, fileName, lineNumber); + } + + public int getFastMatchToken() { + return JSONToken.LBRACE; + } +} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/StringFieldDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/StringFieldDeserializer.java old mode 100644 new mode 100755 index 12dec3a71a..f7fa9d016b --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/StringFieldDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/StringFieldDeserializer.java @@ -1,6 +1,9 @@ package com.alibaba.fastjson.parser.deserializer; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import java.lang.reflect.Type; +import java.util.Map; + +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; @@ -17,7 +20,7 @@ public StringFieldDeserializer(ParserConfig config, Class clazz, FieldInfo fi } @Override - public void parseField(DefaultExtJSONParser parser, Object object) { + public void parseField(DefaultJSONParser parser, Object object, Type objectType, Map fieldValues) { String value; final JSONLexer lexer = parser.getLexer(); @@ -35,7 +38,11 @@ public void parseField(DefaultExtJSONParser parser, Object object) { } } - setValue(object, value); + if (object == null) { + fieldValues.put(fieldInfo.getName(), value); + } else { + setValue(object, value); + } } public int getFastMatchToken() { diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/ThrowableDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/ThrowableDeserializer.java old mode 100644 new mode 100755 index 6ea442b326..94ce677cc4 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/ThrowableDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/ThrowableDeserializer.java @@ -1,8 +1,15 @@ package com.alibaba.fastjson.parser.deserializer; +import java.lang.reflect.Constructor; import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.util.TypeUtils; @@ -14,9 +21,142 @@ public ThrowableDeserializer(ParserConfig mapping, Class clazz){ } @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - Object jsonValue = parser.parse(); - return (T) TypeUtils.cast(jsonValue, clazz, parser.getConfig()); + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + JSONLexer lexer = parser.getLexer(); + + if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(); + return null; + } + + if (parser.getResolveStatus() == DefaultJSONParser.TypeNameRedirect) { + parser.setResolveStatus(DefaultJSONParser.NONE); + } else { + if (lexer.token() != JSONToken.LBRACE) { + throw new JSONException("syntax error"); + } + } + + Throwable cause = null; + Class exClass = null; + + if (type != null && type instanceof Class) { + Class clazz = (Class) type; + if (Throwable.class.isAssignableFrom(clazz)) { + exClass = clazz; + } + } + + String message = null; + StackTraceElement[] stackTrace = null; + Map otherValues = new HashMap(); + + for (;;) { + // lexer.scanSymbol + String key = lexer.scanSymbol(parser.getSymbolTable()); + + if (key == null) { + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(JSONToken.COMMA); + break; + } + if (lexer.token() == JSONToken.COMMA) { + if (lexer.isEnabled(Feature.AllowArbitraryCommas)) { + continue; + } + } + } + + lexer.nextTokenWithColon(JSONToken.LITERAL_STRING); + + if (JSON.DEFAULT_TYPE_KEY.equals(key)) { + if (lexer.token() == JSONToken.LITERAL_STRING) { + String exClassName = lexer.stringVal(); + exClass = TypeUtils.loadClass(exClassName); + } else { + throw new JSONException("syntax error"); + } + lexer.nextToken(JSONToken.COMMA); + } else if ("message".equals(key)) { + if (lexer.token() == JSONToken.NULL) { + message = null; + } else if (lexer.token() == JSONToken.LITERAL_STRING) { + message = lexer.stringVal(); + } else { + throw new JSONException("syntax error"); + } + lexer.nextToken(); + } else if ("cause".equals(key)) { + cause = deserialze(parser, null, "cause"); + } else if ("stackTrace".equals(key)) { + stackTrace = parser.parseObject(StackTraceElement[].class); + } else { + // TODO + otherValues.put(key, parser.parse()); + } + + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(JSONToken.COMMA); + break; + } + } + + Throwable ex = null; + if (exClass == null) { + ex = new Exception(message, cause); + } else { + try { + ex = createException(message, cause, exClass); + if (ex == null) { + ex = new Exception(message, cause); + } + } catch (Exception e) { + throw new JSONException("create instance error", e); + } + } + + if (stackTrace != null) { + ex.setStackTrace(stackTrace); + } + + return (T) ex; + } + + private Throwable createException(String message, Throwable cause, Class exClass) throws Exception { + Constructor defaultConstructor = null; + Constructor messageConstructor = null; + Constructor causeConstructor = null; + for (Constructor constructor : exClass.getConstructors()) { + if (constructor.getParameterTypes().length == 0) { + defaultConstructor = constructor; + continue; + } + + if (constructor.getParameterTypes().length == 1 && constructor.getParameterTypes()[0] == String.class) { + messageConstructor = constructor; + continue; + } + + if (constructor.getParameterTypes().length == 2 && constructor.getParameterTypes()[0] == String.class + && constructor.getParameterTypes()[1] == Throwable.class) { + causeConstructor = constructor; + continue; + } + } + + if (causeConstructor != null) { + return (Throwable) causeConstructor.newInstance(message, cause); + } + + if (messageConstructor != null) { + return (Throwable) messageConstructor.newInstance(message); + } + + if (defaultConstructor != null) { + return (Throwable) defaultConstructor.newInstance(); + } + + return null; } public int getFastMatchToken() { diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/TimeDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/TimeDeserializer.java new file mode 100755 index 0000000000..5d4209e852 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/TimeDeserializer.java @@ -0,0 +1,75 @@ +package com.alibaba.fastjson.parser.deserializer; + +import java.lang.reflect.Type; + +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONScanner; +import com.alibaba.fastjson.parser.JSONToken; + +public class TimeDeserializer implements ObjectDeserializer { + + public final static TimeDeserializer instance = new TimeDeserializer(); + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + JSONLexer lexer = parser.getLexer(); + + if (lexer.token() == JSONToken.COMMA) { + lexer.nextToken(JSONToken.LITERAL_STRING); + + if (lexer.token() != JSONToken.LITERAL_STRING) { + throw new JSONException("syntax error"); + } + + lexer.nextTokenWithColon(JSONToken.LITERAL_INT); + + if (lexer.token() != JSONToken.LITERAL_INT) { + throw new JSONException("syntax error"); + } + + long time = lexer.longValue(); + lexer.nextToken(JSONToken.RBRACE); + if (lexer.token() != JSONToken.RBRACE) { + throw new JSONException("syntax error"); + } + lexer.nextToken(JSONToken.COMMA); + + return (T) new java.sql.Time(time); + } + + Object val = parser.parse(); + + if (val == null) { + return null; + } + + if (val instanceof java.sql.Time) { + return (T) val; + } else if (val instanceof Number) { + return (T) new java.sql.Time(((Number) val).longValue()); + } else if (val instanceof String) { + String strVal = (String) val; + if (strVal.length() == 0) { + return null; + } + + long longVal; + JSONScanner dateLexer = new JSONScanner(strVal); + if (dateLexer.scanISO8601DateIfMatch()) { + longVal = dateLexer.getCalendar().getTimeInMillis(); + } else { + longVal = Long.parseLong(strVal); + } + dateLexer.close(); + return (T) new java.sql.Time(longVal); + } + + throw new JSONException("parse error"); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_INT; + } +} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/TimeZoneDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/TimeZoneDeserializer.java deleted file mode 100644 index fc6eef3ab8..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/TimeZoneDeserializer.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.util.TimeZone; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; - -public class TimeZoneDeserializer implements ObjectDeserializer { - public final static TimeZoneDeserializer instance = new TimeZoneDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - - String id = (String) parser.parse(); - - if (id == null) { - return null; - } - - return (T) TimeZone.getTimeZone(id); - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_STRING; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/TimestampDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/TimestampDeserializer.java old mode 100644 new mode 100755 index be1170ed28..653c561204 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/TimestampDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/TimestampDeserializer.java @@ -1,20 +1,22 @@ package com.alibaba.fastjson.parser.deserializer; import java.lang.reflect.Type; +import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.ParseException; import java.util.Date; import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONToken; -public class TimestampDeserializer implements ObjectDeserializer { +public class TimestampDeserializer extends AbstractDateDeserializer implements ObjectDeserializer { public final static TimestampDeserializer instance = new TimestampDeserializer(); @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - Object val = parser.parse(); - + protected T cast(DefaultJSONParser parser, Type clazz, Object fieldName, Object val) { + if (val == null) { return null; } @@ -33,6 +35,14 @@ public T deserialze(DefaultExtJSONParser parser, Type clazz) { return null; } + DateFormat dateFormat = parser.getDateFormat(); + try { + Date date = (Date) dateFormat.parse(strVal); + return (T) new Timestamp(date.getTime()); + } catch (ParseException e) { + // skip + } + long longVal = Long.parseLong(strVal); return (T) new java.sql.Timestamp(longVal); } diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/TreeMapDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/TreeMapDeserializer.java deleted file mode 100644 index 6cd76753e3..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/TreeMapDeserializer.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.util.Map; -import java.util.TreeMap; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; - -public class TreeMapDeserializer implements ObjectDeserializer { - public final static TreeMapDeserializer instance = new TreeMapDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - Map map = new TreeMap(); - parser.parseObject(map); - return (T) map; - } - - public int getFastMatchToken() { - return JSONToken.LBRACE; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/URIDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/URIDeserializer.java deleted file mode 100644 index 4beb43db28..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/URIDeserializer.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.net.URI; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; - -public class URIDeserializer implements ObjectDeserializer { - public final static URIDeserializer instance = new URIDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - - String uri = (String) parser.parse(); - - if (uri == null) { - return null; - } - - return (T) URI.create(uri); - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_STRING; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/URLDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/URLDeserializer.java deleted file mode 100644 index 765e969ace..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/URLDeserializer.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.net.MalformedURLException; -import java.net.URL; - -import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; - -public class URLDeserializer implements ObjectDeserializer { - public final static URLDeserializer instance = new URLDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - - String url = (String) parser.parse(); - - if (url == null) { - return null; - } - - try { - return (T) new URL(url); - } catch (MalformedURLException e) { - throw new JSONException("create url error", e); - } - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_STRING; - } -} diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/UUIDDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/UUIDDeserializer.java deleted file mode 100644 index f0d610fff7..0000000000 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/UUIDDeserializer.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.alibaba.fastjson.parser.deserializer; - -import java.lang.reflect.Type; -import java.util.UUID; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONToken; - -public class UUIDDeserializer implements ObjectDeserializer { - public final static UUIDDeserializer instance = new UUIDDeserializer(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - - String name = (String) parser.parse(); - - if (name == null) { - return null; - } - - return (T) UUID.fromString(name); - } - - public int getFastMatchToken() { - return JSONToken.LITERAL_STRING; - } -} diff --git a/src/main/java/com/alibaba/fastjson/serializer/ASMJavaBeanSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/ASMJavaBeanSerializer.java new file mode 100644 index 0000000000..9e360590aa --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/ASMJavaBeanSerializer.java @@ -0,0 +1,14 @@ +package com.alibaba.fastjson.serializer; + +public abstract class ASMJavaBeanSerializer implements ObjectSerializer { + + protected JavaBeanSerializer nature; + + public ASMJavaBeanSerializer(Class clazz){ + nature = new JavaBeanSerializer(clazz); + } + + public JavaBeanSerializer getJavaBeanSerializer() { + return nature; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/ASMSerializerFactory.java b/src/main/java/com/alibaba/fastjson/serializer/ASMSerializerFactory.java old mode 100644 new mode 100755 index 1ab39f483b..6c28badde3 --- a/src/main/java/com/alibaba/fastjson/serializer/ASMSerializerFactory.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ASMSerializerFactory.java @@ -8,44 +8,51 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.math.BigDecimal; -import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; import com.alibaba.fastjson.asm.ClassWriter; +import com.alibaba.fastjson.asm.FieldVisitor; import com.alibaba.fastjson.asm.Label; import com.alibaba.fastjson.asm.MethodVisitor; import com.alibaba.fastjson.asm.Opcodes; import com.alibaba.fastjson.util.ASMClassLoader; +import com.alibaba.fastjson.util.ASMUtils; import com.alibaba.fastjson.util.FieldInfo; +import com.alibaba.fastjson.util.TypeUtils; public class ASMSerializerFactory implements Opcodes { private ASMClassLoader classLoader = new ASMClassLoader(); - public ObjectSerializer createJavaBeanSerializer(Class clazz) throws Exception { - return createJavaBeanSerializer(clazz, (Map) null); - } - private final AtomicLong seed = new AtomicLong(); public String getGenClassName(Class clazz) { return "Serializer_" + seed.incrementAndGet(); } + public boolean isExternalClass(Class clazz) { + return classLoader.isExternalClass(clazz); + } + static class Context { - public Context(){ + private final String className; + private final int beanSerializeFeatures; + public Context(String className, int beanSerializeFeatures){ + this.className = className; + this.beanSerializeFeatures = beanSerializeFeatures; } - private int variantIndex = 6; + private int variantIndex = 9; private Map variants = new HashMap(); @@ -53,20 +60,36 @@ public int serializer() { return 1; } + public String getClassName() { + return className; + } + public int obj() { return 2; } - public int fieldName() { + public int paramFieldName() { return 3; } - public int original() { + public int paramFieldType() { return 4; } + + public int features() { + return 5; + } + + public int fieldName() { + return 6; + } + + public int original() { + return 7; + } public int processValue() { - return 5; + return 8; } public int getVariantCount() { @@ -97,80 +120,166 @@ public ObjectSerializer createJavaBeanSerializer(Class clazz, Map getters = TypeUtils.computeGetters(clazz, aliasMap, false); + for (FieldInfo getter : getters) { + if (!ASMUtils.checkName(getter.getMember().getName())) { + return null; + } + } + String className = getGenClassName(clazz); + int beanSerializeFeatures = TypeUtils.getSerializeFeatures(clazz); ClassWriter cw = new ClassWriter(); - cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, className, "java/lang/Object", new String[] { "com/alibaba/fastjson/serializer/ObjectSerializer" }); + cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, className, "com/alibaba/fastjson/serializer/ASMJavaBeanSerializer", + new String[] { "com/alibaba/fastjson/serializer/ObjectSerializer" }); + + for (FieldInfo fieldInfo : getters) { + { + FieldVisitor fw = cw.visitField(ACC_PUBLIC, fieldInfo.getName() + "_asm_fieldPrefix", + "Ljava/lang/reflect/Type;"); + fw.visitEnd(); + } + + FieldVisitor fw = cw.visitField(ACC_PUBLIC, fieldInfo.getName() + "_asm_fieldType", + "Ljava/lang/reflect/Type;"); + fw.visitEnd(); + } MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); mw.visitVarInsn(ALOAD, 0); - mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); + mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(clazz))); + mw.visitMethodInsn(INVOKESPECIAL, "com/alibaba/fastjson/serializer/ASMJavaBeanSerializer", "", "(Ljava/lang/Class;)V"); + + // mw.visitFieldInsn(PUTFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C"); + + for (FieldInfo fieldInfo : getters) { + mw.visitVarInsn(ALOAD, 0); + + mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc(fieldInfo.getDeclaringClass()))); + + if (fieldInfo.getMethod() != null) { + mw.visitLdcInsn(fieldInfo.getMethod().getName()); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/util/ASMUtils", "getMethodType", + "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Type;"); + + } else { + mw.visitLdcInsn(fieldInfo.getField().getName()); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/util/ASMUtils", "getFieldType", + "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Type;"); + } + + mw.visitFieldInsn(PUTFIELD, className, fieldInfo.getName() + "_asm_fieldType", "Ljava/lang/reflect/Type;"); + } + mw.visitInsn(RETURN); - mw.visitMaxs(1, 1); + mw.visitMaxs(4, 4); mw.visitEnd(); { - Context context = new Context(); + Context context = new Context(className, beanSerializeFeatures); - List getters = JavaBeanSerializer.computeGetters(clazz, aliasMap); - - mw = cw.visitMethod(ACC_PUBLIC, "write", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;)V", null, new String[] { "java/io/IOException" }); + mw = cw.visitMethod(ACC_PUBLIC, + "write", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V", + null, new String[] { "java/io/IOException" }); mw.visitVarInsn(ALOAD, context.serializer()); // serializer - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "getWriter", "()" + getDesc(SerializeWriter.class)); - mw.visitVarInsn(ASTORE, context.var("out")); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "getWriter", + "()Lcom/alibaba/fastjson/serializer/SerializeWriter;"); + mw.visitVarInsn(ASTORE, context.var("out")); - Label _else = new Label(); + JSONType jsonType = clazz.getAnnotation(JSONType.class); - mw.visitVarInsn(ALOAD, context.var("out")); - mw.visitFieldInsn(GETSTATIC, getType(SerializerFeature.class), "SortField", "L" + getType(SerializerFeature.class) + ";"); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "isEnabled", "(" + "L" + getType(SerializerFeature.class) + ";" + ")Z"); + if (jsonType == null || jsonType.alphabetic()) { + Label _else = new Label(); - mw.visitJumpInsn(IFEQ, _else); - mw.visitVarInsn(ALOAD, 0); - mw.visitVarInsn(ALOAD, 1); - mw.visitVarInsn(ALOAD, 2); - mw.visitMethodInsn(INVOKEVIRTUAL, className, "write1", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;)V"); - mw.visitInsn(RETURN); + mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/serializer/SerializerFeature", "SortField", + "Lcom/alibaba/fastjson/serializer/SerializerFeature;"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "isEnabled", + "(Lcom/alibaba/fastjson/serializer/SerializerFeature;)Z"); + + mw.visitJumpInsn(IFEQ, _else); + mw.visitVarInsn(ALOAD, 0); + mw.visitVarInsn(ALOAD, 1); + mw.visitVarInsn(ALOAD, 2); + mw.visitVarInsn(ALOAD, 3); + mw.visitVarInsn(ALOAD, 4); + mw.visitVarInsn(ILOAD, 5); + mw.visitMethodInsn(INVOKEVIRTUAL, className, "write1", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V"); + mw.visitInsn(RETURN); + + mw.visitLabel(_else); + } - mw.visitLabel(_else); mw.visitVarInsn(ALOAD, context.obj()); // obj mw.visitTypeInsn(CHECKCAST, getType(clazz)); // serializer mw.visitVarInsn(ASTORE, context.var("entity")); // obj - generateWriteMethod(clazz, mw, getters, context); - mw.visitInsn(RETURN); - mw.visitMaxs(5, context.getVariantCount() + 1); + mw.visitMaxs(6, context.getVariantCount() + 1); mw.visitEnd(); } + List sortedGetters = TypeUtils.computeGetters(clazz, aliasMap, true); { - // sortField support - Context context = new Context(); - List getters = JavaBeanSerializer.computeGetters(clazz, aliasMap); - Collections.sort(getters); + // sortField support + Context context = new Context(className, beanSerializeFeatures); - mw = cw.visitMethod(ACC_PUBLIC, "write1", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;)V", null, new String[] { "java/io/IOException" }); + mw = cw.visitMethod(ACC_PUBLIC, + "write1", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V", + null, new String[] { "java/io/IOException" }); mw.visitVarInsn(ALOAD, context.serializer()); // serializer - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "getWriter", "()" + getDesc(SerializeWriter.class)); - mw.visitVarInsn(ASTORE, context.var("out")); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "getWriter", + "()Lcom/alibaba/fastjson/serializer/SerializeWriter;"); + mw.visitVarInsn(ASTORE, context.var("out")); mw.visitVarInsn(ALOAD, context.obj()); // obj mw.visitTypeInsn(CHECKCAST, getType(clazz)); // serializer mw.visitVarInsn(ASTORE, context.var("entity")); // obj - generateWriteMethod(clazz, mw, getters, context); + generateWriteMethod(clazz, mw, sortedGetters, context); + + mw.visitInsn(RETURN); + mw.visitMaxs(6, context.getVariantCount() + 1); + mw.visitEnd(); + } + + // writeAsArray + { + Context context = new Context(className, beanSerializeFeatures); + + mw = cw.visitMethod(ACC_PUBLIC, + "writeAsArray", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;)V", + null, new String[] { "java/io/IOException" }); + mw.visitVarInsn(ALOAD, context.serializer()); // serializer + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "getWriter", + "()Lcom/alibaba/fastjson/serializer/SerializeWriter;"); + mw.visitVarInsn(ASTORE, context.var("out")); + + mw.visitVarInsn(ALOAD, context.obj()); // obj + mw.visitTypeInsn(CHECKCAST, getType(clazz)); // serializer + mw.visitVarInsn(ASTORE, context.var("entity")); // obj + generateWriteAsArray(clazz, mw, sortedGetters, context); mw.visitInsn(RETURN); - mw.visitMaxs(5, context.getVariantCount() + 1); + mw.visitMaxs(6, context.getVariantCount() + 1); mw.visitEnd(); } byte[] code = cw.toByteArray(); + // + // org.apache.commons.io.IOUtils.write(code, new java.io.FileOutputStream( + // "/usr/alibaba/workspace-3.7/fastjson-asm/target/classes/" + // + className + ".class")); Class exampleClass = classLoader.defineClassPublic(className, code, 0, code.length); Object instance = exampleClass.newInstance(); @@ -178,26 +287,266 @@ public ObjectSerializer createJavaBeanSerializer(Class clazz, Map clazz, MethodVisitor mw, List getters, Context context) throws Exception { - Label end = new Label(); + private void generateWriteAsArray(Class clazz, MethodVisitor mw, List getters, Context context) + throws Exception { + + mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitVarInsn(BIPUSH, '['); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "write", "(C)V"); int size = getters.size(); if (size == 0) { mw.visitVarInsn(ALOAD, context.var("out")); - mw.visitLdcInsn("{}"); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "write", "(Ljava/lang/String;)V"); + mw.visitVarInsn(BIPUSH, ']'); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "write", "(C)V"); return; } - // SEPERATOR - mw.visitVarInsn(BIPUSH, '{'); + for (int i = 0; i < size; ++i) { + final char seperator = (i == size - 1) ? ']' : ','; + + FieldInfo property = getters.get(i); + Class propertyClass = property.getFieldClass(); + + mw.visitLdcInsn(property.getName()); + mw.visitVarInsn(ASTORE, context.fieldName()); + + if (propertyClass == byte.class // + || propertyClass == short.class // + || propertyClass == int.class) { + + mw.visitVarInsn(ALOAD, context.var("out")); + _get(mw, context, property); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeIntAndChar", "(IC)V"); + + } else if (propertyClass == long.class) { + mw.visitVarInsn(ALOAD, context.var("out")); + _get(mw, context, property); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeLongAndChar", "(JC)V"); + + } else if (propertyClass == float.class) { + mw.visitVarInsn(ALOAD, context.var("out")); + _get(mw, context, property); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFloatAndChar", "(FC)V"); + + } else if (propertyClass == double.class) { + mw.visitVarInsn(ALOAD, context.var("out")); + _get(mw, context, property); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeDoubleAndChar", "(DC)V"); + + } else if (propertyClass == boolean.class) { + mw.visitVarInsn(ALOAD, context.var("out")); + _get(mw, context, property); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeBooleanAndChar", "(ZC)V"); + } else if (propertyClass == char.class) { + mw.visitVarInsn(ALOAD, context.var("out")); + _get(mw, context, property); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeCharacterAndChar", "(CC)V"); + + } else if (propertyClass == String.class) { + mw.visitVarInsn(ALOAD, context.var("out")); + _get(mw, context, property); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeString", + "(Ljava/lang/String;C)V"); + } else if (propertyClass.isEnum()) { + mw.visitVarInsn(ALOAD, context.var("out")); + _get(mw, context, property); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeEnum", "(Ljava/lang/Enum;C)V"); + } else { + String format = property.getFormat(); + + mw.visitVarInsn(ALOAD, context.serializer()); + _get(mw, context, property); + if (format != null) { + mw.visitLdcInsn(format); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "writeWithFormat", + "(Ljava/lang/Object;Ljava/lang/String;)V"); + } else { + mw.visitVarInsn(ALOAD, context.fieldName()); + if (property.getFieldType() instanceof Class // + && ((Class) property.getFieldType()).isPrimitive()) { + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "writeWithFieldName", + "(Ljava/lang/Object;Ljava/lang/Object;)V"); + } else { + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), property.getName() + "_asm_fieldType", + "Ljava/lang/reflect/Type;"); + mw.visitLdcInsn(property.getSerialzeFeatures()); + + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "writeWithFieldName", + "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V"); + } + } + + mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitVarInsn(BIPUSH, seperator); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "write", "(C)V"); + } + } + } + + private void generateWriteMethod(Class clazz, MethodVisitor mw, List getters, Context context) + throws Exception { + Label end = new Label(); + + int size = getters.size(); + + { + // 格式化输出不走asm 优化 + Label endFormat_ = new Label(); + Label notNull_ = new Label(); + mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/serializer/SerializerFeature", "PrettyFormat", + "Lcom/alibaba/fastjson/serializer/SerializerFeature;"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "isEnabled", + "(Lcom/alibaba/fastjson/serializer/SerializerFeature;)Z"); + mw.visitJumpInsn(IFEQ, endFormat_); + + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), "nature", "Lcom/alibaba/fastjson/serializer/JavaBeanSerializer;"); + mw.visitJumpInsn(IFNONNULL, notNull_); + + // ///// + mw.visitLabel(notNull_); + + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), "nature", "Lcom/alibaba/fastjson/serializer/JavaBeanSerializer;"); + mw.visitVarInsn(ALOAD, 1); + mw.visitVarInsn(ALOAD, 2); + mw.visitVarInsn(ALOAD, 3); + mw.visitVarInsn(ALOAD, 4); + mw.visitVarInsn(ILOAD, 5); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JavaBeanSerializer", "write", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V"); + mw.visitInsn(RETURN); + + mw.visitLabel(endFormat_); + } + + { + // if (serializer.containsReference(object)) { + + Label endRef_ = new Label(); + Label notNull_ = new Label(); + + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), "nature", "Lcom/alibaba/fastjson/serializer/JavaBeanSerializer;"); + mw.visitJumpInsn(IFNONNULL, notNull_); + + // ///// + mw.visitLabel(notNull_); + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), "nature", "Lcom/alibaba/fastjson/serializer/JavaBeanSerializer;"); + mw.visitVarInsn(ALOAD, 1); + mw.visitVarInsn(ALOAD, 2); + mw.visitVarInsn(ILOAD, 5); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JavaBeanSerializer", "writeReference", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;I)Z"); + + mw.visitJumpInsn(IFEQ, endRef_); + + mw.visitInsn(RETURN); + + mw.visitLabel(endRef_); + } + + { + Label endWriteAsArray_ = new Label(); + + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), "nature", "Lcom/alibaba/fastjson/serializer/JavaBeanSerializer;"); + mw.visitVarInsn(ALOAD, context.serializer()); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JavaBeanSerializer", "isWriteAsArray", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;)Z"); + mw.visitJumpInsn(IFEQ, endWriteAsArray_); + + // ///// + mw.visitVarInsn(ALOAD, 0); // this + mw.visitVarInsn(ALOAD, 1); // serializer + mw.visitVarInsn(ALOAD, 2); // obj + mw.visitVarInsn(ALOAD, 3); // fieldObj + mw.visitVarInsn(ALOAD, 4); // fieldType + mw.visitMethodInsn(INVOKEVIRTUAL, context.getClassName(), "writeAsArray", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;)V"); + + mw.visitInsn(RETURN); + + mw.visitLabel(endWriteAsArray_); + } + + { + mw.visitVarInsn(ALOAD, context.serializer()); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "getContext", + "()Lcom/alibaba/fastjson/serializer/SerialContext;"); + mw.visitVarInsn(ASTORE, context.var("parent")); + + mw.visitVarInsn(ALOAD, context.serializer()); + mw.visitVarInsn(ALOAD, context.var("parent")); + mw.visitVarInsn(ALOAD, context.obj()); + mw.visitVarInsn(ALOAD, context.paramFieldName()); + mw.visitLdcInsn(context.beanSerializeFeatures); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "setContext", + "(Lcom/alibaba/fastjson/serializer/SerialContext;Ljava/lang/Object;Ljava/lang/Object;I)V"); + } + + // SEPERATO + { + Label end_ = new Label(); + Label else_ = new Label(); + Label writeClass_ = new Label(); + + // mw.visitVarInsn(ALOAD, context.var("out")); + // mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/serializer/SerializerFeature", "WriteClassName", + // "L" + "com/alibaba/fastjson/serializer/SerializerFeature" + ";"); + // mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "isEnabled", + // "(" + "L" + "com/alibaba/fastjson/serializer/SerializerFeature" + ";" + ")Z"); + // mw.visitJumpInsn(IFEQ, else_); + + mw.visitVarInsn(ALOAD, context.serializer()); + mw.visitVarInsn(ALOAD, context.paramFieldType()); + mw.visitVarInsn(ALOAD, context.obj()); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "isWriteClassName", + "(Ljava/lang/reflect/Type;Ljava/lang/Object;)Z"); + mw.visitJumpInsn(IFEQ, else_); + + // mw.visitVarInsn(ALOAD, context.paramFieldType()); + // mw.visitJumpInsn(IFNULL, writeClass_); + + // IFNULL + mw.visitVarInsn(ALOAD, context.paramFieldType()); + mw.visitVarInsn(ALOAD, context.obj()); + mw.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;"); + mw.visitJumpInsn(IF_ACMPEQ, else_); + + mw.visitLabel(writeClass_); + mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitLdcInsn("{\"" + JSON.DEFAULT_TYPE_KEY + "\":\"" + clazz.getName() + "\""); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "write", "(Ljava/lang/String;)V"); + mw.visitVarInsn(BIPUSH, ','); + mw.visitJumpInsn(GOTO, end_); + + mw.visitLabel(else_); + mw.visitVarInsn(BIPUSH, '{'); + + mw.visitLabel(end_); + } + mw.visitVarInsn(ISTORE, context.var("seperator")); + _before(mw, context); + for (int i = 0; i < size; ++i) { FieldInfo property = getters.get(i); - Method method = property.getMethod(); - Class propertyClass = method.getReturnType(); + Class propertyClass = property.getFieldClass(); mw.visitLdcInsn(property.getName()); mw.visitVarInsn(ASTORE, context.fieldName()); @@ -222,7 +571,7 @@ private void generateWriteMethod(Class clazz, MethodVisitor mw, List clazz, MethodVisitor mw, List clazz, MethodVisitor mw, FieldInfo property, Context context) { - Method method = property.getMethod(); - Label _end = new Label(); - _get(mw, context, method); + _nameApply(mw, property, context, _end); + _get(mw, context, property); mw.visitVarInsn(ASTORE, context.var("object")); _filters(mw, property, context, _end); @@ -275,15 +625,24 @@ private void _object(Class clazz, MethodVisitor mw, FieldInfo property, Conte } private void _enum(Class clazz, MethodVisitor mw, FieldInfo property, Context context) { - Method method = property.getMethod(); + boolean writeEnumUsingToString = false; + JSONField annotation = property.getAnnotation(JSONField.class); + if (annotation != null) { + for (SerializerFeature feature : annotation.serialzeFeatures()) { + if (feature == SerializerFeature.WriteEnumUsingToString) { + writeEnumUsingToString = true; + } + } + } Label _not_null = new Label(); Label _end_if = new Label(); Label _end = new Label(); - _get(mw, context, method); - mw.visitTypeInsn(CHECKCAST, getType(Enum.class)); // cast - mw.visitVarInsn(ASTORE, context.var("enum")); + _nameApply(mw, property, context, _end); + _get(mw, context, property); + mw.visitTypeInsn(CHECKCAST, "java/lang/Enum"); // cast + mw.visitVarInsn(ASTORE, context.var("enum")); _filters(mw, property, context, _end); @@ -293,35 +652,41 @@ private void _enum(Class clazz, MethodVisitor mw, FieldInfo property, Context mw.visitJumpInsn(GOTO, _end_if); mw.visitLabel(_not_null); - mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitVarInsn(ALOAD, context.var("out")); mw.visitVarInsn(ILOAD, context.var("seperator")); mw.visitVarInsn(ALOAD, context.fieldName()); mw.visitVarInsn(ALOAD, context.var("enum")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;L" + getType(Enum.class) + ";)V"); - - mw.visitLabel(_end_if); + if (writeEnumUsingToString) { + mw.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldValue", + "(CLjava/lang/String;Ljava/lang/String;)V"); + } else { + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldValue", + "(CLjava/lang/String;Ljava/lang/Enum;)V"); + } _seperator(mw, context); + mw.visitLabel(_end_if); + mw.visitLabel(_end); } private void _long(Class clazz, MethodVisitor mw, FieldInfo property, Context context) { - Method method = property.getMethod(); - Label _end = new Label(); - _get(mw, context, method); + _nameApply(mw, property, context, _end); + _get(mw, context, property); mw.visitVarInsn(LSTORE, context.var("long", 2)); _filters(mw, property, context, _end); - mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitVarInsn(ALOAD, context.var("out")); mw.visitVarInsn(ILOAD, context.var("seperator")); mw.visitVarInsn(ALOAD, context.fieldName()); - mw.visitVarInsn(LLOAD, context.var("long")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;J)V"); + mw.visitVarInsn(LLOAD, context.var("long", 2)); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldValue", "(CLjava/lang/String;J)V"); _seperator(mw, context); @@ -329,20 +694,19 @@ private void _long(Class clazz, MethodVisitor mw, FieldInfo property, Context } private void _float(Class clazz, MethodVisitor mw, FieldInfo property, Context context) { - Method method = property.getMethod(); - Label _end = new Label(); - _get(mw, context, method); + _nameApply(mw, property, context, _end); + _get(mw, context, property); mw.visitVarInsn(FSTORE, context.var("float")); _filters(mw, property, context, _end); - mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitVarInsn(ALOAD, context.var("out")); mw.visitVarInsn(ILOAD, context.var("seperator")); mw.visitVarInsn(ALOAD, context.fieldName()); mw.visitVarInsn(FLOAD, context.var("float")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;F)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldValue", "(CLjava/lang/String;F)V"); _seperator(mw, context); @@ -350,20 +714,19 @@ private void _float(Class clazz, MethodVisitor mw, FieldInfo property, Contex } private void _double(Class clazz, MethodVisitor mw, FieldInfo property, Context context) { - Method method = property.getMethod(); - Label _end = new Label(); - _get(mw, context, method); - mw.visitVarInsn(DSTORE, context.var("double")); + _nameApply(mw, property, context, _end); + _get(mw, context, property); + mw.visitVarInsn(DSTORE, context.var("double", 2)); _filters(mw, property, context, _end); - mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitVarInsn(ALOAD, context.var("out")); mw.visitVarInsn(ILOAD, context.var("seperator")); mw.visitVarInsn(ALOAD, context.fieldName()); - mw.visitVarInsn(DLOAD, context.var("double")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;D)V"); + mw.visitVarInsn(DLOAD, context.var("double", 2)); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldValue", "(CLjava/lang/String;D)V"); _seperator(mw, context); @@ -371,21 +734,20 @@ private void _double(Class clazz, MethodVisitor mw, FieldInfo property, Conte } private void _char(Class clazz, MethodVisitor mw, FieldInfo property, Context context) { - Method method = property.getMethod(); - Label _end = new Label(); - _get(mw, context, method); + _nameApply(mw, property, context, _end); + _get(mw, context, property); mw.visitVarInsn(ISTORE, context.var("char")); _filters(mw, property, context, _end); - mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitVarInsn(ALOAD, context.var("out")); mw.visitVarInsn(ILOAD, context.var("seperator")); mw.visitVarInsn(ALOAD, context.fieldName()); mw.visitVarInsn(ILOAD, context.var("char")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;C)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldValue", "(CLjava/lang/String;C)V"); _seperator(mw, context); @@ -393,38 +755,43 @@ private void _char(Class clazz, MethodVisitor mw, FieldInfo property, Context } private void _boolean(Class clazz, MethodVisitor mw, FieldInfo property, Context context) { - Method method = property.getMethod(); - Label _end = new Label(); - _get(mw, context, method); + _nameApply(mw, property, context, _end); + _get(mw, context, property); mw.visitVarInsn(ISTORE, context.var("boolean")); _filters(mw, property, context, _end); - mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitVarInsn(ALOAD, context.var("out")); mw.visitVarInsn(ILOAD, context.var("seperator")); mw.visitVarInsn(ALOAD, context.fieldName()); mw.visitVarInsn(ILOAD, context.var("boolean")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;Z)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldValue", "(CLjava/lang/String;Z)V"); _seperator(mw, context); mw.visitLabel(_end); } - private void _get(MethodVisitor mw, Context context, Method method) { - mw.visitVarInsn(ALOAD, context.var("entity")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(method.getDeclaringClass()), method.getName(), getDesc(method)); + private void _get(MethodVisitor mw, Context context, FieldInfo property) { + Method method = property.getMethod(); + if (method != null) { + mw.visitVarInsn(ALOAD, context.var("entity")); + mw.visitMethodInsn(INVOKEVIRTUAL, getType(method.getDeclaringClass()), method.getName(), getDesc(method)); + } else { + mw.visitVarInsn(ALOAD, context.var("entity")); + mw.visitFieldInsn(GETFIELD, getType(property.getDeclaringClass()), property.getField().getName(), + getDesc(property.getFieldClass())); + } } private void _byte(Class clazz, MethodVisitor mw, FieldInfo property, Context context) { - Method method = property.getMethod(); - Label _end = new Label(); - _get(mw, context, method); + _nameApply(mw, property, context, _end); + _get(mw, context, property); mw.visitVarInsn(ISTORE, context.var("byte")); _filters(mw, property, context, _end); @@ -434,7 +801,7 @@ private void _byte(Class clazz, MethodVisitor mw, FieldInfo property, Context mw.visitVarInsn(ALOAD, context.fieldName()); mw.visitVarInsn(ILOAD, context.var("byte")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;I)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldValue", "(CLjava/lang/String;I)V"); _seperator(mw, context); @@ -442,21 +809,20 @@ private void _byte(Class clazz, MethodVisitor mw, FieldInfo property, Context } private void _short(Class clazz, MethodVisitor mw, FieldInfo property, Context context) { - Method method = property.getMethod(); - Label _end = new Label(); - _get(mw, context, method); + _nameApply(mw, property, context, _end); + _get(mw, context, property); mw.visitVarInsn(ISTORE, context.var("short")); _filters(mw, property, context, _end); - mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitVarInsn(ALOAD, context.var("out")); mw.visitVarInsn(ILOAD, context.var("seperator")); mw.visitVarInsn(ALOAD, context.fieldName()); mw.visitVarInsn(ILOAD, context.var("short")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;I)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldValue", "(CLjava/lang/String;I)V"); _seperator(mw, context); @@ -464,21 +830,20 @@ private void _short(Class clazz, MethodVisitor mw, FieldInfo property, Contex } private void _int(Class clazz, MethodVisitor mw, FieldInfo property, Context context) { - Method method = property.getMethod(); - Label _end = new Label(); - _get(mw, context, method); + _nameApply(mw, property, context, _end); + _get(mw, context, property); mw.visitVarInsn(ISTORE, context.var("int")); _filters(mw, property, context, _end); - mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitVarInsn(ALOAD, context.var("out")); mw.visitVarInsn(ILOAD, context.var("seperator")); mw.visitVarInsn(ALOAD, context.fieldName()); mw.visitVarInsn(ILOAD, context.var("int")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;I)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldValue", "(CLjava/lang/String;I)V"); _seperator(mw, context); @@ -486,11 +851,10 @@ private void _int(Class clazz, MethodVisitor mw, FieldInfo property, Context } private void _decimal(Class clazz, MethodVisitor mw, FieldInfo property, Context context) { - Method method = property.getMethod(); - Label _end = new Label(); - _get(mw, context, method); + _nameApply(mw, property, context, _end); + _get(mw, context, property); mw.visitVarInsn(ASTORE, context.var("decimal")); _filters(mw, property, context, _end); @@ -509,11 +873,12 @@ private void _decimal(Class clazz, MethodVisitor mw, FieldInfo property, Cont mw.visitLabel(_else); // else { out.writeFieldValue(seperator, fieldName, fieldValue) - mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitVarInsn(ALOAD, context.var("out")); mw.visitVarInsn(ILOAD, context.var("seperator")); mw.visitVarInsn(ALOAD, context.fieldName()); mw.visitVarInsn(ALOAD, context.var("decimal")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;Ljava/math/BigDecimal;)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldValue", + "(CLjava/lang/String;Ljava/math/BigDecimal;)V"); _seperator(mw, context); mw.visitJumpInsn(GOTO, _end_if); @@ -524,11 +889,10 @@ private void _decimal(Class clazz, MethodVisitor mw, FieldInfo property, Cont } private void _string(Class clazz, MethodVisitor mw, FieldInfo property, Context context) { - Method method = property.getMethod(); - Label _end = new Label(); - _get(mw, context, method); + _nameApply(mw, property, context, _end); + _get(mw, context, property); mw.visitVarInsn(ASTORE, context.var("string")); _filters(mw, property, context, _end); @@ -549,7 +913,8 @@ private void _string(Class clazz, MethodVisitor mw, FieldInfo property, Conte mw.visitVarInsn(ILOAD, context.var("seperator")); mw.visitVarInsn(ALOAD, context.fieldName()); mw.visitVarInsn(ALOAD, context.var("string")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldValue", "(CLjava/lang/String;Ljava/lang/String;)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldValue", + "(CLjava/lang/String;Ljava/lang/String;)V"); _seperator(mw, context); @@ -559,11 +924,19 @@ private void _string(Class clazz, MethodVisitor mw, FieldInfo property, Conte } private void _list(Class clazz, MethodVisitor mw, FieldInfo property, Context context) { - Method method = property.getMethod(); + Type propertyType = property.getFieldType(); - Type propertyType = method.getGenericReturnType(); + Type elementType; + if (propertyType instanceof Class) { + elementType = Object.class; + } else { + elementType = ((ParameterizedType) propertyType).getActualTypeArguments()[0]; + } - Type elementType = ((ParameterizedType) propertyType).getActualTypeArguments()[0]; + Class elementClass = null; + if (elementType instanceof Class) { + elementClass = (Class) elementType; + } Label _end = new Label(); @@ -573,9 +946,10 @@ private void _list(Class clazz, MethodVisitor mw, FieldInfo property, Context mw.visitLabel(_if); - _get(mw, context, method); - mw.visitTypeInsn(CHECKCAST, getType(List.class)); // cast - mw.visitVarInsn(ASTORE, context.var("list")); + _nameApply(mw, property, context, _end); + _get(mw, context, property); + mw.visitTypeInsn(CHECKCAST, "java/util/List"); // cast + mw.visitVarInsn(ASTORE, context.var("list")); _filters(mw, property, context, _end); @@ -588,15 +962,15 @@ private void _list(Class clazz, MethodVisitor mw, FieldInfo property, Context mw.visitVarInsn(ALOAD, context.var("out")); mw.visitVarInsn(ILOAD, context.var("seperator")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "write", "(C)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "write", "(C)V"); mw.visitVarInsn(ALOAD, context.var("out")); mw.visitVarInsn(ALOAD, context.fieldName()); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldName", "(Ljava/lang/String;)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldName", "(Ljava/lang/String;)V"); // mw.visitVarInsn(ALOAD, context.var("list")); - mw.visitMethodInsn(INVOKEINTERFACE, getType(List.class), "size", "()I"); + mw.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "size", "()I"); mw.visitVarInsn(ISTORE, context.var("int")); Label _if_3 = new Label(); @@ -609,29 +983,37 @@ private void _list(Class clazz, MethodVisitor mw, FieldInfo property, Context mw.visitInsn(ICONST_0); mw.visitJumpInsn(IF_ICMPNE, _else_3); - mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitVarInsn(ALOAD, context.var("out")); mw.visitLdcInsn("[]"); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "write", "(Ljava/lang/String;)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "write", "(Ljava/lang/String;)V"); mw.visitJumpInsn(GOTO, _end_if_3); mw.visitLabel(_else_3); + { + mw.visitVarInsn(ALOAD, context.serializer()); + mw.visitVarInsn(ALOAD, context.var("list")); + mw.visitVarInsn(ALOAD, context.fieldName()); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "setContext", + "(Ljava/lang/Object;Ljava/lang/Object;)V"); + } + { mw.visitVarInsn(ALOAD, context.var("out")); mw.visitVarInsn(BIPUSH, '['); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "write", "(C)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "write", "(C)V"); // list_serializer = null mw.visitInsn(ACONST_NULL); - mw.visitTypeInsn(CHECKCAST, getType(ObjectSerializer.class)); // cast to string - mw.visitVarInsn(ASTORE, context.var("list_ser")); + mw.visitTypeInsn(CHECKCAST, "com/alibaba/fastjson/serializer/ObjectSerializer"); // cast to string + mw.visitVarInsn(ASTORE, context.var("list_ser")); Label _for = new Label(); Label _end_for = new Label(); mw.visitInsn(ICONST_0); - mw.visitVarInsn(ISTORE, context.var("i")); + mw.visitVarInsn(ISTORE, context.var("i")); // for (; i < list.size() -1; ++i) { mw.visitLabel(_for); @@ -645,53 +1027,83 @@ private void _list(Class clazz, MethodVisitor mw, FieldInfo property, Context if (elementType == String.class) { // out.write((String)list.get(i)); - mw.visitVarInsn(ALOAD, context.var("out")); - mw.visitVarInsn(ALOAD, context.var("list")); - mw.visitVarInsn(ILOAD, context.var("i")); - mw.visitMethodInsn(INVOKEINTERFACE, getType(List.class), "get", "(I)Ljava/lang/Object;"); - mw.visitTypeInsn(CHECKCAST, getType(String.class)); // cast to string + mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitVarInsn(ALOAD, context.var("list")); + mw.visitVarInsn(ILOAD, context.var("i")); + mw.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;"); + mw.visitTypeInsn(CHECKCAST, "java/lang/String"); // cast to string mw.visitVarInsn(BIPUSH, ','); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeString", "(Ljava/lang/String;C)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeString", + "(Ljava/lang/String;C)V"); } else { mw.visitVarInsn(ALOAD, context.serializer()); mw.visitVarInsn(ALOAD, context.var("list")); - mw.visitVarInsn(ILOAD, context.var("i")); - mw.visitMethodInsn(INVOKEINTERFACE, getType(List.class), "get", "(I)Ljava/lang/Object;"); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "write", "(Ljava/lang/Object;)V"); + mw.visitVarInsn(ILOAD, context.var("i")); + mw.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;"); + mw.visitVarInsn(ILOAD, context.var("i")); + mw.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); + + if (elementClass != null && Modifier.isPublic(elementClass.getModifiers())) { + mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc((Class) elementType))); + mw.visitLdcInsn(property.getSerialzeFeatures()); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "writeWithFieldName", + "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V"); + } else { + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "writeWithFieldName", + "(Ljava/lang/Object;Ljava/lang/Object;)V"); + } mw.visitVarInsn(ALOAD, context.var("out")); mw.visitVarInsn(BIPUSH, ','); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "write", "(C)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "write", "(C)V"); } - mw.visitIincInsn(context.var("i"), 1); + mw.visitIincInsn(context.var("i"), 1); mw.visitJumpInsn(GOTO, _for); mw.visitLabel(_end_for); if (elementType == String.class) { // out.write((String)list.get(size - 1)); - mw.visitVarInsn(ALOAD, context.var("out")); - mw.visitVarInsn(ALOAD, context.var("list")); + mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitVarInsn(ALOAD, context.var("list")); mw.visitVarInsn(ILOAD, context.var("int")); mw.visitInsn(ICONST_1); mw.visitInsn(ISUB); - mw.visitMethodInsn(INVOKEINTERFACE, getType(List.class), "get", "(I)Ljava/lang/Object;"); - mw.visitTypeInsn(CHECKCAST, getType(String.class)); // cast to string + mw.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;"); + mw.visitTypeInsn(CHECKCAST, "java/lang/String"); // cast to string mw.visitVarInsn(BIPUSH, ']'); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeString", "(Ljava/lang/String;C)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeString", + "(Ljava/lang/String;C)V"); } else { mw.visitVarInsn(ALOAD, context.serializer()); mw.visitVarInsn(ALOAD, context.var("list")); - mw.visitVarInsn(ILOAD, context.var("i")); - mw.visitMethodInsn(INVOKEINTERFACE, getType(List.class), "get", "(I)Ljava/lang/Object;"); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "write", "(Ljava/lang/Object;)V"); + mw.visitVarInsn(ILOAD, context.var("i")); + mw.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;"); + mw.visitVarInsn(ILOAD, context.var("i")); + mw.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); + + if (elementClass != null && Modifier.isPublic(elementClass.getModifiers())) { + mw.visitLdcInsn(com.alibaba.fastjson.asm.Type.getType(getDesc((Class) elementType))); + mw.visitLdcInsn(property.getSerialzeFeatures()); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "writeWithFieldName", + "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V"); + } else { + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "writeWithFieldName", + "(Ljava/lang/Object;Ljava/lang/Object;)V"); + } mw.visitVarInsn(ALOAD, context.var("out")); mw.visitVarInsn(BIPUSH, ']'); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "write", "(C)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "write", "(C)V"); } } + + { + mw.visitVarInsn(ALOAD, context.serializer()); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "popContext", "()V"); + } + mw.visitLabel(_end_if_3); _seperator(mw, context); @@ -705,14 +1117,18 @@ private void _filters(MethodVisitor mw, FieldInfo property, Context context, Lab if (property.getField() != null) { if (Modifier.isTransient(property.getField().getModifiers())) { mw.visitVarInsn(ALOAD, context.var("out")); - mw.visitFieldInsn(GETSTATIC, getType(SerializerFeature.class), "SkipTransientField", "L" + getType(SerializerFeature.class) + ";"); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "isEnabled", "(" + "L" + getType(SerializerFeature.class) + ";" + ")Z"); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/serializer/SerializerFeature", "SkipTransientField", + "Lcom/alibaba/fastjson/serializer/SerializerFeature;"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "isEnabled", + "(Lcom/alibaba/fastjson/serializer/SerializerFeature;)Z"); // if true mw.visitJumpInsn(IFNE, _end); } } - + + _notWriteDefault(mw, property, context, _end); + _apply(mw, property, context); mw.visitJumpInsn(IFEQ, _end); @@ -730,17 +1146,17 @@ private void _filters(MethodVisitor mw, FieldInfo property, Context context, Lab mw.visitLabel(_else_processKey); } - private void _writeObject(MethodVisitor mw, FieldInfo fieldInfo, Context context, Label _end) { - String format = null; - JSONField annotation = fieldInfo.getAnnotation(JSONField.class); - - if (annotation != null) { - format = annotation.format(); + private void _nameApply(MethodVisitor mw, FieldInfo property, Context context, Label _end) { + mw.visitVarInsn(ALOAD, context.serializer()); + mw.visitVarInsn(ALOAD, context.obj()); + mw.visitVarInsn(ALOAD, context.fieldName()); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "applyName", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;)Z"); + mw.visitJumpInsn(IFEQ, _end); + } - if (format.trim().length() == 0) { - format = null; - } - } + private void _writeObject(MethodVisitor mw, FieldInfo fieldInfo, Context context, Label _end) { + String format = fieldInfo.getFormat(); Label _not_null = new Label(); @@ -753,29 +1169,103 @@ private void _writeObject(MethodVisitor mw, FieldInfo fieldInfo, Context context // writeFieldNullNumber mw.visitVarInsn(ALOAD, context.var("out")); mw.visitVarInsn(ILOAD, context.var("seperator")); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "write", "(C)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "write", "(C)V"); // out.writeFieldName("fieldName") mw.visitVarInsn(ALOAD, context.var("out")); mw.visitVarInsn(ALOAD, context.fieldName()); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldName", "(Ljava/lang/String;)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldName", "(Ljava/lang/String;)V"); // serializer.write(obj) - mw.visitVarInsn(ALOAD, context.serializer()); // serializer + mw.visitVarInsn(ALOAD, context.serializer()); mw.visitVarInsn(ALOAD, context.processValue()); if (format != null) { mw.visitLdcInsn(format); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "writeWithFormat", "(Ljava/lang/Object;Ljava/lang/String;)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "writeWithFormat", + "(Ljava/lang/Object;Ljava/lang/String;)V"); } else { - mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONSerializer.class), "write", "(Ljava/lang/Object;)V"); + mw.visitVarInsn(ALOAD, context.fieldName()); + if (fieldInfo.getFieldType() instanceof Class // + && ((Class) fieldInfo.getFieldType()).isPrimitive()) { + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "writeWithFieldName", + "(Ljava/lang/Object;Ljava/lang/Object;)V"); + } else { + mw.visitVarInsn(ALOAD, 0); + mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_fieldType", + "Ljava/lang/reflect/Type;"); + mw.visitLdcInsn(fieldInfo.getSerialzeFeatures()); + + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/JSONSerializer", "writeWithFieldName", + "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/reflect/Type;I)V"); + } } _seperator(mw, context); } + private void _before(MethodVisitor mw, Context context) { + mw.visitVarInsn(ALOAD, context.serializer()); + mw.visitVarInsn(ALOAD, context.obj()); + mw.visitVarInsn(ILOAD, context.var("seperator")); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "writeBefore", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;C)C"); + mw.visitVarInsn(ISTORE, context.var("seperator")); + } + + private void _after(MethodVisitor mw, Context context) { + mw.visitVarInsn(ALOAD, context.serializer()); + mw.visitVarInsn(ALOAD, context.obj()); + mw.visitVarInsn(ILOAD, context.var("seperator")); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "writeAfter", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;C)C"); + mw.visitVarInsn(ISTORE, context.var("seperator")); + } + + private void _notWriteDefault(MethodVisitor mw, FieldInfo property, Context context, Label _end) { + Label elseLabel = new Label(); + + mw.visitVarInsn(ALOAD, context.var("out")); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/serializer/SerializerFeature", "NotWriteDefaultValue", + "Lcom/alibaba/fastjson/serializer/SerializerFeature;"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "isEnabled", + "(Lcom/alibaba/fastjson/serializer/SerializerFeature;)Z"); + mw.visitJumpInsn(IFEQ, elseLabel); + + Class propertyClass = property.getFieldClass(); + if (propertyClass == boolean.class) { + mw.visitVarInsn(ILOAD, context.var("boolean")); + mw.visitJumpInsn(IFEQ, _end); + } else if (propertyClass == byte.class) { + mw.visitVarInsn(ILOAD, context.var("byte")); + mw.visitJumpInsn(IFEQ, _end); + } else if (propertyClass == short.class) { + mw.visitVarInsn(ILOAD, context.var("short")); + mw.visitJumpInsn(IFEQ, _end); + } else if (propertyClass == int.class) { + mw.visitVarInsn(ILOAD, context.var("int")); + mw.visitJumpInsn(IFEQ, _end); + } else if (propertyClass == long.class) { + mw.visitVarInsn(LLOAD, context.var("long")); + mw.visitInsn(LCONST_0); + mw.visitInsn(LCMP); + mw.visitJumpInsn(IFEQ, _end); + } else if (propertyClass == float.class) { + mw.visitVarInsn(FLOAD, context.var("float")); + mw.visitInsn(FCONST_0); + mw.visitInsn(FCMPL); + mw.visitJumpInsn(IFEQ, _end); + } else if (propertyClass == double.class) { + mw.visitVarInsn(DLOAD, context.var("double")); + mw.visitInsn(DCONST_0); + mw.visitInsn(DCMPL); + mw.visitJumpInsn(IFEQ, _end); + } + + mw.visitLabel(elseLabel); + } + private void _apply(MethodVisitor mw, FieldInfo property, Context context) { - Method method = property.getMethod(); - Class propertyClass = method.getReturnType(); + Class propertyClass = property.getFieldClass(); mw.visitVarInsn(ALOAD, context.serializer()); mw.visitVarInsn(ALOAD, context.obj()); @@ -783,49 +1273,61 @@ private void _apply(MethodVisitor mw, FieldInfo property, Context context) { if (propertyClass == byte.class) { mw.visitVarInsn(ILOAD, context.var("byte")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;B)Z"); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "apply", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;B)Z"); } else if (propertyClass == short.class) { mw.visitVarInsn(ILOAD, context.var("short")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;S)Z"); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "apply", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;S)Z"); } else if (propertyClass == int.class) { mw.visitVarInsn(ILOAD, context.var("int")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;I)Z"); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "apply", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;I)Z"); } else if (propertyClass == char.class) { mw.visitVarInsn(ILOAD, context.var("char")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;C)Z"); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "apply", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;C)Z"); } else if (propertyClass == long.class) { - mw.visitVarInsn(LLOAD, context.var("long")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;J)Z"); + mw.visitVarInsn(LLOAD, context.var("long", 2)); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "apply", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;J)Z"); } else if (propertyClass == float.class) { mw.visitVarInsn(FLOAD, context.var("float")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;F)Z"); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "apply", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;F)Z"); } else if (propertyClass == double.class) { - mw.visitVarInsn(DLOAD, context.var("double")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;D)Z"); + mw.visitVarInsn(DLOAD, context.var("double", 2)); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "apply", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;D)Z"); } else if (propertyClass == boolean.class) { mw.visitVarInsn(ILOAD, context.var("boolean")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;B)Z"); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "apply", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;B)Z"); } else if (propertyClass == BigDecimal.class) { mw.visitVarInsn(ALOAD, context.var("decimal")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z"); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "apply", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z"); } else if (propertyClass == String.class) { mw.visitVarInsn(ALOAD, context.var("string")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z"); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "apply", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z"); } else if (propertyClass.isEnum()) { mw.visitVarInsn(ALOAD, context.var("enum")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z"); - } else if (propertyClass == List.class) { + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "apply", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z"); + } else if (List.class.isAssignableFrom(propertyClass)) { mw.visitVarInsn(ALOAD, context.var("list")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z"); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "apply", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z"); } else { mw.visitVarInsn(ALOAD, context.var("object")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "apply", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z"); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "apply", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z"); } } private void _processValue(MethodVisitor mw, FieldInfo property, Context context) { - Method method = property.getMethod(); - Class propertyClass = method.getReturnType(); + Class propertyClass = property.getFieldClass(); mw.visitVarInsn(ALOAD, context.serializer()); mw.visitVarInsn(ALOAD, context.obj()); @@ -833,35 +1335,35 @@ private void _processValue(MethodVisitor mw, FieldInfo property, Context context if (propertyClass == byte.class) { mw.visitVarInsn(ILOAD, context.var("byte")); - mw.visitMethodInsn(INVOKESTATIC, getType(Byte.class), "valueOf", "(B)Ljava/lang/Byte;"); + mw.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;"); } else if (propertyClass == short.class) { mw.visitVarInsn(ILOAD, context.var("short")); - mw.visitMethodInsn(INVOKESTATIC, getType(Short.class), "valueOf", "(S)Ljava/lang/Short;"); + mw.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;"); } else if (propertyClass == int.class) { mw.visitVarInsn(ILOAD, context.var("int")); - mw.visitMethodInsn(INVOKESTATIC, getType(Integer.class), "valueOf", "(I)Ljava/lang/Integer;"); + mw.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); } else if (propertyClass == char.class) { mw.visitVarInsn(ILOAD, context.var("char")); - mw.visitMethodInsn(INVOKESTATIC, getType(Character.class), "valueOf", "(C)Ljava/lang/Character;"); + mw.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;"); } else if (propertyClass == long.class) { - mw.visitVarInsn(LLOAD, context.var("long")); - mw.visitMethodInsn(INVOKESTATIC, getType(Long.class), "valueOf", "(J)Ljava/lang/Long;"); + mw.visitVarInsn(LLOAD, context.var("long", 2)); + mw.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;"); } else if (propertyClass == float.class) { mw.visitVarInsn(FLOAD, context.var("float")); - mw.visitMethodInsn(INVOKESTATIC, getType(Float.class), "valueOf", "(F)Ljava/lang/Float;"); + mw.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;"); } else if (propertyClass == double.class) { - mw.visitVarInsn(DLOAD, context.var("double")); - mw.visitMethodInsn(INVOKESTATIC, getType(Double.class), "valueOf", "(D)Ljava/lang/Double;"); + mw.visitVarInsn(DLOAD, context.var("double", 2)); + mw.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;"); } else if (propertyClass == boolean.class) { mw.visitVarInsn(ILOAD, context.var("boolean")); - mw.visitMethodInsn(INVOKESTATIC, getType(Boolean.class), "valueOf", "(Z)Ljava/lang/Boolean;"); + mw.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;"); } else if (propertyClass == BigDecimal.class) { mw.visitVarInsn(ALOAD, context.var("decimal")); } else if (propertyClass == String.class) { mw.visitVarInsn(ALOAD, context.var("string")); } else if (propertyClass.isEnum()) { mw.visitVarInsn(ALOAD, context.var("enum")); - } else if (propertyClass == List.class) { + } else if (List.class.isAssignableFrom(propertyClass)) { mw.visitVarInsn(ALOAD, context.var("list")); } else { mw.visitVarInsn(ALOAD, context.var("object")); @@ -870,14 +1372,16 @@ private void _processValue(MethodVisitor mw, FieldInfo property, Context context mw.visitVarInsn(ASTORE, context.original()); mw.visitVarInsn(ALOAD, context.original()); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "processValue", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;"); + mw.visitMethodInsn(INVOKESTATIC, + "com/alibaba/fastjson/serializer/FilterUtils", + "processValue", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;"); mw.visitVarInsn(ASTORE, context.processValue()); } private void _processKey(MethodVisitor mw, FieldInfo property, Context context) { - Method method = property.getMethod(); - Class propertyClass = method.getReturnType(); + Class propertyClass = property.getFieldClass(); mw.visitVarInsn(ALOAD, context.serializer()); mw.visitVarInsn(ALOAD, context.obj()); @@ -885,52 +1389,74 @@ private void _processKey(MethodVisitor mw, FieldInfo property, Context context) if (propertyClass == byte.class) { mw.visitVarInsn(ILOAD, context.var("byte")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "processKey", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;B)Ljava/lang/String;"); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "processKey", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;B)Ljava/lang/String;"); } else if (propertyClass == short.class) { mw.visitVarInsn(ILOAD, context.var("short")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "processKey", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;S)Ljava/lang/String;"); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "processKey", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;S)Ljava/lang/String;"); } else if (propertyClass == int.class) { mw.visitVarInsn(ILOAD, context.var("int")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "processKey", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;I)Ljava/lang/String;"); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "processKey", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;I)Ljava/lang/String;"); } else if (propertyClass == char.class) { mw.visitVarInsn(ILOAD, context.var("char")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "processKey", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;C)Ljava/lang/String;"); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "processKey", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;C)Ljava/lang/String;"); } else if (propertyClass == long.class) { - mw.visitVarInsn(LLOAD, context.var("long")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "processKey", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;J)Ljava/lang/String;"); + mw.visitVarInsn(LLOAD, context.var("long", 2)); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "processKey", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;J)Ljava/lang/String;"); } else if (propertyClass == float.class) { mw.visitVarInsn(FLOAD, context.var("float")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "processKey", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;F)Ljava/lang/String;"); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "processKey", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;F)Ljava/lang/String;"); } else if (propertyClass == double.class) { - mw.visitVarInsn(DLOAD, context.var("double")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "processKey", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;D)Ljava/lang/String;"); + mw.visitVarInsn(DLOAD, context.var("double", 2)); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "processKey", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;D)Ljava/lang/String;"); } else if (propertyClass == boolean.class) { mw.visitVarInsn(ILOAD, context.var("boolean")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "processKey", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Z)Ljava/lang/String;"); + mw.visitMethodInsn(INVOKESTATIC, "com/alibaba/fastjson/serializer/FilterUtils", "processKey", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Z)Ljava/lang/String;"); } else if (propertyClass == BigDecimal.class) { mw.visitVarInsn(ALOAD, context.var("decimal")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "processKey", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;"); + mw.visitMethodInsn(INVOKESTATIC, + "com/alibaba/fastjson/serializer/FilterUtils", + "processKey", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;"); } else if (propertyClass == String.class) { mw.visitVarInsn(ALOAD, context.var("string")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "processKey", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;"); + mw.visitMethodInsn(INVOKESTATIC, + "com/alibaba/fastjson/serializer/FilterUtils", + "processKey", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;"); } else if (propertyClass.isEnum()) { mw.visitVarInsn(ALOAD, context.var("enum")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "processKey", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;"); - } else if (propertyClass == List.class) { + mw.visitMethodInsn(INVOKESTATIC, + "com/alibaba/fastjson/serializer/FilterUtils", + "processKey", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;"); + } else if (List.class.isAssignableFrom(propertyClass)) { + mw.visitVarInsn(ALOAD, context.var("list")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "processKey", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;"); + mw.visitMethodInsn(INVOKESTATIC, + "com/alibaba/fastjson/serializer/FilterUtils", + "processKey", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;"); } else { mw.visitVarInsn(ALOAD, context.var("object")); - mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "processKey", "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;"); + mw.visitMethodInsn(INVOKESTATIC, + "com/alibaba/fastjson/serializer/FilterUtils", + "processKey", + "(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;"); } mw.visitVarInsn(ASTORE, context.fieldName()); } private void _if_write_null(MethodVisitor mw, FieldInfo fieldInfo, Context context) { - Method method = fieldInfo.getMethod(); - - Class propertyClass = method.getReturnType(); + Class propertyClass = fieldInfo.getFieldClass(); Label _if = new Label(); Label _else = new Label(); @@ -941,22 +1467,36 @@ private void _if_write_null(MethodVisitor mw, FieldInfo fieldInfo, Context conte // out.isEnabled(Serializer.WriteMapNullValue) boolean writeNull = false; + boolean writeNullNumberAsZero = false; + boolean writeNullStringAsEmpty = false; + boolean writeNullBooleanAsFalse = false; + boolean writeNullListAsEmpty = false; JSONField annotation = fieldInfo.getAnnotation(JSONField.class); if (annotation != null) { for (SerializerFeature feature : annotation.serialzeFeatures()) { if (feature == SerializerFeature.WriteMapNullValue) { writeNull = true; + } else if (feature == SerializerFeature.WriteNullNumberAsZero) { + writeNullNumberAsZero = true; + } else if (feature == SerializerFeature.WriteNullStringAsEmpty) { + writeNullStringAsEmpty = true; + } else if (feature == SerializerFeature.WriteNullBooleanAsFalse) { + writeNullBooleanAsFalse = true; + } else if (feature == SerializerFeature.WriteNullListAsEmpty) { + writeNullListAsEmpty = true; } } } - + if (!writeNull) { mw.visitVarInsn(ALOAD, context.var("out")); - mw.visitFieldInsn(GETSTATIC, getType(SerializerFeature.class), "WriteMapNullValue", "L" + getType(SerializerFeature.class) + ";"); - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "isEnabled", "(" + "L" + getType(SerializerFeature.class) + ";" + ")Z"); + mw.visitFieldInsn(GETSTATIC, "com/alibaba/fastjson/serializer/SerializerFeature", "WriteMapNullValue", + "Lcom/alibaba/fastjson/serializer/SerializerFeature;"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "isEnabled", + "(Lcom/alibaba/fastjson/serializer/SerializerFeature;)Z"); mw.visitJumpInsn(IFEQ, _else); } - + mw.visitLabel(_write_null); // out.writeFieldNull(seperator, 'fieldName') mw.visitVarInsn(ALOAD, context.var("out")); @@ -964,15 +1504,43 @@ private void _if_write_null(MethodVisitor mw, FieldInfo fieldInfo, Context conte mw.visitVarInsn(ALOAD, context.fieldName()); if (propertyClass == String.class || propertyClass == Character.class) { - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldNullString", "(CLjava/lang/String;)V"); + if (writeNullStringAsEmpty) { + mw.visitLdcInsn(""); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldValue", + "(CLjava/lang/String;Ljava/lang/String;)V"); + } else { + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldNullString", + "(CLjava/lang/String;)V"); + } } else if (Number.class.isAssignableFrom(propertyClass)) { - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldNullNumber", "(CLjava/lang/String;)V"); + if (writeNullNumberAsZero) { + mw.visitInsn(ICONST_0); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldValue", + "(CLjava/lang/String;I)V"); + } else { + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldNullNumber", + "(CLjava/lang/String;)V"); + } } else if (propertyClass == Boolean.class) { - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldNullBoolean", "(CLjava/lang/String;)V"); + if (writeNullBooleanAsFalse) { + mw.visitInsn(ICONST_0); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldValue", + "(CLjava/lang/String;Z)V"); + } else { + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldNullBoolean", + "(CLjava/lang/String;)V"); + } } else if (Collection.class.isAssignableFrom(propertyClass) || propertyClass.isArray()) { - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldNullList", "(CLjava/lang/String;)V"); + if (writeNullListAsEmpty) { + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldEmptyList", + "(CLjava/lang/String;)V"); + } else { + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldNullList", + "(CLjava/lang/String;)V"); + } } else { - mw.visitMethodInsn(INVOKEVIRTUAL, getType(SerializeWriter.class), "writeFieldNull", "(CLjava/lang/String;)V"); + mw.visitMethodInsn(INVOKEVIRTUAL, "com/alibaba/fastjson/serializer/SerializeWriter", "writeFieldNull", + "(CLjava/lang/String;)V"); } // seperator = ','; @@ -989,5 +1557,4 @@ private void _seperator(MethodVisitor mw, Context context) { mw.visitVarInsn(BIPUSH, ','); mw.visitVarInsn(ISTORE, context.var("seperator")); } - } diff --git a/src/main/java/com/alibaba/fastjson/serializer/AfterFilter.java b/src/main/java/com/alibaba/fastjson/serializer/AfterFilter.java new file mode 100644 index 0000000000..0c032fcf6d --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/AfterFilter.java @@ -0,0 +1,31 @@ +package com.alibaba.fastjson.serializer; + +/** + * @since 1.1.35 + */ +public abstract class AfterFilter implements SerializeFilter { + + private static final ThreadLocal serializerLocal = new ThreadLocal(); + private static final ThreadLocal seperatorLocal = new ThreadLocal(); + + private final static Character COMMA = Character.valueOf(','); + + final char writeAfter(JSONSerializer serializer, Object object, char seperator) { + serializerLocal.set(serializer); + seperatorLocal.set(seperator); + writeAfter(object); + serializerLocal.set(null); + return seperatorLocal.get(); + } + + protected final void writeKeyValue(String key, Object value) { + JSONSerializer serializer = serializerLocal.get(); + char seperator = seperatorLocal.get(); + serializer.writeKeyValue(seperator, key, value); + if (seperator != ',') { + seperatorLocal.set(COMMA); + } + } + + public abstract void writeAfter(Object object); +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/AppendableSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/AppendableSerializer.java old mode 100644 new mode 100755 index 202fafefca..d977a4bb99 --- a/src/main/java/com/alibaba/fastjson/serializer/AppendableSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/AppendableSerializer.java @@ -1,12 +1,13 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; public class AppendableSerializer implements ObjectSerializer { public final static AppendableSerializer instance = new AppendableSerializer(); - public void write(JSONSerializer serializer, Object object) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { if (object == null) { SerializeWriter out = serializer.getWriter(); if (out.isEnabled(SerializerFeature.WriteNullStringAsEmpty)) { diff --git a/src/main/java/com/alibaba/fastjson/serializer/ArraySerializer.java b/src/main/java/com/alibaba/fastjson/serializer/ArraySerializer.java old mode 100644 new mode 100755 index cc503bae83..40da33d189 --- a/src/main/java/com/alibaba/fastjson/serializer/ArraySerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ArraySerializer.java @@ -16,22 +16,25 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class ArraySerializer implements ObjectSerializer { + private final Class componentType; private final ObjectSerializer compObjectSerializer; - public ArraySerializer(ObjectSerializer compObjectSerializer){ - super(); + public ArraySerializer(Class componentType, ObjectSerializer compObjectSerializer){ + this.componentType = componentType; this.compObjectSerializer = compObjectSerializer; } - public final void write(JSONSerializer serializer, Object object) throws IOException { + public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) + throws IOException { SerializeWriter out = serializer.getWriter(); - + if (object == null) { if (out.isEnabled(SerializerFeature.WriteNullListAsEmpty)) { out.write("[]"); @@ -44,32 +47,29 @@ public final void write(JSONSerializer serializer, Object object) throws IOExcep Object[] array = (Object[]) object; int size = array.length; - int end = size - 1; - - if (end == -1) { - out.append("[]"); - return; - } + SerialContext context = serializer.getContext(); + serializer.setContext(context, object, fieldName, 0); - out.append('['); - for (int i = 0; i < end; ++i) { - Object item = array[i]; + try { + out.append('['); + for (int i = 0; i < size; ++i) { + if (i != 0) { + out.append(','); + } + Object item = array[i]; - if (item == null) { - out.append("null,"); - } else { - compObjectSerializer.write(serializer, item); - out.append(','); + if (item == null) { + out.append("null"); + } else if (item.getClass() == componentType) { + compObjectSerializer.write(serializer, item, i, null, 0); + } else { + ObjectSerializer itemSerializer = serializer.getObjectWriter(item.getClass()); + itemSerializer.write(serializer, item, i, null, 0); + } } - } - - Object item = array[end]; - - if (item == null) { - out.append("null]"); - } else { - compObjectSerializer.write(serializer, item); out.append(']'); + } finally { + serializer.setContext(context); } } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/AtomicBooleanSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/AtomicBooleanSerializer.java old mode 100644 new mode 100755 index 6ed688c260..805bdabe67 --- a/src/main/java/com/alibaba/fastjson/serializer/AtomicBooleanSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/AtomicBooleanSerializer.java @@ -16,16 +16,17 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; import java.util.concurrent.atomic.AtomicBoolean; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class AtomicBooleanSerializer implements ObjectSerializer { public final static AtomicBooleanSerializer instance = new AtomicBooleanSerializer(); - public void write(JSONSerializer serializer, Object object) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); AtomicBoolean val = (AtomicBoolean) object; diff --git a/src/main/java/com/alibaba/fastjson/serializer/AtomicIntegerArraySerializer.java b/src/main/java/com/alibaba/fastjson/serializer/AtomicIntegerArrayCodec.java old mode 100644 new mode 100755 similarity index 50% rename from src/main/java/com/alibaba/fastjson/serializer/AtomicIntegerArraySerializer.java rename to src/main/java/com/alibaba/fastjson/serializer/AtomicIntegerArrayCodec.java index eb36d9c785..fb49907f43 --- a/src/main/java/com/alibaba/fastjson/serializer/AtomicIntegerArraySerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/AtomicIntegerArrayCodec.java @@ -16,16 +16,22 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; import java.util.concurrent.atomic.AtomicIntegerArray; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ -public class AtomicIntegerArraySerializer implements ObjectSerializer { +public class AtomicIntegerArrayCodec implements ObjectSerializer, ObjectDeserializer { - public final static AtomicIntegerArraySerializer instance = new AtomicIntegerArraySerializer(); + public final static AtomicIntegerArrayCodec instance = new AtomicIntegerArrayCodec(); - public void write(JSONSerializer serializer, Object object) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); if (object == null) { @@ -50,4 +56,25 @@ public void write(JSONSerializer serializer, Object object) throws IOException { out.append(']'); } + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + if (parser.getLexer().token() == JSONToken.NULL) { + parser.getLexer().nextToken(JSONToken.COMMA); + return null; + } + + JSONArray array = new JSONArray(); + parser.parseArray(array); + + AtomicIntegerArray atomicArray = new AtomicIntegerArray(array.size()); + for (int i = 0; i < array.size(); ++i) { + atomicArray.set(i, array.getInteger(i)); + } + + return (T) atomicArray; + } + + public int getFastMatchToken() { + return JSONToken.LBRACKET; + } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/AtomicIntegerSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/AtomicIntegerSerializer.java old mode 100644 new mode 100755 index 67948a3324..24bd490018 --- a/src/main/java/com/alibaba/fastjson/serializer/AtomicIntegerSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/AtomicIntegerSerializer.java @@ -16,16 +16,17 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; import java.util.concurrent.atomic.AtomicInteger; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class AtomicIntegerSerializer implements ObjectSerializer { public final static AtomicIntegerSerializer instance = new AtomicIntegerSerializer(); - public void write(JSONSerializer serializer, Object object) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); AtomicInteger val = (AtomicInteger) object; diff --git a/src/main/java/com/alibaba/fastjson/serializer/AtomicLongArraySerializer.java b/src/main/java/com/alibaba/fastjson/serializer/AtomicLongArrayCodec.java old mode 100644 new mode 100755 similarity index 51% rename from src/main/java/com/alibaba/fastjson/serializer/AtomicLongArraySerializer.java rename to src/main/java/com/alibaba/fastjson/serializer/AtomicLongArrayCodec.java index ee4d61093e..307f638b65 --- a/src/main/java/com/alibaba/fastjson/serializer/AtomicLongArraySerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/AtomicLongArrayCodec.java @@ -16,16 +16,22 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; import java.util.concurrent.atomic.AtomicLongArray; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ -public class AtomicLongArraySerializer implements ObjectSerializer { +public class AtomicLongArrayCodec implements ObjectSerializer, ObjectDeserializer { - public final static AtomicLongArraySerializer instance = new AtomicLongArraySerializer(); + public final static AtomicLongArrayCodec instance = new AtomicLongArrayCodec(); - public void write(JSONSerializer serializer, Object object) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); if (object == null) { @@ -36,7 +42,7 @@ public void write(JSONSerializer serializer, Object object) throws IOException { } return; } - + AtomicLongArray array = (AtomicLongArray) object; int len = array.length(); out.append('['); @@ -50,4 +56,25 @@ public void write(JSONSerializer serializer, Object object) throws IOException { out.append(']'); } + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + if (parser.getLexer().token() == JSONToken.NULL) { + parser.getLexer().nextToken(JSONToken.COMMA); + return null; + } + + JSONArray array = new JSONArray(); + parser.parseArray(array); + + AtomicLongArray atomicArray = new AtomicLongArray(array.size()); + for (int i = 0; i < array.size(); ++i) { + atomicArray.set(i, array.getLong(i)); + } + + return (T) atomicArray; + } + + public int getFastMatchToken() { + return JSONToken.LBRACKET; + } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/AtomicLongSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/AtomicLongSerializer.java old mode 100644 new mode 100755 index e70df156af..d61808afc1 --- a/src/main/java/com/alibaba/fastjson/serializer/AtomicLongSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/AtomicLongSerializer.java @@ -16,16 +16,17 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; import java.util.concurrent.atomic.AtomicLong; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class AtomicLongSerializer implements ObjectSerializer { public final static AtomicLongSerializer instance = new AtomicLongSerializer(); - public void write(JSONSerializer serializer, Object object) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); AtomicLong val = (AtomicLong) object; diff --git a/src/main/java/com/alibaba/fastjson/serializer/AutowiredObjectSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/AutowiredObjectSerializer.java old mode 100644 new mode 100755 index 32e85e84c4..8d23609e76 --- a/src/main/java/com/alibaba/fastjson/serializer/AutowiredObjectSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/AutowiredObjectSerializer.java @@ -19,7 +19,7 @@ import java.util.Set; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public interface AutowiredObjectSerializer extends ObjectSerializer { Set getAutowiredFor(); diff --git a/src/main/java/com/alibaba/fastjson/serializer/BeforeFilter.java b/src/main/java/com/alibaba/fastjson/serializer/BeforeFilter.java new file mode 100644 index 0000000000..34ed06041d --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/BeforeFilter.java @@ -0,0 +1,28 @@ +package com.alibaba.fastjson.serializer; + +public abstract class BeforeFilter implements SerializeFilter { + + private static final ThreadLocal serializerLocal = new ThreadLocal(); + private static final ThreadLocal seperatorLocal = new ThreadLocal(); + + private final static Character COMMA = Character.valueOf(','); + + final char writeBefore(JSONSerializer serializer, Object object, char seperator) { + serializerLocal.set(serializer); + seperatorLocal.set(seperator); + writeBefore(object); + serializerLocal.set(null); + return seperatorLocal.get(); + } + + protected final void writeKeyValue(String key, Object value) { + JSONSerializer serializer = serializerLocal.get(); + char seperator = seperatorLocal.get(); + serializer.writeKeyValue(seperator, key, value); + if (seperator != ',') { + seperatorLocal.set(COMMA); + } + } + + public abstract void writeBefore(Object object); +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/BigDecimalCodec.java b/src/main/java/com/alibaba/fastjson/serializer/BigDecimalCodec.java new file mode 100755 index 0000000000..f3b599bcf7 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/BigDecimalCodec.java @@ -0,0 +1,87 @@ +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.math.BigDecimal; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.util.TypeUtils; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public class BigDecimalCodec implements ObjectSerializer, ObjectDeserializer { + + public final static BigDecimalCodec instance = new BigDecimalCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + SerializeWriter out = serializer.getWriter(); + + if (object == null) { + if (out.isEnabled(SerializerFeature.WriteNullNumberAsZero)) { + out.write('0'); + } else { + out.writeNull(); + } + return; + } + + BigDecimal val = (BigDecimal) object; + out.write(val.toString()); + + if (out.isEnabled(SerializerFeature.WriteClassName) && fieldType != BigDecimal.class && val.scale() == 0) { + out.write('.'); + } + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + return (T) deserialze(parser); + } + + @SuppressWarnings("unchecked") + public static T deserialze(DefaultJSONParser parser) { + final JSONLexer lexer = parser.getLexer(); + if (lexer.token() == JSONToken.LITERAL_INT) { + long val = lexer.longValue(); + lexer.nextToken(JSONToken.COMMA); + return (T) new BigDecimal(val); + } + + if (lexer.token() == JSONToken.LITERAL_FLOAT) { + BigDecimal val = lexer.decimalValue(); + lexer.nextToken(JSONToken.COMMA); + return (T) val; + } + + Object value = parser.parse(); + + if (value == null) { + return null; + } + + return (T) TypeUtils.castToBigDecimal(value); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_INT; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/BigDecimalSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/BigDecimalSerializer.java deleted file mode 100644 index 18ffdce003..0000000000 --- a/src/main/java/com/alibaba/fastjson/serializer/BigDecimalSerializer.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.serializer; - -import java.io.IOException; -import java.math.BigDecimal; - -/** - * @author wenshao - */ -public class BigDecimalSerializer implements ObjectSerializer { - - public final static BigDecimalSerializer instance = new BigDecimalSerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - SerializeWriter out = serializer.getWriter(); - - if (object == null) { - if (out.isEnabled(SerializerFeature.WriteNullNumberAsZero)) { - out.write('0'); - } else { - out.writeNull(); - } - return; - } - - BigDecimal val = (BigDecimal) object; - out.write(val.toString()); - } - -} diff --git a/src/main/java/com/alibaba/fastjson/serializer/BigIntegerCodec.java b/src/main/java/com/alibaba/fastjson/serializer/BigIntegerCodec.java new file mode 100755 index 0000000000..5a4d05cca1 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/BigIntegerCodec.java @@ -0,0 +1,77 @@ +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.math.BigInteger; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.util.TypeUtils; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public class BigIntegerCodec implements ObjectSerializer, ObjectDeserializer { + + public final static BigIntegerCodec instance = new BigIntegerCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + SerializeWriter out = serializer.getWriter(); + + if (object == null) { + if (out.isEnabled(SerializerFeature.WriteNullNumberAsZero)) { + out.write('0'); + } else { + out.writeNull(); + } + return; + } + + BigInteger val = (BigInteger) object; + out.write(val.toString()); + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + return (T) deserialze(parser); + } + + @SuppressWarnings("unchecked") + public static T deserialze(DefaultJSONParser parser) { + final JSONLexer lexer = parser.getLexer(); + if (lexer.token() == JSONToken.LITERAL_INT) { + String val = lexer.numberString(); + lexer.nextToken(JSONToken.COMMA); + return (T) new BigInteger(val); + } + + Object value = parser.parse(); + + if (value == null) { + return null; + } + + return (T) TypeUtils.castToBigInteger(value); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_INT; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/BigIntegerSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/BigIntegerSerializer.java deleted file mode 100644 index c414ce345e..0000000000 --- a/src/main/java/com/alibaba/fastjson/serializer/BigIntegerSerializer.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.serializer; - -import java.io.IOException; -import java.math.BigInteger; - -/** - * @author wenshao - */ -public class BigIntegerSerializer implements ObjectSerializer { - - public final static BigIntegerSerializer instance = new BigIntegerSerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - SerializeWriter out = serializer.getWriter(); - - if (object == null) { - if (out.isEnabled(SerializerFeature.WriteNullNumberAsZero)) { - out.write('0'); - } else { - out.writeNull(); - } - return; - } - - BigInteger val = (BigInteger) object; - out.write(val.toString()); - } - -} diff --git a/src/main/java/com/alibaba/fastjson/serializer/BooleanArraySerializer.java b/src/main/java/com/alibaba/fastjson/serializer/BooleanArraySerializer.java old mode 100644 new mode 100755 index 9720c6fae6..70898aaa86 --- a/src/main/java/com/alibaba/fastjson/serializer/BooleanArraySerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/BooleanArraySerializer.java @@ -16,15 +16,16 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class BooleanArraySerializer implements ObjectSerializer { public static BooleanArraySerializer instance = new BooleanArraySerializer(); - public final void write(JSONSerializer serializer, Object object) throws IOException { + public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); if (object == null) { @@ -36,6 +37,14 @@ public final void write(JSONSerializer serializer, Object object) throws IOExcep return; } - out.writeBooleanArray((boolean[]) object); + boolean[] array = (boolean[]) object; + out.write('['); + for (int i = 0; i < array.length; ++i) { + if (i != 0) { + out.write(','); + } + out.write(array[i]); + } + out.write(']'); } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/BooleanCodec.java b/src/main/java/com/alibaba/fastjson/serializer/BooleanCodec.java new file mode 100755 index 0000000000..c18dae6a52 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/BooleanCodec.java @@ -0,0 +1,95 @@ +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.concurrent.atomic.AtomicBoolean; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.util.TypeUtils; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public class BooleanCodec implements ObjectSerializer, ObjectDeserializer { + + public final static BooleanCodec instance = new BooleanCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + SerializeWriter out = serializer.getWriter(); + + Boolean value = (Boolean) object; + if (value == null) { + if (out.isEnabled(SerializerFeature.WriteNullBooleanAsFalse)) { + out.write("false"); + } else { + out.writeNull(); + } + return; + } + + if (value.booleanValue()) { + out.write("true"); + } else { + out.write("false"); + } + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + final JSONLexer lexer = parser.getLexer(); + + Boolean boolObj; + if (lexer.token() == JSONToken.TRUE) { + lexer.nextToken(JSONToken.COMMA); + boolObj = Boolean.TRUE; + } else if (lexer.token() == JSONToken.FALSE) { + lexer.nextToken(JSONToken.COMMA); + boolObj = Boolean.FALSE; + } else if (lexer.token() == JSONToken.LITERAL_INT) { + int intValue = lexer.intValue(); + lexer.nextToken(JSONToken.COMMA); + + if (intValue == 1) { + boolObj = Boolean.TRUE; + } else { + boolObj = Boolean.FALSE; + } + } else { + Object value = parser.parse(); + + if (value == null) { + return null; + } + + boolObj = TypeUtils.castToBoolean(value); + } + + if (clazz == AtomicBoolean.class) { + return (T) new AtomicBoolean(boolObj.booleanValue()); + } + + return (T) boolObj; + } + + public int getFastMatchToken() { + return JSONToken.TRUE; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/BooleanSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/BooleanSerializer.java deleted file mode 100644 index 01798cdb5e..0000000000 --- a/src/main/java/com/alibaba/fastjson/serializer/BooleanSerializer.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.serializer; - -import java.io.IOException; - -/** - * @author wenshao - */ -public class BooleanSerializer implements ObjectSerializer { - - public final static BooleanSerializer instance = new BooleanSerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - SerializeWriter out = serializer.getWriter(); - - Boolean value = (Boolean) object; - if (value == null) { - if (out.isEnabled(SerializerFeature.WriteNullBooleanAsFalse)) { - out.write("false"); - } else { - out.writeNull(); - } - return; - } - - if (value.booleanValue()) { - out.write("true"); - } else { - out.write("false"); - } - } - -} diff --git a/src/main/java/com/alibaba/fastjson/serializer/ByteArraySerializer.java b/src/main/java/com/alibaba/fastjson/serializer/ByteArraySerializer.java old mode 100644 new mode 100755 index 9fb65cc291..1e30e0ec94 --- a/src/main/java/com/alibaba/fastjson/serializer/ByteArraySerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ByteArraySerializer.java @@ -16,15 +16,16 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class ByteArraySerializer implements ObjectSerializer { public static ByteArraySerializer instance = new ByteArraySerializer(); - public final void write(JSONSerializer serializer, Object object) throws IOException { + public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); if (object == null) { diff --git a/src/main/java/com/alibaba/fastjson/serializer/CalendarCodec.java b/src/main/java/com/alibaba/fastjson/serializer/CalendarCodec.java new file mode 100755 index 0000000000..491f754bdc --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/CalendarCodec.java @@ -0,0 +1,45 @@ +package com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.Calendar; +import java.util.Date; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.DateDeserializer; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +public class CalendarCodec implements ObjectSerializer, ObjectDeserializer { + + public final static CalendarCodec instance = new CalendarCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + Calendar calendar = (Calendar) object; + Date date = calendar.getTime(); + serializer.write(date); + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + Object value = DateDeserializer.instance.deserialze(parser, type, fieldName); + + if (value instanceof Calendar) { + return (T) value; + } + + Date date = (Date) value; + if (date == null) { + return null; + } + + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + return (T) calendar; + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_INT; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/CharArraySerializer.java b/src/main/java/com/alibaba/fastjson/serializer/CharArraySerializer.java new file mode 100755 index 0000000000..dd7b5abc16 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/CharArraySerializer.java @@ -0,0 +1,27 @@ +package com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; + + +public class CharArraySerializer implements ObjectSerializer { + + public static CharArraySerializer instance = new CharArraySerializer(); + + public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + SerializeWriter out = serializer.getWriter(); + + if (object == null) { + if (out.isEnabled(SerializerFeature.WriteNullListAsEmpty)) { + out.write("[]"); + } else { + out.writeNull(); + } + return; + } + + char[] chars = (char[]) object; + out.writeString(new String(chars)); + } + +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/CharacterSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/CharacterCodec.java old mode 100644 new mode 100755 similarity index 51% rename from src/main/java/com/alibaba/fastjson/serializer/CharacterSerializer.java rename to src/main/java/com/alibaba/fastjson/serializer/CharacterCodec.java index 5d6493c591..af12651dd8 --- a/src/main/java/com/alibaba/fastjson/serializer/CharacterSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/CharacterCodec.java @@ -16,15 +16,21 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.util.TypeUtils; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ -public class CharacterSerializer implements ObjectSerializer { +public class CharacterCodec implements ObjectSerializer, ObjectDeserializer { - public final static CharacterSerializer instance = new CharacterSerializer(); + public final static CharacterCodec instance = new CharacterCodec(); - public void write(JSONSerializer serializer, Object object) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); Character value = (Character) object; @@ -41,4 +47,18 @@ public void write(JSONSerializer serializer, Object object) throws IOException { } } + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + Object value = parser.parse(); + + if (value == null) { + return null; + } + + return (T) TypeUtils.castToChar(value); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/CharsetCodec.java b/src/main/java/com/alibaba/fastjson/serializer/CharsetCodec.java new file mode 100755 index 0000000000..f3ce26e453 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/CharsetCodec.java @@ -0,0 +1,42 @@ +package com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.nio.charset.Charset; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + + +public class CharsetCodec implements ObjectSerializer, ObjectDeserializer { + + public final static CharsetCodec instance = new CharsetCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + if (object == null) { + serializer.writeNull(); + return; + } + + Charset charset = (Charset) object; + serializer.write(charset.toString()); + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + Object value = parser.parse(); + + if (value == null) { + return null; + } + + String charset = (String) value; + + return (T) Charset.forName(charset); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/CharsetSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/CharsetSerializer.java deleted file mode 100644 index 3eaab7ab54..0000000000 --- a/src/main/java/com/alibaba/fastjson/serializer/CharsetSerializer.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.alibaba.fastjson.serializer; - -import java.io.IOException; -import java.nio.charset.Charset; - - -public class CharsetSerializer implements ObjectSerializer { - - public final static CharsetSerializer instance = new CharsetSerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - if (object == null) { - serializer.writeNull(); - return; - } - - Charset charset = (Charset) object; - serializer.write(charset.toString()); - } - -} diff --git a/src/main/java/com/alibaba/fastjson/serializer/ClassSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/ClassSerializer.java old mode 100644 new mode 100755 index fa00439a83..1b06beffd9 --- a/src/main/java/com/alibaba/fastjson/serializer/ClassSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ClassSerializer.java @@ -16,16 +16,17 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class ClassSerializer implements ObjectSerializer { public final static ClassSerializer instance = new ClassSerializer(); @SuppressWarnings("rawtypes") - public void write(JSONSerializer serializer, Object object) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); Class clazz = (Class) object; diff --git a/src/main/java/com/alibaba/fastjson/serializer/ClobSeriliazer.java b/src/main/java/com/alibaba/fastjson/serializer/ClobSeriliazer.java new file mode 100755 index 0000000000..bcaf577d60 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/ClobSeriliazer.java @@ -0,0 +1,39 @@ +package com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringWriter; +import java.lang.reflect.Type; +import java.sql.Clob; +import java.sql.SQLException; + +public class ClobSeriliazer implements ObjectSerializer { + + public final static ClobSeriliazer instance = new ClobSeriliazer(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + try { + if (object == null) { + serializer.writeNull(); + return; + } + + Clob clob = (Clob) object; + Reader reader = clob.getCharacterStream(); + + StringWriter writer = new StringWriter(); + char[] buf = new char[1024]; + int len = 0; + while ((len = reader.read(buf)) != -1) { + writer.write(buf, 0, len); + } + reader.close(); + + String text = writer.toString(); + serializer.write(text); + } catch (SQLException e) { + throw new IOException("write clob error", e); + } + } + +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/CollectionSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/CollectionSerializer.java old mode 100644 new mode 100755 index feae5169da..28fe6ff3c9 --- a/src/main/java/com/alibaba/fastjson/serializer/CollectionSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/CollectionSerializer.java @@ -16,18 +16,22 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.Collection; +import java.util.HashSet; +import java.util.TreeSet; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class CollectionSerializer implements ObjectSerializer { public final static CollectionSerializer instance = new CollectionSerializer(); - public void write(JSONSerializer serializer, Object object) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); - + if (object == null) { if (out.isEnabled(SerializerFeature.WriteNullListAsEmpty)) { out.write("[]"); @@ -37,36 +41,64 @@ public void write(JSONSerializer serializer, Object object) throws IOException { return; } - Collection collection = (Collection) object; - - out.append('['); - boolean first = true; - for (Object item : collection) { - if (!first) { - out.append(','); + Type elementType = null; + if (serializer.isEnabled(SerializerFeature.WriteClassName)) { + if (fieldType instanceof ParameterizedType) { + ParameterizedType param = (ParameterizedType) fieldType; + elementType = param.getActualTypeArguments()[0]; } - first = false; + } - if (item == null) { - out.writeNull(); - continue; - } + Collection collection = (Collection) object; - Class clazz = item.getClass(); + SerialContext context = serializer.getContext(); + serializer.setContext(context, object, fieldName, 0); - if (clazz == Integer.class) { - out.writeInt(((Integer) item).intValue()); - continue; + if (serializer.isEnabled(SerializerFeature.WriteClassName)) { + if (HashSet.class == collection.getClass()) { + out.append("Set"); + } else if (TreeSet.class == collection.getClass()) { + out.append("TreeSet"); } + } - if (clazz == Long.class) { - out.writeLong(((Long) item).longValue()); - continue; - } + try { + int i = 0; + out.append('['); + for (Object item : collection) { - serializer.write(item); + if (i++ != 0) { + out.append(','); + } + + if (item == null) { + out.writeNull(); + continue; + } + + Class clazz = item.getClass(); + + if (clazz == Integer.class) { + out.writeInt(((Integer) item).intValue()); + continue; + } + + if (clazz == Long.class) { + out.writeLong(((Long) item).longValue()); + + if (out.isEnabled(SerializerFeature.WriteClassName)) { + out.write('L'); + } + continue; + } + + ObjectSerializer itemSerializer = serializer.getObjectWriter(clazz); + itemSerializer.write(serializer, item, i - 1, elementType, 0); + } + out.append(']'); + } finally { + serializer.setContext(context); } - out.append(']'); } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/ColorCodec.java b/src/main/java/com/alibaba/fastjson/serializer/ColorCodec.java new file mode 100755 index 0000000000..bdd0da68b1 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/ColorCodec.java @@ -0,0 +1,99 @@ +package com.alibaba.fastjson.serializer; + +import java.awt.Color; +import java.io.IOException; +import java.lang.reflect.Type; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +public class ColorCodec implements ObjectSerializer, ObjectDeserializer { + + public final static ColorCodec instance = new ColorCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + SerializeWriter out = serializer.getWriter(); + Color color = (Color) object; + if (color == null) { + out.writeNull(); + return; + } + + char sep = '{'; + if (out.isEnabled(SerializerFeature.WriteClassName)) { + out.write('{'); + out.writeFieldName(JSON.DEFAULT_TYPE_KEY); + out.writeString(Color.class.getName()); + sep = ','; + } + + out.writeFieldValue(sep, "r", color.getRed()); + out.writeFieldValue(',', "g", color.getGreen()); + out.writeFieldValue(',', "b", color.getBlue()); + if (color.getAlpha() > 0) { + out.writeFieldValue(',', "alpha", color.getAlpha()); + } + + out.write('}'); + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + JSONLexer lexer = parser.getLexer(); + + if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) { + throw new JSONException("syntax error"); + } + lexer.nextToken(); + + int r = 0, g = 0, b = 0, alpha = 0; + for (;;) { + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(); + break; + } + + String key; + if (lexer.token() == JSONToken.LITERAL_STRING) { + key = lexer.stringVal(); + lexer.nextTokenWithColon(JSONToken.LITERAL_INT); + } else { + throw new JSONException("syntax error"); + } + + int val; + if (lexer.token() == JSONToken.LITERAL_INT) { + val = lexer.intValue(); + lexer.nextToken(); + } else { + throw new JSONException("syntax error"); + } + + if (key.equalsIgnoreCase("r")) { + r = val; + } else if (key.equalsIgnoreCase("g")) { + g = val; + } else if (key.equalsIgnoreCase("b")) { + b = val; + } else if (key.equalsIgnoreCase("alpha")) { + alpha = val; + } else { + throw new JSONException("syntax error, " + key); + } + + if (lexer.token() == JSONToken.COMMA) { + lexer.nextToken(JSONToken.LITERAL_STRING); + } + } + + return (T) new Color(r, g, b, alpha); + } + + public int getFastMatchToken() { + return JSONToken.LBRACE; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/CurrencyCodec.java b/src/main/java/com/alibaba/fastjson/serializer/CurrencyCodec.java new file mode 100644 index 0000000000..80811802f0 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/CurrencyCodec.java @@ -0,0 +1,40 @@ +package com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.Currency; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +public class CurrencyCodec implements ObjectSerializer, ObjectDeserializer { + + public final static CurrencyCodec instance = new CurrencyCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + final SerializeWriter out = serializer.getWriter(); + if (object == null) { + out.writeNull(); + } else { + Currency currency = (Currency) object; + out.writeString(currency.getCurrencyCode()); + } + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + String text = (String) parser.parse(); + + if (text == null || text.length() == 0) { + return null; + } + + return (T) Currency.getInstance(text); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } + +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/DateFormatSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/DateFormatSerializer.java new file mode 100755 index 0000000000..f90030b75e --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/DateFormatSerializer.java @@ -0,0 +1,54 @@ +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.text.SimpleDateFormat; + +import com.alibaba.fastjson.JSON; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public class DateFormatSerializer implements ObjectSerializer { + + public final static DateFormatSerializer instance = new DateFormatSerializer(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + SerializeWriter out = serializer.getWriter(); + + if (object == null) { + out.writeNull(); + return; + } + + String pattern = ((SimpleDateFormat) object).toPattern(); + + if (out.isEnabled(SerializerFeature.WriteClassName)) { + if (object.getClass() != fieldType) { + out.write('{'); + out.writeFieldName(JSON.DEFAULT_TYPE_KEY); + serializer.write(object.getClass().getName()); + out.writeFieldValue(',', "val", pattern); + out.write('}'); + return; + } + } + + out.writeString(pattern); + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/DateSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/DateSerializer.java old mode 100644 new mode 100755 index d0a0978eb4..67fee14122 --- a/src/main/java/com/alibaba/fastjson/serializer/DateSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/DateSerializer.java @@ -16,27 +16,58 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.util.IOUtils; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class DateSerializer implements ObjectSerializer { public final static DateSerializer instance = new DateSerializer(); - public void write(JSONSerializer serializer, Object object) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); - + if (object == null) { - out.writeNull(); - return; + out.writeNull(); + return; } + if (out.isEnabled(SerializerFeature.WriteClassName)) { + if (object.getClass() != fieldType) { + if (object.getClass() == java.util.Date.class) { + out.write("new Date("); + out.writeLongAndChar(((Date) object).getTime(), ')'); + } else { + out.write('{'); + out.writeFieldName(JSON.DEFAULT_TYPE_KEY); + serializer.write(object.getClass().getName()); + out.writeFieldValue(',', "val", ((Date) object).getTime()); + out.write('}'); + } + return; + } + } + Date date = (Date) object; + + if (out.isEnabled(SerializerFeature.WriteDateUseDateFormat)) { + DateFormat format = serializer.getDateFormat(); + if (format == null) { + format = new SimpleDateFormat(JSON.DEFFAULT_DATE_FORMAT); + } + String text = format.format(date); + out.writeString(text); + return; + } + long time = date.getTime(); if (serializer.isEnabled(SerializerFeature.UseISO8601DateFormat)) { if (serializer.isEnabled(SerializerFeature.UseSingleQuotes)) { diff --git a/src/main/java/com/alibaba/fastjson/serializer/DoubleArraySerializer.java b/src/main/java/com/alibaba/fastjson/serializer/DoubleArraySerializer.java old mode 100644 new mode 100755 index f60cd64e1c..b04b8255d4 --- a/src/main/java/com/alibaba/fastjson/serializer/DoubleArraySerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/DoubleArraySerializer.java @@ -16,9 +16,10 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class DoubleArraySerializer implements ObjectSerializer { @@ -27,7 +28,7 @@ public class DoubleArraySerializer implements ObjectSerializer { public DoubleArraySerializer(){ } - public final void write(JSONSerializer serializer, Object object) throws IOException { + public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); if (object == null) { diff --git a/src/main/java/com/alibaba/fastjson/serializer/DoubleSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/DoubleSerializer.java old mode 100644 new mode 100755 index 481af43da6..8dba3612a8 --- a/src/main/java/com/alibaba/fastjson/serializer/DoubleSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/DoubleSerializer.java @@ -16,38 +16,63 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; +import java.text.DecimalFormat; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class DoubleSerializer implements ObjectSerializer { - public final static DoubleSerializer instance = new DoubleSerializer(); + public final static DoubleSerializer instance = new DoubleSerializer(); - public void write(JSONSerializer serializer, Object object) throws IOException { + private DecimalFormat decimalFormat = null; + + public DoubleSerializer(){ + + } + + public DoubleSerializer(DecimalFormat decimalFormat){ + this.decimalFormat = decimalFormat; + } + + public DoubleSerializer(String decimalFormat){ + this(new DecimalFormat(decimalFormat)); + } + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); if (object == null) { if (serializer.isEnabled(SerializerFeature.WriteNullNumberAsZero)) { out.write('0'); } else { - out.writeNull(); + out.writeNull(); } return; } - double doubleValue = ((Double) object).doubleValue(); - + double doubleValue = ((Double) object).doubleValue(); + if (Double.isNaN(doubleValue)) { out.writeNull(); } else if (Double.isInfinite(doubleValue)) { out.writeNull(); } else { - String doubleText = Double.toString(doubleValue); - if (doubleText.endsWith(".0")) { - doubleText = doubleText.substring(0, doubleText.length() - 2); + String doubleText; + if (decimalFormat == null) { + doubleText = Double.toString(doubleValue); + if (doubleText.endsWith(".0")) { + doubleText = doubleText.substring(0, doubleText.length() - 2); + } + } else { + doubleText = decimalFormat.format(doubleValue); } out.append(doubleText); + + if (serializer.isEnabled(SerializerFeature.WriteClassName)) { + out.write('D'); + } } } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/EnumSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/EnumSerializer.java old mode 100644 new mode 100755 index 6f609e1559..987767a761 --- a/src/main/java/com/alibaba/fastjson/serializer/EnumSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/EnumSerializer.java @@ -16,20 +16,25 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class EnumSerializer implements ObjectSerializer { public final static EnumSerializer instance = new EnumSerializer(); - public void write(JSONSerializer serializer, Object object) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); + if (object == null) { + serializer.getWriter().writeNull(); + return; + } if (serializer.isEnabled(SerializerFeature.WriteEnumUsingToString)) { Enum e = (Enum) object; - serializer.write(e.name()); + serializer.write(e.toString()); } else { Enum e = (Enum) object; out.writeInt(e.ordinal()); diff --git a/src/main/java/com/alibaba/fastjson/serializer/EnumerationSeriliazer.java b/src/main/java/com/alibaba/fastjson/serializer/EnumerationSeriliazer.java new file mode 100755 index 0000000000..b0cea5ce1e --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/EnumerationSeriliazer.java @@ -0,0 +1,61 @@ +package com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Enumeration; + + +public class EnumerationSeriliazer implements ObjectSerializer { + public static EnumerationSeriliazer instance = new EnumerationSeriliazer(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + SerializeWriter out = serializer.getWriter(); + + if (object == null) { + if (out.isEnabled(SerializerFeature.WriteNullListAsEmpty)) { + out.write("[]"); + } else { + out.writeNull(); + } + return; + } + + Type elementType = null; + if (serializer.isEnabled(SerializerFeature.WriteClassName)) { + if (fieldType instanceof ParameterizedType) { + ParameterizedType param = (ParameterizedType) fieldType; + elementType = param.getActualTypeArguments()[0]; + } + } + + Enumeration e = (Enumeration) object; + + SerialContext context = serializer.getContext(); + serializer.setContext(context, object, fieldName, 0); + + try { + int i = 0; + out.append('['); + while (e.hasMoreElements()) { + Object item = e.nextElement(); + if (i++ != 0) { + out.append(','); + } + + if (item == null) { + out.writeNull(); + continue; + } + + Class clazz = item.getClass(); + + ObjectSerializer itemSerializer = serializer.getObjectWriter(clazz); + itemSerializer.write(serializer, item, i - 1, elementType, 0); + } + out.append(']'); + } finally { + serializer.setContext(context); + } + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/ExceptionSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/ExceptionSerializer.java old mode 100644 new mode 100755 index 449e8d68d3..e549e1350a --- a/src/main/java/com/alibaba/fastjson/serializer/ExceptionSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ExceptionSerializer.java @@ -1,12 +1,14 @@ package com.alibaba.fastjson.serializer; +import java.lang.reflect.Type; + public class ExceptionSerializer extends JavaBeanSerializer { public ExceptionSerializer(Class clazz){ super(clazz); } - protected boolean isWriteClassName(JSONSerializer serializer) { + protected boolean isWriteClassName(JSONSerializer serializer, Object obj, Type fieldType, Object fieldName) { return true; } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/FieldSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/FieldSerializer.java old mode 100644 new mode 100755 index 25143d2c18..3edb28a930 --- a/src/main/java/com/alibaba/fastjson/serializer/FieldSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/FieldSerializer.java @@ -19,13 +19,14 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; +import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.util.FieldInfo; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ -public abstract class FieldSerializer implements Comparable { +public abstract class FieldSerializer { protected final FieldInfo fieldInfo; private final String double_quoted_fieldPrefix; @@ -36,7 +37,7 @@ public abstract class FieldSerializer implements Comparable { public FieldSerializer(FieldInfo fieldInfo){ super(); this.fieldInfo = fieldInfo; - fieldInfo.getMethod().setAccessible(true); + fieldInfo.setAccessible(true); this.double_quoted_fieldPrefix = '"' + fieldInfo.getName() + "\":"; @@ -84,14 +85,15 @@ public void writePrefix(JSONSerializer serializer) throws IOException { } } - public int compareTo(FieldSerializer o) { - return this.getName().compareTo(o.getName()); - } - public Object getPropertyValue(Object object) throws Exception { - return getMethod().invoke(object); + try { + return fieldInfo.get(object); + } catch (Exception ex) { + throw new JSONException("get property error。 " + fieldInfo.gerQualifiedName(), ex); + } } public abstract void writeProperty(JSONSerializer serializer, Object propertyValue) throws Exception; + public abstract void writeValue(JSONSerializer serializer, Object propertyValue) throws Exception; } diff --git a/src/main/java/com/alibaba/fastjson/serializer/FileCodec.java b/src/main/java/com/alibaba/fastjson/serializer/FileCodec.java new file mode 100755 index 0000000000..0485ec14f9 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/FileCodec.java @@ -0,0 +1,44 @@ +package com.alibaba.fastjson.serializer; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Type; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +public class FileCodec implements ObjectSerializer, ObjectDeserializer { + + public static FileCodec instance = new FileCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + SerializeWriter out = serializer.getWriter(); + + if (object == null) { + out.writeNull(); + return; + } + + File file = (File) object; + + serializer.write(file.getPath()); + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + Object value = parser.parse(); + + if (value == null) { + return null; + } + + String path = (String) value; + + return (T) new File(path); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/FileSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/FileSerializer.java deleted file mode 100644 index f433454428..0000000000 --- a/src/main/java/com/alibaba/fastjson/serializer/FileSerializer.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.alibaba.fastjson.serializer; - -import java.io.File; -import java.io.IOException; - -public class FileSerializer implements ObjectSerializer { - - public static FileSerializer instance = new FileSerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - SerializeWriter out = serializer.getWriter(); - - if (object == null) { - out.writeNull(); - return; - } - - File file = (File) object; - - serializer.write(file.getPath()); - } - -} diff --git a/src/main/java/com/alibaba/fastjson/serializer/FilterUtils.java b/src/main/java/com/alibaba/fastjson/serializer/FilterUtils.java old mode 100644 new mode 100755 index eaa21fc962..00ac25d313 --- a/src/main/java/com/alibaba/fastjson/serializer/FilterUtils.java +++ b/src/main/java/com/alibaba/fastjson/serializer/FilterUtils.java @@ -1,8 +1,56 @@ package com.alibaba.fastjson.serializer; +import java.lang.reflect.Type; import java.util.List; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.deserializer.ExtraProcessor; +import com.alibaba.fastjson.parser.deserializer.ExtraTypeProvider; + public class FilterUtils { + public static Type getExtratype(DefaultJSONParser parser, Object object, String key) { + List extraTypeProviders = parser.getExtraTypeProvidersDirect(); + if (extraTypeProviders == null) { + return null; + } + + Type type = null; + for (ExtraTypeProvider extraProvider : extraTypeProviders) { + type = extraProvider.getExtraType(object, key); + } + return type; + } + + public static void processExtra(DefaultJSONParser parser, Object object, String key, Object value) { + List extraProcessors = parser.getExtraProcessorsDirect(); + if (extraProcessors == null) { + return; + } + for (ExtraProcessor process : extraProcessors) { + process.processExtra(object, key, value); + } + } + + public static char writeBefore(JSONSerializer serializer, Object object, char seperator) { + List beforeFilters = serializer.getBeforeFiltersDirect(); + if (beforeFilters != null) { + for (BeforeFilter beforeFilter : beforeFilters) { + seperator = beforeFilter.writeBefore(serializer, object, seperator); + } + } + return seperator; + } + + public static char writeAfter(JSONSerializer serializer, Object object, char seperator) { + List afterFilters = serializer.getAfterFiltersDirect(); + if (afterFilters != null) { + for (AfterFilter afterFilter : afterFilters) { + seperator = afterFilter.writeAfter(serializer, object, seperator); + } + } + return seperator; + } + public static Object processValue(JSONSerializer serializer, Object object, String key, Object propertyValue) { List valueFilters = serializer.getValueFiltersDirect(); if (valueFilters != null) { @@ -13,7 +61,7 @@ public static Object processValue(JSONSerializer serializer, Object object, Stri return propertyValue; } - + public static String processKey(JSONSerializer serializer, Object object, String key, Object propertyValue) { List nameFilters = serializer.getNameFiltersDirect(); if (nameFilters != null) { @@ -128,19 +176,34 @@ public static String processKey(JSONSerializer serializer, Object object, String return key; } - + + public static boolean applyName(JSONSerializer serializer, Object object, String key) { + List filters = serializer.getPropertyPreFiltersDirect(); + + if (filters == null) { + return true; + } + + for (PropertyPreFilter filter : filters) { + if (!filter.apply(serializer, object, key)) { + return false; + } + } + + return true; + } + public static boolean apply(JSONSerializer serializer, Object object, String key, Object propertyValue) { List propertyFilters = serializer.getPropertyFiltersDirect(); - - if (propertyFilters != null) { - boolean apply = true; - for (PropertyFilter propertyFilter : propertyFilters) { - if (!propertyFilter.apply(object, key, propertyValue)) { - return false; - } - } - return apply; + if (propertyFilters == null) { + return true; + } + + for (PropertyFilter propertyFilter : propertyFilters) { + if (!propertyFilter.apply(object, key, propertyValue)) { + return false; + } } return true; @@ -148,7 +211,7 @@ public static boolean apply(JSONSerializer serializer, Object object, String key public static boolean apply(JSONSerializer serializer, Object object, String key, byte value) { List propertyFilters = serializer.getPropertyFiltersDirect(); - + if (propertyFilters != null) { boolean apply = true; @@ -167,7 +230,7 @@ public static boolean apply(JSONSerializer serializer, Object object, String key public static boolean apply(JSONSerializer serializer, Object object, String key, short value) { List propertyFilters = serializer.getPropertyFiltersDirect(); - + if (propertyFilters != null) { boolean apply = true; @@ -186,7 +249,7 @@ public static boolean apply(JSONSerializer serializer, Object object, String key public static boolean apply(JSONSerializer serializer, Object object, String key, int value) { List propertyFilters = serializer.getPropertyFiltersDirect(); - + if (propertyFilters != null) { boolean apply = true; @@ -202,10 +265,10 @@ public static boolean apply(JSONSerializer serializer, Object object, String key return true; } - + public static boolean apply(JSONSerializer serializer, Object object, String key, char value) { List propertyFilters = serializer.getPropertyFiltersDirect(); - + if (propertyFilters != null) { boolean apply = true; @@ -224,7 +287,7 @@ public static boolean apply(JSONSerializer serializer, Object object, String key public static boolean apply(JSONSerializer serializer, Object object, String key, long value) { List propertyFilters = serializer.getPropertyFiltersDirect(); - + if (propertyFilters != null) { boolean apply = true; @@ -243,7 +306,7 @@ public static boolean apply(JSONSerializer serializer, Object object, String key public static boolean apply(JSONSerializer serializer, Object object, String key, float value) { List propertyFilters = serializer.getPropertyFiltersDirect(); - + if (propertyFilters != null) { boolean apply = true; @@ -262,7 +325,7 @@ public static boolean apply(JSONSerializer serializer, Object object, String key public static boolean apply(JSONSerializer serializer, Object object, String key, double value) { List propertyFilters = serializer.getPropertyFiltersDirect(); - + if (propertyFilters != null) { boolean apply = true; diff --git a/src/main/java/com/alibaba/fastjson/serializer/FloatArraySerializer.java b/src/main/java/com/alibaba/fastjson/serializer/FloatArraySerializer.java old mode 100644 new mode 100755 index 1b1d8beb79..97906b08a8 --- a/src/main/java/com/alibaba/fastjson/serializer/FloatArraySerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/FloatArraySerializer.java @@ -16,9 +16,10 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class FloatArraySerializer implements ObjectSerializer { @@ -27,7 +28,7 @@ public class FloatArraySerializer implements ObjectSerializer { public FloatArraySerializer(){ } - public final void write(JSONSerializer serializer, Object object) throws IOException { + public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); if (object == null) { diff --git a/src/main/java/com/alibaba/fastjson/serializer/FloatCodec.java b/src/main/java/com/alibaba/fastjson/serializer/FloatCodec.java new file mode 100755 index 0000000000..fbc97bccff --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/FloatCodec.java @@ -0,0 +1,97 @@ +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.util.TypeUtils; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public class FloatCodec implements ObjectSerializer, ObjectDeserializer { + + public static FloatCodec instance = new FloatCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + SerializeWriter out = serializer.getWriter(); + + if (object == null) { + if (serializer.isEnabled(SerializerFeature.WriteNullNumberAsZero)) { + out.write('0'); + } else { + out.writeNull(); + } + return; + } + + float floatValue = ((Float) object).floatValue(); + + if (Float.isNaN(floatValue)) { + out.writeNull(); + } else if (Float.isInfinite(floatValue)) { + out.writeNull(); + } else { + String floatText= Float.toString(floatValue); + if (floatText.endsWith(".0")) { + floatText = floatText.substring(0, floatText.length() - 2); + } + out.write(floatText); + + if (serializer.isEnabled(SerializerFeature.WriteClassName)) { + out.write('F'); + } + } + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + return (T) deserialze(parser); + } + + @SuppressWarnings("unchecked") + public static T deserialze(DefaultJSONParser parser) { + final JSONLexer lexer = parser.getLexer(); + if (lexer.token() == JSONToken.LITERAL_INT) { + String val = lexer.numberString(); + lexer.nextToken(JSONToken.COMMA); + return (T) Float.valueOf(Float.parseFloat(val)); + } + + if (lexer.token() == JSONToken.LITERAL_FLOAT) { + float val = lexer.floatValue(); + lexer.nextToken(JSONToken.COMMA); + return (T) Float.valueOf(val); + } + + Object value = parser.parse(); + + if (value == null) { + return null; + } + + return (T) TypeUtils.castToFloat(value); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_INT; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/FloatSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/FloatSerializer.java deleted file mode 100644 index d552ef432b..0000000000 --- a/src/main/java/com/alibaba/fastjson/serializer/FloatSerializer.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.serializer; - -import java.io.IOException; - -/** - * @author wenshao - */ -public class FloatSerializer implements ObjectSerializer { - - public static FloatSerializer instance = new FloatSerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - SerializeWriter out = serializer.getWriter(); - - if (object == null) { - if (serializer.isEnabled(SerializerFeature.WriteNullNumberAsZero)) { - out.write('0'); - } else { - out.writeNull(); - } - return; - } - - float floatValue = ((Float) object).floatValue(); - - if (Float.isNaN(floatValue)) { - out.writeNull(); - } else if (Float.isInfinite(floatValue)) { - out.writeNull(); - } else { - String floatText= Float.toString(floatValue); - if (floatText.endsWith(".0")) { - floatText = floatText.substring(0, floatText.length() - 2); - } - out.write(floatText); - } - } -} diff --git a/src/main/java/com/alibaba/fastjson/serializer/FontCodec.java b/src/main/java/com/alibaba/fastjson/serializer/FontCodec.java new file mode 100755 index 0000000000..294f4be991 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/FontCodec.java @@ -0,0 +1,108 @@ +package com.alibaba.fastjson.serializer; + +import java.awt.Font; +import java.io.IOException; +import java.lang.reflect.Type; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +public class FontCodec implements ObjectSerializer, ObjectDeserializer { + + public final static FontCodec instance = new FontCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + SerializeWriter out = serializer.getWriter(); + Font font = (Font) object; + if (font == null) { + out.writeNull(); + return; + } + + char sep = '{'; + if (out.isEnabled(SerializerFeature.WriteClassName)) { + out.write('{'); + out.writeFieldName(JSON.DEFAULT_TYPE_KEY); + out.writeString(Font.class.getName()); + sep = ','; + } + + out.writeFieldValue(sep, "name", font.getName()); + out.writeFieldValue(',', "style", font.getStyle()); + out.writeFieldValue(',', "size", font.getSize()); + out.write('}'); + + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + JSONLexer lexer = parser.getLexer(); + + if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(JSONToken.COMMA); + return null; + } + + if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) { + throw new JSONException("syntax error"); + } + lexer.nextToken(); + + int size = 0, style = 0; + String name = null; + for (;;) { + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(); + break; + } + + String key; + if (lexer.token() == JSONToken.LITERAL_STRING) { + key = lexer.stringVal(); + lexer.nextTokenWithColon(JSONToken.LITERAL_INT); + } else { + throw new JSONException("syntax error"); + } + + + if (key.equalsIgnoreCase("name")) { + if (lexer.token() == JSONToken.LITERAL_STRING) { + name = lexer.stringVal(); + lexer.nextToken(); + } else { + throw new JSONException("syntax error"); + } + } else if (key.equalsIgnoreCase("style")) { + if (lexer.token() == JSONToken.LITERAL_INT) { + style = lexer.intValue(); + lexer.nextToken(); + } else { + throw new JSONException("syntax error"); + } + } else if (key.equalsIgnoreCase("size")) { + if (lexer.token() == JSONToken.LITERAL_INT) { + size = lexer.intValue(); + lexer.nextToken(); + } else { + throw new JSONException("syntax error"); + } + } else { + throw new JSONException("syntax error, " + key); + } + + if (lexer.token() == JSONToken.COMMA) { + lexer.nextToken(JSONToken.LITERAL_STRING); + } + } + + return (T) new Font(name, style, size); + } + + public int getFastMatchToken() { + return JSONToken.LBRACE; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/InetAddressCodec.java b/src/main/java/com/alibaba/fastjson/serializer/InetAddressCodec.java new file mode 100755 index 0000000000..278c7ace59 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/InetAddressCodec.java @@ -0,0 +1,52 @@ +package com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.net.InetAddress; +import java.net.UnknownHostException; + +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +public class InetAddressCodec implements ObjectSerializer, ObjectDeserializer { + + public static InetAddressCodec instance = new InetAddressCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + if (object == null) { + serializer.writeNull(); + return; + } + + InetAddress address = (InetAddress) object; + + serializer.write(address.getHostAddress()); + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + + String host = (String) parser.parse(); + + if (host == null) { + return null; + } + + if (host.length() == 0) { + return null; + } + + try { + return (T) InetAddress.getByName(host); + } catch (UnknownHostException e) { + throw new JSONException("deserialize error", e); + } + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } +} + diff --git a/src/main/java/com/alibaba/fastjson/serializer/InetAddressSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/InetAddressSerializer.java deleted file mode 100644 index d5c4929f7b..0000000000 --- a/src/main/java/com/alibaba/fastjson/serializer/InetAddressSerializer.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.alibaba.fastjson.serializer; - -import java.io.IOException; -import java.net.InetAddress; - -public class InetAddressSerializer implements ObjectSerializer { - - public static InetAddressSerializer instance = new InetAddressSerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - if (object == null) { - serializer.writeNull(); - return; - } - - InetAddress address = (InetAddress) object; - - serializer.write(address.getHostAddress()); - } -} - diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/InetSocketAddressDeserializer.java b/src/main/java/com/alibaba/fastjson/serializer/InetSocketAddressCodec.java old mode 100644 new mode 100755 similarity index 54% rename from src/main/java/com/alibaba/fastjson/parser/deserializer/InetSocketAddressDeserializer.java rename to src/main/java/com/alibaba/fastjson/serializer/InetSocketAddressCodec.java index d470aeacc6..f841dd41ec --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/InetSocketAddressDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/InetSocketAddressCodec.java @@ -1,20 +1,44 @@ -package com.alibaba.fastjson.parser.deserializer; +package com.alibaba.fastjson.serializer; +import java.io.IOException; import java.lang.reflect.Type; import java.net.InetAddress; import java.net.InetSocketAddress; import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; -public class InetSocketAddressDeserializer implements ObjectDeserializer { +public class InetSocketAddressCodec implements ObjectSerializer, ObjectDeserializer { - public final static InetSocketAddressDeserializer instance = new InetSocketAddressDeserializer(); + public static InetSocketAddressCodec instance = new InetSocketAddressCodec(); + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + if (object == null) { + serializer.writeNull(); + return; + } + + SerializeWriter out = serializer.getWriter(); + InetSocketAddress address = (InetSocketAddress) object; + + InetAddress inetAddress = address.getAddress(); + + out.write('{'); + if (inetAddress != null) { + out.writeFieldName("address"); + serializer.write(inetAddress); + out.write(','); + } + out.writeFieldName("port"); + out.writeInt(address.getPort()); + out.write('}'); + } + @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { JSONLexer lexer = parser.getLexer(); if (lexer.token() == JSONToken.NULL) { @@ -27,8 +51,9 @@ public T deserialze(DefaultExtJSONParser parser, Type clazz) { InetAddress address = null; int port = 0; for (;;) { - String key = lexer.symbol(parser.getSymbolTable()); - lexer.nextToken(); + String key = lexer.stringVal(); + lexer.nextToken(JSONToken.COLON); + if (key.equals("address")) { parser.accept(JSONToken.COLON); diff --git a/src/main/java/com/alibaba/fastjson/serializer/InetSocketAddressSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/InetSocketAddressSerializer.java deleted file mode 100644 index 3c19b80ffc..0000000000 --- a/src/main/java/com/alibaba/fastjson/serializer/InetSocketAddressSerializer.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.alibaba.fastjson.serializer; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; - -public class InetSocketAddressSerializer implements ObjectSerializer { - - public static InetSocketAddressSerializer instance = new InetSocketAddressSerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - if (object == null) { - serializer.writeNull(); - return; - } - - SerializeWriter out = serializer.getWriter(); - InetSocketAddress address = (InetSocketAddress) object; - - InetAddress inetAddress = address.getAddress(); - - out.write('{'); - if (inetAddress != null) { - out.writeFieldName("address"); - serializer.write(inetAddress); - out.write(','); - } - out.writeFieldName("port"); - out.writeInt(address.getPort()); - out.write('}'); - } -} diff --git a/src/main/java/com/alibaba/fastjson/serializer/IntArraySerializer.java b/src/main/java/com/alibaba/fastjson/serializer/IntArraySerializer.java old mode 100644 new mode 100755 index 6be09eeea3..8aba0e6434 --- a/src/main/java/com/alibaba/fastjson/serializer/IntArraySerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/IntArraySerializer.java @@ -16,15 +16,16 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class IntArraySerializer implements ObjectSerializer { public static IntArraySerializer instance = new IntArraySerializer(); - public final void write(JSONSerializer serializer, Object object) throws IOException { + public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); if (object == null) { @@ -38,6 +39,13 @@ public final void write(JSONSerializer serializer, Object object) throws IOExcep int[] array = (int[]) object; - out.writeIntArray(array); + out.write('['); + for (int i = 0; i < array.length; ++i) { + if (i != 0) { + out.write(','); + } + out.writeInt(array[i]); + } + out.write(']'); } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/IntegerCodec.java b/src/main/java/com/alibaba/fastjson/serializer/IntegerCodec.java new file mode 100755 index 0000000000..cc5290f5c1 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/IntegerCodec.java @@ -0,0 +1,96 @@ +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.util.concurrent.atomic.AtomicInteger; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.util.TypeUtils; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public class IntegerCodec implements ObjectSerializer, ObjectDeserializer { + + public static IntegerCodec instance = new IntegerCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + SerializeWriter out = serializer.getWriter(); + + Number value = (Number) object; + + if (value == null) { + if (out.isEnabled(SerializerFeature.WriteNullNumberAsZero)) { + out.write('0'); + } else { + out.writeNull(); + } + return; + } + + out.writeInt(value.intValue()); + + if (serializer.isEnabled(SerializerFeature.WriteClassName)) { + Class clazz = value.getClass(); + if (clazz == Byte.class) { + out.write('B'); + } else if (clazz == Short.class) { + out.write('S'); + } + } + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + final JSONLexer lexer = parser.getLexer(); + + if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(JSONToken.COMMA); + return null; + } + + Integer intObj; + if (lexer.token() == JSONToken.LITERAL_INT) { + int val = lexer.intValue(); + lexer.nextToken(JSONToken.COMMA); + intObj = Integer.valueOf(val); + } else if (lexer.token() == JSONToken.LITERAL_FLOAT) { + BigDecimal decimalValue = lexer.decimalValue(); + lexer.nextToken(JSONToken.COMMA); + intObj = Integer.valueOf(decimalValue.intValue()); + } else { + Object value = parser.parse(); + + intObj = TypeUtils.castToInt(value); + } + + if (clazz == AtomicInteger.class) { + return (T) new AtomicInteger(intObj.intValue()); + } + + return (T) intObj; + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_INT; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/IntegerSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/IntegerSerializer.java deleted file mode 100644 index 2ad6c96832..0000000000 --- a/src/main/java/com/alibaba/fastjson/serializer/IntegerSerializer.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.serializer; - -import java.io.IOException; - -/** - * @author wenshao - */ -public class IntegerSerializer implements ObjectSerializer { - - public static IntegerSerializer instance = new IntegerSerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - SerializeWriter out = serializer.getWriter(); - - Number value = (Number) object; - - if (value == null) { - if (out.isEnabled(SerializerFeature.WriteNullNumberAsZero)) { - out.write('0'); - } else { - out.writeNull(); - } - return; - } - - out.writeInt(value.intValue()); - } -} diff --git a/src/main/java/com/alibaba/fastjson/serializer/JSONAwareSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/JSONAwareSerializer.java old mode 100644 new mode 100755 index 8aab28f26a..5c9f121012 --- a/src/main/java/com/alibaba/fastjson/serializer/JSONAwareSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/JSONAwareSerializer.java @@ -16,17 +16,18 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; import com.alibaba.fastjson.JSONAware; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class JSONAwareSerializer implements ObjectSerializer { public static JSONAwareSerializer instance = new JSONAwareSerializer(); - public void write(JSONSerializer serializer, Object object) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); JSONAware aware = (JSONAware) object; diff --git a/src/main/java/com/alibaba/fastjson/serializer/JSONLibDataFormatSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/JSONLibDataFormatSerializer.java old mode 100644 new mode 100755 index 7cb12da4bd..7ce06da373 --- a/src/main/java/com/alibaba/fastjson/serializer/JSONLibDataFormatSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/JSONLibDataFormatSerializer.java @@ -1,6 +1,7 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; import java.util.Date; import com.alibaba.fastjson.JSONObject; @@ -11,7 +12,7 @@ public JSONLibDataFormatSerializer(){ } @SuppressWarnings("deprecation") - public void write(JSONSerializer serializer, Object object) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { if (object == null) { serializer.getWriter().writeNull(); return; diff --git a/src/main/java/com/alibaba/fastjson/serializer/URLSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/JSONSerializable.java similarity index 60% rename from src/main/java/com/alibaba/fastjson/serializer/URLSerializer.java rename to src/main/java/com/alibaba/fastjson/serializer/JSONSerializable.java index 40df3bce93..adb4ae31c8 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/URLSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/JSONSerializable.java @@ -1,36 +1,26 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.serializer; - -import java.io.IOException; - -/** - * @author wenshao - */ -public class URLSerializer implements ObjectSerializer { - - public final static URLSerializer instance = new URLSerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - if (object == null) { - serializer.writeNull(); - return; - } - - serializer.write(object.toString()); - } - -} +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public interface JSONSerializable { + void write(JSONSerializer serializer, Object fieldName, Type fieldType, int features) throws IOException; +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/URISerializer.java b/src/main/java/com/alibaba/fastjson/serializer/JSONSerializableSerializer.java similarity index 57% rename from src/main/java/com/alibaba/fastjson/serializer/URISerializer.java rename to src/main/java/com/alibaba/fastjson/serializer/JSONSerializableSerializer.java index 8dd391d07d..50ba4b8c10 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/URISerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/JSONSerializableSerializer.java @@ -1,38 +1,32 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.serializer; - -import java.io.IOException; -import java.net.URI; - -/** - * @author wenshao - */ -public class URISerializer implements ObjectSerializer { - - public final static URISerializer instance = new URISerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - if (object == null) { - serializer.writeNull(); - return; - } - - URI uri = (URI) object; - serializer.write(uri.toString()); - } - -} +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public class JSONSerializableSerializer implements ObjectSerializer { + + public static JSONSerializableSerializer instance = new JSONSerializableSerializer(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + JSONSerializable jsonSerializable = ((JSONSerializable) object); + jsonSerializable.write(serializer, fieldName, fieldType, 0); + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/JSONSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/JSONSerializer.java old mode 100644 new mode 100755 index 6b292c733c..8aaa7f34c2 --- a/src/main/java/com/alibaba/fastjson/serializer/JSONSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/JSONSerializer.java @@ -18,35 +18,202 @@ import java.io.IOException; import java.io.Writer; import java.lang.reflect.Type; -import java.nio.charset.Charset; +import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Collection; import java.util.Date; +import java.util.IdentityHashMap; import java.util.List; -import java.util.Map; -import java.util.TimeZone; -import com.alibaba.fastjson.JSONAware; import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.JSONStreamAware; -import com.alibaba.fastjson.util.ServiceLoader; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class JSONSerializer { - private final SerializeConfig config; + private final SerializeConfig config; - private final SerializeWriter out; + private final SerializeWriter out; - private List propertyFilters = null; - private List valueFilters = null; - private List nameFilters = null; + private List beforeFilters = null; + private List afterFilters = null; + private List propertyFilters = null; + private List valueFilters = null; + private List nameFilters = null; + private List propertyPreFilters = null; - private int indentCount = 0; - private String indent = "\t"; + private int indentCount = 0; + private String indent = "\t"; + + private String dateFormatPattern; + private DateFormat dateFormat; + + private IdentityHashMap references = null; + private SerialContext context; + + public JSONSerializer(){ + this(new SerializeWriter(), SerializeConfig.getGlobalInstance()); + } + + public JSONSerializer(SerializeWriter out){ + this(out, SerializeConfig.getGlobalInstance()); + } + + public JSONSerializer(SerializeConfig config){ + this(new SerializeWriter(), config); + } + + @Deprecated + public JSONSerializer(JSONSerializerMap mapping){ + this(new SerializeWriter(), mapping); + } + + public JSONSerializer(SerializeWriter out, SerializeConfig config){ + this.out = out; + this.config = config; + } + + public String getDateFormatPattern() { + if (dateFormat instanceof SimpleDateFormat) { + return ((SimpleDateFormat) dateFormat).toPattern(); + } + return dateFormatPattern; + } + + public DateFormat getDateFormat() { + if (dateFormat == null) { + if (dateFormatPattern != null) { + dateFormat = new SimpleDateFormat(dateFormatPattern); + } + } + + return dateFormat; + } + + public void setDateFormat(DateFormat dateFormat) { + this.dateFormat = dateFormat; + if (dateFormatPattern != null) { + dateFormatPattern = null; + } + } + + public void setDateFormat(String dateFormat) { + this.dateFormatPattern = dateFormat; + if (this.dateFormat != null) { + this.dateFormat = null; + } + } + + public SerialContext getContext() { + return context; + } + + public void setContext(SerialContext context) { + this.context = context; + } + + public void setContext(SerialContext parent, Object object, Object fieldName, int features) { + this.setContext(parent, object, fieldName, features, 0); + } + + public void setContext(SerialContext parent, Object object, Object fieldName, int features, int fieldFeatures) { + if (isEnabled(SerializerFeature.DisableCircularReferenceDetect)) { + return; + } + + this.context = new SerialContext(parent, object, fieldName, features, fieldFeatures); + if (references == null) { + references = new IdentityHashMap(); + } + this.references.put(object, context); + } + + public void setContext(Object object, Object fieldName) { + this.setContext(context, object, fieldName, 0); + } + + public void popContext() { + if (context != null) { + this.context = this.context.getParent(); + } + } + + public final boolean isWriteClassName(Type fieldType, Object obj) { + boolean result = out.isEnabled(SerializerFeature.WriteClassName); + + if (!result) { + return false; + } + + if (fieldType == null) { + if (this.isEnabled(SerializerFeature.NotWriteRootClassName)) { + boolean isRoot = context.getParent() == null; + if (isRoot) { + return false; + } + } + } + + return true; + } + + public SerialContext getSerialContext(Object object) { + if (references == null) { + return null; + } + + return references.get(object); + } + + public boolean containsReference(Object value) { + if (references == null) { + return false; + } + + return references.containsKey(value); + } + + public void writeReference(Object object) { + SerialContext context = this.getContext(); + Object current = context.getObject(); + + if (object == current) { + out.write("{\"$ref\":\"@\"}"); + return; + } + + SerialContext parentContext = context.getParent(); + + if (parentContext != null) { + if (object == parentContext.getObject()) { + out.write("{\"$ref\":\"..\"}"); + return; + } + } + + SerialContext rootContext = context; + for (;;) { + if (rootContext.getParent() == null) { + break; + } + rootContext = rootContext.getParent(); + } + + if (object == rootContext.getObject()) { + out.write("{\"$ref\":\"$\"}"); + return; + } + + SerialContext refContext = this.getSerialContext(object); + + String path = refContext.getPath(); + + out.write("{\"$ref\":\""); + out.write(path); + out.write("\"}"); + return; + } public List getValueFilters() { if (valueFilters == null) { @@ -79,6 +246,30 @@ public void println() { } } + public List getBeforeFilters() { + if (beforeFilters == null) { + beforeFilters = new ArrayList(); + } + + return beforeFilters; + } + + public List getBeforeFiltersDirect() { + return beforeFilters; + } + + public List getAfterFilters() { + if (afterFilters == null) { + afterFilters = new ArrayList(); + } + + return afterFilters; + } + + public List getAfterFiltersDirect() { + return afterFilters; + } + public List getNameFilters() { if (nameFilters == null) { nameFilters = new ArrayList(); @@ -91,6 +282,18 @@ public List getNameFiltersDirect() { return nameFilters; } + public List getPropertyPreFilters() { + if (propertyPreFilters == null) { + propertyPreFilters = new ArrayList(); + } + + return propertyPreFilters; + } + + public List getPropertyPreFiltersDirect() { + return propertyPreFilters; + } + public List getPropertyFilters() { if (propertyFilters == null) { propertyFilters = new ArrayList(); @@ -103,23 +306,6 @@ public List getPropertyFiltersDirect() { return propertyFilters; } - public JSONSerializer(){ - this(new SerializeWriter(), SerializeConfig.getGlobalInstance()); - } - - public JSONSerializer(SerializeWriter out){ - this(out, SerializeConfig.getGlobalInstance()); - } - - public JSONSerializer(SerializeConfig mapping){ - this(new SerializeWriter(), mapping); - } - - public JSONSerializer(SerializeWriter out, SerializeConfig config){ - this.out = out; - this.config = config; - } - public SerializeWriter getWriter() { return out; } @@ -163,6 +349,34 @@ public static final void write(SerializeWriter out, Object object) { } public final void write(Object object) { + if (object == null) { + out.writeNull(); + return; + } + + Class clazz = object.getClass(); + ObjectSerializer writer = getObjectWriter(clazz); + + try { + writer.write(this, object, null, null, 0); + } catch (IOException e) { + throw new JSONException(e.getMessage(), e); + } + } + + public final void writeWithFieldName(Object object, Object fieldName) { + writeWithFieldName(object, fieldName, null, 0); + } + + protected final void writeKeyValue(char seperator, String key, Object value) { + if (seperator != '\0') { + out.write(seperator); + } + out.writeFieldName(key); + write(value); + } + + public final void writeWithFieldName(Object object, Object fieldName, Type fieldType, int fieldFeatures) { try { if (object == null) { out.writeNull(); @@ -173,7 +387,7 @@ public final void write(Object object) { ObjectSerializer writer = getObjectWriter(clazz); - writer.write(this, object); + writer.write(this, object, fieldName, fieldType, fieldFeatures); } catch (IOException e) { throw new JSONException(e.getMessage(), e); } @@ -181,7 +395,11 @@ public final void write(Object object) { public final void writeWithFormat(Object object, String format) { if (object instanceof Date) { - String text = new SimpleDateFormat(format).format((Date) object); + DateFormat dateFormat = this.getDateFormat(); + if (dateFormat == null) { + dateFormat = new SimpleDateFormat(format); + } + String text = dateFormat.format((Date) object); out.writeString(text); return; } @@ -189,57 +407,15 @@ public final void writeWithFormat(Object object, String format) { } public final void write(String text) { - StringSerializer.instance.write(this, text); + StringCodec.instance.write(this, text); } public ObjectSerializer getObjectWriter(Class clazz) { - ObjectSerializer writer = config.get(clazz); - - if (writer == null) { - final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - for (AutowiredObjectSerializer autowired : ServiceLoader.load(AutowiredObjectSerializer.class, classLoader)) { - for (Type forType : autowired.getAutowiredFor()) { - config.put(forType, autowired); - } - } - - writer = config.get(clazz); - } - - if (writer == null) { - if (Map.class.isAssignableFrom(clazz)) { - config.put(clazz, MapSerializer.instance); - } else if (List.class.isAssignableFrom(clazz)) { - config.put(clazz, ListSerializer.instance); - } else if (Collection.class.isAssignableFrom(clazz)) { - config.put(clazz, CollectionSerializer.instance); - } else if (Date.class.isAssignableFrom(clazz)) { - config.put(clazz, DateSerializer.instance); - } else if (JSONAware.class.isAssignableFrom(clazz)) { - config.put(clazz, JSONAwareSerializer.instance); - } else if (JSONStreamAware.class.isAssignableFrom(clazz)) { - config.put(clazz, JSONStreamAwareSerializer.instance); - } else if (clazz.isEnum()) { - config.put(clazz, EnumSerializer.instance); - } else if (clazz.isArray()) { - Class componentType = clazz.getComponentType(); - ObjectSerializer compObjectSerializer = getObjectWriter(componentType); - config.put(clazz, new ArraySerializer(compObjectSerializer)); - } else if (Throwable.class.isAssignableFrom(clazz)) { - config.put(clazz, new ExceptionSerializer(clazz)); - } else if (TimeZone.class.isAssignableFrom(clazz)) { - config.put(clazz, TimeZoneSerializer.instance); - } else if (Appendable.class.isAssignableFrom(clazz)) { - config.put(clazz, AppendableSerializer.instance); - } else if (Charset.class.isAssignableFrom(clazz)) { - config.put(clazz, CharsetSerializer.instance); - } else { - config.put(clazz, config.createJavaBeanSerializer(clazz)); - } + return config.getObjectWriter(clazz); + } - writer = config.get(clazz); - } - return writer; + public void close() { + this.out.close(); } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/JSONSerializerContext.java b/src/main/java/com/alibaba/fastjson/serializer/JSONSerializerContext.java old mode 100644 new mode 100755 index 10f1955327..6a061a0103 --- a/src/main/java/com/alibaba/fastjson/serializer/JSONSerializerContext.java +++ b/src/main/java/com/alibaba/fastjson/serializer/JSONSerializerContext.java @@ -18,7 +18,7 @@ /** * circular references detect * - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public final class JSONSerializerContext { diff --git a/src/main/java/com/alibaba/fastjson/serializer/JSONSerializerMap.java b/src/main/java/com/alibaba/fastjson/serializer/JSONSerializerMap.java old mode 100644 new mode 100755 index 42d2a4296e..6b56a825c4 --- a/src/main/java/com/alibaba/fastjson/serializer/JSONSerializerMap.java +++ b/src/main/java/com/alibaba/fastjson/serializer/JSONSerializerMap.java @@ -1,6 +1,9 @@ package com.alibaba.fastjson.serializer; + @Deprecated public class JSONSerializerMap extends SerializeConfig { - + public final boolean put(Class clazz, ObjectSerializer serializer) { + return super.put(clazz, serializer); + } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/JSONStreamAwareSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/JSONStreamAwareSerializer.java old mode 100644 new mode 100755 index 5fbe2ff656..da164b6c9e --- a/src/main/java/com/alibaba/fastjson/serializer/JSONStreamAwareSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/JSONStreamAwareSerializer.java @@ -16,17 +16,18 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; import com.alibaba.fastjson.JSONStreamAware; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class JSONStreamAwareSerializer implements ObjectSerializer { public static JSONStreamAwareSerializer instance = new JSONStreamAwareSerializer(); - public void write(JSONSerializer serializer, Object object) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); JSONStreamAware aware = (JSONStreamAware) object; diff --git a/src/main/java/com/alibaba/fastjson/serializer/JavaBeanSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/JavaBeanSerializer.java old mode 100644 new mode 100755 index 7d55ae5876..b57fd28a4c --- a/src/main/java/com/alibaba/fastjson/serializer/JavaBeanSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/JavaBeanSerializer.java @@ -17,26 +17,29 @@ import java.io.IOException; import java.lang.reflect.Field; -import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.Type; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.annotation.JSONField; -import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.util.FieldInfo; +import com.alibaba.fastjson.util.TypeUtils; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class JavaBeanSerializer implements ObjectSerializer { // serializers - private final FieldSerializer[] getters; + private final FieldSerializer[] getters; + private final FieldSerializer[] sortedGetters; + private transient Map getterMap; + + private int features = 0; public FieldSerializer[] getGetters() { return getters; @@ -60,23 +63,36 @@ static Map createAliasMap(String... aliasList) { } public JavaBeanSerializer(Class clazz, Map aliasMap){ - List getterList = new ArrayList(); + this.features = TypeUtils.getSerializeFeatures(clazz); + + { + List getterList = new ArrayList(); + List fieldInfoList = TypeUtils.computeGetters(clazz, aliasMap, false); - List fieldInfoList = computeGetters(clazz, aliasMap); + for (FieldInfo fieldInfo : fieldInfoList) { + getterList.add(createFieldSerializer(fieldInfo)); + } - for (FieldInfo fieldInfo : fieldInfoList) { - getterList.add(createFieldSerializer(fieldInfo)); + getters = getterList.toArray(new FieldSerializer[getterList.size()]); } + { + List getterList = new ArrayList(); + List fieldInfoList = TypeUtils.computeGetters(clazz, aliasMap, true); - // - getters = getterList.toArray(new FieldSerializer[getterList.size()]); + for (FieldInfo fieldInfo : fieldInfoList) { + getterList.add(createFieldSerializer(fieldInfo)); + } + + sortedGetters = getterList.toArray(new FieldSerializer[getterList.size()]); + } } - protected boolean isWriteClassName(JSONSerializer serializer) { - return serializer.isEnabled(SerializerFeature.WriteClassName); + protected boolean isWriteClassName(JSONSerializer serializer, Object obj, Type fieldType, Object fieldName) { + return serializer.isWriteClassName(fieldType, obj); } - public void write(JSONSerializer serializer, Object object) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) + throws IOException { SerializeWriter out = serializer.getWriter(); if (object == null) { @@ -84,23 +100,49 @@ public void write(JSONSerializer serializer, Object object) throws IOException { return; } - FieldSerializer[] getters = this.getters; + if (writeReference(serializer, object, features)) { + return; + } + + final FieldSerializer[] getters; if (out.isEnabled(SerializerFeature.SortField)) { - Arrays.sort(getters); + getters = this.sortedGetters; + } else { + getters = this.getters; } + SerialContext parent = serializer.getContext(); + serializer.setContext(parent, object, fieldName, this.features, features); + + final boolean writeAsArray = isWriteAsArray(serializer); + try { - out.append('{'); + final char startSeperator = writeAsArray ? '[' : '{'; + final char endSeperator = writeAsArray ? ']' : '}'; + out.append(startSeperator); + + if (getters.length > 0 && out.isEnabled(SerializerFeature.PrettyFormat)) { + serializer.incrementIndent(); + serializer.println(); + } boolean commaFlag = false; - if (isWriteClassName(serializer)) { - out.writeFieldName("class"); - serializer.write(object.getClass()); - commaFlag = true; + if (isWriteClassName(serializer, object, fieldType, fieldName)) { + Class objClass = object.getClass(); + if (objClass != fieldType) { + out.writeFieldName(JSON.DEFAULT_TYPE_KEY); + serializer.write(object.getClass()); + commaFlag = true; + } } + char seperator = commaFlag ? ',' : '\0'; + + char newSeperator = FilterUtils.writeBefore(serializer, object, seperator); + commaFlag = newSeperator == ','; + for (int i = 0; i < getters.length; ++i) { FieldSerializer fieldSerializer = getters[i]; @@ -113,6 +155,10 @@ public void write(JSONSerializer serializer, Object object) throws IOException { } } + if (!FilterUtils.applyName(serializer, object, fieldSerializer.getName())) { + continue; + } + Object propertyValue = fieldSerializer.getPropertyValue(object); if (!FilterUtils.apply(serializer, object, fieldSerializer.getName(), propertyValue)) { @@ -124,37 +170,102 @@ public void write(JSONSerializer serializer, Object object) throws IOException { Object originalValue = propertyValue; propertyValue = FilterUtils.processValue(serializer, object, fieldSerializer.getName(), propertyValue); - if (propertyValue == null) { - if ((!fieldSerializer.isWriteNull()) && (!serializer.isEnabled(SerializerFeature.WriteMapNullValue))) { + if (propertyValue == null && !writeAsArray) { + if ((!fieldSerializer.isWriteNull()) + && (!serializer.isEnabled(SerializerFeature.WriteMapNullValue))) { + continue; + } + } + + if (propertyValue != null && serializer.isEnabled(SerializerFeature.NotWriteDefaultValue)) { + Class fieldCLass = fieldSerializer.fieldInfo.getFieldClass(); + if (fieldCLass == byte.class && propertyValue instanceof Byte + && ((Byte) propertyValue).byteValue() == 0) { + continue; + } else if (fieldCLass == short.class && propertyValue instanceof Short + && ((Short) propertyValue).shortValue() == 0) { + continue; + } else if (fieldCLass == int.class && propertyValue instanceof Integer + && ((Integer) propertyValue).intValue() == 0) { + continue; + } else if (fieldCLass == long.class && propertyValue instanceof Long + && ((Long) propertyValue).longValue() == 0L) { + continue; + } else if (fieldCLass == float.class && propertyValue instanceof Float + && ((Float) propertyValue).floatValue() == 0F) { + continue; + } else if (fieldCLass == double.class && propertyValue instanceof Double + && ((Double) propertyValue).doubleValue() == 0D) { + continue; + } else if (fieldCLass == boolean.class && propertyValue instanceof Boolean + && !((Boolean) propertyValue).booleanValue()) { continue; } } if (commaFlag) { out.append(','); + if (out.isEnabled(SerializerFeature.PrettyFormat)) { + serializer.println(); + } } if (key != fieldSerializer.getName()) { - out.writeFieldName(key); + if (!writeAsArray) { + out.writeFieldName(key); + } serializer.write(propertyValue); } else if (originalValue != propertyValue) { - fieldSerializer.writePrefix(serializer); + if (!writeAsArray) { + fieldSerializer.writePrefix(serializer); + } serializer.write(propertyValue); } else { - fieldSerializer.writeProperty(serializer, propertyValue); + if (!writeAsArray) { + fieldSerializer.writeProperty(serializer, propertyValue); + } else { + fieldSerializer.writeValue(serializer, propertyValue); + } } commaFlag = true; } - out.append('}'); + FilterUtils.writeAfter(serializer, object, commaFlag ? ',' : '\0'); + + if (getters.length > 0 && out.isEnabled(SerializerFeature.PrettyFormat)) { + serializer.decrementIdent(); + serializer.println(); + } + + out.append(endSeperator); } catch (Exception e) { throw new JSONException("write javaBean error", e); + } finally { + serializer.setContext(parent); + } + } + + public boolean writeReference(JSONSerializer serializer, Object object, int fieldFeatures) { + { + SerialContext context = serializer.getContext(); + if (context != null + && SerializerFeature.isEnabled(context.getFeatures(), fieldFeatures, + SerializerFeature.DisableCircularReferenceDetect)) { + return false; + } + } + + if (!serializer.containsReference(object)) { + return false; } + + serializer.writeReference(object); + return true; } public FieldSerializer createFieldSerializer(FieldInfo fieldInfo) { - Class clazz = fieldInfo.getMethod().getReturnType(); + Class clazz = fieldInfo.getFieldClass(); if (clazz == Number.class) { return new NumberFieldSerializer(fieldInfo); @@ -163,125 +274,49 @@ public FieldSerializer createFieldSerializer(FieldInfo fieldInfo) { return new ObjectFieldSerializer(fieldInfo); } - public static List computeGetters(Class clazz, Map aliasMap) { - List getters = new ArrayList(); - - for (Method method : clazz.getMethods()) { - String methodName = method.getName(); - - if (Modifier.isStatic(method.getModifiers())) { - continue; - } - - if (method.getReturnType().equals(Void.TYPE)) { - continue; - } - - if (method.getParameterTypes().length != 0) { - continue; - } - - JSONField annotation = method.getAnnotation(JSONField.class); - - if (annotation != null) { - if (!annotation.serialize()) { - continue; - } - - if (annotation.name().length() != 0) { - String propertyName = annotation.name(); - - if (aliasMap != null) { - propertyName = aliasMap.get(propertyName); - if (propertyName == null) { - continue; - } - } - - getters.add(new FieldInfo(propertyName, method, null)); - continue; - } - } - - if (methodName.startsWith("get")) { - if (methodName.length() < 4) { - continue; - } - - if (methodName.equals("getClass")) { - continue; - } - - if (!Character.isUpperCase(methodName.charAt(3))) { - continue; - } - - String propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4); - - Field field = ParserConfig.getField(clazz, propertyName); - if (field != null) { - JSONField fieldAnnotation = field.getAnnotation(JSONField.class); - - if (fieldAnnotation != null && fieldAnnotation.name().length() != 0) { - propertyName = fieldAnnotation.name(); - - if (aliasMap != null) { - propertyName = aliasMap.get(propertyName); - if (propertyName == null) { - continue; - } - } - } - } - - if (aliasMap != null) { - propertyName = aliasMap.get(propertyName); - if (propertyName == null) { - continue; - } - } - - getters.add(new FieldInfo(propertyName, method, field)); - } - - if (methodName.startsWith("is")) { - if (methodName.length() < 3) { - continue; - } - - if (!Character.isUpperCase(methodName.charAt(2))) { - continue; - } - - String propertyName = Character.toLowerCase(methodName.charAt(2)) + methodName.substring(3); - - Field field = ParserConfig.getField(clazz, propertyName); - if (field != null) { - JSONField fieldAnnotation = field.getAnnotation(JSONField.class); - - if (fieldAnnotation != null && fieldAnnotation.name().length() != 0) { - propertyName = fieldAnnotation.name(); - - if (aliasMap != null) { - propertyName = aliasMap.get(propertyName); - if (propertyName == null) { - continue; - } - } - } - } + public boolean isWriteAsArray(JSONSerializer serializer) { + if (SerializerFeature.isEnabled(features, SerializerFeature.BeanToArray)) { + return true; + } - if (aliasMap != null) { - propertyName = aliasMap.get(propertyName); - if (propertyName == null) { - continue; - } - } + boolean writeAsArray; + if (serializer.isEnabled(SerializerFeature.BeanToArray)) { + writeAsArray = true; + } else { + writeAsArray = false; + } - getters.add(new FieldInfo(propertyName, method, field)); + return writeAsArray; + } + + public Map getGetterMap() { + if (getterMap == null) { + HashMap map = new HashMap(getters.length); + for (FieldSerializer getter : sortedGetters) { + map.put(getter.getName(), getter); } + getterMap = map; } - - return getters; + return getterMap; + } + + public Object getFieldValue(Object object, String name) throws Exception { + Map map = getGetterMap(); + + FieldSerializer getter = map.get(name); + if (getter == null) { + return null; + } + + return getter.getPropertyValue(object); + } + + public List getFieldValues(Object object) throws Exception { + List fieldValues = new ArrayList(sortedGetters.length); + for (FieldSerializer getter : sortedGetters) { + fieldValues.add(getter.getPropertyValue(object)); + } + + return fieldValues; } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/ListSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/ListSerializer.java index 0191d61cf0..cc9cc0c506 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/ListSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ListSerializer.java @@ -16,18 +16,32 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.List; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public final class ListSerializer implements ObjectSerializer { public static final ListSerializer instance = new ListSerializer(); - public final void write(JSONSerializer serializer, Object object) throws IOException { + public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) + throws IOException { + + boolean writeClassName = serializer.isEnabled(SerializerFeature.WriteClassName); + SerializeWriter out = serializer.getWriter(); + Type elementType = null; + if (writeClassName) { + if (fieldType instanceof ParameterizedType) { + ParameterizedType param = (ParameterizedType) fieldType; + elementType = param.getActualTypeArguments()[0]; + } + } + if (object == null) { if (out.isEnabled(SerializerFeature.WriteNullListAsEmpty)) { out.write("[]"); @@ -39,50 +53,87 @@ public final void write(JSONSerializer serializer, Object object) throws IOExcep List list = (List) object; - final int size = list.size(); - int end = size - 1; - - if (end == -1) { + if (list.size() == 0) { out.append("[]"); return; } - out.append('['); - for (int i = 0; i < end; ++i) { - Object item = list.get(i); + SerialContext context = serializer.getContext(); + serializer.setContext(context, object, fieldName, 0); - if (item == null) { - out.append("null,"); - } else { - Class clazz = item.getClass(); + ObjectSerializer itemSerializer = null; + try { + if (out.isEnabled(SerializerFeature.PrettyFormat)) { + out.append('['); + serializer.incrementIndent(); - if (clazz == Integer.class) { - out.writeIntAndChar(((Integer) item).intValue(), ','); - } else if (clazz == Long.class) { - long val = ((Long) item).longValue(); - out.writeLongAndChar(val, ','); - } else { - serializer.write(item); - out.append(','); + int i = 0; + for (Object item : list) { + if (i != 0) { + out.append(','); + } + + serializer.println(); + if (item != null) { + if (serializer.containsReference(item)) { + serializer.writeReference(item); + } else { + itemSerializer = serializer.getObjectWriter(item.getClass()); + SerialContext itemContext = new SerialContext(context, object, fieldName, 0, 0); + serializer.setContext(itemContext); + itemSerializer.write(serializer, item, i, elementType, 0); + } + } else { + serializer.getWriter().writeNull(); + } + i++; } + + serializer.decrementIdent(); + serializer.println(); + out.append(']'); + return; } - } - Object item = list.get(end); + out.append('['); + int i = 0; + for (Object item : list) { + if (i != 0) { + out.append(','); + } + + if (item == null) { + out.append("null"); + } else { + Class clazz = item.getClass(); - if (item == null) { - out.append("null]"); - } else { - Class clazz = item.getClass(); + if (clazz == Integer.class) { + out.writeInt(((Integer) item).intValue()); + } else if (clazz == Long.class) { + long val = ((Long) item).longValue(); + if (writeClassName) { + out.writeLongAndChar(val, 'L'); + } else { + out.writeLong(val); + } + } else { + SerialContext itemContext = new SerialContext(context, object, fieldName, 0, 0); + serializer.setContext(itemContext); - if (clazz == Integer.class) { - out.writeIntAndChar(((Integer) item).intValue(), ']'); - } else if (clazz == Long.class) { - out.writeLongAndChar(((Long) item).longValue(), ']'); - } else { - serializer.write(item); - out.append(']'); + if (serializer.containsReference(item)) { + serializer.writeReference(item); + } else { + itemSerializer = serializer.getObjectWriter(item.getClass()); + itemSerializer.write(serializer, item, i, elementType, 0); + } + } + } + i++; } + out.append(']'); + } finally { + serializer.setContext(context); } } + } diff --git a/src/main/java/com/alibaba/fastjson/serializer/LocaleCodec.java b/src/main/java/com/alibaba/fastjson/serializer/LocaleCodec.java new file mode 100755 index 0000000000..cfb8f95081 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/LocaleCodec.java @@ -0,0 +1,50 @@ +package com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.Locale; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +public class LocaleCodec implements ObjectSerializer, ObjectDeserializer { + + public final static LocaleCodec instance = new LocaleCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + if (object == null) { + serializer.writeNull(); + return; + } + + Locale locale = (Locale) object; + serializer.write(locale.toString()); + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + String text = (String) parser.parse(); + + if (text == null) { + return null; + } + + String[] items = text.split("_"); + + if (items.length == 1) { + return (T) new Locale(items[0]); + } + + if (items.length == 2) { + return (T) new Locale(items[0], items[1]); + } + + return (T) new Locale(items[0], items[1], items[2]); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } + +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/LocaleSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/LocaleSerializer.java deleted file mode 100644 index 0bcbd86da6..0000000000 --- a/src/main/java/com/alibaba/fastjson/serializer/LocaleSerializer.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.alibaba.fastjson.serializer; - -import java.io.IOException; -import java.util.Locale; - -public class LocaleSerializer implements ObjectSerializer { - - public final static LocaleSerializer instance = new LocaleSerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - if (object == null) { - serializer.writeNull(); - return; - } - - Locale locale = (Locale) object; - serializer.write(locale.toString()); - } - -} diff --git a/src/main/java/com/alibaba/fastjson/serializer/LongArraySerializer.java b/src/main/java/com/alibaba/fastjson/serializer/LongArraySerializer.java old mode 100644 new mode 100755 index c47b6ea90c..f0e045d94f --- a/src/main/java/com/alibaba/fastjson/serializer/LongArraySerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/LongArraySerializer.java @@ -16,15 +16,16 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class LongArraySerializer implements ObjectSerializer { public static LongArraySerializer instance = new LongArraySerializer(); - public final void write(JSONSerializer serializer, Object object) throws IOException { + public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); if (object == null) { @@ -38,7 +39,14 @@ public final void write(JSONSerializer serializer, Object object) throws IOExcep long[] array = (long[]) object; - out.writeLongArray(array); + out.write('['); + for (int i = 0; i < array.length; ++i) { + if (i != 0) { + out.write(','); + } + out.writeLong(array[i]); + } + out.write(']'); } diff --git a/src/main/java/com/alibaba/fastjson/serializer/LongCodec.java b/src/main/java/com/alibaba/fastjson/serializer/LongCodec.java new file mode 100755 index 0000000000..b464797d25 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/LongCodec.java @@ -0,0 +1,89 @@ +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.concurrent.atomic.AtomicLong; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.util.TypeUtils; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public class LongCodec implements ObjectSerializer, ObjectDeserializer { + + public static LongCodec instance = new LongCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + SerializeWriter out = serializer.getWriter(); + + if (object == null) { + if (out.isEnabled(SerializerFeature.WriteNullNumberAsZero)) { + out.write('0'); + } else { + out.writeNull(); + } + return; + } + + long value = ((Long) object).longValue(); + out.writeLong(value); + + if (serializer.isEnabled(SerializerFeature.WriteClassName)) { + if (value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE) { + if (fieldType != Long.class) { + out.write('L'); + } + } + } + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + final JSONLexer lexer = parser.getLexer(); + + Long longObject; + if (lexer.token() == JSONToken.LITERAL_INT) { + long longValue = lexer.longValue(); + lexer.nextToken(JSONToken.COMMA); + longObject = Long.valueOf(longValue); + } else { + + Object value = parser.parse(); + + if (value == null) { + return null; + } + + longObject = TypeUtils.castToLong(value); + } + + if (clazz == AtomicLong.class) { + return (T) new AtomicLong(longObject.longValue()); + } + + return (T) longObject; + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_INT; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/LongSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/LongSerializer.java deleted file mode 100644 index ff56dab957..0000000000 --- a/src/main/java/com/alibaba/fastjson/serializer/LongSerializer.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.serializer; - -import java.io.IOException; - -/** - * @author wenshao - */ -public class LongSerializer implements ObjectSerializer { - - public static LongSerializer instance = new LongSerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - SerializeWriter out = serializer.getWriter(); - - if (object == null) { - if (out.isEnabled(SerializerFeature.WriteNullNumberAsZero)) { - out.write('0'); - } else { - out.writeNull(); - } - return; - } - - Long value = (Long) object; - out.writeLong(value.longValue()); - } -} diff --git a/src/main/java/com/alibaba/fastjson/serializer/MapSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/MapSerializer.java old mode 100644 new mode 100755 index b0eb97c31f..e2b7b55558 --- a/src/main/java/com/alibaba/fastjson/serializer/MapSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/MapSerializer.java @@ -1,117 +1,201 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.serializer; - -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -/** - * @author wenshao - */ -public class MapSerializer implements ObjectSerializer { - - public static MapSerializer instance = new MapSerializer(); - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void write(JSONSerializer serializer, Object object) throws IOException { - SerializeWriter out = serializer.getWriter(); - - if (object == null) { - out.writeNull(); - return; - } - - Map map = (Map) object; - - if (out.isEnabled(SerializerFeature.SortField)) { - map = new TreeMap(map); - } - - out.write('{'); - - Class preClazz = null; - ObjectSerializer preWriter = null; - - boolean first = true; - for (Map.Entry entry : map.entrySet()) { - Object value = entry.getValue(); - - Object entryKey = entry.getKey(); - String key = entryKey == null ? "null" : entryKey.toString(); - - List propertyFilters = serializer.getPropertyFiltersDirect(); - if (propertyFilters != null) { - boolean apply = true; - for (PropertyFilter propertyFilter : propertyFilters) { - if (!propertyFilter.apply(object, key, value)) { - apply = false; - break; - } - } - - if (!apply) { - continue; - } - } - - List nameFilters = serializer.getNameFiltersDirect(); - if (nameFilters != null) { - for (NameFilter nameFilter : nameFilters) { - key = nameFilter.process(object, key, value); - } - } - - List valueFilters = serializer.getValueFiltersDirect(); - if (valueFilters != null) { - for (ValueFilter valueFilter : valueFilters) { - value = valueFilter.process(object, key, value); - } - } - - if (value == null) { - if (!serializer.isEnabled(SerializerFeature.WriteMapNullValue)) { - continue; - } - } - - if (!first) { - out.write(','); - } - - out.writeFieldName(key); - first = false; - - if (value == null) { - out.writeNull(); - continue; - } - - Class clazz = value.getClass(); - - if (clazz == preClazz) { - preWriter.write(serializer, value); - } else { - preClazz = clazz; - preWriter = serializer.getObjectWriter(clazz); - - preWriter.write(serializer, value); - } - } - out.write('}'); - } -} +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; + +import com.alibaba.fastjson.JSON; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public class MapSerializer implements ObjectSerializer { + + public static MapSerializer instance = new MapSerializer(); + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + SerializeWriter out = serializer.getWriter(); + + if (object == null) { + out.writeNull(); + return; + } + + Map map = (Map) object; + +// if (out.isEnabled(SerializerFeature.SortField)) { +// if ((!(map instanceof SortedMap)) && !(map instanceof LinkedHashMap)) { +// try { +// map = new TreeMap(map); +// } catch (Exception ex) { +// // skip +// } +// } +// } + + if (serializer.containsReference(object)) { + serializer.writeReference(object); + return; + } + + SerialContext parent = serializer.getContext(); + serializer.setContext(parent, object, fieldName, 0); + try { + out.write('{'); + + serializer.incrementIndent(); + + Class preClazz = null; + ObjectSerializer preWriter = null; + + boolean first = true; + + if (out.isEnabled(SerializerFeature.WriteClassName)) { + out.writeFieldName(JSON.DEFAULT_TYPE_KEY); + out.writeString(object.getClass().getName()); + first = false; + } + + for (Map.Entry entry : map.entrySet()) { + Object value = entry.getValue(); + + Object entryKey = entry.getKey(); + + { + List preFilters = serializer.getPropertyPreFiltersDirect(); + if (preFilters != null && preFilters.size() > 0) { + if (entryKey == null || entryKey instanceof String) { + if (!FilterUtils.applyName(serializer, object, (String) entryKey)) { + continue; + } + } else if (entryKey.getClass().isPrimitive() || entryKey instanceof Number) { + String strKey = JSON.toJSONString(entryKey); + if (!FilterUtils.applyName(serializer, object, strKey)) { + continue; + } + } + } + } + + { + List propertyFilters = serializer.getPropertyFiltersDirect(); + if (propertyFilters != null && propertyFilters.size() > 0) { + if (entryKey == null || entryKey instanceof String) { + if (!FilterUtils.apply(serializer, object, (String) entryKey, value)) { + continue; + } + } else if (entryKey.getClass().isPrimitive() || entryKey instanceof Number) { + String strKey = JSON.toJSONString(entryKey); + if (!FilterUtils.apply(serializer, object, strKey, value)) { + continue; + } + } + } + } + + { + List nameFilters = serializer.getNameFiltersDirect(); + if (nameFilters != null && nameFilters.size() > 0) { + if (entryKey == null || entryKey instanceof String) { + entryKey = FilterUtils.processKey(serializer, object, (String) entryKey, value); + } else if (entryKey.getClass().isPrimitive() || entryKey instanceof Number) { + String strKey = JSON.toJSONString(entryKey); + entryKey = FilterUtils.processKey(serializer, object, strKey, value); + } + } + } + + { + List valueFilters = serializer.getValueFiltersDirect(); + if (valueFilters != null && valueFilters.size() > 0) { + if (entryKey == null || entryKey instanceof String) { + value = FilterUtils.processValue(serializer, object, (String) entryKey, value); + } else if (entryKey.getClass().isPrimitive() || entryKey instanceof Number) { + String strKey = JSON.toJSONString(entryKey); + value = FilterUtils.processValue(serializer, object, strKey, value); + } + } + } + + if (value == null) { + if (!serializer.isEnabled(SerializerFeature.WriteMapNullValue)) { + continue; + } + } + + if (entryKey instanceof String) { + String key = (String) entryKey; + + if (!first) { + out.write(','); + } + + if (out.isEnabled(SerializerFeature.PrettyFormat)) { + serializer.println(); + } + out.writeFieldName(key, true); + } else { + if (!first) { + out.write(','); + } + + if (out.isEnabled(SerializerFeature.BrowserCompatible) + || out.isEnabled(SerializerFeature.WriteNonStringKeyAsString)) { + String strEntryKey = JSON.toJSONString(entryKey); + serializer.write(strEntryKey); + } else { + serializer.write(entryKey); + } + + out.write(':'); + } + + first = false; + + if (value == null) { + out.writeNull(); + continue; + } + + Class clazz = value.getClass(); + + if (clazz == preClazz) { + preWriter.write(serializer, value, entryKey, null, 0); + } else { + preClazz = clazz; + preWriter = serializer.getObjectWriter(clazz); + + preWriter.write(serializer, value, entryKey, null, 0); + } + } + } finally { + serializer.setContext(parent); + } + + serializer.decrementIdent(); + if (out.isEnabled(SerializerFeature.PrettyFormat) && map.size() > 0) { + serializer.println(); + } + out.write('}'); + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/NameFilter.java b/src/main/java/com/alibaba/fastjson/serializer/NameFilter.java old mode 100644 new mode 100755 index 810b876716..93e677c18e --- a/src/main/java/com/alibaba/fastjson/serializer/NameFilter.java +++ b/src/main/java/com/alibaba/fastjson/serializer/NameFilter.java @@ -1,6 +1,20 @@ +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; -public interface NameFilter { - - String process(Object source, String name, Object value); +public interface NameFilter extends SerializeFilter { + String process(Object object, String name, Object value); } diff --git a/src/main/java/com/alibaba/fastjson/serializer/NumberFieldSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/NumberFieldSerializer.java old mode 100644 new mode 100755 index 7abc97db9d..205a00bc31 --- a/src/main/java/com/alibaba/fastjson/serializer/NumberFieldSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/NumberFieldSerializer.java @@ -17,21 +17,23 @@ import com.alibaba.fastjson.util.FieldInfo; - /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ -class NumberFieldSerializer extends FieldSerializer { +final class NumberFieldSerializer extends FieldSerializer { public NumberFieldSerializer(FieldInfo fieldInfo){ super(fieldInfo); } - @Override public void writeProperty(JSONSerializer serializer, Object propertyValue) throws Exception { - SerializeWriter out = serializer.getWriter(); - writePrefix(serializer); + this.writeValue(serializer, propertyValue); + } + + @Override + public void writeValue(JSONSerializer serializer, Object propertyValue) throws Exception { + SerializeWriter out = serializer.getWriter(); Object value = propertyValue; @@ -43,7 +45,7 @@ public void writeProperty(JSONSerializer serializer, Object propertyValue) throw } return; } - + out.append(value.toString()); } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/ObjectArraySerializer.java b/src/main/java/com/alibaba/fastjson/serializer/ObjectArraySerializer.java old mode 100644 new mode 100755 index 20ef7e4942..86b0c425e6 --- a/src/main/java/com/alibaba/fastjson/serializer/ObjectArraySerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ObjectArraySerializer.java @@ -16,9 +16,10 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class ObjectArraySerializer implements ObjectSerializer { @@ -27,11 +28,12 @@ public class ObjectArraySerializer implements ObjectSerializer { public ObjectArraySerializer(){ } - public final void write(JSONSerializer serializer, Object object) throws IOException { + public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) + throws IOException { SerializeWriter out = serializer.getWriter(); Object[] array = (Object[]) object; - + if (object == null) { if (out.isEnabled(SerializerFeature.WriteNullListAsEmpty)) { out.write("[]"); @@ -40,7 +42,7 @@ public final void write(JSONSerializer serializer, Object object) throws IOExcep } return; } - + int size = array.length; int end = size - 1; @@ -50,54 +52,68 @@ public final void write(JSONSerializer serializer, Object object) throws IOExcep return; } - Class preClazz = null; - ObjectSerializer preWriter = null; - out.append('['); - - if (out.isEnabled(SerializerFeature.PrettyFormat)) { - serializer.incrementIndent(); - serializer.println(); - for (int i = 0; i < size; ++i) { - if (i != 0) { - out.write(','); - serializer.println(); + SerialContext context = serializer.getContext(); + serializer.setContext(context, object, fieldName, 0); + + try { + Class preClazz = null; + ObjectSerializer preWriter = null; + out.append('['); + + if (out.isEnabled(SerializerFeature.PrettyFormat)) { + serializer.incrementIndent(); + serializer.println(); + for (int i = 0; i < size; ++i) { + if (i != 0) { + out.write(','); + serializer.println(); + } + serializer.write(array[i]); } - serializer.write(array[i]); + serializer.decrementIdent(); + serializer.println(); + out.write(']'); + return; } - serializer.decrementIdent(); - serializer.println(); - out.write(']'); - return; - } - - for (int i = 0; i < end; ++i) { - Object item = array[i]; - if (item == null) { - out.append("null,"); - } else { - Class clazz = item.getClass(); + for (int i = 0; i < end; ++i) { + Object item = array[i]; - if (clazz == preClazz) { - preWriter.write(serializer, item); + if (item == null) { + out.append("null,"); } else { - preClazz = clazz; - preWriter = serializer.getObjectWriter(clazz); + if (serializer.containsReference(item)) { + serializer.writeReference(item); + } else { + Class clazz = item.getClass(); - preWriter.write(serializer, item); - } + if (clazz == preClazz) { + preWriter.write(serializer, item, null, null, 0); + } else { + preClazz = clazz; + preWriter = serializer.getObjectWriter(clazz); - out.append(','); + preWriter.write(serializer, item, null, null, 0); + } + } + out.append(','); + } } - } - Object item = array[end]; + Object item = array[end]; - if (item == null) { - out.append("null]"); - } else { - serializer.write(item); - out.append(']'); + if (item == null) { + out.append("null]"); + } else { + if (serializer.containsReference(item)) { + serializer.writeReference(item); + } else { + serializer.writeWithFieldName(item, end); + } + out.append(']'); + } + } finally { + serializer.setContext(context); } } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/ObjectFieldSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/ObjectFieldSerializer.java old mode 100644 new mode 100755 index 5609d4364b..1d0708b829 --- a/src/main/java/com/alibaba/fastjson/serializer/ObjectFieldSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ObjectFieldSerializer.java @@ -15,63 +15,129 @@ */ package com.alibaba.fastjson.serializer; +import java.util.Collection; + import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.util.FieldInfo; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class ObjectFieldSerializer extends FieldSerializer { - private ObjectSerializer fieldSerializer; - private Class runtimeFieldClass; - private String format; + private String format; + boolean writeNumberAsZero = false; + boolean writeNullStringAsEmpty = false; + boolean writeNullBooleanAsFalse = false; + boolean writeNullListAsEmpty = false; + boolean writeEnumUsingToString = false; + + private RuntimeSerializerInfo runtimeInfo; + + public ObjectFieldSerializer(FieldInfo fieldInfo){ + super(fieldInfo); + + JSONField annotation = fieldInfo.getAnnotation(JSONField.class); + + if (annotation != null) { + format = annotation.format(); + + if (format.trim().length() == 0) { + format = null; + } + + for (SerializerFeature feature : annotation.serialzeFeatures()) { + if (feature == SerializerFeature.WriteNullNumberAsZero) { + writeNumberAsZero = true; + } else if (feature == SerializerFeature.WriteNullStringAsEmpty) { + writeNullStringAsEmpty = true; + } else if (feature == SerializerFeature.WriteNullBooleanAsFalse) { + writeNullBooleanAsFalse = true; + } else if (feature == SerializerFeature.WriteNullListAsEmpty) { + writeNullListAsEmpty = true; + } else if (feature == SerializerFeature.WriteEnumUsingToString) { + writeEnumUsingToString = true; + } + } + } + } + + public void writeProperty(JSONSerializer serializer, Object propertyValue) throws Exception { + writePrefix(serializer); + writeValue(serializer, propertyValue); + } + + @Override + public void writeValue(JSONSerializer serializer, Object propertyValue) throws Exception { + if (format != null) { + serializer.writeWithFormat(propertyValue, format); + return; + } + + if (runtimeInfo == null) { - public ObjectFieldSerializer(FieldInfo fieldInfo) { - super(fieldInfo); + Class runtimeFieldClass; + if (propertyValue == null) { + runtimeFieldClass = this.fieldInfo.getFieldClass(); + } else { + runtimeFieldClass = propertyValue.getClass(); + } - JSONField annotation = fieldInfo.getAnnotation(JSONField.class); + ObjectSerializer fieldSerializer = serializer.getObjectWriter(runtimeFieldClass); + runtimeInfo = new RuntimeSerializerInfo(fieldSerializer, runtimeFieldClass); + } + + final RuntimeSerializerInfo runtimeInfo = this.runtimeInfo; + + final int fieldFeatures = fieldInfo.getSerialzeFeatures(); - if (annotation != null) { - format = annotation.format(); + if (propertyValue == null) { + if (writeNumberAsZero && Number.class.isAssignableFrom(runtimeInfo.runtimeFieldClass)) { + serializer.getWriter().write('0'); + return; + } else if (writeNullStringAsEmpty && String.class == runtimeInfo.runtimeFieldClass) { + serializer.getWriter().write("\"\""); + return; + } else if (writeNullBooleanAsFalse && Boolean.class == runtimeInfo.runtimeFieldClass) { + serializer.getWriter().write("false"); + return; + } else if (writeNullListAsEmpty && Collection.class.isAssignableFrom(runtimeInfo.runtimeFieldClass)) { + serializer.getWriter().write("[]"); + return; + } - if (format.trim().length() == 0) { - format = null; - } - } - } + runtimeInfo.fieldSerializer.write(serializer, null, fieldInfo.getName(), null, fieldFeatures); + return; + } - @Override - public void writeProperty(JSONSerializer serializer, Object propertyValue) - throws Exception { - writePrefix(serializer); + if (writeEnumUsingToString == true && runtimeInfo.runtimeFieldClass.isEnum()) { + serializer.getWriter().writeString(((Enum) propertyValue).name()); + return; + } - if (format != null) { - serializer.writeWithFormat(propertyValue, format); - return; - } + Class valueClass = propertyValue.getClass(); + if (valueClass == runtimeInfo.runtimeFieldClass) { + runtimeInfo.fieldSerializer.write(serializer, propertyValue, fieldInfo.getName(), fieldInfo.getFieldType(), fieldFeatures); + return; + } - if (fieldSerializer == null) { + ObjectSerializer valueSerializer = serializer.getObjectWriter(valueClass); + valueSerializer.write(serializer, propertyValue, fieldInfo.getName(), fieldInfo.getFieldType(), fieldFeatures); + } - if (propertyValue == null) { - runtimeFieldClass = this.getMethod().getReturnType(); - } else { - runtimeFieldClass = propertyValue.getClass(); - } + static class RuntimeSerializerInfo { - fieldSerializer = serializer.getObjectWriter(runtimeFieldClass); - } + ObjectSerializer fieldSerializer; - if (propertyValue == null) { - fieldSerializer.write(serializer, null); - return; - } + Class runtimeFieldClass; - if (propertyValue.getClass() == runtimeFieldClass) { - fieldSerializer.write(serializer, propertyValue); - return; - } + public RuntimeSerializerInfo(ObjectSerializer fieldSerializer, Class runtimeFieldClass){ + super(); + this.fieldSerializer = fieldSerializer; + this.runtimeFieldClass = runtimeFieldClass; + } + + - serializer.write(propertyValue); - } + } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/ObjectNameSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/ObjectNameSerializer.java deleted file mode 100644 index f85da2fa6d..0000000000 --- a/src/main/java/com/alibaba/fastjson/serializer/ObjectNameSerializer.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.alibaba.fastjson.serializer; - -import java.io.IOException; - -import javax.management.ObjectName; - -public class ObjectNameSerializer implements ObjectSerializer { - - public final static ObjectNameSerializer instance = new ObjectNameSerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - serializer.write(((ObjectName) object).toString()); - } - -} diff --git a/src/main/java/com/alibaba/fastjson/serializer/ObjectSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/ObjectSerializer.java old mode 100644 new mode 100755 index 717051bee9..f89d3b39ae --- a/src/main/java/com/alibaba/fastjson/serializer/ObjectSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ObjectSerializer.java @@ -16,11 +16,12 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public interface ObjectSerializer { - abstract void write(JSONSerializer serializer, Object object) throws IOException; + void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException; } diff --git a/src/main/java/com/alibaba/fastjson/serializer/PascalNameFilter.java b/src/main/java/com/alibaba/fastjson/serializer/PascalNameFilter.java new file mode 100755 index 0000000000..624f368bab --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/PascalNameFilter.java @@ -0,0 +1,16 @@ +package com.alibaba.fastjson.serializer; + +public class PascalNameFilter implements NameFilter { + + public String process(Object source, String name, Object value) { + if (name == null || name.length() == 0) { + return name; + } + + char[] chars = name.toCharArray(); + chars[0]= Character.toUpperCase(chars[0]); + + String pascalName = new String(chars); + return pascalName; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/PatternCodec.java b/src/main/java/com/alibaba/fastjson/serializer/PatternCodec.java new file mode 100755 index 0000000000..82189a43eb --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/PatternCodec.java @@ -0,0 +1,59 @@ +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.regex.Pattern; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public class PatternCodec implements ObjectSerializer, ObjectDeserializer { + + public final static PatternCodec instance = new PatternCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + if (object == null) { + serializer.writeNull(); + return; + } + + Pattern p = (Pattern) object; + serializer.write(p.pattern()); + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + Object value = parser.parse(); + + if (value == null) { + return null; + } + + String pattern = (String) value; + + return (T) Pattern.compile(pattern); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/PointCodec.java b/src/main/java/com/alibaba/fastjson/serializer/PointCodec.java new file mode 100755 index 0000000000..c9881408ec --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/PointCodec.java @@ -0,0 +1,102 @@ +package com.alibaba.fastjson.serializer; + +import java.awt.Point; +import java.io.IOException; +import java.lang.reflect.Type; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +public class PointCodec implements ObjectSerializer, ObjectDeserializer { + + public final static PointCodec instance = new PointCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + SerializeWriter out = serializer.getWriter(); + Point font = (Point) object; + if (font == null) { + out.writeNull(); + return; + } + + char sep = '{'; + if (out.isEnabled(SerializerFeature.WriteClassName)) { + out.write('{'); + out.writeFieldName(JSON.DEFAULT_TYPE_KEY); + out.writeString(Point.class.getName()); + sep = ','; + } + + out.writeFieldValue(sep, "x", font.getX()); + out.writeFieldValue(',', "y", font.getY()); + out.write('}'); + + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + JSONLexer lexer = parser.getLexer(); + + if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(JSONToken.COMMA); + return null; + } + + if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) { + throw new JSONException("syntax error"); + } + lexer.nextToken(); + + int x = 0, y = 0; + for (;;) { + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(); + break; + } + + String key; + if (lexer.token() == JSONToken.LITERAL_STRING) { + key = lexer.stringVal(); + + if (JSON.DEFAULT_TYPE_KEY.equals(key)) { + parser.acceptType("java.awt.Point"); + continue; + } + + lexer.nextTokenWithColon(JSONToken.LITERAL_INT); + } else { + throw new JSONException("syntax error"); + } + + int val; + if (lexer.token() == JSONToken.LITERAL_INT) { + val = lexer.intValue(); + lexer.nextToken(); + } else { + throw new JSONException("syntax error : " + lexer.tokenName()); + } + + if (key.equalsIgnoreCase("x")) { + x = val; + } else if (key.equalsIgnoreCase("y")) { + y = val; + } else { + throw new JSONException("syntax error, " + key); + } + + if (lexer.token() == JSONToken.COMMA) { + lexer.nextToken(JSONToken.LITERAL_STRING); + } + } + + return (T) new Point(x, y); + } + + public int getFastMatchToken() { + return JSONToken.LBRACE; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/PropertyFilter.java b/src/main/java/com/alibaba/fastjson/serializer/PropertyFilter.java old mode 100644 new mode 100755 index 3298c5a216..33efe56151 --- a/src/main/java/com/alibaba/fastjson/serializer/PropertyFilter.java +++ b/src/main/java/com/alibaba/fastjson/serializer/PropertyFilter.java @@ -1,30 +1,30 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.serializer; - -/** - * @author wenshao - */ -public interface PropertyFilter { - - /** - * @param source the owner of the property - * @param name the name of the property - * @param value the value of the property - * @return true if the property will be filtered out, false otherwise - */ - boolean apply(Object source, String name, Object value); -} +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public interface PropertyFilter extends SerializeFilter { + + /** + * @param object the owner of the property + * @param name the name of the property + * @param value the value of the property + * @return true if the property will be filtered out, false otherwise + */ + boolean apply(Object object, String name, Object value); +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/AtomicReferenceSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/PropertyPreFilter.java old mode 100644 new mode 100755 similarity index 54% rename from src/main/java/com/alibaba/fastjson/serializer/AtomicReferenceSerializer.java rename to src/main/java/com/alibaba/fastjson/serializer/PropertyPreFilter.java index 1af821bc36..35ef42918a --- a/src/main/java/com/alibaba/fastjson/serializer/AtomicReferenceSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/PropertyPreFilter.java @@ -1,34 +1,21 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.serializer; - -import java.io.IOException; -import java.util.concurrent.atomic.AtomicReference; - -/** - * @author wenshao - */ -public class AtomicReferenceSerializer implements ObjectSerializer { - - public final static AtomicReferenceSerializer instance = new AtomicReferenceSerializer(); - - @SuppressWarnings("rawtypes") - public void write(JSONSerializer serializer, Object object) throws IOException { - AtomicReference val = (AtomicReference) object; - serializer.write(val.get()); - } - -} +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +public interface PropertyPreFilter extends SerializeFilter { + + boolean apply(JSONSerializer serializer, Object object, String name); +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/RectangleCodec.java b/src/main/java/com/alibaba/fastjson/serializer/RectangleCodec.java new file mode 100755 index 0000000000..97d84066d7 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/RectangleCodec.java @@ -0,0 +1,102 @@ +package com.alibaba.fastjson.serializer; + +import java.awt.Rectangle; +import java.io.IOException; +import java.lang.reflect.Type; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +public class RectangleCodec implements ObjectSerializer, ObjectDeserializer { + + public final static RectangleCodec instance = new RectangleCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + SerializeWriter out = serializer.getWriter(); + Rectangle rectangle = (Rectangle) object; + if (rectangle == null) { + out.writeNull(); + return; + } + + char sep = '{'; + if (out.isEnabled(SerializerFeature.WriteClassName)) { + out.write('{'); + out.writeFieldName(JSON.DEFAULT_TYPE_KEY); + out.writeString(Rectangle.class.getName()); + sep = ','; + } + + out.writeFieldValue(sep, "x", rectangle.getX()); + out.writeFieldValue(',', "y", rectangle.getY()); + out.writeFieldValue(',', "width", rectangle.getWidth()); + out.writeFieldValue(',', "height", rectangle.getHeight()); + out.write('}'); + + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + JSONLexer lexer = parser.getLexer(); + + if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(); + return null; + } + + if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) { + throw new JSONException("syntax error"); + } + lexer.nextToken(); + + int x = 0, y = 0, width = 0, height = 0; + for (;;) { + if (lexer.token() == JSONToken.RBRACE) { + lexer.nextToken(); + break; + } + + String key; + if (lexer.token() == JSONToken.LITERAL_STRING) { + key = lexer.stringVal(); + lexer.nextTokenWithColon(JSONToken.LITERAL_INT); + } else { + throw new JSONException("syntax error"); + } + + int val; + if (lexer.token() == JSONToken.LITERAL_INT) { + val = lexer.intValue(); + lexer.nextToken(); + } else { + throw new JSONException("syntax error"); + } + + if (key.equalsIgnoreCase("x")) { + x = val; + } else if (key.equalsIgnoreCase("y")) { + y = val; + } else if (key.equalsIgnoreCase("width")) { + width = val; + } else if (key.equalsIgnoreCase("height")) { + height = val; + } else { + throw new JSONException("syntax error, " + key); + } + + if (lexer.token() == JSONToken.COMMA) { + lexer.nextToken(JSONToken.LITERAL_STRING); + } + } + + return (T) new Rectangle(x, y, width, height); + } + + public int getFastMatchToken() { + return JSONToken.LBRACE; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/ReferenceCodec.java b/src/main/java/com/alibaba/fastjson/serializer/ReferenceCodec.java new file mode 100644 index 0000000000..1ac2faaa6a --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/ReferenceCodec.java @@ -0,0 +1,75 @@ +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.ref.Reference; +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.concurrent.atomic.AtomicReference; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public class ReferenceCodec implements ObjectSerializer, ObjectDeserializer { + + public final static ReferenceCodec instance = new ReferenceCodec(); + + @SuppressWarnings("rawtypes") + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + Object item; + if (object instanceof AtomicReference) { + AtomicReference val = (AtomicReference) object; + item = val.get(); + } else { + item = ((Reference) object).get(); + } + serializer.write(item); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + ParameterizedType paramType = (ParameterizedType) type; + Type itemType = paramType.getActualTypeArguments()[0]; + + Object itemObject = parser.parseObject(itemType); + + Type rawType = paramType.getRawType(); + if (rawType == AtomicReference.class) { + return (T) new AtomicReference(itemObject); + } + + if (rawType == WeakReference.class) { + return (T) new WeakReference(itemObject); + } + + if (rawType == SoftReference.class) { + return (T) new SoftReference(itemObject); + } + + throw new UnsupportedOperationException(rawType.toString()); + } + + public int getFastMatchToken() { + return JSONToken.LBRACE; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerialContext.java b/src/main/java/com/alibaba/fastjson/serializer/SerialContext.java new file mode 100755 index 0000000000..4c6f8d61c7 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/SerialContext.java @@ -0,0 +1,59 @@ +package com.alibaba.fastjson.serializer; + +public class SerialContext { + + private final SerialContext parent; + + private final Object object; + + private final Object fieldName; + + private int features; + + private int fieldFeatures; + + public SerialContext(SerialContext parent, Object object, Object fieldName, int features, int fieldFeatures){ + this.parent = parent; + this.object = object; + this.fieldName = fieldName; + this.features = features; + this.fieldFeatures = fieldFeatures; + } + + public SerialContext getParent() { + return parent; + } + + public Object getObject() { + return object; + } + + public Object getFieldName() { + return fieldName; + } + + public String getPath() { + if (parent == null) { + return "$"; + } else { + if (fieldName instanceof Integer) { + return parent.getPath() + "[" + fieldName + "]"; + } else { + return parent.getPath() + "." + fieldName; + } + + } + } + + public String toString() { + return getPath(); + } + + public int getFeatures() { + return features; + } + + public boolean isEnabled(SerializerFeature feature) { + return SerializerFeature.isEnabled(features, fieldFeatures, feature); + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerialWriterStringEncoder.java b/src/main/java/com/alibaba/fastjson/serializer/SerialWriterStringEncoder.java old mode 100644 new mode 100755 diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerializeConfig.java b/src/main/java/com/alibaba/fastjson/serializer/SerializeConfig.java old mode 100644 new mode 100755 index 024fded50d..d85d30f903 --- a/src/main/java/com/alibaba/fastjson/serializer/SerializeConfig.java +++ b/src/main/java/com/alibaba/fastjson/serializer/SerializeConfig.java @@ -1,148 +1,354 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.serializer; - -import java.io.File; -import java.lang.reflect.Modifier; -import java.lang.reflect.Type; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.URI; -import java.net.URL; -import java.nio.charset.Charset; -import java.util.Locale; -import java.util.TimeZone; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicIntegerArray; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicLongArray; -import java.util.concurrent.atomic.AtomicReference; -import java.util.regex.Pattern; - -import javax.management.ObjectName; - -import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.util.IdentityHashMap; - -/** - * circular references detect - * - * @author wenshao - */ -public class SerializeConfig extends IdentityHashMap { - - private final static SerializeConfig globalInstance = new SerializeConfig(); - - private boolean asm = true; - - private final ASMSerializerFactory asmFactory = new ASMSerializerFactory(); - - public final ObjectSerializer createASMSerializer(Class clazz) throws Exception { - return asmFactory.createJavaBeanSerializer(clazz); - } - - public ObjectSerializer createJavaBeanSerializer(Class clazz) { - if (!Modifier.isPublic(clazz.getModifiers())) { - return new JavaBeanSerializer(clazz); - } - - if (asm) { - try { - return createASMSerializer(clazz); - } catch (Throwable e) { - throw new JSONException("create asm serilizer error, class " + clazz, e); - } - } - - return new JavaBeanSerializer(clazz); - } - - public boolean isAsmEnable() { - return asm; - } - - public void setAsmEnable(boolean asmEnable) { - this.asm = asmEnable; - } - - public final static SerializeConfig getGlobalInstance() { - return globalInstance; - } - - public SerializeConfig(){ - this(DEFAULT_TABLE_SIZE); - } - - public SerializeConfig(int tableSize){ - super(tableSize); - - put(Boolean.class, BooleanSerializer.instance); - put(Character.class, CharacterSerializer.instance); - put(Byte.class, IntegerSerializer.instance); - put(Short.class, IntegerSerializer.instance); - put(Integer.class, IntegerSerializer.instance); - put(Long.class, LongSerializer.instance); - put(Float.class, FloatSerializer.instance); - put(Double.class, DoubleSerializer.instance); - put(BigDecimal.class, BigDecimalSerializer.instance); - put(BigInteger.class, BigIntegerSerializer.instance); - put(String.class, StringSerializer.instance); - put(byte[].class, ByteArraySerializer.instance); - put(short[].class, ShortArraySerializer.instance); - put(int[].class, IntArraySerializer.instance); - put(long[].class, LongArraySerializer.instance); - put(float[].class, FloatArraySerializer.instance); - put(double[].class, DoubleArraySerializer.instance); - put(boolean[].class, BooleanArraySerializer.instance); - put(Object[].class, ObjectArraySerializer.instance); - put(Class.class, ClassSerializer.instance); - - put(Locale.class, LocaleSerializer.instance); - put(TimeZone.class, TimeZoneSerializer.instance); - put(UUID.class, UUIDSerializer.instance); - put(InetAddress.class, InetAddressSerializer.instance); - put(Inet4Address.class, InetAddressSerializer.instance); - put(Inet6Address.class, InetAddressSerializer.instance); - put(InetSocketAddress.class, InetSocketAddressSerializer.instance); - put(File.class, FileSerializer.instance); - put(URI.class, URISerializer.instance); - put(URL.class, URLSerializer.instance); - put(Appendable.class, AppendableSerializer.instance); - put(StringBuffer.class, AppendableSerializer.instance); - put(StringBuilder.class, AppendableSerializer.instance); - put(Pattern.class, PatternSerializer.instance); - put(Charset.class, CharsetSerializer.instance); - - // atomic - put(AtomicBoolean.class, AtomicBooleanSerializer.instance); - put(AtomicInteger.class, AtomicIntegerSerializer.instance); - put(AtomicLong.class, AtomicLongSerializer.instance); - put(AtomicReference.class, AtomicReferenceSerializer.instance); - put(AtomicIntegerArray.class, AtomicIntegerArraySerializer.instance); - put(AtomicLongArray.class, AtomicLongArraySerializer.instance); - - // jmx - put(ObjectName.class, ObjectNameSerializer.instance); - - } - -} +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +import java.io.File; +import java.io.Serializable; +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; +import java.lang.reflect.Modifier; +import java.lang.reflect.Proxy; +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.URL; +import java.nio.charset.Charset; +import java.sql.Clob; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Collection; +import java.util.Currency; +import java.util.Date; +import java.util.Enumeration; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.TimeZone; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicIntegerArray; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicLongArray; +import java.util.concurrent.atomic.AtomicReference; +import java.util.regex.Pattern; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONAware; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.JSONStreamAware; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.parser.deserializer.Jdk8DateCodec; +import com.alibaba.fastjson.util.ASMUtils; +import com.alibaba.fastjson.util.IdentityHashMap; +import com.alibaba.fastjson.util.ServiceLoader; + +/** + * circular references detect + * + * @author wenshao[szujobs@hotmail.com] + */ +public class SerializeConfig extends IdentityHashMap { + private final static SerializeConfig globalInstance = new SerializeConfig(); + + private boolean asm = !ASMUtils.isAndroid();; + + private ASMSerializerFactory asmFactory; + + + private String typeKey = JSON.DEFAULT_TYPE_KEY; + + public String getTypeKey() { + return typeKey; + } + + public void setTypeKey(String typeKey) { + this.typeKey = typeKey; + } + + public final ObjectSerializer createASMSerializer(Class clazz) + throws Exception { + return asmFactory.createJavaBeanSerializer(clazz, null); + } + + public ObjectSerializer createJavaBeanSerializer(Class clazz) { + if (!Modifier.isPublic(clazz.getModifiers())) { + return new JavaBeanSerializer(clazz); + } + + boolean asm = this.asm; + + if (asm && asmFactory.isExternalClass(clazz) + || clazz == Serializable.class || clazz == Object.class) { + asm = false; + } + + { + JSONType annotation = clazz.getAnnotation(JSONType.class); + if (annotation != null && annotation.asm() == false) { + asm = false; + } + } + + if (asm && !ASMUtils.checkName(clazz.getName())) { + asm = false; + } + + if (asm) { + try { + ObjectSerializer asmSerializer = createASMSerializer(clazz); + if (asmSerializer != null) { + return asmSerializer; + } + } catch (ClassCastException e) { + // skip + } catch (Throwable e) { + throw new JSONException("create asm serializer error, class " + + clazz, e); + } + } + + return new JavaBeanSerializer(clazz); + } + + public boolean isAsmEnable() { + return asm; + } + + public void setAsmEnable(boolean asmEnable) { + this.asm = asmEnable; + } + + public final static SerializeConfig getGlobalInstance() { + return globalInstance; + } + + public SerializeConfig() { + this(DEFAULT_TABLE_SIZE); + } + + public SerializeConfig(int tableSize) { + super(tableSize); + + try { + asmFactory = new ASMSerializerFactory(); + } catch (NoClassDefFoundError eror) { + asm = false; + } catch (ExceptionInInitializerError error) { + asm = false; + } + + put(Boolean.class, BooleanCodec.instance); + put(Character.class, CharacterCodec.instance); + put(Byte.class, IntegerCodec.instance); + put(Short.class, IntegerCodec.instance); + put(Integer.class, IntegerCodec.instance); + put(Long.class, LongCodec.instance); + put(Float.class, FloatCodec.instance); + put(Double.class, DoubleSerializer.instance); + put(BigDecimal.class, BigDecimalCodec.instance); + put(BigInteger.class, BigIntegerCodec.instance); + put(String.class, StringCodec.instance); + put(byte[].class, ByteArraySerializer.instance); + put(short[].class, ShortArraySerializer.instance); + put(int[].class, IntArraySerializer.instance); + put(long[].class, LongArraySerializer.instance); + put(float[].class, FloatArraySerializer.instance); + put(double[].class, DoubleArraySerializer.instance); + put(boolean[].class, BooleanArraySerializer.instance); + put(char[].class, CharArraySerializer.instance); + put(Object[].class, ObjectArraySerializer.instance); + put(Class.class, ClassSerializer.instance); + + put(SimpleDateFormat.class, DateFormatSerializer.instance); + put(Locale.class, LocaleCodec.instance); + put(Currency.class, CurrencyCodec.instance); + put(TimeZone.class, TimeZoneCodec.instance); + put(UUID.class, UUIDCodec.instance); + put(InetAddress.class, InetAddressCodec.instance); + put(Inet4Address.class, InetAddressCodec.instance); + put(Inet6Address.class, InetAddressCodec.instance); + put(InetSocketAddress.class, InetSocketAddressCodec.instance); + put(File.class, FileCodec.instance); + put(URI.class, URICodec.instance); + put(URL.class, URLCodec.instance); + put(Appendable.class, AppendableSerializer.instance); + put(StringBuffer.class, AppendableSerializer.instance); + put(StringBuilder.class, AppendableSerializer.instance); + put(Pattern.class, PatternCodec.instance); + put(Charset.class, CharsetCodec.instance); + + // atomic + put(AtomicBoolean.class, AtomicBooleanSerializer.instance); + put(AtomicInteger.class, AtomicIntegerSerializer.instance); + put(AtomicLong.class, AtomicLongSerializer.instance); + put(AtomicReference.class, ReferenceCodec.instance); + put(AtomicIntegerArray.class, AtomicIntegerArrayCodec.instance); + put(AtomicLongArray.class, AtomicLongArrayCodec.instance); + + put(WeakReference.class, ReferenceCodec.instance); + put(SoftReference.class, ReferenceCodec.instance); + + // awt + try { + put(Class.forName("java.awt.Color"), ColorCodec.instance); + put(Class.forName("java.awt.Font"), FontCodec.instance); + put(Class.forName("java.awt.Point"), PointCodec.instance); + put(Class.forName("java.awt.Rectangle"), + RectangleCodec.instance); + } catch (Throwable e) { + // skip + } + + // jdk8 + try { + put(Class.forName("java.time.LocalDateTime"), Jdk8DateCodec.instance); + put(Class.forName("java.time.LocalDate"), Jdk8DateCodec.instance); + put(Class.forName("java.time.LocalTime"), Jdk8DateCodec.instance); + put(Class.forName("java.time.ZonedDateTime"), Jdk8DateCodec.instance); + put(Class.forName("java.time.OffsetDateTime"), Jdk8DateCodec.instance); + put(Class.forName("java.time.OffsetTime"), Jdk8DateCodec.instance); + put(Class.forName("java.time.ZoneOffset"), Jdk8DateCodec.instance); + put(Class.forName("java.time.ZoneRegion"), Jdk8DateCodec.instance); + put(Class.forName("java.time.Period"), Jdk8DateCodec.instance); + put(Class.forName("java.time.Duration"), Jdk8DateCodec.instance); + put(Class.forName("java.time.Instant"), Jdk8DateCodec.instance); + } catch (Throwable e) { + // skip + } + + } + + public ObjectSerializer getObjectWriter(Class clazz) { + ObjectSerializer writer = get(clazz); + + if (writer == null) { + try { + final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + for (Object o : ServiceLoader.load(AutowiredObjectSerializer.class, classLoader)) { + if (!(o instanceof AutowiredObjectSerializer)) { + continue; + } + + AutowiredObjectSerializer autowired = (AutowiredObjectSerializer) o; + for (Type forType : autowired.getAutowiredFor()) { + put(forType, autowired); + } + } + } catch (ClassCastException ex) { + // skip + } + + writer = get(clazz); + } + + if (writer == null) { + final ClassLoader classLoader = JSON.class.getClassLoader(); + if (classLoader != Thread.currentThread().getContextClassLoader()) { + try { + for (Object o : ServiceLoader.load(AutowiredObjectSerializer.class, classLoader)) { + + if (!(o instanceof AutowiredObjectSerializer)) { + continue; + } + + AutowiredObjectSerializer autowired = (AutowiredObjectSerializer) o; + for (Type forType : autowired.getAutowiredFor()) { + put(forType, autowired); + } + } + } catch (ClassCastException ex) { + // skip + } + + writer = get(clazz); + } + } + + if (writer == null) { + if (Map.class.isAssignableFrom(clazz)) { + put(clazz, MapSerializer.instance); + } else if (List.class.isAssignableFrom(clazz)) { + put(clazz, ListSerializer.instance); + } else if (Collection.class.isAssignableFrom(clazz)) { + put(clazz, CollectionSerializer.instance); + } else if (Date.class.isAssignableFrom(clazz)) { + put(clazz, DateSerializer.instance); + } else if (JSONAware.class.isAssignableFrom(clazz)) { + put(clazz, JSONAwareSerializer.instance); + } else if (JSONSerializable.class.isAssignableFrom(clazz)) { + put(clazz, JSONSerializableSerializer.instance); + } else if (JSONStreamAware.class.isAssignableFrom(clazz)) { + put(clazz, JSONStreamAwareSerializer.instance); + } else if (clazz.isEnum() || (clazz.getSuperclass() != null && clazz.getSuperclass().isEnum())) { + put(clazz, EnumSerializer.instance); + } else if (clazz.isArray()) { + Class componentType = clazz.getComponentType(); + ObjectSerializer compObjectSerializer = getObjectWriter(componentType); + put(clazz, new ArraySerializer(componentType, compObjectSerializer)); + } else if (Throwable.class.isAssignableFrom(clazz)) { + put(clazz, new ExceptionSerializer(clazz)); + } else if (TimeZone.class.isAssignableFrom(clazz)) { + put(clazz, TimeZoneCodec.instance); + } else if (Appendable.class.isAssignableFrom(clazz)) { + put(clazz, AppendableSerializer.instance); + } else if (Charset.class.isAssignableFrom(clazz)) { + put(clazz, CharsetCodec.instance); + } else if (Enumeration.class.isAssignableFrom(clazz)) { + put(clazz, EnumerationSeriliazer.instance); + } else if (Calendar.class.isAssignableFrom(clazz)) { + put(clazz, CalendarCodec.instance); + } else if (Clob.class.isAssignableFrom(clazz)) { + put(clazz, ClobSeriliazer.instance); + } else { + boolean isCglibProxy = false; + boolean isJavassistProxy = false; + for (Class item : clazz.getInterfaces()) { + if (item.getName().equals("net.sf.cglib.proxy.Factory") + || item.getName().equals("org.springframework.cglib.proxy.Factory")) { + isCglibProxy = true; + break; + } else if (item.getName().equals("javassist.util.proxy.ProxyObject")) { + isJavassistProxy = true; + break; + } + } + + if (isCglibProxy || isJavassistProxy) { + Class superClazz = clazz.getSuperclass(); + + ObjectSerializer superWriter = getObjectWriter(superClazz); + put(clazz, superWriter); + return superWriter; + } + + if (Proxy.isProxyClass(clazz)) { + put(clazz, createJavaBeanSerializer(clazz)); + } else { + put(clazz, createJavaBeanSerializer(clazz)); + } + } + + writer = get(clazz); + } + return writer; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerializeFilter.java b/src/main/java/com/alibaba/fastjson/serializer/SerializeFilter.java new file mode 100755 index 0000000000..73dc2cbe86 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/SerializeFilter.java @@ -0,0 +1,6 @@ +package com.alibaba.fastjson.serializer; + + +public interface SerializeFilter { + +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java b/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java old mode 100644 new mode 100755 index 2217256f47..f6ed80a9b3 --- a/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java +++ b/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java @@ -15,1302 +15,1776 @@ */ package com.alibaba.fastjson.serializer; -import static com.alibaba.fastjson.parser.CharTypes.replaceChars; +import static com.alibaba.fastjson.util.IOUtils.replaceChars; import java.io.IOException; import java.io.OutputStream; import java.io.Writer; +import java.lang.ref.SoftReference; import java.math.BigDecimal; import java.nio.charset.Charset; import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.parser.CharTypes; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.util.Base64; import com.alibaba.fastjson.util.IOUtils; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public final class SerializeWriter extends Writer { - /** - * The buffer where data is stored. - */ - protected char buf[]; - - /** - * The number of chars in the buffer. - */ - protected int count; - - private final static ThreadLocal bufLocal = new ThreadLocal(); - - private int features; - - public SerializeWriter() { - this.features = JSON.DEFAULT_GENERATE_FEATURE; - - buf = bufLocal.get(); // new char[1024]; - if (buf == null) { - buf = new char[1024]; - } else { - bufLocal.set(null); - } - } - - /** - * Creates a new CharArrayWriter. - */ - public SerializeWriter(SerializerFeature... features) { - buf = bufLocal.get(); // new char[1024]; - if (buf == null) { - buf = new char[1024]; - } else { - bufLocal.set(null); - } - - int featuresValue = 0; - for (SerializerFeature feature : features) { - featuresValue |= feature.getMask(); - } - this.features = featuresValue; - } - - /** - * Creates a new CharArrayWriter with the specified initial size. - * - * @param initialSize - * an int specifying the initial buffer size. - * @exception IllegalArgumentException - * if initialSize is negative - */ - public SerializeWriter(int initialSize) { - if (initialSize <= 0) { - throw new IllegalArgumentException("Negative initial size: " - + initialSize); - } - buf = new char[initialSize]; - } - - public void config(SerializerFeature feature, boolean state) { - if (state) { - features |= feature.getMask(); - } else { - features &= ~feature.getMask(); - } - } - - public boolean isEnabled(SerializerFeature feature) { - return SerializerFeature.isEnabled(this.features, feature); - } - - /** - * Writes a character to the buffer. - */ - public void write(int c) { - int newcount = count + 1; - if (newcount > buf.length) { - expandCapacity(newcount); - } - buf[count] = (char) c; - count = newcount; - } - - public void write(char c) { - int newcount = count + 1; - if (newcount > buf.length) { - expandCapacity(newcount); - } - buf[count] = c; - count = newcount; - } - - /** - * Writes characters to the buffer. - * - * @param c - * the data to be written - * @param off - * the start offset in the data - * @param len - * the number of chars that are written - */ - public void write(char c[], int off, int len) { - if (off < 0 || off > c.length || len < 0 || off + len > c.length - || off + len < 0) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) { - return; - } - - int newcount = count + len; - if (newcount > buf.length) { - expandCapacity(newcount); - } - System.arraycopy(c, off, buf, count, len); - count = newcount; - - } - - public void expandCapacity(int minimumCapacity) { - int newCapacity = (buf.length * 3) / 2 + 1; - - if (newCapacity < minimumCapacity) { - newCapacity = minimumCapacity; - } - char newValue[] = new char[newCapacity]; - System.arraycopy(buf, 0, newValue, 0, count); - buf = newValue; - } - - /** - * Write a portion of a string to the buffer. - * - * @param str - * String to be written from - * @param off - * Offset from which to start reading characters - * @param len - * Number of characters to be written - */ - public void write(String str, int off, int len) { - int newcount = count + len; - if (newcount > buf.length) { - expandCapacity(newcount); - } - str.getChars(off, off + len, buf, count); - count = newcount; - } - - /** - * Writes the contents of the buffer to another character stream. - * - * @param out - * the output stream to write to - * @throws IOException - * If an I/O error occurs. - */ - public void writeTo(Writer out) throws IOException { - out.write(buf, 0, count); - } - - public void writeTo(OutputStream out, String charset) throws IOException { - byte[] bytes = new String(buf, 0, count).getBytes(charset); - out.write(bytes); - } - - public SerializeWriter append(CharSequence csq) { - String s = (csq == null ? "null" : csq.toString()); - write(s, 0, s.length()); - return this; - } - - public SerializeWriter append(CharSequence csq, int start, int end) { - String s = (csq == null ? "null" : csq).subSequence(start, end) - .toString(); - write(s, 0, s.length()); - return this; - } - - /** - * Appends the specified character to this writer. - *

- * An invocation of this method of the form out.append(c) behaves - * in exactly the same way as the invocation - * - *

-	 * out.write(c)
-	 * 
- * - * @param c - * The 16-bit character to append - * @return This writer - * @since 1.5 - */ - public SerializeWriter append(char c) { - write(c); - return this; - } - - /** - * Resets the buffer so that you can use it again without throwing away the - * already allocated buffer. - */ - public void reset() { - count = 0; - } - - /** - * Returns a copy of the input data. - * - * @return an array of chars copied from the input data. - */ - public char[] toCharArray() { - char[] newValue = new char[count]; - System.arraycopy(buf, 0, newValue, 0, count); - return newValue; - } - - public byte[] toBytes(String charsetName) { - if (charsetName == null) { - charsetName = "UTF-8"; - } - - Charset cs = Charset.forName(charsetName); - SerialWriterStringEncoder encoder = new SerialWriterStringEncoder(cs); - - return encoder.encode(buf, 0, count); - } - - /** - * Returns the current size of the buffer. - * - * @return an int representing the current size of the buffer. - */ - public int size() { - return count; - } - - /** - * Converts input data to a string. - * - * @return the string. - */ - public String toString() { - return new String(buf, 0, count); - } - - /** - * Flush the stream. - */ - public void flush() { - } - - /** - * Close the stream. This method does not release the buffer, since its - * contents might still be required. Note: Invoking this method in this - * class will have no effect. - */ - public void close() { - bufLocal.set(buf); - } - - public void writeBooleanArray(boolean[] array) throws IOException { - int[] sizeArray = new int[array.length]; - int totalSize = 2; - for (int i = 0; i < array.length; ++i) { - if (i != 0) { - totalSize++; - } - boolean val = array[i]; - int size; - if (val) { - size = 4; // "true".length(); - } else { - size = 5; // "false".length(); - } - sizeArray[i] = size; - totalSize += size; - } - - int newcount = count + totalSize; - if (newcount > buf.length) { - expandCapacity(newcount); - } - - buf[count] = '['; - - int currentSize = count + 1; - for (int i = 0; i < array.length; ++i) { - if (i != 0) { - buf[currentSize++] = ','; - } - - boolean val = array[i]; - if (val) { - // System.arraycopy("true".toCharArray(), 0, buf, currentSize, - // 4); - buf[currentSize++] = 't'; - buf[currentSize++] = 'r'; - buf[currentSize++] = 'u'; - buf[currentSize++] = 'e'; - } else { - buf[currentSize++] = 'f'; - buf[currentSize++] = 'a'; - buf[currentSize++] = 'l'; - buf[currentSize++] = 's'; - buf[currentSize++] = 'e'; - } - } - buf[currentSize] = ']'; - - count = newcount; - } - - public void write(String text) { - if (text == null) { - writeNull(); - return; - } - - int length = text.length(); - int newcount = count + length; - if (newcount > buf.length) { - expandCapacity(newcount); - } - text.getChars(0, length, buf, count); - count = newcount; - return; - - } - - public void writeInt(int i) { - if (i == Integer.MIN_VALUE) { - write("-2147483648"); - return; - } - - int size = (i < 0) ? IOUtils.stringSize(-i) + 1 : IOUtils.stringSize(i); - - int newcount = count + size; - if (newcount > buf.length) { - expandCapacity(newcount); - } - - IOUtils.getChars(i, newcount, buf); - - count = newcount; - } - - public void writeShortArray(short[] array) throws IOException { - int[] sizeArray = new int[array.length]; - int totalSize = 2; - for (int i = 0; i < array.length; ++i) { - if (i != 0) { - totalSize++; - } - short val = array[i]; - int size = IOUtils.stringSize(val); - sizeArray[i] = size; - totalSize += size; - } - - int newcount = count + totalSize; - if (newcount > buf.length) { - expandCapacity(newcount); - } - - buf[count] = '['; - - int currentSize = count + 1; - for (int i = 0; i < array.length; ++i) { - if (i != 0) { - buf[currentSize++] = ','; - } - - short val = array[i]; - currentSize += sizeArray[i]; - IOUtils.getChars(val, currentSize, buf); - } - buf[currentSize] = ']'; - - count = newcount; - } - - public void writeByteArray(byte[] array) { - int[] sizeArray = new int[array.length]; - int totalSize = 2; - for (int i = 0; i < array.length; ++i) { - if (i != 0) { - totalSize++; - } - byte val = array[i]; - int size = IOUtils.stringSize(val); - sizeArray[i] = size; - totalSize += size; - } - - int newcount = count + totalSize; - if (newcount > buf.length) { - expandCapacity(newcount); - } - - buf[count] = '['; - - int currentSize = count + 1; - for (int i = 0; i < array.length; ++i) { - if (i != 0) { - buf[currentSize++] = ','; - } - - byte val = array[i]; - currentSize += sizeArray[i]; - IOUtils.getChars(val, currentSize, buf); - } - buf[currentSize] = ']'; - - count = newcount; - } - - public void writeIntArray(int[] array) { - int[] sizeArray = new int[array.length]; - int totalSize = 2; - for (int i = 0; i < array.length; ++i) { - if (i != 0) { - totalSize++; - } - int val = array[i]; - int size; - if (val == Integer.MIN_VALUE) { - size = "-2147483648".length(); - } else { - size = (val < 0) ? IOUtils.stringSize(-val) + 1 : IOUtils - .stringSize(val); - } - sizeArray[i] = size; - totalSize += size; - } - - int newcount = count + totalSize; - if (newcount > buf.length) { - expandCapacity(newcount); - } - - buf[count] = '['; - - int currentSize = count + 1; - for (int i = 0; i < array.length; ++i) { - if (i != 0) { - buf[currentSize++] = ','; - } - - int val = array[i]; - if (val == Integer.MIN_VALUE) { - System.arraycopy("-2147483648".toCharArray(), 0, buf, - currentSize, sizeArray[i]); - currentSize += sizeArray[i]; - } else { - currentSize += sizeArray[i]; - IOUtils.getChars(val, currentSize, buf); - } - } - buf[currentSize] = ']'; - - count = newcount; - } - - public void writeIntAndChar(int i, char c) { - if (i == Integer.MIN_VALUE) { - write("-2147483648"); - write(c); - return; - } - - int size = (i < 0) ? IOUtils.stringSize(-i) + 1 : IOUtils.stringSize(i); - - int newcount0 = count + size; - int newcount1 = newcount0 + 1; - - if (newcount1 > buf.length) { - expandCapacity(newcount1); - } - - IOUtils.getChars(i, newcount0, buf); - buf[newcount0] = c; - - count = newcount1; - } - - public void writeLongAndChar(long i, char c) throws IOException { - if (i == Long.MIN_VALUE) { - write("-9223372036854775808"); - write(c); - return; - } - - int size = (i < 0) ? IOUtils.stringSize(-i) + 1 : IOUtils.stringSize(i); - - int newcount0 = count + size; - int newcount1 = newcount0 + 1; - - if (newcount1 > buf.length) { - expandCapacity(newcount1); - } - - IOUtils.getChars(i, newcount0, buf); - buf[newcount0] = c; - - count = newcount1; - } - - public void writeLong(long i) { - if (i == Long.MIN_VALUE) { - write("-9223372036854775808"); - return; - } - - int size = (i < 0) ? IOUtils.stringSize(-i) + 1 : IOUtils.stringSize(i); - - int newcount = count + size; - if (newcount > buf.length) { - expandCapacity(newcount); - } - - IOUtils.getChars(i, newcount, buf); - - count = newcount; - } - - public void writeNull() { - int newcount = count + 4; - if (newcount > buf.length) { - expandCapacity(newcount); - } - buf[count] = 'n'; - buf[count + 1] = 'u'; - buf[count + 2] = 'l'; - buf[count + 3] = 'l'; - count = newcount; - } - - public void writeLongArray(long[] array) { - int[] sizeArray = new int[array.length]; - int totalSize = 2; - for (int i = 0; i < array.length; ++i) { - if (i != 0) { - totalSize++; - } - long val = array[i]; - int size; - if (val == Long.MIN_VALUE) { - size = "-9223372036854775808".length(); - } else { - size = (val < 0) ? IOUtils.stringSize(-val) + 1 : IOUtils - .stringSize(val); - } - sizeArray[i] = size; - totalSize += size; - } - - int newcount = count + totalSize; - if (newcount > buf.length) { - expandCapacity(newcount); - } - - buf[count] = '['; - - int currentSize = count + 1; - for (int i = 0; i < array.length; ++i) { - if (i != 0) { - buf[currentSize++] = ','; - } - - long val = array[i]; - if (val == Long.MIN_VALUE) { - System.arraycopy("-9223372036854775808".toCharArray(), 0, buf, - currentSize, sizeArray[i]); - currentSize += sizeArray[i]; - } else { - currentSize += sizeArray[i]; - IOUtils.getChars(val, currentSize, buf); - } - } - buf[currentSize] = ']'; - - count = newcount; - } - - private void writeStringWithDoubleQuote(String text) { - // final boolean[] specicalFlags_doubleQuotes = - // CharTypes.specicalFlags_doubleQuotes; - // final int len_flags = specicalFlags_doubleQuotes.length; - - if (text == null) { - writeNull(); - return; - } - - int len = text.length(); - int newcount = count + len + 2; - if (newcount > buf.length) { - expandCapacity(newcount); - } - - int start = count + 1; - int end = start + len; - - buf[count] = '\"'; - text.getChars(0, len, buf, start); - - count = newcount; - - int specialCount = 0; - int lastSpecialIndex = -1; - char lastSpecial = '\0'; - for (int i = start; i < end; ++i) { - char ch = buf[i]; - if (ch == '\b' || ch == '\n' - || ch == '\r' - || ch == '\f' - || ch == '\\' - || ch == '"' // - || (ch == '\t' && isEnabled(SerializerFeature.WriteTabAsSpecial))) { - specialCount++; - lastSpecialIndex = i; - lastSpecial = ch; - } - } - - newcount += specialCount; - if (newcount > buf.length) { - expandCapacity(newcount); - } - count = newcount; - - if (specialCount == 1) { - System.arraycopy(buf, lastSpecialIndex + 1, buf, - lastSpecialIndex + 2, end - lastSpecialIndex - 1); - buf[lastSpecialIndex] = '\\'; - buf[++lastSpecialIndex] = replaceChars[(int) lastSpecial]; - } else if (specialCount > 1) { - System.arraycopy(buf, lastSpecialIndex + 1, buf, - lastSpecialIndex + 2, end - lastSpecialIndex - 1); - buf[lastSpecialIndex] = '\\'; - buf[++lastSpecialIndex] = replaceChars[(int) lastSpecial]; - end++; - for (int i = lastSpecialIndex - 2; i >= start; --i) { - char ch = buf[i]; - - if (ch == '\b' || ch == '\n' - || ch == '\r' - || ch == '\f' - || ch == '\\' - || ch == '"' // - || (ch == '\t' && isEnabled(SerializerFeature.WriteTabAsSpecial))) { - System.arraycopy(buf, i + 1, buf, i + 2, end - i - 1); - buf[i] = '\\'; - buf[i + 1] = replaceChars[(int) ch]; - end++; - } - } - } - - buf[count - 1] = '\"'; - } - - public void writeKeyWithDoubleQuote(String text) { - final boolean[] specicalFlags_doubleQuotes = CharTypes.specicalFlags_doubleQuotes; - - int len = text.length(); - int newcount = count + len + 3; - if (newcount > buf.length) { - expandCapacity(newcount); - } - - int start = count + 1; - int end = start + len; - - buf[count] = '\"'; - text.getChars(0, len, buf, start); - - count = newcount; - - for (int i = start; i < end; ++i) { - char ch = buf[i]; - if (ch < specicalFlags_doubleQuotes.length - && specicalFlags_doubleQuotes[ch] // - || (ch == '\t' && isEnabled(SerializerFeature.WriteTabAsSpecial))) { - newcount++; - if (newcount > buf.length) { - expandCapacity(newcount); - } - count = newcount; - - System.arraycopy(buf, i + 1, buf, i + 2, end - i - 1); - buf[i] = '\\'; - buf[++i] = replaceChars[(int) ch]; - end++; - } - } - - buf[count - 2] = '\"'; - buf[count - 1] = ':'; - } - - public void writeFieldNull(char seperator, String name) { - write(seperator); - writeFieldName(name); - writeNull(); - } - - public void writeFieldNullString(char seperator, String name) { - write(seperator); - writeFieldName(name); - if (isEnabled(SerializerFeature.WriteNullStringAsEmpty)) { - writeString(""); - } else { - writeNull(); - } - } - - public void writeFieldNullBoolean(char seperator, String name) { - write(seperator); - writeFieldName(name); - if (isEnabled(SerializerFeature.WriteNullBooleanAsFalse)) { - write("false"); - } else { - writeNull(); - } - } - - public void writeFieldNullList(char seperator, String name) { - write(seperator); - writeFieldName(name); - if (isEnabled(SerializerFeature.WriteNullListAsEmpty)) { - write("[]"); - } else { - writeNull(); - } - } - - public void writeFieldNullNumber(char seperator, String name) { - write(seperator); - writeFieldName(name); - if (isEnabled(SerializerFeature.WriteNullNumberAsZero)) { - write('0'); - } else { - writeNull(); - } - } - - public void writeFieldValue(char seperator, String name, char value) { - write(seperator); - writeFieldName(name); - if (value == 0) { - writeString("\u0000"); - } else { - writeString(Character.toString(value)); - } - } - - public void writeFieldValue(char seperator, String name, boolean value) { - write(seperator); - writeFieldName(name); - if (value) { - write("true"); - } else { - write("false"); - } - } - - public void writeFieldValue(char seperator, String name, int value) { - write(seperator); - writeFieldName(name); - writeInt(value); - } - - public void writeFieldValue(char seperator, String name, long value) { - write(seperator); - writeFieldName(name); - writeLong(value); - } - - public void writeFieldValue(char seperator, String name, float value) { - write(seperator); - writeFieldName(name); - if (value == 0) { - write('0'); - } else if (Float.isNaN(value)) { - writeNull(); - } else if (Float.isInfinite(value)) { - writeNull(); - } else { - String text = Float.toString(value); - if (text.endsWith(".0")) { - text = text.substring(0, text.length() - 2); - } - write(text); - } - } - - public void writeFieldValue(char seperator, String name, double value) { - write(seperator); - writeFieldName(name); - if (value == 0) { - write('0'); - } else if (Double.isNaN(value)) { - writeNull(); - } else if (Double.isInfinite(value)) { - writeNull(); - } else { - String text = Double.toString(value); - if (text.endsWith(".0")) { - text = text.substring(0, text.length() - 2); - } - write(text); - } - } - - public void writeFieldValue(char seperator, String name, String value) { - if (isEnabled(SerializerFeature.QuoteFieldNames)) { - if (isEnabled(SerializerFeature.UseSingleQuotes)) { - write(seperator); - writeFieldName(name); - if (value == null) { - writeNull(); - } else { - writeString(value); - } - } else { - writeFieldValueStringWithDoubleQuote(seperator, name, value); - } - } else { - write(seperator); - writeFieldName(name); - if (value == null) { - writeNull(); - } else { - writeString(value); - } - } - } - - private void writeFieldValueStringWithDoubleQuote(char seperator, - String name, String value) { - int nameLen = name.length(); - int valueLen; - - int newcount = count; - - if (value == null) { - valueLen = 4; - newcount += nameLen + 8; - } else { - valueLen = value.length(); - newcount += nameLen + valueLen + 6; - } - - if (newcount > buf.length) { - expandCapacity(newcount); - } - - buf[count] = seperator; - - int nameStart = count + 2; - int nameEnd = nameStart + nameLen; - - buf[count + 1] = '\"'; - name.getChars(0, nameLen, buf, nameStart); - - count = newcount; - - int specialCount = 0; - int lastSpecialIndex = -1; - char lastSpecial = '\0'; - for (int i = nameStart; i < nameEnd; ++i) { - char ch = buf[i]; - if (ch == '\b' || ch == '\n' - || ch == '\r' - || ch == '\f' - || ch == '\\' - || ch == '"' // - || (ch == '\t' && isEnabled(SerializerFeature.WriteTabAsSpecial))) { - specialCount++; - lastSpecialIndex = i; - lastSpecial = ch; - } - } - - if (specialCount > 0) { - newcount += specialCount; - if (newcount > buf.length) { - expandCapacity(newcount); - } - count = newcount; - } - - if (specialCount == 1) { - System.arraycopy(buf, lastSpecialIndex + 1, buf, - lastSpecialIndex + 2, nameEnd - lastSpecialIndex - 1); - buf[lastSpecialIndex] = '\\'; - buf[++lastSpecialIndex] = replaceChars[(int) lastSpecial]; - nameEnd++; - } else if (specialCount > 1) { - System.arraycopy(buf, lastSpecialIndex + 1, buf, - lastSpecialIndex + 2, nameEnd - lastSpecialIndex - 1); - buf[lastSpecialIndex] = '\\'; - buf[++lastSpecialIndex] = replaceChars[(int) lastSpecial]; - nameEnd++; - for (int i = lastSpecialIndex - 2; i >= nameStart; --i) { - char ch = buf[i]; - - if (ch == '\b' || ch == '\n' - || ch == '\r' - || ch == '\f' - || ch == '\\' - || ch == '"' // - || (ch == '\t' && isEnabled(SerializerFeature.WriteTabAsSpecial))) { - System.arraycopy(buf, i + 1, buf, i + 2, nameEnd - i - 1); - buf[i] = '\\'; - buf[i + 1] = replaceChars[(int) ch]; - nameEnd++; - } - } - } - - buf[nameEnd] = '\"'; - - int index = nameEnd + 1; - buf[index++] = ':'; - - if (value == null) { - buf[index++] = 'n'; - buf[index++] = 'u'; - buf[index++] = 'l'; - buf[index++] = 'l'; - return; - } - - buf[index++] = '"'; - - int valueStart = index; - int valueEnd = valueStart + valueLen; - - value.getChars(0, valueLen, buf, valueStart); - - specialCount = 0; - lastSpecialIndex = -1; - lastSpecial = '\0'; - for (int i = valueStart; i < valueEnd; ++i) { - char ch = buf[i]; - if (ch == '\b' || ch == '\n' - || ch == '\r' - || ch == '\f' - || ch == '\\' - || ch == '"' // - || (ch == '\t' && isEnabled(SerializerFeature.WriteTabAsSpecial))) { - specialCount++; - lastSpecialIndex = i; - lastSpecial = ch; - } - } - - if (specialCount > 0) { - newcount += specialCount; - if (newcount > buf.length) { - expandCapacity(newcount); - } - count = newcount; - } - - if (specialCount == 1) { - System.arraycopy(buf, lastSpecialIndex + 1, buf, - lastSpecialIndex + 2, valueEnd - lastSpecialIndex - 1); - buf[lastSpecialIndex] = '\\'; - buf[++lastSpecialIndex] = replaceChars[(int) lastSpecial]; - } else if (specialCount > 1) { - System.arraycopy(buf, lastSpecialIndex + 1, buf, - lastSpecialIndex + 2, valueEnd - lastSpecialIndex - 1); - buf[lastSpecialIndex] = '\\'; - buf[++lastSpecialIndex] = replaceChars[(int) lastSpecial]; - valueEnd++; - for (int i = lastSpecialIndex - 2; i >= valueStart; --i) { - char ch = buf[i]; - - if (ch == '\b' || ch == '\n' - || ch == '\r' - || ch == '\f' - || ch == '\\' - || ch == '"' // - || (ch == '\t' && isEnabled(SerializerFeature.WriteTabAsSpecial))) { - System.arraycopy(buf, i + 1, buf, i + 2, valueEnd - i - 1); - buf[i] = '\\'; - buf[i + 1] = replaceChars[(int) ch]; - valueEnd++; - } - } - } - - buf[count - 1] = '\"'; - } - - // writeStringWithSingleQuote - - public void writeFieldValue(char seperator, String name, Enum value) { - write(seperator); - writeFieldName(name); - if (value == null) { - writeNull(); - } else { - if (isEnabled(SerializerFeature.WriteEnumUsingToString)) { - writeString(value.name()); - } else { - writeInt(value.ordinal()); - } - } - } - - public void writeFieldValue(char seperator, String name, BigDecimal value) { - write(seperator); - writeFieldName(name); - if (value == null) { - writeNull(); - } else { - write(value.toString()); - } - } - - public void writeString(String text, char seperator) { - writeString(text); - write(seperator); - } - - public void writeString(String text) { - if (isEnabled(SerializerFeature.UseSingleQuotes)) { - writeStringWithSingleQuote(text); - } else { - writeStringWithDoubleQuote(text); - } - } - - private void writeStringWithSingleQuote(String text) { - if (text == null) { - int newcount = count + 4; - if (newcount > buf.length) { - expandCapacity(newcount); - } - "null".getChars(0, 4, buf, count); - count = newcount; - return; - } - - int len = text.length(); - int newcount = count + len + 2; - if (newcount > buf.length) { - expandCapacity(newcount); - } - - int start = count + 1; - int end = start + len; - - buf[count] = '\''; - text.getChars(0, len, buf, start); - count = newcount; - - int specialCount = 0; - int lastSpecialIndex = -1; - char lastSpecial = '\0'; - for (int i = start; i < end; ++i) { - char ch = buf[i]; - if (ch == '\b' || ch == '\n' - || ch == '\r' - || ch == '\f' - || ch == '\\' - || ch == '\'' // - || (ch == '\t' && isEnabled(SerializerFeature.WriteTabAsSpecial))) { - specialCount++; - lastSpecialIndex = i; - lastSpecial = ch; - } - } - - newcount += specialCount; - if (newcount > buf.length) { - expandCapacity(newcount); - } - count = newcount; - - if (specialCount == 1) { - System.arraycopy(buf, lastSpecialIndex + 1, buf, - lastSpecialIndex + 2, end - lastSpecialIndex - 1); - buf[lastSpecialIndex] = '\\'; - buf[++lastSpecialIndex] = replaceChars[(int) lastSpecial]; - } else if (specialCount > 1) { - System.arraycopy(buf, lastSpecialIndex + 1, buf, - lastSpecialIndex + 2, end - lastSpecialIndex - 1); - buf[lastSpecialIndex] = '\\'; - buf[++lastSpecialIndex] = replaceChars[(int) lastSpecial]; - end++; - for (int i = lastSpecialIndex - 2; i >= start; --i) { - char ch = buf[i]; - - if (ch == '\b' || ch == '\n' - || ch == '\r' - || ch == '\f' - || ch == '\\' - || ch == '\'' // - || (ch == '\t' && isEnabled(SerializerFeature.WriteTabAsSpecial))) { - System.arraycopy(buf, i + 1, buf, i + 2, end - i - 1); - buf[i] = '\\'; - buf[i + 1] = replaceChars[(int) ch]; - end++; - } - } - } - - buf[count - 1] = '\''; - } - - public void writeFieldName(String key) { - if (isEnabled(SerializerFeature.UseSingleQuotes)) { - if (isEnabled(SerializerFeature.QuoteFieldNames)) { - writeKeyWithSingleQuote(key); - } else { - writeKeyWithSingleQuoteIfHasSpecial(key); - } - } else { - if (isEnabled(SerializerFeature.QuoteFieldNames)) { - writeKeyWithDoubleQuote(key); - } else { - writeKeyWithDoubleQuoteIfHasSpecial(key); - } - } - } - - private void writeKeyWithSingleQuote(String text) { - final boolean[] specicalFlags_singleQuotes = CharTypes.specicalFlags_singleQuotes; - - int len = text.length(); - int newcount = count + len + 3; - if (newcount > buf.length) { - expandCapacity(newcount); - } - - int start = count + 1; - int end = start + len; - - buf[count] = '\''; - text.getChars(0, len, buf, start); - count = newcount; - - for (int i = start; i < end; ++i) { - char ch = buf[i]; - if (ch < specicalFlags_singleQuotes.length - && specicalFlags_singleQuotes[ch] // - || (ch == '\t' && isEnabled(SerializerFeature.WriteTabAsSpecial))) { - newcount++; - if (newcount > buf.length) { - expandCapacity(newcount); - } - count = newcount; - - System.arraycopy(buf, i + 1, buf, i + 2, end - i - 1); - buf[i] = '\\'; - buf[++i] = replaceChars[(int) ch]; - end++; - } - } - - buf[count - 2] = '\''; - buf[count - 1] = ':'; - } - - private void writeKeyWithDoubleQuoteIfHasSpecial(String text) { - final boolean[] specicalFlags_doubleQuotes = CharTypes.specicalFlags_doubleQuotes; - - int len = text.length(); - int newcount = count + len + 1; - if (newcount > buf.length) { - expandCapacity(newcount); - } - - int start = count; - int end = start + len; - - text.getChars(0, len, buf, start); - count = newcount; - - boolean hasSpecial = false; - - for (int i = start; i < end; ++i) { - char ch = buf[i]; - if (ch < specicalFlags_doubleQuotes.length - && specicalFlags_doubleQuotes[ch]) { - if (!hasSpecial) { - newcount += 3; - if (newcount > buf.length) { - expandCapacity(newcount); - } - count = newcount; - - System.arraycopy(buf, i + 1, buf, i + 3, end - i - 1); - System.arraycopy(buf, 0, buf, 1, i); - buf[start] = '"'; - buf[++i] = '\\'; - buf[++i] = replaceChars[(int) ch]; - end += 2; - buf[count - 2] = '"'; - - hasSpecial = true; - } else { - newcount++; - if (newcount > buf.length) { - expandCapacity(newcount); - } - count = newcount; - - System.arraycopy(buf, i + 1, buf, i + 2, end - i); - buf[i] = '\\'; - buf[++i] = replaceChars[(int) ch]; - end++; - } - } - } - - buf[count - 1] = ':'; - } - - private void writeKeyWithSingleQuoteIfHasSpecial(String text) { - final boolean[] specicalFlags_singleQuotes = CharTypes.specicalFlags_singleQuotes; - - int len = text.length(); - int newcount = count + len + 1; - if (newcount > buf.length) { - expandCapacity(newcount); - } - - int start = count; - int end = start + len; - - text.getChars(0, len, buf, start); - count = newcount; - - boolean hasSpecial = false; - - for (int i = start; i < end; ++i) { - char ch = buf[i]; - if (ch < specicalFlags_singleQuotes.length - && specicalFlags_singleQuotes[ch]) { - if (!hasSpecial) { - newcount += 3; - if (newcount > buf.length) { - expandCapacity(newcount); - } - count = newcount; - - System.arraycopy(buf, i + 1, buf, i + 3, end - i - 1); - System.arraycopy(buf, 0, buf, 1, i); - buf[start] = '\''; - buf[++i] = '\\'; - buf[++i] = replaceChars[(int) ch]; - end += 2; - buf[count - 2] = '\''; - - hasSpecial = true; - } else { - newcount++; - if (newcount > buf.length) { - expandCapacity(newcount); - } - count = newcount; - - System.arraycopy(buf, i + 1, buf, i + 2, end - i); - buf[i] = '\\'; - buf[++i] = replaceChars[(int) ch]; - end++; - } - } - } - - buf[newcount - 1] = ':'; - } + /** + * The buffer where data is stored. + */ + protected char buf[]; + + /** + * The number of chars in the buffer. + */ + protected int count; + + private final static ThreadLocal> bufLocal = new ThreadLocal>(); + + private int features; + + private final Writer writer; + + public SerializeWriter(){ + this((Writer) null); + } + + public SerializeWriter(Writer writer){ + this.writer = writer; + this.features = JSON.DEFAULT_GENERATE_FEATURE; + + SoftReference ref = bufLocal.get(); + + if (ref != null) { + buf = ref.get(); + bufLocal.set(null); + } + + if (buf == null) { + buf = new char[1024]; + } + } + + public SerializeWriter(SerializerFeature... features){ + this(null, features); + } + + public SerializeWriter(Writer writer, SerializerFeature... features){ + this.writer = writer; + + SoftReference ref = bufLocal.get(); + + if (ref != null) { + buf = ref.get(); + bufLocal.set(null); + } + + if (buf == null) { + buf = new char[1024]; + } + + int featuresValue = 0; + for (SerializerFeature feature : features) { + featuresValue |= feature.getMask(); + } + this.features = featuresValue; + } + + public int getBufferLength() { + return this.buf.length; + } + + public SerializeWriter(int initialSize){ + this(null, initialSize); + } + + public SerializeWriter(Writer writer, int initialSize){ + this.writer = writer; + + if (initialSize <= 0) { + throw new IllegalArgumentException("Negative initial size: " + initialSize); + } + buf = new char[initialSize]; + } + + public void config(SerializerFeature feature, boolean state) { + if (state) { + features |= feature.getMask(); + } else { + features &= ~feature.getMask(); + } + } + + public boolean isEnabled(SerializerFeature feature) { + return SerializerFeature.isEnabled(this.features, feature); + } + + /** + * Writes a character to the buffer. + */ + public void write(int c) { + int newcount = count + 1; + if (newcount > buf.length) { + if (writer == null) { + expandCapacity(newcount); + } else { + flush(); + newcount = 1; + } + } + buf[count] = (char) c; + count = newcount; + } + + public void write(char c) { + int newcount = count + 1; + if (newcount > buf.length) { + if (writer == null) { + expandCapacity(newcount); + } else { + flush(); + newcount = 1; + } + } + buf[count] = c; + count = newcount; + } + + /** + * Writes characters to the buffer. + * + * @param c the data to be written + * @param off the start offset in the data + * @param len the number of chars that are written + */ + public void write(char c[], int off, int len) { + if (off < 0 // + || off > c.length // + || len < 0 // + || off + len > c.length // + || off + len < 0) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return; + } + + int newcount = count + len; + if (newcount > buf.length) { + if (writer == null) { + expandCapacity(newcount); + } else { + do { + int rest = buf.length - count; + System.arraycopy(c, off, buf, count, rest); + count = buf.length; + flush(); + len -= rest; + off += rest; + } while (len > buf.length); + newcount = len; + } + } + System.arraycopy(c, off, buf, count, len); + count = newcount; + + } + + public void expandCapacity(int minimumCapacity) { + int newCapacity = (buf.length * 3) / 2 + 1; + + if (newCapacity < minimumCapacity) { + newCapacity = minimumCapacity; + } + char newValue[] = new char[newCapacity]; + System.arraycopy(buf, 0, newValue, 0, count); + buf = newValue; + } + + /** + * Write a portion of a string to the buffer. + * + * @param str String to be written from + * @param off Offset from which to start reading characters + * @param len Number of characters to be written + */ + public void write(String str, int off, int len) { + int newcount = count + len; + if (newcount > buf.length) { + if (writer == null) { + expandCapacity(newcount); + } else { + do { + int rest = buf.length - count; + str.getChars(off, off + rest, buf, count); + count = buf.length; + flush(); + len -= rest; + off += rest; + } while (len > buf.length); + newcount = len; + } + } + str.getChars(off, off + len, buf, count); + count = newcount; + } + + /** + * Writes the contents of the buffer to another character stream. + * + * @param out the output stream to write to + * @throws IOException If an I/O error occurs. + */ + public void writeTo(Writer out) throws IOException { + if (this.writer != null) { + throw new UnsupportedOperationException("writer not null"); + } + out.write(buf, 0, count); + } + + public void writeTo(OutputStream out, String charsetName) throws IOException { + writeTo(out, Charset.forName(charsetName)); + } + + public void writeTo(OutputStream out, Charset charset) throws IOException { + if (this.writer != null) { + throw new UnsupportedOperationException("writer not null"); + } + byte[] bytes = new String(buf, 0, count).getBytes(charset); + out.write(bytes); + } + + public SerializeWriter append(CharSequence csq) { + String s = (csq == null ? "null" : csq.toString()); + write(s, 0, s.length()); + return this; + } + + public SerializeWriter append(CharSequence csq, int start, int end) { + String s = (csq == null ? "null" : csq).subSequence(start, end).toString(); + write(s, 0, s.length()); + return this; + } + + public SerializeWriter append(char c) { + write(c); + return this; + } + + public void reset() { + count = 0; + } + + /** + * Returns a copy of the input data. + * + * @return an array of chars copied from the input data. + */ + public char[] toCharArray() { + if (this.writer != null) { + throw new UnsupportedOperationException("writer not null"); + } + + char[] newValue = new char[count]; + System.arraycopy(buf, 0, newValue, 0, count); + return newValue; + } + + public byte[] toBytes(String charsetName) { + if (this.writer != null) { + throw new UnsupportedOperationException("writer not null"); + } + + if (charsetName == null) { + charsetName = "UTF-8"; + } + + Charset cs = Charset.forName(charsetName); + SerialWriterStringEncoder encoder = new SerialWriterStringEncoder(cs); + + return encoder.encode(buf, 0, count); + } + + public int size() { + return count; + } + + public String toString() { + return new String(buf, 0, count); + } + + /** + * Close the stream. This method does not release the buffer, since its contents might still be required. Note: + * Invoking this method in this class will have no effect. + */ + public void close() { + if (writer != null && count > 0) { + flush(); + } + if (buf.length <= 1024 * 8) { + bufLocal.set(new SoftReference(buf)); + } + + this.buf = null; + } + + public void write(String text) { + if (text == null) { + writeNull(); + return; + } + + write(text, 0, text.length()); + } + + public void writeInt(int i) { + if (i == Integer.MIN_VALUE) { + write("-2147483648"); + return; + } + + int size = (i < 0) ? IOUtils.stringSize(-i) + 1 : IOUtils.stringSize(i); + + int newcount = count + size; + if (newcount > buf.length) { + if (writer == null) { + expandCapacity(newcount); + } else { + char[] chars = new char[size]; + IOUtils.getChars(i, size, chars); + write(chars, 0, chars.length); + return; + } + } + + IOUtils.getChars(i, newcount, buf); + + count = newcount; + } + + public void writeByteArray(byte[] bytes) { + int bytesLen = bytes.length; + final boolean singleQuote = isEnabled(SerializerFeature.UseSingleQuotes); + final char quote = singleQuote ? '\'' : '"'; + + if (bytesLen == 0) { + String emptyString = singleQuote ? "''" : "\"\""; + write(emptyString); + return; + } + + final char[] CA = Base64.CA; + + int eLen = (bytesLen / 3) * 3; // Length of even 24-bits. + int charsLen = ((bytesLen - 1) / 3 + 1) << 2; // base64 character count + // char[] chars = new char[charsLen]; + int offset = count; + int newcount = count + charsLen + 2; + if (newcount > buf.length) { + if (writer != null) { + write(quote); + + for (int s = 0; s < eLen;) { + // Copy next three bytes into lower 24 bits of int, paying attension to sign. + int i = (bytes[s++] & 0xff) << 16 | (bytes[s++] & 0xff) << 8 | (bytes[s++] & 0xff); + + // Encode the int into four chars + write(CA[(i >>> 18) & 0x3f]); + write(CA[(i >>> 12) & 0x3f]); + write(CA[(i >>> 6) & 0x3f]); + write(CA[i & 0x3f]); + } + + // Pad and encode last bits if source isn't even 24 bits. + int left = bytesLen - eLen; // 0 - 2. + if (left > 0) { + // Prepare the int + int i = ((bytes[eLen] & 0xff) << 10) | (left == 2 ? ((bytes[bytesLen - 1] & 0xff) << 2) : 0); + + // Set last four chars + write(CA[i >> 12]); + write(CA[(i >>> 6) & 0x3f]); + write(left == 2 ? CA[i & 0x3f] : '='); + write('='); + } + + write(quote); + return; + } + expandCapacity(newcount); + } + count = newcount; + buf[offset++] = quote; + + // Encode even 24-bits + for (int s = 0, d = offset; s < eLen;) { + // Copy next three bytes into lower 24 bits of int, paying attension to sign. + int i = (bytes[s++] & 0xff) << 16 | (bytes[s++] & 0xff) << 8 | (bytes[s++] & 0xff); + + // Encode the int into four chars + buf[d++] = CA[(i >>> 18) & 0x3f]; + buf[d++] = CA[(i >>> 12) & 0x3f]; + buf[d++] = CA[(i >>> 6) & 0x3f]; + buf[d++] = CA[i & 0x3f]; + } + + // Pad and encode last bits if source isn't even 24 bits. + int left = bytesLen - eLen; // 0 - 2. + if (left > 0) { + // Prepare the int + int i = ((bytes[eLen] & 0xff) << 10) | (left == 2 ? ((bytes[bytesLen - 1] & 0xff) << 2) : 0); + + // Set last four chars + buf[newcount - 5] = CA[i >> 12]; + buf[newcount - 4] = CA[(i >>> 6) & 0x3f]; + buf[newcount - 3] = left == 2 ? CA[i & 0x3f] : '='; + buf[newcount - 2] = '='; + } + buf[newcount - 1] = quote; + } + + public void writeFloatAndChar(float value, char c) { + String text = Float.toString(value); + if (text.endsWith(".0")) { + text = text.substring(0, text.length() - 2); + } + write(text); + write(c); + } + + public void writeDoubleAndChar(double value, char c) { + String text = Double.toString(value); + if (text.endsWith(".0")) { + text = text.substring(0, text.length() - 2); + } + write(text); + write(c); + } + + public void writeBooleanAndChar(boolean value, char c) { + if (value) { + if (c == ',') { + write("true,"); + } else if (c == ']') { + write("true]"); + } else { + write("true"); + write(c); + } + } else { + if (c == ',') { + write("false,"); + } else if (c == ']') { + write("false]"); + } else { + write("false"); + write(c); + } + } + } + + public void writeCharacterAndChar(char value, char c) { + writeString(Character.toString(value)); + write(c); + } + + public void writeEnum(Enum value, char c) { + if (value == null) { + writeNull(); + write(','); + return; + } + + if (isEnabled(SerializerFeature.WriteEnumUsingToString)) { + if (isEnabled(SerializerFeature.UseSingleQuotes)) { + write('\''); + write(value.name()); + write('\''); + write(c); + + } else { + write('\"'); + write(value.name()); + write('\"'); + write(c); + } + return; + } + + writeIntAndChar(value.ordinal(), c); + } + + public void writeIntAndChar(int i, char c) { + if (i == Integer.MIN_VALUE) { + write("-2147483648"); + write(c); + return; + } + + int size = (i < 0) ? IOUtils.stringSize(-i) + 1 : IOUtils.stringSize(i); + + int newcount0 = count + size; + int newcount1 = newcount0 + 1; + + if (newcount1 > buf.length) { + if (writer != null) { + writeInt(i); + write(c); + return; + } + expandCapacity(newcount1); + } + + IOUtils.getChars(i, newcount0, buf); + buf[newcount0] = c; + + count = newcount1; + } + + public void writeLongAndChar(long i, char c) throws IOException { + if (i == Long.MIN_VALUE) { + write("-9223372036854775808"); + write(c); + return; + } + + int size = (i < 0) ? IOUtils.stringSize(-i) + 1 : IOUtils.stringSize(i); + + int newcount0 = count + size; + int newcount1 = newcount0 + 1; + + if (newcount1 > buf.length) { + if (writer != null) { + writeLong(i); + write(c); + return; + } + expandCapacity(newcount1); + } + + IOUtils.getChars(i, newcount0, buf); + buf[newcount0] = c; + + count = newcount1; + } + + public void writeLong(long i) { + if (i == Long.MIN_VALUE) { + write("-9223372036854775808"); + return; + } + + int size = (i < 0) ? IOUtils.stringSize(-i) + 1 : IOUtils.stringSize(i); + + int newcount = count + size; + if (newcount > buf.length) { + if (writer == null) { + expandCapacity(newcount); + } else { + char[] chars = new char[size]; + IOUtils.getChars(i, size, chars); + write(chars, 0, chars.length); + return; + } + } + + IOUtils.getChars(i, newcount, buf); + + count = newcount; + } + + public void writeNull() { + write("null"); + } + + private void writeStringWithDoubleQuote(String text, final char seperator) { + writeStringWithDoubleQuote(text, seperator, true); + } + + private void writeStringWithDoubleQuote(String text, final char seperator, boolean checkSpecial) { + if (text == null) { + writeNull(); + if (seperator != 0) { + write(seperator); + } + return; + } + + int len = text.length(); + int newcount = count + len + 2; + if (seperator != 0) { + newcount++; + } + + if (newcount > buf.length) { + if (writer != null) { + write('"'); + + for (int i = 0; i < text.length(); ++i) { + char ch = text.charAt(i); + + if (isEnabled(SerializerFeature.BrowserCompatible)) { + if (ch == '\b' // + || ch == '\f' // + || ch == '\n' // + || ch == '\r' // + || ch == '\t' // + || ch == '"' // + || ch == '/' // + || ch == '\\') { + write('\\'); + write(replaceChars[(int) ch]); + continue; + } + + if (ch < 32) { + write('\\'); + write('u'); + write('0'); + write('0'); + write(IOUtils.ASCII_CHARS[ch * 2]); + write(IOUtils.ASCII_CHARS[ch * 2 + 1]); + continue; + } + + if (ch >= 127) { + write('\\'); + write('u'); + write(IOUtils.DIGITS[(ch >>> 12) & 15]); + write(IOUtils.DIGITS[(ch >>> 8) & 15]); + write(IOUtils.DIGITS[(ch >>> 4) & 15]); + write(IOUtils.DIGITS[ch & 15]); + continue; + } + } else { + if (ch < IOUtils.specicalFlags_doubleQuotes.length + && IOUtils.specicalFlags_doubleQuotes[ch] != 0 // + || (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) { + write('\\'); + write(replaceChars[(int) ch]); + continue; + } + } + + write(ch); + } + + write('"'); + if (seperator != 0) { + write(seperator); + } + return; + } + expandCapacity(newcount); + } + + int start = count + 1; + int end = start + len; + + buf[count] = '\"'; + text.getChars(0, len, buf, start); + + count = newcount; + + if (isEnabled(SerializerFeature.BrowserCompatible)) { + int lastSpecialIndex = -1; + + for (int i = start; i < end; ++i) { + char ch = buf[i]; + + if (ch == '"' // + || ch == '/' // + || ch == '\\') { + lastSpecialIndex = i; + newcount += 1; + continue; + } + + if (ch == '\b' // + || ch == '\f' // + || ch == '\n' // + || ch == '\r' // + || ch == '\t') { + lastSpecialIndex = i; + newcount += 1; + continue; + } + + if (ch < 32) { + lastSpecialIndex = i; + newcount += 5; + continue; + } + + if (ch >= 127) { + lastSpecialIndex = i; + newcount += 5; + continue; + } + } + + if (newcount > buf.length) { + expandCapacity(newcount); + } + count = newcount; + + for (int i = lastSpecialIndex; i >= start; --i) { + char ch = buf[i]; + + if (ch == '\b' // + || ch == '\f'// + || ch == '\n' // + || ch == '\r' // + || ch == '\t') { + System.arraycopy(buf, i + 1, buf, i + 2, end - i - 1); + buf[i] = '\\'; + buf[i + 1] = replaceChars[(int) ch]; + end += 1; + continue; + } + + if (ch == '"' // + || ch == '/' // + || ch == '\\') { + System.arraycopy(buf, i + 1, buf, i + 2, end - i - 1); + buf[i] = '\\'; + buf[i + 1] = ch; + end += 1; + continue; + } + + if (ch < 32) { + System.arraycopy(buf, i + 1, buf, i + 6, end - i - 1); + buf[i] = '\\'; + buf[i + 1] = 'u'; + buf[i + 2] = '0'; + buf[i + 3] = '0'; + buf[i + 4] = IOUtils.ASCII_CHARS[ch * 2]; + buf[i + 5] = IOUtils.ASCII_CHARS[ch * 2 + 1]; + end += 5; + continue; + } + + if (ch >= 127) { + System.arraycopy(buf, i + 1, buf, i + 6, end - i - 1); + buf[i] = '\\'; + buf[i + 1] = 'u'; + buf[i + 2] = IOUtils.DIGITS[(ch >>> 12) & 15]; + buf[i + 3] = IOUtils.DIGITS[(ch >>> 8) & 15]; + buf[i + 4] = IOUtils.DIGITS[(ch >>> 4) & 15]; + buf[i + 5] = IOUtils.DIGITS[ch & 15]; + end += 5; + } + } + + if (seperator != 0) { + buf[count - 2] = '\"'; + buf[count - 1] = seperator; + } else { + buf[count - 1] = '\"'; + } + + return; + } + + int specialCount = 0; + int lastSpecialIndex = -1; + int firstSpecialIndex = -1; + char lastSpecial = '\0'; + if (checkSpecial) { + for (int i = start; i < end; ++i) { + char ch = buf[i]; + + if (ch == '\u2028') { + specialCount++; + lastSpecialIndex = i; + lastSpecial = ch; + newcount += 4; + + if (firstSpecialIndex == -1) { + firstSpecialIndex = i; + } + continue; + } + + if (ch >= ']') { + if (ch >= 0x7F && ch <= 0xA0) { + if (firstSpecialIndex == -1) { + firstSpecialIndex = i; + } + + specialCount++; + lastSpecialIndex = i; + lastSpecial = ch; + newcount += 4; + } + continue; + } + + if (isSpecial(ch, this.features)) { + specialCount++; + lastSpecialIndex = i; + lastSpecial = ch; + + if (ch < IOUtils.specicalFlags_doubleQuotes.length // + && IOUtils.specicalFlags_doubleQuotes[ch] == 4 // + ) { + newcount += 4; + } + + if (firstSpecialIndex == -1) { + firstSpecialIndex = i; + } + } + } + + if (specialCount > 0) { + newcount += specialCount; + if (newcount > buf.length) { + expandCapacity(newcount); + } + count = newcount; + + if (specialCount == 1) { + if (lastSpecial == '\u2028') { + int srcPos = lastSpecialIndex + 1; + int destPos = lastSpecialIndex + 6; + int LengthOfCopy = end - lastSpecialIndex - 1; + System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy); + buf[lastSpecialIndex] = '\\'; + buf[++lastSpecialIndex] = 'u'; + buf[++lastSpecialIndex] = '2'; + buf[++lastSpecialIndex] = '0'; + buf[++lastSpecialIndex] = '2'; + buf[++lastSpecialIndex] = '8'; + } else { + final char ch = lastSpecial; + if (ch < IOUtils.specicalFlags_doubleQuotes.length // + && IOUtils.specicalFlags_doubleQuotes[ch] == 4) { + int srcPos = lastSpecialIndex + 1; + int destPos = lastSpecialIndex + 6; + int LengthOfCopy = end - lastSpecialIndex - 1; + System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy); + + int bufIndex = lastSpecialIndex; + buf[bufIndex++] = '\\'; + buf[bufIndex++] = 'u'; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; + } else { + int srcPos = lastSpecialIndex + 1; + int destPos = lastSpecialIndex + 2; + int LengthOfCopy = end - lastSpecialIndex - 1; + System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy); + buf[lastSpecialIndex] = '\\'; + buf[++lastSpecialIndex] = replaceChars[(int) ch]; + } + } + } else if (specialCount > 1) { + int textIndex = firstSpecialIndex - start; + int bufIndex = firstSpecialIndex; + for (int i = textIndex; i < text.length(); ++i) { + char ch = text.charAt(i); + + if (ch < IOUtils.specicalFlags_doubleQuotes.length // + && IOUtils.specicalFlags_doubleQuotes[ch] != 0 // + || (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) { + buf[bufIndex++] = '\\'; + if (IOUtils.specicalFlags_doubleQuotes[ch] == 4) { + buf[bufIndex++] = 'u'; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; + end += 5; + } else { + buf[bufIndex++] = replaceChars[(int) ch]; + end++; + } + } else { + if (ch == '\u2028') { + buf[bufIndex++] = '\\'; + buf[bufIndex++] = 'u'; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; + end += 5; + } else { + buf[bufIndex++] = ch; + } + } + } + } + } + } + + if (seperator != 0) { + buf[count - 2] = '\"'; + buf[count - 1] = seperator; + } else { + buf[count - 1] = '\"'; + } + } + + public void writeFieldNull(char seperator, String name) { + write(seperator); + writeFieldName(name); + writeNull(); + } + + public void writeFieldEmptyList(char seperator, String key) { + write(seperator); + writeFieldName(key); + write("[]"); + } + + public void writeFieldNullString(char seperator, String name) { + write(seperator); + writeFieldName(name); + if (isEnabled(SerializerFeature.WriteNullStringAsEmpty)) { + writeString(""); + } else { + writeNull(); + } + } + + public void writeFieldNullBoolean(char seperator, String name) { + write(seperator); + writeFieldName(name); + if (isEnabled(SerializerFeature.WriteNullBooleanAsFalse)) { + write("false"); + } else { + writeNull(); + } + } + + public void writeFieldNullList(char seperator, String name) { + write(seperator); + writeFieldName(name); + if (isEnabled(SerializerFeature.WriteNullListAsEmpty)) { + write("[]"); + } else { + writeNull(); + } + } + + public void writeFieldNullNumber(char seperator, String name) { + write(seperator); + writeFieldName(name); + if (isEnabled(SerializerFeature.WriteNullNumberAsZero)) { + write('0'); + } else { + writeNull(); + } + } + + public void writeFieldValue(char seperator, String name, char value) { + write(seperator); + writeFieldName(name); + if (value == 0) { + writeString("\u0000"); + } else { + writeString(Character.toString(value)); + } + } + + public void writeFieldValue(char seperator, String name, boolean value) { + + char keySeperator = isEnabled(SerializerFeature.UseSingleQuotes) ? '\'' : '"'; + + int intSize = value ? 4 : 5; + + int nameLen = name.length(); + int newcount = count + nameLen + 4 + intSize; + if (newcount > buf.length) { + if (writer != null) { + write(seperator); + writeString(name); + write(':'); + write(value); + return; + } + expandCapacity(newcount); + } + + int start = count; + count = newcount; + + buf[start] = seperator; + + int nameEnd = start + nameLen + 1; + + buf[start + 1] = keySeperator; + + name.getChars(0, nameLen, buf, start + 2); + + buf[nameEnd + 1] = keySeperator; + + if (value) { + System.arraycopy(":true".toCharArray(), 0, buf, nameEnd + 2, 5); + } else { + System.arraycopy(":false".toCharArray(), 0, buf, nameEnd + 2, 6); + } + } + + public void write(boolean value) { + if (value) { + write("true"); + } else { + write("false"); + } + } + + public void writeFieldValue(char seperator, String name, int value) { + if (value == Integer.MIN_VALUE || (!isEnabled(SerializerFeature.QuoteFieldNames))) { + writeFieldValue1(seperator, name, value); + return; + } + + char keySeperator = isEnabled(SerializerFeature.UseSingleQuotes) ? '\'' : '"'; + + int intSize = (value < 0) ? IOUtils.stringSize(-value) + 1 : IOUtils.stringSize(value); + + int nameLen = name.length(); + int newcount = count + nameLen + 4 + intSize; + if (newcount > buf.length) { + if (writer != null) { + writeFieldValue1(seperator, name, value); + return; + } + expandCapacity(newcount); + } + + int start = count; + count = newcount; + + buf[start] = seperator; + + int nameEnd = start + nameLen + 1; + + buf[start + 1] = keySeperator; + + name.getChars(0, nameLen, buf, start + 2); + + buf[nameEnd + 1] = keySeperator; + buf[nameEnd + 2] = ':'; + + IOUtils.getChars(value, count, buf); + } + + public void writeFieldValue1(char seperator, String name, int value) { + write(seperator); + writeFieldName(name); + writeInt(value); + } + + public void writeFieldValue(char seperator, String name, long value) { + if (value == Long.MIN_VALUE || (!isEnabled(SerializerFeature.QuoteFieldNames))) { + writeFieldValue1(seperator, name, value); + return; + } + + char keySeperator = isEnabled(SerializerFeature.UseSingleQuotes) ? '\'' : '"'; + + int intSize = (value < 0) ? IOUtils.stringSize(-value) + 1 : IOUtils.stringSize(value); + + int nameLen = name.length(); + int newcount = count + nameLen + 4 + intSize; + if (newcount > buf.length) { + if (writer != null) { + write(seperator); + writeFieldName(name); + writeLong(value); + return; + } + expandCapacity(newcount); + } + + int start = count; + count = newcount; + + buf[start] = seperator; + + int nameEnd = start + nameLen + 1; + + buf[start + 1] = keySeperator; + + name.getChars(0, nameLen, buf, start + 2); + + buf[nameEnd + 1] = keySeperator; + buf[nameEnd + 2] = ':'; + + IOUtils.getChars(value, count, buf); + } + + public void writeFieldValue1(char seperator, String name, long value) { + write(seperator); + writeFieldName(name); + writeLong(value); + } + + public void writeFieldValue(char seperator, String name, float value) { + write(seperator); + writeFieldName(name); + if (value == 0) { + write('0'); + } else if (Float.isNaN(value)) { + writeNull(); + } else if (Float.isInfinite(value)) { + writeNull(); + } else { + String text = Float.toString(value); + if (text.endsWith(".0")) { + text = text.substring(0, text.length() - 2); + } + write(text); + } + } + + public void writeFieldValue(char seperator, String name, double value) { + write(seperator); + writeFieldName(name); + if (value == 0) { + write('0'); + } else if (Double.isNaN(value)) { + writeNull(); + } else if (Double.isInfinite(value)) { + writeNull(); + } else { + String text = Double.toString(value); + if (text.endsWith(".0")) { + text = text.substring(0, text.length() - 2); + } + write(text); + } + } + + public void writeFieldValue(char seperator, String name, String value) { + if (isEnabled(SerializerFeature.QuoteFieldNames)) { + if (isEnabled(SerializerFeature.UseSingleQuotes)) { + write(seperator); + writeFieldName(name); + if (value == null) { + writeNull(); + } else { + writeString(value); + } + } else { + if (isEnabled(SerializerFeature.BrowserCompatible)) { + write(seperator); + writeStringWithDoubleQuote(name, ':'); + writeStringWithDoubleQuote(value, (char) 0); + } else { + writeFieldValueStringWithDoubleQuote(seperator, name, value, true); + } + } + } else { + write(seperator); + writeFieldName(name); + if (value == null) { + writeNull(); + } else { + writeString(value); + } + } + } + + private void writeFieldValueStringWithDoubleQuote(char seperator, String name, String value, boolean checkSpecial) { + int nameLen = name.length(); + int valueLen; + + int newcount = count; + + if (value == null) { + valueLen = 4; + newcount += nameLen + 8; + } else { + valueLen = value.length(); + newcount += nameLen + valueLen + 6; + } + + if (newcount > buf.length) { + if (writer != null) { + write(seperator); + writeStringWithDoubleQuote(name, ':', checkSpecial); + writeStringWithDoubleQuote(value, (char) 0, checkSpecial); + return; + } + expandCapacity(newcount); + } + + buf[count] = seperator; + + int nameStart = count + 2; + int nameEnd = nameStart + nameLen; + + buf[count + 1] = '\"'; + name.getChars(0, nameLen, buf, nameStart); + + count = newcount; + + buf[nameEnd] = '\"'; + + int index = nameEnd + 1; + buf[index++] = ':'; + + if (value == null) { + buf[index++] = 'n'; + buf[index++] = 'u'; + buf[index++] = 'l'; + buf[index++] = 'l'; + return; + } + + buf[index++] = '"'; + + int valueStart = index; + int valueEnd = valueStart + valueLen; + + value.getChars(0, valueLen, buf, valueStart); + + if (checkSpecial && !isEnabled(SerializerFeature.DisableCheckSpecialChar)) { + int specialCount = 0; + int lastSpecialIndex = -1; + int firstSpecialIndex = -1; + char lastSpecial = '\0'; + + for (int i = valueStart; i < valueEnd; ++i) { + char ch = buf[i]; + + if (ch == '\u2028') { + specialCount++; + lastSpecialIndex = i; + lastSpecial = ch; + newcount += 4; + + if (firstSpecialIndex == -1) { + firstSpecialIndex = i; + } + continue; + } + + if (ch >= ']') { + if (ch >= 0x7F && ch <= 0xA0) { + if (firstSpecialIndex == -1) { + firstSpecialIndex = i; + } + + specialCount++; + lastSpecialIndex = i; + lastSpecial = ch; + newcount += 4; + } + + continue; + } + + if (isSpecial(ch, this.features)) { + specialCount++; + lastSpecialIndex = i; + lastSpecial = ch; + + if (ch < IOUtils.specicalFlags_doubleQuotes.length // + && IOUtils.specicalFlags_doubleQuotes[ch] == 4 // + ) { + newcount += 4; + } + + if (firstSpecialIndex == -1) { + firstSpecialIndex = i; + } + } + } + + if (specialCount > 0) { + newcount += specialCount; + if (newcount > buf.length) { + expandCapacity(newcount); + } + count = newcount; + + if (specialCount == 1) { + if (lastSpecial == '\u2028') { + int srcPos = lastSpecialIndex + 1; + int destPos = lastSpecialIndex + 6; + int LengthOfCopy = valueEnd - lastSpecialIndex - 1; + System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy); + buf[lastSpecialIndex] = '\\'; + buf[++lastSpecialIndex] = 'u'; + buf[++lastSpecialIndex] = '2'; + buf[++lastSpecialIndex] = '0'; + buf[++lastSpecialIndex] = '2'; + buf[++lastSpecialIndex] = '8'; + } else { + final char ch = lastSpecial; + if (ch < IOUtils.specicalFlags_doubleQuotes.length // + && IOUtils.specicalFlags_doubleQuotes[ch] == 4) { + int srcPos = lastSpecialIndex + 1; + int destPos = lastSpecialIndex + 6; + int LengthOfCopy = valueEnd - lastSpecialIndex - 1; + System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy); + + int bufIndex = lastSpecialIndex; + buf[bufIndex++] = '\\'; + buf[bufIndex++] = 'u'; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; + } else { + int srcPos = lastSpecialIndex + 1; + int destPos = lastSpecialIndex + 2; + int LengthOfCopy = valueEnd - lastSpecialIndex - 1; + System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy); + buf[lastSpecialIndex] = '\\'; + buf[++lastSpecialIndex] = replaceChars[(int) ch]; + } + } + } else if (specialCount > 1) { + int textIndex = firstSpecialIndex - valueStart; + int bufIndex = firstSpecialIndex; + for (int i = textIndex; i < value.length(); ++i) { + char ch = value.charAt(i); + + if (ch < IOUtils.specicalFlags_doubleQuotes.length // + && IOUtils.specicalFlags_doubleQuotes[ch] != 0 // + || (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) { + buf[bufIndex++] = '\\'; + if (IOUtils.specicalFlags_doubleQuotes[ch] == 4) { + buf[bufIndex++] = 'u'; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; + valueEnd += 5; + } else { + buf[bufIndex++] = replaceChars[(int) ch]; + valueEnd++; + } + } else { + if (ch == '\u2028') { + buf[bufIndex++] = '\\'; + buf[bufIndex++] = 'u'; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15]; + buf[bufIndex++] = IOUtils.DIGITS[ch & 15]; + valueEnd += 5; + } else { + buf[bufIndex++] = ch; + } + } + } + } + } + } + + buf[count - 1] = '\"'; + } + + final static boolean isSpecial(char ch, int features) { + // if (ch > ']') { + // return false; + // } + + if (ch == ' ') { + return false; + } + + if (ch == '/' && SerializerFeature.isEnabled(features, SerializerFeature.WriteSlashAsSpecial)) { + return true; + } + + if (ch > '#' && ch != '\\') { + return false; + } + + if (ch <= 0x1F || ch == '\\' || ch == '"') { + return true; + } + + return false; + } + + // writeStringWithSingleQuote + + public void writeFieldValue(char seperator, String name, Enum value) { + if (value == null) { + write(seperator); + writeFieldName(name); + writeNull(); + return; + } + + if (isEnabled(SerializerFeature.WriteEnumUsingToString)) { + if (isEnabled(SerializerFeature.UseSingleQuotes)) { + writeFieldValue(seperator, name, value.name()); + } else { + writeFieldValueStringWithDoubleQuote(seperator, name, value.name(), false); + return; + } + + // writeStringWithDoubleQuote + } else { + writeFieldValue(seperator, name, value.ordinal()); + } + } + + public void writeFieldValue(char seperator, String name, BigDecimal value) { + write(seperator); + writeFieldName(name); + if (value == null) { + writeNull(); + } else { + write(value.toString()); + } + } + + public void writeString(String text, char seperator) { + if (isEnabled(SerializerFeature.UseSingleQuotes)) { + writeStringWithSingleQuote(text); + write(seperator); + } else { + writeStringWithDoubleQuote(text, seperator); + } + } + + public void writeString(String text) { + if (isEnabled(SerializerFeature.UseSingleQuotes)) { + writeStringWithSingleQuote(text); + } else { + writeStringWithDoubleQuote(text, (char) 0); + } + } + + private void writeStringWithSingleQuote(String text) { + if (text == null) { + int newcount = count + 4; + if (newcount > buf.length) { + expandCapacity(newcount); + } + "null".getChars(0, 4, buf, count); + count = newcount; + return; + } + + int len = text.length(); + int newcount = count + len + 2; + if (newcount > buf.length) { + if (writer != null) { + write('\''); + for (int i = 0; i < text.length(); ++i) { + char ch = text.charAt(i); + if (ch <= 13 || ch == '\\' || ch == '\'' // + || (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) { + write('\\'); + write(replaceChars[(int) ch]); + } else { + write(ch); + } + } + write('\''); + return; + } + expandCapacity(newcount); + } + + int start = count + 1; + int end = start + len; + + buf[count] = '\''; + text.getChars(0, len, buf, start); + count = newcount; + + int specialCount = 0; + int lastSpecialIndex = -1; + char lastSpecial = '\0'; + for (int i = start; i < end; ++i) { + char ch = buf[i]; + if (ch <= 13 || ch == '\\' || ch == '\'' // + || (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) { + specialCount++; + lastSpecialIndex = i; + lastSpecial = ch; + } + } + + newcount += specialCount; + if (newcount > buf.length) { + expandCapacity(newcount); + } + count = newcount; + + if (specialCount == 1) { + System.arraycopy(buf, lastSpecialIndex + 1, buf, lastSpecialIndex + 2, end - lastSpecialIndex - 1); + buf[lastSpecialIndex] = '\\'; + buf[++lastSpecialIndex] = replaceChars[(int) lastSpecial]; + } else if (specialCount > 1) { + System.arraycopy(buf, lastSpecialIndex + 1, buf, lastSpecialIndex + 2, end - lastSpecialIndex - 1); + buf[lastSpecialIndex] = '\\'; + buf[++lastSpecialIndex] = replaceChars[(int) lastSpecial]; + end++; + for (int i = lastSpecialIndex - 2; i >= start; --i) { + char ch = buf[i]; + + if (ch <= 13 || ch == '\\' || ch == '\'' // + || (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) { + System.arraycopy(buf, i + 1, buf, i + 2, end - i - 1); + buf[i] = '\\'; + buf[i + 1] = replaceChars[(int) ch]; + end++; + } + } + } + + buf[count - 1] = '\''; + } + + public void writeFieldName(String key) { + writeFieldName(key, false); + } + + public void writeFieldName(String key, boolean checkSpecial) { + if (key == null) { + write("null:"); + return; + } + + if (isEnabled(SerializerFeature.UseSingleQuotes)) { + if (isEnabled(SerializerFeature.QuoteFieldNames)) { + writeStringWithSingleQuote(key); + write(':'); + } else { + writeKeyWithSingleQuoteIfHasSpecial(key); + } + } else { + if (isEnabled(SerializerFeature.QuoteFieldNames)) { + writeStringWithDoubleQuote(key, ':', checkSpecial); + } else { + writeKeyWithDoubleQuoteIfHasSpecial(key); + } + } + } + + private void writeKeyWithDoubleQuoteIfHasSpecial(String text) { + final byte[] specicalFlags_doubleQuotes = IOUtils.specicalFlags_doubleQuotes; + + int len = text.length(); + int newcount = count + len + 1; + if (newcount > buf.length) { + if (writer != null) { + if (len == 0) { + write('"'); + write('"'); + write(':'); + return; + } + + boolean hasSpecial = false; + for (int i = 0; i < len; ++i) { + char ch = text.charAt(i); + if (ch < specicalFlags_doubleQuotes.length && specicalFlags_doubleQuotes[ch] != 0) { + hasSpecial = true; + break; + } + } + + if (hasSpecial) { + write('"'); + } + for (int i = 0; i < len; ++i) { + char ch = text.charAt(i); + if (ch < specicalFlags_doubleQuotes.length && specicalFlags_doubleQuotes[ch] != 0) { + write('\\'); + write(replaceChars[(int) ch]); + } else { + write(ch); + } + } + if (hasSpecial) { + write('"'); + } + write(':'); + return; + } + expandCapacity(newcount); + } + + if (len == 0) { + int newCount = count + 3; + if (newCount > buf.length) { + expandCapacity(count + 3); + } + buf[count++] = '"'; + buf[count++] = '"'; + buf[count++] = ':'; + return; + } + + int start = count; + int end = start + len; + + text.getChars(0, len, buf, start); + count = newcount; + + boolean hasSpecial = false; + + for (int i = start; i < end; ++i) { + char ch = buf[i]; + if (ch < specicalFlags_doubleQuotes.length && specicalFlags_doubleQuotes[ch] != 0) { + if (!hasSpecial) { + newcount += 3; + if (newcount > buf.length) { + expandCapacity(newcount); + } + count = newcount; + + System.arraycopy(buf, i + 1, buf, i + 3, end - i - 1); + System.arraycopy(buf, 0, buf, 1, i); + buf[start] = '"'; + buf[++i] = '\\'; + buf[++i] = replaceChars[(int) ch]; + end += 2; + buf[count - 2] = '"'; + + hasSpecial = true; + } else { + newcount++; + if (newcount > buf.length) { + expandCapacity(newcount); + } + count = newcount; + + System.arraycopy(buf, i + 1, buf, i + 2, end - i); + buf[i] = '\\'; + buf[++i] = replaceChars[(int) ch]; + end++; + } + } + } + + buf[count - 1] = ':'; + } + + private void writeKeyWithSingleQuoteIfHasSpecial(String text) { + final byte[] specicalFlags_singleQuotes = IOUtils.specicalFlags_singleQuotes; + + int len = text.length(); + int newcount = count + len + 1; + if (newcount > buf.length) { + if (writer != null) { + if (len == 0) { + write('\''); + write('\''); + write(':'); + return; + } + + boolean hasSpecial = false; + for (int i = 0; i < len; ++i) { + char ch = text.charAt(i); + if (ch < specicalFlags_singleQuotes.length && specicalFlags_singleQuotes[ch] != 0) { + hasSpecial = true; + break; + } + } + + if (hasSpecial) { + write('\''); + } + for (int i = 0; i < len; ++i) { + char ch = text.charAt(i); + if (ch < specicalFlags_singleQuotes.length && specicalFlags_singleQuotes[ch] != 0) { + write('\\'); + write(replaceChars[(int) ch]); + } else { + write(ch); + } + } + if (hasSpecial) { + write('\''); + } + write(':'); + return; + } + + expandCapacity(newcount); + } + + if (len == 0) { + int newCount = count + 3; + if (newCount > buf.length) { + expandCapacity(count + 3); + } + buf[count++] = '\''; + buf[count++] = '\''; + buf[count++] = ':'; + return; + } + + int start = count; + int end = start + len; + + text.getChars(0, len, buf, start); + count = newcount; + + boolean hasSpecial = false; + + for (int i = start; i < end; ++i) { + char ch = buf[i]; + if (ch < specicalFlags_singleQuotes.length && specicalFlags_singleQuotes[ch] != 0) { + if (!hasSpecial) { + newcount += 3; + if (newcount > buf.length) { + expandCapacity(newcount); + } + count = newcount; + + System.arraycopy(buf, i + 1, buf, i + 3, end - i - 1); + System.arraycopy(buf, 0, buf, 1, i); + buf[start] = '\''; + buf[++i] = '\\'; + buf[++i] = replaceChars[(int) ch]; + end += 2; + buf[count - 2] = '\''; + + hasSpecial = true; + } else { + newcount++; + if (newcount > buf.length) { + expandCapacity(newcount); + } + count = newcount; + + System.arraycopy(buf, i + 1, buf, i + 2, end - i); + buf[i] = '\\'; + buf[++i] = replaceChars[(int) ch]; + end++; + } + } + } + + buf[newcount - 1] = ':'; + } + + public void flush() { + if (writer == null) { + return; + } + + try { + writer.write(buf, 0, count); + writer.flush(); + } catch (IOException e) { + throw new JSONException(e.getMessage(), e); + } + count = 0; + } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java b/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java old mode 100644 new mode 100755 index c657ddf3dc..3c2b045a79 --- a/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java +++ b/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java @@ -1,89 +1,166 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.serializer; - -/** - * @author wenshao - */ -public enum SerializerFeature { - QuoteFieldNames, - /** - * - */ - UseSingleQuotes, - /** - * - */ - WriteMapNullValue, - /** - * - */ - WriteEnumUsingToString, - /** - * - */ - UseISO8601DateFormat, - /** - * @since 1.1 - */ - WriteNullListAsEmpty, - /** - * @since 1.1 - */ - WriteNullStringAsEmpty, - /** - * @since 1.1 - */ - WriteNullNumberAsZero, - /** - * @since 1.1 - */ - WriteNullBooleanAsFalse, - /** - * @since 1.1 - */ - SkipTransientField, - /** - * @since 1.1 - */ - SortField, - /** - * @since 1.1.1 - */ - WriteTabAsSpecial, - /** - * @since 1.1.2 - */ - PrettyFormat, - /** - * @since 1.1.2 - */ - WriteClassName; - - private SerializerFeature(){ - mask = (1 << ordinal()); - } - - private final int mask; - - public final int getMask() { - return mask; - } - - public static boolean isEnabled(int features, SerializerFeature feature) { - return (features & feature.getMask()) != 0; - } -} +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public enum SerializerFeature { + QuoteFieldNames, + /** + * + */ + UseSingleQuotes, + /** + * + */ + WriteMapNullValue, + /** + * + */ + WriteEnumUsingToString, + /** + * + */ + UseISO8601DateFormat, + /** + * @since 1.1 + */ + WriteNullListAsEmpty, + /** + * @since 1.1 + */ + WriteNullStringAsEmpty, + /** + * @since 1.1 + */ + WriteNullNumberAsZero, + /** + * @since 1.1 + */ + WriteNullBooleanAsFalse, + /** + * @since 1.1 + */ + SkipTransientField, + /** + * @since 1.1 + */ + SortField, + /** + * @since 1.1.1 + */ + @Deprecated + WriteTabAsSpecial, + /** + * @since 1.1.2 + */ + PrettyFormat, + /** + * @since 1.1.2 + */ + WriteClassName, + + /** + * @since 1.1.6 + */ + DisableCircularReferenceDetect, + + /** + * @since 1.1.9 + */ + WriteSlashAsSpecial, + + /** + * @since 1.1.10 + */ + BrowserCompatible, + + /** + * @since 1.1.14 + */ + WriteDateUseDateFormat, + + /** + * @since 1.1.15 + */ + NotWriteRootClassName, + + /** + * @since 1.1.19 + */ + DisableCheckSpecialChar, + + /** + * @since 1.1.35 + */ + BeanToArray, + + /** + * @since 1.1.37 + */ + WriteNonStringKeyAsString, + + /** + * @since 1.1.42 + */ + NotWriteDefaultValue + ; + + private SerializerFeature(){ + mask = (1 << ordinal()); + } + + private final int mask; + + public final int getMask() { + return mask; + } + + public static boolean isEnabled(int features, SerializerFeature feature) { + return (features & feature.getMask()) != 0; + } + + public static boolean isEnabled(int features, int fieaturesB, SerializerFeature feature) { + int mask = feature.getMask(); + + return (features & mask) != 0 || (fieaturesB & mask) != 0; + } + + public static int config(int features, SerializerFeature feature, boolean state) { + if (state) { + features |= feature.getMask(); + } else { + features &= ~feature.getMask(); + } + + return features; + } + + public static int of(SerializerFeature[] features) { + if (features == null) { + return 0; + } + + int value = 0; + + for (SerializerFeature feature: features) { + value |= feature.getMask(); + } + + return value; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/ShortArraySerializer.java b/src/main/java/com/alibaba/fastjson/serializer/ShortArraySerializer.java old mode 100644 new mode 100755 index 5218d9c4d9..4fca15c11b --- a/src/main/java/com/alibaba/fastjson/serializer/ShortArraySerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ShortArraySerializer.java @@ -16,15 +16,16 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class ShortArraySerializer implements ObjectSerializer { public static ShortArraySerializer instance = new ShortArraySerializer(); - public final void write(JSONSerializer serializer, Object object) throws IOException { + public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.getWriter(); if (object == null) { @@ -37,6 +38,13 @@ public final void write(JSONSerializer serializer, Object object) throws IOExcep } short[] array = (short[]) object; - out.writeShortArray(array); + out.write('['); + for (int i = 0; i < array.length; ++i) { + if (i != 0) { + out.write(','); + } + out.writeInt(array[i]); + } + out.write(']'); } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/SimpleDateFormatSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/SimpleDateFormatSerializer.java old mode 100644 new mode 100755 index a6c84215ef..7bd192d74b --- a/src/main/java/com/alibaba/fastjson/serializer/SimpleDateFormatSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/SimpleDateFormatSerializer.java @@ -1,6 +1,7 @@ package com.alibaba.fastjson.serializer; import java.io.IOException; +import java.lang.reflect.Type; import java.text.SimpleDateFormat; import java.util.Date; @@ -12,7 +13,7 @@ public SimpleDateFormatSerializer(String pattern){ this.pattern = pattern; } - public void write(JSONSerializer serializer, Object object) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { if (object == null) { serializer.getWriter().writeNull(); return; diff --git a/src/main/java/com/alibaba/fastjson/serializer/SimplePropertyPreFilter.java b/src/main/java/com/alibaba/fastjson/serializer/SimplePropertyPreFilter.java new file mode 100755 index 0000000000..d7b54695a0 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/SimplePropertyPreFilter.java @@ -0,0 +1,73 @@ +package com.alibaba.fastjson.serializer; + +import java.util.HashSet; +import java.util.Set; + +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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. + */ +public class SimplePropertyPreFilter implements PropertyPreFilter { + + private final Class clazz; + private final Set includes = new HashSet(); + private final Set excludes = new HashSet(); + + public SimplePropertyPreFilter(String... properties){ + this(null, properties); + } + + public SimplePropertyPreFilter(Class clazz, String... properties){ + super(); + this.clazz = clazz; + for (String item : properties) { + if (item != null) { + this.includes.add(item); + } + } + } + + public Class getClazz() { + return clazz; + } + + public Set getIncludes() { + return includes; + } + + public Set getExcludes() { + return excludes; + } + + public boolean apply(JSONSerializer serializer, Object source, String name) { + if (source == null) { + return true; + } + + if (clazz != null && !clazz.isInstance(source)) { + return true; + } + + if (this.excludes.contains(name)) { + return false; + } + + if (includes.size() == 0 || includes.contains(name)) { + return true; + } + + return false; + } + +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/StringCodec.java b/src/main/java/com/alibaba/fastjson/serializer/StringCodec.java new file mode 100755 index 0000000000..1eb4525c5d --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/StringCodec.java @@ -0,0 +1,84 @@ +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public class StringCodec implements ObjectSerializer, ObjectDeserializer { + + public static StringCodec instance = new StringCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + write(serializer, (String) object); + } + + public void write(JSONSerializer serializer, String value) { + SerializeWriter out = serializer.getWriter(); + + if (value == null) { + if (out.isEnabled(SerializerFeature.WriteNullStringAsEmpty)) { + out.writeString(""); + } else { + out.writeNull(); + } + return; + } + + out.writeString(value); + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + return (T) deserialze(parser); + } + + @SuppressWarnings("unchecked") + public static T deserialze(DefaultJSONParser parser) { + final JSONLexer lexer = parser.getLexer(); + if (lexer.token() == JSONToken.LITERAL_STRING) { + String val = lexer.stringVal(); + lexer.nextToken(JSONToken.COMMA); + return (T) val; + } + + if (lexer.token() == JSONToken.LITERAL_INT) { + String val = lexer.numberString(); + lexer.nextToken(JSONToken.COMMA); + return (T) val; + } + + Object value = parser.parse(); + + if (value == null) { + return null; + } + + return (T) value.toString(); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/StringSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/StringSerializer.java deleted file mode 100644 index 08cdcf5d8d..0000000000 --- a/src/main/java/com/alibaba/fastjson/serializer/StringSerializer.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.serializer; - -import java.io.IOException; - -/** - * @author wenshao - */ -public class StringSerializer implements ObjectSerializer { - - public static StringSerializer instance = new StringSerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - write(serializer, (String) object); - } - - public void write(JSONSerializer serializer, String value) { - SerializeWriter out = serializer.getWriter(); - - if (value == null) { - if (out.isEnabled(SerializerFeature.WriteNullStringAsEmpty)) { - out.writeString(""); - } else { - out.writeNull(); - } - return; - } - - out.writeString(value); - } -} diff --git a/src/main/java/com/alibaba/fastjson/serializer/TimeZoneCodec.java b/src/main/java/com/alibaba/fastjson/serializer/TimeZoneCodec.java new file mode 100755 index 0000000000..ef33153737 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/TimeZoneCodec.java @@ -0,0 +1,41 @@ +package com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.TimeZone; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +public class TimeZoneCodec implements ObjectSerializer, ObjectDeserializer { + + public final static TimeZoneCodec instance = new TimeZoneCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + if (object == null) { + serializer.writeNull(); + return; + } + + TimeZone timeZone = (TimeZone) object; + serializer.write(timeZone.getID()); + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + + String id = (String) parser.parse(); + + if (id == null) { + return null; + } + + return (T) TimeZone.getTimeZone(id); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } + +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/TimeZoneSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/TimeZoneSerializer.java deleted file mode 100644 index 74de843747..0000000000 --- a/src/main/java/com/alibaba/fastjson/serializer/TimeZoneSerializer.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.alibaba.fastjson.serializer; - -import java.io.IOException; -import java.util.TimeZone; - -public class TimeZoneSerializer implements ObjectSerializer { - - public final static TimeZoneSerializer instance = new TimeZoneSerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - if (object == null) { - serializer.writeNull(); - return; - } - - TimeZone timeZone = (TimeZone) object; - serializer.write(timeZone.getID()); - } - -} diff --git a/src/main/java/com/alibaba/fastjson/serializer/URICodec.java b/src/main/java/com/alibaba/fastjson/serializer/URICodec.java new file mode 100755 index 0000000000..74004947c0 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/URICodec.java @@ -0,0 +1,58 @@ +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.net.URI; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public class URICodec implements ObjectSerializer, ObjectDeserializer { + + public final static URICodec instance = new URICodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + if (object == null) { + serializer.writeNull(); + return; + } + + URI uri = (URI) object; + serializer.write(uri.toString()); + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + + String uri = (String) parser.parse(); + + if (uri == null) { + return null; + } + + return (T) URI.create(uri); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/URLCodec.java b/src/main/java/com/alibaba/fastjson/serializer/URLCodec.java new file mode 100755 index 0000000000..16db31237b --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/URLCodec.java @@ -0,0 +1,63 @@ +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.net.MalformedURLException; +import java.net.URL; + +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public class URLCodec implements ObjectSerializer, ObjectDeserializer { + + public final static URLCodec instance = new URLCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + if (object == null) { + serializer.writeNull(); + return; + } + + serializer.write(object.toString()); + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + + String url = (String) parser.parse(); + + if (url == null) { + return null; + } + + try { + return (T) new URL(url); + } catch (MalformedURLException e) { + throw new JSONException("create url error", e); + } + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/UUIDCodec.java b/src/main/java/com/alibaba/fastjson/serializer/UUIDCodec.java new file mode 100755 index 0000000000..b50c652cfa --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/serializer/UUIDCodec.java @@ -0,0 +1,55 @@ +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.UUID; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +public class UUIDCodec implements ObjectSerializer, ObjectDeserializer { + + public final static UUIDCodec instance = new UUIDCodec(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + if (object == null) { + serializer.writeNull(); + return; + } + + UUID uid = (UUID) object; + serializer.write(uid.toString()); + } + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + + String name = (String) parser.parse(); + + if (name == null) { + return null; + } + + return (T) UUID.fromString(name); + } + + public int getFastMatchToken() { + return JSONToken.LITERAL_STRING; + } +} diff --git a/src/main/java/com/alibaba/fastjson/serializer/UUIDSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/UUIDSerializer.java deleted file mode 100644 index 2621d87418..0000000000 --- a/src/main/java/com/alibaba/fastjson/serializer/UUIDSerializer.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.alibaba.fastjson.serializer; - -import java.io.IOException; -import java.util.UUID; - -public class UUIDSerializer implements ObjectSerializer { - - public final static UUIDSerializer instance = new UUIDSerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - if (object == null) { - serializer.writeNull(); - return; - } - - UUID uid = (UUID) object; - serializer.write(uid.toString()); - } - -} diff --git a/src/main/java/com/alibaba/fastjson/serializer/ValueFilter.java b/src/main/java/com/alibaba/fastjson/serializer/ValueFilter.java old mode 100644 new mode 100755 index 5ca67a6c11..317c38aa3f --- a/src/main/java/com/alibaba/fastjson/serializer/ValueFilter.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ValueFilter.java @@ -1,6 +1,21 @@ +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.serializer; -public interface ValueFilter { +public interface ValueFilter extends SerializeFilter { - Object process(Object source, String name, Object value); + Object process(Object object, String name, Object value); } diff --git a/src/main/java/com/alibaba/fastjson/support/odps/udf/CodecCheck.java b/src/main/java/com/alibaba/fastjson/support/odps/udf/CodecCheck.java new file mode 100644 index 0000000000..5d9b4b7b09 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/odps/udf/CodecCheck.java @@ -0,0 +1,41 @@ +package com.alibaba.fastjson.support.odps.udf; + +import com.alibaba.fastjson.JSON; +import com.aliyun.odps.udf.UDF; + +public class CodecCheck extends UDF { + + public String evaluate() throws Exception { + A a = new A(); + a.setId(123); + a.setName("xxx"); + + String text = JSON.toJSONString(a); + JSON.parseObject(text, A.class); + + return "ok"; + } + + public static class A { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONArrayAdd.java b/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONArrayAdd.java new file mode 100644 index 0000000000..cd2fb2d8f2 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONArrayAdd.java @@ -0,0 +1,39 @@ +package com.alibaba.fastjson.support.odps.udf; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.aliyun.odps.udf.UDF; + + +public class JSONArrayAdd extends UDF { + public JSONArrayAdd(){ + SerializeConfig.getGlobalInstance().setAsmEnable(false); + ParserConfig.getGlobalInstance().setAsmEnable(false); + } + + public String evaluate(String jsonString, String path, String... values) throws Exception { + Object json = JSON.parse(jsonString); + JSONPath.arrayAdd(json, path, values); + return JSON.toJSONString(json); + } + + public String evaluate(String jsonString, String path, Long... values) throws Exception { + Object json = JSON.parse(jsonString); + JSONPath.arrayAdd(json, path, values); + return JSON.toJSONString(json); + } + + public String evaluate(String jsonString, String path, Boolean... values) throws Exception { + Object json = JSON.parse(jsonString); + JSONPath.arrayAdd(json, path, values); + return JSON.toJSONString(json); + } + + public String evaluate(String jsonString, String path, Double... values) throws Exception { + Object json = JSON.parse(jsonString); + JSONPath.arrayAdd(json, path, values); + return JSON.toJSONString(json); + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONContains.java b/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONContains.java new file mode 100644 index 0000000000..909aebd879 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONContains.java @@ -0,0 +1,18 @@ +package com.alibaba.fastjson.support.odps.udf; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.aliyun.odps.udf.UDF; + +public class JSONContains extends UDF { + + public JSONContains(){ + SerializeConfig.getGlobalInstance().setAsmEnable(false); + } + + public Boolean evaluate(String jsonString, String path) throws Exception { + Object json = JSON.parse(jsonString); + return JSONPath.contains(json, path); + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONContainsValue.java b/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONContainsValue.java new file mode 100644 index 0000000000..97d8a3a734 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONContainsValue.java @@ -0,0 +1,33 @@ +package com.alibaba.fastjson.support.odps.udf; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.aliyun.odps.udf.UDF; + +public class JSONContainsValue extends UDF { + + public JSONContainsValue(){ + SerializeConfig.getGlobalInstance().setAsmEnable(false); + } + + public Boolean evaluate(String jsonString, String path, String value) throws Exception { + Object json = JSON.parse(jsonString); + return JSONPath.containsValue(json, path, value); + } + + public Boolean evaluate(String jsonString, String path, Long value) throws Exception { + Object json = JSON.parse(jsonString); + return JSONPath.containsValue(json, path, value); + } + + public Boolean evaluate(String jsonString, String path, Boolean value) throws Exception { + Object json = JSON.parse(jsonString); + return JSONPath.containsValue(json, path, value); + } + + public Boolean evaluate(String jsonString, String path, Double value) throws Exception { + Object json = JSON.parse(jsonString); + return JSONPath.containsValue(json, path, value); + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONExtract.java b/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONExtract.java new file mode 100644 index 0000000000..e2ed4a501b --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONExtract.java @@ -0,0 +1,18 @@ +package com.alibaba.fastjson.support.odps.udf; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.aliyun.odps.udf.UDF; + +public class JSONExtract extends UDF { + public JSONExtract(){ + SerializeConfig.getGlobalInstance().setAsmEnable(false); + } + + public String evaluate(String jsonString, String path) throws Exception { + Object json = JSON.parse(jsonString); + Object result = JSONPath.eval(json, path); + return JSON.toJSONString(result); + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONSet.java b/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONSet.java new file mode 100644 index 0000000000..5aad30b8be --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONSet.java @@ -0,0 +1,39 @@ +package com.alibaba.fastjson.support.odps.udf; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.aliyun.odps.udf.UDF; + + +public class JSONSet extends UDF { + public JSONSet(){ + SerializeConfig.getGlobalInstance().setAsmEnable(false); + ParserConfig.getGlobalInstance().setAsmEnable(false); + } + + public String evaluate(String jsonString, String path, String value) throws Exception { + Object json = JSON.parse(jsonString); + JSONPath.set(json, path, value); + return JSON.toJSONString(json); + } + + public String evaluate(String jsonString, String path, Long value) throws Exception { + Object json = JSON.parse(jsonString); + JSONPath.set(json, path, value); + return JSON.toJSONString(json); + } + + public String evaluate(String jsonString, String path, Boolean value) throws Exception { + Object json = JSON.parse(jsonString); + JSONPath.set(json, path, value); + return JSON.toJSONString(json); + } + + public String evaluate(String jsonString, String path, Double value) throws Exception { + Object json = JSON.parse(jsonString); + JSONPath.set(json, path, value); + return JSON.toJSONString(json); + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONSize.java b/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONSize.java new file mode 100644 index 0000000000..215ce6c602 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONSize.java @@ -0,0 +1,18 @@ +package com.alibaba.fastjson.support.odps.udf; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.aliyun.odps.udf.UDF; + + +public class JSONSize extends UDF { + public JSONSize(){ + SerializeConfig.getGlobalInstance().setAsmEnable(false); + } + + public Long evaluate(String jsonString, String path) throws Exception { + Object json = JSON.parse(jsonString); + return Long.valueOf(JSONPath.size(json, path)); + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONTuple.java b/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONTuple.java new file mode 100644 index 0000000000..551a794357 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/odps/udf/JSONTuple.java @@ -0,0 +1,33 @@ +package com.alibaba.fastjson.support.odps.udf; + +import java.util.Arrays; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONPath; +import com.aliyun.odps.udf.OdpsType; +import com.aliyun.odps.udf.UDFException; +import com.aliyun.odps.udf.UDTF; + +@SuppressWarnings("deprecation") +public class JSONTuple extends UDTF { + + public OdpsType[] initialize(OdpsType[] signature) throws Exception { + OdpsType[] types = new OdpsType[signature.length - 1]; + Arrays.fill(types, OdpsType.STRING); + return types; + } + + @Override + public void process(Object[] args) throws UDFException { + String jsonStr = (String) args[0]; + Object object = JSON.parse(jsonStr); + + Object[] values = new Object[args.length - 1]; + for (int i = 1; i < args.length; ++i) { + String path = (String) args[i]; + Object value = JSONPath.eval(object, path); + values[i - 1] = JSON.toJSONString(value); + } + this.forward(values); + } +} diff --git a/src/main/java/com/alibaba/fastjson/support/spring/FastJsonHttpMessageConverter.java b/src/main/java/com/alibaba/fastjson/support/spring/FastJsonHttpMessageConverter.java new file mode 100755 index 0000000000..c1649e8212 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/spring/FastJsonHttpMessageConverter.java @@ -0,0 +1,86 @@ +package com.alibaba.fastjson.support.spring; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.charset.Charset; + +import org.springframework.http.HttpInputMessage; +import org.springframework.http.HttpOutputMessage; +import org.springframework.http.MediaType; +import org.springframework.http.converter.AbstractHttpMessageConverter; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.http.converter.HttpMessageNotWritableException; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class FastJsonHttpMessageConverter extends AbstractHttpMessageConverter { + + public final static Charset UTF8 = Charset.forName("UTF-8"); + + private Charset charset = UTF8; + + private SerializerFeature[] features = new SerializerFeature[0]; + + public FastJsonHttpMessageConverter(){ + super(new MediaType("application", "json", UTF8), new MediaType("application", "*+json", UTF8)); + } + + @Override + protected boolean supports(Class clazz) { + return true; + } + + public Charset getCharset() { + return this.charset; + } + + public void setCharset(Charset charset) { + this.charset = charset; + } + + public SerializerFeature[] getFeatures() { + return features; + } + + public void setFeatures(SerializerFeature... features) { + this.features = features; + } + + @Override + protected Object readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException, + HttpMessageNotReadableException { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + InputStream in = inputMessage.getBody(); + + byte[] buf = new byte[1024]; + for (;;) { + int len = in.read(buf); + if (len == -1) { + break; + } + + if (len > 0) { + baos.write(buf, 0, len); + } + } + + byte[] bytes = baos.toByteArray(); + return JSON.parseObject(bytes, 0, bytes.length, charset.newDecoder(), clazz); + } + + @Override + protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, + HttpMessageNotWritableException { + + OutputStream out = outputMessage.getBody(); + String text = JSON.toJSONString(obj, features); + byte[] bytes = text.getBytes(charset); + out.write(bytes); + } + +} diff --git a/src/main/java/com/alibaba/fastjson/support/spring/FastJsonJsonView.java b/src/main/java/com/alibaba/fastjson/support/spring/FastJsonJsonView.java new file mode 100755 index 0000000000..283b9f318f --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/support/spring/FastJsonJsonView.java @@ -0,0 +1,151 @@ +package com.alibaba.fastjson.support.spring; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import org.springframework.util.CollectionUtils; +import org.springframework.validation.BindingResult; +import org.springframework.web.servlet.view.AbstractView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * @author libinsong1204@gmail.com + */ +public class FastJsonJsonView extends AbstractView { + + public static final String DEFAULT_CONTENT_TYPE = "application/json"; + + public final static Charset UTF8 = Charset.forName("UTF-8"); + + private Charset charset = UTF8; + + private SerializerFeature[] serializerFeatures = new SerializerFeature[0]; + + private Set renderedAttributes; + + private boolean disableCaching = true; + + private boolean updateContentLength = false; + + private boolean extractValueFromSingleKeyModel = false; + + public FastJsonJsonView(){ + setContentType(DEFAULT_CONTENT_TYPE); + setExposePathVariables(false); + } + + public void setRenderedAttributes(Set renderedAttributes) { + this.renderedAttributes = renderedAttributes; + } + + @Deprecated + public void setSerializerFeature(SerializerFeature... features) { + this.setFeatures(features); + } + + public Charset getCharset() { + return this.charset; + } + + public void setCharset(Charset charset) { + this.charset = charset; + } + + public SerializerFeature[] getFeatures() { + return serializerFeatures; + } + + public void setFeatures(SerializerFeature... features) { + this.serializerFeatures = features; + } + + public boolean isExtractValueFromSingleKeyModel() { + return extractValueFromSingleKeyModel; + } + + public void setExtractValueFromSingleKeyModel(boolean extractValueFromSingleKeyModel) { + this.extractValueFromSingleKeyModel = extractValueFromSingleKeyModel; + } + + @Override + protected void renderMergedOutputModel(Map model, HttpServletRequest request, + HttpServletResponse response) throws Exception { + Object value = filterModel(model); + + String text = JSON.toJSONString(value, serializerFeatures); + byte[] bytes = text.getBytes(charset); + + OutputStream stream = this.updateContentLength ? createTemporaryOutputStream() : response.getOutputStream(); + stream.write(bytes); + + if (this.updateContentLength) { + writeToResponse(response, (ByteArrayOutputStream) stream); + } + } + + @Override + protected void prepareResponse(HttpServletRequest request, HttpServletResponse response) { + setResponseContentType(request, response); + response.setCharacterEncoding(UTF8.name()); + if (this.disableCaching) { + response.addHeader("Pragma", "no-cache"); + response.addHeader("Cache-Control", "no-cache, no-store, max-age=0"); + response.addDateHeader("Expires", 1L); + } + } + + /** + * Disables caching of the generated JSON. + *

+ * Default is {@code true}, which will prevent the client from caching the generated JSON. + */ + public void setDisableCaching(boolean disableCaching) { + this.disableCaching = disableCaching; + } + + /** + * Whether to update the 'Content-Length' header of the response. When set to {@code true}, the response is buffered + * in order to determine the content length and set the 'Content-Length' header of the response. + *

+ * The default setting is {@code false}. + */ + public void setUpdateContentLength(boolean updateContentLength) { + this.updateContentLength = updateContentLength; + } + + /** + * Filters out undesired attributes from the given model. The return value can be either another {@link Map}, or a + * single value object. + *

+ * Default implementation removes {@link BindingResult} instances and entries not included in the + * {@link #setRenderedAttributes(Set) renderedAttributes} property. + * + * @param model the model, as passed on to {@link #renderMergedOutputModel} + * @return the object to be rendered + */ + protected Object filterModel(Map model) { + Map result = new HashMap(model.size()); + Set renderedAttributes = !CollectionUtils.isEmpty(this.renderedAttributes) ? this.renderedAttributes : model.keySet(); + for (Map.Entry entry : model.entrySet()) { + if (!(entry.getValue() instanceof BindingResult) && renderedAttributes.contains(entry.getKey())) { + result.put(entry.getKey(), entry.getValue()); + } + } + if(extractValueFromSingleKeyModel){ + if(result.size() == 1){ + for(Map.Entry entry : result.entrySet()){ + return entry.getValue(); + } + } + } + return result; + } + +} \ No newline at end of file diff --git a/src/main/java/com/alibaba/fastjson/util/ASMClassLoader.java b/src/main/java/com/alibaba/fastjson/util/ASMClassLoader.java old mode 100644 new mode 100755 index e6b2015f63..6f5f30b12e --- a/src/main/java/com/alibaba/fastjson/util/ASMClassLoader.java +++ b/src/main/java/com/alibaba/fastjson/util/ASMClassLoader.java @@ -1,25 +1,66 @@ package com.alibaba.fastjson.util; -import com.alibaba.fastjson.JSONException; +import java.security.PrivilegedAction; + +import com.alibaba.fastjson.JSON; public class ASMClassLoader extends ClassLoader { + private static java.security.ProtectionDomain DOMAIN; + + static { + DOMAIN = (java.security.ProtectionDomain) java.security.AccessController.doPrivileged(new PrivilegedAction() { + + public Object run() { + return ASMClassLoader.class.getProtectionDomain(); + } + }); + } + public ASMClassLoader(){ - super(ASMClassLoader.class.getClassLoader()); + super(getParentClassLoader()); + } + + public ASMClassLoader(ClassLoader parent){ + super (parent); + } + + static ClassLoader getParentClassLoader() { + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + if (contextClassLoader != null) { + try { + contextClassLoader.loadClass(JSON.class.getName()); + return contextClassLoader; + } catch (ClassNotFoundException e) { + // skip + } + } + return JSON.class.getClassLoader(); } public Class defineClassPublic(String name, byte[] b, int off, int len) throws ClassFormatError { - Class clazz = defineClass(name, b, off, len, null); + Class clazz = defineClass(name, b, off, len, DOMAIN); return clazz; } - public static Class forName(String className) { - try { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - return classLoader.loadClass(className); - } catch (ClassNotFoundException e) { - throw new JSONException("class nout found : " + className); + public boolean isExternalClass(Class clazz) { + ClassLoader classLoader = clazz.getClassLoader(); + + if (classLoader == null) { + return false; } + + ClassLoader current = this; + while (current != null) { + if (current == classLoader) { + return false; + } + + current = current.getParent(); + } + + return true; } + } diff --git a/src/main/java/com/alibaba/fastjson/util/ASMUtils.java b/src/main/java/com/alibaba/fastjson/util/ASMUtils.java old mode 100644 new mode 100755 index f2bc22d289..d3c45e7476 --- a/src/main/java/com/alibaba/fastjson/util/ASMUtils.java +++ b/src/main/java/com/alibaba/fastjson/util/ASMUtils.java @@ -1,8 +1,32 @@ package com.alibaba.fastjson.util; +import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.Collection; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; public class ASMUtils { + + public static boolean isAndroid(String vmName) { + if (vmName == null) { // default is false + return false; + } + + String lowerVMName = vmName.toLowerCase(); + + return lowerVMName.contains("dalvik") // + || lowerVMName.contains("lemur") // aliyun-vm name + ; + } + + public static boolean isAndroid() { + return isAndroid(System.getProperty("java.vm.name")); + } public static String getDesc(Method method) { StringBuffer buf = new StringBuffer(); @@ -31,12 +55,7 @@ public static String getType(Class parameterType) { return "[" + getDesc(parameterType.getComponentType()); } else { if (!parameterType.isPrimitive()) { - String clsName = parameterType.getCanonicalName(); - - if (parameterType.isMemberClass()) { - int lastDot = clsName.lastIndexOf("."); - clsName = clsName.substring(0, lastDot) + "$" + clsName.substring(lastDot + 1); - } + String clsName = parameterType.getName(); return clsName.replaceAll("\\.", "/"); } else { return getPrimitiveLetter(parameterType); @@ -68,4 +87,62 @@ public static String getPrimitiveLetter(Class type) { throw new IllegalStateException("Type: " + type.getCanonicalName() + " is not a primitive type"); } + public static Type getMethodType(Class clazz, String methodName) { + try { + Method method = clazz.getMethod(methodName); + + return method.getGenericReturnType(); + } catch (Exception ex) { + return null; + } + } + + public static Type getFieldType(Class clazz, String fieldName) { + try { + Field field = clazz.getField(fieldName); + + return field.getGenericType(); + } catch (Exception ex) { + return null; + } + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static void parseArray(Collection collection, // + ObjectDeserializer deser, // + DefaultJSONParser parser, // + Type type, // + Object fieldName) { + + final JSONLexer lexer = parser.getLexer(); + if (lexer.token() == JSONToken.NULL) { + lexer.nextToken(JSONToken.COMMA); + } + + parser.accept(JSONToken.LBRACKET, JSONToken.LBRACKET); + + int index = 0; + for (;;) { + Object item = deser.deserialze(parser, type, index); + collection.add(item); + index++; + if (lexer.token() == JSONToken.COMMA) { + lexer.nextToken(JSONToken.LBRACKET); + } else { + break; + } + } + parser.accept(JSONToken.RBRACKET, JSONToken.COMMA); + } + + public static boolean checkName(String name) { + for (int i = 0; i < name.length(); ++i) { + char c = name.charAt(i); + if (c < '\001' || c > '\177') { + return false; + } + } + + return true; + } } diff --git a/src/main/java/com/alibaba/fastjson/util/Base64.java b/src/main/java/com/alibaba/fastjson/util/Base64.java new file mode 100755 index 0000000000..7d7ce9aa81 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/util/Base64.java @@ -0,0 +1,210 @@ +package com.alibaba.fastjson.util; + +import java.util.Arrays; + +/** + * + * @version 2.2 + * @author Mikael Grev Date: 2004-aug-02 Time: 11:31:11 + */ + +public class Base64 { + + public static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); + public static final int[] IA = new int[256]; + static { + Arrays.fill(IA, -1); + for (int i = 0, iS = CA.length; i < iS; i++) + IA[CA[i]] = i; + IA['='] = 0; + } + + /** + * Decodes a BASE64 encoded char array that is known to be resonably well formatted. The method is about twice as + * fast as #decode(char[]). The preconditions are:
+ * + The array must have a line length of 76 chars OR no line separators at all (one line).
+ * + Line separator must be "\r\n", as specified in RFC 2045 + The array must not contain illegal characters within + * the encoded string
+ * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.
+ * + * @param chars The source array. Length 0 will return an empty array. null will throw an exception. + * @return The decoded array of bytes. May be of length 0. + */ + public final static byte[] decodeFast(char[] chars, int offset, int charsLen) { + // Check special case + if (charsLen == 0) { + return new byte[0]; + } + + int sIx = offset, eIx = offset + charsLen - 1; // Start and end index after trimming. + + // Trim illegal chars from start + while (sIx < eIx && IA[chars[sIx]] < 0) + sIx++; + + // Trim illegal chars from end + while (eIx > 0 && IA[chars[eIx]] < 0) + eIx--; + + // get the padding count (=) (0, 1 or 2) + int pad = chars[eIx] == '=' ? (chars[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end. + int cCnt = eIx - sIx + 1; // Content count including possible separators + int sepCnt = charsLen > 76 ? (chars[76] == '\r' ? cCnt / 78 : 0) << 1 : 0; + + int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes + byte[] bytes = new byte[len]; // Preallocate byte[] of exact length + + // Decode all but the last 0 - 2 bytes. + int d = 0; + for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) { + // Assemble three bytes into an int from four "valid" characters. + int i = IA[chars[sIx++]] << 18 | IA[chars[sIx++]] << 12 | IA[chars[sIx++]] << 6 | IA[chars[sIx++]]; + + // Add the bytes + bytes[d++] = (byte) (i >> 16); + bytes[d++] = (byte) (i >> 8); + bytes[d++] = (byte) i; + + // If line separator, jump over it. + if (sepCnt > 0 && ++cc == 19) { + sIx += 2; + cc = 0; + } + } + + if (d < len) { + // Decode last 1-3 bytes (incl '=') into 1-3 bytes + int i = 0; + for (int j = 0; sIx <= eIx - pad; j++) + i |= IA[chars[sIx++]] << (18 - j * 6); + + for (int r = 16; d < len; r -= 8) + bytes[d++] = (byte) (i >> r); + } + + return bytes; + } + + public final static byte[] decodeFast(String chars, int offset, int charsLen) { + // Check special case + if (charsLen == 0) { + return new byte[0]; + } + + int sIx = offset, eIx = offset + charsLen - 1; // Start and end index after trimming. + + // Trim illegal chars from start + while (sIx < eIx && IA[chars.charAt(sIx)] < 0) + sIx++; + + // Trim illegal chars from end + while (eIx > 0 && IA[chars.charAt(eIx)] < 0) + eIx--; + + // get the padding count (=) (0, 1 or 2) + int pad = chars.charAt(eIx) == '=' ? (chars.charAt(eIx - 1) == '=' ? 2 : 1) : 0; // Count '=' at end. + int cCnt = eIx - sIx + 1; // Content count including possible separators + int sepCnt = charsLen > 76 ? (chars.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0; + + int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes + byte[] bytes = new byte[len]; // Preallocate byte[] of exact length + + // Decode all but the last 0 - 2 bytes. + int d = 0; + for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) { + // Assemble three bytes into an int from four "valid" characters. + int i = IA[chars.charAt(sIx++)] << 18 | IA[chars.charAt(sIx++)] << 12 | IA[chars.charAt(sIx++)] << 6 | IA[chars.charAt(sIx++)]; + + // Add the bytes + bytes[d++] = (byte) (i >> 16); + bytes[d++] = (byte) (i >> 8); + bytes[d++] = (byte) i; + + // If line separator, jump over it. + if (sepCnt > 0 && ++cc == 19) { + sIx += 2; + cc = 0; + } + } + + if (d < len) { + // Decode last 1-3 bytes (incl '=') into 1-3 bytes + int i = 0; + for (int j = 0; sIx <= eIx - pad; j++) + i |= IA[chars.charAt(sIx++)] << (18 - j * 6); + + for (int r = 16; d < len; r -= 8) + bytes[d++] = (byte) (i >> r); + } + + return bytes; + } + + /** + * Decodes a BASE64 encoded string that is known to be resonably well formatted. The method is about twice as fast + * as decode(String). The preconditions are:
+ * + The array must have a line length of 76 chars OR no line separators at all (one line).
+ * + Line separator must be "\r\n", as specified in RFC 2045 + The array must not contain illegal characters within + * the encoded string
+ * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.
+ * + * @param s The source string. Length 0 will return an empty array. null will throw an exception. + * @return The decoded array of bytes. May be of length 0. + */ + public final static byte[] decodeFast(String s) { + // Check special case + int sLen = s.length(); + if (sLen == 0) { + return new byte[0]; + } + + int sIx = 0, eIx = sLen - 1; // Start and end index after trimming. + + // Trim illegal chars from start + while (sIx < eIx && IA[s.charAt(sIx) & 0xff] < 0) + sIx++; + + // Trim illegal chars from end + while (eIx > 0 && IA[s.charAt(eIx) & 0xff] < 0) + eIx--; + + // get the padding count (=) (0, 1 or 2) + int pad = s.charAt(eIx) == '=' ? (s.charAt(eIx - 1) == '=' ? 2 : 1) : 0; // Count '=' at end. + int cCnt = eIx - sIx + 1; // Content count including possible separators + int sepCnt = sLen > 76 ? (s.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0; + + int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + // Decode all but the last 0 - 2 bytes. + int d = 0; + for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) { + // Assemble three bytes into an int from four "valid" characters. + int i = IA[s.charAt(sIx++)] << 18 | IA[s.charAt(sIx++)] << 12 | IA[s.charAt(sIx++)] << 6 + | IA[s.charAt(sIx++)]; + + // Add the bytes + dArr[d++] = (byte) (i >> 16); + dArr[d++] = (byte) (i >> 8); + dArr[d++] = (byte) i; + + // If line separator, jump over it. + if (sepCnt > 0 && ++cc == 19) { + sIx += 2; + cc = 0; + } + } + + if (d < len) { + // Decode last 1-3 bytes (incl '=') into 1-3 bytes + int i = 0; + for (int j = 0; sIx <= eIx - pad; j++) + i |= IA[s.charAt(sIx++)] << (18 - j * 6); + + for (int r = 16; d < len; r -= 8) + dArr[d++] = (byte) (i >> r); + } + + return dArr; + } +} diff --git a/src/main/java/com/alibaba/fastjson/util/DeserializeBeanInfo.java b/src/main/java/com/alibaba/fastjson/util/DeserializeBeanInfo.java new file mode 100755 index 0000000000..81a9aaa276 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/util/DeserializeBeanInfo.java @@ -0,0 +1,426 @@ +package com.alibaba.fastjson.util; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class DeserializeBeanInfo { + + private final Class clazz; + private Constructor defaultConstructor; + private Constructor creatorConstructor; + private Method factoryMethod; + + private final List fieldList = new ArrayList(); + private final List sortedFieldList = new ArrayList(); + + private int parserFeatures = 0; + + public DeserializeBeanInfo(Class clazz){ + super(); + this.clazz = clazz; + this.parserFeatures = TypeUtils.getParserFeatures(clazz); + } + + public Constructor getDefaultConstructor() { + return defaultConstructor; + } + + public void setDefaultConstructor(Constructor defaultConstructor) { + this.defaultConstructor = defaultConstructor; + } + + public Constructor getCreatorConstructor() { + return creatorConstructor; + } + + public void setCreatorConstructor(Constructor createConstructor) { + this.creatorConstructor = createConstructor; + } + + public Method getFactoryMethod() { + return factoryMethod; + } + + public void setFactoryMethod(Method factoryMethod) { + this.factoryMethod = factoryMethod; + } + + public Class getClazz() { + return clazz; + } + + public List getFieldList() { + return fieldList; + } + + public List getSortedFieldList() { + return sortedFieldList; + } + + public FieldInfo getField(String propertyName) { + for (FieldInfo item : this.fieldList) { + if (item.getName().equals(propertyName)) { + return item; + } + } + + return null; + } + + public boolean add(FieldInfo field) { + for (FieldInfo item : this.fieldList) { + if (item.getName().equals(field.getName())) { + if (item.isGetOnly() && !field.isGetOnly()) { + continue; + } + + if (item.getFieldClass().isAssignableFrom(field.getFieldClass())) { + fieldList.remove(item); + break; + } + + return false; + } + } + fieldList.add(field); + sortedFieldList.add(field); + Collections.sort(sortedFieldList); + + return true; + } + + public static DeserializeBeanInfo computeSetters(Class clazz, Type type) { + DeserializeBeanInfo beanInfo = new DeserializeBeanInfo(clazz); + + Constructor defaultConstructor = getDefaultConstructor(clazz); + if (defaultConstructor != null) { + TypeUtils.setAccessible(defaultConstructor); + beanInfo.setDefaultConstructor(defaultConstructor); + } else if (defaultConstructor == null && !(clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers()))) { + Constructor creatorConstructor = getCreatorConstructor(clazz); + if (creatorConstructor != null) { + TypeUtils.setAccessible(creatorConstructor); + beanInfo.setCreatorConstructor(creatorConstructor); + + for (int i = 0; i < creatorConstructor.getParameterTypes().length; ++i) { + Annotation[] paramAnnotations = creatorConstructor.getParameterAnnotations()[i]; + JSONField fieldAnnotation = null; + for (Annotation paramAnnotation : paramAnnotations) { + if (paramAnnotation instanceof JSONField) { + fieldAnnotation = (JSONField) paramAnnotation; + break; + } + } + if (fieldAnnotation == null) { + throw new JSONException("illegal json creator"); + } + + Class fieldClass = creatorConstructor.getParameterTypes()[i]; + Type fieldType = creatorConstructor.getGenericParameterTypes()[i]; + Field field = TypeUtils.getField(clazz, fieldAnnotation.name()); + final int ordinal = fieldAnnotation.ordinal(); + final int serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); + FieldInfo fieldInfo = new FieldInfo(fieldAnnotation.name(), clazz, fieldClass, fieldType, field, + ordinal, serialzeFeatures); + beanInfo.add(fieldInfo); + } + return beanInfo; + } + + Method factoryMethod = getFactoryMethod(clazz); + if (factoryMethod != null) { + TypeUtils.setAccessible(factoryMethod); + beanInfo.setFactoryMethod(factoryMethod); + + for (int i = 0; i < factoryMethod.getParameterTypes().length; ++i) { + Annotation[] paramAnnotations = factoryMethod.getParameterAnnotations()[i]; + JSONField fieldAnnotation = null; + for (Annotation paramAnnotation : paramAnnotations) { + if (paramAnnotation instanceof JSONField) { + fieldAnnotation = (JSONField) paramAnnotation; + break; + } + } + if (fieldAnnotation == null) { + throw new JSONException("illegal json creator"); + } + + Class fieldClass = factoryMethod.getParameterTypes()[i]; + Type fieldType = factoryMethod.getGenericParameterTypes()[i]; + Field field = TypeUtils.getField(clazz, fieldAnnotation.name()); + final int ordinal = fieldAnnotation.ordinal(); + final int serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); + FieldInfo fieldInfo = new FieldInfo(fieldAnnotation.name() // + , clazz // + , fieldClass // + , fieldType // + , field // + , ordinal // + , serialzeFeatures); + beanInfo.add(fieldInfo); + } + return beanInfo; + } + + throw new JSONException("default constructor not found. " + clazz); + } + + for (Method method : clazz.getMethods()) { + int ordinal = 0, serialzeFeatures = 0; + String methodName = method.getName(); + if (methodName.length() < 4) { + continue; + } + + if (Modifier.isStatic(method.getModifiers())) { + continue; + } + + // support builder set + if (!(method.getReturnType().equals(Void.TYPE) || method.getReturnType().equals(clazz))) { + continue; + } + + if (method.getParameterTypes().length != 1) { + continue; + } + + JSONField annotation = method.getAnnotation(JSONField.class); + + if (annotation == null) { + annotation = TypeUtils.getSupperMethodAnnotation(clazz, method); + } + + if (annotation != null) { + if (!annotation.deserialize()) { + continue; + } + + ordinal = annotation.ordinal(); + serialzeFeatures = SerializerFeature.of(annotation.serialzeFeatures()); + + if (annotation.name().length() != 0) { + String propertyName = annotation.name(); + beanInfo.add(new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures)); + TypeUtils.setAccessible(method); + continue; + } + } + + if (!methodName.startsWith("set")) { + continue; + } + + char c3 = methodName.charAt(3); + + String propertyName; + if (Character.isUpperCase(c3)) { + if (TypeUtils.compatibleWithJavaBean) { + propertyName = TypeUtils.decapitalize(methodName.substring(3)); + } else { + propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4); + } + } else if (c3 == '_') { + propertyName = methodName.substring(4); + } else if (c3 == 'f') { + propertyName = methodName.substring(3); + } else if (methodName.length() >= 5 && Character.isUpperCase(methodName.charAt(4))) { + propertyName = TypeUtils.decapitalize(methodName.substring(3)); + } else { + continue; + } + + Field field = TypeUtils.getField(clazz, propertyName); + if (field == null && method.getParameterTypes()[0] == boolean.class) { + String isFieldName = "is" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1); + field = TypeUtils.getField(clazz, isFieldName); + } + + if (field != null) { + JSONField fieldAnnotation = field.getAnnotation(JSONField.class); + + if (fieldAnnotation != null) { + ordinal = fieldAnnotation.ordinal(); + serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); + + if (fieldAnnotation.name().length() != 0) { + propertyName = fieldAnnotation.name(); + beanInfo.add(new FieldInfo(propertyName, method, field, clazz, type, ordinal, serialzeFeatures)); + continue; + } + } + + } + + beanInfo.add(new FieldInfo(propertyName, method, null, clazz, type, ordinal, serialzeFeatures)); + TypeUtils.setAccessible(method); + } + + for (Field field : clazz.getFields()) { + if (Modifier.isStatic(field.getModifiers())) { + continue; + } + + boolean contains = false; + for (FieldInfo item : beanInfo.getFieldList()) { + if (item.getName().equals(field.getName())) { + contains = true; + continue; + } + } + + if (contains) { + continue; + } + + int ordinal = 0, serialzeFeatures = 0; + String propertyName = field.getName(); + + JSONField fieldAnnotation = field.getAnnotation(JSONField.class); + + if (fieldAnnotation != null) { + ordinal = fieldAnnotation.ordinal(); + serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); + + if (fieldAnnotation.name().length() != 0) { + propertyName = fieldAnnotation.name(); + } + } + beanInfo.add(new FieldInfo(propertyName, null, field, clazz, type, ordinal, serialzeFeatures)); + } + + for (Method method : clazz.getMethods()) { + String methodName = method.getName(); + if (methodName.length() < 4) { + continue; + } + + if (Modifier.isStatic(method.getModifiers())) { + continue; + } + + if (methodName.startsWith("get") && Character.isUpperCase(methodName.charAt(3))) { + if (method.getParameterTypes().length != 0) { + continue; + } + + if (Collection.class.isAssignableFrom(method.getReturnType()) // + || Map.class.isAssignableFrom(method.getReturnType()) // + || AtomicBoolean.class == method.getReturnType() // + || AtomicInteger.class == method.getReturnType() // + || AtomicLong.class == method.getReturnType() // + ) { + String propertyName; + + JSONField annotation = method.getAnnotation(JSONField.class); + if (annotation != null && annotation.name().length() > 0) { + propertyName = annotation.name(); + } else { + propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4); + } + + FieldInfo fieldInfo = beanInfo.getField(propertyName); + if (fieldInfo != null) { + continue; + } + + beanInfo.add(new FieldInfo(propertyName, method, null, clazz, type)); + TypeUtils.setAccessible(method); + } + } + } + + return beanInfo; + } + + public static Constructor getDefaultConstructor(Class clazz) { + if (Modifier.isAbstract(clazz.getModifiers())) { + return null; + } + + Constructor defaultConstructor = null; + for (Constructor constructor : clazz.getDeclaredConstructors()) { + if (constructor.getParameterTypes().length == 0) { + defaultConstructor = constructor; + break; + } + } + + if (defaultConstructor == null) { + if (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers())) { + for (Constructor constructor : clazz.getDeclaredConstructors()) { + if (constructor.getParameterTypes().length == 1 + && constructor.getParameterTypes()[0].equals(clazz.getDeclaringClass())) { + defaultConstructor = constructor; + break; + } + } + } + } + + return defaultConstructor; + } + + public static Constructor getCreatorConstructor(Class clazz) { + Constructor creatorConstructor = null; + + for (Constructor constructor : clazz.getDeclaredConstructors()) { + JSONCreator annotation = constructor.getAnnotation(JSONCreator.class); + if (annotation != null) { + if (creatorConstructor != null) { + throw new JSONException("multi-json creator"); + } + + creatorConstructor = constructor; + break; + } + } + return creatorConstructor; + } + + public static Method getFactoryMethod(Class clazz) { + Method factoryMethod = null; + + for (Method method : clazz.getDeclaredMethods()) { + if (!Modifier.isStatic(method.getModifiers())) { + continue; + } + + if (!clazz.isAssignableFrom(method.getReturnType())) { + continue; + } + + JSONCreator annotation = method.getAnnotation(JSONCreator.class); + if (annotation != null) { + if (factoryMethod != null) { + throw new JSONException("multi-json creator"); + } + + factoryMethod = method; + break; + } + } + return factoryMethod; + } + + public int getParserFeatures() { + return parserFeatures; + } +} diff --git a/src/main/java/com/alibaba/fastjson/util/FieldInfo.java b/src/main/java/com/alibaba/fastjson/util/FieldInfo.java old mode 100644 new mode 100755 index d318f49304..eeeef5d229 --- a/src/main/java/com/alibaba/fastjson/util/FieldInfo.java +++ b/src/main/java/com/alibaba/fastjson/util/FieldInfo.java @@ -1,9 +1,18 @@ package com.alibaba.fastjson.util; import java.lang.annotation.Annotation; +import java.lang.reflect.Array; import java.lang.reflect.Field; +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.GenericDeclaration; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Member; import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; + +import com.alibaba.fastjson.annotation.JSONField; public class FieldInfo implements Comparable { @@ -11,21 +20,196 @@ public class FieldInfo implements Comparable { private final Method method; private final Field field; + private int ordinal = 0; private final Class fieldClass; private final Type fieldType; + private final Class declaringClass; + private boolean getOnly = false; + private int serialzeFeatures; + + public FieldInfo(String name, Class declaringClass, Class fieldClass, Type fieldType, Field field){ + this(name, declaringClass, fieldClass, fieldType, field, 0, 0); + } + + public FieldInfo(String name, Class declaringClass, Class fieldClass, Type fieldType, Field field, int ordinal, int serialzeFeatures){ + this.name = name; + this.declaringClass = declaringClass; + this.fieldClass = fieldClass; + this.fieldType = fieldType; + this.method = null; + this.field = field; + this.ordinal = ordinal; + this.serialzeFeatures = serialzeFeatures; + if (field != null) { + TypeUtils.setAccessible(field); + } + } + public FieldInfo(String name, Method method, Field field){ + this(name, method, field, null, null); + } + + public FieldInfo(String name, Method method, Field field, int ordinal, int serialzeFeatures){ + this(name, method, field, null, null, ordinal, serialzeFeatures); + } + + public FieldInfo(String name, Method method, Field field, Class clazz, Type type){ + this(name, method, field, clazz, type, 0, 0); + } + + public FieldInfo(String name, Method method, Field field, Class clazz, Type type, int ordinal, int serialzeFeatures){ this.name = name; this.method = method; this.field = field; + this.ordinal = ordinal; + this.serialzeFeatures = serialzeFeatures; + + if (method != null) { + TypeUtils.setAccessible(method); + } - if (method.getParameterTypes().length == 1) { - this.fieldClass = method.getParameterTypes()[0]; - this.fieldType = method.getGenericParameterTypes()[0]; + if (field != null) { + TypeUtils.setAccessible(field); + } + + Type fieldType; + Class fieldClass; + if (method != null) { + if (method.getParameterTypes().length == 1) { + fieldClass = method.getParameterTypes()[0]; + fieldType = method.getGenericParameterTypes()[0]; + } else { + fieldClass = method.getReturnType(); + fieldType = method.getGenericReturnType(); + getOnly = true; + } + this.declaringClass = method.getDeclaringClass(); } else { - this.fieldClass = method.getReturnType(); - this.fieldType = method.getGenericReturnType(); + fieldClass = field.getType(); + fieldType = field.getGenericType(); + this.declaringClass = field.getDeclaringClass(); } + + if (clazz != null && fieldClass == Object.class && fieldType instanceof TypeVariable) { + TypeVariable tv = (TypeVariable) fieldType; + Type genericFieldType = getInheritGenericType(clazz, tv); + if (genericFieldType != null) { + this.fieldClass = TypeUtils.getClass(genericFieldType); + this.fieldType = genericFieldType; + return; + } + } + + Type genericFieldType = getFieldType(clazz, type, fieldType); + + if (genericFieldType != fieldType) { + if (genericFieldType instanceof ParameterizedType) { + fieldClass = TypeUtils.getClass(genericFieldType); + } else if (genericFieldType instanceof Class) { + fieldClass = TypeUtils.getClass(genericFieldType); + } + } + + this.fieldType = genericFieldType; + this.fieldClass = fieldClass; + } + + public static Type getFieldType(Class clazz, Type type, Type fieldType) { + if (clazz == null || type == null) { + return fieldType; + } + + if (fieldType instanceof GenericArrayType) { + GenericArrayType genericArrayType = (GenericArrayType) fieldType; + Type componentType = genericArrayType.getGenericComponentType(); + Type componentTypeX = getFieldType(clazz, type, componentType); + if (componentType != componentTypeX) { + Type fieldTypeX = Array.newInstance(TypeUtils.getClass(componentTypeX), 0).getClass(); + return fieldTypeX; + } + + return fieldType; + } + + if (!TypeUtils.isGenericParamType(type)) { + return fieldType; + } + + if (fieldType instanceof TypeVariable) { + ParameterizedType paramType = (ParameterizedType) TypeUtils.getGenericParamType(type); + Class parameterizedClass = TypeUtils.getClass(paramType); + TypeVariable typeVar = (TypeVariable) fieldType; + + for (int i = 0; i < parameterizedClass.getTypeParameters().length; ++i) { + if (parameterizedClass.getTypeParameters()[i].getName().equals(typeVar.getName())) { + fieldType = paramType.getActualTypeArguments()[i]; + return fieldType; + } + } + } + + if (fieldType instanceof ParameterizedType) { + ParameterizedType parameterizedFieldType = (ParameterizedType) fieldType; + + Type[] arguments = parameterizedFieldType.getActualTypeArguments(); + boolean changed = false; + for (int i = 0; i < arguments.length; ++i) { + Type feildTypeArguement = arguments[i]; + if (feildTypeArguement instanceof TypeVariable) { + TypeVariable typeVar = (TypeVariable) feildTypeArguement; + + if (type instanceof ParameterizedType) { + ParameterizedType parameterizedType = (ParameterizedType) type; + for (int j = 0; j < clazz.getTypeParameters().length; ++j) { + if (clazz.getTypeParameters()[j].getName().equals(typeVar.getName())) { + arguments[i] = parameterizedType.getActualTypeArguments()[j]; + changed = true; + } + } + } + } + } + if (changed) { + fieldType = new ParameterizedTypeImpl(arguments, parameterizedFieldType.getOwnerType(), + parameterizedFieldType.getRawType()); + return fieldType; + } + } + + return fieldType; + } + + public static Type getInheritGenericType(Class clazz, TypeVariable tv) { + Type type = null; + GenericDeclaration gd = tv.getGenericDeclaration(); + do { + type = clazz.getGenericSuperclass(); + if (type == null) { + return null; + } + if (type instanceof ParameterizedType) { + ParameterizedType ptype = (ParameterizedType) type; + if (ptype.getRawType() == gd) { + TypeVariable[] tvs = gd.getTypeParameters(); + Type[] types = ptype.getActualTypeArguments(); + for (int i = 0; i < tvs.length; i++) { + if (tvs[i] == tv) return types[i]; + } + return null; + } + } + clazz = TypeUtils.getClass(type); + } while (type != null); + return null; + } + + public String toString() { + return this.name; + } + + public Class getDeclaringClass() { + return declaringClass; } public Class getFieldClass() { @@ -40,6 +224,19 @@ public String getName() { return name; } + public String gerQualifiedName() { + Member member = getMember(); + return member.getDeclaringClass().getName() + "." + member.getName(); + } + + public Member getMember() { + if (method != null) { + return method; + } else { + return field; + } + } + public Method getMethod() { return method; } @@ -49,12 +246,22 @@ public Field getField() { } public int compareTo(FieldInfo o) { + if (this.ordinal < o.ordinal) { + return -1; + } + + if (this.ordinal > o.ordinal) { + return 1; + } + return this.name.compareTo(o.name); } public T getAnnotation(Class annotationClass) { T annotation = null; - annotation = method.getAnnotation(annotationClass); + if (method != null) { + annotation = method.getAnnotation(annotationClass); + } if (annotation == null) { if (field != null) { @@ -64,4 +271,55 @@ public T getAnnotation(Class annotationClass) { return annotation; } + + public String getFormat() { + String format = null; + JSONField annotation = getAnnotation(JSONField.class); + + if (annotation != null) { + format = annotation.format(); + + if (format.trim().length() == 0) { + format = null; + } + } + return format; + } + + public Object get(Object javaObject) throws IllegalAccessException, InvocationTargetException { + if (method != null) { + Object value = method.invoke(javaObject, new Object[0]); + return value; + } + + return field.get(javaObject); + } + + public void set(Object javaObject, Object value) throws IllegalAccessException, InvocationTargetException { + if (method != null) { + method.invoke(javaObject, new Object[] { value }); + return; + } + + field.set(javaObject, value); + } + + public void setAccessible(boolean flag) throws SecurityException { + if (method != null) { + TypeUtils.setAccessible(method); + return; + } + + TypeUtils.setAccessible(field); + } + + public boolean isGetOnly() { + return getOnly; + } + + + public int getSerialzeFeatures() { + return serialzeFeatures; + } + } diff --git a/src/main/java/com/alibaba/fastjson/util/IOUtils.java b/src/main/java/com/alibaba/fastjson/util/IOUtils.java old mode 100644 new mode 100755 index 3299c817f1..d369bfa5aa --- a/src/main/java/com/alibaba/fastjson/util/IOUtils.java +++ b/src/main/java/com/alibaba/fastjson/util/IOUtils.java @@ -15,6 +15,7 @@ */ package com.alibaba.fastjson.util; +import java.io.Closeable; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; @@ -24,10 +25,128 @@ import com.alibaba.fastjson.JSONException; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class IOUtils { + public final static char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', + 'B', 'C', 'D', 'E', 'F' }; + + public final static boolean[] firstIdentifierFlags = new boolean[256]; + static { + for (char c = 0; c < firstIdentifierFlags.length; ++c) { + if (c >= 'A' && c <= 'Z') { + firstIdentifierFlags[c] = true; + } else if (c >= 'a' && c <= 'z') { + firstIdentifierFlags[c] = true; + } else if (c == '_') { + firstIdentifierFlags[c] = true; + } + } + } + + public final static boolean[] identifierFlags = new boolean[256]; + + static { + for (char c = 0; c < identifierFlags.length; ++c) { + if (c >= 'A' && c <= 'Z') { + identifierFlags[c] = true; + } else if (c >= 'a' && c <= 'z') { + identifierFlags[c] = true; + } else if (c == '_') { + identifierFlags[c] = true; + } else if (c >= '0' && c <= '9') { + identifierFlags[c] = true; + } + } + } + + public final static byte[] specicalFlags_doubleQuotes = new byte[256]; + public final static byte[] specicalFlags_singleQuotes = new byte[256]; + + public final static char[] replaceChars = new char[128]; + static { + specicalFlags_doubleQuotes['\0'] = 4; + specicalFlags_doubleQuotes['\1'] = 4; + specicalFlags_doubleQuotes['\2'] = 4; + specicalFlags_doubleQuotes['\3'] = 4; + specicalFlags_doubleQuotes['\4'] = 4; + specicalFlags_doubleQuotes['\5'] = 4; + specicalFlags_doubleQuotes['\6'] = 4; + specicalFlags_doubleQuotes['\7'] = 4; + specicalFlags_doubleQuotes['\b'] = 1; // 8 + specicalFlags_doubleQuotes['\t'] = 1; // 9 + specicalFlags_doubleQuotes['\n'] = 1; // 10 + specicalFlags_doubleQuotes['\u000B'] = 4; // 11 + specicalFlags_doubleQuotes['\f'] = 1; + specicalFlags_doubleQuotes['\r'] = 1; + specicalFlags_doubleQuotes['\"'] = 1; + specicalFlags_doubleQuotes['\\'] = 1; + + specicalFlags_singleQuotes['\0'] = 4; + specicalFlags_singleQuotes['\1'] = 4; + specicalFlags_singleQuotes['\2'] = 4; + specicalFlags_singleQuotes['\3'] = 4; + specicalFlags_singleQuotes['\4'] = 4; + specicalFlags_singleQuotes['\5'] = 4; + specicalFlags_singleQuotes['\6'] = 4; + specicalFlags_singleQuotes['\7'] = 4; + specicalFlags_singleQuotes['\b'] = 1; // 8 + specicalFlags_singleQuotes['\t'] = 1; // 9 + specicalFlags_singleQuotes['\n'] = 1; // 10 + specicalFlags_singleQuotes['\u000B'] = 4; // 11 + specicalFlags_singleQuotes['\f'] = 1; // 12 + specicalFlags_singleQuotes['\r'] = 1; // 13 + specicalFlags_singleQuotes['\\'] = 1; + specicalFlags_singleQuotes['\''] = 1; + + for (int i = 0x0E; i <= 0x1F; ++i) { + specicalFlags_doubleQuotes[i] = 4; + specicalFlags_singleQuotes[i] = 4; + } + + for (int i = 0x7F; i <= 0xA0; ++i) { + specicalFlags_doubleQuotes[i] = 4; + specicalFlags_singleQuotes[i] = 4; + } + + replaceChars['\0'] = '0'; + replaceChars['\1'] = '1'; + replaceChars['\2'] = '2'; + replaceChars['\3'] = '3'; + replaceChars['\4'] = '4'; + replaceChars['\5'] = '5'; + replaceChars['\6'] = '6'; + replaceChars['\7'] = '7'; + replaceChars['\b'] = 'b'; // 8 + replaceChars['\t'] = 't'; // 9 + replaceChars['\n'] = 'n'; // 10 + replaceChars['\u000B'] = 'v'; // 11 + replaceChars['\f'] = 'f'; // 12 + replaceChars['\r'] = 'r'; // 13 + replaceChars['\"'] = '"'; // 34 + replaceChars['\''] = '\''; // 39 + replaceChars['/'] = '/'; // 47 + replaceChars['\\'] = '\\'; // 92 + } + + public final static char[] ASCII_CHARS = { '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', + '5', '0', '6', '0', '7', '0', '8', '0', '9', '0', 'A', '0', 'B', '0', 'C', '0', 'D', '0', 'E', '0', 'F', + '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', '1', + 'A', '1', 'B', '1', 'C', '1', 'D', '1', 'E', '1', 'F', '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', + '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', '2', 'A', '2', 'B', '2', 'C', '2', 'D', '2', 'E', '2', + 'F', }; + + public static void close(Closeable x) { + if (x != null) { + try { + x.close(); + } catch (Exception e) { + // skip + } + } + } + // Requires positive x public static int stringSize(long x) { long p = 10; @@ -152,34 +271,32 @@ public static void getChars(byte b, int index, char[] buf) { /** * All possible chars for representing a number as a String */ - final static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; + final static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; - final static char[] DigitTens = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '6', '6', '6', '6', '6', '6', '6', '6', - '6', '6', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', }; + final static char[] DigitTens = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '1', + '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3', '3', '3', '3', '3', '3', + '3', '3', '3', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '5', '5', '5', + '5', '5', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '7', '7', '7', '7', '7', '7', '7', '7', '7', + '7', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', }; - final static char[] DigitOnes = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', }; + final static char[] DigitOnes = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', + '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', }; final static int[] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE }; // Requires positive x - static int stringSize(int x) { - for (int i = 0;; i++) - if (x <= sizeTable[i]) return i + 1; - } - - final static int[] byte_len_array = new int[256]; - static { - for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; ++i) { - int size = (i < 0) ? IOUtils.stringSize(-i) + 1 : IOUtils.stringSize(i); - byte_len_array[i & 0xFF] = size; + public static int stringSize(int x) { + for (int i = 0;; i++) { + if (x <= sizeTable[i]) { + return i + 1; + } } } - public static int stringSize(byte i) { - return byte_len_array[i & 0xFF]; - } - public static void decode(CharsetDecoder charsetDecoder, ByteBuffer byteBuf, CharBuffer charByte) { try { CoderResult cr = charsetDecoder.decode(byteBuf, charByte, true); @@ -199,4 +316,22 @@ public static void decode(CharsetDecoder charsetDecoder, ByteBuffer byteBuf, Cha throw new JSONException(x.getMessage(), x); } } + + public static boolean[] whitespaceFlags = new boolean[256]; + static { + whitespaceFlags[' '] = true; + whitespaceFlags['\n'] = true; + whitespaceFlags['\r'] = true; + whitespaceFlags['\t'] = true; + whitespaceFlags['\f'] = true; + whitespaceFlags['\b'] = true; + } + + public static boolean firstIdentifier(char ch) { + return ch < IOUtils.firstIdentifierFlags.length && IOUtils.firstIdentifierFlags[ch]; + } + + public static boolean isIdent(char ch) { + return ch < identifierFlags.length && identifierFlags[ch]; + } } diff --git a/src/main/java/com/alibaba/fastjson/util/IdentityHashMap.java b/src/main/java/com/alibaba/fastjson/util/IdentityHashMap.java old mode 100644 new mode 100755 index b41dfb3e17..79ea63b435 --- a/src/main/java/com/alibaba/fastjson/util/IdentityHashMap.java +++ b/src/main/java/com/alibaba/fastjson/util/IdentityHashMap.java @@ -18,7 +18,7 @@ /** * for concurrent IdentityHashMap * - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ @SuppressWarnings("unchecked") public class IdentityHashMap { @@ -50,12 +50,13 @@ public final V get(K key) { return null; } - public final boolean put(K key, V value) { + public boolean put(K key, V value) { final int hash = System.identityHashCode(key); final int bucket = hash & indexMask; for (Entry entry = buckets[bucket]; entry != null; entry = entry.next) { if (key == entry.key) { + entry.value = value; return true; } } @@ -80,7 +81,7 @@ protected static final class Entry { public final int hashCode; public final K key; - public final V value; + public V value; public final Entry next; diff --git a/src/main/java/com/alibaba/fastjson/util/ParameterizedTypeImpl.java b/src/main/java/com/alibaba/fastjson/util/ParameterizedTypeImpl.java new file mode 100755 index 0000000000..a5cb33fcd4 --- /dev/null +++ b/src/main/java/com/alibaba/fastjson/util/ParameterizedTypeImpl.java @@ -0,0 +1,30 @@ +package com.alibaba.fastjson.util; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +public class ParameterizedTypeImpl implements ParameterizedType { + + private final Type[] actualTypeArguments; + private final Type ownerType; + private final Type rawType; + + public ParameterizedTypeImpl(Type[] actualTypeArguments, Type ownerType, Type rawType){ + this.actualTypeArguments = actualTypeArguments; + this.ownerType = ownerType; + this.rawType = rawType; + } + + public Type[] getActualTypeArguments() { + return actualTypeArguments; + } + + public Type getOwnerType() { + return ownerType; + } + + public Type getRawType() { + return rawType; + } + +} diff --git a/src/main/java/com/alibaba/fastjson/util/ServiceLoader.java b/src/main/java/com/alibaba/fastjson/util/ServiceLoader.java old mode 100644 new mode 100755 index ea50146e6e..b5b77d5b9e --- a/src/main/java/com/alibaba/fastjson/util/ServiceLoader.java +++ b/src/main/java/com/alibaba/fastjson/util/ServiceLoader.java @@ -1,21 +1,27 @@ package com.alibaba.fastjson.util; import java.io.BufferedReader; -import java.io.Closeable; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; +import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; public class ServiceLoader { - private static final String PREFIX = "META-INF/services/"; + private static final String PREFIX = "META-INF/services/"; + + private static final Set loadedUrls = new HashSet(); @SuppressWarnings("unchecked") public static Set load(Class clazz, ClassLoader classLoader) { + if (classLoader == null) { + return Collections.emptySet(); + } + Set services = new HashSet(); String className = clazz.getName(); @@ -27,7 +33,11 @@ public static Set load(Class clazz, ClassLoader classLoader) { Enumeration urls = classLoader.getResources(path); while (urls.hasMoreElements()) { URL url = urls.nextElement(); + if (loadedUrls.contains(url.toString())) { + continue; + } load(url, serviceNames); + loadedUrls.add(url.toString()); } } catch (IOException ex) { // skip @@ -66,17 +76,11 @@ public static void load(URL url, Set set) throws IOException { if (line.length() == 0) { continue; } + set.add(line); } } finally { - close(reader); - close(is); + IOUtils.close(reader); + IOUtils.close(is); } } - - public static void close(Closeable x) throws IOException { - if (x != null) { - x.close(); - } - } - } diff --git a/src/main/java/com/alibaba/fastjson/util/ThreadLocalCache.java b/src/main/java/com/alibaba/fastjson/util/ThreadLocalCache.java old mode 100644 new mode 100755 index 32491bef48..6b8d05d392 --- a/src/main/java/com/alibaba/fastjson/util/ThreadLocalCache.java +++ b/src/main/java/com/alibaba/fastjson/util/ThreadLocalCache.java @@ -1,22 +1,42 @@ package com.alibaba.fastjson.util; +import java.lang.ref.SoftReference; +import java.nio.charset.CharsetDecoder; + public class ThreadLocalCache { - public final static int CHARS_CACH_INIT_SIZE = 1024; // 1k; - public final static int CHARS_CACH_MAX_SIZE = 1024 * 128; // 1k; - private final static ThreadLocal charsBufLocal = new ThreadLocal(); + public final static int CHARS_CACH_INIT_SIZE = 1024; // 1k, 2^10; + public final static int CHARS_CACH_INIT_SIZE_EXP = 10; + public final static int CHARS_CACH_MAX_SIZE = 1024 * 128; // 128k, 2^17; + public final static int CHARS_CACH_MAX_SIZE_EXP = 17; + private final static ThreadLocal> charsBufLocal = new ThreadLocal>(); + + private final static ThreadLocal decoderLocal = new ThreadLocal(); + + public static CharsetDecoder getUTF8Decoder() { + CharsetDecoder decoder = decoderLocal.get(); + if (decoder == null) { + decoder = new UTF8Decoder(); + decoderLocal.set(decoder); + } + return decoder; + } public static void clearChars() { charsBufLocal.set(null); } public static char[] getChars(int length) { - char[] chars = charsBufLocal.get(); + SoftReference ref = charsBufLocal.get(); - if (chars == null) { - chars = allocate(length); + if (ref == null) { + return allocate(length); + } + + char[] chars = ref.get(); - return chars; + if (chars == null) { + return allocate(length); } if (chars.length < length) { @@ -27,50 +47,51 @@ public static char[] getChars(int length) { } private static char[] allocate(int length) { - int allocateLength = getAllocateLength(CHARS_CACH_INIT_SIZE, CHARS_CACH_MAX_SIZE, length); + if(length> CHARS_CACH_MAX_SIZE) { + return new char[length]; + } - if (allocateLength <= CHARS_CACH_MAX_SIZE) { - char[] chars = new char[allocateLength]; - charsBufLocal.set(chars); - return chars; - } - - return new char[length]; + int allocateLength = getAllocateLengthExp(CHARS_CACH_INIT_SIZE_EXP, CHARS_CACH_MAX_SIZE_EXP, length); + char[] chars = new char[allocateLength]; + charsBufLocal.set(new SoftReference(chars)); + return chars; } - private static int getAllocateLength(int init, int max, int length) { - int value = init; - for (;;) { - if (value >= length) { - return value; - } - - value *= 2; - - if (value > max) { - break; - } - } - - return length; + private static int getAllocateLengthExp(int minExp, int maxExp, int length) { + assert (1<= length; +// int max = 1 << maxExp; +// if(length>= max) { +// return length; +// } + int part = length >>> minExp; + if(part <= 0) { + return 1<< minExp; + } + return 1 << 32 - Integer.numberOfLeadingZeros(length-1); } // ///////// - public final static int BYTES_CACH_INIT_SIZE = 1024; // 1k; - public final static int BYTeS_CACH_MAX_SIZE = 1024 * 128; // 1k; - private final static ThreadLocal bytesBufLocal = new ThreadLocal(); + public final static int BYTES_CACH_INIT_SIZE = 1024; // 1k, 2^10; + public final static int BYTES_CACH_INIT_SIZE_EXP = 10; + public final static int BYTES_CACH_MAX_SIZE = 1024 * 128; // 128k, 2^17; + public final static int BYTES_CACH_MAX_SIZE_EXP = 17; + private final static ThreadLocal> bytesBufLocal = new ThreadLocal>(); public static void clearBytes() { bytesBufLocal.set(null); } public static byte[] getBytes(int length) { - byte[] bytes = bytesBufLocal.get(); + SoftReference ref = bytesBufLocal.get(); - if (bytes == null) { - bytes = allocateBytes(length); + if (ref == null) { + return allocateBytes(length); + } + + byte[] bytes = ref.get(); - return bytes; + if (bytes == null) { + return allocateBytes(length); } if (bytes.length < length) { @@ -81,15 +102,14 @@ public static byte[] getBytes(int length) { } private static byte[] allocateBytes(int length) { - int allocateLength = getAllocateLength(CHARS_CACH_INIT_SIZE, CHARS_CACH_MAX_SIZE, length); + if(length > BYTES_CACH_MAX_SIZE) { + return new byte[length]; + } - if (allocateLength <= CHARS_CACH_MAX_SIZE) { - byte[] chars = new byte[allocateLength]; - bytesBufLocal.set(chars); - return chars; - } - - return new byte[length]; + int allocateLength = getAllocateLengthExp(BYTES_CACH_INIT_SIZE_EXP, BYTES_CACH_MAX_SIZE_EXP, length); + byte[] chars = new byte[allocateLength]; + bytesBufLocal.set(new SoftReference(chars)); + return chars; } } diff --git a/src/main/java/com/alibaba/fastjson/util/TypeUtils.java b/src/main/java/com/alibaba/fastjson/util/TypeUtils.java old mode 100644 new mode 100755 index e6a4f897a3..0900749b08 --- a/src/main/java/com/alibaba/fastjson/util/TypeUtils.java +++ b/src/main/java/com/alibaba/fastjson/util/TypeUtils.java @@ -1,654 +1,1423 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.util; - -import java.lang.reflect.Array; -import java.lang.reflect.Method; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.FieldDeserializer; - -/** - * @author wenshao - */ -public class TypeUtils { - - public static final String castToString(Object value) { - if (value == null) { - return null; - } - - return value.toString(); - } - - public static final Byte castToByte(Object value) { - if (value == null) { - return null; - } - - if (value instanceof Number) { - return ((Number) value).byteValue(); - } - - if (value instanceof String) { - String strVal = (String) value; - if (strVal.length() == 0) { - return null; - } - return Byte.parseByte(strVal); - } - - throw new JSONException("can not cast to byte, value : " + value); - } - - public static final Character castToChar(Object value) { - if (value == null) { - return null; - } - - if (value instanceof Character) { - return (Character) value; - } - - if (value instanceof String) { - String strVal = (String) value; - - if (strVal.length() == 0) { - return null; - } - - if (strVal.length() != 1) { - throw new JSONException("can not cast to byte, value : " + value); - } - - return strVal.charAt(0); - } - - throw new JSONException("can not cast to byte, value : " + value); - } - - public static final Short castToShort(Object value) { - if (value == null) { - return null; - } - - if (value instanceof Number) { - return ((Number) value).shortValue(); - } - - if (value instanceof String) { - String strVal = (String) value; - if (strVal.length() == 0) { - return null; - } - return Short.parseShort(strVal); - } - - throw new JSONException("can not cast to short, value : " + value); - } - - public static final BigDecimal castToBigDecimal(Object value) { - if (value == null) { - return null; - } - - if (value instanceof BigDecimal) { - return (BigDecimal) value; - } - - if (value instanceof BigInteger) { - return new BigDecimal((BigInteger) value); - } - - String strVal = value.toString(); - if (strVal.length() == 0) { - return null; - } - - return new BigDecimal(strVal); - } - - public static final BigInteger castToBigInteger(Object value) { - if (value == null) { - return null; - } - - if (value instanceof BigInteger) { - return (BigInteger) value; - } - - String strVal = value.toString(); - if (strVal.length() == 0) { - return null; - } - - return new BigInteger(strVal); - } - - public static final Float castToFloat(Object value) { - if (value == null) { - return null; - } - - if (value instanceof Number) { - return ((Number) value).floatValue(); - } - - if (value instanceof String) { - String strVal = value.toString(); - if (strVal.length() == 0) { - return null; - } - - return Float.parseFloat(strVal); - } - - throw new JSONException("can not cast to float, value : " + value); - } - - public static final Double castToDouble(Object value) { - if (value == null) { - return null; - } - - if (value instanceof Number) { - return ((Number) value).doubleValue(); - } - - if (value instanceof String) { - String strVal = value.toString(); - if (strVal.length() == 0) { - return null; - } - return Double.parseDouble(strVal); - } - - throw new JSONException("can not cast to double, value : " + value); - } - - public static final Date castToDate(Object value) { - if (value == null) { - return null; - } - - if (value instanceof Calendar) { - return ((Calendar) value).getTime(); - } - - if (value instanceof Date) { - return (Date) value; - } - - long longValue = 0; - - if (value instanceof Number) { - longValue = ((Number) value).longValue(); - } - - if (value instanceof String) { - String strVal = (String) value; - if (strVal.length() == 0) { - return null; - } - - longValue = Long.parseLong(strVal); - } - - if (longValue <= 0) { - throw new JSONException("can not cast to Date, value : " + value); - } - - return new Date(longValue); - } - - public static final java.sql.Date castToSqlDate(Object value) { - if (value == null) { - return null; - } - - if (value instanceof Calendar) { - return new java.sql.Date(((Calendar) value).getTimeInMillis()); - } - - if (value instanceof java.sql.Date) { - return (java.sql.Date) value; - } - - if (value instanceof java.util.Date) { - return new java.sql.Date(((java.util.Date) value).getTime()); - } - - long longValue = 0; - - if (value instanceof Number) { - longValue = ((Number) value).longValue(); - } - - if (value instanceof String) { - String strVal = (String) value; - if (strVal.length() == 0) { - return null; - } - - longValue = Long.parseLong(strVal); - } - - if (longValue <= 0) { - throw new JSONException("can not cast to Date, value : " + value); - } - - return new java.sql.Date(longValue); - } - - public static final java.sql.Timestamp castToTimestamp(Object value) { - if (value == null) { - return null; - } - - if (value instanceof Calendar) { - return new java.sql.Timestamp(((Calendar) value).getTimeInMillis()); - } - - if (value instanceof java.sql.Timestamp) { - return (java.sql.Timestamp) value; - } - - if (value instanceof java.util.Date) { - return new java.sql.Timestamp(((java.util.Date) value).getTime()); - } - - long longValue = 0; - - if (value instanceof Number) { - longValue = ((Number) value).longValue(); - } - - if (value instanceof String) { - String strVal = (String) value; - if (strVal.length() == 0) { - return null; - } - - longValue = Long.parseLong(strVal); - } - - if (longValue <= 0) { - throw new JSONException("can not cast to Date, value : " + value); - } - - return new java.sql.Timestamp(longValue); - } - - public static final Long castToLong(Object value) { - if (value == null) { - return null; - } - - if (value instanceof Number) { - return ((Number) value).longValue(); - } - - if (value instanceof String) { - String strVal = (String) value; - if (strVal.length() == 0) { - return null; - } - - return Long.parseLong(strVal); - } - - throw new JSONException("can not cast to long, value : " + value); - } - - public static final Integer castToInt(Object value) { - if (value == null) { - return null; - } - - if (value instanceof Integer) { - return (Integer) value; - } - - if (value instanceof Number) { - return ((Number) value).intValue(); - } - - if (value instanceof String) { - String strVal = (String) value; - if (strVal.length() == 0) { - return null; - } - - return Integer.parseInt(strVal); - } - - throw new JSONException("can not cast to int, value : " + value); - } - - public static final Boolean castToBoolean(Object value) { - if (value == null) { - return null; - } - - if (value instanceof Boolean) { - return (Boolean) value; - } - - if (value instanceof Number) { - return ((Number) value).intValue() == 1; - } - - if (value instanceof String) { - String str = (String) value; - if (str.length() == 0) { - return null; - } - - if ("true".equals(str)) { - return Boolean.TRUE; - } - if ("false".equals(str)) { - return Boolean.FALSE; - } - - if ("1".equals(str)) { - return Boolean.TRUE; - } - } - - throw new JSONException("can not cast to int, value : " + value); - } - - public static final T castToJavaBean(Object obj, Class clazz) { - return cast(obj, clazz, ParserConfig.getGlobalInstance()); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public static final T cast(Object obj, Class clazz, ParserConfig mapping) { - if (obj == null) { - return null; - } - - if (clazz == obj.getClass()) { - return (T) obj; - } - - if (obj instanceof Map) { - if (clazz == Map.class) { - return (T) obj; - } - - return castToJavaBean((Map) obj, clazz, mapping); - } - - if (clazz.isArray()) { - if (obj instanceof Collection) { - - Collection collection = (Collection) obj; - int index = 0; - Object array = Array.newInstance(clazz.getComponentType(), collection.size()); - for (Object item : collection) { - Object value = cast(item, clazz.getComponentType(), mapping); - Array.set(array, index, value); - index++; - } - - return (T) array; - } - } - - if (clazz.isAssignableFrom(obj.getClass())) { - return (T) obj; - } - - if (clazz == boolean.class || clazz == Boolean.class) { - return (T) castToBoolean(obj); - } - - if (clazz == byte.class || clazz == Byte.class) { - return (T) castToByte(obj); - } - - // if (clazz == char.class || clazz == Character.class) { - // return (T) castToCharacter(obj); - // } - - if (clazz == short.class || clazz == Short.class) { - return (T) castToShort(obj); - } - - if (clazz == int.class || clazz == Integer.class) { - return (T) castToInt(obj); - } - - if (clazz == long.class || clazz == Long.class) { - return (T) castToLong(obj); - } - - if (clazz == float.class || clazz == Float.class) { - return (T) castToFloat(obj); - } - - if (clazz == double.class || clazz == Double.class) { - return (T) castToDouble(obj); - } - - if (clazz == String.class) { - return (T) castToString(obj); - } - - if (clazz == BigDecimal.class) { - return (T) castToBigDecimal(obj); - } - - if (clazz == BigInteger.class) { - return (T) castToBigInteger(obj); - } - - if (clazz == Date.class) { - return (T) castToDate(obj); - } - - if (clazz == java.sql.Date.class) { - return (T) castToSqlDate(obj); - } - - if (clazz == java.sql.Timestamp.class) { - return (T) castToTimestamp(obj); - } - - if (clazz.isEnum()) { - return (T) castToEnum(obj, clazz, mapping); - } - - if (obj instanceof String) { - String strVal = (String) obj; - if (strVal.length() == 0) { - return null; - } - } - - throw new JSONException("can not cast to : " + clazz.getName()); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public static final T castToEnum(Object obj, Class clazz, ParserConfig mapping) { - try { - if (obj instanceof String) { - String name = (String) obj; - if (name.length() == 0) { - return null; - } - - return (T) Enum.valueOf((Class) clazz, name); - } - - if (obj instanceof Number) { - int ordinal = ((Number) obj).intValue(); - - Method method = clazz.getMethod("values"); - Object[] values = (Object[]) method.invoke(null); - for (Object value : values) { - Enum e = (Enum) value; - if (e.ordinal() == ordinal) { - return (T) e; - } - } - } - } catch (Exception ex) { - throw new JSONException("can not cast to : " + clazz.getName(), ex); - } - - throw new JSONException("can not cast to : " + clazz.getName()); - } - - @SuppressWarnings("unchecked") - public static final T cast(Object obj, Type type, ParserConfig mapping) { - if (obj == null) { - return null; - } - - if (type instanceof Class) { - return (T) cast(obj, (Class) type, mapping); - } - - if (type instanceof ParameterizedType) { - return (T) cast(obj, (ParameterizedType) type, mapping); - } - - if (obj instanceof String) { - String strVal = (String) obj; - if (strVal.length() == 0) { - return null; - } - } - - throw new JSONException("can not cast to : " + type); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public static final T cast(Object obj, ParameterizedType type, ParserConfig mapping) { - Type rawTye = type.getRawType(); - - if (rawTye == List.class || rawTye == ArrayList.class) { - Type itemType = type.getActualTypeArguments()[0]; - - if (obj instanceof Iterable) { - List list = new ArrayList(); - - for (Iterator it = ((Iterable) obj).iterator(); it.hasNext();) { - Object item = it.next(); - list.add(cast(item, itemType, mapping)); - } - - return (T) list; - } - } - - if (rawTye == Map.class || rawTye == HashMap.class) { - Type keyType = type.getActualTypeArguments()[0]; - Type valueType = type.getActualTypeArguments()[1]; - - if (obj instanceof Map) { - Map map = new HashMap(); - - for (Map.Entry entry : ((Map) obj).entrySet()) { - Object key = cast(entry.getKey(), keyType, mapping); - Object value = cast(entry.getValue(), valueType, mapping); - - map.put(key, value); - } - - return (T) map; - } - } - - if (obj instanceof String) { - String strVal = (String) obj; - if (strVal.length() == 0) { - return null; - } - } - - throw new JSONException("can not cast to : " + type); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public static final T castToJavaBean(Map map, Class clazz, ParserConfig mapping) { - try { - if (clazz == StackTraceElement.class) { - String declaringClass = (String) map.get("className"); - String methodName = (String) map.get("methodName"); - String fileName = (String) map.get("fileName"); - int lineNumber; - { - Number value = (Number) map.get("lineNumber"); - if (value == null) { - lineNumber = 0; - } else { - lineNumber = value.intValue(); - } - } - - return (T) new StackTraceElement(declaringClass, methodName, fileName, lineNumber); - } - - { - Object iClassObject = map.get("class"); - if (iClassObject instanceof String) { - String className = (String) iClassObject; - - try { - Class iClass = Thread.currentThread().getContextClassLoader().loadClass(className); - clazz = iClass; - } catch (Throwable e) { - // skip - } - } - } - - Map setters = mapping.getFieldDeserializers(clazz); - - T object = clazz.newInstance(); - - for (Map.Entry entry : setters.entrySet()) { - String key = entry.getKey(); - Method method = entry.getValue().getMethod(); - - Object value = map.get(key); - value = cast(value, method.getGenericParameterTypes()[0], mapping); - method.invoke(object, new Object[] { value }); - } - - return object; - } catch (Exception e) { - throw new JSONException(e.getMessage(), e); - } - } -} +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.fastjson.util; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Proxy; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.lang.reflect.WildcardType; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.security.AccessControlException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.asm.ASMException; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.JSONScanner; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.FieldDeserializer; +import com.alibaba.fastjson.serializer.SerializerFeature; + +/** + * @author wenshao[szujobs@hotmail.com] + */ +public class TypeUtils { + + public static boolean compatibleWithJavaBean = false; + private static boolean setAccessibleEnable = true; + + static { + try { + String prop = System.getProperty("fastjson.compatibleWithJavaBean"); + if ("true".equals(prop)) { + compatibleWithJavaBean = true; + } else if ("false".equals(prop)) { + compatibleWithJavaBean = false; + } + } catch (Throwable ex) { + // skip + } + } + + public static final String castToString(Object value) { + if (value == null) { + return null; + } + + return value.toString(); + } + + public static final Byte castToByte(Object value) { + if (value == null) { + return null; + } + + if (value instanceof Number) { + return ((Number) value).byteValue(); + } + + if (value instanceof String) { + String strVal = (String) value; + if (strVal.length() == 0) { + return null; + } + + if ("null".equals(strVal) || "NULL".equals(strVal)) { + return null; + } + + return Byte.parseByte(strVal); + } + + throw new JSONException("can not cast to byte, value : " + value); + } + + public static final Character castToChar(Object value) { + if (value == null) { + return null; + } + + if (value instanceof Character) { + return (Character) value; + } + + if (value instanceof String) { + String strVal = (String) value; + + if (strVal.length() == 0) { + return null; + } + + if (strVal.length() != 1) { + throw new JSONException("can not cast to byte, value : " + value); + } + + return strVal.charAt(0); + } + + throw new JSONException("can not cast to byte, value : " + value); + } + + public static final Short castToShort(Object value) { + if (value == null) { + return null; + } + + if (value instanceof Number) { + return ((Number) value).shortValue(); + } + + if (value instanceof String) { + String strVal = (String) value; + + if (strVal.length() == 0) { + return null; + } + + if ("null".equals(strVal) || "NULL".equals(strVal)) { + return null; + } + + return Short.parseShort(strVal); + } + + throw new JSONException("can not cast to short, value : " + value); + } + + public static final BigDecimal castToBigDecimal(Object value) { + if (value == null) { + return null; + } + + if (value instanceof BigDecimal) { + return (BigDecimal) value; + } + + if (value instanceof BigInteger) { + return new BigDecimal((BigInteger) value); + } + + String strVal = value.toString(); + if (strVal.length() == 0) { + return null; + } + + return new BigDecimal(strVal); + } + + public static final BigInteger castToBigInteger(Object value) { + if (value == null) { + return null; + } + + if (value instanceof BigInteger) { + return (BigInteger) value; + } + + if (value instanceof Float || value instanceof Double) { + return BigInteger.valueOf(((Number) value).longValue()); + } + + String strVal = value.toString(); + if (strVal.length() == 0) { + return null; + } + + return new BigInteger(strVal); + } + + public static final Float castToFloat(Object value) { + if (value == null) { + return null; + } + + if (value instanceof Number) { + return ((Number) value).floatValue(); + } + + if (value instanceof String) { + String strVal = value.toString(); + if (strVal.length() == 0) { + return null; + } + + if ("null".equals(strVal) || "NULL".equals(strVal)) { + return null; + } + + return Float.parseFloat(strVal); + } + + throw new JSONException("can not cast to float, value : " + value); + } + + public static final Double castToDouble(Object value) { + if (value == null) { + return null; + } + + if (value instanceof Number) { + return ((Number) value).doubleValue(); + } + + if (value instanceof String) { + String strVal = value.toString(); + if (strVal.length() == 0) { + return null; + } + + if ("null".equals(strVal) || "NULL".equals(strVal)) { + return null; + } + + return Double.parseDouble(strVal); + } + + throw new JSONException("can not cast to double, value : " + value); + } + + public static final Date castToDate(Object value) { + if (value == null) { + return null; + } + + if (value instanceof Calendar) { + return ((Calendar) value).getTime(); + } + + if (value instanceof Date) { + return (Date) value; + } + + long longValue = -1; + + if (value instanceof Number) { + longValue = ((Number) value).longValue(); + return new Date(longValue); + } + + if (value instanceof String) { + String strVal = (String) value; + + if (strVal.indexOf('-') != -1) { + String format; + if (strVal.length() == JSON.DEFFAULT_DATE_FORMAT.length()) { + format = JSON.DEFFAULT_DATE_FORMAT; + } else if (strVal.length() == 10) { + format = "yyyy-MM-dd"; + } else if (strVal.length() == "yyyy-MM-dd HH:mm:ss".length()) { + format = "yyyy-MM-dd HH:mm:ss"; + } else { + format = "yyyy-MM-dd HH:mm:ss.SSS"; + } + + SimpleDateFormat dateFormat = new SimpleDateFormat(format); + try { + return (Date) dateFormat.parse(strVal); + } catch (ParseException e) { + throw new JSONException("can not cast to Date, value : " + strVal); + } + } + + if (strVal.length() == 0) { + return null; + } + + longValue = Long.parseLong(strVal); + } + + if (longValue < 0) { + throw new JSONException("can not cast to Date, value : " + value); + } + + return new Date(longValue); + } + + public static final java.sql.Date castToSqlDate(Object value) { + if (value == null) { + return null; + } + + if (value instanceof Calendar) { + return new java.sql.Date(((Calendar) value).getTimeInMillis()); + } + + if (value instanceof java.sql.Date) { + return (java.sql.Date) value; + } + + if (value instanceof java.util.Date) { + return new java.sql.Date(((java.util.Date) value).getTime()); + } + + long longValue = 0; + + if (value instanceof Number) { + longValue = ((Number) value).longValue(); + } + + if (value instanceof String) { + String strVal = (String) value; + if (strVal.length() == 0) { + return null; + } + + longValue = Long.parseLong(strVal); + } + + if (longValue <= 0) { + throw new JSONException("can not cast to Date, value : " + value); + } + + return new java.sql.Date(longValue); + } + + public static final java.sql.Timestamp castToTimestamp(Object value) { + if (value == null) { + return null; + } + + if (value instanceof Calendar) { + return new java.sql.Timestamp(((Calendar) value).getTimeInMillis()); + } + + if (value instanceof java.sql.Timestamp) { + return (java.sql.Timestamp) value; + } + + if (value instanceof java.util.Date) { + return new java.sql.Timestamp(((java.util.Date) value).getTime()); + } + + long longValue = 0; + + if (value instanceof Number) { + longValue = ((Number) value).longValue(); + } + + if (value instanceof String) { + String strVal = (String) value; + if (strVal.length() == 0) { + return null; + } + + longValue = Long.parseLong(strVal); + } + + if (longValue <= 0) { + throw new JSONException("can not cast to Date, value : " + value); + } + + return new java.sql.Timestamp(longValue); + } + + public static final Long castToLong(Object value) { + if (value == null) { + return null; + } + + if (value instanceof Number) { + return ((Number) value).longValue(); + } + + if (value instanceof String) { + String strVal = (String) value; + if (strVal.length() == 0) { + return null; + } + + if ("null".equals(strVal) || "NULL".equals(strVal)) { + return null; + } + + try { + return Long.parseLong(strVal); + } catch (NumberFormatException ex) { + // + } + + JSONScanner dateParser = new JSONScanner(strVal); + Calendar calendar = null; + if (dateParser.scanISO8601DateIfMatch(false)) { + calendar = dateParser.getCalendar(); + } + dateParser.close(); + + if (calendar != null) { + return calendar.getTimeInMillis(); + } + } + + throw new JSONException("can not cast to long, value : " + value); + } + + public static final Integer castToInt(Object value) { + if (value == null) { + return null; + } + + if (value instanceof Integer) { + return (Integer) value; + } + + if (value instanceof Number) { + return ((Number) value).intValue(); + } + + if (value instanceof String) { + String strVal = (String) value; + + if (strVal.length() == 0) { + return null; + } + + if ("null".equals(strVal)) { + return null; + } + + if ("null".equals(strVal) || "NULL".equals(strVal)) { + return null; + } + + return Integer.parseInt(strVal); + } + + throw new JSONException("can not cast to int, value : " + value); + } + + public static final byte[] castToBytes(Object value) { + if (value instanceof byte[]) { + return (byte[]) value; + } + + if (value instanceof String) { + return Base64.decodeFast((String) value); + } + throw new JSONException("can not cast to int, value : " + value); + } + + public static final Boolean castToBoolean(Object value) { + if (value == null) { + return null; + } + + if (value instanceof Boolean) { + return (Boolean) value; + } + + if (value instanceof Number) { + return ((Number) value).intValue() == 1; + } + + if (value instanceof String) { + String strVal = (String) value; + + if (strVal.length() == 0) { + return null; + } + + if ("true".equalsIgnoreCase(strVal)) { + return Boolean.TRUE; + } + if ("false".equalsIgnoreCase(strVal)) { + return Boolean.FALSE; + } + + if ("1".equals(strVal)) { + return Boolean.TRUE; + } + + if ("0".equals(strVal)) { + return Boolean.FALSE; + } + + if ("null".equals(strVal) || "NULL".equals(strVal)) { + return null; + } + } + + throw new JSONException("can not cast to boolean, value : " + value); + } + + public static final T castToJavaBean(Object obj, Class clazz) { + return cast(obj, clazz, ParserConfig.getGlobalInstance()); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static final T cast(Object obj, Class clazz, ParserConfig mapping) { + if (obj == null) { + return null; + } + + if (clazz == null) { + throw new IllegalArgumentException("clazz is null"); + } + + if (clazz == obj.getClass()) { + return (T) obj; + } + + if (obj instanceof Map) { + if (clazz == Map.class) { + return (T) obj; + } + + Map map = (Map) obj; + if (clazz == Object.class && !map.containsKey(JSON.DEFAULT_TYPE_KEY)) { + return (T) obj; + } + + return castToJavaBean((Map) obj, clazz, mapping); + } + + if (clazz.isArray()) { + if (obj instanceof Collection) { + + Collection collection = (Collection) obj; + int index = 0; + Object array = Array.newInstance(clazz.getComponentType(), collection.size()); + for (Object item : collection) { + Object value = cast(item, clazz.getComponentType(), mapping); + Array.set(array, index, value); + index++; + } + + return (T) array; + } + + if (clazz == byte[].class) { + return (T) castToBytes(obj); + } + } + + if (clazz.isAssignableFrom(obj.getClass())) { + return (T) obj; + } + + if (clazz == boolean.class || clazz == Boolean.class) { + return (T) castToBoolean(obj); + } + + if (clazz == byte.class || clazz == Byte.class) { + return (T) castToByte(obj); + } + + // if (clazz == char.class || clazz == Character.class) { + // return (T) castToCharacter(obj); + // } + + if (clazz == short.class || clazz == Short.class) { + return (T) castToShort(obj); + } + + if (clazz == int.class || clazz == Integer.class) { + return (T) castToInt(obj); + } + + if (clazz == long.class || clazz == Long.class) { + return (T) castToLong(obj); + } + + if (clazz == float.class || clazz == Float.class) { + return (T) castToFloat(obj); + } + + if (clazz == double.class || clazz == Double.class) { + return (T) castToDouble(obj); + } + + if (clazz == String.class) { + return (T) castToString(obj); + } + + if (clazz == BigDecimal.class) { + return (T) castToBigDecimal(obj); + } + + if (clazz == BigInteger.class) { + return (T) castToBigInteger(obj); + } + + if (clazz == Date.class) { + return (T) castToDate(obj); + } + + if (clazz == java.sql.Date.class) { + return (T) castToSqlDate(obj); + } + + if (clazz == java.sql.Timestamp.class) { + return (T) castToTimestamp(obj); + } + + if (clazz.isEnum()) { + return (T) castToEnum(obj, clazz, mapping); + } + + if (Calendar.class.isAssignableFrom(clazz)) { + Date date = castToDate(obj); + Calendar calendar; + if (clazz == Calendar.class) { + calendar = Calendar.getInstance(); + } else { + try { + calendar = (Calendar) clazz.newInstance(); + } catch (Exception e) { + throw new JSONException("can not cast to : " + clazz.getName(), e); + } + } + calendar.setTime(date); + return (T) calendar; + } + + if (obj instanceof String) { + String strVal = (String) obj; + if (strVal.length() == 0) { + return null; + } + } + + throw new JSONException("can not cast to : " + clazz.getName()); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static final T castToEnum(Object obj, Class clazz, ParserConfig mapping) { + try { + if (obj instanceof String) { + String name = (String) obj; + if (name.length() == 0) { + return null; + } + + return (T) Enum.valueOf((Class) clazz, name); + } + + if (obj instanceof Number) { + int ordinal = ((Number) obj).intValue(); + + Method method = clazz.getMethod("values"); + Object[] values = (Object[]) method.invoke(null); + for (Object value : values) { + Enum e = (Enum) value; + if (e.ordinal() == ordinal) { + return (T) e; + } + } + } + } catch (Exception ex) { + throw new JSONException("can not cast to : " + clazz.getName(), ex); + } + + throw new JSONException("can not cast to : " + clazz.getName()); + } + + @SuppressWarnings("unchecked") + public static final T cast(Object obj, Type type, ParserConfig mapping) { + if (obj == null) { + return null; + } + + if (type instanceof Class) { + return (T) cast(obj, (Class) type, mapping); + } + + if (type instanceof ParameterizedType) { + return (T) cast(obj, (ParameterizedType) type, mapping); + } + + if (obj instanceof String) { + String strVal = (String) obj; + if (strVal.length() == 0) { + return null; + } + } + + if (type instanceof TypeVariable) { + return (T) obj; + } + + throw new JSONException("can not cast to : " + type); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static final T cast(Object obj, ParameterizedType type, ParserConfig mapping) { + Type rawTye = type.getRawType(); + + if (rawTye == Set.class + || rawTye == HashSet.class // + || rawTye == TreeSet.class // + || rawTye == List.class // + || rawTye == ArrayList.class) { + Type itemType = type.getActualTypeArguments()[0]; + + if (obj instanceof Iterable) { + Collection collection; + if (rawTye == Set.class || rawTye == HashSet.class) { + collection = new HashSet(); + } else if (rawTye == TreeSet.class) { + collection = new TreeSet(); + } else { + collection = new ArrayList(); + } + + for (Iterator it = ((Iterable) obj).iterator(); it.hasNext();) { + Object item = it.next(); + collection.add(cast(item, itemType, mapping)); + } + + return (T) collection; + } + } + + if (rawTye == Map.class || rawTye == HashMap.class) { + Type keyType = type.getActualTypeArguments()[0]; + Type valueType = type.getActualTypeArguments()[1]; + + if (obj instanceof Map) { + Map map = new HashMap(); + + for (Map.Entry entry : ((Map) obj).entrySet()) { + Object key = cast(entry.getKey(), keyType, mapping); + Object value = cast(entry.getValue(), valueType, mapping); + + map.put(key, value); + } + + return (T) map; + } + } + + if (obj instanceof String) { + String strVal = (String) obj; + if (strVal.length() == 0) { + return null; + } + } + + if (type.getActualTypeArguments().length == 1) { + Type argType = type.getActualTypeArguments()[0]; + if (argType instanceof WildcardType) { + return (T) cast(obj, rawTye, mapping); + } + } + + throw new JSONException("can not cast to : " + type); + } + + @SuppressWarnings({ "unchecked" }) + public static final T castToJavaBean(Map map, Class clazz, ParserConfig mapping) { + try { + if (clazz == StackTraceElement.class) { + String declaringClass = (String) map.get("className"); + String methodName = (String) map.get("methodName"); + String fileName = (String) map.get("fileName"); + int lineNumber; + { + Number value = (Number) map.get("lineNumber"); + if (value == null) { + lineNumber = 0; + } else { + lineNumber = value.intValue(); + } + } + + return (T) new StackTraceElement(declaringClass, methodName, fileName, lineNumber); + } + + { + Object iClassObject = map.get(JSON.DEFAULT_TYPE_KEY); + if (iClassObject instanceof String) { + String className = (String) iClassObject; + + Class loadClazz = (Class) loadClass(className); + + if (loadClazz == null) { + throw new ClassNotFoundException(className + " not found"); + } + + if (!loadClazz.equals(clazz)) { + return (T) castToJavaBean(map, loadClazz, mapping); + } + } + } + + if (clazz.isInterface()) { + JSONObject object; + + if (map instanceof JSONObject) { + object = (JSONObject) map; + } else { + object = new JSONObject(map); + } + + return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), + new Class[] { clazz }, object); + } + + if (mapping == null) { + mapping = ParserConfig.getGlobalInstance(); + } + + Map setters = mapping.getFieldDeserializers(clazz); + + Constructor constructor = clazz.getDeclaredConstructor(); + if (!constructor.isAccessible()) { + constructor.setAccessible(true); + } + T object = constructor.newInstance(); + + for (Map.Entry entry : setters.entrySet()) { + String key = entry.getKey(); + FieldDeserializer fieldDeser = entry.getValue(); + + if (map.containsKey(key)) { + Object value = map.get(key); + Method method = fieldDeser.getMethod(); + if (method != null) { + Type paramType = method.getGenericParameterTypes()[0]; + value = cast(value, paramType, mapping); + method.invoke(object, new Object[] { value }); + } else { + Field field = fieldDeser.getField(); + Type paramType = field.getGenericType(); + value = cast(value, paramType, mapping); + field.set(object, value); + } + + } + } + + return object; + } catch (Exception e) { + throw new JSONException(e.getMessage(), e); + } + } + + private static ConcurrentMap> mappings = new ConcurrentHashMap>(); + static { + addBaseClassMappings(); + } + + public static void addClassMapping(String className, Class clazz) { + if (className == null) { + className = clazz.getName(); + } + + mappings.put(className, clazz); + } + + public static void addBaseClassMappings() { + mappings.put("byte", byte.class); + mappings.put("short", short.class); + mappings.put("int", int.class); + mappings.put("long", long.class); + mappings.put("float", float.class); + mappings.put("double", double.class); + mappings.put("boolean", boolean.class); + mappings.put("char", char.class); + + mappings.put("[byte", byte[].class); + mappings.put("[short", short[].class); + mappings.put("[int", int[].class); + mappings.put("[long", long[].class); + mappings.put("[float", float[].class); + mappings.put("[double", double[].class); + mappings.put("[boolean", boolean[].class); + mappings.put("[char", char[].class); + + mappings.put(HashMap.class.getName(), HashMap.class); + } + + public static void clearClassMapping() { + mappings.clear(); + addBaseClassMappings(); + } + + public static Class loadClass(String className) { + if (className == null || className.length() == 0) { + return null; + } + + Class clazz = mappings.get(className); + + if (clazz != null) { + return clazz; + } + + if (className.charAt(0) == '[') { + Class componentType = loadClass(className.substring(1)); + return Array.newInstance(componentType, 0).getClass(); + } + + if (className.startsWith("L") && className.endsWith(";")) { + String newClassName = className.substring(1, className.length() - 1); + return loadClass(newClassName); + } + + try { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + + if (classLoader != null) { + clazz = classLoader.loadClass(className); + + addClassMapping(className, clazz); + + return clazz; + } + } catch (Throwable e) { + // skip + } + + try { + clazz = Class.forName(className); + + addClassMapping(className, clazz); + + return clazz; + } catch (Throwable e) { + // skip + } + + return clazz; + } + + public static List computeGetters(Class clazz, Map aliasMap) { + return computeGetters(clazz, aliasMap, true); + } + + public static List computeGetters(Class clazz, Map aliasMap, boolean sorted) { + Map fieldInfoMap = new LinkedHashMap(); + + for (Method method : clazz.getMethods()) { + String methodName = method.getName(); + int ordinal = 0, serialzeFeatures = 0; + + if (Modifier.isStatic(method.getModifiers())) { + continue; + } + + if (method.getReturnType().equals(Void.TYPE)) { + continue; + } + + if (method.getParameterTypes().length != 0) { + continue; + } + + if (method.getReturnType() == ClassLoader.class) { + continue; + } + + if (method.getName().equals("getMetaClass") + && method.getReturnType().getName().equals("groovy.lang.MetaClass")) { + continue; + } + + JSONField annotation = method.getAnnotation(JSONField.class); + + if (annotation == null) { + annotation = getSupperMethodAnnotation(clazz, method); + } + + if (annotation != null) { + if (!annotation.serialize()) { + continue; + } + + ordinal = annotation.ordinal(); + serialzeFeatures = SerializerFeature.of(annotation.serialzeFeatures()); + + if (annotation.name().length() != 0) { + String propertyName = annotation.name(); + + if (aliasMap != null) { + propertyName = aliasMap.get(propertyName); + if (propertyName == null) { + continue; + } + } + + fieldInfoMap.put(propertyName, new FieldInfo(propertyName, method, null, ordinal, serialzeFeatures)); + continue; + } + } + + if (methodName.startsWith("get")) { + if (methodName.length() < 4) { + continue; + } + + if (methodName.equals("getClass")) { + continue; + } + + char c3 = methodName.charAt(3); + + String propertyName; + if (Character.isUpperCase(c3)) { + if (compatibleWithJavaBean) { + propertyName = decapitalize(methodName.substring(3)); + } else { + propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4); + } + } else if (c3 == '_') { + propertyName = methodName.substring(4); + } else if (c3 == 'f') { + propertyName = methodName.substring(3); + } else if (methodName.length()>=5 && Character.isUpperCase(methodName.charAt(4))){ + propertyName = decapitalize(methodName.substring(3)); + } else { + continue; + } + + boolean ignore = isJSONTypeIgnore(clazz, propertyName); + + if (ignore) { + continue; + } + + Field field = ParserConfig.getField(clazz, propertyName); + + if (field != null) { + JSONField fieldAnnotation = field.getAnnotation(JSONField.class); + + if (fieldAnnotation != null) { + if (!fieldAnnotation.serialize()) { + continue; + } + + ordinal = fieldAnnotation.ordinal(); + serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); + + if (fieldAnnotation.name().length() != 0) { + propertyName = fieldAnnotation.name(); + + if (aliasMap != null) { + propertyName = aliasMap.get(propertyName); + if (propertyName == null) { + continue; + } + } + } + } + } + + if (aliasMap != null) { + propertyName = aliasMap.get(propertyName); + if (propertyName == null) { + continue; + } + } + + fieldInfoMap.put(propertyName, new FieldInfo(propertyName, method, field, ordinal, serialzeFeatures)); + } + + if (methodName.startsWith("is")) { + if (methodName.length() < 3) { + continue; + } + + char c2 = methodName.charAt(2); + + String propertyName; + if (Character.isUpperCase(c2)) { + if (compatibleWithJavaBean) { + propertyName = decapitalize(methodName.substring(2)); + } else { + propertyName = Character.toLowerCase(methodName.charAt(2)) + methodName.substring(3); + } + } else if (c2 == '_') { + propertyName = methodName.substring(3); + } else if (c2 == 'f') { + propertyName = methodName.substring(2); + } else { + continue; + } + + Field field = ParserConfig.getField(clazz, propertyName); + + if (field == null) { + field = ParserConfig.getField(clazz, methodName); + } + + if (field != null) { + JSONField fieldAnnotation = field.getAnnotation(JSONField.class); + + if (fieldAnnotation != null) { + if (!fieldAnnotation.serialize()) { + continue; + } + + ordinal = fieldAnnotation.ordinal(); + serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); + + if (fieldAnnotation.name().length() != 0) { + propertyName = fieldAnnotation.name(); + + if (aliasMap != null) { + propertyName = aliasMap.get(propertyName); + if (propertyName == null) { + continue; + } + } + } + } + } + + if (aliasMap != null) { + propertyName = aliasMap.get(propertyName); + if (propertyName == null) { + continue; + } + } + + fieldInfoMap.put(propertyName, new FieldInfo(propertyName, method, field, ordinal, serialzeFeatures)); + } + } + + for (Field field : clazz.getFields()) { + if (Modifier.isStatic(field.getModifiers())) { + continue; + } + + JSONField fieldAnnotation = field.getAnnotation(JSONField.class); + + int ordinal = 0, serialzeFeatures = 0; + String propertyName = field.getName(); + if (fieldAnnotation != null) { + if (!fieldAnnotation.serialize()) { + continue; + } + + ordinal = fieldAnnotation.ordinal(); + serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures()); + + if (fieldAnnotation.name().length() != 0) { + propertyName = fieldAnnotation.name(); + } + } + + if (aliasMap != null) { + propertyName = aliasMap.get(propertyName); + if (propertyName == null) { + continue; + } + } + + if (!fieldInfoMap.containsKey(propertyName)) { + fieldInfoMap.put(propertyName, new FieldInfo(propertyName, null, field, ordinal, serialzeFeatures)); + } + } + + List fieldInfoList = new ArrayList(); + + boolean containsAll = false; + String[] orders = null; + + JSONType annotation = clazz.getAnnotation(JSONType.class); + if (annotation != null) { + orders = annotation.orders(); + + if (orders != null && orders.length == fieldInfoMap.size()) { + containsAll = true; + for (String item : orders) { + if (!fieldInfoMap.containsKey(item)) { + containsAll = false; + break; + } + } + } else { + containsAll = false; + } + } + + if (containsAll) { + for (String item : orders) { + FieldInfo fieldInfo = fieldInfoMap.get(item); + fieldInfoList.add(fieldInfo); + } + } else { + for (FieldInfo fieldInfo : fieldInfoMap.values()) { + fieldInfoList.add(fieldInfo); + } + + if (sorted) { + Collections.sort(fieldInfoList); + } + } + + return fieldInfoList; + } + + public static JSONField getSupperMethodAnnotation(Class clazz, Method method) { + for (Class interfaceClass : clazz.getInterfaces()) { + for (Method interfaceMethod : interfaceClass.getMethods()) { + if (!interfaceMethod.getName().equals(method.getName())) { + continue; + } + + if (interfaceMethod.getParameterTypes().length != method.getParameterTypes().length) { + continue; + } + + boolean match = true; + for (int i = 0; i < interfaceMethod.getParameterTypes().length; ++i) { + if (!interfaceMethod.getParameterTypes()[i].equals(method.getParameterTypes()[i])) { + match = false; + break; + } + } + + if (!match) { + continue; + } + + JSONField annotation = interfaceMethod.getAnnotation(JSONField.class); + if (annotation != null) { + return annotation; + } + } + } + + return null; + } + + private static boolean isJSONTypeIgnore(Class clazz, String propertyName) { + JSONType jsonType = clazz.getAnnotation(JSONType.class); + + if (jsonType != null && jsonType.ignores() != null) { + for (String item : jsonType.ignores()) { + if (propertyName.equalsIgnoreCase(item)) { + return true; + } + } + } + + if (clazz.getSuperclass() != Object.class && clazz.getSuperclass() != null) { + if (isJSONTypeIgnore(clazz.getSuperclass(), propertyName)) { + return true; + } + } + + return false; + } + + public static boolean isGenericParamType(Type type) { + if (type instanceof ParameterizedType) { + return true; + } + + if (type instanceof Class) { + return isGenericParamType(((Class) type).getGenericSuperclass()); + } + + return false; + } + + public static Type getGenericParamType(Type type) { + if (type instanceof ParameterizedType) { + return type; + } + + if (type instanceof Class) { + return getGenericParamType(((Class) type).getGenericSuperclass()); + } + + return type; + } + + public static Type unwrap(Type type) { + if (type instanceof GenericArrayType) { + Type componentType = ((GenericArrayType) type).getGenericComponentType(); + if (componentType == byte.class) { + return byte[].class; + } + if (componentType == char.class) { + return char[].class; + } + } + + return type; + } + + public static Class getClass(Type type) { + if (type.getClass() == Class.class) { + return (Class) type; + } + + if (type instanceof ParameterizedType) { + return getClass(((ParameterizedType) type).getRawType()); + } + + return Object.class; + } + + public static Field getField(Class clazz, String fieldName) { + for (Field field : clazz.getDeclaredFields()) { + if (fieldName.equals(field.getName())) { + return field; + } + } + + Class superClass = clazz.getSuperclass(); + if(superClass != null && superClass != Object.class) { + return getField(superClass, fieldName); + } + + return null; + } + + public static JSONType getJSONType(Class clazz) { + return clazz.getAnnotation(JSONType.class); + } + + public static int getSerializeFeatures(Class clazz) { + JSONType annotation = clazz.getAnnotation(JSONType.class); + + if (annotation == null) { + return 0; + } + + return SerializerFeature.of(annotation.serialzeFeatures()); + } + + public static int getParserFeatures(Class clazz) { + JSONType annotation = clazz.getAnnotation(JSONType.class); + + if (annotation == null) { + return 0; + } + + return Feature.of(annotation.parseFeatures()); + } + + public static String decapitalize(String name) { + if (name == null || name.length() == 0) { + return name; + } + if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) && + Character.isUpperCase(name.charAt(0))){ + return name; + } + char chars[] = name.toCharArray(); + chars[0] = Character.toLowerCase(chars[0]); + return new String(chars); + } + + static void setAccessible(AccessibleObject obj) { + if (!setAccessibleEnable) { + return; + } + + if (obj.isAccessible()) { + return; + } + + try { + obj.setAccessible(true); + } catch (AccessControlException error) { + setAccessibleEnable = false; + } + } + + public static Class getCollectionItemClass(Type fieldType) { + if (fieldType instanceof ParameterizedType) { + Class itemClass; + Type actualTypeArgument = ((ParameterizedType) fieldType).getActualTypeArguments()[0]; + + if (actualTypeArgument instanceof Class) { + itemClass = (Class) actualTypeArgument; + if (!Modifier.isPublic(itemClass.getModifiers())) { + throw new ASMException("can not create ASMParser"); + } + } else { + throw new ASMException("can not create ASMParser"); + } + return itemClass; + } + + return Object.class; + } +} diff --git a/src/main/java/com/alibaba/fastjson/util/UTF8Decoder.java b/src/main/java/com/alibaba/fastjson/util/UTF8Decoder.java old mode 100644 new mode 100755 diff --git a/src/main/resources/META-INF/LICENSE.txt b/src/main/resources/META-INF/LICENSE.txt old mode 100644 new mode 100755 diff --git a/src/main/resources/META-INF/NOTICE.txt b/src/main/resources/META-INF/NOTICE.txt old mode 100644 new mode 100755 diff --git a/src/main/resources/META-INF/services/com.alibaba.fastjson.serializer.AutowiredObjectDeserializer b/src/main/resources/META-INF/services/com.alibaba.fastjson.serializer.AutowiredObjectDeserializer deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/test/java/cn/com/tx/domain/notifyDetail/NotifyDetail.java b/src/test/java/cn/com/tx/domain/notifyDetail/NotifyDetail.java new file mode 100755 index 0000000000..7ce5e5cd6c --- /dev/null +++ b/src/test/java/cn/com/tx/domain/notifyDetail/NotifyDetail.java @@ -0,0 +1,127 @@ +package cn.com.tx.domain.notifyDetail; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class NotifyDetail implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 8760630447394929224L; + + private int detailId; + + private int hotId; + + private int templateId; + + private int srcId; + + private int destId; + + private boolean display; + + private Date foundTime; + + private List args = new ArrayList(); + + + public int getDetailId() { + return detailId; + } + + public void setDetailId(int detailId) { + this.detailId = detailId; + } + + public int getHotId() { + return hotId; + } + + public void setHotId(int hotId) { + this.hotId = hotId; + } + + public int getTemplateId() { + return templateId; + } + + public List getArgs() { + return args; + } + + public void setArgs(List args) { + this.args = args; + } + + public void setTemplateId(int templateId) { + this.templateId = templateId; + } + + public int getSrcId() { + return srcId; + } + + public void setSrcId(int srcId) { + this.srcId = srcId; + } + + public int getDestId() { + return destId; + } + + public void setDestId(int destId) { + this.destId = destId; + } + + public boolean isDisplay() { + return display; + } + + public void setDisplay(boolean display) { + this.display = display; + } + + public Date getFoundTime() { + return foundTime; + } + + public void setFoundTime(Date foundTime) { + this.foundTime = foundTime; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + int hasCode = 0; + if (this.detailId != 0) { + hasCode += this.detailId; + } + return hasCode; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (!(obj instanceof NotifyDetail)) { + return false; + } + return this.hashCode() == obj.hashCode(); + } + + +} diff --git a/src/test/java/cn/com/tx/domain/pagination/Pagination.java b/src/test/java/cn/com/tx/domain/pagination/Pagination.java new file mode 100755 index 0000000000..af4e10e4de --- /dev/null +++ b/src/test/java/cn/com/tx/domain/pagination/Pagination.java @@ -0,0 +1,195 @@ +package cn.com.tx.domain.pagination; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class Pagination implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 5038839734218582220L; + + private int totalResult = 0; + + private int totalPage = 1; + + private int pageIndex = 1; + + private int maxLength = 5; + + private int fromIndex = 0; + + private int toIndex = 0; + + private List list = new ArrayList(); + + public Pagination(){ + + } + + + + public void setTotalResult(int totalResult) { + this.totalResult = totalResult; + } + + + + public void setTotalPage(int totalPage) { + this.totalPage = totalPage; + } + + + + public void setPageIndex(int pageIndex) { + this.pageIndex = pageIndex; + } + + + + public void setMaxLength(int maxLength) { + this.maxLength = maxLength; + } + + + + public void setFromIndex(int fromIndex) { + this.fromIndex = fromIndex; + } + + + + public void setToIndex(int toIndex) { + this.toIndex = toIndex; + } + + + + public int getFromIndex() { + return this.fromIndex; + } + + public int getToIndex() { + return this.toIndex; + } + + public int getNextPage() { + if (this.pageIndex < this.totalPage) { + return this.pageIndex + 1; + } else { + return this.pageIndex; + } + } + + public int getPrevPage() { + if (this.pageIndex > 1) { + return this.pageIndex - 1; + } + return this.pageIndex; + } + + /** + * @return the currentPage + */ + public int getPageIndex() { + return pageIndex; + } + + /** + * @return the list + */ + public List getList() { + if (list == null) { + return new ArrayList(); + } + return new ArrayList(list); + } + + /** + * @return the totalPage + */ + public int getTotalPage() { + return totalPage; + } + + /** + * @return the totalRecord + */ + public int getTotalResult() { + return totalResult; + } + + public int getMaxLength() { + return maxLength; + } + + /** + * + * @param totalResult + * @param pageIndex + * @param maxLength + */ + public Pagination(int totalResult, int pageIndex, int maxLength) { + if (maxLength > 0) { + this.maxLength = maxLength; + } + if (totalResult > 0) { + this.totalResult = totalResult; + } + if (pageIndex > 0) { + this.pageIndex = pageIndex; + } + this.totalPage = this.totalResult / this.maxLength; + if (this.totalResult % this.maxLength != 0) { + this.totalPage = this.totalPage + 1; + } + if (this.totalPage == 0) { + this.totalPage = 1; + } + if (this.pageIndex > this.totalPage) { + this.pageIndex = this.totalPage; + } + if (this.pageIndex <= 0) { + this.pageIndex = 1; + } + this.fromIndex = (this.pageIndex - 1) * maxLength; + this.toIndex = this.fromIndex + maxLength; + if (this.toIndex < 0) { + this.toIndex = fromIndex; + } + if (this.toIndex > this.totalResult) { + this.toIndex = this.totalResult; + } + + } + + /** + * @param datas + * the datas to set + */ + public void setList(List list) { + this.list = list; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("Pagination:\r\n"); + sb.append("\tpageIndex\t" + this.pageIndex + "\r\n"); + sb.append("\ttotalPage\t" + this.totalPage + "\r\n"); + sb.append("\tmaxLength\t" + this.maxLength + "\r\n"); + sb.append("\ttotalResult\t" + this.totalResult + "\r\n"); + for (T t : list) { + sb.append(t + "\r\n"); + } + return sb.toString(); + } + +} diff --git a/src/test/java/com/alibaba/china/bolt/biz/daili/merchants/vo/MerchantsVO.java b/src/test/java/com/alibaba/china/bolt/biz/daili/merchants/vo/MerchantsVO.java new file mode 100644 index 0000000000..0f96db3828 --- /dev/null +++ b/src/test/java/com/alibaba/china/bolt/biz/daili/merchants/vo/MerchantsVO.java @@ -0,0 +1,533 @@ +package com.alibaba.china.bolt.biz.daili.merchants.vo; + +import java.io.Serializable; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.apache.commons.lang.builder.ToStringBuilder; + + +/** + * 商家基本信息 + * @author hongwei.quhw + * + */ +public class MerchantsVO implements Serializable { + /** + * + */ + private static final long serialVersionUID = 1L; + + /** -----------------实体商家信息----------**/ + //店铺类型code + private String type; + //店铺类型name + private String typename; + //招商区域code + private String[] region; + //招商区域name + private String[] regionname; + //最小面积 + private Integer minarea = -1; + //最大面积 + private Integer maxarea; + //启动资金 + private Long initialcapital; + //加盟保证金 + private Long cashdeposit; + /** -----------------网络商家信息----------**/ + //招商渠道搜索索引名 + private String[] shoptype; + //招商渠道搜索名称 + private String[] shoptypename; + //主营类目 + private String[] categoryids; + //主营类目名称 + private String[] categoryidsname; + + /** -----------------商家共有信息----------**/ + //MemberId + private String memberid; + //商家类型 + private int merchantstype; + //是否已删除 + private boolean isdelete; + //招商截止日期 + private Date expirationdate; + //旺旺 + private String wangwang; + //联系电话 + private String tel; + //是否品牌 + private boolean hasbrand; + //(30天)加盟人数 + private int joincount; + //公司旺铺地址 + private String winportdomain; + /** ----------------下面是品牌库信息---------------- **/ + //logo/商标 图片URL + private String brandlogourl; + //品牌名称 + private String brandname; + //创立时间 + private Date brandfoundtime; + //详情 + private String brandintroduction; + //证书 图片URL + private String brandcertificateurl; + + /** ----------------下面是公司库信息---------------- **/ + //公司名 + private String companyname; + //成立年份 + private String companyestablishedyear; + //注册资本 + private Double companyregcapital; + //注册地 + private String companyfoundedplace; + //简介 + private String companyintroduction; + + /** ----------------下面是DW交易信息---------------- **/ + //最近30天代理商支付订单金额(单位为分) + private Double payordamt30; + //最近30天代理商支付订单数 + private long payordcnt30; + //最近30天支付订单代理商买家数 + private long payordbuyercnt30; + //最近90天旺铺回头率 + private Double returnordrate90; + //截至当日成功申请代理商人数 + private int membercnttd; + //主营一级类目ID(主营top1、top2、top3一级类目以char(6)拼装成一串,需要解析出top1一级类目即可)example:"7" + private String stdcategoryid1; + //主营二级类目ID(主营top1、top2、top3二级类目以char(6)拼装成一串,需要解析出top1二级类目即可)example:"7" + private String stdcategoryid2; + //主营一级类目ID名称 example:"服装" + private String stdcategoryname1; + //主营二级类目ID名称 example:"男装" + private String stdcategoryname2; + + /** ----------------下面是offer信息---------------- **/ + //offer缩略图url地址 + private String[] summimageurilist; + //offer链接url地址 + private String[] detailurl; + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getTypename() { + return typename; + } + + public void setTypename(String typename) { + this.typename = typename; + } + + public String[] getRegion() { + return region; + } + + public void setRegionArray(String[] region) { + this.region = region; + } + + public String[] getRegionname() { + return regionname; + } + + public void setRegionnameArray(String[] regionname) { + this.regionname = regionname; + } + + public Integer getMinarea() { + return minarea; + } + + public void setMinarea(Integer minarea) { + if (null == minarea) { + minarea = -1; //opensearch 搜索空问题 ,设置默认值 + } + this.minarea = minarea; + } + + public Integer getMaxarea() { + return maxarea; + } + + public void setMaxarea(Integer maxarea) { + this.maxarea = maxarea; + } + + public Long getInitialcapital() { + return initialcapital; + } + + public void setInitialcapital(Long initialcapital) { + this.initialcapital = initialcapital; + } + + public Long getCashdeposit() { + return cashdeposit; + } + + public void setCashdeposit(Long cashdeposit) { + this.cashdeposit = cashdeposit; + } + + public String[] getShoptype() { + return shoptype; + } + + public void setShoptypeArray(String[] shoptype) { + this.shoptype = shoptype; + } + + public String[] getShoptypename() { + return shoptypename; + } + + public void setShoptypenameArray(String[] shoptypename) { + this.shoptypename = shoptypename; + } + + public String[] getCategoryids() { + return categoryids; + } + + public void setCategoryidsArray(String[] categoryids) { + this.categoryids = categoryids; + } + + public String[] getCategoryidsname() { + return categoryidsname; + } + + public void setCategoryidsnameArray(String[] categoryidsname) { + this.categoryidsname = categoryidsname; + } + + public String getMemberid() { + return memberid; + } + + public void setMemberid(String memberid) { + this.memberid = memberid; + } + + public int getMerchantstype() { + return merchantstype; + } + + public void setMerchantstype(int merchantstype) { + this.merchantstype = merchantstype; + } + + public boolean isIsdelete() { + return isdelete; + } + + public void setIsdelete(boolean isdelete) { + this.isdelete = isdelete; + } + + public Date getExpirationdate() { + return expirationdate; + } + + public void setExpirationdate(Date expirationdate) { + this.expirationdate = expirationdate; + } + + public String getWangwang() { + return wangwang; + } + + public void setWangwang(String wangwang) { + this.wangwang = wangwang; + } + + public String getTel() { + return tel; + } + + public void setTel(String tel) { + this.tel = tel; + } + + public boolean isHasbrand() { + return hasbrand; + } + + public void setHasbrand(boolean hasbrand) { + this.hasbrand = hasbrand; + } + + public int getJoincount() { + return joincount; + } + + public void setJoincount(int joincount) { + this.joincount = joincount; + } + + public String getWinportdomain() { + return winportdomain; + } + + public void setWinportdomain(String winportdomain) { + this.winportdomain = winportdomain; + } + + public String getBrandlogourl() { + return brandlogourl; + } + + public void setBrandlogourl(String brandlogourl) { + this.brandlogourl = brandlogourl; + } + + public String getBrandname() { + return brandname; + } + + public void setBrandname(String brandname) { + this.brandname = brandname; + } + + public Date getBrandfoundtime() { + return brandfoundtime; + } + + public void setBrandfoundtime(Date brandfoundtime) { + this.brandfoundtime = brandfoundtime; + } + + public String getBrandintroduction() { + return brandintroduction; + } + + public void setBrandintroduction(String brandintroduction) { + this.brandintroduction = brandintroduction; + } + + public String getBrandcertificateurl() { + return brandcertificateurl; + } + + public void setBrandcertificateurl(String brandcertificateurl) { + this.brandcertificateurl = brandcertificateurl; + } + + public String getCompanyname() { + return companyname; + } + + public void setCompanyname(String companyname) { + this.companyname = companyname; + } + + public String getCompanyestablishedyear() { + return companyestablishedyear; + } + + public void setCompanyestablishedyear(String companyestablishedyear) { + this.companyestablishedyear = companyestablishedyear; + } + + public Double getCompanyregcapital() { + return companyregcapital; + } + + public void setCompanyregcapital(Double companyregcapital) { + this.companyregcapital = companyregcapital; + } + + public String getCompanyfoundedplace() { + return companyfoundedplace; + } + + public void setCompanyfoundedplace(String companyfoundedplace) { + this.companyfoundedplace = companyfoundedplace; + } + + public String getCompanyintroduction() { + return companyintroduction; + } + + public void setCompanyintroduction(String companyintroduction) { + this.companyintroduction = companyintroduction; + } + + public String[] getSummimageurilist() { + return summimageurilist; + } + + public void setSummimageurilistArray(String[] summimageuriList) { + this.summimageurilist = summimageuriList; + } + + public String[] getDetailurl() { + return detailurl; + } + + public void setDetailurlArray(String[] detailurl) { + this.detailurl = detailurl; + } + + public String getExpirationdateForString(){ + return new SimpleDateFormat("yyyy年MM月dd日").format(this.expirationdate); + } + + /** + * 为opensearch特供 + * @param region + */ + public void setRegion(String region) { + this.region = region== null ?new String[0]:region.split("\\t"); + } + + public void setRegionname(String regionname) { + this.regionname = regionname== null ?new String[0]:regionname.split("\\t");; + } + + public void setShoptype(String shoptype) { + this.shoptype = shoptype== null ?new String[0]:shoptype.split("\\t");; + } + + public void setShoptypename(String shoptypename) { + this.shoptypename = shoptypename== null ?new String[0]:shoptypename.split("\\t");; + } + + public void setCategoryids(String categoryids) { + this.categoryids = categoryids== null ?new String[0]:categoryids.split("\\t");; + } + + public void setCategoryidsname(String categoryidsname) { + this.categoryidsname = categoryidsname== null ?new String[0]:categoryidsname.split("\\t");; + } + + public void setSummimageurilist(String summimageuriList) { + this.summimageurilist = summimageuriList== null ?new String[0]:summimageuriList.split("\\t");; + } + + public void setDetailurl(String detailurl) { + this.detailurl = detailurl== null ?new String[0]:detailurl.split("\\t");; + } + + /** + * @return the payordamt30 + */ + public Double getPayordamt30() { + return payordamt30; + } + + /** + * @param payordamt30 the payordamt30 to set + */ + public void setPayordamt30(Double payordamt30) { + this.payordamt30 = payordamt30; + } + + /** + * @return the payordcnt30 + */ + public long getPayordcnt30() { + return payordcnt30; + } + + /** + * @param payordcnt30 the payordcnt30 to set + */ + public void setPayordcnt30(long payordcnt30) { + this.payordcnt30 = payordcnt30; + } + + /** + * @return the payordbuyercnt30 + */ + public long getPayordbuyercnt30() { + return payordbuyercnt30; + } + + /** + * @param payordbuyercnt30 the payordbuyercnt30 to set + */ + public void setPayordbuyercnt30(long payordbuyercnt30) { + this.payordbuyercnt30 = payordbuyercnt30; + } + + /** + * @return the returnordrate90 + */ + public Double getReturnordrate90() { + return returnordrate90; + } + + /** + * @param returnordrate90 the returnordrate90 to set + */ + public void setReturnordrate90(Double returnordrate90) { + this.returnordrate90 = returnordrate90; + } + + /** + * @return the membercnttd + */ + public int getMembercnttd() { + return membercnttd; + } + + /** + * @param membercnttd the membercnttd to set + */ + public void setMembercnttd(int membercnttd) { + this.membercnttd = membercnttd; + } + + public String getStdcategoryid1() { + return stdcategoryid1; + } + + public void setStdcategoryid1(String stdcategoryid1) { + this.stdcategoryid1 = stdcategoryid1; + } + + public String getStdcategoryid2() { + return stdcategoryid2; + } + + public void setStdcategoryid2(String stdcategoryid2) { + this.stdcategoryid2 = stdcategoryid2; + } + + public String getStdcategoryname1() { + return stdcategoryname1; + } + + public void setStdcategoryname1(String stdcategoryname1) { + this.stdcategoryname1 = stdcategoryname1; + } + + public String getStdcategoryname2() { + return stdcategoryname2; + } + + public void setStdcategoryname2(String stdcategoryname2) { + this.stdcategoryname2 = stdcategoryname2; + } + + + +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/ArrayRefTest2.java b/src/test/java/com/alibaba/json/ArrayRefTest2.java new file mode 100755 index 0000000000..45be1a77f7 --- /dev/null +++ b/src/test/java/com/alibaba/json/ArrayRefTest2.java @@ -0,0 +1,78 @@ +package com.alibaba.json; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class ArrayRefTest2 extends TestCase { + + public void test_0() throws Exception { + String text; + { + List groups = new ArrayList(); + + Group g0 = new Group(0); + Group g1 = new Group(1); + Group g2 = new Group(2); + + groups.add(g0); + groups.add(g1); + groups.add(g2); + groups.add(g0); + groups.add(g1); + groups.add(g2); + + text = JSON.toJSONString(groups); + } + + System.out.println(text); + + Group[] groups = JSON.parseObject(text, new TypeReference() {}); + Assert.assertEquals(6, groups.length); + + Assert.assertNotNull(groups[0]); + Assert.assertNotNull(groups[1]); + Assert.assertNotNull(groups[2]); + Assert.assertNotNull(groups[3]); + Assert.assertNotNull(groups[4]); + Assert.assertNotNull(groups[5]); + + Assert.assertEquals(0, groups[0].getId()); + Assert.assertEquals(1, groups[1].getId()); + Assert.assertEquals(2, groups[2].getId()); + Assert.assertEquals(0, groups[3].getId()); + Assert.assertEquals(1, groups[4].getId()); + Assert.assertEquals(2, groups[5].getId()); + } + + public static class Group { + + private int id; + + public Group(){ + + } + + public Group(int id){ + this.id = id; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String toString() { + return "{id:" + id + "}"; + } + + } +} diff --git a/src/test/java/com/alibaba/json/TestGC.java b/src/test/java/com/alibaba/json/TestGC.java new file mode 100755 index 0000000000..44268377a8 --- /dev/null +++ b/src/test/java/com/alibaba/json/TestGC.java @@ -0,0 +1,14 @@ +package com.alibaba.json; + +import junit.framework.TestCase; + + +public class TestGC extends TestCase { + public void test_0 () throws Exception { + for (int i = 0; i < 1000 * 1000; ++i) { + StringBuilder buf = new StringBuilder(1000 * 1000 * 10); + buf.append(i); + Thread.sleep(10); + } + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/AnnotationTest.java b/src/test/java/com/alibaba/json/bvt/AnnotationTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/AnnotationTest.java rename to src/test/java/com/alibaba/json/bvt/AnnotationTest.java index 6f5cb9449d..4dd3eeddf2 --- a/src/test/java/com/alibaba/json/test/bvt/AnnotationTest.java +++ b/src/test/java/com/alibaba/json/bvt/AnnotationTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/AnnotationTest2.java b/src/test/java/com/alibaba/json/bvt/AnnotationTest2.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/AnnotationTest2.java rename to src/test/java/com/alibaba/json/bvt/AnnotationTest2.java index b77d0a750f..c7415f5042 --- a/src/test/java/com/alibaba/json/test/bvt/AnnotationTest2.java +++ b/src/test/java/com/alibaba/json/bvt/AnnotationTest2.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/AnnotationTest3.java b/src/test/java/com/alibaba/json/bvt/AnnotationTest3.java new file mode 100755 index 0000000000..7c3140f14f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/AnnotationTest3.java @@ -0,0 +1,48 @@ +package com.alibaba.json.bvt; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; + +public class AnnotationTest3 extends TestCase { + + public void test_supperField() throws Exception { + C c = new C(); + c.setId(123); + c.setName("jobs"); + + String str = JSON.toJSONString(c); + Assert.assertEquals("{\"ID\":123,\"name\":\"jobs\"}", str); + } + + public static class S { + + @JSONField(name = "ID") + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } + + public static class C extends S { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/AppendableFieldTest.java b/src/test/java/com/alibaba/json/bvt/AppendableFieldTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/AppendableFieldTest.java rename to src/test/java/com/alibaba/json/bvt/AppendableFieldTest.java index 91883c4eb4..1d4679f432 --- a/src/test/java/com/alibaba/json/test/bvt/AppendableFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/AppendableFieldTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/ArmoryTest.java b/src/test/java/com/alibaba/json/bvt/ArmoryTest.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/ArmoryTest.java rename to src/test/java/com/alibaba/json/bvt/ArmoryTest.java index 9f7f0b3ed1..e64dab8994 --- a/src/test/java/com/alibaba/json/test/bvt/ArmoryTest.java +++ b/src/test/java/com/alibaba/json/bvt/ArmoryTest.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.ArrayList; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/ArrayListFieldTest.java b/src/test/java/com/alibaba/json/bvt/ArrayListFieldTest.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/ArrayListFieldTest.java rename to src/test/java/com/alibaba/json/bvt/ArrayListFieldTest.java index 3d6edc7ac8..638de152c2 --- a/src/test/java/com/alibaba/json/test/bvt/ArrayListFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/ArrayListFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.ArrayList; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/ArrayListFieldTest_1.java b/src/test/java/com/alibaba/json/bvt/ArrayListFieldTest_1.java new file mode 100644 index 0000000000..2378110217 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ArrayListFieldTest_1.java @@ -0,0 +1,49 @@ +package com.alibaba.json.bvt; + +import java.util.ArrayList; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class ArrayListFieldTest_1 extends TestCase { + + public void test_var() throws Exception { + JSON.parseObject("{\"value\":[{}]}", V0.class); + V0 v1 = JSON.parseObject("{\"value\":[{}]}", new TypeReference>() { + }); + Assert.assertTrue(v1.getValue().get(0) instanceof A); + + V0 v2 = JSON.parseObject("{\"value\":[{}]}", new TypeReference>() { + }); + Assert.assertTrue(v2.getValue().get(0) instanceof B); + } + + private static class V { + + } + + private static class V0 extends V { + + private ArrayList value; + + public ArrayList getValue() { + return value; + } + + public void setValue(ArrayList value) { + this.value = value; + } + } + + public static class A { + + } + + public static class B { + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/ArrayListFloatFieldTest.java b/src/test/java/com/alibaba/json/bvt/ArrayListFloatFieldTest.java old mode 100644 new mode 100755 similarity index 77% rename from src/test/java/com/alibaba/json/test/bvt/ArrayListFloatFieldTest.java rename to src/test/java/com/alibaba/json/bvt/ArrayListFloatFieldTest.java index cd5a9300ab..6897f63edb --- a/src/test/java/com/alibaba/json/test/bvt/ArrayListFloatFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/ArrayListFloatFieldTest.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.ArrayList; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -20,12 +20,16 @@ public void test_codec() throws Exception { User user1 = JSON.parseObject(text, User.class); - Assert.assertEquals(user1.getValue(), user.getValue()); + Assert.assertEquals(user.getValue(), user1.getValue()); } public static class User { private ArrayList value; + + public User() { + + } public List getValue() { return value; diff --git a/src/test/java/com/alibaba/json/bvt/ArrayRefTest.java b/src/test/java/com/alibaba/json/bvt/ArrayRefTest.java new file mode 100755 index 0000000000..d296713e07 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ArrayRefTest.java @@ -0,0 +1,71 @@ +package com.alibaba.json.bvt; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class ArrayRefTest extends TestCase { + + public void test_0() throws Exception { + String text; + { + List groups = new ArrayList(); + + Group g0 = new Group(0); + Group g1 = new Group(1); + Group g2 = new Group(2); + + groups.add(g0); + groups.add(g1); + groups.add(g2); + groups.add(g0); + groups.add(g1); + groups.add(g2); + + text = JSON.toJSONString(groups); + } + + System.out.println(text); + + List groups = JSON.parseObject(text, new TypeReference>() {}); + Assert.assertEquals(6, groups.size()); + + Assert.assertEquals(0, groups.get(0).getId()); + Assert.assertEquals(1, groups.get(1).getId()); + Assert.assertEquals(2, groups.get(2).getId()); + Assert.assertEquals(0, groups.get(3).getId()); + Assert.assertEquals(1, groups.get(4).getId()); + Assert.assertEquals(2, groups.get(5).getId()); + } + + public static class Group { + + private int id; + + public Group(){ + + } + + public Group(int id){ + this.id = id; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String toString() { + return "{id:" + id + "}"; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/AtomicBooleanReadOnlyTest.java b/src/test/java/com/alibaba/json/bvt/AtomicBooleanReadOnlyTest.java new file mode 100644 index 0000000000..4a7cac0508 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/AtomicBooleanReadOnlyTest.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt; + +import java.util.concurrent.atomic.AtomicBoolean; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class AtomicBooleanReadOnlyTest extends TestCase { + + public void test_codec_null() throws Exception { + V0 v = new V0(true); + + String text = JSON.toJSONString(v); + Assert.assertEquals("{\"value\":true}", text); + + V0 v1 = JSON.parseObject(text, V0.class); + + Assert.assertEquals(v1.getValue().get(), v.getValue().get()); + } + + public static class V0 { + + private final AtomicBoolean value; + + public V0(){ + this(false); + } + + public V0(boolean value){ + this.value = new AtomicBoolean(value); + } + + public AtomicBoolean getValue() { + return value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/AtomicIntegerArrayFieldTest.java b/src/test/java/com/alibaba/json/bvt/AtomicIntegerArrayFieldTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/AtomicIntegerArrayFieldTest.java rename to src/test/java/com/alibaba/json/bvt/AtomicIntegerArrayFieldTest.java index d284a9c988..45679f51ec --- a/src/test/java/com/alibaba/json/test/bvt/AtomicIntegerArrayFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/AtomicIntegerArrayFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.concurrent.atomic.AtomicIntegerArray; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/AtomicIntegerReadOnlyTest.java b/src/test/java/com/alibaba/json/bvt/AtomicIntegerReadOnlyTest.java new file mode 100644 index 0000000000..cddbdee5a4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/AtomicIntegerReadOnlyTest.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt; + +import java.util.concurrent.atomic.AtomicInteger; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class AtomicIntegerReadOnlyTest extends TestCase { + + public void test_codec_null() throws Exception { + V0 v = new V0(123); + + String text = JSON.toJSONString(v); + Assert.assertEquals("{\"value\":123}", text); + + V0 v1 = JSON.parseObject(text, V0.class); + + Assert.assertEquals(v1.getValue().intValue(), v.getValue().intValue()); + } + + public static class V0 { + + private final AtomicInteger value; + + public V0(){ + this(0); + } + + public V0(int value){ + this.value = new AtomicInteger(value); + } + + public AtomicInteger getValue() { + return value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/AtomicLongArrayFieldTest.java b/src/test/java/com/alibaba/json/bvt/AtomicLongArrayFieldTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/AtomicLongArrayFieldTest.java rename to src/test/java/com/alibaba/json/bvt/AtomicLongArrayFieldTest.java index 2e67259da4..dfbae3b59f --- a/src/test/java/com/alibaba/json/test/bvt/AtomicLongArrayFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/AtomicLongArrayFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.concurrent.atomic.AtomicLongArray; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/AtomicLongReadOnlyTest.java b/src/test/java/com/alibaba/json/bvt/AtomicLongReadOnlyTest.java new file mode 100644 index 0000000000..8044f5b129 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/AtomicLongReadOnlyTest.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt; + +import java.util.concurrent.atomic.AtomicLong; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class AtomicLongReadOnlyTest extends TestCase { + + public void test_codec_null() throws Exception { + V0 v = new V0(123); + + String text = JSON.toJSONString(v); + Assert.assertEquals("{\"value\":123}", text); + + V0 v1 = JSON.parseObject(text, V0.class); + + Assert.assertEquals(v1.getValue().intValue(), v.getValue().intValue()); + } + + public static class V0 { + + private final AtomicLong value; + + public V0(){ + this(0); + } + + public V0(int value){ + this.value = new AtomicLong(value); + } + + public AtomicLong getValue() { + return value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/Base64Test.java b/src/test/java/com/alibaba/json/bvt/Base64Test.java new file mode 100755 index 0000000000..242ebe0c87 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/Base64Test.java @@ -0,0 +1,14 @@ +package com.alibaba.json.bvt; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.util.Base64; + + +public class Base64Test extends TestCase { + public void test_base64() throws Exception { + Assert.assertEquals(Base64.decodeFast(new char[0], 0, 0).length, 0); + Assert.assertEquals(Base64.decodeFast("ABC".toCharArray(), 0, 3).length, 2); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/Base64Test2.java b/src/test/java/com/alibaba/json/bvt/Base64Test2.java new file mode 100644 index 0000000000..9194685fb6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/Base64Test2.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.util.Base64; + +public class Base64Test2 extends TestCase { + + public void test_base64_2() throws Exception { + new Base64(); + String text = ""; + for (int i = 0; i < 1000; ++i) { + byte[] bytes = text.getBytes("UTF-8"); + { + String str = com.alibaba.json.test.Base64.encodeToString(bytes, true); + Assert.assertEquals(text, new String(Base64.decodeFast(str.toCharArray(), 0, str.length()), "UTF-8")); + Assert.assertEquals(text, new String(Base64.decodeFast(str), "UTF-8")); + Assert.assertEquals(text, new String(Base64.decodeFast(str, 0, str.length()), "UTF-8")); + } + { + String str = com.alibaba.json.test.Base64.encodeToString(bytes, false); + Assert.assertEquals(text, new String(Base64.decodeFast(str.toCharArray(), 0, str.length()), "UTF-8")); + Assert.assertEquals(text, new String(Base64.decodeFast(str), "UTF-8")); + Assert.assertEquals(text, new String(Base64.decodeFast(str, 0, str.length()), "UTF-8")); + } + text += ((char) i); + + } + } + + public void test_illegal() throws Exception { + String text = "abc"; + byte[] bytes = text.getBytes("UTF-8"); + String str = "\0" + com.alibaba.json.test.Base64.encodeToString(bytes, false) + "\0"; + Assert.assertEquals(text, new String(Base64.decodeFast(str.toCharArray(), 0, str.length()), "UTF-8")); + Assert.assertEquals(text, new String(Base64.decodeFast(str), "UTF-8")); + Assert.assertEquals(text, new String(Base64.decodeFast(str, 0, str.length()), "UTF-8")); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/BigDecimalFieldTest.java b/src/test/java/com/alibaba/json/bvt/BigDecimalFieldTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/BigDecimalFieldTest.java rename to src/test/java/com/alibaba/json/bvt/BigDecimalFieldTest.java index ca1b95d4a2..d57eadae41 --- a/src/test/java/com/alibaba/json/test/bvt/BigDecimalFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/BigDecimalFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.math.BigDecimal; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/BigIntegerFieldTest.java b/src/test/java/com/alibaba/json/bvt/BigIntegerFieldTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/BigIntegerFieldTest.java rename to src/test/java/com/alibaba/json/bvt/BigIntegerFieldTest.java index 76e157fc83..01fb2b24a1 --- a/src/test/java/com/alibaba/json/test/bvt/BigIntegerFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/BigIntegerFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.math.BigInteger; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/BooleanArrayFieldTest.java b/src/test/java/com/alibaba/json/bvt/BooleanArrayFieldTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/BooleanArrayFieldTest.java rename to src/test/java/com/alibaba/json/bvt/BooleanArrayFieldTest.java index e1ef66b488..e133a2a13e --- a/src/test/java/com/alibaba/json/test/bvt/BooleanArrayFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/BooleanArrayFieldTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/BooleanArrayFieldTest_primitive.java b/src/test/java/com/alibaba/json/bvt/BooleanArrayFieldTest_primitive.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/BooleanArrayFieldTest_primitive.java rename to src/test/java/com/alibaba/json/bvt/BooleanArrayFieldTest_primitive.java index acf54e0f14..448f2e73be --- a/src/test/java/com/alibaba/json/test/bvt/BooleanArrayFieldTest_primitive.java +++ b/src/test/java/com/alibaba/json/bvt/BooleanArrayFieldTest_primitive.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/bug/Bug12.java b/src/test/java/com/alibaba/json/bvt/Bug12.java similarity index 56% rename from src/test/java/com/alibaba/json/test/bvt/bug/Bug12.java rename to src/test/java/com/alibaba/json/bvt/Bug12.java index 3ac5719862..553e66df57 100644 --- a/src/test/java/com/alibaba/json/test/bvt/bug/Bug12.java +++ b/src/test/java/com/alibaba/json/bvt/Bug12.java @@ -1,21 +1,24 @@ -package com.alibaba.json.test.bvt.bug; +package com.alibaba.json.bvt; import java.io.InputStream; +import java.io.InputStreamReader; import junit.framework.TestCase; import org.apache.commons.io.IOUtils; +import org.junit.Assert; import com.alibaba.fastjson.JSON; public class Bug12 extends TestCase { public void test_0() throws Exception { - String resource = "json.json"; + String resource = "2.json"; InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource); - String text = IOUtils.toString(is); + String text = IOUtils.toString(new InputStreamReader(is, "UTF-8")); is.close(); - JSON.parse(text); + Object obj = JSON.parse(text); + Assert.assertNotNull(obj); } } diff --git a/src/test/java/com/alibaba/json/bvt/Bug89.java b/src/test/java/com/alibaba/json/bvt/Bug89.java new file mode 100644 index 0000000000..e73346de3d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/Bug89.java @@ -0,0 +1,20 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import org.junit.Test; + +import static org.junit.Assert.fail; + +public class Bug89 { + @Test + public void testBug89() { + try { + String s = "{\"a\":з」∠)_,\"}"; + JSON.parseObject(s); + fail("Expect JSONException"); + } catch (JSONException e) { + // good + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/BuilderTest.java b/src/test/java/com/alibaba/json/bvt/BuilderTest.java new file mode 100755 index 0000000000..4ba83dcdf3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/BuilderTest.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class BuilderTest extends TestCase { + public void test_builder() throws Exception { + RainbowStats rainbowStats = JSON.parseObject("{\"id\":33}", RainbowStats.class); + Assert.assertEquals(33, rainbowStats.getId()); + } + + private static class RainbowStats { + private int id; + private String name; + + public int getId() { + return id; + } + + public RainbowStats setId(int id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public RainbowStats setName(String name) { + this.name = name; + return this; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/ByteArrayFieldTest_primitive.java b/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_1.java old mode 100644 new mode 100755 similarity index 83% rename from src/test/java/com/alibaba/json/test/bvt/ByteArrayFieldTest_primitive.java rename to src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_1.java index ff95d785b9..efd64ec38e --- a/src/test/java/com/alibaba/json/test/bvt/ByteArrayFieldTest_primitive.java +++ b/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_1.java @@ -1,16 +1,16 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializeConfig; import com.alibaba.fastjson.serializer.SerializerFeature; -public class ByteArrayFieldTest_primitive extends TestCase { +public class ByteArrayFieldTest_1 extends TestCase { public void test_array() throws Exception { - Assert.assertEquals("[1]", JSON.toJSONString(new byte[] { 1 })); + Assert.assertEquals("\"AQ==\"", JSON.toJSONString(new byte[] { 1 })); } diff --git a/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_2.java b/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_2.java new file mode 100755 index 0000000000..dd81f96e0a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_2.java @@ -0,0 +1,45 @@ +package com.alibaba.json.bvt; + +import java.io.UnsupportedEncodingException; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.json.test.TestUtils; + +public class ByteArrayFieldTest_2 extends TestCase { + + public void test_0() throws Exception { + Entity entity = new Entity("中华人民共和国"); + String text = JSON.toJSONString(entity); + JSONObject json = JSON.parseObject(text); + Assert.assertEquals(TestUtils.encodeToBase64String(entity.getValue(), false), json.getString("value")); + + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertEquals("中华人民共和国", new String(entity2.getValue(), "UTF-8")); + } + + public static class Entity { + + private byte[] value; + + public Entity(){ + + } + + public Entity(String value) throws UnsupportedEncodingException{ + this.value = value.getBytes("UTF-8"); + } + + public byte[] getValue() { + return value; + } + + public void setValue(byte[] value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_3.java b/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_3.java new file mode 100755 index 0000000000..b47179fb7a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ByteArrayFieldTest_3.java @@ -0,0 +1,45 @@ +package com.alibaba.json.bvt; + +import java.io.UnsupportedEncodingException; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.json.test.TestUtils; + +public class ByteArrayFieldTest_3 extends TestCase { + + public void test_0() throws Exception { + Entity entity = new Entity("中华人民共和国"); + String text = JSON.toJSONString(entity); + JSONObject json = JSON.parseObject(text); + Assert.assertEquals(TestUtils.encodeToBase64String(entity.getValue(), false), json.getString("value")); + + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertEquals("中华人民共和国", new String(entity2.getValue(), "UTF-8")); + } + + private static class Entity { + + private byte[] value; + + public Entity(){ + + } + + public Entity(String value) throws UnsupportedEncodingException{ + this.value = value.getBytes("UTF-8"); + } + + public byte[] getValue() { + return value; + } + + public void setValue(byte[] value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/ByteFieldTest.java b/src/test/java/com/alibaba/json/bvt/ByteFieldTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/ByteFieldTest.java rename to src/test/java/com/alibaba/json/bvt/ByteFieldTest.java index 04b06e0345..f8e24e94c5 --- a/src/test/java/com/alibaba/json/test/bvt/ByteFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/ByteFieldTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/CalendarTest.java b/src/test/java/com/alibaba/json/bvt/CalendarTest.java new file mode 100644 index 0000000000..69f49f3f0b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/CalendarTest.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt; + +import java.util.Calendar; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class CalendarTest extends TestCase { + + public void test_0() throws Exception { + String text = "{\"calendar\":null}"; + + VO vo = JSON.parseObject(text, VO.class); + Assert.assertNull(vo.getCalendar()); + } + + public static class VO { + + private Calendar calendar; + + public Calendar getCalendar() { + return calendar; + } + + public void setCalendar(Calendar calendar) { + this.calendar = calendar; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/CastTest.java b/src/test/java/com/alibaba/json/bvt/CastTest.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/CastTest.java rename to src/test/java/com/alibaba/json/bvt/CastTest.java index 485d55b06b..5a18b3856f --- a/src/test/java/com/alibaba/json/test/bvt/CastTest.java +++ b/src/test/java/com/alibaba/json/bvt/CastTest.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.ArrayList; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/CastTest2.java b/src/test/java/com/alibaba/json/bvt/CastTest2.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/CastTest2.java rename to src/test/java/com/alibaba/json/bvt/CastTest2.java index 2533edd2e6..43e42e6f27 --- a/src/test/java/com/alibaba/json/test/bvt/CastTest2.java +++ b/src/test/java/com/alibaba/json/bvt/CastTest2.java @@ -1,11 +1,11 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/CharTypesTest.java b/src/test/java/com/alibaba/json/bvt/CharTypesTest.java new file mode 100755 index 0000000000..00d8d3fad0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/CharTypesTest.java @@ -0,0 +1,29 @@ +package com.alibaba.json.bvt; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.util.IOUtils; + +public class CharTypesTest extends TestCase { + static byte[] specicalFlags_singleQuotes = IOUtils.specicalFlags_singleQuotes; + static byte[] specicalFlags_doubleQuotes = IOUtils.specicalFlags_doubleQuotes; + + public void test_0() throws Exception { + + Assert.assertTrue(isSpecial_doubleQuotes('\n')); + Assert.assertTrue(isSpecial_doubleQuotes('\r')); + Assert.assertTrue(isSpecial_doubleQuotes('\b')); + Assert.assertTrue(isSpecial_doubleQuotes('\f')); + Assert.assertTrue(isSpecial_doubleQuotes('\"')); + Assert.assertFalse(isSpecial_doubleQuotes('0')); + Assert.assertTrue(isSpecial_doubleQuotes('\0')); + Assert.assertFalse(isSpecial_doubleQuotes('中')); + Assert.assertFalse(isSpecial_doubleQuotes('中')); + } + + public static boolean isSpecial_doubleQuotes(char ch) { + return ch < specicalFlags_doubleQuotes.length && specicalFlags_doubleQuotes[ch] != 0; + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/CharsetFieldTest.java b/src/test/java/com/alibaba/json/bvt/CharsetFieldTest.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/CharsetFieldTest.java rename to src/test/java/com/alibaba/json/bvt/CharsetFieldTest.java index 9c3ef6e54d..b190b06667 --- a/src/test/java/com/alibaba/json/test/bvt/CharsetFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/CharsetFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.nio.charset.Charset; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/CircularReferenceTest.java b/src/test/java/com/alibaba/json/bvt/CircularReferenceTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/CircularReferenceTest.java rename to src/test/java/com/alibaba/json/bvt/CircularReferenceTest.java index 49b76c2d18..fcb050c342 --- a/src/test/java/com/alibaba/json/test/bvt/CircularReferenceTest.java +++ b/src/test/java/com/alibaba/json/bvt/CircularReferenceTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.io.ByteArrayOutputStream; import java.io.ObjectOutputStream; diff --git a/src/test/java/com/alibaba/json/test/bvt/ClassFieldTest.java b/src/test/java/com/alibaba/json/bvt/ClassFieldTest.java old mode 100644 new mode 100755 similarity index 68% rename from src/test/java/com/alibaba/json/test/bvt/ClassFieldTest.java rename to src/test/java/com/alibaba/json/bvt/ClassFieldTest.java index 864563d304..09eb244600 --- a/src/test/java/com/alibaba/json/test/bvt/ClassFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/ClassFieldTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -23,23 +23,13 @@ public void test_codec() throws Exception { public void test_error() throws Exception { Exception error = null; try { - JSON.parseObject("{\"value\":\"123\"}", User.class); + JSON.parseObject("{\"value\":123}", User.class); } catch (JSONException ex) { error = ex; } Assert.assertNotNull(error); } - public void test_null() throws Exception { - Exception error = null; - try { - ASMClassLoader.forName(null); - } catch (Exception ex) { - error = ex; - } - Assert.assertNotNull(error); - } - public static class User { private Class value; diff --git a/src/test/java/com/alibaba/json/bvt/ColorTest.java b/src/test/java/com/alibaba/json/bvt/ColorTest.java new file mode 100755 index 0000000000..4f04773f11 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ColorTest.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt; + +import java.awt.Color; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.ColorCodec; +import com.alibaba.fastjson.serializer.JSONSerializer; + + +public class ColorTest extends TestCase { + public void test_color() throws Exception { + JSONSerializer serializer = new JSONSerializer(); + Assert.assertEquals(ColorCodec.class, serializer.getObjectWriter(Color.class).getClass()); + + Color color = Color.RED; + String text = JSON.toJSONString(color); + System.out.println(text); + + Color color2 = JSON.parseObject(text, Color.class); + + Assert.assertEquals(color, color2); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/ColorTest2.java b/src/test/java/com/alibaba/json/bvt/ColorTest2.java new file mode 100755 index 0000000000..6e881615c6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ColorTest2.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt; + +import java.awt.Color; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.ColorCodec; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class ColorTest2 extends TestCase { + public void test_color() throws Exception { + JSONSerializer serializer = new JSONSerializer(); + Assert.assertEquals(ColorCodec.class, serializer.getObjectWriter(Color.class).getClass()); + + Color color = Color.RED; + String text = JSON.toJSONString(color, SerializerFeature.WriteClassName); + System.out.println(text); + + Color color2 = (Color) JSON.parse(text); + + Assert.assertEquals(color, color2); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/CurrencyTest.java b/src/test/java/com/alibaba/json/bvt/CurrencyTest.java new file mode 100644 index 0000000000..1146641391 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/CurrencyTest.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt; + +import java.util.Currency; +import java.util.Locale; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class CurrencyTest extends TestCase { + + public void test_0() throws Exception { + VO vo = new VO(); + vo.setValue(Currency.getInstance(Locale.CHINA)); + String text = JSON.toJSONString(vo); + System.out.println(text); + JSON.parseObject(text, VO.class); + } + + public static class VO { + + private Currency value; + + public Currency getValue() { + return value; + } + + public void setValue(Currency value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/CurrencyTest_2.java b/src/test/java/com/alibaba/json/bvt/CurrencyTest_2.java new file mode 100644 index 0000000000..318ebf02c7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/CurrencyTest_2.java @@ -0,0 +1,43 @@ +package com.alibaba.json.bvt; + +import java.util.Currency; +import java.util.Locale; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class CurrencyTest_2 extends TestCase { + + public void test_0() throws Exception { + VO vo = new VO(); + vo.setValue(Currency.getInstance(Locale.CHINA)); + vo.setValue1(Currency.getInstance(Locale.CHINA)); + String text = JSON.toJSONString(vo); + System.out.println(text); + JSON.parseObject(text, VO.class); + } + + public static class VO { + + private Currency value; + private Currency value1; + + public Currency getValue() { + return value; + } + + public void setValue(Currency value) { + this.value = value; + } + + public Currency getValue1() { + return value1; + } + + public void setValue1(Currency value1) { + this.value1 = value1; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/DateFieldTest.java b/src/test/java/com/alibaba/json/bvt/DateFieldTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/DateFieldTest.java rename to src/test/java/com/alibaba/json/bvt/DateFieldTest.java index fb31fda7d6..b46319a7fc --- a/src/test/java/com/alibaba/json/test/bvt/DateFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/DateFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.Date; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/DateFieldTest2.java b/src/test/java/com/alibaba/json/bvt/DateFieldTest2.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/DateFieldTest2.java rename to src/test/java/com/alibaba/json/bvt/DateFieldTest2.java index 0a66d43f00..aa45b29735 --- a/src/test/java/com/alibaba/json/test/bvt/DateFieldTest2.java +++ b/src/test/java/com/alibaba/json/bvt/DateFieldTest2.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.text.SimpleDateFormat; import java.util.Date; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/DateFieldTest3.java b/src/test/java/com/alibaba/json/bvt/DateFieldTest3.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/DateFieldTest3.java rename to src/test/java/com/alibaba/json/bvt/DateFieldTest3.java index 598987b152..90b6106638 --- a/src/test/java/com/alibaba/json/test/bvt/DateFieldTest3.java +++ b/src/test/java/com/alibaba/json/bvt/DateFieldTest3.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.text.SimpleDateFormat; import java.util.Date; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/DateFieldTest4.java b/src/test/java/com/alibaba/json/bvt/DateFieldTest4.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/DateFieldTest4.java rename to src/test/java/com/alibaba/json/bvt/DateFieldTest4.java index 9213146dca..53a2a35f39 --- a/src/test/java/com/alibaba/json/test/bvt/DateFieldTest4.java +++ b/src/test/java/com/alibaba/json/bvt/DateFieldTest4.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.text.SimpleDateFormat; import java.util.Date; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/DateFieldTest5.java b/src/test/java/com/alibaba/json/bvt/DateFieldTest5.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/DateFieldTest5.java rename to src/test/java/com/alibaba/json/bvt/DateFieldTest5.java index 0d7efbea69..e19d8bfac9 --- a/src/test/java/com/alibaba/json/test/bvt/DateFieldTest5.java +++ b/src/test/java/com/alibaba/json/bvt/DateFieldTest5.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.Date; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/DateFieldTest6.java b/src/test/java/com/alibaba/json/bvt/DateFieldTest6.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/DateFieldTest6.java rename to src/test/java/com/alibaba/json/bvt/DateFieldTest6.java index 63c54f8801..b14c616b5c --- a/src/test/java/com/alibaba/json/test/bvt/DateFieldTest6.java +++ b/src/test/java/com/alibaba/json/bvt/DateFieldTest6.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.text.SimpleDateFormat; import java.util.Date; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/DateFieldTest7.java b/src/test/java/com/alibaba/json/bvt/DateFieldTest7.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/DateFieldTest7.java rename to src/test/java/com/alibaba/json/bvt/DateFieldTest7.java index cb1070a570..a57c1add1d --- a/src/test/java/com/alibaba/json/test/bvt/DateFieldTest7.java +++ b/src/test/java/com/alibaba/json/bvt/DateFieldTest7.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.text.SimpleDateFormat; import java.util.Date; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/DateFieldTest8.java b/src/test/java/com/alibaba/json/bvt/DateFieldTest8.java new file mode 100644 index 0000000000..6c96f761d3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/DateFieldTest8.java @@ -0,0 +1,45 @@ +package com.alibaba.json.bvt; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; + +public class DateFieldTest8 extends TestCase { + + public void test_0() throws Exception { + Entity object = new Entity(); + object.setValue(new Date()); + String text = JSON.toJSONStringWithDateFormat(object, "yyyy"); + Assert.assertEquals("{\"value\":\"" + new SimpleDateFormat("yyyy").format(object.getValue()) + "\"}", + text); + } + + public void test_1() throws Exception { + Entity object = new Entity(); + object.setValue(new Date()); + String text = JSON.toJSONString(object); + Assert.assertEquals("{\"value\":\"" + new SimpleDateFormat("yyyy-MM-dd").format(object.getValue()) + "\"}", + text); + } + + public static class Entity { + + @JSONField(format = "yyyy-MM-dd") + private Date value; + + public Date getValue() { + return value; + } + + public void setValue(Date value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/DateTest.java b/src/test/java/com/alibaba/json/bvt/DateTest.java new file mode 100755 index 0000000000..82ca316578 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/DateTest.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt; + +import java.util.Date; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class DateTest extends TestCase { + + public void test_date() throws Exception { + long millis = 1324138987429L; + Date date = new Date(millis); + + Assert.assertEquals("1324138987429", JSON.toJSONString(date)); + + Assert.assertEquals("\"2011-12-18 00:23:07\"", + JSON.toJSONString(date, SerializerFeature.WriteDateUseDateFormat)); + Assert.assertEquals("\"2011-12-18 00:23:07.429\"", + JSON.toJSONStringWithDateFormat(date, "yyyy-MM-dd HH:mm:ss.SSS")); + Assert.assertEquals("'2011-12-18 00:23:07.429'", + JSON.toJSONStringWithDateFormat(date, "yyyy-MM-dd HH:mm:ss.SSS", + SerializerFeature.UseSingleQuotes)); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/DefaultJSONParserTest.java b/src/test/java/com/alibaba/json/bvt/DefaultJSONParserTest.java old mode 100644 new mode 100755 similarity index 84% rename from src/test/java/com/alibaba/json/test/bvt/DefaultJSONParserTest.java rename to src/test/java/com/alibaba/json/bvt/DefaultJSONParserTest.java index abc5d8eaa8..c4d44230e9 --- a/src/test/java/com/alibaba/json/test/bvt/DefaultJSONParserTest.java +++ b/src/test/java/com/alibaba/json/bvt/DefaultJSONParserTest.java @@ -13,11 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.HashMap; +import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.parser.DefaultJSONParser; @@ -34,6 +35,14 @@ public void test_double() { Assert.assertEquals(3.4D, result); } + public void test_double_in_object() { + DefaultJSONParser parser = new DefaultJSONParser("{\"double\":3.4}"); + parser.config(Feature.UseBigDecimal, false); + Assert.assertEquals("{\"double\":3.4}", parser.getInput()); + Object result = parser.parse(); + Assert.assertEquals(3.4D, ((Map) result).get("double")); + } + public void test_error() { Exception error = null; try { diff --git a/src/main/java/com/alibaba/fastjson/serializer/PatternSerializer.java b/src/test/java/com/alibaba/json/bvt/DefaultJSONParserTest_ref.java similarity index 50% rename from src/main/java/com/alibaba/fastjson/serializer/PatternSerializer.java rename to src/test/java/com/alibaba/json/bvt/DefaultJSONParserTest_ref.java index db56805f57..bd4926643e 100644 --- a/src/main/java/com/alibaba/fastjson/serializer/PatternSerializer.java +++ b/src/test/java/com/alibaba/json/bvt/DefaultJSONParserTest_ref.java @@ -1,38 +1,34 @@ -/* - * Copyright 1999-2101 Alibaba Group. - * - * Licensed 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 com.alibaba.fastjson.serializer; - -import java.io.IOException; -import java.util.regex.Pattern; - -/** - * @author wenshao - */ -public class PatternSerializer implements ObjectSerializer { - - public final static PatternSerializer instance = new PatternSerializer(); - - public void write(JSONSerializer serializer, Object object) throws IOException { - if (object == null) { - serializer.writeNull(); - return; - } - - Pattern p = (Pattern) object; - serializer.write(p.pattern()); - } - -} +/* + * Copyright 1999-2101 Alibaba Group. + * + * Licensed 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 com.alibaba.json.bvt; + +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class DefaultJSONParserTest_ref extends TestCase { + + public void test_ref() { + Map obj = JSON.parseObject("{\"id\":{},\"value\":{\"$ref\":\"$\"}}", Map.class); + Assert.assertTrue(obj == obj.get("value")); + } + + +} diff --git a/src/test/java/com/alibaba/json/test/bvt/DoubleArrayFieldTest_primitive.java b/src/test/java/com/alibaba/json/bvt/DoubleArrayFieldTest_primitive.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/DoubleArrayFieldTest_primitive.java rename to src/test/java/com/alibaba/json/bvt/DoubleArrayFieldTest_primitive.java index eebe0d77b4..1171616a76 --- a/src/test/java/com/alibaba/json/test/bvt/DoubleArrayFieldTest_primitive.java +++ b/src/test/java/com/alibaba/json/bvt/DoubleArrayFieldTest_primitive.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/DoubleFieldTest_A.java b/src/test/java/com/alibaba/json/bvt/DoubleFieldTest_A.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/DoubleFieldTest_A.java rename to src/test/java/com/alibaba/json/bvt/DoubleFieldTest_A.java index 1dea8c1a99..48d55ecbca --- a/src/test/java/com/alibaba/json/test/bvt/DoubleFieldTest_A.java +++ b/src/test/java/com/alibaba/json/bvt/DoubleFieldTest_A.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/EmptyObjectTest.java b/src/test/java/com/alibaba/json/bvt/EmptyObjectTest.java old mode 100644 new mode 100755 similarity index 90% rename from src/test/java/com/alibaba/json/test/bvt/EmptyObjectTest.java rename to src/test/java/com/alibaba/json/bvt/EmptyObjectTest.java index 2d2942d4a7..9400ca98ae --- a/src/test/java/com/alibaba/json/test/bvt/EmptyObjectTest.java +++ b/src/test/java/com/alibaba/json/bvt/EmptyObjectTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/EnumerationTest.java b/src/test/java/com/alibaba/json/bvt/EnumerationTest.java new file mode 100755 index 0000000000..390812be31 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/EnumerationTest.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt; + +import java.util.Collections; +import java.util.Enumeration; +import java.util.Vector; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class EnumerationTest extends TestCase { + + public void test_enumeration() throws Exception { + Assert.assertEquals("[]", JSON.toJSONString(new Vector().elements())); + Assert.assertEquals("[null]", JSON.toJSONString(new Vector(Collections.singleton(null)).elements())); + + Assert.assertEquals("{\"value\":[]}", JSON.toJSONString(new VO(), SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty)); + } + + private static class VO { + + private Enumeration value; + + public Enumeration getValue() { + return value; + } + + public void setValue(Enumeration value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/FeaturesTest.java b/src/test/java/com/alibaba/json/bvt/FeaturesTest.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/FeaturesTest.java rename to src/test/java/com/alibaba/json/bvt/FeaturesTest.java index 97145c2b0a..039f2dd020 --- a/src/test/java/com/alibaba/json/test/bvt/FeaturesTest.java +++ b/src/test/java/com/alibaba/json/bvt/FeaturesTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/FeaturesTest2.java b/src/test/java/com/alibaba/json/bvt/FeaturesTest2.java new file mode 100755 index 0000000000..a4d65f2631 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/FeaturesTest2.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class FeaturesTest2 extends TestCase { + + public void test_0() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.setAsmEnable(false); + + String text = JSON.toJSONString(new Entity(), config); + Assert.assertEquals("{\"value\":0}", text); + } + + public void test_1() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.setAsmEnable(true); + + String text = JSON.toJSONString(new Entity(), config); + Assert.assertEquals("{\"value\":0}", text); + } + + private static class Entity { + + private Integer value; + + @JSONField(serialzeFeatures = { SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullNumberAsZero }) + public Integer getValue() { + return value; + } + + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/FeaturesTest3.java b/src/test/java/com/alibaba/json/bvt/FeaturesTest3.java new file mode 100755 index 0000000000..476cd9586a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/FeaturesTest3.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class FeaturesTest3 extends TestCase { + + public void test_0() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.setAsmEnable(false); + + String text = JSON.toJSONString(new Entity(), config); + Assert.assertEquals("{\"value\":0}", text); + } + + public void test_1() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.setAsmEnable(true); + + String text = JSON.toJSONString(new Entity(), config); + Assert.assertEquals("{\"value\":0}", text); + } + + public static class Entity { + + private Integer value; + + @JSONField(serialzeFeatures = { SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullNumberAsZero }) + public Integer getValue() { + return value; + } + + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/FeaturesTest4.java b/src/test/java/com/alibaba/json/bvt/FeaturesTest4.java new file mode 100755 index 0000000000..df06359b1a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/FeaturesTest4.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class FeaturesTest4 extends TestCase { + + public void test_0() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.setAsmEnable(false); + + String text = JSON.toJSONString(new Entity(), config); + Assert.assertEquals("{\"value\":\"\"}", text); + } + + public void test_1() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.setAsmEnable(true); + + String text = JSON.toJSONString(new Entity(), config); + Assert.assertEquals("{\"value\":\"\"}", text); + } + + public static class Entity { + + private String value; + + @JSONField(serialzeFeatures = { SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty }) + public String getValue() { + return value; + } + + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/FeaturesTest5.java b/src/test/java/com/alibaba/json/bvt/FeaturesTest5.java new file mode 100755 index 0000000000..f169cc8bc6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/FeaturesTest5.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class FeaturesTest5 extends TestCase { + + public void test_0() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.setAsmEnable(false); + + String text = JSON.toJSONString(new Entity(), config); + Assert.assertEquals("{\"value\":false}", text); + } + + public void test_1() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.setAsmEnable(true); + + String text = JSON.toJSONString(new Entity(), config); + Assert.assertEquals("{\"value\":false}", text); + } + + public static class Entity { + + private Boolean value; + + @JSONField(serialzeFeatures = { SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullBooleanAsFalse }) + public Boolean getValue() { + return value; + } + + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/FeaturesTest6.java b/src/test/java/com/alibaba/json/bvt/FeaturesTest6.java new file mode 100755 index 0000000000..00957355ef --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/FeaturesTest6.java @@ -0,0 +1,42 @@ +package com.alibaba.json.bvt; + +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class FeaturesTest6 extends TestCase { + + public void test_0() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.setAsmEnable(false); + + String text = JSON.toJSONString(new Entity(), config); + Assert.assertEquals("{\"value\":[]}", text); + } + + public void test_1() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.setAsmEnable(true); + + String text = JSON.toJSONString(new Entity(), config); + Assert.assertEquals("{\"value\":[]}", text); + } + + public static class Entity { + + private List value; + + @JSONField(serialzeFeatures = { SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty }) + public List getValue() { + return value; + } + + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/FeaturesTest7.java b/src/test/java/com/alibaba/json/bvt/FeaturesTest7.java new file mode 100755 index 0000000000..917c99a041 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/FeaturesTest7.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class FeaturesTest7 extends TestCase { + + public void test_0() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.setAsmEnable(false); + + String text = JSON.toJSONString(new Entity(), config); + Assert.assertEquals("{\"value\":\"SECONDS\"}", text); + } + + public void test_1() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.setAsmEnable(true); + + String text = JSON.toJSONString(new Entity(), config); + Assert.assertEquals("{\"value\":\"SECONDS\"}", text); + } + + public static class Entity { + + private TimeUnit value = TimeUnit.SECONDS; + + @JSONField(serialzeFeatures = { SerializerFeature.WriteEnumUsingToString }) + public TimeUnit getValue() { + return value; + } + + + } + + public static enum TimeUnit { + SECONDS, MINUTES + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/FileFieldTest.java b/src/test/java/com/alibaba/json/bvt/FileFieldTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/FileFieldTest.java rename to src/test/java/com/alibaba/json/bvt/FileFieldTest.java index a83fe15c31..c59f10ab24 --- a/src/test/java/com/alibaba/json/test/bvt/FileFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/FileFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.io.File; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/FloatArrayFieldTest_primitive.java b/src/test/java/com/alibaba/json/bvt/FloatArrayFieldTest_primitive.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/FloatArrayFieldTest_primitive.java rename to src/test/java/com/alibaba/json/bvt/FloatArrayFieldTest_primitive.java index 22c01f08d9..94cb213675 --- a/src/test/java/com/alibaba/json/test/bvt/FloatArrayFieldTest_primitive.java +++ b/src/test/java/com/alibaba/json/bvt/FloatArrayFieldTest_primitive.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/FloatFieldTest.java b/src/test/java/com/alibaba/json/bvt/FloatFieldTest.java old mode 100644 new mode 100755 similarity index 78% rename from src/test/java/com/alibaba/json/test/bvt/FloatFieldTest.java rename to src/test/java/com/alibaba/json/bvt/FloatFieldTest.java index 837d826b4e..1e5bac5d3d --- a/src/test/java/com/alibaba/json/test/bvt/FloatFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/FloatFieldTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -16,7 +16,7 @@ public void test_codec() throws Exception { User user1 = JSON.parseObject(text, User.class); - Assert.assertEquals(user1.getValue(), user.getValue()); + Assert.assertTrue(user1.getValue() == user.getValue()); } public static class User { diff --git a/src/test/java/com/alibaba/json/test/bvt/FloatFieldTest_A.java b/src/test/java/com/alibaba/json/bvt/FloatFieldTest_A.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/FloatFieldTest_A.java rename to src/test/java/com/alibaba/json/bvt/FloatFieldTest_A.java index 158799ef3d..59b24c42ae --- a/src/test/java/com/alibaba/json/test/bvt/FloatFieldTest_A.java +++ b/src/test/java/com/alibaba/json/bvt/FloatFieldTest_A.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/FontTest.java b/src/test/java/com/alibaba/json/bvt/FontTest.java new file mode 100755 index 0000000000..323df4bbb6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/FontTest.java @@ -0,0 +1,22 @@ +package com.alibaba.json.bvt; + +import java.awt.Font; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class FontTest extends TestCase { + + public void test_color() throws Exception { + Font[] fonts = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); + for (Font font : fonts) { + String text = JSON.toJSONString(font); + + Font font2 = JSON.parseObject(text, Font.class); + + Assert.assertEquals(font, font2); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/FontTest2.java b/src/test/java/com/alibaba/json/bvt/FontTest2.java new file mode 100755 index 0000000000..fb77f77477 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/FontTest2.java @@ -0,0 +1,23 @@ +package com.alibaba.json.bvt; + +import java.awt.Font; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class FontTest2 extends TestCase { + + public void test_color() throws Exception { + Font[] fonts = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); + for (Font font : fonts) { + String text = JSON.toJSONString(font, SerializerFeature.WriteClassName); + + Font font2 = (Font) JSON.parse(text); + + Assert.assertEquals(font, font2); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/GroovyTest.java b/src/test/java/com/alibaba/json/bvt/GroovyTest.java new file mode 100755 index 0000000000..2861f2ac78 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/GroovyTest.java @@ -0,0 +1,48 @@ +package com.alibaba.json.bvt; + +import groovy.lang.GroovyClassLoader; +import groovy.lang.GroovyObject; +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class GroovyTest extends TestCase { + + public void test_groovy() throws Exception { + ClassLoader parent = Thread.currentThread().getContextClassLoader(); + GroovyClassLoader loader = new GroovyClassLoader(parent); + + // A类 + Class AClass = loader.parseClass("class A {\n" + // + " int id\n" + // + "}"); + + // A实例 + GroovyObject a = (GroovyObject) AClass.newInstance(); + a.setProperty("id", 33); + String textA = JSON.toJSONString(a); + + GroovyObject aa = (GroovyObject) JSON.parseObject(textA, AClass); + Assert.assertEquals(a.getProperty("id"), aa.getProperty("id")); + + System.out.println(a); + + // B类,继承于A + Class BClass = loader.parseClass("class B extends A {\n" + // + " String name\n" + // + "}"); + + // B实例 + GroovyObject b = (GroovyObject) BClass.newInstance(); + b.setProperty("name", "jobs"); + String textB = JSON.toJSONString(b); + GroovyObject bb = (GroovyObject) JSON.parseObject(textB, BClass); + Assert.assertEquals(b.getProperty("id"), bb.getProperty("id")); + Assert.assertEquals(b.getProperty("name"), bb.getProperty("name")); + + + // 序列化失败 + System.out.println(JSON.toJSONString(b, true)); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/InetAddressFieldTest.java b/src/test/java/com/alibaba/json/bvt/InetAddressFieldTest.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/InetAddressFieldTest.java rename to src/test/java/com/alibaba/json/bvt/InetAddressFieldTest.java index 72cffbd886..7dc6852dd2 --- a/src/test/java/com/alibaba/json/test/bvt/InetAddressFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/InetAddressFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.net.InetAddress; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/InetSocketAddressFieldTest.java b/src/test/java/com/alibaba/json/bvt/InetSocketAddressFieldTest.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/InetSocketAddressFieldTest.java rename to src/test/java/com/alibaba/json/bvt/InetSocketAddressFieldTest.java index 5469a40d19..06fb15b164 --- a/src/test/java/com/alibaba/json/test/bvt/InetSocketAddressFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/InetSocketAddressFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.net.InetSocketAddress; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/IntArrayFieldTest_primitive.java b/src/test/java/com/alibaba/json/bvt/IntArrayFieldTest_primitive.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/IntArrayFieldTest_primitive.java rename to src/test/java/com/alibaba/json/bvt/IntArrayFieldTest_primitive.java index c458577be2..59e1d669de --- a/src/test/java/com/alibaba/json/test/bvt/IntArrayFieldTest_primitive.java +++ b/src/test/java/com/alibaba/json/bvt/IntArrayFieldTest_primitive.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/IntKeyMapTest.java b/src/test/java/com/alibaba/json/bvt/IntKeyMapTest.java new file mode 100755 index 0000000000..fe09709ace --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/IntKeyMapTest.java @@ -0,0 +1,12 @@ +package com.alibaba.json.bvt; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class IntKeyMapTest extends TestCase { + + public void test_0() throws Exception { + JSON.parse("{1:\"AA\",2:{}}"); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/IntegerArrayFieldTest.java b/src/test/java/com/alibaba/json/bvt/IntegerArrayFieldTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/IntegerArrayFieldTest.java rename to src/test/java/com/alibaba/json/bvt/IntegerArrayFieldTest.java index aab4faf3e9..b287a8c5e2 --- a/src/test/java/com/alibaba/json/test/bvt/IntegerArrayFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/IntegerArrayFieldTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/Issue213Test.java b/src/test/java/com/alibaba/json/bvt/Issue213Test.java new file mode 100644 index 0000000000..a4b69f3be6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/Issue213Test.java @@ -0,0 +1,84 @@ +package com.alibaba.json.bvt; + +import java.io.Serializable; +import java.util.Date; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Issue213Test extends TestCase { + + public void test_0() throws Exception { + String text = "\t\t\t\t\t\t \u00A020:00-21:30
\r\n\r\n

\r\n

\r\n\t\r\n

\r\n

\r\n\t
\r\n

\r\n\t\t\t"; + Product e = new Product(); + e.setIntro(text); + byte[] r = JSON.toJSONBytes(e); + JSON.parseObject(r, Product.class); + } + + public static class Product implements Serializable { + + private static final long serialVersionUID = 5515785177596600948L; + + private String studyTargets; + + private String applicableUsers; + + private String intro; + + private Date createDateTime; + + private int createUserId; + + private int liveStatus; + + public String getStudyTargets() { + return studyTargets; + } + + public void setStudyTargets(String studyTargets) { + this.studyTargets = studyTargets; + } + + public String getApplicableUsers() { + return applicableUsers; + } + + public void setApplicableUsers(String applicableUsers) { + this.applicableUsers = applicableUsers; + } + + public String getIntro() { + return intro; + } + + public void setIntro(String intro) { + this.intro = intro; + } + + public int getCreateUserId() { + return createUserId; + } + + public void setCreateUserId(int createUserId) { + this.createUserId = createUserId; + } + + public int getLiveStatus() { + return liveStatus; + } + + public void setLiveStatus(int liveStatus) { + this.liveStatus = liveStatus; + } + + public Date getCreateDateTime() { + return createDateTime; + } + + public void setCreateDateTime(Date createDateTime) { + this.createDateTime = createDateTime; + } + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/JSONArrayTest.java b/src/test/java/com/alibaba/json/bvt/JSONArrayTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/JSONArrayTest.java rename to src/test/java/com/alibaba/json/bvt/JSONArrayTest.java index 9bb749cf78..09f3c90e9b --- a/src/test/java/com/alibaba/json/test/bvt/JSONArrayTest.java +++ b/src/test/java/com/alibaba/json/bvt/JSONArrayTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.io.StringWriter; import java.math.BigDecimal; @@ -25,7 +25,7 @@ import java.util.ListIterator; import java.util.concurrent.atomic.AtomicInteger; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -117,11 +117,11 @@ public void test_2() throws Exception { Assert.assertEquals(123, array.getShort(0).shortValue()); Assert.assertEquals(123, array.getShortValue(0)); - Assert.assertEquals(123F, array.getFloat(0).floatValue()); - Assert.assertEquals(123F, array.getFloatValue(0)); + Assert.assertTrue(123F == array.getFloat(0).floatValue()); + Assert.assertTrue(123F == array.getFloatValue(0)); - Assert.assertEquals(123D, array.getDouble(0).doubleValue()); - Assert.assertEquals(123D, array.getDoubleValue(0)); + Assert.assertTrue(123D == array.getDouble(0).doubleValue()); + Assert.assertTrue(123D == array.getDoubleValue(0)); Assert.assertEquals(123, array.getIntValue(0)); Assert.assertEquals(123, array.getLongValue(0)); diff --git a/src/test/java/com/alibaba/json/test/bvt/JSONArrayTest2.java b/src/test/java/com/alibaba/json/bvt/JSONArrayTest2.java old mode 100644 new mode 100755 similarity index 80% rename from src/test/java/com/alibaba/json/test/bvt/JSONArrayTest2.java rename to src/test/java/com/alibaba/json/bvt/JSONArrayTest2.java index c5e79b1099..3eaaa5d0d7 --- a/src/test/java/com/alibaba/json/test/bvt/JSONArrayTest2.java +++ b/src/test/java/com/alibaba/json/bvt/JSONArrayTest2.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.math.BigInteger; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONArray; @@ -17,8 +17,8 @@ public void test_0() throws Exception { array.add(time); Assert.assertEquals(0, array.getByteValue(0)); Assert.assertEquals(0, array.getShortValue(0)); - Assert.assertEquals(0F, array.getFloatValue(0)); - Assert.assertEquals(0D, array.getDoubleValue(0)); + Assert.assertTrue(0F == array.getFloatValue(0)); + Assert.assertTrue(0D == array.getDoubleValue(0)); Assert.assertEquals(new BigInteger("1"), array.getBigInteger(1)); Assert.assertEquals("1", array.getString(1)); Assert.assertEquals(new java.util.Date(time), array.getDate(2)); @@ -28,8 +28,8 @@ public void test_0() throws Exception { JSONArray array2 = (JSONArray) array.clone(); Assert.assertEquals(0, array2.getByteValue(0)); Assert.assertEquals(0, array2.getShortValue(0)); - Assert.assertEquals(0F, array2.getFloatValue(0)); - Assert.assertEquals(0D, array2.getDoubleValue(0)); + Assert.assertTrue(0F == array2.getFloatValue(0)); + Assert.assertTrue(0D == array2.getDoubleValue(0)); Assert.assertEquals(new BigInteger("1"), array2.getBigInteger(1)); Assert.assertEquals("1", array2.getString(1)); Assert.assertEquals(new java.util.Date(time), array2.getDate(2)); diff --git a/src/test/java/com/alibaba/json/test/bvt/JSONArrayTest_hashCode.java b/src/test/java/com/alibaba/json/bvt/JSONArrayTest_hashCode.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/JSONArrayTest_hashCode.java rename to src/test/java/com/alibaba/json/bvt/JSONArrayTest_hashCode.java index 3e44286507..e8373bd4a3 --- a/src/test/java/com/alibaba/json/test/bvt/JSONArrayTest_hashCode.java +++ b/src/test/java/com/alibaba/json/bvt/JSONArrayTest_hashCode.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/JSONExceptionTest.java b/src/test/java/com/alibaba/json/bvt/JSONExceptionTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/JSONExceptionTest.java rename to src/test/java/com/alibaba/json/bvt/JSONExceptionTest.java index 8d45f560b1..ced2a856b2 --- a/src/test/java/com/alibaba/json/test/bvt/JSONExceptionTest.java +++ b/src/test/java/com/alibaba/json/bvt/JSONExceptionTest.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONException; diff --git a/src/test/java/com/alibaba/json/bvt/JSONFeidDemo2.java b/src/test/java/com/alibaba/json/bvt/JSONFeidDemo2.java new file mode 100755 index 0000000000..a13164f340 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSONFeidDemo2.java @@ -0,0 +1,82 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +public class JSONFeidDemo2 extends TestCase { + + public void test_0() throws Exception { + Z_OA_MM_PR_INFO_IN in = new Z_OA_MM_PR_INFO_IN(); + in.setIM_PREQ_NO("111111"); + TB_PR_INFO t1 = new TB_PR_INFO("t1"); + TB_PR_INFO t2 = new TB_PR_INFO("t2"); + List tb_pr_infos = new ArrayList(); + tb_pr_infos.add(t1); + tb_pr_infos.add(t2); + in.setTB_PR_INFO(tb_pr_infos); + + String text = JSON.toJSONString(in); + System.out.println(text); + + assertEquals( + "{\"iM_PREQ_NO\":\"111111\",\"tB_PR_INFO\":[{\"PREQ_NO\":\"t1\"},{\"PREQ_NO\":\"t2\"}]}", + text); + + } + + public void test_1() throws Exception { + String text = "{\"iM_PREQ_NO\":\"111111\",\"TB_PR_INFO\":[{\"pREQ_NO\":\"t1\"},{\"pREQ_NO\":\"t2\"}]}"; + Z_OA_MM_PR_INFO_IN in = JSON + .parseObject(text, Z_OA_MM_PR_INFO_IN.class); + assertEquals("111111", in.getIM_PREQ_NO()); + assertNotNull(in.getTB_PR_INFO()); + + } + + public static class Z_OA_MM_PR_INFO_IN { + @JSONField(name = "IM_PREQ_NO") + private String IM_PREQ_NO; + @JSONField(name = "TB_PR_INFO") + private List TB_PR_INFO; + + public List getTB_PR_INFO() { + return TB_PR_INFO; + } + + public void setTB_PR_INFO(List TB_PR_INFO) { + this.TB_PR_INFO = TB_PR_INFO; + } + + public String getIM_PREQ_NO() { + return IM_PREQ_NO; + } + + public void setIM_PREQ_NO(String IM_PREQ_NO) { + this.IM_PREQ_NO = IM_PREQ_NO; + } + } + + public static class TB_PR_INFO { + @JSONField(name = "PREQ_NO") + private String PREQ_NO; + + public TB_PR_INFO() { + } + + public TB_PR_INFO(String PREQ_NO) { + this.PREQ_NO = PREQ_NO; + } + @JSONField(name = "PREQ_NO") + public String getPREQ_NO() { + return PREQ_NO; + } + + public void setPREQ_NO(String PREQ_NO) { + this.PREQ_NO = PREQ_NO; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/JSONFieldTest.java b/src/test/java/com/alibaba/json/bvt/JSONFieldTest.java new file mode 100644 index 0000000000..0b92214c13 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSONFieldTest.java @@ -0,0 +1,53 @@ +package com.alibaba.json.bvt; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; + + +public class JSONFieldTest extends TestCase { + + public void test_field() throws Exception { + Demo demo = new Demo(); + demo.setId(1009); + demo.setName("IT"); + demo.setAge(30); + System.out.println(JSON.toJSON(demo)); + } + + public static class Demo { + private int id; + + @JSONField(serialize = false) + private String name; + + private int age; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/JSONFromObjectTest.java b/src/test/java/com/alibaba/json/bvt/JSONFromObjectTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/JSONFromObjectTest.java rename to src/test/java/com/alibaba/json/bvt/JSONFromObjectTest.java index b2fe8e9d11..10c396e22f --- a/src/test/java/com/alibaba/json/test/bvt/JSONFromObjectTest.java +++ b/src/test/java/com/alibaba/json/bvt/JSONFromObjectTest.java @@ -1,10 +1,10 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/JSONObjectTest.java b/src/test/java/com/alibaba/json/bvt/JSONObjectTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/JSONObjectTest.java rename to src/test/java/com/alibaba/json/bvt/JSONObjectTest.java index abd3b0dd53..0520bfb58a --- a/src/test/java/com/alibaba/json/test/bvt/JSONObjectTest.java +++ b/src/test/java/com/alibaba/json/bvt/JSONObjectTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.io.StringWriter; import java.math.BigDecimal; @@ -21,7 +21,7 @@ import java.util.Date; import java.util.HashMap; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONObject; @@ -156,10 +156,10 @@ public void test_all_2() throws Exception { Assert.assertEquals(new BigDecimal("222"), array.getBigDecimal("1")); Assert.assertEquals(true, array.getBooleanValue("4")); - Assert.assertEquals(2.0F, array.getFloat("5").floatValue()); - Assert.assertEquals(2.0F, array.getFloatValue("5")); - Assert.assertEquals(2.0D, array.getDouble("5").doubleValue()); - Assert.assertEquals(2.0D, array.getDoubleValue("5")); + Assert.assertTrue(2.0F == array.getFloat("5").floatValue()); + Assert.assertTrue(2.0F == array.getFloatValue("5")); + Assert.assertTrue(2.0D == array.getDouble("5").doubleValue()); + Assert.assertTrue(2.0D == array.getDoubleValue("5")); } public void test_getObject_null() throws Exception { @@ -168,6 +168,11 @@ public void test_getObject_null() throws Exception { Assert.assertTrue(json.getJSONObject("obj") == null); } + + public void test_bytes () throws Exception { + JSONObject object = new JSONObject(); + Assert.assertNull(object.getBytes("bytes")); + } public void test_getObject() throws Exception { JSONObject json = new JSONObject(); diff --git a/src/test/java/com/alibaba/json/test/bvt/JSONObjectTest2.java b/src/test/java/com/alibaba/json/bvt/JSONObjectTest2.java old mode 100644 new mode 100755 similarity index 84% rename from src/test/java/com/alibaba/json/test/bvt/JSONObjectTest2.java rename to src/test/java/com/alibaba/json/bvt/JSONObjectTest2.java index 6c508b2d1f..601a015e82 --- a/src/test/java/com/alibaba/json/test/bvt/JSONObjectTest2.java +++ b/src/test/java/com/alibaba/json/bvt/JSONObjectTest2.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.LinkedHashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONArray; @@ -31,8 +31,8 @@ public void test_0() throws Exception { Assert.assertEquals(obj.getByteValue("d"), 0); Assert.assertEquals(obj.getShortValue("d"), 0); - Assert.assertEquals(obj.getFloatValue("d"), 0F); - Assert.assertEquals(obj.getDoubleValue("d"), 0D); + Assert.assertTrue(obj.getFloatValue("d") == 0F); + Assert.assertTrue(obj.getDoubleValue("d") == 0D); Assert.assertEquals(obj.getBigInteger("d"), null); Assert.assertEquals(obj.getSqlDate("d"), null); Assert.assertEquals(obj.getTimestamp("d"), null); diff --git a/src/test/java/com/alibaba/json/bvt/JSONObjectTest3.java b/src/test/java/com/alibaba/json/bvt/JSONObjectTest3.java new file mode 100755 index 0000000000..cfad9757f8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSONObjectTest3.java @@ -0,0 +1,182 @@ +package com.alibaba.json.bvt; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.annotation.JSONField; + +public class JSONObjectTest3 extends TestCase { + + public void test_0() throws Exception { + String text = "{value:'123',big:false}"; + Bean bean = JSON.parseObject(text, Bean.class); + Assert.assertEquals("123", bean.getValue()); + Assert.assertEquals(false, bean.isBig()); + Assert.assertEquals(123, bean.getIntValue()); + + bean.setBig(true); + Assert.assertEquals(true, bean.isBig()); + + bean.setID(567); + Assert.assertEquals(567, bean.getID()); + + } + + public void test_error_0() throws Exception { + String text = "{value:'123',big:false}"; + Bean bean = JSON.parseObject(text, Bean.class); + + JSONException error = null; + try { + bean.f(); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_1() throws Exception { + String text = "{value:'123',big:false}"; + Bean bean = JSON.parseObject(text, Bean.class); + + JSONException error = null; + try { + bean.f(1); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_2() throws Exception { + String text = "{value:'123',big:false}"; + Bean bean = JSON.parseObject(text, Bean.class); + + JSONException error = null; + try { + bean.get(); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_3() throws Exception { + String text = "{value:'123',big:false}"; + Bean bean = JSON.parseObject(text, Bean.class); + + JSONException error = null; + try { + bean.is(); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_4() throws Exception { + String text = "{value:'123',big:false}"; + Bean bean = JSON.parseObject(text, Bean.class); + + Exception error = null; + try { + bean.f(1, 2); + } catch (UnsupportedOperationException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_5() throws Exception { + String text = "{value:'123',big:false}"; + Bean bean = JSON.parseObject(text, Bean.class); + + JSONException error = null; + try { + bean.getA(); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_6() throws Exception { + String text = "{value:'123',big:false}"; + Bean bean = JSON.parseObject(text, Bean.class); + + JSONException error = null; + try { + bean.f1(1); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_7() throws Exception { + String text = "{value:'123',big:false}"; + Bean bean = JSON.parseObject(text, Bean.class); + + JSONException error = null; + try { + bean.set(1); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_8() throws Exception { + String text = "{value:'123',big:false}"; + Bean bean = JSON.parseObject(text, Bean.class); + + JSONException error = null; + try { + bean.xx(); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static interface Bean { + + String getValue(); + + void setValue(String value); + + boolean isBig(); + + @JSONField + void setBig(boolean value); + + @JSONField(name = "value") + int getIntValue(); + + @JSONField(name = "id") + void setID(int value); + + @JSONField(name = "id") + int getID(); + + Object get(); + + Object xx(); + + void set(int i); + + boolean is(); + + void getA(); + + void f(); + + Object f(int a); + + void f1(int a); + + void f(int a, int b); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/JSONObjectTest4.java b/src/test/java/com/alibaba/json/bvt/JSONObjectTest4.java new file mode 100644 index 0000000000..28e5e1ab13 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSONObjectTest4.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; + +public class JSONObjectTest4 extends TestCase { + + public void test_interface() throws Exception { + VO vo = JSON.parseObject("{id:123}", VO.class); + Assert.assertEquals(123, vo.getId()); + } + + public static interface VO { + @JSONField() + int getId(); + + @JSONField() + void setId(int val); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/JSONObjectTest_hashCode.java b/src/test/java/com/alibaba/json/bvt/JSONObjectTest_hashCode.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/JSONObjectTest_hashCode.java rename to src/test/java/com/alibaba/json/bvt/JSONObjectTest_hashCode.java index a86896b8a0..9e466cbc92 --- a/src/test/java/com/alibaba/json/test/bvt/JSONObjectTest_hashCode.java +++ b/src/test/java/com/alibaba/json/bvt/JSONObjectTest_hashCode.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/JSONParseTest.java b/src/test/java/com/alibaba/json/bvt/JSONParseTest.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/JSONParseTest.java rename to src/test/java/com/alibaba/json/bvt/JSONParseTest.java index c13b336ec4..b4ecbd35b0 --- a/src/test/java/com/alibaba/json/test/bvt/JSONParseTest.java +++ b/src/test/java/com/alibaba/json/bvt/JSONParseTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.ArrayList; diff --git a/src/test/java/com/alibaba/json/test/bvt/JSONTest.java b/src/test/java/com/alibaba/json/bvt/JSONTest.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/JSONTest.java rename to src/test/java/com/alibaba/json/bvt/JSONTest.java index 6ccb1ee10f..0a6c7eb408 --- a/src/test/java/com/alibaba/json/test/bvt/JSONTest.java +++ b/src/test/java/com/alibaba/json/bvt/JSONTest.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.io.IOException; import java.io.StringWriter; import java.math.BigDecimal; import java.util.HashMap; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -55,6 +55,12 @@ public void test_string() throws Exception { Assert.assertEquals("中国", JSON.parse("\"\\u4E2D\\u56FD\"").toString()); Assert.assertEquals("\u001F", JSON.parse("\"\\u001F\"").toString()); } + + public void test_for_jh() throws Exception { + String text = "[{\"I.13\":\"XEMwXFMweGEuMHhjOFxGy87M5VxUxOO6ww==\",\"I.18\":\"MA==\"},{\"I.13\":\"XEMwXFMweGEuMHhjOFxGy87M5VxUxOO6ww==\",\"I.18\":\"MA==\"}]"; + JSON.parse(text); + JSON.parseArray(text); + } public void test_value() throws Exception { Assert.assertEquals(Boolean.TRUE, JSON.parse("true")); diff --git a/src/test/java/com/alibaba/json/test/bvt/JSONTest2.java b/src/test/java/com/alibaba/json/bvt/JSONTest2.java old mode 100644 new mode 100755 similarity index 97% rename from src/test/java/com/alibaba/json/test/bvt/JSONTest2.java rename to src/test/java/com/alibaba/json/bvt/JSONTest2.java index 3eb2abc177..9fa3377689 --- a/src/test/java/com/alibaba/json/test/bvt/JSONTest2.java +++ b/src/test/java/com/alibaba/json/bvt/JSONTest2.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.io.ByteArrayInputStream; import java.io.InputStream; diff --git a/src/test/java/com/alibaba/json/test/bvt/JSONTest_Bytes.java b/src/test/java/com/alibaba/json/bvt/JSONTest_Bytes.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/JSONTest_Bytes.java rename to src/test/java/com/alibaba/json/bvt/JSONTest_Bytes.java index 0278cc0648..117d590f71 --- a/src/test/java/com/alibaba/json/test/bvt/JSONTest_Bytes.java +++ b/src/test/java/com/alibaba/json/bvt/JSONTest_Bytes.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/JSONTest_Bytes_1.java b/src/test/java/com/alibaba/json/bvt/JSONTest_Bytes_1.java new file mode 100644 index 0000000000..d03f02c65b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSONTest_Bytes_1.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class JSONTest_Bytes_1 extends TestCase { + + public void test_bytes() throws Exception { + Assert.assertEquals("\"abc\"", new String(JSON.toJSONBytes("abc", SerializeConfig.getGlobalInstance()))); + Assert.assertEquals("'abc'", + new String(JSON.toJSONBytes("abc", SerializeConfig.getGlobalInstance(), + SerializerFeature.UseSingleQuotes))); + } + + public void test_bytes_2() throws Exception { + Assert.assertEquals("\"abc\"", new String(JSON.toJSONBytes("abc"))); + Assert.assertEquals("'abc'", new String(JSON.toJSONBytes("abc", SerializerFeature.UseSingleQuotes))); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/JSONTest_null.java b/src/test/java/com/alibaba/json/bvt/JSONTest_null.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/JSONTest_null.java rename to src/test/java/com/alibaba/json/bvt/JSONTest_null.java index 407866abfe..7ed9881197 --- a/src/test/java/com/alibaba/json/test/bvt/JSONTest_null.java +++ b/src/test/java/com/alibaba/json/bvt/JSONTest_null.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.lang.reflect.Type; import java.nio.charset.Charset; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/JSONTest_overflow.java b/src/test/java/com/alibaba/json/bvt/JSONTest_overflow.java old mode 100644 new mode 100755 similarity index 57% rename from src/test/java/com/alibaba/json/test/bvt/JSONTest_overflow.java rename to src/test/java/com/alibaba/json/bvt/JSONTest_overflow.java index 044e644751..7ed5e66448 --- a/src/test/java/com/alibaba/json/test/bvt/JSONTest_overflow.java +++ b/src/test/java/com/alibaba/json/bvt/JSONTest_overflow.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -13,26 +13,18 @@ public void test_overflow() throws Exception { Entity entity = new Entity(); entity.setSelf(entity); - JSONException error = null; - try { - JSON.toJSONString(entity, SerializeConfig.getGlobalInstance()); - } catch (JSONException ex) { - error = ex; - } - Assert.assertNotNull(error); + String text = JSON.toJSONString(entity, SerializeConfig.getGlobalInstance()); + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertTrue(entity2 == entity2.getSelf()); } public void test_overflow_1() throws Exception { Entity entity = new Entity(); entity.setSelf(entity); - JSONException error = null; - try { - JSON.toJSONStringZ(entity, SerializeConfig.getGlobalInstance()); - } catch (JSONException ex) { - error = ex; - } - Assert.assertNotNull(error); + String text = JSON.toJSONStringZ(entity, SerializeConfig.getGlobalInstance()); + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertTrue(entity2 == entity2.getSelf()); } public static class Entity { diff --git a/src/test/java/com/alibaba/json/test/bvt/JSONTokenTest.java b/src/test/java/com/alibaba/json/bvt/JSONTokenTest.java old mode 100644 new mode 100755 similarity index 89% rename from src/test/java/com/alibaba/json/test/bvt/JSONTokenTest.java rename to src/test/java/com/alibaba/json/bvt/JSONTokenTest.java index deab193cb6..ed366787d1 --- a/src/test/java/com/alibaba/json/test/bvt/JSONTokenTest.java +++ b/src/test/java/com/alibaba/json/bvt/JSONTokenTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.parser.JSONToken; @@ -29,5 +29,7 @@ public void test_0 () throws Exception { Assert.assertEquals("fieldName", JSONToken.name(JSONToken.FIELD_NAME)); Assert.assertEquals("EOF", JSONToken.name(JSONToken.EOF)); Assert.assertEquals("Unkown", JSONToken.name(Integer.MAX_VALUE)); + Assert.assertEquals("Set", JSONToken.name(JSONToken.SET)); + Assert.assertEquals("TreeSet", JSONToken.name(JSONToken.TREE_SET)); } } diff --git a/src/test/java/com/alibaba/json/bvt/JSONTypeTest.java b/src/test/java/com/alibaba/json/bvt/JSONTypeTest.java new file mode 100755 index 0000000000..a49aa812f5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSONTypeTest.java @@ -0,0 +1,132 @@ +package com.alibaba.json.bvt; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; + +public class JSONTypeTest extends TestCase { + public void test_0() throws Exception { + VO vo = new VO(); + vo.setId(1001); + vo.setName("xx"); + vo.setAge(33); + + Assert.assertEquals("{\"age\":33,\"id\":1001,\"name\":\"xx\"}", + JSON.toJSONString(vo)); + } + + public void test_1() throws Exception { + V1 vo = new V1(); + vo.setId(1001); + vo.setName("xx"); + vo.setAge(33); + + Assert.assertEquals("{\"id\":1001,\"name\":\"xx\",\"age\":33}", + JSON.toJSONString(vo)); + } + + public void test_2() throws Exception { + V1 vo = new V1(); + vo.setId(1001); + vo.setName("xx"); + vo.setAge(33); + + Assert.assertEquals("{\"id\":1001,\"name\":\"xx\",\"age\":33}", + JSON.toJSONString(vo)); + } + + @JSONType + public static class VO { + private int id; + private String name; + private int age; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + } + + @JSONType(orders = { "id", "name", "age" }) + public static class V1 { + private int id; + private String name; + private int age; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + } + + @JSONType(orders = { "id", "name", "age" },asm=false) + private class V2 { + private int id; + private String name; + private int age; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/JSONTypeTest1.java b/src/test/java/com/alibaba/json/bvt/JSONTypeTest1.java new file mode 100755 index 0000000000..e201b1c9ce --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSONTypeTest1.java @@ -0,0 +1,140 @@ +package com.alibaba.json.bvt; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; + +public class JSONTypeTest1 extends TestCase { + + public void test_ignores() throws Exception { + A a = new A(); + a.setF1(1001); + a.setF2(1002); + a.setF3(1003); + + Assert.assertEquals("{\"f1\":1001,\"f3\":1003}", JSON.toJSONString(a)); + } + + public void test_ignoresParent() throws Exception { + B b = new B(); + b.setF1(1001); + b.setF2(1002); + b.setF3(1003); + b.setF4(1004); + b.setF5(1005); + + Assert.assertEquals("{\"f1\":1001,\"f3\":1003,\"f5\":1005}", JSON.toJSONString(b)); + } + + public void test_ignoresParent2() throws Exception { + C c = new C(); + c.setF1(1001); + c.setF2(1002); + c.setF3(1003); + c.setF4(1004); + c.setF5(1005); + c.setF6(1006); + + Assert.assertEquals("{\"f1\":1001,\"f3\":1003,\"f5\":1005,\"f6\":1006}", JSON.toJSONString(c)); + } + + public void test_ignoresParent3() throws Exception { + D d = new D(); + d.setF1(1001); + d.setF2(1002); + d.setF3(1003); + d.setF4(1004); + d.setF5(1005); + d.setF6(1006); + d.setF7(1007); + + Assert.assertEquals("{\"f1\":1001,\"f3\":1003,\"f5\":1005,\"f6\":1006,\"f7\":1007}", JSON.toJSONString(d)); + } + + @JSONType(ignores = "f2") + public static class A { + + private int f1; + private int f2; + private int f3; + + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + public int getF2() { + return f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + + public int getF3() { + return f3; + } + + public void setF3(int f3) { + this.f3 = f3; + } + + } + + @JSONType(ignores = { "f4" }) + public static class B extends A { + + private int f4; + private int f5; + + public int getF4() { + return f4; + } + + public void setF4(int f4) { + this.f4 = f4; + } + + public int getF5() { + return f5; + } + + public void setF5(int f5) { + this.f5 = f5; + } + + } + + public static class C extends B { + + private int f6; + + public int getF6() { + return f6; + } + + public void setF6(int f6) { + this.f6 = f6; + } + + } + + public static class D extends C { + + private int f7; + + public int getF7() { + return f7; + } + + public void setF7(int f7) { + this.f7 = f7; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/JSONWriterTest.java b/src/test/java/com/alibaba/json/bvt/JSONWriterTest.java new file mode 100755 index 0000000000..49501a6710 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSONWriterTest.java @@ -0,0 +1,119 @@ +package com.alibaba.json.bvt; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONWriter; + +@SuppressWarnings("deprecation") +public class JSONWriterTest extends TestCase { + + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + JSONWriter writer = new JSONWriter(out); + writer.writeStartObject(); + writer.writeEndObject(); + writer.flush(); + + Assert.assertEquals("{}", out.toString()); + } + + public void test_1() throws Exception { + StringWriter out = new StringWriter(); + + JSONWriter writer = new JSONWriter(out); + writer.writeStartObject(); + writer.writeKey("id"); + writer.writeValue(33); + writer.writeEndObject(); + writer.flush(); + + Assert.assertEquals("{\"id\":33}", out.toString()); + } + + public void test_2() throws Exception { + StringWriter out = new StringWriter(); + + JSONWriter writer = new JSONWriter(out); + writer.writeStartObject(); + + writer.writeKey("id"); + writer.writeValue(33); + + writer.writeKey("name"); + writer.writeValue("jobs"); + + writer.writeEndObject(); + writer.flush(); + + Assert.assertEquals("{\"id\":33,\"name\":\"jobs\"}", out.toString()); + } + + public void test_3() throws Exception { + StringWriter out = new StringWriter(); + + JSONWriter writer = new JSONWriter(out); + writer.writeStartObject(); + + writer.writeKey("id"); + writer.writeValue(33); + + writer.writeKey("name"); + writer.writeValue("jobs"); + + writer.writeKey("children"); + writer.writeStartArray(); + + writer.writeStartObject(); + writer.writeEndObject(); + + writer.writeStartObject(); + writer.writeEndObject(); + + writer.writeEndArray(); + + writer.writeEndObject(); + writer.flush(); + + Assert.assertEquals("{\"id\":33,\"name\":\"jobs\",\"children\":[{},{}]}", out.toString()); + } + + public void test_4() throws Exception { + StringWriter out = new StringWriter(); + + JSONWriter writer = new JSONWriter(out); + + writer.writeStartArray(); + + writer.writeStartObject(); + writer.writeEndObject(); + + writer.writeStartObject(); + writer.writeEndObject(); + + writer.writeStartArray(); + writer.writeEndArray(); + { + writer.writeStartArray(); + + writer.writeStartArray(); + writer.writeEndArray(); + + writer.writeStartArray(); + writer.writeEndArray(); + + writer.writeEndArray(); + + writer.writeValue(1); + } + + writer.writeEndArray(); + + writer.flush(); + + Assert.assertEquals("[{},{},[],[[],[]],1]", out.toString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/JSONWriterTest_0.java b/src/test/java/com/alibaba/json/bvt/JSONWriterTest_0.java new file mode 100644 index 0000000000..428871c805 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSONWriterTest_0.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt; + +import java.io.StringWriter; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONWriter; + +public class JSONWriterTest_0 extends TestCase { + + public void test_writer() throws Exception { + StringWriter out = new StringWriter(); + JSONWriter writer = new JSONWriter(out); + writer.startArray(); + writer.writeObject("1"); + writer.writeObject("2"); + writer.writeObject("3"); + writer.endArray(); + writer.close(); + + Assert.assertEquals("[\"1\",\"2\",\"3\"]", out.toString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/JSONWriterTest_1.java b/src/test/java/com/alibaba/json/bvt/JSONWriterTest_1.java new file mode 100644 index 0000000000..a96d33ac1b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSONWriterTest_1.java @@ -0,0 +1,31 @@ +package com.alibaba.json.bvt; + +import java.io.StringWriter; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONWriter; + +public class JSONWriterTest_1 extends TestCase { + + public void test_writer() throws Exception { + StringWriter out = new StringWriter(); + JSONWriter writer = new JSONWriter(out); + writer.startObject(); + writer.writeObject("a"); + writer.writeObject("1"); + + writer.writeObject("b"); + writer.writeObject("2"); + + writer.writeObject("c"); + writer.writeObject("3"); + + writer.endObject(); + writer.close(); + + Assert.assertEquals("{\"a\":\"1\",\"b\":\"2\",\"c\":\"3\"}", out.toString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/JSONWriterTest_2.java b/src/test/java/com/alibaba/json/bvt/JSONWriterTest_2.java new file mode 100644 index 0000000000..c3db44724c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSONWriterTest_2.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt; + +import java.io.StringWriter; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class JSONWriterTest_2 extends TestCase { + + public void test_writer() throws Exception { + StringWriter out = new StringWriter(); + JSONWriter writer = new JSONWriter(out); + writer.config(SerializerFeature.UseSingleQuotes, true); + writer.startObject(); + writer.writeObject("a"); + writer.writeObject("1"); + + writer.writeObject("b"); + writer.writeObject("2"); + + writer.writeObject("c"); + writer.writeObject("3"); + + writer.endObject(); + writer.close(); + + Assert.assertEquals("{'a':'1','b':'2','c':'3'}", out.toString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/JSONWriterTest_3.java b/src/test/java/com/alibaba/json/bvt/JSONWriterTest_3.java new file mode 100644 index 0000000000..37a7676009 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSONWriterTest_3.java @@ -0,0 +1,31 @@ +package com.alibaba.json.bvt; + +import java.io.StringWriter; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class JSONWriterTest_3 extends TestCase { + + public void test_writer() throws Exception { + StringWriter out = new StringWriter(); + JSONWriter writer = new JSONWriter(out); + writer.config(SerializerFeature.UseSingleQuotes, true); + writer.startObject(); + + writer.startObject(); + writer.endObject(); + + writer.startObject(); + writer.endObject(); + + writer.endObject(); + writer.close(); + + Assert.assertEquals("{{}:{}}", out.toString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/JSONWriterTest_4.java b/src/test/java/com/alibaba/json/bvt/JSONWriterTest_4.java new file mode 100644 index 0000000000..c6b9452143 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSONWriterTest_4.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt; + +import java.io.StringWriter; +import java.util.Collections; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class JSONWriterTest_4 extends TestCase { + + public void test_writer() throws Exception { + StringWriter out = new StringWriter(); + JSONWriter writer = new JSONWriter(out); + writer.config(SerializerFeature.UseSingleQuotes, true); + writer.writeObject(Collections.emptyMap()); + writer.close(); + + Assert.assertEquals("{}", out.toString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/JSONWriterTest_error.java b/src/test/java/com/alibaba/json/bvt/JSONWriterTest_error.java new file mode 100644 index 0000000000..0df065b29e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/JSONWriterTest_error.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt; + +import java.io.StringWriter; +import java.lang.reflect.Field; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class JSONWriterTest_error extends TestCase { + + public void test_writer() throws Exception { + Field field = JSONWriter.class.getDeclaredField("context"); + field.setAccessible(true); + + StringWriter out = new StringWriter(); + JSONWriter writer = new JSONWriter(out); + writer.config(SerializerFeature.UseSingleQuotes, true); + writer.startObject(); + + Object context = field.get(writer); + Field stateField = context.getClass().getDeclaredField("state"); + stateField.setAccessible(true); + stateField.set(context, -1); + + Exception error = null; + try { + writer.startObject(); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + + writer.close(); + + } + +} diff --git a/src/test/java/com/alibaba/json/test/bvt/JSON_toJSONStringTest.java b/src/test/java/com/alibaba/json/bvt/JSON_toJSONStringTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/JSON_toJSONStringTest.java rename to src/test/java/com/alibaba/json/bvt/JSON_toJSONStringTest.java index ec28af5298..f899fe541b --- a/src/test/java/com/alibaba/json/test/bvt/JSON_toJSONStringTest.java +++ b/src/test/java/com/alibaba/json/bvt/JSON_toJSONStringTest.java @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.Collections; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/test/bvt/JSON_toJavaObject_test.java b/src/test/java/com/alibaba/json/bvt/JSON_toJavaObject_test.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/JSON_toJavaObject_test.java rename to src/test/java/com/alibaba/json/bvt/JSON_toJavaObject_test.java index 4ce968be19..8b4e3bf744 --- a/src/test/java/com/alibaba/json/test/bvt/JSON_toJavaObject_test.java +++ b/src/test/java/com/alibaba/json/bvt/JSON_toJavaObject_test.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/JavaBeanMappingTest.java b/src/test/java/com/alibaba/json/bvt/JavaBeanMappingTest.java old mode 100644 new mode 100755 similarity index 88% rename from src/test/java/com/alibaba/json/test/bvt/JavaBeanMappingTest.java rename to src/test/java/com/alibaba/json/bvt/JavaBeanMappingTest.java index 6cd2fcbfd2..ffe2b5d881 --- a/src/test/java/com/alibaba/json/test/bvt/JavaBeanMappingTest.java +++ b/src/test/java/com/alibaba/json/bvt/JavaBeanMappingTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/test/bvt/JavaBeanTest.java b/src/test/java/com/alibaba/json/bvt/JavaBeanTest.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/JavaBeanTest.java rename to src/test/java/com/alibaba/json/bvt/JavaBeanTest.java index 970907ae0e..db7cdcebf9 --- a/src/test/java/com/alibaba/json/test/bvt/JavaBeanTest.java +++ b/src/test/java/com/alibaba/json/bvt/JavaBeanTest.java @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/JsonValueTest.java b/src/test/java/com/alibaba/json/bvt/JsonValueTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/JsonValueTest.java rename to src/test/java/com/alibaba/json/bvt/JsonValueTest.java index bfb4a73d51..4fc31b07ff --- a/src/test/java/com/alibaba/json/test/bvt/JsonValueTest.java +++ b/src/test/java/com/alibaba/json/bvt/JsonValueTest.java @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.Date; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/LexerTest.java b/src/test/java/com/alibaba/json/bvt/LexerTest.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/LexerTest.java rename to src/test/java/com/alibaba/json/bvt/LexerTest.java index 5fdb4b4882..e17f4e42f9 --- a/src/test/java/com/alibaba/json/test/bvt/LexerTest.java +++ b/src/test/java/com/alibaba/json/bvt/LexerTest.java @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.math.BigDecimal; import java.math.BigInteger; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -70,7 +70,7 @@ public void test_string() throws Exception { String stringVal = lexer.stringVal(); - Assert.assertEquals("\"\\\\/\\b\\f\\n\\r\t中\"", JSON.toJSONString(stringVal)); + Assert.assertEquals("\"\\\\/\\b\\f\\n\\r\\t中\"", JSON.toJSONString(stringVal)); } diff --git a/src/test/java/com/alibaba/json/test/bvt/LinkedListFieldTest.java b/src/test/java/com/alibaba/json/bvt/LinkedListFieldTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/LinkedListFieldTest.java rename to src/test/java/com/alibaba/json/bvt/LinkedListFieldTest.java index ed217e89a9..b6cd8cc92b --- a/src/test/java/com/alibaba/json/test/bvt/LinkedListFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/LinkedListFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.LinkedList; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/ListFieldTest.java b/src/test/java/com/alibaba/json/bvt/ListFieldTest.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/ListFieldTest.java rename to src/test/java/com/alibaba/json/bvt/ListFieldTest.java index 8d257464bf..edc6358469 --- a/src/test/java/com/alibaba/json/test/bvt/ListFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/ListFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/ListFieldTest2.java b/src/test/java/com/alibaba/json/bvt/ListFieldTest2.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/ListFieldTest2.java rename to src/test/java/com/alibaba/json/bvt/ListFieldTest2.java index e44a392786..3fa264e8af --- a/src/test/java/com/alibaba/json/test/bvt/ListFieldTest2.java +++ b/src/test/java/com/alibaba/json/bvt/ListFieldTest2.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/ListFieldTest3.java b/src/test/java/com/alibaba/json/bvt/ListFieldTest3.java new file mode 100644 index 0000000000..980c576517 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ListFieldTest3.java @@ -0,0 +1,56 @@ +package com.alibaba.json.bvt; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +import data.media.MediaContent; + +public class ListFieldTest3 extends TestCase { + + public void test_typeRef() throws Exception { + String text = "{\"images\":[],\"media\":{\"width\":640}}"; + + MediaContent object = JSON.parseObject(text, MediaContent.class); + } + + public static class Root { + private List images = new ArrayList(); + private Entity media; + + public List getImages() { + return images; + } + + public void setImages(List images) { + this.images = images; + } + + public Entity getMedia() { + return media; + } + + public void setMedia(Entity media) { + this.media = media; + } + + } + + public static class Image { + public int width; + } + + public static class Entity { + public String title; // Can be null + public int width; + public int height; + public Size size; + } + + public enum Size { + SMALL, LARGE + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/ListFloatFieldTest.java b/src/test/java/com/alibaba/json/bvt/ListFloatFieldTest.java old mode 100644 new mode 100755 similarity index 88% rename from src/test/java/com/alibaba/json/test/bvt/ListFloatFieldTest.java rename to src/test/java/com/alibaba/json/bvt/ListFloatFieldTest.java index 8ba1fd98c6..302e3326b2 --- a/src/test/java/com/alibaba/json/test/bvt/ListFloatFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/ListFloatFieldTest.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.ArrayList; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/LocaleFieldTest.java b/src/test/java/com/alibaba/json/bvt/LocaleFieldTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/LocaleFieldTest.java rename to src/test/java/com/alibaba/json/bvt/LocaleFieldTest.java index 90899ad615..ceb578a23c --- a/src/test/java/com/alibaba/json/test/bvt/LocaleFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/LocaleFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.Locale; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/LongArrayFieldTest.java b/src/test/java/com/alibaba/json/bvt/LongArrayFieldTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/LongArrayFieldTest.java rename to src/test/java/com/alibaba/json/bvt/LongArrayFieldTest.java index 842a968dc4..4e21abd47f --- a/src/test/java/com/alibaba/json/test/bvt/LongArrayFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/LongArrayFieldTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/LongArrayFieldTest_primitive.java b/src/test/java/com/alibaba/json/bvt/LongArrayFieldTest_primitive.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/LongArrayFieldTest_primitive.java rename to src/test/java/com/alibaba/json/bvt/LongArrayFieldTest_primitive.java index 743fbe5d0a..1c60406c70 --- a/src/test/java/com/alibaba/json/test/bvt/LongArrayFieldTest_primitive.java +++ b/src/test/java/com/alibaba/json/bvt/LongArrayFieldTest_primitive.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/LongFieldTest.java b/src/test/java/com/alibaba/json/bvt/LongFieldTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/LongFieldTest.java rename to src/test/java/com/alibaba/json/bvt/LongFieldTest.java index 1e21afd73d..43e25a379e --- a/src/test/java/com/alibaba/json/test/bvt/LongFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/LongFieldTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/LongFieldTest_primitive.java b/src/test/java/com/alibaba/json/bvt/LongFieldTest_primitive.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/LongFieldTest_primitive.java rename to src/test/java/com/alibaba/json/bvt/LongFieldTest_primitive.java index 0cf617a222..ed0786e56a --- a/src/test/java/com/alibaba/json/test/bvt/LongFieldTest_primitive.java +++ b/src/test/java/com/alibaba/json/bvt/LongFieldTest_primitive.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/MapRefTest.java b/src/test/java/com/alibaba/json/bvt/MapRefTest.java new file mode 100755 index 0000000000..9220f9f36b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/MapRefTest.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class MapRefTest extends TestCase { + + public void test_0() throws Exception { + String text; + { + Map map = new HashMap(); + + User user = new User(); + user.setId(123); + user.setName("wenshao"); + + map.put("u1", user); + map.put("u2", user); + + text = JSON.toJSONString(map); + } + + System.out.println(text); + Map map = JSON.parseObject(text, new TypeReference>() {}); + //Assert.assertEquals(map, map.get("this")); + Assert.assertEquals(map.get("u1"), map.get("u2")); + } + + public static class User { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/MapRefTest1.java b/src/test/java/com/alibaba/json/bvt/MapRefTest1.java new file mode 100755 index 0000000000..35c23969ad --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/MapRefTest1.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class MapRefTest1 extends TestCase { + + public void test_0() throws Exception { + String text; + { + Map map = new HashMap(); + + User user = new User(); + user.setId(123); + user.setName("wenshao"); + + map.put("u1", user); + map.put("u2", user); + + text = JSON.toJSONString(map, SerializerFeature.WriteClassName); + } + + System.out.println(text); + Map map = JSON.parseObject(text); + //Assert.assertEquals(map, map.get("this")); + Assert.assertEquals(map.get("u1"), map.get("u2")); + } + + public static class User { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/MapRefTest2.java b/src/test/java/com/alibaba/json/bvt/MapRefTest2.java new file mode 100755 index 0000000000..e71cc9d3f0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/MapRefTest2.java @@ -0,0 +1,59 @@ +package com.alibaba.json.bvt; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class MapRefTest2 extends TestCase { + + public void test_0() throws Exception { + String text; + { + Map map = new HashMap(); + + User user = new User(); + user.setId(123); + user.setName("wenshao"); + + map.put("u1", user); + map.put("u2", user); + + text = JSON.toJSONString(map, SerializerFeature.WriteClassName); + } + + System.out.println(text); + Map map = JSON.parseObject(text, new TypeReference>() {}); + //Assert.assertEquals(map, map.get("this")); + Assert.assertEquals(map.get("u1"), map.get("u2")); + } + + public static class User { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/MapRefTest3.java b/src/test/java/com/alibaba/json/bvt/MapRefTest3.java new file mode 100755 index 0000000000..3c4ad9b497 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/MapRefTest3.java @@ -0,0 +1,59 @@ +package com.alibaba.json.bvt; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class MapRefTest3 extends TestCase { + + public void test_0() throws Exception { + String text; + { + Map map = new HashMap(); + + User user = new User(); + user.setId(123); + user.setName("wenshao"); + + map.put("u1", user); + map.put("u2", user); + + text = JSON.toJSONString(map, SerializerFeature.WriteClassName); + } + + System.out.println(text); + Map map = JSON.parseObject(text, new TypeReference>() {}); + //Assert.assertEquals(map, map.get("this")); + Assert.assertEquals(map.get("u1"), map.get("u2")); + } + + public static class User { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/MapRefTest4.java b/src/test/java/com/alibaba/json/bvt/MapRefTest4.java new file mode 100644 index 0000000000..bd183d6202 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/MapRefTest4.java @@ -0,0 +1,22 @@ +package com.alibaba.json.bvt; + +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class MapRefTest4 extends TestCase { + + public void test_0() throws Exception { + String text = "{\"u1\":{\"id\":123,\"name\":\"wenshao\"},\"u2\":{\"$ref\":\"..\"}}"; + Map map = JSON.parseObject(text, new TypeReference>() {}); + //Assert.assertEquals(map, map.get("this")); + Assert.assertSame(map, map.get("u2")); + } + + +} diff --git a/src/test/java/com/alibaba/json/bvt/MapRefTest5.java b/src/test/java/com/alibaba/json/bvt/MapRefTest5.java new file mode 100644 index 0000000000..ebaa8165a3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/MapRefTest5.java @@ -0,0 +1,23 @@ +package com.alibaba.json.bvt; + +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class MapRefTest5 extends TestCase { + + public void test_0() throws Exception { + String text = "[{\"u1\":{\"id\":123,\"name\":\"wenshao\"},\"u2\":{\"$ref\":\"$\"}}]"; + List> list = JSON.parseObject(text, new TypeReference>>() {}); + //Assert.assertEquals(map, map.get("this")); + Assert.assertSame(list, list.get(0).get("u2")); + } + + +} diff --git a/src/test/java/com/alibaba/json/test/bvt/MapTest.java b/src/test/java/com/alibaba/json/bvt/MapTest.java old mode 100644 new mode 100755 similarity index 74% rename from src/test/java/com/alibaba/json/test/bvt/MapTest.java rename to src/test/java/com/alibaba/json/bvt/MapTest.java index 2008165990..317d4d492b --- a/src/test/java/com/alibaba/json/test/bvt/MapTest.java +++ b/src/test/java/com/alibaba/json/bvt/MapTest.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -14,6 +14,6 @@ public void test_null() throws Exception { Map map = new HashMap(); map.put(null, "123"); String text = JSON.toJSONString(map); - Assert.assertEquals("{\"null\":\"123\"}", text); + Assert.assertEquals("{null:\"123\"}", text); } } diff --git a/src/test/java/com/alibaba/json/bvt/MapTest2.java b/src/test/java/com/alibaba/json/bvt/MapTest2.java new file mode 100755 index 0000000000..152324ade8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/MapTest2.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt; + +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + + +public class MapTest2 extends TestCase { + public void test_map () throws Exception { +Map map = JSON.parseObject("{1:\"2\",\"3\":4,'5':6}", new TypeReference>() {}); +Assert.assertEquals("2", map.get(1)); +Assert.assertEquals(4, map.get("3")); +Assert.assertEquals(6, map.get("5")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/MaterializedInterfaceTest.java b/src/test/java/com/alibaba/json/bvt/MaterializedInterfaceTest.java new file mode 100755 index 0000000000..74fecca5a8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/MaterializedInterfaceTest.java @@ -0,0 +1,30 @@ +package com.alibaba.json.bvt; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class MaterializedInterfaceTest extends TestCase { + + public void test_parse() throws Exception { + String text = "{\"id\":123, \"name\":\"chris\"}"; + Bean bean = JSON.parseObject(text, Bean.class); + + Assert.assertEquals(123, bean.getId()); + Assert.assertEquals("chris", bean.getName()); + + String text2 = JSON.toJSONString(bean); + System.out.println(text2); + } + + public static interface Bean { + int getId(); + + void setId(int value); + + String getName(); + + void setName(String value); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/MaterializedInterfaceTest2.java b/src/test/java/com/alibaba/json/bvt/MaterializedInterfaceTest2.java new file mode 100755 index 0000000000..ee41825d87 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/MaterializedInterfaceTest2.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.util.TypeUtils; + +public class MaterializedInterfaceTest2 extends TestCase { + + public void test_parse() throws Exception { + String text = "{\"id\":123, \"name\":\"chris\"}"; + JSONObject object = JSON.parseObject(text); + + Bean bean = TypeUtils.cast(object, Bean.class, null); + + Assert.assertEquals(123, bean.getId()); + Assert.assertEquals("chris", bean.getName()); + + String text2 = JSON.toJSONString(bean); + System.out.println(text2); + } + + public static interface Bean { + int getId(); + + void setId(int value); + + String getName(); + + void setName(String value); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/NotWriteRootClassNameTest.java b/src/test/java/com/alibaba/json/bvt/NotWriteRootClassNameTest.java new file mode 100755 index 0000000000..1eb1777e9b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/NotWriteRootClassNameTest.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +import org.junit.Assert; +import junit.framework.TestCase; + + +public class NotWriteRootClassNameTest extends TestCase { + public void test_NotWriteRootClassName() throws Exception { + SerializerFeature[] features = new SerializerFeature[] {SerializerFeature.WriteClassName, SerializerFeature.NotWriteRootClassName}; + Assert.assertEquals("{}", JSON.toJSONString(new VO(), features)); + Assert.assertEquals("{}", JSON.toJSONString(new V1(), features)); + } + + public static class VO { + + } + + private static class V1 { + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/NumberFieldTest.java b/src/test/java/com/alibaba/json/bvt/NumberFieldTest.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/NumberFieldTest.java rename to src/test/java/com/alibaba/json/bvt/NumberFieldTest.java index 57ff6843af..858eff34f6 --- a/src/test/java/com/alibaba/json/test/bvt/NumberFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/NumberFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.math.BigDecimal; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/OOMTest.java b/src/test/java/com/alibaba/json/bvt/OOMTest.java new file mode 100755 index 0000000000..9c7f36e1b1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/OOMTest.java @@ -0,0 +1,20 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.SymbolTable; + +import org.junit.Assert; +import junit.framework.TestCase; + +public class OOMTest extends TestCase { + public void test_oom() throws Exception { + + for (int i = 0; i < 1000 * 1000; ++i) { + String text = "{\"" + i + "\":0}"; + JSON.parse(text); + } + + Assert.assertEquals(SymbolTable.MAX_SIZE, ParserConfig.getGlobalInstance().getSymbolTable().size()); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/ObjectArrayFieldTest.java b/src/test/java/com/alibaba/json/bvt/ObjectArrayFieldTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/ObjectArrayFieldTest.java rename to src/test/java/com/alibaba/json/bvt/ObjectArrayFieldTest.java index d8db375deb..072fde0566 --- a/src/test/java/com/alibaba/json/test/bvt/ObjectArrayFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/ObjectArrayFieldTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/ObjectFieldTest.java b/src/test/java/com/alibaba/json/bvt/ObjectFieldTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/ObjectFieldTest.java rename to src/test/java/com/alibaba/json/bvt/ObjectFieldTest.java index d48d3c0054..a25dad03bd --- a/src/test/java/com/alibaba/json/test/bvt/ObjectFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/ObjectFieldTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/OverriadeTest.java b/src/test/java/com/alibaba/json/bvt/OverriadeTest.java new file mode 100644 index 0000000000..24481fb8ec --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/OverriadeTest.java @@ -0,0 +1,32 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + +public class OverriadeTest extends TestCase { + + public void test_override() throws Exception { + JSON.parseObject("{}", B.class); + } + + public static class A { + + private long id; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + } + + public static class B extends A { + public void setId(String id) { + setId(Long.parseLong(id)); + } + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/ParseArrayTest.java b/src/test/java/com/alibaba/json/bvt/ParseArrayTest.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/ParseArrayTest.java rename to src/test/java/com/alibaba/json/bvt/ParseArrayTest.java index a621117c0f..d0ca757830 --- a/src/test/java/com/alibaba/json/test/bvt/ParseArrayTest.java +++ b/src/test/java/com/alibaba/json/bvt/ParseArrayTest.java @@ -1,11 +1,11 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.lang.reflect.Type; import java.util.HashMap; import java.util.List; import java.util.TreeMap; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/PatternFieldTest.java b/src/test/java/com/alibaba/json/bvt/PatternFieldTest.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/PatternFieldTest.java rename to src/test/java/com/alibaba/json/bvt/PatternFieldTest.java index 3dd2a544d2..d36ab51751 --- a/src/test/java/com/alibaba/json/test/bvt/PatternFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/PatternFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.regex.Pattern; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/PointTest.java b/src/test/java/com/alibaba/json/bvt/PointTest.java new file mode 100755 index 0000000000..225c8eb2f9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/PointTest.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt; + +import java.awt.Point; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.PointCodec; + +public class PointTest extends TestCase { + + public void test_color() throws Exception { + JSONSerializer serializer = new JSONSerializer(); + Assert.assertEquals(PointCodec.class, serializer.getObjectWriter(Point.class).getClass()); + + Point point = new Point(3, 4); + String text = JSON.toJSONString(point); + + Point point2 = JSON.parseObject(text, Point.class); + + Assert.assertEquals(point, point2); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/PointTest2.java b/src/test/java/com/alibaba/json/bvt/PointTest2.java new file mode 100755 index 0000000000..ff9c3cf35b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/PointTest2.java @@ -0,0 +1,53 @@ +package com.alibaba.json.bvt; + +import java.awt.Point; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.PointCodec; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class PointTest2 extends TestCase { + + public void test_point() throws Exception { + JSONSerializer serializer = new JSONSerializer(); + Assert.assertEquals(PointCodec.class, serializer.getObjectWriter(Point.class).getClass()); + + Point point = new Point(3, 4); + String text = JSON.toJSONString(point, SerializerFeature.WriteClassName); + + Object obj = JSON.parse(text); + Point point2 = (Point) obj; + + Assert.assertEquals(point, point2); + + Point point3 = (Point) JSON.parseObject(text, Point.class); + + Assert.assertEquals(point, point3); + } + + public void test_point2() throws Exception { + JSON.parseObject("{}", Point.class); + JSON.parseArray("[null,null]", Point.class); + Assert.assertNull(JSON.parseObject("null", Point.class)); + JSON.parseObject("{\"@type\":\"java.awt.Point\"}", Point.class); + JSON.parseObject("{\"value\":null}", VO.class); + } + + public static class VO { + + private Point value; + + public Point getValue() { + return value; + } + + public void setValue(Point value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/PublicFieldDoubleTest.java b/src/test/java/com/alibaba/json/bvt/PublicFieldDoubleTest.java new file mode 100755 index 0000000000..c1031a61f2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/PublicFieldDoubleTest.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; + +import org.junit.Assert; +import junit.framework.TestCase; + +public class PublicFieldDoubleTest extends TestCase { + + public static class VO { + + public double id; + } + + public void test_codec() throws Exception { + VO vo = new VO(); + vo.id = 12.34; + + String str = JSON.toJSONString(vo); + + VO vo1 = JSON.parseObject(str, VO.class); + + Assert.assertTrue(vo1.id == vo.id); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/PublicFieldFloatTest.java b/src/test/java/com/alibaba/json/bvt/PublicFieldFloatTest.java new file mode 100755 index 0000000000..c44e4a2647 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/PublicFieldFloatTest.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; + +import org.junit.Assert; +import junit.framework.TestCase; + +public class PublicFieldFloatTest extends TestCase { + + public static class VO { + + public float id; + } + + public void test_codec() throws Exception { + VO vo = new VO(); + vo.id = 123.4F; + + String str = JSON.toJSONString(vo); + + VO vo1 = JSON.parseObject(str, VO.class); + + Assert.assertTrue(vo1.id == vo.id); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/PublicFieldLongTest.java b/src/test/java/com/alibaba/json/bvt/PublicFieldLongTest.java new file mode 100755 index 0000000000..d3856d3762 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/PublicFieldLongTest.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; + +import org.junit.Assert; +import junit.framework.TestCase; + +public class PublicFieldLongTest extends TestCase { + + public static class VO { + + public long id; + } + + public void test_codec() throws Exception { + VO vo = new VO(); + vo.id = 1234; + + String str = JSON.toJSONString(vo); + + VO vo1 = JSON.parseObject(str, VO.class); + + Assert.assertEquals(vo1.id, vo.id); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/PublicFieldStringTest.java b/src/test/java/com/alibaba/json/bvt/PublicFieldStringTest.java new file mode 100755 index 0000000000..b1fa0cbd31 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/PublicFieldStringTest.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; + +import org.junit.Assert; +import junit.framework.TestCase; + +public class PublicFieldStringTest extends TestCase { + + public static class VO { + + public String id; + } + + public void test_codec() throws Exception { + VO vo = new VO(); + vo.id = "x12345"; + + String str = JSON.toJSONString(vo); + + VO vo1 = JSON.parseObject(str, VO.class); + + Assert.assertEquals(vo1.id, vo.id); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/RectangleTest.java b/src/test/java/com/alibaba/json/bvt/RectangleTest.java new file mode 100755 index 0000000000..5de37b5c98 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/RectangleTest.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt; + +import java.awt.Rectangle; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.RectangleCodec; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class RectangleTest extends TestCase { + + public void test_color() throws Exception { + JSONSerializer serializer = new JSONSerializer(); + Assert.assertEquals(RectangleCodec.class, serializer.getObjectWriter(Rectangle.class).getClass()); + + Rectangle v = new Rectangle(3, 4, 100, 200); + String text = JSON.toJSONString(v, SerializerFeature.WriteClassName); + + System.out.println(text); + + Rectangle v2 = (Rectangle) JSON.parse(text); + + Assert.assertEquals(v, v2); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/SerializeWriterTest.java b/src/test/java/com/alibaba/json/bvt/SerializeWriterTest.java old mode 100644 new mode 100755 similarity index 78% rename from src/test/java/com/alibaba/json/test/bvt/SerializeWriterTest.java rename to src/test/java/com/alibaba/json/bvt/SerializeWriterTest.java index 39eb26bc48..909d63d21a --- a/src/test/java/com/alibaba/json/test/bvt/SerializeWriterTest.java +++ b/src/test/java/com/alibaba/json/bvt/SerializeWriterTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.SerializeWriter; @@ -23,12 +23,6 @@ public void test_1() throws Exception { Assert.assertEquals("-1", writer.toString()); } - public void test_2() throws Exception { - SerializeWriter writer = new SerializeWriter(); - writer.writeIntArray(new int[] { -1 }); - Assert.assertEquals("[-1]", writer.toString()); - } - public void test_4() throws Exception { SerializeWriter writer = new SerializeWriter(); writer.writeIntAndChar(-1, ','); diff --git a/src/test/java/com/alibaba/json/bvt/ServiceLoaderTest.java b/src/test/java/com/alibaba/json/bvt/ServiceLoaderTest.java new file mode 100644 index 0000000000..3643edf8a1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ServiceLoaderTest.java @@ -0,0 +1,12 @@ +package com.alibaba.json.bvt; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.util.ServiceLoader; + + +public class ServiceLoaderTest extends TestCase { + public void test_0() throws Exception { + new ServiceLoader(); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/SetFieldTest.java b/src/test/java/com/alibaba/json/bvt/SetFieldTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/SetFieldTest.java rename to src/test/java/com/alibaba/json/bvt/SetFieldTest.java index a76e3e5e68..ee018ecedd --- a/src/test/java/com/alibaba/json/test/bvt/SetFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/SetFieldTest.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.HashSet; import java.util.Set; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/ShortArrayFieldTest_primitive.java b/src/test/java/com/alibaba/json/bvt/ShortArrayFieldTest_primitive.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/ShortArrayFieldTest_primitive.java rename to src/test/java/com/alibaba/json/bvt/ShortArrayFieldTest_primitive.java index 7bae14f5bd..356bf2ffd0 --- a/src/test/java/com/alibaba/json/test/bvt/ShortArrayFieldTest_primitive.java +++ b/src/test/java/com/alibaba/json/bvt/ShortArrayFieldTest_primitive.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/SlashTest.java b/src/test/java/com/alibaba/json/bvt/SlashTest.java old mode 100644 new mode 100755 similarity index 88% rename from src/test/java/com/alibaba/json/test/bvt/SlashTest.java rename to src/test/java/com/alibaba/json/bvt/SlashTest.java index 84448c819a..70fd2a5942 --- a/src/test/java/com/alibaba/json/test/bvt/SlashTest.java +++ b/src/test/java/com/alibaba/json/bvt/SlashTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/SpecialKeyTest.java b/src/test/java/com/alibaba/json/bvt/SpecialKeyTest.java new file mode 100755 index 0000000000..8744818fb0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/SpecialKeyTest.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class SpecialKeyTest extends TestCase { + + public void test_0() throws Exception { + Map map = new HashMap(); + map.put(1, "a"); + map.put(2, "b"); + + String text = JSON.toJSONString(map); + System.out.println(text); + + Map map2 = JSON.parseObject(text, new TypeReference>() {}); + Assert.assertEquals(map, map2); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/StringDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/StringDeserializerTest.java old mode 100644 new mode 100755 similarity index 85% rename from src/test/java/com/alibaba/json/test/bvt/StringDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/StringDeserializerTest.java index 5876766d48..31b7f9b7c7 --- a/src/test/java/com/alibaba/json/test/bvt/StringDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/StringDeserializerTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/StringFieldTest.java b/src/test/java/com/alibaba/json/bvt/StringFieldTest.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/StringFieldTest.java rename to src/test/java/com/alibaba/json/bvt/StringFieldTest.java index fae180fea1..d9c82e183a --- a/src/test/java/com/alibaba/json/test/bvt/StringFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/StringFieldTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/SymbolTableTest.java b/src/test/java/com/alibaba/json/bvt/SymbolTableTest.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/SymbolTableTest.java rename to src/test/java/com/alibaba/json/bvt/SymbolTableTest.java index 9d8be3e8a3..af38f8b0c4 --- a/src/test/java/com/alibaba/json/test/bvt/SymbolTableTest.java +++ b/src/test/java/com/alibaba/json/bvt/SymbolTableTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import org.codehaus.jackson.sym.CharsToNameCanonicalizer; diff --git a/src/test/java/com/alibaba/json/test/bvt/TabCharTest.java b/src/test/java/com/alibaba/json/bvt/TabCharTest.java old mode 100644 new mode 100755 similarity index 65% rename from src/test/java/com/alibaba/json/test/bvt/TabCharTest.java rename to src/test/java/com/alibaba/json/bvt/TabCharTest.java index 937cf4ef7d..3116d7c693 --- a/src/test/java/com/alibaba/json/test/bvt/TabCharTest.java +++ b/src/test/java/com/alibaba/json/bvt/TabCharTest.java @@ -1,19 +1,22 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializeConfig; import com.alibaba.fastjson.serializer.SerializerFeature; public class TabCharTest extends TestCase { + @SuppressWarnings("deprecation") public void test_0() throws Exception { JSONObject json = new JSONObject(); json.put("hello\t", "World\t!"); - Assert.assertEquals("{\"hello\t\":\"World\t!\"}", JSON.toJSONString(json)); - Assert.assertEquals("{\"hello\\t\":\"World\\t!\"}", JSON.toJSONString(json, SerializerFeature.WriteTabAsSpecial)); + Assert.assertEquals("{\"hello\\t\":\"World\\t!\"}", JSON.toJSONString(json)); + Assert.assertEquals("{\"hello\\t\":\"World\\t!\"}", JSON.toJSONStringZ(json, SerializeConfig.getGlobalInstance())); Assert.assertEquals("{'hello\\t':'World\\t!'}", JSON.toJSONString(json, SerializerFeature.WriteTabAsSpecial, SerializerFeature.UseSingleQuotes)); } diff --git a/src/test/java/com/alibaba/json/bvt/TestDeprecate.java b/src/test/java/com/alibaba/json/bvt/TestDeprecate.java new file mode 100755 index 0000000000..163c61f706 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TestDeprecate.java @@ -0,0 +1,42 @@ +package com.alibaba.json.bvt; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class TestDeprecate extends TestCase { + + public void test_0() throws Exception { + VO vo = new VO(); + vo.setId(123); + + String text = JSON.toJSONString(vo); + } + + public static class VO { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + /** + * @deprecated + * @return + */ + public int getId2() { + return this.id; + } + + @Deprecated + public int getId3() { + return this.id; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/TestExternal.java b/src/test/java/com/alibaba/json/bvt/TestExternal.java new file mode 100755 index 0000000000..1ccc3ed8a3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TestExternal.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; + +import junit.framework.TestCase; + +import org.apache.commons.io.IOUtils; + +import com.alibaba.fastjson.JSON; + + +public class TestExternal extends TestCase { + public void test_0 () throws Exception { + ExtClassLoader classLoader = new ExtClassLoader(); + Class clazz = classLoader.loadClass("external.VO"); + Method method = clazz.getMethod("setName", new Class[] {String.class}); + Object obj = clazz.newInstance(); + method.invoke(obj, "jobs"); + + String text = JSON.toJSONString(obj); + System.out.println(text); + JSON.parseObject(text, clazz); + } + + public static class ExtClassLoader extends ClassLoader { + public ExtClassLoader() throws IOException{ + super(Thread.currentThread().getContextClassLoader()); + + byte[] bytes; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("external/VO.clazz"); + bytes = IOUtils.toByteArray(is); + is.close(); + + super.defineClass("external.VO", bytes, 0, bytes.length); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/TestExternal2.java b/src/test/java/com/alibaba/json/bvt/TestExternal2.java new file mode 100755 index 0000000000..6fd6e7b7d6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TestExternal2.java @@ -0,0 +1,80 @@ +package com.alibaba.json.bvt; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; + +import junit.framework.TestCase; + +import org.apache.commons.io.IOUtils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class TestExternal2 extends TestCase { + + public void test_0() throws Exception { + ExtClassLoader classLoader = new ExtClassLoader(); + + Class theClass = classLoader.loadClass("com.alibaba.mock.demo.service.MockDemoService"); + Method[] methods = theClass.getMethods(); + + //基本类型 + if (void.class.isPrimitive()) { + System.out.println("void"); + } + if (boolean.class.isPrimitive()) { + System.out.println("boolean"); + } + + for (Method method : methods) { + System.out.println("name: " + method.getName()); + + Class[] paraClassArray = method.getParameterTypes(); + for (Class paraClass : paraClassArray) { + System.out.println("parameters: " + paraClass); + + Package pkg = paraClass.getPackage(); + if (pkg == null || !pkg.getName().equals("java.lang")) { + Object obj = paraClass.newInstance(); + // System.out.println(obj); + + String kaka = JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue); + System.out.println(kaka); + System.out.println(kaka); + +// ObjectMapper objectMapper = new ObjectMapper(); +// String tt = objectMapper.writeValueAsString(obj); +// System.out.println(tt); + } + } + //System.out.println("return: " + method.getReturnType()); + //System.out.println("description: " + method.toGenericString()); + System.out.println(); + } + } + + public static class ExtClassLoader extends ClassLoader { + + public ExtClassLoader() throws IOException{ + super(Thread.currentThread().getContextClassLoader()); + + { + byte[] bytes; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("external/Demo.clazz"); + bytes = IOUtils.toByteArray(is); + is.close(); + + super.defineClass("com.alibaba.mock.demo.api.Demo", bytes, 0, bytes.length); + } + { + byte[] bytes; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("external/MockDemoService.clazz"); + bytes = IOUtils.toByteArray(is); + is.close(); + + super.defineClass("com.alibaba.mock.demo.service.MockDemoService", bytes, 0, bytes.length); + } + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/TestExternal3.java b/src/test/java/com/alibaba/json/bvt/TestExternal3.java new file mode 100755 index 0000000000..27f6239510 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TestExternal3.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; + +import org.junit.Assert; +import junit.framework.TestCase; + +import org.apache.commons.io.IOUtils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class TestExternal3 extends TestCase { + public void test_0 () throws Exception { + ExtClassLoader classLoader = new ExtClassLoader(); + Class clazz = classLoader.loadClass("external.VO"); + Method method = clazz.getMethod("setName", new Class[] {String.class}); + Object obj = clazz.newInstance(); + method.invoke(obj, "jobs"); + + String text = JSON.toJSONString(obj, SerializerFeature.WriteClassName); + System.out.println(text); + JSON.parseObject(text, clazz); + JSONObject jsonObj = JSON.parseObject(text); + Assert.assertEquals(jsonObj.getString("@type"), "external.VO"); + } + + public static class ExtClassLoader extends ClassLoader { + public ExtClassLoader() throws IOException{ + super(Thread.currentThread().getContextClassLoader()); + + byte[] bytes; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("external/VO.clazz"); + bytes = IOUtils.toByteArray(is); + is.close(); + + super.defineClass("external.VO", bytes, 0, bytes.length); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/TestExternal4.java b/src/test/java/com/alibaba/json/bvt/TestExternal4.java new file mode 100755 index 0000000000..bc4a2fc789 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TestExternal4.java @@ -0,0 +1,57 @@ +package com.alibaba.json.bvt; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.lang.reflect.Method; +import java.util.HashMap; + +import org.junit.Assert; +import junit.framework.TestCase; + +import org.apache.commons.io.IOUtils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class TestExternal4 extends TestCase { + + public void test_0() throws Exception { + ExtClassLoader classLoader = new ExtClassLoader(); + Class clazz = classLoader.loadClass("external.VO2"); + Method method = clazz.getMethod("setName", new Class[] { String.class }); + Method methodSetValue = clazz.getMethod("setValue", new Class[] { Serializable.class }); + + Object obj = clazz.newInstance(); + method.invoke(obj, "jobs"); + methodSetValue.invoke(obj, obj); + + { + String text = JSON.toJSONString(obj); + System.out.println(text); + } + + String text = JSON.toJSONString(obj, SerializerFeature.WriteClassName); + System.out.println(text); + JSON.parseObject(text, clazz); + JSONObject jsonObj = JSON.parseObject(text); + Assert.assertEquals(jsonObj.getString("@type"), "external.VO2"); + } + + public static class ExtClassLoader extends ClassLoader { + + public ExtClassLoader() throws IOException{ + super(Thread.currentThread().getContextClassLoader()); + + { + byte[] bytes; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("external/VO2.clazz"); + bytes = IOUtils.toByteArray(is); + is.close(); + + super.defineClass("external.VO2", bytes, 0, bytes.length); + } + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/TestExternal5.java b/src/test/java/com/alibaba/json/bvt/TestExternal5.java new file mode 100755 index 0000000000..36301030c7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TestExternal5.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.lang.reflect.Method; +import java.util.HashMap; + +import org.junit.Assert; +import junit.framework.TestCase; + +import org.apache.commons.io.IOUtils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class TestExternal5 extends TestCase { + + public void test_0() throws Exception { + ExtClassLoader classLoader = new ExtClassLoader(); + Class clazz = classLoader.loadClass("com.alibaba.dubbo.demo.MyEsbResultModel2"); + Method method = clazz.getMethod("setReturnValue", new Class[] { Serializable.class }); + + Object obj = clazz.newInstance(); + method.invoke(obj, "AAAA"); + + { + String text = JSON.toJSONString(obj); + System.out.println(text); + } + + String text = JSON.toJSONString(obj, SerializerFeature.WriteClassName, SerializerFeature.WriteMapNullValue); + System.out.println(text); + JSON.parseObject(text, clazz); + JSONObject jsonObj = JSON.parseObject(text); + Assert.assertEquals(jsonObj.getString("@type"), "com.alibaba.dubbo.demo.MyEsbResultModel2"); + } + + public static class ExtClassLoader extends ClassLoader { + + public ExtClassLoader() throws IOException{ + super(Thread.currentThread().getContextClassLoader()); + + { + byte[] bytes; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("external/MyEsbResultModel2.clazz"); + bytes = IOUtils.toByteArray(is); + is.close(); + + super.defineClass("com.alibaba.dubbo.demo.MyEsbResultModel2", bytes, 0, bytes.length); + } + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/TestExternal6.java b/src/test/java/com/alibaba/json/bvt/TestExternal6.java new file mode 100755 index 0000000000..9bcd5e7a53 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TestExternal6.java @@ -0,0 +1,72 @@ +package com.alibaba.json.bvt; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.lang.reflect.Method; +import java.util.HashMap; + +import org.junit.Assert; +import junit.framework.TestCase; + +import org.apache.commons.io.IOUtils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class TestExternal6 extends TestCase { + + public void test_0() throws Exception { + ExtClassLoader classLoader = new ExtClassLoader(); + Class clazz = classLoader.loadClass("org.mule.esb.model.tcc.result.EsbResultModel"); + Method[] methods = clazz.getMethods(); + Method method = clazz.getMethod("setReturnValue", new Class[] { Serializable.class }); + + Object obj = clazz.newInstance(); +// method.invoke(obj, "AAAA"); + + { + String text = JSON.toJSONString(obj); + System.out.println(text); + } + + String text = JSON.toJSONString(obj, SerializerFeature.WriteClassName, SerializerFeature.WriteMapNullValue); + System.out.println(text); + JSON.parseObject(text, clazz); + JSONObject jsonObj = JSON.parseObject(text); + Assert.assertEquals(jsonObj.getString("@type"), "org.mule.esb.model.tcc.result.EsbResultModel"); + } + + public static class ExtClassLoader extends ClassLoader { + + public ExtClassLoader() throws IOException{ + super(Thread.currentThread().getContextClassLoader()); + + { + byte[] bytes; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("external/EsbResultModel.clazz"); + bytes = IOUtils.toByteArray(is); + is.close(); + + super.defineClass("org.mule.esb.model.tcc.result.EsbResultModel", bytes, 0, bytes.length); + } + { + byte[] bytes; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("external/EsbListBean.clazz"); + bytes = IOUtils.toByteArray(is); + is.close(); + + super.defineClass("org.esb.crm.tools.EsbListBean", bytes, 0, bytes.length); + } + { + byte[] bytes; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("external/EsbHashMapBean.clazz"); + bytes = IOUtils.toByteArray(is); + is.close(); + + super.defineClass("org.esb.crm.tools.EsbHashMapBean", bytes, 0, bytes.length); + } + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/TestFlase.java b/src/test/java/com/alibaba/json/bvt/TestFlase.java new file mode 100644 index 0000000000..a474756d89 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TestFlase.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class TestFlase extends TestCase { + + public void test_0() throws Exception { + Object obj = JSON.parseObject("[{\"data\":{\"@type\":\"java.util.TreeMap\",false:21L},\"dataType\":2,\"dis\":0,\"length\":24,\"maxNum\":100,\"size\":3600000,\"version\":0}]", VO[].class); + System.out.println(JSON.toJSONString(obj)); + } + + public static class VO { + + private Object data; + + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/TestForEmoji.java b/src/test/java/com/alibaba/json/bvt/TestForEmoji.java new file mode 100755 index 0000000000..786ff5385a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TestForEmoji.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +import org.junit.Assert; +import junit.framework.TestCase; + + +public class TestForEmoji extends TestCase { + public void test_0 () throws Exception { + Assert.assertEquals("\"\\uE507\"", JSON.toJSONString("\uE507", SerializerFeature.BrowserCompatible)); + Assert.assertEquals("\"\\uE501\"", JSON.toJSONString("\uE501", SerializerFeature.BrowserCompatible)); + Assert.assertEquals("\"\\uE44C\"", JSON.toJSONString("\uE44C", SerializerFeature.BrowserCompatible)); + Assert.assertEquals("\"\\uE401\"", JSON.toJSONString("\uE401", SerializerFeature.BrowserCompatible)); + Assert.assertEquals("\"\\uE253\"", JSON.toJSONString("\uE253", SerializerFeature.BrowserCompatible)); + Assert.assertEquals("\"\\uE201\"", JSON.toJSONString("\uE201", SerializerFeature.BrowserCompatible)); + Assert.assertEquals("\"\\uE15A\"", JSON.toJSONString("\uE15A", SerializerFeature.BrowserCompatible)); + Assert.assertEquals("\"\\uE101\"", JSON.toJSONString("\uE101", SerializerFeature.BrowserCompatible)); + Assert.assertEquals("\"\\uE05A\"", JSON.toJSONString("\uE05A", SerializerFeature.BrowserCompatible)); + Assert.assertEquals("\"\\uE001\"", JSON.toJSONString("\uE001", SerializerFeature.BrowserCompatible)); + //E507 + } + + public void test_zh() throws Exception { + Assert.assertEquals("\"\\u4E2D\\u56FD\"", JSON.toJSONString("中国", SerializerFeature.BrowserCompatible)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/TestForPascalStyle.java b/src/test/java/com/alibaba/json/bvt/TestForPascalStyle.java new file mode 100755 index 0000000000..0ced5dc389 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TestForPascalStyle.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class TestForPascalStyle extends TestCase { + + public void test_for_pascal_style() throws Exception { + String text = "{\"ID\":12,\"Name\":\"Jobs\"}"; + VO vo = JSON.parseObject(text, VO.class); + Assert.assertEquals(vo.getId(), 12); + Assert.assertEquals(vo.getName(), "Jobs"); + } + + public static class VO { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/TestMultiLevelClass.java b/src/test/java/com/alibaba/json/bvt/TestMultiLevelClass.java new file mode 100755 index 0000000000..fe6dbe7adc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TestMultiLevelClass.java @@ -0,0 +1,61 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + +public class TestMultiLevelClass extends TestCase { + + public static class A { + + private B b; + + public B getB() { + return b; + } + + public void setB(B b) { + this.b = b; + } + + public static class B { + + private C c; + + public C getC() { + return c; + } + + public void setC(C c) { + this.c = c; + } + + static class C { + + private int value; + + + public int getValue() { + return value; + } + + + public void setValue(int value) { + this.value = value; + } + } + } + } + + public void test_codec() throws Exception { + A a = new A(); + a.setB(new A.B()); + a.getB().setC(new A.B.C()); + a.getB().getC().setValue(123); + + String text = JSON.toJSONString(a); + System.out.println(text); + + A a2 = JSON.parseObject(text, A.class); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/TestMultiLevelClass2.java b/src/test/java/com/alibaba/json/bvt/TestMultiLevelClass2.java new file mode 100755 index 0000000000..639d7e0416 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TestMultiLevelClass2.java @@ -0,0 +1,61 @@ +package com.alibaba.json.bvt; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + +public class TestMultiLevelClass2 extends TestCase { + + public static class A { + + private B b; + + public B getB() { + return b; + } + + public void setB(B b) { + this.b = b; + } + + public class B { + + private C c; + + public C getC() { + return c; + } + + public void setC(C c) { + this.c = c; + } + + class C { + + private int value; + + + public int getValue() { + return value; + } + + + public void setValue(int value) { + this.value = value; + } + } + } + } + + public void test_codec() throws Exception { + A a = new A(); + a.setB(a.new B()); + a.getB().setC(a.b.new C()); + a.getB().getC().setValue(123); + + String text = JSON.toJSONString(a); + System.out.println(text); + + A a2 = JSON.parseObject(text, A.class); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/TestNullKeyMap.java b/src/test/java/com/alibaba/json/bvt/TestNullKeyMap.java new file mode 100755 index 0000000000..e0375a6bf4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TestNullKeyMap.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt; + +import java.util.HashMap; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class TestNullKeyMap extends TestCase { + public void test_0 () throws Exception { + HashMap map = new HashMap(); + map.put(null, 123); + + String text = JSON.toJSONString(map); + + Assert.assertEquals("{null:123}", text); + + HashMap map2 = JSON.parseObject(text, HashMap.class); + Assert.assertEquals(map.get(null), map2.get(null)); + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/TestSerializable.java b/src/test/java/com/alibaba/json/bvt/TestSerializable.java new file mode 100755 index 0000000000..a483c59f7a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TestSerializable.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt; + +import java.io.Serializable; +import java.util.ArrayList; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class TestSerializable extends TestCase { + public void test_codec() throws Exception { + VO vo = new VO(); + vo.setValue(new ArrayList()); + + JSON.toJSONString(vo); + } + + public static class VO { + + private long id; + private Serializable value; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public Serializable getValue() { + return value; + } + + public void setValue(Serializable value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/TestTimeUnit.java b/src/test/java/com/alibaba/json/bvt/TestTimeUnit.java new file mode 100755 index 0000000000..35cffd2866 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TestTimeUnit.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt; + +import java.util.concurrent.TimeUnit; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class TestTimeUnit extends TestCase { + public void test_0 () throws Exception { + String text = JSON.toJSONString(TimeUnit.DAYS); + Assert.assertEquals(TimeUnit.DAYS, JSON.parseObject(text, TimeUnit.class)); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/TimeZoneFieldTest.java b/src/test/java/com/alibaba/json/bvt/TimeZoneFieldTest.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/TimeZoneFieldTest.java rename to src/test/java/com/alibaba/json/bvt/TimeZoneFieldTest.java index aa1f67a513..a800b07577 --- a/src/test/java/com/alibaba/json/test/bvt/TimeZoneFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/TimeZoneFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.TimeZone; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/TimestampTest.java b/src/test/java/com/alibaba/json/bvt/TimestampTest.java new file mode 100755 index 0000000000..2e6f5f9aca --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TimestampTest.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt; + + +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class TimestampTest extends TestCase { + public void test_0 () throws Exception { + long millis = (System.currentTimeMillis() / 1000) * 1000; + + String text = "\"" + new SimpleDateFormat(JSON.DEFFAULT_DATE_FORMAT).format(new Date(millis)) + "\""; + System.out.println(text); + Assert.assertEquals(new Timestamp(millis), JSON.parseObject("" + millis, Timestamp.class)); + Assert.assertEquals(new Timestamp(millis), JSON.parseObject("\"" + millis + "\"", Timestamp.class)); + Assert.assertEquals(new Timestamp(millis), JSON.parseObject(text, Timestamp.class)); + Assert.assertEquals(new java.sql.Date(millis), JSON.parseObject(text, java.sql.Date.class)); + Assert.assertEquals(new java.util.Date(millis), JSON.parseObject(text, java.util.Date.class)); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/TypeReferenceTest.java b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/TypeReferenceTest.java rename to src/test/java/com/alibaba/json/bvt/TypeReferenceTest.java index 9a5bf91b8f..968c4a7909 --- a/src/test/java/com/alibaba/json/test/bvt/TypeReferenceTest.java +++ b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -14,6 +14,7 @@ public class TypeReferenceTest extends TestCase { @SuppressWarnings("rawtypes") public void test_0() throws Exception { + System.out.println(System.getProperties()); String text; { @@ -95,4 +96,6 @@ public void setName(String name) { } } + + } diff --git a/src/test/java/com/alibaba/json/test/bvt/TypeReferenceTest2.java b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest2.java old mode 100644 new mode 100755 similarity index 97% rename from src/test/java/com/alibaba/json/test/bvt/TypeReferenceTest2.java rename to src/test/java/com/alibaba/json/bvt/TypeReferenceTest2.java index 65272c40ed..93d7aca7be --- a/src/test/java/com/alibaba/json/test/bvt/TypeReferenceTest2.java +++ b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest2.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.ArrayList; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/TypeReferenceTest3.java b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest3.java old mode 100644 new mode 100755 similarity index 97% rename from src/test/java/com/alibaba/json/test/bvt/TypeReferenceTest3.java rename to src/test/java/com/alibaba/json/bvt/TypeReferenceTest3.java index 4e561350fe..5f0aeb81aa --- a/src/test/java/com/alibaba/json/test/bvt/TypeReferenceTest3.java +++ b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest3.java @@ -1,11 +1,11 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/TypeReferenceTest4.java b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest4.java new file mode 100755 index 0000000000..798521481f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest4.java @@ -0,0 +1,48 @@ +package com.alibaba.json.bvt; + +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class TypeReferenceTest4 extends TestCase { + + public void test_typeRef() throws Exception { + TypeReference>> typeRef = new TypeReference>>() { + }; + + VO> vo = JSON.parseObject("{\"list\":[{\"id\":123}]}", typeRef); + + Assert.assertEquals(123, vo.getList().get(0).getId()); + } + + public static class VO { + + private T list; + + public T getList() { + return list; + } + + public void setList(T list) { + this.list = list; + } + } + + public static class A { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/TypeReferenceTest5.java b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest5.java new file mode 100755 index 0000000000..6399423d56 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest5.java @@ -0,0 +1,42 @@ +package com.alibaba.json.bvt; + +import java.util.LinkedHashMap; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class TypeReferenceTest5 extends TestCase { + + public void test_typeRef() throws Exception { + TypeReference> typeRef = new TypeReference>() { + }; + + A a = JSON.parseObject("{\"body\":{\"id\":123}}", typeRef); + + B b = a.getBody(); + Assert.assertEquals(123, b.get("id")); + } + + public static class A { + + private T body; + + public T getBody() { + return body; + } + + public void setBody(T body) { + this.body = body; + } + + } + + public static class B extends LinkedHashMap { + + private static final long serialVersionUID = 1L; + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/TypeReferenceTest6.java b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest6.java new file mode 100644 index 0000000000..c78b05475e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest6.java @@ -0,0 +1,65 @@ +package com.alibaba.json.bvt; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class TypeReferenceTest6 extends TestCase { + + public void test_typeRef() throws Exception { + TypeReference> typeRef = new TypeReference>() { + }; + + Map map = JSON.parseObject( + "{\"value\":{\"id\":\"abc\",\"list\":[{\"id\":123}]}}", typeRef); + + Entity entity = map.get("value"); + Assert.assertNotNull(entity); + Assert.assertEquals("abc", entity.getId()); + Assert.assertEquals(1, entity.getList().size()); + Assert.assertEquals(123, entity.getList().get(0).getId()); + } + + public static class Entity { + private String id; + + private List
list = new ArrayList(); + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + + } + + public static class A { + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/TypeReferenceTest7.java b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest7.java new file mode 100644 index 0000000000..684ad9d166 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest7.java @@ -0,0 +1,64 @@ +package com.alibaba.json.bvt; + +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class TypeReferenceTest7 extends TestCase { + + public void test_typeRef() throws Exception { + TypeReference> typeRef = new TypeReference>() { + }; + + Map map = JSON + .parseObject( + "{\"value\":{\"id\":\"abc\",\"a\":{\"id\":123}}}", + typeRef); + + Entity entity = map.get("value"); + Assert.assertNotNull(entity); + Assert.assertEquals("abc", entity.getId()); + Assert.assertEquals(123, entity.getA().getId()); + } + + public static class Entity { + private String id; + + private A a; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public A getA() { + return a; + } + + public void setA(A a) { + this.a = a; + } + + } + + public static class A { + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/TypeReferenceTest8.java b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest8.java new file mode 100644 index 0000000000..ec40ba2830 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest8.java @@ -0,0 +1,64 @@ +package com.alibaba.json.bvt; + +import java.util.List; +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class TypeReferenceTest8 extends TestCase { + + public void test_typeRef() throws Exception { + TypeReference> typeRef = new TypeReference>() { + }; + + Map map = JSON.parseObject( + "{\"value\":{\"id\":\"abc\",\"list\":[{\"id\":123}]}}", typeRef); + + Entity entity = map.get("value"); + Assert.assertNotNull(entity); + Assert.assertEquals("abc", entity.getId()); + Assert.assertEquals(1, entity.getList().length); + Assert.assertEquals(123, entity.getList()[0].getId()); + } + + public static class Entity { + private String id; + + private A[] list; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public A[] getList() { + return list; + } + + public void setList(A[] list) { + this.list = list; + } + + } + + public static class A { + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/TypeReferenceTest9.java b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest9.java new file mode 100644 index 0000000000..623761f222 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/TypeReferenceTest9.java @@ -0,0 +1,77 @@ +package com.alibaba.json.bvt; + +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class TypeReferenceTest9 extends TestCase { + + public void test_typeRef() throws Exception { + TypeReference> typeRef = new TypeReference>() { + }; + + Map map = JSON + .parseObject( + "{\"value\":{\"id\":\"abc\",\"list\":[{\"id\":123,\"type\":\"A\"}]}}", + typeRef); + + Entity entity = map.get("value"); + Assert.assertNotNull(entity); + Assert.assertEquals("abc", entity.getId()); + Assert.assertEquals(1, entity.getList().length); + Assert.assertEquals(123, entity.getList()[0].getId()); + } + + public static class Entity { + private String id; + + private A[] list; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public A[] getList() { + return list; + } + + public void setList(A[] list) { + this.list = list; + } + + } + + public static class A { + private int id; + private Type type; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + } + + public static enum Type { + A + } + +} diff --git a/src/test/java/com/alibaba/json/test/bvt/TypeUtilstTest.java b/src/test/java/com/alibaba/json/bvt/TypeUtilstTest.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/TypeUtilstTest.java rename to src/test/java/com/alibaba/json/bvt/TypeUtilstTest.java index 00b9920e0b..2a67565f8d --- a/src/test/java/com/alibaba/json/test/bvt/TypeUtilstTest.java +++ b/src/test/java/com/alibaba/json/bvt/TypeUtilstTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.math.BigDecimal; import java.math.BigInteger; diff --git a/src/test/java/com/alibaba/json/test/bvt/URIFieldTest.java b/src/test/java/com/alibaba/json/bvt/URIFieldTest.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/URIFieldTest.java rename to src/test/java/com/alibaba/json/bvt/URIFieldTest.java index 6a7dc7d971..c64e1a8667 --- a/src/test/java/com/alibaba/json/test/bvt/URIFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/URIFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.net.URI; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/URLFieldTest.java b/src/test/java/com/alibaba/json/bvt/URLFieldTest.java old mode 100644 new mode 100755 similarity index 85% rename from src/test/java/com/alibaba/json/test/bvt/URLFieldTest.java rename to src/test/java/com/alibaba/json/bvt/URLFieldTest.java index 0d3bfc34d2..57add69509 --- a/src/test/java/com/alibaba/json/test/bvt/URLFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/URLFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.net.URL; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -18,10 +18,11 @@ public void test_codec() throws Exception { SerializeConfig mapping = new SerializeConfig(); mapping.setAsmEnable(false); String text = JSON.toJSONString(user, mapping, SerializerFeature.WriteMapNullValue); + System.out.println(text); User user1 = JSON.parseObject(text, User.class); - Assert.assertEquals(user1.getValue(), user.getValue()); + Assert.assertEquals(user1.getValue().toString(), user.getValue().toString()); } public void test_codec_null() throws Exception { diff --git a/src/test/java/com/alibaba/json/test/bvt/UUIDFieldTest.java b/src/test/java/com/alibaba/json/bvt/UUIDFieldTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/UUIDFieldTest.java rename to src/test/java/com/alibaba/json/bvt/UUIDFieldTest.java index d5ded9bfc0..5b1628bc94 --- a/src/test/java/com/alibaba/json/test/bvt/UUIDFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/UUIDFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt; +package com.alibaba.json.bvt; import java.util.UUID; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/WriteClassNameTest.java b/src/test/java/com/alibaba/json/bvt/WriteClassNameTest.java new file mode 100755 index 0000000000..dc4dbf3b77 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/WriteClassNameTest.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteClassNameTest extends TestCase { + + public void test_0() throws Exception { + Entity entity = new Entity(3, "jobs"); + String text = JSON.toJSONString(entity, SerializerFeature.WriteClassName); + System.out.println(text); + + Entity entity2 = (Entity) JSON.parseObject(text, Object.class); + + Assert.assertEquals(entity.getId(), entity2.getId()); + Assert.assertEquals(entity.getName(), entity2.getName()); + } + + public static class Entity { + + private int id; + private String name; + + public Entity(){ + } + + public Entity(int id, String name){ + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/WriteClassNameTest2.java b/src/test/java/com/alibaba/json/bvt/WriteClassNameTest2.java new file mode 100755 index 0000000000..297ece8d07 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/WriteClassNameTest2.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteClassNameTest2 extends TestCase { + + public void test_0() throws Exception { + Entity entity = new Entity(3, "jobs"); + String text = JSON.toJSONString(entity, SerializerFeature.WriteClassName, SerializerFeature.PrettyFormat); + System.out.println(text); + + Entity entity2 = (Entity) JSON.parseObject(text, Object.class); + + Assert.assertEquals(entity.getId(), entity2.getId()); + Assert.assertEquals(entity.getName(), entity2.getName()); + } + + public static class Entity { + + private int id; + private String name; + + public Entity(){ + } + + public Entity(int id, String name){ + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/annotation/JSONTypejsonType_alphabetic_Test.java b/src/test/java/com/alibaba/json/bvt/annotation/JSONTypejsonType_alphabetic_Test.java new file mode 100755 index 0000000000..a26db38591 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/annotation/JSONTypejsonType_alphabetic_Test.java @@ -0,0 +1,114 @@ +package com.alibaba.json.bvt.annotation; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; + +public class JSONTypejsonType_alphabetic_Test extends TestCase { + + public void test_alphabetic_true() throws Exception { + A a = new A(); + a.setF0(101); + a.setF1(102); + + Assert.assertEquals("{\"f0\":101,\"f1\":102}", JSON.toJSONString(a)); + } + +// public void test_alphabetic_false() throws Exception { +// B b = new B(); +// b.setF0(101); +// b.setF1(102); +// +// Assert.assertFalse("{\"f2\":0,\"f1\":102,\"f0\":101}".equals(JSON.toJSONString(b))); +// } + + public void test_alphabetic_notSet() throws Exception { + C c = new C(); + c.setF0(101); + c.setF1(102); + + Assert.assertEquals("{\"f0\":101,\"f1\":102}", JSON.toJSONString(c)); + } + + @JSONType(alphabetic = true) + public static class A { + + private int f1; + private int f0; + + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + } + + @JSONType(alphabetic = false) + public static class B { + + private int f2; + private int f1; + private int f0; + + public int getF2() { + return f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + } + + public static class C { + + private int f1; + private int f0; + + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/asm/ASMDeserTest.java b/src/test/java/com/alibaba/json/bvt/asm/ASMDeserTest.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/asm/ASMDeserTest.java rename to src/test/java/com/alibaba/json/bvt/asm/ASMDeserTest.java index c3bec3e0e1..29aa78a4bc --- a/src/test/java/com/alibaba/json/test/bvt/asm/ASMDeserTest.java +++ b/src/test/java/com/alibaba/json/bvt/asm/ASMDeserTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.asm; +package com.alibaba.json.bvt.asm; import java.util.ArrayList; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/asm/ASMDeserTest2.java b/src/test/java/com/alibaba/json/bvt/asm/ASMDeserTest2.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/asm/ASMDeserTest2.java rename to src/test/java/com/alibaba/json/bvt/asm/ASMDeserTest2.java index ca1dfd4710..2338f89691 --- a/src/test/java/com/alibaba/json/test/bvt/asm/ASMDeserTest2.java +++ b/src/test/java/com/alibaba/json/bvt/asm/ASMDeserTest2.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.asm; +package com.alibaba.json.bvt.asm; import java.util.ArrayList; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/asm/ASMUtilsTest.java b/src/test/java/com/alibaba/json/bvt/asm/ASMUtilsTest.java new file mode 100755 index 0000000000..bdd0a5c9e9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/asm/ASMUtilsTest.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.asm; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.parser.ParseContext; +import com.alibaba.fastjson.util.ASMUtils; + +public class ASMUtilsTest extends TestCase { + + public void test_isAnroid() throws Exception { + Assert.assertTrue(ASMUtils.isAndroid("Dalvik")); + } + + public void test_getDescs() throws Exception { + Assert.assertEquals("Lcom/alibaba/fastjson/parser/ParseContext;", ASMUtils.getDesc(ParseContext.class)); + } + + public void test_getType_null() throws Exception { + Assert.assertNull(ASMUtils.getMethodType(ParseContext.class, "XX")); + } + + public void test_getFieldType_null() throws Exception { + Assert.assertNull(ASMUtils.getFieldType(ParseContext.class, "XX")); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/asm/Case0.java b/src/test/java/com/alibaba/json/bvt/asm/Case0.java old mode 100644 new mode 100755 similarity index 89% rename from src/test/java/com/alibaba/json/test/bvt/asm/Case0.java rename to src/test/java/com/alibaba/json/bvt/asm/Case0.java index c1f1ebd163..a0a5f23d4c --- a/src/test/java/com/alibaba/json/test/bvt/asm/Case0.java +++ b/src/test/java/com/alibaba/json/bvt/asm/Case0.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.asm; +package com.alibaba.json.bvt.asm; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/asm/Case_Eishay.java b/src/test/java/com/alibaba/json/bvt/asm/Case_Eishay.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/asm/Case_Eishay.java rename to src/test/java/com/alibaba/json/bvt/asm/Case_Eishay.java index fbe389fcc3..985c96d4e7 --- a/src/test/java/com/alibaba/json/test/bvt/asm/Case_Eishay.java +++ b/src/test/java/com/alibaba/json/bvt/asm/Case_Eishay.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.asm; +package com.alibaba.json.bvt.asm; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/bvt/asm/Huge_200_ClassTest.java b/src/test/java/com/alibaba/json/bvt/asm/Huge_200_ClassTest.java new file mode 100755 index 0000000000..14a1b7884f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/asm/Huge_200_ClassTest.java @@ -0,0 +1,1826 @@ +package com.alibaba.json.bvt.asm; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + +public class Huge_200_ClassTest extends TestCase { + public void test_huge() { + JSON.parseObject("{}", VO.class); + } + + public static class VO { + + private Integer f000; + private Integer f001; + private Integer f002; + private Integer f003; + private Integer f004; + private Integer f005; + private Integer f006; + private Integer f007; + private Integer f008; + private Integer f009; + + private Integer f010; + private Integer f011; + private Integer f012; + private Integer f013; + private Integer f014; + private Integer f015; + private Integer f016; + private Integer f017; + private Integer f018; + private Integer f019; + + private Integer f020; + private Integer f021; + private Integer f022; + private Integer f023; + private Integer f024; + private Integer f025; + private Integer f026; + private Integer f027; + private Integer f028; + private Integer f029; + + private Integer f030; + private Integer f031; + private Integer f032; + private Integer f033; + private Integer f034; + private Integer f035; + private Integer f036; + private Integer f037; + private Integer f038; + private Integer f039; + + private Integer f040; + private Integer f041; + private Integer f042; + private Integer f043; + private Integer f044; + private Integer f045; + private Integer f046; + private Integer f047; + private Integer f048; + private Integer f049; + + private Integer f050; + private Integer f051; + private Integer f052; + private Integer f053; + private Integer f054; + private Integer f055; + private Integer f056; + private Integer f057; + private Integer f058; + private Integer f059; + + private Integer f060; + private Integer f061; + private Integer f062; + private Integer f063; + private Integer f064; + private Integer f065; + private Integer f066; + private Integer f067; + private Integer f068; + private Integer f069; + + private Integer f070; + private Integer f071; + private Integer f072; + private Integer f073; + private Integer f074; + private Integer f075; + private Integer f076; + private Integer f077; + private Integer f078; + private Integer f079; + + private Integer f080; + private Integer f081; + private Integer f082; + private Integer f083; + private Integer f084; + private Integer f085; + private Integer f086; + private Integer f087; + private Integer f088; + private Integer f089; + + private Integer f090; + private Integer f091; + private Integer f092; + private Integer f093; + private Integer f094; + private Integer f095; + private Integer f096; + private Integer f097; + private Integer f098; + private Integer f099; + + private Integer f100; + private Integer f101; + private Integer f102; + private Integer f103; + private Integer f104; + private Integer f105; + private Integer f106; + private Integer f107; + private Integer f108; + private Integer f109; + private Integer f110; + private Integer f111; + private Integer f112; + private Integer f113; + private Integer f114; + private Integer f115; + private Integer f116; + private Integer f117; + private Integer f118; + private Integer f119; + private Integer f120; + private Integer f121; + private Integer f122; + private Integer f123; + private Integer f124; + private Integer f125; + private Integer f126; + private Integer f127; + private Integer f128; + private Integer f129; + private Integer f130; + private Integer f131; + private Integer f132; + private Integer f133; + private Integer f134; + private Integer f135; + private Integer f136; + private Integer f137; + private Integer f138; + private Integer f139; + private Integer f140; + private Integer f141; + private Integer f142; + private Integer f143; + private Integer f144; + private Integer f145; + private Integer f146; + private Integer f147; + private Integer f148; + private Integer f149; + private Integer f150; + private Integer f151; + private Integer f152; + private Integer f153; + private Integer f154; + private Integer f155; + private Integer f156; + private Integer f157; + private Integer f158; + private Integer f159; + private Integer f160; + private Integer f161; + private Integer f162; + private Integer f163; + private Integer f164; + private Integer f165; + private Integer f166; + private Integer f167; + private Integer f168; + private Integer f169; + private Integer f170; + private Integer f171; + private Integer f172; + private Integer f173; + private Integer f174; + private Integer f175; + private Integer f176; + private Integer f177; + private Integer f178; + private Integer f179; + private Integer f180; + private Integer f181; + private Integer f182; + private Integer f183; + private Integer f184; + private Integer f185; + private Integer f186; + private Integer f187; + private Integer f188; + private Integer f189; + private Integer f190; + private Integer f191; + private Integer f192; + private Integer f193; + private Integer f194; + private Integer f195; + private Integer f196; + private Integer f197; + private Integer f198; + private Integer f199; + + public Integer getF000() { + return f000; + } + + public void setF000(Integer f000) { + this.f000 = f000; + } + + public Integer getF001() { + return f001; + } + + public void setF001(Integer f001) { + this.f001 = f001; + } + + public Integer getF002() { + return f002; + } + + public void setF002(Integer f002) { + this.f002 = f002; + } + + public Integer getF003() { + return f003; + } + + public void setF003(Integer f003) { + this.f003 = f003; + } + + public Integer getF004() { + return f004; + } + + public void setF004(Integer f004) { + this.f004 = f004; + } + + public Integer getF005() { + return f005; + } + + public void setF005(Integer f005) { + this.f005 = f005; + } + + public Integer getF006() { + return f006; + } + + public void setF006(Integer f006) { + this.f006 = f006; + } + + public Integer getF007() { + return f007; + } + + public void setF007(Integer f007) { + this.f007 = f007; + } + + public Integer getF008() { + return f008; + } + + public void setF008(Integer f008) { + this.f008 = f008; + } + + public Integer getF009() { + return f009; + } + + public void setF009(Integer f009) { + this.f009 = f009; + } + + public Integer getF010() { + return f010; + } + + public void setF010(Integer f010) { + this.f010 = f010; + } + + public Integer getF011() { + return f011; + } + + public void setF011(Integer f011) { + this.f011 = f011; + } + + public Integer getF012() { + return f012; + } + + public void setF012(Integer f012) { + this.f012 = f012; + } + + public Integer getF013() { + return f013; + } + + public void setF013(Integer f013) { + this.f013 = f013; + } + + public Integer getF014() { + return f014; + } + + public void setF014(Integer f014) { + this.f014 = f014; + } + + public Integer getF015() { + return f015; + } + + public void setF015(Integer f015) { + this.f015 = f015; + } + + public Integer getF016() { + return f016; + } + + public void setF016(Integer f016) { + this.f016 = f016; + } + + public Integer getF017() { + return f017; + } + + public void setF017(Integer f017) { + this.f017 = f017; + } + + public Integer getF018() { + return f018; + } + + public void setF018(Integer f018) { + this.f018 = f018; + } + + public Integer getF019() { + return f019; + } + + public void setF019(Integer f019) { + this.f019 = f019; + } + + public Integer getF020() { + return f020; + } + + public void setF020(Integer f020) { + this.f020 = f020; + } + + public Integer getF021() { + return f021; + } + + public void setF021(Integer f021) { + this.f021 = f021; + } + + public Integer getF022() { + return f022; + } + + public void setF022(Integer f022) { + this.f022 = f022; + } + + public Integer getF023() { + return f023; + } + + public void setF023(Integer f023) { + this.f023 = f023; + } + + public Integer getF024() { + return f024; + } + + public void setF024(Integer f024) { + this.f024 = f024; + } + + public Integer getF025() { + return f025; + } + + public void setF025(Integer f025) { + this.f025 = f025; + } + + public Integer getF026() { + return f026; + } + + public void setF026(Integer f026) { + this.f026 = f026; + } + + public Integer getF027() { + return f027; + } + + public void setF027(Integer f027) { + this.f027 = f027; + } + + public Integer getF028() { + return f028; + } + + public void setF028(Integer f028) { + this.f028 = f028; + } + + public Integer getF029() { + return f029; + } + + public void setF029(Integer f029) { + this.f029 = f029; + } + + public Integer getF030() { + return f030; + } + + public void setF030(Integer f030) { + this.f030 = f030; + } + + public Integer getF031() { + return f031; + } + + public void setF031(Integer f031) { + this.f031 = f031; + } + + public Integer getF032() { + return f032; + } + + public void setF032(Integer f032) { + this.f032 = f032; + } + + public Integer getF033() { + return f033; + } + + public void setF033(Integer f033) { + this.f033 = f033; + } + + public Integer getF034() { + return f034; + } + + public void setF034(Integer f034) { + this.f034 = f034; + } + + public Integer getF035() { + return f035; + } + + public void setF035(Integer f035) { + this.f035 = f035; + } + + public Integer getF036() { + return f036; + } + + public void setF036(Integer f036) { + this.f036 = f036; + } + + public Integer getF037() { + return f037; + } + + public void setF037(Integer f037) { + this.f037 = f037; + } + + public Integer getF038() { + return f038; + } + + public void setF038(Integer f038) { + this.f038 = f038; + } + + public Integer getF039() { + return f039; + } + + public void setF039(Integer f039) { + this.f039 = f039; + } + + public Integer getF040() { + return f040; + } + + public void setF040(Integer f040) { + this.f040 = f040; + } + + public Integer getF041() { + return f041; + } + + public void setF041(Integer f041) { + this.f041 = f041; + } + + public Integer getF042() { + return f042; + } + + public void setF042(Integer f042) { + this.f042 = f042; + } + + public Integer getF043() { + return f043; + } + + public void setF043(Integer f043) { + this.f043 = f043; + } + + public Integer getF044() { + return f044; + } + + public void setF044(Integer f044) { + this.f044 = f044; + } + + public Integer getF045() { + return f045; + } + + public void setF045(Integer f045) { + this.f045 = f045; + } + + public Integer getF046() { + return f046; + } + + public void setF046(Integer f046) { + this.f046 = f046; + } + + public Integer getF047() { + return f047; + } + + public void setF047(Integer f047) { + this.f047 = f047; + } + + public Integer getF048() { + return f048; + } + + public void setF048(Integer f048) { + this.f048 = f048; + } + + public Integer getF049() { + return f049; + } + + public void setF049(Integer f049) { + this.f049 = f049; + } + + public Integer getF050() { + return f050; + } + + public void setF050(Integer f050) { + this.f050 = f050; + } + + public Integer getF051() { + return f051; + } + + public void setF051(Integer f051) { + this.f051 = f051; + } + + public Integer getF052() { + return f052; + } + + public void setF052(Integer f052) { + this.f052 = f052; + } + + public Integer getF053() { + return f053; + } + + public void setF053(Integer f053) { + this.f053 = f053; + } + + public Integer getF054() { + return f054; + } + + public void setF054(Integer f054) { + this.f054 = f054; + } + + public Integer getF055() { + return f055; + } + + public void setF055(Integer f055) { + this.f055 = f055; + } + + public Integer getF056() { + return f056; + } + + public void setF056(Integer f056) { + this.f056 = f056; + } + + public Integer getF057() { + return f057; + } + + public void setF057(Integer f057) { + this.f057 = f057; + } + + public Integer getF058() { + return f058; + } + + public void setF058(Integer f058) { + this.f058 = f058; + } + + public Integer getF059() { + return f059; + } + + public void setF059(Integer f059) { + this.f059 = f059; + } + + public Integer getF060() { + return f060; + } + + public void setF060(Integer f060) { + this.f060 = f060; + } + + public Integer getF061() { + return f061; + } + + public void setF061(Integer f061) { + this.f061 = f061; + } + + public Integer getF062() { + return f062; + } + + public void setF062(Integer f062) { + this.f062 = f062; + } + + public Integer getF063() { + return f063; + } + + public void setF063(Integer f063) { + this.f063 = f063; + } + + public Integer getF064() { + return f064; + } + + public void setF064(Integer f064) { + this.f064 = f064; + } + + public Integer getF065() { + return f065; + } + + public void setF065(Integer f065) { + this.f065 = f065; + } + + public Integer getF066() { + return f066; + } + + public void setF066(Integer f066) { + this.f066 = f066; + } + + public Integer getF067() { + return f067; + } + + public void setF067(Integer f067) { + this.f067 = f067; + } + + public Integer getF068() { + return f068; + } + + public void setF068(Integer f068) { + this.f068 = f068; + } + + public Integer getF069() { + return f069; + } + + public void setF069(Integer f069) { + this.f069 = f069; + } + + public Integer getF070() { + return f070; + } + + public void setF070(Integer f070) { + this.f070 = f070; + } + + public Integer getF071() { + return f071; + } + + public void setF071(Integer f071) { + this.f071 = f071; + } + + public Integer getF072() { + return f072; + } + + public void setF072(Integer f072) { + this.f072 = f072; + } + + public Integer getF073() { + return f073; + } + + public void setF073(Integer f073) { + this.f073 = f073; + } + + public Integer getF074() { + return f074; + } + + public void setF074(Integer f074) { + this.f074 = f074; + } + + public Integer getF075() { + return f075; + } + + public void setF075(Integer f075) { + this.f075 = f075; + } + + public Integer getF076() { + return f076; + } + + public void setF076(Integer f076) { + this.f076 = f076; + } + + public Integer getF077() { + return f077; + } + + public void setF077(Integer f077) { + this.f077 = f077; + } + + public Integer getF078() { + return f078; + } + + public void setF078(Integer f078) { + this.f078 = f078; + } + + public Integer getF079() { + return f079; + } + + public void setF079(Integer f079) { + this.f079 = f079; + } + + public Integer getF080() { + return f080; + } + + public void setF080(Integer f080) { + this.f080 = f080; + } + + public Integer getF081() { + return f081; + } + + public void setF081(Integer f081) { + this.f081 = f081; + } + + public Integer getF082() { + return f082; + } + + public void setF082(Integer f082) { + this.f082 = f082; + } + + public Integer getF083() { + return f083; + } + + public void setF083(Integer f083) { + this.f083 = f083; + } + + public Integer getF084() { + return f084; + } + + public void setF084(Integer f084) { + this.f084 = f084; + } + + public Integer getF085() { + return f085; + } + + public void setF085(Integer f085) { + this.f085 = f085; + } + + public Integer getF086() { + return f086; + } + + public void setF086(Integer f086) { + this.f086 = f086; + } + + public Integer getF087() { + return f087; + } + + public void setF087(Integer f087) { + this.f087 = f087; + } + + public Integer getF088() { + return f088; + } + + public void setF088(Integer f088) { + this.f088 = f088; + } + + public Integer getF089() { + return f089; + } + + public void setF089(Integer f089) { + this.f089 = f089; + } + + public Integer getF090() { + return f090; + } + + public void setF090(Integer f090) { + this.f090 = f090; + } + + public Integer getF091() { + return f091; + } + + public void setF091(Integer f091) { + this.f091 = f091; + } + + public Integer getF092() { + return f092; + } + + public void setF092(Integer f092) { + this.f092 = f092; + } + + public Integer getF093() { + return f093; + } + + public void setF093(Integer f093) { + this.f093 = f093; + } + + public Integer getF094() { + return f094; + } + + public void setF094(Integer f094) { + this.f094 = f094; + } + + public Integer getF095() { + return f095; + } + + public void setF095(Integer f095) { + this.f095 = f095; + } + + public Integer getF096() { + return f096; + } + + public void setF096(Integer f096) { + this.f096 = f096; + } + + public Integer getF097() { + return f097; + } + + public void setF097(Integer f097) { + this.f097 = f097; + } + + public Integer getF098() { + return f098; + } + + public void setF098(Integer f098) { + this.f098 = f098; + } + + public Integer getF099() { + return f099; + } + + public void setF099(Integer f099) { + this.f099 = f099; + } + + public Integer getF100() { + return f100; + } + + public void setF100(Integer f100) { + this.f100 = f100; + } + + public Integer getF101() { + return f101; + } + + public void setF101(Integer f101) { + this.f101 = f101; + } + + public Integer getF102() { + return f102; + } + + public void setF102(Integer f102) { + this.f102 = f102; + } + + public Integer getF103() { + return f103; + } + + public void setF103(Integer f103) { + this.f103 = f103; + } + + public Integer getF104() { + return f104; + } + + public void setF104(Integer f104) { + this.f104 = f104; + } + + public Integer getF105() { + return f105; + } + + public void setF105(Integer f105) { + this.f105 = f105; + } + + public Integer getF106() { + return f106; + } + + public void setF106(Integer f106) { + this.f106 = f106; + } + + public Integer getF107() { + return f107; + } + + public void setF107(Integer f107) { + this.f107 = f107; + } + + public Integer getF108() { + return f108; + } + + public void setF108(Integer f108) { + this.f108 = f108; + } + + public Integer getF109() { + return f109; + } + + public void setF109(Integer f109) { + this.f109 = f109; + } + + public Integer getF110() { + return f110; + } + + public void setF110(Integer f110) { + this.f110 = f110; + } + + public Integer getF111() { + return f111; + } + + public void setF111(Integer f111) { + this.f111 = f111; + } + + public Integer getF112() { + return f112; + } + + public void setF112(Integer f112) { + this.f112 = f112; + } + + public Integer getF113() { + return f113; + } + + public void setF113(Integer f113) { + this.f113 = f113; + } + + public Integer getF114() { + return f114; + } + + public void setF114(Integer f114) { + this.f114 = f114; + } + + public Integer getF115() { + return f115; + } + + public void setF115(Integer f115) { + this.f115 = f115; + } + + public Integer getF116() { + return f116; + } + + public void setF116(Integer f116) { + this.f116 = f116; + } + + public Integer getF117() { + return f117; + } + + public void setF117(Integer f117) { + this.f117 = f117; + } + + public Integer getF118() { + return f118; + } + + public void setF118(Integer f118) { + this.f118 = f118; + } + + public Integer getF119() { + return f119; + } + + public void setF119(Integer f119) { + this.f119 = f119; + } + + public Integer getF120() { + return f120; + } + + public void setF120(Integer f120) { + this.f120 = f120; + } + + public Integer getF121() { + return f121; + } + + public void setF121(Integer f121) { + this.f121 = f121; + } + + public Integer getF122() { + return f122; + } + + public void setF122(Integer f122) { + this.f122 = f122; + } + + public Integer getF123() { + return f123; + } + + public void setF123(Integer f123) { + this.f123 = f123; + } + + public Integer getF124() { + return f124; + } + + public void setF124(Integer f124) { + this.f124 = f124; + } + + public Integer getF125() { + return f125; + } + + public void setF125(Integer f125) { + this.f125 = f125; + } + + public Integer getF126() { + return f126; + } + + public void setF126(Integer f126) { + this.f126 = f126; + } + + public Integer getF127() { + return f127; + } + + public void setF127(Integer f127) { + this.f127 = f127; + } + + public Integer getF128() { + return f128; + } + + public void setF128(Integer f128) { + this.f128 = f128; + } + + public Integer getF129() { + return f129; + } + + public void setF129(Integer f129) { + this.f129 = f129; + } + + public Integer getF130() { + return f130; + } + + public void setF130(Integer f130) { + this.f130 = f130; + } + + public Integer getF131() { + return f131; + } + + public void setF131(Integer f131) { + this.f131 = f131; + } + + public Integer getF132() { + return f132; + } + + public void setF132(Integer f132) { + this.f132 = f132; + } + + public Integer getF133() { + return f133; + } + + public void setF133(Integer f133) { + this.f133 = f133; + } + + public Integer getF134() { + return f134; + } + + public void setF134(Integer f134) { + this.f134 = f134; + } + + public Integer getF135() { + return f135; + } + + public void setF135(Integer f135) { + this.f135 = f135; + } + + public Integer getF136() { + return f136; + } + + public void setF136(Integer f136) { + this.f136 = f136; + } + + public Integer getF137() { + return f137; + } + + public void setF137(Integer f137) { + this.f137 = f137; + } + + public Integer getF138() { + return f138; + } + + public void setF138(Integer f138) { + this.f138 = f138; + } + + public Integer getF139() { + return f139; + } + + public void setF139(Integer f139) { + this.f139 = f139; + } + + public Integer getF140() { + return f140; + } + + public void setF140(Integer f140) { + this.f140 = f140; + } + + public Integer getF141() { + return f141; + } + + public void setF141(Integer f141) { + this.f141 = f141; + } + + public Integer getF142() { + return f142; + } + + public void setF142(Integer f142) { + this.f142 = f142; + } + + public Integer getF143() { + return f143; + } + + public void setF143(Integer f143) { + this.f143 = f143; + } + + public Integer getF144() { + return f144; + } + + public void setF144(Integer f144) { + this.f144 = f144; + } + + public Integer getF145() { + return f145; + } + + public void setF145(Integer f145) { + this.f145 = f145; + } + + public Integer getF146() { + return f146; + } + + public void setF146(Integer f146) { + this.f146 = f146; + } + + public Integer getF147() { + return f147; + } + + public void setF147(Integer f147) { + this.f147 = f147; + } + + public Integer getF148() { + return f148; + } + + public void setF148(Integer f148) { + this.f148 = f148; + } + + public Integer getF149() { + return f149; + } + + public void setF149(Integer f149) { + this.f149 = f149; + } + + public Integer getF150() { + return f150; + } + + public void setF150(Integer f150) { + this.f150 = f150; + } + + public Integer getF151() { + return f151; + } + + public void setF151(Integer f151) { + this.f151 = f151; + } + + public Integer getF152() { + return f152; + } + + public void setF152(Integer f152) { + this.f152 = f152; + } + + public Integer getF153() { + return f153; + } + + public void setF153(Integer f153) { + this.f153 = f153; + } + + public Integer getF154() { + return f154; + } + + public void setF154(Integer f154) { + this.f154 = f154; + } + + public Integer getF155() { + return f155; + } + + public void setF155(Integer f155) { + this.f155 = f155; + } + + public Integer getF156() { + return f156; + } + + public void setF156(Integer f156) { + this.f156 = f156; + } + + public Integer getF157() { + return f157; + } + + public void setF157(Integer f157) { + this.f157 = f157; + } + + public Integer getF158() { + return f158; + } + + public void setF158(Integer f158) { + this.f158 = f158; + } + + public Integer getF159() { + return f159; + } + + public void setF159(Integer f159) { + this.f159 = f159; + } + + public Integer getF160() { + return f160; + } + + public void setF160(Integer f160) { + this.f160 = f160; + } + + public Integer getF161() { + return f161; + } + + public void setF161(Integer f161) { + this.f161 = f161; + } + + public Integer getF162() { + return f162; + } + + public void setF162(Integer f162) { + this.f162 = f162; + } + + public Integer getF163() { + return f163; + } + + public void setF163(Integer f163) { + this.f163 = f163; + } + + public Integer getF164() { + return f164; + } + + public void setF164(Integer f164) { + this.f164 = f164; + } + + public Integer getF165() { + return f165; + } + + public void setF165(Integer f165) { + this.f165 = f165; + } + + public Integer getF166() { + return f166; + } + + public void setF166(Integer f166) { + this.f166 = f166; + } + + public Integer getF167() { + return f167; + } + + public void setF167(Integer f167) { + this.f167 = f167; + } + + public Integer getF168() { + return f168; + } + + public void setF168(Integer f168) { + this.f168 = f168; + } + + public Integer getF169() { + return f169; + } + + public void setF169(Integer f169) { + this.f169 = f169; + } + + public Integer getF170() { + return f170; + } + + public void setF170(Integer f170) { + this.f170 = f170; + } + + public Integer getF171() { + return f171; + } + + public void setF171(Integer f171) { + this.f171 = f171; + } + + public Integer getF172() { + return f172; + } + + public void setF172(Integer f172) { + this.f172 = f172; + } + + public Integer getF173() { + return f173; + } + + public void setF173(Integer f173) { + this.f173 = f173; + } + + public Integer getF174() { + return f174; + } + + public void setF174(Integer f174) { + this.f174 = f174; + } + + public Integer getF175() { + return f175; + } + + public void setF175(Integer f175) { + this.f175 = f175; + } + + public Integer getF176() { + return f176; + } + + public void setF176(Integer f176) { + this.f176 = f176; + } + + public Integer getF177() { + return f177; + } + + public void setF177(Integer f177) { + this.f177 = f177; + } + + public Integer getF178() { + return f178; + } + + public void setF178(Integer f178) { + this.f178 = f178; + } + + public Integer getF179() { + return f179; + } + + public void setF179(Integer f179) { + this.f179 = f179; + } + + public Integer getF180() { + return f180; + } + + public void setF180(Integer f180) { + this.f180 = f180; + } + + public Integer getF181() { + return f181; + } + + public void setF181(Integer f181) { + this.f181 = f181; + } + + public Integer getF182() { + return f182; + } + + public void setF182(Integer f182) { + this.f182 = f182; + } + + public Integer getF183() { + return f183; + } + + public void setF183(Integer f183) { + this.f183 = f183; + } + + public Integer getF184() { + return f184; + } + + public void setF184(Integer f184) { + this.f184 = f184; + } + + public Integer getF185() { + return f185; + } + + public void setF185(Integer f185) { + this.f185 = f185; + } + + public Integer getF186() { + return f186; + } + + public void setF186(Integer f186) { + this.f186 = f186; + } + + public Integer getF187() { + return f187; + } + + public void setF187(Integer f187) { + this.f187 = f187; + } + + public Integer getF188() { + return f188; + } + + public void setF188(Integer f188) { + this.f188 = f188; + } + + public Integer getF189() { + return f189; + } + + public void setF189(Integer f189) { + this.f189 = f189; + } + + public Integer getF190() { + return f190; + } + + public void setF190(Integer f190) { + this.f190 = f190; + } + + public Integer getF191() { + return f191; + } + + public void setF191(Integer f191) { + this.f191 = f191; + } + + public Integer getF192() { + return f192; + } + + public void setF192(Integer f192) { + this.f192 = f192; + } + + public Integer getF193() { + return f193; + } + + public void setF193(Integer f193) { + this.f193 = f193; + } + + public Integer getF194() { + return f194; + } + + public void setF194(Integer f194) { + this.f194 = f194; + } + + public Integer getF195() { + return f195; + } + + public void setF195(Integer f195) { + this.f195 = f195; + } + + public Integer getF196() { + return f196; + } + + public void setF196(Integer f196) { + this.f196 = f196; + } + + public Integer getF197() { + return f197; + } + + public void setF197(Integer f197) { + this.f197 = f197; + } + + public Integer getF198() { + return f198; + } + + public void setF198(Integer f198) { + this.f198 = f198; + } + + public Integer getF199() { + return f199; + } + + public void setF199(Integer f199) { + this.f199 = f199; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/asm/Huge_300_ClassTest.java b/src/test/java/com/alibaba/json/bvt/asm/Huge_300_ClassTest.java new file mode 100755 index 0000000000..e30ec5c042 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/asm/Huge_300_ClassTest.java @@ -0,0 +1,2930 @@ +package com.alibaba.json.bvt.asm; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + +public class Huge_300_ClassTest extends TestCase { + + public void test_huge() { + JSON.parseObject("{}", VO.class); + } + + public static class VO { + + private Integer f000; + private Integer f001; + private Integer f002; + private Integer f003; + private Integer f004; + private Integer f005; + private Integer f006; + private Integer f007; + private Integer f008; + private Integer f009; + + private Integer f010; + private Integer f011; + private Integer f012; + private Integer f013; + private Integer f014; + private Integer f015; + private Integer f016; + private Integer f017; + private Integer f018; + private Integer f019; + + private Integer f020; + private Integer f021; + private Integer f022; + private Integer f023; + private Integer f024; + private Integer f025; + private Integer f026; + private Integer f027; + private Integer f028; + private Integer f029; + + private Integer f030; + private Integer f031; + private Integer f032; + private Integer f033; + private Integer f034; + private Integer f035; + private Integer f036; + private Integer f037; + private Integer f038; + private Integer f039; + + private Integer f040; + private Integer f041; + private Integer f042; + private Integer f043; + private Integer f044; + private Integer f045; + private Integer f046; + private Integer f047; + private Integer f048; + private Integer f049; + + private Integer f050; + private Integer f051; + private Integer f052; + private Integer f053; + private Integer f054; + private Integer f055; + private Integer f056; + private Integer f057; + private Integer f058; + private Integer f059; + + private Integer f060; + private Integer f061; + private Integer f062; + private Integer f063; + private Integer f064; + private Integer f065; + private Integer f066; + private Integer f067; + private Integer f068; + private Integer f069; + + private Integer f070; + private Integer f071; + private Integer f072; + private Integer f073; + private Integer f074; + private Integer f075; + private Integer f076; + private Integer f077; + private Integer f078; + private Integer f079; + + private Integer f080; + private Integer f081; + private Integer f082; + private Integer f083; + private Integer f084; + private Integer f085; + private Integer f086; + private Integer f087; + private Integer f088; + private Integer f089; + + private Integer f090; + private Integer f091; + private Integer f092; + private Integer f093; + private Integer f094; + private Integer f095; + private Integer f096; + private Integer f097; + private Integer f098; + private Integer f099; + + private Integer f100; + private Integer f101; + private Integer f102; + private Integer f103; + private Integer f104; + private Integer f105; + private Integer f106; + private Integer f107; + private Integer f108; + private Integer f109; + private Integer f110; + private Integer f111; + private Integer f112; + private Integer f113; + private Integer f114; + private Integer f115; + private Integer f116; + private Integer f117; + private Integer f118; + private Integer f119; + private Integer f120; + private Integer f121; + private Integer f122; + private Integer f123; + private Integer f124; + private Integer f125; + private Integer f126; + private Integer f127; + private Integer f128; + private Integer f129; + private Integer f130; + private Integer f131; + private Integer f132; + private Integer f133; + private Integer f134; + private Integer f135; + private Integer f136; + private Integer f137; + private Integer f138; + private Integer f139; + private Integer f140; + private Integer f141; + private Integer f142; + private Integer f143; + private Integer f144; + private Integer f145; + private Integer f146; + private Integer f147; + private Integer f148; + private Integer f149; + private Integer f150; + private Integer f151; + private Integer f152; + private Integer f153; + private Integer f154; + private Integer f155; + private Integer f156; + private Integer f157; + private Integer f158; + private Integer f159; + private Integer f160; + private Integer f161; + private Integer f162; + private Integer f163; + private Integer f164; + private Integer f165; + private Integer f166; + private Integer f167; + private Integer f168; + private Integer f169; + private Integer f170; + private Integer f171; + private Integer f172; + private Integer f173; + private Integer f174; + private Integer f175; + private Integer f176; + private Integer f177; + private Integer f178; + private Integer f179; + private Integer f180; + private Integer f181; + private Integer f182; + private Integer f183; + private Integer f184; + private Integer f185; + private Integer f186; + private Integer f187; + private Integer f188; + private Integer f189; + private Integer f190; + private Integer f191; + private Integer f192; + private Integer f193; + private Integer f194; + private Integer f195; + private Integer f196; + private Integer f197; + private Integer f198; + private Integer f199; + + private Integer f200; + private Integer f201; + private Integer f202; + private Integer f203; + private Integer f204; + private Integer f205; + private Integer f206; + private Integer f207; + private Integer f208; + private Integer f209; + private Integer f210; + private Integer f211; + private Integer f212; + private Integer f213; + private Integer f214; + private Integer f215; + private Integer f216; + private Integer f217; + private Integer f218; + private Integer f219; + private Integer f220; + private Integer f221; + private Integer f222; + private Integer f223; + private Integer f224; + private Integer f225; + private Integer f226; + private Integer f227; + private Integer f228; + private Integer f229; + private Integer f230; + private Integer f231; + private Integer f232; + private Integer f233; + private Integer f234; + private Integer f235; + private Integer f236; + private Integer f237; + private Integer f238; + private Integer f239; + private Integer f240; + private Integer f241; + private Integer f242; + private Integer f243; + private Integer f244; + private Integer f245; + private Integer f246; + private Integer f247; + private Integer f248; + private Integer f249; + private Integer f250; + private Integer f251; + private Integer f252; + private Integer f253; + private Integer f254; + private Integer f255; + private Integer f256; + private Integer f257; + private Integer f258; + private Integer f259; + private Integer f260; + private Integer f261; + private Integer f262; + private Integer f263; + private Integer f264; + private Integer f265; + private Integer f266; + private Integer f267; + private Integer f268; + private Integer f269; + private Integer f270; + private Integer f271; + private Integer f272; + private Integer f273; + private Integer f274; + private Integer f275; + private Integer f276; + private Integer f277; + private Integer f278; + private Integer f279; + private Integer f280; + private Integer f281; + private Integer f282; + private Integer f283; + private Integer f284; + private Integer f285; + private Integer f286; + private Integer f287; + private Integer f288; + private Integer f289; + private Integer f290; + private Integer f291; + private Integer f292; + private Integer f293; + private Integer f294; + private Integer f295; + private Integer f296; + private Integer f297; + private Integer f298; + private Integer f299; + + public Integer getF000() { + return f000; + } + + public void setF000(Integer f000) { + this.f000 = f000; + } + + public Integer getF001() { + return f001; + } + + public void setF001(Integer f001) { + this.f001 = f001; + } + + public Integer getF002() { + return f002; + } + + public void setF002(Integer f002) { + this.f002 = f002; + } + + public Integer getF003() { + return f003; + } + + public void setF003(Integer f003) { + this.f003 = f003; + } + + public Integer getF004() { + return f004; + } + + public void setF004(Integer f004) { + this.f004 = f004; + } + + public Integer getF005() { + return f005; + } + + public void setF005(Integer f005) { + this.f005 = f005; + } + + public Integer getF006() { + return f006; + } + + public void setF006(Integer f006) { + this.f006 = f006; + } + + public Integer getF007() { + return f007; + } + + public void setF007(Integer f007) { + this.f007 = f007; + } + + public Integer getF008() { + return f008; + } + + public void setF008(Integer f008) { + this.f008 = f008; + } + + public Integer getF009() { + return f009; + } + + public void setF009(Integer f009) { + this.f009 = f009; + } + + public Integer getF010() { + return f010; + } + + public void setF010(Integer f010) { + this.f010 = f010; + } + + public Integer getF011() { + return f011; + } + + public void setF011(Integer f011) { + this.f011 = f011; + } + + public Integer getF012() { + return f012; + } + + public void setF012(Integer f012) { + this.f012 = f012; + } + + public Integer getF013() { + return f013; + } + + public void setF013(Integer f013) { + this.f013 = f013; + } + + public Integer getF014() { + return f014; + } + + public void setF014(Integer f014) { + this.f014 = f014; + } + + public Integer getF015() { + return f015; + } + + public void setF015(Integer f015) { + this.f015 = f015; + } + + public Integer getF016() { + return f016; + } + + public void setF016(Integer f016) { + this.f016 = f016; + } + + public Integer getF017() { + return f017; + } + + public void setF017(Integer f017) { + this.f017 = f017; + } + + public Integer getF018() { + return f018; + } + + public void setF018(Integer f018) { + this.f018 = f018; + } + + public Integer getF019() { + return f019; + } + + public void setF019(Integer f019) { + this.f019 = f019; + } + + public Integer getF020() { + return f020; + } + + public void setF020(Integer f020) { + this.f020 = f020; + } + + public Integer getF021() { + return f021; + } + + public void setF021(Integer f021) { + this.f021 = f021; + } + + public Integer getF022() { + return f022; + } + + public void setF022(Integer f022) { + this.f022 = f022; + } + + public Integer getF023() { + return f023; + } + + public void setF023(Integer f023) { + this.f023 = f023; + } + + public Integer getF024() { + return f024; + } + + public void setF024(Integer f024) { + this.f024 = f024; + } + + public Integer getF025() { + return f025; + } + + public void setF025(Integer f025) { + this.f025 = f025; + } + + public Integer getF026() { + return f026; + } + + public void setF026(Integer f026) { + this.f026 = f026; + } + + public Integer getF027() { + return f027; + } + + public void setF027(Integer f027) { + this.f027 = f027; + } + + public Integer getF028() { + return f028; + } + + public void setF028(Integer f028) { + this.f028 = f028; + } + + public Integer getF029() { + return f029; + } + + public void setF029(Integer f029) { + this.f029 = f029; + } + + public Integer getF030() { + return f030; + } + + public void setF030(Integer f030) { + this.f030 = f030; + } + + public Integer getF031() { + return f031; + } + + public void setF031(Integer f031) { + this.f031 = f031; + } + + public Integer getF032() { + return f032; + } + + public void setF032(Integer f032) { + this.f032 = f032; + } + + public Integer getF033() { + return f033; + } + + public void setF033(Integer f033) { + this.f033 = f033; + } + + public Integer getF034() { + return f034; + } + + public void setF034(Integer f034) { + this.f034 = f034; + } + + public Integer getF035() { + return f035; + } + + public void setF035(Integer f035) { + this.f035 = f035; + } + + public Integer getF036() { + return f036; + } + + public void setF036(Integer f036) { + this.f036 = f036; + } + + public Integer getF037() { + return f037; + } + + public void setF037(Integer f037) { + this.f037 = f037; + } + + public Integer getF038() { + return f038; + } + + public void setF038(Integer f038) { + this.f038 = f038; + } + + public Integer getF039() { + return f039; + } + + public void setF039(Integer f039) { + this.f039 = f039; + } + + public Integer getF040() { + return f040; + } + + public void setF040(Integer f040) { + this.f040 = f040; + } + + public Integer getF041() { + return f041; + } + + public void setF041(Integer f041) { + this.f041 = f041; + } + + public Integer getF042() { + return f042; + } + + public void setF042(Integer f042) { + this.f042 = f042; + } + + public Integer getF043() { + return f043; + } + + public void setF043(Integer f043) { + this.f043 = f043; + } + + public Integer getF044() { + return f044; + } + + public void setF044(Integer f044) { + this.f044 = f044; + } + + public Integer getF045() { + return f045; + } + + public void setF045(Integer f045) { + this.f045 = f045; + } + + public Integer getF046() { + return f046; + } + + public void setF046(Integer f046) { + this.f046 = f046; + } + + public Integer getF047() { + return f047; + } + + public void setF047(Integer f047) { + this.f047 = f047; + } + + public Integer getF048() { + return f048; + } + + public void setF048(Integer f048) { + this.f048 = f048; + } + + public Integer getF049() { + return f049; + } + + public void setF049(Integer f049) { + this.f049 = f049; + } + + public Integer getF050() { + return f050; + } + + public void setF050(Integer f050) { + this.f050 = f050; + } + + public Integer getF051() { + return f051; + } + + public void setF051(Integer f051) { + this.f051 = f051; + } + + public Integer getF052() { + return f052; + } + + public void setF052(Integer f052) { + this.f052 = f052; + } + + public Integer getF053() { + return f053; + } + + public void setF053(Integer f053) { + this.f053 = f053; + } + + public Integer getF054() { + return f054; + } + + public void setF054(Integer f054) { + this.f054 = f054; + } + + public Integer getF055() { + return f055; + } + + public void setF055(Integer f055) { + this.f055 = f055; + } + + public Integer getF056() { + return f056; + } + + public void setF056(Integer f056) { + this.f056 = f056; + } + + public Integer getF057() { + return f057; + } + + public void setF057(Integer f057) { + this.f057 = f057; + } + + public Integer getF058() { + return f058; + } + + public void setF058(Integer f058) { + this.f058 = f058; + } + + public Integer getF059() { + return f059; + } + + public void setF059(Integer f059) { + this.f059 = f059; + } + + public Integer getF060() { + return f060; + } + + public void setF060(Integer f060) { + this.f060 = f060; + } + + public Integer getF061() { + return f061; + } + + public void setF061(Integer f061) { + this.f061 = f061; + } + + public Integer getF062() { + return f062; + } + + public void setF062(Integer f062) { + this.f062 = f062; + } + + public Integer getF063() { + return f063; + } + + public void setF063(Integer f063) { + this.f063 = f063; + } + + public Integer getF064() { + return f064; + } + + public void setF064(Integer f064) { + this.f064 = f064; + } + + public Integer getF065() { + return f065; + } + + public void setF065(Integer f065) { + this.f065 = f065; + } + + public Integer getF066() { + return f066; + } + + public void setF066(Integer f066) { + this.f066 = f066; + } + + public Integer getF067() { + return f067; + } + + public void setF067(Integer f067) { + this.f067 = f067; + } + + public Integer getF068() { + return f068; + } + + public void setF068(Integer f068) { + this.f068 = f068; + } + + public Integer getF069() { + return f069; + } + + public void setF069(Integer f069) { + this.f069 = f069; + } + + public Integer getF070() { + return f070; + } + + public void setF070(Integer f070) { + this.f070 = f070; + } + + public Integer getF071() { + return f071; + } + + public void setF071(Integer f071) { + this.f071 = f071; + } + + public Integer getF072() { + return f072; + } + + public void setF072(Integer f072) { + this.f072 = f072; + } + + public Integer getF073() { + return f073; + } + + public void setF073(Integer f073) { + this.f073 = f073; + } + + public Integer getF074() { + return f074; + } + + public void setF074(Integer f074) { + this.f074 = f074; + } + + public Integer getF075() { + return f075; + } + + public void setF075(Integer f075) { + this.f075 = f075; + } + + public Integer getF076() { + return f076; + } + + public void setF076(Integer f076) { + this.f076 = f076; + } + + public Integer getF077() { + return f077; + } + + public void setF077(Integer f077) { + this.f077 = f077; + } + + public Integer getF078() { + return f078; + } + + public void setF078(Integer f078) { + this.f078 = f078; + } + + public Integer getF079() { + return f079; + } + + public void setF079(Integer f079) { + this.f079 = f079; + } + + public Integer getF080() { + return f080; + } + + public void setF080(Integer f080) { + this.f080 = f080; + } + + public Integer getF081() { + return f081; + } + + public void setF081(Integer f081) { + this.f081 = f081; + } + + public Integer getF082() { + return f082; + } + + public void setF082(Integer f082) { + this.f082 = f082; + } + + public Integer getF083() { + return f083; + } + + public void setF083(Integer f083) { + this.f083 = f083; + } + + public Integer getF084() { + return f084; + } + + public void setF084(Integer f084) { + this.f084 = f084; + } + + public Integer getF085() { + return f085; + } + + public void setF085(Integer f085) { + this.f085 = f085; + } + + public Integer getF086() { + return f086; + } + + public void setF086(Integer f086) { + this.f086 = f086; + } + + public Integer getF087() { + return f087; + } + + public void setF087(Integer f087) { + this.f087 = f087; + } + + public Integer getF088() { + return f088; + } + + public void setF088(Integer f088) { + this.f088 = f088; + } + + public Integer getF089() { + return f089; + } + + public void setF089(Integer f089) { + this.f089 = f089; + } + + public Integer getF090() { + return f090; + } + + public void setF090(Integer f090) { + this.f090 = f090; + } + + public Integer getF091() { + return f091; + } + + public void setF091(Integer f091) { + this.f091 = f091; + } + + public Integer getF092() { + return f092; + } + + public void setF092(Integer f092) { + this.f092 = f092; + } + + public Integer getF093() { + return f093; + } + + public void setF093(Integer f093) { + this.f093 = f093; + } + + public Integer getF094() { + return f094; + } + + public void setF094(Integer f094) { + this.f094 = f094; + } + + public Integer getF095() { + return f095; + } + + public void setF095(Integer f095) { + this.f095 = f095; + } + + public Integer getF096() { + return f096; + } + + public void setF096(Integer f096) { + this.f096 = f096; + } + + public Integer getF097() { + return f097; + } + + public void setF097(Integer f097) { + this.f097 = f097; + } + + public Integer getF098() { + return f098; + } + + public void setF098(Integer f098) { + this.f098 = f098; + } + + public Integer getF099() { + return f099; + } + + public void setF099(Integer f099) { + this.f099 = f099; + } + + public Integer getF100() { + return f100; + } + + public void setF100(Integer f100) { + this.f100 = f100; + } + + public Integer getF101() { + return f101; + } + + public void setF101(Integer f101) { + this.f101 = f101; + } + + public Integer getF102() { + return f102; + } + + public void setF102(Integer f102) { + this.f102 = f102; + } + + public Integer getF103() { + return f103; + } + + public void setF103(Integer f103) { + this.f103 = f103; + } + + public Integer getF104() { + return f104; + } + + public void setF104(Integer f104) { + this.f104 = f104; + } + + public Integer getF105() { + return f105; + } + + public void setF105(Integer f105) { + this.f105 = f105; + } + + public Integer getF106() { + return f106; + } + + public void setF106(Integer f106) { + this.f106 = f106; + } + + public Integer getF107() { + return f107; + } + + public void setF107(Integer f107) { + this.f107 = f107; + } + + public Integer getF108() { + return f108; + } + + public void setF108(Integer f108) { + this.f108 = f108; + } + + public Integer getF109() { + return f109; + } + + public void setF109(Integer f109) { + this.f109 = f109; + } + + public Integer getF110() { + return f110; + } + + public void setF110(Integer f110) { + this.f110 = f110; + } + + public Integer getF111() { + return f111; + } + + public void setF111(Integer f111) { + this.f111 = f111; + } + + public Integer getF112() { + return f112; + } + + public void setF112(Integer f112) { + this.f112 = f112; + } + + public Integer getF113() { + return f113; + } + + public void setF113(Integer f113) { + this.f113 = f113; + } + + public Integer getF114() { + return f114; + } + + public void setF114(Integer f114) { + this.f114 = f114; + } + + public Integer getF115() { + return f115; + } + + public void setF115(Integer f115) { + this.f115 = f115; + } + + public Integer getF116() { + return f116; + } + + public void setF116(Integer f116) { + this.f116 = f116; + } + + public Integer getF117() { + return f117; + } + + public void setF117(Integer f117) { + this.f117 = f117; + } + + public Integer getF118() { + return f118; + } + + public void setF118(Integer f118) { + this.f118 = f118; + } + + public Integer getF119() { + return f119; + } + + public void setF119(Integer f119) { + this.f119 = f119; + } + + public Integer getF120() { + return f120; + } + + public void setF120(Integer f120) { + this.f120 = f120; + } + + public Integer getF121() { + return f121; + } + + public void setF121(Integer f121) { + this.f121 = f121; + } + + public Integer getF122() { + return f122; + } + + public void setF122(Integer f122) { + this.f122 = f122; + } + + public Integer getF123() { + return f123; + } + + public void setF123(Integer f123) { + this.f123 = f123; + } + + public Integer getF124() { + return f124; + } + + public void setF124(Integer f124) { + this.f124 = f124; + } + + public Integer getF125() { + return f125; + } + + public void setF125(Integer f125) { + this.f125 = f125; + } + + public Integer getF126() { + return f126; + } + + public void setF126(Integer f126) { + this.f126 = f126; + } + + public Integer getF127() { + return f127; + } + + public void setF127(Integer f127) { + this.f127 = f127; + } + + public Integer getF128() { + return f128; + } + + public void setF128(Integer f128) { + this.f128 = f128; + } + + public Integer getF129() { + return f129; + } + + public void setF129(Integer f129) { + this.f129 = f129; + } + + public Integer getF130() { + return f130; + } + + public void setF130(Integer f130) { + this.f130 = f130; + } + + public Integer getF131() { + return f131; + } + + public void setF131(Integer f131) { + this.f131 = f131; + } + + public Integer getF132() { + return f132; + } + + public void setF132(Integer f132) { + this.f132 = f132; + } + + public Integer getF133() { + return f133; + } + + public void setF133(Integer f133) { + this.f133 = f133; + } + + public Integer getF134() { + return f134; + } + + public void setF134(Integer f134) { + this.f134 = f134; + } + + public Integer getF135() { + return f135; + } + + public void setF135(Integer f135) { + this.f135 = f135; + } + + public Integer getF136() { + return f136; + } + + public void setF136(Integer f136) { + this.f136 = f136; + } + + public Integer getF137() { + return f137; + } + + public void setF137(Integer f137) { + this.f137 = f137; + } + + public Integer getF138() { + return f138; + } + + public void setF138(Integer f138) { + this.f138 = f138; + } + + public Integer getF139() { + return f139; + } + + public void setF139(Integer f139) { + this.f139 = f139; + } + + public Integer getF140() { + return f140; + } + + public void setF140(Integer f140) { + this.f140 = f140; + } + + public Integer getF141() { + return f141; + } + + public void setF141(Integer f141) { + this.f141 = f141; + } + + public Integer getF142() { + return f142; + } + + public void setF142(Integer f142) { + this.f142 = f142; + } + + public Integer getF143() { + return f143; + } + + public void setF143(Integer f143) { + this.f143 = f143; + } + + public Integer getF144() { + return f144; + } + + public void setF144(Integer f144) { + this.f144 = f144; + } + + public Integer getF145() { + return f145; + } + + public void setF145(Integer f145) { + this.f145 = f145; + } + + public Integer getF146() { + return f146; + } + + public void setF146(Integer f146) { + this.f146 = f146; + } + + public Integer getF147() { + return f147; + } + + public void setF147(Integer f147) { + this.f147 = f147; + } + + public Integer getF148() { + return f148; + } + + public void setF148(Integer f148) { + this.f148 = f148; + } + + public Integer getF149() { + return f149; + } + + public void setF149(Integer f149) { + this.f149 = f149; + } + + public Integer getF150() { + return f150; + } + + public void setF150(Integer f150) { + this.f150 = f150; + } + + public Integer getF151() { + return f151; + } + + public void setF151(Integer f151) { + this.f151 = f151; + } + + public Integer getF152() { + return f152; + } + + public void setF152(Integer f152) { + this.f152 = f152; + } + + public Integer getF153() { + return f153; + } + + public void setF153(Integer f153) { + this.f153 = f153; + } + + public Integer getF154() { + return f154; + } + + public void setF154(Integer f154) { + this.f154 = f154; + } + + public Integer getF155() { + return f155; + } + + public void setF155(Integer f155) { + this.f155 = f155; + } + + public Integer getF156() { + return f156; + } + + public void setF156(Integer f156) { + this.f156 = f156; + } + + public Integer getF157() { + return f157; + } + + public void setF157(Integer f157) { + this.f157 = f157; + } + + public Integer getF158() { + return f158; + } + + public void setF158(Integer f158) { + this.f158 = f158; + } + + public Integer getF159() { + return f159; + } + + public void setF159(Integer f159) { + this.f159 = f159; + } + + public Integer getF160() { + return f160; + } + + public void setF160(Integer f160) { + this.f160 = f160; + } + + public Integer getF161() { + return f161; + } + + public void setF161(Integer f161) { + this.f161 = f161; + } + + public Integer getF162() { + return f162; + } + + public void setF162(Integer f162) { + this.f162 = f162; + } + + public Integer getF163() { + return f163; + } + + public void setF163(Integer f163) { + this.f163 = f163; + } + + public Integer getF164() { + return f164; + } + + public void setF164(Integer f164) { + this.f164 = f164; + } + + public Integer getF165() { + return f165; + } + + public void setF165(Integer f165) { + this.f165 = f165; + } + + public Integer getF166() { + return f166; + } + + public void setF166(Integer f166) { + this.f166 = f166; + } + + public Integer getF167() { + return f167; + } + + public void setF167(Integer f167) { + this.f167 = f167; + } + + public Integer getF168() { + return f168; + } + + public void setF168(Integer f168) { + this.f168 = f168; + } + + public Integer getF169() { + return f169; + } + + public void setF169(Integer f169) { + this.f169 = f169; + } + + public Integer getF170() { + return f170; + } + + public void setF170(Integer f170) { + this.f170 = f170; + } + + public Integer getF171() { + return f171; + } + + public void setF171(Integer f171) { + this.f171 = f171; + } + + public Integer getF172() { + return f172; + } + + public void setF172(Integer f172) { + this.f172 = f172; + } + + public Integer getF173() { + return f173; + } + + public void setF173(Integer f173) { + this.f173 = f173; + } + + public Integer getF174() { + return f174; + } + + public void setF174(Integer f174) { + this.f174 = f174; + } + + public Integer getF175() { + return f175; + } + + public void setF175(Integer f175) { + this.f175 = f175; + } + + public Integer getF176() { + return f176; + } + + public void setF176(Integer f176) { + this.f176 = f176; + } + + public Integer getF177() { + return f177; + } + + public void setF177(Integer f177) { + this.f177 = f177; + } + + public Integer getF178() { + return f178; + } + + public void setF178(Integer f178) { + this.f178 = f178; + } + + public Integer getF179() { + return f179; + } + + public void setF179(Integer f179) { + this.f179 = f179; + } + + public Integer getF180() { + return f180; + } + + public void setF180(Integer f180) { + this.f180 = f180; + } + + public Integer getF181() { + return f181; + } + + public void setF181(Integer f181) { + this.f181 = f181; + } + + public Integer getF182() { + return f182; + } + + public void setF182(Integer f182) { + this.f182 = f182; + } + + public Integer getF183() { + return f183; + } + + public void setF183(Integer f183) { + this.f183 = f183; + } + + public Integer getF184() { + return f184; + } + + public void setF184(Integer f184) { + this.f184 = f184; + } + + public Integer getF185() { + return f185; + } + + public void setF185(Integer f185) { + this.f185 = f185; + } + + public Integer getF186() { + return f186; + } + + public void setF186(Integer f186) { + this.f186 = f186; + } + + public Integer getF187() { + return f187; + } + + public void setF187(Integer f187) { + this.f187 = f187; + } + + public Integer getF188() { + return f188; + } + + public void setF188(Integer f188) { + this.f188 = f188; + } + + public Integer getF189() { + return f189; + } + + public void setF189(Integer f189) { + this.f189 = f189; + } + + public Integer getF190() { + return f190; + } + + public void setF190(Integer f190) { + this.f190 = f190; + } + + public Integer getF191() { + return f191; + } + + public void setF191(Integer f191) { + this.f191 = f191; + } + + public Integer getF192() { + return f192; + } + + public void setF192(Integer f192) { + this.f192 = f192; + } + + public Integer getF193() { + return f193; + } + + public void setF193(Integer f193) { + this.f193 = f193; + } + + public Integer getF194() { + return f194; + } + + public void setF194(Integer f194) { + this.f194 = f194; + } + + public Integer getF195() { + return f195; + } + + public void setF195(Integer f195) { + this.f195 = f195; + } + + public Integer getF196() { + return f196; + } + + public void setF196(Integer f196) { + this.f196 = f196; + } + + public Integer getF197() { + return f197; + } + + public void setF197(Integer f197) { + this.f197 = f197; + } + + public Integer getF198() { + return f198; + } + + public void setF198(Integer f198) { + this.f198 = f198; + } + + public Integer getF199() { + return f199; + } + + public void setF199(Integer f199) { + this.f199 = f199; + } + + + public Integer getF200() { + return f200; + } + + + public void setF200(Integer f200) { + this.f200 = f200; + } + + + public Integer getF201() { + return f201; + } + + + public void setF201(Integer f201) { + this.f201 = f201; + } + + + public Integer getF202() { + return f202; + } + + + public void setF202(Integer f202) { + this.f202 = f202; + } + + + public Integer getF203() { + return f203; + } + + + public void setF203(Integer f203) { + this.f203 = f203; + } + + + public Integer getF204() { + return f204; + } + + + public void setF204(Integer f204) { + this.f204 = f204; + } + + + public Integer getF205() { + return f205; + } + + + public void setF205(Integer f205) { + this.f205 = f205; + } + + + public Integer getF206() { + return f206; + } + + + public void setF206(Integer f206) { + this.f206 = f206; + } + + + public Integer getF207() { + return f207; + } + + + public void setF207(Integer f207) { + this.f207 = f207; + } + + + public Integer getF208() { + return f208; + } + + + public void setF208(Integer f208) { + this.f208 = f208; + } + + + public Integer getF209() { + return f209; + } + + + public void setF209(Integer f209) { + this.f209 = f209; + } + + + public Integer getF210() { + return f210; + } + + + public void setF210(Integer f210) { + this.f210 = f210; + } + + + public Integer getF211() { + return f211; + } + + + public void setF211(Integer f211) { + this.f211 = f211; + } + + + public Integer getF212() { + return f212; + } + + + public void setF212(Integer f212) { + this.f212 = f212; + } + + + public Integer getF213() { + return f213; + } + + + public void setF213(Integer f213) { + this.f213 = f213; + } + + + public Integer getF214() { + return f214; + } + + + public void setF214(Integer f214) { + this.f214 = f214; + } + + + public Integer getF215() { + return f215; + } + + + public void setF215(Integer f215) { + this.f215 = f215; + } + + + public Integer getF216() { + return f216; + } + + + public void setF216(Integer f216) { + this.f216 = f216; + } + + + public Integer getF217() { + return f217; + } + + + public void setF217(Integer f217) { + this.f217 = f217; + } + + + public Integer getF218() { + return f218; + } + + + public void setF218(Integer f218) { + this.f218 = f218; + } + + + public Integer getF219() { + return f219; + } + + + public void setF219(Integer f219) { + this.f219 = f219; + } + + + public Integer getF220() { + return f220; + } + + + public void setF220(Integer f220) { + this.f220 = f220; + } + + + public Integer getF221() { + return f221; + } + + + public void setF221(Integer f221) { + this.f221 = f221; + } + + + public Integer getF222() { + return f222; + } + + + public void setF222(Integer f222) { + this.f222 = f222; + } + + + public Integer getF223() { + return f223; + } + + + public void setF223(Integer f223) { + this.f223 = f223; + } + + + public Integer getF224() { + return f224; + } + + + public void setF224(Integer f224) { + this.f224 = f224; + } + + + public Integer getF225() { + return f225; + } + + + public void setF225(Integer f225) { + this.f225 = f225; + } + + + public Integer getF226() { + return f226; + } + + + public void setF226(Integer f226) { + this.f226 = f226; + } + + + public Integer getF227() { + return f227; + } + + + public void setF227(Integer f227) { + this.f227 = f227; + } + + + public Integer getF228() { + return f228; + } + + + public void setF228(Integer f228) { + this.f228 = f228; + } + + + public Integer getF229() { + return f229; + } + + + public void setF229(Integer f229) { + this.f229 = f229; + } + + + public Integer getF230() { + return f230; + } + + + public void setF230(Integer f230) { + this.f230 = f230; + } + + + public Integer getF231() { + return f231; + } + + + public void setF231(Integer f231) { + this.f231 = f231; + } + + + public Integer getF232() { + return f232; + } + + + public void setF232(Integer f232) { + this.f232 = f232; + } + + + public Integer getF233() { + return f233; + } + + + public void setF233(Integer f233) { + this.f233 = f233; + } + + + public Integer getF234() { + return f234; + } + + + public void setF234(Integer f234) { + this.f234 = f234; + } + + + public Integer getF235() { + return f235; + } + + + public void setF235(Integer f235) { + this.f235 = f235; + } + + + public Integer getF236() { + return f236; + } + + + public void setF236(Integer f236) { + this.f236 = f236; + } + + + public Integer getF237() { + return f237; + } + + + public void setF237(Integer f237) { + this.f237 = f237; + } + + + public Integer getF238() { + return f238; + } + + + public void setF238(Integer f238) { + this.f238 = f238; + } + + + public Integer getF239() { + return f239; + } + + + public void setF239(Integer f239) { + this.f239 = f239; + } + + + public Integer getF240() { + return f240; + } + + + public void setF240(Integer f240) { + this.f240 = f240; + } + + + public Integer getF241() { + return f241; + } + + + public void setF241(Integer f241) { + this.f241 = f241; + } + + + public Integer getF242() { + return f242; + } + + + public void setF242(Integer f242) { + this.f242 = f242; + } + + + public Integer getF243() { + return f243; + } + + + public void setF243(Integer f243) { + this.f243 = f243; + } + + + public Integer getF244() { + return f244; + } + + + public void setF244(Integer f244) { + this.f244 = f244; + } + + + public Integer getF245() { + return f245; + } + + + public void setF245(Integer f245) { + this.f245 = f245; + } + + + public Integer getF246() { + return f246; + } + + + public void setF246(Integer f246) { + this.f246 = f246; + } + + + public Integer getF247() { + return f247; + } + + + public void setF247(Integer f247) { + this.f247 = f247; + } + + + public Integer getF248() { + return f248; + } + + + public void setF248(Integer f248) { + this.f248 = f248; + } + + + public Integer getF249() { + return f249; + } + + + public void setF249(Integer f249) { + this.f249 = f249; + } + + + public Integer getF250() { + return f250; + } + + + public void setF250(Integer f250) { + this.f250 = f250; + } + + + public Integer getF251() { + return f251; + } + + + public void setF251(Integer f251) { + this.f251 = f251; + } + + + public Integer getF252() { + return f252; + } + + + public void setF252(Integer f252) { + this.f252 = f252; + } + + + public Integer getF253() { + return f253; + } + + + public void setF253(Integer f253) { + this.f253 = f253; + } + + + public Integer getF254() { + return f254; + } + + + public void setF254(Integer f254) { + this.f254 = f254; + } + + + public Integer getF255() { + return f255; + } + + + public void setF255(Integer f255) { + this.f255 = f255; + } + + + public Integer getF256() { + return f256; + } + + + public void setF256(Integer f256) { + this.f256 = f256; + } + + + public Integer getF257() { + return f257; + } + + + public void setF257(Integer f257) { + this.f257 = f257; + } + + + public Integer getF258() { + return f258; + } + + + public void setF258(Integer f258) { + this.f258 = f258; + } + + + public Integer getF259() { + return f259; + } + + + public void setF259(Integer f259) { + this.f259 = f259; + } + + + public Integer getF260() { + return f260; + } + + + public void setF260(Integer f260) { + this.f260 = f260; + } + + + public Integer getF261() { + return f261; + } + + + public void setF261(Integer f261) { + this.f261 = f261; + } + + + public Integer getF262() { + return f262; + } + + + public void setF262(Integer f262) { + this.f262 = f262; + } + + + public Integer getF263() { + return f263; + } + + + public void setF263(Integer f263) { + this.f263 = f263; + } + + + public Integer getF264() { + return f264; + } + + + public void setF264(Integer f264) { + this.f264 = f264; + } + + + public Integer getF265() { + return f265; + } + + + public void setF265(Integer f265) { + this.f265 = f265; + } + + + public Integer getF266() { + return f266; + } + + + public void setF266(Integer f266) { + this.f266 = f266; + } + + + public Integer getF267() { + return f267; + } + + + public void setF267(Integer f267) { + this.f267 = f267; + } + + + public Integer getF268() { + return f268; + } + + + public void setF268(Integer f268) { + this.f268 = f268; + } + + + public Integer getF269() { + return f269; + } + + + public void setF269(Integer f269) { + this.f269 = f269; + } + + + public Integer getF270() { + return f270; + } + + + public void setF270(Integer f270) { + this.f270 = f270; + } + + + public Integer getF271() { + return f271; + } + + + public void setF271(Integer f271) { + this.f271 = f271; + } + + + public Integer getF272() { + return f272; + } + + + public void setF272(Integer f272) { + this.f272 = f272; + } + + + public Integer getF273() { + return f273; + } + + + public void setF273(Integer f273) { + this.f273 = f273; + } + + + public Integer getF274() { + return f274; + } + + + public void setF274(Integer f274) { + this.f274 = f274; + } + + + public Integer getF275() { + return f275; + } + + + public void setF275(Integer f275) { + this.f275 = f275; + } + + + public Integer getF276() { + return f276; + } + + + public void setF276(Integer f276) { + this.f276 = f276; + } + + + public Integer getF277() { + return f277; + } + + + public void setF277(Integer f277) { + this.f277 = f277; + } + + + public Integer getF278() { + return f278; + } + + + public void setF278(Integer f278) { + this.f278 = f278; + } + + + public Integer getF279() { + return f279; + } + + + public void setF279(Integer f279) { + this.f279 = f279; + } + + + public Integer getF280() { + return f280; + } + + + public void setF280(Integer f280) { + this.f280 = f280; + } + + + public Integer getF281() { + return f281; + } + + + public void setF281(Integer f281) { + this.f281 = f281; + } + + + public Integer getF282() { + return f282; + } + + + public void setF282(Integer f282) { + this.f282 = f282; + } + + + public Integer getF283() { + return f283; + } + + + public void setF283(Integer f283) { + this.f283 = f283; + } + + + public Integer getF284() { + return f284; + } + + + public void setF284(Integer f284) { + this.f284 = f284; + } + + + public Integer getF285() { + return f285; + } + + + public void setF285(Integer f285) { + this.f285 = f285; + } + + + public Integer getF286() { + return f286; + } + + + public void setF286(Integer f286) { + this.f286 = f286; + } + + + public Integer getF287() { + return f287; + } + + + public void setF287(Integer f287) { + this.f287 = f287; + } + + + public Integer getF288() { + return f288; + } + + + public void setF288(Integer f288) { + this.f288 = f288; + } + + + public Integer getF289() { + return f289; + } + + + public void setF289(Integer f289) { + this.f289 = f289; + } + + + public Integer getF290() { + return f290; + } + + + public void setF290(Integer f290) { + this.f290 = f290; + } + + + public Integer getF291() { + return f291; + } + + + public void setF291(Integer f291) { + this.f291 = f291; + } + + + public Integer getF292() { + return f292; + } + + + public void setF292(Integer f292) { + this.f292 = f292; + } + + + public Integer getF293() { + return f293; + } + + + public void setF293(Integer f293) { + this.f293 = f293; + } + + + public Integer getF294() { + return f294; + } + + + public void setF294(Integer f294) { + this.f294 = f294; + } + + + public Integer getF295() { + return f295; + } + + + public void setF295(Integer f295) { + this.f295 = f295; + } + + + public Integer getF296() { + return f296; + } + + + public void setF296(Integer f296) { + this.f296 = f296; + } + + + public Integer getF297() { + return f297; + } + + + public void setF297(Integer f297) { + this.f297 = f297; + } + + + public Integer getF298() { + return f298; + } + + + public void setF298(Integer f298) { + this.f298 = f298; + } + + + public Integer getF299() { + return f299; + } + + + public void setF299(Integer f299) { + this.f299 = f299; + } + + + } + +} diff --git a/src/test/java/com/alibaba/json/test/bvt/asm/JSONASMUtilTest.java b/src/test/java/com/alibaba/json/bvt/asm/JSONASMUtilTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/asm/JSONASMUtilTest.java rename to src/test/java/com/alibaba/json/bvt/asm/JSONASMUtilTest.java index da0a9695ec..145d3d89cd --- a/src/test/java/com/alibaba/json/test/bvt/asm/JSONASMUtilTest.java +++ b/src/test/java/com/alibaba/json/bvt/asm/JSONASMUtilTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.asm; +package com.alibaba.json.bvt.asm; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.util.ASMUtils; diff --git a/src/test/java/com/alibaba/json/test/bvt/asm/LoopTest.java b/src/test/java/com/alibaba/json/bvt/asm/LoopTest.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/asm/LoopTest.java rename to src/test/java/com/alibaba/json/bvt/asm/LoopTest.java index 286534d86c..7f8f4cad45 --- a/src/test/java/com/alibaba/json/test/bvt/asm/LoopTest.java +++ b/src/test/java/com/alibaba/json/bvt/asm/LoopTest.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.asm; +package com.alibaba.json.bvt.asm; import java.util.ArrayList; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/asm/SortFieldTest.java b/src/test/java/com/alibaba/json/bvt/asm/SortFieldTest.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/asm/SortFieldTest.java rename to src/test/java/com/alibaba/json/bvt/asm/SortFieldTest.java index e2ad9086a9..afed089283 --- a/src/test/java/com/alibaba/json/test/bvt/asm/SortFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/asm/SortFieldTest.java @@ -1,8 +1,10 @@ -package com.alibaba.json.test.bvt.asm; +package com.alibaba.json.bvt.asm; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; +import java.util.LinkedHashMap; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; @@ -16,7 +18,7 @@ public void test_0() throws Exception { Assert.assertEquals("{'f0':0,'f1':0,'f10':0,'f11':0,'f12':0,'f13':0,'f14':0,'f2':0,'f3':0,'f4':0,'f5':0,'f6':0,'f7':0,'f8':0,'f9':0}", text); - JSONObject object = JSON.parseObject(text); + LinkedHashMap object = JSON.parseObject(text, LinkedHashMap.class); text = JSON.toJSONString(object, SerializerFeature.UseSingleQuotes, SerializerFeature.SortField); Assert.assertEquals("{'f0':0,'f1':0,'f10':0,'f11':0,'f12':0,'f13':0,'f14':0,'f2':0,'f3':0,'f4':0,'f5':0,'f6':0,'f7':0,'f8':0,'f9':0}", text); diff --git a/src/test/java/com/alibaba/json/test/bvt/asm/TestList.java b/src/test/java/com/alibaba/json/bvt/asm/TestList.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/asm/TestList.java rename to src/test/java/com/alibaba/json/bvt/asm/TestList.java index 29fd5d3c06..3bb094b136 --- a/src/test/java/com/alibaba/json/test/bvt/asm/TestList.java +++ b/src/test/java/com/alibaba/json/bvt/asm/TestList.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.asm; +package com.alibaba.json.bvt.asm; import java.util.ArrayList; import java.util.Arrays; @@ -6,7 +6,7 @@ import java.util.List; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/asm/TestNonASM.java b/src/test/java/com/alibaba/json/bvt/asm/TestNonASM.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/asm/TestNonASM.java rename to src/test/java/com/alibaba/json/bvt/asm/TestNonASM.java index bc09823979..395f1ca595 --- a/src/test/java/com/alibaba/json/test/bvt/asm/TestNonASM.java +++ b/src/test/java/com/alibaba/json/bvt/asm/TestNonASM.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.asm; +package com.alibaba.json.bvt.asm; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.parser.ParserConfig; diff --git a/src/test/java/com/alibaba/json/test/bvt/asm/TestType.java b/src/test/java/com/alibaba/json/bvt/asm/TestType.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/asm/TestType.java rename to src/test/java/com/alibaba/json/bvt/asm/TestType.java index fd5324c1e8..2e5715e369 --- a/src/test/java/com/alibaba/json/test/bvt/asm/TestType.java +++ b/src/test/java/com/alibaba/json/bvt/asm/TestType.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.asm; +package com.alibaba.json.bvt.asm; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.asm.Type; diff --git a/src/test/java/com/alibaba/json/test/bvt/bug/Bug1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug1.java old mode 100644 new mode 100755 similarity index 68% rename from src/test/java/com/alibaba/json/test/bvt/bug/Bug1.java rename to src/test/java/com/alibaba/json/bvt/bug/Bug1.java index 87bdc38552..16a44d3ef2 --- a/src/test/java/com/alibaba/json/test/bvt/bug/Bug1.java +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug1.java @@ -1,10 +1,10 @@ -package com.alibaba.json.test.bvt.bug; +package com.alibaba.json.bvt.bug; import junit.framework.TestCase; import com.alibaba.fastjson.JSONObject; -import com.alibaba.json.test.bvt.bug.JSONTest.InnerEntry; -import com.alibaba.json.test.bvt.bug.JSONTest.OuterEntry; +import com.alibaba.json.bvt.bug.JSONTest.InnerEntry; +import com.alibaba.json.bvt.bug.JSONTest.OuterEntry; public class Bug1 extends TestCase { diff --git a/src/test/java/com/alibaba/json/test/bvt/bug/Bug11.java b/src/test/java/com/alibaba/json/bvt/bug/Bug11.java old mode 100644 new mode 100755 similarity index 88% rename from src/test/java/com/alibaba/json/test/bvt/bug/Bug11.java rename to src/test/java/com/alibaba/json/bvt/bug/Bug11.java index fbbb648511..4d711b6c6d --- a/src/test/java/com/alibaba/json/test/bvt/bug/Bug11.java +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug11.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.bug; +package com.alibaba.json.bvt.bug; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug13.java b/src/test/java/com/alibaba/json/bvt/bug/Bug13.java new file mode 100755 index 0000000000..57a477e6bc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug13.java @@ -0,0 +1,57 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class Bug13 extends TestCase { + public void test_0() throws Exception { + User user = new User("name1", "11"); + String object = JSON.toJSONString(user); + System.out.println(object); + user = JSON.parseObject(object, User.class);//报错 + } + + public static class User { + public User() { + } + + private String name, age; + private List group = new ArrayList(2); + + public List getGroup() { + return group; + } + + public void setGroup(List group) { + this.group = group; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAge() { + return age; + } + + public void setAge(String age) { + this.age = age; + } + + public User(String name, String age) { + this.name = name; + this.age = age; + group.add("1"); + group.add("2"); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug14.java b/src/test/java/com/alibaba/json/bvt/bug/Bug14.java new file mode 100755 index 0000000000..fc9f013b7e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug14.java @@ -0,0 +1,64 @@ +package com.alibaba.json.bvt.bug; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug14 extends TestCase { + + public void test_0() throws Exception { + double f = -5.5000009; + Long i = 4294967295l; + System.out.println(BigInteger.valueOf(i)); + System.out.println(Math.round(f)); + List list = new ArrayList(); + list.add(new AB("2a", "3b")); + list.add(new AB("4a", "6b")); + list.add(new AB("6a", "7{sdf<>jgh\n}b")); + list.add(new AB("8a", "9b")); + list.add(new AB("10a", "11ba")); + list.add(new AB("12a", "13b")); + String[] abc = new String[] { "sf", "sdf", "dsffds", "sdfsdf{fds}" }; + Map map = new LinkedHashMap(); + int k = 0; + for (AB a : list) { + map.put(String.valueOf(k++), a); + } + System.out.println(JSON.toJSON(list)); + System.out.println(JSON.toJSON(abc)); + System.out.println(JSON.toJSON(new AB("10a", "11ba"))); + System.out.println(JSON.toJSON(map)); + + } + + private static class AB { + + private String a; + private String b; + + public AB(){ + super(); + } + + public AB(String a, String b){ + super(); + this.a = a; + this.b = b; + } + + public String getA() { + return a; + } + + public String getB() { + return b; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/bug/Bug2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug2.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/bug/Bug2.java rename to src/test/java/com/alibaba/json/bvt/bug/Bug2.java index 7222a1ba96..8740c54f2a --- a/src/test/java/com/alibaba/json/test/bvt/bug/Bug2.java +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug2.java @@ -1,11 +1,11 @@ -package com.alibaba.json.test.bvt.bug; +package com.alibaba.json.bvt.bug; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/bug/Bug_10.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_10.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/bug/Bug_10.java rename to src/test/java/com/alibaba/json/bvt/bug/Bug_10.java index e7a1865d00..642034e632 --- a/src/test/java/com/alibaba/json/test/bvt/bug/Bug_10.java +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_10.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.bug; +package com.alibaba.json.bvt.bug; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_101_for_rongganlin.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_101_for_rongganlin.java new file mode 100755 index 0000000000..14d1fdb05b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_101_for_rongganlin.java @@ -0,0 +1,66 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_101_for_rongganlin extends TestCase { + + public void test_for_bug() throws Exception { + Structure structure = new Structure(); + List groups = new ArrayList(); + + List elemA = new ArrayList(); + elemA.add(new Text().set("t.a", "v.t.a")); + elemA.add(new Image().set("i.a", "v.i.a")); + groups.add(new Group().set(elemA)); + + List elemB = new ArrayList(); + elemB.add(new Text().set("t.b", "v.t.b")); + elemB.add(new Image().set("i.b", "v.i.b")); + groups.add(new Group().set(elemB)); + + structure.groups = groups; + + System.out.println(JSON.toJSON(structure)); + System.out.println(JSON.toJSONString(structure)); + } + + class Structure { + + public List groups; + } + + class Group implements Object { + + public List elements; + + public Group set(List items) { + this.elements = items; + return this; + } + } + + interface Object { + } + + abstract class Element { + + public String key, value; + + public Element set(String key, String value) { + this.key = key; + this.value = value; + return this; + } + } + + class Text extends Element { + } + + class Image extends Element { + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_101_for_rongganlin_case2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_101_for_rongganlin_case2.java new file mode 100755 index 0000000000..43254d0c95 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_101_for_rongganlin_case2.java @@ -0,0 +1,71 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_101_for_rongganlin_case2 extends TestCase { + + public void test_for_bug() throws Exception { + Structure structure = new Structure(); + List groups = new ArrayList(); + + List elemA = new ArrayList(); + elemA.add(new Text().set("t.a", "v.t.a")); + elemA.add(new Image().set("i.a", "v.i.a")); + groups.add(new Group().set(elemA)); + + List elemB = new ArrayList(); + elemB.add(new Text().set("t.b", "v.t.b")); + elemB.add(new Image().set("i.b", "v.i.b")); + groups.add(new Group().set(elemB)); + + structure.groups = groups; + + String text = JSON.toJSONString(structure); + System.out.println(text); + Structure structure2 = JSON.parseObject(text, Structure.class); + + Assert.assertEquals(structure.groups.size(), structure2.groups.size()); + System.out.println(JSON.toJSONString(structure2)); + } + + public static class Structure { + + public List groups; + } + + public static class Group implements Object { + + public List elements; + + public Group set(List items) { + this.elements = items; + return this; + } + } + + public static interface Object { + } + + public static abstract class Element { + + public String key, value; + + public Element set(String key, String value) { + this.key = key; + this.value = value; + return this; + } + } + + public static class Text extends Element { + } + + public static class Image extends Element { + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_101_for_rongganlin_case3.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_101_for_rongganlin_case3.java new file mode 100755 index 0000000000..bee4529a8e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_101_for_rongganlin_case3.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt.bug; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + +public class Bug_101_for_rongganlin_case3 extends TestCase { + + public void test_for_bug() throws Exception { + Entity entity = new Entity(); + entity.setHolder(new Holder("AAA")); + + JSONObject json = (JSONObject) JSON.toJSON(entity); + Entity entity2 = JSON.toJavaObject(json, Entity.class); + Assert.assertEquals(JSON.toJSONString(entity), JSON.toJSONString(entity2)); + } + + public static class Entity { + + private Holder holder; + + public Holder getHolder() { + return holder; + } + + public void setHolder(Holder holder) { + this.holder = holder; + } + + } + + public static class Holder { + + private T value; + + public Holder() { + + } + + public Holder(T value) { + this.value = value; + } + + public T getValue() { + return value; + } + + public void setValue(T value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_102_for_rongganlin.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_102_for_rongganlin.java new file mode 100755 index 0000000000..11ee358bcf --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_102_for_rongganlin.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.util.TypeUtils; + +public class Bug_102_for_rongganlin extends TestCase { + + public void test_bug() throws Exception { + TestBean testProcessInfo = new TestBean(); + com.alibaba.fastjson.JSONObject jo = new com.alibaba.fastjson.JSONObject(); + jo.put("id", 121); + ParserConfig config = new ParserConfig(); + testProcessInfo = TypeUtils.cast(jo, TestBean.class, config); + } + + public static class TestBean { + + private double id; + private double name; + + public double getId() { + return id; + } + + public void setId(double id) { + this.id = id; + } + + public double getName() { + return name; + } + + public void setName(double name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_105_for_SpitFire.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_105_for_SpitFire.java new file mode 100755 index 0000000000..9b91cfd1f5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_105_for_SpitFire.java @@ -0,0 +1,43 @@ +package com.alibaba.json.bvt.bug; + +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_105_for_SpitFire extends TestCase { + + static private class Foo { + + private List names; + private List codes; + + public List getNames() { + return names; + } + + public void setNames(List names) { + this.names = names; + } + + public List getCodes() { + return codes; + } + + public void setCodes(List codes) { + this.codes = codes; + } + + } + + public void test_listErrorTest() { + Foo foo = new Foo(); + String json = JSON.toJSONString(foo, SerializerFeature.WriteMapNullValue); + System.out.println(json); + Foo f = JSON.parseObject(json, Foo.class); + System.out.println(f); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_127_for_qiuyan81.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_127_for_qiuyan81.java new file mode 100644 index 0000000000..1dcc08a1ee --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_127_for_qiuyan81.java @@ -0,0 +1,17 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; + +import junit.framework.Assert; +import junit.framework.TestCase; + +@SuppressWarnings("deprecation") +public class Bug_127_for_qiuyan81 extends TestCase { + + public void test_parserError() { + String jsonString = "{PayStatus:0,RunEmpId:undefined}"; + Object json = JSON.parse(jsonString); + Assert.assertEquals("{\"PayStatus\":0}",json.toString()); + } + +} diff --git a/src/test/java/com/alibaba/json/test/bvt/bug/Bug_6.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_6.java old mode 100644 new mode 100755 similarity index 90% rename from src/test/java/com/alibaba/json/test/bvt/bug/Bug_6.java rename to src/test/java/com/alibaba/json/bvt/bug/Bug_6.java index 82210e7ad9..5ce2ad9ce0 --- a/src/test/java/com/alibaba/json/test/bvt/bug/Bug_6.java +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_6.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.bug; +package com.alibaba.json.bvt.bug; import java.util.HashMap; import java.util.List; diff --git a/src/test/java/com/alibaba/json/test/bvt/bug/Bug_7.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_7.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/bug/Bug_7.java rename to src/test/java/com/alibaba/json/bvt/bug/Bug_7.java index 08faa8235a..bda39152e4 --- a/src/test/java/com/alibaba/json/test/bvt/bug/Bug_7.java +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_7.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.bug; +package com.alibaba.json.bvt.bug; import java.math.BigInteger; import java.util.concurrent.atomic.AtomicIntegerArray; diff --git a/src/test/java/com/alibaba/json/test/bvt/bug/Bug_8.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_8.java old mode 100644 new mode 100755 similarity index 83% rename from src/test/java/com/alibaba/json/test/bvt/bug/Bug_8.java rename to src/test/java/com/alibaba/json/bvt/bug/Bug_8.java index 666e1a3ded..4d83c14176 --- a/src/test/java/com/alibaba/json/test/bvt/bug/Bug_8.java +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_8.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.bug; +package com.alibaba.json.bvt.bug; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONArray; diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_KimShen.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_KimShen.java new file mode 100755 index 0000000000..7545e96273 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_KimShen.java @@ -0,0 +1,63 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Set; +import java.util.TreeSet; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_KimShen extends TestCase { + + public void test_0() throws Exception { + String text = JSON.toJSONString(new Entity()); + JSON.parseObject(text, Entity.class); + } + + public static class Entity { + + private Set value = new HashSet(); + private TreeSet treeSet = new TreeSet(); + private LinkedList linkedList = new LinkedList(); + private MySet mySet = new MySet(); + + public MySet getMySet() { + return mySet; + } + + public void setMySet(MySet mySet) { + this.mySet = mySet; + } + + public LinkedList getLinkedList() { + return linkedList; + } + + public void setLinkedList(LinkedList linkedList) { + this.linkedList = linkedList; + } + + public Set getValue() { + return value; + } + + public void setValue(Set value) { + this.value = value; + } + + public TreeSet getTreeSet() { + return treeSet; + } + + public void setTreeSet(TreeSet treeSet) { + this.treeSet = treeSet; + } + + } + + public static class MySet extends TreeSet { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_42283905.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_42283905.java new file mode 100755 index 0000000000..2de0159db6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_42283905.java @@ -0,0 +1,122 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class Bug_for_42283905 extends TestCase { + + public void test_0() throws Exception { + + String text; + { + List groups = new ArrayList(); + + Command c0 = new Command(1); + Command c1 = new Command(2); + Command c2 = new Command(3); + + c1.setPre(c0); + c2.setPre(c1); + + { + Group group = new Group("g0"); + group.getBattleCommandList().add(c0); + groups.add(group); + } + + { + Group group = new Group("g1"); + group.getBattleCommandList().add(c1); + groups.add(group); + } + + { + Group group = new Group("g2"); + group.getBattleCommandList().add(c2); + groups.add(group); + } + text = JSON.toJSONString(groups); + } + + System.out.println(text); + + List groups = JSON.parseObject(text, new TypeReference>() { + }); + Group g0 = groups.get(0); + Group g1 = groups.get(1); + + System.out.println(JSON.toJSONString(groups)); + } + + public static class Group { + + private String name; + + private List battleCommandList = new ArrayList(); + + public Group(){ + + } + + public Group(String name){ + this.name = name; + } + + public List getBattleCommandList() { + return battleCommandList; + } + + public void setBattleCommandList(List battleCommandList) { + this.battleCommandList = battleCommandList; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + + public static class Command { + + private int id; + + public Command(){ + + } + + public Command(int id){ + this.id = id; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + private Command pre; + + public Command getPre() { + return pre; + } + + public void setPre(Command pre) { + this.pre = pre; + } + + public String toString() { + return "{id:" + id + "}"; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_42283905_1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_42283905_1.java new file mode 100755 index 0000000000..28173d577c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_42283905_1.java @@ -0,0 +1,122 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class Bug_for_42283905_1 extends TestCase { + + public void test_0() throws Exception { + + String text; + { + List groups = new ArrayList(); + + Command c0 = new Command(1); + Command c1 = new Command(2); + Command c2 = new Command(3); + + c1.setPre(c0); + c2.setPre(c1); + + { + Group group = new Group("g0"); + group.getBattleCommandList().add(c0); + groups.add(group); + } + + { + Group group = new Group("g1"); + group.getBattleCommandList().add(c1); + groups.add(group); + } + + { + Group group = new Group("g2"); + group.getBattleCommandList().add(c2); + groups.add(group); + } + text = JSON.toJSONString(groups); + } + + System.out.println(text); + + Group[] groups = JSON.parseObject(text, new TypeReference() { + }); + Group g0 = groups[0]; + Group g1 = groups[1]; + + System.out.println(JSON.toJSONString(groups)); + } + + public static class Group { + + private String name; + + private List battleCommandList = new ArrayList(); + + public Group(){ + + } + + public Group(String name){ + this.name = name; + } + + public List getBattleCommandList() { + return battleCommandList; + } + + public void setBattleCommandList(List battleCommandList) { + this.battleCommandList = battleCommandList; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + + public static class Command { + + private int id; + + public Command(){ + + } + + public Command(int id){ + this.id = id; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + private Command pre; + + public Command getPre() { + return pre; + } + + public void setPre(Command pre) { + this.pre = pre; + } + + public String toString() { + return "{id:" + id + "}"; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_80108116.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_80108116.java new file mode 100755 index 0000000000..35474ad88a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_80108116.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt.bug; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; + +public class Bug_for_80108116 extends TestCase { + + public void test_for_dateFormat() throws Exception { + VO vo = new VO(); + vo.setDate(new SimpleDateFormat("yyyy-MM-dd").parse("2012-07-12")); + + List voList = new ArrayList(); + voList.add(vo); + + String text = JSON.toJSONString(voList); + Assert.assertEquals("[{\"date\":\"2012-07-12\"}]", text); + } + + public static class VO { + + private Date date; + + @JSONField(format = "yyyy-MM-dd") + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_ArrayMember.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_ArrayMember.java new file mode 100755 index 0000000000..ce80bbd7d9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_ArrayMember.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; + +import org.junit.Assert; +import junit.framework.TestCase; + +public class Bug_for_ArrayMember extends TestCase { + public void test_arrayMember() throws Exception { + A a = new A(); + a.setValues(new B[] {new B()}); + + String text = JSON.toJSONString(a); + + Assert.assertEquals("{\"values\":[{}]}", text); + Assert.assertEquals("{}", JSON.toJSONString(new A())); + Assert.assertEquals("null", JSON.toJSONString(new A().getValues())); + + Assert.assertEquals("[]", JSON.toJSONString(new A[0])); + Assert.assertEquals("[{},{}]", JSON.toJSONString(new A[] {new A(), new A()})); + } + + public static class A { + + private B[] values; + + public B[] getValues() { + return values; + } + + public void setValues(B[] values) { + this.values = values; + } + + } + + public static class B { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Double2Tag.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Double2Tag.java new file mode 100755 index 0000000000..43b71012ec --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Double2Tag.java @@ -0,0 +1,95 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + +public class Bug_for_Double2Tag extends TestCase { + public void test_double() throws Exception { + Double2Tag tag = new Double2Tag(); + String str = JSON.toJSONString(tag); + JSON.parseObject(str, Double2Tag.class); + } + + public static class Double2Tag { + public String data_time; + public String data_id; + public String hour_id; + public String minute_id; + public String tag3_id; + public double ali_fee; + public double total_ali_fee; + public long seller_cnt; + + public Double2Tag() { + ali_fee = 0.0; + total_ali_fee = 0.0; + seller_cnt = 0; + } + + public String getData_time() { + return data_time; + } + + public void setData_time(String data_time) { + this.data_time = data_time; + } + + public String getData_id() { + return data_id; + } + + public void setData_id(String data_id) { + this.data_id = data_id; + } + + public String getHour_id() { + return hour_id; + } + + public void setHour_id(String hour_id) { + this.hour_id = hour_id; + } + + public String getMinute_id() { + return minute_id; + } + + public void setMinute_id(String minute_id) { + this.minute_id = minute_id; + } + + public String getTag3_id() { + return tag3_id; + } + + public void setTag3_id(String tag3_id) { + this.tag3_id = tag3_id; + } + + public double getAli_fee() { + return ali_fee; + } + + public void setAli_fee(double ali_fee) { + this.ali_fee = ali_fee; + } + + public double getTotal_ali_fee() { + return total_ali_fee; + } + + public void setTotal_ali_fee(double total_ali_fee) { + this.total_ali_fee = total_ali_fee; + } + + public long getSeller_cnt() { + return seller_cnt; + } + + public void setSeller_cnt(long seller_cnt) { + this.seller_cnt = seller_cnt; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Exception.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Exception.java new file mode 100755 index 0000000000..a062ca8be6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Exception.java @@ -0,0 +1,15 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_Exception extends TestCase { + public void test_exception() throws Exception { + RuntimeException ex = new RuntimeException("e1"); + String text = JSON.toJSONString(ex); + System.out.println(text); + + RuntimeException ex2 = (RuntimeException) JSON.parse(text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_JSONObject.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_JSONObject.java new file mode 100755 index 0000000000..153759c18d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_JSONObject.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class Bug_for_JSONObject extends TestCase { + public void test_0 () throws Exception { + JSONSerializer ser = new JSONSerializer(); + ser.config(SerializerFeature.WriteClassName, true); + ser.write(new JSONObject()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Jay.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Jay.java new file mode 100755 index 0000000000..0133a9fd0e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Jay.java @@ -0,0 +1,21 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_Jay extends TestCase { + + public void test_for_jay() throws Exception { + JSON.toJSONString(new B(), true); + } + + public class A { + + String nameA; + } + + public class B extends A { + String nameB; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Jay_1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Jay_1.java new file mode 100755 index 0000000000..2fc8bfeff8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Jay_1.java @@ -0,0 +1,11 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + +public class Bug_for_Jay_1 extends TestCase { + public void test_bug() throws Exception { + JSON.parseObject("{\"body\":{\"coupons\":[{\"couponTypeId\":\"81c07c7c-7b88-4f5c-9d1e-e6f16e2ae36d\",\"editor\":\"ADMIN\",\"organizationPartyId\":\"00\",\"statusId\":\"COUPON_CREATED\",\"editorName\":\"超级管理员\",\"couponCode\":\"02\",\"creatorName\":\"超级管理员\",\"id\":\"d686bc04-a9d5-4f84-977a-8bfbb4fa9fe3\",\"fromDate\":\"2013-03-11 00:00:00\",\"creator\":\"ADMIN\",\"displayName\":\"02\",\"createTime\":\"2013-03-12 13:14:05\",\"updateTime\":\"2013-03-12 13:14:05\",\"organizationName\":\"X、X\"}],\"event\":\"activate\"}}"); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_JeryZeng.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_JeryZeng.java new file mode 100644 index 0000000000..b5d68a9d53 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_JeryZeng.java @@ -0,0 +1,12 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class Bug_for_JeryZeng extends TestCase { + public void test_0() throws Exception { + System.out.println(JSON.parseObject("{123:123,124:true,\"value\":{123:\"abc\"}}")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Johnny.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Johnny.java new file mode 100755 index 0000000000..798ee8b612 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_Johnny.java @@ -0,0 +1,241 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_Johnny extends TestCase { + + public void test_bug()throws Exception { + MyObject myObject = new MyObject(); + List listObj = new LinkedList(); + Set setObj = new HashSet(); + Map mapObj = new HashMap(); + listObj.add("aaa"); + listObj.add("bbb"); + setObj.add("aaa"); + setObj.add("bbb"); + mapObj.put("key", "value"); + myObject.setBoolType(true); + myObject.setByteType(Byte.MIN_VALUE); + myObject.setCharType(Character.MIN_VALUE); + myObject.setDoubleType(Double.MIN_VALUE); + myObject.setFloatType(Float.MIN_VALUE); + myObject.setIntType(Integer.MIN_VALUE); + myObject.setLongType(Long.MIN_VALUE); + myObject.setShortType(Short.MIN_VALUE); + myObject.setEnumType(EnumType.MD5); + myObject.setStringType("aadf"); + myObject.setMapType(mapObj); + myObject.setSetType(setObj); + myObject.setListType(listObj); + + String text = JSON.toJSONString(myObject, SerializerFeature.WriteClassName); + System.out.println(text); + MyObject myObject2 = (MyObject) JSON.parse(text); + Assert.assertEquals(myObject2.getMapType(), myObject.getMapType()); + } + + public static enum EnumType { + MD5, SHA1 + } + + public static class MyObject { + + private String stringType; + private byte byteType; + private short shortType; + private int intType; + private long longType; + private char charType; + private float floatType; + private double doubleType; + private boolean boolType; + private List ListType; + private Map mapType; + private Set setType; + private EnumType enumType; + + public Set getSetType() { + return setType; + } + + public void setSetType(Set setType) { + this.setType = setType; + } + + /** + * @return the stringType + */ + public String getStringType() { + return stringType; + } + + public EnumType getEnumType() { + return enumType; + } + + public void setEnumType(EnumType enumType) { + this.enumType = enumType; + } + + public List getListType() { + return ListType; + } + + public void setListType(List listType) { + ListType = listType; + } + + public Map getMapType() { + return mapType; + } + + public void setMapType(Map mapType) { + this.mapType = mapType; + } + + /** + * @param stringType + * the stringType to set + */ + public void setStringType(String stringType) { + this.stringType = stringType; + } + + /** + * @return the byteType + */ + public byte getByteType() { + return byteType; + } + + /** + * @param byteType + * the byteType to set + */ + public void setByteType(byte byteType) { + this.byteType = byteType; + } + + /** + * @return the shortType + */ + public short getShortType() { + return shortType; + } + + /** + * @param shortType + * the shortType to set + */ + public void setShortType(short shortType) { + this.shortType = shortType; + } + + /** + * @return the intType + */ + public int getIntType() { + return intType; + } + + /** + * @param intType + * the intType to set + */ + public void setIntType(int intType) { + this.intType = intType; + } + + /** + * @return the longType + */ + public long getLongType() { + return longType; + } + + /** + * @param longType + * the longType to set + */ + public void setLongType(long longType) { + this.longType = longType; + } + + /** + * @return the charType + */ + public char getCharType() { + return charType; + } + + /** + * @param charType + * the charType to set + */ + public void setCharType(char charType) { + this.charType = charType; + } + + /** + * @return the floatType + */ + public float getFloatType() { + return floatType; + } + + /** + * @param floatType + * the floatType to set + */ + public void setFloatType(float floatType) { + this.floatType = floatType; + } + + /** + * @return the doubleType + */ + public double getDoubleType() { + return doubleType; + } + + /** + * @param doubleType + * the doubleType to set + */ + public void setDoubleType(double doubleType) { + this.doubleType = doubleType; + } + + /** + * @return the boolType + */ + public boolean isBoolType() { + return boolType; + } + + /** + * @param boolType + * the boolType to set + */ + public void setBoolType(boolean boolType) { + this.boolType = boolType; + } + + /** + * Constructs a GroupEntity
+ */ + public MyObject() { + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_NonStringKeyMap.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_NonStringKeyMap.java new file mode 100755 index 0000000000..c23b9fc818 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_NonStringKeyMap.java @@ -0,0 +1,51 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +import junit.framework.TestCase; + +public class Bug_for_NonStringKeyMap extends TestCase { + + public void test_bug() throws Exception { + VO vo = new VO(); + vo.getMap().put(1L, new VAL()); + + String text = JSON.toJSONString(vo, SerializerFeature.WriteClassName); + System.out.println(text); + + JSON.parse(text); + } + + public void test_1() throws Exception { + Map, String> map = new HashMap, String>(); + Map submap = new HashMap(); + submap.put("subkey", "subvalue"); + map.put(submap, "value"); + String jsonString = JSON.toJSONString(map, SerializerFeature.WriteClassName); + System.out.println(jsonString); + Object object = JSON.parse(jsonString); + System.out.println(object.toString()); + } + + public static class VO { + + private Map map = new HashMap(); + + public Map getMap() { + return map; + } + + public void setMap(Map map) { + this.map = map; + } + + } + + public static class VAL { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_O_I_See_you.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_O_I_See_you.java new file mode 100755 index 0000000000..f5f0c01d61 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_O_I_See_you.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_O_I_See_you extends TestCase { + + public void test_bug() throws Exception { + Object[] arra = { "aa", "bb" }; + + Object[] arr = { "sssss", arra }; + + String s = JSON.toJSONString(arr); + + Object[] ar = JSON.parseObject(s, Object[].class); + System.out.println(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire.java new file mode 100755 index 0000000000..302c753fc6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire.java @@ -0,0 +1,63 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_SpitFire extends TestCase { + + public void test_for_spitFire() throws Exception { + GenericDTO object = new GenericDTO(); + object.setFiled(new MyDTO()); + + String text = JSON.toJSONString(object, SerializerFeature.WriteClassName); + + GenericDTO object2 = (GenericDTO) JSON.parseObject(text, GenericDTO.class); + + Assert.assertEquals(object.getName(), object2.getName()); + Assert.assertEquals(object.getFiled().getId(), object2.getFiled().getId()); + } + + public static class GenericDTO extends AbstractDTO { + + private String name; + private T filed; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public T getFiled() { + return filed; + } + + public void setFiled(T filed) { + this.filed = filed; + } + } + + public abstract static class AbstractDTO { + + } + + public static class MyDTO extends AbstractDTO { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_2.java new file mode 100755 index 0000000000..da7bd3fb29 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_2.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_SpitFire_2 extends TestCase { + + public void test_for_SpringFire() { + Generic q = new Generic(); + String text = JSON.toJSONString(q, SerializerFeature.WriteClassName); + System.out.println(text); + JSON.parseObject(text, Generic.class); + } + + public static class Generic { + + String header; + T payload; + + public String getHeader() { + return header; + } + + public void setHeader(String header) { + this.header = header; + } + + public T getPayload() { + return payload; + } + + public void setPayload(T payload) { + this.payload = payload; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_3.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_3.java new file mode 100755 index 0000000000..628608fca4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_3.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_SpitFire_3 extends TestCase { + + public void test_for_SpitFire() { + Generic q = new Generic(); + q.setHeader("Sdfdf"); + q.setPayload(new Payload()); + String text = JSON.toJSONString(q, SerializerFeature.WriteClassName); + System.out.println(text); + JSON.parseObject(text, Generic.class); + } + + public static abstract class AbstractDTO { + + private String test; + + public String getTest() { + return test; + } + + public void setTest(String test) { + this.test = test; + } + } + + public static class Payload extends AbstractDTO { + + } + + public static class Generic extends AbstractDTO { + + String header; + T payload; + + public String getHeader() { + return header; + } + + public void setHeader(String header) { + this.header = header; + } + + public T getPayload() { + return payload; + } + + public void setPayload(T payload) { + this.payload = payload; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_4.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_4.java new file mode 100755 index 0000000000..977de20a5c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_4.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_SpitFire_4 extends TestCase { + + public void test_for_SpitFire() { + Generic q = new Generic(); + q.setHeader(new Header()); + q.setPayload(new Payload()); + String text = JSON.toJSONString(q, SerializerFeature.WriteClassName); + System.out.println(text); + Generic o = (Generic) JSON.parseObject(text, q.getClass()); + Assert.assertNotNull(o.getPayload()); + } + + public static abstract class AbstractDTO { + } + + public static class Header { + + } + + public static class Payload extends AbstractDTO { + + } + + public static class Generic extends AbstractDTO { + + Header header; + T payload; + + public Header getHeader() { + return header; + } + + public void setHeader(Header header) { + this.header = header; + } + + public T getPayload() { + return payload; + } + + public void setPayload(T payload) { + this.payload = payload; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_5.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_5.java new file mode 100755 index 0000000000..767b2cb6f0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_5.java @@ -0,0 +1,64 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_SpitFire_5 extends TestCase { + + public void test_for_SpitFire() { + Generic q = new Generic(); + q.setHeader(new Header()); + q.setPayload(new Payload()); + String text = JSON.toJSONString(q, SerializerFeature.WriteClassName); + System.out.println(text); + Generic o = (Generic) JSON.parseObject(text, q.getClass()); + Assert.assertNotNull(o.getPayload()); + } + + public static abstract class AbstractDTO { + } + + public static class Header { + + } + + public static class Payload extends AbstractDTO { + + private String field; + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } + } + + public static class Generic extends AbstractDTO { + + Header header; + T payload; + + public Header getHeader() { + return header; + } + + public void setHeader(Header header) { + this.header = header; + } + + public T getPayload() { + return payload; + } + + public void setPayload(T payload) { + this.payload = payload; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_6.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_6.java new file mode 100755 index 0000000000..45830242c6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_SpitFire_6.java @@ -0,0 +1,74 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_SpitFire_6 extends TestCase { + + public void test_ref() throws Exception { + GenericRS rs = new GenericRS(); + HotelAvailRS availRs = new HotelAvailRS(); + AvailRoomStayDTO stay = new AvailRoomStayDTO(); + availRs.getHotelAvailRoomStay().getRoomStays().add(stay); + availRs.getHotelAvailRoomStay().getRoomStays().add(stay); + availRs.getHotelAvailRoomStay().getRoomStays().add(stay); + availRs.getHotelAvailRoomStay().getRoomStays().add(stay); + rs.setPayload(availRs); + + String text = JSON.toJSONString(rs, SerializerFeature.WriteClassName, SerializerFeature.PrettyFormat); + System.out.println(text); + + JSON.parseObject(text, GenericRS.class); + } + + public static class GenericRS { + + private T payload; + + public T getPayload() { + return payload; + } + + public void setPayload(T payload) { + this.payload = payload; + } + + } + + public static class HotelAvailRS { + + private HotelAvailRoomStayDTO hotelAvailRoomStay = new HotelAvailRoomStayDTO(); + + public HotelAvailRoomStayDTO getHotelAvailRoomStay() { + return hotelAvailRoomStay; + } + + public void setHotelAvailRoomStay(HotelAvailRoomStayDTO hotelAvailRoomStay) { + this.hotelAvailRoomStay = hotelAvailRoomStay; + } + + } + + public static class HotelAvailRoomStayDTO { + + private List roomStays = new ArrayList(); + + public List getRoomStays() { + return roomStays; + } + + public void setRoomStays(List roomStays) { + this.roomStays = roomStays; + } + + } + + public static class AvailRoomStayDTO { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_agapple.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_agapple.java new file mode 100755 index 0000000000..c58f8d6a4b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_agapple.java @@ -0,0 +1,32 @@ +package com.alibaba.json.bvt.bug; + +import java.util.Properties; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + +public class Bug_for_agapple extends TestCase { + + public void test_for_agapple() throws Exception { + Entity entity = new Entity(); + entity.setProperties(new Properties()); + String text = JSON.toJSONString(entity); + + JSON.parseObject(text, Entity.class); + } + + private static class Entity { + + private Properties properties; + + public Properties getProperties() { + return properties; + } + + public void setProperties(Properties properties) { + this.properties = properties; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_agapple_2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_agapple_2.java new file mode 100755 index 0000000000..e9af774947 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_agapple_2.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.bug; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + +public class Bug_for_agapple_2 extends TestCase { + + public void test_bug() throws Exception { + DbMediaSource obj = new DbMediaSource(); + obj.setType(DataMediaType.ORACLE); + + JSONObject json = (JSONObject) JSON.toJSON(obj); + Assert.assertEquals("ORACLE", json.get("type")); + } + + public static class DbMediaSource { + + private DataMediaType type; + + public DataMediaType getType() { + return type; + } + + public void setType(DataMediaType type) { + this.type = type; + } + + } + + public static enum DataMediaType { + ORACLE, MYSQL + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_akvadrako.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_akvadrako.java new file mode 100644 index 0000000000..65b63efb6d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_akvadrako.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.parser.DefaultJSONParser; + +public class Bug_for_akvadrako extends TestCase { + + public void testNakedFields() throws Exception { + Naked naked = new Naked(); + DefaultJSONParser parser = new DefaultJSONParser("{ \"field\": 3 }"); + parser.parseObject(naked); + } + + public static class Naked { + + public int field; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_alibank.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_alibank.java new file mode 100755 index 0000000000..97456dd8b9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_alibank.java @@ -0,0 +1,15 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class Bug_for_alibank extends TestCase { + public void test_bug() throws Exception { + String jsonStrz = "{addContact:[{\"address\":\"=\\\\\\\\\\\'\'\\");|]*{%0d%0a<%00\"}]}"; + System.out.println(jsonStrz); + Object o = JSON.parseObject(jsonStrz.replaceAll("\\\\", "")); + System.out.println(JSON.toJSONString(o)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_apollo0317.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_apollo0317.java new file mode 100644 index 0000000000..f7b3f05128 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_apollo0317.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_apollo0317 extends TestCase { + + public void test_for_apollo0317() throws Exception { + String text = "广州市白云区优网通信线缆厂是一家集专业设计、生产、销售、电工解决方案提供为一体的中型企业,旗下主打品牌(简称:普禄克Pluke);公厂拥有自己的研发团队,自主研发改造的高性能电缆生产流水线使产品的性价比大幅度提升,在技术上处于行业领先。\r\n  普禄克Pluke销售服务网络覆盖全国各省市以及南美、东南亚等地区。产品广范应用在军队通信网,政府网,企业网,电信网,电力网,煤炭网,水利网,广电网,校园网 电梯设备、机电设备、汽车、电子、等行业,其中超五类六类网络线缆,彩色网络跳线,设备连接及控制传输电缆,电器连接线多年来获得客户的高度肯定。?普禄克PLUKE在不断创新中为客户创造价值,在工厂战略的指导下,凭借在售前咨询,系统设计,产品采购,工程施工等方面的综合优势和我们多面的工程服务经验,可以根据客户的要求,提供切实可行的技术方案及系统产品。\r\n 工厂未来将着力于商业模式的创新转换,为合作伙伴提供一个共同成长、双赢的、持续发展的商业平台。\r\n 我们企业的宗旨是:销售最好的产品、追求最佳的售后服务、推广最新的办公理念!"; + + VO vo = new VO(); + vo.setBrandintroduction(text); + + Object[] array = new Object[] {vo, vo, vo}; + + String json = JSON.toJSONString(vo, SerializerFeature.DisableCircularReferenceDetect); + System.out.println(json); + } + + public static class VO { + + private String brandintroduction; + + public String getBrandintroduction() { + return brandintroduction; + } + + public void setBrandintroduction(String brandintroduction) { + this.brandintroduction = brandintroduction; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_array.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_array.java new file mode 100755 index 0000000000..0f4f63d7af --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_array.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_array extends TestCase { + public void test_array() throws Exception { + A[] array = new A[] { new B(123, "xxx") }; + + String text = JSON.toJSONString(array); + System.out.println(text); + Assert.assertEquals("[{\"id\":123,\"name\":\"xxx\"}]", text); + } + + public static class A { + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } + + public static class B extends A { + private String name; + + public B() { + + } + + public B (int id, String name) { + setId(id); + setName(name); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_ascii_0_31.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_ascii_0_31.java new file mode 100755 index 0000000000..795a962946 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_ascii_0_31.java @@ -0,0 +1,110 @@ +package com.alibaba.json.bvt.bug; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_ascii_0_31 extends TestCase { + + public void test_0() throws Exception { + for (int i = 0; i < 32; ++i) { + StringBuilder buf = new StringBuilder(); + char ch = (char) i; + buf.append(ch); + + String text = JSON.toJSONString(buf.toString(), SerializerFeature.BrowserCompatible); + + switch (ch) { + case '"': + Assert.assertEquals("\"\\\"\"", text); + break; + case '/': + Assert.assertEquals("\"\\/\"", text); + break; + case '\\': + Assert.assertEquals("\"\\\\\"", text); + break; + case '\b': + Assert.assertEquals("\"\\b\"", text); + break; + case '\f': + Assert.assertEquals("\"\\f\"", text); + break; + case '\n': + Assert.assertEquals("\"\\n\"", text); + break; + case '\r': + Assert.assertEquals("\"\\r\"", text); + break; + case '\t': + Assert.assertEquals("\"\\t\"", text); + break; + default: + if (i < 16) { + Assert.assertEquals("\"\\u000" + Integer.toHexString(i).toUpperCase() + "\"", text); + } else { + Assert.assertEquals("\"\\u00" + Integer.toHexString(i).toUpperCase() + "\"", text); + } + break; + } + + VO vo = new VO(); + vo.setContent(buf.toString()); + + String voText = JSON.toJSONString(vo, SerializerFeature.BrowserCompatible); + + switch (ch) { + case '"': + Assert.assertEquals("{\"content\":\"\\\"\"}", voText); + break; + case '/': + Assert.assertEquals("{\"content\":\"\\/\"}", voText); + break; + case '\\': + Assert.assertEquals("{\"content\":\"\\\\\"}", voText); + break; + case '\b': + Assert.assertEquals("{\"content\":\"\\b\"}", voText); + break; + case '\f': + Assert.assertEquals("{\"content\":\"\\f\"}", voText); + break; + case '\n': + Assert.assertEquals("{\"content\":\"\\n\"}", voText); + break; + case '\r': + Assert.assertEquals("{\"content\":\"\\r\"}", voText); + break; + case '\t': + Assert.assertEquals("{\"content\":\"\\t\"}", voText); + break; + default: + if (i < 16) { + Assert.assertEquals("{\"content\":\"\\u000" + Integer.toHexString(i).toUpperCase() + "\"}", + voText); + } else { + Assert.assertEquals("{\"content\":\"\\u00" + Integer.toHexString(i).toUpperCase() + "\"}", + voText); + } + break; + } + } + + } + + public static class VO { + + private String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_bbl.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_bbl.java new file mode 100755 index 0000000000..d74d14b032 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_bbl.java @@ -0,0 +1,32 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_bbl extends TestCase { + + public void test_bug() throws Exception { + Map params = new HashMap(); + params.put("msg", + + ""); + params.put("uid", "22034343"); + + String s001 = JSON.toJSONString(params, SerializerFeature.BrowserCompatible); + + System.out.println(s001); + + Map params2 = (Map) JSON.parse(s001); + Assert.assertEquals(params.size(), params2.size()); + Assert.assertEquals(params.get("uid"), params2.get("uid")); + + Assert.assertEquals(params.get("msg"), params2.get("msg")); + Assert.assertEquals(params, params2); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_booleanField.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_booleanField.java new file mode 100644 index 0000000000..8d62d30158 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_booleanField.java @@ -0,0 +1,30 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; + +public class Bug_for_booleanField extends TestCase { + + public void test_boolean() throws Exception { + Assert.assertEquals("{\"is-abc\":false}", JSON.toJSONString(new BooleanJson())); + Assert.assertTrue(JSON.parseObject("{\"is-abc\":true}", BooleanJson.class).isAbc()); + } + + public static class BooleanJson { + + @JSONField(name = "is-abc") + private boolean isAbc; + + public boolean isAbc() { + return isAbc; + } + + public void setAbc(boolean value) { + this.isAbc = value; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_builder.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_builder.java new file mode 100644 index 0000000000..722b524f84 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_builder.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + +public class Bug_for_builder extends TestCase { + + public void test_for_longBuilderMethod() throws Exception { + VO vo = JSON.parseObject("{\"id\":123}", VO.class); + } + + public static class VO { + + private long id; + + public long getId() { + return id; + } + + public VO setId(long id) { + this.id = id; + return this; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_cduym.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_cduym.java new file mode 100755 index 0000000000..658efd5ace --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_cduym.java @@ -0,0 +1,103 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_cduym extends TestCase { + + @SuppressWarnings("rawtypes") + public void test0() { + + List as = new ArrayList(); + + A a1 = new A(); + a1.setA(1000); + a1.setB(2000l); + a1.setC("xxx"); + + as.add(a1); + as.add(a1); + + String text = JSON.toJSONString(as, SerializerFeature.WriteClassName); + System.out.println(text); + List target = (List) JSON.parseObject(text, Object.class); + + Assert.assertSame(target.get(0), target.get(1)); + } + + public void test1() { + + List as = new ArrayList(); + + A a1 = new A(); + a1.setA(1000); + a1.setB(2000l); + a1.setC("xxx"); + + as.add(a1); + as.add(a1); + + Demo o = new Demo(); + o.setAs(as); + + String text = JSON.toJSONString(o, SerializerFeature.WriteClassName); + System.out.println(text); + Demo target = (Demo) JSON.parseObject(text, Object.class); + + Assert.assertSame(((List)target.getAs()).get(0), ((List)target.getAs()).get(1)); + } + + + public static class Demo { + + private Object as; + + public Object getAs() { + return as; + } + + public void setAs(Object as) { + this.as = as; + } + + } + + private static class A { + + private Integer a; + private Long b; + + private String c; + + public Integer getA() { + return a; + } + + public void setA(Integer a) { + this.a = a; + } + + public Long getB() { + return b; + } + + public void setB(Long b) { + this.b = b; + } + + public String getC() { + return c; + } + + public void setC(String c) { + this.c = c; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_chengchao.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_chengchao.java new file mode 100755 index 0000000000..5bacad8553 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_chengchao.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.bug; + +import java.util.concurrent.TimeUnit; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_chengchao extends TestCase { + + public void test_0() throws Exception { + SerializerFeature[] features = { SerializerFeature.WriteMapNullValue, + + SerializerFeature.WriteEnumUsingToString, SerializerFeature.SortField }; + + Entity entity = new Entity(); + JSON.toJSONString(entity, features); + } + + private static class Entity { + + private TimeUnit unit; + + public TimeUnit getUnit() { + return unit; + } + + public void setUnit(TimeUnit unit) { + this.unit = unit; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_cnhans.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_cnhans.java new file mode 100755 index 0000000000..a151312560 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_cnhans.java @@ -0,0 +1,93 @@ +package com.alibaba.json.bvt.bug; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_cnhans extends TestCase { + + public void test_0() throws Exception { + VO vo = new VO(); + vo.setCalendar(Calendar.getInstance()); + + String text = JSON.toJSONString(vo); + + VO vo1 = JSON.parseObject(text, VO.class); + Assert.assertEquals(vo.getCalendar().getTime(), vo1.getCalendar().getTime()); + } + + public void test_format() throws Exception { + VO vo = new VO(); + vo.setCalendar(Calendar.getInstance()); + + String text = JSON.toJSONString(vo, SerializerFeature.WriteDateUseDateFormat); + + VO vo1 = JSON.parseObject(text, VO.class); + Assert.assertEquals(vo.getCalendar().get(Calendar.YEAR), vo1.getCalendar().get(Calendar.YEAR)); + Assert.assertEquals(vo.getCalendar().get(Calendar.MONTH), vo1.getCalendar().get(Calendar.MONTH)); + Assert.assertEquals(vo.getCalendar().get(Calendar.DAY_OF_MONTH), vo1.getCalendar().get(Calendar.DAY_OF_MONTH)); + Assert.assertEquals(vo.getCalendar().get(Calendar.HOUR_OF_DAY), vo1.getCalendar().get(Calendar.HOUR_OF_DAY)); + Assert.assertEquals(vo.getCalendar().get(Calendar.MINUTE), vo1.getCalendar().get(Calendar.MINUTE)); + Assert.assertEquals(vo.getCalendar().get(Calendar.SECOND), vo1.getCalendar().get(Calendar.SECOND)); + } + + public void test_iso_format() throws Exception { + VO vo = new VO(); + vo.setCalendar(Calendar.getInstance()); + + String text = JSON.toJSONString(vo, SerializerFeature.UseISO8601DateFormat); + + VO vo1 = JSON.parseObject(text, VO.class); + Assert.assertEquals(vo.getCalendar().get(Calendar.YEAR), vo1.getCalendar().get(Calendar.YEAR)); + Assert.assertEquals(vo.getCalendar().get(Calendar.MONTH), vo1.getCalendar().get(Calendar.MONTH)); + Assert.assertEquals(vo.getCalendar().get(Calendar.DAY_OF_MONTH), vo1.getCalendar().get(Calendar.DAY_OF_MONTH)); + Assert.assertEquals(vo.getCalendar().get(Calendar.HOUR_OF_DAY), vo1.getCalendar().get(Calendar.HOUR_OF_DAY)); + Assert.assertEquals(vo.getCalendar().get(Calendar.MINUTE), vo1.getCalendar().get(Calendar.MINUTE)); + Assert.assertEquals(vo.getCalendar().get(Calendar.SECOND), vo1.getCalendar().get(Calendar.SECOND)); + } + + public void test_toJavaObject() throws Exception { + JSONObject obj = new JSONObject(); + obj.put("d1", new Date()); + obj.put("d2", System.currentTimeMillis()); + obj.put("d3", GregorianCalendar.getInstance()); + obj.put("d4", "2012-12-22"); + obj.put("d5", "2012-12-22 12:11:11"); + obj.put("d6", "2012-12-22 12:11:11.234"); + + obj.getObject("d1", Calendar.class); + obj.getObject("d2", Calendar.class); + obj.getObject("d3", Calendar.class); + obj.getObject("d4", Calendar.class); + obj.getObject("d5", Calendar.class); + obj.getObject("d6", Calendar.class); + + obj.getObject("d1", GregorianCalendar.class); + obj.getObject("d2", GregorianCalendar.class); + obj.getObject("d3", GregorianCalendar.class); + obj.getObject("d4", GregorianCalendar.class); + obj.getObject("d5", GregorianCalendar.class); + obj.getObject("d6", GregorianCalendar.class); + } + + public static class VO { + + private Calendar calendar; + + public Calendar getCalendar() { + return calendar; + } + + public void setCalendar(Calendar calendar) { + this.calendar = calendar; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dargoner.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dargoner.java new file mode 100755 index 0000000000..7f9efa140b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dargoner.java @@ -0,0 +1,42 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.json.bvtVO.DataTransaction; + + +public class Bug_for_dargoner extends TestCase { + public void test_0 () throws Exception { + DataTransaction dt = new DataTransaction(); + + List> list = new ArrayList>(); + + Map m = new HashMap(); + m.put("name", "tom"); + m.put("sex", "m"); + list.add(m); + + dt.setDataSet("1000", list); + dt.setRetMsgCode("1", "ok"); + dt.getHead().setAppid("back"); + dt.getHead().setSeqno("201010"); + dt.getHead().getUser().setId("root"); + + Map m2 = new HashMap(); + m2.put("name1", "tom"); + m2.put("name2", "tom"); + m2.put("name3", "tom"); + + dt.getBody().getParam().setForm(m2); + + System.out.println(dt.toJSON()); + + DataTransaction dt2 = DataTransaction.fromJSON(dt.toJSON()); + System.out.println(dt2.toJSON()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_divde_zero.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_divde_zero.java new file mode 100755 index 0000000000..22d713e927 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_divde_zero.java @@ -0,0 +1,14 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + + +public class Bug_for_divde_zero extends TestCase { + public void test_divideZero() throws Exception { + Double d = 1.0D / 0.0D; + String text = JSON.toJSONString(d); + System.out.println(text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dongqi.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dongqi.java new file mode 100644 index 0000000000..16a09a628b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dongqi.java @@ -0,0 +1,20 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class Bug_for_dongqi extends TestCase { + public void test_bug() throws Exception { + Map obj = new HashMap(); + obj.put("value", ";\r\n3、ž 公"); + System.out.print(JSON.toJSONString(obj)); + Assert.assertEquals("{\"value\":\";\\r\\n3、\\u009E 公\"}", JSON.toJSONString(obj)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dragoon.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dragoon.java new file mode 100755 index 0000000000..a19cb3cac2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dragoon.java @@ -0,0 +1,12 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_dragoon extends TestCase { + public void test_for_dragoon() throws Exception { + String text = "[{\"S\":93803,\"T\":\"HSMonitorData\"},{\"D\":\"H4sIAAAAAAAAAO1b3W8bxxF/7n9xvRqFipKX+ySPBARYkdVGqS2pEu0UJQVhebckzzzeXu9DNqPqIQECpCiaBG0fWthNH2oDRT8egqKI4LTxP2Pazn+R2d078sQvW7KdWMFakMib2f3N7M7szNzduHkkozDcSgdyXfaS9KD37gHyw4MExX25JDvE97GTXEEJluuaYZo1Q63o1ZphAy/CQJ5i2bah5ayGN8DXPN+PZ/g4SCIPA/1IXidpkMh1vSRfRXHS6EXk1hSkVjOsAvcajmPUhQHyRhSRSBqQwEvg0yddRWpGOCRRsumuchUOSOTiqCRFqY/XSdDxuqsOGSjI99qojZRsruIwlrI7HnXZcNp6260ZTTrzZ3i4Sj8VhvZGGtzCuI8D941aWbNLMNn1Eo8E8erR+Ltyi0R9Fw2XiQvJTaJc47T1fOLlKmo7mqtWStIErEfS6OxIlqlZbcN1i0gDL0gTHJ8DzHGNmmu2j0vIyRbLvyi3UNClv8+LucamXXYdDWsOLkkZDB4gzz8jhmE4HaRX1WNqhASAcAR6HZcY1lUvTlab+6UBaXs+zq9ybfNratfn84lL9Otls63ZGjKa+UZqailIB20cbXeov8erFmBi5PMLteTFMDuBwXi1g/wYgz7cgVd/2dgefXhn9MWD0f/eH52cfF9qBU+//MPog/v1o5YcwRKifkuut2Q37rTkUkt2UNQlW2iAM6rLyQlJkL/FVACGYQCJrn6LsGGabphWhQ2MwWPZGIBHrhuBGnARpL4PzCDH/eqffxp9+fmTB//hMskgRMFwLPXRyb9Hd/6/9sMbj+/+5qs/fzL64F+jj0/YyDAih17g8GGjzz57dHL3yd33OIiXDDn57+89/u/no5P3M2w4+Zzx9Hd/e/zhJzmDG2yiW0jiZJ24RUqPBFySalWr5YplWHSZZTYdDLmTKZPNasm6bVZz5jqoU2DUzDGDKVRk2S35GHjtNPYC2K4tnNBjzbY21wQNG8Mw04UBQRwC1/KczSuMuHZVtVX4Z9hVCgcDvCBOIwTa7USeU1jUmH4D+WmBTpIejqbGhsjpgw/t4ehwCX1qEvOUG8RPmTFVRc1p72Cv20uApnEaaBHTMDo1H7boerYqA6JyTTWzFXUHYJ/BwGMQNGzrFdXUYdG5gCmgCDvYO5z1RfDRmH4p+mNOmPbEnD7td0/vP5z1u3v/GH301zl+N/r43qMH92b8Lj82JniVxqUsdMHJ3sw6XVW35ztdVa8tcrqqoXGnG2B6pMfOtf6LRr7eAaHBbyKbHuy9BEUJjTmnyRuBe5qYe+c6387MnBCKQCjEn4d/HN35lBplMzgkfVxEBd1UTVdtDbKKpeqabWs/pq7NtOLD12GXstFVIMLsJI25kbMFWiqNT1kKZ6CZq0rXA3QIYQu1qQXo+ncx+GAQYwrQPHpRNExrhQMn32aYyfTm5EEBoZckoeSx5UgekdiAutSDlUGoV3RVgfUrFUvCtx0cUjvUH//290+++MvTh58+/ug+B81ZLwXweP94X/q1hAgK+WQpZjshrPSaWQnK5Ws46REXSlOXXCVdIMB2OP1GhBxar7YCo6KptmmqptSkZiqrdlkzJc2CParr2r5UliSp6YWrULDiDvxNEfyJPXd1vxVI0sbu7vau5CiTGiUrnXg19BYKXB9HzVNXyk3Y4nqlSrFFvSzqZVEvi3pZ1MuiXhb1sqiXv7OVGFRLxQyF/FBBLgoh2ynEwQgKJt/bDnGwtrO5MUYRFfZrb9dW8D2USItMG/M1K9vUxGucmO3D5iD0lS5OdqHQeJO4w5VFY1i1XDV+JDULyGUI84pa3tta29l7a7sBg6L6adL+i2nGa+/lSmn2ebWK00CB2wn6HF/5KQ5wBLJcfqey5jhgchJppqpw06xcD/oBuRVIe1BCOxhEBqgeoDlQV7CPuwgqte5pLKZyBrZ0DFuWbnERYHpFPdCtTBDlKT6UnWNxHCAHzq4YhFWrzsUgUVeJwwiEdyLIgrQSURAJlTgNabJW1kh4PfH8OMN8m3hBCL/JdSheurtcLLjhyngck2aoVFrMdqcDInAmo6wrFsjf21hXdWaLwvUzFJpc5VIPMV8gDScOYuX+lJIrS4Zm/qJ/K3pCvnUwdp+tn1k7r37FY+ZGqEuoWJRExM8wlCucmkuG00JjCtyk5H65iM9VU6lqGXIZpMEtDqhVUWym0Pg0fDP7VNVenR3fdvtXhlA6eg44OdRjt4f5Ds3h8POqmudV5xKDsew83C2NNNOhtO29y58mjIPpxu3kalacxduUMxtRZ4asLJ3EFsiOTSbxpYZYwxIhVoRYEWJFiH3lIba2MP69opjLtT9r0C2s2TpP1J2nb36/Ho91HosuhPpLhuKSzaBBH9zwx6kr84Zx3UzNOIdy8zwjmcgbh8iCDg0MMmEHFXwbOylkyHk87rG6/TJO9tk2bWJfZsQ3h+xj012ydUZNfVXZ1BDZVGRTkU1FNn3V2bSiLgx8Z8qmAUm8zpBFWMiovez17DqDZoANFPfzt7bZohZw+bnOUX2012-08-14 15:51:13+Yp4HMnz9Pq5XlgzQ+3GGOP0YsBPk9SS4bwp2nVl6FnTDqJgvAExelhN0W+wmVvMGXgPERpsDJF4km8QrWA+bSxNQNhOpw6ICyKpxA76dtMJ40iHECG7oEV3B1C/Bzy0jvgi5gJo2ZZmR2R3UvalcXJ4kxiFoqoqfYz8hGfWQDJWgIq+sxEuSTT9ydyXT7z43P5uCTTZ7n0fRPMPxyUf4XKTlDWTK2sVVWlFydK+6aj9DsOBXYdJcAJyPMCmMOajycXG7fPhBDC6MkTZBgKxOyl9GaCB5uuXK9UtZptnSLThVLWhMr9l4umtRZEC6aDZtXKtQqAhh5t7dA1XacisiPSQF0gqoa68ZOf0+YOVVUrVfsHGmzIBeis1o25ndVcSvYypE3coRThOPUT8UbkNXsjUuw54kZb1HRk1IwXbDqiP/GidxjN5S8vakyOcKsL4lbPkwqe8VJLJIQLmRCotDkJIUS0BAcLS5nr0nYwyYslPAiTYTEK0S4KqA8S5PfjxQ2Q1RdtgFT4XY6SiSpGollSViqZFH/5ShY5/qTJbYFU4e4X0t2fp/5hHhOLJkPRZCiaDEWT4TfdZCj+68cFqJcvzG2YOnMbJrKbyG4iu4ns9m210ItG7e9gPhSN2qJRW/Q9iL4H0fdwcfseRKO2CLEixIoQK0KsaNQWjdqiUVs0aotsKrKpyKavbTYVjdqiUVs0aotG7TM3Ku1/DWGrUgYEWwAA\"}]"; + JSON.parse(text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dragoon26.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dragoon26.java new file mode 100755 index 0000000000..3798bf56f6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dragoon26.java @@ -0,0 +1,175 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_dragoon26 extends TestCase { + + public void test_0() throws Exception { + MonitorConfigMessage message = new MonitorConfigMessage(); + MonitorConfig config = new MonitorConfig(); + message.setContent(config); + + AlarmReceiver receiver1 = new AlarmReceiver(2001L); + AlarmReceiver receiver2 = new AlarmReceiver(2002L); + AlarmReceiver receiver3 = new AlarmReceiver(2003L); + + ArrayList items = new ArrayList(); + { + MonitorItem item1 = new MonitorItem(); + item1.setId(1001L); + + MonitorItemAlarmRule rule = new MonitorItemAlarmRule(); + + rule.getAlarmReceivers().add(receiver1); + rule.getAlarmReceivers().add(receiver2); + + item1.getRules().add(rule); + items.add(item1); + } + + { + + MonitorItem item = new MonitorItem(); + item.setId(1002L); + + MonitorItemAlarmRule rule = new MonitorItemAlarmRule(); + + rule.getAlarmReceivers().add(receiver1); + rule.getAlarmReceivers().add(receiver3); + + item.getRules().add(rule); + items.add(item); + } + { + + MonitorItem item = new MonitorItem(); + item.setId(1003L); + + MonitorItemAlarmRule rule = new MonitorItemAlarmRule(); + + rule.getAlarmReceivers().add(receiver2); + rule.getAlarmReceivers().add(receiver3); + + item.getRules().add(rule); + items.add(item); + } + + config.setMonitorItems(items); + + String text = JSON.toJSONString(message, SerializerFeature.WriteClassName); + System.out.println(JSON.toJSONString(message, SerializerFeature.WriteClassName, SerializerFeature.PrettyFormat)); + + MonitorConfigMessage message2 = (MonitorConfigMessage) JSON.parse(text); + System.out.println(JSON.toJSONString(message2, SerializerFeature.WriteClassName, SerializerFeature.PrettyFormat)); + } + + public static class MonitorConfigMessage { + + private Object content; + + public Object getContent() { + return content; + } + + public void setContent(Object content) { + this.content = content; + } + + } + + public static class MonitorConfig { + + private Map monitorItems = new HashMap(); + + @JSONField(name = "MonitorItems") + public Collection getMonitorItems() { + return monitorItems.values(); + } + + @JSONField(name = "MonitorItems") + public void setMonitorItems(Collection items) { + for (MonitorItem item : items) { + this.monitorItems.put(item.getId(), item); + } + } + } + + public static class MonitorItem extends MonitorItemBase { + + } + + public static class MonitorItemBase { + + private Long id; + private List rules = new ArrayList(); + + @JSONField(name = "mid") + public Long getId() { + return id; + } + + @JSONField(name = "mid") + public void setId(Long id) { + this.id = id; + } + + public List getRules() { + return rules; + } + + public void setRules(List rules) { + this.rules = rules; + } + + } + + public static class AlarmRuleBase { + + } + + public static class MonitorItemAlarmRule extends AlarmRuleBase { + + private List alarmReceivers = new ArrayList(); + + public List getAlarmReceivers() { + return alarmReceivers; + } + + public void setAlarmReceivers(List alarmReceivers) { + this.alarmReceivers = alarmReceivers; + } + + } + + public static class AlarmReceiver { + + private Long id; + + public AlarmReceiver(){ + + } + + public AlarmReceiver(Long id){ + this.id = id; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dragoon26_1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dragoon26_1.java new file mode 100755 index 0000000000..059b955c74 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dragoon26_1.java @@ -0,0 +1,74 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_dragoon26_1 extends TestCase { + + public void test_0() throws Exception { + + List rules = new ArrayList(); + + AlarmReceiver receiver1 = new AlarmReceiver(1L); + + { + MonitorItemAlarmRule rule = new MonitorItemAlarmRule(); + + rule.getAlarmReceivers().add(receiver1); + rules.add(rule); + } + { + MonitorItemAlarmRule rule = new MonitorItemAlarmRule(); + + rule.getAlarmReceivers().add(receiver1); + rules.add(rule); + } + + String text = JSON.toJSONString(rules, SerializerFeature.WriteClassName); + System.out.println(JSON.toJSONString(rules, SerializerFeature.WriteClassName, SerializerFeature.PrettyFormat)); + + List message2 = (List) JSON.parse(text); + System.out.println(JSON.toJSONString(message2, SerializerFeature.WriteClassName, SerializerFeature.PrettyFormat)); + } + + public static class MonitorItemAlarmRule { + + private List alarmReceivers = new ArrayList(); + + public List getAlarmReceivers() { + return alarmReceivers; + } + + public void setAlarmReceivers(List alarmReceivers) { + this.alarmReceivers = alarmReceivers; + } + + } + + public static class AlarmReceiver { + + private Long id; + + public AlarmReceiver(){ + + } + + public AlarmReceiver(Long id){ + this.id = id; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo.java new file mode 100755 index 0000000000..5e2eff136a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo.java @@ -0,0 +1,31 @@ +package com.alibaba.json.bvt.bug; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.json.test.dubbo.HelloServiceImpl; +import com.alibaba.json.test.dubbo.Tiger; +import com.alibaba.json.test.dubbo.Tigers; + + +public class Bug_for_dubbo extends TestCase { + public void test_0 () throws Exception { + HelloServiceImpl helloService = new HelloServiceImpl(); + + Tiger tiger = new Tiger(); + tiger.setTigerName("东北虎"); + tiger.setTigerSex(true); + //Tiger tigers = helloService.eatTiger(tiger).getTiger(); + + Tigers tigers = helloService.eatTiger(tiger); + Assert.assertNotNull(tigers.getTiger()); + + String text = JSON.toJSONString(tigers, SerializerFeature.WriteClassName); + + System.out.println(text); + Tigers tigers1 = (Tigers) JSON.parse(text); + Assert.assertNotNull(tigers1.getTiger()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo1.java new file mode 100755 index 0000000000..9dc0c72476 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo1.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.bug; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_dubbo1 extends TestCase { + + public void test_0() throws Exception { + String text; + { + HashSet tigers = new HashSet(); + tigers.add("老虎二"); + tigers.add("老虎大"); + HashMap> tiger = new HashMap>(); + tiger.put("老鼠", tigers); + + text = JSON.toJSONString(tiger, SerializerFeature.WriteClassName); + } + + System.out.println(text); + + HashMap> tigger2 = (HashMap>) JSON.parse(text); + Assert.assertEquals(1, tigger2.size()); + Assert.assertEquals(2, tigger2.get("老鼠").size()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo2.java new file mode 100755 index 0000000000..2b7d7f3b4f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo2.java @@ -0,0 +1,30 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_dubbo2 extends TestCase { + public void test_emptyHashMap() throws Exception { + VO vo = new VO(); + vo.setValue(new HashMap()); + String text = JSON.toJSONString(vo, SerializerFeature.WriteClassName); + JSON.parse(text); + } + + public static class VO { + private Object value; + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo3.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo3.java new file mode 100755 index 0000000000..6678eaf7db --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo3.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.bug; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_dubbo3 extends TestCase { + + public void test_0() throws Exception { + String text; + { + HashSet tigers = new HashSet(); + tigers.add("老虎二"); + tigers.add("老虎大"); + HashMap> tiger = new HashMap>(); + tiger.put("老鼠", tigers); + + text = JSON.toJSONString(tiger, SerializerFeature.WriteClassName); + } + + System.out.println(text); + + HashMap> tigger2 = (HashMap>) JSON.parseObject(text, Map.class); + Assert.assertEquals(1, tigger2.size()); + Assert.assertEquals(2, tigger2.get("老鼠").size()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo_long.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo_long.java new file mode 100755 index 0000000000..8912bba332 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_dubbo_long.java @@ -0,0 +1,17 @@ +package com.alibaba.json.bvt.bug; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_dubbo_long extends TestCase { + + public void test_0() throws Exception { + Long val = 2345L; + + String text = JSON.toJSONString(val, SerializerFeature.WriteClassName); + Assert.assertEquals(val, JSON.parseObject(text, long.class)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_field.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_field.java new file mode 100755 index 0000000000..37498ce4a8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_field.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_field extends TestCase { + + public void test_annotation() throws Exception { + VO vo = new VO(); + vo.setId(123); + + String text = JSON.toJSONString(vo); + + System.out.println(text); + } + + public static class VO { + + @JSONField(name = "ID", serialzeFeatures={SerializerFeature.WriteClassName}) + private long id; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_franklee77.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_franklee77.java new file mode 100755 index 0000000000..991d93c8e9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_franklee77.java @@ -0,0 +1,32 @@ +package com.alibaba.json.bvt.bug; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_franklee77 extends TestCase { + + public void test_0() throws Exception { + VO vo = JSON.parseObject("{\"id\":33}", VO.class); + Assert.assertEquals(33, vo.getId()); + + } + + public static class VO { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + private VO(){ + + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_generic.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_generic.java new file mode 100755 index 0000000000..f64629ab29 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_generic.java @@ -0,0 +1,312 @@ +package com.alibaba.json.bvt.bug; + +import java.io.Serializable; +import java.sql.Date; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_generic extends TestCase { + + public void test() throws Exception { + String json = "{\"@type\":\"com.alibaba.json.bvt.bug.Bug_for_generic$NotifyDetail\",\"args\":[\"61354557\",\"依依\",\"六\"],\"destId\":60721687,\"detailId\":3155063,\"display\":false,\"foundTime\":{\"@type\":\"java.sql.Timestamp\",\"val\":1344530416000},\"hotId\":0,\"srcId\":1000,\"templateId\":482}"; + JSON.parseObject(json, NotifyDetail.class); + System.out.println("NotifyDetail对象没问题"); + String json2 = "{\"@type\":\"com.alibaba.json.bvt.bug.Bug_for_generic$Pagination\",\"fromIndex\":0,\"list\":[{\"@type\":\"NotifyDetail\",\"args\":[\"61354557\",\"依依\",\"六\"],\"destId\":60721687,\"detailId\":3155063,\"display\":false,\"foundTime\":{\"@type\":\"java.sql.Timestamp\",\"val\":1344530416000},\"hotId\":0,\"srcId\":1000,\"templateId\":482},{\"@type\":\"NotifyDetail\",\"args\":[\"14527269\",\"懒洋洋\",\"///最佳拍档,非常\",\"24472950\"],\"destId\":60721687,\"detailId\":3151609,\"display\":false,\"foundTime\":{\"@type\":\"java.sql.Timestamp\",\"val\":1344354485000},\"hotId\":0,\"srcId\":1000,\"templateId\":40},{\"@type\":\"NotifyDetail\",\"args\":[\"51090218\",\"天之涯\",\"天会黑,人会变。三分\"],\"destId\":60721687,\"detailId\":3149221,\"display\":false,\"foundTime\":{\"@type\":\"java.sql.Timestamp\",\"val\":1344247529000},\"hotId\":0,\"srcId\":1000,\"templateId\":459},{\"@type\":\"NotifyDetail\",\"args\":[\"51687981\",\"摹然回首梦已成年\",\"星星在哪里都很亮的,\"],\"destId\":60721687,\"detailId\":3149173,\"display\":false,\"foundTime\":{\"@type\":\"java.sql.Timestamp\",\"val\":1344247414000},\"hotId\":0,\"srcId\":1000,\"templateId\":459},{\"@type\":\"NotifyDetail\",\"args\":[\"41486427\",\"寒江蓑笠\",\"双休了\"],\"destId\":60721687,\"detailId\":3148148,\"display\":false,\"foundTime\":{\"@type\":\"java.sql.Timestamp\",\"val\":1344244730000},\"hotId\":0,\"srcId\":1000,\"templateId\":459}],\"maxLength\":5,\"nextPage\":2,\"pageIndex\":1,\"prevPage\":1,\"toIndex\":5,\"totalPage\":3,\"totalResult\":13}"; + JSON.parseObject(json2, Pagination.class); + } + + public static class Pagination implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 5038839734218582220L; + + private int totalResult = 0; + + private int totalPage = 1; + + private int pageIndex = 1; + + private int maxLength = 5; + + private int fromIndex = 0; + + private int toIndex = 0; + + private List list = new ArrayList(); + + public Pagination(){ + + } + + public void setTotalResult(int totalResult) { + this.totalResult = totalResult; + } + + public void setTotalPage(int totalPage) { + this.totalPage = totalPage; + } + + public void setPageIndex(int pageIndex) { + this.pageIndex = pageIndex; + } + + public void setMaxLength(int maxLength) { + this.maxLength = maxLength; + } + + public void setFromIndex(int fromIndex) { + this.fromIndex = fromIndex; + } + + public void setToIndex(int toIndex) { + this.toIndex = toIndex; + } + + public int getFromIndex() { + return this.fromIndex; + } + + public int getToIndex() { + return this.toIndex; + } + + public int getNextPage() { + if (this.pageIndex < this.totalPage) { + return this.pageIndex + 1; + } else { + return this.pageIndex; + } + } + + public int getPrevPage() { + if (this.pageIndex > 1) { + return this.pageIndex - 1; + } + return this.pageIndex; + } + + /** + * @return the currentPage + */ + public int getPageIndex() { + return pageIndex; + } + + /** + * @return the list + */ + public List getList() { + if (list == null) { + return new ArrayList(); + } + return new ArrayList(list); + } + + /** + * @return the totalPage + */ + public int getTotalPage() { + return totalPage; + } + + /** + * @return the totalRecord + */ + public int getTotalResult() { + return totalResult; + } + + public int getMaxLength() { + return maxLength; + } + + /** + * @param totalResult + * @param pageIndex + * @param maxLength + */ + public Pagination(int totalResult, int pageIndex, int maxLength){ + if (maxLength > 0) { + this.maxLength = maxLength; + } + if (totalResult > 0) { + this.totalResult = totalResult; + } + if (pageIndex > 0) { + this.pageIndex = pageIndex; + } + this.totalPage = this.totalResult / this.maxLength; + if (this.totalResult % this.maxLength != 0) { + this.totalPage = this.totalPage + 1; + } + if (this.totalPage == 0) { + this.totalPage = 1; + } + if (this.pageIndex > this.totalPage) { + this.pageIndex = this.totalPage; + } + if (this.pageIndex <= 0) { + this.pageIndex = 1; + } + this.fromIndex = (this.pageIndex - 1) * maxLength; + this.toIndex = this.fromIndex + maxLength; + if (this.toIndex < 0) { + this.toIndex = fromIndex; + } + if (this.toIndex > this.totalResult) { + this.toIndex = this.totalResult; + } + + } + + /** + * @param datas the datas to set + */ + public void setList(List list) { + this.list = list; + } + + /* + * (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("Pagination:\r\n"); + sb.append("\tpageIndex\t" + this.pageIndex + "\r\n"); + sb.append("\ttotalPage\t" + this.totalPage + "\r\n"); + sb.append("\tmaxLength\t" + this.maxLength + "\r\n"); + sb.append("\ttotalResult\t" + this.totalResult + "\r\n"); + for (T t : list) { + sb.append(t + "\r\n"); + } + return sb.toString(); + } + + } + + public static class NotifyDetail implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 8760630447394929224L; + + private int detailId; + + private int hotId; + + private int templateId; + + private int srcId; + + private int destId; + + private boolean display; + + private Date foundTime; + + private List args = new ArrayList(); + + public int getDetailId() { + return detailId; + } + + public void setDetailId(int detailId) { + this.detailId = detailId; + } + + public int getHotId() { + return hotId; + } + + public void setHotId(int hotId) { + this.hotId = hotId; + } + + public int getTemplateId() { + return templateId; + } + + public List getArgs() { + return args; + } + + public void setArgs(List args) { + this.args = args; + } + + public void setTemplateId(int templateId) { + this.templateId = templateId; + } + + public int getSrcId() { + return srcId; + } + + public void setSrcId(int srcId) { + this.srcId = srcId; + } + + public int getDestId() { + return destId; + } + + public void setDestId(int destId) { + this.destId = destId; + } + + public boolean isDisplay() { + return display; + } + + public void setDisplay(boolean display) { + this.display = display; + } + + public Date getFoundTime() { + return foundTime; + } + + public void setFoundTime(Date foundTime) { + this.foundTime = foundTime; + } + + /* + * (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + int hasCode = 0; + if (this.detailId != 0) { + hasCode += this.detailId; + } + return hasCode; + } + + /* + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (!(obj instanceof NotifyDetail)) { + return false; + } + return this.hashCode() == obj.hashCode(); + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_generic_1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_generic_1.java new file mode 100755 index 0000000000..b2d85de76b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_generic_1.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; +import cn.com.tx.domain.notifyDetail.NotifyDetail; +import cn.com.tx.domain.pagination.Pagination; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class Bug_for_generic_1 extends TestCase { + + public void test() { + String json2 = "{\"@type\":\"cn.com.tx.domain.pagination.Pagination\",\"fromIndex\":0,\"list\":[{\"@type\":\"cn.com.tx.domain.notifyDetail.NotifyDetail\",\"args\":[\"61354557\",\"依依\",\"六\"],\"destId\":60721687,\"detailId\":3155063,\"display\":false,\"foundTime\":{\"@type\":\"java.sql.Timestamp\",\"val\":1344530416000},\"hotId\":0,\"srcId\":1000,\"templateId\":482},{\"@type\":\"cn.com.tx.domain.notifyDetail.NotifyDetail\",\"args\":[\"14527269\",\"懒洋洋\",\"///最佳拍档,非常\",\"24472950\"],\"destId\":60721687,\"detailId\":3151609,\"display\":false,\"foundTime\":{\"@type\":\"java.sql.Timestamp\",\"val\":1344354485000},\"hotId\":0,\"srcId\":1000,\"templateId\":40},{\"@type\":\"cn.com.tx.domain.notifyDetail.NotifyDetail\",\"args\":[\"51090218\",\"天之涯\",\"天会黑,人会变。三分\"],\"destId\":60721687,\"detailId\":3149221,\"display\":false,\"foundTime\":{\"@type\":\"java.sql.Timestamp\",\"val\":1344247529000},\"hotId\":0,\"srcId\":1000,\"templateId\":459},{\"@type\":\"cn.com.tx.domain.notifyDetail.NotifyDetail\",\"args\":[\"51687981\",\"摹然回首梦已成年\",\"星星在哪里都很亮的,\"],\"destId\":60721687,\"detailId\":3149173,\"display\":false,\"foundTime\":{\"@type\":\"java.sql.Timestamp\",\"val\":1344247414000},\"hotId\":0,\"srcId\":1000,\"templateId\":459},{\"@type\":\"cn.com.tx.domain.notifyDetail.NotifyDetail\",\"args\":[\"41486427\",\"寒江蓑笠\",\"双休了\"],\"destId\":60721687,\"detailId\":3148148,\"display\":false,\"foundTime\":{\"@type\":\"java.sql.Timestamp\",\"val\":1344244730000},\"hotId\":0,\"srcId\":1000,\"templateId\":459}],\"maxLength\":5,\"nextPage\":2,\"pageIndex\":1,\"prevPage\":1,\"toIndex\":5,\"totalPage\":3,\"totalResult\":13}"; + cn.com.tx.domain.pagination.Pagination pagination = JSON.parseObject(json2, + new TypeReference>() { + }); + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_gongwenhua.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_gongwenhua.java new file mode 100644 index 0000000000..180b62fedd --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_gongwenhua.java @@ -0,0 +1,20 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONObject; + +public class Bug_for_gongwenhua extends TestCase { + + public void test_0() throws Exception { + String text = "{\"FH2\\\"\u0005\\v\u0010\u000e\u0011\u0000\":0,\"alipa9_login\":0,\"alipay_login\":14164,\"durex\":317,\"intl.datasky\":0,\"taobao_refund\":880}"; + + JSONObject obj = JSONObject.parseObject(text); + Assert.assertNotNull(obj); + Assert.assertEquals(0, obj.get("FH2\"\u0005\u000B\u0010\u000e\u0011\u0000")); + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_hmy8.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_hmy8.java new file mode 100755 index 0000000000..97dbe33e00 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_hmy8.java @@ -0,0 +1,17 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.json.bvtVO.IEvent; +import com.alibaba.json.bvtVO.IEventDto; + +public class Bug_for_hmy8 extends TestCase { + + public void test_ser() throws Exception { + IEventDto dto = new IEventDto(); + dto.getEventList().add(new IEvent()); + + JSON.toJSONString(dto); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_huangchun.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_huangchun.java new file mode 100755 index 0000000000..59e93982fc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_huangchun.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + + +public class Bug_for_huangchun extends TestCase { + public void test_serialize_url() throws Exception { + JSONObject json = new JSONObject(); + json.put("info", " 问题链接 "); + String text = JSON.toJSONString(json); + System.out.println(text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_huling.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_huling.java new file mode 100755 index 0000000000..b08fabf56a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_huling.java @@ -0,0 +1,66 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_huling extends TestCase { + + public void test_for_0() throws Exception { + VO vo = new VO(); + vo.setValue("\0\0"); + + Assert.assertEquals('\0', vo.getValue().charAt(0)); + + String text = JSON.toJSONString(vo); + System.out.println(text); + Assert.assertEquals("{\"value\":\"\\u0000\\u0000\"}", text); + + VO vo2 = JSON.parseObject(text, VO.class); + Assert.assertEquals("\0\0", vo2.getValue()); + } + + public void test_for_1() throws Exception { + VO vo = new VO(); + vo.setValue("\1\1"); + + Assert.assertEquals('\1', vo.getValue().charAt(0)); + + String text = JSON.toJSONString(vo); + System.out.println(text); + Assert.assertEquals("{\"value\":\"\\u0001\\u0001\"}", text); + + VO vo2 = JSON.parseObject(text, VO.class); + Assert.assertEquals("\1\1", vo2.getValue()); + } + + public void test_for_2028() throws Exception { + VO vo = new VO(); + vo.setValue("\u2028\u2028"); + + Assert.assertEquals('\u2028', vo.getValue().charAt(0)); + + String text = JSON.toJSONString(vo); + System.out.println(text); + Assert.assertEquals("{\"value\":\"\\u2028\\u2028\"}", text); + + VO vo2 = JSON.parseObject(text, VO.class); + Assert.assertEquals("\u2028\u2028", vo2.getValue()); + } + + public static class VO { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_issue_242.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_issue_242.java new file mode 100644 index 0000000000..b33eb51ad5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_issue_242.java @@ -0,0 +1,129 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_issue_242 extends TestCase { + + public void test_true() throws Exception { + final String text = "{int1:\"NULL\",int2:\"null\",long1:NULL,long2:null, dou1:\"NULL\",dou2:\"null\",str1:\"NULL\",str2:NULL, bool2:\"NULL\",bool1:null}"; + VO vo = JSON.parseObject(text, VO.class); + + System.out.println(vo); + } + + public static class VO { + + public int int1; + public int int2; + public long long1; + public long long2; + public double dou1; + public double dou2; + public boolean bool1; + public boolean bool2; + public String str1; + public String str2; + + public VO(){ + + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("int1 = ").append(int1)// + .append(" int2 = ").append(int2)// + .append(" long1 = ").append(long1)// + .append(" long2 = ").append(long2)// + .append(" dou1 = ").append(dou1)// + .append(" dou2 = ").append(dou2)// + .append(" bool1 = ").append(bool1)// + .append(" bool2 = ").append(bool2)// + .append(" str1 = ").append(str2)// + .append(" str2 = ").append(str2); + return sb.toString(); + } + + public int getInt1() { + return int1; + } + + public void setInt1(int int1) { + this.int1 = int1; + } + + public int getInt2() { + return int2; + } + + public void setInt2(int int2) { + this.int2 = int2; + } + + public long getLong1() { + return long1; + } + + public void setLong1(long long1) { + this.long1 = long1; + } + + public long getLong2() { + return long2; + } + + public void setLong2(long long2) { + this.long2 = long2; + } + + public double getDou1() { + return dou1; + } + + public void setDou1(double dou1) { + this.dou1 = dou1; + } + + public double getDou2() { + return dou2; + } + + public void setDou2(double dou2) { + this.dou2 = dou2; + } + + public boolean isBool1() { + return bool1; + } + + public void setBool1(boolean bool1) { + this.bool1 = bool1; + } + + public boolean isBool2() { + return bool2; + } + + public void setBool2(boolean bool2) { + this.bool2 = bool2; + } + + public String getStr1() { + return str1; + } + + public void setStr1(String str1) { + this.str1 = str1; + } + + public String getStr2() { + return str2; + } + + public void setStr2(String str2) { + this.str2 = str2; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jared1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jared1.java new file mode 100755 index 0000000000..acb13cc9ef --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jared1.java @@ -0,0 +1,86 @@ +package com.alibaba.json.bvt.bug; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_jared1 extends TestCase { + public void test_for_jared1() throws Exception { + User user = new User(); + + String text = JSON.toJSONString(user); + + System.out.println(text); + + JSON.parseObject(text, User.class); + } + + public static class User implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private Integer id; + + private String acount; + + private String password; + + private Set crowds = new HashSet(); + + private Set friends = new HashSet(); + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getAcount() { + return acount; + } + + public void setAcount(String acount) { + this.acount = acount; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Set getCrowds() { + return crowds; + } + + public void setCrowds(Set crowds) { + this.crowds = crowds; + } + + public Set getFriends() { + return friends; + } + + public void setFriends(Set friends) { + this.friends = friends; + } + + // 一下省略 + + } + + public static class Crowd { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_javaeye_litterJava.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_javaeye_litterJava.java new file mode 100755 index 0000000000..885683bdee --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_javaeye_litterJava.java @@ -0,0 +1,53 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_javaeye_litterJava extends TestCase { + public void test_for_bug() throws Exception { + Group group = new Group(); + group.setId(123L); + group.setName("xxx"); + group.getClzes().add(Group.class); + + String text = JSON.toJSONString(group); + JSON.parseObject(text, Group.class); + } + + public static class Group { + + private Long id; + private String name; + private List clzes = new ArrayList(); + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getClzes() { + return clzes; + } + + public void setClzes(List clzes) { + this.clzes = clzes; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jial10802.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jial10802.java new file mode 100755 index 0000000000..fe1b048b98 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jial10802.java @@ -0,0 +1,32 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.json.bvtVO.Bean; +import com.alibaba.json.bvtVO.Page; + +import junit.framework.TestCase; + + +public class Bug_for_jial10802 extends TestCase { + public void test_for_jial10802() throws Exception { + Page page = new Page(); + page.setCount(1); + List items = new ArrayList(); + Bean item = new Bean(); + item.setId(1); + item.setName("name"); + item.setDesc("desc"); + items.add(item); + page.setItems(items); + String json = JSON.toJSONString(page, SerializerFeature.PrettyFormat); + + Page jsonPage = JSON.parseObject(json, new TypeReference>() { + }); + System.out.println(jsonPage.getItems().get(0).getName()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jiangwei.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jiangwei.java new file mode 100755 index 0000000000..835fbc5dbc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jiangwei.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + + +public class Bug_for_jiangwei extends TestCase { + public void test_0 () throws Exception { + String text = "['42-0','超級聯隊\\x28中\\x29','辛當斯','1.418',10,'11/18/2012 02:15',1,0,1,0,'',0,0,0,0]"; + JSON.parse(text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jiangwei1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jiangwei1.java new file mode 100755 index 0000000000..d98844a4b6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jiangwei1.java @@ -0,0 +1,21 @@ +package com.alibaba.json.bvt.bug; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; + +public class Bug_for_jiangwei1 extends TestCase { + + public void test_double() throws Exception { + JSONObject json = JSON.parseObject("{\"val\":12.3}"); + Assert.assertTrue(12.3D == json.getDoubleValue("val")); + } + + public void test_JSONArray_double() throws Exception { + JSONArray json = JSON.parseArray("[12.3]"); + Assert.assertTrue(12.3D == json.getDoubleValue(0)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jiangwei2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jiangwei2.java new file mode 100755 index 0000000000..222be108c0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jiangwei2.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; + +public class Bug_for_jiangwei2 extends TestCase { + public void test_for_jiangwei() throws Exception { +// String str = "[2,'韩国篮球联赛','仁川大象(男篮)','首尔SK骑士 男篮',['大/小',3],'总进球 : 138.5 @ 0-0','','大','0.66','',1,25,200,1,0,0,'True','False',0,'','','',0,0,19819905,1,'h',145528,0]"; +// JSONArray array = JSON.parseArray(str); + String str = "[]"; + str = "[]"; + JSONArray array = JSON.parseArray(str); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jinghui70.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jinghui70.java new file mode 100755 index 0000000000..7129a9fb8b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jinghui70.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.bug; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_jinghui70 extends TestCase { + + public static abstract class IdObject { + + private I id; + + public I getId() { + return id; + } + + public void setId(I id) { + this.id = id; + } + } + + public static class Child extends IdObject { + + } + + public void test_generic() throws Exception { + String str = "{\"id\":0}"; + + Child child = JSON.parseObject(str, Child.class); + Assert.assertEquals(Long.class, child.getId().getClass()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jinguwei.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jinguwei.java new file mode 100755 index 0000000000..489b90d1a1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jinguwei.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.fastjson.JSON; + +import org.junit.Assert; +import junit.framework.TestCase; + +public class Bug_for_jinguwei extends TestCase { + + public void test_null() throws Exception { + VO vo = new VO(); + vo.setList(new ArrayList()); + vo.getList().add(null); + vo.getList().add(null); + + Assert.assertEquals("{\"list\":[null,null]}", JSON.toJSONString(vo)); + } + + public static class VO { + private List list; + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_json_array.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_json_array.java new file mode 100644 index 0000000000..1d165952e6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_json_array.java @@ -0,0 +1,56 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_json_array extends TestCase { + + public void test_bug() throws Exception { + String jsonStr = "{\"state\":0,\"data\":[{\"items\":[{\"tip\":\"\u5218\u82e5\u82f1\",\"url\":\"xiami:\\/\\/artist\\/1930\"},{\"tip\":\"\u5218\u5fb7\u534e\",\"url\":\"xiami:\\/\\/artist\\/648\"}],\"type\":\"artist\"},{\"items\":[{\"tip\":\"\u6f02\u6d0b\u8fc7\u6d77\u6765\u770b\u4f60 (Live) - \u5218\u660e\u6e58\",\"url\":\"xiami:\\/\\/song\\/1773431302\"},{\"tip\":\"\\u6211\\u4eec\\u6ca1\\u6709\\u5728\\u4e00\\u8d77 - \\u5218\\u82e5\\u82f1\",\"url\":\"xiami:\\/\\/song\\/1769471863\"},{\"tip\":\"\\u54ed\u7802 (Live)(\\u5218\\u660e\\u6e58\\u80dc\\u51fa) - \\u5218\u660e\u6e58\",\"url\":\"xiami:\\/\\/ song\\/1773484887\"}],\"type\":\"song\"},{\"items\":[{\"tip\":\"\\u4eb2\\u7231\\u7684\\u8def\\u4eba - \\u5218\\u82e5\\u82f1\",\"url\":\"xiami:\\/\\/album\\/55230\"},{\"tip\":\"\\u5728\\u4e00\\u8d77 - \\u5218\\u82e5\\u82f1\",\"url\":\"xiami:\\/\\/album\\/377241\"}],\"type\":\"album\"}],\"status\":\"ok\",\"err\":null} "; + + Parser parser = JSON.parseObject(jsonStr, Parser.class); + + System.out.println(JSON.toJSONString(parser)); + } + + public static class Parser { + + public int state; + public JSON data; + public String status; + public String err; + + public int getState() { + return state; + } + + public void setState(int state) { + this.state = state; + } + + public JSON getData() { + return data; + } + + public void setData(JSON data) { + this.data = data; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getErr() { + return err; + } + + public void setErr(String err) { + this.err = err; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jsonobj_null.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jsonobj_null.java new file mode 100644 index 0000000000..e373647ad9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_jsonobj_null.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + +import junit.framework.TestCase; + +public class Bug_for_jsonobj_null extends TestCase { + + public void test_parseObjectNull() throws Exception { + JSON.parseObject("{\"data\":null}", VO.class); + } + + public static class VO { + + private JSONObject data; + + public JSONObject getData() { + return data; + } + + public void setData(JSONObject data) { + this.data = data; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_juewu.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_juewu.java new file mode 100644 index 0000000000..32ecd06e9b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_juewu.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class Bug_for_juewu extends TestCase { + public void test_str() throws Exception { + String text = "{\"weitao_feed\":{\"head\":{\"Version\":\"V1.0\",\"Status\":\"OK\",\"SearchTime\":1488,\"DocsReturn\":18,\"DocsFound\":20,\"DocsRestrict\":20,\"DocsSearch\":0},\"auctions\":[{\"id\":\"110009362197\",\"creator_id\":\"673515636\",\"gmt_create_ms\":\"1385540374000\"}]}}"; + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix.java new file mode 100755 index 0000000000..8c8ef85e9c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt.bug; + +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class Bug_for_lenolix extends TestCase { + public void test_FieldMap() throws Exception { + Map map = JSON.parseObject("{\"key\":[\"value1\",\"value2\"]}", + new TypeReference>() { + }); + String[] array = map.get("key"); + Assert.assertEquals("value1", array[0]); + Assert.assertEquals("value2", array[1]); + + System.out.println(Thread.currentThread().getContextClassLoader().getResource("com/alibaba/fastjson/JSON.class")); + } + + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_1.java new file mode 100755 index 0000000000..31918f1121 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_1.java @@ -0,0 +1,29 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_lenolix_1 extends TestCase { + + public void test_0() throws Exception { + Map matcherMap = new HashMap(); + String matcherMapString = JSON.toJSONString(matcherMap, SerializerFeature.WriteClassName, + SerializerFeature.WriteMapNullValue); + + System.out.println(matcherMapString); + + matcherMap = JSONObject.parseObject(matcherMapString, new TypeReference>() { + }); + } + + public static class User { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_10.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_10.java new file mode 100755 index 0000000000..20dddf510e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_10.java @@ -0,0 +1,61 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_lenolix_10 extends TestCase { + + public void test_for_objectKey() throws Exception { + Map map2 = new HashMap(); + User user = new User(); + user.setId(1); + user.setIsBoy(true); + user.setName("leno.lix"); + // user.setBirthDay(simpleDateFormat.parse("2012-03-07 22:38:21 CST")); + // user.setGmtCreate(new java.sql.Date(simpleDateFormat.parse("2012-02-03 22:38:21 CST") + // .getTime())); + map2.put(1, user); + String mapJson2 = JSON.toJSONString(map2, SerializerFeature.WriteClassName, SerializerFeature.WriteMapNullValue); + System.out.println(mapJson2); + Object object2 = JSON.parse(mapJson2); + + } + + public static class User { + + private int id; + private Boolean isBoy; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Boolean getIsBoy() { + return isBoy; + } + + public void setIsBoy(Boolean isBoy) { + this.isBoy = isBoy; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_11.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_11.java new file mode 100755 index 0000000000..8d58f8011d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_11.java @@ -0,0 +1,57 @@ +package com.alibaba.json.bvt.bug; + +import java.text.SimpleDateFormat; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_lenolix_11 extends TestCase { + + public void test_for_objectKey() throws Exception { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM-dd-yyyy"); + + String simpleDateFormatJson = JSON.toJSONString(simpleDateFormat, SerializerFeature.WriteClassName, + SerializerFeature.WriteMapNullValue); + + System.out.println(simpleDateFormatJson); + + java.text.SimpleDateFormat format = (java.text.SimpleDateFormat) JSON.parse(simpleDateFormatJson); + Assert.assertEquals("MM-dd-yyyy", format.toPattern()); + + } + + public static class User { + + private int id; + private Boolean isBoy; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Boolean getIsBoy() { + return isBoy; + } + + public void setIsBoy(Boolean isBoy) { + this.isBoy = isBoy; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_2.java new file mode 100755 index 0000000000..d32e55ea58 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_2.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_lenolix_2 extends TestCase { + + public void test_0() throws Exception { + Map matcherMap = new HashMap(); + String matcherMapString = JSON.toJSONString(matcherMap, SerializerFeature.WriteMapNullValue); + + System.out.println(matcherMapString); + + matcherMap = JSONObject.parseObject(matcherMapString, new TypeReference>() { + }); + } + + public static class User { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_3.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_3.java new file mode 100755 index 0000000000..d75141d15b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_3.java @@ -0,0 +1,23 @@ +package com.alibaba.json.bvt.bug; + +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.TypeReference; + +public class Bug_for_lenolix_3 extends TestCase { + + public void test_0() throws Exception { + + System.out.println("{}"); + + JSONObject.parseObject("{\"id\":{}}", new TypeReference>>() { + }); + } + + public static class User { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_4.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_4.java new file mode 100755 index 0000000000..266362c629 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_4.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_lenolix_4 extends TestCase { + + public void test_for_objectKey() throws Exception { + Map, String> map = new HashMap, String>(); + Map submap = new HashMap(); + submap.put("subkey", "subvalue"); + map.put(submap, "value"); + String jsonString = JSON.toJSONString(map, SerializerFeature.WriteClassName); + System.out.println(jsonString); + Object object = JSON.parse(jsonString); + JSON.parseObject(jsonString); + + System.out.println(object.toString()); + } + + public void test_for_arrayKey() throws Exception { + Map, String> map = new HashMap, String>(); + List key = new ArrayList(); + + key.add("subkey"); + map.put(key, "value"); + String jsonString = JSON.toJSONString(map, SerializerFeature.WriteClassName); + System.out.println(jsonString); + Object object = JSON.parse(jsonString); + System.out.println(object.toString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_5.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_5.java new file mode 100755 index 0000000000..a99b3317f1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_5.java @@ -0,0 +1,29 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_lenolix_5 extends TestCase { + + public void test_for_objectKey() throws Exception { + Map obj = new HashMap(); + Object obja = new Object(); + Object objb = new Object(); + obj.put(obja, objb); + + String newJsonString = JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue, + SerializerFeature.WriteClassName); + System.out.println(newJsonString); + + Object newObject = JSON.parse(newJsonString); + + System.out.println(newObject); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_6.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_6.java new file mode 100755 index 0000000000..db244f5fc0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_6.java @@ -0,0 +1,30 @@ +package com.alibaba.json.bvt.bug; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_lenolix_6 extends TestCase { + + public void test_for_objectKey() throws Exception { + Map map = new HashMap(); + map.put("id", 1); + map.put("name", "leno.lix"); + map.put("birthday", new Date()); + map.put("gmtCreate", new java.sql.Date(new Date().getTime())); + map.put("gmtModified", new java.sql.Timestamp(new Date().getTime())); + + String userJSON = JSON.toJSONString(map, SerializerFeature.WriteClassName, + SerializerFeature.WriteMapNullValue); + + System.out.println(userJSON); + + Object object = JSON.parse(userJSON); + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_7.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_7.java new file mode 100755 index 0000000000..0a941067a2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_7.java @@ -0,0 +1,103 @@ +package com.alibaba.json.bvt.bug; + +import java.io.Serializable; +import java.util.Date; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.json.bvt.parser.GenericTest.Address; + +public class Bug_for_lenolix_7 extends TestCase { + + public void test_for_objectKey() throws Exception { + User user = new User(); + user.setId(1); + user.setName("leno.lix"); + user.setIsBoy(true); + user.setBirthDay(new Date()); + user.setGmtCreate(new java.sql.Date(new Date().getTime())); + user.setGmtModified(new java.sql.Timestamp(new Date().getTime())); + String userJSON = JSON.toJSONString(user, SerializerFeature.WriteClassName, SerializerFeature.WriteMapNullValue); + + System.out.println(userJSON); + + User returnUser = (User) JSON.parse(userJSON); + + } + + public static class User implements Serializable { + + /** + * + */ + + private static final long serialVersionUID = 6192533820796587011L; + + private Integer id; + private String name; + private Boolean isBoy; + private Address address; + private Date birthDay; + private java.sql.Date gmtCreate; + private java.sql.Timestamp gmtModified; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Boolean getIsBoy() { + return isBoy; + } + + public void setIsBoy(Boolean isBoy) { + this.isBoy = isBoy; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } + + public Date getBirthDay() { + return birthDay; + } + + public void setBirthDay(Date birthDay) { + this.birthDay = birthDay; + } + + public java.sql.Date getGmtCreate() { + return gmtCreate; + } + + public void setGmtCreate(java.sql.Date gmtCreate) { + this.gmtCreate = gmtCreate; + } + + public java.sql.Timestamp getGmtModified() { + return gmtModified; + } + + public void setGmtModified(java.sql.Timestamp gmtModified) { + this.gmtModified = gmtModified; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_8.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_8.java new file mode 100755 index 0000000000..247e3dc2a1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_8.java @@ -0,0 +1,103 @@ +package com.alibaba.json.bvt.bug; + +import java.io.Serializable; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_lenolix_8 extends TestCase { + + public void test_for_objectKey() throws Exception { + DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Map map = new HashMap(); + + User user = new User(); + user.setId(1); + user.setIsBoy(true); + user.setName("leno.lix"); + user.setBirthDay(simpleDateFormat.parse("2012-03-07 22:38:21")); + user.setGmtCreate(new java.sql.Date(simpleDateFormat.parse("2012-02-03 22:38:21").getTime())); + + map.put(1, user); + + String mapJson = JSON.toJSONString(map, SerializerFeature.WriteClassName, SerializerFeature.WriteMapNullValue); + + System.out.println(mapJson); + + Object object = JSON.parse(mapJson); + + } + + public static class User implements Serializable { + + /** + * + */ + + private static final long serialVersionUID = 6192533820796587011L; + + private Integer id; + private String name; + private Boolean isBoy; + private Date birthDay; + private java.sql.Date gmtCreate; + private java.sql.Timestamp gmtModified; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Boolean getIsBoy() { + return isBoy; + } + + public void setIsBoy(Boolean isBoy) { + this.isBoy = isBoy; + } + + + public Date getBirthDay() { + return birthDay; + } + + public void setBirthDay(Date birthDay) { + this.birthDay = birthDay; + } + + public java.sql.Date getGmtCreate() { + return gmtCreate; + } + + public void setGmtCreate(java.sql.Date gmtCreate) { + this.gmtCreate = gmtCreate; + } + + public java.sql.Timestamp getGmtModified() { + return gmtModified; + } + + public void setGmtModified(java.sql.Timestamp gmtModified) { + this.gmtModified = gmtModified; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_9.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_9.java new file mode 100755 index 0000000000..3d0e910ee9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_lenolix_9.java @@ -0,0 +1,100 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.json.bvt.bug.Bug_for_lenolix_9.Address.Country; + +public class Bug_for_lenolix_9 extends TestCase { + + public void test_for_objectKey() throws Exception { + Map submap4 = new HashMap(); + Address address = new Address(); + address.setCity("hangzhou"); + address.setStreet("wangshang.RD"); + address.setPostCode(310002); + submap4.put("address1", address); + submap4.put("address2", address); + + Country country = address.new Country(); + country.setProvince("ZheJiang"); + + address.setCountry(country); + + String mapString4 = JSON.toJSONString(submap4, SerializerFeature.WriteClassName, + SerializerFeature.WriteMapNullValue); + + System.out.println(mapString4); + Object object4 = JSON.parse(mapString4); + Assert.assertNotNull(object4); + + Map map = (Map) object4; + + Assert.assertNotNull(map.get("address1")); + Assert.assertNotNull(map.get("address2")); + + Assert.assertTrue(map.get("address1") == map.get("address2")); + + } + + public static class Address { + + private String city; + private String street; + private int postCode; + private Country country; + + public Country getCountry() { + return country; + } + + public void setCountry(Country country) { + this.country = country; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public int getPostCode() { + return postCode; + } + + public void setPostCode(int postCode) { + this.postCode = postCode; + } + + public class Country { + + private String province; + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + } + } + + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_leupom.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_leupom.java new file mode 100755 index 0000000000..cba486dd69 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_leupom.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.bug; + +import java.io.Serializable; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + +public class Bug_for_leupom extends TestCase { + + public void test_bug() throws Exception { + Person person = new Person(); + person.setId(12345); + + String text = JSON.toJSONString(person); + + System.out.println(text); + } + + public abstract static class Model { + + public abstract Serializable getId(); + + } + + public static class Person extends Model { + + private Integer id; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_leupom_2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_leupom_2.java new file mode 100755 index 0000000000..1282752771 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_leupom_2.java @@ -0,0 +1,60 @@ +package com.alibaba.json.bvt.bug; + +import java.util.concurrent.TimeUnit; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_leupom_2 extends TestCase { + + public void test_0() throws Exception { + Time time = new Time(1000, TimeUnit.MILLISECONDS); + + String text = JSON.toJSONString(time); + + System.out.println(text); + + Time time2 = JSON.parseObject(text, Time.class); + + Assert.assertEquals(time2.getValue(), time.getValue()); + Assert.assertEquals(time2.getUnit(), time.getUnit()); + } + + public static class Time { + + private long value; + private TimeUnit unit; + + public Time(){ + super(); + } + + public Time(long value, TimeUnit unit){ + super(); + this.value = value; + this.unit = unit; + } + + public long getValue() { + return value; + } + + @JSONField(serialzeFeatures={SerializerFeature.WriteEnumUsingToString}) + public TimeUnit getUnit() { + return unit; + } + + public void setValue(long value) { + this.value = value; + } + + public void setUnit(TimeUnit unit) { + this.unit = unit; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_leupom_3.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_leupom_3.java new file mode 100755 index 0000000000..84ef326f59 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_leupom_3.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt.bug; + +import java.io.Serializable; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_leupom_3 extends TestCase { + + public void test_bug() throws Exception { + Person person = new Person(); + person.setId(12345); + + String text = JSON.toJSONString(person); + + System.out.println(text); + + Person person2 = JSON.parseObject(text, Person.class); + + Assert.assertEquals(person.getId(), person2.getId()); + } + + public abstract static interface Model { + + Serializable getId(); + void setId(Integer value); + } + + public static class Person implements Model { + + private Integer id; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/bug/Bug_for_liuwanzhen_ren.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_liuwanzhen_ren.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/bug/Bug_for_liuwanzhen_ren.java rename to src/test/java/com/alibaba/json/bvt/bug/Bug_for_liuwanzhen_ren.java index aef72bd460..4c302e48bd --- a/src/test/java/com/alibaba/json/test/bvt/bug/Bug_for_liuwanzhen_ren.java +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_liuwanzhen_ren.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.bug; +package com.alibaba.json.bvt.bug; import java.util.HashMap; diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_long_whitespace.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_long_whitespace.java new file mode 100644 index 0000000000..ab7df4c35e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_long_whitespace.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_long_whitespace extends TestCase { + + public void test() throws Exception { + String json = "{\"f1\":11222509, \"f2\":7}"; + + VO v = JSON.parseObject(json, VO.class); + System.out.println(v.getF1()); + System.out.println(v.getF2()); + + } + + public static class VO { + + private long f1; + private int f2; + + public long getF1() { + return f1; + } + + public void setF1(long f1) { + this.f1 = f1; + } + + public int getF2() { + return f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_ludong.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_ludong.java new file mode 100644 index 0000000000..2ae4148fba --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_ludong.java @@ -0,0 +1,916 @@ +package com.alibaba.json.bvt.bug; + +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_ludong extends TestCase { + + public void test_for_ludong() throws Exception { + String msg = "{\"changedItems\":[{\"attribute\":\"new\",\"benefitCustomer\":\"chance130320584431\",\"benefitCustomerContactor\":5809917,\"benefitCustomerId\":2001385618,\"bizStatus\":\"audit_pass\",\"creator\":\"dowjons\",\"defaultBiz\":true,\"discountRate\":100,\"domain\":\"nirvana\",\"executeAmount\":3688,\"gmtCreate\":1367856000000,\"gmtModified\":1368374400000,\"gmtSign\":1367856000000,\"id\":321600616,\"isDeleted\":\"n\",\"itemNum\":\"W1305070000053_1\",\"lastOperType\":\"finance_pass_rollback\",\"memberId\":\"3592950865\",\"modifier\":\"haiquan.zhanghq\",\"num\":12,\"oppId\":103722314,\"orderId\":315749401,\"parentId\":0,\"paymentAmount\":0,\"paymentStatus\":\"payment_none\",\"policyId\":63149,\"price\":3688,\"productCode\":\"pc060\",\"purchaseType\":\"bought\",\"quotedPrice\":3688,\"salesId\":\"tiandan\",\"salesOrgFullid\":\"/10/1/30/101/160/1001/1051/\",\"serviceSupplyCompany\":\"B50\",\"signSalesId\":\"tiandan\",\"signSalesOrgFullId\":\"/10/1/30/101/160/1001/1051/\",\"traceChange\":true,\"ultimatePrice\":3688,\"unServiceDay\":0,\"unit\":\"M\",\"unvoucherAmount\":3688,\"voucherStatus\":\"voucher_none\"}],\"context\":{\"payAmount\":3688,\"payDate\":1368442850437,\"paymentStatus\":\"payment_success\"},\"generateTime\":1368442868624,\"msgType\":\"PAYMENT\",\"orderNumber\":\"W1305070000053\"}"; + + OrderInternalDto dto = JSON.parseObject(msg, OrderInternalDto.class); + } + + public static class OrderInternalDto implements Serializable { + + private static final long serialVersionUID = 3228508302993121205L; + + /* 对象生成的时间 */ + + private Date generateTime; + + /** 订单号 */ + + private String orderNumber; + + /** 对象的业务状态 */ + + private MSGTYPE msgType; + + /** 订单的瞬时状态 */ + + // private List instantItems; + + /** 发生状态变化的订单行列,比如到款只是对一个订单行发生到账行为 */ + + private List changedItems; + + /** 上下文参数 */ + + private Map context; + + public OrderInternalDto(){ + + this.generateTime = new Date(); + + context = new HashMap(); + + } + + public void setContext(Map context) { + + if (context == null) return; + + this.context = context; + + } + + @Override + public String toString() { + + return JSON.toJSONString(this); + + } + + } + + public static class OrdOrderItem implements Cloneable, Serializable { + + public static String ORDER_ID = "orderId"; + + private Object orderId; + + public static String PARENT_ID = "parentId"; + + private Integer parentId; + + public static String SERIAL_NUM = "serialNum"; + + private String serialNum; + + public static String ITEM_NUM = "itemNum"; + + private String itemNum; + + public static String PURCHASE_TYPE = "purchaseType"; + + private String purchaseType; + + public static String ATTRIBUTE = "attribute"; + + private String attribute; + + public static String MEMBER_ID = "memberId"; + + private String memberId; + + public static String PRODUCT_CODE = "productCode"; + + private String productCode; + + public static String NUM = "num"; + + private Integer num; + + public static String UNIT = "unit"; + + private String unit; + + public static String PRICE = "price"; + + private java.math.BigDecimal price; + + public static String DISCOUNT_RATE = "discountRate"; + + private java.math.BigDecimal discountRate; + + public static String QUOTED_PRICE = "quotedPrice"; + + private java.math.BigDecimal quotedPrice; + + public static String ULTIMATE_PRICE = "ultimatePrice"; + + private java.math.BigDecimal ultimatePrice; + + public static String EXECUTE_AMOUNT = "executeAmount"; + + private java.math.BigDecimal executeAmount; + + public static String GMT_TARGET_BEGIN = "gmtTargetBegin"; + + private java.util.Date gmtTargetBegin; + + public static String GMT_TARGET_END = "gmtTargetEnd"; + + private java.util.Date gmtTargetEnd; + + public static String GMT_ACTUAL_BEGIN = "gmtActualBegin"; + + private java.util.Date gmtActualBegin; + + public static String GMT_ACTUAL_END = "gmtActualEnd"; + + private java.util.Date gmtActualEnd; + + public static String SERVICE_SUPPLY_COMPANY = "serviceSupplyCompany"; + + private String serviceSupplyCompany; + + public static String BENEFIT_CUSTOMER = "benefitCustomer"; + + private String benefitCustomer; + + public static String BENEFIT_CUSTOMER_ID = "benefitCustomerId"; + + private Integer benefitCustomerId; + + public static String BENEFIT_CUSTOMER_CONTACTOR = "benefitCustomerContactor"; + + private Integer benefitCustomerContactor; + + public static String BIZ_STATUS = "bizStatus"; + + private String bizStatus; + + public static String VOUCHER_STATUS = "voucherStatus"; + + private String voucherStatus; + + public static String PAYMENT_STATUS = "paymentStatus"; + + private String paymentStatus; + + public static String PAYMENT_AMOUNT = "paymentAmount"; + + private java.math.BigDecimal paymentAmount; + + public static String POLICY_ID = "policyId"; + + private Integer policyId; + + public static String MEMO = "memo"; + + private String memo; + + public static String SUPPORTER = "supporter"; + + private String supporter; + + public static String SUPPORTER_ORG_ID = "supporterOrgId"; + + private Integer supporterOrgId; + + public static String SUPPORTER_ORG_FULLID = "supporterOrgFullid"; + + private String supporterOrgFullid; + + public static String SALES_ORG_FULLID = "salesOrgFullid"; + + private String salesOrgFullid; + + public static String SIGN_SALES_ORG_FULLID = "signSalesOrgFullId"; + + private String signSalesOrgFullId; + + public static String OPP_ID = "oppId"; + + private Integer oppId; + + public static String DOMAIN = "domain"; + + private String domain; + + public static String UN_SERVICE_DAY = "unServiceDay"; + + private java.math.BigDecimal unServiceDay; + + public static String PROCESS_ID = "processId"; + + private Long processId; + + public static String LAST_OPER_TYPE = "lastOperType"; + + private String lastOperType; + + public static String UNVOUCHER_AMOUNT = "unvoucherAmount"; + + private java.math.BigDecimal unvoucherAmount; + + public static String GMT_VOUCHER_RECEIVE = "gmtVoucherReceive"; + + private java.util.Date gmtVoucherReceive; + + public static String GMT_PAYMENT_REMIT = "gmtPaymentRemit"; + + private java.util.Date gmtPaymentRemit; + + public static String SERVICE_JUMP_DAYS = "serviceJumpDays"; + + private Integer serviceJumpDays; + + public static String SIGN_SALES_ID = "signSalesId"; + + private String signSalesId; + + public static String SALES_ORG_ID = "salesOrgId"; + + private Integer salesOrgId; + + public static String SIGN_SALES_ORG_ID = "signSalesOrgId"; + + private Integer signSalesOrgId; + + public Integer getSignSalesOrgId() { + + return signSalesOrgId; + + } + + public void setSignSalesOrgId(Integer signSalesOrgId) { + + this.signSalesOrgId = signSalesOrgId; + + } + + public Integer getSalesOrgId() { + + return salesOrgId; + + } + + public void setSalesOrgId(Integer salesOrgId) { + + this.salesOrgId = salesOrgId; + + } + + public static String SIGN_SELLER_COMPANY = "signSellerCompany"; + + private String signSellerCompany; + + public static String BARGAIN_ID = "bargainId"; + + private Integer bargainId; + + public Integer getBargainId() { + + return bargainId; + + } + + public void setBargainId(Integer bargainId) { + + this.bargainId = bargainId; + + } + + public String getSignSellerCompany() { + + return signSellerCompany; + + } + + public void setSignSellerCompany(String signSellerCompany) { + + this.signSellerCompany = signSellerCompany; + + } + + // 增加了新签和续签销售的id + + public static String SALES_ID = "salesId"; + + private String salesId; + + public String getSalesId() { + + return salesId; + + } + + public void setSalesId(String salesId) { + + this.salesId = salesId; + + } + + public String getRenewSalesId() { + + return renewSalesId; + + } + + public void setRenewSalesId(String renewSalesId) { + + this.renewSalesId = renewSalesId; + + } + + public static String RENEW_SALES_ID = "renewSalesId"; + + private String renewSalesId; + + public static String GMT_SIGN = "gmtSign"; + + private java.util.Date gmtSign; + + public Object getOrderId() { + + return this.orderId; + + } + + public void setOrderId(Object orderId) { + + this.orderId = orderId; + + } + + public Integer getParentId() { + + return this.parentId; + + } + + public void setParentId(Integer parentId) { + + this.parentId = parentId; + + } + + public String getSerialNum() { + + return this.serialNum; + + } + + public void setSerialNum(String serialNum) { + + this.serialNum = serialNum; + + } + + public String getItemNum() { + + return this.itemNum; + + } + + public void setItemNum(String itemNum) { + + this.itemNum = itemNum; + + } + + public String getPurchaseType() { + + return this.purchaseType; + + } + + public void setPurchaseType(String purchaseType) { + + this.purchaseType = purchaseType; + + } + + public String getAttribute() { + + return this.attribute; + + } + + public void setAttribute(String attribute) { + + this.attribute = attribute; + + } + + public String getMemberId() { + + return this.memberId; + + } + + public void setMemberId(String memberId) { + + this.memberId = memberId; + + } + + public String getProductCode() { + + return this.productCode; + + } + + public void setProductCode(String productCode) { + + this.productCode = productCode; + + } + + public Integer getNum() { + + return this.num; + + } + + public void setNum(Integer num) { + + this.num = num; + + } + + public String getUnit() { + + return this.unit; + + } + + public void setUnit(String unit) { + + this.unit = unit; + + } + + public java.math.BigDecimal getPrice() { + + return this.price; + + } + + public void setPrice(java.math.BigDecimal price) { + + this.price = price; + + } + + public java.math.BigDecimal getDiscountRate() { + + return this.discountRate; + + } + + public void setDiscountRate(java.math.BigDecimal discountRate) { + + this.discountRate = discountRate; + + } + + public java.math.BigDecimal getQuotedPrice() { + + return this.quotedPrice; + + } + + public void setQuotedPrice(java.math.BigDecimal quotedPrice) { + + this.quotedPrice = quotedPrice; + + } + + public java.math.BigDecimal getUltimatePrice() { + + return this.ultimatePrice; + + } + + public void setUltimatePrice(java.math.BigDecimal ultimatePrice) { + + this.ultimatePrice = ultimatePrice; + + } + + public java.math.BigDecimal getExecuteAmount() { + + return this.executeAmount; + + } + + public void setExecuteAmount(java.math.BigDecimal executeAmount) { + + this.executeAmount = executeAmount; + + } + + public java.util.Date getGmtTargetBegin() { + + return this.gmtTargetBegin; + + } + + public void setGmtTargetBegin(java.util.Date gmtTargetBegin) { + + this.gmtTargetBegin = gmtTargetBegin; + + } + + public java.util.Date getGmtTargetEnd() { + + return this.gmtTargetEnd; + + } + + public void setGmtTargetEnd(java.util.Date gmtTargetEnd) { + + this.gmtTargetEnd = gmtTargetEnd; + + } + + public java.util.Date getGmtActualBegin() { + + return this.gmtActualBegin; + + } + + public void setGmtActualBegin(java.util.Date gmtActualBegin) { + + this.gmtActualBegin = gmtActualBegin; + + } + + public java.util.Date getGmtActualEnd() { + + return this.gmtActualEnd; + + } + + public void setGmtActualEnd(java.util.Date gmtActualEnd) { + + this.gmtActualEnd = gmtActualEnd; + + } + + public String getServiceSupplyCompany() { + + return this.serviceSupplyCompany; + + } + + public void setServiceSupplyCompany(String serviceSupplyCompany) { + + this.serviceSupplyCompany = serviceSupplyCompany; + + } + + public String getBenefitCustomer() { + + return this.benefitCustomer; + + } + + public void setBenefitCustomer(String benefitCustomer) { + + this.benefitCustomer = benefitCustomer; + + } + + public Integer getBenefitCustomerId() { + + return this.benefitCustomerId; + + } + + public void setBenefitCustomerId(Integer benefitCustomerId) { + + this.benefitCustomerId = benefitCustomerId; + + } + + public Integer getBenefitCustomerContactor() { + + return this.benefitCustomerContactor; + + } + + public void setBenefitCustomerContactor(Integer benefitCustomerContactor) { + + this.benefitCustomerContactor = benefitCustomerContactor; + + } + + public String getBizStatus() { + + return this.bizStatus; + + } + + public void setBizStatus(String bizStatus) { + + this.bizStatus = bizStatus; + + } + + public String getVoucherStatus() { + + return this.voucherStatus; + + } + + public void setVoucherStatus(String voucherStatus) { + + this.voucherStatus = voucherStatus; + + } + + public String getPaymentStatus() { + + return this.paymentStatus; + + } + + public void setPaymentStatus(String paymentStatus) { + + this.paymentStatus = paymentStatus; + + } + + public java.math.BigDecimal getPaymentAmount() { + + return this.paymentAmount; + + } + + public void setPaymentAmount(java.math.BigDecimal paymentAmount) { + + this.paymentAmount = paymentAmount; + + } + + public Integer getPolicyId() { + + return this.policyId; + + } + + public void setPolicyId(Integer policyId) { + + this.policyId = policyId; + + } + + public String getMemo() { + + return this.memo; + + } + + public void setMemo(String memo) { + + this.memo = memo; + + } + + public String getSupporter() { + + return this.supporter; + + } + + public void setSupporter(String supporter) { + + this.supporter = supporter; + + } + + public Integer getSupporterOrgId() { + + return this.supporterOrgId; + + } + + public void setSupporterOrgId(Integer supporterOrgId) { + + this.supporterOrgId = supporterOrgId; + + } + + public String getSupporterOrgFullid() { + + return this.supporterOrgFullid; + + } + + public void setSupporterOrgFullid(String supporterOrgFullid) { + + this.supporterOrgFullid = supporterOrgFullid; + + } + + public Integer getOppId() { + + return this.oppId; + + } + + public void setOppId(Integer oppId) { + + this.oppId = oppId; + + } + + public String getDomain() { + + return this.domain; + + } + + public void setDomain(String domain) { + + this.domain = domain; + + } + + public java.math.BigDecimal getUnServiceDay() { + + return this.unServiceDay; + + } + + public void setUnServiceDay(java.math.BigDecimal unServiceDay) { + + this.unServiceDay = unServiceDay; + + } + + public Long getProcessId() { + + return this.processId; + + } + + public void setProcessId(Long processId) { + + this.processId = processId; + + } + + public String getLastOperType() { + + return this.lastOperType; + + } + + public void setLastOperType(String lastOperType) { + + this.lastOperType = lastOperType; + + } + + public java.math.BigDecimal getUnvoucherAmount() { + + return this.unvoucherAmount; + + } + + public void setUnvoucherAmount(java.math.BigDecimal unvoucherAmount) { + + this.unvoucherAmount = unvoucherAmount; + + } + + public java.util.Date getGmtVoucherReceive() { + + return this.gmtVoucherReceive; + + } + + public void setGmtVoucherReceive(java.util.Date gmtVoucherReceive) { + + this.gmtVoucherReceive = gmtVoucherReceive; + + } + + public java.util.Date getGmtPaymentRemit() { + + return this.gmtPaymentRemit; + + } + + public void setGmtPaymentRemit(java.util.Date gmtPaymentRemit) { + + this.gmtPaymentRemit = gmtPaymentRemit; + + } + + public Integer getServiceJumpDays() { + + return this.serviceJumpDays; + + } + + public void setServiceJumpDays(Integer serviceJumpDays) { + + this.serviceJumpDays = serviceJumpDays; + + } + + @Override + public Object clone() throws CloneNotSupportedException { + + return super.clone(); + + } + + public String getSignSalesId() { + + return signSalesId; + + } + + public void setSignSalesId(String signSalesId) { + + this.signSalesId = signSalesId; + + } + + public String getSalesOrgFullid() { + + return salesOrgFullid; + + } + + public void setSalesOrgFullid(String salesOrgFullid) { + + this.salesOrgFullid = salesOrgFullid; + + } + + public String getSignSalesOrgFullId() { + + return signSalesOrgFullId; + + } + + public void setSignSalesOrgFullId(String signSalesOrgFullId) { + + this.signSalesOrgFullId = signSalesOrgFullId; + + } + + public java.util.Date getGmtSign() { + + return gmtSign; + + } + + public void setGmtSign(java.util.Date gmtSign) { + + this.gmtSign = gmtSign; + + } + + } + + public static class MSGTYPE { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_maiksagill.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_maiksagill.java new file mode 100755 index 0000000000..abc02b7503 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_maiksagill.java @@ -0,0 +1,22 @@ +package com.alibaba.json.bvt.bug; + +import java.io.InputStream; + +import junit.framework.TestCase; + +import org.apache.commons.io.IOUtils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.json.bvtVO.WareHouseInfo; + +public class Bug_for_maiksagill extends TestCase { + + public void test_for_maiksagill() throws Exception { + String resource = "json/maiksagill.json"; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource); + String text = IOUtils.toString(is); + + JSON.parseObject(text, WareHouseInfo[].class); + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/bug/Bug_for_melin.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_melin.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/bug/Bug_for_melin.java rename to src/test/java/com/alibaba/json/bvt/bug/Bug_for_melin.java index 073675a94e..9829e5c028 --- a/src/test/java/com/alibaba/json/test/bvt/bug/Bug_for_melin.java +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_melin.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.bug; +package com.alibaba.json.bvt.bug; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -22,7 +22,7 @@ public void test_for_melin() throws Exception { } public void test_for_melin_() throws Exception { - Map map = new HashMap(); + Map map = new LinkedHashMap(); map.put("id", 123); map.put("name", "\\"); diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_boolean.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_boolean.java new file mode 100644 index 0000000000..f9b76b0505 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_boolean.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_primitive_boolean extends TestCase { + + public void test_emptyStr() throws Exception { + JSON.parseObject("{\"value\":\"\"}", VO.class); + } + + public void test_null() throws Exception { + JSON.parseObject("{\"value\":null}", VO.class); + } + + public void test_strNull() throws Exception { + JSON.parseObject("{\"value\":\"null\"}", VO.class); + } + + public static class VO { + + private boolean value; + + public boolean getValue() { + return value; + } + + public void setValue(boolean value) { + throw new UnsupportedOperationException(); + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_byte.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_byte.java new file mode 100644 index 0000000000..c528ba5540 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_byte.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_primitive_byte extends TestCase { + + public void test_emptyStr() throws Exception { + JSON.parseObject("{\"value\":\"\"}", VO.class); + } + + public void test_null() throws Exception { + JSON.parseObject("{\"value\":null}", VO.class); + } + + public void test_strNull() throws Exception { + JSON.parseObject("{\"value\":\"null\"}", VO.class); + } + + public static class VO { + + private byte value; + + public byte getValue() { + return value; + } + + public void setValue(byte value) { + throw new UnsupportedOperationException(); + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_double.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_double.java new file mode 100644 index 0000000000..48096414af --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_double.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_primitive_double extends TestCase { + + public void test_emptyStr() throws Exception { + JSON.parseObject("{\"value\":\"\"}", VO.class); + } + + public void test_null() throws Exception { + JSON.parseObject("{\"value\":null}", VO.class); + } + + public void test_strNull() throws Exception { + JSON.parseObject("{\"value\":\"null\"}", VO.class); + } + + public static class VO { + + private double value; + + public double getValue() { + return value; + } + + public void setValue(double value) { + throw new UnsupportedOperationException(); + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_float.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_float.java new file mode 100644 index 0000000000..06ce70966e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_float.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_primitive_float extends TestCase { + + public void test_emptyStr() throws Exception { + JSON.parseObject("{\"value\":\"\"}", VO.class); + } + + public void test_null() throws Exception { + JSON.parseObject("{\"value\":null}", VO.class); + } + + public void test_strNull() throws Exception { + JSON.parseObject("{\"value\":\"null\"}", VO.class); + } + + public static class VO { + + private float value; + + public float getValue() { + return value; + } + + public void setValue(float value) { + throw new UnsupportedOperationException(); + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_int.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_int.java new file mode 100644 index 0000000000..4967279d34 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_int.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_primitive_int extends TestCase { + + public void test_emptyStr() throws Exception { + JSON.parseObject("{\"value\":\"\"}", VO.class); + } + + public void test_null() throws Exception { + JSON.parseObject("{\"value\":null}", VO.class); + } + + public void test_strNull() throws Exception { + JSON.parseObject("{\"value\":\"null\"}", VO.class); + } + + public static class VO { + + private int value; + + public int getValue() { + return value; + } + + public void setValue(int value) { + throw new UnsupportedOperationException(); + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_long.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_long.java new file mode 100644 index 0000000000..fca65674d4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_long.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_primitive_long extends TestCase { + + public void test_emptyStr() throws Exception { + JSON.parseObject("{\"value\":\"\"}", VO.class); + } + + public void test_null() throws Exception { + JSON.parseObject("{\"value\":null}", VO.class); + } + + public void test_strNull() throws Exception { + JSON.parseObject("{\"value\":\"null\"}", VO.class); + } + + public static class VO { + + private long value; + + public long getValue() { + return value; + } + + public void setValue(long value) { + throw new UnsupportedOperationException(); + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_short.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_short.java new file mode 100644 index 0000000000..2129fa25a0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_primitive_short.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_primitive_short extends TestCase { + + public void test_emptyStr() throws Exception { + JSON.parseObject("{\"value\":\"\"}", VO.class); + } + + public void test_null() throws Exception { + JSON.parseObject("{\"value\":null}", VO.class); + } + + public void test_strNull() throws Exception { + JSON.parseObject("{\"value\":\"null\"}", VO.class); + } + + public static class VO { + + private short value; + + public short getValue() { + return value; + } + + public void setValue(short value) { + throw new UnsupportedOperationException(); + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_qqdwll2012.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_qqdwll2012.java new file mode 100755 index 0000000000..cd4840d117 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_qqdwll2012.java @@ -0,0 +1,32 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializeFilter; +import com.alibaba.fastjson.serializer.SerializerFeature; + +import junit.framework.TestCase; + +public class Bug_for_qqdwll2012 extends TestCase { + + public void test_for_x() throws Exception { + VO vo = new VO(); + vo.setValue(" 问题链接 "); + + String text = JSON.toJSONString(vo, SerializerFeature.WriteSlashAsSpecial); + System.out.println(text); + } + + public static class VO { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_rendong.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_rendong.java new file mode 100755 index 0000000000..8d7ae81b97 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_rendong.java @@ -0,0 +1,92 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class Bug_for_rendong extends TestCase { + + public void test_0() throws Exception { + String text = "{\"BX-20110613-1739\":{\"repairNum\":\"BX-20110613-1739\",\"set\":[{\"employNum\":\"a1027\",\"isConfirm\":false,\"isReceive\":false,\"state\":11}]},\"BX-20110613-1749\":{\"repairNum\":\"BX-20110613-1749\",\"set\":[{\"employNum\":\"a1027\",\"isConfirm\":false,\"isReceive\":true,\"state\":1}]}}"; + + Map map = JSON.parseObject(text, + new TypeReference>() { + }); + + Assert.assertEquals(2, map.size()); + // System.out.println(JSON.toJSONString(map, + // SerializerFeature.PrettyFormat)); + } + + public static class TaskMobileStatusBean { + + private String repairNum; + + private Set set = new HashSet(); + + public String getRepairNum() { + return repairNum; + } + + public void setRepairNum(String repairNum) { + this.repairNum = repairNum; + } + + public Set getSet() { + return set; + } + + public void setSet(Set set) { + this.set = set; + } + + } + + public static class PeopleTaskMobileStatusBean { + + private String employNum; + private Boolean isConfirm; + private Boolean isReceive; + private int state; + + public String getEmployNum() { + return employNum; + } + + public void setEmployNum(String employNum) { + this.employNum = employNum; + } + + public Boolean getIsConfirm() { + return isConfirm; + } + + public void setIsConfirm(Boolean isConfirm) { + this.isConfirm = isConfirm; + } + + public Boolean getIsReceive() { + return isReceive; + } + + public void setIsReceive(Boolean isReceive) { + this.isReceive = isReceive; + } + + public int getState() { + return state; + } + + public void setState(int state) { + this.state = state; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_ruiqi.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_ruiqi.java new file mode 100644 index 0000000000..0b2ee2f202 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_ruiqi.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_ruiqi extends TestCase { + + public void test_0() throws Exception { + Map map = new HashMap(); + map.put("a", Enum.ENUM1); + map.put("b", Enum.ENUM1); + + System.out.println(JSON.toJSONString(map, SerializerFeature.WriteEnumUsingToString)); + + System.out.println(JSON.toJSONString(map)); + + } + + public static enum Enum { + + ENUM1("name1"), ENUM2("name2"); + + private String name; + + Enum(String name){ + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return "name: " + name; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_sankun.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_sankun.java new file mode 100644 index 0000000000..57e5c90a60 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_sankun.java @@ -0,0 +1,14 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.json.bvtVO.PushMsg; + + +public class Bug_for_sankun extends TestCase { + public void test_sankun() throws Exception { + PushMsg bean = new PushMsg(); + JSON.toJSONString(bean); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_set.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_set.java new file mode 100755 index 0000000000..96dde18f3e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_set.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + + +public class Bug_for_set extends TestCase { + public void test_set() throws Exception { + JSON.parseArray("Set[]"); + } + + public void test_treeset() throws Exception { + JSON.parseArray("TreeSet[]"); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_shortArray.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_shortArray.java new file mode 100644 index 0000000000..cf24b82418 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_shortArray.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_shortArray extends TestCase { + public void test_for_shor_array() throws Exception { + HashMap map = new HashMap(); + map.put((short) 1, (short)-1); + + String text = JSON.toJSONString(map, SerializerFeature.WriteClassName); + + System.out.println(text); + + Map map2 = JSON.parseObject(text, HashMap.class); + Map.Entry entry = (Map.Entry) map2.entrySet().iterator().next(); + Assert.assertEquals(entry.getKey().getClass(), Short.class); + Assert.assertTrue(entry.getValue() instanceof Short); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat.java new file mode 100755 index 0000000000..014031a7ab --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.bug; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_smoothrat extends TestCase { + + public void test_0() throws Exception { + Entity entity = new Entity(); + + entity.setValue("aaa123".toCharArray()); + + String text = JSON.toJSONString(entity); + Assert.assertEquals("{\"value\":\"aaa123\"}", text); + + Entity entity2 = JSON.parseObject(text, Entity.class); + + Assert.assertEquals(new String(entity.getValue()), new String(entity2.getValue())); + } + + public static class Entity { + + private char[] value; + + public char[] getValue() { + return value; + } + + public void setValue(char[] value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat2.java new file mode 100755 index 0000000000..9e32e2e044 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat2.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.bug; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_smoothrat2 extends TestCase { + + public void test_0() throws Exception { + long millis = System.currentTimeMillis(); + + java.sql.Time time = new java.sql.Time(millis); + Entity entity = new Entity(); + + entity.setValue(new java.sql.Time(millis)); + + String text = JSON.toJSONString(entity); + Assert.assertEquals("{\"value\":" + millis + "}", text); + + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertEquals(time, entity2.getValue()); + + } + + public static class Entity { + + private java.sql.Time value; + + public java.sql.Time getValue() { + return value; + } + + public void setValue(java.sql.Time value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat3.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat3.java new file mode 100755 index 0000000000..c69d89e647 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat3.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt.bug; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_smoothrat3 extends TestCase { + + public void test_0() throws Exception { + long millis = System.currentTimeMillis(); + + java.sql.Time time = new java.sql.Time(millis); + Entity entity = new Entity(); + + entity.setValue(new java.sql.Time(millis)); + + String text = JSON.toJSONString(entity, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.bug.Bug_for_smoothrat3$Entity\",\"value\":{\"@type\":\"java.sql.Time\",\"val\":" + millis + "}}", text); + + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertEquals(time, entity2.getValue()); + + } + + public static class Entity { + + private Object value; + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat4.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat4.java new file mode 100755 index 0000000000..a1cdcc9f6a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat4.java @@ -0,0 +1,112 @@ +package com.alibaba.json.bvt.bug; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_smoothrat4 extends TestCase { + + public void test_long() throws Exception { + + Entity entity = new Entity(); + + entity.setValue(3L); + + String text = JSON.toJSONString(entity, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.bug.Bug_for_smoothrat4$Entity\",\"value\":3L}", + text); + + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertEquals(Long.valueOf(3), entity2.getValue()); + } + + public void test_int() throws Exception { + + Entity entity = new Entity(); + + entity.setValue(3); + + String text = JSON.toJSONString(entity, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.bug.Bug_for_smoothrat4$Entity\",\"value\":3}", text); + + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertEquals(Integer.valueOf(3), entity2.getValue()); + } + + public void test_short() throws Exception { + + Entity entity = new Entity(); + + entity.setValue((short) 3); + + String text = JSON.toJSONString(entity, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.bug.Bug_for_smoothrat4$Entity\",\"value\":3S}", + text); + + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertEquals(Short.valueOf((short) 3), entity2.getValue()); + } + + public void test_byte() throws Exception { + + Entity entity = new Entity(); + + entity.setValue((byte) 3); + + String text = JSON.toJSONString(entity, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.bug.Bug_for_smoothrat4$Entity\",\"value\":3B}", + text); + + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertEquals(Byte.valueOf((byte) 3), entity2.getValue()); + } + + public void test_float() throws Exception { + + Entity entity = new Entity(); + + entity.setValue(3F); + + String text = JSON.toJSONString(entity, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.bug.Bug_for_smoothrat4$Entity\",\"value\":3F}", + text); + + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertEquals(3F, entity2.getValue()); + } + + public void test_double() throws Exception { + + Entity entity = new Entity(); + + entity.setValue(3D); + + String text = JSON.toJSONString(entity, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.bug.Bug_for_smoothrat4$Entity\",\"value\":3D}", + text); + + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertEquals(3D, entity2.getValue()); + } + + public static class Entity { + + private Object value; + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat5.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat5.java new file mode 100755 index 0000000000..d07c456369 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat5.java @@ -0,0 +1,66 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_smoothrat5 extends TestCase { + + public void test_map() throws Exception { + Map map = new HashMap(); + map.put(12, "a"); + map.put(34L, "b"); + + Entity entity = new Entity(); + + entity.setValue(map); + + String text = JSON.toJSONString(entity, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.bug.Bug_for_smoothrat5$Entity\",\"value\":{\"@type\":\"java.util.HashMap\",34L:\"b\",12:\"a\"}}", + text); + + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertEquals(map, entity2.getValue()); + Assert.assertEquals(map.getClass(), entity2.getValue().getClass()); + } + + public void test_treemap() throws Exception { + TreeMap map = new TreeMap(); + map.put(-34L, "b"); + map.put(-56L, "a"); + + + Entity entity = new Entity(); + + entity.setValue(map); + + String text = JSON.toJSONString(entity, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.bug.Bug_for_smoothrat5$Entity\",\"value\":{\"@type\":\"java.util.TreeMap\",-56L:\"a\",-34L:\"b\"}}", + text); + + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertEquals(map, entity2.getValue()); + Assert.assertEquals(map.getClass(), entity2.getValue().getClass()); + } + + public static class Entity { + + private Object value; + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat6.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat6.java new file mode 100755 index 0000000000..f299fe58cb --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat6.java @@ -0,0 +1,46 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_smoothrat6 extends TestCase { + + public void test_set() throws Exception { + Set set = new HashSet(); + set.add(3L); + set.add(4L); + + Entity entity = new Entity(); + + entity.setValue(set); + + String text = JSON.toJSONString(entity, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.bug.Bug_for_smoothrat6$Entity\",\"value\":Set[3L,4L]}", + text); + + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertEquals(set, entity2.getValue()); + Assert.assertEquals(set.getClass(), entity2.getValue().getClass()); + } + + + public static class Entity { + + private Object value; + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat7.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat7.java new file mode 100755 index 0000000000..316ba1a9a0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat7.java @@ -0,0 +1,30 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_smoothrat7 extends TestCase { + + @SuppressWarnings("unchecked") + public void test_self() throws Exception { + Map map = new HashMap(); + map.put("self", map); + + String text = JSON.toJSONString(map, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"java.util.HashMap\",\"self\":{\"$ref\":\"@\"}}", + text); + + Map entity2 = (Map) JSON.parse(text); + Assert.assertEquals(map.getClass(), entity2.getClass()); + Assert.assertSame(entity2, entity2.get("self")); + } + + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat8.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat8.java new file mode 100755 index 0000000000..ac829a3e07 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat8.java @@ -0,0 +1,47 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_smoothrat8 extends TestCase { + + public void test_set() throws Exception { + Map map = new HashMap(); + map.put(1, "a"); + map.put(2, "b"); + + Entity entity = new Entity(); + + entity.setValue(map); + + String text = JSON.toJSONString(entity, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.bug.Bug_for_smoothrat8$Entity\",\"value\":{\"@type\":\"java.util.HashMap\",1:\"a\",2:\"b\"}}", + text); + + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertEquals(map, entity2.getValue()); + Assert.assertEquals(map.getClass(), entity2.getValue().getClass()); + Assert.assertEquals(Integer.class, ((Map)entity2.getValue()).keySet().iterator().next().getClass()); + } + + + public static class Entity { + + private Object value; + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat9.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat9.java new file mode 100755 index 0000000000..6cf9d9f466 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_smoothrat9.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_smoothrat9 extends TestCase { + + public void test_set() throws Exception { + Map map = new HashMap(); + map.put(1, "a"); + map.put(2, "b"); + + + String text = JSON.toJSONString(map, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"java.util.HashMap\",1:\"a\",2:\"b\"}", + text); + + Map value = (Map) JSON.parse(text); + Assert.assertEquals(map, value); + Assert.assertEquals(map.getClass(), value.getClass()); + Assert.assertEquals(Integer.class, value.keySet().iterator().next().getClass()); + } + + + public static class Entity { + + private Object value; + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_stv_liu.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_stv_liu.java new file mode 100755 index 0000000000..27e65b529a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_stv_liu.java @@ -0,0 +1,61 @@ +package com.alibaba.json.bvt.bug; + +import java.io.Serializable; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_stv_liu extends TestCase { + + public void test() { + User user = new User(); + user.setId("1"); + user.setUsername("test"); + String json = JSON.toJSONString(user, SerializerFeature.WriteClassName); + user = (User) JSON.parse(json);// 此处抛异常 + Assert.assertNotNull(user); + } + + public static interface IdEntity extends Serializable { + + T getId(); + + void setId(T id); + } + + public static class BaseEntity implements IdEntity { + + private static final long serialVersionUID = 1L; + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + } + + public static class User extends BaseEntity { + + private String username; + + /** + * @return the username + */ + public String getUsername() { + return username; + } + + /** + * @param username the username to set + */ + public void setUsername(String username) { + this.username = username; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_taolei0628.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_taolei0628.java new file mode 100755 index 0000000000..6ec56d439d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_taolei0628.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Random; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + + +public class Bug_for_taolei0628 extends TestCase { + static final Random rand = new Random(1); + static String createString() + { + char[] cs = new char[31]; + for(int i=0;i>(){}.getType()); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/bug/Bug_for_uin57.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_uin57.java old mode 100644 new mode 100755 similarity index 99% rename from src/test/java/com/alibaba/json/test/bvt/bug/Bug_for_uin57.java rename to src/test/java/com/alibaba/json/bvt/bug/Bug_for_uin57.java index 5028f1ab48..dfe7fed1db --- a/src/test/java/com/alibaba/json/test/bvt/bug/Bug_for_uin57.java +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_uin57.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.bug; +package com.alibaba.json.bvt.bug; import java.io.Serializable; import java.util.ArrayList; diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_vikingschow.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_vikingschow.java new file mode 100755 index 0000000000..ad3233bea0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_vikingschow.java @@ -0,0 +1,14 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.json.bvtVO.OfferRankResultVO; + +public class Bug_for_vikingschow extends TestCase { + public void test_for_vikingschow() throws Exception { + OfferRankResultVO vo = new OfferRankResultVO(); + String text = JSON.toJSONString(vo); + JSON.parseObject(text, OfferRankResultVO.class); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wangran.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wangran.java new file mode 100755 index 0000000000..ed42ee7097 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wangran.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.bug; + +import java.io.InputStream; +import java.io.InputStreamReader; + +import org.junit.Assert; +import junit.framework.TestCase; + +import org.apache.commons.io.IOUtils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.json.bvtVO.PhysicalQueue; +import com.alibaba.json.bvtVO.QueueEntity; + +public class Bug_for_wangran extends TestCase { + + public void test_for_wangran() throws Exception { + String resource = "json/wangran.json"; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource); + String text = IOUtils.toString(new InputStreamReader(is,"UTF-8")); + + + QueueEntity qe = JSON.parseObject(text, QueueEntity.class); + + Assert.assertNotNull(qe); + Assert.assertNotNull(qe.getPhysicalQueueMap()); + Assert.assertEquals(4, qe.getPhysicalQueueMap().size()); + + for (PhysicalQueue q : qe.getPhysicalQueueMap().values()) { + q.getInRate(); + Assert.assertEquals(qe, q.getQueue()); + } + + Assert.assertEquals(qe.getPhysicalQueueMap(), qe.getPqMap()); + Assert.assertEquals(true, qe.getPhysicalQueueMap() == qe.getPqMap()); + Assert.assertEquals("amq", qe.getDescription()); + + } +} +// 500m / 300 \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wangran1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wangran1.java new file mode 100755 index 0000000000..046848acc0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wangran1.java @@ -0,0 +1,101 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; + +import com.alibaba.fastjson.JSON; + +import org.junit.Assert; +import junit.framework.TestCase; + +public class Bug_for_wangran1 extends TestCase { + + public void test_0() throws Exception { + Entity entity = new Entity(); + + entity.setId(11); + entity.setName("xx"); + + Queue q = new Queue(); + q.setId(55); + + entity.getQueue().put(q.getId(), q); + + String text = JSON.toJSONString(entity); + + System.out.println(text); + + Entity entity2 = JSON.parseObject(text, Entity.class); + + Assert.assertNotNull(entity2.getQueue()); + Assert.assertEquals(1, entity2.getQueue().size()); + Assert.assertEquals(true, entity2.getQueue().values().iterator().next() instanceof Queue); + } + + public static class Entity { + + private int id; + private String name; + + private Map queue = new HashMap(); + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Map getQueue() { + return queue; + } + + public void setQueue(Map queue) { + this.queue = queue; + } + + public Map getKQueue() { + return queue; + } + + public void setKQueue(Map queue) { + this.queue = queue; + } + } + + public static class Queue { + + public Queue() { + + } + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wangran2.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wangran2.java new file mode 100755 index 0000000000..b72b743e95 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wangran2.java @@ -0,0 +1,116 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_wangran2 extends TestCase { + + public void test_for_wangran() throws Exception { + String text = "{" + // + "\"first\":{\"id\":1001}," + // + "\"second\":{\"id\":1002,\"root\":{\"$ref\":\"$\"}}," + // + "\"id\":23," + // + "\"name\":\"xxx\"," + // + "\"children\":[{\"root\":{\"$ref\":\"$\"}},{\"$ref\":\"$.second\"}]" + // + "}"; + Root root = JSON.parseObject(text, Root.class); + Assert.assertEquals(23, root.getId()); + Assert.assertEquals("xxx", root.getName()); + Assert.assertTrue(root == root.getChildren().get(0).getRoot()); + Assert.assertTrue(root == root.getChildren().get(1).getRoot()); + } + + public static class Root { + + private int id; + private String name; + + private Child first; + private Child second; + + private List children = new ArrayList(); + + public Root(){ + + } + + public Child getSecond() { + return second; + } + + public void setSecond(Child second) { + System.out.println("setSecond"); + this.second = second; + } + + public Child getFirst() { + return first; + } + + public void setFirst(Child first) { + System.out.println("setFirst"); + this.first = first; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + System.out.println("setChildren"); + this.children = children; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + + public static class Child { + + private int id; + + private Root root; + + public Child(){ + + } + + public Root getRoot() { + return root; + } + + public void setRoot(Root root) { + System.out.println("setRoot"); + this.root = root; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } +} +// 500m / 300 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wsky.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wsky.java new file mode 100644 index 0000000000..7516af5a9d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wsky.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_wsky extends TestCase { + + public void test_writeMapNull() throws Exception { + JSON.parseObject(JSON.toJSONString(new MethodReturn(), SerializerFeature.WriteMapNullValue), MethodReturn.class); + } + + public static class MethodReturn { + + public Object ReturnValue; + public Throwable Exception; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wtusmchen.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wtusmchen.java new file mode 100755 index 0000000000..78b8cafedf --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wtusmchen.java @@ -0,0 +1,75 @@ +package com.alibaba.json.bvt.bug; + +import java.io.Serializable; +import java.sql.Date; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_wtusmchen extends TestCase { + + public void test_0() throws Exception { + List users = new ArrayList(); + users.add(new User()); + users.add(new User()); + + String text = JSON.toJSONString(users); + System.out.println(text); + + List users2 = JSON.parseArray(text, User.class); + } + + public static class User implements Serializable { + + private String user_id = "aaaa"; + Date bri; + Timestamp bri2; + Double num; + List list; + + public String getUser_id() { + return user_id; + } + + public void setUser_id(String user_id) { + this.user_id = user_id; + } + + public Date getBri() { + return bri; + } + + public void setBri(Date bri) { + this.bri = bri; + } + + public Timestamp getBri2() { + return bri2; + } + + public void setBri2(Timestamp bri2) { + this.bri2 = bri2; + } + + public Double getNum() { + return num; + } + + public void setNum(Double num) { + this.num = num; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wuyexiong.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wuyexiong.java new file mode 100755 index 0000000000..16c256bd2a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wuyexiong.java @@ -0,0 +1,66 @@ +package com.alibaba.json.bvt.bug; + +import java.io.InputStream; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.util.IOUtils; + +import org.junit.Assert; +import junit.framework.TestCase; + +public class Bug_for_wuyexiong extends TestCase { + + public static class Track { + + private String name; + private String color; + private String _abstract; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public String getAbstract() { + return _abstract; + } + + public void setAbstract(String _abstract) { + this._abstract = _abstract; + } + + + } + + public static class Tracks { + private Track[] track; + + public void setTrack(Track[] track) { + this.track = track; + } + + public Track[] getTrack() { + return track; + } + } + + public void test_for_wuyexiong() throws Exception { + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("wuyexiong.json"); + String text = org.apache.commons.io.IOUtils.toString(is); + org.apache.commons.io.IOUtils.closeQuietly(is); + + Tracks tracks = JSON.parseObject(text, Tracks.class); + Assert.assertEquals("Learn about developing mobile handset and tablet apps for Android.", tracks.getTrack()[0].getAbstract()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wuzhengmao.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wuzhengmao.java new file mode 100755 index 0000000000..bdca031a2b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_wuzhengmao.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.bug; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_wuzhengmao extends TestCase { + + public void test_0() throws Exception { + Node node1 = new Node(); + node1.setId(1); + Node node2 = new Node(); + node2.setId(2); + node1.setParent(node2); + + List list = Arrays.asList(new Node[] { node1, node2 }); + String json = JSON.toJSONString(list, true); + System.out.println(json); + List result = JSON.parseArray(json, Node.class); + Assert.assertEquals(2, result.size()); + Assert.assertEquals(1, result.get(0).getId()); + Assert.assertEquals(2, result.get(1).getId()); + Assert.assertEquals(result.get(0).getParent(), result.get(1)); + } + + static class Node { + + int id; + Node parent; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Node getParent() { + return parent; + } + + public void setParent(Node parent) { + this.parent = parent; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_xiayucai2012.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_xiayucai2012.java new file mode 100755 index 0000000000..06ccc35a0f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_xiayucai2012.java @@ -0,0 +1,21 @@ +package com.alibaba.json.bvt.bug; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + + +public class Bug_for_xiayucai2012 extends TestCase { + public void test_for_xiayucai2012() throws Exception { + String text = "{\"date\":\"0000-00-00 00:00:00\"}"; + JSONObject json = JSON.parseObject(text); + Date date = json.getObject("date", Date.class); + + Assert.assertEquals(new SimpleDateFormat(JSON.DEFFAULT_DATE_FORMAT).parse(json.getString("date")), date); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_xuzebin.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_xuzebin.java new file mode 100644 index 0000000000..c3e06aa7b5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_xuzebin.java @@ -0,0 +1,57 @@ +package com.alibaba.json.bvt.bug; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_xuzebin extends TestCase { + + public void testMap() { + P p = new P(); + p.setI(2); + p.getMap().put("a", "b"); + String json = JSON.toJSONString(p, SerializerFeature.WriteClassName); + System.out.println(json); + + P x = JSON.parseObject(json, P.class); + System.out.println(JSON.toJSONString(x)); + } + + public void testMap2() { + P p = new P(); + p.setI(2); + // p.getMap().put("a", "b"); + String json = JSON.toJSONString(p, SerializerFeature.WriteClassName); + System.out.println(json); + + P x = JSON.parseObject(json, P.class); + System.out.println(JSON.toJSONString(x)); + } + + public static class P { + + private Map map = new ConcurrentHashMap(); + private int i = 0; + + public Map getMap() { + return map; + } + + public void setMap(Map map) { + this.map = map; + } + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yangqi.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yangqi.java new file mode 100644 index 0000000000..cd6be8f076 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yangqi.java @@ -0,0 +1,49 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_yangqi extends TestCase { + + public void test_for_bug() throws Exception { + B b = JSON.parseObject("{\"id\":123,\"values\":[{}]}", B.class); + } + + abstract static class A { + + private int id; + private List values = new ArrayList(); + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + + public List getValues() { + return values; + } + + + public void setValues(List values) { + this.values = values; + } + + + } + + public static class B extends A { + + } + + public static class Value { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yannywang.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yannywang.java new file mode 100755 index 0000000000..011858aefb --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yannywang.java @@ -0,0 +1,60 @@ +package com.alibaba.json.bvt.bug; + +import java.io.InputStream; + +import org.junit.Assert; +import junit.framework.TestCase; + +import org.apache.commons.io.IOUtils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.json.bvtVO.PhysicalQueue; +import com.alibaba.json.bvtVO.QueueEntity; +import com.alibaba.json.bvtVO.VirtualTopic; + +public class Bug_for_yannywang extends TestCase { + + public void test_for_wangran() throws Exception { + String resource = "json/yannywang.json"; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource); + String text = IOUtils.toString(is); + + VirtualTopic topic = JSON.parseObject(text, VirtualTopic.class); + + { + QueueEntity qe = topic.getQueueMap().get(12109); + + Assert.assertNotNull(qe); + Assert.assertNotNull(qe.getPhysicalQueueMap()); + Assert.assertEquals(1, qe.getPhysicalQueueMap().size()); + + for (PhysicalQueue q : qe.getPhysicalQueueMap().values()) { + q.getInRate(); + Assert.assertEquals(qe, q.getQueue()); + } + + Assert.assertEquals(qe.getPhysicalQueueMap(), qe.getPqMap()); + Assert.assertEquals(true, qe.getPhysicalQueueMap() == qe.getPqMap()); + Assert.assertEquals("", qe.getDescription()); + } + { + QueueEntity qe = topic.getQueueMap().get(12110); + + Assert.assertNotNull(qe); + Assert.assertNotNull(qe.getPhysicalQueueMap()); + Assert.assertEquals(1, qe.getPhysicalQueueMap().size()); + + for (PhysicalQueue q : qe.getPhysicalQueueMap().values()) { + q.getInRate(); + Assert.assertEquals(qe, q.getQueue()); + } + + Assert.assertEquals(qe.getPhysicalQueueMap(), qe.getPqMap()); + Assert.assertEquals(true, qe.getPhysicalQueueMap() == qe.getPqMap()); + Assert.assertEquals("", qe.getDescription()); + } + + } + +} +// 500m / 300 diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yaoming.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yaoming.java new file mode 100644 index 0000000000..33658159fd --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yaoming.java @@ -0,0 +1,85 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.json.bvt.bug.Bug_for_yaoming.SimpleHttpReuslt.ErrorMessage; + +public class Bug_for_yaoming extends TestCase { + + public void test_bug() throws Exception { + SimpleHttpReuslt v = new SimpleHttpReuslt(); + v.setErrorMessage(new ArrayList()); + v.getErrorMessage().add(new ErrorMessage()); + String text = JSON.toJSONString(v); + text = "{\"content\":{\"versionModelList\":[{\"version\":\"260\",\"currentVersion\":true,\"versionComment\":\"testVersion\",\"warSize\":\"43130185\",\"appIdentifier\":\"parent\",\"uploadTime\":1375850777000},{\"version\":\"247\",\"currentVersion\":false,\"versionComment\":\"testVersion\",\"warSize\":\"43130186\",\"appIdentifier\":\"parent\",\"uploadTime\":1375634817000},{\"version\":\"246\",\"currentVersion\":false,\"versionComment\":\"testVersion\",\"warSize\":\"43130186\",\"appIdentifier\":\"parent\",\"uploadTime\":1375613193000},{\"version\":\"245\",\"currentVersion\":false,\"versionComment\":\"testVersion\",\"warSize\":\"43130185\",\"appIdentifier\":\"parent\",\"uploadTime\":1375591593000},{\"version\":\"244\",\"currentVersion\":false,\"versionComment\":\"testVersion\",\"warSize\":\"43130186\",\"appIdentifier\":\"parent\",\"uploadTime\":1375569999000},{\"version\":\"243\",\"currentVersion\":false,\"versionComment\":\"testVersion\",\"warSize\":\"43130185\",\"appIdentifier\":\"parent\",\"uploadTime\":1375548418000}],\"exceptionCode\":0},\"hasError\":false}"; + JSON.parseObject(text, SimpleHttpReuslt.class); + } + + public static class SimpleHttpReuslt { + + private String content; + private Boolean hasError; + private List errorMessage; + + public String getContent() { + return content; + } + + public Boolean isHasError() { + return hasError; + } + + public void setContent(String content) { + this.content = content; + } + + public void setHasError(Boolean hasError) { + this.hasError = hasError; + } + + public List getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(List errorMessage) { + this.errorMessage = errorMessage; + } + + public static class ErrorMessage { + + private String field; + private String code; + private String msg; + + public String getField() { + return field; + } + + public String getCode() { + return code; + } + + public String getMsg() { + return msg; + } + + public void setField(String field) { + this.field = field; + } + + public void setCode(String code) { + this.code = code; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yaoming_1.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yaoming_1.java new file mode 100644 index 0000000000..158f46a54e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_yaoming_1.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.json.bvtVO.AccessHttpConfigModel; + + +public class Bug_for_yaoming_1 extends TestCase { + public void test_0 () throws Exception { + JSON.parseObject("{}", AccessHttpConfigModel.class); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zengjie.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zengjie.java new file mode 100644 index 0000000000..ec65144506 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zengjie.java @@ -0,0 +1,12 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class Bug_for_zengjie extends TestCase { + public void test_0 () throws Exception { + JSON.parse("{123:'abc','value':{123:'abc'}}"); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhaoyao.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhaoyao.java new file mode 100755 index 0000000000..ab5a38d5b4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhaoyao.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Bug_for_zhaoyao extends TestCase { + public void test_FieldMap() throws Exception { + FieldMap map = new FieldMap(); + map.put("a", 1); + map.put("b", 2); + String text = JSON.toJSONString(map, SerializerFeature.WriteClassName); + System.out.println(text); + + FieldMap map2 = (FieldMap) JSON.parse(text); + + Assert.assertTrue(map.equals(map2)); + } + + public static class FieldMap extends HashMap { + + private static final long serialVersionUID = 1L; + + public FieldMap field(String field, Object val) { + this.put(field, val); + return this; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhongyin.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhongyin.java new file mode 100644 index 0000000000..a1a08e06e0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhongyin.java @@ -0,0 +1,84 @@ +package com.alibaba.json.bvt.bug; + +import java.io.UnsupportedEncodingException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + +public class Bug_for_zhongyin extends TestCase { + + public void test_entity() throws Exception { + for (char c = '\u0000'; c < '\u0020'; c++) { + String s = String.valueOf(c) + "entity"; + String jsons = JSON.toJSONString(new VO(s)); + System.out.println(jsons); + VO v = JSON.parseObject(jsons, VO.class); + Assert.assertEquals(s, v.getName()); + } + } + + public void test_map() throws Exception { + for (char c = '\u0000'; c < '\u0020'; c++) { + String s = String.valueOf(c) + "map"; + String jsons = JSON.toJSONString(Collections.singletonMap("value", s)); + System.out.println(jsons); + + JSONObject o = JSON.parseObject(jsons); + Assert.assertEquals(s, o.getString("value")); + } + } + + public void test_0() throws Exception { + String hex = "41544D20E58F96E78EB0EFBC8DE993B6E88194E5908CE59F8E1A20E4BD9BE5B1B1E5B882E7A685E59F8EE58CBAE7A596E5BA99E8B7AF201A33331A20E58FB7E799BEE88AB1E5B9BFE59CBAE9A696E5B182201A"; + String result = getHexStr(hex); + + Map map = new HashMap(); + map.put("aaa" , result); + String stringV = JSON.toJSONString(map); + System.out.println(stringV); + JSONObject o = JSON.parseObject(stringV); + System.out.println(o.getString("aaa")); + + } + + private String getHexStr(String hex) throws UnsupportedEncodingException { + byte []bytes = new byte[hex.length() / 2]; + for(int i = 0 ; i < bytes.length ; i++) { + String v = hex.substring(i * 2 , i * 2 + 2); + bytes[i] = (byte)Integer.parseInt(v , 16); + } + String str = new String(bytes , "UTF-8"); + System.out.println(str); + return str; + } + + public static class VO { + + private String name; + + public VO(){ + + } + + public VO(String name){ + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhuangzaowen.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhuangzaowen.java new file mode 100755 index 0000000000..05e0dc725d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhuangzaowen.java @@ -0,0 +1,131 @@ +package com.alibaba.json.bvt.bug; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; + +public class Bug_for_zhuangzaowen extends TestCase { + + public void test_for_zhuangzaowen() throws Exception { + String value = "{\"begin\":1340263804415,\"buildIds\":[\"42\"],\"end\":1340265305070,\"endBuildId\":\"50\",\"id\":\"4\",\"jobs\":[\"cb-intl-rfqma-UT\",\"cb-intl-rfqma-selenium\"],\"owners\":[\"wb_jianping.shenjp\"],\"triggerBuildId\":\"42\"}"; + System.out.println(JSON.parseObject(value, JenkinsFailedPhase.class, Feature.DisableASM)); + } + + public static class JenkinsFailedPhase {// extends BaseEntity { + + private String id; + public static final String KEY_NAME_SPACE = "phase"; + + private Set owners; + + private List buildIds; + + private Set jobs; + + private Date begin; + + private Date end; + + private String endBuildId; + + private String triggerBuildId; + + /* + * @Override public String generateKey(String id) { return KeyUtils.generatePhaseKey(id); } + */ + + public Set getOwners() { + return owners; + } + + public void setOwners(Set owners) { + this.owners = owners; + } + + public void addOwner(String owner) { + if (owners == null) { + owners = new HashSet(); + } + owners.add(owner); + } + + public List getBuildIds() { + return buildIds; + } + + public void setBuildIds(List buildIds) { + this.buildIds = buildIds; + } + + public void addBuild(String bid) { + if (buildIds == null) { + buildIds = new ArrayList(); + } + buildIds.add(bid); + } + + public Set getJobs() { + return jobs; + } + + public void setJobs(Set jobs) { + this.jobs = jobs; + } + + public void addJobs(String job) { + if (this.jobs == null) { + jobs = new HashSet(); + } + jobs.add(job); + } + + public Date getEnd() { + return end; + } + + public void setEnd(Date end) { + this.end = end; + } + + public Date getBegin() { + return begin; + } + + public void setBegin(Date begin) { + this.begin = begin; + } + + public String getEndBuildId() { + return endBuildId; + } + + public void setEndBuildId(String endBuildId) { + this.endBuildId = endBuildId; + } + + public String getTriggerBuildId() { + return triggerBuildId; + } + + public void setTriggerBuildId(String triggerBuildId) { + this.triggerBuildId = triggerBuildId; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhuel.java b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhuel.java new file mode 100755 index 0000000000..58660e40ac --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Bug_for_zhuel.java @@ -0,0 +1,278 @@ +package com.alibaba.json.bvt.bug; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; + +public class Bug_for_zhuel extends TestCase { + + public void test_for_zhuel() throws Exception { + Person[] ps = new Person[3]; + Person p1 = new Person(); + p1.setAge(50); + p1.setHight("170"); + p1.setId("p1's id"); + p1.setName("person1's name"); + p1.setNames(new String[] { "p1's id", "person1's name" }); + p1.setSex("男"); + Person p2 = new Person(); + p2.setAge(48); + p2.setHight("155"); + p2.setId("p2's id"); + p2.setName("person2's name"); + p2.setNames(new String[] { "p2's id", "person2's name" }); + p2.setSex("女"); + Person p3 = new Person(); + p3.setAge(10); + p3.setHight("120"); + p3.setId("p3's id "); + p3.setName("son's name"); + p3.setNames(new String[] { "p3's id ", "son's name" }); + p3.setSex("男"); + ps[0] = p1; + ps[1] = p2; + ps[2] = p3; + + Person[] ps1 = new Person[3]; + Person pp1 = new Person(); + pp1.setAge(52); + pp1.setHight("170"); + pp1.setId("pp1's id"); + pp1.setName("personpp1's name"); + pp1.setNames(new String[] { "pp1's id", "personpp1's name" }); + pp1.setSex("男"); + Person pp2 = new Person(); + pp2.setAge(49); + pp2.setHight("150"); + pp2.setId("pp2's id"); + pp2.setName("personpp2's name"); + pp2.setNames(new String[] { "pp2's id", "personpp2's name" }); + pp2.setSex("女"); + Person pp3 = new Person(); + pp3.setAge(10); + pp3.setHight("125"); + pp3.setId("pp3's id"); + pp3.setName("daughter's name"); + pp3.setNames(new String[] { "pp3's id", "daughter's name" }); + pp3.setSex("女"); + ps1[0] = pp1; + ps1[1] = pp2; + ps1[2] = pp3; + + Person[] ps2 = new Person[3]; + Person a1 = new Person(); + a1.setAge(52); + a1.setHight("170"); + a1.setId("a1's id"); + a1.setName("a1's name"); + a1.setNames(new String[] { "a1's id", "a1's name" }); + a1.setSex("男"); + Person a2 = new Person(); + a2.setAge(49); + a2.setHight("150"); + a2.setId("a2's id"); + a2.setName("a2's name"); + a2.setNames(new String[] { "a2's id", "a2's name" }); + a2.setSex("女"); + Person a3 = new Person(); + a3.setAge(10); + a3.setHight("125"); + a3.setId("a3's id"); + a3.setName("daughter's name"); + a3.setNames(new String[] { "a3's id", "daughter's name" }); + a3.setSex("女"); + ps2[0] = a1; + ps2[1] = a2; + ps2[2] = a3; + + Family f1 = new Family(); + f1.setId("f1's id"); + f1.setAddress("f1's address"); + f1.setChildrennames(new String[] { "p1's name", "p2's name", "p3's name" }); + f1.setIncome(100000000); + f1.setMaster(p1); + f1.setName("person1's home"); + f1.setPs(ps); + f1.setTest(1994.08); + + Family f2 = new Family(); + f2.setId("f2's id"); + f2.setAddress("f2's address"); + f2.setChildrennames(new String[] { "pp1's name", "pp2's name", "pp3's name" }); + f2.setIncome(100000000); + f2.setMaster(pp1); + f2.setName("personpp1's home"); + f2.setPs(ps1); + Family f3 = new Family(); + f3.setId("f3's id"); + f3.setAddress("f3's address"); + f3.setChildrennames(new String[] { "a1's name", "a2's name", "a3's name" }); + f3.setIncome(100000000); + f3.setMaster(a1); + f3.setName("a1's home"); + f3.setPs(ps2); + f3.setTest(1995.08); + Family[] fs = new Family[3]; + fs[0] = f1; + fs[1] = f2; + fs[2] = f3; + System.out.println(JSON.VERSION); + String sfs = JSON.toJSONString(fs, true); + + Assert.assertSame(fs[0].getMaster(), fs[0].getPs()[0]); + System.out.println(sfs); + + { + Family[] result = JSON.parseObject(sfs, Family[].class); + Assert.assertSame(result[0].getMaster(), result[0].getPs()[0]); + Assert.assertSame(result[1].getMaster(), result[1].getPs()[0]); + Assert.assertSame(result[2].getMaster(), result[2].getPs()[0]); + } + { + JSONArray array = JSON.parseArray(sfs); + for (int i = 0; i < array.size(); ++i) { + JSONObject jsonObj = array.getJSONObject(i); + Assert.assertSame(jsonObj.get("master"), jsonObj.getJSONArray("ps").get(0)); + } + } + } + + public static class Family { + + private String id; + private String name; + private Person[] ps; + private String address; + private String[] childrennames; + private Person master; + private long income; + private double test; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Person[] getPs() { + return ps; + } + + public void setPs(Person[] ps) { + this.ps = ps; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String[] getChildrennames() { + return childrennames; + } + + public void setChildrennames(String[] childrennames) { + this.childrennames = childrennames; + } + + public Person getMaster() { + return master; + } + + public void setMaster(Person master) { + this.master = master; + } + + public long getIncome() { + return income; + } + + public void setIncome(long income) { + this.income = income; + } + + public double getTest() { + return test; + } + + public void setTest(double test) { + this.test = test; + } + } + + public static class Person { + + private String id; + private String name; + private String sex; + private int age; + private String[] names; + private String hight; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSex() { + return sex; + } + + public void setSex(String sex) { + this.sex = sex; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public String[] getNames() { + return names; + } + + public void setNames(String[] names) { + this.names = names; + } + + public String getHight() { + return hight; + } + + public void setHight(String hight) { + this.hight = hight; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue101.java b/src/test/java/com/alibaba/json/bvt/bug/Issue101.java new file mode 100644 index 0000000000..85d7795f18 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue101.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Issue101 extends TestCase { + + public void test_for_issure() throws Exception { + VO vo = new VO(); + vo.a = new Object(); + vo.b = vo.a; + vo.c = vo.a; + + String text = JSON.toJSONString(vo); + Assert.assertEquals("{\"a\":{},\"b\":{},\"c\":{}}", text); + } + + @JSONType(serialzeFeatures=SerializerFeature.DisableCircularReferenceDetect) + public static class VO { + + private Object a; + private Object b; + private Object c; + + public Object getA() { + return a; + } + + public void setA(Object a) { + this.a = a; + } + + public Object getB() { + return b; + } + + public void setB(Object b) { + this.b = b; + } + + public Object getC() { + return c; + } + + public void setC(Object c) { + this.c = c; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue101_NoneASM.java b/src/test/java/com/alibaba/json/bvt/bug/Issue101_NoneASM.java new file mode 100644 index 0000000000..193c7a0041 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue101_NoneASM.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Issue101_NoneASM extends TestCase { + + public void test_for_issure() throws Exception { + VO vo = new VO(); + vo.a = new Object(); + vo.b = vo.a; + vo.c = vo.a; + + String text = JSON.toJSONString(vo); + Assert.assertEquals("{\"a\":{},\"b\":{},\"c\":{}}", text); + } + + @JSONType(serialzeFeatures=SerializerFeature.DisableCircularReferenceDetect) + private static class VO { + + private Object a; + private Object b; + private Object c; + + public Object getA() { + return a; + } + + public void setA(Object a) { + this.a = a; + } + + public Object getB() { + return b; + } + + public void setB(Object b) { + this.b = b; + } + + public Object getC() { + return c; + } + + public void setC(Object c) { + this.c = c; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue101_field.java b/src/test/java/com/alibaba/json/bvt/bug/Issue101_field.java new file mode 100644 index 0000000000..22e9fb668c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue101_field.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Issue101_field extends TestCase { + + public void test_for_issure() throws Exception { + VO vo = new VO(); + vo.a = new Object(); + vo.b = vo.a; + vo.c = vo.a; + + String text = JSON.toJSONString(vo); + Assert.assertEquals("{\"a\":{},\"b\":{},\"c\":{\"$ref\":\"$.b\"}}", text); + } + + public static class VO { + + private Object a; + private Object b; + private Object c; + + public Object getA() { + return a; + } + + public void setA(Object a) { + this.a = a; + } + + @JSONField(serialzeFeatures=SerializerFeature.DisableCircularReferenceDetect) + public Object getB() { + return b; + } + + public void setB(Object b) { + this.b = b; + } + + public Object getC() { + return c; + } + + public void setC(Object c) { + this.c = c; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue101_field_NoneASM.java b/src/test/java/com/alibaba/json/bvt/bug/Issue101_field_NoneASM.java new file mode 100644 index 0000000000..f8bead804c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue101_field_NoneASM.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Issue101_field_NoneASM extends TestCase { + + public void test_for_issure() throws Exception { + VO vo = new VO(); + vo.a = new Object(); + vo.b = vo.a; + vo.c = vo.a; + + String text = JSON.toJSONString(vo); + Assert.assertEquals("{\"a\":{},\"b\":{},\"c\":{\"$ref\":\"$.b\"}}", text); + } + + private static class VO { + + private Object a; + private Object b; + private Object c; + + public Object getA() { + return a; + } + + public void setA(Object a) { + this.a = a; + } + + @JSONField(serialzeFeatures=SerializerFeature.DisableCircularReferenceDetect) + public Object getB() { + return b; + } + + public void setB(Object b) { + this.b = b; + } + + public Object getC() { + return c; + } + + public void setC(Object c) { + this.c = c; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue109.java b/src/test/java/com/alibaba/json/bvt/bug/Issue109.java new file mode 100644 index 0000000000..5dbd0a4cda --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue109.java @@ -0,0 +1,14 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.util.ASMUtils; + + +public class Issue109 extends TestCase { + public void test_for_issue() throws Exception { + Assert.assertFalse(ASMUtils.isAndroid(null)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue115.java b/src/test/java/com/alibaba/json/bvt/bug/Issue115.java new file mode 100644 index 0000000000..483c2b4efa --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue115.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Issue115 extends TestCase { + + public void test_for_issue_115() throws Exception { + Player2 player = new Player2(); + + Card2 card = new Card2(); + card.cardId = "hello"; + player.cards.put(1, card); + player.cardGroup.put(1, card); + + String json = JSON.toJSONString(player); + + System.out.println("json:" + json); + + Player2 player2 = JSON.parseObject(json, Player2.class); + } + + static class Player2 { + + public Map cards = new HashMap(); + public Map cardGroup = new HashMap(); + } + + static class Card2 { + + public String cardId; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue117.java b/src/test/java/com/alibaba/json/bvt/bug/Issue117.java new file mode 100644 index 0000000000..fb721dc522 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue117.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + + +public class Issue117 extends TestCase { + public void test_for_issue() throws Exception { + VO vo = JSON.parseObject("{\"id\":123}", VO.class); + Assert.assertEquals(123, vo.getId()); + vo.setId(124); + vo.equals(null); + vo.hashCode(); + Assert.assertEquals("{\"id\":124}", vo.toString()); + } + + public static interface VO { + public int getId(); + public void setId(int val); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue118.java b/src/test/java/com/alibaba/json/bvt/bug/Issue118.java new file mode 100644 index 0000000000..28af02be89 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue118.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class Issue118 extends TestCase { + public void test_for_issue() throws Exception { + String json = JSON.toJSONString("\0"); + assertEquals("\"\\u0000\"", json); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue119.java b/src/test/java/com/alibaba/json/bvt/bug/Issue119.java new file mode 100644 index 0000000000..0aec8ae052 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue119.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.parser.JSONScanner; + +public class Issue119 extends TestCase { + + public void test_for_issue() throws Exception { + JSONScanner lexer = new JSONScanner("-100S"); + lexer.resetStringPosition(); + lexer.scanNumber(); + Assert.assertEquals(Short.class, lexer.integerValue().getClass()); + Assert.assertEquals(-100, lexer.integerValue().shortValue()); + lexer.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue124.java b/src/test/java/com/alibaba/json/bvt/bug/Issue124.java new file mode 100644 index 0000000000..4a37f95a44 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue124.java @@ -0,0 +1,177 @@ +package com.alibaba.json.bvt.bug; + +import java.util.List; +import java.util.Random; +import java.util.concurrent.CountDownLatch; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Issue124 extends TestCase { + + public void test_for_issue() throws Exception { + // final ObjectMapper mapper = new ObjectMapper(); + // mapper.setSerializationInclusion(Include.NON_NULL); + final Random random = new Random(); + final int threadCount = 1000; + final CountDownLatch latch = new CountDownLatch(threadCount); +// { +// UserInfo info = new UserInfo(); +// CheckInfoVo vo = new CheckInfoVo(100); +// JSON.toJSONString(new SuccessReturn(info), SerializerFeature.WriteDateUseDateFormat); +// JSON.toJSONString(new SuccessReturn(vo), +// SerializerFeature.WriteDateUseDateFormat); +// } + for (int i = 0; i < threadCount; i++) { + new Thread() { + + @Override + public void run() { + UserInfo info = new UserInfo(); + CheckInfoVo vo = new CheckInfoVo(100); + int r = random.nextInt(); + try { + if (r % 2 == 0) { + // System.out.println(mapper.writeValueAsString(info)); + System.out.println(JSON.toJSONString(new SuccessReturn(info), + SerializerFeature.WriteDateUseDateFormat)); + } else { + // System.out.println(mapper.writeValueAsString(vo)); + System.out.println(JSON.toJSONString(new SuccessReturn(vo), + SerializerFeature.WriteDateUseDateFormat)); + } + } catch (Exception e) { + e.printStackTrace(); + System.exit(0); + } finally { + latch.countDown(); + } + } + }.start(); + } + latch.await(); + } + + static class SuccessReturn { + + private int code = 0; + private Object data; + + SuccessReturn(Object data){ + this.data = data; + } + + public int getCode() { + return code; + } + + public Object getData() { + return data; + } + } + + static class CheckInfoVo { + + private final int gmMessageCount; + + public CheckInfoVo(){ + this.gmMessageCount = 0; + } + + public CheckInfoVo(int gmMessageCount){ + this.gmMessageCount = gmMessageCount; + } + + public int getGmMessageCount() { + return gmMessageCount; + } + } + + static class UserInfo { + + private long uid; + private String userName; + private String nickName; + private int userType; + private int avatar; + private String updateTime; + private int modifyNickanme; // 1可以修改nickname 0不能修改 + private long appid; + private List serverIds; + + public long getAppid() { + return appid; + } + + public void setAppid(long appid) { + this.appid = appid; + } + + public long getUid() { + return uid; + } + + public void setUid(long uid) { + this.uid = uid; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public int getUserType() { + return userType; + } + + public void setUserType(int userType) { + this.userType = userType; + } + + public int getAvatar() { + return avatar; + } + + public void setAvatar(int avatar) { + this.avatar = avatar; + } + + public String getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(String updateTime) { + this.updateTime = updateTime; + } + + public String getNickName() { + return nickName; + } + + public void setNickName(String nickName) { + this.nickName = nickName; + } + + public int getModifyNickanme() { + return modifyNickanme; + } + + public void setModifyNickanme(int modifyNickanme) { + this.modifyNickanme = modifyNickanme; + } + + public List getServerIds() { + return serverIds; + } + + public void setServerIds(List serverIds) { + this.serverIds = serverIds; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue125.java b/src/test/java/com/alibaba/json/bvt/bug/Issue125.java new file mode 100644 index 0000000000..742958ce33 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue125.java @@ -0,0 +1,15 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + +public class Issue125 extends TestCase { + + public void test_for_issue() throws Exception { + String content = "{\"data\":\"sfasfasdfasdfas\\r" + String.valueOf((char) 160) + "\\rasdfasdfasd\"}"; + JSONObject jsonObject = JSON.parseObject(content); + System.out.println(jsonObject); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue126.java b/src/test/java/com/alibaba/json/bvt/bug/Issue126.java new file mode 100644 index 0000000000..2fd76b28c9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue126.java @@ -0,0 +1,15 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONObject; + +public class Issue126 extends TestCase { + + public void test_for_issue() throws Exception { + JSONObject j = new JSONObject(); + j.put("content", + "爸爸去哪儿-第十期-萌娃比赛小猪快跑 爸爸上演\"百变大咖秀\"-【湖南卫视官方版1080P】20131213: http://youtu.be/ajvaXKAduJ4 via @youtube"); + System.out.println(j.toJSONString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue127.java b/src/test/java/com/alibaba/json/bvt/bug/Issue127.java new file mode 100644 index 0000000000..f69cd315cb --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue127.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.bug; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + +public class Issue127 extends TestCase { + + public void test_for_issue_127() throws Exception { + String text = "{_BillId:\"X20140106S0110\",_Status:1,_PayStatus:0,_RunEmpId:undefined}"; + JSON.parseObject(text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue141.java b/src/test/java/com/alibaba/json/bvt/bug/Issue141.java new file mode 100644 index 0000000000..1b6f39debd --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue141.java @@ -0,0 +1,14 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.util.TypeUtils; + + +public class Issue141 extends TestCase { + public void test_for_issue() throws Exception { + Assert.assertFalse(TypeUtils.castToBoolean("0").booleanValue()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue143.java b/src/test/java/com/alibaba/json/bvt/bug/Issue143.java new file mode 100644 index 0000000000..a19aa2b803 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue143.java @@ -0,0 +1,76 @@ +package com.alibaba.json.bvt.bug; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; + +public class Issue143 extends TestCase { + + public void test_for_issue() throws Exception { + String text = "{\"rec\":[{},{}]}"; + + JsonStroe store = new JsonStroe(); + + JSONReader reader = new JSONReader(new StringReader(text)); + reader.startObject(); + + String key = reader.readString(); + + Assert.assertEquals("rec", key); + reader.startArray(); + + List list = new ArrayList(); + while(reader.hasNext()) { + KeyValue keyValue = reader.readObject(KeyValue.class); + list.add(keyValue); + } + store.setRec(list); + + reader.endArray(); + + reader.endObject(); + + reader.close(); + } + + public static class JsonStroe { + + private List rec = new ArrayList(); + + public void setRec(List items) { + this.rec = items; + } + + public List getRec() { + return rec; + } + } + + public static class KeyValue { + + private String key; + private String value; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue146.java b/src/test/java/com/alibaba/json/bvt/bug/Issue146.java new file mode 100644 index 0000000000..2254acd43c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue146.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Issue146 extends TestCase { + + public void test_for_issue() throws Exception { + VO vo = new VO(); + JSON json = JSON.parseObject("{}"); + vo.setName(json); + String s = JSON.toJSONString(vo, SerializerFeature.WriteClassName); + System.out.println(s); + JSON.parseObject(s); + } + + public static class VO { + + private int id; + private Object name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Object getName() { + return name; + } + + public void setName(Object name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue153.java b/src/test/java/com/alibaba/json/bvt/bug/Issue153.java new file mode 100644 index 0000000000..4398ee830d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue153.java @@ -0,0 +1,17 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + + +public class Issue153 extends TestCase { + public void test_for_issue() throws Exception { + String text = "[{\"url_short\":\"http://t.cn/8soWK4z\",\"url_long\":\"http://wenshao.com\",\"type\":0}]"; + + JSON.parseObject(text, new TypeReference[]>(){}); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue157.java b/src/test/java/com/alibaba/json/bvt/bug/Issue157.java new file mode 100644 index 0000000000..97ec84ca38 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue157.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONObject; + + +public class Issue157 extends TestCase { + public void test_for_issue() throws Exception { + String m = "2、95开头靓号,呼出显号,对方可以打回,即使不在线亦可设置呼转手机,不错过任何重要电话,不暴露真实身份。\r\n3、应用内完全免费发送文字消息、语音对讲。\r\n4、建议WIFI 或 3G 环境下使用以获得最佳通话体验"; + JSONObject json = new JSONObject(); + json.put("介绍", m); + String content = json.toJSONString(); + System.out.println(content); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue166.java b/src/test/java/com/alibaba/json/bvt/bug/Issue166.java new file mode 100644 index 0000000000..3a80fa0e60 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue166.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.bug; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Issue166 extends TestCase { + + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.setbId("xxxx"); + + String text = JSON.toJSONString(vo, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.WriteEnumUsingToString, + SerializerFeature.WriteNonStringKeyAsString, SerializerFeature.QuoteFieldNames, + SerializerFeature.SkipTransientField, SerializerFeature.SortField, + SerializerFeature.PrettyFormat); + System.out.println(text); + + VO vo2 = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.getbId(), vo2.getbId()); + } + + public static class VO { + + private String bId; + + public String getbId() { + return bId; + } + + public void setbId(String bId) { + this.bId = bId; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue169.java b/src/test/java/com/alibaba/json/bvt/bug/Issue169.java new file mode 100644 index 0000000000..be3e533247 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue169.java @@ -0,0 +1,78 @@ +package com.alibaba.json.bvt.bug; + +import java.io.StringReader; +import java.io.StringWriter; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.JSONWriter; + +public class Issue169 extends TestCase { + + public void test_for_issue() throws Exception { + StringWriter strWriter = new StringWriter(); + + SectionRequest req = new SectionRequest(); + req.setScreenHeight(100);// 父类中的属性 + req.setScreenWidth(12);// 父类中的属性 + req.setTag("11"); + JSONWriter writer = new JSONWriter(strWriter); + writer.startArray(); + writer.writeObject(req); + writer.endArray(); + writer.close(); + + String text = strWriter.toString(); + + StringReader strReader = new StringReader(text); + JSONReader reader = new JSONReader(strReader); + reader.startArray(); + ; + while (reader.hasNext()) { + SectionRequest vo = reader.readObject(SectionRequest.class); + System.out.println("tag:" + vo.getTag() + "screenHeight:" + vo.getScreenHeight() + "ScreenWidth:" + + vo.getScreenWidth()); + Assert.assertEquals(100, vo.getScreenHeight()); + Assert.assertEquals(12, vo.getScreenWidth()); + Assert.assertEquals("11", vo.getTag()); + + } + reader.endArray(); + reader.close(); + } + + public static class SectionRequest { + + private String tag; + private int screenHeight; + private int screenWidth; + + public String getTag() { + return tag; + } + + public void setTag(String tag) { + this.tag = tag; + } + + public int getScreenHeight() { + return screenHeight; + } + + public void setScreenHeight(int screenHeight) { + this.screenHeight = screenHeight; + } + + public int getScreenWidth() { + return screenWidth; + } + + public void setScreenWidth(int screenWidth) { + this.screenWidth = screenWidth; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue171.java b/src/test/java/com/alibaba/json/bvt/bug/Issue171.java new file mode 100644 index 0000000000..77c9ee8579 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue171.java @@ -0,0 +1,19 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Issue171 extends TestCase { + + public void test_for_issue() throws Exception { + Map m = new HashMap(); + m.put("a", "\u000B"); + String json = JSON.toJSONString(m); + System.out.println(json); + JSON.parse(json); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue176.java b/src/test/java/com/alibaba/json/bvt/bug/Issue176.java new file mode 100644 index 0000000000..3ea9d2a597 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue176.java @@ -0,0 +1,51 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; + +public class Issue176 extends TestCase { + + public void test_for_parent() throws Exception { + String text = "{\"content\":\"result\"}"; + + ParentClass parentClass = JSON.parseObject(text, ParentClass.class); + + Assert.assertEquals(parentClass.getTest(), "result"); + + String text2 = JSON.toJSONString(parentClass); + Assert.assertEquals(text, text2); + } + + public void test_for_sub() throws Exception { + String text = "{\"content\":\"result\"}"; + + SubClass parentClass = JSON.parseObject(text, SubClass.class); + + Assert.assertEquals(parentClass.getTest(), "result"); + String text2 = JSON.toJSONString(parentClass); + Assert.assertEquals(text, text2); + } + + public static class ParentClass { + + @JSONField(name = "content") + protected String test; + + public String getTest() { + return test; + } + + public void setTest(String test) { + this.test = test; + } + + } + + public static class SubClass extends ParentClass { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue177.java b/src/test/java/com/alibaba/json/bvt/bug/Issue177.java new file mode 100644 index 0000000000..8171a64a00 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue177.java @@ -0,0 +1,21 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + +public class Issue177 extends TestCase { + + public void test_for_issue_177() throws Exception { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("data", new byte[20]); + + String jsonString = JSON.toJSONString(jsonObject); + JSONObject parseObject = JSON.parseObject(jsonString); + + byte[] bytes = parseObject.getBytes("data"); + + byte[] bs = parseObject.getObject("data", byte[].class); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue179.java b/src/test/java/com/alibaba/json/bvt/bug/Issue179.java new file mode 100644 index 0000000000..726b52cfbe --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue179.java @@ -0,0 +1,62 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + +public class Issue179 extends TestCase { + + public void test_for_issue_179() throws Exception { + Student student = new Student(); + School school = new School(); + school.setStudent(student); + student.setSchool(school); + + // String schoolJSONString = JSON.toJSONString(school); + // System.out.println(schoolJSONString); + // + // School fromJSONSchool = JSON.parseObject(schoolJSONString, + // School.class); + // + // System.out.println(JSON.toJSONString(fromJSONSchool)); + + JSONObject object = new JSONObject(); + object.put("school", school); + + String jsonString = JSON.toJSONString(object); + System.out.println(jsonString); + + JSONObject object2 = (JSONObject) JSON.parseObject(jsonString, JSONObject.class); + System.out.println(JSON.toJSONString(object2)); + + School school2 = object2.getObject("school", School.class); + System.out.println(school2); + } + + public static class School { + + Student student; + + public Student getStudent() { + return student; + } + + public void setStudent(Student student) { + this.student = student; + } + } + + static class Student { + + public School getSchool() { + return school; + } + + public void setSchool(School school) { + this.school = school; + } + + School school; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue183.java b/src/test/java/com/alibaba/json/bvt/bug/Issue183.java new file mode 100644 index 0000000000..4d0ea66283 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue183.java @@ -0,0 +1,66 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; + +public class Issue183 extends TestCase { + + public void test_issue_183() throws Exception { + A a = new A(); + a.setName("xiao").setAge(21); + String result = JSON.toJSONString(a); + A newA = JSON.parseObject(result, A.class); + Assert.assertTrue(a.equals(newA)); + } + + static interface IA { + + @JSONField(name = "wener") + String getName(); + + @JSONField(name = "wener") + IA setName(String name); + } + + static class A implements IA { + + String name; + int age; + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + public A setAge(int age) { + this.age = age; + return this; + } + + public A setName(String name) { + this.name = name; + return this; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + A other = (A) obj; + if (age != other.age) return false; + if (name == null) { + if (other.name != null) return false; + } else if (!name.equals(other.name)) return false; + return true; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue184.java b/src/test/java/com/alibaba/json/bvt/bug/Issue184.java new file mode 100644 index 0000000000..886fda569d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue184.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.bug; + +import java.util.Date; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SimplePropertyPreFilter; + +public class Issue184 extends TestCase { + + public void test_for_issue() throws Exception { + SimplePropertyPreFilter filter = new SimplePropertyPreFilter(); + + VO vo = new VO(); + vo.setDate(new Date()); + String text = JSON.toJSONString(vo, filter); + System.out.println(text); + } + + private static class VO { + + private Date date; + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue190.java b/src/test/java/com/alibaba/json/bvt/bug/Issue190.java new file mode 100644 index 0000000000..1ec92ed623 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue190.java @@ -0,0 +1,18 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class Issue190 extends TestCase { + + public void test_for_issue() throws Exception { + Assert.assertEquals(WebSoscketCommand.A, JSON.parseObject("\"A\"", WebSoscketCommand.class)); + } + + public static enum WebSoscketCommand { + A, B, C + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue199.java b/src/test/java/com/alibaba/json/bvt/bug/Issue199.java new file mode 100644 index 0000000000..4724a93811 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue199.java @@ -0,0 +1,76 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class Issue199 extends TestCase { + + public void test_for_issue() throws Exception { + ConsumeStatus vo = new ConsumeStatus(); + vo.pullRT = 101.01D; + vo.pullTPS = 102.01D; + vo.consumeRT = 103.01D; + vo.consumeOKTPS = 104.01D; + vo.consumeFailedTPS = 105.01D; + + String text = JSON.toJSONString(vo); + ConsumeStatus vo1 = JSON.parseObject(text, ConsumeStatus.class); + Assert.assertTrue(vo.pullRT == vo1.pullRT); + Assert.assertTrue(vo.pullTPS == vo1.pullTPS); + Assert.assertTrue(vo.consumeRT == vo1.consumeRT); + Assert.assertTrue(vo.consumeOKTPS == vo1.consumeOKTPS); + Assert.assertTrue(vo.consumeFailedTPS == vo1.consumeFailedTPS); + } + + public static class ConsumeStatus { + + private double pullRT; + private double pullTPS; + private double consumeRT; + private double consumeOKTPS; + private double consumeFailedTPS; + + public double getPullRT() { + return pullRT; + } + + public void setPullRT(double pullRT) { + this.pullRT = pullRT; + } + + public double getPullTPS() { + return pullTPS; + } + + public void setPullTPS(double pullTPS) { + this.pullTPS = pullTPS; + } + + public double getConsumeRT() { + return consumeRT; + } + + public void setConsumeRT(double consumeRT) { + this.consumeRT = consumeRT; + } + + public double getConsumeOKTPS() { + return consumeOKTPS; + } + + public void setConsumeOKTPS(double consumeOKTPS) { + this.consumeOKTPS = consumeOKTPS; + } + + public double getConsumeFailedTPS() { + return consumeFailedTPS; + } + + public void setConsumeFailedTPS(double consumeFailedTPS) { + this.consumeFailedTPS = consumeFailedTPS; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue204.java b/src/test/java/com/alibaba/json/bvt/bug/Issue204.java new file mode 100644 index 0000000000..640edc5803 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue204.java @@ -0,0 +1,32 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializeFilter; + +public class Issue204 extends TestCase { + + public void test_for_issue() throws Exception { + VO vo = new VO(); + + SerializeFilter filter = null; + JSON.toJSONString(vo, SerializeConfig.getGlobalInstance(), filter); + JSON.toJSONString(vo, SerializeConfig.getGlobalInstance(), new SerializeFilter[0]); + } + + public static class VO { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue208.java b/src/test/java/com/alibaba/json/bvt/bug/Issue208.java new file mode 100644 index 0000000000..ff16c75e68 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue208.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Issue208 extends TestCase { + + public void test_for_issue() throws Exception { + VO vo = new VO (); + vo.序号 = 1001; + vo.名称 = "张三"; + + String text = JSON.toJSONString(vo); + JSON.parseObject(text, VO.class); + + } + + public void test_for_issue_1() throws Exception { + 实体 vo = new 实体 (); + vo.序号 = 1001; + vo.名称 = "张三"; + + String text = JSON.toJSONString(vo); + JSON.parseObject(text, 实体.class); +} + + public static class VO { + + public int 序号; + public String 名称; + } + + public static class 实体 { + + public int 序号; + public String 名称; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue215.java b/src/test/java/com/alibaba/json/bvt/bug/Issue215.java new file mode 100644 index 0000000000..56d9c018ba --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue215.java @@ -0,0 +1,30 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + + +public class Issue215 extends TestCase { + public void test_for_issue() throws Exception { + byte[] bytes = new byte[128]; + new Random().nextBytes(bytes); + + Map map = new HashMap(); + map.put("val", bytes); + + String text = JSON.toJSONString(map); + System.out.println(text); + + Map map2 = JSON.parseObject(text, new TypeReference>() {}); + byte[] bytes2 = (byte[]) map2.get("val"); + Assert.assertArrayEquals(bytes2, bytes); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue215_boolean_array.java b/src/test/java/com/alibaba/json/bvt/bug/Issue215_boolean_array.java new file mode 100644 index 0000000000..4fb7938e2a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue215_boolean_array.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.bug; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + + +public class Issue215_boolean_array extends TestCase { + public void test_for_issue() throws Exception { + boolean[] values = new boolean[128]; + Random random = new Random(); + for (int i = 0; i < values.length; ++i) { + values[i] = random.nextInt() % 2 == 0; + } + + Map map = new HashMap(); + map.put("val", values); + + String text = JSON.toJSONString(map); + System.out.println(text); + + Map map2 = JSON.parseObject(text, new TypeReference>() {}); + boolean[] values2 = (boolean[]) map2.get("val"); + Assert.assertTrue(Arrays.equals(values2, values)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue215_char_array.java b/src/test/java/com/alibaba/json/bvt/bug/Issue215_char_array.java new file mode 100644 index 0000000000..95382cdadc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue215_char_array.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + + +public class Issue215_char_array extends TestCase { + public void test_for_issue() throws Exception { + char[] chars = new char[128]; + Random random = new Random(); + for (int i = 0; i < chars.length; ++i) { + chars[i] = (char) Math.abs((short) random.nextInt()); + } + + Map map = new HashMap(); + map.put("val", chars); + + String text = JSON.toJSONString(map); + System.out.println(text); + + Map map2 = JSON.parseObject(text, new TypeReference>() {}); + char[] chars2 = (char[]) map2.get("val"); + Assert.assertArrayEquals(chars2, chars); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue215_double_array.java b/src/test/java/com/alibaba/json/bvt/bug/Issue215_double_array.java new file mode 100644 index 0000000000..f46f1b31e9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue215_double_array.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.bug; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + + +public class Issue215_double_array extends TestCase { + public void test_for_issue() throws Exception { + double[] values = new double[128]; + Random random = new Random(); + for (int i = 0; i < values.length; ++i) { + values[i] = random.nextDouble(); + } + + Map map = new HashMap(); + map.put("val", values); + + String text = JSON.toJSONString(map); + System.out.println(text); + + Map map2 = JSON.parseObject(text, new TypeReference>() {}); + double[] values2 = (double[]) map2.get("val"); + Assert.assertTrue(Arrays.equals(values2, values)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue215_float_array.java b/src/test/java/com/alibaba/json/bvt/bug/Issue215_float_array.java new file mode 100644 index 0000000000..f33ba0fcc6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue215_float_array.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.bug; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + + +public class Issue215_float_array extends TestCase { + public void test_for_issue() throws Exception { + float[] values = new float[128]; + Random random = new Random(); + for (int i = 0; i < values.length; ++i) { + values[i] = random.nextFloat(); + } + + Map map = new HashMap(); + map.put("val", values); + + String text = JSON.toJSONString(map); + System.out.println(text); + + Map map2 = JSON.parseObject(text, new TypeReference>() {}); + float[] values2 = (float[]) map2.get("val"); + Assert.assertTrue(Arrays.equals(values2, values)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue215_int_array.java b/src/test/java/com/alibaba/json/bvt/bug/Issue215_int_array.java new file mode 100644 index 0000000000..d0a3b3bae6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue215_int_array.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + + +public class Issue215_int_array extends TestCase { + public void test_for_issue() throws Exception { + int[] values = new int[128]; + Random random = new Random(); + for (int i = 0; i < values.length; ++i) { + values[i] = random.nextInt(); + } + + Map map = new HashMap(); + map.put("val", values); + + String text = JSON.toJSONString(map); + System.out.println(text); + + Map map2 = JSON.parseObject(text, new TypeReference>() {}); + int[] values2 = (int[]) map2.get("val"); + Assert.assertArrayEquals(values2, values); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue215_long_array.java b/src/test/java/com/alibaba/json/bvt/bug/Issue215_long_array.java new file mode 100644 index 0000000000..a5cce43545 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue215_long_array.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + + +public class Issue215_long_array extends TestCase { + public void test_for_issue() throws Exception { + long[] values = new long[128]; + Random random = new Random(); + for (int i = 0; i < values.length; ++i) { + values[i] = random.nextLong(); + } + + Map map = new HashMap(); + map.put("val", values); + + String text = JSON.toJSONString(map); + System.out.println(text); + + Map map2 = JSON.parseObject(text, new TypeReference>() {}); + long[] values2 = (long[]) map2.get("val"); + Assert.assertArrayEquals(values2, values); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue215_short_array.java b/src/test/java/com/alibaba/json/bvt/bug/Issue215_short_array.java new file mode 100644 index 0000000000..14603a7cac --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue215_short_array.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + + +public class Issue215_short_array extends TestCase { + public void test_for_issue() throws Exception { + short[] values = new short[128]; + Random random = new Random(); + for (int i = 0; i < values.length; ++i) { + values[i] = (short) random.nextInt(); + } + + Map map = new HashMap(); + map.put("val", values); + + String text = JSON.toJSONString(map); + System.out.println(text); + + Map map2 = JSON.parseObject(text, new TypeReference>() {}); + short[] values2 = (short[]) map2.get("val"); + Assert.assertArrayEquals(values2, values); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue220.java b/src/test/java/com/alibaba/json/bvt/bug/Issue220.java new file mode 100644 index 0000000000..36829af3f0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue220.java @@ -0,0 +1,53 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class Issue220 extends TestCase { + + public void test_for_issue() throws Exception { + Attr attr = new Attr(); + attr.jTType = 123; + attr.value = "xxxx"; + attr.symbol = "yyyy"; + + String text = JSON.toJSONString(attr); + + Assert.assertEquals("{\"jTType\":123,\"symbol\":\"yyyy\",\"value\":\"xxxx\"}", text); + } + + public static class Attr { + + private int jTType; + private String value; + private String symbol; + + public int getjTType() { + return jTType; + } + + public void setjTType(int jTType) { + this.jTType = jTType; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getSymbol() { + return symbol; + } + + public void setSymbol(String symbol) { + this.symbol = symbol; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue243.java b/src/test/java/com/alibaba/json/bvt/bug/Issue243.java new file mode 100644 index 0000000000..7cafaad85d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue243.java @@ -0,0 +1,79 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Issue243 extends TestCase { + + public void testSerialize() { + RpcResponse response = new RpcResponse(2, new Object()); + // String json = JSON.toJSONString(response, SerializerFeature.WriteClassName); // codeA with WriteClassName, + // requestId is not ending with 'L' + String json = response.toCommandJson(); // codeA with WriteClassName, requestId is ending with 'L', and trouble + // other json framework + System.out.println(json); + + String json2 = JSON.toJSONString(response, SerializerFeature.BeanToArray, SerializerFeature.WriteClassName, SerializerFeature.NotWriteRootClassName); + System.out.println(json2); + } + + public static class RpcResponse { + + private int msgType = 50; + private long requestId = 0; + private JSONObject details = new JSONObject(); + private Object[] yieldResult = new Object[1]; + + public RpcResponse(){ + + } + + public RpcResponse(long requestId, Object result){ + this.requestId = requestId; + yieldResult[0] = result; + } + + public int getMsgType() { + return msgType; + } + + public void setMsgType(int msgType) { + this.msgType = msgType; + } + + public long getRequestId() { + return requestId; + } + + public void setRequestId(long requestId) { + this.requestId = requestId; + } + + public JSONObject getDetails() { + return details; + } + + public void setDetails(JSONObject details) { + this.details = details; + } + + public Object[] getYieldResult() { + return yieldResult; + } + + public void setYieldResult(String[] yieldResult) { + this.yieldResult = yieldResult; + } + + protected Object[] fieldToArray() { + return new Object[] { msgType, requestId, details, yieldResult }; + } + + public String toCommandJson() { + return JSON.toJSONString(fieldToArray(), SerializerFeature.WriteClassName); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue248_orderedField.java b/src/test/java/com/alibaba/json/bvt/bug/Issue248_orderedField.java new file mode 100755 index 0000000000..5b09112daf --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue248_orderedField.java @@ -0,0 +1,81 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.Feature; + +public class Issue248_orderedField extends TestCase { + + public void test_0() throws Exception { + String text = "{\"b\":\"b\",\"d\":\"d\",\"c\":\"c\",\"a\":\"a\"}"; + JSONObject object = JSON.parseObject(text, Feature.OrderedField); + System.out.println(object); + + Assert.assertEquals("b", object.keySet().toArray()[0]); + Assert.assertEquals("d", object.keySet().toArray()[1]); + Assert.assertEquals("c", object.keySet().toArray()[2]); + Assert.assertEquals("a", object.keySet().toArray()[3]); + } + + public void test_1() throws Exception { + String text = "{\"a\":\"a\",\"b\":\"b\",\"c\":\"c\",\"d\":\"d\"}"; + System.out.println(JSON.parseObject(text)); + + JSONObject object = JSON.parseObject(text, Feature.OrderedField); + System.out.println(object); + + Assert.assertEquals("a", object.keySet().toArray()[0]); + Assert.assertEquals("b", object.keySet().toArray()[1]); + Assert.assertEquals("c", object.keySet().toArray()[2]); + Assert.assertEquals("d", object.keySet().toArray()[3]); + + } + + public void test_2() throws Exception { + String text = "{\"k1\":\"v1\",\"k3\":\"v3\",\"k2\":\"v2\",\"map\":{\"k1\":\"v1\",\"k3\":\"v3\",\"k2\":\"v2\",\"map\":{\"k1\":\"v1\",\"k3\":\"v3\",\"k2\":\"v2\"}}}"; + System.out.println(JSON.parseObject(text)); + + JSONObject object = JSON.parseObject(text, Feature.OrderedField); + System.out.println(object); + + Assert.assertEquals("k1", object.keySet().toArray()[0]); + Assert.assertEquals("k3", object.keySet().toArray()[1]); + Assert.assertEquals("k2", object.keySet().toArray()[2]); + Assert.assertEquals("map", object.keySet().toArray()[3]); + + Assert.assertEquals("k1", object.getJSONObject("map").keySet().toArray()[0]); + Assert.assertEquals("k3", object.getJSONObject("map").keySet().toArray()[1]); + Assert.assertEquals("k2", object.getJSONObject("map").keySet().toArray()[2]); + Assert.assertEquals("map", object.getJSONObject("map").keySet().toArray()[3]); + + Assert.assertEquals("k1", object.getJSONObject("map").getJSONObject("map").keySet().toArray()[0]); + Assert.assertEquals("k3", object.getJSONObject("map").getJSONObject("map").keySet().toArray()[1]); + Assert.assertEquals("k2", object.getJSONObject("map").getJSONObject("map").keySet().toArray()[2]); + } + + public void test_3() throws Exception { + String text = "{\"k1\":\"v1\",\"k3\":\"v3\",\"k2\":\"v2\",\"list\":[\"v1\",\"v3\",\"v2\",{\"map\":{\"k1\":\"v1\",\"k3\":\"v3\",\"k2\":\"v2\"}}]}"; + System.out.println(JSON.parseObject(text)); + + JSONObject object = JSON.parseObject(text, Feature.OrderedField); + System.out.println(object); + + Assert.assertEquals("k1", object.keySet().toArray()[0]); + Assert.assertEquals("k3", object.keySet().toArray()[1]); + Assert.assertEquals("k2", object.keySet().toArray()[2]); + Assert.assertEquals("list", object.keySet().toArray()[3]); + + Assert.assertEquals("k1", + object.getJSONArray("list").getJSONObject(3).getJSONObject("map").keySet().toArray()[0]); + Assert.assertEquals("k3", + object.getJSONArray("list").getJSONObject(3).getJSONObject("map").keySet().toArray()[1]); + Assert.assertEquals("k2", + object.getJSONArray("list").getJSONObject(3).getJSONObject("map").keySet().toArray()[2]); + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue274.java b/src/test/java/com/alibaba/json/bvt/bug/Issue274.java new file mode 100644 index 0000000000..da625d1a8a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue274.java @@ -0,0 +1,69 @@ +package com.alibaba.json.bvt.bug; + +import java.io.Serializable; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Issue274 extends TestCase { + + public void test() throws Exception { + Customer cus = new Customer(); + cus.setId(1L); + cus.setName("name"); + + Object json = JSON.toJSON(cus); + System.out.println(json); + + String cusJson = json.toString(); + + cusJson = "{\"name\":\"name\",\"id\":1}"; + + Customer customer = JSON.parseObject(cusJson, Customer.class); + + System.out.println(customer); + } + + public interface Indexable { + + public ID getId(); + + public void setId(ID id); + } + + public static class Customer implements Indexable { + + private Long id; + private String name; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "Customer [id=" + id + ", name=" + name + "]"; + } + + // remove this to then no longer throw exception + public Map toIndexMap() { + + return null; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue62.java b/src/test/java/com/alibaba/json/bvt/bug/Issue62.java new file mode 100644 index 0000000000..1e892c3fe6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue62.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Issue62 extends TestCase { + + public void test_for_issue() throws Exception { + A a = new A(); + a.setA("aaaaaaaaaa".getBytes()); + a.setB(1); + a.setC("aaaa"); + String jsonData = JSON.toJSONString(a, SerializerFeature.UseSingleQuotes); + Assert.assertEquals("{'a':'YWFhYWFhYWFhYQ==','b':1,'c':'aaaa'}", jsonData); + JSON.parse(jsonData); + } + + static class A { + + private byte[] a; + private int b; + private String c; + + public byte[] getA() { + return a; + } + + public void setA(byte[] a) { + this.a = a; + } + + public int getB() { + return b; + } + + public void setB(int b) { + this.b = b; + } + + public String getC() { + return c; + } + + public void setC(String c) { + this.c = c; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue64.java b/src/test/java/com/alibaba/json/bvt/bug/Issue64.java new file mode 100644 index 0000000000..8c9b95619d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue64.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.bug; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class Issue64 extends TestCase { + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.foo = "xxxxxx"; + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + + Assert.assertEquals("[\"xxxxxx\"]", text); + + VO vo2 = JSON.parseObject(text, VO.class, Feature.SupportArrayToBean); + Assert.assertEquals(vo2.foo, vo.foo); + } + + public static class VO { + public String foo = "bar"; + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue69.java b/src/test/java/com/alibaba/json/bvt/bug/Issue69.java new file mode 100644 index 0000000000..d81e67a31c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue69.java @@ -0,0 +1,60 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class Issue69 extends TestCase { + + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.a = new Entry(); + vo.b = vo.a; + + String text = JSON.toJSONString(vo); + System.out.println(text); + } + + @JSONType(serialzeFeatures={SerializerFeature.DisableCircularReferenceDetect}) + public static class VO { + + private Entry a; + + private Entry b; + + public Entry getA() { + return a; + } + + public void setA(Entry a) { + this.a = a; + } + + public Entry getB() { + return b; + } + + public void setB(Entry b) { + this.b = b; + } + + } + + public static class Entry { + private int id; + + + public int getId() { + return id; + } + + + public void setId(int id) { + this.id = id; + } + + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue72.java b/src/test/java/com/alibaba/json/bvt/bug/Issue72.java new file mode 100644 index 0000000000..fc59193a99 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue72.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.bug; + +import java.io.InputStream; +import java.io.InputStreamReader; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.util.IOUtils; + +public class Issue72 extends TestCase { + + public void test_for_issue() throws Exception { + InputStream is = Issue72.class.getClassLoader().getResourceAsStream("issue72.json"); + JSONReader reader = null; + try { + byte[] rowBatchBytes = null; + byte[] fileBatchBytes = null; + reader = new JSONReader(new InputStreamReader(is)); + reader.startArray(); + while (reader.hasNext()) { + if (rowBatchBytes == null) { + rowBatchBytes = reader.readObject(byte[].class); + } else if (fileBatchBytes == null) { + fileBatchBytes = reader.readObject(byte[].class); + } else { + throw new Exception("archive data json parse failed!"); + } + + } + reader.endArray(); + } finally { + IOUtils.close(reader); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue74.java b/src/test/java/com/alibaba/json/bvt/bug/Issue74.java new file mode 100644 index 0000000000..8890ce724a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue74.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt.bug; + +import java.io.InputStream; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; + + +public class Issue74 extends TestCase { + public void test_for_issue() throws Exception { + InputStream is = Issue72.class.getClassLoader().getResourceAsStream("issue74.json"); + String text = org.apache.commons.io.IOUtils.toString(is); + is.close(); + + JSONArray json = (JSONArray) JSON.parse(text); + + Assert.assertNotNull(json.getJSONObject(0).getJSONObject("dataType").getJSONObject("categoryType").getJSONArray("dataTypes").get(0)); + Assert.assertSame(json.getJSONObject(0).getJSONObject("dataType"), json.getJSONObject(0).getJSONObject("dataType").getJSONObject("categoryType").getJSONArray("dataTypes").get(0)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue79.java b/src/test/java/com/alibaba/json/bvt/bug/Issue79.java new file mode 100644 index 0000000000..86c87b6f9b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue79.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.bug; + +import java.util.List; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Issue79 extends TestCase { + + public void test_for_issue_79() throws Exception { + SearchResult result = JSON.parseObject("{\"present\":{\"records\":[{}]}}", SearchResult.class); + Assert.assertNotNull(result.present); + Assert.assertNotNull(result.present.records); + Assert.assertNotNull(result.present.records.get(0)); + Assert.assertNotNull(result.present.records.get(0) instanceof PresentRecord); + } + + public static class SearchResult { + + public Present present; + } + + public static class Present { + + public List records; + } + + public static class PresentRecord { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue87.java b/src/test/java/com/alibaba/json/bvt/bug/Issue87.java new file mode 100644 index 0000000000..694903e1b6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue87.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashSet; +import java.util.Set; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + + +public class Issue87 extends TestCase { + public void test_for_issue() throws Exception { + TestObject to = new TestObject(); + to.add("test1"); + to.add("test2"); + String text = JSON.toJSONString(to); + System.out.println(text); + JSONObject jo = JSON.parseObject(text); + to = JSON.toJavaObject(jo, TestObject.class); + } + + public static class TestObject { + + private Set set = new HashSet(0); + + public Set getSet() { + return set; + } + + public void setSet(Set set) { + this.set = set; + } + + public void add(String str) { + set.add(str); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue87_hashset.java b/src/test/java/com/alibaba/json/bvt/bug/Issue87_hashset.java new file mode 100644 index 0000000000..89f27ed2a2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue87_hashset.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashSet; +import java.util.Set; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + + +public class Issue87_hashset extends TestCase { + public void test_for_issue() throws Exception { + TestObject to = new TestObject(); + to.add("test1"); + to.add("test2"); + String text = JSON.toJSONString(to); + System.out.println(text); + JSONObject jo = JSON.parseObject(text); + to = JSON.toJavaObject(jo, TestObject.class); + } + + public static class TestObject { + + private HashSet set = new HashSet(0); + + public HashSet getSet() { + return set; + } + + public void setSet(HashSet set) { + this.set = set; + } + + public void add(String str) { + set.add(str); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue87_treeset.java b/src/test/java/com/alibaba/json/bvt/bug/Issue87_treeset.java new file mode 100644 index 0000000000..dffd5a14d6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue87_treeset.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.bug; + +import java.util.TreeSet; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + + +public class Issue87_treeset extends TestCase { + public void test_for_issue() throws Exception { + TestObject to = new TestObject(); + to.add("test1"); + to.add("test2"); + String text = JSON.toJSONString(to); + System.out.println(text); + JSONObject jo = JSON.parseObject(text); + to = JSON.toJavaObject(jo, TestObject.class); + } + + public static class TestObject { + + private TreeSet set = new TreeSet(); + + public TreeSet getSet() { + return set; + } + + public void setSet(TreeSet set) { + this.set = set; + } + + public void add(String str) { + set.add(str); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue89.java b/src/test/java/com/alibaba/json/bvt/bug/Issue89.java new file mode 100644 index 0000000000..739881a26b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue89.java @@ -0,0 +1,20 @@ +package com.alibaba.json.bvt.bug; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Issue89 extends TestCase { + + public void test_for_issue() throws Exception { + Exception error = null; + try { + JSON.parse("{\"a\":з」∠)_,\"}"); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue94.java b/src/test/java/com/alibaba/json/bvt/bug/Issue94.java new file mode 100644 index 0000000000..99ba9906e8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue94.java @@ -0,0 +1,14 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONObject; + + +public class Issue94 extends TestCase { + public void test_for_issue() throws Exception { + JSONObject o = new JSONObject(); + o.put("line", "{\"1\":\u0080}"); + o.toString(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/Issue96.java b/src/test/java/com/alibaba/json/bvt/bug/Issue96.java new file mode 100644 index 0000000000..d8fbe16bb4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/Issue96.java @@ -0,0 +1,79 @@ +package com.alibaba.json.bvt.bug; + +import java.lang.reflect.Type; + +import junit.framework.TestCase; + +import org.junit.Test; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.util.TypeUtils; + +public class Issue96 extends TestCase { + + public void test_for_issue() throws Exception { + Page page = new Page(new Sub(1)); + Type type = new TypeReference>() { + }.getType(); + // this is ok + Page page1 = JSON.parseObject(JSON.toJSONString(page), type); + System.out.println(page1.sub.getClass()); + } + + public void xx_testCast() { + Page page = new Page(new Sub(1)); + Type type = new TypeReference>() { + }.getType(); + ParserConfig parserconfig = ParserConfig.getGlobalInstance(); + // !!!! this will fail: + // !!!! com.alibaba.fastjson.JSONException: can not cast to : Page TypeUtils.java:719 + Page page1 = TypeUtils.cast(page, type, parserconfig); + System.out.println(page1.sub.getClass()); + } + + static class Page { + + public Page(){ + super(); + } + + public Page(T sub){ + super(); + this.sub = sub; + } + + T sub; + + public T getSub() { + return sub; + } + + public void setSub(T sub) { + this.sub = sub; + } + } + + static class Sub { + + public Sub(){ + super(); + } + + public Sub(int id){ + super(); + this.id = id; + } + + int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/bug/JSONTest.java b/src/test/java/com/alibaba/json/bvt/bug/JSONTest.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/bug/JSONTest.java rename to src/test/java/com/alibaba/json/bvt/bug/JSONTest.java index 3a28bce1fb..14d61ded37 --- a/src/test/java/com/alibaba/json/test/bvt/bug/JSONTest.java +++ b/src/test/java/com/alibaba/json/bvt/bug/JSONTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.bug; +package com.alibaba.json.bvt.bug; import java.util.ArrayList; import java.util.List; diff --git a/src/test/java/com/alibaba/json/bvt/bug/KeyBug_for_zhongl.java b/src/test/java/com/alibaba/json/bvt/bug/KeyBug_for_zhongl.java new file mode 100644 index 0000000000..c5e29e239e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/KeyBug_for_zhongl.java @@ -0,0 +1,62 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; + +public class KeyBug_for_zhongl extends TestCase { + + public void testCustomedKey() throws Exception { + Assert.assertEquals("{\"uid\":1}", JSON.toJSONString(new V2(1))); + } + + public void testDeserialize() throws Exception { + Assert.assertEquals(123, JSON.parseObject("{\"uid\":123}", V2.class).id); + } + + public void testCustomedKey_static() throws Exception { + Assert.assertEquals("{\"uid\":1}", JSON.toJSONString(new VO(1))); + } + + public void testDeserialize_static() throws Exception { + Assert.assertEquals(123, JSON.parseObject("{\"uid\":123}", VO.class).id); + } + + public static class VO { + + @JSONField(name = "uid") + public int id; + + @JSONField(serialize = false) + public String name = "defaultName"; + + public VO(){ + + } + + VO(int id){ + this.id = id; + } + } + + private static class V2 { + + @JSONField(name = "uid") + public int id; + + @JSONField(serialize = false) + public String name = "defaultName"; + + private V2() { + + } + + private V2(int id) { + this.id = id; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/SerDeserTest.java b/src/test/java/com/alibaba/json/bvt/bug/SerDeserTest.java new file mode 100755 index 0000000000..a03506cf15 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/SerDeserTest.java @@ -0,0 +1,73 @@ +/* + * Copyright 2011 Alibaba.com All right reserved. This software is the + * confidential and proprietary information of Alibaba.com ("Confidential + * Information"). You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Alibaba.com. + */ +package com.alibaba.json.bvt.bug; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.json.bvtVO.OptionKey; +import com.alibaba.json.bvtVO.OptionValue; +import com.alibaba.json.bvtVO.TempAttachMetaOption; + +/** + * 类SerDeserTest.java的实现描述:TODO 类实现描述 + * + * @author lei.yaol 2011-12-27 下午03:44:18 + */ +public class SerDeserTest extends TestCase { + + /** 用于被FastJson序列和反序列化的对象 */ + private static Map> options; + + static { + options = new HashMap>(); + + TempAttachMetaOption attach = new TempAttachMetaOption(); + attach.setId(1000); + attach.setName("test_name"); + attach.setPath("http://alibaba-inc.com/test.txt"); + + ArrayList attachList = new ArrayList(); + attachList.add(attach); + + // 设置value + OptionValue> optionValue = new OptionValue>(); + optionValue.setValue(attachList); + + options.put(OptionKey.TEMPALTE_ATTACH_META, optionValue); + } + + public void test_for_yaolei() { + // 序列化toJSONString() + String jsonString = JSON.toJSONString(options); + System.out.println(jsonString); + { + // 反序列化parse() + HashMap> deserOptions = (HashMap>) JSON.parseObject(jsonString, + new TypeReference>>() { + + }); + System.out.println(deserOptions.get(OptionKey.TEMPALTE_ATTACH_META)); + } + + // 序列化toJSONString(,) + jsonString = JSON.toJSONString(options, SerializerFeature.WriteClassName); + System.out.println(jsonString); + // 反序列化parse() + HashMap> deserOptions = (HashMap>) JSON.parse(jsonString); + System.out.println(deserOptions.get(OptionKey.TEMPALTE_ATTACH_META)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/StackTraceElementTest.java b/src/test/java/com/alibaba/json/bvt/bug/StackTraceElementTest.java new file mode 100755 index 0000000000..30ed216314 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/StackTraceElementTest.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt.bug; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class StackTraceElementTest extends TestCase { + public void test_stackTrace() throws Exception { + StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); + String text = JSON.toJSONString(stackTrace, SerializerFeature.WriteClassName); + JSONArray array = (JSONArray) JSON.parse(text); + for (int i = 0; i < array.size(); ++i) { + StackTraceElement element = (StackTraceElement) array.get(i); + Assert.assertEquals(stackTrace[i].getFileName(), element.getFileName()); + Assert.assertEquals(stackTrace[i].getLineNumber(), element.getLineNumber()); + Assert.assertEquals(stackTrace[i].getClassName(), element.getClassName()); + Assert.assertEquals(stackTrace[i].getMethodName(), element.getMethodName()); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/StackTraceElementTest2.java b/src/test/java/com/alibaba/json/bvt/bug/StackTraceElementTest2.java new file mode 100755 index 0000000000..faf9fcd745 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/StackTraceElementTest2.java @@ -0,0 +1,13 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class StackTraceElementTest2 extends TestCase { + public void test_stackTrace2() throws Exception { + String text = "{\"@type\":\"java.lang.StackTraceElement\",\"className\":\"java.lang.Thread\",\"fileName\":\"Thread.java\",\"lineNumber\":1503,\"methodName\":\"getStackTrace\",\"nativeMethod\":false}"; + JSON.parseObject(text, StackTraceElement.class); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/bug/TestDouble.java b/src/test/java/com/alibaba/json/bvt/bug/TestDouble.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/bug/TestDouble.java rename to src/test/java/com/alibaba/json/bvt/bug/TestDouble.java index 87ffb70c37..f6a889ed74 --- a/src/test/java/com/alibaba/json/test/bvt/bug/TestDouble.java +++ b/src/test/java/com/alibaba/json/bvt/bug/TestDouble.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.bug; +package com.alibaba.json.bvt.bug; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/bvt/bug/TestJSONMap.java b/src/test/java/com/alibaba/json/bvt/bug/TestJSONMap.java new file mode 100755 index 0000000000..e351deb427 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/TestJSONMap.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.bug; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class TestJSONMap extends TestCase { + + public void test_0() throws Exception { + Record record = new Record(); + Map map = new HashMap(); + record.setRecord(map); + String s = JSON.toJSONString(record, SerializerFeature.WriteClassName); + System.out.println(s); + record = (Record)JSON.parse(s); //此处抛出异常 + System.out.println(record.getRecord().size()); + } + + public static class Record { + + private Map record; + + public Map getRecord() { + return record; + } + + public void setRecord(Map record) { + this.record = record; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/bug_for_caoyaojun1988.java b/src/test/java/com/alibaba/json/bvt/bug/bug_for_caoyaojun1988.java new file mode 100755 index 0000000000..49d6d63973 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/bug_for_caoyaojun1988.java @@ -0,0 +1,160 @@ +package com.alibaba.json.bvt.bug; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class bug_for_caoyaojun1988 extends TestCase { + + public void test_for_bug() throws Exception { + // 创建 BusinessVO + BusinessVO businessVO = new BusinessVO(); + businessVO.setName("name"); + + // 创建 第一个List list中每一个对象都包含 BusinessVO对象 + ExpiredDto expiredDto = new ExpiredDto(); + expiredDto.setBusinessVO(businessVO); + expiredDto.setId(10001); + + List expiredReports = new ArrayList(); + expiredReports.add(expiredDto); + + // 创建 第二个List list中每一个对象都包含 BusinessVO对象 + + List normalReports = new ArrayList(); + { + NormalDto normalDto = new NormalDto(); + normalDto.setBusinessVO(businessVO); + normalDto.setId(10001); + normalReports.add(normalDto); + } + + // 创建 需要序列化的对象,包含两个list + ReportDto reportDto = new ReportDto(); + reportDto.setExpiredReports(expiredReports); + reportDto.setNormalReports(normalReports); + reportDto.setCompanyId(10004); + + // 第一个场景 得到的businessVO为null; + String serializeStr = (String) JSON.toJSONString(reportDto); + System.out.println(serializeStr); + ReportDto reuslt = (ReportDto) JSON.parseObject(serializeStr, ReportDto.class); + System.out.println(reuslt.getNormalReports().get(0).getBusinessVO()); + + // 第二个场景 得到的businessVO为正常数据 + expiredReports.add(expiredDto); + serializeStr = (String) JSON.toJSONString(reportDto); + System.out.println(serializeStr); + reuslt = (ReportDto) JSON.parseObject(serializeStr, ReportDto.class); + System.out.print(reuslt.getNormalReports().get(0).getBusinessVO().getName()); + } + + public static class BusinessVO implements Serializable { + + private static final long serialVersionUID = -191856665415285103L; + private String name; + + public BusinessVO() { + + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + } + + public static class ExpiredDto implements Serializable { + + private static final long serialVersionUID = -2361763020563748437L; + private Integer id; + private BusinessVO businessVO; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public BusinessVO getBusinessVO() { + return businessVO; + } + + public void setBusinessVO(BusinessVO businessVO) { + this.businessVO = businessVO; + } + + } + + public static class NormalDto implements Serializable { + + private static final long serialVersionUID = -2392077150026945111L; + private Integer id; + private BusinessVO businessVO; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public BusinessVO getBusinessVO() { + return businessVO; + } + + public void setBusinessVO(BusinessVO businessVO) { + this.businessVO = businessVO; + } + + public static long getSerialversionuid() { + return serialVersionUID; + } + + } + + public static class ReportDto implements Serializable { + + private static final long serialVersionUID = 4502937258945851832L; + private Integer companyId; + private List normalReports; + private List expiredReports; + + public Integer getCompanyId() { + return companyId; + } + + public void setCompanyId(Integer companyId) { + this.companyId = companyId; + } + + public List getNormalReports() { + return normalReports; + } + + public void setNormalReports(List normalReports) { + this.normalReports = normalReports; + } + + public List getExpiredReports() { + return expiredReports; + } + + public void setExpiredReports(List expiredReports) { + this.expiredReports = expiredReports; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/bug/bug_for_pengsong0302.java b/src/test/java/com/alibaba/json/bvt/bug/bug_for_pengsong0302.java new file mode 100644 index 0000000000..baf178140c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/bug/bug_for_pengsong0302.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.bug; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class bug_for_pengsong0302 extends TestCase { + + public void test_0() throws Exception { + Assert.assertEquals("\"a\\u2028b\"", JSON.toJSONString("a\u2028b")); + } + + public void test_1() throws Exception { + Assert.assertEquals("{\"value\":\"a\\u2028b\"}", JSON.toJSONString(new A("a\u2028b"))); + } + + public static class A { + + private String value; + + public A(String value){ + super(); + this.value = value; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/cglib/TestCglib.java b/src/test/java/com/alibaba/json/bvt/cglib/TestCglib.java new file mode 100755 index 0000000000..127f3fc75c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/cglib/TestCglib.java @@ -0,0 +1,68 @@ +package com.alibaba.json.bvt.cglib; + +import java.lang.reflect.Method; + +import org.junit.Assert; +import junit.framework.TestCase; +import net.sf.cglib.proxy.Enhancer; +import net.sf.cglib.proxy.MethodInterceptor; +import net.sf.cglib.proxy.MethodProxy; + +import com.alibaba.fastjson.JSON; + +public class TestCglib extends TestCase { + + public void test_cglib() throws Exception { + Enhancer enhancer = new Enhancer(); + enhancer.setSuperclass(Entity.class); + enhancer.setCallback(new Proxy()); + Entity entity = (Entity) enhancer.create(); + + entity.setId(3); + entity.setName("Jobs"); + + String text = JSON.toJSONString(entity); + Assert.assertEquals("{\"id\":3,\"name\":\"Jobs\"}", text); + + } + + public static class Proxy implements MethodInterceptor { + + public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { + return proxy.invokeSuper(obj, args); + } + + } + + public static class Entity { + + private int id; + private String name; + + public Entity(){ + + } + + public Entity(int id, String name){ + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/compatible/jsonlib/CompatibleTest0.java b/src/test/java/com/alibaba/json/bvt/compatible/jsonlib/CompatibleTest0.java old mode 100644 new mode 100755 similarity index 99% rename from src/test/java/com/alibaba/json/test/bvt/compatible/jsonlib/CompatibleTest0.java rename to src/test/java/com/alibaba/json/bvt/compatible/jsonlib/CompatibleTest0.java index 1f5e2d7d11..a3a26f0b64 --- a/src/test/java/com/alibaba/json/test/bvt/compatible/jsonlib/CompatibleTest0.java +++ b/src/test/java/com/alibaba/json/bvt/compatible/jsonlib/CompatibleTest0.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.compatible.jsonlib; +package com.alibaba.json.bvt.compatible.jsonlib; import java.math.BigDecimal; import java.math.BigInteger; @@ -7,7 +7,7 @@ import java.util.List; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/compatible/jsonlib/CompatibleTest_noasm.java b/src/test/java/com/alibaba/json/bvt/compatible/jsonlib/CompatibleTest_noasm.java old mode 100644 new mode 100755 similarity index 99% rename from src/test/java/com/alibaba/json/test/bvt/compatible/jsonlib/CompatibleTest_noasm.java rename to src/test/java/com/alibaba/json/bvt/compatible/jsonlib/CompatibleTest_noasm.java index 189887bfdb..e4c0b72ff4 --- a/src/test/java/com/alibaba/json/test/bvt/compatible/jsonlib/CompatibleTest_noasm.java +++ b/src/test/java/com/alibaba/json/bvt/compatible/jsonlib/CompatibleTest_noasm.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.compatible.jsonlib; +package com.alibaba.json.bvt.compatible.jsonlib; import java.math.BigDecimal; import java.math.BigInteger; @@ -7,7 +7,7 @@ import java.util.List; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/dubbo/TestForDubbo.java b/src/test/java/com/alibaba/json/bvt/dubbo/TestForDubbo.java new file mode 100755 index 0000000000..70a26d3421 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/dubbo/TestForDubbo.java @@ -0,0 +1,83 @@ +package com.alibaba.json.bvt.dubbo; + +import java.util.ArrayList; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.json.test.dubbo.FullAddress; +import com.alibaba.json.test.dubbo.HelloServiceImpl; +import com.alibaba.json.test.dubbo.Person; +import com.alibaba.json.test.dubbo.PersonInfo; +import com.alibaba.json.test.dubbo.PersonStatus; +import com.alibaba.json.test.dubbo.Phone; +import com.alibaba.json.test.dubbo.Tiger; +import com.alibaba.json.test.dubbo.Tigers; + +public class TestForDubbo extends TestCase { + + static Person person; + + static { + person = new Person(); + person.setPersonId("superman111"); + person.setLoginName("superman"); + person.setEmail("sm@1.com"); + person.setPenName("pname"); + person.setStatus(PersonStatus.ENABLED); + + ArrayList phones = new ArrayList(); + Phone phone1 = new Phone("86", "0571", "87654321", "001"); + Phone phone2 = new Phone("86", "0571", "87654322", "002"); + phones.add(phone1); + phones.add(phone2); + PersonInfo pi = new PersonInfo(); + pi.setPhones(phones); + Phone fax = new Phone("86", "0571", "87654321", null); + pi.setFax(fax); + FullAddress addr = new FullAddress("CN", "zj", "3480", "wensanlu", "315000"); + pi.setFullAddress(addr); + pi.setMobileNo("13584652131"); + pi.setMale(true); + pi.setDepartment("b2b"); + pi.setHomepageUrl("www.capcom.com"); + pi.setJobTitle("qa"); + pi.setName("superman"); + person.setInfoProfile(pi); + } + + private HelloServiceImpl helloService = new HelloServiceImpl(); + + public void f_testParamType4() { + Tiger tiger = new Tiger(); + tiger.setTigerName("东北虎"); + tiger.setTigerSex(true); + Tigers tigers = helloService.eatTiger(tiger); + + String text = JSON.toJSONString(tigers, SerializerFeature.WriteClassName); + System.out.println(text); + + Tigers tigers2 = JSON.parseObject(text, Tigers.class); + + Assert.assertEquals(text, JSON.toJSONString(tigers2, SerializerFeature.WriteClassName)); + } + + public void testPerson() { + Person p = helloService.showPerson(person); + String text = JSON.toJSONString(p, SerializerFeature.WriteClassName); + System.out.println(text); + + Person result = JSON.parseObject(text, Person.class); + + assertEquals(result.getInfoProfile().getPhones().get(0).getArea(), + person.getInfoProfile().getPhones().get(0).getArea()); + assertEquals(result.getInfoProfile().getPhones().get(0).getCountry(), + person.getInfoProfile().getPhones().get(0).getCountry()); + assertEquals(result.getInfoProfile().getPhones().get(0).getExtensionNumber(), + person.getInfoProfile().getPhones().get(0).getExtensionNumber()); + assertEquals(result.getInfoProfile().getPhones().get(0).getNumber(), + person.getInfoProfile().getPhones().get(0).getNumber()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/fullSer/LongTest.java b/src/test/java/com/alibaba/json/bvt/fullSer/LongTest.java new file mode 100755 index 0000000000..75a4034676 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/fullSer/LongTest.java @@ -0,0 +1,34 @@ +package com.alibaba.json.bvt.fullSer; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +import org.junit.Assert; +import junit.framework.TestCase; + +public class LongTest extends TestCase { + + public void test_0() throws Exception { + + VO vo = new VO(); + vo.setValue(33L); + + String text = JSON.toJSONString(vo, SerializerFeature.WriteClassName); + System.out.println(text); + + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.fullSer.LongTest$VO\",\"value\":33}", text); + } + + public static class VO { + + private Long value; + + public Long getValue() { + return value; + } + + public void setValue(Long value) { + this.value = value; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/fullSer/get_set_Test.java b/src/test/java/com/alibaba/json/bvt/fullSer/get_set_Test.java new file mode 100644 index 0000000000..c1496a36e3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/fullSer/get_set_Test.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.fullSer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class get_set_Test extends TestCase { + + public void test_codec() throws Exception { + VO vo = new VO(); + vo.set_id(123); + + String text = JSON.toJSONString(vo); + Assert.assertEquals("{\"id\":123}", text); + VO vo1 = JSON.parseObject(text, VO.class); + Assert.assertEquals(123, vo1.get_id()); + } + + public static class VO { + + private int id; + + public int get_id() { + return id; + } + + public void set_id(int id) { + this.id = id; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/fullSer/getfTest.java b/src/test/java/com/alibaba/json/bvt/fullSer/getfTest.java new file mode 100644 index 0000000000..2b9104e83f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/fullSer/getfTest.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.fullSer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.json.bvt.fullSer.get_set_Test.VO; + +public class getfTest extends TestCase { + + public void test_codec() throws Exception { + VO vo = new VO(); + vo.setfId(123); + + String text = JSON.toJSONString(vo); + Assert.assertEquals("{\"fId\":123}", text); + VO vo1 = JSON.parseObject(text, VO.class); + Assert.assertEquals(123, vo1.getfId()); + } + + public static class VO { + + private int fId; + + + public int getfId() { + return fId; + } + + + public void setfId(int fId) { + this.fId = fId; + } + + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/fullSer/getfTest_2.java b/src/test/java/com/alibaba/json/bvt/fullSer/getfTest_2.java new file mode 100644 index 0000000000..a167f2136f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/fullSer/getfTest_2.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.fullSer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.json.bvt.fullSer.get_set_Test.VO; + +public class getfTest_2 extends TestCase { + + public void test_codec() throws Exception { + VO vo = new VO(); + vo.setfFlag(true); + + String text = JSON.toJSONString(vo); + Assert.assertEquals("{\"fFlag\":true}", text); + VO vo1 = JSON.parseObject(text, VO.class); + Assert.assertEquals(true, vo1.isfFlag()); + } + + public static class VO { + + private boolean fFlag; + + public boolean isfFlag() { + return fFlag; + } + + public void setfFlag(boolean fFlag) { + this.fFlag = fFlag; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/fullSer/is_set_test_2.java b/src/test/java/com/alibaba/json/bvt/fullSer/is_set_test_2.java new file mode 100644 index 0000000000..3a9978b2ce --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/fullSer/is_set_test_2.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.fullSer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.json.bvt.fullSer.get_set_Test.VO; + +public class is_set_test_2 extends TestCase { + + public void test_codec() throws Exception { + VO vo = new VO(); + vo.set_flag(true); + + String text = JSON.toJSONString(vo); + Assert.assertEquals("{\"flag\":true}", text); + VO vo1 = JSON.parseObject(text, VO.class); + Assert.assertEquals(true, vo1.is_flag()); + } + + public static class VO { + + private boolean flag; + + public boolean is_flag() { + return flag; + } + + public void set_flag(boolean flag) { + this.flag = flag; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/jdk8/DurationTest.java b/src/test/java/com/alibaba/json/bvt/jdk8/DurationTest.java new file mode 100644 index 0000000000..771eb468db --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/jdk8/DurationTest.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.jdk8; + +import java.time.Duration; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class DurationTest extends TestCase { + + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.setDate(Duration.ofHours(3)); + + String text = JSON.toJSONString(vo); + System.out.println(text); + + VO vo1 = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.getDate(), vo1.getDate()); + } + + public static class VO { + + private Duration date; + + public Duration getDate() { + return date; + } + + public void setDate(Duration date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/jdk8/InstantTest.java b/src/test/java/com/alibaba/json/bvt/jdk8/InstantTest.java new file mode 100644 index 0000000000..c6c18ef05f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/jdk8/InstantTest.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.jdk8; + +import java.time.Instant; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class InstantTest extends TestCase { + + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.setDate(Instant.now()); + + String text = JSON.toJSONString(vo); + System.out.println(text); + + VO vo1 = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.getDate(), vo1.getDate()); + } + + public static class VO { + + private Instant date; + + public Instant getDate() { + return date; + } + + public void setDate(Instant date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTest.java b/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTest.java new file mode 100644 index 0000000000..5e959c8e4d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTest.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.jdk8; + +import java.time.LocalDate; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class LocalDateTest extends TestCase { + + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.setDate(LocalDate.now()); + + String text = JSON.toJSONString(vo); + System.out.println(text); + + VO vo1 = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.getDate(), vo1.getDate()); + } + + public static class VO { + + private LocalDate date; + + public LocalDate getDate() { + return date; + } + + public void setDate(LocalDate date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTimeTest.java b/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTimeTest.java new file mode 100644 index 0000000000..3dc5699964 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/jdk8/LocalDateTimeTest.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.jdk8; + +import java.time.LocalDateTime; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + +public class LocalDateTimeTest extends TestCase { + + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.setDate(LocalDateTime.now()); + + String text = JSON.toJSONString(vo); + System.out.println(text); + + VO vo1 = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.getDate(), vo1.getDate()); + } + + public static class VO { + + private LocalDateTime date; + + public LocalDateTime getDate() { + return date; + } + + public void setDate(LocalDateTime date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/jdk8/LocalTimeTest.java b/src/test/java/com/alibaba/json/bvt/jdk8/LocalTimeTest.java new file mode 100644 index 0000000000..5e7ce3649b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/jdk8/LocalTimeTest.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.jdk8; + +import java.time.LocalTime; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class LocalTimeTest extends TestCase { + + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.setDate(LocalTime.now()); + + String text = JSON.toJSONString(vo); + System.out.println(text); + + VO vo1 = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.getDate(), vo1.getDate()); + } + + public static class VO { + + private LocalTime date; + + public LocalTime getDate() { + return date; + } + + public void setDate(LocalTime date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/jdk8/OffseTimeTest.java b/src/test/java/com/alibaba/json/bvt/jdk8/OffseTimeTest.java new file mode 100644 index 0000000000..9fe28e7823 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/jdk8/OffseTimeTest.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.jdk8; + +import java.time.OffsetTime; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class OffseTimeTest extends TestCase { + + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.setDate(OffsetTime.now()); + + String text = JSON.toJSONString(vo); + System.out.println(text); + + VO vo1 = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.getDate(), vo1.getDate()); + } + + public static class VO { + + private OffsetTime date; + + public OffsetTime getDate() { + return date; + } + + public void setDate(OffsetTime date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/jdk8/OffsetDateTimeTest.java b/src/test/java/com/alibaba/json/bvt/jdk8/OffsetDateTimeTest.java new file mode 100644 index 0000000000..e201098ade --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/jdk8/OffsetDateTimeTest.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.jdk8; + +import java.time.OffsetDateTime; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class OffsetDateTimeTest extends TestCase { + + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.setDate(OffsetDateTime.now()); + + String text = JSON.toJSONString(vo); + System.out.println(text); + + VO vo1 = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.getDate(), vo1.getDate()); + } + + public static class VO { + + private OffsetDateTime date; + + public OffsetDateTime getDate() { + return date; + } + + public void setDate(OffsetDateTime date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/jdk8/PeriodTest.java b/src/test/java/com/alibaba/json/bvt/jdk8/PeriodTest.java new file mode 100644 index 0000000000..12ce8b9194 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/jdk8/PeriodTest.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.jdk8; + +import java.time.Period; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class PeriodTest extends TestCase { + + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.setDate(Period.of(3, 2, 11)); + + String text = JSON.toJSONString(vo); + System.out.println(text); + + VO vo1 = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.getDate(), vo1.getDate()); + } + + public static class VO { + + private Period date; + + public Period getDate() { + return date; + } + + public void setDate(Period date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/jdk8/ZoneIdTest.java b/src/test/java/com/alibaba/json/bvt/jdk8/ZoneIdTest.java new file mode 100644 index 0000000000..cf207ac4eb --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/jdk8/ZoneIdTest.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.jdk8; + +import java.time.ZoneId; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class ZoneIdTest extends TestCase { + + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.setDate(ZoneId.of("Europe/Paris")); + + String text = JSON.toJSONString(vo); + System.out.println(text); + + VO vo1 = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.getDate(), vo1.getDate()); + } + + public static class VO { + + private ZoneId date; + + public ZoneId getDate() { + return date; + } + + public void setDate(ZoneId date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/jdk8/ZonedDateTimeTest.java b/src/test/java/com/alibaba/json/bvt/jdk8/ZonedDateTimeTest.java new file mode 100644 index 0000000000..cd5aad3327 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/jdk8/ZonedDateTimeTest.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.jdk8; + +import java.time.ZonedDateTime; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class ZonedDateTimeTest extends TestCase { + + public void test_for_issue() throws Exception { + VO vo = new VO(); + vo.setDate(ZonedDateTime.now()); + + String text = JSON.toJSONString(vo); + System.out.println(text); + + VO vo1 = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.getDate(), vo1.getDate()); + } + + public static class VO { + + private ZonedDateTime date; + + public ZonedDateTime getDate() { + return date; + } + + public void setDate(ZonedDateTime date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/jsonfield/JSONFieldTest_0.java b/src/test/java/com/alibaba/json/bvt/jsonfield/JSONFieldTest_0.java new file mode 100644 index 0000000000..69de1bfec7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/jsonfield/JSONFieldTest_0.java @@ -0,0 +1,88 @@ +package com.alibaba.json.bvt.jsonfield; + +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer; +import com.alibaba.fastjson.parser.deserializer.FieldDeserializer; +import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +public class JSONFieldTest_0 extends TestCase { + + public void test_0() throws Exception { + VO vo = new VO(); + vo.setF0(100); + vo.setF1(101); + vo.setF2(102); + + String text = JSON.toJSONString(vo); + System.out.println(text); + + Assert.assertEquals("{\"f2\":102,\"f1\":101,\"f0\":100}", text); + + VO vo_decoded = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.f0, vo_decoded.f0); + Assert.assertEquals(vo.f1, vo_decoded.f1); + Assert.assertEquals(vo.f2, vo_decoded.f2); + + JavaBeanDeserializer javaBeanDeser = null; + + ObjectDeserializer deser = ParserConfig.getGlobalInstance().getDeserializer(VO.class); + if (deser instanceof ASMJavaBeanDeserializer) { + javaBeanDeser = ((ASMJavaBeanDeserializer) deser).getInnterSerializer(); + } else { + javaBeanDeser = (JavaBeanDeserializer) deser; + } + + List fieldDeserList = javaBeanDeser.getSortedFieldDeserializers(); + Assert.assertEquals(3, fieldDeserList.size()); + Assert.assertEquals("f2", fieldDeserList.get(0).getFieldInfo().getName()); + Assert.assertEquals("f1", fieldDeserList.get(1).getFieldInfo().getName()); + Assert.assertEquals("f0", fieldDeserList.get(2).getFieldInfo().getName()); + } + + public static class VO { + + @JSONField(ordinal = 3) + private int f0; + + @JSONField(ordinal = 2) + private int f1; + + @JSONField(ordinal = 1) + private int f2; + + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + public int getF2() { + return f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/jsonfield/JSONFieldTest_1.java b/src/test/java/com/alibaba/json/bvt/jsonfield/JSONFieldTest_1.java new file mode 100644 index 0000000000..e3a879eee6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/jsonfield/JSONFieldTest_1.java @@ -0,0 +1,94 @@ +package com.alibaba.json.bvt.jsonfield; + +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer; +import com.alibaba.fastjson.parser.deserializer.FieldDeserializer; +import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +public class JSONFieldTest_1 extends TestCase { + + public void test_0() throws Exception { + VO vo = new VO(); + vo.setF0(100); + vo.setF1(101); + vo.setF2(102); + + String text = JSON.toJSONString(vo); + System.out.println(text); + + Assert.assertEquals("{\"f2\":102,\"f1\":101,\"f0\":100}", text); + + VO vo_decoded = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.f0, vo_decoded.f0); + Assert.assertEquals(vo.f1, vo_decoded.f1); + Assert.assertEquals(vo.f2, vo_decoded.f2); + + JavaBeanDeserializer javaBeanDeser = null; + + ObjectDeserializer deser = ParserConfig.getGlobalInstance().getDeserializer(VO.class); + if (deser instanceof ASMJavaBeanDeserializer) { + javaBeanDeser = ((ASMJavaBeanDeserializer) deser).getInnterSerializer(); + } else { + javaBeanDeser = (JavaBeanDeserializer) deser; + } + + List fieldDeserList = javaBeanDeser.getSortedFieldDeserializers(); + Assert.assertEquals(3, fieldDeserList.size()); + Assert.assertEquals("f2", fieldDeserList.get(0).getFieldInfo().getName()); + Assert.assertEquals("f1", fieldDeserList.get(1).getFieldInfo().getName()); + Assert.assertEquals("f0", fieldDeserList.get(2).getFieldInfo().getName()); + } + + public static class VO { + + private int f0; + + + private int f1; + + + private int f2; + + @JSONField(ordinal = 3) + public int getF0() { + return f0; + } + + @JSONField(ordinal = 3) + public void setF0(int f0) { + this.f0 = f0; + } + + @JSONField(ordinal = 2) + public int getF1() { + return f1; + } + + @JSONField(ordinal = 2) + public void setF1(int f1) { + this.f1 = f1; + } + + @JSONField(ordinal = 1) + public int getF2() { + return f2; + } + + + @JSONField(ordinal = 1) + public void setF2(int f2) { + this.f2 = f2; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/odps/GetJSONObjectTest.java b/src/test/java/com/alibaba/json/bvt/odps/GetJSONObjectTest.java new file mode 100644 index 0000000000..3c522ade17 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/odps/GetJSONObjectTest.java @@ -0,0 +1,14 @@ +package com.alibaba.json.bvt.odps; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.support.odps.udf.JSONExtract; + + +public class GetJSONObjectTest extends TestCase { + public void test_udf() throws Exception { + JSONExtract udf = new JSONExtract(); + String result = udf.evaluate("{\"id\":123,\"name\":\"wenshao\"}", "$"); + System.out.println(result); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/AsmParserTest0.java b/src/test/java/com/alibaba/json/bvt/parser/AsmParserTest0.java new file mode 100755 index 0000000000..6e01e79ad4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/AsmParserTest0.java @@ -0,0 +1,42 @@ +package com.alibaba.json.bvt.parser; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class AsmParserTest0 extends TestCase { + + public void test_asm() throws Exception { + A a = JSON.parseObject("{\"f1\":123}", A.class); + Assert.assertNotNull(a.getF2()); + } + + public static class A { + + private int f1; + + private B f2 = new B(); + + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + public B getF2() { + return f2; + } + + public void setF2(B f2) { + this.f2 = f2; + } + + } + + public static class B { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/AsmParserTest1.java b/src/test/java/com/alibaba/json/bvt/parser/AsmParserTest1.java new file mode 100755 index 0000000000..e30b37054c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/AsmParserTest1.java @@ -0,0 +1,48 @@ +package com.alibaba.json.bvt.parser; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class AsmParserTest1 extends TestCase { + + public void test_asm() throws Exception { + A a = JSON.parseObject("{\"f1\":123}", A.class); + Assert.assertEquals(123, a.getF1()); + Assert.assertNotNull(a.getF2()); + } + + public static class A { + + private int f1; + + private List f2 = new ArrayList(); + + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + + public List getF2() { + return f2; + } + + + public void setF2(List f2) { + this.f2 = f2; + } + + } + + public static class B { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/ClassTest.java b/src/test/java/com/alibaba/json/bvt/parser/ClassTest.java new file mode 100755 index 0000000000..eebbce77fa --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/ClassTest.java @@ -0,0 +1,47 @@ +package com.alibaba.json.bvt.parser; + +import com.alibaba.fastjson.JSON; + +import org.junit.Assert; +import junit.framework.TestCase; + +public class ClassTest extends TestCase { + + public void test_class_array() throws Exception { + String text = "{\"clazz\":\"[Ljava.lang.String;\",\"value\":\"[\\\"武汉银行\\\"]\"}"; + + VO vo = JSON.parseObject(text, VO.class); + + Assert.assertEquals(String[].class, vo.getClazz()); + } + + public void test_class() throws Exception { + String text = "{\"clazz\":\"Ljava.lang.String;\",\"value\":\"[\\\"武汉银行\\\"]\"}"; + + VO vo = JSON.parseObject(text, VO.class); + Assert.assertEquals(String.class, vo.getClazz()); + } + + public static class VO { + + private Class clazz; + private Object value; + + public Class getClazz() { + return clazz; + } + + public void setClazz(Class clazz) { + this.clazz = clazz; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DateParserTest.java b/src/test/java/com/alibaba/json/bvt/parser/DateParserTest.java old mode 100644 new mode 100755 similarity index 67% rename from src/test/java/com/alibaba/json/test/bvt/parser/DateParserTest.java rename to src/test/java/com/alibaba/json/bvt/parser/DateParserTest.java index 122766dc31..1773c194f2 --- a/src/test/java/com/alibaba/json/test/bvt/parser/DateParserTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DateParserTest.java @@ -1,44 +1,66 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.util.Date; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.ParserConfig; public class DateParserTest extends TestCase { + public void test_date_new() throws Exception { + DefaultJSONParser parser = new DefaultJSONParser("new Date(1294552193254)"); + + java.util.Date date = parser.parseObject(java.util.Date.class); + + Assert.assertEquals(new java.util.Date(1294552193254L), date); + parser.close(); + } + + public void test_date_new_1() throws Exception { + DefaultJSONParser parser = new DefaultJSONParser("new Date(1294552193254)"); + + java.util.Date date = (java.util.Date) parser.parse(); + + Assert.assertEquals(new java.util.Date(1294552193254L), date); + parser.close(); + } + public void test_date_0() throws Exception { - DefaultExtJSONParser parser = new DefaultExtJSONParser("1294552193254"); + DefaultJSONParser parser = new DefaultJSONParser("1294552193254"); java.util.Date date = parser.parseObject(java.util.Date.class); Assert.assertEquals(new java.util.Date(1294552193254L), date); + parser.close(); } public void test_date_1() throws Exception { int featrues = JSON.DEFAULT_PARSER_FEATURE; featrues = Feature.config(featrues, Feature.AllowISO8601DateFormat, true); - DefaultExtJSONParser parser = new DefaultExtJSONParser("\"2011-01-09T13:49:53.254\"", ParserConfig.getGlobalInstance(), featrues); + DefaultJSONParser parser = new DefaultJSONParser("\"2011-01-09T13:49:53.254\"", ParserConfig.getGlobalInstance(), featrues); java.util.Date date = parser.parseObject(java.util.Date.class); Assert.assertEquals(new java.util.Date(1294552193254L), date); + parser.close(); } public void test_date_2() throws Exception { int featrues = JSON.DEFAULT_PARSER_FEATURE; - DefaultExtJSONParser parser = new DefaultExtJSONParser("new Date(1294552193254)", ParserConfig.getGlobalInstance(), featrues); + DefaultJSONParser parser = new DefaultJSONParser("new Date(1294552193254)", ParserConfig.getGlobalInstance(), featrues); java.util.Date date = parser.parseObject(java.util.Date.class); Assert.assertEquals(new java.util.Date(1294552193254L), date); + parser.close(); } public void test_date_3() throws Exception { @@ -50,11 +72,12 @@ public void test_date_3() throws Exception { public void test_date_4() throws Exception { int featrues = JSON.DEFAULT_PARSER_FEATURE; featrues = Feature.config(featrues, Feature.AllowISO8601DateFormat, true); - DefaultExtJSONParser parser = new DefaultExtJSONParser("\"2011-01-09\"", ParserConfig.getGlobalInstance(), featrues); + DefaultJSONParser parser = new DefaultJSONParser("\"2011-01-09\"", ParserConfig.getGlobalInstance(), featrues); java.util.Date date = parser.parseObject(java.util.Date.class); Assert.assertEquals(new java.util.Date(1294502400000L), date); + parser.close(); } public void test_date_5() throws Exception { @@ -82,9 +105,10 @@ public void test_date_error_0() throws Exception { JSONException error = null; try { - DefaultExtJSONParser parser = new DefaultExtJSONParser("true"); + DefaultJSONParser parser = new DefaultJSONParser("true"); parser.parseObject(java.util.Date.class); + parser.close(); } catch (JSONException e) { error = e; } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DateParserTest_sql.java b/src/test/java/com/alibaba/json/bvt/parser/DateParserTest_sql.java old mode 100644 new mode 100755 similarity index 88% rename from src/test/java/com/alibaba/json/test/bvt/parser/DateParserTest_sql.java rename to src/test/java/com/alibaba/json/bvt/parser/DateParserTest_sql.java index 21a5244632..569e2a6083 --- a/src/test/java/com/alibaba/json/test/bvt/parser/DateParserTest_sql.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DateParserTest_sql.java @@ -1,6 +1,7 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; + +import org.junit.Assert; -import junit.framework.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -8,6 +9,7 @@ import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.ParserConfig; +@SuppressWarnings("deprecation") public class DateParserTest_sql extends TestCase { public void f_test_date_0() throws Exception { @@ -16,6 +18,8 @@ public void f_test_date_0() throws Exception { java.sql.Date date = parser.parseObject(java.sql.Date.class); Assert.assertEquals(new java.sql.Date(1294552193254L), date); + + parser.close(); } public void test_date_1() throws Exception { @@ -26,6 +30,7 @@ public void test_date_1() throws Exception { java.sql.Date date = parser.parseObject(java.sql.Date.class); Assert.assertEquals(new java.sql.Date(1294552193254L), date); + parser.close(); } public void test_date_2() throws Exception { @@ -35,6 +40,7 @@ public void test_date_2() throws Exception { java.sql.Date date = parser.parseObject(java.sql.Date.class); Assert.assertEquals(new java.sql.Date(1294552193254L), date); + parser.close(); } public void test_date_3() throws Exception { @@ -45,6 +51,7 @@ public void test_date_3() throws Exception { java.sql.Date date = parser.parseObject(java.sql.Date.class); Assert.assertEquals(new java.sql.Date(1294552193000L), date); + parser.close(); } public void test_date_4() throws Exception { @@ -55,5 +62,6 @@ public void test_date_4() throws Exception { java.sql.Date date = parser.parseObject(java.sql.Date.class); Assert.assertEquals(new java.sql.Date(1294502400000L), date); + parser.close(); } } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DateParserTest_sql_timestamp.java b/src/test/java/com/alibaba/json/bvt/parser/DateParserTest_sql_timestamp.java old mode 100644 new mode 100755 similarity index 89% rename from src/test/java/com/alibaba/json/test/bvt/parser/DateParserTest_sql_timestamp.java rename to src/test/java/com/alibaba/json/bvt/parser/DateParserTest_sql_timestamp.java index 9a7499f0c2..cfd99b44ea --- a/src/test/java/com/alibaba/json/test/bvt/parser/DateParserTest_sql_timestamp.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DateParserTest_sql_timestamp.java @@ -1,6 +1,7 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; + +import org.junit.Assert; -import junit.framework.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -8,6 +9,7 @@ import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.ParserConfig; +@SuppressWarnings("deprecation") public class DateParserTest_sql_timestamp extends TestCase { public void f_test_date_0() throws Exception { @@ -16,6 +18,7 @@ public void f_test_date_0() throws Exception { java.sql.Timestamp date = parser.parseObject(java.sql.Timestamp.class); Assert.assertEquals(new java.sql.Timestamp(1294552193254L), date); + parser.close(); } public void test_date_1() throws Exception { @@ -26,6 +29,7 @@ public void test_date_1() throws Exception { java.sql.Timestamp date = parser.parseObject(java.sql.Timestamp.class); Assert.assertEquals(new java.sql.Timestamp(1294552193254L), date); + parser.close(); } public void test_date_2() throws Exception { @@ -35,6 +39,7 @@ public void test_date_2() throws Exception { java.sql.Timestamp date = parser.parseObject(java.sql.Timestamp.class); Assert.assertEquals(new java.sql.Timestamp(1294552193254L), date); + parser.close(); } public void test_date_3() throws Exception { @@ -45,6 +50,7 @@ public void test_date_3() throws Exception { java.sql.Timestamp date = parser.parseObject(java.sql.Timestamp.class); Assert.assertEquals(new java.sql.Timestamp(1294552193000L), date); + parser.close(); } public void test_date_4() throws Exception { @@ -55,5 +61,6 @@ public void test_date_4() throws Exception { java.sql.Timestamp date = parser.parseObject(java.sql.Timestamp.class); Assert.assertEquals(new java.sql.Timestamp(1294502400000L), date); + parser.close(); } } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DateTest.java b/src/test/java/com/alibaba/json/bvt/parser/DateTest.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/parser/DateTest.java rename to src/test/java/com/alibaba/json/bvt/parser/DateTest.java index 62a9672240..85f37a1ea4 --- a/src/test/java/com/alibaba/json/test/bvt/parser/DateTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DateTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.util.Date; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest.java rename to src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest.java index d4eb3e8484..d694ca7bd1 --- a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import static com.alibaba.fastjson.util.TypeUtils.castToBigDecimal; import static com.alibaba.fastjson.util.TypeUtils.castToBigInteger; @@ -38,17 +38,20 @@ import java.util.List; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; + import junit.framework.TestCase; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.DefaultExtJSONParser; import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.util.TypeUtils; public class DefaultExtJSONParserTest extends TestCase { public void test_parseObject() { + new DefaultExtJSONParser("".toCharArray(), 0, ParserConfig.getGlobalInstance(), 0).close(); User user = new User(); user.setName("校长"); user.setAge(3); diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_0.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_0.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_0.java rename to src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_0.java index 3a9edf234c..0cce855998 --- a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_0.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_0.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.math.BigDecimal; import java.util.Date; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONException; diff --git a/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_1.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_1.java new file mode 100755 index 0000000000..964b5456e9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_1.java @@ -0,0 +1,77 @@ +package com.alibaba.json.bvt.parser; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.json.test.entity.TestEntity; + +public class DefaultExtJSONParserTest_1 extends TestCase { + + public void test_0() throws Exception { + DefaultExtJSONParser parser = new DefaultExtJSONParser("{\"f1\":true}"); + TestEntity entity = parser.parseObject(TestEntity.class); + Assert.assertEquals(true, entity.isF1()); + } + + public void test_1() throws Exception { + DefaultExtJSONParser parser = new DefaultExtJSONParser("{\"f2\":true}"); + TestEntity entity = parser.parseObject(TestEntity.class); + Assert.assertEquals(Boolean.TRUE, entity.getF2()); + } + + public void f_test_2() throws Exception { + TestEntity a = new TestEntity(); + a.setF1(true); + a.setF2(Boolean.TRUE); + a.setF3((byte) 123); + a.setF4((byte) 123); + a.setF5((short) 123); + a.setF6((short) 123); + a.setF7((int) 123); + a.setF8((int) 123); + a.setF9((long) 123); + a.setF10((long) 123); + a.setF11(new BigInteger("123")); + a.setF12(new BigDecimal("123")); + a.setF13("abc"); + a.setF14(null); + a.setF15(12.34F); + a.setF16(12.35F); + a.setF17(12.345D); + a.setF18(12.345D); + + String text = JSON.toJSONString(a); + System.out.println(text); + + TestEntity b = new TestEntity(); + { + DefaultExtJSONParser parser = new DefaultExtJSONParser(text); + parser.parseObject(b); + } + + Assert.assertEquals("f1", a.isF1(), b.isF1()); + Assert.assertEquals("f2", a.getF2(), b.getF2()); + Assert.assertEquals("f3", a.getF3(), b.getF3()); + Assert.assertEquals("f4", a.getF4(), b.getF4()); + Assert.assertEquals("f5", a.getF5(), b.getF5()); + Assert.assertEquals("f6", a.getF6(), b.getF6()); + Assert.assertEquals("f7", a.getF7(), b.getF7()); + Assert.assertEquals("f8", a.getF8(), b.getF8()); + Assert.assertEquals("f9", a.getF9(), b.getF9()); + Assert.assertEquals(a.getF10(), b.getF10()); + Assert.assertEquals(a.getF11(), b.getF11()); + Assert.assertEquals(a.getF12(), b.getF12()); + Assert.assertEquals(a.getF13(), b.getF13()); + Assert.assertEquals(a.getF14(), b.getF14()); + Assert.assertEquals(a.getF15(), b.getF15()); + Assert.assertEquals(a.getF16(), b.getF16()); + Assert.assertEquals(a.getF17(), b.getF17()); + Assert.assertEquals(a.getF18(), b.getF18()); + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_2.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_2.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_2.java rename to src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_2.java index 37bbcf7001..22eaed0c97 --- a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_2.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_2.java @@ -1,16 +1,16 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.parser.DefaultExtJSONParser; import com.alibaba.fastjson.parser.Feature; -import com.alibaba.json.test.bvt.parser.DefaultExtJSONParserTest.User; +import com.alibaba.json.bvt.parser.DefaultExtJSONParserTest.User; public class DefaultExtJSONParserTest_2 extends TestCase { diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_3.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_3.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_3.java rename to src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_3.java index 5c0f93f8e4..bf8d9692e4 --- a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_3.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_3.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.math.BigDecimal; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_4.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_4.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_4.java rename to src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_4.java index f1846e26fa..275008df12 --- a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_4.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_4.java @@ -1,10 +1,10 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONObject; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_5.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_5.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_5.java rename to src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_5.java index 9446804ce6..30453c973e --- a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_5.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_5.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.parser.DefaultExtJSONParser; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_6.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_6.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_6.java rename to src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_6.java index d04ac5418a..32aacaefb4 --- a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_6.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_6.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.parser.DefaultExtJSONParser; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_7.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_7.java old mode 100644 new mode 100755 similarity index 97% rename from src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_7.java rename to src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_7.java index 5d1a68d731..fc7f8267d0 --- a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_7.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParserTest_7.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.util.ArrayList; import java.util.List; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParser_parseArray.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParser_parseArray.java old mode 100644 new mode 100755 similarity index 99% rename from src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParser_parseArray.java rename to src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParser_parseArray.java index f344a80a8f..c7ab4b846c --- a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParser_parseArray.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParser_parseArray.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.lang.reflect.Type; import java.math.BigDecimal; @@ -6,7 +6,7 @@ import java.util.Date; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONObject; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParser_parseArray_2.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParser_parseArray_2.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParser_parseArray_2.java rename to src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParser_parseArray_2.java index 7a2a5b219e..888f7d5955 --- a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParser_parseArray_2.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultExtJSONParser_parseArray_2.java @@ -1,20 +1,22 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; + import junit.framework.TestCase; import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.parser.DefaultExtJSONParser; import com.alibaba.fastjson.parser.Feature; +@SuppressWarnings("deprecation") public class DefaultExtJSONParser_parseArray_2 extends TestCase { - public void test_0() throws Exception { + public void test_0() throws Exception { DefaultExtJSONParser parser = new DefaultExtJSONParser("[['1']]"); parser.config(Feature.AllowISO8601DateFormat, false); List> list = (List>) parser.parseArrayWithType(new TypeReference>>() { diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultJSONParserTest2.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest2.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/parser/DefaultJSONParserTest2.java rename to src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest2.java index 87a5cda3fb..045cf0db35 --- a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultJSONParserTest2.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest2.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultJSONParserTest_charArray.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_charArray.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/parser/DefaultJSONParserTest_charArray.java rename to src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_charArray.java index 805ccca7cd..9182de1f70 --- a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultJSONParserTest_charArray.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_charArray.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.parser.DefaultJSONParser; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultJSONParserTest_comma.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_comma.java old mode 100644 new mode 100755 similarity index 90% rename from src/test/java/com/alibaba/json/test/bvt/parser/DefaultJSONParserTest_comma.java rename to src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_comma.java index d4817a8b1c..4b4aa78377 --- a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultJSONParserTest_comma.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_comma.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONException; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultJSONParserTest_date.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_date.java old mode 100644 new mode 100755 similarity index 84% rename from src/test/java/com/alibaba/json/test/bvt/parser/DefaultJSONParserTest_date.java rename to src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_date.java index ab3cb5ec09..6eada951d4 --- a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultJSONParserTest_date.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_date.java @@ -1,10 +1,12 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; +import java.text.SimpleDateFormat; import java.util.Date; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.Feature; @@ -47,4 +49,14 @@ public void test_date4() { JSONObject json = parser.parseObject(); Assert.assertEquals("xxxxx", json.get("1234567890abcdefghijklmnopqrst1234567890abcdefghijklmnopqrst1234567890abcdefghijklmnopqrst1234567890abcdefghijklmnopqrst1234567890abcdefghijklmnopqrst1234567890abcdefghijklmnopqrst\t")); } + + public void test_dateFormat() throws Exception { + DefaultJSONParser parser = new DefaultJSONParser("{}"); + parser.setDateFormat("yyyy-DD-mm"); + parser.setDateFomrat(new SimpleDateFormat("yyyy-DD-mm")); + parser.getDateFomartPattern(); + parser.getDateFormat(); + parser.parse(); + parser.close(); + } } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultJSONParserTest_error.java b/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_error.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/parser/DefaultJSONParserTest_error.java rename to src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_error.java index 1b8c902d1c..f62cf84257 --- a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultJSONParserTest_error.java +++ b/src/test/java/com/alibaba/json/bvt/parser/DefaultJSONParserTest_error.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONException; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/EnumParserTest.java b/src/test/java/com/alibaba/json/bvt/parser/EnumParserTest.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/parser/EnumParserTest.java rename to src/test/java/com/alibaba/json/bvt/parser/EnumParserTest.java index 9568135c0f..6df0249aab --- a/src/test/java/com/alibaba/json/test/bvt/parser/EnumParserTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/EnumParserTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.parser.DefaultExtJSONParser; @@ -69,7 +69,7 @@ public void test_error_3() throws Exception { String text = "4"; DefaultExtJSONParser parser = new DefaultExtJSONParser(text); - new EnumDeserializer(Object.class).deserialze(parser, Object.class); + new EnumDeserializer(Object.class).deserialze(parser, Object.class, null); } catch (Exception ex) { error = ex; } @@ -82,7 +82,7 @@ public void test_error_4() throws Exception { String text = "true"; DefaultExtJSONParser parser = new DefaultExtJSONParser(text); - new EnumDeserializer(Object.class).deserialze(parser, Object.class); + new EnumDeserializer(Object.class).deserialze(parser, Object.class, null); } catch (Exception ex) { error = ex; } diff --git a/src/test/java/com/alibaba/json/bvt/parser/FastMatchCheckTest.java b/src/test/java/com/alibaba/json/bvt/parser/FastMatchCheckTest.java new file mode 100755 index 0000000000..75105c6c0c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/FastMatchCheckTest.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ArrayDeserializer; +import com.alibaba.fastjson.parser.deserializer.JSONArrayDeserializer; +import com.alibaba.fastjson.parser.deserializer.JSONObjectDeserializer; +import com.alibaba.fastjson.parser.deserializer.NumberDeserializer; +import com.alibaba.fastjson.parser.deserializer.TimestampDeserializer; +import com.alibaba.fastjson.serializer.AtomicIntegerArrayCodec; +import com.alibaba.fastjson.serializer.AtomicLongArrayCodec; +import com.alibaba.fastjson.serializer.CharacterCodec; +import com.alibaba.fastjson.serializer.CharsetCodec; +import com.alibaba.fastjson.serializer.FileCodec; +import com.alibaba.fastjson.serializer.InetAddressCodec; +import com.alibaba.fastjson.serializer.InetSocketAddressCodec; +import com.alibaba.fastjson.serializer.LocaleCodec; + +public class FastMatchCheckTest extends TestCase { + public void test_match() throws Exception { + Assert.assertEquals(JSONToken.LBRACKET, AtomicIntegerArrayCodec.instance.getFastMatchToken()); + Assert.assertEquals(JSONToken.LBRACKET, AtomicLongArrayCodec.instance.getFastMatchToken()); + Assert.assertEquals(JSONToken.LITERAL_STRING, InetAddressCodec.instance.getFastMatchToken()); + Assert.assertEquals(JSONToken.LITERAL_STRING, LocaleCodec.instance.getFastMatchToken()); + Assert.assertEquals(JSONToken.LITERAL_INT, NumberDeserializer.instance.getFastMatchToken()); + Assert.assertEquals(JSONToken.LITERAL_INT, TimestampDeserializer.instance.getFastMatchToken()); + Assert.assertEquals(JSONToken.LITERAL_STRING, CharsetCodec.instance.getFastMatchToken()); + Assert.assertEquals(JSONToken.LITERAL_STRING, FileCodec.instance.getFastMatchToken()); + Assert.assertEquals(JSONToken.LBRACKET, JSONArrayDeserializer.instance.getFastMatchToken()); + Assert.assertEquals(JSONToken.LBRACKET, ArrayDeserializer.instance.getFastMatchToken()); + Assert.assertEquals(JSONToken.LBRACE, JSONObjectDeserializer.instance.getFastMatchToken()); + Assert.assertEquals(JSONToken.LBRACE, InetSocketAddressCodec.instance.getFastMatchToken()); + Assert.assertEquals(JSONToken.LITERAL_STRING, CharacterCodec.instance.getFastMatchToken()); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/FeatureParserTest.java b/src/test/java/com/alibaba/json/bvt/parser/FeatureParserTest.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/parser/FeatureParserTest.java rename to src/test/java/com/alibaba/json/bvt/parser/FeatureParserTest.java index e55f567de5..0aa36f7bcb --- a/src/test/java/com/alibaba/json/test/bvt/parser/FeatureParserTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/FeatureParserTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONException; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/FeatureTest.java b/src/test/java/com/alibaba/json/bvt/parser/FeatureTest.java old mode 100644 new mode 100755 similarity index 89% rename from src/test/java/com/alibaba/json/test/bvt/parser/FeatureTest.java rename to src/test/java/com/alibaba/json/bvt/parser/FeatureTest.java index 2e7721e9bd..2bf172bd68 --- a/src/test/java/com/alibaba/json/test/bvt/parser/FeatureTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/FeatureTest.java @@ -1,11 +1,12 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; import junit.framework.TestCase; -import com.alibaba.fastjson.parser.CharTypes; +import org.junit.Assert; + import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.util.IOUtils; public class FeatureTest extends TestCase { @@ -20,7 +21,7 @@ public void test_default() throws Exception { } public void test_config() throws Exception { - new CharTypes(); + new IOUtils(); DefaultJSONParser parser = new DefaultJSONParser(""); diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/GenericTest.java b/src/test/java/com/alibaba/json/bvt/parser/GenericTest.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/parser/GenericTest.java rename to src/test/java/com/alibaba/json/bvt/parser/GenericTest.java index b8f7929102..87edab4ec3 --- a/src/test/java/com/alibaba/json/test/bvt/parser/GenericTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/GenericTest.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.util.ArrayList; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/parser/GenericTest2.java b/src/test/java/com/alibaba/json/bvt/parser/GenericTest2.java new file mode 100755 index 0000000000..58e5d566cc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/GenericTest2.java @@ -0,0 +1,86 @@ +package com.alibaba.json.bvt.parser; + +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class GenericTest2 extends TestCase { + public void test_for_bingyang() throws Exception { + String text = "{\"count\":123,\"index\":7,\"items\":[{\"id\":234,\"latitude\":2.5,\"longtitude\":3.7}]}"; + PageBean pageBean = JSON.parseObject(text, new TypeReference>() {}); + Assert.assertNotNull(pageBean); + Assert.assertEquals(123, pageBean.getCount()); + Assert.assertEquals(7, pageBean.getIndex()); + Assert.assertNotNull(pageBean.getItems()); + Assert.assertEquals(1, pageBean.getItems().size()); + ActiveBase active = pageBean.getItems().get(0); + Assert.assertEquals(new Integer(234), active.getId()); + Assert.assertTrue(3.7D == active.getLongtitude()); + Assert.assertTrue(2.5D == active.getLatitude()); + } + + public static class ActiveBase extends BaseModel { + private double latitude; + private double longtitude; + public double getLatitude() { + return latitude; + } + public void setLatitude(double latitude) { + this.latitude = latitude; + } + public double getLongtitude() { + return longtitude; + } + public void setLongtitude(double longtitude) { + this.longtitude = longtitude; + } + } + + public static class BaseModel { + private Integer id; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + } + + public static class PageBean { + private int count; + private int index; + private List items; + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/GenericTest3.java b/src/test/java/com/alibaba/json/bvt/parser/GenericTest3.java new file mode 100755 index 0000000000..a83dac1da6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/GenericTest3.java @@ -0,0 +1,32 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class GenericTest3 extends TestCase { + public static class A { + public B b; + } + + public static class B { + public T value; + } + + public static class ValueObject { + public String property1; + public int property2; + } + + public void test_generic() throws Exception { + A object = JSON.parseObject( + "{b:{value:{property1:'string',property2:123}}}", + new TypeReference>() { + }); + + Assert.assertEquals(ValueObject.class, object.b.value.getClass()); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/IOUtilsTest.java b/src/test/java/com/alibaba/json/bvt/parser/IOUtilsTest.java old mode 100644 new mode 100755 similarity index 68% rename from src/test/java/com/alibaba/json/test/bvt/parser/IOUtilsTest.java rename to src/test/java/com/alibaba/json/bvt/parser/IOUtilsTest.java index 343c014b40..f9cdff78aa --- a/src/test/java/com/alibaba/json/test/bvt/parser/IOUtilsTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/IOUtilsTest.java @@ -1,14 +1,16 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; +import java.io.Closeable; +import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CoderResult; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; -import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.util.IOUtils; +import com.alibaba.fastjson.util.ThreadLocalCache; import com.alibaba.fastjson.util.UTF8Decoder; public class IOUtilsTest extends TestCase { @@ -16,14 +18,14 @@ public class IOUtilsTest extends TestCase { public void test_error_0() throws Exception { Exception error = null; try { - IOUtils.decode(JSON.UTF8_CharsetEncoder, ByteBuffer.wrap("abc".getBytes("UTF-8")), + IOUtils.decode(ThreadLocalCache.getUTF8Decoder(), ByteBuffer.wrap("abc".getBytes("UTF-8")), CharBuffer.wrap(new char[0])); } catch (Exception ex) { error = ex; } Assert.assertNotNull(error); } - + public void test_error_1() throws Exception { Exception error = null; try { @@ -34,7 +36,7 @@ public void test_error_1() throws Exception { } Assert.assertNotNull(error); } - + public void test_error_2() throws Exception { Exception error = null; try { @@ -46,6 +48,30 @@ public void test_error_2() throws Exception { Assert.assertNotNull(error); } + public void test_close() throws Exception { + IOUtils.close((Closeable) null); + } + + public void test_close1() throws Exception { + IOUtils.close(new Closeable() { + + public void close() throws IOException { + + } + + }); + } + + public void test_close_error() throws Exception { + IOUtils.close(new Closeable() { + + public void close() throws IOException { + throw new IOException(); + } + + }); + } + public static class MockCharsetDecoder extends UTF8Decoder { @Override @@ -53,7 +79,7 @@ protected CoderResult implFlush(CharBuffer out) { return CoderResult.OVERFLOW; } } - + public static class MockCharsetDecoder2 extends UTF8Decoder { @Override diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/InetSocketAddressTest.java b/src/test/java/com/alibaba/json/bvt/parser/InetSocketAddressTest.java old mode 100644 new mode 100755 similarity index 90% rename from src/test/java/com/alibaba/json/test/bvt/parser/InetSocketAddressTest.java rename to src/test/java/com/alibaba/json/bvt/parser/InetSocketAddressTest.java index e5bf0a649e..c35714b1cb --- a/src/test/java/com/alibaba/json/test/bvt/parser/InetSocketAddressTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/InetSocketAddressTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.net.InetSocketAddress; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONArrayParseTest.java b/src/test/java/com/alibaba/json/bvt/parser/JSONArrayParseTest.java old mode 100644 new mode 100755 similarity index 88% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONArrayParseTest.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONArrayParseTest.java index d754be188d..b451ada56d --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONArrayParseTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONArrayParseTest.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.util.List; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONCreatorFactoryTest.java b/src/test/java/com/alibaba/json/bvt/parser/JSONCreatorFactoryTest.java new file mode 100755 index 0000000000..9342aa85a9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONCreatorFactoryTest.java @@ -0,0 +1,59 @@ +package com.alibaba.json.bvt.parser; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.parser.ParserConfig; + +public class JSONCreatorFactoryTest extends TestCase { + + public void test_create() throws Exception { + Entity entity = new Entity(123, "菜姐"); + String text = JSON.toJSONString(entity); + + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertEquals(entity.getId(), entity2.getId()); + Assert.assertEquals(entity.getName(), entity2.getName()); + } + + public void test_create_2() throws Exception { + Entity entity = new Entity(123, "菜姐"); + String text = JSON.toJSONString(entity); + + ParserConfig config = new ParserConfig(); + config.setAsmEnable(false); + + Entity entity2 = JSON.parseObject(text, Entity.class, config, 0); + Assert.assertEquals(entity.getId(), entity2.getId()); + Assert.assertEquals(entity.getName(), entity2.getName()); + } + + public static class Entity { + + private final int id; + private final String name; + + @JSONCreator + public static Entity create(@JSONField(name = "id") int id, @JSONField(name = "name") String name) { + return new Entity(id, name); + } + + private Entity(int id, String name){ + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONCreatorTest.java b/src/test/java/com/alibaba/json/bvt/parser/JSONCreatorTest.java new file mode 100755 index 0000000000..cf2ac70698 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONCreatorTest.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt.parser; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.parser.ParserConfig; + +public class JSONCreatorTest extends TestCase { + + public void test_create() throws Exception { + Entity entity = new Entity(123, "菜姐"); + String text = JSON.toJSONString(entity); + + Entity entity2 = JSON.parseObject(text, Entity.class); + Assert.assertEquals(entity.getId(), entity2.getId()); + Assert.assertEquals(entity.getName(), entity2.getName()); + } + + public void test_create_2() throws Exception { + Entity entity = new Entity(123, "菜姐"); + String text = JSON.toJSONString(entity); + + ParserConfig config = new ParserConfig(); + config.setAsmEnable(false); + + Entity entity2 = JSON.parseObject(text, Entity.class, config, 0); + Assert.assertEquals(entity.getId(), entity2.getId()); + Assert.assertEquals(entity.getName(), entity2.getName()); + } + + public static class Entity { + + private final int id; + private final String name; + + @JSONCreator + public Entity(@JSONField(name = "id") int id, @JSONField(name = "name") String name){ + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONCreatorTest_error.java b/src/test/java/com/alibaba/json/bvt/parser/JSONCreatorTest_error.java new file mode 100644 index 0000000000..0e5085ac4a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONCreatorTest_error.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt.parser; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; + +public class JSONCreatorTest_error extends TestCase { + + public void test_create() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"id\":123,\"name\":\"abc\"}", Entity.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class Entity { + + private final int id; + private final String name; + + @JSONCreator + public Entity(@JSONField(name = "id") int id, @JSONField(name = "name") String name){ + throw new UnsupportedOperationException(); + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONCreatorTest_error2.java b/src/test/java/com/alibaba/json/bvt/parser/JSONCreatorTest_error2.java new file mode 100644 index 0000000000..dc8cb6c347 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONCreatorTest_error2.java @@ -0,0 +1,49 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; + +public class JSONCreatorTest_error2 extends TestCase { + + public void test_create() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"id\":123,\"name\":\"abc\"}", Entity.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class Entity { + + private final int id; + private final String name; + + private Entity(int id, String name) { + this.id = id; + this.name = name; + } + + @JSONCreator + public static Entity create(@JSONField(name = "id") int id, @JSONField(name = "name") String name){ + throw new UnsupportedOperationException(); + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest.java b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest.java new file mode 100644 index 0000000000..e3881829f1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + + +public class JSONLexerTest extends TestCase { + public void test_0 () throws Exception { + StringBuilder buf = new StringBuilder("{\"value\":\""); + for (int i = 0; i < 256; ++i) { + buf.append('a'); + } + buf.append("\\n"); + buf.append("\"}"); + + JSONObject json = JSON.parseObject(buf.toString()); + Assert.assertEquals(257, json.getString("value").length()); + Assert.assertEquals('a', json.getString("value").charAt(255)); + Assert.assertEquals('\n', json.getString("value").charAt(256)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_10.java b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_10.java new file mode 100644 index 0000000000..9f7e60fab5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_10.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class JSONLexerTest_10 extends TestCase { + + public void test_a() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"type\":\"AAA", VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class VO { + + public VO(){ + + } + + private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_11.java b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_11.java new file mode 100644 index 0000000000..c059c346ec --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_11.java @@ -0,0 +1,46 @@ +package com.alibaba.json.bvt.parser; + +import java.util.ArrayList; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class JSONLexerTest_11 extends TestCase { + + public void test_a() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"type\":[\"AAA\"]}", VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class VO { + + public VO(){ + + } + + private MyList type; + + public MyList getType() { + return type; + } + + public void setType(MyList type) { + this.type = type; + } + + } + + public static class MyList extends ArrayList { + public MyList() { + throw new RuntimeException(); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_12.java b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_12.java new file mode 100644 index 0000000000..a8cdb5c263 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_12.java @@ -0,0 +1,76 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class JSONLexerTest_12 extends TestCase { + + public void test_error() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"type\":92233720368547758071}", VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_a() throws Exception { + Assert.assertEquals(123L, JSON.parseObject("{\"vo\":{\"type\":123}}", A.class).getVo().getType()); + } + + public void test_error_2() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"vo\":{\"type\":123}[", A.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_3() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"vo\":{\"type\":123]", A.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class A { + + private VO vo; + + public VO getVo() { + return vo; + } + + public void setVo(VO vo) { + this.vo = vo; + } + + } + + public static class VO { + + public VO(){ + + } + + private long type; + + public long getType() { + return type; + } + + public void setType(long type) { + this.type = type; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_13.java b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_13.java new file mode 100644 index 0000000000..f72cb710a6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_13.java @@ -0,0 +1,76 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class JSONLexerTest_13 extends TestCase { + + public void test_e() throws Exception { + Assert.assertTrue(123e3D == JSON.parseObject("{\"vo\":{\"type\":123e3}}", A.class).getVo().getType()); + } + + public void test_E() throws Exception { + Assert.assertTrue(123e3D == JSON.parseObject("{\"vo\":{\"type\":123E3}}", A.class).getVo().getType()); + } + + public void test_e_plus() throws Exception { + Assert.assertTrue(123e3D == JSON.parseObject("{\"vo\":{\"type\":123e+3}}", A.class).getVo().getType()); + } + + public void test_E_plus() throws Exception { + Assert.assertTrue(123e3D == JSON.parseObject("{\"vo\":{\"type\":123E+3}}", A.class).getVo().getType()); + } + + public void test_e_minus() throws Exception { + Assert.assertTrue(123e-3D == JSON.parseObject("{\"vo\":{\"type\":123e-3}}", A.class).getVo().getType()); + } + + public void test_E_minus() throws Exception { + Assert.assertTrue(123e-3D == JSON.parseObject("{\"vo\":{\"type\":123E-3}}", A.class).getVo().getType()); + } + + public void test_error_3() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"vo\":{\"type\":123]", A.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class A { + + private VO vo; + + public VO getVo() { + return vo; + } + + public void setVo(VO vo) { + this.vo = vo; + } + + } + + public static class VO { + + public VO(){ + + } + + private double type; + + public double getType() { + return type; + } + + public void setType(double type) { + this.type = type; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_14.java b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_14.java new file mode 100644 index 0000000000..c5d32ec307 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_14.java @@ -0,0 +1,45 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class JSONLexerTest_14 extends TestCase { + + public void test_e() throws Exception { + StringBuffer buf = new StringBuffer(); + buf.append("{\"type\":'"); + for (int i = 0; i < 100; ++i) { + buf.append('a'); + } + buf.append("\\t"); + buf.append("'}"); + VO vo = JSON.parseObject(buf.toString(), VO.class); + String type = vo.getType(); + for (int i = 0; i < 100; ++i) { + Assert.assertEquals('a', type.charAt(i)); + } + Assert.assertEquals('\t', type.charAt(100)); + Assert.assertEquals(101, type.length()); + } + + + public static class VO { + public VO(){ + + } + + private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_15.java b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_15.java new file mode 100644 index 0000000000..1b02aa3c61 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_15.java @@ -0,0 +1,15 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class JSONLexerTest_15 extends TestCase { + + public void test_e() throws Exception { + Assert.assertTrue(123e2D == ((Double) JSON.parse("123e2D")).doubleValue()); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_16.java b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_16.java new file mode 100644 index 0000000000..f910678da9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_16.java @@ -0,0 +1,62 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class JSONLexerTest_16 extends TestCase { + + public void test_0() throws Exception { + Assert.assertEquals(123, JSON.parseObject("{\"\\0\":123}").get("\0")); + } + + public void test_1() throws Exception { + Assert.assertEquals(123, JSON.parseObject("{\"\\1\":123}").get("\1")); + } + + public void test_2() throws Exception { + Assert.assertEquals(123, JSON.parseObject("{\"\\2\":123}").get("\2")); + } + + public void test_3() throws Exception { + Assert.assertEquals(123, JSON.parseObject("{\"\\3\":123}").get("\3")); + } + + public void test_4() throws Exception { + Assert.assertEquals(123, JSON.parseObject("{\"\\4\":123}").get("\4")); + } + + public void test_5() throws Exception { + Assert.assertEquals(123, JSON.parseObject("{\"\\5\":123}").get("\5")); + } + + public void test_6() throws Exception { + Assert.assertEquals(123, JSON.parseObject("{\"\\6\":123}").get("\6")); + } + + public void test_7() throws Exception { + Assert.assertEquals(123, JSON.parseObject("{\"\\7\":123}").get("\7")); + } + + public void test_8() throws Exception { + Assert.assertEquals(123, JSON.parseObject("{\"\\b\":123}").get("\b")); + } + + public void test_9() throws Exception { + Assert.assertEquals(123, JSON.parseObject("{\"\\t\":123}").get("\t")); + } + + public void test_10() throws Exception { + Assert.assertEquals(123, JSON.parseObject("{\"\\n\":123}").get("\n")); + } + + public void test_39() throws Exception { + Assert.assertEquals(123, JSON.parseObject("{\"\\'\":123}").get("\'")); + } + + public void test_40() throws Exception { + Assert.assertEquals(123, JSON.parseObject("{\"\\xFF\":123}").get("\u00FF")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_2.java b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_2.java new file mode 100644 index 0000000000..9417037101 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_2.java @@ -0,0 +1,115 @@ +package com.alibaba.json.bvt.parser; + +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class JSONLexerTest_2 extends TestCase { + + public void test_0() throws Exception { + VO vo = (VO) JSON.parseObject("{\"@type\":\"com.alibaba.json.bvt.parser.JSONLexerTest_2$VO\"}", VO.class); + Assert.assertNotNull(vo); + } + + public void test_1() throws Exception { + JSON.parseObject("{\"@type\":\"com.alibaba.json.bvt.parser.JSONLexerTest_2$VO1\"}", VO.class); + } + + public void test_2() throws Exception { + JSON.parseObject("{\"@type\":\"com.alibaba.json.bvt.parser.JSONLexerTest_2$A\"}", VO.class); + } + + public void test_a() throws Exception { + P a = JSON.parseObject("{\"vo\":{\"@type\":\"com.alibaba.json.bvt.parser.JSONLexerTest_2$VO\"}}", P.class); + Assert.assertNotNull(a); + } + + public void test_list() throws Exception { + List list = JSON.parseObject("[{\"@type\":\"com.alibaba.json.bvt.parser.JSONLexerTest_2$VO\"}]", + new TypeReference>() { + }); + Assert.assertNotNull(list); + Assert.assertNotNull(list.get(0)); + } + + public void test_list_2() throws Exception { + List list = JSON.parseObject("[{\"@type\":\"com.alibaba.json.bvt.parser.JSONLexerTest_2$VO\"},{}]", + new TypeReference>() { + }); + Assert.assertNotNull(list); + Assert.assertEquals(2, list.size()); + Assert.assertNotNull(list.get(0)); + Assert.assertNotNull(list.get(1)); + } + + public void test_error() throws Exception { + Exception error = null; + try { + JSON.parseObject("[{\"@type\":\"com.alibaba.json.bvt.parser.JSONLexerTest_2$VO\"}[]", + new TypeReference>() { + }); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class P { + + private VO vo; + + public VO getVo() { + return vo; + } + + public void setVo(VO vo) { + this.vo = vo; + } + + } + + public static class VO { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } + + public static class VO1 { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + } + + public static class A { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_3.java b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_3.java new file mode 100644 index 0000000000..232f135eed --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_3.java @@ -0,0 +1,30 @@ +package com.alibaba.json.bvt.parser; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + +public class JSONLexerTest_3 extends TestCase { + + public void test_matchField() throws Exception { + JSON.parseObject("{\"val\":{}}", VO.class); + } + + public static class VO { + + private A value; + + public A getValue() { + return value; + } + + public void setValue(A value) { + this.value = value; + } + + } + + public static class A { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_4.java b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_4.java new file mode 100644 index 0000000000..4c4ef91333 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_4.java @@ -0,0 +1,29 @@ +package com.alibaba.json.bvt.parser; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + +public class JSONLexerTest_4 extends TestCase { + + public void test_scanFieldString() throws Exception { + VO vo = JSON.parseObject("{\"value\":\"abc\"}", VO.class); + Assert.assertEquals("abc", vo.getValue()); + } + + public static class VO { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_5.java b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_5.java new file mode 100644 index 0000000000..a8e073a4a6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_5.java @@ -0,0 +1,30 @@ +package com.alibaba.json.bvt.parser; + +import java.util.LinkedList; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class JSONLexerTest_5 extends TestCase { + + public void test_scanFieldString() throws Exception { + VO vo = JSON.parseObject("{\"values\":[\"abc\"]}", VO.class); + Assert.assertEquals("abc", vo.getValues().get(0)); + } + + public static class VO { + + public LinkedList values; + + public LinkedList getValues() { + return values; + } + + public void setValues(LinkedList values) { + this.values = values; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_6.java b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_6.java new file mode 100644 index 0000000000..7e4777492a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_6.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.parser; + +import java.util.LinkedList; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class JSONLexerTest_6 extends TestCase { + + public void test_scanFieldString() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"values\":[\"abc\"]}", VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class VO { + + public MyList values; + + public MyList getValues() { + return values; + } + + public void setValues(MyList values) { + this.values = values; + } + } + + @SuppressWarnings("serial") + private class MyList extends LinkedList { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_7.java b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_7.java new file mode 100644 index 0000000000..e5683faa2e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_7.java @@ -0,0 +1,97 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.JSONScanner; + +public class JSONLexerTest_7 extends TestCase { + + public void test_treeSet() throws Exception { + JSON.parse("TreeSet[]"); + } + + public void test_error() throws Exception { + Exception error = null; + try { + JSON.parse("T_eeSet[]"); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_1() throws Exception { + Exception error = null; + try { + JSON.parse("Tr_eSet[]"); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_2() throws Exception { + Exception error = null; + try { + JSON.parse("Tre_Set[]"); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_3() throws Exception { + Exception error = null; + try { + JSON.parse("Tree_et[]"); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + + public void test_error_4() throws Exception { + Exception error = null; + try { + JSON.parse("TreeS_t[]"); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + + public void test_error_5() throws Exception { + Exception error = null; + try { + JSON.parse("TreeSe_[]"); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_6() throws Exception { + Exception error = null; + try { + JSON.parse("TreeSet_[]"); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_7() throws Exception { + Exception error = null; + try { + new JSONScanner("XreeSet[]").scanTreeSet(); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_8.java b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_8.java new file mode 100644 index 0000000000..74177c94fe --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_8.java @@ -0,0 +1,31 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.parser.JSONReaderScanner; +import com.alibaba.fastjson.parser.JSONScanner; +import com.alibaba.fastjson.parser.JSONToken; + +public class JSONLexerTest_8 extends TestCase { + + public void test_ident() throws Exception { + JSONScanner lexer = new JSONScanner("123"); + lexer.nextIdent(); + org.junit.Assert.assertEquals(JSONToken.LITERAL_INT, lexer.token()); + lexer.close(); + } + + public void test_ident_2() throws Exception { + JSONScanner lexer = new JSONScanner("\uFEFF123"); + lexer.nextIdent(); + org.junit.Assert.assertEquals(JSONToken.LITERAL_INT, lexer.token()); + lexer.close(); + } + + public void test_ident_3() throws Exception { + JSONReaderScanner lexer = new JSONReaderScanner("\uFEFF123"); + lexer.nextIdent(); + org.junit.Assert.assertEquals(JSONToken.LITERAL_INT, lexer.token()); + lexer.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_9.java b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_9.java new file mode 100644 index 0000000000..6ae641752c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_9.java @@ -0,0 +1,50 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class JSONLexerTest_9 extends TestCase { + + public void test_ident() throws Exception { + JSON.parseObject("\"AAA\"", Type.class); + } + + public void test_a() throws Exception { + JSON.parseObject("{\"type\":\"AAA\"}", VO.class); + } + + public void test_b() throws Exception { + JSON.parseObject("{\"tt\":\"AA\"}", VO.class); + } + + public void test_value() throws Exception { + JSON.parseObject("{\"type\":'AAA'}", VO.class); + } + + public void test_value2() throws Exception { + JSON.parseObject("{\"type\":\"AAA\",id:0}", VO.class); + } + + public static class VO { + + public VO(){ + + } + + private Type type; + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + } + + public static enum Type { + AAA, BBB, CCC + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_set.java b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_set.java new file mode 100644 index 0000000000..084ca4eab5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONLexerTest_set.java @@ -0,0 +1,56 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.JSONScanner; + +public class JSONLexerTest_set extends TestCase { + + public void test_treeSet() throws Exception { + JSON.parse("Set[]"); + } + + public void test_error() throws Exception { + Exception error = null; + try { + JSON.parse("S_t[]"); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_1() throws Exception { + Exception error = null; + try { + JSON.parse("Se_[]"); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + + public void test_error_2() throws Exception { + Exception error = null; + try { + JSON.parse("Set_[]"); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_3() throws Exception { + Exception error = null; + try { + new JSONScanner("Xet[]").scanSet(); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_boolean.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_boolean.java new file mode 100644 index 0000000000..809ac67620 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_boolean.java @@ -0,0 +1,62 @@ +package com.alibaba.json.bvt.parser; + +import java.io.Reader; +import java.io.StringReader; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest__entity_boolean extends TestCase { + + public void test_scanInt() throws Exception { + StringBuffer buf = new StringBuffer(); + buf.append('['); + for (int i = 0; i < 10; ++i) { + if (i != 0) { + buf.append(','); + } + //1000000000000 + // + if (i % 2 == 0) { + buf.append("{\"id\":true}"); + } else { + buf.append("{\"id\":false}"); + } + + } + buf.append(']'); + + Reader reader = new StringReader(buf.toString()); + + JSONReaderScanner scanner = new JSONReaderScanner(reader); + + DefaultJSONParser parser = new DefaultJSONParser(scanner); + List array = parser.parseArray(VO.class); + for (int i = 0; i < array.size(); ++i) { + if (i % 2 == 0) { + Assert.assertEquals(true, array.get(i).getId()); + } else { + Assert.assertEquals(false, array.get(i).getId()); + } + } + } + + public static class VO { + + private boolean id; + + public boolean getId() { + return id; + } + + public void setId(boolean id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_double.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_double.java new file mode 100644 index 0000000000..4f0cf53f19 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_double.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.parser; + +import java.io.Reader; +import java.io.StringReader; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest__entity_double extends TestCase { + + public void test_scanFloat() throws Exception { + StringBuffer buf = new StringBuffer(); + buf.append('['); + for (int i = 0; i < 1024; ++i) { + if (i != 0) { + buf.append(','); + } + buf.append("{\"id\":" + i + ".0}"); + } + buf.append(']'); + + Reader reader = new StringReader(buf.toString()); + + JSONReaderScanner scanner = new JSONReaderScanner(reader); + + DefaultJSONParser parser = new DefaultJSONParser(scanner); + List array = parser.parseArray(VO.class); + for (int i = 0; i < array.size(); ++i) { + Assert.assertTrue((double) i == array.get(i).getId()); + } + parser.close(); + } + + public static class VO { + + private double id; + + public double getId() { + return id; + } + + public void setId(double id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_double_2.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_double_2.java new file mode 100644 index 0000000000..b8beb2520b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_double_2.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.parser; + +import java.io.Reader; +import java.io.StringReader; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest__entity_double_2 extends TestCase { + + public void test_scanFloat() throws Exception { + StringBuffer buf = new StringBuffer(); + buf.append('['); + for (int i = 0; i < 1024; ++i) { + if (i != 0) { + buf.append(','); + } + buf.append("{\"id\":" + i + ".0}"); + } + buf.append(']'); + + Reader reader = new StringReader(buf.toString()); + + JSONReaderScanner scanner = new JSONReaderScanner(reader); + + DefaultJSONParser parser = new DefaultJSONParser(scanner); + List array = parser.parseArray(VO.class); + for (int i = 0; i < array.size(); ++i) { + Assert.assertTrue(Integer.toString(i), (double) i == array.get(i).getId()); + } + parser.close(); + } + + private static class VO { + + private double id; + + public double getId() { + return id; + } + + public void setId(double id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_enum.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_enum.java new file mode 100644 index 0000000000..74f8533a2b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_enum.java @@ -0,0 +1,74 @@ +package com.alibaba.json.bvt.parser; + +import java.io.Reader; +import java.io.StringReader; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest__entity_enum extends TestCase { + + public void test_scanInt() throws Exception { + StringBuffer buf = new StringBuffer(); + buf.append('['); + for (int i = 0; i < 10; ++i) { + if (i != 0) { + buf.append(','); + } + //1000000000000 + // + Type type; + if (i % 3 == 0) { + type = Type.A; + } else if (i % 3 == 1) { + type = Type.AA; + } else { + type = Type.AAA; + } + buf.append("{\"id\":\"" + type.name() + "\"}"); + + } + buf.append(']'); + + Reader reader = new StringReader(buf.toString()); + + JSONReaderScanner scanner = new JSONReaderScanner(reader); + + DefaultJSONParser parser = new DefaultJSONParser(scanner); + List array = parser.parseArray(VO.class); + for (int i = 0; i < array.size(); ++i) { + Type type; + if (i % 3 == 0) { + type = Type.A; + } else if (i % 3 == 1) { + type = Type.AA; + } else { + type = Type.AAA; + } + + Assert.assertEquals(type, array.get(i).getId()); + } + } + + public static class VO { + + private Type id; + + public Type getId() { + return id; + } + + public void setId(Type id) { + this.id = id; + } + } + + public static enum Type { + A, AA, AAA + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_float.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_float.java new file mode 100644 index 0000000000..a2cb9c8f7f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_float.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.parser; + +import java.io.Reader; +import java.io.StringReader; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest__entity_float extends TestCase { + + public void test_scanFloat() throws Exception { + StringBuffer buf = new StringBuffer(); + buf.append('['); + for (int i = 0; i < 1024; ++i) { + if (i != 0) { + buf.append(','); + } + buf.append("{\"id\":" + i + ".0}"); + } + buf.append(']'); + + Reader reader = new StringReader(buf.toString()); + + JSONReaderScanner scanner = new JSONReaderScanner(reader); + + DefaultJSONParser parser = new DefaultJSONParser(scanner); + List array = parser.parseArray(VO.class); + for (int i = 0; i < array.size(); ++i) { + Assert.assertTrue((float) i == array.get(i).getId()); + } + parser.close(); + } + + public static class VO { + + private float id; + + public float getId() { + return id; + } + + public void setId(float id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_int.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_int.java new file mode 100644 index 0000000000..32b812fefc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_int.java @@ -0,0 +1,51 @@ +package com.alibaba.json.bvt.parser; + +import java.io.Reader; +import java.io.StringReader; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest__entity_int extends TestCase { + + public void test_scanInt() throws Exception { + StringBuffer buf = new StringBuffer(); + buf.append('['); + for (int i = 0; i < 1024; ++i) { + if (i != 0) { + buf.append(','); + } + buf.append("{\"id\":" + i + "}"); + } + buf.append(']'); + + Reader reader = new StringReader(buf.toString()); + + JSONReaderScanner scanner = new JSONReaderScanner(reader); + + DefaultJSONParser parser = new DefaultJSONParser(scanner); + List array = parser.parseArray(VO.class); + for (int i = 0; i < array.size(); ++i) { + Assert.assertEquals(i, array.get(i).getId()); + } + } + + public static class VO { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_long.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_long.java new file mode 100644 index 0000000000..8685927567 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_long.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt.parser; + +import java.io.Reader; +import java.io.StringReader; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest__entity_long extends TestCase { + + public void test_scanInt() throws Exception { + StringBuffer buf = new StringBuffer(); + buf.append('['); + for (int i = 0; i < 10; ++i) { + if (i != 0) { + buf.append(','); + } + //1000000000000 + // + long value = (long) 1000000000000L + 1L + (long) i; + buf.append("{\"id\":" + value + "}"); + } + buf.append(']'); + + Reader reader = new StringReader(buf.toString()); + + JSONReaderScanner scanner = new JSONReaderScanner(reader); + + DefaultJSONParser parser = new DefaultJSONParser(scanner); + List array = parser.parseArray(VO.class); + for (int i = 0; i < array.size(); ++i) { + long value = (long) 1000000000000L + 1L + (long) i; + Assert.assertEquals(value, array.get(i).getId()); + } + } + + public static class VO { + + private long id; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_string.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_string.java new file mode 100644 index 0000000000..d732f54ba2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_string.java @@ -0,0 +1,54 @@ +package com.alibaba.json.bvt.parser; + +import java.io.Reader; +import java.io.StringReader; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest__entity_string extends TestCase { + + public void test_scanInt() throws Exception { + StringBuffer buf = new StringBuffer(); + buf.append('['); + for (int i = 0; i < 10; ++i) { + if (i != 0) { + buf.append(','); + } + //1000000000000 + // + buf.append("{\"id\":\"" + i + "\"}"); + + } + buf.append(']'); + + Reader reader = new StringReader(buf.toString()); + + JSONReaderScanner scanner = new JSONReaderScanner(reader); + + DefaultJSONParser parser = new DefaultJSONParser(scanner); + List array = parser.parseArray(VO.class); + for (int i = 0; i < array.size(); ++i) { + Assert.assertEquals(Integer.toString(i), array.get(i).getId()); + } + } + + public static class VO { + + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_stringList.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_stringList.java new file mode 100644 index 0000000000..50b95127e2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__entity_stringList.java @@ -0,0 +1,56 @@ +package com.alibaba.json.bvt.parser; + +import java.io.Reader; +import java.io.StringReader; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest__entity_stringList extends TestCase { + + public void test_scanInt() throws Exception { + StringBuffer buf = new StringBuffer(); + buf.append('['); + for (int i = 0; i < 10; ++i) { + if (i != 0) { + buf.append(','); + } + //1000000000000 + // + buf.append("{\"id\":[\"" + i + "\",\"" + (10000 + i) + "\"]}"); + + } + buf.append(']'); + + Reader reader = new StringReader(buf.toString()); + + JSONReaderScanner scanner = new JSONReaderScanner(reader); + + DefaultJSONParser parser = new DefaultJSONParser(scanner); + List array = parser.parseArray(VO.class); + for (int i = 0; i < array.size(); ++i) { + Assert.assertEquals(2, array.get(i).getId().size()); + Assert.assertEquals(Integer.toString(i), array.get(i).getId().get(0)); + Assert.assertEquals(Integer.toString(10000 + i), array.get(i).getId().get(1)); + } + } + + public static class VO { + + private List id; + + public List getId() { + return id; + } + + public void setId(List id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__map_string.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__map_string.java new file mode 100644 index 0000000000..c518cf066a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest__map_string.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt.parser; + +import java.io.Reader; +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest__map_string extends TestCase { + + public void test_scanInt() throws Exception { + StringBuffer buf = new StringBuffer(); + buf.append('['); + for (int i = 0; i < 10; ++i) { + if (i != 0) { + buf.append(','); + } + // 1000000000000 + // + buf.append("{\"id\":\"" + i + "\"}"); + + } + buf.append(']'); + + Reader reader = new StringReader(buf.toString()); + + JSONReaderScanner scanner = new JSONReaderScanner(reader); + + DefaultJSONParser parser = new DefaultJSONParser(scanner); + JSONArray array = (JSONArray) parser.parse(); + for (int i = 0; i < array.size(); ++i) { + Assert.assertEquals(Integer.toString(i), array.getJSONObject(i).get("id")); + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_array_string.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_array_string.java new file mode 100644 index 0000000000..d3f25c8358 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_array_string.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.parser; + +import java.io.Reader; +import java.io.StringReader; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest_array_string extends TestCase { + + public void test_scanInt() throws Exception { + StringBuffer buf = new StringBuffer(); + buf.append('['); + for (int i = 0; i < 10; ++i) { + if (i != 0) { + buf.append(','); + } + // 1000000000000 + // + buf.append("\"" + i + "\""); + } + buf.append(']'); + + Reader reader = new StringReader(buf.toString()); + + JSONReaderScanner scanner = new JSONReaderScanner(reader); + + DefaultJSONParser parser = new DefaultJSONParser(scanner); + JSONArray array = (JSONArray) parser.parse(); + for (int i = 0; i < array.size(); ++i) { + Assert.assertEquals(Integer.toString(i), array.get(i)); + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_bytes.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_bytes.java new file mode 100644 index 0000000000..268bc2bed9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_bytes.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.parser; + +import java.io.StringReader; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONReader; + +public class JSONReaderScannerTest_bytes extends TestCase { + + public void test_e() throws Exception { + VO vo = new VO(); + vo.setValue("ABC".getBytes("UTF-8")); + + String text = JSON.toJSONString(vo); + + JSONReader reader = new JSONReader(new StringReader(text)); + VO vo2 = reader.readObject(VO.class); + Assert.assertEquals("ABC", new String(vo2.getValue())); + reader.close(); + } + + public static class VO { + + private byte[] value; + + public byte[] getValue() { + return value; + } + + public void setValue(byte[] value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_decimal.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_decimal.java new file mode 100644 index 0000000000..af464a1548 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_decimal.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.parser; + +import java.io.Reader; +import java.io.StringReader; +import java.math.BigDecimal; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest_decimal extends TestCase { + + public void test_scanInt() throws Exception { + StringBuffer buf = new StringBuffer(); + buf.append('['); + for (int i = 0; i < 1024; ++i) { + if (i != 0) { + buf.append(','); + } + buf.append(i + ".0"); + } + buf.append(']'); + + Reader reader = new StringReader(buf.toString()); + + JSONReaderScanner scanner = new JSONReaderScanner(reader); + + DefaultJSONParser parser = new DefaultJSONParser(scanner); + JSONArray array = (JSONArray) parser.parse(); + for (int i = 0; i < array.size(); ++i) { + BigDecimal value = new BigDecimal(i + ".0"); + Assert.assertEquals(value, array.get(i)); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_enum.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_enum.java new file mode 100644 index 0000000000..48c2e1926a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_enum.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.parser; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; + +public class JSONReaderScannerTest_enum extends TestCase { + + public void test_e() throws Exception { + JSONReader reader = new JSONReader(new StringReader("{type:'AA'}")); + VO vo2 = reader.readObject(VO.class); + Assert.assertEquals(Type.AA, vo2.getType()); + reader.close(); + } + + public static class VO { + + private Type type; + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + + } + + public static enum Type { + AA, BB, CC + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_error.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_error.java new file mode 100644 index 0000000000..a3e859d016 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_error.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.parser; + +import java.io.IOException; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; + +public class JSONReaderScannerTest_error extends TestCase { + + public void test_e() throws Exception { + Exception error = null; + try { + new JSONReader(new MyReader()); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class MyReader extends java.io.Reader { + + @Override + public int read(char[] cbuf, int off, int len) throws IOException { + throw new IOException(); + } + + @Override + public void close() throws IOException { + // TODO Auto-generated method stub + + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_error2.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_error2.java new file mode 100644 index 0000000000..8419a63536 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_error2.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt.parser; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; + +public class JSONReaderScannerTest_error2 extends TestCase { + + public void test_e() throws Exception { + Exception error = null; + try { + StringBuilder buf = new StringBuilder(); + buf.append("[{\"type\":\""); + for (int i = 0; i < 8180; ++i) { + buf.append('A'); + } + buf.append("\"}"); + JSONReader reader = new JSONReader(new StringReader(buf.toString())); + reader.readObject(); + reader.close(); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class VO { + + private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_error3.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_error3.java new file mode 100644 index 0000000000..2f11733638 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_error3.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt.parser; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; + +public class JSONReaderScannerTest_error3 extends TestCase { + + public void test_e() throws Exception { + Exception error = null; + try { + StringBuilder buf = new StringBuilder(); + buf.append("[{\"type\":\""); + for (int i = 0; i < 8180; ++i) { + buf.append('A'); + } + buf.append("\\t"); + JSONReader reader = new JSONReader(new StringReader(buf.toString())); + reader.readObject(); + reader.close(); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class VO { + + private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_error4.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_error4.java new file mode 100644 index 0000000000..d0a190dc86 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_error4.java @@ -0,0 +1,60 @@ +package com.alibaba.json.bvt.parser; + +import java.io.IOException; +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; + +public class JSONReaderScannerTest_error4 extends TestCase { + + public void test_e() throws Exception { + Exception error = null; + try { + StringBuilder buf = new StringBuilder(); + buf.append("[{\"type\":\""); + for (int i = 0; i < 8180; ++i) { + buf.append('A'); + } + buf.append("\\t"); + JSONReader reader = new JSONReader(new MyReader(buf.toString())); + reader.readObject(); + reader.close(); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class VO { + + private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + } + + public static class MyReader extends StringReader { + + public MyReader(String s){ + super(s); + } + + public int read(char cbuf[], int off, int len) throws IOException { + int x = super.read(cbuf, off, len); + if (x < 0) { + throw new IOException(); + } + return x; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_error5.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_error5.java new file mode 100644 index 0000000000..19844d9d21 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_error5.java @@ -0,0 +1,60 @@ +package com.alibaba.json.bvt.parser; + +import java.io.IOException; +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; + +public class JSONReaderScannerTest_error5 extends TestCase { + + public void test_e() throws Exception { + Exception error = null; + try { + StringBuilder buf = new StringBuilder(); + buf.append("[{\"type\":\""); + for (int i = 0; i < 8180; ++i) { + buf.append('A'); + } + buf.append("\\t"); + JSONReader reader = new JSONReader(new MyReader(buf.toString())); + reader.readObject(); + reader.close(); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class VO { + + private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + } + + public static class MyReader extends StringReader { + + public MyReader(String s){ + super(s); + } + + public int read(char cbuf[], int off, int len) throws IOException { + int x = super.read(cbuf, off, len); + if (x < 0) { + return 0; + } + return x; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_int.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_int.java new file mode 100644 index 0000000000..56fc8c5f13 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_int.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.parser; + +import java.io.Reader; +import java.io.StringReader; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest_int extends TestCase { + + public void test_scanInt() throws Exception { + StringBuffer buf = new StringBuffer(); + buf.append('['); + for (int i = 0; i < 1024; ++i) { + if (i != 0) { + buf.append(','); + } + buf.append(i); + } + buf.append(']'); + + Reader reader = new StringReader(buf.toString()); + + JSONReaderScanner scanner = new JSONReaderScanner(reader); + + DefaultJSONParser parser = new DefaultJSONParser(scanner); + JSONArray array = (JSONArray) parser.parse(); + for (int i = 0; i < array.size(); ++i) { + Assert.assertEquals(i, ((Integer) array.get(i)).intValue()); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_jsonobject.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_jsonobject.java new file mode 100644 index 0000000000..1479643553 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_jsonobject.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.parser; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONReader; + +public class JSONReaderScannerTest_jsonobject extends TestCase { + + public void test_e() throws Exception { + JSONReader reader = new JSONReader(new StringReader("{\"type\\t\":'AA'}")); + JSONObject vo = new JSONObject(); + reader.readObject(vo); + Assert.assertEquals("AA", vo.get("type\t")); + reader.close(); + } + + public static class VO { + + private Type type; + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + + } + + public static enum Type { + AA, BB, CC + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_long.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_long.java new file mode 100644 index 0000000000..c5feb755ae --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderScannerTest_long.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.parser; + +import java.io.Reader; +import java.io.StringReader; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest_long extends TestCase { + + public void test_scanInt() throws Exception { + StringBuffer buf = new StringBuffer(); + buf.append('['); + for (int i = 0; i < 1024; ++i) { + if (i != 0) { + buf.append(','); + } + long value = (long) Integer.MAX_VALUE + 1L + (long) i; + buf.append(value); + } + buf.append(']'); + + Reader reader = new StringReader(buf.toString()); + + JSONReaderScanner scanner = new JSONReaderScanner(reader); + + DefaultJSONParser parser = new DefaultJSONParser(scanner); + JSONArray array = (JSONArray) parser.parse(); + for (int i = 0; i < array.size(); ++i) { + long value = (long) Integer.MAX_VALUE + 1L + (long) i; + Assert.assertEquals(value, ((Long) array.get(i)).longValue()); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_array_array.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_array_array.java new file mode 100644 index 0000000000..f8533169e9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_array_array.java @@ -0,0 +1,49 @@ +package com.alibaba.json.bvt.parser; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.parser.JSONScanner; + +public class JSONReaderTest_array_array extends TestCase { + + String text = "[[],[],[],[],[], [],[],[],[],[]]"; + + public void test_read() throws Exception { + + JSONReader reader = new JSONReader(new StringReader(text)); + reader.startArray(); + + int count = 0; + while (reader.hasNext()) { + Object item = reader.readObject(); + Assert.assertEquals(JSONArray.class, item.getClass()); + count++; + } + Assert.assertEquals(10, count); + + reader.endArray(); + reader.close(); + } + + public void test_read_1() throws Exception { + JSONReader reader = new JSONReader(new JSONScanner(text)); + reader.startArray(); + + int count = 0; + while (reader.hasNext()) { + Object item = reader.readObject(); + Assert.assertEquals(JSONArray.class, item.getClass()); + count++; + } + Assert.assertEquals(10, count); + + reader.endArray(); + reader.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_array_array_2.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_array_array_2.java new file mode 100644 index 0000000000..4b52d0aa00 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_array_array_2.java @@ -0,0 +1,48 @@ +package com.alibaba.json.bvt.parser; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.parser.JSONScanner; + +public class JSONReaderTest_array_array_2 extends TestCase { + + String text = "[[],[],[],[],[], [],[],[],[],[]]"; + + public void test_read() throws Exception { + + JSONReader reader = new JSONReader(new StringReader(text)); + reader.startArray(); + + int count = 0; + while (reader.hasNext()) { + reader.startArray(); + reader.endArray(); + count++; + } + Assert.assertEquals(10, count); + + reader.endArray(); + reader.close(); + } + + public void test_read_1() throws Exception { + JSONReader reader = new JSONReader(new JSONScanner(text)); + reader.startArray(); + + int count = 0; + while (reader.hasNext()) { + reader.startArray(); + reader.endArray(); + count++; + } + Assert.assertEquals(10, count); + + reader.endArray(); + reader.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_array_object.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_array_object.java new file mode 100644 index 0000000000..2a6e9adf73 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_array_object.java @@ -0,0 +1,73 @@ +package com.alibaba.json.bvt.parser; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.parser.JSONScanner; + +public class JSONReaderTest_array_object extends TestCase { + + String text = "[{},{},{},{},{} ,{},{},{},{},{}]"; + + public void test_read() throws Exception { + + JSONReader reader = new JSONReader(new StringReader(text)); + reader.startArray(); + + int count = 0; + while (reader.hasNext()) { + reader.readObject(); + count++; + } + Assert.assertEquals(10, count); + + reader.endArray(); + reader.close(); + } + + public void test_read_1() throws Exception { + JSONReader reader = new JSONReader(new JSONScanner(text)); + reader.startArray(); + + int count = 0; + while (reader.hasNext()) { + reader.readObject(); + count++; + } + Assert.assertEquals(10, count); + + reader.endArray(); + reader.close(); + } + + public void test_read_3() throws Exception { + JSONReader reader = new JSONReader(new JSONScanner(text)); + reader.startArray(); + + + + Assert.assertTrue(reader.hasNext()); + reader.startObject(); + reader.endObject(); + + Assert.assertTrue(reader.hasNext()); + reader.startObject(); + reader.endObject(); + + int count = 2; + + while (reader.hasNext()) { + reader.startObject(); + reader.endObject(); + count++; + } + Assert.assertEquals(10, count); + + reader.endArray(); + reader.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_array_object_2.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_array_object_2.java new file mode 100644 index 0000000000..b561acc428 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_array_object_2.java @@ -0,0 +1,48 @@ +package com.alibaba.json.bvt.parser; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.parser.JSONScanner; + +public class JSONReaderTest_array_object_2 extends TestCase { + + String text = "[{},{},{},{},{} ,{},{},{},{},{}]"; + + public void test_read() throws Exception { + + JSONReader reader = new JSONReader(new StringReader(text)); + reader.startArray(); + + int count = 0; + while (reader.hasNext()) { + reader.startObject(); + reader.endObject(); + count++; + } + Assert.assertEquals(10, count); + + reader.endArray(); + reader.close(); + } + + public void test_read_1() throws Exception { + JSONReader reader = new JSONReader(new JSONScanner(text)); + reader.startArray(); + + int count = 0; + while (reader.hasNext()) { + reader.startObject(); + reader.endObject(); + count++; + } + Assert.assertEquals(10, count); + + reader.endArray(); + reader.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_object_int.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_object_int.java new file mode 100644 index 0000000000..fb21d486bf --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_object_int.java @@ -0,0 +1,47 @@ +package com.alibaba.json.bvt.parser; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.parser.JSONScanner; + +public class JSONReaderTest_object_int extends TestCase { + + public void test_read() throws Exception { + String text = "{\"f0\":0,\"f1\":1,\"f2\":2,\"f3\":3,\"f4\":4, " + // + "\"f5\":5,\"f6\":6,\"f7\":7,\"f8\":8,\"f9\":9}"; + JSONReader reader = new JSONReader(new StringReader(text)); + reader.startObject(); + + int count = 0; + while (reader.hasNext()) { + String key = (String) reader.readObject(); + Integer value = reader.readInteger(); + count++; + } + Assert.assertEquals(10, count); + + reader.endObject(); + reader.close(); + } + + public void test_read_1() throws Exception { + String text = "[{},{},{},{},{} ,{},{},{},{},{}]"; + JSONReader reader = new JSONReader(new JSONScanner(text)); + reader.startArray(); + + int count = 0; + while (reader.hasNext()) { + reader.readObject(); + count++; + } + Assert.assertEquals(10, count); + + reader.endArray(); + reader.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_object_int_unquote.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_object_int_unquote.java new file mode 100644 index 0000000000..e6e8ff0d9c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_object_int_unquote.java @@ -0,0 +1,50 @@ +package com.alibaba.json.bvt.parser; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.JSONScanner; + +public class JSONReaderTest_object_int_unquote extends TestCase { + + String text = "{f0:0,f1:1,f2:2,f3:3,f4:4, " + // + "f5:5,f6:6,f7:7,f8:8,f9:9}"; + + public void test_read() throws Exception { + + JSONReader reader = new JSONReader(new StringReader(text)); + reader.startObject(); + + int count = 0; + while (reader.hasNext()) { + String key = (String) reader.readObject(); + Integer value = reader.readInteger(); + count++; + } + Assert.assertEquals(10, count); + + reader.endObject(); + reader.close(); + } + + public void test_read_1() throws Exception { + JSONReader reader = new JSONReader(new JSONScanner(text)); + reader.startObject(); + + int count = 0; + while (reader.hasNext()) { + String key = (String) reader.readObject(); + Integer value = reader.readInteger(); + count++; + } + Assert.assertEquals(10, count); + + reader.endObject(); + reader.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_object_long.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_object_long.java new file mode 100644 index 0000000000..d6da5c574e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_object_long.java @@ -0,0 +1,51 @@ +package com.alibaba.json.bvt.parser; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.parser.JSONScanner; + +public class JSONReaderTest_object_long extends TestCase { + + String text = "{\"f0\":0,\"f1\":1,\"f2\":2,\"f3\":3,\"f4\":4, " + // + "\"f5\":5,\"f6\":6,\"f7\":7,\"f8\":8,\"f9\":9}"; + + public void test_read() throws Exception { + + JSONReader reader = new JSONReader(new StringReader(text)); + + reader.startObject(); + + int count = 0; + while (reader.hasNext()) { + String key = (String) reader.readObject(); + Long value = reader.readLong(); + count++; + } + Assert.assertEquals(10, count); + + reader.endObject(); + reader.close(); + } + + public void test_read_1() throws Exception { + JSONReader reader = new JSONReader(new JSONScanner(text)); + + reader.startObject(); + + int count = 0; + while (reader.hasNext()) { + String key = (String) reader.readObject(); + Long value = reader.readLong(); + count++; + } + Assert.assertEquals(10, count); + + reader.endObject(); + reader.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_object_object.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_object_object.java new file mode 100644 index 0000000000..bdc8bd0627 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_object_object.java @@ -0,0 +1,88 @@ +package com.alibaba.json.bvt.parser; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.parser.JSONScanner; + +public class JSONReaderTest_object_object extends TestCase { + + String text = "{\"f0\":{},\"f1\":{},\"f2\":{},\"f3\":{},\"f4\":{}, " + // + "\"f5\":{},\"f6\":{},\"f7\":{},\"f8\":{},\"f9\":{}}"; + + public void test_read() throws Exception { + + JSONReader reader = new JSONReader(new StringReader(text)); + reader.startObject(); + + int count = 0; + while (reader.hasNext()) { + String key = (String) reader.readObject(); + Object value = reader.readObject(); + Assert.assertNotNull(key); + Assert.assertNotNull(value); + count++; + } + Assert.assertEquals(10, count); + + reader.endObject(); + reader.close(); + } + + public void test_read_1() throws Exception { + JSONReader reader = new JSONReader(new JSONScanner(text)); + reader.startObject(); + + int count = 0; + while (reader.hasNext()) { + String key = (String) reader.readObject(); + Object value = reader.readObject(); + + Assert.assertNotNull(key); + Assert.assertNotNull(value); + + count++; + } + Assert.assertEquals(10, count); + + reader.endObject(); + reader.close(); + } + + public void test_read_2() throws Exception { + JSONReader reader = new JSONReader(new JSONScanner("{{}:{},{}:{}}")); + reader.startObject(); + + Assert.assertTrue(reader.hasNext()); + reader.startObject(); + reader.endObject(); + + reader.startObject(); + reader.endObject(); + + Assert.assertTrue(reader.hasNext()); + reader.startObject(); + reader.endObject(); + + reader.startObject(); + reader.endObject(); + + Assert.assertFalse(reader.hasNext()); + + reader.endObject(); + + Exception error = null; + try { + reader.hasNext(); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + + reader.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_object_string.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_object_string.java new file mode 100644 index 0000000000..41e61b0ff1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReaderTest_object_string.java @@ -0,0 +1,51 @@ +package com.alibaba.json.bvt.parser; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.parser.JSONScanner; + +public class JSONReaderTest_object_string extends TestCase { + + String text = "{\"f0\":\"0\",\"f1\":\"1\",\"f2\":\"2\",\"f3\":\"3\",\"f4\":\"4\", " + // + "\"f5\":\"5\",\"f6\":\"6\",\"f7\":\"7\",\"f8\":\"8\",\"f9\":\"9\"}"; + + public void test_read() throws Exception { + + JSONReader reader = new JSONReader(new StringReader(text)); + + reader.startObject(); + + int count = 0; + while (reader.hasNext()) { + String key = (String) reader.readObject(); + String value = reader.readString(); + count++; + } + Assert.assertEquals(10, count); + + reader.endObject(); + reader.close(); + } + + public void test_read_1() throws Exception { + JSONReader reader = new JSONReader(new JSONScanner(text)); + + reader.startObject(); + + int count = 0; + while (reader.hasNext()) { + String key = (String) reader.readObject(); + Long value = reader.readLong(); + count++; + } + Assert.assertEquals(10, count); + + reader.endObject(); + reader.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReader_error.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReader_error.java new file mode 100644 index 0000000000..2085a6c103 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReader_error.java @@ -0,0 +1,42 @@ +package com.alibaba.json.bvt.parser; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; + +public class JSONReader_error extends TestCase { + + public void test_0() throws Exception { + JSONReader reader = new JSONReader(new StringReader("[]")); + + Exception error = null; + try { + reader.hasNext(); + } catch (Exception e) { + error = e; + } + Assert.assertNotNull(error); + + reader.close(); + } + + public void test_1() throws Exception { + JSONReader reader = new JSONReader(new StringReader("{\"id\":123}")); + + reader.startObject(); + reader.readObject(); + + Exception error = null; + try { + reader.hasNext(); + } catch (Exception e) { + error = e; + } + Assert.assertNotNull(error); + reader.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONReader_top.java b/src/test/java/com/alibaba/json/bvt/parser/JSONReader_top.java new file mode 100644 index 0000000000..5131ec8ce9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONReader_top.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.parser; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; + +public class JSONReader_top extends TestCase { + + public void test_int() throws Exception { + JSONReader reader = new JSONReader(new StringReader("123")); + + Assert.assertEquals(new Integer(123), reader.readInteger()); + + reader.close(); + } + + public void test_long() throws Exception { + JSONReader reader = new JSONReader(new StringReader("123")); + + Assert.assertEquals(new Long(123), reader.readLong()); + + reader.close(); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_ISO8601.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_ISO8601.java old mode 100644 new mode 100755 similarity index 97% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_ISO8601.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_ISO8601.java index f9a775f5fe..544508323e --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_ISO8601.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_ISO8601.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.parser.Feature; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest__nextToken.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest__nextToken.java old mode 100644 new mode 100755 similarity index 98% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest__nextToken.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest__nextToken.java index 9cd0486da0..9a91e77ae5 --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest__nextToken.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest__nextToken.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.parser.JSONScanner; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest__x.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest__x.java old mode 100644 new mode 100755 similarity index 88% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest__x.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest__x.java index 58fe0312b4..7f6c46c470 --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest__x.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest__x.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_colon.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_colon.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_colon.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_colon.java index 3528ef5960..68ad4bcd86 --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_colon.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_colon.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONException; @@ -10,7 +10,7 @@ /** * 测试字符':'的处理 * - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class JSONScannerTest_colon extends TestCase { diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_false.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_false.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_false.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_false.java index 218533e8c5..e5c4b1919f --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_false.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_false.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONException; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_ident.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_ident.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_ident.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_ident.java index f1b4721a46..f10578ac14 --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_ident.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_ident.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.parser.JSONScanner; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_int.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_int.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_int.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_int.java index a58674809b..0bea2becec --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_int.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_int.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.parser.JSONScanner; @@ -8,7 +8,7 @@ /** * parseInt * - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class JSONScannerTest_int extends TestCase { diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_isEOF.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_isEOF.java old mode 100644 new mode 100755 similarity index 73% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_isEOF.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_isEOF.java index 3e6830bdcf..3c7650e8df --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_isEOF.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_isEOF.java @@ -1,11 +1,12 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.parser.JSONScanner; +import com.alibaba.fastjson.parser.JSONToken; public class JSONScannerTest_isEOF extends TestCase { @@ -18,20 +19,20 @@ public void test_0() throws Exception { public void test_1() throws Exception { JSONScanner lexer = new JSONScanner(" "); lexer.nextToken(); - Assert.assertTrue(lexer.isEOF()); + Assert.assertTrue(lexer.token() == JSONToken.EOF); } public void test_2() throws Exception { JSONScanner lexer = new JSONScanner("1 "); lexer.nextToken(); lexer.nextToken(); - Assert.assertTrue(lexer.isEOF()); + Assert.assertTrue(lexer.token() == JSONToken.EOF); } public void test_3() throws Exception { JSONScanner lexer = new JSONScanner(" {}"); lexer.nextToken(); - Assert.assertTrue(!lexer.isEOF()); + Assert.assertTrue(lexer.token() != JSONToken.EOF); } } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_long.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_long.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_long.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_long.java index 8b15ddc733..a68f4b9fe8 --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_long.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_long.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.parser.JSONScanner; @@ -8,7 +8,7 @@ /** * parseLong * - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class JSONScannerTest_long extends TestCase { diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_new.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_new.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_new.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_new.java index 1c5dc40716..9c6c0567f6 --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_new.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_new.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONException; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_null.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_null.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_null.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_null.java index 4251ee08b2..4b76da914e --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_null.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_null.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONException; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldBoolean.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldBoolean.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldBoolean.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldBoolean.java index 0865ffd029..f882fcde4e --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldBoolean.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldBoolean.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -37,11 +37,7 @@ public void test_3() throws Exception { Assert.assertEquals(true, obj.getValue()); } - public void test_4() throws Exception { - String text = "{\"value\":false,id:2}"; - VO obj = JSON.parseObject(text, VO.class); - Assert.assertEquals(false, obj.getValue()); - } + public void test_5() throws Exception { String text = "{\"value\":false}"; diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldBoolean_unquote.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldBoolean_unquote.java new file mode 100644 index 0000000000..e7a749499d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldBoolean_unquote.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.parser; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.json.bvt.parser.JSONScannerTest_scanFieldBoolean.VO; + +public class JSONScannerTest_scanFieldBoolean_unquote extends TestCase { + + public void test_4() throws Exception { + String text = "{\"value\":false,id:2}"; + VO obj = JSON.parseObject(text, VO.class); + Assert.assertEquals(false, obj.getValue()); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldDouble.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldDouble.java old mode 100644 new mode 100755 similarity index 90% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldDouble.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldDouble.java index a6c155273a..c35c9a5f73 --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldDouble.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldDouble.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -11,43 +11,43 @@ public class JSONScannerTest_scanFieldDouble extends TestCase { public void test_0() throws Exception { String text = "{\"value\":1.0}"; VO obj = JSON.parseObject(text, VO.class); - Assert.assertEquals(1D, obj.getValue()); + Assert.assertTrue(1D == obj.getValue()); } public void test_1() throws Exception { String text = "{\"value\":\"1\"}"; VO obj = JSON.parseObject(text, VO.class); - Assert.assertEquals(1D, obj.getValue()); + Assert.assertTrue(1D == obj.getValue()); } public void test_2() throws Exception { String text = "{\"f1\":2,\"value\":1.0}"; VO obj = JSON.parseObject(text, VO.class); - Assert.assertEquals(1D, obj.getValue()); + Assert.assertTrue(1D == obj.getValue()); } public void test_3() throws Exception { String text = "{\"value\":1.01}"; VO obj = JSON.parseObject(text, VO.class); - Assert.assertEquals(1.01D, obj.getValue()); + Assert.assertTrue(1.01D == obj.getValue()); } public void test_4() throws Exception { String text = "{\"value\":1.}"; VO obj = JSON.parseObject(text, VO.class); - Assert.assertEquals(1D, obj.getValue()); + Assert.assertTrue(1D == obj.getValue()); } public void test_5() throws Exception { String text = "{\"value\":922337203685477580723}"; VO obj = JSON.parseObject(text, VO.class); - Assert.assertEquals(922337203685477580723D, obj.getValue()); + Assert.assertTrue(922337203685477580723D == obj.getValue()); } public void test_error_2() throws Exception { JSONException error = null; try { - String text = "{\"value\":32D}"; + String text = "{\"value\":32K}"; JSON.parseObject(text, VO.class); } catch (JSONException ex) { error = ex; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldFloat.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldFloat.java old mode 100644 new mode 100755 similarity index 90% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldFloat.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldFloat.java index 8f9e5aa0f9..e0da50ad00 --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldFloat.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldFloat.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -12,9 +12,10 @@ public class JSONScannerTest_scanFieldFloat extends TestCase { public void test_0() throws Exception { String text = "{\"value\":1.0}"; VO obj = JSON.parseObject(text, VO.class); - Assert.assertEquals(1F, obj.getValue()); + Assert.assertTrue(1F == obj.getValue()); } + @SuppressWarnings("resource") public void test_isBlank() throws Exception { String text = " {\"value\":1.0}"; Assert.assertTrue(!new JSONScanner(text).isBlankInput()); @@ -23,37 +24,37 @@ public void test_isBlank() throws Exception { public void test_1() throws Exception { String text = "{\"value\":\"1\"}"; VO obj = JSON.parseObject(text, VO.class); - Assert.assertEquals(1F, obj.getValue()); + Assert.assertTrue(1F == obj.getValue()); } public void test_2() throws Exception { String text = "{\"f1\":2,\"value\":1.0}"; VO obj = JSON.parseObject(text, VO.class); - Assert.assertEquals(1F, obj.getValue()); + Assert.assertTrue(1F == obj.getValue()); } public void test_3() throws Exception { String text = "{\"value\":1.01}"; VO obj = JSON.parseObject(text, VO.class); - Assert.assertEquals(1.01F, obj.getValue()); + Assert.assertTrue(1.01F == obj.getValue()); } public void test_4() throws Exception { String text = "{\"value\":1.}"; VO obj = JSON.parseObject(text, VO.class); - Assert.assertEquals(1F, obj.getValue()); + Assert.assertTrue(1F == obj.getValue()); } public void test_error_1() throws Exception { String text = "{\"value\":922337203685477580723}"; VO obj = JSON.parseObject(text, VO.class); - Assert.assertEquals(922337203685477580723F, obj.getValue()); + Assert.assertTrue(922337203685477580723F == obj.getValue()); } public void test_error_2() throws Exception { JSONException error = null; try { - String text = "{\"value\":32D}"; + String text = "{\"value\":32M}"; JSON.parseObject(text, VO.class); } catch (JSONException ex) { error = ex; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldInt.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldInt.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldInt.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldInt.java index 0f59497ae1..0ed2775975 --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldInt.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldInt.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -34,7 +34,7 @@ public void test_error_1() throws Exception { public void test_error_2() throws Exception { JSONException error = null; try { - String text = "{\"value\":32D}"; + String text = "{\"value\":32O}"; JSON.parseObject(text, VO.class); } catch (JSONException ex) { error = ex; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldLong.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldLong.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldLong.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldLong.java index 2876e0f9dd..9ed14f8f84 --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldLong.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldLong.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -14,6 +14,7 @@ public void test_0() throws Exception { Assert.assertEquals(1, obj.getValue()); } + /** public void test_1() throws Exception { JSONException error = null; try { @@ -28,7 +29,7 @@ public void test_1() throws Exception { public void test_2() throws Exception { JSONException error = null; try { - String text = "{\"value\":32D}"; + String text = "{\"value\":32RR}"; JSON.parseObject(text, VO.class); } catch (JSONException ex) { error = ex; @@ -90,7 +91,7 @@ public void test_error_7() throws Exception { } Assert.assertNotNull(error); } - +*/ public static class VO { private long value; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldString.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldString.java old mode 100644 new mode 100755 similarity index 59% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldString.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldString.java index dc79413419..79f173ab41 --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldString.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldString.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -12,25 +12,25 @@ public void test_0() throws Exception { VO obj = JSON.parseObject(text, VO.class); Assert.assertEquals("1", obj.getValue()); } - + public void test_1() throws Exception { String text = "{\"value\":\"1\"}"; VO obj = JSON.parseObject(text, VO.class); Assert.assertEquals("1", obj.getValue()); } - + public void test_2() throws Exception { String text = "{\"value\":\"1\\t\"}"; VO obj = JSON.parseObject(text, VO.class); Assert.assertEquals("1\t", obj.getValue()); } - + public void test_3() throws Exception { String text = "{\"value\":\"1\\n\"}"; VO obj = JSON.parseObject(text, VO.class); Assert.assertEquals("1\n", obj.getValue()); } - + public void test_error_0() { Exception error = null; try { @@ -41,40 +41,6 @@ public void test_error_0() { } Assert.assertNotNull(error); } - - public void test_error_1() { - Exception error = null; - try { - String text = "{\"value\":\"1\"}}"; - JSON.parseObject(text, VO.class); - } catch (Exception ex) { - error = ex; - } - Assert.assertNotNull(error); - } - - public void test_error_2() { - Exception error = null; - try { - String text = "{\"value\":\"1\"}1"; - JSON.parseObject(text, VO.class); - } catch (Exception ex) { - error = ex; - } - Assert.assertNotNull(error); - } - - public void test_error_3() { - Exception error = null; - try { - String text = "{\"value\":\"1\"1"; - JSON.parseObject(text, VO.class); - } catch (Exception ex) { - error = ex; - } - Assert.assertNotNull(error); - } - public static class VO { diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldStringArray.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldStringArray.java old mode 100644 new mode 100755 similarity index 97% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldStringArray.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldStringArray.java index 1595762dfd..18661162bc --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanFieldStringArray.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldStringArray.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldString_error.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldString_error.java new file mode 100644 index 0000000000..bd3bb187be --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanFieldString_error.java @@ -0,0 +1,68 @@ +package com.alibaba.json.bvt.parser; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class JSONScannerTest_scanFieldString_error extends TestCase { + + public void f_test_error_0() { + Exception error = null; + try { + String text = "{\"value\":\"1\\n\""; + JSON.parseObject(text, VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void f_test_error_1() { + Exception error = null; + try { + String text = "{\"value\":\"1\"}}"; + JSON.parseObject(text, VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_2() { + Exception error = null; + try { + String text = "{\"value\":\"1\"}1"; + JSON.parseObject(text, VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_3() { + Exception error = null; + try { + String text = "{\"value\":\"1\"1"; + JSON.parseObject(text, VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + + public static class VO { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanSymbol.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanSymbol.java old mode 100644 new mode 100755 similarity index 80% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanSymbol.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanSymbol.java index 326ba20135..d201e59a8a --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_scanSymbol.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_scanSymbol.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.parser.JSONScanner; @@ -10,7 +10,7 @@ /** * 测试字符':'的处理 * - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class JSONScannerTest_scanSymbol extends TestCase { @@ -18,14 +18,14 @@ public void test_0() throws Exception { JSONScanner lexer = new JSONScanner("\"value\":\"aa\\n\""); String text = lexer.scanFieldSymbol("\"value\":".toCharArray(), new SymbolTable()); Assert.assertNull(text); - Assert.assertEquals(JSONScanner.NOT_MATCH, lexer.matchStat); + Assert.assertEquals(JSONScanner.NOT_MATCH, lexer.matchStat()); } public void test_1() throws Exception { JSONScanner lexer = new JSONScanner("\"value\":\"aa\"},"); String text = lexer.scanFieldSymbol("\"value\":".toCharArray(), new SymbolTable()); Assert.assertEquals("aa", text); - Assert.assertEquals(JSONScanner.END, lexer.matchStat); + Assert.assertEquals(JSONScanner.END, lexer.matchStat()); Assert.assertEquals(JSONToken.COMMA, lexer.token()); } @@ -33,7 +33,7 @@ public void test_2() throws Exception { JSONScanner lexer = new JSONScanner("\"value\":\"aa\"}]"); String text = lexer.scanFieldSymbol("\"value\":".toCharArray(), new SymbolTable()); Assert.assertEquals("aa", text); - Assert.assertEquals(JSONScanner.END, lexer.matchStat); + Assert.assertEquals(JSONScanner.END, lexer.matchStat()); Assert.assertEquals(JSONToken.RBRACKET, lexer.token()); } @@ -41,7 +41,7 @@ public void test_3() throws Exception { JSONScanner lexer = new JSONScanner("\"value\":\"aa\"}}"); String text = lexer.scanFieldSymbol("\"value\":".toCharArray(), new SymbolTable()); Assert.assertEquals("aa", text); - Assert.assertEquals(JSONScanner.END, lexer.matchStat); + Assert.assertEquals(JSONScanner.END, lexer.matchStat()); Assert.assertEquals(JSONToken.RBRACE, lexer.token()); } @@ -49,7 +49,7 @@ public void test_4() throws Exception { JSONScanner lexer = new JSONScanner("\"value\":\"aa\"}"); String text = lexer.scanFieldSymbol("\"value\":".toCharArray(), new SymbolTable()); Assert.assertEquals("aa", text); - Assert.assertEquals(JSONScanner.END, lexer.matchStat); + Assert.assertEquals(JSONScanner.END, lexer.matchStat()); Assert.assertEquals(JSONToken.EOF, lexer.token()); } @@ -57,13 +57,13 @@ public void test_6() throws Exception { JSONScanner lexer = new JSONScanner("\"value\":\"aa\"}{"); String text = lexer.scanFieldSymbol("\"value\":".toCharArray(), new SymbolTable()); Assert.assertEquals(null, text); - Assert.assertEquals(JSONScanner.NOT_MATCH, lexer.matchStat); + Assert.assertEquals(JSONScanner.NOT_MATCH, lexer.matchStat()); } public void test_7() throws Exception { JSONScanner lexer = new JSONScanner("\"value\":\"aa\""); String text = lexer.scanFieldSymbol("\"value\":".toCharArray(), new SymbolTable()); Assert.assertEquals(null, text); - Assert.assertEquals(JSONScanner.NOT_MATCH, lexer.matchStat); + Assert.assertEquals(JSONScanner.NOT_MATCH, lexer.matchStat()); } } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_singQuoteString.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_singQuoteString.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_singQuoteString.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_singQuoteString.java index bc3a3ee47d..ea827edad3 --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_singQuoteString.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_singQuoteString.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -34,7 +34,7 @@ public void test_string() throws Exception { StringBuilder buf = new StringBuilder(); buf.append('\''); - buf.append("\\\\\\/\\b\\f\\n\\r\\t\\u" + Integer.toHexString('中')); + buf.append("\\\\\\/\\b\\f\\n\\r\t\\u" + Integer.toHexString('中')); buf.append('\''); buf.append('\u2001'); @@ -48,7 +48,7 @@ public void test_string() throws Exception { String stringVal = lexer.stringVal(); - Assert.assertEquals("\"\\\\/\\b\\f\\n\\r\t中\"", JSON.toJSONString(stringVal)); + Assert.assertEquals("\"\\\\/\\b\\f\\n\\r\\t中\"", JSON.toJSONString(stringVal)); JSON.toJSONString(stringVal); } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_symbol.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_symbol.java old mode 100644 new mode 100755 similarity index 80% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_symbol.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_symbol.java index ed9131a599..cb0585a6ec --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_symbol.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_symbol.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONException; @@ -10,7 +10,7 @@ /** * test symbol * - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class JSONScannerTest_symbol extends TestCase { @@ -19,21 +19,8 @@ public void test_0() throws Exception { JSONScanner lexer = new JSONScanner("\"name\""); String symbol = lexer.scanSymbol(symbolTable, '"'); - Assert.assertTrue("name" == symbol); - - String symbol2 = lexer.symbol(symbolTable); - Assert.assertTrue("name" == symbol2); - } - - public void test_0_1() throws Exception { - SymbolTable symbolTable = new SymbolTable(); - - JSONScanner lexer = new JSONScanner("\"name\""); - lexer.scanString(); - String symbol = lexer.symbol(symbolTable); - Assert.assertTrue("name" == symbol); - - Assert.assertTrue("name" != lexer.symbol(null)); + Assert.assertTrue("name".equals(symbol)); + lexer.close(); } public void test_1() throws Exception { @@ -41,7 +28,8 @@ public void test_1() throws Exception { JSONScanner lexer = new JSONScanner("\"nick name\""); String symbol = lexer.scanSymbol(symbolTable, '"'); - Assert.assertTrue("nick name" == symbol); + Assert.assertTrue("nick name".equals(symbol)); + lexer.close(); } public void test_2() throws Exception { @@ -50,17 +38,7 @@ public void test_2() throws Exception { JSONScanner lexer = new JSONScanner("\"nick \\\"name\""); String symbol = lexer.scanSymbol(symbolTable, '"'); Assert.assertTrue("nick \"name" == symbol); - } - - public void test_2_1() throws Exception { - SymbolTable symbolTable = new SymbolTable(); - - JSONScanner lexer = new JSONScanner("\"nick \\\"name\""); - lexer.scanString(); - String symbol = lexer.symbol(symbolTable); - Assert.assertTrue("nick \"name" == symbol); - - Assert.assertTrue("nick \"name" != lexer.symbol(null)); + lexer.close(); } public void test_3() throws Exception { @@ -69,6 +47,7 @@ public void test_3() throws Exception { JSONScanner lexer = new JSONScanner("\"nick \\\\name\""); String symbol = lexer.scanSymbol(symbolTable, '"'); Assert.assertTrue("nick \\name" == symbol); + lexer.close(); } public void test_4() throws Exception { @@ -77,6 +56,7 @@ public void test_4() throws Exception { JSONScanner lexer = new JSONScanner("\"nick \\/name\""); String symbol = lexer.scanSymbol(symbolTable, '"'); Assert.assertTrue("nick /name" == symbol); + lexer.close(); } public void test_5() throws Exception { @@ -85,6 +65,7 @@ public void test_5() throws Exception { JSONScanner lexer = new JSONScanner("\"nick \\bname\""); String symbol = lexer.scanSymbol(symbolTable, '"'); Assert.assertTrue("nick \bname" == symbol); + lexer.close(); } public void test_6() throws Exception { @@ -93,6 +74,7 @@ public void test_6() throws Exception { JSONScanner lexer = new JSONScanner("\"nick \\f name\""); String symbol = lexer.scanSymbol(symbolTable, '"'); Assert.assertTrue("nick \f name" == symbol); + lexer.close(); } public void test_7() throws Exception { @@ -101,6 +83,7 @@ public void test_7() throws Exception { JSONScanner lexer = new JSONScanner("\"nick \\F name\""); String symbol = lexer.scanSymbol(symbolTable, '"'); Assert.assertTrue("nick \f name" == symbol); + lexer.close(); } public void test_8() throws Exception { @@ -109,6 +92,7 @@ public void test_8() throws Exception { JSONScanner lexer = new JSONScanner("\"nick \\n name\""); String symbol = lexer.scanSymbol(symbolTable, '"'); Assert.assertTrue("nick \n name" == symbol); + lexer.close(); } public void test_9() throws Exception { @@ -117,6 +101,7 @@ public void test_9() throws Exception { JSONScanner lexer = new JSONScanner("\"nick \\r name\""); String symbol = lexer.scanSymbol(symbolTable, '"'); Assert.assertTrue("nick \r name" == symbol); + lexer.close(); } public void test_10() throws Exception { @@ -125,6 +110,7 @@ public void test_10() throws Exception { JSONScanner lexer = new JSONScanner("\"nick \\t name\""); String symbol = lexer.scanSymbol(symbolTable, '"'); Assert.assertTrue("nick \t name" == symbol); + lexer.close(); } public void test_11() throws Exception { @@ -133,6 +119,7 @@ public void test_11() throws Exception { JSONScanner lexer = new JSONScanner("\"nick \\u4e2d name\""); String symbol = lexer.scanSymbol(symbolTable, '"'); Assert.assertTrue("nick 中 name" == symbol); + lexer.close(); } public void test_12() throws Exception { @@ -142,6 +129,7 @@ public void test_12() throws Exception { "\"\\tabcdefghijklmnopqrstuvwxyz01234567890abcdefghijklmnopqrstuvwxyz01234567890abcdefghijklmnopqrstuvwxyz01234567890abcdefghijklmnopqrstuvwxyz01234567890\""); String symbol = lexer.scanSymbol(symbolTable, '"'); Assert.assertTrue("\tabcdefghijklmnopqrstuvwxyz01234567890abcdefghijklmnopqrstuvwxyz01234567890abcdefghijklmnopqrstuvwxyz01234567890abcdefghijklmnopqrstuvwxyz01234567890" == symbol); + lexer.close(); } public void test_error() throws Exception { @@ -151,6 +139,7 @@ public void test_error() throws Exception { JSONScanner lexer = new JSONScanner("\"nick \\a name\""); lexer.scanSymbol(symbolTable, '"'); + lexer.close(); } catch (JSONException e) { error = e; } @@ -164,6 +153,7 @@ public void test_error_2() throws Exception { JSONScanner lexer = new JSONScanner("\"name"); lexer.scanSymbol(symbolTable, '"'); + lexer.close(); } catch (JSONException e) { error = e; } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_true.java b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_true.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_true.java rename to src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_true.java index f5f9dce906..8a991dcdb8 --- a/src/test/java/com/alibaba/json/test/bvt/parser/JSONScannerTest_true.java +++ b/src/test/java/com/alibaba/json/bvt/parser/JSONScannerTest_true.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONException; diff --git a/src/test/java/com/alibaba/json/bvt/parser/MapResetTest.java b/src/test/java/com/alibaba/json/bvt/parser/MapResetTest.java new file mode 100755 index 0000000000..9ff14fa958 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/MapResetTest.java @@ -0,0 +1,60 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class MapResetTest extends TestCase { + + public void test_0() throws Exception { + Book book = new Book(); + +// book.setMetadata(new MetaData()); + String text = JSON.toJSONString(book); + + System.out.println(text); + + Book book2 = JSON.parseObject(text, Book.class); + System.out.println(JSON.toJSONString(book2)); + } + + public static class Book { + + private int id; + private int pageCountNum; + + private MetaData metadata; + + public int getPageCountNum() { + return pageCountNum; + } + + public void setPageCountNum(int pageCountNum) { + this.pageCountNum = pageCountNum; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public MetaData getMetadata() { + return metadata; + } + + public void setMetadata(MetaData metadata) { + this.metadata = metadata; + } + + + + + } + + public static class MetaData { + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/NullCheckTest.java b/src/test/java/com/alibaba/json/bvt/parser/NullCheckTest.java old mode 100644 new mode 100755 similarity index 81% rename from src/test/java/com/alibaba/json/test/bvt/parser/NullCheckTest.java rename to src/test/java/com/alibaba/json/bvt/parser/NullCheckTest.java index fa0b31f5b7..ce47f098ec --- a/src/test/java/com/alibaba/json/test/bvt/parser/NullCheckTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/NullCheckTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/parser/ParseContextTest.java b/src/test/java/com/alibaba/json/bvt/parser/ParseContextTest.java new file mode 100644 index 0000000000..52125bf043 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/ParseContextTest.java @@ -0,0 +1,14 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.parser.ParseContext; + + +public class ParseContextTest extends TestCase { + public void test_toString() throws Exception { + Assert.assertEquals("$", new ParseContext(null, new Object(), "id").toString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/ParseRestTest.java b/src/test/java/com/alibaba/json/bvt/parser/ParseRestTest.java new file mode 100644 index 0000000000..a419c45536 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/ParseRestTest.java @@ -0,0 +1,59 @@ +package com.alibaba.json.bvt.parser; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class ParseRestTest extends TestCase { + + public void test_parseRest_0() throws Exception { + String text = "{\"f3\":333,\"f2\":222}"; + Entity entity = JSON.parseObject(text, Entity.class); + Assert.assertEquals(0, entity.getF0()); + Assert.assertEquals(0, entity.getF1()); + Assert.assertEquals(222, entity.getF2()); + Assert.assertEquals(333, entity.getF3()); + } + + public static class Entity { + + private int f0; + private int f1; + private int f2; + private int f3; + + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + public int getF2() { + return f2; + } + + public void setF2(int f2) { + this.f2 = f2; + } + + public int getF3() { + return f3; + } + + public void setF3(int f3) { + this.f3 = f3; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/ParserSpecialCharTest.java b/src/test/java/com/alibaba/json/bvt/parser/ParserSpecialCharTest.java new file mode 100644 index 0000000000..1c76057bea --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/ParserSpecialCharTest.java @@ -0,0 +1,95 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class ParserSpecialCharTest extends TestCase { + + public void test_0() throws Exception { + Assert.assertEquals("\0", JSON.parseObject("{\"value\":\"\\0\"}", VO.class).getValue()); + } + + public void test_1() throws Exception { + Assert.assertEquals("\1", JSON.parseObject("{\"value\":\"\\1\"}", VO.class).getValue()); + } + + public void test_2() throws Exception { + Assert.assertEquals("\2", JSON.parseObject("{\"value\":\"\\2\"}", VO.class).getValue()); + } + + public void test_3() throws Exception { + Assert.assertEquals("\3", JSON.parseObject("{\"value\":\"\\3\"}", VO.class).getValue()); + } + + public void test_4() throws Exception { + Assert.assertEquals("\4", JSON.parseObject("{\"value\":\"\\4\"}", VO.class).getValue()); + } + + public void test_5() throws Exception { + Assert.assertEquals("\5", JSON.parseObject("{\"value\":\"\\5\"}", VO.class).getValue()); + } + + public void test_6() throws Exception { + Assert.assertEquals("\6", JSON.parseObject("{\"value\":\"\\6\"}", VO.class).getValue()); + } + + public void test_7() throws Exception { + Assert.assertEquals("\7", JSON.parseObject("{\"value\":\"\\7\"}", VO.class).getValue()); + } + + public void test_8() throws Exception { + Assert.assertEquals("\b", JSON.parseObject("{\"value\":\"\\b\"}", VO.class).getValue()); + } + + public void test_9() throws Exception { + Assert.assertEquals("\t", JSON.parseObject("{\"value\":\"\\t\"}", VO.class).getValue()); + } + + public void test_10() throws Exception { + Assert.assertEquals("\n", JSON.parseObject("{\"value\":\"\\n\"}", VO.class).getValue()); + } + + public void test_11() throws Exception { + Assert.assertEquals("\u000B", JSON.parseObject("{\"value\":\"\\v\"}", VO.class).getValue()); + } + + public void test_12() throws Exception { + Assert.assertEquals("\f", JSON.parseObject("{\"value\":\"\\f\"}", VO.class).getValue()); + } + + public void test_13() throws Exception { + Assert.assertEquals("\r", JSON.parseObject("{\"value\":\"\\r\"}", VO.class).getValue()); + } + + public void test_34() throws Exception { + Assert.assertEquals("\"", JSON.parseObject("{\"value\":\"\\\"\"}", VO.class).getValue()); + } + + public void test_39() throws Exception { + Assert.assertEquals("'", JSON.parseObject("{\"value\":\"\\'\"}", VO.class).getValue()); + } + + public void test_47() throws Exception { + Assert.assertEquals("/", JSON.parseObject("{\"value\":\"\\/\"}", VO.class).getValue()); + } + + public void test_92() throws Exception { + Assert.assertEquals("\\", JSON.parseObject("{\"value\":\"\\\\\"}", VO.class).getValue()); + } + public static class VO { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/ParserSpecialCharTest_map.java b/src/test/java/com/alibaba/json/bvt/parser/ParserSpecialCharTest_map.java new file mode 100644 index 0000000000..4ec6577464 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/ParserSpecialCharTest_map.java @@ -0,0 +1,82 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class ParserSpecialCharTest_map extends TestCase { + + public void test_0() throws Exception { + Assert.assertEquals("\0", JSON.parseObject("{'value':'\\0'}").getString("value")); + } + + public void test_1() throws Exception { + Assert.assertEquals("\1", JSON.parseObject("{'value':'\\1'}").getString("value")); + } + + public void test_2() throws Exception { + Assert.assertEquals("\2", JSON.parseObject("{'value':'\\2'}").getString("value")); + } + + public void test_3() throws Exception { + Assert.assertEquals("\3", JSON.parseObject("{'value':'\\3'}").getString("value")); + } + + public void test_4() throws Exception { + Assert.assertEquals("\4", JSON.parseObject("{'value':'\\4'}").getString("value")); + } + + public void test_5() throws Exception { + Assert.assertEquals("\5", JSON.parseObject("{'value':'\\5'}").getString("value")); + } + + public void test_6() throws Exception { + Assert.assertEquals("\6", JSON.parseObject("{'value':'\\6'}").getString("value")); + } + + public void test_7() throws Exception { + Assert.assertEquals("\7", JSON.parseObject("{'value':'\\7'}").getString("value")); + } + + public void test_8() throws Exception { + Assert.assertEquals("\b", JSON.parseObject("{'value':'\\b'}").getString("value")); + } + + public void test_9() throws Exception { + Assert.assertEquals("\t", JSON.parseObject("{'value':'\\t'}").getString("value")); + } + + public void test_10() throws Exception { + Assert.assertEquals("\n", JSON.parseObject("{'value':'\\n'}").getString("value")); + } + + public void test_11() throws Exception { + Assert.assertEquals("\u000B", JSON.parseObject("{'value':'\\v'}").getString("value")); + } + + public void test_12() throws Exception { + Assert.assertEquals("\f", JSON.parseObject("{'value':'\\f'}").getString("value")); + } + + public void test_13() throws Exception { + Assert.assertEquals("\r", JSON.parseObject("{'value':'\\r'}").getString("value")); + } + + public void test_34() throws Exception { + Assert.assertEquals("\"", JSON.parseObject("{'value':'\\\"'}").getString("value")); + } + + public void test_39() throws Exception { + Assert.assertEquals("'", JSON.parseObject("{'value':'\\''}").getString("value")); + } + + public void test_47() throws Exception { + Assert.assertEquals("/", JSON.parseObject("{'value':'\\/'}").getString("value")); + } + + public void test_92() throws Exception { + Assert.assertEquals("\\", JSON.parseObject("{'value':'\\\\'}").getString("value")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/ParserSpecialCharTest_map_singleQuote.java b/src/test/java/com/alibaba/json/bvt/parser/ParserSpecialCharTest_map_singleQuote.java new file mode 100644 index 0000000000..d06678555b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/ParserSpecialCharTest_map_singleQuote.java @@ -0,0 +1,82 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class ParserSpecialCharTest_map_singleQuote extends TestCase { + + public void test_0() throws Exception { + Assert.assertEquals("\0", JSON.parseObject("{\"value\":\"\\0\"}").getString("value")); + } + + public void test_1() throws Exception { + Assert.assertEquals("\1", JSON.parseObject("{\"value\":\"\\1\"}").getString("value")); + } + + public void test_2() throws Exception { + Assert.assertEquals("\2", JSON.parseObject("{\"value\":\"\\2\"}").getString("value")); + } + + public void test_3() throws Exception { + Assert.assertEquals("\3", JSON.parseObject("{\"value\":\"\\3\"}").getString("value")); + } + + public void test_4() throws Exception { + Assert.assertEquals("\4", JSON.parseObject("{\"value\":\"\\4\"}").getString("value")); + } + + public void test_5() throws Exception { + Assert.assertEquals("\5", JSON.parseObject("{\"value\":\"\\5\"}").getString("value")); + } + + public void test_6() throws Exception { + Assert.assertEquals("\6", JSON.parseObject("{\"value\":\"\\6\"}").getString("value")); + } + + public void test_7() throws Exception { + Assert.assertEquals("\7", JSON.parseObject("{\"value\":\"\\7\"}").getString("value")); + } + + public void test_8() throws Exception { + Assert.assertEquals("\b", JSON.parseObject("{\"value\":\"\\b\"}").getString("value")); + } + + public void test_9() throws Exception { + Assert.assertEquals("\t", JSON.parseObject("{\"value\":\"\\t\"}").getString("value")); + } + + public void test_10() throws Exception { + Assert.assertEquals("\n", JSON.parseObject("{\"value\":\"\\n\"}").getString("value")); + } + + public void test_11() throws Exception { + Assert.assertEquals("\u000B", JSON.parseObject("{\"value\":\"\\v\"}").getString("value")); + } + + public void test_12() throws Exception { + Assert.assertEquals("\f", JSON.parseObject("{\"value\":\"\\f\"}").getString("value")); + } + + public void test_13() throws Exception { + Assert.assertEquals("\r", JSON.parseObject("{\"value\":\"\\r\"}").getString("value")); + } + + public void test_34() throws Exception { + Assert.assertEquals("\"", JSON.parseObject("{\"value\":\"\\\"\"}").getString("value")); + } + + public void test_39() throws Exception { + Assert.assertEquals("'", JSON.parseObject("{\"value\":\"\\'\"}").getString("value")); + } + + public void test_47() throws Exception { + Assert.assertEquals("/", JSON.parseObject("{\"value\":\"\\/\"}").getString("value")); + } + + public void test_92() throws Exception { + Assert.assertEquals("\\", JSON.parseObject("{\"value\":\"\\\\\"}").getString("value")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/ProductViewTest.java b/src/test/java/com/alibaba/json/bvt/parser/ProductViewTest.java new file mode 100755 index 0000000000..ff5cb56b91 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/ProductViewTest.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.parser; + +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class ProductViewTest extends TestCase { + public void test_parse() throws Exception { + String text = "{\"code\":0,\"message\":\"Register Successfully!\",\"status\":\"OK\"}"; + Map map = JSON.parseObject(text, Map.class); + System.out.println(map.get("code").getClass()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/ReadOnlyCollectionTest.java b/src/test/java/com/alibaba/json/bvt/parser/ReadOnlyCollectionTest.java new file mode 100644 index 0000000000..cbad13506f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/ReadOnlyCollectionTest.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.parser; + +import java.util.List; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class ReadOnlyCollectionTest extends TestCase { + + public void test_readOnlyNullList() throws Exception { + String text = "{\"list\":[]}"; + Entity entity = JSON.parseObject(text, Entity.class); + Assert.assertNotNull(entity); + } + + public static class Entity { + + private List list; + + public List getList() { + return list; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/ReadOnlyMapTest.java b/src/test/java/com/alibaba/json/bvt/parser/ReadOnlyMapTest.java new file mode 100644 index 0000000000..5f051a2cc1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/ReadOnlyMapTest.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.parser; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class ReadOnlyMapTest extends TestCase { + + public void test_readOnlyNullList() throws Exception { + String text = "{\"values\":{\"a\":{}}}"; + Entity entity = JSON.parseObject(text, Entity.class); + Assert.assertNotNull(entity); + Assert.assertNotNull(entity.values.get("a")); + Assert.assertTrue(entity.values.get("a") instanceof A); + } + + public static class Entity { + + private final Map values = new HashMap(); + + public Map getValues() { + return values; + } + + } + + public static class A { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/RedundantTest.java b/src/test/java/com/alibaba/json/bvt/parser/RedundantTest.java new file mode 100644 index 0000000000..3d240d1f99 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/RedundantTest.java @@ -0,0 +1,70 @@ +package com.alibaba.json.bvt.parser; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.deserializer.ExtraProcessor; +import com.alibaba.fastjson.parser.deserializer.ExtraTypeProvider; + +public class RedundantTest extends TestCase { + + public void test_extra() throws Exception { + ExtraProcessor processor = new ExtraProcessor() { + public void processExtra(Object object, String key, Object value) { + VO vo = (VO) object; + vo.getAttributes().put(key, value); + } + }; + + VO vo = JSON.parseObject("{\"id\":123,\"name\":\"abc\"}", VO.class, processor); + Assert.assertEquals(123, vo.getId()); + Assert.assertEquals("abc", vo.getAttributes().get("name")); + } + + public void test_extraWithType() throws Exception { + class MyExtraProcessor implements ExtraProcessor, ExtraTypeProvider { + public void processExtra(Object object, String key, Object value) { + VO vo = (VO) object; + vo.getAttributes().put(key, value); + } + + public Type getExtraType(Object object, String key) { + if ("value".equals(key)) { + return int.class; + } + return null; + } + }; + ExtraProcessor processor = new MyExtraProcessor(); + + VO vo = JSON.parseObject("{\"id\":123,\"value\":\"123456\"}", VO.class, processor); + Assert.assertEquals(123, vo.getId()); + Assert.assertEquals(123456, vo.getAttributes().get("value")); + } + + + public static class VO { + + private int id; + private Map attributes = new HashMap(); + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Map getAttributes() { + return attributes; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/TestException.java b/src/test/java/com/alibaba/json/bvt/parser/TestException.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/parser/TestException.java rename to src/test/java/com/alibaba/json/bvt/parser/TestException.java index c82d945c1c..89c52354f9 --- a/src/test/java/com/alibaba/json/test/bvt/parser/TestException.java +++ b/src/test/java/com/alibaba/json/bvt/parser/TestException.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.util.List; diff --git a/src/test/java/com/alibaba/json/bvt/parser/TestInitStringFieldAsEmpty.java b/src/test/java/com/alibaba/json/bvt/parser/TestInitStringFieldAsEmpty.java new file mode 100755 index 0000000000..37bc78b430 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/TestInitStringFieldAsEmpty.java @@ -0,0 +1,50 @@ +package com.alibaba.json.bvt.parser; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; + +public class TestInitStringFieldAsEmpty extends TestCase { + + public void test_private() throws Exception { + VO1 vo1 = JSON.parseObject("{}", VO1.class, Feature.InitStringFieldAsEmpty); + Assert.assertEquals("", vo1.getValue()); + } + + public void test_public() throws Exception { + VO2 vo2 = JSON.parseObject("{}", VO2.class, Feature.InitStringFieldAsEmpty); + Assert.assertEquals("", vo2.getValue()); + } + + private static class VO1 { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + public static class VO2 { + + private String value; + + public VO2() { + + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/TestInitStringFieldAsEmpty2.java b/src/test/java/com/alibaba/json/bvt/parser/TestInitStringFieldAsEmpty2.java new file mode 100755 index 0000000000..1fa3f6843d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/TestInitStringFieldAsEmpty2.java @@ -0,0 +1,78 @@ +package com.alibaba.json.bvt.parser; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; + +public class TestInitStringFieldAsEmpty2 extends TestCase { + + public void test_public() throws Exception { + VO1 vo1 = JSON.parseObject("{\"id\":0,\"value\":33, \"o\":{}}", VO1.class, Feature.InitStringFieldAsEmpty); + Assert.assertEquals("", vo1.getName()); + Assert.assertEquals("", vo1.getO().getValue()); + } + + public static class VO1 { + + private int id; + + private String name; + + private int value; + + private VO2 o; + + public VO1(){ + + } + + public VO2 getO() { + return o; + } + + public void setO(VO2 o) { + this.o = o; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + + public static class VO2 { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/TestUTF8.java b/src/test/java/com/alibaba/json/bvt/parser/TestUTF8.java old mode 100644 new mode 100755 similarity index 97% rename from src/test/java/com/alibaba/json/test/bvt/parser/TestUTF8.java rename to src/test/java/com/alibaba/json/bvt/parser/TestUTF8.java index 24de867a31..b53725dd23 --- a/src/test/java/com/alibaba/json/test/bvt/parser/TestUTF8.java +++ b/src/test/java/com/alibaba/json/bvt/parser/TestUTF8.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/TestUTF8_2.java b/src/test/java/com/alibaba/json/bvt/parser/TestUTF8_2.java old mode 100644 new mode 100755 similarity index 97% rename from src/test/java/com/alibaba/json/test/bvt/parser/TestUTF8_2.java rename to src/test/java/com/alibaba/json/bvt/parser/TestUTF8_2.java index 67a4d17a7d..7dd46fa513 --- a/src/test/java/com/alibaba/json/test/bvt/parser/TestUTF8_2.java +++ b/src/test/java/com/alibaba/json/bvt/parser/TestUTF8_2.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/TestUTF8_3.java b/src/test/java/com/alibaba/json/bvt/parser/TestUTF8_3.java old mode 100644 new mode 100755 similarity index 98% rename from src/test/java/com/alibaba/json/test/bvt/parser/TestUTF8_3.java rename to src/test/java/com/alibaba/json/bvt/parser/TestUTF8_3.java index 099785a2ab..8dd263ee43 --- a/src/test/java/com/alibaba/json/test/bvt/parser/TestUTF8_3.java +++ b/src/test/java/com/alibaba/json/bvt/parser/TestUTF8_3.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.nio.ByteBuffer; import java.nio.CharBuffer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.util.IOUtils; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/TestUTF8_4.java b/src/test/java/com/alibaba/json/bvt/parser/TestUTF8_4.java old mode 100644 new mode 100755 similarity index 98% rename from src/test/java/com/alibaba/json/test/bvt/parser/TestUTF8_4.java rename to src/test/java/com/alibaba/json/bvt/parser/TestUTF8_4.java index 756c394911..c567d76622 --- a/src/test/java/com/alibaba/json/test/bvt/parser/TestUTF8_4.java +++ b/src/test/java/com/alibaba/json/bvt/parser/TestUTF8_4.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.nio.ByteBuffer; import java.nio.CharBuffer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.util.IOUtils; diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeReferenceTest.java b/src/test/java/com/alibaba/json/bvt/parser/TypeReferenceTest.java new file mode 100755 index 0000000000..26333e089e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeReferenceTest.java @@ -0,0 +1,17 @@ +package com.alibaba.json.bvt.parser; + +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class TypeReferenceTest extends TestCase { + + public void test_list() throws Exception { + List list = JSON.parseObject("[1,2,3]", new TypeReference>() {}); + Assert.assertEquals(1L, ((Long) list.get(0)).longValue()); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/TypeUtilsTest.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/parser/TypeUtilsTest.java rename to src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest.java index c82904dc73..505a072d86 --- a/src/test/java/com/alibaba/json/test/bvt/parser/TypeUtilsTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.lang.reflect.Method; import java.math.BigDecimal; @@ -242,17 +242,17 @@ public void test_cast_to_Timestamp_null() throws Exception { public void test_cast_to_Timestamp_null2() throws Exception { Assert.assertEquals(null, TypeUtils.castToTimestamp(null)); } - + public void test_cast_to_BigDecimal_same() throws Exception { BigDecimal value = new BigDecimal("123"); Assert.assertEquals(true, value == TypeUtils.castToBigDecimal(value)); } - + public void test_cast_to_BigInteger_same() throws Exception { BigInteger value = new BigInteger("123"); Assert.assertEquals(true, value == TypeUtils.castToBigInteger(value)); } - + public void test_cast_Array() throws Exception { Assert.assertEquals(Integer[].class, TypeUtils.cast(new ArrayList(), Integer[].class, null).getClass()); } @@ -354,13 +354,7 @@ public void test_error_2() throws Exception { Method method = TypeUtilsTest.class.getMethod("f", List.class); - JSONException error = null; - try { - TypeUtils.cast(json, method.getGenericParameterTypes()[0], ParserConfig.getGlobalInstance()); - } catch (JSONException e) { - error = e; - } - Assert.assertNotNull(error); + TypeUtils.cast(json, method.getGenericParameterTypes()[0], ParserConfig.getGlobalInstance()); } public void test_3() throws Exception { diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/TypeUtilsTest2.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest2.java old mode 100644 new mode 100755 similarity index 98% rename from src/test/java/com/alibaba/json/test/bvt/parser/TypeUtilsTest2.java rename to src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest2.java index 3047f10429..7e70b3f900 --- a/src/test/java/com/alibaba/json/test/bvt/parser/TypeUtilsTest2.java +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest2.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.lang.reflect.ParameterizedType; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONException; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/TypeUtilsTest3.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest3.java old mode 100644 new mode 100755 similarity index 97% rename from src/test/java/com/alibaba/json/test/bvt/parser/TypeUtilsTest3.java rename to src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest3.java index a9499fb01b..4caf7e88dc --- a/src/test/java/com/alibaba/json/test/bvt/parser/TypeUtilsTest3.java +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest3.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/TypeUtilsTest4.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest4.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/parser/TypeUtilsTest4.java rename to src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest4.java index 573f5a905e..6985b4a9c4 --- a/src/test/java/com/alibaba/json/test/bvt/parser/TypeUtilsTest4.java +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest4.java @@ -1,17 +1,19 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.util.TypeUtils; +@SuppressWarnings("unchecked") public class TypeUtilsTest4 extends TestCase { public void test_array() throws Exception { diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_cast.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_cast.java new file mode 100644 index 0000000000..3f6d02533d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_cast.java @@ -0,0 +1,99 @@ +package com.alibaba.json.bvt.parser; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Calendar; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.util.TypeUtils; + +public class TypeUtilsTest_cast extends TestCase { + + public void test_cast_0() throws Exception { + Assert.assertArrayEquals(new byte[0], TypeUtils.cast(new byte[0], byte[].class, null)); + } + + public void test_cast_1() throws Exception { + ParameterizedType parameterizedType = (ParameterizedType) new TypeReference>() {}.getType(); + Type type = parameterizedType.getActualTypeArguments()[0]; + Assert.assertEquals(null, TypeUtils.cast("", type, null)); + } + + public void test_castToDate_error() throws Exception { + Exception error = null; + try { + TypeUtils.cast(0, MyCalendar.class, null); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_castToDate_error_nullClass() throws Exception { + Exception error = null; + try { + TypeUtils.cast(0, (Class) null, null); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + @SuppressWarnings("serial") + private class MyCalendar extends Calendar { + + @Override + protected void computeTime() { + // TODO Auto-generated method stub + + } + + @Override + protected void computeFields() { + // TODO Auto-generated method stub + + } + + @Override + public void add(int field, int amount) { + // TODO Auto-generated method stub + + } + + @Override + public void roll(int field, boolean up) { + // TODO Auto-generated method stub + + } + + @Override + public int getMinimum(int field) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getMaximum(int field) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getGreatestMinimum(int field) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getLeastMaximum(int field) { + // TODO Auto-generated method stub + return 0; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToBytes.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToBytes.java new file mode 100644 index 0000000000..e70714ddc8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToBytes.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.util.TypeUtils; + +public class TypeUtilsTest_castToBytes extends TestCase { + + public void test_castToDate() throws Exception { + Assert.assertArrayEquals(new byte[0], TypeUtils.castToBytes(new byte[0])); + } + + public void test_castToDate_error() throws Exception { + Exception error = null; + try { + TypeUtils.castToBytes(new int[0]); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToDate.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToDate.java new file mode 100644 index 0000000000..21aba385f4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToDate.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.parser; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.util.TypeUtils; + +public class TypeUtilsTest_castToDate extends TestCase { + + public void test_castToDate() throws Exception { + JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; + Date date = TypeUtils.castToDate("2012-07-15 12:12:11"); + Assert.assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parseObject("2012-07-15 12:12:11"), date); + JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; + } + + public void test_castToDate_error() throws Exception { + Exception error = null; + try { + TypeUtils.castToDate("你妈你妈-MM-dd"); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_castToDate_zero() throws Exception { + Assert.assertEquals(new Date(0), TypeUtils.castToDate("0")); + } + + public void test_castToDate_negative() throws Exception { + Assert.assertEquals(new Date(-1), TypeUtils.castToDate(-1)); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToJavaBean.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToJavaBean.java new file mode 100644 index 0000000000..29e92888f4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToJavaBean.java @@ -0,0 +1,234 @@ +package com.alibaba.json.bvt.parser; + +import java.net.URL; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.JavaBeanSerializer; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.util.TypeUtils; + +public class TypeUtilsTest_castToJavaBean extends TestCase { + + public void test_castToJavaBean_StackTraceElement() throws Exception { + Map map = new HashMap(); + map.put("className", "java.lang.Object"); + map.put("methodName", "hashCode"); + StackTraceElement element = TypeUtils.castToJavaBean(map, StackTraceElement.class, null); + Assert.assertEquals("java.lang.Object", element.getClassName()); + Assert.assertEquals("hashCode", element.getMethodName()); + Assert.assertEquals(null, element.getFileName()); + } + + public void test_castToJavaBean_StackTraceElement_1() throws Exception { + Map map = new HashMap(); + map.put("className", "java.lang.Object"); + map.put("methodName", "hashCode"); + map.put("lineNumber", 12); + StackTraceElement element = TypeUtils.castToJavaBean(map, StackTraceElement.class, null); + Assert.assertEquals("java.lang.Object", element.getClassName()); + Assert.assertEquals("hashCode", element.getMethodName()); + Assert.assertEquals(null, element.getFileName()); + Assert.assertEquals(12, element.getLineNumber()); + } + + public void test_castToJavaBean_type() throws Exception { + Map map = new HashMap(); + map.put("@type", "java.lang.StackTraceElement"); + map.put("className", "java.lang.Object"); + map.put("methodName", "hashCode"); + map.put("lineNumber", 12); + StackTraceElement element = (StackTraceElement) TypeUtils.castToJavaBean(map, Object.class, null); + Assert.assertEquals("java.lang.Object", element.getClassName()); + Assert.assertEquals("hashCode", element.getMethodName()); + Assert.assertEquals(null, element.getFileName()); + Assert.assertEquals(12, element.getLineNumber()); + } + + public void test_error() throws Exception { + Map map = new HashMap(); + map.put("@type", "xxx"); + Exception error = null; + try { + TypeUtils.castToJavaBean(map, Object.class, null); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error2() throws Exception { + Map map = new HashMap(); + map.put("@type", ""); + Exception error = null; + try { + TypeUtils.castToJavaBean(map, Object.class, null); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_mapping() throws Exception { + TypeUtils.addClassMapping("my_xxx", VO.class); + TypeUtils.addClassMapping(null, VO.class); + Map map = new HashMap(); + map.put("@type", "my_xxx"); + map.put("id", 123); + VO vo = (VO) TypeUtils.castToJavaBean(map, Object.class); + Assert.assertEquals(123, vo.getId()); + TypeUtils.clearClassMapping(); + } + + public void test_interface() throws Exception { + Map map = new HashMap(); + map.put("id", 123); + VO vo = TypeUtils.castToJavaBean(map, VO.class); + Assert.assertEquals(123, vo.getId()); + } + + public void test_bean() throws Exception { + Map map = new HashMap(); + map.put("id", 123); + Entity vo = TypeUtils.castToJavaBean(map, Entity.class); + Assert.assertEquals(123, vo.getId()); + + Assert.assertEquals("{\"id\":123}", JSON.toJSONString(vo)); + } + + public void test_loadClass() throws Exception { + Assert.assertNull(TypeUtils.loadClass(null)); + Assert.assertNull(TypeUtils.loadClass("")); + } + + public void test_loadClass_1() throws Exception { + TypeUtils.clearClassMapping(); + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(new TestLoader()); + try { + Assert.assertEquals(VO.class, + TypeUtils.loadClass("com.alibaba.json.bvt.parser.TypeUtilsTest_castToJavaBean$VO")); + } finally { + Thread.currentThread().setContextClassLoader(contextClassLoader); + } + } + + public void test_loadClass_2() throws Exception { + TypeUtils.clearClassMapping(); + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(new TestLoader()); + try { + Assert.assertNull(TypeUtils.loadClass("xxx_xx")); + } finally { + Thread.currentThread().setContextClassLoader(contextClassLoader); + } + } + + public void test_bean_2() throws Exception { + Map map = new HashMap(); + map.put("id", 123); + PO vo = TypeUtils.castToJavaBean(map, PO.class); + Assert.assertEquals(123, vo.id); + + SerializeWriter out = new SerializeWriter(); + + try { + SerializeConfig config = new SerializeConfig(); + JSONSerializer serializer = new JSONSerializer(out, config); + config.put(PO.class, new JavaBeanSerializer(PO.class, Collections.singletonMap("id", "ID"))); + + serializer.write(vo); + + Assert.assertEquals("{\"ID\":123}", out.toString()); + } finally { + out.close(); + } + + + } + + public void test_bean_3() throws Exception { + Map map = new HashMap(); + map.put("id", 123); + PO vo = TypeUtils.castToJavaBean(map, PO.class); + Assert.assertEquals(123, vo.id); + + SerializeWriter out = new SerializeWriter(); + + try { + SerializeConfig config = new SerializeConfig(); + JSONSerializer serializer = new JSONSerializer(out, config); + config.put(PO.class, new JavaBeanSerializer(PO.class, Collections.singletonMap("id", (String) null))); + + serializer.write(vo); + + Assert.assertEquals("{}", out.toString()); + } finally { + out.close(); + } + + + } + + public static interface VO { + + void setId(int value); + + int getId(); + + ClassLoader getClassLoader(); + } + + public static class Entity { + + private int id; + protected String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + protected String getName() { + return name; + } + + protected void setName(String name) { + this.name = name; + } + + public ClassLoader getClassLoader() { + return Entity.class.getClassLoader(); + } + } + + private static class PO { + public int id; + } + + public static class TestLoader extends ClassLoader { + + public TestLoader(){ + super(null); + } + + public URL getResource(String name) { + return null; + } + + public Class loadClass(String name) throws ClassNotFoundException { + throw new ClassNotFoundException(); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToJavaBean_JSONType.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToJavaBean_JSONType.java new file mode 100644 index 0000000000..d402704b7f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_castToJavaBean_JSONType.java @@ -0,0 +1,120 @@ +package com.alibaba.json.bvt.parser; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.util.TypeUtils; + +public class TypeUtilsTest_castToJavaBean_JSONType extends TestCase { + + public void test_castToJavaBean() throws Exception { + Map map = new HashMap(); + map.put("id", 123); + map.put("name", "abc"); + VO vo = TypeUtils.castToJavaBean(map, VO.class, null); + Assert.assertEquals(123, vo.getId()); + Assert.assertEquals("abc", vo.getName()); + + Assert.assertEquals("{\"name\":\"abc\",\"id\":123}", JSON.toJSONString(vo)); + } + + public void test_castToJavaBean_v2() throws Exception { + Map map = new HashMap(); + map.put("id", 123); + map.put("name", "abc"); + V2 vo = TypeUtils.castToJavaBean(map, V2.class, null); + Assert.assertEquals(123, vo.getId()); + Assert.assertEquals("abc", vo.getName()); + + Assert.assertEquals("{\"id\":123,\"name\":\"abc\"}", JSON.toJSONString(vo)); + } + + public void test_castToJavaBean_v3() throws Exception { + Map map = new HashMap(); + map.put("id", 123); + map.put("name", "abc"); + V3 vo = TypeUtils.castToJavaBean(map, V3.class, null); + Assert.assertEquals(123, vo.getId()); + Assert.assertEquals("abc", vo.getName()); + + Assert.assertEquals("{\"id\":123,\"name\":\"abc\"}", JSON.toJSONString(vo)); + } + + @JSONType(orders={"name", "id"}) + public static class VO { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + + @JSONType(orders={"name"}) + public static class V2 { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + + @JSONType(orders={"name","xx"}) + public static class V3 { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_compatibleWithJavaBean.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_compatibleWithJavaBean.java new file mode 100644 index 0000000000..9c37048e9b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_compatibleWithJavaBean.java @@ -0,0 +1,50 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.util.TypeUtils; + +public class TypeUtilsTest_compatibleWithJavaBean extends TestCase { + + private boolean origin_compatibleWithJavaBean; + + protected void setUp() throws Exception { + origin_compatibleWithJavaBean = TypeUtils.compatibleWithJavaBean; + TypeUtils.compatibleWithJavaBean = true; + } + + protected void tearDown() throws Exception { + TypeUtils.compatibleWithJavaBean = origin_compatibleWithJavaBean; + } + + public void test_true() throws Exception { + String text = JSON.toJSONString(new VO(123)); + Assert.assertEquals("{\"ID\":123}", text); + Assert.assertEquals(123, JSON.parseObject(text, VO.class).getID()); + } + + public static class VO { + + private int id; + + public VO(){ + + } + + public VO(int id){ + this.id = id; + } + + public int getID() { + return id; + } + + public void setID(int id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_compatibleWithJavaBean_boolean.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_compatibleWithJavaBean_boolean.java new file mode 100644 index 0000000000..43f822f61f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_compatibleWithJavaBean_boolean.java @@ -0,0 +1,50 @@ +package com.alibaba.json.bvt.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.util.TypeUtils; + +public class TypeUtilsTest_compatibleWithJavaBean_boolean extends TestCase { + + private boolean origin_compatibleWithJavaBean; + + protected void setUp() throws Exception { + origin_compatibleWithJavaBean = TypeUtils.compatibleWithJavaBean; + TypeUtils.compatibleWithJavaBean = true; + } + + protected void tearDown() throws Exception { + TypeUtils.compatibleWithJavaBean = origin_compatibleWithJavaBean; + } + + public void test_true() throws Exception { + String text = JSON.toJSONString(new VO(true)); + Assert.assertEquals("{\"ID\":true}", text); + Assert.assertEquals(true, JSON.parseObject(text, VO.class).isID()); + } + + public static class VO { + + private boolean id; + + public VO(){ + + } + + public VO(boolean id){ + this.id = id; + } + + public boolean isID() { + return id; + } + + public void setID(boolean id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_interface.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_interface.java new file mode 100644 index 0000000000..1cd9959052 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsTest_interface.java @@ -0,0 +1,136 @@ +package com.alibaba.json.bvt.parser; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.annotation.JSONField; + +public class TypeUtilsTest_interface extends TestCase { + + public void test_castToJavaBean() throws Exception { + VO vo = new VO(); + vo.setId(123); + vo.setName("abc"); + + Assert.assertEquals("{\"ID\":123,\"name\":\"abc\"}", JSON.toJSONString(vo)); + } + + public void test_parse() throws Exception { + VO vo = JSON.parseObject("{\"xid\":123,\"name\":\"abc\"}", VO.class); + + Assert.assertEquals(123, vo.getId()); + Assert.assertEquals("abc", vo.getName()); + } + + public void test_parse_var() throws Exception { + List list = JSON.parseObject("[]", new TypeReference>() { + }); + Assert.assertNotNull(list); + Assert.assertEquals(0, list.size()); + } + + public void test_deser() throws Exception { + JSON.parseObject("{\"id\":123}", new TypeReference(){}); + } + + public void test_deser2() throws Exception { + JSON.parseObject("{\"id\":123}", new TypeReference>(){}); + } + + public void test_deser2_x() throws Exception { + JSON.parseObject("{\"id\":123}", new TypeReference>(){}); + } + + public static class X_I extends X { + + } + + public static class X_X extends X { + + } + + public static class X { + + private T id; + + public X(){ + } + + public T getId() { + return id; + } + + public void setId(T id) { + this.id = id; + } + + } + + public static class VO implements IV { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getName(String xx) { + return null; + } + + public String getName(String xx, int v) { + // TODO Auto-generated method stub + return null; + } + + @JSONField(deserialize = false) + public void setName(int value) { + // TODO Auto-generated method stub + + } + + public void setName(int value, int x) { + // TODO Auto-generated method stub + + } + + } + + public static interface IV { + + @JSONField(name = "ID") + int getId(); + + @JSONField(name = "xid") + void setId(int value); + + @JSONField(name = "NAME") + String getName(String xx); + + @JSONField(name = "NAME") + String getName(String xx, int v); + + @JSONField(name = "xid_1") + void setName(int value); + } + +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/TypeUtilsToJSONTest.java b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsToJSONTest.java old mode 100644 new mode 100755 similarity index 90% rename from src/test/java/com/alibaba/json/test/bvt/parser/TypeUtilsToJSONTest.java rename to src/test/java/com/alibaba/json/bvt/parser/TypeUtilsToJSONTest.java index 6dd1ce6c71..da3f22f787 --- a/src/test/java/com/alibaba/json/test/bvt/parser/TypeUtilsToJSONTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/TypeUtilsToJSONTest.java @@ -1,10 +1,10 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/UTF8ByteArrayLexerTest_symbol.java b/src/test/java/com/alibaba/json/bvt/parser/UTF8ByteArrayLexerTest_symbol.java old mode 100644 new mode 100755 similarity index 90% rename from src/test/java/com/alibaba/json/test/bvt/parser/UTF8ByteArrayLexerTest_symbol.java rename to src/test/java/com/alibaba/json/bvt/parser/UTF8ByteArrayLexerTest_symbol.java index 5db9cd288f..bc739d568a --- a/src/test/java/com/alibaba/json/test/bvt/parser/UTF8ByteArrayLexerTest_symbol.java +++ b/src/test/java/com/alibaba/json/bvt/parser/UTF8ByteArrayLexerTest_symbol.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/UTF8ByteArrayParseTest.java b/src/test/java/com/alibaba/json/bvt/parser/UTF8ByteArrayParseTest.java old mode 100644 new mode 100755 similarity index 89% rename from src/test/java/com/alibaba/json/test/bvt/parser/UTF8ByteArrayParseTest.java rename to src/test/java/com/alibaba/json/bvt/parser/UTF8ByteArrayParseTest.java index be6be0ea1f..69867e4e56 --- a/src/test/java/com/alibaba/json/test/bvt/parser/UTF8ByteArrayParseTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/UTF8ByteArrayParseTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.parser; +package com.alibaba.json.bvt.parser; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/bug/Bug0.java b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug0.java old mode 100644 new mode 100755 similarity index 54% rename from src/test/java/com/alibaba/json/test/bvt/parser/bug/Bug0.java rename to src/test/java/com/alibaba/json/bvt/parser/bug/Bug0.java index 35f14e9c5f..7e64b1b477 --- a/src/test/java/com/alibaba/json/test/bvt/parser/bug/Bug0.java +++ b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug0.java @@ -1,10 +1,11 @@ -package com.alibaba.json.test.bvt.parser.bug; +package com.alibaba.json.bvt.parser.bug; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; public class Bug0 extends TestCase { @@ -16,10 +17,14 @@ public void test_0() throws Exception { Assert.assertEquals(2, json.getIntValue("b")); } - public void test_array() throws Exception { + public void test_array_exception() throws Exception { String text = "[1, 2]}"; - JSONArray json = JSON.parseObject(text, JSONArray.class); - Assert.assertEquals(1, json.getIntValue(0)); - Assert.assertEquals(2, json.getIntValue(1)); + Exception error = null; + try { + JSON.parseObject(text, JSONArray.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); } } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/bug/Bug2.java b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug2.java old mode 100644 new mode 100755 similarity index 90% rename from src/test/java/com/alibaba/json/test/bvt/parser/bug/Bug2.java rename to src/test/java/com/alibaba/json/bvt/parser/bug/Bug2.java index a296ad9c2d..18126b3f6f --- a/src/test/java/com/alibaba/json/test/bvt/parser/bug/Bug2.java +++ b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug2.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.parser.bug; +package com.alibaba.json.bvt.parser.bug; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_lixianfeng.java b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_lixianfeng.java new file mode 100755 index 0000000000..7d01cfe995 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_lixianfeng.java @@ -0,0 +1,54 @@ +package com.alibaba.json.bvt.parser.bug; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + +/** + * 这个bug由李先锋反馈 + * @author wenshao + * + */ +public class Bug_for_lixianfeng extends TestCase { + + public void test_long_list() throws Exception { + String str = "{\"id\":14281,\"name\":\"test\",\"canPurchase\":1,\"categoryId\":955063}"; + + JSON.parseObject(str, Te.class); + } + + public static class Te { + + private Long id; + private String name; + private List catIds; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getCatIds() { + return catIds; + } + + public void setCatIds(List catIds) { + this.catIds = catIds; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_yihaodian.java b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_yihaodian.java new file mode 100755 index 0000000000..8e2f8ee8ec --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/bug/Bug_for_yihaodian.java @@ -0,0 +1,3032 @@ +package com.alibaba.json.bvt.parser.bug; + +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class Bug_for_yihaodian extends TestCase { + + public void test_for_long_list() throws Exception { + String str = "{\"backOperatorId\":14281,\"batchNum\":0,\"canPurchase\":1,\"categoryId\":955063}"; + Te ob = JSON.parseObject(str, Te.class); + } + + public static class Te { + + /** 产品ID */ + private Long id; + /** 要删除产品的ID */ + private String deletedProductId; + /** 产品编码 */ + private String productCode; + /** 产品名 */ + private String productCname; + /** 产品名前面的品牌名 */ + private String productBrandName; + /** 产品名英文 */ + private String productEname; + /** 产品销售类别 */ + private Integer productSaleType; + /** 产品品牌Id */ + private Long brandId; + /** 产品品牌 */ + private String brandName; + + /** 市场价 */ + private Double productListPrice; + /** 分类Id */ + private Long categoryId; + /** 旧分类Id */ + private Long oldCategoryId; + /** 旧扩展类别 **/ + private Long oldExtendCategoryId; + /** 厂商ID,默认为1 */ + private Long mfid; + /** productCanBeChange */ + private Integer productCanBeChange; + /** productChangeDay */ + private Integer productChangeDay; + /** productCanBeReturn */ + private Integer productCanBeReturn; + /** productReturnDay */ + private Integer productReturnDay; + /** 能否维修 */ + private Integer productCanBeRepair; + /** 能否维修 */ + private Integer productCanBeRepairDay; + /** 安装信息 */ + private Integer productNeedInstallation; + /** 条形码 */ + private String ean13; + /** sku */ + private String sku; + /** 长 */ + private Double length; + /** 宽 */ + private Double width; + /** 高 */ + private Double height; + /** 净重 */ + private Double weight; + /** keepTemperature */ + private String keepTemperature; + /** keepHumidity */ + private String keepHumidity; + /** 产品简称 */ + private String productSname; + /** keepSpecCondition */ + private String keepSpecCondition; + /** productQualityAssuranceDay */ + private Integer productQualityAssuranceDay; + /** 是否已删除 */ + private Integer isDeleted; + /** 单位 */ + private String unit; + /** 进价 */ + private Double inPrice; + /** volume */ + private Double volume; + /** countryOfOrgn */ + private Long countryOfOrgn; + /** 主图ID */ + private Long defaultPictureId; + /** 主图URL */ + private String defaultPictureUrl; + /** color */ + private String color; + /** currencyId */ + private Long currencyId; + /** 毛重 */ + private Double grossWeight; + /** format */ + private String format; + /** 易碎品 0 不是 1是 */ + private String isFragile; + /** 向上0 不是 1是 */ + private String putOnDirection; + /** 贵重品0 不是 1是 */ + private String isValuables; + /** 液体0 不是 1是 */ + private String isLiquid; + /** 防交叉污染0 不是 1是 */ + private String isCrossContamination; + /** 16进制的颜色代码,如#FF00AA */ + private String colorNumber; + /** 尺码 */ + private String productSize; + /** 替换后的尺码 */ + private String replaceProductSize; + /** 销售技巧 */ + private String saleSkill; + /** 本商品作为赠品时的处理方法 */ + private String dispositionInstruct; + /** 产地 */ + private String placeOfOrigin; + /** 产品页面标题 */ + private String productSeoTitle; + /** 产品页面属性关键字 */ + private String productSeoKeyword; + /** 产品页面属性描述 */ + private String productSeoDescription; + /** 后台产品配件说明 */ + private String accessoryDescription; + /** 是否需要单独开票 */ + private Integer needInvoice; + /** 清仓原因 */ + private String clearCause; + /** 默认商品条码ID */ + private Long defaultBarcodeId; + /** 广告词 */ + private String adWord; + /** 是否是3c产品(0:非3C,1:3C产品) */ + private Integer isCcc; + /** N件购 */ + private Integer shoppingCount; + /** 是否为赠品 */ + private Integer productIsGift; + /** 是否可以退换货 0:不可以 1:可以 */ + private Integer canReturnAndChange; + /** 是否需要检测 0:不需要 1:需要 */ + private Integer needExamine; + /** 1:新增未审核;2:编辑待审核;3:审核未通过;4:审核通过;5:文描审核失败;6:图片审核失败 */ + private Integer verifyFlg; + /** 审核者 */ + private Long verifyBy; + /** 审核日时 */ + + /** 商品登记者 */ + private Long registerBy; + /** 商品登记日时 */ + + /** 商品登记者联系电话 */ + private String registerPhone; + /** 审核备注 */ + private String verifyRemark; + /** 批量数 */ + private Integer batchNum; + /** 是否只限本地配送0: 不限制 1:限制 (粉状/液体/膏状) */ + private Integer localLimit; + /** 一包的数量 */ + private Integer stdPackQty; + /** 正式表产品ID */ + private Long fromalProductId; + /** 是否强制发票 */ + private Integer isMustInvoice; + /** 审核失败原因 */ + private Integer verifyFailureType; + /** 产品类型 0:普通产品 1:主系列产品 2:子系列产品 3:捆绑产品 4:礼品卡 5: 虚拟商品 6:增值服务 */ + private Integer productType; + /** 是否能被采购 */ + private Integer canPurchase; + /** 标准包装箱sku */ + private String stdPackageSku; + /** 是否需要启用保质期控制 0:不启用 1:启用 */ + private Integer userExpireControl; + /** 批次规则ID */ + private Long batchRuleId; + /** 产品名称副标题 */ + private String nameSubtitle; + private String specialType; + /** 给经销商的批发价 */ + private Double batchPrice; + /** 是否需要批次控制 0:不需要 1:需要 */ + private Integer needBatchControl; + /** 销售税率 */ + private Double salesTax; + /** 外部产品编码 */ + private String outerId; + /** 商家ID */ + private Long merchantId; + /** 商家名称 */ + private String merchantName; + /** 商家产品主类别(用于报表统计) */ + private Long masterCategoryId; + + private Integer concernLevel; + /** 关注理由 */ + private String concernReason; + /** 是否可售 */ + private Integer canSale; + /** 是否显示 */ + private Integer canShow; + /** 产品销售税率 */ + private Long prodcutTaxRate; + /** 是否支持VIP0:不支持1:支持 */ + private Integer canVipDiscount; + /** 分类名称 */ + private String categoryName; + /** 销售价格 */ + private Double salePrice; + /** 库存 */ + private Long stockNum; + /** 商家类别名称 */ + private String merchantCategoryName; + /** 商家详情 */ + private String productDescription; + /** 是否可调拨 0:不可以 1:可以 */ + private Integer isTransfer; + /** 是否需要审核0:新增未提交;1:需要审核;2:编辑未提交 */ + private Integer isSubmit; + /** 审核失败类型 */ + private Integer verifyFailueType; + /** 产品拼音 */ + private String productSpell; + /** 产品名称前缀 */ + private String productNamePrefix; + /** 审核失败原因 */ + private String failueReason; + /** orgPicUrl */ + private String orgPicUrl; + /** 扩展分类名称 */ + private String subCategoryName; + /** 扩展分类ID */ + private Long subCategoryId; + /** 7天内日均销量 */ + private Integer dailySale; + /** 查看是否有主图 */ + private Integer picCount; + /** 强制下架原因 */ + private Integer underCarriageReason; + /** 强制下架原因-中文信息 */ + private String underCarriageReasonStr; + /** 异常信息 */ + private String errorMessage; + /** 库存预警数量 */ + private Integer alertStockCount; + + private String deliveryInfo; + /** 主图链接 */ + private String picUrl; + + /** 是否能分期0:不能 1:能 */ + private Integer canFenqi; + + private String season; + /** 是否是二次审核 */ + private Integer isDupAudit; + + private Integer viewFromTag; + + /** 产品售价 */ + private Double productNonMemberPrice; + /** 产品图片 */ + + /** 是否更新操作 */ + private Integer isUpdate; + /** merchantRpcVo */ + + /** 系列产品的颜色图片 */ + + /** 系列产品的尺码 */ + private List productSizeSet; + + /** 是否主产品 */ + private Boolean isMainProduct; + /** 从图片空间中返回图片ID和URL */ + private String productPicIdAndURL; + + private Integer isTemp; + /** 市场价和售价的比例 */ + private Double priceRate; + + private Integer picSpecialType; + private Integer exemptStatus; + + private String violationReasonIds; + + private String violationReasons; + + private Long remainTime; + + private Integer submitOrder; + + private Integer productSource; + + private Integer isKa; + /** KA商家创建时间 */ + private Integer kaMCreateTime; + /** 配送延长期 */ + private Integer deliveryDay; + /** 产品状态 */ + private Integer isEdit; + /** 操作人 */ + private Long backOperatorId; + /** 正式库pm_info_id */ + private Long formalPmInfoId; + /** 类别拼接字符串 */ + private String categoryStr; + /** 类别id拼接字符串 */ + private String categoryIdStr; + /** 扩展类别拼接字符串 */ + private String extendCategoryStr; + /** 扩展类别id拼接字符串 */ + private String extendCategoryIdStr; + /** 商家类别ID */ + private List masterCategoryIdList; + + private Long defaultWarehouseId; + + public Long getBackOperatorId() { + return backOperatorId; + } + + public void setBackOperatorId(Long backOperatorId) { + this.backOperatorId = backOperatorId; + } + + public Integer getIsDupAudit() { + return isDupAudit; + } + + public void setIsDupAudit(Integer isDupAudit) { + this.isDupAudit = isDupAudit; + } + + public Long getId() { + return id; + } + + public String getUnderCarriageReasonStr() { + return underCarriageReasonStr; + } + + public void setUnderCarriageReasonStr(String underCarriageReasonStr) { + this.underCarriageReasonStr = underCarriageReasonStr; + } + + /** + * 产品ID + * + * @param id 产品ID + */ + + public void setId(Long id) { + this.id = id; + } + + /** + * 产品编码 + * + * @return productCode + */ + + public String getProductCode() { + return productCode; + } + + /** + * 产品编码 + * + * @param productCode 产品编码 + */ + + public void setProductCode(String productCode) { + this.productCode = productCode; + } + + /** + * 产品名 + * + * @return productCname + */ + + public String getProductCname() { + return productCname; + } + + /** + * 产品名 + * + * @param productCname 产品名 + */ + + public void setProductCname(String productCname) { + this.productCname = productCname; + } + + /** + * 产品名英文 + * + * @return productEname + */ + + public String getProductEname() { + return productEname; + } + + /** + * 产品名英文 + * + * @param productEname 产品名英文 + */ + + public void setProductEname(String productEname) { + this.productEname = productEname; + } + + + /** + * 产品销售类别 + * + * @param productSaleType 产品销售类别 + */ + + public void setProductSaleType(Integer productSaleType) { + this.productSaleType = productSaleType; + } + + /** + * 产品品牌Id + * + * @return brandId + */ + + public Long getBrandId() { + return brandId; + } + + /** + * 产品品牌Id + * + * @param brandId 产品品牌Id + */ + + public void setBrandId(Long brandId) { + this.brandId = brandId; + } + + /** + * 产品品牌 + * + * @return brandName + */ + + public String getBrandName() { + return brandName; + } + + /** + * 产品品牌 + * + * @param brandName 产品品牌 + */ + + public void setBrandName(String brandName) { + this.brandName = brandName; + } + + /** + * 产品创建时间 + * + * @return createTime + */ + + /** + * 产品创建时间 + * + * @param createTime 产品创建时间 + */ + + /** + * 市场价 + * + * @return productListPrice + */ + + public Double getProductListPrice() { + return productListPrice; + } + + /** + * 市场价 + * + * @param productListPrice 市场价 + */ + + public void setProductListPrice(Double productListPrice) { + this.productListPrice = productListPrice; + } + + /** + * 分类Id + * + * @return categoryId + */ + + public Long getCategoryId() { + return categoryId; + } + + /** + * 分类Id + * + * @param categoryId 分类Id + */ + + public void setCategoryId(Long categoryId) { + this.categoryId = categoryId; + } + + /** + * 厂商ID默认为1 + * + * @return mfid + */ + + public Long getMfid() { + return mfid; + } + + /** + * 厂商ID默认为1 + * + * @param mfid 厂商ID默认为1 + */ + + public void setMfid(Long mfid) { + this.mfid = mfid; + } + + /** + * productCanBeChange + * + * @return productCanBeChange + */ + + public Integer getProductCanBeChange() { + return productCanBeChange; + } + + /** + * productCanBeChange + * + * @param productCanBeChange productCanBeChange + */ + + public void setProductCanBeChange(Integer productCanBeChange) { + this.productCanBeChange = productCanBeChange; + } + + /** + * productChangeDay + * + * @return productChangeDay + */ + + public Integer getProductChangeDay() { + return productChangeDay; + } + + /** + * productChangeDay + * + * @param productChangeDay productChangeDay + */ + + public void setProductChangeDay(Integer productChangeDay) { + this.productChangeDay = productChangeDay; + } + + /** + * productCanBeReturn + * + * @return productCanBeReturn + */ + + public Integer getProductCanBeReturn() { + return productCanBeReturn; + } + + /** + * productCanBeReturn + * + * @param productCanBeReturn productCanBeReturn + */ + + public void setProductCanBeReturn(Integer productCanBeReturn) { + this.productCanBeReturn = productCanBeReturn; + } + + /** + * productReturnDay + * + * @return productReturnDay + */ + + public Integer getProductReturnDay() { + return productReturnDay; + } + + /** + * productReturnDay + * + * @param productReturnDay productReturnDay + */ + + public void setProductReturnDay(Integer productReturnDay) { + this.productReturnDay = productReturnDay; + } + + /** + * 能否维修 + * + * @return productCanBeRepair + */ + + public Integer getProductCanBeRepair() { + return productCanBeRepair; + } + + /** + * 能否维修 + * + * @param productCanBeRepair 能否维修 + */ + + public void setProductCanBeRepair(Integer productCanBeRepair) { + this.productCanBeRepair = productCanBeRepair; + } + + /** + * 能否维修 + * + * @return productCanBeRepairDay + */ + + public Integer getProductCanBeRepairDay() { + return productCanBeRepairDay; + } + + /** + * 能否维修 + * + * @param productCanBeRepairDay 能否维修 + */ + + public void setProductCanBeRepairDay(Integer productCanBeRepairDay) { + this.productCanBeRepairDay = productCanBeRepairDay; + } + + /** + * 安装信息 + * + * @return productNeedInstallation + */ + + public Integer getProductNeedInstallation() { + return productNeedInstallation; + } + + /** + * 安装信息 + * + * @param productNeedInstallation 安装信息 + */ + + public void setProductNeedInstallation(Integer productNeedInstallation) { + this.productNeedInstallation = productNeedInstallation; + } + + /** + * 条形码 + * + * @return ean13 + */ + + public String getEan13() { + return ean13; + } + + /** + * 条形码 + * + * @param ean13 条形码 + */ + + public void setEan13(String ean13) { + this.ean13 = ean13; + } + + /** + * sku + * + * @return sku + */ + + public String getSku() { + return sku; + } + + /** + * sku + * + * @param sku sku + */ + + public void setSku(String sku) { + this.sku = sku; + } + + /** + * 长 + * + * @return length + */ + + public Double getLength() { + return length; + } + + /** + * 长 + * + * @param length 长 + */ + + public void setLength(Double length) { + this.length = length; + } + + /** + * 宽 + * + * @return width + */ + + public Double getWidth() { + return width; + } + + /** + * 宽 + * + * @param width 宽 + */ + + public void setWidth(Double width) { + this.width = width; + } + + /** + * 高 + * + * @return height + */ + + public Double getHeight() { + return height; + } + + /** + * 高 + * + * @param height 高 + */ + + public void setHeight(Double height) { + this.height = height; + } + + /** + * 净重 + * + * @return weight + */ + + public Double getWeight() { + return weight; + } + + /** + * 净重 + * + * @param weight 净重 + */ + + public void setWeight(Double weight) { + this.weight = weight; + } + + /** + * keepTemperature + * + * @return keepTemperature + */ + + public String getKeepTemperature() { + return keepTemperature; + } + + /** + * keepTemperature + * + * @param keepTemperature keepTemperature + */ + + public void setKeepTemperature(String keepTemperature) { + this.keepTemperature = keepTemperature; + } + + /** + * keepHumidity + * + * @return keepHumidity + */ + + public String getKeepHumidity() { + return keepHumidity; + } + + /** + * keepHumidity + * + * @param keepHumidity keepHumidity + */ + + public void setKeepHumidity(String keepHumidity) { + this.keepHumidity = keepHumidity; + } + + /** + * keepSpecCondition + * + * @return keepSpecCondition + */ + + public String getKeepSpecCondition() { + return keepSpecCondition; + } + + /** + * keepSpecCondition + * + * @param keepSpecCondition keepSpecCondition + */ + + public void setKeepSpecCondition(String keepSpecCondition) { + this.keepSpecCondition = keepSpecCondition; + } + + /** + * productQualityAssuranceDay + * + * @return productQualityAssuranceDay + */ + + public Integer getProductQualityAssuranceDay() { + return productQualityAssuranceDay; + } + + /** + * productQualityAssuranceDay + * + * @param productQualityAssuranceDay productQualityAssuranceDay + */ + + public void setProductQualityAssuranceDay(Integer productQualityAssuranceDay) { + this.productQualityAssuranceDay = productQualityAssuranceDay; + } + + /** + * 是否已删除 + * + * @return isDeleted + */ + + public Integer getIsDeleted() { + return isDeleted; + } + + /** + * 是否已删除 + * + * @param isDeleted 是否已删除 + */ + + public void setIsDeleted(Integer isDeleted) { + this.isDeleted = isDeleted; + } + + /** + * 单位 + * + * @return unit + */ + + public String getUnit() { + return unit; + } + + /** + * 单位 + * + * @param unit 单位 + */ + + public void setUnit(String unit) { + this.unit = unit; + } + + /** + * 进价 + * + * @return inPrice + */ + + public Double getInPrice() { + return inPrice; + } + + /** + * 进价 + * + * @param inPrice 进价 + */ + + public void setInPrice(Double inPrice) { + this.inPrice = inPrice; + } + + /** + * volume + * + * @return volume + */ + + public Double getVolume() { + return volume; + } + + /** + * volume + * + * @param volume volume + */ + + public void setVolume(Double volume) { + this.volume = volume; + } + + /** + * countryOfOrgn + * + * @return countryOfOrgn + */ + + public Long getCountryOfOrgn() { + return countryOfOrgn; + } + + /** + * countryOfOrgn + * + * @param countryOfOrgn countryOfOrgn + */ + + public void setCountryOfOrgn(Long countryOfOrgn) { + this.countryOfOrgn = countryOfOrgn; + } + + /** + * 主图ID + * + * @return defaultPictureId + */ + + public Long getDefaultPictureId() { + return defaultPictureId; + } + + /** + * 主图ID + * + * @param defaultPictureId 主图ID + */ + + public void setDefaultPictureId(Long defaultPictureId) { + this.defaultPictureId = defaultPictureId; + } + + /** + * 主图URL + * + * @return defaultPictureUrl + */ + + public String getDefaultPictureUrl() { + + return defaultPictureUrl; + } + + /** + * 主图URL + * + * @param defaultPictureUrl 主图URL + */ + + public void setDefaultPictureUrl(String defaultPictureUrl) { + this.defaultPictureUrl = defaultPictureUrl; + } + + /** + * color + * + * @return color + */ + + public String getColor() { + return color; + } + + /** + * color + * + * @param color color + */ + + public void setColor(String color) { + this.color = color; + } + + /** + * currencyId + * + * @return currencyId + */ + + public Long getCurrencyId() { + return currencyId; + } + + /** + * currencyId + * + * @param currencyId currencyId + */ + + public void setCurrencyId(Long currencyId) { + this.currencyId = currencyId; + } + + /** + * 毛重 + * + * @return grossWeight + */ + + public Double getGrossWeight() { + return grossWeight; + } + + /** + * 毛重 + * + * @param grossWeight 毛重 + */ + + public void setGrossWeight(Double grossWeight) { + this.grossWeight = grossWeight; + } + + /** + * format + * + * @return format + */ + + public String getFormat() { + return format; + } + + /** + * format + * + * @param format format + */ + + public void setFormat(String format) { + this.format = format; + } + + /** + * 易碎品0不是1是 + * + * @return isFragile + */ + + public String getIsFragile() { + return isFragile; + } + + /** + * 易碎品0不是1是 + * + * @param isFragile 易碎品0不是1是 + */ + + public void setIsFragile(String isFragile) { + this.isFragile = isFragile; + } + + /** + * 向上0不是1是 + * + * @return putOnDirection + */ + + public String getPutOnDirection() { + return putOnDirection; + } + + /** + * 向上0不是1是 + * + * @param putOnDirection 向上0不是1是 + */ + + public void setPutOnDirection(String putOnDirection) { + this.putOnDirection = putOnDirection; + } + + /** + * 贵重品0不是1是 + * + * @return isValuables + */ + + public String getIsValuables() { + return isValuables; + } + + /** + * 贵重品0不是1是 + * + * @param isValuables 贵重品0不是1是 + */ + + public void setIsValuables(String isValuables) { + this.isValuables = isValuables; + } + + /** + * 液体0不是1是 + * + * @return isLiquid + */ + + public String getIsLiquid() { + return isLiquid; + } + + /** + * 液体0不是1是 + * + * @param isLiquid 液体0不是1是 + */ + + public void setIsLiquid(String isLiquid) { + this.isLiquid = isLiquid; + } + + /** + * 防交叉污染0不是1是 + * + * @return isCrossContamination + */ + + public String getIsCrossContamination() { + return isCrossContamination; + } + + /** + * 防交叉污染0不是1是 + * + * @param isCrossContamination 防交叉污染0不是1是 + */ + + public void setIsCrossContamination(String isCrossContamination) { + this.isCrossContamination = isCrossContamination; + } + + /** + * 16进制的颜色代码如#FF00AA + * + * @return colorNumber + */ + + public String getColorNumber() { + return colorNumber; + } + + /** + * 16进制的颜色代码如#FF00AA + * + * @param colorNumber 16进制的颜色代码如#FF00AA + */ + + public void setColorNumber(String colorNumber) { + this.colorNumber = colorNumber; + } + + /** + * 尺码 + * + * @return productSize + */ + + public String getProductSize() { + return productSize; + } + + /** + * 尺码 + * + * @param productSize 尺码 + */ + + public void setProductSize(String productSize) { + this.productSize = productSize; + } + + /** + * 销售技巧 + * + * @return saleSkill + */ + + public String getSaleSkill() { + return saleSkill; + } + + /** + * 销售技巧 + * + * @param saleSkill 销售技巧 + */ + + public void setSaleSkill(String saleSkill) { + this.saleSkill = saleSkill; + } + + /** + * 本商品作为赠品时的处理方法 + * + * @return dispositionInstruct + */ + + public String getDispositionInstruct() { + return dispositionInstruct; + } + + /** + * 本商品作为赠品时的处理方法 + * + * @param dispositionInstruct 本商品作为赠品时的处理方法 + */ + + public void setDispositionInstruct(String dispositionInstruct) { + this.dispositionInstruct = dispositionInstruct; + } + + /** + * 产地 + * + * @return placeOfOrigin + */ + + public String getPlaceOfOrigin() { + return placeOfOrigin; + } + + /** + * 产地 + * + * @param placeOfOrigin 产地 + */ + + public void setPlaceOfOrigin(String placeOfOrigin) { + this.placeOfOrigin = placeOfOrigin; + } + + /** + * 产品页面标题 + * + * @return productSeoTitle + */ + + public String getProductSeoTitle() { + return productSeoTitle; + } + + /** + * 产品页面标题 + * + * @param productSeoTitle 产品页面标题 + */ + + public void setProductSeoTitle(String productSeoTitle) { + this.productSeoTitle = productSeoTitle; + } + + /** + * 产品页面属性关键字 + * + * @return productSeoKeyword + */ + + public String getProductSeoKeyword() { + return productSeoKeyword; + } + + /** + * 产品页面属性关键字 + * + * @param productSeoKeyword 产品页面属性关键字 + */ + + public void setProductSeoKeyword(String productSeoKeyword) { + this.productSeoKeyword = productSeoKeyword; + } + + /** + * 产品页面属性描述 + * + * @return productSeoDescription + */ + + public String getProductSeoDescription() { + return productSeoDescription; + } + + /** + * 产品页面属性描述 + * + * @param productSeoDescription 产品页面属性描述 + */ + + public void setProductSeoDescription(String productSeoDescription) { + this.productSeoDescription = productSeoDescription; + } + + /** + * 后台产品配件说明 + * + * @return accessoryDescription + */ + + public String getAccessoryDescription() { + return accessoryDescription; + } + + /** + * 后台产品配件说明 + * + * @param accessoryDescription 后台产品配件说明 + */ + + public void setAccessoryDescription(String accessoryDescription) { + this.accessoryDescription = accessoryDescription; + } + + /** + * 是否需要单独开票 + * + * @return needInvoice + */ + + public Integer getNeedInvoice() { + return needInvoice; + } + + /** + * 是否需要单独开票 + * + * @param needInvoice 是否需要单独开票 + */ + + public void setNeedInvoice(Integer needInvoice) { + this.needInvoice = needInvoice; + } + + /** + * 清仓原因 + * + * @return clearCause + */ + + public String getClearCause() { + return clearCause; + } + + /** + * 清仓原因 + * + * @param clearCause 清仓原因 + */ + + public void setClearCause(String clearCause) { + this.clearCause = clearCause; + } + + /** + * 默认商品条码ID + * + * @return defaultBarcodeId + */ + + public Long getDefaultBarcodeId() { + return defaultBarcodeId; + } + + /** + * 默认商品条码ID + * + * @param defaultBarcodeId 默认商品条码ID + */ + + public void setDefaultBarcodeId(Long defaultBarcodeId) { + this.defaultBarcodeId = defaultBarcodeId; + } + + /** + * 广告词 + * + * @return adWord + */ + + public String getAdWord() { + return adWord; + } + + /** + * 广告词 + * + * @param adWord 广告词 + */ + + public void setAdWord(String adWord) { + this.adWord = adWord; + } + + /** + * 是否是3c产品(0:非3C1:3C产品) + * + * @return isCcc + */ + + public Integer getIsCcc() { + return isCcc; + } + + /** + * 是否是3c产品(0:非3C1:3C产品) + * + * @param isCcc 是否是3c产品(0:非3C1:3C产品) + */ + + public void setIsCcc(Integer isCcc) { + this.isCcc = isCcc; + } + + /** + * N件购 + * + * @return shoppingCount + */ + + public Integer getShoppingCount() { + return shoppingCount; + } + + /** + * N件购 + * + * @param shoppingCount N件购 + */ + + public void setShoppingCount(Integer shoppingCount) { + this.shoppingCount = shoppingCount; + } + + /** + * 是否为赠品 + * + * @return productIsGift + */ + + public Integer getProductIsGift() { + return productIsGift; + } + + /** + * 是否为赠品 + * + * @param productIsGift 是否为赠品 + */ + + public void setProductIsGift(Integer productIsGift) { + this.productIsGift = productIsGift; + } + + /** + * 是否可以退换货0:不可以1:可以 + * + * @return canReturnAndChange + */ + + public Integer getCanReturnAndChange() { + return canReturnAndChange; + } + + /** + * 是否可以退换货0:不可以1:可以 + * + * @param canReturnAndChange 是否可以退换货0:不可以1:可以 + */ + + public void setCanReturnAndChange(Integer canReturnAndChange) { + this.canReturnAndChange = canReturnAndChange; + } + + /** + * 是否需要检测0:不需要1:需要 + * + * @return needExamine + */ + + public Integer getNeedExamine() { + return needExamine; + } + + /** + * 是否需要检测0:不需要1:需要 + * + * @param needExamine 是否需要检测0:不需要1:需要 + */ + + public void setNeedExamine(Integer needExamine) { + this.needExamine = needExamine; + } + + /** + * 1:新增未审核;2:编辑待审核;3:审核未通过;4:审核通过;5:文描审核失败;6:图片审核失败 + * + * @return verifyFlg + */ + + public Integer getVerifyFlg() { + return verifyFlg; + } + + /** + * 1:新增未审核;2:编辑待审核;3:审核未通过;4:审核通过;5:文描审核失败;6:图片审核失败 + * + * @param verifyFlg 1:新增未审核;2:编辑待审核;3:审核未通过;4:审核通过;5:文描审核失败;6:图片审核失败 + */ + + public void setVerifyFlg(Integer verifyFlg) { + this.verifyFlg = verifyFlg; + } + + /** + * 审核者 + * + * @return verifyBy + */ + + public Long getVerifyBy() { + return verifyBy; + } + + /** + * 审核者 + * + * @param verifyBy 审核者 + */ + + public void setVerifyBy(Long verifyBy) { + this.verifyBy = verifyBy; + } + + /** + * 审核日时 + * + * @return verifyAt + */ + + /** + * 审核日时 + * + * @param verifyAt 审核日时 + */ + + /** + * 商品登记者 + * + * @return registerBy + */ + + public Long getRegisterBy() { + return registerBy; + } + + /** + * 商品登记者 + * + * @param registerBy 商品登记者 + */ + + public void setRegisterBy(Long registerBy) { + this.registerBy = registerBy; + } + + /** + * 商品登记日时 + * + * @return registerAt + */ + + /** + * 商品登记日时 + * + * @param registerAt 商品登记日时 + */ + + /** + * 商品登记者联系电话 + * + * @return registerPhone + */ + + public String getRegisterPhone() { + return registerPhone; + } + + /** + * 商品登记者联系电话 + * + * @param registerPhone 商品登记者联系电话 + */ + + public void setRegisterPhone(String registerPhone) { + this.registerPhone = registerPhone; + } + + /** + * 审核备注 + * + * @return verifyRemark + */ + + public String getVerifyRemark() { + return verifyRemark; + } + + /** + * 审核备注 + * + * @param verifyRemark 审核备注 + */ + + public void setVerifyRemark(String verifyRemark) { + this.verifyRemark = verifyRemark; + } + + /** + * 批量数 + * + * @return batchNum + */ + + public Integer getBatchNum() { + return batchNum; + } + + /** + * 批量数 + * + * @param batchNum 批量数 + */ + + public void setBatchNum(Integer batchNum) { + this.batchNum = batchNum; + } + + /** + * 是否只限本地配送0:不限制1:限制(粉状液体膏状) + * + * @return localLimit + */ + + public Integer getLocalLimit() { + return localLimit; + } + + /** + * 是否只限本地配送0:不限制1:限制(粉状液体膏状) + * + * @param localLimit 是否只限本地配送0:不限制1:限制(粉状液体膏状) + */ + + public void setLocalLimit(Integer localLimit) { + this.localLimit = localLimit; + } + + /** + * 一包的数量 + * + * @return stdPackQty + */ + + public Integer getStdPackQty() { + return stdPackQty; + } + + /** + * 一包的数量 + * + * @param stdPackQty 一包的数量 + */ + + public void setStdPackQty(Integer stdPackQty) { + this.stdPackQty = stdPackQty; + } + + /** + * 正式表产品ID + * + * @return fromalProductId + */ + + public Long getFromalProductId() { + return fromalProductId; + } + + /** + * 正式表产品ID + * + * @param fromalProductId 正式表产品ID + */ + + public void setFromalProductId(Long fromalProductId) { + this.fromalProductId = fromalProductId; + } + + /** + * 是否强制发票 + * + * @return isMustInvoice + */ + + public Integer getIsMustInvoice() { + return isMustInvoice; + } + + /** + * 是否强制发票 + * + * @param isMustInvoice 是否强制发票 + */ + + public void setIsMustInvoice(Integer isMustInvoice) { + this.isMustInvoice = isMustInvoice; + } + + /** + * 审核失败原因 + * + * @return verifyFailureType + */ + + public Integer getVerifyFailureType() { + return verifyFailureType; + } + + /** + * 审核失败原因 + * + * @param verifyFailureType 审核失败原因 + */ + + public void setVerifyFailureType(Integer verifyFailureType) { + this.verifyFailureType = verifyFailureType; + } + + /** + * 产品类型0:普通产品1:主系列产品2:子系列产品3:捆绑产品4:礼品卡5:虚拟商品6:增值服务 + * + * @return productType + */ + + public Integer getProductType() { + return productType; + } + + /** + * 产品类型0:普通产品1:主系列产品2:子系列产品3:捆绑产品4:礼品卡5:虚拟商品6:增值服务 + * + * @param productType 产品类型0:普通产品1:主系列产品2:子系列产品3:捆绑产品4:礼品卡5:虚拟商品6:增值服务 + */ + + public void setProductType(Integer productType) { + this.productType = productType; + } + + /** + * 是否能被采购 + * + * @return canPurchase + */ + + public Integer getCanPurchase() { + return canPurchase; + } + + /** + * 是否能被采购 + * + * @param canPurchase 是否能被采购 + */ + + public void setCanPurchase(Integer canPurchase) { + this.canPurchase = canPurchase; + } + + /** + * 标准包装箱sku + * + * @return stdPackageSku + */ + + public String getStdPackageSku() { + return stdPackageSku; + } + + /** + * 标准包装箱sku + * + * @param stdPackageSku 标准包装箱sku + */ + + public void setStdPackageSku(String stdPackageSku) { + this.stdPackageSku = stdPackageSku; + } + + /** + * 是否需要启用保质期控制0:不启用1:启用 + * + * @return userExpireControl + */ + + public Integer getUserExpireControl() { + return userExpireControl; + } + + /** + * 是否需要启用保质期控制0:不启用1:启用 + * + * @param userExpireControl 是否需要启用保质期控制0:不启用1:启用 + */ + + public void setUserExpireControl(Integer userExpireControl) { + this.userExpireControl = userExpireControl; + } + + /** + * 批次规则ID + * + * @return batchRuleId + */ + + public Long getBatchRuleId() { + return batchRuleId; + } + + /** + * 批次规则ID + * + * @param batchRuleId 批次规则ID + */ + + public void setBatchRuleId(Long batchRuleId) { + this.batchRuleId = batchRuleId; + } + + /** + * 产品名称副标题 + * + * @return nameSubtitle + */ + + public String getNameSubtitle() { + return nameSubtitle; + } + + /** + * 产品名称副标题 + * + * @param nameSubtitle 产品名称副标题 + */ + + public void setNameSubtitle(String nameSubtitle) { + this.nameSubtitle = nameSubtitle; + } + + /** + * 产品特殊类型:1:医药;11:药品;12器械;14-18:处方药;50:电子凭证 + * + * @return specialType + */ + + public String getSpecialType() { + return specialType; + } + + /** + * 产品特殊类型:1:医药;11:药品;12器械;14-18:处方药;50:电子凭证 + * + * @param specialType 产品特殊类型:1:医药;11:药品;12器械;14-18:处方药;50:电子凭证 + */ + + public void setSpecialType(String specialType) { + this.specialType = specialType; + } + + /** + * 给经销商的批发价 + * + * @return batchPrice + */ + + public Double getBatchPrice() { + return batchPrice; + } + + /** + * 给经销商的批发价 + * + * @param batchPrice 给经销商的批发价 + */ + + public void setBatchPrice(Double batchPrice) { + this.batchPrice = batchPrice; + } + + /** + * 是否需要批次控制0:不需要1:需要 + * + * @return needBatchControl + */ + + public Integer getNeedBatchControl() { + return needBatchControl; + } + + /** + * 是否需要批次控制0:不需要1:需要 + * + * @param needBatchControl 是否需要批次控制0:不需要1:需要 + */ + + public void setNeedBatchControl(Integer needBatchControl) { + this.needBatchControl = needBatchControl; + } + + /** + * 销售税率 + * + * @return salesTax + */ + + public Double getSalesTax() { + return salesTax; + } + + /** + * 销售税率 + * + * @param salesTax 销售税率 + */ + + public void setSalesTax(Double salesTax) { + this.salesTax = salesTax; + } + + /** + * 外部产品编码 + * + * @return outerId + */ + + public String getOuterId() { + return outerId; + } + + /** + * 外部产品编码 + * + * @param outerId 外部产品编码 + */ + + public void setOuterId(String outerId) { + this.outerId = outerId; + } + + /** + * 商家ID + * + * @return merchantId + */ + + public Long getMerchantId() { + return merchantId; + } + + /** + * 商家ID + * + * @param merchantId 商家ID + */ + + public void setMerchantId(Long merchantId) { + this.merchantId = merchantId; + } + + /** + * 商家名称 + * + * @return merchantName + */ + + public String getMerchantName() { + return merchantName; + } + + /** + * 商家名称 + * + * @param merchantName 商家名称 + */ + + public void setMerchantName(String merchantName) { + this.merchantName = merchantName; + } + + /** + * 商家产品主类别(用于报表统计) + * + * @return masterCategoryId + */ + + public Long getMasterCategoryId() { + return masterCategoryId; + } + + /** + * 商家产品主类别(用于报表统计) + * + * @param masterCategoryId 商家产品主类别(用于报表统计) + */ + + public void setMasterCategoryId(Long masterCategoryId) { + this.masterCategoryId = masterCategoryId; + } + + /** + * 关注等级设置 + * + * @return concernLevel + */ + + public Integer getConcernLevel() { + return concernLevel; + } + + /** + * 关注等级设置 + * + * @param concernLevel 关注等级设置 + */ + + public void setConcernLevel(Integer concernLevel) { + this.concernLevel = concernLevel; + } + + /** + * 关注理由 + * + * @return concernReason + */ + + public String getConcernReason() { + return concernReason; + } + + /** + * 关注理由 + * + * @param concernReason 关注理由 + */ + + public void setConcernReason(String concernReason) { + this.concernReason = concernReason; + } + + /** + * 是否可售 + * + * @return canSale + */ + + public Integer getCanSale() { + return canSale; + } + + /** + * 是否可售 + * + * @param canSale 是否可售 + */ + + public void setCanSale(Integer canSale) { + this.canSale = canSale; + } + + /** + * 是否显示 + * + * @return canShow + */ + + public Integer getCanShow() { + return canShow; + } + + /** + * 是否显示 + * + * @param canShow 是否显示 + */ + + public void setCanShow(Integer canShow) { + this.canShow = canShow; + } + + /** + * 产品销售税率 + * + * @return prodcutTaxRate + */ + + public Long getProdcutTaxRate() { + return prodcutTaxRate; + } + + /** + * 产品销售税率 + * + * @param prodcutTaxRate 产品销售税率 + */ + + public void setProdcutTaxRate(Long prodcutTaxRate) { + this.prodcutTaxRate = prodcutTaxRate; + } + + /** + * 是否支持VIP0:不支持1:支持 + * + * @return canVipDiscount + */ + + public Integer getCanVipDiscount() { + return canVipDiscount; + } + + /** + * 是否支持VIP0:不支持1:支持 + * + * @param canVipDiscount 是否支持VIP0:不支持1:支持 + */ + + public void setCanVipDiscount(Integer canVipDiscount) { + this.canVipDiscount = canVipDiscount; + } + + /** + * 分类名称 + * + * @return categoryName + */ + + public String getCategoryName() { + return categoryName; + } + + /** + * 分类名称 + * + * @param categoryName 分类名称 + */ + + public void setCategoryName(String categoryName) { + this.categoryName = categoryName; + } + + /** + * 销售价格 + * + * @return salePrice + */ + + public Double getSalePrice() { + return salePrice; + } + + /** + * 销售价格 + * + * @param salePrice 销售价格 + */ + + public void setSalePrice(Double salePrice) { + this.salePrice = salePrice; + } + + /** + * 库存 + * + * @return stockNum + */ + + public Long getStockNum() { + return stockNum; + } + + /** + * 库存 + * + * @param stockNum 库存 + */ + + public void setStockNum(Long stockNum) { + this.stockNum = stockNum; + } + + /** + * 商家类别名称 + * + * @return merchantCategoryName + */ + + public String getMerchantCategoryName() { + return merchantCategoryName; + } + + /** + * 商家类别名称 + * + * @param merchantCategoryName 商家类别名称 + */ + + public void setMerchantCategoryName(String merchantCategoryName) { + this.merchantCategoryName = merchantCategoryName; + } + + /** + * 商家详情 + * + * @return productDescription + */ + + public String getProductDescription() { + return productDescription; + } + + /** + * 商家详情 + * + * @param productDescription 商家详情 + */ + + public void setProductDescription(String productDescription) { + this.productDescription = productDescription; + } + + /** + * 是否可调拨0:不可以1:可以 + * + * @return isTransfer + */ + + public Integer getIsTransfer() { + return isTransfer; + } + + /** + * 是否可调拨0:不可以1:可以 + * + * @param isTransfer 是否可调拨0:不可以1:可以 + */ + + public void setIsTransfer(Integer isTransfer) { + this.isTransfer = isTransfer; + } + + /** + * 是否需要审核0:新增未提交;1:需要审核;2:编辑未提交 + * + * @return isSubmit + */ + + public Integer getIsSubmit() { + return isSubmit; + } + + /** + * 是否需要审核0:新增未提交;1:需要审核;2:编辑未提交 + * + * @param isSubmit 是否需要审核0:新增未提交;1:需要审核;2:编辑未提交 + */ + + public void setIsSubmit(Integer isSubmit) { + this.isSubmit = isSubmit; + } + + /** + * 审核失败类型 + * + * @return verifyFailueType + */ + + public Integer getVerifyFailueType() { + return verifyFailueType; + } + + /** + * 审核失败类型 + * + * @param verifyFailueType 审核失败类型 + */ + + public void setVerifyFailueType(Integer verifyFailueType) { + this.verifyFailueType = verifyFailueType; + } + + /** + * 产品拼音 + * + * @return productSpell + */ + + public String getProductSpell() { + return productSpell; + } + + /** + * 产品拼音 + * + * @param productSpell 产品拼音 + */ + + public void setProductSpell(String productSpell) { + this.productSpell = productSpell; + } + + /** + * 产品名称前缀 + * + * @return productNamePrefix + */ + + public String getProductNamePrefix() { + return productNamePrefix; + } + + /** + * 产品名称前缀 + * + * @param productNamePrefix 产品名称前缀 + */ + + public void setProductNamePrefix(String productNamePrefix) { + this.productNamePrefix = productNamePrefix; + } + + /** + * 审核失败原因 + * + * @return failueReason + */ + + public String getFailueReason() { + return failueReason; + } + + /** + * 审核失败原因 + * + * @param failueReason 审核失败原因 + */ + + public void setFailueReason(String failueReason) { + this.failueReason = failueReason; + } + + /** + * orgPicUrl + * + * @return orgPicUrl + */ + + public String getOrgPicUrl() { + + return orgPicUrl; + } + + /** + * orgPicUrl + * + * @param orgPicUrl orgPicUrl + */ + + public void setOrgPicUrl(String orgPicUrl) { + this.orgPicUrl = orgPicUrl; + } + + /** + * 扩展分类名称 + * + * @return subCategoryName + */ + + public String getSubCategoryName() { + return subCategoryName; + } + + /** + * 扩展分类名称 + * + * @param subCategoryName 扩展分类名称 + */ + + public void setSubCategoryName(String subCategoryName) { + this.subCategoryName = subCategoryName; + } + + /** + * 扩展分类ID + * + * @return subCategoryId + */ + + public Long getSubCategoryId() { + return subCategoryId; + } + + /** + * 扩展分类ID + * + * @param subCategoryId 扩展分类ID + */ + + public void setSubCategoryId(Long subCategoryId) { + this.subCategoryId = subCategoryId; + } + + /** + * 7天内日均销量 + * + * @return dailySale + */ + + public Integer getDailySale() { + return dailySale; + } + + /** + * 7天内日均销量 + * + * @param dailySale 7天内日均销量 + */ + + public void setDailySale(Integer dailySale) { + this.dailySale = dailySale; + } + + /** + * 查看是否有主图 + * + * @return picCount + */ + + public Integer getPicCount() { + return picCount; + } + + /** + * 查看是否有主图 + * + * @param picCount 查看是否有主图 + */ + + public void setPicCount(Integer picCount) { + this.picCount = picCount; + } + + /** + * 强制下架原因 + * + * @return underCarriageReason + */ + + public Integer getUnderCarriageReason() { + return underCarriageReason; + } + + /** + * 强制下架原因 + * + * @param underCarriageReason 强制下架原因 + */ + + public void setUnderCarriageReason(Integer underCarriageReason) { + this.underCarriageReason = underCarriageReason; + } + + /** + * 异常信息 + * + * @return errorMessage + */ + + public String getErrorMessage() { + return errorMessage; + } + + /** + * 异常信息 + * + * @param errorMessage 异常信息 + */ + /** + * public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; } 库存预警数量 + * + * @return alertStockCount + */ + + public Integer getAlertStockCount() { + return alertStockCount; + } + + /** + * 库存预警数量 + * + * @param alertStockCount 库存预警数量 + */ + + public void setAlertStockCount(Integer alertStockCount) { + this.alertStockCount = alertStockCount; + } + + /** + * 提交时间 + * + * @return submitTime + */ + /** + * public Date getSubmitTime() { return submitTime; } 提交时间 + * + * @param submitTime 提交时间 + */ + /** + * public void setSubmitTime(Date submitTime) { this.submitTime = submitTime; } holdPmPriceRpcVo + * + * @return holdPmPriceRpcVo + */ + + /** + * holdPmPriceRpcVo + * + * @param holdPmPrice holdPmPriceRpcVo + */ + + /** + * pmPriceRpcVo + * + * @return pmPriceRpcVo + */ + /** + * public PmPriceRpcVo getPmPrice() { return pmPrice; } pmPriceRpcVo + * + * @param pmPrice pmPriceRpcVo public void setPmPrice(PmPriceRpcVo pmPrice) { this.pmPrice = pmPrice; } + */ + public Long getFormalPmInfoId() { + return formalPmInfoId; + } + + public void setFormalPmInfoId(Long formalPmInfoId) { + this.formalPmInfoId = formalPmInfoId; + } + + /** + * 库存状况(产品预览页用) + * + * @return deliveryInfo + */ + + public String getDeliveryInfo() { + return deliveryInfo; + } + + /** + * 库存状况(产品预览页用) + * + * @param deliveryInfo 库存状况(产品预览页用) + */ + + public void setDeliveryInfo(String deliveryInfo) { + this.deliveryInfo = deliveryInfo; + } + + /** + * 主图链接 + * + * @return picUrl + */ + + public String getPicUrl() { + return picUrl; + } + + /** + * 主图链接 + * + * @param picUrl 主图链接 + */ + + public void setPicUrl(String picUrl) { + this.picUrl = picUrl; + } + + /** + * 跳到商品详情页的来源0:首次审核页面1:二次审核页面2:审核失败页面 + * + * @return viewFromTag + */ + + public Integer getViewFromTag() { + return viewFromTag; + } + + /** + * 跳到商品详情页的来源0:首次审核页面1:二次审核页面2:审核失败页面 + * + * @param viewFromTag 跳到商品详情页的来源0:首次审核页面1:二次审核页面2:审核失败页面 + */ + + public void setViewFromTag(Integer viewFromTag) { + this.viewFromTag = viewFromTag; + } + + public Double getProductNonMemberPrice() { + return productNonMemberPrice; + } + + /** + * 产品售价 + * + * @param productNonMemberPrice 产品售价 + */ + + public void setProductNonMemberPrice(Double productNonMemberPrice) { + this.productNonMemberPrice = productNonMemberPrice; + } + + public Integer getIsUpdate() { + return isUpdate; + } + + /** + * 是否更新操作 + * + * @param isUpdate 是否更新操作 + */ + + public void setIsUpdate(Integer isUpdate) { + this.isUpdate = isUpdate; + } + + public List getProductSizeSet() { + return productSizeSet; + } + + public void setProductSizeSet(List productSizeSet) { + this.productSizeSet = productSizeSet; + } + + public Boolean getIsMainProduct() { + return isMainProduct; + } + + /** + * 是否主产品 + * + * @param isMainProduct 是否主产品 + */ + + public void setIsMainProduct(Boolean isMainProduct) { + this.isMainProduct = isMainProduct; + } + + /** + * 从图片空间中返回图片ID和URL + * + * @return productPicIdAndURL + */ + + public String getProductPicIdAndURL() { + return productPicIdAndURL; + } + + /** + * 从图片空间中返回图片ID和URL + * + * @param productPicIdAndURL 从图片空间中返回图片ID和URL + */ + + public void setProductPicIdAndURL(String productPicIdAndURL) { + this.productPicIdAndURL = productPicIdAndURL; + } + + public Integer getIsTemp() { + return isTemp; + } + + /** + * isTemp + * + * @param isTemp isTemp + */ + + public void setIsTemp(Integer isTemp) { + this.isTemp = isTemp; + } + + public Double getPriceRate() { + return priceRate; + } + + public void setPriceRate(Double priceRate) { + this.priceRate = priceRate; + } + + public Integer getPicSpecialType() { + return picSpecialType; + } + + public void setPicSpecialType(Integer picSpecialType) { + this.picSpecialType = picSpecialType; + } + + public Integer getExemptStatus() { + return exemptStatus; + } + + public void setExemptStatus(Integer exemptStatus) { + this.exemptStatus = exemptStatus; + } + + public String getViolationReasonIds() { + return violationReasonIds; + } + + /** + * 免审商家新增字段:记录违规的原因 + * + * @param violationReasonIds 免审商家新增字段:记录违规的原因 + */ + + public void setViolationReasonIds(String violationReasonIds) { + this.violationReasonIds = violationReasonIds; + } + + /** + * 免审商家新增字段:记录违规的原因文字信息,逗号分隔 + * + * @return violationReasons + */ + + public String getViolationReasons() { + return violationReasons; + } + + public void setViolationReasons(String violationReasons) { + this.violationReasons = violationReasons; + } + + /** + * 违规限定修改剩余时间(毫秒数) + * + * @return remainTime + */ + + public Long getRemainTime() { + return remainTime; + } + + /** + * 违规限定修改剩余时间(毫秒数) + * + * @param remainTime 违规限定修改剩余时间(毫秒数) + */ + + public void setRemainTime(Long remainTime) { + this.remainTime = remainTime; + } + + public Integer getSubmitOrder() { + return submitOrder; + } + + public void setSubmitOrder(Integer submitOrder) { + this.submitOrder = submitOrder; + } + + public Integer getProductSource() { + return productSource; + } + + public void setProductSource(Integer productSource) { + this.productSource = productSource; + } + + public String getProductSname() { + return productSname; + } + + public void setProductSname(String productSname) { + this.productSname = productSname; + } + + public Integer getCanFenqi() { + return canFenqi; + } + + public void setCanFenqi(Integer canFenqi) { + this.canFenqi = canFenqi; + } + + public String getSeason() { + return season; + } + + public void setSeason(String season) { + this.season = season; + } + + public Integer getIsKa() { + return isKa; + } + + public void setIsKa(Integer isKa) { + this.isKa = isKa; + } + + public Integer getKaMCreateTime() { + return kaMCreateTime; + } + + public void setKaMCreateTime(Integer kaMCreateTime) { + this.kaMCreateTime = kaMCreateTime; + } + + public Integer getDeliveryDay() { + return deliveryDay; + } + + public void setDeliveryDay(Integer deliveryDay) { + this.deliveryDay = deliveryDay; + } + + public Integer getIsEdit() { + return isEdit; + } + + public void setIsEdit(Integer isEdit) { + this.isEdit = isEdit; + } + + public String getProductBrandName() { + return productBrandName; + } + + public void setProductBrandName(String productBrandName) { + this.productBrandName = productBrandName; + } + + /** + * 类别拼接字符串 + * + * @return categoryStr + */ + + public String getCategoryStr() { + return categoryStr; + } + + /** + * 类别拼接字符串 + * + * @param categoryStr 类别拼接字符串 + */ + + public void setCategoryStr(String categoryStr) { + this.categoryStr = categoryStr; + } + + /** + * 扩展类别拼接字符串 + * + * @return extendCategoryStr + */ + + public String getExtendCategoryStr() { + return extendCategoryStr; + } + + /** + * 扩展类别拼接字符串 + * + * @param extendCategoryStr 扩展类别拼接字符串 + */ + + public void setExtendCategoryStr(String extendCategoryStr) { + this.extendCategoryStr = extendCategoryStr; + } + + public String getCategoryIdStr() { + return categoryIdStr; + } + + public void setCategoryIdStr(String categoryIdStr) { + this.categoryIdStr = categoryIdStr; + } + + public String getExtendCategoryIdStr() { + return extendCategoryIdStr; + } + + + public Long getDefaultWarehouseId() { + return defaultWarehouseId; + } + + public void setDefaultWarehouseId(Long defaultWarehouseId) { + this.defaultWarehouseId = defaultWarehouseId; + } + + public Long getOldCategoryId() { + return oldCategoryId; + } + + public void setOldCategoryId(Long oldCategoryId) { + this.oldCategoryId = oldCategoryId; + } + + public Long getOldExtendCategoryId() { + return oldExtendCategoryId; + } + + public void setOldExtendCategoryId(Long oldExtendCategoryId) { + this.oldExtendCategoryId = oldExtendCategoryId; + } + + public String getDeletedProductId() { + return deletedProductId; + } + + public void setDeletedProductId(String deletedProductId) { + this.deletedProductId = deletedProductId; + } + + public String getReplaceProductSize() { + return replaceProductSize; + } + + public void setReplaceProductSize(String replaceProductSize) { + this.replaceProductSize = replaceProductSize; + } + + public List getMasterCategoryIdList() { + return masterCategoryIdList; + } + + public void setMasterCategoryIdList(List masterCategoryIdList) { + //this.masterCategoryIdList = masterCategoryIdList; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/AbstractSerializeTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/AbstractSerializeTest.java new file mode 100644 index 0000000000..d6938d92f5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/AbstractSerializeTest.java @@ -0,0 +1,92 @@ +package com.alibaba.json.bvt.parser.deser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +public class AbstractSerializeTest extends TestCase { + + protected void setUp() throws Exception { + ObjectDeserializer serializerB = ParserConfig.getGlobalInstance().getDeserializer(B.class); + ParserConfig.getGlobalInstance().putDeserializer(A.class, serializerB); + } + + protected void tearDown() throws Exception { + ParserConfig.getGlobalInstance().putDeserializer(A.class, null); + } + + public void test_mapping_0() throws Exception { + String text = "{\"@type\":\"com.alibaba.json.bvt.parser.deser.AbstractSerializeTest$A\"}"; + + B b = (B) JSON.parse(text); + Assert.assertNotNull(b); + } + + public void test_mapping_1() throws Exception { + String text = "{\"@type\":\"com.alibaba.json.bvt.parser.deser.AbstractSerializeTest$A\",\"id\":123}"; + + B b = (B) JSON.parse(text); + Assert.assertNotNull(b); + Assert.assertEquals(123, b.getId()); + } + + public void test_mapping_2() throws Exception { + String text = "{\"@type\":\"com.alibaba.json.bvt.parser.deser.AbstractSerializeTest$A\",\"id\":234,\"name\":\"abc\"}"; + + B b = (B) JSON.parse(text); + Assert.assertNotNull(b); + Assert.assertEquals(234, b.getId()); + Assert.assertEquals("abc", b.getName()); + } + + public void test_mapping_group() throws Exception { + String text = "{\"a\":{\"id\":234,\"name\":\"abc\"}}"; + + G g = JSON.parseObject(text, G.class); + Assert.assertTrue(g.getA() instanceof B); + } + + public static class G { + + private A a; + + public A getA() { + return a; + } + + public void setA(A a) { + this.a = a; + } + + } + + public static abstract class A { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + } + + public static class B extends A { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/AbstractSerializeTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/AbstractSerializeTest2.java new file mode 100644 index 0000000000..6e325a9f8d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/AbstractSerializeTest2.java @@ -0,0 +1,91 @@ +package com.alibaba.json.bvt.parser.deser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.parser.ParserConfig; + +public class AbstractSerializeTest2 extends TestCase { + + protected void setUp() throws Exception { + } + + protected void tearDown() throws Exception { + ParserConfig.getGlobalInstance().putDeserializer(A.class, null); + } + + public void test_mapping_0() throws Exception { + String text = "{\"@type\":\"com.alibaba.json.bvt.parser.deser.AbstractSerializeTest2$A\"}"; + + B b = (B) JSON.parse(text); + Assert.assertNotNull(b); + } + + public void test_mapping_1() throws Exception { + String text = "{\"@type\":\"com.alibaba.json.bvt.parser.deser.AbstractSerializeTest2$A\",\"id\":123}"; + + B b = (B) JSON.parse(text); + Assert.assertNotNull(b); + Assert.assertEquals(123, b.getId()); + } + + public void test_mapping_2() throws Exception { + String text = "{\"@type\":\"com.alibaba.json.bvt.parser.deser.AbstractSerializeTest2$A\",\"id\":234,\"name\":\"abc\"}"; + + B b = (B) JSON.parse(text); + Assert.assertNotNull(b); + Assert.assertEquals(234, b.getId()); + Assert.assertEquals("abc", b.getName()); + } + + public void test_mapping_group() throws Exception { + String text = "{\"a\":{\"id\":234,\"name\":\"abc\"}}"; + + G g = JSON.parseObject(text, G.class); + Assert.assertTrue(g.getA() instanceof B); + } + + public static class G { + + private A a; + + public A getA() { + return a; + } + + public void setA(A a) { + this.a = a; + } + + } + + @JSONType(mappingTo = B.class) + public static abstract class A { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + } + + public static class B extends A { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/ArrayDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/ArrayDeserializerTest.java new file mode 100755 index 0000000000..58d6a2a16e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/ArrayDeserializerTest.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt.parser.deser; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class ArrayDeserializerTest extends TestCase { + + public void test_null() throws Exception { + Assert.assertNull(JSON.parseObject("null", Object[].class)); + Assert.assertNull(JSON.parseObject("null", String[].class)); + Assert.assertNull(JSON.parseObject("null", VO[].class)); + Assert.assertNull(JSON.parseObject("null", VO[][].class)); + } + + public void test_0() throws Exception { + Assert.assertEquals(0, JSON.parseObject("[]", Object[].class).length); + Assert.assertEquals(0, JSON.parseObject("[]", Object[][].class).length); + Assert.assertEquals(0, JSON.parseObject("[]", Object[][][].class).length); + Assert.assertEquals(1, JSON.parseObject("[null]", Object[].class).length); + Assert.assertEquals(1, JSON.parseObject("[null]", Object[][].class).length); + Assert.assertEquals(1, JSON.parseObject("[[[[[[]]]]]]", Object[][].class).length); + Assert.assertEquals(1, JSON.parseObject("[null]", Object[][][].class).length); + Assert.assertEquals(null, JSON.parseObject("{\"value\":null}", VO.class).getValue()); + } + + public static class VO { + + private Object[] value; + + public Object[] getValue() { + return value; + } + + public void setValue(Object[] value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/ArrayLisMapDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/ArrayLisMapDeserializerTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/ArrayLisMapDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/ArrayLisMapDeserializerTest.java index c345d8c8d5..4fcf900111 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/ArrayLisMapDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/ArrayLisMapDeserializerTest.java @@ -1,10 +1,10 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.util.ArrayList; import java.util.List; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/ArrayListEnumFieldDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/ArrayListEnumFieldDeserializerTest.java old mode 100644 new mode 100755 similarity index 90% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/ArrayListEnumFieldDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/ArrayListEnumFieldDeserializerTest.java index 87348a5407..ac9158e9e2 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/ArrayListEnumFieldDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/ArrayListEnumFieldDeserializerTest.java @@ -1,10 +1,10 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/ArrayListStringDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/ArrayListStringDeserializerTest.java old mode 100644 new mode 100755 similarity index 81% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/ArrayListStringDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/ArrayListStringDeserializerTest.java index dae6cc94f8..a3e4303c72 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/ArrayListStringDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/ArrayListStringDeserializerTest.java @@ -1,10 +1,10 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -16,6 +16,23 @@ import com.alibaba.fastjson.parser.ParserConfig; public class ArrayListStringDeserializerTest extends TestCase { + public void test_null() throws Exception { + Assert.assertNull(JSON.parseObject("null", new TypeReference>() { + })); + + Assert.assertNull(JSON.parseArray("null", new Type[] {new TypeReference>() { + }.getType()})); + + Assert.assertNull(JSON.parseArray("null", Entity.class)); + Assert.assertNull(JSON.parseArray("null", Entity[].class)); + Assert.assertNull(JSON.parseArray("null")); + Assert.assertNull(JSON.parseObject("null")); + Assert.assertNull(JSON.parseObject("null", Object[].class)); + Assert.assertNull(JSON.parseObject("null", Entity[].class)); + + Assert.assertNull(JSON.parseArray("[null]", new Type[] {new TypeReference>() { + }.getType()}).get(0)); + } public void test_strings() throws Exception { Entity a = JSON.parseObject("{units:['NANOSECONDS', 'SECONDS', 3, null]}", Entity.class); diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/ArrayListTypeDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/ArrayListTypeDeserializerTest.java new file mode 100755 index 0000000000..1ecfb39ef8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/ArrayListTypeDeserializerTest.java @@ -0,0 +1,75 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class ArrayListTypeDeserializerTest extends TestCase { + + public void test_null_0() throws Exception { + Assert.assertNull(JSON.parseObject("null", new TypeReference>() { + })); + } + + public void test_null_1() throws Exception { + Assert.assertNull(JSON.parseObject("null", new TypeReference>() { + })); + } + + public void test_null_2() throws Exception { + Assert.assertNull(JSON.parseObject("{\"value\":null}", VO.class).getValue()); + } + + public void test_null_3() throws Exception { + Assert.assertNull(JSON.parseObject("{\"value\":null}", V1.class).getValue()); + } + + public void test_empty() throws Exception { + Assert.assertEquals(0, JSON.parseObject("[]", new TypeReference>() { + }).size()); + Assert.assertEquals(0, JSON.parseObject("[]", new TypeReference>() { + }).size()); + + Assert.assertEquals(0, JSON.parseObject("[]", new TypeReference>() { + }).size()); + + Assert.assertEquals(0, JSON.parseObject("{\"value\":[]}", VO.class).getValue().size()); + } + + public static class VO { + + private ArrayList value; + + public ArrayList getValue() { + return value; + } + + public void setValue(ArrayList value) { + this.value = value; + } + + } + + private static class V1 { + + private ArrayList value; + + public ArrayList getValue() { + return value; + } + + @SuppressWarnings("unused") + public void setValue(ArrayList value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/ArrayListTypeFieldTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/ArrayListTypeFieldTest.java old mode 100644 new mode 100755 similarity index 74% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/ArrayListTypeFieldTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/ArrayListTypeFieldTest.java index bebb56b900..43a69f14ab --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/ArrayListTypeFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/ArrayListTypeFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.util.ArrayList; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -20,6 +20,15 @@ public void test_1() throws Exception { Entity entity = JSON.parseObject("{list:[{value:3}]}", Entity.class, 0, Feature.AllowUnQuotedFieldNames); Assert.assertEquals(3, entity.getList().get(0).getValue()); } + + public void test_null() throws Exception { + Entity entity = JSON.parseObject("{list:null}", Entity.class, 0, Feature.AllowUnQuotedFieldNames); + Assert.assertEquals(null, entity.getList()); + } + public void test_null2() throws Exception { + Entity entity = JSON.parseObject("{list:[null]}", Entity.class, 0, Feature.AllowUnQuotedFieldNames); + Assert.assertEquals(null, entity.getList().get(0)); + } public void test_error_0() throws Exception { Exception error = null; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/BigDecimalDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/BigDecimalDeserializerTest.java old mode 100644 new mode 100755 similarity index 78% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/BigDecimalDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/BigDecimalDeserializerTest.java index 84ee97619e..67d35fc560 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/BigDecimalDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/BigDecimalDeserializerTest.java @@ -1,14 +1,15 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.math.BigDecimal; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.DefaultExtJSONParser; import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.BigDecimalDeserializer; +import com.alibaba.fastjson.serializer.BigDecimalCodec; public class BigDecimalDeserializerTest extends TestCase { @@ -21,6 +22,6 @@ public void test_bigdecimal() throws Exception { Assert.assertEquals(null, JSON.parseObject("null", BigDecimal.class)); DefaultExtJSONParser parser = new DefaultExtJSONParser("null", ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - Assert.assertEquals(null, BigDecimalDeserializer.instance.deserialze(parser, null)); + Assert.assertEquals(null, BigDecimalCodec.instance.deserialze(parser, null, null)); } } diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/BigDecimalTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/BigDecimalTest.java new file mode 100755 index 0000000000..82438da02b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/BigDecimalTest.java @@ -0,0 +1,49 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.math.BigDecimal; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class BigDecimalTest extends TestCase { + public void test_null () throws Exception { + Assert.assertNull(JSON.parseObject("null", VO.class)); + Assert.assertNull(JSON.parseObject("{value:null}", VO.class).getValue()); + Assert.assertNull(JSON.parseObject("{'value':null}", VO.class).getValue()); + Assert.assertNull(JSON.parseObject("{\"value\":null}", VO.class).getValue()); + Assert.assertNull(JSON.parseArray("null", BigDecimal.class)); + Assert.assertNull(JSON.parseObject("null", BigDecimal.class)); + } + + public void test_postfix () throws Exception { + Assert.assertEquals(new BigDecimal ("123"), JSON.parseObject("123L", BigDecimal.class)); + Assert.assertEquals(new BigDecimal ("123"), JSON.parseObject("123D", BigDecimal.class)); + Assert.assertEquals(new BigDecimal ("123"), JSON.parseObject("123F", BigDecimal.class)); + Assert.assertEquals(new BigDecimal ("123"), JSON.parseObject("123S", BigDecimal.class)); + Assert.assertEquals(new BigDecimal ("123"), JSON.parseObject("123B", BigDecimal.class)); + } + + public void test_className() throws Exception { + Assert.assertEquals("123.", JSON.toJSONString(new BigDecimal("123"), SerializerFeature.WriteClassName)); + Assert.assertEquals("123.00", JSON.toJSONString(new BigDecimal("123.00"), SerializerFeature.WriteClassName)); + Assert.assertEquals("123.45", JSON.toJSONString(new BigDecimal("123.45"), SerializerFeature.WriteClassName)); + Assert.assertEquals(new BigDecimal("123"), JSON.parse("123.")); + } + + public static class VO { + + private BigDecimal value; + + public BigDecimal getValue() { + return value; + } + + public void setValue(BigDecimal value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/BigIntegerDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/BigIntegerDeserializerTest.java new file mode 100755 index 0000000000..24b398ec7c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/BigIntegerDeserializerTest.java @@ -0,0 +1,73 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.math.BigInteger; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class BigIntegerDeserializerTest extends TestCase { + + public void test_1() throws Exception { + + BigInteger value = JSON.parseObject("'123'", BigInteger.class); + + Assert.assertEquals(new BigInteger("123"), value); + } + + public void test_vo() throws Exception { + + VO vo = JSON.parseObject("{\"value\":123}", VO.class); + + Assert.assertEquals(new BigInteger("123"), vo.getValue()); + } + + public void test_vo_null() throws Exception { + + VO vo = JSON.parseObject("{\"value\":null}", VO.class); + + Assert.assertEquals(null, vo.getValue()); + } + + public void test_vo2() throws Exception { + + VO2 vo = JSON.parseObject("{\"value\":123}", VO2.class); + + Assert.assertEquals(new BigInteger("123"), vo.getValue()); + } + + public void test_array() throws Exception { + List list = JSON.parseArray("[123,345]", BigInteger.class); + Assert.assertEquals(new BigInteger("123"), list.get(0)); + Assert.assertEquals(new BigInteger("345"), list.get(1)); + } + + public static class VO { + + private BigInteger value; + + public BigInteger getValue() { + return value; + } + + public void setValue(BigInteger value) { + this.value = value; + } + } + + private static class VO2 { + + private BigInteger value; + + public BigInteger getValue() { + return value; + } + + public void setValue(BigInteger value) { + this.value = value; + } + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/BooleanDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/BooleanDeserializerTest.java old mode 100644 new mode 100755 similarity index 57% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/BooleanDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/BooleanDeserializerTest.java index 58c96f5fff..d4470a9f5f --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/BooleanDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/BooleanDeserializerTest.java @@ -1,12 +1,14 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.BooleanDeserializer; +import com.alibaba.fastjson.serializer.BooleanCodec; public class BooleanDeserializerTest extends TestCase { @@ -23,8 +25,11 @@ public void test_boolean() throws Exception { Assert.assertEquals(null, JSON.parseObject("null", Boolean.class)); { - DefaultExtJSONParser parser = new DefaultExtJSONParser("null", ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - Assert.assertEquals(null, BooleanDeserializer.instance.deserialze(parser, null)); + DefaultJSONParser parser = new DefaultJSONParser("null", ParserConfig.getGlobalInstance(), + JSON.DEFAULT_PARSER_FEATURE); + Assert.assertEquals(null, BooleanCodec.instance.deserialze(parser, null, null)); + parser.close(); } + Assert.assertEquals(JSONToken.TRUE, BooleanCodec.instance.getFastMatchToken()); } } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/BooleanFieldDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/BooleanFieldDeserializerTest.java old mode 100644 new mode 100755 similarity index 90% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/BooleanFieldDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/BooleanFieldDeserializerTest.java index 4e9c4b0325..61bf2dab4a --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/BooleanFieldDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/BooleanFieldDeserializerTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/BooleanFieldDeserializerTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/BooleanFieldDeserializerTest2.java new file mode 100644 index 0000000000..2717fad9df --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/BooleanFieldDeserializerTest2.java @@ -0,0 +1,57 @@ +package com.alibaba.json.bvt.parser.deser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; + +public class BooleanFieldDeserializerTest2 extends TestCase { + + public void test_0() throws Exception { + Entity a = JSON.parseObject("{\"f1\":true,\"f2\":null}", Entity.class); + Assert.assertEquals(true, a.getF1()); + Assert.assertEquals(null, a.getF2()); + } + + public void test_1() throws Exception { + Entity a = JSON.parseObject("{\"f1\":1,\"f2\":null}", Entity.class); + Assert.assertEquals(true, a.getF1()); + Assert.assertEquals(null, a.getF2()); + } + + public void test_2() throws Exception { + Entity a = JSON.parseObject("{\"f1\":\"true\",\"f2\":null}", Entity.class); + Assert.assertEquals(true, a.getF1()); + Assert.assertEquals(null, a.getF2()); + } + + public void test_3() throws Exception { + Entity a = JSON.parseObject("{\"f1\":false,\"f2\":null}", Entity.class); + Assert.assertEquals(false, a.getF1()); + Assert.assertEquals(null, a.getF2()); + } + + public static class Entity { + + private final Boolean f1; + private final Boolean f2; + + @JSONCreator + public Entity(@JSONField(name = "f1") Boolean f1, @JSONField(name = "f2") Boolean f2){ + this.f1 = f1; + this.f2 = f2; + } + + public Boolean getF1() { + return f1; + } + + public Boolean getF2() { + return f2; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/CharArrayDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/CharArrayDeserializerTest.java new file mode 100755 index 0000000000..917104c53d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/CharArrayDeserializerTest.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.parser.deser; + +import com.alibaba.fastjson.JSON; + +import org.junit.Assert; +import junit.framework.TestCase; + +public class CharArrayDeserializerTest extends TestCase { + + public void test_charArray() throws Exception { + Assert.assertEquals(null, JSON.parseObject("{}", VO.class).getValue()); + Assert.assertEquals(null, JSON.parseObject("{value:null}", VO.class).getValue()); + Assert.assertEquals(null, JSON.parseObject("{'value':null}", VO.class).getValue()); + Assert.assertEquals(null, JSON.parseObject("{\"value\":null}", VO.class).getValue()); + Assert.assertEquals(0, JSON.parseObject("{\"value\":\"\"}", VO.class).getValue().length); + Assert.assertEquals(2, JSON.parseObject("{\"value\":\"ab\"}", VO.class).getValue().length); + Assert.assertEquals("ab", new String(JSON.parseObject("{\"value\":\"ab\"}", VO.class).getValue())); + Assert.assertEquals("12", new String(JSON.parseObject("{\"value\":12}", VO.class).getValue())); + Assert.assertEquals("12", new String(JSON.parseObject("{\"value\":12L}", VO.class).getValue())); + Assert.assertEquals("12", new String(JSON.parseObject("{\"value\":12S}", VO.class).getValue())); + Assert.assertEquals("12", new String(JSON.parseObject("{\"value\":12B}", VO.class).getValue())); + Assert.assertEquals("{}", new String(JSON.parseObject("{\"value\":{}}", VO.class).getValue())); + } + + public static class VO { + + private char[] value; + + public char[] getValue() { + return value; + } + + public void setValue(char[] value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/ClassTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/ClassTest.java new file mode 100755 index 0000000000..5c9ccefbeb --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/ClassTest.java @@ -0,0 +1,47 @@ +package com.alibaba.json.bvt.parser.deser; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class ClassTest extends TestCase { + + public void test_null() throws Exception { + Assert.assertNull(JSON.parseObject("null", Class.class)); + Assert.assertNull(JSON.parseObject("null", Class[].class)); + Assert.assertNull(JSON.parseArray("null", Class.class)); + Assert.assertNull(JSON.parseObject("{value:null}", VO.class).getValue()); + } + + public void test_primitive() throws Exception { + Assert.assertEquals(byte.class, JSON.parseObject("\"byte\"", Class.class)); + Assert.assertEquals(short.class, JSON.parseObject("\"short\"", Class.class)); + Assert.assertEquals(int.class, JSON.parseObject("\"int\"", Class.class)); + Assert.assertEquals(long.class, JSON.parseObject("\"long\"", Class.class)); + Assert.assertEquals(float.class, JSON.parseObject("\"float\"", Class.class)); + Assert.assertEquals(double.class, JSON.parseObject("\"double\"", Class.class)); + Assert.assertEquals(char.class, JSON.parseObject("\"char\"", Class.class)); + Assert.assertEquals(boolean.class, JSON.parseObject("\"boolean\"", Class.class)); + } + + public void test_array() throws Exception { + Assert.assertEquals(int[].class, JSON.parseObject("\"[int\"", Class.class)); + Assert.assertEquals(int[][].class, JSON.parseObject("\"[[int\"", Class.class)); + Assert.assertEquals(int[][][][].class, JSON.parseObject("\"[[[[int\"", Class.class)); + } + + public static class VO { + + private Class value; + + public Class getValue() { + return value; + } + + public void setValue(Class value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/CollectionDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/CollectionDeserializerTest.java new file mode 100755 index 0000000000..61c68f2ca4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/CollectionDeserializerTest.java @@ -0,0 +1,164 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.AbstractCollection; +import java.util.AbstractList; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.TreeSet; +import java.util.Vector; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class CollectionDeserializerTest extends TestCase { + public void test_set() throws Exception { + Assert.assertEquals(HashSet.class, JSON.parseObject("{value:[]}", VO.class).getValue().getClass()); + Assert.assertEquals(HashSet.class, JSON.parseObject("[]", Set.class).getClass()); + Assert.assertEquals(null, JSON.parseObject("{value:null}", VO.class).getValue()); + Assert.assertEquals(null, JSON.parseObject("null", Set.class)); + } + + public void test_hashset() throws Exception { + Assert.assertEquals(HashSet.class, JSON.parseObject("{value:[]}", V1.class).getValue().getClass()); + Assert.assertEquals(HashSet.class, JSON.parseObject("[]", HashSet.class).getClass()); + Assert.assertEquals(null, JSON.parseObject("{value:null}", V1.class).getValue()); + Assert.assertEquals(null, JSON.parseObject("null", HashSet.class)); + } + + public void test_linkedhashset() throws Exception { + Assert.assertEquals(LinkedHashSet.class, JSON.parseObject("{value:[]}", V2.class).getValue().getClass()); + Assert.assertEquals(LinkedHashSet.class, JSON.parseObject("[]", LinkedHashSet.class).getClass()); + Assert.assertEquals(null, JSON.parseObject("{value:null}", V2.class).getValue()); + Assert.assertEquals(null, JSON.parseObject("null", LinkedHashSet.class)); + } + + public void test_treeset() throws Exception { + Assert.assertEquals(TreeSet.class, JSON.parseObject("{value:[]}", V3.class).getValue().getClass()); + Assert.assertEquals(TreeSet.class, JSON.parseObject("[]", TreeSet.class).getClass()); + Assert.assertEquals(null, JSON.parseObject("{value:null}", V3.class).getValue()); + Assert.assertEquals(null, JSON.parseObject("null", TreeSet.class)); + } + + public void test_vector() throws Exception { + Assert.assertEquals(Vector.class, JSON.parseObject("{value:[]}", V4.class).getValue().getClass()); + Assert.assertEquals(Vector.class, JSON.parseObject("[]", Vector.class).getClass()); + Assert.assertEquals(null, JSON.parseObject("{value:null}", V4.class).getValue()); + Assert.assertEquals(null, JSON.parseObject("null", Vector.class)); + } + + public void test_AbstractList() throws Exception { + Assert.assertEquals(ArrayList.class, JSON.parseObject("{value:[]}", V5.class).getValue().getClass()); + Assert.assertEquals(ArrayList.class, JSON.parseObject("[]", AbstractList.class).getClass()); + Assert.assertEquals(null, JSON.parseObject("{value:null}", V5.class).getValue()); + Assert.assertEquals(null, JSON.parseObject("null", AbstractList.class)); + } + + public void test_AbstractCollection() throws Exception { + Assert.assertEquals(ArrayList.class, JSON.parseObject("{value:[]}", V6.class).getValue().getClass()); + Assert.assertEquals(ArrayList.class, JSON.parseObject("[]", AbstractCollection.class).getClass()); + Assert.assertEquals(null, JSON.parseObject("{value:null}", V6.class).getValue()); + Assert.assertEquals(null, JSON.parseObject("null", AbstractCollection.class)); + } + + public static class VO { + + private Set value; + + public Set getValue() { + return value; + } + + public void setValue(Set value) { + this.value = value; + } + + } + + public static class V1 { + + private HashSet value; + + public HashSet getValue() { + return value; + } + + public void setValue(HashSet value) { + this.value = value; + } + + } + + public static class V2 { + + private LinkedHashSet value; + + public LinkedHashSet getValue() { + return value; + } + + public void setValue(LinkedHashSet value) { + this.value = value; + } + + } + + public static class V3 { + + private TreeSet value; + + public TreeSet getValue() { + return value; + } + + public void setValue(TreeSet value) { + this.value = value; + } + + } + + public static class V4 { + + private Vector value; + + public Vector getValue() { + return value; + } + + public void setValue(Vector value) { + this.value = value; + } + + } + + public static class V5 { + + private AbstractList value; + + public AbstractList getValue() { + return value; + } + + public void setValue(AbstractList value) { + this.value = value; + } + + } + + public static class V6 { + + private AbstractCollection value; + + public AbstractCollection getValue() { + return value; + } + + public void setValue(AbstractCollection value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/CollectionFieldTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/CollectionFieldTest.java old mode 100644 new mode 100755 similarity index 90% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/CollectionFieldTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/CollectionFieldTest.java index e69a7121f8..d79df17128 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/CollectionFieldTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/CollectionFieldTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.util.Collection; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/ColorDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/ColorDeserializerTest.java new file mode 100755 index 0000000000..c6369aa188 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/ColorDeserializerTest.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.awt.Color; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.serializer.ColorCodec; + + +public class ColorDeserializerTest extends TestCase { + public void test_0 () throws Exception { + new ColorCodec().getFastMatchToken(); + } + + public void test_error() throws Exception { + Exception error = null; + try { + JSON.parseObject("[]", Color.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_1() throws Exception { + Exception error = null; + try { + JSON.parseObject("{33:44}", Color.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_2() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"r\":44.}", Color.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_3() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"x\":44}", Color.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/ConcurrentHashMapDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/ConcurrentHashMapDeserializerTest.java new file mode 100755 index 0000000000..8c970f1b61 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/ConcurrentHashMapDeserializerTest.java @@ -0,0 +1,47 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.IdentityHashMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class ConcurrentHashMapDeserializerTest extends TestCase { + @SuppressWarnings("rawtypes") + public void test_1 () throws Exception { + ConcurrentHashMap map = JSON.parseObject("{}", ConcurrentHashMap.class); + Assert.assertEquals(0, map.size()); + } + + @SuppressWarnings("rawtypes") + public void test_2() throws Exception { + ConcurrentMap map = JSON.parseObject("{}", ConcurrentMap.class); + Assert.assertEquals(0, map.size()); + } + + @SuppressWarnings("rawtypes") + public void test_className() throws Exception { + ConcurrentHashMap map = (ConcurrentHashMap) JSON.parse("{\"@type\":\"java.util.concurrent.ConcurrentHashMap\"}"); + Assert.assertEquals(0, map.size()); + } + + @SuppressWarnings("rawtypes") + public void test_className1() throws Exception { + IdentityHashMap map = (IdentityHashMap) JSON.parse("{\"@type\":\"java.util.IdentityHashMap\"}"); + Assert.assertEquals(0, map.size()); + } + + @SuppressWarnings("rawtypes") + public void test_className2() throws Exception { + IdentityHashMap map = (IdentityHashMap) JSON.parse("{\"@type\":\"java.util.IdentityHashMap\", \"id\":123}"); + Assert.assertEquals(1, map.size()); + } + + public void test_null () throws Exception { + Assert.assertEquals(null, JSON.parseObject("null", ConcurrentHashMap.class)); + Assert.assertEquals(null, JSON.parseObject("null", ConcurrentMap.class)); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/DateDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DateDeserializerTest.java old mode 100644 new mode 100755 similarity index 81% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/DateDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/DateDeserializerTest.java index cf9debcae5..6a9d5ef66c --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/DateDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DateDeserializerTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.util.Date; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DateFormatDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DateFormatDeserializerTest.java new file mode 100644 index 0000000000..ffb7e001c8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DateFormatDeserializerTest.java @@ -0,0 +1,67 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.text.SimpleDateFormat; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class DateFormatDeserializerTest extends TestCase { + + public void test_dateFormat_empty() throws Exception { + VO vo = JSON.parseObject("{\"format\":\"\"}", VO.class); + Assert.assertEquals(null, vo.getFormat()); + } + + public void test_dateFormat_array() throws Exception { + List list = JSON.parseArray("[\"\",null,\"yyyy\"]", SimpleDateFormat.class); + Assert.assertEquals(null, list.get(0)); + Assert.assertEquals(null, list.get(1)); + Assert.assertEquals(new SimpleDateFormat("yyyy"), list.get(2)); + } + + public void test_dateFormat_null() throws Exception { + VO vo = JSON.parseObject("{\"format\":null}", VO.class); + Assert.assertEquals(null, vo.getFormat()); + } + + public void test_dateFormat_yyyy() throws Exception { + VO vo = JSON.parseObject("{\"format\":\"yyyy\"}", VO.class); + Assert.assertEquals(new SimpleDateFormat("yyyy"), vo.getFormat()); + } + + public void test_dateFormat_error() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"format\":123}", VO.class); + } catch (Exception e) { + error = e; + } + Assert.assertNotNull(error); + } + + public static class VO { + + private SimpleDateFormat format; + + public VO(){ + + } + + public VO(SimpleDateFormat format){ + this.format = format; + } + + public SimpleDateFormat getFormat() { + return format; + } + + public void setFormat(SimpleDateFormat format) { + this.format = format; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest1.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest1.java new file mode 100644 index 0000000000..0d5ba1b754 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest1.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.Calendar; +import java.util.Date; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class DateParseTest1 extends TestCase { + public void test_date() throws Exception { + String text = "\"1979-07-14\""; + Date date = JSON.parseObject(text, Date.class); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + Assert.assertEquals(1979, calendar.get(Calendar.YEAR)); + Assert.assertEquals(6, calendar.get(Calendar.MONTH)); + Assert.assertEquals(14, calendar.get(Calendar.DAY_OF_MONTH)); + + Assert.assertEquals(0, calendar.get(Calendar.HOUR_OF_DAY)); + Assert.assertEquals(0, calendar.get(Calendar.MINUTE)); + Assert.assertEquals(0, calendar.get(Calendar.SECOND)); + Assert.assertEquals(0, calendar.get(Calendar.MILLISECOND)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest10.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest10.java new file mode 100644 index 0000000000..ad5802df20 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest10.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.text.SimpleDateFormat; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class DateParseTest10 extends TestCase { + + public void test_date() throws Exception { + String text = "{\"value\":\"1979-07-14\"}"; + VO vo = JSON.parseObject(text, VO.class); + Assert.assertEquals(vo.getValue(), new SimpleDateFormat("yyyy-MM-dd").parse("1979-07-14").getTime()); + } + + public static class VO { + + private long value; + + public long getValue() { + return value; + } + + public VO setValue(long value) { + this.value = value; + return this; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest11.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest11.java new file mode 100644 index 0000000000..f3d83ffbf9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest11.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.Date; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + +public class DateParseTest11 extends TestCase { + + public void test() throws Exception { + VO vo = JSON.parseObject("{\"date\":\"2012-04-01T12:04:05.555\"}", VO.class); + } + + public static class VO { + + private Date date; + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest12.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest12.java new file mode 100644 index 0000000000..a5f597f9af --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest12.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.Date; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class DateParseTest12 extends TestCase { + + public void test() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"date\":\"20129401\"", VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class VO { + + private Date date; + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest13.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest13.java new file mode 100644 index 0000000000..7884a5de59 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest13.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.Date; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class DateParseTest13 extends TestCase { + + public void test() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"date\":\"2012040125000a\"}", VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class VO { + + private Date date; + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest14.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest14.java new file mode 100644 index 0000000000..81c0cbac24 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest14.java @@ -0,0 +1,86 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.Date; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class DateParseTest14 extends TestCase { + + public void test_0_lt() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"date\":\"19790714130723#56\"}", VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_0_gt() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"date\":\"19790714130723A56\"}", VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_1_lt() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"date\":\"197907141307231#6\"}", VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_1_gt() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"date\":\"197907141307231A6\"}", VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_2_lt() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"date\":\"1979071413072315#\"}", VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_2_gt() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"date\":\"1979071413072315A\"}", VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class VO { + + private Date date; + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest2.java new file mode 100644 index 0000000000..8092d2b9cf --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest2.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.Calendar; +import java.util.Date; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class DateParseTest2 extends TestCase { + public void test_date() throws Exception { + String text = "\"1979-07-14 13:07:23\""; + Date date = JSON.parseObject(text, Date.class); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + Assert.assertEquals(1979, calendar.get(Calendar.YEAR)); + Assert.assertEquals(6, calendar.get(Calendar.MONTH)); + Assert.assertEquals(14, calendar.get(Calendar.DAY_OF_MONTH)); + + Assert.assertEquals(13, calendar.get(Calendar.HOUR_OF_DAY)); + Assert.assertEquals(7, calendar.get(Calendar.MINUTE)); + Assert.assertEquals(23, calendar.get(Calendar.SECOND)); + Assert.assertEquals(0, calendar.get(Calendar.MILLISECOND)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest3.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest3.java new file mode 100644 index 0000000000..379a2aa39c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest3.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.Calendar; +import java.util.Date; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class DateParseTest3 extends TestCase { + public void test_date() throws Exception { + String text = "\"1979-07-14 13:07:23.456\""; + Date date = JSON.parseObject(text, Date.class); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + Assert.assertEquals(1979, calendar.get(Calendar.YEAR)); + Assert.assertEquals(6, calendar.get(Calendar.MONTH)); + Assert.assertEquals(14, calendar.get(Calendar.DAY_OF_MONTH)); + + Assert.assertEquals(13, calendar.get(Calendar.HOUR_OF_DAY)); + Assert.assertEquals(7, calendar.get(Calendar.MINUTE)); + Assert.assertEquals(23, calendar.get(Calendar.SECOND)); + Assert.assertEquals(456, calendar.get(Calendar.MILLISECOND)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest4.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest4.java new file mode 100644 index 0000000000..4d88ca6778 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest4.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.Calendar; +import java.util.Date; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class DateParseTest4 extends TestCase { + public void test_date() throws Exception { + String text = "\"1979-07-14T13:07:23\""; + Date date = JSON.parseObject(text, Date.class); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + Assert.assertEquals(1979, calendar.get(Calendar.YEAR)); + Assert.assertEquals(6, calendar.get(Calendar.MONTH)); + Assert.assertEquals(14, calendar.get(Calendar.DAY_OF_MONTH)); + + Assert.assertEquals(13, calendar.get(Calendar.HOUR_OF_DAY)); + Assert.assertEquals(7, calendar.get(Calendar.MINUTE)); + Assert.assertEquals(23, calendar.get(Calendar.SECOND)); + Assert.assertEquals(0, calendar.get(Calendar.MILLISECOND)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest5.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest5.java new file mode 100644 index 0000000000..b09e839069 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest5.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.Calendar; +import java.util.Date; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class DateParseTest5 extends TestCase { + public void test_date() throws Exception { + String text = "\"1979-07-14T13:07:23.456\""; + Date date = JSON.parseObject(text, Date.class); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + Assert.assertEquals(1979, calendar.get(Calendar.YEAR)); + Assert.assertEquals(6, calendar.get(Calendar.MONTH)); + Assert.assertEquals(14, calendar.get(Calendar.DAY_OF_MONTH)); + + Assert.assertEquals(13, calendar.get(Calendar.HOUR_OF_DAY)); + Assert.assertEquals(7, calendar.get(Calendar.MINUTE)); + Assert.assertEquals(23, calendar.get(Calendar.SECOND)); + Assert.assertEquals(456, calendar.get(Calendar.MILLISECOND)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest6.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest6.java new file mode 100644 index 0000000000..c641726b09 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest6.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.Calendar; +import java.util.Date; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class DateParseTest6 extends TestCase { + public void test_date() throws Exception { + String text = "\"19790714\""; + Date date = JSON.parseObject(text, Date.class); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + Assert.assertEquals(1979, calendar.get(Calendar.YEAR)); + Assert.assertEquals(6, calendar.get(Calendar.MONTH)); + Assert.assertEquals(14, calendar.get(Calendar.DAY_OF_MONTH)); + + Assert.assertEquals(0, calendar.get(Calendar.HOUR_OF_DAY)); + Assert.assertEquals(0, calendar.get(Calendar.MINUTE)); + Assert.assertEquals(0, calendar.get(Calendar.SECOND)); + Assert.assertEquals(0, calendar.get(Calendar.MILLISECOND)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest7.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest7.java new file mode 100644 index 0000000000..6ead5e31d5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest7.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class DateParseTest7 extends TestCase { + public void test_date() throws Exception { + System.out.println(System.currentTimeMillis()); + + System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("1970-01-01 20:00:01").getTime()); + System.out.println(new Date().toString()); + + //1369273142603 + String text = "\"19790714130723\""; + Date date = JSON.parseObject(text, Date.class); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + Assert.assertEquals(1979, calendar.get(Calendar.YEAR)); + Assert.assertEquals(6, calendar.get(Calendar.MONTH)); + Assert.assertEquals(14, calendar.get(Calendar.DAY_OF_MONTH)); + + Assert.assertEquals(13, calendar.get(Calendar.HOUR_OF_DAY)); + Assert.assertEquals(7, calendar.get(Calendar.MINUTE)); + Assert.assertEquals(23, calendar.get(Calendar.SECOND)); + Assert.assertEquals(0, calendar.get(Calendar.MILLISECOND)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest8.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest8.java new file mode 100644 index 0000000000..36834fcb09 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest8.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class DateParseTest8 extends TestCase { + public void test_date() throws Exception { + System.out.println(System.currentTimeMillis()); + + System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("1970-01-01 20:00:01").getTime()); + System.out.println(new Date().toString()); + + //1369273142603 + String text = "\"19790714130723456\""; + Date date = JSON.parseObject(text, Date.class); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + Assert.assertEquals(1979, calendar.get(Calendar.YEAR)); + Assert.assertEquals(6, calendar.get(Calendar.MONTH)); + Assert.assertEquals(14, calendar.get(Calendar.DAY_OF_MONTH)); + + Assert.assertEquals(13, calendar.get(Calendar.HOUR_OF_DAY)); + Assert.assertEquals(7, calendar.get(Calendar.MINUTE)); + Assert.assertEquals(23, calendar.get(Calendar.SECOND)); + Assert.assertEquals(456, calendar.get(Calendar.MILLISECOND)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest9.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest9.java new file mode 100644 index 0000000000..e461a51adb --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DateParseTest9.java @@ -0,0 +1,43 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.Date; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.serializer.CalendarCodec; +import com.alibaba.json.bvt.parser.deser.DateParseTest14.VO; + + +public class DateParseTest9 extends TestCase { + public void test_date() throws Exception { + String text = "\"/Date(1242357713797+0800)/\""; + Date date = JSON.parseObject(text, Date.class); + Assert.assertEquals(date.getTime(), 1242357713797L); + + Assert.assertEquals(JSONToken.LITERAL_INT, CalendarCodec.instance.getFastMatchToken()); + } + + public void test_error() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"date\":\"/Date(1242357713797A0800)/\"}", VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_1() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"date\":\"/Date(1242357713797#0800)/\"}", VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DateTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DateTest.java new file mode 100644 index 0000000000..93de251979 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DateTest.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.ParserConfig; + +public class DateTest extends TestCase { + + public void test() throws Exception { + DefaultJSONParser parser = new DefaultJSONParser("{\"date\":\"2012/04-01\"}", ParserConfig.getGlobalInstance(), + 0); + parser.setDateFormat("yyyy/MM-dd"); + VO vo = parser.parseObject(VO.class); + + Assert.assertEquals(new SimpleDateFormat("yyyy/MM-dd").parse("2012/04-01"), vo.getDate()); + + parser.close(); + } + + public static class VO { + + private Date date; + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest10.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest10.java new file mode 100644 index 0000000000..41a8987a6c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest10.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.parser.deser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class DefaultObjectDeserializerTest10 extends TestCase { + + public void test_1() throws Exception { + T[] list = JSON.parseObject("[{}]", new TypeReference() { + }); + Assert.assertEquals(1, list.length); + Assert.assertNotNull(list[0]); + Assert.assertTrue(list[0] instanceof A); + } + + public static class A { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest11.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest11.java new file mode 100644 index 0000000000..d3e976c1fc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest11.java @@ -0,0 +1,32 @@ +package com.alibaba.json.bvt.parser.deser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.json.bvt.parser.deser.DefaultObjectDeserializerTest4.Entity; + +public class DefaultObjectDeserializerTest11 extends TestCase { + + public void test_0() throws Exception { + A a = new A(); + DefaultJSONParser parser = new DefaultJSONParser("{\"id\":123}", ParserConfig.getGlobalInstance()); + parser.parseObject(a); + } + + public static class A { + + private long id; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest12.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest12.java new file mode 100644 index 0000000000..c0547c1963 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest12.java @@ -0,0 +1,32 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.ParserConfig; + +public class DefaultObjectDeserializerTest12 extends TestCase { + + public void test_list() throws Exception { + A a = new A(); + DefaultJSONParser parser = new DefaultJSONParser("{\"values\":[]}", ParserConfig.getGlobalInstance()); + parser.parseObject(a); + parser.close(); + } + + public static class A { + + private List values; + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest2.java new file mode 100755 index 0000000000..072b319efa --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest2.java @@ -0,0 +1,51 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.HashMap; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentMap; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.ParserConfig; + +@SuppressWarnings("deprecation") +public class DefaultObjectDeserializerTest2 extends TestCase { + + + public void test_1() throws Exception { + String input = "{'map':{}}"; + DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); + + + SortedMap map = JSON.parseObject(input, new TypeReference>() { + }.getType()); + + Assert.assertEquals(TreeMap.class, map.get("map").getClass()); + } + + + + public void test_8() throws Exception { + String input = "{'map':{}}"; + + ConcurrentMap map = JSON.parseObject(input, new TypeReference>() { + }.getType()); + + Assert.assertEquals(HashMap.class, map.get("map").getClass()); + } + + public static interface Map1 extends Map { + + } + + public static class Map2 extends HashMap { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest3.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest3.java new file mode 100644 index 0000000000..e840e5a7e6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest3.java @@ -0,0 +1,18 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.HashMap; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +@SuppressWarnings("rawtypes") +public class DefaultObjectDeserializerTest3 extends TestCase { + + public void test_0() throws Exception { + HashMap o = (HashMap) JSON.parse("{\"@type\":\"java.lang.Cloneable\"}"); + Assert.assertEquals(0, o.size()); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/DefaultObjectDeserializerTest_3.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest4.java old mode 100644 new mode 100755 similarity index 88% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/DefaultObjectDeserializerTest_3.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest4.java index a35ccf0b98..fe928fc3e5 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/DefaultObjectDeserializerTest_3.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest4.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import junit.framework.TestCase; @@ -7,7 +7,7 @@ import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.ParserConfig; -public class DefaultObjectDeserializerTest_3 extends TestCase { +public class DefaultObjectDeserializerTest4 extends TestCase { public void test_0() throws Exception { DefaultExtJSONParser parser = new DefaultExtJSONParser("{\"id\":3, \"name\":\"xx\"}", ParserConfig.getGlobalInstance()); diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest5.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest5.java new file mode 100644 index 0000000000..e7935e6e38 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest5.java @@ -0,0 +1,83 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class DefaultObjectDeserializerTest5 extends TestCase { + + public void test_error() throws Exception { + Exception error = null; + try { + JSON.parseObject("[]", new TypeReference>() { + }); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_2() throws Exception { + Exception error = null; + try { + JSON.parseObject(",]", new TypeReference>() { + }); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_3() throws Exception { + Exception error = null; + try { + JSON.parseObject("[{},{\"$ref\":0}]", + new TypeReference>>() { + }); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_4() throws Exception { + Exception error = null; + try { + JSON.parseObject("[{},{\"$ref\":\"$[0]\",}]", + new TypeReference>>() { + }); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_0() throws Exception { + List> list = JSON.parseObject("[{},{\"$ref\":\"$[0]\"}]", + new TypeReference>>() { + }); + Assert.assertSame(list.get(0), list.get(1)); + } + + public void test_1() throws Exception { + Map> map = JSON.parseObject("{\"1\":{},\"2\":{\"$ref\":\"$\"}}", + new TypeReference>>() { + }); + Assert.assertSame(map, map.get("2")); + } + + public void test_2() throws Exception { + Map> map = JSON.parseObject("{\"1\":{},\"2\":{\"$ref\":\"..\"}}", + new TypeReference>>() { + }); + Assert.assertSame(map, map.get("2")); + } + + +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest6.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest6.java new file mode 100644 index 0000000000..4871cc6c8a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest6.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; + +public class DefaultObjectDeserializerTest6 extends TestCase { + + public void test_0() throws Exception { + Entity vo = JSON.parseObject("{\"value\":{\"1\":{},\"2\":{\"$ref\":\"$.value.1\"}}}", Entity.class); + Assert.assertSame(vo.getValue().get("1"), vo.getValue().get("2")); + } + + public void test_1() throws Exception { + Entity vo = JSON.parseObject("{\"value\":{\"1\":{},\"2\":{\"$ref\":\"..\"}}}", Entity.class); + Assert.assertSame(vo.getValue(), vo.getValue().get("2")); + } + + public static class Entity { + + private final Map> value; + + @JSONCreator + public Entity(@JSONField(name = "value") Map> value){ + this.value = value; + } + + public Map> getValue() { + return value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest7.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest7.java new file mode 100644 index 0000000000..af4e8081f5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest7.java @@ -0,0 +1,46 @@ +package com.alibaba.json.bvt.parser.deser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class DefaultObjectDeserializerTest7 extends TestCase { + + public void test_0() throws Exception { + VO vo = JSON.parseObject("{\"value\":[{\"id\":123}]}", new TypeReference>() { + }); + A a = vo.getValue()[0]; + Assert.assertEquals(123, a.getId()); + } + + public static class VO { + + private T[] value; + + public T[] getValue() { + return value; + } + + public void setValue(T[] value) { + this.value = value; + } + + } + + public static class A { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest8.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest8.java new file mode 100644 index 0000000000..f1bbfe3352 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest8.java @@ -0,0 +1,48 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class DefaultObjectDeserializerTest8 extends TestCase { + + public void test_1() throws Exception { + VO vo = JSON.parseObject("{\"value\":[{\"id\":123}]}", new TypeReference>() { + }); + Assert.assertNotNull(vo.getValue()[0]); + Assert.assertTrue(vo.getValue()[0] instanceof Map); + } + + public static class VO { + + private T[] value; + + public T[] getValue() { + return value; + } + + public void setValue(T[] value) { + this.value = value; + } + + } + + public static class A { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest9.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest9.java new file mode 100644 index 0000000000..f43b8502f1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest9.java @@ -0,0 +1,22 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class DefaultObjectDeserializerTest9 extends TestCase { + + public void test_1() throws Exception { + T[] list = JSON.parseObject("[{}]", new TypeReference() { + }); + Assert.assertEquals(1, list.length); + Assert.assertNotNull(list[0]); + Assert.assertTrue(list[0] instanceof Map); + } + +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/DefaultObjectDeserializerTest_collection.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest_collection.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/DefaultObjectDeserializerTest_collection.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest_collection.java index 4a692d2000..e20edec672 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/DefaultObjectDeserializerTest_collection.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DefaultObjectDeserializerTest_collection.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.util.HashMap; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DoubleArrayFieldDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DoubleArrayFieldDeserializerTest.java new file mode 100644 index 0000000000..348b7ce047 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DoubleArrayFieldDeserializerTest.java @@ -0,0 +1,31 @@ +package com.alibaba.json.bvt.parser.deser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class DoubleArrayFieldDeserializerTest extends TestCase { + + public void test_0() throws Exception { + Entity a = JSON.parseObject("{\"values\":[1,2]}", Entity.class); + Assert.assertTrue(1 == a.getValues()[0]); + Assert.assertTrue(2 == a.getValues()[1]); + } + + + public static class Entity { + + public double[] values; + + public double[] getValues() { + return values; + } + + public void setValues(double[] values) { + this.values = values; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/DoubleDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DoubleDeserializerTest.java old mode 100644 new mode 100755 similarity index 53% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/DoubleDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/DoubleDeserializerTest.java index f6e25dc820..a150966f81 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/DoubleDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DoubleDeserializerTest.java @@ -1,13 +1,14 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.DoubleDeserializer; +import com.alibaba.fastjson.parser.deserializer.NumberDeserializer; public class DoubleDeserializerTest extends TestCase { @@ -15,12 +16,12 @@ public void test_bigdecimal() throws Exception { Assert.assertEquals(0, JSON.parseObject("0", Double.class).intValue()); Assert.assertEquals(0, JSON.parseObject("0.0", Double.class).intValue()); Assert.assertEquals(0, JSON.parseObject("'0'", Double.class).intValue()); - + Assert.assertEquals(0, JSON.parseObject("'0'", double.class).intValue()); Assert.assertEquals(null, JSON.parseObject("null", Double.class)); - DefaultExtJSONParser parser = new DefaultExtJSONParser("null", ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - Assert.assertEquals(null, DoubleDeserializer.instance.deserialze(parser, null)); - Assert.assertEquals(JSONToken.LITERAL_INT, DoubleDeserializer.instance.getFastMatchToken()); + DefaultJSONParser parser = new DefaultJSONParser("null", ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); + Assert.assertEquals(null, NumberDeserializer.instance.deserialze(parser, null, null)); + Assert.assertEquals(JSONToken.LITERAL_INT, NumberDeserializer.instance.getFastMatchToken()); } } diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/DoubleFieldDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/DoubleFieldDeserializerTest.java new file mode 100644 index 0000000000..4598fccc70 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/DoubleFieldDeserializerTest.java @@ -0,0 +1,29 @@ +package com.alibaba.json.bvt.parser.deser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class DoubleFieldDeserializerTest extends TestCase { + + public void test_0() throws Exception { + Entity a = JSON.parseObject("{\"value\":123.45}", Entity.class); + Assert.assertTrue(123.45D == a.getValue()); + } + + public static class Entity { + + public Double value; + + public Double getValue() { + return value; + } + + public void setValue(Double value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/EnumTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/EnumTest.java old mode 100644 new mode 100755 similarity index 67% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/EnumTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/EnumTest.java index d28bb7bfad..424a2231e6 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/EnumTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/EnumTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.util.concurrent.TimeUnit; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -13,11 +13,15 @@ public class EnumTest extends TestCase { public void test_enum() throws Exception { Assert.assertNull(JSON.parseObject("''", TimeUnit.class)); } - + public void test_enum_1() throws Exception { Assert.assertEquals(E.A, JSON.parseObject("0", E.class)); } + public void test_enum_3() throws Exception { + Assert.assertEquals(E.A, JSON.parseObject("{value:0}", Entity.class).getValue()); + } + public void test_enum_2() throws Exception { Assert.assertEquals(E.A, JSON.parseObject("'A'", E.class)); } @@ -45,4 +49,27 @@ public void test_enum_error_2() throws Exception { public static enum E { A, B, C } + + public static class Entity { + + private E value; + + public Entity(){ + + } + + public Entity(E value){ + super(); + this.value = value; + } + + public E getValue() { + return value; + } + + public void setValue(E value) { + this.value = value; + } + + } } diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/FactoryTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FactoryTest.java new file mode 100755 index 0000000000..6eccc10829 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/FactoryTest.java @@ -0,0 +1,104 @@ +package com.alibaba.json.bvt.parser.deser; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; + +public class FactoryTest extends TestCase { + + public void test_factory() throws Exception { + VO vo = JSON.parseObject("{\"b\":true,\"i\":33,\"l\":34,\"f\":45.}", VO.class); + Assert.assertEquals(true, vo.isB()); + Assert.assertEquals(33, vo.getI()); + Assert.assertEquals(34L, vo.getL()); + Assert.assertTrue(45f == vo.getF()); + JSON.parseObject("{\"b\":1,\"i\":33,\"l\":34,\"f\":45.}", VO.class); + } + + public void test_factory1() throws Exception { + V1 vo = JSON.parseObject("{\"b\":true,\"i\":33,\"l\":34,\"f\":45.}", V1.class); + Assert.assertEquals(true, vo.isB()); + Assert.assertEquals(33, vo.getI()); + Assert.assertEquals(34L, vo.getL()); + Assert.assertTrue(45f == vo.getF()); + JSON.parseObject("{\"b\":1,\"i\":33,\"l\":34,\"f\":45.}", V1.class); + } + + public static class VO { + + private final boolean b; + private final int i; + private final long l; + private final float f; + + @JSONCreator + public VO(@JSONField(name = "b") boolean b, @JSONField(name = "i") int i, @JSONField(name = "l") long l, + @JSONField(name = "f") float f){ + super(); + this.b = b; + this.i = i; + this.l = l; + this.f = f; + } + + public float getF() { + return f; + } + + public boolean isB() { + return b; + } + + public int getI() { + return i; + } + + public long getL() { + return l; + } + + } + + public static class V1 { + + private boolean b; + private int i; + private long l; + private float f; + + private V1(boolean b) { + this.b = b; + } + + @JSONCreator + public static V1 create(@JSONField(name = "b") boolean b, @JSONField(name = "i") int i, + @JSONField(name = "l") long l, @JSONField(name = "f") float f) { + V1 v = new V1(b); + v.i = i; + v.l = l; + v.f = f; + + return v; + } + + public float getF() { + return f; + } + + public boolean isB() { + return b; + } + + public int getI() { + return i; + } + + public long getL() { + return l; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest.java old mode 100644 new mode 100755 similarity index 89% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest.java index c79104f5d9..14c5739446 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldDeserializerTest1.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest1.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldDeserializerTest1.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest1.java index 5122591fe8..03174a5ff4 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldDeserializerTest1.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest1.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldDeserializerTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest2.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldDeserializerTest2.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest2.java index 3ae8d3864e..15cea063c2 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldDeserializerTest2.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest2.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest3.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest3.java new file mode 100755 index 0000000000..a6c1bded06 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest3.java @@ -0,0 +1,59 @@ +package com.alibaba.json.bvt.parser.deser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.ParserConfig; + +public class FieldDeserializerTest3 extends TestCase { + + public void test_error_1() throws Exception { + Exception error = null; + try { + String input = "{\"value\":null}"; + int featureValues = 0; + DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), + featureValues); + + Entity object = new Entity(); + parser.parseObject(object); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_2() throws Exception { + Exception error = null; + try { + String input = "{,,\"value\":null}"; + int featureValues = 0; + DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), + featureValues); + + Entity object = new Entity(); + parser.parseObject(object); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + private static class Entity { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + throw new RuntimeException(); + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest5.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest5.java new file mode 100755 index 0000000000..1bac0654f7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldDeserializerTest5.java @@ -0,0 +1,23 @@ +package com.alibaba.json.bvt.parser.deser; + +import com.alibaba.fastjson.JSON; + +import org.junit.Assert; +import junit.framework.TestCase; + + +public class FieldDeserializerTest5 extends TestCase { + public void test_0 () throws Exception { + Assert.assertEquals(33, JSON.parseObject("{\"id\":33}", VO.class).id); + Assert.assertEquals(33, JSON.parseObject("{\"id\":33}", V1.class).id); + Assert.assertEquals(33, JSON.parseObject("{\"id\":33L}", V1.class).id); + } + + public static class VO { + public int id; + } + + private static class V1 { + public int id; + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldSerializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldSerializerTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldSerializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/FieldSerializerTest.java index 4710860fbd..6d775e49d2 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldSerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldSerializerTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldSerializerTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldSerializerTest2.java old mode 100644 new mode 100755 similarity index 97% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldSerializerTest2.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/FieldSerializerTest2.java index 9f61cf69e1..687289f983 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldSerializerTest2.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldSerializerTest2.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONException; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldSerializerTest3.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldSerializerTest3.java old mode 100644 new mode 100755 similarity index 97% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldSerializerTest3.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/FieldSerializerTest3.java index 7366c985e2..346c526cfd --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldSerializerTest3.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/FieldSerializerTest3.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONException; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FloatDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FloatDeserializerTest.java old mode 100644 new mode 100755 similarity index 70% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/FloatDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/FloatDeserializerTest.java index 11a1e8e5f6..35b4987480 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FloatDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/FloatDeserializerTest.java @@ -1,13 +1,14 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.DefaultExtJSONParser; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.FloatDeserializer; +import com.alibaba.fastjson.serializer.FloatCodec; public class FloatDeserializerTest extends TestCase { @@ -19,8 +20,8 @@ public void test_bigdecimal() throws Exception { Assert.assertEquals(null, JSON.parseObject("null", Float.class)); DefaultExtJSONParser parser = new DefaultExtJSONParser("null", ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - Assert.assertEquals(null, FloatDeserializer.instance.deserialze(parser, null)); - Assert.assertEquals(JSONToken.LITERAL_INT, FloatDeserializer.instance.getFastMatchToken()); + Assert.assertEquals(null, FloatCodec.instance.deserialze(parser, null, null)); + Assert.assertEquals(JSONToken.LITERAL_INT, FloatCodec.instance.getFastMatchToken()); } } diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/FontDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/FontDeserializerTest.java new file mode 100755 index 0000000000..5300fbdaa7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/FontDeserializerTest.java @@ -0,0 +1,97 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.awt.Font; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.serializer.FontCodec; + + +public class FontDeserializerTest extends TestCase { + public void test_0 () throws Exception { + FontCodec.instance.getFastMatchToken(); + + Assert.assertNull(JSON.parseObject("null", StackTraceElement.class)); + Assert.assertNull(JSON.parseArray("null", StackTraceElement.class)); + Assert.assertNull(JSON.parseArray("[null]", StackTraceElement.class).get(0)); + Assert.assertNull(JSON.parseObject("{\"value\":null}", VO.class).getValue()); + } + + public void test_stack_error_0() throws Exception { + Exception error = null; + try { + JSON.parseObject("[]", Font.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_1() throws Exception { + Exception error = null; + try { + JSON.parseObject("{33:22}", Font.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_2() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"name\":22}", Font.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_3() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"style\":true}", Font.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_4() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"size\":\"33\"}", Font.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_5() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"xxx\":22}", Font.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class VO { + + private Font value; + + public Font getValue() { + return value; + } + + public void setValue(Font value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/GenericTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/GenericTest.java new file mode 100644 index 0000000000..483b609030 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/GenericTest.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt.parser.deser; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + + +public class GenericTest extends TestCase { + + public void test_0 () throws Exception { + B b = JSON.parseObject("{\"data\":[1,2,3]}", B.class); + b.get(0); + } + + public static abstract class A { + T[] data; + + public A() { + + } + + + + public T[] getData() { + return data; + } + + + + public void setData(T[] data) { + this.data = data; + } + } + + public static class B extends A { + public B() { + } + + public Long get(int index) { + Long l = data[index]; + return l; + } + } + + public static class C { + private T[] data; + + public C(T[] data) { + this.data = data; + } + + + public T[] getData() { + return data; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/GetOnlyCollectionTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/GetOnlyCollectionTest.java new file mode 100755 index 0000000000..65eca0bbf7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/GetOnlyCollectionTest.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.fastjson.JSON; + +import org.junit.Assert; +import junit.framework.TestCase; + +public class GetOnlyCollectionTest extends TestCase { + + public void test_getOnly() throws Exception { + VO vo = JSON.parseObject("{\"items\":[\"a\",\"b\"]}", VO.class); + Assert.assertEquals(2, vo.getItems().size()); + Assert.assertEquals("a", vo.getItems().get(0)); + Assert.assertEquals("b", vo.getItems().get(1)); + } + + public static class VO { + private final List items = new ArrayList(); + + public List getItems() { + return items; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/HashtableFieldTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/HashtableFieldTest.java new file mode 100644 index 0000000000..196d8d12dc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/HashtableFieldTest.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.Hashtable; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class HashtableFieldTest extends TestCase { + + public void test_null() throws Exception { + Entity value = JSON.parseObject("{value:null}", Entity.class); + Assert.assertNull(value.getValue()); + } + + public void test_empty() throws Exception { + Entity value = JSON.parseObject("{value:{}}", Entity.class); + Assert.assertEquals(0, value.getValue().size()); + } + + public void test_null_2() throws Exception { + Entity value = JSON.parseObject("{\"value\":null}", Entity.class); + Assert.assertNull(value.getValue()); + } + + public void test_empty_a() throws Exception { + A value = JSON.parseObject("{value:{\"@type\":\"java.util.Hashtable\"}}", A.class); + Assert.assertEquals(0, ((Hashtable)value.getValue()).size()); + } + + private static class Entity { + + private Hashtable value; + + public Hashtable getValue() { + return value; + } + + public void setValue(Hashtable value) { + this.value = value; + } + } + + private static class A { + + private Object value; + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/InetAddressDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/InetAddressDeserializerTest.java old mode 100644 new mode 100755 similarity index 65% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/InetAddressDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/InetAddressDeserializerTest.java index 790372c783..3faade1f93 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/InetAddressDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/InetAddressDeserializerTest.java @@ -1,13 +1,14 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.DefaultExtJSONParser; import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.InetAddressDeserializer; -import com.alibaba.fastjson.parser.deserializer.StringDeserializer; +import com.alibaba.fastjson.serializer.InetAddressCodec; +import com.alibaba.fastjson.serializer.StringCodec; public class InetAddressDeserializerTest extends TestCase { @@ -15,31 +16,31 @@ public void test_null() throws Exception { String input = "null"; DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - InetAddressDeserializer deser = new InetAddressDeserializer(); + InetAddressCodec deser = new InetAddressCodec(); - Assert.assertNull(deser.deserialze(parser, null)); + Assert.assertNull(deser.deserialze(parser, null, null)); } public void test_string_null() throws Exception { String input = "null"; DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - StringDeserializer deser = new StringDeserializer(); + StringCodec deser = new StringCodec(); - Assert.assertNull(deser.deserialze(parser, null)); + Assert.assertNull(deser.deserialze(parser, null, null)); } public void test_error_0() throws Exception { String input = "'[&中国-^]'"; DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - InetAddressDeserializer deser = new InetAddressDeserializer(); + InetAddressCodec deser = new InetAddressCodec(); Throwable error = null; Object value = null; try { - value = deser.deserialze(parser, null); + value = deser.deserialze(parser, null, null); } catch (Throwable ex) { error = ex; } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/IntegerDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerDeserializerTest.java old mode 100644 new mode 100755 similarity index 70% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/IntegerDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/IntegerDeserializerTest.java index 036a795821..a67a1c97af --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/IntegerDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerDeserializerTest.java @@ -1,13 +1,14 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.DefaultExtJSONParser; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.IntegerDeserializer; +import com.alibaba.fastjson.serializer.IntegerCodec; public class IntegerDeserializerTest extends TestCase { @@ -19,7 +20,7 @@ public void test_bigdecimal() throws Exception { Assert.assertEquals(null, JSON.parseObject("null", Integer.class)); DefaultExtJSONParser parser = new DefaultExtJSONParser("null", ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - Assert.assertEquals(null, IntegerDeserializer.instance.deserialze(parser, null)); - Assert.assertEquals(JSONToken.LITERAL_INT, IntegerDeserializer.instance.getFastMatchToken()); + Assert.assertEquals(null, IntegerCodec.instance.deserialze(parser, null, null)); + Assert.assertEquals(JSONToken.LITERAL_INT, IntegerCodec.instance.getFastMatchToken()); } } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/IntegerFieldDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerFieldDeserializerTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/IntegerFieldDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/IntegerFieldDeserializerTest.java index 9ae932b0b0..16e94db729 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/IntegerFieldDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerFieldDeserializerTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerFieldDeserializerTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerFieldDeserializerTest2.java new file mode 100644 index 0000000000..9f4c45ceb1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerFieldDeserializerTest2.java @@ -0,0 +1,73 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class IntegerFieldDeserializerTest2 extends TestCase { + + protected void setUp() throws Exception { +// ParserConfig.getGlobalInstance().setAsmEnable(false); + } + + public void test_integer() throws Exception { + String text = "{\"value\":{\"column1\":\"aa\"}}"; + Map map = JSON.parseObject(text, new TypeReference>(){}); + Assert.assertNotNull(map); + Assert.assertNotNull(map.get("value")); + Assert.assertNotNull("aa", map.get("value").getColumn1()); + } + + public void test_integer_2() throws Exception { + String text = "[{\"value\":{\"column1\":\"aa\"}}]"; + List> mapList = JSON.parseObject(text, new TypeReference>>(){}); + Map map = mapList.get(0); + Assert.assertNotNull(map); + Assert.assertNotNull(map.get("value")); + Assert.assertNotNull("aa", map.get("value").getColumn1()); + } + + public void test_integer_3() throws Exception { + String text = "{\"value\":{\"valueA\":{\"column1\":\"aa\"}, \"valueB\":{\"column1\":\"bb\"}}}"; + Map> mapmap = JSON.parseObject(text, new TypeReference>>(){}); + Map map = mapmap.get("value"); + Assert.assertNotNull(map); + Assert.assertNotNull(map.get("valueA")); + Assert.assertNotNull("aa", map.get("valueA").getColumn1()); + Assert.assertNotNull(map.get("valueB")); + Assert.assertNotNull("bb", map.get("valueB").getColumn1()); + } + + public static class Entity implements Serializable { + private static final long serialVersionUID = 1L; + private String column1; + private Integer column3; + + public String getColumn1() { + return column1; + } + + public void setColumn1(String column1) { + this.column1 = column1; + } + + public Integer getColumn3() { + return column3; + } + + public void setColumn3(Integer column3) { + this.column3 = column3; + } + } + + public static class Value { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerFieldDeserializerTest3.java b/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerFieldDeserializerTest3.java new file mode 100644 index 0000000000..47eb45a0dd --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerFieldDeserializerTest3.java @@ -0,0 +1,51 @@ +package com.alibaba.json.bvt.parser.deser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; + +public class IntegerFieldDeserializerTest3 extends TestCase { + + public void test_0() throws Exception { + Entity a = JSON.parseObject("{f1:123, f2:null}", Entity.class); + Assert.assertEquals(123, a.getF1()); + Assert.assertEquals(null, a.getF2()); + } + + public void test_1() throws Exception { + Entity a = JSON.parseObject("{f1:22, f2:'33'}", Entity.class); + Assert.assertEquals(22, a.getF1()); + Assert.assertEquals(33, a.getF2().intValue()); + } + + public void test_2() throws Exception { + Entity a = JSON.parseObject("{f1:'22', f2:33}", Entity.class); + Assert.assertEquals(22, a.getF1()); + Assert.assertEquals(33, a.getF2().intValue()); + } + + public static class Entity { + + private int f1 = 124; + private Integer f2 = 123; + + @JSONCreator + public Entity(@JSONField(name="f1") int f1, @JSONField(name="f2") Integer f2){ + this.f1 = f1; + this.f2 = f2; + } + + public int getF1() { + return f1; + } + + public Integer getF2() { + return f2; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerParseTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerParseTest.java new file mode 100755 index 0000000000..495d12bd87 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/IntegerParseTest.java @@ -0,0 +1,77 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class IntegerParseTest extends TestCase { + public void test_l () throws Exception { + Assert.assertEquals(Long.valueOf(12), JSON.parseObject("12L", long.class)); + Assert.assertEquals(Integer.valueOf(12), JSON.parseObject("12L", int.class)); + Assert.assertEquals(new Short((short) 12), JSON.parseObject("12L", short.class)); + Assert.assertEquals(new Byte((byte) 12), JSON.parseObject("12L", byte.class)); + Assert.assertEquals(new Float(12), JSON.parseObject("12L", float.class)); + Assert.assertEquals(new Double(12), JSON.parseObject("12L", double.class)); + Assert.assertEquals(new BigDecimal(12), JSON.parseObject("12L", BigDecimal.class)); + Assert.assertEquals(new BigInteger("12"), JSON.parseObject("12L", BigInteger.class)); + } + + public void test_s () throws Exception { + Assert.assertEquals(Long.valueOf(12), JSON.parseObject("12S", long.class)); + Assert.assertEquals(Integer.valueOf(12), JSON.parseObject("12S", int.class)); + Assert.assertEquals(new Short((short) 12), JSON.parseObject("12S", short.class)); + Assert.assertEquals(new Byte((byte) 12), JSON.parseObject("12S", byte.class)); + Assert.assertEquals(new Float(12), JSON.parseObject("12S", float.class)); + Assert.assertEquals(new Double(12), JSON.parseObject("12S", double.class)); + Assert.assertEquals(new BigDecimal(12), JSON.parseObject("12S", BigDecimal.class)); + Assert.assertEquals(new BigInteger("12"), JSON.parseObject("12S", BigInteger.class)); + } + + public void test_b () throws Exception { + Assert.assertEquals(Long.valueOf(12), JSON.parseObject("12B", long.class)); + Assert.assertEquals(Integer.valueOf(12), JSON.parseObject("12B", int.class)); + Assert.assertEquals(new Short((short) 12), JSON.parseObject("12B", short.class)); + Assert.assertEquals(new Byte((byte) 12), JSON.parseObject("12B", byte.class)); + Assert.assertEquals(new Float(12), JSON.parseObject("12B", float.class)); + Assert.assertEquals(new Double(12), JSON.parseObject("12B", double.class)); + Assert.assertEquals(new BigDecimal(12), JSON.parseObject("12B", BigDecimal.class)); + Assert.assertEquals(new BigInteger("12"), JSON.parseObject("12B", BigInteger.class)); + } + + public void test_f () throws Exception { + Assert.assertEquals(Long.valueOf(12), JSON.parseObject("12F", long.class)); + Assert.assertEquals(Integer.valueOf(12), JSON.parseObject("12F", int.class)); + Assert.assertEquals(new Short((short) 12), JSON.parseObject("12F", short.class)); + Assert.assertEquals(new Byte((byte) 12), JSON.parseObject("12F", byte.class)); + Assert.assertEquals(new Float(12), JSON.parseObject("12F", float.class)); + Assert.assertEquals(new Double(12), JSON.parseObject("12F", double.class)); + Assert.assertEquals(new BigDecimal(12), JSON.parseObject("12F", BigDecimal.class)); + Assert.assertEquals(new BigInteger("12"), JSON.parseObject("12F", BigInteger.class)); + } + + public void test_d () throws Exception { + Assert.assertEquals(Long.valueOf(12), JSON.parseObject("12D", long.class)); + Assert.assertEquals(Integer.valueOf(12), JSON.parseObject("12D", int.class)); + Assert.assertEquals(new Short((short) 12), JSON.parseObject("12D", short.class)); + Assert.assertEquals(new Byte((byte) 12), JSON.parseObject("12D", byte.class)); + Assert.assertEquals(new Float(12), JSON.parseObject("12D", float.class)); + Assert.assertEquals(new Double(12), JSON.parseObject("12D", double.class)); + Assert.assertEquals(new BigDecimal(12), JSON.parseObject("12D", BigDecimal.class)); + Assert.assertEquals(new BigInteger("12"), JSON.parseObject("12D", BigInteger.class)); + } + + public void test_m () throws Exception { + Assert.assertEquals(Long.valueOf(12), JSON.parseObject("12.", long.class)); + Assert.assertEquals(Integer.valueOf(12), JSON.parseObject("12.", int.class)); + Assert.assertEquals(new Short((short) 12), JSON.parseObject("12.", short.class)); + Assert.assertEquals(new Byte((byte) 12), JSON.parseObject("12.", byte.class)); + Assert.assertEquals(new Float(12), JSON.parseObject("12.", float.class)); + Assert.assertEquals(new Double(12), JSON.parseObject("12.", double.class)); + Assert.assertEquals(new BigDecimal(12), JSON.parseObject("12.", BigDecimal.class)); + Assert.assertEquals(new BigInteger("12"), JSON.parseObject("12.", BigInteger.class)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/InterfaceParseTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/InterfaceParseTest.java new file mode 100755 index 0000000000..235d3a415f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/InterfaceParseTest.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.parser.deser; + +import com.alibaba.fastjson.JSON; + +import org.junit.Assert; +import junit.framework.TestCase; + + +public class InterfaceParseTest extends TestCase { + public void test_interface() throws Exception { + VO vo = JSON.parseObject("{\"text\":\"abc\",\"b\":true}", VO.class); + Assert.assertEquals("abc", vo.getText()); + Assert.assertEquals(Boolean.TRUE, vo.getB()); + } + + public static interface VO { + void setText(String val); + String getText(); + + void setB(Boolean val); + Boolean getB(); + + void setI(int value); + void setC(char value); + void setS(short value); + void setL(long value); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/LocaleTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/LocaleTest.java old mode 100644 new mode 100755 similarity index 80% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/LocaleTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/LocaleTest.java index f1b9c3caa4..348c5d16e6 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/LocaleTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/LocaleTest.java @@ -1,14 +1,15 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.util.Locale; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.DefaultExtJSONParser; import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.LocaleDeserializer; +import com.alibaba.fastjson.serializer.LocaleCodec; public class LocaleTest extends TestCase { @@ -33,8 +34,8 @@ public void test_null() throws Exception { String input = "null"; DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - LocaleDeserializer deser = new LocaleDeserializer(); + LocaleCodec deser = new LocaleCodec(); - Assert.assertNull(deser.deserialze(parser, null)); + Assert.assertNull(deser.deserialze(parser, null, null)); } } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/LongDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/LongDeserializerTest.java old mode 100644 new mode 100755 similarity index 70% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/LongDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/LongDeserializerTest.java index 63b55588a9..6a3a60b222 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/LongDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/LongDeserializerTest.java @@ -1,13 +1,14 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.DefaultExtJSONParser; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.LongDeserializer; +import com.alibaba.fastjson.serializer.LongCodec; public class LongDeserializerTest extends TestCase { @@ -19,7 +20,7 @@ public void test_bigdecimal() throws Exception { Assert.assertEquals(null, JSON.parseObject("null", Long.class)); DefaultExtJSONParser parser = new DefaultExtJSONParser("null", ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - Assert.assertEquals(null, LongDeserializer.instance.deserialze(parser, null)); - Assert.assertEquals(JSONToken.LITERAL_INT, LongDeserializer.instance.getFastMatchToken()); + Assert.assertEquals(null, LongCodec.instance.deserialze(parser, null, null)); + Assert.assertEquals(JSONToken.LITERAL_INT, LongCodec.instance.getFastMatchToken()); } } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/LongFieldDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/LongFieldDeserializerTest.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/LongFieldDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/LongFieldDeserializerTest.java index 277f92ffb5..1262b198b0 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/LongFieldDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/LongFieldDeserializerTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.util.UUID; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/LongFieldDeserializerTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/LongFieldDeserializerTest2.java new file mode 100644 index 0000000000..880a1ba4c7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/LongFieldDeserializerTest2.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class LongFieldDeserializerTest2 extends TestCase { + + protected void setUp() throws Exception { +// ParserConfig.getGlobalInstance().setAsmEnable(false); + } + + public void test_integer() throws Exception { + String text = "{\"value\":{\"column1\":\"aa\"}}"; + Map map = JSON.parseObject(text, new TypeReference>(){}); + Assert.assertNotNull(map); + Assert.assertNotNull(map.get("value")); + Assert.assertNotNull("aa", map.get("value").getColumn1()); + } + + public void test_integer_2() throws Exception { + String text = "[{\"value\":{\"column1\":\"aa\"}}]"; + List> mapList = JSON.parseObject(text, new TypeReference>>(){}); + Map map = mapList.get(0); + Assert.assertNotNull(map); + Assert.assertNotNull(map.get("value")); + Assert.assertNotNull("aa", map.get("value").getColumn1()); + } + + public static class Entity implements Serializable { + private static final long serialVersionUID = 1L; + private String column1; + private Long column3; + + public String getColumn1() { + return column1; + } + + public void setColumn1(String column1) { + this.column1 = column1; + } + + public Long getColumn3() { + return column3; + } + + public void setColumn3(Long column3) { + this.column3 = column3; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/LongFieldDeserializerTest3.java b/src/test/java/com/alibaba/json/bvt/parser/deser/LongFieldDeserializerTest3.java new file mode 100644 index 0000000000..74e7e116bd --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/LongFieldDeserializerTest3.java @@ -0,0 +1,51 @@ +package com.alibaba.json.bvt.parser.deser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; + +public class LongFieldDeserializerTest3 extends TestCase { + + public void test_0() throws Exception { + Entity a = JSON.parseObject("{f1:123, f2:null}", Entity.class); + Assert.assertEquals(123L, a.getF1()); + Assert.assertEquals(null, a.getF2()); + } + + public void test_1() throws Exception { + Entity a = JSON.parseObject("{f1:22, f2:'33'}", Entity.class); + Assert.assertEquals(22L, a.getF1()); + Assert.assertEquals(33L, a.getF2().intValue()); + } + + public void test_2() throws Exception { + Entity a = JSON.parseObject("{f1:'22', f2:33}", Entity.class); + Assert.assertEquals(22L, a.getF1()); + Assert.assertEquals(33L, a.getF2().intValue()); + } + + public static class Entity { + + private long f1 = 124; + private Long f2 = 123L; + + @JSONCreator + public Entity(@JSONField(name = "f1") long f1, @JSONField(name = "f2") Long f2){ + this.f1 = f1; + this.f2 = f2; + } + + public long getF1() { + return f1; + } + + public Long getF2() { + return f2; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/MapDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/MapDeserializerTest.java new file mode 100644 index 0000000000..78aefce80f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/MapDeserializerTest.java @@ -0,0 +1,21 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class MapDeserializerTest extends TestCase { + + public void test_0() throws Exception { + JSON.parseObject("{\"@type\":\"com.alibaba.json.bvt.parser.deser.MapDeserializerTest$MyMap\"}", Map.class); + } + + public static class MyMap extends HashMap { + public MyMap () { + + } + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/MapTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/MapTest.java old mode 100644 new mode 100755 similarity index 90% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/MapTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/MapTest.java index 95377815db..a0d7ec79f0 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/MapTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/MapTest.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.math.BigDecimal; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/MultiArrayTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/MultiArrayTest.java old mode 100644 new mode 100755 similarity index 88% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/MultiArrayTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/MultiArrayTest.java index fd3ec2ec74..19f212394d --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/MultiArrayTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/MultiArrayTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/MyMapFieldTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/MyMapFieldTest.java new file mode 100644 index 0000000000..198fc99234 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/MyMapFieldTest.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.HashMap; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class MyMapFieldTest extends TestCase { + + public void test_null() throws Exception { + Entity value = JSON.parseObject("{value:null}", Entity.class); + Assert.assertNull(value.getValue()); + } + + public void test_empty() throws Exception { + Exception error = null; + try { + JSON.parseObject("{value:{}}", Entity.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + private static class Entity { + + private MyMap value; + + public MyMap getValue() { + return value; + } + + public void setValue(MyMap value) { + this.value = value; + } + } + + public class MyMap extends HashMap { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/NumberDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/NumberDeserializerTest.java new file mode 100755 index 0000000000..516a5c5dad --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/NumberDeserializerTest.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.parser.deser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class NumberDeserializerTest extends TestCase { + + public void test_byte() throws Exception { + Assert.assertEquals(Byte.valueOf((byte) 123), JSON.parseObject("\"123\"", byte.class)); + Assert.assertEquals(Byte.valueOf((byte) 123), JSON.parseObject("\"123\"", Byte.class)); + } + + public void test_byte1() throws Exception { + Assert.assertEquals(Byte.valueOf((byte) 123), JSON.parseObject("123.", byte.class)); + Assert.assertEquals(Byte.valueOf((byte) 123), JSON.parseObject("123.", Byte.class)); + } + + public void test_short() throws Exception { + Assert.assertEquals(Short.valueOf((short) 123), JSON.parseObject("\"123\"", short.class)); + Assert.assertEquals(Short.valueOf((short) 123), JSON.parseObject("\"123\"", Short.class)); + } + + public void test_short1() throws Exception { + Assert.assertEquals(Short.valueOf((short) 123), JSON.parseObject("123.", short.class)); + Assert.assertEquals(Short.valueOf((short) 123), JSON.parseObject("123.", Short.class)); + } + + public void test_double() throws Exception { + Assert.assertTrue(123.0D == JSON.parseObject("123.", double.class)); + Assert.assertTrue(123.0D == JSON.parseObject("123.", Double.class).doubleValue()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/NumberDeserializerTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/NumberDeserializerTest2.java new file mode 100644 index 0000000000..e67680c3a8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/NumberDeserializerTest2.java @@ -0,0 +1,15 @@ +package com.alibaba.json.bvt.parser.deser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class NumberDeserializerTest2 extends TestCase { + + public void test_double2() throws Exception { + Assert.assertTrue(123.0D == JSON.parseObject("123B", double.class)); + Assert.assertTrue(123.0D == JSON.parseObject("123B", Double.class).doubleValue()); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/PatternDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/PatternDeserializerTest.java old mode 100644 new mode 100755 similarity index 67% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/PatternDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/PatternDeserializerTest.java index 0ce0754a59..3ecc3c2b6e --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/PatternDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/PatternDeserializerTest.java @@ -1,15 +1,16 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.util.regex.Pattern; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.DefaultExtJSONParser; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.PatternDeserializer; +import com.alibaba.fastjson.serializer.PatternCodec; public class PatternDeserializerTest extends TestCase { @@ -19,7 +20,7 @@ public void test_pattern() throws Exception { Assert.assertEquals(null, JSON.parseObject("null", Pattern.class)); DefaultExtJSONParser parser = new DefaultExtJSONParser("null", ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - Assert.assertEquals(null, PatternDeserializer.instance.deserialze(parser, null)); - Assert.assertEquals(JSONToken.LITERAL_STRING, PatternDeserializer.instance.getFastMatchToken()); + Assert.assertEquals(null, PatternCodec.instance.deserialze(parser, null, null)); + Assert.assertEquals(JSONToken.LITERAL_STRING, PatternCodec.instance.getFastMatchToken()); } } diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/PointDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/PointDeserializerTest.java new file mode 100755 index 0000000000..395114e4d4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/PointDeserializerTest.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.awt.Point; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.serializer.ColorCodec; + + +public class PointDeserializerTest extends TestCase { + public void test_0 () throws Exception { + new ColorCodec().getFastMatchToken(); + } + + public void test_error() throws Exception { + Exception error = null; + try { + JSON.parseObject("[]", Point.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_1() throws Exception { + Exception error = null; + try { + JSON.parseObject("{33:44}", Point.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_2() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"r\":44.}", Point.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_3() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"x\":44.}", Point.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/PointDeserializerTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/PointDeserializerTest2.java new file mode 100644 index 0000000000..fc5c0b1590 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/PointDeserializerTest2.java @@ -0,0 +1,23 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.awt.Point; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; + + +public class PointDeserializerTest2 extends TestCase { + public void test_error_3() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"z\":44}", Point.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/RectangleDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/RectangleDeserializerTest.java new file mode 100755 index 0000000000..64e6d3884d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/RectangleDeserializerTest.java @@ -0,0 +1,98 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.awt.Font; +import java.awt.Rectangle; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.serializer.FontCodec; + + +public class RectangleDeserializerTest extends TestCase { + public void test_0 () throws Exception { + FontCodec.instance.getFastMatchToken(); + + Assert.assertNull(JSON.parseObject("null", Rectangle.class)); + Assert.assertNull(JSON.parseArray("null", Rectangle.class)); + Assert.assertNull(JSON.parseArray("[null]", Rectangle.class).get(0)); + Assert.assertNull(JSON.parseObject("{\"value\":null}", VO.class).getValue()); + } + + public void test_stack_error_0() throws Exception { + Exception error = null; + try { + JSON.parseObject("[]", Rectangle.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_1() throws Exception { + Exception error = null; + try { + JSON.parseObject("{33:22}", Rectangle.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_2() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"name\":22}", Rectangle.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_3() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"style\":true}", Rectangle.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_4() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"size\":\"33\"}", Rectangle.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_5() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"xxx\":22}", Font.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class VO { + + private Rectangle value; + + public Rectangle getValue() { + return value; + } + + public void setValue(Rectangle value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/ResolveFieldDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/ResolveFieldDeserializerTest.java new file mode 100644 index 0000000000..a3ab570898 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/ResolveFieldDeserializerTest.java @@ -0,0 +1,14 @@ +package com.alibaba.json.bvt.parser.deser; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.parser.deserializer.ListResolveFieldDeserializer; +import com.alibaba.fastjson.parser.deserializer.MapResolveFieldDeserializer; + + +public class ResolveFieldDeserializerTest extends TestCase { + public void test_0 () throws Exception { + new MapResolveFieldDeserializer(null, null).parseField(null, null, null, null); + new ListResolveFieldDeserializer(null, null, 0).parseField(null, null, null, null); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/ShortFieldDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/ShortFieldDeserializerTest.java new file mode 100644 index 0000000000..c3e93e1f8f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/ShortFieldDeserializerTest.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class ShortFieldDeserializerTest extends TestCase { + + protected void setUp() throws Exception { +// ParserConfig.getGlobalInstance().setAsmEnable(false); + } + + public void f_test_integer() throws Exception { + String text = "{\"value\":{\"column1\":\"aa\"}}"; + Map map = JSON.parseObject(text, new TypeReference>(){}); + Assert.assertNotNull(map); + Assert.assertNotNull(map.get("value")); + Assert.assertNotNull("aa", map.get("value").getColumn1()); + } + + public void test_integer_2() throws Exception { + String text = "[{\"value\":{\"column1\":\"aa\"}}]"; + List> mapList = JSON.parseObject(text, new TypeReference>>(){}); + Map map = mapList.get(0); + Assert.assertNotNull(map); + Assert.assertNotNull(map.get("value")); + Assert.assertNotNull("aa", map.get("value").getColumn1()); + } + + public static class Entity implements Serializable { + private static final long serialVersionUID = 1L; + private String column1; + private Short column3; + + public String getColumn1() { + return column1; + } + + public void setColumn1(String column1) { + this.column1 = column1; + } + + public Short getColumn3() { + return column3; + } + + public void setColumn3(Short column3) { + this.column3 = column3; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/SortedSetFieldTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/SortedSetFieldTest.java new file mode 100644 index 0000000000..9d3354c343 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/SortedSetFieldTest.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.SortedSet; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class SortedSetFieldTest extends TestCase { + + public void test_null() throws Exception { + Entity value = JSON.parseObject("{value:null}", Entity.class); + Assert.assertNull(value.getValue()); + } + + public void test_empty() throws Exception { + Entity value = JSON.parseObject("{value:[]}", Entity.class); + Assert.assertEquals(0, value.getValue().size()); + } + + private static class Entity { + + private SortedSet value; + + public SortedSet getValue() { + return value; + } + + public void setValue(SortedSet value) { + this.value = value; + } + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/SqlDateDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/SqlDateDeserializerTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/SqlDateDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/SqlDateDeserializerTest.java index b40dea1331..da2233a12a --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/SqlDateDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/SqlDateDeserializerTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -19,7 +19,7 @@ public void test_bigdecimal() throws Exception { Assert.assertEquals(null, JSON.parseObject("null", Integer.class)); DefaultExtJSONParser parser = new DefaultExtJSONParser("null", ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - Assert.assertEquals(null, SqlDateDeserializer.instance.deserialze(parser, null)); + Assert.assertEquals(null, SqlDateDeserializer.instance.deserialze(parser, null, null)); Assert.assertEquals(JSONToken.LITERAL_INT, SqlDateDeserializer.instance.getFastMatchToken()); } } diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/SqlDateDeserializerTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/SqlDateDeserializerTest2.java new file mode 100755 index 0000000000..5e94fd9e86 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/SqlDateDeserializerTest2.java @@ -0,0 +1,50 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.sql.Date; +import java.text.SimpleDateFormat; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class SqlDateDeserializerTest2 extends TestCase { + public void test_sqlDate() throws Exception { + java.util.Date date = new java.util.Date(); + long millis = date.getTime(); + long millis2 = (millis / 1000) * 1000; + String text = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(millis); + text = text.replace(' ', 'T'); + + String text2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(millis2); + + Assert.assertNull(JSON.parseObject("null", Date.class)); + Assert.assertNull(JSON.parseObject("\"\"", Date.class)); + Assert.assertNull(JSON.parseArray("null", Date.class)); + Assert.assertNull(JSON.parseArray("[null]", Date.class).get(0)); + Assert.assertNull(JSON.parseObject("{\"value\":null}", VO.class).getValue()); + + Assert.assertEquals(new Date(millis), JSON.parseObject("" + millis, Date.class)); + Assert.assertEquals(new Date(millis), JSON.parseObject("{\"@type\":\"java.sql.Date\",\"val\":" + millis + "}", Date.class)); + Assert.assertEquals(new Date(millis), JSON.parseObject("\"" + millis + "\"", Date.class)); + Assert.assertEquals(new Date(millis2), JSON.parseObject("\"" + text2 + "\"", Date.class)); + Assert.assertEquals(new Date(millis), JSON.parseObject("\"" + text + "\"", Date.class)); + + //System.out.println(JSON.toJSONString(new Time(millis), SerializerFeature.WriteClassName)); + + } + + public static class VO { + + private Date value; + + public Date getValue() { + return value; + } + + public void setValue(Date value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/StackTraceElementDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/StackTraceElementDeserializerTest.java new file mode 100755 index 0000000000..d4d1744bf4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/StackTraceElementDeserializerTest.java @@ -0,0 +1,145 @@ +package com.alibaba.json.bvt.parser.deser; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; + +public class StackTraceElementDeserializerTest extends TestCase { + + public void test_stack() throws Exception { + Assert.assertNull(JSON.parseObject("null", StackTraceElement.class)); + Assert.assertNull(JSON.parseArray("null", StackTraceElement.class)); + Assert.assertNull(JSON.parseArray("[null]", StackTraceElement.class).get(0)); + Assert.assertNull(JSON.parseObject("{\"value\":null}", VO.class).getValue()); + Assert.assertNull(JSON.parseObject("{\"className\":\"int\",\"methodName\":\"parseInt\"}", + StackTraceElement.class).getFileName()); + + Assert.assertEquals(StackTraceElement.class, ((StackTraceElement) JSON.parse("{\"@type\":\"java.lang.StackTraceElement\",\"className\":\"int\",\"methodName\":\"parseInt\",\"nativeMethod\":null}")).getClass()); + } + + public void test_stack_error() throws Exception { + Exception error = null; + try { + JSON.parseObject("{}", StackTraceElement.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_1() throws Exception { + Exception error = null; + try { + JSON.parseObject("[]", StackTraceElement.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_2() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"className\":null,\"methodName\":null,\"fileName\":null,\"lineNumber\":null,\"@type\":\"xxx\"}", StackTraceElement.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_3() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"@type\":int}", StackTraceElement.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_4() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"xxx\":33}", StackTraceElement.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_5() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"nativeMethod\":33}", StackTraceElement.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_6() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"lineNumber\":33}", StackTraceElement.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_7() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"fileName\":33}", StackTraceElement.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_8() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"methodName\":33}", StackTraceElement.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_9() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"className\":33}", StackTraceElement.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_stack_error_10() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"lineNumber\":true}", StackTraceElement.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class VO { + + private StackTraceElement value; + + public StackTraceElement getValue() { + return value; + } + + public void setValue(StackTraceElement value) { + this.value = value; + } + + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM.java old mode 100644 new mode 100755 similarity index 98% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM.java index d669bd9d83..97940cd53b --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.math.BigDecimal; import java.util.ArrayList; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM2.java old mode 100644 new mode 100755 similarity index 97% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM2.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM2.java index 135e2033b7..123eb16955 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM2.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM2.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.util.ArrayList; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASMEishay.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASMEishay.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASMEishay.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASMEishay.java index 742262b021..a6b48c3aa8 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASMEishay.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASMEishay.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_BigDecimal.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_BigDecimal.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_BigDecimal.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_BigDecimal.java index 905c2022ee..a1ff9ae870 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_BigDecimal.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_BigDecimal.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.math.BigDecimal; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_Byte_0.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_Byte_0.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_Byte_0.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_Byte_0.java index 1e95234913..a9fabae108 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_Byte_0.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_Byte_0.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_Date.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_Date.java old mode 100644 new mode 100755 similarity index 90% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_Date.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_Date.java index 16d63024b6..cfaded6295 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_Date.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_Date.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.util.Date; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_Integer.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_Integer.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_Integer.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_Integer.java index b2f2641f1a..e57351c935 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_Integer.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_Integer.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_List.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_List.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_List.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_List.java index 65d7888956..c8a8f039cd --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_List.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_List.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.util.ArrayList; import java.util.List; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_Long_0.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_Long_0.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_Long_0.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_Long_0.java index 3ec4d5a95f..7deab56eaa --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_Long_0.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_Long_0.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_Short_0.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_Short_0.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_Short_0.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_Short_0.java index df2f665504..c774f1cbd4 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_Short_0.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_Short_0.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_boolean.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_boolean.java old mode 100644 new mode 100755 similarity index 88% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_boolean.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_boolean.java index f11ae10349..ff17d2b53d --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_boolean.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_boolean.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_byte.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_byte.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_byte.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_byte.java index 9f770701f2..6c41a48d36 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_byte.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_byte.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_char.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_char.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_char.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_char.java index b410237912..56cdfe448a --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_char.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_char.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_double.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_double.java old mode 100644 new mode 100755 similarity index 79% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_double.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_double.java index 51ff958ba8..c8d4fb5771 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_double.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_double.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -12,7 +12,7 @@ public void test_asm() throws Exception { String text = JSON.toJSONString(v); V0 v1 = JSON.parseObject(text, V0.class); - Assert.assertEquals(v.getValue(), v1.getValue()); + Assert.assertTrue(v.getValue() == v1.getValue()); } public static class V0 { diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_float.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_float.java old mode 100644 new mode 100755 similarity index 79% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_float.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_float.java index 9dab4f1732..e96da014a4 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_float.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_float.java @@ -1,8 +1,9 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; public class TestASM_float extends TestCase { @@ -12,7 +13,7 @@ public void test_asm() throws Exception { String text = JSON.toJSONString(v); V0 v1 = JSON.parseObject(text, V0.class); - Assert.assertEquals(v.getValue(), v1.getValue()); + Assert.assertTrue(v.getValue() == v1.getValue()); } public static class V0 { diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_int.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_int.java old mode 100644 new mode 100755 similarity index 80% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_int.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_int.java index a26fe0f2d7..adf6f1d675 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_int.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_int.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -23,8 +23,9 @@ public int getI() { return i; } - public void setI(int i) { + public V0 setI(int i) { this.i = i; + return this; } } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_long.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_long.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_long.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_long.java index d18ccef2f4..2326f02333 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_long.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_long.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_null.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_null.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_null.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_null.java index 104233db82..8853149f15 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_null.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_null.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_object.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_object.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_object.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_object.java index 02ab35a94b..11d07ca684 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_object.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_object.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_primitive.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_primitive.java new file mode 100644 index 0000000000..dba84fe44b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_primitive.java @@ -0,0 +1,23 @@ +package com.alibaba.json.bvt.parser.deser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.ASMDeserializerFactory; + +public class TestASM_primitive extends TestCase { + + public void test_asm() throws Exception { + ASMDeserializerFactory factory = new ASMDeserializerFactory(); + Exception error = null; + try { + factory.createJavaBeanDeserializer(ParserConfig.getGlobalInstance(), int.class, int.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_short.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_short.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_short.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_short.java index 24952854c9..c19fdeae1c --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestASM_short.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestASM_short.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestEnum.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestEnum.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestEnum.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestEnum.java index 03c830d0eb..a51123498a --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestEnum.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestEnum.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestNull.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TestNull.java old mode 100644 new mode 100755 similarity index 63% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TestNull.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TestNull.java index 21de81b218..c982e5d11a --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TestNull.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TestNull.java @@ -1,38 +1,38 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.DefaultExtJSONParser; import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.ByteDeserializer; -import com.alibaba.fastjson.parser.deserializer.CharacterDeserializer; -import com.alibaba.fastjson.parser.deserializer.ShortDeserializer; +import com.alibaba.fastjson.parser.deserializer.NumberDeserializer; +import com.alibaba.fastjson.serializer.CharacterCodec; public class TestNull extends TestCase { public void test_byte() throws Exception { DefaultExtJSONParser parser = new DefaultExtJSONParser("null", ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - Assert.assertNull(new ByteDeserializer().deserialze(parser, null)); + Assert.assertNull(new NumberDeserializer().deserialze(parser, null, null)); } public void test_char() throws Exception { DefaultExtJSONParser parser = new DefaultExtJSONParser("null", ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - Assert.assertNull(new CharacterDeserializer().deserialze(parser, null)); + Assert.assertNull(new CharacterCodec().deserialze(parser, null, null)); } public void test_short() throws Exception { DefaultExtJSONParser parser = new DefaultExtJSONParser("null", ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - Assert.assertNull(new ShortDeserializer().deserialze(parser, null)); + Assert.assertNull(new NumberDeserializer().deserialze(parser, null, null)); } public void test_null() throws Exception { DefaultExtJSONParser parser = new DefaultExtJSONParser("null", ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - Assert.assertNull(new ShortDeserializer().deserialze(parser, null)); + Assert.assertNull(new NumberDeserializer().deserialze(parser, null, null)); } } diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/ThrowableDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/ThrowableDeserializerTest.java new file mode 100755 index 0000000000..09619b7c66 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/ThrowableDeserializerTest.java @@ -0,0 +1,70 @@ +package com.alibaba.json.bvt.parser.deser; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; + + +public class ThrowableDeserializerTest extends TestCase { + public void test_0 () throws Exception { + Assert.assertEquals(Throwable.class, JSON.parseObject("{}", Throwable.class).getClass()); + Assert.assertEquals(Throwable.class, JSON.parseObject("{,,,}", Throwable.class).getClass()); + Assert.assertEquals(java.lang.RuntimeException.class, JSON.parseObject("{\"@type\":\"java.lang.RuntimeException\"}", Throwable.class).getClass()); + Assert.assertEquals(null, JSON.parseObject("{\"message\":null}", Throwable.class).getMessage()); + Assert.assertEquals(Exception.class, JSON.parseObject("{\"cause\":{}}", Throwable.class).getCause().getClass()); + } + + public void test_error() throws Exception { + JSONException error = null; + try { + JSON.parseObject("{\"@type\":33}", Throwable.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error1() throws Exception { + JSONException error = null; + try { + Assert.assertEquals(null, JSON.parseObject("{\"message\":33}", Throwable.class).getMessage()); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error2() throws Exception { + Exception error = null; + try { + Assert.assertEquals(null, JSON.parseObject("{}", MyException.class).getMessage()); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error3() throws Exception { + Exception error = null; + try { + Assert.assertEquals(null, JSON.parseObject("{}", MyException2.class).getMessage()); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class MyException extends Exception { + private MyException() { + + } + } + + public static class MyException2 extends Exception { + public MyException2() { + throw new RuntimeException(); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/ThrowableDeserializerTest_2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/ThrowableDeserializerTest_2.java new file mode 100644 index 0000000000..09afe1ba90 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/ThrowableDeserializerTest_2.java @@ -0,0 +1,47 @@ +package com.alibaba.json.bvt.parser.deser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class ThrowableDeserializerTest_2 extends TestCase { + + public void test_0() throws Exception { + Assert.assertEquals("xxx", JSON.parseObject("{\"message\":\"xxx\",,,}", MyException.class).getMessage()); + } + + public void test_2() throws Exception { + Assert.assertEquals(null, JSON.parseObject("{\"message\":\"xxx\"}", MyException2.class).getMessage()); + } + + public void test_3() throws Exception { + Exception error = null; + try { + JSON.parseObject(",\"message\":\"xxx\"}", MyException.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class MyException extends Exception { + + public MyException(){ + + } + + public MyException(String message){ + super(message); + } + } + + public static class MyException2 extends Exception { + + public MyException2(){ + + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/TimeDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TimeDeserializerTest.java new file mode 100755 index 0000000000..9289330dce --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TimeDeserializerTest.java @@ -0,0 +1,47 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.sql.Time; +import java.text.SimpleDateFormat; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class TimeDeserializerTest extends TestCase { + public void test_time() throws Exception { + long millis = System.currentTimeMillis(); + String text = new SimpleDateFormat("yyyy-MM-dd").format(new java.util.Date(millis)); + text += "T"; + text += new SimpleDateFormat("HH:mm:ss.SSS").format(new java.util.Date(millis)); + + Assert.assertNull(JSON.parseObject("null", Time.class)); + Assert.assertNull(JSON.parseObject("\"\"", Time.class)); + Assert.assertNull(JSON.parseArray("null", Time.class)); + Assert.assertNull(JSON.parseArray("[null]", Time.class).get(0)); + Assert.assertNull(JSON.parseObject("{\"value\":null}", VO.class).getValue()); + + Assert.assertEquals(new Time(millis), JSON.parseObject("" + millis, Time.class)); + Assert.assertEquals(new Time(millis), JSON.parseObject("{\"@type\":\"java.sql.Time\",\"val\":" + millis + "}", Time.class)); + Assert.assertEquals(new Time(millis), JSON.parseObject("\"" + millis + "\"", Time.class)); + Assert.assertEquals(new Time(millis), JSON.parseObject("\"" + text + "\"", Time.class)); + + //System.out.println(JSON.toJSONString(new Time(millis), SerializerFeature.WriteClassName)); + + } + + public static class VO { + + private Time value; + + public Time getValue() { + return value; + } + + public void setValue(Time value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/TimeDeserializerTest2.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TimeDeserializerTest2.java new file mode 100755 index 0000000000..181add7ae6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TimeDeserializerTest2.java @@ -0,0 +1,76 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.sql.Time; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONException; + +public class TimeDeserializerTest2 extends TestCase { + + public void test_0() throws Exception { + long millis = System.currentTimeMillis(); + JSON.parse("{\"@type\":\"java.sql.Time\",\"value\":" + millis + "}"); + } + + public void test_error() throws Exception { + long millis = System.currentTimeMillis(); + + Exception error = null; + try { + JSON.parse("{\"@type\":\"java.sql.Time\",33:" + millis + "}"); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_1() throws Exception { + Exception error = null; + try { + JSON.parse("{\"@type\":\"java.sql.Time\",\"value\":true}"); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_2() throws Exception { + long millis = System.currentTimeMillis(); + + Exception error = null; + try { + JSON.parse("{\"@type\":\"java.sql.Time\",\"value\":" + millis + ",}"); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_error_3() throws Exception { + Exception error = null; + try { + JSON.parseObject("{\"time\":{}}", VO.class); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class VO { + + private Time time; + + public Time getTime() { + return time; + } + + public void setTime(Time time) { + this.time = time; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TimeZoneDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TimeZoneDeserializerTest.java old mode 100644 new mode 100755 similarity index 57% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TimeZoneDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TimeZoneDeserializerTest.java index bb41c2850c..28e1af6d1e --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TimeZoneDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TimeZoneDeserializerTest.java @@ -1,18 +1,19 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.DefaultExtJSONParser; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.TimeZoneDeserializer; +import com.alibaba.fastjson.serializer.TimeZoneCodec; public class TimeZoneDeserializerTest extends TestCase { public void test_timezone() throws Exception { DefaultExtJSONParser parser = new DefaultExtJSONParser("null", ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - Assert.assertEquals(null, TimeZoneDeserializer.instance.deserialze(parser, null)); - Assert.assertEquals(JSONToken.LITERAL_STRING, TimeZoneDeserializer.instance.getFastMatchToken()); + Assert.assertEquals(null, TimeZoneCodec.instance.deserialze(parser, null, null)); + Assert.assertEquals(JSONToken.LITERAL_STRING, TimeZoneCodec.instance.getFastMatchToken()); } } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TreeMapDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TreeMapDeserializerTest.java old mode 100644 new mode 100755 similarity index 80% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/TreeMapDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/TreeMapDeserializerTest.java index 1990e3cf36..75255f92c6 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/TreeMapDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TreeMapDeserializerTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.util.TreeMap; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/parser/deser/TreeSetFieldTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/TreeSetFieldTest.java new file mode 100644 index 0000000000..b7be0de274 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/TreeSetFieldTest.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.parser.deser; + +import java.util.TreeSet; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class TreeSetFieldTest extends TestCase { + + public void test_null() throws Exception { + Entity value = JSON.parseObject("{value:null}", Entity.class); + Assert.assertNull(value.getValue()); + } + + public void test_empty() throws Exception { + Entity value = JSON.parseObject("{value:[]}", Entity.class); + Assert.assertEquals(0, value.getValue().size()); + } + + private static class Entity { + + private TreeSet value; + + public TreeSet getValue() { + return value; + } + + public void setValue(TreeSet value) { + this.value = value; + } + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/URIDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/URIDeserializerTest.java old mode 100644 new mode 100755 similarity index 69% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/URIDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/URIDeserializerTest.java index e8d6cce643..5f076bc3c6 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/URIDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/URIDeserializerTest.java @@ -1,13 +1,14 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.DefaultExtJSONParser; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.URIDeserializer; +import com.alibaba.fastjson.serializer.URICodec; public class URIDeserializerTest extends TestCase { @@ -15,10 +16,10 @@ public void test_null() throws Exception { String input = "null"; DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - URIDeserializer deser = new URIDeserializer(); + URICodec deser = new URICodec(); Assert.assertEquals(JSONToken.LITERAL_STRING, deser.getFastMatchToken()); - Assert.assertNull(deser.deserialze(parser, null)); + Assert.assertNull(deser.deserialze(parser, null, null)); } } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/URLDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/URLDeserializerTest.java old mode 100644 new mode 100755 similarity index 74% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/URLDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/URLDeserializerTest.java index 94cbfffe26..73f8cd6c90 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/URLDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/URLDeserializerTest.java @@ -1,16 +1,17 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.net.URL; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.parser.DefaultExtJSONParser; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.URLDeserializer; +import com.alibaba.fastjson.serializer.URLCodec; public class URLDeserializerTest extends TestCase { @@ -20,8 +21,8 @@ public void test_url() throws Exception { Assert.assertEquals(null, JSON.parseObject("null", URL.class)); DefaultExtJSONParser parser = new DefaultExtJSONParser("null", ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - Assert.assertEquals(null, URLDeserializer.instance.deserialze(parser, null)); - Assert.assertEquals(JSONToken.LITERAL_STRING, URLDeserializer.instance.getFastMatchToken()); + Assert.assertEquals(null, URLCodec.instance.deserialze(parser, null, null)); + Assert.assertEquals(JSONToken.LITERAL_STRING, URLCodec.instance.getFastMatchToken()); } diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/UUIDDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/parser/deser/UUIDDeserializerTest.java old mode 100644 new mode 100755 similarity index 74% rename from src/test/java/com/alibaba/json/test/bvt/parser/deser/UUIDDeserializerTest.java rename to src/test/java/com/alibaba/json/bvt/parser/deser/UUIDDeserializerTest.java index 4d826bf2d8..480417d3d5 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/UUIDDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/parser/deser/UUIDDeserializerTest.java @@ -1,16 +1,17 @@ -package com.alibaba.json.test.bvt.parser.deser; +package com.alibaba.json.bvt.parser.deser; import java.util.UUID; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.parser.DefaultExtJSONParser; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.UUIDDeserializer; +import com.alibaba.fastjson.serializer.UUIDCodec; public class UUIDDeserializerTest extends TestCase { @@ -21,8 +22,8 @@ public void test_url() throws Exception { Assert.assertEquals(null, JSON.parseObject("null", UUID.class)); DefaultExtJSONParser parser = new DefaultExtJSONParser("null", ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - Assert.assertEquals(null, UUIDDeserializer.instance.deserialze(parser, null)); - Assert.assertEquals(JSONToken.LITERAL_STRING, UUIDDeserializer.instance.getFastMatchToken()); + Assert.assertEquals(null, UUIDCodec.instance.deserialze(parser, null, null)); + Assert.assertEquals(JSONToken.LITERAL_STRING, UUIDCodec.instance.getFastMatchToken()); } diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest.java new file mode 100644 index 0000000000..cc7b9e013e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest.java @@ -0,0 +1,32 @@ +package com.alibaba.json.bvt.parser.stream; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest extends TestCase { + public void test_singleQuote() throws Exception { + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner("{'name':'张三\\'\\n\\r\\\"'}")); + JSONObject json = parser.parseObject(); + Assert.assertEquals("张三\'\n\r\"", json.get("name")); + parser.close(); + } + + public void test_doubleQuote() throws Exception { + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner("{\"name\":\"张三\\'\\n\\r\\\"\"}")); + JSONObject json = parser.parseObject(); + Assert.assertEquals("张三\'\n\r\"", json.get("name")); + parser.close(); + } + + public void test_doubleQuote_2() throws Exception { + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner("{name:\"张三\\'\\n\\r\\\"\"}")); + JSONObject json = parser.parseObject(); + Assert.assertEquals("张三\'\n\r\"", json.get("name")); + parser.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_boolean.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_boolean.java new file mode 100644 index 0000000000..af20356911 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_boolean.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.parser.stream; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest_boolean extends TestCase { + public void test_true() throws Exception { + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner("{\"name\":true}")); + JSONObject json = parser.parseObject(); + Assert.assertEquals(Boolean.TRUE, json.get("name")); + parser.close(); + } + + public void test_false() throws Exception { + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner("{\"name\":false}")); + JSONObject json = parser.parseObject(); + Assert.assertEquals(Boolean.FALSE, json.get("name")); + parser.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_chars.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_chars.java new file mode 100644 index 0000000000..ae271c78aa --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_chars.java @@ -0,0 +1,46 @@ +package com.alibaba.json.bvt.parser.stream; + +import java.math.BigDecimal; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest_chars extends TestCase { + + public void test_double() throws Exception { + char[] chars = "{\"value\":3.5D}".toCharArray(); + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner(chars, chars.length)); + JSONObject json = parser.parseObject(); + Assert.assertTrue(3.5D == ((Double) json.get("value")).doubleValue()); + parser.close(); + } + + public void test_float() throws Exception { + char[] chars = "{\"value\":3.5F}".toCharArray(); + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner(chars, chars.length)); + JSONObject json = parser.parseObject(); + Assert.assertTrue(3.5F == ((Float) json.get("value")).doubleValue()); + parser.close(); + } + + public void test_decimal() throws Exception { + char[] chars = "{\"value\":3.5}".toCharArray(); + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner(chars, chars.length)); + JSONObject json = parser.parseObject(); + Assert.assertEquals(new BigDecimal("3.5"), json.get("value")); + parser.close(); + } + + public void test_long() throws Exception { + char[] chars = "{\"value\":3L}".toCharArray(); + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner(chars, chars.length)); + JSONObject json = parser.parseObject(); + Assert.assertTrue(3L == ((Long) json.get("value")).longValue()); + parser.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_enum.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_enum.java new file mode 100644 index 0000000000..02217a7190 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_enum.java @@ -0,0 +1,57 @@ +package com.alibaba.json.bvt.parser.stream; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest_enum extends TestCase { + + public void test_a() throws Exception { + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner("{\"type\":\"A\"}")); + VO vo = parser.parseObject(VO.class); + Assert.assertEquals(Type.A, vo.getType()); + parser.close(); + } + + public void test_b() throws Exception { + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner("{\"type\":\"B\"}")); + VO vo = parser.parseObject(VO.class); + Assert.assertEquals(Type.B, vo.getType()); + parser.close(); + } + + public void test_c() throws Exception { + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner("{\"type\":\"C\"}")); + VO vo = parser.parseObject(VO.class); + Assert.assertEquals(Type.C, vo.getType()); + parser.close(); + } + + public void test_x() throws Exception { + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner("{\"type\":\"XXXXXXXXXXXXXXXXXXXXXXXX\"}")); + VO vo = parser.parseObject(VO.class); + Assert.assertEquals(Type.XXXXXXXXXXXXXXXXXXXXXXXX, vo.getType()); + parser.close(); + } + + public static class VO { + + private Type type; + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + } + + public static enum Type { + A, B, C, D, XXXXXXXXXXXXXXXXXXXXXXXX + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_matchField.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_matchField.java new file mode 100644 index 0000000000..fe6c67846f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_matchField.java @@ -0,0 +1,54 @@ +package com.alibaba.json.bvt.parser.stream; + +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest_matchField extends TestCase { + + public void test_true() throws Exception { + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner("{\"items\":[{}],\"value\":{}}")); + VO vo = parser.parseObject(VO.class); + Assert.assertNotNull(vo.getValue()); + Assert.assertNotNull(vo.getItems()); + Assert.assertEquals(1, vo.getItems().size()); + Assert.assertNotNull(vo.getItems().get(0)); + parser.close(); + } + + public static class VO { + + private List items; + private Entity value; + + public Entity getValue() { + return value; + } + + public void setValue(Entity value) { + this.value = value; + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + + } + + public static class Entity { + + } + + public static class Item { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_negative.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_negative.java new file mode 100644 index 0000000000..f0443e5dd2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_negative.java @@ -0,0 +1,46 @@ +package com.alibaba.json.bvt.parser.stream; + +import java.math.BigDecimal; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest_negative extends TestCase { + + public void test_double() throws Exception { + char[] chars = "{\"value\":-3.5D}".toCharArray(); + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner(chars, chars.length)); + JSONObject json = parser.parseObject(); + Assert.assertTrue(-3.5D == ((Double) json.get("value")).doubleValue()); + parser.close(); + } + + public void test_float() throws Exception { + char[] chars = "{\"value\":-3.5F}".toCharArray(); + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner(chars, chars.length)); + JSONObject json = parser.parseObject(); + Assert.assertTrue(-3.5F == ((Float) json.get("value")).doubleValue()); + parser.close(); + } + + public void test_decimal() throws Exception { + char[] chars = "{\"value\":-3.5}".toCharArray(); + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner(chars, chars.length)); + JSONObject json = parser.parseObject(); + Assert.assertEquals(new BigDecimal("-3.5"), json.get("value")); + parser.close(); + } + + public void test_long() throws Exception { + char[] chars = "{\"value\":-3L}".toCharArray(); + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner(chars, chars.length)); + JSONObject json = parser.parseObject(); + Assert.assertTrue(-3L == ((Long) json.get("value")).longValue()); + parser.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_type.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_type.java new file mode 100644 index 0000000000..37c2d907ef --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderScannerTest_type.java @@ -0,0 +1,21 @@ +package com.alibaba.json.bvt.parser.stream; + +import java.util.LinkedHashMap; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONReaderScanner; + +public class JSONReaderScannerTest_type extends TestCase { + @SuppressWarnings("rawtypes") + public void test_true() throws Exception { + DefaultJSONParser parser = new DefaultJSONParser(new JSONReaderScanner("{\"@type\":\"java.util.LinkedHashMap\",\"name\":\"张三\"}")); + LinkedHashMap json = (LinkedHashMap) parser.parse(); + Assert.assertEquals("张三", json.get("name")); + parser.close(); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderTest.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderTest.java new file mode 100644 index 0000000000..efa9be9aa9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderTest.java @@ -0,0 +1,45 @@ +package com.alibaba.json.bvt.parser.stream; + +import java.io.InputStream; +import java.io.InputStreamReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONReader; + +public class JSONReaderTest extends TestCase { + public void test_read() throws Exception { + String resource = "2.json"; + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource); + + JSONReader reader = new JSONReader(new InputStreamReader(is, "UTF-8")); + + reader.startObject(); + + Assert.assertEquals("company", reader.readString()); + Assert.assertTrue(reader.readObject() instanceof JSONObject); + + Assert.assertEquals("count", reader.readString()); + Assert.assertEquals(5, reader.readObject()); + + Assert.assertEquals("pagecount", reader.readString()); + Assert.assertEquals(0, reader.readObject()); + + Assert.assertEquals("pageindex", reader.readString()); + Assert.assertEquals(0, reader.readObject()); + + Assert.assertEquals("resultList", reader.readString()); + Assert.assertTrue(reader.readObject() instanceof JSONArray); + + Assert.assertEquals("totalCount", reader.readString()); + Assert.assertEquals(0, reader.readObject()); + + reader.endObject(); + + reader.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderTest_0.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderTest_0.java new file mode 100644 index 0000000000..6455ab5cff --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderTest_0.java @@ -0,0 +1,23 @@ +package com.alibaba.json.bvt.parser.stream; + +import java.io.StringReader; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.parser.Feature; + +public class JSONReaderTest_0 extends TestCase { + public void test_read() throws Exception { + JSONReader reader = new JSONReader(new StringReader("{}")); + reader.config(Feature.AllowArbitraryCommas, true); + + JSONObject object = (JSONObject) reader.readObject(); + Assert.assertNotNull(object); + + reader.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderTest_error.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderTest_error.java new file mode 100644 index 0000000000..5ebea21603 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderTest_error.java @@ -0,0 +1,50 @@ +package com.alibaba.json.bvt.parser.stream; + +import java.io.StringReader; +import java.lang.reflect.Field; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.parser.Feature; + +public class JSONReaderTest_error extends TestCase { + + public void test_read() throws Exception { + Field field = JSONReader.class.getDeclaredField("context"); + field.setAccessible(true); + ; + + JSONReader reader = new JSONReader(new StringReader("[{}]")); + reader.config(Feature.AllowArbitraryCommas, true); + + reader.startArray(); + + Object context = field.get(reader); + Field stateField = context.getClass().getDeclaredField("state"); + stateField.setAccessible(true); + stateField.set(context, -1); + + { + Exception error = null; + try { + reader.startObject(); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + { + Exception error = null; + try { + reader.readInteger(); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + reader.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderTest_error2.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderTest_error2.java new file mode 100644 index 0000000000..6da1c9c641 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReaderTest_error2.java @@ -0,0 +1,57 @@ +package com.alibaba.json.bvt.parser.stream; + +import java.io.StringReader; +import java.lang.reflect.Field; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.parser.Feature; + +public class JSONReaderTest_error2 extends TestCase { + private static Object context; + private static Field stateField; + + public void test_read() throws Exception { + Field field = JSONReader.class.getDeclaredField("context"); + field.setAccessible(true); + ; + + JSONReader reader = new JSONReader(new StringReader("[{}]")); + reader.config(Feature.AllowArbitraryCommas, true); + + reader.startArray(); + + context = field.get(reader); + stateField = context.getClass().getDeclaredField("state"); + stateField.setAccessible(true); + + + { + Exception error = null; + try { + reader.readObject(VO.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + reader.close(); + } + + public static class VO { + public VO() { + try { + stateField.set(context, -1); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_array.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_array.java new file mode 100644 index 0000000000..8a2c4f7f5f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_array.java @@ -0,0 +1,61 @@ +package com.alibaba.json.bvt.parser.stream; + +import java.io.StringReader; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONReader; + +public class JSONReader_array extends TestCase { + + public void test_array() throws Exception { + JSONReader reader = new JSONReader(new StringReader("[[],[],3,null,{\"name\":\"jobs\"},{\"id\":123},{\"id\":1},{\"id\":2}]")); + reader.startArray(); + + JSONArray first = (JSONArray) reader.readObject(); + JSONArray second = (JSONArray) reader.readObject(); + + Assert.assertNotNull(first); + Assert.assertNotNull(second); + + Assert.assertEquals(new Integer(3), reader.readInteger()); + Assert.assertNull(reader.readString()); + + { + Map map = new HashMap(); + reader.readObject(map); + Assert.assertEquals("jobs", map.get("name")); + } + + { + VO vo = new VO(); + reader.readObject(vo); + Assert.assertEquals(123, vo.getId()); + } + + while (reader.hasNext()) { + VO vo = reader.readObject(VO.class); + Assert.assertNotNull(vo); + } + reader.endArray(); + reader.close(); + } + + public static class VO { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_map.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_map.java new file mode 100644 index 0000000000..797d2970d5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_map.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.parser.stream; + +import java.io.StringReader; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; + +public class JSONReader_map extends TestCase { + + public void test_array() throws Exception { + JSONReader reader = new JSONReader(new StringReader("[{\"id\":123}]")); + + reader.startArray(); + + Map map = new HashMap(); + reader.readObject(map); + + Assert.assertEquals(123, map.get("id")); + + reader.endArray(); + + reader.close(); + } + + public void test_map() throws Exception { + JSONReader reader = new JSONReader(new StringReader("{\"id\":123}")); + + Map map = new HashMap(); + reader.readObject(map); + + Assert.assertEquals(123, map.get("id")); + + reader.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_obj.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_obj.java new file mode 100644 index 0000000000..c9f8ba5471 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_obj.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.parser.stream; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; + +public class JSONReader_obj extends TestCase { + + public void test_array() throws Exception { + JSONReader reader = new JSONReader(new StringReader("[{\"id\":123}]")); + + reader.startArray(); + + VO vo = new VO(); + reader.readObject(vo); + + Assert.assertEquals(123, vo.getId()); + + reader.endArray(); + + reader.close(); + } + + public void test_obj() throws Exception { + JSONReader reader = new JSONReader(new StringReader("{\"id\":123}")); + + VO vo = new VO(); + reader.readObject(vo); + + Assert.assertEquals(123, vo.getId()); + + reader.close(); + } + + public static class VO { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_obj_2.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_obj_2.java new file mode 100644 index 0000000000..d6585f874b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_obj_2.java @@ -0,0 +1,50 @@ +package com.alibaba.json.bvt.parser.stream; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; + +public class JSONReader_obj_2 extends TestCase { + + public void test_array() throws Exception { + JSONReader reader = new JSONReader(new StringReader("[{\"id\":123}]")); + + reader.startArray(); + + VO vo = reader.readObject(VO.class); + + Assert.assertEquals(123, vo.getId()); + + reader.endArray(); + + reader.close(); + } + + public void test_obj() throws Exception { + JSONReader reader = new JSONReader(new StringReader("{\"id\":123}")); + + VO vo = reader.readObject(VO.class); + + Assert.assertEquals(123, vo.getId()); + + reader.close(); + } + + public static class VO { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_obj_3.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_obj_3.java new file mode 100644 index 0000000000..e50a7e727b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_obj_3.java @@ -0,0 +1,61 @@ +package com.alibaba.json.bvt.parser.stream; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; + +public class JSONReader_obj_3 extends TestCase { + + public void test_obj() throws Exception { + JSONReader reader = new JSONReader(new StringReader("{\"id\":123}")); + + reader.startObject(); + Assert.assertEquals("id", reader.readString()); + Assert.assertEquals(Integer.valueOf(123), reader.readInteger()); + reader.endObject(); + + reader.close(); + } + + public void test_obj_2() throws Exception { + JSONReader reader = new JSONReader(new StringReader("{\"val\":{\"id\":123}}")); + + reader.startObject(); + + Assert.assertEquals("val", reader.readString()); + + reader.startObject(); + Assert.assertEquals("id", reader.readString()); + Assert.assertEquals(Integer.valueOf(123), reader.readInteger()); + reader.endObject(); + + reader.endObject(); + + reader.close(); + } + + public void test_obj_3() throws Exception { + JSONReader reader = new JSONReader(new StringReader("{\"val\":{\"val\":{\"id\":123}}}")); + + reader.startObject(); + Assert.assertEquals("val", reader.readString()); + + reader.startObject(); + Assert.assertEquals("val", reader.readString()); + + reader.startObject(); + Assert.assertEquals("id", reader.readString()); + Assert.assertEquals(Long.valueOf(123), reader.readLong()); + reader.endObject(); + + reader.endObject(); + reader.endObject(); + + reader.close(); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_string.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_string.java new file mode 100644 index 0000000000..04ca62c304 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_string.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt.parser.stream; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; + +public class JSONReader_string extends TestCase { + + public void test_array() throws Exception { + JSONReader reader = new JSONReader(new StringReader("[\"abc\"]")); + + reader.startArray(); + + Assert.assertEquals("abc", reader.readString()); + + reader.endArray(); + + reader.close(); + } + + public void test_array_2() throws Exception { + JSONReader reader = new JSONReader(new StringReader("[[\"abc\"]]")); + + reader.startArray(); + reader.startArray(); + + Assert.assertEquals("abc", reader.readString()); + + reader.endArray(); + reader.endArray(); + + reader.close(); + } + + public void test_array_3() throws Exception { + JSONReader reader = new JSONReader(new StringReader("[[[\"abc\"]]]")); + + reader.startArray(); + reader.startArray(); + reader.startArray(); + + Assert.assertEquals("abc", reader.readString()); + + reader.endArray(); + reader.endArray(); + reader.endArray(); + + reader.close(); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_string_1.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_string_1.java new file mode 100644 index 0000000000..dfe75b1ed7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_string_1.java @@ -0,0 +1,20 @@ +package com.alibaba.json.bvt.parser.stream; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; + +public class JSONReader_string_1 extends TestCase { + public void test_obj() throws Exception { + JSONReader reader = new JSONReader(new StringReader("\"abc\"")); + + Assert.assertEquals("abc", reader.readString()); + + reader.close(); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_typeRef.java b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_typeRef.java new file mode 100644 index 0000000000..b9fc55ae96 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/parser/stream/JSONReader_typeRef.java @@ -0,0 +1,49 @@ +package com.alibaba.json.bvt.parser.stream; + +import java.io.StringReader; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.TypeReference; + +public class JSONReader_typeRef extends TestCase { + public void test_array() throws Exception { + JSONReader reader = new JSONReader(new StringReader("[{\"id\":123}]")); + + List list = reader.readObject(new TypeReference>() {}.getType()); + + Assert.assertEquals(123, list.get(0).getId()); + + reader.close(); + } + + public void test_array_1() throws Exception { + JSONReader reader = new JSONReader(new StringReader("[[{\"id\":123}]]")); + + reader.startArray(); + List list = reader.readObject(new TypeReference>() {}.getType()); + + Assert.assertEquals(123, list.get(0).getId()); + + reader.endArray(); + + reader.close(); + } + + public static class VO { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_0.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_0.java new file mode 100644 index 0000000000..6c8d39fef9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_0.java @@ -0,0 +1,48 @@ +package com.alibaba.json.bvt.path; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_0 extends TestCase { + + public void test_root() throws Exception { + Object obj = new Object(); + Assert.assertSame(obj, new JSONPath("$").eval(obj)); + } + + public void test_null() throws Exception { + Assert.assertNull(new JSONPath("$").eval(null)); + } + + public void test_map() throws Exception { + Map map = new HashMap(); + map.put("val", new Object()); + Assert.assertSame(map.get("val"), new JSONPath("$.val").eval(map)); + } + + public void test_entity() throws Exception { + Entity entity = new Entity(); + entity.setValue(new Object()); + Assert.assertSame(entity.getValue(), new JSONPath("$.value").eval(entity)); + } + + public static class Entity { + + private Object value; + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_array_put.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_array_put.java new file mode 100644 index 0000000000..a3ff90d9d8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_array_put.java @@ -0,0 +1,76 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_array_put extends TestCase { + + public void test_put() throws Exception { + Map root = new HashMap(); + List list = new ArrayList(); + root.put("values", list); + + JSONPath path = new JSONPath("$.values"); + path.arrayAdd(root, 123); + + Assert.assertEquals(1, list.size()); + Assert.assertEquals(123, ((Integer) list.get(0)).intValue()); + } + + public void test_set() throws Exception { + List list = new ArrayList(); + list.add(new int[0]); + list.add(new int[0]); + + JSONPath path = new JSONPath("$[0]"); + path.arrayAdd(list, 123); + + Assert.assertEquals(1, list.get(0).length); + Assert.assertEquals(123, ((int[]) list.get(0))[0]); + } + + public void test_set_2() throws Exception { + Object[] list = new Object[2]; + list[0] = new int[0]; + list[0] = new int[0]; + + JSONPath path = new JSONPath("$[0]"); + path.arrayAdd(list, 123); + + Assert.assertEquals(1, ((int[]) list[0]).length); + Assert.assertEquals(123, ((int[]) list[0])[0]); + } + + public void test_put_array_int() throws Exception { + Map root = new HashMap(); + root.put("values", new int[0]); + + JSONPath path = new JSONPath("$.values"); + path.arrayAdd(root, 123); + + int[] array = (int[]) root.get("values"); + Assert.assertEquals(1, array.length); + Assert.assertEquals(123, array[0]); + } + + public void test_put_array_long() throws Exception { + Map root = new HashMap(); + root.put("values", new long[0]); + + JSONPath path = new JSONPath("$.values"); + path.arrayAdd(root, 123); + + long[] array = (long[]) root.get("values"); + Assert.assertEquals(1, array.length); + Assert.assertEquals(123, array[0]); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_between_int.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_between_int.java new file mode 100644 index 0000000000..3b9aa207a1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_between_int.java @@ -0,0 +1,71 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_between_int extends TestCase { + public void test_between() throws Exception { + List list = new ArrayList(); + list.add(new Entity(101, "kiki")); + list.add(new Entity(102, "ljw2083")); + list.add(new Entity(103, "ljw2083")); + List result = (List) JSONPath.eval(list, "$[id between 101 and 101]"); + Assert.assertEquals(1, result.size()); + Assert.assertSame(list.get(0), result.get(0)); + } + + public void test_between_2() throws Exception { + List list = new ArrayList(); + list.add(new Entity(101, "kiki")); + list.add(new Entity(102, "ljw2083")); + list.add(new Entity(103, "ljw2083")); + List result = (List) JSONPath.eval(list, "$[id between 101 and 102]"); + Assert.assertEquals(2, result.size()); + Assert.assertSame(list.get(0), result.get(0)); + Assert.assertSame(list.get(1), result.get(1)); + } + + public void test_between_not() throws Exception { + List list = new ArrayList(); + list.add(new Entity(101, "kiki")); + list.add(new Entity(102, "ljw2083")); + list.add(new Entity(103, "ljw2083")); + List result = (List) JSONPath.eval(list, "$[id not between 101 and 102]"); + Assert.assertEquals(1, result.size()); + Assert.assertSame(list.get(2), result.get(0)); + } + + public static class Entity { + + private Integer id; + private String name; + + public Entity(Integer id, String name){ + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access.java new file mode 100644 index 0000000000..ac68514210 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access.java @@ -0,0 +1,45 @@ +package com.alibaba.json.bvt.path; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_field_access extends TestCase { + + public void test_list_map() throws Exception { + Entity entity = new Entity(123, "wenshao"); + JSONPath path = new JSONPath("$['id']"); + + Assert.assertSame(entity.getId(), path.eval(entity)); + } + + public static class Entity { + + private Integer id; + private String name; + + public Entity(Integer id, String name){ + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_compare_int.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_compare_int.java new file mode 100644 index 0000000000..36e2fd9683 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_compare_int.java @@ -0,0 +1,56 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_field_access_filter_compare_int extends TestCase { + + public void test_list_map() throws Exception { + JSONPath path = new JSONPath("$[?(@.id <= 1002)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(1), result.get(1)); + } + + public static class Entity { + + private Integer id; + private String name; + + public Entity(Integer id, String name){ + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_compare_int_simple.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_compare_int_simple.java new file mode 100644 index 0000000000..0ba094c666 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_compare_int_simple.java @@ -0,0 +1,71 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_field_access_filter_compare_int_simple extends TestCase { + + public void test_list() throws Exception { + JSONPath path = new JSONPath("$[id <= 1002]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(1), result.get(1)); + } + + public void test_list_2() throws Exception { + JSONPath path = new JSONPath("[id <= 1002]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(1), result.get(1)); + } + + public static class Entity { + + private Integer id; + private String name; + + public Entity(Integer id, String name){ + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_compare_string.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_compare_string.java new file mode 100644 index 0000000000..75d98aca97 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_compare_string.java @@ -0,0 +1,157 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_field_access_filter_compare_string extends TestCase { + + public void test_list_eq() throws Exception { + JSONPath path = new JSONPath("$[?(@.name = 'ljw2083')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_eq_x() throws Exception { + JSONPath path = new JSONPath("$[?(name = 'ljw2083')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_eq_null() throws Exception { + JSONPath path = new JSONPath("$[?(@.name = null)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(2), result.get(0)); + Assert.assertSame(entities.get(3), result.get(1)); + } + + public void test_list_not_null() throws Exception { + JSONPath path = new JSONPath("$[?(@.name != null)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(1), result.get(1)); + } + + public void test_list_gt() throws Exception { + JSONPath path = new JSONPath("$[?(@.name > 'ljw2083')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(1), result.get(0)); + } + + public void test_list_ge() throws Exception { + JSONPath path = new JSONPath("$[?(@.name >= 'ljw2083')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(1), result.get(1)); + } + + public void test_list_lt() throws Exception { + JSONPath path = new JSONPath("$[?(@.name < 'wenshao')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_le() throws Exception { + JSONPath path = new JSONPath("$[?(@.name <= 'wenshao')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(1), result.get(1)); + } + + public static class Entity { + + private Integer id; + private String name; + + public Entity(Integer id, String name){ + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_compare_string_simple.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_compare_string_simple.java new file mode 100644 index 0000000000..a8f5e9be1e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_compare_string_simple.java @@ -0,0 +1,157 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_field_access_filter_compare_string_simple extends TestCase { + + public void test_list_eq() throws Exception { + JSONPath path = new JSONPath("[name = 'ljw2083']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_eq_x() throws Exception { + JSONPath path = new JSONPath("[name = 'ljw2083']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_eq_null() throws Exception { + JSONPath path = new JSONPath("$[name = null]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(2), result.get(0)); + Assert.assertSame(entities.get(3), result.get(1)); + } + + public void test_list_not_null() throws Exception { + JSONPath path = new JSONPath("$[name != null]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(1), result.get(1)); + } + + public void test_list_gt() throws Exception { + JSONPath path = new JSONPath("$[name > 'ljw2083']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(1), result.get(0)); + } + + public void test_list_ge() throws Exception { + JSONPath path = new JSONPath("$[name >= 'ljw2083']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(1), result.get(1)); + } + + public void test_list_lt() throws Exception { + JSONPath path = new JSONPath("$[?(@.name < 'wenshao')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_le() throws Exception { + JSONPath path = new JSONPath("$[name <= 'wenshao']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(1), result.get(1)); + } + + public static class Entity { + + private Integer id; + private String name; + + public Entity(Integer id, String name){ + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_in_int.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_in_int.java new file mode 100644 index 0000000000..75c8c85a6e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_in_int.java @@ -0,0 +1,135 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_field_access_filter_in_int extends TestCase { + + public void test_list_in() throws Exception { + JSONPath path = new JSONPath("[id in (1001)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(1004, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_not_in() throws Exception { + JSONPath path = new JSONPath("[id not in (1001)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(1004, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(3, result.size()); + Assert.assertSame(entities.get(1), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + Assert.assertSame(entities.get(3), result.get(2)); + } + + public void test_list_not_in_null() throws Exception { + JSONPath path = new JSONPath("[id not in (null)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(1004, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(4, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(1), result.get(1)); + Assert.assertSame(entities.get(2), result.get(2)); + Assert.assertSame(entities.get(3), result.get(3)); + } + + public void test_list_in_2() throws Exception { + JSONPath path = new JSONPath("[id in (1001, 1003)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(1004, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + } + + public void test_list_in_3() throws Exception { + JSONPath path = new JSONPath("[id in (1001, 1003, 1004)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(1004, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(3, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + Assert.assertSame(entities.get(3), result.get(2)); + } + + public void test_list_in_3_null() throws Exception { + JSONPath path = new JSONPath("[id in (1001, 1003, null)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(3, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + Assert.assertSame(entities.get(3), result.get(2)); + } + + public static class Entity { + + private Integer id; + private String name; + + public Entity(Integer id, String name){ + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_in_string.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_in_string.java new file mode 100644 index 0000000000..70cc50c1ad --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_in_string.java @@ -0,0 +1,102 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_field_access_filter_in_string extends TestCase { + + public void test_list_in() throws Exception { + JSONPath path = new JSONPath("[name in ('ljw2083')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(1004, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_not_in() throws Exception { + JSONPath path = new JSONPath("[name not in ('ljw2083')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(1004, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(3, result.size()); + Assert.assertSame(entities.get(1), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + Assert.assertSame(entities.get(3), result.get(2)); + } + + public void test_list_in_2() throws Exception { + JSONPath path = new JSONPath("[name in ('ljw2083', 'yakolee')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(1004, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + } + + public void test_list_in_3() throws Exception { + JSONPath path = new JSONPath("[name in ('ljw2083', 'yakolee',null)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(1004, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(3, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + Assert.assertSame(entities.get(3), result.get(2)); + } + + public static class Entity { + + private Integer id; + private String name; + + public Entity(Integer id, String name){ + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_like.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_like.java new file mode 100644 index 0000000000..271173575f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_like.java @@ -0,0 +1,154 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_field_access_filter_like extends TestCase { + + public void test_list_like_extract() throws Exception { + JSONPath path = new JSONPath("$[?(@.name like 'ljw2083')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_not_like_extract() throws Exception { + JSONPath path = new JSONPath("$[?(@.name not like 'ljw2083')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(3, result.size()); + Assert.assertSame(entities.get(1), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + Assert.assertSame(entities.get(3), result.get(2)); + } + + public void test_list_like_left_match() throws Exception { + JSONPath path = new JSONPath("$[?(@.name like 'ljw%')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_like_right_match() throws Exception { + JSONPath path = new JSONPath("$[?(@.name like '%2083')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_like_contains() throws Exception { + JSONPath path = new JSONPath("$[?(@.name like '%208%')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_like_match_two_segement() throws Exception { + JSONPath path = new JSONPath("$[?(@.name like 'ljw%83')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_like_match_two_segement_2() throws Exception { + JSONPath path = new JSONPath("$[?(@.name like 'ljw%w2083')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(0, result.size()); + } + + public void test_list_like_match_two_segement_3() throws Exception { + JSONPath path = new JSONPath("$[?(@.name like 'ljw%2%0%83')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public static class Entity { + + private Integer id; + private String name; + + public Entity(Integer id, String name){ + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_like_simple.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_like_simple.java new file mode 100644 index 0000000000..46936f9901 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_like_simple.java @@ -0,0 +1,245 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_field_access_filter_like_simple extends TestCase { + + public void test_list_like_extract() throws Exception { + JSONPath path = new JSONPath("$[name like 'ljw2083']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_not_like_extract() throws Exception { + JSONPath path = new JSONPath("$[name not like 'ljw2083']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(3, result.size()); + Assert.assertSame(entities.get(1), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + Assert.assertSame(entities.get(3), result.get(2)); + } + + public void test_list_like_left_match() throws Exception { + JSONPath path = new JSONPath("$[name like 'ljw%']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_like_left_not_match() throws Exception { + JSONPath path = new JSONPath("$[name not like 'ljw%']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(1), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + } + + public void test_list_like_right_match() throws Exception { + JSONPath path = new JSONPath("$[name like '%2083']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_like_right_not_match() throws Exception { + JSONPath path = new JSONPath("$[name not like '%2083']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(1), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + } + + public void test_list_like_contains() throws Exception { + JSONPath path = new JSONPath("$[name like '%208%']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_like_not_contains() throws Exception { + JSONPath path = new JSONPath("$[name not like '%208%']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(1), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + } + + public void test_list_like_match_two_segement() throws Exception { + JSONPath path = new JSONPath("$[name like 'ljw%83']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_like_match_two_segement_not() throws Exception { + JSONPath path = new JSONPath("$[name not like 'ljw%83']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(1), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + } + + public void test_list_like_match_two_segement_2() throws Exception { + JSONPath path = new JSONPath("$[name like 'ljw%w2083']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(0, result.size()); + } + + public void test_list_like_match_two_segement_2_not() throws Exception { + JSONPath path = new JSONPath("$[name not like 'ljw%w2083']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(3, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(1), result.get(1)); + Assert.assertSame(entities.get(2), result.get(2)); + } + + public void test_list_like_match_two_segement_3() throws Exception { + JSONPath path = new JSONPath("$[name like 'ljw%2%0%83']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_like_match_two_segement_3_not() throws Exception { + JSONPath path = new JSONPath("$[name not like 'ljw%2%0%83']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(1), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + } + + public static class Entity { + + private Integer id; + private String name; + + public Entity(Integer id, String name){ + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_notNull.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_notNull.java new file mode 100644 index 0000000000..34b0ff5a9e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_notNull.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_field_access_filter_notNull extends TestCase { + + public void test_list_map() throws Exception { + JSONPath path = new JSONPath("$[?(@.name)]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(1), result.get(1)); + } + + public static class Entity { + + private Integer id; + private String name; + + public Entity(Integer id, String name){ + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_rlike.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_rlike.java new file mode 100644 index 0000000000..1a7d75c380 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_filter_rlike.java @@ -0,0 +1,153 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_field_access_filter_rlike extends TestCase { + + public void test_list_like_extract() throws Exception { + JSONPath path = new JSONPath("$[name rlike 'ljw2083']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, null)); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_not_like_extract() throws Exception { + JSONPath path = new JSONPath("$[name not rlike 'wenshao']"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(2, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + Assert.assertSame(entities.get(2), result.get(1)); + } + + public void test_list_like_left_match() throws Exception { + JSONPath path = new JSONPath("$[?(@.name like 'ljw%')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_like_right_match() throws Exception { + JSONPath path = new JSONPath("$[?(@.name like '%2083')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_like_contains() throws Exception { + JSONPath path = new JSONPath("$[?(@.name like '%208%')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_like_match_two_segement() throws Exception { + JSONPath path = new JSONPath("$[?(@.name like 'ljw%83')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public void test_list_like_match_two_segement_2() throws Exception { + JSONPath path = new JSONPath("$[?(@.name like 'ljw%w2083')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(0, result.size()); + } + + public void test_list_like_match_two_segement_3() throws Exception { + JSONPath path = new JSONPath("$[?(@.name like 'ljw%2%0%83')]"); + + List entities = new ArrayList(); + entities.add(new Entity(1001, "ljw2083")); + entities.add(new Entity(1002, "wenshao")); + entities.add(new Entity(1003, "yakolee")); + entities.add(new Entity(null, null)); + + List result = (List) path.eval(entities); + Assert.assertEquals(1, result.size()); + Assert.assertSame(entities.get(0), result.get(0)); + } + + public static class Entity { + + private Integer id; + private String name; + + public Entity(Integer id, String name){ + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_multi.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_multi.java new file mode 100644 index 0000000000..af7cc2d717 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_access_multi.java @@ -0,0 +1,49 @@ +package com.alibaba.json.bvt.path; + +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_field_access_multi extends TestCase { + + public void test_list_map() throws Exception { + Entity entity = new Entity(123, "wenshao"); + JSONPath path = new JSONPath("$['id','name']"); + + List result = (List) path.eval(entity); + Assert.assertSame(entity.getId(), result.get(0)); + Assert.assertSame(entity.getName(), result.get(1)); + } + + public static class Entity { + + private Integer id; + private String name; + + public Entity(Integer id, String name){ + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_wildcard.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_wildcard.java new file mode 100644 index 0000000000..356ea6ab17 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_field_wildcard.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt.path; + +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_field_wildcard extends TestCase { + + public void test_list_map() throws Exception { + JSONPath path = new JSONPath("$.*"); + Entity entity = new Entity(123, "wenshao"); + + List fieldValues = (List) path.eval(entity); + Assert.assertSame(entity.getId(), fieldValues.get(0)); + Assert.assertSame(entity.getName(), fieldValues.get(1)); + } + + public void test_list_map_none_root() throws Exception { + JSONPath path = new JSONPath("*"); + Entity entity = new Entity(123, "wenshao"); + + List fieldValues = (List) path.eval(entity); + Assert.assertSame(entity.getId(), fieldValues.get(0)); + Assert.assertSame(entity.getName(), fieldValues.get(1)); + } + + public static class Entity { + + private Integer id; + private String name; + + public Entity(Integer id, String name){ + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_list.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_list.java new file mode 100644 index 0000000000..db8f33f875 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_list.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +import junit.framework.TestCase; + +public class JSONPath_list extends TestCase { + public void test_list_map() throws Exception { + Map map = new HashMap(); + map.put("val", new Object()); + List list = new ArrayList(); + list.add(map); + Assert.assertSame(map.get("val"), new JSONPath("$[0].val").eval(list)); + Assert.assertSame(map.get("val"), new JSONPath("$[-1].val").eval(list)); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_list_field.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_list_field.java new file mode 100644 index 0000000000..c307ed1d10 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_list_field.java @@ -0,0 +1,54 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_list_field extends TestCase { + + public void test_list_field() throws Exception { + JSONPath path = new JSONPath("$.name"); + List entities = new ArrayList(); + entities.add(new Entity("wenshao")); + entities.add(new Entity("ljw2083")); + + List names = (List)path.eval(entities); + Assert.assertSame(entities.get(0).getName(), names.get(0)); + Assert.assertSame(entities.get(1).getName(), names.get(1)); + } + + public void test_list_field_simple() throws Exception { + JSONPath path = new JSONPath("name"); + + List entities = new ArrayList(); + entities.add(new Entity("wenshao")); + entities.add(new Entity("ljw2083")); + + List names = (List) path.eval(entities); + Assert.assertSame(entities.get(0).getName(), names.get(0)); + Assert.assertSame(entities.get(1).getName(), names.get(1)); + } + + public static class Entity { + + private String name; + + public Entity(String name){ + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_list_multi.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_list_multi.java new file mode 100644 index 0000000000..520aac38e0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_list_multi.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_list_multi extends TestCase { + public void test_list_map() throws Exception { + List list = new ArrayList(); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + List result = (List) new JSONPath("$[2,4,5,8,100]").eval(list); + Assert.assertEquals(5, result.size()); + Assert.assertSame(list.get(2), result.get(0)); + Assert.assertSame(list.get(4), result.get(1)); + Assert.assertSame(list.get(5), result.get(2)); + Assert.assertSame(list.get(8), result.get(3)); + Assert.assertNull(result.get(4)); + } + + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_list_range.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_list_range.java new file mode 100644 index 0000000000..25d29c9687 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_list_range.java @@ -0,0 +1,85 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_list_range extends TestCase { + public void test_range() throws Exception { + List list = new ArrayList(); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + JSONPath path = new JSONPath("$[2:4]"); + List result = (List) path.eval(list); + Assert.assertEquals(3, result.size()); + Assert.assertSame(list.get(2), result.get(0)); + Assert.assertSame(list.get(3), result.get(1)); + Assert.assertSame(list.get(4), result.get(2)); + } + + public void test_range_1() throws Exception { + List list = new ArrayList(); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + JSONPath path = new JSONPath("$[:4]"); + List result = (List) path.eval(list); + Assert.assertEquals(5, result.size()); + Assert.assertSame(list.get(0), result.get(0)); + Assert.assertSame(list.get(1), result.get(1)); + Assert.assertSame(list.get(2), result.get(2)); + Assert.assertSame(list.get(3), result.get(3)); + Assert.assertSame(list.get(4), result.get(4)); + } + + public void test_range_2() throws Exception { + List list = new ArrayList(); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + + JSONPath path = new JSONPath("$[4:]"); + List result = (List) path.eval(list); + Assert.assertEquals(2, result.size()); + Assert.assertSame(list.get(4), result.get(0)); + Assert.assertSame(list.get(5), result.get(1)); + } + + + public void test_range_step() throws Exception { + List list = new ArrayList(); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + JSONPath path = new JSONPath("$[2:8:2]"); + List result = (List) path.eval(list); + Assert.assertEquals(2, result.size()); + Assert.assertSame(list.get(2), result.get(0)); + Assert.assertSame(list.get(4), result.get(1)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_list_size.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_list_size.java new file mode 100644 index 0000000000..c1ed236325 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_list_size.java @@ -0,0 +1,23 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_list_size extends TestCase { + public void test_list_map() throws Exception { + List list = new ArrayList(); + list.add(new Object()); + list.add(new Object()); + list.add(new Object()); + JSONPath path = new JSONPath("$.size()"); + Integer result = (Integer) path.eval(list); + Assert.assertEquals(list.size(), result.intValue()); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_none_root.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_none_root.java new file mode 100644 index 0000000000..de1cc39643 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_none_root.java @@ -0,0 +1,51 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_none_root extends TestCase { + + public void test_root() throws Exception { + List list = new ArrayList(); + list.add(new Object()); + Assert.assertSame(list.get(0), new JSONPath("[0]").eval(list)); + } + + public void test_null() throws Exception { + Assert.assertNull(new JSONPath("name").eval(null)); + } + + public void test_map() throws Exception { + Map map = new HashMap(); + map.put("val", new Object()); + Assert.assertSame(map.get("val"), new JSONPath("val").eval(map)); + } + + public void test_entity() throws Exception { + Entity entity = new Entity(); + entity.setValue(new Object()); + Assert.assertSame(entity.getValue(), new JSONPath("value").eval(entity)); + } + + public static class Entity { + + private Object value; + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_object_filter.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_object_filter.java new file mode 100644 index 0000000000..c67ddc4ebf --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_object_filter.java @@ -0,0 +1,53 @@ +package com.alibaba.json.bvt.path; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSONPath; + + +public class JSONPath_object_filter extends TestCase { + public void test_object_filter() throws Exception { + JSONPath path = new JSONPath("[id=123]"); + + Entity entity = new Entity(123, "ljw2083"); + Assert.assertSame(entity, path.eval(entity)); + } + + + public void test_object_filter_not_match() throws Exception { + JSONPath path = new JSONPath("[id=124]"); + + Entity entity = new Entity(123, "ljw2083"); + Assert.assertNull(path.eval(entity)); + } + + public static class Entity { + + private Integer id; + private String name; + + public Entity(Integer id, String name){ + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/JSONPath_set.java b/src/test/java/com/alibaba/json/bvt/path/JSONPath_set.java new file mode 100644 index 0000000000..8800005d6e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/JSONPath_set.java @@ -0,0 +1,62 @@ +package com.alibaba.json.bvt.path; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + +public class JSONPath_set extends TestCase { + + public void test_set() throws Exception { + Entity entity = new Entity(); + + JSONPath.set(entity, "$.name", "abc"); + + Assert.assertEquals("abc", entity.getName()); + } + + public void test_set_array() throws Exception { + Object[] array = new Object[1]; + + JSONPath.set(array, "[0]", "abc"); + + Assert.assertEquals("abc", array[0]); + } + + public void test_set_list() throws Exception { + List array = new ArrayList(); + array.add(null); + array.add(null); + + JSONPath.set(array, "[0]", "abc"); + + Assert.assertEquals("abc", array.get(0)); + } + + static class Entity { + + private Integer id; + private String name; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/TestSpecial_0.java b/src/test/java/com/alibaba/json/bvt/path/TestSpecial_0.java new file mode 100644 index 0000000000..aa0e01c5e1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/TestSpecial_0.java @@ -0,0 +1,22 @@ +package com.alibaba.json.bvt.path; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPath; + + +public class TestSpecial_0 extends TestCase { + public void test_special() throws Exception { + Map vo = new HashMap(); + + vo.put("a.b", 123); + + Assert.assertEquals((Integer) vo.get("a.b"), (Integer) JSONPath.eval(vo, "a\\.b")); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/odps_udf/JSONArrayAdd_int.java b/src/test/java/com/alibaba/json/bvt/path/odps_udf/JSONArrayAdd_int.java new file mode 100644 index 0000000000..9f2bae283b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/odps_udf/JSONArrayAdd_int.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt.path.odps_udf; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.support.odps.udf.JSONArrayAdd; + + +public class JSONArrayAdd_int extends TestCase { + public void test_udf() throws Exception { + JSONArrayAdd udf = new JSONArrayAdd(); + + String text = udf.evaluate("[]", "$", new Long(1), new Long(2)); + Assert.assertEquals("[1,2]", text); + } + + public void test_double() throws Exception { + JSONArrayAdd udf = new JSONArrayAdd(); + + String text = udf.evaluate("[]", "$", 1D, 2D); + Assert.assertEquals("[1,2]", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/odps_udf/JSONContainsValue_Test.java b/src/test/java/com/alibaba/json/bvt/path/odps_udf/JSONContainsValue_Test.java new file mode 100644 index 0000000000..175a195738 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/odps_udf/JSONContainsValue_Test.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.path.odps_udf; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.support.odps.udf.JSONContainsValue; + + +public class JSONContainsValue_Test extends TestCase { + public void test_contians() throws Exception { + JSONContainsValue udf = new JSONContainsValue(); + Assert.assertTrue(udf.evaluate("{\"name\":\"123\"}", "$.name", "123")); + Assert.assertFalse(udf.evaluate("{\"name\":\"123\"}", "$.name", "124")); + Assert.assertTrue(udf.evaluate("{\"name\":\"123\"}", "$.value", (Long) null)); + } + + public void test_array_contians() throws Exception { + JSONContainsValue udf = new JSONContainsValue(); + Assert.assertTrue(udf.evaluate("{\"name\":[\"123\"]}", "$.name", "123")); + Assert.assertFalse(udf.evaluate("{\"name\":[\"123\"]}", "$.name", "124")); + Assert.assertTrue(udf.evaluate("{\"name\":[\"123\"]}", "$.value", (Long) null)); + Assert.assertFalse(udf.evaluate("{\"name\":[\"123\"]}", "$.name", (Long) null)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/path/odps_udf/JSONContains_Test.java b/src/test/java/com/alibaba/json/bvt/path/odps_udf/JSONContains_Test.java new file mode 100644 index 0000000000..2036e460f0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/odps_udf/JSONContains_Test.java @@ -0,0 +1,17 @@ +package com.alibaba.json.bvt.path.odps_udf; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.support.odps.udf.JSONContains; + +public class JSONContains_Test extends TestCase { + + public void test_contians() throws Exception { + JSONContains udf = new JSONContains(); + Assert.assertTrue(udf.evaluate("{\"name\":\"123\"}", "$.name")); + Assert.assertFalse(udf.evaluate("{\"name\":\"123\"}", "$.value")); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/path/odps_udf/JSONSetTest.java b/src/test/java/com/alibaba/json/bvt/path/odps_udf/JSONSetTest.java new file mode 100644 index 0000000000..a684550cea --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/path/odps_udf/JSONSetTest.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt.path.odps_udf; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.support.odps.udf.JSONSet; + + +public class JSONSetTest extends TestCase { + public void test_udf() throws Exception { + JSONSet udf = new JSONSet(); + + String text = udf.evaluate("[0,1,2]", "$[1]", new Long(123)); + Assert.assertEquals("[0,123,2]", text); + } + + public void test_double() throws Exception { + JSONSet udf = new JSONSet(); + + String text = udf.evaluate("[1,2,3]", "[0]", 123.2D); + Assert.assertEquals("[123.2,2,3]", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/proxy/TestProxy.java b/src/test/java/com/alibaba/json/bvt/proxy/TestProxy.java new file mode 100755 index 0000000000..98f8bf8c2a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/proxy/TestProxy.java @@ -0,0 +1,53 @@ +package com.alibaba.json.bvt.proxy; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class TestProxy extends TestCase { + + public void test_0() throws Exception { + Object vo = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[] {I.class}, new VO()); + + String text = JSON.toJSONString(vo); + + System.out.println(text); + } + + public static interface I { + + } + + + public static class VO implements InvocationHandler { + + private int id; + private String name; + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return null; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/ref/TestRef.java b/src/test/java/com/alibaba/json/bvt/ref/TestRef.java new file mode 100755 index 0000000000..e5929b8c97 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ref/TestRef.java @@ -0,0 +1,117 @@ +package com.alibaba.json.bvt.ref; + +import java.util.ArrayList; +import java.util.Collection; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class TestRef extends TestCase { + + public void test_ref() throws Exception { + Department tech = new Department(1, "技术部"); + tech.setRoot(tech); + + { + Department pt = new Department(2, "平台技术部"); + pt.setParent(tech); + pt.setRoot(tech); + tech.getChildren().add(pt); + { + Department sysbase = new Department(3, "系统基础"); + sysbase.setParent(pt); + sysbase.setRoot(tech); + pt.getChildren().add(sysbase); + } + } + { + Department cn = new Department(4, "中文站技术部"); + cn.setParent(tech); + cn.setRoot(tech); + tech.getChildren().add(cn); + } + + { + //JSON.toJSONString(tech); + } + + { + String prettyText = JSON.toJSONString(tech, SerializerFeature.PrettyFormat); + System.out.println(prettyText); + + String text = JSON.toJSONString(tech); + Department dept = JSON.parseObject(text, Department.class); + Assert.assertTrue(dept == dept.getRoot()); + + System.out.println(JSON.toJSONString(dept, SerializerFeature.PrettyFormat)); + } + } + + public static class Department { + + private int id; + private String name; + + private Department parent; + private Department root; + + private Collection children = new ArrayList(); + + public Department(){ + + } + + public Department getRoot() { + return root; + } + + public void setRoot(Department root) { + this.root = root; + } + + public Department(int id, String name){ + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Department getParent() { + return parent; + } + + public void setParent(Department parent) { + this.parent = parent; + } + + public Collection getChildren() { + return children; + } + + public void setChildren(Collection children) { + this.children = children; + } + + public String toString() { + return "{id:" + id + ",name:" + name + "}"; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/ref/TestRef2.java b/src/test/java/com/alibaba/json/bvt/ref/TestRef2.java new file mode 100755 index 0000000000..a349c5b335 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ref/TestRef2.java @@ -0,0 +1,64 @@ +package com.alibaba.json.bvt.ref; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.parser.ParserConfig; + +public class TestRef2 extends TestCase { + + public void test_0() throws Exception { + Entity entity = new Entity(123, new Child()); + entity.getChild().setParent(entity); + + String text = JSON.toJSONString(entity); + System.out.println(text); + + ParserConfig config = new ParserConfig(); + config.setAsmEnable(false); + Entity entity2 = JSON.parseObject(text, Entity.class, config, 0); + + Assert.assertEquals(entity2, entity2.getChild().getParent()); + + System.out.println(JSON.toJSONString(entity2)); + } + + public static class Entity { + + private final int id; + private final Child child; + + @JSONCreator + public Entity(@JSONField(name = "id") int id, @JSONField(name = "child") Child child){ + super(); + this.id = id; + this.child = child; + } + + public int getId() { + return id; + } + + public Child getChild() { + return child; + } + + } + + public static class Child { + + private Entity parent; + + public Entity getParent() { + return parent; + } + + public void setParent(Entity parent) { + this.parent = parent; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/ref/TestRef3.java b/src/test/java/com/alibaba/json/bvt/ref/TestRef3.java new file mode 100755 index 0000000000..db5ceb68ea --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ref/TestRef3.java @@ -0,0 +1,72 @@ +package com.alibaba.json.bvt.ref; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.parser.ParserConfig; + +public class TestRef3 extends TestCase { + + public void test_0() throws Exception { + Entity entity = new Entity(123, new Child()); + entity.getChild().setParent(entity); + + String text = JSON.toJSONString(entity); + System.out.println(text); + + Entity entity2 = JSON.parseObject(text, Entity.class); + + Assert.assertEquals(entity2, entity2.getChild().getParent()); + + System.out.println(JSON.toJSONString(entity2)); + } + + public static class Entity { + + private final int id; + private final Child child; + + @JSONCreator + public Entity(@JSONField(name = "id") int id, @JSONField(name = "child") Child child){ + super(); + this.id = id; + this.child = child; + } + + public int getId() { + return id; + } + + public Child getChild() { + return child; + } + + public String toString() { + return "Entity-" + id; + } + } + + public static class Child { + + private Entity parent; + + public Child(){ + + } + + public Entity getParent() { + return parent; + } + + public void setParent(Entity parent) { + this.parent = parent; + } + + public String toString() { + return "Child"; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/ref/TestRef4.java b/src/test/java/com/alibaba/json/bvt/ref/TestRef4.java new file mode 100755 index 0000000000..0fb82d7082 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ref/TestRef4.java @@ -0,0 +1,124 @@ +package com.alibaba.json.bvt.ref; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class TestRef4 extends TestCase { + + public void test_0() throws Exception { + Group admin = new Group("admin"); + + User jobs = new User("jobs"); + User sager = new User("sager"); + User sdh5724 = new User("sdh5724"); + + admin.getMembers().add(jobs); + jobs.getGroups().add(admin); + + admin.getMembers().add(sager); + sager.getGroups().add(admin); + + admin.getMembers().add(sdh5724); + sdh5724.getGroups().add(admin); + + sager.setReportTo(sdh5724); + jobs.setReportTo(sdh5724); + + SerializeConfig serializeConfig = new SerializeConfig(); + serializeConfig.setAsmEnable(false); + String text = JSON.toJSONString(admin, serializeConfig, SerializerFeature.PrettyFormat); + System.out.println(text); + + ParserConfig config = new ParserConfig(); + config.setAsmEnable(false); + + JSON.parseObject(text, Group.class, config, 0); + } + + public static class Group { + + private String name; + + private List members = new ArrayList(); + + public Group(){ + + } + + public Group(String name){ + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getMembers() { + return members; + } + + public void setMembers(List members) { + this.members = members; + } + + public String toString() { + return this.name; + } + } + + public static class User { + + private String name; + + private List groups = new ArrayList(); + + private User reportTo; + + public User(){ + + } + + public User getReportTo() { + return reportTo; + } + + public void setReportTo(User reportTo) { + this.reportTo = reportTo; + } + + public User(String name){ + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getGroups() { + return groups; + } + + public void setGroups(List groups) { + this.groups = groups; + } + + public String toString() { + return this.name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/ref/TestRef5.java b/src/test/java/com/alibaba/json/bvt/ref/TestRef5.java new file mode 100755 index 0000000000..389ff03054 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ref/TestRef5.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.ref; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + + +public class TestRef5 extends TestCase { + public void test_0 () throws Exception { + List a = new ArrayList(); + List b = new ArrayList(); + List c = new ArrayList(); + List d = new ArrayList(); + + a.add(b); + a.add(c); + a.add(d); + + b.add(a); + b.add(c); + b.add(d); + + c.add(a); + c.add(b); + c.add(d); + + d.add(a); + d.add(b); + d.add(c); + + String text = JSON.toJSONString(a); + System.out.println(text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/ref/TestRef6.java b/src/test/java/com/alibaba/json/bvt/ref/TestRef6.java new file mode 100755 index 0000000000..b3334efd10 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ref/TestRef6.java @@ -0,0 +1,81 @@ +package com.alibaba.json.bvt.ref; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class TestRef6 extends TestCase { + + public void test_0() throws Exception { + + Person pA = new Person("a"); + Person pB = new Person("b"); + + Family fA = new Family(); + fA.setMembers(new Person[] { pA, pB }); + fA.setMaster(pA); + + Person pC = new Person("c"); + Person pD = new Person("d"); + + Family fB = new Family(); + fB.setMembers(new Person[] { pC, pD }); + fB.setMaster(pC); + + Family[] familyArray = new Family[] { fA, fB }; + String text = JSON.toJSONString(familyArray); + System.out.println(text); + + Family[] result = JSON.parseObject(text, Family[].class); + + Assert.assertSame(result[0].getMaster(), result[0].getMembers()[0]); + Assert.assertSame(result[1].getMaster(), result[1].getMembers()[0]); + + } + + public static class Family { + + private Person master; + private Person[] members; + + public Person getMaster() { + return master; + } + + public void setMaster(Person master) { + this.master = master; + } + + public Person[] getMembers() { + return members; + } + + public void setMembers(Person[] members) { + this.members = members; + } + + } + + public static class Person { + + private String name; + + public Person(){ + + } + + public Person(String name){ + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/ref/TestRef7.java b/src/test/java/com/alibaba/json/bvt/ref/TestRef7.java new file mode 100755 index 0000000000..9d9e6ab0a5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/ref/TestRef7.java @@ -0,0 +1,84 @@ +package com.alibaba.json.bvt.ref; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; + +public class TestRef7 extends TestCase { + + public void test_0() throws Exception { + + Person pA = new Person("a"); + Person pB = new Person("b"); + + Family fA = new Family(); + fA.setMembers(new Person[] { pA, pB }); + fA.setMaster(pA); + + Person pC = new Person("c"); + Person pD = new Person("d"); + + Family fB = new Family(); + fB.setMembers(new Person[] { pC, pD }); + fB.setMaster(pC); + + Family[] familyArray = new Family[] { fA, fB }; + String text = JSON.toJSONString(familyArray, true); + System.out.println(text); + + JSONArray array = JSON.parseArray(text); + + Assert.assertSame(array.getJSONObject(0).get("master"), array.getJSONObject(0).getJSONArray("members").get(0)); + + Family family = array.getObject(0, Family.class); + Assert.assertNotNull(family.getMembers()[0]); + Assert.assertNotNull(family.getMembers()[1]); + } + + public static class Family { + + private Person master; + private Person[] members; + + public Person getMaster() { + return master; + } + + public void setMaster(Person master) { + this.master = master; + } + + public Person[] getMembers() { + return members; + } + + public void setMembers(Person[] members) { + this.members = members; + } + + } + + public static class Person { + + private String name; + + public Person(){ + + } + + public Person(String name){ + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/AbstractTest.java b/src/test/java/com/alibaba/json/bvt/serializer/AbstractTest.java new file mode 100644 index 0000000000..8fc7d2b8f5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/AbstractTest.java @@ -0,0 +1,106 @@ +package com.alibaba.json.bvt.serializer; + +import java.lang.reflect.Type; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +public class AbstractTest extends TestCase { + + public void test_0() throws Exception { + ParserConfig.getGlobalInstance().putDeserializer(A.class, new ADeserializer()); + VO vo = JSON.parseObject("{\"a\":{\"num\":1,\"name\":\"bb\"}}", VO.class); + Assert.assertTrue(vo.getA() instanceof B); + } + + public void test_1() throws Exception { + ParserConfig.getGlobalInstance().putDeserializer(A.class, new ADeserializer()); + VO vo = JSON.parseObject("{\"a\":{\"num\":2,\"name\":\"bb\"}}", VO.class); + Assert.assertTrue(vo.getA() instanceof C); + } + + + public static class ADeserializer implements ObjectDeserializer { + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + JSONObject json = parser.parseObject(); + int num = json.getInteger("num"); + if (num == 1) { + return (T) JSON.toJavaObject(json, B.class); + } else if (num == 2) { + return (T) JSON.toJavaObject(json, C.class); + } else { + return (T) JSON.toJavaObject(json, A.class); + } + } + + public int getFastMatchToken() { + return JSONToken.LBRACE; + } + + } + + public static class VO { + + private A a; + + public A getA() { + return a; + } + + public void setA(A a) { + this.a = a; + } + + } + + public static class A { + + private int num; + + public int getNum() { + return num; + } + + public void setNum(int num) { + this.num = num; + } + } + + public static class B extends A { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + + public static class C extends A { + + public String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/AfterFilterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/AfterFilterTest.java new file mode 100644 index 0000000000..4f20d19856 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/AfterFilterTest.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.AfterFilter; +import com.alibaba.fastjson.serializer.BeforeFilter; + +public class AfterFilterTest extends TestCase { + public void test_afterFilter() throws Exception { + AfterFilter filter = new AfterFilter() { + + @Override + public void writeAfter(Object object) { + this.writeKeyValue("id", 123); + } + }; + Assert.assertEquals("{\"id\":123}",JSON.toJSONString( new VO(), filter)); + } + + public void test_afterFilter2() throws Exception { + AfterFilter filter = new AfterFilter() { + + @Override + public void writeAfter(Object object) { + this.writeKeyValue("id", 123); + this.writeKeyValue("name", "wenshao"); + } + }; + Assert.assertEquals("{\"id\":123,\"name\":\"wenshao\"}", JSON.toJSONString(new VO(), filter)); + } + + private static class VO { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/AfterFilterTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/AfterFilterTest2.java new file mode 100644 index 0000000000..ff4e28a325 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/AfterFilterTest2.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.AfterFilter; +import com.alibaba.fastjson.serializer.BeforeFilter; + +public class AfterFilterTest2 extends TestCase { + public void test_afterFilter() throws Exception { + AfterFilter filter = new AfterFilter() { + + @Override + public void writeAfter(Object object) { + this.writeKeyValue("id", 123); + } + }; + Assert.assertEquals("{\"id\":123}",JSON.toJSONString( new VO(), filter)); + } + + public void test_afterFilter2() throws Exception { + AfterFilter filter = new AfterFilter() { + + @Override + public void writeAfter(Object object) { + this.writeKeyValue("id", 123); + this.writeKeyValue("name", "wenshao"); + } + }; + Assert.assertEquals("{\"id\":123,\"name\":\"wenshao\"}", JSON.toJSONString(new VO(), filter)); + } + + public static class VO { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/AfterFilterTest3.java b/src/test/java/com/alibaba/json/bvt/serializer/AfterFilterTest3.java new file mode 100644 index 0000000000..8d87dc5ef6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/AfterFilterTest3.java @@ -0,0 +1,48 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.AfterFilter; + +public class AfterFilterTest3 extends TestCase { + + public void test_afterFilter() throws Exception { + AfterFilter filter = new AfterFilter() { + + @Override + public void writeAfter(Object object) { + this.writeKeyValue("id", 123); + } + }; + Assert.assertEquals(JSON.toJSONString(new VO(), filter), "{\"value\":1001,\"id\":123}"); + } + + public void test_afterFilter2() throws Exception { + AfterFilter filter = new AfterFilter() { + + @Override + public void writeAfter(Object object) { + this.writeKeyValue("id", 123); + this.writeKeyValue("name", "wenshao"); + } + }; + Assert.assertEquals(JSON.toJSONString(new VO(), filter), "{\"value\":1001,\"id\":123,\"name\":\"wenshao\"}"); + } + + public static class VO { + + private int value = 1001; + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/AppendableTest.java b/src/test/java/com/alibaba/json/bvt/serializer/AppendableTest.java old mode 100644 new mode 100755 similarity index 89% rename from src/test/java/com/alibaba/json/test/bvt/serializer/AppendableTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/AppendableTest.java index 2d8013de7b..45226dca7d --- a/src/test/java/com/alibaba/json/test/bvt/serializer/AppendableTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/AppendableTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.io.StringWriter; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/ArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ArraySerializerTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/serializer/ArraySerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/ArraySerializerTest.java index 7880f82649..cec0aea461 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/ArraySerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/ArraySerializerTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/BeforeFilterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/BeforeFilterTest.java new file mode 100644 index 0000000000..332e0f7043 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/BeforeFilterTest.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.BeforeFilter; + +public class BeforeFilterTest extends TestCase { + public void test_beforeFilter() throws Exception { + BeforeFilter filter = new BeforeFilter() { + + @Override + public void writeBefore(Object object) { + this.writeKeyValue("id", 123); + } + }; + Assert.assertEquals("{\"id\":123}",JSON.toJSONString( new VO(), filter)); + } + + public void test_beforeFilter2() throws Exception { + BeforeFilter filter = new BeforeFilter() { + + @Override + public void writeBefore(Object object) { + this.writeKeyValue("id", 123); + this.writeKeyValue("name", "wenshao"); + } + }; + Assert.assertEquals("{\"id\":123,\"name\":\"wenshao\"}", JSON.toJSONString(new VO(), filter)); + } + + private static class VO { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/BeforeFilterTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/BeforeFilterTest2.java new file mode 100644 index 0000000000..607cdd33d3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/BeforeFilterTest2.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.BeforeFilter; + +public class BeforeFilterTest2 extends TestCase { + public void test_beforeFilter() throws Exception { + BeforeFilter filter = new BeforeFilter() { + + @Override + public void writeBefore(Object object) { + this.writeKeyValue("id", 123); + } + }; + Assert.assertEquals(JSON.toJSONString(new VO(), filter), "{\"id\":123}"); + } + + public void test_beforeFilter2() throws Exception { + BeforeFilter filter = new BeforeFilter() { + + @Override + public void writeBefore(Object object) { + this.writeKeyValue("id", 123); + this.writeKeyValue("name", "wenshao"); + } + }; + Assert.assertEquals(JSON.toJSONString(new VO(), filter), "{\"id\":123,\"name\":\"wenshao\"}"); + } + + public static class VO { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/BeforeFilterTest3.java b/src/test/java/com/alibaba/json/bvt/serializer/BeforeFilterTest3.java new file mode 100644 index 0000000000..da3aac7419 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/BeforeFilterTest3.java @@ -0,0 +1,48 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.BeforeFilter; + +public class BeforeFilterTest3 extends TestCase { + + public void test_beforeFilter() throws Exception { + BeforeFilter filter = new BeforeFilter() { + + @Override + public void writeBefore(Object object) { + this.writeKeyValue("id", 123); + } + }; + Assert.assertEquals(JSON.toJSONString(new VO(), filter), "{\"id\":123,\"value\":1001}"); + } + + public void test_beforeFilter2() throws Exception { + BeforeFilter filter = new BeforeFilter() { + + @Override + public void writeBefore(Object object) { + this.writeKeyValue("id", 123); + this.writeKeyValue("name", "wenshao"); + } + }; + Assert.assertEquals(JSON.toJSONString(new VO(), filter), "{\"id\":123,\"name\":\"wenshao\",\"value\":1001}"); + } + + public static class VO { + + private int value = 1001; + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/BooleanArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/BooleanArraySerializerTest.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/serializer/BooleanArraySerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/BooleanArraySerializerTest.java index a324f53293..a09042e24a --- a/src/test/java/com/alibaba/json/test/bvt/serializer/BooleanArraySerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/BooleanArraySerializerTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/BooleanFieldSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/BooleanFieldSerializerTest.java old mode 100644 new mode 100755 similarity index 98% rename from src/test/java/com/alibaba/json/test/bvt/serializer/BooleanFieldSerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/BooleanFieldSerializerTest.java index 376449ee86..4c60574c7a --- a/src/test/java/com/alibaba/json/test/bvt/serializer/BooleanFieldSerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/BooleanFieldSerializerTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.lang.reflect.Type; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/BooleanFieldSerializerTest_primitive.java b/src/test/java/com/alibaba/json/bvt/serializer/BooleanFieldSerializerTest_primitive.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/serializer/BooleanFieldSerializerTest_primitive.java rename to src/test/java/com/alibaba/json/bvt/serializer/BooleanFieldSerializerTest_primitive.java index 6ce00f6ae6..8714aa3ad6 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/BooleanFieldSerializerTest_primitive.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/BooleanFieldSerializerTest_primitive.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.lang.reflect.Type; @@ -13,7 +13,7 @@ import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.serializer.SerializeConfig; import com.alibaba.fastjson.serializer.SerializerFeature; -import com.alibaba.json.test.bvt.serializer.BooleanFieldSerializerTest.Entity; +import com.alibaba.json.bvt.serializer.BooleanFieldSerializerTest.Entity; public class BooleanFieldSerializerTest_primitive extends TestCase { diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/BugTest0.java b/src/test/java/com/alibaba/json/bvt/serializer/BugTest0.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/serializer/BugTest0.java rename to src/test/java/com/alibaba/json/bvt/serializer/BugTest0.java index c22afe5707..e9abec33c4 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/BugTest0.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/BugTest0.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.sql.Date; import java.sql.Timestamp; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/BugTest1.java b/src/test/java/com/alibaba/json/bvt/serializer/BugTest1.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/serializer/BugTest1.java rename to src/test/java/com/alibaba/json/bvt/serializer/BugTest1.java index bcc4b4f555..96c2cb3144 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/BugTest1.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/BugTest1.java @@ -1,11 +1,11 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/BugTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/BugTest2.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/serializer/BugTest2.java rename to src/test/java/com/alibaba/json/bvt/serializer/BugTest2.java index ce6ca69f32..9290dff191 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/BugTest2.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/BugTest2.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import junit.framework.TestCase; import net.sf.json.JSONObject; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/ByteArrayFieldSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ByteArrayFieldSerializerTest.java old mode 100644 new mode 100755 similarity index 79% rename from src/test/java/com/alibaba/json/test/bvt/serializer/ByteArrayFieldSerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/ByteArrayFieldSerializerTest.java index 78bba6256f..51b569dba9 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/ByteArrayFieldSerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/ByteArrayFieldSerializerTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -12,7 +12,7 @@ public void test_0() throws Exception { A a1 = new A(); a1.setBytes(new byte[] { 1, 2 }); - Assert.assertEquals("{\"bytes\":[1,2]}", JSON.toJSONString(a1)); + Assert.assertEquals("{\"bytes\":\"AQI=\"}", JSON.toJSONString(a1)); } public void test_1() throws Exception { diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/ByteArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ByteArraySerializerTest.java old mode 100644 new mode 100755 similarity index 67% rename from src/test/java/com/alibaba/json/test/bvt/serializer/ByteArraySerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/ByteArraySerializerTest.java index 3a34e6dad6..3f93af6cf5 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/ByteArraySerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/ByteArraySerializerTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import junit.framework.TestCase; @@ -16,9 +16,9 @@ public void test_b_0() { } public void test_0() { - Assert.assertEquals("[]", JSON.toJSONString(new byte[0])); - Assert.assertEquals("[1,2]", JSON.toJSONString(new byte[] { 1, 2 })); - Assert.assertEquals("[1,2,3]", JSON.toJSONString(new byte[] { 1, 2, 3 })); + Assert.assertEquals("\"\"", JSON.toJSONString(new byte[0])); + Assert.assertEquals("\"AQI=\"", JSON.toJSONString(new byte[] { 1, 2 })); + Assert.assertEquals("\"AQID\"", JSON.toJSONString(new byte[] { 1, 2, 3 })); Assert.assertEquals("1", JSON.toJSONString((byte) 1)); Assert.assertEquals("1", JSON.toJSONString((short) 1)); @@ -28,12 +28,12 @@ public void test_0() { public void test_1() throws Exception { SerializeWriter out = new SerializeWriter(1); out.writeByteArray(new byte[] { 1, 2, 3 }); - Assert.assertEquals("[1,2,3]", out.toString()); + Assert.assertEquals("\"AQID\"", out.toString()); } public void test_2() throws Exception { SerializeWriter out = new SerializeWriter(100); out.writeByteArray(new byte[] { 1, 2, 3 }); - Assert.assertEquals("[1,2,3]", out.toString()); + Assert.assertEquals("\"AQID\"", out.toString()); } } diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/ByteArrayTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ByteArrayTest.java old mode 100644 new mode 100755 similarity index 88% rename from src/test/java/com/alibaba/json/test/bvt/serializer/ByteArrayTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/ByteArrayTest.java index 7d008eff3a..ece915c441 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/ByteArrayTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/ByteArrayTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -32,10 +32,10 @@ public void test_bytes_1() throws Exception { SerializerFeature[] features = { SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty }; String text1 = JSON.toJSONString(vo, mapping, features); - Assert.assertEquals("{\"value\":[1,2,3]}", text1); + Assert.assertEquals("{\"value\":\"AQID\"}", text1); String text2 = JSON.toJSONString(vo, features); - Assert.assertEquals("{\"value\":[1,2,3]}", text2); + Assert.assertEquals("{\"value\":\"AQID\"}", text2); } public static class VO { diff --git a/src/test/java/com/alibaba/json/bvt/serializer/CharArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/CharArraySerializerTest.java new file mode 100755 index 0000000000..8b1e9d875d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/CharArraySerializerTest.java @@ -0,0 +1,31 @@ +package com.alibaba.json.bvt.serializer; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +import org.junit.Assert; +import junit.framework.TestCase; + +public class CharArraySerializerTest extends TestCase { + + public void test_null() throws Exception { + VO vo = new VO(); + + Assert.assertEquals("{\"value\":[]}", JSON.toJSONString(vo, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty)); + Assert.assertEquals("{\"value\":null}", JSON.toJSONString(vo, SerializerFeature.WriteMapNullValue)); + } + + private static class VO { + + private char[] value; + + public char[] getValue() { + return value; + } + + public void setValue(char[] value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/CharTest.java b/src/test/java/com/alibaba/json/bvt/serializer/CharTest.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/serializer/CharTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/CharTest.java index 429ac8e807..4692aa09c1 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/CharTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/CharTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/CharsetSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/CharsetSerializerTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/serializer/CharsetSerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/CharsetSerializerTest.java index b9fda8eb87..676a957291 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/CharsetSerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/CharsetSerializerTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.nio.charset.Charset; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/CharsetTest.java b/src/test/java/com/alibaba/json/bvt/serializer/CharsetTest.java old mode 100644 new mode 100755 similarity index 86% rename from src/test/java/com/alibaba/json/test/bvt/serializer/CharsetTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/CharsetTest.java index 9f8f7e2e7a..d3accfc07f --- a/src/test/java/com/alibaba/json/test/bvt/serializer/CharsetTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/CharsetTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.nio.charset.Charset; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/CircularReferencesTest.java b/src/test/java/com/alibaba/json/bvt/serializer/CircularReferencesTest.java old mode 100644 new mode 100755 similarity index 57% rename from src/test/java/com/alibaba/json/test/bvt/serializer/CircularReferencesTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/CircularReferencesTest.java index 9909da9cef..62c721db76 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/CircularReferencesTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/CircularReferencesTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -14,13 +14,9 @@ public void test_0() throws Exception { B b = new B(a); a.setB(b); - JSONException error = null; - try { - JSON.toJSONString(a); - } catch (JSONException e) { - error = e; - } - Assert.assertNotNull(error); + String text = JSON.toJSONString(a); + A a1 = JSON.parseObject(text, A.class); + Assert.assertTrue(a1 == a1.getB().getA()); } public void test_1() throws Exception { @@ -28,13 +24,9 @@ public void test_1() throws Exception { B b = new B(a); a.setB(b); - JSONException error = null; - try { - JSON.toJSONString(a, SerializerFeature.UseISO8601DateFormat); - } catch (JSONException e) { - error = e; - } - Assert.assertNotNull(error); + String text = JSON.toJSONString(a, SerializerFeature.UseISO8601DateFormat); + A a1 = JSON.parseObject(text, A.class); + Assert.assertTrue(a1 == a1.getB().getA()); } public void test_2() throws Exception { @@ -42,13 +34,9 @@ public void test_2() throws Exception { B b = new B(a); a.setB(b); - JSONException error = null; - try { - JSON.toJSONString(a, true); - } catch (JSONException e) { - error = e; - } - Assert.assertNotNull(error); + String text = JSON.toJSONString(a, true); + A a1 = JSON.parseObject(text, A.class); + Assert.assertTrue(a1 == a1.getB().getA()); } public static class A { @@ -76,6 +64,10 @@ public static class B { private A a; + public B(){ + + } + public B(A a){ this.a = a; } @@ -83,6 +75,9 @@ public B(A a){ public A getA() { return a; } - + + public void setA(A a) { + this.a = a; + } } } diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ClassFieldTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ClassFieldTest.java new file mode 100644 index 0000000000..aeecfc25f9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ClassFieldTest.java @@ -0,0 +1,29 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class ClassFieldTest extends TestCase { + + public void test_writer_1() throws Exception { + VO vo = JSON.parseObject("{\"value\":\"int\"}", VO.class); + Assert.assertEquals(int.class, vo.getValue()); + } + + public static class VO { + + private Class value; + + public Class getValue() { + return value; + } + + public void setValue(Class value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ClassLoaderTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ClassLoaderTest.java new file mode 100644 index 0000000000..04e5f325ac --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ClassLoaderTest.java @@ -0,0 +1,108 @@ +package com.alibaba.json.bvt.serializer; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.net.URL; +import java.util.Enumeration; +import java.util.Set; +import java.util.Vector; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.util.ServiceLoader; +import com.alibaba.json.demo.X; + +public class ClassLoaderTest extends TestCase { + + private ClassLoader ctxLoader; + + protected void setUp() throws Exception { + ctxLoader = Thread.currentThread().getContextClassLoader(); + } + + protected void tearDown() throws Exception { + Thread.currentThread().setContextClassLoader(ctxLoader); + } + + public void test_error() throws Exception { + Field field = ServiceLoader.class.getDeclaredField("loadedUrls"); + field.setAccessible(true); + Set loadedUrls = (Set) field.get(null); + + Thread.currentThread().setContextClassLoader(new MyClassLoader(new ClassCastException())); + JSON.toJSONString(new A()); + + loadedUrls.clear(); + + Thread.currentThread().setContextClassLoader(new MyClassLoader(new IOException())); + JSON.toJSONString(new B()); + + loadedUrls.clear(); + + Thread.currentThread().setContextClassLoader(new EmptyClassLoader()); + JSON.toJSONString(new C()); + + loadedUrls.clear(); + + Thread.currentThread().setContextClassLoader(new ErrorClassLoader()); + JSON.toJSONString(new D()); + + loadedUrls.clear(); + + Thread.currentThread().setContextClassLoader(ctxLoader); + JSON.toJSONString(new E()); + } + + public static class EmptyClassLoader extends ClassLoader { + + public Enumeration getResources(String name) throws IOException { + return new Vector().elements(); + } + } + + public static class ErrorClassLoader extends ClassLoader { + + public Class loadClass(String name) throws ClassNotFoundException { + return Object.class; + } + } + + public static class MyClassLoader extends ClassLoader { + + private final Exception error; + + public MyClassLoader(Exception error){ + super(); + this.error = error; + } + + public Enumeration getResources(String name) throws IOException { + if (error instanceof IOException) { + throw (IOException) error; + } + throw (RuntimeException) error; + } + } + + public class A { + + } + + public class B { + + } + + public class C { + + } + + public class D { + + } + + public class E { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ClobSeriliazerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ClobSeriliazerTest.java new file mode 100644 index 0000000000..1faf861033 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ClobSeriliazerTest.java @@ -0,0 +1,144 @@ +package com.alibaba.json.bvt.serializer; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.StringReader; +import java.io.Writer; +import java.sql.Clob; +import java.sql.SQLException; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class ClobSeriliazerTest extends TestCase { + public void test_clob() throws Exception { + Assert.assertEquals("\"abcdefg中国\"", + JSON.toJSONString(new MockClob("abcdefg中国"))); + } + + public void test_clob_null() throws Exception { + Assert.assertEquals("{\"value\":null}", JSON.toJSONString(new VO(), + SerializerFeature.WriteMapNullValue)); + } + + public void test_clob_error() throws Exception { + Exception error = null; + try { + JSON.toJSONString(new MockClob(new SQLException())); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + @SuppressWarnings("unused") + private static class VO { + private Clob value; + + public Clob getValue() { + return value; + } + + public void setValue(Clob value) { + this.value = value; + } + } + + public static class MockClob implements Clob { + private final String text; + + private SQLException error; + + public MockClob(String text) { + this.text = text; + } + + public MockClob(SQLException error) { + this.text = null; + this.error = error; + } + + public SQLException getError() { + return error; + } + + public void setError(SQLException error) { + this.error = error; + } + + public long length() throws SQLException { + // TODO Auto-generated method stub + return 0; + } + + public String getSubString(long pos, int length) throws SQLException { + // TODO Auto-generated method stub + return null; + } + + public Reader getCharacterStream() throws SQLException { + if (error != null) { + throw error; + } + return new StringReader(text); + } + + public InputStream getAsciiStream() throws SQLException { + // TODO Auto-generated method stub + return null; + } + + public long position(String searchstr, long start) throws SQLException { + // TODO Auto-generated method stub + return 0; + } + + public long position(Clob searchstr, long start) throws SQLException { + // TODO Auto-generated method stub + return 0; + } + + public int setString(long pos, String str) throws SQLException { + // TODO Auto-generated method stub + return 0; + } + + public int setString(long pos, String str, int offset, int len) + throws SQLException { + // TODO Auto-generated method stub + return 0; + } + + public OutputStream setAsciiStream(long pos) throws SQLException { + // TODO Auto-generated method stub + return null; + } + + public Writer setCharacterStream(long pos) throws SQLException { + // TODO Auto-generated method stub + return null; + } + + public void truncate(long len) throws SQLException { + // TODO Auto-generated method stub + + } + + public void free() throws SQLException { + // TODO Auto-generated method stub + + } + + public Reader getCharacterStream(long pos, long length) + throws SQLException { + // TODO Auto-generated method stub + return null; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/CollectionSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/CollectionSerializerTest.java old mode 100644 new mode 100755 similarity index 82% rename from src/test/java/com/alibaba/json/test/bvt/serializer/CollectionSerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/CollectionSerializerTest.java index 39cb95c21c..29541ec224 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/CollectionSerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/CollectionSerializerTest.java @@ -1,10 +1,10 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.CollectionSerializer; @@ -17,7 +17,7 @@ public void test_0() throws Exception { SerializeWriter out = new SerializeWriter(); CollectionSerializer listSerializer = new CollectionSerializer(); - listSerializer.write(new JSONSerializer(out), Collections.EMPTY_LIST); + listSerializer.write(new JSONSerializer(out), Collections.EMPTY_LIST, null, null, 0); Assert.assertEquals("[]", out.toString()); } @@ -26,7 +26,7 @@ public void test_1() throws Exception { SerializeWriter out = new SerializeWriter(); CollectionSerializer listSerializer = new CollectionSerializer(); - listSerializer.write(new JSONSerializer(out), Collections.singletonList(1)); + listSerializer.write(new JSONSerializer(out), Collections.singletonList(1), null, null, 0); Assert.assertEquals("[1]", out.toString()); } @@ -38,7 +38,7 @@ public void test_2_s() throws Exception { List list = new ArrayList(); list.add(1); list.add(2); - listSerializer.write(new JSONSerializer(out), list); + listSerializer.write(new JSONSerializer(out), list, null, null, 0); Assert.assertEquals("[1,2]", out.toString()); } @@ -51,7 +51,7 @@ public void test_3_s() throws Exception { list.add(1); list.add(2); list.add(3); - listSerializer.write(new JSONSerializer(out), list); + listSerializer.write(new JSONSerializer(out), list, null, null, 0); Assert.assertEquals("[1,2,3]", out.toString()); } @@ -65,7 +65,7 @@ public void test_4_s() throws Exception { list.add(2L); list.add(3L); list.add(Collections.emptyMap()); - listSerializer.write(new JSONSerializer(out), list); + listSerializer.write(new JSONSerializer(out), list, null, null, 0); Assert.assertEquals("[1,2,3,{}]", out.toString()); } @@ -80,7 +80,7 @@ public void test_5_s() throws Exception { list.add(null); list.add(Collections.emptyMap()); list.add(21474836480L); - listSerializer.write(new JSONSerializer(out), list); + listSerializer.write(new JSONSerializer(out), list, null, null, 0); Assert.assertEquals("[1,21474836480,null,{},21474836480]", out.toString()); } diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ColorSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ColorSerializerTest.java new file mode 100755 index 0000000000..59d4ecaf5b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ColorSerializerTest.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.serializer; + +import java.awt.Color; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.ColorCodec; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class ColorSerializerTest extends TestCase { + + public void test_null() throws Exception { + JSONSerializer serializer = new JSONSerializer(); + Assert.assertEquals(ColorCodec.class, serializer.getObjectWriter(Color.class).getClass()); + + VO vo = new VO(); + + Assert.assertEquals("{\"value\":null}", JSON.toJSONString(vo, SerializerFeature.WriteMapNullValue)); + } + + public void test_rgb() throws Exception { + JSONSerializer serializer = new JSONSerializer(); + Assert.assertEquals(ColorCodec.class, serializer.getObjectWriter(Color.class).getClass()); + + VO vo = new VO(); + vo.setValue(new Color(1,1,1,0)); + + Assert.assertEquals("{\"value\":{\"r\":1,\"g\":1,\"b\":1}}", JSON.toJSONString(vo, SerializerFeature.WriteMapNullValue)); + } + + public void test_rgb_getAutowiredFor() throws Exception { + + } + + private static class VO { + + private Color value; + + public Color getValue() { + return value; + } + + public void setValue(Color value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest.java new file mode 100644 index 0000000000..0e4fb72a18 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest.java @@ -0,0 +1,56 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class ConcurrentHashMapTest extends TestCase { + + public void test_concurrentHashmap() throws Exception { + OffsetSerializeWrapper wrapper = new OffsetSerializeWrapper(); + wrapper.getOffsetTable().put(new MessageQueue(), new AtomicLong(123)); + String text = JSON.toJSONString(wrapper); + Assert.assertEquals("{\"offsetTable\":{{\"items\":[]}:123}}", text); + + OffsetSerializeWrapper wrapper2 = JSON.parseObject(text, OffsetSerializeWrapper.class); + Assert.assertEquals(1, wrapper2.getOffsetTable().size()); + + Iterator> iter = wrapper2.getOffsetTable().entrySet().iterator(); + Map.Entry entry = iter.next(); + Assert.assertEquals(0, entry.getKey().getItems().size()); + Assert.assertEquals(123L, entry.getValue().longValue()); + } + + public static class OffsetSerializeWrapper { + + private ConcurrentHashMap offsetTable = new ConcurrentHashMap(); + + public ConcurrentHashMap getOffsetTable() { + return offsetTable; + } + + public void setOffsetTable(ConcurrentHashMap offsetTable) { + this.offsetTable = offsetTable; + } + + } + + public static class MessageQueue { + + private List items = new LinkedList(); + + public List getItems() { + return items; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest2.java new file mode 100644 index 0000000000..0c309baee1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest2.java @@ -0,0 +1,56 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class ConcurrentHashMapTest2 extends TestCase { + + public void test_concurrentHashmap() throws Exception { + OffsetSerializeWrapper wrapper = new OffsetSerializeWrapper(); + wrapper.getOffsetTable().put(new MessageQueue(), new AtomicInteger(123)); + String text = JSON.toJSONString(wrapper); + Assert.assertEquals("{\"offsetTable\":{{\"items\":[]}:123}}", text); + + OffsetSerializeWrapper wrapper2 = JSON.parseObject(text, OffsetSerializeWrapper.class); + Assert.assertEquals(1, wrapper2.getOffsetTable().size()); + + Iterator> iter = wrapper2.getOffsetTable().entrySet().iterator(); + Map.Entry entry = iter.next(); + Assert.assertEquals(0, entry.getKey().getItems().size()); + Assert.assertEquals(123, entry.getValue().intValue()); + } + + public static class OffsetSerializeWrapper { + + private ConcurrentHashMap offsetTable = new ConcurrentHashMap(); + + public ConcurrentHashMap getOffsetTable() { + return offsetTable; + } + + public void setOffsetTable(ConcurrentHashMap offsetTable) { + this.offsetTable = offsetTable; + } + + } + + public static class MessageQueue { + + private List items = new LinkedList(); + + public List getItems() { + return items; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest3.java b/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest3.java new file mode 100644 index 0000000000..b3a3c02c1d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest3.java @@ -0,0 +1,56 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class ConcurrentHashMapTest3 extends TestCase { + + public void test_concurrentHashmap() throws Exception { + OffsetSerializeWrapper wrapper = new OffsetSerializeWrapper(); + wrapper.getOffsetTable().put(new MessageQueue(), new AtomicBoolean(true)); + String text = JSON.toJSONString(wrapper); + Assert.assertEquals("{\"offsetTable\":{{\"items\":[]}:true}}", text); + + OffsetSerializeWrapper wrapper2 = JSON.parseObject(text, OffsetSerializeWrapper.class); + Assert.assertEquals(1, wrapper2.getOffsetTable().size()); + + Iterator> iter = wrapper2.getOffsetTable().entrySet().iterator(); + Map.Entry entry = iter.next(); + Assert.assertEquals(0, entry.getKey().getItems().size()); + Assert.assertEquals(true, entry.getValue().get()); + } + + public static class OffsetSerializeWrapper { + + private ConcurrentHashMap offsetTable = new ConcurrentHashMap(); + + public ConcurrentHashMap getOffsetTable() { + return offsetTable; + } + + public void setOffsetTable(ConcurrentHashMap offsetTable) { + this.offsetTable = offsetTable; + } + + } + + public static class MessageQueue { + + private List items = new LinkedList(); + + public List getItems() { + return items; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest4.java b/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest4.java new file mode 100644 index 0000000000..2497498a0a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest4.java @@ -0,0 +1,79 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicReference; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class ConcurrentHashMapTest4 extends TestCase { + + public void test_concurrentHashmap() throws Exception { + OffsetSerializeWrapper wrapper = new OffsetSerializeWrapper(); + wrapper.getOffsetTable().put(new MessageQueue(), new AtomicReference(new A(true))); + String text = JSON.toJSONString(wrapper); + Assert.assertEquals("{\"offsetTable\":{{\"items\":[]}:{\"value\":true}}}", text); + + OffsetSerializeWrapper wrapper2 = JSON.parseObject(text, OffsetSerializeWrapper.class); + Assert.assertEquals(1, wrapper2.getOffsetTable().size()); + + Iterator>> iter = wrapper2.getOffsetTable().entrySet().iterator(); + Map.Entry> entry = iter.next(); + Assert.assertEquals(0, entry.getKey().getItems().size()); + Assert.assertEquals(true, entry.getValue().get().isValue()); + } + + public static class OffsetSerializeWrapper { + + private ConcurrentHashMap> offsetTable = new ConcurrentHashMap>(); + + public ConcurrentHashMap> getOffsetTable() { + return offsetTable; + } + + public void setOffsetTable(ConcurrentHashMap> offsetTable) { + this.offsetTable = offsetTable; + } + + } + + public static class MessageQueue { + + private List items = new LinkedList(); + + public List getItems() { + return items; + } + + } + + public static class A { + + private boolean value; + + public A(){ + + } + + public A(boolean value){ + super(); + this.value = value; + } + + public boolean isValue() { + return value; + } + + public void setValue(boolean value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest5.java b/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest5.java new file mode 100644 index 0000000000..84c93f6124 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest5.java @@ -0,0 +1,79 @@ +package com.alibaba.json.bvt.serializer; + +import java.lang.ref.WeakReference; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class ConcurrentHashMapTest5 extends TestCase { + + public void test_concurrentHashmap() throws Exception { + OffsetSerializeWrapper wrapper = new OffsetSerializeWrapper(); + wrapper.getOffsetTable().put(new MessageQueue(), new WeakReference(new A(true))); + String text = JSON.toJSONString(wrapper); + Assert.assertEquals("{\"offsetTable\":{{\"items\":[]}:{\"value\":true}}}", text); + + OffsetSerializeWrapper wrapper2 = JSON.parseObject(text, OffsetSerializeWrapper.class); + Assert.assertEquals(1, wrapper2.getOffsetTable().size()); + + Iterator>> iter = wrapper2.getOffsetTable().entrySet().iterator(); + Map.Entry> entry = iter.next(); + Assert.assertEquals(0, entry.getKey().getItems().size()); + Assert.assertEquals(true, entry.getValue().get().isValue()); + } + + public static class OffsetSerializeWrapper { + + private ConcurrentHashMap> offsetTable = new ConcurrentHashMap>(); + + public ConcurrentHashMap> getOffsetTable() { + return offsetTable; + } + + public void setOffsetTable(ConcurrentHashMap> offsetTable) { + this.offsetTable = offsetTable; + } + + } + + public static class MessageQueue { + + private List items = new LinkedList(); + + public List getItems() { + return items; + } + + } + + public static class A { + + private boolean value; + + public A(){ + + } + + public A(boolean value){ + super(); + this.value = value; + } + + public boolean isValue() { + return value; + } + + public void setValue(boolean value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest7.java b/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest7.java new file mode 100644 index 0000000000..c05c2d85f6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ConcurrentHashMapTest7.java @@ -0,0 +1,79 @@ +package com.alibaba.json.bvt.serializer; + +import java.lang.ref.SoftReference; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class ConcurrentHashMapTest7 extends TestCase { + + public void test_concurrentHashmap() throws Exception { + OffsetSerializeWrapper wrapper = new OffsetSerializeWrapper(); + wrapper.getOffsetTable().put(new MessageQueue(), new SoftReference(new A(true))); + String text = JSON.toJSONString(wrapper); + Assert.assertEquals("{\"offsetTable\":{{\"items\":[]}:{\"value\":true}}}", text); + + OffsetSerializeWrapper wrapper2 = JSON.parseObject(text, OffsetSerializeWrapper.class); + Assert.assertEquals(1, wrapper2.getOffsetTable().size()); + + Iterator>> iter = wrapper2.getOffsetTable().entrySet().iterator(); + Map.Entry> entry = iter.next(); + Assert.assertEquals(0, entry.getKey().getItems().size()); + Assert.assertEquals(true, entry.getValue().get().isValue()); + } + + public static class OffsetSerializeWrapper { + + private ConcurrentHashMap> offsetTable = new ConcurrentHashMap>(); + + public ConcurrentHashMap> getOffsetTable() { + return offsetTable; + } + + public void setOffsetTable(ConcurrentHashMap> offsetTable) { + this.offsetTable = offsetTable; + } + + } + + public static class MessageQueue { + + private List items = new LinkedList(); + + public List getItems() { + return items; + } + + } + + public static class A { + + private boolean value; + + public A(){ + + } + + public A(boolean value){ + super(); + this.value = value; + } + + public boolean isValue() { + return value; + } + + public void setValue(boolean value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/DateFormatSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/DateFormatSerializerTest.java new file mode 100644 index 0000000000..bf9c788194 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/DateFormatSerializerTest.java @@ -0,0 +1,82 @@ +package com.alibaba.json.bvt.serializer; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.DateFormatSerializer; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class DateFormatSerializerTest extends TestCase { + + public void test_date() throws Exception { + Assert.assertEquals("{\"format\":null}", JSON.toJSONString(new VO(), SerializerFeature.WriteMapNullValue)); + } + + public void test_date_2() throws Exception { + SerializeWriter out = new SerializeWriter(); + SerializeConfig config = new SerializeConfig(); + config.put(Date.class, DateFormatSerializer.instance); + JSONSerializer serializer = new JSONSerializer(out, config); + + serializer.config(SerializerFeature.WriteMapNullValue, true); + serializer.write(new VO()); + + Assert.assertEquals("{\"format\":null}", out.toString()); + } + + public void test_date_3() throws Exception { + SerializeWriter out = new SerializeWriter(); + SerializeConfig config = new SerializeConfig(); + config.put(Date.class, DateFormatSerializer.instance); + JSONSerializer serializer = new JSONSerializer(out, config); + + serializer.config(SerializerFeature.WriteClassName, true); + serializer.write(new VO()); + + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.serializer.DateFormatSerializerTest$VO\"}", + out.toString()); + } + + public void test_date_4() throws Exception { + SerializeWriter out = new SerializeWriter(); + SerializeConfig config = new SerializeConfig(); + config.put(Date.class, DateFormatSerializer.instance); + JSONSerializer serializer = new JSONSerializer(out, config); + + serializer.write(new VO(new SimpleDateFormat("yyyy"))); + + Assert.assertEquals("{\"format\":\"yyyy\"}", out.toString()); + + JSON.parseObject(out.toString(), VO.class); + } + + private static class VO { + + private SimpleDateFormat format; + + public VO(){ + + } + + public VO(SimpleDateFormat format){ + this.format = format; + } + + public SimpleDateFormat getFormat() { + return format; + } + + public void setFormat(SimpleDateFormat format) { + this.format = format; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/DateTest.java b/src/test/java/com/alibaba/json/bvt/serializer/DateTest.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/serializer/DateTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/DateTest.java index b82ecc0089..f29e882d31 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/DateTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/DateTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.Date; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/DateTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/DateTest2.java new file mode 100755 index 0000000000..995869c1ed --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/DateTest2.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.Date; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class DateTest2 extends TestCase { + + public void test_null() throws Exception { + long millis = System.currentTimeMillis(); + VO vo = new VO(); + vo.setValue(new Date(millis)); + + Assert.assertEquals("new Date(" + millis + ")", JSON.toJSONString(new Date(millis), SerializerFeature.WriteClassName)); + } + + public static class VO { + + private Object value; + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/DateTest3.java b/src/test/java/com/alibaba/json/bvt/serializer/DateTest3.java new file mode 100644 index 0000000000..f06e6c957e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/DateTest3.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.Date; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class DateTest3 extends TestCase { + + public void test_date() throws Exception { + String text = "{\"gmtCreate\":\"2014-08-21T09:51:36.25+07:00\"}"; + + Date date = JSON.parseObject(text, VO.class).getGmtCreate(); + Assert.assertNotNull(date); + } + + public static class VO { + + private Date gmtCreate; + + public Date getGmtCreate() { + return gmtCreate; + } + + public void setGmtCreate(Date gmtCreate) { + this.gmtCreate = gmtCreate; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/DateTest_ISO8601_OneLetterISO8601TimeZone.java b/src/test/java/com/alibaba/json/bvt/serializer/DateTest_ISO8601_OneLetterISO8601TimeZone.java new file mode 100644 index 0000000000..84d036d318 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/DateTest_ISO8601_OneLetterISO8601TimeZone.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.Calendar; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class DateTest_ISO8601_OneLetterISO8601TimeZone extends TestCase { + + public void f_test_date() throws Exception { + String text = "{\"gmtCreate\":\"2014-08-21T09:51:36.2+08\"}"; + + Calendar date = JSON.parseObject(text, VO.class).getGmtCreate(); + Assert.assertNotNull(date); + + Assert.assertEquals(8, date.getTimeZone().getRawOffset()/(3600*1000)); + } + + public void test_date_9() throws Exception { + String text = "{\"gmtCreate\":\"2014-08-21T09:51:36.235+09\"}"; + + Calendar date = JSON.parseObject(text, VO.class).getGmtCreate(); + Assert.assertNotNull(date); + + Assert.assertEquals(9, date.getTimeZone().getRawOffset()/(3600*1000)); + } + + public static class VO { + + private Calendar gmtCreate; + + public Calendar getGmtCreate() { + return gmtCreate; + } + + public void setGmtCreate(Calendar gmtCreate) { + this.gmtCreate = gmtCreate; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/DateTest_ISO8601_ThreeLetterISO8601TimeZone.java b/src/test/java/com/alibaba/json/bvt/serializer/DateTest_ISO8601_ThreeLetterISO8601TimeZone.java new file mode 100644 index 0000000000..a3536c3700 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/DateTest_ISO8601_ThreeLetterISO8601TimeZone.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.Calendar; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class DateTest_ISO8601_ThreeLetterISO8601TimeZone extends TestCase { + + public void f_test_date() throws Exception { + String text = "{\"gmtCreate\":\"2014-08-21T09:51:36.2+08:00\"}"; + + Calendar date = JSON.parseObject(text, VO.class).getGmtCreate(); + Assert.assertNotNull(date); + + Assert.assertEquals(8, date.getTimeZone().getRawOffset()/(3600*1000)); + } + + public void test_date_9() throws Exception { + String text = "{\"gmtCreate\":\"2014-08-21T09:51:36.235+09:00\"}"; + + Calendar date = JSON.parseObject(text, VO.class).getGmtCreate(); + Assert.assertNotNull(date); + + Assert.assertEquals(9, date.getTimeZone().getRawOffset()/(3600*1000)); + } + + public static class VO { + + private Calendar gmtCreate; + + public Calendar getGmtCreate() { + return gmtCreate; + } + + public void setGmtCreate(Calendar gmtCreate) { + this.gmtCreate = gmtCreate; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/DateTest_ISO8601_TwoLetterISO8601TimeZone.java b/src/test/java/com/alibaba/json/bvt/serializer/DateTest_ISO8601_TwoLetterISO8601TimeZone.java new file mode 100644 index 0000000000..11c0e06c36 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/DateTest_ISO8601_TwoLetterISO8601TimeZone.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.Calendar; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class DateTest_ISO8601_TwoLetterISO8601TimeZone extends TestCase { + + public void f_test_date() throws Exception { + String text = "{\"gmtCreate\":\"2014-08-21T09:51:36.2+0800\"}"; + + Calendar date = JSON.parseObject(text, VO.class).getGmtCreate(); + Assert.assertNotNull(date); + + Assert.assertEquals(8, date.getTimeZone().getRawOffset()/(3600*1000)); + } + + public void test_date_9() throws Exception { + String text = "{\"gmtCreate\":\"2014-08-21T09:51:36.235+0900\"}"; + + Calendar date = JSON.parseObject(text, VO.class).getGmtCreate(); + Assert.assertNotNull(date); + + Assert.assertEquals(9, date.getTimeZone().getRawOffset()/(3600*1000)); + } + + public static class VO { + + private Calendar gmtCreate; + + public Calendar getGmtCreate() { + return gmtCreate; + } + + public void setGmtCreate(Calendar gmtCreate) { + this.gmtCreate = gmtCreate; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/DateTest_ISO8601_UTCTime.java b/src/test/java/com/alibaba/json/bvt/serializer/DateTest_ISO8601_UTCTime.java new file mode 100644 index 0000000000..c480e107ee --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/DateTest_ISO8601_UTCTime.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.Calendar; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class DateTest_ISO8601_UTCTime extends TestCase { + + public void test_date() throws Exception { + String text = "{\"gmtCreate\":\"2014-10-09T03:07:07.000Z\"}"; + + Calendar date = JSON.parseObject(text, VO.class).getGmtCreate(); + Assert.assertNotNull(date); + + Assert.assertEquals(0, date.getTimeZone().getRawOffset() / (3600 * 1000)); + } + + public static class VO { + + private Calendar gmtCreate; + + public Calendar getGmtCreate() { + return gmtCreate; + } + + public void setGmtCreate(Calendar gmtCreate) { + this.gmtCreate = gmtCreate; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/DoubleArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/DoubleArraySerializerTest.java old mode 100644 new mode 100755 similarity index 90% rename from src/test/java/com/alibaba/json/test/bvt/serializer/DoubleArraySerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/DoubleArraySerializerTest.java index 405aa2a687..c5133c86e5 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/DoubleArraySerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/DoubleArraySerializerTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/DoubleTest.java b/src/test/java/com/alibaba/json/bvt/serializer/DoubleTest.java new file mode 100755 index 0000000000..e859b3517a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/DoubleTest.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class DoubleTest extends TestCase { + + public void test_double() throws Exception { + VO vo = new VO(); + vo.setF1(Integer.MAX_VALUE); + vo.setF2(Double.MAX_VALUE); + vo.setF3(Integer.MAX_VALUE); + + String text = JSON.toJSONString(vo); + System.out.println(text); + + VO vo1 = JSON.parseObject(text, VO.class); + + Assert.assertEquals(vo.getF1(), vo1.getF1()); + Assert.assertTrue(vo.getF2() == vo1.getF2()); + Assert.assertEquals(vo.getF3(), vo1.getF3()); + } + + public static class VO { + + private int f1; + private double f2; + private int f3; + + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + + public double getF2() { + return f2; + } + + public void setF2(double f2) { + this.f2 = f2; + } + + public int getF3() { + return f3; + } + + public void setF3(int f3) { + this.f3 = f3; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/DoubleTest_custom.java b/src/test/java/com/alibaba/json/bvt/serializer/DoubleTest_custom.java new file mode 100644 index 0000000000..6927186a49 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/DoubleTest_custom.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.serializer; + +import java.text.DecimalFormat; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.DoubleSerializer; +import com.alibaba.fastjson.serializer.SerializeConfig; + +public class DoubleTest_custom extends TestCase { + + public void test_0() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.put(Double.class, new DoubleSerializer(new DecimalFormat("###.##"))); + Assert.assertEquals("1.12", JSON.toJSONString(1.123456789D, config)); + } + + public void test_1() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.put(Double.class, new DoubleSerializer("###.###")); + Assert.assertEquals("1.123", JSON.toJSONString(1.123456789D, config)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/DoubleTest_custom2.java b/src/test/java/com/alibaba/json/bvt/serializer/DoubleTest_custom2.java new file mode 100644 index 0000000000..41e5efcdd5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/DoubleTest_custom2.java @@ -0,0 +1,28 @@ +package com.alibaba.json.bvt.serializer; + +import java.text.DecimalFormat; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.DoubleSerializer; +import com.alibaba.fastjson.serializer.SerializeConfig; + +public class DoubleTest_custom2 extends TestCase { + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void test_0() throws Exception { + Map values = new HashMap(); + Double v = 9.00; + values.put("double", v); + + SerializeConfig config = new SerializeConfig(); + config.put(Double.class, new DoubleSerializer(new DecimalFormat("###.00"))); + Assert.assertEquals("{\"double\":9.00}", JSON.toJSONString(values, config)); + } + +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/EnumTest.java b/src/test/java/com/alibaba/json/bvt/serializer/EnumTest.java old mode 100644 new mode 100755 similarity index 59% rename from src/test/java/com/alibaba/json/test/bvt/serializer/EnumTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/EnumTest.java index 5e0d8b3533..087311d117 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/EnumTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/EnumTest.java @@ -1,9 +1,10 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializeConfig; import com.alibaba.fastjson.serializer.SerializerFeature; public class EnumTest extends TestCase { @@ -13,9 +14,9 @@ public static enum Type { } public void test_enum() throws Exception { - Assert.assertEquals("0", JSON.toJSONString(Type.Big)); // 0 - Assert.assertEquals("1", JSON.toJSONString(Type.Medium)); // 1 - Assert.assertEquals("2", JSON.toJSONString(Type.Small)); // 2 + Assert.assertEquals("0", JSON.toJSONStringZ(Type.Big, SerializeConfig.getGlobalInstance())); // 0 + Assert.assertEquals("1", JSON.toJSONStringZ(Type.Medium, SerializeConfig.getGlobalInstance())); // 1 + Assert.assertEquals("2", JSON.toJSONStringZ(Type.Small, SerializeConfig.getGlobalInstance())); // 2 Assert.assertEquals("\"Big\"", JSON.toJSONString(Type.Big, SerializerFeature.WriteEnumUsingToString)); // "Big" Assert.assertEquals("\"Medium\"", JSON.toJSONString(Type.Medium, SerializerFeature.WriteEnumUsingToString)); // "Medium" diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/EnumTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/EnumTest2.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/serializer/EnumTest2.java rename to src/test/java/com/alibaba/json/bvt/serializer/EnumTest2.java index bfadc2dd2f..5f2a813aca --- a/src/test/java/com/alibaba/json/test/bvt/serializer/EnumTest2.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/EnumTest2.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.Date; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/EnumerationSeriliazerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/EnumerationSeriliazerTest.java new file mode 100644 index 0000000000..4657964549 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/EnumerationSeriliazerTest.java @@ -0,0 +1,132 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.Enumeration; +import java.util.Vector; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class EnumerationSeriliazerTest extends TestCase { + + public void test_nullAsEmtpyList() throws Exception { + VO e = new VO(); + Assert.assertEquals("{\"elements\":[]}", JSON.toJSONString(e, SerializerFeature.WriteMapNullValue, + SerializerFeature.WriteNullListAsEmpty)); + } + + public void test_null() throws Exception { + VO e = new VO(); + Assert.assertEquals("{\"elements\":null}", JSON.toJSONString(e, SerializerFeature.WriteMapNullValue)); + } + + public void test_1() throws Exception { + VO e = new VO(new Entity(), new Entity()); + Assert.assertEquals("{\"elements\":[{},{}]}", JSON.toJSONString(e, SerializerFeature.WriteMapNullValue)); + } + + public void test_2() throws Exception { + VO e = new VO(new Entity(), new Entity2()); + Assert.assertEquals("{\"elements\":[{},{\"@type\":\"com.alibaba.json.bvt.serializer.EnumerationSeriliazerTest$Entity2\"}]}", + JSON.toJSONString(e, SerializerFeature.WriteClassName, + SerializerFeature.NotWriteRootClassName)); + } + + public void test_3() throws Exception { + VO2 e = new VO2(new Entity(), new Entity()); + Assert.assertEquals("{\"elements\":[{},{}]}", JSON.toJSONString(e, SerializerFeature.WriteClassName, + SerializerFeature.NotWriteRootClassName)); + } + + public void test_4() throws Exception { + VO3 e = new VO3(new Entity(), new Entity2()); + Assert.assertEquals("{\"elements\":[{\"@type\":\"com.alibaba.json.bvt.serializer.EnumerationSeriliazerTest$Entity\"},{\"@type\":\"com.alibaba.json.bvt.serializer.EnumerationSeriliazerTest$Entity2\"}]}", JSON.toJSONString(e, SerializerFeature.WriteClassName, + SerializerFeature.NotWriteRootClassName)); + } + + private static class VO { + + private Enumeration elements; + + public VO(Entity... array){ + if (array.length > 0) { + Vector vector = new Vector(); + for (Entity item : array) { + vector.add(item); + } + this.elements = vector.elements(); + } + } + + public Enumeration getElements() { + return elements; + } + + public void setElements(Enumeration elements) { + this.elements = elements; + } + + } + + private static class VO2 extends IVO2 { + + public VO2(Entity... array){ + if (array.length > 0) { + Vector vector = new Vector(); + for (Entity item : array) { + vector.add(item); + } + this.elements = vector.elements(); + } + } + + } + + private static class VO3 { + + private Enumeration elements; + + public VO3(Entity... array){ + if (array.length > 0) { + Vector vector = new Vector(); + for (Entity item : array) { + vector.add(item); + } + this.elements = vector.elements(); + } + } + + public Enumeration getElements() { + return elements; + } + + public void setElements(Enumeration elements) { + this.elements = elements; + } + + } + + private static abstract class IVO2 { + + protected Enumeration elements; + + public Enumeration getElements() { + return elements; + } + + public void setElements(Enumeration elements) { + this.elements = elements; + } + } + + public static class Entity { + + } + + public static class Entity2 extends Entity { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ErrorTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ErrorTest.java new file mode 100644 index 0000000000..989e55aef6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ErrorTest.java @@ -0,0 +1,78 @@ +package com.alibaba.json.bvt.serializer; + +import java.io.IOException; +import java.lang.reflect.Type; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.ObjectSerializer; +import com.alibaba.fastjson.serializer.SerializeConfig; + +public class ErrorTest extends TestCase { + + public void test_error() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.put(A.class, new ObjectSerializer() { + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) + throws IOException { + throw new IOException(); + } + }); + JSONSerializer ser = new JSONSerializer(config); + + { + Exception error = null; + try { + ser.write(new A()); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + { + Exception error = null; + try { + B b = new B(); + b.setId(new A()); + ser.write(b); + } catch (JSONException ex) { + error = ex; + } + Assert.assertNotNull(error); + } + } + + public class A { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } + + public class B { + + private A id; + + public A getId() { + return id; + } + + public void setId(A id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/ExtendsTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ExtendsTest.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/serializer/ExtendsTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/ExtendsTest.java index a9c58c78a7..a27018dce0 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/ExtendsTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/ExtendsTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/FileTest.java b/src/test/java/com/alibaba/json/bvt/serializer/FileTest.java old mode 100644 new mode 100755 similarity index 86% rename from src/test/java/com/alibaba/json/test/bvt/serializer/FileTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/FileTest.java index 944b9a5eb1..1a2e0efa04 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/FileTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/FileTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.io.File; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/FloatArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/FloatArraySerializerTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/serializer/FloatArraySerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/FloatArraySerializerTest.java index 67d99f6348..a1c192cf7c --- a/src/test/java/com/alibaba/json/test/bvt/serializer/FloatArraySerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/FloatArraySerializerTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/FloatTest.java b/src/test/java/com/alibaba/json/bvt/serializer/FloatTest.java old mode 100644 new mode 100755 similarity index 97% rename from src/test/java/com/alibaba/json/test/bvt/serializer/FloatTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/FloatTest.java index 57417464ee..c32ca31031 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/FloatTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/FloatTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/FontSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/FontSerializerTest.java new file mode 100755 index 0000000000..71dbce26dc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/FontSerializerTest.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.serializer; + +import java.awt.Font; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.FontCodec; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class FontSerializerTest extends TestCase { + + public void test_null() throws Exception { + JSONSerializer serializer = new JSONSerializer(); + Assert.assertEquals(FontCodec.class, serializer.getObjectWriter(Font.class).getClass()); + + VO vo = new VO(); + + Assert.assertEquals("{\"value\":null}", JSON.toJSONString(vo, SerializerFeature.WriteMapNullValue)); + } + + private static class VO { + + private Font value; + + public Font getValue() { + return value; + } + + public void setValue(Font value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/InetAddressTest.java b/src/test/java/com/alibaba/json/bvt/serializer/InetAddressTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/serializer/InetAddressTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/InetAddressTest.java index 7ab0aaab7a..c39f686745 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/InetAddressTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/InetAddressTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.net.InetAddress; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/InetSocketAddressTest.java b/src/test/java/com/alibaba/json/bvt/serializer/InetSocketAddressTest.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/serializer/InetSocketAddressTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/InetSocketAddressTest.java index 32eeb06062..d2b334dd73 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/InetSocketAddressTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/InetSocketAddressTest.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.net.InetAddress; import java.net.InetSocketAddress; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/IntArrayEncodeTest.java b/src/test/java/com/alibaba/json/bvt/serializer/IntArrayEncodeTest.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/serializer/IntArrayEncodeTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/IntArrayEncodeTest.java index 5a4747553e..c9d7866be4 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/IntArrayEncodeTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/IntArrayEncodeTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/IntegerArrayEncodeTest.java b/src/test/java/com/alibaba/json/bvt/serializer/IntegerArrayEncodeTest.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/serializer/IntegerArrayEncodeTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/IntegerArrayEncodeTest.java index ba68b1ff5c..a5fcba460f --- a/src/test/java/com/alibaba/json/test/bvt/serializer/IntegerArrayEncodeTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/IntegerArrayEncodeTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/IntegerArrayFieldSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/IntegerArrayFieldSerializerTest.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/serializer/IntegerArrayFieldSerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/IntegerArrayFieldSerializerTest.java index fa0fa3b07b..a97e1272cb --- a/src/test/java/com/alibaba/json/test/bvt/serializer/IntegerArrayFieldSerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/IntegerArrayFieldSerializerTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/IntegerSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/IntegerSerializerTest.java new file mode 100755 index 0000000000..c77f890e86 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/IntegerSerializerTest.java @@ -0,0 +1,31 @@ +package com.alibaba.json.bvt.serializer; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class IntegerSerializerTest extends TestCase { + + public void test_null() throws Exception { + VO vo = new VO(); + + Assert.assertEquals("{\"value\":null}", JSON.toJSONString(vo, SerializerFeature.WriteMapNullValue)); + } + + private static class VO { + + private Integer value; + + public Integer getValue() { + return value; + } + + public void setValue(Integer value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/InterfaceTest.java b/src/test/java/com/alibaba/json/bvt/serializer/InterfaceTest.java new file mode 100755 index 0000000000..62511d1b98 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/InterfaceTest.java @@ -0,0 +1,45 @@ +package com.alibaba.json.bvt.serializer; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; + +public class InterfaceTest extends TestCase { + public void test_interface() throws Exception { + A a = new A(); + a.setId(123); + a.setName("xasdf"); + + String text = JSON.toJSONString(a); + Assert.assertEquals("{\"ID\":123,\"Name\":\"xasdf\"}", text); + } + + public static class A implements IA, IB { + private int id; + private String name; + public int getId() { + return id; + } + public void setId(int id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + } + + public static interface IA { + @JSONField(name="ID") + int getId(); + } + + public static interface IB { + @JSONField(name="Name") + String getName(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest.java new file mode 100644 index 0000000000..3c52d28734 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest.java @@ -0,0 +1,43 @@ +package com.alibaba.json.bvt.serializer; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; + +public class JSONFieldTest extends TestCase { + public void test_jsonField() throws Exception { + VO vo = new VO(); + + vo.setId(123); + vo.setName("xx"); + + String text = JSON.toJSONString(vo); + Assert.assertEquals("{\"id\":123}", text); + } + + public static class VO { + private int id; + + @JSONField(serialize=false) + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest2.java new file mode 100644 index 0000000000..b9f0731c77 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest2.java @@ -0,0 +1,42 @@ +package com.alibaba.json.bvt.serializer; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; + +public class JSONFieldTest2 extends TestCase { + public void test_jsonField() throws Exception { + VO vo = new VO(); + + vo.setId(123); + vo.setFlag(true); + + String text = JSON.toJSONString(vo); + Assert.assertEquals("{\"id\":123}", text); + } + + public static class VO { + private int id; + + @JSONField(serialize = false) + private boolean flag; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public boolean isFlag() { + return flag; + } + + public void setFlag(boolean flag) { + this.flag = flag; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest3.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest3.java new file mode 100644 index 0000000000..0d427f2a3e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest3.java @@ -0,0 +1,57 @@ +package com.alibaba.json.bvt.serializer; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; + +public class JSONFieldTest3 extends TestCase { + public void test_jsonField() throws Exception { + VO vo = new VO(); + + vo.setId(123); + vo.setFlag(true); + + String text = JSON.toJSONString(vo); + Assert.assertEquals("{\"id\":123}", text); + } + + public static class VO { + private int id; + + @JSONField(serialize = false) + private boolean _flag; + + @JSONField(serialize = false) + private int _id2; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public boolean isFlag() { + return _flag; + } + + public void setFlag(boolean flag) { + this._flag = flag; + } + + + public int getId2() { + return _id2; + } + + + public void setId2(int id2) { + this._id2 = id2; + } + + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest4.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest4.java new file mode 100644 index 0000000000..896bcafa30 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest4.java @@ -0,0 +1,57 @@ +package com.alibaba.json.bvt.serializer; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; + +public class JSONFieldTest4 extends TestCase { + public void test_jsonField() throws Exception { + VO vo = new VO(); + + vo.setId(123); + vo.setFlag(true); + + String text = JSON.toJSONString(vo); + Assert.assertEquals("{\"id\":123}", text); + } + + public static class VO { + private int id; + + @JSONField(serialize = false) + private boolean m_flag; + + @JSONField(serialize = false) + private int m_id2; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public boolean isFlag() { + return m_flag; + } + + public void setFlag(boolean flag) { + this.m_flag = flag; + } + + + public int getId2() { + return m_id2; + } + + + public void setId2(int id2) { + this.m_id2 = id2; + } + + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest5.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest5.java new file mode 100644 index 0000000000..c04911b09d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONFieldTest5.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class JSONFieldTest5 extends TestCase { + + public void test_jsonField() throws Exception { + VO vo = new VO(); + + vo.setID(123); + + String text = JSON.toJSONString(vo); + Assert.assertEquals("{\"iD\":123}", text); + + Assert.assertEquals(123, JSON.parseObject(text, VO.class).getID()); + } + + public static class VO { + + private int id; + + public int getID() { + return id; + } + + public void setID(int id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerContextTest.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerContextTest.java old mode 100644 new mode 100755 similarity index 86% rename from src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerContextTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerContextTest.java index 291cb13ff0..e587406611 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerContextTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerContextTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializerContext; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerDeprecatedTest.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerDeprecatedTest.java new file mode 100644 index 0000000000..f7f7bba223 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerDeprecatedTest.java @@ -0,0 +1,22 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.JSONSerializerMap; +import com.fasterxml.jackson.databind.util.ISO8601DateFormat; + +@SuppressWarnings("deprecation") +public class JSONSerializerDeprecatedTest extends TestCase { + + public void test_() throws Exception { + JSONSerializer ser = new JSONSerializer(new JSONSerializerMap()); + + ser.setDateFormat(new ISO8601DateFormat()); + Assert.assertEquals(null, ser.getDateFormatPattern()); + + ser.close(); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerFeatureTest.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerFeatureTest.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerFeatureTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerFeatureTest.java index f9c12b3026..a6253882e5 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerFeatureTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerFeatureTest.java @@ -1,11 +1,11 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.io.StringWriter; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerMapTest.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerMapTest.java old mode 100644 new mode 100755 similarity index 71% rename from src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerMapTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerMapTest.java index f0dc329121..bf432e62e0 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerMapTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerMapTest.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; -import com.alibaba.fastjson.serializer.IntegerSerializer; +import com.alibaba.fastjson.serializer.IntegerCodec; import com.alibaba.fastjson.serializer.JSONSerializerMap; @SuppressWarnings("deprecation") @@ -13,13 +13,13 @@ public void test_0() throws Exception { JSONSerializerMap map = new JSONSerializerMap(); Assert.assertFalse(0 == map.size()); - Assert.assertEquals(true, map.get(Integer.class) == IntegerSerializer.instance); + Assert.assertEquals(true, map.get(Integer.class) == IntegerCodec.instance); - Assert.assertEquals(true, map.put(Integer.class, IntegerSerializer.instance)); - Assert.assertEquals(true, map.put(Integer.class, IntegerSerializer.instance)); - Assert.assertEquals(true, map.put(Integer.class, IntegerSerializer.instance)); + Assert.assertEquals(true, map.put(Integer.class, IntegerCodec.instance)); + Assert.assertEquals(true, map.put(Integer.class, IntegerCodec.instance)); + Assert.assertEquals(true, map.put(Integer.class, IntegerCodec.instance)); - Assert.assertEquals(true, map.get(Integer.class) == IntegerSerializer.instance); + Assert.assertEquals(true, map.get(Integer.class) == IntegerCodec.instance); Assert.assertFalse(0 == map.size()); } diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest.java index 0aa6bf44b3..8eee92f854 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.io.IOException; import java.io.StringWriter; @@ -7,7 +7,7 @@ import java.util.Date; import java.util.Iterator; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONAware; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerTest1.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest1.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerTest1.java rename to src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest1.java index c8a21b9314..9a8ecc38a6 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerTest1.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest1.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest2.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerTest2.java rename to src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest2.java index 0d1b823313..87151b5e78 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/JSONSerializerTest2.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest2.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.io.IOException; import java.io.Writer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -16,15 +16,17 @@ public void test_0() throws Exception { JSONSerializer serializer = new JSONSerializer(); int size = serializer.getMapping().size(); + serializer.config(SerializerFeature.WriteEnumUsingToString, false); serializer.write(Type.A); - Assert.assertEquals(size + 1, serializer.getMapping().size()); + Assert.assertTrue(size < serializer.getMapping().size()); Assert.assertEquals(Integer.toString(Type.A.ordinal()), serializer.getWriter().toString()); } public void test_1() throws Exception { JSONSerializer serializer = new JSONSerializer(); + serializer.config(SerializerFeature.WriteEnumUsingToString, false); serializer.write(new A(Type.B)); Assert.assertEquals("{\"type\":" + Integer.toString(Type.B.ordinal()) + "}", serializer.getWriter().toString()); diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest3.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest3.java new file mode 100644 index 0000000000..3472464362 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest3.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.serializer; + +import java.text.SimpleDateFormat; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.serializer.JSONSerializer; + +public class JSONSerializerTest3 extends TestCase { + + public void test_0() throws Exception { + JSONSerializer serializer = new JSONSerializer(); + + serializer.setDateFormat("yyyy"); + Assert.assertEquals("yyyy", ((SimpleDateFormat) serializer.getDateFormat()).toPattern()); + Assert.assertEquals("yyyy", serializer.getDateFormatPattern()); + + serializer.setDateFormat("yyyy-MM"); + Assert.assertEquals("yyyy-MM", ((SimpleDateFormat) serializer.getDateFormat()).toPattern()); + + serializer.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); + Assert.assertEquals("yyyy-MM-dd", serializer.getDateFormatPattern()); + } + +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/JavaBeanSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/JavaBeanSerializerTest.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/serializer/JavaBeanSerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/JavaBeanSerializerTest.java index dbc7ad6852..7caf62d821 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/JavaBeanSerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/JavaBeanSerializerTest.java @@ -1,10 +1,10 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSONException; @@ -23,7 +23,7 @@ public void test_0_s() throws Exception { a.getL0().add("B"); JavaBeanSerializer serializer = new JavaBeanSerializer(A.class); - serializer.write(new JSONSerializer(out), a); + serializer.write(new JSONSerializer(out), a, null, null, 0); Assert.assertEquals("{\"l0\":[\"A\",\"B\"]}", out.toString()); } @@ -36,7 +36,7 @@ public void test_1_s() throws Exception { a.getL0().add("B"); JavaBeanSerializer serializer = new JavaBeanSerializer(B.class); - serializer.write(new JSONSerializer(out), a); + serializer.write(new JSONSerializer(out), a, null, null, 0); Assert.assertEquals("{\"l0\":[\"A\",\"B\"],\"l1\":[]}", out.toString()); } @@ -45,7 +45,7 @@ public void test_2_s() throws Exception { SerializeWriter out = new SerializeWriter(); JavaBeanSerializer serializer = new JavaBeanSerializer(F.class); - serializer.write(new JSONSerializer(out), new F(new E(123))); + serializer.write(new JSONSerializer(out), new F(new E(123)), null, null, 0); Assert.assertEquals("{\"e\":{\"id\":123}}", out.toString()); } @@ -54,7 +54,7 @@ public void test_3_s() throws Exception { SerializeWriter out = new SerializeWriter(); JavaBeanSerializer serializer = new JavaBeanSerializer(F.class); - serializer.write(new JSONSerializer(out), new F(null)); + serializer.write(new JSONSerializer(out), new F(null), null, null, 0); for (FieldSerializer getter : serializer.getGetters()) { getter.getName(); @@ -69,7 +69,7 @@ public void test_error_s() throws Exception { try { SerializeWriter out = new SerializeWriter(); JavaBeanSerializer serializer = new JavaBeanSerializer(C.class); - serializer.write(new JSONSerializer(out), new C()); + serializer.write(new JSONSerializer(out), new C(), null, null, 0); } catch (JSONException e) { error = e; } @@ -81,7 +81,7 @@ public void test_error_1_s() throws Exception { try { SerializeWriter out = new SerializeWriter(); JavaBeanSerializer serializer = new JavaBeanSerializer(D.class); - serializer.write(new JSONSerializer(out), new D()); + serializer.write(new JSONSerializer(out), new D(), null, null, 0); } catch (JSONException e) { error = e; } diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/JavaBeanSerializerTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/JavaBeanSerializerTest2.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/serializer/JavaBeanSerializerTest2.java rename to src/test/java/com/alibaba/json/bvt/serializer/JavaBeanSerializerTest2.java index f1fcb8253f..754df55d2c --- a/src/test/java/com/alibaba/json/test/bvt/serializer/JavaBeanSerializerTest2.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/JavaBeanSerializerTest2.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.Collections; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/ListSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ListSerializerTest.java old mode 100644 new mode 100755 similarity index 81% rename from src/test/java/com/alibaba/json/test/bvt/serializer/ListSerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/ListSerializerTest.java index f3c86e00fd..2469b6e056 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/ListSerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/ListSerializerTest.java @@ -1,10 +1,10 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; @@ -17,7 +17,7 @@ public void test_0_s() throws Exception { SerializeWriter out = new SerializeWriter(); ListSerializer listSerializer = new ListSerializer(); - listSerializer.write(new JSONSerializer(out), Collections.EMPTY_LIST); + listSerializer.write(new JSONSerializer(out), Collections.EMPTY_LIST, null, null, 0); Assert.assertEquals("[]", out.toString()); } @@ -29,7 +29,7 @@ public void test_2_s() throws Exception { List list = new ArrayList(); list.add(1); list.add(2); - listSerializer.write(new JSONSerializer(out), list); + listSerializer.write(new JSONSerializer(out), list, null, null, 0); Assert.assertEquals("[1,2]", out.toString()); } @@ -42,7 +42,7 @@ public void test_3_s() throws Exception { list.add(1); list.add(2); list.add(3); - listSerializer.write(new JSONSerializer(out), list); + listSerializer.write(new JSONSerializer(out), list, null, null, 0); Assert.assertEquals("[1,2,3]", out.toString()); } @@ -56,7 +56,7 @@ public void test_4_s() throws Exception { list.add(2L); list.add(3L); list.add(Collections.emptyMap()); - listSerializer.write(new JSONSerializer(out), list); + listSerializer.write(new JSONSerializer(out), list, null, null, 0); Assert.assertEquals("[1,2,3,{}]", out.toString()); } @@ -71,7 +71,7 @@ public void test_5_s() throws Exception { list.add(null); list.add(Collections.emptyMap()); list.add(21474836480L); - listSerializer.write(new JSONSerializer(out), list); + listSerializer.write(new JSONSerializer(out), list, null, null, 0); Assert.assertEquals("[1,21474836480,null,{},21474836480]", out.toString()); } diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/ListSerializerTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/ListSerializerTest2.java old mode 100644 new mode 100755 similarity index 80% rename from src/test/java/com/alibaba/json/test/bvt/serializer/ListSerializerTest2.java rename to src/test/java/com/alibaba/json/bvt/serializer/ListSerializerTest2.java index 74dd9606fa..67914bbc8c --- a/src/test/java/com/alibaba/json/test/bvt/serializer/ListSerializerTest2.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/ListSerializerTest2.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.Arrays; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; @@ -21,7 +21,7 @@ public void test_0() throws Exception { List list = Arrays.asList(array); - listSerializer.write(new JSONSerializer(out), list); + listSerializer.write(new JSONSerializer(out), list, null, null, 0); // System.out.println(out.toString()); Assert.assertEquals("[1,2,3,4,5,6,\"a\"]", out.toString()); diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ListSerializerTest3.java b/src/test/java/com/alibaba/json/bvt/serializer/ListSerializerTest3.java new file mode 100644 index 0000000000..1fb11fec1f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ListSerializerTest3.java @@ -0,0 +1,47 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.ArrayList; +import java.util.LinkedList; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.ListSerializer; +import com.alibaba.fastjson.serializer.SerializeWriter; + +public class ListSerializerTest3 extends TestCase { + + public void test_1() throws Exception { + SerializeWriter out = new SerializeWriter(); + ListSerializer listSerializer = new ListSerializer(); + + ArrayList list = new ArrayList(); + for (int i = 0; i < 100000; i++) { + list.add(i); + } + + long start = System.currentTimeMillis(); + listSerializer.write(new JSONSerializer(out), list, null, null, 0); + long end = System.currentTimeMillis(); + + System.out.println("arrayList time: " + (end - start)); + } + + public void test_2() throws Exception { + SerializeWriter out = new SerializeWriter(); + + ListSerializer listSerializer = new ListSerializer(); + + LinkedList list = new LinkedList(); + for (int i = 0; i < 100000; i++) { + list.add(i); + } + + long start = System.currentTimeMillis(); + listSerializer.write(new JSONSerializer(out), list, null, null, 0); + long end = System.currentTimeMillis(); + + System.out.println("linkedList time: " + (end - start)); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ListTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ListTest.java new file mode 100755 index 0000000000..94f1c128ca --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ListTest.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.LinkedList; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class ListTest extends TestCase { + + public void test_null() throws Exception { + List list = new LinkedList(); + list.add(23L); + list.add(45L); + + Assert.assertEquals("[23L,45L]", JSON.toJSONString(list, SerializerFeature.WriteClassName)); + } + + public static class VO { + + private Object value; + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/LocalTest.java b/src/test/java/com/alibaba/json/bvt/serializer/LocalTest.java old mode 100644 new mode 100755 similarity index 85% rename from src/test/java/com/alibaba/json/test/bvt/serializer/LocalTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/LocalTest.java index a8c492a314..eb234ce0c1 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/LocalTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/LocalTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.Locale; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/LongArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/LongArraySerializerTest.java old mode 100644 new mode 100755 similarity index 57% rename from src/test/java/com/alibaba/json/test/bvt/serializer/LongArraySerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/LongArraySerializerTest.java index 6e8ede3cf4..393b1087a9 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/LongArraySerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/LongArraySerializerTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import junit.framework.TestCase; @@ -18,24 +18,6 @@ public void test_0() { Assert.assertEquals("{\"value\":[]}", JSON.toJSONString(new Entity(), SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty)); } - public void test_1() throws Exception { - SerializeWriter out = new SerializeWriter(1); - out.writeLongArray(new long[] { 1, 2, 3 }); - Assert.assertEquals("[1,2,3]", out.toString()); - } - - public void test_2() throws Exception { - SerializeWriter out = new SerializeWriter(100); - out.writeLongArray(new long[] { 1, 2, 3 }); - Assert.assertEquals("[1,2,3]", out.toString()); - } - - public void test_3() throws Exception { - SerializeWriter out = new SerializeWriter(100); - out.writeLongArray(new long[] { 1, 2, Long.MIN_VALUE }); - Assert.assertEquals("[1,2,-9223372036854775808]", out.toString()); - } - public static class Entity { private long[] value; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/MapSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/MapSerializerTest.java old mode 100644 new mode 100755 similarity index 75% rename from src/test/java/com/alibaba/json/test/bvt/serializer/MapSerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/MapSerializerTest.java index 4ec73e0ff0..02b3f837c4 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/MapSerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/MapSerializerTest.java @@ -1,12 +1,14 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.JSONSerializer; import com.alibaba.fastjson.serializer.MapSerializer; import com.alibaba.fastjson.serializer.SerializeWriter; @@ -18,7 +20,7 @@ public void test_empty_1() throws Exception { SerializeWriter out = new SerializeWriter(); MapSerializer mapSerializer = new MapSerializer(); - mapSerializer.write(new JSONSerializer(out), Collections.EMPTY_MAP); + mapSerializer.write(new JSONSerializer(out), Collections.EMPTY_MAP, null, null, 0); Assert.assertEquals("{}", out.toString()); } @@ -27,7 +29,7 @@ public void test_singleton_1() throws Exception { SerializeWriter out = new SerializeWriter(); MapSerializer mapSerializer = new MapSerializer(); - mapSerializer.write(new JSONSerializer(out), Collections.singletonMap("A", 1)); + mapSerializer.write(new JSONSerializer(out), Collections.singletonMap("A", 1), null, null, 0); Assert.assertEquals("{\"A\":1}", out.toString()); } @@ -39,7 +41,7 @@ public void test_int2_s() throws Exception { Map map = new LinkedHashMap(); map.put("A", 1); map.put("B", 2); - mapSerializer.write(new JSONSerializer(out), map); + mapSerializer.write(new JSONSerializer(out), map, null, null, 0); Assert.assertEquals("{\"A\":1,\"B\":2}", out.toString()); } @@ -51,7 +53,7 @@ public void test_long2_s() throws Exception { Map map = new LinkedHashMap(); map.put("A", 1L); map.put("B", 2L); - mapSerializer.write(new JSONSerializer(out), map); + mapSerializer.write(new JSONSerializer(out), map, null, null, 0); Assert.assertEquals("{\"A\":1,\"B\":2}", out.toString()); } @@ -63,7 +65,7 @@ public void test_string2_s() throws Exception { Map map = new LinkedHashMap(); map.put("A", "1"); map.put("B", "2"); - mapSerializer.write(new JSONSerializer(out), map); + mapSerializer.write(new JSONSerializer(out), map, null, null, 0); Assert.assertEquals("{\"A\":\"1\",\"B\":\"2\"}", out.toString()); } @@ -78,7 +80,7 @@ public void test_string3_s() throws Exception { Map map = new LinkedHashMap(); map.put("A", "1"); map.put("B", "2"); - mapSerializer.write(serializer, map); + mapSerializer.write(serializer, map, null, null, 0); Assert.assertEquals("{'A':'1','B':'2'}", out.toString()); } @@ -87,7 +89,7 @@ public void test_special_s() throws Exception { SerializeWriter out = new SerializeWriter(); MapSerializer mapSerializer = new MapSerializer(); - mapSerializer.write(new JSONSerializer(out), Collections.singletonMap("A\nB", 1)); + mapSerializer.write(new JSONSerializer(out), Collections.singletonMap("A\nB", 1), null, null, 0); Assert.assertEquals("{\"A\\nB\":1}", out.toString()); } @@ -96,7 +98,7 @@ public void test_special2_s() throws Exception { SerializeWriter out = new SerializeWriter(); MapSerializer mapSerializer = new MapSerializer(); - mapSerializer.write(new JSONSerializer(out), Collections.singletonMap("A\nB", 1)); + mapSerializer.write(new JSONSerializer(out), Collections.singletonMap("A\nB", 1), null, null, 0); Assert.assertEquals("{\"A\\nB\":1}", out.toString()); } @@ -105,7 +107,7 @@ public void test_special3_s() throws Exception { SerializeWriter out = new SerializeWriter(); MapSerializer mapSerializer = new MapSerializer(); - mapSerializer.write(new JSONSerializer(out), Collections.singletonMap("A\nB", Collections.EMPTY_MAP)); + mapSerializer.write(new JSONSerializer(out), Collections.singletonMap("A\nB", Collections.EMPTY_MAP), null, null, 0); Assert.assertEquals("{\"A\\nB\":{}}", out.toString()); } @@ -117,8 +119,15 @@ public void test_4() throws Exception { map.put("bytes", new byte[] { 1, 2 }); MapSerializer mapSerializer = new MapSerializer(); - mapSerializer.write(new JSONSerializer(out), map); - - Assert.assertEquals("{\"TOP\":\"value\",\"bytes\":[1,2]}", out.toString()); + mapSerializer.write(new JSONSerializer(out), map, null, null, 0); + + String text = out.toString(); + Assert.assertEquals("{\"TOP\":\"value\",\"bytes\":\"AQI=\"}", text); + + JSONObject json = JSON.parseObject(text); + byte[] bytes = json.getBytes("bytes"); + Assert.assertEquals(1, bytes[0]); + Assert.assertEquals(2, bytes[1]); + Assert.assertEquals(2, bytes.length); } } diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/MapTest.java b/src/test/java/com/alibaba/json/bvt/serializer/MapTest.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/serializer/MapTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/MapTest.java index 6f795e38ba..37a070ff6b --- a/src/test/java/com/alibaba/json/test/bvt/serializer/MapTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/MapTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest.java old mode 100644 new mode 100755 similarity index 77% rename from src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest.java index 948f35a43f..45ed71b2ce --- a/src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest.java @@ -1,11 +1,14 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; +import java.util.Collections; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.JSONSerializer; import com.alibaba.fastjson.serializer.NameFilter; import com.alibaba.fastjson.serializer.SerializeWriter; @@ -60,6 +63,22 @@ public String process(Object source, String name, Object value) { String text = out.toString(); Assert.assertEquals("{\"ID\":0}", text); } + + public static void test_toJSONString() throws Exception { + NameFilter filter = new NameFilter() { + + public String process(Object source, String name, Object value) { + if (name.equals("id")) { + return "ID"; + } + + return name; + } + + }; + + Assert.assertEquals("{\"ID\":0}", JSON.toJSONString(Collections.singletonMap("id", 0), filter)); + } public static class Bean { diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_boolean.java b/src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_boolean.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_boolean.java rename to src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_boolean.java index 6fb139a5df..d9e5cdb399 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_boolean.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_boolean.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_byte.java b/src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_byte.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_byte.java rename to src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_byte.java index 3e3c2a8896..132e54f952 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_byte.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_byte.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_char.java b/src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_char.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_char.java rename to src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_char.java index 4c6116e05d..7f2a7f1e07 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_char.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_char.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_double.java b/src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_double.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_double.java rename to src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_double.java index 3dc87bc9f8..7bbf8228a7 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_double.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_double.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_float.java b/src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_float.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_float.java rename to src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_float.java index 13b7145f7d..c8742c9b9d --- a/src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_float.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_float.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_long.java b/src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_long.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_long.java rename to src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_long.java index 39663e3492..f49e7a557e --- a/src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_long.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_long.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_short.java b/src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_short.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_short.java rename to src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_short.java index 848cc16b84..2633ada384 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/NameFilterTest_short.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/NameFilterTest_short.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.FilterUtils; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/NoneStringKeyTest.java b/src/test/java/com/alibaba/json/bvt/serializer/NoneStringKeyTest.java new file mode 100644 index 0000000000..2f12959bb2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/NoneStringKeyTest.java @@ -0,0 +1,50 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +@SuppressWarnings({ "rawtypes", "unchecked" }) +public class NoneStringKeyTest extends TestCase { + + public void test_0() throws Exception { + Map map = new HashMap(); + map.put(1, 101); + + Assert.assertEquals("{1:101}", JSON.toJSONString(map)); + } + + public void test_1() throws Exception { + Map map = new HashMap(); + map.put(1, 101); + + Assert.assertEquals("{\"1\":101}", JSON.toJSONString(map, SerializerFeature.BrowserCompatible)); + } + + public void test_2() throws Exception { + Map map = new HashMap(); + map.put(1, 101); + + Assert.assertEquals("{\"1\":101}", JSON.toJSONString(map, SerializerFeature.WriteNonStringKeyAsString)); + } + + public void test_null_0() throws Exception { + Map map = new HashMap(); + map.put(null, 101); + + Assert.assertEquals("{null:101}", JSON.toJSONString(map)); + } + + public void test_3() throws Exception { + Map map = new HashMap(); + map.put(null, 101); + + Assert.assertEquals("{\"null\":101}", JSON.toJSONString(map, SerializerFeature.WriteNonStringKeyAsString)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/NotWriteDefaultValueTest.java b/src/test/java/com/alibaba/json/bvt/serializer/NotWriteDefaultValueTest.java new file mode 100644 index 0000000000..293df7e5a3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/NotWriteDefaultValueTest.java @@ -0,0 +1,214 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class NotWriteDefaultValueTest extends TestCase { + + public void test_for_byte() throws Exception { + VO_Byte vo = new VO_Byte(); + String text = JSON.toJSONString(vo, SerializerFeature.NotWriteDefaultValue); + Assert.assertEquals("{}", text); + } + + public void test_for_short() throws Exception { + VO_Short vo = new VO_Short(); + String text = JSON.toJSONString(vo, SerializerFeature.NotWriteDefaultValue); + Assert.assertEquals("{}", text); + } + + public void test_for_int() throws Exception { + VO_Int vo = new VO_Int(); + String text = JSON.toJSONString(vo, SerializerFeature.NotWriteDefaultValue); + Assert.assertEquals("{}", text); + } + + public void test_for_long() throws Exception { + VO_Long vo = new VO_Long(); + String text = JSON.toJSONString(vo, SerializerFeature.NotWriteDefaultValue); + Assert.assertEquals("{}", text); + } + + public void test_for_float() throws Exception { + VO_Float vo = new VO_Float(); + String text = JSON.toJSONString(vo, SerializerFeature.NotWriteDefaultValue); + Assert.assertEquals("{}", text); + } + + public void test_for_double() throws Exception { + VO_Double vo = new VO_Double(); + String text = JSON.toJSONString(vo, SerializerFeature.NotWriteDefaultValue); + Assert.assertEquals("{}", text); + } + + public void test_for_boolean() throws Exception { + VO_Boolean vo = new VO_Boolean(); + vo.f1 = true; + String text = JSON.toJSONString(vo, SerializerFeature.NotWriteDefaultValue); + Assert.assertEquals("{\"f1\":true}", text); + } + + public static class VO_Byte { + + private byte f0; + private byte f1; + + public byte getF0() { + return f0; + } + + public void setF0(byte f0) { + this.f0 = f0; + } + + public byte getF1() { + return f1; + } + + public void setF1(byte f1) { + this.f1 = f1; + } + + } + + public static class VO_Short { + + private short f0; + private short f1; + + public short getF0() { + return f0; + } + + public void setF0(short f0) { + this.f0 = f0; + } + + public short getF1() { + return f1; + } + + public void setF1(short f1) { + this.f1 = f1; + } + + } + + public static class VO_Int { + + private int f0; + private int f1; + + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + } + + public static class VO_Long { + + private long f0; + private long f1; + + public long getF0() { + return f0; + } + + public void setF0(long f0) { + this.f0 = f0; + } + + public long getF1() { + return f1; + } + + public void setF1(long f1) { + this.f1 = f1; + } + + } + + public static class VO_Float { + + private float f0; + private float f1; + + public float getF0() { + return f0; + } + + public void setF0(float f0) { + this.f0 = f0; + } + + public float getF1() { + return f1; + } + + public void setF1(float f1) { + this.f1 = f1; + } + + } + + public static class VO_Double { + + private double f0; + private double f1; + + public double getF0() { + return f0; + } + + public void setF0(double f0) { + this.f0 = f0; + } + + public double getF1() { + return f1; + } + + public void setF1(double f1) { + this.f1 = f1; + } + + } + + public static class VO_Boolean { + + private boolean f0; + private boolean f1; + + public boolean isF0() { + return f0; + } + + public void setF0(boolean f0) { + this.f0 = f0; + } + + public boolean isF1() { + return f1; + } + + public void setF1(boolean f1) { + this.f1 = f1; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/NotWriteDefaultValueTest_NoneASM.java b/src/test/java/com/alibaba/json/bvt/serializer/NotWriteDefaultValueTest_NoneASM.java new file mode 100644 index 0000000000..0a01028595 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/NotWriteDefaultValueTest_NoneASM.java @@ -0,0 +1,214 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class NotWriteDefaultValueTest_NoneASM extends TestCase { + + public void test_for_byte() throws Exception { + VO_Byte vo = new VO_Byte(); + String text = JSON.toJSONString(vo, SerializerFeature.NotWriteDefaultValue); + Assert.assertEquals("{}", text); + } + + public void test_for_short() throws Exception { + VO_Short vo = new VO_Short(); + String text = JSON.toJSONString(vo, SerializerFeature.NotWriteDefaultValue); + Assert.assertEquals("{}", text); + } + + public void test_for_int() throws Exception { + VO_Int vo = new VO_Int(); + String text = JSON.toJSONString(vo, SerializerFeature.NotWriteDefaultValue); + Assert.assertEquals("{}", text); + } + + public void test_for_long() throws Exception { + VO_Long vo = new VO_Long(); + String text = JSON.toJSONString(vo, SerializerFeature.NotWriteDefaultValue); + Assert.assertEquals("{}", text); + } + + public void test_for_float() throws Exception { + VO_Float vo = new VO_Float(); + String text = JSON.toJSONString(vo, SerializerFeature.NotWriteDefaultValue); + Assert.assertEquals("{}", text); + } + + public void test_for_double() throws Exception { + VO_Double vo = new VO_Double(); + String text = JSON.toJSONString(vo, SerializerFeature.NotWriteDefaultValue); + Assert.assertEquals("{}", text); + } + + public void test_for_boolean() throws Exception { + VO_Boolean vo = new VO_Boolean(); + vo.f1 = true; + String text = JSON.toJSONString(vo, SerializerFeature.NotWriteDefaultValue); + Assert.assertEquals("{\"f1\":true}", text); + } + + private static class VO_Byte { + + private byte f0; + private byte f1; + + public byte getF0() { + return f0; + } + + public void setF0(byte f0) { + this.f0 = f0; + } + + public byte getF1() { + return f1; + } + + public void setF1(byte f1) { + this.f1 = f1; + } + + } + + private static class VO_Short { + + private short f0; + private short f1; + + public short getF0() { + return f0; + } + + public void setF0(short f0) { + this.f0 = f0; + } + + public short getF1() { + return f1; + } + + public void setF1(short f1) { + this.f1 = f1; + } + + } + + private static class VO_Int { + + private int f0; + private int f1; + + public int getF0() { + return f0; + } + + public void setF0(int f0) { + this.f0 = f0; + } + + public int getF1() { + return f1; + } + + public void setF1(int f1) { + this.f1 = f1; + } + } + + private static class VO_Long { + + private long f0; + private long f1; + + public long getF0() { + return f0; + } + + public void setF0(long f0) { + this.f0 = f0; + } + + public long getF1() { + return f1; + } + + public void setF1(long f1) { + this.f1 = f1; + } + + } + + private static class VO_Float { + + private float f0; + private float f1; + + public float getF0() { + return f0; + } + + public void setF0(float f0) { + this.f0 = f0; + } + + public float getF1() { + return f1; + } + + public void setF1(float f1) { + this.f1 = f1; + } + + } + + private static class VO_Double { + + private double f0; + private double f1; + + public double getF0() { + return f0; + } + + public void setF0(double f0) { + this.f0 = f0; + } + + public double getF1() { + return f1; + } + + public void setF1(double f1) { + this.f1 = f1; + } + + } + + private static class VO_Boolean { + + private boolean f0; + private boolean f1; + + public boolean isF0() { + return f0; + } + + public void setF0(boolean f0) { + this.f0 = f0; + } + + public boolean isF1() { + return f1; + } + + public void setF1(boolean f1) { + this.f1 = f1; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/ObjectArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ObjectArraySerializerTest.java old mode 100644 new mode 100755 similarity index 92% rename from src/test/java/com/alibaba/json/test/bvt/serializer/ObjectArraySerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/ObjectArraySerializerTest.java index 7c20dea52f..deb87c541c --- a/src/test/java/com/alibaba/json/test/bvt/serializer/ObjectArraySerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/ObjectArraySerializerTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ParserConfigTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ParserConfigTest.java new file mode 100755 index 0000000000..663f527c70 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ParserConfigTest.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.parser.ParserConfig; + +public class ParserConfigTest extends TestCase { + + public void test_0() throws Exception { + ParserConfig config = new ParserConfig(); + config.getDerializers(); + } + +// public void test_error_0() throws Exception { +// ParserConfig config = new ParserConfig(); +// +// Exception error = null; +// try { +// config.createJavaBeanDeserializer(int.class, int.class); +// } catch (JSONException ex) { +// error = ex; +// } +// Assert.assertNotNull(error); +// } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/PascalNameFilterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/PascalNameFilterTest.java new file mode 100755 index 0000000000..187a4b9df0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/PascalNameFilterTest.java @@ -0,0 +1,48 @@ +package com.alibaba.json.bvt.serializer; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.PascalNameFilter; + +public class PascalNameFilterTest extends TestCase { + + public void test_0() throws Exception { + JSONSerializer serializer = new JSONSerializer(); + serializer.getNameFilters().add(new PascalNameFilter()); + + VO vo = new VO(); + vo.setId(123); + vo.setName("wenshao"); + + serializer.write(vo); + + Assert.assertEquals("{\"Id\":123,\"Name\":\"wenshao\"}", serializer.toString()); + + serializer.close(); + } + + public static class VO { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/PascalNameFilterTest_1.java b/src/test/java/com/alibaba/json/bvt/serializer/PascalNameFilterTest_1.java new file mode 100644 index 0000000000..1d442ae057 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/PascalNameFilterTest_1.java @@ -0,0 +1,30 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.LinkedHashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.PascalNameFilter; + +public class PascalNameFilterTest_1 extends TestCase { + + public void test_0() throws Exception { + JSONSerializer serializer = new JSONSerializer(); + serializer.getNameFilters().add(new PascalNameFilter()); + + Map vo = new LinkedHashMap(); + vo.put("", 123); + vo.put(null, "wenshao"); + + serializer.write(vo); + + Assert.assertEquals("{\"\":123,null:\"wenshao\"}", serializer.toString()); + + serializer.close(); + } + +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/PatternTest.java b/src/test/java/com/alibaba/json/bvt/serializer/PatternTest.java old mode 100644 new mode 100755 similarity index 86% rename from src/test/java/com/alibaba/json/test/bvt/serializer/PatternTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/PatternTest.java index 1aa6ce872e..bde1f14f38 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/PatternTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/PatternTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.regex.Pattern; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/PointSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/PointSerializerTest.java new file mode 100755 index 0000000000..f600c7598e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/PointSerializerTest.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.serializer; + +import java.awt.Point; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class PointSerializerTest extends TestCase { + + public void test_null() throws Exception { + VO vo = new VO(); + + Assert.assertEquals("{\"value\":null}", JSON.toJSONString(vo, SerializerFeature.WriteMapNullValue)); + } + + private static class VO { + + private Point value; + + public Point getValue() { + return value; + } + + public void setValue(Point value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/PrePropertyFilterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/PrePropertyFilterTest.java new file mode 100644 index 0000000000..0e919414c9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/PrePropertyFilterTest.java @@ -0,0 +1,30 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.PropertyPreFilter; + +public class PrePropertyFilterTest extends TestCase { + + public void test_0() throws Exception { + class VO { + public int getId() { throw new RuntimeException(); } + } + + PropertyPreFilter filter = new PropertyPreFilter () { + public boolean apply(JSONSerializer serializer, Object source, String name) { + return false; + } + }; + + VO vo = new VO(); + + String text = JSON.toJSONString(vo, filter); + Assert.assertEquals("{}", text); + } + +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/indent/PrettyFormatTest.java b/src/test/java/com/alibaba/json/bvt/serializer/PrettyFormatTest.java old mode 100644 new mode 100755 similarity index 85% rename from src/test/java/com/alibaba/json/test/bvt/serializer/indent/PrettyFormatTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/PrettyFormatTest.java index 2f5a66bcc9..11efc72692 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/indent/PrettyFormatTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/PrettyFormatTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer.indent; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/PrimitiveTest.java b/src/test/java/com/alibaba/json/bvt/serializer/PrimitiveTest.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/serializer/PrimitiveTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/PrimitiveTest.java index 67aeb1e902..e44d1e5fed --- a/src/test/java/com/alibaba/json/test/bvt/serializer/PrimitiveTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/PrimitiveTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.io.StringWriter; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/PropertyFilterTest.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilterTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/PropertyFilterTest.java index fb89703f84..cd27c0d20f --- a/src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilterTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/PropertyFilterTest.java @@ -1,11 +1,13 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.JSONSerializer; import com.alibaba.fastjson.serializer.PropertyFilter; import com.alibaba.fastjson.serializer.SerializeWriter; @@ -30,6 +32,17 @@ public boolean apply(Object source, String name, Object value) { String text = out.toString(); Assert.assertEquals("{}", text); } + + public void test_toJSONString() throws Exception { + PropertyFilter filter = new PropertyFilter() { + + public boolean apply(Object source, String name, Object value) { + return false; + } + }; + + Assert.assertEquals("{}", JSON.toJSONString(new A(), filter)); + } public void test_1() throws Exception { PropertyFilter filter = new PropertyFilter() { diff --git a/src/test/java/com/alibaba/json/bvt/serializer/PropertyFilterTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/PropertyFilterTest2.java new file mode 100644 index 0000000000..651f3c214e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/PropertyFilterTest2.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.PropertyFilter; + +public class PropertyFilterTest2 extends TestCase { + + public void test_0() throws Exception { + class VO { + public int id; + public String name; + } + + PropertyFilter filter = new PropertyFilter() { + + public boolean apply(Object source, String name, Object value) { + return "id".equals(name); + } + }; + + VO vo = new VO(); + vo.id = 123; + vo.name = "gaotie"; + + String text = JSON.toJSONString(vo, filter); + Assert.assertEquals("{\"id\":123}", text); + } + +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_byte.java b/src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_byte.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_byte.java rename to src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_byte.java index 079800fc29..8911251340 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_byte.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_byte.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_char.java b/src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_char.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_char.java rename to src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_char.java index 5000d07c3f..4843be6a56 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_char.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_char.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_double.java b/src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_double.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_double.java rename to src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_double.java index fb34cfe1ac..72af57853d --- a/src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_double.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_double.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_float.java b/src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_float.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_float.java rename to src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_float.java index e2866d4c9a..0adc015920 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_float.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_float.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_long.java b/src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_long.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_long.java rename to src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_long.java index b41f407a07..2b397d3332 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_long.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_long.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_short.java b/src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_short.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_short.java rename to src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_short.java index f9258420a9..4351ccd0ff --- a/src/test/java/com/alibaba/json/test/bvt/serializer/PropertyFilter_short.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/PropertyFilter_short.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.JSONSerializer; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/PropertyPathTest.java b/src/test/java/com/alibaba/json/bvt/serializer/PropertyPathTest.java new file mode 100755 index 0000000000..34d7c795e7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/PropertyPathTest.java @@ -0,0 +1,147 @@ +package com.alibaba.json.bvt.serializer; + +import org.junit.Assert; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.PropertyPreFilter; +import com.alibaba.fastjson.serializer.SerializerFeature; + +/** + * @author wenshao + */ +public class PropertyPathTest extends TestCase { + + public void test_path() throws Exception { + A a = new A(); + a.setId(123); + + B b = new B(); + b.setId(234); + + C c = new C(); + c.setId(345); + + D d = new D(); + d.setId(456); + + a.setB(b); + b.setC(c); + b.setD(d); + + Assert.assertEquals("{\"b\":{\"c\":{\"id\":345},\"d\":{\"id\":456},\"id\":234},\"id\":123}", + JSON.toJSONString(a)); + Assert.assertEquals("{\"b\":{\"c\":{\"id\":345},\"id\":234},\"id\":123}", + JSON.toJSONString(a, new MyPropertyPreFilter())); + Assert.assertEquals("{'b':{'c':{'id':345},'id':234},'id':123}", + JSON.toJSONString(a, new MyPropertyPreFilter(), SerializerFeature.UseSingleQuotes)); + } + + public static class MyPropertyPreFilter implements PropertyPreFilter { + + public boolean apply(JSONSerializer serializer, Object source, String name) { + String path = serializer.getContext().getPath() + "." + name; + + if (path.startsWith("$.b.d")) { + return false; + } + + return true; + } + + } + + public static class A { + + private int id; + private B b; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public B getB() { + return b; + } + + public void setB(B b) { + this.b = b; + } + + } + + public static class B { + + private int id; + private C c; + private D d; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public C getC() { + return c; + } + + public void setC(C c) { + this.c = c; + } + + public D getD() { + return d; + } + + public void setD(D d) { + this.d = d; + } + + } + + public static class C { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + + public static class D { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/PropertyPathTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/PropertyPathTest2.java new file mode 100755 index 0000000000..a3c604b3d1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/PropertyPathTest2.java @@ -0,0 +1,68 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.PropertyPreFilter; + +public class PropertyPathTest2 extends TestCase { + + public void test_path() throws Exception { + Person p1 = new Person(); + p1.setId(100); + + Person c1 = new Person(); + c1.setId(1000); + + Person c2 = new Person(); + c2.setId(2000); + + p1.getChildren().add(c1); + p1.getChildren().add(c2); + + Assert.assertEquals("{\"children\":[{\"id\":1000},{\"id\":2000}],\"id\":100}", JSON.toJSONString(p1, new MyPropertyPreFilter())); + } + + public static class MyPropertyPreFilter implements PropertyPreFilter { + + public boolean apply(JSONSerializer serializer, Object source, String name) { + String path = serializer.getContext().getPath() + "." + name; + + if (path.endsWith("].children")) { + return false; + } + + return true; + } + + } + + public static class Person { + + private int id; + + private List children = new ArrayList(); + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/PropertyPathTest3.java b/src/test/java/com/alibaba/json/bvt/serializer/PropertyPathTest3.java new file mode 100755 index 0000000000..f36a7be28b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/PropertyPathTest3.java @@ -0,0 +1,143 @@ +package com.alibaba.json.bvt.serializer; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.PropertyPreFilter; +import com.alibaba.fastjson.serializer.SerialContext; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class PropertyPathTest3 extends TestCase { + + /** 测试只输出子集合中的特定属性 */ + public void test_path() throws Exception { + Person p1 = new Person(); + p1.setId(100); + + Person c1 = new Person(); + c1.setId(1000); + + Person c2 = new Person(); + c2.setId(2000); + + p1.getChildren().add(c1); + p1.getChildren().add(c2); + //只输出children.id以及根上的id + String s = JSON.toJSONString(p1, new MyPropertyPreFilter(new String[] {"children.id", "id"})); + + Assert.assertEquals("{\"children\":[{\"id\":1000},{\"id\":2000}],\"id\":100}", s); + } + + /** 测试只输出子字段map中的特定属性 */ + public void test_path2() throws Exception { + Person2 p1 = new Person2(); + p1.setId(1); + Map infoMap = new HashMap(); + infoMap.put("name", "李三"); + infoMap.put("height", "168"); + p1.setInfoMap(infoMap); + //只输出infoMap.name + String s = JSON.toJSONString(p1, new MyPropertyPreFilter(new String[] {"infoMap.name"})); + Assert.assertEquals("{\"infoMap\":{\"name\":\"李三\"}}", s); + } + + public static class MyPropertyPreFilter implements PropertyPreFilter { + String[] onlyProperties; + + public MyPropertyPreFilter(String[] onlyProperties) { + this.onlyProperties = onlyProperties; + } + + private static boolean containInclude(String[] ss, String s) { + if(ss == null || ss.length == 0 || s == null) + return false; + for(String st : ss) + if(st.startsWith(s)) + return true; + return false; + } + + public boolean apply(JSONSerializer serializer, Object source, String name) { + SerialContext nowContext = new SerialContext(serializer.getContext(), source, name, 0, 0); + String nowPath = getLinkedPath(nowContext); + System.out.println("path->" + nowPath); + //只输出children.id + return containInclude(onlyProperties, nowPath); + } + + } + + /** 输出结果 类似a.b.c.d等格式,忽略[] */ + private static String getLinkedPath(SerialContext serialContext) { + //这里有点bad smell,即要考虑parent为null,又要考虑fieldName为null,且对collection判断只能从fieldName,而不能从object入手 + boolean isCollection = serialContext.getFieldName() instanceof Integer; + boolean isFieldNameNull = serialContext.getFieldName() == null; + if(serialContext.getParent() == null) + return isCollection ? "" : isFieldNameNull ? "" : String.valueOf(serialContext.getFieldName()); + String parentLinkedPath = getLinkedPath(serialContext.getParent()); + if(isCollection || isFieldNameNull) + return parentLinkedPath; + return + parentLinkedPath.length() == 0 ? String.valueOf(serialContext.getFieldName()) : + parentLinkedPath + "." + serialContext.getFieldName(); + } + + public static class Person { + + private int id; + private int id2; + + private List children = new ArrayList(); + + public int getId2() { + return id2; + } + + public void setId2(int id2) { + this.id2 = id2; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } + + } + + public static class Person2 { + private int id; + private Map infoMap; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Map getInfoMap() { + return infoMap; + } + + public void setInfoMap(Map infoMap) { + this.infoMap = infoMap; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ProxyTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ProxyTest.java new file mode 100644 index 0000000000..7dbcefbac2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ProxyTest.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.serializer; + +import java.lang.reflect.Method; + +import javassist.util.proxy.MethodHandler; +import javassist.util.proxy.ProxyFactory; +import javassist.util.proxy.ProxyObject; +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class ProxyTest extends TestCase { + + public void test_0() throws Exception { + A a = create(A.class); + a.setId(123); + + Assert.assertEquals("{\"id\":123}", JSON.toJSONString(a)); + } + + public static T create(Class classs) throws Exception { + ProxyFactory factory = new ProxyFactory(); + factory.setSuperclass(classs); + Class clazz = factory.createClass(); + MethodHandler handler = new MethodHandler() { + + public Object invoke(Object self, Method overridden, Method forwarder, Object[] args) throws Throwable { + return forwarder.invoke(self, args); + } + }; + Object instance = clazz.newInstance(); + ((ProxyObject) instance).setHandler(handler); + return (T) instance; + } + + public static class A { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/RectangleSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/RectangleSerializerTest.java new file mode 100755 index 0000000000..37f1e17019 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/RectangleSerializerTest.java @@ -0,0 +1,38 @@ +package com.alibaba.json.bvt.serializer; + +import java.awt.Rectangle; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.RectangleCodec; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class RectangleSerializerTest extends TestCase { + + public void test_null() throws Exception { + JSONSerializer serializer = new JSONSerializer(); + Assert.assertEquals(RectangleCodec.class, serializer.getObjectWriter(Rectangle.class).getClass()); + + VO vo = new VO(); + + Assert.assertEquals("{\"value\":null}", JSON.toJSONString(vo, SerializerFeature.WriteMapNullValue)); + } + + private static class VO { + + private Rectangle value; + + public Rectangle getValue() { + return value; + } + + public void setValue(Rectangle value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/RefTest.java b/src/test/java/com/alibaba/json/bvt/serializer/RefTest.java new file mode 100644 index 0000000000..5ae48eb612 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/RefTest.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class RefTest extends TestCase { + + public void test_ref() throws Exception { + JSONSerializer ser = new JSONSerializer(); + Assert.assertNull(ser.getSerialContext(null)); + + Assert.assertFalse(ser.containsReference(null)); + } + + public void test_array_ref() throws Exception { + JSON.toJSONString(new A[] {new A()}, SerializerFeature.DisableCircularReferenceDetect); + } + + public class A { + + private A a; + + public A getA() { + return a; + } + + public void setA(A a) { + this.a = a; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/RefTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/RefTest2.java new file mode 100644 index 0000000000..c9e41190a6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/RefTest2.java @@ -0,0 +1,50 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class RefTest2 extends TestCase { + + public void test_ref() throws Exception { + Object[] array = new Object[1]; + array[0] = array; + Assert.assertEquals("[{\"$ref\":\"@\"}]", JSON.toJSONString(array)); + } + + public void test_ref_1() throws Exception { + Object[] array = new Object[3]; + array[0] = array; + array[1] = new Object(); + array[2] = new Object(); + Assert.assertEquals("[{\"$ref\":\"@\"},{},{}]", JSON.toJSONString(array)); + } + + public void test_ref_2() throws Exception { + Object[] array = new Object[3]; + array[0] = new Object(); + array[1] = array; + array[2] = new Object(); + Assert.assertEquals("[{},{\"$ref\":\"@\"},{}]", JSON.toJSONString(array)); + } + + public void test_ref_3() throws Exception { + Object[] array = new Object[3]; + array[0] = new Object(); + array[1] = new Object(); + array[2] = array; + Assert.assertEquals("[{},{},{\"$ref\":\"@\"}]", JSON.toJSONString(array)); + } + + public void test_parse() throws Exception { + Object[] array2 = JSON.parseObject("[{\"$ref\":\"$\"}]", Object[].class); + Assert.assertSame(array2, array2[0]); + } + + public void test_parse_1() throws Exception { + Object[] array2 = JSON.parseObject("[{\"$ref\":\"@\"}]", Object[].class); + Assert.assertSame(array2, array2[0]); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/RefTest3.java b/src/test/java/com/alibaba/json/bvt/serializer/RefTest3.java new file mode 100644 index 0000000000..256d41126c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/RefTest3.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class RefTest3 extends TestCase { + + public void test_ref() throws Exception { + Object[] array = new Object[1]; + array[0] = array; + Assert.assertEquals("[{\"$ref\":\"@\"}]", JSON.toJSONString(array)); + } + + public void test_parse() throws Exception { + Object[] array2 = JSON.parseObject("[{\"$ref\":\"$\"}]", Object[].class); + Assert.assertSame(array2, array2[0]); + } + + public void test_parse_1() throws Exception { + Object[] array2 = JSON.parseObject("[{\"$ref\":\"@\"}]", Object[].class); + Assert.assertSame(array2, array2[0]); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/RefTest4.java b/src/test/java/com/alibaba/json/bvt/serializer/RefTest4.java new file mode 100644 index 0000000000..8e0c18ce30 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/RefTest4.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.serializer; + +import java.math.BigDecimal; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class RefTest4 extends TestCase { + + public void test_str() throws Exception { + Object[] array = new Object[2]; + array[0] = "abc"; + array[1] = array[0]; + Assert.assertEquals("[\"abc\",\"abc\"]", JSON.toJSONString(array)); + } + + public void test_decimal() throws Exception { + Object[] array = new Object[2]; + array[0] = new BigDecimal("123"); + array[1] = array[0]; + Assert.assertEquals("[123,123]", JSON.toJSONString(array)); + } + + public void test_integer() throws Exception { + Object[] array = new Object[2]; + array[0] = Integer.valueOf(123); + array[1] = array[0]; + Assert.assertEquals("[123,123]", JSON.toJSONString(array)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/RefTest5.java b/src/test/java/com/alibaba/json/bvt/serializer/RefTest5.java new file mode 100644 index 0000000000..13cfb9d181 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/RefTest5.java @@ -0,0 +1,23 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class RefTest5 extends TestCase { + + public void test_ref() throws Exception { + Object[] array = new Object[1]; + array[0] = new Object[] { array }; + Assert.assertEquals("[[{\"$ref\":\"..\"}]]", JSON.toJSONString(array)); + } + + public void test_parse() throws Exception { + Object[] array2 = JSON.parseObject("[[{\"$ref\":\"..\"}]]", Object[].class); + Object[] item = (Object[]) array2[0]; + Assert.assertSame(array2, item[0]); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/RefTest6.java b/src/test/java/com/alibaba/json/bvt/serializer/RefTest6.java new file mode 100644 index 0000000000..c2e7689426 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/RefTest6.java @@ -0,0 +1,80 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class RefTest6 extends TestCase { + + /** + * A -> B -> C -> B -> A + * + * @throws Exception + */ + public void test_0() throws Exception { + A a = new A(); + B b = new B(); + C c = new C(); + a.setB(b); + b.setC(c); + c.setB(b); + b.setA(a); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("a", a); + jsonObject.put("c", c); + + String text = JSON.toJSONString(jsonObject, SerializerFeature.PrettyFormat); + System.out.println(text); + } + + private class A { + + private B b; + + public B getB() { + return b; + } + + public void setB(B b) { + this.b = b; + } + } + + private class B { + + private C c; + private A a; + + public C getC() { + return c; + } + + public void setC(C c) { + this.c = c; + } + + public A getA() { + return a; + } + + public void setA(A a) { + this.a = a; + } + } + + private class C { + + private B b; + + public B getB() { + return b; + } + + public void setB(B b) { + this.b = b; + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/RefTest7.java b/src/test/java/com/alibaba/json/bvt/serializer/RefTest7.java new file mode 100644 index 0000000000..683c1cb885 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/RefTest7.java @@ -0,0 +1,105 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class RefTest7 extends TestCase { + + public void test_bug_for_juqkai() throws Exception { + + VO vo = new VO(); + C c = new C(); + vo.setA(new A(c)); + vo.setB(new B(c)); + + VO[] root = new VO[] { vo }; + + String text = JSON.toJSONString(root); + System.out.println(text); + + VO[] array2 = JSON.parseObject(text, VO[].class); + Assert.assertEquals(1, array2.length); + Assert.assertNotNull(array2[0].getA()); + Assert.assertNotNull(array2[0].getB()); + Assert.assertNotNull(array2[0].getA().getC()); + Assert.assertNotNull(array2[0].getB().getC()); + Assert.assertSame(array2[0].getA().getC(), array2[0].getB().getC()); + } + + public static class VO { + + private A a; + private B b; + + public A getA() { + return a; + } + + public void setA(A a) { + this.a = a; + } + + public B getB() { + return b; + } + + public void setB(B b) { + this.b = b; + } + + } + + public static class A { + + private C c; + + public A(){ + + } + + public A(C c){ + this.c = c; + } + + public C getC() { + return c; + } + + public void setC(C c) { + this.c = c; + } + + } + + public static class B { + + private C c; + + public B(){ + + } + + public B(C c){ + this.c = c; + } + + public C getC() { + return c; + } + + public void setC(C c) { + this.c = c; + } + } + + public static class C { + + public C(){ + + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/RefTest8.java b/src/test/java/com/alibaba/json/bvt/serializer/RefTest8.java new file mode 100644 index 0000000000..02853954a4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/RefTest8.java @@ -0,0 +1,112 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class RefTest8 extends TestCase { + + public void test_bug_for_juqkai() throws Exception { + + C c = new C(); + + Map a = Collections.singletonMap("c", c); + Map b = Collections.singletonMap("c", c); + Map vo = new HashMap(); + vo.put("a", a); + vo.put("b", b); + + Object[] root = new Object[] { vo }; + + String text = JSON.toJSONString(root); + System.out.println(text); + + VO[] array2 = JSON.parseObject(text, VO[].class); + Assert.assertEquals(1, array2.length); + Assert.assertNotNull(array2[0].getA()); + Assert.assertNotNull(array2[0].getB()); + Assert.assertNotNull(array2[0].getA().getC()); + Assert.assertNotNull(array2[0].getB().getC()); + Assert.assertSame(array2[0].getA().getC(), array2[0].getB().getC()); + } + + private static class VO { + + private A a; + private B b; + + public A getA() { + return a; + } + + public void setA(A a) { + this.a = a; + } + + public B getB() { + return b; + } + + public void setB(B b) { + this.b = b; + } + + } + + private static class A { + + private C c; + + public A(){ + + } + + public A(C c){ + this.c = c; + } + + public C getC() { + return c; + } + + public void setC(C c) { + this.c = c; + } + + } + + private static class B { + + private C c; + + public B(){ + + } + + public B(C c){ + this.c = c; + } + + public C getC() { + return c; + } + + public void setC(C c) { + this.c = c; + } + } + + private static class C { + + public C(){ + + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/RefTest9.java b/src/test/java/com/alibaba/json/bvt/serializer/RefTest9.java new file mode 100644 index 0000000000..f7b353d2f6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/RefTest9.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.HashSet; +import java.util.Set; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class RefTest9 extends TestCase { + + public void test_bug_for_wanglin() throws Exception { + VO vo = new VO(); + A a = new A(); + vo.setA(a); + vo.getValues().add(a); + + String text = JSON.toJSONString(vo); + Assert.assertEquals("{\"a\":{},\"values\":[{\"$ref\":\"$.a\"}]}", text); + + VO vo2 = JSON.parseObject(text, VO.class); + } + + public static class VO { + + private A a; + private Set values = new HashSet(); + + public A getA() { + return a; + } + + public void setA(A a) { + this.a = a; + } + + public Set getValues() { + return values; + } + + public void setValues(Set values) { + this.values = values; + } + + } + + public static class A { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ReferenceDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ReferenceDeserializerTest.java new file mode 100644 index 0000000000..7bfdd91d45 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ReferenceDeserializerTest.java @@ -0,0 +1,48 @@ +package com.alibaba.json.bvt.serializer; + +import java.lang.ref.WeakReference; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.ReferenceCodec; + +public class ReferenceDeserializerTest extends TestCase { + + public void test_0() throws Exception { + ParserConfig config = new ParserConfig(); + config.putDeserializer(MyRef.class, ReferenceCodec.instance); + Exception error = null; + try { + JSON.parseObject("{\"ref\":{}}", VO.class, config, 0); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public static class VO { + + private MyRef ref; + + public MyRef getRef() { + return ref; + } + + public void setRef(MyRef ref) { + this.ref = ref; + } + + } + + public static class MyRef extends WeakReference { + + MyRef(T referent){ + super(referent); + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerialContextTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SerialContextTest.java new file mode 100755 index 0000000000..c4e2dca279 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerialContextTest.java @@ -0,0 +1,16 @@ +package com.alibaba.json.bvt.serializer; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerialContext; + + +public class SerialContextTest extends TestCase { + public void test_context() throws Exception { + SerialContext root = new SerialContext(null, null, null, 0, 0); + SerialContext context = new SerialContext(root, null, "x", 0, 0); + Assert.assertEquals("x", context.getFieldName()); + Assert.assertEquals("$.x", context.toString()); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/SerialWriterStringEncoderTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SerialWriterStringEncoderTest.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/serializer/SerialWriterStringEncoderTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/SerialWriterStringEncoderTest.java index d0b69f94a6..807b61a2b1 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/SerialWriterStringEncoderTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerialWriterStringEncoderTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.nio.charset.Charset; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.SerialWriterStringEncoder; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/SerialWriterStringEncoderTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/SerialWriterStringEncoderTest2.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/serializer/SerialWriterStringEncoderTest2.java rename to src/test/java/com/alibaba/json/bvt/serializer/SerialWriterStringEncoderTest2.java index 9e393ad104..f21fbadaaf --- a/src/test/java/com/alibaba/json/test/bvt/serializer/SerialWriterStringEncoderTest2.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerialWriterStringEncoderTest2.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.nio.ByteBuffer; import java.nio.CharBuffer; @@ -6,7 +6,7 @@ import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.SerialWriterStringEncoder; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/SerialWriterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SerialWriterTest.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/serializer/SerialWriterTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/SerialWriterTest.java index 0144062dfa..0505dc0ff4 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/SerialWriterTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerialWriterTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeConfigTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeConfigTest.java new file mode 100755 index 0000000000..227bf13515 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeConfigTest.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.LinkedHashMap; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class SerializeConfigTest extends TestCase { + + public void test_0() throws Exception { + SerializeConfig config = new SerializeConfig(); + + Exception error = null; + try { + config.createJavaBeanSerializer(int.class); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + } + + public void test_1() throws Exception { + SerializeConfig config = new SerializeConfig(); + config.setTypeKey("%type"); + Assert.assertEquals("%type", config.getTypeKey()); + + Assert.assertEquals("{\"@type\":\"java.util.LinkedHashMap\"}", + JSON.toJSONString(new LinkedHashMap(), config, SerializerFeature.WriteClassName)); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest.java index a73deff5a7..2b7d4d5cf4 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.io.StringWriter; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.SerializeWriter; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_1.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_1.java old mode 100644 new mode 100755 similarity index 85% rename from src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_1.java rename to src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_1.java index 71a57794ef..b602a0c6cc --- a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_1.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_1.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.io.ByteArrayOutputStream; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.SerializeWriter; @@ -36,12 +36,6 @@ public void test_3 () throws Exception { Assert.assertEquals("'abc'", new String(out.toBytes("UTF-16"), "UTF-16")); } - public void test_4 () throws Exception { - SerializeWriter out = new SerializeWriter(1); - out.writeBooleanArray(new boolean[] {true, true, false, false}); - Assert.assertEquals("[true,true,false,false]", new String(out.toBytes("UTF-16"), "UTF-16")); - } - public void test_5 () throws Exception { SerializeWriter out = new SerializeWriter(1); out.write((String) null); diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_10.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_10.java new file mode 100644 index 0000000000..a90840ee99 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_10.java @@ -0,0 +1,70 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.serializer.SerializeWriter; + +public class SerializeWriterTest_10 extends TestCase { + + public void test_erro_0() throws Exception { + SerializeWriter out = new SerializeWriter(); + Exception error = null; + try { + out.write(new char[0], -1, 0); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + out.close(); + } + + public void test_erro_1() throws Exception { + SerializeWriter out = new SerializeWriter(); + Exception error = null; + try { + out.write(new char[0], 1, 0); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + out.close(); + } + + public void test_erro_2() throws Exception { + SerializeWriter out = new SerializeWriter(); + Exception error = null; + try { + out.write(new char[0], 0, -1); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + out.close(); + } + + public void test_erro_3() throws Exception { + SerializeWriter out = new SerializeWriter(); + Exception error = null; + try { + out.write(new char[] { '0', '0' }, 1, 2); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + out.close(); + } + + public void test_erro_4() throws Exception { + SerializeWriter out = new SerializeWriter(); + Exception error = null; + try { + out.write(new char[] { '0', '0' }, 1, Integer.MAX_VALUE); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + out.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_11.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_11.java new file mode 100644 index 0000000000..4ea669b4ee --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_11.java @@ -0,0 +1,22 @@ +package com.alibaba.json.bvt.serializer; + +import java.io.ByteArrayOutputStream; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.serializer.SerializeWriter; + +public class SerializeWriterTest_11 extends TestCase { + + public void test_erro_0() throws Exception { + SerializeWriter out = new SerializeWriter(); + out.write(true); + ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + out.writeTo(byteOut, "UTF-8"); + Assert.assertEquals("true", new String(byteOut.toByteArray())); + out.close(); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_12.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_12.java new file mode 100644 index 0000000000..264304096d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_12.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt.serializer; + +import java.io.IOException; +import java.io.Writer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.serializer.SerializeWriter; + +public class SerializeWriterTest_12 extends TestCase { + + public void test_erro_0() throws Exception { + SerializeWriter out = new SerializeWriter(new ErrorWriter()); + Exception error = null; + try { + out.flush(); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + out.close(); + } + + public static class ErrorWriter extends Writer { + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + throw new IOException(); + } + + @Override + public void flush() throws IOException { + throw new IOException(); + } + + @Override + public void close() throws IOException { + + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_13.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_13.java new file mode 100644 index 0000000000..f46c5a9b18 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_13.java @@ -0,0 +1,57 @@ +package com.alibaba.json.bvt.serializer; + +import java.io.StringWriter; +import java.util.Collections; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class SerializeWriterTest_13 extends TestCase { + + public void test_default() throws Exception { + Assert.assertEquals("{\"\":\"\"}", // + JSON.toJSONStringZ(Collections.singletonMap("", ""), // + SerializeConfig.getGlobalInstance())); + } + + public void test_single() throws Exception { + Assert.assertEquals("{'':''}", // + JSON.toJSONStringZ(Collections.singletonMap("", ""), // + SerializeConfig.getGlobalInstance(), SerializerFeature.UseSingleQuotes)); + } + + public void test_writer() throws Exception { + SerializeWriter out = new SerializeWriter(3); + + try { + JSONSerializer serializer = new JSONSerializer(out); + + serializer.write(Collections.singletonMap("", "")); + Assert.assertEquals("{\"\":\"\"}", out.toString()); + } finally { + out.close(); + } + } + + public void test_writer_single() throws Exception { + SerializeWriter out = new SerializeWriter(3); + out.config(SerializerFeature.UseSingleQuotes, true); + + try { + JSONSerializer serializer = new JSONSerializer(out); + + serializer.write(Collections.singletonMap("", "")); + Assert.assertEquals("{'':''}", out.toString()); + } finally { + out.close(); + } + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_14.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_14.java new file mode 100644 index 0000000000..6f1064538b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_14.java @@ -0,0 +1,61 @@ +package com.alibaba.json.bvt.serializer; + +import java.io.StringWriter; +import java.util.Collections; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializeWriter; + +public class SerializeWriterTest_14 extends TestCase { + @SuppressWarnings("rawtypes") + public void test_writer_1() throws Exception { + StringWriter strOut = new StringWriter(); + SerializeWriter out = new SerializeWriter(strOut, 1); + + try { + JSONSerializer serializer = new JSONSerializer(out); + + Map map = Collections.singletonMap("", "a"); + serializer.write(map); + } finally { + out.close(); + } + Assert.assertEquals("{\"\":\"a\"}", strOut.toString()); + } + + + public void test_writer_2() throws Exception { + StringWriter strOut = new StringWriter(); + SerializeWriter out = new SerializeWriter(strOut, 1); + + try { + JSONSerializer serializer = new JSONSerializer(out); + + Map map = Collections.singletonMap("ab", "a"); + serializer.write(map); + } finally { + out.close(); + } + Assert.assertEquals("{ab:\"a\"}", strOut.toString()); + } + + public void test_writer_3() throws Exception { + StringWriter strOut = new StringWriter(); + SerializeWriter out = new SerializeWriter(strOut, 1); + + try { + JSONSerializer serializer = new JSONSerializer(out); + + Map map = Collections.singletonMap("ab\t", "a"); + serializer.write(map); + } finally { + out.close(); + } + Assert.assertEquals("{\"ab\\t\":\"a\"}", strOut.toString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_15.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_15.java new file mode 100644 index 0000000000..75a2399540 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_15.java @@ -0,0 +1,65 @@ +package com.alibaba.json.bvt.serializer; + +import java.io.StringWriter; +import java.util.Collections; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class SerializeWriterTest_15 extends TestCase { + @SuppressWarnings("rawtypes") + public void test_writer_1() throws Exception { + StringWriter strOut = new StringWriter(); + SerializeWriter out = new SerializeWriter(strOut, 1); + out.config(SerializerFeature.UseSingleQuotes, true); + + try { + JSONSerializer serializer = new JSONSerializer(out); + + Map map = Collections.singletonMap("", "a"); + serializer.write(map); + } finally { + out.close(); + } + Assert.assertEquals("{'':'a'}", strOut.toString()); + } + + + public void test_writer_2() throws Exception { + StringWriter strOut = new StringWriter(); + SerializeWriter out = new SerializeWriter(strOut, 1); + out.config(SerializerFeature.UseSingleQuotes, true); + + try { + JSONSerializer serializer = new JSONSerializer(out); + + Map map = Collections.singletonMap("ab", "a"); + serializer.write(map); + } finally { + out.close(); + } + Assert.assertEquals("{ab:'a'}", strOut.toString()); + } + + public void test_writer_3() throws Exception { + StringWriter strOut = new StringWriter(); + SerializeWriter out = new SerializeWriter(strOut, 1); + out.config(SerializerFeature.UseSingleQuotes, true); + + try { + JSONSerializer serializer = new JSONSerializer(out); + + Map map = Collections.singletonMap("ab\t", "a"); + serializer.write(map); + } finally { + out.close(); + } + Assert.assertEquals("{'ab\\t':'a'}", strOut.toString()); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_16.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_16.java new file mode 100644 index 0000000000..bf41c47327 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_16.java @@ -0,0 +1,45 @@ +package com.alibaba.json.bvt.serializer; + +import java.io.StringWriter; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class SerializeWriterTest_16 extends TestCase { + + public void test_writer_1() throws Exception { + StringWriter strOut = new StringWriter(); + SerializeWriter out = new SerializeWriter(strOut, 14); + out.config(SerializerFeature.BrowserCompatible, true); + + try { + JSONSerializer serializer = new JSONSerializer(out); + + VO vo = new VO(); + vo.setValue("abcd\t"); + serializer.write(vo); + } finally { + out.close(); + } + Assert.assertEquals("{value:\"abcd\\t\"}", strOut.toString()); + } + + private static class VO { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_17.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_17.java new file mode 100644 index 0000000000..bd97c83169 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_17.java @@ -0,0 +1,63 @@ +package com.alibaba.json.bvt.serializer; + +import java.io.StringWriter; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class SerializeWriterTest_17 extends TestCase { + + public void test_writer_1() throws Exception { + StringWriter strOut = new StringWriter(); + SerializeWriter out = new SerializeWriter(strOut, 6); + out.config(SerializerFeature.QuoteFieldNames, true); + + try { + JSONSerializer serializer = new JSONSerializer(out); + + VO vo = new VO(); + vo.setValue(123456789); + serializer.write(vo); + } finally { + out.close(); + } + Assert.assertEquals("{\"value\":123456789}", strOut.toString()); + } + + public void test_direct() throws Exception { + SerializeWriter out = new SerializeWriter(6); + out.config(SerializerFeature.QuoteFieldNames, true); + + try { + JSONSerializer serializer = new JSONSerializer(out); + + VO vo = new VO(); + vo.setValue(123456789); + serializer.write(vo); + + Assert.assertEquals("{\"value\":123456789}", out.toString()); + } finally { + out.close(); + } + + } + + public static class VO { + + private long value; + + public long getValue() { + return value; + } + + public void setValue(long value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_18.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_18.java new file mode 100644 index 0000000000..19acc14f9b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_18.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class SerializeWriterTest_18 extends TestCase { + + public void test_writer_1() throws Exception { + SerializeWriter out = new SerializeWriter(14); + out.config(SerializerFeature.QuoteFieldNames, true); + + try { + JSONSerializer serializer = new JSONSerializer(out); + + VO vo = new VO(); + vo.setValue("#"); + serializer.write(vo); + + Assert.assertEquals("{\"value\":\"#\"}", out.toString()); + } finally { + out.close(); + } + + } + + public static class VO { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_19.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_19.java new file mode 100644 index 0000000000..faf75e4c0d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_19.java @@ -0,0 +1,47 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class SerializeWriterTest_19 extends TestCase { + + public void test_writer_1() throws Exception { + SerializeWriter out = new SerializeWriter(14); + out.config(SerializerFeature.QuoteFieldNames, true); + out.config(SerializerFeature.UseSingleQuotes, true); + try { + JSONSerializer serializer = new JSONSerializer(out); + + VO vo = new VO(); + vo.getValues().add("#"); + serializer.write(vo); + + Assert.assertEquals("{'values':['#']}", out.toString()); + } finally { + out.close(); + } + + } + + public static class VO { + + private List values = new ArrayList(); + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_2.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_2.java old mode 100644 new mode 100755 similarity index 85% rename from src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_2.java rename to src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_2.java index a8d6c8cad8..da8cfe34d0 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_2.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_2.java @@ -1,11 +1,13 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.serializer.SerializeWriter; import com.alibaba.fastjson.serializer.SerializerFeature; +@SuppressWarnings("deprecation") public class SerializeWriterTest_2 extends TestCase { public void test_0() throws Exception { @@ -13,13 +15,15 @@ public void test_0() throws Exception { out.config(SerializerFeature.WriteTabAsSpecial, true); out.writeString("\t\n \b\n\r\f\\ \""); Assert.assertEquals("\"\\t\\n \\b\\n\\r\\f\\\\ \\\"\"", out.toString()); + out.close(); } - + public void test_1() throws Exception { SerializeWriter out = new SerializeWriter(1); out.config(SerializerFeature.WriteTabAsSpecial, true); out.config(SerializerFeature.UseSingleQuotes, true); out.writeString("\t\n \b\n\r\f\\ \""); Assert.assertEquals("'\\t\\n \\b\\n\\r\\f\\\\ \"'", out.toString()); + out.close(); } } diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_3.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_3.java old mode 100644 new mode 100755 similarity index 61% rename from src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_3.java rename to src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_3.java index 64c098a4c1..7ca7f57e54 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_3.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_3.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.SerializeWriter; @@ -36,19 +36,5 @@ public void test_null_1() throws Exception { Assert.assertEquals(",name:null", out.toString()); } - public void test_2() throws Exception { - SerializeWriter out = new SerializeWriter(1); - out.config(SerializerFeature.QuoteFieldNames, true); - out.config(SerializerFeature.WriteTabAsSpecial, true); - out.writeFieldValue(',', "\t\n \b\n\r\f\\ \"", "jobs"); - Assert.assertEquals(",\"\\t\\n \\b\\n\\r\\f\\\\ \\\"\":\"jobs\"", out.toString()); - } - - public void test_3() throws Exception { - SerializeWriter out = new SerializeWriter(1); - out.config(SerializerFeature.QuoteFieldNames, true); - out.config(SerializerFeature.WriteTabAsSpecial, false); - out.writeFieldValue(',', "\t\n \b\n\r\f\\ \"", "jobs"); - Assert.assertEquals(",\"\t\\n \\b\\n\\r\\f\\\\ \\\"\":\"jobs\"", out.toString()); - } + } diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_4.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_4.java old mode 100644 new mode 100755 similarity index 81% rename from src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_4.java rename to src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_4.java index c3259f2269..7899b7315b --- a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_4.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_4.java @@ -1,19 +1,22 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + import com.alibaba.fastjson.serializer.SerializeWriter; import com.alibaba.fastjson.serializer.SerializerFeature; +@SuppressWarnings("deprecation") public class SerializeWriterTest_4 extends TestCase { public void test_0() throws Exception { SerializeWriter out = new SerializeWriter(1); out.config(SerializerFeature.QuoteFieldNames, true); out.config(SerializerFeature.WriteTabAsSpecial, true); - out.writeFieldValue(',', "\tname", "\t"); - Assert.assertEquals(",\"\\tname\":\"\\t\"", out.toString()); + out.writeFieldValue(',', "name", "\t"); + Assert.assertEquals(",\"name\":\"\\t\"", out.toString()); + out.close(); } public void test_1() throws Exception { @@ -22,6 +25,7 @@ public void test_1() throws Exception { out.config(SerializerFeature.WriteTabAsSpecial, true); out.writeFieldValue(',', "name", "\t\n"); Assert.assertEquals(",\"name\":\"\\t\\n\"", out.toString()); + out.close(); } public void test_3() throws Exception { @@ -30,6 +34,7 @@ public void test_3() throws Exception { out.config(SerializerFeature.WriteTabAsSpecial, true); out.writeFieldValue(',', "name", "\t\n \b\n\r\f\\ \""); Assert.assertEquals(",\"name\":\"\\t\\n \\b\\n\\r\\f\\\\ \\\"\"", out.toString()); + out.close(); } public void test_4() throws Exception { @@ -37,7 +42,8 @@ public void test_4() throws Exception { out.config(SerializerFeature.QuoteFieldNames, true); out.config(SerializerFeature.WriteTabAsSpecial, false); out.writeFieldValue(',', "name", "\t\n \b\n\r\f\\ \""); - Assert.assertEquals(",\"name\":\"\t\\n \\b\\n\\r\\f\\\\ \\\"\"", out.toString()); + Assert.assertEquals(",\"name\":\"\\t\\n \\b\\n\\r\\f\\\\ \\\"\"", out.toString()); + out.close(); } public void test_5() throws Exception { @@ -46,5 +52,6 @@ public void test_5() throws Exception { out.config(SerializerFeature.WriteTabAsSpecial, true); out.writeString("\t\n \b\n\r\f\\ \""); Assert.assertEquals("\"\\t\\n \\b\\n\\r\\f\\\\ \\\"\"", out.toString()); + out.close(); } } diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_5.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_5.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_5.java rename to src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_5.java index ee98c83909..c6e419ff46 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_5.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_5.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.math.BigDecimal; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.SerializeWriter; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_6.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_6.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_6.java rename to src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_6.java index 54dde456a6..a0a991ee33 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_6.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_6.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.SerializeWriter; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_7.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_7.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_7.java rename to src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_7.java index 67eb6cd5b3..78ac19dd31 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeWriterTest_7.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_7.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.serializer.SerializeWriter; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_8.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_8.java new file mode 100644 index 0000000000..8d9b34007e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_8.java @@ -0,0 +1,69 @@ +package com.alibaba.json.bvt.serializer; + +import java.io.StringWriter; +import java.util.Collections; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class SerializeWriterTest_8 extends TestCase { + + public void test_BrowserCompatible() throws Exception { + StringBuilder buf = new StringBuilder(); + for (int i = 0; i < 1024; ++i) { + buf.append('a'); + } + buf.append("中国"); + buf.append("\0"); + JSON.toJSONString(buf.toString(), SerializerFeature.BrowserCompatible); + } + + public void test_writer() throws Exception { + StringBuilder buf = new StringBuilder(); + for (int i = 0; i < 1024; ++i) { + buf.append('a'); + } + buf.append("中国"); + buf.append("\0"); + + StringWriter out = new StringWriter(); + JSON.writeJSONStringTo(buf.toString(), out, SerializerFeature.BrowserCompatible); + } + + public void test_singleQuote() throws Exception { + StringBuilder buf = new StringBuilder(); + for (int i = 0; i < 1024; ++i) { + buf.append('a'); + } + buf.append("中国"); + buf.append("\0"); + + SerializeWriter out = new SerializeWriter(new StringWriter()); + + try { + JSONSerializer serializer = new JSONSerializer(out); + serializer.config(SerializerFeature.QuoteFieldNames, false); + serializer.config(SerializerFeature.UseSingleQuotes, true); + + serializer.write(Collections.singletonMap(buf.toString(), "")); + } finally { + out.close(); + } + } + + public void test_singleQuote_writer() throws Exception { + StringBuilder buf = new StringBuilder(); + for (int i = 0; i < 1024; ++i) { + buf.append('a'); + } + buf.append("中国"); + buf.append("\0"); + + StringWriter out = new StringWriter(); + JSON.writeJSONStringTo(Collections.singletonMap(buf.toString(), ""), out, SerializerFeature.UseSingleQuotes); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_9.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_9.java new file mode 100644 index 0000000000..7fe321e9cb --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializeWriterTest_9.java @@ -0,0 +1,74 @@ +package com.alibaba.json.bvt.serializer; + +import java.io.ByteArrayOutputStream; +import java.io.StringWriter; +import java.nio.charset.Charset; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.serializer.SerializeWriter; + +public class SerializeWriterTest_9 extends TestCase { + + public void test_error() throws Exception { + SerializeWriter writer = new SerializeWriter(new StringWriter()); + Exception error = null; + try { + writer.writeTo(new StringWriter()); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + writer.close(); + } + + public void test_error_2() throws Exception { + SerializeWriter writer = new SerializeWriter(new StringWriter()); + Exception error = null; + try { + writer.writeTo(new ByteArrayOutputStream(), Charset.forName("UTF-8")); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + writer.close(); + } + + public void test_error_3() throws Exception { + SerializeWriter writer = new SerializeWriter(new StringWriter()); + Exception error = null; + try { + writer.writeTo(new ByteArrayOutputStream(), "UTF-8"); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + writer.close(); + } + + public void test_error_4() throws Exception { + SerializeWriter writer = new SerializeWriter(new StringWriter()); + Exception error = null; + try { + writer.toCharArray(); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + writer.close(); + } + + public void test_error_5() throws Exception { + SerializeWriter writer = new SerializeWriter(new StringWriter()); + Exception error = null; + try { + writer.toBytes("UTF-8"); + } catch (Exception ex) { + error = ex; + } + Assert.assertNotNull(error); + writer.close(); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SerializerFeatureTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SerializerFeatureTest.java new file mode 100755 index 0000000000..be82d8c411 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/SerializerFeatureTest.java @@ -0,0 +1,17 @@ +package com.alibaba.json.bvt.serializer; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class SerializerFeatureTest extends TestCase { + public void test_0 () throws Exception { + int feature = 0; + feature = SerializerFeature.config(feature, SerializerFeature.BrowserCompatible, true); + Assert.assertEquals(true, SerializerFeature.isEnabled(feature, SerializerFeature.BrowserCompatible)); + feature = SerializerFeature.config(feature, SerializerFeature.BrowserCompatible, false); + Assert.assertEquals(false, SerializerFeature.isEnabled(feature, SerializerFeature.BrowserCompatible)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ShortArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ShortArraySerializerTest.java new file mode 100755 index 0000000000..06461ead6b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ShortArraySerializerTest.java @@ -0,0 +1,18 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializeWriter; + +public class ShortArraySerializerTest extends TestCase { + + public void test_0() { + Assert.assertEquals("[]", JSON.toJSONString(new short[0])); + Assert.assertEquals("[1,2]", JSON.toJSONString(new short[] { 1, 2 })); + Assert.assertEquals("[1,2,3]", JSON.toJSONString(new short[] { 1, 2, 3 })); + } + +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/ShortFieldSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ShortFieldSerializerTest.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/serializer/ShortFieldSerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/ShortFieldSerializerTest.java index 4371a29442..89e4f37140 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/ShortFieldSerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/ShortFieldSerializerTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/ShortSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ShortSerializerTest.java new file mode 100755 index 0000000000..a5f354b495 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/ShortSerializerTest.java @@ -0,0 +1,31 @@ +package com.alibaba.json.bvt.serializer; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class ShortSerializerTest extends TestCase { + + public void test_null() throws Exception { + VO vo = new VO(); + + Assert.assertEquals("{\"value\":null}", JSON.toJSONString(vo, SerializerFeature.WriteMapNullValue)); + } + + private static class VO { + + private Short value; + + public Short getValue() { + return value; + } + + public void setValue(Short value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/SimpleDataFormatSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SimpleDataFormatSerializerTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/serializer/SimpleDataFormatSerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/SimpleDataFormatSerializerTest.java index 1c36080f7c..fd3360f91a --- a/src/test/java/com/alibaba/json/test/bvt/serializer/SimpleDataFormatSerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/SimpleDataFormatSerializerTest.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.text.SimpleDateFormat; import java.util.Date; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/SimplePropertyPreFilterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SimplePropertyPreFilterTest.java new file mode 100755 index 0000000000..35d92712bc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/SimplePropertyPreFilterTest.java @@ -0,0 +1,161 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SimplePropertyPreFilter; + +public class SimplePropertyPreFilterTest extends TestCase { + + private VO vo; + + private A a; + + private Map map; + + protected void setUp() throws Exception { + vo = new VO(); + vo.setId(123); + vo.setName("sandzhangtoo"); + + a = new A(); + a.setId(123); + a.setName("sandzhangtoo"); + + map = new HashMap(); + map.put("id", 123); + map.put("name", "sandzhangtoo"); + map.put(null, null); + } + + public void test_name() throws Exception { + SimplePropertyPreFilter filter = new SimplePropertyPreFilter(VO.class, "name"); + Assert.assertEquals("{\"name\":\"sandzhangtoo\"}", JSON.toJSONString(vo, filter)); + } + + public void test_name_0() throws Exception { + SimplePropertyPreFilter filter = new SimplePropertyPreFilter("name"); + Assert.assertEquals("{\"name\":\"sandzhangtoo\"}", JSON.toJSONString(vo, filter)); + } + + public void test_name_a() throws Exception { + SimplePropertyPreFilter filter = new SimplePropertyPreFilter(VO.class, "name"); + Assert.assertEquals(VO.class, filter.getClazz()); + Assert.assertEquals(1, filter.getIncludes().size()); + Assert.assertTrue(filter.apply(null, null, null)); + + String text = JSON.toJSONString(a, filter); + Assert.assertTrue("{\"id\":123,\"name\":\"sandzhangtoo\"}".equals(text) || "{\"name\":\"sandzhangtoo\",\"id\":123}".equals(text)); + } + + public void test_name_a1() throws Exception { + SimplePropertyPreFilter filter = new SimplePropertyPreFilter("name"); + Assert.assertEquals("{\"name\":\"sandzhangtoo\"}", JSON.toJSONString(a, filter)); + } + + public void test_id() throws Exception { + SimplePropertyPreFilter filter = new SimplePropertyPreFilter(VO.class, "id"); + Assert.assertEquals("{\"id\":123}", JSON.toJSONString(vo, filter)); + } + + public void test_id_0() throws Exception { + SimplePropertyPreFilter filter = new SimplePropertyPreFilter("id"); + Assert.assertEquals("{\"id\":123}", JSON.toJSONString(vo, filter)); + } + + public void test_map() throws Exception { + SimplePropertyPreFilter filter = new SimplePropertyPreFilter(VO.class, "name"); + String text = JSON.toJSONString(map, filter); + Assert.assertTrue("{\"id\":123,\"name\":\"sandzhangtoo\"}".equals(text) || "{\"name\":\"sandzhangtoo\",\"id\":123}".equals(text)); + } + + public void test_map_id() throws Exception { + SimplePropertyPreFilter filter = new SimplePropertyPreFilter("id"); + Assert.assertEquals("{\"id\":123}", JSON.toJSONString(map, filter)); + } + + public void test_map_name() throws Exception { + SimplePropertyPreFilter filter = new SimplePropertyPreFilter("name"); + Assert.assertEquals("{\"name\":\"sandzhangtoo\"}", JSON.toJSONString(map, filter)); + } + + public void test_all() throws Exception { + SimplePropertyPreFilter filter = new SimplePropertyPreFilter(VO.class); + String text = JSON.toJSONString(vo, filter); + Assert.assertTrue("{\"id\":123,\"name\":\"sandzhangtoo\"}".equals(text) || "{\"name\":\"sandzhangtoo\",\"id\":123}".equals(text)); + } + + public void test_all_map() throws Exception { + SimplePropertyPreFilter filter = new SimplePropertyPreFilter(VO.class); + String text = JSON.toJSONString(map, filter); + Assert.assertTrue("{\"id\":123,\"name\":\"sandzhangtoo\"}".equals(text) || "{\"name\":\"sandzhangtoo\",\"id\":123}".equals(text)); + } + + public void test_exclude_id() throws Exception { + SimplePropertyPreFilter filter = new SimplePropertyPreFilter(VO.class); + filter.getExcludes().add("id"); + Assert.assertEquals("{\"name\":\"sandzhangtoo\"}", JSON.toJSONString(vo, filter)); + } + + public void test_exclude_id_map() throws Exception { + SimplePropertyPreFilter filter = new SimplePropertyPreFilter(VO.class); + filter.getExcludes().add("id"); + Assert.assertEquals("{\"name\":\"sandzhangtoo\"}", JSON.toJSONString(vo, filter)); + } + + public void test_exclude_name() throws Exception { + SimplePropertyPreFilter filter = new SimplePropertyPreFilter(VO.class); + filter.getExcludes().add("name"); + Assert.assertEquals("{\"id\":123}", JSON.toJSONString(vo, filter)); + } + + public static class VO { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + + public static class A { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/SpecicalStringTest.java b/src/test/java/com/alibaba/json/bvt/serializer/SpecicalStringTest.java old mode 100644 new mode 100755 similarity index 94% rename from src/test/java/com/alibaba/json/test/bvt/serializer/SpecicalStringTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/SpecicalStringTest.java index 0e6a733e44..f56aab986d --- a/src/test/java/com/alibaba/json/test/bvt/serializer/SpecicalStringTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/SpecicalStringTest.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/StringArraySerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/StringArraySerializerTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/serializer/StringArraySerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/StringArraySerializerTest.java index 158c3c8aec..e599f64615 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/StringArraySerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/StringArraySerializerTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/StringSerializerTest.java b/src/test/java/com/alibaba/json/bvt/serializer/StringSerializerTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/serializer/StringSerializerTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/StringSerializerTest.java index 206b472503..c50c9d823f --- a/src/test/java/com/alibaba/json/test/bvt/serializer/StringSerializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/StringSerializerTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.io.StringWriter; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -144,7 +144,7 @@ public void test_10() throws Exception { public void test_10_d() throws Exception { SerializeWriter out = new SerializeWriter(); - out.writeFieldName("123\na\nb\nc\nd\"'e"); + out.writeFieldName("123\na\nb\nc\nd\"'e", true); Assert.assertEquals("\"123\\na\\nb\\nc\\nd\\\"'e\":", out.toString()); } @@ -159,7 +159,7 @@ public void test_11() throws Exception { public void test_11_d() throws Exception { SerializeWriter out = new SerializeWriter(); - out.writeKeyWithDoubleQuote("123\na\nb\nc\nd\"'e"); + out.writeString("123\na\nb\nc\nd\"'e", ':'); Assert.assertEquals("\"123\\na\\nb\\nc\\nd\\\"'e\":", out.toString()); } @@ -174,7 +174,7 @@ public void test_12() throws Exception { public void test_12_d() throws Exception { SerializeWriter out = new SerializeWriter(1); - out.writeKeyWithDoubleQuote("123\na\nb\nc\nd\"'e"); + out.writeString("123\na\nb\nc\nd\"'e", ':'); Assert.assertEquals("\"123\\na\\nb\\nc\\nd\\\"'e\":", out.toString()); } diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/TestInnerClass.java b/src/test/java/com/alibaba/json/bvt/serializer/TestInnerClass.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/serializer/TestInnerClass.java rename to src/test/java/com/alibaba/json/bvt/serializer/TestInnerClass.java index 419fc40b7e..46aa81be36 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/TestInnerClass.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/TestInnerClass.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/TestInnerClass1.java b/src/test/java/com/alibaba/json/bvt/serializer/TestInnerClass1.java old mode 100644 new mode 100755 similarity index 87% rename from src/test/java/com/alibaba/json/test/bvt/serializer/TestInnerClass1.java rename to src/test/java/com/alibaba/json/bvt/serializer/TestInnerClass1.java index cd8fc41577..d3a5d0a52c --- a/src/test/java/com/alibaba/json/test/bvt/serializer/TestInnerClass1.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/TestInnerClass1.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/TestInnerClass2.java b/src/test/java/com/alibaba/json/bvt/serializer/TestInnerClass2.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/serializer/TestInnerClass2.java rename to src/test/java/com/alibaba/json/bvt/serializer/TestInnerClass2.java index 3f55646d05..3550690b1b --- a/src/test/java/com/alibaba/json/test/bvt/serializer/TestInnerClass2.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/TestInnerClass2.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/TestPivateStaticClass.java b/src/test/java/com/alibaba/json/bvt/serializer/TestPivateStaticClass.java old mode 100644 new mode 100755 similarity index 88% rename from src/test/java/com/alibaba/json/test/bvt/serializer/TestPivateStaticClass.java rename to src/test/java/com/alibaba/json/bvt/serializer/TestPivateStaticClass.java index 22e3a0d005..2956726da5 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/TestPivateStaticClass.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/TestPivateStaticClass.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TestSortField.java b/src/test/java/com/alibaba/json/bvt/serializer/TestSortField.java new file mode 100755 index 0000000000..fbfba5e5f4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/TestSortField.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class TestSortField extends TestCase { + + public void test_0() throws Exception { + Map map = new LinkedHashMap(); + + map.put("nnn", "123"); + + map.put("13", "123"); + + String text = JSON.toJSONString(map); + + Assert.assertEquals("{\"nnn\":\"123\",\"13\":\"123\"}", text); + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial.java b/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial.java new file mode 100755 index 0000000000..3310ebae7f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial.java @@ -0,0 +1,18 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class TestSpecial extends TestCase { + @SuppressWarnings("deprecation") + public void test_0 () throws Exception { + Map map = new HashMap(); + map.put("name", "\n\r\t"); + System.out.println(JSON.toJSONString(map, SerializerFeature.WriteTabAsSpecial)); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial2.java b/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial2.java new file mode 100644 index 0000000000..b626ee9a6e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial2.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class TestSpecial2 extends TestCase { + + public void test_0() throws Exception { + StringBuilder buf = new StringBuilder(); + buf.append('\r'); + buf.append('\r'); + for (int i = 0; i < 1000; ++i) { + buf.append((char) 160); + } + + VO vo = new VO(); + vo.setValue(buf.toString()); + + System.out.println(JSON.toJSONString(vo)); + } + + public static class VO { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial3.java b/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial3.java new file mode 100644 index 0000000000..868d6626fa --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial3.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class TestSpecial3 extends TestCase { + + public void test_0() throws Exception { + StringBuilder buf = new StringBuilder(); + buf.append('\r'); + buf.append('\r'); + for (int i = 0; i < 1000; ++i) { + buf.append('\u000B'); + } + + VO vo = new VO(); + vo.setValue(buf.toString()); + + System.out.println(JSON.toJSONString(vo)); + } + + public static class VO { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial4.java b/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial4.java new file mode 100644 index 0000000000..08d99f2cb1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial4.java @@ -0,0 +1,36 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class TestSpecial4 extends TestCase { + + public void test_0() throws Exception { + StringBuilder buf = new StringBuilder(); + buf.append('\r'); + buf.append('\r'); + for (int i = 0; i < 1000; ++i) { + buf.append('\u2028'); + } + + VO vo = new VO(); + vo.setValue(buf.toString()); + + System.out.println(JSON.toJSONString(vo)); + } + + public static class VO { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial5.java b/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial5.java new file mode 100644 index 0000000000..15c54694ff --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial5.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class TestSpecial5 extends TestCase { + + public void test_1() throws Exception { + StringBuilder buf = new StringBuilder(); + buf.append(' '); + for (int i = 0; i < 1000; ++i) { + buf.append((char) 160); + } + + VO vo = new VO(); + vo.setValue(buf.toString()); + + System.out.println(JSON.toJSONString(vo)); + } + + public static class VO { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial_entity.java b/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial_entity.java new file mode 100644 index 0000000000..52d648eca0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial_entity.java @@ -0,0 +1,76 @@ +package com.alibaba.json.bvt.serializer; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class TestSpecial_entity extends TestCase { + + public void test_0() throws Exception { + Assert.assertEquals("{\"name\":\"\\u0000A\"}", JSON.toJSONString(new VO("\0A"))); + } + + public void test_1() throws Exception { + Assert.assertEquals("{\"name\":\"\\u0001\"}", JSON.toJSONString(new VO("\1"))); + } + + public void test_2() throws Exception { + Assert.assertEquals("{\"name\":\"\\u0002\"}", JSON.toJSONString(new VO("\2"))); + } + + public void test_3() throws Exception { + Assert.assertEquals("{\"name\":\"\\u0003\"}", JSON.toJSONString(new VO("\3"))); + } + + public void test_4() throws Exception { + Assert.assertEquals("{\"name\":\"\\u0004\"}", JSON.toJSONString(new VO("\4"))); + } + + public void test_5() throws Exception { + Assert.assertEquals("{\"name\":\"\\u0005\"}", JSON.toJSONString(new VO("\5"))); + } + + public void test_6() throws Exception { + Assert.assertEquals("{\"name\":\"\\u0006\"}", JSON.toJSONString(new VO("\6"))); + } + + public void test_7() throws Exception { + Assert.assertEquals("{\"name\":\"\\u0007\"}", JSON.toJSONString(new VO("\7"))); + } + + public void test_8() throws Exception { + Assert.assertEquals("{\"name\":\"\\b\"}", JSON.toJSONString(new VO("\b"))); + } + + public void test_9() throws Exception { + Assert.assertEquals("{\"name\":\"\\t\"}", JSON.toJSONString(new VO("\t"))); + } + + public void test_10() throws Exception { + Assert.assertEquals("{\"name\":\"\\n\"}", JSON.toJSONString(new VO("\n"))); + } + + public static class VO { + + private String name; + + public VO(){ + + } + + public VO(String name){ + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial_map.java b/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial_map.java new file mode 100644 index 0000000000..1866b1c37c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/TestSpecial_map.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.Collections; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +public class TestSpecial_map extends TestCase { + + public void test_0() throws Exception { + Assert.assertEquals("{\"name\":\"\\u0000\"}", JSON.toJSONString(Collections.singletonMap("name", "\0"))); + } + + public void test_1() throws Exception { + Assert.assertEquals("{\"name\":\"\\u0001\"}", JSON.toJSONString(Collections.singletonMap("name", "\1"))); + } + + public void test_2() throws Exception { + Assert.assertEquals("{\"name\":\"\\u0002\"}", JSON.toJSONString(Collections.singletonMap("name", "\2"))); + } + + public void test_3() throws Exception { + Assert.assertEquals("{\"name\":\"\\u0003\"}", JSON.toJSONString(Collections.singletonMap("name", "\3"))); + } + + public void test_4() throws Exception { + Assert.assertEquals("{\"name\":\"\\u0004\"}", JSON.toJSONString(Collections.singletonMap("name", "\4"))); + } + + public void test_5() throws Exception { + Assert.assertEquals("{\"name\":\"\\u0005\"}", JSON.toJSONString(Collections.singletonMap("name", "\5"))); + } + + public void test_6() throws Exception { + Assert.assertEquals("{\"name\":\"\\u0006\"}", JSON.toJSONString(Collections.singletonMap("name", "\6"))); + } + + public void test_7() throws Exception { + Assert.assertEquals("{\"name\":\"\\u0007\"}", JSON.toJSONString(Collections.singletonMap("name", "\7"))); + } + + public void test_8() throws Exception { + Assert.assertEquals("{\"name\":\"\\b\"}", JSON.toJSONString(Collections.singletonMap("name", "\b"))); + } + + public void test_9() throws Exception { + Assert.assertEquals("{\"name\":\"\\t\"}", JSON.toJSONString(Collections.singletonMap("name", "\t"))); + } + + public void test_10() throws Exception { + Assert.assertEquals("{\"name\":\"\\n\"}", JSON.toJSONString(Collections.singletonMap("name", "\n"))); + } + + +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/TimeZoneTest.java b/src/test/java/com/alibaba/json/bvt/serializer/TimeZoneTest.java old mode 100644 new mode 100755 similarity index 86% rename from src/test/java/com/alibaba/json/test/bvt/serializer/TimeZoneTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/TimeZoneTest.java index 25e4e5d2b5..f22503ed35 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/TimeZoneTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/TimeZoneTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.TimeZone; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/TransientTest.java b/src/test/java/com/alibaba/json/bvt/serializer/TransientTest.java old mode 100644 new mode 100755 similarity index 91% rename from src/test/java/com/alibaba/json/test/bvt/serializer/TransientTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/TransientTest.java index ea270a1f9d..fb1b379261 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/TransientTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/TransientTest.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.ArrayList; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/TreeSetTest.java b/src/test/java/com/alibaba/json/bvt/serializer/TreeSetTest.java new file mode 100755 index 0000000000..ce012358cd --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/TreeSetTest.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.Collection; +import java.util.TreeSet; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class TreeSetTest extends TestCase { + + public void test_null() throws Exception { + VO vo = new VO(); + vo.setValue(new TreeSet()); + + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.serializer.TreeSetTest$VO\",\"value\":TreeSet[]}", JSON.toJSONString(vo, SerializerFeature.WriteClassName)); + } + + public static class VO { + + private Collection value; + + public Collection getValue() { + return value; + } + + public void setValue(Collection value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/URITest.java b/src/test/java/com/alibaba/json/bvt/serializer/URITest.java old mode 100644 new mode 100755 similarity index 86% rename from src/test/java/com/alibaba/json/test/bvt/serializer/URITest.java rename to src/test/java/com/alibaba/json/bvt/serializer/URITest.java index 63dd661786..286658ecbe --- a/src/test/java/com/alibaba/json/test/bvt/serializer/URITest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/URITest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.net.URI; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/URLTest.java b/src/test/java/com/alibaba/json/bvt/serializer/URLTest.java old mode 100644 new mode 100755 similarity index 86% rename from src/test/java/com/alibaba/json/test/bvt/serializer/URLTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/URLTest.java index 1f501008ee..3b1166bc49 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/URLTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/URLTest.java @@ -1,9 +1,9 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.net.URI; import java.net.URL; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/UUIDTest.java b/src/test/java/com/alibaba/json/bvt/serializer/UUIDTest.java old mode 100644 new mode 100755 similarity index 86% rename from src/test/java/com/alibaba/json/test/bvt/serializer/UUIDTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/UUIDTest.java index 142cba3813..42c505fd98 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/UUIDTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/UUIDTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.UUID; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/UnicodeTest.java b/src/test/java/com/alibaba/json/bvt/serializer/UnicodeTest.java new file mode 100644 index 0000000000..4d7d6c3c96 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/UnicodeTest.java @@ -0,0 +1,14 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.Collections; + +import com.alibaba.fastjson.JSON; + +import junit.framework.TestCase; + +public class UnicodeTest extends TestCase { + public void test_unicode() throws Exception { + String text = JSON.toJSONString(Collections.singletonMap("v", "\u0018")); + System.out.println(text); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/ValueFilterTest.java b/src/test/java/com/alibaba/json/bvt/serializer/ValueFilterTest.java old mode 100644 new mode 100755 similarity index 85% rename from src/test/java/com/alibaba/json/test/bvt/serializer/ValueFilterTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/ValueFilterTest.java index 7929ba01fb..b61e91d2b1 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/ValueFilterTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/ValueFilterTest.java @@ -1,15 +1,17 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.HashMap; import java.util.Map; -import junit.framework.Assert; import junit.framework.TestCase; +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.JSONSerializer; import com.alibaba.fastjson.serializer.SerializeWriter; import com.alibaba.fastjson.serializer.ValueFilter; -import com.alibaba.json.test.bvt.serializer.PropertyFilterTest.A; +import com.alibaba.json.bvt.serializer.PropertyFilterTest.A; public class ValueFilterTest extends TestCase { @@ -36,6 +38,22 @@ public Object process(Object source, String name, Object value) { String text = out.toString(); Assert.assertEquals("{\"id\":\"AAA\"}", text); } + + public void test_toJSONString() throws Exception { + ValueFilter filter = new ValueFilter() { + + public Object process(Object source, String name, Object value) { + if (name.equals("id")) { + return "AAA"; + } + + return value; + } + + }; + + Assert.assertEquals("{\"id\":\"AAA\"}", JSON.toJSONString(new A(), filter)); + } public void test_valuefilter_1() throws Exception { ValueFilter filter = new ValueFilter() { diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/WriteClassNameTest.java b/src/test/java/com/alibaba/json/bvt/serializer/WriteClassNameTest.java old mode 100644 new mode 100755 similarity index 96% rename from src/test/java/com/alibaba/json/test/bvt/serializer/WriteClassNameTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/WriteClassNameTest.java index 69ab0d3a6f..a9d17bec32 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/WriteClassNameTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/WriteClassNameTest.java @@ -1,4 +1,4 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import junit.framework.TestCase; diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/WriteNullListAsEmptyTest.java b/src/test/java/com/alibaba/json/bvt/serializer/WriteNullListAsEmptyTest.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/serializer/WriteNullListAsEmptyTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/WriteNullListAsEmptyTest.java index 294c5222d6..2418bc3064 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/WriteNullListAsEmptyTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/WriteNullListAsEmptyTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.serializer; +package com.alibaba.json.bvt.serializer; import java.util.List; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/bvt/serializer/WriteSlashAsSpecialTest.java b/src/test/java/com/alibaba/json/bvt/serializer/WriteSlashAsSpecialTest.java new file mode 100644 index 0000000000..eb946b2997 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/WriteSlashAsSpecialTest.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.HashMap; +import java.util.Map; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +import org.junit.Assert; +import junit.framework.TestCase; + +public class WriteSlashAsSpecialTest extends TestCase { + public void test_0 () throws Exception { + Map map = new HashMap(); + map.put("value", "/"); + String result = JSON.toJSONString(map); + Assert.assertEquals("{\"value\":\"/\"}", result); + } + + public void test_1 () throws Exception { + Map map = new HashMap(); + map.put("value", "/"); + String result = JSON.toJSONString(map, SerializerFeature.WriteSlashAsSpecial); + Assert.assertEquals("{\"value\":\"\\/\"}", result); + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/exception/RuntimeExceptionTest.java b/src/test/java/com/alibaba/json/bvt/serializer/exception/RuntimeExceptionTest.java old mode 100644 new mode 100755 similarity index 88% rename from src/test/java/com/alibaba/json/test/bvt/serializer/exception/RuntimeExceptionTest.java rename to src/test/java/com/alibaba/json/bvt/serializer/exception/RuntimeExceptionTest.java index 5b069ed009..1a0ec81574 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/exception/RuntimeExceptionTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/exception/RuntimeExceptionTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.serializer.exception; +package com.alibaba.json.bvt.serializer.exception; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; @@ -12,7 +12,7 @@ public void test_0() throws Exception { RuntimeException ex = new RuntimeException(); JSONObject json = JSON.parseObject(JSON.toJSONString(ex)); - Assert.assertEquals(RuntimeException.class.getName(), json.get("class")); +// Assert.assertEquals(RuntimeException.class.getName(), json.get("@type")); String jsonString = JSON.toJSONString(ex); Exception ex1 = JSON.parseObject(jsonString, Exception.class); diff --git a/src/test/java/com/alibaba/json/bvt/serializer/jsonp/JSONPObjectTest.java b/src/test/java/com/alibaba/json/bvt/serializer/jsonp/JSONPObjectTest.java new file mode 100644 index 0000000000..03ad97a86b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/jsonp/JSONPObjectTest.java @@ -0,0 +1,23 @@ +package com.alibaba.json.bvt.serializer.jsonp; + +import java.util.ArrayList; +import java.util.HashMap; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSONPObject; + + +public class JSONPObjectTest extends TestCase { + public void test_jsonp() throws Exception { + JSONPObject jsonp = new JSONPObject("checkValid"); + jsonp.addParameter(new HashMap()); + jsonp.addParameter(new ArrayList()); + + String text = jsonp.toString(); + + Assert.assertEquals("checkValid({},[])", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/prettyFormat/ArrayListFieldTest.java b/src/test/java/com/alibaba/json/bvt/serializer/prettyFormat/ArrayListFieldTest.java new file mode 100755 index 0000000000..8df881a8f0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/prettyFormat/ArrayListFieldTest.java @@ -0,0 +1,66 @@ +package com.alibaba.json.bvt.serializer.prettyFormat; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class ArrayListFieldTest extends TestCase { + + public void test_prettyFormat() throws Exception { + VO vo = new VO(); + vo.getEntries().add(new Entity(123, "aaa")); + vo.getEntries().add(new Entity(234, "bbb")); + vo.getEntries().add(new Entity(3, "ccc")); + + + String text = JSON.toJSONString(vo, SerializerFeature.PrettyFormat, SerializerFeature.UseSingleQuotes); + System.out.println(text); + } + + public static class VO { + + private final List entries = new ArrayList(); + + public List getEntries() { + return entries; + } + + } + + public static class Entity { + + private int id; + private String name; + + public Entity(){ + + } + + public Entity(int id, String name){ + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/prettyFormat/ArrayListTest.java b/src/test/java/com/alibaba/json/bvt/serializer/prettyFormat/ArrayListTest.java new file mode 100755 index 0000000000..ece91cf05f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/prettyFormat/ArrayListTest.java @@ -0,0 +1,54 @@ +package com.alibaba.json.bvt.serializer.prettyFormat; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class ArrayListTest extends TestCase { + + public void test_array() throws Exception { + List list = new ArrayList(); + list.add(new Entity(123, "aaa")); + list.add(new Entity(234, "bbb")); + list.add(new Entity(3, "ccc")); + String text = JSON.toJSONString(list, SerializerFeature.PrettyFormat, SerializerFeature.UseSingleQuotes); + Assert.assertEquals("[\n\t{\n\t\t'id':123,\n\t\t'name':'aaa'\n\t},\n\t{\n\t\t'id':234,\n\t\t'name':'bbb'\n\t},\n\t{\n\t\t'id':3,\n\t\t'name':'ccc'\n\t}\n]", text); + } + + public static class Entity { + + private int id; + private String name; + + public Entity(){ + + } + + public Entity(int id, String name){ + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeArray.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeArray.java new file mode 100644 index 0000000000..fdbeceace6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeArray.java @@ -0,0 +1,33 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; + +public class StreamWriterTest_writeArray extends TestCase { + + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + Assert.assertEquals(10, writer.getBufferLength()); + + for (char ch = 'a'; ch <= 'z'; ++ch) { + char[] chars = new char[] { ch, ch, ch }; + writer.write(chars, 0, chars.length); + } + writer.close(); + + String text = out.toString(); + Assert.assertEquals(26 * 3, text.length()); + + for (int i = 0; i < 26; ++i) { + Assert.assertEquals(text.charAt(i * 3), (char) ('a' + i)); + Assert.assertEquals(text.charAt(i * 3 + 1), (char) ('a' + i)); + Assert.assertEquals(text.charAt(i * 3 + 2), (char) ('a' + i)); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeArray2.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeArray2.java new file mode 100644 index 0000000000..4aa3dfd9df --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeArray2.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; + +public class StreamWriterTest_writeArray2 extends TestCase { + + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + Assert.assertEquals(10, writer.getBufferLength()); + + int blockSize = 21; + for (char ch = 'a'; ch <= 'z'; ++ch) { + char[] chars = new char[blockSize]; + for (int i = 0; i < blockSize; ++i) { + chars[i] = ch; + } + writer.write(chars, 0, chars.length); + } + writer.close(); + + String text = out.toString(); + Assert.assertEquals(26 * blockSize, text.length()); + + for (int i = 0; i < 26; ++i) { + for (int j = 0; j < blockSize; ++j) { + Assert.assertEquals(text.charAt(i * blockSize + j), (char) ('a' + i)); + } + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeBytes.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeBytes.java new file mode 100644 index 0000000000..43231536c2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeBytes.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializeWriter; + + +public class StreamWriterTest_writeBytes extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + byte[] bytes = "民主".getBytes("GB2312"); + SerializeWriter writer = new SerializeWriter(out, 10); + Assert.assertEquals(10, writer.getBufferLength()); + + writer.writeByteArray(bytes); + writer.close(); + + String text = out.toString(); + byte[] result = JSON.parseObject(text, byte[].class); + Assert.assertEquals("民主", new String(result, "GB2312")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeBytes1.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeBytes1.java new file mode 100644 index 0000000000..34b2f70681 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeBytes1.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializeWriter; + + +public class StreamWriterTest_writeBytes1 extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + byte[] bytes = "民主共和君主宪".getBytes("GB2312"); + SerializeWriter writer = new SerializeWriter(out, 10); + Assert.assertEquals(10, writer.getBufferLength()); + + writer.writeByteArray(bytes); + writer.close(); + + String text = out.toString(); + byte[] result = JSON.parseObject(text, byte[].class); + Assert.assertEquals("民主共和君主宪", new String(result, "GB2312")); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeChar.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeChar.java new file mode 100644 index 0000000000..e6041903d7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeChar.java @@ -0,0 +1,30 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; + + +public class StreamWriterTest_writeChar extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + Assert.assertEquals(10, writer.getBufferLength()); + + for (char ch = 'a'; ch <= 'z'; ++ch) { + writer.write(ch); + } + writer.close(); + + String text = out.toString(); + Assert.assertEquals(26, text.length()); + + for (int i = 0; i < 26; ++i) { + Assert.assertEquals(text.charAt(i), (char)('a' + i)); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeChar1.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeChar1.java new file mode 100644 index 0000000000..fbeb275981 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeChar1.java @@ -0,0 +1,30 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; + + +public class StreamWriterTest_writeChar1 extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + Assert.assertEquals(10, writer.getBufferLength()); + + for (int ch = 'a'; ch <= 'z'; ++ch) { + writer.write(ch); + } + writer.close(); + + String text = out.toString(); + Assert.assertEquals(26, text.length()); + + for (int i = 0; i < 26; ++i) { + Assert.assertEquals(text.charAt(i), (char)('a' + i)); + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue.java new file mode 100644 index 0000000000..01b18f4469 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class StreamWriterTest_writeFieldValue extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + Assert.assertEquals(10, writer.getBufferLength()); + + writer.writeFieldValue(',', "abcde01245abcde", true); + writer.close(); + + String text = out.toString(); + Assert.assertEquals(",\"abcde01245abcde\":true", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue_int.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue_int.java new file mode 100644 index 0000000000..5eda133cd7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue_int.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class StreamWriterTest_writeFieldValue_int extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + writer.config(SerializerFeature.QuoteFieldNames, true); + Assert.assertEquals(10, writer.getBufferLength()); + + writer.writeFieldValue(',', "abcde01245abcde", 123); + writer.close(); + + String text = out.toString(); + Assert.assertEquals(",\"abcde01245abcde\":123", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue_int_1.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue_int_1.java new file mode 100644 index 0000000000..3468e72ddd --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue_int_1.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class StreamWriterTest_writeFieldValue_int_1 extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + Assert.assertEquals(10, writer.getBufferLength()); + + writer.writeFieldValue(',', "abcde01245abcde", 123); + writer.close(); + + String text = out.toString(); + Assert.assertEquals(",abcde01245abcde:123", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue_long.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue_long.java new file mode 100644 index 0000000000..3c6725c7b6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue_long.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class StreamWriterTest_writeFieldValue_long extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + writer.config(SerializerFeature.QuoteFieldNames, true); + Assert.assertEquals(10, writer.getBufferLength()); + + writer.writeFieldValue(',', "abcde01245abcde", 123L); + writer.close(); + + String text = out.toString(); + Assert.assertEquals(",\"abcde01245abcde\":123", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue_string.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue_string.java new file mode 100644 index 0000000000..659dcf1693 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue_string.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class StreamWriterTest_writeFieldValue_string extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + writer.config(SerializerFeature.QuoteFieldNames, true); + Assert.assertEquals(10, writer.getBufferLength()); + + writer.writeFieldValue(',', "abcde01245abcde", "123"); + writer.close(); + + String text = out.toString(); + Assert.assertEquals(",\"abcde01245abcde\":\"123\"", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue_string_singQuote.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue_string_singQuote.java new file mode 100644 index 0000000000..366d920790 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeFieldValue_string_singQuote.java @@ -0,0 +1,27 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class StreamWriterTest_writeFieldValue_string_singQuote extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + writer.config(SerializerFeature.QuoteFieldNames, true); + writer.config(SerializerFeature.UseSingleQuotes, true); + Assert.assertEquals(10, writer.getBufferLength()); + + writer.writeFieldValue(',', "abcde01245abcde", "123"); + writer.close(); + + String text = out.toString(); + Assert.assertEquals(",'abcde01245abcde':'123'", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeInt.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeInt.java new file mode 100644 index 0000000000..65396bfa51 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeInt.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; + + +public class StreamWriterTest_writeInt extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + Assert.assertEquals(10, writer.getBufferLength()); + + writer.write("abcde"); + writer.writeInt(12345678); + writer.close(); + + String text = out.toString(); + Assert.assertEquals("abcde12345678", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeIntAndChar.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeIntAndChar.java new file mode 100644 index 0000000000..c3267346ea --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeIntAndChar.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; + + +public class StreamWriterTest_writeIntAndChar extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + Assert.assertEquals(10, writer.getBufferLength()); + + writer.write("abcde"); + writer.writeIntAndChar(12345678, ','); + writer.close(); + + String text = out.toString(); + Assert.assertEquals("abcde12345678,", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeJSONStringTo.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeJSONStringTo.java new file mode 100644 index 0000000000..484dac114b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeJSONStringTo.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializeWriter; + + +public class StreamWriterTest_writeJSONStringTo extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + Map map = new LinkedHashMap(); + map.put("a", 123); + + JSON.writeJSONStringTo(map, out); + + String text = out.toString(); + Assert.assertEquals("{\"a\":123}", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeLong.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeLong.java new file mode 100644 index 0000000000..b1e48a66cf --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeLong.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; + + +public class StreamWriterTest_writeLong extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + Assert.assertEquals(10, writer.getBufferLength()); + + writer.write("abcde"); + writer.writeLong(12345678L); + writer.close(); + + String text = out.toString(); + Assert.assertEquals("abcde12345678", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeLongAndChar.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeLongAndChar.java new file mode 100644 index 0000000000..26a472cbbb --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeLongAndChar.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; + + +public class StreamWriterTest_writeLongAndChar extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + Assert.assertEquals(10, writer.getBufferLength()); + + writer.write("abcde"); + writer.writeLongAndChar(12345678L, ','); + writer.close(); + + String text = out.toString(); + Assert.assertEquals("abcde12345678,", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeString.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeString.java new file mode 100644 index 0000000000..bd8eab71b4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeString.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; + +public class StreamWriterTest_writeString extends TestCase { + + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + Assert.assertEquals(10, writer.getBufferLength()); + + int blockSize = 21; + for (char ch = 'a'; ch <= 'z'; ++ch) { + char[] chars = new char[blockSize]; + for (int i = 0; i < blockSize; ++i) { + chars[i] = ch; + } + writer.write(new String(chars), 0, chars.length); + } + writer.close(); + + String text = out.toString(); + Assert.assertEquals(26 * blockSize, text.length()); + + for (int i = 0; i < 26; ++i) { + for (int j = 0; j < blockSize; ++j) { + Assert.assertEquals(text.charAt(i * blockSize + j), (char) ('a' + i)); + } + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeString1.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeString1.java new file mode 100644 index 0000000000..09a7f6c214 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeString1.java @@ -0,0 +1,37 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; + +public class StreamWriterTest_writeString1 extends TestCase { + + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + Assert.assertEquals(10, writer.getBufferLength()); + + int blockSize = 21; + for (char ch = 'a'; ch <= 'z'; ++ch) { + char[] chars = new char[blockSize]; + for (int i = 0; i < blockSize; ++i) { + chars[i] = ch; + } + writer.write(new String(chars)); + } + writer.close(); + + String text = out.toString(); + Assert.assertEquals(26 * blockSize, text.length()); + + for (int i = 0; i < 26; ++i) { + for (int j = 0; j < blockSize; ++j) { + Assert.assertEquals(text.charAt(i * blockSize + j), (char) ('a' + i)); + } + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeValueString.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeValueString.java new file mode 100644 index 0000000000..c4cefbca99 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeValueString.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; + + +public class StreamWriterTest_writeValueString extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + Assert.assertEquals(10, writer.getBufferLength()); + + writer.writeString("abcde12345678"); + writer.close(); + + String text = out.toString(); + Assert.assertEquals("\"abcde12345678\"", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeValueString1.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeValueString1.java new file mode 100644 index 0000000000..d762840305 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeValueString1.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class StreamWriterTest_writeValueString1 extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + writer.config(SerializerFeature.BrowserCompatible, true); + Assert.assertEquals(10, writer.getBufferLength()); + + writer.writeString("abcde12345678\t"); + writer.close(); + + String text = out.toString(); + Assert.assertEquals("\"abcde12345678\\t\"", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeValueString2.java b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeValueString2.java new file mode 100644 index 0000000000..545fa9f43b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/stream/StreamWriterTest_writeValueString2.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvt.serializer.stream; + +import java.io.StringWriter; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + + +public class StreamWriterTest_writeValueString2 extends TestCase { + public void test_0() throws Exception { + StringWriter out = new StringWriter(); + + SerializeWriter writer = new SerializeWriter(out, 10); + Assert.assertEquals(10, writer.getBufferLength()); + + writer.writeString("abcde12345678\"\\"); + writer.close(); + + String text = out.toString(); + Assert.assertEquals("\"abcde12345678\\\"\\\\\"", text); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/stream/LargeTest.java b/src/test/java/com/alibaba/json/bvt/stream/LargeTest.java new file mode 100644 index 0000000000..00f686ddfd --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/stream/LargeTest.java @@ -0,0 +1,39 @@ +package com.alibaba.json.bvt.stream; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.commons.io.FileUtils; + +import com.alibaba.fastjson.JSONReader; +import com.alibaba.fastjson.JSONWriter; + +public class LargeTest extends TestCase { + + public void test_0() throws Exception { + List list = new ArrayList(1000 * 1); + for (int i = 0; i < 100 * 1; ++i) { + list.add(Integer.toString(i)); + } + File file = File.createTempFile("fastjson-stream-large", "json"); + JSONWriter writer = new JSONWriter(new FileWriter(file)); + writer.startArray(); + writer.writeObject(list); + writer.endArray(); + writer.close(); + + System.out.println(FileUtils.readFileToString(file)); + + JSONReader reader = new JSONReader(new FileReader(file)); + reader.startArray(); + reader.readObject(); + reader.endArray(); + reader.close(); + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/support/spring/FastJsonHttpMessageConverterTest.java b/src/test/java/com/alibaba/json/bvt/support/spring/FastJsonHttpMessageConverterTest.java new file mode 100644 index 0000000000..05a1b7da8e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/support/spring/FastJsonHttpMessageConverterTest.java @@ -0,0 +1,81 @@ +package com.alibaba.json.bvt.support.spring; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Method; +import java.nio.charset.Charset; + +import junit.framework.TestCase; + +import org.junit.Assert; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpInputMessage; +import org.springframework.http.HttpOutputMessage; +import org.springframework.http.MediaType; + +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; + +public class FastJsonHttpMessageConverterTest extends TestCase { + + public void test_read() throws Exception { + FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); + converter.setCharset(Charset.forName("UTF-8")); + converter.setFeatures(SerializerFeature.BrowserCompatible); + Assert.assertEquals(Charset.forName("UTF-8"), converter.getCharset()); + + Assert.assertEquals(1, converter.getFeatures().length); + + Method method = FastJsonHttpMessageConverter.class.getDeclaredMethod("supports", Class.class); + method.setAccessible(true); + method.invoke(converter, int.class); + + HttpInputMessage input = new HttpInputMessage() { + + public HttpHeaders getHeaders() { + // TODO Auto-generated method stub + return null; + } + + public InputStream getBody() throws IOException { + return new ByteArrayInputStream("{\"id\":123}".getBytes(Charset.forName("UTF-8"))); + } + + }; + VO vo = (VO) converter.read(VO.class, input); + Assert.assertEquals(123, vo.getId()); + + final ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + HttpOutputMessage out = new HttpOutputMessage() { + + public HttpHeaders getHeaders() { + return new HttpHeaders(); + } + + public OutputStream getBody() throws IOException { + return byteOut; + } + }; + converter.write(vo, MediaType.TEXT_PLAIN, out); + + byte[] bytes = byteOut.toByteArray(); + Assert.assertEquals("{\"id\":123}", new String(bytes, "UTF-8")); + } + + public static class VO { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/support/spring/FastJsonJsonViewTest.java b/src/test/java/com/alibaba/json/bvt/support/spring/FastJsonJsonViewTest.java new file mode 100644 index 0000000000..6c9f552247 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/support/spring/FastJsonJsonViewTest.java @@ -0,0 +1,58 @@ +package com.alibaba.json.bvt.support.spring; + +import java.nio.charset.Charset; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +import org.junit.Assert; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.support.spring.FastJsonJsonView; + +public class FastJsonJsonViewTest extends TestCase { + + @SuppressWarnings("deprecation") + public void test_0() throws Exception { + FastJsonJsonView view = new FastJsonJsonView(); + + Assert.assertEquals(Charset.forName("UTF-8"), view.getCharset()); + view.setCharset(Charset.forName("GBK")); + Assert.assertEquals(Charset.forName("GBK"), view.getCharset()); + + Assert.assertNotNull(view.getFeatures()); + Assert.assertEquals(0, view.getFeatures().length); + + view.setSerializerFeature(SerializerFeature.BrowserCompatible); + Assert.assertEquals(1, view.getFeatures().length); + Assert.assertEquals(SerializerFeature.BrowserCompatible, view.getFeatures()[0]); + + view.setFeatures(SerializerFeature.DisableCheckSpecialChar, SerializerFeature.SortField); + Assert.assertEquals(2, view.getFeatures().length); + Assert.assertEquals(SerializerFeature.DisableCheckSpecialChar, view.getFeatures()[0]); + Assert.assertEquals(SerializerFeature.SortField, view.getFeatures()[1]); + + Map model = new HashMap(); + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + view.render(model, request, response); + + view.setRenderedAttributes(null); + + view.setCharset(Charset.forName("UTF-8")); + view.render(model, request, response); + + view.setUpdateContentLength(true); + view.setFeatures(SerializerFeature.BrowserCompatible); + view.render(model, request, response); + + view.setCharset(Charset.forName("GBK")); + view.render(Collections.singletonMap("abc", "cde"), request, response); + + view.setDisableCaching(true); + } +} diff --git a/src/test/java/com/alibaba/json/bvt/util/FieldInfoTest.java b/src/test/java/com/alibaba/json/bvt/util/FieldInfoTest.java new file mode 100755 index 0000000000..2bc795357d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/util/FieldInfoTest.java @@ -0,0 +1,116 @@ +package com.alibaba.json.bvt.util; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.util.FieldInfo; +import com.alibaba.fastjson.util.ParameterizedTypeImpl; + +public class FieldInfoTest extends TestCase { + public void test_null() throws Exception { + FieldInfo fieldInfo = new FieldInfo("getValue", Entity.class.getMethod("getValue"), null); + Assert.assertEquals(null, fieldInfo.getAnnotation(JSONField.class)); + + Field field = GenericFieldEntity.class.getField("value"); + Type type = new ParameterizedTypeImpl(new Type[] { ValueObject.class }, null, GenericFieldEntity.class); + FieldInfo fieldInfoOfField = new FieldInfo("value", null, field, GenericFieldEntity.class, type); + Assert.assertEquals(fieldInfoOfField.getFieldType(), ValueObject.class); + Assert.assertEquals(fieldInfoOfField.getFieldClass(), ValueObject.class); + + field = GenericListFieldEntity.class.getField("value"); + type = new ParameterizedTypeImpl(new Type[] { ValueObject.class }, null, GenericListFieldEntity.class); + FieldInfo fieldInfoOfListField = new FieldInfo("value", null, field, GenericListFieldEntity.class, type); + ParameterizedTypeImpl actualFieldType = (ParameterizedTypeImpl) fieldInfoOfListField.getFieldType(); + Assert.assertEquals(actualFieldType.getActualTypeArguments()[0], ValueObject.class); + Assert.assertEquals(actualFieldType.getRawType(), List.class); + Assert.assertEquals(fieldInfoOfListField.getFieldClass(), List.class); + Assert.assertEquals(null, ((ParameterizedTypeImpl) type).getOwnerType()); + + Method method = GenericSetterEntity.class.getMethod("setValue", Object.class); + type = new ParameterizedTypeImpl(new Type[] { ValueObject.class }, null, GenericSetterEntity.class); + FieldInfo fieldInfoOfSetter = new FieldInfo("value", method, null, GenericSetterEntity.class, type); + Assert.assertEquals(fieldInfoOfSetter.getFieldType(), ValueObject.class); + Assert.assertEquals(fieldInfoOfSetter.getFieldClass(), ValueObject.class); + + fieldInfoOfSetter.toString(); + + method = GenericListSetterEntity.class.getMethod("setValue", List.class); + type = new ParameterizedTypeImpl(new Type[] { ValueObject.class }, null, GenericListSetterEntity.class); + FieldInfo fieldInfoOfListSetter = new FieldInfo("value", method, null, GenericListSetterEntity.class, type); + Assert.assertEquals(actualFieldType.getActualTypeArguments()[0], ValueObject.class); + Assert.assertEquals(actualFieldType.getRawType(), List.class); + Assert.assertEquals(fieldInfoOfListSetter.getFieldClass(), List.class); + } + + public static class Entity { + private int value; + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + } + + public static class GenericSetterEntity { + private T value; + + public T getValue() { + return value; + } + + public void setValue(T value) { + this.value = value; + } + } + + public static class GenericListSetterEntity { + private List value; + + public List getValue() { + return value; + } + + public void setValue(List value) { + this.value = value; + } + } + + public static class GenericFieldEntity { + public T value; + } + + public static class GenericListFieldEntity { + public List value; + } + + public static class ValueObject { + private String name; + private int id; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + } +} diff --git a/src/test/java/com/alibaba/json/test/bvt/util/JSONASMUtilTest.java b/src/test/java/com/alibaba/json/bvt/util/JSONASMUtilTest.java old mode 100644 new mode 100755 similarity index 93% rename from src/test/java/com/alibaba/json/test/bvt/util/JSONASMUtilTest.java rename to src/test/java/com/alibaba/json/bvt/util/JSONASMUtilTest.java index 7d64979b05..4346883f1e --- a/src/test/java/com/alibaba/json/test/bvt/util/JSONASMUtilTest.java +++ b/src/test/java/com/alibaba/json/bvt/util/JSONASMUtilTest.java @@ -1,8 +1,8 @@ -package com.alibaba.json.test.bvt.util; +package com.alibaba.json.bvt.util; import java.util.HashMap; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.util.ASMUtils; diff --git a/src/test/java/com/alibaba/json/test/bvt/util/ThreadLocalCacheTest.java b/src/test/java/com/alibaba/json/bvt/util/ThreadLocalCacheTest.java old mode 100644 new mode 100755 similarity index 95% rename from src/test/java/com/alibaba/json/test/bvt/util/ThreadLocalCacheTest.java rename to src/test/java/com/alibaba/json/bvt/util/ThreadLocalCacheTest.java index 4e06d6461f..fc390ec288 --- a/src/test/java/com/alibaba/json/test/bvt/util/ThreadLocalCacheTest.java +++ b/src/test/java/com/alibaba/json/bvt/util/ThreadLocalCacheTest.java @@ -1,6 +1,6 @@ -package com.alibaba.json.test.bvt.util; +package com.alibaba.json.bvt.util; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.util.ThreadLocalCache; diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_0_private.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_0_private.java new file mode 100644 index 0000000000..f4402e779d --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_0_private.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt.writeAsArray; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteAsArray_0_private extends TestCase { + public void test_0 () throws Exception { + VO vo = new VO(); + vo.setId(123); + vo.setName("wenshao"); + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + Assert.assertEquals("[123,\"wenshao\"]", text); + VO vo2 = JSON.parseObject(text, VO.class, Feature.SupportArrayToBean); + Assert.assertEquals(vo.getId(), vo2.getId()); + Assert.assertEquals(vo.getName(), vo2.getName()); + } + + private static class VO { + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_0_public.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_0_public.java new file mode 100644 index 0000000000..1736c6b427 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_0_public.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.writeAsArray; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteAsArray_0_public extends TestCase { + public void test_0 () throws Exception { + VO vo = new VO(); + vo.setId(123); + vo.setName("wenshao"); + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + Assert.assertEquals("[123,\"wenshao\"]", text); + } + + public static class VO { + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Eishay.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Eishay.java new file mode 100644 index 0000000000..465ccb7894 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Eishay.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvt.writeAsArray; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.json.test.benchmark.decode.EishayDecodeBytes; + +import data.media.MediaContent; + +public class WriteAsArray_Eishay extends TestCase { + public void test_0 () throws Exception { + MediaContent content = EishayDecodeBytes.instance.getContent(); + + String text = JSON.toJSONString(content, SerializerFeature.BeanToArray); + System.out.println(text.getBytes().length); + JSON.parseObject(text, MediaContent.class, Feature.SupportArrayToBean); + } + + public static class VO { + private short id; + private String name; + + public short getId() { + return id; + } + + public void setId(short id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Eishay_Image.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Eishay_Image.java new file mode 100644 index 0000000000..ee9dc33928 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Eishay_Image.java @@ -0,0 +1,32 @@ +package com.alibaba.json.bvt.writeAsArray; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; + +import data.media.Image; +import data.media.Image.Size; + +public class WriteAsArray_Eishay_Image extends TestCase { + public void test_0 () throws Exception { + Image image = new Image(); + image.setHeight(123); + image.setSize(Size.LARGE); + image.setTitle("xx"); + + String text = JSON.toJSONString(image, SerializerFeature.BeanToArray); + System.out.println(text); + + Image image2 = JSON.parseObject(text, Image.class, Feature.SupportArrayToBean); + Assert.assertEquals(image.getHeight(), image2.getHeight()); + Assert.assertEquals(image.getWidth(), image2.getWidth()); + Assert.assertEquals(image.getSize(), image2.getSize()); + Assert.assertEquals(image.getTitle(), image2.getTitle()); + Assert.assertEquals(image.getUri(), image2.getUri()); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Eishay_Media.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Eishay_Media.java new file mode 100644 index 0000000000..0c4410cc76 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Eishay_Media.java @@ -0,0 +1,35 @@ +package com.alibaba.json.bvt.writeAsArray; + +import java.util.Arrays; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; + +import data.media.Media; +import data.media.Media.Player; + +public class WriteAsArray_Eishay_Media extends TestCase { + public void test_0 () throws Exception { + Media media = new Media(); + media.setHeight(123); + media.setPlayer(Player.FLASH); + media.setTitle("xx"); + media.setPersons(Arrays.asList("a",null)); + + String text = JSON.toJSONString(media, SerializerFeature.BeanToArray); + System.out.println(text); + + Media media2 = JSON.parseObject(text, Media.class, Feature.SupportArrayToBean); + Assert.assertEquals(media.getHeight(), media2.getHeight()); + Assert.assertEquals(media.getWidth(), media2.getWidth()); + Assert.assertEquals(media.getSize(), media2.getSize()); + Assert.assertEquals(media.getTitle(), media2.getTitle()); + Assert.assertEquals(media.getUri(), media2.getUri()); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Object.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Object.java new file mode 100644 index 0000000000..62066476d9 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Object.java @@ -0,0 +1,66 @@ +package com.alibaba.json.bvt.writeAsArray; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.json.bvt.writeAsArray.WriteAsArray_enum_public.VO; + +public class WriteAsArray_Object extends TestCase { + + public void test_0() throws Exception { + A a = new A(); + a.setId(123); + a.setName("wenshao"); + + VO vo = new VO(); + vo.setA(a); + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + Assert.assertEquals("[[123,\"wenshao\"]]", text); + + VO vo2 = JSON.parseObject(text, VO.class, Feature.SupportArrayToBean); + Assert.assertEquals(vo.getA().getId(), vo2.getA().getId()); + Assert.assertEquals(vo.getA().getName(), vo2.getA().getName()); + } + + private static class VO { + + private A a; + + public A getA() { + return a; + } + + public void setA(A a) { + this.a = a; + } + + } + + private static class A { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Object_2_public.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Object_2_public.java new file mode 100644 index 0000000000..8205be29f3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Object_2_public.java @@ -0,0 +1,76 @@ +package com.alibaba.json.bvt.writeAsArray; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.json.bvt.writeAsArray.WriteAsArray_enum_public.VO; + +public class WriteAsArray_Object_2_public extends TestCase { + + public void test_0() throws Exception { + A a = new A(); + a.setId(123); + a.setName("wenshao"); + + VO vo = new VO(); + vo.setId(1001); + vo.setValue(a); + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + Assert.assertEquals("[1001,[123,\"wenshao\"]]", text); + + VO vo2 = JSON.parseObject(text, VO.class, Feature.SupportArrayToBean); + Assert.assertEquals(vo.getValue().getId(), vo2.getValue().getId()); + Assert.assertEquals(vo.getValue().getName(), vo2.getValue().getName()); + } + + public static class VO { + + private int id; + private A value; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public A getValue() { + return value; + } + + public void setValue(A value) { + this.value = value; + } + + } + + public static class A { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Object_public.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Object_public.java new file mode 100644 index 0000000000..8953ba7bf5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_Object_public.java @@ -0,0 +1,66 @@ +package com.alibaba.json.bvt.writeAsArray; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.json.bvt.writeAsArray.WriteAsArray_enum_public.VO; + +public class WriteAsArray_Object_public extends TestCase { + + public void test_0() throws Exception { + A a = new A(); + a.setId(123); + a.setName("wenshao"); + + VO vo = new VO(); + vo.setA(a); + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + Assert.assertEquals("[[123,\"wenshao\"]]", text); + + VO vo2 = JSON.parseObject(text, VO.class, Feature.SupportArrayToBean); + Assert.assertEquals(vo.getA().getId(), vo2.getA().getId()); + Assert.assertEquals(vo.getA().getName(), vo2.getA().getName()); + } + + public static class VO { + + private A a; + + public A getA() { + return a; + } + + public void setA(A a) { + this.a = a; + } + + } + + public static class A { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_boolean_public.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_boolean_public.java new file mode 100644 index 0000000000..c8acd89b91 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_boolean_public.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.writeAsArray; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteAsArray_boolean_public extends TestCase { + public void test_0 () throws Exception { + VO vo = new VO(); + vo.setId(true); + vo.setName("wenshao"); + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + Assert.assertEquals("[true,\"wenshao\"]", text); + } + + public static class VO { + private boolean id; + private String name; + + public boolean getId() { + return id; + } + + public void setId(boolean id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_byte_public.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_byte_public.java new file mode 100644 index 0000000000..1351f93c9b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_byte_public.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.writeAsArray; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteAsArray_byte_public extends TestCase { + public void test_0 () throws Exception { + VO vo = new VO(); + vo.setId((byte)123); + vo.setName("wenshao"); + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + Assert.assertEquals("[123,\"wenshao\"]", text); + } + + public static class VO { + private byte id; + private String name; + + public byte getId() { + return id; + } + + public void setId(byte id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_char_public.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_char_public.java new file mode 100644 index 0000000000..eea34966fe --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_char_public.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.writeAsArray; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteAsArray_char_public extends TestCase { + public void test_0 () throws Exception { + VO vo = new VO(); + vo.setId('x'); + vo.setName("wenshao"); + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + Assert.assertEquals("[\"x\",\"wenshao\"]", text); + } + + public static class VO { + private char id; + private String name; + + public char getId() { + return id; + } + + public void setId(char id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_double_public.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_double_public.java new file mode 100644 index 0000000000..231302e5f6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_double_public.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.writeAsArray; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteAsArray_double_public extends TestCase { + public void test_0 () throws Exception { + VO vo = new VO(); + vo.setId(123D); + vo.setName("wenshao"); + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + Assert.assertEquals("[123,\"wenshao\"]", text); + } + + public static class VO { + private double id; + private String name; + + public double getId() { + return id; + } + + public void setId(double id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_enum_public.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_enum_public.java new file mode 100644 index 0000000000..42fdb555bc --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_enum_public.java @@ -0,0 +1,50 @@ +package com.alibaba.json.bvt.writeAsArray; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteAsArray_enum_public extends TestCase { + + public void test_0() throws Exception { + VO vo = new VO(); + vo.setId(Type.AA); + vo.setName("wenshao"); + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + Assert.assertEquals("[\"AA\",\"wenshao\"]", text); + VO vo2 = JSON.parseObject(text, VO.class, Feature.SupportArrayToBean); + Assert.assertEquals(vo.getId(), vo2.getId()); + Assert.assertEquals(vo.getName(), vo2.getName()); + } + + public static class VO { + + private Type id; + private String name; + + public Type getId() { + return id; + } + + public void setId(Type id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + public static enum Type { + A, B, C, D, AA, BB, CC + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_float_public.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_float_public.java new file mode 100644 index 0000000000..e6fdd8adc0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_float_public.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.writeAsArray; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteAsArray_float_public extends TestCase { + public void test_0 () throws Exception { + VO vo = new VO(); + vo.setId(123F); + vo.setName("wenshao"); + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + Assert.assertEquals("[123,\"wenshao\"]", text); + } + + public static class VO { + private float id; + private String name; + + public float getId() { + return id; + } + + public void setId(float id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_jsonType.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_jsonType.java new file mode 100644 index 0000000000..17b888fe66 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_jsonType.java @@ -0,0 +1,67 @@ +package com.alibaba.json.bvt.writeAsArray; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteAsArray_jsonType extends TestCase { + + public void test_0() throws Exception { + VO vo = new VO(); + vo.setId(123); + vo.setName("wenshao"); + + Parent parent = new Parent(); + parent.setVo(vo); + + String text = JSON.toJSONString(parent); + Assert.assertEquals("{\"vo\":[123,\"wenshao\"]}", text); + VO vo2 = JSON.parseObject(text, Parent.class).getVo(); + Assert.assertEquals(vo.getId(), vo2.getId()); + Assert.assertEquals(vo.getName(), vo2.getName()); + } + + public static class Parent { + private VO vo; + + public VO getVo() { + return vo; + } + + public void setVo(VO vo) { + this.vo = vo; + } + + } + + @JSONType(serialzeFeatures=SerializerFeature.BeanToArray, parseFeatures=Feature.SupportArrayToBean) + public static class VO { + @JSONField(ordinal=1) + private int id; + + @JSONField(ordinal=2) + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_list_obj_first_public.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_list_obj_first_public.java new file mode 100644 index 0000000000..d2652961be --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_list_obj_first_public.java @@ -0,0 +1,78 @@ +package com.alibaba.json.bvt.writeAsArray; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteAsArray_list_obj_first_public extends TestCase { + + public void test_0() throws Exception { + VO vo = new VO(); + vo.setId(123); + vo.setName("wenshao"); + vo.getFvalues().add(new A()); + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + Assert.assertEquals("[[[0]],123,\"wenshao\"]", text); + + VO vo2 = JSON.parseObject(text, VO.class, Feature.SupportArrayToBean); + Assert.assertEquals(vo.getId(), vo2.getId()); + Assert.assertEquals(vo.getName(), vo2.getName()); + Assert.assertEquals(vo.getFvalues().size(), vo2.getFvalues().size()); + Assert.assertEquals(vo.getFvalues().get(0).getClass(), vo2.getFvalues().get(0).getClass()); + Assert.assertEquals(vo.getFvalues().get(0).getValue(), vo2.getFvalues().get(0).getValue()); + } + + public static class VO { + + private long id; + private String name; + private List fvalues = new ArrayList(); + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getFvalues() { + return fvalues; + } + + public void setFvalues(List fvalues) { + this.fvalues = fvalues; + } + + } + + public static class A { + + private int value; + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_list_obj_public.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_list_obj_public.java new file mode 100644 index 0000000000..ad7a9d42a3 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_list_obj_public.java @@ -0,0 +1,80 @@ +package com.alibaba.json.bvt.writeAsArray; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteAsArray_list_obj_public extends TestCase { + + public void test_0() throws Exception { + VO vo = new VO(); + vo.setId(123); + vo.setName("wenshao"); + vo.getValues().add(new A()); + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + Assert.assertEquals("[123,\"wenshao\",[[0]]]", text); + + VO vo2 = JSON.parseObject(text, VO.class, Feature.SupportArrayToBean); + Assert.assertEquals(vo.getId(), vo2.getId()); + Assert.assertEquals(vo.getName(), vo2.getName()); + Assert.assertEquals(vo.getValues().size(), vo2.getValues().size()); + Assert.assertEquals(vo.getValues().get(0).getClass(), vo2.getValues().get(0).getClass()); + Assert.assertEquals(vo.getValues().get(0).getValue(), vo2.getValues().get(0).getValue()); + } + + public static class VO { + + private long id; + private String name; + private List values = new ArrayList(); + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } + + } + + public static class A { + private int value; + + + public int getValue() { + return value; + } + + + public void setValue(int value) { + this.value = value; + } + + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_list_public.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_list_public.java new file mode 100644 index 0000000000..9f4483c2f4 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_list_public.java @@ -0,0 +1,63 @@ +package com.alibaba.json.bvt.writeAsArray; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteAsArray_list_public extends TestCase { + + public void test_0() throws Exception { + VO vo = new VO(); + vo.setId(123); + vo.setName("wenshao"); + vo.getValues().add("x"); + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + Assert.assertEquals("[123,\"wenshao\",[\"x\"]]", text); + + VO vo2 = JSON.parseObject(text, VO.class, Feature.SupportArrayToBean); + Assert.assertEquals(vo.getId(), vo2.getId()); + Assert.assertEquals(vo.getName(), vo2.getName()); + Assert.assertEquals(vo.getValues().size(), vo2.getValues().size()); + Assert.assertEquals(vo.getValues().get(0), vo2.getValues().get(0)); + } + + public static class VO { + + private long id; + private String name; + private List values = new ArrayList(); + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_long_private.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_long_private.java new file mode 100644 index 0000000000..8d06406207 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_long_private.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.writeAsArray; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteAsArray_long_private extends TestCase { + public void test_0 () throws Exception { + VO vo = new VO(); + vo.setId(123); + vo.setName("wenshao"); + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + Assert.assertEquals("[123,\"wenshao\"]", text); + } + + private static class VO { + private long id; + private String name; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_long_public.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_long_public.java new file mode 100644 index 0000000000..75f04f2a33 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_long_public.java @@ -0,0 +1,44 @@ +package com.alibaba.json.bvt.writeAsArray; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteAsArray_long_public extends TestCase { + public void test_0 () throws Exception { + VO vo = new VO(); + vo.setId(123); + vo.setName("wenshao"); + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + Assert.assertEquals("[123,\"wenshao\"]", text); + VO vo2 = JSON.parseObject(text, VO.class, Feature.SupportArrayToBean); + Assert.assertEquals(vo.getId(), vo2.getId()); + Assert.assertEquals(vo.getName(), vo2.getName()); + } + + public static class VO { + private long id; + private String name; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_short_public.java b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_short_public.java new file mode 100644 index 0000000000..5ac2dbfd5e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeAsArray/WriteAsArray_short_public.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.writeAsArray; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteAsArray_short_public extends TestCase { + public void test_0 () throws Exception { + VO vo = new VO(); + vo.setId((short)123); + vo.setName("wenshao"); + + String text = JSON.toJSONString(vo, SerializerFeature.BeanToArray); + Assert.assertEquals("[123,\"wenshao\"]", text); + } + + public static class VO { + private short id; + private String name; + + public short getId() { + return id; + } + + public void setId(short id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/MapTest.java b/src/test/java/com/alibaba/json/bvt/writeClassName/MapTest.java new file mode 100755 index 0000000000..de2d10bea7 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeClassName/MapTest.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt.writeClassName; + +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class MapTest extends TestCase { + + public void test_map() throws Exception { + VO vo = new VO(); + vo.getValue().put("1", "AA"); + + String text = JSON.toJSONString(vo, SerializerFeature.WriteClassName); + + System.out.println(text); + + VO vo2 = (VO) JSON.parse(text); + + Assert.assertEquals(vo.getValue(), vo2.getValue()); + } + + public void test_map_2() throws Exception { + VO vo = new VO(); + vo.setValue(new TreeMap()); + vo.getValue().put("1", "AA"); + + String text = JSON.toJSONString(vo, SerializerFeature.WriteClassName); + + System.out.println(text); + + VO vo2 = (VO) JSON.parse(text); + + Assert.assertEquals(vo.getValue(), vo2.getValue()); + } + + private static class VO { + + private Map value = new HashMap(); + + public Map getValue() { + return value; + } + + public void setValue(Map value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest.java new file mode 100755 index 0000000000..65b7dffe7f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest.java @@ -0,0 +1,40 @@ +package com.alibaba.json.bvt.writeClassName; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteClassNameTest extends TestCase { + + public void test_list() throws Exception { + A a = new A(); + a.setB(new B()); + String text = JSON.toJSONString(a, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest$A\",\"b\":{}}", text); + + A a1 = (A) JSON.parse(text); + + Assert.assertNotNull(a1.getB()); + } + + private static class A { + + private B b; + + public B getB() { + return b; + } + + public void setB(B b) { + this.b = b; + } + + } + + private static final class B { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest2.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest2.java new file mode 100755 index 0000000000..21fe54757f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest2.java @@ -0,0 +1,51 @@ +package com.alibaba.json.bvt.writeClassName; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteClassNameTest2 extends TestCase { + + public void test_writeClassName() throws Exception { + A a = new A(); + a.setB(new B()); + String text = JSON.toJSONString(a, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest2$A\",\"b\":{\"id\":0}}", + text); + + A a1 = (A) JSON.parse(text); + + Assert.assertNotNull(a1.getB()); + } + + public static class A { + + private B b; + + public B getB() { + return b; + } + + public void setB(B b) { + this.b = b; + } + + } + + public static final class B { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Collection.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Collection.java new file mode 100755 index 0000000000..b67c81b2ef --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Collection.java @@ -0,0 +1,45 @@ +package com.alibaba.json.bvt.writeClassName; + +import java.util.Collection; +import java.util.Collections; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteClassNameTest_Collection extends TestCase { + + public void test_list() throws Exception { + A a = new A(); + a.setList(Collections.singletonList(new B())); + String text = JSON.toJSONString(a, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Collection$A\",\"list\":[{}]}", + text); + + A a1 = (A) JSON.parse(text); + + Assert.assertEquals(1, a1.getList().size()); + Assert.assertTrue(a1.getList().iterator().next() instanceof B); + } + + private static class A { + + private Collection list; + + public Collection getList() { + return list; + } + + public void setList(Collection list) { + this.list = list; + } + + } + + private static final class B { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Collection2.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Collection2.java new file mode 100755 index 0000000000..a8f591f17b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Collection2.java @@ -0,0 +1,45 @@ +package com.alibaba.json.bvt.writeClassName; + +import java.util.Collection; +import java.util.Collections; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteClassNameTest_Collection2 extends TestCase { + + public void test_list() throws Exception { + A a = new A(); + a.setList(Collections.singletonList(new B())); + String text = JSON.toJSONString(a, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Collection2$A\",\"list\":[{}]}", + text); + + A a1 = (A) JSON.parse(text); + + Assert.assertEquals(1, a1.getList().size()); + Assert.assertTrue(a1.getList().iterator().next() instanceof B); + } + + public static class A { + + private Collection list; + + public Collection getList() { + return list; + } + + public void setList(Collection list) { + this.list = list; + } + + } + + public static final class B { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_List.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_List.java new file mode 100755 index 0000000000..97004b3859 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_List.java @@ -0,0 +1,45 @@ +package com.alibaba.json.bvt.writeClassName; + +import java.util.Collections; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteClassNameTest_List extends TestCase { + + public void test_list() throws Exception { + A a = new A(); + a.setList(Collections.singletonList(new B())); + String text = JSON.toJSONString(a, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_List$A\",\"list\":[{}]}", + text); + + A a1 = (A) JSON.parse(text); + + Assert.assertEquals(1, a1.getList().size()); + Assert.assertTrue(a1.getList().get(0) instanceof B); + } + + private static class A { + + private List list; + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + + } + + private static final class B { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_List2.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_List2.java new file mode 100755 index 0000000000..d6e18dd49e --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_List2.java @@ -0,0 +1,55 @@ +package com.alibaba.json.bvt.writeClassName; + +import java.util.Collections; +import java.util.List; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteClassNameTest_List2 extends TestCase { + + public void test_list() throws Exception { + A a = new A(); + a.setList(Collections.singletonList(new B())); + String text = JSON.toJSONString(a, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_List2$A\",\"list\":[{\"id\":0}]}", + text); + + A a1 = (A) JSON.parse(text); + + Assert.assertEquals(1, a1.getList().size()); + Assert.assertTrue(a1.getList().get(0) instanceof B); + } + + public static class A { + + private List list; + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + + } + + public static final class B { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set.java new file mode 100755 index 0000000000..adb5c4c30b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set.java @@ -0,0 +1,52 @@ +package com.alibaba.json.bvt.writeClassName; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteClassNameTest_Set extends TestCase { + + public void test_list() throws Exception { + A a = new A(); + Set set = new LinkedHashSet(); + set.add(new B()); + set.add(new B1()); + a.setList(set); + String text = JSON.toJSONString(a, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set$A\",\"list\":[{},{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set$B1\"}]}", + text); + + A a1 = (A) JSON.parse(text); + + Assert.assertEquals(2, a1.getList().size()); + } + + public static class A { + + private Set list; + + public Set getList() { + return list; + } + + public void setList(Set list) { + this.list = list; + } + + } + + public static class B { + + } + + public static class B1 extends B { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set2.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set2.java new file mode 100755 index 0000000000..5ed5852f08 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set2.java @@ -0,0 +1,54 @@ +package com.alibaba.json.bvt.writeClassName; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteClassNameTest_Set2 extends TestCase { + + public void test_list() throws Exception { + A a = new A(); + Set set = new LinkedHashSet(); + set.add(new B()); + set.add(new B1()); + a.setList(set); + String text = JSON.toJSONString(a, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set2$A\",\"list\":[{},{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set2$B1\"}]}", + text); + + A a1 = (A) JSON.parse(text); + + Assert.assertEquals(2, a1.getList().size()); + Assert.assertTrue("B", new ArrayList(a1.getList()).get(0) instanceof B || new ArrayList(a1.getList()).get(0) instanceof B1); + Assert.assertTrue("B1", new ArrayList(a1.getList()).get(1) instanceof B || new ArrayList(a1.getList()).get(1) instanceof B1); + } + + private static class A { + + private Set list; + + public Set getList() { + return list; + } + + public void setList(Set list) { + this.list = list; + } + + } + + private static class B { + + } + + private static class B1 extends B { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set3.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set3.java new file mode 100755 index 0000000000..8fb03636ea --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set3.java @@ -0,0 +1,54 @@ +package com.alibaba.json.bvt.writeClassName; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteClassNameTest_Set3 extends TestCase { + + public void test_list() throws Exception { + A a = new A(); + LinkedHashSet set = new LinkedHashSet(); + set.add(new B()); + set.add(new B1()); + a.setList(set); + String text = JSON.toJSONString(a, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set3$A\",\"list\":[{},{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set3$B1\"}]}", + text); + + A a1 = (A) JSON.parse(text); + + Assert.assertEquals(2, a1.getList().size()); + Assert.assertTrue(new ArrayList(a1.getList()).get(0) instanceof B); + Assert.assertTrue(new ArrayList(a1.getList()).get(1) instanceof B1); + } + + private static class A { + + private LinkedHashSet list; + + public LinkedHashSet getList() { + return list; + } + + public void setList(LinkedHashSet list) { + this.list = list; + } + + } + + private static class B { + + } + + private static class B1 extends B { + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set4.java b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set4.java new file mode 100755 index 0000000000..f5e5d2d061 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/writeClassName/WriteClassNameTest_Set4.java @@ -0,0 +1,54 @@ +package com.alibaba.json.bvt.writeClassName; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.junit.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class WriteClassNameTest_Set4 extends TestCase { + + public void test_list() throws Exception { + A a = new A(); + LinkedHashSet set = new LinkedHashSet(); + set.add(new B()); + set.add(new B1()); + a.setList(set); + String text = JSON.toJSONString(a, SerializerFeature.WriteClassName); + System.out.println(text); + Assert.assertEquals("{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set4$A\",\"list\":[{},{\"@type\":\"com.alibaba.json.bvt.writeClassName.WriteClassNameTest_Set4$B1\"}]}", + text); + + A a1 = (A) JSON.parse(text); + + Assert.assertEquals(2, a1.getList().size()); + Assert.assertTrue(new ArrayList(a1.getList()).get(0) instanceof B); + Assert.assertTrue(new ArrayList(a1.getList()).get(1) instanceof B1); + } + + public static class A { + + private LinkedHashSet list; + + public LinkedHashSet getList() { + return list; + } + + public void setList(LinkedHashSet list) { + this.list = list; + } + + } + + public static class B { + + } + + public static class B1 extends B { + + } +} diff --git a/src/test/java/com/alibaba/json/bvtVO/AccessHttpConfigModel.java b/src/test/java/com/alibaba/json/bvtVO/AccessHttpConfigModel.java new file mode 100644 index 0000000000..d9ac6e326c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/AccessHttpConfigModel.java @@ -0,0 +1,195 @@ +package com.alibaba.json.bvtVO; + +import java.io.Serializable; + + +public class AccessHttpConfigModel { + /** + * 上传文件的配置. + * + * @author wangwb (mailto:wangwb@primeton.com) + */ + + public static class FileUploadConfig implements Serializable{ + private String tempDir; + + private int maxSize; + + private int inMemorySize; + + private String exclude; + + /** + * 获取不允许上传的文件类型.
+ * 多个文件类型之间用','分割. + * @return 获取不允许上传的文件类型. + */ + public String getExclude() { + return exclude; + } + + /** + * 设置不允许上传的文件类型.
+ * 多个文件类型之间用','分割. + * + * @param exclude 不允许上传的文件类型. + */ + public void setExclude(String exclude) { + this.exclude = exclude; + } + + /** + * 获取上传文件时在内存中最大的字节数. + * + * @return 上传文件时在内存中最大的字节数. + */ + public int getInMemorySize() { + return inMemorySize; + } + + /** + * 设置上传文件时在内存中最大的字节数. + * + * @param inMemorySize + * 上传文件时在内存中最大的字节数. + */ + public void setInMemorySize(int inMemorySize) { + this.inMemorySize = inMemorySize; + } + + /** + * 获取上传文件的最大字节数. + * + * @return 上传文件的最大字节数. + */ + public int getMaxSize() { + return maxSize; + } + + /** + * 设置上传文件的最大字节数. + * + * @param maxSize + * 上传文件的最大字节数. + */ + public void setMaxSize(int maxSize) { + this.maxSize = maxSize; + } + + /** + * 获取上传文件的保存的临时目录. + * + * @return 上传文件的保存的临时目录. + */ + public String getTempDir() { + return tempDir; + } + + /** + * 设置上传文件的保存的临时目录. + * + * @param tempDir + * 上传文件的保存的临时目录. + */ + public void setTempDir(String tempDir) { + this.tempDir = tempDir; + } + } + + private String encoding; + + private FileUploadConfig fileUploadConfig; + + /** + * 获取HttpServletRequest请求的字符集设置 + * + * @return HttpServletRequest请求的字符集设置 + */ + public String getEncoding() { + return encoding; + } + + /** + * 设置HttpServletRequest请求的字符集设置 + * + * @param encoding HttpServletRequest请求的字符集设置 + */ + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + /** + * 获取上传文件的配置. + * @return 上传文件的配置. + */ + public FileUploadConfig getFileUploadConfig() { + return fileUploadConfig; + } + + /** + * 设置上传文件的配置. + * @param fileUploadConfig 上传文件的配置. + */ + public void setFileUploadConfig(FileUploadConfig fileUploadConfig) { + this.fileUploadConfig = fileUploadConfig; + } + + private int suspend=10; + + /** + * 获取请求的挂起的等待时间.
+ * @return 获取请求的挂起的等待时间. + */ + public int getSuspend() { + return suspend; + } + + /** + * 设置请求挂起的等待时间.
+ * @param suspend 请求挂起的等待时间. + */ + public void setSuspend(int suspend) { + this.suspend = suspend; + } + + private String loginExcludeUrls; + + private String loginErrorPage; + + private boolean portal; + + private String loginIncludeUrls; + + public String getLoginErrorPage() { + return loginErrorPage; + } + + public void setLoginErrorPage(String loginErrorPage) { + this.loginErrorPage = loginErrorPage; + } + + public String getLoginExcludeUrls() { + return loginExcludeUrls; + } + + public void setLoginExcludeUrls(String loginExcludeUrls) { + this.loginExcludeUrls = loginExcludeUrls; + } + + public boolean isPortal() { + return portal; + } + + public void setPortal(boolean portal) { + this.portal = portal; + } + + public String getLoginIncludeUrls() { + return loginIncludeUrls; + } + + public void setLoginIncludeUrls(String loginIncludeUrls) { + this.loginIncludeUrls = loginIncludeUrls; + } + +} diff --git a/src/test/java/com/alibaba/json/bvtVO/ArgCheckTest.java b/src/test/java/com/alibaba/json/bvtVO/ArgCheckTest.java new file mode 100755 index 0000000000..f6172d0a9f --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/ArgCheckTest.java @@ -0,0 +1,41 @@ +package com.alibaba.json.bvtVO; + +import org.junit.Test; + +import com.alibaba.fastjson.JSON; + +public class ArgCheckTest { + + @Test + public void testJSON() { + TestDTO dto = new TestDTO(); + dto.setChannel("channel"); + TestDTO[] dtos = new TestDTO[2]; + dtos[0] = dto; + dtos[1] = dto; + JSON.toJSONString(dtos); + } + + public static class TestDTO { + + private String channel; + private String txCode; + + + public String getChannel() { + return channel; + } + + public void setChannel(String channel) { + this.channel = channel; + } + + public String getTxCode() { + return txCode; + } + + public void setTxCode(String txCode) { + this.txCode = txCode; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvtVO/Bean.java b/src/test/java/com/alibaba/json/bvtVO/Bean.java new file mode 100755 index 0000000000..999ce0cf4b --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/Bean.java @@ -0,0 +1,32 @@ +package com.alibaba.json.bvtVO; + +public class Bean { + private Integer id; + private String name; + private String desc; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + +} diff --git a/src/test/java/com/alibaba/json/bvtVO/DataTransaction.java b/src/test/java/com/alibaba/json/bvtVO/DataTransaction.java new file mode 100755 index 0000000000..f017934e49 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/DataTransaction.java @@ -0,0 +1,321 @@ +package com.alibaba.json.bvtVO; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.alibaba.fastjson.JSON; + +/** + * 交易消息体 + */ +@SuppressWarnings("rawtypes") +public class DataTransaction implements Serializable { + + private static final long serialVersionUID = 1L; + + private Head head = new Head(); + + private Body body = new Body(); + + public DataTransaction(){ + + } + + /** + * Head + **/ + public static class Head { + + private String appid; + + private String transcode; + + private String seqno; + + private User user = new User(); + + private Ret ret = new Ret(); + + /** + * 用户信息 + */ + public static class User { + + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + } + + /** + * 处理结果 + */ + public static class Ret { + + private String code; + private String msg; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + } + + public String getAppid() { + return appid; + } + + public void setAppid(String appid) { + this.appid = appid; + } + + public String getTranscode() { + return transcode; + } + + public void setTranscode(String transcode) { + this.transcode = transcode; + } + + public String getSeqno() { + return seqno; + } + + public void setSeqno(String seqno) { + this.seqno = seqno; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public Ret getRet() { + return ret; + } + + public void setRet(Ret ret) { + this.ret = ret; + } + + public void setRetCode(String code) { + this.ret.code = code; + } + + public void setRetMsg(String msg) { + this.ret.msg = msg; + } + } + + /** + * Body + */ + public static class Body { + + private Param param = new Param(); + + private DataSet dataset; + + public Body(){ + + } + + /** + * 参数 + */ + public static class Param { + + private Limit limit = new Limit(); + + private Map form = new HashMap(); + + /** + * 分页信息 + */ + public static class Limit { + + private String start; + private String size; + private String total; + private String orderBy; + + public String getStart() { + return start; + } + + public void setStart(String start) { + this.start = start; + } + + public String getSize() { + return size; + } + + public void setSize(String size) { + this.size = size; + } + + public String getTotal() { + return total; + } + + public void setTotal(String total) { + this.total = total; + } + + public String getOrderBy() { + return orderBy; + } + + public void setOrderBy(String orderBy) { + this.orderBy = orderBy; + } + } + + public Limit getLimit() { + return limit; + } + + public void setLimit(Limit limit) { + this.limit = limit; + } + + public Map getForm() { + return form; + } + + public void setForm(Map form) { + this.form = form; + } + } + + /** + * 数据集 + */ + public static class DataSet { + + private String total; + + private List rows = new ArrayList(); + + public String getTotal() { + return total; + } + + public void setTotal(String total) { + this.total = total; + } + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + } + + public Param getParam() { + return param; + } + + public void setParam(Param param) { + this.param = param; + } + + public DataSet getDataset() { + return dataset; + } + + public void setDataset(DataSet dataset) { + this.dataset = dataset; + } + + public void setDataset(String total, List rows) { + DataSet ds = new DataSet(); + ds.setTotal(total); + ds.setRows(rows); + this.setDataset(ds); + } + } + + public Head getHead() { + return head; + } + + public Body getBody() { + return body; + } + + public void setRetMsgCode(String code, String msg) { + this.head.setRetCode(code); + this.head.setRetMsg(msg); + } + + public void setRetMsgCode(String code) { + this.setRetMsgCode(code, null); + } + + public void setDataSet(String total, List rows) { + this.body.setDataset(total, rows); + } + + public static DataTransaction fromJSON(String jsonString) { + return JSON.parseObject(jsonString, DataTransaction.class); + } + + public String toJSON() { + return JSON.toJSONString(this); + } + + public static void main(String args[]) { + DataTransaction dt = new DataTransaction(); + + List> list = new ArrayList>(); + + Map m = new HashMap(); + m.put("name", "tom"); + m.put("sex", "m"); + list.add(m); + + dt.setDataSet("1000", list); + dt.setRetMsgCode("1", "ok"); + dt.getHead().setAppid("back"); + dt.getHead().setSeqno("201010"); + dt.getHead().getUser().setId("root"); + + Map m2 = new HashMap(); + m2.put("name1", "tom"); + m2.put("name2", "tom"); + m2.put("name3", "tom"); + + dt.getBody().getParam().setForm(m2); + + System.out.println(dt.toJSON()); + + DataTransaction dt2 = DataTransaction.fromJSON(dt.toJSON()); + System.out.println(dt2.toJSON()); + } +} diff --git a/src/test/java/com/alibaba/json/bvtVO/DataTransaction2.java b/src/test/java/com/alibaba/json/bvtVO/DataTransaction2.java new file mode 100755 index 0000000000..3994cac08a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/DataTransaction2.java @@ -0,0 +1,319 @@ +package com.alibaba.json.bvtVO; + + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + +/** + * 交易消息体 + * */ +public class DataTransaction2 implements Serializable { + + private static final long serialVersionUID = 1L; + + private Head head = new Head(); + + private Body body = new Body(); + + public DataTransaction2() { + + } + + /** + * Head + **/ + class Head { + + private String appid; + + private String transcode; + + private String seqno; + + private User user = new User(); + + private Ret ret = new Ret(); + + public Head() { + + } + + class User { + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + } + + /** + * 处理结果 + * */ + class Ret { + private String code; + private String msg; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + } + + public String getAppid() { + return appid; + } + + public void setAppid(String appid) { + this.appid = appid; + } + + public String getTranscode() { + return transcode; + } + + public void setTranscode(String transcode) { + this.transcode = transcode; + } + + public String getSeqno() { + return seqno; + } + + public void setSeqno(String seqno) { + this.seqno = seqno; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public Ret getRet() { + return ret; + } + + public void setRet(Ret ret) { + this.ret = ret; + } + + public void setRetCode(String code) { + this.ret.code = code; + } + + public void setRetMsg(String msg) { + this.ret.msg = msg; + } + } + + /** + * Body + * */ + @SuppressWarnings("rawtypes") + class Body { + + private Param param = new Param(); + + private DataSet dataset = new DataSet(); + + public Body() { + + } + + /** + * 参数 + * */ + class Param { + private Limit limit = new Limit(); + + private Map form = new HashMap(); + + class Limit { + private String start; + private String size; + private String total; + + public String getStart() { + return start; + } + + public void setStart(String start) { + this.start = start; + } + + public String getSize() { + return size; + } + + public void setSize(String size) { + this.size = size; + } + + public String getTotal() { + return total; + } + + public void setTotal(String total) { + this.total = total; + } + } + + public Limit getLimit() { + return limit; + } + + public void setLimit(Limit limit) { + this.limit = limit; + } + + public Map getForm() { + return form; + } + + public void setForm(Map form) { + this.form = form; + } + } + + /** + * 数据集 + * */ + class DataSet { + private String total; + + private List rows = new ArrayList(); + + public String getTotal() { + return total; + } + + public void setTotal(String total) { + this.total = total; + } + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + } + + public Param getParam() { + return param; + } + + public void setParam(Param param) { + this.param = param; + } + + public DataSet getDataset() { + return dataset; + } + + public void setDataset(DataSet dataset) { + this.dataset = dataset; + } + + public void setDataset(String total, List rows) { + DataSet ds = new DataSet(); + ds.setTotal(total); + ds.setRows(rows); + this.dataset = ds; + } + } + + public Head getHead() { + return head; + } + + public Body getBody() { + return body; + } + + public void setHead(Head head) { + this.head = head; + } + + public void setBody(Body body) { + this.body = body; + } + + /** + * 设置返回的消息信息 + * */ + public void setRetMsgCode(String code, String msg) { + this.head.setRetCode(code); + this.head.setRetMsg(msg); + } + + public void setRetMsgCode(String code) { + this.setRetMsgCode(code, null); + } + + /** + * 设置返回的结果集 + **/ + @SuppressWarnings("rawtypes") + public void setDataSet(String total, List rows) { + this.body.setDataset(total, rows); + } + + public static DataTransaction2 fromJSON(String jsonString) { + return JSON.parseObject(jsonString, DataTransaction2.class); + } + + public String toJSON() { + return JSON.toJSONString(this); + } + + public static void main(String args[]) { + + String jsonString = "{'head' : {'appid':'epas','transcode' : '000000','seqno' : '111111111', 'user' : { 'id' : '00000'}, 'ret' : { 'code' : '1', 'msg' : 'txt'} }, 'body' : { param : { form:{ name : '111', sex : '1', address : 'street1', array : [ { id : '1', name : 'tom1' }, { id : '2', name : 'tom2' } ]}, limit : { start : 1, size : 25, total : 100} }, dataset : { total : 1000, rows : [ { id : 'id', name : 'name' }, { id : 'id', name : 'name' } ] } }}"; + DataTransaction2 dt = DataTransaction2.fromJSON(jsonString); + System.out.println(dt.toJSON()); + DataTransaction2 dt1 = JSON.parseObject(dt.toJSON(), DataTransaction2.class); + System.out.println(dt1.toJSON()); + + Assert.assertEquals(dt.toJSON(), dt1.toJSON()); + + System.out.println("================="); + System.out.println(dt.toJSON()); + dt.setRetMsgCode("-1", "错误"); + dt.setDataSet("1000", new ArrayList>()); + System.out.println(dt.toJSON()); + + String text = dt.toJSON(); + System.out.println(text); + + DataTransaction2 dt2 = JSON.parseObject(text, DataTransaction2.class); + System.out.println(JSON.toJSONString(dt2)); + + Assert.assertEquals(dt.toJSON(), dt2.toJSON()); + } +} diff --git a/src/test/java/com/alibaba/json/bvtVO/IEvent.java b/src/test/java/com/alibaba/json/bvtVO/IEvent.java new file mode 100755 index 0000000000..237c5aced6 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/IEvent.java @@ -0,0 +1,102 @@ +/** + * Project: eve.services + * + * File Created at 2011-12-21 + * $Id$ + * + * Copyright 2008 Alibaba.com Corporation Limited. + * All rights reserved. + * + * This software is the confidential and proprietary information of + * Alibaba Company. ("Confidential Information"). You shall not + * disclose such Confidential Information and shall use it only in + * accordance with the terms of the license agreement you entered into + * with Alibaba.com. + */ +package com.alibaba.json.bvtVO; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.Map; + +/** + * �¼����� + * + * @author wb_jianhui.shijh + */ +public class IEvent implements Serializable { + + private static final long serialVersionUID = -791431935700654454L; + + /** + * �¼������ + */ + private String name; + + /** + * �¼�����Դ + */ + private String source; + + /** + * �¼���� + */ + private Map detailData; + + /** + * �¼�����ʱ�� + */ + private Timestamp generateTime; + + /** + * ���¼����������һ��Ψһ��־��ID. + */ + private String externalId; + + public String getExternalId() { + return externalId; + } + + public void setExternalId(String externalId) { + this.externalId = externalId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + public Map getDetailData() { + return detailData; + } + + public void setDetailData(Map detailData) { + this.detailData = detailData; + } + + public Timestamp getGenerateTime() { + return generateTime; + } + + public void setGenerateTime(Timestamp generateTime) { + this.generateTime = generateTime; + } + + @Override + public String toString() { + return "IEvent [name=" + name + ", source=" + source + ", externalId=" + externalId + + ", generateTime=" + generateTime + ", detailData=" + detailData + "]"; + } + +} diff --git a/src/test/java/com/alibaba/json/bvtVO/IEventDto.java b/src/test/java/com/alibaba/json/bvtVO/IEventDto.java new file mode 100755 index 0000000000..384a509f6a --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/IEventDto.java @@ -0,0 +1,53 @@ +/** + * Project: eve.services + * + * File Created at 2011-12-21 + * $Id$ + * + * Copyright 2008 Alibaba.com Corporation Limited. + * All rights reserved. + * + * This software is the confidential and proprietary information of + * Alibaba Company. ("Confidential Information"). You shall not + * disclose such Confidential Information and shall use it only in + * accordance with the terms of the license agreement you entered into + * with Alibaba.com. + */ +package com.alibaba.json.bvtVO; + +import java.io.Serializable; +import java.util.ArrayList; + +/** + * @author wb_jianhui.shijh + */ +public class IEventDto implements Serializable { + + private static final long serialVersionUID = -3903138261314727539L; + + private String source; + + private ArrayList eventList = new ArrayList(); + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + public ArrayList getEventList() { + return eventList; + } + + public void setEventList(ArrayList eventList) { + this.eventList = eventList; + } + + @Override + public String toString() { + return "IEventDto [source=" + source + ", eventList=" + eventList + "]"; + } + +} diff --git a/src/test/java/com/alibaba/json/bvtVO/Image.java b/src/test/java/com/alibaba/json/bvtVO/Image.java new file mode 100755 index 0000000000..f7322a5c8c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/Image.java @@ -0,0 +1,60 @@ +/* + * Copyright 1999-2004 Alibaba.com All right reserved. This software is the confidential and proprietary information of + * Alibaba.com ("Confidential Information"). You shall not disclose such Confidential Information and shall use it only + * in accordance with the terms of the license agreement you entered into with Alibaba.com. + */ +package com.alibaba.json.bvtVO; + +import java.io.Serializable; + +/** + * ��Image.java��ʵ��������ͼƬ��Ϣ���� + * + * @author maik.wangz 2011-8-15 ����06:19:39 + */ +public class Image implements Serializable { + + private static final long serialVersionUID = -6804500330834961534L; + private String imageUrl; + + public Image(String imageUrl){ + super(); + this.imageUrl = imageUrl; + } + + public Image(){ + + } + + public String getBigImageUrl() { + if (imageUrl == null || imageUrl.length() == 0) { + return ""; + } + return ("img/" + imageUrl).replaceFirst(".jpg", ".310x310.jpg"); + } + + /** �������ͼƬ�����ϵ����·�� 150 * 150 */ + public String getSearchImageUrl() { + if (imageUrl == null || imageUrl.length() == 0) { + return ""; + } + return ("img/" + imageUrl).replaceFirst(".jpg", ".search.jpg"); + } + + /** �������ͼƬ�����ϵ����·�� 100 * 100 */ + public String getSummImageUrl() { + if (imageUrl == null || imageUrl.length() == 0) { + return ""; + } + return ("img/" + imageUrl).replaceFirst(".jpg", ".summ.jpg"); + } + + public String getImageUrl() { + return imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + +} diff --git a/src/test/java/com/alibaba/json/bvtVO/Main.java b/src/test/java/com/alibaba/json/bvtVO/Main.java new file mode 100755 index 0000000000..1d1e07a0fe --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/Main.java @@ -0,0 +1,26 @@ +package com.alibaba.json.bvtVO; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; + +public class Main { + public static void main(String[] args) { + Page page = new Page(); + page.setCount(1); + List items = new ArrayList(); + Bean item = new Bean(); + item.setId(1); + item.setName("name"); + item.setDesc("desc"); + items.add(item); + page.setItems(items); + String json = JSON.toJSONString(page); + + Page jsonPage = JSON.parseObject(json, new TypeReference>() { + }); + System.out.println(jsonPage.getItems().get(0).getName()); + } +} diff --git a/src/test/java/com/alibaba/json/bvtVO/OfferRankResultVO.java b/src/test/java/com/alibaba/json/bvtVO/OfferRankResultVO.java new file mode 100755 index 0000000000..08599031a0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/OfferRankResultVO.java @@ -0,0 +1,43 @@ +package com.alibaba.json.bvtVO; + +import java.util.ArrayList; +import java.util.List; + +public class OfferRankResultVO { + private List models = new ArrayList(); + + public OfferRankResultVO() { + models.add(new SearchCenterOfferModel()); + } + + public List getModel() { + return models; + } + + public void setModel(List models) { + this.models = models; + } + +} + +class SearchCenterOfferModel { + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/bvtVO/OptionKey.java b/src/test/java/com/alibaba/json/bvtVO/OptionKey.java new file mode 100755 index 0000000000..fbb516fcc1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/OptionKey.java @@ -0,0 +1,17 @@ +/* + * Copyright 2011 Alibaba.com All right reserved. This software is the + * confidential and proprietary information of Alibaba.com ("Confidential + * Information"). You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Alibaba.com. + */ +package com.alibaba.json.bvtVO; + +/** + * 类OptionKey.java的实现描述:TODO 类实现描述 + * + * @author lei.yaol 2011-12-27 下午03:40:45 + */ +public enum OptionKey { + TEMPLATE_REOUSRCE_ID, TEMPALTE_ATTACH_META, RESEND_LOG_ID; +} diff --git a/src/test/java/com/alibaba/json/bvtVO/OptionValue.java b/src/test/java/com/alibaba/json/bvtVO/OptionValue.java new file mode 100755 index 0000000000..747379eeeb --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/OptionValue.java @@ -0,0 +1,48 @@ +/** + * Project: rowan.share-1.0.0 + * + * File Created at 2011-11-24 + * $Id$ + * + * Copyright 1999-2100 Alibaba.com Corporation Limited. + * All rights reserved. + * + * This software is the confidential and proprietary information of + * Alibaba Company. ("Confidential Information"). You shall not + * disclose such Confidential Information and shall use it only in + * accordance with the terms of the license agreement you entered into + * with Alibaba.com. + */ +package com.alibaba.json.bvtVO; + +import java.io.Serializable; + +/** + * 类OptionValue.java的实现描述:TODO 类实现描述 + * + * @author lei.yaol 2011-12-27 下午03:41:43 + */ +public class OptionValue implements Serializable { + + private static final long serialVersionUID = -1158546247925194748L; + + private E value; + + /** + * set option value + * + * @param value + */ + public void setValue(E value) { + this.value = value; + } + + /** + * get option value + * + * @return E + */ + public E getValue() { + return value; + } +} diff --git a/src/test/java/com/alibaba/json/bvtVO/Page.java b/src/test/java/com/alibaba/json/bvtVO/Page.java new file mode 100755 index 0000000000..a6c3b781fe --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/Page.java @@ -0,0 +1,24 @@ +package com.alibaba.json.bvtVO; + +import java.util.List; + +public class Page { + private Integer count; + private List items; + + public void setCount(Integer count) { + this.count = count; + } + + public Integer getCount() { + return count; + } + + public void setItems(List items) { + this.items = items; + } + + public List getItems() { + return items; + } +} diff --git a/src/test/java/com/alibaba/json/bvtVO/PhysicalQueue.java b/src/test/java/com/alibaba/json/bvtVO/PhysicalQueue.java new file mode 100755 index 0000000000..55b7a9eeaf --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/PhysicalQueue.java @@ -0,0 +1,79 @@ +package com.alibaba.json.bvtVO; + +public class PhysicalQueue { + + private QueueEntity queue; + private Integer weight; + private Integer capacity; + private int inRate; + private int outRate; + + // Napoli 1.1 新加属性 + private boolean sendable; + private boolean receivable; + + public PhysicalQueue(){ + + } + + public Integer getCapacity() { + return capacity; + } + + public void setCapacity(Integer capacity) { + this.capacity = capacity; + } + + public int getInRate() { + return inRate; + } + + public void setInRate(int inRate) { + this.inRate = inRate; + } + + public int getOutRate() { + return outRate; + } + + public void setOutRate(int outRate) { + this.outRate = outRate; + } + + public boolean relationChanged(Object other) { + return false; + } + + public QueueEntity getQueue() { + return queue; + } + + public void setQueue(QueueEntity queue) { + this.queue = queue; + } + + public Integer getWeight() { + return weight; + } + + public void setWeight(Integer weight) { + this.weight = weight; + } + + public boolean isSendable() { + return sendable; + } + + public void setSendable(boolean sendable) { + this.sendable = sendable; + } + + public boolean isReceivable() { + return receivable; + } + + public void setReceivable(boolean receivable) { + this.receivable = receivable; + } + +} diff --git a/src/test/java/com/alibaba/json/bvtVO/ProductView.java b/src/test/java/com/alibaba/json/bvtVO/ProductView.java new file mode 100755 index 0000000000..ef57e6b711 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/ProductView.java @@ -0,0 +1,59 @@ +package com.alibaba.json.bvtVO; + +public class ProductView { + + private Integer id; + private String keyword; + private boolean hasProduct; + private boolean hasCompany; + private boolean hasBuyLead; + private String country; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getKeyword() { + return keyword; + } + + public void setKeyword(String keyword) { + this.keyword = keyword; + } + + public boolean isHasProduct() { + return hasProduct; + } + + public void setHasProduct(boolean hasProduct) { + this.hasProduct = hasProduct; + } + + public boolean isHasCompany() { + return hasCompany; + } + + public void setHasCompany(boolean hasCompany) { + this.hasCompany = hasCompany; + } + + public boolean isHasBuyLead() { + return hasBuyLead; + } + + public void setHasBuyLead(boolean hasBuyLead) { + this.hasBuyLead = hasBuyLead; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } +} diff --git a/src/test/java/com/alibaba/json/bvtVO/PushMsg.java b/src/test/java/com/alibaba/json/bvtVO/PushMsg.java new file mode 100644 index 0000000000..deb54f3956 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/PushMsg.java @@ -0,0 +1,630 @@ +package com.alibaba.json.bvtVO; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +/** + * Created by haihong.xiahh on 13-12-23. + */ +public class PushMsg implements Serializable { + + public static final String DIR_PUSH = "push"; + + /** + * + */ + private static final long serialVersionUID = 8145512296629061628L; + + public static final String TAG = PushMsg.class.getSimpleName(); + + public static final String TYPE_SYS = "sys"; + + public static final String TYPE_WL = "wl"; + + public static final long STATUS_TRANK_NO_NEW = 128; + + /** + * id of PushMsg + */ + private String id; + /** + * type + */ + private String tp; + /** + * start time with unit second(s) + */ + private long st; + /** + * end time with unit second(s) + */ + private long et; + /** + * delay range 以10秒为单位,客户端会在[0 ~ dr*10seconds]的范围内,进行随机延时请求msg,防止服务器过载。 + */ + private long dr; + + private Msg msg; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getTp() { + return tp; + } + + public void setTp(String tp) { + this.tp = tp; + } + + public long getSt() { + return st; + } + + public void setSt(long st) { + this.st = st; + } + + public long getEt() { + return et; + } + + public void setEt(long et) { + this.et = et; + } + + public Msg getMsg() { + return msg; + } + + public void setMsg(Msg msg) { + this.msg = msg; + } + + /** + * 条件:
+ * 1、没过期(et>=当前时间,st可以大于也可以小于当前时间)
+ * 2、消息体有效
+ * + * @return true if valid. + */ + public boolean isValid() { + long now = new Date().getTime() / 1000; + + if (now > et) { + return false; + }// end if + + if (msg == null) { + return false; + }// end if + + if (!msg.isValid()) { + return false; + }// end if + + return true; + } + + /** + * 条件 1. isValid 2. st <= now <= et + * */ + public boolean isActiveNow() { + if (!isValid()) { + return false; + } + long now = new Date().getTime() / 1000; + + if (now < st) { + return false; + }// end if + + if (now > et) { + return false; + }// end if + + if (!isImagesReady()) { + return false; + }// end if + + return true; + } + + /** + * 消息的URL是否存在 + * + * @return true if exist. + */ + public boolean hasUrl() { + boolean result = true; + if (null != msg) { + } else { + result = false; + } + + + return result; + } + + public boolean hasText() { + boolean result = true; + if (null != msg) { + } else { + result = false; + } + + + return result; + } + + /** + * 通知所需的图片资源是否就绪 + * + * @return true if ready, otherwise return false. + */ + private boolean isImagesReady() { + List list = getNewImageUrlList(); + boolean ret = null == list || 0 == list.size(); + if (!ret) { + preparedImages(list); + } + return ret; + } + + /** + * 主动下载未缓存到客户端的资源图片 + */ + public void preparedImages() { + List list = getNewImageUrlList(); + preparedImages(list); + } + + public void preparedImages(List list) { + } + + /** + * 获取需要下载图片的URL列表 + * + * @return list of image URL which image's URL is not cached, otherwise + * return null. + */ + private List getNewImageUrlList() { + return null; + } + + public static class Msg implements Serializable { + /** + * + */ + private static final long serialVersionUID = -2020714577526457332L; + + private String gid; + private String gtp; + /** + * 指显示在通知左侧的外部图标URL + */ + private String ico; + private String url; + private String txt; + + private String flgs; + private String stxt; + private String surl; + /** + * 指在分享页附加的外部图片URL + */ + private String simg; + + private ControlFlags controlFlags; + + public Msg() { + } + + public String getGid() { + return gid; + } + + public void setGid(String gid) { + this.gid = gid; + } + + public String getGtp() { + return gtp; + } + + public void setGtp(String gtp) { + this.gtp = gtp; + } + + public String getIco() { + return ico; + } + + public void setIco(String icon) { + this.ico = icon; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + if (null != url) { + url = url.trim(); + } + this.url = url; + } + + public String getTxt() { + return txt; + } + + public void setTxt(String txt) { + this.txt = txt; + } + + public String getFlgs() { + return flgs; + } + + public void setFlgs(String flgs) { + this.flgs = flgs; + controlFlags = new ControlFlags(flgs); + } + + public String getStxt() { + return stxt; + } + + public void setStxt(String stxt) { + this.stxt = stxt; + } + + public String getSurl() { + return surl; + } + + public void setSurl(String surl) { + this.surl = surl; + } + + public String getSimg() { + return simg; + } + + public void setSimg(String simg) { + this.simg = simg; + } + + public ControlFlags getControlFlags() { + return controlFlags; + } + + /** + *

+ * 条件 + *

+ * 0.gid 不为null 1.controlFlag 必须有效(即非空,则控制位数目足够)
+ * 2.当开启分享功能时,stxt/surl/simg 至少有一个有效(非空)
+ * + * @return true if valid. + */ + public boolean isValid() { + + return true; + } + + /** + * 打印debug信息 + * + * @return + */ + public String debug() { + StringBuilder sb = new StringBuilder(); + sb.append("\n#gid=" + gid); + sb.append("\n#gtp=" + gtp); + sb.append("\n#ico=" + ico); + sb.append("\n#url=" + url); + sb.append("\n#txt=" + txt); + sb.append("\n#flags=" + flgs); + sb.append("\n#stxt=" + stxt); + sb.append("\n#surl=" + surl); + sb.append("\n#simg=" + simg); + if (null != controlFlags) { + sb.append(controlFlags.debug()); + }// end if + return sb.toString(); + } + + /** + * 标志控制 + * + * @author wangyue.wy + */ + public static class ControlFlags implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 6289110973325625431L; + + private enum INDEX_TYPE { + INDEX_POS, INDEX_OPEN_URL, INDEX_DIMISS, INDEX_CANCEL_BTN, INDEX_TEXT_EFFECTS, INDEX_SHARE, INDEX_ATTACH_IMAGE, INDEX_LIMIT_SHOW_MAX_ONCE + } + + private final int COUNT = INDEX_TYPE.values().length; + + public static final int CTR_UNKNOWN = 0; + private String text; + + /** + *

+ * 展示位置(暂时只有顶部,居中) + *

+ *

+ * A:顶部(default)
+ * B:居中
+ *

+ */ + private char ctrlPos; + /** + *

+ * URL打开方式 + *

+ *

+ * A:内嵌打开(default)
+ * B:外部浏览器打开
+ *

+ */ + private char ctrlOpenUrl; + /** + *

+ * 消失方式 + *

+ *

+ * A:不消失(直至过期失效)(default)
+ * B:点击消失
+ * C:解锁消失
+ * D:浏览消失
+ * E:解锁+点击消失
+ * F:解锁+浏览消失
+ * G:解锁+点击+浏览消失
+ *

+ */ + private char ctrlDimiss; + /** + *

+ * 删除按钮 + *

+ *

+ * A:显示(default)
+ * B:不显示
+ *

+ */ + private char ctrlCancelBtn; + /** + *

+ * 是否支持分享 + *

+ *

+ * A:开启(default)
+ * B:关闭
+ *

+ */ + private char ctrlShare; + /** + *

+ * 附加图片来源 + *

+ *

+ * A:无图片(default)
+ * B:使用屏幕截图
+ * C:使用服务器指定的URL网络图片 + *

+ */ + private char ctrlAttachImage; + /** + *

+ * 文案展示效果 + *

+ *

+ * A:静止显示(default)
+ * B:滚动
+ *

+ */ + private char ctrlTextEffects; + + /** + *

+ * 同一gid通知,限制最多展示一次 + *

+ *

+ * A:否(default) + *

+ *

+ * B:是 + *

+ */ + private char ctrlLimitShowMaxOnce; + + public ControlFlags(String param) { + + this.text = param; + ctrlPos = text.charAt(INDEX_TYPE.INDEX_POS.ordinal()); + ctrlOpenUrl = text.charAt(INDEX_TYPE.INDEX_OPEN_URL.ordinal()); + ctrlDimiss = text.charAt(INDEX_TYPE.INDEX_DIMISS.ordinal()); + ctrlCancelBtn = text.charAt(INDEX_TYPE.INDEX_CANCEL_BTN.ordinal()); + ctrlShare = text.charAt(INDEX_TYPE.INDEX_SHARE.ordinal()); + ctrlAttachImage = text.charAt(INDEX_TYPE.INDEX_ATTACH_IMAGE.ordinal()); + ctrlTextEffects = text.charAt(INDEX_TYPE.INDEX_TEXT_EFFECTS.ordinal()); + ctrlLimitShowMaxOnce = text.charAt(INDEX_TYPE.INDEX_LIMIT_SHOW_MAX_ONCE.ordinal()); + } + + /* control of position */ + public boolean posTop() { + // default + return 'A' == ctrlPos || ctrlPos > 'B' || ctrlPos < 'A'; + } + + public boolean posCenter() { + return 'B' == ctrlPos; + } + + /* control of open URL mode */ + public boolean openUrlByInner() { + // default + return 'A' == ctrlOpenUrl || ctrlOpenUrl > 'B' || ctrlPos < 'A'; + } + + public boolean openUrlByOutside() { + return 'B' == ctrlOpenUrl; + } + + /* control of dismiss */ + public boolean nerverDismiss() { + // default + return 'A' == ctrlDimiss || ctrlDimiss > 'G' || ctrlPos < 'A'; + } + + public boolean dismissByUnlock() { + return 'C' == ctrlDimiss || 'D' == ctrlDimiss; + } + + public boolean dismissByClick() { + return 'B' == ctrlDimiss || 'D' == ctrlDimiss; + } + + /* control of show cancel btn */ + public boolean showCancelBtn() { + // default + return 'A' == ctrlCancelBtn || ctrlCancelBtn > 'B' || ctrlPos < 'A'; + } + + /** + * 是否首页 或 Web页,开启分享按钮 + * + * @return true if Not 'B'(B:首页 和 Web页均关闭分享按钮显示) + */ + public boolean enableShare() { + return 'B' != ctrlShare; + } + + /* control of share */ + /** + * 首页是否支持通知显示分享按钮 + * + * @return true if equal 'A', 'C' or [*,A] || [D,*] + */ + public boolean enableShareInHomePage() { + // default + return 'A' == ctrlShare || 'C' == ctrlShare || ctrlShare > 'D' || ctrlPos < 'A'; + } + + /** + * Web页是否支持通知显示分享按钮 + * + * @return true if equal 'A' Or 'D' + */ + public boolean enableShareInWebPage() { + // default + return 'A' == ctrlShare || 'D' == ctrlShare || ctrlShare > 'D' || ctrlPos < 'A'; + } + + /* control of use screen shot image */ + public boolean attachNoImage() { + // default + return 'A' == ctrlAttachImage || ctrlAttachImage > 'C' || ctrlPos < 'A'; + } + + public boolean attachScreenShot() { + return 'B' == ctrlAttachImage; + } + + public boolean attachWebUrlImage() { + return 'C' == ctrlAttachImage; + } + + /* control of text effects */ + public boolean isStaicTextEffects() { + return 'A' == ctrlTextEffects || ctrlTextEffects > 'C' || ctrlPos < 'A'; + } + + public boolean isScrollTextEffects() { + return 'B' == ctrlTextEffects; + } + + public boolean isBlingTextEffects() { + return 'C' == ctrlTextEffects; + } + + public boolean isLimitShowMaxOnce() { + return 'B' == ctrlLimitShowMaxOnce; + } + + /** + * + * 控制字不能为空
+ * 控制字长度不少于所需长度 + * + * @return true if valid, otherwise return false. + */ + public boolean isValid() { + + return true; + } + + /** + * 打印调试信息 + * + * @return + */ + public String debug() { + StringBuilder sb = new StringBuilder(); + sb.append("\n>>>>>>>>>>>"); + sb.append("\nflag:" + text); + sb.append("\n(" + INDEX_TYPE.INDEX_POS.ordinal() + ")ctrlPos=" + ctrlPos); + sb.append("\n(" + INDEX_TYPE.INDEX_OPEN_URL.ordinal() + ")ctrlOpenUrl=" + ctrlOpenUrl); + sb.append("\n(" + INDEX_TYPE.INDEX_DIMISS.ordinal() + ")ctrlDismiss=" + ctrlDimiss); + sb.append("\n(" + INDEX_TYPE.INDEX_CANCEL_BTN.ordinal() + ")ctrlCancelBtn=" + ctrlCancelBtn); + sb.append("\n(" + INDEX_TYPE.INDEX_TEXT_EFFECTS.ordinal() + ")ctrlTextEffects=" + ctrlTextEffects); + sb.append("\n(" + INDEX_TYPE.INDEX_SHARE.ordinal() + ")ctrlShare=" + ctrlShare); + sb.append("\n(" + INDEX_TYPE.INDEX_ATTACH_IMAGE.ordinal() + ")ctrlAttachImage=" + ctrlAttachImage); + sb.append("\n(" + INDEX_TYPE.INDEX_LIMIT_SHOW_MAX_ONCE.ordinal() + ")ctrlLimitShowMaxOnce=" + + ctrlLimitShowMaxOnce); + sb.append("\n>>>>>>>>>>>"); + return sb.toString(); + } + } + } + + /** + * 打印debug信息 + * + * @return + */ + public String debug() { + StringBuilder sb = new StringBuilder(); + sb.append("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); + sb.append("\nid=" + id); + sb.append("\nst=" + st); + sb.append("\net=" + et); + sb.append("\ndr=" + dr); + sb.append("\nmsg=\n" + msg.debug()); + sb.append("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); + return sb.toString(); + } + + public long getDr() { + return dr; + } + + public void setDr(long dr) { + this.dr = dr; + } +} diff --git a/src/test/java/com/alibaba/json/bvtVO/QueueEntity.java b/src/test/java/com/alibaba/json/bvtVO/QueueEntity.java new file mode 100755 index 0000000000..6cb4ed16a5 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/QueueEntity.java @@ -0,0 +1,72 @@ +package com.alibaba.json.bvtVO; + +/** + * Project: napoli.domain File Created at 2009-6-3 $Id: QueueEntity.java 55142 2010-08-24 01:43:14Z guolin.zhuanggl $ Copyright + * 2008 Alibaba.com Croporation Limited. All rights reserved. This software is the confidential and proprietary + * information of Alibaba Company. ("Confidential Information"). You shall not disclose such Confidential Information + * and shall use it only in accordance with the terms of the license agreement you entered into with Alibaba.com. + */ + +import java.util.HashMap; +import java.util.Map; + +/** + * 用于存Queue配置信息的类,这里的Queue就是指业务上对应的�1�7�辑Queue,可能会分布到多台机器上 + * + * @author xiaosong.liangxs + */ +public class QueueEntity { + + private int id; + private String description; + + private Map pqMap = new HashMap(); + + /** + * @return the pqMap + */ + public Map getPqMap() { + return pqMap; + } + + /** + * @param pqMap the pqMap to set + */ + public void setPqMap(Map pqMap) { + this.pqMap = pqMap; + } + + public QueueEntity(){ + } + + /** + * @return the pqMap + */ + public Map getPhysicalQueueMap() { + return pqMap; + } + + /** + * @param pqMap the pqMap to set + */ + public void setPhysicalQueueMap(Map pqMap) { + this.pqMap = pqMap; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} diff --git a/src/test/java/com/alibaba/json/bvtVO/RainbowStats.java b/src/test/java/com/alibaba/json/bvtVO/RainbowStats.java new file mode 100755 index 0000000000..f35df705e2 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/RainbowStats.java @@ -0,0 +1,25 @@ +package com.alibaba.json.bvtVO; + +public class RainbowStats { + private int id; + private String name; + + public int getId() { + return id; + } + + public RainbowStats setId(int id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public RainbowStats setName(String name) { + this.name = name; + return this; + } + +} diff --git a/src/test/java/com/alibaba/json/bvtVO/TempAttachMetaOption.java b/src/test/java/com/alibaba/json/bvtVO/TempAttachMetaOption.java new file mode 100755 index 0000000000..0bc66f382c --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/TempAttachMetaOption.java @@ -0,0 +1,59 @@ +/** + * Project: rowan.server.biz.service-1.0-SNAPSHOT + * + * File Created at 2011-12-9 + * $Id$ + * + * Copyright 1999-2100 Alibaba.com Corporation Limited. + * All rights reserved. + * + * This software is the confidential and proprietary information of + * Alibaba Company. ("Confidential Information"). You shall not + * disclose such Confidential Information and shall use it only in + * accordance with the terms of the license agreement you entered into + * with Alibaba.com. + */ +package com.alibaba.json.bvtVO; + +import java.io.Serializable; + +/** + * 类TempAttachMetaOption.java的实现描述:TODO 类实现描述 + * + * @author lei.yaol 2011-12-27 下午03:43:32 + */ +public class TempAttachMetaOption implements Serializable { + + private static final long serialVersionUID = -8786217160252057362L; + + private Integer id; + + private String name; + + private String path; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + +} diff --git a/src/test/java/com/alibaba/json/bvtVO/TestDTO.java b/src/test/java/com/alibaba/json/bvtVO/TestDTO.java new file mode 100755 index 0000000000..edd0dadcfa --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/TestDTO.java @@ -0,0 +1,31 @@ +package com.alibaba.json.bvtVO; + +import javax.xml.bind.annotation.XmlRootElement; + +/** + */ +@XmlRootElement(name = "TestDTO") +public class TestDTO { + + private String channel; + private String txCode; + + + public String getChannel() { + return channel; + } + + public void setChannel(String channel) { + this.channel = channel; + } + + public String getTxCode() { + return txCode; + } + + public void setTxCode(String txCode) { + this.txCode = txCode; + } + + +} diff --git a/src/test/java/com/alibaba/json/bvtVO/VirtualTopic.java b/src/test/java/com/alibaba/json/bvtVO/VirtualTopic.java new file mode 100755 index 0000000000..f95077cad8 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/VirtualTopic.java @@ -0,0 +1,110 @@ +package com.alibaba.json.bvtVO; + +import java.util.HashMap; +import java.util.Map; + +public class VirtualTopic { + + private static final long serialVersionUID = 1115397330651723322L; + + private Map queueMap = new HashMap(); + private Integer queueCount; + + private int queueLimit; + + private String description; + + public VirtualTopic(){ + + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + /** + * @return the queueList + */ + public Map getQueueMap() { + return queueMap; + } + + /** + * @param queueList the queueList to set + */ + public void setQueueMap(Map queueMap) { + this.queueMap = queueMap; + } + + /** + * @return the queueCount + */ + public Integer getQueueCount() { + if (queueCount != null) { + return queueCount; + } else { + return queueMap.size(); + } + } + + /** + * @param queueCount the queueCount to set + */ + public void setQueueCount(Integer queueCount) { + this.queueCount = queueCount; + } + + public boolean propertiesChanged(Object other) { + if (!(other instanceof VirtualTopic)) { + return false; + } + VirtualTopic vt = (VirtualTopic) other; + int size = queueMap.size(); + if (size != vt.queueMap.size()) { + return true; + } + for (Integer id : queueMap.keySet()) { + if (!vt.queueMap.containsKey(id)) { + return true; + } + } + return false; + } + + public boolean relationChanged(Object other) { + if (!(other instanceof VirtualTopic)) { + return false; + } + VirtualTopic vt = (VirtualTopic) other; + int size = queueMap.size(); + if (size != vt.queueMap.size()) { + return true; + } + for (Integer id : queueMap.keySet()) { + if (!vt.queueMap.containsKey(id)) { + return true; + } + } + return false; + } + + /** + * @param queueEntity + */ + public void addQueue(QueueEntity queueEntity) { + this.queueMap.put(queueEntity.getId(), queueEntity); + } + + public int getQueueLimit() { + return queueLimit; + } + + public void setQueueLimit(int queueLimit) { + this.queueLimit = queueLimit; + } + +} diff --git a/src/test/java/com/alibaba/json/bvtVO/WareHouseInfo.java b/src/test/java/com/alibaba/json/bvtVO/WareHouseInfo.java new file mode 100755 index 0000000000..c2a7eac6a0 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvtVO/WareHouseInfo.java @@ -0,0 +1,94 @@ +package com.alibaba.json.bvtVO; + +import java.io.Serializable; + +/** + * ��WarehouseInfo.java��ʵ���������ֿ���Ϣ���� + * + * @author maik.wangz 2011-12-12 ����09:50:32 + */ +public class WareHouseInfo implements Serializable { + + private static final long serialVersionUID = 6102232214244738211L; + // ʡ��ID + private String provinceId; + // ʡ����� + private String provinceName; + // ����ID + private String cityId; + // ������� + private String cityName; + // ����ID + private String areaId; + // �������� + private String areaName; + // �ֿ���� + private String houseArea; + // �ֿ�ͼƬ + private Image[] images; + + public String getProvinceId() { + return provinceId; + } + + public void setProvinceId(String provinceId) { + this.provinceId = provinceId; + } + + public String getProvinceName() { + return provinceName; + } + + public void setProvinceName(String provinceName) { + this.provinceName = provinceName; + } + + public String getCityId() { + return cityId; + } + + public void setCityId(String cityId) { + this.cityId = cityId; + } + + public String getCityName() { + return cityName; + } + + public void setCityName(String cityName) { + this.cityName = cityName; + } + + public String getAreaId() { + return areaId; + } + + public void setAreaId(String areaId) { + this.areaId = areaId; + } + + public String getAreaName() { + return areaName; + } + + public void setAreaName(String areaName) { + this.areaName = areaName; + } + + public String getHouseArea() { + return houseArea; + } + + public void setHouseArea(String houseArea) { + this.houseArea = houseArea; + } + + public Image[] getImages() { + return images; + } + + public void setImages(Image[] images) { + this.images = images; + } + +} diff --git a/src/test/java/com/alibaba/json/demo/DateDemo.java b/src/test/java/com/alibaba/json/demo/DateDemo.java old mode 100644 new mode 100755 index 3ed30feb6b..06799a02ec --- a/src/test/java/com/alibaba/json/demo/DateDemo.java +++ b/src/test/java/com/alibaba/json/demo/DateDemo.java @@ -3,7 +3,7 @@ import java.text.SimpleDateFormat; import java.util.Date; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/demo/Demo1.java b/src/test/java/com/alibaba/json/demo/Demo1.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/demo/Demo2.java b/src/test/java/com/alibaba/json/demo/Demo2.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/demo/EncodeDemo.java b/src/test/java/com/alibaba/json/demo/EncodeDemo.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/demo/ErrorObjectSerializer.java b/src/test/java/com/alibaba/json/demo/ErrorObjectSerializer.java new file mode 100644 index 0000000000..4c70c8d34c --- /dev/null +++ b/src/test/java/com/alibaba/json/demo/ErrorObjectSerializer.java @@ -0,0 +1,26 @@ +package com.alibaba.json.demo; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.Set; + +import com.alibaba.fastjson.serializer.AutowiredObjectSerializer; +import com.alibaba.fastjson.serializer.JSONSerializer; + + +public class ErrorObjectSerializer implements AutowiredObjectSerializer { + + public ErrorObjectSerializer() { + throw new RuntimeException(); + } + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + + } + + public Set getAutowiredFor() { + return Collections.singleton(X.class); + } + +} diff --git a/src/test/java/com/alibaba/json/demo/FilterDemo.java b/src/test/java/com/alibaba/json/demo/FilterDemo.java new file mode 100755 index 0000000000..a20ae3520d --- /dev/null +++ b/src/test/java/com/alibaba/json/demo/FilterDemo.java @@ -0,0 +1,48 @@ +package com.alibaba.json.demo; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.NameFilter; +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.ValueFilter; + +public class FilterDemo extends TestCase { + + public void test_secure() throws Exception { + + ValueFilter filter = new ValueFilter() { + + public Object process(Object source, String name, Object value) { + if (name.equals("name")) { + return "WSJ"; + } + return value; + } + }; + + NameFilter nameFilter = new NameFilter() { + public String process(Object source, String name, Object value) { + if (name.equals("id")) { + return "ID"; + } + return name; + } + }; + + String text = "{\"id\":123,\"name\":\"WJH\"}"; + + Object object = JSON.parse(text); + + SerializeWriter out = new SerializeWriter(); + JSONSerializer serializer = new JSONSerializer(out); + serializer.getValueFilters().add(filter); + serializer.getNameFilters().add(nameFilter); + + serializer.write(object); + + String outText = out.toString(); + System.out.println(outText); + } +} diff --git a/src/test/java/com/alibaba/json/demo/Group.java b/src/test/java/com/alibaba/json/demo/Group.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/demo/JSONFeidDemo.java b/src/test/java/com/alibaba/json/demo/JSONFeidDemo.java old mode 100644 new mode 100755 index 0d6dcaa649..8265483d4e --- a/src/test/java/com/alibaba/json/demo/JSONFeidDemo.java +++ b/src/test/java/com/alibaba/json/demo/JSONFeidDemo.java @@ -1,6 +1,6 @@ package com.alibaba.json.demo; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/demo/MapDemo.java b/src/test/java/com/alibaba/json/demo/MapDemo.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/demo/User.java b/src/test/java/com/alibaba/json/demo/User.java old mode 100644 new mode 100755 index fb8f8ef615..9607b5c288 --- a/src/test/java/com/alibaba/json/demo/User.java +++ b/src/test/java/com/alibaba/json/demo/User.java @@ -1,5 +1,10 @@ package com.alibaba.json.demo; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; + public class User { private Long id; @@ -20,4 +25,15 @@ public String getName() { public void setName(String name) { this.name = name; } + + public static void main(String[] args) { + User user = new User(); + user.setId(123L); + user.setName("wenshao"); + String text = JSON.toJSONString(user); + System.out.println(text); + + User user1 = JSON.parseObject(text, User.class); + Assert.assertEquals("{\"id\":123,\"name\":\"wenshao\"}", text); + } } diff --git a/src/test/java/com/alibaba/json/demo/X.java b/src/test/java/com/alibaba/json/demo/X.java new file mode 100644 index 0000000000..ee32e2d37c --- /dev/null +++ b/src/test/java/com/alibaba/json/demo/X.java @@ -0,0 +1,6 @@ +package com.alibaba.json.demo; + + +public class X { + +} diff --git a/src/test/java/com/alibaba/json/demo/XAutowiredObjectSerializer.java b/src/test/java/com/alibaba/json/demo/XAutowiredObjectSerializer.java new file mode 100644 index 0000000000..67c06bfe74 --- /dev/null +++ b/src/test/java/com/alibaba/json/demo/XAutowiredObjectSerializer.java @@ -0,0 +1,22 @@ +package com.alibaba.json.demo; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.Set; + +import com.alibaba.fastjson.serializer.AutowiredObjectSerializer; +import com.alibaba.fastjson.serializer.JSONSerializer; + + +public class XAutowiredObjectSerializer implements AutowiredObjectSerializer { + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + + } + + public Set getAutowiredFor() { + return Collections.singleton(X.class); + } + +} diff --git a/src/test/java/com/alibaba/json/test/Base64.java b/src/test/java/com/alibaba/json/test/Base64.java new file mode 100755 index 0000000000..70ce078c30 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/Base64.java @@ -0,0 +1,575 @@ +package com.alibaba.json.test; + +import java.util.Arrays; + +/** A very fast and memory efficient class to encode and decode to and from BASE64 in full accordance + * with RFC 2045.

+ * On Windows XP sp1 with 1.4.2_04 and later ;), this encoder and decoder is about 10 times faster + * on small arrays (10 - 1000 bytes) and 2-3 times as fast on larger arrays (10000 - 1000000 bytes) + * compared to sun.misc.Encoder()/Decoder().

+ * + * On byte arrays the encoder is about 20% faster than Jakarta Commons Base64 Codec for encode and + * about 50% faster for decoding large arrays. This implementation is about twice as fast on very small + * arrays (< 30 bytes). If source/destination is a String this + * version is about three times as fast due to the fact that the Commons Codec result has to be recoded + * to a String from byte[], which is very expensive.

+ * + * This encode/decode algorithm doesn't create any temporary arrays as many other codecs do, it only + * allocates the resulting array. This produces less garbage and it is possible to handle arrays twice + * as large as algorithms that create a temporary array. (E.g. Jakarta Commons Codec). It is unknown + * whether Sun's sun.misc.Encoder()/Decoder() produce temporary arrays but since performance + * is quite low it probably does.

+ * + * The encoder produces the same output as the Sun one except that the Sun's encoder appends + * a trailing line separator if the last character isn't a pad. Unclear why but it only adds to the + * length and is probably a side effect. Both are in conformance with RFC 2045 though.
+ * Commons codec seem to always att a trailing line separator.

+ * + * Note! + * The encode/decode method pairs (types) come in three versions with the exact same algorithm and + * thus a lot of code redundancy. This is to not create any temporary arrays for transcoding to/from different + * format types. The methods not used can simply be commented out.

+ * + * There is also a "fast" version of all decode methods that works the same way as the normal ones, but + * har a few demands on the decoded input. Normally though, these fast verions should be used if the source if + * the input is known and it hasn't bee tampered with.

+ * + * If you find the code useful or you find a bug, please send me a note at base64 @ miginfocom . com. + * + * Licence (BSD): + * ============== + * + * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (base64 @ miginfocom . com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * Neither the name of the MiG InfoCom AB nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * @version 2.2 + * @author Mikael Grev + * Date: 2004-aug-02 + * Time: 11:31:11 + */ + +public class Base64 +{ + private static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); + private static final int[] IA = new int[256]; + static { + Arrays.fill(IA, -1); + for (int i = 0, iS = CA.length; i < iS; i++) + IA[CA[i]] = i; + IA['='] = 0; + } + + // **************************************************************************************** + // * char[] version + // **************************************************************************************** + + /** Encodes a raw byte array into a BASE64 char[] representation i accordance with RFC 2045. + * @param sArr The bytes to convert. If null or length 0 an empty array will be returned. + * @param lineSep Optional "\r\n" after 76 characters, unless end of file.
+ * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a + * little faster. + * @return A BASE64 encoded array. Never null. + */ + public final static char[] encodeToChar(byte[] sArr, boolean lineSep) + { + // Check special case + int sLen = sArr != null ? sArr.length : 0; + if (sLen == 0) + return new char[0]; + + int eLen = (sLen / 3) * 3; // Length of even 24-bits. + int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count + int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array + char[] dArr = new char[dLen]; + + // Encode even 24-bits + for (int s = 0, d = 0, cc = 0; s < eLen;) { + // Copy next three bytes into lower 24 bits of int, paying attension to sign. + int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff); + + // Encode the int into four chars + dArr[d++] = CA[(i >>> 18) & 0x3f]; + dArr[d++] = CA[(i >>> 12) & 0x3f]; + dArr[d++] = CA[(i >>> 6) & 0x3f]; + dArr[d++] = CA[i & 0x3f]; + + // Add optional line separator + if (lineSep && ++cc == 19 && d < dLen - 2) { + dArr[d++] = '\r'; + dArr[d++] = '\n'; + cc = 0; + } + } + + // Pad and encode last bits if source isn't even 24 bits. + int left = sLen - eLen; // 0 - 2. + if (left > 0) { + // Prepare the int + int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0); + + // Set last four chars + dArr[dLen - 4] = CA[i >> 12]; + dArr[dLen - 3] = CA[(i >>> 6) & 0x3f]; + dArr[dLen - 2] = left == 2 ? CA[i & 0x3f] : '='; + dArr[dLen - 1] = '='; + } + return dArr; + } + + /** Decodes a BASE64 encoded char array. All illegal characters will be ignored and can handle both arrays with + * and without line separators. + * @param sArr The source array. null or length 0 will return an empty array. + * @return The decoded array of bytes. May be of length 0. Will be null if the legal characters + * (including '=') isn't divideable by 4. (I.e. definitely corrupted). + */ + public final static byte[] decode(char[] sArr) + { + // Check special case + int sLen = sArr != null ? sArr.length : 0; + if (sLen == 0) + return new byte[0]; + + // Count illegal characters (including '\r', '\n') to know what size the returned array will be, + // so we don't have to reallocate & copy it later. + int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...) + for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out. + if (IA[sArr[i]] < 0) + sepCnt++; + + // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045. + if ((sLen - sepCnt) % 4 != 0) + return null; + + int pad = 0; + for (int i = sLen; i > 1 && IA[sArr[--i]] <= 0;) + if (sArr[i] == '=') + pad++; + + int len = ((sLen - sepCnt) * 6 >> 3) - pad; + + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + for (int s = 0, d = 0; d < len;) { + // Assemble three bytes into an int from four "valid" characters. + int i = 0; + for (int j = 0; j < 4; j++) { // j only increased if a valid char was found. + int c = IA[sArr[s++]]; + if (c >= 0) + i |= c << (18 - j * 6); + else + j--; + } + // Add the bytes + dArr[d++] = (byte) (i >> 16); + if (d < len) { + dArr[d++]= (byte) (i >> 8); + if (d < len) + dArr[d++] = (byte) i; + } + } + return dArr; + } + + /** Decodes a BASE64 encoded char array that is known to be resonably well formatted. The method is about twice as + * fast as {@link #decode(char[])}. The preconditions are:
+ * + The array must have a line length of 76 chars OR no line separators at all (one line).
+ * + Line separator must be "\r\n", as specified in RFC 2045 + * + The array must not contain illegal characters within the encoded string
+ * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.
+ * @param sArr The source array. Length 0 will return an empty array. null will throw an exception. + * @return The decoded array of bytes. May be of length 0. + */ + public final static byte[] decodeFast(char[] sArr) + { + // Check special case + int sLen = sArr.length; + if (sLen == 0) + return new byte[0]; + + int sIx = 0, eIx = sLen - 1; // Start and end index after trimming. + + // Trim illegal chars from start + while (sIx < eIx && IA[sArr[sIx]] < 0) + sIx++; + + // Trim illegal chars from end + while (eIx > 0 && IA[sArr[eIx]] < 0) + eIx--; + + // get the padding count (=) (0, 1 or 2) + int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end. + int cCnt = eIx - sIx + 1; // Content count including possible separators + int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0; + + int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + // Decode all but the last 0 - 2 bytes. + int d = 0; + for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) { + // Assemble three bytes into an int from four "valid" characters. + int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]]; + + // Add the bytes + dArr[d++] = (byte) (i >> 16); + dArr[d++] = (byte) (i >> 8); + dArr[d++] = (byte) i; + + // If line separator, jump over it. + if (sepCnt > 0 && ++cc == 19) { + sIx += 2; + cc = 0; + } + } + + if (d < len) { + // Decode last 1-3 bytes (incl '=') into 1-3 bytes + int i = 0; + for (int j = 0; sIx <= eIx - pad; j++) + i |= IA[sArr[sIx++]] << (18 - j * 6); + + for (int r = 16; d < len; r -= 8) + dArr[d++] = (byte) (i >> r); + } + + return dArr; + } + + // **************************************************************************************** + // * byte[] version + // **************************************************************************************** + + /** Encodes a raw byte array into a BASE64 byte[] representation i accordance with RFC 2045. + * @param sArr The bytes to convert. If null or length 0 an empty array will be returned. + * @param lineSep Optional "\r\n" after 76 characters, unless end of file.
+ * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a + * little faster. + * @return A BASE64 encoded array. Never null. + */ + public final static byte[] encodeToByte(byte[] sArr, boolean lineSep) + { + // Check special case + int sLen = sArr != null ? sArr.length : 0; + if (sLen == 0) + return new byte[0]; + + int eLen = (sLen / 3) * 3; // Length of even 24-bits. + int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count + int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array + byte[] dArr = new byte[dLen]; + + // Encode even 24-bits + for (int s = 0, d = 0, cc = 0; s < eLen;) { + // Copy next three bytes into lower 24 bits of int, paying attension to sign. + int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff); + + // Encode the int into four chars + dArr[d++] = (byte) CA[(i >>> 18) & 0x3f]; + dArr[d++] = (byte) CA[(i >>> 12) & 0x3f]; + dArr[d++] = (byte) CA[(i >>> 6) & 0x3f]; + dArr[d++] = (byte) CA[i & 0x3f]; + + // Add optional line separator + if (lineSep && ++cc == 19 && d < dLen - 2) { + dArr[d++] = '\r'; + dArr[d++] = '\n'; + cc = 0; + } + } + + // Pad and encode last bits if source isn't an even 24 bits. + int left = sLen - eLen; // 0 - 2. + if (left > 0) { + // Prepare the int + int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0); + + // Set last four chars + dArr[dLen - 4] = (byte) CA[i >> 12]; + dArr[dLen - 3] = (byte) CA[(i >>> 6) & 0x3f]; + dArr[dLen - 2] = left == 2 ? (byte) CA[i & 0x3f] : (byte) '='; + dArr[dLen - 1] = '='; + } + return dArr; + } + + /** Decodes a BASE64 encoded byte array. All illegal characters will be ignored and can handle both arrays with + * and without line separators. + * @param sArr The source array. Length 0 will return an empty array. null will throw an exception. + * @return The decoded array of bytes. May be of length 0. Will be null if the legal characters + * (including '=') isn't divideable by 4. (I.e. definitely corrupted). + */ + public final static byte[] decode(byte[] sArr) + { + // Check special case + int sLen = sArr.length; + + // Count illegal characters (including '\r', '\n') to know what size the returned array will be, + // so we don't have to reallocate & copy it later. + int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...) + for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out. + if (IA[sArr[i] & 0xff] < 0) + sepCnt++; + + // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045. + if ((sLen - sepCnt) % 4 != 0) + return null; + + int pad = 0; + for (int i = sLen; i > 1 && IA[sArr[--i] & 0xff] <= 0;) + if (sArr[i] == '=') + pad++; + + int len = ((sLen - sepCnt) * 6 >> 3) - pad; + + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + for (int s = 0, d = 0; d < len;) { + // Assemble three bytes into an int from four "valid" characters. + int i = 0; + for (int j = 0; j < 4; j++) { // j only increased if a valid char was found. + int c = IA[sArr[s++] & 0xff]; + if (c >= 0) + i |= c << (18 - j * 6); + else + j--; + } + + // Add the bytes + dArr[d++] = (byte) (i >> 16); + if (d < len) { + dArr[d++]= (byte) (i >> 8); + if (d < len) + dArr[d++] = (byte) i; + } + } + + return dArr; + } + + + /** Decodes a BASE64 encoded byte array that is known to be resonably well formatted. The method is about twice as + * fast as {@link #decode(byte[])}. The preconditions are:
+ * + The array must have a line length of 76 chars OR no line separators at all (one line).
+ * + Line separator must be "\r\n", as specified in RFC 2045 + * + The array must not contain illegal characters within the encoded string
+ * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.
+ * @param sArr The source array. Length 0 will return an empty array. null will throw an exception. + * @return The decoded array of bytes. May be of length 0. + */ + public final static byte[] decodeFast(byte[] sArr) + { + // Check special case + int sLen = sArr.length; + if (sLen == 0) + return new byte[0]; + + int sIx = 0, eIx = sLen - 1; // Start and end index after trimming. + + // Trim illegal chars from start + while (sIx < eIx && IA[sArr[sIx] & 0xff] < 0) + sIx++; + + // Trim illegal chars from end + while (eIx > 0 && IA[sArr[eIx] & 0xff] < 0) + eIx--; + + // get the padding count (=) (0, 1 or 2) + int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end. + int cCnt = eIx - sIx + 1; // Content count including possible separators + int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0; + + int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + // Decode all but the last 0 - 2 bytes. + int d = 0; + for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) { + // Assemble three bytes into an int from four "valid" characters. + int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]]; + + // Add the bytes + dArr[d++] = (byte) (i >> 16); + dArr[d++] = (byte) (i >> 8); + dArr[d++] = (byte) i; + + // If line separator, jump over it. + if (sepCnt > 0 && ++cc == 19) { + sIx += 2; + cc = 0; + } + } + + if (d < len) { + // Decode last 1-3 bytes (incl '=') into 1-3 bytes + int i = 0; + for (int j = 0; sIx <= eIx - pad; j++) + i |= IA[sArr[sIx++]] << (18 - j * 6); + + for (int r = 16; d < len; r -= 8) + dArr[d++] = (byte) (i >> r); + } + + return dArr; + } + + // **************************************************************************************** + // * String version + // **************************************************************************************** + + /** Encodes a raw byte array into a BASE64 String representation i accordance with RFC 2045. + * @param sArr The bytes to convert. If null or length 0 an empty array will be returned. + * @param lineSep Optional "\r\n" after 76 characters, unless end of file.
+ * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a + * little faster. + * @return A BASE64 encoded array. Never null. + */ + public final static String encodeToString(byte[] sArr, boolean lineSep) + { + // Reuse char[] since we can't create a String incrementally anyway and StringBuffer/Builder would be slower. + return new String(encodeToChar(sArr, lineSep)); + } + + /** Decodes a BASE64 encoded String. All illegal characters will be ignored and can handle both strings with + * and without line separators.
+ * Note! It can be up to about 2x the speed to call decode(str.toCharArray()) instead. That + * will create a temporary array though. This version will use str.charAt(i) to iterate the string. + * @param str The source string. null or length 0 will return an empty array. + * @return The decoded array of bytes. May be of length 0. Will be null if the legal characters + * (including '=') isn't divideable by 4. (I.e. definitely corrupted). + */ + public final static byte[] decode(String str) + { + // Check special case + int sLen = str != null ? str.length() : 0; + if (sLen == 0) + return new byte[0]; + + // Count illegal characters (including '\r', '\n') to know what size the returned array will be, + // so we don't have to reallocate & copy it later. + int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...) + for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out. + if (IA[str.charAt(i)] < 0) + sepCnt++; + + // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045. + if ((sLen - sepCnt) % 4 != 0) + return null; + + // Count '=' at end + int pad = 0; + for (int i = sLen; i > 1 && IA[str.charAt(--i)] <= 0;) + if (str.charAt(i) == '=') + pad++; + + int len = ((sLen - sepCnt) * 6 >> 3) - pad; + + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + for (int s = 0, d = 0; d < len;) { + // Assemble three bytes into an int from four "valid" characters. + int i = 0; + for (int j = 0; j < 4; j++) { // j only increased if a valid char was found. + int c = IA[str.charAt(s++)]; + if (c >= 0) + i |= c << (18 - j * 6); + else + j--; + } + // Add the bytes + dArr[d++] = (byte) (i >> 16); + if (d < len) { + dArr[d++]= (byte) (i >> 8); + if (d < len) + dArr[d++] = (byte) i; + } + } + return dArr; + } + + /** Decodes a BASE64 encoded string that is known to be resonably well formatted. The method is about twice as + * fast as {@link #decode(String)}. The preconditions are:
+ * + The array must have a line length of 76 chars OR no line separators at all (one line).
+ * + Line separator must be "\r\n", as specified in RFC 2045 + * + The array must not contain illegal characters within the encoded string
+ * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.
+ * @param s The source string. Length 0 will return an empty array. null will throw an exception. + * @return The decoded array of bytes. May be of length 0. + */ + public final static byte[] decodeFast(String s) + { + // Check special case + int sLen = s.length(); + if (sLen == 0) + return new byte[0]; + + int sIx = 0, eIx = sLen - 1; // Start and end index after trimming. + + // Trim illegal chars from start + while (sIx < eIx && IA[s.charAt(sIx) & 0xff] < 0) + sIx++; + + // Trim illegal chars from end + while (eIx > 0 && IA[s.charAt(eIx) & 0xff] < 0) + eIx--; + + // get the padding count (=) (0, 1 or 2) + int pad = s.charAt(eIx) == '=' ? (s.charAt(eIx - 1) == '=' ? 2 : 1) : 0; // Count '=' at end. + int cCnt = eIx - sIx + 1; // Content count including possible separators + int sepCnt = sLen > 76 ? (s.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0; + + int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + // Decode all but the last 0 - 2 bytes. + int d = 0; + for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) { + // Assemble three bytes into an int from four "valid" characters. + int i = IA[s.charAt(sIx++)] << 18 | IA[s.charAt(sIx++)] << 12 | IA[s.charAt(sIx++)] << 6 | IA[s.charAt(sIx++)]; + + // Add the bytes + dArr[d++] = (byte) (i >> 16); + dArr[d++] = (byte) (i >> 8); + dArr[d++] = (byte) i; + + // If line separator, jump over it. + if (sepCnt > 0 && ++cc == 19) { + sIx += 2; + cc = 0; + } + } + + if (d < len) { + // Decode last 1-3 bytes (incl '=') into 1-3 bytes + int i = 0; + for (int j = 0; sIx <= eIx - pad; j++) + i |= IA[s.charAt(sIx++)] << (18 - j * 6); + + for (int r = 16; d < len; r -= 8) + dArr[d++] = (byte) (i >> r); + } + + return dArr; + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/test/Bug_0_Test.java b/src/test/java/com/alibaba/json/test/Bug_0_Test.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/CompositeDataTest.java b/src/test/java/com/alibaba/json/test/CompositeDataTest.java deleted file mode 100644 index cba575f3cf..0000000000 --- a/src/test/java/com/alibaba/json/test/CompositeDataTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.alibaba.json.test; - -import java.lang.management.ManagementFactory; -import java.util.Set; - -import javax.management.MBeanInfo; -import javax.management.MBeanServer; -import javax.management.ObjectInstance; -import javax.management.ObjectName; -import javax.management.openmbean.SimpleType; - -import junit.framework.TestCase; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.serializer.SerializerFeature; - -public class CompositeDataTest extends TestCase { - - public void test_0() throws Exception { - MBeanServer server = ManagementFactory.getPlatformMBeanServer(); - // Object value = server.getAttribute(new ObjectName("java.lang:type=Memory"), "HeapMemoryUsage"); - Object value = server.getAttribute(new ObjectName("com.sun.management:type=HotSpotDiagnostic"), "DiagnosticOptions"); - // Object value = server.getAttribute(new ObjectName("java.lang:type=GarbageCollector,name=ParNew"), - // "CollectionCount"); - - Object json = JSON.toJSON(value); - System.out.println(json); - - Set instances = server.queryMBeans(null, null); - System.out.println(JSON.toJSONString(instances)); - - for (ObjectInstance instance : instances) { - MBeanInfo mbeanInfo = server.getMBeanInfo(instance.getObjectName()); - System.out.println(JSON.toJSONString(mbeanInfo)); - } - - System.out.println(JSON.toJSONString(SimpleType.BOOLEAN)); - } - - public void test_1() throws Exception { - MBeanServer server = ManagementFactory.getPlatformMBeanServer(); - // Object value = server.getAttribute(new ObjectName("java.lang:type=Memory"), "HeapMemoryUsage"); - Object value = server.getAttribute(new ObjectName("com.sun.management:type=HotSpotDiagnostic"), "DiagnosticOptions"); - // Object value = server.getAttribute(new ObjectName("java.lang:type=GarbageCollector,name=ParNew"), - // "CollectionCount"); - - Object json = JSON.toJSON(value); - System.out.println(json); - - Set instances = server.queryMBeans(null, null); - System.out.println(JSON.toJSONString(instances, SerializerFeature.WriteMapNullValue)); - - for (ObjectInstance instance : instances) { - MBeanInfo mbeanInfo = server.getMBeanInfo(instance.getObjectName()); - System.out.println(JSON.toJSONString(mbeanInfo, SerializerFeature.WriteMapNullValue)); - } - - System.out.println(JSON.toJSONString(SimpleType.BOOLEAN, SerializerFeature.WriteMapNullValue)); - } -} diff --git a/src/test/java/com/alibaba/json/test/DateTest.java b/src/test/java/com/alibaba/json/test/DateTest.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/DetectProhibitChar.java b/src/test/java/com/alibaba/json/test/DetectProhibitChar.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/DigitTest.java b/src/test/java/com/alibaba/json/test/DigitTest.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/ErrorAppendable.java b/src/test/java/com/alibaba/json/test/ErrorAppendable.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/GenerateJavaTest.java b/src/test/java/com/alibaba/json/test/GenerateJavaTest.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/IntArrayFieldTest_primitive.java b/src/test/java/com/alibaba/json/test/IntArrayFieldTest_primitive.java old mode 100644 new mode 100755 index 93424d5f42..3694273fa7 --- a/src/test/java/com/alibaba/json/test/IntArrayFieldTest_primitive.java +++ b/src/test/java/com/alibaba/json/test/IntArrayFieldTest_primitive.java @@ -1,6 +1,6 @@ package com.alibaba.json.test; -import junit.framework.Assert; +import org.junit.Assert; import junit.framework.TestCase; import com.alibaba.fastjson.JSON; diff --git a/src/test/java/com/alibaba/json/test/JSONLibXmlTest.java b/src/test/java/com/alibaba/json/test/JSONLibXmlTest.java new file mode 100755 index 0000000000..b7f61db419 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/JSONLibXmlTest.java @@ -0,0 +1,26 @@ +package com.alibaba.json.test; + +import junit.framework.TestCase; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; +import net.sf.json.xml.XMLSerializer; + +public class JSONLibXmlTest extends TestCase { + public void test_xml() throws Exception { + XMLSerializer xmlSerializer = new XMLSerializer(); + + JSONObject json = new JSONObject(); + json.put("id", 123); + json.put("name", "jobs"); + json.put("flag", true); + + JSONArray items = new JSONArray(); + items.add("x"); + items.add(234); + items.add(false); + json.put("items", items); + + String text = xmlSerializer.write(json); + System.out.println(text); + } +} diff --git a/src/test/java/com/alibaba/json/test/JSONParser2Test.java b/src/test/java/com/alibaba/json/test/JSONParser2Test.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/SymbolTableDupTest.java b/src/test/java/com/alibaba/json/test/SymbolTableDupTest.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/TestASM.java b/src/test/java/com/alibaba/json/test/TestASM.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/TestFor_iteye_resolute.java b/src/test/java/com/alibaba/json/test/TestFor_iteye_resolute.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/TestSysProperty.java b/src/test/java/com/alibaba/json/test/TestSysProperty.java new file mode 100755 index 0000000000..fc82e9a58e --- /dev/null +++ b/src/test/java/com/alibaba/json/test/TestSysProperty.java @@ -0,0 +1,10 @@ +package com.alibaba.json.test; + +import junit.framework.TestCase; + + +public class TestSysProperty extends TestCase { + public void test_0 () throws Exception { + System.out.println(System.getProperty("java.vm.name")); + } +} diff --git a/src/test/java/com/alibaba/json/test/TestUtils.java b/src/test/java/com/alibaba/json/test/TestUtils.java new file mode 100755 index 0000000000..b0e122c0f3 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/TestUtils.java @@ -0,0 +1,149 @@ +package com.alibaba.json.test; + +import java.lang.management.ManagementFactory; + +import javax.management.MBeanServer; +import javax.management.ObjectName; + +import com.alibaba.fastjson.util.Base64; + +public class TestUtils { + + // **************************************************************************************** + // * char[] version + // **************************************************************************************** + + /** + * Encodes a raw byte array into a BASE64 char[] representation i accordance with RFC 2045. + * + * @param sArr The bytes to convert. If null or length 0 an empty array will be returned. + * @param lineSep Optional "\r\n" after 76 characters, unless end of file.
+ * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a little faster. + * @return A BASE64 encoded array. Never null. + */ + private final static char[] encodeToChar(byte[] sArr, boolean lineSep) { + char[] CA = Base64.CA; + + // Check special case + int sLen = sArr != null ? sArr.length : 0; + if (sLen == 0) return new char[0]; + + int eLen = (sLen / 3) * 3; // Length of even 24-bits. + int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count + int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array + char[] dArr = new char[dLen]; + + // Encode even 24-bits + for (int s = 0, d = 0, cc = 0; s < eLen;) { + // Copy next three bytes into lower 24 bits of int, paying attension to sign. + int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff); + + // Encode the int into four chars + dArr[d++] = CA[(i >>> 18) & 0x3f]; + dArr[d++] = CA[(i >>> 12) & 0x3f]; + dArr[d++] = CA[(i >>> 6) & 0x3f]; + dArr[d++] = CA[i & 0x3f]; + + // Add optional line separator + if (lineSep && ++cc == 19 && d < dLen - 2) { + dArr[d++] = '\r'; + dArr[d++] = '\n'; + cc = 0; + } + } + + // Pad and encode last bits if source isn't even 24 bits. + int left = sLen - eLen; // 0 - 2. + if (left > 0) { + // Prepare the int + int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0); + + // Set last four chars + dArr[dLen - 4] = CA[i >> 12]; + dArr[dLen - 3] = CA[(i >>> 6) & 0x3f]; + dArr[dLen - 2] = left == 2 ? CA[i & 0x3f] : '='; + dArr[dLen - 1] = '='; + } + return dArr; + } + + // **************************************************************************************** + // * String version + // **************************************************************************************** + + /** + * Encodes a raw byte array into a BASE64 String representation i accordance with RFC 2045. + * + * @param sArr The bytes to convert. If null or length 0 an empty array will be returned. + * @param lineSep Optional "\r\n" after 76 characters, unless end of file.
+ * No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a little faster. + * @return A BASE64 encoded array. Never null. + */ + public final static String encodeToBase64String(byte[] sArr, boolean lineSep) { + // Reuse char[] since we can't create a String incrementally anyway and StringBuffer/Builder would be slower. + return new String(encodeToChar(sArr, lineSep)); + } + + public static long getYoungGC() { + try { + // java.lang:type=GarbageCollector,name=G1 Young Generation + // java.lang:type=GarbageCollector,name=G1 Old Generation + MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); + ObjectName objectName; + if (mbeanServer.isRegistered(new ObjectName("java.lang:type=GarbageCollector,name=ParNew"))) { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=ParNew"); + } else if (mbeanServer.isRegistered(new ObjectName("java.lang:type=GarbageCollector,name=Copy"))) { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=Copy"); + } else if (mbeanServer.isRegistered(new ObjectName("java.lang:type=GarbageCollector,name=G1 Young Generation"))) { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=G1 Young Generation"); + } else { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=PS Scavenge"); + } + + return (Long) mbeanServer.getAttribute(objectName, "CollectionCount"); + } catch (Exception e) { + throw new RuntimeException("error"); + } + } + + public static long getYoungGCTime() { + try { + MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); + ObjectName objectName; + if (mbeanServer.isRegistered(new ObjectName("java.lang:type=GarbageCollector,name=ParNew"))) { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=ParNew"); + } else if (mbeanServer.isRegistered(new ObjectName("java.lang:type=GarbageCollector,name=Copy"))) { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=Copy"); + } else if (mbeanServer.isRegistered(new ObjectName("java.lang:type=GarbageCollector,name=G1 Young Generation"))) { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=G1 Young Generation"); + } else { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=PS Scavenge"); + } + + return (Long) mbeanServer.getAttribute(objectName, "CollectionTime"); + } catch (Exception e) { + throw new RuntimeException("error", e); + } + } + + public static long getFullGC() { + try { + MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); + ObjectName objectName; + + if (mbeanServer.isRegistered(new ObjectName("java.lang:type=GarbageCollector,name=ConcurrentMarkSweep"))) { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=ConcurrentMarkSweep"); + } else if (mbeanServer.isRegistered(new ObjectName("java.lang:type=GarbageCollector,name=MarkSweepCompact"))) { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=MarkSweepCompact"); + } else if (mbeanServer.isRegistered(new ObjectName("java.lang:type=GarbageCollector,name=G1 Old Generation"))) { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=G1 Old Generation"); + } else { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=PS MarkSweep"); + } + + return (Long) mbeanServer.getAttribute(objectName, "CollectionCount"); + } catch (Exception e) { + throw new RuntimeException("error"); + } + } +} diff --git a/src/test/java/com/alibaba/json/test/TestWriteSlashAsSpecial.java b/src/test/java/com/alibaba/json/test/TestWriteSlashAsSpecial.java new file mode 100755 index 0000000000..8f60f2ae6b --- /dev/null +++ b/src/test/java/com/alibaba/json/test/TestWriteSlashAsSpecial.java @@ -0,0 +1,35 @@ +package com.alibaba.json.test; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; + +@SuppressWarnings("deprecation") +public class TestWriteSlashAsSpecial extends TestCase { + + private int defaultValue = JSON.DEFAULT_GENERATE_FEATURE; + + protected void setUp() throws Exception { + defaultValue = JSON.DEFAULT_GENERATE_FEATURE; + } + + protected void tearDown() throws Exception { + JSON.DEFAULT_GENERATE_FEATURE = defaultValue; + } + + public void test_writeSlashAsSpecial() throws Exception { + JSON.DEFAULT_GENERATE_FEATURE = SerializerFeature.config(JSON.DEFAULT_GENERATE_FEATURE, + SerializerFeature.WriteSlashAsSpecial, true); + JSON.DEFAULT_GENERATE_FEATURE = SerializerFeature.config(JSON.DEFAULT_GENERATE_FEATURE, + SerializerFeature.WriteTabAsSpecial, true); + JSON.DEFAULT_GENERATE_FEATURE = SerializerFeature.config(JSON.DEFAULT_GENERATE_FEATURE, + SerializerFeature.DisableCircularReferenceDetect, true); + JSON.DEFAULT_GENERATE_FEATURE = SerializerFeature.config(JSON.DEFAULT_GENERATE_FEATURE, + SerializerFeature.SortField, false); + + Assert.assertEquals("\"\\/\"", JSON.toJSONString("/")); + } +} diff --git a/src/test/java/com/alibaba/json/test/a/Group.java b/src/test/java/com/alibaba/json/test/a/Group.java new file mode 100755 index 0000000000..e11b8a297d --- /dev/null +++ b/src/test/java/com/alibaba/json/test/a/Group.java @@ -0,0 +1,16 @@ +package com.alibaba.json.test.a; + +import java.util.List; + +public class Group { + + List uulist; + + public List getUulist() { + return uulist; + } + + public void setUulist(List uulist) { + this.uulist = uulist; + } +} diff --git a/src/test/java/com/alibaba/json/test/a/JTest.java b/src/test/java/com/alibaba/json/test/a/JTest.java new file mode 100755 index 0000000000..7c54c9c6cf --- /dev/null +++ b/src/test/java/com/alibaba/json/test/a/JTest.java @@ -0,0 +1,31 @@ +package com.alibaba.json.test.a; + + + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.fastjson.JSON; + +public class JTest { + + /** + * @param args + */ + public static void main(String[] args) { + List list = new ArrayList(); + User u1 = new User(1, "111111"); + User u2 = new User(2, "222222"); + User u3 = new User(3, "33333"); + User u4 = new User(4, "4444"); + list.add(new User[] { u1, u2 }); + list.add(new User[] { u3, u4 }); + Group clz = new Group(); + clz.setUulist(list); + String json = JSON.toJSONString(clz); + System.out.println(json); + Group clz1 = JSON.parseObject(json, Group.class); + System.out.println(clz1.getUulist().get(1)[1].getName()); + } + +} diff --git a/src/test/java/com/alibaba/json/test/a/User.java b/src/test/java/com/alibaba/json/test/a/User.java new file mode 100755 index 0000000000..227c79d900 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/a/User.java @@ -0,0 +1,36 @@ +package com.alibaba.json.test.a; + + +public class User{ + public User() { + } + public User(int age, String name) { + super(); + this.age = age; + this.name = name; + } + + private int age; + private String name; + + @Override + public String toString() { + return "User [age=" + age + ", name=" + name + "]"; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkCase.java b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkCase.java old mode 100644 new mode 100755 index 0a5c8dc09d..6e1761c654 --- a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkCase.java +++ b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkCase.java @@ -14,6 +14,10 @@ public BenchmarkCase(String name){ public String getName() { return name; } - + + public void init(Codec codec) throws Exception { + + } + public abstract void execute(Codec codec) throws Exception; } diff --git a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkExecutor.java b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkExecutor.java old mode 100644 new mode 100755 index c56664fe8f..64475af9cd --- a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkExecutor.java +++ b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkExecutor.java @@ -43,8 +43,17 @@ public void setLoopCount(int loopCount) { } public void execute() { + System.out.println(System.getProperty("java.vm.name") + " " + System.getProperty("java.runtime.version")); + for (BenchmarkCase benchmarkCase : caseList) { for (Codec codec : codecList) { + try { + benchmarkCase.init(codec); + } catch (Exception e) { + e.printStackTrace(); + break; + } + for (int i = 0; i < executeCount; ++i) { Result result = executeLoop(codec, benchmarkCase); handleResult(codec, result); @@ -60,13 +69,14 @@ public void handleResult(Codec codec, Result result) { return; } NumberFormat format = NumberFormat.getInstance(); - System.out.println(result.getName() + "\t" + codec.getName() + "\t" + format.format(result.getMillis()) + "\tYoungGC " + result.getYoungGC() - + "\tFullGC " + result.getFullGC()); + System.out.println(result.getName() + "\t" + codec.getName() + "\t" + format.format(result.getMillis()) + "\tYGC " + result.getYoungGC() + + "\tYGCT " + result.getYoungGCTime()); } private Result executeLoop(Codec codec, BenchmarkCase benchmarkCase) { long startMillis = System.currentTimeMillis(); long startYoungGC = getYoungGC(); + long startYoungGCTime = getYoungGCTime(); long startFullGC = getFullGC(); Throwable error = null; @@ -79,12 +89,14 @@ private Result executeLoop(Codec codec, BenchmarkCase benchmarkCase) { } long time = System.currentTimeMillis() - startMillis; long youngGC = getYoungGC() - startYoungGC; + long youngGCTime = getYoungGCTime() - startYoungGCTime; long fullGC = getFullGC() - startFullGC; Result result = new Result(); result.setName(benchmarkCase.getName()); result.setMillis(time); result.setYoungGC(youngGC); + result.setYoungGCTime(youngGCTime); result.setFullGC(fullGC); result.setError(error); @@ -93,12 +105,16 @@ private Result executeLoop(Codec codec, BenchmarkCase benchmarkCase) { public long getYoungGC() { try { + // java.lang:type=GarbageCollector,name=G1 Young Generation + // java.lang:type=GarbageCollector,name=G1 Old Generation MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); ObjectName objectName; if (mbeanServer.isRegistered(new ObjectName("java.lang:type=GarbageCollector,name=ParNew"))) { objectName = new ObjectName("java.lang:type=GarbageCollector,name=ParNew"); } else if (mbeanServer.isRegistered(new ObjectName("java.lang:type=GarbageCollector,name=Copy"))) { objectName = new ObjectName("java.lang:type=GarbageCollector,name=Copy"); + } else if (mbeanServer.isRegistered(new ObjectName("java.lang:type=GarbageCollector,name=G1 Young Generation"))) { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=G1 Young Generation"); } else { objectName = new ObjectName("java.lang:type=GarbageCollector,name=PS Scavenge"); } @@ -108,6 +124,26 @@ public long getYoungGC() { throw new RuntimeException("error"); } } + + public long getYoungGCTime() { + try { + MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); + ObjectName objectName; + if (mbeanServer.isRegistered(new ObjectName("java.lang:type=GarbageCollector,name=ParNew"))) { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=ParNew"); + } else if (mbeanServer.isRegistered(new ObjectName("java.lang:type=GarbageCollector,name=Copy"))) { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=Copy"); + } else if (mbeanServer.isRegistered(new ObjectName("java.lang:type=GarbageCollector,name=G1 Young Generation"))) { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=G1 Young Generation"); + } else { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=PS Scavenge"); + } + + return (Long) mbeanServer.getAttribute(objectName, "CollectionTime"); + } catch (Exception e) { + throw new RuntimeException("error", e); + } + } public long getFullGC() { try { @@ -118,6 +154,8 @@ public long getFullGC() { objectName = new ObjectName("java.lang:type=GarbageCollector,name=ConcurrentMarkSweep"); } else if (mbeanServer.isRegistered(new ObjectName("java.lang:type=GarbageCollector,name=MarkSweepCompact"))) { objectName = new ObjectName("java.lang:type=GarbageCollector,name=MarkSweepCompact"); + } else if (mbeanServer.isRegistered(new ObjectName("java.lang:type=GarbageCollector,name=G1 Old Generation"))) { + objectName = new ObjectName("java.lang:type=GarbageCollector,name=G1 Old Generation"); } else { objectName = new ObjectName("java.lang:type=GarbageCollector,name=PS MarkSweep"); } @@ -133,6 +171,7 @@ public static class Result { private String name; private long millis; private long youngGC; + private long youngGCTime; private long fullGC; private Throwable error; @@ -159,6 +198,14 @@ public long getYoungGC() { public void setYoungGC(long youngGC) { this.youngGC = youngGC; } + + public long getYoungGCTime() { + return youngGCTime; + } + + public void setYoungGCTime(long youngGCTime) { + this.youngGCTime = youngGCTime; + } public long getFullGC() { return fullGC; diff --git a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain.java b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain.java new file mode 100755 index 0000000000..f76e40e9ee --- /dev/null +++ b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain.java @@ -0,0 +1,57 @@ +package com.alibaba.json.test.benchmark; + +import com.alibaba.json.test.benchmark.decode.EishayDecode; +import com.alibaba.json.test.codec.FastjsonBeanToArrayCodec; + +public class BenchmarkMain { + public static void main(String[] args) throws Exception { + // 注意,byte[]在jackson中是使用base64编码的,不正确的。 + + BenchmarkExecutor executor = new BenchmarkExecutor(); + executor.setExecuteCount(5); +// executor.getCodecList().add(new FastjsonCodec()); + executor.getCodecList().add(new FastjsonBeanToArrayCodec()); +// executor.getCodecList().add(new JacksonCodec()); +// executor.getCodecList().add(new Jackson2Codec()); + // + // executor.getCodecList().add(new SimpleJsonCodec()); + // executor.getCodecList().add(new JsonLibCodec()); + // executor.getCodecList().add(new JsonSmartCodec()); + + executor.setLoopCount(1000 * 1000 * 1); + +// executor.getCaseList().add(new EishayDecodeBytes()); +// executor.getCaseList().add(new EishayDecode2Bytes()); + executor.getCaseList().add(new EishayDecode()); +// executor.getCaseList().add(new EishayDecodeByClassName()); +// executor.getCaseList().add(new EishayTreeDecode()); +// executor.getCaseList().add(new EishayEncode()); +// executor.getCaseList().add(new EishayEncodeManual()); + // executor.getCaseList().add(new IntArray1000Decode()); + // executor.getCaseList().add(new StringArray1000Decode()); + // executor.getCaseList().add(new Map1000StringDecode()); + // executor.getCaseList().add(new Entity100StringDecode()); + + // executor.getCaseList().add(new ListBoolean1000Encode()); + // executor.getCaseList().add(new ArrayBoolean1000Encode()); + // executor.getCaseList().add(new IntArray1000Decode()); + // executor.getCaseList().add(new StringArray1000Decode()); + // executor.getCaseList().add(new GroupEncode()); + // executor.getCaseList().add(new CategoryEncode()); + // executor.getCaseList().add(new GroupEncode()); + // executor.getCaseList().add(new Map1Decode()); + // executor.getCaseList().add(new Entity100IntDecode()); + // executor.getCaseList().add(new Entity100StringDecode()); + // executor.getCaseList().add(new Entity100IntEncode()); + // executor.getCaseList().add(new ArrayByte1000Encode()); + // executor.getCaseList().add(new ArrayInt1000Encode()); + // executor.getCaseList().add(new ArrayLong1000Encode()); + // executor.getCaseList().add(new ArrayString1000Encode()); + // executor.getCaseList().add(new ArrayEmptyList1000Encode()); + // executor.getCaseList().add(new ArrayEmptyMap1000Encode()); + // executor.getCaseList().add(new ArrayObjectEmptyMap1000Encode()); + // executor.getCaseList().add(new Map1000Encode()); + + executor.execute(); + } +} diff --git a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain_EishayDecode.java b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain_EishayDecode.java new file mode 100755 index 0000000000..6b75897550 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain_EishayDecode.java @@ -0,0 +1,51 @@ +package com.alibaba.json.test.benchmark; + +import java.lang.management.ManagementFactory; +import java.util.List; + +import com.alibaba.fastjson.JSON; +import com.alibaba.json.test.TestUtils; +import com.alibaba.json.test.benchmark.decode.EishayDecodeBytes; + +import data.media.MediaContent; + +public class BenchmarkMain_EishayDecode { + + public static void main(String[] args) throws Exception { + System.out.println(System.getProperty("java.vm.name") + " " + System.getProperty("java.runtime.version")); + List arguments = ManagementFactory.getRuntimeMXBean().getInputArguments(); + System.out.println(arguments); + + String text = EishayDecodeBytes.instance.getText(); + System.out.println(text); + + for (int i = 0; i < 10; ++i) { + perf(text); + } + } + + static long perf(String text) { + long startYGC = TestUtils.getYoungGC(); + long startYGCTime = TestUtils.getYoungGCTime(); + long startFGC = TestUtils.getFullGC(); + + long startMillis = System.currentTimeMillis(); + for (int i = 0; i < 1000 * 1000; ++i) { + decode(text); + } + long millis = System.currentTimeMillis() - startMillis; + + long ygc = TestUtils.getYoungGC() - startYGC; + long ygct = TestUtils.getYoungGCTime() - startYGCTime; + long fgc = TestUtils.getFullGC() - startFGC; + + System.out.println("decode\t" + millis + ", ygc " + ygc + ", ygct " + ygct + ", fgc " + fgc); + return millis; + } + + static void decode(String text) { + MediaContent content = JSON.parseObject(text, MediaContent.class); + +// JSON.parseObject(text); + } +} diff --git a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain_EishayDecode_WriteAsArray.java b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain_EishayDecode_WriteAsArray.java new file mode 100644 index 0000000000..26b4cf4a3d --- /dev/null +++ b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain_EishayDecode_WriteAsArray.java @@ -0,0 +1,68 @@ +package com.alibaba.json.test.benchmark; + +import java.lang.management.ManagementFactory; +import java.util.List; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.json.test.TestUtils; +import com.alibaba.json.test.benchmark.decode.EishayDecodeBytes; + +import data.media.Image; +import data.media.Media; +import data.media.MediaContent; +import data.media.writeAsArray.ImageSerializer; +import data.media.writeAsArray.MediaContentDeserializer; +import data.media.writeAsArray.MediaContentSerializer; +import data.media.writeAsArray.MediaSerializer; + +public class BenchmarkMain_EishayDecode_WriteAsArray { + + public static void main(String[] args) throws Exception { +// SerializeConfig config = SerializeConfig.getGlobalInstance(); +// config.put(MediaContent.class, new MediaContentSerializer()); +// config.put(Media.class, new MediaSerializer()); +// config.put(Image.class, new ImageSerializer()); + +// ParserConfig.getGlobalInstance().putDeserializer(MediaContent.class, new MediaContentDeserializer()); + + System.out.println(System.getProperty("java.vm.name") + " " + System.getProperty("java.runtime.version")); + List arguments = ManagementFactory.getRuntimeMXBean().getInputArguments(); + System.out.println(arguments); + + String text = JSON.toJSONString(EishayDecodeBytes.instance.getContent(), SerializerFeature.BeanToArray); + System.out.println(text); + + for (int i = 0; i < 10; ++i) { + perf(text); + } + } + + static long perf(String text) { + long startYGC = TestUtils.getYoungGC(); + long startYGCTime = TestUtils.getYoungGCTime(); + long startFGC = TestUtils.getFullGC(); + + long startMillis = System.currentTimeMillis(); + for (int i = 0; i < 1000 * 1000; ++i) { + decode(text); + } + long millis = System.currentTimeMillis() - startMillis; + + long ygc = TestUtils.getYoungGC() - startYGC; + long ygct = TestUtils.getYoungGCTime() - startYGCTime; + long fgc = TestUtils.getFullGC() - startFGC; + + System.out.println("decode\t" + millis + ", ygc " + ygc + ", ygct " + ygct + ", fgc " + fgc); + return millis; + } + + static void decode(String text) { + MediaContent content = JSON.parseObject(text, MediaContent.class, Feature.SupportArrayToBean); + +// JSON.parseObject(text); + } +} diff --git a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain_EishayEncode.java b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain_EishayEncode.java new file mode 100755 index 0000000000..13b42bcc99 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain_EishayEncode.java @@ -0,0 +1,51 @@ +package com.alibaba.json.test.benchmark; + +import java.lang.management.ManagementFactory; +import java.util.List; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.json.test.TestUtils; +import com.alibaba.json.test.benchmark.decode.EishayDecodeBytes; + +import data.media.MediaContent; + +public class BenchmarkMain_EishayEncode { + + public static void main(String[] args) throws Exception { + System.out.println(System.getProperty("java.vm.name") + " " + System.getProperty("java.runtime.version")); + List arguments = ManagementFactory.getRuntimeMXBean().getInputArguments(); + System.out.println(arguments); + + MediaContent content = EishayDecodeBytes.instance.getContent(); + String text = encode(content); + System.out.println(text); + + for (int i = 0; i < 10; ++i) { + perf(text); + } + } + + static long perf(Object obj) { + long startYGC = TestUtils.getYoungGC(); + long startYGCTime = TestUtils.getYoungGCTime(); + long startFGC = TestUtils.getFullGC(); + + long startMillis = System.currentTimeMillis(); + for (int i = 0; i < 1000 * 1000; ++i) { + encode(obj); + } + long millis = System.currentTimeMillis() - startMillis; + + long ygc = TestUtils.getYoungGC() - startYGC; + long ygct = TestUtils.getYoungGCTime() - startYGCTime; + long fgc = TestUtils.getFullGC() - startFGC; + + System.out.println("encode\t" + millis + ", ygc " + ygc + ", ygct " + ygct + ", fgc " + fgc); + return millis; + } + + static String encode(Object text) { + return JSON.toJSONString(text, SerializerFeature.BeanToArray); + } +} diff --git a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain_EishayEncode_WriteAsArray.java b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain_EishayEncode_WriteAsArray.java new file mode 100644 index 0000000000..a729e9c479 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkMain_EishayEncode_WriteAsArray.java @@ -0,0 +1,61 @@ +package com.alibaba.json.test.benchmark; + +import java.lang.management.ManagementFactory; +import java.util.List; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.json.test.TestUtils; +import com.alibaba.json.test.benchmark.decode.EishayDecodeBytes; + +import data.media.Image; +import data.media.Media; +import data.media.MediaContent; +import data.media.writeAsArray.ImageSerializer; +import data.media.writeAsArray.MediaContentSerializer; +import data.media.writeAsArray.MediaSerializer; + +public class BenchmarkMain_EishayEncode_WriteAsArray { + + public static void main(String[] args) throws Exception { + SerializeConfig config = SerializeConfig.getGlobalInstance(); + config.put(MediaContent.class, new MediaContentSerializer()); + config.put(Media.class, new MediaSerializer()); + config.put(Image.class, new ImageSerializer()); + + System.out.println(System.getProperty("java.vm.name") + " " + System.getProperty("java.runtime.version")); + List arguments = ManagementFactory.getRuntimeMXBean().getInputArguments(); + System.out.println(arguments); + + MediaContent content = EishayDecodeBytes.instance.getContent(); + String text = encode(content); + System.out.println(text); + + for (int i = 0; i < 10; ++i) { + perf(text); + } + } + + static long perf(Object obj) { + long startYGC = TestUtils.getYoungGC(); + long startYGCTime = TestUtils.getYoungGCTime(); + long startFGC = TestUtils.getFullGC(); + + long startMillis = System.currentTimeMillis(); + for (int i = 0; i < 1000 * 1000; ++i) { + encode(obj); + } + long millis = System.currentTimeMillis() - startMillis; + + long ygc = TestUtils.getYoungGC() - startYGC; + long ygct = TestUtils.getYoungGCTime() - startYGCTime; + long fgc = TestUtils.getFullGC() - startFGC; + + System.out.println("encode\t" + millis + ", ygc " + ygc + ", ygct " + ygct + ", fgc " + fgc); + return millis; + } + + static String encode(Object text) { + return JSON.toJSONString(text); + } +} diff --git a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkTest.java b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkTest.java old mode 100644 new mode 100755 index da4fb9c4d0..6bab9f457b --- a/src/test/java/com/alibaba/json/test/benchmark/BenchmarkTest.java +++ b/src/test/java/com/alibaba/json/test/benchmark/BenchmarkTest.java @@ -2,56 +2,9 @@ import junit.framework.TestCase; -import com.alibaba.json.test.benchmark.decode.EishayDecode; -import com.alibaba.json.test.codec.FastjsonCodec; - public class BenchmarkTest extends TestCase { public void test_benchmark() throws Exception { - // 注意,byte[]在jackson中是使用base64编码的,不正确的。 - - BenchmarkExecutor executor = new BenchmarkExecutor(); - executor.setExecuteCount(10); - executor.getCodecList().add(new FastjsonCodec()); -// executor.getCodecList().add(new JacksonCodec()); - // - // executor.getCodecList().add(new SimpleJsonCodec()); - // executor.getCodecList().add(new JsonLibCodec()); - // executor.getCodecList().add(new JsonSmartCodec()); - - executor.setLoopCount(1000 * 1000); - - //executor.getCaseList().add(new EishayDecodeBytes()); -// executor.getCaseList().add(new EishayDecode2Bytes()); - executor.getCaseList().add(new EishayDecode()); -// executor.getCaseList().add(new EishayTreeDecode()); -// executor.getCaseList().add(new EishayEncode()); -// executor.getCaseList().add(new EishayEncodeManual()); - // executor.getCaseList().add(new IntArray1000Decode()); - // executor.getCaseList().add(new StringArray1000Decode()); - // executor.getCaseList().add(new Map1000StringDecode()); - // executor.getCaseList().add(new Entity100StringDecode()); - - // executor.getCaseList().add(new ListBoolean1000Encode()); - // executor.getCaseList().add(new ArrayBoolean1000Encode()); - // executor.getCaseList().add(new IntArray1000Decode()); - // executor.getCaseList().add(new StringArray1000Decode()); - // executor.getCaseList().add(new GroupEncode()); - // executor.getCaseList().add(new CategoryEncode()); - // executor.getCaseList().add(new GroupEncode()); - // executor.getCaseList().add(new Map1Decode()); - // executor.getCaseList().add(new Entity100IntDecode()); - // executor.getCaseList().add(new Entity100StringDecode()); - // executor.getCaseList().add(new Entity100IntEncode()); - // executor.getCaseList().add(new ArrayByte1000Encode()); - // executor.getCaseList().add(new ArrayInt1000Encode()); - // executor.getCaseList().add(new ArrayLong1000Encode()); - // executor.getCaseList().add(new ArrayString1000Encode()); - // executor.getCaseList().add(new ArrayEmptyList1000Encode()); - // executor.getCaseList().add(new ArrayEmptyMap1000Encode()); - // executor.getCaseList().add(new ArrayObjectEmptyMap1000Encode()); - // executor.getCaseList().add(new Map1000Encode()); - - executor.execute(); + BenchmarkMain.main(new String[]{}); } } diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/BooleanArray1000Decode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/BooleanArray1000Decode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecode.java old mode 100644 new mode 100755 index b993b6a50e..0bf32b8b59 --- a/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecode.java +++ b/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecode.java @@ -7,16 +7,18 @@ public class EishayDecode extends BenchmarkCase { - private final String text; + private String text; public EishayDecode(){ super("EishayDecode"); - this.text = EishayDecodeBytes.instance.getText(); + // JavaBeanMapping.getGlobalInstance().putDeserializer(Image.class, new ImageDeserializer()); + // JavaBeanMapping.getGlobalInstance().putDeserializer(Media.class, new MediaDeserializer()); + } + + public void init(Codec codec) throws Exception { + this.text = codec.encode(EishayDecodeBytes.instance.getContent()); System.out.println(text); - - //JavaBeanMapping.getGlobalInstance().putDeserializer(Image.class, new ImageDeserializer()); - //JavaBeanMapping.getGlobalInstance().putDeserializer(Media.class, new MediaDeserializer()); } @Override diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecode2Bytes.java b/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecode2Bytes.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecodeByClassName.java b/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecodeByClassName.java new file mode 100755 index 0000000000..2367287501 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecodeByClassName.java @@ -0,0 +1,34 @@ +package com.alibaba.json.test.benchmark.decode; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.json.test.benchmark.BenchmarkCase; +import com.alibaba.json.test.codec.Codec; + +import data.media.MediaContent; + +public class EishayDecodeByClassName extends BenchmarkCase { + + private final String text; + + public EishayDecodeByClassName(){ + super("EishayDecode"); + + text = JSON.toJSONString(EishayDecodeBytes.instance.getContent(), SerializerFeature.WriteEnumUsingToString, + SerializerFeature.SortField, SerializerFeature.WriteClassName); + System.out.println(text); + System.out.println(); + + // JavaBeanMapping.getGlobalInstance().putDeserializer(Image.class, new ImageDeserializer()); + // JavaBeanMapping.getGlobalInstance().putDeserializer(Media.class, new MediaDeserializer()); + } + + @Override + public void execute(Codec codec) throws Exception { + MediaContent content = codec.decodeObject(text, MediaContent.class); + if (content == null) { + throw new Exception(); + } + } + +} diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecodeBytes.java b/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecodeBytes.java old mode 100644 new mode 100755 index 25a7753196..a0352a4749 --- a/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecodeBytes.java +++ b/src/test/java/com/alibaba/json/test/benchmark/decode/EishayDecodeBytes.java @@ -22,7 +22,9 @@ public class EishayDecodeBytes extends BenchmarkCase { private final byte[] bytes; private final char[] chars; - private final String text; + private final String text; + + private final MediaContent content; public byte[] getBytes() { return bytes; @@ -31,28 +33,32 @@ public byte[] getBytes() { public char[] getChars() { return chars; } - + public String getText() { return text; } + public MediaContent getContent() { + return content; + } + public EishayDecodeBytes(){ super("EishayDecode-Byte[]"); - MediaContent content = new MediaContent(); + content = new MediaContent(); Media media = new Media(); - media.uri = "http://javaone.com/keynote.mpg"; - media.title = "Javaone Keynote"; - media.width = 640; - media.height = 480; - media.format = "video/mpg4"; - media.duration = 18000000; - media.size = 58982400; - media.bitrate = 262144; - media.persons = Arrays.asList("Bill Gates", "Steve Jobs"); - media.player = Player.JAVA; - media.copyright = null; + media.setUri("http://javaone.com/keynote.mpg"); + media.setTitle("Javaone Keynote"); + media.setWidth(640); + media.setHeight(480); + media.setFormat("video/mpg4"); + media.setDuration(18000000); + media.setSize(58982400); + media.setBitrate(262144); + media.setPersons(Arrays.asList("Bill Gates", "Steve Jobs")); + media.setPlayer(Player.JAVA); + media.setCopyright(null); content.setMedia(media); diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/EishayTreeDecode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/EishayTreeDecode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/Entity100IntDecode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/Entity100IntDecode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/Entity100StringDecode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/Entity100StringDecode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/GroupDecode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/GroupDecode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/IntArray1000Decode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/IntArray1000Decode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/Map1000StringDecode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/Map1000StringDecode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/Map1Decode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/Map1Decode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/decode/StringArray1000Decode.java b/src/test/java/com/alibaba/json/test/benchmark/decode/StringArray1000Decode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayBoolean1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayBoolean1000Encode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayByte1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayByte1000Encode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayEmptyList1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayEmptyList1000Encode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayEmptyMap1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayEmptyMap1000Encode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayInt1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayInt1000Encode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayLong1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayLong1000Encode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayObjectEmptyMap1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayObjectEmptyMap1000Encode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayString1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ArrayString1000Encode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/CategoryEncode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/CategoryEncode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/EishayEncode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/EishayEncode.java old mode 100644 new mode 100755 index 50ab32a775..5b840a3d03 --- a/src/test/java/com/alibaba/json/test/benchmark/encode/EishayEncode.java +++ b/src/test/java/com/alibaba/json/test/benchmark/encode/EishayEncode.java @@ -19,17 +19,17 @@ public class EishayEncode extends BenchmarkCase { static { Media media = new Media(); - media.uri = "http://javaone.com/keynote.mpg"; - media.title = "Javaone Keynote"; - media.width = 640; - media.height = 480; - media.format = "video/mpg4"; - media.duration = 18000000; - media.size = 58982400; - media.bitrate = 262144; - media.persons = Arrays.asList("Bill Gates", "Steve Jobs"); - media.player = Player.JAVA; - media.copyright = null; + media.setUri("http://javaone.com/keynote.mpg"); + media.setTitle("Javaone Keynote"); + media.setWidth(640); + media.setHeight(480); + media.setFormat("video/mpg4"); + media.setDuration(18000000); + media.setSize(58982400); + media.setBitrate(262144); + media.setPersons(Arrays.asList("Bill Gates", "Steve Jobs")); + media.setPlayer(Player.JAVA); + media.setCopyright(null); mediaContent.media = media; diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/Entity100IntEncode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/Entity100IntEncode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/GroupEncode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/GroupEncode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/ListBoolean1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/ListBoolean1000Encode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/encode/Map1000Encode.java b/src/test/java/com/alibaba/json/test/benchmark/encode/Map1000Encode.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/entity/Entity100Int.java b/src/test/java/com/alibaba/json/test/benchmark/entity/Entity100Int.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/benchmark/entity/Entity100String.java b/src/test/java/com/alibaba/json/test/benchmark/entity/Entity100String.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/bvt/CharTypesTest.java b/src/test/java/com/alibaba/json/test/bvt/CharTypesTest.java deleted file mode 100644 index d5938f2ce2..0000000000 --- a/src/test/java/com/alibaba/json/test/bvt/CharTypesTest.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.alibaba.json.test.bvt; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import com.alibaba.fastjson.parser.CharTypes; - -public class CharTypesTest extends TestCase { - - public void test_0() throws Exception { - Assert.assertTrue(CharTypes.isSpecial_doubleQuotes('\n')); - Assert.assertTrue(CharTypes.isSpecial_doubleQuotes('\r')); - Assert.assertTrue(CharTypes.isSpecial_doubleQuotes('\b')); - Assert.assertTrue(CharTypes.isSpecial_doubleQuotes('\f')); - Assert.assertTrue(CharTypes.isSpecial_doubleQuotes('\"')); - Assert.assertFalse(CharTypes.isSpecial_doubleQuotes('0')); - Assert.assertFalse(CharTypes.isSpecial_doubleQuotes('\0')); - Assert.assertFalse(CharTypes.isSpecial_doubleQuotes('中')); - Assert.assertFalse(CharTypes.isSpecial_doubleQuotes('中')); - } -} diff --git a/src/test/java/com/alibaba/json/test/bvt/TimestampTest.java b/src/test/java/com/alibaba/json/test/bvt/TimestampTest.java deleted file mode 100644 index fcae0381ab..0000000000 --- a/src/test/java/com/alibaba/json/test/bvt/TimestampTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.alibaba.json.test.bvt; - - -import java.sql.Timestamp; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import com.alibaba.fastjson.JSON; - -public class TimestampTest extends TestCase { - public void test_0 () throws Exception { - long millis = System.currentTimeMillis(); - - Assert.assertEquals(new Timestamp(millis), JSON.parseObject("" + millis, Timestamp.class)); - Assert.assertEquals(new Timestamp(millis), JSON.parseObject("\"" + millis + "\"", Timestamp.class)); - } -} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_1.java b/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_1.java deleted file mode 100644 index 0a8f815940..0000000000 --- a/src/test/java/com/alibaba/json/test/bvt/parser/DefaultExtJSONParserTest_1.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.alibaba.json.test.bvt.parser; - -import java.math.BigDecimal; -import java.math.BigInteger; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.json.test.entity.TestEntity; - -public class DefaultExtJSONParserTest_1 extends TestCase { - - public void test_0() throws Exception { - DefaultExtJSONParser parser = new DefaultExtJSONParser("{\"f1\":true}"); - TestEntity entity = parser.parseObject(TestEntity.class); - Assert.assertEquals(true, entity.isF1()); - } - - public void test_1() throws Exception { - DefaultExtJSONParser parser = new DefaultExtJSONParser("{\"f2\":true}"); - TestEntity entity = parser.parseObject(TestEntity.class); - Assert.assertEquals(Boolean.TRUE, entity.getF2()); - } - - public void test_2() throws Exception { - TestEntity e0 = new TestEntity(); - e0.setF1(true); - e0.setF2(Boolean.TRUE); - e0.setF3((byte) 123); - e0.setF4((byte) 123); - e0.setF5((short) 123); - e0.setF6((short) 123); - e0.setF7((int) 123); - e0.setF8((int) 123); - e0.setF9((long) 123); - e0.setF10((long) 123); - e0.setF11(new BigInteger("123")); - e0.setF12(new BigDecimal("123")); - e0.setF13("abc"); - e0.setF14(null); - e0.setF15(12.34F); - e0.setF16(12.34F); - e0.setF17(12.345D); - e0.setF18(12.345D); - - String text = JSON.toJSONString(e0); - System.out.println(text); - - TestEntity e1 = new TestEntity(); - { - DefaultExtJSONParser parser = new DefaultExtJSONParser(text); - parser.parseObject(e1); - } - - Assert.assertEquals(e0.isF1(), e1.isF1()); - Assert.assertEquals(e0.getF2(), e1.getF2()); - Assert.assertEquals(e0.getF3(), e1.getF3()); - Assert.assertEquals(e0.getF4(), e1.getF4()); - Assert.assertEquals(e0.getF5(), e1.getF5()); - Assert.assertEquals(e0.getF6(), e1.getF6()); - Assert.assertEquals(e0.getF7(), e1.getF7()); - Assert.assertEquals(e0.getF8(), e1.getF8()); - Assert.assertEquals(e0.getF9(), e1.getF9()); - Assert.assertEquals(e0.getF10(), e1.getF10()); - Assert.assertEquals(e0.getF11(), e1.getF11()); - Assert.assertEquals(e0.getF12(), e1.getF12()); - Assert.assertEquals(e0.getF13(), e1.getF13()); - Assert.assertEquals(e0.getF14(), e1.getF14()); - Assert.assertEquals(e0.getF15(), e1.getF15()); - Assert.assertEquals(e0.getF16(), e1.getF16()); - Assert.assertEquals(e0.getF17(), e1.getF17()); - Assert.assertEquals(e0.getF18(), e1.getF18()); - - } -} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/FastMatchCheckTest.java b/src/test/java/com/alibaba/json/test/bvt/parser/FastMatchCheckTest.java deleted file mode 100644 index b9801fa606..0000000000 --- a/src/test/java/com/alibaba/json/test/bvt/parser/FastMatchCheckTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.alibaba.json.test.bvt.parser; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.parser.deserializer.ArrayDeserializer; -import com.alibaba.fastjson.parser.deserializer.ArrayListStringDeserializer; -import com.alibaba.fastjson.parser.deserializer.AtomicIntegerArrayDeserializer; -import com.alibaba.fastjson.parser.deserializer.AtomicLongArrayDeserializer; -import com.alibaba.fastjson.parser.deserializer.CharacterDeserializer; -import com.alibaba.fastjson.parser.deserializer.CharsetDeserializer; -import com.alibaba.fastjson.parser.deserializer.FileDeserializer; -import com.alibaba.fastjson.parser.deserializer.InetAddressDeserializer; -import com.alibaba.fastjson.parser.deserializer.InetSocketAddressDeserializer; -import com.alibaba.fastjson.parser.deserializer.JSONArrayDeserializer; -import com.alibaba.fastjson.parser.deserializer.JSONObjectDeserializer; -import com.alibaba.fastjson.parser.deserializer.LinkedHashMapDeserializer; -import com.alibaba.fastjson.parser.deserializer.LocaleDeserializer; -import com.alibaba.fastjson.parser.deserializer.NumberDeserializer; -import com.alibaba.fastjson.parser.deserializer.TimestampDeserializer; -import com.alibaba.fastjson.parser.deserializer.TreeMapDeserializer; - -public class FastMatchCheckTest extends TestCase { - public void test_match() throws Exception { - Assert.assertEquals(JSONToken.LBRACKET, AtomicIntegerArrayDeserializer.instance.getFastMatchToken()); - Assert.assertEquals(JSONToken.LBRACKET, ArrayListStringDeserializer.instance.getFastMatchToken()); - Assert.assertEquals(JSONToken.LBRACKET, AtomicLongArrayDeserializer.instance.getFastMatchToken()); - Assert.assertEquals(JSONToken.LITERAL_STRING, InetAddressDeserializer.instance.getFastMatchToken()); - Assert.assertEquals(JSONToken.LITERAL_STRING, LocaleDeserializer.instance.getFastMatchToken()); - Assert.assertEquals(JSONToken.LITERAL_INT, NumberDeserializer.instance.getFastMatchToken()); - Assert.assertEquals(JSONToken.LITERAL_INT, TimestampDeserializer.instance.getFastMatchToken()); - Assert.assertEquals(JSONToken.LITERAL_STRING, CharsetDeserializer.instance.getFastMatchToken()); - Assert.assertEquals(JSONToken.LITERAL_STRING, FileDeserializer.instance.getFastMatchToken()); - Assert.assertEquals(JSONToken.LBRACE, LinkedHashMapDeserializer.instance.getFastMatchToken()); - Assert.assertEquals(JSONToken.LBRACE, TreeMapDeserializer.instance.getFastMatchToken()); - Assert.assertEquals(JSONToken.LBRACKET, JSONArrayDeserializer.instance.getFastMatchToken()); - Assert.assertEquals(JSONToken.LBRACKET, ArrayDeserializer.instance.getFastMatchToken()); - Assert.assertEquals(JSONToken.LBRACE, JSONObjectDeserializer.instance.getFastMatchToken()); - Assert.assertEquals(JSONToken.LBRACE, InetSocketAddressDeserializer.instance.getFastMatchToken()); - Assert.assertEquals(JSONToken.LITERAL_STRING, CharacterDeserializer.instance.getFastMatchToken()); - } -} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/SymbolTableTest.java b/src/test/java/com/alibaba/json/test/bvt/parser/SymbolTableTest.java deleted file mode 100644 index 631ab84c83..0000000000 --- a/src/test/java/com/alibaba/json/test/bvt/parser/SymbolTableTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.alibaba.json.test.bvt.parser; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import com.alibaba.fastjson.parser.SymbolTable; - -public class SymbolTableTest extends TestCase { - - public void test_0() throws Exception { - SymbolTable table = new SymbolTable(); - Assert.assertEquals("true", table.addSymbol("true")); - } - - - public void test_dup() throws Exception { - String[] array = new String[] { "uIX", "thX", "uHw", "tgw" }; - SymbolTable table = new SymbolTable(); - for (String symbol : array) { - Assert.assertEquals(symbol, table.addSymbol(symbol)); - } - } -} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/BigIntegerDeserializerTest.java b/src/test/java/com/alibaba/json/test/bvt/parser/deser/BigIntegerDeserializerTest.java deleted file mode 100644 index 79c21dd09e..0000000000 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/BigIntegerDeserializerTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.alibaba.json.test.bvt.parser.deser; - -import java.math.BigInteger; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.BigIntegerDeserializer; - -public class BigIntegerDeserializerTest extends TestCase { - public void test_null() throws Exception { - String input = "null"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - BigIntegerDeserializer deser = new BigIntegerDeserializer(); - - Assert.assertNull(deser.deserialze(parser, null)); - } - - public void test_1() throws Exception { - - BigInteger value = JSON.parseObject("'123'", BigInteger.class); - - Assert.assertEquals(new BigInteger("123"), value); - } -} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/ConcurrentHashMapDeserializerTest.java b/src/test/java/com/alibaba/json/test/bvt/parser/deser/ConcurrentHashMapDeserializerTest.java deleted file mode 100644 index 6a35875fc7..0000000000 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/ConcurrentHashMapDeserializerTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.alibaba.json.test.bvt.parser.deser; - -import java.util.concurrent.ConcurrentHashMap; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.parser.deserializer.ConcurrentHashMapDeserializer; - -public class ConcurrentHashMapDeserializerTest extends TestCase { - @SuppressWarnings("rawtypes") - public void test_0 () throws Exception { - ConcurrentHashMap map = JSON.parseObject("{}", ConcurrentHashMap.class); - Assert.assertEquals(0, map.size()); - Assert.assertEquals(JSONToken.LBRACE, ConcurrentHashMapDeserializer.instance.getFastMatchToken()); - } - - @SuppressWarnings("rawtypes") - public void test_1 () throws Exception { - ConcurrentHashMap map = JSON.parseObject("null", ConcurrentHashMap.class); - Assert.assertEquals(null, map); - } -} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/DefaultObjectDeserializerTest.java b/src/test/java/com/alibaba/json/test/bvt/parser/deser/DefaultObjectDeserializerTest.java deleted file mode 100644 index 607e8af6b1..0000000000 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/DefaultObjectDeserializerTest.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.alibaba.json.test.bvt.parser.deser; - -import java.util.HashMap; -import java.util.Map; -import java.util.TreeMap; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.TypeReference; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.DefaultObjectDeserializer; - -public class DefaultObjectDeserializerTest extends TestCase { - - public void test_0() throws Exception { - String input = "{map:{}}"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - Map map = new HashMap(); - deser.parseMap(parser, map, new TypeReference() { - }.getType()); - Assert.assertTrue(map.get("map") instanceof TreeMap); - } - - public void test_1() throws Exception { - String input = "{map:{},,,}"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - Map map = new HashMap(); - deser.parseMap(parser, map, new TypeReference() { - }.getType()); - Assert.assertTrue(map.get("map") instanceof TreeMap); - Assert.assertEquals(1, map.size()); - } - - public void test_error() throws Exception { - String input = "[}"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - Map map = new HashMap(); - - JSONException error = null; - try { - deser.parseMap(parser, map, new TypeReference() { - }.getType()); - } catch (JSONException ex) { - error = ex; - } - Assert.assertNotNull(error); - } - - public void test_error_1() throws Exception { - String input = "{]"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - Map map = new HashMap(); - - JSONException error = null; - try { - deser.parseMap(parser, map, new TypeReference() { - }.getType()); - } catch (JSONException ex) { - error = ex; - } - Assert.assertNotNull(error); - } - - public void test_error_2() throws Exception { - String input = "{map:{},,,}"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), 0); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - Map map = new HashMap(); - - JSONException error = null; - try { - deser.parseMap(parser, map, new TypeReference() { - }.getType()); - } catch (JSONException ex) { - error = ex; - } - Assert.assertNotNull(error); - } - - public void test_error_3() throws Exception { - String input = "{map:{}}"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), 0); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - Map map = new HashMap(); - - JSONException error = null; - try { - deser.parseMap(parser, map, new TypeReference() { - }.getType()); - } catch (JSONException ex) { - error = ex; - } - Assert.assertNotNull(error); - } -} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/DefaultObjectDeserializerTest1.java b/src/test/java/com/alibaba/json/test/bvt/parser/deser/DefaultObjectDeserializerTest1.java deleted file mode 100644 index 59b3351d37..0000000000 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/DefaultObjectDeserializerTest1.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.alibaba.json.test.bvt.parser.deser; - -import java.util.HashMap; -import java.util.Map; -import java.util.TreeMap; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.TypeReference; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.DefaultObjectDeserializer; - -public class DefaultObjectDeserializerTest1 extends TestCase { - - public void test_0() throws Exception { - String input = "{'map':{}}"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - Map map = new HashMap(); - deser.parseMap(parser, map, new TypeReference() { - }.getType()); - Assert.assertTrue(map.get("map") instanceof TreeMap); - } - - public void test_1() throws Exception { - String input = "{'map':null}"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - Map map = new HashMap(); - deser.parseMap(parser, map, new TypeReference() { - }.getType()); - Assert.assertTrue(map.get("map") == null); - } - - public void test_error_0() throws Exception { - - String input = "{\"map\" {} }"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - Throwable error = null; - - try { - Map map = new HashMap(); - deser.parseMap(parser, map, new TypeReference() { - }.getType()); - } catch (Throwable ex) { - error = ex; - } - - Assert.assertNotNull(error); - } - - public void test_error_1() throws Exception { - String input = "{'map': 'aaa' }"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), 0); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - Throwable error = null; - - try { - Map map = new HashMap(); - deser.parseMap(parser, map, new TypeReference() { - }.getType()); - } catch (Throwable ex) { - error = ex; - } - - Assert.assertNotNull(error); - } - - public void test_error_2() throws Exception { - String input = "{'map' 'aaa' }"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - Throwable error = null; - - try { - Map map = new HashMap(); - deser.parseMap(parser, map, new TypeReference() { - }.getType()); - } catch (Throwable ex) { - error = ex; - } - - Assert.assertNotNull(error); - } - - public void test_error_3() throws Exception { - String input = "{map 'aaa' }"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - Throwable error = null; - - try { - Map map = new HashMap(); - deser.parseMap(parser, map, new TypeReference() { - }.getType()); - } catch (Throwable ex) { - error = ex; - } - - Assert.assertNotNull(error); - } -} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/DefaultObjectDeserializerTest2.java b/src/test/java/com/alibaba/json/test/bvt/parser/deser/DefaultObjectDeserializerTest2.java deleted file mode 100644 index 0e40dbd38d..0000000000 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/DefaultObjectDeserializerTest2.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.alibaba.json.test.bvt.parser.deser; - -import java.util.HashMap; -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import com.alibaba.fastjson.TypeReference; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.DefaultObjectDeserializer; - -public class DefaultObjectDeserializerTest2 extends TestCase { - - public void test_0() throws Exception { - String input = "{'map':{}}"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - Map map = JSON.parseObject(input, new TypeReference>() { - }.getType()); - - Assert.assertTrue(map.get("map") instanceof TreeMap); - } - - public void test_1() throws Exception { - String input = "{'map':{}}"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - - SortedMap map = JSON.parseObject(input, new TypeReference>() { - }.getType()); - - Assert.assertEquals(TreeMap.class, map.get("map").getClass()); - } - - public void test_2() throws Exception { - String input = "{'map':{}}"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - SortedMap map = JSON.parseObject(input, new TypeReference>() { - }.getType()); - - Assert.assertEquals(HashMap.class, map.get("map").getClass()); - } - - public void test_3() throws Exception { - String input = "{'map':{}}"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - SortedMap map = JSON.parseObject(input, new TypeReference>() { - }.getType()); - - Assert.assertEquals(ConcurrentHashMap.class, map.get("map").getClass()); - } - - public void test_4() throws Exception { - String input = "{'map':{}}"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - SortedMap map = JSON.parseObject(input, new TypeReference>() { - }.getType()); - - Assert.assertEquals(HashMap.class, map.get("map").getClass()); - } - - public void test_5() throws Exception { - String input = "{'map':{}}"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - HashMap map = JSON.parseObject(input, new TypeReference>() { - }.getType()); - - Assert.assertEquals(HashMap.class, map.get("map").getClass()); - } - - public void test_6() throws Exception { - String input = "{'map':{}}"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - Map map = JSON.parseObject(input, new TypeReference() { - }.getType()); - - Assert.assertEquals(JSONObject.class, map.get("map").getClass()); - } - - public void test_7() throws Exception { - String input = "{'map':{}}"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - TreeMap map = JSON.parseObject(input, new TypeReference>() { - }.getType()); - - Assert.assertEquals(HashMap.class, map.get("map").getClass()); - } - - public void test_8() throws Exception { - String input = "{'map':{}}"; - - ConcurrentMap map = JSON.parseObject(input, new TypeReference>() { - }.getType()); - - Assert.assertEquals(HashMap.class, map.get("map").getClass()); - } - - public void test_error() throws Exception { - String input = "{'map':{}}"; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), JSON.DEFAULT_PARSER_FEATURE); - - DefaultObjectDeserializer deser = new DefaultObjectDeserializer(); - - Exception error = null; - try { - JSON.parseObject(input, new TypeReference>() { - }.getType()); - } catch (Exception ex) { - error = ex; - } - Assert.assertNotNull(error); - } - - public static interface Map1 extends Map { - - } -} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldDeserializerTest3.java b/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldDeserializerTest3.java deleted file mode 100644 index 2a1f97f275..0000000000 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldDeserializerTest3.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.alibaba.json.test.bvt.parser.deser; - -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.List; -import java.util.TreeMap; -import java.util.concurrent.ConcurrentHashMap; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import org.codehaus.jackson.type.TypeReference; - -import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.DefaultObjectDeserializer; - -public class FieldDeserializerTest3 extends TestCase { - - public void test_error_1() throws Exception { - Exception error = null; - try { - String input = "{\"value\":null}"; - int featureValues = 0; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), - featureValues); - - Entity object = new Entity(); - parser.parseObject(object); - } catch (JSONException ex) { - error = ex; - } - Assert.assertNotNull(error); - } - - public void test_error_2() throws Exception { - Exception error = null; - try { - String input = "{,,\"value\":null}"; - int featureValues = 0; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), - featureValues); - - Entity object = new Entity(); - parser.parseObject(object); - } catch (JSONException ex) { - error = ex; - } - Assert.assertNotNull(error); - } - - public void test_error_3() throws Exception { - Exception error = null; - try { - Type type = new TypeReference>() { - }.getType(); - - String input = "{,,\"value\":null}"; - int featureValues = 0; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), - featureValues); - - DefaultObjectDeserializer objectDeser = new DefaultObjectDeserializer(); - objectDeser.deserialze(parser, ((ParameterizedType) type).getActualTypeArguments()[0]); - } catch (JSONException ex) { - error = ex; - } - Assert.assertNotNull(error); - } - - public void test_error_4() throws Exception { - Exception error = null; - try { - Type type = new TypeReference>() { - }.getType(); - - String input = "{,,\"value\":null}"; - int featureValues = 0; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), - featureValues); - - DefaultObjectDeserializer objectDeser = new DefaultObjectDeserializer(); - objectDeser.deserialze(parser, ((ParameterizedType) type).getActualTypeArguments()[0]); - } catch (JSONException ex) { - error = ex; - } - Assert.assertNotNull(error); - } - - public void test_error_5() throws Exception { - Exception error = null; - try { - Type type = new TypeReference>>() { - }.getType(); - - String input = "{,,\"value\":null}"; - int featureValues = 0; - DefaultExtJSONParser parser = new DefaultExtJSONParser(input, ParserConfig.getGlobalInstance(), - featureValues); - - DefaultObjectDeserializer objectDeser = new DefaultObjectDeserializer(); - objectDeser.deserialze(parser, ((ParameterizedType) type).getActualTypeArguments()[0]); - } catch (JSONException ex) { - error = ex; - } - Assert.assertNotNull(error); - } - - public void test_null() throws Exception { - int featureValues = 0; - DefaultExtJSONParser parser = new DefaultExtJSONParser("null", ParserConfig.getGlobalInstance(), featureValues); - - DefaultObjectDeserializer objectDeser = new DefaultObjectDeserializer(); - Object value = objectDeser.deserialze(parser, Class.class); - Assert.assertNull(value); - } - - public void test_hashmap() throws Exception { - int featureValues = 0; - DefaultExtJSONParser parser = new DefaultExtJSONParser("{}", ParserConfig.getGlobalInstance(), featureValues); - - DefaultObjectDeserializer objectDeser = new DefaultObjectDeserializer(); - HashMap value = objectDeser.deserialze(parser, HashMap.class); - Assert.assertEquals(0, value.size()); - } - - public void test_treeMap() throws Exception { - int featureValues = 0; - DefaultExtJSONParser parser = new DefaultExtJSONParser("{}", ParserConfig.getGlobalInstance(), featureValues); - - DefaultObjectDeserializer objectDeser = new DefaultObjectDeserializer(); - TreeMap value = objectDeser.deserialze(parser, TreeMap.class); - Assert.assertEquals(0, value.size()); - } - - public void test_concurrentMap() throws Exception { - int featureValues = 0; - DefaultExtJSONParser parser = new DefaultExtJSONParser("{}", ParserConfig.getGlobalInstance(), featureValues); - - DefaultObjectDeserializer objectDeser = new DefaultObjectDeserializer(); - ConcurrentHashMap value = objectDeser.deserialze(parser, ConcurrentHashMap.class); - Assert.assertEquals(0, value.size()); - } - - public void test_concurrentMap_error() throws Exception { - int featureValues = 0; - DefaultExtJSONParser parser = new DefaultExtJSONParser("{[[[", ParserConfig.getGlobalInstance(), featureValues); - - DefaultObjectDeserializer objectDeser = new DefaultObjectDeserializer(); - Exception error = null; - try { - ConcurrentHashMap value = objectDeser.deserialze(parser, ConcurrentHashMap.class); - } catch (JSONException ex) { - error = ex; - } - Assert.assertNotNull(error); - } - - private static class Entity { - - private String value; - - public String getValue() { - return value; - } - - public void setValue(String value) { - throw new RuntimeException(); - } - - } - -} diff --git a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldDeserializerTest4.java b/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldDeserializerTest4.java deleted file mode 100644 index 1c18f9bfe3..0000000000 --- a/src/test/java/com/alibaba/json/test/bvt/parser/deser/FieldDeserializerTest4.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.alibaba.json.test.bvt.parser.deser; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.Feature; -import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.DefaultObjectDeserializer; - -public class FieldDeserializerTest4 extends TestCase { - - - public void test_error_0() throws Exception { - int featureValues = 0; - DefaultExtJSONParser parser = new DefaultExtJSONParser("{", ParserConfig.getGlobalInstance(), featureValues); - parser.config(Feature.AllowUnQuotedFieldNames, true); - - Entity object = new Entity(); - DefaultObjectDeserializer objectDeser = new DefaultObjectDeserializer(); - Exception error = null; - try { - objectDeser.parseObject(parser, object); - } catch (JSONException ex) { - error = ex; - } - Assert.assertNotNull(error); - } - - public void test_error_1() throws Exception { - int featureValues = 0; - DefaultExtJSONParser parser = new DefaultExtJSONParser("{\"value\":null", ParserConfig.getGlobalInstance(), featureValues); - parser.config(Feature.AllowUnQuotedFieldNames, true); - - Entity object = new Entity(); - DefaultObjectDeserializer objectDeser = new DefaultObjectDeserializer(); - Exception error = null; - try { - objectDeser.parseObject(parser, object); - } catch (JSONException ex) { - error = ex; - } - Assert.assertNotNull(error); - } - - private static class Entity { - - private String value; - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - } - -} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/ObjectNameSerializerTest.java b/src/test/java/com/alibaba/json/test/bvt/serializer/ObjectNameSerializerTest.java deleted file mode 100644 index 47bf6ee7d3..0000000000 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/ObjectNameSerializerTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.alibaba.json.test.bvt.serializer; - -import javax.management.ObjectName; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import com.alibaba.fastjson.JSON; - -public class ObjectNameSerializerTest extends TestCase { - public void test_objectName() throws Exception { - ObjectName name = new ObjectName("com.alibaba:type=A"); - String text = JSON.toJSONString(name); - Assert.assertEquals("\"com.alibaba:type=A\"", text); - } -} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/ParserConfigTest.java b/src/test/java/com/alibaba/json/test/bvt/serializer/ParserConfigTest.java deleted file mode 100644 index 1b24e55dca..0000000000 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/ParserConfigTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.alibaba.json.test.bvt.serializer; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import com.alibaba.fastjson.JSONException; -import com.alibaba.fastjson.parser.ParserConfig; - -public class ParserConfigTest extends TestCase { - - public void test_0() throws Exception { - ParserConfig config = new ParserConfig(); - config.getDerializers(); - } - - public void test_error_0() throws Exception { - ParserConfig config = new ParserConfig(); - - Exception error = null; - try { - config.createJavaBeanDeserializer(int.class); - } catch (JSONException ex) { - error = ex; - } - Assert.assertNotNull(error); - } -} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeConfigTest.java b/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeConfigTest.java deleted file mode 100644 index fae72963bb..0000000000 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/SerializeConfigTest.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.alibaba.json.test.bvt.serializer; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import com.alibaba.fastjson.serializer.SerializeConfig; - -public class SerializeConfigTest extends TestCase { - - public void test_0() throws Exception { - SerializeConfig config = new SerializeConfig(); - - Exception error = null; - try { - config.createJavaBeanSerializer(int.class); - } catch (Exception ex) { - error = ex; - } - Assert.assertNotNull(error); - } -} diff --git a/src/test/java/com/alibaba/json/test/bvt/serializer/ShortArraySerializerTest.java b/src/test/java/com/alibaba/json/test/bvt/serializer/ShortArraySerializerTest.java deleted file mode 100644 index f24bcacbc2..0000000000 --- a/src/test/java/com/alibaba/json/test/bvt/serializer/ShortArraySerializerTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.alibaba.json.test.bvt.serializer; - -import junit.framework.TestCase; - -import org.junit.Assert; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.serializer.SerializeWriter; - -public class ShortArraySerializerTest extends TestCase { - - public void test_0() { - Assert.assertEquals("[]", JSON.toJSONString(new short[0])); - Assert.assertEquals("[1,2]", JSON.toJSONString(new short[] { 1, 2 })); - Assert.assertEquals("[1,2,3]", JSON.toJSONString(new short[] { 1, 2, 3 })); - } - - public void test_1() throws Exception { - SerializeWriter out = new SerializeWriter(1); - out.writeShortArray(new short[] { 1, 2, 3 }); - Assert.assertEquals("[1,2,3]", out.toString()); - } - - public void test_2() throws Exception { - SerializeWriter out = new SerializeWriter(100); - out.writeShortArray(new short[] { 1, 2, 3 }); - Assert.assertEquals("[1,2,3]", out.toString()); - } -} diff --git a/src/test/java/com/alibaba/json/test/bvt/util/FieldInfoTest.java b/src/test/java/com/alibaba/json/test/bvt/util/FieldInfoTest.java deleted file mode 100644 index 6ed6568d73..0000000000 --- a/src/test/java/com/alibaba/json/test/bvt/util/FieldInfoTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.alibaba.json.test.bvt.util; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import com.alibaba.fastjson.annotation.JSONField; -import com.alibaba.fastjson.util.FieldInfo; - -public class FieldInfoTest extends TestCase { - public void test_null() throws Exception { - FieldInfo fieldInfo = new FieldInfo("getValue", - Entity.class.getMethod("getValue"), null); - Assert.assertEquals(null, fieldInfo.getAnnotation(JSONField.class)); - } - - public static class Entity { - private int value; - - public int getValue() { - return value; - } - - public void setValue(int value) { - this.value = value; - } - - } -} diff --git a/src/test/java/com/alibaba/json/test/codec/Codec.java b/src/test/java/com/alibaba/json/test/codec/Codec.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/codec/FastjsonBeanToArrayCodec.java b/src/test/java/com/alibaba/json/test/codec/FastjsonBeanToArrayCodec.java new file mode 100644 index 0000000000..62349a7e75 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/codec/FastjsonBeanToArrayCodec.java @@ -0,0 +1,74 @@ +package com.alibaba.json.test.codec; + +import java.util.Collection; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.PropertyFilter; +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class FastjsonBeanToArrayCodec implements Codec { + + private ParserConfig config = ParserConfig.getGlobalInstance(); + + public String getName() { + return "fastjson-bean-to-array"; + } + + public T decodeObject(String text, Class clazz) { + DefaultExtJSONParser parser = new DefaultExtJSONParser(text, config); + parser.config(Feature.DisableCircularReferenceDetect, true); + parser.config(Feature.SupportArrayToBean, true); + return parser.parseObject(clazz); + } + + public Collection decodeArray(String text, Class clazz) throws Exception { + DefaultExtJSONParser parser = new DefaultExtJSONParser(text, config); + parser.config(Feature.DisableCircularReferenceDetect, true); + parser.config(Feature.SupportArrayToBean, true); + return parser.parseArray(clazz); + } + + public final Object decodeObject(String text) { + DefaultJSONParser parser = new DefaultJSONParser(text, config); + parser.config(Feature.DisableCircularReferenceDetect, true); + parser.config(Feature.SupportArrayToBean, true); + return parser.parse(); + } + + public final Object decode(String text) { + DefaultJSONParser parser = new DefaultJSONParser(text, config); + parser.config(Feature.DisableCircularReferenceDetect, true); + parser.config(Feature.SupportArrayToBean, true); + return parser.parse(); + } + + // private JavaBeanSerializer serializer = new JavaBeanSerializer(Long_100_Entity.class); + + public String encode(Object object) throws Exception { + SerializeWriter out = new SerializeWriter(); + out.config(SerializerFeature.DisableCircularReferenceDetect, true); + out.config(SerializerFeature.BeanToArray, true); +// out.config(SerializerFeature.DisableCheckSpecialChar, true); + + JSONSerializer serializer = new JSONSerializer(out); + serializer.write(object); + + String text = out.toString(); + + out.close(); + + return text; + } + + @SuppressWarnings("unchecked") + public T decodeObject(byte[] input, Class clazz) throws Exception { + return (T) JSON.parseObject(input, clazz, Feature.SupportArrayToBean, Feature.DisableCircularReferenceDetect); + } + +} diff --git a/src/test/java/com/alibaba/json/test/codec/FastjsonCodec.java b/src/test/java/com/alibaba/json/test/codec/FastjsonCodec.java old mode 100644 new mode 100755 index 0732817c94..5875477e07 --- a/src/test/java/com/alibaba/json/test/codec/FastjsonCodec.java +++ b/src/test/java/com/alibaba/json/test/codec/FastjsonCodec.java @@ -5,9 +5,12 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.DefaultExtJSONParser; import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.PropertyFilter; import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; public class FastjsonCodec implements Codec { @@ -19,21 +22,25 @@ public String getName() { public T decodeObject(String text, Class clazz) { DefaultExtJSONParser parser = new DefaultExtJSONParser(text, config); + parser.config(Feature.DisableCircularReferenceDetect, true); return parser.parseObject(clazz); } public Collection decodeArray(String text, Class clazz) throws Exception { DefaultExtJSONParser parser = new DefaultExtJSONParser(text, config); + parser.config(Feature.DisableCircularReferenceDetect, true); return parser.parseArray(clazz); } public final Object decodeObject(String text) { DefaultJSONParser parser = new DefaultJSONParser(text, config); + parser.config(Feature.DisableCircularReferenceDetect, true); return parser.parse(); } public final Object decode(String text) { DefaultJSONParser parser = new DefaultJSONParser(text, config); + parser.config(Feature.DisableCircularReferenceDetect, true); return parser.parse(); } @@ -41,8 +48,11 @@ public final Object decode(String text) { public String encode(Object object) throws Exception { SerializeWriter out = new SerializeWriter(); + out.config(SerializerFeature.DisableCircularReferenceDetect, true); +// out.config(SerializerFeature.DisableCheckSpecialChar, true); - JSONSerializer.write(out, object); + JSONSerializer serializer = new JSONSerializer(out); + serializer.write(object); String text = out.toString(); @@ -53,7 +63,7 @@ public String encode(Object object) throws Exception { @SuppressWarnings("unchecked") public T decodeObject(byte[] input, Class clazz) throws Exception { - return (T) JSON.parseObject(input, clazz); + return (T) JSON.parseObject(input, clazz, Feature.DisableCircularReferenceDetect); } } diff --git a/src/test/java/com/alibaba/json/test/codec/GsonCodec.java b/src/test/java/com/alibaba/json/test/codec/GsonCodec.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/codec/Jackson2Codec.java b/src/test/java/com/alibaba/json/test/codec/Jackson2Codec.java new file mode 100755 index 0000000000..c0e58ce9f7 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/codec/Jackson2Codec.java @@ -0,0 +1,63 @@ +package com.alibaba.json.test.codec; + +import java.util.Collection; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + + +public class Jackson2Codec implements Codec { + + private ObjectMapper mapper = new ObjectMapper(); + + public String getName() { + return "jackson2"; + } + + public final T decodeObject(String text, Class clazz) { + try { + return mapper.readValue(text, clazz); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + + public T decodeObject(byte[] input, Class clazz) throws Exception { + try { + return mapper.readValue(input, clazz); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + public Collection decodeArray(String text, Class clazz) throws Exception { + try { + return (Collection) mapper.readValue(text, new TypeReference() { + }); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + public final Object decodeObject(String text) { + try { + return (ObjectNode) mapper.readTree(text); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + public Object decode(String text) { + try { + return mapper.readTree(text); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + public String encode(Object object) throws Exception { + return mapper.writeValueAsString(object); + } +} diff --git a/src/test/java/com/alibaba/json/test/codec/JacksonCodec.java b/src/test/java/com/alibaba/json/test/codec/JacksonCodec.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/codec/JsonLibCodec.java b/src/test/java/com/alibaba/json/test/codec/JsonLibCodec.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/codec/JsonSmartCodec.java b/src/test/java/com/alibaba/json/test/codec/JsonSmartCodec.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/codec/SimpleJsonCodec.java b/src/test/java/com/alibaba/json/test/codec/SimpleJsonCodec.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/dubbo/EnumTest.java b/src/test/java/com/alibaba/json/test/dubbo/EnumTest.java new file mode 100755 index 0000000000..857c472477 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/dubbo/EnumTest.java @@ -0,0 +1,8 @@ +package com.alibaba.json.test.dubbo; + +public enum EnumTest { + + Pig, + Dog, + Cat +} diff --git a/src/test/java/com/alibaba/json/test/dubbo/FullAddress.java b/src/test/java/com/alibaba/json/test/dubbo/FullAddress.java new file mode 100755 index 0000000000..63d926ea3c --- /dev/null +++ b/src/test/java/com/alibaba/json/test/dubbo/FullAddress.java @@ -0,0 +1,204 @@ +/** + * Project: morgan.domain + * + * File Created at 2009-6-11 + * $Id: FullAddress.java 77622 2011-03-03 08:31:45Z ding.lid $ + * + * Copyright 2008 Alibaba.com Croporation Limited. + * All rights reserved. + * + * This software is the confidential and proprietary information of + * Alibaba Company. ("Confidential Information"). You shall not + * disclose such Confidential Information and shall use it only in + * accordance with the terms of the license agreement you entered into + * with Alibaba.com. + */ +package com.alibaba.json.test.dubbo; + +import java.io.Serializable; + +/** + * @author xk1430 + */ +public class FullAddress implements Serializable { + + private static final long serialVersionUID = 5163979984269419831L; + + private String countryId; + + private String countryName; + + private String provinceName; + + private String cityId; + + private String cityName; + + private String streetAddress; + + private String zipCode; + + public void setCountryId(String countryId) { + this.countryId = countryId; + } + + public void setCountryName(String countryName) { + this.countryName = countryName; + } + + public void setProvinceName(String provinceName) { + this.provinceName = provinceName; + } + + public void setCityId(String cityId) { + this.cityId = cityId; + } + + public void setCityName(String cityName) { + this.cityName = cityName; + } + + public void setStreetAddress(String streetAddress) { + this.streetAddress = streetAddress; + } + + public void setZipCode(String zipCode) { + this.zipCode = zipCode; + } + + public String getCountryId() { + return countryId; + } + + public String getCountryName() { + return countryName; + } + + public String getProvinceName() { + return provinceName; + } + + public String getCityId() { + return cityId; + } + + public String getCityName() { + return cityName; + } + + public String getStreetAddress() { + return streetAddress; + } + + public String getZipCode() { + return zipCode; + } + + public FullAddress() { + } + + public FullAddress(String countryId, String provinceName, String cityId, String streetAddress, + String zipCode) { + this.countryId = countryId; + this.countryName = countryId; + this.provinceName = provinceName; + this.cityId = cityId; + this.cityName = cityId; + this.streetAddress = streetAddress; + this.zipCode = zipCode; + } + + public FullAddress(String countryId, String countryName, String provinceName, String cityId, + String cityName, String streetAddress, String zipCode) { + this.countryId = countryId; + this.countryName = countryName; + this.provinceName = provinceName; + this.cityId = cityId; + this.cityName = cityName; + this.streetAddress = streetAddress; + this.zipCode = zipCode; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((cityId == null) ? 0 : cityId.hashCode()); + result = prime * result + ((cityName == null) ? 0 : cityName.hashCode()); + result = prime * result + ((countryId == null) ? 0 : countryId.hashCode()); + result = prime * result + ((countryName == null) ? 0 : countryName.hashCode()); + result = prime * result + ((provinceName == null) ? 0 : provinceName.hashCode()); + result = prime * result + ((streetAddress == null) ? 0 : streetAddress.hashCode()); + result = prime * result + ((zipCode == null) ? 0 : zipCode.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + FullAddress other = (FullAddress) obj; + if (cityId == null) { + if (other.cityId != null) + return false; + } else if (!cityId.equals(other.cityId)) + return false; + if (cityName == null) { + if (other.cityName != null) + return false; + } else if (!cityName.equals(other.cityName)) + return false; + if (countryId == null) { + if (other.countryId != null) + return false; + } else if (!countryId.equals(other.countryId)) + return false; + if (countryName == null) { + if (other.countryName != null) + return false; + } else if (!countryName.equals(other.countryName)) + return false; + if (provinceName == null) { + if (other.provinceName != null) + return false; + } else if (!provinceName.equals(other.provinceName)) + return false; + if (streetAddress == null) { + if (other.streetAddress != null) + return false; + } else if (!streetAddress.equals(other.streetAddress)) + return false; + if (zipCode == null) { + if (other.zipCode != null) + return false; + } else if (!zipCode.equals(other.zipCode)) + return false; + return true; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + if (countryName != null && countryName.length() > 0) { + sb.append(countryName); + } + if (provinceName != null && provinceName.length() > 0) { + sb.append(" "); + sb.append(provinceName); + } + if (cityName != null && cityName.length() > 0) { + sb.append(" "); + sb.append(cityName); + } + if (streetAddress != null && streetAddress.length() > 0) { + sb.append(" "); + sb.append(streetAddress); + } + return sb.toString(); + } + +} diff --git a/src/test/java/com/alibaba/json/test/dubbo/HelloServiceImpl.java b/src/test/java/com/alibaba/json/test/dubbo/HelloServiceImpl.java new file mode 100755 index 0000000000..9994f1538b --- /dev/null +++ b/src/test/java/com/alibaba/json/test/dubbo/HelloServiceImpl.java @@ -0,0 +1,111 @@ +/** + * Project: dubbo.hello.sample.service + * + * File Created at 2009-6-12 + * $Id$ + * + * Copyright 2008 Alibaba.com Croporation Limited. + * All rights reserved. + * + * This software is the confidential and proprietary information of + * Alibaba Company. ("Confidential Information"). You shall not + * disclose such Confidential Information and shall use it only in + * accordance with the terms of the license agreement you entered into + * with Alibaba.com. + */ +package com.alibaba.json.test.dubbo; + +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; + + +/** + * TODO Comment of HelloServiceImpl + * + * @author tony.chenl + */ +public class HelloServiceImpl { + + public Tigers eatTiger(Tiger tiger) { + + return new Tigers(tiger); + } + + public String eatTiger() { + return "想吃老虎"; + } + + public String eatTiger(String number) { + return number; + } + + public HashSet eatTigers(String name, HashSet tigers) { + return tigers; + } + + public Map> eatTiger(String name, HashSet tigers) { + HashMap> tiger = new HashMap>(); + tiger.put(name, tigers); + return tiger; + } + + public String eatTiger(String name, Tiger tiger) { + return name + "想吃" + tiger.getTigerName() + tiger.getTigerSex(); + } + + public EnumTest eatEnums(EnumTest... enums) { + if (enums.length > 0) { + return enums[enums.length - 1]; + } else { + return EnumTest.Cat; + } + } + + public Date eatTime(Date date) { + return date; + } + + @SuppressWarnings("rawtypes") + public Map eatTiger(Map map) { + return map; + } + + public Map eatTigerMap(Map map) { + return map; + } + + public LinkedHashMap eatTiger(LinkedHashMap map) { + return map; + } + + public ConcurrentHashMap eatTiger(ConcurrentHashMap map) { + return map; + } + + public String sayHello(String hello) { + for (int i = 0; i < 10000; i++) { + StringBuffer sb = new StringBuffer(); + sb.append(new Random().nextInt(5000)); + } + return hello; + } + + public Person showPerson(Person person) { + return person; + } + + public List eatTiger(List list) { + return list; + } + + public String[] eatTiger(String[] args) { + return args; + } +} diff --git a/src/test/java/com/alibaba/json/test/dubbo/Image.java b/src/test/java/com/alibaba/json/test/dubbo/Image.java new file mode 100755 index 0000000000..df7818e234 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/dubbo/Image.java @@ -0,0 +1,50 @@ +/** + * Project: dubbo.test + * + * File Created at 2010-11-30 + * $Id: Image.java 75806 2011-02-18 09:08:30Z tony.chenl $ + * + * Copyright 2008 Alibaba.com Croporation Limited. + * All rights reserved. + * + * This software is the confidential and proprietary information of + * Alibaba Company. ("Confidential Information"). You shall not + * disclose such Confidential Information and shall use it only in + * accordance with the terms of the license agreement you entered into + * with Alibaba.com. + */ +package com.alibaba.json.test.dubbo; + +import java.io.InputStream; +import java.io.Serializable; + +/** + * TODO Comment of Image + * + * @author tony.chenl + */ +public class Image implements Serializable { + /** + * + */ + private static final long serialVersionUID = 616779453943392868L; + String name; + InputStream is; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public InputStream getIs() { + return is; + } + + public void setIs(InputStream is) { + this.is = is; + } + +} diff --git a/src/test/java/com/alibaba/json/test/dubbo/Person.java b/src/test/java/com/alibaba/json/test/dubbo/Person.java new file mode 100755 index 0000000000..58b11b2441 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/dubbo/Person.java @@ -0,0 +1,152 @@ +/** + * Project: dubbo.test + * + * File Created at 2010-11-17 + * $Id: Person.java 77622 2011-03-03 08:31:45Z ding.lid $ + * + * Copyright 2008 Alibaba.com Croporation Limited. + * All rights reserved. + * + * This software is the confidential and proprietary information of + * Alibaba Company. ("Confidential Information"). You shall not + * disclose such Confidential Information and shall use it only in + * accordance with the terms of the license agreement you entered into + * with Alibaba.com. + */ +package com.alibaba.json.test.dubbo; + +import java.io.Serializable; + +/** + * TODO Comment of Person + * + * @author tony.chenl + */ +public class Person implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + String personId; + + String loginName; + + PersonStatus status; + + String email; + + String penName; + + PersonInfo infoProfile; + + public Person() { + + } + + public Person(String id) { + this.personId = id; + } + + public String getPersonId() { + return personId; + } + + public void setPersonId(String personId) { + this.personId = personId; + } + + public PersonInfo getInfoProfile() { + return infoProfile; + } + + public void setInfoProfile(PersonInfo infoProfile) { + this.infoProfile = infoProfile; + } + + public void setLoginName(String loginName) { + this.loginName = loginName; + } + + public void setStatus(PersonStatus status) { + this.status = status; + } + + public void setEmail(String email) { + this.email = email; + } + + public void setPenName(String penName) { + this.penName = penName; + } + + public String getEmail() { + return this.email; + } + + public String getLoginName() { + return this.loginName; + } + + public PersonStatus getStatus() { + return this.status; + } + + public String getPenName() { + return penName; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((email == null) ? 0 : email.hashCode()); + result = prime * result + ((infoProfile == null) ? 0 : infoProfile.hashCode()); + result = prime * result + ((loginName == null) ? 0 : loginName.hashCode()); + result = prime * result + ((penName == null) ? 0 : penName.hashCode()); + result = prime * result + ((personId == null) ? 0 : personId.hashCode()); + result = prime * result + ((status == null) ? 0 : status.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Person other = (Person) obj; + if (email == null) { + if (other.email != null) + return false; + } else if (!email.equals(other.email)) + return false; + if (infoProfile == null) { + if (other.infoProfile != null) + return false; + } else if (!infoProfile.equals(other.infoProfile)) + return false; + if (loginName == null) { + if (other.loginName != null) + return false; + } else if (!loginName.equals(other.loginName)) + return false; + if (penName == null) { + if (other.penName != null) + return false; + } else if (!penName.equals(other.penName)) + return false; + if (personId == null) { + if (other.personId != null) + return false; + } else if (!personId.equals(other.personId)) + return false; + if (status != other.status) + return false; + return true; + } + +} diff --git a/src/test/java/com/alibaba/json/test/dubbo/PersonInfo.java b/src/test/java/com/alibaba/json/test/dubbo/PersonInfo.java new file mode 100755 index 0000000000..7f23e0172b --- /dev/null +++ b/src/test/java/com/alibaba/json/test/dubbo/PersonInfo.java @@ -0,0 +1,202 @@ +/** + * Project: dubbo.test + * + * File Created at 2010-11-17 + * $Id: PersonInfo.java 77622 2011-03-03 08:31:45Z ding.lid $ + * + * Copyright 2008 Alibaba.com Croporation Limited. + * All rights reserved. + * + * This software is the confidential and proprietary information of + * Alibaba Company. ("Confidential Information"). You shall not + * disclose such Confidential Information and shall use it only in + * accordance with the terms of the license agreement you entered into + * with Alibaba.com. + */ +package com.alibaba.json.test.dubbo; + +import java.io.Serializable; +import java.util.List; + +/** + * TODO Comment of PersonInfoModel + * + * @author tony.chenl + */ +public class PersonInfo implements Serializable { + private static final long serialVersionUID = 7443011149612231882L; + + List phones; + + Phone fax; + + FullAddress fullAddress; + + String mobileNo; + + String name; + + boolean male; + + boolean female; + + String department; + + String jobTitle; + + String homepageUrl; + + public List getPhones() { + return phones; + } + + public void setPhones(List phones) { + this.phones = phones; + } + + public boolean isMale() { + return male; + } + + public void setMale(boolean male) { + this.male = male; + } + + public boolean isFemale() { + return female; + } + + public void setFemale(boolean female) { + this.female = female; + } + + public void setFax(Phone fax) { + this.fax = fax; + } + + public void setFullAddress(FullAddress fullAddress) { + this.fullAddress = fullAddress; + } + + public void setMobileNo(String mobileNo) { + this.mobileNo = mobileNo; + } + + public void setName(String name) { + this.name = name; + } + + public void setDepartment(String department) { + this.department = department; + } + + public void setJobTitle(String jobTitle) { + this.jobTitle = jobTitle; + } + + public void setHomepageUrl(String homepageUrl) { + this.homepageUrl = homepageUrl; + } + + public String getDepartment() { + return department; + } + + public Phone getFax() { + return fax; + } + + public FullAddress getFullAddress() { + return fullAddress; + } + + public String getHomepageUrl() { + return homepageUrl; + } + + public String getJobTitle() { + return jobTitle; + } + + public String getMobileNo() { + return mobileNo; + } + + public String getName() { + return name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((department == null) ? 0 : department.hashCode()); + result = prime * result + ((fax == null) ? 0 : fax.hashCode()); + result = prime * result + (female ? 1231 : 1237); + result = prime * result + ((fullAddress == null) ? 0 : fullAddress.hashCode()); + result = prime * result + ((homepageUrl == null) ? 0 : homepageUrl.hashCode()); + result = prime * result + ((jobTitle == null) ? 0 : jobTitle.hashCode()); + result = prime * result + (male ? 1231 : 1237); + result = prime * result + ((mobileNo == null) ? 0 : mobileNo.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((phones == null) ? 0 : phones.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + PersonInfo other = (PersonInfo) obj; + if (department == null) { + if (other.department != null) + return false; + } else if (!department.equals(other.department)) + return false; + if (fax == null) { + if (other.fax != null) + return false; + } else if (!fax.equals(other.fax)) + return false; + if (female != other.female) + return false; + if (fullAddress == null) { + if (other.fullAddress != null) + return false; + } else if (!fullAddress.equals(other.fullAddress)) + return false; + if (homepageUrl == null) { + if (other.homepageUrl != null) + return false; + } else if (!homepageUrl.equals(other.homepageUrl)) + return false; + if (jobTitle == null) { + if (other.jobTitle != null) + return false; + } else if (!jobTitle.equals(other.jobTitle)) + return false; + if (male != other.male) + return false; + if (mobileNo == null) { + if (other.mobileNo != null) + return false; + } else if (!mobileNo.equals(other.mobileNo)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (phones == null) { + if (other.phones != null) + return false; + } else if (!phones.equals(other.phones)) + return false; + return true; + } + +} diff --git a/src/test/java/com/alibaba/json/test/dubbo/PersonStatus.java b/src/test/java/com/alibaba/json/test/dubbo/PersonStatus.java new file mode 100755 index 0000000000..96695386b0 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/dubbo/PersonStatus.java @@ -0,0 +1,26 @@ +/** + * Project: dubbo.test + * + * File Created at 2010-11-19 + * $Id: PersonStatus.java 67600 2010-11-30 06:01:31Z tony.chenl $ + * + * Copyright 2008 Alibaba.com Croporation Limited. + * All rights reserved. + * + * This software is the confidential and proprietary information of + * Alibaba Company. ("Confidential Information"). You shall not + * disclose such Confidential Information and shall use it only in + * accordance with the terms of the license agreement you entered into + * with Alibaba.com. + */ +package com.alibaba.json.test.dubbo; + +/** + * TODO Comment of PersonStatus + * + * @author tony.chenl + */ +public enum PersonStatus { + ENABLED, + DISABLED +} diff --git a/src/test/java/com/alibaba/json/test/dubbo/Phone.java b/src/test/java/com/alibaba/json/test/dubbo/Phone.java new file mode 100755 index 0000000000..e1202350bd --- /dev/null +++ b/src/test/java/com/alibaba/json/test/dubbo/Phone.java @@ -0,0 +1,143 @@ +/** + * Project: morgan.domain + * + * File Created at 2009-6-11 + * $Id: Phone.java 77622 2011-03-03 08:31:45Z ding.lid $ + * + * Copyright 2008 Alibaba.com Croporation Limited. + * All rights reserved. + * + * This software is the confidential and proprietary information of + * Alibaba Company. ("Confidential Information"). You shall not + * disclose such Confidential Information and shall use it only in + * accordance with the terms of the license agreement you entered into + * with Alibaba.com. + */ +package com.alibaba.json.test.dubbo; + +import java.io.Serializable; + +/** + * 电话号码 + * + * @author xk1430 + */ +public class Phone implements Serializable { + + private static final long serialVersionUID = 4399060521859707703L; + + private String country; + + private String area; + + private String number; + + private String extensionNumber; + + public Phone() { + } + + public Phone(String country, String area, String number, String extensionNumber) { + this.country = country; + this.area = area; + this.number = number; + this.extensionNumber = extensionNumber; + } + + public void setCountry(String country) { + this.country = country; + } + + public void setArea(String area) { + this.area = area; + } + + public void setNumber(String number) { + this.number = number; + } + + public void setExtensionNumber(String extensionNumber) { + this.extensionNumber = extensionNumber; + } + + public String getCountry() { + return country; + } + + public String getArea() { + return area; + } + + public String getNumber() { + return number; + } + + public String getExtensionNumber() { + return extensionNumber; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((area == null) ? 0 : area.hashCode()); + result = prime * result + ((country == null) ? 0 : country.hashCode()); + result = prime * result + ((extensionNumber == null) ? 0 : extensionNumber.hashCode()); + result = prime * result + ((number == null) ? 0 : number.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Phone other = (Phone) obj; + if (area == null) { + if (other.area != null) + return false; + } else if (!area.equals(other.area)) + return false; + if (country == null) { + if (other.country != null) + return false; + } else if (!country.equals(other.country)) + return false; + if (extensionNumber == null) { + if (other.extensionNumber != null) + return false; + } else if (!extensionNumber.equals(other.extensionNumber)) + return false; + if (number == null) { + if (other.number != null) + return false; + } else if (!number.equals(other.number)) + return false; + return true; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + if (country != null && country.length() > 0) { + sb.append(country); + sb.append("-"); + } + if (area != null && area.length() > 0) { + sb.append(area); + sb.append("-"); + } + if (number != null && number.length() > 0) { + sb.append(number); + } + if (extensionNumber != null && extensionNumber.length() > 0) { + sb.append("-"); + sb.append(extensionNumber); + } + return sb.toString(); + } + +} diff --git a/src/test/java/com/alibaba/json/test/dubbo/Tiger.java b/src/test/java/com/alibaba/json/test/dubbo/Tiger.java new file mode 100755 index 0000000000..189ab6de6f --- /dev/null +++ b/src/test/java/com/alibaba/json/test/dubbo/Tiger.java @@ -0,0 +1,34 @@ +package com.alibaba.json.test.dubbo; + +import java.io.Serializable; + +public class Tiger implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -768303386469936078L; + + public Tiger(){ + } + + private String tigerName; + private Boolean tigerSex; + + public String getTigerName() { + return tigerName; + } + + public void setTigerName(String tigerName) { + this.tigerName = tigerName; + } + + public Boolean getTigerSex() { + return tigerSex; + } + + public void setTigerSex(Boolean tigerSex) { + this.tigerSex = tigerSex; + } + +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/test/dubbo/Tigers.java b/src/test/java/com/alibaba/json/test/dubbo/Tigers.java new file mode 100755 index 0000000000..e29021fd8b --- /dev/null +++ b/src/test/java/com/alibaba/json/test/dubbo/Tigers.java @@ -0,0 +1,40 @@ +package com.alibaba.json.test.dubbo; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + + +public class Tigers implements Serializable { + + private static final long serialVersionUID = -1565572802090235506L; + + public Tigers(){ + } + + public Tigers(Tiger tiger){ + this.map = new HashMap(); + this.map.put("1st", tiger); + this.tiger = tiger; + } + + private Tiger tiger; + private Map map; + + public Map getMap() { + return map; + } + + public void setMap(Map map) { + this.map = map; + } + + public Tiger getTiger() { + return tiger; + } + + public void setTiger(Tiger tiger) { + this.tiger = tiger; + } + +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/json/test/entity/Company.java b/src/test/java/com/alibaba/json/test/entity/Company.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/entity/Department.java b/src/test/java/com/alibaba/json/test/entity/Department.java old mode 100644 new mode 100755 index 4aafd60bb3..bb3fed99f5 --- a/src/test/java/com/alibaba/json/test/entity/Department.java +++ b/src/test/java/com/alibaba/json/test/entity/Department.java @@ -4,7 +4,7 @@ import java.util.List; /** - * @author wenshao + * @author wenshao[szujobs@hotmail.com] */ public class Department { diff --git a/src/test/java/com/alibaba/json/test/entity/Employee.java b/src/test/java/com/alibaba/json/test/entity/Employee.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/entity/Group.java b/src/test/java/com/alibaba/json/test/entity/Group.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/entity/TestEntity.java b/src/test/java/com/alibaba/json/test/entity/TestEntity.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/entity/case1/IntObject_100_Entity.java b/src/test/java/com/alibaba/json/test/entity/case1/IntObject_100_Entity.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/entity/case1/Int_100_Entity.java b/src/test/java/com/alibaba/json/test/entity/case1/Int_100_Entity.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/entity/case1/LongObject_100_Entity.java b/src/test/java/com/alibaba/json/test/entity/case1/LongObject_100_Entity.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/entity/case1/Long_100_Entity.java b/src/test/java/com/alibaba/json/test/entity/case1/Long_100_Entity.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/entity/case1/String_100_Entity.java b/src/test/java/com/alibaba/json/test/entity/case1/String_100_Entity.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/entity/case2/Category.java b/src/test/java/com/alibaba/json/test/entity/case2/Category.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/entity/pagemodel/ComponentInstance.java b/src/test/java/com/alibaba/json/test/entity/pagemodel/ComponentInstance.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/entity/pagemodel/ComponentInstanceParam.java b/src/test/java/com/alibaba/json/test/entity/pagemodel/ComponentInstanceParam.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/entity/pagemodel/LayoutInstance.java b/src/test/java/com/alibaba/json/test/entity/pagemodel/LayoutInstance.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/entity/pagemodel/PageInstance.java b/src/test/java/com/alibaba/json/test/entity/pagemodel/PageInstance.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/entity/pagemodel/RegionEnum.java b/src/test/java/com/alibaba/json/test/entity/pagemodel/RegionEnum.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/entity/pagemodel/RegionInstance.java b/src/test/java/com/alibaba/json/test/entity/pagemodel/RegionInstance.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/entity/pagemodel/SegmentInstance.java b/src/test/java/com/alibaba/json/test/entity/pagemodel/SegmentInstance.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/entity/pagemodel/WidgetInstance.java b/src/test/java/com/alibaba/json/test/entity/pagemodel/WidgetInstance.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/epubview/EpubViewBook.java b/src/test/java/com/alibaba/json/test/epubview/EpubViewBook.java new file mode 100755 index 0000000000..90353feb9b --- /dev/null +++ b/src/test/java/com/alibaba/json/test/epubview/EpubViewBook.java @@ -0,0 +1,59 @@ +package com.alibaba.json.test.epubview; + +import java.io.Serializable; +import java.util.List; + +/** + * Epub书展示实体类 + * + * @author renci + * @version [版本号, 2012-8-9] + * @see [相关类/方法] + * @since [产品/模块版本] + */ +public class EpubViewBook implements Serializable { + /** + * + */ + private static final long serialVersionUID = -3450886861177869027L; + private String bookName; + private int pageCountNum; + private boolean teachingFlag = true; + private List pageList; + private EpubViewMetaData metadata; + public String getBookName() { + return bookName; + } + public void setBookName(String bookName) { + this.bookName = bookName; + } + public List getPageList() { + return pageList; + } + public void setPageList(List pageList) { + this.pageList = pageList; + } + + public int getPageCountNum() { + return pageCountNum; + } + public void setPageCountNum(int pageCountNum) { + this.pageCountNum = pageCountNum; + } + + public boolean isTeachingFlag() { + return teachingFlag; + } + + public void setTeachingFlag(boolean teachingFlag) { + this.teachingFlag = teachingFlag; + } + public EpubViewMetaData getMetadata() + { + return metadata; + } + public void setMetadata(EpubViewMetaData metadata) + { + this.metadata = metadata; + } +} diff --git a/src/test/java/com/alibaba/json/test/epubview/EpubViewHotPoint.java b/src/test/java/com/alibaba/json/test/epubview/EpubViewHotPoint.java new file mode 100755 index 0000000000..82dbc21d19 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/epubview/EpubViewHotPoint.java @@ -0,0 +1,302 @@ +package com.alibaba.json.test.epubview; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * 热点 + * @author renci + * + */ +public class EpubViewHotPoint implements Serializable { + + private static final long serialVersionUID = 2430184364840193603L; + + /** + * 热点类型: + * Normal:普通热点,显示图标,有iconzone、iconsrc标签 + * Hide:隐藏热点,不会显示图标,无iconzone、iconsrc标签 + * BkHightLight:背景高亮热点 + */ + private String type; + /** + * 热点行为名称 + */ + private String actionname; + + /** + * 热点文件类型: + * text/plain:文本 + * audio/mpeg:音频 + * video/mpeg:视频 + * image/jpeg:图片 + * application/x-book:课文热点弹出框 + * application/x-practice:课文练习 + * office:office文档格式 + * audio/highlight:音频背景高亮 + * webview/swf:flash + */ + private String actiontype; + + /** + * 热点文件位置 + */ + private String src; + + /** + * 加密热点文件位置 + */ + private String dcfSrc; + + /** + * 默认热点文件原文件名 + */ + private String description; + + /** + * application/x-book:课文热点弹出框(自定义热点)的标题 + */ + private String title; + + /** + * application/x-book:课文热点弹出框(自定义热点)的内容 + */ + private String content; + + /** + * application/x-book:课文热点弹出框(自定义热点)的附加菜单列表 + */ + private String menulist; + + /** + * application/x-book:课文热点弹出框(自定义热点)的背景朗读音频源路径. + */ + private String reading; + + /** + * application/x-book:课文热点弹出框(自定义热点)是否支持画笔 + */ + private String pen; + + /** + * application/x-book:课文热点弹出框(自定义热点)是否支持字典 + */ + private String dictionary; + + /** + * 参数 + */ + private Map parameters; + + /** + * 图片区域左上角X值 + */ + private String left; + + /** + * 图片区域左上角Y值 + */ + private String top; + + /** + * 图片区域右下角X值 + */ + private String right; + + /** + * 图片区域右下角Y值 + */ + private String bottom; + + /** + * 热点图标存放路径,隐藏热点、背景高亮热点可以不含该值 + */ + private String iconSrc; + + private String starttime; + private String endtime; + + /** + * 热点区域 + */ + private List zoneList; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getActionname() { + return actionname; + } + + public void setActionname(String actionname) { + this.actionname = actionname; + } + + public String getActiontype() { + return actiontype; + } + + public void setActiontype(String actiontype) { + this.actiontype = actiontype; + } + + public String getSrc() { + return src; + } + + public void setSrc(String src) { + this.src = src; + } + + public String getDcfSrc() { + return dcfSrc; + } + + public void setDcfSrc(String dcfSrc) { + this.dcfSrc = dcfSrc; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getMenulist() { + return menulist; + } + + public void setMenulist(String menulist) { + this.menulist = menulist; + } + + public String getReading() { + return reading; + } + + public void setReading(String reading) { + this.reading = reading; + } + + public String getPen() { + return pen; + } + + public void setPen(String pen) { + this.pen = pen; + } + + public String getDictionary() { + return dictionary; + } + + public void setDictionary(String dictionary) { + this.dictionary = dictionary; + } + + public Map getParameters() { + return parameters; + } + + public void setParameters(Map parameters) { + this.parameters = parameters; + } + + public static long getSerialversionuid() { + return serialVersionUID; + } + + public String getLeft() { + return left; + } + + public void setLeft(String left) { + this.left = left; + } + + public String getTop() { + return top; + } + + public void setTop(String top) { + this.top = top; + } + + public String getRight() { + return right; + } + + public void setRight(String right) { + this.right = right; + } + + public String getBottom() { + return bottom; + } + + public void setBottom(String bottom) { + this.bottom = bottom; + } + + public String getIconSrc() { + return iconSrc; + } + + public void setIconSrc(String iconSrc) { + this.iconSrc = iconSrc; + } + + public List getZoneList() { + return zoneList; + } + + public void setZoneList(List zoneList) { + this.zoneList = zoneList; + } + + public String getStarttime() + { + return starttime; + } + + public void setStarttime(String starttime) + { + this.starttime = starttime; + } + + public String getEndtime() + { + return endtime; + } + + public void setEndtime(String endtime) + { + this.endtime = endtime; + } + + +} diff --git a/src/test/java/com/alibaba/json/test/epubview/EpubViewHotPointZone.java b/src/test/java/com/alibaba/json/test/epubview/EpubViewHotPointZone.java new file mode 100755 index 0000000000..97e864ba42 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/epubview/EpubViewHotPointZone.java @@ -0,0 +1,86 @@ +package com.alibaba.json.test.epubview; + +import java.io.Serializable; + +public class EpubViewHotPointZone implements Serializable { + + private static final long serialVersionUID = 7467644447749652248L; + + /** + * 热点区域左上角X值 + */ + private String left; + + /** + * 热点区域左上角Y值 + */ + private String top; + + /** + * 热点区域右下角X值 + */ + private String right; + + /** + * 热点区域右下角Y值 + */ + private String bottom; + + /** + * 热点区域背景颜色 + */ + private String color; + + /** + * 热点区域透明度(百分比),两位小数 + */ + private String transparency; + + public String getLeft() { + return left; + } + + public void setLeft(String left) { + this.left = left; + } + + public String getTop() { + return top; + } + + public void setTop(String top) { + this.top = top; + } + + public String getRight() { + return right; + } + + public void setRight(String right) { + this.right = right; + } + + public String getBottom() { + return bottom; + } + + public void setBottom(String bottom) { + this.bottom = bottom; + } + + public String getTransparency() { + return transparency; + } + + public void setTransparency(String transparency) { + this.transparency = transparency; + } + + public void setColor(String color) { + this.color = color; + } + + public String getColor() { + return color; + } +} diff --git a/src/test/java/com/alibaba/json/test/epubview/EpubViewMetaData.java b/src/test/java/com/alibaba/json/test/epubview/EpubViewMetaData.java new file mode 100755 index 0000000000..77790ed0f2 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/epubview/EpubViewMetaData.java @@ -0,0 +1,38 @@ +package com.alibaba.json.test.epubview; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +public class EpubViewMetaData implements Serializable +{ + private static final long serialVersionUID = 8776084797505245120L; + + private boolean encrypt = false; + private Map properties = new HashMap(); + + public Map getProperties() + { + return properties; + } + + public void setProperties(Map properties) + { + this.properties = properties; + } + + public boolean isEncrypt() + { + return encrypt; + } + + public void setEncrypt(boolean encrypt) + { + this.encrypt = encrypt; + } + + public static long getSerialversionuid() + { + return serialVersionUID; + } +} diff --git a/src/test/java/com/alibaba/json/test/epubview/EpubViewPage.java b/src/test/java/com/alibaba/json/test/epubview/EpubViewPage.java new file mode 100755 index 0000000000..7790d0ebce --- /dev/null +++ b/src/test/java/com/alibaba/json/test/epubview/EpubViewPage.java @@ -0,0 +1,45 @@ +package com.alibaba.json.test.epubview; + +import java.io.Serializable; +import java.util.List; + +public class EpubViewPage implements Serializable { + + private static final long serialVersionUID = -2198407838110786606L; + + //普通Epub书时使用 + private String src; + private String imageUrl; + private String pageNum; + private List hotPoints; + public String getImageUrl() { + return imageUrl; + } + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + public String getPageNum() { + return pageNum; + } + public void setPageNum(String pageNum) { + this.pageNum = pageNum; + } + public List getHotPoints() { + return hotPoints; + } + public void setHotPoints(List hotPoints) { + this.hotPoints = hotPoints; + } + public static long getSerialversionuid() { + return serialVersionUID; + } + public String getSrc() + { + return src; + } + public void setSrc(String src) + { + this.src = src; + } + +} diff --git a/src/test/java/com/alibaba/json/test/epubview/TestKlutz.java b/src/test/java/com/alibaba/json/test/epubview/TestKlutz.java new file mode 100755 index 0000000000..11993f5dd4 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/epubview/TestKlutz.java @@ -0,0 +1,100 @@ +package com.alibaba.json.test.epubview; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.Feature; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; + +public class TestKlutz extends TestCase { + + private EpubViewBook book; + + ObjectMapper mapper = new ObjectMapper(); + Gson gson = new Gson(); + + private EpubViewBook book_jackson; + private EpubViewBook book_fastjson; + + private int LOOP_COUNT = 1000 * 1; + + @Override + protected void setUp() throws Exception { + InputStreamReader isr = new InputStreamReader( + Thread.currentThread().getContextClassLoader().getResourceAsStream("epub.json")); + BufferedReader reader = new BufferedReader(isr); + StringBuilder sb = new StringBuilder(); + + String temp; + while ((temp = reader.readLine()) != null) { + sb.append(temp); + } + String s = sb.toString(); + + this.book = JSON.parseObject(s, EpubViewBook.class); + } + + public void test_0() throws Exception { + + + for (int j = 0; j < 5; j++) { + fastjson(); + //gson(); + jackson(); + + System.out.println("======================="); + } + } + + private String jackson() throws Exception { + String s = mapper.writeValueAsString(book); + Long startTime; + // Jackson + startTime = System.currentTimeMillis(); + for (int i = 0; i < LOOP_COUNT; i++) { + book_jackson = mapper.readValue(s, EpubViewBook.class); + //s = mapper.writeValueAsString(epubViewBook); + } + System.out.println("Jackson:" + (System.currentTimeMillis() - startTime) + ", " + s.length()); + System.out.println(s); + return s; + } + + private String gson() throws Exception { + String s = gson.toJson(book); + + Long startTime; + // Gson + startTime = System.currentTimeMillis(); + for (int i = 0; i < LOOP_COUNT; i++) { + EpubViewBook epubViewBook = gson.fromJson(s, EpubViewBook.class); + s = gson.toJson(epubViewBook); + } + System.out.println("Gson:" + (System.currentTimeMillis() - startTime) + ", " + s.length()); + return s; + } + + private String fastjson() { + String s = JSON.toJSONString(book, SerializerFeature.DisableCircularReferenceDetect); + + Long startTime; + // Fastjson + startTime = System.currentTimeMillis(); + for (int i = 0; i < LOOP_COUNT; i++) { + book_fastjson = JSON.parseObject(s, EpubViewBook.class, Feature.DisableCircularReferenceDetect); + //s = JSON.toJSONString(epubViewBook, SerializerFeature.DisableCircularReferenceDetect); + } + System.out.println("Fastjson:" + (System.currentTimeMillis() - startTime) + ", " + s.length()); + System.out.println(s); + return s; + } +} diff --git a/src/test/java/com/alibaba/json/test/epubview/TestKlutz2.java b/src/test/java/com/alibaba/json/test/epubview/TestKlutz2.java new file mode 100755 index 0000000000..11d7831b16 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/epubview/TestKlutz2.java @@ -0,0 +1,29 @@ +package com.alibaba.json.test.epubview; + +import java.util.HashMap; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class TestKlutz2 extends TestCase { +// public void test_0 () throws Exception { +// EpubViewMetaData x = new EpubViewMetaData(); +// x.setProperties(new HashMap()); +// +// String str = JSON.toJSONString(x); +// System.out.println(str); +// +// JSON.parseObject(str, EpubViewMetaData.class); +// } + + public void test_page () throws Exception { + EpubViewPage x = new EpubViewPage(); + x.setImageUrl("xxx"); + + String str = JSON.toJSONString(x); + System.out.println(str); + + JSON.parseObject(str, EpubViewPage.class); + } +} diff --git a/src/test/java/com/alibaba/json/test/epubview/TestKlutz3.java b/src/test/java/com/alibaba/json/test/epubview/TestKlutz3.java new file mode 100755 index 0000000000..df84f49ad1 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/epubview/TestKlutz3.java @@ -0,0 +1,30 @@ +package com.alibaba.json.test.epubview; + +import java.util.ArrayList; +import java.util.HashMap; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + +public class TestKlutz3 extends TestCase { + public void test_0 () throws Exception { + EpubViewBook book = new EpubViewBook(); + book.setBookName("xx"); + + book.setPageList(new ArrayList()); + + EpubViewPage page = new EpubViewPage(); + book.getPageList().add(page); + + EpubViewMetaData metadata = new EpubViewMetaData(); + metadata.setProperties(new HashMap()); + +// book.setMetadata(null); + + String str = JSON.toJSONString(book); + System.out.println(str); + + JSON.parseObject(str, EpubViewBook.class); + } +} diff --git a/src/test/java/com/alibaba/json/test/generic/GenericTypeTest.java b/src/test/java/com/alibaba/json/test/generic/GenericTypeTest.java new file mode 100644 index 0000000000..344a48f651 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/generic/GenericTypeTest.java @@ -0,0 +1,62 @@ +package com.alibaba.json.test.generic; +import java.io.Serializable; + +import org.junit.Test; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; + + +public class GenericTypeTest extends TestCase { + + @Test + public void testEmbeddedGenericType() throws Exception { + + String jsonString = "{\"g\":{\"b\":{\"s\":'1'}}}"; + + Str t = JSON.parseObject(jsonString,Str.class); + Object o = t.getG().getB(); + System.out.println("Inner Class EmbeddedGenericType test => "+o.getClass().getName()); + Assert.assertEquals(GenericTypeTest.Bean.class.getName(), o.getClass().getName()); + + TStr t1 = JSON.parseObject(jsonString,TStr.class); + Object o1 = t1.getG().getB(); + System.out.println("Public Class EmbeddedGenericType test => "+o1.getClass().getName()); + Assert.assertEquals(TBean.class.getName(), o1.getClass().getName()); + + + } + + static class Str implements Serializable{ + Gen g; + public Gen getG() { + return g; + } + public void setG(Gen g) { + this.g = g; + } + } + + static class Gen implements Serializable{ + G b; + public G getB() { + return b; + } + public void setB(G b) { + this.b = b; + } + } + + static class Bean implements Serializable{ + String s; + public String getS() { + return s; + } + public void setS(String s) { + this.s = s; + } + } + +} diff --git a/src/test/java/com/alibaba/json/test/generic/TBean.java b/src/test/java/com/alibaba/json/test/generic/TBean.java new file mode 100644 index 0000000000..8254fcf251 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/generic/TBean.java @@ -0,0 +1,14 @@ +package com.alibaba.json.test.generic; +import java.io.Serializable; + + +public class TBean implements Serializable { + + String s; + public String getS() { + return s; + } + public void setS(String s) { + this.s = s; + } +} diff --git a/src/test/java/com/alibaba/json/test/generic/TGen.java b/src/test/java/com/alibaba/json/test/generic/TGen.java new file mode 100644 index 0000000000..2eccac975c --- /dev/null +++ b/src/test/java/com/alibaba/json/test/generic/TGen.java @@ -0,0 +1,15 @@ +package com.alibaba.json.test.generic; +import java.io.Serializable; + + +public class TGen implements Serializable { + + G b; + public G getB() { + return b; + } + public void setB(G b) { + this.b = b; + } + +} diff --git a/src/test/java/com/alibaba/json/test/generic/TStr.java b/src/test/java/com/alibaba/json/test/generic/TStr.java new file mode 100644 index 0000000000..d6b4d9ecdb --- /dev/null +++ b/src/test/java/com/alibaba/json/test/generic/TStr.java @@ -0,0 +1,16 @@ +package com.alibaba.json.test.generic; +import java.io.Serializable; + +public class TStr implements Serializable { + + TGen g; + + public TGen getG() { + return g; + } + + public void setG(TGen g) { + this.g = g; + } + +} diff --git a/src/test/java/com/alibaba/json/test/jackson/JacksonTest.java b/src/test/java/com/alibaba/json/test/jackson/JacksonTest.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/knowissue/Bug_for_loveflying.java b/src/test/java/com/alibaba/json/test/knowissue/Bug_for_loveflying.java new file mode 100755 index 0000000000..6e7e148984 --- /dev/null +++ b/src/test/java/com/alibaba/json/test/knowissue/Bug_for_loveflying.java @@ -0,0 +1,111 @@ +package com.alibaba.json.test.knowissue; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import junit.framework.TestCase; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer; + +public class Bug_for_loveflying extends TestCase { + + public void test_for_loveflying() throws Exception { + User user = new User(); + user.setId(1l); + user.setName("loveflying"); + user.setCreateTime(new java.sql.Timestamp(new Date().getTime())); + + UserLog userLog = new UserLog(); + userLog.setId(1l); + userLog.setUser(user); + user.getUserLogs().add(userLog); + + userLog = new UserLog(); + userLog.setId(2l); + userLog.setUser(user); + user.getUserLogs().add(userLog); + + SerializeConfig mapping = new SerializeConfig(); + + mapping.put(java.sql.Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd")); + mapping.put(java.sql.Timestamp.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss")); + // mapping.put(User.class, new JavaBeanSerializer(User.class, + // Collections.singletonMap("id", "uid"))); + + JSONObject jsonObject = (JSONObject) JSON.toJSON(user); + jsonObject.put("ext", "新加的属性"); + System.out.println(jsonObject.toJSONString(jsonObject, mapping)); + } + + public static class UserLog { + + private Long id; + + private transient User user; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + } + + public static class User { + + private Long id; + + private String name; + + private java.sql.Timestamp createTime; + + private Set userLogs = new HashSet(); + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public java.sql.Timestamp getCreateTime() { + return createTime; + } + + public void setCreateTime(java.sql.Timestamp createTime) { + this.createTime = createTime; + } + + public Set getUserLogs() { + return userLogs; + } + + public void setUserLogs(Set userLogs) { + this.userLogs = userLogs; + } + + } +} diff --git a/src/test/java/com/alibaba/json/test/performance/DecoderPerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/DecoderPerformanceTest.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/performance/IntArrayEncodePerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/IntArrayEncodePerformanceTest.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/performance/IntegerArrayEncodePerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/IntegerArrayEncodePerformanceTest.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/performance/IntegerListEncodePerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/IntegerListEncodePerformanceTest.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/performance/JacksonGroupDecoder.java b/src/test/java/com/alibaba/json/test/performance/JacksonGroupDecoder.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/performance/JacksonGroupParser.java b/src/test/java/com/alibaba/json/test/performance/JacksonGroupParser.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/performance/JacksonPageModelParser.java b/src/test/java/com/alibaba/json/test/performance/JacksonPageModelParser.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/performance/ObjectDecodePerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/ObjectDecodePerformanceTest.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/performance/ObjectEncodePerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/ObjectEncodePerformanceTest.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/performance/PageModelPerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/PageModelPerformanceTest.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/performance/case1/GenerateTest.java b/src/test/java/com/alibaba/json/test/performance/case1/GenerateTest.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/performance/case1/IntDecoderPerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/case1/IntDecoderPerformanceTest.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/performance/case1/IntObjectDecodePerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/case1/IntObjectDecodePerformanceTest.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/alibaba/json/test/performance/case1/IntObjectEncodePerformanceTest.java b/src/test/java/com/alibaba/json/test/performance/case1/IntObjectEncodePerformanceTest.java old mode 100644 new mode 100755 diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/Generic.java b/src/test/java/com/derbysoft/spitfire/fastjson/Generic.java new file mode 100755 index 0000000000..b1c1d704db --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/Generic.java @@ -0,0 +1,27 @@ +package com.derbysoft.spitfire.fastjson; + +import java.io.Serializable; +import java.util.List; + +public class Generic implements Serializable{ + String header; + T payload; + +// List + + public String getHeader() { + return header; + } + + public void setHeader(String header) { + this.header = header; + } + + public T getPayload() { + return payload; + } + + public void setPayload(T payload) { + this.payload = payload; + } +} \ No newline at end of file diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/Header.java b/src/test/java/com/derbysoft/spitfire/fastjson/Header.java new file mode 100755 index 0000000000..6f4816db40 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/Header.java @@ -0,0 +1,13 @@ +package com.derbysoft.spitfire.fastjson; + +public class Header { + private String taskId; + + public String getTaskId() { + return taskId; + } + + public void setTaskId(String taskId) { + this.taskId = taskId; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/TestFastJson.java b/src/test/java/com/derbysoft/spitfire/fastjson/TestFastJson.java new file mode 100755 index 0000000000..c31856b35e --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/TestFastJson.java @@ -0,0 +1,423 @@ +package com.derbysoft.spitfire.fastjson; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.concurrent.atomic.AtomicLong; + +import org.apache.commons.lang.time.StopWatch; +import org.junit.Test; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.derbysoft.spitfire.fastjson.dto.AvailGuaranteeDTO; +import com.derbysoft.spitfire.fastjson.dto.AvailRoomStayDTO; +import com.derbysoft.spitfire.fastjson.dto.CancelPenaltyType; +import com.derbysoft.spitfire.fastjson.dto.CancelPolicyDTO; +import com.derbysoft.spitfire.fastjson.dto.CardCode; +import com.derbysoft.spitfire.fastjson.dto.ChargeItemDTO; +import com.derbysoft.spitfire.fastjson.dto.ChargeType; +import com.derbysoft.spitfire.fastjson.dto.ChargeUnit; +import com.derbysoft.spitfire.fastjson.dto.Currency; +import com.derbysoft.spitfire.fastjson.dto.DateRangeDTO; +import com.derbysoft.spitfire.fastjson.dto.FreeMealDTO; +import com.derbysoft.spitfire.fastjson.dto.FreeMealType; +import com.derbysoft.spitfire.fastjson.dto.GenericRS; +import com.derbysoft.spitfire.fastjson.dto.GuaranteeType; +import com.derbysoft.spitfire.fastjson.dto.HotelAvailRS; +import com.derbysoft.spitfire.fastjson.dto.HotelAvailRoomStayDTO; +import com.derbysoft.spitfire.fastjson.dto.HotelRefDTO; +import com.derbysoft.spitfire.fastjson.dto.LanguageType; +import com.derbysoft.spitfire.fastjson.dto.MealsIncludedDTO; +import com.derbysoft.spitfire.fastjson.dto.MealsIncludedType; +import com.derbysoft.spitfire.fastjson.dto.PaymentType; +import com.derbysoft.spitfire.fastjson.dto.ProviderChainDTO; +import com.derbysoft.spitfire.fastjson.dto.RateDTO; +import com.derbysoft.spitfire.fastjson.dto.RatePlanDTO; +import com.derbysoft.spitfire.fastjson.dto.ResponseHeader; +import com.derbysoft.spitfire.fastjson.dto.RoomRateDTO; +import com.derbysoft.spitfire.fastjson.dto.RoomTypeDTO; +import com.derbysoft.spitfire.fastjson.dto.SimpleAmountDTO; +import com.derbysoft.spitfire.fastjson.dto.TPAExtensionsDTO; +import com.derbysoft.spitfire.fastjson.dto.UniqueIDDTO; +import com.derbysoft.spitfire.fastjson.dto.UniqueIDType; + +//import com.derbysoft.spitfire.fastjson.dto.*; + +public class TestFastJson { + + private static final int TIMES = 10000; + private static final int STAYS_COUNT = 10; + + public void f_testF() { + Generic q = new Generic(); + byte[] text = JSON.toJSONBytes(q, SerializerFeature.WriteClassName); + JSON.parseObject(text, Generic.class); + } + + @SuppressWarnings("unchecked") + public void f_test() throws Exception { + + String text = JSON.toJSONString(createTest(), SerializerFeature.WriteClassName); + System.out.println(text.length()); + System.out.println(text); + System.out.println("serialize finished"); + GenericRS o = (GenericRS) JSON.parseObject(text, GenericRS.class); + + System.out.println(o); + } + + public void testFP() throws IOException { + Generic q = new Generic(); + for (int x = 0; x < STAYS_COUNT; ++x) { + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + for (int i = 0; i < TIMES; ++i) { + jsonSerialize(q); + } + stopWatch.stop(); + + System.out.println("JSON serialize:" + stopWatch.getTime()); + + stopWatch.reset(); + stopWatch.start(); + for (int i = 0; i < TIMES; ++i) { + javaSerialize(q); + } + stopWatch.stop(); + System.out.println("JAVA serialize:" + stopWatch.getTime()); + System.out.println(); + } + } + + private void jsonSerialize(T t) throws IOException { + // String text = JSON.toJSONString(t, SerializerFeature.WriteClassName, SerializerFeature.PrettyFormat); + // System.out.println(text); + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + SerializeWriter out = new SerializeWriter(SerializerFeature.WriteClassName); + // SerializeWriter out = new SerializeWriter(); + JSONSerializer serializer = new JSONSerializer(out); + serializer.write(t); + out.writeTo(os, "UTF-8"); + os.toByteArray(); + //System.out.println(JSON.toJSONString(t, SerializerFeature.WriteClassName, SerializerFeature.PrettyFormat)); + //System.out.println("json " + os.toByteArray().length); + } + + private void javaSerialize(T t) throws IOException { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(os); + oos.writeObject(t); + // System.out.println("java " + os.toByteArray().length); + } + + @SuppressWarnings("unchecked") + private T jsonDeserialize(byte[] bytes, Class clazz) throws IOException { + return (T) JSON.parseObject(bytes, clazz); + } + + @SuppressWarnings("unchecked") + private T javaDeserialize(byte[] bytes) throws IOException, ClassNotFoundException { + ByteArrayInputStream is = new ByteArrayInputStream(bytes); + ObjectInputStream ois = new ObjectInputStream(is); + return (T) ois.readObject(); + } + + @Test + public void testSerializePerformance() throws IOException { + Object obj = createTest(); + + for (int x = 0; x < 20; ++x) { + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + for (int i = 0; i < TIMES; ++i) { + jsonSerialize(obj); + } + stopWatch.stop(); + + System.out.println("JSON serialize:" + stopWatch.getTime()); + + stopWatch.reset(); + stopWatch.start(); + for (int i = 0; i < TIMES; ++i) { + javaSerialize(obj); + } + stopWatch.stop(); + System.out.println("JAVA serialize:" + stopWatch.getTime()); + System.out.println(); + } + } + + public void testDeserializePerformance() throws IOException, ClassNotFoundException { + Object obj = createTest(); + byte[] bytes = JSON.toJSONBytes(obj, SerializerFeature.WriteClassName); + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(os); + oos.writeObject(obj); + byte[] javaBytes = os.toByteArray(); + + System.out.println(bytes.length); + + for (int x = 0; x < 20; ++x) { + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + for (int i = 0; i < TIMES; ++i) { + // ByteArrayInputStream is = new ByteArrayInputStream(bytes); + Object o = jsonDeserialize(bytes, GenericRS.class); + o.getClass(); + } + stopWatch.stop(); + + System.out.println("JSON deserialize:" + stopWatch.getTime()); + + stopWatch.reset(); + + stopWatch.start(); + for (int i = 0; i < TIMES; ++i) { + Object o = javaDeserialize(javaBytes); + o.getClass(); + } + stopWatch.stop(); + + System.out.println("JAVA deserialize:" + stopWatch.getTime()); + System.out.println(); + } + + } + + public GenericRS createTest() { + GenericRS rs = new GenericRS(); + rs.setHeader(new ResponseHeader("dsfsdfsd")); + HotelAvailRS hotelAvailRS = createExpectedHotelAvailRS(); + TPAExtensionsDTO extensions = new TPAExtensionsDTO(); + extensions.getElements().put("dfd", "Dfdf"); + hotelAvailRS.setTpaExtensions(extensions); + rs.setPayload(hotelAvailRS); + return rs; + } + + // private static final String HOTEL_DESC = "foo hotel desc"; + private static final String ROOM_TYPE_CODE = "foo room type code"; + private static final String ROOM_TYPE_NAME = "foo room type name"; + private static final String RATE_PLAN_CODE = "foo rate plan code"; + private static final String RATE_PLAN_NAME = "rate plan name"; + private static final Integer ROOM_COUNT = 2; + + // private static final Date CANCEL_POLICY_DEAD_LINE = DateUtils.parseUseDefaultFormat("2008-09-01"); + private static final String CANCEL_POLICY_DESCRIPTION = "foo cancel policy description"; + + private static final String GUARANTEE_DESCRIPTION = "foo guarantee description"; + // private static final String CARD_NUMBER = "foo card number"; + // private static final String CARD_HOLDER_NAME = "foo card holder name"; + // private static final String CARD_SERIES_CODE = "foo card series code"; + // private static final Date CARD_EXPIRE_DATE = DateUtils.parseUseDefaultFormat("2010-12-31"); + private static final Currency CURRENCY = Currency.CNY; + + private static final PaymentType PAYMENT_TYPE_POA = PaymentType.POA; + // private static final int DAY_COUNT = 4; + // private static final String[] CHECKIN_DATES = {"2008-08-25", "2008-08-26", "2008-08-27", "2008-08-28"}; + // private static final String[] CHECKOUT_DATES = {"2008-08-26", "2008-08-27", "2008-08-28", "2008-08-29"}; + // private static final BigDecimal[] AMOUNT_AFTER_TAXS + // = {new BigDecimal(800), new BigDecimal(800), new BigDecimal(800), new BigDecimal(900)}; + private static final BigDecimal[] AMOUNT_BEFORE_TAXS = { new BigDecimal(750), new BigDecimal(750), + new BigDecimal(760), new BigDecimal(880) }; + private static final BigDecimal AMOUNT_TAX = new BigDecimal(50); + private static final BigDecimal SERVICE_CHARGE_AMOUNT = new BigDecimal(10); + private static final String TAX_DESC = "foo tax desc"; + private static final String SERVICE_CHARGE_DESC = "foo repository charge desc"; + + private static final String PROVIDER_CODE = "hilton"; + private static final String HOTEL_NAME = "foo hotel name"; + private static final String HOTEL_CODE = "foo hotel code"; + private static final LanguageType LANGUAGE_TYPE_CN = LanguageType.ZH_CN; + // private static final String TASK_ID = "task id"; + private static final boolean NEED_GUARANTEE = true; + private static final CardCode VISA = CardCode.VISA; + // private static final String CARD_CODE = VISA.getCode(); + + private static final int NUMBER_ZERO = 0; + private static final int NUMBER_ONE = 1; + private static final int NUMBER_TWO = 2; + private static final int NUMBER_THREE = 3; + + private static AtomicLong seed = new AtomicLong(); + + private HotelAvailRS createExpectedHotelAvailRS() { + HotelAvailRS payLoad = new HotelAvailRS(); + payLoad.setHotelAvailRoomStay(createExpectedHotelAvailRoomStay()); + return payLoad; + } + + private HotelAvailRoomStayDTO createExpectedHotelAvailRoomStay() { + HotelAvailRoomStayDTO hotelAvailRoomStay = new HotelAvailRoomStayDTO(); + hotelAvailRoomStay.setHotelRef(createExpectedHotelRef()); + hotelAvailRoomStay.setRoomStays(createExpectedRoomStays()); + return hotelAvailRoomStay; + } + + private List createExpectedRoomStays() { + ArrayList roomStays = new ArrayList(); + for (int i = 0; i < STAYS_COUNT; ++i) { + AvailRoomStayDTO roomStay = new AvailRoomStayDTO(); + roomStay.setLanguageType(LANGUAGE_TYPE_CN); + roomStay.setRoomType(createExpectedRoomType()); + roomStay.setRatePlan(createExpectedRatePlan()); + roomStay.setQuantity(ROOM_COUNT); + roomStay.setRoomRate(createExpectedRoomRate()); + roomStay.setProviderChain(createExpectedProviderChain()); + roomStays.add(roomStay); + } + + return roomStays; + } + + private ProviderChainDTO createExpectedProviderChain() { + ProviderChainDTO providerChain = new ProviderChainDTO(); + List providers = new ArrayList(); + UniqueIDDTO provider = new UniqueIDDTO(PROVIDER_CODE, UniqueIDType.HOTEL); + provider.setCompanyName(PROVIDER_CODE); + providers.add(provider); + providerChain.setProviders(providers); + return providerChain; + } + + private List createExpectedAvailGuarantee() { + List availGuarantees = new ArrayList(); + AvailGuaranteeDTO availGuaranteeDTO = new AvailGuaranteeDTO(); + availGuaranteeDTO.setGuaranteeType(GuaranteeType.CreditCard); + availGuaranteeDTO.setCardCode(VISA); + availGuaranteeDTO.setTpaExtensions(createExpectedEpaExtensions()); + availGuarantees.add(availGuaranteeDTO); + return availGuarantees; + } + + private TPAExtensionsDTO createExpectedEpaExtensions() { + TPAExtensionsDTO tpaExtensions = new TPAExtensionsDTO(); + tpaExtensions.setElement("description", GUARANTEE_DESCRIPTION); + return tpaExtensions; + } + + private CancelPolicyDTO createExpectedCancelPolicy() { + CancelPolicyDTO cancelPolicyDTO = new CancelPolicyDTO(); + cancelPolicyDTO.setCancelPenaltyType(CancelPenaltyType.UNKNOWN); + cancelPolicyDTO.setDeadline("16:00"); + cancelPolicyDTO.setDescription(CANCEL_POLICY_DESCRIPTION); + return cancelPolicyDTO; + } + + private RoomRateDTO createExpectedRoomRate() { + RoomRateDTO roomRate = new RoomRateDTO(); + List rates = new ArrayList(); + rates.add(createExpectedFirstDayRate()); + rates.add(createExpectedSecondDayRate()); + rates.add(createExpectedThirdDayRate()); + rates.add(createExpectedForthDayRate()); + roomRate.setRates(rates); + return roomRate; + } + + private RatePlanDTO createExpectedRatePlan() { + RatePlanDTO ratePlan = new RatePlanDTO(); + ratePlan.setCode(RATE_PLAN_CODE); + ratePlan.setName(RATE_PLAN_NAME); + ratePlan.setPaymentType(PAYMENT_TYPE_POA); // TODO paymentType only cash back? + ratePlan.setTaxes(createExpectedTaxs()); + ratePlan.setServiceCharges(createExpectedServiceCharges()); + ratePlan.setNeedGuarantee(NEED_GUARANTEE); + ratePlan.setCancelPolicy(createExpectedCancelPolicy()); + ratePlan.setAvailGuarantees(createExpectedAvailGuarantee()); // TODO translator + ratePlan.setFreeMeal(createExpectedFreeMeal()); + return ratePlan; + } + + private FreeMealDTO createExpectedFreeMeal() { + FreeMealDTO freeMeal = new FreeMealDTO(); + freeMeal.setType(FreeMealType.NONE); + return freeMeal; + } + + private RoomTypeDTO createExpectedRoomType() { + RoomTypeDTO roomType = new RoomTypeDTO(); + roomType.setCode(ROOM_TYPE_CODE); + roomType.setName(ROOM_TYPE_NAME); + return roomType; + } + + private RateDTO createExpectedForthDayRate() { + return createExpectedRateDTO(NUMBER_THREE); + } + + private RateDTO createExpectedThirdDayRate() { + return createExpectedRateDTO(NUMBER_TWO); + } + + private RateDTO createExpectedSecondDayRate() { + return createExpectedRateDTO(NUMBER_ONE); + } + + private RateDTO createExpectedFirstDayRate() { + return createExpectedRateDTO(NUMBER_ZERO); + } + + private RateDTO createExpectedRateDTO(int index) { + RateDTO rate = new RateDTO(); + rate.setDateRange(createExpectedDateRangeDTO()); + rate.setPureAmount(createExpectedAmountDTO(CURRENCY, AMOUNT_BEFORE_TAXS[index])); + rate.setMealsIncluded(new MealsIncludedDTO(MealsIncludedType.UNKNOWN)); + return rate; + } + + private List createExpectedServiceCharges() { + List serviceCharges = new ArrayList(); + ChargeItemDTO serviceCharge = new ChargeItemDTO(); + serviceCharge.setUnit(ChargeUnit.PER_NIGHT); + serviceCharge.setType(ChargeType.FIXED); + serviceCharge.setValue(SERVICE_CHARGE_AMOUNT); + serviceCharge.setDescription(new String(SERVICE_CHARGE_DESC + seed.incrementAndGet())); + serviceCharges.add(serviceCharge); + return serviceCharges; + } + + private List createExpectedTaxs() { + List taxs = new ArrayList(); + ChargeItemDTO tax = new ChargeItemDTO(); + tax.setUnit(ChargeUnit.PER_NIGHT); + tax.setValue(AMOUNT_TAX); + tax.setType(ChargeType.FIXED); + tax.setDescription(TAX_DESC + seed.incrementAndGet()); + taxs.add(tax); + return taxs; + } + + private SimpleAmountDTO createExpectedAmountDTO(Currency currency, BigDecimal amount) { + SimpleAmountDTO simpleAmountDTO = new SimpleAmountDTO(); + simpleAmountDTO.setCurrency(currency); + simpleAmountDTO.setAmount(amount); + return simpleAmountDTO; + } + + private DateRangeDTO createExpectedDateRangeDTO() { + DateRangeDTO dateRangeDTO = new DateRangeDTO(); + dateRangeDTO.setStart(new Date()); + dateRangeDTO.setEnd(new Date()); + return dateRangeDTO; + } + + private HotelRefDTO createExpectedHotelRef() { + HotelRefDTO hotelRef = new HotelRefDTO(); + hotelRef.setCode(new String(HOTEL_CODE)); + hotelRef.setName(new String(HOTEL_NAME)); + return hotelRef; + } + +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/AbstractDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/AbstractDTO.java new file mode 100755 index 0000000000..66084ecfc7 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/AbstractDTO.java @@ -0,0 +1,31 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import java.io.Serializable; + +import com.alibaba.fastjson.annotation.JSONField; + +public abstract class AbstractDTO implements Serializable { + private boolean keepgoingValidate = false; + + private boolean checkCircularReference = true; + + @JSONField(name="KV") + public boolean isKeepgoingValidate() { + return keepgoingValidate; + } + + @JSONField(name="KV") + public void setKeepgoingValidate(boolean keepgoingValidate) { + this.keepgoingValidate = keepgoingValidate; + } + + @JSONField(name="CR") + public boolean isCheckCircularReference() { + return checkCircularReference; + } + + @JSONField(name="CR") + public void setCheckCircularReference(boolean checkCircularReference) { + this.checkCircularReference = checkCircularReference; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/AbstractRS.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/AbstractRS.java new file mode 100755 index 0000000000..3bfbe70631 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/AbstractRS.java @@ -0,0 +1,31 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public class AbstractRS extends AbstractDTO { + private SuccessDTO success; + private WarningsDTO warnings; + private ErrorsDTO errors; + + public SuccessDTO getSuccess() { + return success; + } + + public void setSuccess(SuccessDTO success) { + this.success = success; + } + + public WarningsDTO getWarnings() { + return warnings; + } + + public void setWarnings(WarningsDTO warnings) { + this.warnings = warnings; + } + + public ErrorsDTO getErrors() { + return errors; + } + + public void setErrors(ErrorsDTO errors) { + this.errors = errors; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/AgeQualifyingType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/AgeQualifyingType.java new file mode 100755 index 0000000000..70776fbbd1 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/AgeQualifyingType.java @@ -0,0 +1,5 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public enum AgeQualifyingType { + ADULT +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/AvailGuaranteeDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/AvailGuaranteeDTO.java new file mode 100755 index 0000000000..f528ec1a6c --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/AvailGuaranteeDTO.java @@ -0,0 +1,31 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public class AvailGuaranteeDTO extends AbstractDTO{ + private GuaranteeType guaranteeType; + private CardCode cardCode; + private TPAExtensionsDTO tpaExtensions; + + public GuaranteeType getGuaranteeType() { + return guaranteeType; + } + + public void setGuaranteeType(GuaranteeType guaranteeType) { + this.guaranteeType = guaranteeType; + } + + public CardCode getCardCode() { + return cardCode; + } + + public void setCardCode(CardCode cardCode) { + this.cardCode = cardCode; + } + + public TPAExtensionsDTO getTpaExtensions() { + return tpaExtensions; + } + + public void setTpaExtensions(TPAExtensionsDTO tpaExtensions) { + this.tpaExtensions = tpaExtensions; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/AvailRoomStayDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/AvailRoomStayDTO.java new file mode 100755 index 0000000000..8b2601ba00 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/AvailRoomStayDTO.java @@ -0,0 +1,79 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import com.alibaba.fastjson.annotation.JSONField; + +public class AvailRoomStayDTO extends AbstractDTO { + private RoomTypeDTO roomType; + + private RatePlanDTO ratePlan; + + private RoomRateDTO roomRate; + + private Integer quantity; + + private ProviderChainDTO providerChain; + + private LanguageType languageType; + + private TPAExtensionsDTO tpaExtensions; + + public RoomTypeDTO getRoomType() { + return roomType; + } + + public void setRoomType(RoomTypeDTO roomType) { + this.roomType = roomType; + } + + public RatePlanDTO getRatePlan() { + return ratePlan; + } + + public void setRatePlan(RatePlanDTO ratePlan) { + this.ratePlan = ratePlan; + } + + public RoomRateDTO getRoomRate() { + return roomRate; + } + + public void setRoomRate(RoomRateDTO roomRate) { + this.roomRate = roomRate; + } + + public Integer getQuantity() { + return quantity; + } + + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } + + @JSONField(name="PC") + public ProviderChainDTO getProviderChain() { + return providerChain; + } + + @JSONField(name="PC") + public void setProviderChain(ProviderChainDTO providerChain) { + this.providerChain = providerChain; + } + + @JSONField(name="LT") + public LanguageType getLanguageType() { + return languageType; + } + + @JSONField(name="LT") + public void setLanguageType(LanguageType languageType) { + this.languageType = languageType; + } + + public TPAExtensionsDTO getTpaExtensions() { + return tpaExtensions; + } + + public void setTpaExtensions(TPAExtensionsDTO tpaExtensions) { + this.tpaExtensions = tpaExtensions; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/BathType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/BathType.java new file mode 100755 index 0000000000..ddf7d04264 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/BathType.java @@ -0,0 +1,4 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public enum BathType { +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/CancelPenaltyType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/CancelPenaltyType.java new file mode 100755 index 0000000000..9135ff440b --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/CancelPenaltyType.java @@ -0,0 +1,5 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public enum CancelPenaltyType { + UNKNOWN +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/CancelPolicyDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/CancelPolicyDTO.java new file mode 100755 index 0000000000..36fefa47dc --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/CancelPolicyDTO.java @@ -0,0 +1,35 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import com.alibaba.fastjson.annotation.JSONField; + +public class CancelPolicyDTO extends AbstractDTO{ + private CancelPenaltyType cancelPenaltyType; + private String deadline; + private String description; + + public CancelPenaltyType getCancelPenaltyType() { + return cancelPenaltyType; + } + + public void setCancelPenaltyType(CancelPenaltyType cancelPenaltyType) { + this.cancelPenaltyType = cancelPenaltyType; + } + + public String getDeadline() { + return deadline; + } + + public void setDeadline(String deadline) { + this.deadline = deadline; + } + + @JSONField(name="DESC") + public String getDescription() { + return description; + } + + @JSONField(name="DESC") + public void setDescription(String description) { + this.description = description; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/CardCode.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/CardCode.java new file mode 100755 index 0000000000..a8facd8efd --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/CardCode.java @@ -0,0 +1,5 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public enum CardCode { + VISA +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/ChargeItemDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ChargeItemDTO.java new file mode 100755 index 0000000000..35345ee017 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ChargeItemDTO.java @@ -0,0 +1,42 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import java.math.BigDecimal; + +public class ChargeItemDTO extends AbstractDTO{ + private ChargeUnit unit; + private ChargeType type; + private BigDecimal value; + private String description; + + public ChargeUnit getUnit() { + return unit; + } + + public void setUnit(ChargeUnit unit) { + this.unit = unit; + } + + public ChargeType getType() { + return type; + } + + public void setType(ChargeType type) { + this.type = type; + } + + public BigDecimal getValue() { + return value; + } + + public void setValue(BigDecimal value) { + this.value = value; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/ChargeType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ChargeType.java new file mode 100755 index 0000000000..a4cff026c9 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ChargeType.java @@ -0,0 +1,5 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public enum ChargeType { + FIXED +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/ChargeUnit.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ChargeUnit.java new file mode 100755 index 0000000000..dc572bc839 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ChargeUnit.java @@ -0,0 +1,5 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public enum ChargeUnit { + PER_NIGHT +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/CompositeType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/CompositeType.java new file mode 100755 index 0000000000..f53828de7e --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/CompositeType.java @@ -0,0 +1,5 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public enum CompositeType { + UNKNOWN +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/Currency.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/Currency.java new file mode 100755 index 0000000000..0633fa0180 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/Currency.java @@ -0,0 +1,5 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public enum Currency { + CNY +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/DateRangeDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/DateRangeDTO.java new file mode 100755 index 0000000000..065d5b9a67 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/DateRangeDTO.java @@ -0,0 +1,24 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import java.util.Date; + +public class DateRangeDTO extends AbstractDTO{ + private Date start; + private Date end; + + public Date getStart() { + return start; + } + + public void setStart(Date start) { + this.start = start; + } + + public Date getEnd() { + return end; + } + + public void setEnd(Date end) { + this.end = end; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/ErrorsDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ErrorsDTO.java new file mode 100755 index 0000000000..b3f1ef8b59 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ErrorsDTO.java @@ -0,0 +1,16 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import java.util.ArrayList; +import java.util.List; + +public class ErrorsDTO extends AbstractDTO { + private List errors = new ArrayList(); + + public List getErrors() { + return errors; + } + + public void setErrors(List errors) { + this.errors = errors; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/FreeMealDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/FreeMealDTO.java new file mode 100755 index 0000000000..4a4ad86770 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/FreeMealDTO.java @@ -0,0 +1,13 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public class FreeMealDTO extends AbstractDTO{ + private FreeMealType type; + + public FreeMealType getType() { + return type; + } + + public void setType(FreeMealType type) { + this.type = type; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/FreeMealType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/FreeMealType.java new file mode 100755 index 0000000000..c26c162917 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/FreeMealType.java @@ -0,0 +1,5 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public enum FreeMealType { + NONE +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/GenericRS.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/GenericRS.java new file mode 100755 index 0000000000..ed87eebc7c --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/GenericRS.java @@ -0,0 +1,23 @@ +package com.derbysoft.spitfire.fastjson.dto; + + +public class GenericRS extends AbstractRS{ + private ResponseHeader header; + private T payload; + + public T getPayload() { + return payload; + } + + public void setPayload(T payload) { + this.payload = payload; + } + + public ResponseHeader getHeader() { + return header; + } + + public void setHeader(ResponseHeader header) { + this.header = header; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/GuaranteeType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/GuaranteeType.java new file mode 100755 index 0000000000..239b7a749c --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/GuaranteeType.java @@ -0,0 +1,5 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public enum GuaranteeType { + CreditCard +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/GuestCountDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/GuestCountDTO.java new file mode 100755 index 0000000000..f9b6c4fb8a --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/GuestCountDTO.java @@ -0,0 +1,29 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public class GuestCountDTO extends AbstractDTO{ + private AgeQualifyingType ageQualifyingType; + private int count; + + public GuestCountDTO() { + } + + public GuestCountDTO(AgeQualifyingType ageQualifyingType, int count) { + this.ageQualifyingType = ageQualifyingType; + } + + public AgeQualifyingType getAgeQualifyingType() { + return ageQualifyingType; + } + + public void setAgeQualifyingType(AgeQualifyingType ageQualifyingType) { + this.ageQualifyingType = ageQualifyingType; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/HotelAvailRS.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/HotelAvailRS.java new file mode 100755 index 0000000000..572105efec --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/HotelAvailRS.java @@ -0,0 +1,23 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public class HotelAvailRS extends AbstractRS { + private HotelAvailRoomStayDTO hotelAvailRoomStay; + + private TPAExtensionsDTO tpaExtensions; + + public HotelAvailRoomStayDTO getHotelAvailRoomStay() { + return hotelAvailRoomStay; + } + + public void setHotelAvailRoomStay(HotelAvailRoomStayDTO hotelAvailRoomStay) { + this.hotelAvailRoomStay = hotelAvailRoomStay; + } + + public TPAExtensionsDTO getTpaExtensions() { + return tpaExtensions; + } + + public void setTpaExtensions(TPAExtensionsDTO tpaExtensions) { + this.tpaExtensions = tpaExtensions; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/HotelAvailRoomStayDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/HotelAvailRoomStayDTO.java new file mode 100755 index 0000000000..5b15b10eb6 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/HotelAvailRoomStayDTO.java @@ -0,0 +1,38 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import java.util.ArrayList; +import java.util.List; + +public class HotelAvailRoomStayDTO extends AbstractDTO{ + + + private List roomStays = new ArrayList(); + + private HotelRefDTO hotelRef; + + private TPAExtensionsDTO tpaExtensions; + + public List getRoomStays() { + return roomStays; + } + + public void setRoomStays(List roomStays) { + this.roomStays = roomStays; + } + + public HotelRefDTO getHotelRef() { + return hotelRef; + } + + public void setHotelRef(HotelRefDTO hotelRef) { + this.hotelRef = hotelRef; + } + + public TPAExtensionsDTO getTpaExtensions() { + return tpaExtensions; + } + + public void setTpaExtensions(TPAExtensionsDTO tpaExtensions) { + this.tpaExtensions = tpaExtensions; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/HotelRefDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/HotelRefDTO.java new file mode 100755 index 0000000000..bc1705cbed --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/HotelRefDTO.java @@ -0,0 +1,61 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public class HotelRefDTO extends AbstractDTO{ + + private String code; + + private String name; + + private String chainCode; + + private String brandCode; + + private TPAExtensionsDTO tpaExtensions; + + public HotelRefDTO() { + } + + public HotelRefDTO(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getChainCode() { + return chainCode; + } + + public void setChainCode(String chainCode) { + this.chainCode = chainCode; + } + + public String getBrandCode() { + return brandCode; + } + + public void setBrandCode(String brandCode) { + this.brandCode = brandCode; + } + + public void setCode(String code) { + this.code = code; + } + + public TPAExtensionsDTO getTpaExtensions() { + return tpaExtensions; + } + + public void setTpaExtensions(TPAExtensionsDTO tpaExtensions) { + this.tpaExtensions = tpaExtensions; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/InternetDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/InternetDTO.java new file mode 100755 index 0000000000..943b8374fb --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/InternetDTO.java @@ -0,0 +1,33 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public class InternetDTO extends AbstractDTO{ + + private InternetType internetType; + private String chargeInfo; + + private TPAExtensionsDTO tpaExtensions; + + public InternetType getInternetType() { + return internetType; + } + + public void setInternetType(InternetType internetType) { + this.internetType = internetType; + } + + public String getChargeInfo() { + return chargeInfo; + } + + public void setChargeInfo(String chargeInfo) { + this.chargeInfo = chargeInfo; + } + + public TPAExtensionsDTO getTpaExtensions() { + return tpaExtensions; + } + + public void setTpaExtensions(TPAExtensionsDTO tpaExtensions) { + this.tpaExtensions = tpaExtensions; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/InternetType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/InternetType.java new file mode 100755 index 0000000000..4b06de21fe --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/InternetType.java @@ -0,0 +1,4 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public enum InternetType { +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/LanguageType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/LanguageType.java new file mode 100755 index 0000000000..08b89e79f8 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/LanguageType.java @@ -0,0 +1,5 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public enum LanguageType { + ZH_CN +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/MealsIncludedDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/MealsIncludedDTO.java new file mode 100755 index 0000000000..27954e416a --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/MealsIncludedDTO.java @@ -0,0 +1,29 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public class MealsIncludedDTO extends AbstractDTO{ + private MealsIncludedType mealsIncludedType; + + private int breakfastNumber; + + public MealsIncludedDTO() { + } + + public MealsIncludedDTO(MealsIncludedType type) { + } + + public MealsIncludedType getMealsIncludedType() { + return mealsIncludedType; + } + + public void setMealsIncludedType(MealsIncludedType mealsIncludedType) { + this.mealsIncludedType = mealsIncludedType; + } + + public int getBreakfastNumber() { + return breakfastNumber; + } + + public void setBreakfastNumber(int breakfastNumber) { + this.breakfastNumber = breakfastNumber; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/MealsIncludedType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/MealsIncludedType.java new file mode 100755 index 0000000000..385ebb7fb9 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/MealsIncludedType.java @@ -0,0 +1,5 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public enum MealsIncludedType { + UNKNOWN +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/PaymentType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/PaymentType.java new file mode 100755 index 0000000000..9f460f3e21 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/PaymentType.java @@ -0,0 +1,6 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public enum PaymentType { + POA, + PREPAY +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/ProviderChainDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ProviderChainDTO.java new file mode 100755 index 0000000000..bffa6aed98 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ProviderChainDTO.java @@ -0,0 +1,16 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import java.util.List; + +public class ProviderChainDTO extends AbstractDTO{ + private List providers; + + + public List getProviders() { + return providers; + } + + public void setProviders(List providers) { + this.providers = providers; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/RateDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/RateDTO.java new file mode 100755 index 0000000000..081d3f2a14 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/RateDTO.java @@ -0,0 +1,31 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public class RateDTO extends AbstractDTO{ + private DateRangeDTO dateRange; + private SimpleAmountDTO pureAmount; + private MealsIncludedDTO mealsIncluded; + + public DateRangeDTO getDateRange() { + return dateRange; + } + + public void setDateRange(DateRangeDTO dateRange) { + this.dateRange = dateRange; + } + + public SimpleAmountDTO getPureAmount() { + return pureAmount; + } + + public void setPureAmount(SimpleAmountDTO pureAmount) { + this.pureAmount = pureAmount; + } + + public MealsIncludedDTO getMealsIncluded() { + return mealsIncluded; + } + + public void setMealsIncluded(MealsIncludedDTO mealsIncluded) { + this.mealsIncluded = mealsIncluded; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/RatePlanDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/RatePlanDTO.java new file mode 100755 index 0000000000..23a1306714 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/RatePlanDTO.java @@ -0,0 +1,87 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import java.util.List; + +public class RatePlanDTO extends AbstractDTO{ + private String code; + private String name; + private FreeMealDTO freeMeal; + private PaymentType paymentType; + private List taxes; + private List serviceCharges; + private boolean needGuarantee; + private CancelPolicyDTO cancelPolicy; + private List availGuarantees; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public FreeMealDTO getFreeMeal() { + return freeMeal; + } + + public void setFreeMeal(FreeMealDTO freeMeal) { + this.freeMeal = freeMeal; + } + + public PaymentType getPaymentType() { + return paymentType; + } + + public void setPaymentType(PaymentType paymentType) { + this.paymentType = paymentType; + } + + public List getTaxes() { + return taxes; + } + + public void setTaxes(List taxes) { + this.taxes = taxes; + } + + public List getServiceCharges() { + return serviceCharges; + } + + public void setServiceCharges(List serviceCharges) { + this.serviceCharges = serviceCharges; + } + + public boolean isNeedGuarantee() { + return needGuarantee; + } + + public void setNeedGuarantee(boolean needGuarantee) { + this.needGuarantee = needGuarantee; + } + + public CancelPolicyDTO getCancelPolicy() { + return cancelPolicy; + } + + public void setCancelPolicy(CancelPolicyDTO cancelPolicy) { + this.cancelPolicy = cancelPolicy; + } + + public List getAvailGuarantees() { + return availGuarantees; + } + + public void setAvailGuarantees(List availGuarantees) { + this.availGuarantees = availGuarantees; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/ResponseHeader.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ResponseHeader.java new file mode 100755 index 0000000000..02641952aa --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/ResponseHeader.java @@ -0,0 +1,20 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public class ResponseHeader extends AbstractDTO{ + private String taskId; + + public ResponseHeader() { + } + + public ResponseHeader(String taskId) { + this.taskId = taskId; + } + + public String getTaskId() { + return taskId; + } + + public void setTaskId(String taskId) { + this.taskId = taskId; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/RoomRateDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/RoomRateDTO.java new file mode 100755 index 0000000000..2263065807 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/RoomRateDTO.java @@ -0,0 +1,15 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import java.util.List; + +public class RoomRateDTO extends AbstractDTO{ + private List rates; + + public List getRates() { + return rates; + } + + public void setRates(List rates) { + this.rates = rates; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/RoomStayCandidateDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/RoomStayCandidateDTO.java new file mode 100755 index 0000000000..efbaac7a16 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/RoomStayCandidateDTO.java @@ -0,0 +1,37 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.fastjson.annotation.JSONField; + +public class RoomStayCandidateDTO extends AbstractDTO{ + private int numberOfUnits; + private List guests = new ArrayList(); + + public RoomStayCandidateDTO() { + } + + public RoomStayCandidateDTO(int numberOfUnits, List guests) { + this.numberOfUnits = numberOfUnits; + this.guests = guests; + } + + @JSONField(name="Unit") + public int getNumberOfUnits() { + return numberOfUnits; + } + + @JSONField(name="Unit") + public void setNumberOfUnits(int numberOfUnits) { + this.numberOfUnits = numberOfUnits; + } + + public List getGuests() { + return guests; + } + + public void setGuests(List guests) { + this.guests = guests; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/RoomTypeDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/RoomTypeDTO.java new file mode 100755 index 0000000000..104a292cba --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/RoomTypeDTO.java @@ -0,0 +1,174 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import java.util.ArrayList; +import java.util.List; + +public class RoomTypeDTO extends AbstractDTO { + private String code; + + private String name; + + private String description; + + private List amenities = new ArrayList(); + + private CompositeType compositeType = CompositeType.UNKNOWN; + + private Integer floor; + + private SmokingType smokingType = SmokingType.INDIFFERENT; + + private String sizeMeasurement; + + private Integer bedCount; + + private Integer adultCount; + + private Integer childCount; + + private Integer maxGuestCount; + + private Integer extraBedCount; + + private BathType bathType; + + private InternetDTO internet; + + private TPAExtensionsDTO tpaExtensions; + + public RoomTypeDTO() { + } + + public RoomTypeDTO(String code, String name) { + this.code = code; + this.name = name; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getAmenities() { + return amenities; + } + + public void setAmenities(List amenities) { + this.amenities = amenities; + } + + public CompositeType getCompositeType() { + return compositeType; + } + + public void setCompositeType(CompositeType compositeType) { + this.compositeType = compositeType; + } + + public Integer getFloor() { + return floor; + } + + public void setFloor(Integer floor) { + this.floor = floor; + } + + public SmokingType getSmokingType() { + return smokingType; + } + + public void setSmokingType(SmokingType smokingType) { + this.smokingType = smokingType; + } + + public String getSizeMeasurement() { + return sizeMeasurement; + } + + public void setSizeMeasurement(String sizeMeasurement) { + this.sizeMeasurement = sizeMeasurement; + } + + public TPAExtensionsDTO getTpaExtensions() { + return tpaExtensions; + } + + public void setTpaExtensions(TPAExtensionsDTO tpaExtensions) { + this.tpaExtensions = tpaExtensions; + } + + public Integer getAdultCount() { + return adultCount; + } + + public void setAdultCount(Integer adultCount) { + this.adultCount = adultCount; + } + + public Integer getChildCount() { + return childCount; + } + + public void setChildCount(Integer childCount) { + this.childCount = childCount; + } + + public Integer getMaxGuestCount() { + return maxGuestCount; + } + + public void setMaxGuestCount(Integer maxGuestCount) { + this.maxGuestCount = maxGuestCount; + } + + public Integer getExtraBedCount() { + return extraBedCount; + } + + public void setExtraBedCount(Integer extraBedCount) { + this.extraBedCount = extraBedCount; + } + + public BathType getBathType() { + return bathType; + } + + public void setBathType(BathType bathType) { + this.bathType = bathType; + } + + public Integer getBedCount() { + return bedCount; + } + + public void setBedCount(Integer bedCount) { + this.bedCount = bedCount; + } + + public InternetDTO getInternet() { + return internet; + } + + public void setInternet(InternetDTO internet) { + this.internet = internet; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/SimpleAmountDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/SimpleAmountDTO.java new file mode 100755 index 0000000000..8f2f302272 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/SimpleAmountDTO.java @@ -0,0 +1,24 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import java.math.BigDecimal; + +public class SimpleAmountDTO extends AbstractDTO{ + private Currency currency; + private BigDecimal amount; + + public Currency getCurrency() { + return currency; + } + + public void setCurrency(Currency currency) { + this.currency = currency; + } + + public BigDecimal getAmount() { + return amount; + } + + public void setAmount(BigDecimal amount) { + this.amount = amount; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/SmokingType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/SmokingType.java new file mode 100755 index 0000000000..01e4c45828 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/SmokingType.java @@ -0,0 +1,5 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public enum SmokingType { + INDIFFERENT +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/StayDateRangeDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/StayDateRangeDTO.java new file mode 100755 index 0000000000..5a1fcc25f4 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/StayDateRangeDTO.java @@ -0,0 +1,32 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import java.util.Date; + +public class StayDateRangeDTO extends AbstractDTO { + private Date checkInDate; + private Date checkOutDate; + + public StayDateRangeDTO() { + } + + public StayDateRangeDTO(Date checkInDate, Date checkOutDate) { + this.checkInDate = checkInDate; + this.checkOutDate = checkOutDate; + } + + public Date getCheckInDate() { + return checkInDate; + } + + public void setCheckInDate(Date checkInDate) { + this.checkInDate = checkInDate; + } + + public Date getCheckOutDate() { + return checkOutDate; + } + + public void setCheckOutDate(Date checkOutDate) { + this.checkOutDate = checkOutDate; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/SuccessDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/SuccessDTO.java new file mode 100755 index 0000000000..4eb669aa55 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/SuccessDTO.java @@ -0,0 +1,16 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import java.util.ArrayList; +import java.util.List; + +public class SuccessDTO extends AbstractDTO { + private List messages = new ArrayList(); + + public List getMessages() { + return messages; + } + + public void setMessages(List infos) { + this.messages = infos; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/TPAExtensionsDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/TPAExtensionsDTO.java new file mode 100755 index 0000000000..1ecef85476 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/TPAExtensionsDTO.java @@ -0,0 +1,22 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MultiHashtable; + +import java.util.HashMap; +import java.util.Map; + +public class TPAExtensionsDTO extends AbstractDTO { + private Map elements = new HashMap(); + + public Map getElements() { + return elements; + } + + public void setElements(Map elements) { + this.elements = elements; + } + + public void setElement(String key, String value) { + elements.put(key,value); + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/UniqueIDDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/UniqueIDDTO.java new file mode 100755 index 0000000000..287b70312a --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/UniqueIDDTO.java @@ -0,0 +1,43 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import com.alibaba.fastjson.annotation.JSONField; + +public class UniqueIDDTO extends AbstractDTO{ + private String companyName; + private String code; + private UniqueIDType type; + + public UniqueIDDTO() { + } + + public UniqueIDDTO(String code, UniqueIDType type) { + this.code = code; + this.type = type; + } + + @JSONField(name="CName") + public String getCompanyName() { + return companyName; + } + + @JSONField(name="CName") + public void setCompanyName(String companyName) { + this.companyName = companyName; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public UniqueIDType getType() { + return type; + } + + public void setType(UniqueIDType type) { + this.type = type; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/UniqueIDType.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/UniqueIDType.java new file mode 100755 index 0000000000..b031195d30 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/UniqueIDType.java @@ -0,0 +1,5 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public enum UniqueIDType { + HOTEL +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/WarningDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/WarningDTO.java new file mode 100755 index 0000000000..3817996ba7 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/WarningDTO.java @@ -0,0 +1,19 @@ +package com.derbysoft.spitfire.fastjson.dto; + +public class WarningDTO extends AbstractDTO{ + private String code; + private String message; + + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getMessage() { + return message; + } + public void setMessage(String message) { + this.message = message; + } +} diff --git a/src/test/java/com/derbysoft/spitfire/fastjson/dto/WarningsDTO.java b/src/test/java/com/derbysoft/spitfire/fastjson/dto/WarningsDTO.java new file mode 100755 index 0000000000..cc599c57a9 --- /dev/null +++ b/src/test/java/com/derbysoft/spitfire/fastjson/dto/WarningsDTO.java @@ -0,0 +1,17 @@ +package com.derbysoft.spitfire.fastjson.dto; + +import java.util.ArrayList; +import java.util.List; + +public class WarningsDTO extends AbstractDTO{ + private List warningList = new ArrayList(); + + public List getWarningList() { + return warningList; + } + + public void setWarningList(List warnings) { + this.warningList = warnings; + } + +} diff --git a/src/test/java/data/ReprUtil.java b/src/test/java/data/ReprUtil.java old mode 100644 new mode 100755 diff --git a/src/test/java/data/media/FieldMapping.java b/src/test/java/data/media/FieldMapping.java old mode 100644 new mode 100755 diff --git a/src/test/java/data/media/Image.java b/src/test/java/data/media/Image.java old mode 100644 new mode 100755 diff --git a/src/test/java/data/media/ImageDeserializer.java b/src/test/java/data/media/ImageDeserializer.java deleted file mode 100644 index 65d30b2413..0000000000 --- a/src/test/java/data/media/ImageDeserializer.java +++ /dev/null @@ -1,114 +0,0 @@ -package data.media; - -import java.lang.reflect.Type; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONScanner; -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.parser.ParserConfig; -import com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer; -import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; - -import data.media.Image.Size; - -public class ImageDeserializer extends ASMJavaBeanDeserializer implements ObjectDeserializer { - - public ImageDeserializer(ParserConfig mapping, Class clazz){ - super(mapping, clazz); - } - - public ImageDeserializer(){ - super(ParserConfig.getGlobalInstance(), Image.class); - } - - // "size":"LARGE","uri":"http://javaone.com/keynote_large.jpg","title":"Javaone Keynote","width":1024,"height":768 - private char[] size_ = "\"size\":".toCharArray(); - private char[] uri_ = "\"uri\":".toCharArray(); - private char[] titile_ = "\"title\":".toCharArray(); - private char[] width_ = "\"width\":".toCharArray(); - private char[] height_ = "\"height\":".toCharArray(); - - @SuppressWarnings("unchecked") - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - final JSONScanner lexer = (JSONScanner) parser.getLexer(); - - int height; - Size size; - String title; - String uri; - int width; - - - int mark = lexer.getBufferPosition(); - char mark_ch = lexer.getCurrent(); - int mark_token = lexer.token(); - - { - height = lexer.scanFieldInt(height_); - if (lexer.matchStat == JSONScanner.NOT_MATCH) { - // 退出快速模式, 进入常规模式 - lexer.reset(mark, mark_ch, mark_token); - return (T) super.deserialze(parser, clazz); - } - } - { - String value = lexer.scanFieldString(size_); - if (lexer.matchStat == JSONScanner.NOT_MATCH) { - // 退出快速模式, 进入常规模式 - lexer.reset(mark, mark_ch, mark_token); - return (T) super.deserialze(parser, clazz); - } - size = Size.valueOf(value); - } - { - title = lexer.scanFieldString(titile_); - if (lexer.matchStat == JSONScanner.NOT_MATCH) { - // 退出快速模式, 进入常规模式 - lexer.reset(mark, mark_ch, mark_token); - return (T) super.deserialze(parser, clazz); - } - } - { - uri = lexer.scanFieldString(uri_); - if (lexer.matchStat == JSONScanner.NOT_MATCH) { - // 退出快速模式, 进入常规模式 - lexer.reset(mark, mark_ch, mark_token); - return (T) super.deserialze(parser, clazz); - } - } - { - width = lexer.scanFieldInt(width_); - if (lexer.matchStat == JSONScanner.NOT_MATCH) { - // 退出快速模式, 进入常规模式 - lexer.reset(mark, mark_ch, mark_token); - return (T) super.deserialze(parser, clazz); - } - } - - - if (lexer.matchStat != JSONScanner.END) { - // 退出快速模式, 进入常规模式 - lexer.reset(mark, mark_ch, mark_token); - return (T) super.deserialze(parser, clazz); - } - - Image image = new Image(); - image.setSize(size); - image.setUri(uri); - image.setTitle(title); - image.setWidth(width); - image.setHeight(height); - - return (T) image; - } - - public int getFastMatchToken() { - return JSONToken.LBRACE; - } - - @Override - public Object createInstance(DefaultExtJSONParser parser, Type type) { - return new Image(); - } - -} diff --git a/src/test/java/data/media/Media.java b/src/test/java/data/media/Media.java old mode 100644 new mode 100755 index 9027be56fb..93a7875516 --- a/src/test/java/data/media/Media.java +++ b/src/test/java/data/media/Media.java @@ -11,27 +11,28 @@ public enum Player { JAVA, FLASH } - public String uri; - public String title; // Can be unset. - public int width; - public int height; - public String format; - public long duration; - public long size; - public int bitrate; // Can be unset. + private String uri; + private String title; // Can be unset. + private int width; + private int height; + private String format; + private long duration; + private long size; + private int bitrate; // Can be unset. // required by JSONiJ - public boolean hasBitrate; - public List persons; + private boolean hasBitrate; + private List persons; - public Player player; + private Player player; // msgpack requires this - public String copyright; // Can be unset. + public String copyright; // Can be unset. public Media(){ } - public Media(String uri, String title, int width, int height, String format, long duration, long size, int bitrate, boolean hasBitrate, List persons, Player player, String copyright){ + public Media(String uri, String title, int width, int height, String format, long duration, long size, int bitrate, + boolean hasBitrate, List persons, Player player, String copyright){ this.uri = uri; this.title = title; this.width = width; diff --git a/src/test/java/data/media/MediaContent.java b/src/test/java/data/media/MediaContent.java old mode 100644 new mode 100755 diff --git a/src/test/java/data/media/MediaContentDeserializer.java b/src/test/java/data/media/MediaContentDeserializer.java old mode 100644 new mode 100755 index 50b89626aa..bb9bdf280c --- a/src/test/java/data/media/MediaContentDeserializer.java +++ b/src/test/java/data/media/MediaContentDeserializer.java @@ -2,7 +2,7 @@ import java.lang.reflect.Type; -import com.alibaba.fastjson.parser.DefaultExtJSONParser; +import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONScanner; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; @@ -13,7 +13,7 @@ public class MediaContentDeserializer implements ObjectDeserializer { private final char[] mediaPrefix = "\"media\":".toCharArray(); private final char[] imagePrefix = "\"images\":".toCharArray(); - public T deserialze(DefaultExtJSONParser parser, Type clazz) { + public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { final JSONScanner lexer = (JSONScanner) parser.getLexer(); MediaContent object = new MediaContent(); @@ -22,10 +22,10 @@ public T deserialze(DefaultExtJSONParser parser, Type clazz) { if (mediaDeserializer == null) { //mediaDeserializer = parser.getMapping().getDeserializer(ObjectDeserializer.class); } - mediaDeserializer.deserialze(parser, clazz); + mediaDeserializer.deserialze(parser, clazz, null); lexer.matchField(imagePrefix); - imageDeserializer.deserialze(parser, clazz); + imageDeserializer.deserialze(parser, clazz, null); // if (lexer.token() != JSONToken.RBRACE) diff --git a/src/test/java/data/media/MediaDeserializer.java b/src/test/java/data/media/MediaDeserializer.java deleted file mode 100644 index a57dc3fa22..0000000000 --- a/src/test/java/data/media/MediaDeserializer.java +++ /dev/null @@ -1,153 +0,0 @@ -package data.media; - -import java.lang.reflect.Type; -import java.util.List; - -import com.alibaba.fastjson.parser.DefaultExtJSONParser; -import com.alibaba.fastjson.parser.JSONScanner; -import com.alibaba.fastjson.parser.JSONToken; -import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; - -import data.media.Media.Player; - -public class MediaDeserializer implements ObjectDeserializer { - - private char[] size_ = "\"size\":".toCharArray(); - private char[] format_ = "\"format\":".toCharArray(); - private char[] uri_ = "\"uri\":".toCharArray(); - private char[] title_ = "\"title\":".toCharArray(); - private char[] width_ = "\"width\":".toCharArray(); - private char[] height_ = "\"height\":".toCharArray(); - private char[] duration_ = "\"duration\":".toCharArray(); - private char[] bitrate_ = "\"bitrate\":".toCharArray(); - private char[] persons_ = "\"persons\":".toCharArray(); - private char[] player_ = "\"player\":".toCharArray(); - private char[] copyright_ = "\"copyright\":".toCharArray(); - - public T deserialze(DefaultExtJSONParser parser, Type clazz) { - // "size":58982400,"format":"video/mpg4","uri":"http://javaone.com/keynote.mpg","title":"Javaone Keynote","width":640,"height":480, - // "duration":18000000,"bitrate":262144,"persons":["Bill Gates","Steve Jobs"],"player":"JAVA" - - final JSONScanner lexer = (JSONScanner) parser.getLexer(); - - String uri; - String title; // Can be unset. - int width; - int height; - String format; - long duration; - long size; - int bitrate; // Can be unset. - List persons; - Player player; - String copyright; // Can be unset. - - int mark = lexer.getBufferPosition(); - char mark_ch = lexer.getCurrent(); - int mark_token = lexer.token(); - - { - size = lexer.scanFieldLong(size_); - if (lexer.matchStat == JSONScanner.NOT_MATCH) { - lexer.reset(mark, mark_ch, mark_token); - throw new UnsupportedOperationException(); - } - } - { - format = lexer.scanFieldString(format_); - if (lexer.matchStat == JSONScanner.NOT_MATCH) { - throw new UnsupportedOperationException(); - } - } - { - uri = lexer.scanFieldString(uri_); - if (lexer.matchStat == JSONScanner.NOT_MATCH) { - throw new UnsupportedOperationException(); - } - } - { - title = lexer.scanFieldString(title_); - if (lexer.matchStat == JSONScanner.NOT_MATCH) { - throw new UnsupportedOperationException(); - } - } - { - width = lexer.scanFieldInt(width_); - if (lexer.matchStat == JSONScanner.NOT_MATCH) { - throw new UnsupportedOperationException(); - } - } - { - height = lexer.scanFieldInt(height_); - if (lexer.matchStat == JSONScanner.NOT_MATCH) { - throw new UnsupportedOperationException(); - } - } - { - duration = lexer.scanFieldLong(duration_); - if (lexer.matchStat == JSONScanner.NOT_MATCH) { - throw new UnsupportedOperationException(); - } - } - { - bitrate = lexer.scanFieldInt(bitrate_); - if (lexer.matchStat == JSONScanner.NOT_MATCH) { - throw new UnsupportedOperationException(); - } - } - { - persons = lexer.scanFieldStringArray(persons_); - if (lexer.matchStat == JSONScanner.NOT_MATCH) { - throw new UnsupportedOperationException(); - } - } - { - String value = lexer.scanFieldString(player_); - if (lexer.matchStat == JSONScanner.NOT_MATCH) { - throw new UnsupportedOperationException(); - } - player = Player.valueOf(value); - } -// { -// copyright = lexer.scanFieldString(copyright_); -// if (lexer.matchStat == JSONScanner.NOT_MATCH) { -// throw new UnsupportedOperationException(); -// } -// } - -// String uri; -// String title; // Can be unset. -// int width; -// int height; -// String format; - -// long duration; -// long size; -// int bitrate; // Can be unset. -// List persons; -// Player player; -// String copyright; // Can be unset. - - Media media = new Media(); - media.setUri(uri); - media.setTitle(title); - media.setWidth(width); - media.setHeight(height); - media.setFormat(format); - - media.setDuration(duration); - media.setSize(size); - media.setBitrate(bitrate); - media.setPersons(persons); - media.setPlayer(player); - - // media.setCopyright(copyright); - - return (T) media; - } - - public int getFastMatchToken() { - return JSONToken.LBRACE; - } - -} diff --git a/src/test/java/data/media/writeAsArray/ImageDeserializer.java b/src/test/java/data/media/writeAsArray/ImageDeserializer.java new file mode 100644 index 0000000000..4424c3e726 --- /dev/null +++ b/src/test/java/data/media/writeAsArray/ImageDeserializer.java @@ -0,0 +1,45 @@ +package data.media.writeAsArray; + +import java.lang.reflect.Type; + +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +import data.media.Image; +import data.media.Image.Size; + +public class ImageDeserializer implements ObjectDeserializer { + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + Image image = new Image(); + + final JSONLexer lexer = parser.getLexer(); + if (lexer.token() != JSONToken.LBRACKET) { + throw new JSONException("error"); + } + + int height = lexer.scanInt(','); + int width = lexer.scanInt(','); + String sizeName = lexer.scanSymbolWithSeperator(parser.getSymbolTable(), ','); + String title = lexer.scanString(','); + String uri = lexer.scanString(']'); + + lexer.nextToken(JSONToken.COMMA); + + image.setHeight(height); + image.setWidth(width); + image.setSize(Size.valueOf(sizeName)); + image.setTitle(title); + image.setUri(uri); + return (T) image; + } + + public int getFastMatchToken() { + return JSONToken.LBRACKET; + } + +} \ No newline at end of file diff --git a/src/test/java/data/media/writeAsArray/ImageSerializer.java b/src/test/java/data/media/writeAsArray/ImageSerializer.java new file mode 100644 index 0000000000..c6d76c7b3f --- /dev/null +++ b/src/test/java/data/media/writeAsArray/ImageSerializer.java @@ -0,0 +1,29 @@ +package data.media.writeAsArray; + +import java.io.IOException; +import java.lang.reflect.Type; + +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.ObjectSerializer; +import com.alibaba.fastjson.serializer.SerializeWriter; + +import data.media.Image; + +public class ImageSerializer implements ObjectSerializer { + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + Image image = (Image) object; + + SerializeWriter out = serializer.getWriter(); + out.write('['); + + out.writeIntAndChar(image.getHeight(), ','); + out.writeIntAndChar(image.getWidth(), ','); + out.writeString(image.getSize().name(), ','); + out.writeString(image.getTitle(), ','); + out.writeString(image.getUri()); + + out.write(']'); + } + +} diff --git a/src/test/java/data/media/writeAsArray/MediaContentDeserializer.java b/src/test/java/data/media/writeAsArray/MediaContentDeserializer.java new file mode 100644 index 0000000000..f03ef5b56d --- /dev/null +++ b/src/test/java/data/media/writeAsArray/MediaContentDeserializer.java @@ -0,0 +1,56 @@ +package data.media.writeAsArray; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +import data.media.Image; +import data.media.Media; +import data.media.MediaContent; + +public class MediaContentDeserializer implements ObjectDeserializer { + + MediaDeserializer mediaDeser = new MediaDeserializer(); + ImageDeserializer imageDesc = new ImageDeserializer(); + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + JSONLexer lexer = parser.getLexer(); + + parser.accept(JSONToken.LBRACKET, JSONToken.LBRACKET); + Media media = mediaDeser.deserialze(parser, Media.class, "media"); + parser.accept(JSONToken.COMMA, JSONToken.LBRACKET); + + parser.accept(JSONToken.LBRACKET, JSONToken.LBRACKET); + List images = new ArrayList(); + int index = 0; + for (;;) { + Image image = imageDesc.deserialze(parser, Image.class, index); + images.add(image); + index++; + if (lexer.token() == JSONToken.COMMA) { + lexer.nextToken(JSONToken.LBRACKET); + } else { + break; + } + } + parser.accept(JSONToken.RBRACKET, JSONToken.RBRACKET); + + parser.accept(JSONToken.RBRACKET, JSONToken.EOF); + + MediaContent content = new MediaContent(); + content.setMedia(media); + content.setImages(images); + return (T) content; + } + + public int getFastMatchToken() { + return 0; + } + +} \ No newline at end of file diff --git a/src/test/java/data/media/writeAsArray/MediaContentSerializer.java b/src/test/java/data/media/writeAsArray/MediaContentSerializer.java new file mode 100644 index 0000000000..0b84d2f66f --- /dev/null +++ b/src/test/java/data/media/writeAsArray/MediaContentSerializer.java @@ -0,0 +1,40 @@ +package data.media.writeAsArray; + +import java.io.IOException; +import java.lang.reflect.Type; + +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.ObjectSerializer; +import com.alibaba.fastjson.serializer.SerializeWriter; + +import data.media.Image; +import data.media.Media; +import data.media.MediaContent; + +public class MediaContentSerializer implements ObjectSerializer { + private MediaSerializer mediaSerilaizer = new MediaSerializer(); + private ImageSerializer imageSerilaizer = new ImageSerializer(); + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + MediaContent entity = (MediaContent) object; + + SerializeWriter out = serializer.getWriter(); + out.write('['); + + mediaSerilaizer.write(serializer, entity.getMedia(), "media", Media.class, 0); + out.write(','); + + out.write('['); + for (int i = 0; i < entity.getImages().size(); ++i) { + if (i != 0) { + out.write(','); + } + Image image = entity.getImages().get(i); + imageSerilaizer.write(serializer, image, i, fieldType, 0); + } + out.write(']'); + + out.write(']'); + } + +} \ No newline at end of file diff --git a/src/test/java/data/media/writeAsArray/MediaDeserializer.java b/src/test/java/data/media/writeAsArray/MediaDeserializer.java new file mode 100644 index 0000000000..54e4336a70 --- /dev/null +++ b/src/test/java/data/media/writeAsArray/MediaDeserializer.java @@ -0,0 +1,63 @@ +package data.media.writeAsArray; + +import java.lang.reflect.Type; +import java.util.List; + +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.parser.DefaultJSONParser; +import com.alibaba.fastjson.parser.JSONLexer; +import com.alibaba.fastjson.parser.JSONToken; +import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; + +import data.media.Media; +import data.media.Media.Player; + +public class MediaDeserializer implements ObjectDeserializer { + + @SuppressWarnings("unchecked") + public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { + final JSONLexer lexer = parser.getLexer(); + + if (lexer.token() != JSONToken.LBRACKET) { + throw new JSONException("error"); + } + + Media media = new Media(); + + int bitrate = lexer.scanInt(','); + int height = lexer.scanInt(','); + int width = lexer.scanInt(','); + String copyright = lexer.scanString(','); + long duration = lexer.scanLong(','); + String format = lexer.scanString(','); + + List persons = (List) lexer.scanStringArray(List.class, ','); + + String playerName = lexer.scanSymbolWithSeperator(parser.getSymbolTable(), ','); + long size = lexer.scanLong(','); + String title = lexer.scanString(','); + String uri = lexer.scanString(']'); + + lexer.nextToken(JSONToken.COMMA); + + media.setBitrate(bitrate); + media.setHeight(height); + media.setWidth(width); + media.setCopyright(copyright); + media.setDuration(duration); + media.setFormat(format); + media.setPersons(persons); + media.setPlayer(playerName == null ? null : Player.valueOf(playerName)); + media.setSize(size); + media.setTitle(title); + media.setUri(uri); + + return (T) media; + + } + + public int getFastMatchToken() { + return JSONToken.LBRACKET; + } + +} diff --git a/src/test/java/data/media/writeAsArray/MediaSerializer.java b/src/test/java/data/media/writeAsArray/MediaSerializer.java new file mode 100644 index 0000000000..01ec22287d --- /dev/null +++ b/src/test/java/data/media/writeAsArray/MediaSerializer.java @@ -0,0 +1,40 @@ +package data.media.writeAsArray; + +import java.io.IOException; +import java.lang.reflect.Type; + +import com.alibaba.fastjson.serializer.JSONSerializer; +import com.alibaba.fastjson.serializer.ObjectSerializer; +import com.alibaba.fastjson.serializer.SerializeWriter; + +import data.media.Media; + +public class MediaSerializer implements ObjectSerializer { + + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + Media media = (Media) object; + + SerializeWriter out = serializer.getWriter(); + out.write('['); + + out.writeIntAndChar(media.getBitrate(), ','); + out.writeIntAndChar(media.getHeight(), ','); + out.writeIntAndChar(media.getWidth(), ','); + out.writeString(media.getCopyright(), ','); + out.writeLongAndChar(media.getDuration(), ','); + out.writeString(media.getFormat(), ','); + out.write('['); + for (int i = 0; i < media.getPersons().size(); ++i) { + if(i != 0) { + out.write(','); + } + out.writeString(media.getPersons().get(i)); + } + out.write("],"); + out.writeString(media.getPlayer().name(), ','); + out.writeLongAndChar(media.getSize(), ','); + out.writeString(media.getTitle(), ','); + out.writeString(media.getUri(), ']'); + } + +} \ No newline at end of file diff --git a/src/test/resources/1.txt b/src/test/resources/1.txt old mode 100644 new mode 100755 diff --git a/src/test/resources/2.json b/src/test/resources/2.json new file mode 100755 index 0000000000..e6c0cd3c8d --- /dev/null +++ b/src/test/resources/2.json @@ -0,0 +1 @@ +{"company":{"aliwwStatus":0,"id":0,"name":"红茄子印像","sellerId":"1000000301","trustScore":0},"count":5,"pagecount":0,"pageindex":0,"resultList":[{"atoms":[{"bankImage":true,"height":300,"imageURL":"http://web.tcloudapp.cn/temp/1000000001/18C3C7410D9B1E5B964E0BAA6268053A727510F2CAC5E70E72C3C7DE48AE1.jpg_640x400.jpg","style":0,"title":"","uIActionParams":{},"versionCode":0,"width":640},{"bankImage":true,"height":300,"imageURL":"http://web.tcloudapp.cn/temp/1000000001/1B0F08D14F1F793842AC87B17003C52AE408D8FCFD26628EF83E65C3CFFD2.jpg_640x400.jpg","style":0,"title":"","uIActionParams":{},"versionCode":0,"width":640},{"bankImage":true,"height":300,"imageURL":"http://web.tcloudapp.cn/temp/1000000001/5857874C9779EF6EFCAC9FD55702FA4D0EE5522F035F2E14A9972CC955123.jpg_640x400.jpg","style":0,"title":"","uIActionParams":{},"versionCode":0,"width":640}],"height":300,"type":"slides","versionCode":0,"width":640},{"atoms":[{"action":"go_to_search","bankImage":true,"colorBackground":"#333333","height":100,"style":1,"title":"人气宝贝","uIActionParams":{"offerRequest":{"beginPage":0,"companyId":1000000301,"deliveryFree":false,"descendOrder":true,"discount":false,"pageSize":0,"pop":false,"priceEnabled":false,"priceEnd":3.4028235E38,"priceStart":0,"sortType":"renqi"}},"versionCode":0,"width":640}],"height":100,"type":"channel_item","versionCode":0,"width":640},{"atoms":[{"bankImage":true,"height":289,"imageURL":"http://img03.taobaocdn.com/bao/uploaded/i3/T1OdxDXXtvXXcWWv_a_090851.jpg_250x250.jpg","offerId":102077,"originalPrice":{"amount":119.30,"cent":11930,"currencyCode":"CNY"},"price":{"amount":119.30,"cent":11930,"currencyCode":"CNY"},"style":0,"title":"限时包邮 8*8照片书|相册影集|婴儿|宝宝|儿童/diy定制|制作 简单","versionCode":0,"volume":0,"width":213},{"bankImage":true,"height":289,"imageURL":"http://img05.taobaocdn.com/bao/uploaded/i5/T1w9NDXipxXXay20Q4_052428.jpg_250x250.jpg","offerId":102076,"originalPrice":{"amount":119.30,"cent":11930,"currencyCode":"CNY"},"price":{"amount":119.30,"cent":11930,"currencyCode":"CNY"},"style":0,"title":"限时包邮 8*8照片书|相册影集|婴儿|宝宝|儿童/diy定制|制作 D调","versionCode":0,"volume":0,"width":213},{"bankImage":true,"height":289,"imageURL":"http://img06.taobaocdn.com/bao/uploaded/i6/T1hIRDXalGXXa_aivX_085522.jpg_250x250.jpg","offerId":102075,"originalPrice":{"amount":119.30,"cent":11930,"currencyCode":"CNY"},"price":{"amount":119.30,"cent":11930,"currencyCode":"CNY"},"style":0,"title":"限时包邮 8*8照片书|相册影集|婴儿|宝宝|儿童/diy定制|制作 青春","versionCode":0,"volume":0,"width":213},{"bankImage":true,"height":289,"imageURL":"http://img01.taobaocdn.com/bao/uploaded/i1/T1GyuyXjxDXXcE22E8_100415.jpg_250x250.jpg","offerId":102074,"originalPrice":{"amount":158.00,"cent":15800,"currencyCode":"CNY"},"price":{"amount":158.00,"cent":15800,"currencyCode":"CNY"},"style":0,"title":"马伊琍同款项链 蝴蝶 正品925纯银 假一罰十 DIY字母名字项链定做","versionCode":0,"volume":0,"width":213},{"bankImage":true,"height":289,"imageURL":"http://img02.taobaocdn.com/bao/uploaded/i2/T1Uw4IXmRyXXayTOM6_062232.jpg_250x250.jpg","offerId":102073,"originalPrice":{"amount":158.00,"cent":15800,"currencyCode":"CNY"},"price":{"amount":158.00,"cent":15800,"currencyCode":"CNY"},"style":0,"title":"马伊琍同款项链 爱心天使 正品925纯银 假一罰十 DIY名字项链定做","versionCode":0,"volume":0,"width":213},{"bankImage":true,"height":289,"imageURL":"http://img08.taobaocdn.com/bao/uploaded/i8/T1vElPXcFEXXb6e.34_054443.jpg_250x250.jpg","offerId":102072,"originalPrice":{"amount":238.00,"cent":23800,"currencyCode":"CNY"},"price":{"amount":238.00,"cent":23800,"currencyCode":"CNY"},"style":0,"title":"包邮!银条男士项链 正品925纯银刻字 实心项链 DIY刻字项链定做","versionCode":0,"volume":0,"width":213}],"height":578,"type":"offer_item","versionCode":0,"width":640},{"atoms":[{"action":"go_to_search","bankImage":true,"colorBackground":"#333333","height":100,"style":1,"title":"最新上市","uIActionParams":{"offerRequest":{"beginPage":0,"companyId":1000000301,"deliveryFree":false,"descendOrder":true,"discount":false,"pageSize":0,"pop":false,"priceEnabled":false,"priceEnd":3.4028235E38,"priceStart":0,"sortType":"time"}},"versionCode":0,"width":640}],"height":100,"type":"channel_item","versionCode":0,"width":640},{"atoms":[{"bankImage":true,"height":289,"imageURL":"http://img01.taobaocdn.com/bao/uploaded/i1/T17OxOXi0yXXau1o75_060407.jpg_250x250.jpg","offerId":102041,"originalPrice":{"amount":46.80,"cent":4680,"currencyCode":"CNY"},"price":{"amount":46.80,"cent":4680,"currencyCode":"CNY"},"style":0,"title":"限时抢购 跨年台历定制/照片定做/制作/挂历/日历 8寸25页","versionCode":0,"volume":0,"width":213},{"bankImage":true,"height":289,"imageURL":"http://img08.taobaocdn.com/bao/uploaded/i8/T12yhOXh0EXXXfz.I5_060343.jpg_250x250.jpg","offerId":102042,"originalPrice":{"amount":46.80,"cent":4680,"currencyCode":"CNY"},"price":{"amount":46.80,"cent":4680,"currencyCode":"CNY"},"style":0,"title":"限时抢购 跨年台历定制/照片定做/制作/挂历/日历 8寸25页 宝宝","versionCode":0,"volume":0,"width":213},{"bankImage":true,"height":289,"imageURL":"http://img05.taobaocdn.com/bao/uploaded/i5/T1fpx1XfdoXXcDATUZ_033624.jpg_250x250.jpg","offerId":102043,"originalPrice":{"amount":44.80,"cent":4480,"currencyCode":"CNY"},"price":{"amount":44.80,"cent":4480,"currencyCode":"CNY"},"style":0,"title":"限时秒杀 8x6画册|相册/照片书/影集|宝宝儿童/diy定制|制作 生活","versionCode":0,"volume":0,"width":213},{"bankImage":true,"height":289,"imageURL":"http://img06.taobaocdn.com/bao/uploaded/i6/T1jyVOXntsXXaQrU35_060401.jpg_250x250.jpg","offerId":102044,"originalPrice":{"amount":46.80,"cent":4680,"currencyCode":"CNY"},"price":{"amount":46.80,"cent":4680,"currencyCode":"CNY"},"style":0,"title":"限时抢购 跨年台历定制/照片定做/制作/挂历/日历 8寸25页 看海","versionCode":0,"volume":0,"width":213},{"bankImage":true,"height":289,"imageURL":"http://img01.taobaocdn.com/bao/uploaded/i1/T1yrX1XjJbXXcDvJfa_090502.jpg_250x250.jpg","offerId":102045,"originalPrice":{"amount":44.80,"cent":4480,"currencyCode":"CNY"},"price":{"amount":44.80,"cent":4480,"currencyCode":"CNY"},"style":0,"title":"限时秒杀 8x6画册|相册/照片书/影集|宝宝儿童/diy定制|制作 曾经","versionCode":0,"volume":0,"width":213},{"bankImage":true,"height":289,"imageURL":"http://img05.taobaocdn.com/bao/uploaded/i5/T1rUROXcNAXXX_AA.6_062529.jpg_250x250.jpg","offerId":102046,"originalPrice":{"amount":39.59,"cent":3959,"currencyCode":"CNY"},"price":{"amount":39.59,"cent":3959,"currencyCode":"CNY"},"style":0,"title":"卖疯了!国际一级白瓷!个性水杯定制 印图照片 情侣马克杯 春日","versionCode":0,"volume":0,"width":213}],"height":578,"type":"offer_item","versionCode":0,"width":640}],"totalCount":0} \ No newline at end of file diff --git a/src/test/resources/META-INF/services/com.alibaba.fastjson.serializer.AutowiredObjectSerializer b/src/test/resources/META-INF/services/com.alibaba.fastjson.serializer.AutowiredObjectSerializer new file mode 100755 index 0000000000..83103297bb --- /dev/null +++ b/src/test/resources/META-INF/services/com.alibaba.fastjson.serializer.AutowiredObjectSerializer @@ -0,0 +1,3 @@ +com.alibaba.json.demo.XAutowiredObjectSerializer +#com.alibaba.json.demo.XAutowiredObjectSerializer +com.alibaba.json.demo.ErrorObjectSerializer \ No newline at end of file diff --git a/src/test/resources/META-INF/services/javax.ws.rs.ext.MessageBodyReader b/src/test/resources/META-INF/services/javax.ws.rs.ext.MessageBodyReader deleted file mode 100644 index 8c8be0de7b..0000000000 --- a/src/test/resources/META-INF/services/javax.ws.rs.ext.MessageBodyReader +++ /dev/null @@ -1 +0,0 @@ -com.alibaba.dragoon.demo.rest.impl.FastjsonMessageBodyReader \ No newline at end of file diff --git a/src/test/resources/META-INF/services/javax.ws.rs.ext.MessageBodyWriter b/src/test/resources/META-INF/services/javax.ws.rs.ext.MessageBodyWriter deleted file mode 100644 index c91cbbd932..0000000000 --- a/src/test/resources/META-INF/services/javax.ws.rs.ext.MessageBodyWriter +++ /dev/null @@ -1 +0,0 @@ -com.alibaba.dragoon.demo.rest.impl.FastjsonMessageBodyWriter \ No newline at end of file diff --git a/src/test/resources/data/media.1.cks b/src/test/resources/data/media.1.cks old mode 100644 new mode 100755 diff --git a/src/test/resources/data/media.1.json b/src/test/resources/data/media.1.json old mode 100644 new mode 100755 diff --git a/src/test/resources/data/media.2.cks b/src/test/resources/data/media.2.cks old mode 100644 new mode 100755 diff --git a/src/test/resources/data/media.2.json b/src/test/resources/data/media.2.json old mode 100644 new mode 100755 diff --git a/src/test/resources/data/media.3.cks b/src/test/resources/data/media.3.cks old mode 100644 new mode 100755 diff --git a/src/test/resources/data/media.4.cks b/src/test/resources/data/media.4.cks old mode 100644 new mode 100755 diff --git a/src/test/resources/epub.json b/src/test/resources/epub.json new file mode 100755 index 0000000000..81313b20a6 --- /dev/null +++ b/src/test/resources/epub.json @@ -0,0 +1 @@ +{"metadata":{"properties":{"isSupportPic":"no","sort":"教材","finishflag":"no","mcpother":"","shortnominateinfor":":未命名","chargeway":"","toolversion":"v1.4","fristissueflag":"no","mcpsalevolume":"","editionsnumber":"","actualbook":"0","chargeflag":"no","author":"教育出版社","mcpclicknum":"","isbn":"","chargefristnum":"","p2maga":"../maga/book.p2maga","nominateinfor":"未命名","longdescription":"这是一本电子教材","publisherdate":"2012-03-15","bookheight":"297","infopricesuggest":"","publishflag":"no","mcpcommend":"","mcpfristissue":"","keyword":"","mcpbookid":"","salespromotionflag":"no","authordescription":"","shortdescription":"","recommendreason":"","mcpcollection":"","bookseries":"1","bookname":"未命名","mcprecommend":"no","secondsort":"语文","mcpchargefristnum":"","bookwidth":"210"},"encrypt":true},"pageList":[{"src":null,"imageUrl":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/oebps/chap0001/images/orig/img1.jpg","hotPoints":null,"pageNum":"1"},{"src":null,"imageUrl":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/oebps/chap0001/images/orig/img2.jpg","hotPoints":null,"pageNum":"2"},{"src":null,"imageUrl":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/oebps/chap0002/images/orig/img1.jpg","hotPoints":null,"pageNum":"3"},{"src":null,"imageUrl":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/oebps/chap0002/images/orig/img2.jpg","hotPoints":[{"type":"Normal","content":null,"parameters":null,"description":"Unit 9 Festivals Part A","left":"193.2608696","right":"205.0543478","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/flash/2012021313291142600023.swf","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/OrdiFlash.png","actiontype":"webview/swf","reading":null,"actionname":null,"dcfSrc":"multimedia/flash/2012021313291142600023.swf.dcf","menulist":null,"pen":null,"dictionary":null,"top":"49.4361290","bottom":"61.3161290","zoneList":[{"color":null,"transparency":null,"left":"192.8804348","right":"205.4347826","top":"49.0529032","bottom":"61.6993548"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Unit 9 Festivals Part A","left":"177.2826087","right":"189.0760870","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142600024.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HideAudio.png","actiontype":"audio/mpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142600024.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":"49.0529032","bottom":"60.9329032","zoneList":[{"color":null,"transparency":null,"left":"176.1413043","right":"189.4565217","top":"48.6696774","bottom":"61.3161290"}],"starttime":null,"endtime":null},{"type":"Normal","content":null,"parameters":null,"description":"Easter","left":"87.8804348","right":"99.6739130","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/flash/2012021313291142600025.swf","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/OrdiFlash.png","actiontype":"webview/swf","reading":null,"actionname":null,"dcfSrc":"multimedia/flash/2012021313291142600025.swf.dcf","menulist":null,"pen":null,"dictionary":null,"top":"133.7458065","bottom":"145.6258065","zoneList":[{"color":null,"transparency":null,"left":"86.3586957","right":"100.0543478","top":"132.2129032","bottom":"146.0090323"}],"starttime":null,"endtime":null},{"type":"Normal","content":null,"parameters":null,"description":"Halloween","left":"60.1086957","right":"71.9021739","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/flash/2012021313291142610026.swf","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/OrdiFlash.png","actiontype":"webview/swf","reading":null,"actionname":null,"dcfSrc":"multimedia/flash/2012021313291142610026.swf.dcf","menulist":null,"pen":null,"dictionary":null,"top":"193.1458065","bottom":"205.0258065","zoneList":[{"color":null,"transparency":null,"left":"59.3478261","right":"72.2826087","top":"191.9961290","bottom":"205.4090323"}],"starttime":null,"endtime":null},{"type":"Normal","content":null,"parameters":null,"description":"The Dragon Boat Festival","left":"136.9565217","right":"148.7500000","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/flash/2012021313291142610027.swf","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/OrdiFlash.png","actiontype":"webview/swf","reading":null,"actionname":null,"dcfSrc":"multimedia/flash/2012021313291142610027.swf.dcf","menulist":null,"pen":null,"dictionary":null,"top":"128.7638710","bottom":"140.6438710","zoneList":[{"color":null,"transparency":null,"left":"136.5760870","right":"149.1304348","top":"128.3806452","bottom":"141.0270968"}],"starttime":null,"endtime":null},{"type":"Normal","content":null,"parameters":null,"description":"Jingle bells","left":"143.4239130","right":"155.2173913","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/flash/2012031513318169610001.swf","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/OrdiFlash.png","actiontype":"webview/swf","reading":null,"actionname":null,"dcfSrc":"multimedia/flash/2012031513318169610001.swf.dcf","menulist":null,"pen":null,"dictionary":null,"top":"11.4967742","bottom":"23.3767742","zoneList":[{"color":null,"transparency":null,"left":"0.3804348","right":"159.0217391","top":"4.5987097","bottom":"29.5083871"}],"starttime":null,"endtime":null},{"type":"Normal","content":null,"parameters":null,"description":"Unit 9 Festivals 预习资料","left":"167.0108696","right":"178.8043478","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/office/2012031513318169610002.doc","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/OrdiOffice.png","actiontype":"office","reading":null,"actionname":null,"dcfSrc":"multimedia/office/2012031513318169610002.doc.dcf","menulist":null,"pen":null,"dictionary":null,"top":"11.1135484","bottom":"22.9935484","zoneList":[{"color":null,"transparency":null,"left":"163.2065217","right":"184.5108696","top":"6.8980645","bottom":"26.8258065"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Easter(3)","left":"58.2065217","right":"70.0000000","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169610003.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169610003.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"90.0580645","bottom":"101.9380645","zoneList":[{"color":null,"transparency":null,"left":"46.4130435","right":"81.7934783","top":"73.1961290","bottom":"119.9496774"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"watch boat races(2)","left":"122.8804348","right":"134.6739130","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620004.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620004.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"84.6929032","bottom":"96.5729032","zoneList":[{"color":null,"transparency":null,"left":"110.3260870","right":"146.8478261","top":"73.5793548","bottom":"108.4529032"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Halloween(1)","left":"47.1739130","right":"58.9673913","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620005.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620005.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"154.4400000","bottom":"166.3200000","zoneList":[{"color":null,"transparency":null,"left":"33.8586957","right":"72.6630435","top":"144.0929032","bottom":"175.9006452"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Christmas","left":"123.6413043","right":"135.4347826","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620006.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620006.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"148.6916129","bottom":"160.5716129","zoneList":[{"color":null,"transparency":null,"left":"112.6086957","right":"146.8478261","top":"141.0270968","bottom":"169.7690323"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Chinese New Year(2)","left":"159.7826087","right":"171.5760870","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620007.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620007.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"148.3083871","bottom":"160.1883871","zoneList":[{"color":null,"transparency":null,"left":"149.5108696","right":"181.0869565","top":"140.6438710","bottom":"167.4696774"}],"starttime":null,"endtime":null},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142600024.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142600024.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"22.0652174","right":"175.3804348","top":"52.8851613","bottom":"59.7832258"}],"starttime":"1608","endtime":"9648"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142600024.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142600024.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"112.6086957","right":"177.2826087","top":"112.6683871","bottom":"118.4167742"}],"starttime":"29419","endtime":"33274"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142600024.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142600024.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"35.7608696","right":"53.2608696","top":"124.1651613","bottom":"130.2967742"}],"starttime":"23251","endtime":"24971"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142600024.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142600024.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"55.5434783","right":"101.5760870","top":"124.5483871","bottom":"130.6800000"}],"starttime":"24990","endtime":"29399"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142600024.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142600024.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"121.3586957","right":"165.1086957","top":"119.1832258","bottom":"126.0812903"}],"starttime":"33290","endtime":"37203"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142600024.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142600024.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"97.0108696","right":"123.2608696","top":"170.1522581","bottom":"175.9006452"}],"starttime":"45085","endtime":"47469"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142600024.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142600024.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"38.0434783","right":"68.0978261","top":"177.4335484","bottom":"183.1819355"}],"starttime":"37221","endtime":"39917"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142600024.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142600024.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"140.7608696","right":"186.0326087","top":"172.0683871","bottom":"178.2000000"}],"starttime":"51338","endtime":"54722"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142600024.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142600024.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"97.0108696","right":"127.8260870","top":"178.2000000","bottom":"183.1819355"}],"starttime":"46577","endtime":"50121"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142600024.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142600024.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"33.0978261","right":"73.0434783","top":"183.9483871","bottom":"190.0800000"}],"starttime":"39933","endtime":"43895"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142600024.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142600024.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"140.7608696","right":"181.8478261","top":"178.9664516","bottom":"185.4812903"}],"starttime":"53566","endtime":"57171"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142600024.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142600024.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"75.3260870","right":"114.8913043","top":"193.1458065","bottom":"201.1935484"}],"starttime":"9660","endtime":"12210"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142600024.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142600024.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"86.3586957","right":"119.0760870","top":"209.6245161","bottom":"218.4387097"}],"starttime":"12231","endtime":"14473"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142600024.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142600024.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"35.7608696","right":"101.5760870","top":"272.4735484","bottom":"280.5212903"}],"starttime":"14486","endtime":"17352"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142600024.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142600024.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"122.5000000","right":"180.3260870","top":"277.0722581","bottom":"284.7367742"}],"starttime":"17371","endtime":"20289"}],"pageNum":"4"},{"src":null,"imageUrl":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/oebps/chap0003/images/orig/img1.jpg","hotPoints":[{"type":"Normal","content":null,"parameters":null,"description":"Unit 9 Festivals Part B1","left":"76.8478261","right":"88.6413043","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/flash/2012021313291142610028.swf","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/OrdiFlash.png","actiontype":"webview/swf","reading":null,"actionname":null,"dcfSrc":"multimedia/flash/2012021313291142610028.swf.dcf","menulist":null,"pen":null,"dictionary":null,"top":"19.5445161","bottom":"31.4245161","zoneList":[{"color":null,"transparency":null,"left":"75.3260870","right":"89.0217391","top":"19.1612903","bottom":"31.8077419"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Unit 9 Festivals Part B1","left":"61.2500000","right":"73.0434783","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610029.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HideAudio.png","actiontype":"audio/mpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610029.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":"18.7780645","bottom":"30.6580645","zoneList":[{"color":null,"transparency":null,"left":"60.1086957","right":"73.4239130","top":"18.3948387","bottom":"31.0412903"}],"starttime":null,"endtime":null},{"type":"Normal","content":null,"parameters":null,"description":"Merry christmas","left":"110.7065217","right":"122.5000000","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/flash/2012031513318169620008.swf","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/OrdiFlash.png","actiontype":"webview/swf","reading":null,"actionname":null,"dcfSrc":"multimedia/flash/2012031513318169620008.swf.dcf","menulist":null,"pen":null,"dictionary":null,"top":"59.7832258","bottom":"71.6632258","zoneList":[{"color":null,"transparency":null,"left":"107.2826087","right":"125.9239130","top":"55.9509677","bottom":"75.4954839"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Christmas day(3)","left":"51.3586957","right":"63.1521739","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620009.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620009.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"88.9083871","bottom":"100.7883871","zoneList":[{"color":null,"transparency":null,"left":"26.6304348","right":"87.8804348","top":"73.5793548","bottom":"116.5006452"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Halloween(6)","left":"155.5978261","right":"167.3913043","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620010.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620010.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"95.8064516","bottom":"107.6864516","zoneList":[{"color":null,"transparency":null,"left":"129.3478261","right":"193.2608696","top":"68.5974194","bottom":"135.2787097"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"chocolate eggs(2)","left":"53.6413043","right":"65.4347826","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620011.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620011.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"217.2890323","bottom":"229.1690323","zoneList":[{"color":null,"transparency":null,"left":"27.3913043","right":"91.3043478","top":"186.6309677","bottom":"259.0606452"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"watch boat races(3)","left":"151.4130435","right":"163.2065217","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620012.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620012.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"226.4864516","bottom":"238.3664516","zoneList":[{"color":null,"transparency":null,"left":"140.0000000","right":"174.2391304","top":"210.0077419","bottom":"254.8451613"}],"starttime":null,"endtime":null},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610029.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610029.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"35.7608696","right":"200.1086957","top":"11.8800000","bottom":"17.6283871"},{"color":null,"transparency":null,"left":"35.3804348","right":"59.3478261","top":"22.2270968","bottom":"28.7419355"}],"starttime":"1186","endtime":"8843"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610029.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610029.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"13.6956522","right":"68.8586957","top":"50.5858065","bottom":"56.7174194"},{"color":null,"transparency":null,"left":"13.3152174","right":"46.4130435","top":"58.6335484","bottom":"64.3819355"}],"starttime":"10548","endtime":"14500"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610029.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610029.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"77.6086957","right":"92.4456522","top":"54.4180645","bottom":"60.5496774"},{"color":null,"transparency":null,"left":"77.6086957","right":"107.2826087","top":"63.2322581","bottom":"70.1303226"}],"starttime":"14516","endtime":"16593"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610029.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610029.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"15.5978261","right":"62.0108696","top":"118.8000000","bottom":"125.6980645"}],"starttime":"16486","endtime":"18029"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610029.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610029.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"42.6086957","right":"94.3478261","top":"131.8296774","bottom":"139.8774194"},{"color":null,"transparency":null,"left":"43.7500000","right":"99.2934783","top":"141.4103226","bottom":"147.5419355"}],"starttime":"17880","endtime":"21471"}],"pageNum":"5"},{"src":null,"imageUrl":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/oebps/chap0003/images/orig/img2.jpg","hotPoints":[{"type":"Normal","content":null,"parameters":null,"description":"Unit 9 Festivals Part B2","left":"122.5000000","right":"134.2934783","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/flash/2012021313291142610030.swf","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/OrdiFlash.png","actiontype":"webview/swf","reading":null,"actionname":null,"dcfSrc":"multimedia/flash/2012021313291142610030.swf.dcf","menulist":null,"pen":null,"dictionary":null,"top":"169.3858065","bottom":"181.2658065","zoneList":[{"color":null,"transparency":null,"left":"121.3586957","right":"134.6739130","top":"167.4696774","bottom":"181.6490323"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Unit 9 Festivals Part B3","left":"180.7065217","right":"192.5000000","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012031513318169620013.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HideAudio.png","actiontype":"audio/mpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012031513318169620013.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":"186.6309677","bottom":"198.5109677","zoneList":[{"color":null,"transparency":null,"left":"177.2826087","right":"195.9239130","top":"183.1819355","bottom":"201.9600000"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Halloween(7)","left":"129.3478261","right":"141.1413043","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620014.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620014.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"100.4051613","bottom":"112.2851613","zoneList":[{"color":null,"transparency":null,"left":"123.6413043","right":"146.0869565","top":"77.0283871","bottom":"134.8954839"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Halloween(8)","left":"115.2717391","right":"127.0652174","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620015.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620015.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"221.5045161","bottom":"233.3845161","zoneList":[{"color":null,"transparency":null,"left":"101.5760870","right":"140.7608696","top":"207.7083871","bottom":"247.5638710"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"chocolate eggs(1)","left":"36.1413043","right":"47.9347826","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620016.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620016.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"219.9716129","bottom":"231.8516129","zoneList":[{"color":null,"transparency":null,"left":"20.9239130","right":"62.7717391","top":"201.9600000","bottom":"249.8632258"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"boat races(3)","left":"157.8804348","right":"169.6739130","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620017.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620017.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"255.6116129","bottom":"267.4916129","zoneList":[{"color":null,"transparency":null,"left":"142.6630435","right":"184.5108696","top":"238.3664516","bottom":"284.7367742"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"boat races(4)","left":"81.7934783","right":"93.5869565","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620018.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620018.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"101.5548387","bottom":"113.4348387","zoneList":[{"color":null,"transparency":null,"left":"76.0869565","right":"99.2934783","top":"77.0283871","bottom":"137.9612903"}],"starttime":null,"endtime":null}],"pageNum":"6"},{"src":null,"imageUrl":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/oebps/chap0004/images/orig/img1.jpg","hotPoints":[{"type":"Normal","content":null,"parameters":null,"description":"Unit 9 Festivals Part C","left":"73.4239130","right":"85.2173913","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/flash/2012021313291142610032.swf","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/OrdiFlash.png","actiontype":"webview/swf","reading":null,"actionname":null,"dcfSrc":"multimedia/flash/2012021313291142610032.swf.dcf","menulist":null,"pen":null,"dictionary":null,"top":"9.9638710","bottom":"21.8438710","zoneList":[{"color":null,"transparency":null,"left":"73.0434783","right":"85.5978261","top":"9.1974194","bottom":"22.2270968"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Unit 9 Festivals Part C","left":"57.8260870","right":"69.6195652","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610033.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HideAudio.png","actiontype":"audio/mpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610033.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":"9.5806452","bottom":"21.4606452","zoneList":[{"color":null,"transparency":null,"left":"57.4456522","right":"70.0000000","top":"9.1974194","bottom":"21.8438710"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"costume(5)","left":"155.9782609","right":"167.7717391","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620019.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620019.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"117.2670968","bottom":"129.1470968","zoneList":[{"color":null,"transparency":null,"left":"138.4782609","right":"184.5108696","top":"96.1896774","bottom":"148.6916129"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"costume(6)","left":"42.6086957","right":"54.4021739","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620020.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620020.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"233.0012903","bottom":"244.8812903","zoneList":[{"color":null,"transparency":null,"left":"35.0000000","right":"62.3913043","top":"210.3909677","bottom":"267.4916129"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"costume(4)","left":"135.8152174","right":"147.6086957","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620021.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620021.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"236.4503226","bottom":"248.3303226","zoneList":[{"color":null,"transparency":null,"left":"125.5434783","right":"157.8804348","top":"215.3729032","bottom":"268.2580645"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"costume(3)","left":"90.1630435","right":"101.9565217","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620022.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620022.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"231.8516129","bottom":"243.7316129","zoneList":[{"color":null,"transparency":null,"left":"82.1739130","right":"109.5652174","top":"208.8580645","bottom":"267.1083871"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Halloween(3)","left":"151.7934783","right":"163.5869565","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620023.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620023.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"168.6193548","bottom":"180.4993548","zoneList":[{"color":null,"transparency":null,"left":"130.4891304","right":"184.5108696","top":"159.0387097","bottom":"190.4632258"}],"starttime":null,"endtime":null},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610033.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610033.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"27.3913043","right":"55.5434783","top":"11.1135484","bottom":"19.9277419"}],"starttime":"1564","endtime":"2684"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610033.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610033.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"23.2065217","right":"88.2608696","top":"54.0348387","bottom":"65.5316129"}],"starttime":"4184","endtime":"6352"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610033.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610033.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"22.8260870","right":"117.1739130","top":"70.1303226","bottom":"76.2619355"}],"starttime":"6369","endtime":"11801"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610033.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610033.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"119.0760870","right":"189.0760870","top":"68.9806452","bottom":"76.2619355"},{"color":null,"transparency":null,"left":"22.8260870","right":"38.0434783","top":"78.1780645","bottom":"84.3096774"}],"starttime":"11814","endtime":"15352"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610033.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610033.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"40.3260870","right":"175.3804348","top":"77.7948387","bottom":"84.3096774"}],"starttime":"15370","endtime":"21014"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610033.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610033.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"22.8260870","right":"81.7934783","top":"96.5729032","bottom":"106.9200000"}],"starttime":"21028","endtime":"23283"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610033.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610033.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"22.8260870","right":"125.1630435","top":"109.9858065","bottom":"116.1174194"}],"starttime":"23304","endtime":"26661"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610033.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610033.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"23.2065217","right":"83.3152174","top":"118.4167742","bottom":"124.1651613"}],"starttime":"26676","endtime":"29256"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610033.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610033.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"84.0760870","right":"130.1086957","top":"118.4167742","bottom":"124.5483871"},{"color":null,"transparency":null,"left":"22.8260870","right":"94.7282609","top":"126.4645161","bottom":"131.8296774"}],"starttime":"29267","endtime":"33837"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610033.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610033.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"96.6304348","right":"129.7282609","top":"126.0812903","bottom":"131.8296774"},{"color":null,"transparency":null,"left":"22.8260870","right":"38.4239130","top":"135.2787097","bottom":"140.6438710"}],"starttime":"33848","endtime":"36034"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610033.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610033.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"40.3260870","right":"130.1086957","top":"134.8954839","bottom":"141.4103226"}],"starttime":"36053","endtime":"39548"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610033.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610033.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"23.2065217","right":"89.7826087","top":"154.0567742","bottom":"164.4038710"}],"starttime":"39568","endtime":"42259"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610033.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610033.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"23.2065217","right":"116.7934783","top":"165.9367742","bottom":"172.0683871"}],"starttime":"42270","endtime":"45941"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610033.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610033.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"22.8260870","right":"125.1630435","top":"172.8348387","bottom":"180.1161290"}],"starttime":"45958","endtime":"50019"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610033.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610033.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"22.8260870","right":"103.8586957","top":"195.8283871","bottom":"203.4929032"}],"starttime":"50031","endtime":"53280"}],"pageNum":"7"},{"src":null,"imageUrl":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/oebps/chap0004/images/orig/img2.jpg","hotPoints":[{"type":"Normal","content":null,"parameters":null,"description":"9ESh","left":"123.2608696","right":"135.0543478","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/flash/2012021313291142610034.swf","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/OrdiFlash.png","actiontype":"webview/swf","reading":null,"actionname":null,"dcfSrc":"multimedia/flash/2012021313291142610034.swf.dcf","menulist":null,"pen":null,"dictionary":null,"top":"124.1651613","bottom":"136.0451613","zoneList":[{"color":null,"transparency":null,"left":"122.8804348","right":"135.4347826","top":"123.0154839","bottom":"136.4283871"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Unit 9 Festivals Part E","left":"108.0434783","right":"119.8369565","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HideAudio.png","actiontype":"audio/mpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":"123.3987097","bottom":"135.2787097","zoneList":[{"color":null,"transparency":null,"left":"107.6630435","right":"120.2173913","top":"123.0154839","bottom":"135.6619355"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Australia","left":"57.0652174","right":"68.8586957","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169620024.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169620024.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"147.1587097","bottom":"159.0387097","zoneList":[{"color":null,"transparency":null,"left":"49.0760870","right":"76.8478261","top":"141.4103226","bottom":"164.7870968"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"autumn(2)","left":"96.2500000","right":"108.0434783","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169630025.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169630025.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"148.3083871","bottom":"160.1883871","zoneList":[{"color":null,"transparency":null,"left":"89.0217391","right":"114.5108696","top":"142.5600000","bottom":"165.1703226"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"August","left":"133.5326087","right":"145.3260870","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169630026.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169630026.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"148.3083871","bottom":"160.1883871","zoneList":[{"color":null,"transparency":null,"left":"128.2065217","right":"149.5108696","top":"142.9432258","bottom":"164.7870968"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"saucepan","left":"171.5760870","right":"183.3695652","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169630027.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169630027.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"148.3083871","bottom":"160.1883871","zoneList":[{"color":null,"transparency":null,"left":"165.1086957","right":"189.8369565","top":"142.9432258","bottom":"165.1703226"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"picnic(3)","left":"127.0652174","right":"138.8586957","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169630028.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169630028.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"212.3070968","bottom":"224.1870968","zoneList":[{"color":null,"transparency":null,"left":"80.2717391","right":"184.8913043","top":"178.9664516","bottom":"256.7612903"}],"starttime":null,"endtime":null},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"24.7282609","right":"105.7608696","top":"127.9974194","bottom":"134.8954839"}],"starttime":"1511","endtime":"5015"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"17.8804348","right":"25.1086957","top":"157.8890323","bottom":"163.6374194"}],"starttime":"6958","endtime":"8850"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"50.5978261","right":"73.0434783","top":"165.9367742","bottom":"172.8348387"}],"starttime":"8868","endtime":"10924"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"90.9239130","right":"112.6086957","top":"166.7032258","bottom":"174.3677419"}],"starttime":"10940","endtime":"12966"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"130.1086957","right":"147.6086957","top":"165.9367742","bottom":"172.8348387"}],"starttime":"12982","endtime":"15287"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"167.0108696","right":"190.9782609","top":"166.7032258","bottom":"172.8348387"}],"starttime":"15299","endtime":"17323"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"9.8913043","right":"46.0326087","top":"178.2000000","bottom":"185.8645161"}],"starttime":"43515","endtime":"46211"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"9.5108696","right":"55.5434783","top":"201.1935484","bottom":"207.7083871"}],"starttime":"46230","endtime":"48880"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"11.0326087","right":"62.3913043","top":"208.8580645","bottom":"213.8400000"}],"starttime":"48891","endtime":"51251"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"11.0326087","right":"52.5000000","top":"217.2890323","bottom":"221.5045161"}],"starttime":"51268","endtime":"52546"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"11.4130435","right":"49.0760870","top":"223.8038710","bottom":"229.1690323"}],"starttime":"52306","endtime":"53858"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"11.4130435","right":"57.8260870","top":"231.4683871","bottom":"236.0670968"}],"starttime":"53878","endtime":"55564"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"11.4130435","right":"55.1630435","top":"237.6000000","bottom":"244.1148387"}],"starttime":"55584","endtime":"57676"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"9.5108696","right":"146.8478261","top":"262.8929032","bottom":"271.3238710"}],"starttime":"57687","endtime":"64108"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"22.8260870","right":"39.9456522","top":"273.6232258","bottom":"281.2877419"}],"starttime":"65862","endtime":"67660"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"77.6086957","right":"87.8804348","top":"274.0064516","bottom":"280.5212903"}],"starttime":"70187","endtime":"71579"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"129.3478261","right":"149.5108696","top":"273.2400000","bottom":"281.2877419"}],"starttime":"73953","endtime":"75513"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142610035.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142610035.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"179.5652174","right":"192.8804348","top":"273.2400000","bottom":"282.4374194"}],"starttime":"78016","endtime":"79479"}],"pageNum":"8"},{"src":null,"imageUrl":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/oebps/chap0005/images/orig/img1.jpg","hotPoints":[{"type":"Hide","content":null,"parameters":null,"description":"boat races(2)","left":"103.0978261","right":"114.8913043","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169630029.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169630029.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"147.5419355","bottom":"159.4219355","zoneList":[{"color":null,"transparency":null,"left":"86.7391304","right":"130.4891304","top":"129.5303226","bottom":"177.4335484"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Chinese New Year(5)","left":"51.7391304","right":"63.5326087","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169630030.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169630030.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"154.8232258","bottom":"166.7032258","zoneList":[{"color":null,"transparency":null,"left":"34.2391304","right":"81.0326087","top":"134.5122581","bottom":"187.3974194"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Christmas day(1)","left":"156.3586957","right":"168.1521739","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169630031.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169630031.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"153.6735484","bottom":"165.5535484","zoneList":[{"color":null,"transparency":null,"left":"138.0978261","right":"186.4130435","top":"134.8954839","bottom":"183.9483871"}],"starttime":null,"endtime":null}],"pageNum":"9"},{"src":null,"imageUrl":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/oebps/chap0005/images/orig/img2.jpg","hotPoints":null,"pageNum":"10"},{"src":null,"imageUrl":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/oebps/chap0006/images/orig/img1.jpg","hotPoints":[{"type":"Normal","content":null,"parameters":null,"description":"Unit 9 G","left":"118.3152174","right":"128.5869565","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/flash/2012021313291142610036.swf","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/OrdiFlash.png","actiontype":"webview/swf","reading":null,"actionname":null,"dcfSrc":"multimedia/flash/2012021313291142610036.swf.dcf","menulist":null,"pen":null,"dictionary":null,"top":"12.2632258","bottom":"22.6103226","zoneList":[{"color":null,"transparency":null,"left":"117.5543478","right":"128.9673913","top":"11.8800000","bottom":"22.9935484"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Unit 9 Festivals Part G","left":"101.9565217","right":"112.2282609","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HideAudio.png","actiontype":"audio/mpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":"11.4967742","bottom":"21.8438710","zoneList":[{"color":null,"transparency":null,"left":"101.5760870","right":"112.6086957","top":"11.1135484","bottom":"22.2270968"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Chinese New Year(1)","left":"27.7717391","right":"39.1847826","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169630032.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169630032.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"119.9496774","bottom":"131.4464516","zoneList":[{"color":null,"transparency":null,"left":"17.1195652","right":"49.8369565","top":"107.3032258","bottom":"144.4761290"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"chocolate eggs(3)","left":"75.7065217","right":"87.1195652","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169630033.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169630033.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"121.4825806","bottom":"132.9793548","zoneList":[{"color":null,"transparency":null,"left":"65.8152174","right":"97.0108696","top":"107.3032258","bottom":"147.5419355"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Halloween(4)","left":"126.3043478","right":"137.7173913","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169630034.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169630034.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"121.8658065","bottom":"133.3625806","zoneList":[{"color":null,"transparency":null,"left":"114.5108696","right":"149.5108696","top":"105.3870968","bottom":"149.8412903"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Christmas day(2)","left":"172.3369565","right":"183.7500000","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169630035.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169630035.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"122.2490323","bottom":"133.7458065","zoneList":[{"color":null,"transparency":null,"left":"160.9239130","right":"195.1630435","top":"106.1535484","bottom":"149.8412903"}],"starttime":null,"endtime":null},{"type":"Hide","content":null,"parameters":null,"description":"Santa(1)","left":"66.1956522","right":"77.6086957","title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/image/2012031513318169630036.jpg","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/icon/HidePicture.png","actiontype":"image/jpeg","reading":null,"actionname":null,"dcfSrc":"multimedia/image/2012031513318169630036.jpg.dcf","menulist":null,"pen":null,"dictionary":null,"top":"223.4206452","bottom":"234.9174194","zoneList":[{"color":null,"transparency":null,"left":"29.6739130","right":"114.5108696","top":"177.8167742","bottom":"280.5212903"}],"starttime":null,"endtime":null},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"27.3913043","right":"98.9130435","top":"14.1793548","bottom":"22.2270968"}],"starttime":"1220","endtime":"4585"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"27.3913043","right":"64.6739130","top":"28.7419355","bottom":"34.4903226"}],"starttime":"8566","endtime":"11747"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"127.8260870","right":"165.4891304","top":"28.7419355","bottom":"34.1070968"}],"starttime":"23460","endtime":"25273"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"28.9130435","right":"54.7826087","top":"35.6400000","bottom":"41.0051613"}],"starttime":"11763","endtime":"13724"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"127.8260870","right":"164.3478261","top":"36.0232258","bottom":"41.0051613"}],"starttime":"25602","endtime":"27691"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"27.7717391","right":"91.3043478","top":"42.9212903","bottom":"48.6696774"}],"starttime":"13744","endtime":"16188"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"127.8260870","right":"175.7608696","top":"43.3045161","bottom":"48.6696774"}],"starttime":"27489","endtime":"29840"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"27.3913043","right":"97.7717391","top":"50.5858065","bottom":"56.7174194"}],"starttime":"16203","endtime":"19183"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"127.8260870","right":"189.8369565","top":"50.5858065","bottom":"57.1006452"}],"starttime":"29856","endtime":"32902"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"27.3913043","right":"64.6739130","top":"64.7651613","bottom":"70.5135484"}],"starttime":"35989","endtime":"38956"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"127.8260870","right":"169.6739130","top":"64.3819355","bottom":"70.5135484"}],"starttime":"49466","endtime":"52579"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"27.7717391","right":"101.9565217","top":"72.0464516","bottom":"77.7948387"}],"starttime":"38968","endtime":"41108"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"127.8260870","right":"180.7065217","top":"71.6632258","bottom":"77.7948387"}],"starttime":"52591","endtime":"54640"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"27.3913043","right":"75.7065217","top":"79.3277419","bottom":"84.6929032"}],"starttime":"41122","endtime":"43352"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"127.8260870","right":"204.2934783","top":"79.3277419","bottom":"84.6929032"}],"starttime":"54882","endtime":"57978"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"27.7717391","right":"89.0217391","top":"87.3754839","bottom":"92.7406452"}],"starttime":"43367","endtime":"46111"},{"type":"BkHightLight","content":null,"parameters":null,"description":"背景朗读","left":null,"right":null,"title":null,"src":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/multimedia/audio/2012021313291142620037.MP3","iconSrc":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/null","actiontype":"audio/highlight","reading":null,"actionname":null,"dcfSrc":"multimedia/audio/2012021313291142620037.MP3.dcf","menulist":null,"pen":null,"dictionary":null,"top":null,"bottom":null,"zoneList":[{"color":null,"transparency":null,"left":"127.8260870","right":"182.6086957","top":"87.3754839","bottom":"94.2735484"}],"starttime":"57828","endtime":"61156"}],"pageNum":"11"},{"src":null,"imageUrl":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/oebps/chap0006/images/orig/img2.jpg","hotPoints":null,"pageNum":"12"},{"src":null,"imageUrl":"http://192.168.102.241:8008/dls/FileStorage/downloadEncryptAPI?contentKey=CNBJTW2600000000300&filePath=ebook/CNBJTW200005109600000000300/oebps/chap0007/images/orig/img1.jpg","hotPoints":null,"pageNum":"13"}],"bookName":"未命名","pageCountNum":13,"teachingFlag":true} \ No newline at end of file diff --git a/src/test/resources/external/Demo.clazz b/src/test/resources/external/Demo.clazz new file mode 100755 index 0000000000..4cb98d3885 Binary files /dev/null and b/src/test/resources/external/Demo.clazz differ diff --git a/src/test/resources/external/EsbHashMapBean.clazz b/src/test/resources/external/EsbHashMapBean.clazz new file mode 100755 index 0000000000..c9cefa0ba5 Binary files /dev/null and b/src/test/resources/external/EsbHashMapBean.clazz differ diff --git a/src/test/resources/external/EsbListBean.clazz b/src/test/resources/external/EsbListBean.clazz new file mode 100755 index 0000000000..8752230ea6 Binary files /dev/null and b/src/test/resources/external/EsbListBean.clazz differ diff --git a/src/test/resources/external/EsbResultModel.clazz b/src/test/resources/external/EsbResultModel.clazz new file mode 100755 index 0000000000..6730de8034 Binary files /dev/null and b/src/test/resources/external/EsbResultModel.clazz differ diff --git a/src/test/resources/external/MockDemoService.clazz b/src/test/resources/external/MockDemoService.clazz new file mode 100755 index 0000000000..7359611c1f Binary files /dev/null and b/src/test/resources/external/MockDemoService.clazz differ diff --git a/src/test/resources/external/MyEsbResultModel2.clazz b/src/test/resources/external/MyEsbResultModel2.clazz new file mode 100755 index 0000000000..bfbe92a70b Binary files /dev/null and b/src/test/resources/external/MyEsbResultModel2.clazz differ diff --git a/src/test/resources/external/VO.clazz b/src/test/resources/external/VO.clazz new file mode 100755 index 0000000000..4a0bb18c9d Binary files /dev/null and b/src/test/resources/external/VO.clazz differ diff --git a/src/test/resources/external/VO2.clazz b/src/test/resources/external/VO2.clazz new file mode 100755 index 0000000000..12b04ce096 Binary files /dev/null and b/src/test/resources/external/VO2.clazz differ diff --git a/src/test/resources/hashcollide.txt b/src/test/resources/hashcollide.txt new file mode 100755 index 0000000000..bab2ade650 --- /dev/null +++ b/src/test/resources/hashcollide.txt @@ -0,0 +1 @@ +QL8kHVYUYnsma=&SVGuEjUWnrkep=&7q9r64Y_rs_dW=&v6Cq7VXfoqd_r=&nVCS4SXqrqfdg=&FPFfCZYYgqUrb=&H6nztRVaqf_cV=&cb8m7kXqnehoY=&pxYRPkZcjVmsq=&_cyom6YrsmaXg=&9ArUASZWdrbee=&Cxjm3uUjbqdaU=&zPnR75ZmWmqkU=&QycGswWeeoboo=&hm8Bd3Wddh_Xb=&mh4uemWjXccVo=&cre2cKYiWsqib=&CHaeTYXadqocr=&eXeQTEWUp_bsh=&wNgj2jWrZsqUd=&_mF2CQYisUhiU=&MD_qjkUnsdlce=&XaAtXIYZWWb_e=&tKtpeVXmjorlr=&llhh3zVUdlhrr=&IIlLBBVbqqcjm=&xKjhHtZcgbmVd=&NthfTvVhpgfdg=&9LVxELZcdVejV=&VDUfeGWqkhlsY=&E559MeUoVjVig=&cbLuZSYqVm_jU=&uGrslvVYZdgqn=&p4aZstYildVkU=&vGc36lWWlfYse=&B8QjgbYnYrcsb=&GGbGRhUggnrhd=&EvchGkXZdochf=&myZoZYUlVfcZX=&6NNcR_Veimemo=&EAecfzXrdj_mV=&3kbThGYbroVqd=&7hCVKwXdcn_np=&RLOJMEYpkXfmr=&4RP2QSUdhndVc=&Ak9jimXeeUbUi=&zZds2uZemskm_=&lisectVqrrpns=&lLkS9XXnYkmYU=&QtRjoDZjYaXeo=&pW35ImUisnYZW=&IlNA9oZemoecq=&OLGOFwWZsnkbe=&dm55SVZUfjdlm=&kwmM6vWjUYYbf=&Jifp2jWmmZUjs=&BFslYEXjqmohj=&5mkJMMWcViohi=&ykLb4wXlfgYgh=&YcAeM7YYgXmXn=&RgnFL_UW_kmkf=&w4UJpwZogspdh=&EIZGa5WoXsZph=&ulBrcOUYneUqd=&kcgwQEXqkbdkm=&KGLCxbWXaomkd=&B6zXpYXsheXVk=&PRqFf5XhcaYod=&CyRApkXnVoVUh=&jJw7vqYkedekl=&gXhGcsYoUghmg=&RTBo4zYnil_hp=&tAn4AHVlWpfnk=&CNkFPRWYo_mkr=&dd_O7nWiX_dUk=&9LOx5_XijqifU=&8RTAnUZcdkbXn=&tjANrVWWfilrj=&O5Lon3UhUjjkq=&aOAxMEZlsmfsp=&FX9FgqWfgrr_j=&AUMuewWeZaleV=&BmecJkWoqaesZ=&NS9CJIZahWZqU=&ruWapgVbfgfin=&yQmh6_ZqUrngc=&vGnvk6Ve_jWWX=&93sy7HXnlWsUn=&qTEDT9VZnUpjf=&hD73EpYWpjeXh=&e2USPmZVhedkb=&yRbQgqYXnimWp=&sv6dI3VkXbgfs=&mo9PUGWW_sihX=&WBx_cFXUWor_q=&_n4_iyZqkccYi=&uL9HZHVkrqnbV=&L35QvmXrjlnfh=&6lRn8VVcdqpXl=&OB5jdsXare_We=&OirRIwYjn_dUU=&PIm2jUZcdkihr=&JGylFuVereq_i=&6YxDtLUlofWia=&x6eXPTVaaVegq=&8yI42gZoVgeVr=&Y5g6cUZZqjk_d=&HrCyL7WmaliVs=&o6xsTJWqV_sXZ=&ugJT7HW_Xqeil=&KjTpN7WkgUdYU=&3a2pPUXWjnj_c=&XMxawRYnfleaj=&5rPS89Xhesfqd=&HMd6ijYemjmcq=&qYsNiiUlleVsj=&X56jlMYbdUhom=&owTupRVVUYYXh=&Kq8qCPYahfnig=&gpOYStWbeopqd=&ljaW76YWU_Yjf=&uy6wiGXUYZbrk=&TgOrAcYfdlXds=&7IerFrUaol_hW=&doKZqPYeXXrbo=&NjX_dhUZqniga=&oJj_LQYqrdYmm=&DVxoRRWWeYsae=&iRARhTUpsdsWp=&8tOkGpWlankeW=&tzF6Y9Uqeeqsn=&OALPHoUValsaq=&y2rnOkUnbjsqj=&ISnpt2UWehiss=&DAmROhYfaWYqp=&ZphzV3VWcr_aq=&6KXOBBXbihpon=&bOqXYfWgoofgl=&gN6c9uZjaoqXo=&4QjBi7ZnrbYYa=&pl2TLuWelnm_c=&vioXdHUbbpggU=&w24qgoXbWknmW=&26ANIiWeXekWr=&7oTBhAXssXklZ=&ariAWlXgchhos=&PSUQBnZr_emdZ=&AagnJ5Zdgkcsj=&zXjNeuW_mUZdf=&OOUlXeWVrjsac=&BMdFsMZseXVof=&ciMHmEYVqbpgX=&puG8_TZeqoar_=&pbV7XqZsWahij=&lvLa6UZfhkrpe=&nacKOeWkcjlic=&JtHnCgYkcZWgg=&OzfpP8VfcYagc=&ZcqmdcZmoUYdb=&yiDrjhZUWZngm=&BMukdcXpaUamr=&WHQizKVXhsY_g=&OrzefrUkhlsd_=&QeS98IXVUoXqV=&oQ5I66VfpjUej=&D9kPY7ViqknXi=&miaZdgUhcdekl=&QtTQSmWZUprqq=&l84LpiVcjk_ag=&t9sZs5UpboZsi=&TOSDQzXWWaeZm=&Yq5SfNXmUbajc=&mOBolmYVXoblh=&fnLUH5YmoZfhY=&FFLE8vZiXfkor=&nEpLiLYk_ebio=&Or8mU2XcqWnse=&IYTsCDUniiYkU=&GcYUVYYdZVXmq=&4ujNg9YrUnZV_=&ilKJHLYoajjqf=&eUS9Z7UaqmVdc=&v5S3fzXohiYlX=&GvfRh9ZplgYig=&sMUebiZohZdXf=&mvxkplUmXqYcm=&5dBQGkVZnsa_c=&ueQes8YmcpYWb=&4CywUQVlXrXrm=&AuQjqWXjjcip_=&tpPsQYZaXpoWh=&qJEcehZWVXUki=&KsFH7kXsqnrge=&QDXrmMYnqnmam=&e_vzHYYsmUmsq=&VL3YkGU_apWqe=&UQnbjlWcq_VhX=&JrqsB8ZZcrpmf=&4hvmIXXXokaXg=&l7UquaZkkhcnf=&nbByPSWjaZsXY=&yUbXgFWfhYibd=&yPH7IgV_hZask=&qhZ9PuY_fafbr=&UWzHCwVaXfgqa=&l7xozsWgecedb=&9mKX5mYgYkccs=&iJ4DPhZcmqfgq=&JaWFqNWa_n_Zq=&SO5aHnWVafhim=&c_NXyuYZbrbep=&Lu9mW9YWgVVeU=&_4PsmvWaljWco=&6WdscAVdjpgsh=&fahGlLV_Xgomj=&c2UHYHUsndenh=&T9nDaIVUZjWbW=&pm2iTRYrkogdf=&iJ7zCzUabihXX=&NG7g_4XYWgqme=&i2WUjRUjdYmlr=&PErLrUY_lidfq=>2wRpWqYXiga=&Td_skVXdeXmrm=&IVS77wVjrVsaq=&ZmAuO2ZrYkYmb=&6hbc6KVYc_bkj=&Wgq5ANUdfVin_=&fuJT_vUsagrfb=&uv3l64ZnUgoXa=&qsLnrvZUcrmrq=&HodawfVqnqhps=&BDbp84YaYccYn=&5yVhPoUrnimUo=&fjSntHYmlqjkg=&3BQlf3Vsjsnjs=&dDKkULYWgihYb=&fAH2RbYqjnlfe=&tkRAWmVWaocpr=&EEcnmIUqmfb_s=&EfguSNVWeZllZ=&CbY9yGWXcgcoX=&zTVr7RXe_fXel=&cfXmDbUsbsWrZ=&j7YLy4YjnrdsY=&YJhuIaYdlWfnn=&WtfCWRVosYYbW=&dJv9TlYiXgmXe=&Ruwq4rWdkZggq=&D6ePcvWleimbX=&hdzS9bYpimqoq=&qevp3VWpVUlne=&w5KEmAWUhjpqg=&iQppK6ZqbUdXk=&K82j46YsjYWcV=&bpOJ2PUrcVfbm=&bCVd8sYmdYYZn=&DRU3wGZmafUqj=&QwPS_WXhmUXlg=&RdUuzSYriZacq=&xJxngAUYr_Woe=&oNzmZdWUaUfpr=&tIbNLFXedYhfU=&qkWBY3Wfommf_=&JFrZ5OYZcYnrs=&zPX3ZyXbVolYZ=&REE99kWVfjVss=&fmkYiQXaXsplW=&feGQFXYfgWZme=&NjEH4gVZfhdbp=&4zCm5BV_hoXiX=&L7fdUJVobXsnb=&DbKMeiVjabibl=&UfWIJWZicbgeV=&x9_wjJUdsajek=&H5rPPWY_aaWhc=&KXmBgSWsnXb_k=&6QG4_yU__lsmm=&JYFHV5Waffoaf=&nPTPHeUaZfbcn=&6MHbHIWcggZsq=&38M3mrXqndqhp=&YNO2BfVdkZjqZ=&cFhKk9Vjpncfc=&rnIpOTUlnakef=&9xwEDRWVlqoYc=&BJQoWIUbsjWZY=&VhBQfyXgjcWkj=&wk33VIUUicmkY=&QLQylcXpabVkb=&foAJPZZob_bag=&MMhmNuXXhdkkb=&Cy77YPVddcZpj=&CHwpuMUnZkibs=&VTFlIgVkZaqls=&o6tkeXZUXUimg=&yXvfclVipdeeY=&JvOeiYUdnmUsX=&3q6pklYZVVqkn=&RdcItNVmod_jc=&nDMUXbX_pmUn_=&lqaDZGWoinhei=&m_9VsXYaiqYbg=&XMcCAbXUYnsWf=&D7paEJUkbfanj=&dKX4IkYdVijdW=&GqBIpvWc_pX_U=&n34w3vWrsfVjg=&IVVjNCXdZmjlq=&kQ2icUWssk_ig=&o_RVFrUWr_fdg=&9vC3IyZkipbjW=&4iyd5eXkXVobn=&q3dCzTUredeam=&c68ERCY_jkkip=&JITLP4Y_pdaWe=&KF3TnjVgcdeed=&UseHKiXbXgZWo=&RmfGfRXhh_ago=&YMzdJIXiXfXrp=&3SxhtVXdfsjsn=&s8n2K8UnnU_dU=&ECxUJbYrXpgne=&uEbrIaVjVhbrh=&sPhvQ9UnhnblV=&pHGUkgZhocUlU=&VVHk6QYqebW_U=&KqB_ZMUnXobpn=&5ehZtuVrnqmfU=&ktm_bWWkbYmoW=&nEx5UCWbo_moY=&Bo2n4vYkcmYoW=&_f9pJaYsZrig_=&slxIwjU_r_mYZ=&cfb5QQZmWZsZm=&ZLPYnzZVf_aZo=&9Ur2HKUZqlgUg=&hD4melVhXrpfX=&IDgRhlWnZsfsa=&u4QXv2WkkdZkZ=&5A9IHAXVbkbdX=&Vpj2ySVYcrb_e=&DfIzWHYgfknil=&q6DNUlYao_rms=&tiwei5Xb_kUgq=&dEEpnrXWUqmia=&3ADTK2YgZWejo=&irZP5TUhgYac_=&CMQdI2UVakoYU=&yUrsUKYYcmWWW=&E2tkuCWgr_dhm=&cIdk_EUiVoWhk=&sl9a67UlVY_ri=&KvnwmaVrirmga=&8tf8P3VqnfWip=&9bjCbzYgbmqso=&kolA9LUhki_jb=&wwSHaxWifmjsh=&hna7zNWXqUYWm=&JVsyOkXomsbWZ=&mrNyqFUqdUfhn=&kKJpYZYcjegba=&Qd3NArVnsdZbj=&LUhrIaWm_lipo=&eygjqdUYrVqlg=&QZspEQUbUanri=&EZvQnSWhrcX_X=&BGePUvUYiXpZh=&MIVpLgVUdZosd=&DgS6J6Xsqnhok=&Ns52u7Udg_ikg=&IYbc79XbeUqZp=&NbYuHeUioeiai=&tukWmWWmWlkiZ=&2Nw6ETUhneWja=&gIZL4xYqYomWj=&ZMktMLVffhqbX=&K7HcvoWohZnsi=&TLE26YZZkUUqh=&SYlsudYgniioe=&lAWD77Wrsolfm=&pOTU5YVjejfVg=&keOevbX_brjVY=&jOjJE7Zik_hs_=&aOnESsWhqlraZ=&837345YZjsYor=&feAGnwVXdcgoq=&mM8mlvYjVYWrh=&CoIu2vUjqmemo=&FMzetdVWXXce_=&zR88MIWaXWWcc=&rKkDK5VelqqWp=&rTBG9GZfpdjqV=&u5D9CuYsZcnUk=&f8YvvjWUaZihs=&cDS4f_ZWgbgfl=&utDSjrYhVsbe_=&qS8OHvWggYnbW=&Y3GZy_WoniqfU=&89wVrZUjUXfma=&PmhOiKYbsplVp=&YkXEGdYmfiqjf=&qgbPvKVlXlVX_=&FMolcHUjrmidn=&NLgXJ9UYUZjpg=&4zldcXWZglXkh=&aJH2gPWiX_qWU=&qC72Y5Xpacp_l=&vnJD_PUrVeXVg=&6YvAFZUjp_Wbk=&cqsHcaYdYUpXj=&DvblZiUmVfgoU=&xXNTWqXWrsej_=&kXzpMSVsUmdqe=&SEXSRAUrZgU_j=&9GOkABZcind_n=&WeNErkZ_oUlVm=&tbEYcDYVqWZci=&XERmgwUjXbdr_=&OhNtDrWVWoerk=&KbLGbvWXWWVVa=&z5yQswUYeVhki=&uabRCKWYebcqk=&UpoqdLUjobedf=&OjzecAUVnUaZ_=&rsZ5mjZaqfWia=&UpOk7sXdUejnm=&6_CSjzWsckfhi=&6LH9eKZXgpsfa=&7qjSzTWsWWhlW=&7WMGdbXlWZXbs=&YdenmpXWjcngb=&8k7U63Vpfkrpe=&67dd7rUqVijid=&FHjQM4YUUgdma=&V_uGuxWsUclVl=&iXofVdUcrZeml=&bjexeNYhsdoXg=&HocYNpVcaZXX_=&f4Ryz7ZbbfqX_=&dqXcsdWZglVUj=&lhlyZPZsekZWU=&CtpypWUmsqVmh=&NluudRZVsZWWi=&IWIqh7VodjZsW=&mE77x9ZbXgfVZ=&veZSfOUrbcUaU=&PA_RnTZYrag_j=&UZZO4yYomhmro=&duak8qVkiocio=&bSEm75WhoikfW=&ZV8IxnZWYUcYl=&mPjWEyUlqsdsf=&8NKpAVVamikek=&4QGhyXXXgffeU=&EabCxdXWiereq=&59tVdwYrXlm_r=&YhedMJUVsYUbY=&226RzKYqaVcZk=&2Nwe32WbhghpU=&Ns4QiiXjlhqle=&XEwYleUfXeehc=&tj8rMaV_ioihl=&NgCw4dYZlerml=&xCPAiAVagkYcg=&dDYXZMWffaXnl=&vaBWtuYdesdWg=&Mijw2dVUmbUZn=&lL4MYMWWnYpqs=&xNI95yZXmdrjq=&aItZJuWpmilrn=&g4xPMNYfeliXc=&aAuRFsYqrjcpa=&UrSblWWoY_qmk=&Zj5b9qWqnYZWq=&MIROaYWhknZZ_=&VWLbaTUhUkjnq=&iC3o9eWWbgnre=&wGnja7VWXiqXU=&vnD4YPWVraoYq=&F889sAUUsldfV=&zMytFJZrrnimd=&iaQTUGXpXsaZs=&eDvhvEWaUgWdc=&5BrHrLWrroilr=&Id7jBpYrWbriq=&lEwso9XnUqVUj=&gXnZrOVcUrmdU=&c7fy8gYfdWgen=&FFSjmHXinmsV_=&Bqs4AFVrpZUnn=&tA_yfEUYdYi_o=&fwQs63WVbbkmk=&8YxiDPUmnsZql=&pR3wtXYdWgdUp=&nMgBrdWkXsnX_=&HYZfmOZrca_gW=&sfjJ2tVisgjUa=&8WDVXXXkhYnkl=&JVQWvbUa_fmca=&Rffnv6YWXelWl=&AChlSKZqqohkp=&6z_vSHXeijXmm=&f9gssmXUqrn_b=&MPpgeDUq_Wlsn=&kyM3vYWsaodUl=&hhZQDrWiYkffc=&DWW234YddmW_e=&lJfCSWVmijpde=&EYkCohZrsXbhb=&7WsQndWfUYmbV=&8EsMDLUWdlhgr=&DYx6T9XckdghW=&yWZFlHWopipij=&ATDA74Zs_kpVr=&yfe6RAYahfZsf=&iWGKnxUjdVVcj=&PWIHKrYWWnesj=&wDpw6JYefcqsm=&9BIrCEXc_lsgZ=&CSdg8jUZjYsYY=&FfRTmUUcekqbi=&P2LLQFXkdoXsj=&USATIxVXZqUrp=&PTfVD8VbW__lc=&yrTgBSXX_fUjs=&YD2sTZY_gXqhZ=&g9MRDJXecrlbi=&mNDZ9OWZiilki=&w_M9WDYjXjrgs=&2aDCS8ZZmZfXl=&ldZW8hVWeXWpl=&wyvbRUVUsjYem=&LlEpd5Vlqablf=&IW8xelXs_qina=&KckZ7WXdsZZpj=&cGF_4uWeUhUfj=&OnXCqpYdjVbUm=&ycQd6eVismdgV=&MqoVptZfprnmV=&c4eTFnYjsmbcn=&cR_MAgYkglcVg=&VchLqOZsdjhkk=&g7xFaAUbYUfUp=&iYgzonZ_XXhVo=&3ixDkuZW_bori=&h3eMPJYWYfr__=&NTLAwtWXWqYWk=&iXw2H3ZXpYZok=&rROpw6Wdgcabd=&moMxVlZUXUVba=&mEodQaYiocaWq=&BoCQ3EVWikUqf=&7sFKL9XdenYjn=&nFbEjGVVh_dlq=&XQk_RrXnglbXX=&9bAxKuWlgWfeh=&2yWWD4WennXdk=&DzYkaGYjjjieU=&t9XpmxZkZVfV_=&hSmEgRVaroaZi=&IMaVAvWcsnjdi=&KpoZFcWZogrrb=&VVqEfcVgZUilZ=&B3POixVrmobXm=&A9NBsJWppoorX=&FqiHz2Wcsmopc=&8deQ4wZr_pish=&VzYb2GUVddk_q=&7sAXuMVlkodUp=&ekgpGjWsnUkim=&i9_LmmUoZsYgX=&TrHE4bWkU_X_h=&7Zk_YYVkarock=&sPx4p2Xekqfln=&RZ9fhVUhjnioZ=&wsUr9eVcofhlg=&TmXbmdYaWgpgc=&cz_2dzWjodUYf=&TsWrXrWe_WrVX=&vRpVYMWZceqqU=&f3RW6TZosenlo=&cnYk5aVoarrsn=&5WhtOXZorYbal=&HNF8dqWbfsgcs=&9lQiY9Wdbhbi_=&984xJWUjrbihn=&hK2MWdZjhqfia=&IbLN8IZnajcXX=&TcYpVAXncrcmZ=&rNrgyTWgh_mss=&Lar23GXjaVYsd=&eQiGccYlkVcji=&TyvE2XXqkorVU=&Kv3hjJZ_gfjUi=&RCBfkYXVsojUb=&teHpVoUigabsk=&_jhYLlY_hhsnW=&7Oy25LWrfdedZ=&It5rC7Wsosbpd=&kYqLd5Xrdjrhj=&NMUQylVXc_ZWc=&mPdn2YX_haqnk=&dIElFdZjjrqjU=&UIfKT6YpYgX_a=&VYTZj4XsV_XUn=&jryJGPUbodp_m=&JnrRZlUcjUrkb=&CeNKz5VapWqpe=&xj_RUJZ_esiXV=&YNQCJcWcdjsrk=&J99xiCWfhnabX=&5B2Bz3ZZrqfpY=&ej5efzXlqjnhj=&fOUEm4YeWggVe=&lS5IN6ZhYcYZV=&FAxfxzWhs_Xdn=&7B7JmwWqfjqgV=&UgF4FPZqeXkcf=&d2D5rnVprnnro=&BTqLpzZpglsqj=&t5_VTcZVYdsqf=&9oEcyDUiWigog=&9xp2_LWVhiVUg=&8cyvwOXgsVlss=&sWdKs8ZUVmUjq=&LqRHBVZbosYc_=&5dVpShVbo_Ymh=&FwlYqdVaarmXr=&J8jM4oYebWggg=&tuVZ9hUjeijif=&xQDguuWghVrnp=&3KC_fHZiXgXXn=&tWXbYBZdYniag=&vkMIjmXVabaYe=&ZWaKrmZeejkhi=&5Swj4sYUqloas=&zO5IKaWesUfrU=&8OWk2DZVn_UjY=&KcsWOCUkljYch=&oC84tlVWVrkfZ=&lhWlq4Y_ejVmp=&kqQyjbYshqgkg=&XLHiCNZWghZUs=&rRXgW7Ynmparr=&xunzHmZnpgiWa=&sdvrILUnZW_bc=&s8LNotUYirsXX=&fvPdSoZno_oXg=&3gQCjCWsYhoYn=&YDRlJ6VllXXaV=&sE35k6WcnWWh_=&mHt6ZXVc_UmYd=&hwu6JlUfhagXg=&gaUlPhYfYjs_m=&_MOkLFWiporeb=&M3fnp5Yaqaerr=&GeBvb_VmcsXog=&xWraoWYkdshmV=&ErlG6yUrhVpWW=&AayHNRYWmicim=&ilX7yJYojlUfV=&9CKp_TZcXmeja=&e_SsTqVnpbdh_=&hrwsHNZrXhelU=&q3SOlbZYYbrei=&MnNx_ZVpZ_oZj=&RtJm2oYbUqiXp=&2QWrQZUWYUgUi=&Mw5d6lUpioYiZ=&Ev9qvSUWXZgfc=&9tRXcfYZjirco=&ydluEaVfrhjio=&7kQPCnWbZkfdr=&IOG5pEXeYXreb=&3BCvPKUWZbamm=&DN9OahVYUdojn=&G5D_pNVpUiWZr=&wp_yZhWleWcXW=&Oysx6iVhUUjcg=&7r75UOVgklrhU=&UFw4LEXajeoka=&HIDVOhYojfpdl=&WijsTiYmkbZ_Z=&UYOoetWiUgnrU=&6MLxMzVslgXbl=&Cuy7K6Xa_ohsY=&ESwzYvUVjZema=&UI54grZ_dsmfe=&bk_v93XkXneph=&zcgZw9Vme_XgX=&9YDvclXidefUV=&4MApFHXYdjVj_=&MnzZ6zUplkc_U=&FldfUrVrenXkW=&GiAHLeZUVmhio=&u9mHJmYersfrU=&dYVgf6XcUWbfa=&yol8ZOVirUjb_=&6KDuSTYdnicqU=&4FZo5FYdllYnr=&hJkGgBVdhZeVd=&KaiJq3VYWnfbi=&p3_dFBYjXlgso=&m_p3CsUmkpfVl=&Da_QSgUnUYpoY=&fqNzIfYjapngg=&Ch2XiJVsUqqWe=&2X3MOIZ_oojZi=&V5ObCJYVeXqoa=&o3onSEVchk_cc=&w5vsg9VYXbUrq=&HiykPDZoVsVYV=&eljMqCXgajfZb=&x5RnYrYmhWkae=&TPcZXnZasVgci=&ItI43XUXplaob=&t9PSuNYbchoUo=&7dUENDWjVqjVg=&X3IhERVprs_pm=&TVzGVXXlllfXq=&hvAFH4Yoofnjb=&EAaOakZoghiXs=&ATCiGVWnhZlnm=&8gb_GTXd_conb=&5k4z33VlXkdkf=&RDDCnfXspprfr=&XJAgxHYUaUjmU=&gm_ADCXjWqerZ=&RIotVBWUbreXc=&_2mDpPZqeYlcf=&kPk8QHYhbbdsa=&LD2KvCXsUkWfX=&TWXpmmWjejXcX=&FwcVjWXcapWYg=&sSvZsVZmioaWp=&Gp8ehgVkcVjfs=&h9fWbCYgmoomk=&uc_qf_ZhVXaXZ=&hZhNg7VkmhZia=&Ld2jRMU__mjeX=&vUPcjhXjhhodq=&t8gwEnUYksYoY=&DsAozMVsbZUeo=&jRSJ4fZrpsoVm=&E6wphpUnokslZ=&kHM5zjYinVs_s=&4U5SZsYsehrXU=&98szUKUcZqYmo=&7nn2HGZ_ZoV_W=&AACGfEWhe_gVW=&bRiZaNVbmrWpr=&bpc9XDXYWgfqf=&kFdIqsUgfo_bZ=&t42rtaXpbflpg=&4X5orJYhkZVYq=&afDaSSWi_UpYm=&4jOhXpWsVZVhs=&CLi4luWVrlZi_=&O2uXRqVneanns=&VDd_6iYlkh_oV=&smLKzJYjriZZk=&3UwQaVZmgcdqg=&cUzUqZYrjjXn_=&goXwwZVmmebar=&_vZpi_VUiXmYW=&swrk3VVaUnkYl=&sJ5P7SXmciZcl=&S7bEfQUaahY_e=&s398e_Wgmmggc=&U7usfYUYWWrdc=&hn8IzrWbZUZWl=&zOYES5XUrZfqm=&kTAmAgVnbgpjl=&kyDciSUVgblbc=&6PJu7tWegaddd=&WsqlLCVjnsacc=&L56sT_Z_jgs_Y=&C2rWnpWYmaXsa=&tRCfy6UWgjlar=&tL9yC4YjdcVli=&HzZkRiWjWnriU=&chf2_mZmrrjfh=&Q8odquXoZpZ_l=&SDYfBaXoXmajl=&duT3aFZXpdiog=&kyzTdSXqrnrZn=&M8AycRWiVqsci=&w4xiLtVhsjeaU=&2gfxSMYrVYVgh=&JJelMZXjfamsa=&OixZhfXnopYXj=&xWZAQjZdddnj_=&J76ukOUnhff_Z=&O2IbkBYqjdVlU=&Ri3QWgZgflsYX=&Glq3CpXrXjbWo=&7AOUmxXkpnnqi=&wTIh5hYYmjssf=&OjumzCZgWcVXq=&AynyJhUksYlal=&QZWAg_YX_gool=&nca3IqZjWkmYY=&hytG_rXrrhXir=&6bGSDxYqsiVjh=&kXaO4aVY_enkh=&hDLgZ5XncZYff=&KlqVNcWorfknd=&TbgS3yY_ibsag=&DWKvvjVchfbqf=&bZ5LzKVqrssil=&cQ8L7yUhnhlih=&BxUkF9Wgrgdga=&Gw_QiGYhWWYfV=&NIASgSXXdhhYh=&wRPMR8VbUpaca=&3zfzPJWkfkpbZ=&S4aJNNUdXWrpp=&TIawKfWp_lfYY=&XkTgIUXepdkjl=&6eaEutVshsWif=&96YpKhYWddpoh=&zUos2NXddVWea=&wd45WhWkroZXh=&jgwCGIUdrhrnf=&_Qax2WXcl_jfb=&vMRXq3XnellkU=&qhBsT6XifWUgX=&uz3bcyWkYVbre=&NY7IA8W_nncqd=&FnShZCWaks_Yl=&q9rnyhVclYkok=&pHwWBQUVpjmds=&rbLBzzViqVWkl=&pbl8IAXY_jWkp=&GsNdMZVhhqfXV=&PiVNL2Vrfn_Vl=&fh_FsjYrlaqof=&vwTiYpVadfinY=&g8qfYFUrgoidm=&6FBeARXheanqm=&rpto9jYYkdblg=&QW6SZVUifclrp=&Fx4LU8VcqZ_ig=&kzjQ7QXsoogdb=&hwC2XEXeoadVV=&mmgvwdUWXgqdZ=&eTBv4PXZnWaeh=&jQBFkXXoVmoar=&vzDfwiYVWelfW=&wgc9cmViifj_o=&GZIwlsXkYnqVo=&bFQ5NdYo_qkdY=&57a_iHXcpUago=&MKFAHfUYYdgVo=&vPZn3sYmojndm=&92kjVkXVlfcfb=&UQuXF7ViVaaZa=&lJjtslZrmgeck=&DSQeBRUVofsrd=&UeDUA9Upmmmbc=&R3pl4bYVdohkp=&E7cwqbWkdkjac=&q6uhTDVsrsgkd=&tFftiaW_Vahmj=&SSaYRdWrkhqYd=&vGblBFUbhibhm=&hipug8XWVXeiV=&aWQU8jZmYggss=&YxOZSEWVhdgfp=&QPxwaKUWhWgnZ=&FWUD4CVpYYU_m=&yWSenJUeoaWWh=&eFMqIiUjpYkgY=&dafvvvWseUcZj=&IOEFz7Wjimqjn=&h2L7avXajbbcf=&UljQnOXaYXZgn=&RFlc3aZhmshgf=&zAucIyVgrp_Ve=&_FFHqcZmqYpnn=&G5u5MgUbohjfd=&Vxlza_ZgjoYhi=&Eoug8XXhbrqch=&kObPVRVlmYWUh=&z2b8v8UpUpfsm=&wkE26IUXbrpVg=&2GvaYiXnVZlVn=&94o6olYlYesZ_=&opFAiVWsknkkb=&7xjB8jYceqUqW=&ldStzdYqrhWeY=&qKqznaUdpjogq=&eNv3nHZkgmpde=&tGi8vXUabdjUW=&atfTNCZfUbadl=&cCRCjkZhaWjgm=&Ofu_jVUqemfhm=&BQUSQoVggopWe=&TLXDEaYafnhkm=&LfiRwzZrqbpkd=&V6M5MlVfanhbX=&W3t2gRUkqlVUo=&8zi5oYYiaWnoY=&g9795TYpjiqYk=&uGY9GCVZlsVqn=&Ay3OAVZYdp_ap=&3KilNEXlkm_ad=&toAFMtZieXkph=&jLMplFZlqjYVa=&pdwyqlWiciehf=&XNCApzUkkWjjZ=&_TgqNCXcfahiU=&mN6q5jYpUcsda=&byivPBZbcYjUY=&Dx4WTNVfkWica=&uB5P37YVnWeel=&XXxaQqUc_rk_X=&aKalAEZ_bVVlb=&zrERZhZWpdoWf=&GyW95sXbhpagd=&oEELQSUeqhmsf=&vc2OubYfXVcmf=&GWun2GVcZWYXa=&kQbSQZUbmadsj=&ldANDKZic_biX=&xsd3OvUhWodZl=&EjIkZZUng_inW=&Fi_BwTVYbnkrs=&lkhYCyX_rYdmW=&oDlPZ9YlXjbrg=&n7ZRVEVdiXVsd=&XjdzTXXfjaaeo=&FAZ4vOVeXboWi=&uCJoKJVrcreWi=&ttF_V4UVqnVUn=&_ocd9xVbUc_sX=&GMeR_QWbpkiie=&EI5mwJWnbZbnd=&VtYP9IWbYslg_=&djynPJXno_oag=&FNQv_HVhoeho_=&OSCAn8VfqfoVr=&YGoIulYmenjmY=&Rm53D_Xhk_rVV=&wX9TxTWYVksrh=&FvcQm5WmcXWnb=&t4KsFCZbeaWeq=&iSOSY6YcXZrrq=&VVt9DpWZflana=&5d8TUfUfqkZgn=&96p7y5YajUknp=&HQ43vyYlaqljf=&CG6FqIUXYhpZb=&hGkQwpYcprfnl=&7W9bGbWXgelfW=&3JIae4WaXUbpm=&zLy7qdYqhfkpX=&FEHKJjVZa_osb=&hK3snzUasXYgh=&PnZndDUqWWkjg=&33_PRjXagknhj=&DZGperYZocjrc=&XwYxVdXUonpVh=&qQRaQVU_jfjYc=&bS4PhEVYZaspk=&ZzdrFXUiaYVcs=&aYtu6pYinbafV=&GmMYMxWVbafXg=&JivYDvYcpogbr=&uNnrqdXbrpean=&kcwnmmXXpecid=&eoZwpHWWerfXX=&URlZ3nVfaZedh=&UvfiNaZXYhpsa=&pAEP5GWlfsVk_=&WM8qYWZrfhcpn=&UNmVtAVaoXspZ=&t2s49aVpnpXbg=&mQFbxVVY_fiUn=&AxUwMdWdibVYs=&U9L_gOVneXagj=&jVDeOlYnrsVUY=&LfFEo_Wnfjeha=&ouxADuVYg_cpb=&RZTNZcUmbcmXi=&mjuojNUciemgY=&ZAQpR8YWdUeo_=&tqRmZAUnol_o_=&BqADDYXkjpdsi=&HPKmwNZgnfcgd=&xrCzKgYoabWsZ=&j9AXJWWXmZlWf=&Qnb_HeXg_hUma=&7OPjLSYYhi_qf=&oSsTtvYUgn_rW=&RxcwPfYmXgnWV=&6CCSGsWlajjZq=&KmuWVWWdkqWhc=&MM_NB3UqlkZ_Z=&ilzna_ZblXmsi=&PHYJ5QVUaspbb=&CkCc5mYXWYW_c=&T5DhnqXXamoXW=&RLxUuWZmidjUl=&vXNIpRUcrjnsd=&dsa9DTYgZgagr=&2lURhVZnhfmlp=&xKsQtTVilqkjb=&cE77qeXWhZWgq=&ThUHqnZslX_nr=&Y_xHaOVhrYUbd=&7IJvG4WikrZgk=&fkx9TbYoUnmaq=&_a3uFFUnaZpcc=&9AanE4VifikV_=&5CINwkZr_Vsgd=&B3oJqDWsVorjf=&NcNYjmVaYgc_r=&PwIhqAZpiq_Ud=&QZarF6YriZelU=&JLkfTyVcpqfos=&tnX6jKYdmnkfZ=&XwUKjaWfWg_qW=&zAtWliWoWirle=&RXHzZsXdcmYZb=&aavTvSXhppY_k=&rVDr92WUjcpXd=&SdNQUjWrrlqgn=&Rw5SroXmXmd__=&lWaVZeUXaarqg=&zHPZUnXghoYrZ=&F64sI3ZWrqjkp=&GnrWOmUbUcirh=&jMq4NnXUcpg_b=&QgEb9PZhogjkk=&URpszNYogngfj=&dvFHQWWbYkgoY=&HvwkmlYgpVdal=&ofwUfLZceXasc=&_Ya6_6XmrWcZq=&FvjdsKYjoXgjY=&kX46ceWVViZcf=&HPafdAVf_eYef=&AkgwfaZjhjcjh=&leALXzVprj_bU=&nsWQbrYneWoVW=&85VvhLVpeqord=&p8zq_HXoZ_hdZ=&m3_rquXpglmho=&z9JFJlYgnbWdf=&hnGxPwVWeZqqn=&RTG3n7YesbVUk=&oFfYoQYcYYYaX=&rwNELFWWj_mnf=&vGckIGYofYfsg=&xmmHLUZh_jUVm=&eX6LrpXaaopiq=&bd9SiMZcXm_pi=&sZ5Ag3XpXjahj=&CRiGvJXkoXnmV=&BTgEKRVnVWjWW=&rpslrxWr_eUmp=&4NHVxVXcrhUdp=&oVLZKWUXcYjdn=&3O4kY3VmhrVfX=&rdliNwUlq_njs=&6OI9VtWXapnfi=&CkdfN3YXVsgWU=&8Grz7nVgdWfqW=&BZETrxXYWmaol=&lstQYFZYUnlof=&UJ7X2zYpVjccc=&bpEUfwWmVcXYm=&6ikX_jUjdopaV=&EAfvDwUWU_fYX=&GsklfCX_gZm_p=&elKjwLYjppWUd=&zPnCL8ZcYpkhn=&Hg5VBGXhWXaap=&fNdYCKUkUsm_e=&9bgC8UUYspYae=&qBkpxhXlcpfZU=&eQFJAMUcgboUe=&VgLtcnXjYjiqi=&s23zskUdVqYbk=&AP5coXWpXesXk=&_SgWbmYdkWpYi=&PeOQikXqXVipq=&kPp67RYhgZkZq=&fUiPILXfaV_sj=&dF99lWZkXoekU=&w69Da4ZUaliXl=&EflBFEUmchWpf=&neWbPUVpZsZnh=&RJ6_qXUVqVZWe=&qKH9hRWgsdqml=&iwr4yiYV_kfhe=&oDPXVVUpYhdkh=&ZpHMdZYW_bqkf=&bKYzcaVshlbij=&jRpYK4UXUccUW=&Q9tk2JUeqkV_d=&kIRykgZVeUqbX=&9WB67pYanZcka=&AHXo4hXaoUg_s=&kns8QpZifpsgn=&JCHjaSYoscUld=&eOi8gDXUYemkW=&lf9mkLUqXenrV=&dFl9kiXoVWZkp=&vjmLOHYVcao_q=&UcqipqZVdjdhg=&E93kuHUdmbjcV=&KfNE3CYkZr_X_=&rXEq38XkhdhYq=&R8BriwWajZVXZ=&GysuQiUVmgcec=&xhPgJmYqgoXco=&im5j4WVjnWUig=&FLypc_ZogVeeW=&TXBh9jVafhWjU=&gCAG4DWrUfZlj=&YKObiCVUpVkYl=&8DuZf5Zaremcj=&WJUVWLYWV_gdg=&kRhphQVXea_dU=&yyjP6mYlflqVU=&k_S_TBYfokder=&jTgFneUnifUoj=&zY6fH5WkbqYVV=&WzP5KrVfqmWig=&OfAScnUsXWbjs=&2zmHZnXfdomUr=&ezEuwsXcqamfo=&3w3ZJEVkakfkd=&eS7cTOUbbYkW_=&BZ2R8sZrWhVaa=&N2YIHmVf_cWZj=&vgoTg7ZcYdhjV=&wC7myBUddqdol=&BBzqcJZqdgbhX=&3nd5GeZlWddgf=&KjRiJfXYmZoZe=&Goh2SRXrq_Ua_=&vsyABlUUhqqjk=&LUqHLQUoYjjdd=&ZXbJSdUboXppg=&bQUgJ2ZsmsVjV=&VXaOcVZVfclWa=&on6pSDUpVfhkr=&OlAeL3Udoqsee=&JXkrOrVXglUim=&TImznxUomXkee=&hB9zTyXYlqp_o=&XJSGpIZbfVWic=&U4UibrWYesUia=&YGwOkgWWojgiY=&NyA7zEWpbpkhj=&8R9aWCYcacaVi=&ODo3hEXgmhUch=&7r9MviWqeoYX_=&aKIGynVbkXjgm=&v2bXb3YleYcqr=&Ba5AvTZhkfUUl=&dyD7f8Zor_Wji=&nilhpWYleWnZi=&JnwjweVgoshVb=&yRH7FGYeseVnY=&x5t_EgWmcendr=&V8W74PVnokado=&4NKdDgYVXUZrb=&qeSEgeXlpXVUY=&2daTu3ZrcpiWp=&cPkSWMUjYqgal=&wqfvkwVqnqmXY=&werWLmVnW_smh=&VGpAIqVandUZj=&SR3Wa_XXoghoZ=&6GYgwHVVfdnUo=&MyhvtsWgdirsi=&nyew7MVggXX_V=&phd5VxZdg_iUs=&yZTLO5Xkokenq=&RVtZbkViY_cnq=&Nhgyw_Zorbpjm=&UfLvZ_ZaUpqep=&yAFyDGXnneacg=&yzOE4eWjmafmp=&nqjsJXUVnXicY=&ZztA3wYpsplob=&LFdqyNZpenXli=&5eXPwLUksmlpk=&4lTlxvYZViqfq=&Uf2iKTXnlkndV=&ug_w3MUlakksg=&aSZXnzWZbbfYl=&dBe32bWkepVih=&8URZ4AZXYncea=&OzVe8GYeodXVb=&bL_HfDXWVZipU=&ftwtrcVXcmjaY=&LWVCUwYhfYXjh=&4tAtzKVgUaZYZ=&dqqANfYjoqgZU=&4ELBHHZrc_sac=&q2PvCkXcXmdrW=&JGTHzkUhsgXnY=&6Z5rwJV_aXjim=&QleegOVckpZeZ=&kADsShXXqmUXs=&tAeOp7WcZcdqZ=&XosCQiUpqdkfb=&uER5N8WqbqUYd=&wxoJILUaYnkhW=&V9EzluWXbpWgZ=&l52pfjWoirgVU=&_dLPUZZVbZpmY=&KISUsNUirbkbp=&j3hgx9UlWVXUV=&nsJkhTWYodWZf=&5RxcjhZfbYlXo=&7CTbRSZWgpqoY=&QFVVReXdVheVq=&zOG2_rWedncpr=&knC9m5YYjijVf=&QlllcXZpmp_VZ=&yBFh7wUZaZZlU=&j23NCVXoXVjje=&MV3oL4XskceWl=&RJyfpQXmjVleZ=&ZSDZKKZnYrfeU=&SNYWVeWqXe_kU=&NMgBoTWqkbbYa=&mxteB_U_bdhXo=&fiuhJpZYrhjUV=&pGsuMkXsXcnV_=&q5ENarYkalWsq=&HCOAvxXgrWeph=&zAfx8bZmfbcYb=&H9O4tDXbhecqU=&qLnEWLZskflZc=&rqLR5RXsZhcik=&XAAHtUXdbahVd=&oPld6uUZlgomp=&hAXvHDYcmXeb_=&TmHiuFU_siqVj=&BqVaMnUkfZeVp=&YdEtpnWpkghba=&6G74PmZroksY_=&Cp2TRCUjjsdWk=&jqVCcRZcfnmop=&_Nwj9_U_mbgVp=&RelFXPVn_s_Ua=&Pkb49oWVrkeVf=&CIigRBWqcsXZZ=&GrEyHvUcfZfrU=&A9chXeXpoZjqn=&qFELRcZfZkaUX=&Osw4BSZWsVlll=&SVoWLRZYrh_jk=&jKi25mUhbqidY=&3DIJMFVVjcVZb=&4FClRRWbraoYY=&CTWuP2YssUUeW=&HY_t_mY_fqXah=&Bn6yAAZhWfiqn=&kko7mPVdbVrdY=&iVTEceWUlraif=&kvIQKhZqcUlcj=&wGHRqSWp__dZe=&y6aQMmYheaWgb=&KQsRFrWqknidc=&FVDXLbXgYcske=&_StPs3Xfqdhgj=&64J_7jWUdde_X=&d_fVl2WphYlZc=&RLkzVeXdknncV=&GlgiVWVZZgpmp=&XgnXjFUWmWrlU=&elMQQWVUeslYe=&YQBlh9X_YqcYb=&tITyifZXpWdZl=&HI4j8iUjWfrma=&5fqF65Udhlgbm=&3JGRzvUYUkYZs=&VN3JDEXd_dmXf=&JqXboWVWWjgss=&Ml7wn4WckWaZp=&9ao9rBZZi_nUY=&TOStSZXZdecpm=&mkCKtAYlkdcXn=&UiJQihUlXWZjZ=&cXPmaDXZYZUda=&EeJta7VbpZkaf=&ObzxpfWmnhgZd=&Vhw_n2XfdZjYk=&VZ74pUZWprfjc=&QadtzqZ_bZldf=&uJtlKkVYfWZef=&efUuDzXbmZoha=&yQC8lbYhplYgV=&oZhKU2UlUiXYq=&SwwsA7UYbabVg=&3C2cmmVseblYb=&r9bzT3Umfabaj=&x78k5dWYr_qXq=&uIfh8rVpfcmpd=&U_XogmXrXemsn=&UsUPXUYioipgq=&VEUpZvVgkiXpg=&WLwGNaYpeYhaV=&hpG8WBX_WqgVn=&PJdk28ZeemrVX=&v2rcbdVbiUbrq=&zjUROUU_YqYi_=&mXdmrsXnYZfaa=&jN5Fz2ZjfXpf_=&LLfdOGWYgmonW=&tAKHX5UXZXUiV=&ydMbZ6XksVamX=&4aLRU2Wdkapgd=&QS_PXlWblhhXX=&akI8vrXjionZs=&xCIaI_UpqfkWo=&t4SjpZVrXYpbj=&beL7coWYgmWlq=&IOMltiYUblhcU=&XnbZ_9WeliXrg=&ENezATVgW_gYV=&scHm5wYYkrghY=&SSnjxTVdoed_q=&Cvhca8Yqrecjq=&zkNTmVWUrcjZY=&2UzpRnXhjeggZ=&IuLDQMU_lYnmp=&WbTPpIZhhhsZo=&pN_AkSVXVdVkg=&iNG3VQZVZhahW=&Xwd9hCVdikcpf=&SgEZOzZfmWXco=&5nHAkEVaqhsrg=&K6uZlSZldeWer=&kThMjgW_csslV=&ptSle4UapbWUb=&HRaPgaWfsVksg=&uiEnbYXcaV_sb=&P_LR_tYbjapbV=&KyUoNWWbXabro=&XrLdfYWsndVVq=&fFIYQgXUXhXXm=&PKeqHPVfpeohg=&bJBuhvUnnZmgb=&mCIgiEXdqhafr=&TyJsKaVnadkYg=&Pg6A4cWaiZjea=&uuwFQdYUUVkhV=&iSX7glVoiorUj=&rksUhEUqsgehe=&zzgT7VXafVbro=&D2c5sOZjffrnb=&xc8U9RZ_kZgmU=&qRngKgWrXbUrr=&rUqdnrYj_no_d=&VQnDgeXmrrmgX=&UpaSljUe_bena=&b_vi6fUrnk_rg=&76_k6BWlf_VqZ=&rSr36xUshhZVX=&tyY_irXYaqhbY=&od4499WVXsimm=&6k8ObEWreknie=&IZy2NrWrg_mcq=&GiKvMtXZcVpsf=&rJVDQSYbXiaZU=&Kkk3qIXngrake=&DJNxexZnssobd=&Rm49C6XsfcrUh=&ROc3mLYZaid_j=&NqIRbBWgdZlkk=&kHsDhmXijnfYU=&kcIyvXZooleZk=&soZadmVebiZoq=&gMEBMlZVXVaj_=&chC5fQYoZbjjZ=&QCCcCJUcqjZmm=&DHp28_WaaliVi=&hIbIGGUnjqqWh=&6HhiwsUdorVbg=&T6EqtlYneYcek=&C4taVUWg_bZWg=&r8bRibZcbboil=&j9eoivUWpinlY=&yAygVNZVXemcg=&invDPNVVVbkgs=&stsro9Zcsglj_=&oOGSsiVjfhmrW=&biLMbbZkkb_fq=&N7qoc7VWrmqYY=&3dIXHhYnbaUha=&jOqeg6ZWbaXlr=&iQnJRaZejgZWr=&f7BGyFWhdZrfX=&ujOGlnXknrXrZ=&WKU7wtXVWfebW=&HpkjAMUh_efee=&9PVvHuWheoYaa=&L8W5m6Ze_WqZY=&3RtBfqWaXXcsl=&jEN3_4YZfenfg=&9zEcSsXgUnjkb=&ZPQ8AwUelslXp=&UO7vH3Vbj_kqe=&nVuTBVWZodaeq=&DZMM_3XrVoUac=&fAqfKGWkZjkml=&e5NtRuUhfsZWp=&2Zh8meWe_eUbk=&J5MicAWsoqnfU=&6uGIhBZXUXr_c=&WndLGNYslgbfY=&NbMvXmXYjebhn=&ZsT5mtYalrjpo=&apyS3qZe_cYXo=&M3KqO8XY_Xikk=&yhxj53XZaohde=&LWtZcmWceopsn=&__76gSXVq_Vid=&wHi2wbVircWam=&C6kZpUVgjdbeo=&KXuwW8WsVUrYl=&N3coghVaaeaga=&ibA44JWcYnWms=&V_ZswjYXqiqj_=&OXDjKaZ_hlqof=&XIdlvcYeWdUnr=&JJG8ovXlqXWVl=&tJAVfzUdUlWmU=&Sj6FeaV_UgXZZ=&CVLkyWUksrYag=&QCviixUZgmspV=&ZkX6XpXZfqdWa=&A_vlifWhhfoVa=&d7NzooYb_Yene=&N8p_dDUqkpkir=&E6RGqJUXdakkY=&QxFTPpZcUdd_b=&uPXP5dXXbrna_=&zVhQN7VflXjnh=&i5sBlYY_s_spq=&sxGQWEUgkW_aW=&dc2QxDVYlYefU=&V64FyHXjoZqfm=&BybdB6Um_omVX=&rZZDzCYXsqqmn=&gjnefoVXY_Wq_=&DLTZAQYhrhUgo=&IiKtPGVWgfbUm=&ZmYdPWY_jpnqn=&wTjylqYeeceXh=&3vmmkMZhcagko=&FxW9TuYaVXebV=&TdiMHuYZVsfYl=&idg3oNWbribbb=&tXmsHvWUUhcll=&SgTieLZUjspge=&MKGo6CUokVgmX=&VPWfTjXdj_okV=&ObFNabZomZpqY=&kIE4MpZifi_da=&y3B8PJVqj_WZW=&fXuq_oVXnk_ld=&8FhnPsZaoef_g=&ZeTeXsUcfXWic=&nm6b2wYbqadml=&AisQjiYhdgron=&FbVd9OZjYqWXc=&75xrAdVUrZfka=&hjSS8VYi_kYfc=&GoQHQtWklUqW_=&7kJhD3Ysp_W_l=&U7PR88U_bXWho=&exwe55VjecVof=&W8CauNUnVWlll=&TdJnzrXZpaame=&IpzgaUWjbZngf=&JNiChrZYkmbij=&blIllTUkVagdm=&BqO6U5Xhf_cnd=&C6kDxyUadVmog=&EwuxKCXphhpiX=&sXaKZyYXmrchq=&5TU6CkXifmdWm=&8ZJj_pVdrlUXX=&brclDRXsc_amd=&_tlKb5ZnqnUfc=&HTO6ETXcqYfXa=&IDpsJIWXXWYhf=&UFHihvVlniWVj=&WjIJqEUbh_bhl=&HVogN_WsUgWYa=&kIeboaZXlibpp=&NvfYOiYqmlejk=&5THNkMWVbYnfo=&uI7M2tZgZc_if=&Btj9WmZomhi_W=&rSeHeqVinqiri=&nxbPewXWcrlY_=&9jzdAyWWkkYqe=&2mxIzLUZllapl=&rSz6VjYVbXaYV=&BbfL_7VXXYsrZ=&MmLqRtVYrkpcp=&pKGhxEVUmrnWp=&jrX7cIZVUmcog=&VNgGsrYZUW_rg=&Msdu6QXaaneda=&EwWCdcVleUZjm=&lTSF4FUeiVpZn=&fqieKaZj_dcpY=&Q3Uq_fZjUenqb=&dslqklXmpsjpm=&T5aoNcVdfmcrb=&rP8_SzWXWXmgb=&SUffeyXbpeaXf=&yGeD9BWjcnfoW=&6zakezVjfoaib=&qeHEosYZaaXsk=&gFqp2mYncgnhf=&__7LNHWn_UbYm=&ta5lfSZqWVkqg=&KoNzNSYnoiVpX=&46ZyDPZbkjbYe=&CznY7uWejqgqY=&VK4fZYXZZqald=&5SkzttZZldpds=&xLoC5SY_ZbpXV=&Ef4nAFZseqaig=&ZECO4rZm_ioYV=&uWg_BaUaaqfqZ=&wUfbSTWWYmkom=&H3jBcOZofrjXX=&YaHYg7Zsmign_=&NME_DNZVoX_UX=&_bGS_OXsUhc_c=&gWcXXNUdXWpbU=&GhtKpCW_laVUa=&xst7CMWokgZqm=&5tW8bTUd_iekk=&ZQGTqpVVqZZjV=&BmhlwcWYdbqlp=&bWGjiyWmVUdob=&emCd9lVZihpoX=&wvbibwZlrWjnp=&qZCP35WcrnXmo=&x4OPd3WnrUcVs=&4ncnaMUgmhbcY=&lwjn4HXaWrjkb=&DXb3JgWfoYcUg=&mY8ILPYanbXnm=&2B_GfyZ_c_rqe=&22zWusVkqe_lk=&hZforFWmYYdid=&F4W5moXdcUUiZ=&i265agWkemgli=&ru4gMBVUrVknk=&wSNE4LVfUjjaa=&R4RcfgYYa_VcY=&695vnqYVjcVrs=&eJPMTTXmhh_eW=&qPr2hOYYnqqdV=&ItTAo_XVpWY_m=&ebJauZYcWW_rp=&XaukUFZgrVrfo=&48_kPwXgXUZad=&eMSSviYpgdaks=&Jy74DmZVpkrrf=&4PpWxbWljrXVb=&Ni3FnvYjraono=&pIezUkWamflbW=&VW5kypXZWm_XY=&AA3_NgZWidkbn=&Mc88NvZZcfgpd=&A8shYQZYr_jjj=&xqSLUKZlobrnc=&QHPdEtVXrXgj_=&wgSelZUmX_YWg=&sygjwuWsaqjVY=&CGl7IcWhgpafb=&pkNS3NWf_ZUfp=&JVKrQ6Ubhiksh=&Rl2ucXWWo_Wdi=&SrQ6dWVYYfsbp=&PyCb9rYccdZeq=&XngnY2YXYbVce=&kjaPHyWUlXi_Y=&OxwDHbU_rnobc=&4leYf7Ubplbca=&64Hg_BYpfdgjr=&S6RjhOXjkcYXe=&cVNHaNUhUfXgg=&wV5StrYcjXkjl=&y6wX5wVffhloo=&5UdmmDUWrU_hh=&EIDL_uXpV_Znq=&viiCJYXlnYdpa=&cPO6pMXUVVqh_=&oMVduBZcjlsoZ=&9NfJScVViqben=&3dD4ZjYrWbqom=&E7c4t4WVqkfgW=&mSIhAwZi__Wer=&Mk4HtkVibieia=&Uzi6uWVfpafir=&JcvtoYZnleVoa=&jPkNNlUXflZeU=&aTShzpVggabgh=&NS6O8ZYekYmsZ=&mwcZApZhkeXqk=&NOTAdSVfrUmgd=&Xu3FZiUlWedoi=&KL4jLTZmUhUis=&BOAEnMVoclalW=&OuGcJ4YpUfk_b=&PNSawPXhmYhfY=&2KXVJxVUphikX=&quICCbUbekc_f=&VlIXOsXV_dsUh=&T_AYdyYliqbjU=&q9xozuYpUmjha=&NF3zuEVXrhjri=&_cCCxfWloWXdU=&Swj5hYVmcYagm=&lKK6d2WsjV_pk=&qn_ssQXoqrlla=&6FRMqeYVbrcmp=&Wx_9jyZWfmbci=&B3JmVOYa_brkk=&PERrO4YafaeYk=&XooapzYsqjf_Y=&PEqbdAXbgYcWm=&GWWVJ9WWoZhoj=&CvNfZ8VgreeXZ=&sJLfqbXfXegfV=&nCtWG9WsXaYeU=&LiRw2BY_oZWqW=&o3BzonUnnpXVn=&4qr6x6XjXjngV=&vYcMXyUfUca_e=&VRQip2XolaeZq=&OrPOZEXm_pcYc=&XQH6FrVWZlYls=&QTxW7TZ_raZYl=&fzaEpoYlfWrrU=&CTgEiiXfWknUr=&rKmU3CUknk_ed=&9LrDBQUoWnoWg=&E4xjR_Yqchckm=&cIjTvrUVglWZo=&xivIvoZplacon=&MfncO2WjVdnhf=&PFfWfkVnWaUsf=&f63VhJUssenar=&DatSglWWnVnqf=&2I9SmhVpVrarm=&_sUJjFZUaaeaV=&5vlAmLZa_cXjl=&pe9M3XWohWnXY=&WJCtPkUlegk_f=&mdnCsOXcjferV=&kn_uboUlVZlsb=&QJSQQ8Yh_VVYa=&Vjq4Q_XfZkZos=&HMoMmqWXaeoja=&Luz_bTZZkaaap=&VT6XtdZXlgZjs=&9bnyLeVkejoeW=&hwVzKfZaZbo_g=&Fu8niPVcdaprr=&CHnT85ZlbXXdV=&SvMLxBVomUcqU=&PMjhoKVpWlbki=&Avy4bqZddUYgb=&NYP5pgXfhfVUl=&jZ4N3ZXZWUkkk=&2bOsZ2ZqXghfj=&NefKpaYrabirj=&yH2ya5Xd_ZXXk=&3RI8TiXcfsoci=&zqbJ5eWabmjYm=&2vyN7xVlmXlcl=&XZ7LXcWbsYWYo=&hSTQhHYZZhgYc=&5oKCWaYUicYYl=&gmCP9mZYVbqWr=&WAigfwUgUjXXZ=&bGhjIWUqiZqlW=&4DW5gsYZieron=&TBER5CVi_jqWg=&5tHnLyYrmbWcf=&Pg9ELmYkjrnWa=&CTXdD2XUeshks=&UpPYTFXlooajm=&xtgfzMWUmasah=&R82UF6ZbeajVc=&822AuEVckhVah=&NEfFwLVWaibYf=&JXeOqbYbsWVUo=&LcuYYeWkUsVda=&3NI7_GVVgZlYk=&QiHE6mUUepVlg=&MUUH3QUVVpoZY=&R4yCYLZmXpeed=&RXqiCzWmqsiUs=&PdAXSGXYdiXip=&daq9fcVripaki=&RcWcIoUakoiqU=&JwqqtIYjjpmfl=&twBliBUlnimrW=&WakxDJXdkpbY_=&3MxryMUfiphVh=&DizOQdWcVUeWd=&qvos72WnaUanV=&VyX7NmYqjkmrY=&WZ2w4AYiVgVsm=&5pFf3UYsd_XXl=&mU882nZdqsopk=&73UF6AZlbpqef=&mLTzbOYceshrn=&OMOKWuWircegW=&wGSJVEZfesmli=&dXZcvwWokgggl=&4DiXE9Zqffrse=&dWXJxMWempWsa=&XSS_FxZnkXYoj=&2MK9sAYhmlsmY=&DTylNnXdrXdWb=&WAaenbWlbnVcj=&dDUvICUhrsbpW=&K63S4AYnWVbqU=&e5yIziYYcVW_d=&8pMTYHWrUUYkU=&m2QVBOVhanYlc=&dxe7F3WrmjUiY=&Jw4eJeYZgsUlW=&YIQq4WVnalhmU=&u3gW4RYnWghmp=&fNUpeNYqZ_Vr_=&kYsYz6Z_XoVeU=&fvABuRWZdcWWj=&smRU_tWg_nheh=&49jKX7Uplsenj=&phaKw8XgpmjYX=&_f4LuvYZcoYes=&akyDcKVWnrl_o=&V6emT2VsWrUmp=&gA2zueX_Zggrk=&V2hmSUZgragpb=&6gbVwDYZqpZdV=&PUO3XYZYnhYhl=&JfUKR2ZXUsVfX=&tU9HAcWhhaash=&EjK9gCWeeUhVU=&6BYqkmXjZcYdf=&4F7bVpWgkYeYc=&BaSxXDUdVaimh=&WbRvggZ_maWWb=&EI_MfYWZdjd_c=&JoVrObVZpXbYq=&BcJoutWobsdlp=&oCr8Q6YXqsdmc=&HFKpCZYWgmVgi=&9GPnU8ZhZh_gm=&_ykK2bZjhjrbf=&YPNKnvUUXqUke=&tzFBqjYharglZ=&KURAL5UoiUYaj=&Jj65ItVpZWVns=&kRB2CpVikkccq=&jGe4MwXbdnbbd=&hFPOLcXhYVpoZ=&UdGZGmUgfbeep=&CVDF_MVXb_Ymp=&_8dPmvZeja_Yd=&JhE8MdUZdcY_l=&Ni7J9AYsmXWhf=&QOYUf5WislWUl=&SkDulCVmfjjVa=&5qGZs2YojnpdV=&MkavdZWXsmank=&QTI8_GZcnjqck=&nZMHRsUVsohqh=&BcHdD6XnWlpqU=&ikVMpAU__jbYp=&9UisIbVhadoed=&SQ2RdnZnipiYm=&L73LskUpZkmcX=&3SFXnMUrqhkUi=&kZARZ9ZfWsZgn=&llgJfaUXp_VWk=&q3TNd8Uebbaf_=&N8bQGbVebZmfn=&tx5fa6YbkWUsW=&8sXe43YXWhnps=&JUpNxyZjqVhar=&c7Yi8aVUU_hoW=&OeBXLXUgpcgUe=&xJroGcVcmqhkY=&tYLjWpYan_jfk=&jQvYiMZVYnrrY=&WL3AO7Xh_hZ_c=&_lZjksYicnVim=&pHrCMDYadelVm=&akgzNLYc_ck_W=&pmeNXdWbroYXs=&UaVfgzVXeclli=&XRijw9UhWlgaY=&viHqbYUodXYnp=&ZqxCkTXriUYm_=&LomRJjZlhmV_b=&HmLndAYsgpWZd=&SjfBoHWeooUlk=&NUXVU2YYmindn=&45LaZCXeqdYWW=&IdmtGOWkodbhs=&bEjAaIYmrXVff=&_VJG44XhWeWbW=&hz8x2kYUkmYhr=&HVOxQZVbYdXf_=&QYkvW7Ziblrrf=&G6p2LTZb_gVZg=&YXFDMvZnoqpms=&WovVlLVmoegqi=&hmSHUcVbi_hnj=&BnLad8XYZrnjd=&wasl5kYopWaap=&aVPNe6WeedWsg=&vmMFtZVjdknnk=&PJhW_zZXjhbph=&Uz2vQnXjUqjmq=&IRczjOYcsXnjj=&EifuKqZeqdVfa=&SEAxmRXe_W_Xf=&oMidnTYUhXqfZ=&CMtLOhZiZarle=&NJCTt9WdeeYdd=&lmWjdQWUdcrdj=&su9DgRZqYkkqa=&CVO_3RWWecYde=&NRHBwaWmaqlfb=&Y_7yGaUjXrqlf=&dieiOXZbhflY_=&taQzqwWpeUdgb=&RISPLIUUnpZWj=&IzijyJYWgXXYm=&EgBONfZcljiXW=&yWi9tMWrjkrgr=&N6Cae8Xpqerer=&a9zdq6Yrg___r=&GXFC8gZjr_klU=&kXZK6rU_Wmroq=&uErtIAUfhpZlo=&R3GzwqWWolVbq=&_rWpSKYeUhpmZ=&ecfpw2VlhoZrr=&6jBXw7XiYjlrl=&SRWldwZloYldU=&PIwuDdVcYrjer=&f86Ez2YehiUnY=&YabwTKVnikcdi=&3JRfFOW_rnmfk=&pvAYeYWrlhUgU=&lWG7laYcilcrf=&ypszKNVkjienX=&YmHiysYVkdmeW=&SHbzTPYUYmkiq=&UTkDvQXpYVVs_=&tXWprwViXonVn=&LdYTvJXhUbkcV=&HAL4U9XVrocUl=&T8ecsvUsohpbh=&o7Af38VoXnkcs=&rsnmpxXVhoZbo=&SXM5efXVgbVep=&oeUBaaWYUggZd=&XESLouVXXhgeV=&VSvh_YZqdfWjo=&uXEgpvYsgbipa=&y4xF4kWWWjmmm=&BNcqpvYYbkY_i=&khB8jhWseerVk=&shtLC9XZfVgck=&Ib6EyBXmYUaWr=&4t2XC4Yhfokqo=&vhFlLuWeYmqbn=&Fs5xLiZpgjgrk=&hFLlXkUsjW_aX=&NYiNmKWYVeYVV=&DDARd6Wlcnfqh=&HZU2_bUhV_sUj=&aLjD7HWn_mpch=&GOqIKAZcgcUee=&EjJC2nXqdprjq=&JAq5_HWUgdUUY=&b73932Ypirsno=&VCV4ciZcXoVVk=&Ako4SVYdUqggs=&pF3jVCWobVgsl=&gAGajsUWsmqeg=&QrInFkWlogXqk=&LY_bZqWsqpmWf=&aYcWQnXZYZsZm=&RSZOnzUVrdZaV=&YlUgyQYpoUdYi=&pe9_2sZUheXqg=&MtgXOWX_Vpcme=&trcdGGVsqV_so=&TyeTMMVUjbXXe=&ZhFcPKYcaWdfb=&Zrk9qpZXYXXim=&B_68TEUVcllW_=&SheDhFUgjnamn=&j_xA4vWUjVhie=&O9HTbvYZWkbja=&9qOwd_VnpheUU=&yFan6eVmdWmnn=&GEUk46ZXcjoek=&lLicsKVlrVcjm=&lwvmzXXXZcoXl=&cBPicHVjhkeZc=&hIrGXjXdpjVWi=&fHqhjAYcbZoZW=&rspmUSUfogVlU=&LE8x7GVWflZVf=&k7dXS7YlbjdZo=&TzcnGtUpfVhWr=&brjgCkYhi_Zpj=&_Bdf5SW_raqkn=&eZwRNfUXUXinm=&7iPusUZkVefXe=&n777pIXhgiWZq=&c9G6F8Xqhjjkm=&sYbVQoUWWcgmf=&npBxeQXflpdco=&wiYvq6Z_ZWlqU=&TLHnxNVdeVgoU=&frDBInYgVlqlh=&LWCmFiVbidcka=&I57vkpVYanbVn=&GsWuczUlYWlmq=&lMEh94WWZdXnY=&dPq42bZoaagZa=&LqFGxCWaXYghW=&F_xEmBZrbjehX=&L5nJLVYferggc=&Zby536XYsUVjX=&DyuiFxVnoXrae=&bPVv4bXWiZmaZ=&wnhaXMVsmhgWg=&oKOQPlXlsdnVa=&fqrbO6Ye_g_rc=&7TfLrMYinXWfa=&y2P5f3XfqVUps=&dBaYmCZUfWYng=&QHAGeuX_impik=&eF6BvWWsXXoUj=&6aZHcHYqpZkds=&fkBuzSZrhnapX=&GZuLLDXrYbkma=&ZpknyqWbUbkqi=&riz3_xZehsald=&89WqkwV_Vd_ib=&MhQrQjUmjfbkl=&MReTrHWbkjhkq=&aTF7_iUhYffmo=&BVUrp2Vqfmfgp=&C5AZGAXYgqbrZ=&vXIqkJYlUnYmc=&6Kj8VOVgijnga=&_sNEDYZjfnlgm=&hVjspVZpenrim=&dtOivAVhYlchY=&w64RzrYgWYseq=&QzTDGgZXcnafa=&MsaSffWlfeqmb=&OqAr6eYocoVmU=&eSpJSuYgsimUp=&Hne5CxXYV_ipV=&Xa4SJPUoqUnjb=&wc5FkMUmmgrng=&HKMcKxUh__Xid=&6KJGzsUnhmcZZ=&JvE2y7Ufjmdhi=&uSiLLpVanYmqY=&NpzAMmUUfVapb=&HnzD3AXagamWe=&8GasubYYjmXYl=&vDw43cVfkhbpp=&95Agi3WiklVgj=&JMKLrmZlojgon=&pHRiR4YYepbrf=&_jRLevWkZgUqm=&LDgE2tZqVpsZj=&25eGqhWfkXZYq=&dozuiGZanmjga=&HtfbFcXeZbl_g=&6ePPKMYgoZgqn=&63wDEbUocohXW=&zFQ89pU_nkcbj=&8hTQnPZrckajr=&OL2dmeViilkVb=&I8ucAwXaZfoeX=&VMzaWBXdchmip=&NJhMTqW_sl_Uo=&sKtxa9UmsnYfn=&IjBdZeXejrgWm=&OCaa_IWrmsdcX=&R6a2k2WYUdjpm=&Z529zoZrqleYX=&Q7yxUuUjVXepa=&fHXD2bYYn_kjh=&EEqJf9Yg_hZbe=&guwwJDZfkZd_X=&g6k3Y3Zbesord=&oOh5XWXdqnjkp=&sgLekYYffmUbV=&WaCZVkXpZZbci=&IIgeOuUhXosZo=&9GbRliVUUgjc_=&tIht25Ye_cebk=&ufgUrAVkpimXa=&HSIKtJUZdlXZl=&gKUfuqVZr_eaX=&jShjARZUpbYhr=&S5paSmYcfohUg=&t4gwQlUWUWeei=&W4K3qsYUoljWg=&7gpveZXiWmnlj=&vIdrujYnclsmh=&s5smhkWkcWbXW=&BFwOqQVidkjag=&_BrXCQVrrcm_p=&cqVNFTUisYlWs=&8i3F7pXiohVgr=&jRswqJXboifVs=&QfcUSzZWjokkj=&3qJEQgVjYqcgY=&7YeX9TUfjVreZ=&WG4DxwXfodkeV=&2QzlwXUpr_mZa=&bCG7FlVpWcnqZ=&M7QalfYWlndis=&OxLi8zVceVhZr=&IQVo4cZjWZnkZ=&HzuQGqXmnWUmh=&iVvhQPZlkejXr=&qzNG2XZanZrkn=&2iL2wsWrb_a_i=&6sgHZoVchi_YU=&3vqn8KZrkqWaU=&ELtSkpUql_Wjg=&RmcgrMZUnUqlq=&dzRFwSYcjjUaV=&PkwylnVYiXibd=&jNGXYXZqipqlg=&fFFfLzUjrkpms=&LdBUfyVljj_ra=&fbpA8OVVajfjk=&KWzxYBWklrZr_=&oKLn2GVZWYpjm=&bVLQQjWglirjq=&HcgWZSZYbpcai=&NE_ovBXqVfYXU=&GBQknHWmfsndb=&7eOUVQYVfVibo=&SFT33_XqYsgVZ=&5wfQP8VVmmUke=&NO5483VXcpoeZ=&PLyaalUbfasrp=&rf2vJwXgjWofr=&qTsagKWccbkhW=&8uRM_EYjfbbkn=&35aYZHZX_qmgl=&QBMMYPUhfbiW_=&Bclaf9XpaqsaY=<PjXNZqXhsrX=&jBGXYVVqdYmnq=&3TpUu_VZqgVYg=&NeCGipZhfXeYp=&JBTWIiUmXZqYW=&_ox_CZVXooesX=&uPvwiRUmqglhi=&7cKDmeYpaZXsb=&TeedrKYdUlbcf=&VzmeNyUVaUdas=&ZWNxn3UdlX_ln=&Cio_LkXUfjqZY=&da4BxtYjkkadU=&Sntqo5Ugcjmcg=&AxCRM5Vlnfmaj=&f4MrcUYYkeakc=&pgp44fZdjiZaW=&by4_odZenifbs=&YIOb_JZqgcVhm=&APVRVIZl_nksa=&Cu5MmAZ_eVqsp=&xZqvZ4XoWeq_n=&6Z8NoMVbsmkr_=&Z3AoG3Ycfoopa=&oPnqgmVheqrWg=&dvTJ2_Zgjmfng=&rWFS8XYipblbd=&RYqJxLZ_ZWqgf=&UoxezTVrhiqrY=&hbIJh3YpaXXXn=&ruoWEfZliYsWl=&gfRkk_WbhhUWs=&iphszHWjbaZm_=&yPNi3pUmmW_nZ=&9MX44BXe_fkef=&2Mhj8AWbjrdVe=&Lq6C6cYYfdefX=&FvhE9EXgejZYf=&Qk9rMzUhghsd_=&MB9KahYrpqs_n=&mrTCqDZVZ_laW=&6K5zrtYfpnh_X=&hqZywqYk_bciW=&fXxmOvXegesff=&qh4TxzZUkapqe=&jLCHrEUeanVd_=&tPbZcWYXbUhXd=&ShSpjtXmbZrpa=&3_PxqQUgqnVoV=&WCtUgpZ_UffWW=&6hk3bIUiWVhag=&Z5rsDAWqhbjXU=&fFL5PnYjYV_fV=&yvwihWXUnfZqd=&zNL3mzVhcl_a_=&LxNrgTWhopYcs=&luTAyEXhmleqW=&l57AQdUhchaaX=&l2GqJyXXdVVnc=&q6G8hmXhhfqfX=&akvOGhYcbkYld=&dS3LpkXceYsV_=&UIge8dZhsbmnV=&ENAGpdZpmXnhX=&9JUewOXdrrVpY=&NZLGZwUeUWXZr=&edsbrWUWZr_hp=&f3XEvyXrpcVUc=&6wnZ97Xkpfeir=&rI_zo6Wlqnajn=&zjWl9wZUqcdek=&eTlh89WqsjUqs=&7lpK9_Ubgijj_=&DXRNFjUnqbZWU=&KMtumKYlapqnZ=&JWRqIDY_brkjV=&hIMUdnVdrjWkg=&gbzapFUkhjdag=&LN_ZooZrsaVkr=&rZNam5Vmbkhnc=&obWmHdWpc_Ukj=&A46mCKU_dlkl_=&ZZJLopYncfpgl=&FOXBO9Zomjmmi=&7e7AA3VVcnjmr=&YYbEEaUbhceYU=&Sz4n3_WjahnVi=&vLXasxWnmcsrj=&AJ_ESZVnoqoql=&neIKi_YfZoVYn=&3Gdcl6UdrXbYc=&NYqcBpXWmslXV=&GnmG7fYodphko=&Z3YSVLYXmcefY=&yZKLOCVfpld_W=&IYcyLfXboqmYr=&Q_U4k2ZogWiis=&VC2gySWnijWZq=&yPK4ahUbbWscs=&H64DubW_hWoUb=&aJwsqXZfYkr_q=&R6KhLIVgYhrag=&ZiRMvBWidsplm=&86hNcaWX_VeiX=&o6l5yiXfZ_shb=&LmDKptXbgfUXr=&2k5nNvZnW_ode=&cmGi4TXXkVYVn=&ldm7_HUdpmhjs=&RBZ4ziZseogVe=&dhSxFEZrmlrel=&YMUyK4ZjemaVh=&hHnVZfVYUlUWj=&L9ObftXcrqdgU=&ykAlnJVcWprcj=&tUzbP_YZikfgV=&2sJhiDZbcYXVp=&GobJWJVhdjnho=&ZlcWsKZa_flic=&zay7iCVsf_ohh=&ftt974WdjUaab=&Ek82piWolZXgh=&3ZxSG7UrYlfUk=&6F9AQaYlheiYb=&lWbcVZXrbbqcV=&HB5VyXUdsYjWV=&akAEWCZUk_hgb=&7oLrK2WjkdWk_=&bKklsPYdrUorr=&7p93WVZdkonXd=&NgXYcIYqVbila=&6Hg_kSUmkf_jj=&3bWacyXnbpgjp=&Y_zyJdVViqpXi=&umHaAfUcUaXhZ=&gXkazNUiicbpq=&FOLcR_WhgjnWd=&gsfJPKXdisqcm=&rAl_BCXpijnmU=&RWyz2XVneeVgo=&93OuA6ZXoqdZe=&BCZRWKYdhZpYm=&eIacpgUVUbmqi=&VTPJZTYXUZsb_=&KP2xzYUsqqdnl=&it9G8xWbrpsfo=&ixiZVTWli_lh_=&WrUVWYVlbees_=&cULQUDXfrqpqn=&uuxoWdXXpjWef=&q5EFKzUdnYUgZ=&dQFsxtZqmqdoV=&KGVmKWZZZmrWq=&Ovu3gzXsojq_V=&CQP9XpXZhkphf=&kreXNlUWhbYod=&CTYVKjXUephnU=&WKfQoiYrrgqjZ=&jvsyAZYsbnqqk=&YN_gDnYrqaajs=&G8x3EwVdUfbqf=&u79b26XYjomgi=&mffjhfUhriqYg=&e_LkVAVrejaki=&35QCvHZdkgpdZ=&d_8KgSVkUnmpe=&pNBAE_VXqqflY=&dJCg8UV_gqWsp=&Yai8PbVsYohdr=&UkQj_jUjsfeYp=&aOFirlVihYZra=&4yXkttZqohdWU=&xnb2G9XmYmfZo=&4nunZgZhV_ipX=&djIs9hUaprnf_=&izRpE_V_ejrih=&gWNsapWhYdqqZ=&pUOODMYlnUshW=&kZIjdTYWjpmrc=&lUOkmRVVlYbgV=&pGV3rmWWVYWla=&jdnTpbVemUUao=&vkulyqXZ_Wnhr=&mj36oYWdeoX_b=&AOD9AuYXoqjbj=&zKqHjwXsacior=&YJeNxFXVWVpcr=&t_q293XlhUYnV=&ue8o83UqYWnrZ=&HxxjjnZliWmXk=&y2RTDHUmkaige=&7PsjpeVeeWjUk=&tQxuIfVXhfpbc=&iuMiGMZhXlhXZ=&MXhuQqWkm_YYX=&qbslhmVVdYgWn=&6n3PqqYdnaned=&5zvUkvVUcbkUq=&jV22aJWcUbri_=&TvJAaOXgXofhi=&Jy5UwMZhrpYYk=&OppEnjZjajWbp=&2BoIJhYofaUmk=&gEYxNjVjlsrZV=&F26_ypWh_cfdY=&ep6clfWkskVsU=&LBiQP9ZroVXYa=&qkcZk8UrfnngV=&HodvqXWd_sim_=&lzwYUTUdsmVqm=&QmlArlWUjccpi=&eRlQJEVesgjYY=&MeF6ADWpVipbc=&vtDXchVlaldq_=&rmgxr8Urgkejr=&wwZ6ZSXdfVmmk=&6nv3ZtXgWmbnZ=&2jPuweYnqnjer=&E6aqUUYkXb_kc=&PNmYj3WkWqarl=&FokNZbXgX_k_X=&9SqkvsWUbprmr=&ZS5rj7ZkkUfgY=&n65Tq2UXiqgci=&tCMilTUjlmbop=&yyE8OTZZgqVrX=&_Fy6L6Vraeoib=&SyAxbiUsfrddh=&D8ViQrWVrgkep=&6r4SJcXWafh_i=&6LnSbuYWVmnUd=&nHABIeUkpemap=&m22JvBYk_YemW=&qzZIZqYbrXndn=&4WBTQxXWlphfW=&iPiGrXZYhVinW=&mJtRHiZWdmndr=&3HVITvYhqfqcZ=&wMjOzlZeqdkoi=&riSFHiUdgmsfm=&_XWFitWUZYpWq=&XPEMSCWoiVkim=&7TBMd9UnsVsrr=&hoD3m5XkUnljb=&XSL_qZWhlgrep=&6tv_r5VYhYmep=&3CJArMYllZg_U=&c_j_9oVqqkopW=&L8xfc4XoX_qXj=&Knq2w2Yrc_jko=&fKSj85UsVfk_U=&bP3g3AV_ia_dp=&qyAPNSYeVmkgU=&LqFGEmYm_jWgW=&CKpARHVblifVb=&b2z2PwXhlnZVW=&45jRRkYoVXrpr=&ck82vDZjsmrac=&Ixdmc3UXgVY_Z=&s2FesfUfikejc=&LOCVlCY_feoro=&sUare4VkZ_eeV=&qHwL2hWckaank=&m48w6jVfVUaqs=&fZyPbCWZpbXad=&W6T9yxZfdrpbi=&HCLQISVbqsk_f=&hAXnJlZibqeUY=&QMJ5JuUgVYjaX=&SKyKBDWbhsnZh=&5pEy4hUqlqhdZ=&Gv2HavVcraeep=&kdzBSjZdVaimk=&ShYE9rWdcoXnc=&xj75aIWafZhdl=&BC3YO_WZlg_Xh=&LrnYXkVflrplp=&bUwQbZUsoV_qV=&OUNUhLUjanlij=&hwT7Q_WmhiZqh=&HBdFOvUqejYpU=&OxcFOAZdVXp_s=&_EBj76Yidpchh=&FfAEOiWjhqVsq=&cDc394ZoecUnr=&2rQrs9VUifsYc=&r97pEDWblWU_Y=&xxMrgpXkjprYh=&RKfpaLYkpWoXj=&RUDyDvWslhdph=&ucdv5QWhYqdni=&4pKWcZWgkdcsr=&JFalYgYlmfqmW=&jpFSakVUnhmlo=&NRjgtWVaaikfl=&EApubsVqrYeXa=&KpaWLTZZbYrac=&oKmOqVZXZikkj=&2kjl7WUpdecjX=&fVJC4ZXUakpVV=&3u4kveUjgbgep=&qYOf7oXclrbll=&OtzqkaXX_pXlq=&36wXL9Vnpo_be=&wmcIcYYpmXfZb=&_z3PDQWUsYWam=&8sTsDPXlsierW=&Oyel7oYasUoWU=&DbD9G8XjgX_df=&xLlLN4Zfiioqb=&ygo7FTVjgXqse=&8igik2ZgkXrok=&NaeR8zVhVghlc=&mJyji3UZqfWmb=&uFQZjcZk_gdkm=&GVkpMxXckXWWq=&hVsIy3ZWfknXd=&fcpg38UlUeUmr=&2ROeZVWZrUskj=&zlCwQeWdngepe=&FQSIgfVVskfWc=&cn8wdyZhnpipp=&lizfnZWjVeWga=&VYnNQSZWacUV_=&8XdU9yXYUiapo=&3ZHPKfWnrbhor=&I3AtUKUjhWYia=&BGFRtjZZZ_Urc=&ygz8JSUbYcVsc=&QcayoVVichsgW=&MGOkm2Wbreeq_=&JZDDFCYssWjni=&QZHdk4Vcrdc_c=&ALac5TVhkcjjp=&2B977mWkaXrbY=&tPrDc9XbfaWam=&RioutGUcbqjXU=&rbxVOQZokZWlc=&pNETdbUpopmma=&pnSgG5YpUsZdY=&esr6bvXrsaUZm=&Gf73UzVZmXW_q=&YFfy7NWfqsbZZ=&VGLXu7VhYsfWV=&b8N8RtWaaaUZk=&eoLDxFWUiWWpo=&Vw5YZHZXXfbof=&K_V8DwYmhcaeV=&iuTgp6WnkoWhk=&I4MSFOX_aXdjX=&MClinKYfjfZib=&RIUIc2WgXp_gd=&g6o_eYWYWrlfd=&GFK5P5WkXnr__=&wy4YEoZiWVVbe=&O4HUL3YlnshrU=&58qFlsZXU_mYm=&stWAVhWnghakY=&fGjIocYbUfYsb=&5BV255WjWoirW=&TDeI3iYnhfVlm=&uQ72wlYi_aojs=&rwWZaDXpsnUsV=&RXeeeGVnnqcWq=&jIkp2QYiaoeYo=&WzJgP_YbiVaWU=&kH8ThqUp_VnXX=&dlzsKZXmamjkl=&UI3dHsUVjVcoc=&PoPqjIWqslhdh=&poOkEIWf_lUjj=&oc3AeYZgoeogk=&ZKzW98UYlgmkd=&wvBx8rYWkhWlY=&wCVSo_YaZrpgj=&75GoMeZporUso=&BLTRz4ZomsgYi=&8dFmiDWgnnYsr=&tyBLuWZhdeiUf=&ndr8jRYglgqYo=&BehoQhXpWmmok=&chyxzGZdWpZWk=&WdWJFTYfrVaZr=&UIzg9OUkapnW_=&oPNwbYVYZopgj=&vPiXosWcjpfna=&YelWDTWomnlVd=&dktr2MUViYdfm=&k8QogHWmYYbga=&D2M7L2WUpdmnk=&QuUE7aVmnnpqp=&PtVnaRVpcpelU=&ftLaYwXfVdXVU=&qsaA3EZdZlmZW=&XIVDt5ZZfqacg=&Kac6UZZnUUsV_=&Q59SPuXVUXYej=&WWSIdIXaqcnhj=&lG4qMzYbqlmoe=&Q7dUSUY_bVWpf=&X5jwmVZUbdmfc=&kUlpTyZhpb_es=&gqIhEXUfrkUal=&dfbYkaVklUoph=&7263KqXgVnhpg=&PnH5q4YpkmlYn=&NnkPRbZV_Ymjb=&2a9dPGXVelqkj=&jCRxz8WaVorqY=&L2NRtzVYdWrUc=&2aBaZlWZrViXp=&YgIeteYUgbX_s=&SqekUYYdsWhnW=&Nq5nHPYUYVm_i=&AjMy7QUiYrYYV=&u4MJckUgn__hj=&R3ygKpVmkmhed=&L2EerbZshsmsZ=&wmZQJ3WcjXeaf=&b_d7WOWqWodYi=&gvdnjhWsnUkaj=&j63r8oWiWm_pU=&p2BbFaZmVlWfo=&r8apFhYcUWoXf=&wdyWLrVcfXsbY=&VJeOtvVdWZ_jV=&mIoCO3ZgsXbge=&NqUVhoUUlfcmi=&ZujvaoUV_rso_=&IuD_dSWeZXjZl=&SCXaOGUrjof_f=&MOI9dqZacYcYl=&M3hhnzXWZefrb=&EGEFpdZXdddal=&D2beRFXcqfanl=&ZWia9nUdgfbo_=&7agRTXZjoroVm=&A8RJ83UnqgVol=&MsDCLjUjVrVsk=&XId3RUYYebWmp=&gPXtW4Zaqkcnh=&aP3gRKZmh_cfc=&xMUpkkYskjhUp=&VkYxtpWqmqsbW=&ZrDAlhVZmYfsh=&qpUKuTVjcVVqp=&O4K5wtWadXfom=&aykOp7ZUgXjZY=&8yBugcZjqhqee=&AMujJEYcVd_Ve=&QDvFEDVkdZhrq=&oYgaRaWXiUsel=&K8GmEvZdncUai=&LMO_D5Zsgk_ga=&88sWqQXlVWekY=&XzxuhFUfdUgm_=&ejiJm8UYXYkZ_=&a3fguNYblifkq=&2kLZNTXajrcYn=&zexRt7WqobaZh=&qwCNzeYglUZVi=&rpEhcJWgVYXli=&cXfaAZYbaZdno=&VmNUAwUZmsbpg=&uFQqvxXjckiqo=&aprrINUbocYqg=&PYGgbDXbVoion=&Is6znoXpodhZh=&k3SGi_ZssghfW=&65fM4WXdmXkhW=&dpcIlwZsjVXbf=&n62fvoYfjgdqf=&lpwgkTVcqVVWj=&QWTEfHXloiXir=&hiII3zXWmqqma=&3ZMK4jZfXXhkd=&h_sjweZgpelgs=&fhaqvYYmdbcjh=&mY_PFPUXiYqrU=&MlLSTxUf_prsg=&TSM4SkUrqpjgq=&9_nbcZWghYXcW=&KgbGaoYaYjahi=&bhGQTRYaUdbpm=&22vpUYYbVUUjU=&LhMmrFX_bdVli=&UdPDAFZkcnosb=&eziLnbUWajsge=&Rv7dyLWmUriZb=&yTMgHVYcbb_ck=&UFzx_cY_UnXbV=&99pNXhVaiii_i=&3CGZOFYllfgVp=&ZSm5U9ZjYcUUY=&lmXAKcZdZUrbq=&US25gmXU_nZpc=&QHZStUYng_nfp=&Yb8Z3dWUdsnrg=&ozJxYwVofXUbi=&kgqBh8VriYhZU=&VDbdzuUggWUhZ=&SyvmJ3X_WfUpq=&WzYdt8Yskbdle=&Q359DvVmZeido=&mCkL8NWYcedoV=&VKNHeDVdfhasj=&PvVE3fYlUcpUh=&3oITXxXddjlip=&eUspMlUWWecXk=&v4mkvSXssgdfd=&AZXFpDUjs_cob=&TxpG4rXcYWmjY=&WIRM5XYrpWWXk=&c65PG3UVaeeWk=&GgCrDeW_nocgW=&_3fMnsXVpVU_h=&dzN9tbVdVks_X=&sBmfaBUYqelap=&GEI6DvVnXsfmq=&PdxXksYaVVsoZ=&5GJPSQUWmrsVZ=&wf6DAmXg_bdgX=&TuGlxOZh_oZUp=&OZPxyWUgZgjkk=&e4WtX3VXpZ_jX=&oEz8gAYeZngbc=&cciqYCYonac_q=&dOS2fDXYqirZc=&ElpQkAWgdXbe_=&hCwQ5aVnmjUni=&dUKPBsV_cdbcl=&lYM_rmYZWYfqb=&DIMEnFWkZkiVa=&wU9ywxUrZdhkc=&hmNHrUUbhVZZW=&5g_ooSZrspgao=&dVCFiXXqepXXb=&7wz5TQYlXlkVd=&QkZAEKVrWYmas=&OQ_8SjZUjaqdq=&nu6ItBXrbkipl=&DVOkjaUds_fcW=&8OFGSCWmnkrbe=&qF7F5BZnaZgqb=&6UYdWoVmWUqmm=&JOBlMAZaZeonn=&abn9Q7Ydjapom=&4HTQ96ZhjZXVd=&LdDhgaZrfddpr=&io4f3JWhkisin=&pcNLRJUfipYsU=&fAHJhiWgWfhWf=&f_JboWXrfYUmX=&4zaVaeUbiaVai=&hK9tRNXcVfbkX=&TsaY3YZdaalVk=&kUwwCVZddWnci=&oHdPUKZ_ml__Y=&WJrg_YYWbUcWa=&EAVjHAVlo_YiY=&wtKDNgYprorjU=&5esUGcZeorZkg=&HJoFNeYsbhbnV=&46dKvhWcUdekV=&DgHfMQXdsjXnX=&ZnjEZxVnrbYsi=&ifuqyJYjmcXfY=&CUuO6sWameXr_=&2epnKwVqfqVah=&_uRljpZsVfUhl=&tf_aBAVarjiah=&6yxwz3UsVZrrW=&4wbaSUXafmeoX=&ndlRiZYigdgmZ=&tzvPcwWcobXXm=&bXqRFhUqUYnaf=&86yWuyXoaskZr=&ok8svrVdZXaia=&YnO8N9YeYm_lp=&_jgkGnVpVa_lb=&7H72TDWaqUUZi=&VCUpSuYXl_Umn=&qHrCxdUb_lq_V=&HPFujWVddeYfZ=&vlgkQBYiXdlXm=&yYIfMKXUYjajl=&skUUkLUhmqfim=&H8kxnzZcdahUV=&zW7GcTVrrcqZn=&wB5yiQYrpbdaY=&GUvuruVmWaVUj=&etLnLyYkiopgg=&PjqUcCXkjoebm=&nz8oyeUjcsjqU=&IJhLYVZgrWssn=&aQl3sEYhkmjYc=&2nbe9cVqkaZke=&f2oAygYY_ofYi=&bcj3hcYWrWisl=&j4MXbsVjXsrqn=&_lxibmZabaUnb=&MPNfGmXZbXoos=&qxyR99Zmiamme=&_qC59_YVonrkY=&cG9tXQXospqmb=&vD6xy6Yhqajrn=&fxBcqAWfrqnZW=&LiGKQEUemVX_o=&lSK2atZffrrmn=&KBvazzXWXonim=&hpvOKWYUonbaa=&DJDTcxWgWhklg=&EGTKGTXorXiYm=&kmd7i2ZdgdYbh=&iBhR7kYshoioX=&LLCtbcZiUWWbh=&lRlxgIZhenfon=&4LfjiRWjfcpba=&2vB6vtVpjmZgZ=&ffmh2cYljfjcn=&a8Yu63WUUVack=&EYJF86XbVXbZl=&K2PBuOUj_ksXs=&h8uTxAUqesZgi=&NVFIb2ZjVhmYc=&7Tv2zTYnbVrqU=&QdLNNvX_Wjmbf=&vDYR24XoeZpdc=&wItAqCXZohlke=&uUdjHTUqiqbXf=&MCH2daVXgnadc=&E52Vl9ZeoWdWa=&la8XIzYlimngp=&uHJvYvWrgZsWh=&QfypFwVYiUlke=&m7QyopVhWeZqd=&ibHs6aYUYmf_r=&dvAfKHVidodYa=&mKNIuwYiqWZbs=&hAXerfUXoYaXX=&bMWkOIUkccmlh=&97qCUEZnqrrli=&KHWJAfWjrqoeW=&jr65vUYXd_Vmq=&uNTlUmUgmXsZg=&UM6StXYWYmWhV=&9494y9Zmrpfoj=&RyuJEtZaprYqf=&GZVF3PUorYpWb=&YRgn4AUcshUWl=&bSdbVMVeqZigV=&LkqWVcZ_fsZei=&WP6W88XpoVqhj=&8de5zQXsoXXXq=&vk4X2zYqZVVsl=&gn39G4Vcjphcb=&DizFIwYqmshsb=&4f8yBLVYmUpZl=&64dQ5TXfrbUXe=&wB9ZwQZiqWmW_=&ksO3p8Wansima=&wCkWJOXon_Udn=&SUVkxgWiVdcXU=&Fps6OsWWnlkge=&SiQapYXbgofWl=&f5SXrqUcpsYjo=&ukwN2RXhkgfkX=&deyXtyUWXpWXZ=&YuCP86XjW_Vgl=&j6thgbVhnskbc=&BQYiEbZsbXbfi=&oUcS4nVifYXUm=>R_jlYVlrbZq=&_zWj95VrgerVb=&C4CrJLWUZiYeU=&kKBBCzZrbrUsW=&VSyVtPUjhjgXX=&rsube3WVpkdnZ=&resttPVnlcXrs=&tUV9nOZVgsUgY=&XSJop_YmgmmZp=&SOIuEvUrdneeZ=&xaehKbYfghsnf=&uqcdZxXUfWrdU=&qw3QiEZqnqiZe=&F6kbP2XWjlWdq=&PMTa5dVdchiVs=&54KMLKVkrqg_f=&_XJpoZYjopfaq=&NM7gpXUVqoZVl=&wPGLtJWhsrkgZ=&NhVgtmVhUVWsm=&dMFkHkWWkmrql=&YtvFlzYiYWZ_f=&UHTL6XZciifnX=&6f3EUJXbjqpXj=&utMxhGUWnlfgd=&4e3MGtUZcYhaf=&4rhLsfYjmdj_l=&ZauB8ZUdWWhkb=&_cSD9TZ_gapf_=&W4RstNYiolpap=&66JJtBVbhinoV=&gHLzi9UlrrUd_=&iGRr_RUfj_lqV=&KPgk2qXhX_Yss=&s5ULTaUjaegm_=&Oz7i5yWqWjejm=&fIpltkXsbmVmm=&dFbjaZXedlUjg=&pss_8tYo_m_nX=&fZA6hpUckknVa=&Ii86qkXcgeYsU=&dFC5PzZmar_da=&UgIFx5Vbrbccb=&EmwMKoUfrgsjY=&2fcR6jUajg_lg=&DFRn_YWperneo=&PaTB_7VWminii=&n7JQ9hUmjjqrr=&te6zitUYhWdpY=&H6tkOvYekX_ss=&OIxLBJW_fpXhr=&Hr4ldiWdcbjmp=&GhAy3JXgYesfX=&STcsX4WrelrUl=&eGhJNCZfl_rUU=&ivGtlbZirrgrd=&bdMefUXqdcbha=&BpEjpEYWorXZe=&xks6iKUnhhpZU=&ZY9C59VslodrU=&mrEFqwZoZjpWr=&_FSP4CVemahYa=&FkjtoAVsac_rm=&uLRjQGYnUdjWp=&5odGTAZmbbilZ=&H9vwjbXblgaai=&9XSBj9Vffiihi=&kjvo4YUqiemXZ=&ZO8JMSZhghmaj=&HGzWdNUbhjhnU=&cGo25aUkjnYes=&kAgFIpXlb_bfk=&3OWohbWXlUrZZ=&RuagxVYVZZqiV=&JSs7V4UhpsebX=&wq4MfmWjgnUYr=&mOrkV4WqkZp_k=&SstnmaZdsW_ne=&cW47WqUYemjfs=&2AtWtIYrVgphc=&SQKAdhVfXsiXl=&SwwMj8UipZoar=&D9BzHqWVkUWln=&UIldq8ZXYmeXr=&D5HIMiZhfhcod=&xKvR8fUbnbsdi=&eAPkcMWnVWbiZ=&hplyeOXikXqrX=&uG8FvuWedfhgh=&g_VpjaVoirbcf=&lvDyyAVUrkgXj=&p2PXRlZjslrUj=&s3i9vKYedgdnX=&56AtFIUqUdpgs=&kIVnUFViqXbUn=&ighTWUVrgsjdd=&zZjfbTXYkWodj=&z7daPBX_srgej=&TUXoZRWfkiWss=&oFmGGRXnVbpmU=&dyC29hUkhddql=&3YaFbnZWkVofp=&Zm3CGCXrhpedZ=&2dNxqKWbnpphU=&Ew8hsAZm_V_pe=&fMgjpdYobgsoo=&Mnv8WFYfgdUhi=&N3tWmCYWahcWq=&bWSXIrUjidlkl=&hHEi7fZqUaaVe=&TlPrChYrhpWkn=&DBb2MJZjj_iVW=&AKf7Y6XkeriXa=&ZRpZoxWfcgdfZ=&zZwW3zUsmssVh=&IoO3nIWjdXckn=&mDa2foYpW_dms=&fsaXT7YofhfbU=&xKSywEZdbkhYe=&vsD3dEVfbrams=&brRgoYXffXigg=&5fLhNJXilWeqk=&wY_eqnWogoeke=&6wmwq_UWbpbYZ=&dxyxq8YrWlsgV=&NUG4ejZnUfZec=&XqWhQqYYjjhlh=&P4GLAHU_ropno=&HWYydDWUeYgZn=&2qlCfnVsddklV=&2CMvUqXmjdYgm=&8MANnUYcoolkl=&SOYXpcVmbfofZ=&L2Xrf3Xpdjfcb=&ZdfijuWqio_cV=&gCpF9jYacYrV_=&Rh6FXoZaVdbis=&OMk9KoYU_inmo=&8x57BoWaVYZok=&ndlelvXfWnmoZ=&aMeXZeVheammr=&HdqTgVVgqpsej=&QUrXFGZmpnnpX=&KammkBY_gbael=&6KVp4aYbUfndf=&XqeIAwUh_f_qY=&uEArD5VaffadZ=&dIhPOsVZYsonh=&_WqD_RXrpfnWq=&tloSJSVX_escW=&LsCe4zWsfY_Wp=&FUS7LtZrrZZWr=&MqrXjVZfZVUdg=&N6Go2QWdUUq_d=&GN_ntvU_ejlmb=&gFhZKrXcbebsq=&4RvpPYYlhr_ng=&INe5fYYlmiefr=&ibHb7qYkkolqb=&9OfBM2ZkUbeZd=&mY_AnvXhleZkj=&UtxkR9XYjkcqc=&jqu9xuV_jbiXr=&V_D2PoZrrmpVi=&qWw2daXhroYam=&4CfO5VUapX_dl=&N5xXUzUagdaXf=&M7AngiWVhg_m_=&CLLPZlXYkZpWp=&hme79GXVaorjc=&BOvoSfYjooVYg=&AhseE5WWklkrk=&g9qRt5Wcr_ffg=&d7iz3ZW_dkslm=&kVxh5TXilpcbh=&6CEDI5Xcsampn=&i5MwRAVWcrlbe=&lhsSOaY_qlmso=&FX2crCVWgVsgr=&OXocOsUlVjjok=&2Wap7UYqVcqrr=&Vq5Xz8ZfZU_WU=&7Sp55zZmbbnUZ=&PXs6EZXkqpXbV=&bLks5yWaZphbj=&tg3A5hUcVfels=&sJdJKZXh___md=&DnxiCPYeUikne=&pbhTJqUrsdXVk=&FOxk3HWqqndki=&cRWy9XVldsoee=&OADm8EVbmrigq=&CHRYmRZssdofl=&8tLBc3YkYXcak=&MBkI23WnYfXVp=&Ofw7phWUjVUca=&KDUbSbUipq_bg=&YqgtgOVWhieUY=&qnyFvEXhfjsk_=&TYXeYfWUghUrU=&lvCWwIZfj_kgg=&2GVUOQVnsceYl=&lDHOs7YoWghgb=&opZOKyXopoiXc=&Y9Dv2_WjngbVY=&IhzRO6YWUWdpd=&OM82H8VWrcUgf=&Fa8jz2ZW_oisV=&4jvIUfVdXnbYo=&ZpjJSmZYqknpe=&ouTEEzXhfcpUX=&lNafkeZjqkpnc=&R2bdgAWac_rlV=&lMFDjXZolsdsr=&tR_ii6Zdbi_qr=&DyZ8hnUssjpWo=&5FLgTRYgrkaU_=&p5rB6cUoehcmc=&kmZkVfZscXkWW=&zcS3TjWqosceY=&gJRdrjWcYnVeW=&ZWgMSCXg_qblX=&KxYOIhXfinibh=&NyL5_pVbaiXpk=&HdVOytZoaipcZ=&pBujA4WloeWhp=&mMzMxuWlm_UYU=&woFCpkXbhWYXb=&zSh7rTWrZeqVo=&eReBBqW_gcllW=&Oa_VCIWoVpfj_=&bpfWTaXshWglU=&Sd8fHsVZsebUm=&wC6eIOYWhUrk_=&amw7f8XarYhss=&OwGHjaYbimWYi=&fGah2sVrchgYV=&e_dWk5VYcokbW=&uHTCfgYqmWaca=&HWUwINVXkdWk_=&8PHIhFUcfisYh=&qjMFynUbW_qgl=&Um7wBiYoleXXh=&cQBz7fUhgVbZi=&YFoZaxWcnaWVg=&GqlqwxZVocpmW=&NRo5GKUXnkiVU=&u8TdNEXaos_se=&NEX2qaVrgZ_Wb=&ixpvPcZiaWgii=&nUpEuWXjXlmpa=&qqV4W9Yqedqnn=&D__9moXsh_dnm=&FsRMKiYi__mVY=&hrjzmHUfXUajf=&uxcD6WZldl_ke=&KL_ZnLYoroppg=&9tocZsWXloasX=&mRLxsfUgpVbdX=&KumMT2XXnXe_f=&FkTkBdXZUdcjp=&dBSRizYYkZXqp=&GWWmlmX_ogmgZ=&YCAMqtZakpXbi=&A5_aqKYocaWrY=&88qFDtYqppjiV=&W7h8G2XplZmdr=&r8BuQFWqij_ae=&7aPItWUWdfqeX=&i7MNlDUVkVsUo=&Y4Z6ZWZYkeggg=&ka5EcZXckfYqU=&UbJNDNUssqjZa=&t4o2MmUfYcasj=&h8o2C3WbZrqsb=&VKsGMjZqnirZZ=&vSD8wmV_kZplU=&qz64lTVYpshjq=&c4rNNjUhXdbXX=&_UiH59UpkabUW=&_WpcdjUpjciWm=&mDywMWWVddVpr=&JixBidWnlpclb=&63rrRGWsba_Ya=&VWlyahWZmginq=&slWYVlVbqYkma=&kantDgVq_ohso=&r7dLuvXZbZi_X=&8RV76pYmUWUZj=&QMuOEXYighXhd=&3Vzu8UZqZsZVa=&TxEnhPZlZboqk=&CFV4ccUoWlYn_=&buzDeQXrnbbp_=&X_M_CUV_Ufcqm=&LpUXJ6WaZnrZs=&taQul7ZsW_keq=&hoc5ARWhhWiVq=&nhSdwpZinmigj=&tYMCFXUhgXfdi=&XMMvEiWoqsYXU=&lMpeAzVZcpWVY=&6TyMbmZjWofoh=&l5UjkSVqfr_em=&BfcwxxYijamjV=&zdKdzPUVoglff=&NHM_AeYgYUhmY=&NE34d2Wsaesdq=&L6Xn6BVVUkUip=&92UmLlYgfkYqV=&o2lmz8XdYfXVs=&x7J2_jWrbXgUk=&AM5BknWkgWXqs=&lumskvXdirbqX=&zo8zw5WWprqcc=&KzrQrqYUhjnh_=&cKLeWkYjl_saa=&8kBkAnX_XojbY=&rD4qgyXkVZkah=&U6zq6QUdgamnW=&4OxfncUXXYWlq=&iZZFzbXhh_cps=&SHD2LpXVebe_V=&P6nGb3WcdpsgV=&5JDLdNWrUaeWZ=&ENT67YYZqmbeg=&OmYCPvZXhhjnj=&6Y8bbQZfjedpi=&KyRJ6uV_plmmd=&ys8Y9GVhmrhpb=&UYSQf7YrZahqV=&Y5O9WEWrjeYlW=&XcyCl4YcpinYe=&OCgZvvZqZcrra=&5hWoCsVkZiUbf=&VGRwNYZXYcbhi=&NTVzZwXpighra=&aKmTgnVnsZsZX=&hClYroUhnfhjl=&RZQXtQWriWVsl=&9NWAWhUpjlsk_=&4OnONAZaZhemf=&jPmQLSVcX_frk=&9tIVnlZn_Zsok=&_WH5IjYl_Yghn=&eAxTXLZUsssdr=&X4uOnAXmWbjqj=&doQK2tXWhhcfc=&GgADjTWXWibld=&7n5lz7WYYdaZk=&5qWEuoYUWUYYX=&9vrpkLZoZsbkm=&I8iJ6dWsgnZmn=&p4btCkYrmZYfk=&YB6ESFZqYgaoX=&Y6dmXfXldgXer=&83pDUZVlgiers=&n7pjHAVileqeV=&V8glzrZgsqabe=&7DUjsWU_aVhof=&3RrKbvVkeUrng=&ynsfHAWd_qVae=&zENLj3Zd_egod=&ulYTUtVneoZWj=&iu5tI5Uscam__=&bahpLmYqrUlWh=&znzjQXZffWb__=&SIhCUZUlYslpe=&YUmSwSZjcgsVo=&68qTNwWdXosWp=&dPLHKVUZXjarU=&JIcsctYlmohip=&2mwJx7VinpYgj=&34UI3eUkrUljX=&ijHcsqUYsmXnh=&O4Zi8ZZlbkdho=&eGURllWjbjare=&ncCbv7VZmgsjd=&RFiGrNYXjXZql=&qcSBpWZifgmch=&pW2GE4Ymjrdfc=&zKIIXIZqgerba=&m_WipSUcl_WjU=&jBksdKXmsjgdj=&VYXtcKVrjfXpq=&LjiB5EUemUeUi=&tG9xcdZYfXno_=&i8doprZclehgW=&exIf5OWpsshYn=&2fyzrLWhaWZZp=&HRFH5uXcVZXda=&IesCODXWYYang=&iLhCIYYccZnWr=&iB7Dm8Vd_rZdV=&LeN83sUUWohYf=&OWTlGaVYcpoj_=&aKnA2MYq_nqbj=&85hkG8XXqhkri=&xYhaOPUdsdncj=&tAQFgnXUbsXVo=&IvnD9PYgb_nWh=&QJKJVUXUjdnpj=&UwjSG_Wjeflmr=&naj97XYWe_ngn=&AVQrFcUcfnkUm=&RSivFpVbinmnd=&d9mqb3Vaarrbp=&eMi3CUVrhZWmb=&FgFH76VjkjXbY=&JzQsXrZhhcojj=&VuMSEXWihorqj=&EqCvA6ZVWrekk=&zG8VwWUqipcrW=&PcseeTWaWprdc=&IaZiKlZaodcje=&HSWV3qVVjnsob=&iXOCKLZprYkcs=&b_O75PUdVsarW=&MM8mGqVYoXVUd=&rQlcwQUhblWeU=&HEg_dKXmlsnos=&jbRrfGXmhlre_=&mtuhDcYihWefs=&3x5YoeXab_nYj=&BRbOxKWmfnZ_m=&JFRDmEUbo_eia=&DAdL3uYWhdUkq=&q8gPMEZVppoZi=&WEkz6oXhpUqVj=&mkrQG6WZbgknq=&HgjSh2Vbfmjod=&nemyrVWiWmksq=&JMCh86ZUarohe=&BPdsaUVohoamW=&dxXoSIV_ncepd=&5VKBTiUYZanmq=&L9HkhEZabbVog=&Bk5zRwUfsnirb=&Bf_LAsZoUqdcm=&DaKwaUXfU_Url=&WX8T7pZbVWVgj=&ujMNGaYiUnffs=&yjI9USUnkabag=&ydGEA9Urienio=&DnsmenUlpnjUg=&iwpeiCYdWaWaV=&MDVr5RVbXVjdn=&KMly7jWdZrann=&xL9NXtZedjqfe=&d3Wi6VUpVq__q=&RaAjgZVsW_ajs=&kqhDDbZsgaejr=&dldaJRWnU_jpn=&_kYKugZsXpedZ=&vZtTxjU_bXXld=&kkSO3yXYYlUni=&3giZbGXckeerV=&bY3c9iUfjiZX_=&hEHN3fXXsoaep=&uH7qZXYsUbsha=&gGmUtvUpUsjre=&ECQXmhZd_Ubia=&dlFhmCUmisUip=&EcRPeOUUfgec_=&NHwaavZjrWfVX=&oCiFP2Ydeodjh=&_RfnhdXkokpgW=&5pC6eXVragkWi=&FvcvTRYlYbbrg=&yNIOLgZaddZfc=&oQ6SFIZqndicc=&4EvtDTWgedblr=&5Cl2noZkWleaq=&8TJRHDWlfpsjp=&qHmDsmVaUUWrh=&iX9kKJXZeVUZr=&DgbHu4YUqkZpn=&yzQ_6TVfkfVUq=&nKwlP3XqlqVja=&ojRPIGZbocWVl=&iv7MwWXnWahXm=&RqkbJYVhXjVjW=&YrBI3yXsWohjU=&RQIAHmWqeserk=&wWGzX_Uibkihp=&YT7LkvZVZarbh=&ahmigGVbZ_sXs=&TY3q6EUkZUagc=&AyvTrlYqhhfUq=&zKmT5wVqXfosa=&Th7KnVVcUbjlf=&rcyDQQWsignUW=&e5HivkVfjhmij=&22suakXVrklrc=&Qzg_EEUraX_eU=&WiH8gWVlslYeg=&RXDdkgZYsejnq=&2VGsWpXrUfphf=&58SOmEYoVdmck=&vmg_ECYcpafmi=&HrWn9SUabVXZW=&ZROpu8Zqjj_jX=&dwuDenUZ_phbU=&qLogjyYgZiZWV=&B3KNVYYXiibes=&9_heCCUYghpfX=&FybxQhVnXrlhh=&Zm6lJ2Ueabps_=&avxCaIVrXfdZb=&aeNcQPZrdfZVh=&zKli7nWWehbVV=&PfelfbWqskspb=&WAtLpmXhsbXii=&NT92HOYssacdi=&Qf5pFoZUWWrgc=&2EollsVkqrgss=&MN6YffYisVpYZ=&h7qC5nVdskjiY=&CIy5NCYcWnhcm=&n99mteVeqkUrp=&4uaKQIVlsjf_c=&MDwTJrWnWo_io=&8JAwVTZmie_eU=&5ziyKRWjqbokV=&qOgOHEZnkgnml=&aXc5oEVpfmirc=&FYFWf9YrVrocZ=&52WKbhYVrkeln=&rLKpznWkbgsob=&hZH6LQYhrUbra=&k6XqaKYaoUhbp=&SQcNGBZipbZsX=&mD5v9KVoUda_j=&GvgxnyYdfoYVV=&uIPuiyWkYm_gs=&4ptyMCVf_bdcc=&FhRLARVmksoZq=&M6nFOAWnafgVX=&zdroklZgmacoo=&3NXKheYr_lWZn=&t6gifOYbjVplX=&kl_rGnUfrrsgZ=&_XpTNBWYZeo_h=&9Twk66Xcabqmq=&xmt4MXVnpjhVZ=&aHOVebUZhlpXV=&QV6TwSXWYrqee=&UGNVzeWZbqdjW=&e8YMjUYfcncWX=&pF7UZ4ZZnsske=&FBoCfqVWslekU=&cuXz8nWWYnWgi=&HUAaOcYcYkbqf=&jJfrKuYWlYgbV=&Mr4hPaWbjbZlY=&slewrmYaVcYnj=&8SnalcYbqpgnn=&Xa9cV3XsYlmoZ=&vKdnj4ZUcVZne=&pVx7_UZcWiZVl=&7kdoXdXjhhVXY=&z7Od4yYfdlYXe=&nz6vsjZZr_saX=&Ww2GCQXbpYkbg=&4nb2TXYsXa_Vb=&3aqqVlZsYUVZW=&5TCUL7WfpflUd=&vq8NAvYlo_amo=&bvTHoEUkgkflX=&3sfYmcVffsngY=&X5zRXcYcklhfc=&JaAsFRXVjfgik=&XVnZkJWUnUsbW=&ksekItWbsWVUa=&z78RTRXn_cXZk=&W8r7xdVZjledq=&QX6r7XYlkmmms=&EvFOyJXqmmeVo=&_Z7lItZskhZWh=&UcGIHmXoegjrp=&j7v5_wYchiegk=&tc9uuSWjjohUh=&DoNXNFVZVZe_i=&r4OmPfVpmUgmX=&eHUaPhZWorjZq=&pQWFt4VomWkfh=&5zq_PFX_fgWrf=&w4VhMbXoXXqgk=&USVjDlXmpcUoV=&mSS3TaYXgeemr=&KUcFooXbqrWXs=&GCB2arZfdVfjY=&AP3XJgWpdZUmr=&l2JfONYgZ_YaV=&hqx_knWbkcUd_=&Q2eUBgYosqqcV=&UnJTzqXXcj_so=&CqXfEKZasrppb=&288INBVqaZs_e=&w8jNRSZVaodjp=&ieZLRPZhoXWek=&ClKEDzYU_YZbq=&QqcR68UmXcleg=&HfyXFzVdX_ml_=&rZg5rTViYoYhj=&BUpGemZkqglnU=&nE8Dc9VljseiV=&oxzvoeYnfnrdd=&jj8aNtWfZmrle=&PKOWUgZZcgZng=&8K2e65UpXhYYj=&5K3LYPUXdikb_=&zxQnM3VUalWlZ=&ErqknPZeUhirj=&GldGSKZUgmjbs=&NBE55uVedUZqU=&xc9loGXjgXmbh=&QgIVmIYqWaXjm=&tv82EgZlYl_fd=&PXMo5tUrmbhWd=&cJNQn8Vbfsqmc=&Pr32REUXfqZfh=&OYzlxlZroaVom=&o4srxhWapaWm_=&49SHzLZonUlrh=&H4XmKLXfYeleo=&AFBE8zUWnYVd_=&CZEi6VZqcjlqX=&iTr6sqVUZUaee=&MiuVo4WZoiWik=&JIrmuTWhrriWr=&SeICPKVfngZ_o=&hsR6yxWbgeUVr=&S49lfSYmnXXYZ=&WjsqrSZlXokbl=&xSk5obX_kablY=&TlSCJ3WnYpbYp=&dXUo6RUhaWglr=&vUsvDWUpermak=&QL8qE8YpsZcmi=&jx_zYhZYsknUp=&nifqdtU_Whais=&c4K47BZirbq_l=&rc6s8ZWkemXiW=&4jMGeSWbmjshU=>3AjVUrmqWZe=&EhJjHFUjgejVZ=&mgnr8OYgaYejZ=&h_Mii9Zjheide=&QZUTtWWpmWihg=&LxjbM_UgdZfVh=&Ff9qT6YrafmZ_=&3IBc36YVWYigq=&7mNQ_ZUhfrZl_=&SX7GX_WsqY_pk=&nRFXbDYZ_WUqg=&D8LMHWZcdmafU=&hv7ul2YeWVgaq=&m9ZRYVWiUmjXs=&KrMPwQXWYsZqn=&9893KsUjUrlmn=&PQ8ZUWY_bqiXc=&YwuIe_WprrfYr=&W_iOPsW_miYka=&ySvzqYYpqfgmr=&qsXrBVYrmcdsh=&HNxPMoXZVlgXc=&wr3pnuYUhZViZ=&lquDynZjpic_h=&KKOZgtUmmYkbm=&IA875aXksaakh=&GNUdF4YXnmYps=&6KtrlAUeZirgV=&AjunpkXpfYgd_=&rABIVsZhkoasq=&NaFjesVYrbrss=&e7bEHLXcc_Umr=&3TcnVGXXghodm=&mzvg4DUU_UYfk=&RUpsQFXaZUdcX=&nXkg2xWiZrkaf=&wCvx25VlZdghl=&pTpuCGWmZrVYX=&IT7RRkZhng_qr=&lIaD5EUZXadZn=&yoCqlJVriUWfs=&7yTPdyXiqjYki=&txONhDYibcqpi=&_HxrVtXcqfoam=&tv7EdrVWXZXps=&8WVVrbZknrpes=&_ogz98Yfeeple=&zfPmCLYeUssgj=&bpLNyKYsnmrkn=&DQARcTWnkqfVV=&UW8KkpW_lYsqg=&QTDqp4Wcn_ngd=&cQXJFWWgjnmpb=&RaQcARUZ_ompd=&coufUKVXos_fZ=&tVqe46ZXsiloi=&Zw8jY5XYaVjsd=&SGZlYkYqknXbW=&WsIib6UVrZkdl=&lTUzPHVbmshmV=&NdSovRVl_Ubrd=&vXwlIIUcZgl__=&NYtpX5X_Zsgof=&oE6Ay_VbiWVej=&9Xy6MzUcVZjZe=&VvRFPcUpe_rlp=&47EUXmVdfjXlh=&DJyC6CWaq_qki=&Z5FZX5Vhgbsii=&MuqUIMVYcVrgU=&oICXvHXfpjpdW=&DFdFZ2Yqogfgg=&8d8kYUYhlshrU=&KRWlrYXbgrWVq=&UryQ3tYhUnWop=&Sn5Zu5VYhelYg=&MMnyezVkVoWUf=&namfUCVcfoehm=&YjonuMVUfYfXf=&vWnFsEYbmbUYg=&UYkk_ZUdfhrg_=&X36kgeUoqdVXW=&3AnmDeYrdVb_p=&RsWwC2XhUhUld=&PlSXlXWkcXjhn=&XTzdAXWqZhbqn=&L2bBwLXpXUnmi=&GVJltlUVdfUbs=&xDiiwyXclqYXW=&SpSCK9Vnmjgeh=&_QgJVHVlWalWl=&8C9E4CVlcsWfU=&M6fFVMVdmsoon=&83ikafVrViZdU=&C43ie6WpkhqUl=&EXln69XesfbhX=&TEeeROYWjbcrm=&_US4oaVZ_dlss=&v_aWFYYigfckc=&iq4PCSWjqbihq=&75tk2PYr_sihY=&Ddd7wBUjaXZdn=&KQ_B6cYYm_oXk=&TfMcO8XnfmUob=&dd_zj_ZYgahrm=&beVUCoWgWoohi=&lFiLFWX_Xspic=&xRS_nJYbscgiW=&YeImGSXUdlrhq=&rT6dTIYpcV_fp=&Paa3GjZkdrhXo=&pnRLvpZljVpUo=&YPim8FWqnlYVX=&34hIchUakYVpU=&vBxcuWWpjpgoZ=&TR5zPAUnkVcWf=&8hnbWNYqkYnYf=&bCZ4NmUmUbbne=&2I9DcWVpgnojl=&DibgbNXXlbVaq=&hrhmzzYZiXdj_=&4xHnI2VoiqU_X=&5vtsifWddjYeV=&UzDqrQXcgnnYh=&Lo9j5tXWiYjWi=&DBqGl2ZmoapZc=&xJBIDCZoUeZmj=&5iLardYgXrfkb=&482g3nZjksWfU=&rnhr6rWeqfiWm=&uPXP7SVobacfd=&7ys2_oVdf_imV=&HQ7mwXXacqkdj=&7Hag5DWZhUseb=&TYd2cPVYshrjj=&KdQshpWXlmjZo=&IDNkxvYfYqhmZ=&b7b6wkYrlhYZm=&nyXfQmZZfkham=&fdJ9nzZiZUgbX=&xC6yV2ZYpgaYr=&exux3mXrhbVnV=&zntVFtXfWjhh_=&7vaotzZUZrXjr=&EU_Sk_ZUUhqsb=&RWrq9sYrrWccV=&drgGXbYZiojds=&hLtWkaYXopeZl=&sUTlqtXdYsUjr=&CmfVHPWpohVjb=&LH98TYWefradW=&dSW37KXVojVso=&tcRHYkWXdmkjZ=&VrUXjUUUlVsd_=&wIxBTCZjYifYX=&X8j_qNXlh_qdj=&6O7F_AYl_icig=&miGEhGYhpmlbU=&zKpYE4XomfbfW=&neO2WtVUjcY_o=&aegfGQVUprmhc=&4jVvy4WUfWroW=&XbLfPHYUjWaig=&lHozAsXlcecbh=&iGJSH4YXUmlqi=&jENJw2YUYapZZ=&JfkSm9UjpbnUX=&l3zQrQWiigeXZ=&VW2BdbVlrZjXU=&BVS2RzXnihpUo=&WurKG5XlhZ_io=&sFnfU2XlVYdla=&2DdC6TXjpUdgc=&8vRFMmXrWkasl=&ZyUZlWUqbUpai=&U_3I6QVhbcY_n=&wnjALDVososXZ=&ag9waZYkYlmZi=&F365T3Xkodcak=&VeKpDVYaqUrsm=&4MgZKGZWnYfhl=&aA3jSyWhWWbqW=&Ws4qB6ZbsUbp_=&ynaOuSWkokqic=&f7Ui7yWmmkWdb=&c7tq8lVroZjqm=&frYGsUXmZqdqo=&E_KlPPZsUZbfW=&_5iUQqXpYpidf=&HQ3t8LXbVaYoc=&rEqxNOZ_XY_pl=&pCv4bwZlefgfr=&dziHWSUnoaamb=&zIk9QuYkeqqZb=&4Fft6yYaWhoqX=&3Mcd2SVnhgXXm=&ZmZ5JKWceo_VV=&FM2XZ_WobUhiX=&tDHZGtXmZilno=&srkTgWYeVYfgb=&Y6SayNXgZggds=&bxTPYFXnpnned=&kqOrGeYdXkika=&nU3KBsX_bkman=&PRyLIsUV_WnqU=&NIc6wWXYljdad=&yXPeHaWbacnjp=&cPUIPQYaeckri=&v5HV_IXfXfm__=&NMJhDOUjdqoWl=&wbFuF3WXj_gUe=&lQgTVeYemdlse=&LPbQOpZegseWW=&MyeIN8UnmkWoc=&zc7SgmUiUqoci=&sHwBuBXppbV_Z=&Wv8RVWVegWiWa=&k5kQekZbpboVq=&E_fqN8XZ_Ymnf=&ps2R9nU_Zcnkb=&5SjZFgUdpnesd=&lk6mCIUmqaVfn=&gbrk2uUckhsYb=&WxzMnoUUblbbY=&Pt5ZTrZoomkqZ=&whDdADXXWpgbb=&nK6ubFY_VkXZW=&NU7g5HWXaZ_cb=&3VR9qjUsrsoVc=&b_j2TUUpkqXlU=&8UuQP6WfqjUVb=&QNqMN_ZaaXjg_=&cImAv3YiXgVe_=&NOHOfWZhkdbUm=&qzBHLDZnZVfjU=&ADJrUOUihbW_U=&Dx4Ra6VcndreW=&z2L3HaXhmVhbe=&8JRwmoYsssske=&6HHxocWfbrX_V=&HVuTM_YVVaoXj=&9YyJo3UcgWkhj=&oyNkZmYjirmpq=&nXxWa3Ysqdmmb=&AmSUvKYYZbnZq=&IXsDuDZY_lkWa=&wNJoh2ZfndiUn=&3S3NhZYmpigjW=&YW8aEUXeabskW=&OQu5XjZoaaWkW=&N3Sl8TXoZiZhh=&fHCh_6Wckbbkd=&EQseVsVpmWiUe=&dpytmCYdihbml=&qV4nQOXpkderU=&4FeSG2YfdskVl=&RVyApBXriYYjs=&r93h79ZUgqgqg=&yJRQkVZUjVUZa=&rwqZQFUirglVp=&IVVZVOW_rqffk=&PFhIURWkWWpse=&y8d6wQYgsibnU=&RvBN4qUfjcXZs=&Z3TKQiWe_VUm_=&zKfSmpYUUXjUe=&vKyn2cUph_dbe=&2vDquzU_nYksm=&38XgMkUnXbVle=&NeE26NVnVaqhp=&vLjQpRWhZoh_V=&LkeDYtWmkV_Uj=&43n2j3UbsdiXs=&fPG_QxYYrqfea=&IyxZizZoVdnoa=&vg2JvBYnhYq_c=&SVcIacVihpine=&vbWCoMY_lWejf=&jLlx7kZohooen=&OlcZTsZqiqgjo=&oRz7GtVhdhcke=&pTVxm2UYdjqhf=&wAM8zxWZlppcg=&UDvvZvVnZfWcU=&VnZ3TlYdrsXWn=&fkYfGAUV_kYe_=&zCVJgKWZdbVbh=&DnWb_vUndeqiX=&ewAaDDYUeksni=&e32n57Ul_asmY=&p7RyZ5ZYXsYmq=&CeHD48XmsXaj_=&zs9jzFVlbscnb=&l8PSofUibbsef=&2olB5xXgpbYWo=&p2eVSaXinmsrj=&VxTzHNWaXq_s_=&mYqlnXWVeU__Z=&Qr2uyEUklg_gc=&azPe6RVjrhZoc=&XdVTMwXogWrgj=&ByXuN5VUnWpfs=&4TMe5yYbrfspp=&L_wehTV_ejogm=&H6g2HRWislVgY=&Y_Wa7QUqelWaq=&7_X9SOZWhWbgp=&gQW_c_Vdklhra=&RZ3k3WUjUVeZi=&DI84stWX_dWhs=&DMSW9rWsdWe_i=&JxC2cNXVddkaV=&gAj_jYUg__ZgW=&tQ5U2NXoZpjnd=&DTMQWrVZqsUsm=&dsn6iLZYskiUW=&PYaxehUWgZVWs=&YNj4okWrZhjcW=&snd8QgUbrrmsr=&ZVGiXZWXcYZpg=&nSrjN4UjVpVWm=&GP433BZZUaZnq=&p8WRrLZ_mkmer=&nYa_bAW_olhih=&_uhSeCWZdspfa=&uwbc49WilhelW=&iEeNveWZb_pig=&ngasU7WlVrmoZ=&doom8JVdopahk=&sp9p5FZooZirh=&Om_T6_Xfergak=&L2YkE3YqXefed=&rDTUvQWUibkeY=&XPSLTKWmgVWiY=&m2CsU6Yfpfrbc=&2cUp2OYibboos=&nWDiHcZcnmh_b=&6UNs8DYYXZjjl=&rLVLsCUXWsliV=&LCipxdUUlorZo=&Ly8K_SWkpkifZ=&eksVqoUc_lgrg=&W7ZbVrVUliles=&XKq6WVU_jeVrr=&5fcbtAXheeYao=&sxBuXCYapUf_c=&8ZqzoEWhgiXnd=&TqyRxoUYWUVqd=&f6Ln3KZXZrbXp=&xClav4Zp_qpgW=&fKeWDZY_kbmXo=&SitvLYUmlf_rd=&tUeqzHXkpWpnm=&Efyf9HWkZjjdU=&_f6AKfUWXjiVh=&IZYnhAXnoebad=&JEA2oQZgmssem=&qdMnnZWnhds_Y=&aWJ6ziUYYldig=&7cuhj6ZUiiqsb=&zbx6JQZlbnqfZ=&AnTOnsVmfafgZ=&WDDmlpZlclkmq=&2Tn4DoXcjrVoY=&sawem7XhqnVh_=&9qvM8iZnVmZZe=&QdgdVQVmglWhr=&wkg75iU_ihfXm=&gn3_RqYcUZgZn=&IxWBVnZnorbkl=&dYt2ojWfUmlgj=&BxsiVBUaYciih=&b2e6LIUhiqnbg=&9rNiywVp_pomU=&8TvmYBZkWncfa=&zIPZbzVe_ecfc=&iapaqfWlbrmsc=&4l9qnXXiilZsa=&BZdaMFYdepqbo=&5aFwejXlnXhYk=&bGuB7zYrahhho=&DcMJY_UXsgZZs=&4IqANLWYorgmh=&pTxYnKUersWXn=&WojgH5VdpejXm=&qwg7RGVcZgfZs=&8pmiS3YgoWgol=&av2CZhWo_Wahe=&orLjgwXbmmeeU=&jYZwAxUodVgnp=&xwszIzVoddlca=&lDTka6UhrdfUr=&QtCM6JZfbfhlo=&s8oGsMYZdUYeo=&o73YVmUkjlfdU=&hh6VteZlcVXXp=&BFm7JFUepblga=&ikwrnNWZmXXkX=&KHxeEiZZZmVch=&Z65HiZWckWpeg=&9DZfRGXcskmUq=&MUtRBdUZgVmaj=&wEuEKAZnXchqV=&b4SeHzZbhcpcf=&ZS3bqoYVjjqjV=&XkCmh4VgiWcml=&sMu8BPZpkWfno=&NH545_VfeXnoa=&ENKNvwWgicXVo=>rxqVVZefWWW=&NUAU6mUscmUXW=&glPiPfUqprnig=&KngAp3ZjWsZeq=&LZXmCkYbrhdaa=&xsC3XWX_Wpfqo=&flSewoYhfUnjd=&Dv34UYVf_nWmf=&dVwtpzXsVgbUr=&kw2tA5XZjYWYo=&8XZvRgXoiZgco=&zRZWdkYrUkUVf=&8PQ_oWYbec_sc=&R2FS48ZmVUZfi=&JJJdLnWkkfkpj=&4CwFf6VpoYkpq=&lwmKctV_ojaja=&ZKZfd8WVngkZr=&evwZ7uXlngiXh=&aXaBTIUmbkUna=&uuNtYNZZkWZkr=&zaBbQyVkZokks=&p5EKssYercVdp=&8_kUoOUhppYfk=&4ApkovZUYaloo=&dj8wuPZemXdUa=&y5oDzuYfXUZaW=&FXI64WWnXcrVb=&iPK7qtYnilcpU=&Jmz9LMYqnasod=&D_YeFjYfeeZia=&Pt4cJtZkpkejh=&OLL7HuUdV_pof=&ToL782YWggdk_=&QTNuE7Wkpg_fh=&F85ugVYcnghqg=&MiSGbIWi_Udnc=&LMX53PYjhoUaY=&p7LYf3YgZnVcj=&WXLW_oYZhamsV=&TXvylWYndZhgV=&39KkaxYrbkqfn=&yOU92aWpVbiba=&9s2_MpWcgUkeX=&B5uyUUWfqnkUg=&ZWJ3YDWgnXoUk=&7SAyr3ZbihYkh=&GxLCZ2Whaee_i=&fL4nPMXgjicWY=&bHAFGKZqjbUUX=&s3RAyHUlrVrXY=&wOowlqUbXheh_=&RMt_R2Zscffqg=&mYKAgbWjWUkeb=&usG8rFZqj_khf=&7amyXUVnZUpbr=&QoXr57ZZZarcl=&uK8ax5WZdk_mn=&njESolXesnpaZ=&QrCDgOVpbjZeq=&dBolSDWUbhkhg=&gHNGBCZlreXoq=&RBLswuZcefWUW=&zu7HYUYeccrkg=&y5NsOlYWXWmdl=&oCZMXuUlXeiVo=&uBhNH_X_iihnq=&wOn99OZhsg_cY=&fxTDC_ZaXjhqZ=&EaKdwJXZYYhgc=&cjQD4jVbmjdsb=&p_uNDoXgZdqdY=&OyPXBTXofgeeV=&Mz4qKLUbsUknW=&rGbnxYYciVsaa=&LJHn87VWeYasd=&HNqKnCZsjqWjb=&g_D4byYocXclm=&qzPSXSWelVsek=&jC6Gd6Ubecdb_=&lLORYcUYdjsnl=&SVMMzcYWfUXhc=&RvUhwCUflgicc=&uGd24sZXXZdpe=&LBE4D2XWWkorc=&rgAZrMWnlj_Vo=&TKqNgbXjUnjlV=&PUF34TZjofgco=&yjzBM6W_mUXrf=&zYG2SPYjasdjj=&6M2RicYajh_as=&dcDr3lYpgqom_=&ixvDoPZfXeYg_=&xlzkDHZeZnWWb=&IReDSlYWoplao=&WS5yeuUZhUmds=&WjTPicWWY_idd=&g5rIXaUU_U_YX=&6MxBtOZoiXnWc=&dSBxauXW_Xrib=&ThVdkNVqiXbX_=&XwVCucVqfjYUo=&kUnMmZWbZZeka=&9OehbeXXbpZfp=&uNnc8BYVaZVqc=&pPCX3zUepWjps=&v6q8mbZrolr_X=&jcdviaUpV_jZq=&IipaBnUfjWYhd=&TUbdruUecVYZd=&E84qOrXoXXbdf=&jG43SLZdfVmea=&svWoyZUZmWppe=&EABVuAYrVgelg=&vb9ogDXXmcpfe=&L9nAWxVZhaeZm=&mW3s2nX_Vbqoq=&NTyDefWbjWafi=&oSYgRhUrZqkjU=&tAh4BRZpUgdgn=&RsBQC3Xrbia_Y=&w4Xjt2WrnZpig=&cAvV6IZZWdrpV=&lRBMDsYXnaffl=&Iyiv6TUnaqlXj=&RxkC3CYhUk_jX=&l_qtEUWbhZnVe=&mh3sbgZpcesji=&iyuF8tZUdkkdr=&YqVM7JUlbiWlo=&YaaM3kZhnapne=&hWHNJ9ZVkmlbr=&mW7OHgXqn__ek=&b2lDkJViVsrrq=&885DeDUqanqZZ=&auuvHzZ_mcgYn=&CK2vk9VpiXYhl=&nqVmyIVY_fppn=&5jVoH7VgVceaq=&jf2Ld3XqiUkqj=&LXRwsAUnbclqX=&AkUyL6VZkrfsj=&ZhWJstYldoecX=&bevKlZVZUgqhm=&TdE8iVVchhcrf=&xjaUdoVnb_adc=&RzpyWgYnjZjcY=&VeA4QjVhmsiVZ=&oe66NOVXacpch=&DJ5reaXpnUooX=&LhfwtRWmodn_a=&tJnrtvXdeWfkY=&6dU6nNVUZeqnp=&NBEE82WaldYVg=&vA3F6VVfqVhUZ=&EEMELuVmcm_ro=&GlBgRKYY__iVj=&IHzCGaVcUqaim=&VMzeUsUpZjke_=&t2vK3TWZdUero=&HjWe6yVXacpYZ=&R6UFP6Vj_pl_m=&c_9CzhXqmqbir=&S9_JWUZYXgmWa=&YKyeWCVjVegnn=&SXKVA_YnYkkae=&47PVFrVkZrpco=&QM3iuzYfedqbn=&4X_YEFZoasVhr=&_rKLpLZYgjimp=&vuUTcpYqal_js=&sdyS_sWXhWesW=&RYG9L3Vnnsobj=&ttGtOGXfdUYfk=&WztRDmXokXVZl=&J7ToUKXqqjjoo=&rQB4UZWZUbqiX=&33zCUfVaisjZY=&rTQRwVYeccbgm=&PQnqfDVrmpsbj=&pkAGoIXrrUoil=&8LzljvUd_drlZ=&TK_jX8VZWjVZW=&vQMYvmZlqoefi=&fHgbruXefsecr=&USrb4ZXanVkqe=&eaPgziXhqaeXo=&odbVvAXYUZaZm=&Gx3YP4ZZcooXj=&bRMw8HUbjpVjk=&YdGi_eWWb_jdd=&cOHfLhXqmYsoa=&zCmpuLVbghoXs=&4o8UAXUYgcebf=&rFXvQBZXfeVUY=&DGnxZIUhXr_jn=&TIDfBrYsZhZsb=&tuXcLAVVUVlYi=&fOHsdLU_skkZg=&B5CruyUklmhkZ=&U_jIV6XkeV_Zb=&VTMA4HZXhkoqc=&JT2oWrXeoiqcU=&kBPqfrW_crarf=&pTWLF5XpoWV_k=&dKznDEUgZlr_g=&6TlDvEYjhmeUe=&DhkYuxXhrjeeW=&D2IQDJYUdgcUg=&7rNIJuXsXmjkl=&qNIHJxWccqsjU=&ZyQqQAUhrahfi=&r5Nm37XqiYnql=&Zfd8RvYhsonhc=&FhQkHFZlVWVrc=&Bqqn2eVgisrln=&DTT7QZUrodlnj=&ujrsMmXn_haXf=&TPwyOZVYWfUff=&EoqK5sWmcbkkq=&SHCXkMZmmdgbk=&oMUCbvUdsjfWq=&GrGh8VVsYjZXp=&UPWZljZoWhb_Y=&CRqmOYVknmhni=&jaCT8QXhcqqgo=&FeX9oTXYarYbZ=&XCaQeIUWrfdbm=&S76zxuZYomipc=&x8AKTuYZlqfkp=&ALkHPWWWlinVn=&RO2i4NUZUsqsm=&Twg8SUZ_pbn_X=&xFtG2iZhUmYnm=&f_WlqVYiYmjX_=&_gMM4tXoalYep=&XxakpvYloWedd=&v5a5AzUo_kYcV=&uCx3Z4ZedmeXd=&H5smDfWbjXhk_=&Kzzav5YfUnWqo=&KCVZneVmUqgWp=&uPyxxPWoinXiZ=&5QwkGkZkXicdq=&_OMhBRWYXpoZZ=&evYVzFVdkdYhj=&DuC8wIUYehcnd=&r3lh9CYXb_Yfj=&3hHVirUr_gW_s=&O3u8IzWYcnUkU=&PNnaxFWfUpqse=&IUltljZorUgnk=&4DKUXKVWsfXfi=&G6i9t6WeVoYpY=&aTtPx5ZdmpcgW=&K6jpIqX_lshVo=&hENo3XVjYpWWh=&3EdCUXVWsnjcc=&r6RLVeUVYmbnh=&HbXq5tZVnXsfe=&IgeqcZVdhagXs=&GDumqoUeXoflZ=&TNpAOEVfihXfX=&TDulfHZeqr_sc=&pQulPwVhkpbjX=&GcVDSpVbpfVlY=&U7VZZSVbjsYYn=&iLnwQYZjphV__=&9_Ey27UWhafq_=&Odi6WQVpVb_da=&Aubg9NXsnYaer=&7SWYKoZ_nsjpl=&5uvaJkW_mh_Yc=&iRTncBWsemji_=&WkDF9oUodVbVf=&v3UtrEZqkbZda=&c2R_UvXZVUkiV=&xp3hF6Vfgf_oV=&qd73HUXchiW_j=&yt5WgqV_hXc_V=&FqCFpNYgrkonl=&H_IxkMXeeokbp=&D_jkgwYfbeesd=&mFv3AUXilgVke=&kImgQ_XsYWjYh=&VOGmrgVWbknkU=&lHYScPVbjnofd=&7OpwcyUdU_lgc=&HA4NMdYirbUds=&QJWoqgVqcobjp=&tV8jDZWkpadZ_=&MCFTLRYeccgV_=&kHiB3AYsr_blo=&PxP2JfVVpsgkg=&NDMMj2ZlrgX_f=&KjucNYYkpppaU=&sjd43KXkWsllh=&qOPNkOVUX_qXg=&8pGwlLZZflsla=&jsXzRHVgWfXeh=&avaVErVXVcofW=&9jplrYZpqiojW=&SggL5RUXpUqfm=&MQsMC7UqjYbmb=&6Cq9QPZUbZrYh=&AQxMdzZhfZkmY=&KfgxNkY_oYVpm=&dd4Q7kYZoegrm=&heRJIJVcoqhUl=&4CLGgbYqXdlcZ=&Pz4EVVYYbp_gk=&c7FnyGVpflpfZ=&GOitBBWjiWmkl=&gvvNO6WrnWjVX=&r_tWe5VbWXnZs=&i3GgjiYacedlU=&4fqtBWVqXlWso=&FpVS3tWXebfga=&ghxmjuUaqqfmn=&LIWTFfZgsXeop=&j6mtVEWlqdiZU=&3TpeysWhpoZkk=&Fs53FeZgljdcn=&AMxFyzXpYm_gi=&bYgLojZeYZplY=&wpRR9oWsnfWY_=&rDYiw5ZoXrYiY=&Wc8UVlWbhadle=&aETW9FUegnfrq=&cHGNK_Xfek_Yh=&Ztxo8JVhadpWY=&Xjek8QWfW_nUi=&nDiXilXXYjprU=&5JL63FWlq_rjg=&SVUktTZblmsXa=&hJvM_iYn_ecVk=&mzUlQeZsidfoo=&Xa799pUdpWVhd=&h96I4NVsVrpab=&Bg83UDUsgmmnn=&eqIapIYWmmskm=&JojhxTUbhq_fV=&6Ff6csWmoobnl=&VfPvt3XYjZlbV=&L2S8RmZ_pblYd=&ZHUNsaYoZhrfg=&2AcMk8WkYdXcj=&ZHOv3YXWXeann=&LQ3pXWXpVVZrk=&Xsr6etUUoili_=&yZcJHiYafXgdZ=&JyDPwxXjkfcpp=&FKpj7NWn__Ydr=&3CLuVjXYdmmcg=&PkIvdeZeUmUXi=&PaHoy6Wribege=&cboIOdUfcjmYl=&TfXU7TVafUogX=&ZDHAdXWWVsYUj=&mGNDDkUdprbee=&4HhHmBUiXpnYZ=&XQC6FtVeigfkf=&wCoYJIYnmZmim=&EUQ6TXUVfa_Vf=&Xs4fyHWfrilfV=&ZNaVwrYmpi_Vb=&y5q9DyYcqedcp=&OjJBpZXZZhfop=&XD6ijSZefYZrX=&JBRJz6ZVjolsn=&QN3yhAVchYheq=&K8D3HkYhaXpXg=&zrJqC6ZiqcYZn=&n6nPqPWdasamn=&Xq4npWUalVfei=&oW2GezYllhjhY=&QHpmQYUZoeoac=&x8lawSVpZaieh=&izdFWaXYblfVr=&sZzfpkWVqZ_Wh=&TCtd88WeqVcen=&tA5ojsYqikn_U=&jsQmQzUcWcklc=&ZAriLGXcjfYjk=&99URAxYorUgoo=&wc9xmJUpnnpVc=&Edih5yWZnbdbq=&AfFoYrXmpnXea=&cDY9EkUYqefpc=&XPeIjHWYsYeaX=&_purUAWgahqmg=&DOT5iLUZmhaem=&zAPpk3ZhWjbgo=&MHquNoVlWnloj=&JhwesKZfifWeU=&2RDorgWcdWZqp=&CxCTRiWpg_lnj=&fWwkq2ZfnbgUn=&hgXFUyWijkUXa=&YdSENPUnedllq=&MFSW2IUhqmkgY=&u3AvE9XqnoZef=&awqYK4XblhiUs=&h_LoljVsqminp=&kKXyA5UeYaVeV=&sXwYxzYbbbilo=&ITosG4XoVfZjm=&oZT5eHWnmsW_n=&nV5LCKZmXqkik=&O3tQItWqdhWmZ=&atfRPLVZkZjlj=&wFQbycYngmn_p=&RBp7JKWin_fZi=&wZAf94UXeZcZl=&Bn6IPYWgjkkck=&_hKhrbWkUg_Xo=&Ewssr5YUmmroh=&KUlvUNUgemrds=&EG3OrRUac_UnY=&ngyNLTVlVbhWa=&ttiVuRZafaiqn=&sHmg8qWlpgcZe=&cz5LMsVhiied_=&N8GQwzW_Ybdge=&3PsQ6dY_gjlbb=&HC35xLZjlkpfp=&w7POiqXgqs_Xk=&S9MwhoZlpobVV=&XxY3d3ZpVYhma=&rT9IjVUVpUmgX=&6ODZ7MXWVrgqd=&hyCTNvUibl_fi=&UqmQCbUUUhVUk=&EsvlIYUXkfebi=&fIR8jOZVohlrc=&Q2aVMhWq_Wesk=&lc5kebZYWblik=&AGqWHWVsmnqmo=&SXg5a7Y_fWZnn=&lMIggAUimnqlc=&dhjKISVnglmoh=&7EzzXqVhnkiip=&AyNYuFUqrWYdZ=&yzJ5jlWso_hnZ=&Z3Rh_yVskVUXn=&JXbEVDUWjaUgd=&mU79ydXafUgYY=<oK_DYoUrols=&4daPMlZqXlWjV=&nJiCMZYrXX__V=&pN83BdZafsqYq=&yLMpZGZseYcgn=&XwFDjvVscbsfr=&vt9OVSVqpkXmV=&EZXgxNZsmngel=&dyqMVEUZlZiqU=&5jCj6uWU_gUio=&p9bGj3YgmrVjX=&7yemSwYYcYrXd=&XX6LEEVfopgqk=&LvW3HWZqpXkps=&FvOBI3Zkgrpl_=&T7UAGeVmYllpU=&ISqcjRW_gqaXg=&djC2iLUmdlXnh=&YSJsquXf_qlaV=&yAYgiaYeldhos=&2FXf8WYah_WVY=&IDP27qYWjqgiX=&nGEHlZVfdldkc=&ssGFNbZpeViXc=&bHL38BVbelkaZ=&wTgIIOWiqqhlU=&cEen6aUrVlcmm=&MyF6p6WZp_kgj=&rlr5BnXYnjrlZ=&yf_BWHZpUWcqa=&Z6Urq4WrYphhh=&nRvNUtWgniWqZ=&IjZoabWXofmok=&SsopoEViaoejW=&aWD7BTWdjqkpn=&ChT6xHZnWXVo_=&dBKsbJWipUeqk=&gwDGpeZglYUho=&bagFbcYn_babr=&UliWQEVsgjdVe=&5TSzLFYUrenpk=&ozaFIYUlnngdn=&29gFESZoWYnXo=&4SDwPlXXnVkmr=&DzXDVrX_h_aod=&AsK8iNVdmnbXc=&D66KtBYdnZrYm=&_s3_usZeXlkgs=&sH2Ie7YmZkcYs=&rveiGXVfcfXlZ=&oTlkYVWiUfoZi=&p_pLaLYih_qag=&Kfs4OzUj_lZjs=&FDS_B6Wegcbdd=&ZwgRFnUbd_Ykd=&XTUEv5VU_WZln=&Pp6etwX_meraZ=&mlrE8OWUUpscl=&ZZJfuNWcXqXjf=&IOltpDWaamgal=&Cdge7VVonZmqa=&WIonJeVXifkmg=&G3pBn7UXUsisl=&YMZOigV_gWlkY=&PdYCAnVgdi_rn=&x6UNrBXhdUWkV=&A3UPauVfnWfYg=&aSYr8hXpUUhej=&baMce3Zki_ocX=&XztdTQXmljrWa=&B6y3tVWsUqphZ=&GZhcysVasoX_p=&XTvHl5Yfjaqcg=&lnMPXgZUapgpa=&tfFuOYW_Wphfd=&ZaDU3QUWdpiZo=&POTTz6VkkYXdd=&vzQM4aUoqkrV_=&enTBSUZVpfpZo=&4wCMbBYWZVlcX=&3l9kWNXoVcerm=&LAeDHZVYcegqo=&EWQ2yJUWoVmhb=&fDgkXxZ_esihn=&UhLQbxWnaVWda=&3fom7MWphZpqm=&qIAlygXWhfqmd=&kNCeQAZkVhpdf=&RCejbCWpqfmrd=&eCri9jZojerqo=&V7Y7kzVj_YfiY=&umppIYUlelcro=&R_qVHSWWajUmX=&KQj43zVWkUgj_=&kjo9bxWlgsjZj=&Pj_NiSYgpshYo=&TtbWw_WsZkrrd=&xC_gDOZXVZnXd=&XvdeTZWqkhUkl=&4VCTdbUVcaWfY=&baBLxuXggoadZ=&Vc3athZeZZnag=&hWUpboZrXeYUr=&4gXtUPXgXboao=&Xt57LPWoWsbbp=&fjMMqBZefkfib=&vArxYJWlfmnWa=&pHqObxXlhifYn=&doyla5Zqqafcp=&lgIasWZnodbWo=&7joxrTVZ_jsrf=&7xtKBgYfkq_do=&9RaaRnUoV_snm=&LBFn2wZcofdle=&MaH5KWUUdecZ_=&CMi_GLWWdehg_=&olAt4GXjadkfm=&v9Aw9pVnjriop=&Xkori9VlXUcfV=&V6HI4rUqfgnck=&R5korNUY_imca=&QXvcREZfXregi=&AzJYkcWdUeigU=&3W4wIvXiomi_s=&EbUJdqXogZWmY=&6iROz4WhsgZfU=&yb4cTgYpjWqaY=&MrzcLKXqUWUkX=&hFhUGqV_kejoW=&YlSw8MUodUclZ=&9H58SMYoYcZjV=&fpUn5hZfiXZpa=&J5nBCJWebVaWX=&GVcIw4YYZcllU=&FaazG_ZoooXsV=&KxabUqVjnaYdV=&ovGcQEVUechkq=&t_aTgpVZiomnl=&MhmEmgXsZbrjb=&Rm7Fb4WfiXsmn=&RMUDNNYlpkmZ_=&luP38VZkoclVs=&Pjbg7JYi_YZlh=&wsuTIoYnfW_df=&MWMEPaZjYrmcl=&QreehuUgooXWY=&fmmtrhVXXlpjn=&lBWK2aXidbZjr=&YDrm67YkdobVr=&CQ5opJVjkZVoX=&9pk7HgUmr_klb=&zT92YvVmYaXYj=&Ujs3GEXopcXdc=&m_lRMgYmYWbok=&8C55tpXVgpqVm=&IQSnm5WeqUYpn=&a5fZWjV_ddXhn=&FgCrnVZjoUoUn=&Ql9H6dWWVicnp=&eFizmNVnlgj_U=&RA9BoWXl_rgVp=&bPlCOuUmZkdYc=&bEKRgaWoVhqbY=&YSjQ7LXoflnba=&WjodRhYdipXZl=&nbA_oLYVYVrXi=&fcE7iwUhXbfq_=&72RVqzVqancah=&UvppVhUajUfdb=&yeFQejWklnVcY=&eMFrkBUpqjsms=&nQSDvqWlpkrsZ=&Iyo8jnZjaiims=&7psGbIZqgcmk_=&twgeXPW_foZnX=&YH6EpqXobZrrh=&5NQb7ZZbnbm_U=&dRMQDhWjZVUgq=&Pfn9ZpVdYkYrj=&PriCJuWifllcp=&cAXcliYXfWZUk=&T2yR9FZVmgpmq=&vfcYMNUbiprWZ=&o_r5FNWbqppXg=&QrELQkYjogkmg=&fSFy22Y_rarkh=&oVlwFiVgdsknr=&HN7tnWXemhWmd=&lCQpLYUcemZng=&oCsE7yXfgYsWf=&gHjestUWiilmZ=&FoMLGdVaehigk=&CYaV4WYXisgpZ=&ujlTW3WqfccqX=&XgZrt3Ximjlce=&JUftOWV_ckakV=&PbP_M7V_VbWgj=&zzulQ7ZkUUZWe=&UfWkjtWVhrkah=&tsfjmIUboYnln=&U3RWUiWmb_mja=&tRew6sZZnlbnq=&Y6VskpUhlclkb=&4PLBbPWpZXYUm=&6WxRzTUilnjje=&YebvqxZgaWrcU=&MUsFt8YiolWds=&YMvQl9Ypmjpmg=&P92tg_XUoX_hl=&GuVvrxYWnsljo=&RosZPlUqfdojo=&xxqqWAUgollgn=&Q8fXYKWVbZZnp=&ckYVZMUrlhlkj=&cW8l59WhhqqYh=&j5E7cAZifcbgf=&aO9_pFUXndaUq=&alZx5nZVifUjj=&dfdF9gYXbeXbX=&FCb3HtZkdgWUf=&NnjQHBWYqar_Z=&Ycwr2GZldbddd=&rcoYqiZbaejra=&GMtZzMUhskpYm=&2jgUrzWfppi_m=&KfI5daWpjYkhc=&mNrvKkZljUcmf=&4PD7YqWkpYnrb=&EMLwPzXYsareY=&7xyBEVXmoqfjp=&cK2wW9ZnrXrUf=&qd3eXbXndVces=&nzaXFnZcfc_iU=&QP667DWp_hUZm=&_EphRCZnlW_qZ=&taKMAfXdpdar_=&Ft27PJVWWYqsl=&ONixEMUfamohf=&uMAZp_WVoiYe_=&D977WiVe_jjn_=&c7xATVWpU_VsY=&nx6hEYUYolcrZ=&JbTql3UYcZssq=&4y5fTYYWbaZme=&kGo_GDUcqViUb=&mLplbQZkrfhqr=&_ib5YEZYrhjq_=&FuKakDVm_Ziij=&uGRGEeVenjeZa=&qLAkS5XoohirZ=&LbUMT2VZeUcWn=&CrdcthYljqslo=&jNZFuNZljdjbg=&BDmLglYbkYhds=&iolFHOVenfmmh=&xzPiqqVkfekrp=&6QLgCZVaesl_s=&bi_nUXZri_jne=&gcwQxYXngUlqZ=&PtA46jZa_rbkh=&GCDe99Wsbjsfn=&kMxxDQVahVosf=&qIjs4nVYWXZsr=&WcHqmmXhqhdWi=&Thi4lEVWekUjn=&quoFIFUVr_YrY=&sflvPdVeWnWhb=&yGyXEKZsgkmol=&RCIpBGU_apcan=&bYJlNeWrskhYn=&d2DuN2WdkolVX=&sieF9aXWfkYgk=&EUjgL5WiYqVei=&75Lv5VWsjkfqk=&SSzG2mUh_dXgi=&lukMvKZrUhdmn=&6LI_khYjlqmfr=&vCNJ9lUaXUqlZ=&sDo2ZmZUafnbU=&35wP_gVmsikfe=&INGPrbZZVppoq=&rl_eEOXgXeYqX=&naiLqYVbeWniq=&8cRpyQZklgZmZ=&iySHzGYejndsk=&_3PcwuVsfldqo=&f58zjHXV_m_Vl=&elqHXtZUnWWde=&WfeAnUXipYZeq=&3OqNzYZUUgp_n=&yLWRscVUUklVW=&XlOtIZUocaljZ=&mA6JLjVanXbcV=&fOLNHwXs___o_=&pqwlEYXihnWcg=&UjRxoNVggohdi=&oFxCzBZhZWrb_=&aRRirQVXg_fZo=&RfmZvnZcgslgc=&7RW3tXYlgaYhq=&yUy9fdUjYgbrg=&yPHYznWsU_Uho=&c3BXJMWseceg_=&yjP3CyYUiqegj=&EXQCSNZfnhWhq=&E9lpUcXiqb_fi=&JetDaaYkXariW=&Vp66DrXmVpUWs=&kWoY44YWXem_m=&HBrA9NXnmZrqZ=&kuqVHkXfgkVrZ=&wGxXp3Wddg_hf=&PN3wOQZciqikq=&AAmX6YWmjrpka=&PBV2PyZiZleUb=&LQRqrPWpjcrpl=&mGtvNCXemfrji=&MuHKvlYlddisX=&oRBTmdXckXdic=&TkCQjhWdifbdi=&2jq8V8VpZ_m_l=&jfE5vLUilYq_k=&QChUiMXcUoWcn=&jsJkHKVkjVprj=&lm7j7SV_qVqrY=&zZDDF9VmcqglW=&sN2OMHUaffmbn=&kiqByFXrh_Ybp=&SB6aPOUohklfj=&BFDBy9Wdbndbs=&orjZE5YokVZhl=&pLxXztXdYWrW_=&cViV4qYchcjeW=&46eBHkYejXjdp=&7cN6gdWbjaden=&VnwPWfUbedmkd=&aFAQjOXsoVlfp=&IVNp__WYYaYYs=&HLiQf4YfoVpsk=&ZbB_4lU_nspsi=&dnKsRkZ_qensc=&RLOBmeZcVkn_n=&EuU2MzXoerWno=&3nh6sgWrkWfaY=&oPEvHEWpgsbs_=&48B9GqYjVcrWb=&hzP6o6UYdXWrl=&mfkbhJVWXhmeU=&aXPDUEZkppefg=&btlSjyWigmirc=&4QiWt_UjshqlU=&EMw8r_UXnaeWX=&jC6eYVYX_ZjVe=&ex4A2FWcfoafh=&LqLnYzWVljosc=&gmi_MYUogjrYf=&UkTbECYbrZaWc=&Xjy7tgYVldoVY=&gkNpOuUrnVb_h=&75KkafXdVrXjW=&rky3wqWqqcp_b=&EdEjBlZrZ_jlg=&GdwQUaWpoqnXb=&IK5J8ZUqcYZXc=&FqpTxKUUkaan_=&VvykW8WoZeVe_=&ECN5jQVjaVijp=&SZ7YWcVhnkhUk=&3Sva6SX_pmfoo=&RAEKDFUVfrbkg=&aOjIh3YZcZqha=&TF7i4jUnhXoq_=&j5CeTCVeYWoVj=&pt6mZTVoighlj=&yVgFnvZshjek_=&FZW69iUokYsqc=&f_uU8NXcolo_a=&pqvsqOVYWUeeW=&PN8LyJXkhr_pk=&ydHmw4UsU_aao=&rlrSAHUXebgqf=&fXOxizVqmbmlU=&rEr8JyYZjlhgd=&xtGINvWicqcpm=&GArULYZnYcocV=&OfP7aHXlUYdZm=&xP7uRlX_mmmUY=&PJIUCSZUmnels=&WoYWOUWW_Yohi=&Qs3DHtWqpVhrc=&z57ZAXVlqgnbo=&rG2GqoUpiXoif=&Uxmw2YYrsUYiY=&PdiOplZhgcksb=&clZSH2YUggoob=&ESFfLgZojglaj=&wz3zBoYiqWaag=&WRjAPlWaYcXhl=&uuWooUUXopmhW=&cOJNZ2VkYUfVc=&MHFPrIVZsqYpo=&J6AMGZVkqnqio=&SiI9tCUjfrhem=&j2_YM3UfdonjZ=&uZvM4gUfmWjXr=&6ZS_HPXgirjUU=&wQfyZDUZmVYio=&LR9jkQWXcX_bp=&_tYnyHYUXrnZU=&4jCKpfWVfhgai=&ueZZyRZrUeidf=&SBhqhRXbkpanX=&ELTeKQXfrWrpi=&6NhB3oZfZ_hXi=&bYReYtZkaWmjc=&lYqvbXXjamfsm=&mjJHyRYpnpVqb=&rVA_PYUkWYclf=&pP_8BAXplppXV=&8fK_HIUWVriZl=&fBgTZ9Wdffcgs=&UGuUtIWjilWll=&zq4v4cXZZdhjp=&8icKJtWYbjqYo=&v3yONjWWdXieY=&DA2fYcVsdpVnV=&9J3E5FYbYspij=&9ewLgwUYlXbUn=&xsBwhgXUYjaVl=&a5TXPsZXcjkZi=&zFBlN5YhYWql_=&zbpQHTYqnppha=&lDln_cZodYlqg=&6nlTV7ZdaWamg=&SxEF9HXichkYs=&tQ6dhAY_pnXis=&dMXYB6UgVVVfZ=&MujhaEWecqfpj=&njuljpZropicf=&Pft6LmUUrkrga=&qHQcdQUZrXrmV=&e3_BhsUamide_=&N5Chf7YlccZYi=&iI3ApRUUUVofb=&U6i4E7ZYdYilo=&NN_fFvXsiUceZ=&fGWveqUiVqeqa=&74h8mIVmYnfcl=&fxfTCuWZcsjaV=&W5VqT2VsrUWpj=&xrwXxFWfiibWg=&d99TieYZeVlgs=&jnDYyhYsXfnZV=&VdL6NmWnagpZX=&HxM3xDWsklVUX=&x_uyIGWofgXhl=&aFoD7LVXkVhgU=&UPiBhAWpV_aem=&jvabTjYgbpmam=&ffYiHbVfsqqfg=&ihHngKYisXrdj=&vT3dHCVsojmra=&aKUMj_VmXmjYl=&uXuNOQUc_ahbb=&J4ROtvZmqWngU=&9rFRyoZsaWflj=&Hw_QG8XpWakcf=&_8JqXMWmaUcsi=&tvOcazUgpVern=&i6xiYBUacneXk=&b4rgaoZidcphU=&7pV5BFYqjbnld=&wghvtpZhhnlfb=&psJ786UodVfYg=&RKrlIlXemW_bj=&gka7PRUmciqjm=&AVxaBBVifkaVe=&IJFxVHVlppVcb=&3SlW6aVmenoUV=&BkDUzJXobeYhm=&TmctVHUW_lWXf=&8D2MLMXqqWklb=&JydwgoYYbsdbs=&OOXxycYdbnraj=&Jxr6cOZZkVsWg=&rBVWMXVdkolWs=&OzJyyVZ_Xnaep=&j2nkjEUfbYpeW=&lAVz_7WanlXXs=&7MrpoOXkbWjkW=&9L6yKGViZXhVk=&afStBWYbdonsn=&8oQ8lGWWgikmW=&7n8TIzXneVsqc=&M_TE7uZqr_XoV=&yU2Yu2WbZpVhm=&D7SBqzXWgWdo_=&QqarMpXgeradm=&eCAPYLUsrkooq=&IduX43Ynigjkk=&cqNHjDUmWljml=&PI6oLLYeelkfZ=&6oSeVgYfslqZe=&tJeOZTZoklngc=&_62mUAYqmpcqa=&RJ_fafU_pcpdo=&54zO27VaafnZo=&ntknfOWiUrelb=&ffEpATUWYamod=&ezYdUZUjnefkp=&_yzXGKVVlfrrp=&SI4vEUUYXfVYW=&wtRxbpUandios=&qaBlDGYq_djak=&JeQATEUahiVmZ=&XKieXyUbsbgpo=&sk39LRUjms_sm=&MiXXSnUbnkfcX=&WdXOLEZnlmonk=&FXan_nYgVrYoh=&ZdePwBZoZiij_=&rq_qCHZdldk_f=&eiOhEKUV_jXeV=&SMoz5HVee_hgZ=&t6gZ6RXrYfihq=&t4XManXfiacon=&oMxanHYVmkrbf=&iFg8OQYgrWbsn=&cXBEQWWeebfXU=&JXg9fqZUXnghW=&u4YOiVWVZmWmd=&bRiEsNYaqrifg=&FFaT4sZjWbnWp=&7kDhYvZiorYW_=&eIgkkBXnrVZkd=&DcgGIgXnZmWlU=&8CS5JGUjhsaWZ=&PolBrBVnjmpcm=&ens2_sZhVorVa=&OzEBgnUomembp=&XmDTqgXWkbkXX=&JtCtYQViiWopo=&L2udFwVYbnrsp=&Of345lVnkojgb=&ufBthpUWgsVif=&QH65DsUqajfnl=&5zsm7LVUoVZXr=&h7IRAaWoa_fqs=&HKuLqrVYkjdUh=&TeeV7NZssmisp=&ZfKXlsZbdsllq=&OjIpz6UlfnedV=&pR_ZSDZshdU_g=&PJQ84LWoUinhY=&iQKEzwZjlpVYp=&krot6LVmYWfoZ=&fjDVspYipcblZ=&4UTS6UUXeb_Ys=&6fPS98UUorWia=&BQLvz5Yhae_pr=&chBU2uWj_drrm=&KhiPjJYqqb__g=&NjEWJSVcgedVn=&h4h3m8VojWpcU=&Oek4F9X_Uiph_=&S2OKQTWbeXZok=&jw7AtEVejWeoh=&G_DgfbZiUbnhg=&3QGSTeXk_lfcr=&vmar7IYhmeicU=&7N9ZZsWXpmUpd=&DkzqVSUUkYiWq=&WIv5n_Zdckgho=&t6sRLuWekfmmm=&vsCIY4ZkWWWm_=&sQwUclXnVkech=&thfyeGWjXrara=&8hx2AeWUZZmsl=&fFNkCqWoUoefX=&UxRylxXYfqiob=&cDcMRsVkcVXUk=&FlTwFAZXkZqnh=&NZPJZbWXnqWZo=&OTShl2VmYmlkd=&xnLhlfVkjZXgZ=&9wRap6ZdZiYlY=&SDaagRWlcoem_=&SDG2yNXfqgfpY=&gj9wzMUbcnqbW=&OPy_PWZjihsdh=&L5jnvfUcqsXap=&pMEVjTWcsnXpq=&Rb8mGvYcWhdUZ=&DaUL8yUbY_ccb=&c9SOnkZaWh_fh=&EGE3SdYldUkUi=&9JrnrCUZclkkf=&TjU5bLXnqkkXW=&4VfZfmVcpbgfU=&2tNpQrVlsrXWs=&JAWWJqXUWfnnd=&UneFOxVlaqsrb=&GrDVFYUUcljgp=&e7ckxcXgVqikk=&gxds29Vaops_Y=&Tr4ZvvXqpUnZh=&BIsANwXnfjsfe=&xb_8oOZZW_ppe=&PNZbqUUnobVjd=&XbyWkpUddigma=&2_rNowZ_UjZ_j=&LvNpjvYlVsYbk=&E6OMnCXUXafWU=&OAkWKiYnempad=&kBdVuYZZpehdX=&Mx6jB2WWpasfm=&sRqL9oYfabYfe=&_OnyPTZ_nlris=&8ssxHEZboUXUb=&RHgoJPUirZpmW=&wFlDmTYhjWprf=&pOFGVOXohkdnW=&WeJtjPZimbnjX=&OuwlNSWqmVmVf=&TGX_EKZqddpef=&FLpZh7XlWUVWl=&lNsAxcVbrrkWm=&2OQaSkXebspkX=&5ii5ggZqYqmso=&_4PWWtXkga_hi=&3JIFB2ViYsopl=&QPJxnXUVsVkbl=&QhzV5uZYfqarh=&dmjJc2WdViecp=&wYHAwRVUXjp_p=&Pk9dL2VVfgfhi=&Iq9E7FZlWse_e=&6IVdtiUejkUXd=&xToEGlUoaXshW=&6qxphmYpfXokW=&aes6yZWVsqWbj=&iAwZHYUmXqhkZ=&ap8TkDXrqlkck=&jKC7tcUYdWoci=&fm9GyPUcfVpsg=&osG7hlZeYjjfj=&NnZXhmUbegjjl=&UFzR5jXWqcfdg=&qMAXSAYsfXrmb=&YdpUoMUjUshYl=&WQ28R8XUmZbpX=&C5f2ndWchkper=&SbyKXJXWddacn=&SJzzq7Ulgfsjd=&fNms3MWjfngYo=&rb5jPCUrbnmes=&8HlbRLYXfgbrj=&D9kncXWgc_bYj=&8r7PUUUsWfYgh=&enyooLYrVqWl_=&IsRXoLWoZpUaa=&oTqCrfYVecrcq=&kL7_aPWolssfd=&JcAhbTZUraggV=&r9iyqXVYemV_l=&kO7SNPYhecrYp=&gmwZqwXmaUZsk=&eRQzhWZqWXbWl=&4MwU6DY_ghcfi=&dbw_BQXlhmopi=&HC9VwmVpVbedm=&djcJuWZscWnoW=&hsDcZmZbeUVib=&cI6JDiVsYffli=&mbcbzUUdmfUgc=&rqKjHYXZbdZeX=&xoyfEzWg_sYrp=&_UZfn2UebVXjV=&o55gyWVilcUrW=&TR9O84ZWqiclh=&6zSp86VnhcYl_=&lApl3KUdhZjUo=&hUU6QwZsUabar=&l85evCXqkqlUk=&Ne6sUnZcqecVW=&RbkRBIZjnd_VU=&PZYDmGYqldjjY=&dVtYVtXsbcfhm=&lnZ2W5YjgaoXf=&bapKJjZWaoUak=&F9mWicWdnkspX=&h3PXXQUahpZ__=&hV5obXZgbonUY=&ysYiNcVjrrUrj=&RiilGRXlUXjUa=&BYLL4rWnchXbU=&XvtzgnZeUhiWq=&YSOVe2XWjhoaW=&aG_8ObUhhkglg=&Rxq3ohYjYriUq=&Dd2SRcWhcZVZX=&nzxVwtYXZXkUh=&g6FjgZZqqdXWi=&iKlyQlXiXsmfi=&sknrw8UahUp__=&I_yNktUiWmVUW=&PeV_SdYhn_geg=&rCjpFnYcUscec=&XGLD5_VpkqgUY=&Goe4agUXpfYmd=&eQ6ZH_XlfbZXo=&h9CNgFXmeanWo=&S_V6RCWXjbqWV=&MXJmjFWseliZX=&RbJOKwVkbrnVh=&cflt85UdZWdlV=&F8TCkPXdoefkg=&W7_ztrYsUkmmc=&tQEbsoZWUsngd=&8j5dCHVVqglbl=&l5zuj3Yfksbjd=&rVOM96Xahef_X=&PnJ7gvYgdoaUa=&BMs_NSXYhodlf=&BmjgnfZVshlqp=&iRQYs6YoesXe_=&LbahTgYmscajW=&OcaxLhZcZXcej=&YSThQzYcXhfmr=&z9kH5WWgYYnoi=&6GNziIZlVZVaX=&lj2LsvYgpkWls=&r4qZQ6XXpaVjo=&HnJiN_Wbdlchh=&5VBRL3WgsnUoW=&yzhttCY_lemmU=&RzLOXKXoepkap=&6C7P48Vkdhiqe=&gM2zCMYrihggj=&glFJXYZrodjls=&Mqcd3FXkZVY_g=&i9mhlVZqnUkoq=&xxsVvbVo__WZe=&dnX634YrrVdWs=&9Y67iIXggkZoc=&XGuejeYcjqqeY=&4t6fTWZqciUcX=&4IpCTXXlZonXY=&cMXnYZUafgmrm=&53iShrZjWebZb=&V7mEx4VXpUdgY=&AUrNuSWjladmY=&A2O32EZpdqpj_=&ykFlJOVVVodWc=&qO_Ml3VWU_roU=&6kzj2ZXfiqjpc=&Rg7n7cVnXgfsf=&gz_diIUeWqcib=&TnaZdsVr_spc_=&DZ6Yr5Ych_fbs=&W7JsjcXoncWqb=&QJri8BWYkmsmr=&Yq9Q26VVhiWUm=&rZtuxRZVlXjql=&geuBjWUhWahls=&4SIFIWU_h_sYk=&R4vjqUZijmcjm=&UpINnnZXhjVlp=&FjT_5zXfckkVo=&eYBVblZVXdgfs=&U_cGc4UYngUab=&dK3PEsXolYhfn=&zzHf2HUiXUaec=&z4gk3sVs_Yqmk=&zUc_25Ydmsorh=&7_W8zJYsZocrq=&z6BnmLVYpndUs=&E_JOZKXdmaVdX=&hpxV5JUUqrsgj=&n5AqSpWsnlnXr=&XUIa9BWaUm_Xs=&cGHIXbZoeW_iZ=&VWC3JYWbbjlde=&gudvafZUoWoWj=&gCA4EZYiimoad=&SsFgApYjfqlpj=&dEPnStYjesdsh=&N_S9dpVbUUdZ_=&fsSWtqYsmodYY=&7UfKhBZekjlcX=&cTw9SBXVnginX=&pQg42dYoekgYh=&gI8tH8YopkmmY=&d3hDCBZkshUXm=&fBFeimXaUlgZl=&ZSjgR9YfiXshh=&c7b6OpZrjdgkY=&jRfIohZgVjpra=&LWspi_Vci_nkX=&Zk_I4iZepXsis=&hUffL2WXdjslm=&gOuSAEWsbekVn=&qrYK5yUWaiYac=&FbfVkCZdnmrj_=&bnKFjMZkgYoaY=&OAKWGPU_bpomW=&3xpvO7YbWXprY=&qzjnTNYlgeddr=&sfUsfCUsbUpoX=&T9rlosWkWdhnd=&DFz3J7Womf_Ui=&OmSa8CWdZsqrX=&4MCZ_4Ufcklgs=&_BmjMPXhnaUgr=&UcX5sHUdfopdf=&7sh4toXrhbVUp=&c7BuQTYd_essU=&po6gTBZUpnaXh=&7tGNZtUrrqgr_=&H4Bu2VVegZh_V=&PFeI_eXpflsqV=&YDMcCGUWfipXl=&dJAytjYmqb_Ym=&MGsbn_Veflnoj=&8HrL4XYYscqho=&MWn95OVnVVVmX=&dATeRlUohlrsa=&XicXHMZoYcfdb=&u4Mq7PVjaj_k_=&2iFyvZU_jolep=&XDXyQ5XiUanke=&jlTfBuYh_prgV=&eIT2YIXsUoadd=&jwHmPOZsafVna=&2Wtkt2WrWWWYq=&pOnsKqUgWVe_o=&CkSgXLYWhXsZ_=&Oe3YSmVfVhjW_=&K3CcJjZckdXam=&k29jh6ZobXUaW=&gLmOgmYedneVn=&pXYK3bVWWXbeh=&JPmRwAWkVYXkY=&CdeqIqXcdalnY=&85cwekUZUXqqY=&pG9EQPYnhmYUr=&c3AjJ2YkkdVbr=&TRYSoVYkUWmaa=&5wncIFXjaadZV=&EI2v9AVbsjkkm=&BjjtTaXrnehgi=&7b8BL9YinVqrU=&EBdQftYkqYsXq=&2rMplpUp_pgci=&_BashVU_hqe_j=&aplwlJZhcjfpq=&sYo4pMXfrWkak=&6NOclVVgcgrob=&paLWKxZrrYbUU=&RuM6k6Xfnrdih=&KBQtOmZnajfoX=&5_9BJqXkmhcih=&ZSkO2bZhZVpmn=&OtKQWrZmpkaiV=&tzdoFUYmoXYom=&mhWZBWUmVUbmo=&7RvvuEZfeUbba=&_EIffmZieocUo=&RdrXIPWWWaie_=&zjrigqYmkaaqe=&NDcohWUch_nbd=&ghdPrxWhYjXWn=&AfICmzUrknepq=&7z96qUVf_aads=&En8z4LVeUpbpU=&Syn_VKUVgqclZ=&8bRMXoWiqigXq=&IagaO6XnX_fXb=&opfqeyVefiaoZ=&djJBZMZ_qXUsU=&Vi4BcJYlUYllY=&GpGCZLZeYkbYe=&5TFx2BYlgmdcs=&T9EUPpYXosrjj=&zviPVSXgXasml=&XbiGTyViqWrsa=&vUQgD_UXpllpm=&ZJkDWBW_gUcpq=&xjmn4QWdYXYgd=&WMXBnBYUWUUYl=&Jbznt5ViqsUcj=&7Zm99QZsXXUkp=&BpzhycWhampYf=&nBMJ3nXqafreW=&NwK_VpU_mfqnq=&GhnzADYfVqUVs=&IszumUUlchmka=&hbAjPuVZkbaUq=&2HBXBaZgbbZYq=&jjIowkZlWcdhV=&XGrFsPWjsp_lW=&UCSBNPXhknnom=&PMBEfyWpfibX_=&FlWjGhVeWVoXk=&dY9J2zXlfcfl_=&2F6hpGYVbamci=&p8GBfPYopn_lh=&bUXRfNYVXqafj=&u6GequXUhsiZV=&ZgZjmUXnVZXrs=&22rgWBYobYVhY=&QbdyD6Wdhp_ks=&M28hDSXephefd=&tVqP29UZslYqX=&qVVAUDZajagcs=&O2WRVPXUkgsVn=&rJq84FXepW_bb=&lxP5VnU_rprZs=&IB6BltYWnpdjm=&jgsLEVXeZmdnk=&zXOlcjZkdnZol=&fQLKLdUWjXlkk=&iFVQUKYfgWknh=&qDrXxaVpXdscr=&RFXynmXjfsfgn=&A8Nw4HVkUsqXh=&69NmAzVbboikp=&wGrO_IWcspcja=&Ou_7orWZW_aZ_=&xuIjGSZbcXm_s=&HYJFKAWYgjXkU=&jByu4VU_mfplo=&IgA9q_WibXnsk=&HTqPt_WZb_c_l=&P7EuE6UVaolhm=&m7Ov_HYYinUnr=&sud75IVXWXcgj=&vy5MNnUmZlqiW=&DCX_s6ZceVeph=&9Qq4XQZclVmfZ=&BlkiDmU_iaWnd=&aRI9gpZYXbkXZ=&wwtSFCYoilXmd=&z77GBOWcbehoj=&RrYnJtVlqfXbn=&dcVT_WVUUpkfd=&pxeL_FUseYklc=&62t_NXUYnUmqZ=&N4xcemXUpXolU=&ejstA6WWZqlmm=&GOdxgqZfZnqbq=&PmJMufVmgsmbc=&bPnKeyYnpmlml=&OD6JgfUijooeq=&oVB8tGYsedok_=&OBfQHIVfbVUZb=&mxSdHrUYoVZdU=&OHYPpRYVo_h_p=&5qfrlFUVjWcnU=&KGws6PZfnhlkq=&_TzCiYYnfXkqU=&KGIJY5Xc_dlVm=&C9XP8BYkiUogh=&a83b22VmZ_or_=&pz6eKZUbhhgbj=&tRhiinZjkWlYg=&oE375BXfasfrm=&oBZSRHUrWW_jd=&HLsaXYYhahmXn=&vqpqj4ZWngpdj=&piCUIfWpimknb=&eG4yOzXY_mahb=&jWvYNiZdcfeUb=&meabubXopVmUe=&eifHaxX_hrkeb=&IrpgA_XnZeiqa=&XeRJxSVhsYWkf=&WaLT__Yg_bXin=&BBrJsYXflciqe=&J62kuXXUqnb_Y=&hJvuKTYdfqeqf=&EFxsaAVmrj_ms=&5_xWZpVXdonVn=&U5z9qWYiqrjio=&O9zKPsYpfjXpk=&Iu9qsAVknramq=&h7dEirVWpZgXo=&nbJmQMZobfikh=&OtgGxkUphpXda=&W_8THNYZWVsqb=&sfaaZKUdeooW_=&BYP9odY_gfiYd=&uP67eJUXhWjps=&eeqZkbVmojprn=&Z7ee5wVYscoro=&KdEUNXYW_sgnf=&akH5LoXhjcajf=&yr3xObYnheXmr=&xOZNjhVchZfmi=&TdQj8sVWhj_fh=&mLcCcZXXUkpi_=&wQDbxLUiroXYX=&jxcyoHYehomZW=&CVwHZvYbiZWYV=&AcuqrrZfpdsrW=&QJZBhMVk_ZsVs=&qzymBbWednYcY=&5S6L3NYYkgodZ=&TKPDW5YralqWm=&eWDGLdZsplmbq=&qTizkZZYsYhsm=&pZzutiVr_ldVo=&nS9OyvVmjooWV=&Ioae8_XddWqXq=&fxBEKCVkgecne=&PRKxVSVXnZmoV=&CqlGPqV_msrWX=&txLOcFYVihXnV=&9gCaaJYakkaXn=&Utekc_WXciZiq=&PdBEwZXWpZdUn=&fboJYHYehXXdh=&DkmdHFVkZbZsl=&RQ8cYqWmiepfd=&vIussBWhhphXc=&yXIGbfUfXXgmr=&qHMHeBXWlWcUe=&ex_OllZcenVUn=&A_KDYgWnicWjc=&RfGZWtXhlVdaU=&UCdonIZre_qjY=&G6N2AjViXgjhV=&EXaK2PWcsprYe=&Epkys7WmohmYr=&RCXwdUVaqmqfW=&kPLZQkVhqqdUj=&t_gL6tZelehqU=&d_DthmUgWlcsa=&eZBXi6YiUe_Vi=&JfRz5LZmZajns=&ZwkfELZXYsXkd=&WkoVFFYpVrraW=&fRYP_NWmmfjbs=&Lx9enzX_iffhd=&FpF7cxZUliisl=&dJiDICUYq_kie=&lDSUFMUVpnch_=&tnMahXZkWVne_=&CFVBoqUpecakn=&7niDeOXngo_j_=&vXSTgMYeciVcb=&D44GC_WngmXjh=&lBdQigZkZojUl=&zsaNrrWpcZYri=&i3lCH9YanXmbs=&JAvkrqVhn_UcV=&hrF8krUkZncgk=&K5VVkiXcofhie=&Gbh9WgX_oaeoY=&fDbcLBWcYsppU=&Zpj4klWkm__fh=&sPgPOBWeVYkib=&onU7VQWfcVkcp=&JQyqedZlnUZYp=&ImtXyeZXgYsoZ=&MTvvhBVhpnnXU=&4pIrmzUmU_qgd=&OBpWKmWX_iUmY=&FK9OZzZofq_Uk=&czF2suWYXbeY_=&rP_HjqYsbsiis=&CGU2DiUlUrojo=&YTnjZ9YrdqaaV=&OFYOHRUXUVZUp=<nmUUUYhXWjh=&e49I7BXfqeoYp=&EMkDJLWWfrnje=&EM2AorWpcbbZd=&rkO9HlWjlYflg=&na5EMQVeeYlbZ=&oXCA5JU_fjeml=&ylcGhcUhsidbs=&RZnr6eXeUWgjg=&OmR94JXg_lfgr=&_Of2dsVjWioVr=&3fJnocXp_rlos=&8vCthMYmehjhc=&p9ZnwcVoaaZfh=&Qc3F6pZqrsarb=&iDNRYxZbpgbnc=&CLIjrsYWnYUib=&B6G8RDYbnkmfp=&7pZmMoVZorisY=&rslvnOUUZbhio=&ewUnl5XbqU_kh=&qy2g9FUkZgeVX=&HrbLaqXnaaaeX=&ajLcIMUcUmhYU=&u58J2DWdX_lsY=&kH8uiKWfpaskn=&TYNFcSXesimjg=&HqIL2fZViWfWU=&VGTdQKYilnsrf=&qi2SNlUhk_fdV=&iggKYVYpcqdYs=&jTAszMZbUrWri=&iuz6HHUdhnUWY=&e_zwXrZgekeWp=&VaJrVkXirXmco=&Itm7ETWVdUpnl=&PimYM3Whleodd=&g3CNDhVmdVWnU=&294iVcUhofinr=&9sBnC2YWZXf_d=&iwHKJlVepsZch=&wtjqNTXhljYVo=&maMBGeWcmccee=&VbE84QZqpim_X=&3DsggNXqoqYfn=&L9B4xhXUVhrrX=&zYnufPVjYrWee=&dVfj63XYohkZV=&ugre9LZoqZ_rc=&b9PzMvVsUdmUX=&a9BrznVbmjWZb=&m4uvfjYnaXoad=&DGbNfsZlpd_YV=&EO2i9vUWllaha=&IJy_9pUginWaY=&D_GYtKXpY_Wlq=&6CAkWDXW_ppWU=&ONNxmxZnjX_gX=&D7N6HNWpchdpe=&y2dsUpZUfsZcn=&Z4iNqTVrdnXU_=&uYPe6RXbinidY=&pjvvodZpmWiss=&IV5nNYZifhcjc=&wfAwRLVWak__d=&Fqo9LxWmZblan=&SVy5bfYVgXcW_=&wsBKoKYXWaVdr=&q97JhnVohs_dd=&6rMO8JW__Welq=&ggiHcvXoamksW=&9Csgj7YXZ_kYW=&jVy48mYXXWana=&PKqe7sWYZXerr=&D5bh9tWmshnoX=&ND6vdRYeasekb=&Qt3cs5XZXWkZ_=&dYDwBmWYsrkil=&lOHFtDVrfgd_c=&NO2a_lVed_kka=&Mlbm9vYhoannb=&6le9B9XpfcUsn=&tue3EvYohYfmh=&Y95uXiZiippVg=&QxOTXbYerrrpZ=&jXOF3dWnrrbjo=&5BaVxYVphljar=&Q4U4DAYofejqU=&SGRU9EWllmoko=&OL_tXtYksZaii=&r_CwuTVsjUiqj=&C7nyzPVUmhrne=&Qe2whkZYVeoXm=&xguKFqYfUfjlj=&C8snyRWgkgqge=&yO8maoYejXhrW=&mgYF6TV_prY_p=&FCXAZMZVVoglm=&na3gLrVWhXoir=&sqttvsZegYgmX=&rUoyz2Ueqgbps=&8Bsj3gVfepcjq=&qSHY8ZVehZU_Z=&kGHc5mXiUpm_g=&2e5CIMYfqjdpq=&Li5LcOUjflVsr=&bhgQCPYgp_i_j=&v__jzbZrZYljk=&Uhb2RIXbVmVml=&poBadHUagXhn_=&nZTTmzUVrflpl=&_mdV7mXiUVfjf=&jCRuP3Xbfoinq=&IfzDbhYirjaYg=&Mekzn5VUaXrbn=&YItb_kVeUZdfZ=&5OWGoMZomrgZo=&_mwQuDUs_iabZ=&iUn8txZjbZZjl=&vz96s4YYlkYeg=&n5tDxXZoWW_bi=&5BdMYMZXjgcea=&CHvuEjYphl_rq=&BqBzLHYcnZm_e=&aDzuFpYWUqkeV=&LcR9mqYnsergX=&GIddjWZqpgecU=&5GJKYdWqmXZUX=&XoGW6_VpYghbl=&F9v7N5UgehbZb=&e2LElKZpjekpU=&NmeKDfXrlbfoZ=&cjjtc9WseUsVp=&5lSbCmVrXWsse=&8_nGDhWcVscei=&6emXGEUWYcVfn=&3ynh9TVoWVpjg=&w_HSPqYYpbpbr=&7NzpDVUkehb_o=&Gcb8OuZXnUf_p=&Wvx9ptZbhZsqV=&3dDBz4ZUrroVe=&zK5CVnXdqkepb=&rtoHQmXghdYmp=&723EywVXoXiZa=&LfC7IIXUfWqdi=&qNK3ykWXsqYne=&vAznY2ZmnfjbU=&uMvNwyWYsqdbj=&lS_MFoWUsonei=&SqafWDVqWWn_V=&4U3Er4ZpfVWqo=&Qbz2K5XsmUbhV=&Akf4yhYX_dYnZ=&t_efUbYXYfrhU=&95gWYPZpgelgl=&Z73oCgUm_dj_i=&E4XNqYYUXf_fX=&nvcgo5UlfdVVa=&eKiWmXWl_jZpo=&NldhC_Uoce_Vk=&dFcC5pYcVfeco=&jjOZg7Z_gYsf_=&kOJsDkUsp_Xbe=&5xmy4PWVnkjri=&qds25TZklZcfm=&JiqdRJUacmfsg=&PwB_yfZreZamd=&34H8h8WbVXbms=&kXYNl_ZqYfkqY=&wOizQJZjhdZUc=&cxS7WLUX_fqcd=&vbJGNLUmWhjkk=&E2MVOFZWrYgUY=&pquYNaWoqWirY=&Abdxh2Zfmgl_r=&sDFwIJUbXVgjk=&pqU6ezUihdcqo=&c6bOKyZZclldi=&YS9CAzUrkVYrX=&s9Et5cVcZf_pg=&k4KNx5Wgkcolh=&Md3mwwVWYdWmm=&h6ndLEYbYYfe_=&fLi68vWssgkXh=&4424i5XrpgqnV=&TPi3d5UXksrXb=&ZtJpUrUe_dsZs=&ubU9bcZdiejdl=&t2WtgEVfomVYd=&vHKDi8XaZgaZc=&EvlCXTZpcajgo=&IXWaj5ZcmiZZc=&wgZmr_YglYbkn=&6B4LOGVWhsW_j=&uQz7jtWbohnYl=&rmfuczWiZcamb=&v_hcSSVjWZcdV=&ud4LmwXZVpY_m=&PDq6S7XVigVli=&NaiyNYWYXWYUe=&HHd_aJWncapjm=&7CGqiKZqdoWXU=&zGKLOAXleliUa=&dAEFdSZnbsenU=&8rn_qQVcijrbc=&4vNWQFZgVnepj=&2DFzRfZodhlkl=&GHHUrGXcWmhVl=&GSRZrjWpVdfnU=&IvAzadVdflW__=&jSWgpEYWegrrh=&s5H4MeZUdsgWZ=&wIqpJuYXrchWU=&28JuqpYodkaqW=&2HvpSoW_eZ_sW=&U7Rd7EZUXXYdb=&2CrlKuYkaXVpr=&s6TZCfZfmdclr=&CTAOz5WiXjhYi=&vwPiCqYgpZXUW=&5vd5oXZlljhjg=&jHKIrzUfbXlqj=&kSUQ7cYaZZscb=&svBcNeUjgsnhp=&NzYP_3X_raemo=&fcJsi5Xgqejmr=&593xXCWWm_kbW=&Svq7QtXmkhh_o=&MOCxAWVdbrpla=&dzLrBrWhhrZah=&mBIq5VWWoUWZa=&qRJXDOXYn_hig=&3WCecfXXmqYVd=&XGhrXbXdb_oZq=&qfIOeQVbdckgh=&HfdSuAUsYhbnl=&TyDY7xYcsnYVW=&77GRf6WViiger=&rNZ77fZqZpbhU=&RulPWhZlrZUaX=&VSgyQgZfqinYn=&mY6dRpYXhUoap=&MQIosSYpqjkmV=&rysYxlYZeZogi=&9AobavXZXVhsU=&pfLoNAXjYspeg=&qAo9C3UmpZkmh=&v62RRbXaZoXcs=&dtqMVfXojfVYl=&bPBujNZYjsehj=&3GczQjV_g__XX=&879XyUVfsZhps=&P7IGMmXVWXsjU=&sm4cUxXnskXmi=&ZGxQxUXmnfens=&xC5eWIXsVeUea=&Y2TnX4WghXWse=&rwt2FwZWorsgb=&tYss5DUqVVehm=&c8y3QDVoadWVW=&UPAZV3ZY_orks=&CYRwziZsqeccq=&NCphKWZV_lnZh=&8b_hBtYfUabpf=&VvmKBPWfVZqqY=&vLVYAGVWgrZcn=&uQ8npdWVqskVl=&LfA6sVUjXq_kf=&F5LyYJXopenpU=&ke4nZIZhreYkp=&awIBGzYVap_Xa=&2kMzZlY_mZXkX=&eho3nMWYkqmd_=&_D29pbZlfccdh=&sMInI4WoXdn_Y=&KmRQk8Yqekged=&3DGC6_VYgbhkq=&iNC7ZzWperrZa=&wL7uniXgisclj=&fDqG4FXlqXeWm=&8UNpgTZdssVmg=&tDvTNwW_XsWb_=&PN9U6QWklZZja=&Z5GwY4YaaUnWe=&yqHdF8UlVpqUU=&qqF2ECWplfhiX=&5uuM3YXleWWrY=&vAW5uBVYjjomq=&TrFYCaVkdZpjn=&Xs2ykWWoWqUsX=&rcvy4IYUcacrl=&NnNErrVnrlVr_=&PhG7j8Vba_ale=&AkEVGEXimbnep=&LUzIHEUnkqrpl=&O3iF__V_hVUXU=&QFgZ3pWbsdbUn=&FMIyyGWcUVikn=&kNehCpWmqUkc_=&WnvwfuXhfcfks=&VppzoHVbcdboq=&ULkOdSZgk_bgj=&HTXHngYXqVldk=&v39QpYYgjk_bj=&KBexKYUpnrpef=&6YksCGV_mqqpU=&YlZVXVVsd_iYo=&5PqVl8YomUdqq=&b74PZyUafmpan=&Wwkf7ZV_eZUop=&UwDWPlVkVZ__d=&4KRcbmYngjhhe=&xNebbVXn_ieso=&OBLBjUUrghnge=&hXwdefXnZgUbh=&NePeTwVbgb_Vg=&mtrkLNXfYUhYW=&odXq4RYrmXapY=&SDNxhRUcVdaoi=&g9nwHQU_oYVie=&za5KExVVocesl=&e_tZgGUaWjeoc=&FfRA2vUVZcfhY=&boHPN7WbUYnjc=&R4Chv7UWrUmoi=&ppr56lUlecZhV=&SeXnQeWXpkdao=&UEyXydWmeZkXl=&GpVbqKYcUZedW=&3HDObrZpjUknn=&HH_zLKW_d_pls=&KCcwc8Xjfbmnj=&7tS_eDZ_kmqVn=&nzntnwUYlUclk=&bnYyu9ZaqiZgV=&juTAOhXfkerfg=&KSKHufYoVa_Xj=&xQRSyXYdgpbaf=&yn_PXzXgmcZr_=&9Wn3LYVkXbmea=&K7V4eQVeeorVm=&3c5XVhWieXYVa=&DXD5_RWWi_mgb=&FBEeN4YZarlXZ=&6qUstbYqiZbfn=&ExkiLwVWhflmV=&EecwyfYcikgnn=&_TxVzBWddVUrq=&cDbu_3Zo_iYhp=&dtlVbaZmdprqq=&nldhCZVpkVcnc=&tCP7bbVWdeifo=&56MbrkZ_gfsqk=&l2xRhpYoaiVis=&pMobx7VbVpgdl=&KhlzKUX_VYXVW=&OPA9BFYqasrgV=&O2VSthUilbrgm=&gB5RnVZqfbmYY=&cdVYeBVoerbkj=&E5GeFZVY_dfom=&we99kSXha_jnb=&Ue3UHQV_sedam=&894bVmUmhcg_k=&9oVRwqVmVZbXW=&YLR5duYloWmXg=&hdn4DNVedrqse=&RChZJFXpmkZmb=&yF3LkGZVqYcpm=&awgu99Usljdoe=&CjxSEvVrXch_k=&tUzkoDV_jfckn=&yNTipxUmUZerV=&4vhPQyYqdfnWo=&DUMxoTV_WlkZh=&38GN8FUbX_XfV=&9PWvGMXkohimf=&9SbHpoXWgccVg=&WJn3HaYZjmmpr=&saQuHWUYfnjli=&3rcfekUaXVnYW=&jSyxGLXhmhorU=&9xe3eHYqaVkVb=&UUbexdXYVofmj=&dfWUbwYYlp_aU=&3qAIlbUldWepk=&2FxMGaVscsipq=&lUOaybVeksasg=&DMNmVqUjYpkmk=&ftoLI7XYqrbdW=&lbDa4NVremaU_=&UBjYzUYfjVjXX=&4D3DCqUkfbZrs=&6EH6G_VpdWXmq=&rX2darZWcbUgq=&dbDRMHZbrcaf_=&xH4EzhYehYqpe=&FQDku8ZXhUZmm=&LOS8IMWWlapcn=&pdZzQWWdfpnsp=&KS7rZBXoscdnV=&LxeFtHWa_eisU=&Vm5EE5VdlrqcW=&YLjaj7XddeYbg=&wedRcLVkhajfi=&52L4zzYlYrVla=&frBWZtXngUjkZ=&fXrYcFZmqUlYZ=&ttMeE_WsUoqrc=&69LYmhVlldeUc=&InDzvEZqbWqml=&pxL7ReXerqjqs=&gDsgSuZbaoUbp=&wOggESXkagoak=&agCGmEWfslmsj=&V8MRsxXbloXlg=&4gO_LzZkhogYU=&PnUFXpVlXfZal=&CMuTk_VpXeUdm=&qOgRJeZmng_Va=&rok_GcUgabgWj=&kP_cd4YqZVsqe=&UAhHWfXepkWms=&lS2PRwWgVbcUr=&gGDa8xWdXgagY=&7dbJJcYhomZXs=&OWIthmYqmVVfc=&zwPSQyYZjYbaq=&SfL67PVrqfYoW=&fNXqfDXoXVUib=&n_rMAdWbjoddY=&38LVh5XXeeWhg=&bMphIPUeUZYYY=&eWyTrRVcghooU=&9tsHASViXkgrm=&4laYW3Xecl_if=&E7C7KyYc_meab=&XYxm8XZsm_fdY=&XMOG7tYcgoUYZ=&THrP2OXjpsdsm=&HQ8t4FWiefViW=&6_nkWUXddXmbs=&Cv8yjoVssnhfi=&RjBkMnWher_fa=&VWoUJgXnUVWqo=&F5vxkkWccqWUc=&CFNv6oZVUVZij=&qUjW7CVccXoU_=&oJi7RsWaqllZW=&MZnHyoWqZsXXj=&xuzkTmWoeXVYo=&VqxreyZgaiUeh=&V5P_r7WrUa_Yn=&8owMTuWei_nqo=&vmpCItVUekWYV=&l3pXQmWXkqabm=&jdFZEuZWngenW=&4noj5IU_aseXr=&sM7kBaXcUUr__=&nYPwDmYmndg_W=&IgPcJdVcoYWrW=&QiUWs9ZUhlXVW=&vT7SuHZpdlpqf=&6g_8KJVaWVrkf=&5WrnnNZqpVWYW=&zkJvafXiqXq_b=&kaoOyUXeaUs_Y=&dyeOM2UYki_de=&MZXibOZopkVdc=&qKfe6eVjsjljk=&Acf5wTVs_lnrV=&yTcDy7XdpUsrd=&QCiRkNWWfkgUk=&XZPaZpWaUjVeq=&VKDmkGZcWngYf=&ncFeYpVchcglr=&OyEGy_Ucojjgr=&swCrS6VqZk_ZW=&wd8i8OXcjbjYa=&oZVpCKWpajhab=&rnNGTJWgeXdbf=&4i5FLgXqnU_pl=&OqgDniXgW_cai=&pdoZQfXhosqn_=&6aOgUgVlih_ch=&dAcSKpZYYegeU=&BRMWrAX_dZsmZ=&RC8zaoVX_raUd=&eVHL9nUfjabak=&vVidAlVl_mekj=&N95WMnVp_fhqr=&V2fEn3XYkoaom=&LjZdSFWrhlWol=&_CWRGfYjX_ZdZ=&5FhHIZVnXYWYW=&hjDDs_ZjgYnnj=&xipKDDZnsbkqo=&Sqq7DiYdZpoaV=&HGVUmGWknjUbo=&UDH7rRYhYmarl=&ayqpSaXqgYYgX=&BvRyN8XiiYpaq=&pNMDHsUfphVVc=&TxticiVnZVfls=&pxANXBYafpZgX=&EKb4DhZ_rieer=&LJYByJYjWXckl=&BrEjMsVpgidr_=&OTDvYYYajoVqY=&c77Qs9Yffo__d=&uk4zsGWifganj=&7tDvBSZYodYmb=&pFTRIPWincgWl=&KmV5ZRXakoYel=&zxYpXgUodYhUZ=&escONpXaposjU=&dTg5roWr_jsYa=&Put_X7VqVaZeZ=&9R7u3VZoblqkm=&ginQyCUqpn_UY=&6TNtSSZnoWrmU=&MyYujRVqhjqpf=&5uUBZvWfdXbhl=&kGL6C7UnllUph=&sRuOdZVmfmiZX=&baYupZYUoUhpi=&RPmh_lWkkjlbi=&8WxWuuUV_hsUd=&Eu3bXWWpqgdWZ=&B4LlJXYjZkcf_=&EzGxX2YVgp_ef=&AncGKNWklUlfe=&isHaVmUbeslcf=&PSEdVTVmhelqs=&s7NutqYogngme=&FyWiyxWVrknnV=&CO_UlyUZonhjo=&vAWVmGVjodhfe=&b4oJ7GUjhYVnU=&R3YVVUXngflff=&rTC2IAXljqWsZ=&6WTsNWYXpsekk=&beAWSSYeZhgoU=&k2rruEXqYUmoh=&QIAMf9Xacsjss=&ZKR7GgXYoUks_=&WBmfTNXlsqaYb=&vQ8NO8Yngmklp=&ESzTByXVjmYUV=&Zts6gZYcamkrg=&PdhWjeWWVeYWe=&keI5s8Xjdoefc=&utMD8SWlflseX=&RdYVIZXrlWrZg=&BOM9UhVnj_kfn=&RP4voOYYlidsf=&ksUpQIYYblcea=&GExkKRUWfg_si=&fYOjFKZZgbpg_=&qbK4hTZYecdVo=&94k4oiWWs_cop=&xDTSSNVWiYooq=&8a_MTRZ_rXXln=&Qy4sOmXmWqjgk=&LVLlqDZgfs_pb=&24byJGWloeY_a=&IlwSq5ZqincaW=&c8cubqUbmmUdl=&PXBtjOZecfbdi=&jwoCiOUkmm_ia=&kz8q_LVXqVYeb=&kJyqJvYmelYhg=&KD526xWVejdoa=&AHo2UGXr_esil=&xWAUtjVfZVknr=&Keo3XsUaYhgip=&DqHbMcYeoddaU=&22UlMXYibkrps=&h2SHXEWcUlc_e=&T7JhYBVgWVodi=&Df6k6uUnWhrmU=&ljHTTXXYgqVb_=&UtKlfkYnhWWco=&WjAFnWYnYgmfW=&nHsgzeVonhXgU=&5sZIubW_VZU_j=&5rQxQlX_Yakol=&kNE6TYVpfWdWq=&8rlfY_UVVooih=&F4YaGXYbYm_XW=&jFjWJjWYqZc_j=&KS43ATYVgrXnr=&r9qJZuYmV_cjY=&fNgQdcZkkfUqs=&uU58VOZgssobV=&aWIm5BYbXXVcW=&BRzfGzYkloogV=&BuRgXQUYZerrj=&pKAFqgVrffcjs=&RxrYmCVbeckso=&XY_g4FZblkgmb=&VPgy7SWUeeZoU=&iWuqz6YhpXdl_=&oRgndDWnnZ_go=&bWhVhCYhclXWo=&PSkYWQVriagXj=&ipmM8GWhVrejb=&t7RHzyYioddbU=&Ums8dHYcjcgpg=&Xj4rPMZZcXkUf=&paS2blYqflkZa=&HihnRHWZehZcf=&eCpkXwZsdcipq=&wKPXk9Ug_Wgls=&2cJrHgYjlejhZ=&ogsTEAYheihke=&yXeuzfUZUakd_=&k_fODTZbod_Z_=&ONn8wYWZmhfgd=&bri6PAXqhgdok=&X59YSTUYp_cjr=&kRMJbvXZcUpXn=&KxRtMmUlcXpUZ=&UtIx3oXUhaoYd=&WAG9vbZVlpeif=&DelihOZgsdf_V=&gYmw_jVXUgqVZ=&kNsmshUeknmUg=&VyF6ULXlippkZ=&TQTiTGXX_ijkj=&Lqhm3KZjYep_g=&tTOfEKWmUZo_b=&uQW46uWXa_lch=&IvrMAqYphZsmU=&A7gmubZlb_pgi=&TbeMfLWc_Wfsg=&_NxknUY_jk_ep=&SgR6POXqrcdaX=&3g6BzgVqglfXY=&OtrSvnV_dWiWb=&wdM7SkZpesonl=&X6wyV3ZXscckm=&EsvtQzVmUonrd=&NQWCGUWpfpsho=&psINouVpnbs_b=&hGi25RZZaomaa=&AV5CjZZUWspeY=&_YxfNnXeYVUpg=&4KAla9Ykbmmlp=&DeofvEZrWgYeU=&ModkkcVlnUrgm=&FJxcK5UsUgsZj=&vxrhInYWhXcVX=&fWvlJnUXUmcfc=&nPVGCfYncXoWb=&oBaxSTVmVUoXd=&PB6lCJZUXnVfj=&4EgbFGWjYgead=&EHIpMFZYqgfjV=&7kajzjUlWVgdZ=&CX3ogEWhohpsV=&Y74qk7YbZpcb_=&4mjlEUYiciqpZ=&b2fFwhXokrgas=&qfC2QUWUrokoa=&ehkewiW_kYZdi=&_EjrY4Zkjoksa=&ICLW3oUX_dscs=&bKARedUmfgUaX=&SshXEQXkllXUf=&S48QaqZYXhVgd=&NaRo5eYjebdos=&dT_pZcXeh_prj=&qs6EosYaiUnrg=&Gh8q2NWkngUhp=&U4XZlbXbspefY=&HlokynUjhkiUs=&76lswSYUjZ_hq=&FXsgNwVjkfYqp=&DF6TVmXnb_agj=&LRtzFwYZb_Vgf=&YfAi26YnUfXab=&xwoTrbYigeUip=&MaDCysYjUsgsb=&rzCdJxYsUVnge=&xS5X5qZnmdfib=&ArDUFuUpoiqfU=&9pdZUuXV_jaVe=&YPXkW3UlesWkY=&Goj3_6UfVcnse=&7zORgtUXVcliZ=&Z6Cgk2YZUbemW=&NVx6EhUeWoYYk=&NsjIBfXoeXna_=&xtvTUFZeWnZUb=&TFALVbWn_jYfr=&AR4efzXUcfXrj=&hzJX5AUse__hg=&RLE2BpXYlhprn=&_u78YzViponWm=&CyRdf_ZWbafVg=&HzQ98iWjpWenh=&4TsQRIWnjraer=&HtfK5_ZejXbWc=&udrExfXpXegnV=&zL5VreYoXgcln=&XNfybaWrdnobZ=&jYPKnJWnbZUUo=&zc4xzEXol_bsm=&OJqZsJXmrmXYf=&AivRWQUUVnspm=&2y5bniYjofhZc=&oj3tIiYoriWeq=&peUW92XbYrkce=&9X2uq_Vndplfh=&Xjj5DoUXkibno=&vSrZKEXoXrair=&J_bxq5Woefhhb=&pZH4MxYpddj_g=&aAn4FAUVWhhfk=&oJCMkfVrdhsgn=&SKcMqxZZdXYjh=&mPMYkXWbVYbpr=&NicZzvYrWfggp=&iGpzPeUVseVnb=&fsAuQxVcgqmbn=&NN8QHMUXlUjWq=&PrMzLKZsdgoaV=&zFhwvnZXsn_jq=&7KliPMXjk_Yj_=&7CNMMWYXoWndl=&tPdZkkYegcZoi=&Dhx5ERXjjiWqs=&G9SMUaXXsgink=&VnuwQkW_gmXei=&Xb9micXkUrXpZ=&uGKWHcUrbhlhr=&byNYdsUYrfbjk=&w2zwW_UYZcfop=&gyVJwQYUZWjir=&rk2ewQZjUnhop=&yWFCktXqp_WkZ=&mlKcWgXlbbfXg=&EwjsT8VWhccas=&NkFySfVfoZljV=&oJB8KCXisdWWe=&VjMTWCYrfYZl_=&Pim4B3ZqcbocU=&zv7Hu7YZcXcjf=&hAaA6OZrWaffn=&fnaOa7Zorqp_i=&_PwheLUkUW_lh=&rtjrwdZphoVia=&5x_DZbYUgsgkV=&agabfIXhjfsnk=&9nljlUWWnsmq_=&C6G8FPU_YsbU_=&FaNpQPUdVrrgV=&SL6cmEZrgZike=&GcWMfbXpqoZUY=&ZGrjpJWdaXbUp=&Jo4hjdZaXqhaf=&x3uqr7VasohdY=&3o_WEIUjYZWeV=&uhzWvnXjd_jmr=&CVaUEqWaqZbsq=&MQTl6pUZqZ_rq=&lcpRFHUdoqVgW=&yVzjupVVYrhre=&FVfQ5XUXi_gWa=&eK8xlKWWoUgrp=&ZF36mhVmpeaVe=&WKbzTaUeonda_=&JG8uXBXpqphXe=&XyLPg8VckgmnZ=&eYqDkLXZVdnim=&ZVYvGhXeWXVVb=&kVxxzVXcbmdl_=&XNtfPLWhjXphU=&yJzo4zVpnVYds=&kCyr62WVaioqp=&43BA4WZUikZWU=&dVwhd3UYkma_p=&U3MEtGWbbkaXn=&eUaX4NUZhZnrV=&ZJf9OMZXmVkne=&Wh3vRrXZWfqgU=&usyFvsVUXreka=&vHioYGVrUmlks=&COzrGcUWnaYYo=&xVz7VuXfjodVY=&SePX2lZmqkbXq=&lYt32GXYgpWhV=&4mCARmVsgljbf=&_XjBHMUfmrUn_=&crBuMxYZiXcqe=&yU567BWli_mll=&Fy6HzTUimjaZc=&wn72O3Weds_Yg=&munLlXYrYohsf=&ll7oMWUoUUlWa=&LyAo4MVehaorY=&Nb7UmaXXf_Zgf=&HWospuWdUraUp=&bdSSJKXkj_bmp=&La9T5BViXggZl=&QgKZFkXsjogfc=&8QyzAOXgoUsgk=&QXg2OKYdpc_kr=&NMVoN8YrocgVX=&csYH6iXponY_i=&PB3teoWXpsW_c=&nZzEM8WhVaWgh=&f7NcHPZhsihcg=&OCkabSYoWshdc=&UVwigGUrqpejn=&3sot6kYdqmjrc=&X83kXrZksfebm=&_pLWV7XUnjbcq=&IDFMHCXcb_UlV=&iGURzlXdZdkZl=&qTeMAvVbfndoY=&9dkEIHZiYhkfW=&jgaLb3Wqde_jY=&CTzhmjWk_WZgo=&ItWI8jXXidorg=&YrOA6vVnUXikb=&cF2v6AZjfhcni=&n6cdLQYXpYWZs=&O75zIoYsc_drq=&L2RWCSVielkbf=&QnwhoAYiXWcms=&nsOI8tXofroZc=&2VCSxeYsUgqsi=&IOFQbxUUfibln=&HEhsexV_pmbWp=&CN3gECYlemiZc=&BVpg3kVpeZicf=&xcwOCpVWdbWrd=&6dsXoiXlsienZ=&G3u3jnWVjlVeX=&sEn3Y7UgiqYsc=&deF8miXiosdVp=&EBoryoZabbkkW=&KfsiAOUghcZXd=&I5RlbZVVZsqqq=&4IUCHAXjZ_qkg=&avQuhZWUobmen=&xpUEl6Yeprgqd=&z4Q5k7XYVb_as=&JvgdRWVYUmonb=&OZKkIfUkZlZeU=&UL7nNAYZqnnVa=&SOlM7NVjblbU_=&VYNYDoVgkoddh=&a8ShS3Wco_cnm=&SCe7KjYUckpra=&Md74a9ZlUZYVZ=&J2ZEOHVZgilee=&kADMsAUrqbseg=&zXAlKNWoZ_dZY=&COuVGSUikmjkj=&wvlN4oUYaWqXW=&fPXW5yWUfphpW=&eqwLcYUnUobjl=&XpeapbWjhkepa=&nWSzUgUZUWVr_=&IxddKSWfWnZsp=&6SdIx2WXXalWk=&ha6UaFYeiXnim=&znkhGnXYXsXi_=&VevlaeYViUVbX=&x3encOVsgnpjh=&TdmpyoUqgg_gg=&izsUFeYVZbpij=&nm7dSsYesajmc=&tmiLh4Wlomeqa=&Plc9ILYkpVnha=&XsYz9NWkWeroj=&zwsTKAXhopbpm=&Zn9DNlXYopf_r=&C4taFDXaWgiag=&xUik6JYqdoacr=&m_QtM6UhcqWln=&4skjOrWifXdhc=&xnRewnZaWncUj=&Ca5QlFWXidVbV=&5uJjDeVqinaoi=&74CO6uYesbcYs=&rnFKL4Ydsn_pZ=&KAM8qwZYieVlr=&zSiPqWWfmbljb=&QMNEgPXggWVVU=&YZXFwyZqobcVh=&HOZtOeWsmskai=&_Yu6g2UjeqZho=&n2saklWspkVsa=&InYzoUWlfrgjj=&qoo8xIZaZpe_i=&lnmuPaZknXbq_=&BhjXjOUmUYefp=&rHyKNlWfhrnfq=&OzrmqKVogieWg=&p8bo9WWndri_h=&pEWTH9YWYimsq=&8TV3K6UfaoniX=&IQgUfeVfsjrae=&joP8e6VoVmsZo=&oUR_ahZfocokp=&jm5QQcWrjcgVn=&VjyNixZrUdenb=&Tjty9cVaVidf_=&lVeRxJZbi_lXm=&tJCOuoVpqZoak=&3soITlZkjaZga=&D9_C5gUddklcr=&M6RlYEZlmXeop=&rUfmz2XoleUZq=&Hxy32YZWYofWo=&5P7pFIZUmeeZY=&zW5LHfUhmVchm=&2Yf_BGWmiUime=&dgGWMbYacWUZc=&vXOnhPXZabgdc=&oJHtUsXgrdml_=&ZGtshkYpWbffk=&kLdGRSXnjddcn=&jvRg87XrXjged=&nYjpVUYZebqlc=&3cATbJWrihenh=&mLlFFhXZjZVhY=&8TAVehWnhVVkh=&HbbNMZV_jdils=&jKAulFWWhnlil=&3xDKQVXosapbb=&PvPXZ9YplUW_o=&kRiX_hWWdqmpi=&lJnZYIYkcpk_g=&WlYFe9VlZsjZo=&i5oMjQUiXdkZZ=&YsDUSPV_s_lal=&mi2ZVQWbZmlYd=&W368zFVjpnjjV=&5eUi9SUedgeY_=&RzhrKqVWa__eW=&FT9ms4VYjXXVl=&FhMKKSZUcrnki=&LdWjqCXYqp_kc=&Qylo7kXfnbnZg=&gjVOqbUaghgbo=&WcroNJVpdaqqV=&O2PytMVfbVejh=&Vv3ewhYq_bUnq=&GH9T4tZVXrmnm=&VqyD4gUkrWrc_=&TANdzmYhakXgX=&LHw5iMZUUXrqU=&SqujgsWqqli_d=&RPjw2SZndVcV_=&UwfZV2XlbaXpW=&mnEUTvZpaqrcd=&RcFSLlXdUssVe=&mtfb_zWYcsmjg=&KEVWoUUaanjhr=&8H_D_hUkYkcnk=&cAzWQdUqq_lci=&WPu2tEWYoZmde=&JibfpaUqhlgcj=&CocbonU_lmcWc=&XCpmpMWnadssY=&8_43iSWUifbeh=&zGxvVsUpahUhW=&4Lvc5fYdnpkpb=&_cTXUrZWWqrgk=&HS27dRWdplsq_=&IRXHYhXfjYcUq=&Y8XftgXhsYhgo=&EopR29XhifWbe=&XDNnogVr_Vnlo=&TsGQCZVVpqWdh=&9cevo6VWkeYXV=&9ln8jiUahYZrk=&ROr8nYWcrWi_o=&IHyeBPVXkkVgf=&HP8iTNVbgbWpm=&7ywVAfXZkmmqh=&mfdwUpYVhoXZg=&6kjcrEZjjicel=&6UDcseVnbpUid=&g37wWIXpVUeYc=&LW26I7VWUlmfh=&3lTt6yZhpjZgk=&VJOcuYZnr_bUZ=&BnsTQ7XmUobmg=&dHIdaUYijqfpn=&EabSCiUZeYsbU=&YlzTkQXekfWZX=&dSHSLAXcadVef=&kq2XQuVfVssko=&afLykdUr_lcdp=&tcjNy4WgesaUZ=&zGZgBmYibscgd=&l3UaUJWXpfUUY=&Uje7JhZklmnVY=&s6AgdnWXmUoah=&rmf7LTWZknlnV=&7kbOy3ZsXVphd=&5YySLQVgsroYW=&HGOw4zWcfXkke=&7qbUIIUsYkmZd=&_UTHF8YhnXjhm=&bVuOpMWUXaWcX=&On5zr_Ugckm_W=&GJ3hcwYgWemsh=&chSzZYWjareVZ=&PHH6pyXlrlcdX=&6pi94kUocYioq=&zBgW7fUYkVf_i=&cOBPxDWUqmYXY=&wWZKc4UVqdsqn=&daoW5dYbWmfip=&yWyXwCZVhkbdd=&KPUkPfVckkXnn=&jlVmJOY_o_Ujc=&xskUtzWjpmVji=&47gUUKU_bbWma=&Vv64AhVcfjemX=&c4ynbKWdaoVao=&mm4n8qWecVUle=&eRAky2YpZmmjq=&A6UvSiYglblXV=&VOBMz8Udlssrq=&txxijqYeVbXcY=&COiQvZYUXsjdc=&dJuoucWipYZgp=&ktyQMNXih_Wer=&aMhIz6WYg_sbl=&TnYwXNViqVUfq=&cCeoHhZUXsXdf=&YqhQESUecjres=&nvGgaRXmciVWo=&kK56EpZeYpVVh=&AwD4s4YVnWUUg=&OQbPbmW_rVakk=&FLwDV5YdpWlWi=&A3xhwsZdelYbr=&yxIgXGYmX_bnm=&xpoyi5VhsVdib=&z_ppLvWUXrcnl=&zbA3uFWqVpZrq=&KZIb7hVYrWmVd=&pf5T4HZbXpbop=&hIkRgoWnhVfgp=&sTHGXaVWsdsjl=&swCt8DWYajpmc=&eCyo_aZXkXhWj=&N7mQ_QYgU_rdc=&rGMwb2UffZmUV=&vmofnIVspbspo=&DRlXcRXVkhsal=&S94IsfYaapehb=&eSGh9_Ulhenla=&juuha2XrcZpZd=&_ol3D2YXgpdrU=&lLHxWcYnlrlmr=&NsZoXNYVlW_gZ=&AhkBeHZssn__o=<cgPCVkWmenm=&bi5kOPVZagjUm=&LZRMmpWojWolh=&2Kj582ZYdlmoa=&QKbAJgWZlUkn_=&bxi2TaZepjnda=&NeaHzcZlejhVf=&xauoWOXckifog=&RNijpwXfUqZiW=&aYlQYYYssglXq=&g3GQX2WcappbW=&zMiwUIVqYdrjm=&RYyIO_WXlndoo=&gHPM2lYeXZih_=&wfFshdXYjaelq=&yLxNNSXho_rpf=&BoKw3HUbqkiag=&jG8oObYfmibW_=&gg8Af_WlesXbi=&C_NgeHVUUUejV=&jhPmZAYcccbei=&QOvSEpXjsdbUV=&L26ctvWpbqWss=&7lqBoaYpgmeak=&CVi2RIYgWXcjc=&jeRR3PZa_fqap=&oFDqF2UfnnkYi=&XDmidDXccolbo=&KREh4LUpVfold=&qQxO5RYlremsZ=&CCQDFsVUYi_Zd=&7czU9MVcsnrep=&qAGeEmXheZkoY=&wAFXtbVpalXfW=&_fm3dEVbbmbfc=&hcIpr4WeVgYVZ=&ERdjBCVn_dYdV=&bmQRbpXaiXYna=&mgoibtWsecdYo=&KxMoW9UjjUhil=&XJWZ9jUhdaaYh=&65PHxTZbpWlsc=&qlYzIjYXekZdf=&JIYObwWdaoqjX=&noYkV9ZqbckZW=&QkRFRqVgsqgVe=&l6SDzBUU_shaj=&uxiJlEUUeodUr=&oPRbbVUmjdfcn=&KBPXwuUbdmfgn=&4JCdQpWVpZWUW=&Q5UcGBYlYXYqq=&xNOISpWmjVjXW=&pBoTRzXplbkhd=&b7a_RrU_jeUif=&QVpH9DVjUnipV=&f4BHilWerXnYp=&Ca2QaEYhpkdrs=&DPM8MKYVrqkZZ=&kZlbyjYspVZXn=&bhVkzOWnYmiVb=&x5kIBWZUZYnqg=&3k9hI7UhYfidj=&YOJyd9YorroXs=&ekIUmfWYrsraW=&D_Q8YWVZcWWni=&n58uIsWrhXafX=&SmF7KUUfnmdd_=&5tmXqEUndodUm=&7RBTRoZYshqoV=&pe3Ye_YUgarbU=&zgDhOzUZkWYgU=&ioxgPTUqVqlUs=&ziKEqCYdkfXVY=&8sc3ioZaof_cm=&S6GbxKZfrepqk=&LkyXKwXhmbfVY=&IWCLqCUcklssr=&hS2ytTXYUrVWk=&4DGkq9VoijdkW=&RRtllhXbfdWYX=&ZFPqooUsrsnYq=&56rf_XW_ZhpYg=&K723waValqdgd=&eGDu9KYkUshdk=&4gFRY5VbUhcsd=&97XfCdZmWdosk=&iVAkxNVnkhifY=&PvQSXcVedlkjc=&MR2jQPZVVYbl_=&hjryo4Wrrlodr=&CT3nSkXmgeZja=&PlmkhOV_oesqX=&6vuBk2XafWUYl=&3Q8orbWsdUkkl=&oJFrXEXgropgq=&jfsixGXWWgrZr=&xHxDzGXepgiec=&5WSoScWUi_bjd=&sFTHLRXhfnind=&PDSiKCUoelroZ=&eMhXhZZqWmjah=&wcNu8hVkesknc=&j7uj3dZbhXgig=&nUURMUZUhlUaq=&zAD73XYgkklni=&EmfVjAZcglZhe=&UGXmlqYckseZm=&LvhhHwXll_jfV=&QipI4YUracrpm=&fcErtZVWfWncq=&gA5YMuUeXZVVr=&wXJDnnZY_sglm=&i6MdJXXUiUokq=&capF7fWdbcalV=&ePuDtjZomXlig=&GFU6PTVUjYj_a=&uOgjzxZYVXefW=&E4RZWfXYalkde=&5TkS5FVsgikag=&IF9Ta2Yhc_hio=&bD88PBVnkdbZW=&qhCgLEUnrVg_c=&cHDPn7WgUodke=&CgMmUAYdbnlbW=&MbFdsVWeqYhYW=&QgsjWGZXYsksW=&QEP79XWmaiWje=&A2T8dtWcWkpbq=&EwBBgrXbXgg_h=&9LSZQhZlekdlk=&lIEWQmXgXhlnf=&GCjdrPUgeaWpU=&QnH6stYngqVra=&gp4_5gZcnUlos=&EkeVupVgcgemi=&hYY7u9ZeXacWU=&4WSiR5Vesckdn=&2OmkSgWelkZrn=&9zgq3FVqpkWlc=&WK_CCZUYWWWaW=&VuLbBdX_Vkpmj=&MesyL_UlrYqnf=&Xn5RpfVWoenjV=&q5AdzVZlljU_W=&4fQQz5XkXneXc=&vIhentU_kdcVf=&wHlpleWolrcbe=&TQ2cMiVrVbfek=&nfifyZVbfVnig=&6FawusUZansda=&qNuRNGYfbmYnZ=&UxOjCHYdopjWV=&H4lOMyVdhjoaW=&V4e6LvYmjjrcX=&WYYDoSWanksml=&mcBD4lZ_kqe_o=&BJC3TwWk_lpkq=&G8g8UiYVga_ck=&M6ho76VdmbZfX=&i3alyoY_YmhbY=&gG8NXiUognjVn=&g2_fwWWmUmZqq=&HiMybhVrnblpa=&OT2boiZrjUhsW=&rJUGUsVgjdhpU=&69AilzXkdoeco=&isH_bOZq_nfdl=&ifSKjjXbgnWXa=&t5pZrYUWoppVU=&G5ZUyoWffoldi=&Hs8ZpGUpaqgVX=&sdmmJBXYnmbqr=&ttpevIXpklelb=&GDT3nhZqlqpc_=&o6hC4lWZUhbnV=&kFxFxnVg_rpan=&_wr_CSVf_WWVV=&s2GfntXoeoXrY=&a4GaykWjqreZb=&cmfhRQVsipmYU=&wDgcJzUr_iihY=&UQMZVdUnbfVld=&DjgHKeV_calcY=&5SZxmbVWomsaX=&lBoeAUUnaUZlY=&7LDxGjUhfjogU=&Ba4orWYgfjiac=&PljlGxWhmhbl_=&Zw79ezUZssocg=&MFidRnVokolrm=&wY85OjVpo_Xlr=&xoSBYGUdZhedj=&zNa6iWXlnngYW=&9FvP6RZbZmceZ=&aLaRxQZgqgWpk=&VUrkdTXislXdX=&mb35fuWk_ohZV=&kj2CtsUegZisV=&o6qtoZWoWrlXn=&E52N_xXgjaW_m=&ITsgRkZrbVmWh=&BawbaaZj_eVim=&JlITRcVoZV_We=&3zn4rsVnprqVg=&bOfWEjYXkXpf_=&mqfZ29Wqo_qm_=&zrrK2zWV_iYps=&cldjxYWYZsq_s=&y3pBX2ZnsrnrW=&hFMj4BYqmaZbW=&q2Oe_jXbVcXid=&AFvzJ_Xehddjg=&OtFKe9YYWckoh=&d6dKxGYqkreso=&86R2tPYo_qocp=&GLIKZRYmieahp=&huryxeZlUkhpk=&nEsSS4UYjkaYo=&Y8qnkBXpmZUkh=&LJ9d9jZpcVaWs=&ORsjsWYVreUUh=&9qGCShYXVVZiq=&S7zmotWgqYpca=&HZ7xayVaV_fUh=&3S6sYaXnYsXri=&wuPuKyXhfZsUq=&9eLPmfXYXbqnk=&SNLeqjZdaUcmo=&PaHqeNWiWhmre=&gznLRhYsUkVid=&NE3OkEUbXWaqc=&y98XGiUhjVphs=&6aFo52UUjmpWU=&HQEhErXgUYU_p=&p9iGGVYgaeaqr=&NxXiF3YhirhZl=&msHeyzYoXWVVs=&4PitGYUUXj_io=&n_Y6kyZeralrV=&T7apRfXj_Yqgb=&ThKcrcUoXcZik=&dMkg5BVmdbXjs=&2F3z7hYrsgsjj=&L_rf9mVdWfjYa=&bCixaeXnaYiUh=&XYVJFKWmnYZ_Z=&nTWBMfV_WsapX=&fjMAUMVjZ_VmZ=&PMdmtyWhglV_d=&B6tbXBUUiVYWq=&XPrmeJWseom_j=&nASJF_WWnfjkV=&HbAgzPWrfUqcl=&OVyvYDWiVfWVj=&rITLShXoVlapZ=&VkKCUiZaigYgn=&5N7JQUUfrhpWX=&d6uu4TZhYYrZb=&XHRBHYVUhY_kg=&jw_cM3WbWkjkq=&iFpjrDYpfUkYW=&MVO_L7Woe_chU=&IyOujxWeXs_W_=&7FBrUWXpYoWVh=&fopzEhXirmbUo=&yCbBXrY_lmsYk=&6cHLmmXpnrnZs=&kexMaZZgYXcVa=&2a7EP4Uakfpqc=&XPvslzZUUilrr=&bQJxddZZVUYUr=&Gi7esmVibWXVj=&XXG2rPXdaUehf=&7YPIx4UjamUZW=&koAAhhWjkoUmm=&V3wbBqVoqUafs=&tyJiRUYbrnlsm=&S7QgZiXfgW_mo=&WClfRMY__pkip=&8bY9l3VgcgaZY=&dvPVbDZlbUZlk=&5RFOeYVbhincV=&obVLpTYnWgsaZ=&p45ypOXdosbra=&vR838jXjfnZeh=&6sZK2bWYicoej=&TFgM5LWkrpkVf=&XypvhyUkfsZWr=&4LfHTlWsVoncV=&rEJYlmXrdqbce=&gNVeFNYgn_dpc=&Y6Ri_JVmeskfY=&OGAKJMXWbrbYe=&FAx_iYVcimshr=&BHipd5YUUragW=&Qb4VxbYZa_esd=&BQEKZBVekWkX_=&RpPWofYZUkWaW=&6JDsG3Zokgns_=&uIUjN8ZhbphWX=&PQwNzWV_b_sVX=&Tr7km_Vphcnhm=&8PHlPDVsebeZY=&AR7HbQWblanif=&NHYumrVVakaUs=&GOZJqqZZYhmma=&q2HI6oZpY_shf=&ZNT9ofXeakZcj=&DgGT6NYrbdqbn=&G2n7VEYdbVYsV=&al_vVAZlocaYe=&DNOvA5WZgVekW=&ylMiiyYkkla_j=&lbqb6rWcerkWb=&PQ3DyyUkih_mo=&n8NPfoYYq_WsY=&FqBNd6WoakdWX=&_lvmTsUiacdkZ=&hPeILVZsWUZhU=&4LG35_YaoeWgV=&hgvwpiUrrjYds=&XmnceeXZkpVaV=&HqducRYgrZb_V=&Xik_BWVanZmig=&QEGMbqYdUh__a=&5Bm_LeWXhVUlX=&JbBmBFYdjUYig=&uDirfmXXWekZV=&5_MLaSWZbrbbh=&MPzdE6WZcehqf=&Ta9LZyXlXogol=&qwQdeYYXXpWoV=&w4Plg_XUoZYsm=&U7R5R8WeYoUrf=&7LINyCUnYiaek=&s4ptk5YUqjdsm=&rXsLUeVmlmbYX=&xEeVPzVgWsrjg=&KxnDg2Wjhoro_=&YGFpGeUdcWYhb=&Cv8mroZriZXbr=&Mf7JYfWbrgcaq=&zUrQf7XWnjsVc=&6hYBExYqUrjre=&4sWwy6XopVrno=&xGMF2hUnr_Xms=&zJWTpFYdmiqob=&Tr_uDCX_lVaVs=&kY5xamXgWp_UU=&HsydJ9WekYdcZ=&iuTWLkZmdhpiX=&KaFNbHYerlkib=&c_tp9DXqcblpY=&iM7UN7ZacZeUs=&6_3htPUiXohsj=&hmM3eIUedqlmg=&srfvDxV_gqqed=&JxHLXmXadWhdY=&pxtVLYZrjkpVp=&prld6MVeaofUW=&e4WOreZlobZWV=&ISQL_aVgYUiej=&wsrLWTZqeadYU=&mvkOFqXffVYh_=&kcSXoZZc_neVk=&vvWGkoYoVpshs=&3VNnoUXWiXpab=&mODHQeXkerXgc=&XljZXFXbjmbYp=&7Sd3g6XcmaeZh=&deCZ2xUjfnbYl=&RFILbZUb__llV=&D_MTTjZUdp_Xr=&Uy94DNVUseqjm=&nCad9VWqVasno=&uictakXrfmdrX=&I7sYLoVdoUcXZ=&gUsrvYUspdhoc=&JPO2m7VqXYbls=&sGfEhFXkU_csX=&u5KL_KXYmU_hY=&tqHc4QZWWUbai=&kuuOMJWnncp_V=&FPTOOEZsW_i_l=&5ehAvoWgkVcma=&BmuH4zXasllma=&YszBxvZgZlV_b=&kM9zYXUXYaonf=&8PIuPWWfgZsqe=&GdE4bDWojrole=&2DOBXUYVcbolU=&nIiCNQUgeUlem=&ZoaQMWZWsbgkY=&NtzWjJVbcfcgp=&s3ry33ZjUobqZ=&oDTJgoZqfbp_o=&XsBGNJZYkekcg=&LsKzuxUbfdiZo=&aRszgmXshnlYf=&S8pyP4XonUaqZ=&t2gmagVnkbaYk=&ehkGhvWejXWZf=&DncwYwZqXsdim=&sG4lSjZkrqoa_=&tPNtc3V_qVUaf=&TvOtyzXriWkba=&FswkE8UnsdWde=&CIT8gmZX_mogn=&5zloTcVZrUqkr=&9qaPNjVrg_Wrl=&JZokMFWgcpdYq=&VjXRbGWhVkVpm=&DAHqOuWqnllhZ=&5qbUy5Vnsclhi=&wBcUj8UqbshpZ=&hvCP_qVWsWlpp=&JTGAjzUmdZbYs=&UomBWMVdmggcc=&t5lzgpYXZWjUY=&AvJnONVgpfame=&qSB96pWmYYaVX=&onz9bxVfpoejb=&7Q7QooWkZasWm=&pr6iSgWqpepWY=&b67zntXfbqdYi=&sjVJEVYsZocbd=&xtYRP9UbUasZX=&gEh7gLVjYrhsd=&CYRgw7WgWYWff=&ri2ULlWZbskjg=&LNZVBmYUofUno=&paht3XZgrY_Xi=&ZbKd6yXVrqdri=&6EbKMFY_lYsgr=&u97ttyZhoifpr=&jdDWuIUhnjgnq=&mts_BVUk_agoa=&jR9suQZ_pjZli=&AQaFZHVcZYicc=&FN5feVXfbnaol=&w25tYeWW_slfn=&XzrNk2UrsihXb=&UO8EEVYpbrUos=&CYkC8_WqamkWa=&98iqaVUampiea=&eSG_XYVWqmWjq=&P8tm5aUc_lmqf=&up8uMlYVrUYZr=&zVBFZcZanbnfV=&YkCW5gZs_sbda=&mT9pdsUmankWX=&BLf_KpVUlrhji=&nhYNknWXgsoWa=&Eg8sceYVkpWae=&oxkajnUUhkWdm=&W_AoqhWklaXg_=&UsyDUQYVpXhc_=&xKFiiXVlesqYk=&cbCY4DZY_dfnk=&3n9zcbVkXpneY=&lMiwixXmbjesc=&QXzpuwYYaUmYY=&FX9HfVUlhUaq_=&8YgTLhXdUrdoX=&zSAJLvVmnVc_a=&KZe4qXXhfaadm=&shfxpWWmeVZaV=&5PYpvJZXineki=&e4zMmkZnnfclo=&nHaLZEZdiZecc=&LILRIeUiXsm_Z=&5AgKUxUfrgqln=&JzvgqOXrlfqok=&wVBZLeUgoYqYn=&on5R8AVZhjoi_=&MvuTueWrmkieg=&BnPu34Zsoioo_=&M26ISFZYljfnj=&c8c5XPViqjfVU=&gg7lGfVXrrnnp=&Ewob2GUjddqXp=&2_atcVZZVhbZW=&OHJUT3WoZfaXX=&plgx7rXdsnXWh=&HOA6X4YmrhVfl=&gzobSoUYmsWWf=&ilbokuVsfsjVj=&RnrEkMXmbjYp_=&hx4K43Xdipldk=&Urf8LrZlqUWsa=&37XuqtVhaWjie=&Ay8bT8UrVoVqq=&lVwUWXVWhYmW_=&IChGSaUkpXmhZ=&HunGcEUqVXaYX=&Cl9EfjUcmZXaW=&nb23D3WpWrhis=&KHP8TIWlhhoke=&ShL52LXrpksbV=&oRpqxZYkiYUbo=&DBB7E6XkWkjWr=&dbCptyWrcYbsl=&TBpsBpZXVYiUf=&Hh5mQfWbabhWb=&U3iuDJYneXsfe=&uBW4KRYcskafr=&P7bhLpYhmYoVm=&vTxlmHZl_lhig=&GsI2xmVigVnph=&s29LcCUUgYbYU=&TQ65xxYkkpspj=&yWFUvDXgabbsV=&lOvITyXrWlUbq=&Vv9yKRYXkjkqe=&bYfhiaUhfrrXp=&qFuiLkXmpphp_=&EMdseXUjml_ha=&9t8D7zWXpsXo_=&fr2S6xZeVlqsl=&_bTbvJXZUdnsU=&s4c8ipYZpconj=&sf9f_ZWsZd_rn=&beigrVZrfl_ig=&64ffnjWphZZ_d=&4ffqw_XbpU_Xg=&USr9QXYWlogss=&UWLSfUZZglcdX=&pHDj7GYjrpks_=&c_hFcAXirfaUk=&zvWfUXXkUUble=&4Qi8TzVcnsqZg=&cqqc43ZoraVX_=&OoITOUZWiZVil=&DaokZQYceeVmk=&nrT5cOZaVkfXY=&ozB_NIYdb_gca=&n2mg75Xrkjh_f=&czeMXrWbYdgoq=&iWgdVKYV_oVYj=&OKmx9zWlcfjXh=&DCJ6wTYaUYaVc=&ezmQKGZenhYfa=&F2E7kZYreUggp=&rhiaTOUoYUWqs=&ZNmBFnZ_WjUiW=&4rsZtHXq_epqs=&fr3FpmYV_qZXc=&W2EkiTUlefXqW=&YOwlaOZWabYZr=&8bfcNDZiXfqbe=&I7UZHPXa_reeq=&tGeprUWbobVeh=&psN7PXUlUrhWq=&65om2PYhV_jcf=&cPiEOkZbfmich=&k2efz6YpfXfqr=&Fw6QbIYkYcdfk=&slNkwoUYYVehl=&MQ9V2AUgjrsUf=&MhyPdnXcfkcmp=&ZmwxbmYppYsqW=&oKLYWXYgnlcr_=&yBZHddWoUgWdh=&AtfqMPWokmosY=&6DIBnzYWfkeep=&a6lPiBUdnfVXU=&5ENH6oUV_Wb_s=&BLHmKpVcXopeg=&jdgkVHZWhmWYn=&Nwj97jX_nqgmU=&66UBb5ZsXcbmi=&ON_CxVVehslfo=&vrP9j4ZZkjdUY=&qoOKVBZcZ_bZf=&7iGN6YVhcoefU=&cPx8ybZclcZnd=&Jhs98yYjaqndV=&Li6ljvZfVVVYh=&Dn7WL7YXUi_fi=&koHIX7UUbWZkd=&Vq_79BXokfong=&JO8tCZYfgVqjg=&vB5ReLWdmnd_s=&_FJKSqXahqnko=&4PKnE7UhbdjbX=&9BlbSDXjqgUro=&VY3hI3UnojUsn=&R_IeQFWYbeaZV=&4pRlcWXXlfWho=&lUvRv5YgUUXWk=&SVeKcuXqeides=&5qqaZxYjlqeZo=&wQpYwUZYheUWY=&lXlvygVasdjfV=&RRzscnVencehe=&esn6UlXespnVY=&dGxuipYXWoq_f=&mY7wxhVnbaomk=&wFzQmdYbhmlf_=&3F8ZUYWXYXmms=&Z_DhEWUasXpka=&NbfZxfZdeilUg=&xCfutzVnXg_sU=&Uk_nroZgXYllj=&o3QgALYqfcXea=&eSYiHAZqVVbrX=&S3Kz5rYnVpbdW=&9xcfnpZZ_djoh=&ICP3TCXnfjhaY=&5BMib_ZmrglWs=&7QLQzwXee_lqb=&dclQy7ZnXegka=&eOttxDZbaaqdk=&MDkG2xWWgUscq=&GsrjkBUZhpbZZ=&x_9d58UrcmUYZ=&TCffRRZfklh_m=&BHNKiMUsbeg_Z=&wW57c5VUlaoeX=&XyZWr2WhrjjUl=&WmWDDtWmZlVZY=&y36z8CZdi_XZe=&hcZcnkUZeZkeo=&Nr_QfbVlenfch=&fXfrmGZblmVZ_=&9Lk9nAXhial_i=&NWntIwVgUhZab=&gv96LFVYhVoqs=&N7HVHBUdajVfs=&i2macKXnkfkdi=&PgXyI4UrXaqfX=&SNGrIIZmbnVaj=&7yN4WAZqYgqff=&wpxCVMYUlmrhh=&pDNFuPU_aggbl=&dXo7VLVirbpdc=&Unr3ZtZkkcYlj=&e2e9hvYnddjUi=&gBuonJUrcksif=&ZxoQ5NUqnYniU=&E3DcjGXq_Woio=&2sw9PBUbgYnaa=&9eQymUWdUlsdk=&ZtTfzDZZmjWcY=&aDQBciVqgshUh=&Dk2IOjXknlVlZ=&9HpeC7Yelse__=&Im29r_WdYWXqV=&ZDuIzPZblgpYZ=&bp8qluXho_VeY=&CnAGiqY_pWiri=&zlcCcOUYdalmZ=&uNYLBUWaaZlaq=&FdVurxVZ_skcm=&Znb57oVWdqqWm=&RJG8UHZWe_oge=&Gk2LavXsUVedh=&uAKtClYgXbVmg=&wnkZrfZegnlsm=&iVFU3QZo_lrko=&2RGqP9ZpYbdgo=&sJPZcaVmprsrq=&KdK8tkVdXm_lg=&XUcQp9WXfligs=&uhKxpIUcjUfag=&cUqGePXUrm_fl=&M3PcchUZpnbib=&9TVzU7VY_Yqfm=&Z6vGB9XWogrkn=&lp8GgLZVsngUW=&WzbV32ZsfedqU=>IQeJUgjpqsn=&7g4DAAVkhriZj=&xw3afsWcX_Vsd=&_e_tfHZZXdmbX=&erxky9ZpelghX=&GHoSSNZWsmgZd=&Qr3DFEYZpaWqW=&MnGNi9Uicbegg=&vtUds5WZokdko=&zoM74GXZVW_Vf=&AtMkQOYfsdsqe=&MsbhOZZdssWgk=&BNzvIpXee_Uql=&Y2TL6GYifheV_=&_pjhFZYqqYYjn=&W2WZQvYqVgcfi=&2IjFy6XVncrep=&iObfOFUlmnadV=&ZASJx6Xgijbnr=&RycNJpWamehco=&4IrVX3Zjj_mfl=&mvjL2qXjkUnfX=&go6BnGXXhjZiX=&VginLkUlimnjf=&WtB8GrZ_ckhol=&Nw4nF2WkWakok=&FeBygsWWXbbsW=&ajqnMWXaaasff=&spW2EvUpbWgiU=&OEsRKgXpsfdeW=&TTA7QqUVcaksW=&rBJIpyYm_Xasq=&BmeJM7XqmkUdZ=&N5TXw3UjX_Xdi=&uo44EYWkmWgWV=&5YZHZIYnjplYc=&OZZL6rUjUkbie=&yeYh3ZUWiWbZd=&_IelWqUdfUlUl=&bqf9mtZronUUZ=&4malrqXkscZms=&saObndZVYeVcf=&hYKsFwUbiccYa=&ChSp6bUegYUcX=&4XFLJrVrkXZrm=&mbcmgSWVibipd=&KSVsYEUoggWUc=&n5MJGcUaUme_X=&w_6jvyZbpsmXo=&L6dVbtVlekjUo=&CbT6DZUrU_Ylk=&tPWu25XZlapca=&KtzFn4Ychnhhe=&v5RTS4Vbik_hs=&SmVyW4V_VUgpe=&9jysWWXiYfVkX=&ZPSPPZZcVYhmh=&7yKDDOYrZclZp=&lRHPqQZsVcpig=&XeBkdgXUdjYYV=&x7Xy2cWsmWspn=&PW4GxFXpWWZpp=&n_x8zCWWnqqbh=&kfQ2SnWkilWeV=&efPq4TUgclscg=&jk6WIAXoXsjrn=&DyFIHiZjpYY_r=&G2MV5AV_dplor=&4h_5xVZWjfYjl=&8XIWeLZpmhhsk=&KrGO7WXbfnapj=&FYdd9_Xqc_YjY=&LddBIUZbiseYb=&Q8BBGrYhXcXYg=&glpKGlYlrcZaj=&OegFNkYbZheZX=&fUd5JPUsrYcoq=&TTbAwyUWqUjmd=&Lvvf8NWZZgVnr=&vklVvaZaUjoVg=&rGuddQVZoYYgg=&emRl6oVrrsWje=&GgkBXJVqgsnnj=&7FdDFZVpkopfq=&GLaZgPYoYjVXj=&aufaEeZcXsgdj=&5ibHSpUbrUeWs=&3GxAppZYscpqg=&d9w4nnXnjjcWV=&fiMfISWnqibjW=&YHuUg5WYonmfq=&9LMcDbZX_ekmg=&iOsg5iZisdo_X=&k6NaymVbregdh=&4PlBVoVkVZphV=&tS69qgVYqmklr=&__TDf7VjXicqn=&kuHO5uZocaYmr=&xqJFhjWl__deg=&gJEJypVpebZoe=&2mbWzfYci_skn=&BkSMx7WmXgfje=&4oiRcRUifrorp=&S2e5_5ZinqUUq=&iVZ3fGWhZZolo=&5PpmGdVVWskgg=&XVvC9WVqdseiq=&tVViS8UpWokok=&yrwl4SXUbcYVb=&sNb5vhVZormZn=&6S3nNKXqUcUqr=&dHQI6bXankknk=&G_bT5lZiflcan=&Lq8hUnYj_kbmp=&qdZJXTWioosrj=&WC8MSTWmaqUbo=&FU6mPYZocpnhe=&J6SE6RWsdXmXo=&UewM4lYmkcjrl=&plHYJbXssemYX=&LAhsUjXUWWmgf=&VYhybhUiomdnp=&6Az_WpZeWYmcf=&mrihEAZqYcmiW=&ssI9DsVjnXgZj=&WDWaUhUlfdfsf=&eoZiedXonfocU=&BBVsYpXUlXnYb=&wtrVLoZYospar=&B69eDDZr_WVaU=&ftq92cUbUmnqi=&fFxgjLVr_apVo=&MoqmVhYsbonWZ=&jcVRbRXrdisVa=&8rY6ZXZbboeqp=&5zkF2rWjfZppa=&xlxweBUo_VUqW=&DFhXEBZkrZhqk=&vL96wsVlU_aoW=&zFtfdbWpfdkWY=&oDZKkFUcsmWYe=&9dy3AJUXcdYl_=&PmzMBLWhZbrgb=&5Lm_RIUXeqjrq=&n7K3qjYinffkq=&DkzWDvZUjrVhe=&wXd82dUrpWmkc=&PvmNecV_UrZdo=&NGkDMDXfZZcdr=&gqhkb_Wogbfar=&kyEDsMXZVksin=&AhhaotXifhlfl=&rSIu59ZpVadjr=&j64PqXXeerosg=&HWwMPjZaodUbb=&OJuZ6NUmqZrUV=&B3UoFzWVXgqYo=&LwUSWFUZVjelr=&pPQ5JaZlnp_oY=&jVD_INVnVXYah=&_TvbktXVXdbkW=&vyTRLgVkn_bYs=&gFei4nUbjikld=&n3lQTwXmpUdnk=&M4lyucVhZhVek=&imirwbZnrcXgf=&9x2NqvVbiVogk=&XQ23ZeWljeZYn=&SwRCpzYfl_aZr=&PccJRaVbUiemk=&Nkv9FzY_Uqpdd=&jqGjVzYefiWqq=&ntaK7yYesb_ai=&VTotmHWqeUcpo=&tpvdfYUmfkmip=&lcucw2WeeWXpr=&kQU3LUZaVcobn=&j3ekWSXXgiemo=&wdKeZHXVrZbcV=&rCivarWd_gU_h=&v5y_HtWdoojsa=&w7GxBNXXsedsX=&VgsOenZrUoqgX=&dk8ZJhYhWYZnf=&SJKKJpXpYjldX=&98DRkwYoiejXs=&6yRDbgXkYseWs=&pHQSZYXmkZrZ_=&3vAHZgVkdmUYs=&KDAojDZpokpYV=&pIYHS3ZZobmks=&jbLNXFZeYfale=&tKfhvHVqbghUr=&RnBKHvWr_aiVW=&sIxwLcYkZYmeo=&PoKEIjZqdsela=&WvrjopZXjsWik=&szHDXlW_fZWi_=&7Mo5KzZpccjgX=&E7suKJYaseXsb=&QHHaLeXmZbbrp=&pSumCtZZgUbUg=&hBSthJXgehlqn=&QLjFKLVnYbkoW=&kFPeyLVXa_ioc=&w3Mh46VpnYXVV=&TBO2JTUUZaapk=&HT7EmqWWdifja=&SarocfXYpWeoZ=&SSK_bKWjqUqnk=&iDjVjMXUraXog=&snTwKRV_jYodl=&5L6EWFZeinqWe=&9e73v5UsleZdb=&FLkC4ZWhgbjpp=&H2Ac2JYokdfoV=&I7UtMwZihYXmf=&bgoDrrXcgnobY=&jYqxQHZXaeUma=&7i5BBUYdcYihl=&yCqTBQZcepUVk=&sDVx7mZWeXnmr=&tn5vSbUsjicdb=&B4GVWsVogmqch=&4J_cEUUUYZgom=&cWasAEZmoispn=&l3aI22VmkUffj=&3tY9KtZkhqgsj=&rFnq4xYbdYnrW=&TG5_NSZbYsqmZ=&XH5n7OYnZmrfW=&ERQapGXhblmoj=&a3PeNQYmqWiod=&bY6FJaWZUVZfh=&vvKV4HViogsn_=&8cUxvaZWjbkgd=&fDDnV3XiZdcXo=&sAMyH2Wd_jbVj=&M2rGapYcnqdXd=&VnSkPeXdfdiee=&C9yCy7UVVeUYl=&quwkGEWsfoUaa=&GaoH8VUqclmlo=&FCU8C8VV_fbVj=&ywN6pNZcVWrWm=&tfC9sgYgaWXVX=&8F8bmfYjUYeUp=&nFmN4WYqYcblb=&U4OBQIXVlmoVj=&H5cWtHZjfjlmd=&3ZhdZjWmomVlW=&RWwngoYi_b_se=&eu4zkYW_qofsq=&xCvLEXVUccpmj=&NwYx8zVpfrrXp=&bEkqiFZlkh_hX=&8ZW6egWicrYbg=&_fCZVOWjpUdrW=&fUZulZZnZrlUg=&ZISWRjUUskcVp=&6vyvPrWVgqloe=&wT3duDYpokWpc=&OqMkbxWceccri=&vvmpcMWcg_acm=&WmgDXXZWWjakg=&2NEJjgYm_rXel=&EcgXuEYgWYsYo=&vLEBjWXsXqcYd=&2Sn3yPWnnkinp=&ddYctqVrncndh=&qZfpZSYYrppWk=&UZdl8CUejjXhr=&jBqJKRZXsVc_o=&PheDvrYhfrfgi=&4zDXsHVpmlcqp=&uaW3yNYdfnlZX=&DC8Xs8Wrcqemo=&slN9clWhWobhV=&gG7bkmZWUrcig=&2UhefHWislYgU=&ryfeBMYUZaYqf=&cIG7G5YqXUqbd=&b8PPavYdmVWsU=&WVIrjzZZdpsXc=&nADRv4Zihmqqm=&44oAekViUbafW=&veKPjuZWVehqn=&FpFiTSYsXslZi=&EkvKymYVsUrcY=&PhKRP3VanjgYU=&3YBhC9UchgiWW=&t9qL3nXXcajgp=&MafVISYWrgrfo=&_HHFJNYnUjqom=&qnSXmXZjkefnY=&AntaPfZrpnfpj=&E7jbkAVqeokpd=&DfsIARYije_iX=&Ik7NKxZZeldcf=&CRAhjFUfsZhVr=&9GKY9SVm_rVjn=&tRrsxNUfdojij=&jRmtLWVVnmqjl=&6W5n8SYqnfhWn=&5yNhgXYZgYiXk=&2ObMIjUgjVkoe=&KQioHmWslsqjg=&3RTcFsVhgqZUl=&pTfIgJVddreUp=&XLW5UEZjYWhdf=&tzH6eVVdafqpq=&4Ye8fxXlkgeWf=&Y7WAjZXfnXbmU=&M5IklnXkaqebf=&wKNCO4WlejZrZ=&tmJL2bZomWbce=&w7k5PHYjaU_VX=&SbBJqRYYYaeXm=&JTJSQ4UgorqVj=&Y2Son3YU_arrr=&62_gp5ZbabpVr=&wTclIOW_XbbXn=&QKRqaWZbmncZi=&lv2fVJWWleadh=&ElvhbCWbUrakf=&xXl466XmXlWma=&4mxD3aWhprX_g=&fxQsfUXobgfeX=&tFlyCFUpfmfaY=&daE_fXUriegsh=&EydoVvZgYUqfW=&4ibWwyZo_hosh=&ryLFWfVWhrrWZ=&ZlpgGuXeXXUXa=&Gx6X5SVhhilse=&Q6fmUJUmqoZne=&7YXPIDWgmjeWn=&gkj8uDZqqknYW=&lrBrk8YedkWjc=&Htv7kqViiZUlh=&suMjC4Vjgsnfb=&6zhCbRWUicUZf=&fMXCXDYUYomqn=&n3ROs9YrVplir=&FWGzt_WloUccd=&o9rHl9Ysgbalg=&fFLjMjXhrsach=&hF69R8YVccokZ=&KblvEYWgaoWka=&qKZUIaZprYZZd=&CxI3B8XhYcghj=&rr2k5gWg_cb_V=&BalbWZUsms_ri=&neCIdNUiUasgU=&KG6NfIVcihqlX=&ghzOsiZoXZYim=&cMK_TcUs_kfal=&VCA8ZGWgUYmdV=&9ImLwSUYgggik=&MZ3AFsWchWWgm=&aj4TUPZmnWVhl=&iboPlvXhUhakk=&4N_F2zWhhl_rk=&SmsOd_WcXZlZg=&PiqO6eXnrcghh=&4wBUEmZdbYci_=&MXh9HwWpiohgc=&OI4f4cZlWhXii=&CLJubXYmcpYWc=&zqLlQQXgrfqbe=&F2Y3WeVgZdUpd=&PIKLBoXbiYndq=&ThjG5kYfq_Ymp=&stU9J6XUVUcVZ=&cyLkaZYjemUXd=&dAYgzgVWcjWnq=&bNfqTAUXVpamg=&8d74YUYreohsm=&29ZhY2UhhseUV=&T2v9DiZZsVrn_=&5oQJMSZdYebqX=&84gxi7Wksqeqs=&SMG7ngYch_pVd=&_nI4LTYXs_ZWd=&rAN4o4VdbUesc=&iauf7sVUVeebj=&H3muvvYjbZlbl=&Mj7TsxW_ZnlZc=&WKQVpRVWafVsX=&Bnjr4vWsopZXk=&vm7hkmUsgZm_g=&9Q6lD5YhYgpqW=&umaaQ3YlZkXee=&W5jT4RYo_gqUb=&3OGwJKXrkjqds=&5TYThSUeqUjaj=&oBCPZkWpkUebk=&Jo3hd8YrlkW_h=&oGi9epY_YnbsY=&RLoFa6XdUUpso=&bpnNqyZqkcoYi=&GNbVWQZUfsWll=&XWMWA3Z_bWsea=&5dbxKmVaeUYUX=&_ili6SVVpraih=&hySVubWZddnjZ=&VLn5FgWijsYsm=&fvuJhoVhVajmf=&ze8s73Vajgomb=&kC9QyWVejfbrc=&jYutu2XUedjpg=&YFQzeaWYYbYlj=&BHQ__mUosdl_Z=&_YMOI5XbdUlar=&nh5OUmWl_Ueam=&XFFQYbWXnViVr=&SiGQVsVcb_nYl=&jToAqzYsgcXVs=&cRaPwNXsXahnY=&fmF5YTXUbUrir=&wzENrsZYWfqcg=&v_z6K6VWU_Yie=&U7GzM_Zeriglh=&P5nOEwUe_ps__=&ubXM9qVmrVUic=&nDekJFZohU_cX=&yaEuBEUrnfXas=&FhSSQ5WrjYajs=&RgIEfOYcfnZlX=&guuTW_VXZidnj=&I675iQYjbjcjm=&Z5GospZdkUqqn=&OvXhlmWaeWncc=&MNar4LWrbe_be=&FYkEIKUn_Zjna=&Z7DzzhWdkUrZZ=&_DYzT7ZfU_omW=&jw4_32XnjZ_me=&JDIOJyZYXiXYZ=&Ixh7pcVWUalmY=&KwdyGKZpimajb=&DPmnDRZZhoUah=&icdzryVifgXXe=&3XXNx_UYUqZoq=&8R7QB7VooaVXp=&adlyQnXXkWrcd=&yz4TO9ZhmjpXX=&68AyXzZa_jdVZ=&SUZJLkWlhsmmk=&FHuLsKYYnqVld=&dPlgI2WrXWasV=&PevFnyZViXddU=&Yvo9sRWjYWUlh=&mrZqycWYeelaW=&rvieawUoajiis=&q9XuasZkfpgmr=&4b8akIXenZmXs=&gz3EGAZpkYogU=&UPkJ2sXmaXoWi=&s8dfZTVekUpjn=&ZdBWHRWrrmmbn=&IuJkXHYnXkqdr=&NEaSbSZWZ_Zea=&bWFJqpXbcYeiV=&gTWgXtWXeloVb=&JQpkVsXhqinUh=&TGKtDmWfYrkWs=&hBB5QVUrsniid=&tFtGToXjVskca=&6XZs3HZXgY_ql=&BzFfU9VaXjsee=&QQ3Ge9Yadmqgi=&cbPCwmZXUYrcU=&8IhCXxVqolaVs=&veT9rnYjWdsbW=&VldOivVYiejfc=&VnX7LZVVdaiqd=&FjDWDqXXXfdqY=&lyeXOCYeUYlZl=&RHPgE5Yoajamb=&UBar4gWkXYgWp=&_bNqb2Ukk_oYd=&wXaST4YilqrjZ=&WP5sLtXfkdVcm=&xfp9vYYmsjisi=&B34oinVUorlkl=&GExPsmXZobdgb=&FQtNjsVZasXbh=&ztBCXmZkWYaUq=&U6QfQiU_gZlsl=&UwPuyNZjYsgpi=&5alDqgWrjVWcg=&XYBwK5VcZmhas=&UEKSriZcYjpob=&VJQwYnXZUfh_s=&ZcSqyKVrrqWh_=&_YPDSDWndgWie=&C5maBrVppdXdj=&AX8QmKVVmlp_V=&yHbB6rWXsa_cX=&yVxOHLXqrfhqh=&vupS4tYZjX__k=&tinnSkZklYiea=&8yVoj9WmipqgV=&26WpcXZbXnpWq=&Sh3_V8WiUjV_m=&ZS3Al2YkcpUfW=&Vs_LO4XWkXppU=&o9DIIGWVWjqmU=&jKD6xLWUnifVj=&brg2QHVmkVWcZ=&brsMsaXnjYVab=&fnAxCGWncriXr=&cTYPkeYsggqin=&iWWYnNWeXeZZe=&vEFcOrXXYhgar=&uN7QMiUVrqmZV=&SPCivhVs_kWlm=&oDcvQtZqnmqYc=&jvOiyPYYssg_o=&oJkt9rYpogimj=&NvoPhWUrfZ_jn=&ipyrpjWskhppm=&BuEtc7Vlccklg=&nKrLtDWcXZrkh=&rYRHdHWWnYdeg=&7ZbWOwYWbpkhc=&5eGxf5ZWcmaeU=&IcBAQHVfWVk_m=&3PAXpZXjiYdsi=&3QqNHbV_rgUqi=&vYta2jZscVXXn=&SeMOOAZkmWnlY=&FOOTYzZ_afqpr=&iPAVwlUUdpVhi=&i2TYVEYdc__ji=&jKpNcwXWsonqk=&emmmyxVanpdmW=&qSa_shUrrgfsn=&jA73CDUamffmZ=&k75MBMXfYYhVe=&GwcFwSZeraefd=&Mv9cTTUspkbei=&yGDMUYWrmdUpb=&zTfLeRZVaedad=&RgouBIVcdi_ap=&5FQsZpYfoZn_l=&_joQKTXlkWqnm=&rJhAewUfbcijp=&H4u2Z3XUkodle=&Z8lnfzYhWXiZo=&VivoNFWXjlUco=&7RRemgUkWXbpg=&CJ3quXZssgf_h=&mdXJudUlXUrZn=&2FEaa8Wkpd_gq=&JQrAXhYjs_VrY=&UCj9tUYcmoikf=&ZAiqlrVhcqhX_=&sAhlXLVrVWrlW=&2sg7XHVYeeVai=&OYB_fGXYUcfkV=&OjzpsRVjfd_sp=&ZccE48Xisklhn=&af6OtfZVnipbs=&8Hh5rfUZXokhd=&odI3bGXfYpmWm=&VmjHi6VmYeksg=&rQdLCcWhcUZak=&RHea6OXYkekXm=&duFVpgXdksgon=&2q5vZgWear_nU=&pwWhYeWisYgUd=&8lVFdtXUsnfoo=&BtdRP9YoUsVjk=&dJfQivZeiaoVb=&U64K29ZdWahdi=&vlhaTrXasnjqr=&NmmUMKVlsVrrX=&z6TbJXXUbXeVV=&TvOlmVUVbid_e=&J7Yje_VbV_djm=&fXvWnXZ_sYloe=&dlzwZ3Udecn_V=&iUVcCTUbbcdq_=&TKt7BQVafeV_V=&PSvvrzZXohcpi=&DdCb7eUnZgaYe=&Ay4vMTUhYbcXl=&iZLK4xXfefYfj=&VIbQa2XkhaWoq=&F3D8YFUmZraXo=&obSSHhUednsnb=&T2f84EVUZgVgX=&Wt9RU5Unjpfen=&KpTCBKZgoq_ho=&Sz5NEvXhoakeg=&_6oUUBUZbZsq_=&YLaM_oX_daas_=&y3eK_lWWUY_mY=&CZLFgLZr_ipsU=&8CeHPyXmXVgYV=&wr4SZtYak_hce=&Lavkv6ZdkYmWf=&4IvNp7Yi__Zgk=&s8HYdhUdZaWsf=&GVTzqEVqgpZXe=&vjZn_2Z_dW_es=&x8TtneZbirdca=&HZlzZRWWpXf_s=&R9qwTVYbX_ijZ=&IWhoJIVgqkibr=&AW6pOvXieoXZn=&IPRWSPUqYemec=&bNtScSWdVeoln=&pfHnRxVsW_o_q=&6WVoRTVsVkhVV=&cPQpucVaYoWig=&MHHVBOXdeVqhd=&68Id2cYWcpVb_=&omuyOzVolehgX=&zNgPyUUXefZeb=&ouG49oYgWghmf=&CoBf4OUrkp_Ya=&YQdXvUWfXrgdk=&JoVITJZoqshh_=&DVJID2WgokpWl=&dMkgjTVmdanap=&WQ72UuYgpdZqh=&EDuSUpWooXagY=&cZUCDHYefrUrX=&OA3oA7XgqbXfl=&EQ4oGNZlphjYa=&SpDye4WhhZYaf=&kCaYctVqUsYWr=&dPGUhdZYVeXhn=&UrrFmoYhmcjbj=&l5lvcQYqXgbnn=&R5xpAuZZZVlaZ=&cGFP44VUar_aZ=&bh3HUGUVklcoU=&GlGrmGWXbiqpk=&PaxAlSVjfalWU=&GpJHLAUrdqiqh=&9dhZslYfUiirZ=&UQQ4isYqVeerW=&SO2OUKUWfVgXl=&wjkxBiZprfhcf=&Hjhal6U_hsVXV=&dGaRmiZfUmsgb=&6m7WY3UWYafp_=&XKScPcVkihbVX=&TiPvHDYpbsdnc=&UcSgxQXhmYklr=&wb_FiRY_faWgf=&PFo7PXUhUVdo_=&HU6i7GYgUZnfU=&Ayx9jPWsXdcpn=&C5UuutYbgboqq=&FRQlZaWcpogjV=&IMtjCYYmVlZUo=&vEYiUJXUYjoiV=&GcMRs_WgpaWhY=&2fjbpTUaXcnl_=&7KBdq_WiWceXo=&ikA45pVYlcZgq=&6xA2sSUhjdkgV=&BsdJQUXdcnojg=&oWaeC4ZakdecU=&S96yArUYkUgVq=&ZMSanLVcWqZpV=&wLqx3kWcXrfbp=&Zyf9o5YXjYser=&B4PszTXmjnZYa=&_Mw6VFZZk_jgh=&ktF8sdViVfiZZ=&qj8oszXmaogbo=&RhUM7CVmggkdd=&CaRVHOYnir__a=&hueiGBWpgZcUd=&BKreXkUZdhqrs=&WfoG5NZZgkfsk=&DvSLL6VWeemil=&VDN3JhWob_jUk=&yTDQMAXlbrVUY=&zNHv97Ysplrig=&3OD3ofZYsZVUa=&khzF7fZUbjiYe=&QnkvCYVfmaWmr=&qgcZ5XWrYdWng=&af8NDPWkfaqZY=&3dPZdhXoraUpZ=&sKokzcYhjndoU=&dyjFNRZfYomos=&kCNYpPWecbmpm=&ciD5EwUa_oVmV=&ED4Xp5YdbXW_k=&gnUUwBVgdUldf=&IDRMDoUroqhWi=&IYZjopYdmkkYr=&z3EqMaXfXYcqp=&WoCIfNUdddb_l=&lhGLkAYemUpUj=&P56_9AV_Vdgff=&4r4eRUVmfpcZd=&kdNRjsW_fbpqe=&fw4SToUdfWsgY=&96M4JkWXpaZqh=&aoar7uWrbdiXc=&YETb8FXYUaYZp=&u_uVazZlafUdd=&7gpJMZXXXilWm=&G9HTaIUkseqne=&jDH9rEXi__fVY=&uOygxTVWUrYhk=&Ul3QFaWioiogn=&fB7YvLXfebWce=&EG7g8tXYeUebV=&QyKuVaVddsqbe=&SRZWztYi_ZicU=&WxBTSKZdqcZsZ=&Wl8De7V_ZrWpg=&dOHDKQVYcrebV=&vZ6HefVUZjn_q=&ATpyXeZoiaWqj=&FdK6nnUhnWYqW=&5IHs5bZnUseZm=&jFkWTKXYmfhnY=&tVRWjmYYcYf_s=&ytE5HCUZafirs=&Rw8mnuUeXnkka=&H_zddIYnUbcsr=&7pfBUSUYXfUoY=&Kioev5UYliVkc=&ipTJfoU_flpkk=&N3F6vvUorjchf=&h_EwAOXbgXqmh=&CuyDUQWiagoqm=&5xLanLWimrmXr=&JUoA28Uaecrpe=&NLjpWqZcWlaeZ=&l_pkrPXXVZhkm=&JIvwwjWomssVn=&mHGM9hUkWkj_i=&SDvYf5Vhdd_o_=&iGMKSxXknYXgh=&cQTVPwXWehpfi=&tOEvfDYnsVbke=&NhitwpYcafnVo=&qMEQRhZdgoesX=&DBqRZpYj_mfjr=&FO8_HOV_hVZsa=&ybUbzuUaadqhq=&wOXQXnWfUZZmh=&O68ePAYioqgak=&ItgldrVUeghZk=&FXuP8ZXXmjdeg=&YqFiZSXsVlcWs=&DFnTKxUgr_Yrg=&bbhQykVesqffb=&oeWxmbVplrhge=&buhKtBYpXWhbn=&kfZaBBZkXUofa=&CNpIUSVmsckYq=&YIkq_4WinaraY=&A653yUWqlUdem=&bEwEEZYeUbdaV=&LMFSBqXfYhbse=&fpygAKXbdrprV=&Y98PpHZqgsZbU=&GVLjaLXgjXZXm=&6pG2UCXhbslbd=&prV2z_UibsUWd=&9AF_ZcUhUon_b=&i2EJCfWnZWaXV=&JJxKG5X_mq_rY=&nyoqxfWZalnod=&zmBy3VXUfZ_ng=&omh5OEViYs_pY=&c8BYPqWWaUZkl=&7TDqBZYhkggZZ=&hOpszPWnWeemg=&uZ8pSVXdhYdXk=&Ct94JNXZnrmjm=&WzUcEwYj_reok=&bjpulMXlcbomY=&bKIhZZYfqrcZg=&6B4l_7YbYcppi=&4_sRYVYjg__jU=&iYCdkLZenWaqp=&Oh7ivJWlWclXf=&AMdpKXXnsnjio=&ZYl4vVXYbbllb=&PWKlgcZmZhWfn=&fFFY6NUkYapZm=&PIrqpSWYYarfs=&kGQHTPUcegWgi=&cBsrRWUmmnrfj=&DvJQfOW_ghdop=&Uxn_GrZUrf_oX=&dE4xnBVlickg_=&KzoLx8UUZsapn=&fsgPI9XbXWgWY=&ciRAnmXpXbZsi=&52PWnOXZZdedj=&m8ZUy2Xn_Xdjn=&SX2ZixVrrkinp=&JXQPqbWpimYqm=&aqIGU2VjqsihZ=&A3MpveXkon_gX=&bNgKcwZ_Wrdjd=&RTbVTYUcqcmai=&xmSgWeYVpie_a=&992ch9ZaffkXp=&HUioEIXWnrfcq=&L8FaoNUjoYjdY=&fbe7tWUlscZnf=&DxjL5HXpdXcbn=&wLHzpkZaa_mdX=&39pFUUYiaY_rq=&l7GqmiXcZeclj=&XKsm4uZacdjlr=&M6WCFKYkgkXeW=&mchtO3X_kqedl=&GjPNmWZb_lhm_=&UVxrSHZoXkVWs=&lft7R2WWhs_UX=&g8p8jrYkYZYnc=&mrNwUcWiYZehl=&9aHZYmVbZcWag=&_cyD5xXbipcmg=&2M4VClUWXlccV=&HKrZ3xUcgsUbq=&rTNP6VVY_qchX=&XvSHDcXmUjjnZ=&tEo4f3XhhrYig=&Vyv3T4ZVYfVhU=&dqxQwTZljmWid=&iXB_DhXiXXofr=&vtqqcMVadbZYj=&jsbVLoWdUskWq=&x2mjoZUqjWcVX=&33SBEQXccpmjj=&SA9ALRUcjgW_i=&g_ixKOYhkkcsd=&Cj4V3lWlghbYi=&dRmnKiXqcWbqc=&duHjqpVZnmpnm=&cgmWRqXihZkqp=&iUEquCWjhVlaV=&tZtaPAVgkZ_hg=&qiVA8XZrWhehi=&wbFlh6ZafjWUb=&W85uPCZahigYh=&VM9mMRVnbprge=&I8mbPwXUXmYig=&QrPY82XlkVnds=&ywk7HiWdcfadX=&PFAUpsXjhfZjg=&XJPg4NZXWgejp=&gCxmADYUXlkZm=&ugjSjWUrogqek=&fWV6jcUbjbZhW=&XaaoNVWgcnVhf=&fbYx47UmlgZdU=&bkyhMyYqfYhlm=&dLX8jMUjXZkn_=&VtN3NrXkpUdeZ=&kl7KPVUgqeYoq=&JyTOfzWZYVbsi=&46zyUiWeanlqo=&UAu4EQZncXWil=&oJiVcDZefdZYk=&QtAhnhYfZsgeb=&YZQVjXYg_gkmf=&fsu_KmYmnkdgg=&BACalyVWpYnXX=&DsMkSZWjrWiro=&OufgoiVWgpdlm=&zy494fVrocdlh=&tqQc6FZaioWkZ=&6iJ4uuW_hqspe=&nb2c5cUUUscZb=&SicGdvVYYrhoi=&SdkiW3UUfjlqn=&4J8P9mYrppkWa=&k_GznqYsfhmYl=&GMQzcgXdjem_f=&C_irb8ZsckWih=&vc6PsFZkUkVhm=&gX4_qrXWqrYhf=&2ycRVvUeharbi=&5FVFx4Ygerrjj=&6Kvw2BVkqioUs=&jxwUBTYXkUfUp=&r3peZXXhmVoYq=&gqCzVvWUWUUqs=&OPSDYDWhYdUqo=&RLWuQaXYX_hhj=&T4vAp6Woeqplk=&cwS_lzZXYZYiW=&Jr5EOOYnshlgW=&Bnl9rsUlddmca=&3F3CKEUrfrjXn=&psovYRZYlegYg=&ezCsTTXXZmcjY=&5dZqUUWlcgYmm=&nlue5gZnUZrde=&72s7huYrpfmpX=&Z9oBNXYZ_dVbh=&9KJYfSXkZed_a=&YmpauMYfgUUb_=&M4LutWVUlagrl=&OBaQgAWebc_pW=&FfkCT3ZXZrfXY=&Y5aVsmYrZlmbe=&wEZVzUVingYeW=&ejRTKlWZsnflf=&9RmMXWUifaWis=&FfWQAOYjclfoe=&DRCZoxUrqnXak=&U4cTFyXccnbUf=&UnaJdMUlkhjcr=&grNb73UYaXgir=&qCUwvBWYUrZqp=&hjgxqdVgaXqne=&zmIUslYajdghU=&67GLuzXpZXpZe=&NlLefWYkUZblc=&WUw27wUnonVbW=&6jhXhWVk_ZcUo=&Bbu2X_Uick_Up=&BgvCJrWnYppZl=&fk2BH_VaoVXee=&eivl5FXpjsYmZ=&3RphJ5Zbajkdf=&Uit_I6ZlaYjgm=&TLuWHDYfcdVYa=&G8N6H9VaqVUon=&B6KSU9WjWYfYb=&2UC6MiYpilfii=&nebw35Xemddem=&4CmOo4VVpc_ae=&4GCH4CVahcnYr=&P6SgzWZicdcsq=&GfMYQUWdnnjdp=&9_MCouVrrVd_W=&Y4Hsx9ZbdXZUX=&hAgaS6WieWioZ=&_lGp6HWWqfbpe=&psfmMEUeqjhYV=&gpJVunUWgbWZh=&HEehMoZZriYoi=&UczIxiYhhkbbZ=&ZDfp4DZVkn_mk=&UNlhTvXdjekfs=&wAcRyyYqqVelW=&iun3bBVfacbni=&TBeZ4zVkjdlrX=&r3JIoLV_ncmpX=&eSPhVrWUgehVf=&XVFbkfX_YWfjX=&jJgLH3ZVfYpYb=&EFms3QYcUqdgh=&u7hDtjWsfioki=&L6gvtwWYWaqhY=&YGLLL_Wblff_Y=&S4woQwXUesjga=&cfcZPxZXnhheq=&DgHHh2Vb_Xccl=&sCtfBpZpssVcm=&EfTFYBWdkXUmh=&uMGOv2Zpj_kka=&w3a7xEZWYnddk=&BaUb4fYlhcVgW=&w64NQXZYVflkh=&J6xmqRXiaiWge=&6iDGgYVeUjiol=&FYIc59UsfkWVm=&9KQgqUUlZqqps=&3LLoCeZdklmUk=&Tdanj6Y__fpmm=&X6jh9VWXdXjhf=&FzDIpLZWcejjn=&4oUOy4ZYgjkgh=&joOlHVZfoZ_qs=&ETOh2BUefVUZW=&YVxSmHYogYngn=&LyQ2fwVVqaUXl=&Qowh3jZVfjkYn=&abY_vdZmZgehr=&QasbaSVUYUprh=&eQX2hEZl_cqac=&gYZot3ZZVUcso=&xRwQJ6VdUgniU=&trjEkdVcmhUZY=&EFpPnlWZUogfU=&teY4pMVZafgfk=&jhTnzrVWocemg=&Wed85OVrrabba=&ccRguGUalgZYg=&qmV73JZqqs_pX=&zT93DkZUrWgcq=&UQTVzxYgcUqpU=&x4riFnXqYmUZg=&fFrRS2Xp_kZbe=&7McAMeUeZVpmo=&9ST94zVoUhdpW=&vYp4pvXdpiYZm=&UYmmnXZgbeWab=&5uELaRYXWfsWd=&FWU2u4UUjcngY=&DISPkeXesacXf=&LazFotUWZV_po=&j5S2jKX_Vekcs=&r7TqWvYsdjheX=&O5GtNDY_oUleh=&RSZB6AYlZncdV=&z9JNFjWYrcZVp=&eGeanUUejdeae=&9NxUWoZYqggse=&dHKL_IXei_khi=&xrMnIiYlhldjr=&m9keNNZepbrYd=&5Yz9xHXegonVj=&e3jWW9UYbVdWb=&P6yNVLZskoZWe=&wqM8ISVr_n_dY=&YOWRV3UsgcWXc=&iBGp9uVoWqbnW=&IMUTjkUfnZboh=&B5DtmmZhjViao=&H7c8jbYfUYrqf=&CQ7jv4Vsknoak=&uNPmQJYqcjUl_=&_MDHilZdVWaXq=&Sab5pYZWgXhoY=&lVQfIBUincbsl=&hRWNc_WlmrdWd=&4eTT7QXVopmZq=&pSqmddXle_lmh=&CgydkfZijahbd=&gXlVVaUqrrdme=&mzHq_4Xp_gbps=&2OrT7pZcbWkej=&wUAulOVlrq_pU=&fHPZTrVhXWjVa=&5Cm_KVZZsriid=&Sb7voCWceeXfV=&T_55WLUdp_ena=&nYcx__UYferkV=&C3QWAvZscndhm=&wslaXdWq_ndie=&wNhYHeWg_qjmd=&Tt2Dk8WXkadYe=&ScW__LWWh_bVj=&eqLi_2XXmirYY=&jo4fpSXVmZWYa=&fCo_VbUWfapii=&7KVCiIYinqe_h=&FTMLEPVn_mopY=&iQspESZkmprra=&rDguc6Xnkdq_j=&MCzLlwXlpXeim=&OdXPpRWmogfiZ=&tZo6mYXfhalao=&AKMoTNYsdrXsc=&bSeoEtVjrklch=&QAeY3OZhlnnZV=&5Kt5TmVbYjXgV=&BHHMdzWUsecmU=&FnIPlBZmfkmYc=&8AriDbZZpqgcU=&78pC6iYjWsdU_=&VL2UHFZekjrir=&petuMrWafV_Zj=&EAQE5ZWYWgaZZ=&ofhezMWpfprrd=&3RIoMQYrsoVoq=&Kei2GEUZddYoV=&uDzhWOZgcsUsj=&Cjje5IY_WXpip=&yLNp6yZpbmZle=&YP4D7mVd_aoia=&kIyQMdZbajYZY=&3owXF3WmaXrdc=&KX_ltSZgWhZUl=&En7VspUknpWmm=&zYqQPHYffebd_=&M25Y5IWgccdfi=&w2OROWZqhYihg=&9kS6ExZZ_ibpZ=&x6pDJ7VVocbdo=&NLAPVLZ__o_l_=&exWFmcWYh_qke=&lCEjutUcsWjol=&NBGv8XUlhXk_X=&NjEcvoUVYpsgY=&jN_eW7VsbZsdj=&34zrOeVaofWYm=&5rs7xLVha_Wdl=&XvFtFcZmahrbm=&5M6VmFZffrkZr=&a6MPyuUoXdpjn=&bpXLBNWpknZoY=&xzBzwzUkfjnps=&wf5hF4ZnjkmZl=&6lamx9VYYYZag=&DbVT2HZnVfinU=&vNqUBuYsommaU=&uoRaLtUmnWlbb=&pLOdYwYpkXWqg=&NNhiFdYsiglch=&DZHxKpWeUXfaq=&AGwkWfZYdZf_q=&eGxsZSV_pWeni=&VtZgaKYnVUZnW=&GFgO3DUoYpqYk=&z33jltZpnbYsV=&99x2_zYnoXnji=&qmKgJhVforgc_=&LOPnhIVebVbfc=&WKVn95UZZshme=&etESuJZdqggqV=&qq25HpVmfVkkl=&3JkZuIWrgqsdj=&OFQvACWplXiaU=&45i7kHU_amgcX=&4CxWraUqdXeVX=&IqTGiKWoZZbUb=&IprLjnWsdkZdl=&8OWX8DXaYp_on=&FldrY_Viordci=&s2BbVSXqqefif=&SojutuZrUVsrZ=&zfSCPNYcrXdgg=&onTMnnWZedqor=&sU6k46WrkUZqo=&xAKvJgVVloebk=&qCzDxqVkfUilV=&39N7XcXVqZ_qm=&tLt6gfWZdiko_=&lMhNaPVjrrsUf=&YDmGV9XpZ_sUa=&F5TjgRUdmlXVV=&v7dFFLYbmhcgk=&jkiDU_Zdosnmm=&lDGS7TXhYmorb=&XrGYrkXkbaUok=&umA2gLWjbZojn=&NVyB5yWYcrehc=&DIMJEhXfqcrYf=&OgxO4MWrfqmhc=&h_Us3oVilhhfX=&LtQiikUWjmikc=&cBlPQIYfZeYdX=&BlXl7LUooVjbf=&sT4tSSWaZpicU=&75fBISXhhWhod=&hQmvG5Y_bhrVj=&rGBt9AUZdqofr=&cK_nC4VYWqlYl=&MzfEzYWbckcbW=&zRPMkdZhlclmn=&Ds7_88VZUbYoX=&RZaUfOUbYslhb=&ckw4nNZnmiffo=&Z2lANhV_pYaYk=&O6HsQfXbXjsWa=&5gkro6UlmlfZd=&7Z4drlVojihri=&H6lu96XjUinms=&O2o8XvY_m_pdp=&mSfqEbYbmWfrg=&Er9vbIUUhcbqU=&beaSnuXaokm_m=&9p6C6fVmloYbq=&S6haHWYWjpaW_=&Op5NGuUYVbrZZ=&ammX7kWjlqojX=&UeeTmJWkjhVVh=&hfzCLOYcjYhsh=&RMMeAcUlcilaa=&DEv8ieWjfghns=&G8DWO7VnasUsn=&3CZW3WZa_iojW=&67M8sTYkYfifc=&Mx6Q9UVbnsanZ=&BFPTZwZgclXgd=&nUteHUXkpprXX=&ZeGSOEXbqrmbg=&a3n2tkXYnUbfs=&CSsyCsUfYoYsa=&l7jcIsWccZdbi=&_88j8UUVlosl_=&wL5BkDVfnp_Ya=&SvoySQUVlecc_=&dS6Y2ZVnUhgbZ=&8uwHpaUWXaWjW=&GJ9ciCYYY_hkj=&SsX8L3XepqVXq=&J3yfCLYrXnZXf=&aZoeNrVqrjfrl=&QJghIzVXXYied=&7HYajaVlnofXs=&nDIbcLUneW_om=&Ho5CrhWYsVZXh=&DdE_EZZqajfps=&6MT5eDXamqfjb=&2JhDXTWrrchlZ=&NIQa77ZeUdnhY=&HyKhCJWXiVipd=&bZ3iPkVXdhZWf=&9t2dW5YYmfbie=&DBsvMIXqXpVVh=&rBdgrGVmdkgkd=&eFj3jgUjZigZX=&GzJSyQYWisdYk=&wHlWWpZfVgnlj=&rAilyOWVVmoen=&5Hi9m3UXZknir=&xQxnYYUqoVsYr=&7_pvWPZhWlcXY=&euCaywVhcUdfl=&7DeVZGXsUisfg=&XIJcZfXXdpl_o=&Q86c59Ynirabq=&ajHQoKVqqqrgX=&pI2nCyVkadodr=&nwqSM4ZiVhnsr=&bwKE4wZ_UZqin=&UKlDvZYVibqXi=&9XpTHyUU_slUk=&eNIRVbUgkUYXs=&cRzNVQUaggjrl=&SIjdC9VeebhUY=&rqFVdKUesrafd=&ZnxenvYdaqlfX=&U7e8oAZgsUjbh=&kKGVeOYnUaVZX=&FbwCmYVbcjdhe=&2V_R3nYosZbbi=&3R2oWKZWUbZga=&Y5qEzAXfiYVaZ=&GVbcIgWlqYoZp=&GDNFslZYmWmko=&9dkdTBXYcemik=&J4X2PEZaanmsm=&5UlmToVqgsUrZ=&Vy7Eg2VeUpdc_=&4zNjCTVge_fZl=&8NMhV7ZjqbYma=&lggbwcWsefrnU=&Xc24TaZjYbdmV=&9rN_mdWojkdZj=&HQRroZZWefblV=&wkyIydZZioUlf=&PZhKQdZYeifbY=&qD3TYlVheWbps=&FJcLpMUrVmXYY=&bBBMPhUmdbbWh=&4l8yKsYrVhpsi=&j9laAzYXjUaqq=&PCEoszZdrZmkn=&edKAZ6ZYVXb_i=&zXzJrdVlmoraa=&5pFm8iVhmsmme=&LBUVs9Xs_qroa=&qyvjKcWhak_eo=&RUsFXrYm_XYYW=&6IAf5QXXcorjr=&hVI3_tZgZYWpl=&zoBoD8WXUprUo=&DJhGszYcamoYf=&Mu3GfyYoosWWc=&sJUY_eUeoesUc=&k57X56YndVkoq=&x5oP5WWjgppkq=&I9WnIEV_lmsaU=&3Eu6b4XsdcZji=&h5zTC5YeiqoYq=&rNvlCaWXsVgjq=&27kfFxXqmXUql=&r5TMnfWsZdrVX=&tOn48gWlsfr__=&uZUgZaYdZYWkV=&7BFZZSVWgWbjk=&O3iNfZWskkkfn=&hZ6AH2YUZWsoV=&2JXaVvWrYWinY=&tbd2afVossbpb=&m6rDt7YkpsWlb=&KiHuyOZgpYdmZ=&sO2MpiVcWlmih=&ZYaD8rVfpqiUs=&shg_rvZaWeXhp=&o33J7iZhammoc=&RDxXKcYsirX_n=&BI6hOHWhpXaim=&9mmJFVUWpVcmm=&lEVVVXWisnlpf=&NqBoxCXnWsnsl=&m3iNSCYokaiph=&6ZF_unU_ajsiY=&WiUmqdUmfbZar=&i44ARhWahedgr=&JWLpIVZUbgWjk=&NlNPAHVlmVdUq=&_ikiX3UcXknUe=&TlAKZvYi_dcnX=&2mkQ3CXfmcemW=&C6xSfmWbcVlop=&BJ7EYoXc_qkg_=&Fyk9krZeYnhmg=&WtpiLCXjskgmW=&Dgwvl6Zbjfkih=&xt2eJCZXc_Xmq=&T_kmJeXXofqhp=&4BcnIIYjiWmch=&9yi9_CWXihqVs=&O6NdurXqmqmmq=&qo9nGwXapbZYW=&ke6HVTUfgrdVr=&GBJ2tRWcYko_i=&MUfSybZkbphp_=&a_m2CyWrbnZff=&iyfoZUWehfrrZ=&9rtJf4ZYXmZgX=&ARhtsnVroWdeW=&FSPOiaZWcqnrm=&6z44gJVfolnnn=&Jqnfe_UlUpUWg=&kYtJVUUdfXd_Y=&HDCHKjWqYmXcs=&WeDLxYZZi_VYj=&EFqaayY_fqfcq=&jwKDP_ZbapZkW=&iCiVCKXWflYod=&UYMQ22XZckYsf=&xkPj4RXj__dXk=&wL5l5jUdajapb=&mqWj2yUbmlWfs=&76A2ORWXool_a=&mkEZQmYcjWfrl=&LZU9hMYsbUdrl=&khrYI5UWcrUag=&vqbM67WZVenjo=&62iD_8VhVVWin=&RzdP_wYk_Wsif=&N7hmUtXdmjjkq=&skXLY2Ygh_Ybm=&xHXHo2WUqgUc_=&cAKKKiWVokihp=&qu4afLVgrlakf=&8B9eMAUqcZqek=&ARFgudW_mVZhZ=&9DMarrU_eXdfX=&tSBMJKUgjheXh=&uRPb4yUfffp_n=&xJEB3gVnpsZUs=&ZPT9jAWmoZlgh=&d5j4yzZrogXdr=&PK6AfJWem_Zbl=&4yKFBTZUfqmqV=&X6GrkFXmjossX=&kVw7rxZhXibpX=&Mf4wEtVUpdqfm=&Xp2mN5XdXpdfZ=&UtsC5kVYapccq=&Tq_s6SVZpqVlc=&xuoZzNXmXomqf=&JKyJlSWWmadjm=&hW4a4rZgnerpV=&AQ_6czZrhhnln=&BTfIB5UflWcVq=&vQgfgHVmVafbs=&m3aLjZYaohYjm=&dFLypqUqjlbci=&qAQKakVhpVjrn=&HvsXxHXYUd_We=&dmSOPrZgXXqqn=&NtB88zYdblfjq=&UJsrZ4Wghagak=&EAs3feYnpjkYr=&soh2HpYragUUg=&oIoZtDUXZZbeU=&8ny__FYb_hXZq=&96nC2GWYVmcqh=&Q2KwQEXnscs_m=&yQ_kSjVZWXlgU=&xA8QlZZgrmsWV=&5zEuwZWnkjlea=&DzCTTQUposUfn=&FDrkRsYrfelYW=&hmN_6mUlZjssn=&_zuXoCZjadqXf=&sRNRhtVfffVWZ=&RMDHLnZrcneYr=&CAqrlqWkgekch=&mcHhLGVnambUb=&P6ljpXUkoqXfl=&PWVPn3Yenjmlg=&xnkJgxWiVkekm=&KpjFXHYkcdj_s=&JJwEUHZkYhqgq=&azvAfjZYoqZir=&ehgfxJYYfZXbl=&nTpiSZYaoqjmm=&eo4MGAZmcij_e=&xpK8UxXaUadna=&PAGG5CWWpekor=&PV3GJpYpispcn=&6vUu7JUYUhsgX=&nOv6WaUa_m_WW=&M9KkqLVoskbsc=&H4gJxBVrfmXnl=&BfKnQnZgfUWsV=&ReX3JeXdodelk=&vjeG9LVnoqWY_=&M3xZwnVikp_Yk=&U2hPovZgfViUo=&spJFTsZl_WWfk=&6vUwDOWkV_m_V=&kt55BhYXUcaeZ=&QYhowpYdjfckq=&2DEhWQWpUnUkq=&aRl3WjUhhreqn=&nHEZXJZlqradq=&6LELiQYcUrVqa=&hFmuviYYrZsnV=&ge5JxGUdXWVWk=&6xuASmWje_hip=&tV_y3nVbqgfbo=&BPfZvcVYVigjb=&geQqTnXUjdsXn=&9neSQpUhpshcm=&fa8eAVVsgreic=&3nU9UZWZbaYqX=&5Dabc9UYXUXen=&uujQnZUkq_neh=&CDw5KEZhUbWh_=&MDAJPWYpjmqlV=&agzcklZgmfmcf=&edvFTxYjsVZsZ=&ErXdODUpfZXkj=&WWVCuOVrqhjbl=&sAS4TtUigjcnk=&bdOtV5WnjpWY_=&oLMU58YVYVisf=&WVuDcUWY_hbkn=&TqFA6lVkXqUop=&mOWxQZVnqVXkV=&cLxDFcYdqekUU=&Smb5TsVkbjpbU=&sa5GxfVfhj_kf=&YVvkJSZZpfcoW=&KfxSQhXolgkq_=&hMNZ85WZqrijm=&8mvVOgUlZpbrd=&nrrdPLUZfhgkW=&mhndrlYbpbjdZ=&uqtQV6YilghZp=&RbAIanVWslrah=&w7RUd2VehWVbU=&xVopSlZdUZiZr=&jJ6a3ZYWXfmoZ=&FmsVtQVkVqh_h=&iWRlXXYl_UbnW=&3oDMEgZpVkmml=&qa5bHDYqrhWhr=&c5G8zoWoZndXr=&y7H9tXVcamYZg=&l9G_UlWdUq_YY=&CZvHkVWdkWklh=&3SyLjHVhVhkmq=&w_EOmRUshj_Ug=&mqRzjhUrejfnn=&irwR3pZfm_gXj=&TMke2aVifidlZ=&kFqXtDWndhmnh=&7TLSVkWZhodpi=&HMaJwaZe_cmdX=&pnFQuMZkXkZrW=&TrWuWZYpXfrs_=&gGa8hlYWWqrUp=&iC9Y6nUWnYmgs=&xzl3xtVgbmbkd=&3puF9ZWoaa_eg=&ZnZNmyX_XXVZY=&726GwuWi__cUh=&ZkAC4gZcjfgsq=&abSKWgWbpiflm=&buRu9AVcZgZkc=&nTETImZVbjZgd=&UoAc3RVYXcbhi=&UtbPocVmqebfj=&dL_gWmVYoplnf=&2ASQIwUogqWik=&HrYGYcUeaXUWe=&hyiavwZXgeisj=&Qob6jOU_krqXi=&6KDt5IXdldhap=&wLetgIYlesZsZ=&ugDPlYUqshZlh=&tVbmVbWqgpiUb=>wB5NYZZjjgY=&tcZYDlVelei_n=&eIdKmZUochhhq=&gXFskxUgpZnYl=&39gLJWUYhapZY=&796_AlVlfacca=&ywa8pxZblZnji=&_65JvEYedlnmh=&QVZiuUYog_keV=&mvtw6rUrUkrVY=&AvULjwUdjcjqb=&7cgUP_Xeookch=&auShSHUlhmfgU=&onVc8kXmqabgc=&VmHsx8Wrhlbjc=&bUXAUAZjgrmeU=&jsDd2NZWlhlVb=&qa7qBKZjglgfa=&XxqNRUZanVibb=&qtUjprVmercUj=&WfwuKwZefijkb=&TcgcumVZfpXeX=&hwGeObUphdnil=&LaWLp7XroYnbc=&ODiUvxYmYUk_a=&4uLvFZUXW_reW=&_AMtOtUakliZf=&Z6kmVCZdYngli=&kv2hfyZaddabV=&yMy4NwVibgscZ=&JMSJiRWscgsak=&xsU_aXWrrqopq=&RnriJsUgbmdUd=&s9qHpcWepqmUa=&VRpcP8WopXVd_=&nW8bd9WsgZqWW=&F9hSBuWfXnra_=&7cH3RrVhmjacb=&9vaThMZeppngs=&zIlSgSXWrieiV=&T35e42WYohWhs=&N9bC7sUWWrWdl=&kazyWNXmnWihc=&wzX_MTXoanpnm=&ZcaTE3XnpZola=&DNpcfSXmmlrkq=&mSRrTBY_WraUc=&ev_wHVXoigdXZ=&h92WkhYjbjYUb=&qD_f_5VsnklYq=&e3tznnYmYfcfr=&zJ6ihaXjdjsgb=&r6pULBYilsgir=&ZeOhRyUpaeikf=&ZvOMezYrs_iZ_=&j7OGKzXoeYiVf=&4jfuZfXegp_np=&BEIovcVpmjjqn=&GCalnuYsVllUa=&8ujXTMXWqolYh=&HnPJgfV__eYgV=&cWjDaCUbnYeeb=&27RLCfZnheWka=&F8lw6yZnmapUg=&9isiDlVbpjiUZ=>SziVYnmaaad=&QK7X3eXXp_Yhe=&jaNjcHUdrgbcW=&duXHRTXaUrelj=&GhJHtpUrn__im=&cZIZBhZe_ofqn=&PWEljLV_qmlfi=&lYOeN3VkfVhfe=&j8XzstZdVccba=&KeWPPzZgrcbna=&Ena_s_ZUZmnhU=&IWdobpYeWkeVr=&jpVrqqXUdndlk=&26xSCqYmbdcga=&NhVe7eXrhZhrg=&X8JHKeYpoaboh=&aZ8DpaUalifpc=&iByJAwUfbjhYd=&VmfU7oZajobbd=&EarpBiXWfeask=&H96vv2WUdepXn=&GcMyVfV_ohY_Z=&joRR4hWafdgqe=&EQzy_cWd_ejas=&ofalKLWs_Wfep=&IMcYlzYhsshXa=&WPRgHEXbg_Yq_=&ldQesbVl_fVmi=&arpVsmYpecXai=&7lBf5wXZlahgk=&MXNEYiUdfmVgs=&ptcHw3ZaWWgih=&PecnU4VrcdZgc=&mAYKFYVkZngeZ=&zkLYpcXookkYl=&TitEFaZqVgUjX=&3WFECcZlWdX_c=&q4HHZtVXaYlZ_=&ZTiX65XYaic_g=&twFgsTWcZraoq=&8lr3SuYannnhs=&Q3azZTXpocfaV=&ooqMJZWdodfsU=&JCpxjvYjYoVaY=&BWyJvaZWnphfh=&fci9cmXrVisXc=&HV7zL3ZYpeXjX=&tz2cbCWrjWsbi=&bYB4xjVjdVsfn=&XTIRTKWiYhgjZ=&G5S8sSUeldjcn=&IGGunVUlbiqsn=&ljqNPhVkXpWeh=&Dbi3pzWY_ZYbr=&hjRsdfYsndZmb=&wGpdWsVXZrmqX=&fMQU5VX_bUZio=&4icVDBWXfUXUm=&k9s894YpeeUhr=&dKchJ9WskqbXm=&xX4QXXZldUmmZ=&pIRwpKXiqbhhU=&Z3HHdLUhYaWba=&yuZplgZUVVmnc=&UAZTE2YgdV_lZ=&GLNAOMUXlimgj=&EJsLwKWmfUqoo=&cJlEeXWfXUnkV=&XGNB3GUZWbk_U=&vPvmmZZpXnVao=&r36LuCVWmrVfU=&cfvdO9Wr_fXpo=&kslnUPVXfclZl=&clJ4PfYlhkjVe=&FQsskkZkisjsi=&BmsSOOUpgkgfc=&ClvdaHXehdqWg=&U9S7RwVsUXimk=&4buKIfUnibWpf=&Ttt3dqUrlpekm=&LPYNjNVrUpWja=&6itAMZXlXkqol=&NUpK8CVbXolqo=&5pJGqzVladbm_=&EelOuCVnmjUjU=&PZeOM4XmngmVl=&gWnLYjZorcngX=&JGRHfcUgq_bZb=&GGnZkHWdrsdWd=&ND_YusWerjg_f=&CAvFHWZVciYqq=&YXjCzvUlpVdls=&OZqqJjUfn_Ybp=&PEiZxtXcplpl_=&7ZYPvUYiqikhX=&4zis9XZoVpUlo=&gy4pIkWWqbjbs=&QjnBAUZ_blZjZ=&5GV8THYqYVsfj=&6RZ7AVXabme_V=&5CDhZBXipomqh=&PO4tm3ZkWfqgU=&VsdlY7Uplesrp=&NgzJcvVanrYYe=&nrbV_ZVhXVYae=&gaCXdrYYWYlVc=&LleOkRWVangWg=&C9jXgYVfWrgcW=&82VkXMYVkcZYr=&9HzLyeUZgk_hY=&psoruGZc__hWj=&Ochm8XXV_hooZ=&uaw2AWZXZirrd=&pd7O8sUXejarZ=&5DkiiEUqWUXkp=&4WjrrWYrjqdag=&8dR_fuXkslrWs=&TuQsKBYohdgdc=&xJyJX_Veldofb=&M8fqImXjfYXcd=&_pg6y4Vklhckn=&DnkFeaVcbnZYs=&sZ8YKwXlihsVd=&5vGKhsUmcllkj=&YoP4isYjVVcYe=&4BC5CvUqbWfUm=&WuPPoPXZlVhsp=&XQBtNEUoZVcUd=&tlk65tUUVbkpm=&tveecMWeelfpe=&WD6QpsWdgVjmd=&bJIuk6Vgs_loY=&M3qyeEY_dhnim=&jqhN_lYdijWmV=&BHpdSiYgmZkga=&fZkTx4Ugcclng=&Oi7Bh2WpsXeqs=&sapB3TZWVgVna=&iwnvf4X_ojVZd=&4N6Y8dXbmecln=&IZFdF8XeaXUpZ=&qlKN6FWombbsf=&5zZYKQVWmcpbm=&X7TTmJZUrZZZY=&uso9uzZiYnXna=&LQYSYzWofoXUX=&obyXFDUUgVYVV=&wHaOMNXkVUijm=&ZH6EwaVcafrmn=&LNL83AUjhVkjX=&vOimBDXWcrW_o=&9egb_xWllcoqh=&gYwSboYnfrhhV=&PuuxVOVn_Wf_d=&_ldmdXVbZZV_Y=&xJlww6XUZVqge=&BdfmLBVVihboe=&6z7gx6Zkhhakg=&WPEbfKVXrcork=&TPeicPWYmkbpU=&QD7mxGUYYqrYU=&CpiDa4XscbYrh=&rdqoplVbibVbW=&lxXmFQYqecY_b=&GSqyJlVhfmlro=&RiR235YXZUlmn=&YUo7OkUmUZnXa=&bZeCodVbe_gmq=&GZGZYEV_XbZsX=&F5AUEFXicVr_o=&JlBIzOY_jhfWm=&CfiRXkXZneoeh=&ZItfm6Yialhof=&NLDyhuUnjbjkl=&dqAXxrXhZ_lXY=&kXubrFWeVXcj_=&Y_4eGgWga_aom=&bL6i25UqrshiX=&n_kLq7Ymemdfp=&mO2jN8Xnpikac=&auAAi_XkYhhnl=&ggKfplUjo__Wn=&fGaddSVZsilhc=&ZSYhtyZpaUjsZ=&tB5IGSWbkiacs=&wabEuVWkddfbX=&Q3qjjeWqbUaZV=&YtEtUwUdbVfWZ=&KpAhYVUfkYsp_=&FH5tsgWigUrVs=&HX_wpHVXofgnZ=&Pz89R3WarkWYk=&ZVCWzNZaen_ds=&CgIsNLZbZokkc=&PceizEXgfcanU=&ZnNXDVU_ohbgr=&kuTupPXqmYhoq=&XCURifYiXWoqp=&2q_Kc6Xokogco=&bCVgjSZgVjYgd=&eFYiJJXpWaned=&ZzJOwUWaZsXdl=&fZPQq3Ukalsba=&DNyyntWfskeWc=&TUIJuLVksjVfo=&uQ95WpYWsckcq=&E45vp9WmkiUeW=&AqMYZiWZenedp=&gASeMXYk_rhsa=&cUXSY3WXUdWoi=&Rysb2LWsabdcf=&gK3_OiYh_sYcq=&YdABzPYqmqXmm=&fo9sYqZlrWroi=&Att428ZUYbsei=&Zq6SLkWjhgpjY=&m6wPTRUrhljVg=&vpiAcTUXrnkpa=&S2EF72YfpUVZk=&rwHXukUYfeiml=&oja4O5YgabdZs=&KRFcssZXfWfX_=&E5YeekYbXikgr=&MgaGwkWcWlWjb=&mSECEDUpVmZeZ=&zM3WnoWXmVdme=&VI6lFCVhclVej=&wPzY_VXkoaiin=&UfHIObWgZ_daq=&vLiNMzYrnZffg=&BXBcsLWUVaodh=&YJJhmbWfaapda=&NKwJwLVhjgnjj=&MChUhyZhmXqcY=&MnqWlHVbbclXV=&YH2kYoYnWVcYb=&FxVENQUgWeosb=&Qmc4x9V_gqgXl=&mz2J82Zopfksl=&WWX3txWZrlpag=&97KyiRYbrpmgp=&Cke_VQZdmUYrb=&YhcQ77XimoscZ=&YIhMHoUYbnfii=&WIW4Y4Xels_le=&p5_F9LYoqfkaZ=&xtfDW7XXa_sXW=&LoWIgGYlYilek=&hx8N66UlqpVgg=&FJTwZqYqpUbVi=&gDdaBxUsYUiid=&4qo6H6Vcodhbh=&yH7ZYWZrpmfaZ=&8Yaki_UfkrehV=&TqUReBVXbasXW=&rPxik9UjegnWW=&NRnqj9VonqWeZ=&YVkHipUkVageZ=&CqYNuyYkY_dqf=&CHrA5cZYmkjsb=&8bdo27VmkaUUa=&SgwPp6UcWakrl=&s_XIFOVsgrhss=&JaBNzCVfsoUpm=&Qs78EKUdjqWVX=&mtgbDEYonrVno=&KscwcMXorrYmk=&62XYV8VqYogps=&u593roVljq_hW=&VkdRqWVjhjWac=&_f2yNPUbpWVem=&bVjkuOVonlWcl=&U49aAGYcgghir=&gCGe5aUjbarfh=&cVv4SxYpqmdWV=&VjmBiaYmddXVm=&25apScUiibbel=&oay5pyWqZdlaj=&PrVvpeWUmmdgr=&VBRC_3Vqo_gZi=&OF5hVdX_cVWbW=&RmjfcZVhWqrfh=&fBaZrtWYVZeXj=&G6Ss8ZUelajio=&TaVYcwUdZVngb=&QoiYqeXUWWXVW=&opCJcQV_nYmZq=&tNvLHuUdXjo_h=&mPGmotZqslddX=&dYs6ViUocajWj=&nYzoAJUijgdbr=&J8qxUJXfUodhp=&J9kqdQVikapeZ=&nOvuwsZcYVris=&4o4rk_Wdlqald=&eaDpPxVo_jjsW=&o7mqMAWnaddgW=&8U8alRZhkonU_=&_x9lX9WWUWgce=&_JRwejVkrhmhU=&AzQ3dYXr_WmiX=&9aA_KXZqijhgd=&s9FHLEWjnshkV=&FMF28oWUigdfb=&TRgxQrWge_ZXr=&TjtynNUeojVis=&cyTx8KXgkYoeZ=&UO9WNdVkkZUpg=&rC6OQgUgfdmgd=&cVUmPTZgrlrge=&BMDoGSXkrppsp=&2Rm42bZYUUc_l=&laMfgzUZaUjlV=&qYcdECXgWpchn=&K7Rs_VYjndmZr=&c8RDwWUgmZoar=&C2Wk3sUWhbhn_=&5EAPMtWnqgbWb=&PlQtRkVkaYeke=&o4lY6bUasUhhf=&qp8R8iVikVYcl=&53HPDnXacYikk=&mJmpIwVYWZaan=&Szp5o8Ugrgnck=&NrNnZ4ZmWpabe=&_XFq8xYrns_gd=&3hTsTZWYidhnW=&HRSUSRWmZoccp=&YSD5FoXeYXoal=&QK4tTkUgirrma=&Bb6tZGVnlhobl=&rOv5bBWdkfdke=&EehxBhZ_knsch=&nMUmVCWqkcj_e=&grgwXqUonhhUo=&jI3CVfUda_mle=&XZcu4CXUrogaq=&wYCdeuYesWVcj=&99jQjUZnblWl_=&Ewzb87Xjcdkhc=&wu534SUoZrXjY=&6mD9_MZX_Ymon=&f8WkseYW_qjYq=&2dz36DXk_h_Wg=&NUuFgrYZk_Xlf=&lYOnCVYehXeUe=&7SFvoXXpahYmb=&QYLehGUadgrne=&x3lgw2UsddZXg=&Kjs7UjZjeoimp=&36SRnwUqqfVhh=&B5CNxgU_inVll=&MpdPKyXarYpXo=&jiYQHrYbpdXll=&kTN22pZfjrrip=&523uacVdYUgrp=&_4abzbWUqnqoq=&XAyfuwZfbVnae=&3f_OtHZrfUkmZ=&Fun5FAXXoqfho=&Xu5Z8RYdfrkce=&BeBAVvVWVrWik=&dxgwedWgqs__o=&6oYEHxZnbinmi=&fHedbIZ_rcari=&3rxheyV_glskc=&9YpyejYhbVidf=&qnsZnsZbasaso=&Doh4ScXqYsaVi=&aqtpZbYWqneUY=&Ew7jEQUWigefl=&cEULHSZmsfbik=&4jdZZXVhqbjZW=&DpPeFNYs_oi_c=&XGI9GpVdckXcc=&Te_GWJZcrecpo=&bM7sfaU_Zg_fZ=&rDXV8AWgjknZp=&O5DTFPYfeqccs=&GtsvSOWpssdXs=&2AH8djZZ_nX_U=&wLpYvkYZsVUZV=&JJC_pCYop_eV_=&OWip28YomeVip=&fCqnWSZWZbYea=&8xZDLsUlWWsWf=&c7qKGUZXgamjk=&h4pJCuVkcmbhW=&E4f2IYWlfegYk=&sflH6pVqlVmlg=&TtJ3UoUgmshVc=&TaBUAiYcchclZ=&wqvHL4Uhciakq=&oId4pwVc_Vhcj=&JCP6s8Wbmnlca=&VFNKyXY_ommZW=&aZP7xMYqWhboe=&gUM7CPXoh_hbg=&4uEptPZsUgjrU=&XOld_wYescrmX=&iSHo6IYVYWYrr=&SNhWXVXpkpjdY=&_ig3OsZlplglg=&kJwfr9ZsadnXU=&VASEFjUdVZkeh=&NcQvGOVeXXfns=&GoacbuVZarcV_=&Q7p4y2WqXZdsh=&sG6RODWlchbUl=&cJ2997Wnq_raZ=&NqzZW9WVridbs=&UBy8gcUZVZice=&8UYILNYsdjleb=&nVgKDIVbsmlsX=&rLi4VsZlfocWk=&lEs8kyXjWkkXY=&afMB4GXcqnajX=&Kbm4VVVcqcfpa=&Czc_9pU_XoqdX=&eCyGuHXVgadhU=&dq6iZ9WWZhWZj=&vMU3FiVijebge=&Vf25_lUlmnnmq=&TPDXsLZpgbUcb=&LCrRJbYXkYkYd=&MWIRDhUslkmlm=&P73ArXVZUnmhm=&OOZutbYdhX_cb=&O5EfFoWqrjgbW=&TjHwvTWhgcVma=&f8ZomZZppXoro=&HZDMXcY_lVUVq=&XbA56rYoabfch=&p_EBa6WYcesjV=&dyKCNaYhWWlZW=&pfmCiMZWYorVa=&agbj8qYfreknd=&shrHyeWcZVVkn=&3PwPQxXkmhcik=&rh2CTiVZUddqV=&awmgxcWhiopYU=&_HMbJUWepriYc=&hqmI2xYXhhndZ=&s6b8rUZciVkno=&UekinpUZekosY=&RMsxyKVXcYije=&dEa7RyZadeYah=&kUUztoWekiacr=&B7xtaIWUlmlci=&ZKgzCuUirWjlk=&ygtQyYZYoaZso=&roJ86AZjXbUYn=&AKavhRWckdlok=&6xK8vgXfdblmg=&UPmw3HWiYfbVg=&NI6sOvUsbnpWj=&5kdHB9ZUUfks_=&ugALGsXWXjjWa=&NPhPkUW_iorhr=&hnorwhUpeWild=&YNS9lMUgjciaY=&RnRdJrYaliUVV=&TWE2nrUmagYVi=&ah9fNMWYolqWr=&63STl7XbYqhif=&86ZiH8UbZsflc=&3aBT2BZdaeip_=&jmf3NkZrhhqlZ=&Qd7tO8ZpoiYfp=&eXx8Z7WWgZeia=&9EaXK8UfneUmj=&MFkDILXjsns_h=&qQPX98Y_boYd_=&tlsEQAWclpdbb=&keZq8FUejWghW=&A5I8oZYnYhl__=&yE4bJFYqqbdZo=&dYyNQHU_kVgdm=&B7sj4YWXoqkdg=&xQyb_PZsnZsba=&rkPOsVYoqsZcV=&S2RUDZVdgf_ZZ=&NjuFvNUlXeUcq=&QfqlVDUi_bpfe=&FSdzmEWWdqbUU=&cIi6_DZnsjmo_=&FtHqm7YmqWpaf=&GBUgRKZZWbsme=&cv_6mTZZapfYm=&arGxXYUmlkXgc=&u4rV4VY_frV_Z=&aY5ZZKWg_Z_Zn=&DXNSAOWmsniir=&OJg6ZHVZqacgj=&srgQWsYsYiUma=&6v69AAZinZdWk=&LKUR9wXp_mWWZ=&mAm3N7XnXbWio=&EDdnnAVdXlZfd=&6ecmYhUmgblZc=&3_2nnUZrlWsYr=&dAFN9QXacobeo=&7LKhxCXkspUdV=&KNY9t4Zlcjskn=&x43rqQXdjVllm=&zZcV5gVidoaie=&XvBAv8YVgos_j=&IOTr3CUclbi_h=&ckK2aRWrhacVa=&7flJ_QVWhgiaq=&s9ts6YVqkgebV=&GIT9hTYesohYf=&9YkHj5VXpjqmZ=&9c7WQ7WfdnlWn=&FRT_IcZoXdibe=&IhZ76PUjmWrkh=&fx7oeFVrYmgWe=&nPNFUlXgffYjk=&dDZkwtUrdrjfo=&Hgg2WOWrfcYZU=&3GGu9yUkVoXdW=&EKDreEW_ZgrWh=&VXHphvZosggaU=&WRe_llWjkrYXh=&cJHmYSV_ZdYoi=&x2A3fEYnrpkcp=&6fww3hYjYndjk=&CVp954Wcsqpbq=&OGjU5OWpmmeal=&CjP62BWYcsVcV=&OrDfNkViidlpn=&rtsSzMUlsn_gi=&9WC7VLYsdlsgX=&WBlPFCYdVaYlo=&cI2nbAZsh_Vpe=&_MvvO3Vimckgq=&744N3gZUeUnqs=&uV2Tx7UsakdUU=&wCR4OdVfWXspk=&yhvVX4VXXmYVY=&SLRFZmVpkUjk_=&supwUMUWqdcfs=&bJnTxaVfpXdaf=&cFKs3JWnkmobh=&boJf3pYXknpoa=&zkGKzoVrneiq_=&cNynC6VUejaXh=&nsDrulYmZaarp=&SLvlggUcgnWip=&lEWOA5UWbZkiW=&orFelLWenpepW=&fNrCk4ZhgeZhV=&RgaWVcYerrbWs=&txVBYUUhlccmZ=&uMqJfEUfkVsXk=&aR_tP9WqdsYZs=&ZKIvXSZUoloZV=&WtLMa4VjYmfUb=&ueTBvmVqrhpqa=&A_DNRdVokVa_V=&fMssl_XmYXgno=&RWYr_NWsicdZs=&zt2rpJYeoWjsk=&4AwNfcWjlbeVU=&T3u383VUnheek=&3LqlCTVnqWhZo=&AilKeqVrbr_nh=&d5H9tMVpmZlo_=&QgyuDzVngmlVj=&3Gl_DqWabWnih=&tLjmZzUrbeigs=&o8x35dYqaXVgm=&TWB449XdVn_pi=&kC539kVWcVfo_=&BNzGs3YpWehYi=&kAyemHZ_sscpi=&BaRWQBUZifq__=&5r8TL9Zikcjnk=&4hAaMIX_oZalg=&o_3_odVqcmoXY=&_wafuYZdebhmg=&67DyG6YVrgdVc=&DLzT3LXdYpllX=&eb65uKXUqnrfZ=&ph9mCwUfnbsam=&7T9sSJUcWnisW=&ZBoJOpXWscqie=&RpAVNCYYUkebU=&5yYwxTYdcYdWl=&wnDufUYagcsoq=&vKgAgRXodahhh=&XvicjjVmiaWnX=&6sNzz5UiXeega=&eXzemOWndl_Ys=&xePN6NUgqcYdl=&kyyHLDYUojV_o=&WaCJkAYgaVZis=&XwDxe6XrjoZkn=&YpcBD5ZaYjWce=&kiA8ClUhqngYZ=&fxzTOBWk_pr_k=&ggeNcLWXrq_er=&bXBVhtZejebUi=&eusK4KZradWol=&SNN59sWjjVYpl=&ANFKVIVYZese_=&gvznTPVceicpW=&YMNrXFUcZnUXe=&WfvYZzWgppfnd=&oAhoBLYoqYcYq=&mGUFj8XqpnUod=&z52eJ5XkXYgss=&KU6KzMWgskrce=&dBWF3nUhVc_gj=&jeN6vHWqapmcn=&QXyNhUZoYehea=&MgGVskXVnrdjc=&ZEqCwVWZcWUg_=&BxwHk6Ygkh_sk=&dOF9IAWiXXdfd=&n2tDl8ZroUYml=&2gIEWOWVmej_o=&_OgcRtUYUjUco=&cTacEWYec_dUX=&npIEqSWlnZhre=&XtAJhKVaahjis=&fIp7GuVralYZZ=&GAtxwPVpUcYUU=&sKg5kuWeesclo=&jmgrM5UXbdjZe=&ZuTvZ8ZjeUWlj=&6afbhHVhUigVV=&5hVXkoViUlUoW=&3teBonUsZ_csj=&pt5hPJWoUflfn=&VbIcclX_cnYce=&yvt3TbYqqeWoh=&pkBiZ5U_lZkdh=&vcch4hXodhqhr=&8J7uPrVWgUmkY=&nvzBKLWqhoUaX=&uMXuz6Zcaa_cX=&rC6_prWXjrqgU=&sjVMpdWmsjill=&ORIehUVWYqlfY=&m3p3y6Yikepqk=&opVifCWodVXjg=&t9u_i5ZVVejVl=&FTKZtKYmXllpZ=&QRzIJlWsr_okq=&hwm_jVZVVUbqq=&sMizC_Wijdcfp=&lFOYeyXZVVUml=&ATEPc7XWqfed_=&g9c9f4UXoshYh=&WhhnHBXekUhVp=&gUBaqYXscgjqU=&EIcBmRVrscccn=&GSgdtrWWqUpeZ=&ex2VKbXoVVUWa=&FrfNM8UhfmZ_X=&Mh6CpDZkd_jWo=&Xax97LU_WmlZg=&RAoEBAWa_UkWj=&BFSNlxVcqmbgs=&El4i3oVbpUrdU=&VVACbvXjXWoUg=&Pt_h6rXpUqVYZ=&6iYkK5WlknbZY=&bE2rXqXmslqYl=&TRXlroXreYfdU=&GjoyhUXkVmnsc=&2AU4XAYamgkks=&rkVoizUmhdWjd=&dHRgvCYp_eeg_=&WANU_yVZbVbpk=&SJnWCYVoWnlcW=&P3IOERXaasbir=&pqeSF5UeksYUl=&miZUs8Vkcdips=&xBhOjJXkkZbWb=&hG6QFLXfnseqY=&sznPCGUeYsUgc=&Cwr4fSZiioghs=&d7DFZuUaUqWni=&rvuvc6ZlmljUn=&9gQ6lTVmqaq_j=&BpWk8TXkaVUkV=&9TkyxzWdicgjo=&N6vXyaWcksmdW=&UEyBwBWeldsqb=&77EB_rWkcWdVd=&FTbpBQZeXbhZl=&p5bpawWlYcmj_=&INVtljVVmnkn_=&2ajk_vX_oUhsY=&zAQpJuYadliVh=&m7cx64ZjmdUgp=&nF6gTxVWagWne=&b6MNj3Wsslndc=&MhSynAZhbapfq=&qzr2J3VhUgXWo=&lxmUfMXoZfp_g=&g2pNNKUscnlmj=&jwsV9ZUYkUaWo=&bj5yCoZqhgcin=&aAa3CeXYmmgdl=&NiKLGkVhs_Vnp=&VxhYPqWdcUmYY=&2lddezWWqslih=&yFm3sYVXi_oYU=&en6vK4Y_iXeie=&5xICn_ZpZeqUm=&DWhzvhWWmjacp=&TE3cjoYg_XVZk=&voWezFWfqbmgg=&dKqe_ZXmlpYYi=&ewNUv7ZUekWsq=&sPhAzeUjodqfZ=&JOmSMcZhkUekY=&DOgG4GWgcfagq=&AdbcD2Ujhco_l=&Ajn7NWUmomVla=&thC3nAYddrdY_=&wgQKsAVWjgoab=&RccI2qWVmirYr=&yJrBw5UpWXUpp=&pnXMJPVV_ZajW=&n85hdFVasUeWX=&JR_p72Zi_lbai=&8JrzGMVlfeoll=&e2JmTYWWfaWsf=&P8BLueYkdclef=&GPgM_vUVcrjqW=&JEUo73Ychnqak=&SBIMHcXebonpd=&KBjgjSYlVVqrk=&9QFVi3UXgpmXc=&NJAPMoUnp_opp=&_RkCPmUjkhUsr=&4ORPRAZc_Wbcd=&kLZFn6UeorZck=&CfIuwXXVXjhhZ=&g5XOaWVZgbpUY=&wU3YCiWVejhii=&Zo4gs7Zo_pgbg=&ZAD3XUVmfpckV=&scyExRXflpcji=&FqjOVdXqrrarb=&yPWlF4VsfofXl=&S56EW8Wkpkias=&3hyPOgYfgmrrq=&AOhEYjYsVZibm=&5YWNj8XY_bbhm=&ynYAIIUfpjZdl=&CJZbFmWleUrhk=&SmLeFYUUskUps=&qpipmnWaU_bpc=&SPTE9FUUUho_X=&UUngEtXpi_neg=&fCkbfiVnVhigY=&Vkm9KOZrWqmgk=&NwhTscZkZhfog=&yWcj_xZXfbinW=&4cezpqWhqjbrY=&4Qcu2tXbqbgrq=&3ybrhPVVqjmmq=&ae3QVUZkmeocX=&v5kYSwXoocnZb=&OAP_XNWaUXiUj=&7slQQnWaZncVi=&sXADFBZVjq_gi=&BFdQ2KVsZn_nd=&GVNfRBUjecjic=&9iaM_UZkahije=&hui9oLYXdjnbm=&axTCV4UniWolb=&4_XOXVZabU_la=&UWaZlSWdUrmkd=&xv3ITSYXagZZr=&trErVwVhdmXdm=&pUDDC6XnmbaVr=&SuPrEzZqceijm=&Yl4cSZVnnijlX=&cyhMOXWi_laVr=&XaNuhSUXWlXrg=&mqoVAzUgkdVob=&wkHOS6Wdoa_qi=&zkiMMRWioaocl=&IcZQIbZjeoslW=&ZDMNGKUpkckeV=&uEExQIWpVsdnU=&bGOupzWYkasma=&zk6RsBYdYZZrZ=&klpsGOYYgjhno=&S66O5BXVXd_Xf=&OkMZsKVgVVfdj=&OLEGGBUohomqY=&S7G2WzYjYinYX=&6qrnYBWhjVhXg=&LPElWXVjkgZWs=&YM72WHVdieYZe=&kXDUMSWmmp_Xp=&k_RUdFUoschdY=&Jt2H__ZYalsqb=&oOl9rnUqjmeif=&URyft9ZiikWlo=&sEuFNkUqqmYf_=&JgLScAX_kZUif=&aWNHwnVYUed_o=&CIi_4CZnse_co=&U3FOS6ZVagink=&CBmFqNUlVZY_p=&PJJES5XVlUUlo=&D9ay7uWllalcf=&Q_eceMWmX_mdb=&p5lZVOVjVXZeg=&IlXzJLVbUkjqj=&M2xs82Vjskgjc=&Br5lGNV_ebmef=&GarYCHWfrXUUU=&Rz2kMaXXfcikn=&glFbtpXmXbfcs=&6HmPZsYXcpohm=&ORnxqmWsqekhp=&eFwdTrZ_WZoml=&Tb674PUoUbUh_=&DAWhuwXYbabiq=&wucIuvWmmrnnZ=&2sbFYNXrhakWs=&fOeWccZildXnr=&qEM9t9YpUVVkl=&t3tAmnYle_nqW=&b3ZoTvVVUe_gZ=&WAGdYpUhXgcof=&NjnFRYWrmihmq=&ovrueHZqffWgn=&t6aQ2eWaodno_=&HwgDJZUWmn_Uo=&yTOkGsXiYWjpr=&6yd_qEXXbqmUc=&sjJZYtYlaVeVU=&fqnVA5ZrWdnXp=&IIUAC8XYnXepq=&Gbjg2lZUYYlhc=&MTaHB9Ue_fnqY=&lG7TS4Xlghfgi=&QXW5UhZcrmbrf=&NcjrDdXqUkcgj=&wijrseXpWnWlj=&hXuhvMWWprjmY=&RPnjm8ZZVhkkq=&sNMBUzYZchnsZ=&FYqN2TXisglZ_=&3cJBesUolnrYs=&oIjNeqXqYmciW=&c4Fk9hUWqaUkg=&L9XpXyUsmZVdY=&qqHw5LVUUppkU=&lnT_hDWnsoibo=&U9rmNPYmb_nfd=&gpCUbfVbUUVkZ=&Dd3aeCWnajkql=&uTVd9LUXcZkhq=&52IYRcYbmWXXk=&z_UroSUjWoiVZ=&4owMJCVglkohm=&Ju2SjBYdqYlsX=&96BOAZUpcaYgd=&NxuiipZZYXYej=&zmbsnkZVmZfWU=&3DUMzaVkfqief=&rwuQykZqYgYYr=&R5F8ogXUmjnUh=&BEd472VkrljUb=&MCPRK2Woqmnml=&cjSFiFZdosogW=&nYuCyIYomfdjX=&2tr9PdZinpZbp=&fDz5ZLV_kXoiU=&uIMbdsXkVsabc=&AeT7RzYbpVhfV=&nxYy54XfYpbdj=&HNlq4UUnokogs=&2AgdKzZUnmikq=&clRK6RWjhpdWf=&HiyFcRYU_nmUj=&QdEqssUkZsrlb=&_hIB6PUZnbkko=&6ar9YoViVanZl=&5vjqMxZgXkkjl=&4AZF4SWcdqlba=&l47MsdYqgaXmp=&qcIWxdUZna_kj=&SlKKEDWfaXpbj=&UZ6l5NUiqoelg=&ohnkc4XnXVdbs=&mQsBn4UqVfXqX=&pqcwYsXiqnZmj=&toHVtDXdXWdYs=&ktLYcvVfcrbbb=&wsvfi8YrdslUf=&zKZL3DYdmbbiU=&Du7JK6Yrsidma=&Au2ylZZgqqWaZ=&t5NDAPXrngkYa=&7BldOIYp_Xblq=&NGXq37Uohdori=&wpMaNxVqmfdcd=&oLwPiBUUbeVYo=&HqkRiZWjoUeds=&lvEQgFUrgseYl=&cIbA2RUmanhhd=&IWARLyZWslWlq=&QgiIEUUdjieaj=&nA53_7WnVW_qm=&cAMriSWpoeepa=&CXy7wfWrrgggl=&bjK4EtUahlVfZ=&jYRsqiYdsYZqj=&yyBkgFYdcrjhZ=&KBgwykYshjYoe=&5elKcTXVapdgj=&4qEjKwYnraVmc=&NTmq42Yranpqi=&FgDyMYXqqcmqk=&JPxqB7VhZpm_h=&vIQxJYUghZgVV=&PgiRWPZWn_oVh=&LyctUhXabUkfb=&pAq9giZinrof_=&fUwSB9WaZhlks=&igLAHAXUceZal=&zmOr3iYsppjVl=&ByaKPcZrlnUob=&AB7k7CZipfZsY=&7GNMdDZbYkoWk=&zIfvu9UnpmXfa=&x5esqwVYsWaWh=&MwcP83W_rYUag=&IPXniZYghiXlk=&jXiKp6Ysckjck=&H9aTGeVnijabV=&2BX7WOUnpUZaf=&GEcIFKVslfdZp=&bJdP63YXdmmpV=&u7jPeuVXUqgdm=&4tVZlUYkWgdfk=&rWfWqJZnnneXp=&PD55ZiZdoq_mW=&s_5LN6WU_nVmi=&5tQMlIZqkgpWl=&2emgqQZrrkel_=&xhF4nQYplof_n=&thQwFwZgUkYgV=&Wru6x3WpXqege=&HutYtPZokafXe=&IlXAtJUnmc_mY=&9eRrCRZgXlYol=&c7IY63WqkYemk=&oH6EyYXsmb_cV=&fLRykoVlnVdpU=&TFy4yMZhiUZmh=&KNC2eQWnkojqZ=&QmvqXWVniiqlc=&sBkeJrYnWerea=&CxUNZRWisigbc=&mkpaj9YYdg_nj=&V53BiyWmigcgp=&bqNlnGZnnpehY=&q4VgcjVjfYVlr=&gbkMAoWhgrfni=&iVVTHIYfYoWdV=&5U7sAMVbklZYn=&Hiq7QYVoUfomq=&QNViqCZlknifn=&pKdMXkZqfebch=&AUAMhuXgijXon=&6J5HItWXXsWn_=&qtxOqKUXjdUaW=&zOrbtnZihaWoY=&xq95kvZZldgoZ=&bKjDZfZscgVhX=&hin6fyZairWYh=&Zr9u8xXXsdocs=&gzg_dWWYWjrUp=&NPBr_nYgWUU_q=&sveZjOUaqmXip=&OSQPdAYpbldkb=&448XLdXaYg_nX=&vG7mI2ZoYehor=&uZScp2VYimrkq=&fHJ3nxWhqqYX_=&7Jj_OGWdYlYfg=&DML6hfXsroUbp=&5ndmLCXnUWZsd=&6nwPbaWk_jVob=&J2KMYhWjiZbpe=&J4Gt2CVUcleZ_=&pKOtE8YcYmsUm=&nJVkRQXZiVWln=&2XDYvnUmosdsX=&v9FuSNUfcrVpa=&97uqCnXkpWihX=&kIkwQsWqWfqhf=&nzw9hHXXiWmgp=&MTWyk4WZdmUor=&kMuTcVVrmleVZ=&WWevigZrUncqh=&2oNnEVXfgfsWY=&V3NgkIYfracah=&cgIPDiXedW_fq=&nvUfpwY_Uadiq=&glF6jXVbjYslq=&9UYMoxYjYmgn_=&HTC9fsUjhd_ni=&si5gPoZYasedq=&BKTqGwYphb_ik=&GmL2unUeibgUV=&vZER3tZpnpnZp=&iZiuULWgUdqso=&H7sNbxVjVYnhk=&xDqtnwWorWcbn=&CjZuuxXnsaosg=&iY_txsVYhcgeV=&qPPLUJYYcpese=&xlLrGRWVVoijX=&IvjDZrVmUkeqr=&ngMZ7cWmblsng=&y6P47wUsZnden=&buniQ5WXbfkag=&mm2MgBUYVbbpn=&MiZkTpVsYbZhW=&iLFX8xYcnfigo=&6xyZ5AWqeqY_U=&ALFaCfWgjYZfn=&qN698aXVnpoqe=&peXPcKUnrYlbe=&8N59awXYVYVog=&e2x3yVXqforra=&axogknWUeZXkr=&vJxkcXXgbgqYr=&8Mfl5bWdardmi=&8Zo9HxXUqYljY=&xxbyxrVWVXZfZ=&VEoiN9Wom_fZl=&3wbqVZWqZagkV=&XYFlG2YooVhop=&VgnN4TYqmscci=&JgPx8yVYlkqbs=&lsNWuuUkYXqYg=&Uq4wAGYomqpcl=&k3zb5rUrpVlki=&GBEYPsXZqsUrm=&DONNK6YkZgZaV=&t6ymR4ZijcqV_=&uqjwypXcVlaic=&F6KwR7YrdeUoo=&AcMo8MYdjdnkU=&oXJnp6UUahdbr=&w2C8YYVsfpsa_=&PRDbG4WkeclUb=&NS2IGvYfXWcVd=&mYsnysUXkXd_f=&MbzyPbXXissh_=&aC3VWhUkUdbZm=&LFLaauWdkfodZ=&JMkZcRYZkeZnj=&y5YKwmZVUrsko=&RvCMlLU_hpbUm=&PqabaxUfVUimg=&RvDZDbVffgm_U=&2oRyNpZfkYplV=&o4baSiXVobU_o=&stcAbNZnlVasU=&S9BWq8ZrlYWmW=&yKXSncWpeincn=&3riXiOYn_redU=&zbSqoxUlXcnpm=&kojHL9VfXYWWZ=&ILdBOkVYmbfmV=&GYutDGUbfdnnY=&Pc6z2fZiVcegc=&36VArKZoZllVr=&ywcZr2Xjejqla=&4WOSMNVpijYUY=&9ICUQ5ZWnp_qq=&skjDW9WXUqofb=&9L7AppZcikdqo=&zuoyGwZsdVgZm=&t9u_OQXfeaWki=&9TL4o6UrbdWbn=&9nlcyoUYopiqi=&HJz2bZWped_pU=&IXJ54VWkhVepc=&XSWNntWjdmkUX=&eYrKmRXoppXkV=&fIWWRjWaspcpi=&aDme95ZdqUoUe=&nnuGUAXZUdVfY=&xfYkfqUpprWXc=&hkootHYYnqnY_=&qrJtCQXfoqXgr=&lf3JHEZlWheag=&IwvxM3YUddlbb=&lZSNEnVVr__Ys=&tr5ujMZspmfZe=&T9Ey7EWWXWXiq=&pPDRo4Yahgsde=&pJhjunVZXss_Z=&3baSJyXqnhjcV=&yTS6rMWdkXjjm=&K5QyxYUqleYV_=&TlHXjJU_sfUXb=&wcxmxZUofsUVe=&wx8XgOUfjjWol=&GnI6qsVbdecUo=&SfjaAUZ_jgfUi=&KMaRadZshrgam=&veikPhZiXlnZr=&BLN3m9Xmeiloq=&i2MkNOVrUecdo=&tPv6raXsjl_sV=&yGFJevV_faeYU=&3JcWYVU_Znjlb=&d4nglcUhkYoam=&XWjNYuZeadinl=&QYJvivVnVaram=&QNM3ZwUo_cVnp=&Qz2rjKUYVUbfk=&QIGtZ8VkVmbip=&5yMyXzZaYslVW=&IQGpkkYWcngjW=&7kDOrPYj_jqdf=&7vRnh9ZUn_nVZ=&gUYXW5XaXWkqs=&q6KwMOZajconl=&gij2oyYlVroXf=&hp_l8WWhWpmfq=&eCfG7sUjZgZb_=&Vt9xF6Zbenah_=&T_G9gPYdeVscl=&7aep7HYodfnU_=&7FSLrNUYhnanU=&iJLuZLYlmqWbX=&j5PucfWp_XXcj=&fVGLW6ZadXolf=&XhjRQcXhn_aei=&YoYuh8ZqsjYgX=&bkdz2rWfosYVi=&iZhAq2ZZapgZg=&mAHA5NUcWipqa=&byBMMJWVZodir=&HLaelpX_lmVVn=&HmCtvNYVrUoZs=&WMqflXUmlZYdb=&kLkz4VZoj_fUe=&S7oqFfWiViYZf=&EovRhZWp_Xoj_=&TdXv3uXmreXrl=&MqMikkVijjWrh=&X5_EiXXYjldal=&5aqVoeWadWhmc=&K_6qiEZZejUUj=&KZLBbfYejhfoV=&PPY5QRVoocagj=&bLUJjLYklcUYh=&9d5fa3Xappcdr=&IDhbn3VoqfYgp=&yzkKEfVbb_rcV=&C5rQTAVUgYZra=&BoQcCyWgkkgrj=&C5FPWvWcnXoso=&z3TGLvUjpWYqd=&9Kw8d6UVinkga=&vrgBMQZdZbpsj=&WmnjCEWoVY_Zd=&Whx8ssUnWnhdW=&MrsEIpVX_eine=>papCXXeZWgp=&aSEFrPWkplhWj=&Uc7JHTVarVgra=&TVskUcWrosrgV=&vMP6rXXpkdeen=&L4vw4PXcZYXbs=&H7Bex9XdXomfi=&daEWblUYqahYX=&7qWhZYZccshnc=&CzkCklXokkYck=&6dnpz8Vblcems=&JhLU3dVjghjgd=&7JVMJGVVnlika=&4JzhEdWXqabdp=&qzSEvMZmpdobf=&UHK2dpXo_Ubhs=&5YU74dUpWg_ie=&sVLGZfXYqgheX=&57Wx2lYcnZlWX=&xdoaMCUik_ihU=&B5n7COWYhUqmm=<NtCXYfrZidm=&yn8zp7XWfaan_=&8toH2fWmdjUcm=&ipYThsYVme_kh=&7mWQPVZoUhWYZ=&2dCBDAWirdnjh=&8AjGqGZYdjdkb=&miHf3jVoZelUX=&yhANCGZdscmoV=&44SelkVVkqWXr=&gP5L3fVUUlndY=&PR8IycVm_eVlj=&UbxvW8ZnoZVsb=&DhSclBVbWiqn_=&NjuKX_YYrsdbr=&R25kMwUi_fsnp=&5Wamc_WhUXUps=&cevbkmZrensia=&86CHbfVXhqqhc=&whZ2UGXidedbe=&IwPD_8UckXYcZ=&84esb4XkponXr=&F49mQIVmdfWnd=&gikdw2YZe_Xqd=&dz8qgmXefmZhq=&Y6lcI4XXaisZh=&w9BSNrVZeXeVY=&ifMu7XYifgXaZ=&a88pV9VscaYiW=&OOzERnYfmhdsX=&Uc8AIIZkgmcpU=&fgl_CiYWfnqlU=&ZnOFBXYqXgnsg=&Pc3zIQUenfVao=&pAF4lRVpcsXWh=&deP7BpYiZUrcl=&N2dNQcYnmgqrj=&tYZi7rWYnmnhd=&zxffwXVafqkbf=&aliutvWZ_iUbm=&zfIJ8NYianUej=&Ykia_lZsjXqjq=&pIgwuyYlfrmf_=&l4uIGvYhVWaWk=&kn4ky6WdXbiba=&G9SBkJXfZbnpr=&QpibMTXhgUndm=&R2R67xZjsdXnV=&mk3EGfZYkpsga=&HYndk2WWlonfc=&r5wgnlYprbddr=&oWibBQZdqqkir=&SZDisLXUqkmgp=&CCtrbwUfa_bga=&KrSrjeUfWhaso=&dEJ9D8ZZadmaU=&8ROo8uWWrVggU=&QN9q9zWgskcdY=&JktE8qUbqjekq=&4zBOdjUZZUafX=&nhvVypYqeUnrW=&o4wSX_Yesagnc=&XklOXxXmpcdbV=&fqL5b4Xmmodl_=&DIAIC_W_dnWmk=&_QcD3aWgnqbWc=&v5CZfmZhbrcXj=&Lotc3DXWjYook=&VSbxArXrkmmWd=&qvvmobVfpVqsa=&QZ5_rgVnpnWop=&ASeyeTYpZjoZa=&obEtWKYWalkcq=&VM_3yBXVemaob=&VVAqZsXcahqfj=&P22MOxXqW_gUo=&USJkPJXZh_kpq=&8QFQpFYiccaor=&yhhaRkUYfmWap=&62DxNvYcUiolm=&flLfUkVp_YVWe=&_TeTtxZUnVoUk=&mvdWFvZenene_=&ytkgA4VldbqrY=&Gf4rxSWWVnnYU=&gublMvYV_YUkh=&Zg3mjbU_angfo=&QQG_ZzVmiWisa=&7JtGEcUYdUkmU=&jMC4RVXoqoWUe=&n2ag5OVroV_pr=&rwCrmIWjjs_ip=&gTQl8jXgsrXhr=&KKLKg2UUlsblU=&5nPJAWZZqpjUm=&JVaUgxWYmrhak=&9ABPltWYfaWmk=&FNl_zBVoUsXWs=&94UyMUUqrnZVU=&_L4qfjY_ZVZbr=&6TfGtBYkVUcZo=&SilonGUedaVsV=&VA4C8LVfWksaZ=&TTrZLsZmckjVp=&irXbe5Y_coigm=&5DzAKGUrbb_Xb=&kWmIPoZaYYUl_=&FxBWszWcehsim=&fBVHBZVlkahcg=&engxeEWgUVkga=&HHYJnaZgjfUm_=&xgpRkOWg_oeak=&Aval94UlaUcfc=&_BilD7WfVqXpU=&kjqWSOUdj_pVe=&3aYqX5VjodfYY=&jJ9xfYYqcdYdp=&LmByOgVlrXVUe=&Df7NFJWYWmajX=&ZsZpq3UpWdejX=&6TJX_bZpYYanl=&8tEcIfYbofZja=&GfXl2BXZZgfjp=&igK4ibUdsbkZg=&8sVuLZYqfcbsh=&H8icdwViZsp_r=&OxnTeeUXrqYYk=&DzFoOhZsqYYUo=&TfS5sUWmlarpY=&_KyiEpZ_lVssp=&Cuvi8ZZcihkfd=&Gl7VipUjXVijY=&ymvgSYXffeWoj=&FMLG6eZ_lqpaf=&DjnWZtUffqss_=&mVLW6iWrZVnZd=&iL7XXiZncXmoZ=&gSeic2Xssblne=&AcfxavWUrmjWi=&rdP2gzVXkpnrl=&RWuy9XWqdsa_i=&85aHQHYUmapj_=&GVlrC_UmhUWha=&lQWZ_2UUYsojj=&xSiU7iYam_jcf=&qzoKsRY_fikjf=&ohPcpFZUcodsr=&UxbBjJXYoiaWn=&UynwgfWYekmrs=&R2E_MzZYe_Ykl=&Ax9q3SW_leYar=&DNSnazZqpipXp=&A7qFFbXqcpseY=&UoutyRVWq_ecY=&JctODnZXkps_g=&zDao9KVke_pps=&9IPo2fXhmYYqq=&YDw3LbZqjoonr=&xs6TjFVXjhcam=&6tTPaNYsYUcqe=&levOloWnlVaZi=&JqlIydVnhrZpa=&JEImuqXgmepmY=&ShI9pZZgimUsX=&QIe64hWpqppnm=&Qf2uiNUhVqhXU=&4CatDXZlZgaWe=&SaRI5pUeakpae=&CBKrfbUrenZck=&ihnTCnVfcshoq=&vNZrHsZZrassd=&KJpOLwYbo_saj=&Wkao2tZoihahY=&37smXgUXWpsZj=&NOmKtmWVsUcVf=&9WJxK2YYWhaYV=&YJkr4pZbnYksi=&In8yTuVmgeYXU=&wr8V2nVfeqoqm=&gnN7DBWkqs_hg=&8uuGUkXbkVZoi=&NqOFCGWVcnqWh=&CPVNZmVVibZsd=&47WbuLYsilnq_=&hcddjEUUaiZdb=&d9W8HSWifigpY=&VBgdOWVkV_VcV=&2G9XKhVmYpame=&CooSlmWiaqbep=&eM9LqhZaXUrig=&FdegkZZ_mefff=&a3VT5qVVqWVWm=&kwH5viZkdmVhr=&qR4JwyVWspkbh=&8V6l7FVlsjqjc=&FSEIRXUjpaqoU=&dGv94RUiZchbU=&hsEQ_oUVgjlaZ=&ycXywNYcclcgs=&Ow2xRcWUcVUj_=&OEer4zUXhrY_V=&E5YaOrXVo_dlk=&Xjmu79XYcWioq=&4O5k65VefWlrp=&Yv5l9nYXjmqnb=&rP59wvZorqlWZ=&ozwBKyZUfpkg_=&nKyGwaXa_ZbWh=&VGtUtzVfionke=&UiYjaCVWXqeWm=&gDBwDDYcjjZZV=&AIcu3WUYbmsnb=&8KQdt4Wq_lnmf=&TuzbuqYldp_hg=&wXejwgXdmlUci=&s6wYa7WYqejrs=&8XtBVsUefWXdr=&7LctqFUsVkjfd=&CjqKQrXlpWYlj=&beHYGVX_Xbpa_=&qzTx3AXUjrgZm=&sAOAJvUZnYVss=&4AOPA9VorsppZ=&K9bGh4UoefUZY=&JrpR_6UlficUg=&Pte7fUZUajcee=&uNFRKAXdhnXra=&KRYVXQYWnpndm=&IdlEmJYqgofkp=&OLhfCDXgjkjqm=&LgmYZUYorZesh=&hZe22RWk_ipZa=&a9AFFPZggmUhg=&qM2tjTUUkeaWr=&wngwZpXWrVbZr=&hQZpwaUWjXXgb=&qDaiDhVg_shXn=&Igiy7qWbYbnYa=&BGZnHZX_pZXUs=&HLpKl5XcoXfgW=&gVRFj5YbXmcil=&HpegVzZXnhqhW=&us3IB4Xfnaepl=&rjzR4RYYcjZla=&aktmkxUfbUadq=&Kf2IL6VYmjanc=&ABH8I9WniZfol=&7FVggkUgjrUVY=&JpqkzqZnYqqUa=&WifSucZjaVrga=&5He8zGXZgYYoW=&S3awSlZbWicoo=&_4bhxKWqfabfa=&Ge_QM7Usfs_aa=&lbOFCoX_nsbeb=&_4SAqDWXkbpph=&teDXLcUYUVdsj=&JNcJ9aYnXajhi=&DVfWsVZYndpUZ=&sKrt4bWlp_W_n=&A2s5DeYiUdqYU=&dGc44lVrql_db=&HW8kNwYqdVorr=&NjT5q4UW_ldmr=&NCjZJDUpVbWfo=&dCXiSwYdjseda=&6dWSRJVUjoWir=&ZdrRHWWXjYUXf=&uQSZiHZqfWsfW=&7KpXO7ZiVWVkc=&OP2hWEUiWinWn=&6B5KMoWehYngV=&ESRDzXUgYpYgo=&MB34mAVhmgpmm=&AB9qCUUYbrcZp=&SRvUSqVpfVVWa=&E7ccuTYppfllX=&v2dpvHXrVWims=&OmugtyVjmjXem=&GQXII3WZdksYo=&ZC3HVBUYUhYac=&vBe3y7UgX_Zqb=&iyIqduXapfgsn=&OPC4oBZkjiUUo=&C9v7NMZkU_ZeV=&cGZv_XXpefcqZ=&GHJ7DkVUldepq=&hLeWyXZbViUYn=&7lU42oVcfVckp=&LfHtZzXlhiafZ=&W_SlD6VdeklUj=&t4mzsIZilVZUq=&iObgr7UXUnjpl=&oSJXlHUlohUil=&HhVadAXkdeicp=&oPiUyMWefqjXb=&C8V_GcXloWsXU=&gQvs85Zef_qXi=&nXuFRLWhbUYUo=&2Bt_IBZ_Yscbl=&WVXjomVkocXic=&ZUm2AWVpUhoiW=&ycknnjZpsjUlg=&jsm4TBUqUkagp=&Jw3UMWXZfVrpc=&NpsylYXomn_W_=&iCFoiNYalnirU=&ANx3zhXUsYaXj=&FzWx83XeXoVph=&swAFHQYhqhbfV=&dvgvfaZlnhkaX=&yoDwlJUcfoYji=&kBwtpMZgroilX=&djx3RZYrfUeag=&ZJUg8_ZZXrbql=&w8UBfxUeejppo=&UIpquIUeYfkWl=&Rhc4HYVdiqfkm=&JjkDntXrpkZeY=&222uirYihlbbZ=&Ws62v6YigVXha=&qkamYiXklZmim=&hwJ59AVn_hhaV=&ombypCXXYsgVk=&ViFFu4ZmasYbZ=&G7vGxLVfqZVhZ=&H82iNoWopij_h=&iWut2TXUclgrZ=&6xQJxZUqWmbah=&l7bTgCWmmnnea=&kwi79kWpplUrX=&o829ipYqggdin=&35pPY3YrUscpZ=&yqcYjpVmsVYp_=&KF_Ll7VWoqocd=&VZDRnpZYskgki=&qErUiXWjreccf=&27Zf9VUXklqkf=&kfpHQYZqXlUcn=&aUSKepZdcVsrm=&EW6hHuZbhckeh=&xve2rKWoXcmrf=&auSM9xWbdWq_s=&HHp7PZZcVirsh=&iks9ZyVclrXso=&zhUJO9ZbfenYY=&B4c4ruUcXZdnZ=&mikqyTYbUXcjj=&gU6TqFYbhenna=&DkGj8uYcnjgff=&5vOaWOYjhkkdr=&5WmFLWVidcfWc=&pAKv5IUVZgkbo=&a763zBVddWVii=&TJBB3iYYUbUsq=&MSSlRsZcVaqqn=&S6uo4iUsecWZk=&IaokTpUmXsmhX=&kPIvWyVUbdfXa=&O3ooMjXUmXbmn=&OKTxoZXsUVmnb=&TDxBVGZfnifhn=&xyPS3QV_XWUUd=&YahDa3XjhdkXk=&3_yj9XZrpgsgY=&MvtXSMXqWVmjV=&n_VcSXVZXhbUd=&5QQyS7U_rlWZi=&oFZfNbXbagUdp=&QpXtEjZiZakjo=&3WLrGkUrU_nfg=&p6ONMoYZ_eof_=&2wAGdsWikoiUV=&MCJBFFUhggkiY=&owmSHDYilpZrp=&wNQYN4VfYesiq=&VEnahqYrndWUr=&m3hiHEVoYkiWW=&etU_LpXb_hghk=&Or6QPDUqscnak=&8nHQdDX_cninp=&t5FsHlUsqbXWZ=&JA4cdhUfrcUpa=&tEGzu7YaYoiWl=&Ja7KTtXbokVVk=&8MTmH5VaUdefp=&nLIkfdYZmppjV=&Yr_adiZhlnmli=&3q2J_TUidcssX=&KuuRA7Zmdap_V=&zGD4czZUgiihj=&QtOBlhVVkpbUd=&V_Mc8PXcrcUXp=&nqIM9QUkrhjrm=&Tmz62LYs_YiWk=&rfBFYGUYoWqfa=&xNKARcVppbWdp=&5KUu63UmbkeV_=&vUYtGOXdbgdqZ=&Ff4t_GXonofcW=&pUGXBpYoqfesW=&j5uMJxWVXejXe=&zWQrj_XfXcnbZ=&jLlQzRXjslUUd=&wm_V6aXhase_n=&3XnlAKWmWo_si=&M2hTCpXbknagk=&D6RhhjX_palqa=&gBEYvzYndomYY=&p5pM66Ude_WjX=&Vbum5WXcqkehh=&XWIg_tVsfmpee=&TzEm2SZdrqa_p=&gCyeDsZZgmkbn=&MDSWDcZpimYj_=&ru5GHiZsidfki=&WUVWbNXnkUhqn=&fXIfTYWsjlbmW=&toHGSDZfVdgsk=&okzjX9UWWfcsh=&5H58BRWhjdXcV=&O2CaxHWajaklm=&5qaP4tZcjsYdb=&ugqyPHYplVqWs=&okNca2YaqWpga=&iCYxqmZYVogUU=&psz2x8Ukm_jYl=&ljvYeaXVXXVfe=&Cq57BdYboebbk=&cPWbWIUaaqapo=&324xROWfcZbhf=&n3arjTUlWnpXp=&LtSGTAWbirscg=&gmzthCWhVmZjm=&yrlriMZUWofYc=&oPMQggWbXnY_f=&8lqFmPVemZoXk=&aRk5wmZXUfeeZ=&LNP3sqZVkVZYc=&wCr_LpWhidgjf=&igNpEfVhWrisr=&MWt_2cVZighpj=&qihX9_VphXaar=&2u59xHXr_qmhX=&ccmfPzZZfYsif=&dR7pL9ZoUZ_js=&bu2V9tXosVUZk=&S3t3wQZYjYgXr=&TmSkaoXcUohXn=&hmgHEeZbXYgln=&6ZnW8kYlnpacq=&XQlYDMZXeZcsl=&Z72Js6ZdXqk_i=&dAHKCMZsYVZee=&CY2PmqVjbbiqn=&_9L8c8YcmYmZX=&2Yib9BVUkYbkY=&AWknpIYmXasZp=&t9skHsXbUirXf=&6UOiWtVocefZ_=&2NpcurVa_bpei=&2NNDk3UUZfepk=&K7KUn4Xlrqclr=&BZPvyqWokXUWW=&F2iaj3Vskbdri=&gkwOVkYWraqho=&gCB5LwWrUcmaq=&YUfypAVijYdVn=&XajruLYabZXhr=&Dk6px8XksbYqU=&hwREbPXU_Xaih=&rd73gyZqepWmr=&vWyDQJUbnVmfm=&jAFIOeUYVVdoY=&S4iJu6WpoUkar=&jFaTeAWhaklk_=&Ki8VgaUnXoaon=&_vAJkCZpbq_Wo=&X4Jf9bUkXjWiU=&nT8RL3VddifiW=&aAI5QaVVenXrY=&iBHkVTUmlabXW=&tQzVmTUdcn_Yn=&zITozFUkfemg_=&5c_ZCKZb_rZco=&PIfdLeVmkmcdd=&csV_47ZWerqcr=&IcVdpkUhranqb=&uR84kOZgrnfe_=&alSiqzXqcpVpd=&4cIy4UY_iXbVc=&nj_EcIUgbpqsd=&e_5ltnUqjdfaV=&y86qkEVWrbYbh=&XVx3XnZpYsnfq=&Q3NwlMUiZWgaq=&hSq_l4WXWZpUd=&nKOtwgXiYaaae=&Udkk88Ulgd_ge=&sPjQbvXccaZUV=&Wxm6VpUUp_hsX=&fF23r2XYrahhk=&JOk39XYagsgZm=&Iq5YAYYdXUZXd=&qna5m6ZrgjeWa=&IKwnu2VjniXel=&VMRmLZZi_oXUV=&_WoK5WWpoXo_b=&XkPTQlVWdgYja=&Ig8i_6ZV_lUqe=&hGCCUuZorYWjh=&O6BuaRZdhoqch=&ps9UVpWerlpep=&_bLN2GYmnfih_=&6CZcmAUskcgdW=&4qCYpWYfXbbmV=&P665AMXrpiqYf=&h8NTmRVipdslU=&Ileuu2UkcXkkU=&H_ENCZYsU_qVZ=&LkIvr9WrqakVc=&IJFsgkUb_rYl_=&KuglruYmjXleg=&2hmcJ6WbdrXl_=&Yfk3q3XsjZjoa=&ya6wHMVasqkek=&Xy45wPUXarmqm=&8SCtZoVkWklg_=&QFVbsFXfa_sbi=&xToLXPUVndpYk=&AvHX6iUVodWWh=&Tjr2J6WsaYjci=&GNsOw8WYWYgmh=&Wt9MtAZaorpUg=&8tOAUeYobsnrc=&wCjmftZgcdpaV=&hPmOAvVZZ_gVq=&nSEEkwXWfabkn=&NXL2HlUcZlWh_=&FIhCSGUiZ_qaU=&gqq5o3ZogWcgU=&ek3d6OZa_hkZi=&VkPBw3VohbagV=&JnXGc8WqjeZda=&s9obF_YUWWmkf=&Xlwh69Xiioc_U=&L_ZOVPUpmirfg=&d2Q4srWngrfrX=&VoUdUQWWdWUrn=&mhHjjDUlqqdlp=&77CvgjXcldnfk=&8rfThKUdZmdlo=&RPqGPnWqisifm=&kl62wjYZXkWqX=&J7a7xvYje_YkX=&bdsm_5UfVkrWW=&x5xI9qUi_bkgs=&kJNYccUhnWYah=&kPY_6LZqhdg_f=&FvgPF2UV_qXke=&WobFsoYqbaZYh=&jC8PgQXXmgW_W=&FnRHzqWUceifl=&8jZap4Ws_YYsg=&K_UtLLZcrWbqj=&XhcfuLVWZq_kh=&U9q2oaYZXiimg=&D9G_vxXoonaqo=&uB5Hi_Yirjgar=&ELbw5YYbalUrk=&lxSY8vUdhmZhl=&FuE_PhXodZ_pY=&yTDyYfXXaYWWo=&aYz9EsXsoYeml=&ljQcGWUZgrjbb=&lwtcGSYbUbpqW=&KujFlmVX_YYbf=&UIuFzoYbeUego=&vm_qdfVZomfrs=&aE6TgdWrUf_ms=&WzbD5zUZnnaiq=&wR4IRTZUXVcbd=&qoef_9UVVencX=&sMdNO2XibfrVZ=&NAhxKNUiplgir=&8yGK7gWesqerh=&ZDpAkFVsobcro=&RvwgI5XUWbhrl=&JxF6ZxZsjosqr=&nW5s8LYbVZda_=&kTySjAVadVcsa=&Sp3NLtYkUpidb=&ogQrSCZkjYpVi=&tUBntMWXinopg=&wVrMw_ZefrXUp=&Um6gS3YcXmfnj=&KQFCfzVdklcfc=&MSx85rWWbgkpg=&s2s5FQVgrZXbi=&aRtUd7UrpfbgW=&EzdBy7VklUjnm=&F2INaaXaWbqdr=&9Y6_8qXd_jndi=&fqoCzMYrkigYU=&sLGqpvWi_apls=&r4GvXqVkrYsWd=&HVWGG4WrhXqml=&EKAKYiXmeqUsY=&xTkLDTVbnrqY_=&47YFifYlsaUeX=&o_VssdXWlmZig=&hMcmKQXg_lems=&hyf7N4ZsZcini=&KG3QSqYhrbooq=&XrPbcqUrrWXec=&eGb3A4Znkqaf_=&259Ec5YVXjked=&RttVliV_bVliU=&HE3W3MVXgrgZU=&QPBKBaWXmbedV=&Yor3qiWlgapai=&5N36N_ZohpZlV=&ivxjf7ZdsqchW=&Q2GQMsYsmYkpV=&I5N9fmUpZZh_j=&6Hh9BPXqZqWae=&olw_4eVWZenes=&YEPpErVXecfVc=&izLlcbYmjcWkk=&dfZWVuYjU_aas=&IjanV6WiW_p_q=&2Ehi_DY_Zdihb=&UgzNmGZsUr_hY=&QvMWD9WeXXkab=&EqWjYUVnso_bl=&EeV9mIVlrUhlV=&GWQDP6YWXiapa=&FszroAXklUmpp=&9VgWj_Vaqhmpa=&7pjHBJXVlqokX=&oFXZ85Vfmibjd=&DTD4STXXghf_U=&FjHPMZUfYmeXk=&37RCioUsUhehi=&q99pKDXollf_b=&WygN58VqshYb_=&a9keY3YajfWsf=&nrcK4OWseperU=&gB8_EbYgejlVV=&mmvnVfZqlcfoY=&oDfNQ_Unlin_l=&KZSDxtWg_WU_h=&JokLdLZXjfVjV=&FmH3DDYVfdoVn=&oh4pePVXbZZjd=&x9VfEWXchZdVl=&V_xHmvVkpaXeo=&LrqqDsUW_ZU_V=&3JW77oZcgYUiX=&l767swXnoZqrl=&93ez9jUXlbfer=&iLbn6RVWkXXWr=&LqCeJLWqZpigq=&9XGtsAZcnrYmU=&rBz3Q6ZnrWcfd=&5DB_teVVslj_e=&gsS5ctZisehoa=&DSQZPdUcdhaqh=&8YEDsyV_fghdf=&JEvb6rUkijolq=&whAjLzVnfUdZ_=&4mVg9XUcpdmaY=&dAHwjCXchcb_b=&KAEd8lZoUbpWl=&j8NlRfZ_ajabi=&GFAFj_ZXVmhee=&vbRhgmZfYqVZj=&HXzUdxWYooYhj=&5P96XSXfnYmVo=&pG_G89XosalbU=&mdFLAFYokhYsi=&VUpWQ6UpoXUnb=&ub6k_7ZWXVflU=&Tb8JIgVogqnkX=&Pm4OvHYXnXnVU=&7dG4wjXhrajpl=&P_fPZyWljlqph=&FRtAwXZVkkqlk=&uDfLLGZbkaboU=&NuPESKXmpXXYl=&_xIFnbUUdschX=&swUAd_ZnXlVXo=&hd8eTrUbijaZh=&IJ4cpLZlqfqnj=&Gx5kYEWsqWjch=&xzA_bdWnsZX_a=&ppL94CVYdUbqY=&Jf8sP3WbcVqfg=&zoJ499ZVrYiYl=&bQ2CFDYiXWica=&lDH9QGZlsjjme=&dJyoJTZpfepqV=&OIeTY2Vel_lpb=&IILQJ4UqYVlrh=&3p2CGHWsaUqdl=&cWU8qMWWossnl=&aISg8hUbUmrYr=&3iet93UZ_bjmd=&CacqLWXmbWcYq=&rlZkHHYrrdmsV=&xThVC9UZcim_W=&h_dbMOXkboeam=&Lj5hnnWYklgbi=&6Czy_sWUpZYen=&vykLa6WWZZYic=&nCsWGbWjmsZjW=&HQydieXfkXqYm=&RgGcnmXYrUspk=&zk8SivWbZcsZn=&bRXeBzXnargZi=&6K_zjDXV_aZak=&FHuhPhXXdaVVd=&d2aBS7Vps_b_p=&RkKJTkYdoec_f=&p6a8LsViaUmrj=&E_QYE3YpqcmrX=&3hzo3BYpkViYe=&eEAGEaXodYdfj=&eZeCIRXrYgiXm=&7mOsYPXWhXWps=&GzOod9Zank_fm=&usTGT4Ys_oYc_=&PYakCBWgWfaU_=&ldmHDBYhbZ_Wj=&5cakPRVmWaoci=&lT73VoZmlVchY=&XOlgycUiYZmjh=&IIUPyhWnpUres=&LlcyYBWVmY_in=&JYqCVqYanjWil=&uOJM3pYjXeer_=&_F8TLxXonmbeb=&YRSgW2ZrZejql=&ihFqcFWrpXeZ_=&srQMJuVkiaXsh=&iXCgjTXXnqaib=&hNRZciUbkefiX=&ERY5xmUYfeiUg=&9e9BdyWkVVZqo=&2kPSNbVnfYeqa=&8FbGSSU_krhrh=&j6vB4JXcUahmd=&bLn94RWbWjekq=&iucmsTVWhokVd=&jqAYkiVojccag=&ifOqoPWWeeeWl=&rmlnKMY_kUamU=&6I65lIUqhdpeV=&GkkiMOVreilVh=&jKd83uZqishYc=&H8rJkuXdVdreY=&KOnpJ_VhneZos=&MLnov4W_lVfjn=&QMqbVqUna_W_a=&Le8P7zXfgUlhf=&oIj3t6XsoqsoX=&4Kbaf3XrmZUUd=&LaUUxzWmUWlXU=&7ZbVcAZbpobaU=&p44ZJSV_Yagh_=&g4Ec95ZncooYk=&zZEuWFYaaZnbn=&NOWqxQUUojZbq=&P6YgLRVjggbkq=&aw_SGuYXWsUph=&yNpvbCUaiVshd=&iaoBgvYsnhmUp=&95LHuuYogegsr=&rMrO3uXUWibjk=&y_8LBfWisqsaV=&xmYbpyWepjdhm=&jn3yAeUYcXamm=&YSVvrFVoppaee=&sexUkTXbcUkUX=&9NCk4bWYhsZnf=&gkNNhiYssprdh=&67wfSAY_ZVaqj=&GBRIM_VVqpVip=&MbaRXIYalXbnq=&jqpFc2ZcgqWfh=&OoBXNOVeoilZh=&oTILrLZYeefsh=&HZUKfxVabZmpZ=&PVhtIRYnffZbr=&h8HsQ6YUpkWga=&6wNIe2ZfmepUl=&kbSJo3Vifghph=&8yqnRbUbkdgbi=&KrFnZfVjqilZo=&GphR2ZUfrp_gl=&Agg9YxXZgUsWe=&x2a8zvZfepeng=&72JxdpUqlViWc=&tHztY3XdW_odk=&LhHDr5Wssmgae=&eZWCLAUfhkpcW=&RtU5tEXkielUe=&s8nYIpVpirkYb=&VDfEVxUVllnmi=&O7XJcTVnZnpWX=&YDsgQAWVlsmnp=&76SZyKVe__ZrY=&mRA9PTZpbYbbh=&JkXTQqWnmZlsb=&vOmXaFWndrpjb=&gmDtYeYVmjmZc=&LqObVjVlZc_oU=&4DoyzVXmVhUln=&2RbzOMVophfkf=&CzfuYMYnkpWri=&iYfzrbXrXefcr=&AM5gHLVfhdiml=&FaFJDrXhXijhf=&IesRFYUVkrinU=&wK7vxeXYlfgYg=&gk2lUcUhdYZk_=&kqadWUZVeoojb=&T7eX2xWlVbdbU=&_w8iYRUogpfqj=&JROZtzYcajXjX=&h5EPJUWhZgmjX=&ez6OxNUirXiVe=&rGOLGSZsUXbWi=&ake4SEYUWniXg=&g4A9CsXZjWaif=&gDrmG7UbWYbiX=&8Yo6SXZcrcca_=&maLYeGYfhoUVr=&klGgHFZrXasfm=&mcGaXOWYZaUod=&LL_YjtUfYkbpo=&uLmJVdZh_fmmq=&NJSMwSWqbsWkk=&Rb5uiEZqbiZis=&pLklSYXgWoXVb=&j_zSyIVn_ggXi=&qQd3WcXhXmllZ=&NHJt28WqXjWsl=&zstPo5UhWeerc=&ObRgiTWVfjakZ=&xIluaJZkpZYdc=&S_TCbCYdabkof=&FvooJKVeUXUoW=&gKoVIUZsiZ_so=&5Ol2LpUdonVi_=&GZQntDUjZgbmg=&6WWcu8VmWneXk=&7RCoUhXsdYnmc=&Q2DNEVZVVpgej=&_GfbQqWprgXcW=&8LM_fxZknUlig=&VqNSiKWdZmqep=&wGkfp8X_aemZe=&UtGb8EYdZVXo_=&nJzhMjVhVVnhm=&eDzrThUfWpogg=&NQdgAAV_Wjhrf=&egKYsCVeVlcgc=&PruNgsUbddZqe=&_4V_ftYhqcplc=&QvL63hVlsjoea=&RMGGdeZljXarg=&r3bGMEXjXof_Z=&VdO9pRVYqXjk_=&UMbTxEX__ZVZW=&SCdr7DZaXYaVb=&ZtosUlZhZqal_=&bQEMcKXeiljrq=&G2hvSGVXYVX_m=&YYJP5QVdn_csk=&HMpoD2XdUlVha=&T9I2aAUkenUse=&ObbKPmUnkkZpb=&Na5EfhVemgajq=&uFM78GVXXoZrU=&qoCwl9YsggWVr=&kl89duWjlmWpZ=&EURA83ZhbZngs=&LdvDRqUnosrWa=&HCy5oWZpYmfif=&FNSnx_Yni_YbX=&dpIJiIXq_ahpj=&gbvMV3VgfpYmX=&dfTSlKWmYoekl=&JWL9UaZ_qjUgp=&nEWESnUjXhnsd=&HtLRvfUdUqppg=&3CLSgmUYijZln=&SpEjQpWcqdUgl=&XA2CNzVUqkald=&ohuVXeVZansih=&Bal4fgUijhsYZ=&LbTEVuUfUcUmW=&NGKPvMWafpfif=&Y2D3pIXd_sYVX=&QV5PKIWmYZebl=&9anmXnZsaajms=&UpL44CZheXVkb=&plFQt_WdaZaVg=&gcHmn4VUrdpjl=&2mKVdNXfbZirY=&Vu7o7FUZsgrjq=&hYIgehYVildks=&moaLZqZVbfosb=&KZngsRZbojeih=&yklxXiUUanhVd=&NgacjXUc_lksf=&DSuR9UUsUhVpm=&ZZJ322ViUnlad=&SkL9U7Zha_ZZm=&LVp_RGVlYrVlm=&bEgTsFVqpmogm=&B2mBSIXnWaqae=&egoHpUYsjjgZg=&ChDgWeUbrmYWV=&v_pRgqZgrl_of=&5UCW4qYhoXlmd=&6Taxj5Zlffob_=&OsMsCwZjbfijm=&ar9G7YZjlomVW=&EFX_m3XpWjYic=&8TRECDVVmblfY=&jZKeuNYjsbleV=&AnQ9VnZUi_nbl=&AZyyHuWlfWYmZ=&5NceujVppgpWb=&7XvdotWibYfYj=&kXQrcrYrfaXdW=&2A9KmqWrbZbhX=&WRuQXHXpdgojW=&NfLtUnVjqoceg=&fOPfmWZfbiWpo=&QhgBuzUdeieji=&EKUwkCUlocsgY=&MluQB8Wlr__sa=&duiUD3YaUXYsk=&sQVzRwZX_afVq=&8u5evoWllZnVk=&4jZJqBYscrfcW=&lZfQ9vYpeXWgj=&SYetnBYbsjY_i=&SWW5gTYmenUhY=&sYSFghUdkYclZ=&kO2t3rZpaXsmf=&z_BCvlYW_dkbp=&jkEiz8UmqmWsm=&STyBSMVfhW_mk=&_Zw4WvWfpejXc=&SXGV7HWYmq_lr=&jSv4QuYhedkrZ=&6uKTPvUYbegpX=&z2lLnvXiYYmjh=&wmmUvmXUklomk=&ZnOYUZU_YVaps=&3jWSIuWoeZnme=&SWeKQXYjqokjY=&s_jGK8VaWifrY=&La4AtKVYsZdf_=&C9izLqVkdrVcV=&p2Wqp_UkolrsY=&ntUaP_Ynefnnq=&9pVYwcVhjrokV=&sfb8_mYhWaUod=&MxKxoBVchXagh=&nKemnSYismeqZ=&G9rvjyWojUUer=&ETqNSPVjobehm=&kktyd9YjU_Wog=&ibsSSKW_mlgbm=&6ufQMyXb_lisq=&fsTplQZopdrdc=&AETCcSVsakflj=&a7HZpMYhUhbji=&sMnChTUmYgaic=&hel4ZTV_UrWhp=&omCuDiWimahkX=&vrQkqWWeZXobU=&9ptHiaYslrbUp=&Zjt9pTUUYeYbh=&yvXtccZknZj_e=&DHI_IWXWlbrqV=&xyt7YxVWYZeXr=&2E5FowYnXXsfn=&_xNeXqZi_fdZo=&Zaz2uUZhUYVnc=&QT_uY2ZbgreWq=&KQSuiBUXiccnc=&inUDoAXeZjXdi=&P_fYH2VVlsaYe=&u2hxZ3WebdXVn=&3qDVRSUklWqoj=&fOePd6WfoUnpW=&bxclxnZhhakkV=&OdmAhjWmUhqeb=&MTmopyVc_nrZp=&OV2XBnXhWagag=&hwKulpUer__Vk=&GhElCuZ_jWW_n=&4P2_OpZYaZeja=&8nDmJnVdrhdUr=&K4aF62XVrrcih=&LRISLvYqmmV_U=&GMaPDhZVoYofp=&uhBdofZr_q_pa=&6DZEiQXUrmjaj=&d4TjBgUbpolch=&dtGxZ5XirmmaV=&uNbDiJXkkUggs=&mUe3q2WpfpiYd=&86m6J5Xjbcfqj=&ZFJKyBWVpalbV=&mXRYLOYhjsnYr=&5mugQYYUlkc_c=&nM6u6NZZh_dor=&lGKCPrYfrnliU=&j2LaNsYlisaVn=&QIOW6gUkoabWh=&lq4E3uXejgrhr=&jHg9RGVgVqlcb=&rTS2YPUfnUrme=&eWNT4vWsWieYV=&TTtsR5YZVpmfp=&9wergLZfVohah=&tu3bmLUeipfrl=&tui23hXfiqUrl=&vuYrWIYViXlqU=&zEyR6nWmc_ekn=&Y5ZD3RValgoXn=&gH7APsXbcapff=&q7ZaMLWmYjrsn=&f_ehTlWbhWWUf=&ivR3glXWpjers=&JJjn6kVmcaafm=&yfSfANUkUebmX=&AX5huFVskYVbl=&XxU4PtXoUdjpi=&_mksgkYrVnell=&ueJgX7ZmaiZdk=&FPDbFgXslWaqY=&DKvLq3YgYZXcs=&C5FiCYYpVdofa=&wRaHVKUkhZkbp=&b3GN4gVnYmbap=&ZBPYMLZbajjdU=&TmRfoQZckZrra=&DzWC5wVdesaWp=&V28g9OVb_disV=&iZtwIlUqno_ra=&HjTglNVYomXic=&Yx9akiYsmfsrq=&f2lMdPXXl_lVp=&fuNZDjXZihYnq=&_rMQreYUUYsbs=&UBTzsBYqWpYqe=&E7qR8WUsgmWle=&863NJTYq_Yoff=&wJKN5iVrW_ojc=&9VwLpjWhlpbVo=&Nj3oGVVpjjqU_=&WrX2gyXcplbio=&K3rQGXUWUakrg=&O9JaWIYccdaaX=&flpWyCUjnabne=&GdpyH7ZZpiXXh=&gJ4lp6WnYrhmp=&jnvDP_Vof_YfZ=&lnnlLqUWafkUp=&6ko52JZncia_e=&MObQ97UfUhlpq=&LmiHXjYpkjocV=&iOKX46YrnYolp=&_94maQVfadrjh=&4ZuAHlUcljplX=&2ZNQATZicsmkU=&KtOSGlVpodfmb=&ZHZjGXWcbqVZh=&Wjt4HBZUkidYU=&awiFqAZomV_Uq=&mcSsJ5Yfgqnko=&gSZQJ6Yl_oomj=&QIxaIBXlU__Uh=&EGtWIZZegiUks=&WyHnVCVejbWnm=&Tsf6nJWh_UirU=&W3dVnfYebZsiZ=&_9YZgyVXXaqgh=&ZCMRXEYmUjlYk=&XMdpKtYoafWem=&SyzXQyYfZecrm=&YZ5MM4VWrUqdq=&jUMteCVndsnfi=&ZzOjGAXfiXoVs=&ysuTi3YgVdddY=&zEZLepVbqZlYd=&zjGVyXYXiZjsq=&iSDH98WgeniaX=&nOa9qnUcsmpfn=&fyZT6JVnejrkq=&YBzbk3XqZXUaV=&7hA_P5Upfa_bg=&wex4E8YWdbfr_=&e9MjMbXgUggic=&AuFAWVXhgar__=&Vx5k9EUohUolb=&JX27G9WYqXrmc=&iZInkBUjXrmgp=&Zpp2luXhqpXas=&CApSIzViq_Xrg=&WWjuTMYlpUVmm=&b3ewHQUjnsgoh=&5QaFg4U_Yoa_f=&OBpXCRU_gpopX=&xX7ip9Zq_fbUf=&HHAg4nXjVUjbc=&nyasT_VnXaeec=&LzjNhJUYmYeha=&cDvbVmVojUeeb=&zY8AyXZbmosld=&FIy98IWs_aVrh=&QfJmEvWVZlkcl=&MU5F76ZiUcnij=&O2xmQQZgfcWsX=&TXtz3UUYbpakb=&yXXDFcX_UVcZa=&WEahcKVafeaVV=&uIzNNBVchfcjh=&ts9_HgYqiWhfb=&jdoKFtViqjWre=&NyRas_UiYsdhr=&flbcf3VhW_bio=&bmUKkSWrpoicW=&AtD5fBXsbgbia=&u_MQ9TXqkgUlo=&AQjIvuXeVpqec=&hGZIk7WfUnZhj=&2NheNDVaUhgbb=&bDe8plXVaiVje=&uX2GzAVglbXoW=&Wlpz6_ZhkaYr_=&WJ4sVcWqsrYaZ=&oMiK26WrfdonV=&zRz7DQUYZjinU=&HOMxdcYplldom=&EPusTkVcfiZqa=&pHTHnYYgsjmdm=&8sWAkEXUdbhdp=&Tj2tneYegngrg=&wQ9JJVUXdkUrX=&Ys5f68Vecobss=&LWVpoEVZrshWi=&wSxG99XojXsWn=&dJ38aTUbpferh=&6ZaFe3WWcXdeg=&JbTKTXZjhUrqi=&dadA8FXgYbrks=&niuuD9UUWUfkm=&FbjVFsXjhfojZ=&rU6PbQXbdUjcZ=&dqTQKMWZslWbm=&lmEKzeWrdlVib=&jwxxVlWmoomek=&2qG4nyUjsVdsX=&f8dpYFZfYssg_=&mcJguYUffcoiY=&vZSE8qXpbglsm=&LOY32UXnZrd_c=&YtMM5cVeZcVlq=&vMlr4UVpggXke=&fgOn7GZeeejZe=&f8gDfSWnmgqrh=&twP2lDXrUomnl=&iKdQhOUXedrkk=&4HbjplVqpjoqi=&eevxBrUbf_UYV=&mTcEqiVbarn_i=&DwDdyMXUVfbYe=&LRDKmDXff_XZg=&dVhvIBYgXZ_hl=&9qdDJ2Zfflcbk=&cGVA5vYYdrfZl=&iqjIsFVdV_ipr=&4P36AaXpUcnfW=&yQ7RJfZmeoach=&C36ANpYVoWl_o=&65KdK2ZjXmnhX=&LzhGGGZnklani=&DbYNo_Wdmfqrd=&B9A3ftYs_Vgje=&C3Fki7YgUVlrr=&F5YxtjWld_Vnf=&amBkydZWpgbUa=&lsVR94Vplekcc=&BnfDDUYiksWrh=&MhTAoQYgXZoin=&MTPdTGZila_iV=&AIR7RJVrZnsie=&ERtaJyUepUWno=&BZqUg9ZUfWnsY=&oTnUz4ZYYcbho=&NqdyfdWbhj_mk=&ZyMNabUsWpaUf=&PrJvm9YmdZj_s=&F8AXYZZ_jVlen=&tZWvKmZnXfVdq=&3SfxLHXkqUkVj=&7OEBbWZYVfYXr=&aX5akRUrqf__V=&TK6QcTZofZcjm=&PFM6L8Zghmepb=&D76HEnUhjfdfY=&5u7YIlYeZXprk=&pmxVzUVVdemim=&FIZ8YTYrfdfcj=&yipffCVWhYifl=&zIxTaYXgrrlaa=&mx3im5UraeaUX=&yOLLqtWbUXVjU=&mj6yRYXWVYYlV=&J9IfVOWgcYfgf=&iOyf_CXenrWVa=&dK8MZXWhrqsYj=&XtX4vzXdodbmb=&h_OJSpYqrmfaW=&h4H_slWXWaVZe=&nbFWeMYfqUlbn=&oWr8JgWVakV_W=&EzL8XeVcqoeUc=&EJNDjQXsmcY_s=&LmrmcJUagWcka=&PGYtYOUga_jrZ=&bxEjLYWepYYVV=&SW2m3AY_nkmhe=&9xe3rcWfg_Zhm=&vETdR7XhYgUgn=&jKyMmWWirXmae=&7DKLhIWkjcp_e=&C9YIkBWgjrehr=&B4a38OVWbk_jj=&qE__ISXVefegY=&3UHBQ6Uclco_p=&82g7MtZaerjXm=&72__eSUX_fpb_=&EkIBbIWfbekZa=&W7lkREXejhXrq=&YADbMCZcYgcpZ=&oen3ImVZhZhqX=&pTghKoVjcaeYi=&vS6c4mZlpiWUf=&RJHCPLVZioXVq=&Xq7tjoVjiVknY=&j2RrrXVnmYXeY=&zpJjW9Uelgral=&BELmkPXWbrgmX=&kKT_jwXcfkclk=&LwE86RVjXfqfk=&AchXxHZdhXcsf=&Kw_qrOZropfiq=&GeIwa8Xh_jdZn=&Z3LwCWWqXZXcY=&FlSZ3ZZipdpbc=&2l5D5UZanUmfj=&FuhMnWZdrlVfk=&lxOFWUYnjhjdh=&XA9ufqUpZheXf=&IBEnYHYmrnasm=&XEPwIjVsljaZc=&ywFwmJUfYisqe=&pOyd5RVkgaZWm=&oVNV5ZUsZgjds=&OqlYrrXsj_dj_=&8vv_VzWfmgUha=&BNs7XvXodpZpa=&I6ydG2YoigVrm=&iZvUbFWUWVjbc=&IJfjmBVXYUfXd=&yQ_IFnWohohid=&zxOwCTUpnVbpb=&QY_hx2WVjhrYi=&d3Dtb6ZsafoWs=&iC4_6DVZhYlbX=&K4vY4ZVV_ijZf=&EZiqrvZWpbsaX=&oWOopjU_dXmhU=&9H9XbcWegVlWq=&yXM6w4ZdblaYk=&xCBN6ZWVZohYZ=&tlOnTDVmiXnf_=&iDdy3AWYYpXmf=&S5FaAaXXpsjhX=&TsXOlnVnnknZs=&kNixzaZphYVdh=&ohIJ3dZasgnfX=&UPyaDxZslpihm=&tAmLSiVWjYels=&eQ4v36UXXrVcU=&gfnVIjW_rcroX=&qrvx7eUmn_inY=&pPF26bXVejiXd=&IZIup4ZYVbXcq=&iPPEoLUfrfVVX=&bHlMcSZZorYid=&vwkNCxZirsqoa=&Zqvd7ZZirXlal=&cGes9XV_efaoc=&oh3HRHZrkgrjj=&4_7vzQWWhhYjl=&Pl52kkZe_bmnb=&6hC7QmXrpigZb=&u9w_ycYpqjmqd=&QCO9EOUVjVfbi=&FRYTIaWrXsm_a=&itBeUmVdngfhi=&ygf2HrUXjZYog=&5fpHsGUjgjped=&YnMUJlZVrl_hX=&sVowUqYckbUdq=&U7cNtFVrkZVjX=&kqQDZLXosVnWh=&rq9hsjZrjkdVj=&Uwk2BaWibsfpo=&FKGDMHVoacoVY=&36ouGSXakUlqg=&ccZ8z4Uc_ohai=&N8oW4QYdoUZee=&8Rk3F6YYkokbg=&oKTwuNVkZjaUk=&9z5EuGYVaYjbj=&PfFeacXpsXrlh=&XzRvtSUZmUcen=&VCM4UVUpU_pjn=&DzRFHuZhcd_UV=&h_pyBtUrqrUpe=&IkYJUzWc_sUsp=&cvmzBGVVhUiUX=&ROiayRUbrWdnd=&EXBVRgZkVqXak=&Rc8FPdZmiUlqq=&IVg2FyYmqk_Xl=&v_4HZhXmVWasm=&FuW7yZWWoXnsX=&9J2Nl7UjUb_od=&RgpdXXUf_UWna=&khAsCPVWhogja=&p6UaW4Vpioqqi=&eaYvqRXhdfaZ_=&4hGTkZVhZVlkW=&cAMRiKVoZYfWh=&rCcTD8XmXmVos=&3EDCYEVXkZeUX=&HpXV47XdYcU_c=&ClA2GGXeqsjib=&HajLzVZbhfeoa=&wMiW5oYVojgen=&ws5S_MZralUWg=&wxtRlIW_nbqVW=&l8tMVcXUUsVfW=&FlZx6GWYqblVl=&PIKja7YXrlfhc=&EPJfdlZVqVs_V=&CdMVIPYUhX_sk=&orP7ljWWjhadc=&yD9ZHFYeVmqXn=&Tll_H3W_UgoVq=&cMqdIwWnlbsYX=&kCgE2ZYblfjUf=&HS7kLjUkljUUk=&PCulvnVVdUimq=&POcDuZZlcWnkb=&l9YW5HXrsmhei=<A5FfUsqqVhf=&uIvH6cYZnnVWo=&QIHHI9ZmoqpqX=&7ix3vnYqWmden=&OJQFWbYiYn_id=&euPRwGXdkgYal=&gx8oxHZZnUjgV=&eXztYcXfhbpen=&SbCUyGWqqgmfr=&LqMaCLXZblrmc=&wmozp_VdfiiYk=&X3J8sRYkVZbcY=&y59Fo5XmUaVZn=&eFObZ8VhVcZhY=&Ca68PZXrUgelW=&UOdgbVUokoUUi=&Rh9_TkWZoemjc=&q2LfomUWUcksk=&8CSeLDVqqpUfZ=&oeiYa2Ydm_Wh_=&RXi4mvUdn_dsc=&f6xWoaXfWdVWW=&P5i8AzZYhfViW=&hcuTF6VfUYgrc=&Z_oRxeYXmojoU=&lvYlr3ZdrUcoq=&MeLZkyYbrsYnm=&sLLZy8WgYcnmY=&trNIzuZlZdkWV=&TRhjPaXnnaZpj=&_vw6GAWj_fhgc=&MCaPwfUYclVZ_=&oBJTSDWoagWiX=&BtRMsuXUalqmm=&zvloRDXriXejY=&pEL63jUjnVnml=&Zr4rZhVVjoeqo=&GGgJxGXf_iZkU=&kBKvNXU_fVlrf=&6Bfr6gVnconjc=&8mFWFTZVVceoa=&K5LiHXWmVhald=&t_YCbAUbVlrpo=&u_AySOWokikil=&b9GWsxZqUYWnX=&jOfxGJXfZVcje=&l6tAkDWiZgesW=&8JpY9dXnpgrZU=&2LJmGsZegnZfa=&SCbAu8YnasWWs=&3Sgo_NViVfcpa=&bcaSJPXVcdkqX=&bK9gjnXsgernj=&_kFaVQUnqUsms=&dOTnrxXjpeqql=&lfxeWQXfYZefk=&3jY3lcYnaYioU=&K7bZvDWbnlUdd=&pTHNzQUjaYigf=&85owlDXsmk_iZ=&E7RMePXmdWg_r=&FlbXZvVsXVVkb=&Bv3r_wZXh_UrW=&FXkiuTXbgijVa=&EHdfooWmbbjgr=&KL5jM4Yqhoplr=&xPQYHvUXafXkc=&sxor6QWsUWerh=&XGgiZWUrjVkY_=&V3he3yX__Ylds=&8Cm5olWmpgcdX=&7jvlXPVceYpgs=&E4afwcZgknYgX=&raIucKYXVfmVU=&V62x8_WfbjqVc=&QyH4BWXd_Uhqn=&3t_7_KXZdZ_kc=&5E2roIXUasnbg=&GHXP65ZsVZcjV=&BAZJtzXigakUd=&wixpwdXZ_anrY=&NMi2lhVgkUgUg=&eFqubRVZiiiWa=&aMQ4FXZkWrhYX=&yXUzUrUhZrbgk=&fgTnkEYded_e_=&8O9u9FUannaej=&r32N5TXqmkqlh=&lTX9PNZemdcss=&d8dSZ_YiWfhaZ=&LtBrsnUjl_Wom=&UsQtmnXVoUbnl=&Umo98MXhjmhc_=&Z8lbqWVYajfVp=&Uew9KgXmiaoag=&icflFrYZgbjog=&ko9M__XUkYjbU=&jIukFOUjpcibY=&Il2mfXXcXXpmr=&oGe5GxZiUXXYf=&UpyjpDVcndrVa=&bMgO9gUhionkq=&WZ23XMUhbWird=&g6Wh7pUfsqocV=&3EJ5tvWnWYnnr=&_Li4DNVgjjWoe=&DYrgMiYrsndfV=&QAyEJmZbeWahZ=&nCwvQFZqYUV__=&gXXEWsZhirpgb=&SmIkaUUVkg_jr=&uEpYPmUiesWfa=&bbSrWoUeohYmn=&wT4lJKYZWqjlm=&3cYDP2UagbkcV=&MPAQmxXmiWZcd=&yCmYYTZfWqnlo=&kZicNKVcrpWfZ=&3YkVYNUmjmVmr=&NpixuoWWaamog=&tPQecqX_dYWif=&xxL_sQUeqWejf=&yppnZpZZcknba=&rXULqvXamefbY=&cyQzQPU_qrrbs=&wvGsesZsrdjrf=&PR7RRVZqmXfVm=&mQsFISZqVZbcW=&3DLRKYVaYisip=&vELxgNXsUoWqk=&tnY9ozWeUdgZo=&5EHJ65ZbnYYlq=&6XiRnuVpmhXYb=&3Oj9vFUnepZZY=&EzqmlNYiZVWsU=&CjJWE3WemgpbV=&6wkwgiYbVWpgj=&AabDJHWUW_fWq=&3GgodLWsdoZhs=&K62A5PUapVqqa=&RhTrTlZoonoXc=&EYBklmWsjpl_m=&qKcXTsWZXW_Wb=&bbeqHcZgZrZkW=&yspqEXYqkggla=&CJX9ijXpfrplc=&L5N_E9VhjWgff=&Q3QoBWVahg_Xr=&VWSJH2ZrspbUd=&w5J8ApXrbdbjY=&HNSCF7Vkcdcnb=&tTVU8sYr_moam=&6DTAQ_UkneipW=&M295N9Wmaljsp=&KCS_6aVqfbUcn=&xwprJ6Xlagsbp=&JdL3nBWhXjdjX=&2VXUkUYcqZbbX=&LLnMoUWeikcco=&dNmwYoXomkn_j=&OYeGABXYerXro=&sATJ9MUXmhZlb=&XzbotEUbsoshX=&DTn6wFZdmbscp=&qU4c83UnpblZa=&l6c2BQVVrpfmg=&WPojoaUYkfrr_=&bYe6dZUmXapV_=&4TXzsNYrbXsUh=&fmyutHZbWlWXo=&4eM8JCUcperee=&u9vZnvUXsicnn=&BKD5AwZVrrVaq=&5b8Kg2WYdiidg=&OqjtW2YUgekUe=&3rZsxcUkmqppW=&VUwNtMUcmksVX=&RPybHXXhXnk_k=&wRMHKgXnnlarq=&Y_SRK6ZncrmZZ=&3g2WZDWVVkphi=&KI6ZcfXjdfVnk=&C3fJGsUndasUr=&jPvl_rXcklfjY=&WrSzJEXrkakie=&uvyoQpXWskirp=&GreKmpVoqbdWk=&_SbjvMUeemYXd=&YYcFX3ZpeXbYX=&DdohoQWgUojXm=&_MCJXxXmcjgqU=&fkGxZOWsdVZUn=&6QgGkPUWVXoVe=&GMPRP6Vldsroj=&rrXUGlYkVqjfe=&_cQOKNXmU_mpa=&uUF3ATZjhW_ga=&IWMZRVZiWggfW=&tGmst8Wppmoca=&hGYE_cUXZWleb=&xDuFvLYkesbjU=&9uSGl9WeaciUs=&WNpAk4VUhfbio=&5ajtYHWZclUpf=&cIdQjvX_eXUsq=&zGSZ64WdnrZrU=&xrdTshWakZidm=&eaGEljUiXocrl=&jqaMfiUfrhaWm=&KDsYhbUfcrmY_=&DD2QXaXhcmspY=&IfezBDXnpVsWn=&TBb8nIYVmef_g=&mhtZ2tXnpdYZh=&CKQVyCXegiWjs=&yL2Wh5Ymngjgi=&vnhzg_WaaZXah=&gqM9waYsoqleo=&K9ORDRVsY_rZd=&fd4uVuXWgsgWs=&K2zI3YUs_Ugfi=&QBKTgIViqXccp=&FsLy_PYrqqmbs=&y5py6eXZsmeqV=&3TCfhtUsijkec=&6mPe7aZeWbVjZ=&xMFgLzZokkebp=&VFMSqNWgisfcd=&WuhqAHUcgmoZg=&mWnGG2WhajX_i=&BvuE_TXrYZYXm=&gbsFQAYjdrUqs=&ul8q7_XoV_kjq=&8SNRmmVUZbdok=&nPkjJsZXZiqmm=&dydIWsUnjbgsm=&UKjtLqZlajWUX=&NQAtBmXnmUccY=&53voxvUUgjhlV=&smLfVcYbXXffd=&jl_ESbYamgVfc=&LXfVR7UrigaeZ=&qHcnnjUiiXqoY=&XBAolVXakapjU=&qCcOVoXgXjffr=&U5zB7TUqVoVUs=&rQZ6zZZffYqad=&NSbVtZYbfpZYk=&CpZGfXUpWjsWX=&6E7HpBZbagbia=&buqj7_Xhqmneq=&dHdqwpUljpeUq=&nKezBSZVkkYpp=&WM2YYTYVpomlm=&TLANssXopsVgj=&tpf9YcYkVnhnc=&eLxHT2YsWqfol=&WW58lqWcnglsn=&Uy9UiaWnhWsqV=&i33JrBVsWbipZ=&esc5_sWZsVhbn=&U4xLujYo_sVbX=&jmpAk7VksYsjl=&cqhyZqVaWfcel=&6VGn7IZpeZrs_=&hAC6QrVgoaf_c=&oPNDtdYpphcer=&wFzjxmUZlmhVb=&BD2PKrZmlqgUg=&WjOVvvVmisdgX=&FZ7HWTXirkZVb=&q67SQsUokjfiY=&s5qEAVYolma_Z=&kYlbB4YU_cYof=&P6agKyWZkg_cW=&htF_exYapqojV=&6TNjpuUl_Xahp=&YreMVyVnbUpoh=&G_rd_WXnrYcUk=&Tqkbc9Ykcspoe=&IcdfDVUbUZpak=&52UzKDUa_eenp=&QsAJnLYiWeacc=&UGkFRVUdhbhs_=&fTeYvvVqndlhi=&UImGOuUakrV_j=&Ztd4xSWidccVc=&HxsPDxYZUYser=&LRIgnkXanjpqa=&SOgwLTWn_Yfoh=&3KyAcWUZkrnbn=&jd4AKlWjYehqj=&Pz8q82Weqgfmb=&PLxmDpVqWjZnY=&3rj3A4YWgaqso=&lXpBbTWslVlko=&eZRFBFYcpVsnr=&F4OUwtYqqlgcZ=&HRQI3AXUWWVrc=&37WHNoZgmZpnh=&PKrElbWpiWilh=&C4hd5PXoVodiW=&XOcEfgZmYmVsX=&dFwcUVXk_qsql=&OuHmfuVaebqYd=&NtbjvlVnjmrip=&v4hSD7YheaUYe=&aQsIMfWciqspj=&VUjvfYXe_cleb=&eL3X8bXVdij_h=&9B7SsMXcsoicZ=&axPviZVsWVorg=&bHEukzZcUpUWe=&DGK5T7UrhgVqa=&9np4soYsgjqgb=&uyRzL9Ygci_jr=&o_6BS5WrsaogY=&2y_rx6UorXgcn=&S_zYqDXgZlask=&_zsNgIUaVWksg=&YIIHrFUjbUYjV=&CqfozEZcZiqjm=&uEiLpjVbhUndV=&Jxbx4lYXfXcsW=&ig6XNZYXkfkod=&Afa2SXVedYbXo=&_z7tz8WrcsqYc=&AXC7PSUpYasg_=&osykPNWcqoUWZ=&3yjeC8UirnVXb=&sYs8vDXksZXqf=&gn7AffUdYmYZo=&cZiE7lVehYnUi=&X7tEwIVk_glbo=&L4nYxdWa_dmsn=&8w_5IxVbkWWpo=&2PIa5bVnrWWhk=&uvtZuhYldi_hU=&RWFPtaVZVgofb=&pYxJY3Zjjagbq=&lkwmpyXsZgkVk=&4q778zWp_fhrc=&HeSVTdZhqmeds=&KoVSuaVarsaeW=&TO8KddWnXVhrg=&mfUXuiWZfchfh=&MJZpGPUa_Y_Ur=&gfq2JdYgdWnip=&PHkWxMZgXhpnn=&H4XDjGYdrkkoW=&nGGZAWUdml_Yd=&UDqvBKXVjZigc=&Ka8MutUojdrgm=&YuqIWFZspjnik=&ZPZHuDUqXXkhf=&ZYvtgHUhdnpkp=&EBQhrUXbkfgUd=&FSWTOIUUiVkqq=&2ornwGYdXjgf_=&cFLZ59Wpprqrk=&EmAtswY_lhgaU=&UmZI2MZiojZZf=&LQGUvWWjhYksZ=&JtLJkPZi_hika=&G9eTgHVVfqVhY=&vYCEO7VjrnfZk=&Q7ODMgWbchjcX=&Y5ogacUipZkil=&7WZ35sXUVocqU=&SLozGtU_XrhZa=&MgwH7fYXsjXZl=&Ve3DniXsdboYX=&U3phlhYmfsaco=&6YFL9gXsXpcjk=&VagX3EVqVdejV=&xSd2huYjdZpho=&2qKx4oWnYeVXf=&6nUlyKZqjkWpl=&HdpcabUssUadm=&5dke6EWnUX_r_=&o6dxlNYekkpXk=&F_xPhxXcdXeaV=&ek7OPDZsUnrUa=&UyungxXZckpjl=&waIzAXYVWqZcl=&nmOxAbZpqpkmZ=&fBDYQoVrbUmhs=&dz_Sg7WoVagXh=&zVwIRHUWrnWjo=&STSoI9VplagkZ=&3bDVafUslkqco=&5EGrLOVZlhXoo=&PHoZ_zZkgqoei=&iFiKt4YngnZkf=&XSFoYVVadagpl=&CiJZALYZkeUop=&79qB4WXknorcU=&He52poVaVkgXd=&faioq2ZjgWYnq=&3tfPkEZpWeahj=&6nsQHiXhUYbnq=&PufM4OXshVpjd=&lHYQhGYiarYsh=&EjmT_MWjqffrh=&jYDg5oYW_VkeU=&lcsG2wVmanVkc=&ewDuEnVnmZffk=&nIss_dYgZpfnf=&lw7GsCUfrjlac=&dr43xYXefVWUc=&V3JmxHWVfkshc=&L5fG8NVa_WUfn=&A9iXOxUasYeri=&rSrYaxZUnWWpV=&CP7KypYeodejX=&VvV8LQYVgbenb=&xusxcSZaofZjZ=&YxUGSLZqkblci=&RPa_JBVhiciiZ=&cItAJ3Vmqijkf=&trC38SWqWoWom=&ohaejrYZZqhhW=&7jgFcRUdsghdZ=&Fj85hxVnWinel=&nwFovrWisb_Wa=&YEMJOFVboaWno=&VecIzFVpUf_Za=&4WExpOZqeiogb=&tFpFAZWlUXocg=&dZN4WLXjcfiYp=&fF_I3pXrbighc=&dKrP8aYmcmha_=&U7vMkJY_imkfW=&6rCqnvXdjZecf=&5pU3OWYfgarbr=&DmZ3zDYhbkpdr=&6kETtNZnYrjhc=&xMS2nFXWYcVVo=&GJlsbiWjmVjeb=&5z3fI4WW_rZYo=&u86a3pUspjYgk=&CxMJKsVeskXcf=&zy_jZnVoeedYf=&BiWMOHZg_ZcVk=&_ika4TZlYapos=&Oc5KauZq_ZdY_=&HtCrozXfhhWqh=&xeLJSEZbpU_ns=&4mKaZqYinjsng=&JNygz4UiqYl_U=&biJOEFWpgVrkh=&IjlPSWZbeqf_p=&WfALLEVokZiYe=&jvhIY8ZcYgaea=&uBrBZpYoa_kqg=&PdmIclUbmseef=&4GDK9tZZYZXjb=&WSoXYyUgXkqYl=&ygyziwZcUpgXl=&MWmzlkXbrsae_=&R2vQBSUfsoekY=&LZOy8OWXaUUdm=&nHP2g6VpqsgXr=&26_lkoVelsm_W=&Nat4_ZXWYXeWX=&5knw8gWaUojVX=&zgb75bZeksYUX=&xSyTOJVYppYqf=&oUJdg8UZbnZmo=&GJPzmLWkXcfji=&ii82cDXZXdnsh=&B9Rx4uYXifZWq=&BmzpdYZpqZmmo=&b87_LXWaYrlfa=&VMUQdIZeZjUme=&iOjRovWmschdq=&lWZXDDVejfrjf=&U5IbvHWfnWrXc=&Gd2CtAZbXdZWf=&A3nEXlUjrVYlc=&OiNA4MVhhsac_=&5bMkwmW_pbdWh=&nCrp6NVZoVnsU=&LhN_4nZekYVae=&fiMa3FVnYXoiU=&TSMDRXZqXbmcm=&IJ7hPrXnfjiZY=&ATtdBHWWr_eZe=&rIKXWXXhrodhp=&dxH5mHV_krplb=&8rc7SOZXn_Ylf=&BJ87jgY_Wgh_k=&3WQrD2UkoWlkj=&D_88lPWsremd_=&J3ym_HXhXgqbp=&W3VgNuVcdUrjd=&pWxJNWYoXmdVY=&uat_raWVZbcqU=&3rBQENWsYUjih=&vQUEMiYnWhZfs=&jZqcbBXZWeUri=&ur9PsCZdUnlpe=&YL2R2KYcmpmfl=&landVzWpfbZko=&R9eSkNUnkejlg=&GbEivTYoXYl_a=&A5Eep_XklXe_V=&Xoep_vYohrfan=&BvK84RVlcUVdo=&Z7IHrjZeh_lVZ=&w7oHDPZpaZaYf=&eRqz49Y_oUgoi=&ABXsqkWe_cmWl=&CW5PwSZVsljiY=&CTPHPWUYkbXYf=&45IfyqUaqpYac=&p3xfw8UrfXplW=&E_kODOXYgWdYi=&APR3NDXipffXY=&MHBRYgYjgWfWe=&CmpmhiZghVnWf=&kC7QrlYqXgimq=&Sw8VHoWksmrji=&BKecU6XhdsrjY=&UT8DHIVjirkg_=&hroMf5YaickZb=&DGvcdrUaljXdn=&aJP563Uomanmr=&BvGzJMYncneZY=&ajbhh7WarjXjl=&RwToqjXWsjVYl=&EQaFNKVdVminr=&Q8ySxuUjreiWn=<t8fdYhqXjVf=&oQXH5gWsrffhp=&p5Hcy8Xinngmp=&4ANAaZVkhoban=&I9NNiwZqsg_mq=&A8B36WYkdfa_U=&P3a6iGZpVpVlV=&dMHKd2Xcembch=&ILCJe7Uldkdo_=&G8yQbUUclbqen=&gJJz7oVdaXejo=&M8bQdRYfisYhh=&MQDxdbYeUqqho=&giRgG4WfbqXgk=&uYy_rOZXiWhej=&aTgcv9Z_hhoce=&s82bmpYXchlbl=&smdyPxXlkijrk=&Ny2brBZdnZ_mi=&pSJAVHYbe_dns=&jBHS5FYd_YXkf=&vJgY56VZl_kXe=&YoRKmrYfllspX=&eUMmBfXmenbkU=&Xj5IbLWoqiVgk=&nC8lL2WUcXcYr=&LVkSFhV_qWjWj=&OzqpigVnZUidp=&Zdb6SFYmdlrod=&3XN8C4YlYnif_=&qXEEOHYlUmnof=&7ojlgPWYleacZ=&hq7cRQXfrchns=&KbF__ZUgYUilV=&uI3LQFUkUXeiY=&ljH59KUjlZUkp=&W6ey4PVojmcgi=&5Qw7JSXpagqVb=&hl5mCIWYijhYp=&ASAH8MWrVpkUg=&r8VLtJZn_fUeW=&OYrfGuVhjYqcY=&hSPyn7WYYlldd=&iLpMszYpmXmbX=&Ew_Ls3YaoWckq=&jyfpnaZkoZeZW=&jsXiZSWZpUnX_=&ETC9bQZWpbVgn=&C4GTkhVZYlWnc=&FOiunhXVmrfgm=&ccPbSyWV_q_bf=&fviGacUcpeqhd=&VKnlsJXpbmiUs=&Qby3LwUblplsh=&RmzcdEYUsXUlW=&RgHSAsYjWdkcb=&vEYWtVYkWepoh=&VUR3BKUkrkUhe=&Qha2FfUrigZmp=&FiAHlTVgeZnae=&_ubtprUVWXjkg=&alYBA_VamY_hl=&7GRRvkXkqihqs=&w4bMQIVsVi_al=&sjE6foXgcl__c=&gxrWvIYmqjsda=&R34brJZ_rcese=&DOeEhXWosXY_X=&jBUOO7VUrgnnh=&fvMCoIXXdrWXi=&wH8ygVVXdmWp_=&KzxSHBYUbVopo=&OeHFEAZmsfdXd=&2KpBzOUo_gUZa=&hsSlw9Za_lXlh=&76KqpsYo_crXb=&RJrbJZYsaVqcs=&RAa_oWYVjhsUl=&HHO986Ybshagf=&rOq9rcYgm_diU=&eI_joQYndmlif=&PgoWjOZlqcXoY=&kKCNppZloWqUc=&__c87IYmjVVgr=&RmlwoAZecfcif=&xrMOD8Vikbaob=&CDpFdFZbhenWa=&WCs53tXbjZo_s=&nwfPtIVeljaXf=&UtTd_6YhgleUd=&H5VvC5VZnejU_=&Yom3nzVej_UZk=&QH4pHAUXiejWr=&9y_3ncVdVUoij=&FIElInVgsfdYb=&yR5vZuXUfjqVU=&xpdtCSVifmdks=&U44Y3hUpehfbm=&sT2miTUqdeZei=&YIKJueXiZ_opp=&TdkigDYaWordW=&EqpUfsZjbjnce=&YNwAUbVjnYk_Y=&y_ptVnYle_YWg=&upOlDWXmjW_iq=&BaCDsEYlfYXUo=&xJ6aFVWUaaYs_=&KeGrIuUdhUeac=&tInbAaUaVibee=&VjOynQWikbrse=&FE5dWqU_XqpUj=&y4vpEjU_mopjZ=&RJrNswWqWhhcX=&oAOcEXVpfbkca=&BqCjfnZdVondq=&oQfMJzYVUpWWk=&WqlbF3YUfgXmi=&zgqDLnXsm_hij=&wG3hXIVjrjjqc=&CDITakZikUijj=&8BR36BV_dqipn=&kjYM9YWqsWsXp=&ovMOPrUgiri_V=&bUHgGiUcoWqgZ=&VeyEuhWcY_ljX=&6U4uFiYfmihec=&6AzS2pUXWadaf=&oIXXKiUZnfslh=&f2lY5YXjcWYko=&KhPTbRZcd_ZbW=&6McCBAUecrZWl=&cKYxyLZiXlbsh=&C9uMMbXsqVVip=&xi27HuUkkioik=&lnyYE2VmWqajc=&lWBWCNXhojWf_=&Ji98GYYcjndrf=&VC6eXsVbXbpja=&vHS62vUdemaZc=&bDetnqWbgqoma=&mC_tzlYYXq__p=&no6UyZYaikVWf=&AmM2VDUfdUXUX=&sLWKcVUWlrXWa=&nRxTuuXbiVWjd=&DZtwFoUpk_gbf=&yN4YBRUdYnrVl=&dLwWUmXbUYhqq=&Vu4vkRZaodrmY=&uIfPg5XsgehWn=&XSrVhjXhmoUsk=&NB_NsbUirlroW=&4RzKZQWUqYeij=&YF5dZKYqiXgip=&_6x54QVldrreb=&bpfnTcZYkqbqs=&YpwnjEYnYfpUj=&M_EJWTZUdXogU=&KucQykUaoqWql=&V2oPHbYYfmqgn=&L5oBU5UoXepfs=&bbeGvEXjinjog=&hMNo4HUXWdkng=&fktwHwWomoZgX=&FQrZ8PZaaXoZn=&VnCSWnZqmqsjk=&h42PQbVapeU__=&AFdGbHVbpfjhh=&EFEJNAZhfhsWg=&prGV7kWYakjno=&FXbpzFZWg_aUo=&DULgPaXiefckq=&TxrVW5XcoVhgq=&FLHBqWXgapZae=&uA96f9Yoeckrq=&4kghogYhaZYVo=&3y_ecYWsUbdjk=&QGrqsdYeVglqb=&YXdEPpWbUnnXh=&lTnvZmXkcmliW=&ElrldTYgsYhZq=&oG4Cb8XWmgfdn=&oLy9tJUneimmj=&TDM6cJYZpnmVb=&pinOhEXhfYcZk=&iIsQ8PXiWfap_=&FROIcXWdWssYd=&PWgKwcUhpdjiW=&JHezqAXincsbr=&75b6kNYZmndWd=&xRW8fsXpnUbqp=&O2wc8UUifiWek=&a8VZRVWbfjhXX=&SGRcGBVfZrlnd=&8FMVXVYYnZqgq=&X2CkZQVasslZl=&eadXy8Y_cspp_=&9ZQiQOXjeZdVj=&Q3UnupVYcprq_=&yrO9OGXmpVeZe=&SxvcIAZgjqZdb=&bo6eDGZraVdbd=&n9qgoUYZblYpc=&i_IOqbUenobZp=&yk7H3NYqhkngl=&jew8n5ZljjZj_=&VWVl3HV_qXqej=&DlAQLhYdrjfbm=&PL9mPHVeeUi_W=&3sZHDFUZoUkWa=&PPwrCcYelnq_q=&rQq6vlXmpUnhh=&FTawpzXjfneli=&ldhFuCYmYhki_=&KguscpVcpoXcX=&Jh4DZHVcpWpoi=&TTGm3pXkllaZi=&oqymYOZVrXUVi=&hx4kqHVhjZYYZ=&fq6MalWgZZbrg=&6yNxxUUZ_jheq=&F8eD_fYaVYmUe=&6LaeoKXflsUbr=&34ahRUZcenZUr=&nPRPMWUYbXhUk=&_Hf8lmXWUnmgh=&tBZcOGVsgqYmd=&kthbI7ZZokiUs=&iwDr24ZXX_dmf=&vMeqWYWe_Zddh=&_ib6iMWpopqUZ=&EqdljjWhdYmls=&iPrEgNUmsiUrf=&e2O4WLWZmhmYk=&XkoZMvXeUdagc=&N3Ff9MVi_ajrp=&y_B2kEZlooUX_=&6_XJh6Xg_Xhbe=&QEhqUqYacqUUi=&rra9RIVaanhVo=&N8dQabUcZcfeh=&LWRWThYZieaoi=&XAiiqEZmknXrg=&psFDGTVYeibZg=&jneXXvZqUbaYk=&pyFMb_VmWk_l_=&LPBtfKZWdrbnl=&eIBQpBVXWWlbW=&O8iqKJUrpqgab=&VX7jVyUZVloa_=&SUrCeBWZbpasm=&3RAEtHXs_dYYq=&ohDmWCUndUhoY=&ZAeUloWppednl=&IEGPsZUUiohko=&faalrcZrfonbf=&IuHWr4VbqXZVf=&dZC96BWkUWjjh=&UUilTDXeigeYl=&rEEMUSZWVbUho=&zaDqdDVnsUlea=&RYmjKsZc_amdh=&tA2q4vYamchWU=&4umz_vZiabXcZ=&_uX4zeVnlreZj=&5DzludU_hmnoZ=&ibDCdZZgdd_ka=&hnk7ZqYhYsoXU=&ZyHJXzVqqlVfc=&IKtCECYskkWeq=&bZDOx3XbdYXrq=&qchOxzXc_lfel=&kFDMUfVsfejXY=&CYKYkPXkdsilh=&Z55UuDZaUjlXl=&GJY5cZV_seldc=&oEBkdlUhXZfrb=&n83QEiUlaXjcm=&dY4e3aW_pUsck=&_ioKAlWnsehmY=&9A43KAZZVWmXc=&EkA9ZwXfklXkW=&pgtgWHZWXjWWd=&myAfALUZdZ_rd=&_3JZGUV_UcpXk=&lQG2UdYkrV_jZ=&5XCNyHZcjgiXl=&WkHvdpXfbshlk=&6Ob73cYkUjeoi=&ojSaKlZfcZgmm=&IrK6jsUsgkXhi=&nLIsSwWeokVga=&dFxaWWWflgqUs=&5nxdBGYajVWVW=&vH9yYHVmapWbl=&z_iFGMUcdVfnj=&wHCCiOZVfhrpm=&7dP5P7YWshkXs=&_PlsuqXkWndXl=&d3SQu5VdmXbXV=&EGfjxMVUddihs=&ysN5__Uk_ZWod=&AlbseQYfhbjlk=&9s69J5UggUX_i=&lJK4JoYZ_gekU=&tE5mNRWUUejep=&O3gAEYXal_jlj=&UKtBPhWVXeona=&5yVQWeZfeiXnm=&FyHjO4ZaZnnmn=&5AgPVmVXqrqZr=&u_Yq9HUmnncmm=&UyvMFNXdVeqho=&DE3ouQZoXgrej=&HL4YVKU_hfUep=&qxFq_RUgnVbYp=&5kFAuVYYcVVV_=&BhWDhxXrfbsll=&cDO_TyZppoqma=&utrdSmVgVgqVl=&9HODCBUlkhWWq=&f8UHgCZfhUj_i=&oNyjRIWZcUYsp=&VxVlERXpka_gU=&46trjbVmdkinU=&ualWssXskmqgd=&g2gCf9Vhlhcsr=&CjYS9mYsrYkaf=&rcGriFVmUVlih=&IA_yxZZeqmjVa=&6sCABxZiegofs=&4xiztjUeoYfXq=&lPQb3MWUYdoor=&j7LBPmX_ndqjp=&L4tBDdU_epWes=&9_aKoUUgkmYXc=&fbO8JFVWjWVWj=&eIYglFWie_Xpj=&3gJQZ_Zrip_sm=&UHCsnaXchVdjo=&OdTQdOZanUYs_=&ZycTrsYe_dsqZ=&ICaw4fVinV_ld=&64NVSmVZiWcYb=&WPmFDXUdgXofW=&fp92VeXo_lWmf=&B59I2fWqqppnh=&VQGRtLXdmcXVX=&jWC59SVZZlbls=&oX8mVMUkkejWl=&8IQ2NKZWekqhc=&pYLhTQYZgk_VX=&XIt9RRZVbgXha=&2Psok6ZiksWpo=&oTnQSJWglZcma=&BeGwvEZcrbVdc=&7KlQFUVUnYhrV=&pahHcmXskhdir=&4iONlBWgcjeYo=&jWcJL9UicdemX=&_DBnaDZifmni_=&SWxQXxZghpsha=&zNoF5IZhqcYii=&YBCok5Wmrssro=&7hjfLSXpZfWoj=&R8QwE8WUd_qcd=&SOmtsSXlUdWnW=&bz_Cu4YUWnnmg=&sqAtRaYiVheaX=&9dAuplWpaYZfr=&gSbk6UWecnWVf=&bPGcdMZpWgdVe=&yXGq3dZrkokin=&_gFGOuWibUoqp=&dcuGPjWjrrWWX=&yT7yaYYWnYlXd=&WwZNF2Wrcmdpk=&xjeBBIVallmjX=&jo66loVXWfUdb=&txdVdFXUUbqXc=&eZ_bsIZWabZWc=&XP5ns4YiUZjUl=&6HK97OWZjmggX=&LOcCWqYaqdedq=&jd6TC2WW_joda=&r92HfjZWgomob=&tbR2bzUmY_eVo=&WBeDUAWls_XZs=&wSbYY3Vekdpdc=&h4l2MMUXiWWY_=&jnwswgUfmqjWl=&l6vVTYZelhsfc=&_ykR_rYfajhYU=&_Kjm26WikklcV=&sVrz_oVhfZ_rn=&miSGAPYpVjorg=&D4QW8GWjnigdj=&mbYMosZgkhmgk=&tUrEgCVXjlrfb=&pV5dRIWiqkW_Z=&X7ZlnEUchrWrU=&6nWOpvWaloXqV=&TKdyONVcheWld=&ZePJHTZUXghmZ=&FKZHXDXkXXVoe=&GkG9duVrlZdel=&4jnRrkWiXdrha=&n62zoOY_njdoW=&3az5zNWmhpUss=&E7LHUuVbenldU=&GrHvSjXcUmXpe=&4LjEiiZnkjcYV=&O4kKuAXgjgkYe=&D6sgP9ZseanYi=&xq5oxrUjohVsr=&N9UPs4YlfrkUj=&CXRnyRXkcbaaV=&7ppHqMXafosgm=&lYt6wuUlqXlYr=&6K_MPZXaZhlqc=&eB5mrcXeg_loh=&AevD_tXXiqhUV=&cQgOJ6ZadkVrf=&GIv8NMYqkf_eV=&5Cwjs4VpeVpYp=&mH8YEvXnbrpb_=&xxKSFvZmXrnWh=&vXiGROY_fkXeo=&ZclkVbWfbaWrW=&hzLpCWZ_bqZqo=&zUfCdmVWfqqpf=&gLfXLZXkWasXa=&xJNJscU_WUYZa=&sNbVyIWpgqeof=&PIasT5Xqdpsme=&XXq3mPZscboqY=&78IQG3Vkernjm=&ti2bdZWnlkZeV=&fvEOilZakgYYZ=&TsVV9jYrcreYf=&9Ydp7rYbpggUo=&BD6GB6UWqWUUi=&vYcdgdYnrmhnq=&_4r_7nVgcebqU=&IfAuTXYiZjphg=&2DYHEJXjaWqbY=&dQQw52Wpbpppq=&7KtMtZXanjiqZ=&KpD_LmUlidXZo=&WjD9UlWrpUjjY=&hLNzNxUWkUfnh=&OHSW2yXemsYUm=&ICGLfBZfbohsY=&KMd_m_ZhrsWij=&hsX9G7W_ocgfq=&hd4uUPVmViZqs=&dZP8uiXXVUbYb=&j7uAdRUnqdVbY=&MvmouCVbdn_Yc=&QNZlE4WloncpY=&npzPjCZbbrVXe=&f7KLhHWlmUVeX=&MpZ5mNZVfsdpn=&eKBjriVgWZekY=&dlDvmdWmhsYbU=&2jmWqdXXXneee=&TzhFADVqjZcjs=&mwwivdVpncnin=&kgML9GYeYifYr=&l6EwpFXYWUsnf=>jyHMViUqiop=&bzbCWiYgjXVoZ=&ehhfyeXgUnWld=&Ksv6caXZqb_fZ=&BnZpmzZmifbZq=&RSMyD8Wq_ngZW=&Az3VotWglekUn=&5MLZiOZnadplY=&DzKCiUYjbYhoc=&AFTLx9ZjoZdWf=&5h6DRiYggq_nY=&5pGOCbYYXjpUs=&XVcxiFYjgdWWX=&7DyDaAXgkXjdh=&EEuk94VWfidhs=&p7t2BZYcejhpn=&L3qhsUWZbphWZ=&tu3SHLYYYVsmV=&Ex4xbIXseedYh=&2I6FVoUWhaeXh=&sakO57ZgpYrYk=&3yKpjPVjUjZrl=&ByceXKVldo_W_=&85wGk9YqoZ_Un=&Vd622MVqecqkr=&QPRLp9XkZsp_W=&ZYUzmnXadbcsV=&A6GRCHUdinVro=&J3dwqNWjpUkVV=&v7QkjjXWmrfeX=&FjfN9SYnlcaXc=&cnTLkVZYYjbpf=&hwBtujWegbcVl=&3aTDT8VcXnkYm=&laH2MBVjUrVmV=&xhZRGlVoekcdg=&dY6TKEUUsVfgk=&g8uIlVZWXmfaV=&eG8fJ3ZgqeZXr=&ijFyQeXjiWqar=&IIV9hbZrpWkkV=&vvU2w2Yomljol=&XXr73hX_herio=&84u6qnWZrcnXr=&zJtSHiYlgVegn=&ETNbYAVY_gsro=&ZaQLduZXdqa_V=&77cDqhYVnnaZh=&34av78Zjaeceg=&gT3C6hVa_oZZd=&PjS63LYgbanfU=&q6aOvnUnVhckX=&64IHQ3ZnnirYo=&xaZYmEXejcaVU=&BFuUEDWgrndfk=&V9kqkSVbnfZsh=&DfHNl5ZYqklia=&xB4z6OZZhXgs_=&2pAeIpYmbcdaU=&6OdIeXUinfhcr=&gDGHhDYqaiaWj=&eskjLCXbUqqVi=&CdjOjmXjeXlok=&zFUVyAZbddXih=&YrZHCqXo_jmei=&MBHXbfZc_oZXZ=&KefPoMXgZkbqk=&NH_NJpUXiehVV=&NZinMiVYZUVp_=&MeJnyuWcqcedo=&KqzygqXYbXgrk=&hMg94HYpbeWnV=&ZccdJvV_khgVe=&6Jio7KZUdoXcY=&WmwNqtVkilhic=&fjCn_5UndVUsh=&B8VSD_We_Woqp=&4CnkqXZfosfh_=&hJkn4mUphshqg=&wKnIyVUekZVsb=&kQtLHFXVhVZpX=&pEI2GEZdioYiV=&RG2OiJUVkfZZi=&bIxKcZZcicsrm=&Dy95BRXVrZmfZ=&rWzo57Zcjhq_k=&Upn4f4WddjdXp=&yJeyYTZXWq_Xk=&NWwEl6ZWUUWVW=&tqH5wLUnUmjgg=&FreIQTXpkpXpb=&xSJOomWrhZrqd=&IsI22fYZbamqe=&3ihaxRVkZrrqo=&inWaLVXXYsksU=&NdIHbsWnsegln=&U4a4JUXbVerge=&8ESR3eWjmgjje=&M_n5tdYfZ_eiY=&AlIIA9UkklVjh=&jxyioDYssXmkj=&EKm8nsUdbWdo_=&A4meRfU_lWWja=&eEgpulVdXaYqi=&WRHXyxXarZjal=&TeZ2KqUskVrll=&ov5ABuVhVrsrm=&vopRsoWhVaoge=&4iHBQrVVnheZY=&KHO7jDVqWhr_r=&viR6PDWrXbbgo=&35EObMVWYfjVk=&6FxFAEZmsYjVa=&NBo6w_XWcocch=&lp9ecQUgmhcoq=&mAsYNKYcXlZj_=&tJghfYVUsVXVd=&RbXqnfVqdkhrg=&vEdVXRVmeYadc=&vIBt8cYsqWVVj=&4Gd9i8UoniUfW=&IqBhZsYrciVhr=&2OpoY8Wjsffmb=&hNNff4XfaVosm=&dJynhpWXYij_c=&vpkcrMWlmUZXb=&prTQe8Xapoesb=&FE5SMhXfUkcXk=&Giy64wVY_kVVk=&4oM4siWZe_bXe=&ZWNpXnWgrj_ia=&ylpaSVZmrjiVY=&PBTrj2Ypjlmhf=&pDTL8pZmnYroY=&MCQi5bVgZeokm=&ojB_HSYUYaYbj=&Qn6hYGZZprZZY=&oUA4flWisrmnk=&kdLJhcYdlsWkr=&cxPTfnWrdhpbl=&bBjIjMWsUbkYs=&j4vizuWlYYld_=&UhOl66VhjgqYa=&6Xo2oYVWXgUei=&QfzZ7ZZ_joXVZ=&UMi3vYUkfUegf=&BiYRnaUg_Yocm=&BCPeqrXeooYqV=&hpUu2pUcobsUc=&pkRkdgXldpces=&PQT3PQUlfgidn=&ygqFQuUemqooU=&EyPOabZZVpfoq=&hUOTYjXfhYiXk=&H8DYg4YXsmdWX=&HPnP5dXlU_YYq=&zbQTzhUemsljg=&II9hv4XqWeXZp=&tzu3smWjkesrd=&VrhjdNUcUVjoV=&iZsLdhXnmrrUf=&f4BzFTXsfUXXX=&eEh8gFX_kpXli=&K2QuvdXoVmZnU=&Ixae7iYkXojge=&IOajRyVclaYqj=&hAsPl6VeVedeY=&eADjl_Yngjiig=&246KrjX_bsdol=&jJuBd8UrikWWZ=&26suzpUUjeXha=&wDt2hAUkVj_en=&xxCd6aVsqs_pV=&FTFCdFUimpoXg=&c4K8NZVbblebW=&NFGEAcUfpWmjg=&Mbp3ujWn_qmfi=&vhAzbTXcmrjkh=&x9wJGvWbnhqYj=&lewxHCWnfVeXi=&SNOSxCVhmeWqh=&gj7yjyXifcfpf=&VnTX8NWbopZa_=&SIi4XyWlcnroY=&OWS9BcWl_qXZr=&l8tU55XjjqYoV=&VVyUejUjnsZVq=&KwpvmbXirmaeq=&Py5wL3Wnro_no=&7hchrFVXgbegc=&6evxG4Ze_koaa=&4o82OgVYYUqsh=&xqMfpwVnrcdXp=&bGylVfXlpeiXZ=&g7CHWrYaschmg=&pKRKQ3Vnogdie=&wBWyfVYhrYhUZ=&AFJ7N3XoXWsrf=&QwJ9YVYdqZVgq=&EqTlQAYimorVd=&SCekeEZhjZqhe=&5hGw4iXklq_Xc=&9VMe5ZXmVaeUd=&mDOtbaWaUsYrV=&QUbpcxYchXcbZ=&MIyHB5UdgYsio=&FgNfK_YXiV_sg=&CWkGxJVcVljod=&wYJtZFZVc_mpm=&G9vVrwYknh_ec=&2gSiAQUproYk_=&n6aFJKVYaenef=&MO_QlvXidbpja=&nn75GfYljWnaj=&t4NIoXZlcWjYs=&CgPWEGYpeh_df=&xbwnpGVZqaobY=&laL7DtZiqj_Xk=&xmvGx8UmqWZUY=&FMfSCRXbqanir=&OFC8alXfWWVdm=&8rwTJNVmkmrjf=&nYGneTYXUecel=&WkSx7gUjjfibm=&IqQO2xVaqjpga=&jTyqm3WgiYUkX=&5xcw4KUooeUgj=&HXPkPDWkhZqcq=&O_cFJcYlhmVem=&bWzTRRZWiUkah=&S23wSeXgmiqoX=&ph3D_MWjmiWaj=&hJXhhwXmphV_q=&lPL7zAZ_djjXi=&AgfZbvVjYopUW=&tvUh_pUaYmbom=&cjgYzTYXac_Wf=&64mLmVUYjZmel=&K8UzThWniVWdq=&FNTXn8YrsiqVd=&JSpdaOWrbmWeY=&OHSTvTVWlcYUf=&sAH2ZyYesWi_W=&7p3twjYgrZXch=&TMrvXbXWbXWon=&iH_5vNUZkWUgj=&JVw24TUrXgXaV=&8nGYB6YpedqUp=&ksFIY2Wa_hgak=&KhaBTkVoagfpX=&vVgLi8VlZiiWa=&fRlh6qUnbnZZb=&8OVtjQVgeYgWk=&SEflWdUciUnlW=&Cy7vMIYlcacjc=&5t72DvUWjihXW=&at87GoXlXVUar=&r2D2sTZkdp_gn=&kld9H5ZgXiaUo=&MAGPAbUeeaeed=&O2eeiXZ_ZggVm=&GzYLkxUab_gkZ=&LDTsSuYYgmecW=&2_NZAeWfrlcfc=&YYzUAaZkYiV__=&8rNWWzYjlUXdf=&TYBTuFZndgeXl=&hMaqXiXsXWYef=&uymuCKYcpgmhj=&fh9H3eVeUqdrV=&2gM_ATUUZfhsk=&HKhxnVYalsqbU=&28shBKXofkcof=&RG4S6cWViqmod=&IL4aYGVphfdmY=&qmPDfsZdardes=&c3XLFUViafceg=<jLZ5YedVXej=&L9FYg4Ydsjhef=&nEmSHTYaVnioi=&T3flWDX_mhgkr=&EmDZ4gYfhVqWl=&C8cKvQVopafsi=&bGeDrRW_UpUjV=&9Uy4TnYaXsqfc=&f4FiaJUiqjprc=&CUSDAtYnVaa_n=&WXlCOHWWbVaig=&JjqNQRVnqjcms=&jJdRBEZsXapYV=&eVIDp4YXjesqb=&Pyrz_2XYUbhei=&7dQwv3Y_qcncW=&F3gpbuUabZabh=&7WorCBZYgZnaa=&Xvr9wbYdmfmjk=&3SQzjEYcVngha=&DFMvsMZgfjdeq=&CC4f6JWgWbpal=&Fx_y6tYicfdl_=&E24N9rUfZjVfk=&5BaWnRZZ_cWq_=&xrl7evYfpWm_V=&ef8xCbUZVqZXX=&_SGLBgUVZVjjU=&bTSvwiWshaWgf=&wqKnDAVYbWlgg=&o_zy6bUf_mhnZ=&wuwbFKXirqrbh=&YH5tjPVqWlmWh=&J_P_TgWV_okaV=&QptpDbWekpZmY=&MdEOUEVlUXhhd=&fBkwtxZiblmXj=&ov2IHgXYgZs_W=&Hu5ZPUXdUakWU=&ZSsRocYaepbaX=&iHFlvZVWoVsph=&qpkgMQZpqkkdb=&4qsjiEZgpmZhb=&DaPE4TUUpcZqV=&5vkRICYkffbVb=&HlBzUrVXebmjo=&B8yqQbXnlnWmg=&itdhJMUYeqoiV=&UMrP7qYmlfmbm=&LeXDB6Xomkhff=&NxjXXoYeoqlep=&WHXpQOWqbWXg_=&hL6VLIWjrjijg=&mItbHRZelpWdj=&Q3y7gYVWcsWag=&HbRjpwXssUskh=&xoOrXyYbXqmXb=&D7d4y6ZZ_enVh=&OBXlCjZnpsYhn=&xjNcAhZjoVVgp=&_GpCVIXaWagpd=&QAiKPLWsqdaka=&2zbeasVnkomag=&4ofzcLUkVVn_Y=&JTLYjHXX_popa=&K5U29AYWcklUX=&qC2PYmVkrbpna=&5vTQYMYlgfYaf=&Kxp3aaYqsr_jl=&QQJNqkWsXnaYb=&LhbmeXXaXoYlg=&J5CHIHZedlqkV=&D7F4HAWWrcWYg=&2rCj_hWaqalYq=&cXyjK7X_Ycbid=&SpyP9OVmdbfYl=&MxVor7VWWonWe=&WzufigUiedm_q=&HCYrzBXkXorlZ=&pOqxRYVa_cjVb=&RG_C_3WUZ_skb=&x5BIeuWXbfZoh=&y_nM3mZUodZds=&HpqWFDWeqeiZY=&UliGtGWpbYffr=&jNSJ3eVhibkjq=&xVCVeBUkodmsY=&JyQd35X_cUiiW=&ZurWtuWanpWaq=&5gWUZbXkojih_=&Cu9PIbVnUpVVo=&ZoYEgnXjoeens=&QUsWJmYV_eZUc=&_JAGB9UsldWfg=&YVxxx9Vspbgqq=&xQxptDZiYpleZ=&qvGrZyXdUkgbf=&kJKbkuVjjjmpq=&5oZwubXamZdcs=&TnnURnZYsorXX=&BWHbIpXUmkibd=&ftkNKYUfaXfpk=&3cyZOtV_d_dhX=&ZZ_KLkZUd_esi=&OAu8jgWsrd_hc=&h6kVFnYYcrheg=&_MUQzzUhiUsZj=&kGlOxuYXc_bgV=&vfp5J6Vkpgmqk=&EEvnxbXUpmjkW=&Co5CKSZpWsVkc=&nFAx6_Ug_mobe=&uARON_UbXYejg=&PABqzWZkhbkVm=&3ZjYsjWWsqZbm=&eVFBf4VbbfhYV=&4BrAk4YqhXqlc=&NzSD_CZeZhq_b=&8kBvvVVYUidXl=&4ayCHUYlqh_Xa=&Ac5qRsWbeXo_g=&GDCRVPUnbirq_=&2WEhOiYbfmgpU=&an7jlAZ_qXpVa=&bbnxpJZpkXo_q=&E9TBFwZkngZnk=&QaM3a5VgmVsfq=&dIwPwsVjdsVmn=&tE4Jb8VlWdphr=&ppV7AQZanrcpc=&wutLLDYZeYroZ=&WRCLsxWhV_jeX=&UAPpQmZgbZm_Y=&EKQk6iZorWllg=&LtELIMVngmcem=&Jj9GwWWooafco=&awKvuAWgrjY_U=&oLMmNMYdlddcX=&CykyS8VbqpUkd=&diYdvGUpmnccW=&yjMDrjVVqhhYb=&e9MsdFZlrW_Xf=&rkxURHXqbnskc=&nDUbA9Wooefol=&fJ27ovYZVbm_i=&CyftxcUdYmeZa=&oX2gp7Zs_bgdX=&FFSudQXsaeghi=&tkHTRzWf_nppc=&CZY_W7WpsZgiY=&yJ_NJ_XpUhlcq=&xREqWQVlrpfck=&iz8XuqZmeUUUj=&vPsIRyVmeWVfj=&T9KX3fVkVh_rY=&e9eVEbWarZnkk=&NnHpDsU_qggpZ=&XKU9tfZnnmVcc=&XIV9KtXh_npag=&6YS2dZWYYnjYX=&XMENPIUYboriY=&NefeaaY_sXhsf=&uIwq22VkrdUmg=&LEvmN_WqXskmr=&Yge8wHWdcoomc=&nAuLkXUlsjhsj=&CrgsPTYehrXja=&hvoW2QUUdVqUe=&gxCmbYWVqheli=&Hw_XC9YslehVY=&JWG35nYnjgiUj=&ZXcs7aXsXhV_f=&APlaixYogYnfm=&M2xQnXUdbYgjk=&WCbWlaYXkdsUj=&8txwDrUrkdmlX=&WKwSSHYVjWhqr=&Am8KxMUhgXUgd=&jBCdbiVjcaUUl=&ineILmU_XZmjm=&MjObRnVhUasXi=&i6IHOAUdsrjrn=&aPECk2XgsWfmh=&Hd_zISZcsWpZr=&fApje3VocW_do=&94Nw5YWZcmoVV=&wrkgWpZmliVei=&BNxzx5XocheUq=&8hiAArWicpadU=&Pkv2eoZppehom=&5JMUesUqhofce=&5EDuuFUYseqqb=&ViIHFjYXkpsef=&AhBZAOUrVrpjZ=&FrGvBwXohhepl=&qmYlnIUjYk_mY=&pBLPARZX_jkVU=&VeHr_lUphiXlp=&ZZ5C4TVgjgXnl=&NeMeEKWngjrlc=&Me7M4fUdbbZsb=&fFQKQFXcjpiWh=&aHaSIeWWgnVpp=&z8m_gOXgZhXWn=&GbNPkUWoWsril=&79b2nSXo_r_ie=&vOQ_a5UbWVoWi=&EBtNLyWkoimrq=&4gIJ_tZeehZh_=&HGZ56oVqjmlml=&ZjaYRIVkZaUdd=&I9cPQ_Xgbarno=&FLx7DUZmb_oWh=&PcZUUIUYpUWao=&8UgTOYZlbsgU_=&9PLcFkXasibak=&NK8fGdVf_aWXU=&Q8PVt5WUcaXeq=&RAVrZLXejWVlg=&UtiRW7UkXYdUj=&YOikgVYUgjakj=&Oy3SsdWkdjZod=&kK4hc9YgsZpfo=&x7dcoyVnafdsn=&9CbhCNUZ_bWrX=&2Dq9MyVspWXam=&A3HXQcXsdUfWk=&QZabBXXqojlce=&qRc_NiUbdcVhp=&WnH5jzUipdppV=&3R3AAAZgsplej=&kbyxv3VarYrZg=&feMmQyYkVooeb=&5FLBpcUjlbrhU=&h9lfOuYZfrkbo=&MZVIueYlVcffj=&EyRxzQUrmoZbr=&DA_SgCVZjgdrV=&jKmmvcYbZrrkb=&kdOjsHZscUisX=&EGRCZ6XjpkVii=&uWF977Ygikcok=&nOUCZuUWgbnUh=&PqlFfqVnpnijW=&iXHkmcUcbdops=&5B8S4tWfXWgZc=&8JnlIEUihfWhi=&_emUVuWcr_iYp=&O28naWXdkUcYU=&4usvCdYqgnnsc=&BmNjL7VXoalZn=&FGZ4KmYZjqWbj=&kFQGXaYZrhsqi=&HSVMb3Vfmbfbn=&7jvX_XUbZprng=&YSuv_IUjara_c=&U6oo76XnWbZno=&M7HAKEZankdsj=&F3z_LAUcdZcUW=&gAfJqFZeemYkr=&KbmRKGUibkibh=&xQRZnCUjcfjec=&8NqGwCXhangem=&IYIkc9Uhrad__=&cDfYYGYiXfYUV=&OUd_2DVfqkrbg=&OsgxQkZVgiYsa=&wpc6tJVarmlnd=&ZNg5LtUaoYhVh=&kTjqdpXneaekn=&ULJR6rWijYfVf=&Lq2AeGZrr_dpa=&d3W8iCUegaWlc=&WexBsMUiZqXpo=&Jd3SFWZlhYof_=&Hg4HjXXUcfmYg=&5aWF8VYUYV_Xe=&TZbKdpYgrZUmc=&mtww_EYrcVYga=&aIzQHhZcgmkUr=&pKzgNZVdYkXlb=&NLmeoqYkodrpW=&8guaRaUffWUgX=&BTcHfSXoXWp_c=&IWIF7GVcalXdY=&yG4plhUekejXX=&XAHHDmXbradXY=&gBD53uXjidXXU=&xRikQCVdcWkrq=&9EwS7BXUUocqr=&77nnMjVrZrcoW=&2zzSGHUdbVeqk=&Cim2W6YZeii__=&Oi8sLZVZo_YXp=&Bl36NbYlUVaao=&P4DFfFYcpWeiU=&fF7IAVWeaiUqs=&BrYMplUUYgpkc=&eHa_PIWkXZWna=&FiXOEfWjeebsY=&koK6GHVhbnUob=&zHq59NZXsWfif=&G5pVNRWZpidpZ=&BFszJ9YifWrmp=&nqX4kvVdprYUp=&bAMissVi_doYW=&KXG9O8ZhipUfh=&_VorT9XVpchqs=&F7YnTpUkiXUiU=&A_afamV_cd_dX=&5KbQUuVVoogjb=&CPBMFUZbsZUni=&VlFRNVWYppnqi=&ZtGvmOWWgYfsd=&obS4WvVfdZcVf=&g7KzF_Udeklkf=&XgmFNDXplVgqd=&OgozTKUbgXoor=&LHyz2EUhY_kld=&256NQBUjWjYj_=&3culfmYfrbXmZ=&bKMb72YXXXchW=&Y7OrAuWVeWdok=&gxHjhgVWkgq_W=&7YlcJlYinVgkq=&GgpanHYkiVoVk=&7OSMHoXgXXhic=&t4kFxcWcamX__=&a5AeWdXfZZ_lZ=&BOxzHSVprqhrW=&R7BF2cW_jgedX=&ev2a5jYXoqdmY=&Rg38DOXrbkbnn=&ZtDVVVZllqqWc=&m6xCARUXmpjgb=&WmS_63XUWWebs=&Dtad6zVpZkVci=&hly3MEU_oWgWr=&tGjTCeZVlbcgo=&QdRR7KUkdXsUm=&Rzo7FRYdV_f_c=&kHtzhcXakriji=&qwrLfyYmmojkd=&BENM4uYXarpUr=&yKSeGAXbqUo_V=&IDU7zAYVmUdpo=&atcfrpWqkqnff=&7fqclHWnb_b_h=&OcXWiaY_ej_hY=&vRvbJdYZfmWUb=&w5r62AZpqXbpV=&Q8dfBaXUVnWff=&rnIuryZ_bhdYi=&AZx8RuVoqnoVs=&TjedkrYomohqW=&Ao3_HbZipYcps=&yWxyF_Ukroilh=&gf_Ml_YmkbrZm=&2wZr7qYXqoYmb=&VOmtEhUcmqrYV=&MLAUplVVpoYp_=&_rqhuCYnslfic=&anc2iQUriYgko=&_gfX_bZgndUgl=&NsajuWUbeabZk=&uYNdCLXfXfms_=&BYApNXUfsaXfW=&zultGjUYYaVYo=&8tzlsGXipkgVW=&ArvX2gWbskqZn=&Gl4tvEZjhoXcp=&heFnm5WqercXc=&XEPH_PU_cgjXl=&tDgxsHWaZrnfj=&Rz_M_kWs_hkpf=&r6w5yjZdaXhci=&t8Y5KmUamYsjk=&XYTJYsWbsdZUb=&dovCVZWZmcnVW=&buhvzkYZaoniV=&IypfrYWoVqkbq=&Blp9jdWrfddnj=&cy3I9FZsgookp=&k8xfKAWgdbhiZ=&UOUzgNUg_Yafq=&lpXIA7ZXbikon=&sxIFMoZoXUjio=&jZVVKnZraaUWg=&4ccVfCWdsVbho=&aNIr33XZkqUsV=&OK52FVYqcUXcX=&NO4PzlXfkUkoe=&D5WIsUWhsqaan=&SGadiSZWrVUZa=&Kneh5nVjkbije=&OTnwlRVlnbaUl=&lVy5kUZrhbZpr=&q8qbFRYUopncp=&Z5HAGMUigjUqg=&zATVgKVW_pgfX=&8i4aIFUYfabYk=&yhiW6hWVnacqi=&jTKBlrUlchf_V=&jHcu8OZoifXoj=&vTrqMnUXYrobg=&v4toXjYlWYaUn=&lAAEhiXmrbfbU=&2tAGbRZlhjbdh=&3ziuQ6UgsdqsW=&6njaFhV_gj_ld=&NksxmHZq_oWnU=&gceTdvZoqWXYs=&_rFEmJUsXeljr=&CkspVJWsXfcga=&jvXcS9X_oWopg=&JfCo8TWWkmemh=&ZDkgNzXiZbipl=&kcO46VWYgbdiY=&2AHiAFUqcjVso=&GuzdWUYcfbjbn=&ihhKqWUbnqXsm=&Yda469W_bYVrV=&CDQNsFYUqXhkq=&OinCmMXpkknWj=&A7tGsXZ_pqgdk=&FbtbqyUlkVppn=&XI7F2GUeroYbe=&QzDFAdZeqsWnl=&ppG8GwYnYZXpi=&t2HiCGWnmaerU=&WhJzMmVoinWkm=&3uvzAzWslbjqr=&yF4GUpViVdprX=&ksSUiwVVk_oaX=&NxZoeSZcd_gsW=&9hVvALWdUgggs=&WMKv9CZXheikb=&vGcKetZYakWdX=&iyTTFxZdolffc=&ZSnP6SZrmqhdj=&WjYjmKUhimWfb=&9obsgDWVhjmhZ=&fO7ejUUqsY_dc=&HoxqmiU_rarjg=&guaTK_XqeoXXr=&2YWw8dWVgkYpg=&5c6_RLUdfsams=&OhyRLUYmcpnrZ=&MZUqurUfe_sbZ=&v2Soi_YXkhkqj=&ykeVlyWYaYqYl=&uFoofrYcjeUgn=&qO68LJVcpfner=&GbcX9TUdemina=&TaZ9XxV__eWhf=&NlODM3XppcgaX=&QBiMU5ZakUrWe=&9gQT9oVgVcamk=&whjMDVWYmofsq=&5BGhnNWollVnX=&2Y2ir4Zl_cqed=&UdK8uLYmgmclp=&nfs7tpVbombXr=&pTRHNpYhbqnsY=&szZsGNUpiUpld=&JGzaDHXYsgVfg=&HnCe8VXmn_rqe=&DEwOkEYYZcUpq=&5vHfAWXjrrgpj=&3TFiEaWmiXcea=&33G89ZWgcVsmi=&Ztce7XYmgqYso=&xztyw2VZUh_aU=&P_a_2wUjghdki=&glRlTDXXskelh=&UbtHuPVeUiWsU=&uFjKSoVsVilfr=&LXUL5lYbgjasr=&KAlclJUlhoYYc=&z45MZ9ZYjjaen=&Rq4WxQWVhVnWk=&sxrXKpYegVhjg=&vh59NJVlmVqic=&EXeSvxYekpaan=&Vk_DeJYWerclm=&oh47n6YhpsWpi=&kStppnXrsbncZ=&_Yh2fmUlrsd_X=&LnzgOUVZqqkmU=&RPj_FkXmboYXs=&CV2G9aXWgZmra=&uGX7b4ZkjUWoq=&niFYdpZngqrWW=&Peq6ObWcXf_ac=&gpTELaWYikanZ=&2JXGS7XcrUccs=&RR_ALDUclWZsf=&whogPOWsghWjr=&xOn4aXZlXXkaV=&xN2GV7Xglor_e=&rCMtmNVmXWZ_n=&Pm99twYrhYjrl=&hUbpeiWVelWck=&KQt7MiVoohmdh=&tJjXhFVaYmfmb=&SX5tKfWfeoadU=&hoDRv6WlVWjni=&3WZ6zjUoViZVs=&I9aGQJUW_eaaq=&MbVfQgUdmVVpg=&PVBETbUajYgns=&RDOz6EXk_dieZ=&NcMeWcW_Viqro=&qifXWJXaVgjcj=&KHBMO6V_smkop=&bQpkUsYjkjmlq=&gZ8dDPViXqdcp=&dV7qIoYhhpnj_=&zdrBPOWbjrmrk=&9TGjewYmiqmib=&HRwKrrVYrdoqo=&tYjGdiZjVWqcd=&gdu9RmXcllYpX=&Q2gq7VVqVXrWf=&ZwlIYwUfWdglU=&8yyEz5XZaiYbU=&va47XCUfYqheY=&ctxEKLVVUZVYa=&IsFM_OZaUeg_j=&E_2ukeUXroZne=&OCjQ5rVhUroeW=&w3ahkhWscn_sU=&pxtiKPVglfkok=&99cYWEZdeqloW=&6TQvoAXWqiWXg=&BCOkaeUhfWdd_=&rzoqOpVoXcWcU=&QUtXotUYdVpr_=&CXc6LaVbaWbmd=&tgABrlZVisYeZ=&Vjr9fEXkaqVrs=&nbkfguXdcYomW=&aT3WhkWslmrnm=&aTPDcLVkg_Uhj=&fC6OTRUbZgUsf=&ifVMKlUrsrnol=&3xyyakVahbjbf=&899bTTWjo_grr=&JyCAMZZgmrsna=&BFXWFSYUnsook=&ekwNbZWrnbcoj=&8Wd6XzY_lrpgp=&LJbo36WZ_aZfY=&TLNsICXfWXpjZ=&7gEorqWnY_Ugb=&YZHTl7VfhpWpc=&4wwDcAUVmUeVb=&hJ2IIVXrWfsmc=&UXES56U_elejb=&vitIlJZWflbWX=&Tu_I9zXXZlo_h=&nNj6q4VbUgmYs=&C9JgP8Vgeh_mW=&HzoL5yZqmWXqg=&thUPx2Uaasqbr=&Yg3YIhXjgkbop=&JAWVbWZqljYjk=&rCwBdXXpsgedU=&jDk5U7X_qjq_n=&rZPZEQX_ifroY=&7zwjchZVUVaiZ=&ZcFkWiZojpXhe=&KoHbTUZ_hUYcU=&KuTaAWUbiniiY=&WACl7CXkmYjWe=&2quUCBUghjgkp=&_GzYD5WWkmhco=&9e5JOvXVpjWcf=&kDLrLVZp_lsbU=&2TNn4RYqiqdmc=&4WRTbpXerdboY=&6WcNIFVXbdYgU=&hzvtYoVniXbkp=&bhTpIIXnVjalq=&Pj9nZ_Vhbjicb=&eyVHvfXZgpsem=&aeJ2OGUgjpkjU=&Uetql8ZWgZafh=&dUOlMFZbWXedi=&_ArgxYZkWoUpV=&ohrJT5Zrqchq_=&NNf3XSUrdgUer=&LEcTzGXjbmgqX=&jHKIAoYhossVZ=&UrIvO4VefUjro=&cLT4WpUWiamcl=&qeXakjXpsoqrk=&E_WTlVWbi_bmg=&SMxubLZiZoqsa=&zBGPEDUVhoWVq=&ZFGEyOXUZYZgc=&mL4nYcUac_dij=&GxCDofWjscrVj=&icZJ7sWlalhkc=&vecO4IUnlqkVs=&qSCpWsUooqa__=&cBR9bbYrWYcWo=&49UXHcVrr_UfW=&NtrIdIUqbiWW_=&Qpv5pbZjnfVkg=&zMxYOdXrchWoZ=&n6KnSMYVibhZg=&3PHFTgXqib_Xs=&lkI9SZWljeVhr=&vO7trpVocacac=&xJ2nBhVjdUl_f=&CU73e_Unnip_e=&niwsQkYdYegd_=&MpfT_cZZcqlfW=&e8IwfqZbnqrVU=&YbgjVJUbnsqd_=&49FHVJWXZnVZn=&zH6DAKXXmjfof=&qSaBcuYZiojXd=&phYpQCXWdabUj=&VvIwvWWeYgU_o=&KHkjqfWokcemc=&oGedwpXjcphij=&3ai5yNZVhraWe=&rMqkvtUajlZgh=&eVts2wXcVVnnZ=&hWuKXyXZdcdb_=&VVrNcuWokYoqp=&Q3oBGdWrpaVVX=&4PszyoWmVbWa_=&H_dU54YWkrrrf=&6Mv9lzZfWkile=&uvLdTEUXVWrZp=&46a6ZIUasnX_n=&zVWP5EYilfqld=&3pegVmY_qYZim=&w6oOHiZ_lkfog=&2yQEcSXZkqisW=&MWd3kbYdeqWYc=&JZhMJaUWdYicW=&lobY9JYcooYlb=&whRPNRVmqamsZ=&akczCSXlomgUk=&2N8jdmZXZagUd=&nrqPOrYZdaVfn=&u9mj5OYUjn_Zp=&iNiQZLVjicdeh=&hLOupDWscsZoY=&VBsvsOWpXXVYa=&LyOPRYWcn_Vka=&46W3J5ZfZsri_=&JqefERZmdpYUj=&VK_nc_VlgcZXj=&fplkZTVfbVhpi=&Qf8PLiXmig_me=&dkfYrdWrdnVla=&BgfzNrUasoY_e=&y83GkkXVdXgg_=&CIYAbDUbnVXah=&ljaEB7Zssfcmg=&sVzshmYibkciZ=&KTtmS4XoiY_ej=&ZlkqnEYlbVqZY=&J7vPwCZjXdqjb=&NL36dDZlsahZm=&8eUU5kYkjdkpn=&3K8JefYpeVVh_=&D7lXWxYkUfmaq=&4CnlkkYidnY_g=&bft_zSYrWlWVo=&VXJcZQWmghcYY=&e_N6ptZY_kjqr=&FbL_J3V_hmrhV=&Jhj5atVcfnXYl=&rIHhEmZdVnkZj=&s7jKYvVrojmY_=&yHMKiCWprYoZl=&OA7OmeXpqpgs_=&RpXgYVUoU_kli=&NC2DD3Ufgorh_=&VNfdhUYaVcrYY=&R6_oe9Ys_nc_g=&ELR9mAX_fWmoV=&_pov2TXkdUrjp=&mGiT8AZcXbUag=&dpw3LeWXbnboU=&ea_XWuXgfjdgc=&Q2sDFpUfgrWVq=&QQKE9BX_jWqhh=&6N5sUmUnlojWq=&65jwSKZs_djfX=&x4k3_KUhjZrd_=&MYiyCVZnZVmZf=&plkYOCUksmUeX=&biDA6vXZcfnsh=&IomlZBUisiagW=&JndBOxYpdgohX=&rc3CjeX_eejWj=&47JV_3YdaXbhe=&eI46g4UYZXYZp=&GHK7jLUsXqhUm=&B_Amx4Uam_hod=&bUlOmgYZpiaUX=&F6Flr2Ycei_XW=&2bYvuvVdisfqk=&SHZwUtUladjpk=&bpUfmSWpqmZUo=&JI7xkhZVZcVag=&SgcbgtWqgdebn=&gCpazaUkiXfbo=&k_TkXnXg_Xgea=&GYlVFQXfbkphp=&HkpqCsZaVYqls=&GF2lysXcUbcWY=&P2e3EmVUf_agp=&y5ekEDZbVqUcl=&s7mkqIW_lgZmj=&SZEwMnY_fbpag=&Te6XQCU_odrkW=&rGWg5uWYhjhje=&WDN6tMWVqVlhh=&KU9dOpXXYchdV=&p_iDSLXlihqhg=&icnozFUaofVgU=&DuYuavWcXggo_=&us5Q_pXonsrXg=&4OxBLoZmalbca=&5qlrooUkVn__j=&qk54NsU_YiY_X=&h4XR6eXacVjjk=&VbapUxWkkmk_b=&eHkSU2XVpdUqp=&Q3fxHmUasea_o=&A_guNxUWVhVes=&vKacSdUgZlmUn=&KVYJgEVkjqngi=&5snpAgXdVbnoY=&NdTfBXZWhsmeX=&nYcH4OZrinqbs=&TYjikVUrmpqZr=&Mg68OfUXploeb=&AMwWQUViYlUni=&tIGmEwUXasWin=&lqldoSXUoYVam=&5AB5laXXlWUqU=&oewpwBWrXaoir=&Jf3X25XfpiXer=&zOC7dXXerocsq=&SJwY8XUWXqbs_=&5knjHNXlcpco_=&SnaJGHYWsXbgg=&9dEA55VnomWdd=&T6syX5Zecpsnr=&3Qo_LpVWchpac=&PiVZHBXlfjcY_=&pDAHZzVednWsj=&vaMdQBUbrY_fh=&GL3je9Ykmfkgq=&KJ92nSWafqagr=&79bqyKWjVUqlj=&3g38RYWfoeZqV=&4yneikUolgrni=&K99Yo3ZmlgfaU=&kHptlYWajdsqj=&8mXljbYoZUppl=&4ICkTgX_gohqb=&VzgEytZgrVdhl=&NqlwvYYhdoUVf=&zHzFQXXXmWjhc=&fcRZHfUomm_jb=&gBuuvnZrc_jh_=&v4uhm8UskkcfW=&NNk34BZUfaWZi=&heJ_Q3WspYb_p=&r4mhgnUkXjUar=&tpzgzXXofeZqn=&uZwh8OUrYfVXs=&TnW89pXmjWYeZ=&FE8e9kUokgaan=&wVcbqBU_jskqb=&t7GdJjWfjkfae=&Rwo9ouZhWUdqh=&B8tItQWaerYff=&ohhCn_XVXegjm=&49zHNYXfgenVl=&OojPApYUVdc_U=&L3IYKzZkYafqd=&Y9EVwcYdXYUlZ=&uKgkHZVkjeggV=&NW2uFQWVsglkc=&LYVCtHUWXqejh=&gHDe8eVneaphU=&eKGfpQUhrljlo=&bYHl_rXZ_WWZe=&tQTwCaXjiqljp=&e5JLuSUkojXfi=&soXX3fVaXieXX=&BFmwEaYlXfWes=&6_CqpgVWgUhjY=&yS29R9WfYnVcs=&A9l5zIYaYpcqW=&25JrkQYpfinVm=&j9EWOKUZrrkXi=&qNglOaZeonkkX=&8qd3KqZhYrXZq=&5OOvTZVnianrU=&BEIp9VZV_gkic=&6ap6d6UgkajUp=&diw44kUlijmWU=&G52dY6UjhgXUh=&dqW5pKXqbqcin=&F7A9nNWVbdnVl=&pEVxRWZ_kUUVf=&QOrbkQVjdfefe=&MeGwcxUrVslns=&FvXHHLXZmoaef=&wVY2B9Wki_Xfa=&iJMN3DWZroVpg=&CeI_bFZahkdWs=&mYdzeiYepqYpd=&R78Kr8YajhbUq=&k9OHvJWVfrdok=&camLJmX_hqfUY=&gJQdjIZaUj_kW=&BRMR6jWmYiYgW=&XcFuFNVhXehob=&EEB2HVXoXqsXm=&In_YSOVW_ldkj=&V8Vfl4UZqclih=&PeVu9WVbne_Ue=&MYuarJXkmfhiW=&_FLjOEZcflWWd=&_XvuklXUapaom=&JwhsfDWXZqqaX=&OuB6EpVrkm_fd=&PmkESMXYYpZnW=&ITZM8UWkobpXd=&KZ67lPVlnspmf=&fmAaAfUjUYWai=&SgfRbqVZUqlif=&BGBGwuX_ckofh=&372ycXUbfjgko=&saSyRhVlVmsrp=&sE99JNWmpggWm=&gKCAFNWYoiVZd=&9H29VRYrlsUZq=&lIQCKKUfiffgX=&AbU9w2Vcppeqs=&2ZglVeXpgleiW=&ke5iisXUoVlnX=&sJQJjlWhZoelY=&c65VyGZoddgYc=&43G5_bVUqVXaW=&DZsQsRXeqhigo=&93jodUVXhZriU=&oyce_fWWWnqob=&_mGXwAWaopnss=&bza9JeVXXoYej=&Hkw3EIUbcbsmc=&zEmlD_Xdfbrrg=&o5d2vPZh_cfeY=&HGf97zWjoWZVf=&jzBlgnX_br_cV=&iErj8qZo_baec=&BsoztdUmg_d_q=&Ct6MEQZqqocjj=&PM2F8eXaqbUda=&f9O7UtVnYdibp=&HXRDvmYjimekn=&luwsskXfmalmZ=&lBtZAyUkcgjfd=&EDmvJpZphgmaq=&ovxVLCXsffW_Y=&KNol6ZZpdaoik=&AkmO7HZqcispq=&9zinycXnajsWm=&QoqUcAWbY_VZo=&IiiAr8YVfemnU=&wJHo3KYmVmiVd=&ADaVhSYXmpWrZ=&p5ZgbFUeqZmYU=&BPniQtXokdofm=&EwLGvgY_bUYqi=&9dPuSaZcjcXVX=&CgAxxpZZcbWmb=&VC8rjyYZprUca=&dRY7vCWYXjp_V=&RWM_yyVWXkWao=&2TBuJiVZajV_d=&9geY2GZo_hgW_=&Ar7OnaWVYqdhq=&8VFarqYejpjhb=&uDKuy2ZhcbjYh=&pdpRmKWhhWspk=&tTwuIgVedUZgc=&GxeEncXVWlnej=&ApWMIrVd_ldml=&6oQhgSWddrqoo=&7YEo2vUZqpoWV=&pdqiacVWqbnmY=&dh9TI8VZiVZYX=&PXoKc2YbbneZW=&XRZ3HbYbolanZ=&IjHwVGWqZUpaa=&nH4bwGXbakaZ_=&QqZPOGXfj_rpi=&cgls4nZoprUmn=&FnoaHQXWelU_m=&eQXSzcUdVVrfm=&NZyKvtZaiismW=&YAKwTeUmrhUXp=&BOvUtpWrohjmY=&BYZL3MUZUiqUZ=&_nmhvXVipombm=&RYtQkoYodreUV=&vTFwQqVjpqZbf=&kMGxzTVbgrali=&mYXdPWVnmgkjj=&YT9mOZYirjmiX=&BdADVSZilkbck=&QeoDybZXZbndh=&jgM9LbZUcbggs=&Jnyai9XdUnnmZ=&lIkpTkYYgj_Ul=&BquDGiVbgkscZ=&Kv7IpyXqopkZi=&OJ8fdAYUVmgiU=&E7eMb8Zo_Xmcn=&HMjqOyZbUqYpk=&9JBJxBZsijnlU=&LdHTdKXZUgpcl=&HIhCTvXUVjhlm=&blzASMYoVUg_r=&SompS8ZakgcXV=&jS6gUVXlbYjZp=&DfGlSwXcka_nU=&h6wTnnWsnkZei=&3vMOZ4VpoiXZo=&i6RADRUXiiZlY=&RlX4ISWYhjkZm=&R9GmwuUZXhWrU=&oB_AolZXksUqn=&dd7WlRYWgZcVd=&OtrZQPUrqihZm=&Am4E4iUshbZnX=&EJ2ZTsZY_lcUd=&Y5bIJzVe_Zjr_=&hVSXaUWZmddcZ=&J82ibVVaeqqoh=&lxvYLlVW_Wjnf=&z8mH9bXUXlqjf=&eudF4pXbhgeVb=&UMAEPaYoXkg_h=&GWX2WtXfUYsUU=&hh5KGWYpkdjlr=&FwxfvnYgjjll_=&2FHyzaXpbsrfc=&uhnkLoWmf_plX=&fIU9IlX_klrmg=&gfxsOFZcedUge=&anT3_uUkj_rmb=&BjGuAkUnXdkWk=&izwdFqVfkrbnf=&fkcOqKXiiZjol=&4vN4QWXZXXUrg=&LIw5EdWeVnrgo=&qD2jmqVdqYUak=&yseOILVsqsleY=&jtXd9hXmknlfq=&Z8P9a7Y_fcqaj=&5pfQT7Wdkffmr=&PmDyKVX_j_jpY=&zhS9VTWanjWpk=&BmORRsXehjcmb=&5muKo4ZlbUhbl=&bnbXkiX_aYbh_=&fB5_8BUjXoUmn=&UuuHXCZrmlrb_=&EymTbuUisfoaa=&5QCi5KXgcliVW=&nk6uNqU_UZfbd=&dAiblrVhUXikm=&FGSbNZYprhnVk=&ysqB6lYYjqbdd=&5OEcGMUh_Wsbr=&uMM4icUinUoVU=&a8XPxoXeeZWgr=&o7FliEZmfg_jc=&KPwZRLZehfseW=&h9ZCJeZasbfml=&DfR4nMZhdkhXb=&X4nFw4WbaYgkr=&qi6yj2YZ_dsbr=&AklzJtYbVcXVp=&wIph6XWUqlgbZ=&p__UCwZldbVUb=&Y7LUOjZmdoVjn=&5taZC8ZgjmYa_=&eOxCKOUksYoaa=&IwR8ljWlYlXhd=&Us8GnmYfVfZhq=&s2DZnlZsofac_=&VFYZBlYcrhUWW=&5QJ5nUZq_fZnZ=&QFIr2cYaXjnrg=&KeMNmiYlsnoWg=&BvQGxWUkWdbos=&oLJDt4YedhqZj=&PukS8eYgU_esZ=&N3zxtjYldfrZp=&Q2YmrcYaWWjdb=&ekeCRhUmephgV=&eXqfY8XmUWdpd=&eviC9CYnrqiUo=&cvwBEFWcXYlnh=&aDxch6Yrdekns=&onLa9tV_qhaai=&CvS4w2Xlaimog=&VRkKt4Zj_acjo=&7CqtwYZeefUdf=&OWLCVpVYpkWlf=&wfuODdWdlWdlc=&KZXU4_VddrcU_=&9NT_TmYphgehl=&KTk4NUYdaaafc=&mdrAsHZeWarZr=&YkwblkUWhWdjm=&tTSxGhUjiojUf=&FO_7NhUjkXhds=&Jc8smqXWoZYor=&BzAyoNW_lnorV=&lXAcIuWipbhWg=&i7mK3pWVYW_qr=&Fr4ww2Zmebqdg=&kbs954UjVaVVV=&C6GY6AYdionXe=&MPSItOWfmhffX=&xegJnsZan_V_p=&wi4dc3ZbbnUep=&_VpHrSUsfsobh=&ZzSsgSYlnqsir=&XULz8OZmdaoif=&OAl43FYbbhqZ_=&ChgAsEXjqnXhj=&vQrJpSYpnYjhp=&wHrrZ2VeU_kXi=&65CiwIZsqenWg=&Ml4Dq_XfeVcXk=&ENggKaZrZldml=&glQDgBZnnbbna=&qDU7rPUfhlsds=&L4c_waYiikVfj=&3imWTyUWVaohe=&pdkGxEYpq_okX=&9J6ujJZWUZdbj=&qiiMfnZgdcfjn=&yeJvy9VXjlbbV=&3SmmMsUnerp_U=&oMxnvCYU_opne=&tFr56CVgakVqr=&h6QLN7ZnnooZl=&AVFP88Wabcdnn=&Wz_x66ZjepUhd=&4WucddXlW_bin=&3RJpVoZ_kiW_c=&895TXIVplkrVh=&8JvPGtVaedaVr=&YlXcGhXbcsZpi=&VvPdjiZqrrqcV=&idqdNyWpbhqWX=&qkNVmtXdcUcge=&pk76jfYlqhgdW=&h8EfFJVYjUUZb=&c3fT3QZmVYsle=&2i2aReYmnkgnk=&XfCj7CXWd_hjW=&YKLsOQUepjkbV=&wztCysZiWcfUp=&7PzGUZXgmgmcd=&PoC7KtUWqhmkm=&HRHvTGVlsnWpo=&me98ANVnYqWof=&v7PKOmUobscpl=&29AFdlZoc_esm=&XguEOeUiblske=&Edxg8hYWbmXbk=&XzdUEbZmWqW__=&XnOEnLVVhdkmb=&t64ZDeXZlnsUi=&_GVBdTZnkhonn=&v3VThEYjgpVXn=&c6sp8IZjWnbdd=&sDLu4sUYlbccm=&iMjfQvYdecakr=&lIMSdxWXfXgnk=&mVeqgMVYqhaVd=&kjUc9tYleahir=&_nAaPBWiodnYm=&_dEbSuUisbmcW=&NZl8ZmYZsjZWZ=&7Fr8zaXgahpqm=&fzfB_gYsfhosr=&aI9NZXYZoqkbo=&LIHiBmVfYebfc=&3LzedNUjsmgVf=&z3cdcdXelakWc=&DsV7AqUZjXXnc=&VGm_OpViVniii=&ymirR7ZjfhsUp=&DriHJEWXeh_X_=&SpJbqOUcaXlkq=&RXGFw2Wbminpc=&Z9creJVqilllk=&Q7I7IPZWYomni=&VWcygfYrccikk=&4kU3ScYVsaheg=&TBBWoyXqnXfbf=&fw3N8IUbqqVbp=&_WgaveYdkqips=&3WxRoLWighhll=&CmBbArVigVUce=&hXYEEPV_lhrdX=&zIJ5OvXfrqael=&Ut3UdqXVXhXjh=&dUjcT2ZYsWkpj=&tgJgbAVVjknlh=&4abOawXWcsolV=&3qkOhaXdpW_aj=&Kb4YH5XYedcgg=&emZmWkVdcgZgh=&gS_rJxXpabkWl=&OVgQjLVXiXqUb=&3QS6GBUrXkkhc=&XuJSpjVWgoeZX=&NKuMoiWbhkXVU=&OIdCqUUWroghW=&aEwAnIYVYrggY=&S2HiQIVshrpXa=&5ehOhDXf__frg=&9uWO9nWpVYWfn=&SeHwC3WjYbddg=&UiTgDlZfgomZj=&kHofLwXookeX_=&RhK_x6XWqsdon=&yO9SODZVVWaVq=&v7feNAYogjdUW=&iWxensYZaisaq=&CuqoJXXaUklcn=&W9x2tCUsefpYm=&_WVo5SVsbdYhW=&GXLQfxXnfcooU=&9tlkCzYscoUok=&VcBZf2UfembWY=&G4hCBSXqgWbpj=&p6IMhCWebbg_e=&EUwnCRXhmfsjp=&EY3ze2UXfX__W=&YWmLMDZoZjjbk=&YKzrzOZqUYfYg=&fUJ3XKZggq_ol=&mlfpFBWfWXnef=&pHN4xLYpjhshV=&p3nSRVVqrksbi=&fJwObsWmUmccU=&TrG4kgW_WsqZn=&3zTYdfWmihnYh=&y4dHmfZiXbd_f=&jm9nKPXocsgXo=&IQdcNHVnreqrg=&kns4asWbdhasq=&f8Uq8VWgidacs=&TlSECmZlks_qZ=&cxVhEfVqYXsdm=&J6i64_YqjkfWh=&RpFEPrYehrZYn=&HJDQ_UZl_gdXm=&LNkpsuWc_jgdW=&8tSlRKYdlinqs=&j3uRlxYqjfdok=&YS2kBPWkclpmU=&L5Kj7DVXhZUdr=&r4HIojZsnXUek=&d3_Mi_ZXe_bnq=&V5vO7OUsnloWn=&xpGZvIWhZkdqg=&tKIkjjWjWg_Xo=&ZtOvueVVfg_mZ=&N5aE_XWpddnir=&X8ztD6VYVrecc=&HGU7ZQXdYa_ls=&mUucMgYUjn_oZ=&pNSe28Xs_jZfb=&Fpj6irYqYUrmh=&l3Su7bUlWhhdr=&YJFunkZpqkgaa=&UyMcqDXdsqjho=&6f_N_CWnYWXWq=&e_wwp4UlsgfXU=&H_SHtbYlgrgdo=&hrGGO8UUjZrep=&X9qiLuXfheVfW=&Ho67C8UWXgnnh=&aUjSN7Wm_Xmeg=&WmGgpnWWrehng=&ht6oM4WYejefn=&JB5XdnWldpjaW=&JBPBdgXaVkWsa=&Sll3zGVfjYpoe=&hFAYn7UbljnXn=&eGjFFxYdoolqZ=&ZgXBlKXieksYm=&t8TzrjXmUke_a=&vsPcbOXXVrbeV=&Yw25aiYalnspj=&NOlJ4rUUUpUkh=&4kc8ucZsYjZko=&4snnLrXdqYbn_=&8jrrwRZoVscXn=&SF5cR3YeXcfhU=&2UtQNRWbYsism=&_WzsBgUVbjY__=&UENqSFYamiaUX=&9o4ElCWnfdqc_=&FSGR6VWVasbab=&6KTeHmZbXYfgo=&CPsnTIY_kkVjq=&CKGl7iVknqmqU=&OvWBwsWgYWYeb=&dau_L7Xeaqpib=&xeUB9vXaVlkqV=&oeWuAAZc_WVZs=&YfOWXRXZeoror=&dyFXKkWb_qZos=&ErQlWRVdUdqnW=&jQo7H9XmkdYVe=&lDgTR5ZbdsccY=&SuXKhGZobljeh=&GViCARUqmgVcW=&uJ5MvQZ_sUopj=&JtGKLOW_agpXa=&AeIqipXbYWUcc=&BHdGQSX_cillr=&jHGrCKWrjXhs_=&_vbeqQUd_nYle=&Pdo5PgZWVaegU=&X5blxkVbUpVaf=&N9LLLWWVWnqsh=&vAsXt6YobYYbb=&8WpYXAXYdXqYh=&AsNyvWVksqkVV=&lyClDYZZVqdmi=&eTiBxnUZqpeaX=&uVPnc6WcoYWep=&2mmUYwXYajpsh=&hcQg6cZdYZUsa=&r9FlvSZcls_dY=&JW4apNYjXVVkV=&LENUoMYhngija=&Fuk8XwUqgjchY=&G4T5zhYXXgqgZ=&h2OCeeUberZbZ=&qQmO26W_dkgpX=&xtpRI9XjgXolh=&QyV9m4UdrVhqh=&s6wo4HWsfgdqs=&oQPsEdZlhUiqe=&3z5ZEaXWdnUdZ=&r_ydOXWdsrd_b=&8nFiwCVjqWmbn=&smD68XZoakiYU=&DXOQw_UipXomr=&5PrFOcZUnkjnY=&zDkuf4UanhYmV=&TMvPFFVkjWUoi=&ursvGtXfnUofs=&AbxqQ8Uan_kYf=&DYyxFqWhYmde_=&OlCbjEUgqmjXm=&tv8HF8X_UX_qZ=&hctQ96VbVYdmg=&bkuGoUXhcomYc=&FqP2MbXVoVfpk=&ClLk8XXeollZZ=&BchxFyXglkYeX=&UIxbEOUiWchmg=&xZO6PzYsYfesb=&zSvEJlWgWcZbh=&UQZHxYWjeeaof=&itfLTGVX_jr_X=&h9UqxXXjpjejX=&LaBqPKZeer_Wi=&HpqFQlZereeal=&p5ptxRVcYcaYl=&aredJSVijgcss=&mfNAuvUrYVjh_=&UfwWFJXnfcfc_=&NdBelwWldZnsn=&cDiNlhVehmdjV=&c5I7yhXombpkp=&Qzh6hWUmdrnme=&mJZNxDZnapqdm=&bDQ_L3UXnmljq=&b3GmIiXrmrZnd=&e_snRfZhXmehi=&pYBe8kVUaZefr=&WMMw97Xqah_ib=&cxtUDDWZnbXWf=&VnJmRVYkkhWYj=&FVcoL8XppsUZb=&OvSrl4YmmbZmd=&rUffZmZZgXinf=&fXm3KvXnjlqgk=&KdEqDQXi_iUoa=&nhrgMQUpefcpV=&RmvB6qWXfiUjU=&CxuXCxVcVjkqn=&EthGsvVjlrqaU=&4EfLOZZoVskUX=&6ZD3FrXrgmhYj=&ECvtrSWe_kmVZ=&TwSsnrUYoeroX=&LNyZj9YboqnXa=&xEBGHDWhbqfgi=&C8r2pUVmcYfkf=&LCVx9NYVeUVfe=&XiFI3qYfaUpkh=&i4Edt2WWlslfc=&CnfUBJWWrWZdk=&pMSEoIZhXZbfW=&fkUOt4Wa_obhY=&luMOViZcUbkjm=&Jq5J7yUfaXsfs=&TQnNSVXlhWkhZ=&EGqxYMVsVpkUX=&hDqW9eUnr_ecl=&VruLR8Wcmjpbn=&TEnYUQWcmaZVn=&x723CSUmelZbq=&SjUl8PYfcXVYe=&NlRP4sUfpsnlg=&ZZkbSNXsbrnoX=&zB2LJvYYfflZV=&e_XaRxYinmXe_=&Z4gFfVXislZbU=&5Ao9LPUbVYVes=&rQ44mUXcknlbe=&76KJ6sXqbkrlq=&XWLCBqYslsldX=&9etSn4Zrdadok=&mq8ukKV_mbVfi=&MWIl7eUjZmpUb=&grLiEvVVfslUi=&8HgUzlYpmps_p=&QFJ54EWickfed=&QTJyniZVWgUhf=&2eyK_kYXWonpd=&oBl9xiZdalWmV=&Fj3ZwFWmcXVYb=&fEqZMMVbnpqcb=&pz5ARUYoUomXn=&B4UpGdXmisWgs=&dQ6_CGWlnXjV_=&qeJUGSWncmsbU=&ummTFWZicpZmY=&KDnddxYbhhpoe=&pFBsHoWfigrad=&DpHLMIWcqWWYZ=&wUb2MTUYrUkZe=&Xbn3JFYpaoUZo=&o5nfbpVfes_di=&HCeP_kZrsXbX_=&niIfqCXmkgkZd=&A6JNNBVZWWjqr=&PwFG_YUioZplW=&dq2INWU_UerWf=&QDJIGAUjgUqqi=&lcfyRIVjgZglg=&mcgHsUWsU_kWe=&FL3Io3ZVdnoWh=&hxFtJEUanhnfq=&FQhUt2Ugrnkre=&zmwwGmXnermcl=&tXdJEyVannseU=&lcGS6PUWkhbqe=&HWlGY2XiUWecn=&xTuyKgXlijlqp=&B8TcxlYroVqce=&zl7OoxWncj_Wc=&SAU9y6XgqVqgs=&xFLq9bZcqWiWs=&3_5_k3VhYmnVf=&_mpfNdYVfokp_=&hWIWD9VjddUbm=&zKfcdTUhrekYl=&FSf8YVYdoVsla=&j9ZddwVrfscVb=&P7rk6DVopcZoi=&oAzrIiYXoniWp=&RyZ5T9Za__e_b=&FhVUQaZ_eqrZd=&tUivh9ZkskUjW=&Dva7IqYbdkale=&_WANUvVnjXf__=&QjDOD3Upijmlh=&E9aCiCWasUoZa=&XDDbXUVbXp_ci=&UKZFsVXinsYea=&WYodHkUWbnjg_=&SvmzkTUddcWYc=&aAWzQAVVbspes=&QCtDUeXpYhshh=&tKHt6uZnWndfi=&QOBu32UkbUnhm=&qFikceYjgkgef=&Z9u_ziVeiYrYX=&DktOdsYWoVcXe=&oA9bsqVkWidlb=&DIXGpfUelWdni=&SAYfRcXpqXeaa=&diOyQJZjYphWX=&2nxJ_bXjjigZo=&qbS7KnXoUkUak=&hE_e8rWjd_lZs=&E_u65OVnjqofe=&6j6moRVmlqlXp=&BIdT7CXpnagrs=&AhST74XlrYrbj=&5ZO7_RUZsilfo=&XuYTFKWZdUhnq=&FO2oBkWrokpeU=&Zi8ZNhUWWqi_W=&znEuMNYYVcZYk=&QDaSi4XqZW_XY=&ZOhiocW_WhngV=&HL66P9Uamgden=&LC9qwKX_ncrel=&To9CutVgqpkUX=&WclqmbV_kiakq=&ViDcK4UVirbda=&rbFr_eUqhbebo=&VBbplhUfcrhgo=&HiDkGiVXjXgZg=&tF8kNRWiVnmVV=&NWqOzvYb_gkor=&oENDciZhUrhbq=&LU53U9XWd_pZi=&nuXA6BWnfkdq_=&hiwvuKXncopce=&xLzEYsXhs_i_e=&BLPSnGXsieibp=&THS8TqVUbmVsW=&yEIPPSZrmVnkn=&omwKy6VolbhiY=&E5O4u6XeZjnba=&xjNhZnWaVjrkq=&oeuVi8XhWdXsX=&2fyi2yWlkfkdn=&I28RfFUZagrka=&hcJtZAXhUYpmW=&EbxCvAZiqosqX=&2v5puuXlqo_nZ=&Mx6fRCUajWpUd=&4ojVXKYgdhqmb=&JcuK4tZbo_iaY=&xrv3pNXqVa_Wk=&xHJCHZX_cacaX=&U5BBm9WXljnpg=&r2ZLjLUZaprYi=&OZ_GvgVrUbaio=&4GoBicXgigfde=&LbLHCcZomodrq=&vq2M9vZYblqdi=&CbUJciW_pmdsh=&Zing9CVnjnmoj=&adhKGKYZWaoee=&ALrwwTZeXcln_=&H6dfBxXeq_k_o=&fQ7HGPZ_qalpX=&slyNb3UsWkhsV=&SscALUYgedoqp=&sDNClBUYfldWs=&HQd5CxZ_Usbdn=&9iSpgDZllVskX=&s2N_kLVnXYZ_i=&2Jp7wwZo_VnZq=&iXCs3KXaYbsUe=&NtvkkvZ_jhZmV=&rUjK8MUpmk_Xe=&EilP8UVgasced=&plu4_cVppgnYU=&6Pv_WYVj_dsrW=&H7M2vNXUscYmg=&oMeOhRW_bgaVn=&47AFPgYqnYiYl=&oTmgyYUYjjirf=&8KkFHTWqqnoc_=&yENqi8VdfYepd=&PeCUYcW_aZZZl=&PHDumiVVmgZih=&zOKmVMZbbdjem=&stgPB9Wsqlkbi=&PaoyfHUaojkre=&xFpwRMWcipqVb=&_HtzgXYdZsipe=&hVY5a3ZghYdcs=&yvOGPFZcqgocX=&5K3XxmYXgiice=&cIHRwWU_iV_jl=&vmluHXXjnhniq=&KxDeaYUjkhjiq=&aUHjAOZlsspqq=&3HxWk2Ucfkkda=&PowUQZVWeUfkV=&V6o9EdWrfollg=&UzvYkpUWUglgV=&Qp4qbMYfVjlpf=&7czgBeUooYmhU=&UkQ8fNZhspbYa=&42TWkZWgVdsaV=&ZnaHtiXlsXYnX=&yxM4R2Vffbbak=&al3vbfXrqfXdg=&xyXbVwWseeeYV=&hPcpDsZWWZXdj=&qwHD_oZhorqjV=&JEVom_Zosgnlg=&gVsnySX_dpWjd=&AJ26OOXXomZ_j=&5KxH6DYXaaabn=&BhzAqtXfWgoqj=&8bYKvzWijoeam=&ahSUKfUioUYgf=&pCjI2UXeVgsqk=&QD5BI3WkUiV_U=&IMIymkZXVdhUe=&nG9j7MYUbfsdk=&iqGy8sXkgdUlV=&IUGLLpYoZddcn=&zrfFOXUoUga_e=&CSNyGIVlVUjqs=&blzki3XefbWqb=&PnyKXJZZilpsb=&DpSWYcZajmnZj=&QBc6D3VUqYcbs=&jHlmXAXijdefn=&fGTQVKVaqnhWd=&lrxN6mZZmrUVs=&wxy6N9Umfgad_=&yOOODyYcqpskf=&9SZEJDWrdWenp=&uI7KiIXZfksqg=&GRxa8yVjYpnnZ=&KH7Ry2Usip_n_=&z8hyKjUcqhqpl=&7zfotxXrisqli=&dJAspoYoqVqje=&VT6PiRVmW_gUh=&dD__YrYcriYUp=&zxiVzpVhgpeXi=&suMh8yXVjlifU=&Z7vCBVXZlcWUo=&lglNc6XWgUlmX=&pYz9mYVYVpoUq=&MYLMcrUlppgjp=&ipz3iqVmZVpqV=&8lm74GXUdkgem=&qbDXeKUnkUhXX=&Ni9r6jXoplkeo=&9z7Vy7XUr_gWr=&JkK9WtVVliXWb=&YQjbmQVgiWmoo=&ijCKstXUppdgd=&o5JiAuW_amagm=&NWMUM9YfeUgfs=&Jrdk2mUXlheZX=&PqpzeUVmroZgV=&HPBOtDXra_lXc=&FNK_E7Xero__r=&xmphCPUgb_ghd=&lfTfzzXqegfd_=&c6KtW6VnfVkUg=&YbA33GZhnkmdk=&dpmU_dZocbimk=&lYax2QXpXYrei=&EXAyLlXqbYbl_=&UngUBtZUlUVcd=&Me8Ye8VkekoUg=&xetcz7UckpdXZ=&VSxlLtVaiqoaX=&KhL_CBVrrcobi=&cpWnO5WUokkUh=&RFmA8nYYfcUbb=&tk4L2iZrViVUj=&2PnOJCWZqqsik=&MfS_2jUjrpbYa=&4nXx5yWrcgrZ_=&4DHV9hUsfirdZ=&2NElHNVoXo_sg=&kXZSWGXkabmof=&CCr_hGVso_hdo=&HQManoZslWsV_=&B8zaUGUfgnklb=&e8C6t3X_imqYr=&U7s4duUdiZihm=&VMNZLZXUqXqlj=&dK2MkCXblYepV=&JVnUVhZqbZich=&CepyJeYfliVWk=&qlLUFPYoqfZWp=&83yzv3Vdrgi_l=&sHtW3XXqbhjVb=&ibwHldYsmbglp=&PyP49AZeXVnZd=&WTIIUXZpUWWni=&4DXcZPUfnnpkW=&dMYllHXlnoYkY=&IUSrY4WmjiloX=&g79hrhWsVileW=&RrooAbUhqsUlg=&bKj7nqWpZrdcc=&Je5mSQUbooere=&pnWqTVVVj_ioo=&J92SavYXZslep=&KeE4WXUbcdnnr=&k_mwQPYklpZqd=&CKercpYZZaflj=&pjTvFTZrlsihb=&_r5tnUZmaimlm=&O2X7ARUlncbpg=&qLU3g7VUbZZnn=&FWMnJ_YYmmqsc=&RTgejrYmkscXs=&bBmQ2vYsjUjXU=&MEvKeCUlYrkXb=&nhvLYZUWrbmYi=&2MyxFxYUlWZdW=&uvPk2GY_YnmYr=&ZTv6QCVVYVnXm=&CHZ_InVjbnqUm=&wJ4FZgXoWqakg=&V_NVnhWfafjgV=&X4sHzrXneh_qn=&lRrNKxY_gcbdm=&aObkwYYiiloja=&JP9LwSZqojYck=&ekSS6uVcrjqXk=&Jc6s2MWnZkkem=&dZV8DyZUgqdoW=&KxWVcFYhqdaU_=&SwgrhOYieUpcc=&kKd5YWVfVo_na=&4Uuz7uZWgkejd=&CttR24Umsbijs=&JMPkMPY_qqZbi=&wNljHMXdoqYV_=&sRRLa2Wjlocri=&CrkizeYdejenk=&Htxwh5UrVcqkV=&EtKFfaZqeijYi=&QdcTRJZb_nYnb=&emqF3xXddYpUb=&H5Q4Y2Wraq_Yh=&7eJD8EZolfbrn=&8wNbVAYssiWar=&BfL6HIVYqWkgn=&bKKXkXUWchjYs=&cQW5RzYosbp_b=&7vT4ypZXjqdsd=&azvs_uYfhVehd=&FrwtWbZfXcZmX=&FoD6daYergsWW=&Jk4QNiVmccqmf=&6YpvfzWh_abnV=&4SX4qwVmjmlaj=&9bPvLTWkrjcmg=&YH7nXHXVXnbdf=&CjAK8kUWbeWiU=&IR7bynUkpgnsU=&VhHv74UnXqW_q=&955suVYdYpmoY=&dmgPW_ZqcbiXY=&U36lpJXjgViaa=&hG8LBaZe_gkdX=&PiQBefZkcnfje=&EcXLuAXgnVpdc=&cWi5jHXgqXWsj=&xWj3yTYggbdhj=&2fVKjIWppspdr=&fmNSO2YdhUqZj=&PamxeJYjhqaWk=&f3sG68XYbmjfe=&oLTx45UmX_nmZ=&8dq74iXgYVUnf=&x6uswkVbkq_ro=&TVwZVwXrUfhUX=&8SOph5WslhgVj=&h_pCUtXdjl_m_=&mxVF9IVYpoejl=&qku8xsXa_nahq=&yLHVr3ZihZVjq=&hikpCTXpZaW_X=&hxGBXrYXZbYdq=&_TYw3kWhWhilj=&oOCW5cZncshog=&4r8xYjVhipfhd=&qjiq_RUqboYsq=&H66yO7Znbenok=&t6WW95UVqpdVj=&MTExvKZibshop=&bKqgvBZgjZfkg=&Q33YT4Wcdcppm=&r4IhdyVkqpfom=&RqZvgNXpibf_f=&nbCI7CXhcokbs=&nvcMhmVbjnWnX=&egdnKQVWUXpZZ=&dcnhpfZrhVlcf=&rqq2TdWmobWWs=&jsgu5CUroadmW=&6KcZ4nZZhUfls=&uZ8XVhWnijjpo=&x2B6NNXpdrXbX=&S734orUZhcflh=&QLtvQkXaUsh_o=&UPtAU5UXekdah=&KjMo4RX_lnbXX=&PPMcn6UZ_kpf_=&wI6sk5Umamdl_=&Kyv4zFUXackVb=&ezRHAJYplZaYk=&umFhb8ZcfYVrb=&5TUvfJXpmarog=&Ice2d_YfWfhVf=&DHkNGYWWojXXn=&qTSFCLVgfZesl=&BWwmFLUikmgpj=&SnGDYYVmgXp_i=&lAQiXVUdgsWbk=&h7MBqVUrXsjar=&4HM5EZVqcobfV=&cIgTbGXnYYfbd=&9bjWzeW_plfrk=&SIGTF_Xmhkddn=&R7W7hvWpqgrfp=&xZdyzKXUomqkW=&9NA3TMYssrUqo=&6AhL9fUnrY_Ul=&pN3PkDWoifpcV=&9t49WHUWjmajY=&oHjXJhWnkfVmh=&oxXPPoYdclich=&e7sMFAXrekYnV=&lSibL7XrUYjZs=&dIODNUYllcseW=&5DpVhlZhejaej=&hRABdlYihlrjY=&Yj_I4XYopUdsc=&rDzjinZUnoUem=&ohNPggZfnpiYs=&bfUx_kUbsecV_=&g_cqpsUbe__lW=&6J8PDrXjbYnXg=&uDtJnWXaroYeZ=&jqI8_pVgjpWrs=&PSPtHUVsZY_nY=&uUv_hNZbUqWZp=&hiRb4oWWoigaZ=&ExmbQDWgrap_c=&fuJgXAXVphnh_=&VmqcI9YXZdipc=&dAipKMZ_WXqeZ=&6qVQSDUmrYWXa=&jyqYkxUislhjm=&GnxBSUZXlgehi=&euz6dxUie_qVm=&wRuSmkXcafaff=&suxeYLXVndsif=&bgDuKGUUk_big=&r37TYUYcaUcap=&pHaBB_UmrnZhr=&COjsYvZs_sUVZ=&pUIsp8ZhUnqbi=&E42lJmXlUa_fm=&EAm686VhrVXfa=&KWLozbXqeXqfr=&tVIEBUUnqXnZW=&Yl8SPjWknVWcj=&QHxnOhWbejUje=&7B_zQpWopjqjj=&kz6qtLZsUnelU=&yTHkFvUqWmd_U=&VQoKDbUVsirXl=&sFkRfIWVinjiZ=&66SzF7VljbiXo=&FyKQjzUpemfqq=&TEoj_kVlqep_k=&maSrlwW_lrggf=&W3_RQaW_pldmf=&K9sBh9UYliZWf=&hFwBnjYehkknq=&cTknvNY_bkqko=&Lj8q8vZeXphkU=&kisWfqUnglmUm=&aBjgR5WjcmWef=&ZR7D8ZXabmdVg=&h8vI7OZZg_anZ=&nnVie7YsenYV_=&U6ViDdYYjgUsi=&ZfIWE2Znhekkr=&zrqoXYUYspZYq=&8TOVQyZcUXoik=&Rr7ycGWVmZafq=&v58wFGYWWreWd=&bn7r5iUmdlZpk=&W57mDsZfidZhr=&5dPBbKXjhYiig=&mGtVczXnX_kXW=&gfUMVgVccWrqb=&bneYSKZYfZVra=&Idi6h2Xbfdndj=&PKYGKaXhZmgnc=&IjEE5gUpoppYr=&oA2zbEZqenWcc=&kvSKG8Ycrlpjl=&AHsNGvXqVdehU=&KjyTGCYgZjfks=&9_cGWeUprVdkX=&qHXVqSYsqnjge=&HukBWPUqaohqj=&QKCJPJZkqhjXk=&ZaoEN_YhefkUb=&Xnipx6Urlldq_=&3fmhvOVXpnYZb=&VM4KtzYadikhX=&zKFao9ZsmXqfi=&AJ4i5FWerlpmn=&DCPmbIWjrVgYf=&p3uGSCYadq_qf=&LOiNTjWbiVrig=&NWycUYVnZmjYk=&vFxnxJWdnYXeW=&vqEnxTYUiXgnl=&fQvRobWZi_Ukc=&fIaT3_Yiijlde=&7BTrwXVkZpgks=&xlQfUgVhUpUVc=&ejJP5sXsisaip=&heoVWWWqjZcgl=&yPMtJeVpqesjX=&vBytpTYaXmUan=&BMVTDbXcqeiof=&x6LTOBWfclpql=&PpTDtQZfsoefp=&2Ock23WjYoapX=&qE_LFZXZjcdpV=&z97rxAXsajZpW=&HjyHxQZdVmerr=&fNxB_MWXXUWjk=&c93WvJYX_fiej=&2WwRTvXZncskk=&b8qWbdXmfWreq=&GkXK7mXYddbek=&G4Pd7kYajoYbe=&b4rtrQUbnflgm=&2hLOIQVrjskVk=&aQTGxYXsWopmn=&U4oTFTXhiYYZm=&G8ZVAgUmomgea=&Aa6RnJYlfsrff=&etXIGgWbmopqh=&POm6tHWsaqing=&AE_FI_Vhjasn_=&8TxFrhVhXUhef=&q5IdvLYasklkn=&ma2RF6WpliWZW=&cruZnnYamUXlr=&czOC7hUVaVmqp=&mHg9cUUUmX_lq=&yEpDstVhjpkgo=&zzmPbqZiglZci=&VFukfqWgskZVo=&iMOfo7XsbYrgd=&ezGmIFUbmhXsU=&BDvyaGVXjbmhZ=&Lv9B7bXgbXjVi=&gI6xPWZdrhlha=&Gt3HCnVrqfnbl=&bkSUXqZbihcqs=&WNVswpVffflZe=&eoqWd_ZnrUkpa=&sJNNoyVbkZqhm=&spGxCZZoljqno=&gXtZhZUimerol=&DinKvJWVhkefs=&GsJkW9WndrUZs=&UoLViGWWdaXWX=&COgVdtUcYUnfg=&H5hNrpXmi_lZd=&mUgQ8gVdqnmWp=&nUncwBXZrfbdY=&rckwYoVaVmmce=&dnwAVfYerUdhq=&4g35GlUgidsgU=&IhNZh4ZcbUfoV=&2Woi9fWaXfloa=&ASTdLFUcZeVng=&ZpAD9aWknljor=&xVkCfgWVnbdVV=&3sCSGTWbYjUig=&3QhyH9Ufme_qU=&Jpa6I4ZpWU_rg=&JDNcsYVdUZfkg=&hKpL2mYX_hfaW=&tMYRQeWinnUUr=&T73hLWXbnaYYZ=&VPU8sxUkZhnWi=&VGI4iLYZXnhqY=&xmKVobUYkiiio=&D_VFouZYWaWpm=&su4HP7Wo_jXmo=&4vYI7pUhhldph=&wFw4GIVbsm_Yh=&vC3fZ8ZXUgfhj=&EhXTygZqkodig=&ennpygXcbViqZ=&vGAUHJZdW_mek=&iMLkFXZflaiZa=&HCdIMVWYXiYkh=&tCOe2aZa_qgss=&TAh3W4YmpWbiq=&9gZL7iVeq_oe_=&HEoxkWVjpYYYi=&5kfZTcZqqWnfh=&iUNKJ5UnafpVr=&eJDRiXUsslipZ=&my4l4WYejVkbp=&ils8CvXkYddiX=&_9XQEnWipgcok=&zsSb2TY_YiWnq=&YAJTz5Ws_jpXV=&zbwIbjWpaZrUq=&MXO4jiY_mfjZX=&7FXok6WdgWesV=&vce2G6WZXiXsr=&Mic8xrZjkUjnc=&GvNWzHY_XlmlY=&kq8p3_VXiblpc=&hhVwP3ZrVdelk=&WE3ZpwYrXcerg=&zHKqS7UpXpUWg=&VUcFI_Yime_gb=&EJz98bXnijjj_=&x_EYL9YmWnhgl=&p3knH9YepnjWh=&H4QxMeUUpmssb=&XRlv_NVde_ngn=&7mIwJoWUlrggg=&lFmqT8WekXjXe=&uxbCLYUnpWjgh=&2NmlJ5Ud_rgsn=&gzeYzuWUXpebo=&Of2p5jWddisps=&X5Ge_eWohYlUm=&UHcbyvWX_npdm=&Z3TTYdVgbU_rU=&jpk8rUWgleVps=&khuOfhVfearlY=&4XO7mWY_ZmWdV=&mXKC_VUojiYYm=&iiLmQZZpphbZj=&MXKMHXYhoXlbe=&wli8KAVsroZXl=&6ZMe4JWfUacbf=&QRWEq6UfhkZai=&VA4hW_VjaqiUq=&ZT5ycBZYnncna=&Ho8dK3VcnZUha=&bjtPGQWkcmnYq=&dJh_fEVZ_kiXU=&pmNDGRWmaWdff=&v39Ue_ZZgWe_W=&BOejm7XXiVrqb=&F_wyG_WWiqZWr=&uu5i68Vcrsnbr=&zox3nYWkmbjnb=&hCGtBjXccYlYX=&2uyoU4UgcYej_=&OCZXCuXWXVemc=&hV3KCWYsohmXr=&oUIRNmXkXZcoi=&_gBQeXVkpphsd=&kBAtATYgXceXc=&ckrm7HYpfVhYf=&aEZPdfVsklnjp=&dWtmPSWmVbVla=&XoaD6gZfecnij=&hZNxf4ZmnroWc=&ze4NlBUj_XnZo=&LiOqurUbXbajV=&ulmX2hU_ZnUje=&RfUzibYgngmlr=&HYyVhPYhiYlrU=&mc_MUhZhWUmYi=&INeRK5Wjifkid=&NAj2QlUgkgnbr=&LiTXzMUlUjeWl=&fOfRv_YlUsVWj=&xnq6ugYdnknVW=&WbtfpKXhYVX_f=&NVwtF8WVgbUoe=&FDNxM9YmZXjUk=&HKohi3Znsnici=&766NNlUkUoibX=&fJAjtWUkqcdUc=&5cyVDjXZoXpoU=&OELBjYW_hVsWo=&BcvmaiYhXkUcj=&TqNdj7X_noh_Y=&5_Ng5JVYnihpX=&i6vFylU__ZUoi=&yZq_59VUeWfqi=&dfhuN6VqXnlWm=&rjOuTMYibXnqZ=&lnxlhzVgiscYs=&IxwDyKWseipg_=&q6ef2PWZclsne=&3l2ansU_pbpXk=&3YqkbgV_ngeqm=&IVxX8yYgolmlr=&PxgfvFXdcUhip=&mU2dmtUZd_qU_=&EzhcB5VUYZdmf=&RSu_TAZrbYWkU=&rZkB2IUirqeYW=&5_tJyGXXirmmq=&RTvluvWpVabqf=&HvKTW4YhdUaXe=&idnXzUYbdlqlf=&98wuffXfhejme=&CUMmcCWigckVe=&7n3qp5WXbarkm=&SoU9geXcekcbh=&MqkCKGVbodgUa=&7oDqovXd_bosY=&clBEMeWjkjbZh=&Z49IswXekkVml=&Ma4GqaVprhfoj=&JYdcAkWgZasdZ=&_XmbS5ZnponhW=&n5SXUPYUpfXkf=&Xg48ekUndkWWs=&2Kc5m3UYqeeca=&BrayWkVZr_gff=&mqTPAZWgnrWgW=&Ib8L95V_sXgnX=&YGFmFHVdpcWVq=&A3fd_9YYkkqcV=&_T9eBLVWVYYUe=&4GbhfaWosWUla=&Bd8YH7YVgbWkX=&pXzTzoZVbgcVe=&QvmdLKWkrpedf=&h93gLVVnkqapV=&LzGZ99ZXdsrka=&igvc92WemWUVW=&tq2uWtUqqoeiU=&M2NezlVoUirjm=&gXhZSNUkdUrer=&O9_ReGXdqZYqf=&XIvCLPXUfbpgl=&roNujoYYaUlbm=&q_e6uJXYlkqhe=&35nayxWW_k_sn=&CiO5ITVohebhm=&KjgLiYWWmeiYV=&htsdciVVVnUii=&AxOR74WgVcfks=&oN_UcCZmrkWgk=&R5U6I4Wcq_caa=&VSa8H6Xjh_dYZ=&ATphu2VgmhYcX=&3hwmVPXbqnfmm=&cUnU89VsXWYri=&9cbOIeZb_Xpge=&XbRhq_YmXsock=&_uIlomXnbmYZs=&UQP8Y_ZhWonZV=&CnwX3sXfUVosY=&bVDz2uWjjbelY=&rh97XDVeekrsp=&PqBMjmWXWcaeZ=&f7WRjCXfhicgr=&LbnOHOYkffZsc=&7KokrNYqWrcmc=&g3OxffWWmpsji=&3x8zzQVUpeWZo=&n97Z_3ZYlbssq=&2QZXtUYViqZfi=&HFtqz8YlpUnli=&wV7mAgYgnbbWl=&_SuDIDZU_rkmh=&FkNo78WijegnU=&QVi2mcXc_jiWb=&fTNCpfXfefiZs=&3wPYWBZclfseg=&4ibvHmXchl_bZ=&SzRBR_ZeVZkfh=&FAQ87vVqWgXXf=&E2WeQyU_cp_j_=&pZdxeqXlcdeeY=&5_gVw5ZpfVonV=&HDLyPpV_jZrfp=&opNSGZYYhkUmn=&eOIGLmYbrZYrm=&99kTH_VpopdfW=&7r9kOJZeca_gs=&iMxiXiUjoelpo=&qgEauTYdpsiaq=&ioiGd9XrsgmZn=&S9EBpfWXpVhhZ=&4HVXWxUmkqmac=&anSeh4Upfbil_=&EEdvXtX_filio=&PBLK84UXsknbV=&YZdRxFYahklsi=&kWsdkMYqnesod=&mhwrfwXqlbVlf=&qLtTPUYVekVrY=&SJBnQPWlYjmVk=&i4HfIqUfmeUnm=&Qlm2KuUf_gpWd=&bJzXXtVjrnXma=&b3ym6FYfiobgg=&jmZbC5XXelamj=&k8cPhZXpeldmn=&HJyicsYjjprqr=&LkpVdnZZZYne_=&f6DyChZjcobom=&Oipj4pVYcWYmU=&nsxNfkUqdXaaj=&vINqIfYXqhaeg=&ayoiWhWabsUad=&CphBHcXdXhdnb=&I3VDrCUpiWgin=&ZtEhrfXdiqjrg=&RNiTjdYalmsYj=&VaBgalUhpWWjb=&fZet9bY_nhcgj=&QJtrbqVbdh_qb=&9SwBxcVokd_sp=&MuBElGYogmYad=&NYwD_hUpYZq_e=&rM5uTHYlmfdn_=&IlLebZXeiibUn=&cL2wuBUk_jsmp=&hI6JVgUi_rmsm=&ywc4EhZj_VsUU=&63dCgsWokdYke=&FbR5DrXlfqgWV=&pGngrLVYkX_eZ=&qjayxjYmhVlob=&wKEXLWVcXlofd=&iR3FLfX_qrVWY=&i3AxGVZgkVbUU=&cFLv6EWWmbcpX=&kQUSYjWfWZom_=&mcU5iNYWmkqnn=&669MopWioZXbV=&GdAd7UZbUkXom=&XM6YQcUhYsnad=&fxFaToVZlpmkh=&tGrEuZZohpmVk=&aocSJPUZharYc=&rcJIKgXeeq_kk=&4zpTw3Xsacp_l=&aychLgUssdfni=&InXCNyZeVYksk=&lX7jekWfdkkdn=&Xv3RVDUUdkXVj=&tvEZEOZm_ciir=&28ejUWZgicrjf=&OrqkN5VdpjXWe=&BMQfUfYl_VorX=&WUp33UVragUnX=&BIF8hQYapem_k=&RVNjk4V_riWkW=&mTWGhwY_mrXre=&3G4lMXWpUXfkr=&k4AH2CYfXgdsf=&3_ysGUXhsnopZ=&swRMBeXhlciWq=&VTmHi2YnglZmi=&rnNedsUUobZZo=&sHDP8mYmblpfd=&B2z6eMXV_iYro=&A37PTIZghYqdk=&TrTm2yZscXfrr=&TfwDBEZmlgigh=&KQJcToVhjWgZf=&T8GjPHYajjlrg=&frvo9lUUdmkcs=&MgmUnOXgbYiXr=&FtLUOPWs_nbUp=&5f2S4qUkoaiem=&Byu5vYXX_YepY=&utfXPgYdbihUa=&6_6vwkVhcUpbm=&fv4WCBWVamrZ_=&DgF76aWlZXkbc=&YpBIsAWghbnoq=&YveqiXVabeaqp=&NCDxV4ZmedUlj=&PrKqHdUmUlsmg=&9ItcyfUjehnZj=&3tqh_PVrWhXUm=&bJbkPKWZkcVgr=&ezFmGWYeWVoVX=&kKkjn3ZargrW_=&6rrVOlUmmcfml=&JlZrB_XibWZmj=&lrccIoWWhlcip=&Fihh5FXXsglUk=&LcVdrzUbqrerb=&K3pVkpXrdmklq=&WIiRdTV_qlcms=&Hzkty3Vraodla=&vvZ9VkVrWldje=&rJRPpUYrfokYe=&kwHrC5WrpYYUb=&Ei6WP2VkpXYch=&cIFq2RXXhkqsp=&7ynvnrWVknXm_=&XcZy5MZddXn_k=&GnDjpmWpjVopj=&_LC47pUmmppgc=&JUk6ERVjnsloY=&P8nsdqUjrrkYW=&pf6RKIXdYgUkZ=&4ZWXo9XasWccX=&oGTA9pYhihXlX=&vXXAY7UrZaebd=&ScXoSOVeWpjkf=&Dg2cAPXgXXeip=&2XRSFRYagp_kj=&ahbmFvYbblZsh=&MI8CwwUsabfrl=&h2fS65UjeoksW=&I7tVu8UmmipgX=&viBaNrVmsUYiY=&ugXOLLVffelms=&EhhUGNZZZX_iY=&cBxsoNUlorljk=&icIcQLVmYmlZb=&ZQcVHBWXhcidU=&EvlHU7Ygenekf=&IAIz3mVZUrlm_=&g9zHiiUbiqUUo=&SLZ5FXZYnhdWl=&4ZECsOYjhisjc=&5mlnPQVUm_iXU=&Fz9qA3XXcd_jd=&GAuRsKVsnWoZZ=&FJYp4oWrgoekY=&DrVm5RU_ZflsY=&Ajcz7yZgVYqje=&5jaDiYZWqcrWV=&QYxywnY_Zkpcd=&OES2e5ZkkUrck=&HaVD_gZcccsml=&BQgS8AYpUoZVk=&fFaSRnYjZnmrr=&ueCfxOYgaqUUb=&MDj9R2VZajqok=&Y3p6K6VnhgnWe=&SX2gzHXVqbVWr=&p9g9GEVmebmrl=&IA6_LSUgsbUq_=&W8YNmwWalqmmi=&wyxHL5VfVoneU=&dGO_6lYXYdpXU=&oIcBWCZ_hhbmo=&_ohtXxUmck_of=&LPtJL9VsdhXoY=&M5AXgzWmqhsgm=&WLW2iMZdoaZVf=&soCXooUcpXnYl=&RHGQtfUgrjmdm=&bLgxBPUlhgnoZ=&BAiRYHVfoVXgW=&TDzMW5Zpfhsjj=&t75iARUpVjVVq=&Zp59ksXlpWUik=&bGRXaHVjbjVas=&EB46e2Yr_Urps=&kLQqGHWpjsmWh=&vnHGxaUfdcZUe=&LNJbcoXjcc_Zm=&6y8eaCWoUkpcm=&xqhsTGYilngYU=&w4UNEDYmqapnq=&XWcyb2ZgbW_np=&n_DSMmYdkecfb=&M2mRUSZXZqXdc=&9Aj4_zYmpkcpc=&E_asF6Z_U_hhe=&X_9YjAZgpqfbb=&P_tXMmZmUaebi=&9kQgQXWc_n_pU=&yRCdHpUekc_Z_=&SwaMlSXsVpnph=&RR6gbfZelgijV=&NVIW7BW_ZYnVj=&iTCt59YppqVVr=&TK6DypWcm_sab=&qyVNyHUqXpYUY=&ybuiruWVjpVV_=&3lB_kZWjgaigj=&spNuypXpXrpja=&DCLfh3UWioppf=&7XwR8WXjrVfbg=&xx5sBkVYWrbZW=&CyidChVajY_fq=&P9aOOQZjjWdgs=&H_OQIaYsogfWn=&etq8JTZgqqhrq=&AreMU4VeZlsWW=&6wfYc9VZcVVjo=&JhLAidUmVrsdm=&SEz3CqUmoWYoi=&q7coA9XXVVpnb=&BbD4SlVjZfoeY=&xlwYFuXXgjqXi=&ECDAGWWigpmWj=&_dQw_mWUhmnZb=&n_j_oRXXeXceX=&Y8ILndYlUiefZ=&XTGeorZagfr_j=&v4W8o2XfUq_dk=&XaOh77Wnmrrdj=&OhKrwrWgbrmZb=&jVEyMDXdakepr=&UeqqcDZdmcrkd=&z4aKYwXpbdnck=&6ZLjNfYbep_bk=&YVDdf3WqZepYr=&nYCQRTYXgZplc=&zZl3lLWraVWsm=&mvVZxOVanjVZi=&kHxDoIVrfgrai=&JuqOvXVXglbfp=&_tL8APZ_ldVeV=&daNlT5UpmqYVr=&I75KWcVXeogfU=&TdVb2mYYsfgif=&kYSHWiWcgsdil=&u7TuC5Vneq_oc=&h_cDWjZrhqhYW=&4xjqfHYrgWgqZ=&uskrdPYmhUdgo=&8ue_YOUmVrqYc=&tDRSkNZpYpqfp=&YcOeDqVpmZZqe=&amOrl3ZqiW_si=&ea7VkzVcjX_jj=&DWngwMWZcl_nW=&JdKTHLWnbjZY_=&ZQdtzjUZngXmd=&2trkcJYopnagV=&jXkmiRUfZ_dhm=&ZNNxNBXs_gcVb=&KowM4XUgd_ZoZ=&kRQ24uV_pknYr=&MIg3SZXhpWs_l=&zvNesXWnVglWe=&GOLrnUUiraVhd=&JzID68Y_VZelX=&keXUfVYYpVqpf=&oucQLoYljlroc=&ekxgEpZVcohmg=&t9a2miZmchhmi=&cLCmtEZhpiacg=&P4XblaUjeZdWZ=&rlH8keZbdplms=&ZjK7WvWXlmZZW=&TNf2BcXqeZUXr=&zD7nFiZUc__i_=&WRnFnXZdgUooo=&6QjouAVqWqcme=&KRh9G2ZprUWkj=&mvpRbHVorgjap=&88IeUUWX_YekW=&ihQOZNXUmsogf=&m4KeZDYq_dhWq=&CJJ2T4XaXoaoW=&TkSOigUdmifWg=&a8YEG_Wdepkbd=&tLwHdSYkbZYps=&MAlzUvXqshmZX=&pmWnvGWbodXZa=&b4Pv3xXUYZncj=&ld5fLmXrgei_r=&QCR9foUn_XWbY=&NLa5KYVjhlohk=&QPMtVPZrlfkde=&mxYnd6ZcerqfW=&v6jhurVnXVfej=&hk4ZHBUhjmoqU=&GPizBnYgZhZ_a=&hjTuk3WqYa_go=&mEUdsDUmdpjam=&FIWV5AXaZXcZf=&uxYg3QXlrlbqf=&8DkC5sZ_ihWir=&WyBRvyUaYbsUf=&NkKaNUUfUpdc_=&rDNYjQZVWffUX=&TZPIbtYZodmfZ=&l3yoCFUqcijpb=&HSBsntVmfpaok=&UVazkYUknhWlg=&tJwIgGVVWVVYd=&Gp6saMXjjidZs=&OES_PcXgVcUYo=&WsDrWUZbjhe_b=&bs4N48WlseYkb=&yeQmxZYeeWeli=&_lnF3UVafoebr=&cdIs2WUkfjoZo=&poi89jXVqjneg=&jgKYjlVXh_YX_=&RvC9hhUegmdrX=&ORDpeNVUf_agp=&e6tLjdZiWokoh=&LVElKKVqcXjZk=&2xrDYOYZhYlbp=&v2faLcVgrdipr=&m5QPRnUgneoaX=&gpDWwlZnqcgcm=&tCWOOeZUfihdq=&eq9fZ5ZsgdaUX=&DIMhjKWZf_qrX=&v6ngcqYUppkWi=&tli8_XValqjoo=&gBNIHrYbkammY=&6eAkg5WXWX_ei=&Kv8BqkYpo_Zi_=&BXpSTpV_UfYVf=&_L6ce_Uhsj_f_=&khNg4UXkrZnYW=&O3N_7YXdrkXXV=&xOWVELZnqqfdi=&mTivlkZcqeVWk=&_OcsXlYYdfXXp=&yOITiRZVXphgW=&HNaZvCWpdpmWU=&ayLraNUXcidXb=&B3ryGgZe_alXk=&5b55M5YranfVe=&MUMh2tWbZUqdX=&fx3hJMZniglnX=&rDq4QYVWghiaq=&ffuHAXXXegsob=&X2aewFVYjngX_=&xiEl8JVZZWZZe=&ITFhmPXjr_WVh=&RyvoX9ZiXfVXZ=&VXytkwXiWYhdr=&rEmUZ2XXdXWeo=&RIqZCeYZndUWU=&UnYuG2WfgYUdj=&NFipbcZmpfqXj=&K4tXAwUZbiUUi=&xrjw_kYkaW_Yo=&B22iX5Uds_cdZ=&YD3RDdUWZcnjk=&PWsVBXXrbWVl_=&bDBeHVZdngajY=&8ohiNUYmc_Uk_=&hDGc5cV_kYabX=&5shLPzUmnZ_cn=&cJYllKWndjeYd=&DCM87hUsiqolX=&i4ptxDWgWUobV=&eCj_JKUisYnYs=&erVjpQWUrsjhY=&mPaCLiYbgrW_X=&nSvstAYf_gcgb=&9FS9LYYWcnirl=&5mGAWTVrZgVea=&oJB9caXenjWkg=&UPTyZVYaibXlk=&vyQjIvYXpiUek=&zVOUteVnXas_Z=&g3txLdXm_hjaW=&UNaQQLYXerjYY=&yCzHb_Zcofjhm=&nauEFlUqkpVsa=&s4mUHmXasanbs=&H3MFWoVWmk_oe=&qPercpYXsnlno=&7C5OFUVjcjflp=&JUd9o8XmqXf_X=&62aIU3ZUaWjdg=&zmpv6XZkckaan=&AojchhVqmXUas=&MPWeCWWsrfo__=&StxGclVgUrdhe=&VPUOIYUdiqimY=&TID3V7ZWmpnbs=&aay_D6VYfgWdc=&nnuK9PYisasoa=&5xksgJVUj_cXq=&zRvZzVXYlpgZj=&XsCRC7ZZWdjd_=&XXXAYrUshWZZi=&iqQqubUlgcosf=&TXi_TDYkisine=&7GACKWYnWcheV=&3U_jFIZopjdj_=&mhqKr4XiXpdka=&mua_AQZmasiUa=&punvQnYYjshaf=&AuVTpAVkbaZpg=&BUXyvkVqkgolW=&r76BCGYlcZbja=&Z9DI6bUZXhm_q=&H7CpTkZnfYroq=&6denVVUfkW_p_=&tr5kWjUWkhpo_=&9tK9SJUjps_eX=&gJfOYHUqekVUV=&p3xYquVfjmYmi=&sT_eGRUlZsYsV=&aPGb5FUmZVsZp=&Fo2cX_ZrabhYe=&Hb3KrDYkZlejg=&xTBhLdVcVqcXq=&C_NXMnUUXeifk=&57TOOBZVZdpVV=&6S_VshYcXebg_=&B_rVAdYahVial=&n5ZAmOVVZle_V=&hQ_E3pWXpbUos=&Xve5GzVmj_loj=&hcVYjnYomZjpe=&4EeaXqUsgablb=&cf5d_bWcebhWg=&8su7CtXqpWYkZ=&P_UAHxWqdadZr=&vinmrrW_Yp_s_=&2cZXDFUpehhXY=&UidIJgYrqck_o=&M75kdjWpkVsUf=&72KTr2YprYipc=&jPz6amXnkrifb=&KNSPW4WfYkhfV=&E4eb3RYdfmasi=&oCzRT8YWWcUml=&ArsNGFYr_UsVW=&umWMayVUhis_l=&NaA5TYZaocphY=&FlGukpUXsalaY=&4JVPJNVdgssXm=&suDEx2UVZmsrj=&7kjj9GXkYagjZ=&UQ7AsnYjYfolV=&hAi69CZnbWfan=&nqOXaBUasehmj=&TaLBHlYiqg_rZ=&YU37TWV_dfoZs=&ahyuBlV_rUbgX=&xTHCZ_ZUlllhm=&ZbOF_pYWUfZgf=&kc7uAXUrYchag=&pMThD3UVlgaZo=&qoJJboXlsojbm=&hQGhGNVUpUgem=&ca44MwYgbjklY=&qQEhR9ZeZaslo=&mqiqGZVks_cja=&4gOLcgXafhjWf=&gH3cS_Yjdcnib=&pq8rZpUoksirV=&JEbKDdVcepZgc=&WFOxjpVqUlllj=&rItlclXicUpfk=&eyZDIDUVV_fof=&8HkPbIWjokWZh=&CnM_RIWldXqbh=&CyKhWuZYhmjns=&lzH3ZvYpksrnj=&mcDNSqWUaasrU=&jJDpSdXnsifif=&ZwPmnyZZoUZVa=&_VNCEaUhl_ejm=&g5CABVUoggXea=&tLcTFqVkoorrc=&OdkDptZkbcleW=&r27aLGXihesYs=&ORmThxVcbZYXX=&Eez_CLV_ZgYhm=&cWMF94VcgY_UW=&HImKizVaphhgl=&BXBmByYmfisoe=&ftSS3MZZrdigr=&pQ8BJxYiiaecY=&sQSIWlUgqYcUo=&zvQms8UprprWU=&Lxh2zfUqWfoph=&qrOVN6ZVerjoX=&XlsbLEZmnX_qe=&fSCKk4Xc_aoVl=&GDdT3HWnlcrnf=&4T_p7EY_bUUb_=&23PtA6YhUsjcZ=&pkMoh3XYl_obi=&fBBkWMXbindkk=&eunSmaWkegj_n=&pCfzwDVXhpneo=&FPtGf_VokffYW=&4QR3jNWksfimg=&WPb_RTZhVqjUf=&bXlmsAUbrWb_n=&cJryOVYjeb_ZX=&8ImUAkYagkVYl=&PJWXAxZjiriok=&M8pzdHXf_esXl=&9QmAejVnomgpj=&7yNxVtVVcsgWd=&aMUC8KYcgbUqh=&pdvxDgZjg_qU_=&8lXdTiWkr_UVq=&cGJVrnXcWeaUs=&NlmCyDYddiUYm=&hANfsFVbUUpic=&GWuTbYUVWoaYq=&EIw8JnZqpedWb=&S2cJAJUkcpnec=&v2R4OuYZklUoZ=&ox4qNeWpWpYhX=&AnBzHpUYplYbp=&al9ESoUgdXUUs=&CL7p7TVhojrfZ=&rRXYxPZ_YrZUl=&rITP2rUYkVmgV=&yGL_GEYoskokc=&UaWJAWWmknZhV=&6pJxsfXVejdWk=&G8gKqfXbWdkZj=&E5LOPOYmrVZoY=&SXPPRFUeehihe=&rBY2c9XbjjZfo=&YdNnUBWnYjXgi=&kigSC2Xp_Zepq=&2mZHaPVbg_Znj=&waPVXUYpmig_r=&4LX2zdYmY_pll=&daQkbXUahUZek=&wjk_JyYgd_ncn=&qCcVZBYojUc_d=&mmeAADYppdlUm=&PQ4B6rZbbeZrh=&lYRu7BWmlnZfY=&fZMFntXhqojpa=&iB_6m2YVmgfaa=&QUOI4gVdbYVVp=&sVNXwYXgsrXdc=&ISv2IGYaeieaf=&WE4tLOXbdaflX=&hZvSIpX_fkZnp=&QB5HpqZf_cdep=&xbYF7xYnWkmhV=&GFbD7nZpscamd=&VUPqRZXormsrs=&MrpnXUUfkhraW=&OhfK8VY_jVfkm=&6U9NdRVUgXpqm=&PUng5SUgUjnZi=&vpg5vuVZoaghX=&zJN64GZdkscbV=&YJrcbeUqarmXW=&UCV6eiYmo_dWc=&vSXYkeVjmkelk=&JlFICrVWeVgoh=&zjqvmmVeaUZbZ=&4zzAckYnenihl=&zRDmgSXseVUhf=&tLePxxZpXadXp=&UUkfApWYcqpos=&aekVa6ZWmbVoi=&k7ZM5bVW_anWr=&IDOkBkUcjphsY=&lBFFTeZ_W_gnU=&WrRYBAUjrW_Zp=&4GeJ9FWaYehfs=&x_UxPjY_sjanh=&BA2TU9XqadZqr=&I3VjJ5Xkgsggb=&6HyikzVgZrhbn=&6mIRHjYWjZkcb=&LyEWSOUhWWcgl=&ZRrvvCUcrrlUZ=&B4HggBZmeafra=&QM3wIgXlgilVX=&Ta9vTAY_Zgm_V=&2uiCdkVseqeXZ=&CDtFdAXssjemd=&Bvhl4oUeZXkbr=&Qk37b4ZhcVfsX=&AQCAAeVXogdjl=&CPaeocXkYdcoi=&KuJ5_sZgghkoU=&ibMgYAUaiprnd=&8OQEGNWmaiUod=&RA8yb5ZmqriW_=&llMOIyWXWergp=&taB_KvWasZqiX=&lsFHH8Ydapafr=&o68FPbViaYflr=&q9bBYrU_saprU=&m2dLgkUZdnYrs=&24AynXUWgXomo=&snNhsdWrfncrr=&CD3D2zVm_ojXi=&V6L8QmVepZjUf=&5Okv94Zfchpql=&9Mbq3qZokUhm_=&5yR6dMWZhUUsY=&JBfIsoVajeWdd=&vJXgLaYWWZ_Ui=&HwVuvyUancibe=&x2MaRDUfXjhZo=&W96GgYUkreVUg=&vd4VfTWXafesl=&t7VJv6VYZkUbr=&N7h4n2WUqieko=&XOcPfjW_VUnXs=&TFzuImVmlmnnc=&gKUIllUmXqbYZ=&ZFJmS_VW_oiZW=&ZuLVNfXYbocbd=&C7tnexUkfWapq=&4solLgWdchUsa=&KjCq9sVdqgiUq=&Pc_4cBVisoqdc=&iREai5WhsWeWr=&l2gr59VUcYiUp=&6EdSjsZVlrZXa=&kLYUNWWecfkpV=&CTV4q3Zb_qcUW=&jMeKa6VnYjVWb=&XAn7USWgkec_p=&cV4FhFVjabfXd=&LtziZ5XkklofW=&tB5OXSYeVYmfe=&oQNqNuUkkkrcm=&H4VtUFYZXnhgk=&VGCbHSXeXVYnU=&idsBEbWVbXen_=&7B_67eYodhcpq=&kiXx9VVrbbfdo=&VmqrfQYnqslqY=&TCycM4Ysqjmbb=&5nWL9vZfWofjm=&RQcjVaUfmXjmj=&VIIGznUYYWppa=&fQV3irXVVUiVU=&p3uq_rXqdpirZ=&yY7ZayVale_pj=&Kp_Q_6ZcX_ZUs=&BJg_uvYdgaqgV=&h_ATD_Znoejcb=&dwvjdpYiWYsiU=&2SuEECXecadjZ=&graECrZdiahas=&JfPhMXXjjk_Vc=&NC29sVUqhdoUW=&uyyfZpYcngkpi=&8DswhlUiUcomn=&G8ZwM6Wr__cgp=&rvNBWaYngVgle=&clbQbZXodbaig=&ZECuB3VpdZjZh=&aj8jxLZribfpd=&u8ETSuVfjeaZr=&smBLiDZa_YsX_=&zRHkoWUk_cWaa=&AQivLKXf_UpkU=&NwNVNWX_shUWr=&igRtkLXeolrXk=&c52ivOVinUqZ_=&Zf_YaaZolqWlo=&dzV7DnWaU_ipV=&3OP7hBYdocqZ_=&oDZHbtWcakiZV=&Ha_HF9Zqdjabm=&iRFyPEZWcdcqW=&p6iXxOV_lidmU=&aesdrBVfhihnV=&uwcoMGVkoapUn=&Yi38FxWXoafsa=&qJyMlbUodkmrc=&VSYlhAXopnefY=&w8ca2IWmZhpmq=&vNCqMNWe_jj_o=&8UeXSXXUksrdf=&rksj9pYcsmUUe=&rjLWVWUfn_hph=&cmTqHpWbjYmpf=&YLUqZQVooeaes=&C3lj9bZfjVdZ_=&U5a7tlZgbckkV=&iOzOTnUXWafoe=&jDslVtZqkXrsp=&WLWP6sXVbdpsh=&bGIUkBUbcjfaq=&BigOPrVepXjqi=&pazvLpWkgjeb_=&3u2Ii6VjolXmf=&MV9HyFUpgeijY=&YlUWZcYdf_UrY=&uoVwlFYkkY_Zj=&mgSyLVWiaVe_e=>uYPZVinjoeZ=&IHH_sAUmebngl=&i4O9A6Wkapdcf=&DYLgAJXZfipgo=&7wHtYKW_bZUgj=&fjXTlcWljossk=&o_dtP7ZZppbba=&H9cOkZWppkhqc=&YCSmmCVdrppqa=&q27xB_XoZjnZl=&WOxjXfUfogZYZ=&fPe763ZphjbYb=&zgVGpHZs_rXei=&OseAP_Zdpjabn=&I3K6oNZp_dmpl=&4qs9CTYVodoVg=&jUDttlVaUffbe=&Fc2we3YUeXcrh=&zmgMZnXjilqkV=&R5T7VTXUppbjc=&pclJcgYiira_f=&FONNusUZUYfhl=&7CPnzEWYVapfr=&Aj9KY2Wiasoil=&s5oxVPXlWjX_m=&r8i2NgZnbUZZi=&yhkkPYZnohY_e=&6Wz5mJZs_W_gl=&YDPysrUYehZnh=&h8j8XzXbiZVWV=&KPfZgkVaciafm=&_dSKIoZikZlkZ=&b9D7uOYkpoqqo=&ga7BHTZpdqWmd=&TvFVjbZ_pZaoa=&gPoblGZVroYsd=&eVQKANZlaisib=&DqCs7CVjkfglW=&7SEys3VVmonca=&BraqfUUfsaeWZ=&lsfDidZiZkWjm=&zjdr_CYWlgjfq=&Dv5Lm7UlV_ojh=&_TvyiDVe_UgVa=&k5qokrX_sqVUm=&CZZvjgWo_clrl=&N7HigLYiUhhfj=&b5iKbjWhbqcqe=&lqAXA2ZamaUfs=&mlsTuYZcjXmbj=&K5QK87Ygfimop=&Qd9n6KWigbmri=&s45T9bVo_gZXb=&xzacX5YrZkdlm=&TxxuDBVndd_rd=&P8Y2kEZksghqc=&szBjFHXgmYmle=&iZ_EBaXWbdhlU=&Yzfx45Xpreio_=&oTeAy8VhcVhUl=&zXTiPoZaUZceZ=&npHIw7ZqenlXi=&at3FFfWpqoYge=&bBJpnoY_cYUfn=&6Gfjs9ZmedWYi=&NFSu8_UnlYYbj=&bOpeglZipcYdn=&ba3funZsaUsgf=&PgZxRrWsYaiU_=&icns73Xmbnlgq=&D8djVBYaipkUY=&e57YyQVaqcqhX=&5GslvpWqemncV=&LznDSLWpoUknY=&4qFwCRXZssqem=&Wd4yJ3WfWeVea=&rB9cfAWnZfrjj=&vFnWZ6Xksfanb=&wv6h3gWZkiXmU=&pRFzBlYYddhYk=&BjdKxGUhpqYUh=&UzvAZDWs_iXdf=&yqOmpvYphjdmX=&LQfQC4UahjXrc=&EvJV24YYXVsmq=&jLqZNrXk_Usdc=&DzVkyjWsWWZia=&AJD9yHYUaaenl=&jYdwJpVqXp_aW=&uRnEzaWgnVlrs=&TnFKrNVfllsWi=&duC7F4U_iskcY=&Esinm7XUfqZrW=&nXFiBiYkpd_rg=&mHyXJqU_magcU=&CAI7qoZVkedWm=&cKJqoeZpmg_Wg=&W9tE8nXaYpnWl=&zh4MOyW_iYhWr=&OBWYYEZlfbsbX=&lhIaVwYlsf_oe=&wyaXcgXrsWffU=&xpwWHlYcprqiZ=&xPEiqyXkiUhZo=&QEJRWdZXdofio=&jSp3fCWfWar_i=&iGjujrYfXbfYU=&uJe_OmZslZncc=&CUCkNdZWW_kos=&kyShlwZicbabW=&xI4kq9YdeflXb=&HP9MqAYbWdheY=&IPFKKXUUleXoc=&EBFafqVnflndq=&vXJ5GwVZcplVr=&zSp9vLYkaj_dr=&PadJgbZnfdbUq=&hdRDByZVgbUWX=&BhbBfcUVXcqia=&4VcvTGZjdcffq=&Qm5iaaWhrllbk=&EQU789XXpdpbo=&ezjdylUdgZleW=&iTjFtwWmoVhqj=&M4hAw4UVmpUqW=&TGuEiqY_finnn=&wy_SW5YmsnnfU=&jsAVO7X_rdWdf=&uqqPCnYfjqqcf=&vTKd_yZqXgqWW=&UbOe7VXWWonZ_=&VEsU3EUfmVYmk=&L9CWjjYefUols=&nwdmaWUhlqXln=&_WZaxzXqqmkmr=&W7U_73WbYdrcg=&Okdy3uVpnpfVY=&DQewzQZsbfcnX=&pIA4E6YpVkkUm=&GN6sXCZXebfXV=&ZsxeWoYfWbmeh=&FkpkCWZYhmXpj=&yntQZwXWanhYf=&IcVpekZWrgljd=&s6_zFDV_fraak=&WyXPQfVgrhU_Z=&RPsPhqXf_rs_k=&4ENc3gZgsVYlW=&CmOgu_Wqjppmc=&L6sKtdZneofgk=&wwJTYxYjXniXY=&x5jt_fXaXrUXn=&XuWiYDVsecVZs=&lw4wWMVVrlUsV=&SQzndHUY_UrYq=&zu7RTvY_onnhq=&A4zuoiZrbkoYm=&ySzWm2ZrVnrnb=&27eXWmV_mdaho=&7HgRtiWanWlse=&zdXe4AZbpZjbh=&plSDaRXWqmVhe=&ukepI7VsjmZjY=&sDzbb6WdoWani=&9Gve2MVqhaieb=&Sj8o7qZd_cqdc=&OmeVzSXsjisbk=&SWe8lOUfjXUca=&flOa7OZfnqiYi=&ahggkTUdXnpji=&FMfS4pZrVehZc=&5YhmTZZbloWUr=&eZ6pHNVsjrqfi=&RAiYlbZkjVYVi=&P4ZxsYZjoeopi=&MD5yyCWchWpmW=&ZYO5rvY_WhfbV=&8QPLUJYdplnXU=&yJp_H_YX_Zlsr=&tVmn7gUogiZUd=&7qMYAvYjjhkXq=&ogQpnXYeXacmZ=&hZjJgdXhobajU=&LpxHduXmeafdn=&RhkTjCVkiksmc=&t7BcarXssfVqX=&cPxvoiYbreq_i=&jeS5XlWUaWYbh=&k5QjNyYslbdZn=&eGkwVjYpVgiVq=&7MuhzJVedWdXi=&lVTEXcXppbXqc=&Bj9GhUWhkqkgp=&lCOXsNUZjolsf=&YrmMUAYrqel__=&RzaDCwVpZsabm=&zhulS3UpoYfec=&CcaOGIYaVoYrd=&w_DylDYjYqXss=&UH9x3aYeUYWre=&bUZkMlZbXZold=&IIGA9yVUgamqq=&lfXlH2YdrVq_o=&2OPEXDYhrpga_=&ykYatwUdeUqfk=&6siMm9V_iWeib=&q2SrQqVZclirp=&576_4UZfbUbad=&cJag7OXlZkYal=&zfjzG_VnsXZiZ=&yXCO2oUfiqebX=&lMqv4RUrsUb_Z=&7PSQW3WiqlWjm=&SG_J2DYjXraZo=&cus4h2U_Zlkfn=&TbNEPVUsflnrm=&Jw5cEOUWW_eko=&Q35c8rYZaniYb=&uhmrWWYXUoWrf=&3XUbV_Vnmceki=&UF5xX2Yi_loXn=&XBBvhKZqfkaoe=&_g9iUnYslUdlV=&ypQIYBXYmgZVi=&QWLa2SVlrYljq=&3wtpfCUkpYpY_=&QgCXQXXdlcgZb=&ZcKeEFXZaeccd=&cRhnCgUcY_mke=&SQQTnEUeici_r=&AiWjegUbrig_s=&SFB6QwVcUrqpp=&KvQ9rGUb_gZli=&KD4GjDYgcohYk=&orRU4QZpna_rY=&W5VvbhXUZkqni=&whVGzxXekdilc=&a8TiySYlcjUsX=&mt6QbZYUf_rlc=&v37_A5WnhVjsa=&qjHNraX_gjYaZ=&EuRuo7Z_bb_hc=&53nKMdZpkqWVg=&sM5VJLXpfcomj=&4sv3A5WafXoYp=&OubUAqZbaYiVp=&HslQlwVlr_Vpr=&I6sOmaWZsUhVj=&flpDhvWWWoomX=&zDPJEWXenVbkn=&pDxJzQWecUhp_=&lUmlcQYpsalhq=&bXYSsuYYVUUcY=&plLuMkVplYppd=&FNRJ66XoY_kco=&jru2F2U_slVld=&j66j5AYVsWUeW=&c8i2koZdaYcje=&6jCwzyZZnjoao=&_yRFUgZlacaWd=&T3Yh4tYZeWlcr=&OaDUE6Xoc_jne=&esE5rAZkrrWpq=&qIOS8AWUdehaW=&kcyCcxYWdmira=&83HvflXjsVkVi=&PpxOfMWZcokmi=&k7vhBxXcaqjlk=&IzQ3hXWZibdUj=&g4VHU8XXqrcWq=&Teuwx3XiXXXde=&fZmbIfWfosohl=&gqRpzmUZWdlZU=&mWa4CXUhjqXbp=&JovUX2Wlnorso=&QKC5puVZdWppb=&CA748MUpoapZa=&nLaMkKXmaXh_g=&BmB8VZYdeVqXb=&mkB8YTXUkbhYn=&IaSgx3Umnihgs=&d2zfDgXbeYjlW=&UCkpV3UYl_Vep=&CNlyglVfrdhZk=&KBA339YXljers=&goKzviWkaejeW=&lUU6t9VqWsWgp=&czUcnuYYYpmfV=&2LycPFVqkUrkr=&VKR6KDVVncUjV=&73E_UOUUgkZeY=&nPFNXeYZocmUn=&WPxmzDVgi_r_f=&_nVP5RXaolVcs=&L2fXkxWmciVgl=&ahRrJLZjfVjYr=&rWuESxVmUogki=&yl5rTUUfpglls=&MRaCy7Y_iUlch=&gwTg5qWskcfrY=&ZQ75iOUhhkinp=&28RQz6Yrpqpkp=&WHC6rVVUcpgqX=&VuDmNsXpsblce=&a2o2L7VmZWYqe=&eI46jGWnWaoVe=&YM2gGIWblifqX=&fpr7H7XXsi_cr=&8WAIk5ZaoWnmY=&4CTGLHWi_ger_=&zGQUL3Zahasml=&_5eaAFVplgZYe=&QwirjXYXsclke=&wMy25GU_kVdiU=&VS_fXlYXsnYXk=&RwkFrVYcdcjmj=&87en7kZVUkesV=&FMpQQHXiZjXpr=&dYkYjWUkkUVZn=&N3ecdAUispWdX=&WBIvVgZfXamkV=&OP5vUeZncjp_V=&EYSMznYWfpZbl=&XtvniKWfmUWo_=&o4rWGIXpgclao=&ohm_EGW_lksd_=&4QvbScWmligrq=&uuG3w6WfnqlWb=&InmGtpXhqrZs_=&fs2Bs_ZfYjUkV=&6IyWmMWmaoVle=&6EKghSXXfnjXf=&obZtqRXed_agV=&mhQb3NVk_Zick=&2gU5VmZarhmYo=&KrYY5oUfmYZYW=&hFbwI5Wcml_ch=&WyyOP_WdVccjb=&Oj5TPYXVjZigi=&GPO25lZabqXmh=&JnD78AXifigbi=&MygvPgYVinWne=&hXwoBTYZqdqkb=&Gsjbx5U_fdmmc=&mThhBmWoXVq_p=&gKhYuwUmqeagc=&JFfdI_VWgjUYr=&LV3j3OZWhrgWn=&hdStAuYZXmslZ=&Xc8nIjZXfpgsp=&mefAWHVcsVloq=&A4mp_wUkXmehV=&_a25FWYcimqXe=&dqsPOUXrZqaXr=&9qagv9UnqUnXb=&5uTA8PUoffWqs=&wNbMvnZkaXofs=&4X39BsXrVoXiY=&gBhHiUVrmscgg=&JYXS3lW_iaaea=&7uuzfAZjUlmVh=&sUmUshYVqYaeb=&_n67U_VllWeVf=&Zm9WxjUZkiWnW=&qgY3iDXWkbZqr=&fuZEeKUpgqgZr=&zACFnkVhmdmVs=&NDpe5OYZbhnqi=&qrfmZSUUZUUcd=&UC42WyUrssdmn=&bHJh3sY_jXmhm=&X8OVdFYWkWakW=&sqWQvYYhrUX_n=&9rvkR5Wnl_Xgd=&LIxmpHYhmiqZX=&q4Tg59UZmYZmX=&x6oDPzUilbrjY=&5WbpduWoadcsf=&ddLJtcWbecZoe=&tvrl2LU_ZlY_r=&sxvySgZdprZhp=&UZPVi7ZrWjada=&N5F2doZn_aenW=&rMBL5ZUrlopnb=&aZizGPXaYfmaW=&xqJKTwZ_pnlWe=&txswwcXWWoess=&6_PLrCWUrksrf=&Ojo86rWffXWdh=&XcHx8UWmakpVX=&XJUNolXZheZ_f=&zvl5niYeUUckn=&uhUeqwUnXZeha=&49OoOZWhqnZca=&5BJZTOYYocahm=&JlLvooWesqUol=&y9NXsbX_q_noi=&TAhGrGWkUhdmk=&NNmsTUWjnfYfY=&uyK5uGWXfkgib=&FFCSgLYZhpkYf=&8ZuNK_Wbhanqp=&dMlS_dXhld_Um=&dKmIvPWlXYngf=&vDamOWVoYkUrd=&iSNnkaYZhUhaa=&vNsXnMXiXpUgq=&iwRRoCUYinsgY=&WGU2AZViglb_U=&vu6XGSZpUp_le=&pEYLTUYnsemli=&EaAMsVYZmsaXc=&sUL5GbW_sjrdq=&o5ocf_Uprbker=&TlaHhXV_kosVY=&dmmJRGUbsnXqV=&FloU24XZgfddi=&5a_5ROZjnphVY=&cG6cVGYlcj_aX=&Ozc3NcYmUddnW=&TEiNdxVrf_aVn=&ZIJxd2ZWcegYV=&KTjb2lWaqZnqk=&IdEl8MYidncfn=&o8tLsPX_sphpd=&BMORGFVfebZVp=&Kkkwr8VWYofif=&kr26SGVZ_bZbh=&gvzztsUfehXgk=&MacUFHXgs_rmX=&yTM7DaWmrl_jW=&j7N8w2WVkVmfo=&JVBgsxVj_hslf=&bZ7lEDVYfdloj=&sVpPleUeWZnoj=&VVvDTMXdqjklg=&DMgeteXe_qWic=&roMg2lWZYrbsX=&pgY6mEYljoXsY=&zXXrcrYkfiYjg=&8mDdbSYmX_lUd=&kEIZAPXWilVaa=&hWvls_Wahqnaq=&hokOJtU_lbYi_=&4BmqEsWkpmpVq=&MwUulOYWcpbsc=&B5cyj4VXdmiZi=&ejS_UgWrnlifs=&RvyXqFXaplbsh=&LDuRBWUoUZUjX=&oIf6bxYdrsreY=&NVvhnSVhVijeY=&QNTznkXWnll_j=&azvN_AVjlYhek=&wC8BGRUXVgpVU=&eNfUV8WXjdlor=&UARvdyVqWXlp_=&m7esxqXq_U_gb=&537KjGUomgjUh=&T4mLfgVYdWkrW=&BPyLKuUjacepg=&iJ_qJbUbifnbc=&sAbKPuVnc_XVh=&HEoWDhWfmjgks=&zJ4Mc_VjqjUaX=&OoQ4sFUnfdVfW=&mv_I7BZnZWfad=&vl9xqhVkdjlrg=&__akPVXfUkigl=&wQZI7UUrYloVX=&LDnkgJZsZigYl=&fttspmYsbgefd=&OAezgTVppeiVj=&9Yvb_6YmbrWYc=&sZAybaWsV_WrX=&FdngDwX_ghsle=&XEH3P2XUbbYld=&zZWoRPYofdV_m=&9CVhGrUbed_Xf=&QxUga8Ukb_gZp=&IqATXzYpYYZk_=&xLQA2VXkkp_id=&uwWDtHVnhkere=&fT6op9Yj_iYmY=&Qy75HuYpVeVqn=&hy9WEiWmhUXaY=&cFZq56XdrsiZs=&M8PIIaWpla_lq=&buNjZ7ZZcUddX=&YoIy6TVdmgZnZ=&75sGIZWmkUqWc=&x7W9tbWZooXaU=&jrSFLjWkjiZmY=&W9ehWyWr_Xcas=&T4_TAHXiVmksf=&WjUOlyZd_onYY=&5V8unnVfjsZZq=&tOMiQ4VsVhcff=&SKdlOXWndbesf=&i6XDWhXgXcnhX=&vtov_7YcpbmpV=&ts646VUfkmcls=&E9zogRZViYrks=&IS7bPSXsjeecf=&TmBodzWnbaerY=&S2vQTAU_WlrYg=&P6hShBYmWabXY=&WIRZRXXsjnbYp=&xB7CmlZlYW_hh=&RoGklHYggqiqW=&LiSiu9Weidsdk=&hOFQ5yXllmdab=&rPxrFYYnsUqWb=&UNmveBUZkaYql=&vbSfMCWm_nqmp=&JqoC2tYmUsYeU=&ubmrkAVmhfnen=&pLhGwMXqlrdgm=&kypcfbU_fadZr=&3Umhu4V_nannr=&iArzQjWV_loaq=&gcRGQPUboUcXr=&38IETvXrlXbUV=&I58LlIYkorqsn=&lECfimXqfmgl_=&GfYPH7WdVaalb=&YvG6PCUZojqck=&tEsYGEXkYbkYY=&2Lm2pKWls_rhk=&_aOHjRUdoaVZb=&q4R8gOZhpYrgW=&LwiTMUUkngjpm=&9HVw2rXn_bUdr=&Srp8CxUWhnlse=&8kTRC_UUbZlWj=&dNYMnsXdeiWlb=&NK_knxZhlVmia=&QYHIBIVfoUrsa=&bmLpQRYoiYpcc=&SIfPCdV_riZVW=&NddrJ_XsVgYek=&n7sXiqZlUaVaY=&llSgsvYeZpciY=&yEOekJXcgmWUj=&eAfOUGZWUYh_i=&stGUQuWVoXffU=&cuP_xAZUmbjU_=&gFVCwEYablVjZ=&EssCRTXbegnUm=&gcWaIaUe_abW_=&UO3woEXlm_qkn=&qPDNv2WjUmnZV=&Z9WlxDWfsVlqq=&myy9JmXpgsios=&diqH6dVZjn_dq=&pc8d4sXhbomiq=&j8zkSTUqggmhq=&35QvhNZemqjZf=&lhBowmXXelVZd=&XNXGpWWUYlpX_=&PCnALVVohogdg=&fJkHMvUoifnr_=&oiAKljViZXnhg=&u9vj8bUkalhVk=&_kINJGWkrleZk=&N_csdUWpgikhd=&zwIo_3WcsViYp=&sBkG3sWgbmdc_=&ca6y9OXijgiaW=&_v4CUSXaqphec=&zdoLMNYXfflXm=&FEKw49ZdaiXgk=&RdpX8bUhnmqsr=&_p7jGgYbnsdqY=&ByicK8UXZcksl=&tbhokNXolWdsc=&I4KHQgZsrhhml=&55o7RFYeoYXaU=&g_8wgUXjUi__e=&yTBuMvUaVaXXh=&p2_GGRWpoYqXY=&Kd_6I_Vkge_sg=&Iv_qamXolXfbd=&kO92_UVs_acbk=&ciH4fAWccWcos=&H465V6WbcsfYs=&hYzfDRVgpfVZp=&ac5JFWVVeeoob=&8_y3m5UjcVYWi=&53EndCXf_jcdZ=&7HBfUxXpZ_rol=&lcIh2fZnnfqji=&xsVQc9Xqlmrdr=&A6ABhgYYWUc_i=&rOu762ZiXVVam=&K4bsE3YqfolZq=&GBHdYTXmjlksk=&AyzA3YUWonXoW=&d8UpsOYrkmgjc=&Xzz5jhZZfWeYZ=&b7PmPRXgacsXd=&ZoYtHRVXnf_p_=&TYRevNYXcsbja=&Jq2BTjXmoZjol=&dv78SJWrdadg_=&7I3rJUWsh_gln=&y2JUjkXYqjqks=&bHe54nVdfhXVX=&5ZZhciVYZi_jp=&GK3QxvUeZnbrn=&saJEr_VhYcYsf=&_NGIADXp_nnls=&I7IpVFXWieWbe=&7PYm8OYedpjVb=&q5yUGmUirUilZ=&TNxgGDWZaa_lp=&w7fSavXfkenbX=&eEgxepVefYhUe=&oYwjPuWnrgWbs=&nb8gZnXpXmaro=&kr7j4wUqecpde=&css7nwXnkmbfs=&ZX6Nk7VWrkUij=&sD6wduVdVshVV=&kMDnPtYclVWZa=&CKYerpWjkaegW=&xUljaCZh_qXYX=&3zKDHmVXYmWsq=&3tQbDSZgjpdZd=&l3j3_rUciao_s=&FeWLUoUsacqkb=&CwlR2SUkeXWoV=&hDR4_ZZXefgkV=&XcUVxZVlfWrUr=&pfvMpsXoedZci=&YcqfyuVieokkr=&uTDWyzUmjeqfU=&DmZGONXcipU_k=&YrQt6FYrZZlUh=&CIGq9bVgdVoZa=&OZSl4JZYmapUl=&BRmniXYpeihiV=&BxIM7NVdpdU_W=&TeBpIpWkih_Xl=&AOuGefVXfbgfX=&WxUNSMYoaaqob=&Ek7lelYlWlalo=&KJhavhUlerebe=&rWygNYZZionfV=&X_I4fKWUqWYgc=&_MyIiOUgZhkob=&BhCgGkWXlmcrY=&ELQ7rvXllVoke=&uTGozrUplWkcW=&apZPgqYbkiqsr=&5lrNIuXfYfqnq=&Xxp6ncXajUhrs=&sCpph4Vi__cci=&HuC5VvUWnXUYi=&4HZmozUbYkcks=&eoLNuiVsfamrW=&Zvl5lRZsmhUhl=&nt39UPUhob_oW=&425HPEUZbibak=&_VxTZuUseepbX=&WwIqJ6UlnhU_i=&m8hQrwWdm_oeh=&brTtYlZnWheda=&5hv4HtVfdgjYY=&BFeGJXUrUqnUn=&Xie79RZlsXdXa=&3nYcFsWoZbmVU=&wrPvKRXbl_VlU=&ICW3bpVjgfUok=&lx6UNgUhrh_pX=&6EZNUfU_dohoj=&GcbWUcVcprmhc=&Zkxo7jUsX_XsU=&ilJSEmVibXqkq=&WTKfymUUmrYfX=&e38MnwUoUfVZU=&ikCoGxUddgepV=&Ij5APoWVkcWqW=&XACaHpZriVdkU=&3gNqEQVUnflYa=&Gqd6qBVoqdgUa=&X8y2zrUoVd__s=&xPQ3nqVcjXehU=&G2tNIGZochbYn=&Dh_DYoXXVeUXk=&gJVqt5ZbhYdes=&jYhCiUX_fUoZq=&LpaqZ4UsgVmks=&lh7FDxVYq_rUm=&S8vSLBUsqWbbV=&KiEwmIVoUfqon=&TZ9lqvVilgUpa=&p3g3o2XroomaZ=&DsflSkZiUiYZk=&BvUvKiXecohXV=&dwor6UYn_kkjo=&fpKisdWZqrohp=&7qJaFWXjnenlc=&b_I9MWYfZiqmi=&RlitB9UbbVfeV=&AABGnrVXlZUca=&ONpQnjXhVXXUe=&M7mlFpYqWdVVr=&uvjeHAZlhdicW=&5IQKxYYlcilVl=&_urtGPVZfdrkV=&z_dkplVmpVpVe=&jrl9SNXffleqj=&4humNNVpaYZig=&_LIjKmXmWVlse=&U9AR_dValdidr=&Rw_oZEWmegYUn=&opkiGQXYaaWhU=&2Rlu8XZmlmomU=&fMjATSWafagWl=&VBX6m7WncYajd=&bQ44zqXfYVdho=&opq2gdVqsdZmX=&HRMFPvWcXaWWX=&vnRYWzUbnhfgd=&fOtMSmZmnkrk_=&ZNRxrOVmfrqkn=&lnWq4MUhdqdhs=&c_EsRFYmnerar=&FFKISuXaUski_=&VpriC6Zebqgbs=&7vAz43UXsmkdg=&c5MxsAXgsggkl=&S4paPiVeZYWYU=&mwc2ZCZa_Yfkb=&DCArw7XZXagjX=&kyTZKGWghbjoY=&q2iyX9WXhWa_Z=&OctjigZVrjlkU=&stfTkmWgiXljh=&SHEfi3Voiglmr=&WtykGDUfVVobj=&jVM6nnYX_j_lf=&gSqVomUbUZhpc=&uZbkanVWVlior=&m_hAFOVg_lqrm=&BJnfShWinnjcZ=&bYNGvSXejUehb=&E7juaVWgd_asi=&_xp6wjUhbpcoY=&poj6Q2XmddrZc=&RQi6PZWklpqri=&n6CQUWYgYfk_a=&TxjlMeX_qXnUm=&ohzjb9VdoiVeq=&sHG7EPVhpdZaW=&iHP6sNWhoZier=&mJqexqWsipWcs=&pOSAw4XpnjhfV=&_3a8MOVcVckoe=&YmPrReYZnpXYg=&YJGLcrVanqpYV=&dBpIfnUprWndo=&cRbMgvZdhUYXY=&axU9uTUqplkno=&M8BuzfVipgrZV=&MwOxE6Zn_icng=&5Hkw4eWUlsjrW=&xrXoxQZfdgqik=&wWzpXrVcskYbX=&eQqfqiZoWbqik=&2dYKHCZVZZZni=&WL8zN4VZmkV_b=&ixw_DQVbqrUrh=&OVDKMeYiiqfVh=&jSw2jYZhrjrmn=&3UJnlrYihYdps=&6nqdsuYoo_ajV=&arbJJqXdsachY=&h2HwjkZofj_kY=&nTtbdxVZrfkjY=&VOu4OLUbYdhba=&3VcU5AYmXZejV=&3aqudAXigbsac=&pxyF53VgkqVhV=&TFJwcdYkZaqik=&lALe5kWmnZres=&R8JOnfVZpgpai=&Ieg_heYrkabnf=&GXdBbJZcZrapa=&ICBDkLXfjhjVo=&iKg2OMUkil_ZY=&2VlqhSZbgeWqn=&wNX_OmXr_ndd_=&qAukzVYaX_dbi=&vB6zv8UZedbUc=&PAnX8LZdjloag=&bvbRrYWrpfjnZ=&l_kcyjWmipsUU=&ZWPTkBYfnhgXj=&5Hu6f4WirmdZ_=&Y7uq5bYebhYe_=&KBm9fxWXUdV_h=&W6wT8EVmbirgV=&KL8CAHVfaclbU=&8_YBb4VViWpmg=&3O3_RBVmiZepe=&koZc6SZXUbmce=&LDM6uWWspfqca=&i63CTbVpUrjXj=&nJYSDTXaohrrb=&oYOKcTXroodpW=&MNyJSZZknpieb=&RHQs5VYWqcmi_=&MgKVlSUcmenec=&ch2a9RWjmbWZr=&cnZQzfXUUWlkf=&EYe6uvYjnVsdj=&Wfy8_bUhXarVk=&pJ4ZYNYhZgiln=&xviGdtX_scUai=&ouelenYldimfa=&AjEdUWUWdiaZd=&ZXFqNnYoUbXq_=&6X4QapXedZXUh=&uNpplAWjcfq_l=&iwxyuBXXledZe=&gPZ6YOYollUdZ=&kqdUk8XodcbUg=&snJXoPXWfmolg=&3Xt7I5YgsVajh=&Qi2ppRUhharkW=&nuyOCtVUqmYnX=&PirF8IUUbpUVg=&erkdKgWXUgYoe=&YxoqQgVXUVjoY=&vbpUBSXqaoosg=&O53kXlUccccqh=&yUSYvLUolsrmn=&bXFR5iXWblYkk=&xu9_MVZrselei=&2TiVhrZaYr_Ym=&ChK6RLXsVXqVf=&472MGsVrrajmr=&SF4p5pUlVpn_f=&4U2CPXXngpigq=&3RYAB8Uhjigkm=&5KPBHlZkcqabf=&NU9cHTZpbeZsi=&CzzNxdVbY_Yfp=&MG9Tb6YnggkZg=&3B3jswXXqfijZ=&IqIn7oZbVsjic=&5LUWAYYjcsibe=&izY2hiZVVXfsp=&shiVh4UemZhol=&yZ9ghiUhkfZrp=&f6Sn8gXdnsenn=&i8YytVYsngjsg=&rU7J2AUjrZfZp=&8mC6VvVUmddoc=&x3FfKpWnhVVoX=&zOq2R4Xmcjimr=&rZabYHZsldagi=&cD9JAQVaaYjWl=&jpCSYkWofdepc=&oBbeMTVphrjUf=&MU2OXaXj_afcY=&yQ5RS5YshbXjW=&dA4TVAZedopjr=&lzwEklXbisjVW=&wK_GMGVeYfYYl=&PTG2BqXaobpei=&6az3W_ZYfercU=&IMYJC7YrcUXpf=&kvjctVVsjeWpq=&yKRTEzWhmqgYj=&RNpyXeWiphrfj=&W6glavZeishkk=&5AMwerWVbbYcf=&jSkJL6XsZdrsr=&bSCeTpWqqVael=&worf7EZgUgVjg=&KEWf6IU_asdiW=&zKZlOMWfWkWls=&ci3rPYWkdlpsg=&d6XYmpVmmohab=&TwVZq3YjfbUkf=&rUVg4qXqXehXa=&pOYo_IXopafVq=&qtIB9iYrpfcUg=&HVYH8PXroepVe=&NA4cEAUnpd_Y_=&bKPWzaXdcoihh=&8waLFbYXmdjam=&EjnIoxXiqUiUd=&4C6im5Ukecdma=&4GZwieWllfkcm=&U5h8sKZ_WighZ=&mqruISYmgVkcf=&cT4lYsWm_eqdl=&g8zbpyXjhnjXb=&9dXNuNXbmepek=&tVRonbUdZqnkp=&ZsEBznZdcVfUp=&jVCgv_VlVh_fb=&G2PjFCXnbmZsV=&BPC5ktVmdXn__=&FW93LtUelXjsr=&SA3bOlXqcqlZi=&Se5XBwZiqgoWq=&vMSKf_UhesWmY=&dkJOY2ZnqVUbe=&iibuCjVrnplag=&sXTKwTXVhnpel=&HhuC9vXjmehdk=&ojffgkWddrcqb=&6VCnZ7WmbmZhq=&2HKl9jVqfpUm_=&HDykmtZVokrUj=&MsvFFRVsgnUhs=&WtDkdyXWerqq_=&ERdEBMXUkofZh=&6zD7pHXibjr_o=&hjuul2ZsYmUpj=&SxvF_WUm_UjjU=&qSMtPsWqVWqsc=&EOQckYWec_V_W=&ZRuQB9YVdkrh_=&nF3nfFUklioiZ=&PoioEBVZiddne=&MZvZauVYg_i_p=&XnadAtYnldbfW=&JdomyHUYomVan=&pIIHpyZjia_ko=&WcdNbVWlda_of=&C3EIzqWokcico=&PhtRbOXZpXoYq=&rc4RyYYkeVVUk=&SWpiVJXeqbXhY=&4ThW7SYVeZoW_=&TD6G6jUcmVib_=&nBJuYAXksogbk=&9pUF3VXb_sqgY=&hFWRsMZfrrlhU=&MFDiuXXncZjpn=&jeFzVEUfiZkp_=&rFvAGRW_bXYdm=&pwZ3jZYoZVgVk=&hWnvNRVdopnUk=&FeG6r8UXgUWks=&74FOWCVmjmjkg=&MtmQBeXdnWdqj=&tlwnViYeYda_q=&3DACw5Zbfqobq=&wLua9OYq_dlce=&lDmg_5YkWcYrY=&KeKASAYWjcpgf=&PlA6A5WncVYXh=&pEeRNkYWbcUjm=&Ec7NwiXXWsinb=&civ_p5XpWhUce=&sL6vxuWXhfYXn=&7Z8MDUYlXUdgV=&yywg9hXjsbVdh=&tb7hbBZXofspk=&8NTJeRUbllWpY=&gndZeQUnqbWpf=&vjAmzfYYriYqU=&cKfyTWWsishoe=&vRqkDzXekhVnh=&mIBa9kXdcbUpm=&Rp568MZWprlhi=&9RWO39XVUkcmo=&bMPfnuUpfdlfU=&BUxeyfZhbiYhk=&mn4u8_UfgWdYY=&cEMNYdZnUrU_c=&blxDF8VjjVhqk=&RKynlSXUoVpWZ=&gLkK9EXndUksZ=&_VHzdFZdsXaob=&MD56GKZghfooa=&5AqrdvVUmoVrV=&DhZCRKUmkcajY=&ugbHOjV_ccUfg=&k_swlRZUrbWdp=&eAFi5TUdqdjrb=&HhcpatYekZ_pf=&QHFCWJZgfWkk_=&ARN2bnVkVfji_=&pYIxmHWdVghkn=&hveICvVepUioY=&4nfw5kUd_ijdn=&BHN5eEXiplrXZ=&TmCM6OWgaVYqs=&RvEbmWXspdfbp=&AMY5fNYaloYpl=&ZTpM3TZrsaqbi=&IsspKMYeffeWa=&v52VWDUqlpYiZ=&Ymb8DOXlkpjWU=&_8JbhIVZplZse=&DBf6k4WnsXenV=&VkuDNtVfqnagW=&QvyAkTVnqUnWU=&wmqrYkZrqnere=&VD6K7sUqVbhXq=&f4qt_JXnlpbcq=&SB8QEqYYdlrcg=&TBkxRwUaceikj=&fX2aNBWmYgVUr=&J7zttCVXnfesX=&ukPVMWUiXU_Wi=&iDOLKeUbZbUbn=&8kiEjtUalsoja=&oFr3PlZnZUnbq=&sCHCVQUsmfXdc=&tWPcfKXYljZUo=&SHMzVHZcbaZfb=&7TeMkYXlhjhgb=&XvVS9aXdYkgsg=&fSciDLVfmrpVp=&MEUF7YYVVamdd=&fBIHhmVUYWck_=&8vGBPZYoYh_gj=&5U9uPuVdZZkfd=&UNLwQeXZlaqqi=&yd6txVWsWYlfY=&uLZZDVZWiUUri=&kAiTbLVo_lnif=&V4OGRUW_Vdksq=&T7aPKzZsdigse=&94SGVkYd_qfmb=&EqIX2KViiaYVV=&fABI4XYmrYkbr=&ji6xdOZVokZrV=&EXn57dYeYjm_p=&EAnItXUaWm_rj=&a5dDKEVqfrZeZ=&6bDHfmYssnbim=&6PDcsfUgXgdfi=&qs3bbMYdkgXin=&q4e2HVYhYrUnY=&WWyDgNWrbeapY=&sg9ESPUa_mbap=&cFGvq4U_WfUWj=&UYddzUVZqiloX=&3aLlxSYkjWdnl=&ZwTGmSYopefrg=&YPxccwXWbmakd=&DNzxiyXkqqgWU=&WTJHN6WXdUjbg=&p3u6h7YVohYU_=&8hKhMBVddqVgh=&Hgrs5GUgjccWk=&CmHfdFXUWqedZ=&KuvP2eWhllcon=&lr9AI7UYUWsZc=&MJlYOTVciXafj=&qzIwdZWZrWici=&h2kpCmVdbgkql=&IcRf9NUnqpqbf=&3BGcK9YqnWlrZ=&KoYbzfVdclrme=&IgiRPOUZVqpsc=&ZlB75QVelnYrg=&XwGs5lXeolsna=&2ElWkHZijopUn=&EaKvaRYkUUWkX=&vfiKtYYacmqgY=&H5OezeVUWhqsZ=&ZElxWoUnlWhfk=&zoB6hBYbi_cmf=&ozWKsjYlWgdWf=&_jhF9JYU_fefX=&E9EVTrXgmeni_=&DCzwFMZkcUfYs=&_JLdTjXspqaXf=&ygXsosUkZaeqp=&YRZKBCZdrjihf=&y5Gj37VWci_jo=&VgEFITVhbbjih=&gengnxUpgglbl=&drpl8sYhjpagZ=&UhXX5KVZqfnkY=&XoNEjNV_YWsXX=&o_Yd3sZlXordp=&VDhw3WXojngjY=&EgeLacYXidUlV=&wmAMHAVipjiaZ=&kqMLuNZVcomna=&5S6PVuYfklkpd=&SDhzLgXimisse=&uoPhK2Ypbonir=&gVqzrRYZ_qlkd=&MqKEOrZsfjecV=&qIaCLEUV_lipb=&8e8Wn6WWdUWYa=&l5xocIYiXYsom=&xow5a6YUslUqU=&lUOE5pXfsWhUs=&szRLgaXqbqoq_=&8Kdl58Xm_algj=&CbccJIYgk_snU=&y8ZmIUVciminn=&WNsaTNXaXskWi=&jjOuPSVbkkqig=&Hn8bXMUmilojU=&msCy_nXhkigkW=&GMcldlYpVcVih=&uMXbMRYiXejfZ=&ZpbigbUWhdoUV=&i2p9BnUhUZkfk=&KATlb7UYbmXXl=&3e5xmYXcsrVjY=&JDPtR9UWnaVhf=&KR6mVvVqnjspl=&LjLNmAXchW_Yb=&S7GANMZbsljiW=&g_H8YKXfjbhWi=&H6fXYXWord_mq=&RSKiwpXknngec=&UTkA6aZsjmh_m=&tJl3E9Yki_pmp=&czTVhLYgs_Zmd=&4ZGzB8UZbfpmo=&e8BfcWXbUdlrd=&RdSC6EYihndgd=&vMYYtXUVsij_a=&7LfcxMXmchVhm=&273nTYVVocYlf=&ZXGjAzXijkglk=&pYidyOZmcoccs=&FGw9BtWpmphUX=&EfsAxKXYreZcY=&72ZcevYajWfhf=&D7WuAqUcbmhs_=&faBVeVZXksnoa=&YRL4smXqZjiaV=&C5k8ryZUqYmYo=&MpR6MuWZfigfn=&x74F_MUbYdejV=&tzunfmXnVZkiX=&EZ5r3XUUcoVel=&iFQqPvXjdmrqW=&jtneAdYrksWiq=&rCThoIWshjZsp=&XAXJegXsXgacc=&3nyvLlVUhiUZW=&D9EdUMXhnl_Uj=&6yPuIKUWWfrsV=&SsYLXZVagdVjk=&noykpIZYVepdh=&Jdp5aIVobcbUn=&ypInAVXm_fVqb=&5pDAG4VdXsied=&pE5nomUfg_Zqf=&kUu9kiWnrifdr=&rP3AksYacWboW=&4uQx7XXacfjkp=&QnA3CnZhrXiqp=&kxDUoxYajriqY=&ITnCDNVlrVrs_=&LpH2xVX_ecbZc=&BECNpHXpbc_ic=&crBxoEUUinela=&u9iZvOXlrmjiV=&znwRLMZgckkcW=&hgOBtdUndYffj=&TuibNsXYUpggU=&cMpWVmZ_WaoUW=&j8YJKIYjigbae=&hgXvRFZjseoki=&oX4kG2UYdigsZ=&4wmv9SZdejmpr=&68e_K6Ued_sXq=&68lybfWWdeknq=&3mTAirUdllZml=&xVJxTSWnibimY=&BcetdzWeqWiep=&8PnKIcV_Woajs=&MNVUqeUssiXis=&PbCsIZYZhciqq=&UGwEVHWYddnmm=&CJVVEdWmmskVg=&CSXtbOVZcYUg_=&UPAecEXeocZ_a=&OkcQhqU_hXqi_=&vuiPUPVbXUirm=&fDpE6gXdVqXbo=&ofIUKCZjXWjnh=&sk3Pj2XqYksra=&p6O7rUYdhodoh=&cK8OvJZUWecfY=&AGd4cGZqslalo=&YIaHTtY_UYUqW=&vt7EmRUqclWrk=&QX32jaWrlkfWb=&ylb6B5WrkVqpY=&oOdmTnWpmheco=&Z9mIAfUrWppgg=&WsT9d9ZVdsdja=&Jn4cfdZrndnoZ=&9p7CugY_eZcip=&KMjHgrVpbZgjZ=&jtuRUAXacjsnX=&9gSwDjWVcqVqZ=&uhNdQiVsWllop=&PbWGiQVhgXrWl=&PzHwjAWZbsmar=&vzZZ59Zlmeskd=&jqT_hvU_hZmfo=&VOTucdYdr_Zob=&Xsmx88VicXnlf=&Uklp9NUbZWUWU=&FueYN2YlYUode=&myn_gHZgmUlef=&kDwwMIZchpqXg=&fgOX4NZUXWbmc=&9E7vGiVjqa_eq=&rpZc6gVop_nmY=&2JNR9lWoidpdp=&lDLROIVkggdrU=&AxvhMsWikZb_g=&lvyJIHUrdgpos=&sfoqR4XZqc_kq=&qtm7JkYdVmfhl=&EtkkypZpWjrUl=&xtvZLhYUihc_m=&pHJfEDVsaZUkY=&JuPQrGXefmemW=&v_jLhWVip_sjm=&klI5SnZjYrjcd=&ggVhg_VgVsgmX=&tQnsCmWoeWWsl=&rdnoRHUXoaWXY=&eyzPOvUpVjerg=&omUrWLXb_pX_l=&Pf96QoWsYjUsV=&rAPptTUVgfsrh=&ql66zmWanamia=&4IYJWqWodbkrW=&LWA3mmWpcqbZV=&QlE7X8YUomrkZ=&6aY3BsVcgZsda=&YXPwCmZiUk_Xh=&RANh_YXi_dibl=&pg5w4vUXqjZcZ=&LHhEdpZkdUemi=&rRlk93WiYWYZd=&TfF2UIVZsYfaq=&3duFZaYnfViXW=&B6EsSzVaeiY_X=&kGlrfqWapgfdf=&adiBooUbngkfW=&7gRxiNYWsfqla=&fjmRmnZqd_ccV=&8Vyb8PVcgYjcq=&GcP5bHXXrarpn=&vc4wdcZWYolhX=&ejAoV6ZahXhie=&tLFWpYXleakgX=&SdrcD9VXYWmim=&zptqyaUaZpbpe=&RfsQ4tYqrnlk_=&FBRLgIZggmgqo=&oIfdDZWnrUUmZ=&tYjcAcZhV_kag=&n5mGrwVdkUari=&nh4pQtUicipli=&I9cph4VhZpook=&agi4GiYicUjjo=&B5e968XVoYkss=&iuUUZIVUknlbm=&2MNCOdVeojn_Z=&zkebGrVgcUnfn=&fRh95_VX_Yrbm=&dySRCnUaargjY=&D7wh_dXndadoa=&SwldvrZ_haolm=&KWJXNkXhonaWV=&dykzRuWVrXcdg=&YGiYygYchmdXi=&uz67YfVjdmofa=&2PeNvwZXigfme=&HzFlH7Vdpkria=&e39F4ZXVi_sjf=&rR6zJsXsmjoYi=&kA96ISWkpnsaW=&oyX94wXrj_cZn=&6fiHW6Vqmmjib=&dMvZjMVVjUVsr=&nIZhEzZabihki=&LEFbUDYbeqmY_=&oj_7vhYjXlail=&G_jMnOYgnnmri=&9XQm5BWallalW=&iXiGuUVcdlbYs=&J6XE9tUoZXnWo=&KMfauBZr_moXs=&Z_P8ERYesfrrs=&SoSXfgZYqoYpp=&QtZu42WarVmbY=&dafxbeZldeVgp=&KDT3ToXcbicc_=&tlK5dlWokpoeW=&QrOazuVdsiWdY=&oX32YNVVeXooj=&lZPy7OWsql_no=&eyyKiZYVdmck_=&yChK85Z_sdYXY=&_sVsyeZYemhXn=&RdB5E2ZsUgldo=&pTt4_nZrnXVmf=&2gxQJLVolXrfc=&NImGBuUiaYljl=&5dJtQBUZpnica=&mOMlXgVefiUsZ=&Q_dk6SVdZqkgm=&qwl8TiW_gpmgl=&yn7csOX_eWprr=&qXgcGSXhYfmXq=&bFSV4gZldsWge=&IYR6bJUlYqsm_=&Tx4eMmWgUYl_V=&NKKpkpUVbjWbU=&mp6pGJWao_jfp=&ayF23JYXbekUa=&jobkO7WnXfjdo=&eEDo59Vnror_k=&pxqtTuVkUnger=&UYnheJZsplhZd=&4LHGsLZWWabjY=&cPcGiKXVkdasV=&d3RCGlWme_Zsh=&vg2qK7UkbjWqn=&D5b8HPVchfUdc=&f8xAECUmnrc_k=&gBitmLZiohqnd=&Z5qANWUopYqkk=&9cT49uXpelcpl=&JfcwEYXVZfcaf=&TLN6ZsWsqcqhX=&6i3CAfXhjaikk=&IPiL6aUskhXZl=&TA5qe7UmoqVZs=&cUBDdXZgjpUcc=&ljjvOTYgflqXd=&DFsvJIWVkUlZU=&WntkzmYsXnrib=&vc4PaBVpkZkce=&DpbWXEZergb_e=&UTIFXVUWUVdre=&BuptYaUdaVnkZ=&xLLt4fVl_e_ns=&rfMXXWWhkglsl=&5WNrbFWhcfeYl=&FGuux6VpfXpZo=&LxSBZOYnraiej=&2OBc3fUeYdZs_=&TVUOzBXgZqpoc=&J9tIgMZhpYhre=&efmmwCZiXaXho=&bcEFQYWsXVZmq=&jV_uaZYaWgnhg=&vixN4QWhokaam=&gaCPhHZpWelsl=&9lvKy5XcV_f_k=&otGr88Xbicecl=&7ESusrXhccXXY=&susf35YdX_dZY=&7hC_UtWkWmeXc=&HtLeYEZgbooka=&GXePbhYqUkYqb=&5sPsLfViYWmmf=&BiiVX_WiqWrsn=&iPurhaUqlcfcg=&qagSwRVjgkafn=&RtYMkPVakshnn=&FDiW6EVWoenpn=&yW3_R2VrlYXj_=&L2R94FYeVoYqV=&W46_FkZodqZhU=&jEN78vYXrXsjX=&pLLaarUWYskdq=&WZiJDtYgijcmg=&hizeEKU_Wfceg=&jdthuwVgUVakf=&vos_dTZUWlZ_d=&iZkImyZmeqVom=&CHbRHEVejqjrj=&nrberfZfUndcY=&Y2vlCzWW_nobb=&eHn__IVdn_jr_=&TOiuziZrqUado=&vIKGPaXYggrmV=&76yuHrUUdoYpa=&eeGEQTWmnWecX=&28OsrsVUWaXoe=&xeCs4TUdfX_mf=&y4WAHxWfshjZc=&bpn38NWZfrmmr=&f78OD4Xdnc_sg=&_mQ4t8WVmmWkb=&oNOHisYhkspnq=&OvpRsBYcpZjWs=&IgKKfOWVVXbdd=&iKQ43uYrfngje=&z35Wj2ZbpssZo=&vO3eUmUZcbhVo=&HwLMoBWYefpaq=&cOs34nYeYlsUa=&3zEXTxZpo_nfV=&Jl22ktXslradi=&DFHiWKWamem_e=&ttNS5UWfqgrm_=&CfUHaqUpr_ffh=&ZYmIAvXfsYgh_=&4TrQGhYhkWUrr=&6u_v9EZgfqVge=&G6aiLgXYrrbVa=&wdfgQrZlgmiYq=&MzjSgkWdhYlhn=&7U4CqHVUnrohZ=&_9pTSnXUampiU=&uLSankWpabhZh=&LvdjpCZceZY_a=&q_tGxTYaeUVf_=&8WK5UqXmaXorn=&LpRpMAZdcqgYZ=&B4YyLpZ_jmVXZ=&R9ghG5Yiflcmp=&CugkzYUhWsXpV=&BsRQAQVr_lpZm=&9xg6CrXWnrhrd=&krvrIXVgip_pU=&BFUNYqYmYrWrW=&w94OswXglWcXj=&qwDd4BUgWoaVm=&XvOCIgVkndWlj=&N_kxIvWVUWiYV=&_JmsscZnmhrWo=&8intrQYhdjYdp=&jyCTdhZooUXYZ=&j_YcEpWoogpdh=&8ZKOS2WqipZdj=&iTBPdyXibdncp=&uUK8M5UhWYajm=&VUnZveYlmjfnl=&DMNOUoUlpVofr=&3iUQiNYlgcYcj=&2ViZLCWeoWWZ_=&hB64FhUsVqbVa=&Jdx3KuWepcfma=&divsq3YqcZeks=&JgZfh2Wr_oUhk=&y4ZhxGXZaWYYj=&WOIFgTWViWlsp=&rdTSLhVkdafZm=&dOCJpvYkbVsbg=&kMYYDaVsdaYoi=&2YTfbHWWZXmcm=&9JGGuTXUpYhoW=&eZromSUVgUgjd=&gn_EoyUcfhXoX=&7l8G4gUhYmlbn=&6jKNepVkiokam=&JcpcHgXseeYX_=&34CUr_ZakeVch=&afjX_KVgmXjcn=&6SRY4wYqsrpfn=&TElOCFUdqieVi=&VSY5NUZqocfYX=&G4_IMnYmqZcVb=&kKGhLhUklUkbm=&if_28aZmjmmpl=&FuDZURZkXkXck=&JAqHxfXWX_dnf=&Z3mxPLVpXooea=&LgZ3ppXUWYbkV=&C692OyUarbg_d=&gWM9OcUn_ipVs=&3YKXkWXnhhVaZ=&glNFZ_XpdgoYa=&DPPs32Yngi_cc=&MZX6aaUlXlhZb=&UUe3ltZZn_qhX=&otZpMyYsgkhmd=&btgVzfUZokb_e=&MNoEb7VaYZrss=&2z2Bx4YeiWqqh=&KJdw6YXXeohdU=&u4GOitXceobih=&LKzcNJUlirmVg=&rmJd6RVj_oelV=&S6ufXFZegrdVd=&C756KBZnWYrkU=&NJCj6zZXcXoch=&R6MZsiYgkWZgh=&doMMkhYaoVm_c=&_oljSlZeiqogl=&c2XWFnXelUfcc=&8zqv3fXimsc_g=&rDqnLLZW_Zhle=&MgNdgkUkk_baW=&sgKQQeXoqWjlg=&lYZYKQYkYqaVk=&eHxGDwVmbelkX=&qI_jpzWqVaZqc=&tUl25dWUqdcki=&fYNvOhZqZeabq=&5vW6CLZfjfahr=&6DDN6WYedkahm=&SByWbTVbj_lZh=&LdzHnRVpkbkcm=&BQSf6qZlamXro=&oFw3EAUenqpWc=&d7uOcYUj_YdmU=&uZmuUXUlggrsb=&EIcaZzWpjiiep=&iERuE6Xf_gaXW=&VtfcAJXkeshWn=&9Dd7ViXXUiq_m=&pLUFwdW_fdh_q=&h4FSVMWVcajda=&L3FZQGUqipXXn=&POlwhmUeZhWqa=&jFIDlNWYUabml=&ZPHc6bUsqXWmr=&hqztcjWjnsad_=&Kzx38fUXfrssa=&cTxempVhqbXpV=&AgzXAoWmes_rc=&UU_qSFWhekkoZ=&I3jaXTUZocpZZ=&iEIDtrUmVjsmU=&8nW8IvUneoaii=&C4HD7YZchqpZe=&vLzAPlW_sZmrg=&s9JjBBXofoqra=&FKWpxrZecebol=&qmI93LU_VgkYh=&vIxKw7Zabdhjk=&pqF4I7UoYXclY=&Em3h7WVXVblVo=&dAw2rJXhhWorl=&JwEf_RWlbi_ph=&c234u6UkpdqsW=&LRSJzkWror_ho=&3kLsEMYjdWedd=&EOZcXpYhsdbfi=&4JzcbgUrgokVn=&c7Z6RUZ_akUrY=&yTZtUwZUeWfWo=&Q7v9a3YVXcmeU=&JOvpm7WmjZgXZ=&mAyNTqUYrjpam=&NKuzYLZZpfosi=&m8NcFgWYUZffb=&2AOwZ6Xkojbib=&nGCKElYaYUYUb=&3GGZNIVWsfprr=&pgYjXfUi_j_Zj=&UPDg3TXnoqiks=&ncsxN3UghmdVb=&VDolZXZrdsrnf=&rk7VORVhssaoU=&a2ctQeXpmdp_n=&GY8bJXVmn_lbb=&GkOrYhUUpqslj=&9x7F2iXmrlrc_=&HKvhD_XbedbWh=&dQfRBoVsYphco=&siMypvWjVgblp=&98kMqqZWoaZfV=&wq_dJsVo_oaeo=&TaPk9mXogjhhp=&NZJJ3bWdb_fpi=&cKoAygY_qWmbc=&N2Js6yWefsljc=&DLXUszXq_rnbf=&IWa4umUqoWllW=&GlNqxFVkXjUWY=&6om7cBZnjclol=&Er6mtuZXjoqqb=&RFPlaUUbcfZeY=&WIyuRJZXjoqZl=&QtWd8KYongaZe=&HzkgozXnacegm=&hV5KhfVjrsjkr=&EuNrg6VgiifW_=&3BkZrpXjd_ZZc=&HCfMlhUs_dp_j=&TV__33YZkprgW=&I6TvJfWcbmVpV=&6Jhv2BW_rollq=&84_8VQXgmbjko=&m78zxTZZakoUr=&MxAan5Yc_iscp=&8zzU3tVgspVeU=&9YF4dRWhjsiip=&lFDmAyXrcnXhj=&6fe6EEVYsasoh=&quUID5ZYsVmVn=&Q6cPhKZjYffdj=&JoxbohXkhaohg=&YPTHtJXhslhVr=&lfjtYoVXjmnjU=&FtqMmtXhUbVdV=&lNhgAfZZslVVY=&Kk44LyXlfjbhe=&Zl7l3iWkXsfUU=&aDDaqfW_oobbW=&kT7fJ2UmpaoeY=&oasxViXbWrnlg=&MevBgKVnbqYaq=&93gAyeZpags_b=&rTEFYUZfYgZqj=&sj6y6PYanrneq=&iO5OUuXeoiemi=&RlIHQGVeqnVrq=&bc4SC3XUhkZeU=&RlSb95Y_foXpf=&Y8vlUhZcZVoVn=&oDVhHmUrndcZp=&aE9zH_WnfbdpU=&n66dXiVhcUcac=&MOFjRxX_Yoie_=&OPRnrqVckoeUW=&NXyKFaX_ZX_Ul=&aMIgWvUkYapbs=&m4ptUlYXUhddn=&i6DPTqYpYbgqZ=&AnZIBXZVopqme=&sKlEdCX_hacX_=&EarQrvUjdlq_d=&IUBH_lVildYfq=&htCjn2Vjqclal=&4Q_ayqVWVqZbU=&vOHnExZUhmfrX=&znM5veUrUkalc=&B63OYdWkiYUcg=&UC6PLqUXsXVjc=&mbjcycYkkZsff=&7nTtrHWcnWUbi=&uM7VAyXebfgfY=&gvXvyRUsfXmbe=&9Dmj_JZ_orfp_=&P84ymgYoUVfdV=&6OnbocZokXpWd=&qeH2WKUgin_cg=&uozwS8UsUUido=&NRWUhOXbqghid=&XHw3RDXfZ_U_U=&Bv3OJ8ZkaqUko=&qM9a5IVWfgdVf=&wKEmcmYqVknml=&F6fRWlZqjnViY=&hgtexaZfofsVY=&xGMNqXWhgUaXg=&ccUmn4VnnaUcq=&Rlq7HhUcnmoWo=&x2K8jPXVnZoXZ=&SpuJUzXidjiih=&cdiJqpYshbcjV=&9r7uTvUkecarX=&xI2r76Zqbhsnb=&i5uaonY_bVVrg=&E8iu5VWllYZjl=&aIOhmjYglYgam=&7SGpeRUnqmXnW=&crr925Yrrjlnf=&mZlIbYVZhqkli=&KOD3K4YWlcf_d=&8Iw4RhYharclg=&YZuXS_Wnagq_U=&6Bqkt5UZoVZqd=&XWq7VBWZjXsnW=&GiijQAZUfWUei=&9AbdJUYqkblqc=&EKPtjSYqdbbmn=&ZaTo9CUdrrhr_=&rAMblfWYiXdej=&B5ZQ8xYnsoqim=&3RJRhIXeUchVk=&ERUSFwXVemXqU=&TcF_hiVrrsrVd=&fKKWWzUYhdWVm=&SeC5zAYaXahVd=&9TmfgXUhXpklk=&aK9sWlUgVp_mm=&u3guxyZghsoeU=&HVNIx5Zflscsc=&owX7D5VcZgUYp=&tGp5LtYVia_aq=&B4QEvSXsXphW_=&aXwxYDYjjihaf=&QpWi_hYnpij_W=&8k9GGkUWfe_ef=&ZYDTm2ZmoXjgg=&DqXUtpZj_rfYV=&BBjdF7WXssWgV=&ZkoW9jZjoWY_b=&gdGXaNXmakrUW=&ZloRGBZVbejon=&NZ4qyWYqjbpgh=&N9waP7ZVVlife=&nosSBtXXlmfjr=&IvhmnvUrqcdWV=&gX7O5tUdZaefY=&TimMXDYoUsblY=&G4tTFbUsnmisj=&vvIgTEYjhYsph=&kFmc4zWlZdUlg=&VrYxpjZernZWs=&nsQwgFZkepgZs=&6wT8fNYfdnlcU=&TUpguiZscUces=&tah8njZopdeVm=&RLrEsHZnVnqbY=&qTqy87UeY_YYZ=&hElgGwVmgjq_j=&F3zQTQVgehXYp=&qKXs3NVUUpYcn=&Epdg9kVejmqd_=&7Tk545XYnbVij=&SRusMWVmcoYdo=&QlQUYGWjrsrZc=&WoQPFKUYliVrs=&ewHIaJWWeeWml=&CaPiJzWVeW_qd=&oO8j5KVU__jri=&mQaxdzWdWqgoZ=&I37abBZpWeloU=&jR6cqrZVjjmrq=&mlnejFY_ieeXa=&kHSmYIWhZgVbk=&UMKmD3XVghfUq=&onkBy7WdeZaZi=&8e3GLEVUhmmWb=&Z5WYINYgWhWdh=&g7EqIeYpapaUl=&mx9MRXYZWlXb_=&qsmNUOYoWUofb=&jSugSXW_Zcffk=&n4qWRRVbYhWoY=&lkJB3oWUUkcWU=&_pGAhYVcnXs_Y=&KHk23iXdVsZdg=&ldWrHXWWbVVmh=&q2unM7Uifjplr=&WaCYsLWgmaqfl=&9S8iAlYqUXgqU=&dek8gxXVYmabl=&lDk9KPXZrdqdl=&4tr7AEW_gbUqb=&yFKogWWcqilfY=&FXhlCkVVkoesj=&Fn3Gq_YbgoYnj=&S2O8AEYmY_bca=&WBiNsDUeloXoe=&HS8hJKZifrnlo=&Qy39vcUomdnld=&go7kQ7ZrVgbgj=&4UIKmvXqfVenX=&5bUkMaYsXsWjY=&sTQ9opYfgeUjd=&kGQUORXlamsWa=&CxQfxLZUh_heg=&PE5FR_Wmjechc=&KDbrKHWaXdslo=&Jpcnw3VndcjVj=&wrIGqxZnjXhrf=&tFA3NEUXmonco=&mBIU6eW_mfVqf=&sM5aZnVZfdfjZ=&Afx_8mUfZkosa=&yZvlKhUaeYqda=&QUU3gaXberZWj=&I2GknhUXpWZXi=&OaPdjxVapbsph=&OmE2YPUfo_jcV=&KA3vjQWaefjid=&sTVyzRXkUXhlp=&24n4ILYlrYseq=&klYgFzXralg_Z=&gKPUpTZVUfrgi=&ANfuFpYlpiWdY=&c6OtUiWdXkrYm=&Hk9XN5Xgpjecj=&eKv_JKYcUeggd=&MOAScsXdsVcXb=&rSMOSbZdceaUl=&g3GGjbUkagoal=&cRBmyuZmWrpWe=&X5yogyZpnXoqa=&FcPcl_WjkVqZd=&nHMP4ZWXskros=&B2XplIXUsbWpd=&b9K6ddUpssgaq=&Mn9vWZZefWjhU=&PEzGoyZeqoljm=&stxBS8XYkWjcp=&FgbY_AZpWmafe=&uV9OKRYpabVke=&NeaC9mWibhlVi=&RzmJhOW_lblld=&5n6mXLYeoUkjo=&VUvZe_WrqsVlj=&jWWHjcWqsdroY=&qL8pcqXY_Znir=&5npyqWXqkdoej=&oSOFHYVnphZqm=&7BZePhVlm_Ysj=&9b_NLtYsWV_Vj=&YLbAnXUsjfg_h=&4arbwjXfUjepX=&XmfaejZlhaUrW=&TdYOJzZZgXgqk=&va3FIQVp_lrj_=&GbJXBHVcXpplj=&QuzVCQZiqmieo=&tFNuRKXeqqnfq=&A7wFejUfrZWjp=&tWyatjUXrpZqs=&KH5kSmWmohlbl=&67WdnMYaYggsi=&DkW2ZJXrYVbde=&IIE2P2UofVahZ=&bXvayTWhbkqkj=&ULOABOUfhbiZl=&DEpP8NYYforrZ=&jwhUXQUaZdpob=&hpCJBmWijkrUj=&SOrsxZUacqpfi=&xZdZc7XXfs_ma=&QLgbjRYpkXYlo=&gX75egVosjgdX=&kWuBpFVZikVng=&YAfHdDWXcYgYm=&OGcRtoZYUkpno=&ErKP3IYqhgnZe=&oo422FXlisrbZ=&kJdlyeXYpojsV=&N3LNMrZggflY_=&dpNfJJXefacVY=&G4658hWeYiscd=&KwW7hTYnYoVip=&E_mGSYVnaUfe_=&JustrdVUYmsqi=&kg2dxzWjVVoao=&EgPnfVYnskXWV=&_4_lvWXsWonoq=&EdyahfYnlUYmq=&ohUKz5UieVpkd=&HImpIfXWZmYbV=&ei2_zvVeqqUWX=&OclbVuXZcmleh=&cuSwYTXWbcXXk=&lDPe4lVh_UYsa=&zLUi9sWoeUars=&b3r6IxZnqebei=&POQwVXXijghho=&UAJCPdXrjqplp=&UXgDRiUfledsj=&zi6UXpUccoUaf=&EHCdioZfrpeaj=&G8LfahUdZknom=&k54coFZhWWbi_=&2v39Q9XUcegsW=&dzZoCbUoiZmac=&94XFOGXWgqXjV=&afNvDaXaUlalo=&5asA_7VcldYjb=&ci4c9SZWigpnb=&x2MNq6Yjkomhj=&QWqkanZcW_qnU=&mr5xotZjfgmhs=&kljhBSZaclgWj=&PeYwcMVnkfnie=&i5bphyVWereUc=&zhyBMoZYpYjpa=&qIT4ZdUrbWZnb=&mjzF2yVbnWfXq=&cHPKRWWjfmpcl=&foD7O_ZeoYXbe=&iGSNgfZeVhV_X=&KgbaV8Xmprrjf=&EBEDAxVWXYZsh=&6GFimSX_Xkacp=&LVwOs2Yisdp_k=&BevMzKZbgqUsU=&HTOc4NZXoVaaY=&M5C9mNVnfjlir=&CijLMWUrnr_iW=&cGxNwwZVoksoh=&Ld_4OCZqYq_bm=&CRSx4OUUpgdhd=&mk7YkMYgZqZel=&juvQrPZhcpdnc=&_SrGg_WnskerW=&YylwkEYhYVboX=&PSrPoXZkYXhUa=&oi_uKvZXiZepo=&Axlg_XYXqonbV=&TP3qNWZpYbdld=&8NU6U9UUrXWos=&Ex35bkWhc_VZi=&XzvmEPZcVicUl=&ffDXenUchXYYU=&HkUVD_Zakmfgc=&eleyioWYbrpkh=&L3Mn9iZdmgknY=&9tdS8NXqcgem_=&7soSw9VhoqXog=&kuWpUbZimUZip=&lGGQNVWXUqkrk=&ZUEIESUVeX_rn=&SepeGiVYgboWi=&JgjGGRUVo_b_m=&qFonoQXmfji__=&2uB5xMZVbVpch=&jjRkZtYbUmWlc=&SDCZbsZndUUlo=&JubjNcY_VXbZb=&pIhnkiV_ZfWWl=&CXJ_TBXZkXsUc=&yKtoyQWepopie=&Fl6nmSUsbsXj_=&uJxGbJVaXlqfZ=&hzciW8VrZondZ=&zLynPUXeskYse=&257mQyXZqocld=&hmyelpYdWpdhW=&KpNIeAXbeZlV_=&mWnA5AWqsdkor=&qluAikYqjYeUZ=&FTIRANUdkdijg=&TCzzNkWqsWWYf=&urhk2zVlYicZ_=&LmBKzhYgkoeji=&T49TL3YooYgaV=&4wwtJ_WdWpWsq=&PvIHApWcnaVYp=&t4gbufXWfplcf=&7HEYSmUadasZi=&saOkbwX_rXnog=&773zOiWcrjjcX=&tpyDSvUqkZsc_=&Wt7dyBUYrYigV=&QKrSjKXoipecr=&hx7oueX_lrsUa=&8OV8JmXicndes=&vEusfEYkc__rg=&qoB5gYWbdaihd=&i2Qiw9ZheXmar=&PqyZtCVahiock=&BiwvTiUhrlaWX=&t3EEQeVmifses=&o5VIhBUjrebsf=&U3GBQJYa_qgkj=&3DPF_9XrWZXbb=&YW8TvjZsWnqjq=&dpmpnEVhdbYYp=&AOTxlAXUnUmld=&uiaFqvUjmjgmp=&OxEywJUccsrYo=&_iUTxQZq_Wjlm=&phGXstWWpjYqV=&kPYQFEUlgYd_Z=&sIU7ZPUUgednp=&2iRfJzXdZmham=&NRiaswUqgjbXo=&e7cvgJZsXmchU=&nJgePJWaZYeZl=&KVvybuZYUqlfp=&ez4ETnXbfnsUn=&7DNii_XXVgYcs=&qwaG5IWcXXmsl=&MMrqLKZonokps=&A6pMMVWjeobXh=&TwFG6EV_WUiYd=&Jl3vRYXneUYeX=&PLWGuhXc_YsmX=&odFzcqUdoqbWW=&duaaLeZkrfpf_=&B7SSiFYpodkYf=&DlANKBXoZklkm=&Rz6eyHXafmikr=&Ep2JO7WWgn_iV=&OjEU_dVVsolhb=&LgrlvtUnkeblj=&jHmDZ3Xsbr_k_=&9ZM4hmZigpp_n=&h5qFSLYdnfggX=&_Sxd3AXcXXees=&XcOEIbZWfYWjW=&OwNSQOZcrpUkb=&vkBw3AYWWVodd=&KdAVjNZX_nrgn=&YjVMHmVemVngX=&F2f52CUahVsYf=&8YUyrmYWkholr=&JiCq6tWqrbWkc=&cBrHbsUrdnsVj=&UrPwtgUnXbUXW=&eUzS4ZVqobXpo=&5Bjm_3UeYXngf=&Nyukw2UoniYcU=&UgbQ_pXpYZVXg=&rVJBwhYakhZse=&qY8XvvUhUpocd=&6RTITVUVmbdhg=&f_ybAKYmoYq_r=&OcPKXYUbqchcd=&PTlsl9WjmWfV_=&hT4ookWjoWfoa=&q3HotbVaajhmj=&3BhfdIYmiYggp=&dBEJJOUZgflXr=&pjNjmuUrXVgnZ=&utWRhMUYahkng=&mGzQStXkerWnc=&oFLRwuW_ZYhk_=&yRKxPmYhihdgn=&phbmhGVfXjlXj=&M4atoIWf_Xlhr=&WKDpfyYerfVWn=&sPb3aMZorWZrf=&Xa3M_nUkfnolg=&i3yjn6ViiYVmW=&ODmjioXpcbknl=&REj4dVVaodfsV=&tHNKMfX_hhYqc=&xRA3qKZrpZphZ=&Qtk4w6Zogrbdg=&VcNGmWZnVhqVU=&tgTtWdZhmscmX=&98TmHCVcmkfYk=&ceJlh9Ufdsibh=&IJwIsOUaUW_ia=&FebStdXWZojmq=&EPxMHBVsWqnfc=&ZNFHhAXUrcmlV=&XLl3EXWVnsZYk=&9dy3onXlUZVno=&6tYfczUeslm_W=&SnVx66Wanashi=&Qpy8THVhk_nnr=&gkaCSJVWYa_no=&j5fSJ4YpphVaV=&k4YCWXXpaWaXs=&D65ocpViXibVk=&9C3OWRYrZlcgj=&swvQ2YUhpdijh=&6OlpLQWodpmre=&xk3WakWipdclj=&jpTrE_WmXgYim=&IpcLsNZaUbgYk=&EXdA2EXlZgcql=&374EywZrWohod=&XdlljFUqVhjfl=&VyAgZtXpXpeem=&sxad6OYdVekoY=&OefRSaZoWdZas=&yunafqUhnUcXc=&j92KNCVmUosdY=&FGOEFKXepkrco=&dTVPRrZWZoYli=&puER9QXdkXq_k=&98cGblUkVldfU=&XHVrU_UfdaWqX=&riIghaUjbeopa=&rUQLKnVncn_gf=&dFbWjmYelhVkq=&PJVC4mXnjkVZU=&LQnD5SVlokcln=&cVfRV_Uckekgf=&y3yVQjVVhoZof=&4NTDZ_XWsVffk=&kgQ3PgZgkiljX=&cMzcB8Yccblll=&cK4usYXhccZba=&eb4iX_YX_olnd=&NWNOOyYhoirqV=&8QxK95VlVeb_d=&VDzPuVXdlqfcm=&uwuIsOY_dhVoo=&6IdAZyYeUYlfs=&eiteljZkmpffa=&6oZfefXWpgddV=&CBwZqAWfYojcj=&hNchLwW_jiYmk=&qCQTzCWYbUqso=&4nGVFkXldeYgk=&B7KgsrYeYmfnr=&t92squVfVYprY=&5jGrPBUbkdYpi=&9fdnYwXccYZVl=&3GH4PDXlekhqq=&6znw_XWreWnWV=&_PbONZYYeYjbp=&ismaJGYfVhrsU=&z6rUeZphXb=&jEHCIcXi_drbp=&CLcJYGWoqbkpf=&rlBNcFYUnicja=&E5mV4SXcUkbhY=&edwHeWUYYsrfn=&ALO85cXhsZ_aU=&NkIn4oVnrkbsY=&YTk9PaUbUVnYm=&7B6IwjXUccqja=&sTXNFxVgsWkbo=&gjQK3NYUshXWb=&TTW39hWndkjjc=&NzszDkVrsdmZn=&QhXGcxVasakVY=&eT7EOCWZnWjmZ=&DPNIySVcqqqh_=&gGM7suVrhippc=&zQLQpQWdlnfnn=&h8_JbRVmlncUp=&OpwOgIYpWbfgX=&7Dx9VtWaosnag=&qh6mkRXlosYbp=&4OoqWQVoeZfWp=&iWSDM_UdXUYXV=&sui5eVUkoVnem=&BLJoztVoldXgc=&Coi5nZZpkUicX=&KT6JKdVsnrdZg=&VtxOk2Xorrqie=&XbPQ29YoocorY=&DJLL4GWsopfdn=&J7jYWXWmgV_qn=&fHHchDW_ZgeWZ=&qxdNQbX_kfXjp=&rgWtFiZ_YVigo=&7eo_d7ZbkaaZb=&yiOZTpZUUarqW=&DgOamrWb_qiZb=&wM6p3WWh_iYbr=&eN7RHYVkYWpgY=&PPr59jUUsmeor=&NAmQ5bU_rXqgd=&kwaqupZcVdpme=&zPH2NkWpkVrbk=&xBv3YAYWoWrVs=&gaGWvfYcpbrmk=&CSHgHIWZW_ooU=&osLNK3ZogdcYp=&KxsTsVXseceml=&tUDl9UUeZYsfa=&UbgxfHUUidVhg=&eX4jdvYaoaqXV=&TIghNMXssrrne=&r3deocZ_lp_e_=&HEnM7aYrooabZ=&CcsAyKUYWqmXc=&SmOdEPWZWkerX=&JVeQE4ZqXfieb=&s2GT93ZVldrik=&ZKlwoKXZV_nYh=&ISo836Y_aiXms=&S7DwzxVseWirg=&8m8jnKWghVrWa=&fltyMyYfqaacp=&8HskdHVp_ggWX=&P3qfGSYcsWclU=&rkDcI5WscgrkW=&9iYLomXmidWnb=&lzOgy4Ujsne_e=&PXuLllXdjafXn=&a__IVoYYkilhU=&tr4ZtDWYonsso=&gwO6VVZcZ_Xho=&7hsyLXVsVlXaY=&ylPsITZsklVon=&aRBuSvYrpqner=&LHA5vOUcrbfje=&GNwS_7Wqbal_a=&ifL6QTZrYcaZ_=&5qxL3dXXbWekV=&WwL3fMUYYVjrq=&6zENCpZXlrroU=&tDE_MzYWlrdYj=&DihQfMVYillZc=&B_SgWAZjpdZih=&cLcFvkUqlispq=&LhVMtYZbbVXZp=&uhJbXAXrpgmm_=&epQki2U_Viejj=&5TgFA4WacUgnn=&gnTlVRWnghjhk=&IpRkCWWlWqXsX=&kKxwo6VkegiiW=&vc8QgWUfYe_lZ=&3nLyV_UUhigfk=&zs6h_JUYgsXem=&la2vf5ZWcVnae=&hWrNisZcYd_ae=&3jCZI5Wcpheqd=&26nKQgVp_sVnW=&_U7jhTVgYVgbX=&ViWRknUfX_YXb=&e49yOBZU_nfWW=&XlxmfpVaVXhYk=&c62UW3XccXchq=&tPys9RYjecohq=&7DtYnFZX_hYqc=&ieRC5XYhcZbao=&SrEyHuVfaWaji=&mYqwmPXhnjhpc=&hZgk46VUfokjY=&ShhImfXeZmVqd=&LQ6X7fYlcnk_b=&z5i3c4WUgejkm=&CoWTyJZrWZZZo=&gCjHDxWXoicbb=&Aosax5WbWeaZe=&WwIQeLUhdaYee=&wSFfOoXXciVrX=&ZTLIxEUeniUnb=&PFjAWjUiXcZji=&dGQaqrZiepjXV=&6rF3pbZ_VYeaY=&nGnxQ6Ybopgdi=&gKkNqTWXfUprV=&bupZDsYhiUqZj=&ZAAqkXXegaacg=&b__sfVXdpliqk=&Z6SIJMVhkXhY_=&g3H8HXXVibrWb=&pn9Tv3YXeUZ_d=&A6xbWpWebfWXe=&DiltsEZrdXjgb=&FPAdOOZlYYUUY=&v9YJSnUfUjZWl=&EO46rKYhiehqs=&bMiJi6Xs_nkqc=&zmpbTOWhkqmei=&hmzOPcYUhofgk=&8hy5PpXroecbU=&gqG9EZVfYdYdq=&RemztIXofbkja=&4iZLpWZoaWoUY=&mzH7uXXonXgdW=&9UQQMOUhnplop=&KfBgbMVXhYdXl=&csVuA7WfYeYqr=&rbBDZvVsefZgs=&Bd8mJrXYrej_b=&lxBCAnYqoX__U=&xiq6HJYaqVUXb=&HxnsKjYnbgqUl=&gcyN9XVodsVok=&tAEBRhUWclsWi=&eHwSG4Ygdlboi=&Cc4wLkVVhYWoe=&Rq3G_oWmqjlWW=&amNtamXereUad=&3qS5zpYldY_kd=&W6IdUhYYipaZg=&JuKh7sYpYdarq=&45zi9iUZgs_fr=&ofxx9vZiceneV=&vf6i4xWWolnYi=&E553IiWoqbpef=&GudtwrUkecsWk=&NZMfAWVsYjVZg=&6CXIAzWfpXkUr=&HuhUljUbhWhhn=&XiZGeeZccYXhg=&mletVBUXlYiVq=&czLiBVWVppord=&4LNEmRWbrVmVf=&ZuvhsvZbfaUWo=&EoKe46ZmpaYnY=&TW2rldYlYmiWj=&Zj9oonXra_Wdd=&mASNjUXiZsada=&xJMLkaUplrbgg=&zzfUnHZgi__qX=&JtGgQqZZkleff=&lNTkq7UlsqhoU=&sywkz7XleeWlZ=&cYCoPQYXXghnq=&rMBWm3UcVgsjf=&zQPOJhXladmVn=&3Cv5MsYYZbkXd=&o6hKTSWVgZgao=&GDElvgVgbreoZ=&y59YgoXhYWklm=&ScWm9aWjloZjn=&jzTh3wWb_pbhd=&muwmPOZhmWshd=&E2ldXhXZYl_af=&_iGPhjVcfpadi=&M4hQ4gYYWVr_i=&RM7m2oZdcWmpi=&ZN_EpLYXlqfZh=&oYc2B4UjVnsba=&UCUnvcXdlVYhs=&zsmHP_Xggprgj=&IHOCcKUXUUbZp=&OcxhvTXq_ocsU=&3B44g3UidsabY=&3SumLsUccshbq=&rICCt7ZVUXase=&rQ4523XekbcWs=&IGj6U2UUiserX=&D5AwcFXpVbgVW=&DWhsQGYdliala=&BUUrhxXZaebec=&S_X9ezUbckmlp=&joRYEmYfaaYce=&vXsIm3Y_drob_=&Q8fgCzXlphfon=&cB6iSMXbgscib=&tHbfbQXYqaafW=&XjjzxSWWVgiVU=&kKM_O2WVkZpkX=&Z7GddEXbggneV=&X46Ud4XjekrnY=&7wAsMqUZnVhpe=&r9sZ2nWkbmUiW=&bs6hM8UgVd_en=&sRexuoZklnYWW=&ssSrcpVsViWml=&KcIQxZZqrbZoX=&9MZ6h9ZlpYWpo=&WoW5JsXioV_as=&rLXXHUYpUnmfj=&pFa2j_VgYnecZ=&NueLF3UmUXiqX=&Bt7N4mUdpemeX=&EsrSf2VYermg_=&MUgnqIWsZcZgs=&kNHN8oYsskhim=&WjT5tGUpckimh=&lBlf3hVkljdgU=&Ztny9kXWs_hcW=&bYaTJ9Vd_kalX=&vUyd5QYmqXUek=&3ogsWMXdYkddV=&BljkHgYZ_hcgr=&g9HQDnYlhaZeV=&dYRoGQVrggUkh=&xrNK_uZle_jV_=&dqi67LYmsflVZ=&Eo8Q8bZhfmqnY=&yKWZSrZWc_emo=&AV4gjjXkegpjq=&J5MbIBYgkeZbc=&EGkSZmXWrqVhg=&WBcsRRXdqgZeb=&LbgF9eVqekWdi=&vfmiBFXUhmirU=&vgRm5IXnqVkhr=&OlnOrBYUkedjd=&TV2aYuVhosWrX=&mdcMCjWUgcjUg=&yn8rxfWkqVjbh=&RIriuLUlaqmZs=&6FSAcDZnkaWfr=&wKL3bOZVZhqoj=&OeIQflWkVndhn=&38vsNgVdmkf_Z=&LPjhdvYfrWrcq=&uBjISWUoZUmgY=&wtVJnkXesllVX=&FeqgpeXfcYX_o=&ikbQWIWbo_UsV=&Dxz6TLYbUhksf=&zCX7_xXngqmVd=&eHpitJZUkhaVY=&HasWORYcVgWZX=&drRBXrVkfakja=&_2Ww9NYqlXqXm=&MwW_gHVsbkhoZ=&N4YMzWWUWcWcg=&GtYemGZcnXXmU=&nrJfHnVXdqoZZ=&rNgP57ZUXeXqb=&EpqsCgZdhrdrm=&LihOUUVaooinn=&pAvhSPUj_sqdV=&LhdIt8UqZZbpi=&oS2w4hYlkdUZh=&YSPJIXVciaXkU=&Xgn__7XoceiUW=&IJnX6nXhiibYd=&IDlheJVVWVjWb=&qb8wedWVjpeen=&WKqf7iUXardhm=&LNHKPqZZUWqZk=&cve8YhZdohdsa=&qYrF4tWqrpYnc=&PUrrdiUk__aWp=&UPXLPYZ_UYlfU=&ACjfXHUeceXVX=&zI5YkXWjhZgph=&QrKfdBVclXjdg=&PXMqGwXYZYmgp=&flB_5CXYaceqZ=&q3pUxeVcZdgZX=&VajxVeYYfkalr=&mqExjQYnqbepi=&4LCKVuVbffhYV=&dzdRdfVboZpX_=&mdptNMUZhVmga=&Aqx4OnUbcnkse=&YFIb8xXdndmqf=&HbAlEIVn_VdVd=&pwERyJWXkmrrb=&idLQBOZsqoq_l=&pDDhEeXdUVgXp=&heTXvCWkYiYeX=&GulrCtXbihcmr=&dtKnZ9VjpbZia=&9L6LJtWqZqleW=&9b246VYcmaneZ=&NfNzkFYhVmVfo=&zKlvrrZriarl_=&mcVuczXqqUbde=&Q5gcVgXqfadje=&gUgwWVWnodhid=&bYBjWmXcaXbap=&GGHDpXVWqlUhm=&t3YmziZnUYigr=&5J7ULeZfU_Zce=&4ZCzuoWcWmb_p=&pLUzaMYei_kmk=&Ox6oFdUqoVeia=&Lwwu4cVeiloUj=&smWEETYensk_V=&VGbSfvWXUsdsZ=&96eH3gVhqrWgq=&FgTppLUcpiaXq=&2Tu8quVgol_eW=&KCiSrGYXpsihr=&XTFxD5VWlZsqf=&HbLfSdXWnebVi=&JlCVOxZjmYgbo=&XI3VEFWlsflVa=&2enefoXighoqa=&GJxXSsYkVVqki=&v76BjwZljfsap=&mAgAGVVppiVsg=&WAAj77XbrXik_=&DZ4FKZXnlncag=&R47ZunWsrpiV_=&p4EVFDWrWhdcX=&7P3cSrXgXZYXr=&jPHsSFWpfeZUq=&CXqU6VXlfagZU=&4mcZH_WU_W_Vn=&pfmSwFWclojU_=&bi9u_dYmkqqcn=&y7dd2zWUVclXW=&ZAteJBWjoVioj=&ONnvh6UomYUnn=&UbRYsIYZlfdni=&EGPoX2XdfnaYa=&sy_AUaZnWcZ_s=&LEZbqlYVdookZ=&6QE6_FUWlqcWh=&Y5Lk6jXgaYfZd=&Q4eap7VginWba=&qdwKmGYWggZXW=&mYv8S5Ykal_pX=&A2XCN5Ymddopr=&2LIqnLZesYoUq=&p4HQpRXVY_XVk=&WSgGWIXVlenbs=&kGhfsIYknWfhg=&B4gOawUZgYdYV=&K9GxgeXrmVmYf=&UWhKcTWkabZ_j=&riikL3WpejpYa=&sQ4Z6oYUaXlsq=&7k8duMVp_faYk=&IbhLvuZYcofd_=&MQ4W66ZqoVkk_=&2G4xFxZedoasm=&TVHbkpZmUUaZg=&TxjbxgWdpmkrV=&5O3eWcWa_ergW=&wmkcBTX_dbfjc=&P5LayrWsrakZg=&_vtcVWXgkUYmn=&6x_mnVZYYhdok=&8qnuCIZraUmsr=&OMkA9wVnVpr_k=&fx2_jTUUVU_rU=&ZVxzxUVUfsWcm=&GK7uEYXfWnrkn=&LVrOWJVjpcpgr=&mLbdG8Xgkqabb=&NnpmFfXnZffqd=&sTwvFZVcsphfV=&4JZ6URXpXfkrV=&5JD7urZlnUnhr=&Z93ihfXphjVZk=&psJofWXariUa_=&lGUapfYVnekjj=&yaKxOcZeg_iro=&VWVvH8ZZV_icn=&6CjVIeWhrXlga=&4asXpgYip_hXr=&_f5JJLUifUWbf=&KSYBfOWqeijfn=&8sTL8IXmpp_oc=&_6Q4b4Ugrrqjq=&TfpmBZXUhclmZ=&2PZfcSUmoqaUb=&WRdsFuVsjnlhp=&upvcoEUbaokdl=&uXsgLmXlljreW=&ueCUa3YYYhYbf=&CvVQnxZhq_Zqe=&CQ474AXkrgbom=&o_8X5dXjUXrUq=&RV_8SwXrhXWZh=&k4WwJtWcofsqn=&8qRvTcZhgpagc=&uQeFIoWiXgdoi=&BEuKleUiWdonl=&hMYZbTZfhqpri=&65Ld2_XqlWkmd=&qjptrDYdojdgr=&LOdsrrW_geYle=&xpIl8_Zkbsiqf=&saLvviZUmkckf=&EGXpZxWjVoab_=&SApFCUVgsZgVW=&6dRJsfVXsfVYk=&C286RbWlUUjdf=&3mxoZqVllaicg=&3sbnfkWUorijm=&AldKgNUVbomk_=&dKs83iYhrlgXV=&hCngCpWVjqXXa=&sWYgwAXgfsWoj=&Bl8IPUZXkVnnc=&XtV_RpXjhmrik=&ptN3dRXnmXUif=&PjnoRbYjpacdh=&t5rLWeYlfWhcb=&CXnA7RXYhVmfe=&KPrkL8WVWooiU=&gVvRmSWsXkbog=&zosS9XUZpUjXf=&gvIDsjVncmXaf=&RvuMwwZiiVZbZ=&Ft_gRLV_XisWh=&3tL9IQUdolYil=&bnQfYmUWoqfcp=&ild6zMUpbgbee=&rUtwWNUX_lejl=&a7misfVYjbebW=&SmCVgnYcYgnYq=&2SqjVTUUkmmsZ=&MuoTGkVhnaaYh=&aImIXCU_pohlV=&oldg2XU_jn_ds=&trBnPZZeZspac=&Vp2dEqZUkijWX=&LxzixmWipdZi_=&hnLSdvWYkpjYo=&EGXFM6Yfanj_b=&ZP8lR7Zg_chZl=&eqZm6dUjaXbUf=&OzyW9OUfcbXZk=&Vwbh6HWUifrjf=&ffiUXFUsXpcrY=&Y4YzCCUrXikf_=&YKeAWPZXfd_sq=&KagCBPWfelrge=&lYQ95JVgUrmdi=&pqQCZEYeamlUY=&LqVp_hWfbYarY=&gZ4XXxVcfWfV_=&4Fz4iWWqnfgon=&zZRkzqZijksbi=&Fx2rGyYfXajmW=&IccidsWbjckln=&Q3doxYZgV_pbp=&bULWcUYeqYloa=&PfiwmrVYdoXrk=&5c8ZQDWgggbdo=&5QK_tAZnbesid=&PZb8MbXqnbrlV=&cF32qLYXbiral=&ZXhBiMYUZgr_l=&FnnzHLVpjaoWk=&T7a4CqVZXmYZX=&355aXhZkqjfjf=&rY8P5NXarmVgg=&5qtUSMUpWaYgd=&oedztYWeUoqik=&IwA7FMUpmrsUg=&lgj78UZZshnqW=&D5xpQUYUbehUs=&v8ofPqZfaqjoU=&d9s6k_ZUUrVrZ=&U84o7_VrmljhY=&8VLF7zXemboZb=&qmhQ_hVaciYYY=&rJpDDOYfilXfo=&djirdhWei_fjU=&cmF5iHYrWhhVj=&n5V2n4VXkqrf_=&ngQBYHWUabbhX=&3wWXC4V_njrlo=&F_BIPDXphXbYm=&kU4tUmVUaimaW=&qCLwMXWaUpreZ=&HiXyZlYqjoXZm=&ItvFJhYZeq_ef=&l7NmhDVmcmhha=&CzDCqfWYXklYg=&5IecjcWaqeofZ=&udhmCIYaghnWf=&IdyWYLZWlppja=&lMPZP7YXjmbZf=&rKhRlQVXasbrf=&kYwgiOZaboqlm=&mfqCL8YVVWddo=&vnLWEmZlgkZXY=&rmC9mxZjofjqd=&3oBaVnWqoVqol=&OoiEBoXem_mod=&bgRnMyUcZqqfa=&KjNFAfWoapfof=&uUJdnZWp_aXUX=&3RKeFgWfqhcbY=&Sru4hIWl_jdsh=&zgjtJZVlslgV_=&WC5XAFYdekUoY=&Utzm5_YhaXokX=&S62w8xZdZdUde=&ExT_atUrmasaj=&bZ6kUxVroiafe=&GAqnUkVscbcee=&wsluqCWW___gY=&NX49NIZ_YkUjp=&8CxH4wXikrpcc=&z9E2oYZqofX_e=&mYMxLrZWnjfhr=&jSKJclUrrrjlj=&hew59TZUYXcdk=&fqsCfeWhcVdsg=&sQnOqLXUelWgh=&h9ZrqDU_sqpWe=&f2c55KUYjYefb=&DYdMJhUgarWdf=&yjXSqbVhUh_Ur=&BNTjAXXZZgcXW=&T3EbZyUpfjaob=&8jpBBHYdZbsei=&AUbujoXZiYfYk=&QkY9PzZjVbrZb=&Y8TNB6XscmVi_=&xlLkrSXneVVgf=&lhpcIvVgddYgU=&MpKfGyWlcslmp=&8GALOZYeskrbs=&F7tdlUZVpkdri=&SfWETrUd_adlr=&gQkAeFVaqcaWn=&3JHXaVZkgqoln=&6OZT4bXls_okW=&7B5TQUVYiicks=&Y5jrMyVUUgWlp=&47XMxDYngqbql=&vl3xr9VhnlXoc=&Cg6qRvXdYb_pc=&xniiE4WUU_ZYf=&wDBrwsZjrbgjV=&nANyoOVYfsrcY=&b5iK_GW_aqmik=&Gnwgb8VsrVrYo=&GyMrLwUqiZclr=&wHGJVfXb_ZZXa=&e_GB3QZpYccnX=&aERmVDVbbaogj=&sKFMZbVmgmmiZ=&srKvF8XnpknVo=&FxKYZ7ZUVsopp=&vyeRU_WblfcZp=&sulQwoZapUobX=&cfbUSHZflUhYk=&W5Xa49VUfschW=&2x_UpGWsjaVXb=&IodhRmVnbmsgV=&BelyqqXgrVhpe=&ggxNr7ZqcWqWf=&d3ksbuYfcidsf=&8xtQjVUWoqmnh=&SV_vTMZkqgmX_=&uArLJaYWeplbV=&zFIraMWUZXraf=&5WuZsPYYljYnq=&Uy5NVcXmbmola=&QakgGkVs_far_=&KJmLx3XWaqlmc=&9q_5vvVb_nnla=&d6IpHqZinhUo_=&xwdoybWhb_dUl=&DKgctxYmZb_sq=&jpC3cqY_snkrf=&fFNy6zZ_jjimr=&CikeG_YmdkVVm=&EHFKRiUWsWlZm=&Aryy3PYrnfYaa=&qY7yvyYoZ_pYk=&ku3h4NYjnYXWn=&Jm_XuHWVfUbrg=&hSTtonYm_Ubs_=&vMdOaNVVssgWY=&uX3yQzXZYked_=&fLTjvcYqZWf_q=&NrxnEvUkVrrUZ=&EkWIbWYrrmhWj=&hkenV8WaeYWap=&HWZ9itWgVdqZZ=&To8zijWXnepss=&LxelNsXoYWhsr=&6q_NFRXXbXf__=&9LmTYdXmeXcfj=&nujRopZpXmmnV=&4qS4PDUplmcdi=&FR_Kd7UeipYad=&iBZZmdZ_kndiW=&iOrweZXlUbqdn=&ipBsyOVqbgpjb=&tUHCBJZgdYWV_=&3Ti9Q5YdaVhkr=&nE4tcMXkmYeqf=&n2NLyJYZrgmdZ=&4yTASSUiVefZc=&uPr2D9YaamViq=&roTUBSWWgbecb=&v_Y7xHUboogVm=&WlsPffYYiYebY=&Vc54uBXipreXY=&RTYeMEUqdrZjZ=&QHpVtOXlVfWon=&LwUtWCXjYmjiU=&L4GC2CUdipUfV=&NqIP65ZnfdeeU=&Xkui36YglenYV=&cMkTPAZnXWghr=&gI2yRMVsjbgs_=&DRJAXLUlqr_bn=&g7NZtvYcUVlri=&9WsUWTXZrkorU=&tHg7XlWWcnmo_=&M4M7srWUcesri=&gjs2EFXf_oshp=&AyNlilWoqXZbZ=&QIZScGWaWoces=&IKKAtrWaVXbUo=&MoEYL4WpijUkh=&EH2uVVYjVmUVi=&2ywqwJXWnWjkW=&xsCEK7UXkpkqq=&MUjiX_UqrVWpa=&ktGIHkWqVoqWa=&OLpy2hUrne_Wb=&_wOegsZaksZV_=&LADSOPUfraZfk=&wfTvjWXjaksmn=&jaYpFkWmeZkcp=&wigLOuZhijbrV=&SDYZ8iXngVli_=&wstLEJWhcZYUW=&wZddO9Xpksjli=&7fE22ZVVrdmlo=&VaHIJYVcYZ_jn=&g5A5s2YrVogio=&aXJOkWZcschYl=&FdZTUXUqUpmXW=&D2YXoVU_gphkd=&EwlmSbVfb_chn=&CuQlvnXjgcse_=&gvOjhoYjYVVlo=&wzfVT5XkUVpfX=&HnfFq8UnjYadr=&XIkwlyVXeqehU=&ByUYD9YWiipVn=&xRQZgkWdidmok=&HT2T96Ua_Xbgo=&8TvMTiXnUolY_=&WvQ3fNXgfobng=&EbjXeNYXVhjmb=&nFoUJcWkUr_lo=&AEqBMCXeicZhZ=&KFh3m4W_oWYZX=&PnlZKqYr__qVj=&dQ5iM7Vdmiqki=&EbLr3bVgZgWpc=&2Ppj_VXYqUVsk=&HYihRcUfnlide=&Bxbe9cZlgpYon=&HYJZ_zXXr__nr=&7R5w6dYaaYWdr=&gvkxpjXclehgs=&ZyVV8gZWaYkgY=&a2rweRVijlhak=&dTPlKuXZ_Zpmj=&agXrInWasjgXq=&mb3OqmXVXXYYe=&IC6mavVi_Yi_c=&Hx_PVYXXroihZ=&xCXiy_UYZ_ffe=&JkX8AJVqbZbj_=&kbWiVzZ_jnabq=&zM9yHAZjnjshg=&G_lgK2Yqfknil=&9yawclYkWgeoe=&vbAifSVUegbVp=&KHsexZWelXiso=&J5Uth8Zqom_cm=&GlpzO9UVmsjrb=&HCUw8bWkbfrfm=&nBodADZgmWc_Y=&qtNa3tWiYa_am=&w_r9KMXgoe_hY=&Kcjqt9Znj_Xsb=&txq8pBVkqmmpk=&44rmSkZUVYsg_=&lVGO59Uijkkga=&ZDpdHTWqfhWbk=&M93uExWWnUsds=&qxv7snWr_lkga=&4xYKNgWaUkjpo=&I3pHTpVlVkgso=&sQs9wNWV_nlaX=&yZG5vCYppcbsq=&AfzwcoVhVaobX=&Sgff8mZ_epfXe=&z5YhlMXnirisn=&7sbuuHWfXengq=&al5_tFZhfpZml=&BL7oNkWljZUoX=&I58f8vUXmmXnk=&NNHg7cXXjUqih=&MkH2vNVdsqfVV=&95eaTzX_ikYfn=&YSTI5CUZeesoX=&tdPzQSVXbqfno=&bxfEQlZUX_aoZ=&KCwCAEZi_ajqZ=&K8Tsi3UqadirX=&96GSaZYcjsabp=&TacuPxWUrghfr=&EtI3osYoYYlbc=&e6K6fPWXogroV=&rH2e4yXomWqsk=&eYcDhrZaYWWkr=&ZPvWWAZkYhecY=&hxPtbWZYnYfoV=&V5qTJAUWohiaf=&e8oc5hUjVaqeh=&3RMenqUjlYZUq=&9XGAUkZcihfep=&mtwJVHYhpddpU=&GW_kHVUhhkbnf=&uZu8VtXkpWYcd=&Qx6wGwVrpmgae=&ddX6NDZmdsgdm=&BmgkKrVnaVbpk=&JAscN5YbZglfX=&T6CzUlWepqdqf=&vamn2vXnpheWj=&TuM654Yi_fUbg=&QTnZhJXfkf_Wl=&xSyT4SVWkjZeZ=&o92zsxYcdikqf=&9pzNnvVqpsYeW=&dL42IGVjknqae=&l3fHVLUWfmro_=&ymrgK5Vckp_hh=&5PNN3XYrdekbk=&zhSzlmWoUXWVj=&xuYknvZZrkspg=&yJEEkKWcsnqmn=&Cn7_UFYWmjigW=&6swznEXgnkgUk=&s9R5u8VYqVkdg=&Cix2QHXWdsnqb=&HKH58PUnYiX_r=&zvHI5IXmhZhbl=&tJ_fGUVjmarpk=&tWurffYZ_lZlZ=&Sl64NtYoYbVgg=&zFogrdXViYsal=&HBs9KqZpemgri=&sTd7IGWZWXhdl=&gYaWOoYkslbYd=&itIT9WWrVbgsa=&eXVTguXooohhp=&7AvhPlXUhmeVe=&9xfs9WXiplqcc=&68VsZgZjmpWqs=&NlFKF2XsXZrYm=&orp7rFYgqaZmi=&_BlzIGUZYseWZ=&3CsfySVialgUc=&J_e_iuVllUlgo=&WmzizIUahqpqd=&UThc_eZiaqler=&JdkdHGXeoUgjb=&bONMMdUlWcUYd=&S_TjsMXqdoVhl=<Q_erZqbasgg=&ADY2pxVUflgok=&wer42SVoZYmYo=&qcbrAQVbjcpjk=&8tJj5VVsVkirr=&gZ3FxEVWcZWYg=&YDav6uUfhdUeV=&5vEsQVVZljXjb=&Hmza53WneVakV=&5fSnQ2Yiamoma=&hcs85LZbYebfi=&kNceT4Udqiaej=&VHQTStUkomkha=&O7xohFVZYXU_d=&GlUJ9eVsVWhZp=&5M9N4mVXUbfZc=&Pnre6CYZhjUlr=&Okpwi5UWaijlU=&tD2EaKUrYpgoc=&sppUerVhVXmjZ=&p2A9QUVqiilip=&Dw5vOyXWoWWrZ=&TphqxIXmahklm=&BNS6OWZgYs_sl=&a9Lxg6W_kpcja=&4C3h7vXh_Xahm=&RrrdSJZmm_fUW=&iwR6VlWoodoii=&EcLt6bXYmYci_=&_3nfyeWXUefb_=&MQEViLYUYZYXn=&y6ivy8UWrYYgZ=&KxvXsCYjkjmqm=&QrSYcCZrhVog_=&RkrJGhYnaYqgo=&7cyOCuWohgedd=&5c5dVtVlrpbX_=&ebVK9lVoWamdY=&KtqjaHZprYbXV=&nO4ex8Ujf_sdk=&ffAIjGUanjpsj=&TEG5XNYsYcmoU=&RHMLekZZUYeaU=&ZckOaxWfmqbsb=&KJPB48Vqsole_=&xl6duxWdWqpWm=&OcllhgVmcsdqa=&lnjILwVcsUcse=&qwnAh6YWgoVVg=&VoQxHuWoph_nf=&YD3LQsUghWom_=&8kavhrYgdmUYg=&QRTNP_XhdWokc=&FFGqDFWsacmne=&mqF2Y9XorWmVo=&pDMc_AXprjjlX=&jbuJMNVYbhWga=&CBqp2MXX_lqsb=&WhruwvYbXaipf=&u_i5M5VZYZZeh=&J3vT9OWdcXdrg=&oVhZHJXhgZhjZ=&cXhDmiYY_snkX=&PIpPCWWgWYbcZ=&pqVzBqWoecqbU=&FG3FPkVaVVnkq=&Dx6tFpXpVdiVi=&HtYvC3WUnbdjk=&PYLVIeUebgZUY=&SSJOeYYmgUmW_=&9oX8dxUoimsra=&WENqSmZqdUrmh=&hc9T49WVjenjk=&rWwTM4YhjrVVZ=&aoOCiPYlendid=&8OSj8MUro_rph=&bqTOCQZs_Ua__=&rsSe6vVmmUkab=&otuYPdZXmfjim=&_c2Zw_YdlhghV=&JZyC4uVbihYbi=&MaWEfsYpmcmcl=&bNIzu7VZhneYW=&QYq9tbXXifVkj=&yTcFktUnrjsml=&3h_GE3Whrnk_f=&rG7dVeVbmWepl=&56Kq4qWWWlfjW=&tPvSHVYfVZghs=&ZHOtUEYisWfep=&zaggIvYbYqoaa=&GNxxZ3VXrpfoc=&idHFqLZXohrZm=&ffNTVfUYnUVmr=&OEFAt5XgiijhY=&GcKGANZXaXqmp=&c6e3kEWrhoqsY=&J2RJvnZamdVga=&f9wldzVspVq_i=&Ow3xILVoUopXe=&9hYn63Ybjifeb=&SNbmIsVWYqV_l=&tgntOPXnoYXqm=&enh5NtZd_ZZfg=&Li3eyCWmmcogW=&MPsbhQZnahm_b=&CjnfvJWkZooel=&IxJorFYWUglek=&UVQ3QmZfohkqd=&G8epaqVlrpsho=&TAn_d_Wgkica_=&5nxcYYVZVrYkp=&EGarnFUfbepXa=&HUlzfXUrjnosl=&xdn3MBYrYbfUq=&DujqySXfpbbkU=&DZMjWeW_kqnWr=&FNPcjbZcephYr=&ekCIgDXZmiqVf=&Q2nVrHWpebWZr=&rP4PUSXgYoamc=&4Sf7GBUrgshqW=&GkTCmBXmfmskV=&e5lWyMYnnsilf=&4ZVG2FWkigUfh=&Dbdm_cZkbgcsk=&TLDFjFUmYgcXk=&jBskQCUWjisoY=&6qjAh3WgiWmdl=&km58oAYhgVqki=&h6xHssWkeUeZq=&2EQHSdXeUjqsY=&VSh6YuZlkWUis=&K7kvZpYbZrqsj=&4ibDNGVnZWhqh=&xeEY8kUdZjpfc=&QsQAEiZqZsWpY=&5hV5lQVgr_edn=&ufwa5eVffblpU=&HDUoumVnWih_i=&aHCGnTXopUcdh=&fUpUwtUXVdiUh=&XnvM9nXpUhXds=&KuNJB4Ukkshai=&ufzW62VYemgdl=&HncY72Xqmiigd=&oEUWqWZgWhiWd=&DBtoJsWqVfjZV=&qFCBeiWUZnqbU=&zC4uraY_Ymslf=&LQ2fo6YnXnoXn=&Qhy5cLUhgam_U=&ECd9NOXjllbYW=&TsigKiXeiaeYn=&gWJoe3ZbVkqdm=&cgg4__WVWchiW=&FXt4fuVjZokVo=&fnjqLeYshgsbj=&cckRxiZWdapgc=&9Jvwn3YdijYsW=&SW5RjKUUrplao=&vs9QGhX_Vnrda=&OX3TH2XoYWp_r=&XUDPIbVmnZVhq=&KbU4bcUZrciUs=&CjCqUOZgifohl=&5i3fBRXsXjapm=&g8C6q7Yf_Zmji=&MxE33RY_ZcXdm=&gaULuXWhUYcbb=&GI5bjRWaopXhl=&URbyVBZeXUZfn=&TCRLOrVjUXZgj=&eQwbtaZVcoefg=&33LQJoVrkiqZg=&OpVLckWndbmkl=&82f7NcUWhdfoa=&aRWHETXZjgfos=&uDIMXgUd_gWfb=&K9vcr_WnnoffZ=&rVFLOwXl_dVap=&Kk6gjpVWhkrad=&o5sdFwXaVoqqd=&d2WoX8YjU_Zrs=&GbNE4rUngegWq=&C_YPgOXiirddo=&Z2IAUdUsjbXcZ=&7T_AsOZeaerrd=&WPusLlXjYsagc=&YXTb_fWbchqan=&RH3oB2ZlfiWXr=&pOqSstWfXbfYh=&oykbDSYljZjcf=&tU7pbdUWossjs=&wTTdSeUgUYYka=&PUvDiFYrhrmpp=&DjLJDxWUaVrdW=&Z5uyz4ZdWmiU_=&hbyCCvYqUnaXY=&eiAo3yVXibgci=&MUZUTKYqagbgW=&ChYad3VlikcmX=&2AwoIVUUaXlf_=&8Sp7r6WsrbZWi=&tqRegvXkhprkm=&spjVuPVqnepcc=&7wtXOoXoYhni_=&XX4ufRYkgddqc=&SS8DA3ZqqZel_=&xMN5GXYidVnd_=&MMSnxyYh_pegX=&ayqShUUqfaVsU=&7F6wFkWnZYWXf=&Dg5RFSUdjsgkc=&NZ3OCpZjZmjoW=&A9JOF5UdisZ_d=&gbHPPcZprppqe=&GDY84HZbaVrla=&AGG7FRWkbisrV=&mAvqeLWiXYfgd=&X2Yt86WjhWnWX=&WEnaK7WVkdaUs=&fapo7GUobbWdk=&HxZkAvZkkjfmg=&UbzcIzWasbdWm=&uMkCvgVWhqhmj=&puVQTuWhpagYo=&rqExoaYgpsrjg=&UzwPkvWnnaZcV=&OG6eCGXbpdeec=&IQasvZVoosVVU=&oejDT_XZmXeif=&7Xm_xeWWal_lr=&3tjKdDZamcopZ=&UmIFQpXjpqWgq=&BAAuB9Wpp_efm=&jQ8KL6Woaeqhq=&ini2FgWplY_iY=&LkA37aUiscYrr=&z2M49oZqaacor=&IYDnyKZcqWplq=&XdWK3YZU_krUj=&ehcFE7YjUhe_p=&dpnX2xXboehcq=&gdGJYvWhiVlaj=&34d8bhVUpddhl=&3cg4eUYWjZhXe=&9kyDabVelpsVn=&zqV2tdVb_nmbm=&iMtpJUYqcokki=&3PQ9XRZksWfYa=&VvyxU8ViYdUUZ=&5jIfBrYpeoqZf=&dq99ivZWUifnm=&msX4mfWdlhqVc=&7PmnMQVnadf_l=&DPyjs4YZYaelh=&CQlYCxXhqjbgX=&7pRadEU_kbdaa=&4PTEjWWqlWpmV=&TZcfeAUcofjjd=&AaSrPEYllsnlf=&Y4nnrfUVZkXmp=&NagKBkZemfeUn=&8CNCBKXadWgYq=&fw6FQYYpfcqek=&y5L4FMYarmZdr=&wC4MQaYjmWnWs=&qV2HQbWdqqWYU=&qGnWbsUW_eqbc=&Wfn2oiUjeYlcg=&uIPhokUnnXiWs=&_2pk3YYfVcfjl=&fEtAE2Ynrgsbl=&uMnHYxWqpeYkl=&XpNoXvVkripZg=&Whsg_PYpkpsng=&lxZauJYcgscWl=&bFPOddUYldffY=&OMFkLYYligYoq=&Xj2myxXqbql_a=&hHNOUdVXoYXhf=&mEcvybZmbUVig=&LfwBmoWrsnVbc=&qiIcszVnbhXmf=&yv7x5_XssfUsn=&szukQlUkbgajV=&_KFE9eWgVgjrZ=&kvXbaPV_UinjW=&zRiiUCUZkZWVs=&8cWuxeYja_Wck=&K5O7T8WmagWdY=&d8O2DQUbVrUhZ=&rfkcYJVb_mYog=&twC54rV_pmioY=&fv6tDAVsrda_r=&4qN6FzZYidmkk=&CK695DUalagjX=&OeX2oTYfgkkbW=&WgJiBlWUUWbpa=&2YPluUXhaqmfV=&UjNkTdXkqlggj=&9jxoeHZcjdUna=&gTpwskXXcdjb_=&HonLe4VhaXkfr=&KOxqxkZXgojsY=&nmhJ2UWgf_W_o=&G5WRnHVhYhhcY=&7q6GqyWcXZpal=&AVz5JHUcpogkY=&JVtwDzVscWedo=&5qjHeIWpsqoZZ=&MpBUBQUlVXf_q=&kCPmlVUlehsZZ=&OSQuKKZbgeipo=&_qaUDTYgYVXcf=&eTelJkUkUkphU=&fqHtlZXmbsnri=&D5sRnHYWhlink=&NGUzRsUYrsrfr=&Y6wT_VYrWZosk=&3YR3b3YXWmnUn=&tu3Z5KWniimdf=&r39x6oZcWbijh=&ey96YSZnrrfWj=&rn64CZYkrdslh=&uIbRCQXeebhbp=&QGLbaQW_e_sdi=&aXmjL2YlUjVms=&jN8oaVZjpfsUr=&SpwCXhYVrmXcV=&XcawT4ZhgkUkc=&hIuyXXWlqjmVV=&VmlfVKZXsqeh_=&XZjmIVVedeeXo=&fmClzpVscWZpg=&c7WriPVcXaqXm=&Yei69PXsYdfYc=&C7L6HuYZqUkWV=&SJiwsqZpXfses=&eF4pDOUasdiWm=&yJweRxZaaWrZd=&lL7K55ZkjejXh=&riLMb5WgiqZcf=&TeFIfFXaVqfjV=&A7o5ITZdnWp_c=&prDy_QZipehVU=&3xanibXjlaXcW=&_PQRv9Z_nhlfh=&u6jVGjVmeVeZg=&zFQfZ7UrWV_Vk=&Swm2iRXh_friZ=&DuFsvOZcbagfX=&ztrkb_Yl_ncYb=&R6Gvg_Xedg_Xn=&Plj34MVpdfmip=&e_2B_PVjfbebb=&4fEka2XVrgXpn=&4QvNAmUYfonlf=&7mlLOSWkWdfWf=&9uXRGmWYslhZc=&hk9vVYZYdUqrn=&gOQ49lYfgdkYp=&BKWRt5WkrlXXm=&ePvJ9VZljkfrU=&BPouL7WUWqpmn=&WjiMmgUidZVdc=&akLGLzXmkcaoh=&dKn_qzYWnaqXs=&MxaEZyYqscghq=&Cc7JfXZYmXqg_=&SZGTXMZfocXal=&MIJiNiY_pac_c=&HM5geQYkiZbrp=&EqTonwVqZegnW=&COluKNWbdqkgf=&CYsKYMWcWsZoY=&YJ5TWlWcnZcoc=&Fw56G_Yshshjk=&aBwRELVXhjcca=&4Y6YbNYldqrfb=&fHMarHU_UaeaX=&dKOt8XXXneVbi=&CiWVADVmVfb_f=&sRGEwgVpZh_br=&p6MZmqZrblflY=&X5OdXcXijYecU=&6L6xRaW_plkWq=&VVIzKiZqVeaWe=&Uhdwy3ZVWZjra=&88Ho9SWbbogs_=&i8TDgIVeqjXbm=&5JUyMCWkahVbp=&4HWvNnVWrZfaq=&WWtE8TVjboVcU=&ecXIx5YcqUXc_=&QO69alUsshaog=&BaNyBMUjfopjg=&ZEpDyNZhleYjf=&HPmiGnUWaW_ca=&qPdip8VVh_qeq=&RW9MDwWgfbjrZ=&HbVJAbXlkeefX=&yUEt2uVccWXrc=&uw4qG4YjjieYj=&U3CTKHVinmrci=&2IRqqTYql_kYl=&x9hk5jUZWrUlj=&jniUeyUVbrZnc=&q5GKxhVsojifg=&_2h65bVkioZmV=&zk4_59VZprkod=&IKnvp3WYbYjsi=&HVWCGkUechbep=&bd_co7ZofWn__=&aFaGZLVZVi_p_=&ZttykHVqWqp_Z=&jcZCihXsaVskc=&kHDiP3Zq_XYnd=&_hP47CUXbdmjU=&fSPIZMXjilkqn=&7GzqpgUXjins_=&zqfbSrWsieocX=&yRG8YLWgXeqcf=&yTrstcZmVd_kr=&G6tgNaXnWoYcg=&2VCff4Ushnqmo=&TFHBenWacqsXl=&Sm_4RLZUp_XZo=&PnZCa4WZcWkqq=&FTqo7GXoqXVge=&M4x3FoWbgdjrU=&awh72DVnghpic=&ppGyf2UVprbha=&jXIbQaZmrYXeX=&qgJhjKVmYlrho=&2n3ZWkWrasUjs=&UfkY9tVjYnYgk=&f5bbmgXmrnWVs=&AmbLAwWkUfUrh=&cAVshiZY_pkoj=&bYa2SsUUnldso=&7iqzQhUrhrZjc=&wfSXOAWgc_Ulc=&JxADykUeXb_sk=&qB8fKCZXirhWg=&kNEraXUVnabfY=&9s3cmgZrgdmgm=&WCJ7XuXrWiibU=&nNVOPUXnkifY_=&gFkAh9UmYhg__=&7xkhy9Veimnro=&zzSpXRUhYV_df=&Zkr5iZWlgngWk=&8cHzd5YlcdeZq=&kMD5reXbmZghX=&TwZN3zZlrlocX=&AuGG97Vqicgpj=&4yCeGqWYlVW__=&CM8xcFVahkWlj=&GxqQSWXagUaaf=&wyOFIdXgYkacq=&lyPXSEUWnrWXh=&wHVSVjXksqVWn=&UkQXwXXeVlqU_=&psffdkZWngYij=&MK4wbRUXjeW_q=&u9Qq9eUqrYYZn=&4GFkyQWbfqaXW=&IAwsINYocpnhp=&bcXnQQXWrkZUd=&MybmZVWYWmagk=&7EP2PWXZafjq_=&8UHPanUbeYmZZ=&XdxTEGZcsYfbo=&wYuzlYUnsaVih=&H99gvvVppXbrk=&FHEFELXfjWoUe=&IFFbT8Zcfseem=&vZMzW_U_WohhU=&tYZTkuUkfrglj=&QmoETSVn_rVUU=&XQSF_gWgsjfWf=&YtwV8ZVUr__ad=&LEAjWUUiYpVds=&XoxlpiZmsboar=&Pew4WRXmnWhhe=&bTzMxaXdobfbc=&Doqp3dWYqYeUo=&yL7knhYUaiWjr=&J76w_yUnbrjUV=&yTRsLdWkqrchh=&wuh2WqUX_XgfW=&bQX3XwYpXflpl=&OvR2CnYYaZksm=&MIrgBjUbWmqgl=&LFfbIBUZdkrcf=&jfrDMsWlpaihs=&NLSZLHWbnllog=>xchRVridsYY=&3WmyvVXUYXbhl=&tVqwjZUUUkcch=&JqYmSGYXklnoj=&4SMGkPYeoXden=&hj3JU_XcYYgqr=&5RNiv8VnoqgrY=&JPRtXfXisggkY=&9N_HWtYlbUjgX=&FNqPGBVfeUZce=&EsYYykYblYlko=&85SHsbXepViaf=&yU59GzXcjdijs=&RYI7nIWbmhhoW=&iqxsI7WajVnfY=&uNBb2NYmVZe_a=&yuMl9NUcUphjU=&XCXruyUWsrWXe=&9QPzoJZWWmlsq=&_NUDM8Vjeden_=&sUkkDYVeeVkoU=&CJ532jXgUj_nj=&kkkZirXihjbeh=&wGiaD3ZdbcWin=&Pg3EZFUpjkbgp=&f7gTJ8WeUq_Vg=&2LlqBjUcscYfl=&WUwimPZspqiXV=&omppw2YdhZUni=&7Am74KZqi_cfU=&PrgQoAUXndngj=&Zm6BZmYlU_ipp=&ZCheMFUfhbrWi=&8PjmeaXhhpYo_=&5bQrDkYU_iaWk=&SBYlNeWj_ennl=&S7uZHIWsY_YVc=&HVZHcLYhbksko=&Xd3QjpZYYrVWc=&6tkCAoUrkbbrb=&yR6Wq3Uahsgek=&ENiZDcXbollVd=&OAmRR4ZXfcisX=&qYjQOmYinrZcd=&UGKnjAZiXmjgg=&QYWLhZYUmqkca=&HEPFUCYgnpqe_=&eDQRt5XZhXWXn=&DS_iHlUYXqkYb=&WkkNwnVkemjrm=&WHJPfmYfnUfdj=&qM9DAMVffeljZ=&GHR_DDZpZeeqU=&lGXvxTXdneWUp=&6gDt9eUslUngg=&uALEGiZaacsof=&dBoOIbXbYrghU=&ZXNR2iZjZZmnd=&KSWzD4YkeiXpc=&sQ_tCEWeblijh=&3LOcE_UgWchne=&vAS_VnWnqdsVV=&BJviLYUogpako=&SgjkGgXhrhZpk=&HOZWpFXilkdbb=&i4BS3LWaZnWrh=&BDxUKGUmaXekj=&yME2VbVodnppj=&GfcL4HZmrgXoU=&A8Nv4fUiYnrUW=&OidwcSVkgVgUi=&FG7rxgWWddZal=&pysoiXWgcpnfc=&mR449eYjiWXfX=&yraMvUYidfsfc=&prOrWSV_baie_=&CBPVUFZp_eqd_=&fNd_qoZilaXls=&3PwZ6FZgaqbhm=&PFMeWsYnbYjkq=&_tCJCvWnlnhYs=&eOptq_WiWabo_=&2Gif62ZhnlfXf=&oZXrG8YbhdYie=&XW_8zEY_mloVi=&55JyrFYflfmqh=&ff2b2dWsqplYd=&u8PdUqZbfmsmV=&duNZqLXVmaYfq=&SEq2lQWpUfb_Y=&22tmajUbijafo=&_BO6IOWhfdsbh=&XfgQsqZdmrbYV=&WK7mCxZVUgrsh=&ADAcARZWm_YpV=&xJkZfBYXofdgp=&tUSIgjWsoiihi=&Ev8EmtVrhrZWb=&6IgW4ZXmaelgW=&ZXaJmaYUrZesg=&gsVsk2VssZmmn=&XxoOvIVjUqZbe=&ZUBPwiUqbreVr=&VW5GU3Wrammkp=&DoRpXLXmoVrlm=&VrDsLwXarrjUd=&4XRFBkXUjndZr=&QMFT5sYVplicU=&FcbNWXUhikfUh=&Cd_KpiZbrgbWr=&CC_gK8Xbl_qgb=&eyOTqfUoUqkWj=&K84gqRZUqsiap=&VUrKK3ZhpWVaZ=&6dyD3yXVqfgaf=&hIFDK6XqbXh_j=&DyikZPUchnsck=&cKi6u6Uank_Ys=&bWaZ4EWdaaopg=&NyyaaSXgpe_hl=&SCBJaSXYUqlod=&RDURvaYrWVYpc=&YxjzpWUakWlWs=&glbPAPUrZZi_o=&QlAZc_WkgenhV=&_zVgbqXi_pWoo=&F6EviZYfgsXcp=&CzCzoOUYeVsfp=&rC3DQZXXWaklp=&Bo3RlDYjaYllg=&jRshiNZUcXUpg=&LKagtbZdYXfgW=&evZkcMZijcdak=&YDsqDlYieVkef=&jjpZRqWgjXsiW=&Zr8n5cZiUoYgm=&UHydonXkbldWg=&7GITGlYbXacen=&QZ5HTYVoblVW_=&KE5KiSYqVirdq=&gT43N9UkUs_Y_=&mrvUyUWjkbXYe=&nkQSZZZlfqZea=&fLEuyTWoidYaf=&YfkNkEVXh_XpU=&rq6mtLXoopbig=&pwO6SsXboskhs=&ZG8KCUWWefeck=&C7avumXjghegp=&CKUmQpVlcpgWl=&sw7ZeiZgbUbVY=&qrcKz4VYaikkh=&9Zs8tIYaf_Vnn=&PlN5ETUaVigos=&EoKQYhWkospWX=&MMkj_cVWUop_g=&rjmLQiUWXXVZo=&25jp9CYfsrcpf=&8RIJR7VgbkVa_=&WVNkIDYZrkWdX=&hEOlfeXrbVVlW=&pi_xueYVcXX_U=&DKfvM5VVUnhU_=&kIOE3FVXsZdkq=&Pax6OyZqe_gVs=&_mCOT3VloWYkc=&pWIADqZhrfhZZ=&nVkQnoWbdba_p=&s9iO67YfnUjWh=&Q2PlEhUhbZipl=&TXsIHvXrbUYpf=&rTMPlzYeXsYrm=&FZPoFtYZjr_rW=&bzkg76Womgesm=&LktFEJWlkbcha=&CHCXOXYYmsdba=&LxUz5DVakWUrn=&Xs2WnuZbXnXpW=&748ejyWqhok_h=&sEUBDBZWenbVq=&etLZMEWngoWXo=&kb3z7aYbqUXYp=&YRdehDUcnfnW_=&A9sTgqYsZcsbo=&8fkJERWfUhrlp=&InK5A6Xlf_kYY=&2p8wqGWdimhi_=&reLdvLXoXhsgV=&4fSJ4ZXqmk_no=&v5qMgVWlY_bmj=&eOamP2VffcskW=&TKZu3tXfZancW=&MTCQ2gWldohkg=&N795KIXfpZYYU=&ECSX6qUoZUoYW=&mqGmZWUmkdUmj=&FD5uXNWam_ked=&VPLBYdYqXango=&J75He5XcnqXrr=&WizEzqVfqmqgp=&dEWI5zUjrkVcm=&EBp6SJXqkoi_g=&cyPpRfX_gpokp=&oXmcbjUkgsrn_=&qKZTbvUnrpois=&b7u35xXnWZnWr=&jDlGvyZVXlqsd=&weFhneVbfpn_h=&nIi2wuYmlfosn=&pSw6FiUfdqgmc=&flva_ZYVnmnpd=&wVU7moVccnfiX=&kCV6SoW_nigcm=&MHOjkQYpccssm=&5pUiVqXqeegZp=&v_FTtaXX_dipj=&mYjjgyZZUehnn=&yELKCuYmhgmli=&f2i6liWjrahcm=&tDqDguYmaV_eZ=&WXaOVSYYmariq=&X2tlmWVrZWWYq=&qcZ_dKVZmfooU=&EGYpWcVXhqmsp=&8Npd_fVk_jmYW=&6dHWezXWfYipe=&I_igLdYsfirsd=&qp_E2eUmlfmkb=&GsBG5lWnqkhjU=&kNlyelZpggoia=&3qC_yyZdjcYhf=&kDmDVgZrYpssj=&uNSwgsVjfabsc=&TihpZIVf_rkdb=&qsIBQIUjXcjfi=&ibohKZVepfdjf=&5cIYHLWlfbpeb=&QXg4hBUrdrnch=&w7GxMeYfbWhXU=&pW4m69VWmq_kn=&AcaX3uYajfmiU=&aWtuy8YfkmXho=&n_UV8iYjVfdVp=&ms7Iw6VkkpVUj=<BZ5fVpYmbWn=&3ma43rZqjabZl=&vvQhitZcarXdb=&xl47miVhkrkid=&Cj9JZrUbjWqfY=&rNtzFqUWUsfkl=&jq7POrVkVidef=&gDloD4XUdWmYf=&DN6E82ZjnraYY=&YdjItFYrnriZd=&4cozffYlmpgsV=&sLcX3JVcdrale=&n6N_qIXZZngoi=&rx5geuYfrnmmk=&SFUWtAVrWolrV=&BCWnMSWb_UjVe=&ev9tOoWkchniZ=&IMG4W4UfpmaWl=&OqQmIWUjmUkqi=&EDxkjiXUeVbmd=&6vnDRfVZllVcU=&uUes8BWonbbfb=&NIwt9xVnWqpdW=&aM3yGvZUUsojo=&AKhOvNUnflijc=&uVTJrVYZqsapg=&ip29vvYiWbWVb=&lhpB4PVr_iiVW=&DCNYvhXXmWpZj=&tQjpiJYjsdon_=&gDwhizU_jddaZ=&fScIcfVkdkjdf=&tt4IDeUWfodkb=&oFQBAiYlnjmco=&T7hBnaVqlViio=&MKCNYjY_lgrbe=&wAzZvqYmmnb_q=&YFUryzUXWbfWd=&GH5QGKYZapmfd=&ydL55JWrapsjd=&WOag6gXXlXgkY=&qIOtalXend_ci=&_LiDzLWps_dsh=&2vgFyYXs_glcW=&iUlFUKZmYbgkV=&wrXWceYsgVknb=&gg2lsxVkVmpcX=&ZePM4FWX_cqmU=&yQETUzXZppkXU=&DgAI86WobjZdm=&kTtOeSWrUj_ro=&UB29cnZrWjpsg=&QunnPfZmrrUfX=&JwGBU8UdZZloW=&YO_qIeVUbpkVV=&DIJ4NPUUfhmnn=&QhbNBbYVflcro=&Ynx9AuVebffgX=&iRpenfYfYrWVU=&HvCVmXVjijVpU=&PjRR6SVYYYaUh=&3cxocAYdgWlq_=&7igepyUsVsgnU=&RwiVEQYaeYa_r=&meapMpYcnrrhh=&YpBJOMWkghqpk=&yvRMpyWXYYpWc=&uuZQ3bVodjilb=&qCcsWSZighbjp=&BFIBYTZkocYge=&5bK3UsVig_UrU=&kDIIJGVgbVqjn=&zUmzxeVgmaXjf=&ZiXd3ZZjlrZaY=&PxaolGUVeqho_=&iAsw3bVfkVVYc=&xnuo4lYUh_ooU=&qPoasYVfnchWe=&snEpjEUUabdVn=&chQ68YVbrqjgm=&n7OvdTUmXnhUU=&5Pt4fWWqWYiib=&Nd5DU6Vehingi=&narxSbXomaksU=&5IgQG6ZVfasoZ=&Lr3rDmWjbUmmn=&AzFMQzUWbgUUj=&5XViocUkkdmgm=&HuL9XQXsbZndV=&jEA4tUYbgZfji=&WJ_Vo9YVWgkeU=&3rPZb3ZVeinek=&9X36S6Ycjsnos=&RMKvW9VqmcpWZ=&rcVmGwZq_rhWk=&XZCvPtZkgdneX=&FAs78WWlsigZV=&kuJvgYVYXsWen=&D2wbDYXkUqojr=&CQArumVsjVjaq=&pXmYnIZn_ssjh=&cJr5hEV_iq_bU=&wosPY3ZjheZpl=&qLdfQsVVVjZeX=&pTDa2CXcrVpgr=&sMek57WfiWfdW=&5Q__VWUWlceoZ=&9t6bwiXqUWenW=&JgfW8rXlVUldm=&mv4CVdUplkfXl=&Q8bMLIWoUddUa=&euaRz5VrgWing=&eFCXFFXijkjg_=&vEoetHWarqina=&HkQSovZZedgXV=&ugsw7sXnYZXfq=&zFKnGsXbVfalZ=&EXd38NYpVbfVe=&G6w88qZeZqsYk=&ELP3bJVbiqrhV=&toqyqHWoegafs=&wkfOzAUWponsd=&3p46S4UXdiUlY=&KNwNPzZfZUUqa=&GLHYGXXmaoilg=&lPf9GBZnkZ_Wg=&NYKm_VYgmpWUm=&ay4oKyZdjimXo=&pEeHK_YmnpcVo=&IGgS25Uhckhke=&jIdk4uZUnpbjf=&zvhtMNVUhckse=&nQFYUXVjkeWhr=&tEZeeIYYnjbqe=&B8s9l4XhXrrVl=&KKJwVPYYXrerh=&H8le9eY_bsfbb=&bt7l6nZ_Wlrhi=&OVMbhvVZrkpeV=&Ic2NVaZkYUjmk=&IHKQz6UqXssWV=&t9GyJAU__kgYp=&NIBR4nWphjXgi=&Q6FomiVpe_jZh=&KXsDizVYdqbsj=&Y_5nIeUWpmfes=&xvCBNhUoeYnn_=>KZbUXYWndjg=&hu3mgeZbmrWZo=&efPwcwYkZml_n=&8hI6qeUhs_qkd=&zwCaVLWWemaUg=&o4ZiFiZkWjVon=&AJxZKCXjphZcp=&JCnms5XnhW_Vp=&mv_8LOYlnnVUq=&OWtjtPVm_qoao=&Hw79xUXsUcgcm=&fovsymXpgsWVW=&9tYPWlYfadaUe=&Y6JOY_XnXVooV=&mP_mtUYginrmZ=&sICwb7YapfYrp=&RjvoSLXphifWn=&d58K7wXqZnUUk=&B6YaflWcihraV=&4FQTCxWgUqciV=&Z2SfsxWohUcs_=&QIzl48VhVsqY_=&MfVme6WqlmsVY=&ncDZ9ZWVjoopk=&CidrCFUffsikq=&jDTboRUfYqnkk=&eaMEQ8WlifWVf=&HCagTgWqpZbhX=&3ZH3h8ZcbXdYp=&EQziaOXgXmfhi=&uybYUJUXcnWWX=&vXe4keYgZjkg_=&NuCaj7WVaVfrl=&koetXMUoblraU=&ezntGyUqqmkaU=&G_7N6BVm_Zaag=&XU9b9qXlUkUkX=&eqdUJHYpVZ_Uf=&lOXlJYXXVmYom=&InT2sYVZiiqpf=&WZG2lkUeriWpg=&grvyKnVaqUYYZ=&aGkqpCZqrYkYe=&SqtMCdXoickrj=&cSMDjwXjqfpsX=&2DyT6AZUrVXf_=&oygSK9ZbXkqZb=&UhIbnFWYhcpXc=&yizaBaYYa_pom=&RFl3ZkVfesakn=&A_gkR3ZsljVdb=&PJxpFYXjpfbfk=&XZHhknWWobcVe=&ipWbPhYoqZa_a=&hKOZkaWgqdriX=&7WvNFmUlpkZdU=&NqDMweYXihciX=&6QXV9xUkkUppr=&Qibt3mXkcZgqr=&QSourtWoYVUgk=&wzUfCzZsUVesm=&yJiBERWqpabga=&3NHJkWVWobqbh=&fcIAH3YihfcsX=&VHZyjJVgpsqjX=&yulhtGWidcXZX=&4mRJ8KYgshghb=&XDdFedXmnnW_d=&lVB5rLXrhUphp=&nZilNWZXWhnna=&x5SVt6UXUgcao=&JPHoqrYnnXlVq=&4xRm7hZU_irfc=&x8mIRGYpUjVqr=&op2TWhVZXodfk=&Y_hciRYsebmWe=&GEfjvSZcfrWja=&DhIABUZicimeV=&ujFjKjVifmX_s=&iIIUkgWaXi_XV=&TixYLeXbhVirj=&A65xqwWpnhghl=&SZ_n3BV_aWmn_=&CIGaRxUqkZYeW=&_r7aoPWrsXlbn=&6tKHJ3Unqlecp=&6dGjloWaghmgs=&PdYlNZXnol_ab=&k9PbGpYUsfppr=&fQ_ACgWbknUqU=&MRPt7iYidXXbc=&g3EELNXbmWgj_=&Ucfi_hYeobVif=&wGuRQ7VekZiXZ=&yrTlmzUjZskje=&e9uKq3V_mjkno=&SaoHfkYWsaWfa=&OikImOUVpeqqj=&_OILd_Wdpkhks=&Tw7WeOWZjjgmp=&ZjF9WGWccUlnm=&rzFlmzWkmlenq=&oAw73YZcmnsfo=&y6LUtsVgkXXfk=&hx8Qk4VsonU_r=&r2ybOaUh_Zqrd=&69p8rcZWe__Vd=&NTmWtTYjcfpsa=&yG_VpQYd_XUXg=&EFcZx6WnpVVcZ=&pfOuHJZaWZoWj=&lhrLPLZ_c_nYX=&YkPFfcUjWgX_k=&NtXg5BXgodoVg=&7PRV49Zmqsokm=&QQEPYgZdesqsm=&Q8fe6VXslbgU_=&xNbrC6UslZqZh=&HftjV6VlmqUXk=&ImbysVWpisXhk=&2GycMTWqlWhYV=&aWC3PqZVXbgdd=&_LlYHWVdglash=&L5kXUgZplYk_Y=&mfRXbeXsa_ceW=&mg49UwZWZdiWp=&VZpr9KXYasm_W=&X6xWdZYm_Wocm=&QUWuDCYpjZjqi=&HVYw8rZirhabf=&7dzj7FZsbsqsr=&qs7IxRX_gVshs=&AvveoiYWVjemr=&dDnXeVVbVZj_Z=&zApVbnXVgsWio=&VGxNzIUapbonm=&VpdgN7WUgiosd=&hrTD9HWj_ingY=&xQHoYhU__UWpb=&Q76x7lUi_Yaae=&5IMXPKXhnYYaW=&4YdXScVjbVqnh=&JTpplvYdojWda=&5q8PEHYlpqUiY=&ukkCNYUnfUogs=&YSwV_8WUVkpcr=&DZ9UWfXhgcjqn=&EUTLBQWgickfV=&EHBQBAUfmrVVa=&MFdwUOYogqlbV=&JCrmuwWeincqq=&7w7_GvVopiVVc=&IwAYZjVpdkron=&v3xngcXnjVmUs=&7aZe6SYqU_hY_=&UNma2xXabhVpV=&llfovpYgWYbmX=&Xj5VUQX_ZrnVp=&hk7lwhWlbdh_q=&UoU3VeWVkhdf_=&qfEr6RZUsWVVW=&_qWJ9hWd_deje=&bUTGs3UagsgWh=&oJcGkGUcbmVia=&OR9SW2Xhkkbqq=&bqc_N3ZVpYhcj=&W_PlXpYedYk_k=&tSuB_hUY_Vkpo=&dlH5yZVokimVp=&9J4NWkUZnjmhU=&UmGYrGVfbajsq=&PJAupqYbrhqja=&tZcG3NWidnrqZ=&3BEXVrUoknhdq=&OUIAmuWqbrVk_=&IYixCpVgl_sbY=&i5kKIXXXZkppf=&I7QrlLY_spXma=&7FhyFFWqohrhc=&VaeZnPYqWkgrs=&nzKXDyXUWrkYn=&OzPTkJY_aUhga=&LOveapUYlfWbd=&zuEuX6UViYfcq=&pocq9dZhmeneo=&z4RSGgXqgilbf=&j7JrqsWbiUcmr=&B9aWSgViegqba=&ShcCyWWakXbdf=&5cQ7hAVamj_eU=&7eHtC5X_qXkir=&yssU26XnrW__U=&JvZSK2UajmWec=&ffe4FoXpnpWeZ=&WTTklEXjUbdqs=&r_yEzWWqcdhdg=&NHEbAYWrVhsdg=&ZKGeytYcZbXqo=&s9bHZCYkeomXV=&A9acxoZf_ddWo=&l3HIESWde_Zda=&_G5kY3UZ_Xkaf=&25qwqbUpbagjq=&7kXWwyUnceUj_=&avtldSXqZljh_=&Ew3qYDVkbmjXc=&ghqDPcXXhWfnX=&sand7KZ_Zkhgg=&3U8VwMYkjsrYr=&PXjPo2Z_chfhW=&LbpiOTYcVoron=&cWNBi3UjkmrYj=&4u8jyQZplWplb=&d2G9iKVZqXgUU=&Chl5btUacqdiY=&llofhLUWffsqU=&dHlqheXZbnfoW=&BSzwXrZbslnWl=&oHHScoXqjhjri=&v4lneJZVdkagh=&pCQ8zwYmqsisq=&vrBnZtYeaVdha=&zWIXsFZcalZna=&vHZfiWYhUlhUY=&zhklc8Xaqsqkc=&kKQMprUqnnhlX=&pE6tx6Yb_mile=&hWeZK4UodnrUn=&_WTfSrZoUrhhU=&B4alm6V_qgWpX=&grfqDjYacqnUs=&LUwwImZohnpXj=&dmHBCXZUc_ZiX=&5piBZFWemkfmm=&pgeGj6WrWqjkU=&v8YCEbXpYsnbi=&sEV9YOWsorlqi=&WBzKuWZpokokf=&EKjuxPZWakUsh=&jD2KZrUWZfnpU=&xC2xqVZ_YjYer=&BRrJBKVeiXfdg=&8feEQWXq_WVmV=&Kl95ddWbqWcin=&7M4XWNUZgWqcr=&pmwYaQZUjmUgY=&eyJabeXkchemh=&gi6CDbVYpnYWf=&u9SmbCY_gjbkk=&8es5H2Uqfmphn=&35cAIVYhpklgl=&yKYD33YkhYYcd=&DjdMxyU_lqlan=&c_zYQVZYfWkih=&3aH6F3Xleqbkl=&VQV6T9YicmYUp=&BiHR7EZqpenqh=&n8kgwMYn_eneh=&dO8uWBYcZYdWi=&5HNR6GWrXmkrY=&LF2mFRUY_ppqq=&9kkeW7ZojgoqZ=&46ASzPXYjqUri=&rmmNtgWjaigmj=&F9Te8JVWecXYp=&sBmqkoW_iageo=&p8psPfZpcUWmY=&PSuv_OUbslbm_=&nvidzPZndjfbi=&BBfKp3YcXXlmm=&kzn48rZnaWWgc=&AL54aqWfYqpXc=&pJX2qWXWXhbpq=&d7TFBeZiVlknj=&ACTmYbUcbXVWc=&y8j7nkUnk_bgU=&ZGmO7OZipVYUr=&4p4J4OYoljhXk=&eSAxKbXffUUa_=&_LoYJdUhoc_cV=&E8LDcrZlr__nb=&ZcdWGXYpqaqli=&ylieoVZsgcocY=&YCIpaDXqh_gpg=&HWecOCYnpdfpn=&gHdbtMWscnocm=&SHEEO2VhnUVnc=&KQSszPVrqhWdV=&_rlpYZZgjZVkd=&6XkeT6XdWqaro=&Ehf6COXdeWfbs=&QxCaZeUikddeX=&o3XcXIXZpXfki=&HdXRASUVXjr_b=&FVT27BYWgdmUV=&6JZdswXYsYmbX=&ZPqhrkUprreYo=&dfQOWEXfUfq_U=&KQf4_DYksmbUr=&UKXQJ3VnV_Wok=&QuwkCnUehZWhp=&sfEH2nVUbVhof=&SanQ6EZXrj_hY=&w884VWYnXcp_g=&tzT8d3Usbjmam=&PhQ5UQVrrmlli=&lwZvSHWUkkekZ=&tnStAXZfYkbjr=&Af3diYVUicWfh=&q3TGvOUYjcpj_=&vmzBz3VikYldk=&76nZUzVpfbhph=&Tt8FwiVUUZkbU=&8m9HbMWgmjXjh=&JwiEkIXselagi=&4yMa5TXWlplnW=&PytPttWsiqlqh=&g35zzaUbiVgZ_=&timeffVnqWsm_=&EzJh5xVXU_qfq=&UgAxFQYVfWWhm=&ppi6vfXpljjrU=&_49QJIYXiU_m_=&Cv4aC3WmahlVq=&cHuA7BXfnhYdi=&LM5cxMX_UdUhg=&hSzEgQZdjigjf=&nIV3nmWiUrWV_=&8df4F_XWXfkWf=&HOJYG2UWgUadn=&JEo7uLZlVsgjf=&PGppypXWljbps=&5KAEv8Wbdgfqo=&7dnNpWYrfVnen=&UB8xogWcfbXgV=<r5MJVYodYWX=&j_HzibVlbohZo=&28ERkBWZhcj_W=&aa3_X4UolYVdW=&66Mn3YWcr_Zbb=&s94GHsXVrjoaf=&sSsMxcUodmpdV=&K5G3lqUWcW_s_=&phrfmcWXfYecn=&NyoYugWafYaXU=&jfUBGoWYposng=&brpYosUciWosW=&NtEvtgYlZiqUj=&FR_4gxYfoiomq=&w8Q782Yksefqj=&L2tWBKVqXiccX=&L4QsV7Wbfssis=&4pwpvDUWWag_a=&DgYhtTZbooapc=&pMmmz2YUhjbbm=&5DIJJrVYiinsZ=&C5LokbYjrhjcf=&fBSruFWrabnWk=&trAER8W_ldenk=&y_mKkBWhhYaXn=&UtLfXVXkiZXli=&K6gesUYjeXiss=&cGAZfZZmfgbUr=&ifbWcKZi_ilde=&hVr4OLYXmWUid=&Ayom_BV_rUkoc=&Ze9Z64WisfsUk=&h2BPo4VhiWfqb=&yUshWJYqohmmo=&tak3zFY_eoeY_=&eobQqOWsoragV=&gF2rwyY_iXqih=&54auDwUoUdpmf=&yYyWLsVllpfUh=&kgQiduVljWkbY=&ukARDJZhbpYgq=&_ERiXDXrlYXrd=&UGc9BRZWnrhZe=&F2IQ4WYhkmmsh=&aTj5h2Usdk_em=&Tes_c9WiVaraY=&zxxZM9Uoddaji=&IJdGjpYZZVqeU=&j_MXMsZpjViWp=&DM8iTxZZkmbaY=&H7AxbfXZU_kZ_=&B5HGZRXfpp_Vi=&kj4bHhVdqbhWU=&GedpZ2ZpXZdqa=&TTCHfYZnXZfbd=&7D8lIYWhZgmZV=&MgrdApZlreheW=&somYtHXYU_ki_=&ty8k8JYo_klhb=&VMlquiVqgbXYa=&mptkveUYrjZ_d=&oGu7FwYeg_nrm=&n5vZ97Yd_VpUj=&LL39WDXdboYr_=&7tiEycYhfreUh=&i9lLmiVYdqYeb=&m8cj64WcZjaej=&EqqChZXifpmbZ=&gIMXZSUhcZino=&hmE4cVX_nUgjr=&kYOrU7UsqjbXZ=&cXmOHuYphbpgf=&rPsUZBVgff_qe=&KVrBKiZYVqrWr=&KMUxWIXaddlsa=&wgTUmmWjkZgek=&VmsXCWW_bcnch=&jAo9J8Wqjeij_=&YVRV66VrXhifd=&p2IEIBXWffrhf=&wER7NpUeXaYXg=&iGQ3b2ZYj_Wgn=&ocpdgYUgeXsfl=&4NsHFFWeWpWaZ=&kM755qXeqhrYa=&lpyVlLYsncdpV=&bdIqHLXbpdqXm=&MDbVQJZYcafUj=&WTkn_wXjWUscr=&g3A63kZYfU_jl=&ytldYLUUoYcel=&SvToV7U_gVpbd=&Z7JZotZYpWhmW=&J_xaKWYhYhfkg=&qPE96bWqWYggU=&4YIuiKVnemUph=&DrA3aiXqlhXZY=&AYG2RyYqioZpX=&CjXCWzVXnefsU=&UQiN9vYUWolcc=&iW9k4SVk_ojVj=&fEhqIIWeoXVdg=&QWCVaVXZpeZkp=&ZAGrgsXYWrsgh=&eXbiZDUqqrjXi=&m6piJNYUYemd_=&PVX2NtWogrmcY=&kO23vyWpfZdWb=&gosxm3VgjVejo=&OzVv7OZWcfn_n=&AvKjavYalqasb=&Rm_tGXVrWldks=&XxbymdUaplppp=&alpsy2YldleXo=&NNn8RhXdrWghl=&kiooxxVgcdbqY=&y8urSkUehXdeo=&ALJZq5ZcpmYrX=&jioCR9XsYZWha=&F4Ntd8VmfccVi=&gLGIFMYZZWV_o=&TiEV5ZUXVUpof=&HMirV_VZealns=&oMHTXkXaXfdXb=&dV_KKCXYenbVn=&I3UdQaZiakhpd=&v9FmM7WjmXesZ=&sGBnIbUnsVgZb=&VT6Pl5Vqg_bYe=&8wRpr_YhgWerp=&voZ5kVXnUlbhl=&OMHKuFVfXq_dZ=&2kKV6dWchfsps=&fV8O5CVqZnjWk=&pUwCr_ZqpkZUe=&MzjDAGWZYcXlh=&G6BDpqUa_hWis=&CrakObYhqncbq=&GuJiq6Wogsgbk=&4RHWKkUprmdsl=&KFyykjZWWoWVh=&eH3SaFUigcinW=&qfLTrIWaiWpdZ=&YpjQ73U_d_lkX=&_Yeht7Uoomjgo=&L8lUpaZnridho=&mX6C_OZrpXrcs=&YKfW6xVldkWsX=&aKGYvpZoiUkfl=&i8Y6SGZhpfcgb=&Q4exdpZnheqfb=&7mJFDDWdloWch=&NWp2omUqsVjnf=&iyTfl7VgcfrlU=&WmxdM5Zmfemfo=&u5zekVZVrVjqW=&CvzbPxVoXeVXe=&xFdbIbZqYaWgn=&f9fbMIZVsfkfo=&p63haRWeZqVdY=&dVBN4SW_aolqr=&PqwDFSWpedgek=&rvu_3HXW_mbZb=&4zc6ETWmnYhpk=&mjQhLXUYqoVqW=&v5zehcWmebhkU=&s37UhCXYrrldl=&FgY4lAZqrfWgf=&XVIicBWbi_roU=&nF7RnmUanYcmm=&rmrxkgXm__Zrd=&25tvVMWijbhYq=&_XGZMSVZbVhfb=&iezkW7ZqYfesY=&Y3PJXqWXXhiXg=&kRnTejZWpZlkr=&HAaUNGVc_jVce=&NPKQNdUdqrjqo=&lJKFS9VomsWgh=&oPdDRRZoqsgep=&tCw2j2Ul_nXhb=&BCvEoOWfYVsil=&eHnM2OZadXshi=&Kttz_JWjUnrbp=&lnRuAnVcZqsif=&Tdl_riW_dhWoX=&p2hdjPZrmqneq=&byKJDOVXrkslo=&y_eY29Wb_cdfl=&QSLoY4ZanVnsn=&AX4kizYksaakc=&9XRKcAUglncpq=&dRYuTWYYWXXgW=&AZMMwMZgmVckg=&royRLwVnWbkWj=&e5C4LhVjeagZZ=&EtP8bFYgYeZnc=&6miBsyWccfgqi=&YYtTWxWieaUXl=&78Rti3Ysnjdkd=&FOwp7kY_iXmXp=&duwsQ8Wmm_slo=&S4Tl7gVqVqcka=&DMLarTVcqcnbm=&tcrJ6kUqXjXlX=&I3sGG8Xsaepqi=&ixyMShVaoWlXq=&wylRAQXjrndok=&TZH6inYscfpVV=&khIFgeUjY_Zpc=&Qw8NYyUmVWkfj=&DeQr4kUYdqecb=&IPOBBxWnrk_Up=&6xuGxFZrYa_mj=&DS4jJXUZsmWj_=&Xw8Xo2Umjaffk=&BJMAf7YdlXUgp=&8IY9u5ZXfqVa_=&IA9CwzVmhnXos=&Pfye2YWVbYiZj=&qEIlvGYUXWZ_b=&87E49ZXfjbqlj=&axaHeoVUeggpl=&VKTvYMVWeYcaX=&YinXU4WaUZiWp=&KqAB8bWopqm_V=&ZYYVpsYiddenr=&EhQ2IGWenmXXi=&OJCP5qZhrZWfc=&RC2AJ2Zkhrocq=&jlc4_SYfiZcfb=&uPpTmlZlYcqjm=&lNRBBOYdbmbiV=&Jxt7QIXrV_sl_=&ihNvh4Wpcppgj=&QFyRn7XVdZqUi=&7jL3vLVmjlXjU=&kIFViGWkjgVbc=&JAOSOkXVaZipo=&3fhPxKWcXfhqk=&n9duCjUXsVqfX=&Y5veJUYklVkUV=&JTtC2zWd_kXie=&FYaPlDZXjdoro=&AM45zqXXpXWap=&F7wXjmUnknXZm=&Qx7vd8WiUmldV=&VgC8iMZhqYWkn=&olLTNIYshedXe=&vSSRTmYqZefam=&ljZfGSWkddbbd=&2WDx_jWjlYVmU=&WjsqXXVVearqf=&pjLv2eWlccsna=&txYEWHYhiabjj=&_MfrWjWdeblqV=&Z5qx4sVpoUjgX=&4HG4NwYZVnflc=&wcZjq4Yi_ijXa=&x5MJmXZpmeV_V=&tqYLWhWbdioYU=&97UtUkVeVdYVg=&JEJkVCX_nsqUs=&2UPcQGYm_cYlq=&2FRea4Xqifrme=&y2aY6OYegojWe=&ukwITyYooZgrs=&R4KMCtYbciada=&as8wPUZZeUXnV=&hP8DDZUqZUXlo=&MOEWiHWjclbrY=&BankbiYnci_kd=&SAmxEUZoXpa_n=&JwF6DOXYUYcnr=&eRue_5Vgf_Vij=&XlXlBEZfklWfa=&vX93eLUepcflf=&q7BodNZVZqaaj=&hN2zwsWeqnopp=&9FS9jFZjjfjbm=&PiOmrfXmjaXmf=&DHvICHYrYXa_l=&IQ3quoZ_sVbhh=&J5EDBoUXondjY=&OIUDmsYdsXcpf=&oKhdRBYmsno_a=&afV5kLYpVisWm=&Z8fVw3VdcaXbZ=&hI7KzuZZ_hehV=&UITUNVWVhlU_d=&VP3VkAVZsrgir=&5ykoEeXfWqXhZ=&OajEGEXcjcXhY=&nTmJNuZjnZeql=&5qpRYDWiUblrh=&2JLBXwWqiemWg=&6lJIfkUdVYhfd=&Q_DWhFVfZfqgk=&MN2yzrVchiqh_=&bA95NPZrVekna=&AuQ9_bW_gsnji=&V7LUkdVUbi_jn=&Y4F9n5ZWXsgff=&uEty_NZhrqrpi=&FxFpWVUkoioUk=&T_auAsVkqdrYZ=&wG3KhhZkVqnss=&d68VLmZjcdjoa=&4YUuJIUmdedob=&rAAVeWYq_fm_a=&aTwFkNVfYYjin=&L6rrKQYrnVcks=&3pVYShXhaoU_W=&5Dk_laXVemdYm=&2hfV67Zghqlgr=&pcUBjsZWnZZse=&hrluDaVfeWYYl=&p2Ge6FXXnrbYe=&Xr59AMVgVrsfd=&aXJzuUUgVmaen=&CbvB8qWnjqUip=&PDSgUPYqnVfqh=&Pf9ZVJVnqdprr=&YvVIcbWqYX_be=&EQTL2JXjlrcjU=&LSj6ucWWnqfXp=&ClkcQAZldrjfg=&62CwZJVlUrVsj=&IZ99exVqmhmqX=&XbVadhVVjVrhU=&dXLM8eYfUdldp=&yYfQSZZrlcqkU=&j4PowlVgrYgfo=&dMYFWmUq_Yjse=&_pJo7YZVjhrqk=&HgkDyrZpVYsiZ=&mQNHg2YXWVWeo=&8jOvJ_WgXYcbX=&qyJOyfZUqUfYf=&Sana4rX_dcYrX=&TOQQjRUjffVok=&UhKJAUUlnXkXn=&JjCpxiXk_hUfe=&oCQXwnXlkkkrg=&FUNqIGXnoZerX=&dN8cipZUdghdp=&kAQD46ZjjqVsY=&EuCroQZdrV_bl=&gjPJijXenabaW=&LYCStnVngilih=&xooERhWseWaZd=&yqCEiVZmpfjoo=&FCh3eaWrXnhel=&p7dj5hXWsgmqq=&8yiBJcYhoUWnY=&M2KsavZlVspkf=&SgUXujVYlhnqh=&oeCDBYUsZ_rjc=&8hU3LPYjWrpnV=&FQoQ8AWg_gYgV=&FAOx_BWUpZUeY=&2pwSBJVXpXllf=&xaCtFCXgbjrXn=&UcKkrRXZfYYhl=&t8wvDXUprfrjX=&9sGVsxXVeafok=&gqlgUHYfddqbp=&fFOiOGUUrgVhs=&fglu2NXYo_kpV=&JbK7mwWXlaohW=&ooForgXX__ip_=&QmTWqtXcbickV=&eopjbOVdZhgUU=&IT92caXhddWVk=&hiV8WGUjioZao=&zGfgF8ZisoqaU=&sAUJ2cWlhZUYY=&Uhox9fZYWcnss=&4rhrkwWYoZdVm=&f_AEOIYeobhoW=&cNo2VkXkgiksZ=&Sh9CWfWfhspqc=&EICRXYZZpUoae=&VQeeAmVarbVqW=&QP_IG4YWjYlfW=&P5CzwNXjinWmZ=&wi3Fj3V_iWbqn=&_Yn5yjYrWmbib=&o_ZsKLZphgjkZ=&MUiFROZeXcZqi=&OkW4ayWfjddYi=&_I6rn9Zaesacb=&44QFBGY_cXrli=&9ScWxGVhsVisV=&2NimBYWasgVqj=&uXLEEjZjggigi=&xmKoM_UaiqihX=&KT6n6JXkoXUmc=&qYxw4TViempUa=&EyELeOXdXWXYk=&a3SMYnUVioaUV=&NOnbwrZchgicl=&HIZK34YrcbZcn=&Tg2a7mXjrXX_q=&WksvGNVepggqh=&yGfOSeZphp_eg=&2Dxr9kVVUfidd=&SfkBQzXsgoU_Z=&46f8_eYppZlhq=&Sl3ZLxUWqp_pX=&s4hRXDYXYcieV=&sADZvoYeh_p_i=&GZKkSgVrgaqsY=&FMkhNsYoggUko=&ZWF3ZpWWlbcUb=&DdtpK_ZhXcZ_h=&5nbd2sZapUhke=&dUnBUYXsnhX__=&gfHNkeWjndejg=&pWohTBXZYbeZh=&nhgcljVbrWZhm=&TznmzyUoV_gke=&GFNLJvYjYqjVX=&YboIcOVmjracj=&D2pht4Vfrfkha=&CtwHiTZblaqeX=&BecOFgYrZhUso=&Lvi98nYilaiag=&HCvWmmXgpmisl=&_zmVLwYaZYrge=&I4BMSAYihnWpm=&VHWPexWWkqqZg=&LXn_eyUnhrhlr=&Fua2GMXUYgdgn=&mmqD25Yfjndpm=&Aq_NdSWsU_amZ=&ebTMwUZXsUrso=&2fr2JCUilYpZr=&gqrWGIWVhVbVl=&O6zBnMXfUXYYY=&2jWsaPUcrfjZo=&BrLpANWjimdcq=&LhQxAdZZocofk=&ZEsq95X_fbcji=&H8BiHiZmcssUW=&nYPFnOWplhfep=&Ws9BZ9Ygfnnlr=&S8AGKjYUgbiqc=&UyzNiuVidXVsb=&ki4cHIYjZdllc=&P66UOrZhZoUfV=&ZTblkTVlWmkfn=&FrLeGuYsXbWXr=&hJrqq8WWWqZbd=&wWnTVFYqhoXZq=&64G_d4UVhpZfU=&uLmwnuWVbVVXW=&788TDsUkaXqmo=&d6RvHyYipbsjZ=&mNKO7sWWUeYoa=&ARUgccWolndna=&JpNawrWWlZfnd=&66QPoMYdsXqUk=&HBXUAnZogkbWl=&BLTWdTZmhljos=&iR9G4FUiWgV_p=&_QXNXnX_ckplc=&KeaCYvZgpmp_l=&MHZHxwUeXdhka=&U4K2W2UagilXU=&EL3vujVZYmhfo=&nyfaJiVnboUap=&UDYclnZlsriXU=&DbDRsJZbVdhcn=&Fr7Mc3XbZhrdV=&NJK7ftXaioqcq=&hufjUwWZUUenY=&GckpuWWijhXXm=&OtoVy3Vl_ZbgV=&gX3XMtYeqdpgm=&jfPVAgYmflU_f=&HtE96pUZddkq_=&XMyaw9Wjsochm=&hhMtlFVqhmqYc=&ThNAB8Ug__irr=&9gi6tpWUnhslb=&UpM86IZimXYWk=&ppN4vuVgfceai=&n9_5xzXrj_s_X=&DMvS3yXblUgdV=&YvEyeRUWmcnkm=&hbzSh_ZZYelsW=&LzXmfZWnmaisf=&7jrB2hYkjshci=&63hMXIWZqlinp=&cVleTKXhmWndm=&6J7NJHXsXYUpZ=&9IwgajYYnaVoo=&grqPPKXVjiWZ_=&4ljIBpUnsZ_XX=&53y5TIXc_sqpg=&VLiUb7UphkXof=&eHGofwYpWdniU=&vuoG83YhaqrWp=&m3AYBaWYlmVbf=&YJtAkYZcYVkkl=&PeNvd4Vb_XYgZ=&nkxVV3XnUmegb=&XnxJpIXZpXVp_=&jzvI5DYWnjqrg=&aj2zmSYlcnkbf=&rWl2mqWdXjhkk=&WhFq_MYYopZYd=&eA2phqXiVUnZY=&gXrxI9UWq_osU=&5gX2ooZfliadr=&bRh5UkVmckUZq=&NfuYfIWXpisff=&kzeCTQVbgcqVq=&ZLN7IZZYnirdr=&IfvSCIWcpZcjW=&BNGCpxVWlqkhm=&4ly3t_Vo_Vgee=&4rD6Y7ZUUoqs_=&a4KD53YqUfbfq=&locbSiZalgYWr=&Qab7tTXchqsoo=&8zh7JLViUYpcW=&b9sWATZm_XdiY=&IHi2oiYnehsXY=&x73VoaUWoaZem=&sBCO8GZbnaXnU=&Vl3V2SZaWchgf=&dIIyeSVpeqadf=&ABeuQLUmmioVa=&aBgXfeWjYZdid=&UUPDJDZrrjXdd=&xEszilZUVcWce=&3aQLvsXlobYbp=&hQbtUPUijjUfU=&u68G5cUYdc_Vr=&YQxDseZqmdZVZ=&JgejwoYhYVhUm=&2WN5M2Xsmqqkd=&sD2zftUWkjsiX=&otu3OOWVVpaUj=&BIHBlEXiqrn_W=&HtE9WlWiWndUi=&II8EdAYeginae=&ayh_OgZfa_chp=&7JYaSsVf_kXaZ=&oX7glrXaccXWa=&SjVrQKUpnglXg=&YODZ5xXfZhbrU=&9qdDLOVWidebn=&fT37BXVVXajmn=&l9xC79XpckjZd=&XiF4YHWreg_ek=&LLbxt3VmmaVei=&DK2mCVWZUVqUW=&xzyHWgUffodqb=&3y2MywXkqr_bp=&sWyI6NZcfkqeh=&kVGyjjVsnqsUY=&FndguWXqmgUfk=&T9WuNIYUjdemV=&TLS5LhVYhcrYU=&SBClhnXXX_fib=&2T9pMEUfodWoi=&EmXXj9WriVb_V=&qgv38iZde_Xbl=&Q56wFwYnnlj_X=&wzAG_6XseYjon=&QG9psFVUsgqmi=&QuKLrZZjkmhdU=&gnLavoWWpdfjg=&XohUjAZgqrkUm=&3sQCyDZhWUo_s=&8EsgQFUelssk_=&ysjZZ8V_ip_Yl=&FvLvNGVbdYWYp=&7uHv2oWsXWniY=&HkztTTUnZfXnr=&BtPV8BZYegqmY=&ChZvHRVoZnqkl=&P7TTgNVikmami=&EBCKzKYgleWhh=&D3olUgVfVreVU=&V_BCp9WiqYmnh=&BHUJByXrpbfYk=&7AUmxcWfkjeXh=&ZDQPDaXjVcpp_=&ylFabRWkcWcpm=>PsYDXkbdmli=&dv8Mo7W__e_me=&SAl23WUrrajeY=&dQacVyWZoobcp=&7OVzi_WXZsgdc=&wTjbsdZ_nfi_s=&qRkTyuZhV_qgm=&M5TERwUZplVfi=&RtibH2VphpdUr=&2vchL3UpsapsV=&WPlIRNXkoZacl=&HOerMkYXsVmkl=&3e7kiLWjVpgXa=&8x4xy7Ybmikoe=&WhngNJUsUddfo=&3urAUzXiUheiX=&dXJ32MUhXXsm_=&Znz7pcVUqrblh=&3_HGkwWopgepk=&uDIJplUZagmbf=&ZUsRoUWfiaWoY=&SfEZC3Yf_cpl_=&P7Z62GYqonaW_=&y3QS8rWmjesgU=&JjPeynUcckch_=&BezLCOYlcVdVs=&dxHC4dWlcVfje=&B_HoyKUrUXXld=&lRKzNkZcilZWU=&IDlq9tZYrjUsj=&zloTCMZjVVrXq=&VV_aecXZfknYl=&L7qMXyUgeaWUn=&JCKrBPXopkcri=&hAzSSUV_rdoUo=&JWLFwPYaXhekX=&xzfp7BWhmoocX=&v6YVMLUXhfbVk=&pl_wuxYmgfVsa=&lHXASQYbfao_q=&Nh9uEdXcVrUno=&aggdhxZbcorra=&vNyfpBZofWdpc=&oDEI67Yolpocb=&xxJAuQXgldbZl=&QG5HeoUpY_acp=&Tr4v5VXdjWrce=&ejls5GWbmeim_=&KMmQPrVnghXVY=&rZKK7oYXZdlja=&qN9nUoYV_bmib=&Rp438nUdqjhiV=&nH8DJ9XiWa_Yd=&NvcpNdWVfoZXk=&8wwmGXZVlW__g=&bVym_ZUYhmdqs=&kZBaK3VnXhnis=&9ETYhWVjfqihX=&MX2IQ5VcpmZrb=&qIEAnWZoVnshY=&fwuVhsZrbngdX=&5gJlKkWVZjYrV=&_AZzLpUloiffq=&wmwlhCYpoVdsm=&6_x6eXZgchVXh=&Zief4LXqgkjla=&6WTyXkZpspieb=&P48D6fXV_UqZW=&N4SfR3Xs_jibs=&HYsGp_ZVYigYl=&hSrfQwXUbYjoX=&KeDqyxXmpUooZ=&LXZItVVdkXnsW=&9NyiLnUobVklp=&JvDosnXYZelfr=&_sjgvKZidmVsU=&bsuJNtZkUloZY=&TRgrY8ZhhoknZ=&BKnYDnUpUm_fr=&QnTHz8ZdYXXpj=&JHLmI9ZahV_rq=&aIOJIUYgfkaid=&nrDyzOVUcibcn=&bUzPqpXpVnnim=&twn4TgZgZUUhq=&Unt_olZalosYk=&jx9pSDXoUhbaY=&qQaWUVWlrYdoX=&OTDHgTXeW_VjY=&n_u8hkVmhooUU=&xsrOkVUZXWcXV=&NEHXwWUYimejn=&5VEkWbWacfXXY=&eQjZQHXZUndmq=&VSJhAEVckqpjf=&CLlSquZnhecrn=&hGI8V6UskXaqc=&ZaPEmaVWYogYs=&RYFmmGUekkXga=&BciBaZXWYi_XU=&3iNDXDVlgoYZq=&ixbvUvXaqgWms=&mhaIaEYbbVgcZ=&UUx66SXsjWlWh=&4uoj3wVjkprUV=&2ZheaAUipe_aj=&ZvtSkoXkckilW=&yAwn3AU_eah_d=&b4OGgoWoWnbYr=&bzPb8GWoadmmn=&AoaJfsZkgpYji=&ZQ7xsLXU_Warq=&9lZfVCXshhjcZ=&c_AlohVrpZY_f=&3WqxhMUV_k_kc=&tBFP73Zlarrml=&LAHsYaWlXiWrc=&Ms7HCqVc_eljp=&Y7eDcQWXqq__f=&yQjALgZlppqns=&NbUNVdYkmdskV=&p4Kc6IYgecak_=&YdGD56UiUUZnk=&vHhewbUqrodjs=&GXHmeaVddjbsq=&aRME5fVbqgpek=&VV3FkCWeakqYe=&MCSXTWY_ba_a_=&NfJzMTYkYinfc=&nZ_qlvZej_XoY=&o85YiuXbYlXld=&fSQWedZarcYhs=&YcoRaNVegYUmm=&hn7XTgVZYenZp=&I_XKnKUbakacY=&Q7ZzBrW_dnkkb=&Qb9ppUZWqXWdX=&g_8fStYlseWp_=&MKLGt5Zoohjsk=&sHNQkzVrrkWcb=&eOrh_nZjUUoXb=&ayYzSUUcareZi=&Ge7gCpZdhVebj=&HR6peBXghjmml=&H4UU2YWnlndpr=&J7LKkQXX_Xcdf=&zFy4vzZsiUd_e=&wAHrJgXbnU_Ur=&iKWvTGUeVrfXl=&3wwVotUg_m_fi=&3bNhIvXUUoYhV=&t2B89uYhniesb=&mm3LWiYWYkshj=&hzlxDAZnmpoVs=&DxZunlVlhkZlr=&GMZGi7ZgomkUp=&pBGVkLVjYnr_r=&exF5HBVnWUbgq=&CmARJ9UeeqogX=&FpTawgUhnrZom=&XLx6rLVpechqg=&SreNdqZfdbbkb=&xNcxpIUgnaUiW=&U3xfovYUYhdfZ=&ElPSTmXarhcWp=&pXUVV5ZUqgpcf=&Ol9RUMUgsh_gW=&jeOzt3XqnkUgg=&WjEC7uVUkVpkn=&Qffi2vYhgbsZg=&uEFBTHVUblrZk=&m9TB3aYXadWVc=&d6IYcXXVUUkUY=&qoHO_EYgnrfiZ=&2OkbHZYcaViWm=&Wwh2CTZcWbgeg=&eFescXUflmXme=&ON4ekrZWe_mmh=&LcMW6AWroXhce=&R3QrgiXjdUYmU=&g_jpWsWZoiopr=&GUYjldZ_grr_n=&f_acPdUmjhqXf=&98KSyKXdkYrd_=&tjnGltZspfqra=&N9pba4Wf_VdnZ=&eIZ84cW_gbeaj=&v4pigZYVgdYgl=&eFFH2vVpVfbgp=&UoKTXZZXbcpao=&Xdk6ULUXokrUj=&FY2cGWYlaZcaX=&LJzpHfY_a_oop=&8dlDEwXceniql=&xgArrMUbrdaeX=&ZFKxOEYpidfod=&KtnRh2XfpcgmX=&dSbJ2XYaZUUhm=&LVDDUjXlfVjfY=&mVaNZjXdqoWdW=&uodN3pYdarjr_=&dPIlOjYnXVnoX=&zyZBsnYl_kckc=&zIurSuWrfehUo=&dmP_lKZsrY_Wi=&gBEPAxUbocamd=&5FJWt5Wslafbf=&OuTASoXfdYfbh=&OlmGBnYmrYYih=&CmfSPwUUbkahh=&VnIw4cUffpV_s=&phCqjIWkghYkf=&Fapr9OXdbljsl=&sug2DVVahagsi=&ZUB2HkZqsfffr=&DwDA2aUXholri=&FOcpXqYlafkaW=&lGdOigYeqbYik=&AzVSdrZrWZfcV=&x2qiJfVnnsUbr=&Hnn6HQVpYn_ef=&iMVvAHZrWabfk=&IVUVAYYmcoXhp=&pWUansWdYmoko=&2LZ8A_YoflcXa=&pbkrFtYdWWiil=&O5JV23Y_ccmqW=&W25zVnWqcZddc=&faFf4XYslUl_o=&HV4UtDZWqhqUq=&Ix4a2SXnUeXUZ=&uDWlIxZiXn_re=&AKUAJuVYmklo_=&hcoHTdW_sUole=&TS3LrLZVjkjXW=&JjOvMnYeqjWWg=&45UFRNWWpkdsr=&eDPQsdXaXpUZq=&_mjgEIWhZ_kYm=&Zg4J8YWaemdjV=&_2xPCtYUaVcqU=&XOzkTuVbseUnZ=&qTXSr8YalrYZm=&3ZAjZZUY_mgYn=&9dupkZVfcZmen=&wtvZUdUnsn_qp=&Me3LDTWVYciXs=&Z8n6jJVp_lqnd=&CZTTBQWsednfs=&pdf2GoVbccXmc=&9g6OBRVkefimk=&nYQpYJUhcppfk=&J_3CYPWYloZfg=&zerM7eWfdkbWY=&ST2FBwWqkqlaY=&P_mAxUZWUfbag=&vZD8deVekesfo=&nqbtkjVbXo_oa=&G_f9QKXmaWZYi=&J75cj6XYplkob=&6GUsfOUcjldhf=&eUH2ZrVWadekV=&LFpnIFZesrqks=&ZZv2gDXadrWdW=&fHNpANUfalZkX=&TsdW3BXVpZggc=&Y4kvhUXq_WVem=&OQdSqqZfcZbjV=&4Bicq9VcenV_i=&MtvjzrYcqejgh=&pKUqFHVW_pgfd=&R363xXXWdcZie=&LzYhFnUqpkhq_=&H5TJJvYion_Yr=&NXgX7RWepZkda=&aIz9XiVlUVdqV=&I6268KXfgmm_d=&kTAmyLY_nqcYa=&wSplxNUiZmnde=&HMZALPWqhhhlh=&ZAm5NZVnmfdUW=&3k6HszY_arZdl=&IHXjPQZdrVrgo=&upAm25ZmZbfle=&AmzZkwYbebmep=&lLs8YNWVf_njh=&HWsk3bYZVVklr=&mDTHHaXVgkmbU=&2cI72rZcmncWW=&KBYAavUioriYU=&bAu_ZpVedhlee=&DLyIdnXUeehqb=&NKIAO2Vqhbcko=&nbLbejUqmbheW=&CNFL_KVpqkp_Z=&wLoMwCWiiXmer=&gfSq_tXUosicg=&Y8pVQkXbeWlgp=&vI2vaFWZlXdkl=&vC2AfIUcVqkof=&cub6bQYfbZZlf=&PNRkK4XWbjcsq=&hFjwbQUWjbffn=&vhKPM2Yesnik_=&h3rkMmUqZVnZb=&jOGCyMUmemnrs=&jWZpaOUWsigZV=&jvmTy3VVkmnni=&skGe88XZssgoZ=&9MhW_3VUUpXcV=&DrPZN_YeWsa_i=&LajrvHZdVmjoo=&juUcxRY_UfXZf=&L2suABWmrVYhl=&WAv44QWqfoZqY=&kZGAwiWqrjq_U=&D_n7eZZhcpnXX=&AkmOGPXbeYmbb=&z7dNLgZcUsnYn=&qrxdU8Yjns_UV=&5qbzqXWbgVgW_=&YSvBROV_ciWUj=&XKyxoVWgkdUZa=&GhE2XCWmfimZY=&LZpsP8VrYdobm=&92wsiAUdaXbnY=&x8uBvvUeligUb=&BF6OxAWnsrsfi=&7gq3mQUgmppWl=&S57yT6YaqUabm=&6ZUdWkUmriljn=&m4zAJBUegjgnZ=&W6tcWgZWeUU_o=&HmAzgIYnWXjgm=&tfoOAhYbh_Xoj=&PlnGGOZhboZ_W=&mBsmtgWX_Xrhl=&OWHU6mZeUsWrj=&2mJQTSVgUbsio=&p6dvwQVgU_rnc=&MJAHMCWopasgq=&GraCQRXfdkbpk=&YBGQ8GZaYmmcm=&4RE5r8W_bVdek=&QumyXPWmleobd=&Ng9aTdZeZlbag=&D4twOFXhjsaVr=&7cPSVZWlmdWkm=&ha_GBTXdheabW=&jIYGWnVkoWqnX=&VEm9sJZrkbqnX=&TofHwMZXbYfjf=&Vth9mlVrnXoih=&unhWIjXfihYXo=&Kls9bZUnkbrZq=&LfIG5_We_gWd_=&aDvSRkX_cnmg_=&beyHJEWljVqVm=&4KMYMVYfdhhkZ=&HFxDlBXYhoUmZ=&oCzXloY_fglmW=&8DjvwDYZpkgqe=&Y8wkEvUaqVljm=&gGun4UZc_Xqmr=&sdsiweXcZreYf=&YWIAOzWlnjnjh=&w4W9cYYjnsdqr=&fy5xFlW_WqWYZ=&yynN54V_Ymmen=&UIogXOWorebek=&UWWLh5UopUoXf=&lI8yUCWneXqdc=&MTxDIpUodmjWd=&F4AqLlWpVjqeY=&NyRbh3VrmrWmW=&RafQQUWdYVabc=&zou5MnYmqpggc=&unQPnZYYjUhij=&t24KiIUXkeZpb=&3uKwZfZcVbbls=&N2CyM6Xfaknah=&E9fcYeWeqZfdl=&QyhHfyVnoUYsm=&zTkxyiZrkgYiU=&JNb5lmVUZUbcm=&XvnDJFZkqmUkm=&jqJAZrVZpVssZ=&ZDtxQkXYVabfr=&GAzDwGUnckrVs=&qT9w2wUblVjer=&rxIcTSXlUhWnW=&2LktiFYVpphVe=&zYbOL7XnjsUUp=&Yiqaq4YferUhj=&JTwGNuXjpqkdg=&a4r8xUZkWnh_o=&tfnnhbXjjYbpU=&fWX7alWgYmrjq=&UCIU3UZVonbds=&SqecQdWVUgqnW=&pQnkw4YieabXW=&It2m7FYnmciqb=&s4fey8XWekrjV=&a9t4bhXcaWpdm=&M__rEoZpWZYmV=&qdVQZvVZhsZYr=&XXC3qjZbfbkie=&fbCfwtWnUnggf=&__Y3ROWbrWWgq=&OEfAWgXWrejbe=&ag8aJSXbgjs_k=&j_znRiZpVqiac=&sIR3eWVkZhZco=&36KxBXXYVokjY=&LGNwgHZadbcjk=&IS3fppYsrrred=&xf7of4Y_dXZZh=&i3cVz4UarXUXf=&4RDNLmXbfcV_s=&OKsXdjZnhmokV=&IalmAgXZUnjmW=&m69EEyWsdXhVa=&PM2qTAZYkqcgl=&TFZF5PUpgbpZs=&OHF4VhXfsUccc=&_SNkFiVWsnmnk=&6HtIbvWrYYrmk=&sLyIWtYd_Xcrs=&rfR52cZjZhqhW=&dLyeLiYqrisqX=&qN_fM6Uhhgqdl=&Z3ftA5VbbeXjV=&rFUfc2Uifopid=&BjFY6KXsfknrn=&EXtLIlXsoerip=&FLiWG6VWq_Uqh=&mQ7fd5UfelpqW=&z6p4vAUa_mdoj=&OTUoiMVcqndjm=&z2nqGuV_gWfWm=&LyWJGyYjgdeUj=&NzmqLRYn_qXdc=&ClgaTIWYZfriW=&4IGspfYbqWcsp=&oRXx_4Zg_b_ad=&OkuIrsXVpYrcc=&5N8XMQUflmdaf=&wJeKnUVZhchZk=&BMjxZMWdWplhh=&JeRuFgUrVlmpo=&JwrOz2X_mlbdd=&wXjgXoVpZrcXV=&iTYktuYjhkkpq=&kQQgVTWWssfq_=&nGswFHYsnamjc=&f242RwWmrh_qg=&OIcfmEYpnWebl=&69cz5EZdVhXks=&7qIGLBZngZrro=&i4_xxjZkjoalq=&rXDIK5YVrWiiq=&iDM9v2UnnobYn=&pDzyjBYZfYs_e=&hvubDUYj_UYrf=&qVEXKLWqcdlhj=&vw55VoUahWZsh=&z9bVFIVZiWdmk=&5A8oSKWeZjjYb=&MU9FHEYaYnckq=&8MEOgrYdlZWlr=&FvM9AVVlsWmrj=&jMmIlmYfZnYik=&MYo73OXonVgjl=&5X7MDLZdijgrq=&8_QMaqZnWooYc=&yI4994Unrphng=&f9rrI5Zrklrkk=&Z7sDUWZUodiqb=&DuuzaRZXpUqeX=&m8JfzIYiVrrcm=&doWKUNVbcnoqk=&FM8Ag3VmpY_kb=&YbHPpyXpamqjq=&ME23x2WbUnkrX=&H496BwUVlkqkr=&QeKbPNZrUjmfi=&z3I68oUqbilbp=&vvwmKHW_qhafq=&na9hosUdeWnZm=&TymlFgUmVkUVm=&jz3clYXVYahej=&MgT6UmUngYlbo=&ljv5aIZU_hlXo=&ger3F3XXg_cni=&ZLkrMeUfiolWm=&wMJOypXcWXpqY=&MGo5jyVjidmoZ=&9jzkeiVqYW_Xr=&jwAEcvXYXisXU=&Qaw8ksZkbapna=&8udBdGVagWbZk=&ea69BJXmafpZe=&_gqXmmUq_kdUb=&3LzA2wXsYpnps=&gcOmP6Xamhbhd=&XEvtuIUaVlesi=&wm8L5BUhsXYsc=&5fzQbGWnoVkYs=&Tvk8HzUmrisri=&kQZoU6Vegmlnm=&Bo5X5iYcYmdjb=&cdUOZoWsmYchW=&jAYwh_ZUcklVs=&BSUnaxWoWqcpZ=&g_iDYDYeYUeni=&fKkB_KY_dqaqe=&E6JTvrUjgjpXq=&9s3kULWZpsjsr=&zItcAHZlhqWor=&ev7b6bXZfpZqe=&noWeaNZpqVidl=&epR9loXbYoqXV=&bAGnYHWlYjdeV=&2SltLrYm_ibmr=&lqy6zYUlYgkrg=&tHG4lwYYgkglo=&MpAyFnVbkVrqs=&t5GAHQVaqkZfo=&3JA9JeZZirYk_=&Pju4ckXaflcbi=&cb_yWHVjVlqol=&jz3hjtZXnXcsa=&2Ktl8yYhUYaki=&xnecqMYVhZgse=&4dwcosXj_peZr=&B_adRjZgkp_kp=&5VqM6cVYqqrYn=&4ZdSBMYZfbeWi=&pnMYauYUYkZdp=&OlKdfVYldcaWh=&WFF9w5Zggrkgn=&oRX3zMVVbrjdU=&4BS6LPZdd_qad=&PpUmQtWdbYqck=&pylnH7ZYnbiki=&nPXDzBWZbcfXf=&zTs9JMV_nX_eV=&EidUn5YcYoVnn=&yelmUjYplZskY=&A6vFqhWoqnsph=&w3m88nWhgUmdm=&AS5qzOWVoZUse=&_buBpnYZbqrjp=&YFk4QwXkoogce=&qHHaQ8Vgjoggg=&ILJ98tWsi_hfX=&M2sEWnYY_sVgm=&9KIkbMYcigUco=&KnE83YWZUVang=&musK5xYedUhrd=&Jg4anmZYoZlhi=&do_dUuYi_UWkd=&wFOqHhZmghpYh=&UkxT8RXmdnlrk=&FAHYbzWrhqcnm=&o4Z5KEWdUipch=&nm8QPNVZUob_k=&Cr6H7QZhpbpfk=&QCYEkcXUUlYfq=&9rx47tYknb_bU=&QlhwDeXeXminl=&lT2r2nVZjeVah=&LmAmoaVcU_hhp=&yUKFYjWnjhihV=&va5r66Zmpofao=&GOFVrfZdUb_ca=&YbcgSjZUXlghn=&STqakZZqVeq_n=&rv2QBHV__rZaf=&v4mreYWjjmp_V=&9HFk3xWflpsUh=&tyjOydWYhWpo_=&6LFybTZsZVsqh=&5nyeaEZrpssfq=&v_OXVbWkUY_qb=&RRQMAgYhmjjZX=&ZoCryDVYimWqj=&UlddymWd_ifpf=&yHJiPCUrbfomZ=&AmtCIyVYYe_bW=&ylCJasWYg_mWj=&8fUwPaYcfeonc=&OkJaCvXgfW_XY=&vthKUeUl_Uira=&sRqgQoV_jZ_kr=&X5rui4Vrknmsj=&JUbCCYWaqiafc=&HuO2gXZrcbiZc=&KH4bS_WWcdUgd=&k2VTi7VjiXoXY=&n9yJNgX_l_sbX=&leq2dkWVaXY_W=&2UPU6vYbY_pcd=&TaxtnRUsjZrsV=&gM3rtvZYWdYma=&lbEoRzZrsmmel=&RHXeDDXhgrfeW=&xhm46fVZXnd_V=&JENlc9YfUofXb=&vrksMIVbbU_rl=&PmTTuyZhmWrhi=&OHFMZBYlsnqed=&JPmYVIXhVWZlb=&UzI_P9WUbXjjr=&qbtr4WYhVVWrV=&8DnlxPXWU_YmY=&IcfTr6WYccpYq=&bYfVEwZrdjkqW=&heJgFQZkanZ_b=&znpPgOX_WUnlY=&h7zb4IUbeVUhW=&9v4IUxVmhpfW_=&2_7tQqYifki_o=&tR6mBDU_mqcso=&HLKvDqYrqiZmZ=&ZfEInhZrnXWsb=&sTWBSWVXWenjV=&dZ94ICXfhUflf=&cj4rj3VdrVkUd=&n_Pyk6XWVWbfc=&WCF7ihWlbgcYf=&pAILsZWYajqZi=&I4OhLYYhXgmfb=&cHa3OpZhjpkVq=&GY6cV4ZspfWcr=&9bvVr6Zhpfskc=&I_BqFEVWldpX_=&sDJQf3WjpjbmW=&Mvm6c8WmgpleY=&UhhTUNYospnlc=&AHP5QeZbrVpUk=&aAJ4oMVgeUgrn=&XTze79YqjYqf_=&Kkq4lpWUfrmpn=&5OXszwZrdebWZ=&GAtAC5Yfcpchr=&VQIOg5VaUmieh=&A2F4rBXYXlkUh=&7OOWtQVVZhdpq=&4hEhZvY_eahZa=&t75ZRGUelfiqi=&mCqfNUWkYXoZj=&2d7pC7V_XZedc=&Q2MmB3ZhgrVhW=&JdQM6GZrVgXZl=&TSqvbiVrmbmir=&TGG2AQYeWYqjo=&AiTQfjY_hsrln=&iMrT5kUiWjqmY=&AVAOXoWcWkken=&lioNQBVpZmfbp=&K4WDDrV_q_nZa=&P4usHJVYhbl_n=&bbgd3DUikb_Xl=&PTjFhjUcb_rla=&JQNe3eUslWqbd=&zqFgpOYZjbXYk=&lv8HmzXkimlkW=&Gx4es4XjrccZW=&BQpyKsVViZp_Z=&zYY9lcXVkospo=&bZ3AYAVXdoVnm=&fzRSXeVcqqnUp=&O6ra_sU_pUiWa=&mPqNRQVnlsdpd=&23rH5DWXZbWdV=&eCiklqUlooaqf=&uwRpglVVsmUqU=&H7GwFdUjqmhll=&jIeVUbUcUsXXc=&7iYR8OYgdhW_V=&ec8Fi_ZVm_sqh=&W7vtqFYjVaWfX=&nybZM4UkjahYb=&afncvZZ_Zhnda=&h3ldptVZoqgqq=&FCC2DJWfVceeh=&pyTu9kYdkaUnp=&wI8jutZrnXpWf=&pZeomeUWoWrYW=&tOKgpzZbUWYZf=&xCZIbtUrsrcXW=&_aSYrrYenijih=&umc7KEU_W_jhp=&3C6lzOZdsZjVr=&XvIdm4Zncmrbh=&8xHIYfWphqcho=&FKnbzpXlmclbi=&iWNeUJVsUVZ_W=&r_xyVjXahmWre=&HZG4RLXrhcbdj=&63nWitUgrXfYV=&lUeN9KZWslnfl=&fcfTVKZaraara=&MsF4kHUhsWZfn=&Y8SngBWlempkg=&lGVd85XbimZbV=&MGU8OMZ__jaim=&8dkKw_Vqogjkb=&MEPHDpYjihsgZ=&YPavs9XlZVbic=&3Blap8VogZbaq=&5D9QTCZegcbYn=&uhncyVVaqnnXq=&iUV7T4Zp_egnj=&FMZkpjYm_jsqi=&fXRzVxWkYphoh=&9iliOCXWdogec=&JBTWLcYYjcqcW=&B76buXVdjlfhp=&Y5gADVZbjbegd=&d9tknzUpcsseo=&87CtbnYjZsnpb=&4fWo3oVYbXald=&KzyKpnYZXeWrb=&mJRG4YVqhWUkq=&yxtVjaVWjpffY=&uGfqQ7Vfgsgrd=&kbBYKWZgrepmq=&RVnAJzWbUjhmf=&yYQCpXXsXVppm=&t_BwKeWjbmorU=&7xKbPzUXmVZdr=&Or3hbyZXpYVpj=&UN8nYNWmllZhb=&YqDb6CYopeYUd=&eV8ctsV_bgs_o=&KJdaY2Zlkpgkj=&6aE7uyUkVVjoV=&crJm_VZpedoaj=&gokS9NWZmhiqe=&ck42CTWikafsf=&LjsY2rXsnoXce=&MUqGBWWjWrkgW=&z5PXxBXqWadgm=&ntyhIgZlVifbn=&mlBS_pYnUVh_h=&dZDYgSUmksgnX=&W2hM29Zskpgsk=&Sa7IVYUZUUobU=&aLLt5kZkcblpW=&H2eV_dYYo_joo=&4lKygzYaorjma=&StEXHkXqfhgdi=&fIevixXlXVZZo=&WhfgwAXipZsfd=&79OyqwXhabsnX=&OeMBIpXdVsm_g=&TxSlxzXXhdosY=&np6BFbVccYcdh=&Mf59cbXddUVro=&cHyPUfZa_fnsZ=&JcMKcIWsifYbY=&8YgIKxVcecnsZ=&6mnhRMVdWkdjn=&DqmnQ5VehXcZb=&P8RATrYolZWc_=&uDS8e3Y_doVcZ=&NTrx3mZZsXl_X=&WChYbFUsYffgg=&OZI57EXZbeYdo=&LbQNdCWZgopjq=&NmKWpMZffnbqe=&2ZHHnMYroXWXd=&HAFJytVhknXds=&nJbrgxUVfnYpW=&kitgFNZXesXjq=&cI2TmoYpijmjY=&MJng9FUshqVUc=&5UyRoBVWedXao=&SRKncFXdndaii=&d3iiGOXapqXad=&VYoOXXWWesUZp=&Gm5w6uVapUldi=&aIVQ5ZXiWjn_W=&i6yXkQVUmqfdm=&SxPZndZpaklre=&7Z78XzUUgoead=&tGJtZEXmkhqgj=&V968eLYUmgXjn=&L7SUKhVlndpkk=&g5EZL7YfnmVki=&h2M4CQVnZqrbX=&LxzALFUYjUWsr=&qcNAdaYclXjks=&XZ6x5eWkXVlZn=&_OHhm_Zibhrlk=&iKwou2Wngfalr=&CDBpqrWUcsnZd=&crqFcMUajksVX=&SfSridUUpofbb=&LKCQHEYUVpnnZ=&RWvig5YXeo_pZ=&EdEy_sV_iUYZW=&ynPbgrYXlkqle=&AD7cAHYcpWekg=&EqLgSJWmolWaU=&f4Rv3mUrZYjqi=&W_XAElYfegnqd=&URfMn_ZcsrggW=&TojRCFUji_nmj=&RkfDsWZa_iWVe=&4BzblTVdeca_b=&Lpn_GuWZZikjn=&lkJ5buUmcUofX=&C3KfZXZ_ssoha=&fdE3aUVihiZk_=&AD3eD7Wbinkdk=&4hAvz4UelrYUo=&Hjcb3lUgmnmga=&nvIq9FUfUlamk=&5Y8vJjXiVZcWe=&kls2HVXcnfboX=&bJugl4VhWsmkh=&5J6ogpXreUWjn=&7wpAqwZcfmqXh=&DoIcwlW_q_coV=&Urf96oZmhabXe=&naROdHVYmirVq=&vC__YgXYbilVg=&9n7W4yVVWeiVo=&RvK7gaXmpqZjj=&xT_92bZfsbWos=&ZZUUeTUmgYinX=&7MyqBUVmlrVqs=&vFW3gcXcWlehe=&k_5_UTWchmjrp=&puxpqsUslZirn=&xKxa56YUejp_g=&7tTmLEZsgegf_=&kjgvjyYk_fkZ_=&UHGqFDZsWjcki=&pPWFAOYnefrVq=&7q3oqjUn_rXhe=&_de3PZU_jfhdY=&AdGg9SYpiaged=&eulRT4WVVgVmW=&HBeuhOZ_nXWWZ=&x7G_jGVZjhn_a=&3kr_2gVsXWpmm=&TbXMOvVjZrsb_=&VSXCUbZamZfqn=&FyEuHpZZeXXWW=&DLsaOSVgdWpbj=&yv2Vx8ZnUehne=&fCCRyfZaq_gno=&Ek4w2FUpp_lrg=&tewMmOYZh_YsU=&iiJu3TWjkhleo=&jqUSWUUodopcU=&CpxjJmUY__cjg=&bbD4Y9XiViich=&GJHzK3ZWdaUc_=&tbyB5_Zr_Xqkf=&6dFh4cVaeihjj=&fgvtDaXZ_anbn=&CJ9gYVVfXrnqY=&Gw7RzHUVo_kZs=&A9EFATYbhljqZ=&e2KRO4WecfZoY=&gnKFuHUpdiiY_=&goIsWGZgchlnp=&mhzCgkZnsprop=&FnaNMDVaaqoWi=&c88JWiXhisZUh=&PUvVwfXiZddfk=&ZYt5taXffnrnY=&DB_U5EWZrgYhe=&ohTCefXVlmsYh=&DLYYBMZWckoor=&PNUvxDYVrcgmY=&dIMyzCVqWUfcj=&smSJdjWrqXZUn=&V2qUPBV_YXjZd=&vZ2pWzVkgfY_Y=>kBpmYZqjXeb=&V65UJ_Xil_hlW=&EjU6VzUcjfjrV=&sj7dVdXdXebbe=&b2XHTwZpddpkn=&DOuIEPYmYVdfW=&qJ7MokZjWhbos=&lwi5fFWfXWXoV=&VzBo5rXoaddnl=&CYhiuCUfmsVmm=&g9eCoVVdikpiZ=&7NVwBaUddoUnd=&V6Wb9BZllqZXc=&6WWTfvZoemXfs=&S_sxImXjXaadm=&PbV2ctZrhcojg=&HrHH8eVieajaW=&_PvGlRXebksgl=&5xZdffXVcdhqo=&nnunU2WejWkWW=&5EQsqeUfkpgWf=&fbmM56VpmkaXf=&p9_OiYVW_qkep=&c7VWTlWZYqfhd=&pI8fwCVb_dslW=&UWGcVWZhpqglm=&fRhRTqUfZUsjp=&296slLUWjZhZb=&ZOPEk9Ukki_fm=&qeufpNXWZhksr=&2xwk7fUcpZsnV=&MTgw58XakZgrW=&p9Yc8BVhqVbam=&tQRDm_UaWohne=&9gstN3UsWUYgX=&NZyGqVUUfpXal=&rVchWTXinddad=&VhCm8nWiarogg=&7RtUHUVnUiqca=&c52cIuXcWhU_o=&w_JYNdVrg_dkb=&D5muD_YdYUWnl=&o2qNlJZmnsfYc=&BjJlqLXndYWWj=&mk3SnzYo_hbhi=&jVgrhNYdnnlrh=&Reh3TPUkbUblg=&yy4Au8Xddbsef=&Duf5CMUYeZjcV=&WAzq4gUjZcrUo=&wUmzH5VrjVkYh=&IMv7XrZkdbscX=&7BzWFiWaoVYXU=&L2R_BVU_kZVmq=&uEsRgEYl_fYmU=&72KbX3Vcpsgrb=&MKwNz7VYcpfi_=&FC7MxnUWeWYec=&D28hpSXWYhlqn=&XxMa2BZiamcka=&2SFSvVWsfdWWb=&ZSUbUgWeqVsYk=&Efv3BDVockjYj=&TfECnFVigms_g=&NoDNeWZYblYnU=&aZoSgeVmmspnp=&KtlQFbU_hqraf=&gHytM6ZfUhWZa=&KOGVuWUoXiZVV=&gDbuFOWpqmgno=&cY7JfNWrbXnYg=&lUireWUXYnhZh=&p946wQZqpfepW=&kshDxAWZiZWdh=&4SOg8TZgYroUY=&rXoRwrUUpXWYh=&hQOgGhYieqdsg=&OtLlQVX_cjVgc=&zUKGRKVgmsacc=&rwHXFlYWohZoa=&o8p8owWpaXdih=&iQEDPwYgXlhac=&6XRdhVXYVWVmU=&UccMDZXdZeiXn=&vBldUoWUjUUZf=&C4hyHVVe_goqc=&c2XSsTZUbm_am=&ckWgHHWpUhfaY=&Zy_m_zWlbkhsk=&8nXZaAXhggabc=&ynZRbwZigVaqj=&pFVvHqVWilsWa=&ov7ZatXjpnV_p=&uFCQ3XZriWbWY=&gciyrCZhnlqse=&z56rYRWnWaigi=&_iAgeWVasa_mc=&3SKvQzZnUVefd=&jscBp_XZpddeh=&7Ei2h5UVmqoqe=&8bHnt6XnksYUf=&ROI7WNUciinjf=&9m5lZoWUgqVgs=&QyeUhZUiqWmeV=&8rv3iLVcWlnjr=&QAv6v7WrgYm_j=&JDYzrtWnijjbg=&NdNfzHWprWqkn=&ghN7opZjckpXe=&MY4UTGXUVY_Xs=&AO7Go3ZmVoWXi=&OeOmPOYZZgVmr=&t_Ymf9YelgkqY=&SKDKNIVjhnWZq=&zJKZCrVqXhVpm=&SSlP2vYskXonh=&gjmtFEZZlpfjk=&g786YGXlhjlgg=&ofrlAZYVnjkgY=&v6VsxhYUdZmXd=&loOBCiWis_Vdb=&fnenYGWYosfWp=&yUCGDuYl_rjip=&H6eY_pUUsfYjq=&AGyQA8UfjYUic=&XLi2TBVlhqWkX=&RZpK5jVgaUem_=&3nx2owYgUjUfk=&Vo97tKZddiacY=&e9K7EIVjYjfVs=&RZrHPSXdhbVep=&Ckvk4HZefsnod=&CJSfLAZnfkajk=&SMbRw2XhcYalp=&dHyvYnVkqskc_=&3m9RmgXfUnrjf=&yrarAxZfd_rhX=&95iWfgZlmgcVd=&flxsj5Ze_dhkY=&86hRfoZnUqXnq=&HpIOv7Y_roboY=&ebuYGDZaWoVhi=&SAWQgvZdaqgnr=&qU6rkvYjhjUsV=&iMVbDeXqVZeWZ=&5flGiZWbsrcdb=&iVatkhZggkYYh=&ZdYR8oWbrVm_U=&uvE8wuVgdjjsl=&KBAeNYWdeiejV=&jOeuLhUeaqrng=&XS4DOtVsdYkdU=&VhhLDLVlrYoek=&Fc8xrgXicck_q=&YyujKZZdekmlm=&rJ6Bv3Ymdabeo=&F_3oVAYpacc_o=&oJ3dw2YanakVg=&8PgManU_rp_cq=&LFdStrUhmespi=&psbplNYjfbcpg=&vS5pOGUkhqWgY=&GkpeFWUgVorli=&r_ZTXSXWYmlbe=&kZdrgVYhkYimg=&ZeYFq5WZcYenX=&_3YmmPWXoekUf=&4Vzi2xYpsgXlp=&UVs_UxWrfZdVk=&vLaa7mWkikoYf=&nu7ahFXZrbrjs=&qAiXxZWipgVao=&JF_opOXaefUUo=&_YNBQgWrikofr=&RVFXZBV_XY_kn=&naBZQtZmioXjs=&Rn9b_3Xj_UaYs=&ZN7VJ_Zlqqboa=&GYveHdXflXjel=&yDxOtZUqbbnYi=&EvddGQWY_rUrg=&JjTYwwXeXaacW=&yN4NefZojqcil=&2XFYWCVrnUZiq=&CfqNQcZbdjqjs=&Pm_jLFVVZnb_m=&A4C_GNVhZerje=&Xw3FWEWXqYZbk=&sWR7gvVnpkXYf=&jsdFC7WjZXspg=&_KlXQcVUrrded=&8jZtmuYXUZrdd=&m7nULGXeZbgeY=&sBS84eYafs_bW=&_5AnGqYoZid_g=&2wLvQQZ_lgmZV=&wZ_vJIYesrVYa=&kOudLtVWkYfa_=&SeOyc5Zrbjiih=&jIPsBpYhieXb_=&NPc7RjUss_Vnj=&kEtl9ZYsYXoof=&8U2BrlZohoseo=&h5j5dnWncqmUi=&DumEGfVXcbpbU=&stYLXlZeaebap=&j42EWbWZhmUZo=&bGr5K6Up_fZmb=&OousAKZVirmke=&x6IqJUXnYdZfX=&W6E2nXYachseo=&rmXjZ7WoVYioe=&CdwjgFUUXVXWj=&oDwpjeYcqgqdV=&3PgDM5YsqUrmU=&WYAXV5UXmcgrV=&Gu4yDNWY__jXg=&CQbH77Zaeiiqa=&W8UooVWlWhbnn=&lUcdkvXranbXl=&EfSL5AXVeUncc=&zQTYYJVprUdll=&OaJFtxWsjgnmd=&_RA8_BYUfiZjV=&LaotFiXdsZqWp=&7kZqv9Xgmkmdl=&dbqaItUd__afg=&ZGamCDZUjlnrU=&7nVsQDUZnUXaV=&nZtRA4ZmjofpY=&JoOgxuVkkYsos=&2NNtdGUiacmpX=&sAez2IUVjmrio=&ZNj782XogXaqm=&FWPkg6XrhpsUY=&aqVVkjUVqdcjd=&O3unC8ZifmgVq=&Is5GHoZY_khUU=&ZZIC9qUZ_YsaY=&wsfJ8bVojbaWk=&wP5OldZsbYppU=&aAHHcmVnUo_md=&pWOY7yZXiamdZ=&jRA3D_VWcUUbo=&JgJ7_hZYkgoVo=&2b3Zg4UXZgVld=&riq_H2Ufgicsl=&9jzBOQYnnaoVd=&_IsiVuXlsjqbU=&54Ton9VasZbds=&KhutUsZoqk_dh=&qTWClPWahoqer=&hweJKfUrWofme=&PSPJPYVXbgiZX=&GwFNEJYmbneYk=&QjucEDZbcepsm=&uWprt6VUYhamZ=&A2c4EFVWUajee=&9sBdb5ZomqXpZ=&indVJZUemcqcY=&VuhW9UZmionjY=&589Fs4ZdWVcn_=&zACu_OWgln_ka=&zCKr_oXadWWYX=&tokAssYahdalZ=&_Q_uc7VjdYpap=&X4jMq_ZjaXWVm=&_59s4SZYWaorU=&F5JgBIYZnseWe=&uFXsl2YkrckUY=&AA33VtZcakqnh=&uH4Y47ZZpqWba=&jGkGlJVq_Xhgd=&bytj_qWUen_ab=&RobHs3UeqfgWr=&CF3PgxYkV_aaf=&9MAcBcXihWnfi=&DHS7awUeVarop=&nuJNC5ZZWgkfb=&kjWp9kU_Vec_Y=&izFAqyZZnqefr=&a8TcZcUneoZcU=&p2Kxr8UfpUhif=&kFtcQyUdrei_d=&jSfSLpWqorqhh=&6kW63EXZgddni=&RBreYiXVpqenU=&UrXeuSVXXXn_U=&DPC5_vXXldhnm=&5OUnSRVjXbXgY=&CoZpOOZXrXnfX=&FrwjQjYbmfVom=&vqsloZXjcYshV=&khVKhGVrbmree=&XG2zQMZZlasZi=&6Ip6TkWqsgYsr=&jLRAptZfljZYX=&ZynvkbZVpgice=&2NPafMWcfmXjs=&nBgKw_WXbkUWf=&CfPyE2Zaggapi=&EM5FsEYrfn_ip=&gyibndVniqmjX=&tQqfbaZho_Vsf=&7XiU5QZplaYj_=&7Q_xwAZaVZano=&ACImP2ZkghmX_=&nP3iemVnbd_od=&GG7pBRZndpqm_=&iz3HdqZpmlbrr=&KstDPxUiZZjsW=&Gxg4FIVrcrkid=&uGTWIEWjabUpZ=&igWcbTYpqld_c=&3lhSD8Vahqqod=&gIycKVWcnnmsc=&bvwXmWVoWkjfb=&ZmkCLgXgdZksm=&7JqrxTVajcVog=&RWf7ovYYqXYns=&HhvRstUbblsoj=&qEGQFnXecslUf=&FP4wRzWWlgbgo=&LULA9PXmgWUdc=&5FztxsWiqXqbj=&zYTIwRXopUhli=&2gR88NYhaflbU=&UGnC8EUonYUig=&nw3giqZirW_pd=&6Wu4oxV_Ujhkd=&gvYj9_YZk_Ved=&488l_qZpdWk_a=&ZzPQl5WZnqmVs=&hB_y2ZXl_kkbm=&qZvWdEVbp_nqc=&ZCg6yWUnVcfrb=&5uHkkLZhfhirW=&4oWesaUg_Zemf=&bksf3XYZiUrVl=&SDpRfUWeZ_kfj=&YXY4IBYWUsdlq=&RQyVNYVaXsjol=&j96JavVb_mcnW=&l7CUZtVcWVfUl=&nAjZQpWdjisYn=&lFiBDcWdoWbsr=&kqe3eYXgfWnfZ=&i7IrRKUsbqo_g=&6UhKhWVpmYsrp=&LXdUhwWqfWbap=&OBLOnnVgiYdan=&q6lflLVsclbZW=&Z2Sim8Unqonkg=&DpUHGnZrd_Uec=&unsPZVVaahWah=&h5GEiMUmslsjq=&fXbsDpWqqrdii=&wiPKqNXValjkn=&EsjEvYZggjWkj=&AelgwTZfVfree=&icLHxKZnophaq=&q3Ww6xYaplkaX=&sR7pGmYsUWWkh=&FJsjEDXreephf=&iq_uJNZpicgrW=&LRaJumWjXkfmn=&nZvwsLYsfqecc=&Aqwd8cXYnoacf=&5YBEdSYjdisna=&p5rmrnYdgohhi=&rjeNStZdddc_b=&89nWiKXcrZhqb=&TGGunnUn_plZs=&p6bFARUmcaegm=&FvW7POWrlkdon=&avPzuIWplrlii=&M68po3ZXpUfok=&ENzRytYZkUpar=&jTJk7QXaXjjcs=&bLJy57XggYbdX=&T4K6IfUsseWgb=&Af2a6gWcngmsj=&9GiggrViUoaYV=&BXa7bTYjdsssX=&UAZQ2fXcbjje_=&2erHahYWVdarg=&MPOPUrYdgnjhk=&GDrM9tXnqoiYq=&8RS2HFZbWZomZ=&ALiGXyZaqdrjV=&FPsLaKUssrYoZ=&Bqy5ACUop_pee=&9FW24jZmlXmhr=&8rAnQfZj_dcks=&YAEYfvYiVWqio=&xvvrRFUqfnsng=&fuhGGlUfgdbng=&T24R5MXYqoVVm=&5ISfCHXYbVUhn=&vaGzmoUeoiXs_=&cjv8nxYhgUqpi=&ng8WIXX_kamWh=&QfQsxlZejsois=&ieVCG9Xmgjolj=&Tc7jUwYhgi_Ue=&8rqLw6ZikYpgb=&ZGYTMlWehZamm=&Nj549UZVbZqZn=&tdtYwGXXaZqah=&7Nz4r9Wfhd_ig=&pdiELRVaqUphW=&QCMnfzZUlklgV=&Vp4NPMZ_oUrlp=&6RiT8BXWVoUq_=&mrZuwCXkdWXVj=&CF8YPhVag_Zpo=&wqwmJPZUiehdc=&dHlU3FXYeslif=&ZARCugYZUdWif=&UPkFS5XXmlhaj=&TPU3RkUneboqe=&gcVgaDYUqUked=&gJn8eSZZkdpUs=&UJmxT6Yim_mYj=&WrHIkxZhsqpnm=&XGXZdGYedbYcb=&ZSIK7iYqdacpi=&XfyYLKZVbaeif=&EhYVtAZWejidd=&LfaEJvYkdYogc=&D8TD4BUndadnl=&rotkieYeXWaYm=&Fe2UrHZhfpkVU=&MnrlZ4ZpbbmXp=&9Gb5tSZjWampW=&Bd47ZGX_gXppd=&VJirorUdYkZqr=&OF4ggeYkWllda=&gDPR8sYjYVlcY=&DfVrCxZcaprdW=&BLZrEVUaordph=&o44kieXdnqiWo=&taAf5lUsZfofd=&iHVzCUZcVcoi_=&7FUVsMZfmoWql=&3gkc3kWmrZYps=&EQjTxoXlspXkk=&wbu6MvYkkcXlm=&Gmt739XqUmV_c=&edLzOoVgZqrmj=&ZzARaBVej_lmq=&4abBi8Yjpaogp=&xbOE6LZmioZXg=&bgvTSAZp_ogpZ=&fhRkz7YbqjWro=&nBDwTVXe_jfUj=&yHmXC9XY_kjjW=&GHoQyZUafraj_=&dopT_gVXli__p=&Zfeq9_XomUWkk=&hfKOtfVdcXnmp=&GXBKepUlglYfh=&HmfSlAUZscddV=&ydjJBIYnlqcps=&N4zEKLWgoljZi=&gE_oEmWYnmhjs=&hSXWsZZdZVo_a=&jIAXKhW_VYdoc=&nh4NYdWYUUcrj=&DZT639Xfnflpb=&if3VqUVaqfamj=&zCWMuEVgmboYY=&FegQtzXbZgagf=&FlE9JOYgZriWm=&rv6KUuVsfcY_s=&WSLPIRZnedYif=&UlTGNIUVUpfUj=&VkjDVeUog_nmi=&MP9T3NVU_kshs=&OvXlAVYbfakps=&m6_A8mXehYXZZ=&IIoSloVacfYXn=&BqGnwSUdVdkig=&4NUnvzXqWU__h=&dDdP5gXXoXgoi=&6yZkXZYiq_nqq=&Z6r7v3Wijgfpq=&avLt5xXXoWnoc=&RcgCDwYijkfaf=&AJdaOnYhUUffn=&fBO4ufZaXnUk_=&OOGytRXZeh_aq=&HtTgztVsgZdqp=&VwTTMCVjskdZs=&iKfXj6UnUdjbZ=&qZyvCGV_WWVWn=&i5WNgZVWhVfjc=&EJwPRNXXndmqn=&xqrGYKWsdsjmh=&fRc7PBZj_dVkV=&I88tWcVgjkZdm=&XnoZgVWkcgZrZ=&VAOMwBXXjrYeb=&d8QlR4ZsfWfhW=&sp8YUgXrgksUj=&NKBZH9XssV_fe=&uyslcVUYXYici=&vZLDXHYdmssjn=&RBGRWKUdifh_l=&OyBWoEYbkUYir=&LOuhlnZlk_Vqs=&cr7xf4Wcrocpn=&vLPQMwYcVkZhh=&HU5YYeYdiiVlX=&7s2thJZaegXjU=&sz_qafVpYeh_U=&FqTzPoWoXlfqa=&bIJrKeZ_rVhfj=&Aoz5uQXnlkZnh=&W6TLGoXVclZoU=&vVVkUpWfUhZhZ=&HWaw7cZgaVsga=&deyWKhWrpsmX_=&keREoAYcoZgho=&u7FeQiWmmgelj=&SaEFE9Wni__Ze=&gCqnvtXkilrbW=&L7ZhN3YdojnWg=&OdlOtLYqoiiZm=&Hs7fxRVVcncdZ=&qur9VJWeYsrcr=&QcjchZWfrs_Zb=&ePyPQZUri_Wcd=&726SJ2VjZXahs=&BQniz6UpWUkq_=&cAQNMuZVofors=&8YTqqqUWcZoXZ=&PNpWCuWffasfn=&hoEIoKZ_rjXdj=&KmH7V5Yrdgrqe=&SlrXeaUjUYbYe=&Cc2PyJYcimYca=&xBb9BSXkaYeeW=&odB_RPWXUq_Zb=&8eA8axWekUVja=&XrW63oXeUnh_l=&xhEH6CXUbZonn=&W7aKsIYdaWWfj=&a8CZTwYondrUZ=&p_cHHiZXWUhUX=&hVwIdWV_lffU_=&3xwC7iUfsqips=&HLHFLBYproWZi=&_6c2YCX_llmko=&YwHioPWfkmbpY=&ATPIpwWV_kfeW=&b7brCQWXggWWn=&t55VftUjmrVsa=&JgfaysZjqWpm_=&gyHyrNZsXaWko=&PcqM8FVcaUiXg=&qDh5lwXUlgrWb=&CWLEM4U_espoe=&tesNaqVpcjbsh=&wojQbfWiffm_a=&xGdjjfXsZbYod=&_bAy7rYprbarh=&oid9xCUZbsrrj=&zpPvsRXqdaWUi=&6OQuOaVaomkqX=&CBpJ8mYrmpnXn=&OwKFrZXbVXpbc=&cmDjEzZidWVal=&ASmYerXcgrZef=&pMSxWvZdXjiUc=&bNX2a4YrsdjWj=&FjGBp4ZnhoolU=&aq2isqVisZjbq=&iodoiNUjXrgUm=&F6siuAXnapdlY=&xM3EqlYhkiUbV=&ov8URRWXrXgjh=&DBMsUGYgci_ns=&gnzcEhYmbnohf=&ZIqsouWmscerd=&e3m9tUXiYmWgj=&DrJOT2XanXiXm=&RpRKLsUjefWUl=&HFzdeRWdUrUim=&kxWmW4WZmUXiV=&yj3yfWWVrapnn=&4dGJ3vZZ_Xgpr=&4cEkmbVb_rrar=&rbQUMtXpjgelq=&KuxeotYdUbWof=&SeruvnWjbrdhn=&NRpwGEY_mVgep=&G7yOs5ZjbWVhY=&d8cRTPZXk__eq=&xJqYAsYZbqrmq=&q2tXMjYqhcbUb=&S_YpHvWYfgkjm=&FySHjFVVqbrkh=&YXi2raZailoZf=&V6M_AEYqspbjm=&HKx_V2Yjelcnc=&Yj4ACuZmXdXhY=&ctWW6OZj_bhZi=&UxWl_HUlYU_Wf=&7nV9rjYXqmhml=&LeSgVzUhlXYhY=&cy4b5aZhVZY_b=&xbkvcxZsiXVka=&Bi32zEZijlgbW=&KjFpe4WqbhiYb=&e7Nis5WVinjil=&3pTkIgYeVognX=&NnC3_JZlankfo=&l964wJWglWphk=&BpPJh5UebkdsW=&7nkTZDZmX_qlY=&3Nw8RuVmnZeof=&6qUgdeWdj_Unc=&iRWAA8WkaeniW=&fSPd3IVUfjrhj=&mlnCyKXUoZVeW=&EQK8tAWckVgcs=&qIVZqzWeei_Wi=&LuVIC6Zcgfcsa=&UqmIIkWcWZedb=&5yVFQxVsnUnoZ=&GpdaN3XgZsjbe=&Xfr_KvWdpiijg=&WAegY9ZdYasej=&b9znt6XqoUiZW=&yBzRSFWZmabbe=&2Wjf8sWl_iUdd=&kKqLoWZZeYdkX=&kjwGtsUm_ZkZj=&nx6JKAYcem_ij=&EUoJkjYXnr_ck=&XtJrRlVYac_hf=&K_ueCWWnfjjad=&WRCFOGYnoq_W_=&amF7gHUiVejZk=&RSzojiUaVrcYm=&8WepzwWabXnXk=&DLNMQjWYdaema=&Vl5OtZWkjhmYn=&iw5ZsuXZlkccp=&AhbOz6VUgc_dj=&MLcg8QXZhmami=&JaHchGWproXZc=&OnRaIaZWVdlXW=&D7f68dYkggqWa=&2l5WcLYnkqneq=&w5eD7SZqYpcqo=&OMv32DUaiXirk=&xFq9n4YrWmcac=&jxckXIZonjnVZ=&qKXtXpYsV_aWa=&zcoNPNZsZjUaU=&ZznLfHWhVY_ap=&KzfwC2VhWohnY=&ySHhRiVrmYgXd=&pknRUyXeis_nc=&cOS9vSWijrWeq=&amcvYWUni_qaV=&rzGodNZlZiphm=&ma2UcLYpprmY_=&9enynoWdgYbVe=&68gyV4WmfgZmV=&dAiAs2Xfpbgho=&t7Om2sWgkpjZa=&5wKPYBWqrUVfW=&HU3QJyVcUkqpV=&yp8Rd4YbYUpqa=&QaMEymWfle_qp=&fJ4RYkUiiVsVr=&WjittMWUfjjbk=&gZMGRwYZrfZip=&vg_AzJYXdngdc=&s5uWUvYeWggbV=&tdpcMcVpcpYbc=&jeCbCfVnjacil=&DDPSaAZhnXp_d=&EKPlMLVaUsql_=&sPaV2IVYsaimX=&NGaNFOWpnWa_i=&XctcMcUpXWeVU=&C3HyoZXhUVqci=&pwKB8yXnhgqli=&IPuxtZUngcrr_=&bU26wHVZcfYo_=&INzL_IVmeshsk=&Kq7rCoYhokmfk=&58RDtZWbcUhmW=&bhgQyRYZpYfls=&9CtN5tZYopdha=&_VyOCuXcXkbbW=&bq_UDiXoYeklh=&mZKns3XahsVai=&IqKqzrU_pmXjY=&mdcsCnWfqoXqr=&MkottWUlcaljs=&O_ayH5Vcleolr=&ZY_LZwUiZo_mZ=&Q3Za8zUUlrgae=&WPxoP9ZojnZdV=&HeXauaYZqdgng=&2FlnLKYdgUYWf=&BaoU9VYZghibW=&DsEGcsUlXegld=&_WyW9bWikqmos=&Ab3FzBWYojapb=&fQBS4bYalpYpg=&JJ9mHxZbcZjqd=&cMbmI6UcdcoWq=&hIniF4Yfm_pl_=&3LjNsKYddfkiZ=&IrMx45WaXfbZ_=&BMj7xhZo__jlY=&cQvRwqWeqZcrd=&XsdxzoZUZrpop=&aE5icOYmXYoqU=&O7wqoYZfeXgfd=&qZL9xbUUdhskV=&WG3CnRUaVg_YU=&a23XmuXeomnla=&vwLhlhZdpniVh=&_bbrLiYm__mdU=&pTdywqWmhZlaj=&hIyLUGXsdUjXZ=&8oZ26nVmjlfdX=&v6GYsiYYZqoak=&GrQZQOVdnhlYa=&yqAtjZVdfsmnq=&mN3YXEVqcUoXd=&9yE_UyYnYZoXW=&p8pGmGYlrjWah=&mX6Lb4YZaqrs_=&2hQrrqVmW_XYp=&ZBEbGoZnl_jsW=&HKJvXoYZpndsn=&c4pGx3YidYeZW=&tFhIFlZgfac_W=&_8ewQgXYhWkll=&IduEBhWdVgVgZ=&ptSbeSZWa_YXU=&MIOlPLXfiYbal=&K7o_RfVXUqZq_=&ev5LzFXnndqqZ=&NfUr8pYpjages=&KW4UlHVYiqkkn=&LMbhJmVqrdhaj=&6vAtsYXldZqs_=&HmGO4SYqckccf=&jEGrsxXXZbdZc=&eMFaUEYdqjcUc=&qSgQxhZjVpafe=&JTrFZMYabZb_h=&oYeG9NWqVdglh=&yEyDsbVsYXmp_=&SDzXhXWqfrqVd=&ZkYFeEXeVbkio=&hFw6KsYpXgcjl=&Fn_9vfYgbWgpX=&VIjpzjVhUWooW=&wPRahVZlfnpe_=&hvPkWRZaUlYcf=&uH9EQiUmipdVb=&ONyo9gXolZ_mp=&xIn8WOYnYmfYi=&HDshelV_iXjYY=&Iwv8iEVoYYWZb=&8cREtdVrefVgV=&eVa3F8Xrdjdbm=&d9oUyYZ_joZ_d=&Ry26hvUbchcln=&932j7jUfVf_rs=&Ym_njjUYaUiZf=&AcjrU7Vgqrdoc=&hCsXDaVhirVVr=&AJSbHdYnmYngh=&2Nii2SUWkjZdb=&4Z7WcnXcanqas=&M8EzKnXpjggXc=&MlM7m7Ukairha=&E27eTpWparbqj=&pcXKJdVhodqqa=&AIU2hZZmVUfeb=&53pPy8XZZnYYm=&XjJD48YaYZrXY=&3hZeqzWfsqgnW=&IVGVbJUdsUWld=&ttRSkBXXYphef=&uA8_E_ZgXacXr=&jXFy5GXjfa_Wr=&xeAhYQWilhnqW=&ouZluPVaYpbWd=&6ahxZCVeXggXm=&W5AcvpZdbgkph=&STQvrCU_kYoke=&I2DWJyXqXsgUg=&annHX_Yjkmmbp=&7q3CevVYcmWkV=&tAIEpXYfkdpbc=&XEKyR4Uehg_kr=&xFJMN5XgrWnUm=&bhKCGmWcqlYam=&c8gmQ2XqbhYUq=&HfQ_tDZhadjXU=&HTdj4sUkjjoas=&ABXjIhWaZkpmd=&PDQ4U4ZofVi_k=&eLEt9SYgbrWrc=&edKIhdXYmkecp=&LpuDtmVfkaqfa=&fN4FOzZjUoknl=&sCxSGmVinqbgf=&NYKxs_VVsXmaW=&JqKN_ZYbaYqYh=&dOYfweVcogbfi=&b5jS3gXjoipsY=&2rvegNWemaUgd=&Fvf7pxXcfprkq=&2Snal_Uhpr_sj=&RqJxngUUbkcpV=&2qCT4UUiemVfW=&u4wk3pYknkqem=&i5UPjrUUaUhdY=&aU72AJWiXYrdW=&72K8R5ZWZjrYY=&8NVL8hUl_Zkif=&GZkoooWcobWoh=&k9ocuiZWYfYcd=&tVLGjjYUjjXje=&yLHUlAYbonWaa=&yQZjlxYfajWbo=&rrK4RbXblgkhU=&UDzUhpYZjZVbi=&dmsNIbZVdUUgV=&wYNQEPZqUUngZ=&6bsigNZoXVl_i=&cw6v8gXosqbUe=&_UggDCUXYspso=&v_vP6LYjlZUmj=&PLggm3YqUrncf=&Mdcu5yUac_oVV=&MqzdhZWmoccpq=&2qUeNSUrnlWYk=&zn_vktYlakZpa=&BB7pKRXoqpibi=&UzbTN3Yinrkml=&TzoZkvXVYagqf=&YPIFruXkacnph=&J53hQqXXboZdq=&2LJYtiVWgibrk=&6bZMstUcdqehX=&MtR5VaZlYiUWs=&DrxfgvVrqobli=&MQA6DSV_mecWW=&nF6QiWWYiWXna=&2CKWgeYkWZcbi=&Urv3QFWscepof=&tX4uyQVakkYcl=&IQf5ohYqYfXUl=&DGul5KUgkgnU_=&ix_6WDXZUWZcZ=&BlANRRUejUeoV=&zmqdNeWqaehYf=&sCSdwQUskcVnc=&DgiVVwUn_qplr=&Ax5r3aZjcdeai=&zrtWzHVqehbsr=&UNIIdIXZasl__=&7XaXywZnnYkae=&wca_omWUcmmeb=&FGnhyeVVabghc=&y4aGCJWjUWU_a=&_fBEHaYliV_pn=&rrWpZyWcjhXim=&DvRCH7Vchrfeb=&8t5_S9WceaoWV=&cCyPklUbaaqiW=&kIM7EXYsUpYeV=&yMy5KOVkgmrof=&mlLcyNXYXWamq=&3SuJadWUpqncf=&Rl58WJWfXeekl=&ZHbhmrZnsnZem=&BaGYG8VndUkke=&EGbKvtWZi_aVq=&kaBmRAYkihlhW=&ktbBMjUarjmlc=&U9SBQpVgbilUm=&C8I6vRUjZinXf=&jCsLvvWYnssqq=&CYBaZzZjWbnWs=&OkAPjzYmcWibV=&UtXQY7YUhZrbn=&G9m6fNVhbWWXe=&KyBhtFUgYZofj=&JsMiCDU_lhrWk=&gdRUyHXm_oZdX=&Q7oPZ2WUiUpl_=&Hcx_eUVkoggrd=&PoeShnZhjghZj=&FPWx87VlskksZ=&nKEWXeUVaUfsX=&4qvpPOUeemh__=&KYS_aMYgWnlf_=&vK5moaZigZa_Y=&ZNepAtVepecbo=&YxEAluZdsid_Y=&vBENsfVmipgZs=&AGI24dVamaeXk=&Mb4x64ZUaphVi=&R96IcAYhlngea=&kYuReZZilqisX=&XSzwPuZVnhadp=&nOeR8DYjqoYfp=&MmQ9WUWZq_ojl=&VhQDPVVmbaUsY=&udHaYVYhcbnXW=&cjtAh3UUpclss=&jkJEiqVgXdYsU=&WZYmEqWacenoj=&e4qn7iUZcedid=&_Gbg3AUVXYgbr=&fdUqzpWXsdmcr=&YDO7yCZl_ZgUr=&G6VaIlVqU_hdX=&oOQ5PpWonhokl=&qtSoP7VYdjfnq=&xHiuDaWVemale=&S6najEYjXUerf=&8UkFxqXfjbcVd=&xh2u9YZZZfbri=&reGs96XXlVrVd=&DieEqEVd_krhc=&LLvDVlWqqZfXs=&64Rp2EWZjanj_=&cUC5OxZZYmmbp=&gDNlapXnljUjm=&TqfOBsWophkVl=&E9bfDEUigXlco=&CXody3UXimU_o=&BpPoz8UmUjrdd=&KvoKgTWjsakjn=&Ikws9KVWkgYhV=&HkHwjUVYlaZrg=&ds5b8yVjhphjU=&SBedMPVdglWnU=&oHrws4Xakrolf=&wpb66KVngsWgp=&_hmbKPVr_lede=&pSxR4GZUjcUir=&T3_pFJVkhWc_n=&h_yphzUeeVUci=&wYoGG6YiYsroj=&h92QF7UVXchpo=&_WqLiYWirsVhb=&SUTeG3Yb_b_oU=&Ql4PHlUYcemjX=&6D2TU2Xfsbekj=&YlOd5qXjcqiZo=&HoeSvoUdfpXpY=&pbsVdvXproqgl=&l5vaSDXloUesg=&NiXQdfVZWoajU=&takQoKWrkef_W=&hzuUPNUjhWsd_=&IC2qnyUdli_jU=&h2lkQVXdfmfWl=&uJPQmpVVookiq=&MnvE9_Xkablsk=&Wg7RGCUkq_hpm=&a8qRVBVXrjkYf=&CkTX2WZbZUWXo=&B7o8HdWWhjhhV=&TZzu5MVhocecW=&T_cFClXeZsYdb=&TYiYB7VnUYbsq=&RkoivYYrkpisX=&oZ7KqYWrfpUWh=&U8IJNXUWjm_iW=&VPu2aRZ_sZcVa=&jEiSxwYhjVpcl=&quKUdIXmaZVkp=&iRlaKvYZbinsp=&IHF5WqUjibdjV=&gFXcvIUmsYYie=&Dr_Z3HZkV_jpX=&O7IahBWjqWbVa=&hd_jmMUnkjXVW=&8SSKvSVegZonk=&uRz6GjXimnork=&lj4J9JZegldYd=&jg8svdXkXaXos=&XRttozWYkYgoW=&ZLa6GUZgbsYYm=&YtvtcnZfXm_hh=&axuxpMUrsVrWV=&pdd28PXdrrWhq=&Pxmb8FYhnfpUq=&tQJTfIWZVdfWf=&vyCZeHXbnsach=&gFVobjU_kUsid=&hztyQnXq_ZWlW=&Qi7lNXVbe_rej=&lAWnypZkWXrda=&Qaak3FYonZkec=&E9iBoVWsbnghW=&7c4RntVlYmXYU=&5MsShXZbsgfog=&lPOqlrVYgg_oY=&VAeox5UdXasbs=&2T9DKnXVWoceb=&TjNSFrZUWlYWo=&A7jEARVWfUcaj=&HeHK2WUYX_jbb=&Tah5dWVpgjcqr=&rkChRNU_cbibV=&O5reJoU_jZffr=&bLX3c2XmoWoUq=&zEOw2VXhpaYXq=&tWuaMgUlirjYr=&gFWaC5Vdcjorm=&Voa6AkVnoVhnW=&RUykc_Wfhqgqm=&wUPrssYWaocad=&_nzDLhYjgXksY=&HGcghxYWXjWag=&G4DLM9VhsYcrb=&LqyRSyYXng_Xo=&Yt_dKEVgaspgn=&Nmj3hGWhZksrb=&NubJqdYrpqXdb=&YCTgtTWbjXsol=&foi27SUmrjjlZ=&Q2vJlQZpjglhc=&gKNAmjUclserp=&LSdAEgWq_crdp=&45lcQ5Z_qcfdk=&3zStoKYkssprr=&FzjHTpWcjbjkm=&JpuIhuUgXabUo=&zoXi8TYglhnqi=&un8nndXbrgriU=&OvTkIMVVcUfgo=&k23aGRUZjfpal=&ED9aMMYinZiVj=&4YPJjSWcqfscs=&AcxGF3WgUrUYi=&ZVrwXAVUmhhmc=&XFjk7fXinnadl=&a6s5SgWfUbYpX=&vgqW3mVcrWapl=&3e4pw7YfVqdfr=&HfjpqcWjlfhod=&HhmjsBXbjjnhj=&lyMuAZYnZYeqh=&pgnlxQUUZbrXV=&opmjH3Zbqfbqo=&WmwovuWkq_ipp=&Si_QDoVpoZb_o=&WY7XOUYahWYVW=&3nDCQKZmjlnrg=&QfUXp9YaiWnbe=&RX7LZmYfWrciV=&bSwnmBYiWdsij=&5tYi9KWmofnXr=&FQ7mfWXrkpfqV=&ZeeITtYVqaZUq=&bEV4a4Wildm_j=&4mdutfXgnWnbb=&W33soHVkbnbiW=&CKuJZJVkgYZaU=&ofmhRoZmdkism=&bhOQzGXb_kmXp=&OW8mfgUom_rdV=&bda5ZFUWkZqjf=&5s5BZnWZZnjY_=&nsQj4DYejgqaa=&MDcmdkZdnpdgq=&WcqAqZUdeWiri=&36LFnjYmeqXhc=&2WBUIMXVbWWVh=&mv26xeXZaijcW=&WP5SspVdbXodg=&qfujwCZmeraap=&D37Bh9XVhbqbn=&vAHpI4XsqjdZb=&yrME9SVmfa_Wo=&mhJOQbU_UencZ=&zGL23LXinlUhh=&DHEVLEUfqiqoo=&Wr_ruDYkY_gem=&JscVMcUZaeiYe=&ucx7xyYmhXkpq=&CzoZQSXeVdksa=&IyYmgsUdl_sXq=&uqUy2BXppsejj=&RnhTLXXlakqoj=&rl9VleXXYmram=&JCmWN4UsXcfsY=&4pHns2VbsXpmi=&IQbphzXnf_phi=&Iha4Q_VUocrmh=&4LQIPxVfXYgkg=&zUmYJgXYoYYiY=&_3ocIUUVWVhoU=&QSqlagUiUgqfX=&l8Oqq7UUfcmjh=&7MYmQbYVjVWdk=&JKsLzCVqgVXfU=&xoptIGXn_apd_=&ITxCOsZhngidV=&P_cJmeZfsUsfi=&GNNz6qWYhehih=&blGWEdWYjUsVc=&jLtNpOYlnejla=&XcbmrWWiXcsji=&zBfty3VsbaXhV=&RtI5HtUm_XoaW=&GZESdYXVg_sWj=>uz8YVonnUhY=&XAItG5ZchXiYe=&C7L3SiZrWsbZW=&wJUhXvVXZjara=&E_pwIYWsoaZnm=&Vj7OJSXVWV_bo=&D7qSXqUciimpY=&IMWWWVWslkonW=&CAgzSPWsbUmoY=&GGN49kUk_anZV=&JHnN73XmfmUni=&76mSYoXomshlV=&FiiyqNYWrpkWr=&EHSYK3ZYosmrs=&MfT8vcZsh_l_g=&p3d9n8Ylbqj_s=&cGmqWgU_ggsYb=&5GOGRbVnsWppp=&YlN_h3XfdqfUs=&88F4UvWiYkbVa=&jHO9nJYXmUXan=&uvMaAMZXqfrmi=&88cNBiZfdVlpn=&wkorN5XfomrXj=&M5RtzwUpqsqbo=&wOsmEDUkimcpr=&H6ppH2ZeWeopl=&EVKqBfYbWZskY=&Fewo6kXkcobUX=&spMVLUYlaph_b=&NAk68zWejfYlW=&E8qylmYbZidfp=&ZijVmiVpegpro=&ymuQhHZWZfccs=&HI8QHCXsdXgja=&WZyz8HXXoposs=&qhVOuuXpXsdqj=&XqLKowUfocndU=&XVF6RlXcnqmcf=&6JSudFU_rZZeo=&sHU7ShVjbcZVW=&t_8hGAWrhhUZo=&7zBruQZdqmUnh=&IQSVE9YjlWaUi=&Dj4s4JUpchkXb=&eP5OSlZsqlhlp=&zJAhQKWlZhphf=&GSAaQLUbWpnXq=&eaWPtXUU_hkpa=&KS7LoWVngYbZa=&elyUrPWfecqof=&WpTPLhYqYmiYg=&gbeZbcVomksUd=&3Wqo2uXXZjYbX=&mrxgS6XpqeoYg=&Qz9pI_YZZdWlp=&C4v_HSUsX_i_Z=&Irn_tbYUdq_Xd=&5JgdEqZ_VkeiV=&jZ4W8iUabidhU=&iAmq7nVkWdfnW=&wFOLWcYWojkWW=&F_3vXFUj_fba_=&gJJcpRUVmWcWW=&vdCoiKXkefkba=&oTpmjnXeWoUeU=&kB2684Ysoafne=&wzCE3lZeUfmpW=&gkILWWYnrshsb=&A84CWkXUcfUkj=&wCLdHEXWrobbW=&dWGWwYXchXkcr=&VrvtIfVdW_gjj=&3vc56DXjkqkXb=&DB7Ym9VhcjskW=&p8H9QkZpoonZo=&w8DgAeYUcencU=&JVmarJVddhbWY=&GBYEBbZanlUfW=&_XLvLYXjVraVm=&rHJMSbZbVnXmW=&LfVNp4WjopVsa=&XxhiRqVXUUWdi=&anoP2YZmorehh=&VBjIOcWbgqoqp=&Hr6arYZsXhqZh=&huzU4wYiqmdr_=&yb__bwZpjbXes=&IPgEVVYkkW_qo=&H5fUclWmmWlna=&nwro2IYlaeoZY=&2Hgt5CXUUehfV=&gGC2eWV_UVodZ=&uTBllHUeUsgag=&ir4GLbXrlinmb=&DIBQgVZZcjdYY=&SwtYp_ZcqdVia=&cJ9RvIYrmqdfl=&nmDNaVUYkUekl=&UY2IOeWbdidcZ=&Yrbnz8ZgdVY_b=&RGOl3GYihbWre=&nLc_y7WZeXjYW=&IY7qCcVmWojV_=&2rkVeEZWWXVlY=&HouxCZWidbaeo=&hmBCuzUbderXY=&Qc9AmGVafqVgU=&VrG28nZqcXnpe=&JV9C9pXlZYjhX=&Y98yVRUdWXoYq=&uFqz8BVofmoVe=&jf4qMjVielYgX=&rZj3g7XXcpfik=&CsuCPAV_lqWZZ=&ZOu5GbUeqkr_a=&kgmZ7UWYWkVlm=&mSpS3gUgooYgW=&evdautXYVopgX=&uZV5raUlkrfkp=&bcN4MhXmp_qUd=&Qr7cVNZUopjVg=&pqwk63XroaiVe=&RapJ4MWUsfigk=&wsVsMFXjodrgh=&HVt_KZZ_pWgnU=&IbplQ_VXgnhki=&QZSNjaZqZfjlZ=&9PQudTWmsjpXZ=&lmfoeOUlVWpmc=&lIIzumZhockja=&eK9FctUillsYX=&S43qtOVWmUqnZ=&sF_kJpYeoplYY=<kcb3VlZ__el=&L_wfN9Vhfjeog=&SqwVMTUmnUVjq=&7wOEA7V_diWXU=&jtSAJTVlZlckl=&KH7owQUefqs_p=&kLmCakYgXqrhX=&eVAyHlVmnqfXs=&cg682RWYVrfme=&2MxXwlWXopYWj=&nDyZPzVWksini=&GgN2oHUXasUof=&eAOXhNYmhpjh_=&IoZly4Ybgnhla=&hZQwVBYnXcrnZ=&oBOEffUrYVmo_=&YdKAieW_ZihY_=&yOyrTyYUrnoZq=&QYBrf7UjlomgU=&HENhERYXiirep=&U9xeOGUsscklr=&M8bBbdUeogZla=&_qf9sUZclWkgq=&mdV_hbWsnmcmY=&5JgKXhWqhksVc=&f3ijjdUcaamVY=&csSCl3XaepchZ=&SItUatWal_shV=&T6TxGAUdgVfrd=&CJh_zpYhbYhmY=&orn8GVWmUmoVk=&kGGMU9Y__rqem=&FYAfT9ZUs_lVh=&97p4ZeZqXbVWi=&8RGeFIVnYXZWi=&OQ7cPeUZbcgok=&5xjqQ8XhWbkWr=&e9bOKgWVVYqiq=&gNdPDrVqnkYpj=&c6t5QvZgUmV_a=&UxGV7KVrbcmhX=&5iTTkTVZrfVaZ=&e_cQn9ZkceYbi=&Aoq2okXrWWnfW=&28WRnwXfjjpbd=&mqTlbHUVkVmkf=&RjRaGbZbjrWVk=&5tdW4YWlploWj=&cmhj2zZsaaog_=&KrSQPzZeZcXej=&eeQ237ZUaaUdi=&4kVaGaUgijadl=&ojXnOEVilfepY=&6OEm8sYcahe_a=&tZd2HuYqrjnnk=&FQQbtwUcqrckp=&A3M9idUqhasUj=&vVpLtAZ_gZmkY=&wo3lkaWoiYmhd=&NdniPzUmZmpeU=&hSi22sZX__gek=&9S7ZVrVdjjWWa=&UcvZLWYXa_lks=&oMXFRMVrakZWd=&hLXYxlZsccggl=&Tq3OAPZUchUZg=&ykvWx6YVkelbX=&qzYHdtWYrfnU_=&aZONKzWZesUZW=&DJUbPUWaUnaeY=&h_bGwlWqkZ_Vk=&3WIDXLWlVWVZg=&VVXvT3YppmZrc=&hLmv7RWhnsfcU=&yISOC7UjWmhjg=&ZsLTWhWpXngoc=&BAoL87Wlnsped=&Mt6a6BWpm_rpa=&xV_AfjUcaZfWV=&h7Oer_VrZhVll=&RyI7MtZoYolrg=&t8grTyXYlprVW=&iS6HluVpacfZo=&9_OuWiVcUhqbi=&jYta2tVkmoUke=&7hQ6LSZenXZfX=&SdpDJeXXcepXd=&Pkc64fW_h__ic=&StHQFBWhWmgkk=&CGhOVkZlskqsf=&HtJfeVWdejooe=&MmmySCXcdWrdf=&c7fz4hY_sdVlc=&LL4bQ_Wgbcgjj=&jS5AjCZhrpVec=&hwh_luVUggqpg=&EJUnVjUfZXliX=&jAruSOZXraioc=&UgBPOWXljkcpd=&YwGdxfXgkYmsf=&hUUr_MYardqVq=&oLOHLhV_iieeU=&YvPuGCY_ricse=&_IHPidWgqkqkk=&Z2FPWtYlleiZV=&FpaJ9PXjVqmbf=&OnxsNCZWUapWY=&fvTHPaYqchqje=&UtC5G5YoUsUZr=&5EkymFUmsrYXg=&iIPV5WVYbWiiZ=&DLGDVeZsa_jVq=&tDzWdsZisYfqV=&jr8dxZXYdYdkm=&fgRKgKVnWqjUU=&tyfUzVUkUgghs=&MVkNk8ZiWcpmk=&3Bwv9UZUWVmn_=&xREgSjUaYmdaj=&RzQEloZssnXbW=&J6UfDHYaqYaXb=&THGj8aUppgZpb=&bXpoY4Uqkfbnm=&3JtP2iXfkUjUg=&2k2zrwVYlerkU=&QBf_POUYmbUnU=&WwtkgSVdjrkjr=&vPqRaCZichjjk=&TPenD6Zjmsgpp=&gSl6rWXdVkgfU=&4iJDt9UUoXWWW=&MWc7FUVqpeqpV=&adqY9BUYUjraV=&YtqjuHWopZrgX=&5tARumYengffg=&t2kmHRZWohlkY=&ol5DzoXkqhqoc=&FKZrjnZqZsiln=&JsMs2aWrYdjk_=&YaDwOhYhZhnZW=&9o8UMCYffWcca=&keLqnxX_calnj=&OplRrxUcrWXgi=&OD73BeVhospsg=&ZlGCjYUWfq_rW=&XqiLLWWjWgU_n=&_mQ8IMYmjipi_=&yLrgAvXbqc_ma=&nAdb9sZXcmfoV=&fl8KvFX_Vpnsi=&yx7sMiWmsVmZW=&aGZ9jyUfYZoXi=&A_GUXMXrkaqjd=&illNQMVnXbrnY=&A7PlMtVoecofa=&XIaXHKUjgiXbf=&hIZOiYUdcWnaV=&iDrktIXjoc_ak=&VH9LgJZnjhlqY=&hkEopYXaloU_f=&duzYgHVsdUVps=&oXyzYzYfgWVmY=&gfiT7PV_kgdki=&aaFV6dYdelsh_=&wQI4WOYr_pqYi=&oBeUKAXm_cblV=&uIHqouZjopnjj=&gOMfQ2ZmUWbUd=&uzPPEyVZnfkim=&WctwlHYsaeYU_=&Li4gcqUmhrobm=&KQw8IuUiWl_Vm=&OM8UN2XnXlmnd=&kqfa_MWrijYdp=&Mqyz3AYpZVoqb=&VdlfqCYeoqlqg=&eFbM7VWUrchiU=&EtJevCUheVWlj=&AEbaZbXjmjUdc=&fnA2JjZbgieaY=&BGWwwHYdnsiWn=&LBIParXsbVhXg=&7vMOmqYa_goii=&J9f8QTWWlmepj=&rCI2DKXWgdcUi=&ZdAlHKYnagcgq=&uOmQn9YfXnomd=&gBJPkZYsqV_mW=&K6UA5SWcmqioe=&GzktlCVmirdXa=&YZwIDvUbYnhkd=&Zjn8vjZVbaddc=&kATt88WbZUibo=&A2N3NyW_YhVso=&CG5XXwZsrkfeq=&ME7w8kXXXlqks=&h3oVDMZiaepia=&fRR4oSU_sUeob=&2NNPvQUUpplsZ=&6IWt4yYVbepon=&KJh6cdXrepjlo=&ZMZeRmZslqoqs=&3AkkbSWqnbfef=&JAPGCyXkZVlrs=&MFnsHkZioZqqU=&PpssyHUYcZqUh=&xXreVwXUgbpmc=&v3MViUZqlsbks=&NYbLcvXjddacV=&ROiiEWWiVZapn=&dE5rbrYlYbije=&B5OAe9UnVmbfg=&oYRX3oWcrqcgU=&VqccavVVheXYh=&ggQ_4nV_YeZpm=&JWar3XYWgfckb=&LzE5k7VoUbqjc=&AE5Pl7ZkfXapV=&m87i_nXknWbrr=&r6GaTeWejpojX=&kiVKSYZrkjlnl=&ViZk57Z_qqfon=&k_iz6AZhsYUjs=&dijIuXXge_biq=&ZVwEqOYYarZYr=&IDtwboYjhonVe=&sxCbZfUdXish_=&4pWqJNUcelXqb=&qx7ZHDXopW_fe=&BhE5q4YlVhfYk=&dw657_Xcraeen=&i_tMdwUWoncnh=&D8iMluZsrqqpr=&AD8bMwV_dhUV_=&zE3DsDVl_gWUc=&ZfDey7WrVnZnl=&FZo6ARYbocqgY=&Vj9l4sWiXrcXa=&K4_jfMX_XWboh=&X29DxMWlsWrni=&wLn_jYWjkmjWq=&ldIui_XibsiXe=&3YPDhtYeiVYVV=&dStyUWXdgbfn_=&abTF2gZbknirV=&VGEq7_ZrVecjm=&gbsoCrZZjWpol=&FW82EkVkVokhV=&3jtbTBXfVVfUj=&IrEQ5vVsYsagm=&SIgFBhUrdYe_a=&zvOFh_UegjWaa=&cuC5sgUlXWZYg=&8eCEBZUagVlcs=&EVBhBwYVlUdks=&uelGLCUZhds_i=&vy8AI4VbljiXj=&xLPon4Wbhhdjd=&Y2p2fSXrqedam=&en8HuFUUWYone=&eoZJqEYpbkYhW=&ByPq8hXe_ngsj=&7iPBkvUbaaXge=&QOqEQ7ZpUsXdr=&UJpcieYrmqpWb=&Zf7cAgYspncr_=&nIp287Wkrhobs=&Gt_WqBXcXUWlm=&6rz4RkXUlaanh=&PlKhnhVbfogrm=&AB9FXOVhYrXpb=&wBoRjSUfeqsd_=&Y5xrGEXWsWldi=&YvYyoNVVifosW=&8fyJI7YrerVof=&f4Id6VUsXnZfc=&FnGoFfZjoqbqk=&AQ3joLYbeniel=&CWzm37YmXcXnZ=&MCNhmPY_hlpqX=&CbEqudZkUnqjW=&pO9QPJVesmndj=&3RErxKYrXdnrb=&cAK5JlXmYmlmn=&U9xRwnVilfYUX=&vvLoqNZegrpYY=&4yHKQAUYrZbnj=&ByvqsYWhdcVkW=&O5bFfSZ_gZUpd=&TqN_LqVcdYkhl=&Q_OhcaXXZXpr_=&X3HDrrV_srolV=&3n_C9oXmrfZca=&Gtm9JXYYp_Xph=&Z3MbAZYnpiVng=&_w4tKkYjimnYr=&QjxmVKZfbZUam=&K2D84fYkgf_oh=&c9itk9UZhsVps=&GBQdfVZoarUgp=&OcT4EtXj_afkV=&ZcPL4OXojgXoe=&gYCRpXWUscedp=&NWzBBwZaXWreY=&eAe2cnVmYZnme=&nizJ_NYiqbeVf=&uzqA5XYreUbVo=&dIFTxTYso_ekY=&9AShsZUkffXZV=&ufMlDZYsiYmhe=&zcdrk3WpjWbro=&OvOP7GXh_YokX=&urwocFWhYssXb=&kqzHqlYUhXfkZ=&DDk2kbXkapcof=&QsftOyZXdccbp=&kb7KC2Wkghago=&aAZou3XoooVbp=&kMYJOgYbkgbem=&sjzLonUfgkkVb=&nFwrVkZUjeXkk=&HP2SArZjdcUdr=&R_xdNwYb_jrpn=&ATeTGXZUeeggh=&_NVHe6YZcncXm=&gpLpjmXsWUZhq=&NkLwKPVckrmkY=&kpXynMZmZVoZY=&g8P7T5ZUZXhlp=&I4LM9EWndekVU=&hOPxEDYlrgirY=&smffk4XaZVWgr=&83mV7GUWg_glm=&HVlZLyVmkhVUV=&pnT_9WVmiYehk=&UmCUGMYeabgXh=&pdPixRYnebnaf=&gdf6ELVWmbmlc=&3kAHhbWrZjWnU=&nTWa_UUmnncbW=&kdBUvcZebgoaU=&BI4LQuYpbelbm=&wVeVbpVoXooZs=&vdFWe6Xjmmafa=&9Xq5moXViWjfg=&2F7ii8WYZdaYs=&QYqzmAZYdqgfj=&qFSgDIY_pgXbo=&ix9DhVVZmhrds=&nFh7L5Xjrpmcp=&m8fWDJYYknaYW=&_b_kuRUUVcWpl=&rpgxXfWarreqm=&urbpVXYrplhnb=&VCA5GEVUmUlrf=&hIAl77XdmmWmh=&YlZPJ7XscXfoi=&ar_EzEVbdnWlg=&yTPNwGY_shsnY=&3UwW25UadhYWm=&ZoMBkVYscsjbq=&y7PMCnUWfYXZW=&qse5ydZdjqkpm=&bCxf2MUsYrbZs=&twNjl5XUo_Ylb=&JtLBzmVjYgksW=&faQNIeUcjaZYr=&gdxXC9UosrYfs=&7FQN4KVskjqjr=&mL2hySYdhsbVs=&EVKlCAZarmc_h=&vFAlqrVYo_ZkZ=&js8zAGZlgfjhZ=&ES9Qw3UVYYpjW=&36rx_OXsVWUoi=&LdO5ndZrYiseh=&N4Al65Yjifhqa=&vJHnpFWlpYbjp=&tMBFyoUl_qbpd=&LtwcBHWWnZgib=&Tc9tHIWYsqsgY=&ZOvrI3VY_ag_r=&8PZwPtYjVrqhW=&TXxwtcVYofbko=&6yY4aSXZopZpc=&6IwE6eYskUnnn=&cguw_RWsmhmXU=&VnUzpwVsaeVaj=&ugBYMzVglppYn=&lhjImLXsasksi=&iuhRiVZYZUdsf=&cWqBk7YpVmler=&z4O2pwXqWfgcb=&uKNWvnZqpoVVg=&qd3G_yUYdkjpl=&wRLk59Voamnra=&HtYYpfVhZgjZk=&eFuybFYjfhkmX=&RqOabxUcYfmsb=&N6JU9IXkiUaid=&nE85iHUfddjma=&98UoFbVqYqmqf=&V8bEnHV_blUVm=&3BnAXqWfWaVog=&XxCOglWVckiqZ=&2UOqyBZZsech_=&QBN_tjUpjYkiZ=&ga3CDoYgbbeg_=&sZVFOzYcpqgss=&ZjPUHsXqZpfmp=&miLjBfZjUdbXm=&JhJ36SZaooaqU=&VdR2RcXYimYns=&BemwsnUhmsfla=&l3pvorVsVYgUX=&CWCL5YWckVinW=&xaboDsUmlVeUq=&5vHpcGUXjaisk=&pf35CQWeqWsXY=&_gee8qYVaoXjX=&49RS2OXlrn_ao=&i7AWqDWcUhX_W=&frJWVdYgUgrfU=&FssIOyXldpXVe=&w2snr2VddWiks=&6JLILWZcrccUb=&7G7VF5Vmksrbg=&3ZQKlcZrZghap=&yUK5qVUX_hUYU=&Qv3YfLVgpbjfj=&skJ5vWVXjZqih=&8fIeTYUV_oqbk=&BdBMjdWeUsqrn=&6YPviiVeZsgfj=&_Wpj8FWpcfpjp=&SoiaIeVacjnbp=&G_CuhsVgnossa=&JjigV_UUma_dZ=&ZauDLoUbWchlp=&H2PVGyWZki_XV=&5zYd5mX_eXndr=&wZ5zOcUdj_Zoo=&XRv7WtXsmj_Ze=>IDp2Y_jVg_n=&Sc2V5sUZlioih=&8eDLoWYkgpmej=&Pf4OkOWoqglWh=&u5beJ3VerrVqp=&b82UEvXsonnXh=&CVnc_mUjepjhn=&5lRNxdYrdckpV=&RkdGuqXbXhohe=&gl6_6hZ_gsjkl=&65eEWSVaqsskZ=&bWRLdsUiV_kcm=&3s_CQuVcZrYbp=&HEW4FpW_kVrZY=&AjCp3xUYdem_l=&_QFzwuVngiaUl=&24d5zAYdopfjd=&aBn2WHZmqjUkr=&ObyHvxUplqrjV=&HSBB63YeijWqi=&DR3AsnUdaY_Yr=&UDwm6vVXjVlde=&JrNhlBWhUfkfo=&NEWUJTWZbrb_i=&M6yJfFYqkljmp=&G2PeCoWYgielq=&Iuvl62U_YcVUk=&4KT4vkYamUklW=&xSgQNFXlUkj_V=&p9wJ7cYe_dZ_X=&m24lb4XVniiha=&QGjGKPYgWnnpY=&aBVivEYeilnhf=&zORllfUfqiYob=&F4XeQHVnrhYbc=&xiDhTOVqXbelV=&tTicJXZedUZei=&VFEFJXZbpZUZp=&_RnQnWWoqY_ga=&VQb3FVUqWbfYp=&AVp2wFWfWeflc=&dnNioCVhnsmli=&7xCypvXsVZZfb=&AaVj7AYkd_WYg=&nEmeRzWdpgZWr=&gvjeEgWioVfVo=&zBu3KzWhakqsl=&I36PCyXZWprsp=&bpsnRxUjXgnhg=&3ut5d3Zhgpagi=&4pmX3oUbYpYZb=&YWVIiiZpfppZU=&Q_OVXoWcXiYU_=&eyOyVXZklffZY=&NDp8GMZlgVYoU=&mu3wSZYjkWUaV=&dzi4PUWasiegb=&juJjR8UndrYle=&zxGh2uWrWcXep=&COIYpaWXrlcpo=&bAEHJlU_lYXnk=&8as4pAYpksbVh=&a5XqYGWd_fVbU=&6XVmW_YcqcqoU=&SyGWZ7Ugsjsil=&IQosSAXZmjnpU=&KVlYAuWejqofr=&9I7YccZbf_Xsh=&MmsKXmZkfVZ_m=&kE_O56YVplfZr=&ELUb2iXjZkrWm=&tXIi63WbreVdg=&vATsEAYroZXWc=&pX6ZHSZlYYbfg=&3GfP9CVhbbknW=&S3odS6UXWkUpd=&JX8ezuZjdqWka=&GXVWaiVXjaaXd=&atcatZUjknkUs=&egsEz8WheWqZX=&VfkicOYVefUif=&cgcLfaYkq_hjd=&ad6QFQVlUqpjo=&f_heWwWVYZbgU=&gghiDSZVh_sZd=&q2hwurYo_fhWs=&ssbvKiWqrgdof=&gHoMTKWqbbsne=&FEgyeoXYhiW__=&tnI24dWqfkZVh=&rDtNSrVlplXfe=&FTljlGXmagZnp=&V74HnwUgqqVUi=&8vokYKW_rqsjd=&okCgNPVfhipif=&X9Q4wdYbkkgdq=&EXsCuLWafUbnY=&aSstLJVkqfdiZ=&JizJqWWWcXhrn=&TKYQd5YYWZUW_=&fE8vKBVkXUjka=&tmvfwJWnrgZem=&fTBlxJVfWpbgr=&wxpj3aZkgqZjn=&JJhjR6XWrXmnf=&OLBnsAXVaWkpj=&HUfucTXrragqZ=&Xa4xmLZqjbrjm=&_Dq3AFYYehhjk=&sDqnEiVresnrZ=&FgL26aYlpomfW=&RwGSpYVqfqmYf=&6toUXbXYbfdmV=&ZvPV8CZsgWrge=&LuqB8PYdXYlco=&f4LdNKYqrYrfp=&uCbT9VXjkdXYc=&mp4DdmXYhdmY_=&hcBychWofelVr=&rjAu8_UWjjoVV=&LBpli_WagmZnf=&v8TUU_W_dahgk=&XntuHeXijlVfq=&35_DUcZmjZ_Wj=&QzfzXFWqbolcc=&TwOMEvXgc_oai=&dn7ypvZjYfbgn=&nDTcfqZZVUiii=&yRZr7lYWgjZel=&NneMd3ZVZgphr=&noBKF_YlbjZhf=&5jPXLEXkUfhco=&KHVdqgUglarjZ=&N9DaNMYeWhapm=&tT6KlUZrrllZX=&M75uQBVaiVnnm=&lm3lSWYYhiY__=&q_g9BtUgWopms=&KX7VJVWdqsfd_=&PQOzceZmXdjnk=&qUVXKKZfkoaUd=&LBHVSJUWleYVm=&uui7FYZahXoor=&LzDuZVZgeYeeV=&oesZCJXojU_qr=&3bxg2mZarWmm_=&IEUyj9ViZYipb=&StEkLAVroshsa=&WFrd5dX_WlqaV=&8FRBgFYWWbdqm=&AYG5fYWjdWsoU=&HCwy5cVUjXqWX=&ZnYIADUYcnXjb=&kSZ59aVmlfeiZ=&Mlq6GaUhjVbpe=&6zcWtdWclsieq=&O4SZ2_UXWgnph=&okiqgZUjdiZVg=&FIbFomUglfkqq=&fbcH6cZeUrsnk=&655T6WVoqnnbc=&LLYv5YWnbrXeo=&U4As5gZXrpjkZ=&iAXmgLVoZ_slc=&b8EwvgZUkdiYW=&_kQlpQZpspkcm=&ACS4otUXggeZZ=&vJAx4uXlscosn=&T5KE4YVcWbogj=&sYJHEiXceafWZ=&FOSNQrVoZhgih=&OtZMgVVpVophl=&mOiYFGWlpibha=&vqPIcgZlrroUj=&t6o3vkZhoefWj=&JVlEisUpqZdbk=&OUtGWuWrciWni=&SnKkIEZohpbdp=&AM2fqsWZmgk_m=&j3GgiiWjgXVrc=&ZeuT9TXZqZo_Z=&qt2cCAVjocgr_=&AZBvMVUdlpoWk=&dXFAJpYmnaesd=&yeF3BqXUblrqh=&4m7DRCWleUYXU=&7J_IFBZfVjXXs=&U9yJ5uXm_ZZsX=&fXRssMY_Ucjbs=&yYBssHWaabma_=&6uyXmJWdeViak=&hlE4XlUmojWsp=&kMl6g6Ye_aedb=&fdVK6KWderarm=&HevOEdZjelgVU=&Fglv3aZqcjggq=&CvTpejXXYsfac=&h5mzC4XXdUfsc=&uwlLRyVhkoame=&wQfQJ2XlpYgeb=&OUUAc6Ykqgfop=&vAdP8HXqWUiiX=&MFD59lZVliUje=&4T2Y5_XUimWod=&3yjtKKW_bikcq=&koglOrYWorsfZ=&ZNvmRAZeecdf_=&DhGb6sWsqk_kX=&_quc3pWXrsWln=&nTeYgzUVcVpZe=&E6p4DbUYaqefb=&OaFInPXnZohma=&uPux7nVpe_lcZ=&2JqPkFWqhhpqg=&BekKHOXjoWkqd=&GNBqPXUciqcXc=&S3sJtVVsVjfig=&dZV2TEWpdbUYX=&6TGWfDYspWrpe=&vDaSijWVcoZnZ=&TtLnueZkqkqag=&7ixy7jVgXeVW_=&vYHKwYXibobom=&gJmCYSZ_sUhnZ=&dxGxgZUccZrmr=&XA57j2YbllaeZ=&WkUzzOUVWncUr=&7LDwtAXZpUhcq=&HQn6c4Vpa_ljr=&PTSFgZWhlcikn=&2WpzZdVpaXffd=&f9hvd2XqfeqhX=&O8WqQVVfgnema=&CvLWZ8XqddZZo=&zjigNrVUZddYj=&uniu3VVoqYZgp=&s2fTuiVjpnpVs=&7fdGPtZqmcUqY=&d8ocdXViecbbg=&_QKJPCUkbjlcs=&rUHuq4YqWbkpU=&spGymmZqaWooV=&hMa3yxXmjapdp=&25fksmVscYeZd=&UOFdmWXbqlsdr=&oWGzgRUognnre=&dk9OGVYafb_nY=&35cQxtVbekqgn=&KTAMgDYcUYang=&_EVxlPXdnZYkp=&oCMfNeZedXWhn=&iOm_jaYXWVZiV=&RHi7NIYejnlpm=&d_7JYTWommWae=&jqHTEEXaZVZg_=&2gJqOZUXsgVgi=&RnjsDeVpajXdo=&EeUQnAXbrmsUp=&vQTwYyWVWsshh=&ziqnbUUbbWUag=&A8Kq2SWdmkdZY=&ISvsvEXVs__id=&Zx79DzZbacXbd=&TIGayUYjYXqcg=&xxkv78UYbmmpX=&NgXSfEXUjkmWU=&jKq6KEZfafXXk=<6qSsWhlUjVc=&kFiYNlZXpreqo=&gbhyR3XpcZkoZ=&alh5F2Vhfadgn=&KbPSLeVbbqnpj=&uS82iSWlsrchU=&5amBPhXXkipUV=&8UpNwTWha_rUd=&drGDnHZfXmZsY=&x_j3QLZbcsscm=&EP_HkmYnqmiXp=&PVignKZrmakVr=&p6ZuLaWc_iokb=&AhFvvmV_ojanY=&K9CySDUmkVgbm=&nSMhjYVhkWUas=&HEMBEJYfVbphb=&7SfIlzU_rbbdc=&gmrSF_UVshoij=&LZj7gIYcrabq_=&ghfkNjZehjesW=&VhDcoWYm_lm_f=&RMhIEdWZadaXr=&Z3ol7lUnbUlrW=&zOlbRVUbhafnW=&sftAGcYYZVWsn=&89KeGBZYW_Ylj=&rdU95kX__qnUf=&FJIDfNVh_dojs=&vWwBAbX_mXpZc=&cY3CbvXaZbjoj=&6gkX9hYrephWZ=&HreXsdWYeifem=&rgTJgJVpfq_dr=&CWS8FgXjf_mcU=&OevcYEWkpeWWr=&hD4O8mWsljfhb=&HKNROEZfYj_la=&bHzsK9Zanjgbe=&jwjHUwXXZYjjf=&AiHwzxVjjfUkU=&CqnWnRZWlhjos=&BKeydhXmUopsm=&rEEfefZpYiZhc=&sDW7vcZYjddmZ=&JBxZ8CXUnVood=&Pb7JsDWlbndjW=&8ZDoYKWeVqhjd=&5KYsYlVijgosq=&hhKmY6Xfg_emg=&HI4zlMUfiWgqk=&fuBqQRY_oecXj=&kvapyEVZcVUik=&p43SAwZeUpbnf=&NcBn_NZjjndhb=&HOyLYWXYYnmXs=&U2aM8qYkYXmll=&C_VHHoZ_popsV=&DOoUctZVcgoUb=&HPkfxsXWWYYff=&uh4tn4YjlpkYV=&dPlJsKXqhgh_k=&WZNhMDVandmnp=&bqdQjmU_kmnh_=&quRmX2UboXonh=&UceRRpXhjYmmr=&DWPu7lYrsggan=&euvoOaWlUolme=&dBGXpZZVascsq=&G8_vyuWrXoqZY=&RIWnWTVVgfrpb=&OvbqICVrq_YWr=&IbRjAKYjdkgrX=&WVknpdWkhjolc=&kRCc3ZUrojmdW=&5TlP6kUcnYroh=&qQ4C_dVkjWqnm=&Dc3erIYUmhVjm=&crIvHOVmkfj_d=&nJdw4sXXa_lic=&DebvwTYYYnWXb=&fhs3ieVigZVZb=&erwRiOYnYXcmf=&lZmCD5VcbpVaU=&47UBgBY_cXiof=&A56yjRZhZ_igj=&b5TCXhYnXrVpU=&xTtrHkZgVVlg_=&w5DZTYUqebkkl=&A4Zqp5Uoqipep=&DNqHXbYmdk_op=&XgiyR_UqnYnYX=&NOaMZIZhgZaoe=&EMyPOmWifbodZ=&jFgvYBZfrgqdb=&fHOgjGVVgUVfo=&qBGhckVbWVlna=&xuRMqkWaianWW=&vtqXOGZhiUsec=&jj9gIvVclhiWl=&PFiNfIUWVfnYU=&qWEECPXcXUis_=&KCSdnfUmeUfda=&XH7vwyUbYlVVk=&TAprU2ZlmqYbe=&rkksBvVigmne_=&yxPjj7ZbXjYbc=&pJH7iEUdqVn_d=&SXVosyVXksoZs=&4S_NzFUmVcgYk=&vgnnI2Vcaiiee=&u7cltNXcgXYVX=&6qtM6iVeeecmZ=&U3OYa9Yessrnb=&IfKFaQVcoqsZX=&HO_v7_UieZrja=&J48Q8qZlmacWp=&2HxbJvZWmUe_e=&JTWxUJYqXZVpn=&XtBGVDYVamjiq=&7D7zR_UfarqrZ=&_m3wlzXnj_oVl=&aeDHYzUiZgonc=&MGWOBaVrkqjsV=&CA2OxXXonbYjq=&apdngvWYoiVbj=&CyfXAGUZafgmX=&jd3_3zXeYqdmU=&9wBEyXUkdqrbm=&y3WfmWVViVcpg=&wPL5OSVleVkc_=&SPULIPWUYlfbb=&FZGJAbWqqlbns=&Fbuc5wZkgqqfV=&c_7srZW_obplq=&srKD9mWfZVngj=&zGGkarVVUfgag=&NjuTzkXbffWWp=&XFCXPoWYZkmmo=&Jo7XNBXYffis_=&u2bWF_VXlfa__=&eMkkLUWogcilb=&63kzqyXqfYVlp=&N5e8GMUZoZgps=&NNJcAzUoVZcsZ=&FAgRiCWehsmgm=&demBDTXpYlisU=&cgyYpWZVkbkYf=&ixwIVHWdsncqc=&TcuXSPZXgsgiU=&JLA6ljXdiUZjW=>cJoFWdWlnUn=&A5HmJaWobsdds=&IlATbZVjiXlba=&vtg3tlYWiaqYZ=&TM5HFeZpibrjl=&UUZw28Wdrfpao=&5oyCIaUplfsme=&KrkoqnVdlbpi_=&UUKMsqWiUgeXq=&m3vTtBYpkkXep=&2lwJkWYbslkcm=&WtwgNzZcYcepq=&BPqpdRUmpVchX=&AXomhgZVllXas=&79XuUpVp_fmiq=&y5pbc7VUhZigk=&JmtR4DZnijf_Y=&tTWrEZVoarpUY=&3Zy9nEUlZqocZ=&dGXefxZpkiZcY=&gB9cFxZVmpgir=&CXySiFYmXshWd=&bbNppCVcgokf_=&RYZRcHXVcqafo=&eesXTTUfqao_p=&mDPTd6Xfjkr_c=&mKJlQzWeshrYm=&mZbmoSWrsUUYW=&6xalC8Ydbqamb=&7e6MAgVZsqoYq=&jTzbIxUgYdobk=&qzAhBbYZljioo=&x4g94SVpenaen=&Zx8KNvZmalmnr=&xJZg7CUkcYqff=&vfKs4tVbpWmqi=&aGXOZqXofdlmd=&JLMNy6WUYhkjf=&g6yfvtUjbUqal=&xzWZOcYjnqeXZ=&q83HByUrXjhUi=&qagLJKYeVWcUo=&FRGuYuZnhnopk=&hsNpsjXXUihbl=&Lct2LxZjecckq=&C5Bwg8WdZmkbi=&7WDGGlXgrqsqn=&_oFkwbWapaknX=&XhUxOpWoZg_aU=&BsHwRgZkhffme=&f5eGDtV_ekdoU=&TSLCluYdgVsmm=&DmrOAZVlgqfbU=&KEMWgJWUY_eff=&77cNj7ZsWdgbs=&nOrDjAYsebqbl=&Qpw7V4Vsqpg_k=&VkjGB6YjcUa_a=&gGrFXSYolWgdg=&VuBSgYYXjXorl=&XefcqyW_pjkmp=&YabfxwY__kjlY=&ZiTDi_Xfdiopc=&q7bi5iWUsdhnp=&fTjWONVVjj_Vk=&iaMsOsUmrabVW=&scVUDhYqdnnqr=&AHM4VxVVqqkji=&WVznOyWWjYUsd=&rj7MoAVfcafik=&U9XTY3VliWqrY=&udTBnCUdpWVs_=&WS_HD9YUWXUok=&4eUBqaZecYXrc=&wn4SAmVjjenpm=&QO4hp5Zfgrlso=&FKJsfZYolmgiU=&FtRT_gW_Wgjbb=&Dvm68zUammZcl=&zDlOR7UhjcVmo=&THxqnSVsrUXYm=&CSij2MWccaeZe=&7uBmAHYUceqne=&RaTtRAUgYnn_p=&VHxofKVhho_km=&FkIwBqVflg_Ya=&H2IaclUaiojVc=&DYzHZ4YdoncXV=&xA4CQOYgUapga=&txK_WzUUXnnmj=&5wCc2rZsnZqeU=&jNrEnGUaZqhbg=&Fx7haQXhZh_lX=&matXkBUqYneYn=&Imrsf4Vicinqi=&K4JCbiU_knqkj=&D3Q6MjXcXsqrr=&ZKsbyyZhgfjXU=&OwNF7QXmlgjqk=&vYP8k6VorbaWo=&7myHw8WqpVjoe=&9l2hcbU_mWaWl=&9DGrvpYUpkqUe=&JcjJALUoqmphl=&KYWARKXhWkqYW=&b8eXhPWZabWog=&iSuOgDYXVhgns=&oZQyG5Werkced=&NSNyIGXjksaqr=&yrRGmdWgncseV=&B3LQP4Y__ifdb=&ErnDV4Vl_ppXj=&Uwa_kQZijrqY_=&3ecIPnUbcXosV=&H2wycDXZrVmii=&2AI5PwXZlXlZX=&f7SJacYcnsXZU=&f7P6E4ZVfaWrr=&25pdq4WkZUodX=&YMNeHsWbsUerj=&9Cwf8uV__laqV=&Rr8kMcWnbiall=&4SUSIGUonZipb=&Nz3WKhZlljYdb=&n3fqxtUeUfqXn=&rjfk9jYnkZpVr=&LYtz6vVfklqfs=&tz9ahqVdXkqbc=&ezVkPfVYfginc=&bf8II7XYmeloY=&GjOyI8Z_WqWYW=&IHl64HYneXcrn=&hbVZ2yZWhldok=&ioBTD_ZokhqYg=&i8RbIuVnbVlZ_=&BcfTbwYYabiZp=&njMK5cYhkijch=&rrQ8DRUUpVimY=&RCorZlZepXbiZ=&I2fZLOZXYhhqp=&M9wHU5XggVZVq=&32Udr5WXkfklh=&Ap_qvCVdnrmcp=&KOiaVaXooggV_=&wguPziZrdmXVs=&jyM8EzXjlpqes=&Eb8v7pUjnogeb=&hBqu4yVoppjjV=&DVYSNIZfZgWad=&ShKm5QUrddbhp=&zo_56eXjZr_kj=&rhHVVVZ_dq=&c3r7eEXokd___=&NBO3ztYXnZmcm=&NoIgnGWmmhUq_=&rGw4gDWVfnhrZ=&PZJWgTXqlnpgp=&kw2TeGZUrblnW=&M6F6GEUgnWWsh=&fv_APkVZWd_jc=&tZgNKuXrlogip=&Imku9iZY_sWnb=&KUdUDPVcYfYUW=&eGDyWCYsYrdkW=&kO92eLWnpfmXV=&XM2FRZXZikVjc=&TLPGcZZhq_qnY=&xODYCpYfibjWf=&_RKtosWrbnZbi=&MDAFwxYXdbmX_=&JHzjl8VlWsmib=&Ujo6WeYpjjfrg=&EiLzfwWVjW_Xb=&azRAz8XbbUZeh=&2smkbOWaYeojW=&4RynrjWjjXVWg=&vXCn7WZjYbpcs=&9SHSwhZW_bqdc=&L7xvldYZrUnZk=&C_BDcfWlbnscl=&FQjQjUVmbil_h=&Xv72sdWWmkdca=&FZocYqWampgqq=&7m_OPnXdekYXo=&FqDu4EYcgqanh=&HuGgAkWqqnpqi=&IRYzWfWUW_gVh=&hRMs7uXWgpZXn=&rmnnvuWppqVkc=&dR48AzVoi_asf=&usVP9EYqecVXV=&Hra8kcVil_r_f=&f3Z6n6Xnemiss=&v_7vKyYdajWXe=&Dk8zEWYrpskdj=&8ROg2BVYd_Zff=&qsSjmfUnfdjXq=&7_NxxTVaisYhl=&z8CK83YVdnU_l=&io4_zLVamlUqc=&PpUgLvVfpbX__=&LjGTmWYjrWYWc=&lvIoUWXkfhklb=&I_SfS5XoiYYWj=&CNVeSKZkYjlkm=&_P9Jx2VoVYpmo=&gy4OoWYseXqal=&VDq6YaWecomln=&4wQQwRVWrjhmV=&3ppr_jYpc_lVa=&PxxJHZUaWehrj=&BdcpkJY_qhZkV=&bKEDgbYXdoghh=&KyE6OgUhUrfje=&rdbFXTXmkfsoX=&O5oYStUXnsYhb=&IQpI8eZkkpele=&QJFlv6ZdXpsdl=&mxeEqwVmdhdfh=&fCKn8dUslfXms=&xkkl8fXcjVfUb=&LQdv_oXmajqao=&4qKWwxXhjpbnf=&UIaYeDYsbZYsq=&k4JBrKZamnlUe=&lYWhP4V_gVorW=&8h_3JKVhlXsbl=&uGijYfWjXWXsg=&HMNZ9DWqYmYhs=&pLrFg9VgndeYW=&2zwhMZUYaol_e=&7WVKo4UWfpnm_=&LOFak9Vaoofcn=&ony2RIYcomXpi=&GMoLDdVicVpVi=&fBRf2uVnZklpZ=&CvNeepZlqmojX=&rpATy8WcWkqWp=&COjU3CWkqiWVl=&gK2SEQWdmcs_Z=&aeL9IiYiVmYf_=&vtDUGTWjirbrb=&ZLHWO6ZfokaqZ=&3nZ4gCVWWgYjm=&yJwPYmWkidapV=&jQtjN5VklUUrY=&TBHho9U_dd_ro=&rYr4dEUgaYmop=&dqUmOVZkhddUd=&GRczrCUXohoga=&nrpUHGZjcdWok=&eR6h3DWbqhWeZ=&JIx8YdVkabocn=&aOD6W5Zcao_rb=&SMQbNiXogabds=&SzKVvxZcnWed_=&fraJx3ZhrcWoa=&i5okdMWqkoopj=&ZSS7ftWqXnqjn=&ZGb9S7Uanbabc=&e8DVvTYrjgfVc=&bMOSLqZoibcUn=&xveSMjYgXhrYh=&asBvUAWWZfnWa=&5Xj_YqZbaYgor=&9QaNVRVnqmrqn=&6SNzxGYgeioUj=&2GiqfOUdYcXlm=&R_o8qNWbblsra=&IS8AyXYhlXghh=&PHTMUCVr_nY_j=&ss8G_jY_Zpmgj=&o84hYJX_hbiqq=&OLO8DIWlnrele=&YQjregXka__lZ=&wrKzFGZh_ddbV=&Xm_Od5WegahiY=&GVFWTXUXjfcmg=&Zivlv4XbjfZZc=&k652QDWaUXcfe=&86Rn4xWncpUnU=&2xCfzOXXcYcbm=&HTuMEVYYnglea=&9COIyzWgmUWoo=&VTiKS7UoWYp_i=&OavRXRZoonboc=&K4VlAXYkomdWs=&mSI9UjXbeVlWk=&qBkp6LVleZXqj=&qy2odfXUkWZbr=&MIdFgcUhjUX_Y=&wY2cH_WbipjnZ=&rRRN8tWhqeloZ=&NgCLkCWXXVaeW=&mGU6EYUfoalff=&zsYBY4Vhiiicc=&GwMku2UpfZWjg=&ixHacNYmeZWnm=&jaVCPXUpXhXpi=&s3gXxmWkdnirg=&f_PxhVXoWfjhm=&2PNjBgVfmYnip=&c_uUafUYaknd_=&2D6fj6Zjk_Wsh=&Tnql3sVbqYdgf=&VF_onwWZfeYkW=&6GupeBZnecUee=&itgPFbYlaspqp=&cwBxGTYeZUUeh=&RBxigSUjjqpVi=&aHj9L3WjjsYlf=&HHVailVpXVqgV=&43rebPYiqaXbd=&AANFHWUniXZap=&gLepo2VsWX_dp=&3iRapTYjmpeVh=&9AG2PmZqVfnWZ=&OIGnDsXgdenco=&9nsiGlVskgbij=&E4DAYCX_n_YUd=&sQt3p2Yl_gl_g=&EfdX2CVVhpYap=&IcDB6LZphfgj_=&eVoNr_WqWkqma=&tFWMTlZapYWgZ=&YE9RhtZfoclml=&OlBzknWoclhnY=&a_MxZMYhhkXWg=&a2zVGqYkjWUsn=&Nd_KHnYq_oVoc=&9lj3OkYpZqbpn=&dZIoRbVhpsZcd=&uBn52hZfXXUoj=&fyiTujUpU_XUo=&U_ZzpVV_ZaqZc=&yU7YEWVnqbase=&ZvLoDcXkpXjmV=&Wx3bsaZVesjkc=&8w7yLGXrrlVeY=&Ui32MTWYlmgXh=&OmMo8lUVZbgsc=&8_OvnOWcVdZbk=&TT3ZGLWjqYrds=&IeE8F9WkZspUn=&GW3PsuYodZVhg=&JQUqFTWmeYjdo=&okiEjBUhjpoVj=&vjUNLQYjnlXbe=&OBjjeIVihsjej=&Fe3UUfZnkXjcf=&iQUWYoWhjemkd=&RBkxcDXo_UVds=&3KrxOQXXhfprZ=&2RPVVSXcodfWn=&8av9JoYVkWWVs=&P3P9JbVYclhqs=&qGdjBXUqgYkhW=&Nqmw7UW_pYi_l=&7b8qoDVoZpajk=&eV7NiwXXkbpYp=&yowXNfYschfUW=&gUJTPNZflV_gn=&ETgSNoXcXWkWl=&yiHMY2XkoeqWW=&OCKCtdYbcXgjW=&K6QSAcVVqlgkh=&p43dmgYdVhWiX=&YtcOlCXgZfVda=&ngrNnsUmXWbZc=&vNxsnEVgYeXgp=&mRPJ_lYWeXYca=&oRrfQfYsahqrh=&TWa_rSUroWZbi=&wTXoY4Xalpcpc=&d5HxE8YqeYdUk=&ZnJCVbUjenenZ=&KvqWvnXbZlpiX=&iSJp_CVrnZcob=&eAzXwnVd_ejeZ=&wvAZBzYqaXsdj=&pRtSrmUemiZ_g=&PD8uGfWhgkjla=&xssm9qYUYUjsh=&i4yOZKUjYY_ik=&T9hddvZhhmeid=&hPpKtmWWYmrkc=&btbFgdUYhdVYp=&MRwDjeUnaqdXd=&v7mWTOZdbegdj=&XdtL6dUWUVrhe=&Idy6koYbZjmUW=&nBo4LoZebesn_=&CgcovWUpoq_V_=&7j39yRYqXlZca=&nae_gaUZjk_mU=&Zehy9lUoZdpYV=&8uvAIDXVgkXho=&DvcDWaXeoeasl=&MzcVglVfUsbdo=&DtKKNMVqrVpme=&oLJop7UUdesiZ=&zSPfyhWiWocVU=&F7LyenZkZXqsr=&xveAuvUbYcgdi=&DMdRlUXefYYlm=&yGfIoCWeanaYr=&gP8FfWXfdZpcY=&s7YZzGYemjUss=&492kplXrUaqhq=&ddlCVPXZckfhW=&MX28gWYmdfder=&PdrFbRUobXlqg=&FF4pYsZmlcsoV=&cqgnzZZhmVkid=&zoE6uzYcUUcUa=&wEnb_CUsfpZVd=&LSmc3cYjkpZbe=&VGwcmPVefil__=&lSp276ZaYZUsh=&iC2qftYhUjWao=&Q9PTnKYWarkqX=&Nr2JEAXcqUhVo=&_uuLIkWjYsVbb=&7DBlVrZWkZolV=&v3I2scWWlgfpU=&5qXVNhWZjgiUZ=&7dlx9wYkjaUdi=&vlGMPAZkkZrVk=&z8UxgeYbdgrl_=&OPHxthZZohUps=&qMwwnCWoobsjm=&VVLhNdYfdYjos=&QpVUJ8VcocaqW=&eFktjYVVZkZhr=&xHz9aXXYVklmW=&W7hiJnYiadXXr=&f2lxhXZWbhqUi=&LaXAxBXWfcgXo=&LwvFARUfjhiiU=&GgVzazW_eqZUf=&VaCTY2YXedZna=&pE4lFNYdpgafV=&efEZjbWcpekig=&BoV3cIVnj_ofn=&ID_DOZVnedYor=&qB5txXYYpbUkr=&qLpkAPYdniglj=&GydCxxXlY_peZ=&fIGcHcYmVqedb=&N4O7HRVUgrebY=&mpuhuSZmhepgU=&GuvPJHZdqhXXa=&bP_AuZWmleXbh=&zi5DTMWUpogls=&m3P2JUUnonnmd=&I38UMGVVdmhVr=&Eg8WfsUimejkU=&VrX9fPZlXkkid=&hhGUmwUUsWbZn=&sbMchvVphZkZh=&veEigSZpZnZgp=&IT7NQPWdhqaYi=&TTkxx9X_nbqeW=&kvtVTsXjqnVWV=&aRqhbNXWnqYlc=&BiuYpgWkhskiY=&F2C9zMYZomWlc=&adoOKeUdmWrca=&5BAbtlUllpasm=&UBpMKJWoelWbm=&ZmZ67lUnbXXWl=&wWZ535VrWmafn=&DZIcvAZel_sXX=&rVFdwQUgsVagq=&CygtCHZikoiiU=&K4AhEYVaXfbXm=&ICwKNsZndYZkg=&22guF_Ufpjkno=&3UeOgVUcrfkco=&39GhJAYXhjXlm=&XksXTaXlaafkX=&mdlVWcYXlaXbe=&KwQh43VYUegck=&xryjQJZgaeY_U=&_ILstMXldU_hr=&ZINS2oZscUoip=&zOJYqEVqjjjil=&_pYxFpXblbinY=&iX2YSmZZ_cqgd=&TkRJwJUfgoifr=&mCfkNiZZm_Vdp=&cBSNaxZWlbpbp=&EyWXKzVsfkine=&TU6_xwZknkfYd=&I44OuGZZmgkXY=&CiF4i2YVbUiWU=&IZYfa_VdVoac_=&cNOmz_UdYmaoY=&dIoK_dXjYqjaa=&sovwjSUeqpsWs=&tPNJJyWWobpbf=&cT7vJPUokVWXV=&Et65b7UWnsnVl=&zJYToKVeoUlZd=&jOp_lEVnXXZdi=&MYQMyrWcbfddk=&KdocmsUjjqkqo=&VKxQ2RUkikckh=&VrQO2SZhkbfZn=&H9sExpVnqoYVh=&V6FVOpZbaYVod=&LDPvGBYipcWZY=&HIZQjJWdaojUX=&mEueNpZipgZZj=&lj__REXXlcX_i=&ZUFVqbWZsgXsh=&wzQAucVZZjgfn=&vk59ocYqjndml=&9WAfoEXakqUkX=&TXSDdgZZ_rXdq=&qgODehYfXhZXc=&AifmCqZeUpeia=&_ryyn9Zsebjim=&cTLYchWUqXcdc=&bGIp4bUrZkpWi=&tpy8wIZWpXjnp=&6RSUmeWmdo_Vh=&esDRL4Vnlcrql=&7wNEGtXVhZWja=&77DsopYdkeWnf=&jxNS4vYbjedjY=&BmefvqXqmeqde=&dlqI2_Whpbcah=&EW8dxRUospflo=&V2rQBvWdhYWo_=&GNg93KUbVUhjY=&n5DhmlYsVheYd=&9AsqhlYqharWZ=&wbEQY_WdWdeYe=&8ZuPq8VspnXqr=&cn_zbKWYgbYr_=&PWfaWgXVipbZi=&KucoSKWZmWkpZ=&3YF2USVflfjis=&cnqQ_WYjWbrsZ=&lU66PpYhbooYi=&kIEKUYYc_rqZh=&nzxdS2ZasgmYX=&nsn_j4XmmVkhU=&qsnskjWUWefkq=&FWrU4pUZliajU=&5U593aXpWenfj=&RtYMDeVkiseep=&Ysgzp_XfVmfrg=&UfcPTfXVnmmnh=&iwtCQ9YobjVX_=&IrW2wpXeclorp=&RH7W5ZZYgXabf=&FQBLi6WkfgmUY=&xjfMIIUlpfXdl=&zlVoOmYqYcfsr=&SmmojWZrpYXjV=&tN2bGAVhekr_c=&Ll6_b6ZYlsisg=&bc2rlkXfbifmV=&DVih27VfebYim=&AO4gWqZeigakh=&gR6N36ZdXpbjj=&vAlkYrZsYajqe=&_RsZeZUbkjlpY=&KDYYHAZhbXdiU=&UwsZWgZcccpnZ=&zV7nXTWolamlU=&wEsoInZkgZmii=&2FPvgEVnndbWU=&nJpJSMZZcbnXs=&mwJjUOVZiqXpb=&bTCoDWWYjoVkg=&Y8zvdrWdUadUm=&RXEcUQUeZqiia=&tfcXOHZkmdqeV=&SD_vaaUa_ZV_r=&UUbRBVXfWYrgc=&yGtVL6WeYkcar=&OZleDrXassXUr=&u8Fkh6UrehrXV=&fEqcdXYcr_mdm=&aUeDYhWhcpZXX=&P9tlYmVcVrjdr=&QADLABYdfVsVq=&uNhLJDUZdVjXV=&XE6eRSYUgbbnZ=&zgVTYSX_Yrhlc=&4fj2EGUsWldjo=&kktWZIXbelcsm=&MnLafAWo_smZd=&FwoCzSZqgUd_X=&Kt8S7NZocZZls=&IhKQDuYeehaWU=&h9Q6fwVYnUXqd=&LOZJtMV_reUhU=&8IJBvUXV_qggr=&rSK4bIWeZeXnZ=&M4Yim3Xjgefde=&KBS_tuVrcZkci=&8JF33VXWiYYm_=&9q5Ar3XlcmWqW=&JQB33NVXbbsso=&rYdFRxXrpZcpZ=&zkiagUZllmlWo=&KqafAfXnp_i_e=&OWOIWRVlcrXhl=&kiCcjvValagXU=&FztYv4UhZoofp=&aDoQviXViic_l=&3pVbWoUUgdhhX=&FYYNbZW_fmolf=&6LKHZTXciYlcY=&UKEhFoWYscqjg=&HlnEAeZZqgVXq=&XztcI9YX_dika=&KvI4fhU_ognY_=&EdckYaYjZZ_mh=&8NsOlUYqomgqU=&uY4feTYpbneif=&jGU56WVmXiWhq=&wWhHq7VsWoVgf=&kXJo6MUZXgXji=&BetOY3ZreUq_h=&YqLGpqYYsjfih=&Pp_osDWmfsqiV=&C9U_ijXolWfmd=&kX5O5gXqqpbV_=&aGvXHuWk_pkhq=&HyYROMZbZbhkU=&VUIAtKZZchorp=&vXQgs8WhVerkp=&oflcqiUYcjsog=&tyJ_OTWqn_bnp=&iB4MizUUXoiXc=&wwEInuWWVbelX=&FsLeUpYbjVnmo=&9NIRzUWhgoZpb=&CE99OBV_VkYfZ=&V6xgsjVrhcefX=&d8msyeXpZiWaq=&sLJ8vNYgoYipX=&kHCeIbWqcsoan=&m6s4IPWVmsads=&5HBHw9ZhiVYcZ=&4jEiWzYnehgfn=&HsrJTgYg_hkie=&PECq9yVgldida=&bsuQVBZgakkVU=&UWoQdvVpeadsU=&dzL9isYfbmdql=&ZGzfmQWmf_arW=&cHHVKYYhaijnV=&BdrJ72Vamqrfr=&vS4ZzQXjgdcdd=&whwffOZjfYamr=&gwxyurYsibqkU=&A46fPXYfnonrW=&zbUtEfXighcpa=&_gNVlsWpmYbsg=&Ps5Cj_Zgkjrlf=&AuMEFDUVnddUl=&BGkRdRWjUaVqn=&qTKe8HVq_m__p=&Rn8zNxVa__ZfY=&T8O8JpZpZlZni=&EkkXrbVjdlVil=&JClvLmVXbooWU=&gp_pQXXkfXmqd=&LvdqONUcpjdaU=&JfIXWoYkpmbhr=&_FcNnKUacilWf=&ZVO8l6Wkqmkq_=&Od4RrXUW_eXbe=&pV3szrWpmlfnX=&Ut9LoRYeYfpZr=&D_ms7UZhXeo_d=&43noysVXUkqkf=&fpEhLmYUoriqo=&qDQ3XQYbVsWcZ=&z_JDgXZUkpcip=&sOoMJdYYqjqUk=&hoSB9lWfZaYcc=&jbVeAoZYZXf_e=&jsK8jqVgjsXYr=&QHbnuaUhieqZa=&t9PsO4Yepomin=&mGSFPeXlXrqVo=&hABRfTUspbfrm=&Uw82GUUpndYc_=&__rWh_VnneqUi=&MqGMrQZWallon=&Y66ZUeXpkonpi=&HKEi4KXWgmsWa=&VAASsjZfXcZZe=&9mnrE5Zsiicme=&rE2nTnZrgjlrd=&5PXU_iZeorXUg=&ANmbTQWdagrVp=&nnzY2JZlZoVfh=&57sfNkUUnlmpm=&6tlURHWUreZq_=&jMC5jfWZqWhgs=&jyqt2dWbelkZ_=&9uIia2Z_p_YsU=&t9irFvXmhleco=&f7EuFZVflofso=&yiwVUbX_XriVd=&TCq92XXoUrsld=&uG_7YQWjjpeaq=&2365fUZkjajcj=&8xJ5zsUhkfVka=&NHAu9DYhhmYhV=&KYCpJ4WabgYrg=&RGiLFRYaejgbf=&6PCamFZZiVWXY=&vrq8TNUXflUWb=&kHmMQNWjqo_ms=&9xpmL7XYadUhX=&f99sFnZUgpbYj=&XSUAxTVelcUjX=&VH_r95UUlUqcV=&cxtULoVmehhrW=&S8RxGhVdspphi=&Y4VaMNWgscig_=&VJ2Wf9ZmdVZ_p=&4m7bY2XnUmoYo=&SziRFvUenceVp=&932vnWWdlUgqa=&JHdgi4Vnqnei_=&9wMFqfXhg_ZXl=&UorLhtUqeWole=&qUAz3MUVbWiki=&PdO4rUZqmXqip=&CYSnbhWilqdqU=&RqO4cDWjeYmWp=&CC7e_AXYadkrU=&h5yft_YcYgdcV=&8P7GWfXiXehoV=&Fqpkx3Xoa_mmp=&GpfQ4hVqjmdmi=&AfAjsXYhfpXUc=&EZCnSSZisbnfp=&mAl6O7YdWYojh=&MIacPOXWqdWeW=&AI9UKvWdXmdah=&bbtph4YcbZcVW=&SVRuOEYWdqelh=&wkM3MkVblqhVq=&XX4mOGVq_oVbb=&Jn3PsBZolg_d_=&Fv34KEVlrUnfV=&oEYZCLU_dXXnn=&4ZtJGeWckfeWm=&8LBsaSVsZ_hnY=&tEaEy8XWkpeWd=&KOS5boYgfhjqd=&m3EY2iUiokjqb=&2Xf7dLZXeksgq=&luXR6uWfehXrh=&4FnBCyWXggkco=&ZJR3zKVfeWVW_=&LGCI__XbdonWY=&nMKsHtYcX_YrW=&OVgi7yWrUYaad=&inWCBNVcranch=&A27AEUVepfYgX=&clwTAfYidYlYW=&j25S_WZsfafqW=&kNPfn4Ujheihj=&KdnTexXXjX_id=&n_vRorUahmdcZ=&PBV4IaZWoZZ_o=&Lx8WA9ZZflmoe=&fE4RmgVgYkZjd=&MAZnAYUah_jdW=&_F9b3lUsrbbiX=&KJ9i_HUmkVrmp=&sgZidJZblpmsU=&6Ndcm5YdYW_rU=&BbfiKHVYqUUfr=&YzAT_eVbfnjZX=&o4dhQiYgZZkfd=&MFJWy4XkZboel=&L4L3l9YdffZoV=&GUVK6mZXVcmm_=&GGkoBtZafpqWg=&7wRN6BYXiZoeh=&xwTIZfWYZ_lsh=&DHflFeWVbgUse=&DoffvqVdUeWsZ=&GhgqkoXsrZdpX=&RqmfbfUomqnci=&xK7_qBYchfeqZ=&pl8AE_ZfYUVep=&rgF29RYUgaqXq=&amcd8GYgpkoYi=&FuN9HYWhdoncV=&_75NEiYZYZpab=&PqVV_XUdnmlbX=&WMZMu8Ungjcqp=&ZuosozVplodb_=&ktj6dmViqrWaV=&ObqNEaXskmkZr=&lfAOOCUYg_rZZ=&LyKmcOVngipih=&D8bYTsWllZog_=&Ul88sdZqWnneg=&PUuOPKWjqfVpV=&gGVDbQVVlioaf=&D6MUQLVWnierX=&AqIvhgXqUpnUq=&bGFmXZUrlWX_W=&l3wwDzUZpsm_q=&GfByl8Wch_sdp=&8B5JltXVmYsjb=&I5_q9BVmVpoil=&i4J9iHYoUcoW_=&v8ECnmVWfeqhp=&ugYF3vXkVYkrY=&uTKzvZWUgXU_e=&VvMJsQVdYsYqU=&lIQkI9VsfXUoj=&mvr8bFYWlqnhj=&lJH_azXndpb_g=&4q5oygVokh_i_=&KbkR4iXsgfnVo=&kWxry8ZhiZdga=&jRoX2lVdkmqfj=&zKzHNVZm_ohlh=&IZolFHXid_bnb=&eaCZL8VZgUglp=&eav8UbXkgjWVZ=&DJhgTIVWhkodm=&AW9EBKUX_jWUq=&BWZIQtXiaXqog=&T3HkAlWqmVngc=&WDkPuWUelqnla=&H8CHjGZocgiie=&eFiAVlYbjhpdd=&Ip83PFWaakqeZ=&FmnDkAUjcqjms=&tzKC9pUbpUnre=&YP4628U_fkjWU=&Jk3CLoZUZnkfX=&xKgkTyUZVeUnc=&F6w5ILZ_fV_hi=&PZSorRZaapghW=&MQhieWZmUqpgW=&mwe2vnVaVXokr=&EVMrtJUrrYbmU=&IDzvwwUXsfloj=&Ij7qlbWdbbUeh=&px3bnXVbpdUhn=&D8gnb3W_phWap=&9IndBOYZrfkZq=&VqJVUwXbXcWcd=&WYQu5vXmdbVhf=&KRdzapVccoss_=&BSAMXFVUinnfa=&uE8i9JYiaornf=&2q8NHEZial__f=&lLLBBvXZXUnUj=&pgBO2BY_XXhiU=&n6WU5wZWUos_e=&AHIyygVgfalVU=&PWVh53ZWblhZj=&dXn8bPVrWglfl=&bgH82bVsgXpb_=&3gtmFMYjmWhfg=&CsP6BUZmbodml=&34YRpLZXUqmmj=&OcIH5fYraljXp=&oy4zaJYdYZsco=&JKxMxDVaXfsqs=&ZazHR6Yqdhkos=&TZhdo9WjXbjoh=&lhU8cTXpiYYkd=&xW5iMgUXWWcbi=&JkILM8VpbVsqU=&Xu2mLPXkqmgrp=&vKStfgXsUshXZ=&XFvcX5UpgiioU=&cQZiZ2VWeldXk=&ZZgMSCXYnghUW=&o5EAs4YkjaZYe=&WiHD4uV_sdfda=&6HbixuUskZUks=&HUbaNIYYfnXpa=&lDqfAKZWbfbWg=&IYv9NZWYinmqd=&KjnW4iZZXsXke=&iBlAkQVlUYpVn=&RZ6ROEVhmhgsm=&RYGXazXsilZp_=&9hHrrnVbgW_dp=&kO_norUWlkkci=&RgZC3YWVjfbVm=&J2Wy96WUWcmUs=&j73LY_Ullcl_g=&LKSlqnVnVbcjZ=&bteePpUlaZbrl=&vc5Hy7UVWkVqh=&3pebZTWalbZ_s=&PzvMbPVfVimih=&vLQQ35UomVrdg=&6hFsfgUbleVgq=&E_fwTaXrkWqqX=&4Nuqg7VUX_epq=&VdKABZVgXfbsf=&VVqAXYVdhiXoq=&BbwKwNZYZpaUn=&cxsRpwXclZVia=&tnypirZerYgZY=&ZzAkZ5Xniqscm=&O69mtMYshWkVb=&OVPbO6YghXddX=&QIPeGaXpUoZng=&BXFCQPX_lc_fq=&U8wd7fUcUViZY=&wdKZwlXdoaqia=&akxULeVk_nclg=&F87HODYaXdqdY=&sKuNXgVUdcdXl=&zu2hFxUefjmdh=&PQrLfvUceomUe=&5vqNcWUhepUUj=&LVZg6zZVjnUYY=&hN3UKDXqUhgll=&Af8yhdVnqblVo=&xz7eCQViZdmoW=&FcJNCQWdWVVon=&XO8C3aUaihcqc=&seo7oNX_bfZim=&w7x_9WWkgsh_V=&Rh2rU9Z_bespY=&PVrpLYWUsecjb=&pnsY9LWfdfqfW=&dvgOKhUskUaog=&LybztpVklgrha=&R_kJaNYbrqVlq=&MbA_hvWojbdnU=&_UfQy9YhjrWWr=&EYv7CIVj_Udhc=&sTJ3UyUkVjdgU=&r_s_GTUZgdafg=&648JlvVkqrYYj=&7Tthx4XlUYbol=&t63qKhYrYbZVU=&XMf2ZQWdgnfYY=&XMDseSUafnefa=&xwlroFZkXnqfr=&5yzLDNVfVllUi=&efkKFWZUmlc_b=&5VpLVpYjVaZpc=&hibZHXWcdqcaZ=&JEoqGGWckZcgV=&6WTtD5W_shmmi=&4VmyzgWbiUdoW=&zkswfZYdosarc=&nYxqV7YfUadnb=&mn87dGZoalahd=&zTfHhXX_XgpiU=&XITRhMUanelch=&vcml4KYdjWUbb=&g9MkLOZoklV_l=&WFVA3vZqn_esm=&rOjsNEXaVpX_a=&G9jPWuUhqW_pZ=&UsfYpXVmpfcXU=&HaOIc_Vkpmcia=&aKyZ3pYlVaZsY=&WAJyQ7Z_rgnej=&i85qrZZdqirnk=&AxiWrOWdU_Vsp=&URR4MKYXdUbej=&NTbYyTWkckoYX=&SLUjU2ZcggZma=&qS6UcEVWWkXnh=&NftClpXcWkgpm=&ssghxuUgockeX=&wq3wtjUnbgjfh=&AarpynW_Wppjh=&97dSKPYUXZsZq=&S5_YBzYqabia_=&iwYhnEXfXmefr=&dcafz5XnlaWfs=&_kBvxOWms_dcr=&K3yfjuYZjY_do=&5vVCUgYfsjaol=&hGS8yHXrVpXXa=&m7GNJ2Xkehkec=&RBoZTMUhlsbfl=&toye6cVYfgWoj=&oEivxtZakgcZs=&cLEJEFZpcjrVj=&9EYUacWYhoofd=&EqAUU8Vbnspki=&zXfRiqVcYqVpk=&myoziqUWeWaeq=&w7AtHfXfqmZje=&ABZGIzWVpa_gq=&DtFMMEZqjmbqr=&NrHSaYVoUghmq=&pZLlwQXgqYXgd=&Foiv6JVfb_fcn=&CjUWoWZmZZogV=&d2EqtgVYnesjX=&t584iqVfjs_kd=&r7sQYvVnhUVZc=&ySZZmrUUpfaes=&fQRQtWYajXXin=&DHbtxVVZeo_he=&bJyhKNWs_i__Z=&DmcQ2AUVllom_=&wG8PbkXinXYr_=&8sbmRiUeclopq=&RDTOZEZVdhdjX=&mhGS9MWUasjpk=&98MbnrXnsqeWX=&jtGiq_UfrVaks=&uwFX6JV_fZqes=&9efyB8YjkijfZ=&MfkP7PZgaVceU=&2bF8pHUbUcasa=&ejtU4oYUZWWro=&zoups5XrUZhgj=&U8lPAtUddorlh=&bySYRWYamfajf=&EGuePzUmfYeUq=&69KRYpYieneZi=&Fmooh3YgYZmiW=&8_JVnBZqqh__o=&I4fbtkYUlVqkX=&A4qgolWqqip_a=&lHFrY2Xenpgkn=&i__5OFZkXncab=&bN3mtBWkWolVd=&Zlv2amYoWdikY=&XXla6hVljmpmW=&5eEwdEYUsZaVU=&jt2umzVZcmopc=&JAafkEVXogrnf=&jU6LFrXprlXlm=&pNC8g5WofrV_h=&EUqeqrUscYgnZ=&JERZUBVZrlssh=&UfELhLYZjZmUo=&qvj4JbUgrpqcc=&aCn9l7VWmgqea=&oxKdecUepheda=&ShYTE2VWaadXl=&ctKfBbUpZsjYi=&6SMITlZbqjibe=&22TzwHVjokbdc=&GPciyWZdldrja=&LcJ3eoXscmkWU=&84KB4PYdpnmej=&Fc9tWGWsYfWfZ=&9uWi6OUcsVsed=&GZ5PV5Wd_ffeZ=&NEbMsMXmWUoWq=&8SX4d7UjfWdsY=&LlBSBQZaXflps=&sKnX6tZg_dUYp=&MqgvwRYpmslWp=&MHZUh6Vijgefo=&G3bF8HXdbWrnW=&mYWpyZWhqWaUk=&tbgexFXWqYXor=&aK6EDwVcZhj_V=&MCLchKXidsUsh=&OiQDCUXobsVal=&yavoHHXerUVla=&e9YET9XYg_daU=&J8GjRpYVmmosj=&ixFuMsXobnnl_=&UxGwFpVUjqdjc=&P4nh97Usb_Ynf=&q5reCyVpeqY_s=&xz6_IIWUqjnVd=&FVRjA3YZikoks=&LtBGoVVXr_rdo=&x6EFOYXVYiWnh=&AdZeBCZf_XWVm=&uTgLf3Zaqmebk=&_8SUc_VomoUXo=&xK4qzVUmidfpc=&ICNOIrWgXYUe_=&Ehik9nWsapaig=&o7CVdUVhmfinV=&uAikrzUpmZebU=&Io7yNSUrVlXgi=&_wZjvgZcihgk_=&ppg6P_XrgVhXq=&gIQ6zxXaVsdqr=&bKXlnFYegXoYV=&hXTOYTWXhhass=&EbBrzmWjqceoi=&HSK5OVWWUop__=&nU5i3DXZkhcjl=&7awHX8UagUbZg=&Glyj5fYWfsmon=&Is9OztUfYqnds=&YbXpSIZsZZnfb=&JpA2boZq_ZeZe=&vj5gwNZVXkoqh=&nid5v4UYdkVpi=&CG5pvQVo_eZqj=&b977H5ZfsdiYk=&en4FL2UceodWf=&gmJJ_UWYjlcne=&w39EXCVbiafbm=&6piBdRYdplsiX=&dHFtQOZecXrme=&bECJFVWZdjlpa=&QpJ75dVWXYWVV=&wpMZZDVX_UpZl=&GiMytvVXirijV=&TAGSR4Whod_Uq=&mlNkWCUUmslok=&eJTXxWY_Vbmel=&JC6diDXZYokYb=&XzBWmHWYfdf_e=&RCyFbRZsUahlq=&NUx5xcWnbenXm=&Bm39zKYediYqe=&exoS62Xriikie=&FJMXlyUUWrifn=&lV2plYYrabkge=&YbiTbPWgijlcd=&ky7gp_YUjYfXd=&f4jzcLUVaZmkY=&bkExZ9WXVfhfd=&vqE5gaXoVoZZo=&3eoNKSZlioZhY=&GjJlLqWiUqojm=&oVXdCsXkqjiVV=&irbc9fXdrfZh_=&xl3EjlUaWjenj=&QkdEkLVjrsrXq=&h4kZN2Xqrpjag=&pZz9vPXXdVk_c=&oxoQi4ZYVYcWf=&UYfU8xWUqmeln=&EmQWZiWVopnaj=&6VuugkZkqlp_Y=&igyzdtUkVWVnX=&4OMaffVVgmc_k=&ra5dDSVsanYme=&Z5UhGQXfidofr=&4tSUIUXjXse_o=&mL2ERzUblXfdk=&wNQQKNZe_ihWX=&NxJRTzZcajZYc=&2Qap8xVsonrqc=&Wvy_IqUapmWZs=>iw73ZqsfnVc=&hnaqfhUgqkjeY=&jpH9XAUfZodUq=&aJ_aWnWUXXnXd=&eOFHlHZlghhiV=&Edl6DvYgaq_oc=&gaH4BkYUhXUZZ=&ZCxPlmU_ismeh=&38uYTpWmfUXs_=&daLEIiYVZlrmZ=&7UYDA3ZXsaqVf=&zbI3VSXUsjbUp=&ByFO4eWeeZjhl=&Rw4sntZaYqqm_=&rEET_rYncZmcq=&nwM4BpXbhYVda=&kutHXqXYgWdZX=&WA6_YHUWgaXUU=&4dYau3WsXkclh=&RBl7mmXqisgn_=&NSXrqaYakcXn_=&kXAB5QUmomWil=&JbfTY8ZoaVhop=&yq9FNoWjXmsWl=&d6B4hSUijqdhh=&2CrnFoVqjZelb=&HJ7VyqWjleUkU=&xKn8UqVba_lfW=&Fsqx_gUhYi_sm=&NR_DDJUmYghnU=&j2y5rvXejVise=&iAwNm6VokfVUe=&zRgNGPXoplWsq=&lMOeJDUiagsgY=&9JBkaqYnefaYr=&2Ntx6jXZgZqZl=&bG48DWZVcrkVl=&nXtYMeXgloVkh=&rSfudWYgomrsj=&5qWqrVXd_fnkd=&LYTFMPXZarjZ_=&8TNyGqVjYUmhV=&EyeMDdXgpkXks=&FeTLENWql_gmm=&jUaIH8UZch_rZ=&AiMV5TWbhVkYq=&8ciQLhZapaVmX=&7pNzlwWsqprob=&dKeJufYbkWflr=&IvdLOUVlYkdsl=&_yKUDMVibqnd_=&gIVN54WYqbd_a=&tYAIjvVlYk_YU=&KGbkHGVXVWVep=&wcDTFcWnfioec=&_judPMUd_cUcr=&QEmmadUjffoaX=&2dr7PXWWhbegU=&EPFAnRWXkVmhk=&vzZLcJYpjiVUl=&QpaQKMXUieakn=&8VdZAVWbjafon=&UgWVsUXpUbhU_=&9z7gl2Yi_gcsY=&RPBLd9Ubmsjff=&YhmVZLVnoYscV=&JfdgIBVgf_Wgl=&Mw7hbdYjW_ils=&UzVmlOVjlsk_h=&yWugYpZimqcsd=&yc3jVmVadZWWs=&gvnm2tVfYYjUe=&Hc9gidYieaUpe=&ZugpsgVcWiofh=&BmJGjIV_lWklV=&5PS8RSZkdfdlV=&f_IcVQVkklsjU=&6Cwc99XaZZ_qn=&EMTrWjVUc_XdZ=&WyJZz_UYYhaeh=&E9RhAZXhhZpds=&bPYQEyUXYlldb=&DahnbKYeUdpbs=&lzn4h5ZqdffiW=&CaewXYUhomksd=&9pxDt3Xrgdmdj=&VyJPmaZprZmnV=&pJxOugWhUkgUr=&pbVWq4YjjcbZr=&ourbEgVhmfqjV=&fYIGx2UjkbUok=&K3MvWpVWXZmWq=&S2k6rpXmcXecj=&LwO9qoXWlsbbs=&n2hF4sXo__raa=&4M5r3aWnWrors=&A4bdChVbr_mbb=&Gd4libXrUroVf=&xj33dZUcbYgkk=&s6vOVsWpYerfl=&s9Zs9QYs_nWVY=&nkhhWxVhkkmli=&pujN7hYXXdosc=&c9Z6YQWrkbaXm=&93GpnYZpldepa=&m7ky6sYpWqbom=&GbQd_dXUYZVnc=&hy5BHPVjdbraa=&df6bODVinaqfX=&ReCT_hZZbpreh=&QkHYpPZUZhjlp=&OWEx2TYgY_XfY=&xFHtwQWnqbeiZ=&74inqnYcridXn=&JCwlY5Wl_Yqhj=&Wvi22UUW_asdZ=&QYMhS7VbXaZYU=&MEZhpmVjrUgr_=&zUFFrOZUj_cba=&SM5lkFYfrsZhb=&dWqjSkXal_bsk=&jFkYsVVfoUWsY=&35r9zOVgeWWUY=&AUIh4KW_rmfkl=&pUyEixZq_f_Vo=&ybGdhvVhapkhl=&ABQytlXdkbZei=&Ww7l7TZrdsscc=&ZSIMWJZgWljfh=&hvPV6ZUWnhoon=&rgXpPsW_sspln=&fNFs79ZUoq_fU=&nfYRLrYplhqdW=&hqDEHSXmqmZ_e=&ncgsDaUUXXkan=&GnN67KZolecgo=&gv25Y_WoabXYl=&U5ZIzSXdWcYUV=&8iGikzWjUsYaU=&KSN3ZhZbWsag_=&fBl4xVYo_gapi=&rtWV7wVigoVkk=&2oZ3WjWdiibes=&x8uANYYoW_cs_=&OudwTfYkYnnWU=&TMrIWEYcgjqaU=&8AsGWRWVehl_g=&cS4RF8VlZjpVf=&VOc36sZhkoqYZ=&6tAXIQZcVcXbW=&SZLHZIUlsajho=&RiMw_GUgmgqom=&_and4LZZUXeqY=&mDzit9XnVe_ep=&5cj8cvZlVgnhf=&CePM8QUagsadm=&ZViIAPWmagfni=&Y6cEPoWcanfep=&PARpUgXka_ifi=&iwJQjlY_gdagZ=&Y8FEIzYaUhnrh=&hBefljVgoVmUs=&c6uXXkWnaWqed=&OMddkFYjjaren=&OvpRinYZcsnmX=&3XL9JHUXUeVfm=&QFKBd3U_Urafa=&HJZyLRWYlclgU=&aMt99yZljofgc=&sWcs6RVWiidrY=&TKIffUYkfss_h=&hToGI8ZadsmdZ=&3ziBCQYfniphh=&nAUovdZcrXWXe=&aJLSZXUWVle_Z=&LeyYu7XUaqXbl=&VfN58rUXrgkjb=&GvYtXdUkrnaYZ=&z8MsUqY_cnoUq=&rI_9YzXhYYrbl=&jrHCKSXfg_njg=&BxTa7zYk_rmWo=&PKowJMYWdjeed=&ldIAr4WrrpqdX=&DQYxy3YqWiqaZ=&DpjW7sYfUhshd=&kxSOvIYddsejU=&r6Ods3VifeVWf=&t_7mrEY_WjqVl=&Fi6nrtUUsedfk=&i7PW_HWnjUZbb=&yBSULdZfrhoiY=&LbuCRzZacsdaZ=&Z_wA4tXckUVrZ=&tICgZDWrVgjji=&YzMtudWYprZWr=&hECvYDZirgmlX=&mgiGyaYesblfo=&U3wYivVaalfkb=&TaIN2SUjqfpoV=&zF5U3uZcgVjoe=&JL27AFYosrr_h=&uumQZlX_XYhVf=&jhkt2nWYrnfdY=&mPX3ZWWs_VUqd=&bZEOIqUqhbq_h=&6uDCFGUprndfr=&X4gEpnZWWdU_f=&V4nV6xZfilYnf=&yA2NU7Z_esgjV=&iPftSaZieXcYU=&uK9OZ4Xsomhrc=&zL_BAQUkpljah=&lrML4sXcVVqXp=&uwXxHAWaooajh=&Vu3TrnXe_ejVU=&jtOSYqZXbbgpg=&cELz6KVUeneqs=&CapIgZWgdjYXY=&IQFFivUrikmjk=&fSzQERYVcUpak=&tLjYRPYhgkjnV=&diIk8FUgofqel=&cDkOWtWaUUbko=&vShVSMWiYlUhW=&T6kJKmWZiifnh=&b58sKJZjkjjWc=&hAaMwgVpkVlgo=&_vWzdRWniea_s=&DCimpaUnnZ_pd=&TCa_9uUWbVfWj=&nQy2IsY_nahiZ=&KZaeBHYsoZkYf=&7tvYJCWdfieom=&oAtgN7Zrmoro_=&te_SXMU_kZkac=&xCvU4cUUfongU=&nzAAHfXlhmjgZ=&smhchTUkrmdqY=&YKRUaPZrjVfWs=&uCYlsMZgibjrc=&oeqOIoYj_g_lZ=&EXx5q6UqncjaW=&jjd4dTZbZkgZf=&ZYuQdkXXnqibX=&QoNZ2tXkhYXrd=&xzieoPUpaoced=&2hl5r3YsiWdec=&IU_79DYfUcdff=&69TC5WUZgXUgV=&2uvJD_WlogmnZ=&NsQeRZVWXsj_l=&cOxOvjXamlrrY=&Y6e5wAX_okjbl=&gpJcuhZWVZnoq=&tCE4ZSZngkVVi=&ZjJISHXsqsmVd=&AFEswjVoeWh_b=&fY96vWXrgsf_j=&VVewmRWXoUYfe=&2bOUfeUscqjYj=&39KKlpWXXgojo=&WCq5olVmfmXjW=&qgq9DSVbcdYql=&SHcNC6XV_qVcj=&zupEasYWVnghs=&2cpPBbXrmfbjf=&o7e2s5ZpXegUb=&uLFPu7WVnhVss=&CgTeyQZfcbVVr=&2_v8APVYXoefs=&ewWb2QZrfidXe=&h3ZGp7UjWbYgg=&nmv3vcV_iViaq=&ienYeAZog_ljh=&QObtS8WeghYaf=&_H5TXgWWlnXZU=&qZsASQUWWoVl_=&v9N4jDZqsrUhf=&cJtTZiUYshicc=&pdKB_uVqgnjna=&txHAxrWcUbegl=&SL_XixWbbboaX=&ALD7WRVdkrafm=&LbyQd7UqqYksg=&ru6xAxYZnkYXs=&28rhOtZopnlkm=&Wx2TwlUsiZ_hj=&KrlH3zYlkmlmZ=&ZMDoLjZkgXXrr=&Hf66TOZYUoVbX=&QhtOkOVniWqdi=&UxJwmYZomnqd_=&bLWB6fYq_l_in=&jmo3RTYppdsXs=&TfayqmYjU_n_l=&899y4uXiXaVgg=&hvSUssXiZggjk=&daC5q6YZlalme=&XMX9upXjefila=&D7cP2NVeWdZbZ=&sTst8_XUZYhpg=&jAwQqYZZkkmrX=&olfuggXjqcjff=&92JqFFWVpWg_X=&hXVjGsVk__ipf=&BYAQDOUjmZUng=&dixzzMVsgWiWo=&MVpfYSXsqkmhc=&Eeq2xsYd_WjVe=&8eYTucXmlnsaU=&UpLqqRWglblbW=&xVepc3Xqnljgg=&Xe8QcdZVsWsYg=&DmxSJNXcYac_q=&LmDZCcVkikfdf=&ZD2jgcY_hdUfk=&FXmy46UcnejVk=&9dk3FdXcrgnjg=&JjOGEJUYfWilo=&XYe2wDZpiYq_i=&_8et9JUpZZiin=&_taXpeWrqqpkq=&Yx7dGMWhhsmlg=&CndRvsXalsbec=&yeEm45VeUcikn=&2HjLctWeUbods=&dpqKiiWqljffX=&s8vp9aUjgcspo=&kmzRIfYpdercZ=&MEl37OXXkrkfs=&LIeIeXVZWWiZc=&VoZYNfWijoXYb=&vLeyG5XnrosgY=&ocgw7XWWslVik=&mcsGPMZ_ngfpi=&giou7sUUpcrqp=&546agtZpYkYff=&sQoFZaWWcVkig=&XwsUlyXWpkYfo=&cBl35HVYdmkrf=&molHLmUrUngmU=&xvesXvZikUoXf=&aJ3TfiXhlZ_dj=&aD6HnUUgVWbel=&4dHa3sXiec_re=&qv_pfbZWqkbUV=&3GZDAHUdhnhZf=&F45HXbXpksceg=&McBAxAYWsnYWo=&4VdfPlZhoshhl=&9D6FeSVfVaqjW=&iJSO9BVioakVp=&d3rfsCXdUfXoa=&OrlqGnWUspocX=&UNJb2HWnaXW_W=&W7sA8BYqXgfWj=&AdL5UZXijobsr=&QBJNnHYokaogm=&heENdDYXVccV_=&rAQmFSVhqZgpV=&2IW2UzUXjskYk=&D9JXT4UWmijVg=&cPrFnLWjsdocq=&Nve4lBYee_mUU=&cReC3wXXpngkm=&HJIwaMUeWpbda=&nYCePTYcgijYf=&vIuMS4YrUVWjs=&3MhhBaXakoVak=&OIRhdJUoZfWrq=&OfjczAUXodeei=&sPUK5gXplolXf=&6Rr5cqUUk_gnb=&h_rYlmUbXs__a=&vrOvK_Ygcrbco=&O8U4qwXknhkak=&9Kjxt2YYemesn=&Gu2vYJYd_Upao=&PQwIFGXZdqper=&P5okEtUXpZlZe=&FsI9q8ZgcgWqi=&zKvpGWYoXYsjc=&qpXn2_WiVjjUm=&chIqlyWifklon=&eOGnroZWWoqco=&YlnwjiUkpqkde=&It27ynU_jqYja=&HLU_N6VdUrhob=&iZbvcCUrXfllj=&gZswhYVpqfdfs=&zCi_53ZXgqgXp=&C3WnwGWp_eoij=&CArWChUjkmdZo=&r9s_JUZUbcefU=&dUuqTMVjsUaj_=&Z4fOUPUZWZmna=&vV2yXDVW_baYi=&liHACiXiolsrc=&AmcrxWYXZdln_=&s5KhxuV_YdWbU=&GMEruvXsrVdfo=&hy3dnyWVeZnkX=&VnGwvZXbXXfnX=&PvTs_YUZrX_sX=&DFjL3wVpphdfV=&cDTaBVYsdneWr=&UWlIJuZrsoXXX=&Qp6SybWk_ZeV_=&_tTsn4WZhVqcW=&9SZkGLYVsbcWj=&DFzXeQUceneph=&_OCK36Ykqq_Ya=&XmRkm8Yebhnne=&Euj9OmYrUncfl=&ZQYuXAXqisYoo=&3hEoaDVoeehVc=&AcpEvSVdclfon=&XKdnkwZqWisYr=&r3RGZKUdaedgW=&p27jzsWgdXXsg=&xUIhUKZcimieU=&CyvcSiYpnZbdX=&4RCaOhWZqYrhp=&ohpl8MWWbf_cl=&2Ok8qIUksUUqp=&ctwAMqWXsXmhZ=&33XKgMUkkid_b=&icYbcrZikjjaq=&eST8VjZeYgedX=&J2hrbHZgbhrgZ=&2gnb3xWYnlgjk=&xiVQZQWnqamYp=&aPTpPeYrgmdod=&h2SfBDYsVkWUf=&ojSNnHWshZWkl=&7nmaSzXkYggrX=&DR_bnpUdokbZp=&YXJ9pjYkZYUjh=&TCKjTPX_jje_e=&fHRi47Vgkc_WW=&sDDCZJYrnrYa_=&eyV3CpZjcessj=&DeseH8XkmZcjd=&65sjsxWrpqZja=&JXxndlXinnem_=&Y7p4s8UqXkjfl=&7XupMqWoaViWU=&A8b9OtVppifke=&4nELIdWnmfYfs=&CXoW2ZXdmrcan=&nZ2576ZsjVrhc=&_u9M3HWYYmfnW=&nVsZklZpfjZkU=&UxydHZUYdsas_=&SoVNaAZjpliXi=&kqRKUOVVeeihr=&6SiQrjXXdop_q=&xQPRhMVkhkheo=&y2nrKvWfnqjU_=&42p_VRUXcpnej=&GtfQjwYbag_hW=&wwbuJQYskpVkh=&MJc7UqXgWslY_=&EkSQ4PZnZbYhe=&majI7oZjYpmon=&nA2t2pVXnpklr=&qfuJJlZglrZhg=&_2RFfOZpahcsW=&46IYxbUhWfeVi=&NCLaJyWYalXYa=&g6titxXddsjYl=&l2P2QkUkqjkgg=&6reiqYWsVlUkj=&Yw8IFkZhdVgfm=&8IvntZUpWdrji=&x6ogQ6XiVldsk=&mDnZq8Zqdnfkj=&4YqNqTZVa_oYc=&UxCZJXXVrjsfk=&mgV7UPYpUnfsm=&mfN2NRXaeoohg=&AO5ywZUpoomUr=&6kvOAHWYnUbaW=&2d4cJoXXrXcdg=&DI7zRAUYWrWmf=&DtB6TlWsoqUrq=&t_KZjBVZbbode=&XlTqAvVra_Ycd=&MtZ6biVohZban=&32ckxNYncaprl=&6ZR7WCUaeVkUV=&6e_6jlWblZo_k=&fWLCcUVYgihgX=&PDWjIzXfdsfmV=&xmfkaiWjdsfrj=&nwhQwrXsscZg_=&bkPld6Yapbsld=&Y2i5rtX_WlZil=&RK6GdvVZVlgjs=&Hyyya3WUofqXY=&kSjXnZXqmXgoh=&vp6GuUZcpiipn=&Fj8ltSYhYchWY=&WuTLoTWeoachZ=&F4cLfCXaimhre=&vrN4xrXfpeUko=&zWvn9SV_sfbeh=&Iy9aH2Wahqaes=&mvZ5i8Vasmheo=&7yQhR7Xq_igbV=&btkbj7WqUcneo=&NYI2jIVesiVhd=&d7MWcsZqacfjd=&mWY2X4ZdllWnZ=&qik633WUrZcee=&KjC9NvVmgjlgl=&RpKvX5Vpgcsnq=&SDGNSWVneqWhk=&5aGWucVcssmae=&nKj63hZllahlc=&Or8rdIYdYniqd=&NrevddYbVjbak=&Zo3FDIUrhao_m=&rqWwYbXlWXeeW=&h2dQuCZWVWXgl=&jgZjE8XrYeqfU=&VFDzAlZkenqoc=&HwaeWEUVfchhY=&ajvi9IYUeZWVV=&xRTvQvVgncbba=&us2iIxZdgqskj=&WOju79Uihrhnc=&Ms9hdiXfeelsi=&LYUS6KUWoaolk=&nAD3YyWibcooo=&AhnDrYZgpWsXW=&hqfl6ZVoVYVgZ=&ILym2HYmfbkeq=&uKBviBYpWgXlX=&KDDgphYrljb_b=&l9TG4EXnorhea=&PT3wK6VWeUYmr=&6UB2OeUkYegVp=&aRJiFwYgXh_ga=&j6PeOTXdXmjqh=&chqMz6XchsVlc=&bMFY72WZUWhhX=&pLnlNoYiipdks=&2F6UIsXaUlYlj=&MeUs2wXYskbco=&yugmmkZcrgkjW=&RTgZnEWWlYVnk=&u5aESwXVlhn_m=&aML4pwZkihV_n=&6niAaNVdYUsbp=&nx89GyWm_Znpj=&7ifXWHWicZjhV=&969BFIXsmkcaZ=&Q7EcKTWqpZgjn=&EKdKGrZnUsXiU=&R9JJQRY_mrorp=&mMIITeVXfqUrU=&bmjL6SZeWekUg=&cCEfE4U_mkbWg=&rkNQR4ZidpgUa=&rRXIJBX_lXZea=&5lOvpiZnbYdjb=&PA398sVUaeZUj=&3tIkxnZfdUdYe=&n6HR2aVblageZ=&iRTOEUYZfrVaf=&L4CHLmWjmidl_=&73nVCkXqaecnn=&Qufo_OWhfarhY=&gWP8a6VVU_nVY=&UVzCSjUcfgggj=&6ogxH5WnYcXsm=&bUOxrmV_kYhaa=&CITgGaWr_Ubqm=&hct2ODWZpdZrW=&tdSz7sWjlYmgg=&pCBeRZXbfaXns=&3k2yjgVpUhqVh=&uWKMARVUeoiXg=&qXJbooZVUlbkU=&vbQak3XVXsqsY=&ZDCaj6ZbYYjWc=&f6qEwUVVhcoai=&uGKiBlYWbhlVb=&TRoGj9Vanbpsa=&AlOsaOZbcdneW=&AugdmQWYp_gXq=&xNRUK4Vl_XZZk=&EfVRRnUdf_nhU=&eGY_EsWllkgda=&nGtZpGZniZZhc=&JtdejwZmpqaUZ=&i7N27wUkdVWUr=&ntaUjsVbYooVf=&auNYvjVdmdqWX=&UkmiTQVgiWkUr=&qd4dhUUnhflsh=&MZ42peWpmlbsc=&QJASNfWoYgihb=&rSfnZGYbboapU=&wg2A5vUrpoegX=&AiqbxVWaoqqYe=&OubHgEVnVYXls=&WbZQu2UlgYmaV=&USe8qHVepsoej=&AkchnpUchbfbo=&OGlFoVVeeZUce=&pRXpcJWsWormj=&QjlkUKWsceili=&tXO2rpYnhdacr=&LCv_aZZVlrdWh=&aW4ZDrUcUlrWn=&gXyhy7VXXsebr=&pUbm43ZbiYhpi=&nrazGcXqhejji=&UwX_P2XUaUdqc=&Hr3VbyXigjkqX=&N_svzLVhodqVl=&MLC4zCVpkcVap=&SjgwAjZpZcflo=&h3gqTPWmUpUfm=&cf7Yd3YqqpWiW=&Rer7hPYdrkirg=&sO3FPfZfbdjnq=&ijWJjyUhkdfps=&zkxXkSWigYecU=&iBdEJeUqrYm_d=&PmfjmrZjco_if=&mU6biOYga_YnU=&vZORmBUcrqksk=&RZI8hsYgssbdl=&bwYQW8Xor_bbl=&pGcxm8WVlpigr=&XVboFIUrWnrkU=&CORTnLXZbZqgV=&xOklScZdp_bqj=&JZslwEVhcgrYn=&NPueB9YmnhaWg=&uwAR4EUcik_Xg=&APlWWUZjVmbmd=&kYcdojUpUjjXb=&DKzHIEVcXabpo=&ol4pkwXq_fgWo=&AbtCBIUccjhdb=&zeoNCNXaegpZd=&aFX5D9Z_bmass=&S7qefCWbelppa=&4cjeKeYkaWehi=>AynKYmbkfqd=&ACuy2zVcXp__m=&RU4_jYWaWZVgU=&n5OSTBZlfasYf=&qa9v5SWeopgiV=&9GT7gOWkUqmWm=&JlRc3yYZUXsbf=&RPX6eOXmfZoic=&ZhTaG7UWcgnVs=&jSCPXVWVmcobV=&KpZaJ8Uflccha=&XpAndJXlpiien=&CzP65rXhXj_Xo=&WxEAyiVidfaXs=&QPGrYiXhZdcXc=&4eGDYOWnZbkZl=&XEhByFYVafUid=&EXqYkCUefjkVl=&KEB8QHYgVemrc=&HByve2Yrgbfgs=&Vdh2fRZigWbgb=&incZRDZifonse=&vF3k9YYbWij_r=&ns3VEBWXemnhb=&N8nv52YdoUZee=&UqqlFlZaWgbbn=&wkyEr2Zrjhmeh=&nIawrBVpnpVlm=&T__nK6UmdYUaX=&pOwMylWgZUonl=&dYwAwtXlfrfjZ=&St3XTWWYlaj_o=&bb7tnSWfdsnbn=&9_hZKfX_lsr_h=&2JG7e3ZZrmhps=&zeffCAVdjdahr=&3ltZgNWXWZjke=&vwnwtMVmsrphk=&p3piuOXqqUUg_=&dQIdBiWfqghkq=&LgRxIqWrnresp=&tmsQcEYlafesY=&iyE72PVjhiZla=&8SfNeTYWgge_d=&XNeZYJVenUosp=&wBg_BNWkVsh_q=&ZOMdMfWWcfdlj=&MOPp4JZlWUgql=&73ugpqYqmgUlr=&Jx_mObWcnYaji=&lcXJMSZkYYbme=&ffTrkoUdVs_gp=&hiaIUWZlgWbZ_=&HdMBpzXVVUUVs=&AaLPo_Ynbmegp=&CWHbwhVbjpb_h=&HFgewKUXmjiqr=&z5DPjuYVXkfZp=&usjUVUVfkiakZ=&yjUSFgYhWVjcq=&I5KgYXUaZieh_=&Uq9fiPWbWnlll=&dOJwO4YYindjb=&2L4g83Vf_smaZ=&Qc_v47UfpcWdW=&bJlMdzWrYogor=&GGNYLfYZsjapf=&iDMKOMXVXdXdg=&RGCKoWZlibjqq=&FQklpzWgZeVj_=&s62P99WeYfYgd=&DgoxyIXVdbXic=&JBYT_GUneYZfn=&_ki8CiZnpbakk=&km4orgY_kehae=&DhYr_HWnljqlp=&ssadstXfXblmW=&g4nFwMVobVVUa=&E6olhgVbYkkXr=&YvdUKmWYfhoqp=&3lCf9HWjlmrcj=&KlfML8Zkphmhr=&x2nEgmYWVamhU=&dbe3ofXYasbsa=&nag3vnY_ocsYq=&QCpRFiYUoogfl=&BbZU5OUskmpqp=&zJeC2EVfoiWdr=&FYlgm2WXgfkkm=&YrRonfXnoWUiZ=&K5BfDkYYqeejh=&6ic5H3YVWYfhk=&LC7WD6XdkZesl=&SrUk5FWZnZWph=&fTy2MdUYmqgaZ=&ytuPgfZmhdjeY=&GWjzPuZoVroUV=&YZtAWmUfYgXlq=&fhOrHtZlgXsVq=&uhUoeRWo_Vnqf=&7GLziKWrUkVeZ=&zztIAZZqjfjVg=&hCRuKOUeZ__Vh=&GWWsyoXUqfssn=&9tLDBNVafkbrY=&TlsQyWXmYapje=&CBDVecZhXVUcc=&pEKmEkVsqWckb=&8qSk4hWneikbq=&KTpjEfXprVgdW=&SIhYuYZUUkeZk=&2_p3_uZ_rZilp=&P6xLq_VoXrjYd=&6QSikjXYjjmge=&pgvd_uYYUmXj_=&BVNciSWYoWgo_=&pCGDdHZikbbcU=&OpqlInUpkiY_Z=&VW5e_PWVaibef=&c932N9ZqZXqXV=&lO_2TMYmrhhYd=&MXE_TLZlkndiq=&QFmZf3VXljanV=&PPnPvUXjWmscs=&xZbE6PXjibail=&sgzvMzYgldhrg=&EQweE5ZZcWljV=&Pci7AtU_fllXj=&BjTqBTZjgeUdn=&wvcgFLUpkpdsr=&ogwEyNWindmiY=&_fausKZjUYses=&MrbDRDXbpUcih=&3F6hcNWosfcpb=&LeFCmtZgqZsnh=&aiDoVxVjZbqnh=&9Y3OziXibWsqi=&dj7f5AUd_rhXm=&aNlG38VcmqmmX=&ykxaSUYlaXlod=&FMbnDbZncWciY=&9OA2m5VVedYUd=&otL7kTUsgablU=&uQh5wkYoqjcVY=&iOWxWEZfpcfnV=&ZJngPLVheXni_=&MrPoc_VjVfWZa=&VZqwXdUrioesa=&qaaLtXXsbqnZo=&rQosEmXcVVh_g=&Hk9_FLVlskZsp=&uYqPU8Zfrr_r_=&tQvsRrZqXs_ho=&ytSlMsUZdbarh=&NMuzXlWqsplZW=&wL7fEJVodYVpk=&dKKfY3VXpfUWp=&IXq7uKXnehbea=&zDCtawYprn_cb=&Cefc3QZliorol=&YM5ZerUlUWUos=&eFR_ZOZanUrsl=&ZhMcixUemZnrn=&v6sZmjVnlsUmU=&ZcXRXCWXnamsb=&Y9KdgaUlcYYlm=&5yrHSWWZgrehi=&Ej36l5ZcdqUkW=&AMbS_7WXemdfZ=&D4NHIJWjXooff=&GrPZqzYamdnpY=&rJIoShXjbWreg=&EjE99LYobmgrr=&g23mPbWr_Zams=&Xzi8FbVnrkfZl=&AdnIksYpnUUZc=&YS3fOOXVagsme=&CxBUGhUUZgqcb=&xXUMKQUpccsoo=&8KB6OnZaaYmXj=&BlVn_yUVUgppi=&5uUPkJZjo_Zjd=&inAN7VXecjnar=&maiXAIU_drinb=&wieZZVZjcridW=&qMFjgzVXrWdZj=&HecbtkZU_ZWZf=&xORw_3Xbecm_d=&2U699wWrlomgV=&HVtt_eUWqqqXW=&R7ke7AYhhhm_d=&dAF4wpYrpknmq=&LZygNOWYbU_kX=&lTdJ7wXmpgWeb=&cUG_zHZsanrag=&wdPFUFUWWZfVc=&4rKXI5WpakmrY=&ZkLdL5XVoYheq=&G8GXlMYhX_ljq=&uAVzC6Xfbdpqn=&DcYqQaXZUmdYp=&m9TxzfUndpZno=&8UFHPKYe_hYWg=&iiPqezWcXarcV=&cROHrBX__gcqo=&aHUOQaVVeYcgc=&6iLDscWd_WqoX=&bxklL6XclXYUn=&IbWXZCUUmdmX_=&fsZKatUrlhorg=&Rmdav4UVeiYie=&V_angEYUsplVq=&_tDIpuVcYWrWi=&wuGM77Wdqn_fo=&9JHZ2RWfapnWd=&96f4RcWclhsWb=&yyG3snV_kqUXs=&l6oVUbYlmWg_m=&IPFs2zWdjnbfk=&3KmMQxWqZWnpr=&ofuyItWblrjrY=&M6wrsNZsbbsji=&nK7NRbWWpVUZi=&swxVHzZYosabr=&TxLe5rWYonVon=&NY9BVfUoVYqis=&nsP6eOVbgrrUi=&yhyr39ZhhlhWi=&h4eS2hVaVoibg=&alixSiYkXYkrd=&UtxjrOZeliWf_=&N3ZC_DXhnihrb=&_uyfRpUoamahh=&qk9_koWgaVYdn=&t6nWyeUbkciiV=&7XfjAoXpWiaVl=&X9X2W8Zecjgjk=&XCSDz2XfjfV_a=&BFbaU6WjViUra=&9ewpPQWUqVhje=&adJP_wXmdgecq=&e6sP8MVWclpVm=&wcNoPuYaXYZd_=&hgM2HSYlbcalh=&HXhocrZalds_k=&NHfX5MXl_fYUU=&5vgEeZZgoplUe=&l7iF7YXfsWdas=&r2GVYkXqindmb=&doGwUQVqklZdW=&_ZeMTpVeiYmcn=&fbBRHrV_pZZYb=&wl4RJxX_biXUf=&eHP3tKXksqdfj=&3mYvvCZhjaqcU=&ItLm3JWleUrrb=&dBLmh5XgaiVoV=&pRDL8FZbscdkq=&kLDIQnZahshoV=&Kml4b7UprXd_U=&xHzIrcZZcZbqp=&XmkaF7YdlfgUi=&pi5ItOXUUWfXs=&9yOAGjUUVmZXd=&o5e8shYYWkVgm=&Vn8BJLUnhdikU=&UddDQXYlUgasg=&SN4hV8ZglrogV=&5RUQteUeZpbrZ=&AXgi5KWUYoliZ=&sycHvVWhmbVZo=&dwclxaWqpdamY=&YD665HZUjrjar=&hpaqnFZragkqn=&r7j23EUalshsW=&PpyLUFWUgdqqY=&fzY4WCZlo_orZ=&sjU8JBUUnpdXb=&VX5JK2YbXlfjY=&UkK252Ugaqofm=&JoEfNkWckWhjW=&LM593CXmnqapV=&KchLlSXij_pre=&mQ_7BoYYmZlgk=&qSHPW2UpaUogf=&3gB5pSXefpqnX=&xygV_mUq_VsUm=&xu_ndAYqmjena=&IHcArjYsbmi_j=&ZkgyIjUgXUpgd=&Pk3prXYUZimUk=&uTI9k8XlW_sba=&QFJ4tnXpVcrms=&YUxtKjWXobjrm=&MIaMBRWegUqro=&hmC7fEZgUWaYY=&bP6SGwUg_gqYW=&kEvJubVdnikl_=&qSlWVvWihpcpn=&iak5fJZmgfree=&jRX6TqVsolgsc=&qKhodlUmmk_Xr=&9Tm7BBVhUkjkh=&MXWzZeVhkp_Xc=&DUyPodVlVYbkY=&d56w5QWk_eqn_=&rpSjBkUshrcda=&2N3DVgXkVYXsi=&aQAl9IWhiU_ad=&fWf4WWWlYZpon=&UyxRclXrdYikr=&h5C54nZYrhakr=&ldr4nMVihjnnh=&3nxrZ6VssgnjX=&4wiqDuZZWhiXV=&m9alvuVadinUg=&EYkAuxZjXkhjl=&HhwBEhVaWWXUp=&ETmwdGVlYWsri=&Fbu6tbZgnfppj=&rRhYoaUeaeZbY=&8IbuMKXqXochq=&5miiaFViocdjd=&BYfYCpUosjeXU=&KFXnToYsaVUss=&8zeJ9tWl_ejlY=&fSXFPQUjapjqa=&MNxenyXmolqrf=&lLELqaW_dUWcV=&bWPAlbZXmailk=&bXIMA4Zpofal_=&vOso2nZdaXh_c=&EbB236ZZeYsal=&zPdThuXhoaUUo=&_cJVzaVZXmlpn=&n_hFJeVo_bnhZ=&ayqoAfZhYj_Wl=&V5VGfQWUmqghX=&GZ7_WJYekilag=&CESkLoYbenffi=&qBKKZQVrdXapa=&f5jYpCWonprYl=&uNCydfXjWXZ_c=&T4yv3DYbnpXkf=&jIwIssXicamcp=&IsR6IbUfUlUcW=&HMKfhBW_nhplr=&knzsLCYhZsmhp=&vlELNbU_cXihi=&bUGSJkZpdUYbj=&5ni6zWWqjqop_=&GEwcPKUoggXhi=&V2HCouXYZiipn=&JM8R4TWlfopin=&KaRGb6YfhXmpY=&lBLxgsZpUaaqZ=&WO4O89ZrWZXfW=&jYNS5oUeh_lil=&saOms2YegpUin=&ZhQ2hmWnrWrYq=&AviKtAWiVkreX=&2qVyecXcofmUd=&4BtmFhUracdqo=&BCwJZpYfsghda=&v6HXS8XXfmoel=&4EP7rjV_kolVa=&OYDNGrZokegfg=&C2O2YwWWhpXsm=&PG23o6ZsZdaVq=&BHgkB_Vsemha_=&7razXQWcliojk=&4ITqdzUdZffWn=&7kWDUZUkrafkj=&9vgX8JYYdpejk=&GMESb2UUlYlqp=&OaBPmqXUc_eas=&wMfIfwVeifglU=&bwXGGYXorfhdW=&aRCoTyVmsjbhp=&BjtpRBWjfihmi=&54ZqEpVfcXprb=&pZBR_qVaYdYbe=&ZDOQTHYXWUZb_=&XSpvYOYrbsUag=&BssmbjZrs_rsr=&bjfTV_WeVgqbi=&kAQGAVXpZYdYg=&ofHmMvYoWl_bm=&iYgB9HZrsaspW=&c3_Og9XZjcmqk=&OaPB7QUcsjXin=&5XoozRVsrpmor=&ufg82uYnn_iea=&bx5cdUZsZhhVd=&jkp3sCV_dafXf=&CMmFZgYnqjaZq=&MK9rBvXqsfao_=&6KMZeyYrdnnch=&bLYnalWeshcsW=&VpR2VEUkWYXbe=&lDaJdjVWhUdhs=&KfoEuKVdckXsr=&SognE_XopjjUs=&hDvQFEWYqidbh=&TiNQFtUmXimfb=&XWVerJXodWrrj=&5NNQjoUZUUicZ=&okmOAdVUm_hfj=&D6keFEXdWd_YX=&SyKOpxVednhUr=&ubzgzRXdXqiYa=&MZD2r6ZnqpclU=&TxioiNWfZXXa_=&Bv8S8CWUoknss=&LsQhypXbUijrU=&FUGBG2VpqeWio=&B5Ayr6WkUbhdf=&dk3iVMWjXmYb_=&_CTgqIZa_deWg=&fG9uw6ZWpZjfY=&UmAA5IZrocW_Z=&wEYggyUdYqVle=&y2xFRhVgbijZ_=&vD9PnNUWcc_ac=&59wxYuUWWhWne=&MIhP3YWXehWar=&wubyp4ZUWgeYr=&IQbniyWenadrm=&Le2t2NXUhcrof=&acaC3kZmYgies=&y2_XJmVbjjsdl=&RuxL_aVYhbrmk=&yhf5xFUppkqWb=&VZflXcWakZfWY=&vH_qa7UnVYpZZ=&6hTXXEWsmrmeV=&vROxiKXgenlmZ=&hHR_VkZplgcXb=&SpaBAYYnffrcV=&cRQf9zZlXanbn=&ppsH86ZmmUcch=&7PmPHlYfdZhpe=&NPl2JHZisbjpd=&z9QfNbUaplide=&Z7WC4PZrklVoq=&xxNV4VYndVnb_=&bI8QqPWmlVWkm=&FkhyhyZcmilrl=&hmESdHZonrqWp=&849TmtWqjWqcq=&jJPxPSXr_qsUs=&eJkhgeWUUhrle=&_JIyBcXofqk_l=&cR5_geYsm_WoU=&zRudxGYeafcdb=&_siStIXprqcpq=&YRmnQEUqjYknV=&7gXztUVYfUgld=&faGk9QXUddVme=&n8AJx7WYiirhd=&MwyNjAYhshpgk=&bRra_vVdkrUo_=&qYu4wNXYsnrdf=&OGgfLbUbgWnsi=&itGOv_Yiperfo=&eZdtMpZfZiWhn=&j6gXdJXXhWlXX=&GkYjAQZXepc_d=&GpSRb7XfaUhXi=&_58kO4VVhlffl=&dkloKPYUeaqsc=&nbmMQZUfVbqgj=&c5cDlfWrndalc=&ttgm2FYorcYkm=&8SzDicVjgojYd=&2rKQjJWbmYscg=&roQUxmVjdleqX=&j4y9H3VlrlUeo=&lTOin7WgWWerb=&g92vmWZXrZih_=&igV2ytZVsspVq=&_rlKnGYpnmcaY=&TzfHzoZlkmXfY=&oYVjEuUkffpjX=&_dL8K5Xhefkoj=&UeFNkRVXnpZhk=&9EHOOJXVUbYUo=&J58bfhYgcrkjm=&vfQ8RLYiqimag=&dNkznBUrdYodn=&CcRQUEZshmZr_=&5PUMTAZbsqZdj=&RcVjtKX_gjche=&2zHTO3ZahYpXr=&XOhGecWmssnXn=&mRs9OmWldfjrb=&fzDBHyXs_ZbYj=&PbV7MCUaibcin=&H3ZwBHY_Yjbeb=&iRxxPyXsaijaf=&EKveCcVfghpbr=&eOVyVoZVcakjY=&jSUbnXZqskemq=&ttdNG9WYmhicm=&ECmL4dYeeooZh=&OLNyQqVmXmfZb=&___fiMYWXdUpj=&fuMCTBZfkoVfm=&uQ5_7oUZWWVpW=&zPTkwLZXsscof=&3vmqoRYoWaipk=&lOiTpdZkbcilq=&DqAmpoVmsklmb=&yPysyfZcagepr=&KdkUFjU_eeVla=&nruZUQYaeUrfk=&uoREPZZajjgYj=&IwqdYAUqmgXrs=&kXw488Welbacj=&QL4oW9WUfsXfk=&rMDR_7ZlVqja_=&5d_OZoXZspjhk=&t6GSVWWhdgcmg=&OKmfwyVZeXbdj=&9syJUKXW_afZp=&mYPC4sVncsbca=&eVmlyBYXdWbgj=&Qh3UJeXXaXWjX=&HijVhrVrigpZU=&6MOEtKXrhcobf=&ZJ794nXXZcnde=&ORwQ9pXrdfoid=&WMgRniYpbcpa_=&HbMn8OWn_Xpbn=&URP22WX_cgidd=&27fAFbYhXrbpm=&5_eDe_YenrfsZ=&Ztw5oEWXlsdlX=&zwLDvCYmYWrc_=&s3Ry4eYbfV_fr=&y4AEflYoqfUrg=&FTvKUoXWjVhXr=&nFsXimVkoVqbh=&hLixouVgZWohZ=&6HsKgIXXkqaXc=&cRR_ohVeYagXW=&gp5wvNUkVVnsX=&K2F2zfYnib_ks=&VpMX45YkkifpZ=&gAGqzzXXlUb_d=&gSsC4rUrbegVc=&2JUWiKVhoprVm=&TTg4yTVmmsZUZ=&TCCRDDVo_WWqc=&awIil6Xmhon_g=&PsS9YWVihjarg=&p3ISREXrijdqb=&nfrOrKUkiVfkp=&vBo5kZVc_Yopc=&FNOenJZqnbfib=&iTQzoPVVrlbX_=&xadtGEUlniqas=&mgCjUwWknjnhg=&QlXVtnZZjjd_h=&IZfAEyXcrepW_=&MwtOawZpYWUaU=&O8jlrXZbWhafi=&UkGmBHX_pUXVf=&dlEBueWmiWkrZ=&iMLpNNXpkhhZi=&DocVGRZasU_bo=&wYlf3KZkrdqss=&emlggUZrUfXc_=&lLta_VYnecYWo=&Ud8_k5Ygfckic=&cXdWvQWmiUksg=&yOIyC5WccZacW=&EbnmkVXjUhkoj=&BU4SHpVUfpsmW=&V97fxtZardiaY=&IH3zOsUoWlUXV=&UY9wCSXnherlY=&XR4mTzYlnaj_n=&DObYttYfZobmi=&OORAwJZnoenld=&hmPv4rZisirVl=&2bGCwjUlihYdZ=&tpAn_AZssqWej=&aY4M_LZqXkUdq=&HKmWIrWkZmVij=&ERgnh6UaVseii=&ALf9KKWUnUmbr=&Mmnv_EVYagred=&qylHWgVXdjcVi=&veIP4rXaa_llU=&ANUFGQXdbdds_=&nal2zJVYckbs_=&EsiINrYfhinco=&ceyirjYj_Xilq=&8lf9RXWcqlVjb=&YcungpYVgVfWc=&GZGTuQYbUrfsi=&qTlwYCYf_orYV=&8RRvvNYcmmqpY=&4d4dXHWho_gdh=&nGeeVCZaUXqaZ=&gzUsq5UbmlpXc=&73sy39ZXlhhWk=&dfxuWpViWidna=&I5VcwCXYUjZhc=&tJbxLVUh_nlgm=&bndjYCUrYZcbs=&QGvQ3NZdfcg_e=&B6bprmWrVsbVc=&6PK_djYdiWeXZ=&tjWIPIVmrjhWY=&6Ou3y7ZWnsqZZ=&if7ILQWVg_YXd=&xIT2jhX_rmYcs=&lqytARYWhrlnU=&WxHD6jZdZXdWf=&eyY2gHXkVWnkY=&wVvbSJZfcYXoU=&IBLJw_Wkscdsl=&MpvuWQZojlZYl=&a_MMfRUVidcfc=&UqsUmWYUnUasW=&CC_hjPZYjWifr=&OWl7uJWhgfolo=&I7GBgoZpUnkap=&YIGMPkVUqXjZa=&OFuVXOUUoelpc=&XfwgHDUUfVXfr=&rN6wTZZhZZblU=&gRtPXIUXrdWWg=&wmtFUGVqqcqZj=&JoqScVVsclqbk=&rvrWf3Ynkpdkq=&kKWIbKWZssWmn=&b4mqbVUdXianq=&KWlSLwZUijomr=&xP_QqMVrlpriW=&C2cy6KUnoi_Ya=&TeB_QAVWkfjYc=&sBrlteUqqalUi=&5NfEuNWhnbldh=&t2AOvAVlgaWeo=&ZtWhGAUoUjhio=&kr9YwzVXXnXqU=&445WzOV_rZbgg=&cjO7IfVgYdijc=&6P8NlPZbXhpWm=&yxeXtUUfkWrVn=&rIKMRUVlbfqml=&eO8MukUkVsnsg=&sbccEMWbclcoq=&mKeYjQUejkedc=&jY5GAOUif_jZf=&JUKHiIWoasrqk=&6YWenmYfslnce=&qXULyQUWgkgp_=&mYVCQ8UYmaWkf=&OIqgRlXeXWssp=&IEfDuOXegnqWh=&nFZ_HJWgZ_cgr=&x2ZGWOUUhUYUb=&AVqqvxZaleUYU=&XONEJWUfgg_rY=&WwcdRZZnXgsVi=&i5ocb2VjsfWlf=&ljM8q8XYgZokZ=&B2iot9Wiopfln=&g_dD7hYcpjcUY=&6inNJLV_esfcc=&GfXMiyZYgjiXo=&TXfzIQZXWYgre=&2wX_VmXr_jgrm=&zRac47VqlqrsX=&mnvhMFZaj_jld=&u3FPzhVqioZkb=&sXa3BAVnhlirU=&WcsbKnVibqiWh=&UwOQgbWUkjZmi=&MvHVfaZlVVZlp=&eM7_PpYpqpj_U=&neTXjtUZhssqm=&O4pBExYaVlol_=&Zx9_g7WsYloWe=&8AQxeDUVrXm_b=&HHO7iJVhUeXdq=&t8OHoDWjhqZlZ=&6zq2K2Xbj_iqm=&THdbPYVbpfrmr=&UxdF_aXbeWeXp=&3mRvyJXZjXaXp=&wURhlpWaUhZbW=&aXD6gwXqgpsmo=&fKLFXsYdqiilZ=&c_OhtAYpconYj=&7qCX_JZqYedZm=&9QYSW8ZronmaX=&jOzSJeXc_mbU_=&pVA3TIUnrrpYi=&AU_6ELZfkrbda=&ngTSjTXfWZXod=&jNHViVUcakWXr=&GpdNBVWsreVXr=&BJ3IkoXpUgVVf=&ABiICJXgo_bcb=&8wlkQ8Whicggj=&ymSURcXnkWfYV=&87QBdaXZYpkod=&Cq_eRxZpVejjY=&3TgkqCUmonnlf=&8EHuawWrmjiaZ=&DG6QcHUeUcpYd=&wRCiR4Xindmja=&mNb4SzXifhakq=&3Cm5T2Vsfinik=&H4fiq4Uinnbom=&W3ghZ_WXmocYU=&JpJNPIZaUcqWX=&irUwxXVq_komj=&25zdLYZhWUZjp=&z3_HO6UXqmU_l=&lhOIrAUcXZnde=&zDY3tZUVUeWhf=&FRHUX4Uesakoq=&EhxWXpVUhoaib=&VXB2TBWidd_er=&Hq43NHU_hgrpc=&pUumoIYk_WVsX=&JgC_xOXVkidgi=&zVvVV6Upecsqm=&9hAysFViXoYmr=&9N4nZQUr_aXho=&BpYUIYXdjhUYb=&BTyaeCVVWhcbb=&vBcIa2VVqksfj=&anJaJxYqhXWb_=&aLWshmVpeoerW=&BOCBZbUjjihnh=&ij5ZXSW_cohcj=&CSy85HZoYmlng=&rXViQzVlXiaac=&XJjr_tUeirrZj=&8xbWcVXrfWqjf=&vsLmCAZXr_YpX=&Vv_ddDYmiabir=&l52cFzUZgXjdX=&DkqzbgWnnlmmd=&zp6O9BVXlhYqh=&wf7ySpYfdYVnb=&GiUUfVYrjVelX=&gFUMDoWYelUqa=&Zw8xKBUgbojmp=&FQz5a9VkfVjdW=&GtEl_VZ_r_bqf=&OHTv_OWi_bn_k=&DCeMYQYXZepUh=&zWs4fOYdkpneh=&cCWZfYYdYXsel=&MBl8hXYdpgoig=&x2uF2_Zll_mZd=&p2aA_uZXnsUnn=&P58uITZeWpkrr=&B3iy8wWlligUZ=&hNZlf7XrVqqls=&d4NXjKYhWolaq=&IaHHLAYgYVUeb=&RD4mAdYdYnokd=&FS7fmeXaameca=&aYjiOPXfkondZ=&pdXCcfXYnkfoc=&RQ5bPyVZc_Vqj=&YpPefCVqVdWWl=&6cA3ARUnondge=&JMaqGrYilqbcn=&oG3PyCUYfmdcc=&7y_sahWpnmqom=&99BPQBWrgsfYs=&W2A4ocVrmXehf=&KimUMsZWgecig=&M5hZoSZkUlskX=&wRMKO2UfoblUc=&7yTLp2WXdrfZY=&9FEWNGWbgrZkY=&bYv4sWXblZoie=&IPHYAbZpcdklk=&oFi2WyZYWanh_=&4jOzCGVYd_Wci=&TKvBmFZldYsis=&JWMRTkUqbqYdY=&jcDeNgZpfnnli=&OflnCoWjYbUag=&J3GB6bZXccrka=&iY7jYjXYhgmcd=&xciFIuWZeigjX=&ALIhssUZjhscW=&i5sldAZmVckqb=&lbZTlTUjlipaU=&M4byInZighas_=&GUy8OBXof_nUq=&rxq4qYUhZVXln=&UgpFYoUZ_qabp=&uRuKwfWZgUkmo=&yhIFoZYdYf_oY=&dWAHATXskhlre=&pfzjoUWicioZi=&EdjVriVUdmclm=&wXAzBNZsahblj=&Gs7Xy9ZZrodjj=&UFCTVXYaj_oiU=&8SQ36YYqZsZXi=&dpUNYPWXnZXZe=&2wjYHAUZZqqoa=&qEpXzuVZsqXfa=&VeK2xqYoc_shp=&qXjyKFYjZjeqX=&QAxk2HVkhfbhl=&zkOoEyUZjUdXc=&iqxKYuVZaXjgi=&H42CyGVcYngss=&BAdROYUhVrUbm=&cewxBMVoqWeUW=&xClShLYfkVjmk=&cXsysRXgXnUcg=&hBG3MpYjVVhjV=&iX6XnVVpmjeUZ=&IRKx5kUhZUsbc=&Wn2YYfWheWWpa=&ygbdqTZYrakfV=&RsMnsqXnVZjYc=&7By9IEWmlrqbn=&bP_YpPXVeZe_o=&YRbPxmVqhmc_r=&Qv5jrHXUV_qrq=&CNsaEOWsbsefk=&Dgclz5WpdmWfr=&reyxL7VobmmXf=&B9xQJyWqWUdZg=&xzwbQIUfliaXd=&FbhSQyYljjmsb=&egExdwXq_YhjW=&2O5NBAZUYXfor=&WXQT8VWihhZfZ=&PHUCVSVakdngZ=&iFfsN9WimZlXZ=&Q_q7HZZ__nprV=&tCwyVeVaqmhoh=&uoffEoYWldXVr=&xhAQrQYddlsha=&apIwnfYnqg_oj=&Lkhjj5Vadrdni=&7K8EF2UeaVhjn=&cyAE_UXrdXjiW=&LwyNaxXmqrkfb=&ir8OwBYemqXjg=&MXGAeGYVmplnc=&e4YJwLZW_kere=&igylSTVhfqcci=&rAWyjuXhnmoi_=&3aPFhHXXbodip=&I3VwcpYfmp_nq=&XIQF_ZZpnfYYi=&bvy7dTUigajdd=&mlsfQqZYqhmXm=&9QEkQfXkmbhZg=&rYzUs5XmjcmXW=&h6KaamXfriacq=&TfOj92Zbgeloi=&FHitpIVVhVrpl=&fSE8SuVUXVljW=&aUUyE6UjrbVas=&99XgEkZkX_sWk=&Vsj9u2UoXaWcr=&eFPXCAYieVars=&aLoaFWVXUngkg=&OQcrklXZVVisX=&PdXEL2YkpXg_s=&kG7xYmXhleYrm=&7idHezWneamVa=&jF6UF6UW_pYWV=&2fuCNVZeksdeX=&xN8dgVUlfrgel=&9Ro_j_UgqelgY=&PLXCuEUkrpnri=&8KTxgzY_gWonY=&naGogKZepVqle=&cH3qe8Xfhsi__=&66kF7rXksdkZc=&Rv464VUfmUerh=&pGh2G8VfabheZ=&jCTicPVWrcUrd=&yVLALbWdr_Vjp=&oYSH_YXXcgmkU=&CKNIvIZkelpnf=&wRHXP3XWfYojU=&3kWIypVgjdc_b=&7MCRdFXi_grhp=&FfsmsEZYlkbXZ=&SSXyZQVosogee=&JBeCyqVdlqfeZ=&3CAXd6XbsVmgZ=&JKBzpaWsqVaUY=&BO8CTkVsjXrhj=&bYlc7zZqqmeVo=&iLGEzyYWejnXg=&NP2zRxUbeiipb=&HiWWjgXpqhkYU=&KSlWKMYibgjlf=&4e6AdyYbil_me=&3po_2fVsYkgVY=&umarAxYsVanbs=&_Y_nLaU_XUpYh=&i5SE_ZXknkVUb=&EINUQwX_qZVjo=&Ae7WP3ZpniaVg=&H4Pfu_YsnXdoU=&UAqy79WgUq_mj=&tLCOcgUUfpogd=&TADqwFYddZgUr=&j5aCKHWaWVgms=&9CShanVqsZUcV=&9ZXpGIZsnoaVd=&EEhQ8RYoYrYna=&f_zL9cVbmhYif=&TwiUx5XsmZaWd=&WKZj8dYsqfaXp=&6jwXkeVUqmije=&IzE_RaWgUVpqf=&8kRDmqY_cifdm=&meZFZAWshojpn=&rYQCXLUelmlgs=&5q29QyWodkkWp=&o6IpzNUnWsd_l=&5LRDXuZhagUgf=&vriUIMXmViZpd=&RkL2aeUljnXnn=&bRKWVxYekVpcb=&URpxwvXfooUkb=&_Qb7yVWZXfdkV=&gM5cxTX_hWfnh=&PBoXELYnfhmhn=&d2vnSfZbY__oq=&Pg4KFgU_eejXa=&zNKiaQYkaXqk_=&e4c6sPYpjdo_Z=&QgDn9sUcWpZcd=&SmG_h8VhpYlgr=&5hc3c_VUnXgql=&cKknycYaZkiZY=&ciYEx9VWZjUen=&n6BPIHWeUnaj_=&A9zz5yVsXZUss=&92HBByZYWmhn_=&aQcXY8VVoosbm=&xkQiQZUbpilfn=&WHYmDiYZbcikh=&Gm9YEtVdlWpZr=&BYZbAfXnXUrih=&GYcAfVWZYcYcq=&abuKB7VmiZqpm=&8xbb52WleWclg=&T5imJHYVnkjZg=&VxVBphZWlgZmk=&ZIfeedYsVshYo=&y7w4JgYkdYoak=&MWNDKKVmdXkUo=&BO8OqWV_sirdU=&bqBFbeZqbgUqh=&Zz6lfsZbrgVlp=&eBpMucZpWUeWh=&k6XonUZsWZeoi=&PyIAePVYckkag=&Ph5sIoVcl_Xmk=&ASRUBIZepgZig=&Rv6gBXV_gfiVZ=&dpELChXZaqfUs=&_6uF_LUVghmos=&xg_KARZoglXmU=&c5r3n2ZWoeZ_i=&S3mZB6WlnnlVZ=&_EAzJtUfZXVso=&IZ_f_bXilkrre=&_MO5niUqZbWka=&i3fN2_VXVnZaZ=&VmOWoOZdkarfm=&YOr76aZcpsbpZ=&ifS6gXXnkXelU=&XewNDlYk_UVia=&eGhUbJZripYUl=&ofI8UcZZfifmX=&4ByAPNUYsospk=&B2VqkfXYVrmUe=&SB2oIwYjYniXi=&JTolPLWofefjX=&svjSINVnbdnja=&vW9dqJVZqfVeg=&AZIbSAUmlm_pd=&fHu4_nVgZcpeY=&t5xR2JUlVlYkl=&SOEsTLXnVbcXs=&yXgFkmWlVVbZg=&BfWUNoVlmsfZm=&9ZZtYkUZeoo_f=&SaOCrVXpXflsm=&O4E_pxVho_laX=&xHDql5WZZhXng=&zJBMlLXbYZsWd=&t4JOAWYVkgqZW=&ddZ5tfUpagdhl=&Hn2sZzYqVgVbV=&aXWXwuYZWgmoc=&pAKyzCWsgWcfq=&vxYR5lXkqgYkg=&SpzIvOUinXsU_=&uzRfOmZhsriYn=&DCavLiYWXalqW=&FXkcGdWnn_ZgV=&KOgwQAYXcUdmX=&GwsvQXUWalVlW=&58ripuYfksnnn=&nNAQvnYfgoloZ=&Cc8M3LYsZ_pja=&MF7T72Xcjfrdd=&AYiqkJXcinrne=&rITOFNYpfjqhf=&bgJNiuX_cmoar=&VzDLiJUjobjaf=&99R8a4XUYkr_o=&nmuG36YVnhnof=&fHuh_VWYosXYm=&4zyFwQXlYUYec=&cVjJowZlZkZqo=&3tDiLyYlr_Yoc=&35PQ7VZiWXbnX=&TVuDhbZYrsoka=&ijDxIjW_qphiX=&Mc5CiKZc_ampn=&PzftZcVhXnhmh=&38_juWZk_nfek=&3q4DopU_fZdor=&ruPOWkVrYdfhY=&zjcLEgUikqUke=&XXB7iAZgmsjhX=&xNY9dRVkfholr=&f5ujqCVprqmok=&qkmB_hXi_esZp=&mGiOfSYgqccae=&LKXNaHXlppXpb=&ehRRGaZn_cjhm=&jAQTdqZ_XX_el=&vFxEUiVhZgdjp=&vfiraCXUoVV_b=&yC2rSTUaZskkj=&6D_Tl3YWWgrhh=&gz5dP6XdhkWWq=&rpE3fEVqso_jg=&Vf5GTPYjedXjZ=&sBn7nDYiUcsWj=&aDLSBeXrojjfX=&sxPyJzXgdgcip=&KRhQejVVnasjY=&ulLVLpYZmUaho=&NLpCH6VUVkWqg=&oDMqzTYsjcgZs=&inBIPaYkddsZp=&zTtLmHVfihVff=&nmAlRKVcUYVia=&CsiI4SWYlkjkk=&8FGbPrUn_cjXp=&BGAptwU_sfqgd=&OPShfjZsqZ_Xo=&dV8YhNXcYjbYf=&o4PKhJWckWdXh=&4mFsV_VeimXhl=&t5biJEUhfbbfp=&IVdONKUcen_X_=&WPUDN8ZhjYWZl=&mUWPORXlUknke=&SvreZkXhXgmna=&PkXVrpVnropnd=&OnGixGZeUespb=&nHEo7CUdsnUXW=&G567b5YgnhVWe=&kFi7weWpkaiVm=&MdGMyRYlUjUil=&AxLQ99ZVnqaUi=&zsTNaTUodWmgg=&izDfRrXdcXkmp=&OrrbKlXfnphcY=&gNRtSgVaiiY_h=&S_ajpvVjbcZo_=&TFDPZOWUVZXkb=&l3aArEZr_Xhro=&RfZxygXZemgfc=&nfl57OYnodsWa=&sdcgIGXghYbVa=&DPhq7OYZaqiap=&aQAy_mWeaYZZV=&7icruPYZbdhiZ=&izqhsLYg_ifVc=&jI5nG6ZZmgshp=&QfcrPdZVbdfdn=&j6wDg_UmhjjZU=&dLiht8Zjpgkab=&acqzACWfYnbmV=&J2_efYWnYffaZ=&GWLibnVarabXc=&J4zwCMXmZadmp=&8M28CuWkacUqY=&RRnWUlYefamrf=&ZDWBIxVrZlsWp=&bK2c_sZXY_oXU=&hZgU7dXpWpijY=&MlTrjwWhmcfkp=&U2G5w5YYfsZpf=&WIMomEXjpZaef=&bTJ5hpXdljkYW=&b46NZzWdUqomk=&YsteiIZlsm_eW=&CXvHbNZUfZVhn=&WDJjQKVVXppV_=&anlE5IZm_kmY_=&A9kutfUgknfli=&JnWazaWUjfnZU=&QeaDxnYaVXUgc=&XpV9lPZZoipWZ=&2TxvcOYgomekX=&nqkveCWZkodYb=&l6NROAYZZbsUe=&QwhIiuVmf_skU=&XMURjZYgeqhao=&o7RISUYZnlhWi=&dKLi7NWegeWdn=&o9MLFpWVfqnV_=&mWBGizZqpmmcd=&uE6SUxVYdiWd_=&ooJN6QW_cimlf=&wxuBXcUskgrsn=&uNM73nZXhppao=&NjmQCaZdkpoYq=&Sbv3r5Xgrkh_h=&bgZUT_XoXZbWs=&ZqoBWLYVaflXg=&ClGOdmVkZbijr=&QW6RRkUsdciir=&TVIlBmUYofkga=&KfIUgCWajZoai=&mzBT6oXkdgqaX=&_wPeMzXiZidZj=&Bt694NVcpabqV=&2rZV7pUhYmlkU=&M4XawBZ_Zjhmo=&WOrqKKWUYeolX=&cqfvc8ZrefrYm=&DHznA8UZjlhqY=&Oaso7SYmhnaeb=&BxLaiSWa_UbmZ=&w9G3wMZdpjUmZ=&nCvxSeUlbqnUp=&qJ4Pa_UZVXcYj=&nTmuznWbcbdoq=&xY7q4mZoZfY_U=&taueA_VYdYmaa=&WdAQt9Vnbdfsc=&XVEtT2WdXmaci=&xAuOjwYlWVsir=&5JcM4aXbqanVh=&7dQ6dYYdhbhlj=&LCm38FUhZjsdY=&gP2wobXnneqlc=&JWWk6TVWnVVYe=&zkYngyW_hnY_f=&tY4FeOWbpsWfX=&cZlfrjXdcfohk=&uxkQTrXpXesfY=&4rGTB4Zmqrkdd=&tFeBpNWWcijgj=&qwIksnZliZYho=&logPRwYZshfgb=&wOU2cEZaprsZa=&gOjKexZ_cnWcr=&vCvI88WZdoVas=&LuXxCRXiaam_U=&3PYKBeVp_eZse=&oro5RNXedhZYo=&UBrKDrZgmeYlf=&IAdmLuVVbrapc=&G3cSevUVXfYVs=&Iaq46CUfbllqb=&FsDqv7UidWsZc=&tasX7KXbodfYr=&Bk9ZGAWrohnUY=&65TzibUcVWcei=&J_3iZtYnd_jrW=&a3mRQvWblnsVf=&fuesTkXhmpUVb=&uUjtwDWWgZahk=&GEqCPXYdZdWsc=&b6FaowZZlmrYY=&tM2yP2VbUmgoh=&Moe3gQYW_jgpf=&iTSz6gXfbkpae=&yjwjEDYpqUgqb=&QwLXREUjUrsqo=&X8l_KQVrmimYW=&gFCLT5Zd_Yrod=&VFxfjEUdgWmhm=&XM4eYPYbdYhiV=&R8R9QqYbnhsh_=&uvTnRsVegmrha=&NIqBerWfWbVWn=&4OQBGsZflkgUk=&NHgkpzXVnpalm=&vby8mUWfndgoZ=&B8_hgYVsnnfik=&5DJd6IZYrUojs=&btvzZ_VhaWcjd=&b9GysrZofYbiq=&RAWNbNZXhhppj=&tTh2fdVqdfdlg=&FGEdwtYghogmr=&rPuB_pXfbcWq_=&aoJ3PvVVopsrW=&XAfMbgWiqskZr=&4qOs2JVhZdpih=&Tox8IoXaVZedg=&KwkTImWamjbrj=&YQVXhKYVbrVq_=&DXVRZRUpjjmjZ=&sm9KozYbflcXU=&BqiErgZrdVsar=&pRGfYXUlZlZhq=&VH_sDjUoUsogV=&GNF4jFZqqgXpp=&jvCp9UZmhshaf=&IknfCQXWkrekn=&H7G6XyVWolUjl=&hMNMnyYmdegpg=&pZdueSXqpdpaa=&5knPpoYsaseg_=&CmcGASWaZVYX_=&wxrlrhXmhacaW=&4OsqqaWbqideg=&U7mQaVZsidVXk=&xkuk3xWZYrpaU=&UsUhbZVZciZZm=&2oeo4eZhmXlYX=&CC_zwlYnfaZpp=&ipLVPOYnpfVsr=&8hpu_XUYrVjY_=&wJ_9u8XUffYXf=&emxjyNXpUXhgc=&PJ3GzwXejYnsf=&PjrrJOZbscenZ=&EerIOVYarsneX=&_V6FUfYdnldh_=&7fEEDsWdql_lm=&DtOgtlXkUYeiU=&6HVeWZZZcrVbY=&uz_szoW_jXreq=&EhqOVJWaYWWff=&GYLyjdVpakrlq=&Z6SRksVViWbpY=&hHjohbZpmrYUp=&QF7LrKVdbqfZn=&8KGWaaWlZZkah=&VBxVqGXUrgldd=&IyLPOsVYp_siZ=&IRQEfGWgUaegV=&orT6AkWjhqjhc=&J_AaLpVVqWi_o=&gdMzuSZschija=&bhu_n7X_gimZi=&BL9Eh8ZbalfYf=&OALr93Wpqd_Un=&j_wWLoYfsaqUq=&Svy3PRVfjY_f_=&BciijDUhsq_dk=&WYWm7KZpirinj=&b97pmLYnoadbn=&pulOdnZrqWngc=&VXXcEKYsmqplg=&C9gHQ9ZYUocUd=&N3VlemYWaXfam=&pld3DuWlZejdp=&bYrSRxUoksrck=&KGOIdMZZgapUX=&xrvUk6Ynfs_ef=&LspQdhYssflZa=&tSmwA2VqWplrn=&WQqVLBXlUVmqh=&JMMi5UWVgeWkj=&fmzzP2WhkoUcf=&wIkVhFYXboblk=&Mc2SDeW_jrcnm=&wN9hh3VeUbXsb=&JGeMFgVVZaeoq=&vCO5xpWWXjrmr=&op7ZbiYUgoicc=&Niaw_xVhdVseZ=&PR_7u3XZcnXdk=&3x8mrhYblWfWo=&drmR8eZmYXdjr=&B6qZfpWr_jnsl=&zEY6PKZWhlniY=&7gm2w8XioXVZn=&yDiZwjZlWhdpX=&JiV4ogYsWaYjd=&iCFGRyYhXVebf=&JtKMgnUYhsVdj=&zqEtQ6Uirbjsr=&oNoANyZraVdVU=&CjVQIUZglVqZh=&VQOyXPWZfXUWn=&p_3UpvZbhcWmj=&ZmnAGVXaYjZsb=&cLFjDtUVnenop=&5o6KPDZrqmfdo=&UYP9NLZVsieoa=&37clxSYZbr_Zn=&dfLzGYXjUadbX=&Ey7yuQYWgbWlZ=&LmqCzyVjjhqWd=&i5AGOhYbmabss=&NGD7J4ZWpljrq=&akTMSNUssYXos=&ephRhCZrWUslY=&W_OD3aZngkYjn=&2h3oWGVkml__p=&DBdrzFWbdkmqh=&fTRltmZcaZjsf=&JJsqCQVbVUslj=&TYWbnQZqWpXrW=&8j5eJiXsVqUqm=&r96o5bUiXdhnm=&riEVL7YginZdj=&tBc7C6Ypjpric=&LdtjvuWqZibYg=&SNglLaYVW_l_g=&LpVkDeZkoo_oU=&Y7biDwVsmberq=&uKntAMUYYqhmc=&WTOoxwWrndepr=&8D_nWdWYq_rcc=&CPwyTcWekUbjX=&vkeGmYYhgUpfp=&8QOhPBYehZkn_=&xqOXxCZVcjeUZ=&SsC3CSYfnYbfV=&8SgKszWpfcmZc=&fTjY8xWoYndmm=&263C2EUb_jkbp=&LMLFj9Ussqscp=&pG9fNDZaYmVoh=&5FlVs2WpYXhmq=&WnD5cqUnmadZs=&2WHLErUYgsWaj=&tfUveeUqi_Wai=&IOOnjjZefridq=&cDNitDZrjs_hp=&wENXt7ZYklWec=&des3OCZforcZU=&ozfGW3WrZjWqg=&yOS3uQZigXjac=&L5Y2ViWjjZpeg=&OCmzQpZXqplVa=&WhXHlNWmonflX=&PRAJr4VcplhqY=&U3dDpXWalrYXo=&Fz7gDCZanndoo=&yQ4pE2VdglVkc=&m24KqGXdlVViU=&2O48FOWrkpZpZ=&yyTA9LXgqqY_o=&D3L2xKZaYUenn=&uh2US8XeicYsV=&VXvOkVUrcZWeb=&Oqbcd3XkhUpie=&KX_QXCXVYi_pc=&2_pDj2XaVrbdj=&sjw98VWnpjgVq=&V6MeYQWel_Vod=&LDvU5EWk_kXir=&eMOSoLZgnsVba=&lNAzM3Vmedmae=&XlqXtzZrjjiYc=&srZyjSVqqfkfl=&n2v69aVg_pcmr=&IpEcSaWXibYlZ=&ER9dV6Xp_kUlm=&BGeT9SXVsUbag=&npo9iHYqmmcrl=&GPJZDwXadnZhg=&IfZQgwZlfYWlX=&uHC8riXXYlWcX=&8fFLxRWqWUqhW=&8jTMZEZUVbZol=&FjnB_iYZXldiV=&fwpZteZWkpm_Z=&x3L9UYWmdhsfs=&ct5ZQ3Xqmfkjc=&xQ6Hv9YsaaV_k=&pVl7eTZUglWlo=&_iInphX_kdkdZ=&TbRBdQUpoWnhb=&E8_BGWZqeiYdf=&oXszJvXghelpf=&LKOSjoZnkY_af=&oBqPCKUkbdpgc=&czcW8XZnnjadX=&uN2zygUgm_fdk=&nsFPTrYgUoeoY=&tGETE7U_ngkek=&gqk8DmUsroprW=&ducCwDZdemlUs=&oUTORXWXerUsm=&mczcSfWWsedpj=&TKLlLeU_pskdp=&5OeJ_4Wsimrie=&4sTfn9YbrieXi=&izie43Ucdalmr=&cpgUzPUe_rWXo=&5xsxDMYWXheYm=&XwyfIdXcrlr_s=&ZdM7K4ZlWZgin=&T8w4BsZkbnspf=&L8jTmVWekeYgo=&XWQJIpXo_eZUq=&Gbd7PmWiUeeln=&uXtD8lWnjZWsd=&cpEZx9Wqgkhpc=&VM9XhPWobZhWW=&zd46GMUZsVljr=&pJRRwoVnXqmZj=&Ke82TvZbeaphl=&CXuEFVWZlo_cY=&crbzsKXerlZek=&U8EYkzWXlkbom=&KbqwMEZgaosh_=&dgYAJUWYskpke=&43jlc3ZcZXebo=&kCxlJ9Vcpjeja=&WBkZOpWaUfnpr=&2KnIO_U_hkWma=&xcciv7XWfciYX=&nzG99AXUdUohg=&OiJMzuWYUfqrf=&tOQztfVblo___=&EKe2ofZjgefeq=&fV9w9WZoiXZo_=&CvaH7SZqjpVWn=&5ABEBLVWeVedd=&xClNe2Yofcjpm=&kgOCMrVgXVmXi=&Ppy9FpZlqprdg=&vZzZDGZjVVsZX=&5ZQXf5UdUXrj_=&e8LA7pWgdapbZ=&FTnFPxVcoqefX=&f9QXdZWnf_dYo=&zeGxEMZdghrpg=&LxjsNQUUbXZhV=&Ug8pv2W_iqdmY=&AWiujPZ_ndmUe=&bh2yjLXXffZfU=&qXMiUuVYp_Xh_=&PrPVt6Zmpj_Wi=&MJyQOlXWmiWYi=&wzFGiDWYalUXi=&X7THutXrZWWiU=&KWHKI4WgZipgj=&cJMnSOWcfZg_V=&5pxO8EWaUcaiY=&v3zmKpWeffbkf=&ho4b7UWcsmfhU=&x6_z3IWpXiaWi=&TY9Yr8UakqWaa=&NZHF7XZshsq_W=&Qu_gJzYicaola=&SGSIh5Xbponfr=&2cC7UmVnqsZUl=&PwNWYgUVnklZd=&PmUARVUqWsgog=&ZME5H7Yhsj_Xk=&3WWIKPWjpUabn=&CeqdMTWkdbqri=&QghF7nWcrZqiq=&Txctj2Ys_hjVf=&F_ngfiYUeXZae=&yOFPamV_s_s_g=&hPsDb6Z_oUioX=&jbanZRVldojbp=&hbTn2EVXbqfs_=&OZWnLmXeZldld=&MmcSFxXrenjbW=&A865tHVWo_cas=&TpLZQXWdccgYj=&DqvnmTVaVfVdo=&VsJWSbVmqYfbn=&CRazjPV_WqWcW=&Jw7ChsWcYWlWs=&Sdw9ZLYfremeW=&A4rWbIYrgkeiZ=&yXuIxMUWgWhZf=&SmCskFUm_fbfb=&Z3LveeZk_pWai=&KmxxaeVXkbl_l=&kBQgJgUgiWosh=&KrCTCkUsUZVkr=&GP66z3YosUnY_=&8PZQSzZXbfcap=&m48f3zXnXnqdU=&vpvQ3AXbXshlf=&2taPohWgZmdkn=&cnN7G7Yqoolhr=&hvVAvQUlUpbge=&vvpEz2WXUifrh=&9xOfSLYgUmmhj=&NNakH7Vb__UZd=&AjhoIzYajmbUY=&PJRoUIXUrs__c=&W_LOQZYbhamhk=&o9y4WnXaVseri=&hXlgwCZ_Unbdq=&QNEOIOUqUWijf=&fAYbcUXiabssb=&J4GA2hYZaYaco=&4VomPFWcZeokc=&huxk5KVsidelo=&vmNUyXVmfiqll=&OHdpKDYq_bcqa=&hIECleZhZbcpU=&pXlnZCXjbXrps=&Xh4Pu_YWXpjZV=&9KXiJnWsjhqbl=&dJTt8UYlkfnVs=&gytcprZlUWlZ_=&mm6PDZVmdirdX=&JLiZ39UUaZpZV=&b7qRpOYnjigea=&wzwdjNXWVVffm=&FcfKwFWXjspqV=&wu7sKpYXj_Vkb=&cgzsTLVgrhnks=&jKzoaiZirifog=&zZdJuaWnWpnVd=&themHpXgofdhh=&zIUAQeXVhrjdk=&dIbuUuZdgWkqr=&zxmSISUXWcepb=&L6cpQEZWoodsq=&ahr3c5Wgc_qYh=&qg2gT_YaVVpfn=&CylXH9UnrqV_n=&y5_aRSWgdWlhX=&XkKjIAVVsedZl=&jRoZuPYiXWcaU=&Ib_jqVZenVZpl=&QAMNOqWrWkqWb=&p3CjvgXbsapb_=&BpYwZ7VXhdahh=&bgaCDeXeipXUs=&zFkQ8WXrirkfi=&qVSuGbZjfUplW=&SPLuNBVdcqXog=&6pky8mXqslXeV=&f8KU5tXWeflgp=&fEdB7gYgsskmW=&bNKh5PZjshq_q=&gYZnF7UZraWhV=&vUqKMnYVXbmlZ=&KkN4w3Zg_Xfpl=&YKPJu2W_YlrVb=&K3HrCkWjkUnrU=&L9Fw7AYUhfZnp=&gNzLCaY_ioYim=&gZPoDdXkcnief=&EX3bSKZscVUal=&blPaLcUWojVpc=&_nObnsZmgfidn=&YVcisBZkhVbYb=&FhoKrIXelqWXb=&PET9iPXcoUUqh=&ke5nL6VrbWYkZ=&GfQDDOZm__nie=&FwtxVsWqpYmoq=&Rlpq35UqkoVYZ=&DpHapvYfaW_gp=&LkJKhGUoZYffr=&UGky2NVVgenlr=&OQooj4YVrrmaW=&y9YoCAWgkeqdk=&RuX9bfVVUdncf=&hWiXspVZm_ais=&DcR_eWVn_epbh=&EEoH36Xl_hUUs=&8yDE92Vikpspj=&3s5ebfWensqVf=&mhDhExXdd_hhs=&Bzp_B8YgarooV=&tvJCgjWoWneXZ=&PH87AKUWjocsr=&3WVScIWgmqnX_=&k8tzriYhqfUVi=&MQyW2dXgkroeZ=&AcjfOsYaneamg=&RiNJiEWbjhcds=&Tn7wImVXaYjYa=&WQaoBsZckoUbm=&P9cwN2YoceikU=&KbvuilUfYZ_Y_=&dfTFmtXjeXWWZ=&DywSsqYmVmn_e=&EaYU_uV_eWX_j=&K9mQ6zXngdbVW=&htWXXwXWsccZl=&IeMlUTXXgjlYd=&2hOYpRUggiZlb=&gHxXzEVbjWYpV=&JJkNppXadeoUm=&bxcGBsXchXUal=&9ExXnBVsrckjg=&fK2eSsVm_jcUf=&iTFNuQXdehecV=&CUV2k8WZUialW=&udAFi2ZdVsaYV=&CAV9USZgWochc=&WINbC4XqqcjdV=&22_NVHZXXldmV=&ySnU3DVraWYch=&iPeBepYgnsoer=&kKXp5JUginslW=&3NtUFkWZlXqmf=&h4fS4mWdko_pn=&ajvr6NYggWrWZ=&7RalfpUjmpUlY=&P7ggAMWmilbgk=&bEzGFPXimqoic=&RyzovvXbsk_kd=&7ZxlpuXbWmVss=&rY_fnHWZmqbkr=&I2RC7XUjjmWnd=&KLN2eBVhWlYmW=&aQlgHNWobsWhe=&ibwDF2Zerbrsh=&MuzqfZVUm_iaV=&zckIszZoVgeV_=&gWmFRrVgZnfce=&Mx3gTSVWiZkpo=&MhHDfXWXa_aVW=&t2zSbUYZbUZpn=&6Icd23X_YmWob=&_6Xn63WpkfaWn=&Fl5k9mVVWfiYi=&hCHQpTXrnYjb_=&A5ckUpVherbZh=&_q38MMUUakajd=&7fm4SOVqhqkdi=&EzAqQEVjihmrk=&Mh7jBIYnoZpdc=&gj7fMMWgjaqUW=&Pum3eZXdVaaWg=&8N2leZUoaoUZl=&PIzW6kWZkgXgs=&VP4tatUiZnnYZ=&VYmaR4WbVUY_c=&e5QJeAWkVn_fr=&zIajC5ZaUZakZ=&tfRVHYUifVZlW=&KSGf_FWVpn_dj=&nz53zxYYWkmjs=&M6kGqJYsbgm_i=&TRYWulXiXpqaf=&R8Ob77Zcsjqjl=&s9DuQYXkcVee_=&FnfHeBUWlYZbX=&P4TwMYXVjjZYj=&l8mlxmVlVbmXg=&qLSQrrWXUqZi_=&Tflh3VYspeiZk=&FGVpvTZjdgnog=&AzqzRgUrcbjrU=&z_eWGcV_VncjU=&V69R7nZonmlcU=&voUMOaWhqecqp=&VAIM6lXfiZdrl=&gwfh3QVhkZmdb=&fmmHH5ZsYcdbj=&AOu4UzWcnqUdj=&uUZvJ7Zhonmdg=&SidlR3YhkWVlj=&x2nPNMXqZYsic=&hun7UdZieacjq=&USZglqZbsdrrc=&65GHAXWok_icW=&5wRNxFYZq_qjn=&JhgYhTXUspZsi=&ghSB5sZeqnfXb=&nJR3YOZjplesg=&VpnLTTUgcklmm=&pA6lFVXXdaaer=&LUklzkUforXhY=&ACsVNZXVhlnYX=&dmddL7W_lZYjU=&wjhBUqVZcrYb_=&_fsJ9dUpgoZWc=&hHwfVsXkpnVab=&JYCbrhWeU_gcr=&SIx7iZXcbaZo_=&bIWskJUWUlcfX=&XESe3LXimUhil=&afZoylVZYZbZd=&4ssuLuYcYagjY=&Rqxb5FXXnmZYr=&USDKtkWY_Zsff=&ariGJ5YZkZje_=&kNGSVaUkagoef=&8aO3jpVdWlUVq=&s6bQT6VX_iej_=&DgN4gZVYmslYl=&JbRyQgUcadZms=&CvV2kcUUrpaa_=&id32n_VondgiV=&pztXI3WUrppom=&PBGly4XompcrU=&I9CYKfVrXsYmf=&ovPjQUXpefrgm=&CtCY8kZls_eWd=&UljjQiUbeolcW=&6tAB5PUeakrnj=&8_UfotX_nqZfm=&2amejJUlbhWqX=&r4JLxbVZrdWsZ=&zmbrVXWraVlps=&Ff8SgnWbfaYnW=&w72xszXVUsVbo=&w6RBjwUUhsppa=&sP9JKtYsZWipo=&ogm6uzUjhslbV=&I6J7YjZcprohi=&59blE2WZaojqm=&miNKD2WgWnejm=&oafAGZWeprhkm=&eMGnf3VrhXpdV=&wSGTSLZbepooo=&NkC4kkYljZkqq=&oQvfrEYpikbYo=&3CPML3WqbrXdd=&3G3MciUfcqqYU=&HEpZNpZWcbYci=&6wZ4hGYgqgqqX=&YOBS6LYXpmiXb=&Q5J_euZbpUXme=&j2UOvIXp_rZii=&ptoTyoZjl_VqW=&53MB9fXkkfYbq=&cz8GjCZVoodYj=&6BGNZzUrqihUo=&HKDxBYUfaZaUf=&QS4HT3WpZqhXo=&XQi_pmWrYqjfU=&4vmCQiUUqeinc=&yrp8qXYheXUsb=&rgE8msUopVdcg=&ab7t9SUli_pYh=&FniP9ZVohqe_f=&iNzVcyZpsfZUU=&rN7vQdVUsrhom=&B6YI7YVifamab=&eArzg5YbVoZma=&4jbtubYnfYZro=&bEXCbaZs_lqWs=&HiUQxAYoqgWYn=&_EuUjgYbqYmpq=&3GbbNFUdrceUV=&9_esKPWcYgnqp=&CQ3H7NZasas_U=&D4msNPZhZYlVi=&bKOSkmYfUUloY=&RyByTMU_cpbfl=&lFY2syYfjikk_=&z7kisQXVfdcmY=&NEg3iDUgrgpfU=&IXv4BVXroZhWo=&87T79YWjdohdV=&fhVxnNXpkqrbl=&RGdHcWXqfmjda=&uQmhVmXepaUqb=&hXZg6HZkrelno=&3w9EqdXfneirk=&qoHuCAWfgnZba=&oPvZsDVemirYb=&LLvL7FVipgUXl=&Ef7nbwWabdikU=&wBdItvUe_jcei=&eNWQCwWUpejoi=&APsD9XVpgnVlp=&BKimn5XqZVWs_=&6snN4dYkqqZsr=&GObmbAUpYgd_p=&a_8AiUXdZdapr=&PJccOeVcc_mkq=&xsRhgsVhmhql_=&uGe2Z8VrkjiqZ=&z4x6dpYeZhWqr=&Fi6NZWVUeWgnj=&LpfBbeXV_Zlak=&jcpJWZWZsilqn=&vfWQs7UY_nlUd=&LrcwjrYUeUjec=&tY_UmAZrgXeWd=&LpLFQsUcnYqgi=&DmGmZhWnpsYnf=&5QLcpKZYcmUc_=&phVYcbVfkjenl=&D7WEgZZqkWder=&7GpW99ZikgWhm=&lugL9xWmdbim_=&tzw_Y6Xmikcib=&SxBD7dUsrVidk=&YgCuYnZUjerZm=&2bALHqWXrsYbi=&YvvjKiWjmscsr=&HwREqtZeWpUdr=&jtXz64XVb__UU=&6UVsaaX_YUcWm=&7xTj5pYXndlZo=&WFVRtXWfgYadm=&hxcdlgYnlrbsr=&frSxTYYWgp_kc=&Y32_wrW_djqWp=&QlYly2YgWhWhq=&wOTfxkWaj_hUc=&jlmwGSUcVgkfl=&qhCd6AVrWbefe=&SccFvIUsghaca=&IJf3yoWbYcpjm=&b26yOHZnYkqlg=&dVK28WUYWkhXZ=&tknEwyXcjWobU=&HeHoYuYbVgegV=&smYpDRZdWflpV=&8D6B9XWeedhlb=&wm4lzrW_fYhcV=&DT9WuiWWdfish=&El_usoXkmnajp=&QvvmvnZpcZZqr=&xX5vEiVsVlpln=&US4fiiUmookmd=&5pOWvPVhVYdhp=&azJaFZZfUrgss=&Kvm6UQVrjdgUn=&_LLYCOZYjZooo=&C6pHcbYYWVhWr=&5J2uw_ZWabYba=&bUGKSEZXhpVl_=&9jmxL8YapZhVb=&IKau5cXYlZpli=&TIPYElUkgr_pq=&ZrShJyUcnlcXW=&75Elw7Wnomep_=&cruiyGZWqWsd_=&b_tpFjXnpkkhe=&gk3tCDYbmmjsr=&kTdUGGWWkoljV=&njHewKWlahm_U=&uazAoEXZkkdab=&f2RGpBVWd_rpg=&8vAg2MYVWWllV=&2YfEH2WXYmbli=&fmeVKEVbiXmlf=&eQa6RTXnofcdk=&_QTcAIVdls_Wp=&6cd5pCXkshmek=&7IPTvAYpegqor=&AMXTP7YlsVXoV=&4_TdwAYjgUYfk=&IlbghsVsYWdim=&OLzS7GZdocZae=&XRqbjQY_nppos=&OrQTawUaqskjc=&WoCht6Zfnldhg=&o7TsxdUeZphgr=&HxjU_yV_sfrsl=&nW7qhAVf__WhW=&iViKouZUdfmba=&Sd_kILZUnUapk=&3fBPomUXkVYjX=&uIYs8_UmiqWph=&FYj_N3XmcXfoZ=&hylnbfVp_Vhoi=&5j3R9JVhYjmod=&4UC3oHXbaoVhn=&2pFUTHZoccWVo=&_yYJsiZaZVVfn=&jqIvXUUol_qjq=&TDOaJHYiYhhrc=&c7gKBYUjqWmqh=&l2DcLUZmgeqqY=&qj59GTYhsoj_d=&x3upCbUWskZgV=&W3rA9IVbbaYip=&Yvg8wIWadiinn=&sUyzzzUrZrekX=&5RyxwJUnqam_d=&ri9bQBZbUmlrq=&SIDhDGViZaeZf=&IINamrVgWZrma=&TqMgzMZpgebnd=&SYZmasXXdiqUn=&t9X7RUVsqjdob=&SCc2rHYjsdUea=&kmZksGYqrYgkd=&kAmCVJZUrilaa=&jafoeSXiZjlmj=&f3_bhxWo_drhm=&Xzvg4dWnagUfk=&lDgvt7Uo_kljh=&IT_A_hXqjUVpn=&vNXZL3Xnjeoqn=&S7Fpm2YZWXbkX=&EpMQxkUsYXncn=&uFJgUfXoVUWme=&eWdnXeZXbbZcj=&tpECaEUminbYl=&rPHkDNVVneU_f=&h3SVoGYllUjm_=&vDexWeVZefnmm=&VFPHMTXalqYWU=&RxMx_UUZplhlf=&6kiLpSUpjXiZo=&7Vt85fYsonjqn=&PND5qHUpgpdee=&44SBkKUpYdkim=&NWcJ2rUkpmfri=&Np3bGWZofsidX=&xYCG4AUmYcfmU=&apg6gQZfpeaoq=&mWAVriUoqiZgo=&vOdKSVYVolfsd=&iwEugxVfWocUc=&QJFiIsVdUofUW=&rF8_ZTUcrlWWW=&CBQjvIZppVime=&7V4NPxVfXXdqX=&WxiiIZZb_mZgo=&2gyVM3WXoqbdW=&Lk3YuVWmbmg_Y=&gh9tj6Wrokfsf=&2XGj6gZ_qnoZa=&bb6RGkVrksdrl=&66SYDzXsp_rYg=&NKLuOHUdjorVq=&W6wIh4YijVXid=&2hHMsAXqWUman=&rSxmmhUUrpWoa=&iER_yeWhWeiZ_=&tUMBUnWof_sah=&h9beb_WjflVes=&tzD3QgZkflbga=&RDMVuMWiiclfs=&ktTbkxXWgVphd=&BQl4ooUmUchkZ=&8ibJusW_Vchlj=&6VbGKGYheljgn=&jblP6TXVkpbsh=&4m4OSKYmqsps_=&N2KyDcZU_jmim=&PU_ws7YsdVrbW=&kUwhWpVecjiql=&s6LSfUUeljYfn=&wkAxpZZY_pjYn=&4I2LyHVdbnpVX=&Bjd_PBVZdsfUq=&n_eGm3UqhgXnd=&WJsHg5XrharWh=&POC_GCYpkXrVY=&LaooXAVcfjXpa=&AZz6hGZX_sjVl=&a3gu8uW_Zjaq_=&lqYG9QWXanibl=&duP_6ZUqXjgkp=&XSZl4LUVXgljm=&tyQrEQVspVdep=&BpNLNkWcgmqbf=&szOhtfV_hZblq=&PQiTULWnqqXgc=&3thpEUYsgnsrs=&aBKqKKUnif_bZ=&98ZGfPWWUckcV=&DvFg5OUrbocgU=&ntwpElYogmhk_=&uFkoAwXYkVoeg=&LacR6yYcinofg=&QdrHKGZbWjUqV=&Khc4oTV_Y_hdX=&8IKHDMWeskrkp=&g4lcjGYVe_nnr=&XhhFwsYZnXpZY=&X7fpwDWaZlqVq=&DhEG23YVWsfrf=&cGmGnOWlUrqpj=&qh4xpDZrhZmY_=&ubsXHNX_Xbeec=&hA_MvuWZqsncZ=&yjs7rAUmV_VZc=&OB9LKlVgVVsqp=&MD8PcTXfUlqcq=&zSQhkWZYfskUl=&w9a6VqXZobadd=&e6ZmPWUhp_sXl=&5JZv4OZcXWdXb=&fa6e6_VaqeXma=&ryaeNCYWfVjlj=&xAhgZyUcZkdhd=&9FEEx4ZYmerks=&XMUs8NVaZoaWY=&oQ8SD8UfmqpYi=&gmja8qUeieiYl=&NroOKqWdfoWfi=&N625bnWbomcXo=&iq9CDbVpgioYp=&v8L_7kUcqaeie=&iid6p4VUaXnqi=&sXU8bAZWojpen=&drwCyRXi_XjkX=&5rWkfqVslWerk=&aanmDxWaXZ_jd=&VOxP2sWpZ_rZr=&Dt9h_MVjbnggg=&HjlnmPZodh_oj=&8IFfzlYgrlilh=&lNo4lwYZphmme=&WkQGTJUZhmpWk=&k8javeYekhaWl=&HL_uhbWnjiYoZ=&8KMvYTVrksqcg=&9gEVSaUXVfqpY=&vIBkupUWboloc=&RSo5BLXinpakh=&8ueWkPYifWdlW=&Le8n3IVdbqibU=&mq2ir4Wajjdb_=&g5p5_UZYoXZZk=&bMqkHuZrZaakU=&fEHmX5Vo_jbVs=&czC4fnXYUdsbi=&hh9q8hVUqqlZo=&K2j9ETVnsViWh=&VGvG99ZZXjbs_=&Y3achEV_kZZbs=&zodRODUbkarWZ=&bMkDBMXWp_qjp=&kJYueuWirrWii=&KgP587Yrapssb=&yuK4QkYsVabnj=&n2rPurUrdbmX_=&j99NUKZcpXjUp=&VUt9xDVVjlepW=&MDSh9rV_rbabY=&wBIKrTYYobpgs=&ArQUAmXkVYVXs=&t8O9vcZsjpbrd=&lFgdA_Wplnelq=&WN9AkBWdncWje=&2sjHKzWceVqXl=&6W6I69WZqjalX=&JBEdCdYlfaYsZ=&399Ku4UZgmeaX=&UF9KWUYhWXsaY=&Zux_jZUgbiX_l=&WGK5xJYe_sXcq=&Esd8TjYWobpqd=&bNHkULUkkpqgq=&IfBMkcXjkschY=&efXzfnVnUWkUi=&3BImjoWYsloqo=&ZTLZ68VpfXjms=&8lmSbIWZimeUr=&uveYgGZhYbgdc=&3dLSqrZpnobpX=&o7DpGmUUfdlhn=&ZVoD5NWspZhmo=&axP2SbXnjm_YU=&OGs2ucWnVaqrb=&rQj6qHVlYdlbs=&kaGDFaUlnYUaV=&kPfS_HYmjeorg=&ftOk7sXjZkWmY=&vGWRwOYgisVYY=&YG5OYvZghVWad=&4VGlpkUoqYXlr=&IlY9_RUjWlUmr=&_Po7wBUqf_Yke=&G7pjsYZUjdbZW=&AO5Jq5Wehiqnm=&BWD5kgYXsVWel=&lMineMUibiWXd=&AbQ4SZYradiWo=&PBItPKWUZZUlg=&IXwuRTXibbs_f=&rUFhFaVWrgaWf=&7PlihWXZdcWqZ=&7dmbPEVkib_bb=&8bCYdeYeWko_k=&dx_7MEXgeXUYd=&tYxvbZWVreXhW=&ze_BQUWckcoWX=&v99fgwXkhsWbc=&UlllUQWYXVenV=&cTqQyHXlecofc=&OGGCBrVrUaYVc=&Y5XkZqU_pfceb=&AeOHOsZkcZjrk=&dgVuRlWqiemgf=&jz6LXLX__gqWi=&f4JruuZlrmhVk=&Qy7VtNYYnfUdb=&PLtrguXYadgcb=&HFB7xdXceWVee=&3UgqL3VgmmqXe=&RL6nJwXYXdkd_=&w2UjMtVWcedZj=&lWwDXuZZbekls=&44gYWdZVUZfWk=&LhpU8KXojYbWi=&nk_9KhYZkjWVm=&j8qIIHWfgdjij=&UFkU2RYkgUWjh=&RAJjAlYVnfscY=&NL2DijUcrpUkm=&xoh84sYokdmVX=&MQmWdFYepglkl=&dYnHcqZcqbYaY=&KAvNwrXlmkecs=&EjT2rnZfaa_bh=&ItDDeHZnV_fed=&bnQQPgXanqrUl=&lbQzbEYneWneZ=&hgplEwVsbYrXa=&NVv28rWjoYcdV=&YW2eFgWdndfhq=&cNEWpGWYYmhWs=&FOci4cZmUgXkp=&lfByruXqhhXVe=&DX8e_BUcohUVf=&_zdEALZkgZb_b=&oULYvhUskdbbV=&XgNLMTZmbklmk=&lqFLYpWqbolja=&IB3NlCYradqYi=&KXHheJX_XqWZo=&MhUPItYYkfXjh=&HJTZqgWkoiglk=&i7Bp6lYp_bdXZ=&9_YO8HUbeleeZ=&SwT85YYWUpZqV=&cDgX6hZpV_piV=&2myxuKYa_sdfh=&4oaWy7ZsUYgdc=&ZaX_WxUms_bkV=&hBHfJfWdXWUin=&A9li5XZhblnWs=&aqd9xSVjVs_dp=&cW7gMCYepoqVd=&rAL_qLWhcdXUf=&oKhf6tYppbYoq=&iH7V9SUerarhg=&kRmcWQWlsfYbb=&ycdBPjXYrhgnZ=&pdv7iqXcasabU=&ISXaCrWg_c_Yj=&jHKX2aUWWWUop=&GjotZ8WUYWjgY=&KXoe8yYYkrXZg=&jktxNaVlceVnb=&nx7p2_Vorpdmj=&q7V7GVVqboocl=&wqS3qKXjdksZn=&p4RuB2UamcsXX=&VJ6I2UYliomrb=&magr5QUhU_qYZ=&4tIUuCVqhfhUZ=&hPPJ__YVfjkoa=&qdGhepUajilWo=&BIP8OMZmnffjV=&pBWskJZkVsVji=&QgTH3BVsYooh_=&y5iI7nVcfkhbY=&I4FnpQYYplUXm=&ljmUAfWbUX_sg=&RUHCMbXdiUgrp=&4etDyaWlibao_=&IjbLnfYspWkVi=&eKFnCoYjdlpeb=&Kzlla9UgnX_WU=&k8ftDyYkeaphp=&MRlsHoVjlYaWd=&gDpoPRZjUdknZ=&l2TdzbUXUkrnm=&G3QzyNYa_XdXY=&SD5X7NZiooboa=&ojkYCeVbmgdls=&zftUZrUldgmmY=&IgnkdbYkcfmql=&tl9Q6UVecds_e=&UN65KEY_Xffnh=&mXWCj8YoZnsVl=&CIxrIIXiYpcYX=&3FUwefVjokrXf=&2Lf6oGYscpXVa=&lFmrZzVeXYcrX=&tHiVDgVbg_bZZ=&8JKL6kWsZkh_f=&8D4zUeXifpmbl=&FqaSOOXpqpgah=&zopGlCVVmsYbl=&vqZi9ZWYZlsms=&I6rJ77Zbg_XnU=&bljEinVkcoqbV=&LXtudmZdcoWra=&p3NwTmUnWkdqY=&XinsUCWmVqYUk=&hUdfgXWhanpYa=&BzznKwZVbqmYi=&FbjgU_YjeVbda=&WIJ3HPXeihqaY=&X3Ayb5Xo_gkYm=&3TVrTlWfpWnUl=&AeuNykV_gWpfX=&JhmOkQUlpZXbk=&Q3ATwcXoanjj_=&Y_KRPbZ_plhfX=&H8JD8ZUsgfoma=&NhCAfSVcgfWaU=&ELUP_YVmXjeUo=&WcvkSqZgqUlfd=&Dhc8FaWZdXnUl=&WVSzn8Uajclps=&coJCU4YkUqblV=&DUrf3_VVfopko=&bEJeMuYlXobck=&gOhUxcVZYhfho=&7AdhnHVfrYm_k=&JYS2pwUbbjmZq=&jdnCxNYrbsdpU=&nrbi7FW_odrYX=&wVra7GYZijYbc=&5BZm4PWieVYkk=&XvQMVbUkqdqjb=&qtBzSsWhcqrsU=&XunS5KUZaiZsX=&I7KNjXYskdabm=&WI78QmYsfidln=&ZJ4dCCZaZcqmf=&759N55Zra_qm_=&YJBGxPWqnmUUa=&CpNMrgVqik__X=&kvCgshWiooUlg=&t88SD8VUlXWWX=&SmrTwOXpqWdmU=&R_PWijZqcWWVY=&Jqm_GbWlpneea=&fgSqRtZXdhkZl=&cMkoDGYgjlsjr=&Djoy3cWmfjqeh=&tjaK_WV_slido=&pjFP4XWXhlcnr=&lQtg2pXWUacUm=&kAFRaoYrhrcak=&oHTsUmVVaWZsY=&ptnAsFYoaVUmg=&BcRza3Vqolnkj=&GOO9XiVsr_mrl=&zxxCi6Ugknjd_=&oYlfUcZoahWeV=&7XkxdCUfcUa_h=&ofDK9UXgncpks=&dbgz8RXajoUmk=&x_EytCZrVUXUX=&QQ8xnfXkjjYjV=&tF3qp2YrbgYXi=&6I8K6hXeelmqj=&qiUUwDVjlhYWm=&5axUPBWgairmh=&akwVqmVdXsjnl=&T5QIUeYpmopVb=&gTGXdrYbjrcpd=&4NQzYaXUbpUfa=&2eMKqPYjackqc=&mXZXdqWkaorZZ=&9UKZIqWjWnbod=&8xT_XJWkpXjfo=&c2PQoLZhWrqfe=&q5FLOeUUbrWbU=&JcDWuGXnZhYWZ=&rTtDA5WqmYZgs=&qoZsTrVZYlVUe=&Q4WAYvXjrreWh=&3u7vdIX_afnge=&6W8migXespfas=&7NycpZYsg_Ynl=&pKDH8MVeUVldV=&Rw7iI_YZaXfaZ=&UBVjGZYZdiYid=&ireXobXsqosZi=&ikr5deYsZUiZf=&IqGVuJVahZpgZ=&xAPBWJZicXsng=&OMJNS4Vagfadj=&9vUs5wUZlsgqm=&i_saysYkckhlV=&KhcOcZUXlVUfX=&NTDuYIVacVUWa=&537vt8WYZXjgX=&7i2v6RZqZehio=&gV9kjAV_jhYpp=&vXiqTzVUmZkdo=&fnMZBkUs_dfj_=&xMt6VjYbaiidq=&hvPKydXZUme_b=&45fnL7ZkdnsYo=&axlcrbXoWbpak=&dwjo57WdoWoe_=&wocPabXllYprc=&bMhCRHZ_WgkUU=&lcxBk6Wp_kbdm=&MvDfdZVZgsjde=&b4grwMZbpYUoX=&jDCDVNXelYmke=&ka6jryWkamhad=&dd6SiSWmYUbn_=&_7y6UxYYrXqel=&XxhPEcVarYZ_W=&LfSaqaVhXXmUl=&NjLFS9Xnpqse_=&iu2MQZWdcXXeY=&ypzoiQZlifnYh=&wcmILYXrfgYbs=&m9vTWSXe_XX_m=&HDwU7nYanhoec=&dGp8LKWdnocfU=&8TtnDHUfgedon=&cJmzDAXrbeVfX=&7gpzX3VakcVjf=&cWUpxCYnlgdii=&D942vRZofqUWk=&__493bWhlVfps=&z3WREXZcmkmfa=&6iiBOuZ_daWsj=&tcWBEfYZsXXkn=&QrvRsNXsepfYk=&paqPT3Uooe_ic=&kwEBCKZsXbZbV=&ArmFYJUchcZrV=&Dprr4tYYYeXke=&j8J77kWrqfbXo=&_V6MAJUrhnrmo=&MtwK36VqWbcpk=&a5LIIWWXocfem=&A7Ass7UnnceXg=&NPYJEmZnggfsV=&s5FmIaXhZVpUl=&VyNk7sUcqe_Yr=&4sjWX_Xisldsf=&AGhplGWWqbpdh=&Ezzu23XXVpgca=&t4IFlcZsZZWjZ=&AhaS_TWXqgVpY=&hs7izYWhYqYpV=&zIEeWcYcWdVdZ=&QOPPXZXZVXkWj=&bShZN7ZlXsskk=&pWM5_pZXofYrh=&iJanYyXkeegsg=&qGc4bwZl_oofo=&r6LTeeZjaggWl=&GsAYraZbodkqp=&y8stNVXmbYdYc=&H3YMDdZUXjUZk=&lTU2OTXcY_Xjg=&ISaAOJZakaUZa=&eRvyWdVWnofWj=&uaOGGiWbXsbqU=&dYd2QoZjoWagY=&utXhHmUUbYhsp=&PCmkugVZdgrWi=&rxYvFaXjiejYU=&hLUtRlVWlUYnV=&TvytOXWckVnXa=&wKqhIgX_VZnqq=&Qqz5K4YbgqkqW=&Xq9UPXUmXXhdk=&JRbYBSWreVe_p=&woWlDHVokrbhq=&QMpYGBUclZVee=&qBpGC_ViWXshg=&XU2ltLUjllbmi=&8EagjAUhgXfUW=&T9nRyAUrZssao=&JamrX8ZasVqjY=&TKChiYZmimgpf=&2gBqEBVUdYbjW=&xGNOUDViVcgYk=&eypPKjZkacjcY=&HBWgFOVbokooU=&cusNdRWoa_dpW=&5L6yEHZdfrbWb=&CMBQ4gWeWlnje=&lidBONWeoYefm=&2dXKt9Ureomrp=&E_5MYRWnrcaWc=&LprnyZXpnUn_k=&JhAEqwVqkUbhm=&3JZZeUY__bjmm=&hzgfvwWUpZfbp=&n7gtseWekaokb=&WkA2flUmYpVa_=&2ONT3kVsroZqf=&aWNqQDZhXZXhf=&IQMARQVXoraYr=&SRVzVEXqlkVWe=&Y6CFTyXnokcao=&bVmsBIYkopmVW=&K3jMAfV_hZgki=&UsdugzVXrZchk=&cvr75wVb_eWWf=&UMxSx9XcelZhn=&H4kIdbXVdoggk=&azfi6cYW_qUpn=&QaV_cLWspgrgd=&yYd8mwWVlWloe=&yrmR2uWrj_chp=&HpnfKMVsamdrs=&eJ6TBDZegoWni=&ugkmfXXcjnYdZ=&c_ZYQXYZfcfdX=&Qnj924Yk_nUWk=&9KSxwrWesnmdl=&H7vfdLVqbWphi=&MBSi4jWfYenpX=&o3Pyr6YjeXqjh=&JcLFjIYbcdjmY=&_fmqbNXWqaVU_=&H77ptEZZaVllh=&K7eA84UWibqpX=&2PR6aMVV_ZXYd=&RdWIf8VpWmWcl=&BZUPaUZnsrcgX=&3Gp7exVosVUWf=&K_9_DVYsqimWb=&hHyxIIYolXqis=&sAm_EiUiWlXjY=&c2JRKNXfZipWX=&NIvtijYVcbYri=&TDXmVvXZrVfXW=&t6OrT_ZqYkhVa=&RV7jwXUcnVrnd=&ibyt3aUelgg__=&yM5cB9UkkfpXl=&jCGkbhXcqUghm=&8rKKdaXmaasXk=&fN34jFVqZVifs=&gMFzH9WrmUnlf=&Q4aowkUjdoarp=&YDsHzsYjmcjeU=&_lGNnWVkergdV=&KlIWjNVUZrlbZ=&x6MPIRXhZZmgn=&u5hyLTZmbbpVl=&_zsGhEXpghVdm=&qhL_LrVdoXdgd=&3QVKY9XWfndqa=&wYolD4Znc_skq=&tQf9_vXdWfZjl=&aYReINXpWhpnq=&QVNpXzUanknqo=&cYPszuWgbfdlj=&L6gMj7Vfqii_U=&ERpEwoZfsWfjh=&RbIKhjZsYaoss=&BKfKuKUW_WXff=&joT_qwWcposbj=&NiK7vHVlVheqg=&AaAPfLVebnUod=&Nen_VGY_Ullko=&6kcRCxYniUZjd=&j_RdGcXsrZgsl=&gCBjreVgXUeic=&PIo6TnXhVhaWl=&pipjI3UaXYnrh=&UpWARjUlscef_=&B8TdzdZgphj_d=&w8_Nj8Wacblnc=&rHqHDnUYUVcZm=&fyCysJUfhqe_n=&ThSqjhXjrXXgq=&E7rrjmZnZVobr=&azrB_zYnrgpWo=&inwSWkWadY_bq=&eYUgLVWXdgrUq=&tBP5UGXYWc_Xe=&UHXTHbX_ZZqf_=&MpjsKfWfZYgpX=&dtaHfGZlYWlnd=&7ngS9gVoksdfn=&5BlcYcW_ifnVU=&WXj9kXWVphrgc=&lyMobfXfjaoWZ=&pF3x_TZappffq=&ELc4zhZprWhYl=&yedwNoUkWojdb=&grUNidUsZmXcU=&SIVLMHYjq_dUq=&S6TwLTVohdeYq=&sc3XPsUceUpll=&LJrO2eZkscqia=&72tDm_ZZfeYVs=&7nkWfBZlqklXq=&wnqOCIUiqhYgn=&eveIZ8YglgZVr=&a8ns9QUrfVcXp=&wQXdUVXqnifYh=&ljF3puVercrph=&9qU2RAVghsfbV=&zmOvCfZhrbo_e=&DG39moZdcsXoV=&SvwgXpZYVjWUV=&AcFOHdYenddZY=&DllvUwVegXogf=&KWcCMoVUWdVdb=&TnzTosZpdljhn=&5KaA2XUeW_jhl=&FzUB_WVWhlg_p=&DyZrcAUWbgsWp=&kcLS3RYjZjksa=&3624n2UVnosfX=&KUyXX_WjYbrcW=&BWccKVVkqWgYg=&LjeBtfWjsnjhs=&tlYAK2Ypp_goo=&mhmLWQYncYaph=&xZDez_VUUYWiW=&n_jUIQWqUgUmb=&Doe9IbYkniWdl=&2uSsDsX_aUqbX=&rCyKVnZsc_alU=&kDSAvfUajgirc=&FpbiDWVopVZjm=&_cuDbQXpVrjsY=&iiw_fVYscioVY=&yaDw_6UmakYnc=&MptSpcZU_jqim=&aUKbHLVZncdig=&pu9wfWY_rrqfi=&xfv65mY_djlhh=&maPNsbZWdsgmm=&VQyrJXWkibdin=&LO3cYiVo_ebga=&RGs4fZVVbgfdg=&BeRNWFVsYid_p=&nr56NwZbYXYbX=&9EkCURYnsrlsV=&rYdQviWjofUsi=&lcjoDtVWrljmd=&jO7866Z_edgpm=&kEnBv5V_sqWsj=&5P7TrIV_Wmnmg=&_SB8qcVrbljVh=&JtTvqjWbfqUUU=&4oRpXwVZgfis_=&W4wn2xVqrWdfV=&fBsj_IZgaogoZ=&9zRyN3ZWkmqaV=&HfJzDyXjcbhdj=&3uqtmhZZpcaZf=&BeRzLUXalfjZa=&7mxaECXsqolcg=&kyMhpkZoncbfl=&WcMKivXkgsXqi=&FL47JIUjUqYrl=&pvrxyjZWaoqqb=&LuIL5IZrXmcgk=&eVMHR7YZoVWpl=&Di7UfkXgslief=&6YQpSnUnjcjVU=&HweIzXWV_VsjX=&jxVk43WifWXho=&Nda2XpXVejaql=&W3jsJmXmbnbfg=&xRF9D6Zkbjoil=&HiZ3dJXZdrZo_=&92XzZkUcicUha=&bqSnj2ZrVnUnU=&B8xzoqVfdggii=&5QoJReVpXrgZk=&q38OuoV_eViqo=&DZ22LiVnXYdeg=&a2jKe9Zc_pWgj=&NzrtYgUoXrafo=&h3OQePZq_qZjk=&2wFvyEVbgZYUV=&EKlBSxXhgpsVW=&j5mWO_XlshUVi=&dMi_fnYeVeVgm=&n7SUW5WWqpZqY=&iHx6cIWmdbk_e=&msDbFvVjfpd_g=&KmElF9YVdoplZ=&GJGVTPYohsUVj=&kZRrZuVnffeh_=&ftIIRfVgqafmd=&CpFAazXWielgq=&98GBXWWddZmlU=&jIQkQdUqlqYdr=&Qh4s5hVnnadcm=&Fqk_YtXfVXUra=&mz8JbSUVVXchr=&AqxXCUYUlXfrp=&LVe8kxWrmnagf=&9JA4O2ZWjVYqb=&36FSexWqreheg=&7LCAdXXafjbjV=&kgNpIjWfh_mcU=&iKVfWdWZklhWl=&5Tg5ykYjWhfZo=&TDM9AgYdXalVZ=&ASmEbzVbUqdqq=&afVEW4ZYZgVef=&pP4yicVriiXro=&KexzpZVhqhdqV=&XDWiZSZpfgjZX=&n5AFG3VkXVhda=&g_DYbdZpgingZ=&dUcdpmYropnod=&IAVUzJU_YXqle=&Qfns9DYndmmo_=&qzVBmnZdoUfqk=&k6ESYQXn_jnpn=&nwDjhGZVjecWs=&cGV4UHVqYjcld=&ZQkUuzYgpmolh=&WiIt5vYablgor=&zIlnLjUoraUnk=&3HIZt7Vg_b_sk=&FclQaNXcljZUm=&NNyx9jYcimeeX=&X_cofmUsVifdc=&uoiinYWUmgpbi=&6rZktPYqhfodn=&ZM76szZXeWkUm=&9vXlTpYYrflZi=&9__KkTUVgYc_d=&NR_wHSWepVmqY=&PbUCRCVepdgkr=&oxLiZuYUUXjaq=&o5h4TtUVh_onc=&G_2xfOUgdbeVb=&_fG8TRWsjqUpn=&ckYFn4UYXfVpa=&mWkaWqXXrhked=&4PmggNYpcjnls=&fRFKtTXpdcXhr=&cu2hFmUUbZXcl=&eTDlSMVcYhlUp=&ZbvkFbUVdqapp=&J7xMvjXVWorUi=&CCErrbXasmhXj=&qDYmkdUsWZYce=&kpXpFOZdiqjmU=&ryGycgUedfc_e=&XYZp3tVkkcbgd=&iGDpVIZUViUfV=&2BaFsmZsYaWcV=&AKroCJYkpqqcm=&xTsmObZ_higmo=&jhOpSMYUUhmj_=&mUaEpXYaUhknl=&h69puuZYnhpoW=&9NO2UfUgZcXsY=&3JfCRYVZkgbWj=&vmxlQaWccbo_p=&XOMP3eYW_mhoY=&YXPsDFVXdWlah=&32QFOGVknobWq=&atpZnMYqWjVjU=&5Fvht4VUhemiU=&lTPfcAUhZmdqi=&yvz8PlUWgahgl=&RglP3TWmplUsd=&CifNzoXr_kcaa=&2ElX_KYgcdbfX=&UvXFkjZfYbnra=&8BBVwHZ_drpUa=&bAEOlaZhgXhkZ=&7WbPMOUU_gdao=&cVB_daXbjampk=&R9ZJz7XpbmirZ=&UnyXb8WdrrWdb=&K7kJCxYkamsqV=&KUunsPVhcbraZ=&9bnIguUYgbUZp=&BQecwrWfjZWeo=&drIEFaZWoVepn=&m76fhrVshXYYk=&tCUpLwUjelmjh=&bwrlU7ZXnajXj=&yFi8AaWamZijn=&tfla_DXcnlqqo=&Ud2yezZ_plYkX=&6B3CPvXgdkWkf=&rtP_hDZeaimr_=&fkzr5oZbgreWV=&YOY2ZpWcXbfbq=&RMAREzWseseYY=&cwN88XUbialdU=&DPlfYwUedadgn=&zllkTeVoqZaZW=&2DFOGmXkrYggU=&NkaPyaXjsofUk=&KVldXEZkjfbeZ=&6LcBiMXWgbcWa=&iQU3PKXckXibl=&mPL4WwVpsYcdf=&l2qYusXYYpXoU=&3ruqwOZWlqeYc=&kf_AVqUksjfle=&W6J8gRXjllmmd=&k5dkRAWXVhbbm=&Eg3e9rUl_kked=&orC7EZZZosh_a=&PnNUhiX_nheYU=&tSDk66WXnilcs=&PetiNGXVjefiY=&DMsNEvYrUXgim=&cAzzBxVlqe_Yr=&h_GTYIW_WahaY=&tHjLXiYZdXqpU=&EYottwUmpjrqg=&kZm7UgWihZmZV=&ILMAi9XpWrZVp=&X8EAwZWnUrsmg=&L6jMuvXXrjdfb=&v2VAz4Wqjajeg=&aoVPNLXkZZahZ=&Ptziw_ZnqrYpa=&pWjIomZXjaioY=&tT776AZcVqoga=&3ShIRJZipW_fp=&BzezajVhpgpqZ=&zhJtnkZmssqgX=&ttxzZQUacsXsj=&2G6FxkUV_l_no=&cRH9SPVjWfYfg=&mkxKDHZaoWpgU=&b5g4fmZasjnXi=&DtLEG3UkZfbWf=&4Lmp9eYXggbqo=&3EH8uEZklg_jc=&dDV4lQWmsjldb=&gC83O7WkfhdlW=&fLsJmsVZUnUch=&5UnxLiXpnpoUa=&Uk4QSMWoWikjp=&qh28CiWdZU_jp=&cucKoKVXXgYoW=&YJ6VAhVpUhWhp=&FuBfIOZYWUbcq=&sA4cZtYWbjfgX=&r8DPiyZgVVmlh=&5JqfK4XYsbrmX=&8YEu8dZokmenW=&QSEXFDXYacoXY=&dALzHGWpemZal=&xrGlimVWoqgmf=&gNH7kTZbqaXkd=&J7zbVaWrfUacf=&NS7SJPUnnclUX=&Ug3T4IYofcjnY=&rLnEZjVq_UboY=&GKHS7VWscppjk=&w93yPWWbhVq_p=&rk9kG6Uhq_osY=&qH5R3gYnpejdf=&x4wf6xYjjdeiV=&C8JUEgYVabZXX=&CM_x_XXUWpnUs=&HhV3EeUVjqcmi=&uuVDuaVb_ij__=&HX99tCZoa_rYs=&4jRd6NUoWkrXn=&NxJ3D2UrVmsZV=&pNxQUSZhWeVod=&fZEBJ6Zrjadqs=&MKVeFiVddcrbg=&k9kR2DWUYobob=&GVQgBEWaWdaUm=&Ne8eCHZjVibei=&vOdoB3WgYnXc_=&HXO5seYqUaWjY=&lewybiUkjjpce=&84IxFrVilZXga=&6mkFksWphsgWh=&rYF_SdYgZnb_j=&_hMHD7UXbqaUW=&dx6bPIZmcpmio=&vQTBMSVlmjqgr=&EZFyTnVqbsefi=&fnxPVOWdWVcmi=&RQZbybVdfWlfc=&AInm3mVhnWqsX=&lGBL8gYhcYcsc=&e7Bfd4Vksekrn=&S7XqGsU_cdqZW=&Sjy3EmUcsprco=&La4GghV_aY_sX=&FYdmTyZUVnrc_=&RisVNcYnkimgV=&F88VdMZfmUgrr=&qTkMcrXfnqXls=&8NnL7UW_osWop=&4qQLU_WpZrVaX=&HuERoiYklhhnb=&sO4ZajUWWgcZn=&9awqWQWfirVYq=&uuS3lGYrnlphd=&UMaSzzWkUYsjs=&KaqpLKYpfXabX=&zaPqN9WqokWVb=&VyaxXUXaiogib=&9i7KWSYigZYmq=&o3RPUgYWfVVdj=&yoNq8aXnfhrfh=&cH3dzxUVelprX=&E3UEyzUmrgori=&XfrDdXYkk_gcp=&PkGc5dZYXiXXp=&9zWwXhXiWmfXd=&rToW2UUalmZXr=&Ont_jFYrgnadc=&3wfkeMWoZYeXU=&GvR8EmYUkWVpY=&RWnT4fUrdiiXh=&5amnsJWkWbcYs=&jcq8x2Umsnqka=&bXqqZXWdYXrai=&zdDC6NXk_jhrc=&pdtdyJWaeqXr_=&CCYgECZoqqaXr=&LqUhdHYVYXdVd=&SkdrSOZrkhjoV=&Echj7OZUsWfjU=&FDZQpnWYsqqok=&bYZLQ8VlpZ_Va=&wAFuNwZneVrgV=&rN3msvZco_oro=&k4_PNEYUdlgbj=&zgl827WkW_VZX=&hXL4BxWlZrak_=&O2zCfqYcjfnir=&MXrRwBVUhbeos=&aGxlnnZer_cfo=&YXFg2fYefscos=&suoNLGVmoiXZi=&8TOUExWXdbhoU=&mmzg5jU_Yacbm=&pEhMIcYpjqsYr=&AKWIEVYbdVZgo=&ac5ySzXWaUaha=&qCev_GVoWm_mb=&c7RNDLWsXbkfs=&zYJFeCYmceqZr=&Gj9gPNUbifqln=&HSOsI8WnoUWmk=&bHzT2GWamsXah=&Zl4UeUVsfiXkp=&DhDfX4WUrhsXU=&j8io5UZrgZbof=&jYVWA3ZUimdof=&KJYKNmYppfWhh=&5EPEk_Wbkojme=&H6q55BVmibYjZ=&hwa4h5WqZafmq=&a9Yoc7WVcWodd=&i5zNFCVdrsYWd=&wYGy5JXsbWekY=&wzmPTyYUZcgVY=&2V6atlXajVZok=&djUK5GYlgfeYn=&9ydstcYXneUVo=&a9SttpZhrZlZs=&ptpSOgUg_YUYi=&j5mLHTXoYpWdk=&MSMbxTXecfhsl=&dQKeyuX_lanlW=&QlwHRTXXacdgm=&Sq7slhXXpVodk=&8q4N5XZnUkVlp=&XEAUPXYUehWhs=&UhumUCZWrploq=&8wcLvHWXnapUm=&g6pN5mXjooUkg=&RXfnTdVaXXbqr=&AxBanWXdiabd_=&uf5hSEXXWa_lg=&qhVl8AWjhinYo=&z_6mLQYriqqfq=&QkmKp_XnXqsYV=&8W2D7KXpgfrrV=&g6XdArXhnjVjf=&cgnzgRUrWXX_Z=&AEl4eYUnjdWUk=&KNAY8KUYcdVWn=&nNksa7WioViai=&OZl7X3WnabmVl=&JdBBFeUVYhinh=&Jis7seXnosajr=&RNWxG5Vmfn_di=&qktfJFVafgoml=&fCKHrHVYc_oXr=&edoypIVXqWbVX=&vUwW7rYpnXdsd=&JYB4ThVmnUVXo=&erAgkXWimUqhk=&db_TIPWnjcXkW=&WzHvJEXnoqm_p=&3c6TCKWjgfXoY=&CLpFCqWiZUifq=&Wr6ogmUlZaapa=&xMdtSeXsldmlc=&unyYNiWZldedh=&AazSutVobWmob=&v57TsAUqqhVfg=&nzY_EYZnhaa_k=&bbIgs6Vhjfmie=&8Mj2gfYhYqVpW=&2cYCNTVgljicd=&oTkimDXihkbhn=&K7XHFUVqsmpbl=&zXMMzYWbnhiqd=&349ZZFZoYhVlb=&WkjDTnXhmlqVV=&ewCz6gXcepXoa=&mJf2rRXfbo_ed=&KERzNMVmbWklh=&FEXynFXorUlnn=&9y5wT_WfYXZgb=&oAQ_kJXcdickq=&kDUWYTUYZr_kX=&DRiB4jYXnVqdq=&qkWxTIYjmb_Uf=&G_ETVJXdZbsoe=&_iDSMPVnWZhfo=&JWC6ndWcUepjf=&9tHsdKVar_mqc=&VI88nOXijhVel=&D6tAmhZW_pZW_=&H7pVPnYfX_gga=&yz54OvVmVVXXX=&Y3pX6pWkWg__Z=&AmKddhYXirejp=&BbUDUzVjseheq=&mNdE7gVbkidYk=&ypYeX5ZdZffbl=&wz9djzYVqZ_fe=&DwQmO8VehkWUb=&Aze53BYmVaYnf=&KfXIuzXolgkm_=&NN8yGpVXmrrXq=&dz7Ec4Xgla_rf=&DnmUJ8UdWhYgh=&tleOX4Vgqpcgl=&beTpLEXjbUmZd=&Mfhxg_YWgsdcd=&oD83IXZhjbpds=&sywcHeXadsdgd=&lEj4YWUZVVUmX=&2bThiUYbqoUie=&e9DLrwXYjrUfU=&3SR5CkVjbklka=&PdUNZeVgpdUXZ=&kEqpbkVdikeip=&WJqZcNYkcoUfp=&oByC4kWqiqmsV=&EqFFN7Zhjcojq=&dVftdPXaWfdUo=&WkKzlXV_sXgUe=&XeBygWUWndaqV=&PA7fAoVjordje=&lLGsVuXUrnaol=&aC2UDVYmiYghV=&OvfXIyYrfclhU=&pbixOlVqmWdYr=&32BIsKXhWfisa=&EeF9nOXZkrbrg=&9wp3KVUXnpaU_=&nD6SopYkckelo=&oPFa9pVbWmVpi=&ph8I5rZlgid_o=&INAHRWZlYsYec=&8VXuAfVXUmYql=&XGkHE5VfWkibs=&Y3z_yQYVqrnjk=&6GyYJtZispmaU=&m3BT6qUbnpdld=&3_i_ToZYjcgYa=&oGM7dAXfnkXmY=&ep5gHiYignUlf=&XpBh7jYoXppqZ=&oS8vZuUmofihe=&ib5kc3Uf_VXen=&B3YbuCWpcfYjo=&tMjoczZVmhWZi=&SjQLWvWWkVaXm=&a3pEN_ZsacmXX=&ZGwbNhXjVVkdW=&JeqsmnXXh_Vqj=&mkGWAYYoreoXr=&W_BrE4Xajma_k=&at8AVdYpY_cca=&b65IYOYVXXsmo=&sGB3maYsaoW_c=&qnCrpBYZdUair=&HGRKXHUqipgZX=&6uwUPlWh_UffZ=&uNE2CLUVkW_lc=&K7KxTbXlVkfko=&tsyTHwXomWcab=&LiBeEsWaVppkg=&2_ibfDZgf_Wdq=&AsWdknZna_rYU=&noyhmOVWopidi=&ussPAtWYlXaod=&l4Fe6TZorbdee=&qBoOgJYhqfZkc=&MFlXsBYUqefrj=&YzNoqPU_ZcXbX=&hAEI8sUemZqa_=&VjW4VsYWlnUna=&w4sVOQYWeaVqq=&hopnURUVYg_gs=&nfNQMTYhjfddg=&BIy3OhUnYhroY=&BaFN9PXsjaXoa=&ER8KhaVlrpejl=&SQkQzXUqmlkVb=&jmk_GpVlZccYo=&OmZPatUZblXjb=&lsVdGeZqfqWld=&uI_jSsWcdVllW=&zbSy5PVichWUY=&lPxCaqZYcnYZd=&nfbIwhWdnmnnV=&kHSIOgWcoaWdp=&i_8X6WZVqhWkX=&nQIwjdYgXklYs=&mAK5UFWcqrbnb=&uMolTeV_fa_sX=&c_suDXZdVrVc_=&5l3OdPXokWibU=&6qJMgbZnporWk=&KUkjY8XkU_jWl=&gy5esuYilbgqn=&jNHeoMYhqjcZX=&bE2N2TYb_Yr_k=&SEM5CHZZUqh_l=&c2hwhNUpcYbr_=&639XIgXprUVjc=&b3hp6hZiqYhYm=&Ltuq97Visomhf=&ua8AmeZpkpcnm=&LIoBDFWeXYkeU=&jVa3yVWZWdamq=&fx3AqRXpeWcWY=&RoqU_9ZcnrVfr=&QgjmWnWqXagio=&rOX2fqWYYmjYa=&lBKIoPZpUnqXe=&TL6HfUXUlrYsp=&U5ldToUiUWdkj=&A79OeBXsarjsX=&OuNCFNZsijkjV=&Fu39JUXblqfor=&h2fbtWZblhVYj=&ZMDeL_ZldYnpj=&KPmUSQUgdjlar=&ni_lxPYeZkhUd=&9vlClTXqsehUn=&kKW8LLUVjrXXd=&xbNqfgZUcaUeq=&pkiRgcUjZqsl_=&rihFYDZXknZVW=&Q64AppUocrigs=&T7Yy6QWklYWoq=&MGLJ_YYriYrrU=&jUwjPOXmjjomj=&BwxXuPXndlgrs=&JXs2BzYdpagUi=&fHFGaMXjniaXm=&hKkfkzXZnfkmc=&Nhxq4yZpVYnsp=&dDoUZLUUdcjip=&H4ZChZZiplaep=&KhgISyUekfapY=&GnwYGlVdafalf=&Ev8RfYUVaYVsn=&jFsfFOZighZoW=&6aEAv_Wm_ed_a=&cARmm2WgbdhVX=&czQIaGUpqoXo_=&vNXJlHYoimheW=&4bfPgZWsleYjk=&EAOoPRZdYZrhY=&r4AEjQUnWdfgn=&q2C8NuYpc_irs=&__EYn8YnUhqiX=&cGlFYHUdobVUh=&Eyxm7VVmbXXZq=&wiNTIFWshWZdd=&z7UHRsZrnnZV_=&trIqYAUiok_Yr=&RIk5ruYg_Xamq=&Hlly4wYWVpZXd=&J7IkgGVWnqdYb=&muP4w5ZnbZZka=&wuEjBPWaYaeYq=&M9ERRxYUooVml=&t3VNdNZqhoZji=&Rwg3NuXYjkasf=&r5RXesVVlc_mV=&N5V4qnYZiikcU=&jVo7hTZelrYqc=&beuTfOZinsihX=&oOHQ3KYbhssmi=&qHSPCeYoh_hWl=&tD6lsKZrXhVXb=&UFtQIxXropaqb=&34INRaYsdkmrU=&738eGaXXgbhYi=&mWTxVxXrZpUUZ=&jdERneUWXlpsq=&_eo6vnVYlah_n=&8Alol7ZamkZea=&rG4jGeYonidbr=&AoSHoAVdkbrjl=&yVX2wVXroioZo=&KrdjTtWd_VsZr=&cWSlkUUsfWoqb=&TifOYMYdlsoiX=&caFilxWhn_egk=&oJEgT9UVghYsX=&YRqgjxVmfonfo=&n8MMk9Vesmm_m=&MdxiRWVfXedaa=&Wk5gkAUfkVrpp=&fW_6N2YheYZXg=&O8weWEWnsji_c=&YGrYAyXrpVkWs=&u7v6eGXdfjsfa=&l6EpMhXpZocUi=&aaFvGEZcYrmfc=&D7w6fLUqUZceU=&JvZ4J_Ylngpn_=&NOJiZWUjZZZdV=&U5mR_4VblZgjq=&YYBVR7YnXZgil=&ejd6wbZkqYggU=&BlHWCvWfjWmbW=&oKFMJyUYjU_nj=&kMtiOOVmlUkfl=&o2fAsUW_gisZk=&PvoC94Zh__Wio=&TW5r63VqZZcbq=&tB9nbIVakgYrd=&tbo4DoZqieice=&hhYOcHUgqsZWf=&ndj8eGYigsplX=&IdAsqyXgcjjmh=&mZXfvxZVYjpVj=&xfNoe3WbiZa_q=&a3xtdDYgZcdUp=&Y85StzWfflgfq=&OvDg2gUecbefi=&tSpjVHYijland=&5Q_ec9YegWmcd=&kntVANYrjsgoV=&KAcMuJZisZZep=&yIyj7fZfsWscj=&xDHQRhZeZjpsc=&HacHGVWidjkrf=&rbHb_4UonZhZq=&fEOqGxZfq_bko=&azCBU9Wbbbijb=&n5_PMUUbkhgsp=&mXr46MUsssXmq=&sBV9GjUoklijk=&5mCBcvUYUkeZs=&H8FewHYYeZ_fV=&3x96xPUafeqhV=&2pWxeYUoqcci_=&qL46L3XpXmabl=&jex3ddZ_YfYqZ=&PWHby5XdaVrY_=&agpmIBUnUUbXe=&p2FPeaUbaXijg=&iBh3aAVgdrUai=&tcmLbOZYnmfiV=&vQUx_eWenUXXs=&vIebmwZVYpasY=&NPtrevZelplkY=&RHtsHTVbedYiV=&ZYq6avYpgdpof=&JAA5thZlXdVef=&UTKxgYZrsUpqs=&cCT5s_Yq_hnoi=&lMQHlHVgig_ZX=&_SnI7KYcVffeV=&AePlkiUbbZbXs=&BUgCXCXqbbrje=&T8pGtsZhlrYfU=&zYNHiFZqYUXdo=&kcwuPSVdo_oVX=&xUPQWOZqqWrZU=&gl_GirWkhpeah=&yc6hEDYeclcZa=&25YhlYUUcjYls=&OIIbH4V_lkmbV=&PRPOu_XUjWfYb=&t88WveZjbeUeo=&f7R4l2UVqgohc=&_DfcUbWboXoVd=&7Ze5glUdpckhq=&R5sjWkYqglgjh=&xoSuuOYjmUXgU=&vCiJd9UnYXpkp=&j8QgJjUip_oYk=&RMEndiWd_lW_e=&hpF6p2Zlgneem=&dFhSrAW_sihlX=&gfwgWiVgViXdk=&P5ACGrWqdXUmr=&4AQN66XcsnY_p=&2HTnbUUYb_nsc=&nbq2UbYm_sVZh=&HonifRYafWX_h=&5OnGcNVnodalp=&feCcNBVpYfUkj=&56q8geZWcZhiU=&ylwDtRVdmfran=&5QRFVBYhfXhra=&frh5C3YUeUhZa=&DJH64qY_biel_=&vAyZ6rZhrijUr=&4dKFHkYZVipeq=&s3flRDXaniqaf=&DlczeXZWXYelq=&WDzuduXhrneoi=&MfxdgPXbcksgn=&fG7utLYrq_aWn=&tshHzCV_nrsso=&zVNkKZUnljrbi=&iPANb3YdbZdXV=&BZ8leyWWc_jVb=&9TEcwaVhbUbee=&GyHMJYXfjffVZ=&d7gP2xUhgfrWs=&QKhsAyZgkmhdb=&mNnAidWjjdcl_=&5yOxzXUVdhXm_=&PcRADsWmUnbbZ=&3MXIuAUZrWgcW=&xxJZOxU_mWYkY=&wTZEHIYfkY_hg=&SFXXH_UVkgmeY=&f8Tz98Zbn_Zaq=&pvVLnXYnbsblp=&3Ak_gnUsillaY=&gmJhcaXVjf_lc=&_weRwNZnWiWej=&LZcAsSWZWnmpc=&imVeyuXoXWkZn=&mp7oABWoqrpWV=&Yk4icGZbspiUV=&eJRNFpVssecpa=&gXnF9OVqiijpZ=&dgpivoYZpoadr=&YcCUuVZpaghhs=&T9hw9GUVacjVk=&X9DOLjUpgrgnq=&lqg8YIVesplll=&meEcDMUYghlas=&Sm5SGtYrlhpbf=&hLWwYOYapYXkX=&E8E8f9UeVgXie=&EE4LloZcmYpqk=&58hAlUVXoon_r=&FfStCGYloVkes=&F8SRbNUWhrUlZ=&MWxuF2ZqjUpVU=&HXBcfoUkf_VlY=&qJgZhdXgopmsX=&CSTMxvVVjbjZi=&peRxqRWhgkUYo=&ylCeg_Vesaomb=&iCOAApYfbXqls=&Rg5qr9WhrjcZr=&bc5OeTXlfkleV=&RATG2bUms_nce=&aGS8IcUoqmqlp=&CXVlukWegaVan=&hhoIaiXsgWejl=&NO6Ov5Umeflnn=&EkaDb6VmnaWgq=&Qhjv9bZrVdWod=&Lo6eQxVeW_j__=&jbP8wSWmlpWUn=&9YxhuYZgeqkmi=&yFDNIIUhe__ji=&Ndp2ZNWhhdflY=&_3HoeCVfsWrqf=&o6lfwPV_p_qXs=&AZ5fcKXZa_qpk=&AiiSVeU_gpZma=&rcuwtnZspdoin=&_tYpkyZehjmoc=&MZWUAIWVr_Whj=&fWIXYQVkjVgam=&ZSeQDQZp_Wbsk=&mUODbiWhUnerU=&YUu3V5VimekZm=&5oj3MsWjdUabh=&2mOTnkXinplUs=&vZkyMwXUqfoWp=&mZlB4vXokpeXn=&lTu5ZGZehdZso=&PgcAAEYjaXZde=&O7kUc3Zpjr_Wr=&SDeOudUVXYgcb=&aZ2q2VUUopZZW=&fqvE3MUmpm_qU=&eKJJYeVdomWhi=&BTemSXVboUgrV=&C8dazKYd_h_dV=&IphGumVYoYZhs=&NqNlBNW__ZnYU=&hkAUYxWnfXY__=&NYKnReWYUrbg_=&TDm9fTWpbdirh=&sgl2uYVUVUjnZ=&JeQBkOXhjqqjZ=&rFP9jiWsYdngV=&Jm95Y6WYiadmY=&yqnkmUUWhWgde=&tOYJy9XrVbqni=&ivJjrPXoreskg=&H7B6F6XgqkjmY=&QcnZROYoVWVbX=&mJejCIXhsXgZj=&9IRlpXZqfqdak=&DDHF2SZeVsqrb=&qefGstXmdZnmZ=&B4UcHoZfVgZdh=&Lo9__JYXmsXni=&FDaBihUojVbc_=&GlEpSFYjnrgYd=&PqUqoTV_oZqfe=&6ijuYIYbif_Ud=&2msqxlYgecYoi=&L7HxrCXnhrdeg=&Z43IEiWhgZpeg=&oZXoCoXloe_re=&RtcyxoVoVaYUi=&iYIjqCUeVrqWo=&hnPIO_ZgclZmr=&kQPjtnZrVancl=&sFhndmUUXVnjV=&7ECknmWeaqgbh=&ny2PiYVoXYfqX=&zp9bZBVZesdZi=&e6msCgVpsZmV_=&Ls6vBqWaqdsWq=&thoivFZfYZhhe=&JejfKAU_ojqfa=&gxIgQ2Vgsbimn=&VGq9tqWYVXohm=&FmdnR_UqVUkW_=&SGFUijXfgVdof=&nDdUi8Wcoakps=&rq3BdzZjgsjXh=&yS_K2OXmkopek=&CPz2btWejpeoo=&bSnvpeXUZpanh=&MmFOibUlefqfi=&rY45f3VnYVsar=&6nkAtDUrjXVjW=&APXWhFZWUiqY_=&8kMB6BXWoZrkq=&lAPXz8VpbaVZr=&ATpNQMZUcibio=&7kn8bJZleeWoj=&ydzr9fYjYqjnW=&sLN4vvVUkgbeW=&uXzRRuYrlfkee=&fz82ldXgXfXkp=&GG25xdYUq_knV=&uA5bLiYch_ejV=&DXNXbxZXpeWlV=&nAA5bTUqWblgU=&PsQeDVUb_hjcr=&QeqBVDVZgbkpq=&Ztmw4kUXoh_pb=&6twhKpXcYc_sW=&P8JZGfZnVgWlk=&xafp4yXccWVkf=&WtwFyuXg_jpkW=&5vt4qTVckccZZ=&vfCiWAYblnlqj=&833RieWXarcZY=&hirKT_XeXmdpm=&XmWtTzUiiVfr_=&kzgCj2YjlUlpk=&qewqhlWXZidWo=&lwOysBYYZlWaZ=&37jcU9ZnZ_aob=&hQTk9hVjUqmmY=&QCW45rUrWonZg=&XaVqO3XY_dXaq=&UwGcGoZfrojlk=&w5F3iJZiUldgo=&8LxB8NWgUnssW=&kKpycyYZhdehY=&EAE34dZaiorra=&QET3jWUbrbknZ=&ueWWaIVorakZi=&U2BYY9Zhigdoe=&jK6thQXWakXdW=&CIQwqtZWhfhc_=&KrrIuDZrZpsoq=&QoFYj4YbYpk_i=&UJWxBbVgkWVVm=&3D2EI4YmWYjXm=&INJNqAZnWsWco=&5emMdZZbnnfkm=&L35PdnXnkgUnq=&5RVOJrW_kchcs=&hwPYH4ZbXinmV=&W8Sw5aZqkbfYl=&ByYk3cUjjaXgn=&nCH3dQUXdXcid=&FllPV7UdpaZXc=&BfFIW_Ylfjmsf=&_AwZRLYiZpcjf=&CYfc74Yoah_W_=&kXgiyFYd_nqfe=&QgTjKIZqblWdr=&x3YMErZWrmsoj=&XrYgTfVilVnps=&QsyhfoUrVlnmf=&NRKRihYUjcpmV=&I9kPiiUhmqfee=&yFdIMaZsZbfoj=&2hpNDYZZgVdsa=&bk8iiaVpbkVle=&oL6aGKXUnglsc=&2wSvdxUsgkgZk=&i7QFaMUZigsaZ=&6FRX4HWXcliZ_=&Rux9fzZibnXZo=&6YWtsBUpngjYl=&Hpw2WKXZgWckk=&AVhq6vVXjUo_U=&aw4YnGVUapcng=&TK_VnRUZUhZgq=&dKPxNmYlfonYo=&w8MVYIV_orkVk=&4Jjg8yXbX_hVm=&CFRulOVnhblcl=&s7Z_X2XonqVmn=&M_qKaQYbejn_U=&X_AwrHVrlp_kY=&f2PpdwXaqsql_=&iCELP6Ueckesg=&MuBcwTXegbsqf=&6liaeQVbigno_=&Y2jT2IUZpkYUp=&x7TnXbYVogqqr=&T4KKG5VU_giY_=&W9ijXqZVYkq_r=&JEPoEDXsodsqa=&LdwgdpZisWYfn=&EZfrL_UpidlbZ=&jlQQqQZcUjoYd=&7EnScOYhqqpnf=&3dR6wYZZlmjhp=&WrvWiGUcYhqqq=&vHZpU6Volgerd=&YlVOe5V_iWr_Z=&GKN2vvUjhqWen=&WeVmR9Z_mas_k=&Zu6AUVYca_iVV=&Vco5qEUngmYel=&RhyZZdVlocqdX=&ZfLtxdYhrWidi=&GbWc7xUidU__g=&5dc8itWkjrYnZ=&XaoagtZ_XlkeU=&9baFzyYUWZWWf=&WCHKr7YmnilYj=&YvppfyUqqhqfr=&46xCxtW_XcpoU=&F5mpfQXsjVriU=&7U6KrpWqkXafW=&q3AlodVdYqkof=&I2LhmdZkbhnVU=&Dn5zgaYdimcZi=&8IXDeGUdjfgpm=&Cg8lRyUekgnZq=&396R2kWo_srZi=&xsp8hOXdbiWff=&yKYRsrYmVoXWp=&Sr9HtqZmsWlVf=&aMRoADVdcmbso=&_52TZsXdUVdrf=&UX_gnbYncscZU=&XCNFiWWlbbdUq=&64WVUNWWgdYnb=&QblijmXpredVh=&fDW5BaUVshoqm=&eZ96gSUYbh_VY=&HHu8dPXfoiclZ=&e4Dvu_XdjZakk=&FCk9lrUpjkokc=&CVQYDvWgmXmsh=&yUK5I5Wms__ap=&WPS3BEZqkferU=&KBlIzOXpXdlid=&f_IkssUhlrkgj=&BnmOivWmefUaX=&gIX2vVWjphWcm=&agu2hrZcYXkrV=&v2DJhxVehXsrj=&PdEx5aWrpZmrW=&ImlKmlZqksqeo=&XNteGFUjpgbmW=&7Mg3QCXUWrqdY=&KGUdX8VaY_m_h=&o4DmQNXghkqag=&4jVkrTYlcWZXl=&RE5IVKXYhXoph=&xSYdXrUiprclY=&jtXgnOVmgcfYZ=&Qj6pk5WXipqZh=&acX6TOUacgjrm=&3XZrAUWVbjsdc=&H2OTOsXgbsmii=&MV5veKUnbmZdX=&nN5XxfVgkghiY=&jAiketVqiXpmi=&fPO_LDUschlil=&BJ84gfY_shYXW=&EthKzqWcbeUhe=&O6fiu3XXqfdbU=&qocUQpUpbf_fo=&kv_2AQUiVYlpc=&KRcausYfVcqbh=&Hu5nxhXimdUps=&gYqxOCZUlZmfi=&o2IaZ9XZajosc=&R5iZ2LUec__rg=&dlaIS2Ynpkkes=&m7iO8uV_ngssi=&cya2WXXhkpdWj=&m3thbDXadaaXs=&Q6hwEPVapbZc_=&Pyjz8SWacogZW=&CamaZjWUcWl_a=&Y62rPvVXVeUVo=&aA_56RZepVjbU=&lCGtElWYWbhmW=&PZDzrWVeZrha_=&rOnGQzZaermcc=&Qfk4eIVisllea=&2XOa7CU_eiacn=&d9bwTSUalpXid=&KDrlQrVqaZnoc=&zVDJFaWgUfk_l=&vijRw3VZVljde=&MAV8YlVgdjhoa=&6mig6ZUeinoqj=&gPLwshYbnhWkZ=&8kMC2uVcshnUo=&HzQXNfWZsXlbi=&CeQ3J8UYoYpgq=&yGKHjyZhigoiZ=&nAeQpWZnjcqlh=&Qlmt8nYlUqYhp=&4VWNxzXmYb__s=&g2zjsdUcYrcXb=&NkIADzWofrYcs=&L9vpskXpUojrs=&O5UJc9Zd_sjnm=&Za4HilWadcXaj=&Sf9KsqV_drZUo=&2HnnDmWhgfdlq=&W3_sspVVgnWof=&bIpgkiVilVXfa=&SnKqoPYqUckne=&OOfl2iYciWlsV=&hIRFNCYa_nVgl=&XEPBVZYgeXXbh=&5TkQbXYgpgZrr=&aVxbJRWZccVcq=&PyX_ZdZeVbYgY=&klStGeYWaqiji=&t7RIrFVhqgaiX=&B9ejsNWahfsms=&kcWqTVZoVsbom=&f9lY2kYlqgcaZ=&n_hmW_ZZnqbsl=&tdtyNbY_dfrmf=&X7l4eNXVVVdlp=&5KJNlfXpsYaep=&cAVphaUnjVfkU=&5KCebAXf_oVoh=&4wM5bNZXhbXWh=&4UysPsXfbeUnb=&oZfoMfWadksfk=&TwMFaYZdeoro_=&cnSJ8pWglfgUl=&AItPv2XZnlaVo=&8iN2RjYehakef=&rE2MSKWb_UVVa=&PsRak8YaefUkX=&uZx5DwUcjipnZ=&aMcgzuZhWrZk_=&_b6LVPZmXf_Yh=&ekPWxyVopmZos=&23tULRYZiYVol=&KHQzzUUhjYrbm=&Uoo8l8ZWdsjal=&zgCmbFYfkosYl=&oVt8GPVksrdfd=&U26zikUcjVmU_=&Z6SlSSVaoXqas=&VXW5XxVZjWesY=&MnaCakYY_isom=&OeOWeoXbVqjgd=&KFrokQXpnfUcV=&THO6UDUgnd_Zg=&cgHN7BWmZpdaX=&w_AoySXWokjsn=&e8rT7hWihdsmh=&akGr8cWmd_ZXi=&JUvtWeXZcdWnk=&f83VvEU_VahoZ=&NEDFbhXolilpq=&l2K9LsYshmfq_=&jVDyeFWoqXhXk=&aVOnVKXf_Vfpr=&KEVEs2Zekromr=&H4L2fHYnrqWfq=&AJhn8tUeZZndk=&oUPA7WUmqlb_a=&nw_miVXqoiiks=&VynKMWXXfooig=&dT3HxcZademin=&yojETVXfnnqgq=&GO4OmHVjjkYoc=&Wii6e9WUVUoUp=&wVhVlhUbfmcaU=&8h3GHNXmnfrcb=&iBv_2zVanirWo=&LaVvB5Xl_dmZh=&szJWjGXlmidri=&yT8_fhUbkhpld=&GWvm3VYpZsjkU=&_9EyHbWkmihdn=&eyeTlLXshgprY=&WAnJLZXbjdYZs=&IMQ5IZZUijpWV=&eA3B4NVorZdYU=&9SZyuZZgijhca=&ow9HrlUkajUaV=&wcSODmXejpZVZ=&sMOMtNUhseUrn=&uojcKNVbepkmi=&zAjDSuZeghill=&HK88ViUbjUasZ=&pFw39NYY__Zkr=&DHnKzxWXUlmgk=&VmlzcPWUedjon=&7J2CQPYnUYaVk=&wgi_cdVZnYXg_=&bJv6RMWViWh_a=&ZAT68JUrnqkkU=&OyWxvJUhhdcmr=&IN9zn4UfWV_bY=&2RfvjLXXjq_sg=&SgFMU6Ubskjar=&_VW_n8ZZaoqmm=&SCLY2DXsjpgil=&MYqlJAWVWVrlp=&ctkWKsXkphdgm=&9zXiTqUrbseZl=&BySrhsXjqpcZc=&a9CGyGUlXloll=&V9OsRZVeYgijg=&Es85jPUeZnVrk=&Z6ynBQYesngjd=&lvhjOjV_drqpW=&kSWFe2W_aZYdj=&74EeNOVcaibkV=&wxVmBiWcaqVba=&TzEeNtZhrYjfW=&E7suJfUhfhqao=&IDAQGeWodZngj=&HFLk8BUjcemmX=&U9stk2Udnorfj=&2t4TnoXV_lead=&C_7fhwXe_khfk=&OGlkK9XVXkXXp=&DwrLHAUWcnbhs=&xtR2c3UgiaclY=&2tMqX4Uck_mUf=&4fco2JYXcqqnZ=&hBM5O3ZhblpZb=&uZt4FwZqWa_as=&XRmH5KZhrqXke=&MARqwfVfhWXnq=&vlAVLNUhYesZm=&IWJpmeUrY_ijj=&hxQsMHX_WhqgU=&eCb_oeXqsnldW=&blXsGKXsiccZo=&6lrr2tZjcneW_=<uEOQUUchag_=&JOAAwkVlXcdjZ=&CiDvsdYelsaZo=&R8gwzVXhlpXW_=&wrZY3SZYbprbq=&wi8saVWXn_bXd=&A8VEeyZffrh_c=&B4T7JuUg_fedr=&DpkkrHWiigprn=&o8HFuiXbVfZqf=&nkdczxUmlWaqg=&6g_MkbYkaVUUW=&ewvnWsWeek_Vk=&pAMBExUhVqkYo=&5AmVY7ZlorYoX=&lbtLK9XdoqiVq=&Sl2RnrYkkepeX=&N7zM6NUmpbrdj=&ll5SSaWeachdr=&T3bhBZU_go_Xb=&3xD8FdXUWYjrX=&nygMCHVfisghk=&aEHAoAYVgjpsl=&tlyg7MXkUnboo=&Ng2T5JZb_bspr=&evOQB5ZrgqcYX=&KQCaJZXVhWUci=&Px74rKXXWhnhc=&PCc5qoXZpgWgf=&mSCJDLYnelfjo=&ZR_rD4UVpddhn=&AwBg6KVglhXWV=&HI9A5BYbrUhpd=&Re5R4EVXWcprk=&DleVWlVXbkieo=&o4xB4LUjVVobi=&bJAwtjXjjcWnp=&_9cAQvZqsimWn=&8yOqb2VVYrnaY=&7haGQsXfcplUW=&yhwMcjYgjY_fj=&Zv65H2W_Xdi_i=&Ct8k9jVZYjeqp=&qGqvV8WnVZYmf=&BiptYNUnrlrkf=&sFFthNVdpip_W=&CtB3MrYsrr_hd=&WvJMkXZWipVne=&XdjCpzY_njipr=&occ7P_WclmYaf=&EHHMCgWZWiifX=&xjOrKZZiqmVeX=&m_dqTrWhYlgma=&bHnA2xXdnqh__=&Pd4mBkVsbnheV=&fFuLh3VVZeU_q=&mkXPGtVmXkjjg=&jK9laoVrpiqaa=&yGUfHkUcUcoir=&CsawspYgXsYiV=&Iivt3hWssVbpZ=&4THxtAYdrqmYm=&r6_LPEYaUgbbZ=&8DYKzmVskZock=&72vvX8UpanqiU=&_qGCeoZjggkne=&2yyH4JVrgUfhr=&kdBDhPUpci_XW=&ckfoiHZbaplqf=&vwEl46UfaZoon=&pGleI3ZnVkarn=&Kd5d78ZeVnqod=&SF7L7wXjcWfik=&59MAnYZbjhfsp=&CVXgXyVdVieqj=&e42paFXYV_khs=&WSWXFfXoVggrj=&LYFsAtZmriZmd=&KWhBuwYWWXiVn=&g8FL9lZcikbhU=&8FMf6DWnsfVmp=&KBjGOEYVZilVZ=&IseQXMUhmpgeY=&vHxvnrVolrhrW=&6BOOamXrUZaqa=&ptgzIJVofhgms=&xGUcy5WVX_Wln=&tLBooUVrfUpcc=&zdylFpXiapXen=&fSWhsOXsXfdng=&WLylXTYrdZrUp=&_s73hGUpjWYsk=&iHKVXTUgXYaeW=&thE_ARYfifcqq=&L7nwuWXngrqkk=&Idi9PEZUjiVdb=&GxvloRYWdfghe=&uno3wGWmsUiZp=&EkCTRxZUjgisY=&cottQjZloXokV=&_LefrVZXhlrgc=&caxyjtYklXbZY=&5cShclXrkZlfi=&jalS4WXfshdjd=&icZCROZprjf_a=&SRTC5EWliajUp=&Qd9qw2ZksXiXe=&sjd3dPVdsoidq=&ESqsarUnfbads=&N6G7aLXiojfor=&wSZKt_YVnWocl=&TPQhbJZVoqVro=&iMLSnkZjfYVsb=&F4pvwOVjcriqq=&uCBD3KWnbriaa=&btybM8YXYhXaW=&XA3H6nXVbVpeW=&CNeK_FVipfmhV=&nwJmDmZbacdYn=&RAWkTHYdXjmYZ=&qIYgKwWppogZW=&f9EM_mVZoqsbX=&T7uUbjYokUUUe=&PLLdLSXbXkZia=&DkFjKLZdshhnk=&OkU7JyZfq_blk=&fQlOSCYcpafr_=&kmRdeNXUUbhsl=&hsMQ6qVanjUYo=&xbEVLLZWdjmYd=&jtNIlGZpnhnpl=&fLuzUpVpgZ_hV=&ktOOzTWpchmes=&wyZsWrWrqsaVb=&NDCESTUnX_Yjd=&cHpGtZYYUbWm_=&coOQ_CYUYaZdZ=&2tUXEMZhZkobY=&tA99ZIWfdbYXb=&gBjoZpXikZXog=&XJVdPOXpiaiWW=&N7BeKLW_eZbsU=&gfTgfKUnaemhi=&VL4Kl_WfaqXab=&YSU2zpUpUoqdo=&S7oRtGZYq__mo=&ujWdCCXXXUfZm=&iXs23zXfijYpU=&zdAEzqYqqrhcs=&tliMaLYifdgiq=&Ibs9NmVU_mimi=&Pyyi3dYmncjor=&im3RIeWmVqYeV=&rbREFfZqqbrZm=&bUfqn4UYUbhX_=&KesFUBVZjahgn=&kNHps4VknhjXc=&QEqWp2VsnlgYc=&UmkWq7Vlklpdo=&ElpnqqYaidYjs=&abeUEwWWVdeci=&wb6jpAZsZiUqn=&2knjuGVjagrqZ=&2bHiSZXZhYrob=&2swlS3XksroeX=&oPzGgHWZccf_e=&uKZ_QKVZgpWin=&hQzeQpXskWolq=&F_VnnVUpnkdX_=&rJjbOyVprpsYr=&i5egv3VldVmrr=&ckNwFBUkrfkag=&qzVLb2VeXWqY_=&_wZqANValefXl=&uwHVmoUlXigan=&ATjIdJWcfgnXi=&zQ2sjLXaUXhld=&M48zlXVcVhjko=&P5bd6ZWbignqq=&j5ee8lUfohdqp=&uBq3KcYZWnjbq=&Cosj_wXhUccXh=&Y7KaXVZrfkrYp=&V54skaXrmXbXi=&8TqYIOZhmUZll=&jYQ5OqZbebaWj=&H5l6oFUispepd=&63JtAYWdXlVdh=&SMhzpGXUbpoib=&Dk38lkVUiYgUb=&NYksp_ZafVolp=&PnUFMqVfpZUYk=&qCvnVOUcUXrpl=&QbtEOmUjfcWZo=&HRwkI8Yllh_pg=&qXSpsEZioWrrg=&OnJZSdVmfnslr=&Hp__OzVYdVmeZ=&HjB_pZZgbab_l=&HVwGVzYaVkeeY=&LbMOK5Ylcisnp=&V8sOOuWhWjlVl=&3yTIMwVbl_req=&jzicIHVpbdUgq=&SDDas8ZUfU_rj=&jtGcujZYkqobm=&KKBeZnUrUYcXg=&3Q_P3IZfXfaZr=&_DiJ8DWnqrUkZ=&KKNU5uZZhbWVZ=&yoeQnXVfppmYb=&Hu6tNYYZdcenY=&udym_YVeWmXrV=&W5lSFzZdfbliV=&nYzJ32VangVhj=&ronuniVl_Yiaa=&o4XopwWrnpWil=&Mlj4OFWXVnebp=&_BlpIvWbmffeq=&5TQjHHXkaZplZ=&Prbhq4Udahkqa=&cONE8_ZWYpUps=&tG4KNhWZnemnY=&5wQutXVZjmrpi=&e8raevXsbslhU=&wuWcQKZVrhgaj=&dYfzanWZ_oUZh=&OdAMIPZpkdpef=&l9ZujaXkfoaUi=&VzISzaVnoplhd=&cX6ljCYcfbbgi=&r53pyFUXcqq_f=&DQKhxMWZsjWgc=&T_uWhZYakeXhk=&myhiGPVpqefia=&J2QryNXlij_Zh=&Q6MKyWYrpUrah=&FJBGKzVgXdrol=&9iLVBPXVsXiVr=&mrm7BhWkjYsYX=&Mqb6eNZVUUdbU=&WcdYOwX_UeZdd=&YYMvBRVmhsmqY=&lTASTVUk_jhra=&4ZXoLFUnrWW_W=&CqPv7hYWodksZ=&U4gaamVVdXqkm=&qRyGraWopdWlY=&f3cMkvVn_lqWg=&pvxua7UWfnYUY=&rpWs6kZssVcXZ=&WMTMKcWgfWgfa=&ZGqKDdWrobrb_=&uyiI3GUh_cjYX=&XqozRdWUnXZnl=&SSheDtXamYgpe=&RB935dVnaYYkU=&nrJSuBZfpdUsr=&5fjY5xWXeaqgp=&_d_LCFVjcUpaf=&jXYEigVXmoofm=&2fX8g3ZrkiaXg=&cjVjLHYropmfd=&W6fdgfVnhXp_m=&nVRb_VXZVVhlo=&8CSX3jYZiclbr=&64WNGxZcfUnis=&97lrPnWeecn_Y=&2S58ESYZpYnmU=&I9kumvVXsXVVd=&PUdE8bWjclfVV=&UfD8FlZsjassU=&4kQHvQZhVe_qr=&35J2eZYkUlZW_=&LFuM66VWmb__b=&YQ4DOkZlfjfkY=&rWtRmBVqerbme=&uQjRpEXXehorY=&2z_w66WqecYpi=&jy2pVUUrnlbhg=&x8Tul_XjdUWic=&xwBgLaWVUdkpf=&EziklhYjnnmn_=&6hDN5VYVrfcrW=&2hOePRZnsnbmb=&F_7ocjWddbohV=&ah3AUKYnsqooX=&LzYgHdZVsUW_X=&haTkA9Vchpr_d=&tSvw5pYgjVekU=&ujyCTYWnbXbgp=&gCvXq2WgVooqd=&qyDVcFWmaWsYi=&PcctuUXrVelXs=&uqpDJiYgmlqUZ=&4CXMZiYnjgelf=&g94ZL8VdVXggn=&35rY4wUdkkmbj=&ma883EYVdeWX_=&ihea2uZgkYhhs=&FViXjoWliWjcZ=&OyPUV_WrqoUrh=&_9yZzsZVr_aVl=&gU7AenUpmmfZj=&dHUKGcVVnjkrs=&4hXSctW_iWoYZ=&4s6HEXUm_Yqih=&5B_KuOYWqpsUl=&UV3_3bWZpdmVV=&5Z3ryjVXYZUnk=&lFj3HrYXYkoir=&RAIm5DXfnrgdk=&tu25WaYYYadVb=&3lCKJIZZkci_h=&QWecFvUhlbgo_=&ApKL3SWkeajo_=&TAuCPxXUjmfja=&hYJ3TfWgYkdrV=&F53FEhWUanijk=&7idORtViaanom=&twisF8UgkjVcW=&5t2RtrVUsdrWl=&Ll_sz5XWrhcid=&9fB54LXjYrce_=&ZZJEHNZYVanbY=&BW9UCpVXcWXi_=&26FfOQYkZihng=&kw4JHwXfgglkX=&MEXgxPWqjkjXb=&_yunwZVZrXb_W=&DwzsdZXnVWlpW=&uU3WVtXeYnq_l=&gRacjdWkmmbWj=&AhPpv2UhahUfh=&bKgGkrVrdUa_U=&KEJUloUljXasY=&hvnQ4XVdknaqp=&xd7PWCUiofWYX=&HbrtnJUbgelpa=&WZK8H6WUhjWef=&vzWVfUYppkUYb=&7ej2ORZkWXe__=&Rwy3NIUZcjhVn=&LBdcEIYW_cak_=&zIesLoWZhedVl=&LkiZJeUYodqkX=&6XXyLLVpp_rZn=&nYap3lZUamcn_=&amLx9QWrZcdlV=&Ek5yWrVsnqejd=&AkR7j2ZpkdWfo=&3YIjDvXmqcdpf=&CE4BbiXjgiZlW=&_SpYYrYjmqaVZ=&CiY2ShWeeaVkm=&yjQOuUZkVe_dn=&QoQZMAUacXgVe=&gWCqn_VVbcqmf=&TH9GPIWkpYfkW=&IsYLXbVlZrpZY=&SQQUFjVdcbkpr=&xKBdBhWjcjfen=&iR3nlcZoVnhe_=&lg5hm5WWcVeom=&6g8F5RZ_rUmhY=&v9ilgZY__g_fh=&Oio8pHUVj_lji=&zEVFBtYnpajnq=&E59ztdXWqksrs=&RSOeMNVoiUjlY=&wnnL5MVXo_hdU=&WHm46LWamZidZ=&chMRBCZVbepqe=&ccm8kbZZUhVZs=&2NEt2tU__cZrm=&lQ7nEAWarYsiY=&KUAA5XZkfmmse=&u6zIQfVcYYnec=&snQRSlZer_l_Z=&W8CPjrZfmnmqa=&MpefnCXkooZbn=&osez6MVb_ieje=&2y__DdXjZrYrd=&b4zHT5Umbngnf=&DuipnAYgdgVZZ=&Kf9udkXlYYagr=&MfKoWdWgedsWW=&vjxX32UhkfZrs=&nB3YhDYiilq_q=&Ynj2NEUbUcdjo=&NuyKXYXWgmWln=&l95VarZkqmYkX=&3qmBdgYXcgVmj=&wBu7zyXao_oiY=&EfQMDGXcefXUc=&bll7SRXZbrikb=&2_ctQEZrWVmmc=&su8C93Ykilear=&yLpJCCUancfeg=&qsNNoJUUXrhmV=&cVKrLQXfmeqcq=&eTNb9SXYidlcj=&pbiYTuWWoVcij=&k8LVx_Zgri_ZW=&JGGVxGUdZffhr=&KydwkzZeiiXnk=&ZMn3VcZXqsVaj=&V4LbeXZsolalb=&xdz4BjVXVW_mY=&764xZCYbnbqqc=&NKfWEFVVUXcdm=&DNIdsVXkXqqUr=&5G2hggWkljplp=&jZ4g97Wekjmgb=&8G5_5OVdgUfkn=&GqimjsUmnfcWU=&5QJMy7UgamdYj=&k7cCocWfpiXoY=&InfTsFZVYbgdb=&hl9cZyYZ_ZpcV=&Jq_glhZphXWsg=&Xc5cNgXUUkrXe=&zeaifmZrkgeUX=&IDvarPUfUfkmb=&vhgRbwWnkgrdq=&cUJUjiYabnhWY=&xvMac3Zbbjgfk=&Gf6ZRuVniVWUc=&QQFMMmYeUckhX=&trtvGaXomefVs=&ZYOu7WWloYYkp=&uJVdfJZZpsdZZ=&kmJfRIVqhodbo=&gxcNXvWVUoeck=&sKOh9hZWbaUef=&5VfYknUYUgeik=&U47DrBVscsbbc=&dGQotvWZeXqdf=&Lz8V2vY_rVdaq=&PYlminVlkidZs=&DwUSAKZnUnimf=&6Uy_JyYnkalZg=&auzvXrUodYdjY=&heDRcRWccilpj=&V5lZ23Xmal_ir=&eX7m7oVUYsqbe=&yRllv8Xbsmqfn=&nQDCmYUs_goYX=&8xZSZiXnbkUco=&_zDz9DUcsssn_=&RKdkNRW_c_loe=&ZUiN7sWVhlsag=&T76qOUWZrojUi=&bmrb6YZXqoWYV=&MhCFVmUpYVVbs=&DWilDfYkseWfe=&cfHVCmWlnaqs_=&KWhrkVVVo_mdb=&ALxQHAYWcdgkZ=&edrzI6YUiihpr=&YCnIesUfko_hk=&U93YguZqcesXp=&tnkU3uUeipogo=&7A2XnxZmhsaVg=&X8KlxUWcYjhZg=&JejYRjXmsccjh=&Q_W55jXXinlpd=&iKIZkbX_lbkdZ=&7iKCBSYmkeXVa=&NRrsAvZehWmUV=&VgASFmYXgZir_=&GZbSfiUerUXqm=&2jMj3kZldZslh=&r_752GWZejVXd=&PzWNmAUemiojV=&64qHSfUbYkVbm=&FSi5LxXmbZlpp=&EtoD6BWlsYcln=&8ZUrIrVUkajYf=&MhcIGSYfi_od_=&Ggcx7YWiVc_gX=&hmLIvKZVYheaX=&B9w6sUXq_XXjV=&jsuxDgY_kbnqi=&UcRT9VYcbhYWU=&mTTc3vYrrpjXX=&CGJg5cUclsfg_=&lMpK9dWsXlhdm=&E52SDwYqdqhql=&f2j9fcUXkprem=&_oathxYjZgmsq=&PNiQmKZVkmYhk=&It2EXIYVlqacm=&y2YBqCZscXkVg=&z826c3YYoidsU=&sITAOzVmjgb_Y=&pwZKN3UjZi_ie=&2SDhwiWZnelml=&CrkvH_Ybkhhbk=&RrK47eYfpn_ro=&7cXIoAZcUigZY=&LOJuZMWrkUYZa=&sHVHuhYYXdgle=&fqFSYRX_UepfX=&j6bWqbVYlndZg=&MRgVPpY_WWhlX=&PYrmisYWrepnW=&3AnxLLZUiZgsj=&YP9etxZajbZsY=&ij6a9sZlj_fqr=&bAaIKoUZ_pYsU=&ZZc7VmZlmYXYd=&CtrLkiWgbrepn=&85hpXIUhgpcen=&ehJw8jWne_sYs=&HCV_MuYphiiZo=&v6vtLaWoZirik=&RqMhYpUZdWpZm=&9HQlt8WbfZhfe=&MDt5TnXfmXhhe=&LnSsh9VlYUWYa=&3obWlFYrpdbrb=&dlfHMoXkZjrja=&RAQlenZmhWohh=&NZHy6yXiqgZgn=&oewqzfVdYVkYo=&6AJUTLYfplmae=&na7DkIYkojmqi=&fjs6S6VYZUabc=&w_T3yWZqUcrYk=&Trsoo_WdmnjW_=&l3EBkMVmYdhhb=&ZLKGfyUnWhpdY=&gzWflXYsYfWYq=&iMkXNVWWfbpsr=&T7nFXxWbVs_a_=<MiqHUcqb_cX=&CISamkYXcZdXV=&3xYKDxVembrne=&KO6Bi3Xajhesi=&WAWJ9kUrYfam_=&3NsoaoYi_cfmZ=&pHunlnUi_Wqem=&VGn9EnXUdnfgg=&KK6aOeYpqXlr_=&GiIcxVVVpmUso=&FLxIlyVZkaWop=&BKWDtWUhaWnsa=&WV5jT_UZWsbjb=&z2Kty9UlplYUj=&fCOigGUrcjWUs=&vgWdaBYUcngUn=&9KMDemUbiVWes=&kfYfrEYkUsppe=&mW3bJTWjprlms=&gjytQ3YroUald=&qFPvQ7Z_mgZaa=&nLpgUWZbVqep_=&gNtijkZZ_pefi=&X86DTjZqVVnfm=&bkWG2oYkgoXqc=&be8J3RWdU_cik=&FIhfjQVkgXhkk=&WVv8ckVoikh_U=&nhkeZtWWm_m_l=&4OSAHJUUVrsZh=&oFD2wQV_j_mfp=&ya29iuWXpejbc=&hLZn55UlashWj=&7L_ye5Wqg_cW_=&QxHgrTWbb_coV=&sYrtnWYrelkdd=&Wl4NvzUXnalkb=&kGOE8nZhrgYZf=&kFF2rwVeiYjd_=&OSCBjsXhYdhng=&2y8Un3WhkZncX=&xAQyuoXc_dpqV=&kKFZajZamqeda=&2J4EnTUmY_qsi=&PrGAdqXomhfra=&gbkkQSUVliieq=&xJvN3NWmWZceZ=&2rRJUzXon_iUk=&IVD9HzUdnWmf_=&dijmhkVUdbVco=&2g892LVselich=&MEGVN6WobsfXd=&SdNQpBZoUcjpi=&DQObRcYeV_pqa=&8_lC9kXXXqqoa=&m93DV9UcYdnhm=&QXaQjDZVedlWq=&MJv6AoUZohVr_=&KsLRHmZdddYrp=&avQjIOVhUqj_q=&hNimcbWVhgZsZ=&62ZJqUZdrpWql=&26REE6ZrrkiXb=&KFmZ3eZZgdfhs=&8C3lacWocfUms=&GweV3BYnegkVl=&NdZMWfWmWfcVj=&Tm_YxbYZkbrhe=&Mk5wlyYZhr_Yl=&wbwAXLYmeV_mV=&f7lHZgXdkWbak=&IbQeuyWhUmbeW=&8nfKmnXblVhln=&rDvvg8Ylkckeb=&iHAcGPUUWngdX=&Xq5oHEUWsdYos=&WvTVU6UpkniWh=&sjAZAYZZsggra=&56xwLlXZjjXcg=&7ntElfZWlWqcV=&oFFjhHUWceclb=&yTYGskZXVppcf=&qr8HOiWbqqZqg=&O_WsrlZnfljXh=&PhHhotXcWUiqh=&39YbBGVcpcoed=&rWlySvXnnok_Z=&ZJaWD7XWfneZo=&ENQXVaYiqpnYo=&6NtY9iUpVcrda=&4gBR8iXVmpXsj=&3mYMQlUaXncik=&ToyAV4Yf_drmh=&vgnDErXeZhjkj=&pZmF8OZaUZbhf=&FohnbPXUVjoWp=&kNVaD4XhhnsVq=&qc6qaSWalWdmW=&BesNe4Vsdklkj=&aJEwNEVpnXfak=&6rmcZUXVemdaj=&uPn9I8ZYqafbZ=&PNEz6CYhqhYZa=&X685zXXdrbUrl=&z4SoHIZ_ijdeX=&5LSXYgWpisdgj=&VSGM_VWhZYsn_=&8aaJOLZdbllqb=&tw8hRRXUWYrmg=&BDbziTUUXlUqo=&gcBxlcVaqWcar=&3bGOydZWkqfkd=&YzqCN6WdqZYse=&QVgw63VmY_VVi=&5jebBFVqbkh_k=&ADcZEsZgiolcl=&qsu8wfVebVsZX=&5kwZSTUUhqqs_=&Mn2RJeXWUZk_n=&VLr5veZscfcfa=&8Hkx72XUsWiZd=&FjHv32Zeandih=&7BRDUPVjijlXs=&GryXqOWVadXUa=&fBtEPGVoWhWiZ=&cEcVMqWYngbmY=&v8DBHEYnqU_gX=&ulxMGrYfsnald=&68wDtKUiklpns=&DGsNUBZUXsZmn=&8GMU_5UfqYYjq=&ieJcomYiVZ_pr=&PVZSndY_cmVjs=&rCBQA2UV_bfpY=&AIOM8zXfVmbaf=&EtcrOaWpnf_qm=&K9MS89Xbio_WW=&_ktQFOXjjobqr=&FLF3mEYWVpjZm=&yWPQ8XWgcZXfn=&D2GApQYegahWX=&fFxl8YVeYgqZU=&odDkzFXbfbqof=&dkFVWmZZdqZYs=&lCeqbuVsVViUY=&DJqw6UVXXphkb=&Y8MnymUprddja=&SZD4MrXndgsso=&r7BUvIWefbrjg=&d23_XbUhdZsdX=&7JiGFuWhjVgWg=&ol4UvyVpigUnl=&OehphAVYnkaXh=&bGojmkZgXnbWp=&rSrt3oWlZa_lb=&G3nazMXdkVfmj=&s4qiF_UiYjhaj=&oQZzi3XeZq_bm=&UHzxq_UYjmaed=&3d7XXIXli_gUU=&8uDPgrVkdrXib=&u2rGI3Vdgc_no=&Smu9ibVWiUYin=&fIzEoAZhYnVgn=&zNYBeDUVWijWV=&uz26TrXZgcWai=&RgiMGwVrZdhbc=&I4hgefWsVXoZn=&yobyllYffpmdU=&V7deVdZeoVqZe=&JKdYglUaeUedp=&oNfBtnYijhmUe=&J4CZp5ZapbmiU=&UKdmEcUcVqpaq=&EMmM6tYsjpXbj=&JXzn_WYprVZpe=&QLTGh3Wkhasbo=&87RvWFYegaVea=&iXOmYMXVVnUpl=&GuwcqJUYZjmbV=&Nhm2SjYZZiiWn=&CL5zuWYVXdnkp=&DiRM3RVkogbcg=&Any9akWsqpXXl=&2mwCuNWWcprsh=&GotUFOUqZlYef=&kxO4oZZjfmfiq=&nlCd3VVakambr=&FY_2EnVpsrVjV=&f6jIrSUopcnYb=&D6TVzyUrWoVdp=&3Au3KGWUgbrbk=&vW9muWZYqsWrm=&8mMgDYYUfmlaV=&eMWXUgYVfaicg=&OMONklXioUdlW=&SHOIHwXjYmZdh=&GDVg7EWaiUerY=&UTODAdU_naoWV=&GQnKYiWlWjcaW=&uF8QadUfhYjhg=&8sjYULWlmnciW=&jp6cd8ZoXlnnj=&EXJfTxZnbngbh=&Y_ZTDrYdhZekk=&6psxlhUXsisgb=&It7li4Vpejhea=&nnTzHpXWieaUW=&b5W9UEXekkYpc=&TblQcVVcVWcgr=&tLLPLVZUYmVXq=&rjbu6gXfeikfc=&RttSBKXWhUmVY=&rMvnQDVWWiYXr=&cI_S48UgccUod=&sXG6rRYemYsYl=&oc_wV3Ujolpkp=&UMpWMZZYsWVdW=&MNgckiXql_Zkr=&UWkqo_Zebmlrn=&_WygkoZWeYkkU=&xrWdHgUdZarbf=&3z7cxRWXYhgeU=&9OKrRqWss_bpl=&yPTpJ6Zoehdan=&pJpmPkVmlsapY=&NEyn_XUYqsZ_j=&vfkMiyZqgsriV=&s9USlRWfaqhhc=&F5LoFtVcccoqi=&ImKcBjZrngahV=&RwpcnfZhrgnlk=&X_EBSUVgqdfXV=&dKsTCQXbqhnrU=&6PnHJAZphdcnb=&3Uu4xuZdVZink=&ZQxWSuZnfpsjg=&QKC_t3XVca__k=&tRe7t8UoboYea=&djrpfEVZ_bdUU=&C4T9lrXqZYkad=&EblsVGWZWUWib=&WPkuftVlglgkj=&HVK78nUVesnVa=&IeRzNvXWXrkXl=&DdnVVkVWWZnlY=&xoDeHOYrsjeei=&KW8CrcXZeWWed=&hEb47FYodhfgs=&Hdv6h2UaYoXnX=&iEVHFfVbVUgs_=&hjHruEVjWqrhZ=&q2kk5XVfnVUYZ=&EwhzgjWUZelnl=&ipzNOAUinrcnj=&97fCC9Y_l_XXd=&NXVFHwXedgfhU=&rBwRFTWlUqlsk=&b7qSaBYoroilh=&GKhE9_WjWnr_X=&rWeJNaUheblZU=&MyAU2hVqmVnrX=&oZHeW_WgcZsfd=&UVmqcFZ_iVZYs=&q4M8NEWrheWWW=&KvlLPZZseUlUa=&kUPr_tZnXWXmc=&RUmPWpVgUZoss=&3nqZwFUcjmmeV=&dJlxTaUgbeWaX=&CIYJQDVjc_mjq=&Am3oxIVd_egee=&wJVVLVXiieini=&Misf48Y__iVel=&2KdmY9Zh_ipcg=&mHmQG9Zlo_rXs=&FjfKIhZZrii_o=&9P_lCtUksUUUg=&g_tdtBZjZpebs=&rMZyQNYgjqoZq=&hEaSAMVmikfiq=&T9wETEUnkXlg_=&tm7MGBZcgfqWr=&7_GpaCVV_bpXX=&AwL5UiUdUslUc=&KsqPqbVZbhVhn=&pBhRC7XZrWqaa=&gJ7gbkZobfgiq=&8efJtdYfUUcej=&yDM62AWVkaspo=&VpqUxXVeekego=&Oeqf7wYqXdiUU=&8Q2CgiYilhUgd=&_nvZXUZYdpXkh=&cjIJe9XedlrWp=&XiO2bnXYnVVVc=&uFHtscVqWYYoZ=&r6y6iTVUnkVs_=&bIKK_HYcieZrh=&eLYUySYUnbrZo=&t7cQWUVm_ghXX=&EazwhvYrYbdsr=&PWdRorXgijda_=&JTfthGVesWl_W=&PMUsB4WbUXror=&wxPxmcUYq_opl=&MvNxG_UWlsocb=&dQeWDGVahodcm=&zVtiXEYjjUUrq=&LjIbqRUm_sVem=&E4NjX2VXaVWrq=&FXZ7IuVrc_pgd=&ouO8wGXpUUXXq=&RDTiPHXqWqgaf=&kOS4JuWjaidrs=&cgrnBXVdqokUf=&lBGXadVVoUXXj=&jhHmeQXbppahZ=&8WDdyWXajWeiq=&FH4ApyZrnsclX=&aev3A3XpeYlkX=&BUDQuJUne_cZY=&p9mjsnYo_Ukjf=&WqWhpoXYVaoXY=&OVbyw5XkrjYrZ=&EcU6XkZsebakl=&Ank74jZdooVsp=&7VsxgiVlrrXpn=&xFoRNsVbedrdm=&w8edHgXWUigpU=&4wPo9eVnpphVn=&ZxMc3zUcZlmnV=&x6PF5fUVroVpW=&tZn2zzVVapcgW=&UBuECuWbYeiYp=&KMsbDwWnso_fX=&DkVHbMWil_bWX=&Y9skzMVfeXr_U=&Nk7pt6Yobqkeq=&lV3YLHXsVhjmV=&rivJ7aYrasYef=&Rv5OloUdapmeq=&96btMJXqUqsbj=&8oQVH8XgUibfm=&qc2k2jWXkngnh=&59hHPVVhVbgUp=&s6EqmDVqsWfYr=&ZAIv8tW__babV=&bMC5KhZW_jsYb=&8zEOqHYUegqoY=&X38TQCWb_Uhmi=&D6Kck3Za_Znff=&a8Se3zUckUloe=&4OrPOEXVkag_U=&2LtPtDVqksrWh=&rIQVx9XWlnrqW=&DPGPeaWqVcbcs=&nRwAZUZVpWWsb=&ylYRvvXWZocVm=&H3JgPSY_bYlbX=&Tmv7CpYgWVcmX=&NxMjIhUlgsbhi=&MfzHGxWlYmYhj=&qY75cIVmkVVUg=&PxvLHuVnphabV=&OhVVeWVYmVnps=&4kk23sUZq_Ypb=&rOduE9Vldrjpf=&OpFKjEZo_e_ja=&tvUspJUlkXcnc=&J78o5kXXsZoWc=&d3WJMgWhbhbZe=&3LwUq8WjgrVUU=&I2oJjjXidUWpY=&VmTTZIX_dbirn=&cKs5nEUqimVkp=&PXeIfcYrVYkUi=&eSUYSrWkWYVkV=&M3T36tXbddc_c=&sQGvv7XccpYip=&dstHqlXm_UsgW=&5SX_xxYgWfq_j=&xtNcftWmrfViV=&svgmpgWmmiVdZ=&ef2UA_Vbidhgb=&o7TM7wVcndUpY=&uojju9XrVZZpl=&AWYzSYVd_ZkaV=&cs_EyxVaYoe_j=&J762EOZaWghea=&BaM85mVb_scmf=&Ev_yJ9VdoqWmZ=&ZScaajUnejeYl=&hjTutXVnZhgUU=&QTvm3RVrhqkbo=&Nlv_YAXeXZXff=&A54WnXUWgVnig=&GdbOQRZblXYnn=&dXo7xuUWhjcpd=&i9SepwWbaVqoa=&77vbYPXorZYlo=&RQoBtwYpUqbnn=&CvniZkZhgbdge=&987l6_UqbgXhh=&uxVtRCYWqZnns=&RZiOV6Wlklkqd=&k4iLNrWlhWljl=&_CchYgUmfVbYp=&7O6FlnYWbfdXZ=&JTK_hyXlVasWl=&oMOcczYYkoUhZ=&DwGP2EVgYamWl=&gBuhpDZfqUrrl=&8GNvsdVppqnVe=&iidZCcYXXnlYr=&poBAmfZsXXfhl=&beiMsXXYdmcYf=&gri8HoVUjnqdq=&4qMvDZXchfsVb=&wtrjyKWerYsad=&ebOX_PVrUYciW=&TqHcVeZXVoane=&r4zWlVXYknsqe=&ZUdTpPXocrXcV=&knDWDsVYcnkbd=&i8ryEbYWdjofh=&_iabKRWhUbjkk=&sH3i5tYbjg_Wb=&QmOdwXUdp_nkg=&2f6nhzUbXnlhW=&RgHsFCYprXklU=&ZCGKDdZhWYpfm=&Wf73LlZrlkbsm=&s7dxmcUaXejja=&yOxR7oXphmirh=&W2RLWNUZgWp_j=&vwzKw_Vhp__i_=&hW4YvxUhqelXc=&SXyAh2YglchXf=&PIG8qpWa_gZfa=&vAEJCQWgrinhY=&y_wKe6ZZokdda=&FsXyyKYqghrno=&Vg2Il3XXgiifh=&3O5ZKdZseXprb=&dv2yFLZochWgc=&RHJ_pFVffcjnl=&DCbJVJZUUcV_g=&F7ZcPsUmnZjn_=&XhiXeCYpcnmam=&fRI7B2Y_lbjXn=&ifJCKXYVhaam_=&KevdRMZers_nX=&u2AvX8VZfdkWZ=&PVgZNIZemiXjg=&mDVYEjVggrYjf=&IVmWsYUflUUso=&rhJ_JfWlkkibo=&FasOqlZj_rkrV=&dvrEGGZXenjpl=&pQ3UiwZmUXoUg=&m6titDVYWYXmb=&B2WsIyUinidab=&9WHlzIYbYUijq=&u2CH_jXVqYmss=&QxqevkYb_flUc=&8QdmAwUiUbkZb=&ojz83YUsWgenp=&IHQUJKUlrYhUi=&VdXulKYaXXjbd=&mpY6jKXqnYbpm=&yDs57NUeUWfWa=&X_7IhhYcdmhlj=&xq8ZW3UfdndpX=&xWOLYRZec_sps=&TS3kiKUaZkUd_=&yuiTvKWplWcYp=&22fFR6VYgqbcl=&pBMfK6ZWhUWmp=&2yAlwtXlZVonX=&_VOmNuUjeqlkV=&mSXFTJUjkWZgr=&fEgdY7Wic_cml=&hrrWTpUeYnhbd=&7HIO4fUcXZkai=&VHLJcCZprYjol=&YXlH78ZlXqjh_=&oRScRsZZZhfUk=&wRrNX5VdUZdol=&AmrboWWqgnqbp=&nZYoh_Uqnqlms=&FzWxF7Ynagcrj=&zG4DmAVsrVdck=&Bkf9oEUisdUlh=&JHVCteXUYancp=&fqz7QAX_sp_sj=&7tcE2WWXfpd_d=&66IHCVZWk_mZj=&yCQIYdVUZbX_U=&xbcM3OWZlVc_s=&R85LbNYpkYja_=&E99f2RZdUjWrU=&TgTwQKXfajWbl=&HMMs3FYmdfYaV=&gYMmlVYjXdcUe=&pMeMHwYkqV_oU=&mybsZQYdeUska=&738BILVrnpVWb=&pSrjy6WkZnbme=&PiDF5SWXfZidc=&h3IsvSZnileki=&QAZ7FEZYXlVlo=&fino5mYVio_Xr=&2P3D9ZXlisc_d=&bAnklpWcmrcgo=&ZG9tm4Xnedchc=&K_hscCVmXqVWj=&8yGGBdZlebfhn=&6msuwxZabobek=&XXvfLTUkiosXs=&GdG5N5ZegqmVj=&lNAUV9Ysealfc=&HNifrDVrfchii=&3NOHxnZnYWnjr=&B9mASYUZlppdh=&ZQTWraVccp_qo=&2ZLo5hWhUciao=&Lsu2b9Yedpkdf=&uGo3tRYrpcZbb=&9pZWrLUk_Xbpe=&oIGPKCYlUUoXq=&l_g9pnWlmnoUY=&rNVzZIUecfkXi=&Fslli5YlhVkhq=&slVLQAXVg_mmo=&ylgjblZrjmnsZ=&IYa9AzZnaleXm=&OFXusNZXphcok=&Y6uslbZneedWr=&qflpr2WbUZlcZ=&wspdtPVdmfXsh=&acPwScUoVhUbl=&D9ilDsWqrdYnb=&XcUrzQUillrlg=&9AhFJDZXXfemn=&X8WZgVUjkZccp=&amKH8fZWihopn=&Zl5DCYZaroo_e=&EWvhHyV_hqWnX=&jgFeaTXWpcaoi=&3fbMsGVnnbpZb=&yvfcsiWke_isb=&mba_TtWkWiXUp=&iF5NnzWZ_jlYW=&K_MuBSXmaqbis=&d3TBwKYhmXjmh=&eai9aLVkZaYdX=&8f5ha5YYhgZYm=&C2GNbdYZ_nrgW=&4O6btiVeZlamc=&7TJ8NOVnWrsY_=&KgiblgYgWXhiZ=&wosM_TUoYpkcj=&7pnAenZ_qgcfm=&b3l8FQVjeWqcZ=&7MEHrLWollVfU=&2Hp2myUXUhcar=&At2ciYVfqknmW=&LRfUByXriZZof=&4msjZCXlm_omW=&RP2I6KWplkVhn=&4cUdCIZdpjpeW=&yXypjsUmg_qXp=&cLGZEEZliiqof=&YQVklQYhYgsXn=&6eTvoAVofYolf=&m4elMFYdkfisq=&7QjQwRUYrcVla=&tgkAlfW_WgVba=&fbrUC5UkXVbYV=&MLuEB_ZhVfnmc=&OJjpT5Vhs_ifW=&QIGCBhWgZVZrX=&skCZ4WVWWnZZd=&CEkhOlVcXZadh=&pdM32QZpmiVXg=&LiwhFyXnlV_gc=&54FJk4WcaZdho=&Kvn8NGUXrs_Zg=&QxjZ4YUVqUUsY=&iPMzAMWenqcai=&3PvmeMWhnpU_s=&63auAtVWssmcU=&pit63DZpmfrnq=&lcx3l_X_saYkf=&bvJPbsZmcVlfe=&larGdaYkshgUV=&Pjg9EkWZegioW=&_2TPfDYkWifgl=&dT4Cy3ZnjZigU=&uwk2FBYnkosch=&XEoP7NVoh_dlW=&B3r9yqZmi_pmp=&TWoyQ5WfmiZYU=&tpR6UJYddXkrU=&EJWx_sWhho_hU=&CtFw9pVUqaeZW=&zByCfFVsjflXq=&ZOAEQPWqZslha=&4VZjpWZfrWsqb=&jZWKRSZVrXZkr=&PYchpgUlecqdg=&BmGxSCUXWs_gm=&Cfiyt4Whi_dbr=&nd8pk5WXabf_m=&qlcd_yZmpVaiq=&mAP8xuVqqiseX=&BAd4EOWqghfgo=&_DjUFDVqqkfcZ=&prAJ9MVqliVlg=&SkGNp9Wn_rool=&PHHEhKXjmcmbo=&gDzTS9Wf_Ulaq=&e4yndkWcaolZm=&wvW3lVXcnsVqj=&Sj5yRBXkmmkkX=&VtoUGZYdZWcUk=&Qwdj6CUYsqjkV=&BxRNhJVmYddgs=&R74GVaXWZaXbm=&B2RrU7YUqUlVV=&fNiCqSVihgprr=&8rCqBEVXZWisn=&bbbPErZVVigmj=&GJ2vcwUnaYqdY=&kNEqFZXnpWm_l=&bu8MdrXpoVVXq=&rKRoNlXkhriac=&ERR6s9UjgYUUX=&W7zsrgXUk_skq=&RO2Pl4YosmVja=&AYzjmtVd_g_XX=&jcsYYbYmegUor=&Jiqm_gZmlZYdi=&Fwnq9AYZUmnab=&OO3BzpUghjYnh=&jlvIDvVacWZbh=&KDzmI7Vlcgiaf=&Itz4HrXrXkgjY=&ZIoCt4YsUhVdX=&PgfeY6ZXklhnr=&eLpPv7Vfnfgps=&yHRPL5Vqfdbel=&QIJeUFZdhnlWY=&sAe9EIUYrrnbX=&M9rxeRXrWbWls=&9pwr5ZUmorWj_=&DPNVJeXrjmcUX=&FsD5zKYhpXZag=&cGksb7WWmpfqi=&IKy7q4UohhlmX=&pRyKfyYbmjnqj=&gDjPhlXoYmWZo=&H_QolSXYlehqY=&foRY3YZodqZg_=&makB6eYaamqmd=&peB_d9VnrcVcW=&VdaFJuUnj_gba=&pzj3FQUeVpgrm=&Put3ypUilciYp=&biIhPEVkhkjhk=&sB7FK9Vmbnrne=&5SY66mZjlnXY_=&uTWzjTXsaYmfr=&jQcPn5Weaifns=&ufs9JIUWpgmWs=&Gf_UX6VpllZiV=&JiXJhXYpkXpp_=&iPtzj9VUnmiYd=&u4N5xbU_op_nd=&p2eM_KVfh_UUW=&xdRcEUWVpXjlp=&9IMmQfWZhjqeX=&ddeFfoYqpcber=&TFKnWyVsbsdid=&H9ia9cZsrjhlb=&nhlDQbYYfWqmj=&kEY6iKWiVZcio=&yn4qMtU_dhnYl=&CquaFSUrnjp_i=&Jn66JUVdsljag=&2WHHTHUsblieW=&xLqydUUnajmlh=&7KCoLNXocabhW=&MU2fOCZnWgqZW=&25WaZKYgnkbbc=&j7GKw9Wekrbrr=&uJLIZTWhoYleZ=&EdSuL3Ycqpqmg=&3bTgFqYXisYri=&pAFBYQWYWWkka=&MIlQBLXgfonkZ=&zPwGfCWjXmimi=&lGPN_yYqVdYqk=&E2GkrCWZcf_VY=&zs9PlxYmqnnWp=&OSZphsXWUpYjj=&bLm2DbYobUnWY=&mogWvfVcdZkcW=&8RpywqYUpsrUY=&4D2HfcVflenrj=&e3pw3RXbbkfrm=&924N9HVhhkVlg=&Xb2uhlUhjai_k=&ucBY2sYdeXj_s=&Q75mZBYlonscb=&JiCOTEXhWm_if=&DfpshGWcVpZnX=&U_mJhDYiljZdU=&tOtvRwWiorshf=&nRRRvVXdXnq_n=&f2s8QAXafhsXk=&cfdNNpVgpoVps=&Z85eedUZfVgdY=&KrDhVrX__a_bm=&ODQj4hXUjrVkV=&UdIsDpXUjchkX=&6Idsz9XZhdodn=&8z9UESZ_gneer=&QeAPLEUqZprUk=&aOHSvUZlgfrXi=&vQYAw_VVfVphm=&aOJvQ9WUsZVlW=&cnKVhPYcmasbe=&WtJpSRZWXbeXV=&WR2z9OXjZnZnm=&DaEripVrkhpqe=&hTfbpeXfoVjln=&GZxTOcZanheXq=&M3GWazWmpZXbs=&PbkoSEUjqijsX=&dR7BMxYhmoqYW=&xBQiZDZUrZfps=&I4wUZwWglbeef=&8_lfv5Xsldbep=&fbzu8ZVe_cXUc=&UzBrQgUelcjmo=&ibV3xdVeYZpmi=&n2RhJLVXfVrqg=&5Pr_HwUgZehrX=&JuPxpTVqkUmgp=&BEJC3OXcfklmc=&pWk9HwV_Wocpl=&69thyvZgaYknV=&qAVJrhXie_Wdl=&fm2bkCXnWnaaV=&nJUgYNVVppoXf=&uORgo9ZZmZaWV=&MzUIxIVWid_ir=&TJ8JXtZebVmsc=&Pmr4E2YZcXrWa=&Re7VjkWioVfkk=&YNiIPzUWimcUq=&geps9QUbjUciq=&LVSSjAZpVXUca=&zLHvWyYeb_bWZ=&uvNEoeXrbaYoW=&PZgP2AUYfZbse=&Buy7qMVapglli=&SfjFDUUhlXXno=&A4FwVkZrq_njU=&IN9EjYYmlgjgf=&7u65ZMXfn_opj=&mEa3H4VhniicW=&8ehLlxVoplWmb=&y5KGq5ZmlsoXY=&3pVqSkXVe_UlY=&thMH7wUWebsla=&nNl8HMXsdZ_eb=&pHmTQRWpkrljX=&uggngkXpZpcdf=&Kzbi3AZmsppUs=&fbuiNKUWqnmVo=&ICqkEpWoUpkhi=&rABgRPZXcjlns=&Q3Tla3ZYafaoX=&Yg3evRUohelbc=&TtKP6VYjbXpqg=&3IqjRkVkhhbrg=&Lxh7mFYdehjZl=&4gOZj2XocksZf=&LxgsH5Wnj__am=&SUB8W8UYd_eiV=&hGt4RrYl_l_ke=&5gvLetXZ_mbfe=&C4NRgAVWV_kfn=&dYrNpnXk_fWdp=&68YDMzZ_anl_Y=&JuzU3jXkidYs_=&nhyCILXqhVion=&PtZvSSUhmmfip=&PvfR7FYeghlso=&OLhH4kVYXgVnX=&Yo8B_6UefWWlg=&QHHZhwYfUhrUU=&htdp7zU_nfkbn=&Ex7dRiWYmm_fZ=&dlmnq5ZbWUhej=&fw3569Wpsfeof=&2YqzLYVeqgheY=&ZbRlJYVgadiZp=&Wh99DIZamajUV=&wvS_p9WcbVefo=&cexNjRX_WWlUj=&HWsKfZZ_jshZU=&8WgsouXYpkoVn=&R9ytL4WjVhfeh=&Fbn_zmZiXlfVm=&o7WdvLWmWgVsh=&AtgAGGYfXoZWh=&bbaTLqUlcfXrf=&jz9dvkUbZhr_r=&DFCfmZWYYheog=&Xwh9HBYcg_gZY=&iYZaCWVhXbgsm=&XM8O5XZlXenlf=&XqCukGZZbVlhq=&pKexQEUadWrpY=&9Uq5GGYiXlsfq=&cmNypqXnZXWfs=&5mXyhcZeeabeX=&VDWLrWVXepihn=&4I3KzzXrXsgsh=&gUoo3BWfomWXe=&QvnjghYYYUrrX=&FyMvxuXWWffVq=&lhQuB2YUhj_gp=&EA72i_WiXscrc=&87CZ8PV_doebY=&X8hGeZYcdamiq=&o9IdlmZXgsckr=&OVl82HVY_nVba=&twtAEIZbWWrim=&DZTugzZc_fVhf=&u4orE3V_qgarZ=&258eEVYZhjfia=&hNYgCkVhehWVj=&T8qLfjWlphiYZ=&m5G5cCVd_gebc=&DwMYdtZprlrah=&v6FpKNWrjnbmq=&KlfLkvUYXhZpV=&_Oya9BVYZ_eXV=&oJqvyJXlmZbkU=&OqgVgTUiqqpjf=&sD4opxYefWbhq=&9yearKVig_Uin=&yDAiU5VhandoW=&ysRnQeUdgrmeV=&hsKyyuYYkjjqU=&NyWhlfXjVsanl=&CV8H_KUemhXZV=&NpjLQCWgoW_aj=&ZctCd3YpcfUjp=&KRkohYYpXgngU=&OfXYHGWkZUYbi=&t9AnUdW__fdY_=&I9fojzYlZcriV=&OY9PE4UWgbUUg=&kp4iM3ZYdbUeg=&8OOl6AXXjrsbp=&7kU6DmXqlqogn=&cDTwsfZhkosZj=&I_WsccZdUkVbX=&5kVrOTWronjef=&g7Z5aLVbZpagX=&jcg4ykUbimrYj=&U5ffYaWarcUmU=&QNocJJUgfXVqj=&aoSVNRVjokdje=&oCqWhyVijohcX=&CSxKhCZfdWVab=&hqW3A7VgZiaYm=&z5QnIVVhhZoXl=&ipqAg2YinVgcp=&imzknqUghqadp=&OwowbaWXeoagZ=&IYQLVYWqpqbbc=&nKCSWhVjjkmXX=&MlKjXbVlUjrfa=&KopdBSZiYbqYc=&WApscbYYedVWf=&HuinLfXqbonca=&YvhtcWWkbYisl=&Vw6I_bVbXspfn=&9f4wXxZpoqpWi=&jHihZRVVgkkmU=&59aoSdXkiZXlU=&gAnuvLZcY_qkZ=&I3hJnZYkVafmV=&z5RSOlUfkssXq=&fLjjdDZqchlgW=&BkVkwUWrYjpWi=&p_s8JvWn_nUkV=&kqtk_JUjdcgcr=&vveXpQYasZrmX=&6Evv54WXh_YnU=&4B4S2SVhZdabe=&xHRkRNYfjrbWi=&ThxpKZYVaWfpr=&EypCzCUUqfg_W=&q5ixMHWnoebna=&nLq733XX_pmpr=&ZIS9oUVkqhg_Y=&zcJ7oUYaWcfbf=&nUXztZWbrcjfa=&VutvxHWVheXkZ=&hYfIEjVfUgVon=&Bsq_TdVbn_YjW=&UfFVbvZiqdmko=&Lzt7gkVjmWmss=&vdpGQEZ__YbXh=&634FNkVmlbehV=&vnYKdiXhasjpq=&CRs39LWjn_jnd=&EXUN6LYecdckq=&AymR4SVVUekje=&XXmLsCWcUdrXj=&wmM7OPVVoleYl=&wmjDcTXgWsWra=&IlL6PsYZZjoUa=&cRRoOtXbficeZ=&XnKNXZUWcsfno=&pSoEmdY_gpngr=&5yM2UUWsfij_W=&7VIA7wVqerUhl=&p5jgpvZqZnpkh=&_Zmb4fZpekYrq=&dloDoAVfibbWg=&sNLcgHXrmbaoj=&IJV6GbUohpobk=&cuo986XpVXpjh=&uNhaBUXephdoo=&Zz79TtVXfbfbV=&_mGGj9Wadmiop=&uacno6UpY_clb=&HfJ4XTYmhZrpb=&2wxsscVoYXUhU=&gGH_hsVfkkjce=&HedE5OYkclrrm=&UKrhBjWsqiYcl=&rGExsQVpgkaZW=&zx6BY3YgcriZl=&KKgZYiXllpmai=&gPQGPOVXcqokd=&nN8uqjVijeVck=&CzhkzWVUVdeVo=&S32EL4YfseZXr=&OyqGHFYsmecgn=&SveGAIZokrmsi=&5_NS7EUrYgXfp=&HxNRmQWignVsh=&TobAPYXmWebki=&3Ux2UZWehZbf_=&m4Oxc4YVlebWf=&hRyY8IZcmdpjo=&2IhXvWYiopZha=&GB3MIsXWVrolq=&dV3JQtYVgnhln=&Ph4we9XjlghhV=&AaNioeWh_Zbj_=&cRvFWaYjrUWqq=&abKqqHWUlVcro=&ibgREDVmZWYaY=&BOfYmeWsoaVfp=&VPUvFWWXjodmU=&ChsQCCZcgaXnV=&_yY7sxUlkpfjW=&OUuKbVWUqjWhr=&KFBlJgXkipsad=&oIMusKXkeafYV=&7L5MEPWpaW_ac=&LxeaotXkp_ioo=&8EwAyeVcXjYVY=&u5MMcyWilpWXg=&Er_pylUdlpeib=&Tr6fgYXZUbhjk=&xINTizYqVZfaY=&gq9Ot6YYgjlcV=&KAi_b7ZqZUinr=&SUitbKUVkoVdc=&qKd4qRXrUbigj=&YTJVEfYg_dXda=&FV489HUif_ahq=&iX5IYdXk_jgZY=&dCijgfVriqZor=&TgloR4Zhljekd=&GdAZ9IVnUpc_o=&YBQ2QpXjej_kf=&juqzTbUWkXaWa=&RmucDRYnqlWdn=&Pe6YaNUfZodrs=&vOTGYcZolpopj=&vrJkWAWmjefeq=&moTKizVVlro_Z=&m_T6qDYqgmanl=&fi7QNPXg_rspX=&MiWTrKXfoUeid=&2WIJTVUYmafcW=&YZPwQ3WgUieps=&D3Sli7WarfqUr=&sGJBJuZpkerUd=&ZJt5fUUmoZkse=&pZdAXuUmpjpoo=&RgZnTyVbZegia=&h59Ec2XgVkYWd=&dbl83KWcrsYcs=&RGlzOMUariUir=&C5OcPVZkq_rqd=&N9qn87YrkrWcm=&iz45o8Weqmika=&H3fzu9WqZnkee=&Nes9HKXemkqoc=&PGCY_NWsVbcmh=&DrJ46wYWrcUZg=&sXH6wAVkpclsf=&ADhbPqZXcfdqf=&iyDOqqUknkUWj=&bf8uW3UosZYcb=&Bf9YytZYfbrdf=&ch66yTVorZjgX=&sptd3xZpghWlX=&63KHOgUhdcjXl=&xc9he7YZlebsq=&s4aQCIYpUpUiW=&pNJYc3ZghVf_k=&cxKWovZmdgf_q=&uYDeSTUabmoks=&HzZE98Zjilcms=&VYaGkTXspZcVd=&Q6Dw2zZloYWrq=&Ku7bRwUnrVYVn=&g5pqtpX_nnbmW=&PTZlsQYbZZm_i=&HZW_azUgoYmmi=&jRmWE9Zarhbje=&AtQkuHWrfcdsa=&Q_F5gKUkpbpdW=&crcouiVecXXaV=&jr6mpBWpfVgmZ=&xjdY28UbgiVee=&lQo_Z9Vfs_spg=&9fCkbXZdonVXp=&WEd6KPUh_qbln=&FwZkkeXYjqkdW=&Zyp3ikVfdlVVV=&OSKLq8WXodl_o=&x_DEIpU_sodlW=&WwdBAyVgdrslh=&PZNzjlWrfmVsq=&UZ8eHcZcgZpl_=&kkN_vpZd_badU=&lA2Q5aYWeZ_lZ=&ljBkasXbYUZZY=&_PbLwLXZZaZWp=&4XTMYoYVigfac=&K7CNNJXcmlfqb=&33zOuzUqjYXZa=&SG9IVQY_jYhci=&lxKqFuUkqUkak=&sK5jzrWjpYjXi=&6v5W2pXg_VhWo=&fuOiZlZoaWZkq=&QaEC8GUlmsphl=&acBs5nZVkkkof=&DK9vveZhbiraq=&bSiJLFYfn_sVg=&BiEqASYbcknjl=&NVhda8XlmbslW=&9LUKdhVhcZsb_=&6BUL58UoaohVV=&yXd4dkVkWdfUa=&heAU9qUiioU_g=&YYZNI9ZZecUip=&GiUWMRZplgsop=&inib8rWXpjifj=&iKdgVdYeWobcr=&GuGhTxVchlhka=&UNwzIiXoceZbW=&Kvtv22UelZic_=&DxeUGOYYhqbZg=&itdfGiVeZdbkk=&oUxNaYVkrqXlV=&NERCocYqlUisa=&5cWXRHVVUcodb=&TZ6ViLXiqfbX_=&bCeTcOZshZbXW=&TatxmJWgqgrso=&s9TEojYnYjlms=&878JUQXgXmVaV=&Jo5SUEVdsspfq=&UaleM4YXmlsn_=&I7spO2Vnrckkq=&_6cQBFVVVciel=&5ry5yFWrfVhhk=&zvgHBvYbogZeW=&zpkxJoZjbhsin=&zVdtZ3Ycpqffj=&ns_JmyXqnsWXU=&kToEo_Vqbhqrk=&SvLAhuZU_Yjis=&osxfcdYeYsWso=&w7gk8_VhUjpUq=&5tnjPAZfZhhnf=&3ctdpVXaccnZU=&uLTpojWfWslls=&hXkbbBUXZgasc=&fWVnfeUlmjlis=&g4onUmVhkbqcY=&zQGokDYjecXYb=&A3vAUlZWZqpas=&Gnan9HXm_aVpn=&UrncFJVUskghh=&DZBaT3Wagpcsq=&MvMkX3UWVoUik=&dfOYSNYqoUlre=&_aw_gcXeqbYdi=&2zeD36WdjXfle=&rSrgbfVrgpeeY=&jWIdThXgcfiVU=&VgJCxTU_dUlfU=&FtftbaYpbpUkp=&CC32gJVkekies=&UIBmyCXofVsne=&aIbi6gYqlboWp=&jsGxkxUmsYXX_=&7dQls_V_phkqU=&F_Z28KYXpiokr=&pnQtIEZaXheoX=&5rbVNSZbsgXma=&O7WgrRVsWVZfZ=&s29CMWVVkropU=&3cRAdFVeohhfa=&IdfHlwYidpfld=&gERnVRZZi_sna=&4ZIWw4UrnaYWY=&PMQE3FUdm_hpg=&zrDrB_XYfZ_ob=&o3m7wEUdYUUbn=&amxdYRZhaVkad=&QEu44PZYZfkpY=&TTYpdeWehiU_k=&KK2D4mVrecnVg=&jnLi8JYcpkcp_=&KpsyMzUlfmcbo=&6Om8fGWYoVjge=&SiI67TWXi_ccq=&LsSCyPYV_jrfd=&QummBxWgsbVYV=&_cS4tWYledqad=&5pulF2ZiUXfos=&6Tg_GzYU_kohd=&TJhSFdWjZfpmU=&rsXHzIYqVUZpg=&6tF4xoZjgsYoo=&fHrCk7UhUlYXb=&EN563nX_kgaWX=&ioGfRPZ_mpejj=&k77bCQVgbYfij=&_ISNyaUUXkbld=&VV5ZjJUVsf_sg=&yXlja9Urkbepn=&M9osNLUanWlUf=&Z_uUiYZXcmUfh=&ovBYreWkdYYpk=&_w7hYDVqYVWfU=&EjFp8qWbcaXdW=&slBJJKUnYprqk=&tPoIyYYhgoUfX=&mJyhyPYbWUkVo=&bnC8wUWVX_drm=&FUq5I5YnZnZgo=&H8RqqTYsngeUo=&mLXVTeUhindZV=&AHIQTCWghnWof=&sBpH_7Wggdmmf=&4CqFYCUiabdoh=&I8fMcmXmkjYYn=&38WFNqVWmfimo=&PjLqY6XWoekbb=&vJvcBCZjXkrdq=&ZevYNHYqU_Zcm=&XTN7gnZminYaf=&AQH2pbXWZYaor=&DtlBYyWlaf_Up=&hxbiR6XhfekZs=&2u2EvyVojiYWi=&ft5wZZVconbYm=&zU5ngLViesYql=&BXdX4_YbUXcjb=&NPN28NWrmehhi=&dUYXbhWWdmiWg=&xbfcv7XYZYsp_=&oLj4RCZmjr_gU=&Y72JlJUUhsmZf=&Szl3QcVaZjcXj=&AxONCpZXWgoso=&Z9gldYVaaXnho=&bptLbGXUU_lZZ=&nzJWrAZslnnjY=&rwaq8PYbq__qp=&ic8JndWmdiXgf=&PeZYQ9YijjXlZ=&WlhDRZZgpWaoU=&8cHOC4WgXUejo=&DVXqDfZbqmgmq=&wDAkD8YbrXYgb=&FAKulVYiesefh=&_ZfNFyVYkaXXi=&_b84UqUgYq_ZZ=&2fhCdYXhUjglh=&G7R5AdWjbcrWi=&iB9tEUXgZih_s=&TMnZlSUpkUedj=&mAUt8EXmYhamj=&pejxLAYaqjgUa=&nu_NhmXaVgrsp=&QVg4KMWoaVojV=&lMG7hvYrVdqkZ=&ChrpDzVYUebqU=&KyrCD6Xpclr_Y=&9p9YfxWfallhY=&LnMCY_Yc_nhYb=&dcuuixWbiWhUn=&x4DqiwUUlUo_j=&HnhZuOV_Uiibb=&cO3wqbXq_psYk=&gGwgcYXpZidnq=&8W8sl9U_qZgcp=&kR6IFqVXspkdW=&AEwxjbVhesWnn=&4WIyoaVVjYVaY=&jPipwYXassjoW=&n6XEPEVoipbhj=&TxesgVYgajpjl=&vVWYjEVsYYsmn=&hE4SFhX_mcreh=&ro64JHUrqVoY_=&Zo8H_cZlsfoYr=&ZKT3rRYcciYYZ=&BLRir_WroddYm=&ocusxfXmXincU=&veOPxeZ_jhfsg=&jgRGPRYfjqXbl=&gcehC7Xpihaeh=&AUXqR4Uhlmdkd=&MgSlz4YccpqmZ=&HYlrzsZipUcgb=&v8H_JiVXsipic=&cCNfLSUshY_ir=&WczvLwYh_prsn=&N9O_2eYca_bWe=&jfNUilYaoXWoi=&UTTaMWXrbWVpY=&C9iFbmYYo_kYV=&cL4KggU_Vnekb=&C8sJ3hWbohdoj=&LuAH3OWVY_Wqe=&GacCzkUrWiger=&RSVt9WYdhV_Xi=&kLqO_9WsgngWf=&pIhk7nVWlseUe=&rjKWy4XVmUr_l=&jz5bHTVbhkbqa=&f9UMjZV_nreb_=&kwm5Q5UqsqdmU=&mTgvKlYobWmp_=&WSn7RhUjlWqsW=&T9o9gnXWXpqWm=&9hTBsQVddojUY=&qDvO3nVhdjcbX=&XSkHqeYnpWodW=&Q4Cqw2XqqrYls=&DFz5HDWksrdkm=&3lO36EUsVoncr=&wgVhDSWkVqsX_=&VJRGLeZXegjfX=&artl4hVUUfnha=&BYGEZMUobmZ_l=&kXv7G4UoqbiWn=&HZnVU4X_jqnl_=&Fu6Ay6X_jYjjg=&BDyfhCZkqjXWm=&LClgNEXhqpgal=&PR5YdhYkrVmUb=&P55SRlVnlqgjW=&etuzqHUiZanm_=&4T7NZRZXodahc=&oZVattY_UqjqY=&lL8mbAZrUYrbZ=&vlPbTJYf_rbrh=&yZgTE_YVdmXsc=&Zc3omuYVWmpeo=&mlAyf3UVmZYVi=&nE6dKQZgVVVie=&cCAC9nVUmZsak=&oLIKOXXZrngsl=&Mwhq4TUWWrdio=&TNabxEXqprcWq=&AttwP_Y_pphpm=&dvErAAZmkrnaf=&nNbWE3Vingooi=&9OX_zdVbjUs_d=&lqlmNMWnjjceX=&D7d5u4VZbWVjj=&rhBJPlVkWiko_=&EyVW9rWsiWeZg=&SMxd2dWZkWhVo=&pnew9NZsWXsjp=&5So9MUYejgqik=&FmxXzKWaebWWY=&whwUl_WWkredb=&fnuSobVUUgb_a=&Cgqj2UUVarerY=&SIBFROWpXpore=&PZA2u4ZrdkmsY=&lCeBvqVbbYUja=&gvEqHwVpibZgd=&7iOoNMUmaqXZU=&Dhkz59Y_Wjjgg=&M35zZEVUdrc_Y=&cziw35V_jhXcs=&2vAyPiWcfrsZn=&nRMBr6Urlckii=&6zfvCeUlnf_bb=&WedIRgXYbc_fk=&tPq39SVa_kioo=&D5dihyVUp_bUb=&gQScgVUlcVmbb=&LH84cEVjflnmm=&u9jwkIVgfkkfZ=&I8CT4hXbkeehU=&LLgPe2XeVjcdr=&xSwItGX_XaiVW=&gxLDdJVZgkeco=&VdbhNlW_XYUWW=&SIqeM9WaraVob=&xGKhsyVjYblmj=&oJwxRjYlcXVkk=&8zVrJXXWpjmcU=&5BgAViZdrqnp_=&FBnVSfZendWfa=&9ZOqb6Wojjmhd=&oiQYIAWnfbgbb=&xG3HPSWfqfcjl=&WUS4fHZWqpldo=&66D36xXejm_Uq=&C4nRZUYr_pVfd=&Yp5TTYXrgmoY_=&lPDdZwWXcepes=&qtSvpkYcceoaY=&Y2F6ySWVqVhle=&3j9EhwXVnogbf=&JH2QPDWYWUbqZ=&fg5IR3ZWgcago=&u5byKdXkp_sha=&vaY9bWXloZoeo=&HRB__VVirmZeq=&Y6hCqwZfiiehg=&awI4MyZbrdqaq=&uVRjw9VlmhbVZ=&2XbGsRYmsfYcU=&Z_mN8oYWZoYsd=&UxMc7BZhUiUbm=&WCTPYxVilcaoY=&hxDXcMVZ_Xehh=&mBl7WmVqgcX_n=&iDMF4_XenjncW=&OtV6vpWVdjXpV=&JpY6ysWb_pqpr=&9iabCxUljWefe=&BcvS3iVrqrbbk=&AksJcEZsmcWeZ=&I_UIIzUdVibZo=&RlLXYLXXjYejg=&XrwzPwZkiasfZ=&bSzXkeZhmWj_p=&VrmT3fXrqUZrf=&xYleluUlUZh_p=&pMTx3dXasgemq=&f4DEo_YrpkXsh=&K7sYKsVrlUjiX=&cN44pHVfZrirn=&38k6xMUjfsose=&vciAIZZVYfqnV=&QYEkUlWUrYbbd=&KMBVioVkVbnaj=&tUX3BoUdjnWnm=&NTAZaeXpgncng=&YgyDzLU_pgfkk=&gTp9GvXsrVUXa=&tlYZSNUmZYYam=&irIjlnXpchege=&OQzTHSVepWngp=&FjuAxNZqWpfbl=&xMLJp2XjYdpgc=&2tfexGXjnsUeq=&7ClGelXbZekWi=&GbFCvIZegfirX=&GYGvg2ZlUjkkm=&7lZRL6YVpqibh=&xwWJwAYiU_acr=&lSQ_RsXqrkgql=&YS3oNMWWmZsnW=&TKU6bZUbaXpnl=&hbsTJTYrdfbXp=&R9k5wHXoWllkg=&bT4aStU_sZbqZ=&jDQkvKZXhVgfn=&cBeIY9Wijbbkp=&bWy2VFXVbcUdf=&kpKyfhWWphinl=&RB75IrVlrijbV=&U3XhNaZhkeZdm=&wFAjb5XZaZoar=&fl2EoMZaadjn_=&jv7ntaZVlpjmm=&n2HuDLUfblWVm=&Rkb5H6ZWhV_bb=&Qfv8CHVXaickh=&A3fX2RVXWdppm=&kHr9o6Z_UafYi=&ByWmt6UWU_adX=&5OeDDUWoeVcmW=&BKSUgLZqsXlic=&mNSNbuUVnmjVU=&eUe2tOWasUkcV=&exOq_CUlilYma=&HcBkOkUhckqdh=&zIZZA8VqUmeWe=&X73anTUqg_oeW=&eS3mnWWl_dnaX=&RaVfoDVcgkhri=&3oOQWzYZgoeqp=&2JZxYrVo_bmog=&fisU3eZekWcns=&RZgRVjXkkigcn=&_E7cLnUlZlbUj=&NSr4rIUenhY_h=&4CjmJQYnlppkg=&cNi9nXVpfXpoj=&XmEYlEYkiaVo_=&kqzJ79Zo_cXsf=&xxSC2QVrraXVr=&6YqZntW_XmfrU=&YdCGCIXloZfiq=&_bpjsYVolcUYq=&BWF3wOVpVfij_=&qBgl53ZrglYas=&my2PduYWrrqUW=&wRk6iXZrmZehW=&QBWyKUVsVasdp=&MgjGigYohqZZn=&n4szyfUYaX_Yi=&22ScHJVaiblgk=&k48Vy6Yjdc_jY=&sDdUVfUqnnadk=&K5mVSyXhbZeqg=&xBQtG9YpgkeVe=&QXRRumXpo_dmj=&9ExHJ3Wsiek_k=&QTyRv9Xjhpfcp=&kInCZ8ZnlcVcc=&yJCIB5Wfplkgk=&tpwFgDUklkjVc=&6uBrF9ZkZ_pjl=&mWFYaoXrsosW_=&ri7_jIXsrmqli=&TGVKAtZfiscks=&hGdkFIVpkkZ_b=&3WGFCTXfjfqrY=&R8jq7MZl_YWZl=&T3w22oUhkXZYp=&ceXIGdUZeZaor=&CmcdNBZlffcai=&sdwx3WUincmZf=&ZTeR_6Wibgcam=&ra8fCEYqbgYgd=&Uv9GEqVpjenea=&iRzbZaWpscmYg=&LVuabGV_iikpc=<5KI3Zfbdsif=&mmnJ8cXsckfUs=&LrYykTVgmbXsj=&Y3Qt4NXsslpla=&gVfveVYlcoWqc=&uhxttsVoasjV_=&5lhhOHWelmmXd=&YPYS4kUXirjjn=&FGIRAeZhaoXXd=&pobSQhYXi_Zpl=&RI3ol4UXehsjr=&yeeIruUob__rW=&vkcd3AXlioakb=&OOAbQhWXjhhnW=&uqddYVWUi_scW=&NlIDWrYesWkre=&Our7iLVaiih_j=&mOXPSMUaiYXWi=&fA3QMdXfZlXXj=&eRtOnUVXrVUpj=&TfR_f6ZleVsZs=&UP5PCTZmiZomc=&9YraxUVUmYlns=&PmDjMDUkgXdsj=&3byzJZZpfaXob=&H4slB6Zbjmqbo=&2CttU9XfWYbnk=&2WPNUmVXkkock=&UupuyvVpkkXZX=&fVurBlVjji_ch=&45U7B5ZghpqUi=&G228TTYffbfVd=&iRcITHWZpnkpc=&zqhCiaUqphhUe=>knglWahpkZp=&XBfTjXVbcanZV=&Y43p97WaocfmU=&BYktElYjn_qXj=&oITZ6cZXXqYrW=&B7yZzuVeVgVeZ=&OCD9sPZqkrWpW=&NBg7o5YpjmYgl=&yVBeh8Xq_nUsp=&Lf4eWhXjlhUp_=&mA8Uv4ZppfVon=&Sued3wUVhfepi=&WedTfnXe_segc=&rjn82UWoWfYYf=&AAqk6yUiaVUlW=&SWASzEVZXlnpU=&P2bQk9WVUVeUi=&X6Jc5oYmlgroW=&dncGW8YdrobhW=&mmHC48VmaheVh=&KUVo9KUYrWcZo=&oDcDjAZgUWmmV=&WCQQotYqfimkd=&8Axjm3YhZWkUq=&mjYoyoVcjrohq=&jNZdFtVllpYaX=&YlRHGdWoWseap=&KclOuVUin_arl=&z8Mp3RYsebdmZ=&y8CqZcVhirg_c=&T8UgGoUWlnmXg=&56tawqZVkUqh_=&_QS8cdV_kg_Zr=&aZGqJcWsdqrhU=&OEljgBXkroZon=&Xkp3l5Xm_Xrpe=&TUN3KHVjYrbrZ=&dsjhNaXoemeeY=&WcapacZjZnokW=&vO6fS_ZjdrUZr=&FftCXaYVhbZds=&Cqegp7Xraeogg=&h7paKOUdkrrnp=&fSTk6VZllncbq=&vYkoA2ZfYYUir=&pgIlQbZofdVik=&goT3R8XqrYapV=&DrMMPWUnlpieh=&z7KsYjWsVUUrh=&oSR3VpVffgrZr=&mUh2YwXbZfcnk=&gXyXzGWVfoYfl=&jyslOKVfbdWUn=&AkIlNPYcYgiog=&AHeR8zUremrhk=&l3IlQ5XjUXjbU=&tgkbmNZfdpjXk=&OjdLOMVnikZWr=&G9LQDkX__mdir=&DVCoMAZWdVmkY=&DxpCDyVghslci=&MJUyG8ZeYZqnU=&RSSyvYXjeYiab=&HgL3vAUargqWr=&RNoXqHYaq_fqW=&VDeKRpWWhhrpj=&uy4dJ5Unrdhrn=&4FGqfzWpXckbe=&NdUtMfZXk_dWm=&Gqh_FHVrmZjrn=&sRuQATZiYooYW=&eX7WrIWZcinsr=&DMlsn8UrcoZps=&CcBw8ZWjcodXd=&d5D9DNUepkjgr=&g6bkP3UhqggbY=&7PQzvgWggVndb=&zMpMOGX_ZphXo=&Od3asTVgXrlqn=&nTZCPfYVhZZZn=&tPOhgQXZmoocq=&SPQwE8XjfYrad=&z9RFxPYqphWjh=&UC3DbbWlWsqng=&R4ufkUZVlUZpr=&ZYtxojZVshWYk=&4Ti3GAXXmoYgn=&j45iyzYcbZ_qm=&vFQzgBYWbgWUo=&TDAkKpXhhVZro=&L9gtB4VrjXcer=&XJV7N8ZsdsmVh=&P98jtzUqrmb_o=&DdMoCGUncsd_d=&GnJ5tpZfaUqXo=&_gZrDYWsgdnUo=&HxpO28YhXclZW=&zfOCmDWdZihrW=&odTwTrUeYjrWV=&KAb9kYWhj_qdn=&_zyZqlZeonZfg=&k6YS9hVkfdleZ=&hQbWBkYYqYVna=&F3rLh5WfqmjiX=&zw5NHFVZsfYVb=&khCLBgWebcsWX=&lgL4pvWkUkhfk=&c7XPziUnro_kW=&z9RRGaZWafYVr=&kvWFqAVqWsaYs=&Jz3NuDXnblVec=&KXslyJV_iWhii=&QmLSD9Zlcmrhd=&eNtJkWZWfbkWj=&yEgxvVVpYlcUV=&OnHAx5UYnlqff=&_K8AkhVehWboW=&pL5Ew9Wakiabq=&akEtWkXVhiYZg=&JlKQ3_XZjiqjh=&zhyWcgWfikYUW=&WDLKOxWfhcllY=&w5sTftZmnfcbq=&vINXhhYfclYUi=&ApNyloWbchknj=&Gs2LoIXejbmZl=&DHQTGaWnaeegX=&T4zOxgVpZaWhp=&SpM8DIYdUkYkZ=&MEOtsLYgrffbn=&At9MOXXbpZpao=&GaKnAFUjsglVo=&Ia9a7HUihnfkj=&AcnmXNXbWnhmW=&a3PC3zWXhlmmk=&vlUKVsZkssYlg=&CXbt5MZfhmVrf=&ARBPc8UZm__ms=&xDu4hUWrcYaqs=&9LiPcjXaWbhX_=&zEDFgBVgZnkso=&OUr2foWjpqbql=&CSllpkXlZnakW=&9mifb4Znssnmp=&Y6woEOUlZmXoZ=&acCSQUYdUrebU=&ieo_MxW_oVmYl=&S9_KNEXqkbieo=&LChtErXUsedeZ=&zZQQQIWhVlldq=&dQ4bcyZWefgqs=&Zr9FhKYhaqbpo=&Ilwuw7WaUeosY=&fVVm6bZhWeiWW=&8cLB8KXYgfs_Z=&ft_q2sXUokdcs=&lhxFkqX_Xabkc=&OOhBQXXmdmhWh=&jaeoyUYfZoYUU=&SfnnZoVidlXpU=&TlyZGqUeinsfe=&CHYyCIWrcbYkq=&r2REAlZccrprr=&8DJjwAUjpVoYU=&zLujTJYreseib=&4UO84yVZsancp=&atRXDQZZqjc_U=&ctARoSZ_scsoq=&oYJmEhWh_gUXf=&u8HknpUXdqfs_=&UbqJRJYY_WcWd=&mkkvCEWYfhUZn=&Ultb3DVbf_lZc=&Uf3MixYfpdZhc=&X2l8OoVdiljoV=&v3uCdcVcqWqms=&BNmW3FXZgZZrp=&gGumQNZcYe_lq=&JYzG88VllmbYd=&H26otDUmYolbq=&MFFyERWossgdh=&wtAa7UXmYjYkm=&qSpstjYnslfpm=&NEwU3YZcdpmmj=&Z7tauYWXpcZpr=&Qss2eSZgWZUmq=&kElYPjYnihZqf=&A3IveqVjcr_lU=&ECjcxYXrYWUVk=&4IQ2zXUWlVd_U=&Qs_axQXgfnjcg=&O29_i5Wsskrar=&Ayd5yVYfZeiWf=&srU4DSUlnorkX=&BlNMemWhhjgof=&mFBkKOVUXsYrs=&anf6YwW_bljYV=&IKQM2MXnmlnVp=&MVSQxpYpfVdfb=&nl4oL4YVcVrrk=&tEpocUXqcnih_=&pSoFZJWahldbp=&clRIM6WcVjlaX=&SGz4rcWrjbaVa=&SnjDkLYZhfmkm=&xHWL2dVWifmUW=&SPiGZdWomWki_=&qkzKsYUebkql_=&kZahtDUXUcgmW=&gnQOvdZhjbWWs=&c6ZiErZrZgYZo=&PNsUKjWehqZoe=&5ILlMbXZUU_ek=&l7W4ZOUnnZlfV=&9tFQIMXdsndkr=&eGJfRPVaa__dd=&p_yWo6ZWldqas=&zPlpdPXbibriZ=&NXII4YUplXqVU=&d9DGHqUfXYcnX=&pmwJlnVUrseqX=&C9WXvIZjcXeim=&VaSmtYZqmkVad=&fufNkOWdleiXj=&RlqNZ_Vnknghr=&aFJwaIYkeojek=&uT4PQsZghgsiY=&I8KCwJXYchmkX=&2QLRAXYrqrciV=&IOcFD6XnesZqp=&89hDtoVlYgWXW=&WRspKyYsiYggj=&UbcFCUZUojnbf=&x52hIJXsopqib=&XXva8UZ_UfYqp=&u9xsNbXZbp_Us=&6bSgffWlZeVqU=&CyMrexYsqmj_s=&DP5wRCUYjieZq=&BtThfRWVrdk_q=&SmiVQpXhcbnop=&6R_hhDXhsnpaW=&CgTlmTZnamUrZ=&RmrZMMZf_jabU=&lXVjyOV_lg_mb=&zBeooJZqZopbe=&phvVgEYsVbscf=&hn3fneYiZoVqj=&73R4PkUVbjkiZ=&uDx3xxUjlljXg=&5qkoliXjfXcbZ=&yaJSVlVfrbsgU=&jv5ubaYhVhZmY=&FiBHfeVfmhWsi=&34Lea8VaVUUXX=&kdXh57XcerpjW=&74sSsdXlYde_a=&lQ33KLUqZnmps=&_WtnKXUjjqlnW=&zOsIehWlXocXi=&fHPOeSWkgjsdq=&l4_8A7UVekoYb=&JtsHCVZbsd_ci=&BAz5d5WZehcjr=&CQRBWbUmqhZUm=&_ubIJRYssagss=&Ns9wCbWYjUhXY=&cG9_bcXgdngYp=&scVxlMVsXXplf=&cWaboBYndsopg=&llmevkWZWVrlc=&Cl8djNZefmnof=&fqVvQqZUdXkir=&qywYVsVesiqj_=&VFUnsBYUjmnor=&fRu4jpYWlUnos=&O2kdSIVqXcoWZ=&L2OQD_VlnXgVl=&DwtMhXYsqjnZU=&CnKx5CUeYU_an=&WE2LtxVYpbkVf=&j765DRXooZnmU=&FRcqihXgicemd=&czclyWYcqafUa=&pCVCUXWpckhVl=&5Bi5HDWiblXZm=&8kpyNfVahVrrg=&ywqeVPZiYlehk=&uFaPJzWsplqYj=&w_2xeJYpgUqef=&3Pnn8FUkWkbcp=&b5nfwCWfsXVfU=&mAtCcWVcWmdhX=&K8Z5J6Wps_rfg=&LGXmRuXgnUeom=&HjRUmiZVepphZ=&6xLGuPXiUgXhe=&earAl4YYWjpgW=&nPY9XjXsmdiWn=&mxlX5YUbkli_Y=&uSpJc5XhapZfo=&U6K2NPZYclips=&6_gTTSVajYXpa=&u_rJMyVnYWWho=&h_J5VcWbjVlma=&FjmNAbVUVZ__c=&mMjcnWYXaqrXq=&VyczaLU_ngdom=&R7bNZhZVdqYhq=&c9NwvKUsenVih=&oEKuWsUZomYhh=&3OfVvkXqcqYbk=&GlWGY_YpZVjjh=&4BPT6KYrjqjsj=&aAghTvYWcneWX=&sUrT5QZcViVgg=&G4tGCPXYoaaWp=&OHuxz3ZikailW=&xKTyuyWrohmXU=&PLihWWUYbffkb=&v5BLHOXYopdhp=&LY5lyrZelVZVh=&PZzQCeWlkmaZm=&y82QcGYafskms=&SgelPXWnYjpdY=&Rjn2SCVekWXZc=&NCRtXwWenscaa=&cQARo8ZaZcpXZ=&n3M4apXpVYj_e=&tFVxkCYlhp__a=&b_2Tz2Wbklsdn=&ScnRN3WZaUhVX=&V2H57CXecenjZ=&OJOwYYYYsdjVZ=&QkRCKaXgapZWV=&PDiypLYso_Ycn=&T2rbUzWfjgp_h=&z8URXSZibmaoX=&JR3Qx6U_oeYaf=&SbtvekWonqlkk=&MJXGRnXsmmkeW=&WkCBxBVjYaeXf=&PSDmLmYpklkqe=&5_TPxGUecfars=&EH4tkRZpmmdWm=&gAnGFKZr_UWgp=&eaywwMXfjgmYa=&iLnNoWXfrqXe_=&y69nz3YrY_m_V=&5DZyHVYrYrXYi=&V9WqdDU_micjd=&IzNe6mYcXgr__=&nxesv7Wsfhrgf=&eDBuEfVfXfehn=&NbHWYsZcWdaZf=&tUCP6QXk_mbfh=&WpD3D3Zcrdsmf=&9quupsZbYYW_e=&A8Ef4uWiebWmX=&eEjuK8VVeooXe=&xDp87EWlpacba=&2kR_ObZkfgmnf=&sdWj2qUindiqo=&Jc3keQXopodhq=&IgENNHXnZWefo=&kI2QyzUUsli_g=&lJH3tyUolbXgg=&BWXJH9ZamUarr=&SwrfhgV_ipkka=&fbv9XuVsXVsec=&QbfYftZVVUnZs=&rRAyPLXenhWpn=&f8BNFbYpadpYW=&MfxtIrYrWaim_=&cSlXbbXppdUUb=&COWdaFWYgilhX=&5vWhuLW_WZdeo=&EuPspeYdbaoqn=&giGmihVsbmgkm=&LHtA3MWq_ogii=&qcrYVYWXqhZsg=&2uvMZEWdkgbY_=&YqwqtUXrggoia=&bzX3UoXinreqh=&UPiu5PVnjjdUe=&ZcLAYPXmq_aXi=&OseBbsXXiYqcn=&BGMwRHUohiWad=&2tsSv6WXhihnd=&bZj2ImYjXinqc=&LALnyXZchj_ok=&En7tFvZfrYpl_=&pyFo3uVVdfbes=&UTJIe2XYZrjWk=&9kQNT7YqljU_l=&hWljuPZfglsVV=&9SmuD7WbnqsnX=&gzi6PqWXZgb_f=&HzVQHWXmsbjrb=&vYVejnXqipVqk=&Kol2WwWX_kjqX=&KS3xKKWXbshZk=&q7m9JMYrmffoj=&tLAsiZWsZYgV_=&DXpcFhWaeVhpf=&OLy26dYr_hhog=&izDobDWgWpnVi=&Lb8MzCUsehrro=&xJvPwVUZ_VYck=&CNgf_8UcoXfZh=&h5V3JSUilcrrX=&aVoIeTUbjafaW=&fUPiaiXhpVUmX=&tJZaMpWqUpWaY=&JgGocTZihge_X=&YPvOidZaplooh=&C5M4AHWlWifXs=&8TEXXMYVZWopY=&jzlALcVq_Ykmm=&_yF4cUWhX_jjl=&GWAjS9Ydfgmsk=&gJpfJAYhZkibc=&_xSzbrYrhggmh=&TedBiHVoaUZsn=&2Jc3VuWchbsWk=&i8coFfYaZYkhY=&OGNb6sVakUjq_=&ZHbGcCWjsppmZ=&_lGoFmUdsUdhk=&hNwbs4ZjhjjfZ=&QaXWR_ZqqhYbm=&6MVYBZWfrgmkn=&UVC_32XUhdk_c=&3uYTlWZVjakoY=&Za6fUyYqYolcZ=&t5Y46TWXdiVgk=&G2O9tLYV_UaUn=&CZOzOXY_XXjno=&znKntTUXZs_Xf=&MiQhnQYrojljb=&twppwOUshVooa=&C3IOE_WgqrolX=&HlKiHpWjmkhkX=&Vr795VVfmaaso=&9LtwaoZpdhhXh=&iJRKbuVceglZd=&BZwD2rVhaWUWi=&nFurEsXpXjqaW=&bwrw_WXmnZnon=&Rjx2zAXdpiel_=&a9Dd4yWlsZgmY=&NUS7iYYeqpmUh=&nCKiWAXkhmVUn=&h7TftgZdZUnsX=&ggxydiYpcj_ml=&Kyc3C8Wkbdepn=&na_FoGVcXibck=&pExfyBWXsjjpd=&Vk__KPXaahbUW=&JRbkZwYcoWrW_=&lN5We5ZUdcne_=&Q9A45yWZbgrkZ=&T7zV7kXXXslUq=&dgrzCvZjilpZU=&Ew5zfPZnromXW=&o8LExrYfmhdUo=&NgIOvgUdaVYod=&Bs9kQNUabaiZV=&_S4qybYcqZplc=&BNiLraZUdoaol=&IuO9znX_VZspl=&5OrmUkUhmhgUa=&9Q_rNVUsUfsgp=&TWYaSNYcskpoa=&88jSr9Yljhgk_=&83xWQVWeVYdfl=&UvpTLDZndacfk=&wa7aRRXhZsbWl=&q2lZedVbcfVab=&al8PwrZeYV_ij=&IW_I6KWqWiicm=&YOCL9PWodprXZ=&PDKF9GUYfZibh=&J4RzbWUnhhVei=&zYq2WqYVYXjfl=&B2TUmdUp_rUkf=&BwxZg9VfbUnVn=&bYdWrrVrmZVof=&TyOQLuZpiXVaZ=&7aPo_wYdrngmh=&RMb5EzUcdqUlo=&Y4_3dVXWUrccW=&U_DO98Zcf_noq=&VHWxX7Umsl_ca=&sNjFVdWfWoVUe=&2fVrwIYYZrUcb=&2e7T4kWicqbhg=&O5EI9zViljleo=&Od4YSfWraZsoW=&vcBrH7XhXXfhX=&wwVNtDZjdYakq=&ejljyxYUUkdWa=&a7Rb5gZbhUsdX=&hPX4XoXfpobnn=&PjTfsIXcZspqa=&LoG4o7Zklqmrm=&x_kkLwWiigjXj=&e95MJlZWlisiX=&ko32nJXbrXqnf=&YLyPqrZqqkl_i=&zrLLu7Ygoem_j=&UXq4kUZoUXeVs=&_aM2M4Zrlj_YX=&HpXTlaZfsm_jd=&4Z6wK3WqbcVXf=&BLmZuwXgrWbin=&kS8pJJVgs_asi=&b59FRwVWdXp_c=&5vKl5FZeilWbf=&THAXycVqZdUVU=&4cSCTfZjpUpVf=&xGC9QzUiaefVp=&lE7JP3WecjXrX=&7sWWvEUqgimoe=&tAv9uOYkplmsX=&CuzF3cWZVbnhq=&DkwmKdZUpqqje=&Vw2wqIWYkagaj=&J_FtAfWracVgp=&epFVEqXndgUhm=&P_wdCCYUmpYUq=&G_sO3tYirceXc=&m_zxUDUkolmZY=&UOlzKPUkefYlq=&LQxsd7YWYhspW=&YGF3ARWaefVpk=&QZCpWXXfnhjVe=&DG48OBUjhfdbe=&BQTZZOYolpkgZ=&Je8DDSVjYkfo_=&ssYuI_Ypjjkjb=&2p5ZOUYgUUdlY=&PQ735ZYpbjnbo=&b8dDuTYienfoq=&XCs_e3Zalslop=&bylsEcVWYaWjr=&wYwW3kZagdeVi=&5mJWa5WZfeanb=&rFnJubVsshpZs=&LEgTjhVdolrqh=&BufW4rZbcUWsr=&lG3qO8ZbhqZob=&lgou9OYYhVnqb=&795vctZXsYWql=&dv2IHuZplWfVa=&biGihKZrmedpb=&ZlEemcYfYXqfc=&5fZHdvWj_VoqW=&E3AKqaYXikqWi=&NkTqQbWplrljb=&TzJiMbVfhsmln=&TN6ZcMVmo_XZk=&aESijFZddqmic=&7ttYccVVbVgpY=&vlxwIKWqerbZp=&6Qygl3UrfgaoV=&EyyYqpXegsXiW=&pZ5bYLZZbqqjl=&rQmZ7BVacaiZk=&kE5YW6UYqdlnp=&6nMgNPWehVagp=&ETtBqEZfVoclY=&Kstqp7UZ_lUbe=&tfCYFTUpohXUa=&qU9ljxXconljg=&bCpZBNXVpYYed=&t5dkCdWgWUasc=&lRkVoxW_ipjZs=&q28o98YVomVZp=&vuOx4IZmplr_s=&qWiKCvXVgriaV=&9hlrUTXamlrim=&IKw6xfYgmijir=&8khGw4Zmosbhf=&487LBKWibYhsp=&2xPvmWUcfWjlq=&2MJdQGXjkYbgj=&C6xQrIU_bYYlq=&9hthkwXYhbnWm=&zKP6ZdUn_UWre=&Ork9STUZqoXmd=&_uKTE6ZijkYab=&xGArX7ZVWUhVa=&LyHzWaVlbqjlj=&NG8E_HVqYiilW=&eG5mU9WUoXgjb=&EeOXEFVZUWklk=&ifnofqUhfapVW=&MpWCuSXkVcdmp=&gpYmd7WcaUfVZ=&lghNYdUbamsZf=&KLy4bBZgV_oZW=&IJ7_CjZgXpkdh=&Kf63GZZmUlqge=&5WDsRLZsfmbps=&WtNENFWdmiiag=&BPvtm7ZkigeVp=&y97Y4NXcnrZVa=&j4xV3jUfqmiif=&ujqMU8WbkcXVo=&V8bQCiVhnpVhW=&IeENbXXkmnpWp=&EzAcdNZXZUXmi=&dlm9zEYmfegfk=&F9rUJPZkdshZh=&aRN6ZwXahVepr=&cahZLVWUXl_cj=&n9BdSIZfYpZgm=&B6OA3zXcs__gf=&RSNGFyUrnsnXs=&NVrzOUXUsUhkr=&o8YSnNWVjZeho=&k7EpDiWcbgsbV=&cV8bPVXblYZXr=&My9MtJXWVbkqa=&QeYeJ9ZpjVpWr=&mRM5G_Xpa_oag=&3R3Y4lVhmjbdh=&tABDDDWlagfdb=&wpivXvUcXbeUf=&bQ3j9dXbYknWp=&wigpHIXdUZUWi=&QbHdqDUcldqfU=&mdIAXpVprbrng=&NHQBgcUcgUc_Y=&R6I4i8ZpXkpWh=&HT_JCZZWoaiXf=&fZyBKXWrkjWqX=&S8EOZPXerXflX=&e33BBlWemhfos=&Rbpmx9XddkoiU=&bqtkUkYdbfVfU=&zu_xa8Yo_omfd=&_cyIXoVfYdqUd=&tJjcHHWcqprgi=&WuICx7ZZUiqbV=&GkBJ9JWYfYjik=&RNYbqFYkgphah=&4ju5DVVdodlWp=&_ItbnUYibkrYY=&O8E3rDUkZXfZk=&nyu5fNVnkjUp_=&cAsPscXZjXlpY=&rvTpoLVYUcead=&JYL8g9XprlsY_=&l5IEahYhX_oVc=&jarsuSX_kafdk=&3DT5I4W_UbWmb=&JfuLgfZqjZi_i=&nPTS4rWfUcoqX=&hjn_PJXlfZo__=&2rRmWlYcaqlld=&enDc2aUdkXkac=&WpzFIkYk_iicW=&fUpfjjVomYmsj=&sVraYDUfdesqg=&txap4xZYolhfk=&ef3grEXbgrihV=&7SzqrfYaknWXm=&w7ChzkUZsUUdf=&UISi_JYfiqdll=&amBBplZebnYbb=&ZGVXE2XUWibgj=&5F2qFCXeYanjX=&6jGLzNVXUZjko=&BTbC7aX_Uqdi_=&VF74sIXmnrUno=&SRamTbZodancZ=&uzM4rHWfcmjkV=&wE63VUWfoadYZ=&WQG4RhXhhegmj=&YVqbaWXUk_lhk=&VQNpMwZhogqrh=&TJhWsQVojsZbg=&9PAkyKYbicphh=&MLIpwrVdrWljl=&ImIAZWXYan_ln=&YJza3MVrjrkkp=&3Q_QKcXgbUbgi=&NiyNDJXpnVrWU=&uFv4xlUmdesrU=&AWOdkeVj_nmXm=&TbBRnRUXqUUUc=&gitFqHXpheobm=&7YXPvQZnYgVoj=&aKJj3WZlqbXgZ=&AYqu9mYohZrYY=&WB8aytWfZfiXs=&I_KAILVVcUhfY=&AXSZhRYl_qcgk=&vDhqKbVipWdYW=&377awHYnUnadj=&HILImKUkaaXYm=&IbzWxRUjZn_Wk=&XKgVbaWdgUVqq=&fwxRtgZqZXqso=&mretJFZildnlo=&T7qjnfYilmZrW=&He46m5VfickYY=&Iqu9ElVUsgaml=&zIhJ9QUVYdqge=&KU6doxWqqg_mY=&vWYcqUZbmcdeh=&Hqnr9pZfjbbqq=&gGkmmcUsnmnab=&YVb9lDXqnYfei=&6Th8QpXe_spYq=&ZXjGFHUqsYaZr=&flTIZ8VUZqqVn=&YFJ93bUbhcbjU=&4j_jBoWiUaXkY=&dNB9gsZsscfkU=&W_XWDaYmrWaVl=&BpSVCMWqiikVZ=&rO3snaXoWsnWf=&E6lLdwVqphX_X=&OlKOSBZe_lflh=&NEKVUcYqgefjd=&eqEVroUbfcoXg=&wsaNMPWsgVYaY=&swaHJzXXgdqpq=&gg9VKnWbVpmXj=&BcAHReVqgmmir=&wYFfSsWecUWjo=&_OioqwVZZUloX=&aRc9tVYhsYebU=&jKWRKxYYiYiYc=&NOwu59UgUjoWl=&YmPvwuZcVUYYZ=&LordeMZscgcfW=&rxhmyyVjmoWos=&wlUTuQWc_eesj=&NVpRIgUhfcf_k=&FoY__qYolkiX_=&Wr_H6oUbkqjii=&Ywe25yUdcYblX=&rvJTiTYnghpib=&_nFkL_XYhlqpe=&k655lKUkp_iVV=&JxwWMTVopkaac=&Jx2DovUlrngr_=&8cTTU5Ygphnb_=&mOHOdYXVaUlqo=&EzOAoUUjjqWco=&GPO3hVWikgUUc=&GP7YigXkkjgYg=&8ns5b6ZsmhpWa=&POxr4iXWrj_ss=&mAox8uVljYqfn=&8dhRgoZsmYoXf=&rsdzX3YfXiejo=&eVOyOVZ_afqUj=&deU7axYXpZapl=&ABN84wUcnasVl=&BFrZIjXlfcmbm=&YqCfDLUVdh_ps=&U_mdEkWqUmnch=&U5KgLyUZqae_r=&F4jTWvYmmpjjh=&wJ7ZEbUl_aUfW=&G3S5VfZbXkccs=&eqnlzKZqocbdb=&O2DxwmWgXXZro=&hUx698ViYcjja=&cVukb4YqccVVm=&B6dfRuV_Uesmf=&2PWkfWXlnkWWn=&LoXxrEYmgUqgh=&ddI8cKYpbUWqU=&rwRVdAYpkigjX=&LwUSAeUrbipUp=&_T54uKZireoWn=&BMU2rUVnnYelo=&ogYvhGYd_gWdn=&4Aqv78WiYolir=&MISXGZYsZXhlj=&dDbYCbUjZWlka=&sdTCpRXkdefoY=&GjWQsUWekUkoU=&c5R_aAZarn_ol=&zoQFhtXWcpgeZ=&LPaAXjVV_mdqk=&8q2abNZrZkqpV=&mQAx8RYWVb_mg=&qzpr6nU_XUeml=&kSeY6nUaeXYma=&jeshYHUmsinsl=&9XN7ydWop_opU=&MOnBEgUXVcUkX=&RHmLTCWfmp_qb=&h2VkeTXhYUUhg=&BGNI2_X_lofep=&p5Uy2uWlrWmUh=&uDZv5aXocdgfh=&FhsZoYVhdaWgl=&XOaacFXkVVVhY=&KxPwXWUVsW_fY=&e38cOeWXlaXgn=&wTM_fNVajeqlr=&BHpDHNXrZsgqW=&eJW5haXiblWga=&p6PxXbZ_spl_g=&KahCGuUZnpXks=&dlYSi3Yi_ccbY=&66wrNJXcggX_c=&IINsjmYbgUUVZ=&6QOVqoWqjXaWX=&TIwFo4YnffUil=&A_3b5UU_cknhs=&Ikws34YsrVpZa=&HfkjknXcVmsdm=&RGwIhfXscWoml=&YUhuTZZZgdomd=&NfhHxMZjYqZeZ=&COgZufUensrcp=&_3FWkWXpYprai=&M5hvG3WrrXdle=&jLmJ8tVaspjbU=&GFEbtFVlZVfeY=&OTP8BfZeYiqWl=&3Ru32FXnkZlmq=&4nTkbZYYjqofa=&8QbXkpYXjaUYh=&WtSIbvXeqekaX=&dG6niXXYnsfbf=&PiEVvYWcUjgmn=&Pr5OLPZmon_er=&bGoDAHZ_ZiXmd=&ZHDP2aXUqbsom=&Yi3XDfVlnhmma=&ZiYnRuUjgcdZh=&yg8GaBXfjdpYi=&5pJwgNUski_kq=&vtigAdYWhmbVp=&fWYI2WWdmlUVm=&Wo_LgKWpV_mUm=&NzbgnEWdp_dpj=&6IGmweZcrprWm=&yLdmZXXshVXdi=&qVyiKGZhpjpad=&nAS4FvUbperhV=&kYQP3wZoaZjap=&pZD3F9Ya_ndmf=&AuKNcSXajjZUe=&VlZomxVpcilcg=&CyTfHLZYaiYoc=&aityDeYrbZYZZ=&zdARjsU_ahici=&bZkG_7WdfVcrr=&QDnR8YWkrpVUc=&6cfoEIXfUZgpp=&vlYV36VpUraoU=&YpsWWxWmiop_a=&Nhf8jUVsXkXhq=&XK3ZTvWfissc_=&JCwRPNWZWkcdd=&2_pjUlZYsWfsh=&F3IqlmYslbWqZ=&zGuaeiVhfUlkW=&AFAOOJZpZogXd=&lWsp5EZghmZpZ=&9RQfQZVrcWVoZ=&TAmadiZgV_Xfd=&LeLaTJWkhjYni=&tHkLC7XesZdna=&ONxXt4YXjoeia=&EToaVcYeiZlUn=&K7ZjwTXrnskjq=&izlG4uUribkqc=&Wa7W4mWedkan_=&6XxIFRXUlbdmU=&dh5EPYWXqsdVl=&wQ27cRVmaZ_qj=&QmrUFdWlrjiUp=&vqVvOFXfc_jjV=&OPP79zVdoXjbr=&QpqrgLYqhjmiU=&oUfRcNVefanYl=&3DAm2UUXccpXe=&fHCyakXUjk_Wr=&NyCuULYYmrrjk=&gf2CSWWWmmpig=&gFEx5AZZfZifi=&WvQ8UNXrmUdpg=&x67qiuVehWc_X=&Knv4L_YXgjkmr=&tgmSpPXhkWoWW=&iWlpf4WhbYgid=&oJyFe9VsiXhsm=&IshpN3UkXspXj=&LVtGM5ZdciaXf=&vACWLyYYXd_l_=&uLJJ8LXVpYYXk=&RKI7MUZiahVir=&6ZBmmfYbasn_n=&8aTT7fWbjWXpb=&4FGDSKWriXrng=&df5H4dVpdqrVj=&jvudcGYcen_mZ=&tLXTPxUgjnZqc=&5ASf_yXndbWjZ=&jPUmAaVXfrlpj=&ys2HasUYaqqba=&gBy9RxYgenraa=&SQEg8iXVVZdV_=&K9fDzEVpdVWfl=&BdhXu8Vrnrmln=&ypV9CkZad_eXq=&iZmvTzUmppUpm=&_je3WfYjYZXhd=&qWLXJXVUkfqps=&mNidwHVfYUZWp=&nUrmUFYYqaUck=&gTk6C5VaaabjW=&BxKXIJYXhZoZZ=&8PocYoXZZWei_=&uLv2GVZmkYcrl=&mpeJtiXmafYZr=&3t388ZXoYgXcr=&rgTJRmVjhXoXm=&3QmuCmXsbflpm=&zqoZe8UhWpqoY=&EtDXwuUle_ieh=&tex9KLV_cfdWl=&BKBg6EZggZojr=&FrB_QHZUgsgWq=&GeLEl3VnYqZjX=&fgdvCGVinlsXg=&sn5GdZVorZgkb=&8bLXOBUWl_Zjh=&nKXQmUYqXgcok=&4dCYi7Vmfngkq=&VDxQ2fVZpfVWp=&d7mOSbVscjeVs=&f7zaZ2Zrohfj_=&MrzUqZXYeYssX=&T5uvcQUisjnsZ=&U7rOEZYUldars=&3e4mRlXdqZcZk=&XCayWpUhqkcss=&vBL7DxZhjWldX=&FB5R2KUpbrdsf=&woduguXakZngb=&yASHuLWnYflY_=&ag6UotWbkesqg=&WxnkSiWWWnViX=&WWK8WiZbnjheZ=&SNgtaEVqollcU=&_Ol9LXUZWiUgl=&kTZBV_YgnnbXX=&giL_naXpo_gkn=&Lr3FWfVnpWscq=&4FekpFUosfgq_=&8P_3oWXjYqVpr=&kULi7xXZnqVXi=&LCxYU3VoalVhf=&LJTf57Ws_iUUr=&TYo5yHW_gcmal=&fJAA24XaibXZd=&NoJ6mxWZiYZYd=&O2LFvgWrWgXXs=&EzlVurYnbbYcU=&IseOXLWYrcUkk=&YMpgeTWqrdY_f=&MGydaOYfXbWfs=&j4njLLWhlYfnf=&4Q5QQBUlZjkoo=&ukEJEzWUWYbgo=&bbqKvaWqrYiVm=&JlECsOYdqekis=&Le9f4CZpiVinW=&rnnMkxVUqmUiq=&xgIBeQZfeUcfm=&jCOKTBUhedims=&wqIUBiZkbUpXs=&_IcoCJXqriVrc=&NVukKdWVmapqe=&pOd59KYfjafke=&lrjQV7XefsoYl=&chnIh6Xaiqbne=&3RpOAFVarfkbs=&AX_A7UUXY_aib=&qP3S4VVaUfnV_=&TipjVWUYgbsbX=&aj9Z7gWrWifXs=&4zavrPVXgm_ZV=&EiLFQOWXofggn=&27ABtQXlasbbc=&bgwYS4UiingVj=&F46zHGXfWYcZr=&HbKvBlWinb_aq=&ZvQUEmUZidpXj=&pTWv7cXh_hqYj=&rhyXMzZY_rYod=&UKiucgWjVYarg=&DIOuilZZfnqhg=&tMtYQEUlWYekk=&GCrJ9WWZsdjrh=&ChTFqeVVoZWWp=&mzcGRDVVVbimm=&EyfL4jYggeUcd=&vn7biUXocfWiU=&XwebOZXhlogbo=&tvHTAVXYochak=&wXiYAUUsUhjlr=&t59i8AUXkZXao=&_QUtu6UdYkkjl=&iq9jqaWdlUnXc=&vxwRxzYVorlUb=&cZFiXrXlWlZYV=&buYfPKUmkipZU=&KMPjETYdobWam=&r_K5iMWf_mafW=&8G2zWnYqsimen=&ccWcmpYmfmnlb=&jJz2d2YmonXd_=&2NlpXNWsYUknk=&f_eDp7UjsXjcl=&KcsVHtV_fWYac=&CDbCbAVeddqle=&njBTX8YfmqfYl=&Rhh88gZimpq_o=&awhAqyYWYdfXl=&GWmywXWpc_bXb=&uOrghpUrcYsiZ=&pdn_FFYbmqdfn=&jYIPUPYdXpoZY=&3SKXqcXVUjkno=&_y6K3_XXZm_V_=&pDIsHuUamUhrc=&qjUjC2XadpZse=&pGpWCmUnrcedk=&RkpDScYie_goi=&7eVP6kWeUXmid=&dgqdjCYYsjsr_=&yVLa3IWrXrUkm=&MHWuXgYegVeaY=&iXaEy6ZcXbZjm=&cPOlqZZsdolkp=&Q7ZuyTWmVnoj_=&7UBfVTWXpjrkn=&pPe2aUYjiichq=&X6qgsKZljscZX=&eY5knrUoifll_=&gdDE9FU_ipb_s=&TFaFyEZlqomXX=&fnwbXUVfpfUpk=&b9qZBtYdmWgjd=&f_IidhZlknVVl=&PfbKz2Xf_h_V_=&xOMycNWXfZarn=&w_DgwjVkVXYmc=&8sUMeDVVbsdib=&8CaDe5VkZb_i_=&pZToP3YmkXUcq=&k8wFMZVjjbV_X=&WJeY7UWirmnYW=&QbdgWqXh_Ybaq=&SRMYeMWqaWjVi=&6tXJ46VXZWkqq=&ft_2ooUZelegi=&rzCtD3Zrpejjo=&hw_2PcYaWXk_l=&O9YJ82WXVdjVj=&YaucvnWdjkXUs=&T3AilQXWdpUkg=&wzE8U7ZmddVds=&OIpUnRXrnrdh_=&CGDWDYVWrjdhc=&A7CgZ9UhYUUWd=&fniu9iZjd_ihh=&K7STuYYprpohY=&qIy3emWrZaYmj=&nb4HDvZnigchk=&L3vgMBZpXqbUi=&22T43SU_bZ_Vs=&Gt4inQUribjcn=&RPvMIlYVdocVm=&tFwUSLWXhhrXj=&CMLXBTXUqmVmr=&KhyfulWiqacke=&gqjJtRXkYbmWh=&CMX9qZWlqcdiZ=&Zfigf7Upbobpk=&x6o9YHXblUiZU=&TPPOpqWicWpiU=&m7d5wbZprWWqU=&BrBXn6Ygmmcna=&SRv9WrVpUaWio=&r8bBtpVioVlkU=&E7XK53Xkccap_=&zfMfEWXfbZpX_=&yLxQlBVsqZkaX=&uMBRJVZdmhXlg=&9R5sYjUlfpdhg=&FUTBXcZ_bYhsi=&mXfS4iVrYbrUo=&LmDSzzYXfWcsj=&sF52B2WigZUZd=&e35n2uYmdfheW=&M8DroPVieWgXj=&rwVji3VolrhfZ=&RozHjOUUkUjmW=&b3tkQaZiXjbeV=&5P6ZtCVrrqeUs=&LweQ_bXXZnong=&8ZBSfBWemnfWi=&laQeD9VdfXVbd=&NJNfeXZWinlne=&qobmBoYhajXVf=&mv3b8bVmljn_b=&dwXs8pVcgnfao=&nrNr5pXXnX_pX=&8qt8mzXgUmiWY=&626zGcYbkpiVq=&sxdEtxZpl_as_=&YvySnRXseeoqr=&gxfJ96WUcfdaj=&cgPgQnUkqbUsW=&z7pKQLU_epjg_=&54oT2AYYkfejm=&2zjD_CYXjaUmn=&WExOYgUrpjeon=&gTovEcZZVniXs=&qjwW3AZspglhm=&8pFx7hYsmlcjU=&8Pb6YLVknVWed=&e9hwODXXriaoW=&6dBB8nUcighpr=&jdC4LlXZaslVc=&LpNF4CZo_oZZj=&nMJOWSWjlYoep=&d6OuZ4VYmj_Wd=&ZkJO9yVZpWaXr=&TbzZoaZgaWUiq=&HLXMjLWpZpcno=&ShMISSZmrsjrg=&nSqyLfV_i_esn=&s_nl5vZsgUfgm=&vaKntzXcp_Xo_=&MBsR7jZbqnhsq=&2dwYlDYkgj_so=&BEtOHbYiqY_Va=&O7mcLYWpdUioU=&BHZdOmWYYWeWZ=&BkdRPaZUqlcZo=&2eEJnpVg_loUX=&2KKnlnZsjZogY=&5taK_EYksWiVl=&5uQ4kkYVVVUbg=&3swnVUVqok_em=&G9R8ZzZrWUVfX=&38gA6FUZpcYfn=&Ae_Nf7ZjhsYbb=&mObKPhXsYdoYm=&RRjsyiYam_mXX=&33SZC8Zahddmb=&q4ON5bZhpfeqY=&YMzwHrUjjrZkc=&S2deHbYphbfZY=&PBFeGxWVnZYes=&Qiu_bGYhefe_k=&ZwEbvjWUspYXb=&XGrW_MUilofVc=&Fwk6OpUbmrsVl=&WRWtLHXpdUfiZ=&qEAsCNWaiWcWW=&KYRvozVUpshWh=&PXTZsaYjZgreg=&bDVb4HXWUnesb=&HrntohZkfnlaq=&8ThVSXXrmnqdW=&hzZ5kHZkXmfUY=&woxLFjXkqYcWY=&olRzv8YpjiqY_=&I4JqbpUrp_bjn=&AN9U25ZpnmmhV=&6vPTOaUqmoogf=&mEe9luZYZnacd=&s7p7JcVqlZdlo=&2UAPC_ZpUkjcm=&ZQDfcbWmfklUV=&dPCpTAVsYsUfh=&7MZEbhUjnZpm_=&O8k2z8VYddqke=&iizixXWbpZaif=&hWMLfhXiegVbi=&JPuxFlWmdrXVk=&i69LmOWgrVZi_=&ZGuL2eVjhgbbd=&ISEbqiXX_e_kk=&UExxf4Z_hppsh=&HSNMvXVoYame_=&SxFnGyUWUYjrg=&PtUpkXYVdfrdW=&tO9YRuVjogbbd=&JXoAItVfojsfc=&aZB4xTUommpcn=&2E4ySmUpe_mk_=&LDcqACXi_nbYY=&WvD_ZrXZspZiZ=&Z2wQSkWbVdlpa=&fHBZKaWoXcm__=&YNVS4sWnd_jna=&JPvswEZopdVa_=&yuQjG3Wed_eYX=&CnSMHaVdbhdYa=&OKsIbIZZVdlWl=&CukTDzXVr_cXk=&axYQ6BXiaid_i=&XHRP4IYdWrfeb=&xyDFbcUiVUsmk=&497W2nUbVsfhg=&9liXtxWmjlWbc=&8g6yT9Ydcecje=&l3nuW4WnbWacs=&TmkQPrUrV_WkU=&lbpMakU_Wdnqq=&SkllSJVgqncnb=&vvAfpiXhrsclr=&VdWGRrWsfssjX=&z6MajfWXXYokd=&WxA2NHV_lridp=&86WO3kUeiVgqo=&njl9tNUikdlXV=&IdAMxWXhUkV_o=&B96PV8VmUqUlW=&CLqP2vVZWoYXa=&Zq27wSWXgcgjr=&unkaMqVasjsnj=&cqOOOLVag_bag=&T8qb3EUhgaVsk=&4NtOrPXckUjYq=&tWvjmsWnmid_e=&WWWMPGYhiXqeY=&iubE8yUhqjZrn=&bZHks2YirV_pY=&W2ncNzUmaWlph=&ZozXa7VYZmarj=&bSOjt_VWUsjms=&3dLVTlWnsrYhr=&6tfOPgVVXUpkp=&4wuJVGWhhbqkh=&byHJhmYhZengk=&jejwMvVmlXjgk=&3Q9vpnXXhgn_c=&N7mfe9Unirhgq=&Wjx5uZYhbZYfc=&4dn7uJZeobccf=&bW7_zbYZcmrld=&85sB2FYYXkhUZ=&idOsmcUYerWpY=&iQigNTYjjqcrm=&NrXz3MVmcn_ol=&opRxuvVWVdeYe=&NSpKf2WrhYroo=&KOn2P_UYVeUgV=&RJeL2EUUlUYVr=&2fo959WVfmkja=&BXoFTZZlYVlVf=&m5iamGZcp_VXn=&xkj4xKXUrrXsb=&GLZ94FZgjVqld=&3Np7wNXoW_Xga=&xlFpiCVVUkpg_=&Hu8BV7Wm_Vaom=&4sAbP6Vnrileh=&58sZVhUVfcXrn=&zCRmoDWnlWsgi=&GqaWUgYWflqhg=&bJAtYrYqnVYWl=&dJ8Ab6Zlgisge=&hcHEv5VsnUcdV=&6QUOg9Wal_Xkq=&77YxazYneoWUo=&TifWjrWXkUlel=&iKoNPZYclpdfU=&yQWstmYdbfWZY=&SWtOsvWksWreg=&3JX3J7Uam_ddW=&bu3ZfMUmgXrse=&uyFqGzUZhYVqm=&iDul4LYbaqidX=&TJZkHdXWeiacb=&YByfFMWZjkUjp=&6aCJKkUpndanj=&5UphHlUVbZYYo=&WZjvXWWlUqnbm=&3geVzkVkUdflZ=&rsoSOOWraUmrs=&rISuMhXdrXbig=&qsQil7Yenejog=&LC7XVkYVpYkVX=&UxqWp8XcjqlVg=&vwlSFuVbsqplW=&a5ypYSVsWbpof=&lPum7FWbdZqqf=&FZQwkTUskUmZr=&rXLDmbUUpiYlY=&vQeKDMWgecsZY=&8MMI9VUVYliVi=&Y3ZMFFXV_Vkbs=&WtgVHzZcgelXk=&lCiyO8UscrcUi=&T7cRovYejerhp=&uK3rqzUqjefcl=&6hAEGiUZii_og=&ZUeOVdYd_mXZh=&ufm4ELYhneaUs=&Du7hdCXXk_nYZ=&gJsgSXXbdbjZn=&aKiGKEYimcijc=&vqRAGPZpUokm_=&qIh9KXVjb_qhX=&NpeKV4Won_dpU=&JueqPgX_Xscah=&PMplpvZWraVhW=&pAhf9fVfkUads=&7ejdQsYboipri=&NLDdD5UYfaVZl=&sHkLMeZoXZqYg=&VGrxqDXfn_qse=&mxcXCCUjkkXh_=&nUeXEJZ_cqikn=&MbNL2UYUUoink=&dnxOQmZXWlZ_o=&RDB4QdYaf_Vso=&rJoh_KZgncois=&z2dqOVUZpVhir=&Z6kh35YYgqU_i=&GbuYJXVUjiWq_=&goR5azWpmjroq=&LU5bczVcbrVdr=&J2_xUcZslrmWr=&YFODH2YoYskmX=&Uf6MjeVglWUhl=&iOQ3ZVYXalVhZ=&FxDJT6Vbqajfl=&wZDUp_UrjkXfi=&Z_6sqpZ_j_Wki=&RxqDRDZfbbgZd=&pdAZYbWachWYa=&lEne2iZrqdUqh=&9wi375ZZikpcU=&wihQRNY_qecnV=&RgTzsLXWpVfVc=&tug2V5Vfkdmjk=&mq4wMFUdW_bkZ=&8TgA7IXgb_igl=&4TbqpvVcZYojV=&myhAduXhrWspb=&xgO8rJWdX_Ygl=&dIOL9lUpWlmpb=&7fcE42XcUka_h=&XLRCHfYZZqijV=&wn8vsZVnhoVhg=&AvfnZMUa_emra=&69E_fZWYporqk=&d2ETGEXkinpro=&CI6pVBVlXUXmn=&OteEr6VYghaag=&RFjooRVVXafng=&TxYLdDZkpfiap=&IoEt2ZZmnZsps=&YySG9zXhfjcXX=&inTW4YWrifpbq=&w2cmcIYcjlsa_=&PWEADeUoac_ZU=&4PBiLyVbrijUX=&mz6k7yUmjofla=&inh8SxYsVnYUb=&3guBOOVqmhnps=&JGTvP6U_aepnk=&Ug5nvaZYrYros=&ClNq_GUlYcefp=&AzsQEwUrXXr_m=&SRWaahWcrqfkZ=&5il55MYlkodfh=&HwCeqJVmlUbsU=&DRvkteUh_jVdZ=&hBTWNRXYWiVWo=&K5pUJwYlcUqZd=&Lz59UTYWceems=&b_k2FtZcpmb_o=&GSYI5qVYUVfgW=&Nvb7MkUiasbZs=&OqwNmBVbdmVls=&A8tmKaVgaVpnd=&XUpTTcUqX_aam=&gmyiw7XpWfkfr=&bQBERNXflqpcn=&Dx8aUsYZbcUVX=&ob3k8CUdVoho_=&kPH2YZZ_Xqafm=&PxNoctUWUbUsa=&ZvIeLzUcUaaf_=&oOb4pkUlYrllW=&QHQCHQWqrWYXj=&Y5NEqIZYW_qmh=&QISEYKUbsakio=&K5FEJKWfrcjpj=&xGnimkZlrVYba=&LfyproXZnsomm=&wPLufsYlpmisc=&MSP3IqVaZZokr=&gvlkeUWXXp_pb=&ZH4V8XVoeUqnp=&GcSgaiVnhoick=&HBZccQXjflhXs=&zILPCVXhVUgmU=&wBccvZUafXobZ=&9Zi_tzXVYpbYc=&OwCFXdVlVlqfr=&4XjtODZZVYVlV=&ermfCGYlUeojb=&YdkBBpUZpgYXe=&9nzw9VUWbffgp=&Tvp9fFYsbomqp=&BPTIYTXqYa_Xr=&6jFTYQZZcZmig=&QoMHrcVlUoial=&NANeNXWpdjorp=&GocwdpYZmgahd=&KFbI9aYVmkrhU=&8eaRRMZsngdrs=&aXk3U_UlXojah=&AIdXevWnejjXq=&zB4vIfX_WarXX=&W78h6vZiksiog=&KOGtH6YoUrna_=&G_9dylVllpihi=&zROPAhWnpYVqU=&xt3A3FYdis_Vc=&oMLEbhZaVj_Yl=&I2rpGlVUbrnZa=&PjmWdaWXdmdde=&9LtW7BVhhrigU=&laFCzvZbkibeq=&OfI7MtWmVmgfr=&gIMUytXYYXdkf=&J38BQVYpopcoV=&xH7nhsYsdgeko=&ti9ba_VW_rjss=&qguv_EXpififi=&ObqNcSZchYcgX=&PFFdesYassbeg=&phvgSsXd_gnZc=&CxQNy5X_rqogf=&Zk5bOpVYqU_VW=&qVuL2QWoVVlhi=&uA_nEyWrVnsjs=&4u5bG7UdobjYi=&EDYtYQXYcsYcg=&hq_WvEYfmlhsa=&tqv33ZYrfdkho=&YVvvLCYade_nf=&HSDEmDZgpinrg=&VwIG_EYbrhVfn=&5Ee7nmVXmkq_i=&KIWcZdUUpWsXZ=&XPU6QbXqmmUks=&xd3RgOWVYgZaa=&VQHBb6XjffhVc=&ocjdtkXmUVsoq=&3BnTfVVZh_Vos=&ctTPRHZqfsfni=&qQyaUqUf_gegY=>gnb3YXaklfb=&9KCqgwXhdhVai=&LJd3rDVmlsbrg=&nqlsBsWeqpiaZ=&XFQfGOZddqgWl=&BgqZBAZXkZXie=&Apzg4LXdiWeVY=&nphq_KVWsUdaq=&O8GOBoWsgeqpq=&bibVi5YpVaXep=&LcusUEZWkesil=&QCOEvEVYn_dkl=&QelsBzZYnXcUh=&OJfea9YphZrkn=&YnpdHXXYdoirh=&3bSVAxXbfVsnX=&V4twphU_mWcfj=&kb58bjUoskkil=&ZwbAXDYVjlpWh=&GActrmZpqpngn=&mLOUZ2WgrkcXU=&ulOM5fUbWWYXl=&obNAGLUi_adYp=&rGVuNOWrUlig_=&qSfYewZUnnrcm=&ArsSBFUjsrZYb=&l6Bf73VhcqXWc=&ILWnIqYXs_pri=&42ntAVX_UhbjU=&6tJMU8Wnebg_j=&INEbkvYmorkfY=&TbAxwgWrpWWqk=&JsyzaLXWgbWpb=&7HqgZ_Xirabmq=&qhIAqHVbjgdkp=&_zOA4jWlfrWah=&X7oLT4Vnbhken=&5NH7r8UWjainf=&wkFOd9Wsoe_YX=&_Ocw7NVfoUffk=&jCQ6wUUXnWijc=&TcFo27Xaachnh=&uwyYe8Xgeiaab=&aGhLf9ZcYjgeo=&ePm3K3ZfhUifi=&9XsKtmZrlqfrs=&HmZguxVrgfqqj=&dRQi7EZXhqmfn=&QhTxmiZgdpj__=&O9j268Unledmi=&n9KT5MYdrhsUi=&WEeMlyYXepmic=&RfsVWXVhppssd=&mQTSzYYsijjr_=&DulNIWUkkgWZp=&F8tUSjVaXYnoq=&X6nR4gZ_ZiUbp=&rgC5BAVqlgZUq=&kQX8I4XdomfZi=&DNeq78UUWeeoi=&Ih8aS2ZpqZkqf=&kELsbGWmbdWop=&eMobjLUhaWsiV=&WXPb_vUsWYssd=&Xb2lvsXkgrhrc=&jHVL5dUenaikb=&dPRWAWWsdpZp_=&VPq3PbYUnXaiV=&Fz6WbJXhqkooa=&dTTv6lWqZcVXg=&z2b27LV_ieXVZ=&V7kZXHXlZZZZn=&TPdqecWekbhlj=&zX6pvzVsdblaf=&cxoXFIVded_dm=&7_wQVDYWkgfhf=&i5HE69Vcsdcef=&fYEyUYZnjiqho=&uC67tdZjfmsnk=&K8SLPSW_YVkro=&CajbiSYXokk_i=&dCQReNUm_VaWh=&SeJNpNWaceWdg=&JkfmjBUoncmgc=&tk6y5PWfblbdj=&MYf5bcWqmVanf=&Omc2ruZjhsXbo=&Qfbk3iU_iinak=&LvDqzMVUpUfmo=&zkprvVXpkr_jW=&A8SkXVVlnZoWq=&A8jtodVqkrXic=&XdbL2mZfWgpZq=&vsTqkCWrjmZrb=&dwduk4VWmkmjc=&Qbx9sgYXrXalp=&6bSMMsWn_onsr=&YYMVb4WiUkqnZ=&uTCxnIWcejZ__=&koNpBHUjYmgpX=&LKXqcDYWnikbc=&K9anWtWUoWYVU=&3ahUVEYpr_rqg=&vhAhovWlajWWX=&Qh6d2pYrWoVld=&K_3BF2XXmkkqm=&JyDvPjXkmrirV=&aw82GVWpqlc_i=&WAmTJ3XfYUWho=&FnEm8NUciiWUl=&Jg8d_xZ_VpVch=&X_aTEQWqadhsh=&R4wh_2ZbnnsYn=&xnFUrOYVbbebV=&wfXfsoXhr_cVc=&ieTd6WZccUdnl=&go6CTaZmkgcem=&5n_uwRZZcoWaZ=&ETqfhBYj_acks=&sX4_8iUggZWjs=&TfXbpNVdW_gjm=&pYgrkAXnbaV_b=&wKOqNDUosq_YX=&ppW4mDUqkqoop=&EuxLJbZ_rcjsU=&DLTkGyUYjVqgq=&nXkdPBYgZX_ok=&slXndIXkpgYlk=&Ec2bnaYcaXZbd=&qXh_OOYjqgZUZ=&3v5FPZVdkW_sf=&nWfWQHV_fkhYj=&oUbbZpXnl_jcX=&e5VO8SXWreVic=&89aU4CUhjYhkc=&yeCgYrYrVrUlo=&tp75qvWddceaa=&oZwMgsXdUeoZn=&T4Zv5FYkohqXY=&wJw6vKVYnWVmd=&wHUJs8WXbZbso=&oqSIsbXenklXW=&a7SRB9YgVlsZq=&fiGsafZYXraoU=&9hsl6pYgmf__c=&IQVrRVZoilfcW=&vkTM7zYoelYVe=&5dyrwMUisigWr=&snfJbyWqenlgn=&LSyfGhWdfiUdn=&fHxpoZUofhsmU=&e2WxOMZdjljck=&Hv7M3fYUbr_qo=&h39ZIFXahYsdn=&9KAyZNWYnZZYe=&ZMF2_3Whcsldf=&rhoKucWZcbe_V=&V6VLubYslaskd=&mMNhi_YprkonY=&j7k7SzZeqqkga=&3xcSVZWsebWUj=&glCPApZsrgcrX=&wF8siHWgkqald=&HyPmz5WVnYisW=&XMxCnzWqosilg=&rn6gXUZjqmiel=&9pScsFXUkZji_=&qiMrhdUZXd__d=&9UoTsQUUYpf_i=&SyLkpxYqbsgbk=&jlMIilXjipqps=&YOkgJjUmjiqpb=&ExsdImZdjchVs=&QeaLPwXnYjUrd=&ScCSYgUYr_a_W=&ebh4qqVqdmssg=&J4pYt4YmdWUYX=&obzW4nXinrffY=&_dRhtQVj_eVlb=&UN_5hmUXXZlrY=&2_MdEOUpa_ZpW=&MJfaGJYXjbWdY=&hcoYqOYmciXkj=&XqTlkeWpeUsoj=&hpQqLTWhpjcdV=&6cxrsFYkfmihl=&jZD8WXVcananf=&4RFyiAWlrcrZq=&a7gtBgUsiheXr=&CJvlzvYkViUfi=&J8s4fDZWZbebi=&8gFm4mWcYpklm=&3yAgWFXqsgfnj=&ucxqwnX_Whrge=&dVMEXUUVkcigX=&sSP4cGYbWdfoa=&N_sTdlWhUpYel=&SgBypKV_XYein=&7Vd8UxWbXcqod=&7KgQUFWdprrlr=&c9vNd6UVbYXqk=&QDx8nJVmnjnZh=&Vucdt2XemeZor=&ScGizsXejadkp=&QfH7OOZfYXWfX=&YcdJyXVpiiijd=&2JCvVUZirqhXb=&p6jLLuZolarVY=&f7qFooVebp_pn=&HNrTwnVsVnXcY=&t74kGAV_dnfgb=&3ibKjRYfqhoi_=&Qvuey4ZrbsdVe=&hQYT3VZhoVs_b=&9gD6CMWeUoeel=&kKyWVcWfeseda=&HNYm9IYqVkbUd=&wuHxGJYd__baU=&9ZTisZYZdbcob=&_NXNUwYZnhqlW=&JNSvGFZhXkUfr=&FcmL8RUYhVgoj=&_xdTm2Ynfiikb=&PtpzOHVbrqmgf=&XEqRfIUgVhUic=&8dGaMtUkXlqYY=&i3DF5DYYZi__d=&GkbH2oXmYYsad=&v_oDLqXflW_kb=&dDwuuHXpUs_XZ=&J3pZI7XhpjX_l=&S5QJktZhYqgol=&5nK728VnkmXah=&uTBypkUpajlVY=&o7itjZUdpiUrb=&DLa3szUWnXfUV=&eJSbecU_YWrUW=&xSVwu4ZaanVVi=&cd_ukpVaabnUi=&I_ULXoUWVcV_V=&xWWiEdUcbfkbs=&slGlvnZccWirV=&fpWKDtYUammWZ=&PBJ7xuYUocZam=&Y4XTQlValhkpX=&tQEcmzUdg_boV=&fbDb6cVkrqfVe=&9bOb77UmcVa__=&ENf57aZ_mVWUh=&P6z4VSXUsXcXn=&lFrO65XZUhbgj=&sb7e9DXnZ_aok=&QOJsJOVedUhWU=&gWyDcRVqarZYo=&rB5B2yXnhnoep=&8bGs5fWrnlbsk=&SVLbe3UXpmefb=&7HJHRyUeWhqii=&CjX45cWlgZ_dX=&LKoEZOUsgnhjk=&SqfD3wUamoq_V=&q7XiXXYZdrpUe=&eG7I4tXmUqeWq=&Qw92qZYkdkqmW=&fW2tfkYedmece=&RFSlMTVhXmmW_=&lYBjp7YUmgfpV=&uy2NqyUk_sXWk=&_t2IquUqhVVhf=&OLUeihZcsZYeb=&7n7VETZmrZW_b=&BitvszYrnkhaY=&OvqfwDUhiUiaZ=&GJt6yDXqYZYWb=&GDcgaTWekfW__=&umjs9hYigiagb=&RZkS4QVgVhoid=&E2AjefZqXdWro=&4OmkyzYfecbgd=&h9xsLMWZZosam=&pRdMJqX_VfpdW=&iLNRfVZfqfkpW=&ywXyipXWWifdo=&oKgw__ZfXiqXj=&eEycWDYXcomWf=&kcU_3nYcWjWmj=&PQBjRFWZZsWok=&rJpgMGWmqmrmp=&EsccuYZkWXn_o=&zus9vQUpVinoe=&VeGC4MUcndkUl=&SRAJnvZVqsabi=&FYuINHYYgeWdf=&NnYvJnYqWilqj=&AZsY6UUUosafa=&GYpwHKZmash_r=&qOm3_FXbWsqVp=&7TA9OyUYoZbag=&QHiuB7YiWfklr=&YmyVP4Xlrqqrc=&qoCIcPXpnisal=&dLfXrpXUspqUp=&KcHYskUnkXjqh=&QIrNFaWinXfcb=&_rxpvtYUoXrXn=&d9NnjzXfmdXs_=&LdDFXWWVUUhYc=&lGdQtWZfpfq_U=&pbkGLrVbbUlXY=&pwohHkUUnipYa=&KeqYxOXeirrWn=&CqVLJTWho_kXV=&jN3omCYXVpmkg=&8j5n85XiiijYb=&ECRCztZmZ_lXg=&y98jPEVjfXonf=&vo35cdWV_ZfXb=&SoRwubVsXlVrU=&XWdt_MZcWeg_f=&Gfqg2NYqanoij=&_YTEh_ZkhZmUg=&KI3YAZYrehpmp=&ZzKljmYsffZhf=&76ES9UZfVjUes=&WDrjlpVbkengb=&r4W5QoYfnohXV=&o7ccaZUYesoge=&WZojqfWhfkgZV=&WZICCXZkeboYd=&MBNJAkUa_iZfW=&xCE7GSWsmnnhZ=&DIxO8eXammpnj=&OaypNQZUiZUb_=&gkIBIvU_jg_jV=&l9ksQiUXihioo=&lh7hpbZsnsrlq=&Oi5iJJZkgYpVq=&36Fd38VdpWsnp=&viD9pfWjgiVja=&edxatyUdpilrU=&HXUO_wYmqU_Uj=&5EnuCrXbbrplV=&g93kyvWYnZWrj=&KODHYiUqiiZsg=&XabMV5Zgdkeea=&Bz5utzWfjkhcc=&DvyI_wWqljnec=&8F2nGJVn_hZbp=&CRVcuyWrkpdqg=&dixKzKZZliUVa=&E_wZmkZZUcahj=&njyET9UpYm_cZ=&osKZ9KYsYbefc=&NRhSc5UosescW=&ZGlyqXWWmWcoq=&zvjXAmUigjidb=&kzGOGiUamcUqq=&XlHb4fXchVbXi=&7dH42QV_lqhWo=&DZCX9SUldUiec=&spPUgpWpmUsVi=&tzwiQbUXYaWYp=&lKarvgXWbdVek=&qioPRkWqkjlpi=&WCLWcuXgg_nlh=&WhcJ8JUVqUXar=&ibjyguYUooa_j=&FfOlppVZrdemU=&YoxfT3Ug_rqar=&M_Meu5XscanjY=&99NgqBUkehper=&48xMXgX_UblpZ=&LAok8jYkoilnk=&J3XSfeYdabr_V=&dPpwPTZh_nUXq=&OIugObUrapcpr=&FBLumTWniWpoj=&OOa9v2WWsdkUi=&TAT5sCVsqbWds=&CMZRj3WWraeiX=&P7UphyYqeYkYg=&6ADxt9ZpUljrs=&EqNQRPWjVqiiU=&ZZHvuoYpndVf_=&gJUicdUfWXoWl=&VjI_b7VjmWZda=&YOhEu7UjiZhbo=&HjVKdyYkrcipp=&nQr4BtXbdbjVe=&JmKCeiYjiqcds=&N6fYkMUbWUsfU=&uqGBWoXgaqiXW=&8vuu2MZrfealU=&HPemDZXaleeqn=&dooMZwY_crqrV=&YTnZ8PXYeWZZl=&jSRCTgWejkmcl=&Q6lwP6UjnfXmr=&95ehyAXbkonrs=&DVAserWrqiUqZ=&blnmeJXmldUmm=&h4rDDIUrWddsV=&HAbbSzXdkrqqm=&WK3TUYVndr_Xr=&6ro8rDWaijkVg=&RUFlqJXYnYagn=&6jaImHYdkZjYZ=&yHr5TrZhhmWio=&oudE8uYoaijas=&869LElWojsn_d=&JHoTMlWqnmejZ=&XbUAHiZerpYef=&E4R8KaU_piWfW=&uCV5v5VpWaWre=&IrUNr5UVhpWhY=&k4uFCDVkVWabl=&XHq83tYdcdngW=&FhZBBWXYsUgbW=&yYNLPrYiWXfgl=&qVhOvuVbUqmWW=&K3ffK2ZXdnYqi=&B3sFEJZfrqfrZ=&sZvtACYWmebod=&mFhQCeXUbVsZV=&zaXgf7VsUahUW=&6xLY43Ymgiapm=&bJISaPUWnshmg=&vfwwPBYieXrjW=&RfZB6UVbZfdaj=&CddqKpWhoalgk=&pvKAaIWbsnlWo=&Rt59RPXoWoslf=&IOIS3oZqelXs_=&yuylUqUaeVkh_=&EfaBJyZeflomZ=&dUgWkGWUsflZV=&ZEAL2MVqVfape=&wes4bRVrlsUel=&KOAedkUaVnfgn=&b8gnhAVnqZVrm=&o3E_4kWnVoage=&dAxqhsUsrcVdX=&64Xpr4XnrjrjX=&5WbmJVUbbgflk=&O9MZAUXefVehe=&RWdvoAVsjrrlb=&A9efjHY_UhfsW=&CDykrgUadefV_=&5woTbGWrcYXed=&QL_bsQYYhkWUW=&Gkent3Y_bsrZe=&emd3IiXisdlqX=&f5otSTXrgVhqa=&ZEpazuUbWe_Vc=&kGsxVWWdqfWdk=&2oyyitZoZZfeV=&FacywKVenbagh=&TbjteFVqoaoqb=&UEvkzcYqiYU_Z=&w8zzg7Ygahsan=&z_LSnJUqZsgbr=&4zskM8WVrddqa=&fVwmI3UZZgYmp=&wnCBRGWVcUjco=&VR75plUUoqlpV=&AhyXChXqgkpqc=&apLs2tUjXbghr=&kmIgq2VrfUdgi=&BEuqGrUXsqgec=&7PpkBBYgkkUpW=&jewYQxVdcbiqs=&wqzMc4XbjhpjZ=&LlsgnAWgoblkc=&9kwcijYrWljmj=&yGgytqWm_lmkX=&2t22mNUsrlhlY=&9LEDUjZmjpYbc=&cUieGcVefohVj=&tEjyuJXo_grok=&thkmIaXjeeYkl=&WeqPPHZerphll=&KxV2XOWrqXr_i=&Ipw7jeVqrssfk=&KyUiZdUUYdoVX=&DiOg8CW_i_nfX=&QTKFRrX_eYkrZ=&Ym7Lt8VY_XgZV=&bcvuStUkhesd_=&rVP_SRWepcsXr=&icLvtRXmsppmk=&vRmSG5VWZXmie=&WzudYBVfpjdql=&3rZfsKUqlmmhU=&5MsMzNW_jqnef=&jBwtDnUpgjsgk=&HXrrpMYchZrn_=&nQ5wkPUfakjsh=&J_i38pWXUmUpe=&LyewWvYVhnsgo=&cyBtgjZrhUeUZ=&kIknfSYpjYsfa=&CT9x24Zk_sVid=&9nAkqVUpopaib=&xUY85lXklfWWZ=&AegDwEWhV_bop=&XiSgiiXdmhekl=&YWEalnWXbbdUh=&C7VkPwUYck_ne=&K8y_UuWjclXhY=&EBRFeIYjqlXcf=&k66p2WYmreWnb=&twATWUVkhrcpZ=&xHAxCuVa_qnhj=&Fm898nVfjklqn=&JloylVUqacfck=&cMO4BDYaqZZgi=&w4LkR8Y_Yhccq=&n9bbmKWmZbWmW=&ur9OrBU_pacsh=&f6opowUplaYbl=&maKisYYWnkmmm=&pmjNXcUUgocoZ=&CSaXQnYnYU_br=&z6P288Umbrcro=&g39v35WjeeXmm=&UwNJ9YYkUarcg=&DdUOLpUsdfgpa=&rCeWQmXcpnabc=&5GLG5dUe_idgs=&FEvPKkXeoWWgX=&mCtZnRYgiUXso=&SkS8fCVgeiUsg=&MmOCeWZgVkgql=&9oN3ybWfckUgg=&5ETrHZWggXheX=&Ddf8RTZffmmWk=&J93AVoXZX_qW_=&gdNHwmXZlnlWV=&56zyaiXXYqfoc=&NTw3noUXmmfnh=&raoN5NVooWdec=&BSEDGRWZarhYZ=&morc8eXk__mcc=&xGEz2mZjcWVsZ=&YPjoQGZrfohqV=&pVZ8mBVWamadc=&vIBedwXhWsffo=&MmOmMcUdpie_p=&Tl7TwrUWg_XVb=&O5hGsQYf_kpsY=&9DuEWPYhmgefX=&Cm_eYDVoUfohX=&lCAuMtUcbqlYV=&fGtolmWd_ikps=&YsCBe6UfgiXih=&OK5GuyWjWfVYq=&5WjYhqUqfjljr=&GxfVslV___sWa=&DZt3UFYrcZofg=&favEVtWigYkUp=&rWjVM4WrfnosY=&6XrQM_Zfkesnn=&485PQsYkfaeps=&5UeA5ZYdjYjfq=&zSkLCdWio_Vop=&bV53RbZodqmZk=&qdukWhXs_rmdY=&VRbIE5ZdVsjWa=&ri_FjtYjascqs=&nHrDrFWmkrjXe=&p3Y6zTYdlVkki=&DPjFGYVsYWiqW=&q78lBoYrZclri=&kg27zFWXeYUho=&mrEaF5Uh_YWUU=&fLTv5tVdikoXZ=&dUgrlvUUidVpU=&TvrHgAUU_mhVh=&DqOMeEUpUeV_Y=&eeOCLrWjdqZpj=&THc_v8UgpaWnf=&huuGa2ZidXUWo=&sMfGKXUncZVfb=&RgBOjKXiomihk=&IJ6PneUoWpnVg=&dW2KYRWpiocid=&7CUh4gUUbolYf=&xNT8A7WYrqWnb=&E7TSIhVmpZ_bn=&qY7cu9WheeqhZ=&AJQZzPYgqlXdW=&jfg5dHVslUipU=&kwkMMrUWnYrhp=&e2sPUTXbVsqha=&piENfzUsalYaa=&kYzH6dYja_rrs=&Ec8GJTVfadpsg=&ZSYxUBVVspkn_=&9Az8QRVUaVhdq=&5bw7xKY_bfpbV=&nch_yjUlabZXm=&ZwykWBXkslbdb=&RJFRxaVrpchq_=&w8jfBKXZVseUo=&DNNOBOUfkpjUs=&9m4UlAUqXhoUV=&AmLVXPVeiYbkp=&xONrJfV__ilqi=&iBBfKgUbVcshb=&MBCiZwWidX_jc=&n4qZXtZhUolUV=&jxmYrUXXjfYpj=&uBkxHyVehsUnX=&Mq5PnJXqqkUYl=&FcFYhdUsidlYl=&JtXyx_Xdgrike=&SgbnfhZkdXhf_=&8suuh4UqchUcp=&KGEL3gYXrfoYn=&_CpyXRW_ZVbor=&D7la8RXiolhsU=&xpDpA5Udhabld=&KcbNchYserYeV=&pBXJiuWWpenYj=&oIUzkQWhjngkX=&hBmuT9Uk_asgm=&haM8ySZXlpWUX=&W3s9qSYYglkia=&ld38fsVoaglXo=&DRzgb3VhUs_ri=&FAoNv9VVeipdo=&iKYhSaVgno_co=&qqsYSUXoikVjo=&fq8rpYUardZYe=&fw4OO5VjljXio=&83YIBtWVgUfdb=&pwYvO3Ueigacr=&MDtBxhYbjakUY=&_i75f5ZUojgWW=&OfthJhVsrpcrm=&KHC9U4Ufrrlqb=&vPUAsjWVsppkn=&NUPWShXpec__s=&zGIb48VYbirea=&h8PN3pVfshWna=&eA6USeVWefimm=&W8JT7_Wcidicn=&jR9Ji7Xeelsgi=&na_AYtWjViZsi=&LozHZZVqjpnge=&ngwoLdWhYflnc=&_pABESWhsYXUn=&FDerowW_phios=&KKIC_qWZsjUoZ=&6W39T4UfqYfdX=&gwfyOGYhfaWoW=&rTjmiFVXnjark=&MQNPzMZZUsqkk=&CvxhHZXUmgaqV=&anDUyxXffbkZp=&_392rCXefsZaY=&ayx2_SXWUWoeW=&ydoGPmZsdnjUh=&fNeNmiWkeaibp=&tGJr_kVniqaee=&uYqMFlWqaoakr=&CDfORgVorepaV=&VQQDqZVflidjd=&ezrO2kUWelUWp=&Zzxp4uZZcYUrf=&Nex8MZXo_ijWl=&8BAdEvWsk_hnn=&uyFbECYUXjc_b=&sFv7sUVpqckWh=&A_RFKFUdeqXbl=&aqeqJzZehfoXX=&zbVh3RUnWhYcg=&Am77NnXekjgZe=&5okpb_Xcoceo_=&HfUGIyZdald_j=&nPyqzVZmrmWZa=&TONzXmZsViprd=&zwER3VXoWiors=&m3ed2rVnnWfke=&UJVEJWVscdnpk=&7KNImtUhYmqkq=&QkOrSCUojnbdg=&aOKXMWWr__Zkk=&5THGEPY_Vkfld=&pZj2_QWhgWmWi=&bcq5h2XhbpZZg=&piUHHQXWZ_hkV=&wkzNAIUeYmlfh=&7Hl6X9UUeojpf=&_LVkh6XnWaXeW=&ymtnwoWYdcbpo=&HDAJI5WeVqkhq=&oZe9h9Zredbfe=&Wyj57qZqedks_=&zmF5vwYmhmcna=&5ymyAAYgrimjl=&OL5jzXXUUfegZ=&OP7tcdVZoeUpn=&ArsvWDVqfdfes=&D8HKU_WobZabl=&R3VkOoYoV_ikq=&GwzbuuVsmsZVq=&GMToIUYVoWYpc=&mmPuzCYnniZom=&87w7vBUsfhgig=&2YbVnkVrXgYbf=&qJX5_uUbjajdd=&JolLO4VnhdWno=&oJ6GjPZmbgpsg=&bgui7dXkpZnsb=&TVjAGoZhidnsi=&ipvf_TWoVhlhl=&gzClpaYiomiUa=&B6vzleUlUqmUf=&EdggbvXdi_cZf=&CUcKLFVcbphno=&erRHsJVbUpjiZ=&x39wrQYbZeghg=&4hsaiZWacqlXq=&IHmZ2DYWffanc=&QwERWvZgkVkZs=&ZwopqgXgpieWh=&wsJ_NJXVYkgqa=&lC4RePXjgilfh=&hbi9klXhqcsqe=&mSy4RyVVZnqin=&wYQ6X5Uqkaobc=&ZRcg_vXjgYdjW=&FJuFOBYrrlkWa=&5sPkvKWqpWiqq=&94oZZrVkaVcfe=&c95SoVX_XpUhg=&KpZPtaVnmXeXX=&9yiBfgUqWnkUq=&Pw3knzXimgXqi=&SS4OVmVkj_hUc=&WqUPQuVXkrrZd=&CTn5bvXbbhXUs=&92Y_L4XbVrWVf=&Jpew8UVecXUWU=&K2P8veUolmeZh=&JhgLthYirWqrg=&RqiBNoXnaqqnV=&Q5vHZ5XscfVna=&fyfyQWUoibnhs=&MiUuhpUqciipg=&ipkifPX_iXbpm=&JI8aZwZhrmeor=&dg5ct6ZmZikae=&l4wyB6YXoWbhe=&SDrtVsUVUjbqo=&numsW6WUYnf_r=&YgDpMRWgqWeU_=&GBnHoOX_aenWc=&Rzo4JoXamskbr=&qhVTl3YreqhfY=&aMW_xgWrsYlfX=&CRaoOMXUoXhl_=&mBQnk9UiZceVh=&LWJohQVlkofqX=&itexQoVgeUgrb=&JRXyAEUkfcmZg=&p9e3VrVdjbaZl=&cEzkKJYprggiZ=&9VtHtqYgcromc=&w7DvZ6UilrXmW=&4XGjkHZbqV_jV=&8KaKyJVgbfnds=&RLU_TOVmfoebV=&QkbOfIUbVkiqn=&8JzBclVjqWVgh=&uVej7QXXapopj=&mKJCDzUosYUWi=&NZf8xCUXfo_iY=&4UCxlFWU_XXoX=&SvOCh8UiZrmee=&odetVEZkkgnnZ=&6ANerEXremlgl=&j65owCWsUbcUg=&MZWfD_WgqgsUY=&kSldcrYUcjlVV=&23h4NrUqfdfYX=&iTuwFjViUXgrl=&WUMcQLZrpVeUW=&JCo7z4UbdXccV=&V2PBmwVbaY_ja=&khKGd5VYlfapp=&ca6CYQYf_il_g=&FNfT6VXWZiUdm=&i7IW8uYldljei=&QQn6_hVWVZaUd=&Vl5gC6XYeXWgY=&U4ZqKxXnZgnXj=&NTzW5SVc_VZjo=&JdHzGdYaV_ekZ=&Hnq9niYsrlraf=&whyuTEZkbkYVo=&5IijDKVZVoglX=&bHKnBfZjlikpY=&x7RUWVVdUsagm=&TwUrnZWk_Xndi=&Q4r9pTZipVbgb=&9d8GTjXiXeeor=&dED5btXZXhfmW=&NRthGoYWbo_rX=&ZPHXUPZWpnedU=&ur_fmvXroZZ_q=&sRXRdpWZXgdYf=&NM9GT4VUfVfgW=&vFx79gXd_napa=&4Ec2e9VsjZdUl=&Fs9o2qVaimpgb=&olI7CyVi_Xnoh=&w4m6u9WppoVdj=&vfpVIhUlpoblo=&dKWqKZUZqbfoi=&OcRfiXXdkpVYe=&Lf_KRHWZUfXVh=&8DZYVKZafbbje=&8QzQ5ZXlZdVcZ=&OjgMbSZssiZgh=&UbxfUfYippgiX=&s3UEDbXgebfsa=&KQwqgFWXmZgkk=&EuhP8IZhkUim_=&Himyx3WjliiZc=&cwraEtUiiqlmi=&cqdifDZllmqan=&WulFzvUglYYYm=&sdnsDJWmWgbke=&V7wBUtWnUiYmd=&N2yvV5Vokbhce=&dScdNBVWqZjWU=&QxtVYYWniZsbZ=&Z3OBBIX_hqlWh=&ibV_mTZlhgpdh=&HbQFQzWaiifoe=&X6CvtWZkeWb_n=&CodEhgZXkUmVW=&4skXsnWasUcfp=&IDUbWyVjsVmbp=&GwHbyYWgjbZpb=&u59wGQWjVkWcV=&ZvflzHZmYYjXk=&nZXdq5UdXfobf=&QgV2OgYpX_i_X=&4eNuvCXsmkVXZ=&UxXElRUsZbnYa=&EoLW5GWaqmsdX=&45A7ULWZppYeW=&nWokMsXspfkYd=&L4WBL_VgqVqUZ=&RzpDDjVkrgWbq=&UmFtecVdWhlYj=&89TkxEWbfgrWp=&XS2oi_Yoermsq=&vnjJuRVcdXejU=&ZKibGxVihoXUl=&Zf9NU8Vqdpeoo=&HE5LP2XdigZss=&7JzfVzXlsdZZb=&xtvMkvWqZYVje=&IsjI2EUepcnVa=&wa6PcGZibZhWX=&EqOTUwWhsYZfp=&IJpYK5WqW_Xia=&dB5UZKUsbcZhV=&6Fm4GCUef_Zmi=&VPmkihXqUpgXV=&FvBeSLVse_gqg=&cLD4RyWlXjmcW=&hAOxStVrb_hiW=&_YRW6NYsYcbob=&qipIfoWacgUhU=&TOiVHiXkqWWin=&WAQ33ZYolafqc=&uxqPi8XWjefpo=&dGJtxkY_foX_p=&tuFxveXbeZbng=&F56iwWVUokmU_=&4VePpNZphkbpl=&AShivmWhWeo_s=&XnggpjW_akWkp=&rbqGn_YiZjfdo=&7In3rrW_mipmr=&GPwZbUYgnliWs=&YKZDitWjoVpbm=&jkqJqiW_qcfoo=&sJbDnaWeqlUke=&6rtVE_U__Y_ja=&RXJoD2UoWscqW=&PcP9xxZqljkhh=&rOG9F7XchWYUp=&wlbfbGYVVYVpr=&TudRLdU_Z_clY=&PBOtwrWcljiiV=&AQ_kaDXdrUjki=&VTN_JbWjcosdq=&RwOOxOYloorqh=&y695CEYicpcXg=&2fAKBtWfkcYia=&xhIFAPWjnkYiV=&rsILrjZhdronq=&ZyURTwXfmg_hj=&83Kh29ZlpriVZ=&Iuzsa2ZggemkY=&zLT9k7VlfjYfd=&3r7fadYU_fmqr=&eaf9wpXhbiVWZ=&lU9QFzUpWqbeg=&_YfXJaUkZXpXY=&e6ezT_XkUcisV=&tWuUUwW_bsYba=&tZc44IZcgViVk=&guxn3BVafZsZs=&YT6rFsUVZlYbZ=&bCkfYRZeobrVq=&CDM_YfUVfVdsZ=&JyqcxdYnjhWjm=&OyhUNzVgjqgWe=&oFUgGWUpYXqkg=&LzzcvPZegcmmr=&WpOwMjVeafYcV=&UnmU6oWfXhqik=&SGaM6cZVofkWf=&zUYJb9Vlgkfar=&9zQVW3Xrpahlk=&Qr87VOUZleZcZ=&5dMNYqYXhmekl=&mHULmjYsgfaqr=&b3qvUbX_rned_=&RqjIqQWWfsWhV=&DHUtE5Xerhlmq=&Vd8w5DVcmZVUo=&7fyuR7XbebbYh=&4tonkJVpjbhhj=&PHgn_9ZcZUdXk=&vK6W5mVcjorai=&Ip7bldYVjskfe=&D6L3LnVjhahke=&3ue7tmZjjWYgr=&v9wJH9Wh_hVdi=&p73yHsVkhc_be=&9zUN9vVeZbkZW=&yGpZGzVgsngkU=&3DRBrKZgpscef=&Am3tTlZkoZcsk=&qAGMUDYr_pXXi=&OYTUkMVpbhqrh=&IiJG3gWjiY_jY=&qkzmPaX_dihWs=&HjL5waWeesrqj=&GzPjaPXbrbgoX=&TlwN7iZsljVmi=&_6W4F9Xsjnbig=&ksktriUjqh_Wf=&4vEtf4YYdWUsj=&9V_LbpUohdkeb=&7fjEThUrdZimo=&6Wi6mGVopfWmg=&ubfeeUZoVYXZp=&vZP7pPYZim_Ze=&_ag8avUWpkhaX=&pjD4zLXYWhWiZ=&m_bX9lXVpoUZW=&tc_bYaUgcboUk=&_gILxxU_dlYrp=&a_7leyYknmdhV=&G4G3GeZZmbsWj=&5qVHolVYkocir=&OlQCnpXpUbdYe=&6KUjZpZbn_gfr=&my4ZABZ_sXrmr=&WOT2QCXhkbnsn=&CQIs8ZYWdUYnX=&n_46h9VnUYjbr=&fVEAxcVrfbgVX=&9EEQIBZkiiVfl=&Jesa2eW_Vdrga=&6YVMLhUkggmqj=&pUIokNYfpWpVb=&kfhqs9ZVbXmjs=&m2agQBVq_qmoe=&NAWkDFXeophmV=&atKanaXflXXld=&X4cfN4Uef_kgd=&FvNYsoUjproib=&Xt9arzZckYsgq=&TYWGbMWjlYWfi=&TN3OMuUgi_ogX=&yuGGBEVgcjkag=&eO9NgeUlYaqqV=&VgkmcYYdnYZcb=&Z2YdErUapioqq=&_lziBxUXaarZW=&3dxyAKYmmobgq=&eHxrGJYYrbXqc=&93ugVqVVUqrep=&6jb97kX_gYemZ=&OtNSmFXZlpUsa=&HrgXUVVhbrXYY=&wI7vpzXsfplq_=&f_ik6xXsXXcgV=&9JdtDbWdbpjlV=&haGtzMZf_fcmp=&fcdF7uWjVqdhi=&YyGhs_Wqgabmf=&vyuo67XbkmmVm=&h7pXewVrelkd_=&fZtpTIWalqXWm=&maGu2PYqolYka=&j6LqNkYWaUYef=&IJNRH4Url_Xfi=&KVeT3NVcYgqpi=&29sfLjVcjhibV=&tTCPGQYgs__eq=&yN5QOqZVlrjkp=&mhVkKUZanem_d=&gHW9YcYpnVpqg=&QBtiC5WVrisbW=&3ZiJQEZUYcoYe=&FEUMHLUdkjqVh=&72vTYcWpqfaYc=&_K26N9ZikcVjp=&5ohFm5ZpXlXam=&6h9z6uUbnlUXZ=&MgMyrAVlpYpYW=&Z7LVwfXkWUZgn=&HLU4UpXhdqjoZ=&ZzVf_JYdjdbWo=&SzTO5xZqdYpXs=&JzFhEWYqnpYWV=&CWf462Vcbrbob=&joLDVjYWblhlW=&NX5hvAXhaXlro=&QdULrIXkjYYae=&GdZUYIZZic_nk=&zW2swxZdbgXcs=&j9GTb9ZUpcelb=&ahjDbSVmrWZZh=&mvHNzwWabemfl=&xpmt8mYdd_egV=&AQ7Ur2WY_qjXj=&OsDymuZiljaho=&aoee4cXeconnp=&zyY7REXqeZsej=&SFydoyVXasZok=&sVwEftYcYdmij=&6V_caaX_hfeca=&M8dy2LYojabon=&BGpik6UUmcms_=&3sDn3ZVcdshcb=&djpA46VcUoZrr=&F2JcqBVpngjrk=&96s9OAXcVYVcj=&z64LyzZofpdWa=&2cmmTKXokk_jd=&CHsqfuYndWojo=&FBiQRRWdqcpWd=&uG3hX4XfjUfaq=&iITl5HYoc_noX=&TYp_wjZkpleen=&TonQ9VZZkeVsl=&W5gIEpVWikUZm=&jGkoTJUgoeklZ=&iZV8vwVXmg_lW=&92tB7ZWUqihYk=&JwLBGfXW_hlme=&yjyDvwZUdpVck=&859SqrYrfVl_n=&tBNFdmW_YrVaU=&uu9F86UYlkprj=&M2IYAuUcromlm=&Nv5szHZmWcndc=&YQB_CYWggUhoj=&8a62wEXdZn__m=&6Fno8SWVdmYbW=&ngnQkmXodcYla=&gcSWnXUsWkhWe=&44qQhfUsVarUd=&lVQrfKVYsmXhW=&5u76sEYUsqnof=&JaehgcZjopjh_=&jddN3FWijeoZi=&lbEHOFVaUffbb=&ecxZjNZXakrZn=&iVwzRsXYmesar=&qcBS9TYaXXba_=&D8ldjnWhpmgUf=&ckZUanUgqcoon=&F_dYmKUgkbYka=&Il3z66VfffUon=&jbbxInXdds_Zc=&wznDhmYlcknfk=&4pL9MnZoeZs_Z=&tOICQgVcUYjUa=&uv7RBzVgaaZdi=&VSfErpWogUenc=&DYiaYZZbdaadp=&qDTkNNXgUlkih=&bQBchPWjimbbi=&Gw64QDWofgkgp=&VxtE_BYoqZcnZ=&og4xGWZhVf_lq=&PrFUcnUblgkXk=&OnIDPzXiaW__e=&VzBuZXUqk_smY=&7R3AFTYUXskUr=&gzI7oLUkkfqjb=&a_3_otYgYrlhl=&652_cVYkhmebm=&8DxHHKYnpYe_q=&JZztUmUblgcpq=&wbVTjRUqqsbsZ=&weSc8KVgqiqbe=&HV4yZLWcnYUhi=&vkAILyUfYmlsp=&f34p8AVkeelUj=&DJWikKU_gpkjd=&_nOeupWaiVpef=&xduf_zUiYchrZ=&BQUemoYeiWVml=&kWPtOBXnYlpka=&GjCDipVqisgeh=&c2DRu4WZafWho=&wx8U4QXbVUbpl=&VhQfRMWUnmdVk=&AOwbHFUadloVl=&sB8MgrXj_YqVZ=&Mn2P2sXjYmZhn=&sxYnEfUWeakmU=&SlDQv6UodfXim=&pBDbvwXs_hUrl=&EAGhocWsYd_Wj=&p6LfBsWZqsoop=&EFUlY2Zcap_lp=&5tDRUGZfVoank=&e9KamiUfhpfUh=&CDuPjkUpjljeo=&ngh5kYZbYUX_Y=&fkYf4LWicVVVi=&MLXkjsW_djbYZ=&5fFpFMUYdZsil=&hvLTUSZeUlkbg=&RiBYKuU_Zpolo=&hHFCENWfdlWXX=&yTugZlVcpsegk=&tPsubqVWqn_ek=&Yvw2bvXrnjUrY=&fu2SFAUdZmn_X=&RESC3jWsqrrWV=&XMrNFMUXnools=&UIigUtXprkpZf=&E_lqQYUZhajpe=&L_lC8EYopjiVn=&VFdnW6ZlslZlp=&MoEusEVprerUn=&U4wkoVWorVVsm=&nbCN8RVdqXZWe=&Hsdi8YVsXsaln=&F3nDrlVofYo_s=&8_nfx6Uchomed=&pFvVu4YVmpoXX=&APbOnSUfYkgh_=&pkE6eeUjlehWc=&mMYdNmVp_YmZe=&4LTaymVpkpY_X=&Tiqvf5WfZqnni=&4MoGkiZmshlZ_=&OBRfdWYqlcfro=&lb7l3bYdkjhdZ=&9jirS5UhXnkbV=&yl5dLZUacjanj=&APSYCVYlclYqV=&RhWQN2YjZkokl=&vdlRLKVprdWeg=&wcZ2g4UqlXZf_=&EBQQQyUmemaa_=&3ALLZAZgZqUjh=&jb_akXXYjhgrk=&BRDisbXlkbhab=&GFPmuCZ_kljoo=&_ASAqxYgVcchq=&ML_AWEUmVrr_j=&xBgg7GZnqlasU=&BCZwUoZjXYdWV=&ud6Yo3WdspZff=&m7P8lLVaVijcc=&nC8_VbWiormbl=&NLiqkzWdpUbed=&2bJqpZZYiddZk=&ANqCwRUcZYiYq=&IlucASXgrrna_=&LfKJKrZVkefWa=&EGfDqRWadcjrl=&GrteooUcnqppg=&ymufWYYhbolfW=&pA5XmcWZVqZfn=&eN4q8FWaXUico=&AbEd__ZpqWhbp=&juGDCFZkcXi_a=&XokimrXb_somp=&zr3iCqVZanpbY=&pmNmwDVgpjXYo=&7Vr7myUUsYWf_=&WwovRZZVlVisY=&XbBbKqXdcoapq=&izOWkrZgsUknl=&uhOfzvY_bXVdj=&OALbarZddWomn=&5sfhETVrV_ZZn=&bcBq9kYc_pXWV=&PR27PgZgjeoar=&zoN3fHWejkm_W=&jvUrOlXgmqfYf=&hCGXoqWfnebjV=&TUf3L6ZaWopgh=&KKJNYDUeddbmd=&LfHcLxYbreepb=&WGkNj4WbdfWhU=&kJrTbUZqnWfYa=&KklbxbUmXnWiZ=&eNrbhgWjdkjpr=&6UtAIXWbdqhqV=&ZApL8FWheWpig=&38nbPTXfmeoao=&EoMA4vWUnfgqZ=&LqbEO3Vk_qphe=&d3SuuQWpgVslh=&BIF88QXbpsbVm=&gWra7rVaqaqa_=&Bh6r9IVsYaXaZ=&6GTIgoZmWsoai=&kEuspKYnmdkUc=&htjgEaVUUldar=&_HP9RbYneZqVk=&AHnMTtYgl_ndW=&UauZblVXZfghd=&GxAI6zYX_lkrj=&O2ENwXWinZUeU=&7BBaz6Udk_kph=&ErbS_fWesceog=&QWL24TXYlfkcY=&f3mJxAVqqVcnX=&h5BWapVgaeUYd=&HBMZkEUk_famd=&QljaBcWfYUXdd=&uYGAUjWqnmnme=&kVYD7WXjoc_qh=&eyA6GZUijegki=&hoYkyaVdhYcaX=&Sg2ts5WhXdklp=&SDRjTCXoeZbok=&DVc6mjXZsWeXU=&bq6AnBZqoperm=&NnNbDKUoWUjdg=&uftb2qYlaVlaU=&_xvIHGYdpndhr=&QB2AlrW_hqpbc=&7nOSRoWskqWeb=&WAnHEsWfaqmjh=&Ijnt3oVr_Wnhk=&7fZDvIVihYZfV=&xrGERuWdajjde=&H2mhCBZVbhhnf=&RIkWv8YfVk_jl=&YuJlOEWkafsbV=&xgADo6ZXnmqnm=&YSVdtOXhn_Yaf=&7E2AEYVjdkrk_=&KYCFvlVmXhgrs=&8Be5YzVfcUYYW=&cZ7MRpWbefUhd=&kuS7rxZiWhVVn=&X32OAOUmVlXaW=&Yxv4g5YalchYU=&LICpeAZcqhaZY=&o5vLrDZZ_Uepi=&Gss5SWVsc_sWi=&mpV9C5VU_Yggk=&LzWmnYYepqjfr=&sJgv25WcenWij=&FdWntPWUUUqog=&pg6Fo3VVnlVcp=&upD6IYYohbrsh=&SiftlGYmVWUng=&5nqiVFUZUrflc=&GWJSpcXpkmbhf=&aGSvL4Vjfhejf=&GLGENEUdkbrmU=&HXtzxzZsUrcfk=&Z_vyLnVqcjrbV=&fttCHfYWWjmmf=&YeqprpXshfrU_=&jW36lHWdncisr=&qRtjF4YWoXqqf=&KlTksLVfiXkdc=&TpapvkUndfXhe=&DMQn4eYocoVgd=&EqAlAtWoZngoX=&YyxvTFYWhaYoW=&udUqFuWipZZnd=&H_KFvjZeY_Zof=&JnPYUbZfUkeWh=&UMCCCIYqWsmkj=&DdJ7H8WhdldkW=&n5CQcHYhaepja=&WGKuD4YaZnhog=&QLiGwIXf_er_f=&dPz_krWXfXfVU=&mAhMU9UWpc_dq=&4TzOeTYhXpaqU=&hW6gusVVkjlbm=&YOzzG_WchkXnm=&L7d9pSVa_qjrb=&c7TcTtYbW_Zk_=&okW6R2VdUWeWW=&LzmbReYmZlniq=&QzaZCiUVWUZnU=&_C9xuhXaZYkfs=&26Ds_gWgmmrgZ=&9izjhYZdVYa_V=&PikboeUipjgsZ=&eEJreJVg_grWe=&Ze7kc_YlcrhiX=&ztD8C5VrUZiUg=&xy4qnPUmslepV=&95WlIoUnjrpmo=&yBGc2lWnleiXX=&jwDhnoYkVdkhi=&cryl98UWef_ZY=&bBUPeRUWZ_eos=&Y6XuinYsdfqmq=&K9Zx5HWaWbWZq=&2ci_LjWgkqs_a=&mPqKRsWYjsjpi=&i4wlq3ZW_frbp=&gEwHqjWXbhrcZ=&8M9R5FYZYo_Uf=&oiBS9bYabUmlh=&nepj9vUjfbcnd=&7evPzCXiakans=&ApPogiVUqmfWV=&BuBEH9XmegefY=&9NA6XzWpVsgmb=&yV98pvUqqdrib=&hdUXZ4VdqjhYk=&Je5Jd2ZqipVff=&gmVVcfXoqfYUk=&NMzTVZWV_cf_s=&Ci2aKMYfrngsf=&FEvBzqWXagWdp=&c2kT4bYVkXqXq=&KXHQNhXmabXnV=&2WyIhcZoepnc_=&fcR53kWsqe_kn=&5wmOU8ZhUh_lo=&x_82e2Zblipjg=&73oYgTYXZea_U=&KKDarCVq_gWma=&vyDOSQVrVeYaY=&dX6_v3Yergsoq=&PZyWlXYheohlk=&6XoZopXckWcea=&mWWtOIUVoppiV=&26Qe7rZVVlckg=&t_xKYaXYgiglh=&ZsTiZBWnheZnX=&uZ4TiqU_kpjYe=&HNWpwCYWVilYc=&DXr5DNYehd_nr=&dCHf6EZkklUrU=&7yhfibWlheWhV=&xpSzmpVsrpdfY=&aycSDaVeWUYdW=&VDiWp7VsZcqm_=&pI8TUDXijrccW=&r996CoVqiibgj=&NRqbk2VV_ploj=&oEgSszZeZegfX=&HbvsdGXeYYnXk=&o4LyhdVpoYZoa=&r6CkzNXVsdpqj=&9YEkmxYpgsaYf=&grL8FdXaUmdfr=&Ox7gKYXqoneYm=&seDs2LWnlqVXs=&ZhtUAUUlgpsWa=&aHNVkwXUbbsba=&ghDik6ZcoUUgl=&c9NrbvUecVjWX=&VotApDWXacnpY=&g37x3QWZcchqq=&AoGKvnZaWshgf=&HgQedrUVZcnbY=&nETbmqYeecemU=&u4HFfzYrrp_hk=&X3C6H2YWaUpqe=&qC5T6cZbssleY=&FSrRWUXasioj_=&sRn9mXZUYhblc=&fCTgjbWbdmUhi=&jptGLqXWeVsqf=&k36pmlVpgqrWd=&56V26sZjfpdnX=&MxXxMsWilbWkg=&vayE7ZVrdVZZb=&qv3wpTYYUYdkr=&Frpg3PXljgpVq=&uVBWDBX_Xiipm=&hYRgedZqrrVWW=&wMHZnDWqnb_el=&qJ3ebkUhXreaW=&wg2hLbXlmYbk_=&e4rt9JZffYjbs=&bpH3nVUYfgogX=&CCffBFUgqhkok=&PvtIBDXsepYdh=&wpkD3fWkkprsY=&fFOKyyUWr_ess=&XhXrjDXmmcerV=&9RmWlhUer__ri=&o6OJtVZiZghVh=&sasIoqZ_jmpjb=&zO94y8ZsZXnrd=&qukwApUnmqhkY=&oTgLRvZ_oqnpq=&FAlGrmYYi__jl=&OxMSq_XZmrUmV=&OwfckhXaeWe_q=&rHUEAhVjUpUYZ=&ElIUEfVqfjXsh=&xQi9aoYdihsrZ=&mcugUdZjiVphf=&X9LdjkXbjZUqj=&9vWTpKZeVhfsY=&CiymwNVdkegYe=&uPekXJWpdlccn=&2AHyg3XUddsbr=&mjHZ3dVYdobci=&ek6K_cVlmfeWZ=&xvt3SMZWladfe=&E5T_xuW_oVUiU=&gSct3mVjnalnZ=&hf4NICXhYogmX=&jBACbNYhpbYZb=&_LiYrmXpdg_Yg=&cMnf46Yhrdioe=&AYEpEjXWVdkbf=&hyip8XVXisngW=&uUPWGUZcYeqre=&go4Je9ZZVeYnp=&hvWVYeZosbbrg=&8dwUIQUrsdihY=&DwLtLfWshpjcl=&jDo9IRWhdhXVZ=&64nzviXVnVpXe=&PsKdZQXsUlika=&YyJXvnVcbUe_Z=&YHf24pZhmkdpi=&MhjXOFUsYrrsr=&5r9RvFY_kYf_m=&YDrXiPVhVidVi=&pAJW2hVgbXYYU=&2bbw5oYsceWpn=&HnckELYkekojb=&Gml6g2UihigVY=&fMgyonVUfobaY=&lJ5NmVXdYdUea=&hpuQcOYXlfnqf=&ZdHjRUYlfaZgd=&BuANtGWrpekgY=&AWZyIQXcqfZol=&G5aFZJXgYjp_l=&Q5fK3YVZoafpi=&uRxyEQVaecpb_=&emqmeCZX_cnjZ=&Gi3dt4ZjWhlik=&ru7gUrVkgdobo=&hpiSvcXpbVell=&npYkduXfhsWhi=&N4hVpsWfjgYdh=&TQnEfMYqUjhrl=&iAZjorYsZXmXh=&oPcJ7lZgbrYmh=&4BXdMHYoVbqYY=&aOECpHYhVUnjh=&cBiwDMVncdqaY=&eZ2Gn5Ynjsjed=&Uw7iUfV_erVlk=&G7kR3yYdce_mr=&2boUiYXdeWpao=&FSPItCWminqWp=&tLhpXfXkgs__g=&qEuUGkXoeZfnf=&YnMH6SUoprqZl=&r_geDYYnsmiWW=&QcLRLVZVfUW_o=&IZBh7hWZ_Uckc=&xJ9wfRXkXpefb=&EXVGyIWZXnjnk=&8i_8cpZVgnVsq=&XV7AsXYgbUoVo=&YnsIIvYbgiXns=&zz9knxYYqieir=&Ad38jnZghjqUY=&NknJvHXqsUpaq=&DmGXKYVqqXmbY=&wahJRTVokijcX=&Wbzsi5YVXXapV=&l5HAPnXjfmXpk=&4b3jbAWcghngd=&rhr4ZLXUcbXYa=&PM6RX_YUdbbqc=&oP4uSSVpWrsge=&XdPSMTWYdmjsd=&iQ4f2SVnVapfn=&Sh3zEkYeUWZbr=&P6GAoCY_ehm_i=&BatuBGVbXpYXb=&_yOlGcVrhjgnr=&S2YWoWXXgcj_p=&F9B38rUoVigca=&37esSTZVeejdc=&AvmBvYYaloUli=&LgWOeLXUmqYso=&e22EJKUYkhpVb=&fZFz4kWZWbkie=&uBEcQYZrgkklj=&dJOyIJXfqVeYr=&zsQFqOVehnksc=&ipscOaUpqbhpW=&vzpsniZWeaeVf=&lJ7EdwYjZYipp=&_Wha8rYldfZqq=&Xpkc8_XqeiUng=&GwU9_uXohrpaV=&q7bbovZrqagai=&qwS57tZprY_gd=&oqi5GaYahajkd=&W4WvnwYsrcmZW=&ZqMjSFZlpZqkW=&idh9OlWjpo__U=&Bqvx2wWmdbfUs=&ZAD422XVViWbm=&l2bcQjVgkis_U=&HPRWQjXeXlYai=&tjkfPfVcUWaYh=&hBXzI6UosUrcp=&H85AMFVYVhbmo=&hVeKz_YXigWpi=&Q7rN73WYrqfgZ=&OA3FOKXXqonjU=&QiAHkfVkdmsYX=&A25eA6UXn_jqk=&2VHTnLUdWdUgV=&Tfsch8VUcilns=&Jtb3BAZgVlceY=&rhOZqEVYikoZ_=&Hn88gnUmjUVk_=&zjWrJ_ZoUmrla=&UxNWZcVmYofWm=&IfaprlXVdnkb_=&C_LHV3ZhWg_gU=&bkdDogZmalerf=&wtK8scXZisfWq=&oxKITOYVncggn=&dS9sK4XimpriW=&KHV_QJUrgbibj=&Q9sSazY_kWkWY=&nlx3wvYY_aZnh=&yUIJ4pYcnkWeh=&4yWT4OYV_gjoa=&tBlyGJVlhpUhi=&OrzSpaWXWnjZo=&tTBiDTZmnkgoi=&nZ6UmgZpfsdWU=&XCe6FQZhqVdbr=&b8jG36UVbkgXk=&gcfTwBXeXZZcg=&2QqvUUXnYZXkh=&DahLqcYgkjgna=&dnV5UnYbdnYcY=&kJlBbqWfbedco=&fdeaODZhXXjcp=&FWegNiUslgVZe=&hfYosCVsqXXgq=&VQnduxWWobcjh=&qlOStqZdgap_i=&eXUveuUcZreed=&qTjmaTUfbmmXZ=&a7IwnQZsXVdXl=&_xMS4KZmdhold=&BhbxV5VshXjnf=&8XC6aXXXo_nek=&ILbTT8UXhqbYV=&muWym4W_pjXYn=&scbs86XY_hrpa=&inVdU7XdskkqY=&LwtfN6WmjqmVe=&WBOGiXWobqcrb=&osbcaMUafkoYf=&pUga5QYbZsbj_=&_6saijWYhlkXs=&jxS7i8ZlisWZZ=&LvKkvfUZncbbn=&xXgFdLYfecmqp=&a9gBrnZpbZo_g=&HD6pHXZUWYac_=&e7Guy2XnWeWYY=&gkzWkhWe_dcYa=&dkLxIPYpmpfjr=&xZJ8m6XsiVeXn=&9Pcx9TZfpWhlX=&nmXhISXaqprjs=&hTevGgZidofYd=&CdAuzCUghqbqb=&TEOUvVZphir_U=&h9oGDAZinZYhj=&4jkhGfVXmlnsr=&OOchM9VfpeYja=&uzmrmdVa_eikn=&EVnxzsZi_nnjh=&Tn7HrNYanddje=&AZ5CZuZqiid_n=&TnFfk7YgYkeVq=&Ls2e6JXsei__g=&pyCcpLXdUojVq=&CwwHozUjUbfrX=&QJrhcgW_YmlXU=&uUh4J7UUcrgXs=&ghmx9iVYaYlkp=&DWe9djXrbqbq_=&PqTWMsXmenrcs=&IjJxX3WYXpqiV=&e7FY8SVibeakZ=&PxySphZYcl_Vs=&kncMcIYVhajf_=&FAZbF6Vldmdai=&Qwth7GWXVposc=&V5debJXppccdn=&JcfhRSZlolmld=&XtLbQvYZ_X_co=&MMgahxVrYgUjc=&JjHW6kUhfsqlY=&C9vRj3Xh_bhdd=&JSCBBFYUrYbip=&Mr8mHbXWZdUmo=&a9b5WgUVWqg_h=&iKi5ZbVXrZaYr=&fAoQrhXmmkbYW=&hNQz5GWm_ieUk=&iut5_AZZZjiWg=&mDSmgWYp_VYeU=&wCYLbEYc_jZh_=&VYR2KZX_Zqgdg=&QYVVZcVgXkdVa=&SgwgEDVmbiVjo=&c8A6d9Wic_raV=&_5KEv8ZpiXegs=&jWdopVXVeVYjX=&LsEQVkYeViXlU=&UDx5UJYmXpWYi=&KWvmzVZhUsrYl=&PUwJUiUckdfkr=&mImlKnWmZk_WW=&33DCwHUosrsqa=&Vuvw2_Wd_lkoe=&gcFaIUYZpUsXh=&ekn8J3Wknki_Z=&argkmFWbpfrZq=&edpxQGVmipk_i=&3VOBkTXjmmYcU=&XiEXSnY_ZXkcU=&YVOawBUiUqhUq=&Xw4fnLZhXWUop=&5hPFDrVncpcVi=&jzIfrfZppjXgZ=&ZmRDcVYaUdWas=&ZPyxnbVYYceZe=&QpUpVtXspgkYr=&HeKzWWYogUW_r=&BIbk_sVneWhZZ=&hObSYGUXebcUr=&Cyj_BXWipYmV_=&LH9bThVknekXl=&3Bf6zxUjjWoZd=&cPeUe7WhZWjjW=&Vi4SowWiYkbcY=&Xz4haeWhsncVs=&BwNIYKXlfrWZ_=&3fYbC4Uagr_XW=&nsli_8ZgVphbV=&FoPV9nZXV_gUs=&cSavlbXmjbZrZ=&zY__BrZaofUeW=&KEunzUXfYbUZd=&BYo3lGUcifWos=&WtuxOoYgrlZrZ=&3_hsP6UVWpoXZ=&d6oR6kWjipfph=&5d8InKUbrfp_g=&viKO6zYj_cXse=&Le8GydYsXhYlj=&mWty_MW_jfdri=&8ZzK9DYVsq_qe=&xMsDqZYmsYdZY=&2K38PiYjkdeXn=&qVBxSSVhkpfrX=&8RUQ2mVamUVnV=&R2u4tXVpX_fkc=&xufznvUrkrXpo=&wHaQ38YWgadbV=&HuScK7Xhprdrc=&svDbfRXgkrgoe=&Sg5jgKVlZioro=&7SeEZgWqs_nje=&njArUnXdlZUUZ=&SyAvCXYilVelk=&97jCJpUrrkqhd=&gxUUIaUbmdchl=&ghuD4bYfUraXY=&vm4GGzUWWXrks=&Aq4djOXlhhscc=&T2q8XEYiUfVqh=&vWiCCwZnWijpU=&EYEOIaXeoeXni=&wUpI6fYhr_Wkq=&EURocsVpshqdY=&hzqec8Zboeomq=&jTKrqXUVVsedo=&i_QOGLXblZesY=&8tRMhtXcbiXZq=&TuH_vtUhejnsm=&dRZAgMYfsaafU=&4OJamdXcrb_WV=&XBdnFeVWhhgkr=&qbXDiGYdgYbqa=&b2qf8bXnVcqUp=&ff33LhZnqWkpU=&EMUzYlUXhknoa=&V24Ku2Vklegn_=&UN3NUuWdVaeqr=&fdlp96Urkfnor=&dwnjGaWaaUn_r=&aEy7nPVmrrU__=&Ja4VZlXellkip=&tqVWYDUsZfqhd=&CsQTUtVrfnoab=&3tjLDGW_Vfrlr=&cHaYULUZbi_rm=&Vx884VUcdgmgi=&l3H7niYrVYb_d=&sxH6bjYcckdmp=&myG8lmUkWfdXq=&zJ5F9fYe_oifa=&8mwFyMZYqoahV=&sSqOuAYioUddZ=&822TCYUWfZUfs=&iLgiHMX_lseZg=&wC_nVeYhUVeds=&RMhsE7XVinnpW=&9nmxWcYjrVpnY=&HmnSltX_oZeUn=&UjoGExWbiWgUa=&BEAvanZYhlZ_g=&976PjpWblnnaX=&LUz_2gUgdndcX=&In7LDjXUeqZhq=&q2ZWEfVjeWind=&rRBdeWWkegVkY=&rf7tSKVpUWnVg=&VxHwReVUlVjpm=&AfrUPZYhdXVqj=&Jf4ettYicrhZX=&vX8RmXWrdZqde=&LwuNfbZegmjXY=&BWuwPAWWhnrka=&TAJEA2Xrigssk=&RlGDjBYXbWnVe=&WBoQMmUhhaVjg=&nzZHIeVogp_sf=&hit8jvXUVZVbX=&CntA3SVsgrlcq=&Sf7IG2Vqaj_iX=&JsrddOXhW_ggX=&YDneDZXUsV_Yl=&bZRFO2VdWbZoW=&mBpmFIYn_fhnq=&fpp_UNXljYoXX=&864RS4VpaVlqk=&DD5atnVZlosYm=&gvECPHXdjnjsX=&pbXgaiVcVrUja=&QJOoouWfVUhkj=&FImPqFYXmpknZ=&4oShagWmbshgV=&BPlOjmZcrlZUl=&tNrV2_WjVpYqj=&snwL_pUrfkmcs=&wWn3gLZrWaXhV=&IYF7PjWsrembY=&JoLrmrUrZVcii=&ThIC5eVphrmYh=&hMhgJwXcpeahr=&nR2Wx9UnfhsWc=&ZsSPMSXYrUns_=&4Bu5cbX_iXpkX=&WFuTw_UWXVVe_=&qtJs75Yflqmaj=&moLh4qWhr_lZa=&LINE_YWbfofoe=&rJ6hvKYmdZoWk=&eaol7zYYhmhdW=&Xt9DBcYehlhcm=&vizlfpZphpjpm=&IdZ9ekUosfqpf=&j4McpHUqhrlWc=&Zm9WyAUcabgsn=&fQexPxZ_iZVff=&npmCjmZVrpYnd=&iLRS8bXXilfjo=&YRl7nMVVYUmXd=&FrNiMMXpddWbd=&qGMXYoUbeoclq=&Jox3tzWVWYW_i=&DSX4JNX__kkrc=&BJCjswZbjfick=&buPX6YUibqfrg=&mlkaA2VfYlsUe=&K9rhWxXWWeXk_=&9CLdqjXXjYpXl=&QQdQ4OVfWfVWb=&4Ty2pyXshbgXb=&QDZt68Vcdmff_=&QxQCryWrXZUeg=&OqOBhPVXWaZir=&LPTC3bWhfZpgX=&rRo5FyVqkcgnm=&VJgAjbVsgdZdd=&A_xARHYaZhXj_=&JxhxbcVmh_dVY=&hjbJmoYlpYhlf=&yUiAxvUafeceY=&IoxgqdVqaefWr=&zXmurpYrisaaa=&AAinicVe_lloX=&oorwv2WrUpVid=&gBAevhZjbokqn=&9PoRVGYbVbppZ=&DjXphUWfXepqb=&UM7VFiUjUdhhX=&YkpXgyYWrUjfc=&kByrc6XkVshmr=&wo5Xv2ZpVUhrp=&IBeVdtZXkaYWf=&scKh2AWgYXecc=&5Mtu6nUhlmmeW=&ds_yDyUXnXqbV=&bGMblYWYqcigs=&PlEeUCZeasiXp=&TZQf_vWgebZrq=&7rShm5YseXhpg=&YBiM7rVaVcWUX=&gofb42VcghqXq=&F2qByfYhjeeir=&bVHby9Vkoplpb=&zBFEF2XrYYiec=&WzhUthUjdoeng=&BtRsRbZkgWakh=&ERi7uqYdgakdo=&KczJpHVihdhqr=&_UfCLHVasqlgm=&RiNoX5WgaUgdp=&y4lXXsUiW_Ugj=&pxDo8eYpUZVUU=&yDNr8UYnjbUWU=&wNbV5HXZslmio=&M9QL3zXdZhWhs=&STigNeW_UUhhX=&27Va_TYcpYebo=&x9etD6WqfXfce=&BAaf59YUfhnfX=&umkBbcWVdbeUW=&TYKBTPUrsddWs=&9ZXKbkUelhdgf=&QCVCRgZccUXWh=&glpY4fZYosWY_=&OMTsVVXWUfeeg=&iXALU6YaamWoa=&lqSW_zUVohmWb=&oOIHSMWmp_VXZ=&VgQtGbYeogpda=&VwN3ptUonsXfq=&UaG78HVeWkoWq=&HQI63bZVdpU_q=&Nul2GKWnZsdaX=&M2xXCEZUgfkVf=&yR5VDjVlkqnnV=&j5N6RDWdmaopa=&AzkKiWXbXVqia=&cAV6aXZqfgs_s=&C3zpzsXfnbgfZ=&RXx_6JZXgrkUn=&5FPaGoUfUso_c=&5SLfkbXacojYm=&LP46NUUrkVqrp=&jfMNaCWYfsgij=&EHyg79XiVforq=&Cp6HcrVjleYmi=&BIR6drXkYd_Wi=&PS6HMsWZXWlep=&KHow8BW_Webif=&nwrs3cUZbWXka=&gjfEcTUedXcUc=&tcK4jYZWjUmUq=&3rCmZPVhqqpZU=&XtvmSzUlaosrX=<Pw9UUlUnnho=&ycValmXlsokod=&ZxzHOBZmV_bsf=&jaFaMgWcdsZbi=&6oSANzVWbdWsl=&_CYnehY_mhecU=&ERgqh5XUecsio=&EbEX76XhWisrj=&zmjzqTVdZiiqe=&Lj9HpkXcUUXrg=&2JOqSHYkhjkcU=&vkbFD5Yperfln=&t3HbfnUimYUrX=&vDyqTEYqVUmoj=&7wnCTBX_Xankj=&jskmD6UcXfhVa=&i28KwoWUo_gqf=&DXib_oZnaldas=&DXb4cvUVnUcVn=&3sx6enWVcocgp=&OnyZVWWloVjWd=&Zle9xyYqjnVdk=&QDJLSSUYVnjqr=&PHvT8dVjqpdep=&mdTYRDWVaafVW=&OdCepvZepVWsd=&MmFpFeXdWXcbo=&B8l7KQU_njlpk=&nOYSlnYVlkiZd=&2ytxFwXsc_mee=&Dzgf6JVaUhUWc=&u3xJirYUgksXX=&En9v7FVZqYckc=&q_xszsYYporXa=&QPk4PPVgdWXcq=&pWfqzUWn_rdWd=&P2zuvNZpbldhs=&WN4ngNYdsagVZ=&dj5MUlUisUrXk=&MmWoxhWrkZcmV=&xgSatiVfpnnco=&Ei6N9uUaYgfgm=&_rB4IFVWaYXif=&rZMP3CUahocdi=&Iyp7gAWhqmkr_=&MdhhScUhoYahe=&GagQjiWnrbcVW=&ZpFWJlVVgbkWj=&d3sktdVqgghei=&ePUZ4VUVoes_o=&SKlFXPVWnXgmU=&EdzCzCXsZneod=&B3FdNjWbXohqp=&q8ibCqXXfXfcW=&mIk_PmXYrXqkh=&sX9NsmXXgddgn=&OKzDy8Vihb_jW=&i7GLwFVXWcpUo=&9cV446UdVXloX=&7kI4eKVoedUkm=&MR7ek8WnesWqY=&o8VRJSYfknkbo=&OwuLSYYbVfsaf=&7SMmxBUZXlrah=&H5MO4gUcXlV_g=&CfHMliYXkieZq=&7xwV95Znkpjkp=&cn74EXUXsUljX=&bHSj8yWVhneUm=&TgkEDUWhaUWio=&SzncHbYepfpXZ=&zi9bmqVnkgerW=&nFGULZVelkaWr=&O7X_ShW_sdfn_=&UrtdJ2UqjpcVd=&4l5estV_hZipe=&a7Lr_8UbnrVYc=&tNWBCCYYknbmm=&3xmeQmXqfYojZ=&tiHvcuVgZUoiU=&TNzvQeXndkWdn=&Q7fHXhWfohXmo=&9qvRWpXWYnomY=&4WSANyZpUlfVs=&8DsLzjWipbsnn=&wgElB3XlYUosV=&VswYk6VZor_am=&klkagcVaq_mjc=&APixBsWUhbneX=&eEFs9WYabaqXs=&UcIAK4XZqqggk=&9NtvPIVnbasao=&erecH_YZZfelp=&b98M7mXaVjYYY=&zzXfjMVloskmg=&_9FqbYVUjZnWn=&dFZgUFVdjaofV=&nRqzTOZWsaWZp=&3thCjeZWdjXYU=&GImlpJUlgrj_l=&AJJXuYUocWp_r=&nIaJn4VghegXc=&MqF5XcVaWa_es=&uW9PHXVgZYdkZ=&qVnS6eWhqnrkZ=&RGtwvjYfZYZYq=&qnH4vqWll_bnr=&nfxjPvUiscc_j=&ppFG_qXodp_Uf=&yu3FYAVVmaVcr=&eCxxrFUUcmnpX=&Hp7CEZYneVXeV=&XBNZhMUkkrqrs=&l_JeOeVVdWbp_=&vkbe7CV_edapU=&JJc32UYlnbqjm=&INDtRDZhpajcY=&f849OKVdkZXrd=&dLVQX6Usom_ia=&FObFdqX_pbXla=&i4UpsOW_sksaj=&tb4Q74Vhd_oee=&Xz3rWWZXlojUg=&MVQDYQUenUbeh=&O4NY9LWgma_pr=&QavhIHZ_YelVV=&xBA5eVVajYsgW=&vEypQzZi_hemi=&Yphl26UkVqpga=&SIT7LhXkabcbb=&l4lgAGUeWmqbZ=&KxRBoYVapZdcU=&a_GulZWrcbVqi=&pHzgduXaUfrme=&pdyJuEXgklZbg=&vqw2FQZkXqrbU=&HGLSBvUgajjqV=&XjQwBCWpieinm=&yc2GZjUnhYimW=&A9HaGwXehXlbn=&IGFQsTYoseUcZ=&mezUPIZsikjcZ=&ZvFNrOVWqUjVl=&ac5nTsVqWdp_k=&yUyK6LWbeVbog=&D3gmRbXmnokeo=&BurrLyXWlhpns=&gq9BppZVglXka=&BJt9rHUZYXfmh=&keAb2kWVsVkhm=&yIIr3VVZoeXbZ=&zctDDvWoYloab=&rnTvstUsWcYU_=&nUclqUZsZecgV=&RZ5QMWXe_YjZ_=&uTgQkZXVVbgrg=&FiIAPpVUmVrZe=&qBUgtoXWcfqZc=&du3tA5XZkefdZ=&LekawgWa_jsql=&PNGzWtXpWWlcW=&S2ItBhWYYkeZs=&r47RrPVjg__pr=&dmGK_QXZUjpll=&PfpEZVVZfdnsh=&DwNwjQXfjdinj=&i_eMKjWaifYsX=&Nh_auRZnZsYbi=&nCHVbPZl_efli=&ZCImMhXcfpedV=&GEdd4bUlhjYoU=&GahJawZpbUWmk=&jKj8KZXnhU_Vr=&3WaOI5Zcmlbca=&W7zVmjYkciesY=&GPo3c_ZkfedfU=&Ioz8gQWngUjjm=&5s_rYjWUmcopq=&JKbLiAYf_XZir=&PhWkAuVlaoocr=&oaUJyIXjlgoap=&dnEAzYWYmf_oj=&2rgyXgXbYcUWq=&mKiRG6X_lZnlc=&sY6bu7UYYUogf=&fksKyeUalklpr=&HMpbKIXfknZci=&GFFuUcYV_XZXj=&HZ5PweYnWspqg=&wrjxB9ZUkrfsi=&6LslsgYajZfVe=&2B4OqVVdcpfml=&jkZqkDUicjhXV=&HAOr8ZZcekXiX=&M2EJQIVgYUXpa=&jYedigXXYlpdm=&HUuMBxXkcbkVr=&juUgYCZahXXYY=&9Y2b6tZcVqc_h=&VStYdqZYoafma=&Gr3RaNWgViWhe=&2jkLWZWUeingq=&toeWAKWpdpVss=&gmmZxhXVjZVod=&d5nvGfYnrllla=&LoBpwUUYkoUc_=&bjsm58ZVZrYic=&4laMO7ZlifVZY=&56Ci2yXUrZUia=&TmaLfiX_jmsog=&pxwTQZUbsafgd=&2FehoZVmbkkfW=&pxVIhHXjrp_ag=&ftjOqqYnbkqUo=&VOSKl8VYZoZnc=&qZz35AZicebXo=&4NhPwZXnbdVmn=&6e7Gv4VfYiaqg=&T58LOlVfhWrXq=&oiH_fGYZ_eVYV=&ICmt8wUWWUqfo=&zbKozJYpg_ghf=&HaLnEiZaZZpo_=&A8ZoXQWbqYUpm=&kaCBAKVVdhaso=&RlwZBoYWmbqms=&7azbn8XnVhibW=&_ZVUbDZgWs_ff=&8zd6vkWjkaoif=&Cxv9EoXoXh_fj=&6YWvRlVjUsYWf=&fis46cXb_YWrj=&7tb_3nVbbknoe=&wZVlUBUpsWYio=&89l5b8UbihZdp=&2_Pl6aUqXZXsg=&lRRWjvXljs_jY=&kFph2VXrkjhgi=&U37Yn5YmprdUh=&ZIJkm7ZpVZgcj=&qCrM9_ZpUnrU_=&lfWXdzZhsjoij=&4hnhzIXlgdllh=&DFX2F8VXmeWdo=&56ACFtWabrWhV=&_3hVw4VXpdaYg=&PpRoKYXmeniVp=&Sxzf4xXrUi_Us=&EM83fXVX_ebYn=&4eyoQ5XYkeXdl=&iozwgmVagWZfj=&yWPDbCUiijcdc=&tMaTmKVfiVZoV=&jbqfyRXfgiifm=&pSBf55UalVkam=&56hRqsUUZYqqf=&AqdVtOWWZVfUb=&3ggW_aYdkWUVX=&Ih7rGBZUcWqbo=&zV9dOHZWqoaaU=&pgxdQxWnZpYrj=&hvcSR_WnmoqiV=&N8ex3dZcYkcqq=&jRV7QrYgsasmZ=&d4tuEeZXlppjg=&dbfiv9XgiphXd=&GYTydtXcojmYs=&i8_lsNXkriroX=&uixzzjXpiXcmq=&Vd7XTdWfaWXoU=&Ix96kIYhccYWq=&jNjKeEYsrYVdn=&FgiBg4XemmVaY=&s9tO9hYdVXgcs=&GlEvEVYZa_fVp=&f7GPHOXlYbojs=&hWm4FeXojZXom=&O54HY9UY_pqVn=&CWqBFBXnUWhmX=&BDV9f3ZdZgrrc=&Ahq5Z5ZsbVgqW=&vb9xjnV_dpdWq=&7xcxU9WirWYas=&IVeDObZ_U_mgb=&xc9eDyZXoXmss=&3Rj6kgYccbnnj=&oXHwOOWhpboY_=&LFQB4iZbfgcff=&HkgQgxUUkcbcq=&8aOzqAWlspsUr=&TPftkMYgiaimp=&gRbfyvUhac_lh=&Q5u4HuYfkbUYr=&X5vCVVYnmXsrc=&RlWzgrV_Ypssb=&zsIoraYiddXdd=&gfGr8ZXn_Vbn_=&tu5NHpYYXlXWo=&rnZRV_VoYgaeb=&aRkL7FYnjofp_=&zfCbJOXcresla=&77Qv99Z_XnlhV=&LPoKwkUngX_jc=&BnAUlpZdribYV=&ZzxivlUobXUUq=&w2qjCbZUVrcef=&gxdb4oWYhflqi=&oWb35GXYXWfrq=&DG_Yh2XZjhkoe=&_YCDIHVdqp_pr=&RY_IIeWqXjrno=&PXiBfDYgpqYhW=&vVttK5Zqbiagh=&bxkafJZVYqXrX=&IsvH5dXkhdbqc=&2SpRcNVqWoZqr=&vpz82HYkaZsXX=&jnseb3ZZZ_rdX=&3SfFOGZfsoXpr=&ZpnLBqZXXVYYY=&NjP_gQVaZmWVl=&JjLDinUorsmdi=&ySh8rtWqVheWd=&OGK_YRYqnoVdf=&xxdcOeZZkrfYi=&McE7vkXisYrkg=&gTXdYuXesZYcm=&ns_aKYWhZpgYh=&_9wSgkUirWVh_=&7jiUQoVaWYd__=&If_ityZUrYjge=&q6HUElUnq_dka=&rucTNJUp_hVg_=&xZhFO7YlolZYq=&z9TSX8XdbiWrf=&JD7rsXXlaalqm=&FHM6mYYaiYqrj=&_67skDWVppXWd=&Ksd53pXob_joi=&87dcnPVWUcpng=&KodlhpXfelXbm=&xSPLyVWelfsfi=&9y42tpWeWVmXl=&yzql7dZscgWpY=&ygwH6RWjWUclo=&KudEiuUmgmdlW=&4TGkPOUb_kWqp=&8zNiCDZWejUhm=&VwrVVYYYdnkrs=&Cd5v6NU_aaoZi=&P5cbsvZeVYZj_=&4ET3UtWcVYsch=&wIZKqdYXZidrl=&2dJjOhUf__ddV=&J8PzyGVonhWgc=&blPVBaUfoe_gX=&ifB7OSXZVWfr_=&wfwZo9VraWfln=&9zeltpXXlbfVd=&O4fKDMZhahVdp=&mz4RRzUjX_hcd=&oOqm7TVofhVXp=&rMO8qnYYdnY_k=&PIQquvWgaqjmW=&VMgh_YUhYsfqd=&PeixK4ZhapZWa=&7UKhCEVpW_mZf=&XDYmN_VehZcV_=&yYMhuWVjdUhoc=&9s9yJAWXjirf_=&Bw9gspVakWgWa=&JjHzAOXdbqYYU=&f39H32WqZiblh=&8aeOiqYircccV=&oiu4l6Ujmifem=&nUjfjAZXlmZYr=&JTOtiHXbnUeYm=&AluWXTYchjrol=&r3TGJwVjm_nfY=&hI3Hd_YdVffqq=&j3R3_kXjVoahb=&LdXWkQYnalhjY=&zvdNHnXbbjo_h=&3ub3sMVcfYhWV=&wtqjtNXmrpkeW=&YE5f7VYfsdcrc=&BpTsSGWdiYbdZ=&y8LUAlXYaqWho=&e6WZPmUaYZoZc=&pk48GuYpU_ipo=&mK7FetX_dXmhl=&klLTyRUsZgpcZ=&OJmEYrYkpfcZe=&zPcqGTZhhelXb=&pwqkLQZosqekY=&FrdzdDZaeXmdm=&fo5Sc6UsieYrg=&hl2FMmUUldfqU=&sXyIiwYcoseag=&9DTxNNWcajrgs=&jRq8RUW_fadnY=&F99cUKXWXWcqY=&wjkCpOXaceijp=&XypCwhUYZW_VW=&54R4CcWslnWfh=&TrPdu8Xd_kflm=&anVMPHZbnXckp=&zwahOvVeUrogi=&oYb_tAWiXdXYm=&jeVO85Xbmrogr=&4HGxnaVlmqa_j=&mUNtCzVnWrlrX=&PoEdJ6XYqemdp=&PoztlEXmYVUfo=&83s_jJUpihWjn=&wWhWr2WhdegZn=&5nJ8dKVhgenis=&MYgdBJYXmfpWj=&mxnFk7XUqnelj=&TsbGKCXiismbf=&GkN8nLZcsoc_g=&rIh6ZJV_WpfkV=&nFVKgHXpcpmVV=&HrvBEEXkfsobc=&gR8CjzUXUliiZ=&NEuutMYlXirpl=&knXEADWocnUhc=&pqolnnZedXsqU=&kSMM5xUWZendh=&wQYUFYYqZ_jYo=&2q5TfDVVpscVl=&xGKIvRYqgXd_g=&66c7jPYnnYZVp=&oafuDeUooqdnb=&UdIU6YX_snmcp=&Tr24BoZmYkmon=&D7EnZDUXpfcWm=&i33sRVXaYfkZm=&M6DjUZZUkmYWi=&NxdNYFUY_ffbb=&JZ6Bv2Up_bsb_=&UQnvEAVcoVggn=&dwjHpvYnqh_rp=&AEcFfeXmYbs_j=&tPhRxuXZiiYek=&y5lEj3XlqYhUa=&vwhv6lZfUXXqg=&cMyu5OWeisasd=&MAM5ENZkherWr=&QYrA9OVdbgbme=&HgYrxIYoeVnhd=&Q2c9HFXpiijVs=&E8xbU_XnpssZa=&FkT4ElZfskfqU=&Dgv3xQXfZmYd_=&fuyKL8WsiVdfr=&nPGjjzWsnZhgV=&xv4Vq5VYsnkfW=&akuxTIWWf__aW=&kBNXcbXepgeYr=&jdio9WXlscWpU=&WMjzxLZZh_WWk=&OQZCnLYllngn_=&96rayjUmcrjqe=&np8tRlWUrjgno=&uBII6mZsdZodb=&kstTMVWnsmZUW=&HjV2eDXjbiVrl=&MWOXxvZlodbZj=&pQ8L2tYfllbZV=&U342kjZkiVoim=&jaPmtwUmbascX=&tG_KMfYVUnesV=&d4TmpHUnXUneh=&PaZxugYmXUZgY=&FJ26dLZV_WYmr=&LhfwC6VfUf_nj=&tSIQsGUfUsgro=&vVeDVlZY_Yjec=&HYQVxRUjgUdfo=&ZtbGToU_gshbd=&GC2hVKZbakhlW=&Hj4TbiXrflYYc=&QbycjwYarjdjh=&YDpX5LZsepYsb=&uktVGBZlogijX=&TGLxxuXjqdspX=&qZbVlKXrikson=&UswVQQZeaeUar=&A8d6lZYWscZjo=&ArCSaFUedWWYe=&zQAr6YXkleWsm=&hPiAM7WhZcali=&zVzn4zZXX_Wom=&Hd5YIDUihqcZi=&Zb6jyHUsVgXkg=&rLffxjZkddYqo=&hDeGVfZpnYaiq=&URRm5tXdYeXXi=&38wbRzYcqfYXp=&Vzc4ORYUcda_m=&QpaiWgVW_Vka_=&XXJmlBYUs_pVa=&vZhYTmYafnkUb=&uuX8RgWUrZak_=&XPLua2ZdsYUjq=&lBmAUaZrqZkbh=&huoPEHVlYUfkb=&nA2GejZZfgmmh=&vpD6eeYlrlejX=&Mv2FenWjYbk_p=&8aQXsKXWlYZk_=&IaqRw2XgZpgWc=&OUhxJmWqsiagi=&fOosvLYinUmfm=&HLbowIUX_Vdl_=&oW7AlYZdofpXb=&cEFkmaVXnkmfm=&3Ei9bLUsZasnf=&wr52qDYkckrYf=&NcXwqaXZqVViX=&HujXTaWseoYhW=&dqjm_IYkmpcio=&dGgGcdYkZVkbc=&MyvS4TWXmosqd=&SrpW54ZdhdWXf=&6MxdliYXbsjjj=&rrMKy9XYeeci_=&ZCgL2LXikoprY=&dYyCLaVeqiqlp=&FgnYvUXojllgY=&SMExuqYgaqmcW=&Klh_JJXaWccko=&G9FfUrWZsYfjV=&QZ6NEGU_XaUrm=&JKyvHdVqeloX_=&Ru2XjNYVmhdkf=&iiys8vWXlkYUn=&PalECbZinfUmb=&D4GlEkZmmmYiX=&4RVCz2ZUgeehY=&4gyRjNXXXkcic=&iBjAu6X_YiZqY=&M2tXwZXdnqVVU=&DdmCBUWYdbelj=&8r5Y88Vhonnsn=&9bv8qbWdkVe_h=&dnuHpNZ_dpkUp=&atlCMOWo_lsld=&JrDLBcUVarfXo=&_lnXg3XoWcdYU=&SDtSiUWbbiXiY=&6RLCC_WnhlpcW=&L_LX4iVaVblkd=&HYFtNaUkprnqg=&OWoB5bXVgZrkl=&UtMB_WUa_XWfZ=&baDgtFUsihnUr=&ooraCPYijYhZg=&myfARRWheWcgh=&nqDCTbU_Yrsga=&VEz_ESVqneXlb=&Q3JHyfXWeYr_g=&RtCedvXrsaVdf=&hvS_fyVcsaqYj=&AtLd4uWnhZpnm=&cjrEWoYXjpUok=&mlpQHFWciljfc=&bMY4qgWqlYsfp=&XBuZfzVmVZZpn=&8ILGFHXkcklne=&FLDHD7Vpjaaah=&WObEGqWqgkngV=&PbaZfWX_snlkW=&ioWOqFYXgirhd=&zL7ktcWZkhXqh=&nhna5iVqec_Xm=&K4u6IjWhXsbfU=&ppmaDqYfYfYso=&wN5UIfYseXhdW=&zKjRJtZ__mglU=&CrNbFSY_hs_ie=&OJLt2jUldlesb=&pdeo3pYXUafga=&fxys86Xhpirid=&9HuFS4WkaYfUV=&4iFeSjZZkbor_=&OPEH7XWYakWaU=&TlQQTQWUrmWYj=&s4vFxOZgocZcl=&vTHHqXXYdsYrh=&rbvEoxZsjmish=&U2h8mdWeZdXXV=&AKQN4aUWfsnbq=&s7ZQHVXrescrZ=&jtl_LeZdfYWaW=&AbCamOXVaejXk=&jbsfIzZeccahh=&a6aZdUUkUmiom=&FB6KzIVppZ_ba=&JYm8TeXjcVnrn=&Gmm6E8Xqrskcn=&OhFT6uWbWUafn=&rr6RF6Z_abUof=&odMZnpWqmmocl=&yUM5pyZsapZcX=&Aw8tpdYosZUhp=&RdGRKAUbf_rWX=&A698nnXfVclfc=&PZ8pn6WhgVmqh=&XLYoIdZU_berj=&fd4mLMVbYWjfX=&mBWfmvVmZnphj=&tNZ5BkYZsfkef=&wnrT_iWnl_gZZ=&aZaSkUX_fmUdl=&itiC56Yckqseb=&IbDVe5V_Zfked=&hlQpcoVieVV_V=&iV6jFZXrqWkei=&HeuHl8XakoVbo=&eJLKDMZbrjUqc=&mJN88XUgspbWe=&NLEwkOZkVqfqe=&X_YULDWe_jhoU=&HTptSfYgfnrgh=&gpCqkGYfZenaX=&EviuBuWpsfVkk=&3CzuSrVpViedp=&6His2TWeeodiU=&9_XsLjYepgbhb=&WvfcLwZfYcsfj=&NHJBmLUXroUcY=&t_DiVBWng_YmY=&MEADGrYidWYpZ=&NBd4RhXdUZZVa=&nNPeeCWWaVVZf=&bY_PJTVgsWkoe=&hioqoAXhUjana=&bDpOxwUqVcnYn=&OwxH5lXYi_Zek=&QvVfXBXffbffc=&GCquTPUslpWab=&6Y6SlYWoebqkV=&efz8HiYlaildm=&XdCoUTXYnidcl=&AdkjMJV_nVknm=&wRwc5tZYrjWoo=&g43n6ZY_pZaeZ=&jIzNSuYi_bfmi=&434VbnUmrl_sm=&9JQ3c2UfanXce=&8nMMxzUdcosqk=&RaEQvPVdVsoVa=&JYANGtXpclj_Y=&hhqfCAWpWUbkm=&DfNWpxW_hqqer=&hpGnQ8X_hbVVq=&_I6naMVjXkdYd=&hGcX_nWrhYnrm=&GiPasLYpeiYai=&VzE7heVWrfllb=&jvFJgGXhs_gVU=&ZlSIyAVleenm_=&usPvn7Zrebfsi=&6ZVVKRUZmsqWV=&Kz74IVWeZlbeV=&6Fc3D3UehWYhW=&emMXU3Xnmpamp=&Pn4LrSWginZfr=&d44sDWWZeqXna=&u3nTmZWeriidk=&kWiIBJWkbXdVj=&ohg58wUdkcnpi=&WHUV5GXUYknhg=&u4IKydWpcepZk=&qXKdO4YrimZjl=&AttJhAZaVqWdk=&qaPnoOXrWpgfZ=&i56zPrYpqnWmV=&Fa2bl_UXXjsXr=&BB7SP5Vii_WYf=&eZnSqIXoferZj=&NV9Y_CVcp_eVs=&jlMIEZYbmjZqj=&IKz86_VlhbhkV=&grbwVbVgmisYY=&RTZYIQWcUgZbi=&dS5eOrYjbhoUY=&L7YWpMWaXhidU=&sJXyM2Ygkqegm=&EfMqcBXjmUrgm=&oUTgJaWdcaXro=&slE_KJZofjkrl=&hWXqaFXgicfoY=&qCFW7OYaqoidV=&lSLIMrUWahspi=&pI248oUhhioqb=&ypWqaAXjkjlqa=&DGZVFsXgkkXYV=&WWLkIKZgpVXrh=&PxNO4XZcnnnqs=&2Oz74YVWUUZVV=&uuT_uQZlUkbrY=&k7CjrHUkWbjUo=&USPXjdX_cgihd=&ZpDflHYldZfn_=&m87JlrUsZrXgc=&jE833jZrgjsap=&W9mGgYUmhfoVe=&wOukKcYW_lWma=&zxtIWnWWXVaVW=&w7qnEUZkdasqs=&gJ_fooXhUqVnh=&sWiM8vZrcirmY=&tqbHBkUYiU_kb=&4gH98gXqdlYaV=&bx9pkVZVbd_eV=&OZUVTNXfnhkkh=&ACBEx7VXaarbp=&EfjT2WWWabYeW=&NYg4_PWaUahVg=&UZHXqWVjsgiZn=&NO7MDeYjkpjjh=&FaZ9DPUiVsjX_=&3o7MFlUmsYlhl=&dvdwUoZfYrmar=&lPjW5yVkjiUVd=&jq_4a3YgWZkYg=&LIFJf9Vebhssc=&bIRIicUWVoiUY=&jUMBnHYXYmlmh=&7H6ntcXcVgfZb=&MCVSJ5Wcgrsrn=&NRfMlBWnYigWr=&P6PDqgUYrsnno=&owa3D7U_nWang=&hZWVzIVcfqlfl=&QvvUCaYdiYndm=&PoE_kEZqkcjm_=&qjRxftUZcUdsm=&ZAnHhCYfYaYhZ=&WEUIYfX_WXncf=&V2BPNVWVhW_sn=&tFpj7SYWqWdsU=&zaXwMjYcdhoqm=&STxhtqYcfkoW_=&fTuRf6UVaVYUg=&qshQYfVqalqdk=&ksDM39YpdWfpe=&KP7dEoUkmZiYi=&iAAOt8YjnarXn=&uBZRorXcpoiil=&Ycspw9ZeckmlU=&maarFYWei_Yhe=&oOnRqaUXrYVik=&A4cSQnVqfoaif=&s3PWeFXdigi_b=&mVO9mjZremljh=&PXAGhBUcorcsc=&VapsnJUrZnWpn=&X26v5rVqbZbmo=&aIqtHJUiseVUl=&cuzGH3YnVjpif=&dy2qVkYaYlsXc=&FMmmylUUnrgar=&TVhbeZYlfjfqm=&IwZUgmYcUrZrh=&iO7BWmZY_knqo=&yDomkDYeckbjX=&JeQAZUUfdoVsY=&TzwvogYrpaaXX=&ly5e2oVpWdaVp=&sGuQipYjcVYie=&aaEvgEZjaXlcg=&vdJWAmYjiijck=&9j2AO8YkWXdXj=&UWg2BsWgW_mrU=&438c3rUYpaprZ=&N57HduWaksmai=&AXZYHrWUVgkhf=&jE4sCmUUZhiWZ=&RsW9SxVYmnqsh=&Zp6_v5XdfWinZ=&XYjLOoZphYkng=&7jL32pZfVVY_d=&NHBOChVYhXsek=&o8MJNOZasahlZ=&xi2RvzXcbngZY=&FXd7ZCYseXggU=&K9He3kZWcZWXr=&HXXUpLZblbbYX=&FpWNQCUiZklgm=&2isHG4Vbgjopc=&CoeEAwWlkefgl=&tanf94WX___hd=&IJGR3AZgfsnkk=&UNwMpZVYcocji=&cDAdlTXaieqUo=&uFhM5HYZ_krYW=&O5GlXhUhrgZps=&2wBoJWVWVeWgY=&sf2BWOUi_Zmof=&bPl7slWUXlYej=&c4BHBHWdesrcc=&FXfnHkWmfqsjo=&AiPQcNVfdgWYc=&XqdmZ4ZYpZh_V=&8y3bArYhamfbr=&rlEtq8Vqlslss=&oAir4VWrnn_gZ=&2VFKxgUdhjVkX=&sA6_sEUb_pbYX=&9zqiP4Xdmffi_=&QCPp4WWhopfXs=&BhV953WWllbhg=&LenldoYpnbrpe=&psTxEdZdqmlmg=&jp_7ZNVUpVpVW=&6O8DNSYXiXlpV=&_bUgK2YfepVVn=&xf6bn8XVUsiar=&z6loX2WleWgdW=&dQzSJ3WgZsonq=&tldGLdUXYladf=&fBhBaaXsshpVf=&IRtB6wVl_m_kb=&XEXkkDYeicqnV=&uQ56BDZs_qXZf=&nBNT87UeWibUh=&nI5lXeVhamZZW=&pyHgFiWipgksV=&8gzx6yXfqZdUr=&gFIwAVZrUcdec=&5lUdP4YdaVjUo=&akDa3vXecXkgb=&EUpbmnWoWjWXi=&Ln_SZJZcYZicd=&OSte3gWmVVbmd=&yzRqPiYmWZZgW=&pRi9qgVhXWZUn=&4VDKXkVeZUiaX=&iBZ89zXfnjVpV=&RnT2GUYipfjWU=&nFZgNtVoakZcq=&nxaCGcUfWpjVX=&GSoOoLZdZbreh=&q46dwSWmYicU_=&VqcXAkXbjdmoZ=&3iy2T7UgbXnqW=&zBx4ZuUplWWbj=&UjRPCpUqXkXXi=&jlWe5eZlUfYlp=&zDV6DXWbWrfnf=&QCSgasYikYdbn=&EWQuXCZUiYUqb=&lO9_BNZiplZ__=&Mmr2PBXadUolc=&_9DlziXhscimo=&QqFVVRUhVWfsg=&k4vJXhZkilZlm=&vlvC3cVpgbYgp=&mV4tOtYggab_m=&6r9WPvXdqifkc=&KozaGXVaaccnn=&qvlpWzWYWllfW=&LJIEGcZqhhnaZ=&JJUfJtYl_mbcW=&3opkhgXdiUZdr=&qOigadUaZdahV=&Dynnf2Wiecqjd=&kYeSlbZqbpbp_=&hNlKgaZorYXkh=&TV_JPzVbidffX=&iJPcZ2VongmmX=&3HZDJtYpXqXXs=&WF5bCZUXeiger=&kNrPZpWpqWrlj=&GIbteiXbr_aqY=&pNTtjwYdamlcs=&5mLY8vXh_qpbq=&RBFXFtUnbXYYY=&iUUao7YZg_Veb=&DjHrbQYrbnneU=&QLIlItVYUZcjr=&6kZorgZscYqpg=&r4hwdlVahoUhX=&5nxu9UZqXWopc=&_WwkVQXeoYVik=&nM6hWVUff_sop=&L7AZwRWcVmWjo=&KPSU8jXfmXkgh=&gmJB2rVnVbVkq=&j8QjiYZqWrk_W=&cAVwQLVhVsjmf=&y4dcR9VcVbZYs=&DM7LwFVihnlqe=&gXkJRLZYfogUZ=&gz6LuCViU_XZp=&SVz4vyYbde_pU=&aI7r9zYmoVmnZ=&qU9vB8VdsiUpp=&WaAtKTYYifima=&BaNle5Yqemkjf=&_iQXq_UdkYYro=&OcvtVLVcYUgbf=&CkfVbOUUsVlaW=&7Bq89pYogWqog=&zKMVBbUbalgbg=&PpbWIZZcoYXXs=&fkNtrvXWeVZdc=&zKSLiHUdkffrY=&tTAww7XYhpqmU=&i3rRXNVfWdWpp=&dOjLz2UppakUU=&PJOTzwZVXs_Yg=&KWLhLXZlbXf_o=&LZtogdXcbsfoe=&TzoBrGWiV_qqc=&QjwNeQZlfppac=&KwPenSUdYkmqe=&c2CfMgWUkUleg=&UNMw2PWiocbnm=&vGxW9gUlbrdrm=&esCCukVUcleYZ=&vAXPojUi_a_Xg=&CcubLsUsnZcrg=&YLwOZHXbWfkfg=&QOIqz6Zfionqq=&XHGPUQYirVejh=&Qns7DaYiiodeo=&_RlgckYqjXWdc=&rDdRmlZrjYqhW=&dcIryoVidlapb=&5lWOxnUdc_khg=&MisNgxVadWVbl=&xirY9vXjodYb_=&zA584hXYcmXZe=&l4In8vYcldm_Y=&fPkgqTVl_dhmc=&uVcvLoUWochji=&9nAonLUmhWVZf=&XInpv3Xlk_qij=&_x2iDoUYmfrss=&yC7xhGWkVnZaW=&4ZWmiHZX_qZXc=&bv6nsnVohcqrV=&jwKuj_Vcqqjaj=&TIqJypWfjbfpp=&Fs7TxyWWhoogd=&4vcaLcWenh_sm=&v6bD8QUcrpjkb=&s4ZuGfXXYeleZ=&CP3hz7Zeaabdf=&wyvbkIWqeUeYd=&3MvdBNUb_qoZX=&vqKn87Uo_mcok=&9b4MTaZZWjire=&MJJWRXXVWZZsd=&fpR9YRWiZahj_=&JCuQPyUfbXsjV=&AewaDeZaXeWjp=&XxKYC7Wnhilai=&S4EB3AYdppVZU=&bFZ9HlUoqioae=&_TNgJwUWaXaan=&xjTAvUZfXfr__=&RXdKUGZUi_bks=&NlxrEEVqVfg_U=&inFlt3U_Wlgie=&wFyi2wZXmUnaW=&GxJSqCVVnbemb=&EXjNjoVrdkhn_=&7kR6VaYoYhZbj=&6kHfhZVlVimWr=&y4jjWCUogZVkc=&pP72RcXemjVke=&4RGL9aXhYembV=&KD3NxFYdlsmcd=&CnVNSWVbhXZil=&6GHdaxZrleYbX=&cUgjlvWleYWWb=&cumONtZZdjmer=&OfjofmVcfsnXa=&8ZDo4TVbhrqco=&mzosncWZkpUUh=&O2SaXAWkpnl_Y=&yJJsKmWZUkf_h=&JDex_VX_jUdmY=&jBqIfNYnrVmXV=&zq6lpAUaUWoof=&BcT6YaUbmoaZm=&5JokXeXVqfigi=&NvAY8cVbWd_YX=&F5U8m6Zbbjbil=&DUjmUCYZWdmli=&VnIj3yZjZfsdf=&p7HiU5ZVXghaf=&2gBji9X_lXXoq=&I_sMUiXmdXoaY=&NcOAYUUqpZaik=&XllIaDVmaZnfV=&qGcRMsVjWbbmo=&IS2tohUaWgqbl=&E9OMn3Yrcakqn=&MfjzkaXXhVlUp=&LSh8iEXqfggii=&Y4FMoFW_llhqd=&pSS6aRXhfVrsr=&HUEuBoUnahmYp=&Nw23hPZgpZnnc=&LLslk9XbsoeWY=&HWqRYKUsghmes=&WegdKzW_ihZUV=&agEFdJWcZnmke=&s_aTb5UVraXgk=&YNpIbVUhb_s_X=&nWkbGwWooreqq=&dgtDPzVpkVbUo=&guQDGIXVZehZX=&tcf4oJWglbVfh=&xNGPEFXa_Zlm_=&il5pKzZdVWfYe=&mIskDdZfispdX=&Hb6S8qYdXnZWh=&FXpzupZpmngVW=&XqApZIZUkoUql=&TH6c4GXUUdkra=&dPdzoAUZYoWse=&eqeFHRYVqjrsh=&D5xNQLYcpkVbm=&5bXPRXXpeVWsj=&6OUbqrWbssWsh=&MBuHhgVidiY__=&99qOknVecWclg=&OKODcbZWpsbnV=&vdKJ_UUlkj_fZ=&fTztwTXWiWafq=&79SDB2ZpiaWk_=&LpUQq9VmadYbe=&8IivBHVmdqVZf=&3xFtrTZoksV_U=&RLQ75GU_WhasY=&_3MyuWWaVeoY_=&3GiwQ9WgVWYkg=&nyzZpeUZlcXa_=&tthofrWhlefar=&GLo4h2XcWjrVp=&o9LtBTWdXonrf=&ErhxDGYfsfaUn=&iqKRjbWpqnhgV=&CzeIdHZqkVlZi=&qeh5KZWdUg__i=&GSdmkaXaUiaqr=&ptIY9sYgnefnU=&5GYMdkXjZc_fi=&aMbA5UYgisYqU=&f5C6TLVYlqgWl=&gjsl87YomqXVm=&6qlKZDZV_U_ar=&v5sfx5UbreZUd=&NMzMWzWgjWmpo=&WDJGuOUiqpprs=&aI9lb8Wodaapo=&PIbqpxXer_lme=&9WUk56YksmU_e=&dLsqyWVbrrhUW=&pBcjonYZimaXn=&muScBtXgVWUlk=&eOzitmXqadWsd=&jeFkWJXsdleWb=&_535oPXiroU_k=&QKp3U2Xpgaqmb=&6j_yoEVjcfXeb=&HIX59hWqhYqop=&WyQMr5ZUikgXi=&QAy5lVUYokirY=&P4BJF2YcZUadZ=&Da8UerUjgpqao=&hYr8TsVWdgopU=&tGEWTiZrrmpmd=&mFAXTqYahelrr=&xDjR8SYmmUsas=&mjx2GVWnspinY=&mkrWWPYaWdaU_=&gSqIyWXVXfhcc=&DpuAx6XX_jepf=&tTUuVJVgcpoqn=&lAqtf3UbbldgY=&B9ZPoRVqpbraf=&dMr8LUZahrcrr=&Jwk4zHWqXegca=&uIRMymZifZWnW=&XIxX5pXigffjZ=&fMheW8Wepr_gW=&XHroLnXsUbjjq=&LtvV6lXjYZdgn=&E2HVhQYqkhWok=&tJwvYCUUhaqij=&NpPGpXYhdYaig=&ewmqjdYkjaWrn=&X42VcEXrdnbjh=&pljkEEWgmmc_c=&OOLutiVXqhslj=&o683dMVsjbhdV=&Z_kMELXVlnhjj=&eN_yiVYknnnq_=&VekLXfWmjebsZ=&hT4RM9Zoqrbim=&OZloLFVolljYj=&UFGqNoZonbqWe=&bjD8qqU_oqnUi=&LXbFILW_defXh=&c77m8jWcpsWhV=&WLUo2XW_gXals=&3spSizZpf_slV=&KjVyjVYqdYbUh=&vk3_VJWhehkWo=&rwYqcTZVlWqec=&WFOhypYkWro_V=&ILayOWWs_aYce=&VgZjRSYibXVjV=&qDXUbKZVZYcgr=&XatzkOUZV_Vhm=&ZPOW8OUifliaa=&U5GGk5WhWmggk=&hk86MeZXrljUV=&dTZtmPWfXnfms=&dSbMbJYcosYfW=&aJCjvzVaX_hrj=&B3L7pWYjeskfW=<QdPJXUYmnWi=&ih79KvZmfrZnY=&o4jkvrWdXZnpm=&3UuYmJXXpVjZs=&4YX3yLYiWbqXo=&y82XGRYlgeqeo=&R2ZB_dUXjmsnh=&ItTX7zZh_oplf=&qgR6EPYUXmmgj=&S4clxuViaXddk=&7AokYZYci_eie=&Klh_lKWqbpYoo=&2nIvj8XmoZXle=&JzSBWDYoghgcY=&VkACXXUcZcof_=&csaRJQXjofiqs=&inHP7jXWZWphn=&sRik35UXgsclU=&zhBcjNZgqWkVk=&Ak4kbgUnqZWYd=&G4MqGQWgZerjh=&dYMecPZVesslW=&vVaCGMWrb_Vko=&zdpIB9Yrfmdsc=&V_anDsWXlZV_W=&puNPAVXfcflkf=&BVJctSVrZgWYq=&TrVqqsUscWsaU=&TCa4fxXk_ZXfj=&MClpXmVUdhhnr=&2_LVqFVaoYnan=&jYCjMuZqresiX=&ZECgkwVsfbsWr=&BDpp7gXYajUkl=&d7MrDeUbrjkhU=&NriRAGYkmgcXn=&pQeetIZdrfhY_=&82YGrtWk_mVqa=&MVRezvYbXXomY=&ihek_LUqcnrYZ=&pOTlaGZqdbWpe=&GlAUzeY_dUXjg=&uFMb2vWpl_lim=&KZV2CeXhcbVss=&2Pgds3VXkib_r=&5KXpc7WbesYkg=&mNgyh5YW_rhnq=&xx6qJmUfaUXkp=&Usbg4RWeilkno=&P7oMCUVggfXfo=&U7HohBUqjpnYj=&PLpuXLWXhhXWo=&8gbhPvUgkqeiq=&IlBtaCZeohsln=&MLMClbXnhmUal=&8kSlI8Ugimgdh=&H6l6e9ZjefWss=&NPTWZxUaWlkeX=&psqcDYVkZajXn=&mn_ZzjZkfmhaW=&zFlJTFWphVjUh=&I5DG3FUUXpYVq=&ngIXI5ZWnacWr=&7rIidtWhVkbpY=&w6Hzw2YXojZsY=&qexwsZZYX_sah=&Ukc5yeVWcXnZp=&yI9UP6WUVngkf=&xY2zqnXnpbYWf=&9iLUjVYlpoj_f=&vdsJo4YqihUci=&aIeShYYmahsir=&Vcp4xaUhXUdll=&PhrZHPYWZUW_c=&7qHJQpVlYcooU=&u4WuCfYVpVhod=&xqK6giVZUdjfo=&kqGEPAYbesXUc=&xg_V5IVeaUnZc=&NWDZc3UcrWdWo=&nbpeReWVheqcd=&LpRzwkVWqaanX=&PlhT8eYpZbgqX=&SVScjyXaUcase=&sSCfybZYkbr_i=&F3qlmAXrUerVd=&F896oBZmnapoa=&rJR8iqWsjoiqi=&Uxe8yfVrWnkaf=&txDuP6XdqUa_c=&gjTlZ3YjUcse_=&Q__JlJUabmqkb=&t5zZYdVVmkpWk=&XQ3WBKUbWUnhe=&UUtYGJWjmUmVf=&uRQ9cVXXYengW=&cvjOX6Ukjmbcj=&GpgN7eZgokYmU=&xKLibuZhXVUk_=&XkpbGQYoUbf_e=&NdnfXGUanUrXp=&EGq9wfUUkqU_c=&duIzTYWekjlfh=&lZZCvgUdqmchr=&ZeF_LHVlfXmdY=&TJazpTWmhrnhg=&4LumWPZoUlihn=&Rl58IOWrVXnnZ=&OsmGAqUjhnhni=&BH8i6jUjZUVqp=&98qltcYcigepV=&sxyinTXfZsVY_=&RTybjIYr_ciWo=&9b89a8YeUehZi=&3y9ZK4Zbnamsk=&e2_zYCYWaajnn=&xP8jE8VYdrmd_=&EAxf94VmfcWjf=&m4JKIoXpkogpm=&vhcV49Y_ZbkoV=&NH3AqXUnlnYXc=&XM3rB5VmcrYZh=&VAEFa8YfUinhX=&HkOemMYXoZj_r=&zMajnBXrVjojs=&dXeoYLYmWsUms=&6K_CP7WYpees_=&ZCaVb3ZWcsrfj=&kEs8IuYpWaWWf=&aGPXrzVdbqbnY=&PThoPoYosqqoV=&c2f_JeVafUalb=&bFIaThWleklle=&us72WaYegmrYV=&zpvZq9Xeersnq=&QNdwxPVlUbrWj=&rTJHDdVsUniah=&i49aZUUhdemra=&mRREEhUhqpoWo=&rB48RaUgUrnsq=&ReL3h8Wodmlha=&aCNpRTXXhsled=&2TkNqlXqWja_d=&rwUQvAWrqhfgY=&PkMmA8YdqsVsV=&VWgtshXarVjdd=&HYUS4yZslfslZ=&aYmeNSUnncYUY=&kfhCWMZUpgYed=&dmAkX2VZWno_r=&eCk24XYipjroj=&M5SRCeZoXignp=&AamMY8VXqahlo=&VfSpXHVgW_sfc=&UIglOhWhajiqn=&i8kTWOWbsZboi=&msD_zoYefUWk_=&g8PsnCZVVmVii=&7ILw7uVflnhba=&NMAX98VjcYjUd=&jg7iLHWmlcZqi=&qYdtUFVsVchsX=&AkCh4oXbUqUYn=&3LNtg4ZsefjZp=&w9APnSXfVbWYl=&CCwHNuYWirZfe=&oQgbHgUaXjjoY=&dtJ4_lX_corce=&E_pa9_WYierVm=&BsrifwUZsYZnr=&fnSGDfXcWdXia=&lhOqYvY_gV_Ze=&kaqcfkWjkadVb=&eJG5z3VcbaUfc=&_83VpHYWsdmjZ=&vPviofYodolXk=&fP4jbeV_hoYfZ=&Dp_buFUqpsqW_=&I4i_FGUrpihnX=&N2TTdCWjrarbo=&3zVqClZlgcdp_=&HgULBwUsVpqWc=&xTDbdyWYZmXms=&wQ27vzZdXVejj=&lqSADlVfiXhlX=&OXyqWcYVgfriZ=&_UvSkOYckrkaX=&6P83BOWsbcnoZ=&BFZ3WyXicVncr=&9LVzSpWbkkkiW=&P6NQFpZVeeWfX=&fHGylyVZrjZjg=&lurvkyXfcVseh=&mKLAFoVXesemn=&hA3q2lXdssnfo=&bR3dFKYqlksim=&R5FDTvXdmbZqU=&EvcBW6ZgigYql=&vub3uAWoleqmc=&T_ahbcZejiand=&NMU4vMZprehaq=&YsrvFVUhdajZh=&nZTBWiYUb_oqa=&FgxDrmWpoZhUs=&im8e4oXWrqlg_=&5w3j35ZUkldr_=&_YN4cHUgjdYdV=&dnGiyoXjhrXgg=&KUdEKeYnUednn=&PB8MjVYn_bbhk=&6UaSAEXdYWjWf=&teIKgiWZkscmd=&mTUHJbUUghajV=&eWFHoTVidYgk_=&ppCiTfYdlaZZr=&V4Vr3rWkcbnYq=&NcyXPKUbXZeob=&agsfKtXZYcXqa=&WHwKJFWnqXZZY=&EzO2XUXlqWrXo=&pVwZySZYdnnnf=&pJhnVAXWkqens=&YpFgj_XUbZ_sp=&FIdqDVZhsnkjd=&nWb5h7XUmrgss=&qZIiYKZrlkUqh=&Z3qEIuZekkrmY=&byKrJdU_UlUig=&isYyZwYcsmXdq=&Q6TWLnVXsWdoU=&mH2EdAYbcWoUh=&WiGEE5Ysjrbpj=&rmyvB5XZYfYoj=&snRKV5XskVrXY=&lTP_caXsaqf_s=&FzQmx4VZZgngp=&sxOKtRZbrlesi=&romvqzVkWXjYn=&p7YrZlVjjdl_m=&OAuktPWaYniZn=&4sQEv8YdVrpkq=&M_rm7ZWkggjZn=&sFLmnZUlkplWa=&C_6PdGUcjkdlj=&M2cAe7UqZorZh=&V8nJ2UYoXkhlh=&cUDkeSZr_jesr=&hvYZg2XrpqhnU=&OJVrb_Yapjssp=&hnRXaNZfqdrdd=&vrQe34Vkggbge=&RaQQ8uVW_rWVY=<F8qxWZkVrpg=&Gt_7QbXolZafZ=&Kmovf2ZjVWXgo=&DcwihlZXZrpj_=&Wv252TWiXohcb=&SOW5PFVXolYUe=&tDdOsWV_eYeWh=&8RouyaWknVWoV=&FMMuBOWqmfpaZ=&hTrwJRWXmdmqo=&btttaQYXkZein=&GxcLB_Zpgslah=&M6BNzbVZjssZk=&vp4aEuVcWagno=&bDgpfFZssWpm_=&eKOlOVYVloUcr=&de9axlWrZb_kf=&7Do9cMUYchasV=&47XZNyVshlVmb=&rp2WGqZmjUloh=&6_AQFHYUXVoii=&KU5EXeXpUdpld=&ShCRdLWV_Zsfs=&dp7RlpUaYgeke=&J59BR6Xlcgcbi=&DG3EJgZnapqdb=&WAtOZ3ZiXlXrU=&5R2uSuXelolkk=&Wn5oY4UcXjeab=&C_6CJaUVjhXno=&uuolDjVdqXdq_=&gIHJnFUb_kipV=&tPrw9TVsqrjlV=&nHWE3tUkadqYd=&_CmTSFVbkgkVk=&enNgh7VYpedpo=&VpwnmHYVZcdai=&oy2DN5Zeoaldr=&DhXsJJWkeWfYr=&q3Exm5XjVjfpg=&LO7BXoX_fflmg=&qqk6XjWWmrcpi=&OnynWaYXfdcZl=&kUQUlZVdrsmog=&5rplFMZXmbmoo=&DrphB7Ujgcmng=&4sSTz7WgpaZsq=&5L2sDVUbWhodW=&RPipoIUqrUZsq=&Jhfc3YVgqiYlW=&lum2a3XeakZZq=&bfd_TEUW_jZda=&V4G3jDZpcdYZV=&_Gjed3Wkjclcp=&6fBo3uUkmmbXe=&THiMArYkUkegm=&t7tuJIWfWhcga=&2SeYStYhpUpVj=&U_wafYYVkoVZf=&HWPAxcYcskqZp=&avfqYcZXi_Yqp=&FNeLTcUrs_Xen=&W3NAIRVe_hekp=&_idJDYYahmmWV=&reUz_TXXXmbnh=&eXRpTJYYqaX_X=&LsvuGbWVZhfeg=&9Y7zCUVmVbbZj=&5tDFgGUnqijsU=&Wrq3fvUXZXnga=&fRipTAVobbqdf=&gkPffSZXVhYjb=&73kSgLUjpfepY=&o2gtV_YkX_kqr=&eJqnATUdlUlkf=&dcCHqfUrdoeWm=&LShvdcVmbkadq=&QT_3YEVqYnpkh=&sn6OUQWcelXpU=&erbCpkZ_pUhUZ=&aUZKy8UsmZrof=&ug6GsCXofgikg=&vca_ZnZ_lgYYY=&LV4VzRZpaVjWV=&ubL3iXWcVnlUj=&zGrVxFXldefpX=&8YhuxaYonkseV=&Hvkex4UVddlqd=&Oq9zDXZl_fXcU=&DwjG8OUXsVZVc=&wzeuYeVqUXiao=&tfi6YKZchilgp=&OqPaMmYeXY_sn=&ZZ2Ft3Wgghsep=&Nc7wJuVfjaqo_=&RlHSPxUdVlaWb=&SVDwnUXVhZXp_=&BCGDbfUWWdhmp=&leZGWaVjYZnUf=&zufakSZchribd=&kGsrOnYirXgbe=&_MdCmNUkcX_bV=&yuuU_kUUWdZaV=&o_BKvnXXmcgqk=&zT57q8UpZWeZj=&DzXxnnXnsUllh=&jA2ll_Y_qfsrX=&dhqbsvYUierUm=&3hRnnlYqcm_iU=&gxeZoCZjsqddb=&L6jvvIUsckkom=&fy82CYYlVjjXr=&iBRYbgYZnodqn=&vvJrJbYbcrUli=&W8LfDCUUgefjV=&zLbLwAUaaaVsi=&SWPySnZnqU_ZU=&uUSOAmXhrebad=&wn4mOoXUYl_gb=&MgRk69XrVdmbm=&z2PiapVgeXiYn=&t9iGpDXmXZsbW=&69FZXzXiojUak=&aLNgxfXYbbjVY=&uFpK2sVsUhjZg=&B7pfMoWpZoVji=&8UFIcMZhoZ_db=&gFTtHeWihWdgZ=&myS2fPUiaXjhX=&FzRRTRZ_Yofgh=&LpEFD6WZmXkoc=&aJbhWPZhbiVbc=&IihsFyXrYVbr_=&jMnuIdVb_polY=&lksDw9ZlXoqos=&oQTbCDVXblscg=&Y5IFJqVmgeaWe=&moJ3TwVecbUno=&C3C37_YYcq_Xi=&2ZewY9WoXWbXa=&yjRPkdVjacolU=&TGbBVsUUc_YiV=&HNcpuCYqprlmV=&lfzNCnVhYngre=&pJHRXYZZlrl_X=&Ck4BJWXsqXhri=&aOcwROWUnnbsh=&kgpdFGUjsmYXY=&L3XgF3Xpdsfa_=&rypxjgUmgVcmW=&o9AZqUUc_ZcZa=&sINsFxUnqaUrm=&v6a3O8XeWicbs=&iue22VZmaqVgk=&taV6bjWhU_flp=&P_4PriVZijbdc=&m9pUzKZsrbqoc=&6SSgwlXfk_iqj=&uT7zBlYZ_qWik=&xEpoMaYh_Vi_V=&ou_7sJWiYpWgh=&OKqUZ3VhrdgYi=&BFhkYhYbaWo__=&PPYNJYXgdcfqW=&U6mRuvXglqn_f=&85RTRAVlrndsi=&zzQW2PYjVgmZm=&RixuUHVseqelq=&Wv3drcYib_kfc=&BH2RorVeqqqno=&yjnVrXZgWokl_=&XdLqSXZVihcgo=&5klEQqYUnUqje=&GQlyotXVcsU_n=&rzjPXSVhXXcfX=&CeexYtWebUkXX=&c85PGZUgfrmZh=&J7UrOOVWVadlX=&78mL6fViZfWhZ=&8SDINkVnjmmgl=&ywIoWrWdX_hjo=&Mmn6e9Xa_WrsX=&BrWUmcYbsfhhZ=&fZeYeDVkUVl_j=&9GXBbNUZmcXde=&NfYPvvXmpkebV=&VZp5xzVbomXWn=&PCrlieZeammiV=&8JOFWYUslXrif=&Zns9CbYWhc__l=&TUh7bUXqqelpn=&ZSVryfVXnbhpZ=&v8XvP_WkaXhs_=&xKoSCtUlhVcfj=&d6J6tXWpiiVdc=&TyIQIbUlZdinf=&nS5ADFVXgcfch=&kU5yHLXlcscmZ=&nqYKl5Wmsmirq=&o4cojHXjZ_icZ=&iQQsMDWihWd_W=&xkuGZ6YnZcirb=&DS7_oLZrnXpgg=&RIGkSnZfongqe=&jl8gb9Z_UXpUo=&42IPJ6VgljkUd=&eIjtoyXsmidgl=&_upamVUcZgXhU=&pvhdDsYnZYYY_=&DomtjBY_ikoZW=&TupeNRUdeYck_=&8WR_H5Wc_eYlX=&T9YTyUVoimnkp=&EoRld_Ypif_ao=&M6d466WdkUeaf=&s_RjjPUlZVbWl=&RcCjJAUghdUbd=&JMwPezUZlUmYe=&GgZuFsVrroiVh=&rjRO35VgfqepX=&6TYvCiZsnsZpo=&7nHILsUafoiqV=&xFJQq4ZYhamZW=&_kLr8WVrZooYf=&eVeROmZlcllZ_=&NxsgggYgbjUrk=&JwHxypWUcodXl=&nmjfSgVYlVqgl=&OpPA9PYXhkXdq=&R7awFyUppmcif=&AYf4LuUogaVjq=&pNMtLdUanfVgl=&5YFwwCWUqgZaV=&4QL7NSWWWUcfh=&pb2FaBXcgiVsk=&H82cZHZmVUZUV=&RwVRUBWpidjXj=&AWMlIPUbjmZlX=&QwCLayZUicVYY=&PKpFvQYasfose=&Q_tqRlYb_UfZr=&GkQhNiVjfZsUZ=&qv_egCWibVrod=&AbwERNZfYmlsl=&lbNTjJViWqiqk=&77d3nBXWcsZZl=&5xcjyWXhoWkWf=&ZmG3obXbWqcfs=&72Gbf4UflX_nj=&hiHPzRXYhVhqs=&Iad246UWpbqUZ=&GB_84SZrarlbl=&zclOn3WqqWiXZ=&seTwgsYfYhpah=&7BYZiNWdZqshd=&drvbV2UVjbjml=&ndSqqcXWgdsir=&SN25HZVbsqpae=&cUDRZeZfmbqaV=&kQTOKSVmVgsld=&oynkWIXalcVda=&fT9FmkXodgZcV=&yLV3AgXanalii=&n_wggUYZjZfYm=&XTUfgWWrchaaW=&7LzXziUhWqZcr=&eyCLLMVlXUqoi=&fwVUIkWUYemYb=&IfOszuYgicskV=&_4Yb7VXgqm_il=&JnTTjzX_ekfeZ=&3IuWJ2YcjfYgn=&yF6JYKUVkaacf=&ArSdzFZ_bVYbj=&NkePfqYgmeiWa=&94DusJVjprcsc=&Znf7ycXVqYjmr=&GDG8KKZXUaYkd=&Vhl8XDXnYdijf=&82BTCnUqcleqb=&NZg7ZHXgamUpZ=&uTLG7TWVina_s=&G5PpejZmYr_ke=&wJYwsZVdmplaX=&jodRVlXbs_gZl=&chWGPuVfpsbUZ=&VqboQ6Wnkfk_m=&L5WP3DVnmUXaV=&kNPYMSUabUmjh=&Ksi3NxYaqiiYf=&GZMusPWaimhXp=&mqarRiWqYjWic=&VXGHeaVWdreWZ=&habnNSVVqccpc=&A5YjAoUcckhsn=&TWqlZZWiYZ__k=&yHX7vJYbfjrh_=&mSkf7RUeZgmsY=&VcrwL_Vfjinff=&4DfmfgUkheodZ=&Yb6IQQZdfXjai=&yAXxGAYkZgWmq=&c3d4MFVbibWkl=&T_5_B6ZagrdUf=&QpoXbiUfpknip=&5PRGfAUnlnWYb=&fv4gO3Vak__bc=&DE4HsPVrnZhgs=&__N3rDYVYXijn=&KzkjJZWhoheif=&uQIFnkYrsflWg=&uCjnIEYdrqiqZ=&xWvH5pYhWVdaq=&Tvyw9JZZjrjpY=&Bi6xRQYdUWqki=&Oag45TUXcscYa=&SP7b_OWgUhYqm=&XfZQWDZjcmqXm=&j2xjZAZehimsm=&e72NCUVabWVko=&AxwruxZrlnmok=&2XnpxTUp_fgjc=&bP2mHxXZUiqnf=&2NqBsiYpZesVb=&Dk35bsWspdfsq=&zNrKIzUpdcZme=&ctd9p_UlhdeXU=&EdPHYIUl_meVW=&7H_wdTXVpoara=&zka6FVWnge_jp=&7wOn8dZ_mWmcj=&GsfAZCWnZkXpj=&ZX6mejWVldjqr=&S6wonjZVbZYVb=&LrjuqJYWiUdeo=&LgGrTbWZjeVlb=&w9ZilfXmo_c_f=&RVoQABWoUh_Yf=&8dnm4eWmqpZ_p=&q67mz5XmVbqll=&2FS9U5XjWc_Yl=&jCqdtXUZmcmUm=&rSQVCbVqedqrZ=&ENYdDuZimUape=&zjQ4CSXmdVope=&4qwh97VW_cUmc=&vvZT6kUnabqfX=&2veSv7UfYZqVd=&LKFQyFVbfbskq=&XXzXEVWWUgsqY=&JW3AG8XijUnk_=&d9XeifZnnecef=&BTccCbVVUoUUe=&5gUbfiXfsmViW=&Oo3ZCjWibnged=&zg4hNCVZYhUbp=&UjxxapWhZnrgX=&qaXmaSWqW_ihr=&zMddXTVXmdqWh=&tx4K7RZrYfUkk=&G3ykwfVnh_gXg=&eYGX3OZoqagjc=&nIwZBqYnleeWg=&Mn8rs3ZfhpZjY=&koTkMCUaWmbnY=&ps3Gp8ZVYUYme=&nOOZfcYbUhWck=&qTB7bkYnkdfVY=&jube9rYdUWoVU=&EZkGBVXhpsnrV=&x7xnK2YaYYqZg=&3XiMKqYXobnUb=&9kk3QxUXapXeZ=&eNkvhwZWglcso=&taKv5gZeqgkqk=&8W4GlkUcfXgqU=&Yx55YJVjab_mm=&9PsWbSYndXcVb=&WICGFZXrjqpXm=&Sh9ZL9VVYXkXi=&ttgXdAZaaYgZZ=&mugmwjYdXXYhU=&z8pvKfYdp_gmY=&Wam_7MXecWcXb=&t5oL3hVlZdlqr=&cQU44BVWa_Zga=&YliaRzZXamZmj=&NwedrmUoqUgWk=&lpquBIXXpYi_h=&B4FqfoZddjpdd=&PQzDQ_WmVVfad=&3SRtwSYYXjdms=&yosk2DVYnYfXZ=&eT9MLwValqeob=&AzvULTXmVjcUU=&mGMk5lXiWgmkh=&ZVVKTxW_bWqni=&I3QawrWZlr_Xq=&HKK9L2Zma_ghc=&bknnjtYc_hhph=&Pthnx8ZfeoYhi=&wlTqIFVlifoXe=&9FGkMzUjV_eVg=&yPi2nTZdakpbf=&WIiN2tU_dbVns=&ygZ226UbooWjd=&5UJpbUXhkg_hh=&sSIpOzWsob_c_=&r4Bp_UVcXilYk=&59n4lOWipilsY=&jWenFVVgZ_Vaa=&EeaPF3Wg_fdfo=&9K52B5VWXdUsg=&mT2HcdZZcqjrn=&h3qq3RZXlopcX=&H9owXdVqcicb_=&dVwbioWdZ_ifl=&B2Ut8rUZXncpk=&QVsn5bW_gcjno=&NOkvgxXUapilf=&LlNj3rW_figXq=&LBQppsWhXXqoa=&i3LluwUomfUqU=&zZYKEqVgliVhX=&29f8aTWenqYom=&tTYbGkWWhjiUU=&rkpvIHUpkkrij=&f_7_rZXl_bpis=&YFcDscWnZmZbj=&MWSRfXZlchpZV=&ZoaR4_VgmYiba=&e5WsWVWgV_sXc=&YrldldZdelilW=&PbotqrWUUXVsp=&myaxJWWlpVXkX=&7kPIlyWirkcjf=&BxYT7gZka__nY=&AArDcDZpVprfq=&4LyB8cZggkbZo=&bKJAttYjkgZ_l=&pPsXflVhlXhgb=&F6a2rmXUmYbgd=&ZkJWPuYbXqhpg=&rncnN_ZYYlqYl=&JjsfeDVsmad_X=&8kFJxxYeojmZe=&7obznjZdXqnZU=&TBCsyIZmgkaqo=&PehI9ZWppgkXn=&AAl9PNZesarfr=&D7GPFPUshYrda=&rDuCgeYjqqssi=&B5Hz2sYX_ZllZ=&R7MghOWXgXZqi=&6fQDfoVkgsesU=&4w7MJSXs_eqUa=&HNnPaWXUmWseq=&KPjKyTUpkokUd=&2Ju2tWXoYpbXV=&L8_o_cYmjahgd=&NrXscCVdWiabZ=&NLmYJiZ_nfhph=&SKLViEUqUmZpb=&p3m3kWXVnobmY=&JtEKjfYejjVie=&tCoDLCUe_kUVr=&LLzljcUol_WUp=&FzXipIUcnhnXj=&Y9yZDNYcnXUim=&ERUyHyVqoabjq=&qYceVlVceYdof=&JexyDcZXenapk=&dzdn3eVlmUsXo=&GOwPcHZqX_sVa=&rjxJfGZgnhZm_=&SxuEOtUrfgfdp=&PEle9qZkbXrrg=&dAQneTZZ_XXmq=&yyZyLQXmo_iic=&ChdCwyZknVhpa=&A_NJeCXknceqf=&CnXPTXVZXfYic=&q8rviEUndjshU=&taHbFgUhcslha=&yZdmlUZm_plpU=&SsIq2XUeadYsU=&bTEBoMVnafUUd=&_dpAHVWlgdjY_=&vELqfdUklseos=&Mn7CouZageWid=&mGwV5GVnodbYi=&oD76EXUsUYnod=&NlbdIoZla_bcq=&_DQy7mXWiUork=&FiLxlaYYUqnYe=&axTwNbWdifUVs=&2NonKLZamnsdo=&dNOWzFVdWmcpi=&krbGWiYmbWjZq=&KxmyyoVosfieq=&RlcjFXVWoqiqX=&EKJIJXZVdqaod=&m2Gt3MYrgpW_p=&8CTvFaVcchZmg=&c94TkUUZgYaZj=&fF5yCVXdfpipn=&MicdkQUei_kXp=&t9AIwQXqXkYeY=&cZcKrIUerZjec=&vxXK3kWpknggc=&nEyfoTVUa_gqj=&Hu92p7UsdhWXj=&Wh4Ra6UahpioX=&WVdYA_YcjaWUk=&tZ7LdMVqcVldd=&9mZqLuXpUmohW=&j8YDKwUYgZape=&_2nrgXXbqaeYp=&2_5JZYXekesZi=&vHyKFTZjcX_Wi=&hw2YorXsdXfZV=&QZhorOZlZes_p=&CB6e_CWZapfld=&aAHAPBWbppVWq=&PUlF7pYXYeYlp=&D433SiYcqahZl=&wrUpPBZbongWY=&rCgBWdXknsabl=&qvPQfCYeiqao_=&jBFulTUeogn_b=&N7yc2eXfjalib=&xtrQCeZj_qdsh=&GWmxq5VXZmnaa=&jRTBtUUfbnjhl=&iVnQFiYqljZhq=&5JKG4eXlWggib=&UXZ2PKUqYWbW_=&HJsnO7Wsslsde=&Q7OiC_ZsXdsoW=&63X7iZUVZkfob=&w39GArXWmYdWs=&P6UHsDVjnVjpf=&GrFmn3UjmVo__=&BITYxGZZiXXs_=&yKZENdYcXldkr=&HTXMWjZklgU_d=&jmENOzYnVcUnl=&niVkJKXoXXqdU=&eVc8JcUfenhgr=&Ggzs6HWUlqffh=&T95pcxZedZaZi=&GVgHgLUVe_UVk=&C_lDlaYhkphXg=&4LVu6BVqbnirm=&9_BrPSXamcUjg=&tWGt6qZVjjfgb=&w7Wrk6ZXoeXZV=&fB2tOyZoZinZr=&_PPkeLYjVjfbn=&QETL5nWpsnoUY=&WzODBLVWrWgid=&NstLRnWqksrrU=&FgaCYiUYpikrq=&IdN_ElYroeYjm=&HWRZiiZhUhZ_W=&nMtVI5XepaiUq=&Llu6fXWXYZogg=&49aUlqXimsqUs=&FTAgnCUfqrqei=&lErvg4WaZUVna=&m7kueuXnlfeYb=&DJ9rGBWWrsqqU=&XsCeSKWjXpZmm=&eMpesHUc_XafX=&dT2lIFVhWhseV=&zJJFYPZa_Zjj_=&VBUjhWWsjllso=&boQM2MWUinjpg=&xpYb2wZgaW_bf=&h3TcW3YqWZcem=&9hQH5eUg_mbUc=&ze8GIKUfYjVce=&ECkPlYVdscnYs=&5aF6HjWqWkXhV=&QJvgqbUYaZeWd=&72YLm_ZeU_mac=&xLcTjtWklW_gp=&N9_qOhWWVqprm=&jf_4VJVe_bagW=&je9yBeVXjnloa=&OhifVlUaqXXef=&w4LMGZUcaXmcf=&96ZUNLXYgeXpg=&wvBBM6WjlYqsd=&g4izsAYYb_bab=&EcR5gWVlgWohj=&fO8n5VVeUqXer=&zYLg8fZmeZpXr=&Dir84WUolmcnn=&wxjeG6VdddoUY=&3iugJGUoUkYqg=&5dN7stYfZkfhs=&arHhhuVWbarY_=&8PWXqyUkmfsja=&4oaAONZpoWdq_=&_PzQu6YpdlYaj=&oFT4QNVaaffjb=&AzV9HfZbelYXb=&dyvQtMX_msfbl=&nlEmC8WZUaVZh=&AM5ZXFY_hWifk=&TPrzPEZcdimfZ=&sjed2KYiZXkjV=&6BbrJOYYlcpnp=&PJkSLHWVdUsqf=&cLx6jAZsmrokr=&hDIH9pVaYlVnb=&NU69iHXoarVod=&l5ro64ZUYmlcd=&CwiQMCXaheffr=&nYIYaiWdjfZZf=&vvCnNHZUll_oj=&I2eVDyZVebade=&UgKqBMXXVgjmq=&9IPd2xYfjZYW_=&kMItwbYpZdqln=&uRZW26UjdXXgp=&uTsgndYYnsqne=&RolSgvWkbXZif=&pH48AqZgeXjea=&V9wbuYVsUejap=&WYJTFdXpbankX=&5VOPfKUbenjiV=&srZ6xcXesWoce=&SwoszeYohUmhk=&KjZXIGVnq_dja=&cmGKjNWWlUoms=&PfvNruX_UYedU=&YnOgbDZUjXZg_=&5K5qQ3YhXlpno=&PuJgfrZdkkYZs=&EIAIAiXYoWqjp=&FAzY8LWeZcdgb=&HbgqpxWfVgdkm=&7JjWhYVllakYd=&6MJDqsZkqpkoa=&BXsAugVZikjVb=&XqsOGsVs_oblr=&UkAYIuYgqkXmq=&HQdJW7YXsppeZ=&dGCy9VUsqlZgV=&lOM7YfXYfmZVX=&PLHFhGVeWbbmX=&okywJ6WdamcWm=&Udjbs3UpldhXd=&WmgvCCUWnZbdo=&SEGQeaUUZrskb=&X4B2OVWi_Wogo=&_q7udgWpbaXfs=&otaCllVWZj_ob=&tbjRGBUYYUkcc=&ZZV9YyVYgkcYZ=&PON9dhZYmarcl=&kSMqOyUrhdlZW=&sN3Q2NXodcrqd=&A8Os6uUnfipgg=&7kL2EaUlUaqln=&xxyGf2YgfcrkX=&YVViptUrUi_YY=&P6flgNYohUZUk=&IqYT_qXXshbln=&G2swelWXddWWq=&_MqFHBYrjqWll=&_oQXKzYkelUbf=&QRZzlxYanmUib=&smEYTHWbkccZV=&DOfs5tVamkeYn=&kHdTgcYXjeZor=&w7gJTrY_fgdlj=&3sUe6hWnpVaZr=&nM7GSQVmiqkni=&dr_jFjVbhep_o=&cMWrBZUna_mpq=&aRnTW8XkUXmni=&aag6ZbVYYYVqo=&cRmOp9Vmigjpo=&IhmyqTVfUsloY=&pT8Es5WZqYUWZ=&s8fFCOZVWl_Ur=&29_LwPVqUUoZm=&kB3g8RWdpbfog=&DfWrAaZUolUnh=&TZQtdaXpbqVhY=&KowVBeZfldsWh=&Ir3zwXXaYhXWb=&PRd6sVXZnYgcZ=&NRvWL3Vjqcjln=&3wlvpcVcddVoa=&BIdMIsWnacmhh=&QNat4HWphZUk_=&b9IJzVZniVnop=&6VvrRJUXVssid=&nDXDi3XgbYjhj=&lu9mp_Zciejop=&DHzDzfWXjXonb=&iVivXXUbpWhgg=&hstSxVWWlWXeZ=&yuyWxvXsbbsqk=&hEL_qFUoYqjbi=&5Fk68aXqiboUW=&rdbCKoZqXkipb=&jOCEp8Ve_Vqca=&9alF7NXboVr_q=&oT2EfXUsYddir=&WquW4qVkpfagd=&zOzNg3ZZredec=&DrBensYdhemoZ=&xn4TwDYUWljrV=&D3JUXEYXVUdd_=&JIlG9jUgVpd_l=&dfUGZWYnqdWie=&UsQfAtZVWbeoq=&coyuTFZnWbref=&ZZAXkFUiqUZfp=&nQwQmVVqjVhml=&SmvDt_Ympbpdg=&ff9OVtVhbnfhn=&FAHHwKXg_aWfi=&T72UfNYqkUgVY=&xKtfiBVqphdsZ=&pypBigUi_qpoX=&amYqY6ZfaZUnY=&obDOy5YjUqeea=&JOBAPaWVjWoVb=&UxkCpHXpUopXg=&VVpX9CXsrasor=&cyhym6YlfVWoe=&afONOUXnUsjdr=&CviJJiXemYeqr=&EmXPLKVeaYaji=&_HLqJzXmUgmcU=&_33TSwXVbbmei=&gYzxZiUVsZjbY=&z4tz9mWaWagUp=&sjoMldVkba_mi=&n_EB7mVeVl_sW=&x6siQFUXqlmXl=&gvoy6EZVdmjsp=&ACRDYFXgmsZWm=&SGXdOvZeegXWm=&pQvPc9XVcUhWj=&TwOT_pWXrYlhW=&9VDsUXYeVVlgp=&KX6Jz_Z_U_YcY=&Geka6tWekrmma=&_aL3IOZprogmb=&StnVWBXs_Xrcs=&WLzZx8WYrmpok=&KdxiGMWrqiicW=&8F7xx8YXdUaWo=&SGr6YvUgldYff=&upuzirYelmUrm=&il4Is9ZdrccVf=&ARfLuyUfdjfqW=&eVRLwmXopYhZm=&5wOMqmXoWpgrq=&AraHu2X_fhesf=&Wqq5HeWUahhcU=&2MwZCoUVlXeYe=&f3CjYPUlngdbs=&96ZV6nXospldW=&VTtLp8XUUlnsq=&OqEn3tUjidgsb=&Gm336gUXmgacp=&UEESbXXm_gkcc=&lhG8ofX_qmXXa=&Ewlin9ZdqUpUg=&8jI_tVVbklUlh=&72l6mUZeWmVZl=&XxGH_fYWjUaU_=&8NMhpEWYUYZkW=&AaKDmTXYgpcop=&IDMRtIYh_bdol=&TYABOsXbbrgsj=&nEygIYVYZrXqc=&yapKaZXnnheef=&ljYZCgXofXZfr=&AU_JrmWrskXds=&9odGhmUYlVrk_=&fDcc6rZlfqedp=&4B4Jz8ZjnUWc_=&z6wBatUfqWsYq=&mZmVQJUqdjc_g=&3StsRzXWgbkWg=&eua5TPUhadbgU=&yvjdhxWlVbnrf=&AaikkWYdZUipU=&HUet2NUnajgVc=&YULw7DZiferkU=&Nk2rBwWnmi_ss=&LYXIlmXglhbmo=&62MRo2WWWspWa=&QjRvstVXboVqb=&FTm2qpUdphfcp=&QeyRJYXhmWl_c=&QpHvMcXknnpff=&bgLLQ8UbYfdhd=&DWhmFxZekoipZ=&uAlv2kUcfncmi=&gadfDOZUeXsYU=&5suuxJXnigWel=&fACHjUVdYjYZe=&OIDUecXdhgggn=&LaiLG2UgjfUka=&MGrAQ_UpkYkp_=&F4Dk9yVcdikpf=&9BDcxqVpVrrkj=&zeMCpkUjkiVgZ=&qhCuXsZmiakge=&jTaLdzZnomjer=&BhSI4SWbbfoaV=&5dYD_bUXnpkWh=&kQBhWvYUYk_fZ=&nqMG5cWkkXcdg=&uQGZaaX_mVqhp=&zIJF7AYcggdla=&B3tKpzWUlnhnr=&CxbpEGZjXkdnl=&a9GyD3YdVpbka=&YXk49WZacncgV=&JVyOOcXWVUVaY=&_iGVJ6ZXXejss=&9QHGTcYYrqWnV=&zeYS5QWsnnZro=&GopvCnZkajkfh=&YMWgDhUjepsgV=&2tOITWZppiYiX=&b2RSdJUsbbpWV=&A9exf9UgVcUkm=&D6wvHPY_fdZli=&wzLnjCWkhVsdk=&mZ328qYdfhqkf=&LYKeRwWoZYmiY=&XINaTKXZcnZZb=&BUJFJPXYUphjm=&lsTR5dVqYWjXU=&7pWCMxWUepc_o=&sX5CyyUgaegmi=&yeKPkwYZZdccb=&9rYNrsWWs_bZm=&QXD3wkZkcjXsW=&dTXPgSVcZgpqi=&fBgrHQWmamcoX=&euo5eEWqislmU=&sKbR8bUUpmXpa=&ZrEt84ZpZers_=&VETumlUr_UaVq=&JPJa85YiUikmZ=&KKQCSmVnUjomq=&6zfInDWnrknsl=&JTS3HxZWUbhrh=&yMKfYYZlYZdog=&akDXZPZfddbme=&kFzavuXcomsVg=&xcakDGVkiidVY=&bePgsvUssiXeX=&eqqAarUnVrhYm=&vnRqY4WXdV_ee=&whqLQuVVscqlU=&GCkugZXVqoZUj=&jJw53jWfdsnfe=&ubTOEoXYooroj=&4IYuYLVsrUqr_=&6mHx4eXlff_oV=&vHnl_uZpXbUhs=&_V8l_4UUk_gfm=&Ssrm9VYVhpbaV=&DtcckoYfsioqs=&q5oxYdXmhcYir=&gVMHAYZWlUsVe=&sugoWGUmiWela=&Sunwa9Um_ccmc=&LUFPQFZaiZYUV=&LnLLbyUkqijlc=&OJSpgbWZqXck_=&8EI_LKZVXZlZh=&4BJ7IuZeWjqlZ=&LQh64ZYhVfXqk=&p5NtgPXfUXUcm=&zD56E7Wbncmhr=&EUebYGVqWUimr=&GgKLERZqjroog=&g6_xywZdVcsfj=&bL6IDDVVgYrpg=&6WhdijZlU_hdp=&OYpSIlZbnpera=&ytodCRWlZkrXe=&Oc_7dpUnfrsmq=&3J3Y62Yhagrka=&IhvEdlWaepnVm=&yn3ivFZnocicW=&ueytXTX_WqVmY=&n2JBboZV_qqUU=&HCCRjJUfpfheh=&Sik_9VWl_Zpfg=&u6rOznVYbXcqs=&fevBVCUobeWrj=&rsMIURZsYjXY_=&4xi4wYU_eepaf=&Q49GEvU_qVVnc=&oeWqdOYnWpsgW=&wSpxDEWZpWple=&8ok_DUWmo_WZ_=&5JKyvuVigZbff=&PtNALIXoloqUl=&Q995wuWhqrrqm=&TBEYjdWmaUibY=&hp7QIIVrkgkaj=&7JKHkSVrpig__=&2nJOcGVpVipWs=&nCWxNkXYYb_kc=&ujVeu9VmXUgjY=&rJheVnUdbisZd=&Fj7hzFZfrhjdW=&V2vbpXWbVrWUo=&v8RwE3Vfcmfad=&hj7U2QYWbfsW_=&h5x55tZrVahqo=&pTOpK4Ws_cqXo=&wx3mcHZehcgaZ=&9FDMEOWpZYqYZ=&XZ6LUdWUsXjYs=&gA85vpYnljgne=&nzXWnpViXeqXn=&X5eMC4UjhYqej=&UXOfT2Xnommrk=&GvkN7VXfoUlZm=&kkLflbUbkjobi=&XFHPmtVi_karg=&YxHjWSZrdprXa=&vBMlBnVWgZYkW=&2hB9JdYcmrsVs=&rE3mgHYqmrpla=&bi67pUUjVkhen=&EFDWItWhZhqho=&qakMmNZhjei_l=&Xel8e7XjVicsZ=&8d4RP4XgiVmZq=&EWJ57NYUbrYqr=&K4WnAzX_oo_id=&zVk2HFWidrWnr=&zs_6YWUcdkhnc=&hlYpwwYZYfaik=&kphShmXWsgXdn=&qoCGLOWYWrbWq=&fFAzKMXq_aXld=&OiFKKAYndafhc=&_9FOQ_U_Uadda=&gckZDIXniWUng=&c6ZssHUaqppXn=&S2XsKzZgZn__d=&RhgLazZor_meh=&G6Wt_DUngWqcf=&pYxhNDUXcUhmc=&oEvY4dUdqiooj=&VGpdLeYrnflqn=&FzSBhZYhiaYeb=&532ZcqXmjWojk=&fp9zO8Vrhaenl=&fSQLoFYnjqsoq=&DCLfYdXs_ep_n=&BvCIKIUgke_gf=&jrFgDmZWlVcUe=&akAdwtUZrqdbf=&ynMtI_Wblasf_=&4MldP7Urjri_m=&8b_hhIVoUcreh=&rTixUsXXWYapZ=&dlDwuNYbgXdVZ=&64qFERVWUjnoq=&EP7BQ3WnchlVX=&9kyxrhWUfmfoo=&6HgkpKZYifWhX=&rdB9cIY_ZZkdh=&I_28UvVjngWjW=&BYaDQwZjlqegq=&z9niqqYnnrsjd=&Dbj4ILZgscr_o=&9thgB4Ulejchg=&Oc84trXWjpWWm=&lgPEPZYaUjcq_=&pE2zniWsUqVbV=&6hYUE_UYWgmcl=&ictu8_Ygjl_Vc=&vYdFxNUgsqgge=&IKbO3oXUVhimX=&x85Gv8Xd_hpsf=&jskzMHUnocqlU=&5RciH8XqVncoj=&fiDXEAXpYWVer=&4xdfcJYebabVf=&i7rpl3Yfodmoq=&o_6K4RZolclnk=&h2hA95WUpsYpq=&IKNf6TWeeaWbg=&aSFPxjWUdYmbp=&4f6EAKUVXdfnZ=&Jh3wvJUqpgbVW=&sOT5a_UnrUoXZ=&HfTUOeYnncjUd=&n_7JsWYnqasoc=&4_sFiqUrmqcca=&BG3xdlVdnkfUf=&mM62gOUklkoko=&fZPNtLUheZsZs=&JnvMGMZbqgocm=&Qm3TfKXmUga_a=&hRFZ3LWdlo_km=&gbwLbnXqnhemq=&YWTVlsZjsfrVh=&bJtjj9Up_fmlh=&hzSmlpYogeXhn=&ZiLIMrUgm__Zj=&Xx3hOhVqafnrl=&dCbYTEUbqosqj=&C4T54dXfosoml=&cZD7AmYnpenmY=&AvjsmaYZkjedk=&omTFDwYUsWaok=&N8jcovZnj_qlh=&vK8o99Yreckrd=&u2B6UcYrblpXd=&QNrbRDUiYsaio=&AV2P2SXYXq_nW=&lkTktoYUXWglk=&UkBFE_XgocosU=&_LA7B5ZUapibs=&G3lUtIWXfXbeZ=&DRf2rsVchlXsa=&76XfdJWeklkhY=&5y99f2YcqiUri=&wU4JslUikblqW=&COzo3xYffWWjq=&nMCOrqXrmqjVn=&naeaZ3Vfjcd_f=&tDyPUrWfYomVl=&VZK8AHUcqUhUq=&wOBkuJVfgca_Z=&eN_4jaXloiZWZ=&_TSVizZgmfYsc=&NDyfgsUeXsbgY=&VKwlsGXmonrUo=&FM8A8hUbVsmZq=&RXmml_VbopmgZ=&BdtjFuXckkphd=&tSGqcYXafWVb_=&AowpnbVpmloed=&NEsOTYU_aZjgr=&wNUHs_VhnrXsa=&RTVoW6X_YXqdm=&vaQ9omYk__hsh=&ELHq9nYcndUXb=&EEFafOUaeWgWl=&rFUrMZZmehmlm=&B4Pn44UaaZUoi=&CLlIK5XdkormU=&nMnUjmViUqZld=&XpfN7oYWhbZsc=&dxlrCnZUdopod=&LsyYJ4VfejYnU=&5lCIfzYqddmdZ=&og2y8gWkhspja=&63aWNTVdceqhZ=&YN3Kf4Zjqlegb=&Fon9KFUaiVda_=&OSB_QaWXpsUic=&MPqLpAZplqVYg=&SJs2IzYbWpcee=&6r3OsRUqVUoXU=&Ie8q75ZVYibri=&WelFquVWh_qlY=&spOdqsYYhWbd_=&ju2_ooWclqWiU=&NfrpSbUcbXpgZ=&szFcgqVj_Ynks=&KqIV2VZmpkmm_=&LBxvk_Zefbdbg=&48QQBuWsVUVlb=&BVkESqXlZfmpi=&3Bz2GNYacYZnZ=&e6tTxkWnidjag=&e99KhVUpokcWY=&duaVT_W_hr_om=&TTJ2vhXka_qrf=&GIqulJWjqfWsb=&6jx8xoWnUksih=&AnawNlUWUaVWj=&ls7pnEUsUlnrj=&_3vPR9ZpaYmo_=&7HsvWvX_WscUb=&8fbTLZYbmWjZk=&_eutx2XlWrUdW=&uu9PCkWrnmdXg=&BCTwsJVc_qafY=&wKAX8PZWjYiWW=&pLTGkkZqXle_n=&uiTND6UdkeZfo=&rBTz8ZWWWggZU=&JJsaniYbmapo_=&6qGwTPZkXfapo=&GGTJToVrmUYaW=&3DF4ePYnllpV_=&MGTVHYVZZnm_q=&zmMuDvZong_lb=&FZMxKcYrfg_Zf=&XjlBUEXZU_dlf=&pQuWlkUYdbnbr=&28oSHVVWhUlma=&lfOdlGWWcrXoj=&Mq9T8qUfododm=&fVbYoCYUpaiha=&mHnsm9UlilVnX=&GPrETkUaWdWXg=&XDudoqZngbZeq=&ktJC3HYfpeccs=&fcJDBsUXkeYkq=&2Z_ayKZrrkmhb=&7OVawkVdreoWZ=&QtSBoqWb_lXjX=&jLKWE4Z_fmcii=&LSnLgHUodr_mV=&ejY_xgYXlWbok=&QBCYf3XfXgraZ=&SBfmesUZlrkge=&KgtSrNWforihb=&ZIw2mdUnqVlVc=&wzsbFnXfVeqqq=&ZO6wr5Zceqpnf=&2gMrtoVnegbip=&HWn7ybYXWgkVU=&FNlj7MZqiaWcq=&nF2GOXYipemai=&vu5ZaYVqUfgfa=&oDXN4WVkcpZYi=&pLXokjZceoeWq=&hlO2yVU_pllUm=&h5RycBUassiUe=&MJ2keIWneUjXi=&mECDFOXkXjrhW=&_3ANNeVsoWhkZ=&2gPKLGVZnqels=&NqAs4SWYbgrrU=&YW32EjYioYcqd=&F9ddGXWbebghg=&R7Ok9ZVVYmWf_=&BZG6dvYsjrdUf=&7UbzUPYflfgWb=&bn2Kx_WhWfbjn=&loDhVEVbUcZUe=&Ev79MHXsjeZbf=&bMXAebXjVhnfg=&TzQKrBWXakbVi=&QHi_p4WfarfsX=&giH6g7Vjrkojb=&pjhCCdWciXinp=&LYlMM8XicY_d_=&wIhKolWsgilge=&TGPlLOXoVjdYl=&R7VC2BUdomrcZ=&e4YW_AUVWncec=&UIlXlzWsr_Xle=&RkFMonZbbYfZl=&fcU65PXckZlde=&fcvKoHUjUUlYg=&_GFGr_UnX_lqU=&NSD9_4XUYWood=&EkjKdkXnskarg=&Cv_RmrYmimcmg=&dI2Zi4WrkoZXo=&QG8kSQXWa_qVc=&l4gIGhXlf__Wj=&lOoTzrVWWZgmd=&26PwCVYYgi_rm=&4ZqeH5Vpd_rjn=&z3IrHSYsdssqn=&HDBZiFZsplXhp=&Ej6ioZYjXXnXX=&_d8MsNUYmnjZd=&dX28opXmdfVi_=&WgkuhyW_norkg=&5rDgRNZYldfah=&2tt44zZZcfrVi=&HhD7hRUd_srW_=&e3yT2sZY_X_ol=&SRXKkhZcslrf_=&nfANHCUo_rkpl=&IDUbtpZoaeWhh=&kLnaApVZbjrne=&d_lbPHYfrsopr=&grw6PkYjWXWjd=&X6ygTgZchgprc=&Nqkmo7YdkcjXX=&cOJsYwXVXsUWh=&iSsBaaZbbakUd=&TqvwAXXYnhc_f=&orvkZ5XXWkYks=&6jZJvPWocV_nr=&3IKskRWga_as_=&LeXM6MYUYWaZr=&_yEvSSVWVgilZ=&ZOhjjuUfkWnlW=&aj5JilZpYlUfU=&b96RQoVW_osgp=&ChhQ5DZriWifZ=&GkYJjFVdfZa_k=&fWh4JgWYYonhf=&NI23z2VadWVVl=&RX6hFYWb_hnkV=&SlfntUVdZchnY=&eUmjGgXerjdqY=&aw4K89WelXpas=&RH6VUGXlaqlnh=&QMu8GXXhsmXfb=&HWfNjxVdqfUXe=&DefMGlXcUZarh=&mq_XbaWjXmWkr=&2OnlWZYgZWZcl=&WGzGRmVXanpiZ=&UKCQg6WmYecmY=&ImpqJSZWp_Vki=&5qu84MVWrZfYn=&PiZak8Wjimab_=&aOBwfSVro_iUb=&HhVsz2Yemagiq=&xaFGbLZZfgWZr=&A52HVfXcUZlYq=&93GwGoZmopVZd=&rssqqIVqlZqir=&J5jQgSZUUsUie=&7XTPENZgXileW=&ZnvdNuYlqcmfa=&eKDbDIWVjcfdY=&sfgI9dW_gdjXm=&Ki_DgRXhYpnhi=&Tv5X8DVVcoiiW=&iQzyDDUqkmgVn=&aZFBygUsfhaso=&FafvQ6YishjUZ=&ByYBnSWoeelWb=&DPuO8KXndpUVV=&59SghgZiYsYhi=&i7j4K7ViakkfV=&XfOZqWZpjVepf=&gFhiflUrrXmmc=&bPPMBWWqsohiq=&VTp5eFWnhgfiW=&EurP5KV_ZUnfZ=&NwtFoGZssUh__=&YpphHIYYriZsZ=&whUSBiVo_isXX=&IaHXL5Wi_afle=&qK9t52W_qmprr=&nV2FhuUqob_bU=&azPszlZXshYmo=&IK9XWZWibjkXe=&OzWUbfXdYnkUr=&QKJaTLZUoXemo=&SDCUpWVXZZejk=&YC3LpJYVereie=&3tksxAUUYcVdd=&ICcCBRXqedpeq=&GrPds9WoUdipm=&zAiFzdUhYfUWj=&BNvvTlVd_Wdss=&e6tb9JZ_drjsf=&WGbSbCWcspaei=&bpsyNQXmrVbZb=&Ygf6lrZilUXig=&DnjD2eXbYen_X=&j2pWILVdddbph=&Lg5KQTWjYoXsr=&OalsP2Uld_cVZ=&tR8GlJVsf_Vch=&r7nDXnWdaqdrV=&LVA7JjVbiqidi=&KnTqgIXaqiqlX=&id7DuFYjrapjm=&mJVOYYYpZbZZo=&TUkfcZWresicp=&krkASuYdYsVem=&ClmZ9SVUiUfkZ=&rBbUYeYq_jWnc=&k_SiKyVbisYap=&xCF7XVYkWghjX=&KIqdcWYmobZ_k=&GpjbYQXhrrYWa=&ycOMhNYUmsbW_=&WO7AtBWXqbdVn=&nX5bBnWdhYnYf=&ngKIJDWgdashm=&rtRR7jVihkhkh=&LMhsgsUpab_hW=&c5yCesWidXUod=&bX5vSdXskVoUn=&ItmA2DVnhZjdo=&hTmyEpUmWnXbV=&2Uxj57XiWXlaX=&gwEW2YUasVaeV=&2J2bllU_gfXZm=&vDJEKAZimabic=&3JhEwNVUXhjgq=&c5V5YWWmibmdo=&FYq7oNXqrXelX=&UOPHb_XgUsmlU=&tKgDW2ZW_kjjr=&IATwrUYhbr_Xp=&Dp6mVBUfqom_j=&NwfgbhYsgpofd=&c6XNpUUWnoma_=&HcLZhRZnZqmXc=&e_XJVyZlhWZqa=&JFkfskVUraZol=&_7JaEyYrgUcno=&cjkhfsVUssgfi=&nzgMenZkcorll=&RImcSZXpWkmVc=&sYETgGV_mopgq=&nSBvz6Vdmjfoc=&hty8dJXbhkm_j=&mhFFpxZ_Uqdpj=&c7WGosXZaggmp=&o4rctTYUUmjsm=&kWDxAKVrrjboe=&XkWXTXXbschim=&55SfwzYWk__sV=&ayVsPnZaW_rgq=&khc_4rWVmoYoh=&zfqz2jUVXfVoo=&RZrDklXionnaX=&3vG5cmVjfoUeb=&eIZkGzW_V_mdj=&S9oYe3UhaWmWk=&JnjnPxYhYkhcf=&d5BVP7YlomYYW=&IGpZ36VXgdqsf=&EKf2g6XarnqfU=&CVy9tLZWpW_Xb=&6uXPhtZmgXhXq=&Ct4zn8YXVUVVY=&4Snu5fUrkofam=&_yyOp2XnUqYUZ=&BAoXcTWZakrhV=&DxmTqyXnieidj=&YAyU8GVZshYVc=&oi9rB5WrdVndc=&KLIPPaUrjimsU=&pqryixYUjZlYj=&82gBkGWbmZlsj=&S3FZ8sVbYbhmc=&_4jViyZf_nmZs=&Q5nnkPVsqZlol=&OTlqa3Ushbhek=&_9En_uYsjo_ob=&2D_iuwXdaWVcg=&ntvKIhZmp_ihU=&eHtjR5Yjg_hcZ=&jh_DrvYbdWmZj=&urSUpLVfobUkn=&PwwJTbWaabUrj=&yywUJSWslkspY=&PSywSBUZicdej=&OQCJl5ZjW_lme=&3OLQ6HYjnnmgX=&pimqdTZaiWZfh=&Oyfep6UhZmsUq=&rvDGhAUpZWfgs=&zT9mRbZsfXqUg=&GOoiELXkajUU_=&iZaZnbWhjbnre=&IAUI5uWsYjeWe=&tKtTgoUsXXhbq=&j6JAQdYapainn=&3eVTSTYjUsaha=&XJBeBvXjnWckf=&iSltUaWWmVj_V=&gcJuCeWXejddi=&XuSKfRUlWfXfo=&TaMdpdUWqlnqr=&t43yqHWVebVYV=&i7jMOsXscqbbX=&6Na7S4UgdZ_rd=&qtGTWqVpjjm_p=&xIMmYsYWqoXZc=&ChUEaHXUpkmcd=&KoYkiaWpccqZj=&uYDLwTUb_qsUd=&26avUjVodsdjV=&TQcDSMVmbkZme=&RG9RQRXekUcZW=&d2CM5MXnrUiga=&mM5jgHUiammps=&TqSrJPXrVddaa=&WxxiSxWWrWggV=&Oav2qqX_cisac=&uMEZIoUrYmlrd=&BEgMygUYWeoVj=&SLKh6xVrkiZdV=&9lgoKxWgqmVnf=&gd8BQhZpeaaYb=&OeVu79Wk_fnca=&8fz7IWWoYkp_l=&bLtijrYgVqWgZ=&JVuIW5XcjkYgr=&dDJY7qYid_XXn=&VfeXG9X_pkWnh=&3VnXSXUWmssef=&Aocgf5WbpioiY=&TFE5EdVYifmdr=&WQ5DsLUsZbpoa=&sskZ3OWhYnUqg=&73FPjFVWnshVp=&YIwX_zUXhlden=&vRfPuVUgaYsUm=&LqNR6kVhl_aYU=&xeLhHnVXnm_Va=&gx_iAAXqaYalq=&3lfRQKUnajlp_=&yCN_X9YmVponc=&CWaRZzWdhairn=&ZX7W5_Z_WrlZp=&4wuU2AVgnniVj=&I9slIgUdmZmo_=&6BAFBEXebioXk=&7llWF9YYdlrfi=&7jzNngWfcaZWd=&edaauHXnWfYjb=&d2m8neXYqonfa=&rsjVG5YVkoXca=&kKvzPHVdY_jrr=&LBmuz8XWVUnY_=&z5OJx_YlXUome=&EAj5CyW_Wkolp=&pZkSfcUfWgdrX=&wXoyg6XgnXoZX=&xURWBcVohbqqp=&cHvHXIWeihgmU=&HIvkClVUkkWrs=&c_Yz4oWUkeech=&5lKVy9VgdYlYo=&DqzqMFVdnbjWf=&vkhwyvX_hjVdr=&SnxFakUXnijXY=&C2RRdXVkmZksg=&dDySg_YYeUcf_=&_YHQ8sVqeqpiX=&tA_oX4Wmokaos=&NfOZJzYbsslhr=&E69QXPZYpeeWa=&XN_bKfYcYqqVU=&cwoH2hWroqbog=&Qh6f6EVZfrcVs=&Xv2PJ8VdrVgap=&WvCgOWYeZljsl=&EGtvMsUdZVWVn=&NLkLQjZpWsWjW=&bAmAmQZinVkqn=&Ja46mNWXdsgol=&PqgQvfYmYehUb=&_HRU8gUjhUlkV=&HbMkH9UdmhUog=&QiFwyGU_cqbrY=&Fo2oBLVXcedcm=&_8LPoNUoakVnr=&XM78dFXorjhUn=&rw7hquYa_ickn=&6TNuUnZdeppsp=&SKMzbTZqUVafn=&fhfarDUqZZinj=&okCHw3YdY_kda=&auAPh_UYrigem=&oNd3W8UkbUVc_=&3RlgCOYaXVWhW=&rRiQGPZrVUmrg=&2W4SArVcUYqiX=&28PLgwWo_fqjd=&rcmWlRWVcahaq=&yrEFuXVadgUiY=&jMUsKJUiccggn=&rHZrkWU_haUeg=&5Tc7tCWcngYks=&_s_6eyWboonYo=&9ySRzIVckklaj=&HEYQO2WpYYZn_=&qO8n2SYqshZsU=&rKVB87XWVY_qr=&_8RK6GVdgpeds=&m3iaK_ZeocrUn=&U8Gd_qVoWe__s=&ikdhZ5XkrUZh_=&8Hiok7ZroZenh=&MgAT97XdbUU_n=&nn3adxZqhplp_=&olCE53YlnaVbi=&CPy5slXXgbYUs=&Z9FPt2XjUqlkn=&yxBqVZYikXWXj=&nfmmQbVUjlYal=&CJBXFOVZjjk_X=&QlVz5qZfnVZYh=&ClcX3VUqslnVX=&ZNEywoUcccYgV=&eH8TykVlZYsiV=&IpRSSPZVbrpql=&3UQ8iJVpgkbgg=&sK4ERxUosgefX=&H5JkNRWnchajq=&DfBopJZrYrpjn=&Tewy_dV_knbmi=&XRkwupVqpporY=&CQPUpnYXeesUl=&8H7zXHYc_bjbb=&tJ2bcXYaYYmZj=&nrCbl3ZoanVcs=&llg2wFUZjcVea=&7eYV6MZqcohbY=&ejL9CJZdhkVnX=&9xS6MlYbYZgec=&2Jv2LdUdiUmsg=&8gV9A9VqXUnVd=&Cxh__lYVYhdZU=&Qa_kHhVUbVgoq=&WFF6SrZaiZnmo=&T_aFYYYYpjeon=&HYKQPkWWWVcqY=&Es6yt2XjhimjY=&8_GKHZXfgj_lU=&K26yQhW_rplmb=&TfBsaTUiUWpWm=&AsqpLnWngWbWi=&dXB6mMXgsmfbg=&EQcuaAVjZfomV=&7nI8vlZssgasU=&7RDolhYcXfcWh=&sr99mEWrZnbqo=&FtaHnuYVnnWso=&aUhwdgZiUlqYn=&bSmmbzVnjradf=&njFDfqXY_lfel=&McxCsPViUXddn=&JrRqXcXrkaUgn=&pdvFl4WUhYbgZ=&gYhLSEZckZepe=&pxcJQfVqmjZVr=&fJRhSDYncUXrf=&J7ysz2Uqj_oni=&nOxKsGVVUjem_=&3xJNLnWqjZoss=&B4KswBXfYdXff=&uVetpBUoYdjZq=&IeDLIyVjgWlqW=&GZBY24XU_iZna=&p8IhBlZZcVjaU=&84X2joXmmcosd=&i_p7guVsrmWci=&xECSodYejamUW=&DyZmssVXmUWsh=&Dn3tMoZmgkjqe=&EFVnisYnekZWU=&uCIpGeVpjXmks=&qpxT3hWdZjinl=&l_ZVGlUWgbUlb=&QSCLL8XZjWmre=&9CMh4KUlYo_UY=&THoSatVsskljX=&U3isxlYmmkiba=&rpqhzLXqeVifh=&b_EX_aUscdkgg=&mC3aIpVgmlUhh=&Z8NvwYVdrfmaX=&lSt_ovWYdXbho=&Sofj9PVYZgYjr=&3ZcLp6XhZlZaY=&QMKnO3UYnpVXe=&bZUufDUbZchig=&8a36cyZcmodWZ=&yhrZjPYge__gg=&AgSr2CYmk_bdZ=&4riJ9ZXismako=&wDS4sZYbdWboX=&D6l5F9XqnZbcn=&rVX4d4VXrfrZh=&WcYDYDYsUjcks=&9QrUgXWflsjrd=&IecqSoV_qkYmW=&RBOqQEXlrdged=&jEhAkKUcpinbi=&gCG8NJYeiemXV=&SuBZ3zX_pgZdc=&xHF3pjXUkmbcq=&Hox2g3WmiWpd_=&d4r9gsUdeqjYg=&pl6TYIWefehZc=&Fff6lIWhWloWU=&kbMDqjUaadsgd=&HTNAYSXVUWYpj=&RwHcKXVoacjnf=&LiJnmSU_gqeqa=&AToghwVqkmbbq=&J9GhveVgfqZni=&_RfS99UsrsgVh=&_QO4SoZqklhli=&OO7bJbXgcXlsh=&X89kacWliUgfn=&ax5cEcWXqbsie=&ckGlQzXUsfjqg=&bt7w4VWbYUZXs=&LZ_TbGVklVYbj=&KkalqSZgfjqdk=&BKBHYaUdpk_Vr=&Uf22f7VrmddWb=&5IB_BDWUnoffl=&ET6SimVpVnnao=&NUopxZUn_bfnh=&6uTuHsUl_lqkc=&SmqbFSXmiaVXa=&R_DOuxZnnZsmo=&6M2fLmWkilqWc=&ItxqrPVYrhXqn=&7mmsZQUsgfcip=&7dBCSTUgjXVXk=&hczkN5VYdljes=&9XrvMUUeVhlid=&vqRlfWVoqeqVr=&I_LzhmY_jUdZj=&PuJYBGXobcUoe=&7G2OdTYomaajj=&fJ4cRhUqVfbWd=&H3H74IUihpigc=&tmQFe2Xpol_Va=&ZLwy38Xlgblnd=&ApfoFxWYdYeZp=&Vj85lhXXamsss=&ktUuzTYWneqqr=&wuALySVnccjep=&EnS2bWVUegspU=&UCobT7Wpsnb_o=&nqtFm_Yroimfm=&HnhYAkYlasWir=&ncQGwcWXWdika=&SnV4NyVcUngeb=&ad3zeEY_bYYgo=&HNEgx_YhdbXlj=&Bvo6SwVlmfb_e=&VztJkGUr_qdVq=&6r_fh4Uqooprg=&UURHrIZXfkjbb=&BdJN7NVninqgj=&Vyy5ACVclehmf=&DV7N9PUWaWldj=&HjgUxvZkfbb_r=&V3ZfPyUaZihpo=&rV6ytsVhXpUWl=&tatOiyUcZihnU=&ztQPGwYVokbWq=&lYgwEBVjYg_qh=&RAzjMSUf_rqeW=&v8SLJzU_Zjhlc=&ByQL_tYnhgqrV=&SJQHOUZsYgplq=&AsLQntWjnccpl=&wQhi6OWfcdmhY=&cjBDNmXhWbVjq=&rabsvzUipYmsa=&Xqu5RkYdksU_i=&z42x84Wahcamg=&9ZMx72Wq_aqgs=&fTUR5SZrqaepV=&QU8G5iUsi_lbk=&6gsth6XcsZldd=&kSn5QgVrjpdeb=&IIGd8yVpjZona=&4TkmDjZscjWfq=&yZaPHFWifWiac=&JRHYWyUkcnhiW=&ZyqZryXVqdemb=&JFlbBHUYdWchn=&HjI3rSXiWWrlr=&mbpNOnVp_sVei=&XCEgH_ZkVqgVY=&vaA64SYZmroo_=&xSDjW8Xg_ccUa=&m9deBIUraaoZV=&8f4386VkY_gha=&SIsq8eUrVhaoX=&Kyz6BwVhjqnos=&lB9lX2Xlkhifk=&tqhl8LWjqWlVr=&iAgRYnXfUiZmg=&UjvRfWZpZjars=&HqSIrCVWrWdkW=&rctKQmW_hoeW_=&khHABLU_Xrab_=&4ulEx2WXradUo=&ejoFMzUdskebg=&tOeaoHWokpYbp=&lYvK__XmhronZ=&7JnNajXmapsbi=&R_TU2sYpXUocq=&qe8SkNUiqgidq=&hYOv2oXekohph=&kYGyoDYWpegUp=&b7phFnVgnUnXq=&UTB8mpXejngZV=&WRTjEtVafW_md=¨qWhVhXhWcV=&FQPt3LWpprjZm=&KaV35fVaYiZih=&P3LCrdZV_ijdf=&zGEqUZVhsollf=&n_GMT7Xkdikij=&ny59oDXVcqaaj=&OUrLx6WZssfbW=&r542YyWYebniU=&9SQGjsVghcfXq=&QuLN_EVVVZWfY=&J8VZeIUseZlja=&cxky7NXpmeakn=&Yxz_gLZpsWlar=&7En_oAVYqZbeZ=&cPhPEUYdYY_do=&23OBoSYVjobgY=&FvI9pEVmefnpi=&x2yAHSXjglWjq=&2urNsDXrfUsZZ=&4DZtNmYbacgcj=&ToxhfeUlksike=&HR3FkQYoohXfZ=&KGWQgOVYZkWrg=&fyCyt9WXdosab=&JXNF74Ujahler=&jNPYfTUhbXZmq=&BWQgCkZbecbWh=&VoLUMOWVcXdiW=&Foyp4lUdiVVVn=&9cVfqlZfUWWek=&HeR_fCZbmeVgr=&XcK4ZfZcddie_=&OweJvoYddYp_o=&xHz6eRXVZYlei=&qm2g_6YmpsdWl=&h4mwvJU_ipikW=&JCUajPZUmbjVa=&vvoivmZUjksrf=&gmLYdAZlYajmg=&8YzatRUXjdVZa=&7NkTf7W_Xkf__=&QMyx2HUVdiUjf=&wmN8HDWrUk_ai=&_KAHA4YU_agof=&clO7s4VXjrkgr=&eOY8AkUecadmd=&o5y5NzZobnXeV=&UEaLHTYYlZf_h=&_PQLZfXnY_Wkb=&IIJElCYrdklpp=&JXPrT4UreUrbg=&7zbCReWfpmbje=&o7Aj_VYaVqbbe=&W5NNF8Zdkiraa=&jbc85yVgsniYg=&Unzp6TZgjejdi=&GVWcKGXofhdek=&megbfeXlrbWmf=&QQ_AWzXlfnjYj=&SAm9EbZWcidWg=&XeMXYiYb_hkfo=&ja9q5SXrnjeqi=&vMKW3MUoWpjll=&HAeDqeXiWUXZW=&qwVULRWlq_cns=&WffBMHWriZkjk=&A6TxTLXqshbmd=&TDjHofWch_rqa=&G3iEnrVaZ_jam=&7irG5nZYjqgsl=&vASs8sYXXfgio=&uXwn9bVYsolVf=&HLoG8nUdkapgh=&slTCQ8ZUXjZWs=&bxi2bvWdassha=&fweVwSYUqicgp=&COdB9qZVoeVqi=&TZ6F3JUfXZUkp=&miLtOAZa_iXZc=&ZOEWo6V_VV_se=&rxoFKXWf_Ungb=&5Me6cNY_aUnlf=&5RcCrnYUjUjsc=&Yn_bIoWgWhm_k=&uxMZAyXskXXpb=&3KawIcXZeecWX=&u47VjvYgofXfW=&ACUMtqVfqiema=&vsSyMYUVUnWZf=&PR7H_IWdUjVmp=&KHhw4xYhcimdV=&bCLvVFWdZnqhm=&IFZOKFUmVmUqr=&TsubreWjlfjYU=&CVcCFLYgXVobr=&jzKFwdWcYUkgV=&SHGRliXZcqkqm=&QdeTnGYhrdVUU=&jAzIA_Vfpsegs=&ZzubpBUflooom=&VcI6gtZUjhfXl=&h4rNEIU_nolin=&FYvprMZkZcfi_=&r4Zmn6UccYkgW=&Imy4fYVn_UZUU=&QnRBsmWlglpZe=&Smwa87Xcorr_X=&H4cvaPVoeVUli=&rPTER2XiYfams=&i4SOGBY_maq_d=&XOJ5YmUcfZbo_=&pQbp7hUiisneo=&iILKDUUpdbodX=&PzB5yzZ_adblj=&7d8Kr5Ydli_jp=&IEfk7RZnrfZlp=&A79yw3VrqZlUZ=&ybIxjEXqqrmke=&5uRBWtXsfsfen=&fYnjaeYXqXXWr=&mk9CqgXhqdr_h=&bgTgwdXqXjpqk=&AerQHGZfUilrb=&nY2RHlYVdrVfd=&jQnVOnZqiargl=&SIMLCcZVbjaWi=&dBI2aVWZk_iim=&Fv6ToVVhfqjVX=&V4yaYLYWUUhYb=&ZLDZe2WahXVgZ=&iaHP7SVkjnsie=&uHtCusYXdYihm=&QzoRKoWWflabq=&gqKlWNXkobdlj=&WhesP_Vcgfpmq=&biEzBjWq_WlrV=&FfpAfIXaarakr=&ot4zWdVepZbXa=&J2KVeWYbiccpo=&mVpcIuVilgXjb=&txFO8nYoWhnlb=&kMKFIlVffkqca=&d54g2jWnrs_sb=&tenuJNWqnkVri=&hLk4XSZigsrgr=&vYyvdyVZfmjcs=&liyoc5YdlsejV=&WLKQPUXkcZVXf=&4pcmL3XeoaUbs=&SqVB4eUXjVsfW=&vjHyqCXhnshUs=&hU7TgaVYrshe_=&EiigQdWkXefU_=&kYTpDKYeeqhni=&HThnEYXbodbmj=&SzI58GWmfXcUV=&obu2YmYggaYZg=&tpxCcUYXkWVks=&S5L7BSVhcVUck=&diXakXUd_hbYd=&8eZgnwYpk_VdV=&J3_XGEUXp_sjc=&ClcowcWoVlkhf=&9OtaFFVqYldgn=&KYf5tyZac_esm=&TjtwwfZZcekXq=&SSILkWXkkVdeh=&c6sSFCUnseher=&5CUaXhVaehcra=&y5I8vRYpmcWWn=&VXQ8geY_Waccq=&I_54KVZnYrgjj=&tDoCsXYciUXjk=&HsjzQcZgnXnfV=&MeigIKYonVrca=&4LBUVDZprYafU=&_hUJzzYnprgYa=&S6FXgZZUbgcfe=&TOxFtwUkmhrlq=&OSgfOfVma_UYm=&3x2a6DZpfrg_V=&IDDDOlXlckUUn=&ERO2DuWmsnZZl=&66ehtvYZqedYi=&pTrdl5UqkrVms=&_UdCYdWknnk_b=&7wOOpeYXXpjjf=&N8ZgFhUgUjYef=&UqKzR8UUqjVXf=&AYAgiTXUnVbdj=&WL8sjIZlVmkrY=&QayGLeViYkaXm=&FIyJM8Uh_rrfs=&SzWu2UZgebdai=&WbOoZBZZqlbqW=&hpNgKqXXkcVjm=&4zyAB6Urgkjpc=&phSUTgWhnUZjo=&HQfNuTXef_idk=&8lAst6Xnimaoj=&A6ie3LYWaWonW=&IMuydgVbkaYUc=&DOjnzXZdaeUcc=&YpDIQUYgfoWXr=&UALdkWXp_geqV=&wbtTRvUZcah_c=&usAOhaWq_Yonr=&59CcEwU__YgZg=&w4ZIdfUdldmik=&IvJn7rZijXnla=&yDlDErUkZgjnq=&ahEl6SZnrksml=&buUpIUYfmskUq=&VsfhDVWV_aXZn=&eGUpXUYWmcqpg=&yhkk9qXnZdWis=&YnafobXsWUelg=&LZnloVZacZgUY=&AvQlsOYbXVqVr=&mHdDRuZaYspir=&ZRXF2yWafWk_V=&KAxBMuUoX_naV=&QTOFGqZeVmdrn=&q3S4UwXUlcimW=&RMrEehVbVadYW=&nsN2tSYjVnibd=&uMW6DeYsm_nUe=&Js3jyiYggaahY=&8T3ys5YbZgsop=&gZ6IwCUUqicij=&mOcGfjWbcUZbi=&MhAioxUUaaiZW=&9oBvqhXlUfshU=&_33dVXUsdUijq=&yxhtdMUnXUacf=&NbKjqTYdhWsh_=&g6sT7IXgmWlYb=&SCWkWPYgmcX_b=&icZ5EEUmprYsc=&w9C8O5Wpshjni=&dS6lrUUskelcq=&d42j_lZVbahXZ=&5UABmoYiVZbhW=&yGHREsZrhWYbp=&J6NHdWYmjdinf=&B5EyA2VYaafcr=&yxVkN5XaljpYe=&ssiSaAWVcadqn=&3PZkKlZpmbgfs=&dh48MMYssrVsX=&sWEob4UosWjes=&9thfSaUUmXisV=&DcCvXsVeqnjaj=&GcdpmFUlXpjss=&9MDFeoWhnYrdh=&LQvmDNYdeaqrh=&tL_wogWpnkapg=&DJP9xSZigUXYb=&azUQC4ZjXqqph=&6VtiYTXZsplnk=&T3GENXUZZYWjX=&lg_evqVcmgfh_=&WfCPNvVlcUdXZ=&jHpMXGWfpncbp=&dktDliYgqbmhh=&TxX5Y7VlZUWdW=&S5v5svZs_ajds=&NoTf_3YelVmpZ=&mrk_9BUqdlVmW=&E4vW6zWliYnmr=&xQeNx4YVmUsnX=&SzTRHKWsbnmgd=&2TCnBAUsmrdqV=&tmcEAhZr_mVjV=&5l2xNpYpommqr=&EP_8jAXaYYWfm=&qBfWlMWZUfV_Z=&fDnQz2Wj_UU_f=&oe3_JTUijZlom=&BBgWAmWmWYbiU=&7d3Bc3YdWZdbr=&Z9rIIWXfplXo_=&A26Fo3WqZVcas=&5clBiYXlWcdmW=&qVUQCgXZYfegp=&iCV9SxYVXsXWs=&L5dimgUnWhfbh=&Vz44skZiimc_e=&OPCIfRYZnfrcW=&ZXRBGbXoWVZsr=&dtyFELVWXpkeq=&RgfP3WYXl_foX=&KZL_GdXcWqZgk=&kRYEEaXjnfcXh=&e5ISzsZjVcXZl=&ZGqzSqXpUlac_=&tWdZLMYYZhlXn=&_dl7qkUnnkUgl=&izHhGLV_mWjjc=&VIizpNWeqZhlW=&PtUKrgYobf_UY=&tzJGkeVl_e_cW=&E3XRwNUY_hlmg=&Wj_wpbUmpVmW_=&6vN4OhZWhVmsj=&gz2UN3UllafVq=&brNP_BWrgropV=&CnIwrxVpajrak=&VWXevxWdXlojf=&6_AnFjVkhsWsp=&UcTfV6XkoZnhr=&xg4XfDZYsesZc=&FVLdugYZ_girf=&4ujps_UsqYebp=&29Jf3dZYkhgUX=&94dvsiZoYojki=&72ulziXemfmYm=&oEOI5MXqhn_ac=&8eIDteZbsbrZr=&TM7lmRXsflbs_=&lPwGvBXfeaj_Y=&D2EHWCWnYZbWd=&b6FmlnYpfYfmh=&Fg38M3Zep_csp=&kwy2rZYgfYVfX=&4gNZkvZnpo_ph=&58xCfFWmsbZsf=&w2BHBZXWprgkX=&8zs6EQXjeaWln=&6xtykfXXZZlcs=&umi4qRZgeYcea=&QuY_7SYbcXcUp=&AM2g5zVsXapnd=&f96GijUgZZngj=&4e499fVg_oZim=&hqZny_Wsj_psq=&7b7UPcZXekYab=&3JjGSHWVWbrsn=&TuFzC9UVXkggY=&APexnIVcdYiUe=&O6KeNMUsgeqin=&_RmwzMUXXZnkl=&GPvHvUZcVUZpr=&Gl4YLuXncojhm=&Lv_GGCUpaZkUf=&9Ix_XbVmckpeo=&rVPxpzXXaeXYU=&x8WAeQVnYVXVc=&PkQcvSWaeZpob=&eH2b9LUigfilV=&38zFF6WYciiqk=&mcVHvmYrjnkVa=&caHLZKXgW_Zcm=&PtswG9ZdipmUm=&FtqVcfXVimdiW=&QW_UcRXnro_ha=&TgH8c_VanmZaj=&tmEoraZYVZUlf=&SjAagRUZqYsoe=&Ls8HE9VViWYke=&j_vFGUUrcUWpU=&nbiu_YWlZVarV=&lgtkovVpjXbaZ=&NdighDYmd_m_k=&mbUxHqYXjYesW=&RPZ9qLUXkrZpr=&IGM4RDZpUhmer=&tsi7KGWdgicp_=&SYcyvqWrVVdYa=&jSAMk7YrrYeVl=&CZeOFmXs_Yojr=&a2x7dtXbandcp=&4vX7WKVmamdVd=&8pnFVRWZpZjhq=&wsIlbkYUdgbdc=&F6g_LRUlnkhsg=&pthitzXXadirq=&oUXYYlVqksklX=&QnQQmpUcbegUY=&nnMO36WXqUflj=&PFKK_QUhqfqUn=&QAtNMcXjefVmd=&KKONdCZsfVhsl=&V9pPDgVjqosed=&94nGulYZnV_Yh=&_KcStxWVsjkgl=&lBCX4tUf_Xldg=&Wt2RJCYdqZmZq=&duZCELUaeedor=&7JsGNLXempcdp=&W6lnskVlrhcgc=&NJwsO4Zfbbdkj=&5CgeZOYmffnUV=&NwegX_ZXailoU=&dpCnf7YmXUhXc=&zNKWmEU_kllfW=&nUpLlLXifqogq=&FlJnziUfYkYUr=&u237SrYZjZqpj=&PWvY5wUlmVVjZ=&8RRn_sYZrc_Xo=&ZjzlIwZregpoc=&ztrDRgZplglll=&jTPdH9XmfWfYb=&zI6Eg8Vl_rcjY=&k27_43ZnedsoW=&jegaaUYbgcjhf=&gsKK9fYVnVpnV=&uRv_P_VUmsc_p=&J9ivyFUZimYdW=&AqSdPMWshXUbq=&uvc9EGWilcbhb=&FR7uYHXkeWaja=&2pHaJ4Wbardob=&Wq9UwXWbk_jlr=&_qMgdmXdnbbWd=&YRIDYXYZj_WlX=&AyGOclXqniUdf=&AVEbm6UWemsiU=&YXN4QZYZpdWfl=&gXQI76XakVVff=&CAefX7Ueqlhkf=&tZKqCOXijqnnj=&XXXkKbXeUYnpW=&SUagx8ZUj_bbr=&r6KUdcZmXljos=&rq8G2cXnarpgW=&YLhBTWVWkkadn=&vNJqrwVokXXXd=&vJmaTZWjomrpW=&vctM_EYjmakZZ=&f6NpLlUeqeeep=&GNPK6lZgqksY_=&FfiujSXlnibgc=&lHgkKsYgjsZhg=&O4dVFFWcjabfX=&NcMhjBYohfmYb=&BFUG7YUcikajk=&BKfWFHYoboeWk=&sI4XPnVfnh_Vs=&8_EZwyXnUeg_V=&a96t8TUjksfeh=&dAaQ8OWfYZg_f=&dpN_b7VVsXgnX=&rnfsWUVpeXqYV=&4yd5wrYXbjqop=&6YyHrMWcrjkXX=&fYwZ8eXVmos_i=&mH_rFYWXoXekk=&ECmwoUXsUbbYg=&_I2oL5XUYfnci=&4pgUT_XsUgslU=&OnFHmrZdXqZfo=&nljBvEUkUbqZk=&vFqYDuVbhX_nn=&f_ve8bXiWpqin=&MQNTqRWXUclZb=&r7pRO3ZfVmkqn=&uaB6LmXjljaYc=&_hyCZuVccifmb=&a9uLWoXjbZgUY=&GBszSDXhaaXjo=&yrIrcMYZn_ssX=&ILSnzKVVsegnb=&qLU89oVkc_VmV=&IH6ER2XX_oZsq=&4zW5ACXeXUboW=&WULmDmVsddafd=&Fyy6HsXdrWjZV=&oizdfSZeYflkb=&jsXuJVZWiWXlk=&PejAjOZgYmsib=&AOtGLSYoZdaWX=&waOiNvYZfrhoZ=&K_NQLSXj_lYjh=&kScRjQWmgabpV=&8y53NWZZaWlXd=&wbP4GfVnWZfsp=&6VRTrUWo_qbcj=&lU3lNpVgeZiXs=&mH8mFQUiprfch=&N7qaQWYrqYrnV=&I2FIkBVU_gmWn=&fIaeySU_bqrbd=&9ANYAzViojXie=&ChzNCoZZZUXXZ=&JBFUDBYdsXb_l=&IM6niZXraXVpr=&ccx7i3YXseqbe=&pjSZmCYWbflkr=&zSKzErWWanqmX=&jEJFwYZeocqpq=&hIUiiDXd_Xgiq=&ZU2GuwWkZeXna=&aPUlwPUqrlhip=&IdUohyUjV_neU=&ulNd2lYrglmpb=&ub_RaTZcjihan=&V72bJxYceZnbl=&TbiAHHXVkhqmW=&8mEZYgZVmUijW=&votgCHXpVZ_W_=&TaHPmIXaqhpgb=&FVB_NSZfqqkhU=&ZnhisBXUbkfca=&SUcoA3Ugfjh_g=&KVdX7DXqUjYfa=&kAiD8NZhgYcYW=&dupjX_Vkloalo=&YpPEzJWboblhp=&KHhcBuZff_oXs=&doOdLhXi_gsZV=&IBtFJUZsqcXor=&KTdljxZegVqnp=&4OqlojYgVfgfh=&xxNcI7UVZehlm=&LJpkutXfsYUZk=&tlykKFVUUp_qk=&Of7Eo3VmWifrX=&yMz99IXrm_fbe=&3IIKSGVXpldrr=&UZ9uXHYjfYhho=&XLhkviUZdglkk=&LMmHmcVfjfsrW=&FILARCWffrkUh=&wCFEGKYY_bbak=&QPqZovZnlpV_j=&SRqsLwVafrbfa=&o33AntWWr_sdp=&3yQQlvYZXrUVf=&oFOU6DVrahknk=&uiI9zjZhqsXms=&TTPt6eWnegWds=&CIVvAiVlXUkeU=&KsUXLaXeaYpZi=&tK3m8CVWkVlaW=&thS4NcVsUogZn=&fdMGBJYriVgWp=&BxWEmNWf_Vlpi=&MjPjWaWaflsia=&YFPFaRZWUgblg=&musU4cWaZnofh=&qAVyTAUeYloZh=&VpMkyjVnlnsgq=&nlmTOnZjbipbg=&GDzxSaXinba_f=&NtEn7XUYicnnh=&Mqq_sGYcfghWZ=&j5dmVjWbdWpZj=&F8G7vzVfgeUqj=&CkPuXQZnXXfVd=&5kLTHLVkbsYgp=&sQDACyXnpdZgb=&4i7tVGYgUgXgl=&REQRPIZYgfZjU=&8IF5ueWZXXiUY=&FF8GG6UoUgWYf=&LtYNt3W_aWhkW=&wutwqFWodlbUc=&b4O7x3VkalVVo=&Qot4APYXjekbX=&PrFqJ2Urnnpfb=&9gJAcXWgeYdfZ=&3cr4bXYjVcWpY=&wilGm6VVcmieV=&avpWFdXYfUZbl=&GQ_ssuZmWsUVj=&c3QpGoYdlpadc=&jEjVMUZpYhmhi=&MNqmajYVo_adp=&yXTjsIZsqnoam=&uLjqaFWaWs_im=&6j9eUOWgdhfWY=&lvlB8IYUmUakY=&PJvrBzYfsosge=&AmePquUVbpabe=&ohaIrhYojcYkr=&WmsAnqZVibWon=&jVpcaDZbdkdah=&VNoxwpYfgaajd=&55rutKVdeYpY_=&thDCldUZchcam=&TCK75cWq_gfml=&X4ZwJeWjblUqg=&_BMEH8VcnUdbW=&jysYbKWZafhqi=&Ocvjb4XVnUigW=&nxCKqNUgjoXjr=&6oA3FJUm_XVnr=&HunbSIZYpneoX=&a9gj_bYbsaocc=&4UOKP4Y_jmnka=&PsotWeVYaXlec=&V3IJeLXmmVmgW=&3tbdjPWlhnZUY=&xb2vNPXmdicgh=&pX38ZDZUlcjaZ=&wExY6dVgimYsf=&E3Tz59Ydns_eh=&Cm5Gz9Xmrf_on=&eU2Ml4YmVblij=&rInVw4Vnrbpes=&IKQfnfZVZmXpp=&99EomsUphreoY=&Q8UhXIWWrnfrm=&WF9MStYbq_jnY=&YXRkBqVsfleWV=&TqGsUaWlbnZWm=&WylCaMYlfkWmm=&M85OV2Ufnk_hr=&s5FfwnWcfqlsq=&BfWO55Udmcae_=&7T3CpIYngski_=&A6TUgmXrehZle=&tLAuFtWVsfkmh=&ZH7AW7ZaYjrVn=&eWyoTeZnkYmbj=&V6MDmfYafbmpq=&oS9ArmWbmnqVr=&zivPI3UaisXYd=&NAJL9dZZpce_g=&tlOfaqVV_mcsW=&waHtzGYsUW_ke=&jVMgqHXkrhafe=&gM5sYmZrpq_lX=&KcqsVQYZZYrsp=&iYtVOoUXUVZXn=&9h7rR7ZUakZVj=&5Olq5aVqaUcVg=&I5KfoFWpisdZq=&fpxwPIUkYqrYq=&pquELDWqegdlg=&J_Xsi5XqiXVck=&OxiScsVlqqlcj=&Hp6ewTWrecgYY=&Zy5nnlUZcjagb=&PamXUUVdcmnhh=&5Nqs5GUlr_ogc=&uGgyPEYpUolXp=&UYI6bvVkYsqqn=&cCU4B_XkXqdig=&DTxpRtXfqojY_=&dCD9RUXgcfXmX=&voXt87Ygaklpj=&OlOfzWXipZqXm=&a_Y6zCW_ailVX=&OK7ExOWqiafpW=&nN8jxSZbUofgj=&YBFOrAWZWjUfb=&VKNJtBWeps_kV=&ORHBxRZfmrano=&q32oBzVcjk_aa=&TZGUdPUcnqgqU=&jjjfcJWjbWsm_=&KRCLJeZjcXked=&USDQxyXcpXfsf=&F2qWfuYVbnshY=&29zwktYnpakln=&sY8YmdXspahmi=&TyxuDeUjhrgVk=&iG3XSLVicbfUW=&Y756ykWViqagX=&xmOTmfZf_gqZj=&Bbd2h_XigfhoV=&PTNd4OYUVeipa=&gKD7Z4VnUehmX=&57KcaVXYeUgXk=&3mVohLZVngeUV=&Ft2ovcXVcmUkp=&CErZFDYspkdl_=&IGzJy2XjffloV=&dvviFBYloeqVi=&jEIdcDZnjp_am=&WGFRBSXoVqYmm=&tmd8ltV_napd_=&unKrszUX_ggpU=&SfMMHQXUmanoh=&7gmR5rYarjpqm=&yOkfCaUViicrY=&ChZZTCVYeUarr=&maxAwSYiX_aYb=&XfQuVDXWgbpUY=&3XKnxQXerckdr=&aJbwZkZg_roga=&iMVcUzW_nUgia=&Zv47odYYoZag_=&UiFBoAUjjVdpi=&TC2aI3Yhlhpfc=&PN7zk_ZViUjlY=&v5EVcsZarVUiY=&JneywIYXc_jla=&CMbpufUbVjk_X=&5bp8djUWgqjsj=&r2DrlqVqkbpXg=&R7J4dTUibriUi=&U7jatFZnbeVlr=&o7BWgGYabVdbq=&jBEXm8Ukcehqq=&Yeb5YlYgjd_pe=&VCQaFKZYfimdU=&EwXUb6UXfgYfn=&6ThjTTXXYqn_c=&QGXjXBZibXmsW=&Sp2bprWWlUsji=&osx3BhUbemgr_=&Ux75JVXeigVjf=&cjbg7sXUcdbnl=&VyXCwvUn_mggn=&2sWf_TXkcYdjn=&AmeakNUbZmXer=&9nclL_VYWfsgq=&5W6QxOWpkppso=&XrZElWVqYigYg=&Y9PKB6Yl_pbXc=&lSpmkoWlXdlUl=&EpWgKQUUhdhra=&ffJQ33ZlVrXZq=&2x4YU5XhmnVpp=&KwgVe8UsqhWci=&ja2bwnYra_nhi=&GhmxBMZmqVcbh=&J9p7SBXc_hZYr=&lN_YKBW_ecibl=&fyNNQMVXUoXWd=&QkeHbIVhmgrog=&za25PwYmoZpic=&BuqKUZXp_gmon=&bieH4GUWUXdph=&iQe7fYZiqVahb=&DRNszdX_fcsmU=&oyQzEJV_gordU=&vMiXCXZVZYeal=&FwiL2rVZqsXnj=&Qy8wBHZkV_oVh=&2wYJ5FVUiemhW=&4MJrhcYYpcdjo=&PqJoriVfrdffY=&iDybzvWiXkind=&GaTPuSUkXmoeo=&gUQOqLWifepkm=&KWU5cgVVVsgii=&uQeReuWYlelmo=&LnnNZEUsdfYcq=&wsVWXyWUnqhZk=&thlWTlViXqsZd=&NPsZ9QZbphVfk=&Z9eVVwVoYZhb_=&pVv9mcWopiirs=&iEKkVYVcZ_ZXi=&ThLuL2VdYlohW=&6H5lEdYgghrcb=&gzvcjHWcichVl=&h9u5inZibUgnY=&kW_c9wWeYjsk_=&EeKTPzYandanX=&z7KEhGUXe_maa=&GDNh_EUYbWUrm=&kqdxKHWXoYVkq=&O4cT7VZmcp_Xh=&yf4zuYWckqmsi=&BLa64uWgaag_b=&7l7n6JZ_cghql=&6jtVdqZWimkeX=&JSlwBSUichrhn=&X6_gAjUZrWphk=&PzWnLEZYofWcV=&rvt_etVrimbbX=&TiKEoYWlUaUdc=&aqaU5aWackifY=&nUHqS_W_gqZhV=&NwozHlUdXZgso=&x8MB48XiskX_c=&wSzwFtVlWmXnc=&FzmHyKVjiY_jj=&QslvR8Vbcqqnc=&pZr7YIYWYnjac=&Ik7kqTYneUUfi=&nboD4nZpom_eW=&As6Z3VUefdqeU=&R2owNqXpslZrn=&e9Z5_yYnba_nf=&xWxuYOVpdkilp=&bvbVAeVcnglmm=&7PvVtEVflpYqp=&d3RdSlZdeVjch=&486C4MUWaibkW=&MNfUkKYcqfbjq=&reEJhrVlipWik=&87v2TPWlXscjh=&Re7C8jZWWj_qm=&zErYFSXZgjj_s=&8F_hOyVWdoqpf=&xfyEVdVnhfldp=&GHi4tDU_brgir=&QuWwa7VVYhakm=&XcEcqZVemUZ_h=&lai3ALUbkiYaW=&ienHUOUWlhfhj=&Z38hOvUWgnUYW=&T3QDzwUedZioU=&uIFj6JW_cgjbj=&WSe5cKZocpnmo=&yXfyakUamU_hs=&DpmS8JZZdqkbb=&QbUUX8ZmsZbbe=&KJwde5Uegep_s=&7HHxjYWilVcjm=&VOta2NXbpkknd=&vreLbKYsX_qi_=&OHniRlWpVmqdk=&eAXm6ZXprcVUW=&QsX8_EVaYraZ_=&NcPs__VlpWpba=&_AehglYcdkjcn=&_bWR5nZpZgkbk=&yXDLKIVhqXoqZ=&7NWb_yUXraXVf=&ObpO7wXWUgeXp=&BrdWGzUgpVVWi=&gbbM5nZdZbZfW=&pdEBduYmjfomj=&qJVggwUcgcjk_=&e9COu8ZmenUqU=&oCCISCWfrphXa=&fYaKDEXlbYeUs=&Sy_WEYWgWpcpb=&8CM8GzXrXddbg=&U6debIUesdWkX=&Q2dXuIVlZgUfW=&TSyJbfYhdUepY=&3uCH3nYjhXgYo=&AvpHprXkmjrjq=&2mYiylZcVgWje=&KVgf2lVmWYknZ=&qcHRKiWVnYfjb=&XHlVuNVrkjWhY=&RWGyb3XUoYhUV=&sOCcbHYboUVqf=&iBo2xYZgUsnk_=&AUpKK5Uaao_We=&xsGSykWpeUlo_=&cNav_fYWYdhjl=&NAk8gAWejefYp=&VyjtdmWpkeepn=&E9u6HEWmVngXk=&AwdngFWfUbiWc=&aoocsSYUVkZpc=&kSK4P2XpYjloY=&XM_PO_XYjbssi=&gCSXVbZWfidkn=&urvvcpVrUrgoe=&gC5pwYUibopmq=&CoFwPOWWrVfqe=&DihDq7UrphqpU=&PhopGuZgjYi_s=&cmaIKFWUmeiUi=&7BfMDUYgYjbsm=&TQTcjmUsrfeYo=&eSub4hVmpfdpb=&gsY9MMWXVZsme=&fC4qyXYfbgenn=&mSSWxrXharZin=&R4w7gYWVkUgrb=&GEv4PLUsahXnm=&avkEDqWsjmYgc=&ZpKmsSXcZZZgj=&BMCHb5Udpskei=&Xej_MDVgqoioh=&PAf57BXssUVjV=&P7k2pMWqnYe_d=&EVD5keY_reisY=&3q23DDZpZbqkq=&dtOwRDWrYoXli=&zsvGS6VlcmsUi=&JsxzqEXnpsUqn=&tFBloTYXpbfgm=&xEVHTfVUcpmeo=&wATq_AYfgjekY=&HHitDpUVnXpam=&eSMXBrYqVVlZi=&JzuG7iYkhXgpY=&vEgXOeVVqhjkh=&3fm_NJYqd_keh=&A6OHbvVnWnjfg=&DV_7aQUgsVjpo=&i3YEWrVYfqZdc=&3z6aVtXrrlhoe=&c_Ed7gWipjndg=&4yrh3FV_kjf_i=&YUAoAwXc_lnjn=&FYg72GXonieZY=&vG8OheWqiUgki=&gCJVouUUhslls=&uyPv3_Ymbneep=&QlPCB7UhilVb_=&JFjRHeZpmeaks=&LWHfWoXn_aYVp=&sDO8WqUZciXVW=&R2jxwXUlnqUao=&ovrGR8Ws_qXfX=&utuJ7MWpYa_rX=&XH8iBrWZYsopi=&DeGKMTYb_kiUg=&nWubbxXeraYcl=&CAsDC6YlcZrnb=&ZegEgAZkfgrXU=&Ce6fC7WfajVnp=&vZxbpNVnncrWX=&aovX8vVWYoq_m=&yAUB_YWrciaoX=&5WwN92Yajmrin=&ZTbfVSXZZZonV=&wLS6rRWordfaW=&PhMzaCXUXpUYZ=&yCRhGqUrZcqaZ=&cryyKLU_icjqU=&sT8SUoUijnseZ=&LFNPxdUlZZcsi=&5pIR2GXVdmZhh=&VOL6rfZniUkms=&DKuInoXmaZhUq=&p9bgB5Xkjmghr=&sg2HVgZqWnUkY=&uwl92PXWpqbfk=&fch7_QYl_nqXa=&BbMDz7XjhcVsX=&g76oQaXVmYlsd=&doRhiSYbphmkd=&_G2eIwZjrdbdg=&biXfJwXeZpbVs=&noUdaGZjgamhU=&iTNy3wYWesnrd=&OBvJvtWqroYhe=&pQthvAXXWhboX=&vXAesrVVqZjYW=&utmBZWWionlhX=&OuJNlSUYdkZUq=&9cvykOXYVWmXX=&Dv__r5Wchjlrc=&vZ3JwdWWhZbXj=&_5FQNNYbYlnhq=&eBrOwjUjcbZlm=&4JrzcZWpmogad=&4ioZuMXoinofe=&mpMiF3XcVlgoo=&zwJ2vzYpa_doc=&opyA7xUfiimks=&NvPDjuViraZcl=&hSF4KPZqssWjb=&uIJIvfVVkXnhd=&tUkkjkU_pgeqi=&vIhraJZsliVUU=&5BtUAtUqqXfbZ=&FAvRD7UcmignU=&VEHS9CVmrcbsW=&sIzWDPX_ebalh=&EbfupfVpgnqgs=&BBhmgoUonXYeW=&krMipwWpngcUh=&8_Cd2xXlabiXl=&NMT4UpXbkgbia=&iIW5AcYV_lfsq=&kZz_W7ZdpUdZs=&422Sf8XrjaYkn=&hPFxRlYpnYl_c=&iqYkBYWUqpkXU=&ki48dYVaiiY_b=&TN6rldYcldgrU=&t3qwttXbeajZU=&AkHWAYWUnlsma=&LYjrFEVpkeisl=&K4A9eCWfgsbXj=&LgclwBWqoWUWm=&nCfmUqYdjbm_g=&5otIKtWaqrpr_=&O8ZmcYXiWcXn_=&pBrdvDYYYasmn=&WCohNOXhXgZsX=&_JObAVUeaeZjq=&oJt9qFWaooWln=&25J2vIYhhhjol=&U8TeYaYUqmjqU=&6fPvEaUXUrWZo=&rYmY7PVfaaYjg=&Vs3DylXrYlmZU=&PjWzCYZlpdcVf=&dTi5_xXojegoi=&RX6KDAU_oilak=&F4KdSqUcrXlah=&3TFivBXlhinn_=&mddUutZknqkYc=&YXQxgbVZiWbhs=&wOHapwYppfldW=&yf3ROAYpei_Wk=&pez6IiUcUasWi=&FUx2pnZZ_mipV=&tZodRPUhlcVpW=&yuFSUgXZsYjsf=&2QaHdbUXpdqos=&4RukhUZYUqpio=&NbWICeUpkqiYs=&Z6PBqTVhZorll=&QGcPzYWjgiYZr=&99yfQ7UbnUXbk=&2BGD7rYlplfep=&aohEbLVUmgdim=&5G4FHkUogapej=&yGT58YYogaUkp=&S4PdJoUdfXWWU=&LlRaEAZnfjokY=&vmesHgXZmcqmr=&w9vdmnWYqrnVV=&iVAU2kUjpUZpd=&EfQ5o4WVhqhmq=&pnkClAZ__sjk_=&PZdldIYXlgiln=&XZ3slEZoXjdrj=&3MKV_BWfjsm_l=&xMQQR4XfdhW_k=&yfszNXYZd_sUV=<Cm2DVUaknpi=&8WNVSMVeXWppi=&wYVYbAVWfep_m=&QvX3CSWbjhXUp=&j6vrCjZsgVj_f=&PcAvu_XU_cYcW=&896rxlWZVsdgn=&c2al7QYarq_dZ=&lkCqDQYibZmgV=&qTbORMYcjnlqX=&OcfgwTXYsUZrg=&P2KtLkZYgYfgV=&XFLg6fWqeWZZ_=>gNKfVY_des_=&td_HACYkfWikZ=&XlJ83sYedXXUY=&YGEw6tXjhdglk=&syaqyKVdffmor=&jmNGywVgiUnad=&HFIbzfXXcUjgl=&YRhd8TZUYramk=&uJ6AuVWepnZlY=&5PpjfAVfkZlYV=&daS_ZuZsi_lij=&jnUHJ5V_iiVfU=&BoDFvvWZmrclZ=&3bX_bVY_jkVpe=&TQZDSGUZn_ZiZ=&VFoai_Zdmqbqo=&wlHC5CUZrsUqZ=&OTDtTWWfWdplj=&QVoMqHZ_XbncX=&6ywqwGUhaU_fU=&Ak4dO7VhXgUem=&mOZxjsUVgsUoj=&fdrEHvUaemdZc=&rIAFC8VeWlhoV=&ZDLsw_WhfZcmb=&4tvcUIYihmobc=&pSh5WAZkXYssf=&78QiQ_ZgbkXih=&WhRBaNUmlfela=&DvoySIVXsnlUr=&seNsLfZhVpYWq=&re2zqUUmrqnsU=&QJ_Z5rZZapeqf=&D3s4obVr__sbh=&u33EFLWVfnUnp=&Z34BglXjbslif=&3S3a5RXXonchi=&V8EETdYVrpfWX=&xcoBLKUaajmpo=&rncJA4VpkcpVh=&AzSExqZgWZlkm=&dXeVsBYWbXqbs=&CgrdKJZdinnZj=&9ETIGvUkmVgUW=&adRamQVVqabYW=&eUxPDdUdWUrfc=&XbyYHRXWpfopd=&W6uU5YZnWpe_d=&FafbhDZWcYUal=&YlsNSPYVXmaUk=&csANlIXh_Y_ZY=&tHL8qiYbgnkUl=&HScAJlYlpfWYp=&kP99SOUafhmqm=&ZtmWP9XWWjnYd=&X9xWyUXjlZrfj=&yu3hr4Wle_dog=&oOrO4HZUcjqhd=&Faz5aTYcUkkrj=&hOQYvgVrjpaje=&o73FdhZnadd_k=&hsrhgQWWfjkec=&jc9lCQZrsdfXo=&GlehFtYYjWXpU=&AEVT2gVaYkYUj=&QNnYzYVlYcrgV=&dkNbxyYlhojgm=&jKuFOmYpVsirg=&4rtBBeVessker=&fxJs3_VjXWoin=&RqW6neVYWUXaY=&PjDRi7UsYllYn=&52udLsXqsmemh=&oMb7jwYhhflni=&_9b_rpWbbZilU=&SvnEscVndkkYq=&RzcaEaVfVp_bi=&wGopjQUkhisXn=&YN_yXQUZWVgWV=&TOTQLUWjdlpoU=&GIEB5aVhldqXV=&EJMcLAX_qcreV=&5H59osZdfgUal=&aIYSnFUseVdXW=&kZitLqXscXVZm=&oIdLNKYfrneqn=&LyJTYRVpasgjY=&dBt3ElXlhVVkU=&K5ymQ_Wfiadhq=&GJGOidVropmeU=&IJJlaqW_abZmi=&7PA5ehUgqWjrj=&sfGMSvYbblhUV=&5JxCLCVeZpbWk=&GOgJBaZqUfhae=&WPEZscWpoonWZ=&Zt8gAQZeWYVdn=&FiNehWZm_VXmb=&ib6j26XYeZsq_=&bRKETjYhVrlXq=&dxYGOWWbbWhpl=&YLd9CYZjXXmUp=&4LDf_CUYWpbVi=&knKraFYZkfagk=&xBJrihVXVcdbX=&jlH35IYlliifh=&hP_ruLYajVon_=&9PpAPMWpZbVcm=&CYuxzoWaWlpsj=&tq9BUtYfsajrb=&8M6XJrYZeeclc=&g7sonUZrVW__f=&sBgxq3Zhqpqia=&WqOxVgVhcrqpn=&9xUKekZphomlq=&KH9NQhUeqs_ka=&3yELFtWWjqdUm=&mOrXKFXp_ijWl=&ZEgJm2YlpjV_c=&Q_FefcZlahYdh=&DXmC8qZsWoVUm=&Z9NMYLZXgkZeX=&t6kULcWsokhr_=&A9hHCCVpoljfe=&cNGrgvXZXcaWb=&TPBeD8Vdlhrns=&nJcyYzZVqbhhZ=&UYlM95ZimjUse=&qXrCRXW_pjZkk=&FsFSj2WmriYfV=&MKj46cUifeVWc=&m6_8EZWarUdpj=&azrTapXdafWfd=&DwGzAoWdoepXY=&9aExFiUZpiYfc=&uHuC77Weebha_=&sN6xyZYWp_Usc=&irXwa4WmrsmXW=&tb4SLBWnjpmbo=&pivoBoWfWhZba=&zifc38Yjpjols=&CAHYCBUafpWel=&AQmEcZXiqghld=&EoN4mzWrUUohk=&x94_bpZrlhcaf=&OUAfrfUirZpUZ=&nnJiY4UoehcUc=&SlSBjtWjjZclX=&lYODj_Xlarrnr=&s2YcKyWWpghZZ=&taYr9EVcVYUsZ=&kTsnA_WoYXVb_=&qHgzoZV_VYcph=&gGejozZZUkasr=&NBTSNDVm_h_ko=&kpi_Z2XZdlVqr=&PrquROYjlUslp=&Aw2wedYohshjW=&gLUiXGUqnf_pg=&FYGEDuYiUqWYj=&qgdZ2rZpUUgcX=&IycxIPVmbeZms=&cengItYidVbUU=&fLJcJHYgccjrm=&WhRDlyWXgXahc=&sIZ2HnZaoXmgX=&AydqdZVWoqasj=&hgFhWhVeaWbYh=&8_4Y7vYapp_Vd=&cWJIqZVgrUpVp=&RonwZYVieaXnd=&j5ctToWgZndbs=&DARyjmXjhYpdX=&GKtAwgVYeUdeo=&IHI2RcYVpUlir=&Vp5dnAYrkemfb=&tOso4lXYosWUl=&Vv5ZAqYjnfWno=&6DqWJsVXfsZeq=&sdC_KUUkfb__c=&SceHBTXmnsfob=&OGRi3vXpnakXd=&tIJGBIYfaqeXc=&7DSiGHXieqWlp=&e_puCyUsebZYi=&kAuvHKWVaplbX=&yAjbD_ZYbsXZg=&MDjgdJUpfVkk_=&ox6JPRUriaikp=&RTu8i3YeUUcqc=&mSgCqcVibbqeU=&3k2WKNYdd_rdr=&6OwnMrUhhchVk=&DY4tVxVo_adZb=&9xd5IeUijrkri=&A8Ju4GYnYmojs=&iUwCDiVglWhoZ=&idb2VnYZcWddr=&VDj9ddZeerocc=&ItjtMgWsaZcd_=&QVmOoxUZbesba=&tfBOtNUdabrgX=&TxQXoVXbrZUen=&_tjTqAZqiXVYr=&vLpq6_YUomqhk=&GLUdkFUooUsdZ=&PLQdcpXbhhr_m=&JQm9kvYUdoeWq=&q6vuurXYZjhrV=&orX7w5YbWlggX=&LtjCNnUlpcXXe=&T6iGdiXUYgdY_=&hprqCNYnsjjVd=&JX8HT9UslUoYn=&I6zBOWZpsrpfb=&LdansGVYkmcla=&4GabwwUhWYa_a=&emzEJYXaZmnpZ=&LEnHgBYXaYbb_=&JAiyJ9WWhWpZi=&OuCU_sYipr_Wp=&yLHp7xWfpXrd_=&IWZC6WVlkUXpj=&eYatrKWcWoUYb=&fyf66oYpiplhp=&toeeojUWbisbh=&YHArs5ZYssjiZ=&6CSCxqYiflV_o=&PxjRViVqXorUr=&7tSXTyZbhbkVn=&EP3tJ8ZqafXme=&XclN9eXXjeV_W=&nWAiOwXbWfsUn=&eNU7I2Ybdl_ff=&yYxLhXZkbaXpf=&QtgZBRWrdYYja=&6oT2AjYkdp_ng=&Xh4dobUWUkVfU=&FFITElUhVlnkr=&6Yua7iXnpbVmZ=&D3GlqnWfZcVZg=&S6bBlGWjl_apm=&ZftFjMYskspiV=&A7jmvzZcUhobf=&RQMNScWjoUkrj=&a2OZk4U_pnrZo=&ZmSFllV_egesY=&_EtouWXqnmkhr=&53Gl9aVUlbnlX=&YxrnYxXqriail=&CvfXKGVhZiZ_a=&oSOwjVUkUfnhs=&n5n2ZKWedeaae=&GVbsb7VcbjoYn=&5N6HKaZp_i_Ws=&_jsYkMZbkWs_m=&tO3b5bXir_YUk=&_4a_sNWZnVeiW=&lCREGqXall_og=&n9uffTUe_fqfp=&3GP2pYYkieUgY=&VECwUbUhoZWqb=&l7Ix_bXsVqpYV=&aLA8M7UZaVrcq=&VQXIapXs_YcpW=&YwIpPJXZpZUaq=&TBbxHCVUdWdrY=&w9i_ymZsYeWsg=&cmXJZHUrrqhog=&VbBbokUnidmnW=&4fx6u3WjcoYes=&AoakvgVbchbdV=&YabTPyWWWdq_X=&yqmvNAZiobVjd=&VaDnwpYck_rma=&5YVd3JXnXchjf=&pnTwXZVbharhX=&a2HrJ2ZhrfXbi=&FomjsIWefpUkd=&LSYDY8XUnllic=&jdx6i_VrZndVj=&pLifhPZanf_lg=&KMP4qOYpVqVYs=&reiLVlVnhnadg=&Xh5Wm9XVoq_pi=&wrfeliX_qggsZ=&sLUQAJUWgiakf=&ldS2L9UbdrWoq=&bwiveWWaosreo=&AnOSWnXqjm_sr=&JXIg5SZdsrpqn=&sNEEteVWVjpXc=&TUkE7yUUjclbf=&2e8xxkVXmZfpY=&cVLNKlUhqoqbr=&JSokXhWmqqbdg=&4NpqVmZWacoWs=&LWVWotUYhlgZf=&nSpHGQUZZhbas=&wp8W_rXgfmsgo=&zYL9TkYWrpmeq=&bd5xYZZdlipYp=&uKSM9BZVgcdqX=&4Gpjp4Ypflecf=&dly667Yekjb_h=&XnNl5TVjdcUlW=&OxmyiVU_iWVmk=&gew97QWejVnWW=&qWOsNJZYrlrnU=&FbWESRY_meofX=&pOr923XljZiYU=&hq9nGUYUXoanf=&ZazH8pWgsXfsi=&aKY4V_W_Whcki=&UolRuUYoifjUX=&Pes7GuVeUhmbX=&nFM7xuYqdkjlZ=&4BsOn5Ydrpdqa=&VWB8xqYdqsXpo=&ikVzgjXaeemed=&zAIbJbXVnioUq=&gSmrnuYsXZ_kZ=&L9ZU_BU_emabX=&fVqBI9Zb_dalc=&JpnEDcUmchl_f=&rSNZlIXddfZYq=&lJeQUpVafhU_V=&KRp6GFVeVflqj=&K62msnUWfhWdl=&n3T6AIZjppVil=&ghVrhgYdaVojq=&bjEwPcZiVhmgb=&k7FT86ValUsl_=&O2yUjoXsjolWi=&G8om9nXofqjUk=&7aR72LXcnVVqq=&FVCRgPXcZdZol=&JbDMhhWandbUn=&svg8WgXVqrXin=&_VekFaUUnlYXo=&6GPzdaZkXn_ic=&YcWFKaXinpkqb=&x_EqCYVdqmmXX=&bQ5UkOUjrseig=&u2wkieVXXUVWg=&BfoDXlZXZgolo=&3lJo2kXhhdoao=&oo9QqjUqobfaU=&LqHOQwZkgcYUU=&HtPssqWjhsceg=&lTyso5XoaXXYq=&2Xjb8gZqmmbok=&LHLKhwWnokkdp=&Yk6d3JVegdlUf=&A65geUWlYYZam=&wL4WrUYb_oZWk=&MDAtV7WYbcZXf=&mP293JYYXlgW_=&_NQdzSZb_dX_i=&2LhNgcVYbXidj=&FOAXVZUkgeer_=&ZFSSj2XfhYrfa=&KtknLhU_c_iih=&9f44fYXUhspqc=&ESIdhgZgkjimr=&YgoglhVYdkYjW=&y5spLSZYocWoe=&JUNQvtV_mipmh=&YYigZhWlnsegb=&8UyGrkWihUrZe=&9eu8fhYfonhcr=&cepf7UXilkrUc=&Xq6obHZhaedhh=&iTssDBXbchdYg=&NzuHVIVgVoaVk=&cZmSjXZobnpUk=&eUDqCcYVprcdW=&TwZ9WQUWoVsco=&6mZEgfUYib__X=&BbwIDyZXnjner=&BEk8akYqfUeWm=&9CLU38Ul_kges=&VYt_4iUsqcUph=&ShvE4cXVnsohi=&lzUpCRUnfkpbb=&aGfeBFYpcXsfb=&BaqrZbZVojaia=&_J_YTRYphVhsm=&W6P9ryZblVrfo=&fYpmrmXfZrddk=&IgprNwVkWWlnZ=&qqlJjeVmachlp=&FTUh_fYqlfYZU=&DpL2T7VZrrkai=&nc5PsnYlgnh_V=&CtSp8XXYaqecW=&jcLCsCUqWmd_g=&BjWQTuUkokj_d=&Cx2PEOVoZ_soq=&jKDJLpVUaZqs_=&arCwcNWgm_qoj=&vOz7YZUYegVVW=&Dblay8VmhsrYU=&zOH48XZij_hsj=&MfEZabUanlUXV=&duxLQnVcVoXgq=&L5EvLaVhqXfUq=&9LoRpwWajhXcj=&rE4syuUXrdlpa=&6yUnDtZVjZqmn=&y968XIYjbViZc=&BDy97UUs_pknl=&AW_PrUWkrkkdj=&e6CAAdYa_pUUe=&qamWgRVdgoqqU=&kKLYWIXjoYanb=&DXxHRpVsnniXh=&V8VOOGU_saess=&papulOZllqolg=&xU9UgQXbZekoV=&skfgsQVrphcce=&oyqPL5VUjZVjo=&Xum_9PXsZnonn=&3gBxUxWUrmYoV=&4B5DJwWjlsUV_=&y84E9yZsZWXmU=&RmuNKxWkk_Zgp=&dOIs_PXVZbsob=&vTJNLwWrkafYk=&a2NZM6ZpjbepY=&libEf9YrssnaY=&uI9uEoYWq_bge=&tDdnE5UiUgjii=&T9GYqgVslWoii=&wYPVRsWjWres_=&CWlW4WWjpcjUm=&t6PAGXXkVjnUl=&iFTCx5UgabdeW=&zNB2VcXjXhf_f=&u4JoEEVkjaqWp=&oD9v3vVVdoaZs=&twBDDKUdpdmqm=&f2J_vQVspmWUn=&Q63spSXrVYjcX=&IFlUcTVokmZfX=&j4IYjKVehjahm=&n7pUPEZcZekgm=&feCuR5Unbp_bX=&49wLUbYhoaeda=&km9Kv4XdYjhde=&gzX5oJUkXZnra=&A9cDJ6Vhlidcm=&k5TE5QVchoV_n=&35DrjgZqWaXWg=&uez7NBVsfXicd=&BRFI53ZciUosd=&JXnLLzZsmcnbW=&WfBSyOUUbncUn=&SoWUu4WrbnqV_=&DanhGiXWUYojq=&XvHOPdUj_ii_h=&dIykRXXqYahZj=&B7P8MkXdjnimi=&VBroANVVqmXk_=&NiAJ4wUrpplgY=&d5U5_XVjUljej=&ioPHm2ZUXXYgf=&EbO7oxUsqmoZm=&CHEAS4YeZfYid=&P8J_pBVaija_s=&tEDgeQWarYkll=&nYESA4WrbpVpi=&6xjQMjVnoaXYk=&raNOHqWUkaXXg=&QXeEM5ZWgdVdq=&HqRFQdVppVfrV=&Mrg8fyUmnpmhX=&yDjC4GWjsWrZp=&LUMSvpXbkmeXb=&vaLDBXYjhlddh=&J8fvjFWbVagrU=&dtOejZYhepapY=&CQJkrOXkXWakb=&qtkTiiV_YpWap=&oTUB5uVennqlV=&FBaxmpZeperWU=&myqEHRUgVhYXg=&b5aTPEZVssahX=&gQYwzaUfWqYlg=&zuQFveWXZcZYb=&77lhdTY_bo_rl=&Eyh_haUqmZ_mU=&gQM9RDZlifo_a=&UbQztLZhUdkhb=&g2ng5PYiX_Vnh=&Cob5onWpZedkc=&ls7GhBYqdinmg=&lTB8fNZfsqaXa=&r4L72aZZdemdn=&j8KhnzVgn_mhn=&v5Bs3uZjsaXVh=&lfWUseYZcffhj=&3xrF5UWXpkdmX=&tjPGDxVXjYerY=&KIy3MMY_eqoWl=&t_yRCzYlsmqXi=&fjKjwKWcUgrZW=&rssMwvYqbWrWf=&OtS6P5Ufhof_X=&lMjau3VZdqlUj=&B4eeqHUVmlopd=&tD9ozyY_rqkaZ=&V_LvhOXlbjlVZ=&VFNHwuUkoqqcl=&UK2PmnVVg_eoq=&2yCiynXhekkpW=&cKqRDcYUrijnY=&KymS2AVrkUcrr=&z63mk2XUrsVlk=&jMB3B2Zoef_Vk=&YpciqkYcgjZae=&tcBvIXXsfogmV=&iHPI8GWVrjpYa=&IdsQwDUijkVgf=&KBplmxYjZsoVi=&Jps7jFVnVnWYr=&yoftvMZjasmU_=&TLnpk2ZlkXeqf=&A2at78UdYUglo=&JmVNJ9UqkpYco=&pOVEIhXmkrrfW=&ywdfivVjfkjpf=&CWrb2kWs_fbkc=&WqvKv6YfireXr=&7QvOTvXUldadg=&FOroKCVsYopsn=&zzH792YYdZUlo=&oc3yRvYhjWUgf=&ROz3VHWWb_iWm=&LC4xWUVqalhiZ=&dNyHAzZ_mpWpm=&muzGgzYannegl=&Xr9AiDYXmkqlo=&A6Ell9Xokd_Vj=&OptKwEYcnZppV=&KUBumWYhVlgpo=&5TglXzWcbaalV=&s35HalXWnZike=&cRFwzIWqUdjqY=&N32gmLVdaWYdb=&iw2I3aXqZkgYi=&BQfHtSYsiVslj=&YTNDuCUsYacso=&O65An4YiebhVn=&MfnTGqYed_air=&sBCvdjZqh_nik=&AbxKDcWWXqXgU=&M5GWoQZWYqsoe=&4rDj5uZ_isZUh=&oC43RqUmgcine=&PbAEwgUUoadgU=&HST7zKYWcndYW=&wF427jZWqXZei=&t4DHE2XakXaoo=&qovIpfX_UiVdj=&NtGaPyVrcembV=&thKTXOYXZgccZ=&L5HtmKVehmpgX=&OiOiwWXdhXbhp=&2K43_yYlZYish=&h_ym84UohiWmr=&6waKQjZWpVlVk=&JxxVJfUqmsesr=&x8CHzgZsfqkfk=&OnwmZpUjelgYs=&wbj24pUeUXqep=&uI6qcVZjgndap=&eGvVmhWod_dqW=&sDSMxQWhd_qaZ=&fsejA7WbleVgW=&Qvv3zAWbpgiqm=&6UwnrhWmoqqXe=&ZbEClKUUebcVo=&pRBHmkVqe_gWe=&j8eSyaUXbacif=&chhmF_Y_bYXjl=&Y2YQ2iXpjf_pg=&poVfyBYgpjXbd=&6sjXTiZnZqXer=&pTBWwAV_XeYhb=&t4qHZNYpZViap=&E2LQA4XrkaV_X=&hUVkljXcYahaf=&uP8cAyXYpgioV=&sN5PLDWoVlodk=&fkdk5FVYbYeco=&KymF8FVcppsaj=&8TCnKCWojYofW=&L3qGtwWkhVlsc=&dtWHDBXdhpsXr=&L7GlejWfWnprW=&uS7VadWgfqnbi=&5DPtWdVYsbVUk=&CFDRx6UesX_VU=&Eag7iWZedimcZ=&RaLxELUXaUdXg=&mFnZEcZmkjYmc=&oLJgLhWqhqVpm=&ksFuZaYYjqmhZ=&PIMWfmUVoo_ek=&PHJF8eY_iXdUa=&Q2QS3qZjfsifU=&BGyAsSWgrcXfV=&ViwDuSUXqiilV=&qESP5JUlmgofh=&XeemMRUsWilme=&KEMPS5UrnUdkd=&NBHp5SZZZbgdY=&rNA4uAXebqUlh=&BX8huaXlnomVj=&xo2fWnV_ZqjgY=&OvFMSfZWejYmq=&A5cLxuWsnchpm=&FD29QeVVqVbsi=&veVwnWVaekfnl=&HtF788Yd_msjg=&NghuWaUsUhmYg=&m4w8X6UskVfgj=&DHNXBAVpjied_=&gmiSrXWqkjlYV=&qK6HNlUsdgpaV=&AXm46YVYrYecc=&srOwkjXoVhdin=&AZr8DaUcsXlpm=&Jx4flpXdighss=&jvCfuwUqsmcnl=&2XsqpQZihYage=&SkiAqKVgamXgp=&XzdgAQZrossld=&OxXKhxYibnhmg=&S8QUKdWqUUkhs=&CvM6BHUgpnYna=&SiHNkgVahZpnm=&XNbjGHUYnjq_g=&nmieu3Upbhrln=&jbUosSWbednfn=&8TtZlYZdgjUfg=&D2CY_6Zhfkljf=&6APSn7YUYrdfh=&4s5ErRYknUbVV=&5GmdrtWVXkZda=&DKIVTQUsUnqdU=&_XZ_oMUmfkmfl=&Y_uC6AWYYWZYX=&2H9H5FUjfhkVr=&WJTLgrV_jcYXq=&VgHc_rYodVgUo=&DpVGOdUYUrZre=&BjDkTWWkqhYec=&wWib3OZkmU_hq=&6bxUapZYa_Vsl=&VWm3HtV_goasp=&bmOfCpXfeei_m=&X5M8IOXbi_nlf=&O4wqZVXUUeesp=&ay5mWlXndYrsk=&miYvUuZZgZnjb=&KyWZ2IV_Yamgm=&dui56IXUf_YnU=&hnWtNHYijqhbh=&FFWnQkXVcq_g_=&sMpy2qYkbUoVh=&DlM8xCViUhmqb=&VxRedWYUZeZds=&YNHLZdW_gUikU=&ixlolLVakfUgd=&yxF8R_Vejha_c=&dkCATjXq_aUid=&t2vaXtZV_soaa=&hKy56zYjemYda=&UHQtXlY_nZpoU=&pUG38ZUYme_dn=&ZTznq8VoUnaii=&ASfotRUbpkerh=&c_JEz8WaUgnol=&bHtByOXohobqq=&xcvfpPXlrflWh=&EV3UQTVUZbVUV=&dqEBG4Ygol_mj=&7wF46WUfpkhbo=&7Tj7TbWflgcoh=&rpXYT_YibVlhd=&Dx9v2qVfjVgWV=&qBlvMBXoUWjle=&JFHCMgWprgmmY=&vFecjdXUhirao=&XRj5VHUjsdXVU=&py2Jn7Zeecslf=&SU9XM9UfZkUnb=&UvqSnFU_pUYfq=&MefZrGUYpUUcr=&qgRgVDUbqhlbm=&gT25ljUjddmUe=&lY7x4AWkaWee_=&3EqGHqVYUYkjq=&7yMIEUZZqpilj=&RmA4HqUrf_plc=&F9UKSZVf_gmpe=&JnafH7YUmYogr=&c6BgzwVmeWgXi=&3cd_rwZrisrXr=&4G2MVQZUZclid=&8SYeseWZggVpp=&57NzAdXqeYiiX=&fC56yWU_XjbeU=&krwoXEXWZpYdf=&ft2udbYcZocch=&DN4MITZYoomqk=&wRgkDUXVcisXs=&CoCzygYUfdUsc=&nTOcLEVsUZWaY=&SZHh9lYZYUhqZ=&Qw98NuWkqZcbb=&DaQwB9WjrqaUZ=&VANJHtUXYbdsh=&vcs8xDWdpZZla=&svgjMSYUZnlgq=&_hrw8BZeVc_gr=&YRsQcAWlqalck=&TiiHM2Xkq_gXe=&YkNf8GXklVqed=&lNFvRtUVYXkVY=&PDF__mXZYgloh=&Uhuqu9XjWXdrn=&hfN46SYgZiiVe=&77hDvoUrZVgde=&gjABeSXfsiVsm=&dMmzonXVdeWcZ=&38hhGtXef_rjj=&JwFB_AZspZgVW=&BBXEBDWfnobVm=&584NROWkiZXbc=&KyCZgXZbgkqhs=&qDJ_BlXmgZVUs=&gZVFYiZoqlVel=&ud58IYUpWWqms=&CxfZ7bYnUZllh=&bbf65EZWieVif=&9pnaxyZspUcXX=&5QTCngXgaUdjg=&k_6YumYkemYYc=&I9ByF6XrsjmdY=&umbwMOVlYdrXp=&pwrigeXnVbUeh=&HLEqGmUnpcUrY=&27vCC9UfYWrih=&Wp3RMeYegeXea=&z4u9KcWlhsahW=&A6JhZ4UmY_qcW=&dc6KE_VVnpoVq=&d7epL2UdherVn=&XK3IVlXYqiqqr=&_BcCBBYV_khWU=&FCREC2Ymdj_pd=&NBNapCZpUVdho=&vy7sxPWnl_dcZ=&bW6M4dVjkZ_Xr=&dXX8dDYaW_gcZ=&3DLFOHVfUrWqe=&OvZYGwUWmjshd=&PjK7aWWhbVfod=&w_YOOhYqspmle=&gofjOHUdmh_Xb=&9QlOz5YflmkVi=&FWhhbjWdeadph=&L2JJoJWlescVq=&NOJ8tOUbVbmhX=&A5l8sZVfYosk_=&iKJWqIXX_jcoX=&xPXbkHXikllrq=&rw2LhhYreikZe=&nNZFuPXYrVWZi=&yuFicHUifjrbf=&kDKIdhXcfo_is=&Kk2VDUXfhVkqq=&EjT5p_WfkjUgo=&YBJVoPUbmUUqa=&gllvurUsfUl_f=&yLiXntUVcnWpg=&yC9k9JXppqYgn=&ovKDvlZohaVem=&uLK4EEVk_XoVo=&lOoSPZVYmZqpZ=&VhGF2gXiXcYrU=&xTDQh6WgXVnZk=&9iSjUnVbphoXg=&TcR9eRXinpXjb=&Xhf93MVYecXee=&z3SiidXnjerhk=&gpXLEHXWermpi=&XGDxYGVdobZWi=&FxDj9QWYlnZma=&E9NDIWUWWsrmk=&A3VCSdUl_akld=&UORje5WXiqUUe=&tAL6U5VkUfmU_=&JWeMugWcqXhWc=&oJKB7YXWophfl=&JipNxzUnoceYZ=&xmbvprZWVkqfl=&ffCI9vVXd_kZi=&MauE52VelaXjq=&7vg8A6UloYkj_=&77XBZwVnphVZU=&__elX6XpibUUp=&HoG_MSZoaVbip=&BS4sTlVsZhsrl=&hp9LpGZselZrd=&rDhv3tY_hXqZZ=&Jru36dYahcXib=&2KLZgxWmpUroj=&fdhcNfVacqhc_=&fF9nQOXUqiore=&KnHD4KVjpiobp=&ig4beMWVsXpdf=&VU7NbcXrsqqXp=&FUNMKrWgknabc=&OlyaqEWsorilU=&8KxflMWargqak=&3dy4LVWUnfY_l=&LA42xZUemYeoU=&5X3qaEZgaZhb_=&q4KB2lXUbnZda=&ukCEIrV_ikpnd=&_uobmBYVhnqmW=&nYa_LnYjXjasZ=&4UbVZtWo_pgYd=&gx3RrhZedbjed=&RocSZwYcXnXgs=&g4LdlKXbqdq_i=&PzONSTUfUigsU=&gwXAE3WYjhUkW=&vV_VarWlcllaU=&6Wiz97UdsUksc=&LkBEZRUrhrshp=&Mm3yHaXYYlnYX=&b5b7OSUZbkfXf=&kt5s2sW_smWcp=&TMraNVVhbooYs=&EJnV_gW_XoisX=&ME8IwcXbrnnip=&Tep7xAZWrWbrm=&hwtyXaUfsacUh=&ibQqEoZcsg_mh=&IS_BM5UVUXZf_=&qASSmqUlgWmYa=&Qi3Lj5ZekdYpq=&rK6TcMVYghsVb=&a7gs7JVbfndon=&vSkFkWUeqmUsh=&tLAawNWimVkib=&8p4drDYrcZiXs=&xhX23CVccWWec=&3oyvldY_Vrhin=&8RFRNeUbjbYnq=&5DqwlpUkmdZbh=&FN2_RoYrWrWir=&jCueiMWoojcmd=&zP4usZXjkqiah=&IJ654sYXbfYcf=&yXjED3Y_pWj_e=&4FUoivVZnkVqo=&8L9HppZpsapVg=&qqQE8tXca_dVe=&KmLhhyYcXi_fk=&f4Prn3WgoVlnh=&ej5DUfZrincaZ=&C8T5gxYiohqha=&LzgWVOWnjqqom=&9wsiDfVdsaqrm=&Jf7qy5WX_iYa_=&s92dTwWidddmp=&oZaH4rZrfXh_k=&JfswsIZiqd_fY=&KaUrSfVndobbc=&JHPhDlXjdVVag=&5hNQUmVWqZqqr=&hoJXuVYfprff_=&4hwELMYiU_Udf=&m6Uyi_Vsgsnqi=&94cOaLUrhUbfZ=&oYzpoXYdasWbk=&6AaGrCZnmakaZ=&Vf4CdUU_rnbiW=&7FRUXGYcdaiaZ=&eIGa8MUXYfmqa=&jCgBbzYdZWVWo=&d5dH2XWjZnmcr=&d6mLQwYerafjp=&Z67maYUaUnVdW=&Z25fSKYUqZnYk=&UAvxdXYejgUjZ=&34TcpRVcjhYqo=&S3icDqVUieapk=&DsV3WhXjmafof=&pmTQyeYpqjaUd=&RIFghQZgan_pf=&2Tq45dUghkWkW=&Lkdqt5Zemcgqr=&u97dHeUYp_dVm=&EoUEVIWdg_bis=&8rLra_WgZcbp_=&WolBKCUZjhodX=&rBIEz3UUUohfW=&jXsc9QZodoZpf=&3vo7hJW_gWXkr=&cy28hvViacbne=&7BIowTVYkhhkk=&UekanjUdnsXqi=&P59s9xZbqeifq=&y2_FIHZZYWmhr=&tKJl5ZZnseXhn=&nisKuIVmeklWi=&ATrHcpYjjregk=&iyDswMYdpZlbZ=&tWzIbCWpgYkan=&sUWzPHWnesqep=&6fwR2kXWdWecn=&4_oqftYpqoZsc=&WlQmnYWqZeXil=&VCvh9fWXgq_Ug=&ILKZEwXoqfZcs=&Nzzmq6Zkhnsjl=&WTuWIUWWeWeas=&DzoOmhWjWdfin=&E7zblNZselbbV=&TVgPguXVXbZlm=&FHFuMUUXZlkif=&9NMJlKUWiWdaX=&Aj_h5gZanf_db=&JMpNnyZokcbgX=&gESQvuWWUbfrn=&VpMdNBZmVrjnr=&p3HLMeYmdjWpl=&juLE7RVrZsVaY=&hmWPSPZnnolki=&8DVnUMUnmYpcn=&OQZyrSVbmhejh=&g4Aun9UZXUsj_=&XNcKXVWbnb_Xn=&hhqvX4WXleqVZ=&cNPldgYjaWkii=&nrmUSwZZrbVim=&MHz4Q_YaVraZZ=&9wQyBMUgbodsY=&3n4NxJXsmeesb=&OocMC7Xen_jWc=&3ATKJTUVppskb=&n5UfnWYmejhiU=&h7UsQ4UesYfXr=&96uKWuXXUWpVs=&s8U7qIUZZ__lp=&fmls7LVbbYiVm=&PwFqlSYirUkmh=&NO2uZyYXpYjgb=&YPT9SwYbqhaVo=&nhkhduVml_ddl=&Qamk7bVjXgldn=&BAGmfGVUomkfX=&F9qUioZrlYgWl=&86RLR5YVrn_Xg=&eH6QDtWWi_Ugp=&692P4rUYdkbUW=&kqjw3vUiiYfWe=&3BZ9nVUVYmZkV=&bFSirbUorgqoq=&DqEne_Yha_kiU=&NACm9UXgVrcUp=&NNrPOrZjiZlgW=&koXT7TWhmla_e=&zxQpliWXZpikm=&RInWNqZrqrnZb=&T_3YKiUcmpfUi=&e7TFaTZjqWYiW=&xjGycxU_ophka=&kzH5VIWrkekpc=&ugXPmpXY_cnki=&Vp5cb2UW_qXjX=&eDikweXVYaabp=&ai29IgXlVgpok=&Bqnh9wWYd__lk=&JJe2I7XV_f_lg=&eawy9iWgpsdYp=&Gk5EqcZmjqXXZ=&iIYKBaYakWbgd=&nlNhGKYhfZaqi=&25cKk4WZsbiWn=&8Uu8BoVmZiUXp=&ExLs9aXXdVUXq=&hWa47HVXo_ckg=&W92DroZViWjZe=&F7XrQRXsslVlp=&aCpcaiZYojiiq=&uiJoJaWcXahlc=&iiF8fmVskdWXj=&IxarzcZmprZec=&wtf5ewXqcdb_o=&2BlHcIXpaksUp=&bSBDUbXlqmVrf=&IMirbzVroplaq=&zQ7c_SWoeleWb=&U_2X3EVUiZY_r=&ljnlLLZfejm_Y=&SjsjNKX_eelrr=&3UYeVYXcYbfZs=&XPPttMXqWpgYs=&Xvv3kYYdrdsmZ=&SIvdc3ZsnnVeV=&YJJTXeWjqe_Yc=&9xM2MbV_menlr=&LhlShRVpnjlpa=&CZellkYgnlmdZ=&LbD7vjXb_gnid=&5fe5gxXfqUqZg=&RsxMyKVUna_la=&tHXJKjVlh_fY_=&voJ3IbXseenkm=&P3mgUnVYXpWaU=&vEoyWGWscssso=&rU7NUFUYasUqW=&JMi4suXsVpcUq=&4eQdKqWhYkojb=&x4c2duXoscosa=&yVNQBoWqlcllX=&XxNuJMZdpdhmg=&Kw4Y8wWbiUZnU=&8c49nMUehcdbr=&Jk3pkeZmferpb=&kG_UIHUmqpWal=&ExhA42UZi_pbq=&AbFzhPWdljfqm=&LclVAlXcfe_ar=&YqJKyqYnVgedp=&VklYxLWWYhnsd=&yUaH3TXrbfqcn=&DkklLkWisjfhl=&CquBO8WegnhoZ=&9d6qKuWoZpWVW=&NW8XnYZmfgfrn=&4eStWBVXkYfjk=&BKZjPvVqX_UrX=&nr_x5JWZnYoXc=&S9maQyYVhWhXX=&LrzNlpZressfq=&iLtH3hYUXjghU=&lqfVlPWWbcpsW=&guerdgUhhjYZn=&UQTtVbUcqabom=&jJSSXCZsffZae=&lXxgALUWfZUno=&Du62WrZosrWXW=&8qKLStYnZlfYo=&CqSAVXZpXnbqs=&CKpSieUZUgfoa=&vRyWKTWf_fibl=&Xd3TzQWcgmpjj=&SfZUYMZoYbVUY=&MQOAC8UoZcZhV=&6BF2QoZjbblsg=&AUJBm4W_rnchV=&6FiV6gZrficcc=&seYxwFZZnYdmn=&jixnlIUUbWhqj=&A6nCh7Ushdios=&z64VzJWkqqpVb=&uWOdBzUgpVern=&kNHediZUeaZie=&76dO9yVfooaWj=&fftghBYlcl_cg=&IDCvjkWUXVjrm=&nneFQqXhqbsir=&zETaMfXbZbqkW=&wTLpNhYoWqcWY=&H9dHXrYiblUjX=&YaJkcPZZioYqn=&I_dJzXYVp_Ykr=&LE3OlaUVcWWqs=&e339gJW_XcreW=&kyrY8lZUVsWUY=&wDxvAuWUoZeb_=&OOG_TAY_o_cYk=&HHF2WkVnUqW_V=&sdnaZmXprcXbd=&JXPYptYZricnX=&jnIyVuWmpaejY=&JXIIoLYqa_gUi=&72wqYZYneZVsW=&AzMGLNWVWrWeW=&UmkrH4Wkegcia=&oK25SvWlekgbr=&vUbtLZUh__ZWi=&xYDH9UWsVnaao=&PTrmlBZe_sdeo=&rKmLNnXZYpdpW=&8AffjLYVUiZok=&wPGSk4YpUVeni=&7nwBzKUWf_oUn=&MpDbyhVqjboes=&8EJrFtUmrbkjd=&AB2kppXqZikZk=&rxOyyDYgZarph=&C_8HPQUcYhcfg=&HPuMYhUbkhdp_=&zWGDT8YpqUrde=&hMdsFgVrgUZlk=&sez5MZYranYpq=&penMRkUdYsUfa=&ayLtTVVqiZssh=&FkE56JVsWblfe=&epERa8UdZjWar=&e67X52Uor_emX=&dLDEwtYpsoXkf=&96FUKgZYikcll=&2JudXmVmlW_mf=&eFiw2uWoUa_Uf=&Vd5QuOXmYnWpa=&MF_YGdUgrjlks=&AXS_7LUXlVdoj=&AnzxeGZomcXe_=&aSkhCdZbodeln=&fpPiikWaajbUe=&z23treVejdV_X=&3_fL6pYaakecV=&d9P5YEVeqkgac=&TsGg_yWWdlWfj=&ga9VM6VZpsrZi=&8tMlGZXanrcUg=&DQ5ZemXVXrcaj=&QocKzKXqXYnsp=&NVgGk7XYXafqc=&8kLln9VlXfdVn=&PO3fzYUnpm_WY=&gg7TVuVlXipiV=&l2qsNcYbhWqnl=&9SJw5fWlbZnXi=&wrgwW3YpbWdlU=&aDdGURYqefijW=&ZR4iV2YnecUde=&nSsm2lZlaXnWe=&_BsK5EVUYajoq=&ixOD6sXXXZarn=&iIIz7RXsmaghV=&9ijaooZVrZfji=&_ATdTsXnkkekg=&g68G5TZhWYVdU=&8L6SvHVWgnj_Z=&g4sCbiUikbZWf=&TWfyaDVsrnhqU=&aFXLq2YdsWabd=&pwd2lXXnofZkY=&K82EfSWrngbha=&EMiWvsZgYjYWi=&UkDA_8UgWocer=&kWu8FpZZaiUqW=&6ZjfbwXpfq_pc=&lAkZ7EVcsqdUh=&_oCmCoZjgh_Yk=&ay2yviVjUpZno=&vcTHaTUebqgms=&tNqKwQVjekhsm=&sKzDroWgrssne=&5TRMdsZm_dk_o=&n8sCspXqcsffZ=&2ZmKALUekUchj=&Zf7w4MUYVorhr=&YOGZXwZbjbhjd=&g9yHGQUddWdrU=&N4CpRRUUrlXXg=&6KwmClWWlelWr=&EC2dsHZqjXaWZ=&9EvqRSUZmYdsb=&WvTLocVs_blWp=&bOoEvRUkplkgg=&SQJjT5Xfsim_o=&NA_5WgZpWkeqi=&7wnLhwUVaihck=&OyiuO6VXYsfcp=&zL7sZCYZYdqZf=&_cEd8MUhearUd=&LYocOsYbncgWm=&kMcV3yWkfcViY=&wh9x3WVjmklWk=&jgZkexVkdglqX=&GdrwSaVrhaohX=&9Co72MW_iZapo=&rYzX8TWdVdpio=&ZpfTxqXoigppl=&f3FJezYhfqmZg=&VIJap_WdXXXhp=&yTT2XQZl_WXge=&BlccziXohdYWd=&YMqoSGUbhfZ_p=&wUp4_IUXVgVgk=&SWBGESUgmWmff=&9sERc9WYZgoUl=&KW9wypZblqmWr=&ozPYUuWqfspch=&kFm6U2Wroqhqa=&kEkpaSUfmmksd=&Q44WvBWXXlYnV=&8Oz2jKXqVa_p_=&8XWRb7Z_qbsr_=&u5qzxOWiqflsh=&GiNusfWgkldjm=&Yct69cXlUlajd=&GoVR5VWbjXkr_=&nO8IGMVqXgZqs=&mxNl3WWVladaX=&cUGvnIYUpls_Z=&RwyBVzUsrZkpW=&f5KiTbYmmkimk=&MoNFWrYikZWaX=&xArjvrZUqndVa=&V9JVfKVqnhWUa=&fooCpeZdjgiis=&rPo2qNYZmlgsd=&nGAyHzXifXhUm=&8tRJAzXemcfdh=&hzQEwxXcseeYr=&8DJgv6ZWkYZoc=&sqRpFGVpdsoYj=&mnU8cjXjlsiWl=&uDYv8hXpUckrc=&nDIWyaVrfdaba=&LK95suYlVrikh=&RXySGTUXbgqhf=&wLekUXYaebgnd=&g_cGXKVbrrYqm=&owpKQJZoVrnha=&mn73alVgkj_bU=&qeNRRMUpcsikZ=&zbvIgmZYijarl=&ogJFUQVrd_dnk=&yl8P4VYfs_qZi=&yY9obKUoacqbf=&d3FBAFVrlhro_=&Y_rflxUrXbX_n=&ELNONrUcYlemo=&UjqCGDZ_VihjX=&tS3FT8WZUas_k=&yinmYOVmXnsaZ=&vBWvBwZpUbVls=&SwLWZnYiYWVWl=&UZceMiXngZjhd=&pSR6NpUmaedZU=&VSOuDmUXbhjdi=&qEEP3BXap_pqa=&SAe4UfWngr__j=&PhiPKDXhdVUqp=&amf7GwYlgVpWp=&NprE3lVcflnmZ=&4wd_btUp_klpU=&9wnmuvWfpasgl=&SzLZaVX_orkWZ=&N6sGnEZokXYi_=&38KAtSZeYebZc=&avFBF6XmcmbUm=&qInoRgZlcisfs=&YbQTIQWldcaXY=&OQVCWdY_VrWef=&9Bm9LkWggiqVe=&Wjty4PUchnfso=&76Om85UailjaZ=&cAaBtfX_cqbZX=&jVeYN8YefkaVj=&aDIl2GZfZnmgo=&zUnZn8Vhja_Yn=&BgxCfxXjrqcdn=&wD_wHHZoigXjd=&hS5G6gXqrcqab=&LeZoLsZXmjjdd=&2TuUFtYjapopk=&5wQai_YZUbXg_=&Mf2YrFWqsYqnk=&BrS2UdZdphdUk=&BJfgiKV_do_oi=&rBbdTsYbeamfi=&v39O7GZjcqXgj=&i9UvP2XYamqZc=&9zoPyJU_k_mdb=&MV97tvXsjkkma=&VJiBuvXqUcijp=&RCbJX9XecVkYb=&k2wHC_VopceUj=&B6seeLZdcUbef=&42YHcyYnUokVW=&S5jChUWsfXbsa=&uyUxYAVhjbiWa=&fCREXzXogilXq=&e2iXCKYiriYmY=&SRjwrYXbcor_p=&NWb_BlYZckmag=&DNbOKKY_ddeYk=&kvzxQwYfsfUfZ=&s8pg7CWjVdodX=&_vZHl4Ublrpak=&RMHyrBYmjWigU=&sEgMzkZionUmi=&irwSIXUrZcqil=&dspH5SUUciaei=&CwS_axZWganqk=&AO_AuJYWsmceY=&UAR6mcZkVYnag=&hYm4ptVfpcmfr=&hCnN4yVecWV_f=&zKyXdrVroc__h=&QQGkETWb_adUk=&cu7N6QWgVrokf=&QNCK3oYcfeood=&btnZkMYlblUfh=&UpII3FZriWndd=&ytr4tkUdbrdhq=&MKBJCTYipabVf=&o8rqDiXUpbrnr=&2OAmmcXkojd_b=&jZx3aVYXd_fjX=&WfAHgmVgrahkY=&eEl__wY_rkisn=&hdxi7SWVpeXfe=&MhfAuqUWkgqng=&yAbMEDZcmihbk=&nFuDkHUiaojpf=&KzmiPcVUbrYgU=&Cvo2ihWp_cYXk=&yafa2PY_Vhidn=&P9jOpRWVkhfhh=&8QdQQGZYciZrs=&CjKU5SUiWdnmi=&mQojwjZppVoWp=&7pdUnCU_sfqkp=&LBLSItVcfUU_h=&nF8nPfYoWiseX=<bkEkUZWjp_X=&wHqUoPZro__pi=&2hlLfzVWbcpYo=&RieSSaYbpe_lX=&7d5kVkWYmjUnj=&roCr_AUkrid_p=&k7ybjMYkmZqjj=&wifcZ3Zo_qlqn=&oOTMrRWWVmscZ=&GFJ9bcVYZbdcs=&AtSROVXVhcajU=&6HE6dCWrgUfba=&vUbwLnUkgX_aY=&glbq4oXZZXsZp=&Q3ruYMUe_ogco=&4i6sGJYgqlk_l=&MkXvtGUfhgcqg=&ICBhBiVldppUh=&JmwnMNUsefioZ=&vEOt7kYckehUs=&ozF9MOYp_bpos=&8B_Eo_XipWg_j=&Y_Hl7zXmYZrmX=&wdXWYRYgqfUdq=&CP3WyYZfXplfi=&Dy_t6IUWaksjZ=&IggRs_WXVakaq=&ew_VRqWcdiVif=&OSpwbvWUaVkfg=&NjETjwYrmnkhi=&OJSLG4UUkZpWq=&tfA7i3Yasbbgh=&pnefkeUmigUqe=&N9iTxZZppUpro=&SA7VoyUgogiYk=&Y3EkrYYr_Vpcd=&4eBOy7Zmj_kl_=&_4ocPpYjV_VrY=&wJUOfEYYoYUrm=&mAuBDVUYscfgb=&HPo8_ZXsrinlV=&8ghN5ZWYlfsli=&PES29UXhkaqon=&6DobjoYmUqsgd=&7As7KIZqmpipg=&KPX4S8Yjmmjfm=&MJmu5EUk_ainl=&yHieeFWqdfZgo=&Lcn5a9Usmbgso=&3z2eUbZoosZWW=&w7p99UVacnldm=&SNzm_oZefmgmp=&yBheedZlmjhlr=&bjAxXsVssoXrg=&RHgIlyU_nnUdX=&75LHyeZVcjqas=&U7cs7VYeZpalX=&eo9HDCYlnojqm=&NM2M3lYfmXm_W=&ambnnsYZ_ohUU=&B8a9ncYlso_mZ=&Py8NE8YmiXU_Y=&mkaISgZdjWkff=&h4sotoVksoaan=&iij9avXjbsbnm=&GzzruWVXWsbVY=&9Htvg6Yfnmbcg=&NhfGZEYXrfcUe=&LRA2pPXeisfsU=&9wHvrSYlnpgYn=&SumaFEWbnkYpn=&TqGXXYYWcXjse=&D_taY7XhXj_lo=&XdcItEWXY_qYl=&4nhr6uU_srekl=&JiRgUYWVrdcee=&oBNyroWirjYlr=&KWBXZyXlZUUqf=&pm9c4WZkeogog=&PI2DTPZUqjYkg=&dNgcv_ZZcoWa_=&im5C6zZoWYhfe=&kYKI3YWimll_p=&cVckEQWdVogqq=&BdCv26YbWlVql=&3_zgKsZcpijre=&rAmG2PZacUgcV=&E_eLn8YphcjhU=&eztGjZYgpcsrr=&T2nGOfZorralh=&pDPV8HVVWYjso=&9pGW9vZibcZk_=&y2OoUSYV_osVa=&4GHjChZsforko=&VEDoKIZbYcsar=&rA5oWDYhfXrXW=&oNXBYdXpaWsjs=&u5sYf9Zrmjrnd=&Wr9zyzZorVfXb=&gzqvPgXkYspsY=&czPhevXojeqql=&9ZFaTvZrocXs_=&zW9rZYVqXpmrg=&KxszuSXUZdXje=&NPztreZaabnhk=&kCaDIkUjc___h=&mZsDZiUalffnU=&Qq9bm9ZYXXldf=&5bdfPdZargVWZ=&Nmu5pTVfsVjfl=&RAasJ7UnWbldd=&dJ8dxNVdkhV_V=&wTGRjmVafVndV=&fhQTInWceVjqh=&2ZOHN2WYfZhcp=&zuisyfVpkVdfs=&sxRy_LUadfUXd=&6K4QpRWqsWfkq=&vU3n87YkagYeW=&ZgSrxVWZYZlfb=&OCUItyYYUYpid=&nTOJzEXUZVqcq=&XRYGJxVgedlbV=&kyKGOKYiboXch=&4Lm2aiZqgpZ_d=&GppCLjZrcggoX=&n6jkeLXYijob_=&7kaH4aXnnYmlb=&l87LvZZilVs_d=&edBixmWWm_fUV=&rGeIQjZjaXigq=&wLwLwvZgiVaea=&lUHmhcVnnXmYq=&tLH3ptYpfhcsj=&QAE_BiXrUgiYg=&odfqnzZXrWVZm=&uJq_2oVZciipk=&qBiLTcZilZhqc=&XAj6tEWhnnejV=&tPnu7vUVbkdpr=&BzNGz5VsdilYU=>cJcFZsrsUcY=&FYgQM_WrnelfU=&Io4ZdsXoVYaZh=&DYux4oUdglbZY=&m3n_6KWVh_gqf=&d9Ts4RYlgmeYY=&Kor8pFXUinf_U=&IfDBsDZVhobcj=&hvNUeFUYhsclh=&EHjKmoYpbdVUX=&hhmJjoVooWmbr=&yxkXzBYZd_bgo=&covuiBVrpWnZm=&LPHhSrUqdkXqY=&bznIpJViqpWjl=&HjtF2CUnrVUjq=&jZmH6EUViWZen=&6owsgJWlgqVWr=&gcEvjuVdgfgia=&xfz6aMU_lYUZl=&m4fswZVXaibmf=&9J8JRBZY_pVrY=&pYRM35WsUW_lk=&P87fYoXdbjZfg=&gCL6fLZqshjqY=&ufp_sCUqkjVkZ=&cbbBjEVbnfcdY=&P2jA5MUrZgcas=&xSMAkrWcsZYoY=&jJ4IcuUkblaWW=&l4T58XUbpbrjZ=&EC9oGOVbqZlih=&72TDamYgjWnsq=&tEH_vNZjmmhhj=&Bgix7zVflXYUi=&99EXdFWqjarjX=&zpWzPIYWjfZUa=&x_i_tEVaXiZdn=&NPGcGoYXVberX=&ysljy_U_Vchls=&FYqlOhZqZYr_d=&Tt2GhYYc_dnqr=&SrzmlQXappcYp=&jIjlebYcnbpag=&ecXzTsYYrlXni=&K9XMnfWbemkVs=&eTUj6zYYjarX_=&9eygl_YgUceca=&qjyZIjYVZjkZq=&9ZkslUUYUXlfm=&Kcqbj7ZWebWqd=&fD3UwqZrWjqcq=&_7TMr3XWZiUin=&xYvG9qUgmnjVc=&MIUPeKVUdeies=&JJxpnVVrsepia=&inGIFGVsfkpfZ=&RkPBIWUjjbbjh=&HZ7ncGYiUjbYc=&kXv3IQZZg_Uap=&Gd35SZYZsoUmU=&Si_IHNZ_VqZbh=&Db5iRGZrUlljn=&8_7sU8UjWkiee=&IwkhlxWhaYcsj=&WtMWiSYpjVmWX=&tUbSZqZVZeqUn=&jDBXMAXcabVVj=&HRxtRJVbmdjXi=&eGZiGpWcUXaWY=&B2XAvTVWXercp=&MLhGANVaeYmsj=&IpxBC8ZiaVgkh=&MKc3MxVfVqUpY=&CaS4xBVh_Vmfe=&RckMKBWiZbjpd=&WGwb4OXike_so=&KiiGUEXk_r_an=&SDEAalVe_kjsV=&L7akeMZcWhlsX=&h8sdLqUblViq_=&W7zSO3Wfn_sos=&nFRinUZirfbqb=&SYNC8EUeqcqdW=&hMgetcYnsc_hZ=&dj7WtWUUZhrdc=&ZMNDNhZXUnhkW=&v8yFrlUsqkVns=&lPCf4AYsebWXf=&cCytYkWlX_ijd=&cR8mY3VfkhoVl=&DO5a_zZoZfoa_=&BgzsVCWlokngo=&FMpxdcWmmpdeb=&d2UhSZYa_qieX=&FyWySNVUbj_Xj=&6CKfpGY_YYfqj=&4FcPukUrkVqio=&PmusiyViUqmho=&JBzGObX_qaesW=&QGEg8hZmdhkiW=&2A4gRzXmholqe=&geygm2Xkdmsk_=&t5P6neWWiZnWr=&ep4KUHUgpiiVg=&epY3dzWflXgir=&lqkLc2WZcoqZg=&75tlmrZ_WrmW_=&hOu3VVZgrelbU=&jfuXHZXmclWcU=&n2or8TYnsoimr=&Ih7pifXXlYrnX=&bKzOiFXejbWad=&BrEWysUZjUcgj=&zYdOLeYi_mgrf=&VwLNwBXqoijar=&qWY6ynYgUsjma=&uTPacDVbdaYni=&EUvxqMZjlUkXn=&EcMokxVVlVlfk=&UuBLDVYghhrgY=&g_ek22Yedjjff=&uvULPCXraYcsg=&6kgGw5Zsl_Y__=&CAK2NcXnrohXW=&P72NAUYqUUiZZ=&Ii_VIoZV_YYnb=&MnFmsUYlcXZeW=&XCirxeWcgkWZn=&oMoit9ZWhndbX=&92C2FHXpcaYXY=&36_WhxWckaYkY=&_PU3dEYbbrbkl=&DRy8vuVqsabfs=&pgeIVHYkkicdX=&7z8BZwYkgnVgn=&g49wbIZsbUjq_=&XdSDL6Xjkdnpn=&ifNcHHUslhbbf=&zb4mqAZhXk_kX=&C5ds4dVYsmUXk=&WZR9OHZUWfblq=&3Rw89lVocciro=&XEt5mlXnnrbYX=&RJh5IDVaproqi=&rvFFtkYkqao_g=&dWROGMXUccpif=&bQdyz4Xdr_dWd=&_lpuudYipkgXW=&Gr6zxnVdsYYga=&u6924AYZdclod=&RzDML5Zs_hbdX=&L8PnVvZioshgV=&8R9ZnvWoUYjap=&Gu_sRPVYlYhXZ=&J5EkWcWdf_Vdk=&gJjiaRVl_hqsn=&mNPwCsVqnhghh=&3IC5fYVsXphln=&i24KuBUmfpZ_n=&cyFnMFVbaqXnc=&KBjHaDYZYoelp=&MlszkAVVXjjlj=&ZAhxssXlmZmns=&4_UOShWZqVXdh=&nFMOp6VdnkUXh=&eRTUCAUioZ_rX=&m9Z8FsWpW_cap=&PME8AiUopWfr_=&3UA4UcYgpVYme=&vsx39hXmZWUki=&O7ECSSXlhdmeh=&3GKGbBVaZfp_p=&YPHEXCXYpcqVr=&yt3U6jWl_hhcd=&8jWg4WZkbYbdi=&EojpIPYhrZmid=&b5rMF7VdkZnhp=&xgPMkOYbmfnXV=&EyLxdsXWVbVfd=&E3GI_eU_lhidq=&QFUddUUVcnnUb=&VUdSTLVegfsgb=&x_iOCqUaVgUif=&9dG79VZWiZgUn=&8WEkFmZXVneja=&lO_BxIWakUbeh=&WPTBk_Yssqoig=&qwj7LIZpsknYc=&ME2UCQUnpdeWb=&vPVujMZniqaWh=&Ab84JVVqmelXb=&Rjwyt2UfiegUm=&JTWobUWraiqWX=&w5X3v2YaWiqUm=&qeegmBWoranca=&VnyiYNXYjegYe=&HbxKIOUgnYVma=&2DfG4EYsggmal=&QuDRH9Zssflol=&8PfORaXb_lZdk=&AgmBwQUYbbbXi=&vr8F_tUXpeshf=&QgG49mUhdiqph=&bOBBgWYXUcrZl=&TDGPiRXsgkjgX=&5dZoHRZqkpmri=&SYcZm5XhZabma=&gFd6iMZUYlqUa=&SgBrliUcfUbZp=&JTJun9YYdodkl=&4vVYwnVjpensd=&empxv2ZlqrrZa=&9UEnkPXZi_Ylo=&lsX3XnVfWsX_e=&BBfZVtVabkres=&NvusROVbdkcWd=&RdcubAUaodada=&vD7d7BXrmZiYW=&dZq_jMYihUkZm=&bMxpnvYjiaYXm=&EjnqFOYjosXdl=&G4tjgWWkcnYgZ=&pSOUDNYbYZWYY=&yVedqCXeg_qso=&Ay5cSLWZZqaYk=&EOTqMVUVinXsk=&n4nibUVnnUgio=&8iNVk6Znprobg=&Xq86DbVVbVmZp=&6ePilWYcooUdf=&bkScJiZarYlcW=&oMecAJZrmfkZ_=&TpH6snWme_oaa=&v8ddxtZZko_pm=&MuDHI2XkfVmkp=&TvdEF7Zjkidnf=&DEMCJ5Vhkphgr=&y933arXWacUYp=&WkYaRHWhhmdki=&yKvXKDVXWqVUb=&TAlNYnZoZggYr=&3wme2vZeadXeU=&r2HpcnVsdljqY=&Kk4d_QUsVXagb=&Mh7HQJVjdWbim=&B3t9ewZkcnXoU=&wXwfgGVfkdlah=&KM37cHYhsqlek=&34oKMrXn_mmbU=&CK_3zPZcol_Yl=&IOhi3AYZpjlhf=&_PviiAYcYqgWh=&mFrEEMYVjlhjo=&Hsra5ZZrgorfm=&MjZxkvZpehskq=&RNxB6bVaoU_ZX=&NdvPMCWUsdsc_=&iL9WhHUfj_mbV=&wWYSH4WpkYqWm=&_oB8EJZlbWnom=&7qxUULZskrgef=&2cxUDvZbWjjYd=&8UFttDYepZWfZ=&yU3qlpZZmpZpq=&u57_pVYWgkrme=&Zvply4U_pslYg=&2fjVmwZZVmfVk=&VQ9pdDXiUdqlg=&62fJTPYlmUjX_=&Ry2qBIZXjfZel=&a_GCclVXflhYV=&s3PhKnVgalrih=&jnt2k8YajdXqd=&Lt2DFtYkYVYbZ=&IYi8daVnhdcoV=&_49i7lXhiWsVU=&N9TcR2Vknkghg=&vhsAe8XZYanpY=&rlzwyBYqopbUf=&ZbTLkOXYWjXqk=&49OLORUqiVrsi=&KXEXsjWrV_Wfd=&IAuWceWaWiree=&MPzQU6VeVojqd=&vJ6LVhXhZbar_=&brFFBbWsfalVk=&L3HbilW_UbbUf=&HNsedHYsWbpoZ=&A_7IIRVYUl_q_=&sjEPNdVbcWeZg=&jpNChJUmf_lea=&EOzDS3WmkgVWa=&BcbLCLVVopakY=&oDtVNwVqXZWkk=&GACIHDXsorjhr=&7ujYk7ZqdbsaV=&9fs4vPVmZdjib=&yVnpAQUmhnccg=&GvYZklXbrpWgc=&3EawAHWVshfWn=&9N2zHxWcYUmUW=&Anl_rCVciliWi=&KYxaFwUfVrVZs=&YGypGkUUpnshV=&BXEeoeYdpacsr=&bYWL3XWbXpZWk=&LDWKvpZVVicZf=&SN_nRrZnlcaWe=&snKF8LXbakfgY=&dAAje5XkhYdaq=&jaaU7sUhcbVZW=&Qxx6LzYdoUnUe=&DJBU2FVsimsla=&jIvrcLVcqUqom=&ykDBn5Zg_csXg=&afTNIkWVsmZhb=&4kBWzEZbebrqU=&OWXHeyZfaVnVo=&pEjgOkVec_nrW=&2SSQiBWraiUmm=&KoO5RqXkepki_=&8CQDjzXjokr_c=&WahLg5XbViWea=&8GBcqSWjpphkb=&nEWuocWngXUbX=&LkrVoDWmcWgaV=&HntDsfUeqqqsU=&WEki2LWaVZYZo=&OQ2MA3YbYkfZX=&tnKzVtWigfgXc=&KTGWBLU_hZkjX=&XiW4xpWggiXYs=&QrKSyNVrfag_g=&7e4MioYneremq=&UOTB9XXdoYbaV=&mEN8VzZ_nalbn=&9tNqn2ZYjmjma=&gODsm8Vmipfrf=&G5sQwaXXrkjVU=&6w24qNUmiWZek=&tyLVm9WrkVVqV=&Wu6jKYUnZjkVn=&85pGD3Ueoklnk=&LkVvdSWrcrjgo=&QLmblxYffcgha=&lf4VSiUo_epnj=&RAid2LUssrWfj=&wwc9qQZafhVil=&FqQG5dUcsiWWn=&uayIZQY_onbeU=&daBQc8UXilhha=&ewYdnzXkkligU=&eI8xyxXacea_f=&ribzyQZameqp_=&CtBklRXUpphgV=&bFYmr5ZcsgfiU=&Yxiaj4Zmsnjlk=&yOiKiCUdg_c_o=&qg_5yCVnoalYg=&G2Md_8VZhhWVX=&W3XRKaUYnoZeV=&DqDFSFV_ecVYf=&N5j_2IXaYspXX=&sxIYUEW_phcZV=&ptkZYYZssgUbg=&XuAGZwVnbVsbU=&eEQ_ROVlepqpe=&aLrWJeUYUmfVq=&ItdQ5CYpolbXj=&3J_bQOVmkhWbq=&5hS9jtZpfXXUb=&ymiRNgWineYoo=&hlCGewUsnkWkc=&8MIVxAYibUkhe=&RGI3icZo_efYa=&7ZGx76VgncmrX=&QyVgnsU_Yghhp=&zpYebSVYiUdUm=&UNAYpAVhg_cgj=&EaqLwWUoqrrmg=&Ti2EhrYqecXWa=&auBrhKZbbYVis=&9zLLPXVddgrfh=&JIsVDVW_Uqodg=&JP3Xt6Xkb_Ymk=&XaO7ogWWpVikk=&TKltPXXmoWgja=&wDXKvVYfsWalV=&JjwOoiVXYWUYp=&7MYfvnVVnljXa=&TGNn6nVUhkbbg=&c9YF_hZagbdko=&8HJ3tQXiYZXU_=&hlSUsIUcicjUi=&GBDvPjVWUVdji=&vwsjUSVpdfl__=&Co4u5zYnrXXds=&rmHPdnWpVWXhq=&bbzqEZVgeUpWn=&CJ4ed3Yj_eisb=&TYv2juXabbpba=&HPnJvVWgVsflq=&N3sYUEWqiUsYa=&OtTDUgYmmWWiq=&CN_XLyXfsjZrh=&UJAAWWYakjerc=&pJt9y4VYjslaU=&qAxIp6VoeWojg=&48JiLGXZfipXe=&7sXiz4YqYijhg=&o6xxgSUnqaVss=&zrz8WOYbqWhhW=&I6eV4UXojrqpW=&gnVWd3YdhYhjo=&tvsx3uXrpmbbZ=&Ab5w3QWjncajl=&7i_Ka9VfZdhsU=&7jaLm9VWembal=&uPv7vmXhqWYfp=&ZSNOGoWoeZcjp=&pdZQ3hZakbgn_=&_LwNJeWlfcdls=&5CZrWGUhcphjr=&BkaRxcXppqWqr=&EvCGF9XUssndU=&n62Wb_VhXfseV=&jw28ulVsbgYYf=&RHO79kWVpnfcd=&psRRDUZrd_jZq=&VDmds4Ula_sUW=&ZlXzRgYZneb_X=&HRFlumWhUfrdV=&zN2m5IWW_efZW=&QuE2mXZkofsmX=&nEqJjgXkWggor=&Fb6LBiYclniWm=&25GsqNWhdcZso=&O2SX8mYVUVaXl=&ApGBc2UXbnpqc=&O3U5FNWcalkXj=&hS4MGWVe_plln=&dvGjAQZjcolap=&tmVO8gYZonnkX=&AglrFoYqUaZib=&nt5__LWgpgmZk=&QoOdWWYllifpg=&s3isdXXgVdjhs=&2XqSxGVoofqeU=&giOKkQVn_moXm=&tdOoNCWgjjshd=&SSaHb7YUWXYWq=&FJPxiKUgdbhUe=&apM3ghXpiXbUj=&CVkFvyVmjrUnc=&TjQI_pZhgVlmW=&g2uxw5Vqjphdc=&kCr6ZxWaXglbc=&3DmqQmYc_cokU=&aD3o6mVihrhch=&nVfHBiYbijdWh=&BXmgmaWhYXfai=&aHkxkiYmpsZV_=&vA_lcTZqaibii=&C539CoYeYdWqo=&qsfF4VYkipmWa=&UmetFkYlmf_na=&IK8JQaZbmifea=&axSzLkXgbos__=&PObAPiYkdXlhs=&FDYNXnXniipmV=&MsfNOHYdZodro=&vOGZ8JY_pXZbn=&ZsXm7ZYjrfWrk=&xnmnCfZkmWiag=&ABFpzQUqlihmZ=&WQTPEcUY_oUbo=&AuGPcqYgaXqrk=&_zsmgAXglU_np=&_mjB4kY_iXWsh=&LUECO_Ufkfgka=&uV55GyXWgqdYk=&en65YqZYaiXoX=&UyeK7PVpnlfXg=&aQYcjeWWpjqYq=&9WdgSfZqVYjsq=&NzhlfQYr_smeZ=&QIT3jwYmZsoZV=&BXgM_YUr_YpbY=&rQCd7LZahX_kr=&MSrTz7Zjnf_hp=&V2hjHpWXfejYo=&2R9n5jYkWqgoX=&cEm59IYeXfl_a=&4x9b_XVqlZYjZ=&3LPsMaXsqjhcY=&rojIQbVdlqUZ_=&w8e8j7Vrpelff=&kg8GmoWlkZgdh=&Vy_uKxZXgsVWk=&tldbpsVer_oss=&ZUIXtEYUdmhWi=&mbcaGEUbbllcY=&aHbx2HXVgUVVY=&_pjSlpZbbnisV=&ECZwqcYskjfWq=&fiUW8IZfgimfW=&LwgkbTWri_kkl=&jdqi9QVaVmXZh=&AshJOFWmUcVdW=&6TZkfkZZkcqsh=&UAw42IVaeXVln=&suWx38Xrndo_b=&nekR_iZqWidip=&sCw7CjZkUqcZU=&ZgDkJuYbXrnes=&tNwCVWZipamUi=&ranrobYaVlgVm=&_dD88xZqUpfml=&Dd8mdNVhpglaW=&pBZPgaXrjXZZd=&lGtOPLZZ_bbdq=&PLFKFhUVUnUVX=&3wOkAIWXkZXic=&ayA94LX_WaYsm=&8YyQJtVrbWsid=&pNM3XbYjrsZXX=&rv8NKZUhneios=&yshw39Ygcln_q=&TELjkJZheWlfb=&k4exlaWXVYkrV=&2EeFwTXXnVknV=&AM4LXFYVlr_sc=&yjo8FJVlgaUsf=&fa856xXn_fdYf=&5WqHvAXbfjj_a=&Mxg8iiXgV_ihm=&TDfAhNVdcqdgj=&oDnt8SWqqgo_p=&IfNmJaZjWigiq=&Q3uCtzUonabid=&33Lw76V_fpcUi=&kep_8wWr_jajq=&WapMdyVZhqkme=&vsJd8KUggiohq=&DisufmWb_hWZ_=&rul8g3WeVl_hb=&E6Zr9uVfbYdqs=&wZGINgVjboXkl=&P_rAy6Uimbemf=&o2MQJ9YZhpUgk=&47w9qeXc_pngh=&NPLKy7Wqpkk_b=&95tQ87XWnapfZ=&JavHI8XYialnm=&c7vYK7XXrqocp=&HbVMQtVijgUfo=&FE7bY5UUZgm__=&XZLTdxZlWqsrc=&XtzgS2XkjkZZV=&wjSCxRXqjWfUl=&zhUdEYZbUgfhg=&9skhNqXmnV_cU=&nkhOhLZnbeigW=&HfHRjmYhfflrZ=&4I6xlTXZbhqjZ=&LombuDWXkmirm=&2DxHHnVpVZbXV=&6fLsckXld_WYj=&6qkHQqWXnjgbj=&6vkrlXXcgXsXn=&qZO5ECUqo_YUo=&vbK6hNYdjba_X=&j3d8udWsneXgh=&d69pcbYdWUjhi=&mK9RP2YqsVpig=&2JyGNPV_hlgZb=&h28AWMZqclmi_=&4hhQWYYmsVffp=&tB_O4mXpnplqp=&RJg9xQWkZomaZ=&ZUeDefYcshkpY=&q4rYEMWlWqiZl=&og2Rz7UYnWiob=&J_iEM6XVcbiYa=&F9lF9pYXYlmjm=&RufVVkVenjoqo=&pmtTs3Vc_np_b=&t7pqUkWbd_k_n=&WG7tIqYWqXapc=&Dmkb6oZgYdkqq=&6aYov5UbgjXse=&NIZQ4TZedoUXe=&cYfWx3VqqXrgs=&FjjszIXldZmVi=&d8XMIjZWYpVqs=&LNLvDHVbZjYlY=&xHTGH_YsZZrok=&8WLdB8W_lejge=&fSJJEiZ_XYkY_=&cvXz_rUqVVrZf=&e57ybWXXcoaeq=&tTCqcFXbcsbgj=&cTbT2eYmloYcq=&i4lBgbVZlVeYX=&wwnjmoZ_jbdUf=&GNB4aFXjlfXfr=&cIZkgVWUlYUrh=&xxu8pdWcckegg=&eWvqZ6XWiYjbj=&jgAsVTWjnWXnY=&A_zkPNVpdXgcq=&5KDHmhXVhhrd_=&cXxe5oZXmampk=&shqwTQXmjqYj_=&ARccjqWfibZdd=&SJ5m6SWbcfq_b=&NGKe9zWfWmXfa=&L7Xvu2WjYh_kn=&6bazHXVjgUjsZ=&r9fBk6Xfee_aX=&w7c39NWUeXWkd=&BnjywMXknUV_n=&XJgtYXXmilqXW=&lD_wMLYfXUXkf=&jCKNSgUlpfqbh=&jJ2e5wWVhkUc_=&UL8iNDYVlphgX=&ZsDhuhXnWWVis=&ruaMEWYiajWnk=&peUdZXXkfWZbh=&GMxiYSZijUXr_=&httF94UbhhdWs=&MMsKsYXUdgZhf=&vCuPlqUdoasZo=&d_o5hIYVeY_cq=&QTT3R6Ydroisr=&9pyGaXVldZsjY=&ifmVhqVscpbWh=&qGuEWlVgnZkip=&8D52drYbmdbap=&SpaHwbViibfcr=&HWhEKdXqYmZse=&Ue6VXTUcdnmbs=&6uu5NEZqlhm_U=&jtF4qxUhldqcV=&Gp4kjtWegWkqh=&rOtOK_WVhseal=&sz6EXbZXcZqnl=&ZBhQgKUjmYUd_=&Cegh9jZpnc_lf=&t2ZOPHYmlZUqc=&Nb5PlBXfcpfdX=&pY7TtzYmpVdgc=&RTEjieYXbcjna=&tixvMEXVaohgp=&WvPh_kUZehpbW=&oXOCWjWbpkffp=&Job9DiUq_Yqgg=&Mus_bcUghpVsf=&kCvgz5ZYe_hap=&iT_CdCZoUcsXp=&6FSz7TXpf_fsl=&jbhBKoZmoZXka=&ZSNlguYg_l_ZU=&I5MjDVUYadnlZ=&IrEWHiYgsibWo=&cYaVEeWcfZrfY=&7UpahVVVrZoYi=&e7csGPZm_hYoW=&lfJyaLXXXiahf=&VBeHYGYedYZjh=&td8ZcSVbpbrW_=&9sLlKkZigkpcZ=&pZc_faUhXdsdk=&Z7TClrXgrebUa=&GezMvTXpfhXbm=&TumTxgVWgkkkV=&Zn3bvqVeognUf=&btXzdfZfo_s_X=&JHxGhKWfadndr=&nBqYGsYfmhafo=&kOLIIBYZ_XbnZ=&KkOMDeYirhoeU=&fPSFDLUfsjhlk=&oJJ_g7WhgdmVq=&97nOe6Vesrgrc=&hBppviYoqsfoh=&2GYQSsVhnfoce=&QhfJdYVaZfeie=&bkycbZZnklWgj=&cAGeElUrqdslf=&U4qL_hXVVVbZs=&iicUQ8WhWWagj=&r4eeUkVcnidWm=&SBF4blXUUrWhl=&p8BIRcUeZZpVp=&DlG2glXjho_gs=&JcyDDkYZhe_fj=&rLqTbkVbinemY=&8ITuYmUseZaas=&RD3jLsYbZbYqs=&zJXmIzYlZrmao=&L2AfBdWplZprp=&gm88zZWVfZeiW=&LPMxQFYsUhbdm=&m8zx79ZhdeXpl=&8wZ88MXWjWXhh=&kh_sp_XUsgWma=&ZITpPiUhraY_f=&FZKlE9Ul_emsf=&M8w8vlWrjqcje=&S2qf_XVXojeWV=&a4nYOHUZjXlog=&d_6dBjXiescgn=&iKNjtnWXWXoin=&DM5MXXUseUUXl=&Rxq5lBVVbif_Z=&AsIacuYoYUrka=&mggxwcX_lrhbX=&ZaXPrKUdahajq=&g57QTXXYnpomg=&Ll9fEmUflscae=&Qs4MLsWelhpWm=&iz2iTOVmsjWma=&CyQexbUZYqlji=&sSI54YYgZdrVg=&O9SxFDWs_oggs=&92vgPrXejcZse=&h6NZhTXjklqmo=&d6EiCxZsVrWbe=&ypdjEFZZkblbe=&OmjeYmZhmcnhe=&DraeUzWgqnlWi=<N_ybXYorUjU=&HFyONKVb_ihaZ=&zkYKONVXkVfor=&l2hfT6Vi_Uehl=&MfmsxRZdcplrp=&9anvBlZnYsVWc=&Ncc_QYYfcncks=&IE73V8WmaXdgd=&LjReyIUafacih=&FqZov9WakaVho=&mzfpxDVhboncq=&3GbUcCWkrihcg=&noQP8sW_UqrrY=&jVaueIVfnfWXg=&9SxKJGVVmdjZk=&XfKYjsUqhXb_h=&gg63gnWWWUfqg=&_Vcdd2WhloYVq=&nzYTAoUbehkYm=&3eGT_cXZYhdis=&LJOPo7YcmmWcW=&4TdhgoXlosgmd=&Sc29rpWpr_bcV=&dDct7yVsmkcZ_=&joenRRV_rWcna=&SPRdgaYlgoada=&MTiKcFZnogafW=&jr7pBPZaVZolq=&tPIWoUZaXkhWs=&tvoAydYlofWkW=&_ClTmYUekmoXm=&bCNVIgUXoYfYa=&dV_MxHXYemnch=&NuQGtnYlYWbkk=&HF2iuEXVVfoom=&v_MzGfVid__fd=&8yysHrYjUYkgp=&Zh896NYlj_dns=&xyr5ujXiebpWh=&z4zZ4wVnjroem=&K2FIUPVrrmnjr=>dwXxYrdWWcr=&Yi9WTQUajoZjf=&8YF_MLZmqkqkZ=&FMQRIIZXjgn_n=&lZiMWnYhUafZr=&Sr7QAbVqoeXWd=&VP5_UcWYWYWVo=&SlwId2UrcfWea=&aYqVDrVmmaqXW=&MarBTJVXr_agi=&7nFAFQUkpbkbV=&5srgw5YnaYibq=&gy4bK9Ycbhr_e=&aonOPlWssoUqY=&meINJTWWZsqqZ=&QuWt2oWmYsoWp=&Wk4B9pY_VkjUY=&GrW_3WZkVVZiq=&lMyez3XpsUbia=&NxdSngXajUpsc=&8O856bUfZlYlp=&8lhCxdYdaoqsp=&aVrLBrWnZsqme=&jgqwZuZaehghc=&9b3Bk2Y_blcdj=&KIM_IvUpXnjXV=&VBg7V5UZenfXU=&8xzZOnYWUq_pd=&QIT2unVWdXiaV=&DKwvGiXaWmose=&hPwzkVZWohgfe=&MR82gSYsaUbYj=&izyZ6DVXhpZeo=&vV7ACaZfVeiaU=&xce8uWXsqfjWW=&KmIfHfXrggprs=&weVxXtVnlnehc=&uzSJl8UWXq_rp=&AjjjYBYkboejp=&2jQlrzVoWadcW=&cmlDf6XYVhXcj=&B4emS3V_ZdZhU=&pfSTcQXoqXnhW=&i3f_pzUjVeWpd=&2x6MwXZeoidWp=&vpPGHqXbjnlbX=&LPAjfWVcjplhg=&s2kMahZaVWnmi=&NHn3BqVaooZoh=&w6fCL5WmYoUZp=&4vZaBpV_dUmsq=&3mr4keUommrqi=&S4Vm5yZcgiZpW=&tzRQ8vXprbXkX=&EOeZZEWYWXlgb=&UsD47sWcjVkn_=&FLGSKfUXfpWnk=&2qHClfZaqbhqo=&yoDH8NWYWVqqk=&Q7nKq5VXnodkk=&kTgam4YegZpl_=&haTM4tWdsbfhj=&9mIhESUgrqYZm=&283SBwZnnWcgV=&tFVvrkWrXYiaY=&z2FBn4ZjqrUaq=&r_PPm8ZYYpbkq=&dxO8ndVrdXeXp=&AwtBB6ZcbbY_a=&5zYsTIUYe_bpZ=&_bBHC4VqiUokW=&tpWeWwXiWaqsa=&Ln3E9CUYhosXh=&SqwfcgWYpigcb=&uOGH_mVVgaYUY=&LA8WCIZZpqWXV=&Qoytf5VqkmXrY=&NrewaBWaU_qaU=&teLOndYZjZapd=&T5EHDNZbikqjk=&xCpmNIUae_srb=&AskFy5Zpnboec=&mPeTZbUdXcjcg=&8pILnfVXigenV=&H7WVNOZpmhjiY=&JQNmTOVooUckb=&zwHOZhYrUqlUj=&Zjmq3VZfoobgb=&EOU9YrWj_Vrkd=&YS5StsWjqfohr=&u2fe8LVlglpsh=&xVaElYWgoekfj=&6BPhaDUVosgZY=&KIu8coYbWsimp=&xxW2tIVfcaZa_=&8qRxFHVesahbr=&bueI2NUWbscda=&MUgKuEVeqjiaV=&HWhqK3Xagrcgr=&8su_B5XmpiYrY=&OQRO3KXjfmens=&LgTQL8ZXdYmos=&dTGEijZmYWcri=&jFwI9UWrlmWir=&kSjybuVe_nYfo=&oz48oiZleemai=&r7HnioVaXjsUj=&pYGvOuXaVqsnW=&bgSCmEUepslXf=&KmBShUVogsldW=&_Tu4WkVhrfqUl=&UskMirWUqYohb=&gBav8LWrqXgkd=&arpdZqWcUicYl=&5TAvOBYojoil_=&ZiVUaiYdVUWjm=&L3pxOxVsima_q=&GEXLtwWZgholp=&Y_My9BUYqloUZ=&gayN5AUbrsWYe=&YoYhFGVYdkZgW=&nV89QUWUVnmfV=&k_4nXXWUkjkYs=&wXZWRaUfhognf=&jVURUSYaorXcW=&A3tXXFYfoZYZW=&UpxPwLVqfarY_=&5ifh6xXmVhplU=&HLbZBnXgec_o_=&JnJJluYbqcrcs=&Ae8ilDViodrgd=&vNhHFiVWjrkbU=&ehdcfqZYhpVia=&v2m6IcUYlfsUY=&mQ3KcBWcn_scb=&ysDBejXUZrdW_=&AyaQoIZUXWkjU=&4fl3YMZYmWWf_=&ia9zCaVmraarh=&yqqsXBWcibnXm=&tmj8FIVZqZmqU=&Cxdbj8UYYb_Zc=&AJnVczUpYokem=&NUnOzcWWergfW=&qCsk65XmjrodU=&7MZUHJUeaXboa=&rPRezbXfh_WVW=&9TjTSNX_dhfrq=&a5DapqZWoUhdk=&RSWZRXV_ZXd_f=&HGswzEWgdibql=&gAz72nY_lihnV=&syKr7pVlcZnml=&6te38rYgibpkb=&VpifCEUlUcWqr=&XYixF9Yee_XWb=&ZuXYd7Uignm_V=&947ggbW_iihmm=&Zny8JOYiiahcU=&Ir7x85Yjrdfsq=&pv42PIZVdneUm=&BEJ_89UYbWhVZ=&pC37yBW_YjVjg=&HqFtR8XhlhZoX=&7LjBsiW_XfYmg=&pjUebxZWYYZYV=&gw7CgDZdqnZWW=&AgEtK9XphZegi=&RXdQDeYljq_nW=&oSx2ARWcpmmin=&_nyJugW_sXsjp=&9XUUN9VZsnlXo=&9QfmJYYnqiloX=&hDnYeyVsfUXhq=&kHBaHdXkarqhm=&IuNh_WVparhWr=&jpukaaUYnfsgf=&oW2fqhXihWrje=&nzsmA8WWdkkre=&BwZHLzVUb_qnd=&vzkrjsUnjao_n=&I3aAHtUbjUcUZ=&zXuEhtVifsVmk=&ImIrQoVllsile=&7L_J5BYkmYic_=&vEPxxMZXVdlgm=&XjF3HAZqXqllb=&Wdko6kYfWsYfV=&GMBi5wXsVhgUd=&2w_Ee3Vr_pgoh=&gPcB8uUVopXmV=&NmPzwYYcVZrqr=&y_YhiHVXVXVc_=&N3x8qeYljpahs=&UuYT3dUdjep__=&jRVsefYliiqik=&chiMuvVbcbXri=&CE7RDXUXilhcl=&qC2c7JZbchdha=&TpUB2jYVXaaVV=&_hotEEUUZfnms=&TtZGdyYmaliUg=&3vjxAmXhjko_X=&oZfVcpWjUWXnm=&GGhudlX_iVcff=&usEHl3Vcj_mkb=&icbCMkUdXWfsn=&2UyNSXUglsprr=&YUsTdgXUZVkbj=&p4EIoIVYhfXch=&JRNCFfZoalYqo=&5CYrr8ZhXdclj=&Au6qFOYeodbgX=&okcXSgXohedjY=&ItoqjrVdifhUg=&R8ZBZhZagZabq=&PD_Ev4XeqsrgV=&7OPhyTVbhlYok=&gLy3SaZc_pVVa=&2D2WSkXVqaZXU=&xOJs8fZZrbfUg=&5rPxvVXkWZXqn=&89sbhCUjUlVoj=&MOjFSRYfbfpog=&VBTbS6VpUngUX=&73rI4eYpfWeij=&qzIVJFUfeqleb=&IO4NqIXcsWgrl=&dZMaHhXeajigX=&3xVmD2UXenhjr=&tfcgEQUVihVio=&5vC2_mYmrpVbV=&t_mvbJZdcVjhq=&spcxKPVjhgWr_=&ZaBaXFXjeVdjW=&7Ks3vRUpmpoqj=&LRVNhPWWlbdcU=&K_XlY6WUsdpdb=&ROCYpXWqqhmf_=&LhYWe7VeqaUbr=&9mE4nuWfjbWXl=&f_7xu3UVWhcab=&FehYXIWonmllr=&Yn2gt_WeeajiX=&a7kkSLWmc_Wfj=&pzIp39YVYronf=&YbWVpyVjrbgmU=&CPPGEbUVsemYZ=&MwcGQYUo_bYVj=&aTH5CeXbqlWpZ=&BENFyyYfdmVaV=&ZpE7UIZhrbmfm=&YoKlnhUUk_ogW=&PFNxPoYiZcnsW=&jklLtCZiZnafr=&tnYKXOUerilph=&PAPVSZZjcflpo=&AfxQQ4Ughgqgb=&xnUSB9XhZWXlf=&yv4xc5YjohnV_=&UjdoQbXbakkma=&kW4VSjZforVph=&w84DBFWgXrlan=&zpH6YUVn_gnkW=&Y5rCsuYqkkdXU=&Aj54qfXsbsWnZ=&aiK_6wW_fXaUe=&qMxl2jWWnfnfr=&F9vBKoYUaVjsW=&4mNcGTUagXjdl=&BPg6GLWjniZWg=&rTTbClZaUVZWX=&jSRmhSYkmhaaV=&HKlrhTWpgmaer=&8dEzJQVqYrYli=&k5pCEkUegUird=&UuyNuMVfqsask=&tHPo94ZWWhYol=&VlCbSTYVmoomm=&PAFqqKYeqshnd=&6IfiHwYVeghka=&E4UUJCVsWkXd_=&CHbROHZVsnYbh=&fc7WwgUfkpcke=&n8UwE6XrZjqUe=&NXua_cXediimj=&FghTcpUeVerUV=&nRwzT3Ycmlnmh=&Es9ZSdWVjZidd=&ZrQFYgVfboemZ=&ykK3sUWdfbsjV=&YVsVGwYlqUcqo=&kpWd2TXdkbcgU=&6rlH4PUWWUfZb=&q2vtIqWrkngbZ=&WGNsAtYVpXsnb=&hwv3beVhogqgi=&vGuGEMXkaomf_=&qoRDRkXg_qaVY=&9_upvTWgfnrYX=&PaeH2cXsXgkqo=&mPBeTSXoeenW_=&uORSI8WlhlplY=&3XoZcaWicmUjY=&2mhRG6VWYVpkg=&fexuC3YWdZmWd=&JELvunXVbaZWr=&pKq8ULYqmbZqW=&SKppsgYXedVVd=&LZZyWRYZsnakh=&RhjSa2YojUijl=&YjBBr_Xpdjplr=&Zhfu2bZjdgbph=&S9hHlWXjWjign=&9zduTQXhi_nrs=&pXNGkIUjqoXsg=&U8DE9gXksllbn=&Oq388DXdibelY=&5IKCFmYgbsUsj=&MU7wGcXcmkbmr=&rbAX4kVnoUodk=&I_DtApXXsWgUa=&HYqg2YUVkUXje=&oViuXDWloWfUe=&9jVzZVUcpjZqj=&xdFFDBVmWsYhf=&7p9JyxXa_gefU=&PIzPLFVrdhbop=&oVCdGeVjhmsfl=&8Zh8TJVmXaloe=&YvriUVXihiYiq=&CPJ3i8XmWlmpl=&o4jDcoYgjYaYZ=&JmLZmMUnekrVn=&dD6QcKUmoYo_o=&QJSC6sUVjolsm=&rsqu8EVoVeaYl=&wu3oXrXZWikqh=&YiovVWWbbhnWl=&MsAmpHXiUeYgs=&HSK3FRZiifcnp=&E9__7YYk_YkZk=&9ccufbXaWmmmq=&mJphJLYmofshq=&tCBixDUamjnbY=&Xosrm5ZqWcndq=&2Fu5CwWYqhnYf=&QaqvUPWZshcba=&DsgBZQZgrXblX=&NfsxV4Xq_sopc=&zLNF8fYbYlrso=&c5oDEsYfmfjal=&VozmUNWgpmZpb=&PkTFD9YeWflmX=&Q7oLmwZrleYWV=&DoyRvNWhddc_c=&WROL5yZYfZsdZ=&N5obYKWfieciW=&XpvtdfYZrngrZ=&FA58HzZoednZj=&Uqe4zYZbgmYZs=&ydBF3fYnsp_Zi=&rQjkGuYXi_hZo=&F4SV5VZdgoeVo=&4eQFekWhjjjmZ=&5OxfRyVnmg_rn=&gfLvxRVZcb_op=&cJWkttWWforUa=&_DqGzEZhmVrhm=&9eOLNjZWgpkXr=&uJaVUtYVhZson=&_aYMpaYhdjbnb=&vV4JrdYZmhqlY=&wUUGzaZpflmdd=&gfGpBUYeZhhgn=&vmAiBfYrUXqgo=&4DtLEhZnmksbf=&8WkjAEUZUmlan=&TlBqjiUhYbidW=&SXUOzvWcoXZbr=&oCXsaHUdecnZi=&yjFS_mXjgp_XZ=&_trjpmVcakieW=&FeEApMVgXbios=&uWW8vhXYVhYlU=&OmUKmEYVgdrVd=&JmGrZXXcfmeVi=&iuRSYMXsYopgc=&uzkBoJXYZpmrm=&34PfhwVpZjZiY=&Aqm5AZXihUrsj=&GZluvAXrersVk=&mFRJ5kXkljhnX=&PzCyIUWYrVkbc=&CEs83oWZiVYaU=&4TX_vsZUapZWe=&VYdXn5XaWZfhf=&Iq8Ny2U_iWZfU=&558a7BUedfkdY=&rWrmWaYhkieVb=&wwaKyFYeXj_Zj=&ROqBwMZo_pjYs=&TJfr6gZkoVjrm=&V9T37SYhamkhp=&oFEVfRXmepnaa=&A_klaYYXfnrek=&mVyU22Ykkgnlk=&yVj5LvVrsafhX=&q5BVfDYYensqW=&TanUoxWqehlqY=&_izpwFUXqddZU=<Zuo_YargUla=&7BVvzwZXinYWc=&8rgMhfVZdbcVm=&GjNMzvUhjccrs=&ASkzLSWZ__ocY=&4MOs9rZcjYsla=&_9EOfJYpXUnZb=&Pv732HYeorpiZ=&6ASRpJUn__eVh=&HLThLOVeXjUop=&xl5cEMVbll_iZ=&m7UntzWifodpj=&L3p6RqWaYenjX=&kovEI4YjfrrUX=&h2Lj3aUsZbdVh=&YSjnL2WclbohY=&QtAeseZbnlssY=&syZdUmYWWm_Xo=&2VsZPAZnihaZb=&eJCXFQUoXkZWi=&yrdyYpZZkmofX=&zYJnrXXkafZUV=&GvM5IGXalsVqZ=&JXbFhjVVoerqc=&lM6qyiYmhY_Xd=&FshbAaUmmrYin=&DugbHaWaapbXn=&3kBMNcYaYnrZW=&VncQcgVspXkpn=&N6zZGKUm__qZg=&o64USjVmlYk_q=&Ifm2RBVpdkpqn=&_9UfRkYfsYZpg=&q2N2u2YefckYs=&Vq6jnTYkjZXaZ=&xv2ZNdXmnpYZn=&JMsxi8XZrsqor=&Qttbt9WqYhb_V=&KdKUuvWolZefe=&PcazOdUnrlfhp=&uBEDDGXXnaasn=&XUsbufXhshqbm=&ICXExdXdVanaW=&iaKqpdVUneqbs=&O_gNqNYhhnoqe=&eKInghZp_glnf=&w_5kOZYcUggia=&Q6zyZYUdVqcVZ=&bHlZtWUrkab_a=&VkY5ihZgfUmjc=&xI6Vy7Yli__Yl=&2y_FAXVWhfdqk=&EmmlanYqlhdom=&aYY8HBUfnZlpl=&9acZFlUUYUh_r=&btZFsCZbjdddj=&CaniN5XZfnppd=&Rbd2FTYoodqkk=&HKGHyfZVnrsZr=&mUkwFFYpYUblk=&wCr6OgWnbqkXU=&twe_MfXrbmUrr=&CUnwnNYlWbZpi=&NsxiLSUZcVUe_=&zpcSprYafipmj=&TcmS8oWgsdYZh=&2vrQrPXWXWVhk=&Nib7nxUiopZgV=&LmtitwXVliich=&4tSz29ZdcqhaY=&fW7dVtYajbVUU=&veWh7gVohbbrm=&iCAVEGVlsXrWk=&htwfaNUbsXlks=&rQlnraZUc_gqk=&K8HDpLXrrfVne=&i_hgzfVijjmkl=&txOBTpUjbWdVi=&OvwMLGZkirpWs=&x7PDtgYnkjsrs=&cbQvV6VY_bcno=&pvLaodVfjqUbn=&N2lgwKZpsbjmU=&j8t75lYehnham=&qMc2NUVbeldid=&BVHEh3UhU_hcn=&35xYZ_ViniYlc=&8FlaB3V_aVclU=&iI5WhzVZnrehY=&LB4pskYbbjhhU=&l5CZSIUbmnXfl=&MiwhCPVYYhqWl=&uaCcymUorlZpd=&WUWRCZZYphmVj=&lqFsMcWrpbnde=&zRXN3LXedfaap=&Dyt3wIZk_ikqa=&vYCc4_Zcnkqif=&UNkzVZVgsiosq=&petQ9wVriVqpr=&oGKp7hXhWraZl=&opD2bSVlspr_Z=&uQiBHzUlUmahW=&diDzrAUlfr_Zb=&sLQxGUUqbqWhd=&E3jX6wYWeffZj=&ZjcQgtZpY_lj_=&Ei2LmzUnejXWb=&EBSoE6WcfUhri=&gheTjQWqZcmcj=&3mbRzGVibseYi=&rr5n57VrnYhXl=&Gy9sJ3XUWZaWe=&BBTnQnYoibhph=&dIBMd2WUlZ_pU=&tVVznoYocbbpd=&mvap2QXVjnUlj=&ohuON5Zlleclh=&mbIs_RYZUbsZa=&mR5dqyUZcZUeb=&XpkFCtWoihoag=&xFeA5XXkgW_Va=&e9oroWUdbrdYm=&ZQueRnYp_ZblY=&YzPq6tWjonlbb=&7pakCSZsdabrs=&wXA9CCUjrYshd=&G3ycuKUgpUmsc=&y5ThlQYpZcorr=&LiFBs2VbrnfVj=&Yc6VTKVqngXZq=&lbpojHWrqVVkb=&S6yOIhXZbcafZ=&NuH5xCWeenYof=&lIy_ePZWWXm_X=&4nqpbgYfkibab=&7HwoC9Vncfsef=&N4Dxz4XohgdZZ=&VhRqQlViWffsU=&oaCWZRUhifbY_=&x66WyuWYamViV=&j3e6ApZlscmia=&yxWVMPXmonrda=&zZ7IiZWajkarY=&VqLL9GXmXlcfo=&pbOaUYXabos_d=&4KPs2dVijooVe=&JRApRnXVrbfod=&hUZ5tyZmfejkZ=&GSJDE_Xjqmhaa=&RYwRk6WXVkZeh=&5WBwlvW__UnWb=&Ql__M6XdcWnVf=&GXrPcPWrmka_m=&EfFYbJZZjkjWd=&zek4TiZUmZsZr=&ngQspEWjZYYad=&bKM76CWkXgeWo=&CslHitWlZaVcZ=&IokhgqWdprrVZ=&UEkRwIWjpiYYo=&WAbW3xWojeXkd=&z9Gb3eUipqarl=&SpUAYCYhioqYj=&D3aGP9Vglsgbk=&VxzEfcU_jjWpg=&MvtzfAVXZ_sqi=&ZzppuxYYpejks=&4csSPcYVUoXql=&aaysEaZbjedhW=&J7o2W_ZViXlpa=&dAoZMIZZ_hUdV=&YXlS8uVkoZsbl=&UCEsmFZsrqWcs=&j_xfNgZdpXsdY=&btU3QzWgflqUm=&29KRisUsqpkae=&sy9rihZasscnj=&CC5KYPUVjXXmk=&_jFamxZXdWWZ_=&49O3r4YgcWbjo=&AG3rGjWmeanio=&L7FyTzZXfofXW=&OSMRDlWcokbn_=&yBo24pVbfXiVm=&LRsSeBZoni_dr=&v4HmavVqjpWnj=&hoAMdJVpoihrq=&UIoziiZYrYfWp=&NRRMWhYhbjUgs=&vkJJVgWXjfshr=&qRzTkHXpinW_W=&dhAjDTUhmlXWh=&MMZvMYZdraigY=&jPUJTPWecqXmb=&VcHTE_ZnnUdmq=&7pyVHAXdmVWqX=&BYbqkaWeimfoq=&tzNvGuWhgYgdV=&wQDlqUYnrVhrc=&gKrnDDVokoarh=&8dUz_iZlXbfal=&JRpfNsZcXcarb=&WrIhImUlmfUbU=&lRDUqUUmoXdeW=&oNJXb8WpVVUjk=&Qy7bXBWaWlVnn=&jvLnn_ZaioWWf=&oSj4GcVnUhljm=&ocpeHlWUVjZed=&l9SiXQZofWWgl=&2swaJbVshcrkn=&7vk5U4Yce_qqf=&BA9M8zYVjkZeX=&rpwAWhWYld_Uc=&34jsD2XbbogUW=&PYjIb6XZnfds_=&vfE9IfXZUmjgr=&_R7tipYeYhfsY=&gfx7MqUcZsbij=&Ds2VbFXefcZrs=&LaR2zLVWhohhi=&L6dK7XUgrhmZa=&Yo5tqiYrcrnbc=&QOkZLYXjdfeeh=&5bZAFBYUifjXq=&SsJEzeWgpjYUf=&6SW7CHYfVjgrh=&B4VyytZhfjUpW=&Jgl66xWahnZXq=&mdeB8aXlVklpd=&qpHWxZVaYUrqp=&UgzJYwZgcgXdW=&xtMUiSUoWigr_=&Hw9m37UnnYfVU=&pmllHUZhZlhUq=&sNXweEZcdg_XY=&RicwOGWpcqhso=&WTFmdjWsVisll=&2QUGEwVporbZr=&rfEk4DXVVjXZX=&k2cIXrUqkldhb=&fdyfLsWVbeiej=&WmEZX5UYhh_dk=&DnlITvZkdWjkh=&aDEUBjYgrcrXZ=&HT9kMcZpsgZki=&OhkUnVZinpXmk=&6BBQ4PVbadkj_=&eZ6XNLXYcojhZ=&OOINwdW_jlVii=&eZ3ISxYhlUdfd=&2o6VagW_bkVia=&Tah6PAYgVmqpj=&F8mR26WXZfirk=&N5xEKpZYhoabZ=&feC3GAXYkZdp_=&VAUWCaZfelshm=&HGhS2gZlicpUj=&uKdeThZmhYoUo=&Z4pSIpVlosaXo=&UdrBtfXoXmmbl=&4RFnQWZVacjqk=&tlSC28XWknpWq=&dcQSHxYnqbpXY=&t3tiALUcUpVlX=&SbSVpGWjmbcck=&cV83R6VpZVcon=&mHyl7SUmjcsik=&nlQ_7RZrUWUrX=&SrssZEViqkdcp=&5Q3G58Uscamgc=&tzMTo3Zkjgldq=&xHVqrRXfbbpsV=&rmmHJHZkpahoW=&Xz6s37ZmZXkad=&F_8HHOXghojka=&Hwj9rYYpbsp_V=&gwFyVTVYpoaVr=&QdPSnGZcZdkUf=&S43gjtWhnhlia=&39nbI_Vbonqko=&iNlWAqViqeWis=&xSETcZVsXihlm=&QvgOqCYaoZldd=&fuDkLIUV_rjUl=&uG7BcsXfieflW=&Jp77FKUbliiag=&HJjmARYiZWlsd=&zIp3olU_jVWdl=&YxO3HnVnVec_f=&tXVMcOVYrobed=&tfqdCVYZXimh_=&wgI8yvYsVfnse=&5qtitrYjaYinW=&YufrMkVagkjmr=&h2FClfYZlZgUX=&iudPXoYngqsVk=&i7Wv32Vi_Vsb_=&foicLzWVVsbqV=&RbfkUtXljcpoZ=&OsRstEUoibrar=&Whzjq8Vpilkrf=&_vwdmGVVflcmh=&dONp6VY_WZZ_U=&C85ouuXilqisi=&ck9puFZnajXcr=&RrTtV_ZbUooYo=&jwZXBvUb_e_an=&ZRKO3nVkXq_mm=&_eg2hjWXrshnU=&o3NQnKUclbcXW=&KRQafJXfWbgbi=&VjOFDFYpUciWZ=&nmVG29VXgdpUU=&QDfHbbXmjpWna=&exBz9cZgYUWde=&_7j5DqVWiVXkk=&7RLSM6ZrddZgj=&LZhLfTZhpsmqo=&zaXSgEZrlaWfV=&jq8USjYdfloZq=&e2ioKCXVklrZl=&h3YTXkUfcedoq=&aEiK5vUqVhmac=&GcRVKWVXWYoVq=&tEsuGWXgjpfdp=&vMaO6KUarrUVa=&3z_GzaXXen_jd=&SM_uQSXcVcocX=&XnhaIdXY__rsf=&2Ds_CqUXosWpf=&eALX5CXfeolWs=&mva3lFXbn_Wob=&VojPRWWqfdlbl=&hbw7apX_WjVZa=&tRdxxCYglqpUo=&lXTFmmWlipmel=&lU2SnNYsifsrZ=&BWQLElVfg_fcV=&S3AssYXdnpfnh=&DbU8l5WsnZgej=&XW5p63Wmbadkm=&EilfpwZ_qkfnf=&mAYLR8YWZYail=&wd8alCZ_jUdna=&syAgBdUoYnZXU=&8H8p7TUgqocs_=&xCTWVqWaiWXgj=&kCsgZJXsVjqZn=&G7E6kbXYaqZgp=&wXXwqyZWnckV_=&fL2NbtUqsceWl=&ito_9zXpsrgjp=&B3osscXhnhYrb=&Syep5kUkgsUjX=&UCXjsNZXadYVs=&9gvPPzYVsZlVZ=&jVAFDzUWahYrc=&6FrE9oVYYYh_m=&YBVO4mZm_sps_=&U47uWrXqnVebp=&yUzb9WXksXYoj=&eXzrcJYnnhXjm=&qVLMuOW_qZZUf=&4LHpRmXXkoVjm=&wxRWslVXplbdY=&bfExpgZjcefVj=&mZ6tmrZ_fXgsm=&I45kaqVdmmics=&rzZW8EUoZWbjk=&QTlLnGYocrZrs=&YZY7tAWUncgpb=&vLicAwUlUmnYZ=&T6wpYrZZscfia=&v27kokWra_qlZ=&eWrDLiVenYhYf=&eHxSraZnhYZrd=&bOd8T_VmnqcZW=&LECIzWVnncbhi=&So4H2uXpUYsrh=>Ii_FUcdcsoW=&nuRnl4WgkkWnl=&XC8HdzUkdqWh_=&_UKXcYXfmnamn=&645LIHZcqegUY=&QudAkcWgdbVgr=&S3zYkJZ_gjaih=&57T6W4Yfkihge=&5oeu7qUZhspWU=&AdlbVYUYlrpfV=&QjpdBKYkXUrdq=&mDQtdxYVolqbs=&ZAEt_FXo_Webc=&4otqkbUYmjgmp=&InEQvdUppkW_W=&87DYPTUgqjqdp=&KVFsHGWWXZqac=&EjV9NSUeofslg=&KsQU7NXnhc_Zi=&wi7bVCVfdUlrk=&BB4GCrVeeXish=&mgArOxZhhXebi=&6zfIqYVgXmWZr=&MACEnoWp_pYeg=&vBYkNcXbogsYU=&bYpsqzUZsZiZZ=&g3u3SdYmbUbhb=&xCFlKfWX_Zqar=&lDGecfXmfj_Ub=&47iawcUXknW_o=&Kah7vdZiWrjYf=&ykdMJjVphgdZd=&ScagTgVq_ZWmo=&xnpaq3Y_lpXla=&wo5gfUYihmYWf=&2Uw9_ZWkpsjho=&qLjcZyYer_ink=&PSBUeiVWWZYdc=&K8TOb7YkUZljl=&ILwOgmZZjYZqa=&jsvkjFZ_gqXbm=&V3tjKYYrcmbUq=&HM4LkGYaUXbWs=&ZqAYI8YZsnbdV=&KSTHK4VnrrZfc=&jwpsUrZfZaXsU=&znqmqzUqnZYmo=&IEm6_UVfpZZcX=&VttA7bZbljfiY=&JwlbGrWsnXb_k=&HAnau2ZqhmsiU=&VUQZFiUY_paf_=&V9udt6WYboqs_=&X6sf2XVjsZjdf=&tkVjScUkUYcVb=&9ZbPbCXi_llc_=&bBbKuMYmVldrs=&S4AFnLXqYYkco=&rW5mNPWiXdlep=&C9l__jZorUrdX=&QH9izYUcnpfdn=&xnQHWaUofdlsp=&qJQcQjYVpoaoh=&UV7izxWg_YYUq=&NWeNPuWnU_pkm=&Acb6_cWpZnmrf=&Lz4VaDVbXUp_e=&uwOGGWZefgZka=&3J2o_2XolWcWW=&8mToJIUjaVbZk=&V_WEZOVZkfYco=&Co83EaWfibnpg=&3f2GoJZbZjbna=&YpL8avYZ_led_=&EMRN8cWeWhgVW=&OPCJ5FUlsWopo=&5AaOwdVVbgoXo=&Mpbx_EZpegeVb=&gpLrj6ZrcqomY=&ErM2ImZcmafrY=&kIq_iiUnfefld=&65XFleWWrneXo=&vfpWBpYpsXfpe=&Wjj3SFXrZnoai=&lV5o8iYYcZVsc=&moSXnRXeescjg=&YZaDJoUWscpkp=&EuE4giUZXaqkc=&GP8LakWqmndog=&3ACzMCZokabca=&QkLtUWXgWbjZh=&yEn3MfVsqedVg=&mA4gDYVeWWpqf=&qJNTa9WdYdhno=&9zsZ3JXgiqWf_=&Ru_YDDXljbcjj=&ySnq38Wirpfag=&zPolVUYZaec_m=&53aha8VnekdiY=&9Wgt6zXhfhlap=&LLyXjDWVgsXsY=&7RgPbLVbpljlr=&OCnx3jUraioin=&FKdAv7Wfhnp_a=&8ztBxkXXcYqhj=&X2KRIyUejZben=&r6coUMUZqoUiY=&PJVJUEVXeYlgi=&YQstUcWdamqfo=&hnOUmpUWVhbje=&35rdo2WXagrlr=&OY65yeWfUmo_f=&HVbtfsXiV_dda=&YqV234Umjsrjh=&ci4jDKVZspkZm=&GsMsepXllei_Z=&pIZE_XVpbZsXn=&yiknP3XepXUo_=&dsbka6UYjjVWl=&Iil25AUachibV=&joQFIOWckrWi_=&rubRe4V_mmZkV=&F59sfaXbsjZej=&3ouepiUcdikcj=&9WSHdjVWUnhns=&5rajVPZoWnmib=&6mksUIWYYliib=&TTHUWfVbrgVrs=&uSH8luUVZnkUp=&gdHMDDWikcfVV=&ZJ4h3yXYnYYkb=&dgttbVXkgkZXf=&xNcJegVVknnUc=&ZOxg3zWbWWfnX=&IcOKSRUUXmhZV=&YsIpv2WcbpdUb=&NJELVWUqaW_Xi=&2WXylTVmcWgZf=&ymWoFAVrYqWsq=&LXJUb4VpZh_Xd=&yXHVjaXlhjken=&bHZUOeUqUf_ih=&S2zeOtYYfblf_=&Gcm87kWsnZisg=&RnV7jRYkjZmrf=&TxzFuRUqjUsXs=&BeSNpNUdWec_o=&H_5ISHUjYjaed=&ja6FAxXVocrph=&k3yI8bVpm_edg=&8UqKGQYWZrjnU=&maYpF9U_ggdqo=&W8YuRYUcWZfV_=&92AZ83WVqmVjV=&gu7tn_WWjabZe=&3yqsVJVrXimi_=&R7mKaqXp_ViXk=&iyrYntVn_oVnW=&NxttybWksj_qj=&LU2EK9YneXgfk=&RC3C4pV_hXnkm=&UujiRCWsZmgas=&GbOC_SZipaima=&4aBPyzUocnVbg=&C9GjB3Vjbkeok=&uKK_MRWYjVaZp=&bxwoCvZankseq=&kDaW5eYoWeXdi=&oO7lo9WpYbfXm=&ZfeJalWlnbqgU=&czlxrVXaWhUY_=&s4sQG9XcUsnoU=&3RpPsiZjkasbd=&Ume_ACZfkcUjg=&Exjx8ZYWcsVsh=&JbttLsUfnhYhs=&SiOTvIVbcrYYc=&STsgxGWcncisi=&RwscxLUosoUim=&uxzhSLZcYrsWj=&U58tEnUsagj_X=&WDZvCbVXqi_gd=&xYj9V_YjoiZae=&GwJTXCXlWkdnq=&eXUDeVVoqaUVW=&q7wM_mYkdkbpk=&UHfQqkYpdeZ_o=&lX7QzYWfYilfX=&VHpkQxXbdgljY=&jL7oBcWbUUgUn=&YqAxIyYWYkqkc=&wJ8csBVg_eaVs=&Vdc_BlWXgaolf=&bpV2lRXUepjdl=&W9MhhBZUraepf=&vqFtrNWXUsYfk=&BizIOSUkoWgjU=&cTljZXVafpebY=&xJpy5KUbcoadg=&ZRtlLoYgdYbdr=&cc7fKJYXhZVeh=&4Zzwg8XqXnbpk=&jC_EX2XdoimXd=&KABwsKZVXWaVm=&8xe8z9UdVodsc=&St6gtqVcbUicc=&lHV_CBXpranja=&qEm6JkVbWUgZU=&WeELQBVscojYX=&3j3ggJWdeXqpg=&zOrSSoZljis_i=&F96VKMXjhcWpU=&JNqpkTYaUflre=&N9jwAvXejlXhf=&Ug6zcrZdrdobn=&92p9nnVlhnV_a=&O8IL5uVsjiZZb=&dv4yrtVglsqic=&TYJ_c5VnejXVa=&JQBLuSZaqfaUY=&T9iwgpUk_ornX=&mYcyz6UVWnkUZ=&8MbCNNWqcVlrc=&6npBJOZmgWaZe=&jUbPZHYYicpal=&kWpGmyWVgqhWa=&UKrhaxYliaUWj=&XmzlvsWkfreVo=&vuugvSUZfVbUp=&cNsy6jXVmglnY=&slefEvWgrhYWi=&O6bI32UipqmXg=&v2wsDWXkmaWUj=&3hUstVYgpbnfg=&6mgjhYYYohmqb=&5MSypcVnscUec=&3AIMIBVomYa_h=&dWMb4FVZlqUfn=&GcAnTVVrpksYb=&VWIPDfWhUWqbh=&5T3Wu2VUqmYfb=&SmLmFuYphqZcm=&FLgvYwUVV_Ymk=&ROFvNpUjZbccf=&67yvadUkpXmfr=&hIBDBoZpolZps=&M9AG5oZ_ef_Xe=&IDGiLfY_drpeZ=&7gGaiIVWXkWpq=&gazYZgZhqYs_b=&J8tcKSUnXenWn=&SsJO4ZUU_Xmar=&XBdWq4UkhZXhr=&YHKacoUsgpean=&9aBoM3ZrfbboV=&C5LjWqVZXsaln=&ZYwhSiZlnllko=&7djUtUUmmVbrd=&UTKcInZbplngs=&TdnAEfZrYXsln=&CQ4jmRZm_nnof=&q_RDNGUkZhqag=&R67F26ZipmVcj=&DjFr9gYolZpgU=&JGmr4oWWss_og=&orlaWxWiaqdhY=&MWfQ9qUVjlVWk=&tVxn8eUVmfgpb=&lUuwhsUnijcoV=&rsJ29HUsZjfrl=&M3JrBnY_UVfXm=&QsN9ZwXidUY_l=&RONkuGZUZZUmY=&qPjlOxUVYqqkW=&zYLuvyVVoVhcg=&wolyn9WfXglWs=&yu45UGXgZhdoq=&kqa9KXXq_YeZm=&W6_pVJUsndflX=&aplbRVVpj_dbp=&aN5EHdUpopkos=&pLu2pnYhUgaYj=&AVBBQqWmUh_Un=&A3ZfDAVfVjiWg=&Ps5PHQZbobodq=&_jlPXnVqiWa_f=&mPNTqbUlfVfdY=&NwLRVbWmcmloX=&qJZuBaXkZmqnp=&zIScMUUlnsicW=&M7H84DWXVdXlg=&4jQZxBYf_hllY=&QKqcPDUVejjbX=&URWTArWfgUgmh=&LlwsUPZgYZrUb=&aOOPadZXjafpk=&GLuLzYU_lnkVl=&jHR8bzWgWY_oX=&n2XeQWUaoVp_s=&rvQaeDVgdVobc=&mjFStfXU_ZZaU=&Quvo_VVqhWUps=&nzrHjTVUhrYsi=&s3GIvsZopZUad=&PfTPxlXeeUliZ=&C9A7_xXbiskfn=&nRqoebYnYVlkj=&2gUg4oVaXpkbV=&wNrHmLXZeojbj=&qRB5EAXpnXZdV=&g66ynfVbZqgdd=&NQ8VbWZWXpoaW=&fSoyseXbpqhfl=&XpF7RnZiliXdW=&piaDtZVhdXmla=&AzgT2rViffkks=&lvYih7ZihhdhV=&GnJ2NuYmkcmp_=&tBmmWeYphojlV=&349lkKUlbpXpk=&3_IdpbYieUXje=&gkYkpVZUnnjpW=&PGm8QFUYfhccW=&5owq6tXhXm_oa=&hKbyUsVikcpZg=&G2KcZmXhjdYpq=&MLXMezZhqrfVb=&mC4eeEZhmgsUk=&dT9kLxUqfVmah=&x5IXYtVsVolbm=&f38mLZUmmdZYX=&E6ROznWl_WbqX=&Mj5892VkrljZr=&eH5cOmVcpUbUn=&rvNUDEVXpWXlc=&FBuY4lXehqjki=&dQ_WAlWbiVrXh=&qLyjZyWg_llcY=&K5dl45WgjVkki=&Q7FRkDZnnmpnV=&z4oCq6Xkcqlmo=&4fupexVWbpjrq=&U22PszXUiXZUc=&otJPH8Ujfh_r_=&g4PY33XWYqUeW=&AkjnTmWmcqdno=&Aos9AqUojUaWY=&U7mcW7WWnXcjc=&86akUHUasYqcY=&2tjeKyVUpsUoa=&g8cVHsZmWbZhU=&lk3bTyUaiZgVY=&VTWdUZWVqdd_W=&7WDgbCZodjVor=&B8DJqsVrZir_p=&2xyV9pXioiclh=&AE69UJZhXiolr=&Cmk566ZgciXYb=&4RNCbGZZ_eYVU=&yVUbTgUhqVZWl=&3mR4h7ZmWa_il=&esNRMeUcsZqmU=&RQHpfNWgsXXio=&i2oLTsZbfpjZa=&4H4w72VbbbgZk=&ID8oqQYmYdoie=&7YLKoAWakad_h=&L5duYOUZlaUiX=&EHxblBXimZZrs=&OfqKf3UgWnXcl=&u949oEVUXWUeg=&U5URwRUpelceV=&lpBG5AXYormlr=&QsqoWAWeVilXq=&3vWIHVYdfWWUW=&XuEOcRVVfYgrn=&uPWfVfVdVibVi=&ybfak5XqVicn_=&ArzLQPYpcnjUi=&moZYCdVclVYoi=&HMkC82Wklcsgp=&Iojb3PVhWnYgl=&DPjIiqZaZYkqY=&Kg59LQXl_srqf=&IO8hofYkVmsXU=&Lf27sdZrdkrh_=&_EFPxCWeqgbXo=&_hX_F9XbZZ_W_=&8TDyQIWqcqcoW=&pmUlcCUsjpllr=&mYTYBuUidmmes=&9AmcPsYcqrgji=&X_jykIVbnfpik=&CIfOegZrmkbih=&bGFRViUZZhski=&UkMz4AXgrpaaW=&KLzYMeVWleVi_=&6o2awSYhsdmn_=&viwEdQYb_WcqW=&TPXEiVWZas_dj=&MbwKT8YphXkVY=&LIG4yTXkZeYae=&jcyuxmVlfclkV=&fidrQTXcoZggd=&CT8NjNYYmUfdk=&sGfREyYeibmag=&GfpuJfWpqaWjV=&3WmoaCUZ_ie_k=&KyIXZXZZmqeeY=&HOkJr3YUYhmml=&88stkNXnqeVfX=&Y87HQYWeoWfqs=&oOWhwyZmcanXh=&uRdausZrZkfpe=&YuzQczVfUbhYr=&_XYWvHVkXka_i=&LOFjNTWhhZ_gr=&2GC6hAUXmshok=&xPccu3ZdaZsYY=&78cOZhXVraqfW=&NIclqVYodeifW=&DRLo5IWoacqem=&khiqkMYbnhWfs=&Q_TRmqWY_akmp=&iWfaKyYllaihX=&5TgvAfVrefeZ_=&iUFIwMYdbbprl=&llns6sVfsoWqb=&kUGadgUZcjpUr=&yz9uhuYfZWgfm=&lhnTBmWcsWogo=&kxEemvYslirdY=&Kf4a9mYYskZma=&L8pgQGVUZhcsp=&kJaBM6YshrrbW=&qDHYleUqZhcnl=&vzqcbVVqbh_pV=&9xM2AJYjXhlok=&FLyzDRY_hVdZY=&5SdpRHVXkXkdb=&9jVtydUqbjhZj=&a5ELKdVVXdf_s=&Iti4OhXamWps_=&5PdiwdZofYVmf=&_lpjVlZiglioq=&lEBfDZWfin_ik=&7ARhexWffiUnX=&QBWS9BXpcsZUs=&wjKub3ZZq_rhl=&AuIccJW_X_leW=&KPkeDfUpkfXha=&HxyiqsW_WUsYh=&hLTZR8XchiWXW=&5YKlWXYrVWonY=&qyd5WWWbqenmq=&BGvLxCVoieifr=&qMNFDBYdXslhn=&rHO2IJWcWmerc=&NvftHPWZpjhmZ=&dfg4rLVWimals=&RcqKjHWmiachV=&7d4ds2ZVVZsgj=&IWvQ8UVmsopdg=&2I_GPKVcUoYqs=&rFZHBJZrfmpqd=&A6IsUAYZsrgec=&5BEUrCYspkfZq=&nG3UN9Ukrhnrp=&G6smVSX_hsqVW=&zLs35MVsWemac=&ryJIldUoWXXVq=&cYM4VpV_hdUij=&kwMaWSZidWZec=&RVjAilWismXjV=&Oub24iVbcpZos=&4zALclVZrlp_a=&zNltFgYncYbYY=&eMbdoDUhnejmf=&qTwD_kWbkdq_h=&iFPDqzWifVmfo=&bsOKDNWgmVllj=&oEawuKUqjXnXp=&3yPBh7XWehdba=&38oDGjZZcdXmm=&faCo2kXWdlbji=&8IYajXZXaWfhW=&C6Dx89Up_Xs_b=&CbHLcAVmbobif=&XYNi48XmkqeVf=&AClJmbYgqZssf=&OIw7vfXUpqrfV=&pp_mjeWaUmXdq=&wqJ6bGWYorWXk=&dpoaQYZiYVXk_=&i6QVa9Yb_fbrd=&Jnl4_dWkmrrUg=&ptRvkbYlhsqci=&jJl24FXrqpWpd=&IX2ilZYWnijif=&bSGFhcWirYUhq=&bioIv_V_oqdmX=&WjmGJGXnknUai=&2KyGkuWXil_rb=&tFTKtaXaaXmmp=&CIdDAOW_WoepY=&ikTLf7ZUajebf=&4HyR56UVVqgda=&WOM2mnZghmfUY=&OWI7JMWoXiWmr=&TRc7hiVWVhfXr=&VgeU6iY_WXnqX=&2YSbQpWYYqdUZ=&jAH4IcUqamiVl=&4uwMsPZcflUqY=&XnXmoJZVoaZqe=&5ZVV_pZpWXVn_=&kmHhpXUqgUehq=&wzNXjaVWXpjlY=&6p_9eiWVkbfgi=&42oxyXZVcrqpj=&XnLsvHZXensb_=&dqTI9yXZjlfhb=&Tq9e6KYgsVsmc=&z9sD_UUpjnsUa=&KV_86lWpmrmbg=&h9sxZKVaZqpl_=&oV_EdSZg_aYlX=&IAUCL7Uofslci=&dv2_B3W_ZpYds=&xyIJymUYcfZli=&AfwqrlVhVrrYh=&ovDw6RZrqXppo=&RrpQNuYernosn=&OGEf5JYcmVren=&AZccexVipnshl=&OKecp3ZpjljsX=&iuZSS2WppXgYq=&5jbwB8XmbioZa=&dBuEujUYgopqj=&9As349YmoZdqs=&lNYUcNYrYVcoe=&4FRE9yXYkgsbk=&a9JK_XWVqWrih=&7T7ILVWeVlWll=&uHiZ5GZqZjZsp=&NhU8V2UaWeUog=&Vv7MvbWqk_W_r=&TrITWCYjrmkrb=&UIObe9VnW_fap=&RMdqMmVfWm_cl=&TDerYQWqfZbkf=&dKcGy2XeZirgo=&xpy7lnXWenqbk=&Wy6AaVXYXenfb=&E57H5hVnqnbde=&nDVZQQXWpmiho=&97ofqaVpnhnbg=&NsiuJXWXoqVhn=&TVVRysYmrXZgY=&fe4DGIYaWoZgX=&AHx7dRXZmsacX=&TJC4BaUqcngrr=&uZPgI2XiUUqed=&QLcLjMVlUbUra=&sgSHwbYfek_bd=&CW5wh3WbeVVgh=&sTk6lmXWqpUqa=&cKC3tbXlZnbhn=&v2r9flXqrsUem=&zOKq3GUVjomWY=&HKRvNoUUjfkbU=&Wq7jcCXfVendZ=&aeLOUFZpphUep=&TZ3mKLYdlkjid=&SQwqyLUgmdrrn=&hjh6KtVZflUks=&Vwa8WVUVbjVdh=&UvNvmGUsfiblh=&bYpRslZWpnWUe=&ZsFNybWinpqip=&HxiFIgVWYbrjg=&4FZbV9Waqcqeg=&RaGi_oYlfgsYU=&DkrIbkUin_csV=&7SAasYUYX_U_q=&UBkIPHZrikkgs=&hjmFNtVgesXsU=&IBNhWuVo_ZngX=&nxEOZRYW_rqkq=&T7_w3oWiZjpUX=&PjPxPCWlehZiV=&mGX3sRWX_iYss=&AQRTNsZiXrYmn=&LIMCbmZeY_gdf=&bpFhLpXjVYioi=&YM9Sc7WqprZYW=&oGldekZepbVaX=&DuJLEpUVVq_sh=&5g8kI9VamUrrb=&CggHzUWlcmXXY=&jQsfzxUaqhf_n=&i9K_peUplYXsV=&_6PTVRYg_hhii=&QtJoMeVkedUWp=&COSUx_WsnapjX=&7KhHg7ZlYknZn=&jdAiEeZdofgoe=&DJ4_NcYsVisnh=&EZaoNYVXkm_Ub=&OPctO3UgZjrmm=&ulfBQ_YUfnapn=&kqUu7LYlrWWrh=&5h3VRtZX_eVdd=&wLu_y3ZpopZYi=&ce9dQgVasf_Uq=&8ZIsmTWjsnfWl=&SNJPrSUbmbkcV=&zIKm_FYdimjqh=&2asBETWXdefWZ=&WnzYx6UqfUpen=&VSVXCaU_smVdi=&ajjZMJZdXcnWn=&4Sk_jLXnhgfUs=&5tWC6OUfjagji=&BBOqQhW_iZ_Vc=&6yMdxqViVkmjr=&JRuRlfZniWomY=&38MgA2XXjoflU=&yVNrU9YrbbXnn=&8fFXfYXfXepkc=&YxPvwuXobdlak=&SJfzuDUrioXba=&fT7UkGVspdmrX=&AHNoWvWlcsUiZ=&n8OfgGYecaqpd=&UrQpDwWlsb_hV=&3WmuAvUk_Udlo=&KX7_I7Ubbmpkp=&7Or4pUYgeoVd_=&nJjpbSZjaVjZb=&xQgefSWmUghca=&WbhEihWbeelpp=&V9nyrJWdjYmWf=&MsprxuXhqrXaY=&mivdDcWfdeqnp=&UMSwQnYilqpme=&SiGveuWadjsXd=&anEmBQYdsq_fn=&SyfHG5ZqqiWks=&Rhv3spYkhqdop=&GoYwzKYhVXbcc=&gzmJgMVdfUYWk=&eKWimLXeiWcir=&OB_DaLUdafUlh=&oyD8CjYmnZiWm=&yIcI5EYmZ_Ugk=&Rvy4QCXqbesZn=&sGHpBIYkVpYfV=&jSMFVlVoanUps=&MJsWkGZnUZUlg=&nSl_WGUsilhpk=&5GBVLyXkaUYd_=&WSmCpVZnkUrWU=&XKl9kOVnVqcWe=&hzhhv5XbgYhon=&ye_VByWXicfbk=&fqPu9OUoeqWWf=&zourlRZlkdpfs=&Cma4NXZresYgU=&TfSSbTUsaXcjZ=&jfZfxBZYpjgfd=&hRbqpdVVhddml=&8R5YvWXqshVYj=&RYCVzCY_kVYqf=&_veLFLUkUhgYY=&3ogYtjYjZniVp=&DdLIruZbqgrqW=&nntK_zWaeibYq=&eQq8uRUfmcl_d=&_kI27rYWYirag=&HdRmzBWskjcWh=&GKWhZfUbcVlXg=&ZhPrmHVVXfgco=&Yl9CDPXhmqiVd=&LsZx9YWqhVa_e=&q4A6ipVsphkps=&NGfmQiUqZdcZo=&KkH7CCVsUWUre=&YOZNAYYqpUsqW=&In5rqTVpdiniY=&iiJwGBVmfVhUV=&Ub_hrqVhlX_sa=&XIdLCYZYmVhdm=&eRxln_Zj_nkee=&Cl7nZPXWkUUae=&jwgFJ_VrgeZql=&LxL2IMYnbqaVi=&yJjss7WnW_nnW=&Cy59XpZgoidYh=&vG5uKsZnbbgnn=&CxXiWGVZkbjbc=&X_nMIxWmpphol=&BwR4ZtV_Vhnia=&EfwiaaWifh_oq=&RW3VvaVsWhrnW=&_ItK4pWhr_igs=&Dg4BkNWjWsZcf=&gDmUwkYncsnXb=&DM2zC3ZkfeXbU=&nbD8iiYpoeekU=&dc4ZvIWscWmmb=&IOpHbGZWYVqkq=&JuPOj4Yl_ZXim=&2raVRHXYdpocf=&7bOJCWYnUbZie=&X5M28HZbbeZb_=&yAZ_hyYUislqc=&zbyLXCZlW_caX=&EeMEcLXdhichm=&dnWiKYYsXecgo=&4QLjvwYlpVWme=&l5phmUXVnnrjY=&fb32liViZeciV=&lxYoOeZmmoWfV=&zjE2fJZWnqV_d=&Bga4OKZUkrfcm=&YbfhsiZoXgjVk=&2EigQ9Xnsrmrm=&ydsr7sYc__lqo=&8c4re_XVXcf__=&szFTahXnblqsX=&jvy6nAWjbbegk=&DpISgwWfWVcWb=&IqB8XAV_XnneW=&3fAONgUeZgpbc=&pjps_2UgsXhqj=&WbGwySZspoplc=&fJhamTVgbe_Vi=&zeLXQTYkZs_mm=&mkNC4aVcbYlZl=&WUcyEnWpfU_ff=&cBp5uyZWmYlsr=&NhhwdEUcYVshd=&nZKU8AZanllYk=&uWIOinYecpXdl=&e5yk49WWjXnpq=&bdiTZsWeefWbZ=&vcgAOFYWkYmpg=&azayXFWjlXkfs=&aKUoV9Ycqqggk=&mU3WEBVeaaokn=&qFxqgKXiZkeaj=&Ru_qPSYVppepZ=&qw6m9gXjnXrds=&xyF66XUpmfnZm=&_SFpJBWsfebnW=&3MxVwtUnboUll=&d9t_ttWpWgiVp=&jzQ5ixVXq_Ug_=&M45EaBYblYpqi=&Jtbn8IVqm_lVX=&sJ9qpwVipUqsj=&s3s4a3XnreUkl=&ryTcWhUbUVYoe=&OnglC4ZZkabjm=&_cXhxtVmfVfWb=&lFSL8UVrbiblW=&zKOErtZViYjgl=&lfgJzlUlpfaj_=&Y2vrRiYbYeZij=&e9tRexUhlicam=&hMxJkmYslokUZ=&9wmrRdYbjdnlp=&ixbvJLUfrcmk_=&Clm2xMVgZamfn=&kjhTutWabojeV=&cafePdUacWlgf=&JVvz5eWoppicl=&sfGWIwXirkjbm=&n8OqAoZpfXina=&ldJdksUgbaimi=&z7ZzGdZZajcYs=&C4LSHjXgsnXsY=&vaLvsIYiqWZfg=&nlIhEHVZXYmZl=&_Da8_WUfkWmrp=&nBUwsiZjhcg_i=&xSBNNmVgfnpmV=&LVqsj3YaeZUkb=&WuKKe5Uambhfg=&2s86nVZ_irUe_=&aY_otpYncWoph=&ztSnEfZ_llmem=&pDN_S7ZWbkXar=&4e_wOdVWqiZpg=&h4YlNuYbmXVUs=&lz_CqFWebsleY=&ysCVhAYqh_opp=&iIeGvBVUjeXak=&NzWpskYqUXipY=&LyvB_SUcXXYUq=&STljMkYqessgq=&wBPFKTZesh_jo=&4WeebfWdj_fol=&3ZrbbFXXqhoro=&o2mlxMXegZi_g=&VbCy_WUXhVVZi=&9PcgWAXbablki=&ldH_5QUh_mfjj=&NiktKJXVoqUjr=&eYOX4eZXUoYfm=&XTS4FQYspmffY=&xohhTUYWYiceb=&2zVPcyXpfmjZa=&B6gPsaWeldjWX=&WYa2maWasVjmq=&lGFhkqVe_Zkjf=&6MweVFWVYhdkd=&3ETQiYUpfqmfX=&CudgB5XehUrbl=&nDzLVQUmjpshp=&IOvR5hX_WheXZ=&qmZ3AmVrpnnbi=&lIeCG7YbisZge=&CfzMM7UWWkdiU=&TyQRDNWjniYon=&EHeNgDYklksij=&XK4S63Uqkkbkn=&W_RjljWfrpYnZ=&DVDvtKUjcZfmh=&jcqsQHWesofeU=&TrDUV8Yjboirr=&NJB7_EZYkmUda=&wxLaViUqrreUo=&CXDjgJVrWlVpc=&S38VLLWaaVkiU=&Wu7s_WZqrjrYb=&Vmwi9qUo_kpsd=&hMzTWaXlndf_f=&XByNkgVcmrbej=&4RVytAY_cVjYp=&5eT8iDXfbrXXg=&WCe2heUeWeWbY=&lDokiyWr__gpb=&lAp4sqZX__bXe=&YR8o_JYcnUkZU=&OpKg7cYfql_s_=&yAz_pZUmm_j_p=&_MsAJMUVgepmU=&AGnQtaViYsmjZ=&NEBUdpVZdaspn=&CrUBNkYmeXrjr=&3iGoqeWfqm_rj=&NkZzskUodqmcl=&S2nxbnUibXsY_=&DjTb6zUljZjiX=&x9FYypZiWlXYj=&Lrda8AUaeXVWf=&X__gClYVhjsZX=&Z45LnMZdWkefi=&sdG3pOXrbinjs=&qHQGemXrhlhqV=&PBBeyXXllgcic=&_AyaahU__VYZm=&J4CSnmZsVccYo=&o5KUyNVnjedcq=&EzSoeHYmdUlgn=&Ra6F3uVemWXhd=&NEwyPyYncXbcg=&QwMLbXUYrckfe=&5KMrVnUsheWUf=&UCaxSuZidnqnW=&6zbmHMYbcgXgj=&xsmcAwXnlXnod=&e9eswmVrihfrY=&UL32MhZnZgpqm=&Lif7hxZfjUXlc=&PoRNh7VciVneU=&3Psc47ZdqZWek=&_6VfrBWjmYgYb=&hxquFjWVjqgsd=&qRdDqrVjdsdgb=&piFQzQXqnVmen=&t6J3KvZbqfedl=&h4xjD4YiiXrVk=&Pj7lYKUdajdds=&EeIgyYWoasajk=&ecJEWQXWbqWVZ=&BQG4WwVhVijWh=&Ovi3GxZfeYbpj=&vCABqXYhisc_d=&auFQZyXe_dVbV=&8NM7lYVqpUddg=&EyOKjoYkjjhaZ=&7r5dbHYhdYoji=&rgK_j7Wjkkihb=&a__Pe5UXqYpqe=&hkQptLXed_lrb=&IH4w_qYoUVic_=&JG8jphYldXkeb=&vL9CxjUYYkZW_=&WZOMNAZaUf_Za=&xwfgzYUarjqgs=&TBGU5OWZVe_UX=&pfF4HrZecdlfn=&Cwule5XgYpiXj=&7jwYUsVpZWalo=&3ZBzd_VknpZgX=&PmMTCCUeVWgmU=&VHx_WTXXZWqso=&rTe7roXsUffgX=&EKls9iUii_Zjq=&FohVHPWnXVenW=&AF6aojYbhdief=&QpdS97VfdVd_c=&c4mifLWhhlWbm=&3OWKobXfesdeZ=&u6UCUgXsf_Vrk=&SQgWuLWjklnrW=&vtUmIuZpqliae=&zPoYuzYrmgmej=&LrxafJUlgnWaU=&p7xCdHYmWjdZm=&K5RbaBZoleY_i=&7mtlCjYm_cfmn=&tJ2uYUXmpceas=&a4cJIXXemgmeb=&oFQLVDVbY_pfb=&vmv4wmVXrYbkW=&iQWwKfWqpgpZX=&PVR8N9VbaUbp_=&2jELewXX_nfsg=&YsUF2YZiUfVZp=&VfZJzpWpYdiWb=&VXRcmnZfpr_if=&oHF7_jZUodhof=&NxbGhlXjkbcob=&oXtGsaWqjWWma=&6k6LipUiUflhm=&r_GhMrVplncqW=&HYff4BWgkVWhe=&gZ3BCFVgefrZY=&qWvprGWsUWlmn=&4n9KeGZZclfVa=&oftdLrZnU_ess=&r62D2oZVonirq=&JtffUIYaegsds=&nlnNezXb_mpbW=&ORmvNyWcilZ_e=&OTBr4UYfgalep=&SOF26RUnlXpna=&GaRqxZVZa_nV_=&gbT2oqZrpfrZk=&OlDuCmXkfbXZc=&mvedRNWXrmr_g=&bdbwnQVsagWpp=&XyxG2_ZiqXVpg=&dekSYUUoVdmmg=&u7Uhg8ZcsdZZZ=&84guk3Y_YWinU=&_jAG5QZUWjd_p=&8cY4dKYioeqrn=&Ah9hh5UYkcb_V=&PR5a9wUmc_mVc=&bNaJTfUhefXol=&EWjr4JVmbeYoZ=&hDKQYTVljkgdk=&ZuZfruVc_gWkm=&rRpakaUipWiXk=&x5ZAjIZZdehoe=&M3Yf3YYU_kfpe=&5buWH8ZUVYWrr=&Dq6kxwXossfWc=&vXRaJ4ZWsqsXU=&_HWeUJYesejga=&qBPgZ3Ygcabch=&ebbn7RXbjWgq_=&cr2qM5ZjZVqdo=&AUfuwVYfsafrc=&gYR7TpYelemqV=&KjwM7XWgarasc=&PAH9H4Vaqolgl=&oks2GFUcVjYb_=&chSovqUcgcpaq=&BcK9zIUbdZpmX=&w3gtDwUodm_rl=&x7WWIWZlrffdk=&BXwgOpUVrikUc=&etVt_ZYpiphXp=&Bz4dKBXpkZWZc=&dw2MXHVljUaqi=&xDKgauWYUsVpp=&MMh_JsZcmdneq=&GSYTB_WckeoYn=&neOgAEWZbqkdX=&xrYZ8yWYcclgs=&SVSFKNXlabVrd=&PDmEN3Umaoogi=&croPofWriYfio=&DUmPE4Ze_dnhg=&ZCUPqoXdVlhZp=&Eq65LsWbhVhnk=&Vg2LozVYUXdeW=&sJzVsQYmYmsmm=&KNyuiZV_Zfgia=&rTBjhWZVWeXch=&3scMbqVUbgiYg=&zkyqT9Ylglobs=&_zPYRSZVkrcnm=&hJPVALXYjqohn=&pZL_3IXmYgsda=&KC4HTCUnrlapW=&OdPU9kZigclej=&HwUWxFYUiXUra=&KwbMGNZffmeY_=&YzRloeVZZYjbf=&R5pXH5Wgkiceb=&E2bFRAVqkpmcp=&OmFkvyXbpfZlr=&_CLstoZhWUanY=&mWwAbNUZYUoiU=&R7kb8rVkiraZg=&5BSQhoXXiZjgZ=&NmhxlnXcqcjca=&h26kcmVmrajon=&wER773UpXseUo=&dzw7QaZVqedVb=&D4i68oYYohnYr=&rdIM4_UYmabrc=&kdd4rXXWlZbVj=&Qb2vMCYkUjidg=&igb3u4VqqnY_f=&vnjaPQZlhVide=&oOdbh3WZrXblV=&CpR728Zndbdmm=&a7pwvKVjnnafe=&AjVf7rXWsagWk=&8Rj9KYWsbbgdj=&rtaxZfXbhobUc=&wWTXUZXmqfefn=&Vtf4IlUqdY_Wr=&w_9xMXZglgdaq=&5WjswIYcfoUqf=&cAsqDBXlqe_YV=&eJJJjuUUgssUX=&TbNpSMUaolYZn=&CVY7mJWXlYYif=&hv_VlvXZiealr=&TKd39AZalaUds=&ciXSrGZsiUcoa=&x8e52uWrnbnjX=&amvxFpU_kombU=&IMfu2iYlreUpe=&tLicmBUZrmbfe=&hvGjCjUkUijgY=&s2MxpkXUiqlme=&h_w7yXWsahXje=&HTmFNnVZUkeaU=&BXjTi_WhjemgV=&SYlWpoUdcrife=&jEFGM5WZiWilr=&tP_YMqXfsrsVd=&7E7annXWnhpid=&atzc8kXbj_paY=&vjlAdvUaqroUh=&ZByPziZUZblji=&jfDqtKYsaogWr=&RYrhLpXkXgspZ=&W_u9KoYqlajcp=&u6J_k7Zslahhj=&37FcnPVgVdpXd=&3ARFIoWleskYs=&KZTipUYYqVXWg=&9N6G5FZeYXliX=&iovLfHVZaUaXg=&XTICyOXq_oqpn=&M67k6cYgWbpVc=&jGieJYWgccpeg=&CAd_kVXnhihjW=&NY_H64ZiaZkdm=&3iyyq8UncXecc=&cIl_XLUjneYVp=&DfqCagXomXrko=&gM2pqdWon_lkY=&HPuA5AVVjjZpp=&O5DUmOXqYXqrl=&cE89B5YWolbYb=&_daE3IYb_hjef=&UO_4MVYb_Wcrb=&blhWJgZdka_gX=&Hqwp2yVXWnkVg=&UggSOUVUVfsXr=&38meSQYegikia=&YrsDQMWlmbWYl=&5Xo8ubVbsndrh=&h_HdIiYaqconf=&MuxiLAVUmkrbU=&3oxqEaZWkkqri=&M38w5LYbeenrc=&FL8ufqUsaVhgZ=&Y9bT2pXZclkhr=&fzd2ldZfccYip=&VqmhfzUeisYhm=&d8_fS2ZWnqasf=&ZQNOKeVpjlgab=&HvsfV5X__apdW=&eyCFTrWXoVem_=&gAbXZQYjZngpo=&SxeAQ9UdaU_nU=&FSySBLWa_dZnn=&C_W6CMVprjqoo=&5Oi3B6ZqdrcfZ=&VYgT_cXoYcfYb=&Yu2OXbVVYrjam=&boaK8iUpejkYp=&2Qn_S8VrpiqUh=&rallzcYqoqflr=&QRXqx2Zakkpbg=&f7nlbNXcsYUfW=&SKjtfNUrcnV_U=&aNVgXRWnnkZco=&wS3rIEXjXVn_r=&wMN7KrZaqkVdo=&IZ3WH6YVlbqZY=&bmLt_hUklcbde=&sya3haVpokVfq=&jPWDG3Vo_asVW=&PA9uvIWppciif=&DJ9U5vWWgrong=&TkeL_VUq_erXW=&DCROaCZUhsqmZ=&uGocEUZqollWo=&DAvBaJXdiUprf=&rA8q7mZnUli_Y=&Pb2z9PVqcVngr=&uftFMVYqsmpai=&fEtAdxXXXokjp=&Jsj2wIWhbVZ_g=&VWE_MxZUbnfhi=&S7JE8jWgneVWs=&AgwtvaWoZkjX_=&ioDJcEUpsqWbl=&rzaLPZZjmZXea=&OkFMBXYaYcXlY=&usmeiBUWiWpdm=&GS4474VosZUhV=&Kh99c4YZpdnVe=&bxJpVEVVbWbrj=&X9Y3D7UWfjgoV=&ZPwE5iZscYmeY=&yKZasMUdneZsl=&GbJ4RDYpeaUgV=&Ba3N2rUhqmike=&ponLJWWbfemop=&S_liaSXoaWlWm=&NokXBMZhrXgss=&8xWTunYbWUUhj=&OGMpQuZYjZroe=&BVA3kvWZcagej=&lxcjTJZpWqp_b=&bDNipbVcrUaZr=&hvxGXTXqiVljW=&YBVorKWiZX_kq=&q4iQLEXVZeXYh=&YXRcToWWhsqXW=&s6uV8UZVkUdnk=&rIK5zFUpjqqqi=&wHR8cwZYUdfcp=&6_aZoCYafbgjW=&dpHm_gWrearld=&EOjrjHUjrliUe=&mhCaNAUbdViYU=&iRubiTUc_Uh_V=&9A7ADHZjcW_Xm=&ZGsrO8XcfWWZn=&apg2O3ZVbsZep=&Zn2_RtVqbZqpo=&rFeLF3UYmVoWW=&hJcAvbYqeWikr=&5XoxtRVbscbXV=&LHoBttUajmbpf=&q6SToyUh_nqXs=&yjhCquWnopoWj=&menYxSZj_ga_n=&nzLAxMXdhdYba=&tvwyBhZbrVZka=&2KGB7UVpkcgbY=&gOff4CWigVc_n=&MPs7p_YcYeYr_=&etfcI9ZXsnUmg=&NwNsWEUekkrYm=&juBdsOUdbllYi=&a4oROXXXejcid=&8GA87TVkqlZVi=&_gEpSfXlf_anZ=&_7zYxMZXfXkgr=&5wuKDwWqp_mde=&qyMJmUYbXYfep=&CImihhVUUqhjY=&tG_3sdWglsqjb=&DW3NIQXWsjoqh=&6AAIFpZcllnpb=&8s8of4WinfkYr=&Vm49NEXWq_rW_=&Ar3zetVViUZl_=&9YO8qjVWmcVda=&jJZgkqVsgl_o_=&lujQsHYfrUlmp=&n9oRLHWrjofig=&pu5T5sXX_dhWp=&KPQPIZVeqldVk=&k_FzvqYknUfaq=&ludYvaYbsnfUV=&R486CbVVnZrUh=&DPr8GsWkfl_Wj=&z2QkbOXYlWfji=&EG9BdKYgYUkZe=&GI7CEqXkYcbkZ=&LgZtmhWmkmaXY=&zRBZgEXokpgb_=&Kyl34_UqfghfU=&wHBcm2WhVqajf=&i3U3veZYYsVfZ=&RxZWs5Vmdhl_m=&iXoJzrVaXppbq=&qptBEnZgimdYV=&HdVJtYYUornXX=&w58aGxWXsiXZk=&ZGrtXsVYcprpr=&4WuVS6X_hUmoW=&dhHllxVngpWrj=&MuAdyXWmcoYZg=&ZNmODPYsWUejY=&GjlUW9U_obckm=&XbU294XZWhnfg=&ENKCogWnZXbgm=&7eitAMYbolgge=&DfKtvrWd_pbfc=&TJQ8PoWYYklUs=&tfCCPWUndrYXY=&S3XvqDZhnaoqn=&WgcxnQUYmXbYh=&D6FWmqZgjXfdZ=&N7CWr5UUsesoh=&X5H2_nUXel_sn=&3U2Y4ZUiXfejp=&F3AGi5VWgfkiW=&hrNq3PVgrdaY_=&zfEtDvUYbajYY=&hmCLEyUgq_WrW=&m_8P25ZYsdfrc=&RB7JEHX_UXXse=&ZvX4VmWrgsjbh=&qdXAd6WfWilsp=&R67kIwZi_ljqc=&oY7TTNVdlo_er=&GRtvhgZdoemqj=&vVrsuVXUipmcV=&xGnwYOXlmhbeZ=&KGjN6UYmjkc_j=&PItWqVVakoUnc=&ZJnZV2XrgeXse=&PCQgzQVneceXc=&6iEXaoZXiXfod=&EwLPl2Wqpacdb=&wI7VBZYlsVmlX=&5gp72aWWmaXec=&9oewy5WegrZnk=&ScoTJYYYbfkne=&QHmro6YVsqWbc=&euz7bEUZ_roWj=&Wmi4GbYfUVhrn=&ng2YIeYnhmgpY=&Z4GYcYXjZZrhd=&AmVS6SYVnYidc=&iCO3rPYaZmofh=&JRTf6fWoZU_Um=&AyuzlZUfdqqoa=&yXqpAGWUfjrUc=&WMwo6IWZ_hobZ=&USl3CxZkfcrbr=&mXL68wUrll_Wc=&JFKFR4Xnibgje=&38C_LfXUdnroY=&DqTaKiXWhchVZ=&xzyGbtWVnakil=&xPoH9OVdamojV=&pX8LzaXgiYZac=&lwby9qVfgemj_=&dcUluzYfaaobU=&l9Bk5hUhWZfsf=&itxfMpVmUbUbg=&BdLqUTYoraWkY=&8Pa4B7X_ilqna=&jIvbujYk_grln=&LgktyBZhWYdgZ=&JhOnjqXUV_Ubq=&ibpVMWYjsZpZe=&NLVBnAXqjkedp=&amMDDaXmfYnpd=&QgtG__Wapdchf=&_VNb7AXXeWlod=&v9swtXYZlmkok=&o7bohpUorcmbW=&EPtlebVmjbrne=&lgAE2WVWdgnZn=&hkp3cAVVksnrj=&VKrspgXkUWXbf=&rPGOVgYgcqmoo=&EiUwcqZqlageX=&mOuUN5UaXpYes=&3eq7OCZfjnmcl=&JBkkIJV_ipUYg=&Xw6ng_XbZYdq_=&692am4YhVipjo=&GXsNpBUbfoUib=&itjU4QXndcrXh=&enXZJsYYdfrrp=&EVEAnXVrjlsrn=&NUhOZZUdnVhUl=&uUqZ4BXmoVqso=&rRmdI3VnnrjiV=&GFxxEZXqhUgjW=&fTGxmWZXhVZYn=&SnRKnIXUcYZjl=&3FYS2HUbcdben=&fS8loCVVsUbgV=&92aoZ9XY_iisU=&Ocpf2TXiWipjc=&Nqfva5Ziji_Ue=&tZujN8YjnVeVi=&YZGQ2dUdVdmdk=&KKO3mpWf_dplq=&OR9OUQZfZWhgW=&XK5l3EZlXcXoj=&lOvzZ5ZjWnYkU=&zTeBIOWqXhjne=&nrIaYKYeqarse=&jrMCrGUehflds=&t3WsWtWYlaUma=&i9hiSGXglfeUX=&52p5ZHYaidhjo=&lBBvyBVqaosps=&l9aFolZlahhrl=&MirDxBW_VVrdl=&4ZV5OAYkWgsqq=&xcoqIpYheqUrf=&PEkWlGXV_cZa_=&Lks9hkY_dh_Zg=&zeFrKAYVnWsoi=&9CtWFsUZggbYp=&Eb26ZfWaWgcqo=&RmiwcSWgWgUdb=&sbefPEVjpapWk=&ArDY7IYaglU_i=&SxnK6aXenXXio=&ZuWWQlUgnUiff=&S7vIIEVbnXUlZ=&oMyOcBVYnrohm=&jQJuNdVVibnlY=&3EaXBpUrioUji=&K8uyCSVbXejbl=&ZehjaWYWbdUjr=&wnHUJxZdZejof=&QL35WnYVnadga=&977CMMVgUrqlm=&HVcmQ6XkUnUVd=&j_W82EVZYVkYr=&34ns4fWiaaXs_=&wwVrIwYssfjbi=&fBuFtjXnofefk=&BeQZhCYacpccV=&eUekmrYhrnoZk=&tsGIDpWfri__m=&ZmO4DhWlcYm_s=&MMYpcvYegoYXW=&FIc9E9VnYhoed=&shEvUIYnfdpaX=&OXoF_DXVlselk=&7Y2HjlYdeiesq=&oWLd7FYdoZgYq=&Z6_oadWYegiae=&MBjNW7VhoXsXs=&H_sWkLZmlj_ks=&VUiyWzXgjbard=&BcnWkhZpZmYWh=&DlvOoCXinkmYi=&MaEUUNZZqdgor=&K7AeEHYhl_hho=&vu_jOFYUpkfeq=&horp9DYVVkUX_=&zf3AYQYqdVniq=&u_xLMXVmUaqcX=&i2frKaWsUqgoe=&msx344Zhagnde=&VLOrxuXersX_e=&Fm9_ejZV_njWd=&OtgJ9qVnZhneW=&SWytakVYsckkV=&vgQ8fTUdrh_jp=&P8dzVSWkjmebi=&yVMOdYVgfpnmh=&Pn57FkXgUedlf=&OugeKJYlVanhU=&xc2lF4VahhYhg=&HC5wz3UXYgjXo=&SEyDpdXfiVfgg=&uA4aE9YmlXajp=&Zu8dp7Vc_pisp=&tB9SFGUaifmon=&6M8nbVUYmfdqe=&spbPNQYhopbrh=&3GYfT5YgWiqal=&VHFHI_VeYYhkV=&QApr7KZpiZcUY=&kloTf6VUgrYlm=&_SBrIHZjr_Wlo=&xgKaHvZlXWq_l=&qdQj7TVlfWkqp=&33bTesW_ph_ni=&izgIYrYlnfibj=&z53dtrZY_qknX=&_lA9GcWqhWeZY=&QtJmouUaZYWnh=&iApQDyZfnnoej=&CRr8xdZebaUrb=&lG7tBOZcjmmhf=&i3a3lTXkkqsei=&QQNvFXXemjasp=&yO7hGCUsdbgcU=&SHkwx7XheohkW=&By8N_wVsmniUi=&j46KZrUn_jacW=&QqwkddZjcXXZU=&i7qjvjZedWgeq=&Qmxc9eYXX_dds=&auNGFvWUpUZbb=&Jl3ywxYboYsil=&zlhrsXVkVhchg=&HQSgnoUXbnYes=&xcsW6zVpWiWpr=&aJku4GWYqYVsg=&fyF66YWidXigd=&_B4II8WZbjqkf=&SXn2FqXnhWqhj=&FjWSkcWbVjqXX=&DjYi9hZddqiXe=&WC37U3Xbdciem=&q42veXUgWXqrh=&7zDzbWYamUjbp=&6vyyUBZebsrdU=&iWutysYccXYpW=&qDjH6QYrpqVmW=&JHwSIfXZkmolr=&kUiu2VZUUrbis=&fUb62QYabmZqf=&Rg5M4WXWYjark=&9_LSkyWUUkjZY=&6WpLHHVijnhpV=&ODRDSpZ_gjfnn=&VUQ2HuUnipbjo=&cKvO96WUmdUbZ=&tQPSuuVmcW_io=&bCeS2fVYj_jmX=&gBSK9UWjdgafd=&NijY4YZor_ggk=&7bwz4fWepWqca=&dhRUiBZgmermZ=&nR3RHSWrdbge_=&P5n7gaVZrajal=&nmXk5bViUeqcn=&9QI6VUUXarjnV=&U9uuoYYWqaanc=&mrAwlJYdnlobo=&EfHrWsXmpWngV=&l5_MLvYoqpbUc=&rBZKyHWYlnUpi=&BmDMRkUjqXkbZ=&6uph_YWbleajX=&U6uA5uXnVhqWU=&_Qjqp5ZWkrliY=&zwzkFgZocchcY=&qttoMrYWUWaso=&mBYsVqZfajhfW=&Fdsbx4XUhnUeV=&HILsaHVYleocY=&lPIGzWXYrmnZa=&SaQKsgWeqbYkg=&FpxTpcV_d_nYb=&GA8HOiUebsbgd=&qe4nLRUYolmXZ=&F_8Zw5Y_fqmZq=&Flyw5IUijXkcl=&jpBnHQXpejdkY=&QbDe_TVrcrjVX=&PP5bGgXYsUeej=&ZA8VRvZU_orVr=&RnZupBWboUgdq=&welFNTU_lrVnp=&pUb6EiYXcjglb=&iB_HoAWUffcaj=&2T8rujWrkrqZV=&dDkcayXZbZlrj=&_XHKIrXbopggj=&KGkKaIVYhWap_=&Iehy39UpbneiX=&iHyBpzZclkWqn=&3mv586WcWomai=&N2WQSVXrVcmod=&fJqv5NYchZXpp=&xWk_VnUdalaWU=&R8tN7gZqYmak_=&WUT6k6Yjhqgme=&5QPEzqUkpmcVh=&C6lxzkVreYbog=&n5CSzAWlVmdee=&GDZshWZUerorj=&JVsztiVXUVnWn=&5JYI8nXiXfbpb=&l2lhyfZnWsXcd=&XPFK77Yoghidi=&5scXfbWsrXUmc=&bahRM4UrfeYXe=&jg_H7cYpfhodZ=&4eC6ilZrqkUYW=&WYkYo6XilVq_Z=&gjcucXWWZkXif=&XTTt3xWjjrWgf=&WqiErYVimefqm=&sDzzGGVkbsZlc=&l2BFxIWUqfhkk=&QI6VbmXe_bm__=&oPw6iZYhZagVp=&69apPHYlihmZc=&LO34zZZnqVndm=&azmWrjVkeVkbr=&JJHGcWVssdedZ=&pHpUiRYnpZZkp=&S3BZ2lYebnpXl=&CrWKltZolWmog=&q_8RljVgroUib=&7j3wJ5YVqbegl=&DEx4HHUbiYnfl=&FeMrmcXeUqbfa=&ETzSZoXbsmdUl=&XIQuyZVdhUnkh=&4edIdUZdiWrjq=&YXeOpRUWacijj=&DsWBHDUmnbmcr=&h69sG4VWUfeie=&pvUn53ZhUfVll=&7mvxgcVll_lcn=&EFMr7jYrlVnW_=&dtMB67YVjVkYW=&vgs2bbX_qcesq=&Sdn6jLXleenpk=&_JbdLuUsUmllf=&lNG8zvWrhmeos=&LOF8mgWoobglY=&MqnTpZUqrXUXs=&PQdO3IUoZioaW=&D3RZOIUVmqqWV=&nPNIpcY__X_mW=&CjjihQVaqmbUc=&a9Hws8YohXZcU=&TmUqgoVjc__nV=&AxzZHjUhnngon=&Cn_vhoYmmafhm=&qWpzdaUfmfZVm=&VBId38Wpjjejd=&ykMPrBYjcch_g=&BbkEiAZfbmagi=&6LCUSuXV_WgUh=&PZu4qpZWXklY_=&b2kqYHVVhlVVc=&KoALb7VYVirWY=&AVvUt3Uaqlmgn=&XGG5PAZfaYi_b=&dHXoVCWUmeqel=&wdRFwKZcdoadf=&LDkiGHVXqYpgr=&ORjVD5Uocjksc=&ByExIeXrmWasV=&laIpfbZdjdYkh=&NWnDdKVjXWcZj=&2IxHmtVmqWhmj=&y7bm5IUiYhWeh=&aKbOIPUcgZeaU=&VqVllsZUegaq_=&fepxfHYWZ_paW=&QuaNyUWZ_Wcml=&tERDWxZUmhmcj=&kL525WVhoiUar=&dpEgxLWjgfoba=&e4CVmlZnVcWbg=&qFFodRXXXnjfX=&_CgwfUVblbmgY=&gaZdzfUksgial=&fmjJUlZqefoab=&PNaheyXchpgdc=&fGptj5YgrWWhn=&BtmRlXYjcaiVY=&ZLzt5gWmVgWZb=&oB3vP6YfWqmZj=&HaqleKZeclsbW=&lEZxKzVkeZfjn=&A97EzOUYgXqqj=&Pv32v2XjeWbol=&5ed_MdWYssods=&3cVhNVUXqsWrd=&IPAS6dWloog_n=&WFyD3UVqeZiUr=&iQPLcHYlcmnas=&9AUOZsUokYdVo=&jVrmZjZWnqsec=&pCk4nXZpfilan=&wMKhHcYdfmaoh=&daR8qSWcfbpri=&5UEGcVXonWdjU=&GiOdQ4ZgrZosm=&jlZ4O6ZosdcZZ=&B3p884XcVg_fr=&4_OcEZXYUeiWm=&8MrqYvXosaY_V=&6RhgUkXYlpocd=&LAUejzVn_XVfp=&DXA_LWZZr_bgi=&d3vzhwWmofjYX=&UKO76sUYmj_ne=&HFUq7KUeel_ZZ=&9nLydEYYasomm=&KLI6A2XkYebsi=&lNX8G4ZVaZlUg=&uvZVvxYXggpW_=&lGL6ATXVhgVle=&_rsZMpUdahmnn=&3iLscSZqVaYUe=&93aup9UklYUqp=&dcuUKcYedghrj=&piCANHYiVcUpc=&LJkOEFYUq_mUo=&pfEwnPWmkshqk=&7ZGe_vVfqfpjq=&IGVzqNZicWjdV=&NEim2eUaWYmlU=&NjPoSyVmnishb=&SXURnQWsUchno=&P8nzxAVlXjYrX=&QMQdnmWp_ga_g=&EBeNWDWVnWpej=&gVdDC5YfZcqee=&7GPm4OXilirjh=&LlivLQVZX_lkV=&DsNaUPWUsaXXc=&BqbV3cUqbriaq=&PtiblDUdUjmms=&dnJFlIVmUjVna=&hCKiYQXbeeVgf=&96F6ekYijXaXb=&UBy6BiYeeVoXq=&Igiw8pVYadbce=&VkLVmXVrehUUc=&4Yu_3QWssVZfr=&PkDOGVZerombl=&KLTTHjYijndan=&Rnp263VfcUefX=&_dvOiCVenUhdd=&telHinXkgcoZf=&oAcqBFWYVWklb=&jTAavVYiZonUp=&eWIrX8Znbifak=&7wA7miUUrZnio=&hZk2M7VpicWsm=&wpmSDBYXeh_ga=&Bq_CJuWYV_elj=&LJJ9yHUbiXYWp=&Gc2NOKYrnngqq=&gawE5sWj_jeib=&Qsf3SPVrbYWln=&uwgLhxYafhaga=&sqJTlaZndafdf=&8LojquXjUqnmZ=&mC7ylrUXZYofq=&H8WbxsXpibphY=&OTPQMxWrdUck_=&dSHjcZVcbhXpm=&6muoTlXrnaYsj=&kTVRDKWijjaaX=&SobSfXUrsUZXV=&NumoGtUlVeghW=&mlHfj9VesgpVo=&Zdcnm4ZpcVbda=&xFMkOYZlUqqmZ=&QcDbCvXZbZVYZ=&NxrX8tXngloUg=&N9ggkwYpsjnfW=&l6u39MXVndcel=&lTepfcYVhsaeV=&e6T8y8UYfjjgs=&7p_rudYZdldqk=&ids_SmZjjUs_b=&fL8hsVVWXW_Vj=&VgM_xRWUijdYk=&q5oxaUVYhY_sc=&Fnpb3FXeWfYbl=&ThBjUrWXk_hrr=&Wb4moVVsUYjUq=&s_3SQjZYZhVdZ=&BYA9iQXprgZim=&fjCLe2VkdZsmY=&mJSETTZpsfhkU=&z9O6YzYfebkdd=&9UpJuKVYkqrkh=&tq3ECXVlV_ZsV=&KJEct4YZgdfsb=&_HiD9QVhfjjoq=&jQ_na7Yeqkegn=&KIuvBXUrbYs_o=&qQ5RzVWbpgpch=&MAALkJYUgYfll=&mSEndRWcqWegk=&tLtHRDZrqbrcr=&xDbak2UpgobZg=&hZyOE6WsZb_ph=&SIgNxtWUkcZVe=&A5IIZpYpYYcVn=&uDYhn2XoclWqV=&rQnM3DWsmVlfh=&v_6o7GZYcckkk=&e3J5xdWeijokj=&Qpfe3bUVdiYrf=&8BebY3Zlon__l=&Xqy_OPZqVsoXW=&9jGHXaZrgmcWg=&48C75zZZVX_Uo=&sYGykQWXWj_iV=&YOsKi8WknZceY=&vAsotNVecXcgc=&MB6FINYmojco_=&4n4GxoWjq_Whp=&CHUGvvYXh_pWn=&4DhA7aXVeZcmj=&EwP6ASWqdidsr=&K3pCNaYUddkib=&kjGYafZkaoc_k=&QzNwnbVfYWfck=&J8E52oWdajldc=&BQHdKrYdWqsZX=&3YlHObWsmnZXj=&XYFtp4XrXhfVg=&SnwSH2Xqgo_ro=&RekXOjWYchpnZ=&lw2yaKWaYnoci=&db_JWaZbWbZfl=&PtPuZFZbeZcpY=&fR9ujzXZjppcm=&z9sYVXZeXsYhV=&VpLsobVlglqUm=&tP9wKsWkXasY_=&TEXiKzZmYhUqi=&VHuXHsUoWqnaa=&6tYypsVbWheob=&Esk3DxUhjfpVY=&4FcnX9XZ_njVU=&a_xKZKXaX_klm=&G6zq7SXielbZl=&Vy3GG8YUepkom=&f7kfXoWoidiel=&ROvmEFU_WZ_jg=&wU4UE7XnbpfqZ=&cv_M8sVYlppYf=&6tcO5jVnokfqX=&EDW_wHZcaYodh=&2aeKTwUdZfabn=&bcOqkkVrbWnll=&NGsUx4WZXqoca=&RtNjD_WdfqWeY=&W7eoRJYhdsZhh=&Gyi26PWhjnhmi=&P4JCGNUVUahVY=&l95IZVUVWhlb_=&zL6JKWUimUsZo=&_6HGl4WXmlofo=&6BqgsgUjqblhr=&RzaeJVZsZc_mb=&XSoZxWZbcWaUo=&6oYgBiVfUnbkZ=&gDxzsQZgmodXZ=&6tcuUAVWZqs_Z=&Dymr_GYXYmaes=&dcLIhVXbrgqXj=&QwsQbxZj_isql=&PgcxVTZscrbYc=&Ch2JmyVnjhV_b=&OCg_pDZpWofoq=&PxSG9lYWsodZY=&GbSB3lUipWmXc=&jIPOCgVodgqoV=&maPWwdVhVVdZj=&X7JuaAYjYkhed=&XAPWU3WX_sXqV=&fYZF_BUrlcikr=&ZLHlIRVWr_paX=&xfOafaUZf_pmp=&T4VHYsUbfqjZn=&5RRPuXWbcYhn_=&_TYLDgVjfXYm_=&lSJfDgUp_glne=&7z64HhUVlZnYU=&w7BKbpZhpZX_p=&U98JRsWqaonVa=&QapRMaZbbddY_=&VdNOX3VdUliqq=&o6xwj9YesckYY=&Fr4WwvUiqslse=&mB5JpTYcXgjYp=&RFYTMxZdlffrd=&ZmFI3qYho_erZ=&7FzT6WXqnppWf=&e__DOgUscVano=&rGYwf4UVak_ls=&KpR_3zZpqXUlg=&h3RDrQYgYjlir=&ZTcHCLWhkgkgk=&LsY3GWXemZiVr=&WNrfrDUrWgqZm=&jel9mHWbhWpbi=&eH4VLmUYdqUWs=&A99zmrWspmgkU=&HBTpYzUUbiYml=&OdTYbiUbpqeos=&LG7xOMVsg__U_=&euxeXOZUiXUjm=&9VVDosVbqjbmY=&5rSSwRVmskXen=&7GbrIqWjofYdW=&fGrZkZYpVoffb=&OXuNt3VZflcWY=&M3PM_eWlUie_f=&nxy5BpZd_VelV=&YTymJsWaYisWp=&n6HlscYsfqsai=&i_TtLEWqiWWnh=&5BtVniXWqhfpd=&cObn8uVlhWcpa=&_SIhn5YdjggVk=&xXRLPHXWlkosn=&Dv8V9HUakgapp=&XcPUSVV_laUdZ=&w2wPsRZWUhsgq=&QVHhO5WVWfkfn=&S2AoXmUcZaYqi=&9siSVaYXVWsnd=&3jSLbFZl_Ukdo=&LFwI4pWb_Vqre=&ifkIWbYahnjnr=&hKkwGbUXmscZd=&fxrkUiYjWjfmd=&B7g9AaVrZWibs=&l8ADosY_on_na=&qLPaNzWdYeesY=&kGfucZZmdq_qn=&bmhmJXUsZoZ_p=&v9xANdXUmpZoq=&cvKhjhWrjfVgp=&drNpPQXqofqZd=&A6tYQBWmlpdni=&frTZn5WXq_aYZ=&aXwpjWZWbjeh_=&hKEWE5UaYlWip=&On2seBYWjgXhb=&LpWtz6Xqoiqib=&TelUC3Zc_adWb=&VDNRAeWXigdWb=&9AehK9VYnneUf=&o9uRCrVkrlnYj=&YsGwHFWdqUUrp=&pEHrinVenmZqc=&M3GPbiWmjgkg_=&v8HcX2XUpZnlV=&otwNG2Y_VXdns=&uAeepZVoWW_pZ=&vmAp39VaZaeob=&7ZbYlmUrbmYjn=&8Hpu78Zes_sUi=&8ZeIHGZXhecpg=&ZRB_8oYqpcqee=&8LEWU4Yaijmoj=&BWwHQPWZjrbrZ=&yXXXyqVoclsVV=&MTTHDRVmWZpVc=&E8k8YwVncrerl=&c2phvaYrojpYi=&JAiwSaY__heUl=&IvbQfwXW_mkqZ=&O7LlLDXdcW_kf=&24XA6qVmVUXmk=&c95OCAWcaYUne=&hORhwIUdeipdp=&raVjmCVYfpWaj=&3y6ImQXVrjios=&_A7_K8WncbU_q=&TUl7MiWfsjead=&nZ_pZjVpsVhkg=&VkYwaKWmiYgi_=&nJ7msKUdZjY_i=&8Z2vmjZfWqVmZ=&U28gU2XlkkYec=&Ynu4rbZhblsrU=&kxtISmZbmWZhV=&qOPp58VmilXnk=&g_iP62ZXkkoim=&CEXCGEUffqXpY=&vyuocrXbZskig=&_dJfkUWarpkqs=&6L9dAYYbkjcXp=&I2ouk9UYZpZVm=&w9NM_nXkUsaga=&qZEqUmWYiWfpa=&cWPkpQXVdrcre=&2yINekXsphjod=&SO5BGaYYmpXai=&tfj8KyUaciZdd=&JeYtAXZXpnfro=&UBEgkrUXjekkn=&oO7oe9WedVUsd=&TeE6xgWpehVYj=&SXxPoOVqiiUol=&ez7VZBUgadqXr=&GQIjlvZqqb_g_=&MN3UZ7WidWZrW=&mhRcLBVUcbWad=&pYo98dYZgeVUW=&xviwOXWUWUrng=&VebikBXgdXXfX=&9yirLjVWjYrba=&BgENWTVXYaWkc=&F7flsDVqmajls=&V_934wXYVghmW=&yrR9BiXlVedss=&uPpTyVZhkWfmW=&MLhwhKZab_onn=&4WlWGhXVnZrop=&4x7xOiYeddlpi=&PTiFnlVpjcpYU=&39w7oKZnifgio=&UhM4TtVrnoces=&3BbzdjUUknlec=&slEhXWXrjXaea=&sqE6TfWrckohW=&4IwQvdXmalkUa=&r_EHUyWsfdo_X=&Eupq3hVhks_pk=&ddOYe6VppipbZ=&Tf7Hy6YVfe_kb=&4iXrpsXhaXUjh=&YcT9LqYVgckok=&xtpEZxXiomhjZ=&74tEx7YbcZimk=&kDcYssVhpoc_V=&GbrHafUoconYa=&qcGVs7VdnqZmc=&33kLTGWnnplje=&_twZdkWVhehfs=&O7StCgUYZke_V=&pu2UWiXonshbj=&F2cbv5UpmjnlZ=&ifdEpvUshsXds=&wZavMVXjhUdrh=&h4EMFYZcYdmck=&ynEnDgWfrhkla=&ihFjKkZjmWXon=&MoJ2PlYZlZmXZ=&2MGPg9WgVgnrU=&fJ5ESzVjbecV_=&NxJbvRVrXjkkf=&952KhQVrVqjfk=&n99jeHXWhWdfi=&ZuX4qPXkheicZ=&NR_uFKYVoUiWj=&ZwFaHiYWVVfYd=&ekxMYSUZiYqXk=&mYFYyQYsscnmZ=&mx9MBbU_ainhe=&jGdQLsXsYUbrr=&DMowjWVmnpYWo=&rXQ8LFYrdjhWo=&qtvcF9VdjcrgY=&5vA4xIVndXXZm=&RNM89lZW_gmjV=&JJz5lSYbrVdej=&RMd6DJZUaaffh=&foShq9Vpilnds=&kwYyehXZnecqp=&D2cXvwXqcbhsa=&B8epbhUciZopa=&HrBlIKUpkWZli=&FAlfxrXknflZb=&VcOS_hVnikjko=&3EJ3otUrbnijd=&q773DcXaon_sW=&rxv4y7Vob_ZVn=&fNu6VaXeU_khb=&VdaQuKXqrsYgV=&M734EpXjidb_Z=&UFM9xVYkqrcUZ=&hZhVaTWWnZWXZ=&nfNIAxYeWhWU_=&x6GQXPVsWciVp=&9Bk9x3YfXrcgW=&UXtzOrZaWUiVX=&e6Yp2VXVobfqb=&HYAItvWkegfns=&PxxmFHUjiYWbi=&xJ6TnBXkdmp_i=&mtCl5OYsiXoge=&7tvrrUZlenXng=&bhpBmrYadonjf=&s7e3rWVe_kXsg=&nDwNOwXW_rXqZ=&8peXLtWbpVZUY=&F3MEWUWosiVpe=&yFvE2tWcdoegq=&zTc9I3XcXapYq=&QUFdMWXnqVord=&vovYcMWXXfZqf=&rPEIXwUqYhcgj=&JzprSgWZYnbka=&oTFFK8Zsfcefc=&P7D7iFVslkYbV=&6ViC3xXcqangm=&_oUkRFWkqafhZ=&rBCrtQYXgXghg=&oGfUbwXrgmkXc=&I5h6sLXmeZrkp=&nkMNylUYcagag=&yKaAXLWsUgsql=&Y5aVFGWbdofYU=&lAKwJmYpcsmqi=&rdri7kYZUadkk=&sZGTWiWj_jmeV=&gRrUuJVVdfimc=&ysaxDhUkaXVio=&WoStsqZUVYYqg=&7XB7gNXnXscbg=&RKWLawWrYfYXe=&H7yLgrVcjYWmY=&xLUXT7Vokdqqf=&IGYph4XedjcoZ=&pn8LuXXViVmjW=&NVU8KOZqkqlYs=&YSyMMpWhUbZ_n=&mfmUszWsZdeUX=&WuyZGYXmicifW=&DBtGBkXYcaUom=&dp_iMVVmsphfk=&OBgpw9WWiicdY=&GwSVDvWdqgdhf=&cK65U4ZWWhcZe=&gocC3KZYmaqqm=&ldcgfQVsngrjo=&zGvLVXVoVfdko=&Bm38GLUXaahoY=&tof9qtUsmqdmV=&FVz86MZcqbgrd=&gEWYi9Vi_kZbq=&qymzj7Vsagnsd=&fpnhi2Uhj_off=&UxsLTvUecksfc=&t_5lAfYnsoaUf=&zrfcK4WVlmfrd=&xYRI66YVVYjqY=&JvhmJ6UbZUWfn=&3NBYpdVXgmqh_=&ueSXi3ZWomgZg=&zwpI_wWalpsnq=&Ge4KJOYeiYoab=&2H7oIgUfgfdoa=&q7zc_cVbbZmim=&96rpaVYZmfiUp=&gEeQBjWgkX_lV=&eRSXRKUepYVgo=&v_4C8TVknZeXb=&Ypk54ZUfpqhWb=&Jb6239ZjVsbWV=&P77m43YXaaico=&ZZaFAHVViYjbn=&Ntu_ewUsrabZa=&i9UFkyUUmZZnj=&ih5TYAYnVllsr=&eYHxRYUacbZYo=&JeCw7CVcleomY=&aOXAnCYnmegmY=&ASUtu7WnosXZj=&rEbPTNYcnaYrk=&2B_QQ_V_UUsUU=&4Ps_rgXWmrpcn=&YOKi_BYedWmsV=&zrzRRhYZVfUso=&NwR8RIVkl_dcg=&tyQvkjWYaUbmd=&3Ks4_ZUYpWaUm=&KwhwtVV_UoZWW=&2jYCrmZcVXsds=&HxkylOYYokWbb=&DbfBVUYfo_Zoe=&bIOmOZUfbZZjc=&pU4MjNUpchsdm=&frmSs9ZXselZp=&WIkkfOZch_cZl=&AlSkjKYWZdhYW=&opYfRZYhlWbbj=&o_LuKTUsmfqmo=&mDIFI9Wo_idVr=&tBDn_wYinflek=&W5DZnOYofYoir=&nmarUSYkpbhqU=&GhM4c3Uig_dVp=&g4573WUoYVdrr=&rlUILVVoZWWiZ=&zSizRkVanoaiq=&nzGrjGWUgYWqX=&9g9O6gZVXlWqY=&OJycCpYcoqkVc=&xvWH8MWdeaeeg=&iysDiBUWjhphl=&ZCLZbgViqkfmj=&oYVcN9YijWkgU=&pqlDiPUhVhhXo=&xgD4seZmVfWne=&p6_GF6WUrjUpi=&XajQaeYVlrpij=&qZZiMmWaicnnV=&yj24IpWb_lnnl=&xOFNqpXWagce_=&mdEScXYahrm_X=&5X68iHYgogqgZ=&hBKGmuYmsbfVk=&yHlC5WUsjjemh=&BsqCtUWliVXem=&IWBlEnUonrpXa=&4tFUBxUoVedgk=&mBEumoVlfcjhr=&Vt4CSLZffZcol=&qd9CKKWrUUops=&6ZrD2cWchsXll=&RPMBE5XrYUrno=&4WpfECZhhedaY=&vtXXVIYVnn_lU=&eEXArgXYYaejf=&a2VQtVWnWmfUd=&C6BzjnYjnqpWd=&3YRTJiVildbfp=&ofMuCJUdigVsj=&fTtCMgWbXUieU=&KXYhIjUYligXi=&ifsCCoValZbcm=&e85EIdWhZZenr=&jsO6wJVUbjomb=&wioXWfWdW_cZp=&57QEpbVXhaik_=&NaaiAlUpXsiWd=&otbzzpWVjflok=&asXycpWobkXnq=&7OeQG5Wl_mmmo=&Go7GvnXXskcqp=&ZJ2fPWXdiclZY=&5Q_WvgXUsamsp=&ipEP8AVnejjck=&nOg4dAUnhZhgo=<Ul8eYU_eZkY=&HhKD5mZoY_mVo=&RKKqdGYqsfbej=&LbduQsXbjeUVi=&mBZgzYYaXUjsi=&IdXSLMZknhcXq=&ddg8gaVefdjpX=&h78VCUVmhXYbi=&gGX6aSUp_ajpm=&3iC4ZkZVq__eb=&pCjUKdXbeYcXd=&XCUdf7WpUVfUn=&oqOaSkZUkiZmr=&aitBTRYgap_iU=&PZEQ4_WdpskZZ=&OhDCXNYqqsUan=&NVo2pkZUgcjWd=&3A_HfHUhembiU=&8jCCJQYZYVofh=&FWGJJ_XaZcgkY=&5FHJgzXcgU_rl=&BRfWYQUibescZ=&Uozt_kVXmcldj=&z_SCyYYdWYdZr=&yBQIdHZr_nsre=&UaGUGHYnoohmo=&DU9ymiWo_mZYl=&ZNFpiJVWmdsmk=&NVSHKPXcYomjZ=&hPatzuVcsgcWe=&Ov8rbtWdgZjsV=&nzbOW3VXmpZpj=&UhevGqVUrrfop=&etacFUViemaVj=&LO2FvKYqZlhdl=&lJvq_AZfWfVlf=&agCNXUWeeqrfV=&EcJocCUdasqVc=&42oEZhUnjslm_=&OYWA5yZfg_Wgf=&HVagvkXcsmagn=&cfbqkMWbfYrmg=&CKcQpFUYZon_p=&VBmiMZZUWYhko=&9PBFvdVYbUhqb=&_z_CvWYWYXUkm=&xlRsMcWqcsdnY=&wFqWe4WggmagZ=&nMrRbwWZnUddX=&hoie4HYViYXdj=&_m8BcqVfacWWr=&FIe6ccXZaicsh=&tSJoGjUpohqfj=&ETBrDTVqsZijl=&xnrDOBUVsnopr=&QwKfSwWaYahZc=&P8ZafPZlYlklY=&YPJwyyXhohghh=&pymNVOZipnhoq=&MPyfG5VmfXbnm=&WBQWovWcdpjii=&wLD7acVdgYdff=&BXCUvbWfUjkpW=&Q9GIe4UfqWsof=&WJoXJeZmZlmnW=&6lvoZTWfhhnrV=&yJCLNjVVUmirq=&hrimDKXVasfoh=&mfbdmYWkiYYco=&8CQt4_Zlsaohl=&tKZyFGVkqUVYm=&SkzRcnZbpnZbc=&xRRWp5Walla_f=&gFxbraUbVgicj=&JFtP_LUiYsXaV=&DrrabWZe_aiUe=&ywsJslWrjbmdr=&SxbIl3YpgkraW=&nx3dk4Wprmrhh=&cw8zRlXeorfXl=&9jbBVtXaYndVY=&Q4QIKUUgZcUUZ=&pwsYKlYXbecdk=&eOpe57YW_brpZ=&5ODAjIWcVmhfq=&HuEUpKXbcohZZ=&9bYphnVaempor=&vKlVJhXckbhrc=&TOtq_rXWgnfsX=&hRoVbtZUfpUUb=&iJeVyzVrrniWs=&kJDEIHZWYmXYk=&ioGpzNZoYnWiY=&2Oh4TEUiWrdnm=&jl9AfKZgofZbU=&fSvSb_ZkdcUVr=&LeVXCeZqqpnnm=&Iz77XzZqrgkdr=&Nk8dAUYUhVlWl=&4mVyqoZgdVUrp=&mwXxb2YlYcsge=&sD7VTnVfammVi=&D8tpCPZncoXqp=&xxd7mnUYiriYk=&ygR99AWiZqblj=&uiilhkYaWmZWo=&8SUx8AWVngYXX=&r3P2ttWrcdpir=&9LDxZHZXqmYhX=&bMoeqCXZqiefh=&Uog5TcUWflfXk=&SbvEf9Y_egoVZ=&9xIR_iXpfflXp=&z6pFGSXsbgWVW=&g5lHcgXXWrgqm=&IPTK5bWhsU_le=&jVPALGZbjcfkX=&OGxKEsUgfWmaj=&gKXVtkXmdbZgs=&oCUghpYqXeZ_r=&3XL89ZWdbiXfn=&BTS6RgXggmZml=&KwTPY7Vhk_Xdr=&EBlPwKZZlrmgo=&xNaAhAXYmZUbd=&unD6qNVlYjhjk=&TNNYxWUkXggc_=&CemAubWYXYjWm=&w7tqTAYofdkmZ=&bVRQ5aYbhgUgs=&gVcRYXZpqXsmn=&p96aYWYjfneff=&GcU_ccUgjgdlW=&KdE8dAUdsicns=&Y4J3hsXjclqna=&zV_NAoVXZXfWd=&h4M2oWVckgaid=&x4ucjzZZ_biWe=&oI9PnHXsapWia=&hI6vOfWr_bkbg=&R9jpexYrafpjr=&bhUXbOUqsrYUg=&Q23sL8XfsjU_V=&XG976DZqilfhq=&V8OVY8Xiscgea=&7d6MHyYbmabgq=&UP4u4vVlcdY_U=&6YHrUlZfgimVU=&et9gYyUonqido=&2vk8CTZgpr_nZ=&FdmF9qWlZnfVb=&GJihDXU_sqcUj=&KripC2WcaZZkm=&uuOhEmYfksgoX=&8ynGJ5YfndnYm=&pezJlGWgXnmYl=&z83usvXapriYX=&eFxHSyYkcaYgo=&K3NOF_Wpnfnnm=&ZQXM2HXegZpWc=&qWrqeFYcWkj_s=&FKyn4cXhUqckW=&w_YbD7UjdYUdW=&kYXCytZpmnilh=&UAjNi8Uajhejh=&KmdCOTXj_YUkb=&4l7Cy9UXjWUf_=&LyOjRSUicVZXh=&tzDAD7YUhqssU=&kZwbaiYfWesqU=&qZDMrqYhsZ_fh=&elhIpMVZhlUfX=&vjzQbXUVXcZjW=&PDjCtXXoWjc_q=&8JUD9EUfZXiZg=&QDpNIoWZWZVfg=&b_94ZiZklhlsU=&QONaiwYlZeVUV=&JZlzWtWceXp_c=&Qwr_GTXXdicok=&oxyxSbZ_iaUha=&dVcQxsZXlbVYl=&9nbI6DYamiWfW=&Q3AfjVWVgaViY=&QUtKMuXdZbabr=&QE4pluUmgbida=&sX9YESVhpjedX=&9cNHOqUbbsmsd=&Lr32WqYoWkV_l=&eQkjPuZbcdWfb=&uiv2sIUfjsWil=&lmVfrHVknpbZp=&Xzy25FUVViWVY=&zRZ8vIYjsdXbo=&Vd5YOhYpi_aar=&YW7blLWVZVora=&NAkSAXWX_UXal=&bvFClpVkUreqm=&EWvSflZpepUje=&VuzBteZ_iigjZ=&vzJOtEXWgoidV=&NztVd2XlWcjlX=&Eq8rfXUYbVVpd=&MYaiXVYhpsUlU=&2ydmKiVsgbpsc=&dISEMtXaiUojh=&_ruHtEYkeo_Zh=&UTwWqHZsnZfZi=&hmbqieZXZmdbY=&eh9_DrZjdenUi=&RwUJ2WWkb_agp=&_axgBSWXnogsj=&CTtpWRY_larhs=&uL4eL9XnclpYW=&RhHO3HVdhog_Y=&plpa5SUofolpl=&DLCcl4Ug_VWie=&VheBC7XiXpVjZ=&VvZhZUYk_brlr=&W4Itm5WYjgorl=&4ZUqthZVqbaea=&3ubutlUmlmnhZ=&ZMwPj3ZVphseU=&DIvC5lVVcjdrX=&DV77N2YkZigdn=&lRNVrSXVYjkZg=&9QEqd9Vc_cl_W=&tLxYMfXmdqpge=&rtD8RIZWfmc_g=&znIKjPYnjsWeb=&_9sANHVfghknp=&wK5bXaZXcfheb=&gohMEXYbZdrXs=&uUBhbYXnXXrkf=&kQgEpeUgnaeYl=&wSpfkOYlejnic=&6hhhaNYYWrpae=&Z4HRQaZUkUfXe=&DidWGLZmoWejW=&dliHScWUghphh=&RiL7bgZXbmjYY=&chfDKCXYalYoW=&Qi_z76Xneomcb=&fMGahHZmjm_Zl=&7PyKc9XnoYfla=&q3qlULZlXikio=&kq8BpYZrmYZZW=&hYJJuNVUqbjkU=&B_3UnzWdehnrY=&7L4PFeVVYWnke=&6VmmvRYddbiUk=&PxAZcVXnVpVZb=&tAOQyFUc_egjm=&djHLKPUreeeef=&P8RjGnUYrpeom=&Vyb98yZholpjZ=&AkOb8bVsjpqob=&9KuykHXnepgcj=&ofeOThVpZZklj=&aBflwQVfWpVhV=&HygDB7XoYeoYj=&a7ATPwVZXmemk=&O39OHWZjWsYXn=&oi3454ZmjYopW=&IBTtwEVonpWrW=&wjMNDkXlcirjg=&pOcTZHZWagWdh=&Iis5HyWVZr_kp=&8zfYyOXUXVqfU=&blTLDaUodjWac=&QRTyfJWaepdla=&ouGJxWZnknhbs=&ZUOyXEZZVkoUg=&Vw9OgWXZXm__X=&nnn2eYXilsqng=&AXZZ7pZaepiXk=&g7wJjkWpepdmk=&5nxJIaZaflYZk=&S_bMOKYo_fW_r=&gfALYHXejdgdW=&TShNWFVoanqVY=&qJ6lfLYinokVk=&2npyoNWUebiWg=&mviILHXnYgpVi=&ypJgvRXqYUWdl=&IX5VpMZlcmmWm=&t3zhx7ZqmiZml=&OshreMXlirafr=&45xjLlYrlZVYW=&qUvGvyUqlrWUr=&EHBYibWbsUlXf=&Z7ZeqbVs__opq=&I4j5jUZhllorl=&zf3FksYrfhasn=&IkbhjMXgjmm_i=&nUUC_SXficfej=&YjfmSkYbhnWeg=&VfJlkuUfYlmbo=&bZOzfMUlYcjpk=&B7F2FzVYVpWqf=&QaLMMLVkUpi_p=&E9522YVZUglVr=&klObVYWfXfenW=&hCxHLnXnaWjcl=&s9PDOhWssooVl=&KxsmXhVcYUcri=&4HN6B4YqjZdgs=&YMwrYpXUsalcb=&aIL9rdUakWVad=&lelvcmVUbbWVe=&KKkybrYopaYhn=&vNzQsAVhafaYf=&knCYFEWUfrpZf=&uULqzVXaVYkZV=&Mb34vhVhoYaZW=&BsuYogYWbmXVn=&nigMbNWUcggkm=&CU98C2ZlcYegd=&6gI25BXobVYob=&XFR8JDZjcmmXm=&ubFw8rYefhgf_=&SN6p6DUXmYmWV=&CxvgFAYlnknsp=&cMUgWnWiipjgc=&bniLMyYgklfpn=&bt2eKvV_qgjsr=&PUvWRyWdreiki=&VXipU2Wsffl_o=&3jYjnEWfXdsmn=&SIvNZkXdZUakj=&SLcfboWecpVmU=&VajLtDYYrZWZb=&tBY7_EWegjqkW=&oFu54oWiVmolr=&USTvyeXXa_jhb=&zLIPfOYjilmdg=&qg3HISUkVgUqr=&y46bgGZhncfqo=&2xZ9HDXV_n_nW=&Dnx3CBUjed_Yl=&h3mRHdWasareq=&VuEEldZ_roXZU=&HRIvlPVXrVhcV=&5ML87YWiYaoVa=&xZJ83cUlaZWZm=&xGIPooXnWogUl=&tWSsrKX__igoo=&SCTpyZZjadjfV=&IHQ6eFZcprqpi=&ad2rSnY_sYmcZ=&DyJSffZfpZibg=&2Nii_QXkWldeq=&VusMW7ZeXn_Zo=&lkWOTnXgWekhe=&_7SojyYoWsZUj=&B4dVA_VnZfriW=&7ROjhJXmhqVqk=&CvyyVwYfnpVls=&IKQUenVXbgiZa=&KmmBsdUipcanV=&OfivVgYaWhlVr=&FUS7fQVndjfhX=&aGcuTCV_ncfqj=&CcBFEZXmnWnUX=&M2UIdLXiZZWpe=&KkYrApUfenmfU=&QriSJVYddqmhd=&NiFkbHZripXah=&yIIfoQYk_Vqjk=&ddkY8vUsUcXVp=&bf7PsBXjmVern=&j3ATISXWkbgsb=&fJSr_RVZZjaad=&pM2o3EXY_YnVi=&PxeoRGXg_qegd=&jKPWqxZfacsrV=&L8MnDcZWnebqi=&SVddfpYUWWoZn=&Yh47RsYcWrWXs=&3RUogzVjloiWk=&PYqjrvYZXqpWa=&OljsqjZfsZamX=&5ej9IgVehshen=&vFs4bLXadXWlg=&sVlFjaXihnrZm=&adboWGVkVkhlh=&d4CkxcVnWfYWb=&StEZ27Xghhjmg=&Bnkcd4VgpUk_X=&MQSrPUXnsmdes=&TyvfQWXkrdUmr=&Xb7tePV_eXokd=&8Ni9LOXodjcUr=&e22SYaZXhgg_e=&ztiljbVsmVskm=&ApLmvIXgmgrdX=&U2gnSUXcmkjml=&zOqeIWUhUeVa_=&shvQ8VVfokhiU=&96t_XOYkgXYil=&fUZAfJXnbXg_X=&2h2D_sW_mYdhn=&ePke2QYaXqofV=&r82AftXaa_aUX=&cZuVvHVYbmZg_=&ftZoyEYmWegae=&7pJAw9Zbnnohm=&KGPZ37Wlsbb_e=&2JrzH6XbYnehj=&ZNTXbeUaabmod=&webV_SZkUagdj=&3eRQdGWnmesis=&slX9qFUZ_mhoc=&5lcBzaXXoobZo=&uaJNRLZbqXbgX=&o7YhbzWcjUneW=&TeaKwuUngqXZX=&KHS7P3UXgnZcq=&9NJn9iXlXWmqZ=&yynnTZVljgh_j=&_mqqrTVrZdZWm=&bPG7uKUmrUWoa=&SxzU2oYWpr_Yq=&xSEvKTVbipmsh=&FVHIQ2VdcY_qb=&wTEhqlXqlssqs=&l6698KYepYdgr=&ShvQHMWelembk=&VLFpXxZloWafY=&BiojO4XWpYW_q=&horWIMXkii_pn=&D6uheQVVjhWoa=&8LPdRaWnnlsdW=&bs8icvZ_bgXno=&4BRi33VblmVdZ=&FvK5fUVfcoi_U=&cIe8Z9YlgbWZc=&eEVwuDXgrhhls=&N3xcacYsfbhYs=&WoPmYFYildmcZ=&asPguUYgdendh=&WeNv4dUccXirl=&_TbjhhZrqUpcf=&FyDkVIYajYjrf=&LuFFAKYebZm_c=&tvUnhbXsgnron=&wJZilkVZonZVZ=&l3_p_4WYkkfUX=&sj96Y2UUhfXiV=&ZDOJlWWhUWkpb=&7VNd3LYY_ackr=&fz5CpZYoj_agW=&uroRgoYbUpgZY=&mu8PnhYiWUaYZ=&GW5WmYYnfmYkf=&l9aPveWWrpkia=&Il8o2KXbZWgr_=&yQD4_sXsoUgUe=&IiRMXbXloWake=&DoMtM_Wgi_nWm=&VQAgGbVdjVfhr=&SuYdeCZcpVsYZ=&LfhBkjWekUlUn=&uXA2pnUokljkh=&ZVu74EXjpaXsg=&lpD9mJXjcondd=&5GV5jFYgUdXam=&5Lf2wlVriqjgs=&QwuSViZeWqknY=&bksBHqYaeUhmX=&h8lAYvYoeeXVp=&i9XpxpVckliZY=&BNK5sXWboWWfW=&j7cR6jVfapnZU=&73vj7yViWjqjk=&rfnNFzZaebsl_=&uFHRvZXhqWXYp=&8hbeTzUWimWUW=&62LcZgWYbpYYj=&D8fh7vWcdngnl=&qpZ4GxWVbpiem=&HJdqAVYpgjjlZ=&2VNwvDXsm__ad=&GzrhItUimVbjs=&NC9BFxXohf_mm=&RWpNzfVVfehss=&fGTicSWs_bhXo=&QVsyo9UYocige=&g2H57tYpZshUl=&TZ8YrmZcerXUo=&UAVGg_XecVZdY=&QpFVWdV_WVYhm=&GgnZztYqbhlYk=&SGERtnZlYffgU=&PuA_Z2Ycslasj=&ZrjWjOWZsmoZl=&ErgtrPZWjqpio=&SG7kOWZsbodVb=&rDsR7KZiqmVma=&jLBxtsZYclihX=&p4aqvmZbVkjia=&MXLQn9Zcijbmj=&3ZovMfW_fWb_W=&edcF8GUgepVUg=&vS3p9YXhmfbql=&g8NmYKYWmsjrh=&CJs6DAYsaWYqi=&qo9pb2ZgmrWlf=&OT42qUYU_glaZ=&tMvw7RUjsVYsa=&Hk4DRWXUojbgo=&wlWNBVWmshZbm=&mutCNcUYhnjjp=&3ndGfjUYXmUff=&hbq_9IYnpocsV=&BnPhI8V_pjbjX=&_FyXXGUedgdlj=&2lC2eOXnVksZ_=&LZ4OR7Y_khqUo=&Gwp62XXnVdkjY=&gsrcOyXp_ljUq=&6phl9zUe_bppl=&uZhbtoYa_okkl=&i7JDi2ViVaVre=&gCJSjoZmibYaX=&n37nZeXkWo_Vc=&jXKwHkUklnnpq=&mEvG3WYoVnZid=&bAtCjaWXfr_Ub=&dvxgrhYUZhaic=&cGAbmjYqcfonV=&Y2Mb8ZZjVWkVf=&s3uvnCXVZh_jg=&OENUawZraplem=&SI2PgNWqXhUfp=&eTNfpmWWbXbXj=&ravbvKXpXjUhg=&wZ7TTJWZjrXor=&kOArBBZldrYYo=&7M472VXbffskY=&4OS3yBVXUmnoY=&pNm5yYYmogirU=&pw9cNiWeWgZeo=&9rUup9ZsidXUm=&YPIe3DWjm_oUi=&gTDVXRWbr_neb=&afXyK9Zml_Wb_=&uJoos3YVpnapY=&3b4a9aZodjms_=&PUt3HgZckmfeg=&od3_LPXVqdVic=&QxZft6YoclVZr=&n8q7XgXcVbUhc=&7CguBWWcqsfar=&wuHRr4ZosXU_h=&YDtY6iWraiqVe=&WNZKr5Yogsqi_=&yJlHvLZli_lha=&Omh6GOXlc_qer=&hXLWGBZkocYWs=&sHWiH4Yfnkqgm=&p8hmA_Zbahpbf=&wrWWPeWsbpnek=&QDjif7Z_UYeWX=&p9RJzNUnoUbnZ=&DGRbOoVkgpidf=&cEzfQ9VUX_rVZ=&bMOT_bVhpYsnc=&iCYUv8U_aahdX=&4sNcymXpX_ahh=&4cSUEHYZemZZW=&tM8pyJYaXjjmY=&no7v6QVb_oj_f=&yXtqr_WqU_ijh=&yGJw6sWZZhoYm=&ovftiUWknelUo=&UtvF5yYgYnsVs=&i8F6CvVskmZYj=&2RleUoVhhUhmq=&K8MQSXWWrW_oe=&VWYQo_ZpbaaaX=&ckDdetYYdjgiY=&bXl3DTYgfcmns=&WyiyAQUebcifj=&kHa8XMYdcZpcX=&XzIuatYWYVocj=&Jxi_ZFZVrmngZ=&4MUl4kZXhfkhZ=&vsoKgcWbXkfZa=&5pbSFBWnYbjrj=&j8hYMsXenYdpc=&9HTU2OWpnZmhg=&zxnj44ZrsZhhs=&53cF69UlcnYnU=&MvMJf_WhZkqXb=&2iynaJWkXmsin=&aezunIWcVeaUc=&aMRIfcWkargme=&NKRIgDVfknqYf=&onZvPXZdn_geV=&JP3qzDXihZoVr=&ybOFfjVhkpXkh=&xjpiq4YkoXppc=&H2BWYFYacUXnV=&knUoS3Xebijcd=&M5BatgWoen_Yo=&Y6CnL7UZgbVYp=&rB_ujrZ_emrad=&3xy2bGZZjeUsV=&DTv2XvXlq_lic=&vw42ZKXrslXej=&3JZrmLYpodYWr=&k8xZL8ZYWbZch=&hffaQmYZVVoij=&AzNOVIWY_drie=&PYkPInUkrbdfU=&w7svFaYehihli=&EEuTa4UUjhYVg=&ICNi9sWnjZfXb=&Jjc8XDZe_qhsc=&oJv3LPWWqeprl=&75PzasZqejsnk=&ENqsVOY_WnUci=&QENH_RYfdnqUV=&8agahEZYUmrba=&mgBvPQUVkpnrs=&OXelIXXqqcrpb=&IV3Ae3VnUYfha=&ApCozjVlgUhWX=&FhuyxHV_hcmel=&xMsHXJUkZVnjd=&Pt5VGTXemdbdr=&uhYIySWgZgWZW=&Xh2nsGV_VfaZl=&DhgHQIVWdfliW=&j5uxh3Ypmmmsp=&E4d4K_VXn_Uep=&TnvSy2UaZoUqg=&kCqWOiZVdXapq=&qQ4KZJUndcpaj=&kiCLiDUeXljVl=&UC7Gl5YWsbjlp=&SnZaRIZmUrYfp=&Y8VVbtVhXodXh=&a_FkBLXfsbgUr=&WErrR8WUbdkkn=&6vKzvAZsbfWjd=&ANTWAYVdiblnk=&JD7wL7Ylcf_Xn=&GVr6P_VqsohWb=&saeMEsYffoWnk=&vTFiCQXpneXUU=&9iGNDEW_Vobrc=&ZDixKlUfWga_s=&GpgAfhUgpY_je=&HzXqktZW_ikkU=&jHeplMWdVqqfa=&E98qqBVWc_Ugg=&wAaHE2XYneXaY=&QjeNNnZoqndWa=&5KMhrqVdpfXi_=&fjuJTZXooonnp=&sJT3oSYmqaZpn=&v5jA2tWronbhr=&DKHuoiXsgeepl=&kjTimBUVldZqs=&GzkIgDY_WdoZf=&_HeJyDZesbXXm=&uccgaHWqkrknW=&NeMZ4gWkkZbse=&RgVpROYbVeZlp=&jiI9ETZUjZfeb=&PvukXmWUnsXVl=&KCEbPOYca_j_k=&KyEUArZleaqio=&uTIyhkXgkghcr=&rBZrNCZhbWhhZ=&5olYY6YeZmfja=&ag74IwZnjVlpo=&5wLsMMUeokVle=&MCFTXPXojdZlY=&6SoG78ZgbanZh=&4NjisxYbUmZkj=&2NaPGZWeiXrnq=&gxmzPAXienfZW=&zhpqIQYfYWZfh=&SRcwohWWme_ji=&JP3WKhUpXUsrX=&XNSdO6ZfqZYfj=&DnUWjkYcanpao=&bpDJfhXfmomeX=&syFSLKXagsYYa=&Ri66XoVjkYUdY=&yPlhAkWoknWZU=&Dj49ZyWZadomh=&oFrXbSWsUX_pX=&pCS2baVo_fofb=&ZbfqNUVXoUjas=&KLnPw3XidYrZg=&xoTvmKX_oilhn=&oAqXpVUWqcZZm=&AlI3X_Vrindob=&29KifKZrXahXU=&tuoBF3W__gqqk=&WbR4HzVgcdVYn=&EcKXpqV_WXnWY=&yoU_RcUXnhsla=&dHp2zMXjYig_m=&7VtSOKUmmnWcY=&gCLEvKZWmfojU=&uZZ6pNXgorokg=&xorkK8Uj_UhVp=&EhgrORXcrlqml=&E77UHaXhfqpsa=&kYstDdYfn_U_q=&LDfwTQWqUpd_p=&vzSHsQXnokYZd=&diPDhPVsn_Zp_=&7nsgSmYUYeUhZ=&lc7Rg9VXmffWj=&_PyyaSZsiVsgW=&o6kBMeYqhashV=&5zr677Xonhbpb=&j3MRRtYigqabe=&J9w_CFUfjisVg=&kQWcwGYcdWi_o=&Q3hhfiWXqU_jo=&3CGzseYqsmVlW=&hCCnVJUncfbbp=&lTEbGGUgjqkdq=&U8u3CPYmmYWpa=&5ppQ8ZXccmsnh=&4vT63bUnWkenc=&bKNolfZYgndVV=&ZC7pJmYsnepgg=&jDeYaKXjgqqb_=&Y9yzOzUmhnpbV=&r2r_PIZqaVggl=&fZDpiXUnUWdUU=&2rKtZcZr_cWrc=&S7rzXoZdesdVg=&4l6md9X_fjmrn=&TsvJ6IYmgpXgl=&ciyLGrZjsYfbp=&VSClaXVeaeUWl=&qOedRMVahfqZd=&stOigdYWi_klg=&92bFM2WkYrXar=&yod3x7ZdXjssZ=&k9JETgZanqrXf=&P83DKSYigedfk=&QizrTkWUlcnem=&3CxtTiWmgm_aY=&S_5ybuZeZdUmj=&seHZvrVdlZghW=&iP6FAUV_gVYos=&7cvm3XXgaebUh=&EoFyunXYpnbkX=&LnIeUZZfdjfV_=&PU2OsWVpXZrkU=&AIH2wwVbpgqWU=&kmGBAvUaYnjcf=&vOJSiuYoqsohY=&D9keEOZflpmWm=&qKnKouYooes_o=&_HhBszWpmVVUe=&fu9V6nZjXUYgY=&sAFApoUdmiqie=&jdoMLQZhleleW=&i36GjoY_lieZr=&YCEcn5Z_UVpsr=&V6xUaPWjaYhbk=&id7dKKXesp_bo=&kf4CklZbXZoXX=&IqJDAqUWVndik=&Nq5fPcUfknYok=&FkGA3oWddhUYj=&zBk2FqYZYnlnl=&upnxAkYcnajok=&ZoZL4cWbnlpoX=&hoZR_QUibYaqf=&RAkmaUWn_ipbr=&GU2iy2WbYhcp_=&yf7U2GZk_kbZo=&NrSe7rYlsqWUZ=&fccBmnWdiXbqb=&5DQrUHUbVWf_d=&JxvZjrUi_Xdeb=&FwaWoDXfogq_j=&CyIUNHYUgpend=&jdVP4TWemljeV=&PIUWW5Xkh_lZk=&7lPovtWanlUVU=&lFT_SeWkWrcVs=&dU_YmPVkWrkan=&erakkyXepUpab=&BRRrJIYeilVce=&bys6rPYopgZhm=&X4GIiwVZg_dki=&UJAbN7Wsnld_n=&DDNAW3YkiUXp_=&vhiKIuVpn_dVW=&Kx7JGFZsnirXs=&WvHQQFXisVcnV=&TzTeD7YlrZfpi=&gZQxITUrdWpWV=&AVefBYVaesrYg=&aDv5RIZaWYYjm=&WXR7ZnZompnsq=&RGYfydWkgfjo_=&oHChJtZcg_epn=&KyabqgUmcbhWe=&fPE_BxXbfpkda=&cX6XucXYqgYjg=&jzDlnRYVXfo_q=&SdH6B6YjnkVbg=&9jMzFxZbXpesX=&65jy7bVUhVoiZ=&B_FEhtXXgUcdq=&hyegKFWYodfYr=&NwCXRuX_oqZfp=&J2kVKUUoaVYiV=&ORntZvUdmboUi=&syHj5JVesYs_X=&dcNnUeUmUlXee=&UmYDfcW_ZgVpi=&dNjY8YZogfesV=&gSgNzeVsnqZXV=&o52BGYWhgYpmb=&iJ5OrRVa_nZcX=&FeyXd3XWbVcWn=&Gut5WsUbbW_ck=&9I_mLXWjmfhqY=&oZfGoMZaqVqji=&3bAZ2dUmncU_k=&Ykpl5xZboW_so=&f4jA2hWUnbsXl=&aZPooyYeYkfaU=&WNWKoeYp_qbhj=&aWpuQBVoVZZfo=&GgQOwMYfaelob=&AzEEjjVZlleYk=&mtluRLUWjXfq_=&X93gpmZ__naji=&M3o4IiWckbfdf=&uCxw6YUbhZhUV=&RB7jMFVg_mVsr=&tsI4rYZ_Uqnfd=&RqlZqBUhlmUqh=&afv2eEWmUnYpa=&NMOcpfUqeclYj=&mJImBKYfdXqZn=&LpHxD7Wo_jilg=&yJLCi8ZpnXnsV=&PyrQl5UXhfcqZ=&7RBI_WXkq_mem=&3DgbTpXkhUoWj=&smpGvvVeXqpfi=&WZg_64ZgUjddU=&Jdm8jNYrfWWcY=&8lQQQCYcnaUjr=&_8C2lhZqmpZqo=&A8gdHpZcahpsi=&E9MRFNXUomlnX=&OCptohYajhaeU=&mCO5SSUVasaem=&ZfxyIjVoe_Vhm=&OlWFF6UkbdWkb=&QlTktxVcXaWkZ=&pUFSwEUekXVUV=&MLZ8CSWjpbZ_q=&88UYdrWZme_Ya=&ayAlZyXhndZfn=&fIb7FwVdrZobl=&Ml87HfXdYhjqX=&kv3jZdUcipWae=&QWkZLlXqrrZdr=&Qropy7UgnV_dY=&6v3xeLW_obnVi=&MnXIHSWnaVhUp=&WDWiqaZfVdbop=&R7xfGmVfZiphj=&Z8JeMXWope_Xd=&rCfU3MVrqkVoc=&Gnk7tuUWlimbb=&TAv_DVU_gfWnb=&MKbcFpVqmmksf=&h567WOYsWWZYY=&gC7RxAXjUaXqq=&VURuLNUmfkomY=&yEtK35Yibcl_c=&OwLid5YX_ehjW=&UB_S4oZXpsjkX=&TXgP5PWgrWqdj=&mG4TN_ZUjUjlm=&uJIdqMZVnbicp=&uui9jpYrpeYpU=&9zDwwIWWbYXih=&RW3a5uWYYaVfg=&ahmIfyZbXUXli=&7rPnCbZaZgfWW=&dkHdu3XbXqsal=&O5UZUPXXcfsgW=&VYZ_sZYdWhmg_=&CwPTxxYjjaecX=&LyOmIZXXolUpn=&PyNdyyXbbaYqZ=&bMn7fxUUXsqnX=&2m4rpfXaoarse=&Zpt9jhZkVW__e=&Ab7OEuWfoYaoj=&SFMDbBUsdskqW=&QkorAdWqXahZo=&tUvx5JVkcZiod=&bGd8ojWckjrZa=&HWtE_GUVonajk=&EGKauMZsqcoY_=&nShx8wUkkqnok=&ZMcQaYWdeZrhk=&II3VPNYdkbpkX=&AF5o_kYoWsjiV=&hrcNbnZbeXiZg=&rUAKfXYcrX_fp=&9GOeLYZfqiZXm=&gTYfH9WX_nllU=&6w79QNUWlgkVb=&AC7CIHYYlbojX=&nrTxrUZXfYqdi=&hKFD9JZXnkehj=&ENkhf6XikXrjf=&dgfGjLV_nWZme=&lRhlAXYZahnmb=&Ats9g3ZjhrqW_=&MRHj6mUfZisZ_=&KSnIdIVcbhher=&hhBUe3ZeYsWaj=&92dUrwXZapckb=&Dng8BuUjhaols=&nHOigKYjcZUns=&yZ9QR7Ul_jUkp=&savlWhWcsgWld=&wfibkCZieesWm=&wSIPZKUh_Xsah=&cYh6UcWdrrebV=&U3kHQcUdXlplf=&cIcnKkYqcifnq=&t3AVr2ZXiWVcg=&WttoLQZUWYrmo=&mR_adWXoffpoj=&7TBwbkYihqWkb=&dzTgPjWephWam=&vbNJe9VlVdZgg=&H_3UoEYYXVimk=&rCgXc_YYibjpW=&mf66IvZcselcr=&8ZYY9tZmcdhhk=&DeZuDwXoebUck=&ww5nBNXfZrqeY=&ejRYlhZlqW_id=&HXGUw5VaikVVc=&ESTIXKUlUjliY=&r4AaSdZXqnXjZ=&n49e7FUVnjjhV=&tSqVHKVknskYi=&6xDVKBUcmgeiq=&NhqSlNYdWlrms=&SZ5MJ2Vln_gij=&tdIZMKVqrpfeq=&LdkzIfXcfk_ap=&QS6QOCVZsZgra=&O8FiOfWcjmbis=&cLS6k6XXapWqZ=&t29ipOUUWdZe_=&cA_Yf7UanVUVX=&iK2MIiVfmfhVn=&ygjD2oW_XjoXb=&NLNNTUYhbUqZd=&h5tBVzWqYXkrY=&E64uwfXfrhrmZ=&tsfZlFZgecojm=&OB3cF_ZVUWVfd=&CRRgPjXWfZUcY=&f5tp9rWrihshm=&a6kU98XlWggUj=&GzsOK2UZbUpnf=&3bI3BLUsUiqXV=&mWweIsZfVVljf=&V9q5hrZq_qWda=&jnCfvjZccicXY=&g3bRyfXWlsdpU=&m2R2byWfjUWmf=&V8to_BYXjXVUf=&Wedg43Waikbqe=&QKVvJQXmclcdZ=&xILfmtZalgoml=&QD3mV6YfiWmsh=&opySisUVlmXaj=&9FeJOGXclnkhn=&lzwXTZUsmrrnn=&KJ9kjGVajUrZf=&lUvsi7ZjYZlYl=&r3ypVMXpYUqnZ=&OKE2_eZejadsZ=&BU7NytVYZa_cm=&vKmzolXeji_pV=&yj9KsDYppkqYh=&yotbwqYradYgb=&7qv_9kWaclldZ=&Xq8eLkUaZhVWZ=&KelNbaWmV_Uba=&q4O6nBUZsooYc=&EKfGGfXddXlma=&FxD8pVV_XqZdr=&6DUHBBVippnnn=&H_7iBkUanfofg=&JaxKszWdmVpfW=&zUOih2Yigsnah=&LGJet4ZnphUX_=&ysPyuoYZbXlhj=&Vd5XXbUqXWXbZ=&JJ_cNdZnkVWkg=&9kRkyZUhmpWch=&QflaFtVgbrbYj=&NPOhQQXpjUn_i=&GRSUkvYnkinne=&WVd76EVadcppe=&h7dVpVVdjimbc=&MBEBeZYnojqjj=&SgEbgVVWoljUc=&uIeHKIZeXdmng=&jOVwcjXnqhVXV=&assSkCXlXhUYl=&_QntoPW_n_cjs=&GcvNfUUcelqqr=&GZToNbV_fodZd=&qpmz2rZiopiXe=&6uyvjkVYbYUkg=&d55AaMXqqmUcf=&N7NlByXleakli=&yS8EGeUdefgqY=&zn6TwKYiVUgck=&4LmOFNZejYWfe=&fRkZR9WsiZoga=&mU7pstUsaZpps=&KIG3ihXpknZei=&hebPZ7ZdmZhZk=&6_RbYHXcUheql=&nIEL9SXsikXUp=&AlqPtrWhVWsbc=&UZCZ2tU_qkWqV=&fSlJd9YX_dYfk=&gqUmY_YfnWXdd=&8wbalnVjspcem=&jbJlX4YlXrrYd=&dTS2OmZksdnpk=&vrJ3f4Wqdbiqm=&Llm3brXcbrbpY=&nbytjZWXqjeUc=&jOAmE7Wso_jpo=&_9q_AAZrbpZes=&U9MGFpWUoWZZh=&J3A36nYmfhY_i=&reAUZkUjcYbfa=&3rXUh7ZYfdlUk=&JVqbeHVmdqeZs=&_skVcVVjinjlg=&egT8izZVcoqbj=&WaMqZBVkhgUZi=&27tJsGUfdganj=&xcyFIPUlkkmcf=&8gGQDeXUjVlgX=&I9NNFuVd_em__=&4ouOEKZsbeeUa=&hG8FFCXdidfjo=&Udv_7DYcVqsgX=&tcllOCYlkgjeg=&I3xUx2WrgUkrk=&ulEptWZ_fnroi=&iUwqSIXfWZVYj=&CwHVfJXpsgqWr=&Z_jzmBUmdaoak=&bh7CGkYhdr_ao=&CxDaRsWipqYip=&9pwVICXWYasUs=&YgaP9QUrhdXVf=&aTNQpFYrYWnra=&MDQLvFX_Uidl_=&3aiSrXVsscpZo=&SQ96HqYXkWqph=&ZlLpGRV_qfaWo=&Wa4RlWWfsVoeU=&YScOB2YhcZZfb=&TeaGzCWgpcglb=&KLAv98WiXmir_=&3Dr52xXiqs_go=&5bFvNsVmlgsrm=&hLvR4PVUrWbia=&FLAeBsV_Zfooj=&q3MCKSZnYYahU=&UwQZaxVVZqdWf=&MrSj7TVfVoscl=&B8exDXVgjdqeV=&E3l9xRZWgfUaW=&ktFy4HZhgdYgc=&KOv9wWVjrhgae=&Olmga2YXbfkic=&X4IF9nVq_gakU=&2y8ryzX_fggro=&Sq3ZuGUUsaYgm=&KGyAeLUddXpnf=&8MlG3CZZihgdV=&sgrPoiZZpWcpZ=&t7D9oRWskikfj=&xQTu6DVZbopdg=&8yXcvwXifsjmh=&ZinPI2Yhgcdfa=&Lx6ttiWhnbZ_c=&OLWNmBUXVk_ok=&gIayMeVXpXfrb=&g5ldjpVV_VsWa=&EIltxpYb__imk=&zcIKyxVscnUcZ=&YfZ_hkZpXhbgZ=&5hxBdPUqmmgXp=&wdEuTZYroiiZa=&ogQ6ZMVgWbZnZ=&OhEQNYVrsanio=&JQb2B2VZrpr_p=&6_SmIcYfpZUib=&4A6NynY__cWip=&93sTWfVpmYrUm=&VRLD2XWb_qsqo=&FyrWtBXbWdobj=&VtEqn_UXU_glg=&L_WcDiZbpelgV=&qrIrWXXpnWagl=&ioLKNIUfnqkkn=&ulyBaUWlhfbVU=&QI7RuPXeYjagl=&_NBPNMYXbVggi=&6Im2REXgrjqlg=&YdwmokYnVqWcs=&aMsbBWVXq_niU=&A5XcviUccqrYo=&f_rjfRZgsjerh=&FtWYHbZfinUkk=&sSuLz6U_bWbWa=&2VfDY_VmqecoY=&SNZxJVWkomWga=&lLrs8kZWdXXls=&Wi9qKhYqgqqeW=&mZWxdFZhVZVpV=&oAf6pLYbqhVnp=&WaIjxDUof_bbd=&f8UOKAWapdZjj=&QN6VPxWhUaYkn=&Kf65kBUoUkXeh=&ZJRMBCZlqsnnZ=&EmX3fDXkjUpir=&4wRIBVVjkrkph=&DAxKefVbYdbhh=&KJX_54Ufirio_=&y_2KPwYmgkUfi=&kHVfHfWjYjlb_=&KEevq4YpaqZcX=&9_8iFRVdVjkoc=&YSTEdsZg_madr=&vzaQj3WZXjbU_=&EgVBsLUXnikWk=&kmKcZZUkVrUZk=&3kjsoHZqmhfWW=&SXv2szWVclbai=&Z_EepoXdjojns=&7uwcH3UWVqsmf=&RNkkKxXWqmXgm=&ZOFHKoXdrdZf_=&OmEeFRXXmZgmW=&j9qLmUWcpjsZY=&zdNcqbUhepWbs=&bUkXDKYjWZ_mc=&ZUDPkdUUmnqhr=&9xo2SUVcfoVmk=&ICbKXwUU_ZVmn=&d_uxdkYdqkUZi=&wo8h3dXcajkUq=&HWQS5gVjcZZbp=&8txRRzZfhZXqo=&CMFDTJYVVWpdj=&83kOnGYoqZWe_=&WmaEl3UVrcsrl=&Wru_QGYf_V_sm=&eJnRp8Xbbmloc=&sdCBkdUsds_Wh=&gcNNAzYic_arl=&bAJskfWZsYrcW=&OR3wwWViZUijp=&aaWAhzUrbiWkn=&2p6C7SUXheXir=&7z2smBZoiqsgd=&m39KTCUsopYls=&PKHS9ZWZcqjW_=&_4_9i9Uqboalm=&DC2DsvUXqZWjm=&JAYwWjVXpqYYe=&emW92ZUUbcUnf=&vwEeIFZeXigiV=&bV8TDPVpXfZmq=&gErTMaVq_VlaU=&ffV8g4WhZdYgr=&ejBVNzWWnmemf=&rDLhrBVidehgk=&ndGfTpXWXomk_=&VDbrShXVWkZch=&rvKOGGZgWcn_l=&uwW3aGYpckenf=&wUQ4eMYgogspf=&QPfRtgWWY_kZm=&ciTmjzX_no_qc=&32bMpTVrgiZs_=&EymBQwVjgiVdm=&m4NocbVi_hfXo=&aBdTTFZbVhjhU=&YeSIexXkjU_es=&O5YRbOYUWjjmX=&_SKfZOXbbprgk=&ErOJzrXZmZpZs=&sZz5iHWYWhssn=&QBbtgpWrYjlqW=&en8MTGYebZodd=&2Rdbd8W_dsso_=&596IKGWYadZWo=&twtxYDUa_lYUa=&RZAUwqZXfmbeX=&vc4nIEWZUgsgf=&C37KQmUrZrlVY=&vxKOBoUYkeonj=&tkRnOTZXrciqi=&uqqb7MUe_fdqa=&mJszsiWjhbUYe=&DA6wRwXpUbYhq=&Tx9oH2Ybrlprc=&Eep5eUXsmifUU=&gJ5FagZYmXm_p=&KfcrLVXVgXXns=&E36HtwWZVXqZk=&z2i75rUoWjdbh=&TJtWnAXoVnjmX=&BLa5oHWmpsnnj=&dbfArCZisiXXi=&Hp9PMTVXbeflk=&aRC8WEZpsiirc=&mzGc3_Xlkogoo=&htBEUHXoVaYkp=&N3JN7oV_qicha=&dwe36SXgXicaV=&cMMZiSZeVibVm=&Zie3pIYfigZYZ=&aGuGZ4VedmlbZ=&lznE4BYWarYil=&2dXDf_WknbqYa=&Q874WZZkdacs_=&WutEJUWsgWgWp=&OFrl3zXfjhemf=&OihF5MYZmlfko=&Z84pI8ZlrshkY=&TiXZo6Un_Wadl=&nhqHVqZfarjng=&EIau6gZsbnVse=&vhUpjXVmoa_WV=&a_RpXOUYeVXXb=&bGLXjLYofapiW=&KbE9EbXlakU_j=&WwzLSnUYg_dpo=&gg7er6W_prg_n=&5fCD_DYeZanrh=&DqewaRVjZbimj=&TfstwZWbeqjro=&r3rNh9YpVssXa=&H248u4XdZb_c_=&YN252CXmj_Xrg=&NJVQ7HWlkoZbc=&OM5jmkVsanegW=&hUleIKWaYcbfZ=&dEL_s8WVfbjlp=&PG67rUXlYiZqp=&Mi9IAPUZYmoVU=&2TYZX9YnqXkap=&wRSrA2We_XoYV=&CgxYqKXegXapf=&p7XkGAZYnampc=&2sVK79VYmrlkY=&97QEyxVlihemh=&GLENOAXdgVfYh=&yOf3r7VsYYbhe=&loNIm9WrXbka_=&8jcg6XXWpeqnc=&cpQHyBWlcrgdh=&Y5Sg_yXZ_lgdp=&6ec5DqUensUoW=&EYnSIMZkkdsdr=&z55U38VqWmZrc=&9zViufXbgbmri=&n7VWDPYUZWjml=&Dood8nUdsalkl=&3JQBuTUniVclp=&rGY_flUqYhbfj=&KYNYpjZbodeej=&u5EEbUUXpZnkW=&sUI3RGXdmUUga=&NSiHXTYYdlafg=&aC2ByHZ_snhqd=&ImuXHBZXfspoe=&ucCQ7SU_k_Usn=&68vp3ZVaodVnU=&8HTAYCY_fklff=&Jai2ZjZZgeYkZ=&yJAc_kUohUeXs=&vEf6GqYpbcmiW=&SenMtnVUhkbbg=&KwgKLEYaVlqrb=&Pz3iAbVnkkjnW=&NIen5QXbgbdrm=&VFRGEtZejdc_o=&iZTMucZWhjdiV=&OH8uioUVlZpdY=&DVkjvMYfZlclj=&VG7P7kYmesbUm=&fbSoxMYdolXZq=&JumRbtYbakhX_=&MG9YfmWokbfsW=&tEG7RMZkpmkYr=&6SnjK6WlXWcYh=&EiYM7hUenkgnW=&9ZHSG3Ujkf_nq=&qfTkNZYX_kfri=&Ce7UvNVbqUodW=&az2EURVocaYXY=&8nSRQ7WsfqnYg=&fyPzULZhqXYeo=&znPg_xVjXjmbY=&uxsf7yZYhahUW=&kLM98cUcVjXie=&SdmXFPUjYnmfc=&aPvSKeXrkWlXr=&ncUIMSYqdXhfs=&Uk8Td5Vahabon=&zsF_dkUXsbnja=&LsM__LVaZjYnp=&ZDA3yWUdYkVml=&h_yFJVUnkomWq=&4Mh3I7VhdqUsi=&vgxbuzZskVaUr=&4OwVemYrlhnkn=&mDA9jpZpdhXpa=&mLl_xJYqdldic=&MejQzUYlUahkV=&bm4N2EXWdsZms=&QVMzYqUrhhkka=&2Xj3rUXnVjssV=&oPZ5UWWmbdhhp=&exvsZMVrieegW=&ONGbfUWeoYkfV=&CABzmVXXbVWaW=&oSVoAbWnq_isg=&CVA_MhWoWodrd=&SJbqpKUnZg_pr=&vIwybDX_dWnZW=&yrrsHGZdgaadZ=&wXprsxUemdWWi=&JzNnbeUmegVdU=&oS6r2NUikYjUc=&BWwMrCYWaodjh=&fl7di6WXXsZea=&RptgLcUj_da_Z=&ORTfr6XZdYcqX=&mC9gK2ZaelXje=&tjkTgMVcUZaWg=&fVtCLrWjbVnaY=&DERQzdZmompZ_=&9RVyxzXnlnfmW=&njYhEqVkjkYiW=&qEJDWPXcienpj=&8C9WBTUpUjfdc=&OBhFCQVcp_oqW=&RznSJxZXU_bgb=&pLb5BdYWYdbhZ=&M3txZVWmmmWXW=&2iTBrzXghVZhr=&hhcflAYmflsYr=&tZAif9YZidWhh=&649SbSUpfYdmZ=&GJaQzzWq_ksjj=&tMj7K4XnYfmXW=&g5VpefWdVrsWp=&7UkbMdZcedpnl=&4smfBwXaiffip=&GiAloPYdjgjdj=&DRdxBoUcUlUqj=&WeByp3Viq__jn=&yIpASpVYfbZUr=&_upEvhVbedkri=&ViWszHVkajlfo=&NVSClgUZsskpW=&z4AAL_VWkgpma=&XJEDEpVUZUrca=&zWpjAOWmcZdrZ=&cmKwJ6Vpfjjqa=&Jra_EJWUo_qln=&qaK9Q8UUksfcd=&IA_jYbZiZjYfr=&wd7aPTYojakcZ=&V9qsBvWYiWjmf=&NQNGLdYsnsYk_=&oKHGacUrrijfg=&u7knBNZaYiXpZ=&HJnpujYbcZcbr=&l5iqFtZbfkili=&zQvXxXYefnobZ=&uSrXgnXmXVane=&x8SW9bVaonhdm=&vg2_PKVeZrgZm=&CXNEXuUhfojbW=&NlcAJsXpgasge=&Sw7tWdVbebrgf=&bK8q5QVfsrdps=&xDWXW6Uhendig=&ydFmQmVZ_jYki=&DqV7H9XkYY_fs=&evNmi6UcsjnkY=&cyZ4r_WXbqreZ=&OzhNstYlsckjn=&WOvVCIVbgnbqZ=&2aHvrXUiqrYUn=&Wr5fSzXVpl_oW=&LhfrPIYXojljs=&TJOD9vXWVsgqh=&6HXKi7WaYUjcl=&dHwsjgVoUfUZf=&lmiVhCVqdpXas=&TAxgy7ZgeZgjY=&UYeE_CZlZkffe=&B6jtiHVlealYV=&STMfTkXqcheei=&6NFfTbXeodbVV=&DS9WgmYfnWYhr=&sN2mq3ZcZbege=&fMrvOUVkU_jgg=&E8AtBEZgrZkcp=&ckaqPSUijXand=&B2pHRzUVqZj_i=&6hxsoLXiZrYeY=&Q79aRsYZVnmla=&cafb6PZasfUbU=&IhhcXwWamlelc=&zHntYNZgWUrYU=&JwDNdNXmVqoZV=&hTtlnQVgZVWpg=&VgY9DJZYb__Xf=&YfC3okWeffhrk=&n_qv5WZlXpkiZ=&R6pINVYhbXXkW=&GuSCHBWaXidXa=&QbBQIZYhlqrVc=&jd6mi8ZcciXeV=&KJ_qDMUZkVgol=&LKsHYqXohnefd=&axQxiqWnhVdVW=&mPfn3TYkgngXp=&SlNNkOWZbsmqo=&qqfaPhXhpYUVg=&xWsID4VreboZc=&cu49aRUVYcksU=&FJZh_nZhjhhdc=&vnyHKxVpreUjp=&eNxnjoZokqgUg=&3BtnXrX_gimng=&FPOQfTXsoohls=&lyHLaeYsbhg_g=&dCZ6hZZUrpshU=&hszXz_VlVgqa_=&YSApxwYjWijrm=&ylQEMwUYqaoo_=&OcSv_uY_qgWnZ=&eox3g4ZmnalpV=&yrCTKYUVrpqff=&Jt2JevViqpWck=&2quztWYbdYpXg=&4PrZTkXge_skV=&SlaajcXemesa_=&zkhk3ZVenVprn=&H25HHlVUfodba=&E9hei8WZYnlgm=&QjXrADYmrXdY_=&MiNaR8Xqkddkh=&zPxpV6Vpencck=&IurkjIY_nUa_i=&hQ2CznVUhibsY=&GKVzitZbsfdae=&KiuCNPZmgbWZY=&rDrMraWWXjZao=&YmxLUVVUkVfah=&tKWJ9DXaVeeoq=&y6OOFiYpldslb=&pcykDrVrggi__=&gzr4fuXgfZrp_=&pf2YklXVmoZUs=&ShMNDNUjkeb_f=&yVOudmXnfccZp=&q54VWUXn_WdW_=&_4I_YyUXWpall=&ZhRrpSYXcqere=&WYoiaUX_rphZa=&ynZK4jXkWYoYU=&4H3Oa2XdaZUXc=&8unORXWpahasp=&XVkN6RZYiXrqd=&QphHD3XgoraVo=&ysTNoxVpmYbXs=&ydvukQYnYmdWf=&4hKsFjVlcg_j_=&I5qvRhVXZlkkU=&xhiKraY_lpWsa=&vUhkMpXdZbmag=&PoyxBHXYsgrfg=&jSagPKZbqoUZo=&MrenYfZUmnVUp=&sL3DlSXXZkbYs=&82_9V9WochVqi=&sSRYOVYfVYgYj=&wIknyXXoiqhhm=&3iw3JLWq_Zrar=&UYyxMwZpVZ_km=&zOklX6XXUVYWm=&Ue8HksXbbom_k=&nqdWGPZnjYUoV=&vfTfQdUmrhYgk=&k3o3OLXqZXsbi=&yP5cb7VhqnXkV=&TmxzJtZindZ_i=&dG3MdVWpZpqip=&WM5ruQZso_bjZ=&_f4yapYfUscqn=&qD_kemWY_jjae=&AJLFW3Yli_Xfp=&gk4xyrWmoblqi=&xx8dWlZsZregn=&ZJRqiwZfmaYqo=&7msiW3UnYgYbr=&sZmV3vUgXZass=&5vuXfCXWqoWde=&Ot_tlxWlifXhb=&gAXGOFYWXWai_=&joKzcyV_pqdcm=&pxqD8tXlsbare=&tpWVuVUacabUs=&2iFG2pVZUXslp=&tqIZeEWhfYsaZ=&B9mr5uVbVmdsh=&urntFxWcjemhq=&HKvYsAYkcYWba=&XewUEXYUngYVj=&ST2m5XWai_Zml=&T4_FtsZcVnWZd=&g7ckbpViegspr=&Do9MnIUsUcsUb=&jmzQ9bXmojVkb=&yn4oiUViYgjfs=&4ufnwcWbZmqrn=&USgtagWo_ipXU=&PqLERIXis_ZkY=&2Min5gWVgfhWY=&9geDDYWdoVicj=&hl2BAvZbUrelo=&MKeGTdUiVcioq=&VEO4VPXqo_pno=&8kPybPVZqn_ek=&qDnWLzUVVjYff=&7lfuDQZdnUVjp=&jQ_CmCZfqYWph=&8xnhWIYWWqahe=&GjjgGwUnYWXpY=&86mOfcYrhdUaX=&zhTd5tUVnraXs=&zGVmNwWjaqVZn=&6H_UxqXZi_VUr=&LuPykGXhkaUoh=&niccjYXYpkjqg=&OpkgTyWrkVemj=&GhPbSJWWhqbhs=&OintKpWgbjsmq=&HVqsVCXeZYhoj=&nfCEfEWUXbUkq=&OLH3RHXbnlpiY=&oPRFnwWhasqbl=&KKRfnCXomWUds=&FvAftcWonW_jj=&c4CfzTUUlkece=&cICBUTZgbbeqW=&Vzts8IXoiglXo=>LwQ4Vrkbhaa=&sI4zcZYmpkdaY=&gQOFZeWpmVcZ_=&MSArbsWqfgXlq=&QTjEbaVZpVdYV=&KbJNHNZoVcZkn=&vVJv7DZsoYXrp=&C_9WBmYfobhsj=&hRujugXfUfbck=&apjevIUfdqVpo=&ywUBwsWgcqUpZ=&YqVPOWZalpZch=&WuuRmTXjmgoUn=&XEnaYUZokcrZk=&Xlw3aAUp_ba_f=&B3rOWMWbglVVn=&_P8lMVXrWWdpn=&CqHc8IXVaVXXg=&GBtpfYUpirjjh=&8k8g6AYgks_lj=&k7QMlFYiibqZn=&TCcrYsUUVmgfh=&Vt9eEXZUekqfm=&JMi8pOUmWZZbn=&6i_CZoYs_qmfk=&QI3Wh7Yhd_Ue_=&pdh9xTUYedfld=&fi93w2XWWmlXs=&xHwvEtUZian_f=&CXbarOUjWhdjW=&FwwCMyZpWnsXU=&HJFLDzWVWgifd=&GcqdoOZsWkoah=&TsiEAaVUsisbY=&hppDiDUlUh_Uq=&CS5OWmZ_hiqhW=&jGkhYXZr_UZfm=&rZAn7VVsckZng=&usEn4KXfkWarc=&V6kwwrZdZXjml=&8FgZ6vXUsdeei=&xUvCUzUrWYbgm=&3PhPdjUnqeXoi=&zinTRbXWcVd_l=&nUmXVlXqZfsaU=&KBWF3VZgjkces=&7vydEQWWf_fkn=&rpJi3nYZdhXsr=&GlrMIKYiYesrW=&XqJTG6Zsdahqk=&lwYSBvWmlpXVk=&eGRXnLVr_abpl=&a_MxHbYZZkiek=&eVsoNcYpiadoV=&KT3PfRUcjp_qr=&QuMuFQYrriYdl=&ZPpua5ZbYdnhV=&R7TBmXUgllVfZ=&A9LvpxZpUnhoZ=&OIxDXtVgsrXZn=&kXOsYHZZW_Yen=&guvYV2XcYm_X_=&wScHLrYcgYaVr=&qk3WiaWaneaVf=&oJAjUEYrprUoc=&SfbuohVfYaUok=&bk53_EXrgceqi=&Kz_9RhYj_eWVo=&uq5HujUjUdeol=&DUNo3lVamiYcV=&KaWrhDYXYUpgY=&36cMfQXbj_Uqm=&Qt58RoZ_XeUsm=&nUCLHUUhZbinW=&HiF5ATWpVhWfW=&BC2JEdUecdhVq=&YwtDIkVbsnUWs=&CfaaSwUXilZYf=&wdfbbsXbed_lj=&gMZTfPWfqmWnf=&X9j7vzUnVjdWl=&qhtGHhVfgqYin=&8zi8y9Varfpsm=&EMYjaNWbpVkio=&6eH7g_YfWjoij=&YKDbHSZrfnXif=&svKb9GZmscncZ=&Pa6BHQWYibmq_=&bHEudIZYhjYli=&qzjVpBWglkign=&dlLgBwWWqjihj=&fL93lIWhdrbUi=&CWu_RfVX_dqik=&foVfoNZlmYZ_U=&3dShyoX_oaceq=&678j2hYorekYZ=&PAHWXfUeceYde=&9sfryrYWYbfqk=&cdFva9Yllorkr=&gWEitGYghVs_i=&WF3Hr8Wlqies_=&m3IrN2ZXifWZk=&ewLMobWXrgf_o=&ToySa2Usrqkpb=&aZqZBGZcmXWUs=&oPZqmFVeraehl=&hN2Er9WfoYWZV=&nuSV7PUqpehpV=&hzkw9WZkkp_mZ=&SFWanUZXZYrbk=&iE4CcgXWjpcfq=&MipfcIWeZhXqg=&8SjPPNZnrbhla=&Jz8BYGVgmUhXk=&Ea2VQaZrbjXcU=&NDDEzJZXanVmc=&g5rShYWXpjZoj=&HgHttdVibjjms=&8dNwoaZ_Ycoab=&2wnvk4UZpcfoq=&ToxtxBW_jcdqi=&WId9NsUsrZfjp=&cFwZFlZWabbgi=&5E6rLoZfYnfae=&fNRJDtXcVXasi=&lNvvk_UhnlpVg=&fAFwTCXionmg_=&TfVWz_V_fl_pr=&H6Lr89WpcWUdk=&Yr_aCmXZZeVi_=&PGRQnvWqjirml=&nNCuxhXahreYc=&6abXzLUlYVZqX=&MoRaBRYrZdrUa=&xY3XRJZpiZfng=&yMMbxaXXXeeZn=&nS6hzkZej_WnY=&hOEmbPZp_ecZj=&BD4ogxXp_VnXa=&if78aqWamgmji=&gR57IgUZl_s_i=&2iWjwUYgXidkh=&CxNVfxXUYbVaZ=&kUcYkyUYVjdie=&IPJkLWYjbWsmm=&wxT6N3UfkhZcY=&WNdZiaZrpYdZV=&8QlzgkYecVesr=&FLoOJ7VXVqkkj=&NA7VWdZnojYcr=&97iNH3Zm_pmih=&o7jAu_XnjVeZZ=&yCclTXZ_nfegp=&rbU65qUoffsao=&YYLetuYqXfYWX=&7FWI4VVXbXnX_=&xQYQFfXUj_dha=&ywqZ96UVfagre=&tsb7euYZihWip=&tE94frWpXYVoe=&frkDmWYVlgmqe=&PLBNiuYcjefVc=&KfQcZBWVW_cWj=&NpOXwuWaXpheb=&SZS4cjWleoWiZ=&TUcekBVfbUmoY=&OorY7RWihjp__=&m_WFj4WijVglh=&bxKnHtWmsVqoV=&46i2mGZXkdZea=&_TKAoYXjreWmj=&NYqZBpVXUqXWY=&lbTh9cUUXhiaV=&XE9lMtYajVqqU=&rbCJfrXlbj_Wq=&qYJeioXU_nj_d=&T9KEokXamonXj=&uP_JeeUbjVncn=&r2rElKYojhahg=&PbKisoYaWkeqn=&aNGQH3Uk_kVks=&a4J_XUXjbn_ge=&Gr3u6EX_kVWpa=&elBbNNXl_Xhdj=&O7KkfdZp_flhY=&pHddvMZhj_bdn=&Gmam4YXjhZbeX=&5Vq2PVZqYqkio=&RRIXjCYkfUcoo=&Z_nf_xZakdVpj=&mXL6GgUUdfshf=&qUpnFWZYabbYd=&jrpbP_ZbpfohZ=&cnwqxdZlWslYf=&H4hhCIZWfeqZq=&Br7erVXXbchmb=&dqPacsUqnZklq=&vkHe8jYnYpklk=&CazqzJUZnsqme=&BHXKt_XbmeWpY=&bjwUD3Yhjskc_=&beQwpgUpZmdgk=&yrha6_XrbWlXp=&mdmjGUUhqUhkV=&LoRRCaWqWreYd=&XtYIkJYgsfmha=&BPgz2nUZargqW=&WJFDlUYcrhbhZ=&dDhaPiXYZeZom=&isgLY5Uanqqkn=&pgIUzgVocehXU=&wE9EZLYfsXgqb=&4KqFQeXepXreb=&p8lfBuYjbnXma=&TJMKusWnijcWX=&226sHvUZ_h_nb=&lkRGAFWdjdZss=&WIyJvIXXqrrkj=&6V3OzyZf_hheg=&g497huYkmUhUY=&KQ7EZWV_rYnUb=&dcZKMtUgqWWWi=&XRpLHnVqjjXXq=&OzscyBVle_kjm=&dk4aqVVeecrao=&FtqOC9Z_ifapm=&9CdDaCVeVnios=&_V5HVXXbVlbVZ=&bu7GKSUniYcfq=&HW8k_MVUsscek=&2Mj_LDUZgqshf=&UKKZoLXkqVpgk=&LSMHWVXkrUWjd=&faMnlFUreWi_U=&PEkQoiXsVoihb=&X6tVWQWZgjUbg=&rh3avjYeVhsfc=&_HctV5Wo_niiZ=&w7HUdkYohjcsV=&HeadYxXYpljVb=&YsQgePZahcZda=&9o5faeUarbcom=&IdqaZ5YbacUrh=&AG3wrwXUqsWbs=&PltDpRWlpqVks=&eQYObtVhhWcWc=&bIIKtGVghYprZ=&RwjTZXZsX_WfV=&zIHc47ZoarWYo=&OBbDqaWlcl_ec=&AbGCurUcZjdq_=&8xEFeJWsfVfgm=&u9jEVVYdekanW=&Ysu6OLVc_UfkZ=&EjQD4XWisqfss=&5jjxvDZlcUZsh=&GjzLK4Waemfjn=&TKXiGSZgaldnp=&icqYRSZqqZhnc=&Myla9aXdijXqi=&PubS2OWndleho=&ghB26bXUWlWas=&l_SE7YVaXWmlj=&qRq8DYWZWaWYf=&j4AWkxUZredfa=&7hTxoxZd_ahso=&mLUBwLYVZkpkd=&kF6HdrXkXehUb=&mEcvK5Ucisbbg=&MTFFfBZpojaVc=&6SiFTmVbimb_Z=&ua8dYhZkodclp=&ZEDJOmXlcmakq=&njSiBLXXkdiqW=&XUJTrPXUecVim=&LIcnCzYmmdqsf=&2meQ3BXWX_Xa_=&ZCAv8jZcrZWos=&23dTmaYclpm__=&Y6QuZ6WcopZZd=&yzhrJgWegUgZq=&DxktXsVgoZhag=&TO5__hWcspVni=&9vexbPXdiWYf_=&HYNup2Ycnhqip=&YCLJIlYnbajjY=&4EoxLfYYWbgoa=&HXin8_Z_llcsk=&ySvqtqZbkaaen=&yDswLvXeqgrae=&fr_zovWiiUrUi=&dFlyrzXkakYqf=&VzbNujYYWdqpk=&vDj7HjYrUrerZ=&l8Y7MhWbXmipf=&M4LXlxUhXgWko=&A7twsKWmg_baX=&B45WHRYkgUrdj=&UsQrIVZcblaYq=&OzDVGYXee_U_Z=&2_EPmEXqkqgpr=&I72Pn8VgkkiZr=&EMagMKWdcWjgd=&YYBZ_gUnepamj=&z7BfsOZfiYejX=&9dq7xxVhnsnma=&pwl5xPWlqsblc=&Rk4o8yWgkfs_f=&tmWl5jUhigsmh=&ZGbJY4WqocXZZ=&t97t3IZqXrhni=&rbKoLoUbmafUa=&8DXIpEYcipleV=&YNj7HZVXhpaqh=&MU3mREVpdkbWe=&J7_7dMVkVfnWV=&qFFUJSUdfc_nb=&dHrskmV_YhgdV=&iG_bwoUlfsXfe=&GxcZ2uUrgpYgY=&f4tAgXVqpXack=&BcbBbgYXjnqXj=&noUBCBYroUsna=&hgxQbCXspcVZe=&tYtqtiUVnpslm=&9awJbUXhqeWWl=&3wyGLWVdjjiqm=&vreV4fZigjYhZ=&WP_kysVaXdkfk=&inGUaaXklgqU_=&aLdtUEUefbkqW=&sfiIBvXphjqhr=&wIPTlEWihZsoi=&GP48cEV_jcoqm=&oBpYx2Woklckq=&DGX5wsUWnfUfa=&pAzfD6Yi_mcnr=&u6WICoZaWdfcj=&PXOj8WYVeUhde=&XXScoaXsiiVVW=&VCbkDhYrjchom=&UChEukZcjjqsf=&w6ySgtZXXlscb=&Gps9mUWXaocgd=&ZybPt_VajnZdk=&7UZHebXfqifmp=&drSbqrXjVskWs=&x9VESzY_eki_s=&LtGOIgXpZf_dq=&y53_w9ZggUpkZ=&WWjd8iZYbdZlX=&zdMoxJYfoVgbg=&e474iKVgjiefY=&cvBPQ4VgXjec_=&liTzWjVqmUnaf=&uZKOLEZaafmgb=&ZBHNaKUcZqWdd=&atGKdVVeUZlep=&gLoijMVUfhrjU=&xQW9hfYnjlbYa=>_R9wWplanZr=&RZk57jZZpWnph=&nBt3m5WrlZWbi=&v9g4NvWsWpqWm=&cxheZdWXegsms=&AjRlk7ZYlmdqV=&h2enwBZUrYYYZ=&gvroMxXsmlheh=&IVEHWrXk__Xkk=&3QiPGnXfXWjoX=&6hVHCxUqilsih=&ZS3R8gVlkWdnm=&zZwWEdXbYXhqk=&xzRyVfUYVlfah=&SwrVo9UlhUVoi=&M8sJ7SVqUrinU=&IG5xdsXnUdUVp=&wZ2YRxUaXVY_Z=&KwXP7WXcmZfUe=&3SYCQEVXeVmqo=&5YzYHyUelaXd_=&IYilPtXVfZ_im=&FstGaiUniUXYh=&GiEJoZYmkWmdc=&4AY3RaZhsXWeq=&codHOuZjrespp=&IO5JqLXfiqoVm=&l47yXYZclYWmq=&4LOkTiXqbniqp=&DNF2JNZpecfdf=&G5oExBWVfe_jq=&P_WIAkZd_YUcW=&7eBhZyXcqbUYm=&ZyevQQVYfWqan=&Muw_sCYefVefW=&eMqN45XZombnl=&lxhxNEWZejpns=&N2bmGUZWqmX_W=&AlbMVcWo_kWpZ=&yWoWKMVZUmkYl=&bp2VMfZWYclUU=&PzUUZwX_Yjdod=&389dimYsmpXpc=&oWyVaIWmdXYWo=&PEzpTMWdWkpUd=&VHojJfWqhUWYl=&GDZjlnYk_bXY_=&xiFxkNZWZjeW_=&bqxBJzYpjpXgo=&LGIiLzXeqVaUi=&Wn6BIWWdjqZpU=&V52ExCWeZf_Yk=&ZwNUzxWorlecl=&dtcC5AWraorfs=&3JRvziWikXnUj=&5fQBJAUaUklcl=&Sz3AIxUqoqbWq=&MTBpegYspZdqb=&ilBhpOZqpVgaY=&tXMP_kWkrr_km=&_UIPWJWlpbhcl=&dW3FZIYZVcdYr=&xB2a33Uqaemci=&_RZcgRZclhaZ_=&Y6z7yfVqikbc_=&zShyyHWYbUUgZ=&wqKERPUmlqkmk=&jCK7cMVpfopso=&TWmUCtWooZrX_=&am5oMLUWmgcqi=&ogsBuhWcZUoeq=&L7_ebxVck_lcY=&8xD7JNWfU_YYj=&qPi8svUnkrqmg=&RtkdnfVUefVXo=&sPNjxOZraUm_h=&7eiLlMUpjWoaf=&z4ydFyUpWjres=&rNib9OXWo__aV=&f2Q6pDZp_opeZ=&Zkn7yqVp_qqoV=&xROdezZoejcod=&AgslWsZmmfslZ=&xMkYkNYgjbXYg=&SRqFurWdZlebg=&IHnNjSZlraXcn=&6CUflDWrnVmio=&gzoUWeZjmVrfn=&7Zl2GJVXWonWi=&7bB6afUohXecf=&Rpy4ZYYXegi_i=&B2pLJfYfkaqqe=&De3HQOUgarXmf=&PlrcJ6WejWpa_=&yw_NTuXe_WbjU=&8rXSKKYnXjadY=&vxqZ3WYYsZXaY=&T7upFPYpWVijY=&LIHAPZUbnmahm=&tNoWykVkWnWgj=&uma9L8UWjWkrl=&3_CjZnWpspUhj=&LtqNDcYWsipbd=&HLJ7SuWUZcfes=&aYhz_jYZ_pkka=&7pF5KeWfmpleg=&EdQz3yVpqdkbl=&3dtPidUhipspY=&qTYVQqWZgUoZV=&ZbMPh_Ujs_qZf=&n69hqTXrdmfrc=&WKPUfSUjilVdf=&Pb_tVQXhYUnrl=&zoNOfTYeckYXq=&BLO4DGVdpsXpU=&pfTWc8WaqfseY=&PXJ9r4UesigdV=&BgfLD6UgVpndY=&tZehFkUgkfhhU=&GUXqzrVVdVXna=&rwtwslWrfbjrZ=&eLAUunUkkXjls=&irXhWdVUYknhk=&YHjd6sXhhaqjb=&Hu_eDSWjfjbXi=&QvbvXAY__bjje=&ZjnWHvVYVZWqb=&ARj6LQXjYVUYo=&kPPxdyXaWsqaq=&DiOQrKXWrnrnq=&hdhuw3Urnoami=&65S7NnVnjZoVl=&URZEVjZkcjUWp=&mLe7q_XngbamV=&sWENIMYokYfbk=&JlKW8qXepnjce=&oGQF6EUfgbirk=&6iekOAVrqfcl_=&pZkhhtYqkrWeZ=&EFByw9Wjpmbnp=&Mdrp6GYWUVmfX=&lY8v53YmjcUmh=&h9LFWSZjZnsrd=&_7lLV7ZqfabsV=&f7NJ6nV_Y_mXY=&WadLMGXnZeeln=&hpDZIrWsnWUfW=&5SuWNgYeiabsh=&hWDQzqYlkclbn=&CBomjbXcUdraX=&dWd5UuXUkjk_n=&RSeskFUdWZZkg=&WQoseAZldlsXs=&EWjbMiWmosZ__=&HEk9BsUpWanhU=&gRWqTfYgnshVr=&QfqQ6BVZmZnca=&ubNNbEViclelm=&RwMBzzYgXWrZi=&4vC6L8WslUVZd=&42hLz4Zcegscq=&gS3x4zWplclsh=&2e9goyVrgpZVf=&shwP_uWflXnXc=&45AbyTVffbqYk=&XafukLZhlUXpb=&TK9Xb5YfhVnjZ=&aDef3JXnlVsnp=&PGCYavZqhejoU=&iBy634Wae_rUX=&ZvdInEYcdkpbU=&siwZKDWVodnas=&R6QjGxXiVqjgq=&P39Q_hUfZbbYn=&YlmMLNZefsfde=&xyjYF9UmYkmnh=&rm95_5UeYdbnn=&zyjhrzZblXfcp=&SOuOzWXheqZWf=&psnxK8VqdmqqX=&QaqzyWYfoqgYr=&G73DCZUnmnpYU=&zkRbPIXpkiVcW=&VVZKwMZYXic_m=&q4vctZUs_bXaZ=&s5QDytYih_eUa=&jaqZXJWmfksoc=&_HlIsTUVmZrhe=&x6EAHFUmbYiYq=&VJG3RvUmqlgYc=&4YNo5CWjgqgjn=&BYWcWKXnnrZ_p=&7ZWqziZoVmfgs=&FQSwhdWjfarUV=&bIkE7mUqi_YXb=&QgrjuTYlosWcj=&cmgQTXXllmghh=&vCyy9PWneheeX=&sjo3GVV_droam=&_N9bznUYsnlng=&lFvAp_ZWmejib=&smyYMVXWXnicl=&SwIHUaUqeme_g=&Z8eZVnVZplcln=&6yNOaCXmkUbqn=&e2OvCMXYahpeU=&wAuQCmXY_mndo=&qIR72AYZoqU_s=&uvdSuCYlaossY=&YrVY7OXXrqlYZ=&9P7FPYZ_pssom=&nRSfqwWjqZchX=&TlTzRcVrlnjol=&ntv5KTZfcpXcl=&bauqFyUecqXZh=&9Ifxb5WZiqXVX=&VEhk_zWfsYh_s=&xOI9lJVZoodgf=&oAakCwYZsmoaW=&qEOtCXViboraW=&edJK45WdUqecb=&QJjbpUXWYaZqn=&MtRBlCZpXljmU=&6r4uZBVe_ngaW=&kF8IwVUVXjids=&5Hd2n8UUYbnaa=&XDlGTvXdVUpjh=&7YwX7vYphUVeo=&Omoy5jZsrjdrV=&lPXsooWmXrrof=&56i9DGUqpdhaW=&N7IsDMXaZbsUi=&VekQOyVdalYUn=&TuOco8XXbsipp=&yme4vzXValijk=&uSXhrvYqiUnmo=&t8tCetZbeVU__=&zjPisoXVZfYUe=&v4vTQVXhksccs=&gHjJofXmUdgZi=&MBXC43UrnY_gi=&YfplhRZgjYfdg=&tIfGlWXYkdefV=&YI6gCjZqklldr=&73IHSNUqaeZaW=&OU3Xs2UmcWoqr=&6GgevDUpmdbdk=&Tx8S76WYbfrVb=&uONe5uWillpXe=&LVLAUqZerngqf=&xJxhGYWiscsjg=&Eg4UptUoanqcZ=&czR_Z7Zgjgcgi=&EsBqXCXfgblVU=&jX9MNDZWcVehe=&KQXUuRVUcYfpY=&YTNCTfZYoWcUU=&9NXRaEXnknWbq=&DLbunhXZeciio=&lu2VbqYhYkWUU=&ODkQjoVZdUebl=&wdPiTqXgpiklf=&6dEGcbWiUmUsq=&hLt68DXYZXe_e=&wIh8a_Zckpo_X=&3KKMYIXrYfZn_=&YTAEcnXmhrp_r=&ck6uVfUjneoiW=&KRDwLqWgZUZkU=&c3qvbCXqjq_ar=&D_6ZTxYpXoXUh=&gWuuv8Wcg_eXc=&D3nj9FWUjkeco=&WQtOjuXWlaZVj=&QNDYKzWsoegfl=&VpG4qiVphZmUm=&plgSktUdmdhgp=&k39bmzVfidfZW=&gzVTqiYmknkWf=&8RfRRIWekafnc=&EolleqUUomshc=&9Sz4SCWUVcXpa=&D5vqLBXXhdkan=&wUChTDYjn_off=&XZ7lqxYjdpYWs=&_HFx5pXqfgnWs=&b5Gs_VUUZWafr=&QXsn_sZnWmnbn=&wgSNlzUgdojfl=&zaEJGCZp__ihW=&4zNvT6ZoUqrZc=&fny2NOZlr_c_W=&4nUpBBXlgesgU=&K33whbZqekieY=&h3m_YjXrXpjXh=&2YcuteUrforZr=&YqGgjAUpiphWZ=&8gv9cCUYqXpoV=&F_7WV9YUiYZhp=&vCqSsvW_rhjWW=&D9ib9rYcndahh=&MVTSfCZnnVYbd=&bSvKfEXlhkYsp=&3fcZ2NZmiWhsl=&2g6HP8YoVqmfs=&xcU6xiYnoYUXY=&9TiYXMYpf_XcU=&sWzE57V_iqflb=&QCblNtZZZXZii=&yqJLuWUboWkrr=&tWUnRYUkahjsc=&32BvLlUUbhpbe=&ewLc_wUqkqb_Z=&Mg3s2rVqejqcf=&rZQTrSYiXmcem=&GplkVlXmcejZ_=&HIOQGwYckXbdf=&2WT9qZWXgkbhX=&ockyS9WkXhUrc=&vUX9yfVeVYnbm=&8ao3F6UaYVV_i=&ExspR7VosXkgi=&JDUoxNVjnjafY=&NnZ5NGYjVccqZ=&5uG4GUWWVVYpl=&w5G8sGVYqjjap=&tjWKRAWipVmdb=&FbreBaWUkrlUV=&fCaAYBUZZajWY=&qq_tCWUgW_coi=&fq5lixYslpmjf=&WKx5nlXWjdjVn=&7p4ZVAYdj_ksl=&oDUpFXXsrYUnW=&gPTbiTZoojl__=&9Uo_qhVgcfopr=&NFdjyOXVXfckb=&98HXK9XXhcihq=&MWwVyUXYZVkdU=&NvV6gxXfblpUp=&xIGeVpYcjqaWj=&CUWPF4Vae_mjU=&wr_sf_Yehdcjq=&_SVKLHUXmcWef=&kyUKzYXgjdoja=&OPQhKmXsasiVn=&pFAcJHZWZZspj=&RV3ADBYqXobja=&ZyREK2Z_UYV_e=&LD7aAUVdgU_er=&HRMqZAUqamjkX=&e9xQV2YXlienh=&p7KB5GXgXrdWf=&RPbf8OZqrqioo=&mir6ErUapZYqU=&NGXjbYYVsbgpq=&wnvjMaYeciolh=&DZtf4UVo_nWpd=&L6PJKBZXeZWhY=&65PeWWVjZcWoc=&4qbwwCVijgUUh=&TDujUDWeeogpo=&FjdjWBYipcWd_=&2EpQ6lXZkjfpo=&LuCt7LUnkfjdW=&_JHMnlVXdnham=&QCtxosWYYUZVn=&plTIApXYUZerm=&JDJvgXYYlcscX=&TtoUFVYnUbocf=&Pb3HqoWdYrUsc=&2DYfjFVg_sgl_=&TFdnRGZXYYgdf=&EOrZb5XfmhZao=&bnvKvYWnffafZ=&3QknWTVXVVdsi=&8ptKj6YjeUrim=&AbTkHbYboWrXc=&e2ydBrYidgobh=&EQamT6Zdjbofm=&wcEowsVlolsZf=&e4O2ZWUcp_nqi=&Ly7vwdVeddbrr=&U3rx7_YaXZZaW=&_RRlQ6Vbsdabj=&fK4O5WYeasenc=&H9reclVUhophe=&GPUuUuWbssaiV=&d2mNBIWbjsZcm=&dxPw4QUUoiccl=&KPfcyfVcnacek=&JmBsWBVh_dpmm=&hsHeR4XYjZ_dZ=&Nh7dyiYhUkjUa=&vlQP2sWom_cja=&U5MJJpVkrlool=&EMPFLvUXipnWU=&4FMMI3ZYefgp_=&TXstGPXm_sW_Y=&pSUmc6VdVjUaV=&ouVSg6Uh_eqcW=&3JGwICXoWgdZX=&xuW3AKZkmZsai=&ZsfYafXdXooqp=&pRWvGHWalbani=&7ebGSSU_krhrh=&g5l9R_ZVsZepp=&cU4Kn8XrXkWps=&LI97lTWmefdaq=&6EvurzXZjWjrg=&htPRoKYjeVnaY=&oL3dl4Vsj_ars=&Zvlg6zWlebpZq=&mO5KSaUcchdfU=&ZyiKZkUpVbpcf=&x4jNAdZjoVkqZ=&KHNzI8UXbjpan=&tSQNkDZjYVhdX=&y4rVoxZnbqghf=&qsVheEVkkfhnd=&lGURM3ZakmaUU=&VCIlwqWVYj_Yn=&nVdHZOXejWUbb=&eVGZlTVjqbrpi=&lqFSBdZaVYgqb=&iHJHPKVjWYrlb=&BouZ7QVmbZWlj=&rF2OLGVZYVjli=&2IlZ_ZYVYmjab=&QkjIRcUqqZWrd=&IpmDCvWbUcUsb=&wxIHk4UijUeol=&qY3fzYZbsecYd=&7pGxWlZqnnrUs=&Cmlfs_YXfnrih=&xtcTGwWUcUjjg=&R_vyI6VdinoVq=&IJLXJZZXkqVej=&B5LrHOUXaVqkl=&HzqKryX_Uggpo=&9nyDJHUcqajfr=&GuZ4WjXripZrn=&COdZpqVaajbsb=&OlRnHUZfffmVU=&GQDVgMXhmWhao=&RKb2e3VbdVZpe=&bF6uq6UY_sqlU=&hHvL7nUkYnkho=>jy3MV_lo_gd=&DjoWurXbbomra=&xbbknhUbfXVfV=&_smSKlUXe_sdc=&5MmBfgYadloYb=&nFCxTJUdnVhXd=&FRw6AeXodkgll=&BUpEggVmheo_f=&HfQjBNWkseqse=&6k9BGrXqjnW_h=&ngahBMUjXjcjs=&VRbwkgYfYlalr=&z88ONmZeWoVpk=&SR8mJZUcWprWj=&ObCPaZVbYhqjg=&Nk2tOwZfYlanm=&Vu_tvmX_ikjhl=&KsQaUsYgiZXUl=&ZkHG9jZcckiad=&47lnEQZdhbsie=&lxF3RDZggcoYX=&tB6F3jUZcZeY_=&Avu8UrXkaknZX=&wFJR7wWYqacbb=&B2O__MYmah_qU=&C2ky9hUWYjcVl=&7BjrgzYsafkfZ=&FWziiPWobolke=&CnX3utWXqjUqU=&ULHlUAYUrjiiU=&hByX49VnaosYd=&Xze4dcXg_sbbm=&ThQSUXZomfVZe=&8WeOHRYhmhscg=&h8Vn7PYjajfWf=&PX_E6wUVjgUas=&imLzXfXkekYe_=&iAhQBXVkXerde=&IoaDOgXXqpcja=&RwkIXeUYnghlk=&NNSRs3UVrqlZg=&rgf2LNYVjVpqg=&a2tHQXUordkkr=&YfGCOxUqYblin=&DyDia5WWZUbqr=&OYnbfzWakhsWW=&cNLBQbVsVqYkV=&ieoSkGWYjkddY=&odAS5QYYbjdgh=&uzb9OvUkcZrZr=&Wr_4SsXihkgVm=&WLH_8iYerZiWY=&LVeaXqVgpbfZp=&KuOHkbZZUiqne=&AdJeKHZosiehc=&9j2jfYUijgpcZ=&jtWUQ2X_npoli=&dgjT8RZZhsikn=&Jx4bGFYqUgYms=&eh4W5JXWgksaf=&2hVrupUhXWrls=&N8WWs4UnhclkX=&w3IU4oXcsWdiq=&ooEO9fZjkh_YX=&NvtYStUc_pXYh=&YyUHjZVYmaknW=&kbj2YAYdaohZl=&QwIe5oVXrgmZZ=&mToZyTUmnsbik=&Q_c2IYYWakjhm=&MufCVGXcamhfe=&d9weYMWnscWYZ=&vFbrTMZceVYpd=&w_MTnTVpahrWU=&7lvBy4Wlhskbm=&Z4WPSlWqVjesb=&Ef3Z8hVeqYejn=&gx6RKoZeoXsVb=&6Ln6ILXVcUUXn=&u7SYzdXhkmVjr=&QTq_sOXs_sofm=&qs5M_8ZYrefng=&mespFCXkhWZXl=&HocufLValglna=&PgVubLYhcc_ak=&9Ds_mgZse_qVc=&QkVfCXVccVldq=&lTaHUdXlXXcV_=&riYYRcUhUVifs=&2OKqm4VUhbYnr=&LMMweQYrhlfnV=&ti2HksZmefcsq=&9ehJR7Xoego_V=&JuYSiFZnpYfWj=&zZAcAfUn_XYjd=&mInk_cYUXdmas=&l2VpWZYcdZrfq=&5UbZY4Vpagqc_=&lYlo7aWqaqpjX=&WhHuakWiWYnYa=&cFBQt5ZdpcXYk=&bI9YsRVpqbnXU=&bTkXdsVXpVmsV=&Z4EhfGUofeqee=&iIDr7UUkcneln=&6n6XNpVXdZXVl=&dN9cOmXehWcns=&_qfOdBWg_Vpbl=&iWmearZm_YZrV=&MrQ5x8XlZhfml=&KTotuoVpsbZZk=&nitRWwXrki_kW=&tVP7VfYkpogVs=&lNhuAYYm_jUcn=&a7Ul4cUZoUmUi=&ycxeTZXojepWp=&6iFDtaVYhfqqY=&n43yRsWdqYcmf=&XIS9yLUaciZmi=&KTkySNUYhfYpe=&NUN42RVrlcirc=&4EsFdsZYishXf=&v3ssqcUibgdjh=&rnUCblVnhlVZn=&JqUiadZaohogp=&wT7RJXXYiZjck=&xeALzBVZjnsp_=&7MaOphWVdcjis=&L5MnnnVkUroho=&v5aBEgUmehqlr=&CPEmaPZsfhohr=&7oc2AIXbkhhai=&k2PNEvYXnkdnV=&aiasdkYUheWkh=&zzbk_hUqscZom=&683GG9ZlnZsZg=&3FSX8LXbeamih=&S9NorUYoefWrV=&JS9UERYakleUe=&H9Ez_xXnmWUmq=&YP5OafXgpqUnY=&crRFuYXsVssoU=&FenfMMWYldnda=&nqdX9NUndpeio=&l27hvtUaa_eXl=&xuoLMpVrrajaY=&UsZNKpWgpdWge=&NsyGtcVYsakdf=<Djj3XeiggdY=&xIwRbOWmmYghV=&qJGHOFZksdUZr=&FbkvXXUoiXckr=&YtuLTUXehiZVW=&SYyQUmXcehsdo=&VXVhBlXkhWofq=&cSMSF2VcZsZW_=&CQBGv3Xrkogno=&zUOwqAVcmn_Ws=&cyK7U_UcVfqYl=&IkyWSQVaXgUVs=&XhiKBtXpalUs_=&SBvQVBUX_eqhp=&TuHmaMXinkjcs=&h9lfIfWVnhcqi=&ICUDypYjhjjmp=&Dq3YG7U_fYUhm=&urmA8ZZVZqeid=&tNJATkVbbrrVb=&Kq5KT8Xqcqeso=&cuB7vJYYgeZha=&_u2mCzWVXhc_m=&6OpwAfWXUZpod=&DgyXkxVorjr_g=&D9qZk_XZisgeV=&le5c6_ZZprZeW=&yxj5EWUWjiWZZ=&dtJ6rtWfhjWUg=&BDKWX4WrXhkqU=&gJ7zkcUepUrrm=&pYBznGWbcafne=&qvNXptXgroaph=&74h8BSZpYddj_=&ZVLlHKYqofcZ_=&zC39fiWXZZopn=&qTlKgQZdscqsb=&TVuduKVhYXsfe=&BIgVVNXfYcpsc=&DWnqGyYXshqgl=&JHpMHuYgYUYfY=&C642tUUnsdVkk=&bkTRSFXhcqpWY=&y3HIiBWZrmVi_=&zKoWJ8Xkc_pVV=&lMBE6mZjqdWqr=&fpB3jeUXdjesg=&Ld6_T2ZUfampr=&gaOwpJWmWkrUc=&xfIjlVYdWgibg=&cnHk4cUZiloaq=&2J2qvTXagrseU=&4r3Z_BXVbWbUh=&ojxB9zYh_sWYe=&RLq5_8Zboq_jf=&Y5nqMFWfaiUWk=&RzK8VkWarV__r=&MNHTfKZqjqkVU=&Gu37lXXlqniXX=&ppmACeYcmqsoZ=&pNANI9WcoZe_f=&v6ZinCYXk_lhm=&CgesgOZdqgera=&PelWEPUXYqdmi=&aSIEceVksdldh=&vhiHIBYgcWXhV=&eq_ZaqUpoqs_Z=&7UeEP9Yogkmes=&mmdZkHXncfha_=&_kJ8NaUeis_bd=&cIG2AjXiWdccr=&IbJkngVZhaqZs=&d3XyEvXZlls_i=&BR6jwqWkcd_lZ=&_fP2LZWaamjsp=&vQpETkWVindrs=&zeBykPYZmrZer=&eaHbrWZaYljlq=&uHxOLMVYjjcin=&B2r2FhUcerams=&AHBVjKYXc_hdm=&qIvKJPYYa_jVW=&VOLqTOWrlg_fp=&TeJEAqUnkrXec=&o6X6BYXipneqq=&h_NU8eUsobeZk=&RMMHyrVdasqme=&4jpZS4UX_grWk=&3b59BXZsiesdi=&cCfjAJWZjeWXf=&ZhZ_cgXgZibVc=&mBERm4Xadn_bY=&4frs25YUdkWc_=&X8glVRZclYhgp=&_gI5hhXlesUid=&ybQF7dYUgoiWW=&PdCEV9WkYUism=&HTHHzGUrUYXkg=&squOdHXgbbpla=&9JTVSUZUfrehY=&juWO3NVrYUZnd=&Yy7hUSUlXobYn=&raeHTWVfYcVfY=&Z43TVeXsip_Za=&iBV5_gXVamnWm=&nvqMBbXVXknmn=&wmxhClZUsjjiZ=&GA9dJDXcoYphf=&HhZukWVngZrYs=&ZMWJXKU_aZkXc=&YkOAgeZ_bVWmk=&A9QasSXUXsVjn=&mUTGmjYmqcdYm=&F7UxAWUafYhfa=&7YUReDUlkiaUa=&kFXMOBYZZssrV=&kdOoXXWreWshU=&9zVOUtVnUiXnU=&EZoVlQXrbsseX=&dri76XXcnVUaW=&zeWjqQUahjnVn=&hA8wxoVhWenUp=&UR38sKZXZkhd_=&8wsapqYdmbnqk=&SRd5meZnracpr=&lZ3mpeYnhgUbX=&8KMTa6VpaaVhU=&YYLTHeVUnZgps=&cKjsAYVUasodi=&FNUwyqVlbnjaU=&fdzlnYYkZVZqZ=&dI_2fsXm_VXgZ=&K_2x3GUpWWdfe=&6Z_3hZZhXiZpY=&FgeAZtWlmjlh_=&NtoXsFZfgkieh=&mckf_HWdkXZcW=&9Cgd9CZmsge_l=&OWrA6CYWUVaUq=&LZoSOmWojhi_V=&4vfDOtXrkUhZU=&4LRqq9UXXaZZe=&XqoBHzXdYsWnU=&36bY7BZfblosY=&VKVYk_UUhmdah=&44ZnMjYbnkoac=&dAraktXsXdWrq=&iieGQwZipkU_V=&eevhNZUkVghqh=&hycy7lWpbkfas=&W6UTkXY_fjYXn=&YHGyp_WomgXsW=&MuxA3TZfjncng=&eCELRKUleckik=&PweqS3VrV_ebo=&c4Oh_gZVlpZas=&9GuZffVVZc_cZ=&Gbu_aKWYUfnao=&hFCPdJWpmqn_Y=&2VI6AlZqhXcWq=&ebqnxMVmckbkq=&F963X3Upfejnc=&iBqgoVYWlmngh=&H4b7V7Wpj_Ypa=&U4l4LLXpbh___=&ktgM9NXVVWqXd=&mYgsoQXsZhrmX=&8PB3nHVbVgooZ=&s2sydhXfbkZrr=&3jSaXbWmqacs_=&x57_SoXaVjlWc=&rtFF9fZsqejkW=&iuhXEVUpnqkWq=&5NNLMGYUlkhhf=&nrY7FEZfhbqUe=&CbaPJZVjVjlk_=&YXmH_yZYdrpbm=&xZTUoeUdlVsaZ=&BDBLxvUXf_ipg=&jkg9H4Xldokfs=&4LCC3BY_e_X_h=&wrVAJlXspfbdU=&jP7IWDZXinmsh=&GgX6pcYYZjXsV=&aEOlU4ZZVnbjZ=&HlooN3Ziprhbn=&LRQZTBZfse_Wm=&MmAA5hUds_fhj=&idEkPgXYsngel=&toRY26YgZjosb=&Ubh24gWpqUgsm=&NHuQZnYailhZa=&fkHKxzZfpUncj=&oeeLq_ZdeVleY=&Slta7rZcnsrne=&oMIb2aXspjjal=&uM5aUIVadqcdk=&mnqujyZceYXYl=&66tP5VWdcYVbf=&KTBsrBWdiaqog=&APVxtoUhqfpca=&47jmiIXYicim_=&PyVVNfUYdmjlj=&CM3Xr4VjjlYjr=&azgFxcWXXfqmh=&MnTKmmYrZVoWo=&ozq5VuZkiZiop=&LnSqMGVWpoUed=&E5XYjLXVd_rYm=&syXuoVZXba_ln=&Exzvx_VjdpUZU=&Wmd7jsXrbXgpe=&jyMSZiXfb_olf=&IRQ9mYXUqi_Wd=&VqKL_eZkXVpkf=&WjR_RuVbXUsfY=&wJgnneUqcrVii=&43siWWUcikjla=&jQPeFVVdejYbb=&e2rYABWoZlUsW=&tP2uXyWmdbgoV=&NlXQkfUcbemo_=&oq8pbGYr_Yogd=&5MRP_4UUcXhhZ=&AuZ_oVWohghoX=&EX2MOyWcZbfkk=&RknBRTXaYrZn_=&S_gPiRVgpZZWp=&tfvLhfYdqqdqX=&zBgkGvZlXlae_=&K_AW2AYiV_gjo=&Vvah4UYaqVhls=&VENKpNUrqWjpm=&dLdRbjZpeZqrd=&cLYx4yYVsoXpX=&AIuJVIYodZYsp=&pgSGqnVblpkjq=&mwxptNVVbjdga=&vThBekYohadVY=&7wNJV7YcjdXor=&oar8A8Vrrephp=&_gj29PVrqXrm_=&Kpe7xtXqfislb=&gnKHSjUneVrcp=&7MOxqpYfbpcVf=&NSPtVKVWWeph_=&xoQScEZY_ebaY=&m98CGYYWcklol=&tfvoGlZonpcjh=&iAbhTIWjinell=&96xTdFYXapdgf=&qILgmrWahXmed=&zgtrtlYUcrjUs=&5uA8tUUZejrnX=&Yt3_CCZddqpdl=&A2aE6OZmeXcYd=&BJjmr_Y_eUlZV=&6ZXACMWmepbcs=&DU_Xm4W_gmcoe=&xAqv2VYb_Yrro=&BzhfQjYfqdmea=&9RjPZlVhqidgX=&ExKBifZgWmekj=&CAwkrJZ_iobcp=&5wSlVZZrsrlae=&UrWYfYWcqeZdV=&FnhBhsYhspWc_=&vmgzAsYoWblVa=&fr9AezVUqmhqg=&rjfGOWVeoWpac=&Gl_d7kWbgmcoU=&oZXsYoVWVZoVb=&xzpPBsYpibdmf=&cWuiDMUgmnlm_=&7QbogmVmaUkel=&hlXf_JZem_pdh=&hed2MTVlh_Wfh=&PbvbFvXoreeVc=&bloh9yVornWfa=&XKXMEKWiqVipf=&ZHRBwKXqXidVh=&h6gttmVeqrirg=&8jDbOzUmkUhkZ=&F9NL5CZfXjbpe=&fC5HDJYZ_clmV=&nzkaGGYjoXZea=&3bbXjjUVpYkrp=&Ad8iieXdaVUrh=&uaHdGbXfqmjnk=&z3_AxjYYqpYmZ=&IUwwITUkfWWde=&CQfkZYVfiWqmf=&uoV4gwYcmXnfo=&L5wKQMWciVjjl=&B78yomZgYYmWe=&k4hioQXihWUqb=&A5FITpVXWsgae=&9Bnm3pXmmmVca=&7xGRGYVWbZrml=&ftSt9YVYliYbr=&34xtpwZcg_nn_=&wxe58pUoXosab=&7ClNBZWqc_UYZ=&ILYPxgZgYXhho=&SPieI2UcpghVo=&DvaNUBUbgXlg_=&QFkfjwUZYggmp=&rtGT_IZXhjsUU=&TIWDgMUUpoose=&Zfv9NsU_gWaZa=&BQWmruXqdWqVs=&R5tOGqUYoWrpl=&RS7EAaUfonVdg=&ucHAnOUsUkZrn=&8FkoM5Ve_qsWY=&5gAK4xUqkoq_h=&OWLxJrXpbYVXg=&OUAtROXXshlrk=&5rZWiuVpiclmU=&YOpC75UfsnbXc=&xpzgbwVpjVVmq=&ZvaPuAWjgpYYm=&oIa3fQZoqVZpa=&afG_N4UqXfpWn=&lPhHftW_jVche=&jXR4_OZXabqck=&V7mehMXrnraaV=&biILiUUdjqhjh=&PtF7ZOWZgrogj=&hMzBrUZlVqrin=&8nIXr8ZlbegZm=&B5XGCWXdndpce=&8bwtneUiUpfop=&wBoVBcYkYsfbU=&IHPjPbY_YWlb_=&gilSPhUoqfaqZ=&nuUV_IXacdgap=&fSOmICY_ek_Zf=&js_zerVU_fYXp=&pqMKeOZmsmqgf=&RrVDW8YpVafdi=&ZQn394XqUqWgV=&eTUqWeWoVaodk=&I3b3MiWXeWUYh=&kc6jtfZXXrokl=&LVB2OjWolYXZV=&5R4mgvZpUcriZ=&nk6pE7Wnokfrb=&okk9iuVceaYWW=&W8ICxUXeUXsap=&soFM4nWWZbXsZ=&uPcfYqZcUVdoe=&S7beKpWqmlgme=&qwRyyDUmjdWXe=&ulxHPNUesmWWi=&5sIIxEVqikaij=&WMdo2GXVZjsZe=&ubC_aSWUfYsfY=&H3Wf4KXhoecq_=&TsyvHbX_bYjos=&oSfVacZmgahrg=&vU6U2SUsVqkjq=&bTAwZAUlpscss=&d7vDeWXbgYcoU=&Z9OJU8Xkgmqrq=&QVOu8nZd_fpie=&o_FK3DUmpWUYc=&4osdYpXjcUssa=&AxFjClZlpskoW=&Dr5z66XWmqsro=&_rFCWSZmommpZ=&EXvI_FUscXbUm=&dhkqqlVWcgfXV=&S5HWKlXkdcnaq=&llAj6dUoXqfca=&dAnkslVVhhYdX=&4nITIoUmZjXYn=&RqO4fqWjp_rYr=&YYtPvyUVVpfXf=&xJ7owqZdrhZae=&JqhRKcUmdnhfc=&fqI5x3UrXomWj=&3U2f3HWrnhZff=&NYkiz9VaWoZWb=&J_RKq_XoYrpYo=&Hn25kIVVXiZia=&YKSz3tVnanYdd=&SGhW4XZXWddpX=&O6N9BNYmerdXm=&YkZZZmUhlemWU=&SaGQKjWkqqkVp=&PMyLyxVgeXi_c=&KTu3KeVdofgng=&IaWxPrVVqpXqm=&9LcKASYlqildj=&7gHVXkZknViUp=&p3mK4UVqbZYWm=&47bIAKUVmfiWV=&7lz_dGUXgneqm=&i8Q4eCYcmspoY=&NS5VctVomrsqm=&soQ93yZrgjlna=&JNLCayZenah_b=&2fsNC9YgdXYpX=&NT7pfUZqeZZe_=&tUTfx5Yrkcajd=&v8VUApUUlrXXp=&5hkEq8UcroYcc=&G2t5pyZlafbae=&TJn6urYVbVbdh=&THGZ43WXcbgWp=&NyVhLyUmnobmh=&BTMQjjVjlXqnm=&PKwVIFUdUahsW=&DoRFBMZmshlii=&5IpPPMZpjnpZo=&4AKXuXVobnrYc=&yiNadVZpnqeps=&Ps4Tg7W_rWomX=&49Lt_GYibnrVo=&UNfUooWiZdmfW=&xkgRCTXnZisVq=&6w_D8QWdokhlf=&lp_bvjXfjrgcg=&BqijrDZblipZk=&MXR_HRUjoqqnp=&nLJk3CZoncqmo=&_Ds6h4WiXXblj=&ZjFrF8ZWfUliq=&vLhIAtXjbh_nk=&fxlgX9UWVjrUa=&OzgENzUkhbeXr=&sqyhN3Xsdmshe=&bHLqq6Ymfppld=&4p7K6yZ_krgqc=&eIhCPJXkopmhb=&wsTf9PYYrkasj=&jjpkxGVjdcYca=&So6yxbZWUdZVk=&vhwHPAZgnUZnV=&IJnvWyWiYXhZh=&KGx4XAUabZdgb=&T6DgFoWhmcUjd=&l6uP3qXspqXrs=&jz47gLUsf_lli=&RxTNcXWcodlqU=&ol4cGcZjsaVdn=&zYnXteVpijbUb=&L7VtoGWmrfrgZ=&MoQT_PYrergap=&Onkjy6WlUaUhi=&Yp4IL9WdWpbof=&KPPYedZUlromf=&rGb34uVZrkWZa=&RamrY3ZaafWjg=&k3UDMXYndXedd=&unFBBPUlb_Vid=&2OUn2jWdcWYgW=&goxmnLUrbWUYk=&C8E2HyZ_Zbn_k=&zSSZqiW_Yalnd=&QJeELnYcZZkZn=&5LC9fYXWfXoc_=&zZ4CYVYYkh_bf=&2rCEWuUmjpUnq=&ApWxRWUWsfaeh=&U495wWZedUXXq=&3w5sNlUrZonnl=&QdfvzHWmis_co=&FyzF9IWrVbmlo=&gH3lXsVmek_bo=&3tpBhTVsZgfro=&vEOZjuUirgbdj=&eVFS7MUkfqUsm=&DSMG3FWeclkce=&DDoGvAWVeqlYU=&joAlhLXrpbooZ=&yKaiSEUoscZmc=&XAbUfZUsfjdiq=&sCvhLHWoYjrjY=&HRriT6VZ_aqas=&NN6eIDZjbisjr=&Ce43EXXqeWWgi=&XRxyHwUkmjWXX=&p7jBLtZccqZec=&VoZbjyZUddnmd=&CQgdMrXqWdXUm=&nRC9IZXgXZidq=&XM3ktOWhYYbfW=&DWjqd9VkVajhg=&OMDBw3XnVm_ii=&LLBzPPUlhfgii=&amH2ERVn_manp=&IBgA8UYndfsVd=&zSPospZlZqUkn=&L9cLTpUh_ikom=&Ul92kiYj___nh=&o2lcWCU_gkZaU=&2mgYM8YVbjiUc=&f8_KiVWqerhei=&ATNC9pUUogWhb=&8frij4Wsjnpqj=&Il5OKXZsXpmqY=&cFp78RUoigVee=&WkJxtNUrYkW_m=&8Tmy7MUqnpYkh=&NkI2Z7VjcVmne=&Q8iU5iZpheqlo=&DbiMf_Vnqnmkh=&iFCRu4YVsZoe_=&AzxK4TZXrfaof=&fSYQ4BVmZnjbp=&mkLfKjUcZedlr=&FtYYJDYobjZgm=&llu54LVr_lidV=&Xxg5P2ZflXnfZ=&qg5wHRUfpZcaU=&IJ3trtZhaidVf=&YeNSBZWnZVnZb=&ZFLVghXkkYkZa=&rtvPdzXirUlWk=&9nDBepYikip_U=&DfdsJKZsmVelU=&d9BME_WpUZjbj=&AXcfMFXeoqeWn=&S55aeqZliVcbr=&MoTeLVXUqaenm=&L4gawTUUirhqk=&FILToBYpcfkkr=&ShyzWCUXrccmZ=&ajKO_WYiWrYar=&RhBgTsVhhrfhr=&oE8dgGY_rbaqb=&WeNdinWdolVja=&Ulv2QoUfXWnkX=&i4EGC8ZWbopWm=&bmiGkpYscesiZ=&F4OyN_YeWsa_i=&fMOosyYdkldgV=&b8zPV6YWkZYlf=&rQJVjCWdscYbd=&XGiOemWiVmkYn=&A2HyzUVbkWhel=&96nfsCUWniWjo=&iPzfeyXfUgYiq=&noEaFdVV_rlYU=&Gj8HDGZVks_aV=&ZlPDHYWeVW_gh=&blAGetUoba_Uh=&NjwGEJZUpVWdY=&yltD4XX__oamd=&jjfhC9VronVsj=&yBb3MqYqniYas=&3WBocdWaaiWsZ=&tExmMBWdejkqm=&aqbZvoXreWXZi=&BOnVGiVVXdXqV=&JG3bScVjdehbe=&uO2peiVsbZerX=&euNjstZVbYgpc=&BKGPtBWbnrZ_n=&yguYXoZU_Zlan=&26GFEoWiVkqpm=&Tvqag5WpgYZep=&eGJDJlUUlsVfo=&tP5holUqjVcfq=&4mPWg8ZnUoiUe=&Iz5_zfXXeamVf=&bAzcTwVWqliYq=&XwOog8UZlqYql=&z23eeyZVmogap=&gHe6B6Vdrlidc=&bR2k_fW_lYmcU=&rf7RITYjhZqrX=&6PqNzzXrhmlhl=&6jLzEsZ_nqpXZ=&DZDr5KVgXpZ_b=&te5gRfXglVicd=&a3TWLyYgqisjY=&LQWKjnVsiohUg=&5X8YY_ZrqnsY_=&PB5PyeUddcjXo=&f_AXMSYa__ddX=&qD9zCEZfrdfoW=&sa7MbpUfq_ifh=&ArkTLGXYZoXr_=&jmkpaQXZsXkao=&I67YKgZYjp__j=&ipKBecVpYXrb_=&LzLRLCXdWnfsU=&7mpIs3VXlWYqn=&VYDzdbVqpshqX=&PwaorBWpYgosj=&SsXUg6Znjolpc=&HsCpgZVbYiqjZ=&5wqXVWUbVboiW=&lgJ2XnXlkiamq=&QAxeiGXWZenn_=&5JqD5XZrjfZdc=&cnIbRGYsjdWVf=&fCrGYrYfhpark=&7piCBqZgpo_lU=&rzFKJXZbbifjh=&qEEbR2U_Y_jgX=&Xz9LKpXW_ddsg=&5dkThOXmplh_a=&GBpLNUVpVhahk=&oQsx4CVbqih_k=&XZPmWfYVjYqeh=&b99V9PZdsaVrY=&5_eIPuVrcUasm=&egzbm5Whnqdfb=&_xvxzUWYfUnqd=&vK_KReVksU_hn=&uiNFWkXcjqYfY=&cr_NssVYUg_q_=&E9fWcrYaegXss=&VWSdcUWnbnppa=&VyqZd_Yqkmm_m=&Q5kD2DUfisqre=&MDOuSCZpYdgbc=&MVkvAXVhgsmpf=&6lAHCEYkrgYdk=&8Q3WsmXdmrona=&SkaozRZUXmjca=&AsaImMVodpnYd=&dewdafWYWdZmo=&EoocykXaWbYdi=&ASu5abZqsclnV=&O3T7kLWkkdoqq=&eOoZGIZlkhcXU=&J_h7HhZjigndb=&6RprOAYqssmcX=&W4NxHmWVmXsb_=&HmNAZfWnrbqfZ=&UufxjZVqYhhca=&YGHnhvYVhhUUY=&rJhxDqUosrmrm=&oGkoYOWhaUqWW=&MoU_MRXrWnpjV=&ePBpdjUlWpfil=&hiDqrwUdsbpoj=&ZS25JUWalslsY=&G2yI94ZWbUckh=&iyjjOlYpVbiVW=&2ELJEmUpabsc_=&WOSzEbYnlZgas=&zysxnXXf_kdki=&nshuDuYbYYreY=&OrmZHXZdXenWZ=&k9SauuVmm_Xgn=&866ykgWU_jZhn=&PphOMpUYpdk_p=&7c4SzXXrmjiZk=&6enZPMZYnpshh=&eMELpvYsqlhc_=&ODZ_ivWcdbngd=&5tBOK2W_pqerc=&OiaaVpYYfhZdZ=&raSIBmVhVfjik=&IxxpsHXgYVXfp=&TYLSKQZnbpYpe=&pMRDyLX_XhbVg=&afK_wmYlofVro=&arzOa7Zohqpim=&fZngsFYVqkppq=&5U6p9KUqXlbma=&TgD85jXoemplq=&XkFcpfZnriskc=&TgWjmSYeUgdZZ=&Ypllh5Ygjpshg=&YFeyvYUmdUVXi=&g6_VRSXlV_brn=&MXysgZZjhjaVY=&vPXEFVZVccenV=&eZ9YHYZfgoghU=&TXWr7vXschihW=&FsLzeuWncZqdf=&diU7XiUYjspcr=&8RBLklWcVWebi=&2ccSpnYooliad=&anSNtsWsgdcri=&57f7NrWm_spnY=&d_ne4YZsoaYWZ=&Nvir24Xcs_pfZ=&UdcWVKXqfWjgY=&tAdpotWVpilcg=&57FvPcYnlXsbo=&WrKExgWrZXjer=&zid2C3XZaflfh=&VPVWUwXjoUVVo=&6JZuKOYU_hnae=&Fh4jHqWjpsssq=&JWHOaUVkllihV=&5m4lVWXmZfqfa=&TJF7nfZZdlVjU=&d6SGTTVbhhrWq=&x4rESOVUfccig=&wMtU6FVsYWWjo=&Rjhw3zZkWZsmV=&O4eRBYVkUirUo=&lTWuftVdgifbZ=&dwIGZIZf_YZek=&wUYNJaYpicklV=&aLHPh8YqqlbgU=&E4vMq4VjVhkki=&Hskj6UZhebl_a=&cDxGrHXmc_sdb=&yQxKYCWnrjsdo=&5DN3mRYmkajob=&Gkciv8XXealsi=&kbstTzW_Ymljr=&a6WKCQUVobjXs=&wZNi7_VdbicWi=&ekO779Zaqb_hk=&LJtrzwXUWUbam=&sAAnpVZpeqb_Z=&VHW6kXXhmhbij=&SwEFrwXa_akqU=&6FiL7DVqaVbhp=&nhDt9jYjlYifp=&Gq6Dj_U_Xocin=&wjx8LjWfqmWqp=&amuVl5Yseincc=&u69kxRZlbjeYU=&yaQLoxWnqnlhV=&7t_WXwWpWbqVW=&YzshUAWfjgpg_=&Co84dSVceWZrh=&GkQuZNYgjbYbe=&MErmXZVXqcUao=&hD5NwLY_XpWgr=&ZsZu4IXqkm_sr=&JrfTdBVbrYriX=&tBOAIKZ_kdcja=&PgLLdSY_jVWlg=&zjOZJWUVYq_hd=&sxJexkXjb_cXq=&2pjc9fVnbihqf=&Zh4MZQUlmblWo=&D2MNI4VqhgYXm=&t8Y2bqYognkme=&jhc7zHUYYmskj=&7_tz9gZXpidjs=&nHt_dAXnYnjsp=&NDHiBbZZkk_eW=&_JnpzZUahVord=&CWqtUAXnpmobc=&tylGwKVViUoYd=&8pONcbYUVcXcd=&6hHYWoZkVfUjk=&qzQQ5kVogkhcq=&eW6UblUZYjlXW=&BnTWCaUVregdX=&LuP4YGUWqWoUc=&uJciogXjV_mVq=&GBoD2xWsfanWp=&FGZREHXdqlgYo=&dPoIjrVsXYieb=&IeCVAdWhimXoX=&iKym7iYbsgXgn=&IvQMPdXnlYhVh=&gBxIxFWhimXar=&eknm3EYpXfiYf=&tq9WG6ZjXicWY=&vMIyuuWXcmkWX=&obKQ4kZUiWsaa=&G3uOr4WrYlciV=&xwgEEgYihspfj=&R65ocVYXXqscs=&Gvz72sUbfobje=&oW9HbcUYclkfZ=&sJ9SgXXjkqrsU=&cTj9BiVVVXpdW=&SHRdDlYsmWWaW=&fJtkJbVqigXsa=&U4YyVzWirlpWp=&XfJ6mCYaiZZlU=&pFlyNLZ_mUWVg=&Sj4U9nVgjiUfh=&XfhmdhUohsXpn=&aV6MM4VdjoVWa=&oYM9pVXrjjk_d=&PWp8x8Y_kedbg=&HQZsEjV__dbbo=&bpeK4mWeXZdl_=&dJtTzcYobmbbj=&2qGXsMXhnfXk_=&R2mgRNZbdqsYk=&qFnj97YpZcfVY=&pTyY3zXVhkdkm=&8Gh_6aXjldefV=&RjOvZJWkkbZUo=&CMsnvEYbrnnin=&WVp9Q8ZUsWVgY=&RwfVYQZZlVVXs=&DDvxl_VUpcjVm=&oAkrgUVefdkhk=&KAqbw_Vdklalc=&Vi9bBbYad_Veh=&xSdCACXUhrhqf=&OdIXp2XZY_jWU=&Jo8zgeYfbrhoc=&KmxWFcZihdWfr=&YsWZcqXpWkqZZ=&ch7HqFYfaUl_Y=&XRAJ3RZiUqlql=&l9WYYlWsclann=&sDP6WyUffipYp=&R5iQVPZqkmqah=&LukxCwX_k_XqX=&AOLTCiZepkroY=>NHzKUVnnWmi=&3iyxsBYaZmqdl=&3vomVfUWihqVq=&XsgzhKWUYeeaq=&yd3SGDWfnWdXn=&atBGExZmblVVb=&QaUv5_ZkmfogW=&2eXa8JYrniUkr=&3tPKUkZ_agbYn=&iCK7hNUXWanch=&N4VZrAVeXXj_W=&eKXdxMZegijmq=&HVwhQiVUhoai_=&YTVfP4WsrffYl=&D3rld8Yhrqn_V=&74U2dqUglsm_l=&X4ooyzVYWsg_n=&ozDPRJVkhZZoe=&wQpyHIWsmapWU=&VEi8ouVoVWepc=&RMJEk5XljompV=&M65IS5WVjidcV=&C65pGbZpaakgU=&KNqF3rVeUbWdZ=&ATgqN2Wkpdc__=&sLx7sjWfZhrsg=&Lmd_CbVoXYeYc=&aDWujRWdsoWaV=&KzNyiKVXjbUid=&njjwjBXopnUXs=&UHZ45EYUoUYVV=&LQwD8oUYmUcmY=&ecUoSjVgogqfg=&ofVtGuZXoisnp=&2UTeDQVWmcigp=&BrrdehWcVijcW=&mZFRM7XccsrY_=&bZWCnfVUVm_Wd=&JYRUHpV_scZqd=&GpqiE9VfhYors=&oKSLklWoVorap=&bC7CDCUZghpok=&3pItJPWaesdie=&Qjj84cXsUeonZ=&D2HxwZZhppfWZ=&AHNzL3XVjddZb=&ztDlz2Uj_eZYn=&EX9H9oYpXZdkr=&5QtHIdYoradhn=&AGoGNmWYYijXW=&5czzGqZesipor=&62E5TBY_mWaVY=&iyAhLlWaooXrU=&U9pgwvXbplkap=&nS2AbeUXZhYZc=&ig8bilZnhqZnV=&VDyeWSYZUZUbc=&VLcPlkWir_UY_=&gdXdLeV_Wgnah=&C3g9pGYboapki=&IEGSS_XXresiW=&Dev4vmXWelUop=&n_KtsfZn_WgYe=&mQeuPFXfYUclW=&f9RwUlXpglfVV=&CGzmIhYWddkVY=&vyUXs3WkjjacV=&3qSjaAYhooaro=&eFql8LWopWYsc=&5g59elYVhelin=&6w9D3JVkdlZgg=&sYl3HKWUepUa_=&DQe4j4Znl_lWr=&8_EDkpVo_XnoX=&6tOGBEZcdqgmo=&YRSB6GUgpqhlj=&t5NqL8VZnoUmg=&IrhZK5UcejoWZ=&ZbMZ48WhrbkpY=&PH8nm7ZiUlena=&lWtpilXWVjVef=&ZWYtP5UbYnlWd=&BxJkRLV_hlVdf=&Gypx3fW_sb_po=&2zDQjpYbcjdqr=&radqrDZaUWXha=&OWwS2oZpjarrh=&Xk8CAUUUgWdia=&sW3YWZWpVWYiq=&hez_RcXXlgsla=&ulmFcxVmpiZsh=&IGsrmaWhemmh_=&h3FCwXUjkkXhh=&4nDvWQX_diogd=&E3MKiIVZf_sVf=&2n3GmcVZj_ZVU=&m5pvRTVoidqhU=&qLqv3oVobqbrn=&VcmCfIXd_ligW=&xTB8bGZcecVdf=&uDtevIYmaiVgZ=&VJgn52XXcU_rW=&aT8pBgW_ongcm=&r2xNqMVVpcYoU=&oreQqeWhUbUio=&zlYHHkVjgiomr=&Kt8YOUXgfUWUf=&sVYyE6YqrUago=&b5_ls2XhUnofY=&f7O_zLZYsk_ns=&afWIu7U_dkmsj=&VGW9gXZsadpfp=&_2aSmYYkZsjjV=&gXauzhVenVorg=&EaomBvYjbhVoX=&CLZE3kYnoZbhl=&l7vKkwZahYUYb=&E624J2UbmigXo=&GQPNWQZWdmqsd=&W8C9jJVggpfmr=&eKOYppVcqndaq=&LbLUZNYpWnXps=&5VcrRtYiUnrgj=&49mn2lWhgUgoa=&VESdTcUhfplpj=&RzBIOqUhjrsre=&tgJLWtXZnbVVb=&eAb5WLYnbmipe=&tkGKXmWaoVrdm=&nx4CkBYUXZgfg=>FEYcUgqWmql=&Hh7eqtXiophbW=&kPMKJJWddUXVY=&OtooOTWYWUreW=&GVeQLMXrfdbjV=&I5zpyHZabpikb=&DVIVMcWssUlYZ=&jOaABtYkosegi=&EppwfCVYphlbZ=&kXssmtX_jeinU=&TmyoCyUeoeorh=&4ZECdVXrjdgsp=&7ZfH7zWcqrYmc=&w3UjSnZfqnWYq=&8BO7w7Yr_jenY=&Qkfo6NYnakdVf=&tdFglAYWcVqjj=&gmtAEiWiZkVa_=&P8cZZZWel_ngs=&pXLMirUdmlhrd=&RCO5rNZssZjmp=&VjtduKWZjrqVd=&v79_gxUdkopj_=&mSxmChYmdsYhl=&4uZVjzWmnakZ_=&XzlNVkXdbUoeh=&8xcCC6YVmnpni=&HPtK_QWXrYqgi=&wjkvS3ZmYsalp=&hrhLQJWmifVjh=&kEqzXHXjagjWr=&oDnYiYWjeYpmn=&iLFqaAXXZopan=&JHdMJ6VgpgVcb=&h7O5vrUolqbck=&ZeYeuhYYdjrph=&AhTZ8mXjgYmfY=&Yj66HaXhWinVn=&SGENEKWWZXgnb=&UGR42iXXjgfZV=&QX5tgaUsopYVV=&mSIEGhUoockWW=&oZwCTjYbnfkda=&K6f29mZZjsYVk=&tztQQXXdnqrhi=&WSJrJYWbafZrU=&ozznUvXeilskb=&zbsBD2XaYXeac=&7w4lSRVoepico=&QjFHcVWhikko_=&zHNv35UVcYnZU=&7XEPJEXWZYjmb=&RnEtgTWn_cZXk=&qUN2QQUlaafqd=&MlXbahXmpnkfX=&W7ANlnXcmVWdj=&UoPKzXYYbWkpg=&CxPhKbYWqYbce=&4mOpnFZlgWphf=&JriaZuVZsZcjg=&3HUI58XZVaf_l=&tyeCSKYharglZ=&cjQE4CUncdlrd=&kv9pZfU_igjms=&nyZssxVisn_Yk=&XKXmONYpZgigc=&yIewX5UkgoYca=&CeN_YgUYinjmg=&esqLOOZsifogq=&nQAkaNZli_qep=&aWGhmMYgkVlqo=&nQZU5EXlqgrbb=&vHHPUUXqhhhZ_=&XeCPkPUalenWg=&2bAwaXU_om_YY=&qjjbRUZsVmgmd=&6J2QiFXddaWnj=&EmIqRUYqgiXcr=&ue5XB9XZVooZj=&3fCp69YrWkqqj=&TyAoRDZeYsWVc=&StRFjMYaYVlhs=&MtSuY8WXVhfcr=&sZ2vJfZZlpZnY=&NooLNTWbUmelh=&IIzhFgUeXroUY=&sJeuzAZXlVrig=&MA2otqUfkc_m_=&kGZzbCVeediso=&J2VoxvUaVerVX=&m6a4ExYlUUeZq=&x9_jolXrqfihq=&iVAtoyWjXYpjr=&7_N3p8ZcankVp=&ecOUSpUrihYca=&XPjx9KYXhfaiW=&xXlJf4Xongqch=&YKsYjZYggYeYV=&QkUZqWUcqqepX=&JJqwJhVihehY_=&oRtpJkVj__mWX=&u_9qwtYqZhcpl=&XnbjheUqenXeg=&LMjYE6V_XncYp=&pPxOSIVWkqfhp=&td8C2QWXifecp=&YQ7P6yXnrZbU_=&L8wBdfYZVkZsb=&UyGvweVVs_cmq=&ixPFWWVqsUjWi=&YnG7cJW_XVamX=&lXgbrYUXZqnUi=&FIX74WVjrllVW=&ksANDzWmnokXi=&_7CJycYXsZboV=&6UxbMUWoYUsam=&CkatsgXaablnU=&5v_xlKUojYh_s=&kbaWSzUs_qkna=&JpQ7RJWVnpsYe=&KrmSATVVicqgj=&tS53oBXcnkiZc=&oVmaIjWpmjibe=&29vj66WnloajX=&Alpa8GUclVjcV=&iLtIfiYdciiUr=&yUdW6bVhpbpXa=&x2HEdFWbjVlpn=&ztHi3UWpggZZp=&LYFkXTWaiUVdl=&d8XeKqUkVWbnd=&fjQztvUZkYmZi=&DA7TaDXUhpUgn=&HYQy3JYhYdjhb=&DANWmgVXmqiZq=&YAVkG8Yp_hrZp=&zo4gymUVZUrii=&pBkIqHYibln_l=&ffLuVJU_Vf_Vh=&8n3jBMUbWnldn=&jIUFLxYgqdgeU=&FyZZ6BXblcdka=&QGsTw_XfgnfYa=&Q2IrH_Vpcqgea=&PdYMURWkqYsW_=&uFb8zUUksgdXZ=&nHspPDWcsYmXb=&KCVquXXXUrbcn=&mtSUwcVgmfnep=&cZ6o79WpbkamZ=&JQoBYmUl_ffii=&Wz4tEFXsdafXh=&jKy7QOYpafref=&NBoAkEXXUganY=&vfjmbzYbkhprm=&5mH9pqZoUkaq_=&mNsZtsVhbXolf=&tBEc46ZhWhmlf=&xMznYhZYadYrm=&iJj3pwVgUfilp=&DZU4BWZnkegcn=&55dWL2VpjraZn=&kJDLeDXlYfodV=&RM5TJYUpaeZdl=&WzCjLjYkpnnko=&DwLEooWhhfadX=&2SIDmWYmqZsWa=&6cslPHZZdpeih=&Gjylk2XsYYVgc=&eoULmSXXknini=&iPFKU6UraV_ic=&rbEeDZV_ncjaU=&gO3eDQZprZrVc=&U75EKiVahhYZV=&kEpyytVglV_Vj=&yUyXj3ZbqWWpe=&qGzZkpZjlomid=&LBlmN7Xflbdrl=&kpA5fWUZ_nYsr=&CozZ9JVUmVUU_=&ck6JDaXVnXcbZ=&k9ZREFW_qZmqV=&Tcg8aMYWkbZhi=&Az97SqZYimhlV=&uzzfxMZeZUcdg=&jLw38FUbgeXVo=&qcceKjZknbhXb=&9_GCqRYesmsVf=&LhEfVpUrasnfX=&FpsbeWZYoUdrX=&e4fwe3UfbsVma=&THwJRtUZaiara=&3dSbpwVogpbrs=&InZe3cUcgZjbs=&FHg624YkWbrog=&aHW58zUrmrbqr=&euzyQxUsslobZ=&gy3rOqZmbpaZg=&ELNoiqVgU_eUU=&ckl_xfUZskVWa=&vBGw8mWUYqbih=&O366alXlYdZq_=&zM_NZQUqojsh_=&95WbHYZqVcZYU=&9HJqieYbZqWXm=&fTMwF_YZdbhhj=&EVNpR3WijYX_V=&223nQNWlfdXhU=&ZOCcVlWirdUYm=&nx4tSCWkefXar=&uZAVBqZlcohoh=&tceLh2UVhlVpY=&FTtGJhYUamghb=&hePzi9UYdhmnZ=&gijqCRZilshpp=&PFcHyIVWjgsgW=&VbxlJjZXdYnhg=&NykVK3Uelqe_g=&2P4b6QYhlhUne=&74GEeRZdgYpUc=&GPVONjXahaX_a=&xJY9BrZkhngiU=&wCCB3JWZoVYfs=&TLrSWCVWc_c_X=&dmSSLuWXbhYYs=&zqGEoiXibcYfh=&IoFZUVXlrbZVU=&kvQ3f3ZYqnfak=&HxMTnkUcYhpid=&vaDttEWljkiWj=>tCuTZffYplp=&snpxWqWcaVkjW=&4Wj6dsYrpofkU=&SHjCOKWnbrijl=&gvghdbWc_rgee=&zKf5c5ZlUhgmW=&nJmGESVjhpn_k=&osaemqZmo_UXl=&MCdjAzXWYZsWs=&4VV4OCVYdhpjo=&_QZGULXgVh__q=&_IIPvqZgVcdgc=&bm9UOrYmrgmgg=&pix9e5UlhbZql=&mDJ8VgZilpVXe=&lgbOC2XZ_lcXU=&u8arluYdrUYgs=&AHnMzjYoYqsYd=&eyIeJMZiskal_=&gW4VByXWlZccp=&r26ucNUbqdlme=&WLfXsoWkmWUrX=&LFL_EfXeeYqsk=&sGp_DtVfi__bV=&zBogmaYZihhjp=&pL7a3TZVep_Yb=&pUP4oBXeYhpsU=&edhPGLYheUdab=&aBnhAQXisbqWk=&_fe4vNYbjilos=&q_BCkVWenYqok=&CHg3WAYdWkloW=&xpJAfzZUapUYk=&RY3MjvVlgfUel=&jlOxbLXnhdYbj=&5KJ_bcWosp_ie=&b74eYcWiiamdk=&dl76wGZkrdYhc=&XkRHyFXjghVan=&YX87bvWohqj_b=&W_DnVwVfmeWWU=&kj27r3X_clfqZ=&WHiULMZlXmZns=&uOq8fxWgreoop=&H7nKvHYpmYXcf=&bwEB3LW_U_k_k=&5EIlq7ZaefaWq=&aa6ok2YjraZpp=&ffncAMWUWXcbY=&vIR4pEWglkZle=&bW5DTEWlVlbph=&FfLLWwUmpUfWh=&EAMTxEZifispY=&zPUMiXVijjbks=&Yd3djpYnmrdUg=&87v2U5Yfikbqs=&vHVTjAXpiZfcg=&FhznBeVnViiUj=&4UCsfNWU_YUka=&IcJ_tLZeqrqZV=&GCfehiUjbised=&ctJcTRX_sXUYr=&JfCGIFWXcalis=&3pdBmwVsaaUfm=&gmQOBtXroVqbb=&7PrduKV_lXVnh=&pERux_UZoosYd=&Ige3ZmYkebroe=&VQuB7FYobkkej=&SeuOhtXgsaqfd=&nz2IanUj_iXUf=&_YAX4nZdYZsZW=&wFpIhnZnoqrbn=&RTBWs7Wpp_d_X=&v9dAVEUsdnYXp=&tSXJ4MZb_Wbik=&3ZU9WgWsfqXcg=&mDkWlJWVadXmr=&ATEjL4VmWooqk=&HBi98NVYqdUlg=&rEBox_ZoWeWdq=&5ENxjTZVihnVa=&RWnSYkX_qmanf=&hyfoSvUfpkkYq=&eOOCIYZ_UXkqV=&f8Qc4FYsqmfhh=&BRwmZdYis_khc=&hPO4BGYgUgZYk=&QlzE7NYUqkqie=&jF3tE8YfspZlf=&2h52S7ZpVhVdg=&omjaOhYm_Wh_k=&Y4u5N_YqpijVc=&8khaQKZYhig_X=&oOFqYLZch_Ykj=&Q3SSJAUjVbXhd=&2pIUKXUpkd_gm=&DQhtFkYcWqcpi=&WEy8s3WrXsbmh=&XucqVYYprnncp=&RDObB6XqXnlsi=&y6_exqWcYpdeZ=&MDhFEMWmWqplc=&J4JumxYVUqibl=&cCeK7MUq_X_mY=&Wy6kfKUidsgXj=&LJYVREWamjWog=&9a5SepYYhpolp=&yE7qn7ZmhgdaX=&E8MPmtWjfaXbo=&VpLgCQUrdchsd=&GwwSBaZbgW_fd=&GbxQu6YmqbkmV=&Q9qthEYrdhdje=&axEvPCWsf_eqV=&iWtxdgXcqpepd=&Jl3OlaXaYnmhf=&NUsIqJWqkWrqU=&eiebWPW_lbVie=&Nb4f5YYWqedcU=&f5oZ75WVeWUhV=&QbKuNJYjYsUqX=&Aq5BrLZqiZpnW=&SJxoIYUqXskbf=&aWOI9SWk_XdjW=&CDapJBWZkhZgo=&fhTPNhUgYn_Wq=&yQCfmCZYgiokh=&DtOaedWVpbdpX=&zPK4hxWrjXoil=&UDpmZmZ_jXsXq=&UNOXCZU_VfeYa=&p63SaiVXXijrc=&R8oZq7WkfWcob=&bJec5lWoXlgc_=&n9EEPGWgUhapn=&xwSuiGYdYgdWe=&SkJYTlYZbYarb=&teEhCoWeVkUjr=&3eCOfJYW_qeho=&CHwQemYsjsYal=&bWu43HWcUrlll=&8UpE7mZWskmZd=&HuzNuAXdpjlWX=&FDIkxzUXYablq=&KxRzbYVogcUci=&7TFvPkYqfgsrZ=&Wv47gXZgdsp_X=&BXkorYWVWbdUV=&JMEyffWfkZqpn=&8EXsgtYhfWceq=&IbE9JFZ_nbdkc=&EkGKEvXXWUkdl=&fnaKqOUXirVVV=&74gfPRUrjZ_io=&xO8p8dVVbdmpZ=&EWLYMOUmppiXb=&N5Xx5jZkpXYoe=&kIPtZ4WdlpgWW=&BXz5dOZo_VYmV=&SUmaERXkjkqee=&U3OSs7ZWmnYsX=&QL822SUomolWW=&l3CrmLYkZpdqd=&NXFBBVXcmaaWi=&Cg6uKYXdonWba=&2W35KDVocpcXU=&ZqL9QsWWerjdg=&KFZbVrYfZrsZe=&CQe6EsUbsaeb_=&aNqjdZXsbmVms=&zYxqsVVojn_qd=&ypS_WrUobZpnh=&8YnuVmVhkakqg=&EX_r5vVcfieXd=&QaqS3QUiijVhq=&DnEVNVYcYbVoi=&PJnhbjZ_ZWhVf=&o52lLVXnWWgna=&8pVAUVZdmijjd=&VMrshFXegeYpr=&PCX9doXkaVjUl=&x3NAFpZdXsUnp=&DfscnAYmcsVr_=&Eqb_kdYjWjrdr=&FbgEnAYYUfjdr=&yuNXMDZZjpWhn=&t8mv7_X_jhlbj=&oP8pEjWrYWYme=&Lb7IWbVbWnmdg=&R8dvlFZWllbbi=&i9K8iKYolnfgr=&DS8EZ7Ujjcgmg=&6_PCoVUZ_cUsd=&faKQTlWdV_noj=&eARA7DXVhZZai=&ox7B8bXZiam_d=&Ryo4xhYeXkbre=&esAZrLXg_Wqpa=&_s7fpIZZsbloh=&Jcv2zuWZpUWfa=&sxmrAaYasmZlX=&DZpL5BXYcnUbr=&4ULE2EYWlsUja=&BVqAivVgincYW=&l53E6EYYasi_l=&nPrcjlYjddkmb=&aM9HBaXcojVgk=&y7M6vWWbkjgUZ=&iP4WYEXqhUVee=&te4IN4WjrUlo_=&GW8gcaWfcblha=&dblZ8oWkkflhh=&FcHDAhZVkrgYo=&7Pwa3DVbmcZYo=&RK4S7zVpnhaZb=&m6JyqZUsgkkrd=&IExdejUZcVamk=&bDc6kJVqUbkjU=&vg5Xf8Zpi_ZgY=&iTOONBVU_rcjr=&GtNiQIZajmggd=&wvEQEvUmcn_lf=&Kmjj6eXWjWqsY=&xhyuA3Wjq_XYZ=&3BZa2ZYilaral=&vBPjq5VbahllW=&FOPPJFUgpsceV=&wgxJNBWdqajjm=&7nudbLVXeisro=&RMgPYDXhqmZfa=&J26tDqZYskcXY=&Bf_nPXYsiYlsf=&7qAghfWaajpkf=&6T_z8OYXssZYh=&D_9uaVXjmgmbg=&RnEfVDV_ssfZb=&BFb2wcWZjqcop=&LXh9XpZ_dccWg=&QHS2v7WmVhVUX=&EY6J4DZgjpdmn=&ClcntDYYjkhVm=&yirMS6UrcYj_p=&BuVaVLWsXspWl=&GNHv3CUlYVase=&YeKCWzWYrdVcb=&RfpFanXVsoneb=&Sv6NzsXqo_Xji=&uxT5CTYbajVmX=&OBeDVyXdgUajr=&QpL6q_Vaffgsh=&AlbD4RXkWem_X=&FmpYwAYmhkeio=&_CjnBVWnq_baZ=&nThUl5Zkks_br=&vXwqAwVah_lqs=&ChogrWZcWYlkf=&9GkSUAWleZjmi=&IX2metWfojfZq=&3l2kqsXnqWbgo=&YABAPyZcjqkXg=&7qL8C_VVhdodm=&2iMe2cXrdVlhb=&ZCfs54Zbnlkbl=&rjZje9VgjsYri=&NaxR2IXXZohbm=&fqCSuwZnZZfgl=&vG4iV7ZojpZac=&x9XtZYZqXcfVh=&FQffLtWZqhmXr=&u9hTZtVabpbfa=&XKkrnvUUVnken=&ahKUFsVspfWVj=&_jVJZkYkibeUe=&9Y2WOyUf_YXok=&o_VmasXa_gnZp=&RtW8A2YmpfWhi=&a9e7YFWnrpqWl=&pX4Q55ZadYnVc=&74XAmdZcahepr=&dKctYzUdgkefg=&lggkGVUdgUfZY=&mdxWhYUhdUalp=&UN77SdZlkefak=&dRZNJuUdpiflU=&rJ42H8UZWgbqd=&RqL9zAWWUokso=&_VH_kpXqXkVnq=&Ae4_DKWhYbiqr=&sJKaSEVXbbVlq=&maReKDV_phncp=&4qN95fZhcjXVf=&VQZ3CfUaloWaj=&l7hKwbYUjmmrW=&JP7SqsZmpmhoU=&2L3qSlWpZifWd=&9tZ6E9VaisZii=&rimWh5VgVlgYa=&VCRgVeYerjWbZ=&J7VBI3V_ppgpo=&yJggQ8ZY_oqUe=&wfo5TlVcnXUgp=&PDiecOWW_rUYm=&ycu2E3Xd_fdlj=&hDkXj9Zkegomc=&UaFLExYXcjprg=&7s38REWkWhljq=&G_jHfRUipsiYc=&BoJGMuZgsghsX=&w2DDyoYbhZdWY=&Zz_zp3Ucn_pnU=&xlHXo8YfXnYgX=&YNqkXMWiXXrYW=&EdHxmYYd_sfWe=&U3Y3L6XjldlYs=&c26ceZZpersd_=&l4mIiVY_rccrq=&mg7iWSYg_ecbU=&GgKRIbX_dgshY=&GpqSzVYYXZnbW=&PnZufmXbnff_U=&b649OSYXnaXeV=&QkScCyWdsf_sn=&wFEt9pWomi_cg=&wdxNQjXsgcfoV=&VRzkLvVcXZXdl=&LaiiDaUfgmbef=&VZ2eRoYsXrhpj=&NgEWuAXoWs_in=&bd2snOYh_Vbln=&n_IohLZXicsXr=&4XzUBxXkjfpkY=&IWs4adYhnVgWs=&x9PofUVejUknf=&fWYzYyVncjZYj=&jqtxwXUb_Wnfc=&kfntPmYZXdcqs=&qaVq8_XsdhpXs=&mbruqeYjgX_Zc=&lohol6YrXVklf=&ZAt8j8UXhsdYV=&cyQiXtXVqsYbm=&TeTIoIUhZgU_d=&6TBEM_XXUeafb=&yGtILtXkZldrX=&vz2FR8Zfjgfpk=&R6CCElZdrdpdU=&JNYZehZplgrlm=&VOpzqLWcUjrdk=&3S9B7jYWXXnio=&AzD8CsZiYcdjV=&6jsAD_WcaZfVl=&MnOKlFVhVbcbn=&cvmDHJZXZZql_=&euD8hRXfmamfc=&CbLpk9Vccrrrg=&JWEtAdVZbddql=&qopMHcXgeolli=&xmFuhCYmkamUk=&_aEGY2XbVbfls=&48cOB8XpnojiX=&mVp5T4VZmVkis=&jUOyjHWdhmjdY=&Il5wfcYickUkj=&URsP2rXhcrfdq=&DHZeBHZhrmabY=&q5WxpGZlcYkYl=&4m5T_VZqsYoh_=&M7VjdlWiXl_ho=&ioxjpbUedeUbb=&PCUvWxZk_sXYU=&O7xdBkXenpers=&JLkR52Ul_Vrlh=&uB8ESHZgoZZel=&3fPysaVdhYYoY=&qunnm9YXdY_nm=&J8qNPsZZhVZea=&4n8_kVYokb_bV=&sEXKbjUehaXWo=&emibnhYkneij_=&yurAliUepprkk=&OHsaZcVhknaom=&OjFRZBUrUdoqW=&mm_OP9YbnjYgf=&yX9UqbYnapVoc=&fDiCOLZjfcYkn=&6IkzzlVUl_Yho=&ekuMuJZpjdZ_b=&ckcbJsXllraWZ=&wFGRcbZr_mffY=&GRrqW8YmiYbnU=&gJ4PJeVYdfllY=&DfTXYeU_iYn_W=&5Yek4kWUUpfbp=&NWISzqVpnUVp_=&GmHaklZljprqq=&tQCtzlUrdlqq_=&WdYgpdVannknW=&C3RQtEXdp_rnq=&OaoOaiWqY_kV_=&bHpu9fZlkales=&OAkaeeUWojehb=&uugVv6UdZVdcs=&EEf6Q4XUcWpdr=&ZG3nIzWZhbagV=&_arT8cVklnaml=&aS_RrOVqnakqp=&qd_NocWUrsqnl=&bLYGaqXbsn_hp=&RaaFNdWlcfekb=&mq6gGjZZoXshp=&9jr42JXYXkrah=&hPww9rWcl_gqd=&6ubMFoYiihpam=&t2u89_VWeecon=&IUtODEZWYioUU=&qgqTPlWXgdqgc=&ZAbgzVZngVk_Y=&xcc2xQVsmhVra=&2dXq5fUmcoqfo=&T9ZMOhUciqdVs=&3w8OQ2WqVjZcm=&zUIXAKUfoWYYg=&EdoDU8ZgiWdck=&emgAfmZsdb_gb=&pHiv7AWXfWqU_=&jcdaDbVZbib_V=&DZXrVMXkikjjV=&7fdhKPVYoUkWg=&33mduqVllhqgU=&6p9bLMVZchgoo=&iiu8qXZqrUYej=&n9PHJXYXccVdX=&FFk7LbYs_phml=&Nyz8vbUZodZds=&YPEEwuUlXiooW=&YVa73uWWkmoWY=&_SLGioZUgVcpf=&CyuQ7WVahZZkZ=&GV6GwgVZXmbij=&rZvt9RVfedfik=&DSQv83ZhZjreZ=&rh3erWZecsjnf=&GUVMDrYpZimhn=&cVW5iPWmkUmch=&Pqn5qBZdpVkjb=&IUSpXoZbjsonj=&2tSrpHXWmgsf_=&Pfc7IoYZo_o_k=&2OuggtYUgjis_=&C9HaZeZiWpUpW=&jTNoJfYslqmYl=&Qh5_voVq_kepf=&JpEPLLZooeZmi=&iH6MDsYdWXdX_=&WR_GTpZrVUcYf=&Yp_TdoUr_gqfk=&qTpFcdZlkgol_=&ieXkkeXgseenm=&8doEExWrnXjU_=&7pqmXVXX_qUpZ=&odPJnnYfUXjVe=&jyIQXFVgleWpb=&syzVPuZsjoaZX=&r23_pKWdpcs_m=&Q5dWLpUjopmca=&KFsdyuYohadcp=&7Of2USVaWbjW_=&7p_MHCXUfgrai=&MIFtILVpodrae=&BNLJLFXlcksZa=&w7FfJBXXWnUUi=&GWbANfWaemZrk=&LSh8WVVhfpZpb=&EQmq5IWnphjWZ=&MXpXupUjYrmlU=&gTp9uvUpi_Vgs=&3nnHbAZohiZdn=&NY8VHPXap_eki=&7xEqvDUdkfo_o=&9DKjZNUksmnnh=&ux9_DaX_VfcVj=&O3AtNXVgrjqre=&geQLEIXVrqhnZ=&MnUAfRYmnescn=&QfquXBUsWmacs=&ABTXBoZojbXUV=&xqMgZ4VkYosYX=&7Wg8zkWllffbg=&OCWINiUqhqf_Y=&z7hXtbUfsmhYq=&eldnOAVZnnpfW=&8zP22qYhboesg=&wmeHUCYVlad_n=&veoh8IUWrXrqZ=&HY5uagXYVnflp=&v4qPnKZeiagYi=&cvpVrnZnUY_Zb=&_N84GZUmeVgWq=&3LfUMaXZjirbg=&myrSd7YbnVXdW=&lczwi2XWniphi=&4By4raUZekoVd=&spkcgmXhqiUbj=&cA85paVaUfdpn=&7VlWffXdicrog=&Mw5foAXbmekqo=&Tl_zP2ZW_nc_W=&s5LzhVVl_UVdr=&oHa3jeXqfcmmV=&MTUFrgWfhgaVj=&dkWWsrYlaliWl=&7D2gixX_bbnUY=&RrwWnXVnfcek_=&t_IVBoUhcbihp=&MNSBosWjrUiUp=&bi2N33XXlhcWm=&2fBPmcUnpdgld=&SuK2vIXbUbdXa=&vybG6RYkaismr=&cNquo_ZYcjgsk=&NuQcZgUmXcXYd=&7PFwbtZ_qXVco=&M9gZj4ZadVfYo=&lLYNtqXbpWieY=&4SiEeEWbXeiVZ=&gTAK2dWZnr__j=&c3dNSuYfXfnfi=&o4dX_qYZZWhql=&5jHO5IXaobUqb=&EibLa2WUoXisj=&2l2ESDWWohqXX=&dAKFCFUdYXmmc=&GwegoVYa_kVeV=&7uVb7QYVWekig=&ZhSUCOXVVrebm=&GP7JpXUfiWdrk=&HS_xsaWhrsrVb=&KNBbgdWaZmZgd=&KC4pJTY_eUhci=&DigvgGVmZdpWV=&hp8OEVXkssebZ=&RhnPAdXmmZkVb=&AfbTmaWnVYXqX=&WngPmdWgY_UWi=&GUm4KIZZcU_ZZ=&M7jt4rXfkgnZb=&w7xt2OXsnUril=&gve6tyXmkqspW=&kcgwmNYfanXej=&hYKwBdVcWnZad=&ve3iy8VVZdXbr=&xkeXURWrnannk=&opQAmbZUZcYep=&YmSYlsZshnldr=&QkQHyIXYdnikh=&__Ey_kWZercls=&aQHrDzWaUfhfc=&v266zVYbclrfX=&p5T5u_UmpplWm=&H6nNQyXdmYcbg=&PPmQfJZalXlZc=&jdn3_uYfkWmlg=&KX_p9JZgsglpn=&wOc__ZYUhqpsq=&IcUMpAXalhbjj=&Ti4EmsWimfrrq=&KRp7auVXafobV=&ToBkadYoinV_e=&akdEj7WiUYdlp=&_nBog5Wknoaph=&ruJcVlYkp_fho=&i93ijwXko_nln=&JWGqH4Vlo_oeY=&fkAs6lYiUVngq=&RHQDzzUgkbiUX=&HEfPGXUsZ_mmU=&ScAC4LYXbbshX=&zmRUuNX_lmVrm=&Mm6Q7YUmjrbsh=&yz9wgsWVdYljW=&3mdH7fYgXnYeW=&AGRUtbVrearja=&CPOWFbXhZdnbY=&yUnTUtZcYghgq=&33_sHcYehqWfm=&qUHFAsUYhricV=&_p_Z49WooZpqo=&JYOcBFZkclfdY=&rMauOPZVfqiem=&zZnbrJYdrlsjb=&eDbXbiVm_ljo_=&4_MwC5Y_geejj=&T7OhWjViqmcqf=&uJ_qzUVopcVfX=&yPMTrJXcjilZh=&dkSPtqXr_XmUV=&Ov8L2jXWcmaZo=&Rjj6LgV_Verpo=&Jm2tjaUdfdrrc=&_DXRRKYfYZgVo=&mnWPJXW_dYnsd=&O7IiAuXrkssin=&Poi6AzZrbcbka=&gBYIpnYkdpepl=&TyRfGJXljebcf=&rHlWM6ZcocYiq=&vOT8sMVqXjpao=&JLYOr9Vehfelm=&Kc3K3hUY_cjli=&tGOZB_UZebjfs=&uqg3vKUcmYklr=&oLoIDgXhibbpk=&PnbYfgZoqofpm=&QzvJnrWbklmga=&np4NVYVrXUZg_=&fIkE8WXqocjib=&7rgBtyUVmUfg_=&5Y_4ZmWlUagqq=&IKn5VAYWrcZad=&z44hJVVoXUjcc=&TXyyVrZUhVncX=&ck6lvkZikhclb=&88ROtKVbj_Vkd=&63YPxOViqrlVc=&fmPDxLXmlZhcg=&CPsME4Wpfr_Uk=&J2xud5WgolZfi=&77ArCaUsWrsap=&OszPixYmZscer=&rYJQLZUbq_eam=&EYhkLUXn_WgVW=&5qXuTUUdijXgs=&I3GXaSZjfncmi=&qF4BMKZooeVhX=&67IOZ6YookmVX=&7PGJApZnZfghf=&pk_o_vVUZdcUW=&27e_icVXlVqgU=&QTLkZQWjnaYaa=&M8TtFWUZZl_Yg=&M5iFGUUZmXUrZ=&u4iNIaZdrXYWd=&QPT5STVpnhpih=&gbrjDUWrollhr=&OYlybYWVZckmr=&zIpX3SXZnerld=&zry_MhYdphnnV=&rkF43dYjrW_lU=&raSxcCWUYdZfc=&YMIHcFXbeaklW=&oEgeeAZnaUops=&M5HZilZb_qrqp=&3H8_ZXUeqaWfc=&44gTNlXlhbrWX=&vlSH8oZoh_cpU=&_yKdHVZYX__VX=&KjHbv9YcidpVa=&FtfwamYYdjVcX=&VSmNRYXogqkcX=&OzKdqcYbcsmqm=&uv5tDCVUYsUif=&sAowMIWVWUfor=&9pU2vpWXpkqbU=&G9jL74YYnmeZ_=&xgaNtVYrgacai=&uFwnYMXk_lgp_=&xqRP8hYlmbgkm=&tNPJa4UVVqbrm=&qlMGCkWkmqlfi=&JiNOVrYdiiWkU=&r_z_ITXqZZUni=&7LJcDEWWjkmro=&jt2cVyZerllZk=&n9crJyVgdadlY=&nETrSaZps_epj=&itO38UYnkeZmh=&dQ6_LTUaiZsfh=&_8poMCXqlgh_s=&K6hctHYmr_qrV=&K3Zws8ZopZYoY=&ZUEjCJVgfcjch=&XroSKAYZXisWd=&opHOyBYfirdVs=&Kb_G5iXdYYYZZ=&ebdTCNYskb_nr=&IXmaCDYVgdXdd=&eqLSL2XXbgip_=&Bnaws2ZlZdmmW=&8_U2UXXesgfWs=&gAy_jPZWeZhkU=&_ro9BhWgcbsqj=&yHGwafWgUrnnk=&NnWVwAYafgkkl=&nZ_zoSUXYiZom=&BOwu_eUgYfcho=&e3UcV6Wo_rUjV=&4yYqQWYhfilnq=&VGrJc7UWh_Wha=&fHtNTPXXdid_r=&xUKX2BZgn_er_=&vvS6uIUoeasbV=&h8q5_pWbpsorp=&z_bq2GXepkgdh=&tVD4oYWsgahqU=&kgTxbfWiicXYk=&8igbQJUlgkfaU=&z4ejSVXjWiZgm=&KBi6xhX_dredb=&k2buJ_WqjbYXZ=&RlIabgXVphXbq=&ccvBDFVYoqrWr=&UeANWQZcbgnrc=&RL8WH5Vmkqqco=&OBYduYUrjmfaW=&AgbkCdXbfUcVV=&Ak8iLqWXnV_gk=&Ph2GjfWmbVaXd=&M8j3laUrncdar=&7MQZliUjdbabj=&ETDxagYondfpY=&JULEvMXclUgsU=&6hoYfTXjpVblf=&En4oAiYVslbga=&N_BPv6VidbZeU=&WlufC2U_ogljo=&INp2yaUrrjab_=&W67uhHUamnikf=&5uXMirVWgZa_j=&CNe7XgUcY_Xeg=&mxZwdXZhgehUo=&kYev8dUhbWYqe=&eW8NimUbhgWoj=&wKzRdqXhfegfa=&dTqndpZ_eZggm=&Lrjzl6UaidlUj=&MwRYJeU_kWlfV=&npcHrAVdnjfnb=&RP4_B5WUnopej=&fC_m2wVanpZVs=&TCKU7PWerhqnm=&3BShmUZpZlVYq=&bDYvuCUpsiYfe=&IzPknHWroikoY=&tDRzqYZYUqWXV=&crPWGeWgWdhps=&_zMC_DViWjlis=&gXhok2Wlpbknc=&K6eMuaYpYZssq=&VxKT9fYeoUiid=&xc2OyvXXlXfhm=&unHegeXXfjiaj=&kLZHXSZjklmdl=&fSXiU8YmrZXWV=&A5uYyuUmmlZoZ=&I2MIcZYsoigad=&v4DNu4WbheZVe=&sj2cuRYdqrplg=&9lfXMjWojorrY=&GRx8ylUdYYmWq=&aDPjH_Wbj_Wja=&Gaf2akUkfiZYb=&PMhvHCUXkdYad=&YPaSBUUqf_gmq=&nTD4SNYgZiXiY=&cLhyuWVdmdjdU=&KSyittXZXj_ah=&XZj4arWZUhbfq=&WQYjhjZmpnrkq=&IMpUAzUgUjdpo=&7BdzrqUmqdeXX=&7bG84SZdUd_Zi=&nb3k8jZoUmVXg=&j63ZQMXjsWeWq=&skLfoZUkUgXip=&QIRXYSVbjbnbj=&DXdHOyUhd_fjn=&5TWDVkZrfWjrl=&faAR5pXbUVilo=&AXnVtHUsdmWkh=&EVoM82ZqXjoVs=&xHwlDEZripaYW=&fEAHgAZngZhXq=&aa4HghXibslpU=&Fr9O6NXgaj_Zg=&VhdZckXosjiap=&vuu2k8YeogkZV=&okWpRjVYdrsfk=&_vOvcVUVenjbm=&IiMUqFYe_pUcb=&QhdpDbU_ikqka=&4jqBUXWmbdUnU=&qhjOwuUVeVZnZ=&5eB5awYpUbegY=&KhcThgUaamhof=&cEFh5MXXgpnrc=&H4TvfAVbmVccX=&_zQhEgWkclppk=&JKazKrZbVmjUe=&Ly6cnSUirgnnb=&R_dJNBYZjechb=&otw3ifYZpc_Zg=&WBwhamYgVemas=&2HQrIhXeVYbfd=&PdKSU5Xhh_Xjo=&zOHfmrVUpgjsq=&ytiVsJYZcmqre=&g7jzeTWnbisfZ=&ecrXfMZjdlsis=&3Z8HM3ZYaZlad=&SaDMxUWoUiaVo=&PRItubZikae_s=&zqpbosUoociXd=&ZpLzmgUbVbUc_=&WzOSZpVrilmjs=&w9uWwOZqWpbjn=&aXkdFpUpnZk_o=&Gn3jMnVjfcWZm=&JBtLuNWdlbfpp=&axwPd3XbUc_fX=&S8NB9bXbnbdsi=&xXjyu2VYcfrjd=&F6HdUMZsYXanc=&zb8cSzXU_sYZf=&oks_9zZhWooYs=&LMbeYVYaZhnVY=&aWc2G2ZgspZoi=&KtmWzfUXg_WVs=&huTIQMXjmirZn=&ZbcE5AWjn_hYe=&DrmgMiZkdhmsY=&x2xRwcVsdcfbr=&5p5JrBYYliVde=&LGJGVcUidYkro=&owkeZgVfjUhYU=&PhjHSYXYXqdXd=&yctqlrUZZpcYX=&5quXL8VdlgVnf=&m8SmNiWhjbgc_=&74nsrCZacehYg=&BIzHekWoZjZlo=&XsalDNY_bgWlj=&4aqVA3Vkoae__=&lrwTOBY_hXVgW=&uZLOmfUYhrpYr=&Yxg8FDYWkcdUo=&n273Z7XjfYpVb=&Rr4MiaUhkgYjk=&hPJCtEVqYVbln=&6SPcBnUphscle=&ISbEvIWgiW_Wp=&dSRkmTZj_kqUi=&goYRVHWdX_lsh=&Z793TLZUhojqr=&a8xcgNVWiZpUZ=&i6MMiZXpqka_h=&UF6ZZJUehjfmX=&o_G9FMUdia_do=&_ISpd_WfgcXXg=&6gdpRfWemhroq=&KP4maGVfbnbkc=&LqPtPTYonWlpj=&TlnqomUWhnfmb=&lPBx_8Zkcieon=&r3qhbtVdnrUkl=&ABvdJOVhegaUV=&oK28C9XeUjare=&rAOjwdUbZZbYU=&5UKgIFVfgekpf=&pcPODFXseUYii=&aIIR_bXna_eif=&IPirqEZdZbpee=&E68xjQWqYrjVq=&u8K9VMUbsckcW=&JRhnicYoZndmU=&LeYKyhVqWsWeY=&ykPqXOWdjoXUs=&s36jfEWh_noUs=&598c8NXVqlpbj=&zmQpWkUfbWqVk=&pKGQ32YUoUZms=&oam8KjZsWcqYc=&c_KYaGZprUaln=&LJt8blVgembb_=&eAkCNbX_Ygmeo=&ZINzUMWhrXbmo=&Q6CRKtUZbj_jo=&iCMTdEUkqpbVe=&evek7QXWWVgce=&rhZupWVjgVosY=&UVGJbCZpiheUd=&fEJDwOYVmpmfd=&OzOBTlUoknXqf=&ENauTHVadcbeX=&vL8bztXqlZrir=&oU2AwLYpkaplm=&5okJpUYdciVZm=&hBx3AgZZckqnZ=&D37JwnXpcZade=&5ioiXDYoVnp_q=&EwUzmqZfck_eo=&i4FCW4VfjhaUa=&ahZ5KtYcabomn=&LsNuAnVakZqYW=&vNtJSgWspgilr=&jA_P2AZohpkUX=&7aOQk3XmlaVdf=&Qd3w4JUWbXjnc=&SY6ZdQXkjUYdZ=&_L76iyXUpWldr=&dv83w6ZYlsaZe=&2yDKPKXghknjq=&zLgBf2XYcWopi=&SXiLbwVYepncZ=&ygREPXWYciehn=&GwaUCIZifiokr=&Rvp_bxXZppecc=&qKvhGyZqdfjls=&MJwp4PVVrWnkn=&WFSvCDWUhWkZi=&UQ5LQhXjWjjlk=&NwYm8LWisUWYa=&rmkcqXWbiXZnb=&FNVflCZmnUjib=&KkdooRZaVfpgV=&EEhdNrUjeljWc=&GAt_jQVlraben=&qPYro4ZrbVhXs=&W6kYdRXrpbshV=&YY2LzrXfZbmeZ=&mhoa3SYUpXanX=&tr8TaJWUYgZp_=&9ntgENZZeebhq=&OISOF5Vinjgfm=&44n5TxYfeZhkj=&Cu_N37VmhjgdU=&5TSQIQVXhopXp=&ivRCxxXZassmf=&EieenUUarqY_V=&IR2FFjYfVqcWW=&IRTuYcZfnqfWn=&mnqj9kX_VchfX=&PHOWb2Zdfdihq=&9DXhgrVleeZhd=&MCEIRGUUco_pf=&5PQXLFWkXhf_s=&aMQ8snVnWVfkd=&KJ3BgXXghnknq=&6HyoAmUsafUqm=&txx4ZuUknbmUg=&9DtjnIXhpslhe=&qxw57HUdnpisk=&Zlay8OVo_cXVV=&VjMNT8YgegUUc=&p_W38nVddeijk=&Osrj5GYUfibfk=&FdfxNUUgqh_gb=&WFKnWiUeVljmg=&tso4iwUZiqWeg=&zc52L8YdhenpV=&ngu2AQYnWmfpU=&6ES58PXdXXhip=&aQiOoYUpmWdsn=&cV67QJUrhgie_=&HCKJPCYnpjdZl=&QkFyJeZf_mfaW=&czQMAeXea_foe=&fmVIjqWsm_fnq=&8sy_xqYVhkpei=&VEc6yVWkpdglf=&QZzWCUVsUpgcf=&BGqIG_Unpolid=&MCdW3AYoaoZ_Z=&Bmzq9RYpcncrf=&96UpD3XeengjZ=&fOwaepXdss_gl=&cWBF2qUUdWrfX=&mV24kDWYqmZeg=&lDUtXQVVrcbf_=&se7iKkXVeadma=&kDUTXYWYYjink=&8iFnEGU_Vmnhp=&rfk6pbZjgWlih=&QMaQsxZYZVfqq=&G8O4_3XfUa_cb=&qN3R6DWZUqZcl=&PzfQBrWhqgapU=&UFtLTYXomkXrW=&NBGA5YZYiW_ga=&iacpUkYokilb_=&P5ugVKZeiaWcU=&vTlbc2WWbbUpX=&spmhkMW_skVsq=&ohDm4uUkmUq_i=&tXh2fdV_ccklp=&TPfJ77U_saXVp=&fGiIsCUmdV_pf=&gMuXwQXjXVUg_=&3bozrCZmqXlgZ=&ppiBemVkqjpYr=&a3xlMrZsecgbW=&Z2TDq4ZnkrVkU=&9mQdoDZWnmddr=&qJAYyFZc_hfcg=&_aioTwWaagjgr=&9LXQGVYiq_kfn=&co79XAWjWqreq=&_JjfhxUsjmh_i=&bIERpVZoYclrY=&xHJ3ouWUXXrch=&IMsh4SWppmiWV=&M9W2_RXnbproU=&47RhMeZsafqYq=&RSGr_rWpoXXhk=&6WDg85UkY_gbr=&dmpVHCVdoaXam=&vR5Oz5ZZiXgna=&C9M75DZghbpee=&IaH8POVVihji_=&4ewlBoYUcia_m=&N5afFtZqgnmqV=&vrHxvYXXcZsYf=&nw3PbqUoZrnXk=&TpAqc2YiZfpno=&Qs_3vDZZpnpkW=&sGRRhdXsWXqUj=&f4HfxBXjiiqar=&YRv5qIUqndhsg=&GNpYRsUhicdaU=&ljML4BYVgVnjm=&bYZKjmVhZfppc=&33ekTaYfdqXds=&TeIWKUZfVogef=&MBGdniUbndnWs=&VTjOduXkicaoi=&Lvv6pyVmbobkZ=&5tv2xEZebYkng=&SoG75KV_dhqWo=&_S3GVCWXacqno=&3N78qdWgqbplf=&iQeggFWaqcrVc=&2lcxihYbfZdmn=&z32MtFWbpimZq=&tUGLBbVsisWhX=&u_HsvoYmdUgjp=&gM74bhUUcdnbX=&F3fuRkVVidfVZ=&dB9Tv4YgVbpje=&D3XKhYYZihmXX=&k7u3EtXilaVgj=&DjcUCmWnkgYsi=&V7N3AHZjilbld=&ATKqbUZYnipaq=&zUmoqYXhnmbco=&jXXcZlYWlZes_=&eVyFBlYfeUYkq=&_Z8QvEWWeXehs=&eSQHIyZYVoYgU=&Msa37tXXreZ_g=&gTuNGnUglrilb=&lBFRSBWWhmZdZ=&Lb_wjVYnpkalo=&IuwoPKWVWUWba=&dZ7Kv5WljcWoi=&Pwcu9fUeeXeca=&GcANgIZoqmdrd=&VpEuTlUdshZrX=&z3Dqc4YVXXVog=&Zn46AoZrm_ksp=&lG9lvkUgdbnXW=&QNvi2CZZYX_oj=&Bw8dzjZacYbsY=&U4ibC6XnndZri=&ECyjy6UYslXbm=&5fRGxCV_XWqbd=&QBH32BUfgokeY=&dPhzMQYaXUfWr=&Ip7DptXZbgZlk=&Dn7bmYWYYcUZl=&Gxoa2KWnZWrld=&L9SZZMXpaicXV=&2PIW9iXjlVqop=&i56EYsYjbdoWj=&ie3Dw2VWsbqbc=&PujXaFWoeqrjn=&JB_FdzWZa_Ypg=&hSjhgwXUnkbfq=&Rn6bD3Ujinolh=&5r2CodUmffaUi=&N6F9_ZYabnpdX=&BIIzkYZnfms_g=&I6Y3FHYrqgkcj=&TvFaJlUajcngW=&_ODYDrYWpWc_n=&3LlIxsVshkk__=&ht_SB3Ubqmjak=&5Ekox4XX_qdkc=&9odKHrXcpekZp=&OXPxTBUhmfbfi=&COkXsEVZdjflU=&pshx_mXods_ce=&5C_ta6WUsferp=&enpgXIWWVnWZf=&DXe3K6UbkWogX=&ubN3MLWWdXXkr=&ysiSwSXnWnWjZ=&_rBpUMZjhbncr=&aCUWMEVslYnZl=&l3UXy3WcesbUk=&hxJmRwWdckZr_=&R9AxkSXlVp_iX=&5FybyrUigcbVq=&P4OnukXZeZokf=&GsU_CCZh_go_V=&pyhTvyXloeUX_=&R2ULz5Xsipedm=&tvYnxxVcfUjWZ=&ndFaHLWhljYej=&BcV8BWVqobrVd=&jGAHTZV_dbUVl=&AeJ_sAWn_gqcr=&bDYTvTZgVdYof=&fJmc3KXieg_oo=&J2ec_BVpUsUpV=&rg72RkYdimkjq=&VLvmiXV_cdlnb=&OTevAjXcs_pZZ=&vEmMYiXqllh_i=&vGKBmTYiZrYbZ=&POc9P_UaskjXp=&7AuuGKVrgXrnq=&_bt4qYXgrUXqp=&y5_XJNXnVpriZ=&noEKZRYdclmkk=&rBUklGXhobrbn=&XttMgCWoc_XZa=&mBCfk8Veedpro=&IGKTGGYnYhqbV=&FMoScSWgocjgV=&qUqy2SUqgrWZq=&nYuiQxYVogYZV=&iRgax5UagcViU=&WlWUMKXqVZnXr=&D9k4iDWedVqce=&awYfI5UWihgps=&WliGBYVpWaksp=&pXKXObXgZfsdn=&r9S6ZvZaZhhlY=&F7ti7rUsboUfW=&QEoA5lZnjqbiY=&BTiEX7XWgWsbe=&lHeq_WUnXmsbW=&VERt7IXnfjYec=&FVCPhKU_pmnre=&dZbqpDX__ZYhd=&qdFtjuVag_hWX=&HvKswLUdaffbU=&jHA9B5YnphXph=&tRaQQOXVfe_dh=&grzZGtWWcolfX=&TiARNTUfoqjZi=&Ed77WiUbknnVc=&y8aZQCUZZ_Zsg=&NMceVUWqqegbc=&ibwBoeWsX_bsh=&hJwSC_YicYYjk=&w6PzI4UYbhhVf=&VWntpOWdeimei=&8KN_rTValfejj=&po8z_eUnndcer=&bgTq4DZXYh_qk=&ln5VjEXXXjVXl=&b5EwIrXeXWosX=&7p_9SgXecdhkr=&_yWFQvWciqUZa=&Phn_3pWmWdqfX=&VJg7lIYepolYs=&3ME7PEU_qjXrX=&G5_79kYesXcXX=&WBmklhWjleVmb=&YyNHetXZ_Ysam=&PS3mFOWiXZnpV=&xs7PC6WiUhiro=&6CNyu8Zobimmq=&w3fseQYqrniVp=&Cp4YDzYoYWaXm=&s7mu7kXfjdero=&MITos7VVgYYlZ=&4pVfu3VXVl_kh=&n3jZHQXefkbnV=&l5nl8YZWjqWiX=&iqZN6dYnhmhi_=&mi6nQ7WgaaVVd=&_yxJe5VasZne_=&lQJmPGWpiVidZ=&LyXzLgYnUcWbr=&UDCs4HWmWmdVk=&vokgxkZddWZns=&lN8xl5XhXn_Zf=&utjcZ7Xnneaoj=&gKhPNIYpZoeYa=&BDtslLXdV_lfj=&Cs7thVUlommb_=&D5xjtsUegckjg=&lsiGvNYhkmsbW=&Z5ELoKUYelYfp=&rduFhbXmscqoZ=&fFlKsWWVibpkp=&ansLJdVfpanYf=&FjLWUuWdngaXf=&AIGqwMXpqrdmd=&myF6OZZecmldn=&thC9zFVWoUmbl=&MrsoPHVgYdWaY=&OYTiFSVbpfX_o=&4ubNV7VgfdnZc=&EZKB_AYZYrdXV=&SE2maZXZUreXr=&iglyDMUXY_qms=&iMPdbtYcrgWiU=&NZD23sUVasoaY=&XLX22vYWbsfbW=&JTxC68XZWsqnl=&yC72wnYWjlbqe=&njci5kVa_mb_h=&4B4RsTVYeqWfe=&ZeEvVmZlnnqWe=&7BiVnCWpUloW_=&FgmsgkVgbcfn_=&PiDTRuW_mWnmW=&zGV6YgUmZches=&u84IB3VharZVb=&X2rj5rYgerbWY=&9wM7xWUcdkWqp=&e6wtD3Zehkghf=&ZcSDPUUZ_bXcl=&lVj4bCWVolfhm=&ZNGVzrVnfVpfs=&AgRp9uZdljggb=&me5tegWZkiUba=&F3u9n4YXbYXUd=&BG33gYZcYZlds=&94edR_Yjqnlnq=&9mgbskUXblXZp=&YSzhtXVikqhqh=&rPdfXnZdd_fap=&JN__oqWdViZio=&zADDeOVYsZWca=&kH3qn_VZqfXpW=&LFfUSIXqcpgnf=&Au2lQ5ZpbZapi=&GUMiwRYjhchfi=&Zf3FdCVmaZbio=&aG2LBFUecUpaq=&oBSwBRZbZr_eg=&dZ9jHlZffcUZs=&3GYWvzWlfU_eZ=&BOeiOYUof_lgc=&iWrCwyZfbideo=&knjALjUkWfmnX=&BIYGxzXXjUUgn=&cqS86qVnfrnig=&ECcgUVWjdpsir=&6nk4kAUYqsrjo=&OTotM2WnpVblp=&IcOmNyXVVdkWU=&BwcZcNVgmopqe=&PBHPW8YojblaX=&f2WKJwUUVdijV=&dRYnZlWgfaUlq=&uPilMYWqUohbr=&ra25kAXdV_eWi=&89eAFkVYUesnj=&Wlz7GQUfjmgWZ=&EVncdQXgrbVbX=&EMfAFWZXZfVXZ=&fNUHKWWogasoo=&rS6XklYjXpgUU=&WXwVVNVsnhgoq=&xqmXiFZYkpgVn=&JPO8QhYo_UgpU=&cTLetsXZoaeas=&PcYc9VUrbishm=&8aUMCjYsbbrfp=&KqMDMAYdrfrg_=&yMQMj_V_UUdqU=&pvTfzCYcWaZrg=&kv3soiVekgYWh=&75yjKeZZZqaVo=&YGNlA4XUnUkse=&YBkrcLXhrUgfe=&SUVIf9Ua_ZXar=&l9LKbsVfXZlol=&2XJsMlWVdZXrW=&8otmH9YsehVce=&uspAdOVZrkqdd=&AkKr8PXlXVdpa=&EIb_zRXmpaqW_=&IW3ZltZXgqgVn=&57NJrXZ_gljhf=&HcUNvkZhkbf_a=&AMQ_8oXfhUseX=&zSnM3PVY_VgVX=&MPvjJ4Yisdsbk=&UTrel6YmWgohs=&SumUf3XeWYaYX=&gXm5BvZhfaopq=&WxOTePZbjUVqY=&INMkuFWXfUZqU=&tiAZcwVcrgibW=&mx5IjZVao_kf_=&tFE6lXXhjnqZf=&6dp8TcZcrXcdo=&EQFlfvVrXboob=&kjhZlOYng_pcn=&kIHx7_Uodq_ld=&ogsk2BWrYgbkl=&hkDw_eXVaZicg=&hnGyDVWrdkfbb=&ta2iVIUkofbrn=&BLAz6aZpboroh=&M9RiM8ZlbgjUj=&WZdUynUdZUinr=&PlWXsQYrbfXqk=&ea4ClvVWgerie=&lqRFZYUdapjio=&33rximYfmmUok=&Pm2ce6UaUp_XY=&YzEgYxWqmgUfa=&TD_zFlWcYZpai=&cTAUFdZWsfUYq=&Qi3QNdWdmfcen=&4gmTTRYUesVkq=&XDhGa_YXfddgc=&S2QfCIZfYdkZZ=&PWT8VjWnqblYn=&FMHUBvVWfcrkY=&9ZbTSFVs_UUlj=&KBm2kjY_lVgWU=&hi639cWhXZYlh=&Km_mpKUhjcWpj=&eG_nMnZhgkUjs=&Me4DizXUijojl=&2PkmKMYeUgsdk=&CxAFVVWcrm_ea=&rhOsXbUbsh_gh=&3iKssNWkgigac=&8ypaqbUggrWsV=&_I69RWWinslri=&WUFHo4WWmefUf=&2LGJQ5XZXadkm=&SLvUO5ZsYZXic=&6jeQvmXgjchhY=&viKskAZWbbaho=&N3kp9cVjqqrsc=&lVo8QlYabsrUd=&YSoKglYUbXlWr=&KMgAMjUfmmafi=&phWYUyWdnWprp=&CepJPCZabWedd=&URiroPWo_Xcra=&yGBTA8ZZbkch_=&kLl9KBWZebmqc=&HJQdDDYsromle=&58K_exVffkY__=&NoqksoVmddUob=&c3GSR9Yi_mUY_=&VcvxeCYcspWri=&3C3VI2UXkajkp=&6kg5CpWofkpZq=&vSU8XIYgrksrq=&_VSzmfWhipjba=&ClJgXhX_U_bcb=&D9hE8VUgZYqbl=&hkB99kWfbXVrg=&t5gnzLXqgbXo_=&wM3gwiZlZjqls=&dzoXEkUdYpaqU=&qrC8yxYijgroY=&AS7UV8Umhnaen=&N3W5lSVZW_gjs=&C7nmtoWjncZsi=&qDuMtXUeZprUr=&beSFYDVbpdgsg=&FVUHYlWgZVjXj=&S_C7raYUYchah=&HHC2HaYZffXkV=&M5jZJoUahgksj=&uiVfpWZhoccmq=&i3uEg7XUraVmg=&FQYJw2WrdUesk=&KuXJ6gWohZmbf=&H_exRlVililjl=&8Zvv9gYdkrfXn=&3uSe8dUlVdiYo=&78JuWsUppaklo=&ZdaEDcZjjbdlW=&ZfYpahYbUWUYs=&UijwjFWalcVoq=&G_WbivUZX_sjm=&tZCxpBYffhpdj=&7GugNGZfnUmlg=&zuB2GpYoZWnXk=&Dn2kHVVsXcpps=&nTte_fWnedgrY=&EfsvRPZXhlnrb=&CIZkOfXWsepnW=&JYns5IUreiYcm=&rUtPFxZVZbVpi=&C5Y5jdWepZbUm=&x68N9UYbrUeUf=&s5lVWIZqik_qc=&MiHzZzUYeXldW=&n9pnwyWedkkWf=&H_b66iWbhkqod=&aMNq3OVmpigYg=&oBMHAyZpYbdgb=&z5rl5nY_gslWe=&K2R6dbWkqgeks=&ZbCrXoVapclhb=&veyafxUncaapi=&_pUQosVafal_d=&d4CycmZaplgsY=&VvQQcMZlkdiY_=&du4sEPXikYiYd=&MJ3iDgYXbbYbX=&UkhlTcU_ns_Vi=&hLmRP3YnlkWeh=&kFXBsuXqsVqmY=&u8tM5zUWZoree=&v_KlWwXaYpppd=&6WWUSMY_fnfje=&5ihnIFZjcgdWX=&vxxb8nYcopkie=&v6VXCWZl_Wneq=&mT5efRVVlZcW_=&fT3ehEUXUfoc_=&QCVuY7YWWlmiX=&KyCIeTZcYhijV=&II6arVXhmdYWn=&L2EHIrZhhfn_i=&ORvg5JUjZYXji=&Av4noqVpolhhb=&OHaGziXYbnnfm=&bNLGhuWge_jXf=&BX8HPzWpqisqY=&SBiOj2VrYYhfq=&WEPWlzZaabjd_=&qAjC8TWclYceZ=&aoqJSJXamqrZm=&uMEwVAXZjfbcn=&R8UCD8VadsVci=&SwsHHSYjpsfs_=&Q5PdcYVolVgae=&tfZQhIZpZdiUp=&7l92GMUhjejm_=&GMh4YBYgekUma=&welMQbYkWYoji=&mAwZhXVcsY_Xm=&RGMgPIVaidakr=&_8NJO_VnUlrrn=&egU8GRVoigkdZ=&FZukBPUasipfj=&Gyu39DXgbjrrl=&NH7xizZmnbrfa=&GbURFlXafrnXW=&uIpzfhXrWlmrn=&3ZstPNU_Uoioj=&reAHXzWssksmd=&lnbf_dYmmebra=&auMqMZVXdlraX=&TNErwhVUUaln_=&U5JnK2VghjdcW=&b8ZerzWrXnlbj=&3OzpeCWYhfZWg=&lbAjQ3XdWUWWe=&QHkS2IUshkneh=&7PEt_qWblscfi=&6nIlMtZWfnjja=&wCattGYZbjUaa=&4ChT63XlZngYl=&UtDOmPXXfXUnr=&XN49VoUYklcgW=&8IqwQ5XmmbleX=&SOYhQnWoocZbV=&bP86QuXYn_fdZ=&bty4VRYlUoaYh=&htCFb4YWhadYg=&MmwaqxYcYcZdi=&fTG7eaXZnonZc=&lFcxkzWjngkjc=&eIZZhpXYYnYeh=&u4o8rmUYZfVUl=&3SFyb4Xpgf__V=&FjAgSyZkgdlam=&HdJSCTXVlnnac=&8gnXyFUjlXime=&xSiyOwYkkXskd=&3YM434Wsbdjjf=&yGnnpCYlereZp=&vnwvpLUapiWhc=&XanxWwXmhVqsr=&mpDCKHXnoeZgr=&nxO59zXcjgiU_=&xAVsqAWd_XcWj=&nALLCmXYkrYdj=&AErM97Z_nlmlY=&uDuI8KVWeYsdV=&2oRe4mWcmmUXr=&rVw_lKUshZWhf=&3JHxMhYdXsol_=&vHyDi5ZhiYahh=&oIHx42WZYeVWr=&X3fxssVWpWaUc=&xFqxPgWndkU_n=&tXV_xmXeXinmY=&LoAQbQYlWoWrb=&6VplizWXggkol=&TBsqOnWaqkcfl=&gnaTzcUoclqkZ=&AMd74xWeZgbZp=&yz5UmEVokoYUl=&UIPA7tYlconUb=&ZZHWjnVmermhl=&wUUflMYYqcUnU=&rHRehjUldbdWm=&HqIScCZlYamUo=&RnckgSZcZhZah=&XuiM_3UacrVoc=&gaflZMVVipUed=&EfftvkXdYWdlp=&Ps6bF_YWlaqgk=&5nDJVyUbrkbVV=&lUSAioWdphmVe=&v6rcC_UmWeedl=&SrCK3EYrZfpem=&8fRfFFXWmUZmV=&JkV9sAVbmqhWk=&_VRjNLY_mdjrl=&mN2cFWWjcqgne=&Lkeu9MZjoWdgX=&I5BI5gXasjjpe=&bfB4THWqpXssf=&wsxC7HXdkWsbY=&LNAXijUcWgVqm=&mbRLOmUklbVli=&7lpEZhZWl_jnf=&JA5rmGVraYhk_=&BXKkiTUbgVpho=&hDYZEMZXilXgo=&V8vGxeZjbqdbW=&8PgrMzW_UaojY=&9_SKsJWUZYsjc=&rrglpoVhmWjeU=&dtkSEiZlhXVhj=&huYKI4XdsglXp=&xjByPiU_kZVXW=&mUWyUrUqagdih=&c4Ro7DYmbkkfm=&hhDYZOZicsr_p=&X8KbuRYolcljY=&tjFtduXnerUol=&Ilp3fyWrakWcd=&9N4AAUYmqkaeb=&c7Rfa_Znsakkb=&UzaHxsXacbarZ=&3RuSZ7Zj__eih=&bVe9HBVieqWrV=&LiFC_MYjrXhar=&PYrywpWbiXsmW=&BOPgASYWaXWiW=&EWmyuUYV_WaXd=&LyDRzgUlVcfdd=&J5Q73aXsUjcoU=&u2UVu2Xmqkegf=&DqtuhFVjWo_Yl=&z32PmeUfkdsWW=&rbu_ntZokhcoX=&JgjXl6XdbXoXZ=&JTo8OpUp_dZWk=&eNBVBXUXVUdbm=&Jwo4nhVYpppng=&xe8hz9VsohXnb=&TjMDnvUip_apa=&YrqinLZUjjZoY=&8O8e_bWkkmnaj=&t3McNNUmZiacX=&754sskUVbaYaW=&CCRAvgWjkVXaa=&t7jxMMZbUcVWb=&HfhEDlUmkUnVg=&ITvi99Vihikij=&VFrb8gWlpdYoh=&9jPLVhWaeqe_i=&2ylluQZbo_loX=&sI8uBSVpfYrha=&yyQVomXmqWqls=&P5SWvyYmZmhsX=&tg6d9gUZpofsZ=&r2EBTaUVqgnfs=&D4WjydWekkVWW=&sCvbaCUoqacZY=&iueAmpZhZapak=&HSSpmfWqpdsnd=&oXHp_JYmZhUrU=&spkNPKYaalVVh=&xtuQsUUgcYnZh=&7x4FXOYechoio=&5XuT9pZhXdfcj=&RVLSnZZsVZaYf=&dnCk4jZjWfjYp=&7_ydtEXkdrdpk=&COHqfUXmWeqUe=&Caf7GAVUWZadh=&CI_tlzZrnkhZj=&rqnYWAWlrkcUn=&auFBBYYdYengq=&KKLs4WVkpXcge=&T9kyp3Wsgnrgh=&2ULayUVnao_mb=&GtGJcEYj_mnro=&XZDBn3Zqfaqbb=&UF4qLWZgs_rWq=&mZjnkQZdY_Xfo=&vxl7TWZXWmemf=&9ayZZRUnnsZrq=&iDqckMWlgdpkV=&lQw9tSVfrZbWm=&qj6TXQYlmYU_s=&XodNWZUXminds=&p7vBlZUnWfkog=&ShQiWtXVdafqj=&4_GbD5YXVdcql=&Rw38X2WdrYYkd=&WxdGB8Vfmlihb=&paX36LXUclhVp=&3JGdL8XYg_Vro=&UbcYGOUXrYmqs=&FeEUvKWmoj_rb=&9dToCeUoVr_qj=&ronFbuVaohamr=&7WzWvnUZmsbWo=&tlYCCRXholrkq=&3HlWOPZbUVobW=&x_aODXVbmegUU=&yW8GHMZsZinoU=&NUNrV5Ulpldre=&VCISKPUkjcncZ=&ZZYItIZYjZgkr=&7yzYooXiebhXY=&jEh8YhVilWj_g=&eZ8vdqZ_fchUi=&JDHhiVZUYcpsi=&znGAVGYeosfhk=&vvMbvzZphbrn_=&2iqdTgWdiiaps=&FHmIbaVasabWe=&Y_ZihBWdnqdbW=&oen8rLUfiZZVr=&VBiiXzUUiUVnl=&FtuHsRWcraXb_=&tlbt6lXfn_ghZ=&mU9TjzWgbYhmY=&PfzXpHVYbWWkr=&UQ7HahUkYWXis=&J8JXYPZnYqiqa=&EffJcVVfjsbV_=&9QhrwVZpsVheq=&O7BlDhWkihkaY=&SndEAjWijihem=&Z_mPrqWfacgep=&QUre_kXbUbaqd=&f6ZCuEZgXefYp=&oXzU3NWfmsXcY=&zZTUChWcZUrpe=&QEmS9uZqbYrmY=&79BPZeZXqWoU_=&6Iqk5uVirfbWc=&N4xD4xZbdUqVn=&Sbf3UaYnWchUp=&5NVP66WnYfcdr=&P2bkQLYhlUlWc=&3dbKosXqclYVW=&waBNkIXZVaWko=&k_jQAUVW_qojW=&zLNzSZWemkp_Z=&IUqiMdUqes_qq=&RmN5kMYqolcVf=&FMrPs_WeXsWeb=&shtaqEUdsnYop=&Z2HZGbYXdrjqs=&tF7tGNZpjVgYd=&yIMppdXrhknsc=&7GGmkcUXbksrs=&SaCJYpUYaY_rU=&IWMks_ZkWWssc=&OFbMn9YUeYmak=&MJynliVpVXjfa=&NWnMR3YcblUdf=&RsGdOWZpqhZre=&fCBTdxXYiZhZa=&uehWIGZog_cUV=&nszQEfVcn__qg=&JUNqdJZogl_ir=&W9osm_Z_jbceq=&TpKuhFVecqeYo=&GEDJK6UergUng=&EWmp_HWYWaZoY=&dBDE4sWegXYki=&OekZzLWpnihfc=&42hJtfVWjfehl=&IN4zaaVaiWhdZ=&9jeBx9ZnnhYYW=&3xQNVRUddcUZk=&YYJmfJUdUggmh=&DzznUPZpUXmfq=&B7JyYPZmZb_Uf=&pwoEwcWWasnoV=&oL82hPUnemaVo=&jkvr7CWUraagV=&K6IVOoUYmf_Yi=&KZvQrwYskhslY=&NhZRkPUXqdlrm=&ndNyFJYiVWsVs=&cv4_pqWZbhVUa=&He3wCyWrniVbs=&h5CBDnVqYoeVr=&ogYJiLVdY_Xdf=&s7FPwbVdsXsVi=&DnDogZWhgjsdg=&faR2zIZpjZrjb=&yDe7SeXnjZnXY=&MwaS6eXZbVUoU=&uCOoO4UdnqoeU=&ax_jVrVqpqnpV=&VaeDRwVqm_rgk=&gO2IShWaqnlmV=&cHf5T_Vjfemhg=&OPkNajYmUmhlW=&NTIo4CYjijiki=&W4CXhUWkhZnn_=&pslwWKYYZWfna=&BxvcUWUfqZg_q=&UqE4mjVlsbrUj=&Rqia7qXcfmUrZ=&OPASpQZ_VnmXV=&cDXc6JWsZZlWa=&iNRqUlZ_dfafa=&Rd5OrpXjcZfcj=&w9MOihUabbpha=&G9tYdXYjUrkZb=&LJKSXBVZrZWcb=&WP_kx_Yl_gfni=&mupP__Xeb_coX=&HrhWSSUajakep=&wdLNfTZjrbkjV=&m9aYZBVgnmVss=&CKxHfiYmlkboU=&teuEVJYpipqea=&u756qOVgooXk_=&6jnH_lXslYkrd=&w2x9CqXWVpVqX=&PQ2pt7WVdXaq_=&EKspoiXZXbiga=&6La7jqUedXoeg=&BkwQcaYenjVcp=&uPP6hiWgrprkc=&zZOYWDXUecWmb=&D2yU5zVcnqpV_=&2grgvHYrYkpZk=&LxWv4xWVfk_Xf=&W2AB4wZ_Zkooo=&7SqMzsWofbUak=&T3RQWJXZYVnYU=&bV_rZbYskXhjr=&ds_bZCUjeVUio=&XWspFXVY_XWer=&MF2x9OVjWdfis=&c4_9oeZdVlZcd=&VrDacxUlarYYp=&NOeGBvUsaoqiU=&eFZQDpZjbeUfb=&osVjMXWbdeVVi=&u34UYRZd_Uqhi=&2vEqs4ZXUnhnh=&vBZCP4VVW_end=&6Oqnl5WUnok_l=&ymkdftZUgmgcr=&kUVR9MUaWaVfZ=&s65W2WYkg_Upi=&ucBlt4ZdllniW=&WmsUnVYb_YVgn=&g9ygSGXVbUkdX=&GhasW2XgdnfWr=&RGKJUFWZ_gUXm=&tbpXmpUikXons=&ZvLfyNUpqVgom=&SqQlDrVdpVdeV=&mweJfUXobkXss=&Ax5VEhXVc_eak=&ScxOQHVYeklpe=&kVXjoDVl_cmZs=&jLv2EkUaeXUYa=&afYrbEUdqYosV=&TZMEQLWbjXccl=&PXus95VliobZp=&AhwjESUmWWin_=&KAkfgSUgVagdq=&NPgQZHVXqjW_W=&lBVPmAVoYasgs=&obtkHHYnsoWki=&WVssNTVfhqqrY=&zQyzOeZpndWkh=&mwr7dEUWddXaU=&E2FXS3Wr_Ugjm=&RKzlclYrWhmXc=&inpvRlXZqYYeU=&mZFnpNVqWWhss=&43dKhrXYYUabh=&CWtVdeVnqkVVc=&zudYmkYsifcea=&CjQ44KYhsXqUs=&G6Fyp4YeUjcmk=&SRt5UrWemkpXk=&4zBvDdXnVjZei=&6XtuHKXYUjWZY=&tOTw4qYqrhsiY=&K6vFr8ZjYibVo=&ik6yaoXc_dafb=&aBPZUnVVdgrjY=&5FzOCWYbiWimo=&K8z8GGYikYUcq=&Sw_Yq_XkXm__n=&zLi4cnVYdWlYe=&OifKSaXjspfeU=&rbMvIlUsfmoeq=&l4weIuVenchnf=&4mSr8SYh_bcie=&LcTFA9XWmZrcX=&lRqL83VpfYYWa=&uhZeZYXiVbYgb=&FAdkt9Z_UWenq=&MnHMCUUl_pVbf=&LpjnNNZrmlame=&3Lf2tLYmfamkd=&bFoW7GUrjc_hU=&wMUPfIZlk_gUb=&Imva8BUlWqbVX=&iBh6WXYcqnicc=&LdOonAUaeeccq=&5UM9ZpUnXchYq=&y4keDeWmZrkbU=&IkfpPKXZYWcig=&PpdDKNXqgksip=&M5dTL2Y_Vl_Yn=&uF9yQxWdfpklj=&vndYJlYUssorh=&63bfSCWUeimnn=&XHQMp4ZebddXk=&D4kZd7WnckdpW=&p_cpSjUeW_ga_=&BZBtn8UjanWZs=&WSPFIfVcfme_W=&oGM2u3Vilggie=&sobhCnX_flqps=&6NlbhmVrYfpY_=&VXyRNTUrbhgaX=&RON7N5WiUehab=&T4tQfDWpcZpod=&6xearnYjUorlY=&rjHt4cWpZnUZ_=&Rk_TQVUWcYhnk=&Qf92N4Zjkkcd_=&KI_GzWXrV__XY=&r3hh8EYfenUZc=&gLkVuXYUsepal=&XMysczWoj_pol=&6CJXz5VjYWfok=&ihKSnWZYakspp=&K4xBCtXj_lgXn=&E3cWADZlrkh_a=&aRr7_KXkeaVmb=&hII2uMWnbqing=&vcRQKlX_ZYXla=&BNfQGPXqqmagU=&ll7NuEXpXjnZW=&xBFkL2YfZpknU=&5jWeMzZnkgssZ=&x3dDznZigk_if=&ypql4xZgnrsWe=&7GPa_CUoYnhbh=&rCayehZWVcds_=&RPYS8pUsXfXjh=&GrYObAYmigicf=&VSwGC8Xfpbkqb=&qRjIVLUjrfXhi=&emNCxnZUiZjZi=&3_xzBrXmdrqXb=&llWg2aXl_Upre=&eu8FgvVgbcopZ=&2KqL8HZagaqYg=&KyuGpxYkcgbYo=&oClPa9YhdchXh=&wcsy62UbggabV=&adjHPJXhsjjas=&GkbsiIVeVZjYq=&XUXRaUUsrdhjW=&Ajoi4SWjUccmg=&elf9hJWeqehcs=&_6daNMWmVfXWr=&gHxA8VWlorsdk=&BLjDYDVqaZiXl=&zBIGrRX_pUqfa=&kHl9hDYicWXfr=&NXGdbyYhemfpY=&32eAA2ZcYjdnj=&TfwQ2BV_firjZ=&hLI6vCUlZVZhY=&vGheyKVqiggeq=&qzSeTCVsqiddY=&BnuTuTYnpih_i=&IbKiBiVZbieca=&rd8qnuZWYmZ_b=&MlVIezZkjoc_s=&DnKARGVZVgkXq=&Q8mkIxVXXjWcn=&Zqw3jKY_lcXna=&YTipjlVZiikYp=&2WweLjYshk_gp=&OM757RVZXnWsg=&KnwWTiZjqWbsY=&FGBzI_YZnispb=&hlQcj_UqVYUgV=&fN5fuZYsp_Wgq=&bEkvrbYWpbpia=&6q_5LAYc_akXY=&zECLIiXfWXcke=&4W3JkhVhpZqkg=&jqQvBZVYkrksp=&87zyDxWelprWc=&_q5RTAYWidbdq=&cPjcpNWlcegUc=&8cuNaMXoafjnj=&trdNmIUUiiYns=&jN7ETJVYhrVqj=&_4rQ49YdsXgWs=&CReNcSXkjZhjg=&XOTrGHWchbghW=&u_GkGUYkdiXWl=&xhtEYIWYgpYXU=&k4nvWmVrXalmg=&zxhnwcYscnacq=&gfdVr9WXrn_cs=&44ES9PUYhpWVj=&lwBNKAUXWfpnW=&thp2oUUWeWqUn=&LKa8DfZhXgVng=&nQQtxgYUkmYXl=&zAsoSHUieaXWa=&rH9aMiWjgrUgd=&bTJX44XndqUrZ=&tp7b6XYcUZX_Y=&2fKmXYW_mkmak=&OFbLa_Y_WreVk=&6fJzYUYkoadZp=&V33jVlXhXdgf_=&HKxhphVskaWVW=&EWVmCPXYhlqcg=&E7UtsGVlrnVXs=&9lDBy_Vhrqfnj=&mxTOLTVisedhq=&K2eLGGV_XUrZV=&c7gcQNYrVaqmg=&5m77nSVhYnali=&gmLqY2Xgcr_sp=&xg_wMCVlWUrXq=&9gx4b7Zgi_hZn=&RImRymVcijjsa=&KE8GYqUoodnrn=&JIXTvjYqlYWri=&k3ffr6YsmrobX=&EcRkadZUZpcnp=&3TWI_CViYmUbe=&aNwIK2WgVsWVl=&hUU_QmZiWZhri=&HtspmQWefkmiV=&mGGbhaXiidXjf=&rq3j84Y__arqs=&bo_ZnRUbhln_h=&NFnpx8YnjejWq=&ORqLn8UdmYeqi=&iLvUV6V_fYoqZ=&F2vaj5UZnoUcp=&y5FGaqYrsWnsi=&dziKo4Ym_Vgsn=&ZbFk2rYqmj_if=&Hs2LgUWkegWam=&HTdKmTVbqhssW=&vqiSIMXcno_Ue=&HnVnKuWkchmq_=&5pVEgOWfnUXbl=&TLh55WVZaoXrm=&VtgBlXUcUpmhc=&e7SZeDYXlsbXn=&luev_IXdk_Ufo=&giofSdZlcZdV_=&JQxH_fWkZX_fq=&DOeuuLUhapsgb=&q2dMhdWsff_mj=&UCAcYJXoYlheb=&T4C8gsVcXiqks=&RTdk7vYcndYir=&Tug_YtY_bamsY=&NKfnEiZYebrkX=&nu9pIFUiejqVs=&NUzE8WUbZgbeh=&otDxMYZjgWbkh=&kOzTqvViflWXW=&_uYbwDYsdUhlU=&WaPe8WZsXmjkg=&TbDGOkUnaXUqs=&UMyEsHVcfqcZb=&vLJXN6WfUfrYm=&uRjBi4YVWkcmU=&sVlrevZemkiaU=&4MaDUIYdm_Z_l=&GgLGPsXYpqVlp=&xkPA9sWprg_qX=&LGep_rYpcjlpU=&ztSmTGYghsnnZ=&uyQv9QWsWdlVn=&SJFhaEZher_cV=&WVFAMYXiqrciX=&3AyJg_ZlZdfbi=&pX2MjhXaps_bj=&BuqtDEZVnenZp=&f2ZYdOU__WnsW=&5jwI_hUqhlsri=&sx7qqkWUdncUm=&OUZ_lCYhcZYen=&sxI2BtXWXhack=&WQ5jR5VonUaep=&SgDfPEZobrqpi=&SWdXi8ZsYXics=&XhqQroXYrrUre=&wunguoVqXXfoo=&RylnSGUkpiXgU=&HFDCrJUhZ_jli=&2oIZ2pZkiWolb=&cSIV9KUkcW_rf=&fLU_m4VVVXUlj=&KDsws8UmYsdis=&JjlR6EVod_gkg=&r5ecSbYnYsh_p=&EgzyPNZYdlfke=&VFlJmHYXXalgf=&zJRW8wWfXsrio=&UkfnooXsUmf_d=&h5M9QKYVrXWkd=&qcIOfbYabXbWa=&XrtFf4Yn_Vkqf=&om_htSXooZcih=&XJ3SrnUenW_ln=&VfpuzmYlemakg=&HCAAIxYgkdWfZ=&mbgvADWqkir_f=&HrXpMtWsmlij_=&cxuhxWYasojkf=&G8lbj2UUqbWeh=&t7NG9bVWm_YUn=&iqNuZyVpclYUg=&hS82PGUZVsogp=&2DRnjBVpbYfdo=&tkKpvwWWpZZdk=&kAMOS9YVbZlWX=&SpxpzqYjsqjal=&_unbNMYadUXrV=&iWI2NZWhbsWck=&Y5xVDVUrjXffq=&W_eX7HZfjsner=&uEfEqXWZUroXY=&xhH39LWfYaasq=&XwheKlUleUbjf=&eZMjuXXWprqqp=&ZruBsCXhkliWn=&48Ha_nXUjooib=&Ah9baQWZahjYs=&7tdKt3WcrcYfg=&FAYT6LXXgmnki=&CMsb6nXpWebfU=&Ctve92XVdq_ba=&3fgstiYVWWsg_=&wQ8ysXUrjgZga=&LbTyWcZpiZoib=&U7_ujbYfnrhgZ=&xwl7_XWYgWgoW=&qkiAzeWsaifsh=&BFMpWlVoeUrbo=&BW3furXeWkeoj=&UqZc7bXsjWfYe=&mD9gLmWksocmZ=&9BJicoUjpqrYk=&5FCtS7VehdnZW=&SH_ut4ZinpdYk=&ENA93kZZUhkgb=&Ao_onNWVWklWV=&tetMz8Vspqahg=&C9qjXtXpillqe=&jK379LYVrrdfq=&uPFDT2Y_ijpgo=&gDbJ4vZrlrXX_=&9cFScQXYYUqZe=&nBs3iFWrl_cka=&6ttev6YgqlbVf=&6z4QDzWYqgahp=&BOpRcUXkUchma=&FiBnQGVqsgccn=&_a74Q6Ymfqnap=&NJnx_pYnpsicc=&34HnnaYYofXYl=&upyeEqYaVgqdY=&by9I9wXoascsX=&9cchgCUdofeek=&qcFDjKZiXVgbs=&c7p4XhYshdslq=&sQfH8ZVaZnodp=&Nvzh75ZZsmpXp=&UkpGbeXpsjWpr=&yFa3TyUorhsd_=&FjRSiiUhnUsdj=&z5STgaUjpgrgq=&QP8xRmUohlcds=&ijQuzHUslpepZ=&xg6w9bZoiUaWj=&pg8pCrY_dolif=&3qIyEHYViqkgl=&yubdjEXmrmWbn=&rNX9BVWpheUZf=&Tayl9HUVgdhVU=&L6Ws_RXmnlecd=&pRulUjX_YVhko=&ixeRoaXlfiXip=&HQrSh4WaWipie=&Bev3FNYVWdhjn=&bmP2hxZ_Wmebo=&oCwwZyWWYUpib=&QxbL6PWdnaUfV=&T6nNuAWUlqcqY=&OUGDHUVeiXjZX=&gcY9AtUZodZlU=&J5NqQQVhale__=&vSM6x2VeWhjWg=&ibFRjZZnkVkbe=&2bxciRYjdaosp=&shs63wViVgggZ=&Lt2eziYUhcbXq=&bbWuM6YWigbrm=&psqVDzVm_jVos=&8h9hLfXherjrX=&AOKWoxVbZndZs=&iOR_l6YWYXmcj=&Z2RbjdVehVkiW=&_JXh3IWfrVsal=&_kIeRxZ__epcf=&6fOZOdVdlbVYq=&xoIvZYWUUbZWe=&tKREMQWeZViYb=&iXCfnvW_slXmj=&nZ8Ic_WhanYYq=&3x3CSLZqXlVYV=&Af8LPnUmakkhp=&KeqrCSYgZmo_V=&Jf9_VYUelVopZ=&2nSTGOVjljekW=&9B4kRyXsZhkZY=&orCz25UlaYrcW=&Z2pmkQWbblgrU=&PIjnCAVfdVdsf=&ZHKzxdXcgfnrq=&gaWAUGVclprWf=&NmnbtkXqW_fpo=&YdZaXtYlVnWkg=&nPlfriZkYdamU=&aehCkfXZkqXrV=&FzZlgQZUpkhia=&upFgH_VXWrcnU=&NBArxTUXVmgVd=&dcETPCY_hejZn=&TSWuDGXYrqlZh=&u48lLmVri_lUi=&mJfig6Ylnjoir=&hQSVdxWlhmWnk=&shlz72ZnmXVef=&mFYGj_XfdWsos=&HqAQDFW_pXqXl=&cH_NX3Z_ddbiU=&zzwSUKWYWdpoZ=&QPhdCkYWhbjgr=&q55AMVXVoVfeW=&Y_fe3vYgmmogh=&OCt4raXiqkXgW=&2bPSUmUhcZdep=&DbxyO3YWfeUUZ=&CTag7GWgYUnfe=&C4p9aoUeggmmr=&UoG8AWXWrmmgo=&25jCLEZZmfsYn=&_u5hrAVk_kojn=&lnEb25XqdbUge=&BpaKviZXpUiYX=&OGZWXoXgUkeag=&Ky3jUOZsoakf_=&lJxlOsXeqpodq=&HICqfuVWneUhc=&yM5XdmYYaeZae=&7GMRCNYlqjsgZ=&IVi5UMZdVed__=&6RtimMUZfpniU=&fyQE4DWdkecsh=&NxywObUgXp_dd=&PdoMqcXZ__Wen=&cTBEzfXqipjZj=&dVCwTAWiYoZsn=&rr7QFmUlgaaVa=&7o3PFmWaibXlm=&leiQZQYVaVhnj=&wGczeiXglakUs=&uKSrZDXqqWnkU=&e8k6RRWgoplYV=&OoqqvrXijpqso=&qNZ68YXpcbmca=&h5U8JTWhcZXhl=&Wvi9vsXloiWli=&nX44TxWckgWpi=&VbZ_FiXVpjijg=&vd2scIZcXV_kb=&IyqoS6WmWXb__=&qUs7JRWdUjoqn=&oxQhZeVlmeaoa=&Wvgzi_WkZWXWr=&ZshVHVVpmmfhk=&xVtHPuW_WbjUo=&y9uHGAUklrsZj=&HSpc_kZqfomof=&ZfLm_fVdVUsZb=&Wz24fDXigXenh=&bwZljAXofnWaa=&WeXcK7VjeVcVW=&tTJVhXZndoVrq=&yADXLEXUfWiZn=&ENnl4IWYkhqim=&jwmAchWjYcqlX=&t5jXkfUrcXoip=&fmkLfzZnsskWV=&6BUNBnXsrlVZd=&K9MDNYVbkZspb=&BhXBWYWl_kifj=&t9eOi8VqddgiU=&UlzXaZXmYcn_X=&ujoUM7ZZsorlU=&gllr63U_ojVar=&yo_rJMXWpkUYd=&5UaYI2YoejgZi=&tSdH3SUr_l_pX=&8qvF3TZr_qUrk=&r6F2akYmnVode=&TX_B9sUYrVZnW=&Up6X6oWpUabna=&j6OgnsYZWecra=&VA4u5LVipVmpY=&ynKjHfYgbYkfl=&7LgaZ5Zqfsied=&a63E3bZVjYshp=&55bhcjVaZgrmZ=&q_BGPFYVmWpYs=&QXXtpBZpahssl=&I8gUSkXYYWkbe=&lKGkF_W_hopVk=&KGpKYoWhcfdYp=&BLbJG2ZWpbfXX=&LEptLCYdi_giq=&nrBgewW_YWXad=&EHYhJ5UYdUrke=&WaX2N3UfWonom=&vMWBviU_YYYmm=&_KvptfUVUdloe=&q4IEpuVlbfk_l=&zcq739VhbUYsn=&5qNErOXmgsYpb=&pMYGAyYdUlnVg=&nOXcS2Ykka_Yg=&APpkP6Vq_djUU=&j2PgJXUsmZbgW=&BELkxxXmikrhi=&EK7qLcVc_dhUp=&Mytc5jYUYopam=&UzNFlRUUbiZpZ=&LQ8AhQYacUbir=&632DEMYUakcnb=&Y6TfNwXZ_naac=&jERyJvZbZnbce=&SCeyb_Ymo_elf=&r_zwYcWioonUg=&FieIUKVsgkgsd=&HgMgnhX_moaqf=&xggVVaXqllahc=&sr4c3vZerfrld=&yIWTzDYbVYajf=&ImbFKmUck_ghg=&eanCsyZpoYVUp=&AO8higWacZrrW=&TQTY75UVdojkg=&nDvJISZahVqWi=&olSCWbXsjoY_X=&_6ZeAxXZUocXd=&Gm5dnzYiYUdil=&GgjSqPYWbsrpo=&GU8On2UqpZjYX=&Nw_XqzWVgperZ=&aJMvAFXrecegk=&SRliDKZr_XsVq=&kw5TZ6WkgUUXf=&2yNx7tYUa_fmi=&zGGwS_WnXbn_U=&6TbHx4Xbd_iWm=&DAqhXiUUhsqib=&z97T7MVWsrhmq=&HhVILaWoVdhll=&F3FCS8XZgifdk=&zgMR3iYanXXYU=&Oj5_sLUimmerY=&PCnG42ZiVjqZp=&m63CxsYamXdnk=&RvwjZrUlpjbqi=&IIiZ_SYmhiWVs=&iDv_5EUUXrroe=&BIFrWHZYhmj_W=&5Co7eDVfn_kej=&NHlRnsWmolkjq=&_jyruIWremhVc=&cN83NUVlocdr_=&UStv25XVanXYi=&ReT_maWUhaXdo=&5xruZeXpjncbf=&sqWSLfUdY__mq=&O8M8QOVmporqa=&OW44afZmnahlq=&g2XfOdWgcahgU=&J6p4vZXZnlnii=&COiVsUXsafcdV=&ZpPmekUoaZmUn=&_HbB5fUenlgfa=&8LuhDhWddlYgh=&kdf56pWfoVejW=&Si7Yc8VoscaWf=&kdHDTmWcaZZre=&vnP7y3Xrlo_Yj=&qPAE6_X_srmXW=&yIq3CsZYiadcr=&cZjpz_UoX_pjW=&PToObQZprVqaW=&Nlg38VUYbXrmW=&JMSZ_IXnoXUaY=&Iqg6PzUnUhsYm=&Lh6YDoZgckaVn=&gorn4WYYsgmrZ=&f6PxlPUjgkiio=&XixNSxXcdldWl=&3piICYVfUXZrX=&4nvgPCXZkWmpi=&o3zdKuWqkndjU=&cQBYdbUpZaobr=&dl9av7ZY_XlXo=&8qrgvWZVfUrVX=&YV5QfJZbcsXUl=&KXzA_dXhWV_UX=&Y2LFUMYgsiVgZ=&Cw2DBWVkUadse=&4o3aHLVcbnfrl=&i8iuruUg_smXi=&xGIOZbUoorn_e=&4hJPOcYjjomn_=&rVx94SZZjWapZ=&bzvZRyXlZqnVp=&l9a6bkVpniYhi=&PNEVXUVecdpms=&cpQmtoY_mdaic=&6rFkyfYUUipdl=&DRXhLjWmkVYUs=&gTyNoVVmghYln=&JwlN33YXisjhp=&GrwjKaZaXUsml=&kOBTr4Zad_brd=&4Bmsi5Yioqghm=&M6Kn5lVnpbrod=&EorJOfUmoklsn=&Dg_UbKYWffdsi=&NODTNcXhgnmkU=&24oKVgYjlialb=&E_FK5EXepkUjf=&4nhKMRZifgcir=&LiUFazYjYXVlg=&BLPRZKXfnrlda=&zxpCh3WmYr_fl=&QEQbrOWqZnamV=&6ruj65UhpiWed=&lFKCKCYfgajjk=&Ee7fumZpWnZZn=&MjYLHDVilnUkq=&QZj_aPXepfdbh=&7ZJxT5Urflrpm=&mmdr9oYrYgn_V=&qlzRE9UXsepfl=&Lmd42RXhlYWfW=&sNBa7ZZUpreap=&2oZJCHYgdopWl=&8jxWtnYYiYfra=&lUbj6DXZfmhic=&cBYd6TUaXoYkW=&ftt6ohYWslnUa=&aQDQz_YmiYrkY=&8BK4wHVdsXgfp=&ZMWo3MVnskmln=&g6rmDYWZ_fepn=&SysaEVWmcrgfc=&8LJBN9ZZXqoVq=&HwC6bTYXiUZYX=&2gSdEXXpWmUlX=&rfp3fCWba_kbn=&HYynD_XrpVcnf=&debUKJU_lWbVV=&rODrZBYrdhZgW=&uJb7y3Vlbojlc=&8W2HKuVlXndab=&LGD9NkVmqnqpZ=&K_LQStW_Wkneg=&GGG5k3UYinmXd=&YzfcT2WfajcmX=&ZD8ldBXVYW_dW=&ghcM4pUjUYdVl=&SyFvbxZai_rVg=&K_njFIYUXVcfj=&k3mIXSYcjedga=&hkhi7OZej_iXe=&fSdAsFZcXcphc=&OYsaT8XhhlYgX=&RsD4YRYomhnkr=&9ifjgMVVY_soV=&esty2EVrn_dqZ=&OnBCvSWplkXZq=&JbnDPoXcnhhUY=&Z4DiRjUpnqaVd=&YbmtEGUgddcd_=&963zAsXefWWpg=&QAPeY9YXUbsaY=&BYHbJFYs_XecX=&CaWwatUdsUpgs=&V3vxmZVrbcVdq=&aubXnpYUplokZ=&dWjgVfYdfkjnn=&LmUrlHXlmfki_=&_pHHaTUhWYdZi=&3bjj_jWjXgV__=&Ra2OECYcXhVnV=&BW5d8sVqacWdc=&_eYEFTU_gZadZ=&2yhvHLUUYlnrj=&QbepL7W_lfbkl=&QFU75DU_eWgZo=&AXREGEYmhanqr=&DbjzQmVhmUeaZ=&auxCR5ZsXano_=&tuuzLFVmdcifm=&fAq5c4Uh_hmib=&WfkPoRWpWnqZj=&zgF7xkYkWV_da=&HLosecWdodaef=&XrpdL2Wkiockp=&o4GpFZXWkbVZV=&TpzXRgYokhapk=&bjz6oZZYmUglU=&4HXzKMYhacgVr=&Fr3c6UVdVdUpl=&a3RfYwUajcimg=&Y4k62IUXkriWo=&3erwKsVhfnigq=&xnqW8AZlieZfY=&3v3cNPUWhqXdf=&n9_4ZPZldjqkb=&yYFYBUUagloce=&L_CvLnYime_cn=>OhBoXdVYoYf=&QvX9k_Xgc_cmi=&w4oH9bVmqhmjd=&dETcpcVZbVpZ_=&7ehCY6X_koVcX=&EODZXDZmje_od=&6Qpaw9Vjkrnsh=&bobDVNYZaodfr=&qmzWtaXkshVfX=&FluJS7VhYnkbW=&FnIjaoWahXX_r=&qrc53kUYpbeYo=&xff22jYkYpebr=&xQ6vwyWnkmmkl=&px7UJMX_laind=&LsOWnnV_ZmZWb=&g25vyqUXjojc_=&YGKuRCYXbVkgr=&hZsv7DVeadfhp=&KCjYJTWXfocpb=&4VAH67XcYjlsg=&ZVqTTqUYkUsZk=&K94FrJUmsedqi=&4WN8KYWWnaaah=&A_yq4VVVcpe_Y=&6pUHF2ZmqlsXf=&MVJwf9XdroZoa=&wxbbTtUikY_Us=&KdsZTJWeahdno=&kldlovWehif_r=&5JAaoSYaqYoma=&zAD2MmZecXrli=&a_8u9HUo_ddkj=&fQt_AfZrZdUhj=&fUr5Y3Zefrseo=&qkInWlXcfl_kk=&hcC2kaYjXdhVe=&KDSbibWkYZqlk=&mYxfy_YZrf_Zj=&S6v3kzUghUfmo=&uOaNamVUkbpre=&2GpogFYpikUiZ=&xQXKZ8UWXbflV=&ZvUITgYabYeri=&TBUswwZqXgeX_=&7P6or8Zbpdpjh=&fEbdBrYVifdXY=&_Y4TV9Vfssjfc=&CRq8tXYafmlcZ=&7CTme6VegfWZa=&937pJoWZVmqXs=&Cv3nroUpjmdWV=&jLVQVDUbrileb=&H4aNFtXgqYjq_=&EovMjaVmZmaql=&yNrMudXYeod__=&Ev3vsnWdXXgZi=&6hA2Y9VWXqoqY=&3tIt6vWhWchrm=&7QFvndWlpgo_V=&PTdVZiYUnmfdX=&mYsaOuYfeo_dV=&hAaKEZWgUodg_=&BjF9JHYnVdVjj=&ijdl3nWYhUfoV=&uDScJLVkfpeqf=&h9aJoJY__hUXa=&qtKFaxXnnndlm=&oA2zPuUnifomm=&jJjoO8Xrfiqnb=&Vno_EcZZmifcY=&Aevb9cYcfqcio=&KulrssWodcsVd=&Z5dg5eV_fmdeY=&WMXeH4UfieZhd=&9xX6PMYXZ_Ujm=&vnlqrgUjWfnac=&TnNgWlWUhaspV=&aIPOxnZrnoqqp=&JwzBSCZdVfrdk=&ORihdFUkdflU_=&M8oOt2YpekZsY=&m5uqCfXVihmfW=&djqAulUmWWeVp=&4jUaCuYegdrgl=&TxSjrWVXdZojm=&NP6MIiYohdUVf=&EiFIVLVpXmljd=&JpOjJTWairfm_=&mJa3PmWVorrXn=&2StqTzVeomepV=&R3BmQKUoVkiag=&aLolhuYZliamY=&hf3uxTYnZlldU=&LBSuzYVlkZdm_=&XYDOIjYhslnfg=&FlsFpYXd___Xa=&lUs_3fVUXZeXV=&4WCDyKWUkVWce=&RVRWPQYhWrldf=&PdpR67VgZsfaV=&jLwXlVZjZYYb_=&54dtpAXqkphVf=&BrGL3LXfmnnnW=&gOibsLW_bra_j=&55OqIRWiXncZd=&tmWy_KYlUaaba=&DK9N5WXZrZpfX=&oKx9mNZosVogh=&WNwkxLXoUbUhp=&W5PuqsYbXeieq=&oGVqWIWYYisa_=&OVKUo_UcUsabh=&aFY3RoVsaYVmb=&xvrHU2YkUhsfc=&7rAMdGUnnkdnd=&J48MAnYqViYsk=&eByh3QXgfaWlc=&wDO_xXZbqpocr=&aKtAEBYlmmjh_=&a_ykHfZWoYabp=&E4jidHUXZUbpX=&RZZY4HUjYgYWV=&zkMOoEWcooilr=&dLiQgIXiimncV=&axz4ElWbnrUWc=&qZmD5BZ_bXXXb=&WcEoxTUoriWdj=&VnzOk9YkccVdU=&zuPlqKUsYVkZU=&_8ikSgWseiicc=&DAgtB3YreXaoo=&8ko9NwZVpisgi=&eNb5s7YaedgUo=&ZcZXvmZcoeWcc=&tnGXD7WaoifWm=&CcmGnuZarrrsc=&xvT4UtXdmmlbY=&QwttcbWhdagoU=&2uGeLxVlonsir=&u9cRYnUgUZpnW=&CdGpoGZgVlYY_=&sXtyWnUeVkYkr=&A6GWQKYpYhlYl=&MIhrccUiZolro=&qlzBJ2ZsphsWZ=&4y9tcbXrhUj_U=&gcuC3iXmdolq_=&7lzRjnUh_WcVi=&bbCgAFVbVb_nj=&Nf_c5dZa_rYbh=&uv_LYFWldVcUn=&3LV7DoUgajneq=&wRDULtXkWiWZV=&7NoXyZZchqXVk=&neghBeYjpirmZ=&HJrZxqYomskcq=&ybbzZtWjoi__b=&G4dgRxWbehXY_=&dVPpJIZomkeqj=&QjQJ9KYsV_lWl=&pTvORVWlmqWnk=&t4_pe2VbjVpcc=&fl3KPpWkXmekg=&Xbp7KnZpnnqpc=&W8T5knZZsVcWV=&yEWJcaUhann_h=&YEnAxLWdUW_gd=&fPPz9FZWbsdqV=&82Rde_UViXhW_=&_axJPqYUerihW=&tPJFHhXVokkkl=&H9J2E6WWaVrZa=&kbss45YjYYZbk=&DuiIVUYgdmqqa=&kjLKtfXVclZbY=&B2245iYXmqhni=&KHnbbzZWpkboh=&22RqaQUrUrbij=&FNunTEXUcd_fq=&SztW22Zarfrdq=&QXafBOXbYVfVj=&ogFKTvWefsfgU=&_FV9iqUlqnkrg=&8J2xihYXZfmra=&q5V5KFWhXaicl=&XZ2O6nXmUYdci=&BmAF4CZjfXodp=&lvAvvGZbekbnd=&jG8zwyYg_aWXl=&rG8y8EZUjWeZZ=&X5lx5PXnVUZle=&7Hwm7CZjgceZn=&S5WZViYsbaqke=&ACRmdUUmfVUWr=&pPqCO5Uoqakn_=&qLp8x4Udqceqf=&mLQahWXpdiiam=&OePpZzZjdelpe=&r6owLxZlfYZif=&o3gjMzXgbc_nm=&tMrQhoWoXcboi=&llLBXxUinnqob=&mjVyhtVfhUofZ=&DVcuSBYUmdkVk=&kOGZ83W_WlXqb=&xp7WAoYlqogkU=&tGBRiQVfmWmUg=&wLswv3ZpjdZfl=&ZQnQQjVmWmolW=&gZowdUXZon_jr=&Hgv8PJVZfcoah=&PMhLZcX_shWir=&ok9yBAUUWrmWZ=&4UYWhqYklZhrl=&mO6BATXpdgfhX=&Flesa3YsiVspd=&wFx2JwZqejUWn=&JPZRizWocngpU=&hZtz_9ZpYleaq=&iyioKgUmbXigX=&cylOugVVnjdsp=&7bTeQcVibdjXk=&OjBDKhZfX_cbf=&3NMDylWUUZjYq=&SVSf9uYVsVXUi=&oSFUnpYhngfar=&DW4bQAYUpaVdf=&BdrxCWWWqobUg=&Jy72K7XqoaUbh=&IjHm62ZmlgdoU=&JmVkO5VZojnfo=&tOeBrzZfUfai_=&zmSJ_DVrrdpqX=&CqOlvdUdloWhV=&lbb9O7XsVrVfV=&xINle9XpgjVbd=&ZReuprUWlbbe_=&tKOJRuYmhcgmd=&pJyLkfUWmodhj=&jxERhjYYpjijr=&QCJMgOUjaZfYX=&MZmesiWUqalh_=&kk2Ci4UW_Uk_b=&HwRSIqUmlredo=&HkLdPZU_nVXsl=&JeQDlSXXWkqYk=&xd7Ez6XXUXrkl=&yng6YsZhgrcWe=&giWE9YZhWeers=&DxlEL2Ycpsaha=&IPhVfUVdsjrgX=&drJm45WnUebXi=&xBzT3rUlXqodb=&8syNmMZUnUYWj=&jFDSmrYXWqeqo=&p95RnfWsckjpb=&ypTeHlYmkVnbY=&mIp9mHVWgqreX=&f8SUPsXhnlhkb=&e4OgKuZUlqZdU=&bLhSDxWaUsheh=&rg8DpHUUUomWW=&s3qnqDWYlZqZc=&eP_HxKWZqbbVi=&bMlVIbVcnqmlW=&QPV7FgZdsloXg=&EQejBGUsYXjkn=&4Xq7mzYbgpYbl=&cJxbuTZrjimYm=&z_EahMZghsYfe=&j4EUWsZsXopWg=&q7hyV8WWqrroq=&DvT4oHYj_mZbl=&WIOuvAVaYiip_=&cjngxnUXsdbmo=&WyN4UXVXoXjpV=&GrgVazWslmfei=&gKA47LWcsiael=&frLJaeVsnUfsY=&eXZNpTVnbifge=&dUmJe7VcbbYao=&dXTXz_YoUVZcW=&fnTx7mZYbsh_c=&RRhT3iZmmhkXW=&DacjiGZrXladk=&fok3t_YXfUqfY=&mAzn57Vrljkre=&2RAWFOVnn_sWf=&YYrwotZUjcZsq=&6fYDATUbcbnsY=&qMpulOYZZbdVY=&Jl9WSiXqf__sV=&pDDzZhUmennrW=&zryNqkUbWicfc=&opafYhWlefViX=&P5mxlWYigjpkc=&uaKwxFYWsepgg=&E2x4ENYsspanp=&RsJv7tWWgXpbg=&iRolpVZjfhjUc=&bVOcRWXhZbWmU=&XtdFx6YojciYU=&wsouUVZlidckr=&veFxcAYesmlcV=&ZdTTI2VspXpik=&sJRYHjZfadnWr=&A8CEBaVUgmrUZ=&uRJF2dUUmslcb=&KxpJHDVeokjca=&bkTD6xWsbbder=&CveAubWnadjhn=&OEiydzVVjlnYc=&Gn6DuXXVXWsWs=&rTMfACZhbndXe=&zEBVkwVrVW_dg=&9pI9UvWUeaXjn=&mGrUnsVnYrmYY=&SKv2V4UWYe_gb=&_TVQHgUVWiVkq=&9O5H6nYdZ_jfg=&fm4agmYXnoqdg=&bYpZwYXqlmnen=&LXjONDWopjUge=&cOIk2aVkinpkl=&rFqlsGVhllUnh=&ok2h9lZXkqWmY=&OmMHF5WWraVgb=&bbF4J3Xbpqmcr=&lmQ8aOUnYhqZa=&AoVG4UWmbqVaj=&No6nK7XbrcXsU=&ciGymJWh_Vpgn=&trtK99ZihXjdh=&QA2tSiYkorck_=&3JECOPYUZUold=&EqhNpEVobobkp=&Nut9gOUbnUocV=&ZGSvVfXnlZhi_=&JjKoosZqlfaqc=&PQ5SSwWaYYepr=&HYPT3DV_hmfgo=&oK7Yo3V_sXXqc=&QffqcPVlejaYZ=&b5tW6xWaeYqdc=&YOxqKPYsonjfc=&283lmzVXXpbZX=&Px8cDKYXjZege=&zYj_wtZpWUdql=&dohC3ZYZniWdp=&E6WGG4VmYXUhq=&lpqVnQWaiejln=&9ZXU3tUikmXYp=&HzUTGKYhWsZVV=&MP5VI4WX_Zkmg=&gIYQzGZhqflog=&Heb5oRWploggi=&VXL7f3XUhqbme=&75Yt8DWfmpngj=&AaZIZTZgqsaar=&UqauCOVhcoWli=&BlUGs5XrVpVYo=&HOEfftXmip_an=&ovAKPcYpYkadj=&_2W8HZWmnepYV=&4kYorLXWggkdY=&TC86CsYornpXq=&mSNwAtUmiYVlZ=&PKTgmcWseWsf_=&cFUSFIXaqnekj=&qXnvcJYlYgrkj=&of4oCIXlbVcqh=&PApjlBXfpmUdU=&I6tCATUaYfsUd=&U4MLmaVbf_eWc=&WrF3HYUnsfclh=&JjFAABWisssqf=&W73ljHXqlcqhX=&79e9lvVgWVosn=&SE6QAbVgrosps=&kyg3FHUqonacs=&qkz7gTUoUhrha=&SxovHxVks_frc=&FQKDGlXgbccrb=&ZNY7pDYgWbZkj=&kcuMpKVkkjqqY=&TAmPn3Waaqgfh=&VSPvf5Wdoflhl=&d6RD6kXmhZVae=&fKuGZXYddrbkq=&uKw7u8VsUhjng=&Ui8bs3Za_lXma=&tgUbaJWdmnXWp=&6jA4riVb_fVUj=&_FQC_eUpqoUhe=&LYDLl8UXXsmZf=&qZfmRlZokVqqd=&mLJQAEUZXjhXk=&NPkiniUYfWcbi=&X_gIDJUYaUchf=&mMif7XYqecjdh=&GMGIcRXsUqspe=&s6u8yNYZsaanq=&y9PaGCUUfoqVU=&ItJp4jVcsUVsm=&5ylI2wUfWVbcq=&O9laNDVpbdUaW=&xRkNXvZZgsdVs=&8KJMwOYdZVomm=&fCpqqNXffnfaf=&B36BcVUsgijff=&Ms5pAuYUhsbbV=&x_DCmpZcmWqpU=&ldYPMWZqWrepp=&FQMRPrWlrccgV=&aQlvk7VhjeXaV=&3AK9A4XUZchZa=&_evmx9YslZUYd=&vTsRR9XVlWWcs=&CAsbZFWh_dYrb=&Wy_VPUUWVapbW=&F_d7gkZXqWYnc=&kPEmY6UksVjfY=&Asxs8BUbXkgXb=&PYWHdSXfiocWk=&aC6qONXsYka_a=&OIfl6VWaiardn=&vNvgnlZacnXrm=&tk8esKWlldghd=&SwV3XAYba_eqW=&WH6B8BUYWqbjg=&VnpBSVVgeZYUi=&dIkujCUY_jggq=&ibHSOoZneX_oU=&eQr_cwXepsklX=&i23OksYVf_Vah=&IsVfHYVVZZXWd=&oXxZb5YXYbaml=&AS59O6YannVXa=&GxQSkNZgoisdh=&wDW6HXVqgolWd=&LqrvbGUnmjrWc=&nOuL83Vaggohq=&Qfl2wZVjeaaho=&t2LDEMYjrVlmn=&pCFodLUcg__ns=&WWG39tUiZmZYg=&xhym6UXkZY_aq=&XlFt7pYa_idmp=&Zgi_c3ZfYfjgc=&_KLGVAYgYp_eW=&f_JsEUXekcXpi=&ojKAcIXXXUjsW=&qS3MlDXnqZned=&aaXx8sXklpcYb=&cSFwkQUVjbYhi=&MpXjv_WeZkYhf=&YowsglZhmdcl_=&iFSmqEUqYlkYb=&v5y7mEVgjdlcq=&o8eA7WXsg_jrZ=&PNDXtmZUYYpjZ=&ocpdFhZfbZadk=&tIfQabYqcZpjd=&wzLOV8Zlq_hhb=&EzKjHtVk__ikq=&fPkpBvUrlpe_X=&l2uHPCWZdq_bY=&bvpvauWqZeqjf=&_E7SlzUWriccc=&yOJITBWrhiZWV=&zAg5t6XZXXaas=&FWFoDPWggomep=&TTkEkUWeprnrr=&3i9II_Wgknnd_=&nmzkmBZaeXhhY=&GaJpu2XrmcVWh=&R3npxgXkgZhkU=&xg5R86WfrjjVW=&c8Gz5YVsXZVYh=&BsaaqAZ_aYskp=&XE_X2AVXVd_ii=&BGCLLEXcmrXmf=&wYZlvQX_hcdgn=&qx8q4WZee_Udq=&XOHu52YkrnoVp=&XgwhOUZZVpcbY=&DCirCDVXieoeW=&lheSZkWsUbgmd=&8rhj76YWnUapi=&DerPRhZbegqks=&5BeMYfVglkmnm=&VWzdvyVaYkXan=&eJgngqUjleqiV=&VubDwvWdnjqdV=&t3mxMlYbbioVZ=&BwVhvmYgelWZp=&J3Dv9UXckZWpd=&Fl_FviVpVcVhs=&G5yn6CVcbgaql=&O6QWXyWWZYeoq=&SxOyAbUbdqcij=&q4LytEUljmesc=&CJ33z7Y_jgeqm=&FYMPe5YUihYik=&malthuZhjdfaf=&VJDYEhYYsfblc=&OkflOCXasYsbn=&eakFGuVUXmm_e=&PjRx5jZppfnmZ=&OT3QC8ZslfVXg=&aKdQNaZrkoX_g=&fB7dOdUb_ik_c=&69ZeEOUaai_pW=&7NSfmwZspWZYm=&iCld5RXpXkcrc=&MZmWUDUnZYZig=&WzKm9NYUcVkg_=&tkr8ulVXdesZX=&8gEvPuUZkWign=&OGMWbaUqeonsf=&h6nYHTXXYVhWk=&x98pqkYriikfa=&FIhtHFZfseYgs=&fs45PqVkc__je=&frCa8GWslUnbl=&btq2KoUjjscWc=&XS87q_VekrXss=&TgkRHCUgjmhie=&_W8Zv8VUWb_VW=&uCBljgZmfhbdf=&H5kri4VZpdoUW=&s9JO4vWlbiaUW=&MfY5IpYkrYdVa=&lBTpdNYfopqWj=&2YwU3GYcVWbVr=&n7ofEqYofoU_o=&Ksl8i5YfrqYiV=&I65fcEXcpUZcs=&_VGwGwWaeUZdU=&Nmh8lfZUhZi_f=&9Yff3fW_imWmo=&7TC79JWoiYocX=&BImQncWpYpboW=&7Ph5ETUbnYYiW=&qeRhPPXpiirak=&diEWPfXYndakh=&ILx964Ymldjig=&3wImY4XXWrkan=&js9P8iUddUXcV=&dXQJ_EVamreUm=&PGLCv6XnfZXke=&aDpivfVlkmgri=&kcJgI9WZ_anaW=&f3OaTOU_aZgcs=&wXdyblUhUkgjf=&5Ui3PvYik_XUk=&GwXejyZZmrebh=&_HSgx3WUsWscd=&MU9OCJUprdUsj=&VsgzAZXlmid_n=&UeVf2SXVkXfll=&tBn7IhYXbhYhd=&sAEsluYYdoaoX=&_7WUZ5Vihebjc=&VdB9mXZ_dbhlq=&Wi8HqgUgVceiU=&moGHSzVogamgq=&XdDJ3fXjnWfrf=&w8SmriVnhsVYr=&ogKlW7Ygoccoa=&sCbej5WUhUcnn=&2hspZCZZUegZY=&uLEvKrZcdcihp=&iyXKuLZUXqinm=&d7edQFWhfeoik=&DIYs2hXXUsjad=&WwopSEXbpekbc=&T5ZMJVWUjfqhk=&97VpzaUohfXXq=&HoFuohWnhmbad=&33JMq9Xbbmcja=&nSn8eSV_onaki=&EsVFsJXZqndU_=&MwMdTUUpeirZc=&_G8WVIUppj_kU=&q_VyFeXarrrde=&bsOMukW_cbnVn=&rj5WCpVk_porj=&aOvJrPVmdmYhi=&MHa4dKWjn_acU=&U2ZHXDWhdhbUY=&gGFOMqZnmhkXc=&wzS956UZnhmXn=&7BWH8qYsjkUsh=&HkcIexZbfb_ZU=&kDOvgxVVrZhZe=&MlbgPsWnYXZb_=&oWydxjWbnhdpp=&9ib3jWVX_fYld=&kX8fb9XdeoWlW=&5U3rdZYsr_Wqp=&VLRulFZfWlqli=&Hp6i2JXrVnjeZ=&AK4AvRUkhVsqo=&2K2BMlWfhWkVk=&fXhMDFWVWl_em=&6Zc23oYicgjna=&99NrFYVWkmVki=&btXejfXcc_daY=&HuDjyyVnWfeXg=&rCDNUWUejWkgp=&xEMETwVs_bkqh=&MqittsUdga_hZ=&sQHieUZoppqbo=&zT43vmUohclre=&D5DmxPVnhbdoi=&CrALBWUjnckai=&i4QWnlXoh_Yca=&UMjCq4VUflXql=&KKmY_uY_moWdq=&UxIl8oZXoqVYZ=&9AAb27UqskWpU=&7DT9kCZgjkjgo=&GNthRLVecVpmn=&rpnJ_9WfbskUX=&BXWp8zVbr_YnY=&2ZjaKRXWcqmcc=&aNZY7RXeijZdY=&X2Ys7nVmW_XVb=&oByDPpVrj_oWq=&UOeVJoWmZXZko=&9Esz49UgWaidi=&AEEhLlUUbaXZb=&BurWP6V_VVehd=&sq4JM2WlVscXZ=&_DOvxCZYVq_gs=&4k6vNlZjprjXo=&5dEHhOVhkjaad=&xcGVokYoss_ip=&vS79R3YXalclm=&c2HVs_UW_pseh=&wBySMnUprsidW=&v9lqLpUbclshq=&XyYJSdUrlgldm=&eRyGABXejemUf=&KI7XdOYWgfnre=&5DC4uuWpplqjh=&5amZq8UeZUecc=&R7gVt9WdZipon=&u9mJdCYq_le_Y=&mShHy_YkserbZ=&VyP2sRYj_fXnl=&WlIgETXiZXomi=&6LgATZZfpcemW=&BIBZH5X_dWiaX=&LOzvFAZlosfdh=&tbgbRPWZqZlef=&NX6mZAWrsYeom=&CK2iNaVlYZjoh=&EAhby_YkjeqYk=&sHuLawWbfZUoU=&iYUEoHWkiUgdp=&NDTbuGZlfVfmY=&z6nuZTXdsjUns=&pd588UVdZkaXd=&7RwXhTXWlWmsr=&TDpGRmYdhiael=&fOjSJYWshklao=&tNltE_VslrsrX=&SXNjQmZpfVrep=&seNedbVZapijU=&uyVyWjVfeVsXZ=&eDVlz_WVZeZbf=&6_dWSMZlWpnUb=&jZOj7WZcmqYrk=&82PYGFUqfpsap=&D76ADhXslWrrb=&SwJcWLVUVomXo=&8Bhax5XWaZjem=&EGgNSUWffVabe=&gL2EZ_UUiidVi=&NNmCkBXhkmaog=&fIt7kvXsWZgjl=&EA3krSZdnomhU=&SemW6dZpcjf_Z=&KI7mXTXdpjUsn=&q5hXr_YfYnbkf=&njUqVtUYrafmj=&s5xSZRXckkmYf=&CmWaAlWdnsUlb=&tqDqAmZbcaopW=&KNZypZWXUdaVk=&VijSZdYprWlUe=&R72OuGXisWXZe=&kaEyLQXjipalm=&wEMGVAUppYnhk=&ZgP9EuWhbaspm=&ZPF3WRWircXad=&De9_w8Ypdnfhe=&3Ug29nWcqYVke=&4I5E2hVoWladf=&OfooKsWpnWiWi=&UNIF8UZcrenWr=&pbmgp5Waqoihr=&kd6KULUeeXda_=&P3HYgrZYmhkks=&4YQkWlVcXiakV=&lsgTsbVhkZd_Y=&aedZaVVfZe_af=&bYIVxOXnfZqhV=&UCzjFAWsnccpq=&dEOzDqUUohroi=&sToqvwZhcljfq=&jmXhceU_ffXcd=&ZsmdAsVsibmjo=&v3TpoHUjdsjgm=&kDp2qEXrkeniX=&9RnvZoWgYqibq=&UbASDZXpXZYXh=&UmTTeAWafYqWq=&XJoH8iVgpjpgX=&xQugneWnlYpo_=&lkWOJJZeVjVmg=&Vgl_koUkaYrrp=&VPE23_VpgUinZ=&hsPaCLXjhZrar=&JsXNybYmeeeZk=&vyFd2kXjVagWa=&dWZVOVUUl_msi=&VLsSQhVYpgXlU=&bPNZy4XbpqXjl=&EWBzqvXrd__dc=&bmnZKUW_WWVer=&Y98WdQYW_mipY=&M4PY9SVqkoaVX=&kVzf3sUabVkkq=&cooR7uZdqmhrW=&gyDpy5Zsoedcb=&WxNpFmZjWhXbo=&Y6zdnbWZgonpb=&vnUiq4WVoZXfa=&WpKg9AUhgsV__=&FrqBE7VWbXqUd=&6U4bwzXolgYrU=&J9xm2WZbjoseb=&ZwceGiXf_anqn=&PQiccGZlsXppp=&vPZG_lWkksalU=&UMl6pWYUamUsi=&rG32mEUUZpoWd=&bVnUHPXbaechp=&7kLKPYUnppVZs=&Sk7s43XjpkYVW=&wLcEGkXesnjZm=&74Hm3hWUfWeUp=&_HaCFTUridpmh=&PITJBwUimjepZ=&i3l8G9YmZsYZp=&qlmPtPYf_ibhq=&8W5OD5YiVsXXq=&UmqYxjVVieksp=&VQTVWLUjccjXo=&MLM39nXeWWfsn=&nX5tGwXnsakco=&LQtfL8U_UkoUc=&NYnjBCYigbWsi=&jHtRYwVnl_UkU=&HkJqnOYbmsZXr=&tJIXoLYmnmrsp=&Pmu4lwWfliZfY=&fJG7UpUiqXjlf=&vLB5kIZZppUiU=&ipaixKUehkkdh=&wVyD8dZaqmdYh=&2MtLFmUqddUUp=&fxBh2xYdlbrjq=&O3ueveYiYccaU=&xYDbkmZ_qsh_Y=&4LXTyDUeWjil_=&9iHE6GXmfpbla=&ep5QFuVZrbkaZ=&vTImeDYUVlmZZ=&Re_RleVoYfaca=&mgBumzWfrhXij=&uogAtOVhZZren=&KxkebbZrhdecs=&NlPIYtZcXaq_l=&Ul2zkdVldbhfd=&udUjl3Yomkgqc=&v4Ukw3ZlipshX=&GrglzFVZr_UhZ=&5YNboEXVYWhlh=&YGOJq8ZYkrono=&bGzaOGVgYdajc=&tt5Cq9YgqlggY=&fUPUW6VffhVV_=&m5sn74Y_aroik=&94WgLrYqjbeka=&_bzuG2VoYomlq=&FkElnbXhkinqk=&o24ljtUmnf_sc=&wls4xdUk_ljrg=&Dz4r_IZgkbqWb=&r4FeD4WaqU_hb=&YVSAyMXdZXggc=&eRxwcYW_icnhX=&W5Lvk8Xa_iccb=&ELOxKKYglbXsi=&I9ll5pUeZgkpg=&NRDc5oYhdsilX=&VKBcMXVdbrmiU=&JIpjrFYmhiZqs=&BnyyJ_Xprmorq=&B5iTaZYWWWWsk=&B8mWlqYYgbVim=&N6QWkVWjhgsYk=&VZbjR2UbjYhXr=&IY8qAOZXrfrrc=&EuR92QZddfkar=&aWSYtqXUdqZps=&9mtIiAUkpalsi=&vftxM2YlgoVWo=&OO5zggUoqhXsk=&Ru3c6hVgUcsep=&WSnxVFWpnoiWX=&qFApqHUgcloWX=&uBlngSXggZfZk=&COMLenWsYXbjq=&EhJVbJWiXgVea=&ebwPYAVgiiesW=&kUC8KhWkWfWsU=&ccK_TfVffhUeb=&Xo_oXmUlYefWj=&rpjyU3ZrrkXjh=&yaBCTsWkljbas=&v8fiPCZlWWUXg=&kpY2RcXZVsYjY=&tqXsViZVb_iYn=&RTdY49WombkYq=&OEiTYRZcWnpnr=&UzBIlNXgbUUcX=&6UHcRzXXZYamg=&vELIIsYsiWaUl=&gxCpAfVrYUkcm=&ASCmeDXdqkXcf=&LSaTLBUoafarZ=&zPdcsJWdbkpdp=&_uxyv6Vdnhbh_=&6OdMjhYeVbVmi=&ue22zBWmZUVXe=&MsYbJ9VosWges=&75Wv5sWZpiUmi=&naO56vXkcoofi=&jN2xRdUbWenps=&ZXQJNsXn_lljW=&fPlKyaWoibrpZ=&99SZm_ZmdWgse=&ID7oNUVVenZUX=&NLJO2QXXclrbU=&J4bVfCYqejraa=&yiM6hvWfjoWca=&tPoadbWkplonU=&WVqENaUeYfkWi=&eY5ghtXZkqfhV=&SvFEGCUebqem_=&bDeLJsXboqmhs=&NAePGEUXa_Vop=&c4y_hmWjkqadr=&IcryYCVlXailg=&BN3MfgYolbUjb=&WCacFFYgUUbVj=&TabQaeZpkiXUk=&SVMRDWZpeqlZe=&y_wcL_UVplgeZ=&89acA7UemchfW=&UwYYgiUhY_noX=&4CyT4gYflVfYa=&eK4SayXkhcfYX=&vh__gwYeeWZii=&tEhEZFYWVbpVd=&4e_gFBWbcjjXo=&g8Wk6RYgchfW_=&rnvOwHUonfrpp=&kAyQ2aVVjbmVX=&LRb9J9ZmrYpVf=&dAPmfVVVWamqr=&MUH95bXsmdmUZ=&oYYVNeXkgWZij=&B8QuHYZ_gcnbZ=&_QWawXZaVqrho=&a_bJaGYqqeUjg=&HNq7SiWhXkipg=&g2QMRwUWchpsp=&3JMyiSVmcafVl=&c_2KGnVjnsUVp=&acb5taVofncjd=&MD8sJSZpsqVVi=&xeJqAbXehaeqa=&P83a38ZfVeqji=&XHLRiiYUYZojh=&o5E3LzWeVfUbg=&soY2tZZlgfUVg=&KIkyTAZXhkrpr=&g7nl_KXgbnrro=&4gjFqSXeqs_Vq=&NXX6X5Vjaml_r=&I9El9gUgqlklm=&L7WItLZ_plicj=&b4rlbbUcZnbY_=&GnoEtnZisXihd=&V5PSY3UlsrXcW=&ABemGWZcXsUmo=&fdmAEuYgnYcse=&TU5fMyUpUUnch=&l9Q_rWWVbZnrU=&Q9HCFzXqrcVsX=&a4AwwBYXjUmVa=&xlRMYXVnkUqjc=&oQ_HN4Xjg_XYV=&qfl766YqpVWWX=&lRabOpXVaeobW=&csZam9YmiohfU=&U2q_gTZUmhcjo=&xzK56SZrfflap=&p3yv65ZohqabX=&SSKMbkXhhdeXd=&xeqRQiWe_hrUZ=&IVD7_DWqmUgic=&gUaxKMXdcqe_U=&UgbaMfUW_sroW=&i5dkIaWejg_pa=&Fq_G3nZXjilha=&V3Lt_mZVrc_fa=&r3u4ILVeerVnq=&PkHTQJUgrXWrm=&hBVPC2Wdqlfsr=&FrGldbZicUjcc=&UJkYkmZZjiVnV=&kmFM6FYqYmkZn=&moaIeAUVnYkde=&iZ__ChVrqmhhh=&LpfDhuXhqrfk_=&wkWKM2XbdZpqh=&Iu3GO_WqeslrX=&x_f8HyXVh_iXh=&q5hIdxVVmUhVi=&9azcuCWZkprgV=&7PebntZhlniXU=&WGCEXlZXhoehh=&iYkiNkVfqoZng=&gsibg_XXZrd_j=&NPaKSbYgmoYXd=&gxlfaZWWrlcdY=&Hql5jlXkWlsVY=&m6JwzjVsYXbqk=&FhK_VJVqaWrgj=&lcaLf8WdZosmj=&ZlVP4wYmbpnnk=&CUSC44WZVWprb=&oNSAdLYsqecnh=&UHt_z3YqonZhV=&OpOswlWZcogmi=&vfuAVmXeogrgg=&dNGOh9VbYhbrh=&Vmo9MhXaYqZro=&NoVYmpVepcnWl=&EtbcYkXXjgoak=&CihrZTXn_sfrZ=&AW9wYAZWVnqXr=&F4NS7yWiXnlfq=&6VtLOtUirrZYj=&xfzfVSUsgoXXW=&PEOECNYnaljpV=&dgV_FMZcVsfYf=&n7QhltXfncbhk=&zdjSObXpkgndj=&zqZPyEYrmcXoY=&7qwah6ValglqW=&V6Idk3WjXaqW_=&XzHOPYW_odhop=&Ie5V_gUcZpU_m=&acCDeeUmj_qVo=&xtK3IeYpiWaUs=&fhLym8UnrlhVU=&SQBtCFXojmjUr=&PsHNmiXr_UXri=&wVAg2BWkasopV=&_Q2IKFVfan_lh=&4Be2GoXpZdika=&BbECyWYioUcoX=&Ks6MyiYgWfZYe=&cQi5wDYrVeUrf=&NC2PtAZknnhil=&lfynIaUpVV_qn=&d9ougjUc_Ump_=&5lSQWOVUqhYim=&mTArzQXZb_oYr=&rBYzOYWqgpqah=&O9Q7kOYanXgYr=&5ydodHWsmeeqm=&4_Cu8pZWmVlen=&cVUC5dVocYYee=&QR2iCLYnpacec=&WHZpm2Ymfoefd=&rdt6QyXUglsmr=&7hWN4uYYgfpYk=&8vp6WoUYdkhZs=&QJNxi5YimcmWY=&JLbl6zXmifsbk=&zPsSCdVdciilh=&ejZVWbYnrkpqU=&MMTIOyWWVgrog=&upWyRxZrX_iUh=&VO8I8_Uijroog=&Djb8eMZcqnkjc=&4VpBxLVkghboe=&ZDjNCkXYcfldl=&CpjvBRVddcYsj=&gTiikWXsbZ_cj=&6hXDBSWXjalYn=&39tYpCZimjmcZ=&khqbOQUnsVVUe=&sA7f2aUemWcpm=&wNIvWkXkfdelj=&rqO6YpXklihfe=&KaMlEoZokr_Yo=&2yDT53WfoXo_W=&W4buijXjWUfZo=&iW8qj5Uedhdkg=&BDP76UWgbfeeV=&m6fQUUVhYdVdY=&cluxCqUklUlpW=&3fvvpjUlhsdhm=&nfnGAFWdr_f_c=&_rwQEaUaissio=&tKvaMdZgYl_pd=&EQKAPfXiqfheU=&b6AHdxXpYoeeW=&xd24gWVof___j=&AvzGiZXabmejf=&NlWhcHWgfXjqW=&ieyYWyUrgsshV=&eIaSbiWlko_Vg=&QkfE3mVXpjW_q=&UFitKrUcZdmck=&a7hMIZZXqeklY=&GAx_fEZqpsZsm=&r_744MXqkhbqb=&_UzQ_2ZqjhgW_=&WhESgpZrpYpfY=&dmbF9UZ_sZmoq=&i5Sh8oWXrsZke=&ZFiLMqYYUfieZ=&gRnFpOXdforfe=&XzvexuVUahmbc=&pc5i8xVniUbeh=&sMI3zfZprkjra=&u3yM39XnhlmYX=&LGgSvMVUpbgVX=&Hrt3zAUoZdmjk=&NUMgHMWrXXqWa=&8ICoBKYeWiVgo=&oL_838UrcmhXl=&CmAXrYVXsWZsa=&tfOlxFXokkbdp=&ObYnvFXsjZ_lj=&DND2XyXscirWY=&4eZcPMYjrdqmp=&qIKLVMUoldecZ=&7ouIvuXgjZZlV=&FpZkhHVmUnYeq=&oG6ASIZisgVgg=&qPAyXNV_o_Zbh=&sd4VZOVUdcfrl=&GFzaybZrnkdjd=&VkytuJXYimmcZ=&zTEe4vZfidlYj=&Z9VaeVVdkqnmh=&WpbKg8W_apWXe=&MYMB6eVsnlZXc=&wMIvetZVUhhsf=&SeO_lhUhpangU=&yIYpSjUrpriiW=&C5hOu2YaallXo=&OPAGlGYcoqkfc=&CsnDTmVWjXllh=&OPICYxZohk_Ub=&7w2ZqYWcZXfgU=&zmNTfVWUVqflb=&Z8ykGNZYhWXho=&2oZkdDYjfpWWc=&IThqzOV_riZZc=&DjvBhCV_lVZcc=&DRnuFrWqqepYr=&J6caVYZpkWmkg=&kNnnvVXVmnYmp=&M_7pxRWsdsslc=&TQ5OmSUiXcaqf=&IbcLQqYrerVdp=&nwkYqwY_WcsUk=&a_p8ZqZYjscnj=&xgDjNWXlZeZUr=&_ITK46X_scheq=&weHro6Uag_ZWZ=&47nERUYfprmmf=&m9cEJtZrlgjql=&TJpN8gWkgUfrk=&s75pfeVasjnam=&Rth4sTUnVlWab=&lK28KkWpqmVec=&iMSAPLVYbfioU=&7exSF3Vhpno_p=&n_76pYYpeqniq=&gnqjvCZjoeVja=&4Z3DUZVqfj_ka=&ch93yAVVWqXmp=&eu9MNFUXkeXVq=&EK6tZwXogZga_=&S6rNzWZnXmdoj=&RcQGW3WfmgZVb=&Ay5mSCWjhbkgc=&UYopmYVcedYZX=&XwRiCWVadmboe=&4WI7_lUUZehd_=&3sUbWZYqembnV=&x_xQxkZksZlpi=&ZSpNDUZXggsiV=&wZ8tWzUfoVZga=&rXamNHUnpYpld=&VLH3r6YiYqUeW=&czYmqxUYfpXik=&xs_uEWWVqX_hl=&XA_ghpX_Uhlhi=&mOkaZeUWm_ojl=&iL78ZJZgrjrhi=&KWGZUCXjoqise=&dsRs5YYlioqYo=&K3QevvXeYXZqY=&hi3pG_WojegUq=&6iQNkKWXfZkqe=&3qa_8JVsVmYeh=&4PjauGZooUlYg=&hQsvPZZkVYoYn=&wxUItqZsplcXV=&xhEFKKZbaXiqr=&e5_F7ZXenZs_Y=&oH32atXXkWllq=&IyyAUaZoajXVZ=&ZFz86yUgnbsWq=&luMuCXXkZdZmp=&b_QPXqWUqbgUl=&EPMWpMVZgYikd=&xisorqVUUorUb=&IsbwreXrmWiho=&umMUz3VellXeo=&TpE8igZVnZngh=&ig4X5sVjamoep=&xU7aifXgWUben=&nR7YtrWhZdlbo=&h2MJlFUcnboVd=&pRtPMCWZUbWjq=&xJgQ94WcfsWeX=&wwX7YRYbhsVcs=&F9sb4OVigisXq=&fVx2RkXrghZWU=&7nZEpwYhmn_k_=&hKqXSfWhhhgab=&xbfFdlVYqsjcj=&L_d288UlakXrV=&yqhbweXqjbqe_=&ZjJHBXUiWXaYk=&yC9ehwZWfjegb=&VnckmkUqWnVqf=&HddHBeX_Xfofi=&LKcV7XWnUrm_s=&i4mRuJUXohYmo=&GlDHSlVcgcXr_=&lAVu6bWlXsVma=&6nW7FFZnbpXnj=&xu9maGVneslkV=&HbjS8KUdcXl_g=&RzZbHiWsesjnY=&yQXokQXfphfbq=&u4R8IJYWcVohj=&UxLAmPZrdmbnb=&5S4tXtYoajlcj=&QhkTlMU_spXdn=&acjLrhZ_Zmgmr=&yHE66lZlomXdl=&qd95BRVhk_oZj=&GeoWalUabZkdh=&bP9ZgpYokjq_U=&ckohbiVXjdrXd=&DaL8opUskZi_g=&g29iyiVjcZopq=&dXnjqaZ_aUaeW=&6gtLbeXbkVZkl=&4TxBo9X_VYcdY=&57ApyLZpnmapb=&8pbrv9ZXbeWra=&xVgTsfVrrbcab=&Pq7MkMZshbolc=&2W9CBWZUecbpe=&xFVkvLXWsVffU=&xDFgGaWe_hdcW=&zvXHRqVrnWUrg=&jPhMzNVsrUYqq=&vof6slVaplWgs=&SHFiOSUWUjUYq=&qLggj7Vo_Xqmp=&KNoEYsYqeVmen=&BqYqRqYrjUrfX=&TVWvE2WihgmnZ=&YfHubuUeUmmln=&A_HoQ6XqsjjpZ=&7gUnmCXnieZfW=&qjUT6CVgYojgc=&hmjPRGVopjfnU=&bSDjDZWZVinds=&rzSB87YipdWsp=&69zM8fWlaZZUg=&7kVoUoUpXYYko=&WAUqANV_bcllW=&2kIqRUXlqeans=&eyMQaMWrhUlke=&r9O_SKXrrYdkq=&WhNEC4WjXshYr=&NihLVSWehifYX=&yLKStbZXmpZZd=&3jSmkNVYsZlUa=&R6vSUxU_s_fVd=&dBzJsfUhqrihn=&KM_GYtUZkrdel=&n7nrTQWWmUspi=&coFpS8Y_XlrZW=&2dEg8fYqoWifY=&PVGP5xXbV_Z_d=&P3ftg8VpXZnkU=&_7QFjjVnZiVog=&z2rjNOYnadr_p=&7gS82_Vapohki=&aCIlYaUZsmUiZ=&FmdC9wYiU_lkW=&vyaKzzUgp_mpk=&2tvfwXZksXmWm=&8fzDgVVUsXinj=&fh6CNiWl_h_WZ=&2v5XGWWadVYcW=&fasDA_YeVbWfk=&jebVDgXrWnfVm=&KlkeLDWbs_hgc=&YlLZnBUeamfin=&YbKPxZYofbscl=&Xv_EtoYnXaZsp=&8CF3xjXkcelZg=&fBhQB6Yb_rbVc=&tQkwwYWddsUVb=&nCxKOIWrqZWaj=&WlHzROXalgdpn=&FfxogKXjfpkY_=&qEV_bhYZhdVhl=&EO7BNiWXmbeje=&teuTl_WXYdgWY=&m9eYuUXZlhbXn=&DFwsLJVqefWfa=&bgimY8UcglYlh=&GqKMMsYfpUpsa=&4RRHgAWcddUsr=&Oz4JTEU_sihim=&7sg_Y5Wgpmohp=&CmEKsSZiXqUb_=&DdqXfxUXmdUYq=&nrUlHTXZfqgah=&L7XR4vYiUsZeZ=&JRHWqvVVgbXaZ=&lhwZ3WZiZmlVi=&BOl2jXVkhahlm=&YZ_ZA6Wflhaqf=&rcDH9lWlfZoea=&Cqr6EpXnZmUjU=&BlAxTJUgXgUVs=&4eKgjJUZohihd=&tmYsPbY_ejlom=&JBm5ftXpmejes=&S_XLkVUbnnigp=&6quSROVidds_o=&Fr3HttWnggUgd=&6SNdY7VpepemX=&zWRozyUrkac_b=&j8qS4OVdej_le=&GbIZafYWrlqXj=&Nq6r2yWgVdoap=&7DNth6VkrlnUq=&TiKNcLZnfhoXZ=&s3c7ylZoUUZpl=&jTLj8BYnqXcaf=&VGZcKLWanissZ=&IP_x7vYeVsjog=&X_2VUIUVb_acY=&4sSdqmWllddfU=&Kqk2PdXdZdllq=&FEo4UeUmmqijk=&8UwAXIVbYi_Zi=&PDY3ncYiXdio_=&ZEIfFwVchhmpc=&FaFvk5YcoZmja=&foP9UeVjZromf=&q_ZcuxWYaUorm=&Iwy9iAVckn__p=&wCorqnWhYXbqe=&GlyczBZi_sVrp=&vl8FmPXaqXYqi=&JwJ9MYZlWlZiX=&alGYoeXfecYUU=&jDt4GDVZoh__n=&JihCehXVeo_dd=&lk9FQkXemsojn=&KpyIi9XVekpl_=&pu6YEQXrpchgZ=&POMbDWYhZZklq=&kvMPvWYWjshW_=&Ge8nR3YfZWUdh=&OYPJZVVrsmlgk=&o2P7RWZbccWrl=&8BntkhYXdmrpm=&mEiEyQVlaZXqn=&yqlOGcVXVrmpr=&DzJefoVbWhmnr=&2X92e8Wgfoegg=&iM8jkeUZViZYa=&2_EzlsXXsdqeh=&NNlAf6YpVYYYY=&WRZJywUU_o_dX=&6y2XMDXZpoZXY=&xvHv8IYj_jUki=&OedeGpUdbjoWY=&_u_SppZXWVpiZ=&hezxrVWfgdVUd=&giYN3LZgpeips=&ivPuhIWYnXZrq=&YW4owoUqYYahn=&PL8mG_XljqiVk=&JSj3ZeYlihigg=&pAJg32VqZabpW=&KHj9wgZWfblil=&J_s6x4UZZck_p=&ChcHLBZpjablq=&aWsex6Uplf_qg=&DiDmJfWfaanUZ=&tKTi9FZWnUmis=&ivkzEEYZjkkWd=&RrWvZoXZiUZeg=&NQySeSYmhiXkm=&roRErmWckVgdY=&qDKFdJZhdVsZU=&bajUAVVfjkprl=&sSPbLPX_XdUhV=&sV_CPlXlbXarX=&ncMEnoYpnXlsp=&ZDSWj4Un_fshg=&SX_2fnUrngWUn=&97sK_dUZjlaje=&DYnzH_ZjambVb=&s4Xj7CXkdYWpZ=&ZJwcw4U_fUgjo=&xJbH3MVhgdsoW=&hHRzkyWreegbf=&mGe8PgYXrdljm=&CzQPtBVimUhqb=&SJOoLrUkldkmg=&IPmrcGUdjqbig=&Li_zzcVohlfYk=&DWGmutXgVbgsY=&CUooiTWaWsZhk=&KUuTZ6Uobnfpo=&xMMBohW_VhcWk=&Lu6Y_IWiZXbca=&CPwXuWXklYmb_=&emrlIlUVZcoYs=&zEoQjdVaZXg_b=&y5PmKLXaisrpe=&abVy2NWXqpspW=&yvnJHaYbgbqkj=&LrlBw5VqWh_hi=&3ov7CRXpqVfVs=&9aW9Q3VX_iXic=&532TrBY_Xjpm_=&yES7DhXaVrb_p=&jtt2dBXeXVk__=&e3y9SPYbcirln=&fPJGryWalgYsg=&U_q5jfXdbeonr=&T3w_roZbfWgiY=&BHP52oUbhejgi=&V6cLtjXpemmkW=&7PwfjIXXhfeVp=&DaOE32Yidcr_h=&iknRb2WgXhejU=&sYiCiOUlk_bdm=&vzLUxsXjqiamX=&Y6EzPsXirpiod=&vLYhiDZpbfnag=&L8x8qtWribcqk=&XXzVmoYrhXngZ=&PLdI2NWqWqjWX=&XNVuatWq_basq=&kld7dgWjeYohq=&a_EbTFYbqUrdf=&odK7TOWsblZdf=&8XELHmWZUq_qW=&4MHazFWoW_nlV=&7IUQbyXsjaZYp=&i6GQ5xWV_akU_=&DlRIMMZXcflUc=&oNIeoVU_XUamo=&T4u2odVqnna_e=&QMj8tmWlVjqYn=&WuoTnQYljmpek=&YsWCFCZodnWjo=&Hxkk5OU_qXnah=&a7SyVRYoelUga=&nLfYvvWqhaiZo=&UVn9TiWYoWfgf=&zb8AdIZ_hWhVr=&2G597YYfpihVi=&_GyxWVUZdVhbq=&B8AVCQZdUneUf=&U7zDsdYkaY_qs=&wdvI5QUfqrllh=&CFbpr3Xecbiap=&vY_3BVUrYd_sa=&wZ3ajEXZs_Vca=&PVO794Uprrmn_=&fyh6_xWZdUpjb=&VyikbbVpcsjnm=&amc7YlXkWgrge=&VJlVHuWYmqWXl=&xXpKAwXjUkase=&pTR2OIZmaaplg=&u2zsCMWp_sfWX=&Q9okvzUlsrkVc=&ogVgEqZp_raof=&EAGOECXmWapoZ=&rksqVtYUZeprX=&ebiXuEYnsrVaU=&sZn26LZmgbcdj=>nCEMZXbqqss=&o4xDRMWZhmhio=&84TQnCU_YdoiW=&aZHjnmXqVfce_=&IGjaZKYdlgfhh=&XpS93bWeopfeU=&IdLalVWsskX_o=&5TKiVdXgcVZan=&3d4wTSUrrmYkW=&tDwXosWoqfWej=&IbqVnvWdVkekh=&m8fOqmVXWfZab=&D38ntEVZbpdsq=&wzBLZMUZUcjrU=&VmQewJUVhfgVf=&G3BMBYYikfgWc=&QUi5nmVZpecqp=&KXtlrtXbYVaip=&ym8VBgUphogZf=&NF2YfeYpXirYg=&dyE_YxUXXXgim=&HebPHyWpadrYY=&NadPxBW_Wrdfh=&i5YeSHYoXcZkY=&LmSd3PZZYrnma=&zIhyWiZVijZhW=&kC8CdtXZXZYaY=&b2tsX6YhjVk_V=&gj2ze4Wqnlc_h=&yyXskPUgpUjX_=&vifCLrZqXmj_q=&64ykCaVglpik_=&GiyZA6Xeab_ef=&Q_QBnUVYiVhfn=&YSAwcDUjjrmni=&l5XihNVmrbeUq=&2jbno3Zcp_YXY=&QUEJxDYmekrof=&viqtr2YrsVZhZ=>KoYYYjslmbj=&sGdmzCWiojbdo=&J5NaQ6WkUands=&BnmuAKYdhj_ek=&GRnfuzXZhlWrc=&3lZm_dUhjbdqc=&W9ZlSDYppqsqU=&PdYcJFXqrUUkf=&eY_HiUXqnZljf=&w_Y7ivZkaUUnk=&UFG4VEYUfiWsb=&dyf_fjYkpbiZa=&jkEwXoUpWps_d=&6iBNsAWnofbbU=&LIoAesZ__ojce=&Ffr2bAWUaqorj=&iwcFSvZadsl_W=&_jY5nIW_ljqWh=&kd5boeWhZpbpk=&ooiDWoXbbjrkX=&aJNaqxZkmr_fZ=&YMJWWMYciqgWs=&HVeMLlZbdZjbf=&43sTWhVYnUohn=&YaD63XX_cVe_m=&D4Vf3NVporYaZ=&GfzESiUlfmecV=&MNMYWpVVoZprm=&qySR7nYcYimZ_=&VNfszKZqq_jep=&SuVk7gZrjkokV=&xA4QsNVcZnmiX=&VyQT5UXWXcUdY=&SKfwmlWWqVbkp=&4zZfmlZ_greka=&3F7jSnVokhVd_=&Niqw2tXccnrqr=&h8QYbmVZjgY_d=&IQrKRHXs_scVs=&tfl3KbUXgrZge=&O9Fxo5WdgqfWd=&ioFJ7mV__reeV=&HKYrOOUlarhsi=&W8YUWVYgjbXnr=&jJY3Q3YUcriqi=&4DVWrcZbddYWb=&6GkoTPZdnmrsU=&VLziPMXbclsrn=&QpCfLyWqVUgWr=&XyoLToWZl_csY=&wuKtGAXYrcqok=&OBHhPoXkghjsi=&dyp9HDVVobkc_=&qsp3gNUUXnYdg=&VnnFREZgWlgsk=&2MGwwoZdqWoXV=&oMtdqFVncWlda=&UcJXPjVf_inie=&6C8CVMYjWhgko=&FM4kBYXVerqfo=&ScLU9QVjgXjms=&oL5ISkUoWsbZq=&MbpOaOVrbaeYk=&7PAhGjYrcij_q=&_qOpqPVUodqgV=&eo3YJbZmnsYhi=&87mdhrXbdVZnj=&8LzEXvXgbnqij=&k2z7BqZdlqjfX=&8whkWDWesZYrW=&Z8bBsTXYWYcha=&tLLzPWVYUigkb=&Hc8npvWcWZrjX=&JBRQvfUshYoWX=&VKPktZZdX_qfV=&_e5LVeZhhafrY=&T27_FSZq_rgcs=&bbtXFDYrgjkXe=&4cN5h9UgcqslZ=&JRXG_RZopm_h_=&y4zV9gXddnak_=&PvyvWjVpoUhYa=&bjfrXeVbsisU_=&IXeldPUVk_b_n=&RoQ8eNWVWf_rh=&EvNm_DYrkahVl=&9IBNRJVUrUmil=&VnhGc_VarqlmX=&UpP2asZnnab_m=&cVbMdYWe_aZbe=&_ez8tGYbaZilV=&qXrm3SVphWYZf=&XxUBWSXkgUrhZ=&EWDRlEWq_bmjm=&GE5vvxZhkfdll=&vHsHJqWYicndZ=&J6gj_XWadVloa=&cDydNaVYWdnlg=&Bx9G7UWbeVrkq=&Xfl8kGXjbWeqc=&vOokDwZn_nacg=&ji9spcUUrgWim=&fx5j3YWnh_mhp=&KYgQs4VqWXnjk=&AiZFUtX_qVjap=&4N6WM8Vdnabpo=&n8LNUUVgWfink=&ITXKlyYapemmb=&ouziiTYZoolXg=&Zf7M22VVsW_WX=&2beM5wUfefolc=&le6mvNXlsr_Yo=&aJg7neUnfmqng=&wmVM35Zhgqpqb=&AtI37MWnXZkmh=&UhB7CHXXXkVqU=&YkSglEWqgmsbh=&VlEICqUYgZoWa=&z7i8SZWWrlc_c=&zuXLJwXrfrisf=&C_uW7PUqW_rjm=&LJd8hIVldlcoW=&_CZFNLZibhq_k=&ulrbpVYprkdVi=&26J2TmUViamZe=&hPw9dmXorVYWf=&6gQ6_FVnjdVVi=&SJA992XoiksYa=&arsAZQUjnaYih=&aFPlunVossWbX=&pGzWJ6XUWollo=&_ACdheXlcpXdg=&69kKE8VhmhUdl=&TBVploUfnhVmg=&jK5pepUqrZejj=&Wi3ExuZgbZpfV=&IJLjxeXlcbhgX=&F7lF9CZiZpVUs=&OJ8neqZdcpprp=&8w56vfUVrgWjs=&lll4xjUZXmUkd=&tJlApaW_alUdX=&PNEHgxXmqdrnp=&aZK7HbZnXcjcq=&LMttmuYiaUhkj=&gRwkf3Vh_rp_Z=&MWw6YOUklXi_q=&sm__fpYoZhpse=&_JJy5bUkfi_kf=&hge5XQXaqqjbc=&2TqDmqZfZcV_q=&du_5ssU_YrWWd=&I8EovrWbXVlZf=&AJycSGVhrVoem=&K_NvcBUYpVeke=&VI73hIYrWfogj=&JSwrBFXmmVrXf=&svDtQ3Vde_Xdc=&SpKDZ9Vpccjml=&sIBm_QVWfjaqb=&FeVGwlUaZWsVk=&B_gk29Vrmqjkc=&GQfJjoY_Whfpn=&UsF576Ujqrm_n=&Tz4CI8XgWrjki=&CF9ZvWXXjdXhi=&fv7ZJ8Xrngkmp=&4lrLMSZXYnikg=&Gv_mGbYoXWkok=&J7k_haXkoUWqg=&tgQTghWjbZapk=&7tCncHXVnlnod=&UWmEzyZVnXcYo=&jLSs8JVhWrsnV=&Q_Cs45Zmoopfb=&bHrRitYfopgas=&x_sGxGVZlVl_e=&pEFpJqUhXlsk_=&W8DE3HYihYrkk=&Zs6AxWVcpmalr=&4r5IIDWsmbaWn=&LQtrHHWYUgsXV=&Y9TXrMUfhblqi=&5Ff243WdmgVsZ=&tc2b_RYaYXsaa=&XowiGfWrXeiVW=&PagiuuZXonebg=&OLStgfYgpcZjh=&bIZGVYVgjnr_s=&vDfTZxWlXrdon=&j_Uo5JUlXqYVk=&FMFDn2Xcnbhga=&RxqG4TUnaZfmo=&ZpudSpXXWrbeZ=&PGWABDXfepccV=&H2_BiIWpj_bqd=&5bGRJ8VrXVYqr=&4haWuRXpiVkWr=&RqASCTUlmpZhd=&bqkWzjVWn_Xdc=&WGMasKV__jYgX=&d7MyFJVUibkpZ=&yCmPkbXVbVmhk=&FkyHjFWgnpebY=&mBgr2pVVeUoUn=&KvQrr5UUYcqln=&QJIOwVWakoYhU=&CaaP2DZnifV_s=&47JeOBXo_bsXj=&xX66qSViXrjhg=&qtwHATWXXhpfh=&en9REQZorr_qo=&bwCKpiYhklcVs=&g84ATHU_Wikol=&9pegbbXsbU_np=&uYUOfNWsqdZZo=&Fwyv6OXhZWfbj=&bROp3ZUrrfUcq=&6dHrd4YYbZYgh=&94ZbqRWpsmpmn=&6XaYdhWWmlfhY=&3mpmGMWgnZjfo=&GGhoq_Um_lger=&MJN7ThZkorqcZ=&fXrOA6Ycpqmjf=&cE5BPRZbrs_qf=&4ENJrCUib_Wse=&8DHFcDUYZnkas=&xJRpwHUfmpfgp=&mAq5WRVofmXsh=&hFbc8_VrUWhka=&CrvN2RXbVsfdf=&StfbkGVslqYqm=&ewrxWqUfoncXq=&JstAR6WinUlkl=&QNQefWUnljVXU=&32to8gVVYZehg=&BbORUbVW_Xjmg=&kyDFUIVflYs_g=&r3C999WqcY_sU=&kivH9jXXacaok=&8mqBQqYdklUsj=&mqEILrYUsqol_=&AqkGBUUrWfeZZ=&Wjax6gWrjiUe_=&QoHVZBZmrkaZs=&J7x6OJZfYXnmj=&4LCbCRWjaadXg=&iX2I9dZWWmYhm=&4gT6jEWfkXgrq=&MUGVftZWfirfs=&oLc5wLVYVjigs=&lb_BP3UXYYWgi=&ijk4I5Urkl_Xg=&Rfn7Z3Z_nbYcs=&Uw5lnFUacjd_Y=&IxKK9GZpksdsd=&qZBztAWbYkqXl=&RxDtzLZ_nZaqc=&Mc5KVdVkZjcaW=&aPJ2nLXkqdj_j=&AXEPfEZ_YZkcY=&6E8WJtYgUlqag=&gsaZddXWdsehp=&uhfaTUX_afokq=&9dft62UlhUVnk=&sS3fcPWUbqoYq=&FjZWpHYnndVbj=&LWHCvHZXmrYUq=&6w_YWwUdppUap=&lLoyvrVfVWmhl=&Etn5ofYXZYghf=&acK7VmVkkgpff=&FT2TCqVUqoobh=&7uLEB4XcscUoX=&Vh_2ohUjldZkV=&9cR8k6Xi_Wdic=&4xGUYqYmkeWid=&YUtLfEVdkmUoW=&8rpR_DVZsiVVU=&JXlA8VUbcileg=&K4UaZOVXdrVmk=&O8myz6ZdVheVX=&QoOGf9Zegsrks=&OiWMDDUZgsphs=&kDtar9Ydofgqs=&4TDyNMWYiXWmU=&V4ZMwxXdnqfYn=&u3xNNdVgnabkq=&O8I8ivYkVonea=&VWmDz7YXaibcW=&R56ptCUsnnkng=&NUaDsaVkVparr=&fePMtbYUU_gbe=&hzfzKvZqqXnUp=&7SCgxcUpleUko=&ESV_KBZjkiqZ_=&QItAnmXijabjn=&KHZSKvYfaXVgp=&GOm9NeVnprdpk=&2DotdIWWljUed=&V8t3WtWZejhWo=&gCZFHWXeXmnns=&jVeSmnXobfkfk=&pmhTvuXjbV_oX=&MPjmmcXgWnW_d=&WldV_HUagVYYe=&QOw2FMVbkZhiV=&WLCkd3Xsmslmh=&jR44doXpg_rbm=&xcpLdvWreZmka=&6LVBBEUYmsjnm=&SaUfkxZiecpcf=&SpNvKmWdrcYdj=&taBalPY_lkWZr=&GiEU8SUqafchm=&pWwUnmXUllaVp=&Qldga5Yodqooo=&QS24opWZpgfeX=&e5iDY_Z_fmrqV=&wDbYWhWVYl_WY=&z98TOdVsnYhak=&CsI75jVfZUWcd=&jH5xlGZrnXYpo=&K7uuVPVkY_Wae=&lSBGceV_XlYco=&ZPlHZFWhiYffY=&vZ8xwoZhg_aje=&V3s7ZSYqloZj_=&Oc38PZVejZani=&8kAnnkWkZUqYn=&Ww9cmwUohcZaj=&iHiA5tYnh_Wej=&jVc3dlWdqYbXi=&pZiyzFZnUldrY=&C43xp7WcZfjUZ=&CClb6uVgmZnml=&jBeryKU_ZiZsc=&EAOKk4UXalhgh=&I5tulHVlgUmWq=&mRAvBaYWVierq=&Cu66mzVhsknmb=&YSzNicZYaf_dk=&OCF9PIZirmsgX=&H5tsqQXZbcnql=&5YtZbQXsUXbds=&gYh87YVegndjZ=&7dUwYpWsbnnoi=&EIQignXkskYbq=&n_HBokYgVkbmo=&jBp7ycZrnWoWl=&UW5TG7XUZaqec=&AiXPlVZhqWXUU=&cTDTatZcphXaX=&U_KLBMZlZrZii=&gdA6KFXajsgeW=&itJuXdVcpXmfj=&OLPngRWgliroj=&g2bf8uZebsbss=&Nec5pOZYlWbWa=&epo5_hUYXfhfd=&MORqeRWYgfmpl=&x4ZFCeWjZflof=&wdRteoZWlgpni=&qfUboMUWjkgi_=&yu6xtuUXdanjU=&zBmiK7YYVfpis=&9gtEaKXdngpUm=&zPWZYNZ_Xriig=&d7Ts8CXrXlpqf=&HHfMgsW_hsdc_=&_XjkSBUbXXahW=&jixvbnZfUolnk=&soZwcRYYkblhU=&RLFyoPVZYe_pi=&igPT8wWeWkr_j=&fYkHR_Umgk_k_=&8pXZzUUc_ko_Y=&IK8qX4Za_iUdq=&rx92nKUXlfpps=&5YdGq7ZaplVYm=&uJ6mDXUeUoVkY=&pqHyIcVeVrimU=&hAlJUVWYrlidi=&jVN3HlYgdqhVX=&CGR3HfYWkloan=&UU4QMCXmZqsek=&glk62qZZWhhcU=&Ow77prZZpbWVU=&aIk_8NVdobslf=&w_n7ZxYWjaniY=&IPuncHYZcbbpm=&PlV76MZWVqcVY=&EZK8bVUjjXikU=&XQcUU7Zlbknrf=&GiYFXsVjolYqm=&dgJ9ltWgWfeXf=&skOsiPWfbkkZd=&Svs_8mXkkceim=&xAwLG6VfsV_ZU=&FMZcq6ZeiYVYm=&ePK2_tYcXlbnk=&RlPIAEVmnsdV_=&fhtUgVWkbrqba=&QkBySiXWrljYi=&IvoaNtYchamnc=&nL3e42XWVsnsi=&6e9_TJYrWipqq=&vcupwDWagkUqY=&TifBqoXXVqZkU=&ryiJLBWdqcfUf=&iXYLbwZVosjho=&YjvSuEUkdWpgX=&LngbjIVbshlcn=&RgSnkjZclhVsk=&QZglCAWgXVdjZ=&Xf9UCjXccmZms=&hXvH3NXmnk_hr=&PH9lxlWsccqVZ=&GXiRWdXkpVedY=&W8YKT8VrjZXqV=&zAuDl9WsVmrki=&PmaXv5XpYiqmq=&KmDLm2VUVdobi=&hScOB4Unalbhm=&dKQ7QlUcbsmaU=&9VnBkOZjXgkps=&iNZbsCYrpomqs=&A2trOnZesrsdc=&Z88DC_Wbbo_Wp=&epBwXrZpcbVWj=&Pib_rqXVca__k=&OqMv_7ZcUdnah=&Zs7GT6VYrgeZr=&83yyOVXYplgfX=&B_rAoRWrnajbo=&TTciwJVhrZboZ=&XEruw2XVWlheU=&3IpG7gWplrpag=&mA3o6ZYihXncc=&bs_sgTVkgWclZ=&tSaniRXqcrhXg=&4AuWsxUaamqsh=&ZaNJN7Wrdqfjr=&Oh2x4rUl_YZjX=&WE5ARkYhkWacj=&So6Bh8YVrhgig=&KcFNpfWpiokbf=&oZRihGXoaslsk=&_lQfakZWpmZY_=&UeHVq3Wgpbe_V=&VG3RpRWhU_Var=&E3TatrUnjUmis=&NUmeBhWVcaqXc=&ff9FEmWrhhjhh=&4FjbloWgsWrlU=&cKGnM8Xljgjql=&L_jhxBUVosbbZ=&_lgD98Wkbhlpa=&EgBXjAViWffej=&GfuucrVialdeg=&lf3ksbUXlhZii=&TgY_rWXhZrXck=&GA_59HX_dVYib=&36RkCsWYofXbi=&EjLbsvUnrWYda=&WA8y5tZUrYcor=&4nmLqiUglWcdi=&2cYNXOZZoeXeZ=&QHrRjtUsmXhgc=&uTo9XqWiWgiUj=&5mvk3uWYrgasr=&yIt7S2Wrk_Zno=&XfScm_VnUnsbj=&9ecL6yZrmUUol=&NjQm9GZVsao_Z=&M7oZtxZdogrWZ=&MCKdrRXhmkmoY=&vmV6FMVcVjXfg=&GzElcaZeoijkX=&vLbpI2Uplegqe=&YWPnJlZddfWfs=&DP8wj5U_XYWhl=&nu7wLbWeZ_rph=&bcHN7YVbUqlji=&UX8FkPZojXWWs=&K9NRZfUhmZXpp=&66ywjoWioUqfj=&FnEX4eUgXZUch=&22X7gKYpcqVlX=&EIoafeZldjajp=&_OWHJGYmhcXkZ=&KCDjXRUWqhUWm=&AL7yXKZgWXZgU=&C39aBLUfbdhqX=&xhkBKTZkqrYWZ=&ZBI2D9VgmVmXe=&XwMMnmUannqre=&34vMhKYnf_brs=&sOz8DFZfachjf=&m_55VqVnoiqYa=&zFKRVWUdUakdb=&pF5qhbXg_nsrc=&hihmEHUfrbaor=&7BPnhbZcZj_lc=&WJRbteUrVjaig=&xk5tiQXVsZc_U=&FErCQ7Ubaeeea=&rlGPNkZhi__ji=&Qts_5mWWoodVs=&2xXW7wVeaVddc=&jAcZBzYfpZiYg=&xV7R_JZjiVjfW=&XpPPIaYmWUYjm=&DWKuXXYeiW_Zl=&9lVewEZkXpVro=&dXPcIrWapYosa=&4Mx94MWhYWWgl=&eGdP_sWWaXmhn=&Zd4mvfYolVWqg=&AwMuroZpccppk=&wpDuCeXV_fsZr=&C8anhgVglfggf=&9QDesmWiUckln=&fKQjOyWZcW_Xr=&jEq9PqXcdolqY=&qTTQ9iV_arfom=&OY7GnaXjbWosr=&3Ywq2dUaZZWYZ=&otjDNzXeUVdgV=&SMnEY_VafgqiU=&8l9buzWaXXggf=&n8deDxZYirrgV=&6BP77NUZiomik=&eniXvjZVraemY=&wZcE6GXjsYfsU=&FgZtVlYZqjVsb=&A7t4XFZjlUjhU=&9w8cebYZjZsWU=&w4hCo2WUiVsmZ=&3JBFK2ZmspXXl=&xB9iC9Xmasggq=&qyjCvKWlnaiZi=&2lB54lUfhakpn=&LdhpIdXracqhh=&hJ9BpsU_VdrkY=&vEdwKPVWXgW_Y=&7mWGTrZZgphih=&C6B4gWYVs_isb=&MNQceMWYggjiV=&e_HvFNZqla_Ul=&tqgyrJYh_eUlm=&d63TbuUUkljXo=&2StYj6U_nrmdq=&YQ2yLaWmWhqsW=&WlTnoWZdZkUof=&xCnPGLXieYron=&lq3MFaXnfXris=&qePv8qZahppdp=&3lZ_VVVohclpp=&tQGbrdYcriiea=&f44o5qWhZelVe=&s7oqWtZnrdbhi=&vYFsXQYgefXWq=&xBRk97YegUehX=&gNebEwUYqXUkq=&CEi5VwWrqYob_=&Bxx9qzWs_Zlej=&LuaHrCUqhmmds=&SNfRDJUqmrsnc=&53YPuYYhi_rhn=&JZbvePXXbohgU=&QqIGZpZnpWack=&68ms3NWgUsllk=&LNTat6UpjnbnV=&iSCeuzYbWfhhc=&GlX_FJZWclWVo=&69mnhZXbamsob=&D6pDRZYUisleg=&b7NzbdXklYhbW=&ssaxYSUckhkdo=&6QAVCfZVYjUch=&MFwnqVW_iYqZp=&pcAyDWWliakqk=&xiCrREXYakYrq=&4wAq9cUUsekfd=&mhpEnRZnjbZVV=&HqjzrSWpmlebi=&QufcodUssefnh=&eixUJwWhdg_ZW=&mcMeQ3WifqZmZ=&nq6LAaUYn_sdY=&6xY4xmXrjnfos=&T3_L_SWmohpjc=&5Z4yizXgWchoW=&2UcriHVemfpmp=&V8Ds7VUUarZWX=&UNidpvU_bmZYh=&YD8AqLUUjppih=&jLqWumU_q_odg=&jNR5mMUdmrlbk=&szR7XRXUcWddq=&3BDn8oVknodUq=&YXWdyQVdq_ark=&jJk7AAUhb_WZY=&zi2SoIYVanfgo=&Jvm2eNZ_gjleU=&jEy3d4YhmWXoo=&aVrxslXYcqpiV=&eRKexkVmUsrpg=&5xcKSUUlWYsr_=&NmQtSnVpq_frk=&qs6LrCYjis_VU=&sY58dKWUimXnb=&cAvEZQUqrY_eg=&eOyXptUbaWXrd=&wvD3ChVUkYjrb=&ERe5q9UspUqfW=&RqAUA_YfleoUW=&CMC2nIZ__cd_r=&f6gDFUVmWglXi=&Ay4Pi5Xhk_ish=&zUmmNhYWkskdn=&G6wCeQWlUla_k=&GMwHUtZi_ZVko=&tjAOBiWkscUZn=&E9Os8hWffpbYr=&HXKVHdUlrhoXg=&9TcuI_ZhjsiZe=&BcAdXsWeaUjhY=&2HQCCoZoiecok=&FRNU9iZZkngib=&G_AQFkXmrfZrh=&YOBGNLVreXsVe=&BxDanDVhpbZr_=&Ub4kknXidWifb=&lpcHpuVYUWimq=&mvcWoyXjffhYd=&sjb7LMXlfXhUZ=&N2rknuUabYphY=&OWiVmEVmardlW=&F3Shs6ZZXkjYa=&YQymRbYXarcmp=&pSNUHxUibofsb=&znPHWqVrbcenf=&7pohXMZr_aUag=&xuPwSvWaXkidY=&tj3qtIVaj_Van=&LUXWB9YdkhkYo=&KfdgxbZlrWpbk=&DGwCdyZmodplb=&roAPgtWWp_rYi=&ORCME4V_Ydeaf=&W9jokxYWeZXir=&MWSRtcWsikfcm=&tIMpnwYcjZXb_=&SI9hVcYgnanVU=&wBIzZ_WYpcWYr=&C3Y4qKXVfqb_e=&PD__hBVjdXfmW=&yLtT7YVYqdbil=&pe3SKkXglor_n=&Du72BOYncmolo=&iVFacqYjrYYds=&RYtHIxXVjiiia=&xMHQokYYhYkWq=&LUFRamUfejqll=&BeOmYhWsamUkh=&cXXfCDZXbYnrW=&JARfpIWXiZgcl=&obQHiRWnjffrl=&ua5DABXmqWVUp=&KjuEu4UYqgoeX=&WIi_6nYipgYmU=&hpZeoqXdfrpja=&4ZRUjWUrrblYj=&nVOI9DWlVeekq=&gsXXQnXdqr_n_=&KyWsIsZXZr_jo=&jtyrqBZplfWho=&vK6shTUqpqfYh=&84ReaBUaY_l_o=&a8MwdoWa_pkXn=&BVwrAuXZac_km=&jpGbAoZrXUpcq=&ms4jUEZpkcopU=&OzwKmYWjaleWU=&cuiwpbYVoUWph=&nZC6SVUrYiibb=&AF7CDqYsWWmkp=&BEiROrYhZUrqr=&p5bvvGUleqVVg=&WeUzvNYae_hnm=&oNjFvDXanrndf=&rAwDLJWgosgab=&7r229tVcmcbgX=&7eR_GvZqeUghl=&t9ER2RWZbnsnV=&n9kfS8VaipeZl=&FSlD8IVnpiXbk=&alorqOVoknmsh=&LfDkgAVaoirks=&uZbbrDYonpesW=&pRz3F3UoeZmqU=&nrKsX3YbiZaga=&MR4cQpWlldlkY=&B2e7XKZraspV_=&tA9iFzWVrfnYi=&WMC7dUWsqrWkf=&ouoIlOUbgimYX=&IRDu6VUUgcrXV=&uX2MupWWffnfk=&I3TTRyXaYiiZU=&5O6vvDUlUfrnf=&qadbw6Ujesksr=&Ey63SbYqbllgW=&YHz5FsUYZUcWd=&tQcYR4VZUflsk=&tY4lNuUjparhZ=&dBp9vFWUmrZqk=&Dnp6M5WUgUiUj=&Xa6TJ3YUbflfd=&WKlOOTWascelW=&bYEY9CWridkke=&hCFMJ9XjdrUlb=&23MO98YUWkpmi=&BNvD6JZlqhdVc=&yEcpiAVqmplpm=&riIsWuWV_hkdZ=&692wRvXrcZcqe=&XeYvcWXsZggkd=&JDCmiZWiZspWa=&E4TUiNWlicXlr=&3ry2QuWWkjYfb=&o9eRIXXgYWfjq=&98yFRmUnUYfme=&H52iK7ZegkXef=&4HP_faXUVi_qZ=&aNXdg8ZfZd_hc=&YMA7TuUsZZbfg=&cSkMmYUmmhXpc=&RzNBGxXUjo_is=&Lx253HYrqnVge=&qFO8m8VXXnspX=&wa2YfhXlqdUnm=&7QH_DxWksa_jl=&hbuZ4QUcVYVgX=&dmM2mOXdcg_sn=&OoUePlYeggk_f=&B_MctXVkepYjb=&pKSs8vYbreXYp=&f2dA3dYppl__g=&6cwa7GZbmoakU=&9cTPpIUajdgjb=&YYbQUmWbgYYgl=&aNMDLHZqsfnVl=&SrZuIKVpaVcac=&3niYsWUgemcll=&N2vd3rXsisrXV=&2RwercUVrldeU=&VLtEzoWWgoaol=&7aARkGYYimmks=&rOlRoqZYWVenf=&ZN6hp3WYfpqfd=&loCZoiZfWsWlk=&tVTFZYVbhgYji=&6RjzpRYZkgnh_=&RQnYXQV_fcqm_=&ZWCnNVVncVWlj=&CdrPqaYjkd_bV=&JZpYZfWsfsrqg=&Q8fOgDXgclkaU=&sNCjegYgpefWr=&KIRY2EUs_mila=&uvub6yVkferjW=>nBRTXXYUVad=&SHngH2Ud_kpb_=&aeXl72ZXhUUeh=&QN2tYBYencWkW=&I2S4UeVWscfVU=&O7KFUCXipcWld=&rJS_7qXlpobaj=&PuMFY3YkeUZsm=&5TTOpbU_meZsa=&R6K4y4VsWdqsn=&jySUTAZVhoae_=>lkmfYial_Up=&JPadW3WmheUhe=&TIDgB2ZVealao=&2m5x9IUXVqmXq=&M45L_sWdVgVcW=&CexlLAZfWXWni=&s_ZicoYdheoe_=&HOkDNlV_VlkWc=&ivCDOzVlWVegj=&VkT2lpYfglUbp=&dhAskXVgroerX=&mYqAQPWakbmgp=&CnWKrGUfdsUqj=&TaJDWMUeoiamm=&PrWhTAUXZlhpW=&GR8zzsYcirilV=&mgnuchUZiVsdc=&MwRRGRZmmfY_a=&AlAlwaY_raims=&T4NIptZYa_pjp=&2WB_KOZafqrll=&j65af2XcfXWae=&STH2YkWYaoZmZ=&lNe3MSZmmqq_U=&CDKH4mXbeUjVW=&9myLNGWnjonhp=&HqJn_cZirpgiZ=&ZxpTdqVfirUhU=&zxY42TZfcY_Yq=&Il7SDjYogrqVe=&dnNJOnUUnUlga=&q5IzK_ZaYmank=&mZJSadWoodrXf=&GnzOAKYjqgblq=&Ef8b8NVgYbb_r=&r8tsx_XaUglVk=&ZwovsLXrkhXmc=&vIMkyEXhfoVjd=&BASSjcVllVYf_=&a33raXWrbjjid=&Dm7HTWWlnldms=&sREpP4XpYcide=&55_cTiY_gijeV=&tG4DdkUnqbV_W=&XXeVadXYknhWa=&mAMAreWeeqmdf=&he5ng_Ycdo_ig=&mgkNuiZiXbXco=&sAYFBJYepUqgd=&PRSGMzXdia_jl=&B4JRAQYnZaofW=&2vkT5PUnlr_np=&afPLEEVqjWmrh=&q2kcBEUisjnbU=&j25fXZYfcr_hZ=&Ted3HkWqsidZc=&_ff3N7XneqnZe=&YgFqgyWgkXoXk=&avZSq_VpXcmkY=&aPCWFzZUjcoXn=&SJOV3aVonUdUW=&ijUFV8ZZhkgkU=&ieMrIYUXoXlcn=&I8Uk56YojhlW_=&PfS_n_ZYkomWZ=&eno3XXWhaodhj=&mpwwnpYpW_j_s=&uqBCxkVUVolnd=&ugoKVMWkqklfg=&ynwoVUVnfZfdp=&h2QLdAWeqiro_=&EYj_mJWWXock_=&hVOkPLZeogVfs=&MTtEiyVlebqnr=&yXjde9XkekfUo=&dnyEy8VkYYXYe=&76ZHdtYfreYXV=&u5AH6SXmjlaYm=&SWGEurXgrkfmh=&AlEeSaZ_cXsnh=&ngdh4dZikhUqo=&IRnQWIUbkmY_m=&YE8o7RZsdcsgd=&upPwhJZcjfsbr=&CSUpCiZo_kejq=&iDz3uOWgdbYZW=&tFN_jHZVemmqc=&nhV7TZWkrniln=&qRpWQ7XcZeqZg=&NjuMDZWkebXUr=&L48K8iVcUgdcd=&qZDRsuYlr_ekY=&J8PrJSVmicgif=&q8KIcRYnXa_hU=&gbEmCDVqrmbpb=&SrK_WNXmZjrmd=&7z3OoKUnm_WZc=&dvy4WSU_lVpho=&6dySxrUre_eUc=&CGkIpKZ_WVrfo=&BErnDCWYdsoga=&6gSQM9Ukehabo=&MIUKJ9Ycbibcm=&rv5YrgWdhqnYX=&sIC9tHXhpXm_d=&hhDmD2WpYZg_c=&cxsfM9ZYagkck=&Ew8El6Uelajqo=&kbnYG2Y_orgcl=&V39FbkZYrgsWe=&L2Tkq7Xr_bZXX=&pBfLqTZdoZqmf=&xDwNIBVcUdhcm=&vTGcv4Uopcdni=&7HPgKAXrWeXfn=&FqjdiYZsUZVYp=&BL7psmVnasaXX=&CpRbD7Zfkaabm=&H6MRoIUsfeZeo=&2JmsCbVhesiYg=&D9uL9_XYaZhmk=&7OmO8RXgisrla=&gTuyTAXseglmV=&wciNqVZhWZqaq=&zMrjj4YcfrYbn=&dmJnS9ZmnjqkV=&5swx7rZjssWer=&V8YguTUjbedfc=&9X5wISXirXcXq=&O9RUqhUaeXZcf=&agW7CuYqdeXre=&jkA_VzUdf_hfc=&X5Wy7EVjldnhm=&VHvM2vWsUl_kf=&ITOqZUYbnpjVY=&5YmeevXXdWmmZ=&BYnLCaYqobpqY=&55qZgLXlsakml=&K92NThY_hqjol=&BSnwkPY_kp_di=&NgcK86WoadVca=&ckmbrOVreihWc=&vpMgXDYbVrW_g=&enluhVYXoYmnd=&Wy79rdUnrWhhn=&pWorrUUYUpVhX=&l3lTMyUY_jgkh=&yjopVtWseUsrU=&DF9QzhUaqegfa=&CC68cOZjZbriW=&24P2lUWVUogYr=&x_QWE3VrmVdoe=&CsVgfGXlpsrrs=&cTKLBtXYaqlnq=&DJPfXjWWcpVji=&E_N3z3Vfbdlnf=&cvnpHXXplgqgh=&t8N5vVYaledfh=&3vYDwVVegbcq_=&FIUMVvYVVcrVc=&lh4IiCUrmcYfe=&ETVSEFWZhjVi_=&EGqvWUVXYeefn=&h75oFVZablkXq=&7ZtJgJUiofWak=&7LB3MtWqgZVig=&x8cyXEVk_iUls=&dZORKmZaUmVXV=&rQ6RtGWjYkrgb=&t_78iNUYa_ebj=&ixiPbMUUfpfnm=&gjR8QGYXYksbY=&eOQmfPXcZgaef=&CUZB_AUkf_Uo_=&QL6DPqWsfbcqj=&BgQv9WZsbkkVo=&ikpy5VWrcojhk=&ywbyWTWqjehpi=&3kGdoRYViVbXr=&scOneWUWhVmge=&_B6k6bXpeeVpp=&PNkpNSUVZngo_=&m9bmbmWnfo_mj=&qVZUxFXUginZs=&opu9O2Wnaqqg_=&aSdNzzZqphjd_=&ttFXJZZqcibsj=&qaZyObVfjfole=&vgy3HgV_lWolU=&3SHJLWUYbmmhq=&KZ8cyWYWpkdpW=&xlwDj2UXVXfqs=&DsFkELWVUkcgn=&oNUaweUpkklkm=&oPFla7XisnpbU=&AXuTeBZhbhbfe=&_qEJQUXoZZbnX=&9IFx9RZVZlqqc=&3dFRwtVnbUqlZ=&zvJU8oYpqkidd=&qF2oIwY_ec_gf=&VxpP25ZjVZqfh=&uehVnqX_qaqab=&ZonZ2JXrdfoUU=&x6vbOWVWZcXpn=&wNlTJsZeZrqcW=&uhcV4JYdZqkfs=>ncgEVborgnp=&PeWi2wVYgnldh=&goqi45YpaZkjj=&q8EVtpZXpl__h=&pDgGWyVdrUmWk=&GF8FtLUsrWing=&vnJSzCWdhmZgc=&8KlmdVXmXakUh=&5E2d5AXsVcUgb=&_WXUjxVjVWjoW=&OGRb3DXlXodXr=&fGsLsVXlZspoc=&wEbHfVVXbjhee=&QuDM5TZXphgsh=&258Eq8UbdZngm=&NtMiOPWa_hpss=&Pn8xOfXmobhhW=&gl8RLsUjWokpr=&bDsxeAZsZfhWq=&57usGAWgXijZe=&L5VdSTYXagYom=&b2jKXnVWU_Zoa=&hq2OcdZjfZfrq=&8CLjTKZqpe_jq=&mLvvq7UWeVhak=&i9DBcZYc_gdiV=&sqHyzFYaVsidU=&woXvCMXqjVimc=&VQp9dGYshbgZh=&YSiU4MY_UqVin=&2P4KDSYlqegjh=&dVayN8VeiijYl=&jsLb5kXp_XVoY=&3ynwV6WYhlhah=&If6sflXeUiapj=&RqnhRhUjf_rhm=&ne7JOhXkhmllU=&mPjj36XXZnUWV=&RAx3uMUYfUmqs=&f8l53CYrYsUrU=&Qrve2nVkWopeh=&pUVqYLXbrWVgm=&9rD3JcZZibfgU=&nuZa7AXbjmZlq=&Loil37XdaUVao=&V_LkeyYjZYYYf=&mvSANVVniqqiq=&PETR9lVcYkmYk=&PeYT_4ZskVZXa=&bt6x9jUfdnmjW=&UDxQoyUiloZZc=&zh9QGRVVjjmXV=&C5ete8ZjpbhqY=&nfIKStZcknr_n=&9cGvDOWWrppVb=&z2LVWKWoqjVal=&oEgRaEYsUfbdl=&QiQARfZod_fdd=&_qJ9vfXmYmliq=&66oonIZ_nXmbY=&EES2yhZqeXahY=&FdowmZYZbYgWU=&JrDvfVVkbcZpp=&h77DsSZeViVfd=&hj9ZHvUkqdldl=&6mOxo4WUjg_Xs=&YXv8AAZm_cmsX=&DH7qdnYiWhXfq=&IgCr6qYZZnapf=&Yz3a7hYlhWgmb=&Pa7NhcWmYs__m=&ZhOUATUabecr_=&wrq58IZnXWnkZ=&ahVeFyVdnlnij=&D7dxjvY_iskXj=&jsMt5cVaeqVZs=&eDbIDPZn_qiV_=&skrcSwVkggV_e=&L_yg_FUcmfpVo=&uRwvcgWWobkac=&XvL9KTUrhj_Yg=&pa4YNCZWmkaXW=&mF3afcXdZYdns=&GVZypHVWfceYr=&QqerIRYaWnkim=&TlwoCcVXqiYYd=&nGWclnYkXsdU_=&qhgPkyZcZZgkU=&hSHDnAWrjUlUc=&3NlVNXVXU_hZg=&KQaEHRVcoilXa=&JLYbJLXXgUdWh=&XdYBa_VogrVZU=&RoE2AzUgZ_Ysn=&s9eS2OUYqVXso=&Z9of6gVfaflWa=&cDNEs_ZoXZjoZ=&erQL6OVkmbnUl=&_dVJ8vVoqgdea=&UiC9N6ZXWcskn=&bGxc9oUbqpWXm=&V6g8imXc_bbmh=&qSpWbdWmlsfnj=&6evRMqZjalVWe=&2c_5AjXpeonZX=&SFTgwqWaqYWZo=&lxybIgXZ_bqpq=&DZVnKhZhqoWoi=&5a2xuHYlslWsg=&pN6JxhWXZXcjb=&XLPs2kYeUsoqV=&vsGIeKWlhooiU=&rX7a2MVYoqVcW=&4XkmIOZjcfsoU=&9Ad4_vUdmjnrY=&2IPtCQUojUcin=&6wzYjCWan_VWo=&sC2VmxXdgZcdY=&ByWNX7VrqVhkk=&NDYtTcYYcrYsc=&bT2cp5UcapsnZ=&apBM85VdXYqsb=&xdH3B4ZjXgmnc=&DZLc_dWdmqsmW=&Fi9tTsVefkmig=&jdUz9YUdflmjk=&4rg7jPXeobeZc=&rNAkfyZodqhiV=&kCFd4cXcrfWpW=&p5nJE7UZbXUWj=&eFlSyiYfcgqas=&mvM9MmXhZYsfq=&9EOq9lZXcYnlm=&Jf66HTUfinYqp=&jkifqVUhdYolb=&QfhNf4ZqdmrUf=&ZgewHhXadmqqk=&8clRMTYhcpeir=&Rk_qJYUpUfcYV=&bzb_w9ZjcXYb_=&IiSrSEWjVeejr=&TQ_dw_UUqWdci=&UoOMp2XgWimdl=&xSxc7hZsXao_c=&4VoPKwUrVYnmh=&OEqK4dUqYiZs_=&lpIS2sWmnWoXq=&9COvFQXknXo_c=&ZeL7ovUeVejnZ=&46ycI_Z_obhUa=&ZLD36SWhdXiZn=&jAeuZgYUYpocU=&SbEpyPYrrbk_h=&RpLAHOUdWVjjb=&7tD7K2VlZrbnk=&E49DPeXXchbfr=&7jzqhmZikpnap=&bKjWrCVsZmnsV=&TlD78QYpZpg_c=&C4awKyVk_hbfq=&K2GBr8WZXVkUm=&CjDVQZZmWfU_h=&sIyfieUVXbWcp=&gSWttBZdXlfYb=&AHrA__VWshiUr=&XC7YZgYpioagW=&QEE_k7ZscUhcZ=&hW322wXcqVheZ=&XSg4CSVkbgmpo=&qcccLwZsrbjdZ=&VYrVGAUpjVfUq=&KmY9bzV_lrqqc=&cB_uViVeYWUpj=&E9zcVCWWZXqgX=&PhbpiWZnWaZZl=&96o5ehVacjsWV=&SzqC2TUkqfbZX=&KcPf7gW_snboh=&vmWvrEVsckc_d=&mry5TTZkhsjiV=&dHtmCXWekWjie=&pbk48MUXgfpZV=&59djWsVqWqoek=&L4b3IeWikadre=&HVTLOLVUoWchi=&7UijxJVcmrUgo=&9aN39fVqYbWab=&Sie8WeXqoglmc=&OoS7MMVdoqXWm=&LMbouCYYlsf_V=&jnR7hoVhZbpZn=&CHDcCjWVrasVV=&R9zkvgWhVpsVq=&HgEQNTYmX_UWh=&pO5hODXbpqVdZ=&cuPgh2XijhrYc=&ZqS5VBZheVgUl=&BKFkX8WpffZho=&EBG2SvXUWUkeZ=&7LVQYYVjefcjf=&AYepNjXqbXri_=&nwMJxgUcXpkZd=&hFddHkZeshUY_=&RtN2UdUaUdUbW=&LEjUgaZlkXbZo=&YXOaPFZUjnpZj=&kM5PPGWgdWUea=&EcC5KcWX_Wkaq=&yJHjw8ZqZmjao=&9Opm62XYnlZbp=&LRQbB_UodVYqr=&6NFTiVWs_amfd=&rZV3FRWWmmkXX=&K2KEnCUeisqmf=&FB6nYUVYfgmmn=&TlKmf5UhWpsnj=&vTRvTjWWfnbaY=&HTHQpUXcaacso=&exQyTxVWlr_de=&V2wOeVVXmXeqX=&Bq_L7KY_oncjV=&geaO9yYefpcib=&OR8MYfXorqhUb=&EHgEPbWihdshp=&RzbgJiZUZjshf=&SVggr8Yms_YXb=&PvXvJbVlYfWik=&laQEZAYYlZnbl=&gvOvO6Zbmerns=&LtHrMKYZqfrlZ=&4JII6KVjnjaaU=&i78G8GXpjb_ri=&PbiDO3Yiaqmig=&MHB2pqUhYaVep=&TvTW8NUabdmi_=&rb3TbPXYqhbra=&lBELYlVWVUflp=&DkrZnKYglXekf=&fhmJifW_Uobsi=&8Bo7TiVppVdnk=&3QUSrIWrrrclq=&eKLCywYmklcls=&nTuTQlY_is_do=&dsbdFwYjrmUsf=&74WkiDYeYaajc=&j86hOCXrkk_ir=&BBbaJcXmjqeZc=&XRcfCwVpomeqo=&Fj9fJtYsp_YUZ=&Bb5dJfYb_bWmg=&DqrkEsZYgYehb=&evRAPHYe_ebnp=&RBiJnTYmglsYp=&yycU4YWjih_rV=&3WJ58sUVVWYcp=&5aBrJBXgmVdqs=&vsxFevW_psqXh=&MWnhGjZecVclh=&hCnXXlZmoihme=&dAWSvJWj_j__e=&sLgAznZm_nlqh=&cc69i4YcnlqXW=&ipoIUPXgrZqc_=&VpyINFXgh_lqg=&qXfPsKVWa_Yen=&7qVxftWggrnqb=&oo6tgEVih_fUo=&vCBugNWjoshaq=&IXSnZhXUll_rb=&K9VFqhXohehoj=&pmmnfbUXXfVZi=&fAnBVdWeWUoWk=&_dN6x6YsWZkpg=&7UpK2ZYZlnbfb=&IMWXU6XqXpsmk=&VIzjWvUlZgYX_=&vyyCStXseXseh=&xCdFbjVciaprV=&jmDhjIYpfpWZd=&XbeFNoUlqngZm=&Kjx4G3Wjijsjl=&fcKyWcUrkbUqa=&RNAHtJVopWnkp=&DHe39GUcokelk=&RAM5uHZhVdaed=&eOQrwiYgr_Wgb=&qMVEsyX_dbgcl=&VlK9TSUicUfYV=&BF5_UPUairU_b=&zgiXPmW__inaX=&mLg4fMZhliUsV=&JZh5wEVVibmpa=&tCAdCYWrqhglY=&jXr6T_WUXmcfm=&rbpb9VZbqprkY=&yMSi3ZV_ZXmsX=&Hde9bzVljkics=&b4WlogVZUcnhe=&FlsJKWZeqbsiU=&tHDadtWclobqY=&vt5WzQZXUVisZ=&PlJh4uZm_dfcj=&lLBtK9Vbiqsid=&lD4WUUUsWYnah=&OS7y5CWUe_ebc=&DB_ppPZXWkhbU=&hEyAapYXsZkcl=&KdFiIsZa_oidr=&jQHyp7UhoZeZl=&ffsazyWiWnfZd=&EQ7lXdWggnlUg=&_WHkAxVrmeikb=&paSftOXfnq_lW=&IJfLTXVsVfbXh=&gd7CNCWp_WUma=&SUkg7RVegqjsU=&4bHYUrZhlaYll=&W5ZlyFVdqeqjr=&BsB7S6ZWbmaYc=&w8AB5GUUlabbc=&73swy9WVlYVXh=&rThUDqV_jsXcs=&25L_wEY_gVbar=&VTQjP4WbpWrqf=&ttErlQYhZqhdn=&RsqBKEYYdgVVi=&YdZIt7WUjnhar=&WaHtwCUsZbrqa=&aWvznEZ_qmZas=&9t2n6MX_dejlr=&_wRUSlZYmYmWc=&Gcj9yPZeVaer_=&jinS4ZUfnfbnY=&kxSvE_Umsd_cq=&sIakGSZlhfqmr=&9mTMoIVWpqlbY=&QSJL_DXbrcaXU=&mjMakiZlUZnfX=&q5JuAZUgigfWc=&6rv6VqVakqrqa=&yJbHrEUmhbkcn=&9aYEHzUWeilXr=&F3cpICZjiXYsg=&tEwdTnXllWfep=&Rc3AMEUrUjUZh=&3c5QhDVsqldrh=&9Hfh_TYaYXZXe=&sR9duAWfUogXj=&Wzf2EiWeWYgmc=&_kE4r_XoilaZU=&bwNftzWnXrh_U=&RZSUJRZrdVcgZ=&dNEF_MUjabr_V=&vDvEJWZrqrlbs=&_bAM5OVlVgUmb=&aVFGBcUYe_i_e=&oZfK9HWqrearW=&k5NO9OXgrrgps=&3_eXlWYaaneaU=&HUSC6zVWnjZZX=&nB5gEEVdUodmq=&dnCSjiZnrpgZX=&MDk5dFYehhsbX=&ZjvlZjYlpejgU=&eUYFw_Umhhsdh=&35_zDVXnbehga=&5tFZUZXWsrXme=&qMIuTZYlWsepb=&runhkCXghjlaU=&2RNf5cZsZdUes=&2AuhBMWimUkVl=&CpiJfUXqiaYbq=&92JemaVgrrjhq=&w_vRAwVdmlhsl=&PhK8NiVj_VUjZ=&KUGqyWYapeYiY=&L44v_IYmk_aXm=&rZuHSBVfqXh_r=&k2jqeZUlskalW=&8lr5oTUohqpaj=&g9GCqeWdZkUZ_=&ZqTlltU_Xknpp=&juBwC2WhUaajo=&6qnUZIVdXkabm=&FzCqlEWsmlbq_=&3wdzvjXsfsUpk=&BNOFW7WkiiqUU=&6SRKnYYiYhpak=&yzaXxhVkjgcqb=&hgPzNcWkkafqm=&JPKRB_YYigaYZ=&dyLerwUkfhrgZ=&K22TCVWfog_qo=&3Lx57wWgprgmh=&ZvGIvLVebokVU=&aY7E5qWVYrsXY=&Wuf3IhXpoZiqo=&86tkIwYbYegnY=&WDWxHxVZqlhds=&3H5jc7WgpZgep=&Sv3BiEWdsZVfl=&XdhRBXZlU_XU_=&RB8finZacpnUX=&MlZ_ybUXUUccj=&oAPrMkUkmbVgh=&dyZolzXdcimpg=&3wHaZiWoYnUjh=&CYYPM9YcfaZge=&Eikw8LVjXqsog=&IboAwRUekobgY=&SeZmwkXnWkaso=&vwh9i2VjsYpVU=&IaRX_VVhijkVm=&jwxEyBYqhckfk=&S_XIZYWnefjlp=&uURKm3ZneVdXr=&jnCpx7ZbfglZa=&_v7NxxUosZkmk=&tKnWySXjio_kX=&mx6pehXbeWmdU=&QnvXkiY__rf_i=&hsAYerUVh_oVi=&3OoYecXpjqrcn=&Ly9HBSXXbrsos=&z7T_LPWhdlkbV=&a9JMxpVbrXWai=&TWhzJtZdpZXla=&z78o3NYXkdYnV=&jysLs2UksWhob=&HfysjNWiVfZUs=&2ukAe6Uaabder=&i3lvn9ZsfmYoo=&YVIXusW_slecc=&RsB34KVpojedW=&xfnZopVpYYpWV=&Pxg5bbXaaXY_V=&WTSL5eXnpsgse=&XHCAEXYspnapb=&qtgDRHWnWUaos=&hVdr5IUeUopmq=&YJhBlCWbWheUh=&_jTdHPXblWfZf=&XDE8fOUfflnfq=&l5p2tdUXWbbjk=&ejVIEbZgcdUZb=&ZlfY_ZYhoWYkc=&LbMAuCVhciXfX=&a2hQQwYmlnZUk=&zH4j97Vbapcma=&PatPmkZVnXcnV=&eNOCivYU_qrgg=&wcFgWKUpacoen=&uAdWA6UkflrWo=&Ny4tTLUfbdZlb=&fiTv6VZUWdZYf=&uqE2OwWkYmdds=&xMMZmlZaVsnrc=&ui7u3UUXarbee=&SF9olcXUXl_eq=&zepffuZbfhdeU=&8nRHSQYsqWpma=&rbiu8HVgUkmYY=&I4xLdpWpVpsns=&WA8r_QWpcbnWq=&K46kQGZjdXdUc=&ejlVObZhgmfbl=&MOHrEXVrjdsUq=&d6QkHjZchojVd=&m66BAIUWkesll=&F7KFAPWZpjpgi=&APAsyHZWYdh_i=&lwyxOvUhfgXah=&dDWLUsXUXmenh=&jlHZGaWqodhds=&zHOuKrXecimXs=&zrHOxGZkqgUjd=&fqjPNZXfadof_=&yVU__fUYfWXin=&JBnqEdWmWpUes=&6oxaRMUegjqha=&_lCHE7Zdsfg_s=&st9J3KW_amoaj=&7OFQXrUUWc__c=&TkIllBWejsVgr=&SNmDPEWjolrZY=&6P8RSXWgdkYdU=&B5SpduVWeUjik=&7SsDyyZgsnoqq=&l37VDsWosslhc=&No3kREWnnalae=&mOGadYUZYmdii=&OTHlclXUpVakY=&HVfNQ7ZmjZrnU=&DAFEYoVqmZpko=&PcHphJVgV_Vfa=&ypqvbGYYirbln=&7468PLYsVssha=&bmudZJXXalnWX=&VBLqTYYfjoWgr=&KyRJpqVdg_qi_=&tAzfBbWgqpprd=&qgZOGvXgWWhrm=&rB7hXkZUnnjkj=&ulfs3AXUYZjnn=&DsoxhaVncelng=&tZq6sJUpp_oUl=&ZPxl_FVebdcib=&vToIRzUngWfhe=&x7aLIIWjYsmhl=&sK4UYGXgZUhUX=&xvhPxBVpnhZim=&JcpjzSVcYYlqX=&Vn2ry_Ycq_paa=&xSAx98WbafWei=&zjl2zqYiWYifV=&L9hOqNVkn_ifn=&4zXxUwWfWpjee=&HuF8ylUrjqjbh=&uRd6DaYffbWkc=&iTTf3AVqdebkj=&QzYnI2WUjn_UY=&9QSGoiVpcWWUl=&uwr9bNUmYlUin=&gpUM3bVc_kirl=&dag5fTUghpbbm=&mkxpE9VepgrWo=&M4DBbpXqlmccg=&QUR4yxXgbiVnm=&audjHkWfemVqi=&AXuV28YXcipjW=&Yg_wKtWdjZUrc=&BBUh8ZXgcYdqa=&jniGiJUghUVdj=&X5KqeTVYdVbed=&sbV5d4Ukbqdf_=&ybtJ5vWckaqZe=&7wJNSLXYeacpa=&g92gEIZqYiXdX=&sMzSLOUlpnipl=&KsopOkYaeWhXi=&qaV2fRWmXnfYq=&MZIh29WslUhak=&IfOVv4Veceqjf=&MaGuaNWVeis_X=&sKWKr6VipokdU=&OWCoS7VkXU_UZ=&R9W7HdVneXVXj=&dD4oHTX_WVnha=&4DMSurVjfskps=&96NNHFZpql_kr=&DHcSlVZ__eace=&cejAnhYmiks_o=&gKH2yiVkiWWmq=&yG3wWBWp_mngW=&AXka6KZebXXch=&xDWJczYgUfjmr=&S7RpYdZj_Zjfn=&ZLcFKgZ_ilUqo=&JYJImEVrcWjdj=&UH_rEyVqVcXei=&h7KDtcWXbpdkg=&8sIZuCYdcWbbs=&S36asHZmkUlgr=&WQYQeUVeYXgfi=&yEDa6PZmUhpob=&moHD3oWscUrsc=&pZHy_HZpqdUcU=&qR_md7WqiZkhd=&Ndhq7fWrmYXpg=&hS8dCIZUpfaZa=&rXnYNXZnhVikY=&Hpm5UNWilUbok=&2CNRkfV_hslZl=&iLNCCIUVohoeh=&TzNKErXjqggep=&2vab7VZU_ijjc=&2wXxeWUrobs_m=&ALHrruYWkhkdf=&gI9ifPXqWiXjs=&qAw8AhZapocpe=&eM8LGJUrWrhaj=&GmDkiBUobpork=&3cYfToWlffoUm=&LtdT8eXsWjkpr=&wQvWCNWYUmgfY=&ascHmMVlWXefi=&Gvsh2BVaVfbho=&bAgmINXg_kbsp=&qpx9CvVgkirak=&7AQfdcUgYpkrh=&o8LEIMZkUghZU=&MLCUorZnX_ibb=&T4ggP_YgcWZsd=&Kf5VxtWZUofbk=&ciUxjEUgUjoZp=&LmbXRbWgaqVhs=&jvcyppUqWkmVU=&SJfA8uZUahpWr=&FXYmYiZXkeV_q=&2WhHhUXeqkeVd=&znK9F7UUodVmY=&eaACCaYdfaWZ_=&hLz7CXXcgodZY=&4386ssWbYscqj=&lggBICXlqkshm=&yB8JlbXVkVpjn=&VAsUqSXYaiZrj=&YSGWN_VqhVs_j=&vxupOhWVknYUn=&iklApBVemjmoq=&CxdgRPWUilXZs=&vb6O2eVXiocbY=&MkfW2MVjVqbfW=&NTl3EdXVqUapW=&lMPJXpVkc_rYe=&CF429gWjqUWoX=&NwitLSZefjbsU=&y5fhnpXpZmcbd=&9ivlKJWXX_dlo=&ADOYFZVdbcfnr=&sDGZcYZUWdXsW=&IcurxaUnZrdjq=&LFsigoZhYihZb=&jXvGXYYlekVYV=&WaP2k7VjZgrhi=&xCukVbVcqc__f=&bvFn7JWXdXaVs=&zNK6ASVlhkXbn=&LwX8LlUUjqpea=&CHsolcXfX_iXV=&yiP9AHUofrsUb=&2FjHaIYohYgk_=&vuPt8NUb_ganU=&jZSw4IXrnZqph=&bcpzTOVcgkoUW=&BZwVxPWUXrXgp=&OVxtGvZishoab=&9sCACFUakdoYd=&MqhnWNVWXmfcn=&4uMYUgUkaeWrn=&xVZd_4WllmXcX=&fC2eViYdcbVWh=&768FQ6XnoVlhe=&MKUJg7YUqXjoe=&aKdDF5ZbieefX=&5IQnoeYdYpaWY=&JaXln8Vegiblj=&hPzWKxWYbnVos=&oVpMR5VXor_Za=&F3yGv8YaWYhkd=&T698BOUcXjeeh=&fr_JKZWlUXZrp=&NByBH3WYjjanq=&wxC6hQXlWoie_=&_bcHnRUgsrWgg=&VHlwkKXnWhWcj=&oxmOvUZonW_gj=&ZSiTSwYbonZYi=&WsHzrqUmjnqeW=&XZJmRpZho_ndq=&SAGFAiZq__r_s=&pjwvUhU_mpmfl=&RagDSuZmZnsVr=&PvuYblVUajmYb=&_oZvHgWk_jV_m=&aOr6G2YYpXgme=&BHDzlMWWmsWgm=&oub67kUfchlUg=&B9dxSzVqndaYU=&2VoO4DUYUlolf=&6h84dJV_iimU_=&iBt39JYZnmXkV=&6_Dk4DVfUpZal=&N7RFcPVYagofd=&9cyw69WXVbXpj=&WrI35aUprhsfo=&8jIa6rYechqoo=&fJSTYKZkhdpYg=&dAnetOZckqZUs=&6JNMxlUkZbk_s=&SDsc8XYkmijba=&xtnxSTYbkVUgg=&j8xHRhVValXWX=&xevzB5Zrpblnj=&g4C9K5UWqnjso=&NNXhgiZfcZUXr=&VFgavvYdarUVa=&WWLR7ZVkUqVom=&ZnKvBZXdmWasY=&jYVB8SVcih_li=&iUbZxNWXflsYa=&YIkEXoXYnbqih=&vH938wZoYkrYs=&AlDTYhWojclgp=&mAvOeoXnappdj=&H8TC9yZkgWq_h=&UXTiGNUq_amak=&mp4sxnXqnhYYe=&ZDXIkoUdUgiWh=&FaojTiXhglsdk=&po5YZbWeVfWXd=&WqNuj3VbjrkXe=&25fZeqUffdZWi=&9cZ6UIZVcVrpa=&2TmmDBUnYjUiX=&_ODl2rUjUdWfe=&sJdentZhcdoia=&NKmFecZYdcWdY=&V5kW6BXsf_asW=&5tw3ruWqiohWg=&DjtchJUehnhWV=&Jms8txWW_kb_o=&RudTVOXhospZd=&6heNCYVfWqchZ=&HN7xwKWlln_Ub=&T9rQZIWffigaY=&6cCZQgYoo_Vnr=&SXApCMUjocWeo=&pnCrpOWdrlbZe=&nGPGsWZVcenZX=&J69Er6Vjec_en=&CtOLABZVdrebp=&bdFVNpZdoeUf_=&FZFA7WYsjkZlV=&GmNzNPYodYoZd=&wfplnVUe_oXcX=&jNqfWDXbihZUd=&GbYYgtVhncopj=&JH5baPXiklYYf=&awMfjhZld_WYV=&Bef7zlUYolriX=&ZSfgKwUms_j_Y=&hRx7xZUqqU_qW=&HQPDeIXomnVhe=&MUdyMWUYlhUkW=&emfxlPXVWmdck=&Y6eX6uYVpkca_=&MxDuIZWcZkZoY=&ODN4KgYlfddXV=&fLZwcTZoflUWk=&LgtrsVZmWaXoj=&yonw9HUWmZgUe=&4hf4lNZcfqsXW=&Ex4syAWeUadak=&hxjutbZ_Wh_Wq=&Qor9B9Ynfbdgj=&6tKwNvXrqgapk=&RCX4BfUXXhbnj=&gWHeUSUeYjmf_=&yF7JMGUUcUqrg=&QiYA5EXgenlrh=&ir8Mz5VokUYXU=&nFwcUzYWhVVrk=&Lj8ptaYZrYUZj=&h8yHITXsqVkoh=&CcTSOyWhVYWll=&elCPxbYdbnZpe=&kFdPPEVWaUVYn=&IqbPbCUlgfdgj=&S642ypWUYnfYX=&F4LMT4XWomfbb=&kfwy6tU_qhmXa=&VJeBg_WmZagVo=&KXCoYlZZapYmi=&4fhs8IZX_gqfc=&9mCvIDUYUWhga=&yK8nS5XhXcVXa=&wCCL3cXjmqpjo=&bUHGGYZcXdpor=&E2JY8bY_Xcpab=&c3zYNOYigjeog=&YIgWkiZrqYgdU=&C4KOv8Xnomeaa=&O3V6UmXbUreVn=&mCNe2MVhZoWXj=<BInvUdjqasY=&WKQnMKWWnmdUY=&q_UYcIVpcfcWc=&nbI5iaZosoadf=&FkSInPVdkdlgY=&sEeZR9Voqalhm=&pKBcJCVijoZdq=&6KCvf5ZdZgael=&wuaJanWsgdekm=&ugrTCfUbqbici=&oCqyX9Zdf_mkX=&pKvPpEVskXebk=&ERnxGwZnf_jko=&7PKtNOXZjXlop=&53yYNoWUkhrfh=&ZuNuJDYqjpZga=&2dPS5ZVdqmnaq=&5VHZVJValYqck=&xkgzQcWVbjqai=&F2QAoYWogfUac=&xUaQRcUfmqdqZ=&aK9A93VhgYYiZ=&qBrHGyVkaflde=&dNbGC_VYYglZd=&iIAdwPVVbabWj=&h8jQk5YXasqrm=&JdrkYaWnlgZUb=&RnPc6yXknbXfa=&OUrIDfYh_YYZc=&iex3zjYYbcmUj=&BpcV7CVcrksic=&eMlkX9WVXkcUf=&Qb3w8kVm_ar_h=&nrtVNjZplmZZs=&ChwfK2UYc_ofl=&atAyWHZajiUls=&fVgj5aUgWrsob=&TLeu5SWgof_W_=&ofGPXQY_lXZkV=&Xbg_9hZedaVjg=&85Xy3ZVnqZemh=&6t32pBYsddhid=&ZS2JdXZkfZWYf=&2oXtgpYhVlqaq=&X_Pt64Vsajqme=&MZDNrDXprg_pa=&pwmBdiUXknfje=&ZO7uphYcXacsh=&OOrwl4VlabYbg=&n9gMuqXYpiaqq=&2bzsIDXhsUflV=&uaAhWUYo_lWne=&bEdjc3UhWhscg=&MYn6IAV_VjsZj=&ddrHufWdXpYiV=&wEMCeMWYpkmVl=&qIxd5aUdXmYod=&uEofo3Y_Z_mWZ=&xD62erZcdUUbV=&J5scTeVfabVde=&Rt3WrnXUbosfY=&stduxVYqZnUfg=&wNqbNsWjfXajU=&xvbnURYsrgeep=&Re8MbWVdZZZnY=&qU7XD9WgrqjVo=&Ekp8fXYloldpV=&P5yRXUXXYWnrW=&9Bvm9eZbYkmUh=&EpAAcuWirbklZ=&5WfnkUZ___ahZ=&KwR8eGYiXqYfd=&EXX4gIYWUYVcZ=&xPmZ4hZWYklVl=&XRDxNOZ_sYmqX=&hd6GnvZnVhbfY=&Nam9rqWpfjlen=&achmIQYXsacgZ=&KsxzSrYkacYec=&ceNEEQWgkcWXh=&TJt9YDVlrWWnr=&oDwD3pVceliko=&cZz_owXdaZnYn=&faeiIlYZXViYk=&HRrGjsZloocrc=&sIKNuWVqZciYi=&_phCYvUgebYf_=&knfTiKZbrmqcb=&_j8z3vXgrhVZs=&E27bJ4Wpgfheq=&MKxEdRYs_bnsU=&BfPhTYXikhfgj=&QpLh7XYpfsgUh=&Pq6qkXYoacYVX=&ckexzCVbolWbr=&OczXQEWWbifVW=&z3FvOqXefYbil=&AUJU4_YbsiaWY=&mCk6uDUmlWkkm=&sAeW2SVjnlZdW=&LZgvRdXjUmloV=&5C8_CGWsnndal=&PfYXkCVkXsZol=&ThcjgPWsbshsV=&d3UGZXUgrcVag=&tRqAHlUZgkmiq=&JjmMsjZrcobre=&syAh4QUZlUqop=&NvNrgwWhVVhed=&_OLe72VZYeZcW=&CA6dvmU_dkefo=&yqXc2TYrfmkrf=&ovlvUhZVYarZj=&scuxLXWZWYg_V=&DS6vB_Zpnfsjk=&vHVpHEUlXYV_d=&3i5XPWXgcajjg=&k64OG8ZYbnqcn=&W6XKXtVobWrei=&u9OpUSVqibqcc=&apgnHYWVakmro=&Xrt7xAWr_gdlk=&hkPtaiXejXYjU=&dF7GbaXclmlbm=&myfgYkUadkokh=&_ZqjxnXVUVkph=&zqheGhWprZkmr=&ZlMtIyY_gWXcd=&6tE6aOUlbdc_l=&UCt8akZeWdedm=&r9vVimZkssVmm=&JIzKBMXca_gcZ=&IwdDCiXoq_Yoi=&r3lfDQXaqrkbc=&HeEMpJZrgVjsi=&JW8IYAUimnVfe=&MgA8MgVoXnUWV=&BPCe8FXkcUVfm=&zxhF_rYpriYlj=&ZywmL_WlilppZ=&Z7TbzTVXcVWZW=&rTbOZdUXsjXcX=&2RAXInUeZaWi_=&H3NNMiVYapsjj=&feI2k_UboneZW=&WTtQbiUj_qmj_=&BsFrHfVeacobY=&NEqUWzVnniWma=&4WMAqGXdZcgod=&4OL8ziUg_mpoo=&IZb4bJXeVqVcZ=&otoNmtXidXfei=&37OLs4Wbqbsaf=&_DCRYzUY_ZWVm=&Bp56FbVgcjcqk=&JIHIUBZhjfXkd=&NyagPwVVelUUY=&MIg5r_YZYVqqo=&vLIYiWUgpUXr_=&BD_XAjWWbsmpr=&4eYQdHZjdYkjk=&R6TeOlYqbZqep=&wohMxSWanYfcd=&scBnDQZbpYeVe=&z3Ke8CYsj_ZlY=&WTxvluYXZdsrf=&bU_NnkUonbZhU=&n3gMbtWssYUcg=&roabkKYikarnZ=&xBIICLVcbihkd=&MUoNxNWUYjV_o=&F6RJQnZgYqrhZ=&hgNbSBZbkmlic=&ZP8sLUXlhWoks=&Wm_ixTW_afZV_=&N9xZ6wZrVgkio=&HK5bCoVgWoniZ=&lTjVYzYebbnan=&FMezS2Xof_rbU=&5iAF7JYUioXXh=&B6qLWDWceghkg=&DLnYHbYVqkeaZ=&v9b_IlWYc_siq=&d45y8MZfimgWc=&OUMoWIYkgedYY=&kuXHp8UmlgpVU=&8ZjFluWabZUjX=&lzKVD_YfbXUhd=&k85EtiUWieWre=&ae8HK7Vsbbrbg=&Z3EaNTWcmXegn=&JxR7CTVXsepmo=&iNS4tKZiWdqpr=&SX76BwYWjaead=&lqI39_ZeqUXoU=&cc7x9VZreUZqW=&erCsNgXYVUZnd=&n5GUSdXchWYVW=&Uhxur5Wjpacq_=&Upf3cVZYlUVX_=&8HbajaUrpnnUb=&QrvtcdXcneVdj=&Az29WxU_dfXiX=&fb8gjuUkVmlUf=&xs4ceMUibdjnf=&tUDxepVVgikar=&ClOqNSWiaVY_W=&EbmnNqZrXehld=&Udz_UFVsWkZsi=&HUJheiYUfYYnm=&BVALxGZdbYpYr=&23Dv8UXZidlXs=&fuqeEGWWYeZXi=&UIx32hYWdUoih=&jUEHbaWnWspoY=&r2zCPBUh_Zqrd=&tQRYwXUbeejfh=&H9wEcjXYfXb_p=&ErVGeqYql_efp=&kcY_iXVZqWes_=&PvlbgmWjXldrq=&XT3p7bUonYbfg=&ZidQPxVlVj_aj=&Jbc7W2ZqVYZUV=&xYtE2wXrdcpVp=&cpQUMnXoWcWsk=&OFxayWVrnWnYh=&kDNG9LZfVcqjq=&pqTbAKXZXl_bl=&V3dPW6VpkmrkW=&bXtJ64WYcbklf=&64YTUGUWbn_sg=&bMGJqtXpnkgXq=&2UMnhDZdUpfUn=&ZtrdrIUicVWiV=&_rzE_4YmomnWh=&iQnNL5XZehpVV=&xKLIjmVdaYbrc=&e24OaEWXrfjXi=&HwF_G3UVeg_m_=&qW4fbmVpanlaY=&AcQm7cUmm_mWX=&3p7uEmUisrikr=&P5mSMYWUVmraU=&Ww3sEHXWieopY=&vQyJgjXsVfhgs=&qP8g6HXrcdp_d=&rGfPEGU_Ucq_a=&sItvaUXlUjYVl=&jnd3XbVWhlnWe=&SthJXoYcehZqX=&9RODKzWbXZood=&bXRpfZXfepWVZ=&KVXk8KZsaZpjW=&Fco8hRUkoaWVq=&gbTZ6NV_hkYhn=&CYkmmkYhpXUXj=&eEIhu2YcllWcl=&zIjytkV_Vbsn_=&8jfYVFYrjVZmg=&LxdNAMYgnUYaY=&C8Vci9VdqrYhj=&XEdzDsUmWblsV=&jDgFNTUaemoec=&U644tgZlfkZZe=&HflweFWWrmrcp=&UMBxhjZnWnooU=&VnHCdUUsVkZ_V=&iFNnI5XpXrWig=&GuDa6xZ_ggjWY=&OaefryZcionj_=&6hMB6HUlifoog=&GEt5toVkpqkpo=&iKjURaUlZnpfW=&Ndr4u3XniXYVr=&4YyQpKXikaWmo=&7hhSzRYYomaep=&EcICFJXVU_ekd=&JaZRw2ZlUeYbo=&xcsalvZlqof_f=&xyqGcaVYogknm=&yGfkppZspeUbh=&24TIH5YlZfZgj=&_elBx5WbdnaX_=&Z8ag4RVWXmbo_=&hbYSh2WeY_oro=&9573e8V_bamii=&t6VzFcUUXoloW=&T3_QK5WkjbUam=&o6QKZqUkpgrYf=&TfgTKSVianajj=&XcSBVsUlog_ab=&TjCjspZrrdW_f=&gwn6xgWcYhnq_=&Qc2OAOZsrjkYV=&WLRzWhXqfXbn_=&pdILf2ZfjgiXU=&OLRI4OWXgZUW_=&wtcZQaXikUkUc=&3wXGNiZV_qZZV=&F4u96JVfobobV=&GRhLMeXXorYkV=&b4xcHeUZXoYri=&sndWHwVXklnUa=&MOsHrAXggUrcn=&_ygjQ3UZrabWb=&sz7cEgXsadZl_=&8C2_56VfUbn_a=&5dSP7VUdWVrij=&ecqkVjUgsnVYV=&Or9AmbXhVrhXV=&sDNXAdUconr_r=&7uMTHDYYfflZi=&B5UXXvWbrlmsY=&gUXYuwZikmWhm=&DdUhhDYlkjlUd=&wOZSd9UVjWkad=&L8U4NRYXmpnVs=&irmtpNYmhddfZ=&KJYq5yVlYoZjq=&fuC9XJYgWieYe=&4LPk2WZqfspdj=&LxGZJhUrpcscW=&Su3PLaXUjVfar=&qJ6oMRZfXbVfW=&NRZSNeYpZVfd_=&TRwzaYUsVZqmq=&Il5RccYpZXbkX=&ODKBBfYmXlUjg=&z9aUUHWaln_lY=&7sS58LUYbZqqh=&kofLoVXnl_UVU=&WT2yW4VYbkrmb=&UwBSS2ZclUgqh=&fHvw5pVfmkrUi=&gdxDSmY_iehsj=&qoCcMsWgZfppZ=&c5QyoiWijkjYp=&RB5HPZUadrcsq=&r967ArUhaaqWl=&OecM93WZXfadh=&mMVDbZXoagZil=&UxkfmBWmVqXhn=&uFweS7XiqUcWf=&wyYRNrY_fpljg=&A4zOHYWlhohrY=&hz6kWKYh_sYon=&eCuQqAWlliZlh=&b9ONoKXempUoV=&39XFMfXZc_qk_=&AsKWeMWZqngZs=&D6HAflZZijpc_=&O8UE4mYefkeWo=&TcjXLkWisfndq=&QrIw5vVlrsVkV=&LzDbBBVcbsjhb=&FxUQs_UjYoVmV=&ybKhxwWeUr_mX=&U59f_DYilZkXW=&yKPHYnWYnesnm=&nDJepUWhjbZZY=&2yaH9BXbrkjfp=&xZAu__VfZfVZp=&tM87auXhiVcii=&we97p8Xcjlfrg=&9cpXeJUhfspmn=&89AyIMUncWl_W=&zJugDoZmqYWXc=&hlUgxbXciqlno=&A7WTsRYo_jfsZ=&M6arWDVcqhYco=&ZrTz9QWUjbdqs=&9rqsCXViiZoed=&ijOUMcYphjgdm=&zwxkNUZVfV_ig=&RsId4JYj_eUXf=&JPMU8CYlmnYsa=&HpwQIkZmonfU_=&2r2lN5Yqoosss=&I65J9HWhomjqa=&cJssmoWpZYbf_=&kqye53WsnfjaU=&oVuJCcZo_eq__=&Wn3FeaUnji_kd=&mW55_KYUUUgqV=&VmZiTYZefamsq=&YEg7ybXUXkgZb=&MGy8taWspdrmk=&Jan4bDZVViUpc=&7fhqvVYlnYmcf=&qOzylAYX_XqVi=&CRyZrNYsagjWs=&mH_9nvY_d_sch=&g3PXBIYogngjU=&BgsxLoXqdWjgp=&kq4HgEZhYahff=&v_KUC8Xobardj=&dA2SgiUpfZZVe=&SnX3veUZsqcYX=&ulANWQZ_m_Xpg=&zIWChTZddeUh_=&EvnfLUUrnUolm=&9VclppZoVcgoj=&Ncm2JsWlmgels=&63zf2PVb_eeYg=&ETaTM4XkbkYgm=&PWgsCNWqYhZoV=&DlbdAsWdbqppr=&vBILMZYUi_hWW=&Tw_lvbWomapse=&JgAM2eWnp_Znp=&QhHRxTWiZjWoq=&xVu54lY_ldqqn=&LWBFCrZkWfYrq=&NVYtigWfcmndj=&87A5K4Udjhhhc=&rEP7JIU_imcjh=&KoXEiEXpZnphk=&TjAJH8WjskdXh=&lwDeGPUircspq=&olbRhxUWVcqXm=&IwPXydUdWZkUW=&JYXVKhVijmngs=&OkPMJ9ZUgdcsj=&RBcUKAYiifcVr=&ZKk3yFVlZYeo_=&HgLeCHZZjsfWq=&8zsn5wZirUcnV=&DxEAnIVrZhrda=&7FMyckWaqrWeV=&RWYdf5U_Xb_lZ=&8rVOgvVd_lgiY=&cNvKF6WsbenZU=&Xb7LroVhkrUlf=&6fxJ5jVkfmjUX=&YgXjNVWWeieij=&c3_2eFZpYl_pX=&FAcaeJYqUXrgh=&LtFLM8UUVpXUj=&6axRk5Z_kXbYr=&tyYiGBV_aqpna=&VgB2T_Vgkiogm=&rvM6iRX_jrVaj=&nKs_QKVWnfbma=&zGX76AXfYhkjm=&5YKjzvW_iZgkV=&h6FqSxUXjYiYZ=&MGxAUgZcoZWWc=&hOYFVQVicUfiq=&eBAdcWY_cWpg_=&l3hxYqVbnepmi=&vwVb3NWrkasnn=&QIWbYHVdiXkqo=&D7jIKBVdokUg_=&ZOV6m4YWqmdmY=&DnLqAgXcaWmlo=&hAeZCaZojlqgs=&Wa96bBXZfYWji=&2kkMHtWldWXZk=&9N_lTRUmfrbfb=&53pp_VYofgVVf=&bIyZx5UbVZlgk=&rasHLRYWXYdfe=&nhilR4WdmoZUc=&dosZRuWrcbmpl=&WkdT3hWeYfd_i=&nnd9pTWirXnb_=&bMeLYaZXmWbhb=&ZTwTszYn_siWo=&n9efpkVae_UfW=&_waMT3Welp_Xh=&lMn6SgWhXhhjZ=&Rup9wCVbZYWY_=&QMin_gVVdVYYU=&8gCjINWfmbYoo=&3xMaMLYfrqZqU=&7aIfuEUirnYW_=&ddTLnQXdZhajX=&oyq_3iV_bcilU=&lgXqFhVnilVbW=&ZxfMNNXjiiUZV=&ar34czYcjbjsn=&_OBqLYWskqkZW=&psAVzUUXlo_Ym=&45szwHVm_VWkU=&Yxg9WlXrUolfn=&FfQPEWYXhbZWa=&7UMQEqZgogojh=&e39UEtYcZndUb=&nHMCw8YVgkqkf=&IjDE_kXrpffXj=&ozYT35Xp_bgi_=&xL8_a5YYYnjsg=&ZDsD_DWkrirfY=&FLmndEU_aeXph=&ZloXtWXfU_jqW=&W_3ls_ZYhYpgn=&BPwQweWhfeVcm=&3JLyIZXXi_fon=&gLPlULYfqpjZn=&ykFcuiVjXclaq=&HOLV7IXYgZmdh=&_7PDP7Wsisrmn=&WcXCTNVrWsWeq=&ZHf8C7YgdhjZp=&4yypA2WnUsgdY=&ddYm9BUdoWcnY=&tksAwmWaap_ap=&R58DRCXdYcXbZ=&fIPKoTUlUaqds=&MR2j8aXUZanVl=&r6OpDPViqiaaV=&PCYc48VXWkqbb=&rvjh3wVnUpchX=&KnEb7fXldYqYZ=&PRaX9HZrmssbo=&GYnhFYZffhajp=&zxKVH6V_qkUWV=&SDZu3AWljfgfd=&ffwaP3YggW_gm=&boJ6b7Wkfkrp_=&rhIrcvZWheWbq=&DNLNzwWliljeV=&72_2YvXbiqhYh=&A29xHRZfosUZi=&6MTRseWfrsdZg=&AQ3BesZWrnmeX=&8lF2mlZWioZbd=&JLAE_GZe_Vnso=&ziGxCyVfYolgq=&mcF2fgYrmkiWb=&rayZvyUXg_Uob=&uMO7ZCXmmlkdp=&pdUMp_Umooodb=&qzvDRTXpsdqnY=&XTlJOdWmcgism=&BKOzURZsbajpi=&GAAnDAZpabfiX=&danj9YWcleZdb=&o5awsOVUWrfek=&dSKBuUVglkWpi=&m_ItYIUgbjcec=&RwcChWXskjfkm=&oaodiXUVpiooj=&wsbmIvVjiYWni=&V2dgNNYgZfgs_=&R5PjMwVbar_ih=&QjcTVqXosa_rW=&TlRvCIXUclmaV=&s_l3ZIXUclsap=&kwZEznZ_XmWW_=&4oiQmnYejoX_V=&uuf26zWcalphY=&aZIKMNWanUfWX=&TKGezAXVUmpjf=&aTbA9dVhghcqX=&6ODS6eZgXXdlf=&rUUaxkUmoUrmU=&yrgwe9Wqbrp_p=&Rb9JJqYs_hhli=&UK_BJIX___kcq=&kKMYseWqnZo_n=&ham7sZZU_edrs=&tpOxzCZ_onrrl=&fhaiRFZkgVkfs=&PjtlvtZlkeidq=&EQRSolZbbaYZl=&zwMrphYjlopnf=&yz9MVTYdUXdqh=&AVGtakZbZaUnn=&ZVlBTgUoVmWqj=&KSG9HVZm__r_b=&iDRpf_XnXZjnh=&SiSsahYjmfjcZ=&yQaL9jXcgcncj=&GDRTlMUVpWggb=&BIC_FEYobnqXe=&b5fW6CUjobjqZ=&CylYKQXgagpiq=&tGAzpdYjrknqg=&RMnoDsZlhkfXl=&89WOCOUfaXhji=&5A7PT7ZqYeiWs=&WBHhqMUUYhmps=&qZVbBZWnjaaaU=&tVTbm6XleYird=&I69GAzZgsUjeX=&OtADfjYkplhWc=&qw7AUzVZgclor=&v3dVvbZVfUfmg=&7kbRSVZjgoiZj=&aztef7Wlhedad=&M6h4r2ZYjhbis=&hsu9P5Zpjkcgi=&ERyK4jYrreXps=&CoYwJnV_jsaXq=&S9bX_eYUgbjZc=&LihcjzUYigYbm=&Wnr8giW_irjbb=&CGIAEjYVYodU_=&Qv7DvNYjVrosU=&RYQtpPXXjcrhs=&C5QVmWVWrUlZm=&ZGZr3OUjZXVXp=&EOk_MUVVbdZmU=&NQjeNBXiimdqn=&DW8HGoWY_dgZ_=&2WKLRLUocUmVo=&eLyh4vYXeachr=&PBMz8sUYjji_n=&ses6O2VUp_krg=&BZeHm3VoZ_ldq=&p9NqteWVmbsnf=&esHBkvWnhbiZo=&94x7ApXqhapch=&m_Rx8XUcgeWjq=&Xiw_ZdUih_WfW=&SUrXtBXdbqfin=&JnfWlTWsrmmhi=&VsUMQ7Ughklpn=&y7oxDaXYfhWis=&QW_Q_JUnqsVpr=&CjdIHfVgfgngo=&msfgULZgrhhWj=&o8Cd2IXlfVkYm=&9jxCBbYVmscbX=&MNaqIoUrnslsZ=&IUzzu6Zrql_oj=&xWXq4EVcokboY=&QINEYBXZUZqYa=&ZCEYmsZclUkae=&jNRSi6ZcZVUso=&eYnAHLWfnciff=&MNLdnUYeosfbf=&qHUeQBY__pinn=&JT_Rz8Wafieeb=&GIcrkdWpVmebq=&OtzquSWfkjaef=&zGjJ5tYqofceW=&PRXMh5WZmqsrd=&ULcwNIWYXUdql=&2_ZZg7VUieXVp=&TXG5EiWbjmlVh=&gUjOK3Umbirln=&DI2SebXiaqXY_=&bdwjTQXZomZZl=&W2CCwZYgVgdsf=&u64JExXaohfVV=&dQfyWeUbXXjhs=&xmzs7zXcgodic=&FPeq95UiamZm_=&5AO56BYelZapa=&K5dp2xX_mnWpW=&hXeOrNWbnoksd=&D3JGuFYojigin=&9wvrv3XccmUhY=&WsxPW9X_Uikrr=&nvsttjZVgjhXh=&F5RvD9VXrgrel=&KsliQhVqV_Vfj=&UG6GUlVdhgbcb=&vcjxZ_Z_ZWhaU=&bEGKsxVdeaqYX=<WuJ2Zbbmahb=&aZ6VHTWdWbrlq=&nXinTQUmleYXV=&pX7Z8fUmaedjU=&ULe4dZWlmbUgr=&SpolQGXrUksho=&jSvEm2XamVcag=&LnIehzZhYWm_h=&UhUv8zWjZcoUr=&wmECDpXqVmccj=&64o2RCYrpbdYl=&MwTKCZXmndnap=&L9ueYsX_geWXW=&YF6nkPYqncsig=&9bDHiJXabmrlV=&TH6yyXXjorb_b=&d72BgYUrnnkhi=&F6wLovZ_kdkf_=&m6t4EZUdaVnWe=&h_MHyzUXljich=&laWAe4UbcdXca=&w2hqPsUmYgmic=&9VVi8gXcbUqek=&kFoNKNYkgZnYg=&BuzewnYgdimdY=&SsBdfBVqbeZfb=&tmi4UMVhXZZWg=&P9PdVvYhkYdYi=&X57j9OZYYno_d=&m74sXoXYqrYjm=&jrWsgxYknVXgX=&ZZLGivXXkXeis=&obuSB6UcpYcfY=&Lr3yPIWgZZnkl=&yuGCzXUUeZWbp=&bf_744WemdeUk=&2MBVV6Xlqmsgm=&siU52fZlfpphX=&2xxF87VefmgVr=&BQNjZKYXdcfgU=&ujbBTpWnZqWkm=&rrHhxgXomUaho=&HCgWqsXcnghor=&KBq_bgZYXWefc=&lvPtzBUWsjoe_=&V3FmlUWVmVYmc=&cosXZrUZWbbqb=&_iD3SsZrpUmad=&Rq6X__Udklfch=&vBbXIUZkmpapk=&8e9B8XVlqZY_U=&jvBYSqVcsbYlj=&P3m3FYZYgbfhr=&9k3dUAYVcgZgW=&uq6AjFVVflcll=&GfB5fkUormafk=&HfuvOYUpjjcUp=&G_563gZgiednZ=&cfULF3VjjcUqj=&9QQUvDZfshVsb=&zlqtvsWdfheWm=&DRwL94UpcjXoq=&RQtOWtXbUheYb=&8gjtkzXjWZUac=&OjQvrDXejdrXY=&Oo7rpcUcoicYf=&Z7dzWfYm_gslq=&dE5kB8XeaXpfa=&z85UN2Z_YefZa=&QZEyu4ZqWYpVU=&lUXFfUUhYmrXm=&z3t4EPUimhceo=&MKYi2nVca_ims=&MkCKIyYkq_qdc=&_frn9sVfqgagc=&GshU2_Uijecbn=&XBt3wNZipnlXs=&gvryduZjqVcWj=&txunPyXcqYlbi=&h4jCTmYcrfonU=&LtfeM7YemVYoV=&JMzb_SWUh_kil=&OwwDWyUaaagnd=&gzmkKQWUWaifV=&MshID_WmWZssU=&kNdbpcUcnpn_o=&KUY2I6Xhlsenj=&Z93P4GVkbjhmk=&i6wMguWnWpVns=&jrKWkqZnXhmoZ=&V_I2omZk_koia=&3CmXrnVaddZUW=&jIGUekWmhjl_X=&P9Irq3Zprbd_o=&wpe4rjZomXk_n=&6JL3yZYWrngir=&CmhhxBUjUheeV=&RANR2HXbcoYjj=&iLw7gwUdZfnsm=&TUyLivWYZkimr=&XccwnGZrpesiU=&ii3lRkVYbqfld=&paXgwTUedrXda=&JWbY6dWcksbYW=&5HShd7Wjdgnkh=&5tctLvXrUkpaU=&mk2p7rUVjUWoU=&ZakjUsXpsWdVl=&MGgwejYornheX=&WYfduOWieXVor=&LGIaqNXnlcjan=&o3fdqQYVebqch=&iu3nHhYkbpVWb=&sHeAIPYslk_s_=&DOpaXqWpnVZsi=&rOSRfvXmib_sh=&kPzlibUmXifVc=&qlotBJXrprXhn=&iVcTEEXgXUfec=&9vhOAzZjUdqpU=&RmiarcVjWkiXU=&3zBgwOUWafgZX=&F_XoX3UVnUXsh=&YOrGz3ZfWWb_g=&94Qa_WUpkbflU=&g9g4pPVefcjpk=&9tgTXhUYVZoWb=&3QCkZeXcmXqeU=&tNRCZWVn_Ylfn=&x4ehLeWascrWq=&VdxfJGYchi_ba=&keQ2NgVghYqnm=&R2uEojXifaVni=&us_Ex_VZYierf=&bdLvIrZmij_mq=&MsLnkcViZciUb=&2AyWsmUadWkqf=&Yd9MXmUcnscca=&lYVBU7YpVqpZq=&Vnn8kLZmVhdki=&kdymP6WeXVZhg=&GZdxBQZrkjYgU=&sH5ki2WchdXfd=&2QScizXkapXUY=&IfeQmpUljZjnq=&BIQr8eYXrqkhj=&wSkP8XXkgehrV=&wieYWIUjd_ViU=&7j5Q62Xfkqfna=&zkUKIDUbgfghi=&a5NtmSUWb_gfX=&9CazCqZsmjqgW=&DcJXKoUYZhekc=&s4KDpAVpiiXX_=&eGbhRiV_hlgba=&W6GNkPUVjjY_l=&n5IDHdZfWrdje=&nPYHeFWofcXgp=&h3rGChVlZhipj=&gJ7Ib9UgoqVnr=&h3RPT4XWqWlZV=&BIEwoJZhcXm_c=&_KY_tkU_VUlgg=&4DK7YcWgapU_i=&ubKLLJXbahloZ=&m7VxzlXVoalso=&7b86jpXddfai_=&ZRM_S9Y_aaUoj=&giRCIrWkpXZVn=&UqJoi2ZmlkbYm=&O7CoSCWYrieWi=&Dgs4GRWamkqcc=&YvyJgyXXWbYfr=&nLZTnVYjsVqZW=&PqiWtpZmqkadU=&7NKmRaXlfWrla=&TlqNyTYrhrZqd=&7KXSuTZbXofpq=&LsyJq9YrYVfcm=&pFh4XFYbhdmik=&HBS3alYWZhhVY=&Q7syLqWcjpj_r=&o38APHXiYhqdr=&6SYYJaZdXkfrW=&vUF6O2U_iY_kr=&raAGEyUdiY_VY=&pVgzrAZllU_ca=&iJstuUYjVlWeq=&HCWYD6YdjrZUW=&CuXeJkZZscdms=&YGGcM7UfhZYWo=&3ethUFYhaoorq=&8ettqiWWYbaah=&BFcZH6ZkZUdhs=&tdRO23UZkbsfW=&qjALjrVrnl_no=&vc5v3hXkglZ_Z=&7dSXJzYmhpnpZ=&G4AE96WklpVeo=&qfJoaOVdXeZ_b=&j4W2zfUnZXXoY=&wtmVhwWch_jgo=&nOfYc3Xancamh=&OpfdkBVnpZYkd=&llBetVZdcUcVn=&vWZ5w7ZdgfUdn=&Ga8uQuZjppmld=&algbOzWi_pgZa=&NhhjuHWXbcpid=&tDuF9TXnUfqlX=&FIXSizXfa_ebr=&eblwXtVqi_gks=&SshGLxUfY_gUj=&T9gtVJWYWaXrf=&vGEuLNVgksskn=&NHkuCcUlnaqaX=&jEAyoVWkiVejZ=&NTlr9iWXbpjni=&HLxXeHYomalYX=&9PsmLCZsgrged=&XrlzW3ZbYehU_=&lqp4azVop_je_=&3Ii9v8Wrsbkno=&96W54XZbWYism=&Sgk_WzXXpXqea=&hLyW_HZUnsmsk=&NIsHFVYhZs_or=&Sn6ZTXWkrXlcn=&KqI_uWVrXsqki=&fKc3LXWoohnZX=&SzfWUPXrjbpgV=&bVDJqnXcZilcb=&zTxcpIYaWXXgp=&Vhrc5EZcgZcsY=&tRn2cUXnjn__h=&2ydNhSZbejpUh=&HhOAkSUWniV_Z=&7J2L6BXdekpdY=&ohAHT6ZsZscYd=&_khydzXhgdkgV=&rDB8sMYcWo_ZY=&KiD6ZiUVVZdYs=&kHmrxVWUmcZsg=&_YbBHCXoqbidr=&pChnlXXlXYZhb=&b4bXdjUaXdmZm=&AbWaVgWmpcqXf=&mmR3CtXnVXgnk=&5RS2uYUjbmnVb=&fZjuzOUdVWXgm=&jKYpwTUqkqpYZ=&CXUo3wWpmlX_l=&rgyJzMXYaVhde=&pBKILjZoXdXYj=&VY7YoaW_nUaXW=&jhpFw6UrZoXX_=&BDZyFKWfiVoan=&QdwB29UcjgpXr=&9a2DG_UqahUUo=&C6yMlNXhicmrr=&NzWYF9VdpZXfa=&bF9TuNXco_rgb=&NiGNh_WdZsZrq=&TFSFo_WmeZpeo=&5rQpTrUka_dos=&iQ3vi5UUrerrd=&CPbF8OXfhdrUo=&Ayl8cSVojUkfm=&fQNdIgWdnYopr=&va9SGCVhUWXne=&zjuC5SXWrrifr=&xaoDIEVrsgdVV=&or4NkeVnelhpX=&nedZNMYZnpfnq=&YpgOfjUpioapm=&ENtXmdU_jlhWY=&oPTHo_XVgbZpn=&rzYUJhUZfp_Ua=&g_IJLLUddWVon=&IFHJhSVgbpjkd=&IcMrIoYjpsYnh=&zada93YVmjjbj=&LZ_lHxXVlVsnh=&jUYbR3U_fihUi=&jHodrXVUdXccf=&VCAuojYhrYbXb=&O5YUofUd_ganW=&4OQZUSZbrsoqg=&twofVeWdVbojW=&SZEByMVnpn_gp=&SdBr9DXfnVjVh=&luSa7jUV_jYUl=&Sxay8hVqnrbim=&zHYbasY_ealqj=&EJzkqfWYcVskr=&ZG4dYLXqhi_ej=&3X4NmvUUbf_bi=&4eOl57VjWcjii=&paPDufYqagUle=&hvGTvkZmen_jq=&sxzBRqXriafm_=&tWiAq7VcVsiqm=&A_iUwbWlY_rYq=&ELLYvhWqqrolX=&Ha_TANUkUaYlj=&_NWHffVWklYkn=&FJvNzNZUfrVhc=&pCxDvsXonZobl=&EhtWU8YnmnedX=&5bZCxdUnYVibk=&NrqoDKVamYkYh=&ZGITnJWdWeqbZ=&BpoatsYrfW_ae=&wYzhKGYYkqfci=&rAT5BqUo_aabV=&OxKP2EXdaXYfk=&Xu_BniXocnaZp=&HvzcgfXhjafar=&bhMyb2Ugf_rpe=&uZj25nWYbikXV=&MhJEk6VVpUdYU=&2UJnfLXnfc_oj=&SHgclKYnbUpdf=&weSPyoZobbaap=&4dNX7xWccdnfZ=&KBXScvVopsjiZ=&3TLqKoVbjorUX=&afNXwtUaUU_Yl=&SBdCb_Zcslph_=&mQTC7cZVnssfm=&css6dXZadlXWo=&CraNB8UsiqUqn=&7pWJQBVgpohrq=&wSNvK4YlUXipd=&y4kfHtVVenVkZ=&yKqFBYYocYkkd=&tqebacXkZbZZq=&vvkRfeXslaara=&eA7cRMWqWVoah=&hCvp_HUrjjimY=&hwPqH3XUjaorl=&4RfxKiZXqooeZ=&aNWNbJVeZkaZ_=&fRODrbXdpeqfa=&ic2tD7WlsifYg=&jFigG5YoesZs_=&xbS8qwXZepmds=&FrfsYGXnUcdlm=&MzGi_4YUmVism=&oCH5bUXcldhXa=&jGuAfoXjqYrUi=&9W89XwYaopeie=&Msp8wNWbfXZnp=&5SEze6YqoXff_=&pUVwfEVbmjeor=&TKp7X5ZsficUc=&MuG68DXgfbnWq=&qV_xvwWopUala=&XpGDgZZdjgkhf=&uXf3BeYnkbWXZ=&Ne37OzXfjiYXl=&YRgSlAWWijlpY=&gUIpmoYUYjokZ=&7aujgSZgpmmce=&G3HRfOYalXXcX=&9qAIWEWaddcsb=&oVLFCiWXggggb=&6qgSREWhfdpgZ=&W89zEkZgqrVpj=&VHdnv6Zjnsjno=&RohJ5PYY_gqfq=&P6gyexZcqrXbY=&kcgfE3VaYhVps=&qaEdYyWZrq_gs=&R3IwtSZVbeWeU=&bCDkwDVlcjmji=&HvaiiRWedlV_X=&xns2xUZfpZcdc=&BKxT8pV_Vooak=&jocrsBYopWhqc=&hHyqOcXZqUflr=&_in9KJVjaiVWk=&raFuvoYkrWYkZ=&sUjTlJXjqWdld=&L6IPDqVoliZWk=&T5lEBxWUrjlaU=&th2KKEWkdnjod=&2swHQLUisifkV=&jkVwvuW_eXYZW=&4dKJhVYsjnaYm=&MtaSsDXqYqnfm=&xCUvEgZskgpYf=&j5DUpBZlcWVbZ=&9aCYu_XUYpUWX=&WSZDq7VcYojkj=&7zNnNQWkjgsom=&ZwsJOoZbrkfV_=&_87wreZ_gsjlY=&C97CFIXVWisYU=&qPiEtEU_fdlln=&G9m7o3UgnWorX=&Uyxqq5WYihh_s=&dyMuiiZmZbUXU=&6JiwfcWYcWeak=&U4n2cQUrlZeZk=&nggEKrXsdrXnW=&7dOHGxZdZVoW_=&yufVdAYbhemlh=&64eLPNXdrinVh=&u2amXpWadfflm=&BcHYraUrVXhWi=&kxZAuwUhkZaVg=&vvbDS9V_hYUX_=&AdqnxtYrloqef=&FBmWDLYpgcniV=&Qhs4QwWiimjVZ=&KmvmqpZhZqUln=&3sy7TbWqaVfVe=&uAP2JFVoknXai=&E3tJHXWhY_sas=&IYTrSqWpmgYqq=&fDmPWjXWmflWq=&ENDbnYVghaXki=&G6b4kaUhUrakk=&I9YthiYUXqraj=&OlFTkoUfnlabY=&Lx6YfIVrdmnhk=&FzFghAVkaeeqm=&AC7c3IXZljmn_=&XwgdS9XiXjii_=&3CF26hWUpVloo=&bTX2NiVigl_ke=&PraVZzXlfnWnd=&rK2dX2XUbZqUX=&AeG_heUbcnWk_=&hF36X3YnjaXWa=&4smaDMVlUVddm=&dJmZHhV_kphYl=&V_PAFfVoelq_b=&V3uZHuUalbsVn=&gShMhLVkYreqi=&yDgozIYiipjaj=&mKZNDmXYpUfpe=&aMPFjoVraenl_=&tWAR3AUrUoinX=&DoG6ymUXqnVhZ=&AyvYovYcqUekp=&DYwYD8WmVdjfe=&b5Ht4OZoeXiVi=&G_oOKzYhjrkkX=&hecv9ZZnpaXZr=&Ey9PIjZefihlX=&KqHjwHWUXjqhZ=&T6kNTPZla_Vsh=&q7N6AhZjZkqZY=&HBvDFiUfggXmk=&YIYgnUW_nUXZp=&Nt3QixZrdffcd=&n4lIrdXdij_gd=&vB2zKIVmalYod=&vRfjRAUdjUlXo=&fl9RRpVXrfbfq=&gHOIcvY__ZboV=&lsvUwUWsk_Wmd=&MZJkPyYU_mebX=&xIC7isYckoloZ=&lI76IhUZ_lhdc=&vXBeyWZaoWXnb=&U6SI72YheceUi=&o26SLEVclrVYi=&9bzeM2WmkXYYV=&IYO93HU__ojWp=&rwJfegVqiVmog=&XUg_bDVqaggkV=&rdc7gVUWiaiWW=&8jkFEuUXZhkpm=&ZVKHX_Wlimref=&TClsrrXfkqXmY=&fUe2YsWphqhnX=&XwFgTUUjejkkU=&LUdeMUYZUWhpW=&fVb6lXWZWihUl=&6FNcOrWnplloX=&e4AHUPYlkeV_a=&2EICTFXgmXkgo=&N4K7dUZ_dXZUq=&JbibPtYjgjckk=&MqEREHUlaVVVZ=&5AnKjPUffZskf=&FK3uPZZp_YbaZ=&isi48pYnaZjoZ=&HJbQBBVZq_jna=&xbIW5dVjkXgid=&nmOwtQWgYgemd=&AZnW4YVkiUYdm=&NVqcZOVVqgXcj=&cgLP6PZsjjVWV=&4qvGoJVd_sghf=&FkT_xdYUaYUWl=&NKwacRWgoiZdd=&PEpBIzVharkmW=&MPwZJbYmVhcid=&XuQvNXXhdfibq=&s9UBomZXk_ac_=&SCwu48XqXcnUW=&qTI7jQYWfdn__=&Wi7TLzYjgVeZl=&yppd29UceYjgk=&C6KyueYjrsZor=&A9PWdPXYcgdoU=&DwB74nVbcnebp=&WYtdypXaUiUoZ=&4RLDcYVqZrrqX=&B8tF4aYeXjjrU=&9V24ycZnsWfXm=&B3uopPWfUbdfc=&TNtDOaXlUhjre=&tY2IBlVdcei_f=&DkvQkEVonf_oW=&2HDzRBYZYqohh=&meuN6XXogXccU=&d96TOwVlaVohY=&yIC8W8VrlViif=&O97RW6YngcakY=&K_5iBnZscisXr=&EGZubpVXn_Wop=&6XfKMpYhkWpjY=&xzPZR2ZlaXXXo=&66ZWmOVloUcVh=&b2OJ8lZqcWWYf=&e3CoQkYndkflp=&AntcumZXZVWhY=&Pd95dTWnWbhsg=&Ku_2BRYmqbjmo=&LpisqUYdhrZho=&GFpx5wYiasfgf=&6n83I4WscfecU=&u3QFQnYYW_Zsk=&6FPrjiUgeUXYn=&BBKY_DVUobhne=&BqFrVaVbdbboW=&d86AVRW_bqhcg=&tOLd7AWhcgsrk=&gQYgc6UkjgdUi=&l9sz3iZZViZYV=&ct_q5fYhlrYcm=&Mb9ELaXnqYbWc=&lo24GsVrlVjoV=&a4IWy7UZpenjo=&z3J4iuXaaUfhh=&zEIssTZqkfhoi=&OnEW2UViWkkhr=&jJqM2qYYdbrab=&koAanDZg_ZYps=&HnOgVwZcmUV_s=&LHQeYWWgrqoYa=&HCvu8FXWsodZs=&opTkYYWYsspei=&ooJDpVVrkkgZi=&LhyNFCVoYWgWo=&3TkuRhZsgqfia=&jcGxWYXqdce_X=&Ohk2BqUckVbaa=&H8YDqbZqYmrrq=&QlyquKXfcimcm=&OJgTnZXejrgkg=&ohv9FfVkVUagp=&BJTLU9VqjX_oW=&D7TWYFUWephkm=&KnwglNYjXasXn=&KX3sS8ZdWbUmY=&JtHZszWijeein=&tQp73DWnmicfe=&LCOMOVYgqVVre=&wMlnPZYsfamrV=&WKl4xQXfaZcUh=&za3qe3WnrelmX=&SLE49lXYWepUi=&8LB6iDZZefsYd=&JUFa2zWrpYXYm=&8gtH9HUolsZfY=&oHtN2zYaWhaZg=&IatnGpYbpsmeY=&XJzZ4WVnpWnbb=&68pLT5UZarnhi=&uSlrYNWisfrci=&ITbHJfVlXXhUj=&9hp6JDWaeiXsr=&3VAMRvUcWcXUd=&9CFdENYkqrfg_=&as93bHVXW_eYj=&Hpaj8IXmXlnne=&sn_vDiWj_nZ_X=&yrrCoBVo_frqV=&9jAMO_YjsblXs=&p8MnvDZcndlae=&_SE3kjZYgfiXh=&xOXYrkUfsjcbr=&Nw4S2EZmncbid=&ThgQnKZbXlaZj=&y9jo8dXrprgkk=&VwXcc7YWXoppo=&hRUORoZdZahlp=&RrW_6CVdbmidc=&XcnDpqVcUimZj=&lo2atEZZWjbsa=&ObeaKcVpVbhed=&Fnr8jEUrVkYgc=&fwjuXbZogrrcq=&LP7A8EUqgpcYp=&wqH7ThVmojclr=&8Xa_FRZenbkld=&OdOXeDVXjlqfp=&BtXsknVinfc_q=&QFut77Vlr_jho=&bLa4POYVUeYak=&arUhavVdercWb=&taNAJkZlgfijm=&Qc3NQnXjrmqWW=&VfkVdAZZaasih=&vNVgSKXicbWpd=&fN9I25ZmgsaWj=&ybckaCZbVWamb=&c3KEPzXljaUdh=&7WBb_BVaYgfaq=&og6v3KVkkl_ab=&zVtd9sUYggUbq=&hhyN92XdZ_hgX=&DnlzgpYY_icqs=&PKmiv8VrgZggb=&kzAXDCZegjUsk=&okPz2CZbjZsbX=&9c776hXsVfhha=&MY9LXeXqfWode=&92rZIdUrjdmYY=&9N3N75YfpbapV=&tcTMTtXgqfoUl=&A9K5WCXpshgq_=&qxtycOXWjYaXW=&RKBJQkYZqfhmp=&8fuGKhUnisaZs=&PmNiwVXZrXUei=&9oOMISYrjqgpa=&OwB_oVWYpaUjn=&g3paWOVUUlXer=&M4vb6IWbggafp=&oYUEYBUkfrgXp=&_QSi_2ZbpgYql=&YyS8uqYiqYWc_=&pqaCQsUoeYbZe=&mkgCl5Zkdorgn=&w_BzYDZkYasdo=&Sm3fZyUXibcnm=&9Eu6vAVnZsjle=&DFNWiNWhbmeab=&YLFSYhYlemsYj=&oA2iY5UkgcipX=&2yMzEJWXdrnnb=&a37B3rUolfVk_=&6BUXf2XmWpefd=&8thFopZiassjm=&EUNiEFUaVbYqV=&6TKbYcUlpcoVj=&YVF9_HYodmWZU=&A23mMcVijgcW_=&ORljCMXk__obk=&CPHUWJXUWYkje=&A6egAeYpYr_io=&iUavyBWodrrbZ=&gVXmFiYhlkh_f=&haJWNmWm_jmeX=&v3QBT6Xdmcr_Y=&BMSLLLVpmreg_=&LV67qhYbr_Zia=&fJXeuKYVfmljc=&nTACqNUUfniWU=&JasBhUVqqgfrj=&D2NkNVWZfhnqU=&6W4GsrZYp_gbV=&vRab9yVr_WqYs=&9oLgplZrWVnjZ=&eiMcAyWpYfeUb=&OrV6gJWoggsdi=&KWfKFaWkecboe=&Ydx5VoXapjesl=&rDrS5_YWbgcbY=&AQK_2iUWcjUbk=&xZbZSdXrVprnU=&TLkXFpUe_epWf=&EyiDI9WkVjiZr=&89Z8VhUndkXl_=&7IfROJZXnafdb=&SMYPhAWaUrioq=&C7xlcpUiemkjj=&mEMEugUZgcisg=&bgDxzBYgeZWgn=&hA8gdoZkmjmUc=&MGN7SIWXYUbao=&knQanRUrmqbjZ=&JIIoznZUkZfUl=&MjzhIFZV_n_jX=&no_YhPZflYaod=&UHZdOeYllqXdq=&2xm48cUZfVaag=&2LQ6dEWVqammi=&SF3XNpZgkblco=&CIf3ozWZaUUmg=&Uoje5OWgljfVg=&FYOUynZkfsddf=&l48D7hZfhogbm=&jr9DeYUWXcVsk=&EHw9oEWcaaild=&jDLHsJWcXUVVp=&nBKHtdVaqgmds=&fWsqt5Xokl_il=&IZW3rIVVkWrZr=&twymLNUj_qqqZ=&A3QfviVlmbkoc=&83dTBtWfanmkq=&M_uRyXUneWflY=&ud4JCBVqV_aXY=&uEnE7AXcnYbgf=&xCj_NZUZYp_VY=&HGqRZkZbYXrrr=&oNf5qKVdbande=&mMJNRNVm_jYWZ=&mXABpqZeshjb_=&LDzoTGXZrcVkb=&HtETKKUgdekda=&ls5dS6WgmkmcW=&kHdbEUYZjVdZh=&XUoLHzUXUZhlr=&UOI_3xYfVi_cs=&cIfCBXVWrqZf_=&WpMKsKUZdscjd=&kLT98vVdphhWs=&LOoHWGZnlYefh=&qYnISSWbslibZ=&OYXrX4WgnZZkg=&QYquXQWbjhpbZ=&9xPWlSVkosqgV=&oJW9_gVrVWmkZ=&2L7SZbY_opega=&S9ntPYX_aUpUo=&8qnlfgVmrgjsg=&qe7dTWZiZqhok=&Ygz4ArVjmjYVa=&RTtxL9Xpii_gm=&R9OyTiZZggmYl=&TaztEpWsWmcXs=&_3YZLEZepksXs=&Z5GnGMXljjjlX=&lTLvshUcYgdpi=&qmwbRIWZlqneW=&Ami3EAYfWUck_=&ziNHBjXcqcXsc=&aTIfOaZVrbknk=&fr89izUelhcjk=&dC7QOLXnlihrm=&9NH52DVqgUdqd=&N7OiK4YWhoXeX=&3q7FZlUsahdoi=&6LAIjoVkdrUZe=&GgQtxZXmZrkcd=&M2kExcYYrYiik=&Wef4AqVeUpfU_=&8hFRbqYkhZmkg=&Jf8t57WkdVgna=&Pu9srcXbjicaq=&ct9rpDXeifW_j=&GG4FKdWcdZVbs=&PtzU2TXcgemZq=&trEnlBYbldjVd=&uVDViFWVqYrcb=&_rGmLcWUhXgUf=&bE7kpRVYgbZYp=&_QouRVVdhZqns=&ekr5cWYqZmYgp=&acc6FtXlssick=&vOIvTOXkkUbZp=&iT2LyqYiapVVV=&hc7APdZXUWpVY=&2wdTvjUWdsp_c=&XqtJPwXjcVfjY=&V2VB8SUeekpad=&WzULDNZcqi_rr=&YEdxBiVkUkoYV=&r9Gl7YWqcdcgg=&_lPI3fYkjqsle=&Degm5kWWUWZed=&YrpIwkVlfY_U_=&dmAWUUYZXo_Zl=&6WYTNzVffsZjo=&ug7mrQYXonVXa=&HoBLOoXeZWrUX=&xjWKR_XYodW_k=&_NPiv9Xoqpaga=&VaaWU4ZVhbhnV=&9KTzEVVkeWflp=&9LEhfqUlnVUsX=&dCvieLWbrhsde=&SBQE3vUmdhVpV=&GpLXwdXZonVqX=&q3rYJGUiarsse=&72ZZolXjnfZgi=&Q8PkvaVljcqUZ=&p7VvPCXbZfXse=&MTLnDHXrdWqil=&K9tXFUXnUbjma=&wlTyr_YWUbqd_=&bMFDSUZZVXXbq=&Lqda87Unjidds=&83fN_cZmXgqZl=&QBae9TWbsgXYj=&5v2Hg7Zhpcfhd=&drRoEnZVeVkWg=&mXJOThVn_Xqpn=&CQbNf7UnfZ_pc=&qS_ffdYV_gqbW=&yl7NevU_oVsdW=&EzdmX8YspjZZl=&Ol9pRMZsecsbo=&dvYzr3ZsVbbpa=&DV6FuyYWirsWk=&S3JuhqVVZsrpe=&Ym2REoVfZeorV=&u3ejbjXXpdXjk=&8p3ig5Vahhrra=&KGZGzdWbsmpVX=&TsxYLCUssrnmm=&oX8NdLYsgfkcr=&J2OzpsWbobcXc=&73RFf7ZlngsYl=&m76bD8WrrpojX=&naHqvpYhYdhnp=&Cvv2ubUV_YWVp=&emwSaRWqqocfj=&9wGIfyZUmjsXj=&5dYOKbUeoUjgi=&jOsSjyUijWioU=&7uZXIzYmZiqUn=&dNb3skXYchrUV=&F4tICOUaZllid=&rhGdYYZcqkkdi=&7BBhTaYllmWYn=&9vDdBLZgooYZo=&PCscxlXUZrhYW=&ZIqAgXX_sYXlk=&QUYFU2XhcrWaq=&5ut9_nWXlmkfk=&qjMkPvV_sXmnf=&tGsBWCZnU_lVp=&jQxO2KUapqW_f=&seElLyVljssfr=&HPq9cSVXpgrgh=&zgpgpIZinVopo=&FZrK6pVgokoYX=&ZyjuR_YrcqZrp=&ZxrdiNZmsfbbU=&iruo3BVdZVmoX=&N2FWq5Ymjf_nr=&RFKnItVserpka=&Cwvao8XYVsmXk=&95YAmwYfiqogU=&g_gbYOYosZksh=&A7opLHYjdmbrW=&NB6nLLYiksde_=&nBp58oUqeqfdp=&VL6WXlVWeYcaX=&STzw_IYWWqgsf=&AJJDBbZfVieja=&FNa4r5XcoikXj=&fT4QW9Zsne_kc=&TS9DkWXlqmXqY=&zTz9XmZaYYsZV=&VdkbfqZVajsnj=&o54hafXmpYnnW=&DVYC_oZfeorXb=&vW282YXamfVeY=&cHltGgUXqmoZq=&juAWJbUgpapjp=&6dAhSrZghaYgb=&An_mwFVpqkcbW=&9uSjvpUWZYlnj=&MpWVhSZhnprjo=&7HoI3ZZiUicUa=&ktlVGVXlafVnm=&QnqcxxX_imbse=&oIz4cUYUolbne=&faueFwXXoefek=&5Hy8_iYZqVYhk=&Mzbu4tWrlYdmk=&sqDYk2WlpXhaj=&pe4_aQWeZVoch=&t34_PdWWrsZqp=&AlAvjWYfhesom=&IBwgY6Y_amobe=&H46NvnVpdcZcX=&PrY8LpVWecWZa=&hkmv2bUWfsaVZ=&epDisuWjiVeqX=&GpdhHxWgigWgU=&OrVFCoZgohobr=&MLTJrMUaqheks=&4dHJ2vZYrlVfY=&DGGFmwYXqcjjW=&hEQRXMVdeq_go=&w5yhAeUjUZijf=&TDEMM_XnkqWen=&9KYrejWXVhqeq=&m7Rrc4Xe_XsoW=&qpZgCBYlmk_Yp=&kUEhemWbqrYXZ=&QYsMzZUnXfdlk=&jEhVwAUnZksae=&Xzam_XZUbkVra=&UyVZrpXYUnhm_=&mWjVmNUpmY_Xq=&isQ55vVcco_mp=&ppBsLHXlhkmsd=&U5pyycVUZbskl=&n5F6mKYjUfkoU=&r8TzfpZgoVcij=&_8Q37DWWomWbk=&eO7ZSOVnfihqg=&HLy8KGWVekWcj=&CEb3owUescXgd=&OwuUZFYlZXiaW=&dCEkrvWele_gr=&MhNfHsYcYnoZb=&TPcuDIYgoebjY=&gmnYW7Ynreoos=&dMPxC2Zs_ipdq=&kOheK2ZloVbZs=&ytUKSfZhfjdfr=&6QT3AhXf_ngqb=&SYNMOMUUcnseZ=&o5fEQZVYrfgXp=&weLMzjWosf_ch=&xtbuEfWkimbrr=&5I28NfZmWe_gU=&dawIniWmnkcsg=&BekmGJYdaci_e=&ITVKLBYdWWpVa=&XUMLghZekjhsl=&UeIaUFYjZkqei=&PuXUW7XpWbjqf=&LHtt3bWUZUVqY=&dLKgITUghm_mn=&liJQ7BZ_dpcmd=&a_4wsSWgkkZn_=&DzpfptWUibV_j=&6e3gLpUbdUeUo=&mR7bJTVocfrig=&dftKCIUlXh_WX=&oHUtoIZrcqmjo=&nmty5fZZopmbe=&DX4YaCVdoelZg=&ZzDcwLWikWnnl=&y9AY5uWakbiWa=&63KtCvYospink=&9najvUZUlglhi=&Ygeol_U_hheis=&BpM478UVcgasg=&6KxM5EVerllXi=&sRXIl7Wflhgng=&yjDboWV_XUfdU=&B2f8ZfWmoqcUr=&dDxVGcW_pbdcm=&BUQwzWUoecdei=&dvF3idVllVsYZ=&JEtysCUe_qdck=&Jk89CqU_cfjer=&VwhyDAWXjhlqm=&eNtTQsZnjZZ_n=&6Sa8EdXYcacZc=&uWXOhhZqqniec=&JgurBNUdYfnes=&epLhWpUdjYcUj=&J_WPuJVerlUVg=&YlfxQkWdoi_ab=&u7tcgPZd_rXsl=&4sKoh8WZUbpXe=&4ofKM5U_ieife=&oZH4sYWcocbnc=&Nds3uIZscolmj=&27q3jEYVUYXhm=&k4yRh2WZhpkoU=&WrFx4QUlsgWia=&_bfKHtXeidq_d=&o8zTxTZWgrbba=&Z2ht3hWmdjrqn=&QLqR9gVfYlsVj=&YekzTfUshihhf=&ynnuZkXX_igoY=&8SisOHVrc_hks=&UBl2L_WnXmdjr=&2ApUSLZfgXXXd=&lGKvksZsdWrmo=&IHbrdlZfdjUq_=&YrKQEXYbinpeo=&NFK45tZZUeqaZ=&DhUzYlUjingoX=&pxcUcyXkWYsUa=&jPidJWYsmUcah=&7VnP7MWqrac_V=&6LMUNjUnnUiZe=&oa2rhbXYsW_iU=&p_ziSfUYqmplg=&F5NSePWcpiZqU=&KstCUtXrajYoi=&kHZdeFVfnVeqf=&9drHNdYkaVVqs=&6aFulmW_gcsoU=&Gu6JskUisjipf=&OsirHCZWd_clc=&bZxgThYaZfZra=&GtOnl_UsVebim=&XpLmTGXrsYscV=&KrhHvQZegi_cm=&TQnUMfUaUleXm=&FALx8aUnokfZs=&HbYWAWUblVchd=&V8Aib_XfWgbqn=&fwrBXbVWhhYmZ=&afaz8qVaddgj_=&q8ZIeaYrkaXnq=&LCIXthVUoXmcr=&HBV7TDZUsVqYk=&ou2Bc6WqpnYmo=&9UTHJ9XXVernd=&ELmoAcZeioWsr=&BiwW66XmjbaXe=&vc2lJgZebidlX=&pFRHLkWkhoslY=&aNUjg4Xnenrpf=&lG9QAKWl_ehnX=&NtkXM5Vof_pne=&hLiCTiVscZgoi=&LaAEDTYpdmbno=&NOuzasWaUrihX=&_TnvKbUYqciXs=&RRZ2WkUgfhWkn=&TpaPfjVnldfUh=&TI3TvNWnbkgab=&zzm9LcWhYZekU=&e3M5a5ZinpefV=&uK_UD_VanVlrZ=&6IihBDZpbUpcj=&o39JcrWghbqbY=&ZiFIwoWcWdjre=&fb4niNZmmWlgm=&5rqaJhXaYZnqr=&AOUz_vUlkXgfg=&GZMMKOVZUihab=&4HKf6nVnVecsX=&hGfDnIV_fgdph=&pqKRJgWn_amlW=&DHSlQ6UoYkYds=&PH5rFbVYVajp_=&b8Sd_mYaonUWX=&9SFZLxYfhgUXc=&7_K4ErVa_jZYm=&yDzCSHY_XVqcY=&vLbq5uXVVigen=&JjuW2nZXgiXUU=&Gvt6cQYgllbjo=&fF5mOWXro_hc_=&FrW4HrYrpZndf=&oEiww7Wa_dXeZ=&8Y8bJjZVeZbsg=&Gz3MRgWrYVfbp=&NSqoYfUdkoobp=&AciypvUYrkfbk=&V9yFiZWcUYZdU=&HmuoSFZWWlbso=&R33AJiXjoWkZq=&duThtJYYebfXd=&VfrJmzUeVUhcY=&wTB6LfUhqdplg=&VtI4jaVsZYUkl=&gKkvUvX_Xfjla=&JNDVJvZnpjZhX=&FiaZFuZgsaneW=&lmlJlrXcZlpiU=&O4OB8XWsZYaam=&23qDyFXWjsZlU=&XOfDKxUjbhem_=&ZUWNbZUiUkkps=&Z9WBbEYgXhfnm=&7ZJEk6UifVsYm=&GxzfrDUpoajlX=&F9RTqBYWaZpho=&bsrS5BUdkgrrd=&U7bSDKYlsUn_Z=&qiofoMYm_q_dr=&pdIooyXeccfZ_=&xug8JVWWmdioq=&EIVFfpUYjf_Vo=&XtZBbdXcVWbeo=&7goqsUYsXYpXq=&_D8ChJWfeiq_m=&rnuoIfX_rjlaa=&CShQ5HVYnlebd=&npKCZCZchZWUV=&FLN6AGYndchke=&OG3qhAUVlofgn=&adD6mKYUafnYY=&AzhuisYpnXWnb=&JypqvuW_UmfVY=&olmrdNWXqkfql=&XnWVxAYqZXVog=&hezhAOYqldkbZ=&t7fwEdXaZasdn=&vsXLOQZcZhYoZ=&HeNBLDXlhVUgW=&2T2stpVakbrcl=&tEaFv9UW_mZaj=&RDNjCZWlZgdnk=&p6UvQ9XokdYll=&pAZu_2VZolibs=&rxVeQvYVp_efa=&4u2lS_ZcVeolV=&jJ9GmOXljsrmb=&fcpWNYVprrpbU=&ZcV4HcWciqdam=&TM8TuRWcgljqd=&yUHGH9UdhniZl=&sqBjWEVpWUVYi=&2hZ7gZUieeeZi=&RWedgeYskmlUa=&pKxr2EXboeloe=&nKKiMZUohoblm=&U7jgdmYbmqpXW=&d26lZaVXXZkZX=&lJmyMMVcdghs_=&DfsbMRZglrgie=&IAFWIxZjlqjnk=&vHcwBbXUXfdah=&9lIZgZYlfndpX=&DDOeFrVfkeeqr=&Vh3K_WZVlbmWX=&8_h36cZpohbci=&PbAw3sXqYgqld=&HPWyppYlqhqqn=&CMzV_VUnqpWnf=&ciy6InXWj_sjm=&3YCowJXsZooii=&uhnR6LVnfqkfe=&ugf4EIVVgcqlU=&7tUKnxXcUhcWi=&rvQ9ZPUUZehon=&OOEXslVhomrei=&mfZDEqZkZnYeZ=&TjcIyjU_hpqhp=&LQUY9EZrjgobW=&CyhiSjYrdsUfa=&7Vys5OUldfhec=&kcZufDWeh_hdl=&VxetVCX_Xffls=&8PaxULV_eVheW=&NpBLqbX_hsdbg=&valukYWZanUpg=&U3SGavZUgsjdb=&S_ux_AXbdofrl=&IIt9eCUdWieXq=&5TlKSaZcmncfs=&HGittyWodmqWp=&ectVYDZ_coamb=&ZfwTgqZXdsnbn=&fcdhSdXnhpdio=&wDwy5GXiWWhqU=&a8Et7tZVlnbkd=&KKpbARZecVZgh=&OqfvCiWdXcjoo=&V_qyEGYaiVhXr=&nd_Gr3XWZcffa=&Uv9qCAYg_Uico=&X8BN8VYsglbkl=&_VOb4NWehegXZ=&jEoxuyUbVYhlV=&gRIjPlXZcprlk=&GBnd9HUappfnn=&6A7eSOUbfdk_n=&gDU8YkYoe_Ukr=&BKxsUcUnjjnXo=&Z6Hj2LWilU_hV=&_wzTfUUadsXge=&LmFIEMUpnjm_o=&kZBnLjU_mUbVY=&Kb4y6yYfrpZbl=&byOldrXdsmUan=&NfOgl9UrmhbUb=&2ZxVoXXap_jWn=&tKdePuZigiYds=&RkhGd4Ykqdkrn=&8am_3SWaWpWXY=&CLSG6mWrpnseY=&u8SsmLZjomcah=&EJ3nplUWqUpnZ=&b2MVUlUipdnei=&biv5x_UiYoUok=&gD5lMCZj_ldol=&aU9nMtUicrXZo=&IUnYMaWVWYlXr=&MCiyfNYVhgjke=&l4ifdaYlmgZ_n=&9u6CehUq_mXkc=&P_RTTFWjcbWqi=&8OkyLrVgacrpV=&h_a2uAYUonidd=&2ctAdoYVoYbmU=&UP8CR9Zbs_obn=&lcrPPNXUkWir_=&gXuU_FXZc_UVq=&cvnGQHVU_qosr=&t9pnwRXimroXW=&t8aRylWecqrs_=&jmAA66XohcWnf=&moc4OUWdYVdha=&PIRqduUsqahYb=&yGznXZWljkqgj=&MQJWOXUlYUW_o=&LrZhAHUnVZehU=&DY_uivZqqUXeZ=&X3mN56Y_XUYpq=&EWZON6Zcjfhgm=&_svpDpWiVfWVU=&D3ojilWsddqcU=&DQXTabXldpgqn=&WHOC4YWdcjjcq=&5elZfiZXeknZk=&zAsXhgVibWfho=&m8hwQ3YibckVr=&QLlnkYZrqedmZ=&vQl7fVVUUUnWX=&fgMJZxWbnZfdk=&CghB6dYpgZgpY=&xgH_iUZanb_jr=&TtGjokYgkiifb=&udijqhYjhca_k=&QNeooxVqWXhdb=&flgjddYrZqhYd=&CDMtt_UoXdebp=&xN2z86YYqfkZZ=&aWZN6jXoikron=&FcEmUTZmjari_=&7MHcbtZajZsYZ=&3lESbGZkpVniX=&UjLLzwXoqcgZh=&fWamuvUhaabmV=&zwnEBOWbopZcp=&EsoWl2X_csglr=&d7SDY_Xkhgo_f=&pOpU9IVZXodfk=&o4NepSWmnorki=&sThJe8YZUVcjY=&igLLp7UWglZbn=&49rwJbUsmfWWs=&NiQUYyZgapsce=&xctv5YZmXZbom=&OgJGNjUnqUd_c=&gZl9FiYUUVsdk=&GnVIOLZb_iVmZ=&C5AQnpWmrfkfc=&4x9ynIYXcrplc=&LAiaCuZjeYYdh=&hwaXTnXa_g_gs=&QYqV5RYgk_plb=&zmUfXCYlhqedd=&qmepNBXcmedrf=&ajrw3GUaepmek=&IyowBSUpZpZlf=&KaAvHXVZfkaUr=&uCJnDOVoalheX=&m52ZAeUeiWZ_q=&SFHVedVrZXqgj=&r9TDzuZVpZm_d=&a9zFS6Yrrjpjl=&zNcYbpZcUhdoY=&BZKRZVXja_jXs=&eOoPnCWnYfkeX=&QwvDlVYWXcpiZ=&ZPzdpCUllhZbh=&gW9u5aWUclrgn=&MeEeghXbaYqos=&rVnVKpZbohldd=&gsKJFOWpddflm=&DlGHOUYogWqWU=&jCsHC9Wiqaorc=&nmIFCsVlk_meh=&S27LMxVVcqWYi=&B3ntgYVpXVa_Y=&YgTz2NYglsjod=&WpByEkUran_Up=&vkHbcEYjUX_ss=&TDe2CBWbfl_rZ=&mOzJaQVceUsag=&ntaMqbXkpVWba=&ZwMJbKYUklgl_=&zYlVYyYlklgbr=&8r2butXrrhYVp=&AE35JwYVUWXqe=&yVe2TOVmajdsn=&rUa5ufYeqpY_s=&lnelBGUal_VVg=&ouyzD4XWqZjYh=&d2uD8sUjcjjcg=&5FRvSHXmsnehW=&7aJWk_Uese_ai=&_cN69RUpbdicV=&lPaiIkWdVcnXl=&sUeAvvZgng_WV=&f5lM3iXncUVcU=&5S7OorZX_mVoX=&7CiS8bZb__akl=&rX85U2Vgaripc=&S2x2qoUXgUUWd=&RpKjH2VfoZWdi=&FdfnIoUWXpoWh=&rbRqA5UWkgaXr=&6WzJBGVeiqZhU=&SZ8aE5ZpYfqfr=&TtYuTeZXjpUYo=&oSCd3AXVpdaig=&aVgTklUZVrXag=&R2LDB5UgrhUYq=&NmFozbYWeggdg=&gGElowYmXW_Ur=&fanTXLYiag_Y_=&PTdAlRXlpdrri=&HMzzwJUhhhegg=&V8ebg3WXWhk_k=&h_vWpPZbWqrhj=&YcLxwYZoWiUUY=&kRWh9uVlis_hW=&VbDsexVc_bqah=&3xYlBZZhVegVV=&W7CR9xZpkgdcY=&PZ8mMaU_g_skg=&HthqdFXXeUhqj=&ZLjuexZrVbjgk=&457SMEYrfllUW=&UBnHUxZZWhqlp=&OU4lSsXZYegsr=&L2Il9CXscrUac=&NxUWCSXVlUokY=&QFgPcUZnlbdo_=&ljtl2KZbkWZrU=&vA56OrWocYhUd=&gPiU2aYlbZdin=&MLffxrVsajjbq=&6XpMplWnnssca=&T7CcOvYZYUhaZ=&occxMRWaln_pe=&Nt9RQTVbXcgdp=&PBS4zRWbiljZc=&kzsUXnY_XcZog=&Em69UyZhVVW__=&CMD5S9XnZkioh=&ngrUQyYW_eipi=&efHXDDYYkZjcs=&awghROUsgZUpZ=&9WZQgDVZark_U=&4FlZaOVlrbXWm=&42UAMmWrgogqq=&jiXVs3VpajrrZ=&PdAGoXXigXmcU=&3ok36oXm_sfmg=&Gd6rieXbXmldf=&UroNGCYdnlgWk=&LIgkPaZeealX_=&nM4FTWZXclXif=&3cDUvKYcbcUek=&HGb2QUWeWgkjj=&lXPL3iVpVmiqq=&WOrv7rVrYqfdc=&ICRd9IZZnbf_c=&MmZGLZUsX_qdm=&Mh4nfZZjmViZm=&MEKiKEXmdlbZ_=&dCDks2UgWZWgd=&ed3xMFWlnblqe=&qXkH8RV_ojqVa=&slsIOnWekYjke=&_4xW8YWUbk_ri=&qNu5UWZZaqecg=&Mlj6K3Wilgbg_=&jy9uTXVbgjijY=&IVQ6gCXkhenhr=&vbjUeIUapaoVY=&bmznb4W_poqXY=&lmmeJoV_gk_ci=&OS7aDfWW_cepY=&3yTDYWUdinXU_=&775A5DXrXheXr=&VSy3KmWeZhodd=&yQZY86ZYcllZe=&i39CQrVXociVr=&JE8CZaYWZXjXq=&ttnF_uUWbagoq=&wgyeysVoodbfb=&nkxgWfVagflre=&WSLUsvWaofbrs=&fDOgUGWbUWYnd=&Aa_uycVWenVXf=&RMlW5uZcmnbfn=&_5FcTIValfdVY=&duU5HQWnjsscd=&DjvCYfXqafXbb=&E6KQCoUpUfYUe=&dghgn3VsXkbjY=&sW2NhMUdYs_Xa=&fzsrfWUdfojam=&OC3xvlY__ZlZX=&3xRbFLUikfcqr=&UJIvaCYpXsnbd=&zToEzcWWVdfoj=&BNvNfeY_XnXmn=&gNVQKAWUbefUb=&WsNNozXhX_pbj=&aaxEe6WddVhfU=&y5IOIWUcjW_qW=&TdUVafWcmcWfa=&pQjabvVVUcghU=&wGTMYFWkaWqmV=&g88TcnWbbsqro=&XOVIdNVZYrjjk=&dwXuZzXXqYlms=&EWzlV2YVbdeXl=&puJWjKUdXeX_p=&OMhhs6X_VYdVW=&faao3uWijfehV=&kG5_hWYpgrqbb=&dBcjn9UhdsVYo=&Jg3jNvYfVqrnZ=&qauIMUYYlcoUc=&NO7jaaZbodfbg=&b2VQHtYhocUWV=&GzuVPfZmeoiqi=&z5aVLcYcYcYUq=&QoNRZMZYdqjYj=&DtxRu8W_Ygdjc=&tHr2pCWhVYVon=&yvXLXbUhlfmaV=&6xapHZWVVZ_no=&RAnQrcUYasmbh=&cAIvbKVs_beXa=&ZlKzTxVmcidsk=&ZpEjKZVpsWeli=&sk62eNZqhqjUb=&d5iF54WVnmihd=&DCYemHYnXWUdc=&_c9nvGUbsnrke=&6_zctmYWdVqVZ=&9L8_LRYfoUhlq=&AUUvdUVabodeY=&Qd4LWEZqmaY_d=&GFnWb2WinsZsb=&F9JPV3ZUeZapo=&ojuNpwWrpcchh=&sGpXTVYahcnjW=&FPPkaIXns_kpn=&ZSn7vYWnsfYUe=&ORvBxUZkVrqoq=&cS6nicXirkkhc=&GpSIgkVgYkkZo=&yEY6ROZnZbbmg=&X_TQdLUdYiXmZ=&cJvGw9Yheakpd=&dkNWJhUXYWe_c=&Pd5CJTWqpi_lf=&5tAe5sWYVZhoh=&54zeHrWrsmjf_=&baZ2ShVcUXbVj=&aNjsHHYUUlWam=&rd9zhLYmcllac=&Sw7ZIpVirZpre=&DYn2SlVY_kmjX=&m4JAJnUoWgsl_=&YKgkfWVaXhfZp=&MSZuoxXXaUkXe=&rTWGUjWdqrj_d=&k395dEYlicUmd=&535TAzXpknVpe=&kXkaZlXkihYW_=&mAwuLCV_smkje=&nRkpF5Xgg_bof=&qepku5YrUaosr=&mdhQFiVlWaYos=&E2VTTnWpsWWns=&zjHEtgVcWslof=&_5uU5sZrVYhgh=&QFppD4XlqsUZZ=&DO7eBvXXsjjYm=&tXesqrYfeqjie=&9whMO2Ulqjnkm=&CVgPgFWgi_pep=&yXsyWVYVghokX=&WA6FtDYYomgpk=&W_cU3xYqdZfde=&gszbxsXnofodk=&QqXlRzXhdemWq=&jnluJTVoVsilj=&9m2WQ9Vfprkfh=&Rnrg9lXcjXbqf=&kmE_2BVkpflin=&8wlOCMYXesbsd=&guoLhoYpsnc_Z=&CkbRszYY_hlWm=&5sEXiqVZff_bZ=&EO_R4aVUgiYVb=&VKQHDoVXbqi_X=&2UHZtGYhopjW_=&dUWcnZYUYUdja=&fWgYBTZXnehso=&jVcbqsVcUkVma=&vOFVQ6YeXj_fm=&LvyHQwVVXokZ_=&yNH6EhUsaergW=&VUxyvBXnchZfm=&auootMZWjfWhq=&La_PyxXjXreag=&eCHkCFWiVXnbf=&xOw5UTWllVgio=&o_QyrgZkbkge_=&8V9dWOU_einpk=&CHtHbbWknaqYb=&IBO6c6UhVYXXc=&GtwGQjVfmmija=&Mz8q_dWYjcgqj=&3e8czYW_lfheU=&t98eq9WgeZUrV=&4vys8bWhajrrZ=&KXnEkpUbdgifp=&rpDDVTYeqiVei=&4FyCY5YedgpZk=&OXYdGRYqpZdZq=&DJPwPvYjlje_V=&IO5zq8ZWcUajd=&SplpiKZpklqps=&j5ouu5UXeajii=&ZmYx4iXdpUfZf=&uoErq6VXsnm_U=&gShACtYoe_Wir=&puSgQcVhnhkag=&nV9XqmYklmeZe=&Px_gbMUmjWpgq=&wpFWxCZmVjmnW=&tnkW2YUjfWfdk=&vp8lMoV_mocVh=&SnTWqxZmsUqps=&HSOWBXVnVgafq=&VEuZteWisZicr=&euGyckXcoqqVV=&A8cTbjUcsgUkb=&W7CpL6VmZrkYn=&f2uhiRYelshZg=&B9GAV5YpfrXYn=&Gk7SouWfbgYrm=&SHr6XZUZa_XXX=&5zYHe5VgpXrdi=&mTVBaQXdmlof_=&B8uttZVXgrsra=&kXIvxVZXoYfXl=&bu8M56VmskUVs=&QJdX_pWjbdi_c=&K6Uf5qUYkaZas=&4PPrdBYmUishs=&MmXlvPXnbmflo=&rDNbckYhbeb_W=&msWW7hZhlkgWn=&NQswX8WrrYhsn=&hSg6oeXiUXZhl=&P_eDBdYrnYecl=&zlYnFDZZs_mig=&MSJoQHWeri_XZ=&tPQTzKUVgqmmU=&4Q_ex8UemqUie=&zpP2mHZrkjoeZ=&6zqDctYYUUeXU=&ZWfCFAZoWis_b=&sPWyHDYfjnnrj=&85EFBBUkYsmgb=&noPYVKVgcW_nm=&AsZZa4VgVniVU=&B2e3dIYaZoodo=&vBc7cKUbrojnp=&WO9iizXiVaqig=&QY_guWZ_a_hrY=&nGsXSFY_amrlW=&V_vBFSUZihdZV=&MxiJWQWki_YeV=&rBZG69Zfsecj_=&HnSGc9YjfXafr=&xE5fwgUcoifkU=&UWTUtJYZimbZp=&W39oNLUnrhlUb=&C9c53EYrcWUVb=&UqJD8SVVq_Wkm=&gAanxyYgcpWfl=&sjaaftVqcdmhV=&amwovxUYlrWqd=&pvBOIRXVcdbob=&keCpMxYmirVqd=&gakAr7Vman_Xl=&pNilROW_XW_ee=&AIH_wPUpemWWU=&Wc2rcPZgUfqoo=&eoiyTFXspjZqr=&r5mgl5Vcmcqas=&xv3RVdZnjcpWY=&8rZMLxXcfbUdi=&VtCPsFYc_YWrW=&_MIDBqWqZXmgd=&lXy54RVZ_bdhk=&qY6rPHZgXlYge=&ZTvVl3Wfsnfgf=&AEfupRZ_kUclg=&97w7fHUdhZUdj=&ZilFnXXrXdWZV=&3P79G9Vbmqrdm=&vzj6qwVgfXUlj=&iWg8MPUUpn__Z=&DRRoUpXgYU_dp=&CJzXlXUWWUdkr=&dlZ5HOXinXVlU=&uzGKo4Yclbp_W=&wDYj2RXnclmis=&NH8uGRVraneqq=&4UDlwWUW_odbs=&KnDiI2VkWlbYl=&wSw7EbZYWYfq_=&lyY6o7X_rcYoZ=&lgIZJBZfqYkdk=&x4KblCWrfgiqh=&eM5XtRZjpVcXn=&DgAcx7VcsfjVj=&A6yeS5VhbaX_U=&CHxQrBVm_pqWV=&26hDyRYarrmYg=&mPqo9KXp_rWbc=&OkTVIXZba_ghn=&6QXEgnXncUdiV=&LNmYY2WgocoYo=&sghJ8tUUjnfcm=&jCghgMUYfslkj=&pYWjxSY_asinn=&l_YQMZUrpZrjq=&UDNJKfXpposlp=&ekcS2rWgZpmfo=&JtYh9lWmfkXYb=&R75joAUlsjbZl=&MLCqBdVWm_mWf=&QtCP2RVkfpZ_n=&un4cScWmqmfig=&6KfrYBYX_sl_j=&2AwIbNYsifhka=&EiIP5OYYklqjY=&BULw_NVnZjsc_=&xvDndcY__nbXl=&9N3JgOVsokhYX=&HQBYUDZmiibpj=&FiE3FnWbYmefs=&2BZCs4VbhrsbY=&5gqsFTVaWpqds=&uPGe_kVfobdWU=&ZbYDgLYaWasn_=&2t3J7nYps_dZc=&Dwhee_UVWgrdg=&DGSqc5WUWndki=&EMRo8gVsXWUYn=&yIxsuzUg_lnql=&GP4a2lXbZaYce=&Wk3VRAYlbZbXa=&lsG3xuYVYbcUb=&39PbRcYamlUj_=&ptrHBfVpggkjq=&vfmM5ZXidqrlg=&akhkkeXcWgsfo=&MoxsVhZrqsepn=&SlBzZ7YsVYadh=&QqYYv8ZrfmgUi=&GufMz4XUeWdVj=&ZxAyZsVhUcrUl=&VN7n6fXjWnXcm=&thL93WZpWqgnV=&vWzZb_UkcfUie=&au8AXcVWkjYmV=&c5xlCoVf_jZlY=&iPUi83YYiZbml=&WPJxHEUjZqZhX=&okSrs7VYehsXd=&JVqkNHUdakZjc=&wjUiTyVsjaYYZ=&6mE4vfXlriWqU=&KkEKFWZpV_lmq=&Q_A8TkZpgeggj=&A2kjVrVhidbhY=&RMIGI6Xffhnbd=&BUvf6IYffnsWi=&MdNbyVVZsVpf_=&OjNngNWVceaie=&KQTHkvZbllrla=&UmM6srZnhhbiU=&awz2UJYkXVdYb=&NUMWorV_WVosZ=&q7Pg3cVpfhqm_=&C5BG25VXlXkZq=&kZDIxSZYmkVWg=&ElrRyxYmrWgse=&qtB3w3WUZYdsV=&BGBEmGZXaWpmm=&DxCHX9ZaoblWY=&Hm3mdoYYqbjal=&EHyLIEVWfnUbb=&OpsrWLYliemqb=&qWvzF8XXYnraZ=&lVPSFrUeircbk=&etxDqGVfjrr_p=&EjKs7NWdVqWWf=&EVtv7LVVgrppm=&qeAXgQVXrmloo=&bAJu3CZkWbmps=&YPkMrEXnnejir=&I8PcVWZVdkoUf=&YAsmlBXgsbeYd=&J25GfMWbnhfhb=&OOLOEWYqpeoZg=&oHEWYHVkbagqr=&aca2IVUrabqgn=&unEJMjUpaiVdf=&J2nIoeWaVqqpW=&kUlEujUnonbYa=&e6ChwqUjcZVZZ=&yOLj3vYjboqig=&_SlNAZWXWf_lf=&ZY3s7qVV_ofqn=&LGzKnwVosZUUo=&c6WS5RVVhsihp=&Q37sRRVkkWUjn=&Y4L9ZUUlbWlb_=&SKbMjcVXVaiYs=&hWeJPjXWeViWf=&PspdaXVrogp_k=&YqUoFFZraVpjs=&tCVF66Xiikopm=&qzSEIWZngqcom=&unvbEzYcadcge=&lZB3zhWrflhii=&8z7JMFVro_eds=&WycWoSWofUhna=&S_vkxjWUgsqjp=&elXGjSWaoWmki=&3SHJ2DXojdUnX=&2L_f3hXZdperk=&7ZmElAXfipojZ=&Z5APKLYlhclZa=&umcrSqV_ofsfr=&75EXJtYlXiYbb=&NTIzJHXafckhr=&K565OlXsVWpgs=&cxXAF4ZgcjXac=&9kfjCbW_bfdri=&j4kSTyVighaos=&XCaqJnUeYZccj=&AKfJj3YpinWpf=&HiFBf4Xghdpnn=&wbBbDIUgqmdeY=&oWxAzAYiie_ba=&DHrfeCYpjnqqk=&ajTnQAUosebaX=&nLIzDMWmbopaf=&BbETabZjsjbZi=&vCnSHsVjqgXV_=&v6Nn2SVegWrW_=&vY3gKbUaacUab=&C3qZCKZWoWgmf=&cJOT4RY_Z_Vpi=&yTb2SZVadZhUZ=&CionCaWnWUsVU=&hpMPWsVsosjUm=&WKz_FRZaUofga=&yG5u9WUrZkkaj=&OPYG6QUphpffg=&CJ9PEHWfqidqo=&U43N4WWnYmqgX=&RZrO3GXbcZosX=&HVk8M4XrfqYpX=&XyuDkDXdeplq_=&M4WLlbUeZYeYo=&yrgIl_YrjYmVY=&NSutL_Vnejnpp=&FHN9f_UaqXWVr=&4esde_Yplrnbg=&ZOAyf4Uorlill=&c3SXTfXnsjalY=&Ax27aXZrmqsVl=&ByZiNHXndkaqg=&vXYDcSWpdfUmj=&zAEqfmYijnfqs=&zm8hdOUgcchYk=&KfSkabWnheW_j=&WP9HL3Xrsnank=<Len9Vf_g_nm=&lRLHt_ZbaiWll=&_3RckLYVYesdZ=&WqzsamVaqekmZ=&P_QLZ8Ykjfmbe=&akRKHRUXpeYsY=&fthPPmYfYd_ci=&bwkBYUXclXbZq=&vNF3kbWZdedZp=&PuYojYWrZYhoe=&rRQGRZVbpmann=&dSeVHsUWX_mqr=&SbkkBJYlmWrso=&WIdkRlYqjZ_oe=&rdbijoYomYfXl=&PmFryFZXlsYZV=&3QS46bYifUoXm=&oJWO4eZbaokdm=&O35CS5Vnei_Va=&GZ3EU_XbmlW_Z=&kKb_MQXndphUj=&KcguLCVZZsbqc=&CLfQlBUqqlUjp=&qJgadbUrYYcsX=&ljFAIGVVVhckk=&fhtfYMZ_Zshrj=&k5bgxGYjhdikg=&lSV63rVp_roki=&5HKQY6YeWopVZ=&2XpaIsYkZsipm=&jSaweDWgansWY=&aXkXLLXkbYrbX=&JZJcAQUodahik=&Xp8rnJVrlieUq=&ECFNOqXonVXir=&Lf9zqoYboaajW=&DoVToFValgfjd=&UFYn2zVknjXmn=&85EY93Vebokmc=&c2lWZkXeslXZm=&EFiY4gWighXWp=&dIlXl4ZW_kdme=&Cllp4CZlYeVZX=&7pLHCLX_b_Wkp=&wcTFlUVdcnZZZ=&GdhpvgZmZibWg=&UFWyJyWfikmnn=&elRR7tXWni_sl=&IBsGlnUYfagXY=&Lb9hB6WkppWXh=&_ROKDMXeirVZl=&mXGYrCVVdaknh=&MffQUUXaofmdU=&kv3NmDXoheVdY=&h3RqDgXdZjdkj=&BmWogtYVcqgiW=&di8aZIXXsjfZb=&8sxoT3UlrYZjY=&3cGbLKUcisohU=&rnVosdZobmdmi=&rC2PqjXgmjemV=&3wLDuWWqXoqqi=&iuIpqKVbWeose=&VvGYs_XpbcUhd=&CcOLasZdiemkm=&88tc8zZadmkjZ=&HcX4nzXleqi_s=&ZxylEBZpXdkrq=&jWbeyOYifgZcZ=&Eid56dXrnVajh=&jCb2DuWcYjdan=&gI_ovDWncVlZr=&KWSZDwWflcsWj=&xucRPjVkgomiY=&XG7j4nYVdjYoo=&YgjGOpZrfgrXe=&XCYm6FVpnYeXa=&HeEpVSVYkhZjo=&XdwrIKZfY_oY_=&L2qROKVoYgoeZ=&eOHN7vVgmgcrc=&TJ4g63YZebhlb=&Brp2fTYbob_Ul=&bfMoTaXjcccUq=&hf6fTfUeackUV=&kWQgRIZUUUrqm=&BcmZUXZiYerZn=&62hVRDVqmddae=&jFDCB9Uk_Xrdm=&ptF4QjXiadY__=&kiM32wVdVlZdq=&bfO5skYeXgrhm=&_abTdIXeiqmni=&_wAILMZUemVem=&BIXZzTVkdkWln=&LdTuNzYYXdsbZ=&VDsWpsVZklrUW=&dn6NKyUUVZZUi=&QLylLPZksdfYa=&wltnYrWaZasWW=&D8JnecUiijinj=&fkixjtWkZYdrY=&CxIbnYUXfkXWZ=&czAlNFWbeZcZk=&Ow48QTYmhYmkl=&mX48y8UnUjhcq=&AcK_PPVZlVepi=&X9b3iVXlYakpZ=&BzmZgNUe_nqeY=&7B_WdtVlfqspk=&wXk6PPXlemepm=&gVIu9CYnhcsc_=&j4J2KXXVgjbsk=&YkoAUfWcesaYa=&KFpv6nZphUVhh=&w6rZp_XiZgalY=&y4B4ImUZdhcXi=&ELSt3gYlWYjno=&5l4VtxZUnnmsX=&olZsyhXsclaXZ=&hrrrhhYoqYWjU=&A4eSOhYUVhmaV=&2c6GTCVbZfXdo=&he46vEXpnfXpp=&xEvITZWdUWpcb=&SHnWgBYcepjsq=&gSSCnpUYYdekm=&tZLv7dYVWeWhs=&ejBrvpWqiab_X=&i3Ibx6UdgrVfe=&eKH8UqUcqVnZk=&4MJbYOYderbZq=&YXE_yhZqVYcmf=&GryNyoVjUl_mi=&zsjzwYXUfYmYa=&usTrZEXUccamj=&umOhLCUoW_UgV=&QINpTyZmnihcb=&xY3DuMXrY_mmd=&4EePXPXremnmo=&9NnSqbYpXrcgZ=&tAU9fOYZUdqZm=&7KpXVRUlcndeU=&Sh3xx7VrjlafV=&yb9HlbYndZbsd=&dOB7LVWedncUn=&9uXFfHYhgYc_c=&T2whkPUrnYo_f=&yO7rEEYpZVmYj=&vetQ66YdXiWnY=&Z86P9rVbffbod=&ruyhWrYYkmYqa=&LswcRRZdibm_b=&WTaaqsZjsfjVh=&gH76N4Yd_hrkm=&fyizQaWVYWepV=&RPctukWpXlgUZ=&XJGwm5Uknmms_=&PhaIWyXUqisca=&5jeO3DYrqelbm=&kyyr8NV_rYYbp=&jcGU5dWXdkg_p=&vauzfvWlmaa_a=&kcZcK7WrsnpWd=&_tzJlvYXfbffd=&zDOYFDZcgipdk=&LfZdhLUiW_VZb=&b5I3MBWZencsh=&5nxkcTYWfaaXg=&mDgsn6YmY_bb_=&ZHlfHLUkYojck=&I7KsxJVbeac_f=&fXWFqSXYdjggd=&_25ZcAWUbinsZ=&Xwxy69XUdogom=&Z9NlkNZspXbUn=&xS_dmAVmfWZmi=&eXyHSJYcnbhaj=&P94tYEUgYbkYX=&i4zoDMYhVigmk=&TnMYH6YhksjUp=&RnaU28Yeckfki=&MkIbRkYpfmWYj=&P_jt3FZjZaWkq=&ullOphVgaZfUe=&YEvXv7WopYfgk=&kxbPB5W_gcZUg=&ssQapOXZXVecg=&KzMvbnWfYZXi_=&OqQTBDXjnWXhl=&IaQlKMZZdbsjd=&ifnxAjXqmoncZ=&wFDeZTXfcpbfc=&QRXfW5Wcdpqdr=&c_ut_tYcmneWg=&Z5MbdcYqbdUVd=&rLCS7cZgep_ir=&gCTLC6XllUV_g=&7CKnsPYeogmli=&yLJ3wcUYqZoXX=&jJNyYqXWnXYiV=&L_8ZFMYgYgccr=&Ldnt55Umhqhpa=&OKTgokZegdfrY=&BZALGkXnWXcmb=&Q4dVo8WnbafW_=&WKsi4nXanjYak=&NyUbj5X_gfllc=&njCx6YVdmVgUs=&RL6CQnV_igkmg=&LVYtVyUcUVfWb=&hZ_rMSYeepipc=&GHmj9IVkakcgk=&mCtROxZarUopb=&7VheIyXlhd_ja=&y_EbTnVgYaVhb=&iquQE_Xkpe_de=&KZEwvyUjYcfcZ=&iyRMbXXheacbf=&Q37akbWkbYU_r=&NrXD36ZrngYgl=&JzLOrkVUVjcnd=&OPANgiVimmYcg=&N4ZHYQZfhaaWa=&OLJeklXhakkpr=&lVL3KfYgWWoch=&nSxrvZWWf__pg=&2bpueLZmjWWih=&Uu4SPiXiWidfW=&nHDpdSUonrgio=&WhDvZkYkVZeZY=&mRXvoZVZYf_Vp=&tfqOsGUprpbcX=&ZinFExVslnWie=&fcc7QsUs_UoUg=&RX5hPVWcbakZs=&LqGshRZ_obeW_=&7z8zATVWYn_ir=&bUFaD4VXkcXYs=&sXAAszUgYoorq=&u8Wi97YssgWnr=&vygMyEXqsmcrq=&fYmeyHZZsVraf=&BPu_Y3UVkiqjd=&F7W9x4Vopjhoc=&Ga8TJyUdViZho=&uyi5xMXrdWVXn=&3ynxlDU_XU_pZ=&diJExwYY_WnrU=&AvsKwHUkqoosp=&HzZYlyUoqaYaj=&syGhPOZeegrpk=&jloz7IVpnspqY=&kx6mjdZhehUVj=&f4KFdvUZkiYkj=&4XXvBgYhYojqm=&5YsD22XlYh_Vi=&tAaewtZUYYnVk=&CD57VrYpWcpkW=&5zbMO8YXjVqUb=&3M7q7MUd_ZlUW=&5TUirOZrkndXY=&pa4_25Zqhccks=&5O6BO8ZrjjsgU=&O_BDycYZleYlc=&4HvNXxWddZfUX=&nJqWv6Ujkeieg=&D5dWN4WYqmsVe=&AKWiCzYdiVlkd=&Fcw2C3ZsUipVU=&EyloVuYaVjXXl=&7j99qnXoaYajb=&5VKT7RYlVlopi=&CJXGgeXVlXdpd=&dOfQ8JZrYqiqZ=&_hn5naWopghos=&ZWxoYbVkbnrqW=&LDhYpUVWifafk=&x56LT8Ukjccnk=&Lt76VcZXfhgel=&ySSEvjZfekXXl=&ealSy7WVWkVia=&5vDET9XhnhgqU=&Ma5OQaXbhlobY=&4F35m7WsXpYgZ=&Yk47CqVgbXYep=&yRuLr7Xffasfk=&lvsmyhWbamkmf=&Mv7JPDZUZp_hd=&zLTTJLUqfZWgn=&r7W9feYeVdgeX=&bPF2HmXmmdsgY=&GhZpYCXUXpWmf=&Nn8fEOYgeWqpq=&eGfbOkWqaVfjg=&up5gMkVjbcooZ=&got9mRVaZhjd_=&Sg7MubWWciqpV=&alRFh2VVmknna=&Ija_4_Yb_scsq=&8NFRRUVpXWibq=&MJmyjIUVqgek_=&5DF_naYmlfWco=&IlG2EhWVXWUbV=&cKwGCzUaqmrpo=&Xyq6NvYbchqlq=&Jm5E69Wjcmjeh=&ZGWFLUYhoYXYY=&snp8rMWikacsp=&NkXlypZm_mgnj=&Mb7xbUWUfVnhk=&VZfuMZYdqifUl=&Cqb4waZcfpopX=&LNxQ8VV_rieUc=&CbU9d5VXbXqZo=&EzbbrjVilgacW=&yBCvFvUirZpse=&L3ZnkiWsoncdo=&O857wlWcbnX_Y=&zRfgFjWjVaqko=&BWbO4cU_lUfVn=&WezrXzWhlnmpX=&hPawxsWUVrnhg=&OQc7mJWonmgif=&lYqmwSVVgXomn=&UrmKUJYpadmri=&GZxWbWZbZnWgm=&5yZIVqUnXfZUj=&lwRjo8XojXiVX=&k9KisMXmWUZmf=&9JkfWYWZnrplk=&wMeVqBXVcUfea=&p87_VCUpVrnqq=&5i4NohUkjYgZY=&qtJ86JVcdf_Zi=&KjdR22UhiWdnr=&uXkgW3Wp_qgib=&Ip5o7GZXrhofV=&jLVtT5YerYafs=&Dcof6IXeiUp_k=&oCxVHGZWeYeh_=&SOSOafYbigXbh=&o6docLWifiZVf=&5Yp6NaWoebnXV=&ZMog8mUoYiXVb=&wd9zYlUZWcisV=&l3sejnVrcqhsl=&PA2GtZXspjspX=&HE4XU2Yhpi_WX=&RPnZyJUaXcnYW=&kdJkBuVdaVY_p=&2_dw7yXgWeslr=&HgZvrUZogUsem=&YKF3kBWhgnhss=&VqSRiGZkgbfjb=&IMgPZ4ZWjqrYl=&vJXhTBYUmrrd_=&2gbKiBYpbiplk=&jmUu_dZcqVWZs=&pW8C9MUghWZsZ=&KCOjtYWkjaoiW=&PqcBaJUknVdZW=&DR3Os7ZYZdpUV=&sGKi8EVfddbbi=&ygwZiyUWYZpVd=&ejpDYBZoWmeVX=&F5EJUJZUeZjir=&gActY_WkoYqjb=&Z3hbg4XbUmpdp=&GKeNktZrhaYpX=&QQJgFCY_UoYje=&ruAl5UZZiblXm=&9YxHoUXnhljbb=&ZUzCWjZfnlmYg=&qHGKiZVUcfhoo=&u3vffUXmUkqsd=&sbJp5eZhrqe_f=&w4WVe9UgoYmUn=&9BiyJlWhjgpeX=&okCIVhWmrUU_q=&VOqL5mZkUXUmr=&NkMz4LXpjjgr_=&5dkONoXVgascV=&fjzEpvUaekkZp=&7nDDLXZdiarhU=&SXv7HFXZeXWhd=&jRsdtCYfqYXXW=&KWHuVeZVgYohi=&R7JVCTXpjijir=&KEzs8IZfbchWZ=&divCgAYdhokkX=&qR3LgYZfkkZaY=&9mD38iZoldhfY=&vhUnfcUiWiVas=&cOZUL9XWdZUao=&msljFHUfikrkl=&fIwoMwWrWZleV=&n87I4zVsihheU=&CZBGdzUm_sWYZ=&qgGHj_WfqiVWn=&epwQr9XdckWps=&Clu3GCUlicXYo=&HmKF48ZsYiWZj=&mExr5XVZVlVXk=&7Vx3UiXdrmrsp=&r2vamLYkYmZjZ=&boTGzjYdgo_XV=&UVQGh2X_Xsmo_=&UNNaBWYYfZXkb=&p9HeuSUbgnYmf=&PG2VPPVYrojkV=&YxZRC2XWenXZj=&6y5mxrVclocYU=&HQXAEjZfjZned=&yCNreGXXrV_iX=&iL9vcsYlfbhpa=&GbngkxXsojYaY=&NQFMVXZUgkbrU=&wRaJaYUqfrqer=&9UwsWyXhnhWdk=&zXqbOAZijfp_U=&5a5GAOV_ahZrn=&s7IrOTYjleZgc=&le8ypGW_ZmZ_k=&ZTp3AlUrcXlgo=&kxpcDjWhqXccX=&pZNugzXUiYpUp=&2L_9wrZgdVfXZ=&7uqQkiWaegbcc=&WGd8TLWlicqoc=&zFAwmKZgifhie=&JcMRpZWcgXsXd=&KFSGVoYnZkbgm=&RA3NXhZsficYf=&EhkINmUjVmkni=&gkd2_TX_fpngk=&d8c9lrVVhmmpr=&jbqtz4YjnfXWW=&AdSMnHWrbkb_r=&IE5qpkXsbWYlp=&Nfr9ALYdmjpgc=&JQb4aOWsbUnmo=&t9kNR7WoZoXgc=&lHBpVVUccplXk=&CO7TSsUnmYmd_=&vWyhjmZXipqmn=&C9AOHsZgoskfU=&tIRQwxYksVpbV=&TbkAZ6VjWkobU=&7ol8UGYkrmgVl=&nOb4V9WXUnXqc=&AkEIlmWbd_ppo=&6GoaScZVZglgq=&D3ci8NUdbdZhd=&ffPM_nUbccsgg=&m8T_IYXbhXipa=&yGvo8HXmYmnfr=&RvIWoMY__iapi=&dld9lHZaacolY=&vpqNeYXmZcUWe=&eNXCkaYhhfYWo=&zivvpjYbinbra=&vZUm7sZshfgXZ=&Qx54vnVjrrZm_=&YDXEZZZpb_gdb=&Q3AV76VVZXkkn=&TQJxZpYsqi_dr=&FAeiyKVXVVjps=&lWAZhBYakUZXh=&hOZHFtYbgr_oa=&NEUlosXZe_ZgU=&BUjbknUYeiqXW=&PyTXijUXhXsfn=&lVeUJaWlfbYrU=&coDxwcUgjmbVo=&rukVMEVX_goql=&moWmnTWirssaY=&Op7pmRWsUUbna=&dfjFRzZihh_o_=&BFIODtYhkUjps=&myW4pcVqqlqXs=&C5VmC4Y_jkigY=&pSkajsUl_rcps=&XvqJfbUifmZYg=&bWhKjcVdcjqds=&hmLN3WZnkZoWp=&YOhBX3WVqf_lf=&DHvFkBUkkVjmi=&BCtSizVkilfb_=&bsGCVpWqfpYfr=&9hB5aRUseiqsq=&bISgq5YVgmbke=&LdOoPgUZo_hrh=&daXLcUZrqZl_q=&Zv_8UaUnhnd_U=&R8cAw7Ychhrnd=&Oibj2VUbYXlnn=&ftN9BHUhqVqkk=&F2qwRhZgoamdX=&32O5mjZiVlhoh=&CAysuhVqblpnh=&MchfUKXYjbqjV=&trbjA3YYqkZYk=&963EBTVcmhenl=&nrH9GXYWXhiaf=&t5Py4aXbkfrhl=&cvvQ4vUjfXZpg=&OXSoMEXqnshVc=&lLADCpYnncegV=&zjlLqQVjXjmVY=&Jiq2MhWdjglqd=&fv4euqYssncfo=&ZwjprbZ_fioqW=&B84Ab5ZeZmcXc=&k4bIFGWoUXjjf=&btHyhLXXphUei=&FdXQE9ZXne_ZU=&xeEr6LYlahdhh=&eyFVm8W__Upmd=&MFLSMIVoemdbU=&6T_vd8WdroUsk=&7IsSO_Yr_Yiek=&49drxZXdeqbrW=&Ri3a_YYedqbVf=&kO6YQEWgodWgj=&QANXSfXVdqVrn=&VHE8jiYnUjkZW=&d5EAsSXYWncqm=&o98jy9XngkpVV=&zKL6hBUpdpicp=&XMofN8Xid_cVo=&zHkXO6ZfZkUdh=&YzJO6jWiholcd=&OVYigGZskolik=&XllqHWYj_iqeq=&uYBkAMXmraiq_=&8La67ZZZkal_o=&lOZLwaXahaZqr=&OyOV47ZhdXsUr=&QctNXVXXplYcj=&NtZYI5XWVcYfd=&rMGmXEZWhclqe=&4impsoVgakiii=&BKbkijUoerl_g=&imsmlcZbsZVpX=&mxBBsZZmmmaec=&cL3lPUXmejofr=>7vcBX_jkfoV=&QlTpWEUXUgrbd=&iqHt5MZahWicV=&47iVErVqUbWai=&SH_3eXVXlmrqX=&42a9HNXgVgjWc=&4SHaUhUZqmYfs=&QVBTqxUfarqoX=&2L6UfIXkUWYcU=&93qGzfX_akdmp=&rc2mTFWdYqYjn=&xccaUVXpipmsi=&XXKxQtUddhidX=&J3EbMWXssWfUX=&wEVUvdYYbgmVc=&8krkM2UnUUcYZ=&WUuZJkYsigadY=&anIowZVjepgpX=&3qjamUUdihsXj=&7jvst7WikiqiU=&kpeSIFUmiZkdl=&WGrjgmVfZgpYn=&TtcDHBUkn_sjs=&23GuIGXa_ZjXY=&qwE9jsVssieoZ=&ChThwnXYYdicp=&WpjJzeWdsWecm=&TI8bpUYgdkehV=&q9lqFGYZVjjZm=&qhXdTdWraYnm_=&XUl4FWUYXbdqk=&pikHVaZskhejV=&ILKmTFYZinpho=&vp5FngWUmYqaX=&ACg34fUrjXhsp=&nDFeRiUhfmbki=&yMTVWbXeWfqoU=&TryOg_UrkarpW=&9ziSPLXVqphsi=&8UoRDhXeacsqk=&OjVLiiUdUgVXn=&VTTc5sWdXn_mV=&wbocwtYpshfmi=&ygF5nKWogUYpq=&_gxBCQXokYfYr=&OTHfqNWUbjslY=&zGscjVVrofUcd=&HXBk4SYVeZhgc=&Q3Rn_RY_dXnlc=&_m3ofRUhjjie_=&Kxr4i_UaWkqcq=&PFCPizWnpca_V=&J5XntQUelcff_=&OqZIFpYYdYlfd=&tAl3VXXscfepY=&Lb7AezUaXjqkg=&zPtbD5YaVqaeV=&n3pb6PWXhpdqa=&UsG6jNVhX_hkg=&fbgSOFWqmphgU=&5RpLbtWdWsWYp=&LJjMRTUepoX_s=&LarpvAZrcafks=&btEIzkZlfdqqq=&IPMZfbYckcjWY=&yQARo9VUkcabe=&iiJtdMYkVfiY_=&uS_2j3VbanjrU=&QKtFBvXijnhpW=&cdf_KBVsgrZjc=&RgwouoWUmpXak=&JbXW9ZVWpbYVb=&MEopjHYnXVV_m=&nWT8yiXkf_feb=&FGDNB6VoUocen=&e4yfQmVhaejXV=&EeVz29UUfXo_g=&aw9FyvYmbmoYc=&95bsaGWVlfmZs=&sP3ydKXsoWnkd=&RmhBFjUlUdsek=&YdPnF3Uqmgecd=&IpUMM7XXc_gWo=&bxgTCtUUXbkWd=&vFmIcLWmZoXpr=&mCyCNsUhrsrop=&TjOtJ8ZkXfdlj=&iAF3hkZUkjiXk=&tmpGbPVonhjpq=&vlnuNMXUYWnlo=&9Z_cTSYlolYmb=&dFeeaUXmmoWo_=&QyhElVYj_qmlk=&YqnkDgV_UWslV=&vS_eYIWsdahsq=&_DMjVhVjohsgo=&3wiECeZXglpjY=&aQAXTfVWgfgeq=&oKzLFKXdhWmgb=&tTsRIOXmVneX_=&3WKCgfUgUZqoj=&W5nKI7ZXhfZch=&GyCyQ_ZifeWZa=&tTyqB8Ucaqbcg=<9doXYfjjqas=&SWnHIXVYYhisc=&9bg8aIXZUnncl=&EvyChbXbZUrpr=&DMY8NsZeVXsjk=&jyvcwkUWZcYpl=&wXB8sBUgjZncW=&5fK4qNZZUWocg=&cZiL5DUYWfape=&xgkSDDWhXXnrf=&d9EzdnYZsfcZY=&62hqDFYdhceUW=&ZwXDxoXqbWiqp=&niWE6SXqhffar=&kg3bobYUlcYVh=&8NyAgvVqWebXf=&MjkgJjWgUjneo=&o6vfubVegnYrm=&66zICuUWnaeZe=&j7iufIUXldcYg=&LDlrLDXneiUod=&Adb6hQXZahsXh=&uPWgk8YYbZWeX=&yGHidLUlXjmkX=&thEHoSYWippnX=&X_EVAoZbaorhl=&DoDD5gVXchfWo=&D9IYcTYkVcsYU=&GPb4AcYYonsjm=&4pCKW5Wqpeqlf=&_5kENcVfhXajh=&_ZKgowUkjY_ba=&3Ev4eWVUesjgf=&sKgtYeVffWUh_=&9qSFRIZhcjasc=&mwfDanX_kaXnb=&QvnLXuY_WsohU=&9HXIpGZYYpZlY=&e3SPxVUsqhqls=&C4yQvxUlrddXb=&TZpoiOYgoecsY=&PIQrTeWoqXhqm=&_i6KzOWaVUopX=&faJjfdZYVjebc=&m8aTFEWaqrkaX=&Ulk2ICYnqolWp=&ycYRGMXjcVXZj=&K8tD6HWYeaUas=&2EyGg7Ubroshj=&nqwMMpZscWgkg=&eUftAfZeamcfW=&jGYgC5WpahkjV=&fP3B9ZZsmpoYZ=&VboTdGVheYqkn=&GJN4v4ZWXecbj=&VaNTTdZXprboh=&x8_P_7WWqrhie=&hvRy7hUreosXl=&s7GYoFUilqqkZ=&npmHL3Upmshh_=&c3ZDnDWhlUjmg=&djuSIoYcffoVU=&oJtL9XWajYdmn=&eCNKkYXccnics=&_pRZkdYXfmhmW=&N8vTgeZZfmXYh=&h5mJbeWrbdWjW=&oq8LyZVihibsV=&rpzdIdUYrhsmq=&JKcQhyWYkZelr=&48ahauVroqiiW=&oU6NnhZcgVUVk=&CCwVbcZnompkg=&D56anuXh_iqhn=&legHHmXYgWesX=&c7cT6HXepoZil=&YC5ZNXVflhUgq=&z5nXV4XekUfWe=&wtBxNbXZ_sojr=&sISuDcZUafnrU=&GVPUXkUbfnjs_=&LlE9P_VpejsXa=&eXMhqZUeranhj=&5KmAkxZcfWpni=&hE2vAFUk_Xjhm=&_D_9TgZnoVscW=&kL7qR_UWbZqoZ=&6JbU_tUfZkphp=&P5auO4XpiVWdj=&487PdUYlcVidi=&vd2KVJWVWZfpa=&_4n8vGVUbbrja=&to9ulZWlaqrYk=&F_gZ_OYaifqeo=&hV4wUyVZ_kpbq=&TItCdvUrXUair=&2GdESOUUUZnnq=&HKb_ThYpmrsYp=&cEJtXoXopdjec=&7CpwegWqsZsVs=&lRdCC4XjbmYUi=&9TOqmhUelhmXi=&klwt2lZrUh_pn=&QpDnL8XjVfoeg=&CVxKPCYhrsVUb=&RyLGUrVmrgVp_=&gXtQ5DUqksrir=&YGIw2lUUWeapm=&cDB8ZvXfkapgh=&JzqYXpUoYhd_n=&8iDat5XcmkUkh=&ZDJkXjYUkqmkW=&NHdQvtUkVnfgn=&CamY6uWXe_bie=&f9_nUcW_dUZV_=&8tSTihXglnlni=&ziCCJMUXaXW_n=&phOEvSWkemZsZ=&bQf_miVqbmdff=&RZMmxmVVrjmik=&mDjK8DYpUiVcV=&r7Y8MYZZslWfr=&OgrEo7Vqnbpfr=&3d3HA_XjpYVbe=&pbl4cGYjrVcdn=&NY2EvoUrdlYjg=&ReHz8OXVoXUck=&wfJ9tBWdhcWcZ=&V_hZ7HWWbomhn=&hMEgbVWkrnaqU=&GlcHxTWndnjZq=&qIEdb8VhhfsqU=&cM9LxeUjVlenX=&QuL2dIWUUpenk=&PwRjZjXimn_Ws=&TffDRpVmfpZjY=&Xtcc_eVfWmhlf=&l93DmiVXYmUUj=&OKYzshUUojpaX=&btsEg6Xjenife=&TGFUICUmhodqb=&B9r4_ZZjskccV=&Bsw83UVWg_UWi=&EqkKGmUW_anmo=&aDlmPXWkfbjVb=&nXsVMgVnjWkhc=&ey2RIfUf_gXVb=&PzJjTdZrjUUkm=&BM6OK7WadfVhh=&AIIYZFUpZbjpg=&nCR6UXUqk_bsW=&VOjK8CWcgncds=&D3AVUGZWsY_dX=&85N4DQYWjnegn=&DwOofOYbm_nlo=&ELQ2lQZUliXbi=&QfeAQ9WcVdqVr=&R6MQPhZpcWi_Z=&3D9StjXfspf__=&DMsREqZrmicsr=&KyXPhAZnrekrg=&Q3hcqXXfjmdmX=&_xolN5WXYeVjX=&_TDVpGWedcVp_=&_Ms9YhUUYmbjY=&bngO6JXXjYbbq=&jbCGp_UVfqrcb=&OI9sfQZpqolXY=&NallUlVhfVXcq=&pFhkZwVpojZcn=&KAXyC_UXYn_jp=&UG8bUXWamijcX=&c_tiDSUYmUWhW=&tAgeOXU_rchab=&lfIQMsZfemZUq=&EU8LBUZmshcpf=&jPmUNwXcgocUV=&MC3XsxUmbVlpj=&dKDYpmYXrklba=&uzCvbLYpapg_Z=&hTl_NNUidYWYd=&8dpVl6Yo_Zia_=&TmwJmEVkkcUnd=&Ii4GD8WmoYiYq=&ddL9ReWqpenmh=&fdLC89UeqZqia=&qfcsa5WbVkkai=&ODVVQtZdcWsro=&y7zGUPZYckYhV=&gFC3o4XisYlle=&XjF2bAUfcprWZ=&4LgVpyZkYXkWf=&44YHiZUZhVkik=&XJuTGjVbmmngs=&xWT38xXmgpfbr=&LxiHgbZsreWla=&VnqOkyVZYeaVc=&TSUn6YVcVfjhp=&D7FVLXVhocmmo=&OxwM9FWgYdrap=&6rGUeJUpf_Ymq=&dlnRQyUrjfY_m=&D2StFpUZfshda=&3hdTbqV_nkdfV=&xV74FEVdrfbXl=&p9PYlnZemqlhY=&v_74wZYomnjrb=&VQHRskUjefkmo=&YWTK4pVgWsdUi=&GvF39dUpgcocl=&cNtJjcXUedWqj=&dPfX8BXjhZhXV=&IzltVkWXdmgcn=&TXKCscWrlabbV=&l6yeO6Zkjnplh=&nI88oRWqYdiWk=&3KYWXdXhocpXh=&qrakUjVoWnbck=&SWvoYIUppVV_q=&nnMbecUbdrjWU=&cVSNqjYZk__Vm=&UwzdNfZdYgrdh=&fEBdXGUlbUehW=&Z3iVqcXbqjdbs=&EfKpOfYYjfkqY=&ZkndTaVmcWnjU=&UdyumvWsjkg_c=&qG_GiYWbgYrdW=&O2Qm7eXmbWfZe=&dLu4XdUpblsgf=&_3VeZCUcflg_r=&hVQ7woXqssXX_=&DKrxZcZcgmbXU=&MeqMsyUnllVVm=&SzcOxgWoqoXUo=&pj4iLSUopmVar=&4Y6NcnYbaafpU=&IwHACAZjmenUn=&FBe57WZjVVUkl=&Vw34TGVrlnaZf=&NyluYaUoYlgWs=&FabbDCXVmjepZ=&VCvfdgZUaUkki=&dCwxCAXjrrejo=&E5tLBVYYoY_pq=&mGmN4wYdhsjsW=&D3vnZyUjX_sV_=&kDefTIXkZsYrn=&VjJBnQYfcfdbW=&calDfgZbjWVo_=&BaoC_6YqeqVVh=&YNUcY7XrZgZqY=&6_y46yVeUg_gj=&UbC7VpYoh_eqn=&zjZcZSVnkjfYV=&P9ZU4vUkWnhhm=&7lZ5UpXjjpmcs=&LKzDRcV_lXenr=&6BT7yYYramrc_=&MHFjuVWVeqsYk=&oef5HpVjf_gjW=&3C6BKuYqqbmpl=&t8kXzoZkmVr_g=&saOCS3ZedjWlb=&ebevY3VVrmdUn=&ZtqvWmWlihsaq=&GEKoBEYZWhssq=&QzLgjFWWgXZpa=&_MDBdWV_bVamb=&QbxXUoVrUamff=&pSldbPWiVjkrp=&eFzxawXbpaopk=&BeZ43RWhpaeWj=&DeHFm5UkhjifV=&ugEvJZXWbsVsZ=&2l9riCUagnh_q=&2njmDuWXcYki_=&2rinjvWfaaXgi=&PzKkgWYiqoiZs=&G99ZBJXaWbcfl=&wPWKCFZmhjgbZ=&Fk6iteXXqdj_k=&fTyCcmWUbZVpl=&SsVjrKWXcaklg=&l_OrpGYihhXba=&qcklmDWnWpqmp=&CV5BSYYXkcYrp=&QVgMSYVXfZann=&8m6OZgX_UrYqq=&rCIpSiWrsYkdb=&5IAtdkWYhdgVU=&8ej2R_ZsbUcrW=&VSLFFgY_WWfYk=&QaYqJiVsbhbsU=&4P4kCJXrkUYrq=&8kk2HvYdrUpgg=&BaIbGcUodVmXe=&F2beExUcbcsaY=&txbltxZsYfmUZ=&w77zmTXalWcmb=&9vzcg8VpogcWW=&SAvmGPViUeXWj=&iLjxIEVcVbjVl=&TbEezQWqrcpoi=&m3xKawYeZUskh=&pFjPW5WcqcfXd=&e83ETyXqncqef=&BCc7siU_gdlkk=&tPvyG6VZbisoo=&VompBAWdehaVZ=&HHZOoeWqanojg=&GoIO9OWZmssoc=&PGaFB_UrUgocV=&fcCMv6ZefprVZ=&8vpyopXncnmaW=&m3CHuhUgpfdc_=&OLGVzbZjkoq_p=&Q5IKwVYfrq_fr=&SSHsUeUrkdahr=&6kOGUfYooYXUU=&937e6gXlUarbc=&LvxrDWZrlhrna=&vXZAgmYphkeig=&YF3DgnYlmbm_Y=&fg5wFKVlseUUj=&tI_H7nUhkggof=&uJltlAZkrVnre=&jaaH3lX_ngmhl=&r_M_KWWqjsrqg=&GR37AOVpYjdca=&6hMR9SX__UXZj=&OHZqPCVpXVpgl=&OaFlcyUgcfhmb=&NRQpYTUccaWbo=&5i9wBZYZafUUj=&ElR9ZhYaXgaeq=&_lJkboZfffVnY=&s_sKuUZecekUU=&YzGCNmXVabcXj=&RpAwg7XiUl_qX=&FVzqdhUjbWVha=&qUsIxqUfaiagl=&__6kDCVrahrba=&64oc3kYmhlqjU=&jneJoZXUVmmla=&vgZSxHWikoUdY=&8seSOpU_omoYV=&947EbKZgiYkUs=&LxrC9NWgVdhnp=&Smj9MEWqsVnYc=&7U3e3WUnjfcpp=&vyavnAUnqdgbl=&xT_nNGVegoaYm=&A4q_8zWUUldkY=&GLcViBUogWfYh=&97mgn3UUioXZ_=&ZD5FicVjWVgWr=&ieRyfnUgWgbaf=&CLw59RU_amYh_=&lvtFrMZfVlVeb=&dLh_KnZkbhieo=&ZKuMIeYh_gVee=&uFHzrnXmgbhfg=&Ft4FvDUnceamo=&KhVvnHVceh_mo=&zWuYrNYbfYcXh=&ERIuVeZnafpnY=&QbGHtsWocffXX=&QmOPl8WhssnoU=&h2lWaUYgZcbog=&rxp5U8VlaZ_ph=&FJjKQyUodZcsg=&rHF7q8UeZZgYj=&DP6LyNWWioiXf=&w8G97kVhfrjqf=&jR2SupZdWpVWb=&rMBp4XZscjnqj=&VQwoxTWllaWkg=&ezgk4qUdbWcbs=&xka5aMWUaed_j=&T_CjWGWUfrrqe=&eBhqrsXincjpm=&uFUBYtXamdrno=&kPnOQ3XmlhUnl=&nUS_G6YXcbojU=&dxJTrnVVjcUia=&naClxlUckqqiV=&9cqPEVYXVlhYZ=&7i7VnPZrVnrkV=&b33P9FWornYfV=&OohFVEXrmjjXl=&2MUyn3XYXqofo=&quKvk5VkWblqX=&dtjbLvZcagcsk=&vx_cjFXmjbgbd=&Hlx3asVVmirXm=&F9xd2iUi_Urgo=&bMSJiGXcrVqme=&pAIiyNZhgnlcl=&CnEJ7aUmXjjma=&aPOWHbXWnohps=&jBvRj3ZeaeUiZ=&IyOpVqXcaZfae=&_cOGxoUgfnokc=&qRoodnZZnkclk=&L5ROcLUrZWsiY=&FnePKKVmogsoX=&8xdgIpY_XVfdf=&kvYk6LXVigghj=&ZiCDaHWofbnof=&f4fOABUfjXb_n=&SrwpmYXjafsfh=&Z_Jw_5UXZgnUY=&4sJibhXhkahqm=&WP68SYVknjjoq=&L3YBRWYjhaXij=&y8wUzDYYmaesc=&8EmGi_UbqhYoq=&JNKjaiUUfkrog=&sWyGpQVXcWded=&TtMtflXdqagnj=&gd87HVZreVpfc=&U5eT6sZqjnaii=&b_FigcYhZeXme=&aUGMwGWUohrfo=&LSXFYtYgmcmpq=&Og9gQAWVfeqnk=&AkH85LZqonegc=&mPXcKTXcdYjip=&McbmR7VeYdh_q=&LCLUpxUlYnjVZ=&KnBXwIXjjkcnc=&sV6uRjWkdZbYU=&X3pie2VUXba_b=&4FhFhaWUqhZdb=&cLTUVHVhjmXsf=&BzjjZDUnrVoWa=&Pm8vhCWZWisYk=&7GzKvKUnqicsq=&cWDqEnYrX_kVo=&IoMktYVeZgVfo=&JpZzKJVdgsfXk=&xQ_I6QWjelbrb=&GDvEggXfVnYsf=&o5n95_Zqodbcb=&Evvn8uWcercZp=&HFIbLKVZXjdik=&IXIwIQUYlkkkb=&FErZikUjZZrbh=&yf837cXnXUUlX=&mMf5iLWWgYjZn=&Gpd4qYYmlsp_e=&hsvLWFWis_lrn=&T9nBrXUpfjblb=&g5IgFLUnXedXf=&JsY2k3VdXbZsU=&ISwLuvYickecp=&NjkxJsXeYdZdn=&YJndCnYZgfUh_=&FcgUHgUjhbWWs=&BQtjliUkdseWs=&dNCA9bWkhlknf=&4Z5wHLXlhgfsf=&ZtpNnqVnmWXWV=&jPeVSNZggZYeX=&zUnjqzWiicjc_=&lA32muVbYiWje=&L8t8EkU_rUhpe=&JzQD9JZmpYbZb=&eiHGrBUlsVdad=&4FdcAQZfrbkeq=&sxgv3IWWrclfo=&TXIMXQZjXnWhr=&WqF9PCXklambW=&EdliotZlegXVm=&OWJXaRUmp_pph=&uTrvM5VdiZfUs=&ZWQGJNUVnjYsh=&DBrThSUijkmiV=&pOT7XdVZccips=&PEpibcYkYhlYW=&jI7TzjUaXlbmq=&UfyMeGWWqUprg=&XaHljpUnpammW=&x4YPbEXUicjpm=&Vj_wJJYWkVcam=&WNDNuZZknlmkm=&CV2Jw4ZbqjZfo=&Rp_pXNVhpoejU=&7qVt9_Yelkhsn=&7TXLVXYZZ_nbg=&8RCQBaVlednYa=&NLaixbYq_ffil=&JI3ayrUk_nZfq=&Ozd7eAZYfj_ia=&MGIj9lWfmZkpi=&WfjsNZXXdalfU=&DP5ZtIWmkYXfr=&HXNcgFZr_iq_n=&Wdoa_BYZjfame=&PXxQaGWoscoga=&3Ak_dpZcgUjaV=&PTznybUXYZVoX=&axoP9JYdibX_n=&F2EYPAVlYrVsW=&oyoYlgYig_arb=&EVYN9MWfUbXbZ=&3euAzkUkUnleq=&5dUzx6UrjVj_j=&PcOpU4UqVegfW=&clAQ_OUqhoabg=&_vFqjSUopaWsl=&w9HkE8WprdUqY=&3qoMDpZZjepr_=&_L2Ha4YmcUUfg=&5XI3zrXmhrrUa=&zU5QoEZqggdVp=&qRL8xtY_XkfbX=&vhJjHBZaZnkZp=&h7gDnXUbbpc_g=&hni9f3WUgnZrZ=&YeP8jjWedVsni=&Sg3X78VUhYlXp=&wQnkKTYfUsjWr=&preEg3ZeUdjrj=&NsT4WbUbmfbsa=&p7Fm86Xlffkbq=&JFXxAaZ_eogjh=&AmiWTgW_VjZYb=&ADS9mRZjiammp=&riqJ9gVhieqrg=&32fmPvV_madqp=&FJjpHMYeccVcb=&n3Z8xuU_ogWhm=&m4BjRTWsrjjj_=&hDWEUiXVkpWdh=&cDIYl4WfsVb_b=&LSEzEOYkojYZn=&klHDalZeniYUd=&lR5KEIXmmWema=&evQMZeWcVXYnU=&cLRVGkUYnloom=&KpDFlhWcallem=&H6fFk3Vkkhdpn=&j24SsFZdUslYi=&_9APLpYqlXhgj=&ZZKWWlWYZnnhk=&oPnqskUrlrema=&JD9oRfYaWcdVd=&loo8TvVlbi_ek=&hQRBhhVssdWdn=&7owIAxZXssabZ=&XDOC82ZpWajmW=&7UNkGAUapofdX=&JTJFqTUVpiXmr=&FLPJ_YU_aYkgr=&WMdYhGViqcbsZ=&Zdme8FVoVXZXc=&uCmT9YZfceWms=&eLqyubXhfpokl=&NhDz6SUhfjeYr=&u3VHy_YhgUoUs=&vhJ86fXXfgYse=&N3Xa3DXkkbr_p=&MkEDnjUksfflb=&jZUdYnVicUfan=&LGOyv9UXnn_ms=&VD_eUvYekVoZq=&MhkgtVVogpWpn=&LAh784Wncnreo=&qtO266ZscfsYb=&ZnY9xqZkedmis=&zIcKnjUgYlZkc=&QTkd9uXbrbdck=&nte5SOWWq__mh=&r8xItwYsdd_hW=&bdqQtoVbkU_Zh=&lby42lWbgnkfr=&xCqeWMVcVZqZi=&NFg8rwWUiriek=&52nsJtVfdmlgZ=&pTcmUfXjnUWsn=&ZA7F4oZ_Xe_ig=&JgIeWdUVXpghZ=&CggogNUrnnbfn=&FdoSJuWffnUnW=&rW2YUMWhVelas=&VPutrBXkqi_Yh=&OycBKkUrYeVcY=&82Hd2VYqejmsW=&zcukckVbsUecm=&6NQqmRYXiqVhp=&3E6mykViaesf_=&KkGtQwWlfcerl=&HZ3sZZYqkYhfp=&6MhUOqYqnnisb=&hPoGSEUndiWXk=&uF8MFbVoekodp=&wMLjhaXcmUrW_=&PILREUZpdor_W=&KwODK4UXbXdUn=&y83Ra7UXmrcre=&ttHffeUXUUedY=&VdthQXVpcUhqX=&KRZVTjWXambmk=&mb9yepXnnUVkl=&jT7BY7XfXandZ=&VPxF39ZYbrkco=&6t_sVXWhhaVpr=<Qx3eWqVZlXe=&OY4a_iZdmgriV=&ZmVhTaWZjonY_=&gpgyITXmocsqg=&uEatseZZmorVU=&JjlDFlXYgfoXa=&nMnprsWcYYVcU=&fFzcO4WWoWndf=&zo6cdQUppcrin=&32ixaLVYWhadj=&hufgFnXY_msVb=&vfdAHJYdfqphW=&wIKXWuVgVcmYa=&LkNMKWVZbhkrU=&qJGPwdVUoZjnW=&udtlhVZkZdrXp=&fCaDinZWhheof=&HxEDnKYoVZdjf=&8dbFHnWgomYch=&siXbDYVkZodeZ=&ob9bcAUdqoime=&ykJin_VsXkric=&8JKi37XlqlUiq=&Cyua3SYialsae=&rq8bMcVpWcgia=&XVdoOPYkirrlY=&sUQgU3YUbdigl=&QFvvNYXinjekm=&ih9lzlZnhpphr=&KAGINtXsUjrbX=&4ccBzTZbcickX=&FgX2crZVolkas=&ROhrvKUYesVoa=&Pgoie3V_WjjXc=&UFlNweVralXeo=&zrpGgzXasfefY=&gAw29gZnXlknh=&9sA3SpVbkXXUY=&v73g3rWcngpfi=&nZpB_YVrdlebs=&NwWMfEWZhegsd=&WNfDNaXaUnWan=&z_qKyCXkmXlXm=&2hE5xYXrpisjk=&HvzEYmXXsaYhd=&8d3LmHUisYlck=&VqRaFGXdamsZd=&ig7V4RW_bpVYn=&VYKW6nWaoliVU=&Bxo3yhVZqhkqd=&JTVRAMVWbclnp=&NpClfaVjdpcqn=&8xPP72ZXghaqd=&unsQHGYXV_Xaa=&frvt3xYVjbiZo=&phYtnwYcdXsUV=&lpqFzoXX_gjpV=&kDIOimZrejYef=&UCKAzNX_Unjbj=&mg7KkuUrbnZrs=&UEAD8OVqqiXnm=&KqhAmAWjmrqk_=&qoxaTHYpmXk_k=&vKiFZYWihipVd=&VWx_YjUdjqgVX=&Dar6AuXUkepoe=&d2oQCzYqcealf=&gMaTdVZkmidiW=&HpkHOHWaWcbUa=&CAGXdwUUXibhs=&alGFrjUdYojZq=&W3vV75UsisohU=&NbZtdqWVoXjsf=&b2dijeVdagXgm=&DlfWfGUXUZiXk=&sMELBzYpZkhVi=&NuHPZXWrqVgmm=&EcakZ7XUj_oce=&9wUNZxW_Wemg_=&ddXzT5YbriXch=&zLtMMrUdZooVU=&zkGnBsXrgdXnp=&pyLrYDXfon_UW=&GbLfVmZkYqqsq=&BBoOXaZ_dkXmd=&aetW8sYYcjcZZ=&6yupBYXWnWpls=&IgSGEYXWoqbed=&DG5VFVUYnbjpl=&Zz9WRTWncikYe=&o6fCxqUrhmnep=&egizgaZfmbhoo=&3SGUl4XmeaV_j=&xbpE9TYrXermU=&J_3QYAZipVhik=&AEPvXhYbnohcY=&6FjnPlXZrVYbY=&h9npiNYcmYaah=&jeSBphXfW_hXb=&biQY_gWgYgeis=&duf_p2UYjd_lq=&hgGAwoWmaisYo=&5CT5WiYsnedjr=&fouznSXVVqrdX=&5FbcsUXpberWn=&EvCDVJVficXdV=&QxqTC2Xpkd_UZ=&RAN4njXngZndj=&X_njHsWdY_edZ=&GtLGA9W_jnnVn=&rC9OjtXUjdjg_=&YpOUvWYZYcihb=&hI3hgVVcnpbUa=&hZZjLxZViZngn=&yhHfTJZ_eYWcb=&otJNinYsYphdU=&3s5nq9WcdYeof=&CkNtNdVqsgaeq=&MzrGpPZXolYsq=&EWXGbNWqrbgeo=&F57YSJYrgqo_U=&kxuNpeZqabqUq=&jOeuceUUp_kmb=&tOZIsrWflqkXd=&QILE6PVrsgVed=&GshcN7XnrlXik=&zfPPolZdlXmUa=&tWMJbjYmepgoi=&T2jNcpVVmYmrZ=&KmJgChVlodfdg=&H7NktnXsreeaj=&m4QI6XYkphgXV=&P4jIlxZmihebX=&UP5qulUVegUVl=&OpePIEWeUhjpi=&JyIr8OWgfYlff=&znfF6WZjnfUpr=&y7eI5kYfpfidp=&sxfb6uWcYrbUr=&9JWSdbUZWmp_o=&Cx2_P8UYbXnsc=&V9pgKGVha_hrj=&YwNpNcXjlWbXb=&6YqjYOVpaXlpa=&AvxVakVaYXlUj=&FSYNZMWlpoanp=&3agm8RXnphgra=&vUjBdNUlhgrba=&kZe5GLUodVbem=&oMVANTXrUhash=&BKBERPYcZnYaj=&JFDrTZVbhcsa_=&GShgWKWrcUdgi=&X3xyN9XkVpUmf=&4TWUkYUaZcZVW=&d77ly6Ymcmnsb=&zs73j7VlchomU=&jYbrguWbfnolW=&zQhqgBYndeUZp=&8qoHVLVmVhjjk=&xNi57TUfpkke_=&hsuSAlXlgVfgr=&umfuikVlihaaX=&Mzry3KXalYYcf=&Sbm8HlVVe_rWW=&IyowkeZckXlbX=&RbZW9gVhX_mlm=&aOlmKKVrhXjnY=&OhrAyKV_lkUel=&uCfXQBYVelbUb=&zPNqu6YacUblX=&Qb3l9gYabmhhe=&JuBqnwZjcsXpU=&fxHZCtWmmkrWh=&8Ua6tDVqnXcge=&4ibUvNZelokqn=&vHiJkPXVeffgr=&fKHYmqXlhpXg_=&DcxlT6UdoXqZp=&vDDDmVVraZUYj=&NRyFmAZUdkneX=&l_mQRgVqaWnpY=&rnPpf6YfUcgWq=&XL9CKGVZcriom=&sSO7Z_Z_sheqm=&ECgQLjVfWlpdY=&PP9KR6XnUUqaV=&LsQj5WVfrXsgf=&nwdn2hWbVcUlr=&KhRR89VijqgnY=&Xf3wTLUbaXpnf=&sXgq93Wsk_esa=&oy7xohXqappdZ=&K685SYYrUeidl=&ZQqOjhYZdakpp=&FuvuQhXdklggl=&TyD6KqWn_cYoh=&eg5pzmZYkXplr=&BYDptLZsapfkb=&7XvciGVYnacha=&MtEczjVjillpj=&fE33mKYXqgUVm=&4FMcaBUadZsse=&t_nHKpVjjWUiY=&Avx9MkWhhVblW=&qNhvXeUppfUbp=&SUxfHXWWeVkpp=&fWfgCGYkeoZm_=&4pxBeXZXjebak=&_MENKgVXfUdpj=&jCB4B3Zfgqqlg=&XFappJWljlqh_=&UYyDKDX_X_kjo=&llCFITYXnccf_=&l2u3DyWfWbVri=&xSxdmCYqmVUkn=&rkl6RpUipsqmn=&gF__ooWiUcsqW=&FkvsSCXnaqqde=&LtowYQYsWlekW=&LHK6aXYVsgYsc=&sfPGamYghhapm=&ZvWR3PWqeadee=&O5IWeSYoZnain=&o_fBzBYUrbpXb=&ycwOFwXcVoes_=&SrJybCXXlrhbi=&Jbuh7QYgXZlnq=&Fuqwe9Zoqeips=&IyNmwDVdZUogW=&CD59kyUc_ahnc=&BKMbYyZgpdffY=&X_nUxbXYknhsa=&YqYMieWaeonfn=&A6K4ElXWogfZj=&XNUzN3Xnp_qkY=&KFQjhuY_qdWda=&AOzUVbV_VWlfs=&feE6gKZUYfUYZ=&6ymSA6XgrUnok=&S8htOVUUnYkpb=&q4lQRGWpcadYc=&eX6lyCVmq_dlZ=&tj3cUPXjjYYnq=&LMHLfqVrXZXo_=&K2MYXbUXnrhlb=&ruIxggXajhkpX=&GNUsRWVoqfejW=&cVq2MoYhccnhY=&Tygq4EUdVkmhY=&csUa_4UZcWaor=&SGnezoVgcp_Zs=&WOryuhX_YiXcn=&nyulEyWjn_mel=&qlczR3UiqWmsm=&X9xOMaYprmsej=&wyVwEbUZsYcoq=&r6cCfCVYlVgef=&jeNkEDYseempn=&URbddLUWUjgdU=&JZuZgMVmeZVVa=&Wj5ijhYnUpikq=&y5UH9AYmnjgnh=&sv2gRtZrcZdYX=&2oPIi4YUYbUVa=&B9oGmuXebmsqg=&i_qjQMZdjajVr=&6yuZAyZqrqijq=&cUbkdHXscrgnj=&Ww9u4wUWVmfco=&DmvbMwUqaYeck=&7G8ncBXrfhWlp=&SGBcQ6Xakcjbm=&_IdbK6Zanpnai=&URccZEUWkqnhd=&yKDC_6WYkVllo=&qxAVYKUfVWWhk=&5dYT4kUVdUcU_=&d2hAvbWjdjfii=&v_Ut_hXahqcsm=&Evs_EQXYYqoiV=&ndmIffYVnUU_Z=&MROtDuZerbkej=&ljATjLYXcWgib=&uOst7uWkUWWZl=&JJdujCVbXgknb=&RSjLR4ZljreaU=&aptMcNUoipolk=&y4YKX8WfhUqm_=&5MIfCUZZesmjl=&Auje3tUibipmb=&akV8dSVUYddoj=&AYoF5cVpjdbdm=&yEwxFpVgla_rj=&MzqQZ2YqUW_rl=&OTN8yXUhgloYj=&jYvP5WWZYsZbj=&IHIBgoWgpfqds=&PiTClSZdrjoVr=&Pz3dfOWWdeqao=&5D3_6bU_daarY=&mtgdwiYgjqjZU=&OEjAayZphl_Ys=&uFBAC3YUYabkg=&rzwxb6Wmosmfj=&HnVzc_Uipbbko=&eSiwxwYWabkoX=&kDKO3KZdmleob=&_RRkktUZgkpem=&imevJ4WYhcWba=&MXsm7TXVXibXa=&NOiQQPZYqZhbd=&8o7mr3Wskoaho=&shDaQcVohddWf=&4cV6spYUXb_Ub=&OkU4_zWZVoidg=&dbbYDHZognXlc=&m7SMbgVhmneXi=&pADlV5XUjsYXW=&jtvnsHZlWdbq_=&yinutrY_VqWle=&UkDjJQUWZoZjd=&RyqPQQYjpbW_k=&BSFlMrZskbbnr=&mGYCZbWlqlp_e=&gEwcf6ZecgXhs=&MOTWgJUooanll=&WEW4ZaUVpssUr=&fqfAZbUosZaW_=&wIBwUMVmaogof=&ARxkIWVipsYoX=&yGll8uUrroXkr=&qrxapQZWrZdag=&RFSMbIZpehffh=&T4f8vHXamkpmb=&BbIwXVWgddgra=&Lq2KM2UeloksX=&WHEJSrWjXsdYr=&3_iEWdWqYj_Up=&LfZYZUUbUso_i=&62vOumYsZmsde=&apRazrYeoYspc=&x7eZozYkelZrj=&Oh5ApfUWUYYeg=&liCUMRUgdnhmo=&Q45CvdZeYmUhk=&hwHQUiVmnUfom=&wyjiYyYXhUkea=&GOWT2zUdnompZ=&KXLwOnZkZVj_s=&iKb5aDWVeYpYn=&9pYe29UkYhZWf=&Vn_3yWZafoqeh=&_vt3HeYkabhld=&_Fm2YtWckhcdk=&CzP7PfUXkmdds=&pYFHOYWgoskme=&NC84ieUogprnf=&7SKLulVo_iYjb=&tH7gI3VlWdgko=&fDIEdAUpZ_mVZ=&btZAiVYki_qof=&FYZrWIXrmZdWq=&4dqAkxYlhdUqr=&miKBa7ZV_dnVl=&XZnR5YZbYikYj=&ur4b2ZZjkmpZi=&ncS_HkVieVbrr=&GxzzLhWbZcXcf=&opTI93YWhYVdg=&nnJOO8ZgabWcb=&HPTLJIWbpXUbY=&wxvP9cVVjrpUl=&kq6TyXVslqXgn=&_8XBspWYbooXr=&LbFc4qYfesipl=&p_6DyQVrakrgj=&E6GUhEVcca_np=&4wzAT4Ubojmpo=&pStQl9WkqUclh=&XNIzJSZ_fZlh_=&cWIaZnZpjqqms=&gKqrz9Vhjghch=&QpPg4CY_fqap_=&8fDUmuVigfgs_=&A4EfkCZ_mVVpn=&2Et7qgYoUcsof=&7aJ9ZFXeiabqs=&KKNikgVplUZjd=&2tY3VXYUodcY_=&Al7rRpVgqglZs=&isnJqHVdrWmjg=&8cJAI9ZqrhnjU=&wgAxnwWlscnYZ=&sa9n8hUZhVUfq=&56LKC3Wmilscs=&IIzYCdVnamrkW=&ZJfJcUYpUZXos=&B25rTdUWlsaon=&t7uA2vZnsV_rW=&fO_SxvWqphjgd=&_mVWBhWprjf_Y=&9ttFk7XaijmfV=&6L2iQjZXUVjXm=&kodXxoZfVeppd=&Ec5DY7YpfelZi=&BlNXwsUqZWkbZ=&HvvxxfUqpihjo=&xQi34pVdsscos=&PH6TINXZheikV=&Ur6LJMUrgflff=&B3sOjjZfgihXe=&j4lf9jVka_nsg=&XXicj4ZkkmUqm=&DPYyHNWcqqqip=&8SLrQnXXqrYii=&ujacTYUUoZki_=&6mkVRNXsbWWUf=&FI8K6vUj_hlVX=&4tPwpLZbpVfrW=&Bs5gkJXninWdd=&bS7zomUgpjVnp=&C9clpOUkoWedU=&tCB5PrVUVgWVm=&M9YuS8Uqnirbn=&HJGLPhUqrVqhp=&GevW5QWZieYni=&_Q35uZVomrXUn=&MGrdIbZn_mmbV=&fSJioIZjnrkgp=&wP9pooVVlbflf=&ndcwrnWkdXiih=&GmUrM4WcUomro=&XacgzNXkdokVd=&aKkEZwXfWsWjX=&gOzZWLWYrVkUg=&o9JzMRVppgcnU=&JTlAvLVkqXonj=&Uyh_MHU_VZaeb=&YfgbpqXd_hfVh=&r7fkbxZ_gmifb=&nKFb6AVXhYnad=&r2FPjgY__UbZU=&QHmTQJXeUjgam=&n5he_4XmeoYXq=&PyYQqrYbblfXa=&BMh6grUfYchZk=&PnsaLgXhcelkr=&WA2jTQUbhgrsf=&QKWmuLYbZUZcn=&2pnflqUppZbph=&iw_ZoDWWfirqZ=&7mb7TcUYXhkXU=&C9DrbuZeoioZa=&StmxeyWfsYksW=&wyLD2YUonYed_=&FlnH7nVUrcoYk=&OJqJUxXjeclYn=&jp2MQpXqZbsgo=&9pY_M7ZWWjpqr=&STMUakWbalpl_=&iFdkRlVhhnWoh=&S6Q4OyVdnagfj=&GJcgvuXnjbkgj=&qwkwiAUWdsgao=&AijYmnXnh_rfs=&9igCPbXYZ_ajg=&ymHpcNZ_UaUsp=&qHp5QpVgdZYeh=&lZM88BUaqqedh=&K9ZE58XYqp_of=&VXWvwGZfYfkpi=&soH8uxWpsrhYr=&sgnxkWYXcgYlZ=&xuObmvZXdYUar=&GzBwspZVWY_fd=&Wj4k7QWgfkmjp=&mAkzhDYZo_sri=&r34NuwVnrVdfU=&MCJM8sW__jaYY=&cSDjQwVVmUd_Y=&PYpQhfWnajaYZ=&BJyo5kXdgiXjn=&U3bFmwYalU_qi=&Do2Y_6Zpjcj_g=&pRnbkEWmU_boW=&SvDCtuYUcrjge=&UsF2znW_YkXXr=&Tz6bxSXrnaqhk=&FqVbkVYUrqVgh=&hR7WF7XUaVeUW=&RWIqN4V_Wjoic=&vlQrdVYhdp_ba=&dASptsXefZsWX=&VX77U_YUcecYZ=&5jnsG2Zgq_rqY=&AXHM4lVjlgnYh=&idQ7LKYjsgZ_d=&Js5ey9ZUaikZe=&BcutL6Xbspcfn=&o2abjdUYZUsjn=&lHxuEpVVVpbi_=&DO7_JoWmpYagW=&Cmfy_HUgoj_lZ=&aFlgc3VYmsUca=&6VvtgGZiVUZdp=&ekTvZoYahbefZ=&tgAqL7XbbsVXe=&jo8eEiVYdlWfj=&4TvMlZXaVUoia=&_joWskWiqpfWg=&7M_52WZnfi_be=&Tewl9OVUsdnld=&3BOqB8XUjdWhi=&Eyxvr7Zlbdo_U=&8IGJCNZajqome=&BDTamJXgXgbln=&hpwBakXomqer_=&Gfry4HWgYhjYb=&hBg9_IUYdalmr=&f9yNYIUhgea_a=&87CsEmUgfei_X=&vaJx2rZrcmWWU=&n43SweYsoosbW=&RszyGKUXWblmm=&nzQyZUWcW_lgX=&X7OzB6XaqjXik=&MSC9C7ZdVcpXi=&zVCoSmVsalafi=&R2YINMUdnYWVb=&kJ4ChkUdmqVqY=&GfQCpNU_mkaYi=&tdBYa8WiljYZi=&shUvxnVrrndjd=&VCHMiyWYrhhkW=&XlrdeoVjca_he=&x3DqyEZXhVZYY=&aCjPBXWgmYYkf=&SRBZcRUo_Vkhn=&zI8if9Yqrpppc=&XX9iZVYXVqgmf=&lWfJ4oWdbesde=&rMHPK5Zhgo_qo=&oUNkBMYek_jnl=&vSiFH7Wfmolem=&nkQ467XsilYZZ=&wK6QBXUbgbmmg=&4ZUtk7V_o_cXY=&CQtgxiUhikX_h=&YKuscFZfUbYiV=&y_Dyn7ZqZdZgl=&VO5duRZYhfpkW=&c6ZrvHVcbosca=&sZdbRpVokUjXn=&kFmEqBWobbg_n=&ihm9vdUqbkcaV=&Eclam2XoXWXgW=&OVQHN5UmiahrY=&ePNnXEZWVp_is=&PlMMD6WcqVYaa=&uzu4ywUiqXibp=&prKNPzZkifcUi=&rkrZr4Uee_soc=&JHzSTlUeZZYYY=&NA4O3tYmZjYbV=&cqyaLxWlbjqqY=&OcFUfaYpmmrUr=&YlhukPZabninW=&7WGfnnYrXslVW=&BFg5b5Wc_nk_n=&yhMzNlXn_giqZ=&_BVmQHZmbWmpV=&Wn5aERYZfVkrb=&XancUVVmoVaUk=&R_IZRNUfXoWgl=&mxbYGRVm_bnYl=&PtsJTTWpVUrUp=&r4ulDDYmjlUk_=&DsYV2pXpkdZni=&DmMY_LXYWhhrX=&9qxVlFWgYisja=&eQxRApZkWYrcs=&E6MA4tYfefrXs=&eDNFSTVosklpg=&IRZTyjXlnXhnr=&nxWczWXdqYcWU=&YHkPn4VokUWjj=&HSqddxWdegbjc=&3Xv7KzXVqYgVd=&Q9YwIdWaYoliX=&H8CXlCVrsbfgb=&Gglg6AYXp_nii=&A2DAuyVjdpbWa=&cFa_PzWqYdZeU=&IXbfZIUfWpZWc=&IYbS5pXrmXZUV=&eJWgzpWfnpmen=&pFOTxPVggrebf=&HeHJj8UhXXpWa=&VgqNzFVsqlWbW=&DqzT_JYefpsds=&rW32Y6Zlgcs_U=&rB5QRyYffqegg=&9QXDLXWdVUXXV=&N24P9qZrUjdql=&XIZgZ7WonqWf_=&85ssMWWkVWsbe=&y_PqPuUbobc_b=&7iRtHFYi_hilh=&L3keneUsnZmra=&ZGWGPKXgorkpi=&ZwnPsDYaXaVpU=&RE6Us6Vieqknq=&6oTxOtUVshmch=&gLFua6Zfjenrn=&rypXR2UdqbiZZ=&Fz6jyJVcZjhbj=&ttnI2aVglfUe_=&hkRKTlUUfjjjr=&ByOfivXhWVeed=&WmNA5hZr_Uini=&7EguvLXorZdkr=&iWI7DKXYe_Ykj=&9phHFZZbaUjmd=&MMUgNcXdibYlY=&KVOYhWYkgpaVn=&pK6co8VkleUsW=&bICFpnUabiiUa=&uKFouvVdchkce=&LySxUkYkYkl_Y=&KJoYaVZkrharp=&uyTKYEZshqirl=&gQEZT9XZoidka=&AeGYefZfWcnje=&nkwDXaXdXW_aZ=&X76_GUWgasn_c=&KIylm5XbehjZp=&MvIembYUknpdg=&HIhooAWb_ihjk=&ZFGerjZkeWYbh=&37OpSeXpeaijf=&M7VQG6UekllgZ=&HGUVxFZrZkrdc=&stxyNFVobUjUk=&kqiOaSWZbpdin=&J9i4uIUfgknkZ=&6bsnu_WWaesUq=&xNTpEGUrqhero=&S4CTfeXlVqr_g=&HavHOiZgbjsno=&A_y3FnZpbW_dj=&L3cIT5UerfWcX=&7YTItGWVcnrkg=&t_HjlrUagjlfV=&ocECR4XoqimWg=&FGyzgpWqdflbW=&LIWONtWsdhaYm=&9fXYdgYYcqZsr=&aOrD5WYahnnc_=&Tn3S5SZV_qhXp=&BKwhlhY_snbiX=&cWI2EjYXscZXi=&Y3cPvkXchodim=&gaQ9EsYWZqW_g=&WcLFbPWpgmoec=&nOXye8Zblbpol=&hJuODSVYUUe_b=&S3yfpiXpnVYah=&eYvcItXUjWdZf=&bSi_oRXjpogdr=&mEnqdhVbgihml=&GftsoMY_dodUX=&TgFQxJYhkjVkm=&spM8q6XjUWjn_=&OSqqMpUlerlib=&IULL57WhdjsUa=&wTDp7jUmaoVhn=&Mhb8xGZskrpcm=&FdyOkBUfUfZr_=&RovxdSVnpsjoh=&nogH89YYWjoij=&eqsj96VqUYjbq=&VhqHtvUdpVela=&9lo575UUdmnbn=&OsvN3TZ_qcoji=&E4YNoFZaXYaYU=&norHAbWqsnoaY=&miqtAfX_fXWdd=&VYZDwXUpsqVZe=&pfTIx2UhiXcom=&jfAG3ZVslqfVU=&Iu5a7sWUZ__se=&MdChsVVqWXeUe=&WNmCfWXgXsjYq=&biGb_qXaioeZr=&rrwKgGYisggkV=&NsQIFCZqbZsUe=&yJ34qdWnlbjWY=&2rFk_PWgojVjo=&CNEggHXoWdaXc=&cqpCsSYYim_VV=&cSenCdYrs_khV=&mURR2iZsaqj_W=&SrjYkEWhma_iq=&g4iutlWprgkes=&PgYtpWWpWacUh=&ehXNKDYlWWm_q=&6H6_OAUpkVpb_=&ubycelXeleZgk=&XTKYEiVVnddhb=&enNkndX_WhnXX=&8CAot9XUbplmd=&mTeRYfYWmVpdV=&FXWCqVUeablVX=&yafjtFZdk__of=&Fc4tqZXiXslUU=&meMokNYeVVWZf=&qubaV5UolgjrY=&lS3DC2UbaUUXe=&mi_ICFYqmgqqU=&QZODNdUbadfph=&IPTxDoXXaksip=&drt2MYVlnadpg=&ihJUj8XVlZ_fe=&9EsD2zWWpVqcW=&N33rkTUjcVpXW=&TIVdLYXsU_dkV=&V7aP4bWWqhXmd=&QUMGOoWahVipW=&WhLnnnZgWmqYX=&awitd9Ublrnsh=&svVmGIVonVUoq=&hi6sG3YVjrlVs=&H_UkXQWgfpd_U=&ekQ7OQVeggkjV=&SKAcsWUafUqgi=&ofQhJtUaqroaq=&jBwjAXVpiqrYe=&4TSeZrYWZeqZV=&f7UBWRUaqgi_k=&I38ZMoVVYffXg=&v9U6b8XhbZmcr=&4pXuMPZfam_kZ=&PR7XNiUdroeml=&3tlvvwXpbkpUl=&fWMvfDZfdomYU=&AsGbRdYhWscab=&3iEADmVsZUenV=&ABrcaCUmqXfho=&6nGvY8U_Zin_j=&is2dFYVrn_jkW=&dWT_6nXYWV_ar=&9Se8keZaXfbUi=&8ArtmeWrpkcsc=&ZPdy_lZbfloZk=&wSe78YXbgkedV=&XeYuJXYX_agWb=&9DVpDIXpXfbdl=&6zZ4xSXdsdoqr=&kNRFLXWqWjnrn=&99TKnLZXphXWd=&xLDViEVhgcmmj=&Fk8YnKXlbUqdW=&Yrye4iUXqdWeX=&Zny3qJUoeYj_d=&GXuqGiWZaVcrp=&kYO3XRXVeZcmc=&s4a2SbUoflqcm=&ZAkKu6Wl_fWls=&ENQgfxZWqspmg=&C7lpOWYsXXlqY=&XQ4WAXXqbkrif=&iqKkXVZUjUisp=&tnLFp_ZWqmodk=&5C5zZGV_kbihY=&wGufgEXqgaWZo=&kcGeXhVicYqbZ=&4SuLuKUjVWZUW=&w2zvJHYWiYirf=&WUaXjPYnZcjdm=&6IAErnUZbkpVa=&Q5GZy7VVdjasg=&mOa2c7Zdifkeb=&E8rEJQYpWsWnq=&4vuGmbUlspojr=&B9Al_xU_ZWgla=&SQW4abYboWjmj=&lRSYGvWjnhisl=&ETZiMAWesiXjb=&OPJQ6OUohnqeo=&ryXTSCVrimYaU=&JeOvcOYdWfcWV=&86cYqOZVaYprb=&GRHOINZViamia=&bGcIzSYUrqrho=&NxqW8kYkmeWfV=&oHTcqfUeYZ_bk=&N_eZqYZdjmUjj=&DezLPtWmcqoio=&NCRa7xVlcXkih=&eFozAXVeYmZfl=&o2Aw6TVUbbnik=&eUqQupYj_jelh=&ihG_toXdinbWr=&N4LBIYZUqWehj=&ZvDvhxVnXqhbc=&QJeuWhZkZcimr=&yVhuf_Xkpkjrs=&_r5SQxV_radqW=&wnos6oZXrUioU=&5E4fb6UkaskYf=&oEbPj7VdlYjWs=&YIz2ETYqnppql=&8ydlDGXUndYbb=&mv6DGgWgjXmnp=&TVSq9BZ_qoYlY=&mMphFqUsksYfp=&IyctoqXnXioVk=&jcgCfnWkibrgY=&Nje_I6VrlqfYq=&Ctm7elXgZqXeo=&m4QsVaXc_Usnj=&ZdQlb2XlbiYsd=&HdtFXMVaVimcq=&5RsyWrUVfcnmU=&hnuhXkYjsgWpd=&6IUHtNVmZmmne=&9RRIvMViVogrX=&lgiscfWpheomV=&zmJ6qQYrodVrc=&IehEBXWgfcYli=&Xj5nOyYsdZaqo=&KGoETUVbbnYYe=&SRpE_yYglipdg=&snjXhIYcUnWXh=&zbX8uGZVraWrZ=&mud9rkXmbrUmm=&KRJ6gcUfWsjYe=&du6V5tYcsrZsl=&A8z9aTYnWaeVs=&3arwzxZoYg_jY=&DiwN8MUWkUkkW=&N4OOXdXfkeeZi=&Ew8QilW_qpbVc=&mEIrWfUsejeoW=&6vOClqXbXo_Vk=&J28RfuYsqllpd=&2bXbcbWdlbkdo=&AinoLeVY_UqUY=&2WXoPlVpe_fmm=&ssPeOkZiaqjjj=&3rWu4UZWrXdkb=&lhfm5jZXcogVk=&wnVmgCXpVne_n=&GyxsJGYZcnVlf=&LjNMSUWZjZfpV=&__VX2mVcghYiU=&6FWi5mXbslcbV=&oloMqdZcWWbgV=&FXYCTwVjjifms=&cOsrjFXkrVXqq=&25lVrEXkbffmX=&SOlMpiVoY_epZ=&nVtw7VYoraWoa=&ibH9GMWYelsgg=&FZXCWmZlsfWhe=&u6K5usWpclmZr=&U_Jt7yUfbVojp=&EN_NFxVbrnmXW=&ikk8jiUijrhok=&O2tCcbVYlkb_j=&5xvaG7ZrsmWWj=&Kf3dTqVejrdqg=&Eo7duFXYWemUY=&Cg3nNfZdidgra=&UREWMYVgjfZai=&T822RuZejbVlZ=&5lmHQCYrebbVh=&cn4ERSZW_j_YY=&7mrPIHZlp_fks=&3vh5sCYeUUink=&q2ShOUVcpU_V_=&oFQTQ9UWrfVok=&CqgL88WYlhWrf=&ksYdafYfsXdnn=&aZWKWoZjWWeoY=&WoxtS4Xorrkgb=&yKbdUjZmhYkmi=&DW_BWiXYq_ao_=&c_W_HzVboiUrs=&V46RVBYbfq_Yn=&6gT532Uprgobn=&NIsDSjZcUlqs_=&QFnbjmUmhp_gn=&N_pIgnZrq_n_b=&BpdOnhWgcYsrr=&FSwJZCYnogklq=&_U_evKVniqohd=&f45IeoZroolWi=&sJQGiqYhYgool=&F3DgkXWnahWrp=&KUMjGmZdWpjpp=&dtqFqTUjgpcda=&JYuUtoYWopgpl=&aa8ojSYnkhq_Z=&_tsANeXmdXifZ=&48hJ94WbiWZoi=&L9_uV2Vgjprge=&FP8NrUXbcjXoe=&aNlPlRZgYknUW=&FYgUXnVhhlebd=&nGQs5oXXigckU=&FPZI46ZmWesbe=&GGIw3nVoVWZor=&5EZNQXYnqgkch=&2yh8uNVaeVrYm=&tnPTS2WVb__cW=&6ec8DbVhbeUmi=&K4ptkuUherlhm=&RE6rOvWigrWqg=&4JUzVdYeenroU=&KeNRNmYbpVili=&k5KxuZZgUsXmV=&fNbu7GZhjUnhX=&koeYpYUnkeXi_=&pMAIWdXidlUbr=&_rwGUxYsXjopm=&G9ndbgUYjpafV=&E4N2ynVUYeqc_=&k3VlDPXafrpbk=&Xh4HfdZdUjei_=&JeFYMBYXldfhV=&iLlZaLYrglWnk=&tuC7QDVcYYVaZ=&rEA4AVWp__Ysh=&ewITc4UgXYWsW=&wW7OaZVaieYqj=&e_sXU4XaoZlZZ=&4WPFDMYUrkXjc=&VCFZWGYbmVYsW=&OIrfwAUfpUekn=&Jpx_bOV_fklcY=&BJhThOZnVihcW=&qkeTh4UgUYXZg=&ZCXMHKZloaYsY=&itY54HYZmmkoZ=&Em9jyDVeUffVn=&PP3ExxZomnkne=&9ymVlFX_l_ihV=&vx_RtpZioimqX=&Y5_JjTYmomarn=&uxmQZIXoqggrh=&j_CKFoUfcVV_m=&sFwIlUX__lasn=&CNt8BjYfVaXeV=&l7BCW3UnlYddh=&NogCItXYnnUYg=&BC_GnIYpdrsgW=&7Hg7AfUWkqiji=&tYVEsqXmWbbXb=&PlheLOZcaqfdm=&Vip7VVVYrXqUa=&fW5X9HUo__srV=&I9DPi7Z_hYZcc=&hkHMttUhlsqhs=&tIGLQsZkqfkYj=&HXGszHVVc_sXe=&oIfNnkVkbfXga=&CEsvgqVkqWrXj=&4rxOySUZjoh_j=&94SVTCYokhbXp=<noCHWpkq_oW=&zooF4mUjmflab=&lxpubNWVjknZc=&xH37DYVZVYUdY=&5GYR9HUcc_kob=&cdPkMcZnrfebq=&wQRJCNXmecZYi=&pLtRKdW_qopeh=&8heIcLYjeojpX=&AKfMrtUipe_aX=&VlO7iOZjolnjg=&rDpazyUiVfba_=&nm9EdrYbkbehV=&XdULayWsirW_b=&HOIQERVrqsWnk=&RsYneoXeXkXnp=&ifWyqsXmaoZrV=&PcRsSiVXkZqrV=&IjfV2mZZslUZd=&lGu8DjVUk_Vni=&2wIkSuWnUiksV=&O7odsgZogffXq=&BgX3VIYlie_qn=&fhU3DMYiVpZeX=&_it9O5ZYipjdo=&xpDarEWhqgnkf=&wakLT4WjkdlpU=&kP3SZFVlYdZeW=&pY5G5HVhhZhrV=&C_ocRJYrcg_ii=&8bJzbFUedWWmq=&DknRtsZnpaljg=&QoBuXuWljdXlk=&aDN8bmXXXkdjk=&YxqukMXflghnn=&kwNuoMUZirisc=&teblV9XginanY=&ohHqNgXViVVfp=&GdpWCYWsbdnim=&GWLr7qVplenfU=&gArdKoXdmbYgY=&De4pOgXnibfsk=&_nDlCzUfbmlWo=&u8c_N_ZnaXril=&yrK6kkUkeVifb=&PljbzGWWsphrb=&kSKluaYZ_sYbm=&5LFvwzWYsdZUr=&fgXUpzZXieXdh=&q845X3VrqZsp_=&SfsfIlUhorlVc=&DzApU3VWi_qmp=&suT8_JYXZmWoU=&2_mnYRZrZrhZc=&4gsTxSUajhmms=&SK2axFXcnlUnq=&mDhf5KVc_remm=&ChcP3GUZXlXno=&67EdFGYkkeWgW=&_FvEwpVqYls_c=&DEv6mxWXonkje=&YOo7AIVZmbhWh=&QOAXGWXqVoeeq=&Bc3KYPZejWqUf=&EtYlL2YgbpWoV=&QVUOQ4YicsXqU=&Js55FwZppXhdn=&q9dxhJYcinm_Y=&D2BbVMUZdbcpo=&hopSpHZlprenY=&xhYQA6VcseVWW=&IZfYwpWcjhhoh=&JJvomhXopbeZl=&e88qADWWZUs_p=&8rLZpQWWcanqd=&NTz82TVV_Umjs=&SiKodSVWoXUUm=&5vnXdZWgbchbf=&5JAmPjUabnffm=&bnqc8hVsledhb=&kIjFa5YUmZmos=&NW4W7AZZh_ZkX=&ftLmMhVeqWjap=&4OtqALVZprVkX=&QBZgVkWhWfolj=&TPAM8rZoeanZY=&sCdwuCUXphbae=&r4FeCcUVUj_Ug=&vAWZqEYsfZbck=&LVHEZTWfYZsph=&sMwAjNUejbslc=&sd3SW2UlqceoY=&94USr_YjXjgea=&UBSKSOXadffgg=&BGzqXaUehdVWl=&aNatHjVdfsaWm=&ETQbH3UWhebVX=&3_rqXMUiUYlek=&Nydy6uZhomXYf=&lzNSvzZeqreld=&J8xAH5Urbbcqi=&2px5fyVkcpgWZ=&DWlNIfYisfg_g=&zX_bQUVlrbYgs=&IOKsDYWqodqgb=&Vd7L8IZfroYge=&BhUW5vZmnoWll=&guPsyMXllanoi=&q9fZ9VXgUpgZp=&98TcvaYsqVqWX=&4sbJlQYb_g_Vn=&JeD2WnWniqXgh=&DbHebkUfkifbi=&66mnkfUqpn_iZ=&kFmg8QZZjZjWe=&_4mpyWZbeffre=&5GCE_PZVaWd_l=&kLiw9RYiiksjk=&akahtrUmUqlrc=&k2eEkQZrmijsd=&yI_lKtZ__mlqX=&9PxszdWlj_nm_=&rRRaPUUcZdebc=&W5UrE4YbbplWf=&ZtnjchYWosgfV=&8h5breZmrailo=&qGO4QOY_lZjqn=&5mwgV_VhjcWYX=&Kq_zquYlgrYbf=&tqUMvUXViqsij=&8ioeJ4XUccUbU=&T4SN6PWnckslg=&KLjpmjUXYZqVg=&YiPZtoUijnfUV=&koV2ejWngcmns=&L6AdBgZiaaebX=&efpcPiUhqjejX=&MJUgrtZYrWrmj=&RqWpvEZspeYdZ=&uq8iu7Wpsqiof=&HmYRdOWcYcYll=&Fkl9gnYbslmmU=&5vfEYwYccdkbZ=&4XrJCrXlcbZom=&qDjvwbWnrjoUY=&flQvhOWlfksna=&ucEuouVfn_Whp=&t8_iLDYspp_Wr=&oXOM3_V_fkYbd=&ZKVD7kWkhcjdV=&k4BbdRWbeeieX=&M4vZ5EViVVsla=&6dwCcnWUVlXfa=&ofSbQiZXjjggV=&rlbWpAZcnU_Va=&fo8wupUjsUYlg=&OJjESpYpgjWZj=&xF4xEzXdbimho=&ZbmYokYrdUa_r=&3rFi2qUqYomee=&67GVrFUcdZfpl=&JAqraLWWUrZUU=&LUja22YsWbnbs=&MfDKp_Wcgkhpa=&klTlZGZYiYqWU=&aHlX95YopgYsp=&ZrAxDoYUrW_oe=&dxpIpPYflnXWU=&bps4cgWgqccbn=&Wy6BzGVcWmaYp=&uUXzA5WgacYgp=&W4YwldXmerpWV=&dfoewpVdbkVeq=&DuGZz8WVVWfka=&Enh5ONXndWVoq=&yrmZJaZlqsrXq=&TUNMmFXZfrcUs=&pNkbh9ZVnWoqg=&bmcxqXYrlq_jj=&ItAAmMUjnbirW=&4yBXk4VhYWoba=&e97FapXUhbaVX=&yBZKjeYWd_WiZ=&IlisxSWqeffXo=&YrLPjFUmlmXnb=&iGPdpWXjpceZm=&G7pRhhVWgYseq=&2qiyFQYdUVgVo=&Dm4EzsXqbbsob=&hc7ukCZkomWWZ=&vmS2s8VfYamff=&dwxUUKWgiaanU=&gUEUb3XWcZiZp=&RRFOg3Wgsodja=&v39gUuVYVXekp=&wNlv8BYolssiX=&yrUw6iXr_id_g=&BY4CRmXmgaZiY=&buAZpKZVZrmai=&hDpTZbXd_VZnY=&ybbBzmVcfmqUn=&2tCcM6YUsVcno=&NChwHMUodnVVg=&nid_svYaZkqql=&JQwpxWWnViYhr=&lBzw4mVonrrVg=&xG7GEjZmmfmUr=&GXnkakVnajlqX=&C5oWHdYkijnla=&MdmUyzYqVbeha=&IQerbTUYkrXpd=&eZj3zOUVn_erl=&rHAIvaVcsq_p_=&pK7HEMVilqVUe=&BvORqhYjccYhh=&xWwOIAUpWl_ic=&IdT6W2Xkeer_r=&6A3X7gVcUiUio=&gudNF6VffVUUb=&sPurXPZUsiZmp=&PLvs_UZfeiplU=&UMqvWkZospkcU=&eOVpSHUrXgbZW=&4YmWsFVcdjrkh=&vzQDRIUhjmfg_=&yiHzVhXZdkWWW=&AoHIXlXVXdkc_=&9cYt52VgYgnmZ=&fkRri2Yridad_=&wuZU2YYeYamqr=&nGTLUPZhYgnpd=&kguALrXcVhYXd=&EYKXelYkXsfjs=&UeIlkxWYVrhhX=&GlV9aNZpVpWW_=&FyhxN8UcqZVjr=&74xzsoZlWYiss=&DA9TKSUfaaiUW=&EfoNs6YmkjbXf=&gMeghTVWbgrUW=&b3YM7bUkhjpas=&hZUhAYXqhjodg=&4OObLFZedjgmY=&x5AeopWgb_sWm=&DbrzC9Y_ZlXaW=&53YDKJXsWVekb=&WfxplaUkZchdq=&CVeTBeXfXcUUX=&3UNLG2W_ZXogc=&_sIbAhZYbfZja=&AdDTejZZeapec=&WhS42kVqbhqod=&mckyJ_VVfVbrs=&AyvCQmYfs_ham=&V3qmwMVaigean=&u_GwQ6VdsWfrW=&L2q9BQVglYpsX=&4lqGtrVZVfUpU=&JL8GIQZfnaldj=&IPvMKfWakjpfr=&JInslvWkeUcnW=&NbKlkAVUVgfsb=&587Ou7VgrcefZ=&yo6zcfVXZVXnk=&QeNnJ9UYWjnci=&jJhTqCWobmpYd=&e4DUDOUarcddb=&oF6GEtUihdZho=&kvdWpaZnlqUdq=&vmqfwjXXqccYa=&nwkPBuWdZghcp=&_xcjmqYrZkXYi=&t56pIrVlXsjgl=&FrKrO8Vfbhfek=&zMpANsYZfebmn=&nIbxqKXmehhXm=&84bLsbVWZpcgj=&YZd5TwWihf_dd=&oWqZnKZZlsgYa=&_RjyTcYellgVf=&Bav4v3Ul_qVX_=&BsOzHmWrWUojo=&Re7FPMZWnWWck=&Dm5insXslpZYZ=&A77WibZWfh_js=&5BSaBlWq_X_dW=&C7BOsRZbgsVrj=&be5XknZ_ejUVn=&hEmMEvUmedojZ=&QKsr8OYjd_Ukl=&lmMllqXaqYqih=&RkA8sUY_irren=&Ziy9siYZhd_nk=&XjLLtIUjmX_WY=&YatNrwXpeYrid=&nq5UIyXZUs_iW=&zAUD4dVUenjZX=&rnaWcaUriZdoc=&SgMwxBXpeZYWm=&bZiugFZYlVf__=&TGvlxnXVcXjln=&jkLbZjUWob_ri=&VSD2cVXfWmobo=&JT9OCmXqaUsWU=&wrOS7FUjjZlhi=&crh_X9Ygbnjpa=&LPio_OWladZ_q=&_WDe5QZrq_dXi=&rAXna6WYgY_ir=&YIMQ5yYZarkha=&jqNTDtXcnsnjc=&RNZ33IYecgeqa=&pdTtPVXcgemYi=&NzLMmzZmjsnjl=&8VzduwXZoppri=&QqFwr2VrlbrlW=&ZpfbDHUqmnpqn=&nns2RQUdXhkmY=&6RUZVXVYkqpUk=&pROneiUWqYZUd=&g94TleZsoa_iZ=&QZrcY7ZVWjr_n=&ghnbOhVdlpdrh=&65f6DfVeqXaXX=&mTprx4VZqokaW=&kGH8HBZrfibf_=&urzQGCYYiaced=&HiVZlkXgegidj=&BbKdb4Wc_cbfY=&LbDzhBUfWqlpo=&G5wbYjXsXqeob=&YFEvqWVilelpn=&joQSYXUqYdqXn=&tAeRokUgfXbpb=&5AHeRtXaU_qah=&CyGbpJUampVmk=&E_oxYuWsirjma=&IxjpleZidsrdX=&AGJh6fVUikrhe=&F_gtcNUqcYcoi=&sDhNDHUjgZbql=&fBmtnSVkjZXcr=&JF85I_YUZnfsf=&8xMMR8Wophfdn=&_bDXEyXqakeUX=&kw7EpMXWreYpZ=&_ZtMVQYqYoYom=&3FoE2tXoqiXrn=&3goaRBYWibfVW=&U525lPVq_rkim=&4dcwAfZrUZgng=&N_GldUWk_fina=&r9VbzlYaWjddZ=&92_ALhXghiarr=&ponRsIXbsoqem=&KOGZL3XbjYjpW=&AFHKVhXepkqkV=&gyskEtVXVZbVm=&AXqAouUiUgYpd=&fBHWRNXoccqnU=&YbZh7eWjsspWY=&OhrRwIYrrXVq_=&SvOGE9UparVon=&DO7fOQUoelkZf=&WbnAJBUsjmUpl=&9CRLkEWhoWWqk=&4PIDEtWsmgrei=&ZlEf5_ZVdXffg=&5ylkfjYUZegab=&jtoI75UXnXcci=&tI4pExXple_jZ=&aG3SayZmqhnrf=&RaclVAXcXscZZ=&DpdWIuZlshqid=&hoEtbqZkdnlZh=&Kq7wbaYbZdlpV=&lbhotiUacdfl_=&3xgwyHYjgonV_=&je4zRdVfhpYam=&_2Rx7vY_pgmln=&AulyBMYrqcjah=&r7HXQtZfndefU=&e3kTigVVriaaf=&y5qpKOWWijkap=&RLFtljZmrUZrn=&bv8L4AVsrkjhc=&Qv2stTXhaUWWd=&6qpCAHZnorZVb=&FQzFndUlfaUsW=&qDzZ3nWdVXaZp=&VD_hm7XfqWZVk=&N87aErXdejcdm=&6GlZoHZnlklha=&nOx5arUpdngcj=&9NzLLxVUcoUjm=&zhO2BMYd_fVdV=&ien4GPXpqUjof=&vBAnwBWZsZqpg=&FpMDmWZhYf_ef=&8Ye8j2ZdqZkmk=&gXFScNVhiqshr=&WPnFlQZmasZ_Z=&E9olgcVrsZkVU=&Ut2q9oUspjqeZ=&H33Sr9VVd_ssg=&aNjTIkXVV_nXd=&X3lkNYUgXqppj=&huh_fQVkWeofc=&IqwL__UialZso=&Q6zMEaYofUnkp=&QNkzhHYeokijo=&MGhXToXsdiajh=&CCSeqMZZcgVaW=&Bp4_gPYknqnfi=&GgEGOgUnomhcf=&ODb75uWibWiWY=&t3TEuiZjWVblW=&lOJ5S4U_ZUXZp=&zwHWiOYWcjqpp=&dHBb2nUXXpsik=&GsVAgzUZsfjfX=&BX9jFJYWacnXo=&4q8PdOZbbrrYY=&PD3Q4JUnholZp=&TaHPwDYfdmpdf=&2lQaaGVkieV_d=&WKFsrMXrjgjad=&KUWFV3WdkodVs=&TzuxEaZVVrZVs=&uqrcHPWcdXkei=&unZQUXYhsbkYY=&533rRLUmXWhpp=&IXI6CtVgfoaWW=&wztaTSYhXYaWo=&VfHHyKWkkhrUp=&e9SwvRWoljmVm=&cLt2myYcY_Zbe=&Tqh_NfW_sanlZ=&rcdfILZWbmgWh=&pu8l2vWd_orce=&QIOjZeYldYqVe=&YsCYkyWcXogcW=&o22giEXhhblco=&CPYLNfUnmXppV=&wDT4yZYYskXai=&IEPEzSZWrmhnb=&dPXUmLUW_eejo=&xblZEZYcdehdn=&LzITUwVZfnU_k=&EPlvwGUVqVWgU=&rmYfyaXsmlcXY=&7xv6TbWVjfbmo=&tehz2jYZ_dYdf=&CHhZamW_ggqYm=&hhRjWsYeZdoqf=&2szvYSYrq_ker=&__YUOqUUbYnno=&sMgSAQXkahesX=&fBY2YhWrkrshU=&G6aG6RVlWaVpe=&Ct8tjRUVninda=&YIQGP5UZXiUoU=&RlUXKcUpnVoWZ=&35R7OCXUgaXVj=&2vimg9YYUhmga=&lZaFw_YVpoYsk=&jmJWPxXecZcUh=&QejR49ZnbUlbX=&_MxQs2ZVknage=&uHQDPAYjfgkaY=&yPMuIzWacXqbZ=&efsUYhYfXkclU=&OntT9eVfXggVs=&7oVS_LZldneXk=&Bcy8CAVpfmZfe=&pckycQXUfXcla=&xCqJGFZingomc=&kfOaOmWqWnebs=&hNlUevVdXUfnm=&Vr5ZTHXdljeoc=&ogoNXSXaWheUV=&52M4_8Xrlmhdn=&uV83xWVVkiigq=&PHX2TZUbUXhrl=&M6Re2rZmoleef=&anCw8iWrViaXq=&k28XudXkohlXh=&DuPj4iWmcbUqk=&oJLtTtWoshnqm=&PNGePKWfgo_pY=&2DUEnUXg_ggsf=&g4AQWTXhlkdVU=&WvepOmXXhokge=&nnPYm4VmloXam=&TBqZLPWeZsqoZ=&24dn9MVefWbXp=&K7_Xa8Zlhfjhd=&XbR_EgXqrWdiV=&TfAfnZUlbkk_q=&EgIUxbXVrXlZd=&uIs9HNUXV_faa=&5X7Mo_Weem_e_=&w2wJrbYYoX_eg=&mx4TtpXZlmlkc=&_uPxEMWmgrWeo=&5GmkHDWheonZm=&kdIiLcVdlassm=&tdHvydXWZojjW=&3tpMGyYpdbrUb=&9KZx2OXUVapgf=&kjrmqmYlZkVsq=&iHz_gdUWcreip=&aMYQcbYoYUpZY=&FTLStWZpbgdbk=&U3FYxLZefqhlY=&bzrak6UhaWdar=&MbgnipYslphre=&xWUDIQYhsZpoe=&Ad_rX4UpVqWoZ=&FcOeoIWVXoZps=&VOjBYCYlrmenl=&veHmQoYspjlaU=&rBebMeXr_eY_e=&bgC7NUVgjaflh=&uscd2aZYdcpWm=&uWGZtKWXZVYYc=&vXSi4vXojf_rZ=&lcOVuZYhgWUbi=&h5jw3hWUemgnV=&pgncjYWZknmkY=&RU7utLZsomoZU=&YlUAj7Wcjjslk=&JUXJUDXeoXeja=&52ikP7Ujbkpao=&zTcLd5ZdYhmic=&AA7_2_UqXl_qq=&ei62r7UhkpihV=&FOLeWcUfcldfd=&LLDXiAZVrWX_n=&TsilCCYpqklUV=&c9qlrQZqphoU_=&nV9kM_Vnmsedc=&xOErYSWfoshps=&lhSKOSXsqZarg=&tZFjX2Yghmpde=&7eQA7PZanZgYV=&ZZq_uQVaVUd_i=&3bz5SOXeajUno=&5EEctnYkbXq_X=&OvVRxCXgqk_Wi=&M9VrXGXrgdr_U=&AopurJUfXa_ss=&aB5Vr9WZYpZUX=&TJTTnMVqnVmkp=&W2zy7vZdWrVnp=&nzGUgPZjaZcdg=&ZTrtC5ZiUohjs=&N3v6KQUpVfn_a=&wy2EVdUYqccaq=&Lxqo2XZbkrYss=&CYNNDoWffZasp=&7SOrCuZ_YoVhX=&mMyzDTXdUUrhm=&OYtH8fWmblXXf=&x6kZEdXkb_Vpp=&DpgxWrU_WXbid=&VJGVPhWrVWsom=&NKPtVsVXcf_om=&EHw7K4Umqcp__=&IoipSCVbiqWrf=&Xm_hkyUXWep_f=&LBd88gVXgUWs_=&2onuqzVkYoWmh=&SmQDulXZjeVej=&57NpP5XfdhWdb=&ZEqxltZZnpWZY=&MEVIkbXUWVbaW=&rtUguKVXhjilk=&cLEOmOXUrljjf=&4yrcbOZjdZaoq=&vEqYkoUoZjhWn=&vbEu5UUUWck_V=&_5SQMZZYcpgoo=&u5yY66XirfVir=&_GhnCpWaraVZr=&SL7JNQWodVjir=&mSY377ZmrblgX=&qy7YDKUrqgesl=&k_Ve7eU__dqmV=&IQ9QRPYoagnlr=&UGRZdHXr_fVps=&IDUingXZdZZgg=&OVaoHeXXWrZYf=&vcMOtWV_rijln=&Ke6lVZZeghjWg=&Q2hzRZYicgpib=&cKuaqsXWikWga=&TuSU_PZngpfdi=&TbcdgiVnhqfhn=&Ka3QIXUfYfqWa=&n7zkBfZUaXVoc=&MK9WTmXpkdoUf=&GUx67BZlWpZdf=&rm8CU2Vhnledl=&JADhaBUrrnrpm=&olSe5RWkjXWqb=&abbrMwYZnZoob=&UpksaAXjkbXhV=&GMNkeJVpogeXg=&LE3BsUVXdqVb_=&Ob6VIkZclkooW=&wD9lufWlrkgYk=&65y4AJV_cnmos=&wgmW2UUWnkfhX=&glzukaXamkcoc=&U43roLWeXghpZ=&x3fomOUacdinr=&BzRTUfVWiejVn=&_kAwlYUcqZjdZ=&VnKODNVnlqWag=&NkxTr3VapXkc_=&Ael9VgWYlYkUU=&x_SkQ3ZoWVrZW=&5hzIZDUVdnrgf=&yJnYrfWlmgio_=&fYwn7UWsnYscY=&qRW2xcZbUhZXZ=&tY9GWgUVsmWef=&6fzc3FUdh_njh=&KtONEBVljkmgp=&NqTSvKYgaUYYs=&jJjRCeUpUejkp=&hP6OSPZqjkcdq=&uhlqXRYUondnq=&4LnA7WYhjWXjs=&qkRwaXVVkn_rf=&mSTggcYUpWXqk=&qe4QKNYaZsmXZ=&HX6tncUjekUjm=&ngLfupWedcmjr=&vtl6RfUrshnYs=&7hSSXMXoVbnla=&V2_2hjYpgqbdn=&9lUv3gUhWXrqU=&LzVhNHXdfllke=&GVvYYvZcbcVgd=&8P_2klWcgYihc=&RMsxyYWi_XXlY=&o9eqyNWUefWr_=&8anbzYWaWilrX=&2a8gaaYgriqfr=&zQ_3BkUpslcih=&y8X9uOUZrccrY=&PYrjyWXphfehr=&77kJ3bXpfUcWc=&EZhAdyVg_aiel=&xpuhywUXgrarb=&L5G7ugUer_mbW=&4NuaN6VlVgqec=&hW_wbTX_YUrnr=&UDtR_xUpckfnk=&mPzcQ3YYhUsWY=&4OTVzGXWmfgZo=&UItnjnYoYri_q=&4sKeS3UpWrapX=&5BFSdpVUYjgZc=>WsCtUqUcoWf=&RbHtJSVqrjer_=&sLOjcmXienrmm=&XKLmVuUeYUjjY=&vLzBH_WYXaXXZ=&FoGbdFUmgffeV=&CUwHH7YeeemWb=&28T7kLWXUha_V=&EoQZI6ZVfVVXh=&9R4zVtXfnkijc=&NsUjEOUfaWjfa=&nMIU97UkjfegW=&CradOwUfig_nr=&YyP5GYYhXjVfb=&3_oFyzWgkbmkc=&5ZOYrgU_dcgnn=&HApAQyXWcrUej=&5IqTjeUX_Uhqn=&ZEiRUMZcqceYU=&xgyuQgVW_Ykal=&ndDHIKVpiaZcq=&KbFs_HViUW_he=&4Lw35eWkUiWkZ=&6xrEA8WUaiifi=&XMR_FUUn_XWio=&B7LKMYZqj_cdg=&aNbCxPVYfdUXd=&2KmwMYVjem_ms=&4AVu7gZdXVpVd=&6m68i7VaYqXiU=&yTr8riZpincis=&6WUqAxVejdljU=&t7MxCPWkZfkgq=&Nrdba7Wmiheac=&bjdKNwUmrigYs=&pDmhx9ZlgVlpo=&at92ncVZmfbnd=&2cu7YdXWYVoej=&sF8NMNVkXkXYm=&A6bww4Ubpdnpd=&5Ye29YVVVhmfV=&oPoWH8UXrYrjU=&n2R7fgXr_oWZq=&trAXChWkisejW=&6kcCpUWZhlm_m=&PRZR48WUfZbem=&ZNa4Y8VjW_qgr=&WqynxaUrXfYVZ=&roHONbUcnUVUf=&5JayRfW_mYc_k=&sIFRpRVsfXgag=&Peay6iWdhlhkn=&339kCdZhcX_ar=&tchJeIWmp_kqZ=&y_AA3qZUqlh_k=&kXlS4mZflWYlq=&YuacyqWpYnipe=&d5iCbCUioVeVr=&aNHFLdYZhpd_a=&3kynetVUbaqil=&7nIWylYcXcfhi=&nHMmncWebrgll=&Y_MKnGZneVVkq=<Me97UXfsfeg=&LUEEkAUmrepVj=&ThpBUjZ_UWhk_=&BERqwmWrmpjek=&kan6kqYbVXioo=&O7tfTlVepnms_=&MDPcbbWh_kjlc=&DsSNnzZbWkZ_q=&pWoeTdXdWbkZm=&9GC2RYVfelXfc=&XiFN5gU_gknrW=&qfTRmMYrqVWk_=&xUCuy7W_YohYV=&WLWtL9ZZeoUao=&t8LzItZbZoqeh=&UGgFXLYqUsk_i=&NoYSq9VcYsmh_=&sWNjAcXihcfVX=&q4QBCxWUjmnWm=&_vwFb4YcmhXji=&LxhOqDWeclikY=&VkTb3KZiUbrVU=&dFojrxZfcnaVi=&lRkDBYVcab_hg=&keT6M2YYZegZY=&qu5DZJUpqfhqV=&zihN7VVklfjgZ=&rDQN_tYiYeZYY=&lsPHIjVZlcYWs=&bX6gJiXgVseZa=&WiErckYiriYYh=&UqukDCWgegdmf=&_IID7cXksUZgm=&q96LqJWZr_ZsZ=&M8GfgAXkbrqeU=&ZhbJhVZcdXrZc=&KKkbjsYbYqrV_=&N3gDATUfqdmhn=&Z953HYYkngsgg=&byDhl5ZYWoafZ=&RlgvjRUYrZn_h=&s8yaiAY_ieYpX=&aHWVFiWamXggX=&KmsUjcZdgfcli=&r3SBIQXaejfrl=&3pAbqtZcgrreb=&Vus8iOUWajqZX=&_tWQVYUZcaaq_=&jOBCUnWfihY_m=&hVBGwBWfbqlgq=&lmVuP8Zrbcgk_=&plxT9YUokYgUh=&X2mK_qWeWo_Ze=&kDs_WbWVcVYbe=&hqIDUGZipcXke=&oILVbuXfcrlce=&rdyDWHXjkUZak=&vlSns9X_fspcX=&Fj6Q2OXefaqWd=&dJyr6FWsmbZpp=&TGlLbwU_jkboZ=&S_AzRQUa_ZYfr=&mgS_qbZYZX_p_=&86kmBlXikXbrr=&pnxWSYZmfUahf=&PrWrRGZnaXmnX=&C_6asEYnspdop=&yzQn55UnbWmha=&853teTZfUWsVX=&85Xz2eWhXeskb=&nmarGPVckesdk=&7EhvBtUkaXaUi=&hhLqqbWnhroqs=&MOklWZWgfVimd=&JxwE4lVcbbicU=&A8c4MdZrsZnWa=&ykrFqlWf_Zejj=&sQsTcYXlhhc__=&ZszBEtWlmlaYV=&nqgYDpVcerXjg=&u4AgiDXm_Yhhi=&BU9ErMWgooeVU=&dSmRJpZsgaYkY=&PalzKzZqlhqlV=&XHsFCXWb_Yhbq=&h__WLxZadebje=&fr7JI8Xmqgnkp=&55qeedXaarnUn=&AZutsZXcsYsWn=&_BqYsRYUZfjXZ=&2QUsPvWYWjdcq=&LF6jJvXXWqkcf=&xkP7ccVdbWiao=&CC7xy_VaUobos=&AvLXyLXYaWdkl=&gZKJdvUkXmgbd=&sKtnuTZicdkVf=&HpA9H7ZlZkenU=&2qxqHyWZUln_n=&Eu2vyTUsYXejk=&Vzydh3VgfWibo=&rvANQgUkXlsVn=&wzclXdUhcYodp=&5BPbaMYqifXhj=&KTNmKZUepoUhs=&d3IlOYXjfheaf=&i3aoUGUeqdjgd=&xSRc33ZglhZcX=&ftDYNPZpebnmq=&TeXJatWcVnfdr=&ECDsqWWdUUbrj=&YhEE2vYmcjpWo=&GDsqwsVk_ksqp=&b9o4Q6YUWcZhq=&tfLqh6WfiVpbm=&KhqZeoXaqVXkk=&gjQ_krXbUdqga=&RGajYOZf_ir_q=&_KbWXeZajYhcY=&fSXlyVUdsjVpX=&bdPdQiZYrkYnU=&aQrGJWXsninaU=&FqHGUhZjkVVso=&oabCYhYVjsgXs=&ILXmiLXarUVYd=&PbJuKMYoZhaqm=&KNtsOzZhjkWWV=&ohE8T6UoaYbnf=&RWczFZXlhcdaV=&pIS3U8WUWdisk=&QUVVVUWYmhWsV=&SxmiyHUXrgkne=&Q9ykNTYdfXbla=&tOXWxzUrUiVbs=&bRgz5tYmdag_e=&L7sfisX_rgqjW=&Qt7vzkZrggchj=&SFOIcUYlUd_ok=&k3axIHZnoXacW=&JcyiwEWXofprk=&9dfGhAZXUdiVY=&3yblPYUqreprd=&sc5jaFUnjllqd=&PThLIFUcbiobg=&TkazcAXskjZ_g=&DPF9FAZZ_XXeZ=&EKcTXTWeYmkhl=&A93LMOXgUWbnj=&GKBLnJXpYksXs=&U7JcbbYjaXUW_=&GPHM3PYfcgeeV=&jH2XzaYYXcZlb=&yADWw5UmqYmoU=&dcv9x2Y_ZgWhZ=&FAW_yfYhabZmm=&lGp7k9VmallWW=&ifbqqbYbgYsdc=&JaMgcdYobpgbk=&jC9GbyVeckWZr=&s4aw7CUhdsrYf=&sJDMPjUeallcf=&Tq4Dl7ZllorbW=&tUoLasVbXbmfY=&g_aC_oWsiibXV=&PgcauyZpapYXW=&VFDRmoXYpeg_h=&rSaEN3YqXegpr=&XZ8mMBZmccdbW=&NidRDAYYYiqkj=&fLmoF_Ugpihig=&cQw_92UVlndai=&oyVQRIVmdaofa=&DYmvYcUdnlZcX=&iusPojYlZecaZ=&5NT5ruUrZdnjZ=&EkQXFdUjgWpqk=&TGMdnFUhprhYb=&LJ9SgdVXjdVeZ=&x25bWZVb_ngXp=&zuTFZuWUWlWki=&R4_8ZzWlYrie_=&7YPF5uWXXrjVY=&QKdS2sZeapVck=&P7i9x3UUolXsd=&B7qlYDXmqUVg_=&G2xzAYVWohpdm=&yAxDqGZqgWabl=&E8PeouVU_agqs=&CmuZ6AWlbgfW_=&TuTvyiYdaloXl=&XfM7rfUfVfdhk=&2D9JzwWccVrgn=&Sd7_9SUpVlbVr=&wtxdNbVhUZqmj=&SDVOpHYmageeV=&Ur5BjEZUYihsU=&bPOSwSVpdUkbj=&hfUI_oXeblgZf=&JXvn9hWZbUnof=&99exJ8Urbrigf=&vDuD9ZVqfpVah=&uXJJEnYfqlcep=&ujHNUeUidarjn=&XSke8vWYVhblk=&kzv5nHVlbgc_Y=&aqLiThYUhaeXc=&l5Vz3uZkjsWgs=&_mBfbPUgefUog=&2bexkeUese_Uo=&U4m5cDUqo_akX=&liCQjvWgcfrqc=&4YiSkMVYrhkWp=&pL2W6LYobakgb=&pb5YWrUladmnf=&braTP4Uek_Xbo=&vwdlD3UZcncih=&xmf2JWWmVjqab=&5tQN8GUrnflbp=&alRlFDVildn_Y=&GGKOVWWZ_YVek=&I62HbKZsaUapb=&aBxIsMUqdZZqo=&3qbpbwUWjlicY=&LtyyqHZXZmria=&MmBMJ6UsVp_mW=&ieMuhTVYhihms=&5tWhkrYaqWVYb=&Fh_SkuWqecZXp=&shu8L7XipsYbZ=&VdRa2tWXdlaqr=&MVDgqWYesY_YX=&_9Ci9iYWeid_g=&7F5tGaWbgqqsY=&46fc5zXmeshqj=&tw6NOCWUkpbXb=&T_TwWzWWcenkj=&QuSZYkXhUggoa=&cTimrNVgfZhW_=&AwZYHNUbdfeqp=&O7aLK8WaUiXUU=&ZgekGvZWpn_Yq=&cdkP4BUigUYkb=&kw58FhWmfldcf=&VUNOjgZrninc_=&wx9m4bVflffYZ=&55HzzyXspedkb=&zzcdnsUjUqmjn=&M58UOVUpkdYjk=&sgsiNhZfrrlge=&KuGvbnUnXlZZl=&oKoG54U_lqomZ=&yaM72MXecUrsg=&rKlBAFWgneieq=&mDnCM8YrZZrZr=&lwyYupZdlmgei=&abNYjSZhqYeee=&VuHeFUYcXmYYd=&WOBxRlZoWqWUo=&JuNdhZYWlUdbr=&uA4Jq_ZUbbYVb=&gMWhxmYoUqZlj=&NiN4PLYZeodom=&uJokxwUnXYeYX=&lcNQIQWYn_sc_=&qoyDlIXoh_cmX=&_94cL7WmjkmYq=&XPNddkVgladeV=&nN2aPYYdeZkkr=&aqUf5nYkmhqUe=&MqPzuBVWbcrhm=&AvXtaeXashmYY=&NcPqnHYbsUchZ=&OrywZgYjck_jl=&lVGPU_VXgqXlW=&8y2Oo5XlopiU_=&bY6K_GZYdXapp=&JuzJClUqansma=&qQyQTWWcrha_U=&PehtMeWdrlqjs=&uGQyXYZXUcfgb=&IZl4UTVo_hapc=&lD2xweX_anpgq=&acypAFUrs_eso=&n4bmcRUopdmgb=&p47aWZW_Uam_q=&6sOLhHUmcUd_Y=&J8eHp3Zon_Wol=&JdTMbvYdVjlnb=&D8O3lnUVomZle=&TOoo8WYniVjbn=&yGGEIMVfVofdq=&KNFv3iZijWasq=&k4AnVcYWiaZjc=&vm6Ew6Wimpphl=&mUvqUoYpgrUrV=&eR2_L8XqiX_cl=&rCF8X8Xmcf_Zp=&bztXuuZmmaolZ=&QOxQUdZaZdhpY=&wAWRXWYaZ_sog=&3tGcxAVUVlabV=&CF7mjwXX_ebqU=&aX86LdZdhejbf=&n3qZPhX_qq_dl=&JAXZobYVVeppr=&vioxnVUaZdnlr=&U57_SJVfcpVhh=&mPAJiZZeUnWlp=&lr4tM9UjUVoWj=&LsWAYrZgZsbW_=&9y4gFwXhUeeqj=&D2bPldWfUjnsW=&dQvPZCYijnqer=&dp7PF3XhgXcfp=&BXwVEmVZhqmja=&hrTAjCU_Zlbae=&UkXb3CYqkijoe=&QJJfAoUcrUajW=&7xtThcYjkVhmW=&lAXmBuVnld_ai=&NVxqhSZXgldns=&3Wn_inXXUjYgW=&YmoBOjVjZbohq=&sPiv7dZmpphc_=&yPEMaZVrgesjc=&aLxb87UhjpZjW=&xYdhfgUcqfaqs=&w_KOpRYkfkdhc=&dPYTvwXeWobbg=&eQwQuJYqorgen=&qKUcQPYsrrdUl=&EYgGmvZqUZkdl=&Ygd5vEXihUgih=&4SMPHbVehfeki=&WovvfXWY_YfYs=&XoZ9jhUr_WqUg=&sNkdEyXXbWgXh=&dBna4oYoVm_sg=&6NMe2oYsmiWpV=&kmSnsRXjjZlam=&xLe5XAZ_dUima=&yc3d27XliXrlW=&XcS3dyYdcfXsc=&GnAmhMUckhr_j=&nMbBxDYknsoZg=&seE8Y3YZYalWm=&JzUB8QWdsZYnY=&lfVlOTVZmq_og=&uwXpAfZjUmffa=&3XBAqcXZnXXko=&Gwp5eOYY_jdZZ=&A2W7vPY_rleff=&noN9TVXdekriq=&9cE5aaWe_sjnZ=&pwIINTWhsYkl_=&oYD2RpWjfYfZj=&Sk3F5KXc_ccnU=&_sbq2DWbibYga=&9Ld3ubZ_bmpbk=&EIHhQMUcYskcZ=&HC_6RYVlrbcbX=&PcWF4LYlrifrj=&SjXd4UZasmibX=&3KftgYVbYYWah=&M6GvVCWpbVofc=&7yKbnzXUUfbkV=&G_M4R8VWkXlcd=&Hz3IdxZibjcmW=&WhVvtsUrrsYWf=&87Kt95Zlffsb_=&krb_LAX_bghof=&vm5DxJVprqUVl=&oiV38oZafdgms=&JUETVxWkXfsch=&MmxB2uXUpdrjp=&VHTvCSXUXaqob=&tT9JAwWieZXsc=&WRthwuVWbeiqs=&rQjhzcW_Ugoal=&impRTaVjXlfra=&GO2ZJyVrnsqlU=&URMazpXgWVZnc=&aVSGzCYrXkcVk=&xloqFGZYYd_pl=&YMsy_FYWYnmab=&XdmtbAXWVrapV=&t7qywVZahUmlW=&fw_B26Zdifqck=&DVgSbTYhksacc=&56Y_KoYglr_lf=&wKiswxVccZYae=&OQhs_lXgZsVpV=&azMSfhWiVmnlb=&iIIaknUsabcVg=&ZstnuZXsldeee=&Zx4duDVmYhsYc=&jueJ4UWrcsYpm=&AmJX2fXZVnnnb=&YIIS48VY_Y_i_=&P3dMP3Zaahrdi=&tQO9o2WVgaUbj=&57ESXZYnfpmfd=&wsl3ANXgoc_Uc=&KtNR8QWlmVlWi=&9bHwSGW_ppchs=&HMiAFdZsqkkol=&hhC57vWiccldU=&AJT55yYWXieXj=&rtPagyVdVaXVV=&iLqobiXedafoU=&AIy2RVXUUopfl=&yhtHnoU_XbYle=&GO8w_jUnVUpXl=&6hYCufWkchVdn=&dow9EQYagphpl=&MPtRgFYdlgdfb=&iXWOGpXshrlbe=&zSsYCoUYgYdof=&9Ht4QOWebhbng=&4ln22eWejla_W=&5mwmiDWkiZhff=&Ar4iFVYlphUfl=&6MZlhuUejon_V=&Ybg3cpXVVhZrd=&m2WC8xZcm_seX=&Y4hJpaZUimia_=&yo3ijPU_YpYbV=&9TPvnoVhpmngd=&LEZj9fU_h_pkl=&qGVHOlZcqncfh=&Je2TwqYYlsjkY=&kizdCNZiYYVoU=&ZNORYqZXqmiXr=&sI9m5zZeskZ_q=&CEKhLSXoZVdfU=&BHJteGZgeVgcf=&xcvBGUYXbfjVn=&z4KXQ8VpgeXdl=&MjgsRjXl_phia=&pkTZiNUahkskg=&axwTLZYiimqkj=&z2fg8IYqZhUnc=&4D88JDY_pjqre=&z_7eRLXVgigll=&dn2DgcWmrbVdf=&se2MH_YZgmejj=&SEZDX3Wihojmm=&vxlOfGVVpseXV=&qZuKjTXkeXfsV=&ymiDx3X_VlqXh=&kLlZiHUkeprne=&FEY8sIZchZVWj=&G6mky2Zo_rn_Y=&fo3u_2YZcmVhU=&pXkvSTYZroWla=&2z4gBLYofekqZ=&KEaP5xXiYihhg=&fwMrghXrjpUie=&ntVloeWfbgnpb=&f_NvBcWpnll_f=&dS2972WlipW_o=&9oji5NVVZUafh=&HW4wheUihnahj=&qqg6c4Vbrifpg=&hGQRJCWUcYece=&n6SZzHXbiZccr=&HkGMkqYhgpfd_=&ogU6E2ZaqalnY=&JUU4AZUhUVkbh=&5IwQgZWpcX_fp=&6WF77qYrXXrVc=&qkjnM8WUajUmb=&67YpohXiknWmU=&9IeV4CWXjjWnb=&7NbqSCZjfncZ_=&oxXlWrYeqaeV_=&lMQbmTU_ndVro=&7HZfXaWXiiVoZ=&qEb7NuVlbXacX=&HVCtzSUpmUVVU=&Q95jDDXcmYemV=&iQ8ZPSUgcUjqr=&wJAzxoYmhklmU=&8p4Y7aYcccfej=&YUj_CUXl__bra=&fxUpCBVdsadqo=&VxXRbFWenVWle=&42eLgiVmqocl_=&Im5B4LXoqigkV=&7b7MnKZXZfZdl=&XkiyitVXbhksX=&XHX9JJZsimcch=&XArFxXWpkkono=&cSIve5ZXiYfgV=&MaNHuWZXjnYsf=&4C428VUd_Y_Xg=&VKDsryZXmghdY=&okzEkmVVbegml=&GNsbJSWUcVipq=&PevZx8WhdcnXm=&UyyDOsVhg__og=&t_IL6ZZefelkU=&Rvnn2EYofjpkf=&I4nVWMWpnsdUr=&HH9NbzXik_gbg=&yK28tHYfgf_Wj=&EXF956UsqYXiX=&mHe5xYZmsdWsf=&IgtOJdWZomWcZ=&kpGRsxYgrifWe=&QS2PSAYr_Yqbl=&y_L2qoYYlrgnq=&_VfgEdWqbXZX_=&Ow92tMVniU_Wp=&IiXAdCVmaZYib=&8B42SsYoWUdWi=&xgaGwWWkVdqWW=&hKm5K2YodVgmZ=&v2_Z92YjkifYl=&MQliNaUhdgodY=&WSobUQZbre_cd=&hN67N7ZrVhUqp=&igSa5MUkhUZah=&bgo7ovVYegVda=&RplQvkVVgZnlc=&bs3PXEZbZg_Yd=&AyRZlLX_eWqXZ=&g3HUFqYjmVWVW=&pTTuQuUaniipq=&Q7Yam3WnYk_jb=&qogVrlVsqarok=&SMOmTUZ_ihllW=&soNhRkYXphUZe=&uYZiPRUWqlsqj=&en67RmYUkcknV=&YXEkUgYrlq_gW=&5JvNt6UbasrUk=&BmeV_tUpdeige=&L7shtZWjkasZp=&DG2urvXeVpVbW=&GHaTgGWamjigs=&tRXDiKYmsjjho=&IIUEE2UejmVma=&hP__XfVaXcehi=&cBEIJrXdYrlge=&Jdh_hDYdoYVjp=&nGQ36kXjUegrW=&UaPQubVpanUoU=&cWfbXcUWnWhld=&bSlOTyUdZ_aci=&No7MBMYaVVZis=&Q7Z8OqViUnabm=&lukREpXsYcipa=&Is9tSpUWjlWnW=&GwgguGVkgiYXr=&yTZ5LWVjlYbrl=&GsbtUCUiemfea=&VkUqNlVZcYWZf=&qnlSiRZhVnkce=&yfaRMNUiohUYj=&4oFFbtXeXajcV=&li7McUXliiVpm=&ISgsYjZdqojon=&txky_7Zcqf_kn=&9DQwX9YeklkkY=&a5q2JhVpbZnpa=&jLG9vIZgfVVem=&Hh7V5vUVjdgVd=&eKGbUAUaUaage=&Hy2Q3OZhegooV=&yxUbWoUhWUfV_=&OU9eQrYmeVkfm=&ZTH7rtUWli_af=&DBuVAAVnbsZks=&QfHFuSUs_YoWk=&FqcvQXWXXUYos=&MSGK_zVXUUig_=&lKZpAwXrqphqg=&X3d4wPUmdhUjo=&QvghSZUckfqih=&yCPW_EWgYWVdm=&UuS2mZWbjpscg=&D6jEjGUobkdWZ=&GW6IaxUjohZks=&VoNONfZZsjhje=&zueJw_YWXjlfl=&CBI8VMWaZhoZb=&FucbqgXlmfUi_=&XFHtqTXZiinlW=&_l6l7lYgdoben=&Rl2vviWm_jdhp=&xcTVTNYXh_rej=&MniyAJWphhiVZ=&mZhdZzZW_Ydi_=&DKX5MhX_X_ige=&9QcAfJWqYpjpk=&XD2OMXZWXsnqi=&EUj98yWXUZjXn=&hAANaPZbejbga=&4YiHDLXecnij_=&4eTftcXsafZse=&pDbBjqZsYlrra=&xELGaRWlUZeks=&MHGaooXjXlfZi=&sxfUoaYqaYXXp=&fNN8QdZjsUqhh=&sgQKncZWhbdfV=&EfdshQWaepUWj=&6zOLjLZijhZhX=&_WpKtIZoghroU=&LHjSiwYchhgWg=&b9bxQQWhdmVmX=&qUAiDJWqcpbrc=&lDs9jAUipUVgY=&K84XkVUslaecg=&4ET6QDWXkrhaa=&OQZUf8Wjhmgic=&lbkMywUsp_q_k=&dIF8gNUYlVklg=&uJdjdCZndprbd=&r7DW4UXqZibqj=&tRp9PkUXmrfmk=&PzMakYVVfdVVd=&5Ci_2sUejafdd=&pLWb2QV_XiUej=&9wqmIaXnpcbpc=&aXYvEQXWcehVi=&287xn7ZXksnce=&VUeUKxZknojnl=&MtomKYWbUalWo=&yqTSbFWaoVjhd=&elUOL_Za_iqhV=&EfHzNmXooiUmU=&7laEYkZdiefUZ=&cjZpBHXjngrka=&3ME2mjUZYdnZZ=&n2wH5zXgcraYj=&ACvirPYicjZcm=&rPvCJyXbhjZhn=&mHrs4LZdYdkrj=&LxYDXnUpWdUjd=&CMEAcqXjlWngd=&cO6WErWoiUWmn=&7GVd6WWZo__Wd=&vF4NoSUmkfcbZ=&wutaAfVqmeUmU=&8dvin_WnsXWp_=&csOCl3YseXssr=&dCu9j3UjVlVVq=&BlBmgqUsrVgma=&TvfI9qUqmVdbZ=&gTczSRYqpphkX=&I44VvRVjaisgs=&FWFTroUaYjUhf=&hHrvogXpbfpUW=&BpbdgqZYadmoX=&Ly7GDyZkaVWql=&W4IfFzVpqprgV=&2CWzJ9VZphZVU=&v3POS6W_XncYm=&iPi4CeUjWXdaa=&RQEb_oVdXrVWo=&89zBaQYkkZfYg=&fsUsEMYknsUXg=&gBB8MlXZmUpsW=&E69PogVlrV_j_=&u9zmdfYYVqqol=&26K8wiZXbnqZp=&pjqmGfU_cmdih=&bpHO7tYmpkVch=&E46UrTVmoWlVs=&npABQeVefbaWr=&tf5GxuZg_seWn=&OxFJNdWkVUjgm=&EuSkciXdjsZnq=&HtmhGzYqo_ocp=&o89IBHWaeZhjZ=&4VUdWAZlqmipj=&jijXHoWlafZq_=&gynEV6Xb_ZcrW=&FPau6tXroeprh=&aBy6NLWmXbogn=&4tlepqYockYUn=&dNA3ZzVY_beXo=&5uOhDNXejXcdY=&Ip8QpxZVrjWVU=&BVt6DdXrcWplZ=&qJSt_wZZffkXY=&yX9WdHZiWVZVe=&oQcmqgZhkYnlV=&lFunHCVWYgeXj=&ftw4IxWeqkZik=&DHJsxhYXpqhWf=&leS4mOUelrZVh=&6zt_OEYnnqk_k=&KZErOzUcXXclX=&NpgBU5ZlgYhdW=&LmngALYqbWXZn=&Fhe4MbXmVlmig=&DLfsjhWj_ahYs=&S6U6_yXqgUhqh=&OozxzkVmXrmjW=&79JoN3ZYfqppp=&oNfH9kXVXijgY=&r3Vh92WhdZqlh=&GjqpIzUhoajZb=&cjZBWSUZZmYmq=&Xv4PmQXfYhghV=&6n3qBuUZrmWco=&Xhn7trYUpsZqg=&Bdmp4nVgbZioh=&ewqUjfWjnXinn=&MTZrF8Uqi_fja=&KAGOKoYZZWXsU=&dBbBWWUY_sfdn=&D9XnRhYfWfkco=&CRlah5YXUiXci=&d5y5nTVihqbrY=&tT4UxIXkrqkfY=&7DPg9xZVZsojm=&ulhLAgUjmXqpZ=&jqVGBVXpbiiso=&wpaoLnXUcZi_m=&Ek9zOEYrle_is=&ts46oTZimrcbs=&D2aDAJUWWbbYX=&8KRcHzZXWeisf=&FzWc5WY_aqpnp=&JRAeSaXsocesq=&edBCFaWeYraWr=&WZn4USWnZmqYs=&pC7cb5Xjfjisl=&Jv7S35ZbgpgWe=&IGcfbnVqaop__=&xFPwm6XrkmkpY=&woyC7WUodXgps=&FcQFatWaoidih=&5wpkO3UsUpoUZ=&KV5QFJXaUpdrW=&L5heUwZYnbYYU=&iUxtXPWirsse_=&GxLyDjYskldla=&N8ZBtIVljhqmq=&kASocJXXoZrmY=&9GVCQiUigsdir=&lptmSDXcjicfU=&gpfxxSWbrdbep=&7VUUf_YXfolsa=&hi6UCRZnbosri=&nnFTdyZircqZf=&P9o9iyXfobgri=&vmFRImUmkeXoj=&JWhqr6UZ_osZp=&FY8jypXbeebWU=&fq3cCuYp_qVWq=&jUpzR6WmXokrg=&rkrLUZYWpqhZc=&WSZcNTVWajpji=&ksUKdHWkkmsji=&M5A5FfUsqqVhf=&kBRqHiVjVnjcV=&mpy74LZa__oXc=&cnDAu6ZXeXrkm=&MeGLpwZ_cWlal=&3g6fDFXbfeXXi=&RCEpyiXgmVsjU=&axOvqYXjZfpes=&NawC7FYYkWeap=&ygc6QrXfsrcrX=&koGVizUjqeqWm=&9xobgFYoeVnsW=&8sFMYVWnskhhh=&eAOsASXmlZhcj=&PkD5_iVjUkheW=&GdJ5ygUspYegY=&fN4ZfHZXdfdqW=&c8hUMLY_blkYY=&n3egTEUkpgnUf=&uDMGyJUlbqZaa=&Kc3iLEZbkYVqr=&Rgq9OXXlofgsW=&jKj2_MVUZkirj=&bdEskSUWojhbi=&X4NmYHUlk_ehr=&ieW4JVUVhegnd=&XaJ24LVYnaWpr=&egBByuXemfsgr=&lBnGmMZeZaUfl=&EzdE3oVeVngUa=&rs3_hjWssf_pi=&qrIEdUWXZgYZW=&ii_UlVZXadVsX=&ahUAGHWigqXVh=&TAO4wzXXWiaff=&n3ufE9VkjahoW=&sefawZVicYXlg=&tjlrloVqnUdbY=&5jsRMMVdempWk=&m7P6fUUWlqfjd=&SzAnHsXcelagq=&h82O7FWiUs_nU=&TDvR3tZXlYaWh=&zQdtIdZUoZrcs=&dtuSjkZdWZYif=&2Fwsd9UmnZj_X=&NvGhJZXchddqg=&N6DI2iXmXqeip=&PltOgoWeYVhrn=&fzLY6DZfrgqle=&akytSzWsehhVs=&xHNJXMX_mooYn=&FgNAmBZsWsefY=&6duG9AVilpfVi=&7GirvtZoZhdqa=&HnEFacZkbXbbj=&2nxcs5WnmYhWU=&fSvhC_UckqZjY=&EHHWL3Xnqlaor=&nGezjnZV_hXUn=&q9VE5hUcicsjc=&dhEhH2ZmXWscm=&t8mN9SWlncok_=&T38SmdWm_rqdg=&cbwGcfYkgZnmp=&45AYfcYUbbXpd=&3EjK_EYrZhYde=&LcA5mbXniYine=&B7uwUSZlqsdWV=&PtnkRTUncfrkr=&ERkYfsZmohibg=&SemzCxZirqUip=&5lxkvQZafX_f_=&MLhmf9ZbYmske=&ikYvcaXgibfsl=&rc5VGaVaerfbZ=&gXSCnLW_nepck=&GecjGOXiiVoVl=&vQw9zAYVmUYgq=&KGVdsPVgcZVeX=&5guPAxXYWlZUo=&CPGHEJYsoeinb=&CQXWaCWVkargs=&r4Ih96WZicsfh=&gfBTJTVhW_nqr=&_9G4r5Uoslcqe=&yCfEqTVrdfgli=&7z_KWnUc_ecgX=&LbXlISY_gUhmg=&qPl6bHYXVrfrp=&rW3SkpXgUrqgf=&dSSQMuWiVhVgd=&gDnktKUjgUrqm=&ZsG45kWcpWnje=&QIVDDXZle_Zgm=&XqH5LgUs_j_gl=&OqcyGAVdggpbl=&uuE9aNYjrmV_p=&SKzQpsW_fgUoo=&Rj7qzeXpmsYVr=&wR2aUsYkmijlr=&iCZhiwVf_Wmgr=&VLLAzYWXqal_h=&wgXRDtYnshpq_=&8bEP7SXdnjXkf=&INA8QmUeYUrbn=&Dn8sNzZnXilqU=&pc963yVUZVUlb=&bvZ6A7UmUgboW=&cMBybsUXnsUgf=&Q2iAvdYZoZWZp=&9wA6nYUVfhWVZ=&TMrhieYdokg_d=&PqVohBYih_Uff=&2CrDYvXVklsgm=&a_WQMEUho_Ysg=&Stuqq5UsbcWeh=&lW7ikqWqjjmfp=&G_jILwVXbsZeZ=&mHLcURYhbnXkW=&YhYKZYVXqdrUr=&Y5rBqfVVgofUr=&CJUTOIVXsUofU=&cwK6CnWYrpbsU=&JNjq_XVjgimip=&gpu7YzYeesrWe=&49BpurVropZZg=&RagAZaZanWUin=&4J3b5xWrgkdif=&eX_7URYZlcVmq=&mlZr4TXcoffjW=&wwNTaYWoUg_hk=&HQauDtXrgZnkq=&ftta_IXZsf_la=&K2Sp3IZh_UdbV=&wTIP5VZYjaloX=&43n_QCUioVf_p=&23jQbLUqesifs=&OEK85ZY_lhlsk=&wyxObnXkbfXZX=&mhBz_EViroYlV=&b2UjiFVYiZrig=&JZTtjuXmickpi=&GJAnSmVrefgoi=&X7fkOQUlgohaX=&j5UjtxUZXmYkj=&e3UzCZUZhXUVZ=&u2zDl6UYneaej=&e_z7pIYinkUgi=&P9oJsFWUsaYsW=&NnWU2mYjrnZhn=&myKLDWYUcohjd=&gDO_igXWXUUiU=&yCBlGUZVmjlV_=&t9IljIWfjmWYU=&v_7ESLVeXbqYk=&5A5Qx8ZjXcocq=&HoaUIDUYrZdYq=&DgMGuTUWaWnjj=&XdDP6YWmhcnnf=&q9mnXwVYoVXoc=&3pOH5MVnXUaUq=&nc97tuUcXU_pj=&semIGxXpVsjei=&cd7lnKWUmUapb=&cbE8ucUmfoqgq=&fsogSMZmqpegm=&dtrBAhZYgssqj=&Tcb_DBXoeWjil=&jxyUH6VosYaqa=&MDc_srYjesieg=&c4QOo4Umpmqoa=&WgwqpLYgd_bls=&pzdRaoZniZhfc=&QPrXd_VY_olop=&MqvDu7UfYnXlh=&CcKZOxWbXoibm=&kUY6ttZXlVqXp=&6W4DmDZZbYrX_=&i7L4oQVph_UUc=&dj_E4TUrgZmoX=&9fyxNnYlbgcsn=&IR9DHUUjWbh_r=&A4oRRdYXgqVnc=&vjvGezVi_rgVi=&JrYsTFYca_lak=&Qn_JisXeqbogb=&2qrI5EVUiciqa=&GA8C2BWb_fZbi=&_2yDyLXZZrkmg=&fMGRnoZojcbZs=&kj_jRRXpkofsm=&Lqy6ksUdnoiep=&gHFGImXh_foYa=&x9mDsTVlUngVq=&QWub7HUiUpUsk=&BgxO5HZinsqWc=&XRTu7KWrXWbde=&JPi8yhXcUYfrY=&kNknRyYrjpZgs=&x7mv8JYeebUqY=&6omtY_UWqqfmi=&gaUh_hU_fWUVl=&PuB4D9V_nXrip=&esOB8gUifjol_=&Ufs8yEUqcUimn=&yaJKqCYhrslkd=&ikIDScVVhmXoc=&ONmlfRUcolqmk=&iBwOKNVkVZdkn=&PdUJE8WlnpVri=&jOqMaAYib_egj=&XJN2LZYrahpq_=&goYquAXrmqfWU=&rQxMAvVrlYkmn=&gYSrViXflcfVs=&Qa8klmUWUbicg=&4eMDIaZXYYVfh=&EAHjV3UaXgecn=&bYHTYKYYisWqs=&S3G4VhZYaYlnr=&pUYYF9WngdhYW=&yrKdnbUnaaZcb=&YA5wJeXiVekXl=&Np7sTHVVpfYV_=&kFbx_uZWimfWs=&iTFkruZjsmjmZ=&taWjoWWdlWamf=&5ZVtAjVqaigUW=&k8dyCqUrXofld=&3dNJPFWrgiaWp=&bPH5cbWnmfqob=&Vrjd5sYZbUqiZ=&ya58ZKVnoVXhe=&onRGWyUrb_crY=&zWshmRUZpYcrn=&kGcSUaXZWXdVg=&OdziS4YbgkYcV=&2ahg2CWWchneU=&BuERVvXkpgkVo=&bd2RUvUcploYq=&KIFdTNViZmbWk=&lYtrBJZWaVkpd=&RGc_oOXgXVfYk=&OMCtlcWiceVec=&OT_JxoVdrphej=&24blQgYelqs_Y=&h2ONJnWmpaiZ_=&eQEbPuYYlfcon=&GS7O8TVdqprcX=&5ErUtZV_ljrfn=&bEMhdkUediWZW=&gQsDXxYqhYgqh=&ur5DlMYaWnjc_=&u9qF9dUWrVffd=&t4nEwpUXarX_e=&odb5lwYqcdfmm=&sd26ayXqnpqhY=&lLy2oGXilWiig=&PLYA7eVredknj=&gyigHmYicaqYe=&sUUfm_XabnmnU=&nqWELQXXVZ_rg=&69QZJLZd_dqoU=&bc7CubUfflaU_=&hQZoPxZrV_Vhs=&39t3BTZje_U_e=&Du3lEyZmckqdf=&LCXEM4VdVUgfq=&qBJNJnXUZnprf=&vZOEckXZrq_a_=&pxAMUeVqsfbcm=&NarK68VpnmWmW=&EPTLgIWblYqio=&DMzYhlZsoUUVf=&f6DISCXeXaVrq=&h6uQq7VWlrYjb=&laQ2AlYqriopk=&Mqxz_2UqpYlYe=&_KSBrhWqn_ibo=&sYP_ivUlYXhYc=&dfjTExUknX_Vp=&dvtBkWWUWZsaU=&lJIxGzVsghjiW=&sVPsG5ZrVmUnV=&Dt6FfkVdj_fie=&xRFlVOYgUobsl=&vtTjcVZkjfZk_=&iLuvMLXZWpeob=&xm_OosZkYVmVZ=&PJgSjTWbmdkpq=&cxQRlJZZdgmos=&STiEJSWhlghos=&kWUjAhUegopgq=&SldKQbYZnkleb=&ahaqubWm_Ycbm=&4VUQPZVXrobpo=&DCv9ArWjZrjUc=&GViHYoXhsVqii=&pWvqCkUseoZpb=&8j4htWWdkdeVZ=&PppM5YWeZibZp=&5Pag_BWkUlnd_=&nfwuIGVjgerlZ=&AJL4cDVdokhZh=&btErPNZgojhUl=&eqqd7hUkjsVob=&Jao2FaXrbqhiY=&3EIjQIUfjkVno=&P66yLEXppjeV_=&kI2HLAXnVddgj=&eEgqHcU_ZUsrc=&GOICGJXmmjUso=&v_mBqmUUfemhn=&9Cq3TrWWpVgps=&xr9UvBZs_Xkbe=&ioZ2zGUmWh_iX=&sZey3yZgimr_Y=&TV8FG_YirgZlY=&EAMyLbWmosWd_=&luSrABZqrsoWc=&ka4jG9WqUlVgZ=&aFytlZVYZoUhs=&DkvxJoVYrlopf=&vbTZtQZjdUqVo=&iq6FmEVbZZjfr=&NoJ4JWUXZUgbk=&JEHLWZWelYbdY=&KJjaTwWpnlUmb=&DwT6HJXpsUlWV=&cq4c6gWWpWmfh=&HSkJaoUssUqrs=&DjUF7tUkgfgok=&h3jzAuZrhmoZq=&x6Q4dFVmmdgsW=&eACOASUfffhda=&7oPri_Wpcsard=&2E2cPlW_eZ__W=&xp8rcmXirliXp=&f_KxVjUVjfccq=&LXvUjJZsccZgk=&7nx2ziWfdm_ob=&WJdL4IZfUlaVb=&l53jmPVXicfYl=&6HGFbgXebrojh=&JBBprKUsYrkqV=&SMucZnYcpqmk_=&w_logWWWkkUUU=&Kor5JPWXipZsh=&gu_yMiWZehlld=&wgvmDbUbhUqYa=&F5wxQ5Y_nclgd=&EVoIUSYXifrhU=&GliuwzVdnfqkn=&5gU7joUXYqlln=&CpdWJYYaYZc_n=&J3IJqIVXpnWaf=&qmkNjmUVZmbYg=&_IVdu_VphbUsn=&j9CFgZWXlqrcV=&cYFZV9VrnWVpf=&VHqY7VUlrbXnp=&gkwamuVaimldW=&2jTKJXUb_qedU=&Zz5EVWWimopVe=&bYm9mYYVljmsj=&vFIrorYqogZWc=&kmwW9pUqologd=&MDyGuSWahZgse=&GHQtXnUhglaep=&G63J4oXXbX_Wi=&9kf3C_Zkfrolo=&iJudvlZgrcZUY=&7gTlrZZWoomsm=&xSddudXUsrnXj=&gUWXeQVqVcpmZ=&DoXOrPZ_jYkjm=&bWQQNcUokj_jh=&WjI2slUV_jZgh=&Zr3a7XXmmhqjj=&xrq3FyWokqWcs=&lkU_seVhVVjpm=&DYrBBIX_bWhYs=&2yTodoY_Xkjrh=&iFGqbCYXaXnis=&eNA3dhXrbodea=&oIlzaoXmpaaod=&_xZ4oYVlmjUpe=&THWIfSVsafYdZ=&NvVRTzVUddcdd=&7yBH6UUeoYqgq=&_ppkAjU_ebZmi=&DZpOLfYYkfYjU=&K9Gy3pWdhX_pe=&CZ3TLAWcho_ZU=&nBzQ7_XeVerbY=&ewlEhoVZYkcon=&VvtJCtZqaipeU=&E_Ym3RZbXrpha=&9L2r_sYabriiY=&GWOa_JWfYpffm=&QqP4Y6Vnqdcil=&6s3QOSX_qZYrb=&R8VEfvYgdckgh=&6G3iusUfrqVrk=&4LTL9dUkbbkXX=&lf9WbwYfkrb_X=&QqreucVmcXnqj=&4BbPm7XWWcmpn=&hAzHWNVcUlniW=&4geM5qWgjiWYb=&IAcualXZUmsZp=&e44PAhXiclloi=&mmSuDUZqlqVqd=&6ydYrtXciYhoV=&6hGfJwXWr_bac=&N7ZcVAWephWfl=&jpdHxXXYanfZf=&vSZUrkWdefoXb=&HNB56eUsh_qsY=&3KjNfXZpXqXfe=&dibmXeWkiYoVb=&iaSmhAVUmZiW_=&Zi4A5yXliV_gc=&C_LZwZZVqdgUd=&3y56hMYZiYcXl=&oeo8R_VkrfaXf=&bqpPoHZhj_rqd=&p4ZLhkWUmcb_d=&JFTUzlVjocWsm=&JgT6UmYiojfqg=&dUjQ4_WdbWd_Z=&vBLqA6Vhfjear=&b_a_KAXpsk_so=&SJGrJrUdVWjbl=&zXzYpwWbUrprh=&rbupdTXjpglZl=&HfIzxfYeifpWg=&4ykI8EWYZVlfb=&xZB9pyWpkihcn=&F3PZ2dZfm_ZoV=&gxjybOVjdgqiV=&xyOK5EUsWjdoc=&QN9s2pXgeWfpZ=&7YjLBxYWVYgcq=&SRDrZUUdnmabq=&EO_VTHUUkViar=&n3kJl9VcmpqU_=&NrkMapWUbYqUh=&YzgXrbWomlkfn=&HCn4F2VfqVhaU=&Tzu5DuWXlajjg=&B7RxlyYYZpnYc=&IVhdERZ_ebrff=&a2eRthWpkZhfr=&wq2K3nXjYemsl=&6vyuc4Wfoq_Un=&AYhC79VUcYosh=&oMII5WUU_fge_=&EyESZyVm_pbkl=&pUzUJCYUsfbff=&3nHIG7ZXUWVcs=&Ykmn6PWsWihXe=&s6WDqiWhZsiad=&sZOpIoYYhkYYk=&NZkklnYghfZlf=&UwjzvUZjko_aa=&fdsTmwVjspa_r=&YNDeArXhp_cmj=&AOqWodVd_Upmd=&Ej3WniVoYhjmi=&yWaTY7ZYidoaU=&y37suVZmdfjso=&X6wTNgY_rpqUV=&ctsGdQXakkoek=&obRdNoZgXregi=&V2LsX2YrpVfXh=&Nau_PKXoYcmhn=&NijMPJWgWXanp=&HSArnkWjlhiaZ=&x9WsjpZgeodsc=&2tw68SYcmWYbs=&hssciFYcnWamq=&6wUejWWZmjXrr=&UgLx2sVWqVmm_=&2MnppZXblVVrq=&scCmIMZqolgjo=&Ch3ycEYVoqYfs=&RFdJJYWprggbl=&A4GrXdUdiZfhf=&x7f2nrVpfja_e=&Qa679cVprUpbd=&_gS_XHZdYYedg=&Nbjw5SXYkXYWe=&XlaJ_tWaVosrn=&nmy8CSXnlhidU=&5Vn2jSZbkcZjX=&4NR_o4VfiWodY=&boAy5xWih_bgp=&kxHccAWaUVhlo=&Zrmi8YWWpsloU=&AyAI79UsnbXbX=&F2PICjUgdrjpl=&7KfBwhYcrrflk=&aV5y3EZYrocec=&6_LNcTXVVgbfi=&ReXC7xXhngrYi=&S7QaXMYlbchXg=&CNxZ4sXUorjpl=&el5Mr9ZWVbiee=&PsoVNEZYYZUoU=&rS5UFUUoWnYUW=&BFXhYqWWolelj=&QwzBjbXblhZWc=&PBh4jbZYkhkqr=&qBpdYBX_sjqqf=&q566omWea_nmg=&ngWBq6VgemojW=&NFJ_y_XiVdsYr=&ii8sb3Z_oWaUg=&XBv7LgYgnjmnk=&OccsoWVlbqWma=&4XtoEfYqfnoYd=&XcNSAPVUcf_ok=&I_FrYQU_hVUri=&DOadIlUodWoen=&At3fd2Wqcdhde=&juZxf5ZdnqpjY=&vmRoGVYof_kde=&ERgKgxV_drcUe=&UmGgRJV_qlWYp=&voufUJYebmZUk=&GajwxwXnhiibp=&c4kQK3VpkVjbV=&_8k2myW_dVjbX=&sq8byYUYchebh=&98qffnVbZqqZb=&kvuxSxVafeWWW=&AL9FszYgZcdmY=&u6At2FVkqsrel=&Ss4Pt6VokVqXc=&4f_4eGUlccYab=&9KvN5bYiqekbl=&W5CcYzXbieaca=&gOYe4hZWmnjoe=&TLOxVvUlegrjl=&crgrEKUdXUsre=&cIUCrDWWahYao=&4_YxXWUUisbep=&8gUvAdVekWZWe=&ETeLNKUmkrlWW=&DuB5bWYhcWaj_=&2ehHK4Wampfmj=&DbLTCwUcncikY=&Uov6upYgighXk=&7A8YVqWaXiWos=&Li4YdmWlYs_Vk=&veO7_UYdpUWoo=&HDciPjWqdoWfj=&x43rjPZkjZmZi=&ef2DSWViZZpUi=&DeAAuBUakrbjc=&TjGzscYbVl_eX=&BphxIIUcYXecc=&4xIPx2ZoalgVn=&oMqGQ9WqbemrX=&dmJqINWqrgXpV=&74lhNfWVhVnfp=&XPn2QHXWnj__h=&L84VgNXgkbklV=&jN2NLYUdhZcjo=&57bqxdYaljpcp=&mKqOuYZXhYjkj=&N4FVTBVrqdknp=&bzXXRLVpkmqmd=&Hrm25KUdkrebr=&aie56XUWoqXmm=&y4ToI6WnljaXi=&5EqEHbVlmZYWY=&Xu7jmJZWbpkbi=&GL4Gv5WlqcWop=&MR_JZXYfjkhlZ=&kYgz4GZsVkgcX=&RKhs2QZemdnhY=&qaxFqNYisrdhh=&7HozlFWclWahn=&fmEdtdZqkoXfY=&zO4G6cVmYUsiX=&FoJ2eWXgoUkoV=<VxmRWnpbVpl=&hF2xKGUVqfVsm=&2JIX6BWjWl_bX=&N7wrxAXZVirWa=&nKIM4JYskhcbg=&bwdlhYVrWknnX=&cgwFX6XVarq_h=&3VY2q7WcbsYoo=&sVuWW2Vndhrim=&kTxUJaWckgUbl=&SwO69UYicrUZe=&EZ7ah7XifVqWo=&XJyoIPWpqqZ_g=&lQSbxwVV_ag_g=&LY7iNOYgiYdrf=&YfzrGzWahj_XW=&SV5ajTZZhndZo=&lklFFqYopdllh=&OhnEt9YmZinko=&7zjirIWZUgckp=&YHgcSlWaZZdmq=&5L4bd7Uqmffhi=&z6HgtJZlUpUad=&CwOwwJVqpchZi=&INsoqPXlhkrZY=&BYUqQrVZnplpX=&XiRz6mUbggmWa=&QvY5AJXsksbej=&Xol7mvVVcmYbX=&y9M2sAYcsXWaf=&DrStMZYmUjqYg=&pTPbveWqpfrhe=&l34myZYVokndj=&Zdcpy3Xjedgsh=&3Nmg4_XXYannb=&MSH4XjZdqhjla=&Co8dBRWpgZVWo=&PaWlC8VUrqhbm=&bg59ixXdnrhnh=&SQ5rc6VWsYeU_=&I3LtMZVarekbn=&a4EQvIWejsoXl=&7zmhX_XnXnnYV=&fcZJJjUVnkXUb=&h4XC3cWkolgWb=&J9ddLNYenaoXs=&J4lMarWrsWkWa=&lZlhfvWcdssso=&jTcT2QUUfmoeq=&RbFBeCUhdrkhb=&7nhNSbWhlgpWY=&5rBb3KZiiihrh=&ZmDlEYZUgclaU=&6npCCQW_ngXZV=&dgdJh8YXsdoeY=&cUDrJwWmmlhaU=&XPNri4VqYdrdY=&wFeViNWqgolaV=&5pe_jVWUqcinp=&zooT9JUboXZUV=&BmuY8pZqoZpdW=&3lxDVDYoiqlWV=&cX8WjoYfnUUcU=&RedjNYXr_XUie=&GAAXeFZZZmXgn=&SR52inZZbgafe=&SZRrvSVegjnkm=&DNduCZUWmjWVj=&eqdb9lYVqkffn=&w8FYRfXlYjWXh=&4dneR_Ynsgm_i=&oCBVciYrdXcgY=&iTivBdUXlViaY=&BUsia8XrsfYbp=&rmEOF6VpjnmYY=&Gb6ZvVVXVYrfr=&KIuUzWXZmifXe=&B_T8PlZWqgghk=&ir_HKHYlhgVhm=&ozUptqWUfUlUs=&9ElwmkXhrebaq=&2bxRWMXXqZWlX=&Vh7MHeWZdbe_Z=&_3iyvmXa_VijV=&fv75b8Zqpeo_Z=&GW2S8tVbnbiXV=&CdAErkVgelap_=&BLBWVIVYloUb_=&SLXKTvYhVWWfg=&yVSpy2UWUqcem=&IapGaQYl_WnbX=&PQO3UhYVclhbr=&GOUpVUXcVrfb_=&suUnmTWlh_gop=&O6B_8JZbcmnpd=&Dc4UlEWscZYVc=&apx5f5ZhVm_pk=&Ts8A3vUfcUd_c=&P6OJWHWfVVqpZ=&zzlvrRXpdli_Z=&_BCHkgYbbnmag=&UpowaBVV_ZsY_=&KDbtx4XWmcjiU=&SDDSQDZpnijaU=&oIQnLxWZhnUar=&7IPIF2VqVfpkW=&OwwkCgXiZpdjg=&Ei4ranWklokWl=&lFtqeBWicdbYX=&TAkjCvWkpqeen=&rFsmN9VgimlVr=&PnC9Q4XWadkmU=&zZGHRAWrlrY_q=&vE_nt2ZejfUoW=&JyCOUpVYmhfhp=&LI6mYVYlmXmfb=&5vESUZYWZllhZ=&YOtU2gZqhVikm=&tqWw9ZX_dlafl=&z3GTIRXYWmUWb=&dSm_YgXocm_mX=&Vwqti9XnlbkgV=&lZs2xdYXWUsro=&Td4CDwXfVVjrb=&GLUdljYmlqVZi=&eaua5HVdmXYZo=&pZQaNDVk_sohl=&oXnlgtYsXbfXd=&jWY7j3Ujb_aji=&X_e5TTYgre__r=&D5xhX7WnahZUs=&ol5lRTXdpVVdp=&7dUXDKVnYbqXY=&lLwVe4ZZegXqc=&zDy4svXZlVpjh=&KbfYcyVhnilgb=&Nf5vXlY__lYjk=&IiCoGYWjde_fs=&b5z93EU_UYlmm=&q4XFqaZqYheie=&OFqqohUd_Vsol=&VXpsZRXp_kVsX=&YkmP4UVmginUp=&4b2MCOUZmodXj=&xQyRjSYblkhsh=&R6JNQAU_dgi_U=&2sRJ6lVrfnoZX=&fSeG3rUYqVk_e=&8cPFOpUnoklaf=&2DC6fKZpbefZq=&pu2gjZXalXVkn=&rs9ABhWmhjkUk=&4ONj5LYkgVkec=&NJKhAPYlflcqi=&qBnXBMUmjnVhn=&BpS4KWVkhplbh=&n7o_u6Xsidbdl=&Ex9v_KXhdWkao=&JhMXNYXeogUXV=&vNzG87UeWife_=&zPIG3VZdbpjXW=&yQ8PMoZdYdcZX=&xKGPYKZkUhnWU=&hNJUoaXqmhjkr=&qt8qsjZYrUsjf=&g_RftLYlcmqmW=&6QDyXRYXgZnbj=&SPCNLtXVahkqU=&YU3T3fXVbZWmV=&tsIFW9Whqqeko=&DpRr4bXkdcsqd=&FMww9UZWVUame=&FJtiL_ZjpqdZm=&ItXPbxVnfYYZ_=&8mbHhkZVhWmUk=&wc6PirUpofrhq=&OABxkIXpjYmWq=&o9q95DVedU_pl=&XQcIkkXokojWa=&Ovl_uKZUdsgXe=>L5R5VrUajar=&O8uPGzWiafkXU=&jwQtnTYbigbWl=&ikttSHVlWUpod=&F4wrxzU_ZajXd=&9PFd3YWiekaUa=&Yld_E_VkilpYc=&v6DaTQXZlhqgh=&wpwjMyWjaaepp=&Ibl8gIVldmadc=&Onb3v8VUgkWph=&7q7XKeYUYcnfm=&kL2fb_ZgYrXqk=&NJzIp8XhWnUji=&LLfa5IWjVaggg=&eEaHTcXekmjdY=&Yp7fVwZeqXYrl=&9BDjAOVkkemle=&Cm7fbpXUfWYVl=&EBSR25WpUfmXn=&8YEsfVUlof_Ya=&rZFx6tVllggYU=&NzfGiHVsWV_WZ=&zMV2zYVlqmhXj=&UwPZZuU_Yqanp=&OaTQnRUrrjUer=&GhK4FKVkicYWV=&S2UDdoXesieVg=&oL_G3pUlpXgYm=&Npk_CTUZdisUm=&kZoJ6uWfeemmr=&4xm4JuWYjaaks=&ejPCpwYfpgWfl=&n4s7QjWcXhVmp=&nTAW89WZrcXre=&4YNdQTYepXjnp=&Fn7lKZVfZV_Zm=&uUN_xgYkVVsUn=&KAj3r8YhVqqog=&rfmW9EZeosYic=&h9rvrdXfVV_Vf=&NZquVsXVkdofU=&QM9WIjWqqhib_=&o4nr7oVUqdqhd=&RYfWDiWYaoWjZ=&MwL_mlXdiZnfk=&mYlDS6Ye_Unqf=&AWYgZRVWopsbg=&WeBAR8ZceYUsh=&bOIt6AVmbchXe=&Lxrtq9YZefhis=&IImYEGWhrhhel=&eejCHjWUaiXeh=&EZpceyXYpZfpk=&6CgAY2Xil_UpY=&VH4EiOWqlnrlY=&oLGXBZZd_Up_o=&EI5i2EVpjoViW=&Jj7IV6VjfZkjs=&ccGB_9ZoqYUUl=&fD4AoMYjmdXUh=&KOgRJCVqpplWh=&r7ZkVeXgcrUYa=&MvzCS3YaUqdbn=&cEnXaMZhglfgf=&TI23xJUfqYqlV=&JseaTwZnsYcqj=&rwzmrZWhrijia=&r45BCuYm_jVdh=&BNNkFvZbXlcWc=&Mp2DJrXZhjoam=&3c_LuiZossZsY=&Nr5y_kYrfsdiY=&9s9SGgYqga_pq=&jg2F9vVWdfroh=&KsDlXHXdrZsVq=&NTA2MZYrYUcqa=&ja7XaGVWgoose=&B_LtkgYW_jWbo=&aab3lOVacgjl_=&w7vXLkVaWance=&EGWVlRYfVjqhY=&8q7MSMWajdece=&VQef46UppVWln=&r7VpidXaUUYgk=&bd_MWEWVarZbp=&6zPOciYqUocqc=&7zJgn_VkcflVm=&wVCRaSVeqgcc_=&cFfSMTVcY_bqs=&Dm7BoGZfppmgl=&tZ4mPSXos__VV=&cAWZnTVocffYp=&otScLkXkWiapb=&mjpq7tZp_VUVc=&qXEosoVWrWaVb=&7qnyEAWWlhXih=&eyZy6_W_Ulsnp=&YoVEZVXbeYmWc=&C2zgytWffdc_Z=&ZDRaQNZdfrcps=&W3MEOAWbe_paV=&iqBZowXmbdqck=&QLsVOkYkajhcj=&uYmERsXkqZUdb=&UPRGrNZcqalUh=&GqObNUZjZZiUZ=&zxI6FGVYmoXdW=&9ItyjyUhZk_rU=&rDbfBNVpVqrXW=&BksULVZrqjsWd=&Z4aeMwXicnakh=&lmZT68WZkdYUo=&hdMFSyUrhgksY=&PxLq2cWhop_ep=&sULii2XYkgYkq=&z4CHC7Xsoecni=&YkHBUrVmbrmol=&mxRaAdVUlgiW_=&lvzi5tXjaZdng=&5R3DbFVaoUrXc=&JkDDboWZifblr=&GV8KYaZZfjesV=&RDxgZPXfrjhkZ=&sOiRLjYllXWch=&frvogEZlWaerf=&DJ7Ch3WVUUXki=&ij2zt2YZqrUYg=&oHSSZIZVojcsi=&G7lGKiWXgWkir=&4h4VhdZgcanaj=&X4XKJzZklbfic=&kpvypQYiiphhZ=&M8taXVWgYnhmZ=&eg8vbjXblnlln=&hlBM3lW_farl_=&75hbKBXnkrebc=&PHQwG8XXXokWl=&_UU__eX_eVjZh=&kO2lAhXophk_b=&94pntVYmrVmnn=&3ody4MYpjlsak=&dA5woQZlkdWZi=&D9ANJWVolhcsn=&oTKfXKWjX_Xra=&7DsgikUlrcVsb=&86bFphZlbhVsi=&UrU7ZJZgfrmZo=&RkRfoIVcYoclm=&nHnKDhU_eddUo=&mDOJWMZXleZcb=&kxIfBMVanjjfr=&3teoq5VXjWedW=&r6f7wyUprmpkb=&_MNmZ8XolaXib=&FP_xISWbpqfVc=&JkRRr5ZpiYYgr=&Sfuk5pZglhcei=&6dywujYUZbhlc=&WAZXItUnjfcih=&WdYxdvXcaossq=&twhqioUXqioXp=&qODx2TUbnhbWj=&htg_7nWUnpiiU=&8sCcaHVonrjVe=&PkXldvZYUhoom=&3qd4PFWUipj_X=&NN6DUNXZlrYjZ=&rDK56eZdqcqqa=&isTlyQXam_ldg=&tXMdG3UdmXcVn=&9NwAJxWrcf_ci=&nJvcuOVWWaYVe=&77lcCbUconVpW=&kb_rtQUgmkgis=&JnXKU8Y_ai_ps=&kHKLwkWcpl_pe=&ZdFMZlYYWXlWi=&SJv7CEVnpUjkr=&V3fz4xXWqmdgm=&PGzyYOZglUsfo=&FbUpMhWmfdeid=&ZvEO4BUZfUr_o=&JEnTodYUmVjhs=&K4aaPhY_jl_rV=&rMs3ewYmZfome=&mtMVc9WaUsiZY=&VCQdlKZlpnhhi=&9KAWltZVmVocc=&3EuRSaWfmYhU_=&vbBoY4UVkbV_o=&DJdFtCYf_XVXY=&oUsTFZXlYWdnq=&GSx5WnXrWdYgo=&PXF7u4WrhWniW=&GiIl9MXkhbriW=&ZJqROKWsapZsk=&iK26OwUfeqmVn=&MseBEIViraV_l=&PXOgI6VZhqken=&nVhJKhZUpq_lj=&6dFWTjUimZejU=&Y3L6eqVebi_VW=&tCWlGaXUVsVpl=&ESBhF2Wrfsccb=&ZDiP66VklgWdh=&KjM9QZUongdkh=&KC5cTpWlUfhpj=&Ct6w9sVcZrqjd=&zNxJYXZjiompX=&A2rHQsZnYelZq=&WgaPSaWcdnYim=&uvO_Y7YUlpXpa=&OgxNUYWnbYXfh=&VGqdqLZgosYeV=&Hf965nX_fZinn=&i3sA39YalqhVs=&iCDu6FZdUeUWq=&_pZUpGYWWhkYZ=&sAwtqhUsYckmf=&MFlXm2XpV_flk=&dgI58IWaimVse=&536HWJVscrlhe=&vhmqb7W_eUaok=&LNaHLXYXeajUU=&g2LSCNWeessee=&siBZkIX__ofVm=&UtqL6EXYlXiZa=&_kBJptUpqbpXf=&ELUmLnUoflkUe=&VFjhIKYqafjgd=&2ArKjsVodkcZb=&WQQFGzXslpgsg=&hb3owZYlkXagY=&UwXaEyV_Zidcp=&oy6hj8YsoXsqe=&BeGp95XWZYhZr=&ZQLk7oVlZrlYc=&3nwxhoUYkgkas=&KuwQC8WVdsnl_=&3sXQycZffrUll=&Oa4Ev_VkWcfkl=&AnIK_yYVkWUpg=&4MllsUUfrqbnq=&oQXC4lYfZlWho=&45lZaKWbVnZVr=&FqEn3mVmdoqng=&eYeDjZWfjalZq=&Y3ZchCZhZV_hk=&VFXkyJVXZmdlk=&aMONgtZXofica=&Y3ORXhZUWceir=&BP7BXRXgkisel=&PE2moyXjYsser=&i98gqpWjo_Wjn=&hHlG7SX_jX_ho=&DlxwZ6YZe_pqY=&8XgI_kUXmjfce=&_XqIi7Up_cdUi=&bZA5ceZdn_ace=&XTNZx8YZnVsnf=&z9iF5rXYdWsWk=&cSQQblUhjkVm_=&I3rJ8iVipZekp=&OZ3ID_VaXWcol=&AXpRURXiVfkoU=&LWtjqLWejsZl_=&yuAYBDZW_kgWi=&uQgqX4WqlmlYd=&wnWA5CZhhVdfg=&33rsYTUhYeeqa=&RzpmJnZdhnloV=&JBeABeYfgoZVb=&QWgqXnWWeljYV=&ODXAvmWVdlqpU=&7CY_c3Zeinndb=&Tz7wQ7ZfXp_bm=&ZZdAptZi_dfZc=&hMaWktUmckYUZ=&dGXybwYY_spaX=&cQ_cSRUeeenfs=&HuMwdvZaXnahg=&D2z6kFUhhrbYs=&lRl_kcZfqfeip=&SEJAqVZUjsYl_=&dQ9H8FWikedbn=&cnAdpZX_hXamU=&b84dQ4UpUpqgo=&udAR2zVfYVeis=&FSJpGUWrfojeZ=&TVF7MLVmnefYm=&A4tocfWrnXacr=&jKrorhVoolqXk=&EuYNQgZekbbYn=&ymAiW2Zhbnoc_=&8QCGjuXZVpgja=&_6WTwJYpjgkU_=&tst2SzWkafkdp=&ZNMZ9lZfij_qm=&tObl_cZffiYf_=&Ffm4OgYoVjjWp=&qsjcSXZoosqmo=&6wkH_LZhhXjWp=&VnQs_cVnfVneW=&4m_mSDUrcd_fW=&GYOJdbXmXbXmY=&lpNVSeVnbbbcq=&MdOTDJWobqfqn=&hve6gAUdprgnk=&yvA8wYVakoZin=&WZwRw_Ulkefep=&OS76heUWffgbW=&IIrKcXXdigrZZ=&emv9V8YbqXqY_=&L7KnDEWUnYlhn=&F6xzPIYW__UlZ=&uFtluiYWfclio=&MbR5U9Wgnqrh_=&XYqNEuWpZnhZg=&kOp_AMZ_WX_jj=&IEvGxNVXfXlch=&8OizIAZgpWrgc=&fQFLT8XlYnrio=&tf6ybqZqsqiYc=&7Kfq4vUsVUdk_=&GYumdvUmlkjhk=&vIxo8jWjbablr=&b6BNwkXjkiZlp=&w2xqbUWqef_XU=&MOpKVQVjeabVV=&JWkp28WbVpkco=&RERp5cYf_hkos=&eWDDxjZkgZkh_=&aKwDKpZsehZme=&I_u4hRXpkkUnj=&HF7iyVWbge_pa=&47QczbXgebpbU=&Waa9olYhikfUY=&ot7RMZWpVhlek=&MbsaVgUfVnkbn=&bYEohVX_VZWgd=&_CnqYvUbiXWUX=&DOOfwvUZhhXai=&nkvUgnUfghspl=&_iIUl5Wjoiklg=&RgjJ7ZXcddejb=&5oD9WXUcdoVr_=&cm9ElEXoUbbYd=&UoswdnVgXVmae=&qX9y8TXnengXm=&D2_cKDZsmhUgk=&HX3vLeYZVXeae=&VIi_JlZbpVbZk=&5GOAl8Ubbfgnb=&S2xw6OVhefoeZ=&UM2l8YXZ_sWlX=&9GDIkaZZ_kaao=&Q3yJPlXafZscV=&fYyFysZrUqo_X=&FzZk4hZmkqeX_=&zzJ3vKUZc_sgm=&9Sj5UxZ_XXhnm=&qIR5fVUiaasoU=&8WMPYcVVnq_eo=&lx66zcYYZWaYd=&GEyyOLUrXdpUc=&j9r_MjXqombZb=&u8IA6oVkq_foZ=&383NrYWUkYXrg=&ybnCoGZhXm_Ym=&ihBHL3UcVeZjs=&YCKgs7Uaorhal=&fj9wmzVagjffW=&YzLGzXYf_dXkY=&bytnMrWspffc_=&lkfMwMZVjjf_k=&BqokfXWd_Xocq=&ZBAAs5U_saZhj=&ghoetYWekogVW=&EckrsYYXrehYh=&zAFpLWVfarnlU=&VM8H_HY_isqlU=&ZH2FUfVhiikZn=&QT4YQeXnhnbfV=&XGfasJZobXbnr=&kGtorTWfUUipi=&pyvgYKYjYYpdk=&PuP89yXdUnXVj=&5liCiNXihg_lm=&qrOJzYXq_Vilh=&mk6IRcVjbWZVa=&feXQuVXYVf_pU=&FII_SXWiXjr_i=&7jZdtYVkWiVVc=&5vfr5EUgYmajf=&228gl2ZYrmXWh=&B6P4_RVaijcXf=&hEHrlTWnmVemq=&3kb6hJVgcXXka=&UIjV9_UplZUdX=&vQKaSHUVU_oYU=&RQvqZSXhopbfb=&Xab5B8WVjZfVk=&SswnwYYXassUf=&Zee72rWdorbZ_=&YugXwxYbpmlce=&ZdcELUZY_dinX=&BMePY8X_olecq=&b3RgeuZYVh_qs=&i5ZjoPZklUjah=&Kzs9cMWZU_ZUa=&jlcBabVhrsl_b=&3IK3fuVcZkiso=&VyRhCmZbWdYXq=&L4L9MwUUXcgol=&avggugUom_hUZ=&ttiRMsXbdjlbo=&uo9Dc3WXVksqc=&OOcPhZUrqilnp=&c4zq9bW_kVqjW=&Jb9ozXWdraing=&IDYwebVUnWVbd=&MT6yfKZnrgVWs=&PLQyWuWoqlYaW=&cCGInVUZq_bUj=&VVP2XEYeUrlfl=&yAxv7CXdsWidW=&B5kyczZrVVhln=&QYudxkVedcbsc=&sx8QE2Ylg_kpU=&6syWQsUehcqhY=&Hztbi5Xos_aem=&ktXyo3ZVmfnWf=&y2JqnEZUepgcs=&fYNtMuYpqlrql=&OTRDoBZZoVrjc=&W6rB99XgiZlXU=&FPMYJpZoddjgh=&G3SCKBXgVX_ml=&EUUci_XfsqrnV=&XGOzXVWamclqW=&Af_yOIZcmZYaq=&FeAxoQUgriasm=&AFMOIeXiXiXgn=&mc_ht6XefknZY=&Gmrt9hVVYioWi=&KQGmSgVlo_i_V=&FdiBqCYffinin=&pgKtU5VkcnheW=&6H2IsEYskejsr=&A6fYvWXkfjVei=&XjmuvLWZnjpVo=&XA_SgoXidejip=&WnmHlnZnUUkUl=&fhJXWdXcWgsji=&2tgKKaWbssiYq=&BgaZOrYgkfZlV=&SjrnAhZpcnZd_=&DapSaNVsVYqVl=&oCaNapYflaYpc=&9sCc4TXYWbdjf=&SHi3XpUsqcmaU=&i4Z8VyXkbYgbk=&TbQsp8UsesfZr=&LybK3_XhoUloU=&Bo7RTIWdWkmhs=&hgkKFHVcUhcph=&4NTWkEVVUgoYm=&oQ8dqxYZhXcZW=&r8Z4srUgnlcpV=&NaHJ9iZgVesiq=&uJnOtoYshemmb=&HXq5DUYgmdnka=&PhRJ43U_kllck=&BMvN6BYcsmeai=&95ajJXYqhqZdX=&JTpBHpUeoche_=&qjnIRJVXUmjrh=&pTKnK5WYkUaVl=&safFnGUkebYfa=&FfQbHGWWaaWWj=&7h9aopYsrhkWp=&RP_CzQVgrfhcs=&STpdeMX_aZmWa=&rE_ZjEUZjmeag=&yjsnNoYZZXddf=&IMZwkpUsgjinf=&dlzSiaZ_ceYXY=&T4S3GtY_Whosb=&qQvVdDYdciYqc=&Xi47hzVYsrdig=&Mm2aRaVhqeZlp=&IHOzMUZqWka_U=&iFIQihZgWjqVc=&PdqmQGYXlfnZe=&4QdtMjWboXVpr=&DZgvAVXgWXhUq=&23P7hnYXj_ekb=&hktkkEUrhmcfs=&WbgfuMWqZXdZj=&aah4SmZfmUnjp=&ESYimmXhgYq_h=&SVoqgbUgpUhgp=&KBcFS5ZUaVlhb=&E9MtwxXiqZenY=&nefqqDUi_qfiX=&irssXqZfsblal=&iNRvSfYcllgsl=&w4FnIYVibrXlf=&hA4twyZVjYaba=&TCF8WNVoodYfm=&FvdsBpWdVfYhs=&qFU8T9XqjkVd_=&5oYvumXlh_jhr=&bEuKdFWfpUZgV=&GpyGULZdpUq_e=&TxhUHcWciUohW=&zNKiF2ZlqXVVq=&HExb_hUmce_bg=&Fa2LwjUosUYmr=&UcvEH_YhoVdcc=&kRt7q2UVaoqhk=&VlNCMmVjraion=&cE_5KJVZoqVpq=&vq3RVeXqomqmV=&FNBqKMVp_lhhZ=&crLhkRWajXZdn=&jw8uxgUU_cbnc=&dhw66OW_barXc=&rThbInZmZ_soo=&ob9H7gYlWcmca=&ODcpS6XjkrgXi=&i3kLOmXhgorV_=&f5tdyVVkfY_kj=&8kvnf4X_UasWj=&3kU84gVgjrfXs=&PzgMDNZrjknZY=&F3hotbXgVdeWk=&i2nxy_Vrkkdgr=&dlToWoZrc_dZ_=&QF3uHxWmffWgg=&4OgV_eZWngrsa=&lkfljyUiionpj=&R4YVweZg_eeVk=&U6cIVbVVpgimh=&D9cNpQZUcndda=&Ltyg2VZUieXbU=&Wz3p4_YcdaUqh=&WosLOUXpeo_oc=&nRSE6FZ_fdXXc=&Zd_zt7XsV__dk=&wiMdfpUbohfVc=&KYJGoSWhWmafU=&SCSmmZWlesmdk=&7mpvPMUVjVnYk=&8nAjGqWYXlYZZ=&tN6cHuVncnogi=&IteahPVjdgZoU=&TAcO7JXnZnhiq=&mVAm2vZXVmUZm=&JQzZaTVmWWmig=&ymK7qTUsgqhro=&RUukG9WaWUoki=&Fe4mEOVfXfXnp=&zBJVdvVbhVXpr=&dvga_xYgpaYrW=&R3kzMaVdmXpjq=&hzWy7nXfXakiZ=&nfsTAwVfchfaY=&VcdnxZWqYdcrg=&uvOIqHYsVZVoc=&pgWJYDZWnimlf=&gZyL5AVUmmolh=&UjjvD8UemYheh=&7BgKMAZjiWokW=&SnF9QsWfmkngp=&KRXrGFYqijahZ=&I_JMoeZmYZZdg=&XClTpBVX_UYpn=&5mLcGbXWZph_p=&JyMGylYUbbkdk=&S9BZQEXVWUcgl=&_7wH2BYsareha=&jLzq5BWhdZhon=&NbT_8aYdfgnbb=&xiXmyBYVcigZ_=&LWOpSSYYVdpUY=&gJTfjcYacmbph=&TdTlaRVV_rcps=&ifTm4kWjXcocY=&prvz6EXhqkiYi=&xzGB_bVeoXsgf=&O_TJieZboe_rm=&xS57vWWpqsWUq=&WluxljWVroWmb=&aKvOWKVonidrs=&R3P7I5ZbYiakp=&9dgeeLZalfZYj=&XsGDRzVWmhZqm=&dw8C7EXhWmUja=&haspNNWZoospp=&hqpQgmZsrmqlY=&pgnRlDZUebdjk=&yYnD2UZbnaVsk=&Jx5oMMXbim_pa=&kWsDV8VYmVhqn=&kWJB2AZlkVVZn=&oO6C2_Zoc_sqc=&x85YkwVjpabUb=&FxWnlwXUVVmca=&WjhslhXVfVbrr=&6DiTBDWZjYdeh=&3YsJ4qUqcVmpf=&tNVvUpZdXVlep=&xXen8yZhVfnWk=&KVT5oWVmZkVmm=&NC8xwkXgoheio=&OrqDHAZdWsXlc=&vW2YHnYgn_UXj=&H6lj6BZblcmcg=&B3iGOTZhniVmn=&A3BpjYYmbjdkl=&zESpanZeqoopY=&4ooSEiXf_Upsd=&wYfwIhYfipjbX=&5VVmb9YjUXhUj=&OdrtVhZs_aWip=<NOuFXscpeqh=&bfkKczYV_VerV=&O8NsxgUmhg_fU=&VdtfH2Ydf_nke=&vqt76dXbjdfjn=&ZCT5LOW_XkiZs=&tLsI3VWceknbq=&RAtHH5ZaooVmh=&o6eZ9qVepbfoX=&MGHadyWe_gjWe=&XPcE8BXrscbsY=&IXAdluYecjWUf=&V6TQHTUnWWdsk=&tNcsedZUlb_rg=&5i85ZJYqeolZk=&MmBw3UYZgYfnl=&hBmSPgVZgsnsf=&M5E5QiVakmilZ=&fc7_bXXfV_nki=&DNdBlmVXaqibn=&Sb5gllUbYaqih=&e_5HJ9Vn_crjj=&iyCFsnVoYpndn=&U44oUHW_dodoe=&g5Zf6gWhkqqZe=&7cvJg_Upgadfi=&24NnyYZjcessn=&lhcPjDUrjonVg=&dyM6vAYqWmkqW=&XrD_i4VeperjV=&Eh6VqGXbbbXmr=&AeTD93XpeadXp=&spD8XbWsqcjsl=&tFY7BrYerekXf=&yFKfobYohbjgb=&WNfPpUWWUfqoo=&WFCusiYZemdXn=&tv9Cq3YoYdjYX=&5Ia2skUglsUkf=&kpoXynWhofZZe=&6NlFGPUUUUVqp=&crE4LeWXYndrU=&fsBgD7YmUqnbc=&r5vEN6W_idXlk=&mChSkiUWZcgro=&LvS8QzVlqeWfk=&NWCpCdVhjpomg=&TtFQLvUrcqUkp=&_4bKdQWVnmhoj=&ygxFKgZmeYhUf=&nOU2CVZdrfibb=&7l8iF2XjjqWiW=&OPDJteWckVhfg=&bflnt2ZqoUeaW=&LucJFCWqagYbp=&Qsh3vRUlfaqlp=&JYZUdNZoUqejd=&iM5pmsZpWrecn=&modsnBWlgjrhm=&XNDCGXZngYeWX=&hrDe3jZWdZlor=&ygvdcBYWrmYWl=&t2FYW5Xffanmq=&w5MwkqZqc_s_g=&xOViPdWiXpfgc=&TWGBOjYdnbcVe=&d7Y65JUVmlpjY=&Gc4NCiXWnrZon=&WK28v5ZiqlYVZ=&SJEFqgZbrkWse=&GZzsJuYioqrgX=&ABIy2PYikZnVp=&2RU7oHVnecYse=&y3rwysYlUesil=&hZFSjgZfXljco=&BAY49CXsZdkld=&d4Z9kJVoahrrh=&g2r3_bXUpZYkb=&YRnbYHZoddWUi=&K9O69bYolUffW=&BFJ_Q5ZeeXsoq=&N8xDhBXokroVo=&h7plF8YVfg_i_=&tmDZkVZmnbaoi=&btqglNYXZsWch=&Z5_qG4Z_YosZV=&DCvXtiUbXVcnf=&2vZp9_YefhZao=&cxRT6oYWZccq_=&PQssoMXdhsYmd=&VTqk7xXsqjdgj=&IuhTuFWc_egWe=&rScCXvXmVnone=&H83st4VrZVprd=&zQADyjYiiklkV=&O4OPhmYeVUYne=&NLHRfvXqriif_=&4z7_jAVfqsekW=&iIY9YYUVrkZga=&Vw3_tlXsmqXfl=&mUe6iWVkWkYdU=&KSqlGqXdhoepe=&DED6UEUfZrjie=&Ks3Fc9Wohflmb=&mb_t7hVjcqaZp=&H_fpIOVnhkpWc=&f_aIN3UWdU_rf=&Z2z6n3Wqqqceo=&K2GLjoZqWWcfe=&DI_MHTXmokmif=&Se7EQiUiUkecZ=&TCWwDVZdniosd=&Wt8EAmYqjnUWn=&ssIVQiVUXsZkj=&7keNO7Ujm_VXh=&wdJl8EWYgYdfl=&LASLLVVnjmdgp=&uDX6USUondccU=&KwNVpGVa_koWd=&UZS3z5YWsndZi=&PW4IrKVhjkkXo=&aklBo7YZX_WUh=&Q6zi4VWpXrVhU=&PKAiE2Xq_ldjV=&C7dZ7NVWoZUgY=&MUPTvAZfpX__e=&E6gOJJXjchWUh=&joTtx5UsXabWX=&W8Q2ffXsaneqp=&MQjMx3VjrWYrn=&zIW9iYU_hkqVm=&AoZyRVXidpne_=&gMxVTbVbegin_=&R_k7MKYXingdr=&WcyaZ6YWfaie_=&yNRwDgVinnh_a=&LwGmoVYkUnhaV=&pKiBc3UmldXsi=&s6naEAUsoXVUr=&QnezvJWiVljmk=&pWaRv8UlbibgW=&pnyrHqW_bUVon=&hCKAr2YlUWrbp=&VONArqUaWsjsV=&gXzRSAWoddUnb=&nG_MdFUoooZil=&GaxLFGZaeVYiq=&4Y9rLsUeeanif=&jZjBPFUWfhZbd=&dvx4mxY_ijksb=&xcpgUuYenmahn=&jfcvPNYZYWhrp=&Bk4yucWbWemfh=&EtNHANXbaUjmq=&2nm6uQVrfknkY=&mO6oHiVaUUnbU=&Xx2NbhXmgUrZg=&q8GOeVXrVWinZ=&zHp6cAXWfjsfb=&yUd7ZDUrlbkUp=&v4dCWIVZbcnnn=&sHlqIWVearbrr=&vlHajJXqZYsUc=&iGjSVwYerUrrq=&wTgG62Zrsnmpi=&jbG7DdVrsir_a=&Kfg5dcVhisirg=&xmcM7tXngVapj=&hLqPgSV_Zej_r=&sJDIbYVqr_fUd=&z6Kop9YrbkkWq=&3VPKulZYlqWqm=&SKMzkuWsdeikh=&LDuVh5Ujikojr=&GkfiPMVooejil=&5feersWpVZhcd=&H3iac4Umrqeii=&Oo8wygYagkhhs=&vqxE9RWom_mld=&dKGNvGWibXmUi=&sGMsJ4Ubh_Z_g=&AJdvd7U_ahjds=&LnnuH6WaqpiYj=&ZkvLVvYeofUYh=&jbUZVlUrXcqgk=&eGoSQBUmVbkZd=&qBkQ6LYfmVdYr=&ENoYXaVrlmUqo=&PGSyHyXXiWccV=&yYnkgzZnU_npj=&4hOjMDYmfbqnm=&c4ZdcyYWencgV=&9UJajIWmZYeea=&hl2A3rXppakYc=&2QTWtTX_Xs_hg=&x3a5fHZrnqdbd=&8AxSQhWropXYr=&bacw9nYWrcrlk=&PAJnkhUpchekr=&u63bcuVXYejss=&rc4vGZZjdajkn=&3NNjXhVcqbUfp=&dPLuVvXfgkemi=&LPoPKxWrYnagb=&Vn9VFxYjUjgYY=&Qf3_hrWcdhUVV=&v3Et_VXWcplfc=&rq4auKZssnkpU=&MkurSsVfprnVo=&YTG8OAWhdVZUV=&yZdmwPYYVerpj=&mhfPjQVZriWgq=&n5g3ujWVeraYf=&hLrD8lVWVbq__=&8eK5u4WnYchgp=&ZHdGUwVrjZfcV=&daN3CcXihY_ba=&efYiSZUiViYjj=&pk6J7eWVqmdcq=&y_IIokWXfamnY=&GPUBk3VUqqZXU=&g87b8JZshsfoU=&t_ZkTnZkgnU_r=&AZpLNLYaZnjdc=&zyCHzoUoWgmYi=&6kDmp3Uroranh=&RaySsNXafdgXV=&ANjkqiUijklpY=&cyirXEUlhbbj_=&AxzjKMY_Zaqqp=&ZkYvGrUZkWjic=&4ENtU4YfWlpac=&qbtEwaUYoasaj=&CIammiU_Yadoe=&eASFaGXf_YaUk=&YgWt8GVbimr_q=&Eck4tLXbnjo_o=&SNviV7ZqeXWgc=&ykDdOoZcejles=&E_8LIxXXbYbjV=&H6bnNbVYokams=&KGJ_D6YXkssdU=&rijqLcXqoomsn=&4vsFlxYdbecci=&gYHw4pVVbVYfX=&vqMgl2WqiUZbc=&tK4LSRVs_noej=&BQizuYWjskojd=&b8Bo38Vaqmlda=&RQPzw9Yqss_qo=&KVf7YgVYrUWUh=&m2LbW8YifXah_=&VcAtHoWcgrkr_=&7mnVBOYpWhfnU=&_wVXnvZkXUhkm=&8rwsAvXkjlpfp=&OeorD4VoiWdhn=&foOZMLZphUf_i=&xpXBoTZerhZbj=&USYhZqUonhi_h=&wvgR_7YesaVpp=&cXRnhsVshiUfe=&hdlFrTZrWidg_=&cqXomjYjmWhZi=&lW5H_8VhhWbjZ=&FeRfcnWpirXce=&sbhhydVnXioes=&jKfud8ZqnphVe=&ds9fWiXgoqYjj=&Eo74SaZlUeckY=&6hCIwkWYphVnX=&p4xlxwVbkjibU=&rZcxQ7WrskdmY=&UmUObQYdleqXf=&jhe_uxUerndif=&7gzAFGUoeVnds=&MDUkAYXjkmejX=&NmsnJtZbZrqiV=&Z6W6LBWZYXcbl=&ZrMm5wXnkihXX=&rlfzLMVpYblYY=&Z8wS8wZjsYYjZ=&7o787HXlZne_f=&gyAqG8Xkgkgif=&h_dbW8Vdh_XUr=&WsJOHhYpjafdg=&7XsdWKYUkUokb=&xl6JiiVlYpsmi=&tKAEqfZUfkYpa=&9umsmoYcacVoc=&BsxJNoV_kVWid=&sKCUjFWmdoVmX=&3b47_PUojpiqe=&uQ5N52ZiVgYgZ=&M46_dFUmnrhmm=&tbQgXOVsZZfkW=&PpdjeJZaXiseo=&JJ55HWV_jXnfX=&65_9uAZhaZZUa=&PfeQdrUZfZhrm=&QXIBDtYXVaYje=&SnUbTpZhemsfg=&P4sREUZhknleW=&kXEpmEVnsgVgg=&wpCxOQWdUYkeU=&r48uQcXksdhoV=&7PLe_xYaWZpcc=&EI93bfVrdbfrb=&CYLeJbWhqZpZe=&PU5FOfYnYVVfi=&JtsDqEZnUXUjU=&RRhwwqUneZnrU=&ytHgqaXZrcbUj=&ZpohwEYalqdcc=&cQtNwHUjcmsji=&RfuOt_ZprVhkp=&_8lqfbUnjZekc=&zAwYe4WaYrmZb=&3MeVRDUhVfU_d=&hWm6GCUdsokao=&KfMDLTUhqoagk=&sChVivWYkocoW=&IqNXdlVlVlcYV=&sSzobcVrbZZeo=&w3fWt5VsqirnY=&LrCmX3YkUakXp=&P6aE_gWscre_q=&7yZoawZsggarq=&stFxvuZjqfhYb=&3Ae2PnYhb_kXl=&QDqmWHYoYkepm=&AUy_YBVns_Yck=&KQvxH5Uqqrkjk=&v_aiHrW_jkofU=&vsW3OVWgdbYUd=&AZVf8nUmjdpql=&3axoxdXUopddi=&Y7ZDcxYpmkjnp=&BfI8bJWrkqrsW=&tFW8bHXZjeWib=&UdixXoZYhbVse=&4lIQ4eVcihhap=&PapDPmXqWXgVe=&Fc8KzQYmjj_nd=&a9yysrZYZscbh=&CYujcqVlacjef=&ZOyEvdW_ppgak=&ANOf2vXsn_oXW=&ADBpgfYfYpiUZ=&WAZhIjYiZrcme=&aG2EE5Ygekn_h=&ToPqGbYorfVpU=&FF4ovJYnVeUXp=&RWbpsKYcocbjk=&e3zToVYbneqog=&9nHoomUgbcZmZ=&2FV3VnYspediW=&jvJ6MtVddVUlp=&t6wtPnV_ikfhd=&_sByTVW_r_Xko=&nSJSN4VjpqWco=&SS7tJtWU_aiZr=&RjHDUYZgiUnli=&ZSXmjqZYhgakW=&ydkqWaVbshgds=&j2acyXYbWeb_W=&qzxkJXWXjahma=&W4CDeLZUmhbYl=&mEkD6vYfhepqV=&ISmPYmYUicagW=&jP9RWyXpUW_Zp=&8KApTqVYjkq_k=&FZEDtVXsspjb_=&UtlobUZkmdbcX=&CNOIg2Wfnlpjq=&XnDoIhWqike_p=&ykNckgVbidbdf=&4yiXVAWgmppVr=&6hedHzZVXcrVh=&7TX8a8WkUdjah=&DfUYf_WYXXgma=&vNiuHJZbbsmbn=&9FRNMVYrfoecl=&kYTBtxXkmsrYZ=&fOnQcVYeigdih=&mXa4slUpoXdXi=&9ysqMDZndWarg=&IW8ZKyZrrhhfd=&UhJEqcYsgfoqU=&QJckGUYZdeaXb=&qaskXzUqorVer=&2oiy84YZan_rd=&Th8KoEUZhdmfq=&qppBbLW_kZjgi=&HCyoaoVYiUjsq=&YDNqyyWcmqrpV=&IapfKDWUggpra=&5opjEJYYVnanX=&DWWjwUXcjpabp=&Xj2Dz6Zdajphe=&or2XolYWWsaZs=&M6A5O9Zqfrsqb=&2KM6ZrVeYXZmU=&ALMkEoUfVkiU_=&ncrVwpXYlollp=&aFKDayWnibcXU=&RDxywAYYXfmnf=&cTs4HWWmpqrll=&dXRrgEYaXVmZ_=&ckmYRlXiiWVYj=&Wr_sgKVaZbneW=&g3VWShZVegUin=&2re3a3Wjagskk=&ZkyBTbUVfheUU=&4xeBCCUaZfgmY=&2f8CHVUclXssa=&avocEGUhYmgrW=&GmIWCJZa_UXke=&5qZfdwZlmVahW=&YmQjfUYUVesjX=&KTqniLUeYrjsU=&lzZ9evWYqeajW=&m2THYJXZnXfak=&UMHc67VrcoZso=&rktBe6WkscikX=&KO4S2iWoZkUdl=&dltWcFZoVXnrc=&w3TlRwXhrnnsd=&5bi7xpUXkksZW=&3vavr4XXiqbke=&ykVKkgWiUafpe=&wAzZT5YsgUiUY=&OEUbvgUaagXW_=&7AtdCYYWe_Zgo=&k3RJuCVmfjbab=&wW8TxBVkajpYg=&dR8L7qWUdkend=&p6l5YGUhplkgb=&_XgRAtXsiogfq=&gpimrBXVkbVaW=&znO4gKVW_mZfr=&8KOYhyVVUbher=&taHJs3U_cXsZo=&dUKq8oZnZsWom=&EIa4NbVpiXWri=&p3bIunYammfba=&HoIQsdWamp_ck=&2EnwSlXjhgon_=&ax5TZkViiYedc=&tzPi2IXpansWY=&22fyYOVmnnWor=&exK7CGWVh_Zpi=&isBl9QVZYrfUr=&AVxWoFUsWaZWj=&XezPbbUUkUdjm=&q4fnaBXiYocis=&Niu7vUXZhXWYj=&3e4QBTWZes_hU=&VfxRS7Zr_rqWY=&xf3rBRUZeeXbf=&5RdaTPZignoh_=&5LJW4cYVoeXbj=&57x85SZohfnWV=&cpkMjhYfjfaWf=&L7oBuOYsfbseZ=&ct8tpxVcemZXb=&bwUiR5Vhgfhsb=&G96Ma9XoZnUrc=&vl5eFTYVWVXdV=&nhp3aDXZqXoWk=&vVhPiwVqmVsef=&xmRE9EVWmXr_g=&uSdIhtZqcj_ks=&7BbpEnUklkYUm=&KQdxDEW_qnqdm=&Jy9FRsUmchcrc=&z79RPtXeXjbhY=&7Imf4BXmre_YU=&7cGGU9ZrXampn=&LeIfwYUpUnjVr=&XPrAU4XoiWhkh=&46xRrQYWiemWY=&_5AuOmVdiqmVa=&gncOFwXmors_b=&2tjeJRWsgdjYg=&PPvHEiUUmaWcp=&ACKPsXYodckcs=&RizqAxZieWdkg=&3GQGguZoYmedZ=&El7GI9Un_qbbl=&LqWA6oXabgsb_=&rRRBwIYhjkkXY=&2MXPv6Zjarhio=&ZQdDy2ZeoWdle=&dfA8XhUsnZWcY=&JSAF5vVXhfcoU=&dh9cq7Unblder=&Dua9wvVmXrref=&3apyPKZWYYsVl=&bjd_46Wd_dgXb=&CEJ3AeUWihpe_=&uwFrjtVdWUrs_=&OZTDLEXm_dikj=&DSCv3vYpolffs=&4YeUXAWfjclqe=&txUUYuWpiidap=&WJEpX_ZWUekWX=&D25qXlWhs_Wsq=&DOdIPQUckkl_l=&I7XQvWZYearjU=&ApC2nWVXpsdeg=&IrHLrqZdWZWlh=&K5CHYpXcVr_qY=&JB7a_3XZ_Wggj=&y7hvYBZWVZbkY=&TQpRTfXdnqkbq=&kliM9sX_el_pX=&m_ZmVAY_oiegl=&jkIZYGUoplqZY=&nWvecMZgjqsli=&sL64h9Ysjhgob=&i_yPB8Wbhikec=&FbhtbZZrZjUcp=&FOeAQaVV_aiqY=&2D4vZHZUanVdr=&MTlMnGXl_qlXm=&KhXgjCXordUgZ=&B99OGHXkjqmdY=&E7Fr4rUZkjZ__=&tAgTsjZeZgabd=&IKNj84WfsZYXi=&ZDQOFEYbkVqUY=&7xBTMzVkdham_=&2s4tekYhnjqgb=&GZu3ldUkmjWnm=&bUh5vOWf_esj_=&4d972EXpijcn_=&j39YLPYnrksoq=&lz8yJlYWkU_qe=&3AlX6SXWjflrr=&zGvesMZlmjcso=&tsddutY_paikq=&WpbZABZasWsnr=&anaEpZWegrV_W=&OTGPkZWpes_gf=&OUWajtU_ZUbbY=&bykPhEZ_fapWZ=&wxcWcAZYWcqah=&fMUZY_Ubbfjqd=&YqznKBVphmYdg=&DvNJanUlWhbfa=&z9rxuTXqcUfrU=&CvjUYJWhlrWir=&qcrvRoZga_kYf=&ekAXmhWVlflZY=&HQbpzBYrXabkd=&WwbJvOUsqcorn=&_elLptUYeVZfe=&WU7pDmXjZijn_=&ssCeqzYgmgojh=&H7lkuiYUYeagj=&GvNnhRVeVeeUa=&44wsN_UmlmjdZ=&FVQ4XXXXWhrfr=&haVe2AVdZaXVd=&syGrdvUqnjkYc=&w2s49lZdVjcUY=&6nB7VJWfVbUjk=&lcYyXuWn_gepX=&qMvmOzVjq_Ulq=&SR_fg3UgUrrqZ=&qT3SKyXXeUZqr=&V9vyAaYajq_Xh=&Uf76NbUhlcYp_=&x2Xt8mYpWlZri=&D3CD64XefYhss=&BVOo4dVUgpfrr=&cWVKbuZjdagea=&Dj4KVXYlVqmnh=&qDnxWmWVZnlfZ=&qtW72xVjXdghd=&xPBHmlWpi_rVj=&JAIFmGXifpU_m=&vRxNUrXfVleqY=&muycQJYnXhg_b=&asZTz9XeflZmk=&x8FBEQYWYXcYU=&gTeRA5VVlpmnm=<Hhl5VicmXXh=&evLUEnVakfakm=&SZI_bHXebdnsq=&O6aLY2YXcrsdd=&OqG6k2XkVfcZl=&ssf9SyVlcWdqj=&6HrKfVWfgX_Vl=&saCibjYYaZqdb=&ZUlAN2Zdqgqkh=&uvyjZJWskrmrd=&h4ACqlVo_rsnj=&rFCUuDUcppdkd=&jiPca7WXohZmo=&H7uP4kZlnpWrj=&mjxwqXWrVjfhn=&jGF8LnZgYqWib=&IHZYbMVqckbmq=&Ji3eKcUcnY_if=&E4uvbqXfrXlqr=&l5kjTcWWdqnYi=&ZUD5JpYqUVXcp=&I_neCQYgsbcYh=&QZKNXoWskcYYq=&wZ9rsSZXZqioq=&h7VqWcY_Uidhn=&StE9VqYX_sqYe=&zN72xjXUr_rre=&EbiUqaXVkcZ_n=&j53Rc4UkcmjZe=&U3376zUrjsVXh=&r9hz8CVql_Zoa=&3zAFX_WibiW_n=&d5SlZUUirhkqo=&PWSqVIZhsahio=&epjOW8VYaVoaU=&PtLUqLVXdsecq=&ZkaJqCUfmXpoa=&CRAhMZXpVWcqd=&9wb2LJVspofc_=&3mZobJYooXbcq=&KiyGp5VejnrVb=&d6pkb8Vgjmqgg=&wpQjngYX_Yckf=&Lh86nVVUikVel=&A_mHRlYqjWXe_=&vkhxqUXjXcaVU=&6MG98RYUienah=&pWpjmaZ_pZcd_=&xrxObdUdpmsag=&t48tP_ZYrpdYW=&QnvmpaVUUlUkk=&l_ucxcUpZnkak=&L2bvbuXan_scq=&nPz7GOVi_osiZ=&LCk8KZVrUgV_d=&_tfWvnWfmp_do=&rAQuIhWYseWen=&Hgay4_ZcWbZaW=&qegzhGZhqchaY=&E8VYb3W_Xsmlc=&3Q3_TDViYhdeW=&LbdV8qWnfXehg=&pCfADNZ_bdZba=&labNp8VaqpVsj=&wLHSJFVkVpiea=&AskZXDZgrrcWh=&gw4sWqUbVnlUq=&cLb4kiZcoagnU=&rkNw9vWqrsVa_=&iRKq6gZUhjZhe=&P35YbKYVfsVYW=&ZM3XBhXU_WXYn=&HVVyX7WUebpYn=&Z5xJbWYecZ_oo=&DWGusUYWfs_en=&2H8BihWghsXqm=&s6LMzDZfnrbmc=&MXn5eFUVo_Ybg=&GayFWwYegeZfW=&oWrjcVZcbeUae=&EpHQtEYWmphYq=&CXVo4dZfZWinf=&p4pTI7ZVgdqUm=&wOh5DfXkakYhm=&6nGTLEXjrlafi=&m6TiAfWnsnrli=&hzcQVuZccpcWc=&Pm4_NvUakrlfW=&plaSGQXYXccoj=&aFkxZsYWXrfh_=&jJweBVUlYgVYd=&5DLry_XqnUqnr=&TSAeTbWaWVjeo=&qujwUlXoUgd_f=&oh7_QnZaenUbU=&tNn4njUehUfjW=&EJyAdHXpoUfps=&tQJ6ewYmYsege=&oiZFE_XUcmXnW=&SVpuIwWnYf_Uj=&75_zEAYolernZ=&tJ9V7RUsm_WXY=&8gAW7XZlsZdj_=&p2t9dSWhasqjl=&9J3OrAU_kVpmh=&rfX3D4VYsYnsg=&J6wLhgWdnoZes=&ArxKoBWWronll=&olBcm4UdVeZor=&5jVOjuUVqWmmZ=&qdSWqUVhUoXZc=&ypbVDbWgegZZU=&7LckmgXcZpsed=&CWTvS_XfaUqer=&aJ8AZhVgdcofa=&gsYRUOUhpXWYV=&kTJWPjVXeg_cr=&IkJ9jSUfkkarV=&3kXZmgZcbqYan=&LiKgmmWsmjkef=&9T7Ae6Xodljch=&JaD2AvUsUjViZ=&yoOGoCWqqqiZg=&yN435EZiUpboU=&bACKqYWaYsjgj=&5XO73KWVgfkfV=&uRV6t7Vg__cqY=&vVh4UvZ_sq_Yd=&8DA4GjU_q_hYe=&OcO2zIVgjemml=&vqw_fnYenXecY=&9tkmUAVsWpmZf=&EOkjP8XhcYdVc=&YQYSJIZWahYZp=&OANAwBZmpXhYV=&yxWI2MZVpcjjU=&6VxVtRXWkdkVY=&gGD8NOWgUaqYs=&bYi3m7X_Uod_a=&buP3wPWZbWXjs=&XsKioWYnkmfiU=&tYaoKjVdksWgr=&oSM49VXUfnlni=&YXoRmMUdedlpn=&YcSQTHWeWliVf=&OyR29CUUpaVgp=&cYzY6bUVnXjlh=&b3Cwv9Yqhelbm=&P9FOYBZjcfbfl=&CGz4plUXir_fg=&reyhP9WeaccWi=&MzDyBdXVWeZcs=&KRHLQ3Wbbrile=&blqyWUZsXheUc=&cv8rejUsfcWeU=&qTz2pUYqigqpo=&XAtpM9YWUkdfa=&ORIUHYVqpmiZc=&MDktIjYXbdnes=&chs4ZrWpfmaWn=&Ui3oNzZshXrjW=&Q3ug5WWdaYqhl=&mzBYjCXfbmXsk=&c_fxI5UilYUkk=&9gkzMmUnlrofm=&VTfdsZVgUjrdU=&BTQPcQUokWWbj=&SsDjErZebUraZ=&PDGqW9XVe_bjZ=&TjMv4fWcjailq=&UA59JZUeWYbYc=&E5SPOzUcjYqUs=&iL8eciYWmkhmq=&p6ip4TXejWYZb=&yJYYcqYpcs_rs=&KrdcvQXaoopaU=&BsZzmFWqndqfi=&89VXoLYWdeWik=&gA2iiCXZdXZkl=&kealVGUYejoak=&pWJ4tRXk_eYoX=&6zfZQoXblUnsh=&4qSZs8We_eVgh=&h26CcbYosYZgY=&GrTIyvXogqm_j=&TUNqOyYljpsbp=&ruwY7OU_grXbV=&BWnG3rZpngihU=&rIDSyEWsVdppV=&l69BKQUnWWoUr=&xVjTWlWYedqZa=&q5aF4gYXiYsfX=&zhdJriXYinVYn=&CZ_scCUsopdkk=&jTydDaYrbqrce=&_wbJcIUqkfmis=&PrwYneZXekhUf=&vDgmLQZYeljZi=&pusiCJU_keWir=&eYHE42Ygefskp=&G_cyWgWsni_o_=&lzrxfTWoWmfVZ=&hrgMDnUgqmdmk=&3Ymad_VY_laUs=&N5Mh2PZdpjqkX=&tgXlRVZWbl_lY=&Yv4fAGVjfdYYa=&Oh7STRUUqWonr=&wk9RY3ZbbdYXj=&sIlBRMYlYebpn=&REBHOPZZagrdl=&malziOV_qgmrf=&uoJzZLUalYfZc=&fGgChKUodUksm=&PcsmFQUYkefoY=&UEAMydXXg_nZe=&YjMgL_UeUqXdp=&2RA5AnZdshaha=&sAwdwIWlrqWei=&p_kRUqUabXpca=&GjdUtPWpckmca=&bhYexSUceZjss=&yjgYL2Xnfqhfb=&wtbNPcWjkjelo=&OBnqSbWsnUeli=&piwqQbXUkUdbc=&dYvo5sUcYmbjp=&zX2o8DWcjejmk=&MDgSGoXo_a_ZY=&87WABoZccmege=&Jat8s9VjjdXeV=&BXB2d4Wpjc_or=&8GdAuqXfnYn_l=&RlWTOYWnVciXn=&cjFIbyUrdgUqW=&artSYkWUcW_gV=&SopwfLWmVqbcU=&Se5iZXXVbsmff=&Ji39omZjinYjc=&yJb5V9VoYeYVc=&Xzq5OWYWXWfrq=&oO7G7qWrjVg_c=&LkP9MIX_WkjgV=&6UFusBVYoVapp=&Dqnhk3ZpZnhjU=&4PAn4zWqifiVm=&zQghqzXYig_oj=&vHFx43XcUZdaj=&4xoYnWVbhifZr=&sOrY6xZckjWgW=&MHV7YXUqbWiqn=&gHkQvGZVfiWic=&iTclaBY_qgoea=&BouZImWna_YkW=&Uil9jTXrhadqe=&hJrCHKVkmsdpW=&GUoQSpXlZeqeZ=&xchMNQZYijlqr=&H559c_ZZlceUn=&4pUAgfWfaj_lf=&3Am6U4Zbodlkl=&8UR6G6YZsbqbk=&gqZgl3WrqjZfX=&wC2pdMYXZcZpk=&XvqHn_XVcXdVe=&9hT66uW__kVpX=&sq6iDlWaqpWmr=&Hx3R2BWcmjrqa=&eEleHsUfkbYfs=&ajvC2DZjZqhef=&Su9u5FZ_kYWns=&mqZCe6VUoaojd=&Nb5pPyUcqaoYZ=&mhdOzPWbblcqY=&3HS4jrXUkcaVb=&mhFMzlWajsYqY=&zXxos2YdjqfUo=&okmkW2ZVVocUV=&OpJeZ4VYehqgl=&s2E2mdXYpdgoZ=&kZiLlRZUmjYrc=<5oRoZshXVnZ=&c3ziKyVphWrdb=&m9lzMfVlncpoW=&sn6ILWYqVdfre=&93WP35ZrXkYmn=&H8FZ8tYmVUlij=&LAQKVvXcnpeXi=&DlSM7SYikmhkm=&rnmGcRWlr_Ygo=&fIAqZrWqnkqZe=&F2AjRAVdVepWb=&uD9ORAVqYdgcp=&SfAzgzZZolnW_=&hKAev9ZVomneU=&XkjkVVUpl_qdo=&qhRFkRXbbYdXa=&miPeuWZiWneao=&dgZVWMWhbb_cd=&3GTHcUXqe_Zer=&AM7EBIVbiYmWa=&3bgrWvWW_jVW_=&IDjdQFVrWa_bm=&9zJBjPZnfWZae=&zrwuTLVsdeone=&iiqjBsUdmUWUY=&LQTE_lZYgdpen=&gpDrL7YXmsclj=&Mjvxj4Vankkdd=&on6esZVVchZmg=&OB6JlAVebZrcn=&UmjSpjXYZqgY_=&d3BCkxUmclh_o=&tyFjcyYVjkgjZ=&CE2_ngZa_s_fd=&DHIBlRZZb_dqg=&k3YpZ_VeVWbXd=&VhN4QuVWgbUro=&vdeWDnZbhlfZd=&REnZvfXnWXgVo=&aLyDfyXiWrqlj=&mvh4NKUYpn__n=&V6XQXqXprpbUU=&JDY2QLXWWjkkZ=&2ectZRWjodbnj=&VJ7Bz8UkdVcrn=&GqQvvMYoolUdb=&doSAuAYaWjZff=&mymRejWcVlraa=&IQvmepXrbWrpq=&xCXeKLUrc_joq=&y3ibvtWnndYji=&5dyC5fU_eYhmg=&qNkrmOYraqaoW=&9hIbgMXgmXnrf=&ru2a2eWgemdl_=&IMpmYZVcckegs=&vLjtkCZbmflcj=&lJmYLnUYYbXsn=&sBT9VWVlfcoYl=&THeqlCZaZaWhp=&HLkACJVqXWseg=&vQLAivWjUihnd=&gKJ62QVYfkhbk=&c49CD8YYekldg=&Hr6LzDUmZ_XZc=&qsbnwhYrq_kmb=&TYeo66ZY_nWaa=&aHNkXUVoifmsW=&c5Qw3LYkiWjqr=&hN5jxpX_XmXqb=&s4vdq_UbscZYs=&mrKMpbZdobelW=&UgMzvdWXpUoom=&8W5j2IWbmWqbk=&xc3HQbYrneaYs=&5k3rtLXmpiiVb=&fVjhgXYkjdseW=&Agm9dWUqXVqjr=&7HqjtbXUZabqe=&RA7kdBXbVpbXU=&eW2NDoUrlUbja=&inzybCVjgniiZ=&hnSwJnVfnXXoY=&eEIHHBYsikZYn=&MuvVlCZhYoUoW=&5J2Nu_WVckrak=&rcaaEBYfUlegn=&A43x3kWqUYclq=&734wySWdcblVi=&AIX7LvWfoZeWW=&f_wyQpYdWsdbY=&3rC9K4UVbpZhU=&bhWS6IXcqlYc_=&V8ysSqUUienXZ=&76TiPSYcUZkZo=&W5rLVdYmYVred=&bXEEo5Uhlidnp=&PiBQIvVejWfej=&hTaKdfZdoZqYo=&wjcX4EZbkl_da=&ud_8mcYWkdckW=&hGbqEoYm_egaf=&cx5OaiYpbphcq=&tu7sr5Ynrlgfh=&ZAw4MKZkadmrU=&WzyMGJUgpfc_X=&_scIjYZdirqkp=&Ajb8u3ZokcrUg=&zZxYMWYYpdlUb=&UlYatMXZelmiW=&TaHvzSYYjUWmo=&JLUy3OUgqihmk=&W66rKaZkZobVe=&rRVSQnVrgVYbh=&jkHIexZfddVqV=&oWmUJIYUil_Yb=&7fPBmAWfYVidV=&5cEOE8Vaohpmf=&MKvnZGVfdW_qr=&3auRGGZlgpgng=&DZOAiMXiqfenU=&3LweuZZjcYhhl=&z6DZm3Vcnfpah=&ttIxhaXeUnmoj=&ZWFpqFYfjgoqb=&Gd94W4WXXchUh=&c7R2kCVqghaqr=&m8XHQJXmmkrds=&JHlaQSXkrgsfj=&r9Ua9nV_hZidX=&ihnsYfVZqbXfn=&Ivh5vcXcVpori=&lM2uLNWdnjcqW=&USAYzbYojlYZq=&8piaZCVlpkXWc=&Z46YGYYZmkhZZ=&zP7_laZrWoeog=&I_CsWgUbp_jac=&vXuJ9lXjsoVWs=&vu2FmwUcroYfo=&ZFimwoYXcfqfY=&sNGnjaVjZkVdf=&VD_t7YXkVnV_s=&hiPsIiXXoWbsW=&wiVeh4UbnVsdm=&jwvyMNZjXdrbW=&wAktz5YeaWhkm=&J3VEr_Yedchbd=&7XLp6dYskjjhd=&8lM6gAUarYreW=&oK_vJaZ_oWaqa=&mvAipNVXkiWpb=&lPS9bWUccVXVX=&HyudmLX_e_ipa=&u7QMM5WasnsUg=&ZcPYjDWnZehZZ=&DtXaRwW_ooqp_=&PsJMkAYnahjbj=&Xnca9RUhYdijf=&QwRhLFWZmZpbr=&7SCAnrUkjrUrs=&_ZEd7kXpsdifn=&yC69NlVcggVmi=&L5dxRfY_fVZgn=&3EfEDqYYcZbcp=&6ujUREXkehlfg=&XtKKvJXrcgqkb=&Q8Y62UYhjrUbe=&NUqQ3NWUqVZaf=&z8s66sZfUrcWU=&pjrkEDVjksead=&J6xvgoZlmkigZ=&7EOcviUnVrYZe=&KTwNNpUpdpfnk=&S5ENlsUkdY_Xp=&_R2AHNWUjcghZ=&HKVvUzZhWjfsp=&KrriaGZXkYmYV=&y9BePNXZUfjdh=&aBYhfTVgWYkVV=&3Zt_7cW__lVsj=&NvptfRWZcldpj=&GjLGM_WU_aldb=&J2CFIbWolaaeo=&mZM9nZUpsUU_f=&Kd_nnjYsUjmff=&3KSE_8ZpmlZ_W=&tEKGprZnaafof=&YyA6czUfcmneX=&NqhkCpYengrkk=&qZw_ZzVm_qfsa=&Zoeu6vZa_kpVX=&XXfyjFXVnohXX=&YkGWgfVkcaprp=&wV43pNYjUcdUf=&qS4EhBYkUUsci=&x8CR2iWndZlfg=&PFSZdIWddbmoi=&Qz7qyUVgZXZkY=&z7HDzRYVXeopV=&Rm5mryVUrqUgd=&aFOvWiYUcnepj=&NiOltIZokjrV_=&q4bgf2VkfiWp_=&bUTbbWWjgfdca=&eilLLvVkl_pnn=&GuP8O2UoWjbhf=&HXBLXYUiVVnWr=&GYGqdJYheZXqY=&Sba9J4XqX_b_h=&WMn6miVYb_iXc=&bNNIbfYsVXbml=&GgaJ7NU__rZol=&CwEgCnYmnamZo=&MaGqrMXpWbfYi=&nOyDT9YgUoagY=&XaA23TXprc_ji=&k_X89SYmpcjlq=&dRPy8DUrilYhl=&IgWGzZZoiXomj=&GgsCCoYeoeYYX=&2JQ5ZqVnisban=&H2fTHoZVcrkUn=&wiQ_5jVjiqqpj=&9J4jIFWY_dWZh=&fmvvTZUjWUepe=&74wjhDYYacdei=&msGwaiZnhdoWp=&YcrRHuZqrchdU=&WKwSAhV_jZbpX=&WFjjVxVosZYqc=&xycznBYcebghn=&KJSDyRVYVepkp=&DnPGDvXXehqXW=&2_CIwVYijcs_a=&OE7FxZVmUppad=&u8Pep3X_eomWp=&zZ9hQFXk_ZXeY=&m26vAzXWZceid=&YWXXtPWdWZccd=&YfZsqXXUrmrr_=&Op9PCAZoalgcl=&VnzfBVUVVcsZg=&I7WLJcUYeshss=&lVKqAjWgXZkic=&ikMC4CXmjgnfk=&GnaSEXUdhoYmp=&FJI9meWYmYmip=&WJdGrbYZlaoqX=&bnjcqUZkVaqZh=&mgLpPrWfekZrg=&ZW6fvQWXUeWc_=&zuoA2jUemYc_W=&ghsp_BUrfrioj=&g2bbn_Wrmcn_X=&OGwQXqXnWkahV=&YqviMHY__nccU=&kGQZ2sVsdbhfY=&JGsMEYVgmldiZ=&VCNL3oVZfoUrk=&tNSizcUhcaaad=&wl6aheWiXbcaq=&QDlS9HUcZWjei=&sqbM7KWiWsmqi=&uXw8_wZsrUVlh=&8GlR5kVlllUgm=&qo3BGlXXpk_qY=&QeylmGYkZpsYi=&wvB3OEXVVbaXa=&o5qXg7Unlrl_i=&4z_sB3Xsiompi=&Y8woLEUckUsbq=&KvsMiUXjXpWpn=&wezYi3Wilkaqr=&m7rAsZZl_fqWY=&N76WBAWalegXW=&UwqXkDXsVjZpa=&kttDihVcfYVlh=&aP4BEsVWXqjla=&GeCuSFWmZmUgX=&QjVpVnYYppdno=&3kCktIVZWZsad=&gKX5t7VnWipld=&RbIQFtZeamojr=&h7CJceVqkVfcU=&fOsWqYYkmWjmn=&FaC5HZYhUpVlY=&tRDMnkZgdWocr=&K3TemyYkj_jhd=&55aTHKUnik_Zf=&Z2E4s_WoeXoXa=&juGnuzZVod_kn=&Fm44EBXhXshkl=&dltpM8XlUVkcV=&2WDmxTWbbgdaq=&XLSW5zUadZWkm=&YcH3iAVWejXj_=&HD5YKFUhasecX=&phd8yHW_YbXes=&7oaYQaXZVsUVZ=&p_bMXtUiVqWfn=&25Ec4zWZbXkUd=&N7xKvGYpjomrh=&VHK8U4ZiqVXdX=&XRyXBxZcckqaj=&aaMHNGUapZYYd=&eixZzQVpks__Y=&zhRlfqVnrZjps=&ybq7b_XZggscX=&zMjbgzWhenmej=&ORFV2iWXpX_ao=&TGgDjYUlUbWfl=&enthCjYbknqha=&dvvFx8W_egqla=&TbiJFGWrXgd_o=&XKjDMwZkhp_do=&eoVwurXrkm_lk=&Y2Sl2fXhViajl=&_xSqBsXgUXXlh=&QWRivFZdYknbW=&6CcTS3YrdoslU=&PmGdoGZq_cVeV=&Z6IqdjZgmWqnX=&j8ZlSbZiWsrkm=&oDdxgZWhgXljV=&8ojWyPUhXgkbn=&_2dnC_Vk_UkYl=&k2SWCkZeZXbbV=&HWBsPPVYUadaf=&GsiudKUohrosa=&ZLUxTTUYmcZfU=&zSJNzOWbhbdVc=&bQHDrbWjXXjqo=&MaYllgYsXjrpf=&BoKmlnZncmpkd=&YFXZVAWmjlphd=&A5tSc7VmpXrWe=&fBPdKKUVc_jnk=&BraQN8Vfdrh_Y=&InwkhgZkprYjV=&ELnrH8UcYhVea=&XcMdbEYcVeYpo=&oTGShZXZijrVd=&di7pHgUmqc_np=&JAlTSYXo_eYad=&9cC37KYWrjpYg=&NOyqE7Ven_kic=&9_FAlLXjWhZqU=&PZwAK4YVYYmfm=&TaDSdIVo_sWrc=&kNkGYYUnhnhrb=&M2AU2wWYobXj_=&56cMuYYbXkVfU=&mrZXVfVjsjkan=&gy76MUXXjnZda=&O4zqpEYsmYdiV=&LbxIrDYrknsrn=&BmkGGLUimaZUi=&6HmSDuYbgckmj=&8mWfcOZZnhaps=&UBBy7PWbrpjrh=&K67vGoWpmaopZ=&FH5QRoXr_ZqZs=&kpxvk3Xesa_pq=&Htxh4oUb_aXfn=&kXAksEYoaafsf=&WsiyxTZplfXnh=&VPhYNKVbcen_a=&agLJqyUWnWYia=&JPmWyCXrpVshi=&6RvkGWYbbajZs=&Vhx_5yVkgWboi=&4hWpnYYkkUlWY=&HX69gLYUjefkn=&EtWHOxVfeeWmi=&8yNtKOW_sjWer=&KeRJyjWgrcYdi=&nMvmEpYngphhY=&gqQWLCZgbod_V=&YIDNjHZfXWfri=&cNYkjeYrnkafm=&2aeGzvVe__iUb=&bJU_2_Xdbkpca=&sM5bizXeqUepn=&D7SnXzZccZVXl=&CDRomUZfadnop=&PoVYXJUZjlZhc=&fVtAYOZdimWhl=&dIDzdKZibofWi=&OtxLZrZYVffcW=&on2b6uXlocUql=&nl2U3MZekXcis=&F5KQRGXs__cnj=&hk4vF_Xpd_fej=&gFEIkLZkZhZbe=&TO6tuzYXUkdcl=&9YpV59ZUkVanW=&PVOFBKVgXViek=&TE84csVfZsmZm=&IqeKp_XcVZigd=&_g79glVoleapj=&mAlEUMZojhbo_=&72tgTeXcbsdpa=&a6bw_HZYcqc_V=&8Mno8gVYXZqeX=&Tk9MxfYYXigb_=&OnmBKqV_XeWWj=&L4Bb6YZlWmicg=&upp5CdVnnXnVe=&c7bxXgX_fn_VY=&LfJkpeYl__XZ_=&UGmd_3YmUgYhl=&vlcOckYfgrjZl=&H2IXjKYpafecn=&2WFrsgXiZgWfl=&89S3QAXfWikll=&xOAYvIYkfYfni=&ObpSsHZdjpcZl=&YWhswYZXWfeWd=&ufUnQZYfVlmjm=&pGqReBZaqloik=&yuCG_GZW_cmcY=&oE_vYLZarrUVb=&mnSRWvZmnXoho=&QJPpESUepdqpd=&UlKUyTWdXpaqk=&DGV7krXVaskpZ=&3STsBRXhUs_jb=&Tx7i2KVroVXZn=&mJI4WuZcdalmg=&zbk9HZVqXgfag=&AGoSatZendWfg=&XT4OfEXWWpXo_=&acu4WHVXZZUYr=&PaPlbKXUVoqdY=&jklL3aXXWXeUZ=&oipOfMWWhehWf=&IOaLAzVmpYkib=&oqTraTUhohc_U=&uedlFvZhfeYka=&vPBLzKWboXkme=&TmUu4BVgfkbj_=&lLgvcCYamUZji=&4bDaohYYedUiq=&XAn8TXZdYbajm=&73FRoyXdsdago=&L3shetXr_pfbl=&Eqr_BpWgjah__=&BUPw3UX_ilshU=&XUgeOKYVYpr_r=&89khYUWZioalh=&GEgdWCXdYoqYk=&gCdTByZrfkUpU=&V3sF6oZlrkqqn=&hSob2gXVjpomo=&MwrfGxUa_caaY=&_38dhOWe_XY_n=&3cbfSdVnmhsba=&gWPWhxXobcrkr=&GI4X6SVhXrXiZ=&rWwVFpXieldYU=&3ZJ2w5WZeckVs=&x4nEoEVnjeape=&VlheZRVVUkfrg=&4Cg_rfWUZgVgq=&rxZvStYffklfi=&hcuBT3WqnackV=&3PwWP5YYmmVlr=&NHneYPXYdjolf=&VJ_tcrYhndkjV=&mzQ5hNZXrkfac=&5Qsh_sVWedsmY=&AI_lwsZmorhZs=&Fj6aLwUnqgpYl=&u34dvfYaemVas=&PQABKQXndkZpU=&8uis22Z_iasfq=&idKUBQZlphbYo=&6hf5S4Vi_jV_c=&vFg8_SXjafVcs=&nNiBZIVWeqkos=&GzHzctVgkgcmg=&7GXbNdUX_oieY=&mjDwSMX_bqYef=&hXHaUrVofhXWZ=&ZVNQ2dZpi_eoa=&N5LBsKVllacne=&tf_um6XkXqVjk=&657TewYqfmYcq=&TPUIFxYXlnaso=&2VKUw4YdZUonj=&bj5IEcXfoY_cp=&TvxxhOWZ_UcZs=&7uRVknXeUqYap=&FhA9e3Zanqkpq=&23pK6nUergi_i=&rkWNPbVagcrrc=&vl3GlEXaaZWrZ=&x69hn9UrUUVha=&mBwb33VjoXkjV=&ohoIFAUngrrnh=&B6GYbsUbepZgV=&DHebH2UadigXg=&3LfJsaUjqnXlk=&G29UBKV_blnZi=&TFPe3PWmeesab=&5zKIgSZlaUd_j=&7rW5IAVjhbWVX=&B8n7S8WVUjjck=&W3dzGhVkpj_ro=&qTRgpxWblYWsn=&j33QaEWViXdra=&PrqSGsZjnaYbV=&s4hX4aUsjYeaa=&IFJCWhUnganci=&rkKO65XWYdnVh=&fKmd3OZfb_mao=&wKZUu_YhhhiYr=&NcZIapWlkYsjg=&39vz2qXjZiVYg=&rXF9VOUXcYlrk=&NTpIUhWVbnhWf=&Qref_2Wljlnme=&eeagD2VhkUiop=&gRTIaZVUVbnaq=&YqPXM2Zeriklb=&jn72_LZqhncll=&YtPxzhWhnoZVY=&qdOrIFZf_caie=&pD3VjVWYZrVpq=&jtKPb9XicmiWi=&XkI649VsqYbqs=&gFPQgqWZnmZjV=&T3nmUSZgclmVU=&hnnYGsYhjWjmV=&UjEvnVZcsggfd=&Ze5bf5ZUseonm=&SHlX5VYk_VXfs=&GLtCNjYUVYbgn=&WFG6q2Zchgnpc=&VT2HL6W_mopVh=&JWMn_fZc_gjYo=&fJnDM4Ysk_jXW=&OoKm6VZ_lioWf=&ZoekQVUUmlhiZ=&PABTYpXsmoogi=&EIbyMRUZjmiib=&U7b5_qWjdVlUo=&8t4Af4XggXgYc=&Z5BjA5XceUUcZ=&uPYoCGZdokmem=&RKFk3rWnh_eii=&x83NnFZglWfnm=&fLUdKHUWlqWkg=&TdKLUOUlUdgae=&G8Cj2hXfsZjqd=&vcMdGmVnaeoWh=&2XIAJcUdsoqlW=&BdZjaZZgnZaqn=&p2Q6zoXZmVrhW=&7WhGtCVoaY_e_=&Vm_RVXWWggYiV=&YSLd4BYaeiX_m=&zmi3hZWUnbWcg=&2PBJg4Z_qWker=&z_kDqNUehqVrj=&MaquWkUWsVlYX=&6BHxLZXVrZrWo=&4xyJVTYapeYdU=&QkFho3ZrhikZb=&zRI7c7Zbcncnr=&J5NGdbWcmfbsr=&xl7lZlXpmpVhb=&sPlxRAUegXpWZ=&GPlqMPWpVmoiU=&qzlAsyVkoXsoX=&BzFrjMWjlgcgs=&huSKdnZVeaXdm=>s9BEY_nVXdj=&PoZHTcZ_qZini=&FpGmTcUibqsfo=&Isbi7iXdosinr=&MKjuySXoqVZji=&Gq8GaqYgeYmUm=&8UPa6NUdhpZro=&muqY6sUqdafpj=&siDwXpUYjoboq=&fvTKspXoaocii=&SA439ZUgeXsWq=&Alz7NMZkhgUok=&3K3W22ZfjUd_h=&LeY9gNWhoiZal=&GqabuDYqacnXX=&OOxhDDYZYmjcX=&Q62GePYjefUZV=&qmRfgDUXXsiYU=&KYGyaCZjXecoe=&2F5CrmZfVeokn=&YN6R4gUWlsjUr=&AIbOiAWejjorX=&HFxxxsUreaqkf=&p4PrtDYX_Xiji=&7yJMTJXldnogk=&FrjKPKVVqdYYU=&PllxCFWgeUcpr=&niCWtVUjXnir_=&sdWXXEZhZoVag=&U3xTzfUgoVZVU=&4DtFCOVYUkelh=&4ITjvEYZ_jZrX=&uv_eAXVdc_qWh=&TvdtTKZ_jnUsj=&aWCwlkVmcrjcb=&DCiQvrWdicjic=&O3qNG5YeUdffd=&UHA3TjVknUbjY=&PpuQJiZeZikdh=&rMOYwsYZah_rV=&2FUDWvWkscsan=&nqh7GGZYphksk=&5X9auKYbaomaf=&VLSExDVXhahrs=&GN7DPlVfZV_Vm=&iJMXleWcWlkqf=&lBqJbmYbqdWrk=&esT4XlUXqkfcV=&N4oDA_Yjrgrip=&rRPLnAZUhgssc=&slRWWCZjWd_ce=&fmCFkqYgqmnrX=&4_JtCVZaYVYZg=&beYWmQXe_daiY=&GmqxogUebheaq=&M2HjrFUkkkdoV=&JsEuoPYcYndsb=&ITyt6IVjYpdYs=&cfqPgzVfqfjmW=&xBfPqIVgmgWmg=&fVPBAzWlsX_jZ=&BZxQZUYgdkZgh=&ptNu37ZfVjYYi=&yDsr3dVaWkXfb=&m8ohrCWqUmhpi=&3USsOLUoWWiU_=&OVyxSCWdplWjl=&8lJpgAW_kpjeV=&ZXnuIxXicprga=&Qo4rJlVhesYZY=&cMKZwjYZ_bnso=&GDeEbrZXUkVej=&87ZgfyVV_mhhg=&nfUyVGXlq_rWn=&L6E2TSVZnqopX=&qSyMHzYqiaqpq=&x3UU7RYVnjbel=&CQAcj2UZdgfpd=&b2JxcKXd_Yfdd=&ln6ZuzVllXnjc=&5dadsJYmnsYsV=&XiOh5CXWWlUbs=&7bayVcXpZiigo=&RCupeJYmejndZ=&2OZwSbUlVgioq=&bjj_lbXfkaqhh=&9eHML2ZWcdgmU=&IRTR96VihiXjd=&cJjnv9VbrmWg_=&oaB7SaZpb_kof=&ScstVdWnV_eoc=&9z5UuvWabq_pf=&7RhenTW__hqme=&5wjfMPYXmcbVd=&2uRyDWYaWkmqW=&sswAbjVZXdhbV=&FrXEYdZXfdobm=&SoZNWPWjifgiU=&z3PMbvUUlesdn=&VJOkxBZiZXUZf=&rBFOItUsqppjU=&yRFWitZUbig_i=&IzEWpYUZlfqbV=&uDbUibUehsqpo=&WjJfJ_YUZXVik=&Ocid6zYnhVpVV=&nSKwa7Zmdsopd=&ziVKiwViYjmor=&RbavHhWoZeWZe=&bD6fffVbbmiic=&yMPw_uVWVfeWn=&NJnywuZabYsfp=&Df_BRSUXkfrco=&iadthZWbVYh_Y=&63lhtlYfbVYfY=&Vn8XnKXesdYUi=&_oDwhrVrsdkpY=&8TWtr3Zdlfalc=&J3nEMKWeafskc=&sTpDfbVdgZeoV=&NCHVGVUso_dXn=&PMBeuKUZqljek=&4oFfUBUVblWsi=&6rC9x9ZbdUosj=&b6GITTZrmeqYh=&_6uGazVXnsrVg=&ZiRVYuZYccglm=&sVmeZXWcrkids=&44JCwwXZesfli=&rj5QJ_YcmhqcZ=&pBS5zfXUXWrVZ=&C575gZUca_ejn=&UitR7gZdbnppr=&_X7274ZUqeclc=&8xbsVzYqpjriX=&OODBc7X_WbrmY=&8yg_GRUajkcai=&KDrAkeXXmgYb_=&C__ug8VbWmWYa=&fSAMcDUeiiUbq=&s3SQ4QXUXekqe=&MLGGtsYdmsVgZ=&9ZqbmUZkUmicW=&_Aclz6ZjhhUnj=&hiq_W_W_spfiY=&JegwJjWggicUi=&IcdGaKVhaeWqq=&x2CtKpYnrZoVn=&p5a5R4VfincpW=&BTVk9BYbg_fjo=&kjOnBvYgomdYm=&5dvHk5XYm_gar=&U6_5uPYlWcsnf=&vZvffnWflsdks=&Q5sTaNYblaUXm=&f6qnJYWfraigr=&ZRaAoKVmefcjm=&C7HNTbZWf_prZ=&QporfyWasYVgp=&D53bhLXYkgmhV=&WqCCLNYUWceha=&cTLiI7Ubrcngm=&MPJNeTXZWlZlY=&r8Z5ScXnkcWVX=&IR5SM8UXlcccf=&S_kkIvZiUsqYh=&KFREDiViiUalW=&6_8EL8Wfeeems=&JH4OlOWbnVsUk=&yoVmy3YkZVZla=&UPgpMGZYiriZq=&LB9SIFUXUkrhV=&Em_zSuZZbZaYo=&aFdLyFZnkfXdo=&Gc_t9QY_mbaUr=&TxPmGfYdcZqhs=&LXyFmYYlYoiji=&yTgda6UnaVfgV=&XoQU5fVVmqUmb=&ZlGTCxXpedgrp=&vA2iZlXemYrcX=&xImwRtViVqaVZ=&62aZnHXqsUjVp=&2ySB7UUYbdebq=&eqpiY8XhYUdgm=&LYftPTYdiqsUn=&XUxJo3YbedVba=&IyKkTNUoXsfob=&7hXQ57Ymnfecp=&4Fv_EvZif_eYb=&2hBFhAVjWs_om=&mCp5UUYWrkddl=&udYrcdVnXjakW=&7KzTARVesj_oo=&7nDw6kWbcVXXW=&3JzNTIWZdhfkf=&x5KGycYUhkqhs=&Ixph_WWeidirk=&eKuAXbX_ZXbWp=&J6I2CtVYiUgfn=&e9ujr5Vcr_Ugr=&KAmC6eWWiUcqo=&PdmYjSYbZfeob=&CQAn9PXgpnqW_=&ok764fZlrdcW_=&2gs9jhVbreheo=&QPGlbgU_oVXfb=&B64SeCWqrqjVp=&sQHI7mXYkfnqn=&BMqxYOVUeea__=&5ObpVkYnacX_U=&fc5EqGYbjgqfX=&ZUk2_VWnXfX__=&vNLT_iWmsWksf=&cnswGbYkopjfs=&fbHZUzVoUc_rg=&dD9yqrVefsfar=&pCEfsWZaaspUp=&fBkDlIWhYreWh=&nZzjTsVYjhcob=&bHx7QrYdoahVk=&ACkKtwYojYjsm=&ewK4HDXWlpegV=&TUvQjBYeblYbm=&OfFNNWWjpsgqb=&e9PrHjYphsmls=&fSf8FyYcVUlV_=&OvJyukYqbrZnb=&moM3k3YWfhUod=&TbOjSzYjboq_V=&atMBbbXaY_aYi=&EpIPHeXccfWbb=&fHBjREXVWZgWh=&AmajwLX_ZXpib=&ms_g3aVrZsXcV=&XRmMXiYghdjej=&27V_rvUZUjcsV=&bsb82xUUX_smh=&H6cXI3WslhVhq=&4a9VW2WpUpZkd=&j3LhNIVegoqff=&J456rNVdlggps=&hiHpbUXoiVkZi=&ftJ8FcZeXmqUW=&QHNQg5Vqp_cen=&tSX6hCUkZqqsa=&wRyq8VYkrWXis=&ILARPDWmUffor=&f6vFWaYqqWjaY=&oPLHe4WefbaUd=&W7IHXaXYbd_rX=&fE5_S4UcXXbfV=&MJVgfKU_kcpVU=&_8gULFVVlggkZ=&zE24HOXYpaiZq=&T76T9IXfggVmp=&x4zy6EXnfpsn_=&27qsIrWsXhVii=&BXNgB_VaU_eYo=&T2r3oUVhbjhn_=&2LnVh_Ulcbmfb=&RSgjg2YhirWYc=&2rtrt5Y_mghrc=&hN5ANFUoppkqd=&YmIF92UchibgX=&vTswRFZWasnsd=&XBB8DGYZUqqoX=&6_wqhkYmejZWV=&AayJkHUrmeplY=&xj3q5dUcanXc_=&x2yNzHYZgbpUX=&XqaHrSXWlsXXa=&M_LtP6ZaZiggp=&EtEHaoUWqpbqj=&SfWpiEUnWfUnc=&tKOUWMYUbVVnU=&hc6ksbUcflsoi=&HtQpJyVhlijkd=&9PbYnnZZbVWns=&qARm_NVYoqYZZ=&_sSwY5Yo_jrXU=&Fnz2KrYiWbniW=&qlXHICYjbfVlj=&V8zbdgYYfXroV=&sKgPtvUjXWmim=&ozg3aQZeqkk_Z=&EENKo3WlsrZZo=&eG6gFaUWooWbU=&v8hShyZnlnnoo=&j8zckpWkashqe=&czAElkVgeUdWh=&cSlgSHXedhVj_=&qMPD_mWnsqVbY=&K3MR4pYWjWsrm=&vSVRduXidiZmm=&7L6A9dVbrarVd=&W4mz5CWgV_YZl=&IzsFV_Zce_ZiY=&Qg_EbQWklemrW=&JDeFznYsWhmnU=&NSkQdHUXipcUe=&TZWUqXUWhrjfm=&lUzBWcZjcsUgi=&wkxoioUrZY_em=&bStlc4UargYnj=&Jm8ugLYbnenUf=&JohIcCY_dkWpf=&t6z7wLYghnraq=&wcUe5HV_ajWim=&xElNfXYfkeabc=&SM2IosWcrlbre=&xqou4XXUWVoXb=&EERoc9Vsacips=&J9VSkvUfjoidb=&mX3VrXZlfep_n=&qqx9igVnrpaq_=&iiR67bYrm_Zlf=&K74cVpVjgjk_Z=&TtE3rnXXdlnlj=&_gRlkXXrWjd_q=&afXIjlVjreXcd=&TXPQhAWckipUg=&MsGYRmXbdUXrb=&W9ZRmDXjjdrmr=&ucczQ8ZsUrjas=&QcBkGDUsdqnUd=&8jKq48Zmnrrfa=&UAaGXHVjoaYbk=&eFEwjwV_sWcei=&gvepVvUYiYYkZ=&qWqt58ZbWcbqi=&qdVjo3VsqmqZg=&OoPtt8Xm_UZVi=&bvNcT5YopdZZn=&PdAxWkZlbZkg_=&nsxPPpYnYmWfo=&a8zNnUZnomsWb=&UJxZqwUXcfUgo=&3aTmWOZ_rpWgl=&dl6o9tUXhegiX=&CBqnT6UqmbpXq=&CrlcOlUiipcpe=&oHcwABXbUZaUk=&NfJw2XYXkdpfs=&pXhWG6VebbYWm=&wdhHQwWnUeUnm=&xWWWwhX_isWjn=&vUsLCJUfbgnUV=&vjASQnUncXbcl=&vYG7Z9UsenknV=&piKuMpZUZrnlq=&oTTTK5Ygoagln=&rReiFuVVd_hll=&mHNzgIU_oWYmi=&WGN89zVhkrWri=&nDSvYLZYYWofZ=&Mz6QTqZsqpXrq=&MFFoJYVqqcho_=&yS_tjDX_hoXkd=&9cZiBBZqZfZVr=&ZWHyqJWldilkZ=&kIm8ZgVUkoYVp=&dyBBQSUapZppg=&vjXRObXlZnndY=&h765NMY_qracp=&aYnmrTXaXfUYn=&a_vMm7ZZVUijY=&lPd4hMWkboWUr=&PGac5RVfjnifa=&lze_FxYdcejmd=&qo4bzIUqrnknp=&Jpg_jtWdhV_qo=&xRaW_mY_cjdef=&X2yi_UV__nsji=&GHGe3jVdrYjmh=&WeKgpEYlglsdb=&VKCwYsXffgnWU=&ifw7EKYZpibYn=&XW8ZL8ZXYXrhZ=&fpRFVpXbUdnda=&4LWs7WXUab_fs=&mVFTZHWbXkeUm=&hTrML_Uadmmhd=&HvDemzXZpsZjk=&3eaISlVgVhibi=&3Wu7JyVXaZUZo=&Hi78EhYrbkkYo=&g5iNmAVaZjf_U=&Bssl5yZhdfqls=&fnn8YkUhomVVo=&rgdcidWdsmXrj=&9gP3ggUUccbZc=&855tpZZjj_ghf=&OFMnuHVsrcldk=&Zao9qhW_kdjUn=&Ws3J4DVjiYUeq=&XLYvmwXoaUpeU=&CFtlO8VeralWg=&BztOrcXX_a_hi=&um8vOHWVlsnjk=&fne5z3YWYVYdq=&ZuIczAWdrdqos=&x9Ubx_VgnbYZU=&SG33pTZ_mclcd=&7w9W_XZceUkon=&kqZU2fYhrZkWr=&up28hZZnkXolk=&kRjUwLZirobWb=&4xSWHDVUbYjlV=&jW4KqhYqgdgsV=&auZqvPYlYmgYX=&de53TUYppqjW_=&TYZCt8XeUgkkk=&AZXgEbVpXXnfq=&4V3q3JXjWjebs=&o__utsYUbfqZh=&NJJcWUWkpnbYV=&fDThr3YhhXkcd=&vS7UQiXohnWVi=&7MD3McVd_Whpc=&fXCNcWZdViWn_=&chaOaDYasqYYV=&opVymfZYnosqU=&Q4fZKdWploUiZ=&vzOtiLYgprWon=&WWroRpYqZV_nX=&xzNOMnVqkbaiX=&CWTUZ5VVZd_bW=&jQrmuUUaqllcZ=&PtJsZhXdljaki=&jxMmhbX_Zsgfa=&hnQCUoVgq_aak=&dr2layYVhbrVU=&sV_P6uXlghpqc=&g3QRjfZpVVbXo=&nzKuuwVnrnfoo=&BZHEBuZsVceVY=&_lFjPQUYanima=&miiIXZYciWjgm=&P6Q792XodZkqr=&8GjCRMVVqg_Ui=&RQzrHgXmZgXe_=&aYYr3ZZmcjgpU=&9iXvgDWjjiecU=&fzOu2dUXYXbci=&pxk5aEYa_khkg=&AsdSEkUbasZlr=&KAM7B7VUaihq_=&fRDYvUZVcWino=&nHF9D_UmdXoWV=&quZYhHVgfgpVU=&fbLGeFYqklsYq=&Z3Q5wyXiqnnVo=&ZQIsS9UnXojX_=&IQkRBdZankXsj=&VKs8AwVVWqdff=&geMaDYUVVgeiW=&jvsswVZ_cbqbZ=&jOIsdpZgfVVqm=&xK3l2OZXjmXYe=&iKGt4JXWhieoi=&KBezVlUrc_nel=&lTzRbBYhmWkjr=&bnTiotYUbViip=&Rz54aaXoohhV_=&veYhciYcpsnif=&hmSt92VshdUmj=&JNRXklUcsgqi_=&BhThyhYY_rmnW=&eNf4RkWidclkZ=&CAQNvWVaVkkbm=&lporLAZbrnrck=&UWM6qPXsUschb=&qsVt9lWkmisoY=&KdEyJWZomqmjj=&JK8mdeZiYlngl=&XWCGSbX_eZhZZ=&EOGPWFXjcec_l=&xrpgKdZjjpmVc=&j9jh4nXesempc=&GvtcWhXVZYopg=&8cO9QvWkrXikp=&qPZiM3VhUiqkn=&TcC2gQVsefih_=&_X53mqVWWsjpX=&5DTBWCYqcpbms=&eWWc6lYimZUdZ=&TQ2FbiYahqahj=&TuPQ_2YepcisX=&WYDVwrVffjsfp=&y9WNIKXZnVmYi=&F94ZUuUbXjZWo=&AmIS_RZXrZWUg=&zjBzjIUpVlcra=&ZhK3ftWXqrfUo=&4z7mpDV_ZXe_k=&HYf26kVle_qoZ=&DtgEgfZpbdjZo=&CXk8_XVo_oleW=&P7epuCUcVqdVU=&ksQO8aVssqZfp=&BZxKoUWcrUasl=&Ses7X_Wprkbjq=&GfkEOQYeechof=&sQag84UZWrssZ=&QKrdBeUqnWqqn=&VN_slCXYmbsll=&CeXxfIUUcYoms=&EaPPg5WspUWbp=&YAleHaXdajohb=&M_DfaAXrgsZlf=&nSYaOJXjalgia=&dwE4vBZrcXhkX=&fjxNDlZnUVrgf=&qckIrxYlbbapr=&qGaB4VYrmfhmj=&rAM_qDZoZajoo=&H4LsJxXbrmeoj=&LCeWzvXdnaWip=&asIpFBVlfgmqj=&iyV8DXYVjhYbd=&Xk8z3nW_iXXen=&allcUtXXrgh_g=&AGVU5DXfkcshi=&769MP7XaiVmol=&CyfzINUfjZWVi=&C3SLtuWXjobem=&CC_G38ZfYijha=&ToJQt5ZrakfVo=&uNtYzUYhVraYV=&IQSWTjWYsfVql=&ilJl3YUYWoUjV=&UeNnJiXscnegq=&o4dOsFVeYn_jl=&5aBWLBVjkVphh=&qL525aX_jVlns=&JztIlUZZecXUc=&2N37TFXdZandU=&CHgKO3VhqpjhV=&QuarENZWssmnV=&yohw66Wickpir=&w38UOLZimrgVs=&4R7FSHYZle_qh=&gpJ_9HWpoWnrl=&GePcdYXWYgoa_=&qT7XbTVYmlVhd=&kwYVvhZolVZic=&mnQN2PYsZ_Ygc=&x7o2FhVoW_cnj=&m2hZjWXe_qojX=&8jappyZrlrXpZ=&WuUYPcVrrmZnZ=&LrbzuWUiXdVrV=&wF33QaV_VZnVn=&utTbNlYlo_UYl=&YKQ_YoVfidnbo=&amQogGXaghc_j=&PEpVxMVafVbad=&92vVxiWXmmegg=&Xa8ibUYdgdYYo=&iTj2yOYnpdcZc=&IpMseoVshlZnf=&YUde7oYeqqelb=&LIRIInWnXeeYk=&VlGRYHZjZgpXo=&5WUqz8VUVUYid=&fwjKI_ZmWnUVm=&8XFSMeWgaWjmh=&qQdCLHXpsXZ_W=&PGOmWiVWsjmjV=&FPpAXsWWbdYrk=&52YUmMXcp_frY=&mMhEFFXalcndm=&s2RW7iUYgesrq=&DZbEcbYWnbdbb=&rKk9EcXUi_lek=&IAHE7RZUbqWXU=&3kbq7VWgpYepd=&GitUVoUfdUebU=&RGpQbkXasWdpr=&ek7l8CYZqkn_l=&B44Op_Xhhcm_s=&jS33vBZekdcfV=&ZSp2mJWaWVepf=&lem8KZVrYsVjW=&_VZ_aaVVdjZoq=&RooRYDZibpmVk=&e5qjsWVngdqmX=&tkHjUYZl_ajWX=&OUeE7wYiigrie=&cokLqAXaUgUXU=&na3SOGYrUkWYV=&R4382ZVdfhkes=&ePOPejWicYjhq=&NPOwcyYVZqrnj=&aMDG8RUlWccgj=&r7zz53VVpsih_=&AtXGcEWgYimdU=&eZ3MQeUVa_hVj=&78UEJCWpmdmjq=&pKiNnTYgpjfhj=&ZfzO2CWYknUjf=&_HVqNfXjbcjZY=&cGJBRgZiqZaqs=&G9OjrvYlacldX=&8XVGHXYXnYVhW=&nFTnjJYqnamlV=&ooILjUZsUeaaq=&OBNrSsVnissoo=&9vvRBNWYcgWXf=&GSHjrOUcjUlse=&8NO6xwU_UXoeY=&m92v9AWdUYcaa=&u6ulR3YcqYUeU=&ExwkWPXnhsjiZ=&Ge9TgWVqpXiVs=&37TbytZgsYpU_=&SwmNeFZpbYifj=&A5xjtRVbcdqYs=&heHGiwZljebap=&IaiRLfZmjhUiZ=&55WdlpYY_Vgkf=&advC2iViYdskW=&LjEbilWlmghXW=&iiurpfXlkfVlr=&vAWGNOVnXaXXW=&TqYQ9WXrqiUlV=&HkdGcwUWZoW_s=&rZPNZUVkbplXj=&3vf__3UcXWXhg=&RfN5W4YhggphY=&RsKyorVlhqsog=&H2xZL5U_Vrgao=&XQTfmeUgoUYie=&YWAlJFZl_rhnj=&3LFi8uVXlZkbZ=&5K6FBpVhsrUlV=&3_VLAdXcVkiZp=&gplqWuUVofrjV=&EhJ3YYU_locfV=&xJHlFGWgemcsY=&_L8xnFYZbjrsi=&lsKtB6VfYoood=&FkyJgbYoqgklX=&AWesyhYbXoWWm=&MPXWwKUkdepbY=&AQgjMdXUpoiXo=&d2PsQQZchWs_o=&UPpbiaWV_lnmj=&rlSugqYigchfj=&NtZqdeWsdqdjg=&GeJIpQZrgjioY=&Ohh7aqUfhYUpo=&BOI8JVVhUodZd=&AyVGdVU_cgkph=&zUX9MpUVoodaW=&Qy4EjsWqfUZfq=&gCC_c_Vljdfld=&xWdUryZUbpWjm=&rp8eFPVemV_jr=&CYV7TgXpjimWe=&RSvxLSZbYnrYh=&Z6FOl5VWWfVpr=&poSt8CWmkgaVl=&ILaBfSVrZqmgX=&HHpED7Ybsbaoh=&U4gPYMZXfpibW=&lkjA5KZnpcXmb=&DRHD5OWdVhcUo=&5qkdYLYsnqseq=&gUhft4VXUisfo=&iSSnhVUlfVsab=&zTj3sgYfaZqkq=&_OJf8LVfWbrmp=&VLCiBqUrnmjXo=&SKGjxWUWlf__p=&wODSKhVVYirrn=&hQK4RcWsZrdbo=&EElrZeXmbdZks=&5wxofvZq_kbjn=&GcLILiZsoXcVe=&_P9Rm3XbkVsUa=&MmrugoUqYqmmY=&wVUiqVWUnXqdm=&EhpfGKVsdXrnd=&L7nGjOVUkkeVs=&2zmHywZcfspkl=&ncnBp8YWYoWai=&kSKi93UjYkXV_=&DVqtxBZpYn_mr=&_vR438Zpppnmm=&t7gglrZaoc_ed=&R6QIrcYZYdWUq=&YPSzq7ZZdagnb=&MnSfK8UZabjlc=&xA5mTFUsZkbUo=&DxSewEVecUmce=&M72ZJiYsaaqXl=&t5LiLnZchWpXZ=&jBIclWVfsrfjj=&hIcxv7YpmYo_d=&IZDajLXnbbmsf=&4fW6LOUiWbibf=&LPst6hWndqphm=&OAEcCSZoZjf_X=&5xCBlrUeUljqp=&6xMWBFWaplp__=&d_BJMsWkliqfi=&s8kimjWZpsZ_e=&kbukvqYZrbeWe=&X3qg7cVaqompc=&t2P9gWVqUqZes=&dEgnLdUirkdhk=&jaRVw5YmjpUXp=&doVocEU__bhaf=&qpEKCPVYfbeY_=&Qh6UHVUjaiaUo=&xisuGZXcmlifg=&5g59gfUfWVi_U=&KEgAeyVmof_qb=&bl9VRnYhZZjWY=&6_N3x4ZWheaeb=&fb8pEZYfhnknY=&xgOuaBVqfnUqo=&kinQBwZpsXbZc=&Vtv799Ylbhbbr=&I8by3oUerbkhY=&zwtJMTYWlrena=&uyHO_bZggmi_q=&HuLpPlYqdbsdn=&FJ_GQUYnqmYhj=&PnCWvaVepgVdk=&eStjJPVegXVgU=&QJSOl6UZiscin=&nOOdBTVdYojWs=&kkMUTqWhnlf_g=&tBcZTYWkjZ_lU=&kEJlscVUkXqjk=&7OeBZvWbapgki=&rQRjK4XscXffj=&ga8mu7VdXhahp=&D8hQN6Yfeehcg=&WsbCxYXndeghp=&fDiGeZYehWWp_=&ocbplyYeZZUmm=&qoKjFUWWasUil=&cbUFHDUjVhbal=&ljrltqXXccppo=&vxCHphWkbcoqp=&ay8CO_YsmbgeZ=&chvatCYcjYqpq=&leRM8aZragpfk=&ME8QM_YsX_las=&4uRpVjWafoqp_=&HHR5gxYmbqYog=&vWzA7AUaejqiU=&DCdBOoWhihcko=&PTO7_FYeXslW_=&PbApeIWllWalj=&INQQAyVibjXsm=&wJohiAXjrpkad=&qX9UliWbkokZX=&Vds2w9ZZjscp_=&ustvOkZeonZek=&sAqvMJXpohYWY=&YrMYhpUehfbsf=&CbJNwzWnlofnb=&reTzS6VipU_Ud=&3r5By2XfWkkoe=&ZatVnFWXiWhVX=&Jiih6tUbrrmqg=&U_EPhJU_akfXW=&nH9vMBZZfje_d=&qCEMTXWo_kmVe=&uKtuOVXse_pUr=&wwJ_BaUgipreZ=&y7SV6KWU_XYsa=&5odNQjWsepij_=&hnmhiFXoXgdXr=&YhthhMWsfgmdV=&lPVxEMUbYsVaZ=&zMeclCYbqnooh=&jtxkiXZkpfiqU=&SakBALYaVXfXf=&kZrX5nYWoWqfc=&CKVOklYkVsdoV=&I6Tg5FYjhg_rn=&iujurLViigXae=&Kd2EOSWrggolb=&NbN3XYZasVnbr=&3hVSAHUgmaWln=&kMNh5VXXmZiZU=&opgdmKZjUUkWr=&GhQh55UXVZgUg=&47Muo4YdfUbeg=&KntsXYVoYllnk=&gCeGYHWsbjldc=&fxB6zRVldgm_c=&YMUKCAWWfZUjk=&mNrcP7WesUlpg=&yBuIoGVfo___o=&fSXZ8DVXrlrWV=&MfeeUUUs_q__c=&9dxj6ZYnrmqhb=&zahK8AVrfgdjp=&vS2NiEUbsnbnc=&Ax3pG4Yckd_ih=&aLrYSsZqlg_qp=&qTW32RWhormaa=&iiN93CVojqXYV=&2qctThXgrYdgW=&OfAsjoZnlYaZb=&ELoskBZrdVgml=&fz25eJYjnksgX=&k5dThnVnqlfZa=&gTrUepUUeoage=&KPWKFxUmlsVdr=&uHVASqXbeZskm=&FDFbMfVnWkci_=&UTvqEiZ_abeXq=&qiHr6wUqh_kns=&PPluPtZVqX_kV=&bbHkmTVrhkZmV=&29UWEDWhWpcmV=&yBdTANWdigfbg=&I9Do4VXWpbkqn=&WsS6YEYmaZkcj=&PVes3_UmaaoUX=&YesNhRU_erZoW=&wBJVLBUbrkqlh=&B8jXBSZerpobk=&nOooX9WUVhclU=&Z2I6HoXkVgfhl=&P7b2wYYbccZac=&BM3vEHWqahkno=&lHLFKoWnlqfYc=&675zjTZhnYZqZ=&zivqH8UjjmWnc=&pIIhi3Z_Wnnbl=&WRhe4xXYnZhZU=&NWDuFvYffacen=&VPkWAOVlqnfgb=&EvQV_eYVebmWZ=&GylTTnXqVorsa=&4BvTKGVofnlkb=&hI6lY8YroUsnj=&EOZynzZiVejeh=&yW7Ei3Zh_okeh=&P22FO_XVjnVfr=&_3JdqsVXpUjho=&H4GQsnVngd_VW=&qXvnwCZppUopa=&nWF64hZlde_lg=&Zcn_cFXYdWlqp=&Or5r2mYrblUfi=&ciR3IfWWclnf_=&2dI5lzUnnsnka=&f_ljTkYdeZarY=&RUAqPFWejahbb=&yPcyjkYYjngch=&u4ZmNxZXU_gcZ=&kvipi3UmXojfa=&Ph4tWWWkaoafY=&yDU2RdYXsgUdV=&7nXEvZWUZVdia=&_sVq9sVkj_YYm=&xiPbQAWjmfcoe=&hjWrsUVa_emda=&XFwQihVYkgVfp=&FIOHQdVbYnqXq=&hXV278YoZYrpZ=&6kSTnEUpmpfhg=&GRMyvjXWUllbq=&lJar6sYZfhmgc=&QXZfb2UVrZZco=&Ikjxc9YnVdUsa=&GjPq7BWeUima_=&9BW9I7Unhessi=&IAHKkmVYjZmhe=&V9NTqCYYbohe_=&BkwayyZlfr_Ye=&grJQfTYirfVks=&8vq6Y_Xmabg_q=&YFqDxBYeVWsWU=&9xgqvuWneUmfb=&YVXCORUsXXqeW=&5EYqZLYVpmrjf=&pXiiktWicdjaU=&hmIDGzXarbghg=&7wepEWUkVakXe=&6oo3inWf_i_cY=&lV_QyVZarsmjX=&a9B9lRZhYccdh=&DSmc35Ubh_XUb=&e8iSbcYZiUmqi=&yKuJuiYUbVjZU=&hZgOKGXberVZk=&3ELVg4ZsjXohc=&KNf_vPYXWpkqn=&fvKJl8Xjahbs_=&wktLKMUbibsmh=&yjPutKUihVfrU=&DigbGsUhmWVkX=&hFhY5DZerseWV=&iMRga4WZajehU=&uNreW2Zdpglnd=&DXvw9RVnmXled=&dlvn76ZZmcmik=&DOHYvLZdaqprh=&mCkv7YW_VpiXn=&jtbP5vX_aneln=&GGhF3KVdfmYbn=&FrTrQZUiUppUa=&OO7YK9Vp_niYc=&ZYaJmyZYhfegm=&5KWd7YVWccaih=&zPkMC9UidkZ_h=&YR4KyOWdgfplh=&_iHuTMXjqnpen=&zqHx2RZif_ihh=&GgjECjVbWfjmZ=&MjLyRIUjihnop=&_QD2WcUafVnoc=&GBTSYyUWUppgh=&hHCSBEVqcgdYa=&gWIb_sWrnonmr=&zXjaMiUgfrlli=&GFNLSoWp_gUqp=&EdtzJgUWqWnVl=&GXZMypXbUjZga=&aQJeoxXXaifiY=&4lYrPTZleYUqq=&RbdWNbVohmoqq=&Ri5LiUXXgqosb=&2wXDsqZhZsibi=&MHg3bJWoXjgYe=&emRuEnWgcjgsq=&yYVAijWljVaek=&ykqHa5XmsjncX=&3yzVXcWgdVf_b=&brBS73YlYZdjq=&vAOygcXcshnhe=&49c6X9W_hWZeU=&_sR5fWZslnYae=&sX7cFnWVkfkeg=&8Eg6w3WigjWfV=&owMB3FUkcocen=&kFDW3gUlWkfpq=&LsWMRpWlaagsV=&6Bw6FHZXcYcUm=&dHpqjjZeacXYm=&KFpE7hYUhkn_k=&CGURkyWgiXhff=&3dyJV6WsmsqXe=&IRSsPsVl_hepp=&TumfnNYlgXgar=&3SZNvlY_gXcme=&DC9WrRUVjiVXY=&8QWtSLZUlXecn=&K26j9CXcX_nWZ=&nupx3QXnoh_Zq=&RjqDoCZkUqXlZ=&d9VQc4Zphsire=&WMCkw7UnZkYlU=&zRVlJJXicqpkb=&b4IRAnYnZencW=&bDUrZTZZbVUm_=&Q8fL83Xdlmgck=&mtQWdiUlb_gZs=&I43ulHUrnjlsc=&_SXfuHVjkdbe_=&sWxFtcZelXgdo=&aX9ZZzZiYYoXj=&ekRijZXfWjXeU=&zRO7YeXiphnfg=&svITOpVifbapg=&OGcYLfUrooW_g=&CKdUTzXgoZUig=&aoBusUYplg_gW=&z2MadmZl__mk_=&fGuSoUXZXhegs=&_KnpTaZq_XdVW=&t6btD6Ummsjrf=&iQEDCdUprjZkf=&B2YWA3XepZgXb=&iZ_aHeXrpeVor=&DlH6TnWjlWlso=&SJYeGOYkbjlVi=&SVzQtRZrXXhjl=&kClc_uVlhhUbb=&rE7c6fWYWbZnj=&YUDYILXlqYsUl=&TZij7jXogahVs=&zbLjebXUgickd=&S56LbiXVnjVif=&DZAcMBZdkYiYo=&R5leqAYWhhajm=&PuiNjeYcakUZX=&UyzGaeZf_aniX=&2mEvl5ZnZfjgl=&nAOaPrVdarfYs=&EcCkFBZlrWXpk=&FGktkPZdrrc_o=&iU8DijZkhcdZU=&EK2OcuYscoYc_=&yrUjbeVlVsqXe=&e2sm8vZUUaWZi=&5WTJqUWZ_rlkk=&kwBwITV_dmkUb=&K9jaI8ZVkdVhU=&y9KaRXUWrebpY=&GYxH7dUcXVZje=&EppcXhWUnXnik=&BXvisUXnnpsZd=&jhBCiEYVUY_of=&bp7499WWWppYg=&4HTVApZqkXpbU=&6ZTnn8WmqeWla=&HhNs_7ZnUrjmk=&ybJjCHYiYiYiX=&FIdBmyZZZpqkW=&twsRgSXeenjXl=&seQgyRYbqcUUV=&aTIXnXUddolbV=&PbkWMYVsXrnr_=&2OoHOyXksXqlm=&nxqXXqVZ_ZdVU=&vIsxdfUW_pkpl=&TZO69eVsgWXW_=&Yd9XZnZUkmUWW=&Hu_9akUVaUekf=&ZXDqLlUhrqWjj=&erITWHZ_nihmh=&m_wFABUUimgrk=&fASIZmWm_ieUn=&jk7kcKUVjndg_=&odACInXksaZVs=&NAMbFnXhWpWc_=&GXRDONZZbioYm=&FIjzVgXjmsr_c=&KQz2ssWqYsejq=&mavK_MYbbbfbV=&f_cXIwYWaVhXY=&YO5D5nWcdZnXd=&4JNW4xYlcVbef=&Uqi3zXZghpbgX=&fk5Ow6Wjksm_e=&3g2ImgWlssijU=&sGVVRaXWahqcU=&zm8qKwXmcXmjY=&yVKGKCWgXiedk=&lLqDlOXdqZedd=&dMGUr8ZosUmjk=&fplynQWpgkfmX=&UjrKgpWaerUWj=&VLcMjwXajqaaW=&nwP8iMXjesYnd=&Sd_x3oUnqjWWr=&Hi4apCXhsiaff=&34ER4MYseamcm=&_9cHg5ZkXnpWU=&7pqIg4Udgsgfr=&xT8SerYn_ofb_=&yMHr7VVpffajZ=&KJtLpVYnaVngZ=&3rWYLHZfVVfpm=&9bmRWLYdZafqZ=&iouQntWkmqWil=&dlXBifU_ipWps=&6LJD38ZYojlli=&iFLx6hXeibkrb=&7R6mAVZkUsWXq=&3npxilXgZX_Vd=&Pupo5CYYWYWbY=&Ve9UybWnYlYcb=&iziv4BXnZgpUn=&5zzvjbUbZscmc=&gkjQZBXroomic=&N45hGHVUlZnre=&yylBQoXeheiZi=&C35GtoUbo_dZj=&paf7tfUskZXfi=&KPjSMtZWbdZfZ=&2mex7sVVmZ_Vh=&GsbqTCWmnrYkp=&4qF7sAYUcqefa=&IdrdjxUWhmmYh=&epfVuqVnkdWbm=&wqUXrmYbgroZq=&c63CbfVZndnfs=&ofNQ3jUlhUYqg=&8RiKRHYZninWq=&9bTg7aWYYjpil=&MMLus8WsnXhek=&5qoogqUbU_Vno=&IjhaChWpbmrjU=&rprg2NZZkVmkr=&GZpSgSVelYcUj=&X4nnETVcrZWmp=&P6OM9LWUaoq_k=&h7ER5KXnraflW=&Yc_8mYYqskppY=&5ZLWG5YbdjVZk=&7lHG5jYrncsZX=&UaYblZVpk_qke=&l743u8Uoki_rr=&QLwy8eUUrrosh=&8gXMdZW_her_f=&833eoGUUfdngV=&lCDTusUaWmaYY=&4OQCgFYch_rWl=&Y8St6pWjkmZds=&qC9CM_Vfiq_qr=&QC5J_xVV_niqq=&Zx7jEuXrYhdcc=&VYPr_UZqlbY_h=&vLDHIqVYp_sgb=&55qpz4WeY_WZj=&OvlWAJZmUUdim=&dt_QgnVkjXfcc=&qaV5nFYgXlZjs=&9tBDGlZUh_fks=&YAhgZVZjpkXcs=&rUa2I5Un_UiUU=&DYb8tIWmpkbgp=&X72EneWorUekd=&ogJTCCZfdYflc=&hIt8AcZUilqUc=&3y27eyWgkXabW=&aPxSxmVipgneZ=&myPCVkYjahYWd=&Fzn5orYZrmhZf=&QoR3CQYqcUdkX=&NkUm2KZbZYYUk=&S3gCPhWrnmdrV=&w7bT9IWggWYrU=&iVVZUeVfijlXX=&hslCljZlVhdqk=&l97SqSZmkbmWY=&G2TUKoXhngpVY=&u2qRuAVXis_sd=&xUJrLZUhq_Upi=&MvF4cqUZprgkj=&AZw3ngUscohXb=&RI5bLzVqZXifb=&DuLnx2UXUrrqf=&oCfYGOYmaidef=&vpFKwMUchheqi=&Jm2YBcZqfdcVm=&SxQt7qVrcfXor=&QsWNsXWnarakj=&IcEZZxYsbjZVe=&Jro8NhZ_qhhha=&xaXNdFUrjYp_V=&BiNMiPUamdcoV=&TeXyRvWgUlfhY=&5FdcijYadgXig=&ez7yP6VomWbYq=&LOpVOYWosZqoj=&C8lA4iZkVmbji=&o4CYCkXhkhaaj=&9BTlU8Y_Uik_l=&VgqJnyW_llcpd=&wmIrttZoZfa_X=&Ulo5B5WhnUlbX=&Z_T_VDVXqfnde=&twPgpfZbmqcgZ=&i5XSHDXhqZ_kb=&xq39l4YgUYaUg=&zwQJLWWkeWX_h=&7oSYVtUqgcdZd=&NvCRu_Z_ho_W_=&HRvEqCUrhkdhi=&2vkifiWr_fXdm=&DHKZOnWXlfahn=&XOhb9KZUhmZWZ=&3KxFbhWfbnlbW=&Sc7vnDXZVXkog=&LPgm86VmsWiUi=&DkcwzTVrWnro_=&wNKRjOVehneYf=&VgSiKFVehnb_n=&9pyjrGYqfjc_o=&yQC5ZPWiib_lr=&kncxTeUhgWehi=&HCFt6IWZqUcoi=&Ji9W6uYUWWXWq=&qr5EmKYanfqaY=&IxS5TFVgUocmr=&YLbKCPXqqbYoc=&bDVm6CUVWoibr=&HJcMk6Wqkqofh=&IFK8GbXnWaicY=&9Md52fVinlWlY=&n8QNA2ZnksVme=&9TndAhYjfgnpf=&pcjqZVUXbUmkd=&tpZ4OnZWoqjnr=&MkJiHkWhXhnUb=&5IMpitXfWsqdY=&4szjGJX_gjbVj=&mzKX5AYiegdjX=&K7JTmAWsr_UYq=&UpB_VFUZilh_a=&kKYWxQXiYd_Yg=&39ZPFnXimqsaa=&BjkooBYgdllUX=&akCAVGXYZjWUb=&iKrUMRW_hmjrY=&ZAGRZHUmXnfkm=&iMiYQxUdmoVVf=&rr2ghpZhbsabW=&lEQAYNXsXsZoc=&JQVGZUUahpcig=&wK5okNVkeUVmg=&2IsPGZUsnelhr=&WkQaEbUoahlsc=&YSbsSHVsnUiVk=&DncHOcYkiWjeX=&A3lFLOU_qmfaj=&4GRow5VXYcXok=&dmdD8wXWYkco_=&v8r5ZLVojmkbd=&8VNEoIYjqVmhZ=&4HoEd9Xnegfhs=&yV_sfwUoea_Yl=&nC2DjxVbbaVmq=&khoFBYVhkkXgf=&sSUx33Ysqhslg=&3a_S88XpqlisY=&f582mqYiVYZll=&nZKx_fZanfbsj=&YSvSVxUdWs_cb=&ZqVg6xVgXsg_h=&QuWQ9VZYdkXcf=&XVtdUTU_fgaXi=&HOz8VRYbhXscd=&KxPw3iUilc_cs=&xoiroeWoUonnb=&UjkyguXXhWYij=&gNRrp2Yadrkq_=&VIkjmqUmpgU_i=&MbECCEVbardfn=&Q2HHOkUgqsWqe=&WXchgqXrskl_o=&JyWRsiVU_lWhW=&piSAIaVroljmU=&4m26IHUXZbfWr=&3Ka_AJVhdXhWn=&dWyrwcXrYcqch=&ABDAEnUhqpk_g=&8nm_a_Won_mWs=&K_bGbBYU_qdfc=&b7IhZOUVhVZWo=&vc8iotXqkjYrn=&xI6J5JUe__ndZ=&Hu2uJ5UmUoqYo=&Io5gzcWjh_ZjU=&toYEhFUrWXblg=&ZPXKBhWUhUkgp=&jznlWlZjeoWbb=&e2Tm7CVhgclUc=&FhyryzXjaeqsn=&pOGMEgWphrfWU=&zHEI7kYhdaspi=&lQdc2PXgZgVsU=&mGSysuVihekrs=&MwaWK4WjsUjao=&lWbmaiXrbaXjc=&AmY7MpXdhmnU_=&a6aUMDUigUqcn=&H4iLYlVZeiZWa=&GdtwUWUjVjsXj=&criP78ZnUdjnX=&KcjOtxUajjbbg=&IFHhTEYjUUqnV=&B_sgRyXfrgojp=&iMUUhXZpnfYps=&n7lbEEWUscilj=&X97YFiUadlplp=&dpUtm8VgqZXhZ=&cNKY9iZ_Xbqab=&GzVxPNWeZrelZ=&PAOE95ZWpWVdo=&OVqvdrUmcgcfs=&GexkIoWYqibgp=&yzLln9Vjeqnme=&EoOY2WUbirWrd=&VqBYusWoWns_e=&E_EvOHYopmioW=&lcwNQsUYnXmfq=&wI8i2_WcmcXbV=&JCDP8oWfXfm_e=&ErjyKPUgarUZc=&QuHIgMWWlbrhq=&Fn7orMZeppgha=&uwEyKmUUfUflg=&zdFREOZmna_VW=&zHP6hbYi_goZk=&DbZ73NWfrlUcg=&jiOaRWXVlmVle=&qUUpINXknrbpc=&q9x4fFYi_rWWa=&ZxgNoOXbecedf=&GdufKVYkmXYcZ=&O3DrLMUfmbaas=&zmF_8hYaZZepi=&HkCXObUbfieWg=&mDM3wsZpbffip=&AAMLTcZoZjUld=&SgzlG9UlnYWXU=&Gt6ltzZXsemsY=&RYuWUXXkhsfWU=&_NoROVWgfcsjW=&bNwYmgZdbWnbU=&3E93tRYljVhpk=&LCfDSeXjVkcZ_=&dbD7RMYiqoVWU=&7pq5lCUssWenY=&fM6ahpYYYZmhp=&iLvnZ2XeX_ki_=&Hr5r59YaZZifj=&fRF_wqVUsbcrV=&LtxK89XVhXdVV=&SRQGzEWgbddbj=&3VepheYbWWfdl=&hwapOiXdlodb_=&42gME_YolajXq=&6OhIL5WaWnesl=&guYoCDVaZlgrg=&eH9HauZZqesbc=&QkfXoTWabqflj=&uuefO7Uokjkar=&PsbDbCYrsXjpd=&ffVYbGZsfsp_W=&pbXRylVW_VqZZ=&bMihaDZfXhUYg=&vgjJyVWmWdnif=&3XxJLLWVne_ck=&If5PjoUnrXeYj=&ne7nqnVakoo_d=&P6sHkdWinUihf=&P4RDbHUrdmYmp=&gWc765WWVnnel=&fN3kwaWVo_d_n=&pmnoA2VplXjsX=&EuB866ZUarsrk=&JWtrS_WUqXseh=&3XzP9sXc_jnsj=&JzJ5vPXsUdYpp=&NdEVqxYVfqZnd=&pknFvfXlqVUde=&gx4SVlZnZVnbd=&d3KpfDYlhUjac=&n3FvKVZkdkrff=&BtOFhNVZeaZds=&OYBjyEYhhYocl=&TwJQKvVkoocde=&mxlPwpUnXgXZl=&XTpyhXXngahqh=&hGAlXSVdhsjZh=&OGePr5Wanphcg=&Y9YW2sXqiWi_V=&B8sJdQVpi_YlW=&7eK5U6ZsZomrf=&wgTj4FVkeqVjg=&jW4OvfZaaigsm=&hAp9KvUk_UaYk=&EkEZQrZhcgjZX=&NPeTfMWjZYpbV=&3H7BwSWqWhsUc=&nxFHAoXYnWUgp=&LHRRgbWdecaZU=&AJgEsDUfsfqpU=&hWsT_KYWdklbq=&dtxzZyXiopfZq=&GywGUbUdj_ilp=&qTxLj7YqoanWq=&XyTiceYXosnZa=&LfSOwKYia_Umj=&XSWka2UrYWqcg=&Ux_SugZUdbVbh=&kXAgExXjspVsl=&tojACaWpdXsae=&atILFMVWbobgj=&8yV_peWdca_rW=&5uaf_tZaUknad=&eYttdHXm_pshm=&KSFkMMXsYjnrW=&og7jecWffakac=&Gshrf9XkZVqVW=&EewfBIUibWlUb=&DnqHqQWZWkmhm=&Nh7mHbWnlYfnp=&gYAbJjYqrbhZg=&SUaQXAYaqWhhc=&DuoVyMYsfpUsh=&aFLJqVZor_Xco=&shVi7dYeWbsqd=&HPpyztYsiXVUm=&ITevs6WZmqbig=&CdZDaBVXVbljr=&jMOpxZYeWgcf_=&6NaZyZVbd_h_j=&tkPb_FUbZnqjd=&DmhesJXdYWXdm=&pvjHM6UbdcsZZ=&fsR5iXWlsjbps=&bxT6vUXdVseVk=&bMKmH2WrZcmqY=&zF_56UW_piXrV=&Cgg38DXeop_Z_=&IRIkYVVmXnVUn=&uQVXm4Zkqslio=&mg2VOxWrWYrWc=&U9LP7FZeajZ_j=&MkMwjjUkfjeqh=&NIrfx2Wjlhlms=&UNSSQqU_fjfsn=&yKdg3_VgUYWVo=&HL4WubX_oVmZi=&BMk3p3Wnfpjgn=&5PUxAAUckbac_=&c3rGyjYdrfsgc=&eWSW5hYfkkdnZ=&pSJIN6ZqVbpsj=&4dBXQEZboWnnd=&O8Sm7FUWlZsXa=&e89bMXUcXmerq=&e7MGp_UjmVYYs=&ylAUtoXeam_bX=&ufrFASVjfi_js=&EODhRrXYY_akY=&SDwsCzZpehsgk=&GcWcgOYfeXWcV=&UBdUVBXqiepdm=&szZlGGXajZmgf=&xucsmSVriWWii=&VeiTXxXpcsqhs=&tjkSPUVg_frcf=&dtyOZTZqgcsmg=&9y5aiSVXYoqpg=&CP9LovZjmdqWn=&kgPkzpVfkcUke=&LXtL5KV_jankq=&Q9jQulUimZarr=&Gcv57dUbXXmWY=&yP7Hl5YiYXgZm=&lIoY5NZnWW_Ud=&wEswa6VnUcafl=&ONKo9wZYUkUkf=&GDghL6WnUbo_V=&YlsrCzXamaiXo=&SoQaYyYZrfmao=&DpSVMMYganpVj=&BI2dz3VcrcYXi=&2yOap8WfaqqnW=&bQtmGPZWWmc_Z=&tgBzJXVdXaiYZ=&pigN_eYoe_Wmf=&HdXA2LXiidYiU=&Pxkk2SXfVjsfX=&ptXYduWcmsnUi=&YqWx7iYicX_jU=&3PfZiuWXXsVeb=&Nn9CFtZjXjYUp=&eGmctrVdWos_b=&vtiOGIZrWidfl=&Z4OfruXZV_kZh=&8cI2CyXVUZqoe=&frKGqOWdeaWhZ=&mzzZptYYUbhfV=&eOyRgSWUjobbl=&YcxF_GWfpUWh_=&VBFeYsWXpUoWm=&jKGU_eWWWZ_cV=&TTY3dxUXdcamV=&HG9gvGZVeYVse=&2BwxvTZdUdmaV=&HHdLzPXoscss_=&5m9ROjYsZnaUh=&YQu29TXWcnZrl=&zL2_i2ZYjogdc=&QlqFBAYqhVslh=&hD6IRqWaospci=&TaRTwFWamkZag=&lIH3b_ZkgVbmj=&86BR2lXW_gckq=&KRJOiyZipWgpU=&b9EYXPVidnXVX=&Op6qeGVhhnhem=&SpnsM6YdfVnYk=&jAgOvVWrWsmps=&T5CuR9XirWlki=&CKKLLEYqWjrqf=&mcQYu_Yjggqbd=&Mf8vE6Ynndgag=&cH8bHTWmgbdik=&r3qaUlXkXjqZp=&6fhZicZanfYrn=&EH9cmjXW_jrhd=&daOJqFVkWpimY=&XA4_R5UVqiYqb=&EERxN9YlfeiZn=&pAAIUhXYpcspW=&nQMtNYZhhUorm=&TweF2FUe_W_sn=&yAFqLqXhdfrZl=&U729KtYrcpghs=&hmVB88WebUnki=&SzWu7mWe___ae=&zfr268UdfljcV=&vYsEqlZshrfoV=&eWVx3oYsZaifh=&RmJGtjZl_qfag=&oVpAdxU_ihjUZ=&QOY3W4Ubhgpal=&sld3p_ZpdZV_f=&JCuzQFUeYjkad=&jX92DoUlgksfZ=&hGScBIVXbkmVd=&fPwKMEZUmjXYi=&g5a8o6ZsrVmWm=&l3Pd2NUhocVac=&HTaV6DY_ZbVij=&vQ8r2uX_ZbrXg=&hbbHXhUiiXeW_=&LNamDTXorU_ob=&v5skczW_oVXXW=&945Sp2YnhhrVn=&8THx5gV_YdWj_=&iHXQF_VaojbfU=&oTyEJZVdkflbZ=&F4OjvIUVZmoje=&t67CNOYndskoq=&_yMOTrXUjsVei=&tjHZDYVgpnZiU=&burvoTXhf_oo_=&uGBhBIVYWjifl=&tinCyhWVrdfrp=&fdvOzBVkeZodX=&batBfYYmpssge=&WMrmejXZWcnfV=&6APLxvZfl_cql=&p3b8UYZl_o_rl=&lEQ4aTZgjsll_=&Hk43jOZmXpjnp=&tgdA64UfaVrmi=&k7gcxiUXcVjWV=&S4BXsnVkfesXe=&pnX3kTVaedfkk=&EVOcjeZkpXsXX=&AMSZffVk_fdZ_=&EUbFXHYshssaq=&2W3GtFXYa_aor=&7udT2MWlbnmbY=&itPTLhXVsarVU=&qwbIYnUksgZnZ=&Y2AS4qWZellbb=&vS84dIX_UhiXa=&IaILKCVeceglc=&8oLrwIXqeYidq=&OOCsYCWWrmeZd=&Br99wMVWaVXnl=&3QYJSZYdhifbX=&68KHi2WWYkoin=&lgeRVEVhXWVeq=&hf5xNgWnfpXZW=&wNLwRcZpUjqfm=&H6b39GXZkmelr=&YLhgvfUipqgnX=&G8RNAfYYmXiYg=&C4BVGXWncrfqa=&oKRTPvZaZk_aX=&ne4eGhVoiheaW=&HwbpQmZjaoeeq=&Bubv77ZZjking=&ZBb9BHZke_nfb=&YxIQCYXYsfaak=&olwbRVZZeaUr_=&axwgbzUeVhbsl=&4HmwhZWgVqVrq=&M3lMFkVfqbpVm=&H9OTL_Vooakad=&pkvcwOVUVfkom=&4bLIClYiqndUl=&yuYlIKZYkoeYb=&r4hEesWnepWYk=&dcGbOeZghioXa=&4lyyJAUadq_gj=&sBQP7vWgaiXjq=&F9wuMlXXUbZpm=&4mEbZbWoYadrf=&vcfcvSZappeeh=&_wJrqUYobZjkm=&iwlLzZYdiUgkc=&o7genBUUkjcZj=&kKJt4qZngirdi=&pMMzf5Vrdhnfk=&dvKBv4Ubjrepa=&v5n7qEVsogjab=&7929rTVdhqYjm=&Owfg5WZXshUbe=&isIrQQWhhocdf=&HEJru3WUXfmYU=&Vtw7JMWXrqsfn=&6X7y2rZqjrdaZ=&x2DWf2WrmVUqs=&EANvDtZlbqdoZ=&XpCKBzVX_ah_m=&wFOcgqYgfl_Uq=&TZFIHcXWlpakk=&AxVTQDYocZZYn=&iUCVonWcllhmi=&wHyemwXXiYgpZ=&GW5Jl6Zkfndsq=&iTyh3VWZVpjgq=&SAlQTWWbngVhf=&5YBhPxZeYiabh=&id6FhQXblbVnf=&2mvPQSWWXnXYh=&NvOIRKUcqgUjn=&wGKczbVgaZVa_=&OnrNwbWdl_ckh=&VaZYzSZmmalqi=&fWeuy4XWVsdao=&ylWj9kX__WXpi=&lDvRfkXqnhksn=&UTgWhrXcYbfgh=&DB4JivYhpaqfp=&cO4vjgVUUnk_q=&gUZ7yTVhkfVaX=&ITpRGMWjiUWXm=&8jx7C6WacaZUa=&vycjWJUhahibj=&9FQq2NUbfsdjc=&Z944x8Zme_cil=&UeMFf4YZhgqWW=&bXOPaWZchkWZV=&43rTcIWZbZYmp=&a7QgUCUV_lXgq=&e5QqWUVhhhkhW=&sv37ttXjU_eWo=&LrBK_6XeZakoX=&AR29FXUdcVUdU=&NciJrAZancbZs=&wEn4ezVcrXgjY=&MBTyRmUaoYcVX=&EGpknnYWXWXkg=&HL4I2qXkaegnp=&elIcwAV_olmec=&6Jzw_JXiYdVlh=&Zo4Q3pUiraYXk=&wspZ8oUXmomZi=&FBwhG_WekqhmX=&oRKTlIYqndiiq=&8Nf9n6YnYfoXV=&GxSoM5Xochjjk=&_dfw6gVohsWiW=&tHNcvwZekgllk=&mO2waAXejUVlo=&HyRHkLYcg_ahk=&lOZLDoWkYUlmk=&9R_uXoVmirjaW=&UKtJmJUmhklhZ=&bpbbSKZhVVshc=&2jEVApXnffYWf=&zJkikeWmflWip=&cpaYbOUbYZW_b=&i8snOeXhamsfi=&takXZpUaVsbZk=&ZapxkcVabnYkj=&YQO57SWXparrf=&t_TPUrZsamdcb=&HkM6APUhidqoa=&mIiNyoW_Xmbam=&ijdHT9ZlhXUsd=&ryw3RFVWraoYk=&W3U4HdYcjsnXn=&RW3wfaZkg_fhi=&2N_nM5Wpod_Vr=&kuBzi6UfX_sao=&7bxAyEXjhsjdq=&xmKkOcZbUm_ae=&9YSNM_VVohrjX=&xk9CYOUjbhkZW=&3Syxz6VohfsYr=&OqRslAWaYlbiV=&cz3WJ6WaYqiWq=&TR9aZxWokngWi=&igqaeeZhenpfU=&YUE_sAWrgsYYe=&nWDwq5X_pmXY_=&HOrbMpWfilUpa=&aBHsBsYm__gmq=&xthGmAXrfrkei=&rAA_YtWrcaVej=&wNQ3s5XhXWkUn=&T6PQldYqZanms=&7igJ2uWadjmqf=&37HgcqVgVYcrn=&pbU7vYUooY_qg=&cy6Z2UVYiai_h=&3nL5HZYsfWjrc=&grXuVkVrjaknm=&PH6cfvVedjlXp=&nXlxf7YocakZd=&ziHJxzWfrdhpV=&9Fn8fkXejrojf=&232oaAZjbgUaY=&l6eEHCUhliXja=&Dgz2WEVihldVl=&MzeL4IWXqWech=&LzPeKjUWfkmXn=&VUOKlEZ_oelXU=&S356QxUXrniWo=&sWvsglVZhfZbj=&JAdzu5Uddmkk_=&FrKa6ZVXZ_jro=&fAc_pjXhmqpiX=&kcnGvZWosqbgj=&TapsoCVepfgfb=&URZ_JEVhcoolr=&U9ddOTWdjjkrW=&HU6OU3Wahgenp=&pVbPe6Ungckaj=&4P_CXWWhXajqZ=&548OOEUronlpf=&diXpmjVfrX_Va=&vr3FczUpaaWnr=&zIuTHKXYkXWkm=&V52eHPWcesjfj=&UO58DnYoUkidh=&EEdtKoUlerrqq=&ZcN2C4ZVUhkok=&GRPS9nYYbbcoi=&KQTSi_Ufqoqqd=&ahK9vQZcZsgfk=&GOCyphXsrmpka=&GDm3VhWnkXWok=&Mx5IFfUbVhe_r=&FqqSrRUVmnnUp=&yJanArWqf_iYl=&cU8T5NYllYkWm=&dmlBHdVgraZhc=&9biPFMWqbZXXc=&dc73ZZVrnngnX=&of44SaZZj_Zsm=&jSaFbCWXgqliq=&Pho4UnZejpbrq=&Kyvl2ZUnb_pco=&b5JSo2UiUkXYd=&3LPTPVUiVs_fU=&rkucOYUZYUVoe=&Rh7lMxYmb___a=&6cMzpvWrpoolq=&NhlmiRZdqVqkg=&lE2tvoYnihgni=&43WNENZqkfg_c=&3OQD5oVWbrgZg=&NFColUZegsbWs=&WYUenAVVld_ia=&RcylPeXdngrhn=&fVuDNxWWWjjWc=&pLHypOYhWabpm=&XJIx9DZYlXfVa=&lhJeFfXhrUXZf=&FFNlchWkmWplW=&tvP6rYYsegXan=&W67iHOZrakaYl=&rgHXGlXhXccqm=&_9rd8kZVsdifc=&k5UdMTUXekkWo=&wnoiOmYeYjcil=&7zISTxYeesXmZ=&4_nGrbUYUUZVn=&ohbBZ4Z_ddoeh=&Mdm3tyXirWWni=&iywZESXYdkjqj=&KjxnGSVWsbe_e=&BhiSI8YhmUqVU=&CqqMGFVcqpknr=&vpsjPoUiYobdV=&FRwN8VZmXefla=&XReVktWiYpslp=&m2CqoaVjXcoUd=&D6or53UinUisr=&jZlbomWglmrsp=&SjGVGlUYbaVrd=&ruWAwvX_ndrsd=&OqKM9lYbbXqYX=&JL_SVkYenU_Xq=&89Q7O5UeZWnsY=&QPfGqjWYimrjq=&tddwvqYYhfdhZ=&jNpu5KYUfWrbV=&8bLesXYVaeZZc=&6rCdUcVenXjdX=&hbXavlUcqdloW=&cg2P_6Zhhsloo=&7jiPQwXqnjbUb=&LEd3b7ZYglhl_=&F2gKQVYWloXkc=&rpgjroZf__WjW=&QxWCFVXpdpohZ=&wbjqjFXieifXo=&Wyxd6nYsZiVre=&RwIeDtWnlVnpn=&RXJJTtWWrYeoq=&pPJSSlYiUZVlg=&IdMu94VaXpfbW=&vzOQRsYXU_sqh=&nnWuloVVrplWd=&dQcjD7XrahUhU=&nyqrpCUnYVqfd=&WwygArXYbikVl=&RfvcBBV_o_Unm=&AmbMfxXkhdheo=&ILMnNHVsf_sni=&TZ4vYKZXqWihW=&kzhcn8Z_bVgYY=&sF7Cq9UdfZghe=&RmUk56UXsUYog=&7pJnDbUal_rsU=&GdSoJmVsjnraf=&sRcTsXZlorjsm=&4VUnaXWeobjrU=&Uzrjt3XZjXZVb=&MNYzQoXVfVpme=&ShjlOGZbVmXbr=&mPvTwhYlbZiZh=&ECwlYjXdYfrlq=&JRwlLmYceo_an=&ZlqnVoVUrlhYl=&hLeLBTUcYisfh=&3UtjUxZsqoZXj=&vBkZDjWUdhhZo=&mnxuUSXXYa_rq=&Fr4xLSXiaqdq_=&yfkygvXrirbaf=&LQHVM7XhpYjY_=&eQdeqMUahWhnd=&yHXJsMVcsdb_p=&OSa9EdVrdaljl=&nIkStgXieWfUb=&HjWlsbWismYob=&zxybJiVWZchln=&Zlh83XWnXfmle=&zdxZVIZZqpmlW=&oYh2DGVlhegfc=&ATBcuoUdkibl_=&CDRVlLVYcsmhm=&RBuhbCZroWlXj=&x899dqZWhmXn_=&5ndyYhXnqUUWs=&votw2dUWbgnno=&eVey4hXXXVZri=&XqAoLFVekYrsY=&m4_ORXY_ZZeVn=&9Ax68GVWfhUVs=&Mc8ywgVoiqUlY=&iYiYsmWddVaVh=&6Zqy98YamgYYg=&mZfkK5ZpnUqdf=&_euxO_WYasYdr=&KU9FdIYdjZqbb=&bE6jYcZmaVmqg=&WwuPLoXkecfdg=&aOy275XZXrksc=&aifC4JYbhXgX_=&LZxpBlWsmjsYi=&gSKyKdVakrdni=&AZMiOXZebXXgh=&pVuZA6WWYdZhs=&DECOsOVsWkrfh=&Yz6hbTXkh_oe_=&_QpyMLYZpdmpl=&oPVPHVU_r_ZZZ=&bl2nTuUgkslcr=&se9rdxUgiWddY=&oPolM7WaffgpU=&N7cqefVXgUggb=&OAQMBPYqlffln=&xev3BPYsZpWYd=&cFaEdHUfedkeo=&puNJNlUUneWVo=&xwAHC9YsWZUa_=&aNLRQXZYVpkhj=&M4BSdTYhcUffc=&2a5wQNVrrmhWn=&lSq3n7VekdbZl=&Zx5ZY7XsWVpns=&d5iBYaZcopqmr=&4YZkwpYacgdZk=&NLs6nLYdm_jdp=&chDdjeUihrXmm=&SM8nZWVZWrgqp=&67O6w9VknkhXf=&KCH9lBVlUrVXn=&DPAe_BZ_lkVgb=&WPT32gUeslnln=&P85Kb2UqhVree=&U_cGypYffhijo=&JaH2VuUfegb_j=&qKZ7mwU_bckhc=&FCNrtKYXlYbmi=&8MrnlCVjrpXok=&PbkPWHZmWisma=&SrDHeUYXjnsXU=&Dr3vDrZhfnaq_=&wXzr7GYdaVWjV=&Ujf86XXdlda_e=&FntoRWUjbpUrb=&LCaYwbYndUrhp=&WmAprRWgjkUni=&JM9sRvVgW_gbo=&CVefzTUX_oalf=&fTV3bZVgbeidl=&7zLH6OXaXrhXe=&pdnl4gWiZX_br=&bm_RMjZgoagbo=&SbJjpWVV_rVcp=&wFLgaqVjslWgq=&2WVMB3Zs_rbXi=&GW48uxYgZed_e=&_9KC4WXYmXhdW=&BhLRalXloWkoq=&zW_R3VXWVcWjl=&kk6JRFUXqjchc=&LAQckVXWqZUqp=&GRJO3IXYlecbY=&NbWHDYWWajbfa=&rKlUR9YVhZhdn=&9FQLmpWWe_Yci=&lQPH9MVcZimXr=&pblACXZnbepZW=&WhIqnCW_inZXs=&snRznuZ_mfWfq=&MuI4YtY_ocogZ=&Ddohy5Udekdnn=&csaBzPXWpimgs=&BYPxrKUqU_Ygf=&cpRYrAZqqgYZk=&Ss7BqoWrXgYXl=&N5Iu_XXhlZgif=&Td4qVsUZbdgjn=&NkHJFaWldoobg=&jR89hUYesajii=&MAP4BIZhUVXgW=&QG8z9jVYbYZeh=&ggqtbUUgqilXf=&rcXeunXadXqVs=&VrHAUQVbpmsVW=&hwNP_IUYchjdX=&qymNDZUs_jcnm=&ude_eaWnijYki=&DyL9SoUklelhc=&UhdnfRZXVnqW_=&EuORcAUiljisg=&8IAIjHVs_jXef=&a_PWY8XpdgiWg=&ZgGdXHYoXihYl=&9pVbiqZjgsdro=&jwJZ9fZlkXkrj=&yIFcXnUibefao=&N8wCPMXkg_ofo=&ZfdE6xYhsmkfm=&M5asItYprcqZp=&TmLxJGYdlfjXo=&cYRsj9YlsfW_n=&Qju6euXYXoncq=&3vpcKJXbkUfli=&KdB8cAWWgebor=&To8qeLWdfgXdo=&mfVlWiUloVZWV=&Hp5QCkZYXWrWi=&j2qiuQZUrjlpm=&cVD9g3XficjnZ=&GZy4bqVpZeqfq=&2tyeLHXnpclno=&g6K5QnWdonlZj=&bwnGzgXmoYdqa=&i8ZO3BVafZsZs=&e3yCzQVoWjghV=&AFtgtwYiYdmps=&QSe_IEVVZriXY=&J2cO8IVo_VWnf=&A4TDtKVlrrUmb=&SpeOsRZfXmZgn=&dyKjdhZgahjVr=&Q8dKEeUXiVhhX=&6rpGgXYYimbpp=&QnlCPoYhWghos=&P5CTw5ZifYqfe=&WHayRyUlkXppn=&dGtNW7Yfflnlh=&slCRvVUUljkqf=&zlwjpSYsdZYha=&IRQAgUUbejfdq=&2dlvReVmbefYV=&ydT3NFYp_ibpk=&FlRE5oZaVamUg=&zPscH7Vrqfaih=&rh_sxyYcZdqdl=&bkDQoMYgqckrU=&NQ4fPsZiaWjan=&7zBSwjWUkicnh=&boIaSXVsbpqXV=&WaGb3lXapVmic=&nCQOC9YcZoiib=&7uueneYjjXeqj=&9SH9JbVkckVUY=&xnj2RcXcZamdr=&OmzFJ9VX_ngb_=&kuId6AUeecibq=&Q5V8yRYlYYrjd=&kgMpp7Zprgneb=&VT6U8NWpldWZa=&SKP5U5WVrhlgg=&7ORv9XZpnZpX_=&PffMAGYmmj_iX=&OoxD4hYahXqqr=&nZXAWVUnVllUf=&K4YcaqUjihsYW=&3fcNjxZioeqlf=&m2bq4GZUnUY_i=&6TxisCVYUarlb=&6HZkBWVqieWWi=&pOwtQsXXlssgs=&hJyC3SZnfoXWb=&UiSPfTXeVUnYp=&uLZ6EGYajh_mc=&2jucAFWcfgelY=&5IONVNWXnpgjk=&AsI8eoVrZfZUh=&7wdbeUVlqncog=&3xE5UIUndifWr=&EBDVcYWcsriWX=&hEk2yuVoVrrjg=&aBwK_pVZh_WUY=&dZ4ZlgWblpsiV=&MPakjjXmXZbfb=&XzfaE5YVsYfae=&E_CFgKYY_b_ji=&nmyqKmVVagkUc=&nYYOeJYqflbea=&SpWJyrWqZqebq=&OggETbYlocell=&PHqzLNVidkqrX=&aRXO8DWUlUnbi=&2RZhOPYnjnesp=&JSjHkcYahqjZZ=&ZxLKZEWaeagYZ=&_lvcxoWZkikYZ=&Ofj5cpUnekqqh=&mkHPnaXo_bboZ=&fnslSaZdcojpe=&BB7SHEW_mdhdn=&W8hOhPWhZqa_p=&H7uOwVYZeXj_k=&mstzWuUbiVsnY=&hI46uRYgidXep=&o8y3bdVmlUelf=&J77iu3WrfaWi_=&YTaKlqUWfpnqs=&EoR9cuVgb_p_Z=&nEzE_VWlrddWm=&ow5qhvUao_sXm=&WXpMAxZlks_mW=&AoOYkWXpmsYeh=&uJkWoZWjnpias=&lORPP4VpZUchY=&btHBRyWriebik=&YimVW2XWdlWXV=&43FK_oWepVYlU=&9kseSAXrgWfrb=&IY_q3gXgrcbsa=&k7F4l6XbgrUki=&pGu9JEU_aZk_g=&aGscUbYmipaja=&kKF54EWb_Usks=&7b_ZYKWiWhama=&aqAsRTYiUbeZp=&3aQplcXbfVWmn=&smpbYYUerhYfY=&MZ8oIkZpbbaXm=&9YHH2UUZiUfpX=&G2N9ZsXYdnabU=&fhYjFwYgacljl=&fdKHY_VphpdaZ=&IMAQD7XdbZahl=&lxUrzdZhgXgej=&bqWVMBUdonihj=&iXyTH9YqegksW=&qe8bkkZXlZail=&jWcI5vXZonjmr=&iCIQgcWWjYjXU=&kazwPcVWsm_pl=&5HtnLyXidUjlX=&u25kISWZjnasp=&56ArAPUkgebhU=&VpzfaFW_mVdoa=&5huyMSWjel_dV=&G3ujJzWqmanZe=&mD4TOGVaXimld=&2Eus8qUflqgbU=&5gGLsJYcpjgUZ=&uyCb2bYngmchm=&jSMetHZUYXrWn=&dcSWYgZZlVseg=&F39JxHWsecnsg=&BrIvTyUgi_flj=&37HVmDUWhWjXb=&jWQWzuVUlkhom=&tJu3dbZfmlcoc=&7FPx2XXokZlbs=&UcYYNIUqqpbjf=&L8TKagYiVqfai=&iUtGJwZ_fVqWa=&IMRdzbYlZWYap=&nZZfVcUUXbfrU=&xmckYMVbdrasW=&nJHAm9YkroYgX=&2HORkQU_Vrran=&AXnQv6UgVarba=&tgA2CCUnegncn=&kYLOgDXYbYZci=&PGHmE8Wqqojri=&YhI2rEWrfZYgb=&tIUUbSWpYgVeV=&8k7GvLWgmgXdi=&g7nm3qYXpbXZZ=&iuWIvbUijrjUk=&NJTKlDVpXblkh=&XzDAdEXafoUbY=&wXc_ejWorZarm=&gsIgrtWobWco_=&S98EDKWmeisrm=&lfKp8RYhmpjXs=&Ul7CsxUqcdisi=&zxL26fYnlnjZU=&RuqrG2Yqpklo_=&22Ji6MYpZolXh=&OuFZdwYdiUWX_=&vEO34YYmodZhi=&IlI5TFWbfWibp=&tmqTyCVjrZqWb=&tjsFw6ZZqrZcl=&WxTbzLVehZeh_=&lE5ryaZ_kdjam=&WbmxI5ZggWonX=&zXhqTPUebUfsm=&T65PbEZVcpqZl=&IUC6yQYVhklns=&uOMifuYefoasf=&CdKuo8Zeahanm=&Fa_SAEWscdfhl=&jSdjzeXXcloao=&fFY6G_Xhkaror=&MZw7mwVaprhVl=&lWbx6NZjscpmp=&hmfB_iXgqnWlf=&ySpNoeXlkphsl=&gRbiJMUgjVk_a=&Iqf9IwUlgUXgW=&8WLaQqWfh_jlV=&AbdOfTXWikYpl=&YrmOMXWUjhaVq=&uZxXcRXiolojW=&CMGgzyXkskdnX=&_8TvzIYbsmg__=&AZwkzyWckWrZf=&NksqNyYjrkckr=&9pU9m4Venk_lU=&WSGBjIUVfUcXU=&Bka5zbXdscpoZ=&SvSKf6UjhUidb=&24Jzq2WcgcpqV=&8DMylGYrek_Ub=&RcmCaZWYsliXd=&Rneo74WfUrdlq=&gUBxvJZYrhkZV=&lqXidlXbrlfYo=&qAm58fXs_cVoX=&eChaBOVrkbsa_=&8c_pbaWZoiYng=&ZJ7L8RWj_m_Up=&lbGOirWfirVmp=&lNBO9QZrjbnWZ=&emG5WuXgW_Z_j=&5joDOOUXrUflp=&qg5c88YrZfVr_=&FTIr_MWproYmi=&aYPXIAXXhWiia=&lqCI_HYjUenjk=&rc5NYrWqYlYar=&PIWh7gXVckjhX=&FimRJmXggbjUZ=&myKj3xXZhqfZi=&fvwaxQZcbah_l=&klG7AuUWVWapq=&5tS3JSWbp_XUY=&KZmpMtVghrafs=&3PmY6MUapbYsr=&qD2YaNX_Wlnds=&Cake6yWeqUWeU=&7OfSekXnlfnbi=&cqRXFUWdkYWkl=&s_z8WzWkeqkie=&mIEtgSYfjYjUX=&dkeIXyYndhWck=&9sXzbXZqXllkV=&ensrBUZXjedcm=&g82bGrZrVcUi_=&4KBHMtVpckafe=&aqATicUiXYZXj=&tXS4vvUViepnZ=&7wnXMlXZrdfYj=&pETTiDYpcYqsY=&wc8UJFZXsipcf=&DubDYAZignYqc=&fQavFkVrps_hg=&WP52CNVqbdhiY=&3HswxOZiqVfqi=&WJ5ECsWWnVjbm=&299nn_Zjbjqsa=&hXbtYjZYXjdga=&jZDZYYVbYb_ka=&PUY7zVYhjchWp=&67lXEKXa_Vssm=&BfE6EaVdbWoXW=&BToQydVfgUrmr=&qLKZQ8UjppnfX=&8hGslqUfWlhZs=&q8f6DzUjgrknj=&XHUJilUVbaamn=&dCHccOYdWaYc_=&LwKVEmWoUkgon=&yobUehYkXWqlr=&G3YKWsXmdhUbZ=&GaOkF3Waechkh=&bNxs62Z_kZmos=&bHtawFYrrhs_W=&cUl9NrWUkrsds=&SS7cinUfk_iip=&OlqCerWoaeWoj=&qKgpjmYamlpaX=&tbqwNIXiZpdmY=&fyG5FUV_nsjZh=&yfRATLYWbgfdo=&Iws9_BZkWqhVj=&7Ajm6cWhbVqai=&C2xTzMU_fnejo=&Bppc8aWoYloii=&CAoiQJXlljrmX=&V9o3LiUmabcdX=&NaPJHEWVZchnr=&JRnH5WXiobjme=&ditZlmVqbliXZ=&xi6blFUWX_rrZ=&BBiwQLYnn_mie=&WG__2dZpdhkXc=&jQEP6jY_lasZb=&L3VR7gWoqdVgi=&82QGrWYlbdbpr=&KQmmRwVjiYmnj=&robGxWXhaUnqb=&ZOosGkXnX_Zoi=&ydj4JKWiVXbeg=&lzioJdZdYkakn=&JRW52lW_bgUhZ=&tVpMdEXZdUsjd=&iWRf4_XcgWsUd=&lI6EpwXVafXbZ=&LvYa3tWk_Ukgs=&eOMUZHUiokXse=&pJByhnWjiibln=&_nNciaUXieZ_Z=&ITu7y5ZmZfqZk=&rHLDkGWqZskVb=&UdEYEKUramXsg=&LnLdEiWgqWbbn=&Kj3fVgZl_daUh=&elS7AMYY_gfcV=&PvKHstXkXZsUU=&tTvhHSYnklXnc=&IM89LcVmkkalX=&sD2htqVceroaj=&eFEdQCYmfWclZ=&sjxQ4uYVsrb_d=&RSLp3wZXWsbWr=&BRDhXVZsqZeYb=&7ViuFDUnle_oe=&6YQ8eWWdeqnde=&4pembWVVpeUbU=&pZU9pyYoZUffb=&srxiJaZZkldsq=&IWqIpEYkZW_fk=&s6We4uWcinaso=&F6EmD2UqplXnn=&J8u6t9VgjZnbc=&ldSjqfYiccrYU=&3PeNJWWpYskVk=&UG9berUcsrfV_=&EzDv3vVgVXWff=&V98tVfWijYgcf=&F27jEWXdmapfa=&FnYI99XjWpYrV=&MbVpsAVag_iUf=&AZewCbXceXrqa=&Y4hyPvZnVdpki=&pgqAVnVUrlUmj=&TKjz77UbsdnZk=&5anwrqZejXjb_=&SdqmbxVgXsfnq=&z7wowNXsrYksp=&FsjNwJUjkdccl=&doagNZYfroYYa=&HHSYw2ZlrppWr=&y5MfDqZibWjcY=&MIaxLjYiYeXXg=&AKDrVsVXbgofm=&W_XJPmWmmnZes=&j3i_QxVXbjlZX=&x6iGsOYfcYarf=&VrD_ygVWZ_bnq=&iV93DzXekWllp=&jSXfBPVqYkaYd=&DYuRlBUqmlWhn=&9qCPzeVqiqg_e=&66uAKjVpii_oo=&Dv8G_cWXXhXbZ=&UPLMcQVmVrYki=&4NKSo7XVaXppY=&hEYedcXYbfeVX=&aNnKYbV_WrjZa=&YzvvipXkmsVaf=&cjuqW9YsmWabd=&5fG5CMW_rjVjW=&Xnqm_GYmace_d=&OROzmOZrjU_es=&I3vUdiZUpqXmY=&sHL2fPUbccs_X=&qo8olNWhYalmk=&a7EZc9VicVadd=&WnFXkNUoocZrl=&jBPiPqUrbqpW_=&oKC5rDYqhqVkp=&Xlg7lBY_Zinje=&Ho5IHQVnobWm_=&EicpchWUX_iam=&uIKMhhZacaWjh=&K_2YIwWhbmgaY=&iO8HkGWojsslf=&DoRqArXepilkZ=&yB4C9NVahVl_s=&ud5vfbWlacqnZ=&FCeVQYXmdkfY_=&6nF3ZUZsghlYa=&FKqj65Xdhqphd=&xk7SJbYqalfUs=&tuWvw9UUqraYU=&J_a5rJYopVgrb=&xyGwMYYXikgqb=&kuHDlXWsrehWj=&2iPbnmUgro_rd=&J4jGU5Znis_VV=&t2nzWvWrUXbml=&kJ68GZWZcZ_bk=&iwmiIwVaZaZdn=&fs_UjHVpcWjYX=&7pPjxkXXehmpf=&WFby7uY_gmiqr=&CV69FQXWUlpWX=&Yl2Xz3V_dWiWV=&ySAdPSVnoZoiW=&vCUpKQV_ofhoo=&iPbMZjUUpUXmV=&iQmWMkZgopbka=&YOJIfOXdjpXhZ=&5hpSVcUXZq_rj=&99gKCZZrmjkon=&NXmCxzUrkXXlZ=&q8LCbCXpfdYZp=&hLFCVkXocZqhU=&Q_duDqW_fbicd=&lFncvcUm_cj_g=&hgWdNLXrsckcf=&yFxzgWYWe_pab=&qKrmKKUhYahfh=&XkPVqxYanidZs=&TutgHpZiepWib=&OANr5KUWXhnak=&qHBR_VYXrji_e=&thIOwDVakoaiX=&c7dZoDZUamZek=&4qHHoKXaddcaZ=&qF3L3CWjalUef=&VcbjqzXYfc_Vm=&7ytq2sZWhkVVZ=&7AKzFaXbp_bhm=&V53J8DYUaqfVX=&IqdsiIUdsnjZk=&sb7YoJWf_bbnd=&ulWIaYZVbr_fn=&OMlIV_Z_YrqVa=&dqyKMFViZZdef=&7XPnzsZedmalq=&5sf6OOVjcankW=&gQNdnCXjpbXfa=&tChivUVZgpedU=&U_7Dy8ZbZoebj=&LaiFUGZqWajVk=&mmz6VWWVbhWUZ=&26JK6iUksVkcc=&Y5ATbsYgpeniX=&qqigF8WijaikU=&pv4lZyWWZslos=&hsbhG4UZg_iVb=&6LscdLUjbfXhq=&bHPsWBYfjagmX=&V2zAZOZXjYdlg=&ERVOwGYifllic=&vwwvE9WWbgonr=&rduVkFZebrUgU=&TJ6ybdZgg_dUk=&NkwgylWjs_ifV=&ppk7j5WeXmhfr=&_i2M26Xibcrps=&MFhOgTVqU_nsq=&TlXhyvYhienea=&kuIASqVY_V_rg=&EPHchkUmYfdqU=&7MjJpBVnr_me_=&J23PYFWZe_dgl=&L7ZUwTYcrmpoa=&bH5ffgVjmcUfm=&bJrUL2WqVZemq=&nuvVGYYbhYiUY=&2R_3UPUqcmYXn=&7CxEE9YZmVfal=&yjfdLlViUjoqs=&vILQSyZWfeWpm=&IWedLoYncnWYl=&qyFcgbVg_kYWU=&EWp7GjUqjVWbi=&uuGJ9HUq_oleq=&I2883OXencZjq=&boNVyFVbWdjWb=&2jxRFwZo_VrZq=&AeuOIjWf_cZYk=&nFwkE9YXpZrUf=&4DTBFsVedWiqo=&DQ_FfwXYYfmff=&9qyLO_UjsbZhg=&8DIqtnWemYZem=&VnkGMkWVWskqm=&3ZlatHYYUoabe=&5ycr4gWjljrih=&gePrY2XabimYo=&23kp38VlfUkon=&Xapy4MYlVdVqa=&GpwANXZopssjf=&gV95blYmngqWb=&DUUZqtUdlfjm_=&W6LkRPYabXhZf=&6VIA9qWqlaYrr=&hJrcfmXYjfZ_V=&MzFGz2Yslsbba=&qYlRLfWVppWak=&QDLo6sV_bcVVW=&z9JgAnYZbobgV=&HzzMQkVhgWlZi=&Dr3vMYUc_m_eY=&ImVFWNXbU_Xjk=&rCIag7XVonkin=&SngiB_VhjmWgY=&qCaxOvYnVmUkl=&aD4LhwZeloZXp=&C2MJEUU_n_mUY=&VGg_IrWaVVbVj=&hZgxMSWjmYVco=&mvNq7fVdfr_aq=&jJq_lXVXqhkce=&qfOZB5YfccnmY=&Jni_VlVZgXUak=&HsqzgzYpq_ZWc=&I8EsyTZar_bos=&mpvFBoZsaljnb=&VsqScpWjosYos=&8GnUpbXsVXUbl=&Mzb7omWYiX_jV=&SmEORuXiqqloU=&UmCCIYUajcgss=&nv4JgYUqjsogg=&r5BjKaXbeonhi=&vm28cIUlfqpWf=&MHjKNjWgpVhff=&WKecg5Ummnaas=&pEJzBiUikbYbZ=&qGSFf9Ulsjkng=&mLDZbgYrsqkcc=&qO3Jt9Wqp_faX=&XsCjdsXapbWgV=&jS7ZmbYUfVZVc=&8TCzZHWVfkXX_=&xnoQyNZgmjfdo=&dxC4XgXdglqZh=&4u_JrQZbmqhdm=&7uMrmfYogfnb_=&f9FEevUnihXif=&3xEi6zXUVjqbi=&3AZSh5Ubrssir=&HFsfpKZeqVZso=&Tn9tQgXee_gUZ=&LIkbaIVbjjgfa=&qbMBzfXqljUes=&MZkYfmYerr_qZ=&XDYYwEVUUXVVV=&IO5L9WXopeX_h=&txY2DDXc_rapd=&zEhbjfVfmnjjl=&HmBKPyUdlfWor=&LIzaEaUUprcqj=&JpkEKCYVniZhX=&KfjTvfVm_pdsf=&H8IhnoXWbossV=&uJVO9TUfcogoh=&RnIZ2SUnZgWXo=&4D24jMUXVprnh=&piOcKDY_fskgo=&gbhbZiZnmiXpf=&JLDeTtYjnmbal=&MsjVIPZmbpYkf=&EkZYtQUXceig_=&GxNZoUU_VXrne=&G5u7vyZdXcW_j=&Qz6n5nUVifZph=&lEPxHLWmcWdhm=&2Szq24YcpVras=&9urzxPWhcgkrr=&rw4WTjZd_VbXo=&t2PEfAWZ_bbgs=&vOfsdfZiYqssi=&_4gizZWacYdUb=&uMgzDfWWkdWgp=&YZuHSXX_ijZYZ=&gvkRVZWfgZjXd=&5833ZYZpqm_sb=&zJwcINVjZkqWf=&NE23WZWZcrgkk=&8g8sqiZpnZZrV=&vgf_zJUkjfYZg=&hh83p3YsgkUfg=&p89HvDYronUWY=&dWXNeQUbakarW=&ef3keMZjeVsgp=&2Kolm4Zhhrskg=&vNDZsZUVfkfbq=&DGrmsuYiiZesi=&hGIAIQZlcjrii=&ZuUbFXV_ldVWV=&cmE36zXipijVl=&EScixgYnksdUk=&GhTYoZYlegVoY=&T4Y9bGVcZcWom=&ali7pQYfaqaiY=&di2YFcXpdlfYV=&cw2CEwXkjdbfb=&R8xf5mXcbhmeo=&sPMHi8V___fbf=&74JfiuVocsVXj=&F4Aqq_WXqqidb=&ImFXlhUgdWkio=&ztpJ5oUsocrZb=&24NuGpZb_e_Up=&j4oXJ9UVZf__i=&rH3BVNVmnmXaV=&_uG9bAYobfsdl=&_7vYLDWdnjpfl=&FhPxywUdXXrji=&tjthmfVlZWmgj=&w_EezLUfbmVpj=&IDeirqYkbrZcc=&2WAvdkYadnUYq=&O_TC54XpnUn_h=&PtCJ72Z_ecrUf=&7VkxsSYndUnki=&Wk4JUqXWfqfmq=&vWf5IeUiVnmjo=&QfAdP8UYkVXgX=&U8yox_XVZrbhV=&yWnp7PVglbUkp=&Z9rFwtUqpbhbr=&HI6wpHWfapfbn=&NT25_fWoZigpZ=&_FyNLMUnZbnkU=&GhAk9hWZmilsZ=&oTTXUTXjinYqq=&AejxbVWXoYdel=&4jJBBHXiaUlqX=&wEKOIHVrgUnX_=&5_SrP4Zbfgasb=&LsDWGtXsmnVsZ=&lLtPRzZeUqocY=&kU99auVrnpqbg=&cBKINPXbjXkhn=>lEf2VnnVmcb=&2OwkJdZdnpdfs=&_lekEUXnr_Zag=&WSDERUYcdZfsg=&U7EcLSXaogpfX=&d3kJqkWXgrslg=&YCSno7U_ckjfU=&Nfi8alWq_qcdY=&mLXiBSXebngiV=&cuXk4_UjjrWcs=&4SJIeqYYrVXUe=&knRJ4yVgiokhn=&b_nOPoYgmYWlf=&cC2Bf_YbZcrmp=&VfdcBbUZbqlbs=&zpZuYwYmpnqgq=&dJMZrgYjgkdcV=&VFThpxYifshZU=&UeFu9tZjnXkVY=&euSOL5ZWihmjh=&V4ygmCZkcqmsa=&JqdGDoZikhaga=&YadLHNYkse_Wl=&sQtRQiUZegXeb=&LV898UWlfVWqa=&8NjX4AZpZdUbX=&wobkLmVbYVocY=&oheoMCYYsfrsg=&OA5IExZfmbYmh=&k2zn_FVdXlUir=&fIqoHyUpYpkUh=&XLY_n4Vjknhhq=&jMVVWUXrZYjnX=&kFaGSMWlmeUiV=&ZCkSXpUi_Ulrs=&P3hQV9ZYbefkp=&nOsnS9Yegohiq=&Vznc9bYUleajZ=&vHqtpxXkmk_js=&FlpdH6Zo_Ueai=&mTGJ_yXgakbmb=&eNm4m5XhshabX=&hAlTXlVYpejro=&h8jLkYUVpYoZo=&anpo6XUgkfldm=&gdJXMYUlhqekW=&4sKhM2UrmqoWd=&tuRZ9pZqgaZeV=&xA2PeEZjpbrgX=&gf6zsGWnZZ_lU=&kamK4qVdejVW_=&TfDChTXcsXlni=&3misyhYjeWkaf=&knOUAWYXUVZrq=&PRurbXWihcsoX=&3LYEjMXpsmfUc=&sbUKULX_UdYcV=&EGh_9kYYiqnml=&Op6ARoYbZaifp=&vMRke3Wrbjake=&OBemO3ZXmeebl=&dqQEixXsnikYn=&8j7qMUWnhqkbe=&7WYhFfZXboiep=&SDWXbOUbXXhki=&K9ztMAXWrWVos=&kcE8TDVmnYlkV=&3dhnrWWhpYiel=&WysMoRZrqghgf=&ToPVVgZXZjbZr=&aiQoSrYhopped=&W4EGVjWfU_jok=&k7eyZjZh_jpVi=&uXV9mpZogkaVq=&qpGwt7YXo_dXo=&gN9FmiYYefVqf=&NLqADnZcVnUlj=&wUVNfXUqieWad=&dBB7nRYWniicd=&jyAxSNWUmpYil=&vH2JX6UoUgUoh=&ioUwEXUXdkn_p=&9mdBDgZfZjUYo=&JYUjriUVjVjZr=&kIIBTOXsYrVoY=&bmkTc7VWgoeek=&qLHQJ6Vikbgan=&NX2fvKVikXgms=&eUvwc5Umneoli=&EM5AbJWrmkXVm=&gIbAL7VhVhoUp=&TvboWAVkppoZs=&MBycCPUWZVrdV=&TZLH2LZjifhni=&rvu_aVVdrUqkh=&SbisaPUgnXqdq=&b56jcJUYapUgm=&vgR4GRUeYWb_c=&MDmSWxVpWUfWa=&KBMHwJWikYVen=&rvjdMGWrbcdWa=&wmvOLaVdejinV=&nKHQK2VVWdgUb=&c8sc6RUXmXjXW=&TBgT98Xpp_W_c=&r_LUnxZZWfVYl=&vOw5dQYikfeae=&tTiehAZlpgUps=&4qgypcWpgifrc=&3AWEikXaqprsa=&OHpkWuYkXsesg=&EZrg_tZjbkhdn=&2LpTLfV_jjfXm=&TT_ZJWXkWpknq=&4midXTWnVYhqm=&zQenriVsZlVZd=&cupGZBVbjlXpq=&VAJOAoXZqUX_e=&RRvrcFYUhWlZr=&tbq25RWVjqnZX=&83wCo8Yllrehf=&KTxsuEUl_jqVU=&cijhcmYngapfm=&PIGqtmWneViZo=&zIA7iPWWVdngm=&PkcafbZabsesU=&FMDJskUhjV_on=&TdD37YVqkh_pd=&2Bi7tUZXZkYXg=&Ifiiz6Ye_nnVV=&rgyQTyZbf_kbd=&CMmZbsVsloqfW=&fQ35kHYhqUpah=&SWZTVJWlXgVjd=&pu32A4YZgaejq=&Ubat9NYepU_bc=&ZbMYAIU_rk_Wq=&4HixP4VWoVb_f=&qMzo2pYjkqkqf=&9vs4ZYWZlcbZi=&QotF43YjlbWsl=&vyMY2iYngaqWU=&_SDiT6Wgi_Yce=&WNWVbkWrUeYhs=&99HUmgUfpZoUb=&lkwT4_Ykikher=&UaJMiDXrrUZah=&88taPrVmjeYkm=&T9vLcSXaksVkk=&SlTZJKVZjqhli=&5jplZGUkeaa_h=&wRD5EgXVoiXem=&bBktpuVarcmcZ=&e8gxkTWpZmsqq=&c5zRS3ZWbllVU=&pEL3JaVhphpdk=&s8NuDSYgXoonY=&LO5zagWZbhqii=&a39oHcYnlbUbU=&4NZsKKUdennof=&chYKvSZdXWcXl=&5Jyn_DVafcgdn=&i4qW6TVkjcXml=&Mya2qgUde_eUf=&n4mhrpX_mYeoV=&UINe5QZgYZjqV=&JjRGBeZZWUYYp=&vQ_UzkZU_mZfq=&IqrlNOYXU_ZnZ=&yL4WRRXpcWmVe=&KxqxShYZdanpc=&3xkTaMYbXZfqj=&hp8p4rXkWmqjZ=&xbNIJCUYhlsdq=&VDJF_LYljiiic=&EZSVxJYmmnhar=&6nZwbqXdZWVn_=&6kk4DAXbhUroi=&yREsarVifmdks=&v8muxxYmlgmhn=&u9ZnAFXkVjhsi=&lI_yj6YpsWnak=&CquMTUVlfsipk=&_i6MP7XY_aahl=&ZYmWGbUXXsbVp=&JODZylUr_hhag=&9jQ3j_YWUnkZh=&grNYFdZWVUYfW=&taHeLSYaZcVci=&p_m6eoZkeYsZh=&CWwXjlVsglsWW=&U62Dk4YmrglgZ=&eoR3pmYhkbgij=&hkcPIAUmjXXfV=&Gqg3lkXjbkrsk=&aCQ6mSYqWqrah=&HTlkI4YfpZkVr=&_sdwiFYgcrpfq=&yWVg9EZkgjjkj=&8KpXcxV_adpci=&hTjppEUZjZros=&HeiDnEZZZdWrn=&bdOXfGXeqmqa_=&BubAhJWjfppXs=&lgiLcfXqsXsek=&IRmyCfVepWseZ=&u9zkLRXljYsch=&HEZUnmVcVfrgc=&4hl8nHZ_UpYje=&UoZ5moVXbfpah=&gAnamRYmfWjsZ=&aVH5YwWrVadea=&SmDBOfWlgUYZm=&wyWxTPUgWYiae=&DUQRa5Y_caWZg=&2m4f9yVcYrkVX=&aGLqDIVclWdjh=&rsGwmTUfenofc=&2OCIXSWsfZcZ_=&gXqOjdUmgkcc_=&_QYALQVXiXcbi=&4mofKFVpneash=&v75PztVlgghrp=&R85tKjXpWrplm=&_4igiKZjYdjee=&OJCDHeW__efid=&5pLA5JZfpiocX=&7IjWKxWrmYlkl=&8o54R2Uepgiq_=&R_LxEUWWgqWlb=&jXPMUTZbpbobq=&Y9CnXyVV_ohcq=&dsmgNmUiefrsX=&DlIzg_UnfaZbg=&DZRg2yXhsoYhg=&yaOEnNZWilWpq=&fQuKIaZcUVYqU=&bB9UZ4ZZqmsaZ=&jiVmRpYilhqcl=&rELSobUdlXfVr=&_GJdG_U_nXefi=&QR6y6GYibhbcf=&ZOytlbZssXbrn=&SQwTMOZYjejgn=&WF6RVHYpcneYm=&e_SrZSYsmejbV=&gs8TzIWValfZo=&wyNX3CV_mch_l=&Ak9G2mYlcZfn_=&BKPLAWUdhipmb=&MsgCr3UcUWWoe=&cDZ8xPXsgbcae=&D4a8UXUjVqghU=&aXaz4JYXrWrfX=&Ylpwn4UoomUro=&JQhRSYWibnljm=&oNcIwBZesjacn=&5vtKpXVdsehgY=&oDCJVBZpfmniZ=&UlwSBNZbXZerp=&CgUUDFYn_fisf=&7lQbnqZiseid_=&ZFhQ3DYl_pprf=&w2bWzDZoZUirm=&_jFYz9XdnYsrm=&e_hUywYd_WXmW=&fVIXVOYef_dbU=&iMjfWZXrfWebe=&EJFNjNZfrrVYZ=&nLZOaLVgjaYoV=&Mvz_4NZkqqiak=&2varruYqhfirq=&AzgUO5Viqlgdr=&yFQUbDWXpZmhs=&PagrnZW_YonXj=&UQ6kVPWYUmpXg=&PCm5AZZhjmY_e=&YGGMM2Zdseabp=&FOO6cxXhcssgs=&r2mabHUsaolrf=&wbUk_4VmimoYU=&vDCxT_UqgcqkZ=&zXnxKvXerhqnm=&9jGfOOZasbhog=&kPsLC5ZUdXqgo=&KyjZetVYhXdrh=&Kp8W2zWjYrhnX=&kTlc7SXrd_eoU=&eitC2fYWj_hmY=&r_jvUOVZkWqmY=&ufMJlqYk_lYWj=&zpoD8bUngacfe=&ORfjNwYWlZcna=&dvudQkVggbo_q=&XIKCf8VeUfVsr=&QTAHJ9VlWeand=&giT966VbacZYn=&aPajxEYpUZXgj=&gxLtwKYsfYWqn=&vyS7ODUncdZoe=&gBvnpkYrUoZij=&6fCHx9Undn_ma=&A4o4DbVqjeqpe=&OhwB6vXkmlrWU=&WkamhYXpWWoYm=&YuaSajWqbXlVk=&qSqQZhXeph_br=&oII9VZZYWsndY=&YlqoWWVjdnehl=&eINt9oWYdmamq=&b4yqWSXbcWglc=&vpwpSQWdlcaq_=&KCAUCyZeXjVps=&vftroYZlohima=&wC2CpZWkfYjki=&MV_fYDXpVdYXZ=&wQLBKUWWssomr=&FbfI28UXUierc=&Ck_3D3ZpUcsqg=&xfQ7rFYhlWqYd=&2KEsYgXpYciqY=&_8awBpUVppamd=&bSXh3QVWZVhZh=&2LtybhUbinahX=&Fw5K6AUVhnnjo=&Pn7e3EUdmnlfb=&eDB8YcZhflqkg=&xHBynRZWjbYlm=&N3KmP_ZcbmWWd=&qaR8sgZbjgcqW=&huxmBnXkinlrf=&pxPN3pYgcW___=&f_XR48X_pUicW=&8dGaEzViqksjY=&uDf9DdZbZjsrs=&u_Y3MdVoekibm=&ASwWueXrkgfs_=&SDIVC6VYfrXfh=&3hwtZBVqghiip=&bg6yQnYseZh_e=&KWIMHDUhifXlj=&ELDrsRZZYrYVd=&rtUePvUgUefXf=&8NGYvMWe_Vapm=&_ncBTfWXYgkUs=&wb3SXuXdsZefV=&ojHWxXZebeipY=&9Zg3OZUqm_qp_=&b6dhULWZfifmV=&QA_OvPYmWYd_e=<sEeSYVh_Yfc=&ZMvhPqXUo_rrm=&krBPbvVmUp_cY=&6NPfdUYcjkhgc=&WCCWEUVhlmYsW=&CEVQHeVkeejWV=&_7mH2iYrUpepc=&RXFEWHXYXhiog=&7XgeVXZhWobYX=&kBAVC5Yn_hdUg=&w_mfvaX_qlVVh=&g8jGWDXsV_pYb=&iY8ov2VWoiiYh=&yAt6aeUUbhqnk=&tbKpG5Xan_YWs=&BNxG49VWdaqah=&wkIzxHZilW_nX=&ZDR6QPVkkXdlq=&wxntWeVgke_Xs=&3diaouYeVZpYb=&QEhfqHYUUflgk=&xHqMxcYpnqgae=&rbRDfgVZYmpsX=&EBZOqeWUrskpd=&exIr8QWpsqeXY=&wj2oSFVebbljj=&aPLkF4ZbcaZgi=&7NTAkRZdeXk_V=&GIKqIdUrlhcYl=&6LppAkUoYghga=&nLOLWeVYoYXme=&jrea5MWUqafYW=&97KN5WZVVXrlU=&E3YhnhZabsYqa=&fc9CV7XVdfqXi=&_evD_JXfdbjWr=&3fGmOOZffnsYm=&jjyVKhXsseqqa=&cQPSnxZVmjZaU=&y7dvZZZX_WXW_=&2FUWrLYWZYUas=&P2u3WdUhkfi_k=&gX9tENXmfrZcY=&bN3sMaYWemeql=&clNMYBZmgVrlg=&gllRH7WkUmYZa=&3pwyPAWncliUV=&GAdQx8ZZZ_hec=&T8irskYsaYZri=&ncXrzDZilkmcW=&MKy8AHUpZWhWe=&ZutD2kXhaafrZ=&HhmJfZZUibcc_=&LKTFu2Uadqcpn=&RNxQ9nVmldqgi=&YH7kOKW_nVpjc=&mgdn4sVahnUXq=&5np65pVjklnoj=&WsSs_uYUZccsa=&gVi2HCXVqZUgf=&3ZvyM6UYVeWlU=&acwqbuZqkXfpW=&c2BZgFXmcUXcr=&LhWZaRYlXUccZ=&miWqymVrZVpfr=&HTynZAVrYmhcm=&X8MGubUfWbUW_=&LITtyhUWqbYoo=&OnK24RZpffbcU=&teMg2FVcirqki=&qRB3aYXilkZpj=&8cNqYdVoXgmbp=&kmeU3ZYjnscY_=&Oq5rcAWfZshkb=&E5tLT4VXfVXVr=&ATNiAAUpaemnh=&GdqtnfZk_Wbha=&6ELcG_Ug_rqUa=&WHulhuXqpUkce=&uSS9hnXqsZqbU=&joWhstZsmsfeo=&r4Ipt5ZWmklgZ=&WyetW5YUXjVcd=&R6d6e6XeeeXbX=&ahJ9UfVcXWrlg=&eXFT6CXksbpXr=&4nrdPgVYpWVhY=&Pt4egjWgpgrls=&x8rHlDVUlrVh_=&fMIQKeVghijmX=&yIkMTXYYW_Zge=&_J7ctVWmbmkZc=&Y4oiMgVWYkshq=&OwRRGAVYUXpqc=&FctkhrWoqlmki=&rc5aFhWfocWjo=&L9U378XYXZUeY=&EbwXphVlkcWX_=&yzjFKmVhVYfrZ=&lrkKyeYeiUdee=&PurkT7WVaWYXo=&MDbPTqZqoamYq=&jWhBXoUUUpngl=&5ppjQ8ZjiaWpW=&N8dMELZX_Yfio=&D9WfSNZcWlgYi=&fO2Ic5YYpojlm=&mOZr3TUncZnZq=&8_nRWoZhpUcbo=&9pVJRTZiZ_Vmr=&UCCU42Ullmmfi=&JDT5TFVncZqlq=&ZbDAJSYepjVZr=&wQL56YVnjcqVV=&765NVCXenellc=&vVZ_MoX_ffgno=&8KGPhpUdsd_YX=&wGHBcoWrdhcdp=&lcdUQlVZe_k_o=&WZylslZqrW_sY=&YlTAp5WWbWqps=&eQrG5EWkmlfld=&gQ8VnVZoiiWdl=&ESjP3oWaqgfsW=&PpvGWhYkmfmke=&iIsRmTW_WaWWr=&M2qvIdWWVdojh=&eLXhAlWlmrsjm=&ramzAOUsqnUlV=&hmpIjWUpdqfho=&nTdgDnVmnjorc=&PaqJiyZfkbrhm=&btliOtZqfsYmf=&vihPOeUqcrVii=&agcUfYWbXeqVb=&ghMzB5YUWggWW=&___rqlUofqdlU=&wauMt8XVj_pil=&n_kfHRYjccXgp=&CazX4RUqgkeYh=&mb2Ta3VYrXbU_=&h4BgFSWadgWUc=&4q3KjrUgkhWfU=&Gf2KlzYdgXl_o=&XzOThgZY_fgnm=&BvLciCZdrcZUU=&kiqX_wYnpmZkZ=&4lJvdAVWfVlff=&ln2h4MZskhVkV=&epPlAeZhscbef=&Lu3z2wZmpredc=&GrCk_QVdprsok=&o3FrdNYV_kbd_=&3EBtP_VbnoWmp=&KnVKroUWViVbp=&uLDBeDYesZVal=&Ml9ABaUdXdhfY=&fa5H7wZrcdm_s=&HV9ZwoZlXqirU=&gbmFyzUmeWrnU=&grlVgEYdZUref=&dggs88XmigUbi=&pGN4bDYsabXea=&h5uazQZqjcfma=&xQE5mNUhUhjgg=&opOeS_UgW_nfo=&IlWGm4UVahdqi=&qtQVUzUnraYYo=&SQlzDMZqmU_Yh=&7bUfqPYlebVkZ=&O33MXNYhhVjlm=&3ZuouvYqZgZls=&IFTWuzWofpmYm=&c5Sy5AZojWopa=&GLuoIgVmksojq=&MJR4kVXalrkhp=&uAEehIWefafkU=&BAavNCYrnkZWV=&AcllIOUdrpYoe=&i_9ssyWmXYlje=&zVg7ZqZrmWqjX=&9v4cGIXgWpekV=&ZW_PU_YpoiUdr=&CjaIeOWrocnpd=&Z_GT6UYcomcXh=&8mgfWOXcbqZ_e=&jcy6Y3YjhY_dq=&yiLQnIZdUlnol=&cOh_pVVhWXian=&yQEuYFYgsVrgU=&tIGdi_WarelUh=&3tWz52YWjlim_=&ZcvLUiZUWYihi=&XkX63xXaejfsk=&SeBxP3WkWcdWX=&2xVwvhWh_sVmo=&zH9Z7fXgahnWW=&JedbneWbUjglo=&a_zAO4XmfbmYa=&GS5gjfVdldigX=&m9v2iTVi_lZbU=&2H8XyTVproqiZ=&QkIOpwUncobei=&3dCqYgUqbalaW=&7JowKMWnrklql=&bAe8VeWslgXlf=&hh3_VBYceredh=&eK7UuIYpkpnUU=&fpZfydUfcUqcp=&r7oBLUYehjeUY=&zfsKqhYqijhY_=&gOxf4YZgZUrbm=&DsbPSzUgmieho=&9eTGOkYd_cjVp=&6c_AxhWnciifs=&I7V7ZqXaefkZY=&vaCljaZpebrY_=&R79oAmYXcilga=&DoDznrZqiliZj=&lrd9FAVgiVWmd=&PGHedGUrpZWlm=&j4hefCVqqhign=&WhqzqAXaombcl=&sHV5txU_jkjbU=&JAz8VGYelhapW=&A4_f4xVgicXYd=&eAoiioZlWhXlm=&I6mKm2YUkbYgk=&IdKQ6JWsWsgaa=&LH8CwWUkadpeo=&DP63S2XZhlqXo=&FtmimdYXUlUfb=&J4WxecWkipmar=&6QctvDY_hngmf=&J2B6R2Xaqhrmq=&NEfNMNUd_hocf=&nXVdhyYff_lVs=&d4yaQ7Ygileim=&wAzS3UYVjWsWm=&dkXzsNWrgVgno=&8lG4AIVZssmjd=&PEJC6hXnkisoj=&FTzHvtYsqX__U=&4SCAIwVjUmYsk=&JnWpQpXjehrpi=&swPZ4BXsVrXWl=&ccYfZfYrsbdZq=&JXj296Yjplhrd=&HZNVnJY_dhrks=&HY2NVdUr_hkZj=&Gc_nGBWq_qZm_=&_slb5tXnVkgZa=&ZNmqvDWaVXYdW=&HVa6TzUablmVb=&t8_Nm4ZjgUXrl=&I4IcJRVVVmeUn=&sEWqqnUgWYfZk=&KsfPrBZVsgdpX=&ylKUriWbrWiaV=&sIymUdVeeejWo=&MdgUEaXjj_XWa=&QdajbWXhejacb=&BkAumoWeWdkhq=&imcZmGVinllma=&RB_ZMDZegghVU=&ePyx2qXYaVXpq=&tEFgfRVjkUphn=&9kJLFRUkfbimp=&8huKkuW_nrash=&ewJvQ5ZaXhXfa=&uhF2BvUpkchXp=&aQtOVOVfilbds=&38IFaTZckViga=&GC7REKZXWmmig=&q_M2vjYZdphfl=&RpDMbuXsiofra=&XR5F9SUa_gglX=&BA5cHRZd_besl=&xQRaE4VbakZ_l=&se94fTXfgkjZW=&eAWE5rVqkdqhl=&gqMyToWigiZin=&g22rbqYaYWZaa=&U2xS6OXsrqhZW=&azOCQVUflUbos=&i9nYCIYklsaVi=&kgfsmSZloVncW=&enNNA5WaZoVUU=&cJbu3JZjpUUWb=&M5EYsNZnciUpf=&XZuT_ZVseeqpr=&SGACwDUhqqZ_U=&YgFT2qZgUmmfs=&_wvZ5dYkfjkiY=&KkoVCcUlfffVh=&N9mPG5Uda_fjg=&ykVXEPW_bfVcr=&w9itUnXWqXYYf=&SGvV7xUjbhZrb=&QZTQntXheocZW=&IHHROwWcUcgrp=&56KccJVpinqbj=&mr6ww_WXiYkgU=&GEZpiAZpiZbZe=&BIVGYMWqfYYUo=&d8XLvzWZUfdYo=&QKRt8MZYrbVim=&fU8L8pVacbfkd=&utocgwVokqhWk=&GkwP_IVad_gll=&7Z3jhOXpUlUrg=&kaL4jiWV_jnfY=&AAchcoUiccfjc=&eyylQiUlsdrjY=&kqL2gvVdoXWrg=&ooxdusWZjfbbc=&CuN_q2ZgdhXaX=&5kAuoDYcaghWX=&p9AFWXUbcglUc=&BsTZ_YYsborii=&_WuArXYbdcoYV=&GvRuseVXUgrbb=&5zuiXcWVWcjrq=&caY3bzUUhVUad=&Qbe7XtUoZXrgf=&YOgqyYXUqVUah=&WQFKg7UdnWaii=&QmYJj5YUlbrUg=&g8a5NpWoao_pX=&6vcWZJVZXYcpp=&7YgFxMW_gYgeh=&TLrzKoZ_dgXUc=&vCRCAEXUqWlcV=&tD2JJqVfiiVVY=&6jh36bZghoopZ=&3y7r5yUhbgXqp=&jUBjDwVg_sXdq=&FmentmVXphk_q=&rOcxIfWbnphsa=&fjhfx7YnUe_hi=&BVTwCZZUoiUdl=&G29TEbZhVVWk_=&Ceoyy8Wkooslr=&_swBleZghkjbZ=&By5OLeWchebcn=&nj3c7gVqdqnsc=&IYxQpxWdYYYlk=&4l9djjZj_rhsk=&CGiWeRWXZhlhd=&LpIf3KYbXfqqj=&mGG3ZRXp_r_bf=&LtCFTqVaWZhgo=&Rarx2sZ_UohsZ=&4Kuu_aU_ipUbq=&LoT632WaZsbcb=&GaPIHyXodoWen=&WtviHFVnb_ocq=&3h9YiPYYVihhi=&puCgQzVdlhWfe=&ZJ6kjLUYlofsU=&opZ9A7VlpVhei=&4L3USOZpiepas=&a58VdRZXhfdm_=&EcAVD_XmpmjhX=&_zZbAeUp_jnZs=&vxnJ5CYUcmYl_=&znZvqQWsjoUaW=&7emuvJZgsUcZj=&NvJcXmYcolrlq=&tOP869UY_Varl=&5TxooPW_Zhjgd=&aoKurEYX_VlWf=&J4P6yaYWhhgqZ=&c3IR3NZkrUXak=&XlJdXuXb_crkl=&O2STdAYrZheif=&PaBngOVh_YUUk=&7CaXI8ZnXjWoj=&eHD_TSZWrqase=&yXyycVVqhiicb=&ikcBpfYmhrfbk=&jWTnlUWrpncaa=&bicbO5UYpqXgZ=&VtqVZhZbmWojX=&PZdhkvVkYpqhV=&Jo6ADiUjpfYYZ=&__AzkBWcbUonh=&P9wWMNZbgnjcl=&8kB3KdVpjhZj_=&Vc9u7TUVjbXXY=&zxA35CVWdcUgj=&Srf5mQZmemebd=&WE6eLcXgkeiWe=&IOvRnVYkmlsmo=&D3TxmWZhoUsog=&zB5fCJVUenWfq=&KzmGxxYipmrjh=&2uXUk6WmUkshf=&22mw78ZsYWbXr=&Qs5Z8AVsgaqaq=&8cEA_mVanVdfd=&d5SbYEXiWgdnq=&uQP6cDWUqYdXW=&4DtDTHZddgbXq=&rKEGKkXXlcXoc=&fOKTDrUXfmlrj=&YGaOLbZoispsn=&fo3t76VlYijVU=&GKGuC3UUpmWWY=&d6H9DCVVrhsdc=&3vBnpDYkZWkij=&ffPK_vXhnaXri=&Nm5eddUsedlga=&c_OF5cUjmabgi=&wouUnhWmXhlgm=&Twz2baVWfXirp=&2AuDzfVgUVe_p=&GBltK6YZVndmj=&svoFV3VcUqjiY=&9LHGsFXsdmenl=&29yGi9W_gYYkk=&GklacEXknWbra=&ssADlEYpXkjrh=&cfVQhUWcebUha=&aoIzsoWsnnYVn=&SBqwKXUeqZnsZ=&CK8wrVZbmrXga=&CVLY9fVddUokb=&bQ7_6qViVZUVd=&Ls5kmeWhb_ahd=&AXqU65UYiddra=&nrerjkWqZdspm=&P_zGmgYUWXalX=&FcJsixVmqhqVb=&8Sm8zLYXcdf_k=&tgtfBuZjhXd_m=&gh2iLpUXUprce=&pGN9XrVofpn_j=&ZwJmOUZbhoYlb=&nTNjDlUfclWel=&HqOMCwYYbc_Xo=&hL_jUtYjYajqh=&gZoTggUWakX_e=&lw3hSMWWlfgnU=&hs42mHUreZsVs=&ZxGqN9YicZpim=&4wa8PyWgoUhoZ=&M9PSD_XeslXWi=&iD7oGAWlqdpYX=&GB3TklUdaab_c=&VGaIwIYjm_YZi=&FF5f5UZkafnpc=&zwhsdaZ_ilfij=&C4cn4CUWUshmj=&FY6cmyYXjWsZY=&f2TgcmWqksWao=&hUDu57Uqcrqqe=&tdWeDIXmj_fgh=&sKn96qYhZdYnf=&rohqT8WrfmZZf=&IlLlcgZmflYbc=&D9NqsGZinbpYr=&q2qCDXVejhUsl=&qQWEC8UmgVdZZ=&FA9VwWZsibdnn=&lJVthoUWhogpo=&HS8UP_XbfrXgV=&zL_ByDYnZUjpp=&gb3FLtVqZXrri=&8IKlFXWimYZfh=&TLnDtcUa_qpbg=&xNXS3_Zrpkrrj=&n8yO4VYaWcjsY=&RYD6Y_WqcWrXm=&FdWOpbUVYWWnX=&qTtMScYYikhss=&m6uVtuY_rlgpn=&_Wb_9WXilbj_i=&SwW_k5VUphbdi=&asemm6VWcZhfs=&vMn8SsWYqYfrq=&ps9u2hUbUiijq=&m5mbRxWqqdoZU=&gflBAaYqsibrm=&JQpxaHWVmbpaU=&aHVQnbWeldjco=&bKtEpbVjXZdXp=&2jU2nGVslhec_=&7j5b2WXroUbsp=&dUCT53WrkhUhe=&B6nEFyV_YggpX=&KeV78bVYakffl=&WVDdWsZk_hiY_=&CZkAprVhjVqsi=&AHt9DKWZfprck=&hRZx8jZlbqXkh=&OAhErlUesYmiU=&JvWJiWYs_gb_f=&VyTaiSUonXlUa=&uPuonmWfcrqrm=&5moIuCYrpdaY_=&h3Yl4uUVUnco_=&bvRyfPVckfqnd=&No_4X3VdVYUip=&FJrCpcUhgVX_k=&GHWL5VXsWhlUf=&klfKmTXppogWn=&kge_4jWgli_k_=&foxIn4Zpqmiad=&WLHnmjWehYlej=&ugQvWUUldYshp=&dv2Q5MXrrdgks=&xSkgrYY_Vpfpb=&uMEGcyVU_XVfr=&Il5XtoWlVenrc=&ZtAGrwXXbUedq=&HaYFw7ZXWYrjX=&AzLJomVaajsXh=&dntrwUXbmpi_c=&ZMLEY9YidZggl=&FGzMv3UYYrWsd=&A_shkRZYdhlXc=&w2fDAqXjikXji=&qDwdLTXnVkeck=&_KejxvXqgfdif=&LvZmmyYa_eWWq=&aJE4mGWkXcZsd=&N26KwMWgYchlg=&9YKjK8ZdeqpkW=&52OVuBVsjeUkY=&vRWNmhUajfspm=&pa9wIkUpZUknd=&P6noOVZe_gWlp=&Z2SlbdYUUessY=&2wX6xrZpoofsZ=&jCzSEEYhfirdp=&sKws3vUa__ejb=&McbLEXYfbmflk=&wl6JcRUdXVVcl=&7DCWN7Uacpce_=&xozFASXVmrpmo=&BLmiPeUmopiaf=&r9E4NGZlXVsfl=&BjNAjUY_kiecb=&kHBf99ZdYjZie=&vJQxJJUpXgbVs=&rkMgNoZdWr_Zn=&MCnFBWXoXbchc=&RVIvIXXsWlogb=&5ulHP8Vngdqpr=&WiDzHqZaelepd=&rC5QWVVWUi_YU=&HlfMoKUUUdUWr=&fwa7ZEVViUpoW=&R25BPNZgpiYcU=&tFwDjdWqUjsUd=&97kXCoZUoeWep=&FWxzqqWbskeZe=&XXLwu9WlVaUk_=&qvbyWSWaWoXie=&q4PCENYdcpedp=&LsleDEYpfljYg=&z67FHUWnhdjql=&54oIMxVqqWqWe=&b2pJ6TYdUaW_a=&h63_rqZdjlmVh=&pDY_YRVWXYYZp=&dr7KiqYsoqsiV=&zBbZt9UVXpjq_=&RkDe84XlVbYlc=&qYSAWjUrZekVV=&yrEayxVWfbheh=&ul6S3GXWrWieb=&dRYQjIUjogonk=&ixO_GvXqqmgmc=&lUlD9FWisj_fX=&9rXKJ6Xoeisqk=&rh9PQGVbiUZVq=&cNctVtZajXrUl=&SSPrE8YrrmcXX=&SKT8wvUncYsYj=&uddaZPWfUVkef=&56YRLYXalVmho=&nYMvoVZasghpX=&czsxJ2Vrgob__=&8dnuEOUYUdsUl=&xdEzzTXh_sfZm=&ZSa769UrpjWYe=&dwCu2dYhWlbYl=&9B5IIQUhYZVeb=&CcgrLZZqjriaj=&yRmUUFWchspl_=&gbM6oxXXrieZs=&IPvOcjZYsmofq=&PE6xyXWgejUXh=&FZAfdsVUZWsal=&8zsP4AVakXlhZ=&uOUdX5UiVbVcm=&gBqCZVZqg_WWr=&IwSi_DZjemsYa=&W3vFpkWiZUhsY=&oKHhRgXlXgclW=&MID9WfUrhUgda=&d2hUMxVagVUbg=&YqOuAMZW_XUch=&FKm7pqXlmpiVn=&CFb6uiWVrgrls=&WJZaDSWppcW_W=&LKGeaFWfgefVY=&7AJfpRUjWjnc_=&lXSDuzZfqmcWX=&ylb9NGWaZojpb=&D2emyBVnbV_dj=&8MdW34WhagsqX=&Z9gc6mVrfZWkp=&J5w2P2Xjokkej=&wm4ENOVolZqg_=&aClbzpUXslbdf=&uYFfWwWYsg_la=&rZs3iEWlakqdp=&bGMGQAWoVnUim=&ZkG4mZZpimaqo=&DpTCm5Xafaaff=&NsyV5pUimrfcm=&cmKA2sZZXXXlo=&4KDez3YZskipk=&nZA9VlYUejgbp=&z5bJXYY_jrcpY=&YrVtcMZodcpgf=&B8GHpnZiriVWV=&JT23eCYgffmmq=&dyMEQBXdfZYgf=&MfcMgOV_ffsid=&IAEq54UgpkaV_=&grxXwKVhlhbjo=&saHiQnUngVVaY=&bYrwiwYafcnpk=&lh_tBTYWqVrjX=&Y5GLmCUsdc_Wf=&yZZxUiXdViVmc=&Y5RRb5UhmYYfU=&mnUJQhXsmp_ag=&_VSnQHVonmdh_=&dlLTX2XsWrZaa=&akWF34ZqmXVqq=&yswAjqZjendoi=&AaL8kqYah_eci=&jSmcCtYYabYgY=&M8P3M_UasghYk=&IEPelRYsjnciU=&_WHSw7VsYokgl=&LL89wKWYYhVnX=&nIrtpaYgUcWmZ=&X8WRLbWiVfcZd=&dLEovvUgXsZhg=&BOotD9VWUYemn=&NcebQMXmscrmh=&f2LrflWWakasn=&oyisQQVUZfZji=&KFbImSVragfom=&jhS5fJUWWa_oZ=&ua23btVjkYbWp=&ut5mdZUaZfoXh=&byZPIbZjirjcr=&BuS3xhZnXpYiY=&yvDZcXUbkfhik=&BiMOUBUXackdn=&3KnNGNY_rijnZ=&Kc4CLPViXjcdk=&ElpDJVWfraWmU=&JabzACXgXsiUa=&z9FYmtXVgobsj=&8rXVeTWVYYqZi=&rxWLN2WYhfhiZ=&ThIpFeWqgpVcd=&BPN72OUbeVmon=&Z76U7BZllsYqr=&AkQUUWVfYhjrq=&5U49PXVYkgfbb=&hIfGdfVnlamUs=&lWeq83YaooWXU=&UHFaU9YYqalcs=&eyEqF4Wccockh=&j55DuYYaWmseh=&krI9TtUmcb_qZ=&TYeUqtWhdbYpX=&ebk4JTYpWa_co=&9nvfwKUfsqmXm=&uGUxnSVnXcsrV=&ruvrysYicbVmY=&SEKXHqVbmaZpX=&PnXtppXsWpqVm=&7pNP52Wihrjjn=&ogV_TgVVrr_ds=&sGrz2zVpVUpls=&mquCzpXqibcXi=&SuOuPKXXagWco=&Bdh4XYUmeglpg=&UswyeVZclqcrh=&oNzC_vVbYinah=&qaxq57Yqfq_fo=&qKap9qZgjZheU=&HxTXFiUpia_lq=&pI_v4uYZUgYdi=&4yAW7oZVploUk=&i7MbQeZjUmUim=&Zp6lA2ZrmYcWo=&JZRUGyZjfeljl=&efAsjDUlbfVUa=&EvcTb3YUZYZ_m=&j_5E7fVfgihrj=&NscKPmUVgiVXi=&JYQhmkVgfkUih=&JiS655XghrhmZ=&zTYk2hXVpWj_V=&pkpQZfVhapoeY=&bDhdUaYnoUofV=&vopwgjZonqVlk=&leT2oyZsigihq=&MM9nN8Xllhhqr=&SrnJPEZieWrqj=&RtnrTRV_slWlU=&Oi9BcYWcVgVqk=&QKcBNRUgVplof=&fcylhEZjdldrm=&ASR34PYYkbYho=&DbbVAnUsmUqiW=&O7XsMtUVWii_m=&E3CscxVbUcZmZ=&pavpaCXcUmiVW=&ApXEgvVlchWmV=&DzC_fcYiUgVod=&KIfietX_qrdVd=&vnB2g9Xda_VYa=&AmBIuAYUconl_=&YD2cyLWUdpase=&lYzdSUWrbYqsg=&xrMIz_YjcleZd=&o9X82YUYWmljc=&ptlo6LZhmX_sd=&5ZhrnxUbmaYpk=&qF6bdFVWZ_hWr=&W_nuPCXoUXmgp=&eyWKARYrjigrV=&PhAYg5VbbZmgV=&4JOEKlZbr_lhX=&YWEslfWbqXngk=&e35zhxZVsjZ_U=&SKtrevXWehWjV=&S5t8GkW_bon_j=&l5B8WFUWmgXnZ=&SqSH_9YnXaYkW=&NgbZa6Uejbjpn=&6vGTJPZqXijoZ=&OnvJfGXqhbYdl=&xIRRV6ZlqpVfl=&5Y3zo8XaibWib=&7GMlmkUabjgnb=&5dD2yCYeeWmqc=&MTzJf6UYXVVlY=&CRgxwPZhfYZlf=&WirlpCZqZhjrf=&WdkOMFZibXcdj=&GQXQfmW_lWhra=&QVkWHnVUhnkal=&aE3QtsWplplkW=&dZDzjxYcejZoX=&Rcr7ajWafYmlU=&eVLbi9WbiXfsX=&k8ERPcWokmbba=&cFOuIVXfnoqlZ=&sctzlYUpYlYUg=&ui_rmRVZsZijr=&OFIqaPZpXUsai=&LpE4jzUYUcphg=&ZqGKxjZqsZshZ=&coXJ6vVfgYodo=&meUt3IYjlndsi=&S2xaFuXXgiWlh=&sKXFSAYrrhWrX=&aKJ7XZVUpcXUb=&EFAnZKUhaplp_=&WQKjxPXUnYkhp=&Xmb8dHUWed_gr=&2ZpHSKVUdjcsg=&euNmvgXciZiWd=&shS3vaYeiVqik=&PZHCjBXUrqgdp=&Rm5vgaXfZfmnk=&eTAV7OWYiifXj=&4pBJVyUhZggXr=&OvmMNqXoqldYk=&hbN6PfVpjhssj=&nRAiZ_VWmej_Y=&qdxrNqYhlZhji=&nsAI3cXfWgico=&qvA_zHX_epXrW=&fJE9h3ZeaWrlX=&MTJt45ZrhlXqa=&6w69UBZfqmmY_=&WamqgeUWYjXlm=&wZug3bXWZcYdq=&JnKcysXjgmeVY=&gZGFVhUaUqgji=&CdEdRoVgpWpnm=&TVPJUCWYgjWse=&E7xyPrZYZages=&paYeJuUe_Zkln=&SSYXSEZpn_f_k=&KAbgZTWegprUi=&ZDkHnYUrUWsme=&qwHcezXXninkh=&c3qCMVYdggXjb=&aox7b4UUhkkUf=&AO5lBYX_qccjV=&vI6PYjVsloUil=&jB24s7W_hZggr=&xJEsqWZnnYqgU=&wBVifZZkqZceh=&Jo6HqhXqbUVlj=&ftCn5_ZfmXhZf=&pjky9yWcWdbmf=&QqToR5ZoperXh=&CmMRO_Xr__dVe=&UxoLbvVgZsrlr=&o6cLyMVochpnZ=&agWVoMZkbXdkk=&qj2jCUYYiXnrp=&ReFbGqVUsoWYp=&3Ok2n5XpUbmqm=&ASu2H_Xmorrms=&cDgQhgViWeVgV=&3IbZpDXpUbmYm=&iOuMOmUinWVsp=&syGbOUYqUooUY=&dG4vJ5VhjlUqZ=&gIP63eUeqc_aX=&XuauBuWnXnjXY=&iUjA48YgiiaWe=&c7KWvAWq_ggZZ=&WgqpMVWrVbklZ=&Bgx4mTXWXUjUi=&iaveqpZnmgfks=&Iwb8oFUhobfsh=&kG82_QYYXkabV=&Dh3u3iYbchlrj=&X2yMwHVmbmVpU=&YoI8VqZUfUsVg=&iv2CdoWbcmXdd=&eZwf2WZsnUihb=&stALOYUXeorcn=&n8K4N4ZhhlfZY=&eMOU62Xqsnd_s=&2AqT7PZaeYapo=&96PDnaXWXr_g_=&IddUHuVocVp_n=&rMXPjLWlhrnZZ=&PGGhKqVkZjkeW=&LwTvnVVrdnXqn=&ap_N8KWjpWgki=&GEYtiwU_djoac=&9CpWXmVnUhgmq=&Q67AQGYrcXas_=&aSUQoHXhWdapm=&Csbh3JUmphXlk=&JNibNDVUXfZZZ=&a_5bSTZbeZaac=&LkqVi5XcrhkXX=&yqlg8DWomfljh=&EYTXTcZshmaa_=&94eDrMV_pdppl=&WaQsozZscklpV=&MpmbL7Wahkfnr=&qJQHv_XWkniiU=&8wJ5FbZjdsZgl=&Dy3c9_Umjhsiq=&M9UdFaXVrsrXU=&7_mZEuZU_VlUZ=&jnkQDAWarlYjV=&EjntsEZ_kqjld=&iQQ8XKXWsmhiV=&M6h4S7YmdbmUm=&usolRKYWfZiXo=&QswUV2WcVZccf=&8EPTKnYWbiflY=&FE3IJhZjdohXX=&mkdY6SZUdXWac=&g5_I3uVlscYWX=&VfRUl9UodjihY=&imYnkJYqjWhap=&yx5pxdXefaWiZ=&8XioUIUq_kWkp=&nEhenSZUalmmY=&qci5XVUapVYWf=&KRIG7_Y_drg_s=&hK98r_Wgdk_VW=&d8E6OlXiq_fpe=&ZWOmSnXcdjohZ=&6CUns6WqkanUZ=&ohPrvUUmYjq_k=&BayujcYYhkWoi=&YB9opeUXaUhda=&fWYjV7UmdgmoZ=&wOqmZDZfmfpXe=&HOJHKtUjZpeVd=&KbkXBFZlpWdpg=&iBvlZTZdsoljg=&WHa5tHZsledWX=&cU3qG5YeqVpib=&XxfY2VUkWofqj=&daV3fpWjlmWhc=&SSMNKqWdqshnV=&Pa2ymwWXlngZr=&6UkNkqWacnUgi=&Qh5xGMWjesXUX=&q4fR99VamjaZj=&BCxPM3YcZmn_g=&AsCSOdVgkiadc=&WZ_45wZrhjsmh=&qvAExRWqZhiso=&R42Kb7UmeeVmY=&qNDLPEXsXecUn=&YEsa2JWVbVknb=&9fqVAIXUcnn_m=&nRdCVEYnflfmn=&qUwYVyYjWraZh=&oAA7lHWVjqVjX=&qBOC8tZnVencs=&XZlXyAYbWmocc=&Is7d4bUaiZckd=&TPiz7qYmbVmkg=&bQS2iyZooalUh=&N3YQMSVdpnn_Z=&88H8IHZkeVlqp=&zppCp6YihdeYi=&HXkPd9Wbmomim=&paQf87VphqkcZ=&7NjtQAXVjjlro=&eNL7ptXm_XrhV=&Jr_IItZpbpnXe=&j5Z2gEXnZkUcp=&33w4PeXYjrXYV=&onnSDbXog_VaV=&yFZcHqXXeeXlm=&IdFdAMXpcqafj=&eaJHOEVhcWnce=&LJPSl7VVldasp=&77Q2GcYVlbrYq=&JnjxqEYnXc_XY=&ZPfHR_WebaZ_q=&hsAwtlZchUYZj=&6ife78Z__Xjqr=&PG76CXUkfmced=&HjYKfGVlnVdqZ=&mbUOkkZdokcgs=&vNmhIdZZoZfjW=&iXSvz3UkdedXp=&wEGouHXbidVWi=&BuDaS3YimigWf=&w_dhEIUieZo_c=&ilRTyXUjUrhem=&Pio2weYldkpq_=&tjAYnHYdkYWVZ=&8oZs8SZecpYgk=&HTlNriVlsnjpV=&SUTyPiXaprbcf=&wX6Y5FY_pmUgd=&CT7CUSZZfneld=&nSOvE_XqdlrfU=&qIELHPWjpWhdW=&Kukq54WplpVYi=&ct93SNWnsqokq=&xYPaPfWjoginr=&ddmwm_ZVsgfYY=&GBxPxyYlgkZZe=&oS7AHkXpmeoYe=&8WVqCyVd_YqXY=&UBmiB2WlXkXil=&ka25owYqUXfcs=&rMfdcRYibrmrg=&GxyfX9VaaZ_WU=&HQMbILYb__lph=&OGDfvvUUrfgkl=&_jA6ulVXrprhg=&PAHtwKWXmXYnl=&ShrOxtZdZlUgV=&f7S53KVilshVm=&pDl8D2WfsU_lf=&OHatHMYs_ecem=&daywBiYofokrb=&Lj8NHOUcjiWZe=&IzhjhwYpjiYng=&nyVA9qXri_Yml=&EkETjYWjWXrVV=&sRISXWVdmapoc=&iSWNqNVrUjsqg=&ysqhiTXoijodc=&AwiibbYcgekiV=&yYNUjEWmWeY_f=&FDhs2MZgoaojX=&kg4wL3WjUhVqa=&dsX_QJWZbhYha=&ErF7m6Y_rncrr=&YTv59fXojihra=&owYVw3Vsmahei=&DDOoDyZ_Vlcel=&9YJKteVbXadZW=&t6XHWdVbkr_r_=&URjt2QYr_pUVk=&OmwlyHVrkjhYh=&ZYzqd_U_hlms_=&PLpUbIVqoggUc=&AThINOVosZdWb=&pxtqjrYgWUmfl=&sEwCA8Zacdkdp=&gPN5C5Zrgsrbp=&kDkTefYWZhZXg=&rQMUY3ZZYohgp=&AigxiXZmjbfdk=&oxgvsEXcamVns=&k4ZRmpWWUiqUV=&vokUH7ZpVfhWa=&xgxAd7Y_jX_qk=&xJKMcHUnmjedh=&_7mknTVpqZfqd=&2IggB9WefoZrW=&PR3tBxWmgqfr_=&oRajrGWkrhkVp=&9Z6ovsXahnji_=&uW7iBWWd_qiXq=&S4lE4OUhUapsq=&bwIypCYmqocUV=&OUR3h6ZlZrppY=&4qiJFCWpVmbdg=&rZ6md_ZWWqfjo=&vATA6aWYVrWei=&9Uzu3TYibVmen=&6ULDvGXgYaag_=&6AxSHfWascgqb=&O5vVlhVUW_hUp=&Mti8_bVgafkXV=&f_vuKkYUcgckZ=&qjeeY6Xpgdn_V=&dhZUGbZopYops=&UnMp3jUjXpspW=&V2ScdAZkojhsZ=&axT_NGVn_qVmV=&x5bZFpWnnphak=&M8YAzGZi_ZkVo=&3PCVP_UWXYXhl=&uvc7eSZXhaYpk=&Fa8dmTWcVsagW=&RGblL4ZehWqhr=&coDObqXefkeUb=&NmwtsHZjibWda=&aTbBw8Vg_anWj=&2fiDfGVkdZegW=&RUU8TCZklfYmn=&KXGCQwY_qoeoW=&PabFhBWobroVX=&nwLHrXUjppUlq=&LXk_JJXUlgqop=&szQj_AVo_UYse=&edDWljWrpWXbV=&fbjQEFWkXZqdg=&QCGxItVVbVhfZ=&m5SiHvXYlZcfX=&edvw3VUggpslq=&KuajxRZadfYYp=&tHI3vJUfddfaX=&zfRdvZUisar_k=&FSrZTsXWdoUjm=&2ftxjlYpYcmbj=&TUznaGZbVifcm=&cDiMWOWmnrkoU=&VRYOfOYkskmas=&X7kpIuVileg_n=&ctDgvCXjXjibX=&QxnpfjYVbboUj=&nnus_JZqbraen=&RWOe6sWlipfck=&Ou25bWYqVcblg=&Io_BpDXqYhUcm=&LCcFiFWXXjXZf=&vbUDNcVapkb_m=&vIGNoZUpeeenc=&Y5vdJHVUYZhVp=&fE_WmdXjifaWm=&cy6x3jWccmkeY=&VSq9vYXZsrqgY=&RsL_ZVUfgrbmq=&pvW9XlUnkVcja=&bcaBJ2UXmdaro=&BsPbjZYfnebXg=&rE5tAeWUcjVdc=&TpB8KIVhmh_og=&uGgKKpVjah_Xi=&s4T336UnlUojZ=&E7ytBIYnapWlg=&bRnXReXZWUqbX=&nknurXXnhYerX=&bQQdLZUZkiios=&hYSdnzVmZXcnh=&uXelkhZqjVVUc=&ReGUbUXjZiYi_=&ibVfiDVfUqXcU=&eGq8OdZbfWshf=&8W3nN7Yen_kds=&KO6yPvWcrrieo=&U9YZF9XVUiYjU=&afTdmCXrYmd_n=&APbUDvWclhooV=&QnfDZDUjqYsjs=&eTmk3IWkoWrho=&Wx9DpZXipfbeZ=&xejVHlXklsqhh=&U8Tf_YXYchZmb=&ZorPPlYZZXpYq=&P96uBWYrWYlek=&rOaKw5YXjhcrk=&5hR3Z4XjWsbYm=&lv8mg4Vieic_Y=&r4nhHoZaZYqoa=&2UGZthUkcsllj=&8rvoSYWcpUXiU=&kbAwSzV_kdWha=&ZLF2WfWcmZbca=&H5NzUWYYsmqec=&ayWlclUWosgWf=&cUbGsjX_mlspk=&CbTFReVkVU_Uh=&UVQ8rAUgaljUY=&a6hOnpXsj_abi=&iTtsPBZjkmZdr=&o6UB8AWnejqXZ=&WWeaVvZke_nre=&i955DeWh_knga=&rejOviWsfsfgo=&TfFuN3VbUZYog=&RCZjW_UUqmWck=&xJPqKzWe_Zbbe=&_ejEmRVsWZYel=&hkGpZTVkklWih=&kQFsTqXkhmUdq=&RHLpQOVZWiZbp=&A9oHfLVqkenld=&vL9Lo_Uf_cUqd=&_xNDFaWmchsdp=&ZHb8DrXibldps=&_7wBl4YWggl_V=&kpGjnxYgVebnU=&KaSlg7XiVsXXg=&yG2dG6WYgdkb_=&4L32GzZairjhr=&QmBB7SZoWVVo_=>RommZncXeZb=&XfYAJeZhjWZkW=&LFVJVLXZhfWX_=&_X2tzTZjjsokd=&JaSUWoZjb_Wef=&pytUG5XZqVler=&IIj8sOY_UW_mZ=&U4iHhzWnVVqYi=&H8sETuZrhjdeX=&cPrZN7WfcakXr=&LsHcmXVrZqXik=&55gYjLXqq_jnY=&3GXBLWXcmWjZh=&Fpa5dCUnfYVcp=&GN7K_pVggmmYi=&j98DEJYd_scaW=&U2j4RjVnimcse=&nEPVo2ZbUabmY=&fUFHY9ZibdYmp=&9bIiAPUZeVspe=&mn9djQZgWkogf=&stAXzRWc_eWej=&8LHOYVX_VidrZ=&CoaxbwUfnahkY=&4bpDiVXcjhlpV=&ETlfMtZqoVVpb=&8SyIiBWimZbZU=&XSgLRYVgncinl=&3T9qrHWnsdpij=&UntlP4VpieUiY=&XltTHaYdjodre=&HXfSxZWmdXXVa=&iI8G3NVeoXkhY=&jdQEb2UakYlms=&SPdzUBWeojXoZ=&z_QowKYfbV_ob=&n59ImpVocnYrq=&LFcl_OVW_fkbl=&OuLWOoXbqapqf=&PfunVrUmsUnn_=&q36UM9XoUjeZh=&HvGMPyYqk_bjk=&Q7WX33YciW_Uo=&urD5TTWjblorh=&TaeaFmWpdelZr=&et67gEXcsUnnU=&bEkX5FUmiYY_i=&lfbtHaVsifci_=&Fml8U4XlYiU_Z=&5tdn9mWsVVUjh=&4Xk7PvXsq_akc=&PoV3maXpgbeph=&kPiK2gVlffnWU=&ShWTN2UoUYnkk=&MdHk5SXh_Zkrd=&kbylIFUcdcbVb=&ElziB4YVracdo=&RcwLKhUdcVXX_=&Kv5iNmUUXmhmr=&mIQTntZXbUqcb=&k2qTJxVWpihcg=&IVhYUUUfaifVa=&B8x4mjZaqcdhf=&eNasaYYhfkchf=&YOWgTKWnipZql=&bpCdJEYd_ijkZ=&YcOqPlUWrlblh=&89jvkWWXdlYUX=&byLyHUZWgfpaX=&aHHSo5WYU_bgc=&heNXZaUcWsUgd=&Agx5p9YUdcjkb=&pN7WnlWsbbhYc=&EsIIzyZrmsVcr=&LySDroUoa_inr=&9rkFt4UUfkdhW=&fbblCaXYjanbj=&pGztj_Xlfimfp=&tFQb6PVcsZnVs=&7E2aYlWeYkihi=&UeBG8wXj_ehZX=&xA9Pf7VUbaUXl=&Z4JJbFWsns_Uo=&3T36H8UrY_qii=&iXbAEkYjsdkfk=&DGFKOxXVoohqr=&lTvhI9WValYqf=&ttVIySYXfhZUc=&EsF72cXmWipij=&SoAlRjXrcWspd=&TAa_KxWXWkmsm=&qf26kIVcZadUV=&hTdD7DYdrYiUq=&7ypz2qWqXUlfV=&bRxpuYWgXlsUl=&VxFAmqVqgWZbn=&YbHzREZnUdplg=&Jx_Op8ZZcUejW=&VexeHwWfaYefm=&7qnJnrXYnhlkn=&239jAQYbfbime=&p8vMyjWsnicom=&X_nzRbVjqpWha=&LoMzT8UhdWVmk=&WxZhJkVfdXcdo=&r3FKvVWnkdoXY=&wzVw3uXdlifkn=&RMQqvNUsiphoY=&iOnym3Vodmebp=&nVfjsXYmojYop=&pl3qGtWlmpfre=&2MyI8MVYjhdXo=&8T2ei4XlmXlbi=&YT8biYVpmndrX=&BwkkqjYmUjWga=&5r8ygbWocfYbW=&qokBVmYl_fXpX=&pH32vfZrkdi_h=&McHSIjXjipghV=&HkOvjiUUobVdd=&7UGfLmZjmXrab=&eU3565UocksYs=&5mrW4JXeWYoVc=&s_oZH6XoiU_jm=&SHBLYFWadVl_U=&IxUnY9UkhhVqs=&ac2qCJXinlhdm=&f3zoAAVonsqqZ=&3YwnVQXpfVplV=&ehffMNXcrrslb=&bUWfpRYbalicl=&rSJSZcWqhqYsj=&3M85P7ZqdlnYb=&V47g3hUkY_nbm=&BBEKDwUUhmjVd=&eDaqSLWiblrmY=&kNdFhLXmh_nVW=&2kSTDoZmZpkpm=&A29pFLVnpqr_n=&mOxKvIWpbXnjm=&Ub8hb6VX_jdYm=&iKxYKAZsYarVX=&QUWBCJWUcZVXg=&pFlKqkUkegig_=&z3HuRBYY_ZiVX=&qtH7cmZgafinm=&8uW4CxWYVmgmh=&nH55CvZaX_lXa=&ASAsJQWerc_fk=&3xsTrWVkgirkU=&Ey9bqWWcfVler=&93zblMYfcfpeb=&lPXyIkW_VYmdc=&gDSIuaXmoUXso=&SkOmMnUeocqrV=&KGfLLcXpeodeV=&CsHcncXgfcVqa=&SGJMP4WXabsrV=&rjdFJBYYVli_X=&WeCN55ZgdWhjU=&idX4vbZ_srlnc=&aKlGbXUqbilco=&chPLlbUfosoUl=&saIMNvXopXjhq=&yob472UWjVYeW=&N8VAzKVkn_glk=&8DhI3_VqiUale=&FGvLNHYhWpqac=&JYEcEiZXqkXal=&khkAwSUoZoaUl=&h7h2ATVmefpsa=&nnuYBOXpVfeYg=&GmMbmTYaaiomj=&fLX5GPZmWWV_b=&SkxGbPWgldpho=&UIYpNLXqaifsq=&qfwlSIWhWjirg=&8CaoRUViZgbrf=&z4psX3UaYa_dk=&phyDPSUclfsmb=&WBFacRYcecsei=&V6TQMHUjWparq=&m3cTkjZVeglln=&L5K5H4WZonbmf=&ic8lpiYfmUUkl=&wGWmHIYaflVmf=&MQtwBhVXWkglb=&FCQoTMX_josho=&eULIiKUarpnej=&8U3LKLXZpqrsU=&nhzy9iUrnpZai=&zM5adkZfYrVap=&qEiqHRXUaYWhf=&xknXKAU_Xkqrk=&EGupboXanspeg=&y5AAyLXlWUoiU=&MUBT9PWgiV_Xa=&qro4x5YhfUXkn=&9SzkP9Xdndd_k=&C3uuVfUUXgg_a=&Ad4JdaUkbaXiV=&c3TUYIYfqjslZ=&ppuyUCUsqYbsc=&Py66ePXmgaeqi=&Z6AulNXdb_Xkh=&4I2MrRVjlned_=&G2s2X_UagYUfZ=&JXcLacXqUVepX=&ysL4JvUcaXsic=&z6IaupVglomo_=&DSWoQeWnbmfYj=&7NOqtEVceiVrq=&VfOsqiYcYklaW=&yCLcYGU_rrrYZ=&PlHhPDUXlnhho=&4GNX2qZaifWmp=&3rqc5eUZ_c_ej=&hfqMPbWodqWsg=&6xwh47ZVijrXs=&9rvxIXUqdeUdp=&h2PnKCVgid_X_=&C9cKYpWlpglWf=&o4L9sNUXVYhgl=&Mo5ngXWsne_sm=&p26j29VkVXgkr=&r8PQcJXjsbapX=&ZG4BrLXlabood=&2aBWPBYUcobXn=&rAdQ4JUajdVYU=&8Bz6bWZekUnc_=&JAr6TQWqVcnep=&Kpj_L9Zgf_fUV=&oN9nh6XshbWWq=&u2uPJTYpZZioY=&R9JH_jYiUfben=&K8XzIVWdYkfYh=&geGUkwUqUWZnd=&LWBDlaVZZjngi=&HQaWfKVpcaqdi=&zVrvatWYlYn_m=&Fsc3p6Zfgjrqk=&oJnDqOYWUfg_p=&JTNUMHUbmcbah=&P22XtzZZcUspW=&64TIU3Wgdonnf=&NaVeVHYWZgsci=&QCQDVAZksVk_r=&KQ_ZZ7YiYZska=&MVaQi3VdYqqcU=&LGwJBkWXldXZl=&SaWYKgYWfifUV=&nIlu4vXbhrVge=&37rJ4IUXiWakf=&gmULvQWYXVW_Z=&k6YRhLWZnphVU=&EwJDb2Yplrgbn=&WgGnkMZqVbgWf=&xf724kXgqclXg=&_HJ3CIZVgicdq=&kqbPJeWnejVds=&8UNelfWXdkrWU=&BBLHdAZjZgqlk=&upO_2bUkiiZVg=&3rHaUqVpYXokc=&CJHYkHVUmcVYg=&K6AvI5ZgqZsbk=&SAWRG4WadbXjj=&KnK2PRXeVmcjq=&Kt39GYZmjZerk=&rYu6CPZalipeh=&8RiVHDXmenfZo=&oGbs3uWi_fmZk=&XP8PG5YcVVaWX=&Wgs7oMXoafroe=&Hgvg2aWXcZqoo=&sbOY6CWVdXUom=&WFenlFYrkqYfX=&_EmIRdUjWeglV=&6AZnlzVVjfa_a=&nOY8BwV_amWlY=&_wn9sbYrdVjlY=&5iiBCNXqf_Ycn=&2r_ZwtXbqagch=&TrJxutXmVbpXn=&ZkEZ39Z___orn=&UtxgRVXaX_ecZ=&3TQfilXe_mdis=&AIK98uUoWjXjl=&NbQFoYYcdiapk=&j3sQevYoZeYrl=&PECw_DUdhXXjY=&YtLsizZkmWYZi=&kkHsRjXslhXYU=&TbN_LKUoVhdbb=&HTVQjJWcmgnib=&SpquVGZhrWkpd=&skuAkrZkoqcdY=&XDdAaVWjYipcn=&ZmsvalVXoZnnh=&DkSZmpWiV_sfY=&ZeDJG7VlUmbcj=&DFWQANUsWqi_q=&fKVmd7Vbigrcd=&5rXW6AUqoomWg=&5JvTzxUeXrlhq=&MIlPWAYnpUoap=&OZ3C5PXnWVZoZ=&k_7MQYXqmdhpd=&U3UXtHVeVVmiZ=&w84EDjXrVXamZ=&jeP9xGXshpnmo=&cTrfrWZbeqspU=&id6mvHUZrdilX=&sIJzwLVbZhWYq=&BfkOTMXmUdUgq=&CQ4iKYUUYnmWj=&L6tygSZgXnqkr=&56FpDgUaWpas_=&TS6hIKXepkUss=&QhF7t2Wo_flfY=&XNljBYVVVepgk=&YlR39SXVrpnmc=&QmD7kwXr_mnXg=&g3GJQ7VVYsfdg=&hDKTXZXXsWXiV=&kTZJT2XfdajhZ=&6EzspdVfmofjl=&EAEngYXgcsidk=&QGplefZhlYfXZ=&AagzpEZknhrfa=&RiG7OYXYaqoZg=&kWWcg6YaZhdZm=&6PkfvhYrqcjVX=&ljf3JVVb_ennc=&BFKOl9Wl_qnck=&lYlcErZWW_YbY=&fAOR9rVqhejsr=&32iazfUkmroZc=&WwfP8zWsYXWhr=&m8JM8DU_fofcd=&9ZAIwvXkjkala=&wpor3aVmmsann=&PUfVlNUnclnkp=&msLWyzUZUmnoj=&ghluUmYWWbmZr=&tjBjDzZhfhhpf=&5f2N_6YiVpsj_=&lL45EHYfrapeo=&YbcmSvWXpbVYf=&dB9x4gUgigZoo=&Tbr6_gYnVjYnr=&rJZvm6WVqlbVe=&8BFBxvWseVlrq=&XIDEaWXnrcohb=&Eh248PYWYjgpo=&O7yFajZrbggao=&9N6rbrZlkWUUY=&dmfDpFYcYXnoa=&38SgWNZWkfUan=&x8FjsTXqmcssn=&48SyINZWllgrq=&hBxCUWXbhpsbb=&JWuYorXkXbddk=&xH8tVaWZmdUka=&xPR4dtVicYVja=&TtbCISZoglnXi=&KJVE_nVXineng=&cXaHgcYqrlhWs=&kHpBJNVlnndgf=&QctjTBVkpnpqd=&UxLdrNXhWWWgq=&ZOvMbsUcUnlXj=&QLpfYKXXqmYVV=&HnkOtUUnch_gk=&jOwtV6Ubmasfp=&X2tltPZlXlUng=&tVu4fPYlaobrV=&D6fnGfU_fam_j=&Cah2kYVWrbn_r=&vFh2gcXmXafpX=&SlO5bvUejaoZ_=&mOAb88WYglomb=&km77z9XUefjkZ=&Km8HtKXpkXkmj=&aDbMXqUijUgrk=&bXagsSYanpiZq=&lHcT3nUlYkcgo=&lEscoxXrfjYqb=&i64cfhVsbsrZn=&S4TL64Use_Ysc=&bOm6klWZe_prp=&TqPiJdUYiZsYe=&ohOvaiYjqYZjk=&PG4zTOXqqndjn=&OtVSlxVb_rZZg=&4NIulFYnobZgo=&4DN7T3ZhjcW_a=&PpM2psYcZahkV=&_eJcJIVeYlodo=&DdiWf3XVjgW_X=&QlzybMXcVVoWr=&wyYKoVXsqelUm=&mxyGg_Vkr_qie=&lXgO5qXga__nf=&IloVGVYg_oXmf=&rkcoCaXib_koo=&kUq5gyWjXZlVY=&qGamroYerkhqg=&yucrvbUhYbZob=&hXbpNrUU_cs_l=&7XdVgRXqZjsVd=&8RK4p6Zlg_lrs=&pnhjK9YmfdsoV=&MX64K5WaVmVg_=&LqviQaWhrhfcf=&OCpzFYYqlscls=&X6D6aRXasksV_=&7YLVgyYajWbXc=&pxfZzvZfYYgh_=&LGI9FRVZaZqjg=&wQkWCOWWndgXs=&uAa_p6ZVWddp_=&GxcDhLWipqrbs=&eEdr_UVVleXYX=&ndAUlJYZoYrmh=&ufEQ76Wnolkfe=&CM5XcLUiehkZV=&_MRAYHWhmsce_=&8hpM8RZqmXWZf=&LmspUBYnY_oar=&vEaq2_UaeliWg=&WXw2LgVsnnqUr=&boPScIWdilWhq=&Gd7ewqWisqdep=&Y33t92XgYma_o=&nKyXC7XWqppXp=&VULgAFXVdsfaa=&88GSfiXrVqpcq=&opodN6Ynacecm=&E3ihqkYY_hlom=&jhCLQ7VZigsrh=&6LnUeqXrhaYmj=&_xITHpYjlYsUf=&UsveKXZVmUjcq=&BJspx_VfiefiU=&zKyXGLXUZnoiZ=&K46KvtUXbigib=&pUpVJGZZnVjVV=&CjX5b2WXefsUr=&K_wPcxWg_chbj=&5C9hoLYedrZaU=&Yn9BGFYisYaWc=&yGru7hYkbhesb=&EY6OZQUdcaqpj=&EQTroPXfsYVrU=&UZjiKPUslbhUd=&hLXddKXcWWrXb=&8zejssYXVqWdh=&jIsmcJXWVkepY=&MV2z46YnkrjZY=&jpRJn2WVZsYsn=&zwmDYDUphprhr=&K8IMFHWpjsUpj=&WWcprrWXpqhij=&qRfPOCWapreoo=&ytRHV7Udmsopb=&YlqsIeYiWqZWr=&9q8AYEVUUfVkl=&SH7i22YcilUib=&z8eaTaZkp_XlU=&ELztw5ZnbrYim=&tYW7XsVoiUYag=&pHwyQBYjYYskn=&Zg7jCVZYbUUmW=&Ys8EawWpUccUp=&cA4poTZiWaYZs=&YuocjgZmfqZWb=&3ukif2UXlkjXV=&aFXDinYYVegnf=&fVMB_wUmUpdjp=&ah7KqxXZYUqpY=&N4xujdUsnj_m_=&bZQ5TuUYZeha_=&74gujcYdYfier=&uUeUBHYms_blZ=&JrcGMAZjcbUpd=&XXYx6PUsrmhos=&mU8mkPXdm_rrZ=&Dd4anLZddbhej=&3VSjM8YopnjpY=&hHG85CZj_YZZc=&MrFiQ3UnZrcYk=&GcpCmAZekjsqe=&eRGyhXWnlYhpU=&HPmwdzYmjoUlr=&77_bEuXgrZZpZ=&DSxeIAUoUmcmj=&tjs2bMYmXcfl_=&XyrsHXXlY_pnd=&3jJJ9TVqdqkdm=&J_paODYoVnYeo=&wXPnWmZqYphZo=&HbwOMTWhjUdZe=&x_H8BwVlosisj=&WV3iRZVhnWjqY=&kU_h89WiXbaXa=&Fz6fccXc_Vnpb=&ZztpZ8UjUlhjb=&BxSKp7XdmdW_Z=&gyFVr5YfVfrXb=&W2GqXAXsgcgia=&z_5rLxUVabehm=&CjnpEAZWe_hgU=&UhAshxZYYpZhs=&zCvJaBYinZqfi=&XluE47VabWZX_=&l_iYwZYeYo_jm=&ataPQ4VWYWVdl=&dtl6PBXfdriWp=&K2EzdgZoblqqX=&dhWc8lVXXrhZl=&5nkk53WXfqkas=&dBE3hGYYbfgmo=&2eq_wyYVYejrn=&bS8ZAiViloheh=&IGQhNxW__fhWW=&2PndbbYeZkpZU=&nuJUNTWXgojeV=&VXbmhlUVlWqjp=&q3ZAJRWfsgj_c=&QvbmhiYlpckek=&SdtuwuUUeWX_c=&nmgLHiVjqkWZp=&uBIp_iY_kapos=&NjIu7WXejgnZX=&g8BYaDZaeY_jk=&ol5fbyUngfWcc=&YIID3JXsiedbq=&noY42IZYghUjb=&U7IPibXVXUpgn=&sa4mu9XX_UUfl=&2ytBg_YkmUhaZ=&h2oeuIZcbbdcV=&fzzOPlXYklg_Y=&RT_7vnVUqerer=&xbZt2EUeXoZXV=&yXo6dLXVUkrXb=&eSL9aRZoXrsoq=&H89b4XWoodanq=&rxHoJFYjiWpfX=&AUFJNXWelilql=&ymDhsxXhiZeXk=&8w8emZWbWkdao=&eGt2TOXeccfrn=&8p56YcVYdgaXZ=&qS2rBnVjbb_sp=&jG4x8UV_qgqfl=&OLanlPWlUXmcV=&2tVdUQVYnVZZq=&5kqrL3UZfVXla=&GhjrZtYfhbecb=&MpfMjKUfgdqjl=&iWTBrbXmYkgio=&cwBq5yUXmZkci=&pIc7szZdZsjZa=&NzjPEUU_XYpof=&926l3cZYqWgja=&La5KkaVrZ_Vkq=&h4ddXeYY_V_Wb=&2NiOsUVmifapa=&A2E4PtXVmYeor=&MYaU6ZUeqas_j=&iBlg7rXskcqbm=&7kRYuXVcU_Xof=&NtJSOyWpeil_c=&8gEVNoUnVbmqd=&XHi6ApYopjen_=&qFQwstUglYllU=&hrz2zVVcfaine=&gmjuRsZgcVmXW=&W_BPsHVplUfVX=&cFZVCnXZoesYb=&nqnYwfXhpbnep=&HQ9_R5WfhpiVp=&Y4JJppVqqdcYY=&DDBzyHVjlogeV=&MVr3qGVbmrdjq=&rDyPBxYiXZdcj=&MepskCZUhsWhd=&Zzj9bPZZZiahm=&z7DGLeVXcXnnj=&cJEhX4Yg_qpsc=&5JXokpXdmXj_W=&BL72_HUicsUja=&rhSm9hYpmhabl=&rXLEcMVlkaXZq=&kkB7QQVarpYml=&qQb_JUZdXbjco=&H7TH4UYfsjXis=&_ZzaBcXcokroa=&ks2vH9Zloeoaq=&EjFRHxYrdiqYa=&UL6jXzViejrZg=&2N_EPTVrrl_kb=&DTgGnGXoZUmck=&CFHL9DVeoUnXk=&XqnupQZ_rmelb=&CI4GXVVnXZdls=&OMfndwWXcjjYj=&BqvkI6ZUdhide=&R84carWsccZnp=&mMDRGOUVUYq_c=&ElWRHsZ_jrken=&DzfIemUfkrrhi=&eijklMZVenZnY=&kX2PIbZW_rkcf=&D_ldWjUUZZcZW=&zZT6WSUYWpYpl=&AS7iBaUXokkUf=&jT4Rk4UUclaob=&hBhtc3XilmhUo=&obrkefZmWl_aq=&lgj4b_Wirebed=&aBJrOrXZcbrnc=&mEhCRtZskbUnX=&bQrG4DVimidpi=&NXY_R7VdWadfi=&oqxHxLZmkVdYs=&VVFShVUcZbfmr=&UoXim8UbdVjns=&gBy2iIVoXYsrg=&4TZeP2WfkZhjg=&VW6tgWZXVjlds=&cT42apWbpWcip=&GHMF4lUWXecZr=&AkKUFnZhnYfdm=&suDyRqYUkmgbi=&ukdNYSXq_Wbhk=&xhaP7dXfWWZ_Y=&twzJCvYfXhgmc=&6BUDUaXWrnfka=&GHsGr9Xgkgp_p=&8qBqmVZUfXZjh=&NYrK4FUedhmUl=&qjMs_3Zeo_fXZ=&uI8QtuUgkapcc=&GgpqpIUjndcpl=&pqAQEKWrerbh_=&l3jPGuUeXVjqj=&a8Su8AZYfsdgk=&pInRgRZgUebda=&fHcxaUY_ZYYWh=&RGqZU7Zhrshfg=&GC7EFXWqkYapm=&hZspN9Zkhsp__=&DCBOHzWbkVorq=&K63RMhXXddfjc=&mfhNyAYYdsUhc=&_wMLOnZYsinsj=&zO7wGYYshknjZ=&6gbPDkVcfnUee=&D3FpELWlomrje=&VSYaaTXXVkVbs=&JMPhSVYXpedYa=&XGeqMqXaqcpfj=&WxQ95_WXpeZ_h=&l4vdeeZcfqdll=&CS9SOQYhaZj_c=&fLt7ySXshiVbe=&sHUmquUndmWqg=&HZAzWaUbqUnm_=&jI6FLnZVXWVrb=&8CpwnIXW_pnhq=&qSylCKVre_fcj=&eJY48_UlnqVrW=&6ecCseVrZnrXq=&64hNgPYfWprpk=&rC4jv8UmkWoph=&WoTONGZrieogr=&vNtqaEUbligYo=&uFZkszUosplgU=&eIqHwGVqcYrUY=&KliLv4X_smgZp=&_RuS4fUfjgfmr=&bpeHXtX_qrmfh=&Di5icGZigYXjj=&QCZHsUZqeVpfZ=&teJ9SxWhcddYf=&TWwdn5Ug_bgrq=&VzZON9UXdVUig=&85kz6oZa_rnbm=&VxgTWPUsocjcm=&eWwLgZVWpVbng=&dvDQDGUciWnis=&5aII49ZllgfVh=&hqTLoEY_WrZnf=&56LxolUXfggij=&uPZiOXWXZjmhY=&LGuSivYi_jelb=&agyCL4YhWrpgs=&LIRMdHWhpXcUa=&XdQ_yjUUUn_ji=&HGhRqpYooXZoV=&qXviqxYhodaqo=&QUFtTcWqZgfrn=&bfP8QKZhsZqnr=&7scskEYZdkhbb=&ckhILmUUarZje=&hyC_wOXcosmde=&5iwQoaUmXdldV=&NdBaiTVgUVedk=&KgtwvBXeo_VVb=&AavSeiWXqs_YX=&Hdi3ENWUWikcq=&eiKOx5WnZaqYe=&__LulSVrnfcoj=&OYYCPpUbs_YiW=&pMmBqWZY_XUeZ=&uCvY94ZgjXsq_=&5P5bOLZckYaeZ=&sc_E2LYVesmgo=&nZhIXfUl_esVU=&cSdACHYaiZpYn=&4gUSBrUpdbjoY=&ILQvtQXnbfVeh=&PNdb_QVricVrZ=&ChqLnhUkUkVmW=&en7GnbZr_Ydj_=&dGoDrWXklq_Xh=&CBlS_eWV_UoiU=&rflTgbZkXfUd_=&rbipXSZ_ZbeVj=&JsI9SwVZWfofa=&u7l5PGXZdolqn=&_HAzQPWmkjeYd=&RrixW6ZfVsqUU=&D_HQL2Zhj_lni=&D8FMBBWsajskr=&pfTznHZsiWWaa=&yOgYdeYpWcbhl=&cQAV9PYVWkVXg=&H6cJxyVjoXpjg=&rvUeQMUfimZmr=&Rk7slyYYrZdkk=&PsJjQpVdbgXkb=&XuUYHWYkhadrc=&MOsHIZVimddhp=&6StkaOVYfjWnZ=&utWQk4VpggYhe=&TPc5FgX_o_Zjp=&4RpRKSWWloXiV=&idnSSoXdmbegY=&TAtOlOUo_ZWmp=&5Oz4qkXZYpZZa=&i9nyFXWslcZUU=&Fh3zaxWjUWdZe=&zTrXnpZqsYlXe=&7SLrAwZlpr_pW=&LLmTXrYkrg_or=&k9zXTzVlXnaja=&_9zgPIWWWmgbk=&9WZIDBYhppnrX=&LgboBEXpcggga=&OkDAK6UdoaZsX=&8Kdg2vZcpseje=&7tPVy5YfZmjWf=&zsOnbQZlWUhhq=&Gjyj5wUUoWbbX=&d9_6vNZlsfsYi=&3DYxAIXhbek_Y=&wzSzL4WbemkeY=&WFI3_aZkfinrm=&LdfFGsZcaUcXp=&BR2BZ4WrZgrbl=&Px8aURU_sjrcZ=&utK4hJYYVYpZq=&S9k8VzXscc_Ub=&tmmIZBWgbXnWf=&3IOborUhdggcX=&6CUmpIWoUbWdj=&59MzEQXdkZibk=&S2nVybUh_kZds=&IDaSF4Wfnbdk_=&EMxRe2WVbUmcq=&CbSTwAXiZnqog=&u4EKEUZbsZXek=&CoetfHVliXUgn=&EDALClWkhZcaq=&VqZwtoUsdlmci=&c_yDEzYrrmaYb=&G7ZM3VXngqjoe=&knv2U9ZfoasYa=&aNw5XkYiUamcj=&5NYs4FZ_eZYee=&MihyNiZqZaZ_e=&MLGCx6ZkkrdnU=&sqL9T4Yikbsjc=&KmSJvIYWpasqs=&TU8XglUVjgmfW=&w3OuHJUgjfWWl=&lLc9IqYVsVldp=&n2w2ldXqbVgWn=&sqaeQFZmhqkeg=&8LwXw4Uphqprr=&C2RPQrXdYlVXi=&KVwXXjZqgdsYr=&DuqwWMZZ_elde=&qFc9CnZXXbjq_=&kTySuEVbaVaYf=&ftT8jPUphnZVo=&Yk_eAIXrYkUn_=&7Pzo62XjYZlbm=&C6kAuSZ_dXgqd=&Oy2WDYYppflih=&uJvFkOUme_gdr=&eoVpekWqlicsk=&9Wix67YhhbeVb=&rBMyndZasjlUs=&jW5P8NVXWnq__=&XEpMfTUVbhggY=&okazlIZogbUqX=&q74jCDUgmqfdk=&obbnaRZZaYWal=&A7p5AtUsnWVoh=&pZEiGFYffksio=&ukOrtwWVhfn_d=&2MdMOJWfjsrpo=&ySdaxbXVlj__W=&lxDXGCXndjUfc=&xVCnwxYbUcVej=&jrMgIMZZanjnq=&b9gC6IUcXcphq=&XJsqokZpcVWia=&MaMnSgWmhcVnl=&OHbTWoWaohXgo=&PnNs4cWsbjZcY=&KY4rKyXfX_ddi=&YFmikxWldbjYr=&3uqKHqYkWdsgr=&wAzj6TWjlnXhW=&7L86WkWUhqYjY=&sOpDVtWVebql_=&ZUTpFRY_f_nq_=&XkWNNwZfkoirf=&P2s3Y7VqcpXpZ=&HiJrWSXd_lbpf=&hj3qXWUVWoVgc=&2WZCosWUoheig=&gxrtXUXsnZeam=&BzzBYAYVUmrhm=&83W8mPWcroUVc=&ulw2jzXl_rpre=&pnF6oDZZopbc_=&DWfvoCW_VVifV=&FIh836ZYbpXdi=&GJab7yWoeickd=&x_jFc2UfiVcZa=&xYAnwSYoVi_Uc=&MQmxb4YakhaXW=&5uDbonYimaise=&qEQJ6OWXplWjp=&N34bJeZVfhplb=&lMe42vXbcZkrV=&B8hTO9ZfYonhb=&XnmiawWaeojbn=&bYHTysUbsWgop=&tgp7RLXderWYi=&IPbVsIZedUebd=&SaBzOJUWliXjl=&Rd7bGqYjYjlja=&K4QZO6XhlaXmm=&lKfdpJVge_kWh=&FBVo2AVnZVXic=&mzEZdRWVndf_X=&rKiGmsXk_gYqj=&IPuYqYY__lVgq=&IICDx4UpncsZn=&m9tdfHVrUgmib=&TN5cRbX_empUf=&Tk7sdUVYhji_Y=&YqTRRyYVpVkWf=&mYpryIYn_VoXm=&aggv3jVfedgsa=&9VtMhBZnVjicl=&bISV9aXWmqiag=&hsF5KEXlXsVoV=&9XvaoQXhirg_W=&i7sScXZsaVjef=&CPszwgYobncb_=&rP4uDyYZVUqXU=&QuczgHYnogkjb=&oj9eLyWqVfZZX=&6Gzt5hYYoUlm_=&XuK2HIX_eUV__=&QJjhvzWUsg_mU=&MN9VswXZeadWm=&Nqo9c_Yfjimbd=&flJOoTXlYelqo=&j8eWtWZgrgjrg=&rT9bxCXijZZbY=&JaYRH7YiVrWao=&igQDROVnrcj_f=&Y2qMATWadcafp=&rlzS4CYd_XdWs=&MfskWQXoorkZn=&Nm6f5GXZbope_=&KMenNSUcZpcep=&_Pv5AbVeikY_b=&b5MweWXrVpcsm=&b5wasPUejhgXs=&AHtwUuVqmlepi=&zcY8SGUgrZpUU=&eiXvXFWXrlprg=&bCc9wyWgomXjs=&xRhifVYdXsYm_=&3_FhlYYYsqcqa=&8i4EQAUjkejZk=&jvAF6YWjUimks=&XeagKbYblpbsb=&DWvn4DWmVXjfi=&4GFv2LUlfXleY=&8bpue2UljWsdk=&qkjfSyUrplaq_=&2r7HerVpfXVq_=&3vcWB6ZWkdZXY=&4TC94vWdoneoh=&fxxGa4VoslX_g=&E6OA3tVkq_Ueq=&7PLMkiYfodsqr=&Sq_R4EWcVrWkX=&sEZCBeZegkkYU=&sO4muWYpcebck=&wQ_XCCVfsmiXf=&WgIhSXZpoeaib=&_gbB7yVdohohd=&CWYD7DXbrVgUb=&KAT4GFYqlemXk=&MJiOCDZUYZajc=&wmMxqaWqckgbh=&5U_P94VUdnb_l=&wbTTmsVXZkamj=&vrScrUZqiXcnZ=&jGZvyUWYWsmjj=&9aIcQgZlqjbgb=&7AoaU7Ylosgjr=&Bap87LUnkkirX=&XLHX9fVfohcgX=&BEltV_WVXgjZl=&JMsupFXnXgaYr=&xIILsUXlie_XY=&WFdJ9uWVmgYep=&gDewSVWmcolln=&RVnfUhZbraYX_=&hXCKfwVsfmmUo=&PqDurxUUfleqd=&przzYDWkZicip=&cMihnyZkVXgnh=&YcDiCFYoVrkXk=&7EiIV3VcYlgUs=&bxwlPxXXXheqi=&9cFNucX_cVceV=&jxQmEzY_Vopck=&DjDVwnUijn_ln=&XaIkAcWkraXm_=&UUwHjCWqmsfki=&3OBrPbX_bbVmV=&QWTasGYeeWUnX=&jHaojBWUcVdXc=&Id6R2GVsYcYrf=&ptzG_MZVXXgZh=&dFtO6JWV_niZj=&4qgK_NYYsjZls=&GUFYVTWribfjq=&EMns7JXYmesaa=&RgsL7fXahqoe_=&pidxjVVooqWVm=&Ld5dusVkoogdq=&9vJSzZXlflYlm=&4XcjbsWqkWYjm=&CmOfjaUfkgWhp=&A85NTZZkXUojY=&7jBbZKYiWebke=&5TbUjoVrfgpom=&2RqJvuXYUbrgU=&DLdtLoVbosmsk=&hRIJV7VamiWqg=&2RVTiyXcXWYf_=&cTemDTYZgggeb=&HizRNMYmZlooX=&Nit59AWooqVhj=&mwuIXjYsldmra=&9fCMqdVUaqcUe=&5_Wew2WVriqgY=&knxovnUmZWbhg=&AukwoYWnheXWW=&Jp7AStVoclhhm=&ynKENrYanljaj=&7ZSEtnYirlqWY=&AXSAoZWgjkeUk=&ZYjX94WnonYXW=&scplxLUqmq_mh=&ZlpRdKUVseYfU=&YvMQmgVoXofWV=&k43iC4YVXcWql=&TD_jvIUohqgae=&9f9jkyVcqclaZ=&mYpiJGWsbZdfr=&Ixua3vUsV_anl=&tIIkVeVWrUUWf=&sPTeq8Y_jWVYe=&YgvzEsZgnofik=&Qj4kJ5W_kipdo=&fbeZWtXnbsUnh=&CknsYVZWplWrX=&PIaCm8YbgfVoa=&Q2i4RfVdaYUfq=&QHaM8SVUrjlcf=&r7PAguVbpfkUj=&2arwJSYgskgnd=&bBzVgxUqjicnm=&5ricAEYZUksle=&PMWCIuXbhUcad=&zyy_JKVXWkVaa=&wAaJHAYbqiiYW=&5h7UNjZXjUqkj=&UekG_7VblWmjr=&iF7_WbZbdYq_U=&mkGdPmXojjjrq=&WqiILhWZdjmam=&jTu8CPXrVdkWh=&RAHAKaXojlg_i=&GX2zzAWeasrck=&Thb8lFU_n_XYZ=&ujF8CsZUhfWWj=&E7g5lLZVUqrgg=&eAN_AlVdV_gWY=&WYWEUTVlWXaWV=&B2YHoMYYXnqso=&ttQmRoXVkXpYg=&fGhW86YUlVa_l=&BDmyyHZhUcYqk=&YdHd3QZplWhXp=&VBVaCJVg_jfes=&zg9EnlWkZdVsl=&RKbYiwUnjbgdf=&CJmVT_Whbgkgg=&aoXNWLVcWXakk=&__CRx7WZfdomg=&UMjKjBYgcsgeg=&nymsddUcofbq_=&8PkmW9Wc_Ybe_=&sXndpqYeq_dZf=&2wZ63TUqlpaUp=&tCYx5iZklosli=&n5M5F4XkeghsW=&_nKqZ5Yglncof=&Jf6_rVYYfohim=&2npgI3Wjikdiq=&qbme4oX_jfcWU=&ozbRgXZgfnelb=&7pixBjWVjijsq=&arQHReXilrhfj=&hUZlPjXYeqgqj=&NBa4kHYjgblZX=&89dM2gWlgglpr=&lQ7O6MY_qckWr=&bhE9c8YVZshja=&UJASH9WpaboVs=&oGDsAdXnWrVrq=&2PFF5gYZVVsYq=&zJbbkwUqXUZdY=&CXKIJMVqjeXkY=&OX4sbUVmegnii=&fHroWlVVfdZYk=&ttOcVJUZYUhmh=&dBx8vlVcVmXe_=&qOliswVareaaW=&ka52RMYjdUkkj=&wdtQVxXbhljWa=&VRXJB4ZdoXiko=&qA7_kqUkcjXZW=&_On94RZnnqech=&csl6lvVoZciWn=&Urxp_lXcbhmii=&Eh5miiZkVsosg=&gSuAkBWkjkjdX=&Jon5WSYgbZdlp=&NUsSeQZimfYjf=&GE4jGxWUkqoXl=&IiE3SpVlmYbrW=&Jo46v7UicYlpp=&cKodUJZamWVsZ=&EMZp_iVrYihbh=&L5wiZ5VscdelU=&dVLShIYVcbeep=&NaqEYLVdqaWoj=&3sXTM7XUnajio=&y5JmpDUViemVs=&ANwftGVsWoncs=&49cwfrVWV_jba=&Q5bWdIZsZcesh=&Xf2aXYU_pUlZU=&nZyC68VjjaiZn=&mY7TVKVYXoUfc=&b5uovgYWkZkrl=&vBXbbVWmWocgV=&54rjKNVlngbbc=&rOkdavWhlafhm=&9ypGTgXkcppcW=&VtDfLEViWYYZi=&6OnLQ4XYk_fnq=&oUKZQ2UoVWaeo=&JbjkDxUhYgjZX=&TVJlmxUabgWUX=&5uW9unWkegkll=&cgC95uYlnahm_=&IDMrvmXYsjmso=&NLm8ghZnneeXb=&XJuUTIUspgnpX=&lQKVOXXXjabqY=&lUUBULZlYZkkZ=&Qjz2iEXcfnWcf=&6XCDn8Wqmobef=&UV3_H5WieWmgr=&PeX_meVgjdYZZ=&LRLHgnVnonZXX=&bGe3_CXnsqfdc=&JqWLFZVfhgYYY=&UdONWqUYme_qp=&FVM3WPXhUXqnY=&bkQEmQVnjZdon=&YwDpByWqgbhjr=&_znGfNZpln_cr=&kyjVP_Ycima_o=&YhqzYLV_ncqeW=&cBsULVXcpq_cU=&3WgHnfUVakacd=&mZCjp_ZXhXoea=&NgcOmoYgVgdso=&XbfuKvXUneUfc=&tzHrebUpmc_Un=&xGcg6hWlgolbr=&IJAxaRYWnc_ne=&SDujgEXUiqmWm=&5aZ7OkWjXbmap=&U7FeeHUrsdcjs=&WuVJtKUYVlVfm=&COi4hIWcWglac=&D4eTJtUdhWcdb=&SlxI49WmZkenY=&hEGlxCYWWaoii=&LoZkppYf_licb=&4_VtVXVeoW_pm=&HAVNPRXij_skk=&G76bFmVjpXiVf=&Hrq8QNWso_eiX=&M58OaAUUslYpi=&c7s6toVfVWmiY=&v59AEdWpsXipe=&4fn9GQYkldgnr=&zsGihEYonoljg=&wa8cxdYfnYqkm=&Z3Y9ifUeYqklY=&IRO6LSZmqegrc=&jS4nSCZcZgknf=&6SI7IDZrijVfi=&ejkbKcUsnbqcr=&xG8JiGUdr_lnW=&yLjCHfUldrVre=&RuSeSJZkhgWWV=&ulJLwWXqiaqgZ=&uUiaObZdbrcso=&NJydDcWppVpUd=&rA45NzUpmYfWn=&3Zk4wEYYaclao=&K7DHBlYqamVsU=&95nIQnYinVain=&iMH3yvZnkmkbs=&h9MQyvZn_aZiq=&jdw7lVYfcqVgj=&JujqZdZnmVUge=&spjBU6WlXhkak=&fr3zedZsiriej=&QvTBQmYYnfgnh=&JRy2fkYYsVUZh=&JGwRhoZUbqeZX=&mrCqwGViXr_ep=&Zy3CsHYfjegji=&mCRG9CXWpWVhg=&t8k5fIWoUYnmf=&FHWfX9WXmVVcc=<wcYhVdnrbiV=&R3nJuXYYasbak=&nZvi4tXXrilim=&g6HwazZfZWdbX=&UuUDkCXZcUshj=&XCTt_XWlfkpks=&gbm9nVWiYdng_=&VtrBT7YmUVih_=&gH7buVWjjiXVW=&VFsS6RYliegkY=&kugtzcVVW_pas=&QqTt4EVffokoh=&G427StWWmsUig=&AT_uLsUpikb_d=&gxIRFIVsera__=&MAJZI8Zrooaae=&5sTlGSVbsV_am=&HuxrOaWjsWcah=&ao6tHUYXbkWUY=&IFJ4JsWidbiar=&8NqMprUUrjsdW=&JbzpCWYrWoios=&sdEbLjUXgWieU=&3VHKdCUsXhgci=&auYAqSZVlUmsc=&_4IwL5VZYeWXW=&y_kbu4XY_emiY=&ry75ktVqapVnj=&aJlGJ3ZdVjnaX=&n3aSSYUYYUsko=&SNJtARWehgVrY=&mrh_HyYdbeqae=&aDqR9tVnprjcl=&n8EwdNWWX_baf=&5CIWvZZajnlpi=&fQqmVIZplXofm=&3WINGzUsicepY=&Mx2h8EXhapYsa=&jrRNiVYUmqqhb=&FbUz4HWanc_Yh=&VqH6S5VirVYmp=&uE5ZAtVillnls=&floPj9ZfoVoaU=&rCSvt2V_eUrsf=&8C3NHoYUVpaso=&yka832ZpqqZrp=&mUBQGLUdZWcji=&4b9OWaZilVdhe=&a2FwRkXo_XrVi=&htoU89VY_aW_Z=&3PjKyxYehWarc=&ihrhBbVlVmWns=&3lzVSGZklcU_U=&qLqMIJXlpcqmU=&_GOgTcUk_hWgX=&Je6AGHUcrebdd=&ytVcFbYUpbhmq=&ScgpATUYkqrWU=&uPeFGxUafbocc=&ibzxigUUdalUU=&Rf7WwSXlhb_pi=&vhKXT5UZYkbXg=&EhbYBtVVdVoaj=&xep6HzUifVWdp=&J2wLFgVghaVWc=&a4TdA_WXmkUUZ=&Oxff43UnjZgrV=&LgjA8MWohqV_k=&46dF3mZXUoefq=&8mVZAmXUcYbaq=&YGDypFWcjjenh=&N3OfJhVcooaYY=&D6iZd5Waiqprb=&SLyZ3WUikmfmU=&PdNnnhZZXabYh=&JD_6OTZsq_i_m=&j2qSt_YdjoXel=&bvvzydVapqkig=&QbIr25XelmUZj=&4vvFbiZYcg_md=&q2zpWyXhXqoXe=&3cOnGCUiakmrh=&bJJUCiXiqjd_X=&Gbt6RJVYonZXo=&bbrKAWXllleg_=&69oM33WjiWad_=&wOuRbmVerfbZU=&v8FZHcXjXllsX=&U6aiYdVbhlcni=&ZHPU4zWlprboW=&3RyuSPVeYg__o=&3KgbZIYahZXfd=&OWY2icUnjrlfp=&TwbaAKVmpmoWb=&V_qC42XqXlscp=&6sb5UOVWfbki_=&bYh35XVdipmjq=&UGhMwjXUjVVUl=&lY8xK6Zbfaq_c=&z39oXbYWmarfY=&dt7nvZVngpbim=&VaCJqwWaVspqZ=&fO9BQSXcqXbqo=&VergG7XZqrhlU=&5IqLuTUpebg_X=&InbxBgUUbprdZ=&iVr8KwYjjknUr=&lMfrT_WqqW_Vi=&DOZcOIYdbZsrj=&mznCTqVVZYmgr=&iWIGMZUabkcej=&mZCyzRZrWgs_i=&qwW4ENUlmUcfh=&emirjXWdsqeih=&DVDBYXUgrWbYW=&zkefmJXf_YZUl=&LertWGXqnYeUY=&VEXMAAYjhnk_i=&pEzhcqZUlcUks=&g2vxEcUe_lqgX=&C5hLgoUhZdkZd=&aAmQa7VhaaVZj=&GLdhZNVYgmoZk=&E9AZ3gYUhnUbj=&Sh3aaOYeZmrg_=&g_xq96W_coVag=&flivobYXZYYsX=&MLNmDKXVggfZq=&leVXZdWafZUnV=&JnXdF7ZcsjYjl=&m6Jr6zZZdVdZW=&jWRJeSYnZdoda=&LklKk_Ycdqpre=&JAZ5JGVlapcWb=&X_pTalXaocqmi=&phQBJbXZsbkno=&CBrqBXVnbUsag=&HG7v9iWVojkri=&WKX95MYrisdio=&LpXafrWpjoZh_=&8ss2QPVZsebho=&yVaI8yYc_fqZZ=&ZNQPUgUoosqkW=&7JEXF4XWbZmWo=&wUBhnuWrnZbWa=&u3JPV_WmUkhdo=&im6d78Vhhkeol=&amjzJpXspapjb=&qlAg8UVdUpVfq=&IjEQvBUdabbhi=&sia5cGVshkilk=&qvK9y6YqnXZZl=&twD4HJVbrncbV=&8AV9t3WWrrXdq=&fsl3WZYjsqriW=&yuVfnLXaUibrq=&ts8tflZgbXe_X=&xgcfrZWaXUXmp=&jweaYIZV_hWpq=&ZsLkdvWXcXjqa=&cL249pZiZegsb=&znUjyoUnehplq=&d8kKUVZZigWXn=&n7Wq8sUpdosoZ=&8cpzhAWfonmir=&ZoP4DDWgahggj=&wioXeGYljojqV=&wkVABHV_iWlgq=&32rKRmVYgXisk=&IHspmGYjofgVg=&wNwviGUronWVi=&eGjk2BUgXaUWj=&PMUGkIVVqgqdp=&DWIopkVVcZW_m=&reSqKdW_chVUp=&3cmwC6X_jgcfn=&RGRGgSWhUrrYe=&WYbldZXUkrXck=&C8uJF5YsrsqZW=&ZvhVVJZYbfZfg=&5zj5FmXprhX_f=&fbT2jvYsjXXWg=&uoFYq5YbVjcUZ=&aCVX3cXjXqkWe=&psUyxtWmUjiji=&GKSrTIUfbphdm=&owJZK8XlVrWjb=&zGn54GWlhogXn=&ERGFFvWnfpdUh=&trBTHrYWrZokV=&UpbS8OWqUspaf=&NTbFNAVdZjarf=&A_ct4qUqsjajb=&5fmMAXUojUWUe=&9rglznZXnhpUi=&68DAvcXjregae=&oZpysvXWgXm_s=&8pOue2Ydfnblb=&nYnnmHVqrnpah=&EuXCf3UmYhZUd=&L9SAgtVchckba=&m6PP_MWgmipWd=&J_fdVzYmXqnXh=&vsv_i2U_aikiY=&6UF7zeZepVehi=&rMkqHZZVZUbeg=&VkO79EZZVlqoW=&vgUmtoZeWoriX=&E2TxFqVcZc_Vc=&9mCwJJZXnXiab=&_ktvvXYonggdV=&W9GtkzWsfoYbf=&cOoCfKZsdqfdc=&NflZX8Xdqsjim=&bxJ5QgWsaesXV=&Ip7XykUVgsZrY=&jINTLaYnhnmik=&h2TYRkXilo_kb=&Qvlg4oWmgbomd=&eLgA6JVXgoUfj=&JFdlPlWVgerns=&uDwRYSZaUUfon=&qBeMnUUmrUjjU=&OgZTB4VfflYkf=&l7FGhqYrhWopX=&2Ta4JWWhahZga=&A9h6aFYkclneW=&mucopMZiWYgbW=&Da8Yi9Zdsqg_h=&hSAChbXdYniZs=&QGiy2bYmlqicc=&pKSnCHYlpegcY=&OQcDA5Zlmbd_s=&fovPL_Yfqrdga=&3IZ5vLZUnmndq=&ZurOYKXqscjmp=&QpWkMkVblfhgp=&jJGntYVdZbYjm=&4t87B5Uhhegla=&MkPUoLUhXsUUh=&o_4wmFVZjqcVd=&iB5Wz8Xqopqkg=&IljpkFX__srip=&iJa4DnXgaWXqV=&ZsuFvbWoZaVWp=&AX3lpEZXqYmme=&hPlDvwZpjUbmg=&FCk7MSXUspbqr=&Fs4iKqWYnckhV=&a5tfM2Zmmbrni=&j9mfQDZeffcmj=&MmZL7BVghX_jc=&334UtJZs_Waqr=&cbr7k9XlsmU_d=&eiXpQfZsZjYUp=&H9TH_PUViWUpZ=&s5DS66ZjXpgZf=&lkGd2WUYlq_in=&G8oI8JVhfsrlp=&rLJg27XhhbVYc=&slDibnVfWfYmW=&a9lQXIZYsonsh=&ZKAesgZhYnigd=&YIHtzmV_njsfa=&jwCQfJUkdekkp=&l4eGSjUbVspnc=&y6a4x6ZVekifg=&zRztKKZmqsZip=&ePZqq8YoXsgYf=&lenEShUcslnme=&G_UzsHZicZoUX=&4qbXNkWYYlYY_=&wB8OuCUbeWq_W=&5x5yODVXYpUsm=&bYZ48bXahogUs=&8sBWzFXhfrUsp=&iIvMFjUnWreei=&Iez_nWUoshkqY=&cTqHFOZY_jeYi=&dMxCiLYmXVsbr=&IxSUUMVmjoqVd=&IechozZlYUfbp=&xhALfXXqhbXVX=&Pv_W6kXpahspi=&3WbkjJUrgrqrp=&ru763JUZkoWqV=&CVQ6SCYficVZm=&yg8cPXYeiqlVY=&QxL4ECXpfphWX=&yCrpDzUZYkVha=&nlvsUYVrriakV=&fLoZVTZmnooYg=&vv5DJTXasorY_=&pr3GJXUcY_b_o=&IatRtFWslZoif=&Yvn_njUYkjrod=&UsPUerXpokmrc=&fB3UpQVfrgjk_=&bX5wURYqbbYWe=&JBFcwxUgfrbXd=&NmOsypX_eoVjY=&ZOpfGnVqVWlqm=&RBWKCuYqojcss=&eQ_PJSUphojjb=&sFbYDCUdoagro=&FCf8aZZgdicsd=&HcQurJYlc_gqj=&YK2Sc8Vgkrdnd=&bPLAojWrlU_jg=&yThEfAXqdYhl_=&Yfrx8UZbsYfUg=&cajriqWpfbfh_=&T66CZXXneoVhY=&EhGNIlWr_lUXr=&wpWDQXWbcZbjq=&gH8CJpYanUUhn=&mvQV5NVXXZqWk=&HpodWCYWhYqab=&25Ag7gYdjkZfk=&2WwuFqVqhYVsq=&3OsYL9UUUfjZj=&QjXRAYYpXdZXf=&THUJVkZersbln=&G98YExYUrg_se=&xh7qb6WWrgqYU=&D6WxxyZhcs_fs=&Vkv_ZhY_qUX_W=&z2oRYMUaddmiq=&fAYYyfXahjpb_=&MPtZPAXYYUUgc=&iC_WXlYfpUkoV=&E6kjSPUXkWgbq=&awrbLAX_Yan_U=&fpSm8XYrdpXlW=&O_U_L2Yn_c_aU=&6RsjP5Zmppfml=&ycypjrVYoslki=&rMJ2h3XXferj_=&dzng8zXqkone_=&p8SnbFWUXscne=&u2pw3tUZamara=&Sy8C2WUfhhfoj=&7PpHWtY_mdnja=&fGxP7xYodWenf=&S6a4gcUZUWZkd=&hQnHJ9YXa__nX=&WMfUF8XllcpiU=&_bxUCIZYgdUel=&ULwVSkWqqdidp=&gpRChZUis_VUe=&OtihIsWbodelo=&4jywzlXpeYqWr=&PHRXIRYdoUdWe=&PcqPodVsnfpbh=&MZfQcmZpqUdYk=&OLA5MsVf_hjbb=&CXKOAxWXcjYZs=&gSaJfRYpnjYXm=&TDxiLjWepepam=&yd48IsW_ligiZ=&nygNLWZZiolhY=&QZjFcxUrosgdr=&6D55egXpepZeX=&Cbd7rUVfWXiri=&YQrTRjWfg_snn=&tp_6MpWnaXlcU=&VTHTbVWcnmVYf=&GWSvZMYWXUqnX=&SeUCGcXsUUpqr=&75AxYZXWXappX=&E_TCBFVa_gaf_=&Spkt4iWbmoYoX=&Oov9oDUVYihpk=&RTSLogZWZZhjl=&iZHTRnUlijYVh=&MM8qj6Ubmpigm=&UvifqNWriablr=&cngSGVZkX_jbp=&___uC3Uao_XVZ=&NEAuf5ZZmWhUk=&UtiJDdWeneelf=&xYFVw2Vokaseg=&rtPzgcVnjhncm=&Zs_Te8YapcnoW=&tT4H_5XksUXpq=&JtVc4KVnrpj_s=&sNcMxWWb_amec=&kPWgKeWYr_UUX=&rbgIRzUharfeW=&hTTGa5UihbZbc=&DufIl6WfoZlms=&U33_OsVpbXbbX=&u9ZPJgXnioirV=&xNu_VrYeXcsoi=&gu9iCCYshnkan=&t6ucjtZiehagl=&RvpKGSVq_iVVj=&BuZKFRUerqWqs=&DIK8X5Xkbqflq=&siB9XQYefgmYY=&We8byEWpUYodp=&_HVwv3WknVscm=&iHGsBKUnZWZeo=&PC9rYiVUqabdg=&qpf9WcYdWXYdo=&5D2ctvXqgbZYo=&mj2UQNVk_ciah=&x8mwLiXndcYro=&e2KpI5YileWcm=&8aQONgVbWiUbe=&YZmrBgYrksfmm=&OLGXqgWZslqir=&lowsL7WrVjljq=&4tY_GVW_Zkjec=&xSeJluZicbrnm=&McEDacXjdpgmU=&mcuzrlUUjkjrX=&YlRQu8VUkm_bs=&8wlBkqW_WqWUU=&zPGzArZhbYfpc=&92BIZyYjfmsig=&ycHQh6XslfmsV=&mVeUghUU_hZnq=&XxfwZtUorpZnq=&sHRjibUgXkbad=<_2HUVlWWqX_=&JSNz3OUYqiYYg=&792vI_VoiZV_i=&b3gDZ2XpcbUkm=&GrQIGmZfqacnj=&8DTym_XWYllcf=&xS9ss6Ujsaljs=&y8_HpaVZs_caa=&MkKc2NUrWlcmh=&_26EL6XZlZier=&m8CB84UhiXncW=&PUZO7mYfpZdif=&ZD_rAVVnYqgpe=&yQwxtmWhsnmcn=&lumYmCZZjoWbU=&VaV6cTYVmrnbl=&5SIhhpWpasgfi=&xlIizMVZjo_Wb=&dqquozUgdldWc=&Elx5sIXdbo_Zh=&9dFkbiWjaedei=&PNTo2OZjpoYbh=&ur_ppVWegYodc=&B8cWRsYcV_onW=&EsceSxVoihqXn=&JjBWylVseZido=&gU2dh3Y_lfXcp=&AFWyPWW_reXkV=&PYva4MUarboaU=&qN5FGPUWpjclV=&jeYixFUqlZZad=&TBC_WDUUaniaV=&86e3BeWXZXrYo=&VpzgnWUddpqZn=&wYsRSVZnbmqUa=&cDMXthWWVfla_=&VCaGIiXZgqU_c=&OydwAwYiUebZe=&EVdczTWqdlseX=&rbyBZhUVhWkci=&LnaQDwVkYlqZp=&yZnlf8WmbonWW=&qydBNnYlWmkfd=&UPL5F2XXhVYba=&X6xihLZjdfadb=&e5kIsWVkfenZl=&v84fW4UmbkWsh=&zL4IJ4UZhUUW_=&GvaP2XXehfVZm=&xoUOqIXsZpjoY=&E2ShcFXpdoWoZ=&C27w7QXZkbX_c=&Wz3Af6WZjdsmr=&Sm7d5fXgoVbfl=&sLhrlBXrmiUZn=&NbAdChYnmc_WY=&yrvIGqWVncUjY=&9teYaAUYlqVpl=&3SAVnpXrWaror=&KFtWKIVffaqsc=&jIp4T7UnZbjne=&Giih6bZlocYpd=&T_44ruVmWiosU=&UHWJCpUYUXofk=&jeFL9gYppX_hq=&3dindhZjZWeWs=&6oUrGlZUe_erW=&B_tliaXpjmfqm=&9h2C5vYrncUWk=&jngXfkVsmgpUp=&aNWZBeWYYhpWe=&vgMXbpYXmbXdd=&necOB3WYhZsXg=&ZMxRhkYmfoqnd=&nLDdDjXbebedd=&V7PDCFWYnhcjU=&TYYSFPYfeiekZ=&8eZpJOWbilfU_=&IDRJCuUsrejpV=&qZh2xFXisXaYi=&BjsQ66XpsZepj=&qKBLlNUsmjjdU=&CidX4SViUXZiX=&ykyrFwYakccWj=&bb_LnyUW_lf_Z=&xZFgA_UkYaZon=&zR_OhnVUmames=&MFmvhIZgY_jms=&f6NUwMWiogodf=&hwo58VYbVqpVW=&3sVRtFYrbji__=&csfgbnZfheYcj=&LrtsGeVcoZkYc=&DAkLeGW_VXipk=&4OEoiEZhhfVn_=&VFaZfoUspecfb=&VGPdgnVjXnfeo=&hoeqR8YUgYnWj=&ijyLbbWUZYjab=&lYn6mcXgkinqU=&R7TDrLUqeXliU=&xJ5tcaWrXnfWk=&YCWDhfXpiYraf=&gf6gPqYfUUpjr=&ZJZzVEUsfqWgr=&mcMGJ4Xsrbd_Z=&I4KXHKWhqViqs=&RVmoX_UZXdUfi=&aSPXTsUmjUiYf=&EYVzbZZjVcZhU=&HekmpPUlmVhXi=&YbAwJaVrnorXs=&hd5WJxWipUfne=&PBCYfhUlqZpYm=&hrJRNuWocXisj=&5bSYk2ZYfahci=&a3tExwYWobeW_=&ucbpY2ZgnsqeU=&stkKbpZormncn=&ZoLZOCXWaplqd=&3zj5ZHUdUdeeX=&k5qP6CZVaVUmY=&WO4pbaUpWknZh=&gby9SIW_YbmWf=&wF9GciUYYiljo=&8TipcIVZsgkXh=&W6hYCJYcbfadb=&Q3lyztYWflarX=&7kPXz4ZccrapW=&cSl9DbXjaWYmq=&dqFYcfYbhVgYf=&o5f9qsYpqjrZm=&sj2k5BYYklUrU=&Km6hpIWkVe_jU=&TCweidWpUXYod=&DbNLE5UqpriWr=&cbsXJpWbbcbZh=&bSIwfGUkllqih=&VYmtPeXXjpYfl=&zgdW3NXcrkXUV=&W5RCixU_Xmqfl=&9VQZjMWfcUVWe=&i_uvtzYUbWmXs=&YlJR53UUpgqrk=&MNsg63XUdigX_=&mhR4UPZhpqrbq=&hTglHlYfZghij=&_CzwTpXcdpddn=&HpUOQUZjbkm_k=&mqLcleX_sshVc=&DY2bvcXbcsmrk=&8qwaHQYehbVsi=&JRgYlsVpmgoff=&2Vvsn3YaaUZnp=&5GBncoWqhjcVs=&WGG2joVVpmjVc=&aW9OqxUpkeoob=&T7ZzjmWiflXgg=&d92lCxVgkUncn=&A7InfiWfgodcn=&dLL2PGVhmipgd=&FIMmFpXYnXlrX=&zOWt2ZUZmfabs=&96ZDewZ_eY_lY=&x8_mtkWadfsUm=&LS5YwRWppWo_p=&mZrCuKZgefmgV=&gmnawEZfkWZWV=&NnB6NGYjkbYZp=&nixxVVUsVVbpa=&HqdiKMVgq_iWW=&pSAgnnWlerVds=&fnGhYYVe_oYV_=&v5CB7xXs__kfo=&HpUeWFXoZcgYs=&FP8cPuVnhUiqa=&OylohHWVlomUq=&7hqXT7XrinYsn=&zbCHg3VVbW_bk=&xC2AZbZUagkfX=&o6bdPJYrqsheU=&WVm5qKVklXaXs=&ct38t7Wen_lsY=&xhqSbPXlcomUb=&_hMytIZhYcXae=&V7NtOQVpjkWrY=&Rjz6T6VViZffa=&RgELUwZkmhdff=&nwvIXDYejokiq=&JqVlzqYcVcmZr=&kHjVrKXsYcild=&KLfAj7XVaViWd=&FlSaE8YZhqcdl=&kfHpiFUgmUkhq=&OAIV6UYohjrom=&QzSMABWgnUlmV=&EXducTX_ZXafY=&Sky29mYkYgchd=&SGXGQFUi_jmrV=&EdUDz8YXfUscd=&sHb9iHZbdooaj=&EFAvQYUYVoqjn=&bRQAuPXcmsYZg=&wm4_OiWYmVXbj=&HpvzVLXasbkhq=&of2vspXWXfhh_=&3dArWCZhlghgp=&ReagNmVdXdqlg=&2NOGFRVsVeWiX=&5xdnUOWZd_jqf=&ULKBFtZgprqaU=&NXUgVQUhqWbhp=&c89ydcZqnoihe=&QeIsJ4ZlsYssZ=&sgXQ87Vodprmf=&AhT7qAUUgohdX=&RMbaUgWirsdcX=&qlALqkZclpbUZ=&fN9EKzWgbjkhr=&Dn4klcZaohXVp=&thpbu3WgZlVak=&Ig_YXoWimeprU=&Y3Ij7FWfgic_q=&7xaneAXgobgnm=&q_aoh_WpX_Wpf=&gmHnSxUUalsgj=&NqOIrNWaogfZi=&9d3yMUWenYqWr=&GS8yFeXXrhmgV=&3mI2QgUpUqqZs=&FCTrevWqY_ink=&NiInxQZrckkrZ=&xZVG_6XWrXfeh=&HaaLOHYfgZVhi=&vXFvgeVeYgog_=&eXJzcAYeYqYci=&AOofyLUdmqgUs=&J2AadBVhiUrlX=&XeOxjkWjofcVn=&ioxu8wWenaafb=&UsQHbWVfbXbiq=&VtQxUEVpfsUfg=&gjy9PGXnbmZoj=&xwVMZrWokrgcc=&UU5QwJZUXkYge=&NB_KxlZW_iVih=&uGUHWJZfhhjfZ=&IlmOH6Urhr_Xm=&D9SYfiY_mf_ia=&3liijyVgmUkZj=&xujvW7WmWanod=&dW5NkSUlpsbjp=&_INEDmVffabWd=&AbjWhXXeqUbel=&3acTZBXlaVrbZ=&WiKESgVdXllaq=&IpiliJWbaXgYY=&b6aPGDWZlqeli=&DNyrdeUbjhkhf=&Z5jyz_UacWWZl=&NgQySxXghXlVi=&cdp5ciYgXrf_g=&YyMc9gZriprWb=&kOA8diYqpWh_p=&E_oAlEWmZilaY=&sg4xAqVkkkhgV=&WDclBZVlqkhsc=&Gsgzz_Xbogbki=&M7bdgHUmgrqUn=&QpqOsZXmmYXkr=&uXSLnvXqhsreU=&HTkTNuZneoZqk=&MReTUWZpXslj_=&gVeTdBXagVeaj=&32vEnMVriniYX=&aWgRQPVgoqpVs=&YTpSOtZsicbq_=&c95DZoUWpVsV_=&8RbeQuWYnafhr=&3cPbsrWZfZ__r=&cs3LqBXgjZesa=&JW5wMyVVZojcc=&Y6NifzZhmf_gU=&WYAQIhWgqhggr=&MfSWtfZjlriXn=&FYUGk3Z_bnr_e=&MKEjTlZ_WpZng=&p9_scZYenhVec=&IzaYGBYcfZfbX=&kajbmNVbfc_Yl=&ggEinJXeYWWYg=&HIZHNcUoclnob=&imkgNvZieZimj=&EOZINiVr_qps_=&K_rNyyUsja_cc=&acac3fX_Wprrq=&pyQIwJUjmccVl=&_TRQmEXaYngmj=&QmsW5fZaghgWc=&AUUhRlXgZooVf=&eV3MkvUnrUhei=&OxY8DOYnolg_W=&NV8ygrXYUWbkZ=&TcB5wmWbWjsjg=&pQC9NwVZfogoo=&zTJcQtUnVggob=&xqjyUuYUjoneZ=&dUJXccWqglofo=&TC_vVrXYsfchU=&s4mhUyZjgnlrW=&tIYPlIVclrl_i=&yArFghZnqXcVe=&CEBX2gVYrZpmo=&bNYXesVcahgUU=&fkE2yXYjhXfhn=&6_Hc8bZdidcfp=&Cvc2CpVhfgXjn=&HQihfXZsrabhb=&KQdDtCZamUgri=&H6xQuTZoeXbbh=&yFJC9BVZi_ea_=&ZuY7aoYqXdorh=&TMyH64Xrik_pm=&d3KdyYYaapndo=&pqdLssZfnaneY=&Mqfhy2Xlrcora=&4YJGrZVpkVjqp=&Hct8JYYb_hemb=&MIKwugZk_XWZa=&r4JyuyXbdZVoh=&klcstYVbjUsoc=&ZYIRVjXocqner=&aJ2cfPUmgfZUp=&eTtJgqXWcbmmg=&rUy5CyVXabaeV=&leS5OjWmdcdgh=&erwJFqZ_aYeb_=&rdIcfDZUbdppa=&jxtta6VYVi_Vj=&iAJk_zVqrmfdb=&KWspHdVeroWrf=&stmMSuXoskUWn=&iIOqtYXiXUdep=&K5wHzDZokoYqp=&fekntpYgncWdh=&f8RhzEWhgVjil=&HTrnACUisocgX=&rBuJldYZcoood=&t2GU8CVZoepni=&mdG8OGYnXYnhj=&XBx6EKZgpec_f=&vDhwRWYsckpq_=&xAmaDlYd_fes_=&EbeAaTWnjpWXd=&nrSkJwWUXXcpn=&eoyIcFXWcUXiY=&fTYcP8YoaVcXZ=&TzNmCWWXbVq_V=&EiOKQBUrkVlpW=&tnJ2CkWaXrhff=&zR_o25UaWomc_=&T4F329WjlfXnq=&hrxaF6Xcpbf_s=&nOpBi6Zejmchm=&VzY_VXUgidcsc=&m6ES_4ZpkohXp=&c9jARSZWlXrkj=&HMky7MXZnrrsj=&tBqNS_UWgdabq=&Tx4uTdYZdalVW=&ghJr7jZZg_ZcW=&pCESItXphldjh=&IsLNOJYilkZWm=&RdQG79WqXUXjm=&xZqEEkVqcpblh=&UcN_eJZdmgoYl=&EvUaowWYbesZk=&4mRdIdUkogoon=&P99AR3VYiV_qn=&2uT382WblbnYb=&OVVDscYklUpoY=&FVW2diZoiqgnn=&8byIqlWVkrVhg=&xgYpX5YVsnnrY=&8EYOIQVcnhVrh=&5UdJOAYpgogZd=&hP93etZhnrsYc=&PU3lm9XmYspbe=&ur6ZjzVXfbfps=&23kuMNWrVYlVn=&aEEWKhWsUepmV=&YwbJRrYmggYni=&95maeWVqZlpZs=&GoL5cKXr_lfsg=&GphAFrUWsZogi=&KcdxSPXoXmlVY=&juqfTqYqccbZg=&QjzpJAZcjmplh=&77FpNSWciojXi=&dYoKk8ZkjUlem=&wOuCBDXpfmWZd=&SwrCHPWhbVjoa=&Zi5ReTUqXogpq=&qXSkiSZXY_ia_=&ssACk4WXohbif=&wTZIKLUnqhlmX=&Bh3lMbUkdgU_q=&nHqsFUXbWVkdg=&sdKMlaX_nVhfo=&bkQbQOXerrqdr=&odpPq2Zonjbqp=&9bdSJzZZk_fgW=&GpNFiAYlbq_lb=&PkSRbyXcqqXki=&iN5G5vWegkafi=&OH7AfeUVacXdk=&TBOecgUjoWkfZ=&7HUjyQYa_UaWl=&uiYRjtVUrgocY=&KQ6gIRValY_Vi=&XBg9gxZrnbmoU=&Wn8UPnYVfafYW=&EXuKvpWcpbUdj=&nNjMNZUrfdbmo=&BgmBfXUdd_ads=&KS6zB6WdeiUYo=&gEZslsWdYnckb=&YIUZtwYfnpmma=&y_szMPY_ombYe=&azApXQVbZlheV=&xfC9HtYXlYZie=&X2PJWIUsqknXb=&HNWdJCVkWbVVf=&KvBwekWlilnbl=&8pEllOWcrcfWj=&GdnywxXWpVisr=&MPeuTrVsWdXnk=&5TW2PdXd_WXoc=&bov_xzYbsUgka=&2a_WUjYVabUkj=&cbyhayXkoj_ra=&dlIzWEZjUsnWX=&tHwYHsZ_prpeW=&_dVotjUrknVnf=&PKWcRvWsdgjga=&tbivmOYjqoWXg=&5y4qHqVUXXhlg=&pXUqP2YjWcgZp=&iZu2PqVmfnoWp=&DW_BlZWmeeopU=&ThnE5IVfjYah_=&K4YSNuXoVVXcf=&GdRQ3sWbsfgcp=&P2_E9CWdchele=&OMVG4RXkmbqpn=&Z4LtseYgoelpV=&6ZUOdFX_ejmsl=&I3AEFGVciXalp=&Hv_xpLXiUfhri=&yLZ3CqZhbiUpd=&8z3e7YYnqgae_=&2weqCAYedqkZq=&rvMHFrXpYbZjV=&5fhumiWgZZhlh=&JvADatWU_elsg=&Q_mbyMVamgmnW=&f7DlZrZir_jjg=&jVg42JYnVmYXV=&JLbfoPWgsoWqg=&hA6mqJUeYZhlX=&ncCYuxUZepl_k=&aGfQ_UZonUXbg=&6BkLMpXielZW_=&2FgexhUo_nmYq=&l4vxEeWmoXWkW=&OQ2YPKZUfnsjX=&SZEMFuUq_snnh=&d3idpnUknUbXU=&5ACyExWWaYkZV=&UZA32zYqfebkY=&vV6b9DXoigVqa=&vbU8yeUYYnfYa=&GOxIdFWiikbip=&OahiG4WVsboUn=&eXjvTOZerfUom=&FUFKbkWspabmo=&uowbZ_Z_jXgsc=&KarFRwZjieofl=&MtrMgeUslXbbd=&SXQyOyWZXZfYi=&Z59gOsWiXUVnn=&Nxax5FWhoZdmq=&LoPKTKWekerqV=&PA6abUUjbmZkZ=&t3tcegUVqkWdr=&l_fUJ_WfcomYX=&t86gTSU_W_riW=&NhjSqiZfUYjpk=&ZqAEAQWYVggn_=&L6msW5Vphmsoc=&Sxk6dNWngrfZj=&g6UdFjYXXgXVh=&xrSNRBXXdYgiV=&bb6liiXcYseVf=&mmRJpJXrqZaq_=&l9_jkbVnXjqgi=&_ZZyVFWrrlpV_=&kteWUQXrV_ons=&QfybLkYmkgXfU=&fcVERzYlhcqfq=&D3diy3YUkZqeg=&NZ5txJWWZ_oer=&CP_b6cXprWWif=&abWyg2Wefjqdm=&aAbHxwYsjbbkZ=&lXt96oVsXcWdY=&MZvGwuXUrZlYh=&ML4xiCU_qkeoe=&jyvoIDYshhndm=&UMWQUsWjYq_i_=&XEsDvPVUakfmb=&Qluz_ZUhcUaZs=&fPbzhuVaZlrYm=&PKxiaZVmnjXhb=&4KeyqcVfdsbaU=&ZBwwXuXpjUcXW=&EntlxXWedXcWq=&pShLYrZlkb_cg=&KjjmpOUsWiisU=&xByNDKWYXpgeX=&7VwIKTXVYioob=&DhBPZ6WqsWha_=&P9zTTvYhcrbni=&qIEvwzVVfd_Z_=&KYONdGZlrsalh=&VBmNEKWdlgVpo=&kIntvGZeegWin=&Wf2nFaXljYYZd=&3_mEZPXYpm_qd=&YZ3UZ3XVncbrY=&ZelXK3ZVacaaW=&ro7dVvUrkUcgo=&YOr2_DYcnnpjY=&qHmOOnZsZUUWh=&X2XXXHUXVpohZ=&8S_IlwWWddg_b=&CaCm4YVbsedXY=&_rdTkrVlpUofV=&2aC9mcX__ifcc=&jyQykLU_dlXUa=&cDpnYGUdmnodl=&2ahvVaUbpgiUr=&ibIq8aYnbgjma=&K73YjXXVeWfko=&M75qvQWonUojU=&l4OXhwVWapijk=&KIVxHYWXepeZl=&jtkqC6XsrcWqc=&TeZgRhVXYZUgc=&6a7SEMZqmZZl_=&mh_x_KYhUkhbY=&XdQTBkYfnksfo=&nibegjUmksXbe=&DRuhMyZVn__Wl=&MLfsLqY_Ulelo=&2iDFWPYaslojh=&WJVpSXY__hVrW=&LFrRpzYqXmblU=&lQlMMgUeigri_=&FAsnl5XkbXgrm=&jZ8Kj6Yffphog=&NhuSOKWsXYYWi=&WwNTDQWYbcakZ=&bfJKLXZeqqnbj=&rdhj4MXVqlnhZ=&E_Thg8VYUmbse=&asAorcUcdnnod=&IEWS_wXYllogc=&Drdw4lVslhjgi=&shzK5OVcaiplk=&uzA3ycWZsd_Wg=&QjCiJdWphcbZ_=&xFA9B7ZnhjeY_=&XQiPRyWWWV_bc=&E8AfVmXaiebeq=&KTMiAOXjskm_i=&zELwYrWiZrUrp=&bc62D9Yegdhan=&D_qBArYsremkb=&iFRRxZYhlsUVp=&TLYb9DWUoljpg=&o9_SU7XcfXkYe=&odh9B6Vsfksps=&EXdnSQYXkkeUd=&EgVmfJVhVsbdh=&v3fXwoUfhaerX=&qRRnRbZlYlXsg=&vMvdYnVlUqkXs=&Qvxp3WVgYYmji=&EknCbbYaioeki=&cOk5KgZmldhhW=&JwJRqAZprmjbh=&uZPHSBZWh_ssZ=&6luXVvWnVefsf=&JftoLfZVlmgVW=&bTHb3bVfhWXZV=&GzsecBXYemsYm=&arQtVnXpbprlf=&YhVacqUYr_fcp=&cDW3VfZ_jlWne=&7SlHAhXgpjklc=&pzjL8CZVVgoVe=&tSZvvgZmdieXq=&NlNwigVrfUdhn=&2acyQiXnYepXa=&FV9POlYkgsrpZ=&INnAkyWUoXllg=&GhBBNjYrVnoUn=&Bo93oRXXakoXW=&r_nL8mWspZiYp=&h2zilWWYranYZ=&xNqFJyVWqhecj=&6I3LInVZlprhi=&H8nsRlZXXYW_p=&bw8uB2VYgYioW=&izqYl_WrVabkU=&T5ENWWXgafbYo=&n8zcb9Vlronhq=&IyhN8RWmXojbo=&rZTM36ZfiWmcn=&WtIaBkXXgleld=&AoFCIVZchgsX_=&GYjtBpYpcW_aq=&bRMB8BUdYsUVs=&BQBdNFWgVnqoi=&N2slXjXhocngf=&4LoXaOVjboc_f=&eliGzBVZbs_eb=&vJktPBXYVnneY=&6MZAS8ZXpZUfV=&83NoWrZoamadU=&R8I7cCVcaXarc=&dodrm6VkmesXn=&rRy5w7YlhnrXU=&IItVWIZ_Zr_Wc=&49YIHFZhZmifk=&d6cC4CVZVjogk=&xPJyTpZVbhage=&hquFKXWkrjsUo=&3KJuuDZUlVsge=&EEMYYjVVpjenZ=&zMVgesVreWrhp=&b86fmaXVlcchn=&K8If9WZkirXos=&vDqZ7PYfrrjcp=&OPwJIsU_ocros=&bLt_YwVcronZc=&vIdWklXgZllmc=&hmy5dgYqceoZc=&JVsGfFUsfrbsU=&2H2T3yZrZhUnW=&5q2_B6UsdsdYY=&4s8eCtUg_oek_=&_t2KETZgdWdUh=&leV33qUfcnpqk=&g6r54rYp_mhho=&2G5DrGWn_brXs=&awuNKlZgleckX=&d7GJ74Zhlmnes=&u8woTGWkpophs=&ttGLbqYYqafph=&L44sIsWisUlZm=&psJyfTVoZhoas=&8PANVUXf_ll_l=&pBsP7iYUjsYah=&uEHPFUWeVXYWo=&FNHqVeXnccZXn=&9NGLhgWjWUnpf=&WomofVUnZsj_k=&8n7qUzXrefskb=&DvrBmgXgVYYgV=&c5EBkNVaVZVin=&rSH35tYVZUYnr=&vYR9gaUieqcsn=&KKJi9sXqWhrkV=&r5esF2XerksoY=&BOdUFYZXbdadn=&2pr5fFWhYjlhY=&EPuyRtUajcUhc=&ZgTzWoZnUoees=&_Y3fHrXbhaf_m=&rQXMWeZismZWb=&2y5ttiVfXsUcn=&MzAAsvUgrnfgY=&6Kt3FtWgolmlh=&lYiWuPVYpbacg=&D_UyhuUYboVgh=&paUls2UrehZkr=&7gycBiYVYekoh=&Qwiol9UidglZX=&8o57KmVlc_lpk=&dpaErEYsmnqoV=&qPZ7hsWXlYYUk=&rO5KVPWpnjpXd=&nNFg7eZk_iWYf=&N7kCCbXnZgoes=&KpjOSRVWqlsdp=&VIsBkiUbXb_Wi=&fHLsdxUdbcjUr=&8gRc5zZpdYqWp=&Mm2d7QWrUikdn=&AQuhEnYjXmdks=&ozvIJjWqkjg_i=&qJg_SuVYn_qWg=&YH6Hy8YXfZYcW=&IhifqpWU_ZdkU=&wHjZG7YWembap=&mYWxpUUlUd_pc=&JdMh7LUpWpgXi=&Bs7k87ZXlgnir=&CKb7Y2YYcohcW=&tpzxYMZfimXgg=&Koml2jZooXk_g=&8z_tjXYibcjms=&U5iRhTWWXVhfk=&xguEHhZgplpVh=&cpcvjQXprkrss=&PDyuCTVkrpdnX=&aPWjk6WXmmdnr=&zXFmWkYpZmkdV=&z8NlGVZXoisZd=&9VV3RAWqslWba=&NVX5rJXmgpcUg=&lWqxKyYWjXrWk=&pAM7WyXnrjXWd=&AKBjS8XamqkcV=&im8cBxXnZkXbp=&OLHIzsZ_efrch=&_tNzrqZlkr_ma=&ZeA8A6Zh_pbiW=&xJiQldVgnoWsZ=&drzmKJXsVlhdg=&tB2rt9WrsqiZW=&DlpHpEWghbqem=&Xe9XmdYnUdZho=&Zhb3WPVkjmZUe=&moDGqgWUikfjY=&pTpFOtZpXjhZs=&XZGKApZnXcZdX=&w2dBXmUilZXm_=&NGlQYWUbYnjes=&qCxl_nZWVoWjX=&6Jlv83Xkl_Vcf=&uvRJjTWcpeWdk=&_aRbqUV_oWqcs=&u5K3aqYddjq_q=&LWz5xBWsVhVdf=&R5Ud9_WX_jele=&JzDSAIZpnqZkk=&WK_ZRrXYsnsVh=&dzi2DyXhfbecX=&wRoazzZrfhpXi=&ANFPgYUgkqrbk=&BLMtwsYpobjip=&XiTgHVYiqbZl_=&ohIA4_Uliahkh=&RBQ5uEUXYgk_c=&rzQblSUfZfqhn=&QWWfmQYVj__ci=&7B89iIVXUpesq=&oxUAunYiklaqi=&tY_dasWmiqqrU=&z7nAn8Uc_pdhW=&ETeG_DYdhcala=&XUo9cTYdqrZ_c=&z42mUSWspXZWn=&bowsGyUZkjXVW=&wbRv4NYkUZaUn=&HcpnmZZUasqUq=&d95BdWYfcbhl_=&PDAvhxYempnrf=&rlXooTYb_hsap=&cgEzmyXfr_Whk=&_mixBKXssfs_Z=&qZpIxtWaUVWWc=&OhnZIeYnmrlnW=&6MhuaeYdXVoso=&a7Th4mVnrrsnp=&QzYwQ2UrcaaVr=&a8F2nIZUjaiXY=&yslXkIV_oYaqa=&R7N_GXYgeddfp=&GmurLjWk_dijU=&PpQzkmZprWUlW=&KVMetnVrso_qa=&Dj_6CNU_mqqqp=&TShaPdZcranZj=&gVpph4YgkeqXd=&QSPyVXVnpUm_V=&DzCJGEUhUhkXh=&cp9fqeVgoZnlb=&vmUPg6Vamdhqf=&lEL9qdWg_kdgr=&rzGpDyVelgpmg=&XFx55vXqkWiUW=&a4N8o9X_rfUah=&uc4DhCVeXfXUm=&M9NX4oY_qoWXp=&VAoqSPYXalhsY=&TlHJOtUYXnspp=&5GUNJGXos_oVl=&dYeW_OZiUjgdr=&CuGGIkUnVqkXo=&t2E967Ul_Vrjs=&RLGOSRZebobsd=&RCYUevUpobfUU=&eYUoqpXsdXWWV=&FdKGM6Xgqpbaj=&y3Bcd6Y_iUWhj=&HRCZeGUkYiggc=&VhtgdlZ_ggjdf=&5ZZxU3YmWcUdj=&ByJhSEVmklnbm=&3BfkwlZjcnpZh=&WqvsPcWebmnhW=&3mqCsQYd_forY=&Ig9rrHWkhaWro=&rZdIUQYqYfXhX=&YbZmX2VmhmeqX=&IsMMKOXUnabZp=&UVtt3yV__Yclm=&QQ5unsZ_flmeb=&W7BHvDZaUhgYZ=&sX7_vBVbaagWo=&8NANjeXcseWom=&gZDVkgXpWVYoh=&doaeLSYYViksk=&qXDoHZVYUofnc=&tpKRpZUknjedX=&MdcOiYZoqZcpX=&8jmsM4XZprVnU=&4S4LC9VUYlUnr=&KuGG9DXpoqcdj=&WiJVU9ZjZjsen=&BOVer_UVpmdmj=&Glf2iTWdqhrnV=&6_7koFY_nUr_h=&_RlzlfXaebi_q=&k4v6ILVemgeeo=&OvPllAZlWYgrq=&TYdCKsXc_cnqX=&iTsCCpWWUrZgl=&jusDeqWZksmss=&x2Ii3qWbXphiV=&4TLdKfWVehhcj=&2vAEzHZmfYbk_=&MmVSWoUpgfrne=&5vCp7PXjhfhcl=&yp7olZXkcVplY=&yS2ntcVVk_rgh=&llEbT2Vq_hgse=&P9eZSjY_Ulnqo=&GYQgj9UdrUfnk=&x2dAlCXUVadfr=&MVbUaZXcfiqUa=&IHn5lmViVolde=&t5huvWVr_pXsq=&xJnXVQUraYscV=&UEPMYwXgdeiZf=&ZdLa6YYVomWll=&NF5UTIYZsUWna=&UIGKRkX_cU_bg=&8s5Y7BYUfmZbo=&VU_cTNZeqUpdZ=&GGxBMkXll_mc_=&DY77htZVjXhif=&Jnft_AZkofXZX=&FFXNwkWm_qfdj=&KDZvnXWksolkh=&TZKaLpZsdshqk=&dSMHhGXYsdUff=&5hyIsDUeosjg_=&nNMljFVoZeYqq=&DQweIjUokqacX=&CitAyyWprUWm_=&EqgtYuWiUaYoc=&QHrffAUhlarcY=&hIIW2RZWkVlgl=&zTMevOUckpVqs=&cS_YGVYbrXkja=&VVc8KsYrXasrX=&_7OpWWUoUgalj=&rrt6cGU_WZfX_=&tTv8urUmUeiVn=&oFFgSoVVcXkqi=&nEMbHMZVnioqd=&u55tikWbYUlnd=&P5DgLVYjkqbmn=&EeUTEcXorscUa=&eNUMGaUVcsXgU=&HG7iNcUdcUhoh=&OpbY5RYllhkna=&gDoZ8oYcsoWbj=&sMDOaQVsamUVY=&9GapHsYhUdcUr=&WokmTrVcbebaa=&2cg_zgV_fXekq=&MEmYj6Vs_UUiq=&S_n9GMYdbgaqW=&aCmHSYUoaXcdo=&2_o68uVspodeh=&3BwXOeWWUqaoj=&5OTURLXooiiYp=&v8cnXIUbp_Xie=&WxYgLZWpoiW_r=&VXEBxUYkgnYsi=&7FtVpTUWnhqUo=&6USBvtVejifXf=&Phuh3MZadljjn=&krCTE_Ucf__dX=&KCT3hoZhbrp_e=&nYcIjtYmZiamd=&uedq5PXZjfnoq=&y6nOxSYgfY_Vk=&M3nOnwZplenjU=&LN5ZquU_ZcXjj=&K8YnP5XdVZnil=&fm3jHXVfZcp_p=&OIaZowUonbZdm=&LWAvV4UeobWhl=&gjGFFvZkmeXkh=<34avUnrekVo=&jdcuTHYmsh__c=&xufKsnVqklpad=&aUl_ocYnZbehU=&ZzJbDnXifhhcj=&G3UrI4WlUXplb=&fV37HJVksbaVi=&FTEKXhVYsampr=&JG6nWsVilfUad=&_3hZatZlYXsiZ=&kl_BSeXUoYmmW=&czJ52CUpsZd_j=&QrIIydUp_blZr=&9VzKrEWrdlepi=&RxaKQnVdmjoeh=&gfvvgXZqsmiXj=&caZYXXXhaqpqX=&7tcv2NVginkUf=&zw5w5iYcjUhmg=&4LLY43UobrgVW=&TkMr4VXngnXpm=&WrdfYiXcssfnZ=&J9oWZoWZVobmm=&4RylRBZriakVV=&BxJNZ9UYWYbqh=&CYJ3l7ZjlkVpm=&klqyzsVrireZV=&eVMFRsWWWkYii=&47ZOamWrbbYee=&fbB6mtXigbjl_=&NtmSGSVbUVclh=&nmUJuoVXroece=&9Tg7tnYpfogg_=&sYpyymZahopid=&iZP29ZWhhUpc_=&xIGyyPWjWVkd_=&FZ9xt6Ziehekg=&YQaJhRYhhj_sj=&xsTEMVVrUWjhk=&v4t9ALUUgUUbc=&Nyl66AWiZVqWn=&wdaNRXYcpoYkU=&Z9u88sXaXYUfr=&9RuZeHXWco_Za=&wCbRLgYaXpkms=&wDNskqUVXkoYp=&k6riFUYoglXhV=&LaExK2XiqVchd=&M6IJIWYVUXoeh=&K_Nn4_Zaskkan=&3kn8nlUnenmZi=&ojbZK8ZnonXZo=&Vf9QqmWgiaabg=&8LtZeCVkoarX_=&lNXaGCYUlsiWr=&FNYn42ZflW_Vc=&8_s8kYVslnUrp=&PvHsoqUWUskVX=&lpAf2cWpUfjfZ=&3h2AShYUdUilc=&TUcjqMWrrfWqg=&dfGw73VVfmUnh=&XTrGmaXnlrXps=&4fBu6yYdagqac=&_RiMqSZneYYhj=&9fo3T2WdVmcfp=&RxA2XpYbXjjoi=&HX7g47Vsss_ZU=&Jaf5ypWkfdbip=&SRAM5VZkZYl_i=&BA_8DXXU_ciqo=&CEgdx6WrfVWkV=&2TDkUZVhilqVb=&HF6uCnZiirXgi=&652euzVVnpVif=&VSxpO5VcXjqWZ=&WSIntdUepadqY=&vJrON2WgVblji=&qP9VgYUoqXohb=&s4Jv62Yeoccpp=&e4HxHwXrUolrb=&yDjVz3Yobjq_V=&yCCsnqYVZdram=&DLHePuZfUghoi=&PmkXXaWbnslZk=&fPElQUXsUac_r=&cnonU_UUaZnZs=&epDK7nXl_mhfc=&9WQarCVZiUorl=&oBHcK_UfbXlmd=&7XVnfWWpnhjlY=&hKkcmrWraspbY=&SYe9KyUoUYZ_e=&qTKvPqXWciWbY=&R_N5XnZXUVVUb=&ik2BEzV_mlqg_=&6SaQT8YiWU_ga=&LeaLrlVVjUZhq=&uD4FTvVWpbnqs=&Brst9hUjYWYpd=&GCoPZqXqcedUZ=&qpCyfuVWVXmUi=&VbLNfjZXkrcYg=&GEOi6mYkllncp=&ULz_mVXfajssV=&8ASywkXXlijaq=&2KO2jfWlgegec=&Wo7VzMWasoWYl=&nvhuSiYopalff=&hzpwcoVUqrkeY=&KcNjMiV_qsZlg=&GK7jaHYaniiZl=&J6EMfPUidZ_VY=&CeSEgQXhoaZWW=&qwCBsHVWhmaib=&I62EECZeXiYrm=&2Sm6dfWgsXVsX=&L4ZomNWWpWXZa=&sdtpJ2Zogosjc=&y9NJqJYgaZnrZ=&VvFnu4XW_YZUU=&PIc5fMXXr_Wdf=&HDc5nzVkdZXqX=&JdyLIfVgsZnUc=&okpm44YWrldkr=&kzIOAcYUlsjhr=&7awchAVrWgqcg=&_WAdwtWbhrrZo=&7BMT4aUsnqYab=&W76yrmUWYnYcY=&YkZIX2WZsmaXi=&ISszxHVfaVrdr=&GXJREuVgaXVrg=&OY9NEPWkglXUZ=&38xmlOZsjighp=&KmJ9Y3YrocVYU=&xb9fibZUljasU=&x_twFdZWfpnhc=&8sS383ZfhrXYg=&V9FszGUbmZqbb=&e3zxJhX_isg_m=&AnevLzZan_YsX=&dAtOytXdnobnf=&g3bv3pXkcZbXW=&xD_sBdVUapYWh=&mfKkXgXgdoiZm=&gpfJ6TVWYgrqs=&uUrwPQZrXob_l=&GlAMzaUlUrpsi=&Cep7duVnYjjgZ=&658a3RYoa_ilX=&sHbh3SUamfndp=&oYN5fgYgUkiip=&NrhUIsZocq_f_=&pNse5yUcghsmW=&LapYmwXXYfmsU=&xzBEZIVrjffii=&QXRFHmVepWmjm=&Ev_kFiWcirfir=&9oJZj2Xpoeqej=&BNzHX3X_fm_ZX=&a42uHPYrgbUWn=&7tW4MCZae_qpj=&siretNUYslonY=&ALove8XUspccY=&2nreFVYVlYfXU=&F2YOsfYlsbUok=&anmpsuXrmfgsk=&FOIfsjYXdfYkj=&ORHBqPUWhqlUj=&wkLTI5Wsnc_oc=&vEOHWbUYeXgeb=&iSFAghYeYbqmq=&rYRV3_UfoXogc=&xn9HutZWiebXm=&K_pQOKWaapgkh=&9ehLJ5Vgsimds=&GBmcaZUkibsdd=&KJj9kLY_cXgjg=&LeBAY6UiaVqip=&Ih_zTwZ__jiUs=&cpFz2EZgoqUem=&uAzT2uViZ_kXh=&wAXz8RXcmmfns=&CArO7TYWj_ZVa=&UdrKuaXZ_lpjW=&eyH5MZWhpiebo=&4Uxuf9Usarkcr=&jtZhGyXokVlmg=&DfjuumZdqmrob=&MjP7okUsopqZb=&aIbt2iYsUgXfe=&AyQMrpWpW_rpk=&FJ6pUPWXWYhUc=&dmt5veUZiXg__=&efqIbAUnZVnVo=&udTdZfZVaeejj=&i6weuwXindlas=&sDSpYVU_dbdlU=&3w3TabYmsVmis=&PiwNQFUrokbi_=&rUeQEqZrhZnn_=&y_78DzYfpldok=&SbGW6XV_gZXYX=&MMlelLZpVfdaV=&rrcv3eWcbqZii=&QxB2y_ZWcsiUp=&fujC4MVkZ_fVe=&DjUHGkXVYWcbr=&uhkRBoYjcfXif=&LXKRCcWilVbjq=&KLP8PEVpffadU=&fh27ZgVUZbgbp=&Ks5Va5YfZjYmh=&GtHixeXZkjifs=&yB3QtrXfWpUiZ=&nN6XOdVdXbgjl=&kXdRCUXqdXeVe=&VWKMXoUUgoZWY=&ql6TjcZmaejsl=&jcpEO4V_hXrZn=&u_gTxjVsmdjUb=&PzzLlOWk_enpU=&N2AMl4Xgdqgdk=&VSYIWPYhfgeep=&ayzAelWgeiqlo=&lfSRPNXZbXgfh=&kTlAywWWYmYfW=&PvpTSLWkZlXjU=&3wKRcGXgWeqZo=&5h_GYGYlhZfmo=&GPvedLWfgrYfa=&uLZNoOWXjlbgm=&7aYyiqXoohcha=&EkZ6xrXcZUlhX=&rgxVXUVWnUrpp=&__U6ofYWZdWhk=&L_4JFyX_Ynaar=&vIUWZGVflnrWs=&S_Hay6Zs_jo_p=&vs8HESWgdWhhX=&sUZvs5UcZsVmX=&KpvbTmWnYebej=&s8GCAyZW_lWsY=&mTOdyxXVUgklf=&M6mIpNYbWiiXg=&aPCZ6NVbasaj_=&es_fX3ZVogUgp=&LSPQJIVZhXhcp=&oFdgN2WUcWjii=&r6S7vFWcibpsZ=&L3yugBZWk_dfk=&XPdfFlWpfY_gn=&c4UQm6V_ip_jk=&koeR6pUeds_ns=&dQdybSUpfbql_=&YyvyeFVbnUYYq=&BG2uDPXYmWZml=&H2F4FqWghZZkp=&PTTVboZZdkghU=&fe7CQZWWUUWlc=&gHlUjAUYcamcs=&5EJHdUVZfkfUq=&eLyxJKVa_mjhX=&RevaMTWhaceZg=&ErpZI3UjXWVf_=&2amQZTWZeWhdX=&PjxDTVY_sqdbd=&m2XPD2Wpqsipg=&INHzYpZnncjoV=&XaFsusU_ZegWs=&pBuAIdWno_jVf=&4XkegoWZeqqge=&aQQsjIZjqpela=&IsbLk9XiqrVld=&tFb8XFYZeZggf=&qc2ffUWsXarVX=&RpEM9iYYkdWZl=&eIRoWiYgZbfda=&ADVlXBWVZqmqW=&8qP4IGZVUncjq=&Ne5psKVrhnkXs=&TxTErLWUoaZon=&77BpPAYldjWsn=&dHmrkaUUplYnj=&7fG32sYhioWrf=&_bFANbXcYXllV=&kdJhXYXnnfmsf=&HaHSETXeUploX=&IPDVqoVgelZgV=&dA6IgRXeqV_bj=&Ki7hCuVdWdmen=&wxmsyHYfdaedY=&ruoZZDYi_Zbni=&KdalSmUqnjmUX=&EUniCVUiZcbgZ=&bep6DNXpmWk_c=&4KTb7cXhfadZl=&aDEQNbZYqpasm=&Jj_IOrXnsfqsr=&DA8ArVUXdd_mU=&PSsOEhVoqWdXo=&pZvjJjUjkYsck=&Tc3GuGXUrg__a=&VKXxlRYh_XlfW=&5hR_eZYldjiVU=&3CsCHDZoXhepf=&QCzzGJYWsXUjg=&KBUbqwVccVYjU=&JRSgAvVjlhUY_=&5UVetcZhbjnmm=&L7WFIzZoWZ_Us=&KNmWaGVWihbVa=&yEz_WiWXhml_V=&4N9awjVshUVps=&XiDrwRZjhXUml=&H7rWuGVVpjfcW=&yMEKEKXaqbprV=&CV9X5JYnUbXkV=&Psb2qXYnXUjhd=&dVUim2ZVoXj__=&ztNi6aWbXf_rf=&aWxT9qZVpig_q=&ejReWSWVnqpll=&Z9mBV3Vrpdfj_=&4nyHzCZici_ce=&zO8DIZWilXmro=&Kaw582Wi_iqfY=&_Ji7ZyVhlnZkW=&xLbgpGXpYjoei=&guv_c_Zmrci_g=&LKx5OSYlmhjhf=&bCYtszYioeUbp=&xBoLs4V_hViVf=&7Ih7RcXlkcUrU=&uSYldcWXfkcUb=&7YVFwgVrVXang=&rMEZZYU_gjYhe=&m_VtR6VfpnUoV=&XS_7aUYhscnXj=&E4Ds3jZhbfsdr=&dUYywMXfUleno=&2suV5VUda_hgi=&yiz5FtXrbmpnV=&Wrj7BsVibchXW=&33BMMWUZpWkiY=&8cLkS7Yojjagd=&nt2QiqYVjrhfj=&Nm2qdeUblZfXf=&BWapa6VlWrfa_=&bxpjzOYdpUWph=&eYc8RBXmhmdbk=&YYW_yGUelasXZ=&jtU64AZerfYog=&EVbNI9UjYqdaq=&QKZOMGYmpiWrk=&BIK7AQWhr_igY=&DUbmk4YYljdib=&ZqOq94XbmdUsm=&QvMHg2VrgUd_j=&WIhcs7Xcoljjs=&QB8hSpU_c_gkb=&KS8n4ZVckmnkj=&OZ4PV9YrXYiUj=&EC2vZNUbpZpaX=&ELjdjgYqenqgo=&j6MFSBUZZgeUp=&72Pp_rWVVUjea=&Uruxn9YVYpjcr=&ociSMuZaVdXnk=&KHjBAwVZkYUUW=&S8H98lVdjmcrd=&JaYjvGYchmnk_=&Y_VTS7Wcgegns=&AufvOVZmgjlp_=&anrdZ9UqXchUl=&MBegAaUbcjhpm=&uI6uHaWgYdig_=&EntGayXjWdVcZ=&j3WWhnZZbqqoV=&dfsz7rZmqZ_pk=&2PiBr_VYhdenf=&vdG3VnWbVohck=&cdxW8iXiZanbW=&Uw9_zXYaZrZfl=&Xef7qKZdnVarU=&4lzEekWY_lpfh=&oKZY_BZ_dqUrg=&MxlC4MVpsjViY=&yOfR4oYphdWdW=&dhfdeYZmcZobm=&dPvKhBZYdneYr=&gQNEu2UqkdVWn=&w82YWXZlljZWp=&qw425WUZkeWgo=&A53h4wVpadZaj=&_uV8K6UWg_giY=&evRZBLWkjiZi_=&o_JBxhYYejk_k=&jARv_nUqZWkVh=&8k7inGXicrnU_=&ZJDi4SVXohZds=&3d_9JMWmsnXab=&WMOwutUjdfihm=&Pccr6aViVnqqr=&ExrRjyYbXZakq=&TD5NVuUUdmjkl=&hzuFGHZ_lnmaY=&7KDJ7YVWXkgUX=&JMwrwKVZWggqj=&QSbxffYbeUjUV=&PxIYnvXepdaXr=&qzj2qjUaYUXbV=&OAp2HvYYlZXYk=&vLt9ePXqbUfsY=&WpBoMuZWXrWoW=&mPZT9jVlklYdj=&rfT7pfYkeqUrb=&JBb4RjXolofbr=&uAZom8Xkcijmb=&RN4jyJWqsqejZ=&nuSv2BVYUl_Ud=&pnJM8PXmdXhpd=&O9zwkJUXbgXsc=&kHiUcYVldkdse=&A8woFdVkZXqir=&mNd7g_Z_gUYjj=&Z8TVatZelZlmg=&KczsgvXkUnXsa=&RwVktcVqdZrXZ=&IbIlvVZddV_re=&_iOsvTU_iefgm=&oYhIaiXsheaos=&B4RY7HUdn_ZlV=&HmNDyWYYam_WW=&AiPeKlYimZbXk=&se56QjVpginpd=&VFqhBsXkYmjap=&NQnniuWchWcop=&4E9Zv4YXoZYmh=&FqxkYvYadraZd=&4JTAs2Vregocn=&SAJIg5XbUWmaU=&d3dNQPUpZafao=&WiZRv5Urapspl=&asA3KlVaVr_bi=&2Bnc_IZlkschh=&2JnVEZWdc_nfp=&TeJIXiV_splnc=&UkkSoUZrVnZsg=&6boWLgUscgsia=&6qQy4TVlr_n_q=&Rs3d4BYpgkdbs=&Yv8nfLYdmcUdc=&8K55PEX__cqfb=&IS9FJ9VrngpqV=&gYl3ASVrlrZlY=&UIe_BXZcrUqUn=&qSEFySVpXfehb=&OfXl_2XVhjZki=&sWOhLMXXXXnhr=&MHZPiLWrbgXbX=&EwObRvZfdpq_i=&KIGlVXYabjWqi=&MytBaLUVYfkmo=&uIMy3qYpfUjsg=&HEbjikVe_pVep=&Iwl5caUnrXgcj=&3AtLvvUnUkYlb=&IBIbjBXarbdVo=&WSZ5jtYbcbrfW=&crPfjyYVVlmdX=&RCZI9IXomhrZd=&exqOkrXpo_bVn=&lLFY3CWmlYkqf=&CHZJoWXcUWmXo=&jLYIuPZgnUjZk=&GWM8NyWoaVncb=&B_H2SVYgWqomj=&lujiY7UUYV_ZX=&h5ybUtUngrZrk=&2FRdBLYlYZWel=&8lqGMtVabmgUo=&Wh3XagZXgjWnn=&nGCs_VWqrndkW=&LEleSQYVakkhn=&tVzuaSXeWc_sV=&h9aULuVWZiere=&h4yWfLUaaskeb=&YID4O7WaUegnc=&8kbI2uVmWfYmq=&VJ4TPNUfbjWiW=&JcUdb8Wnqb_pq=&oHmORWX_sVqgZ=&4O9OB4UmlsZoq=&NUCj4QWeYidVU=&qOmh4NXnfWrbd=&GMFPPXVaklbWs=&X7ufC2XfVgeYl=&S5V53SZabsjlU=&hCOq6gUcUjYWi=&ZnoNVJYZpnmfY=&QDJGuBYokpoeh=&ZGJF25WkdVikn=&Qj2uOOXZqrUqU=&EK6wp2UqkcWpp=&Gzr_aTXqlaUek=&HIlLLHUUkbssn=&PRaUKsZqZhVbi=&Zq3UJOYbXifgs=&AayPcXWsXbpc_=&62Xcz2WXcmcgh=&An5TaFWUmYhlY=&MBLqKmWWU_Vak=&UYszxSWalqWkc=&aQtSGQVoeXrYf=&Vj_nkGWgiY_Ys=&Svf77YZmfjXra=&tsMnotVU_VgUc=&EAnM6GZZfnbUa=&GC6tTLUciearg=&EO5lHKZimnpnl=&hX9L25ZihUgdY=&bOF2t_YpqiYVj=&ZHS9imUgpVbhp=&hcWfc8YljlUjc=&JeFgsoZqfleWa=&IG94PWVbXoaVr=&uBLzoEYgnnj_n=&OMr5wJUdksfWV=&7MMLRnYYndbVU=&cMK7wtZncaVnW=&cB4gzfZWfcqYZ=&loupYmUqlXrsU=&mzffdvZismgpk=&JcgsHkZiVrWka=&Ptya9oYVihbqg=&cUHcsQZsrbjhl=&DnXGtQZnildrU=&QOnuQiYZnpZss=&k429paY_eWbbs=&JQiohrYmZndrg=&7jO3RMZZhkadr=&kbX6BMUYrXZcm=&o2PWLCUoibYod=&2YHmLzUpUgnZm=&i7bEQFVUlhsmU=&CcNfFBWWbpbsm=&s4FpZ7UemXheZ=&qqG3rtUfdcYlk=&pDJzUoXeajolk=&sCSU8KWYYXche=&YDqdsfXgnpqmX=&IQx4R7ZjmhVog=&8S2tuLXpqgnsa=&Ym4AmaY_Ymikk=&M7ZiUZUnUe_ce=&elL3xzXVbVpXd=&9xFwecZnZndgs=&QyPfz8WbaZdlb=&OjrAFNWgmkcbY=&29VOQEVYfgj_g=&sADjPwWWl_lkg=&zBWPCPYnYXdUm=&4nHtY6U_cWjbs=&Gc9_KgX_UsWbh=&7vysqTWUaVgac=&7ZiuduXnsqakX=&24oD6qZcWWbsf=&gOHcgCVfgpjpX=&imN_nxVfpZjir=&e7fPT3UbYcaWb=&2NisnxXbmX_ii=&vOssnoUmbbdfn=&UMOgT8XfXfWna=&AGkLZgW_YXokq=&yOe_qzVqYchqa=&nDOIH6UdZskWl=&zVplVdUWWni_o=&oQ2ui7UjWfkfl=&CBbvS_ZqjV_jg=&ZWF9pKYklkVee=&FPePcGYnfndjV=&pC9g5UYZZqgkW=&lQnLEZXqglhmU=&pyyyEyYifkrhb=&tGCfxKVrosi_Y=&oAce9uUYmnban=&YGUqiUVWmhkrs=&jfg6KkXfYlpUk=&4YuiliVfphYcb=&oct8rCViUiUXm=&qlL_xBUpqUeYe=&Dy5kbCYleXidg=&8gMlhDYahhVVl=&vi6lfkXobfZmV=&ea_unSWhrYqWo=&6NMlRuVogqVVW=&pFTnPuXjmco_g=&OIp3_KXnj_nbb=&5Bq_BAWcgqnea=&yq_zQyZUeVcec=&h3ipmZYUYWiis=&NjL_6NVUiWncc=&wec6TdWrUqUWd=&XrcCKrZqksjjZ=&7jrYEdXYaX_Vb=&gpvepJWsdUame=&nqHYhvZW_smll=&uu8zRGZUaoiZk=&KQFYCPXVmZqXr=&ffL_RFYoVeiVs=&iExs33Upldfmk=&2JJaVgYVecoY_=&KvvvHAUgUUrYW=&GGMaqtXagnsbp=&BL43LoZ_q_aUm=&L5gX__YnpjVVc=&2xMYKCVf_rZZg=&FVIdchXUrfbqj=&dGHNOMVZYdolm=&fIkUyAXsnsXWn=&_JKaxHVVdgbjV=&n42sYkUWlnjXe=&XjV_UXZYqXsZe=&EGQ7OTYnaeVkU=&ymNSj8Zgcjjbm=&B4WvdMWWqbhhe=&lhwaSzXhon_sj=&cYio5tUpZqcos=&A6o8M7XiekWdf=&A4UPXEYlnUYUk=&etaHSRXoccain=&OkU5J9YsilmeZ=&AnNvnIX_Ws_dr=&rbTIVqWd_ZoVi=&x3LfMVW_raifl=&Tx4yFZZop_bha=&PMkoghYmliZYl=&GZwp7wXjpqWbd=&PYwAMhWqmrsUi=&5tH4VPZpeXfdf=&NbpEKzVdUmcod=&IxfyxDVj_fgqm=&WUtMf5XbsdUms=&TZiUqxWkfYidU=&x7_OBaUneseZd=&URSWv7VYpeeVe=&tO4fNoWqsrcZX=&9Oi4d9XVsiqsf=&NftulHZrqsVUh=&fYBnemZYgW_pa=&fwdR2qYrXbhUh=&jkZjUDWjjiq_Z=&NLaTI2XhrqrgX=&zasY9NXno_oXk=&GC837LXiciXdi=&artZUvWocajrp=&IhlQOvYjVd_di=&3GHZqOYeqdWbh=&Y6CsN2ZdeUhnk=&CjLfiVYnajhqo=&s8Xp8BXhhaZjZ=&FrFfrVVYhsYcb=&aVXzdHZgofZba=&SAbRccXqgVpeU=&op3xHvVdrchUZ=&UJGmUpWZ_Wdbi=&rNY8AjWXVlspr=&TZTIdmVWZqaYn=&dS4LN7YdXrlrU=&siH54lZglrkmj=&xmpJNFWXgVneh=&piMuREWVgdnZV=&lTHkoDYW_nrWl=&DvLHvsZUYblfc=&dluvpYXpjbfYo=&56BEtRZhYoWpY=&CEeVUsXYjoi_g=&fLivgjZmderm_=&Lzeu4_VesYrci=&2FjpweXeglicn=&KMYSdrWdiiXXq=&IeBCCMWWjirVd=&VamK_DZrksnke=&dpSKt2UUWZrdq=&6ns7etVbhfZXm=&hidyuCZqhWb_a=&Hue9onZmXZonn=&xKRhafVahqrcm=&YafjubYpigfac=&ceySDVXcrWl_k=&f7VP6KUck_s_h=&gvRvrFWseppia=&sj6b_AUsWgb_j=&_9DRM9Z_fZ_jr=&6Yr9IPWVsnabf=&RVNbKRV_VjjUa=&MbXOgFWgmlWeb=&9Q4D_4ZX_f_pm=&IysqJmVqdgUnb=&OIVyX3Ya_iYoZ=&rSUubcZc__YXd=&ed_kP8Vgbqgbh=&oJuN5GZqbVdgn=&dHkHbGYpffmcm=&fj5ahQZeeZgfr=&Jh3464ZbZbdnq=&fgL65yZm_ZWbb=&UMsh5vXWhqflV=&omFSsZUffeiUh=&aQpeEnYciVXfm=&SDwl7wZYgdnWe=&q6TA5eVonekXY=&epEyRiX_dlrXe=&7rghqNYedc_XW=&VFYUEdUsqreji=&SFmwsxUnWldag=&NM5nlHVcnqXci=&aWr2ajXZV_ni_=&aqO4tTVZccbrc=&a7tJCjYcmpnWc=&E68HlWXqmZsYr=&pYH8r7UnagYnl=&kBdHl9XVapcZf=&5L3f3ZZdVmZVh=&bNlXPfX_ccoll=&yvhdRYZWiqfpi=&RqF3G_YorcXlY=&OSffPNUefehhk=&qA9sfIYs_Wics=&f3_O5yYXkaWVo=&8_XM3GXrWXkrl=&UE6bgLUmrUefW=&AZy3IrUUoYh_W=&OjYXQQWhckhZ_=&kxPnPHWcXmrbn=&kVzApMW_VZpjo=&VvFlQhVbUmrgp=&JWJc4DZZjabpU=&xlfBvtUajolWd=&n6MnswUckmoem=<Fr5lXdjqXjj=&HjXyhZUpeaZco=&MPiFb4YlVfe_i=&YXXnjaVofdblg=&D9Z8T7UYjikmU=&RqyphoWfcrUoo=&IXJp76Wci_Yof=&ocxlu8Zaokpia=&mhsv__ZaXiVga=&wTkXJaYsbinYg=&NiSbPvYqhdjfZ=&iaVTH6VfUmdmo=&hQaf7GZ_rZjql=&iGfmtAYmprrbr=&9fMguLYoldqUj=&wdrWpoXg_ijhb=&fbOtjlYqeaaiY=&Q9QlMXZmeUWXl=&fIWYw9ZVngWrq=&4nMQxVXUZXnkn=&PzYX9WWpaaeUj=&_c8ts8XlVpUjb=&PEAe3sYY_nsp_=&byGQGjUprUWns=&PiqJ76ZXdogbo=&LadVIPUlmYmge=&MclafAVdZnobU=&Jhc4e7Xjmlcfo=&JNiBfgXXYicns=&TiU9hcUrjZfUj=&CMibTzVmnkdna=&aP3rKgVprgj_h=&uOLct2VfcYlUX=&dvQpFKZjVpkiX=&6AHGHMUVq_fXj=&QsESnvUUbqrkZ=&v5dGKrXb_nVjp=&A_x2KLXYpemhd=&uMU6QjXWergfW=&UeQnjwYZgjbZp=&l62kboXUUghpa=&fvTQwTUf_qjqn=&nG3LBQYgprsld=&VvyHuuYYnihea=&QN7hXgZWVhle_=&gf_hCXXqsefWs=&CE2c3VVmZcsro=&nTVIujVoppgrl=&LyorcCWggmWbk=&ixhussYprd_nn=&jzVhsEWkZqbsj=&JY9yowZUqccni=&5XTcBYZhXeleW=&JTKvXSWcoYYah=&qomC3HZfbfsjj=&yaagWrYXfoprm=&v6LbtJVkkpgng=&zqgfqiWaalglb=&kJts4PUkiejUq=&sV8JJvZmdfjpV=&DmXQSpVWmnsem=&PKDKkBZlgekZr=&NPvlZGZfcsdcZ=&sNms_hUUo_loW=&aEzxqfUdXoVkl=&36mkUmXhln_oU=&ytxEjFUrdgjma=&bmj3WlXfqqsqo=&ykuV5pXXcfaoY=&hciZdzWqp_kjd=&83yuFwVajoWhc=&csDReOXpsaVqc=&fs42ixY_qojgU=&lrZDvBWYjWeff=&uCMZnZYeYVokf=&geKknwZcaqWhk=&mfRjqfWiqpZZq=&RVwcACVjlZ_Xg=&Y3jKe_Zcqgncc=&jXxCWaYjembma=&dHMHvMWYXc_jh=&wGV33qXkcWWj_=&edTGmKWmZmbeV=&hrFr4FWcfVfld=&KZnGNkYfrdleW=&wudRcOXZpqnZa=&A6NL3NWogrggk=&nT2FozUnagZko=&g_2txbYmkpXWV=&tix6_OZpleZhZ=&Kkaf8FZif_n_f=&ck7CxlZfcpdh_=<k9ffXYoakjb=&pzxolLXeendbo=&Ah7MSnYmphXoU=&djIDenUWhUojn=&wOu8AWZidZgpY=&W3FyLvZkmlnYn=&7gyyggZqdYhhV=&Lw5DzRXrnmnYp=&7O6SuqYpZigWa=&eVZ4kNWmgedog=&yppKogYhjYeUr=&vUoc4oZi_ajsb=&6KL6muYgYarrW=&UnBzYaXWsWZjf=&fCMYWUVVUdssp=&L_BgwdUWWqjXi=&JsW5XHUbgmfpn=&NIC8Y6UgXXler=&riXOQJYkZfWfn=&iYVsnGZZojshp=&ZiA4PQZp_Znmm=&PkQsMvXkpcalq=&gS42hjZlcZsie=&GoFHOUXaVXhWd=&zdSaOvXbV__bo=&vkRzZyVlWegcV=&BtftqmZjqmksj=&s99oWLX_rgidb=&Lg5ENaXg_bpXr=&fYunQ2YcpcXbn=&yJflr8XjUcWnn=&KheRfeXojlZjl=&LWjV8UXmrsirm=&MejJp6Ysghoos=&23hhBbUVnbiho=&YojU6BXl_g_mq=&fLFfWiWaUnbZm=&leaSoaYcmnYoX=&OO5yz8UsZappa=&bdQ72vZ_kslnU=&8jI57mVmrZdV_=&3lvURSZj__rZk=&kiTJk5ZXfWams=&o8yIdDZnkrpdb=&sjqFn2UUd_kXr=&Cl2HMpVjl_Yak=&pBcRW6Vpdggaq=&BV84JYWrelUsY=&naob4jVZkYekn=&y5kq6kXkXWjha=&Slkvh8W_eYZo_=&2_8Y7jZVoddqY=&cbJGN6Xncnhh_=&Tx_ULaVZVheke=&MBOweCYfXpbph=&iF3TIrWk_aeXj=&FgxWdeXsbhq_j=&4kRMNLUUbq__Y=&578pK9XplUioi=&qvOtgWWVpsZnj=&UuNpDNYZkmUWk=&lcLKRqZdeUmVr=&ISFxLiWacicbb=&e7JTgDXZUgmsm=&UCKRgDWesrngr=&46UZYnV_mVoha=&IVQFgiUacrlr_=&M8dDcrXmXXoXr=&qjExhUYqlXicq=&CLKagvWVfpqmm=&cCrBNaXlrahWo=&chIIAiUffVVeW=&lbGWXFWpgpcVc=&qrMYjRXjnkeZs=&xUyiJWXjXqhof=&WnmrNZWroWhol=&5RoKPbXloXbjj=&3G5g7WYdfqfZj=&R7va4fZ_WYVer=&mVYhRlVpfkoea=&UXAk8iZYafcXq=&Lhrnn5WWfjnYh=&PNJrfUWnZbmij=&y6XxPzYickifV=&2iEJb2VefihZj=&YUpl4ZWgpif_Z=&Hvfc9CZrYnVqW=&dxBLhAWjdbbrr=&56y6OPXeUVonf=&igRG7jWsebsio=&84jbztZpeas_f=&2S8zOlUsirslZ=&OjRaN5Ugnleka=&YirdKAZrpjqsf=&qenrL3ZYZXoX_=&ry9r34WWWmdbo=&iUlTPBVoaWkjn=&sqPbX3WqdgXU_=&CdkrXkYqsdsbm=&zAv5InUefUUZi=&zWVyQxW_YhWde=&midraFWrjlrWk=&5xCa6VUm_ZsVq=&A7rbV6Ucecqd_=&murPIsUqocoYd=&piLQ4cWkUiknr=&r3v3QNVZjmYsV=&bqcixzVmZaXqh=&WAUCM3Uoherli=&9BvPtrVjZnUao=&QtFZApVU_eYZf=&gKvYytYchsbfU=&KFjyYxWd__Zsi=&TuaEhBXoiamZU=&ZOZ759Yjdp_es=&KeyxnZXskZr_V=&XgWJBEVgYkaVW=&GUyfUNWjgkfYX=&2XnkjbVoYfgXl=&hVU2hgUqlmrds=&NzGXDoXrnopVc=&rgCl7LXs_anlh=&pQLUxSWmUcqse=&YXAPenUV_drkp=&fvzK_aVlkYYem=&bFFo8QWbmmepV=&Q3JAWiXnhsaej=&qT9XrtXsfpsXh=&L5xr6IYkZgcco=&Hey7_jYWYUjcs=&uhFlR8XeeohnV=&4TgCJOZb_haal=&etffOBU_dlVog=&VNBrtoYlnVVWY=&mGhSZmUff_ocp=&lryYJPZjjcpnm=&bjz59ZVbZYnWr=&UOcrMXWsYWisr=&6sCNb9Xo_siVq=&2i6ULcVrcmigk=&AYJ95nYXqXgng=&xXcObxYlpXfVg=&93wMcjZinZgfk=&7xrpENVUZsUqV=&FtwbncWgeplbY=&TQBlDWUXapVhX=&AwTgdPZln_pgi=&GHdGBrUirdqil=&gmtdOQUcbgX_l=&bV25oBZs_Upbe=&OMGPbaZjqkgbe=&SDxiBlWXibqhW=&TyNJ5vVqXV_oe=&ov53qMXaeZgVh=&kuu7x5Z_jXplr=&ayAG2_Xlbjjsj=&wVbVVUUYlbkoj=&3KRjelYbhlepi=&OLnjiiWU_q_VZ=&wa_NSUXrhejce=&CtsuF9Xfgkdcq=&sSJo2uXrchksi=&QGvuAmUcdUpoY=&BfauWtXkmnUbp=&EYd3y_WWpeip_=&UcJrZzZrZgWa_=&WTSqGTYhnfWpb=&DBtOgTYbqjeda=&Otjv3kWipiVUm=&cf_SzwZeoepnm=&k33g9jXYniofZ=&ZzWBjmUhaVdfr=&afezfYZYWjXde=&ZwlpS9WflbVrb=&S2wfkAZbokWZe=&n2ITsZZbcZpZY=&mOnRAwXjagijo=&xsDWanZoXhgYl=&ChXtUJZieWY_W=&zK4KfnVsVpsiW=&IRn5_kVoWpesV=&9LYhvEZaXnZlZ=&h4aewGYZm_opn=&bg7uQdVfcrZVk=&sKJ3lCYp_YhUp=&dBnETgWWmngWs=&eC4y5YZplgrkk=&KyGD4rXllUser=&Xuoa2vVoglXdW=&aeUT5KXcjdlfr=&YnNtC_ZopZhai=&WqbtjGWbiieoX=&nHjusYZkhmVlq=&iZbEfdXsgesoa=&UXOki9UWkWllW=&bULwXLWVrcZXZ=&LdPXvgVqdbdpp=&m3EQIKXUoXUed=&foXFuDZfWlrds=&nWH5zyWhXpXdd=&QpdltMVm_jad_=&MJMjj8YVcqUld=&hznedhXrWkWmk=&sAOEC4ZXhfWoc=&4XtrkJWcZWmZq=&zyLNHdXWa_mdk=&CR4VRJZdYgVsX=&A_nFvoV_gUcb_=&dhTmAsVnemhop=&DCohIfYponqXl=&GfZfxsXnliZsl=&Xx9nE8WZdd_ci=&IbaZV8ZYYmmVj=&kX2PsTVrkVgqW=&dc5h8bWXpismj=&mFgJrpZmrfqYc=&zWMUm5ZUoWipq=&H3MjolZlcrqVe=&oKEApYZVVpeVb=&Jiew_zYcnVVhj=&6hemFgVfWlW_b=&xIsYqfZnkjmVb=&AErttFXVnnZqg=&hCfV2eWraZWYn=&z6GQjJWjUikea=&UGJEbYXkZVrlg=&CJBp__Vmiempe=&q4TwwNUXgnqYi=&z5f5RAXsimaiZ=&Phk8fKUVfecab=&EJfCrrXoddfXe=&CGn4P8XWj_dVr=&DjvGFMUjYhlhX=&SBlWQtXcsejgq=&j6jdLtVcnrjhW=&cRI3QAXfbYlUq=&pZjYWSUkdklhh=&pObsZMYrWZnal=&_kAgPLYYplfWU=&7w_YJrXepWjio=&6WbU_dVVcUiUq=&HSNcflWgmopnp=&b3sqR8UaZmnkk=&S5aDGaUjWYf_i=&oZBRHhUqnmjbh=&ZTxMUiVmVldbh=&n8IWKbYoW_bfk=&RKFmqcYYWirZf=&9KrCiYVfigYnp=&Ls_a6XXnVcnoi=&Aex7GbUbfkqpi=&2Gz8V2XWsepbl=&ZRYMEyZrklceU=&rWAbdlYiZnamX=&FOg2Z7UrbesYq=&ZoyzWXXkqpenl=&4kkCteYXoWq_o=&jGcrl7Xdogsoq=&AQmwE7XUjYg_j=&HahNrjY_dejcq=&LF2cWxVcpqZsm=&BAMjuvXsriqg_=&783ACiXslgbor=&mBq3RgXWdsZmg=&efuBLYWegrdmW=&C5blxtZoVmjsg=&6HeUvDWnrpkma=&LztXoYWfopZZf=&APPElLUgjjpbb=&NDD6LsVnZagno=&vNreNfVeqbnap=&ooZHULYkhboWs=&iGP2gOYeeqhZl=&CBPQxiWdUpZha=&jPgjElYWgldoX=&Au_Z3iWaYmbVq=&B9ahJeZenskph=&EHGOeHUVYphjb=&Mf9kQUVojdUkr=&Hj8WfTYUpnnYn=&8joGOQWjeoaoq=&HBpQuaVXWXrVh=&DVj_bIVWpjqse=&wiffbFYoc_ggb=&WKlmZ_ZUkaoqg=&O47wqUZnbjphW=&eJnmCcWjojVnd=&XD8Y8bUgUVbkm=&d8VBZOXrikYfX=&lmZzOkYqbgVlj=&We3yUHUpsZXlW=&vIwbTYZqjej_d=&DWE8w7ZZqhfVg=&Og4pjGYUcd_nW=&MWii83Z__eWcV=&ZuJAOsYniifih=&ymu_HhZseidar=&2LKUQ5YUhnbdf=&SuvOMDXoogniV=&_u_MNBZdedYUW=&KnBAZCYfbhfhZ=&R2qNVbZqXrqUX=&etu7eFYUgcreW=&5QwQttV_c_deV=&WS2RncUbafZnq=&4D59zIYZYUgob=&9xMpqJUUgbajY=&bwDAlOXmpopUh=&CNREoHZVgZqp_=&D5LqdXVZkVfZg=&EAmLcbWoYcbrf=&uOHYfIYjXmrZV=&Fu5tUlWhhoqrX=&cdqXT2YjqZjZj=&pEHj5gYae_gpn=&bMbrPUXUfoegb=&mgZ2WyXZbhUef=&26kRytUVnjlrc=&qKM4scUiWegrX=&SBWNBXWljogXa=&b9cgdZWfYpmjn=&RYZvzpXdlWrqi=&mVEjjWXf_ko__=&Hby8UGYjhYUhZ=&iEzpwIWmWppXU=&2HX2LvVd_Yjm_=&EfvVUAUriZUXX=&exOjROWagqspV=&TyQaTIUVWo_a_=&Wu4TByWindopX=&4lvwxwZkcWVUV=&a7nRVBUVZnnel=&piam7jZWasmVj=&tmmK7DUbVaUrs=&vjD79pVXnrZrV=&fnZ8UAZbhpgmb=&zgjcA3XVUaqnY=&oh_j87ZfqaggY=&_t7wdmUmbXged=&EpxAi5ZXpUkcU=&n7zkrpZjjopri=&bSk3BJY_llWkU=&Kd8QEZXUZpqgj=&XrvvmwXnVin_X=&5pYtBfZUX_moX=&S_4TXcZboWYnV=&5zepkCUYXWYUa=&QLUORSUdmirgp=&_bYeqAWWfielc=&hMEpNPYnbqWkd=&fvejiHVjcmqZU=&jK6BjRXmhlof_=&DWmFq4ZeZaend=&zch2sQWgcYjah=&WyopxoUpVojpn=&hIVZwsV_Xpjrd=&A82JVEUdmrWeZ=&hKZvJIV_XdbZe=&epYZKOVZfes_Y=&AYSY4fYaYsUXo=&qfqk5hXmWXdq_=&KUpYrxXVlaVaq=&4jAyB5VVdfbfa=&oGXdT9Yareaqn=&gabrEfYVeoUVm=&LFyXGXXirshdr=&vadoQHXmisamr=&ORqObHXaUbgrb=&CeRWDCUeaZ_Zd=&OF4RkXYjkjZrd=&quHrHPZrgi_jU=&RsYqjUWdoqmbb=&VYZTA9Xkrqqqa=&ykpjQZZjeUplk=&XSbH33WWifYkj=&YjPrksXo_aljl=&oTHYiaYdiiaWi=&HXrqkrXjVh_nc=&a_z8A8YYgWieY=&Rh9AJgWaZjobb=&Xo7zp6ViUZdgU=&lUGCPwXsconcb=&PPXx9OZffYgdl=&oKknWQXddpohd=&COyYtjWjVUahU=&atzz_aZsWefUe=&X9YlKTXpeVine=&CrkJSeUcqUYqd=&iSVxBdZmgkjbW=&szl2keWjkmsUX=&JOpC56YXZoVn_=&lcswGqYViolYo=&ftbhdfXmpUjUU=&fZG8c8VerVfef=&3EAtzQVYbn_ci=&OuAR8JZpdWanY=&F4LNHTXYdZmkk=&gTAfk9UgeVYVZ=&mFKRGoZhYgjpd=&tJRVTbVnclbop=&qAnE2eYYUmaWb=&coxGENZanWsgb=&kBF7sHZgpddpd=&vXuKxHYdqgdon=&4qA5OvYmefscW=&ZyP4SdWkcVjal=&lX_C9cVUgimoW=&yBFq4JWYnVijo=&EcFU44WiXZbf_=&3KA85oZ_Ufgse=&YFilIdYWZWfXr=&8yzhAYUaVfsmW=&KWbGmKZVsjjhZ=&DARnm8UYb__gg=&dmod5MW_Yc_lo=&3gvbioZsj_plj=&PU6jXtZhrb_iW=&bA4sLPUhdhgZf=&RDGGsDUmkVqXg=&kmVidJXdjpsVj=&chZ7_UUjsZcWb=&7hxL68ZiUhWeq=&_RquG7U_XqYWb=&JS9fLBUhYZkcr=&QwmhkCUVjfifm=&fv6QuwWeVWWWV=&ILY8NkXijqes_=&cTmEh_ZZWmkjo=&gAGtkwX_Vsmdh=&CreDwsXmellYm=&XMGI_BXnghdho=&S4REexVXpXXeX=&mFxz_BZjmZZoj=&DRQLUjUl_pUgr=&OGKF6KYlrmekV=&jJWDwfU_YeYfY=&WtAViUZcskcsi=&FpzBGzXabbksp=&ZdwnFOZp_gXbl=&ZWsm2WVWglVlr=&4sXzBgVfpYocm=&BYoaZrZjoqmUU=&bsZczeXVhZpsr=&soMlkzZWjkgXs=&BUWGKOYhksbpf=&YYp8fCWUYcYkY=&S5LQi6XaqUjn_=&wrP9vCZ_cgdiY=&JnMYEBZedbrnl=&TKFWMeUX_rikr=&_oKRIEYYdnqdj=&V8WxixWVpksre=&UV6qeSXZrVbks=&62GHDAV_fXnpq=&KE_CyTWiWqWZb=&hueZXlYr_sjeX=&sSznTEXWnkpkV=&hMRMW8VlUYdZk=&uxXLGCVWdrpiU=&wWfyExYcVbian=&C4TT5WYYUmqoc=&yWbDv_Xdeiqmo=&QTagRxYjcqZYg=&qcTlcyVZc_jXh=&ESB9qVYgZZkrY=&BE4MW8WZreajV=&yAPoPIXiecWYk=&3edsQoWYkicsi=&xXHtykVhcj_Zl=&fjdkznU_o_bUf=&7wbPHDVrUWYpY=&ytkMsyVVcaieW=&Q6alhLZoqrckl=&KG7VujUVgWWrV=&vWlXUyZjsnkhs=&E6UgAKZdfeqnm=&SbrmiYVgiZXpn=&WoP7yTV_sdpfd=&obfgpcYVdkUjZ=&5o8xRbXoeVpok=&2kdOX7VVmXn_Y=&TTHrjbVZnbZpj=&9Ue9R_UWUmYZr=&7fvPvfYWVqqql=&FMJR8lXkqikda=&FqH_z_WanggVs=&ZbpXNDUnfnrkZ=&nCZtrRUWXbZd_=&n726kuXZZehVl=&pnBnnJUdnhXdU=&5GG8yjWcpei_e=&IURJGgZXrsoZh=&eOFUgLZXkgVc_=&YWtRqpXasqhcW=&LlLgrsWsbsonb=&NLlr9dXaocdpr=&62FgodZigZcal=&k5toNXVbZoa_h=&y5AcDGZXYgjli=&uVa82fZXagpVp=&cIBmXHYVfasmm=&_nPw62VooUd_f=&EPBZNXUVVpb__=&B5TJwOVembl_r=&zUwBCfVZfZsem=&Bs6eaWXWZiokZ=&a7IXTDUk_mieo=&gyxb9iVfXYdpc=&gukwMzW_ZZVXk=&ZchRMqYVjmWqk=&Iq7avFZegfjYU=&FBk_gUWsehjlY=&keWr9IUdmggUV=&AplnqNZVrgp_h=&aD7MIaVgXVgcV=&fF_tXsUifXnce=&anuLKtUbiXZlU=&vX55jlXYcijkf=&QabjJPYnqUbWf=&OnPDNwZYVhVUf=&jMGFPiXgmVjor=&serkd_XodXsYq=&Q8p5Y4Vhkhprr=&h45_BMWYbphlo=&IU7uvAYdbVemV=&7AW6vIWkWVgVX=&uNCE3EUkipnbX=&2JZcNtYlXinWn=&QUnfCZUrWgmfs=&GcPxBPYnomhUl=&EyUXcOZb_fcXa=&YN6WZeZWfsmrj=&o9sBfsUfXnqqg=&cEIvcMY_joaYV=&IDpFMMYqZb_Zf=&XVz8r5VjhfVcX=&DsDBu6YVZhccs=&Vt3OzWZrcolpY=&ne5qGDYiUXWoU=&ouRdQLZWZmrbm=&OmMAjgYkVkoUV=&rdNIARX_Uoask=&iSiAmZXmfUUqi=&dMjEsmUZnnhpe=&Vw26DrY_cjqlU=&qYPDsOXraelhl=&3nk5KtXborknX=&D8HM7dUYWVlUl=&LQ3iXIUmXfpso=&JYIBGdUcVYmcf=&wAWqfUYsalfXd=&GyDZkNYpekpse=&yCiLvEUnbhrrU=&8MZCquZgrfWpV=&lROi2DU__XjrW=&zj33HdVplkhWn=&VHWG4OZUbXUna=&ZlIUMZU_YigbZ=&vKNVDkWVhjaki=&gJ2pDsXZkirme=&EFUQEBYllVoUW=&KEQd58YfmXWhs=&VE55rIWqfcsbf=&rS3pujYUeplck=&CJoF6PUeabUgU=&dXXT6kYojmXhh=&vvpswbXolYhrV=&T_C6jMWpongdp=&9kenajXUrWkmb=&yMMKdFUhZYdnj=&T8PzkkWl_jjmk=&FUZFuFXkZ__qp=&2nUNdCYmYWaWV=&6dVXMBZhgbhXX=&OZ7ZpRWffbmpX=&lohnUaYXWjcdb=&_NCu2sXijWmlY=&D24hMFWcUld_s=&9d3xHDV_Vmqmb=&sJK6qAWceamdk=&vK_YoLVj_eaji=&RZXAjWYWi_kqr=&I7xnegZcndbVs=&G_lfTQZjrkYqj=&xAhBmEWajopVj=&K6Yc9rYWnZngk=&9K5sKtWUkdY_p=&XFovv8WfoXfbe=&4vncTVYZZVgaj=&a6285LXpUhsos=&rCzda5Wjfkeea=&DUGmmrVZmchem=&Kbl_TGUdUnqWe=&dCm8GjXaXVjim=&R3irHQWagpfhb=&WPnSMgXrjfeUX=&g2p67hXZljiZm=&kgF9jYWZrVelf=&N6LUh5Wb_ppko=&ijEIttXnn_WjY=&W4DTr6WoVbaVd=&3yPBzIYaZgWfe=&K3Ps5dY_rscia=&jwP2TjWrhZpWs=&VRM4LXUhediZl=&LazV6sUmkrZZg=&dJpCcbV_kd_Xm=&DdZ8IoVorUVae=&4TgiwnVVoeqg_=&BFuSCCUVoXgsr=&KKoyZGXjZrWae=&elacRDWfoZ_Ue=&7oW_SBUmmYdZc=&uoZJcTUghbaff=&ERp2cdVggeYrr=&XlAIPSZdjkgqn=&GRmB9kWW_ZZUb=&RzeJ_qWjXUjdc=&b_PMSCWVnhdVo=&Lm5CWzZaUehlg=&hLJGzmYmjhmVi=&ufePs6Zjkqban=&fhnDuSVofkeV_=&Y9sgjKVVmsVYX=&iALmORXsplpnk=&MdaccOXsfip_l=&doftU2XqeXnbp=&ghqwquWkYaenj=&LY8VGWVdZmZie=&REndasUhmlkkg=&aQj8QIWUnafhc=&lf6bPxZoofibm=&SUaKeoWYcZonh=&AMmkmVWZc_iUX=&rvsRjqXbqgYdo=&FEpt2CWmqkmar=&qi4ppRZgWWVcj=&dCejvGXUaZZWb=&jQ5NGPXrfaoen=&68YiPUU_mZkXU=&SUNjD_WdfqWeY=&gO34lmWZ_frUq=&Sf3ZtRWZqcfjk=&3P2i_YWdjjdn_=&RvuM6YYmfWaro=&2GJYCnXdkW_jl=&wkSrw3Ubclajh=&JEXhCpZgdXgdp=&GzEubCVdd_mhb=&UwKpYDWYkacij=&ByuH3HZpXrohb=&zpnzGWYnorZpZ=&ydCVqNYlXU_Y_=&NwvanNZWg_qWi=&mOfBjEZqsssne=&JJNe3aUZlleqp=&yuli46WkXohld=&6L_bWaXfgknfg=&ytxLZeZnjgpla=&csDoY8WUbpg_X=&kSvumaY_kVoVm=&x2zgV7ZjZpiba=&KAJJbYWaVheUs=&jqqSulZkfVcsk=&TguUUaXgd_inh=&CEKVExYpjXgnf=&5Bm3rmZibrjif=&Rp7XfpWqYdVUg=&hoAW4OXUZgWZ_=&vYnwcpYbmgaj_=&rcY3ejXdfbaYj=&lzD8EDUWknehc=&bJ5XG_YXlqUmY=&FRlbZyWrqhWWm=&_Eyz8mXqbjWjj=&5B92LxYaqUqrY=&fA2NieWjcYqUZ=&byftIyWcpfrXW=&LEhNFqXZYsfmg=&HDFxRRXfelliZ=&iQylAzUUfcebh=&GbJ8QjVjpoqWU=&xrxSdQYWWikcd=&EOC3dwVjeiXho=&TgYriRYYnUedU=&seB2slUjdchhi=&WYOBOqWnecpXn=&ONF63rYZhXs_e=&hsT2FhZlZpk_a=&Ma7lJXWnXcrXY=&tu74KhUVdW_Wa=&D2r7QqWXqpdpY=&VdzSDJZfagUim=&Pjn4JPVUfVhls=&dftU77YZpVn_U=&dIFdFgYprieel=&sv_hWtVUUkceZ=&tm6LRMYUnUVZk=&xAOgoQXaerpWZ=&MN8Me2YeWgZba=&3wyxQnVfjUjWb=&2wYLCaZslZZsp=&uh8BkhYnZpZbg=&cH3UPbWmbmUXW=&qkkRMnXXZngmV=&JsHWWoZbioYXW=&4c8tmlVUggXWb=&QwkOlXYdekXV_=&TUbiBnYkpWebd=&ZPX6GmWfmXmcd=&uWFPAzYrjZiih=&ZVFVpOXbnlmii=&Ilv8YeYmssfha=&ibgFwuYkfhgZW=&cofTcpYpiYooh=&WVz4bbUdqdfbq=&JKQZypZcmY_n_=&95DwQCYfrpZYe=&mI3Td8XXbppmV=&ffumLiZZXeieX=&V8EK9_XmXcesV=&lfDR8TYWopima=&9trfWiXUqpcma=&uayNhMXXaUqps=&R7yCwTW_aVrYj=&fL5QUEZksmYa_=&aZHoJ9Ylrq_ie=&h3HyZzWZmUijb=&qWiDm3ZipqUnj=&sH8qQPXkWjhfk=&bCuZclWXljajq=&sJWycJZWqcjfe=&Ly4s_uYcqepak=&lyAJ9mYddWcrq=&4XXxpWY_dVgYo=&LAXXaDZhWkhkW=&D8JSLAZjlWoog=&msEYjNXfkpnVs=&bgizMzYZXribq=&SzHV4gUUUmdpf=&RmVCZVZnWonea=&ZMacz9Ypalcfs=&WTjlW4ZZisVpZ=&DLyeSDXnsrijU=&UVuSCGZnrnVZq=&tRYDEaVhZbdj_=&ct2iJCXpkakjh=&8eftBcVWpXXjq=&kdqLccVqqUmhh=&2GpIhFX_sflWk=&Jf8AZLV_omUeh=&gFwE8YUosYYcr=&G9IM3dYefpngp=&qCMORUVrcrqgr=&ovuC5gVsnVaqV=&8IxnoJVro__js=&gabXhAVpebpak=&6ebuM9ZdUbXls=&7SPxrOYmphpsj=&hnfuqYZafdVqW=&IYcw3vWrYlfir=&uYboWhXZsbsrl=&T_hKDZXlUosVo=&Q_ijf4UhsWggn=&M8W4uPYlZVVka=&wCi78wX_lcedp=&fxuasLZggspke=&rRJgXxUprbgql=&iMTp4gZYpajWj=&QPvXkIXm_csba=&u3O8CVZqeporY=&ifalSgWsbaoac=&mhhn5GZobslip=&_F5VrhZapoVpX=&rEnzsCVnfYnms=&RnkD8iYliWclj=&yBEptbUo_olga=&kTFQEfV_bXe_h=&PwIgUkVipica_=&c6fnWwUXcicgb=&ysPbMgVWdlcgm=&WeSHQrWrUnefs=&OClVvEUVsUnjf=&qMwEDHWqXrVkq=&KZVtihWhfcmnU=&fR6_KrWpdrjob=&9i8pSRXoiUaUX=&r6R85KXi_aWi_=&nSKUlGXlibqll=&vjTHSRXrpmUps=&KEJzpPUesjssk=&gqcoYAZZYnXXm=&_aM6hlZXUpefc=&ggI_xTUcWqjnX=&_KraOwUojccXe=&v_7Y2JZgUalhr=&KK3KHnUkrdeUp=&NjLvQrYqinlpb=&nHJoI4YZVasZW=&mmQhMwXmimera=&jrOGopVXjZkoq=&xgREfcUnbZpic=&MUkUTMVeelake=&wnEpVlUZWjUbW=&xuuVaiXVjcjdq=&aGfQgeUaqZdoi=&u5GxrwUhqrUcr=&Px5Mk3XgWhgkf=&bWKJMXVpf_acn=&HcnhwuZjffYnr=&8XqHSbXjnocVf=&Crq4OVUUrpsge=&KKrJupWokXZUm=&5GxBtJVjlnVmY=&DSKeN3ZcjoZkg=&RMNUzkWngdlj_=&Pt5cyRZjseqrh=&q9di3sVbfbXcZ=&G6GRyMZofjcfd=&mSHmT9UhshdlZ=&T_x4eGYppfshe=&pqqFfeWespigX=&D_QEwcWpUefjb=&Pes6UuUlponjd=&2O2IK3Yqmomor=&xhCunvXceVnrd=&ZLmN_XUlhdlWd=&gQKRYlZoqfqaX=&ev4jkCXYj_ioU=&u9jjEZYWpedbd=&QSW9r_Vf_sZVk=&XQX9LkWUk_Ucs=&yRrlVRZoUjbn_=&qmRM3OWfeogpo=&hN6IkZZWoegXf=&XVlWaVVmVglfZ=&MNy5VlZkcnWse=&gs3SQOWpcUabp=&RVZaSyXncrZdZ=&AU8k68ZYabcbb=&hlyJJOXpihook=&qDifL_WjhfsXs=&RglbKPZbprebq=&BDzhIkWUobVip=&7vnj9BUiqVrin=&LYwtuSUXUeYrn=&U4VtuPZgiasae=&TdCUpCWZdaWUm=&GQUwrGWXjsrcV=&SYet2RZjiVhae=&w56xoIWkVoWYc=&veiwqNZgYXUcn=&nMQSYBVsdYbbV=&VxbpedUnhmahn=&f2agBDXoUpi_V=&QplIUyVVZkfin=&DhRIlzYi_pfki=&6A8rXFYYsekqe=&BNSlEnUafbnbd=&FeJ45HYrirabY=&DSZ5qpZlXjfop=&GbxRhrVWXrldl=&qFq7_QVmgqkhe=&RcnMqsYakVmhZ=&LMdP8wWboWbVm=&3HHBi7UpdZVpb=&BZCB9wVrmjZhV=&UCJ5rUWcoXVZo=&pRPxNNUnoWhro=&NAzVsEWpsfVqb=&6mUHrvVUro_rW=&En55YMZYrijgj=&X8dYxLXhdheUg=&t7wKblXildfec=&w8IVHHYYgfeVX=&LqfhCrYqd_fif=&zamGuXXYfjmVl=&HSdRUvXiUeUZZ=&ziuC6fVoXlspq=&EAYVQQUUXZabV=&dgnYqZXcYkXVl=&7TafmyUdirhrj=&wYqAzBZacVgrY=&BQaIUFZpYXZsp=&LWj7ncVsmgrmY=&eF_FN2ZckeUaU=&nBeBO2WsZpdWs=&LQY3CaUVpXfke=&LOqunKZgdfWcY=&HcCV78Zk_qhjn=&V_Fx3YYn_qWoZ=&SSra4LUsfqcX_=&rQZQGlWspddVW=&FXiAB_ZaisdUc=&xVMe5QXfagpXh=&mlT8iZWVhsUil=&YPAwqHWbeVVhl=&zalVvhYXUfaZf=&uHasVNZYkrblg=&TKNKR3VVVUZpd=&gELHxzY_onjYj=&JmJGFwUV_nfqf=&Qy6QU7WanamZi=&GXyDSiZaWjjgc=&QJBLKiUsp_ZYg=&5EMUJZUgdYpha=&BEif3JVegh_hj=&ej5cCpYqdpbYU=&olSxD5WdWmljn=&SrDdUoYX_dU_a=&Ihs9R6UYclg_h=&TlSYA2ZnqWVWd=&VXT5iiVXeacXp=&lvGjZJUahXiZd=&Qk6tVXWiidWmW=&WivZ5WUgrneql=&sGGZQUYmmZZYe=&lGaVFTYlmjoZs=&99wcaDWmbdYiq=&wqX7kWXXgcgk_=&xQWxChWakdXlp=&tytVXrVnsegmk=&VkOQBLUsef_lg=&egCInDXdjlprh=&88R9wgUqmifbe=&64ND6fZXgVnVs=&p8FYFZZa_bsbb=&XHOfPwXoarrca=&VSnMhLXadsVjf=&szPrfjXWmpiee=&aPbux8UsdoeYY=&JtanVhYrqUdnj=&3uXe5CVnWaeZn=&nO9HqYWloZj_g=&8IxN7sXfkWZsp=&2P5KmgWhbh_cc=&hH3WMCVfprjqm=&IbgP6IXh_cefd=&XOCEK_X_cakbc=&MLJoHKXemigjm=&ibgfSAVplrcnk=&oSD7SSUlZblmq=&7O7qNcU_WpZak=&jzCyOjVWpmWgi=&D6AZHrZrUZUWn=&RnOM2iZgcVpWr=&_D5RgRVbYesjV=&VoVfDgYYmaqhq=&w2iWlKVrhkmoc=&EIxyrmYYgbmhp=&Hwjc3VXWbnlbf=&4prfKlZdhrnUf=&7V8ZktWf_Xfek=&mCmmCNWUoUWks=&IkBYuZYrgshla=&tk6smfY_ZeZsq=&NJNNKSZVVfkhg=&hJew42UYUaeUl=&6N2haqYWV_aqo=&UzpibAWdqcogn=&89MyIMZlfiWlU=&_FOB4BVselkUp=&XLu372Xcolnrs=&SDNPVjYgdZqWk=&QhSWWkUlmU_gp=&rQwN4qWofjdsX=&jhllgAZYbmdg_=&5ckdQYXqjVenW=&kDTnaFXbbcsmW=&KakhLIYfnmrqU=&kIFbm_ZXlbfUi=&oV66oVXeWcUmY=&ooVQFxWi_f_de=&P2ikJeXodbeZc=&MsbwLjZZjjhcn=&FOT9OcUafbXlX=&kq2_a2WkZqefj=&SbYTazYjeenoo=&iOVTCiZY_okpX=&zLv7giWellqXd=&Oh7ZHPUbZoXnV=&jspw6QXoa_ch_=&GWogr4UfUffbb=&dM7_pLUWokjWr=&M56hfSUfW_bZr=&Ow28JDXaWra_d=&twOLNjWhUkrdo=&ZI8GCAVcacWXf=&wLCTPlVsrYbom=&RwPgY4VspVmX_=&mRsgdhWhYq_qr=&5x_hsLYcpZZVo=&8fiDPlWaYniUj=&fxceDzVlinjVk=&WzlZomYaqapUf=&iQjVolXjWopbg=&9fOqfCXWnlpVi=&nwX5l_Ydmfnfo=&Q76cpkWlZgUsh=&edVHwWXoammYZ=&5oXz2fZlVbmVq=&uP4TizXdUrnlm=&GPpMdnZbpbWjW=&UqTNeMZrrfhc_=&b3u9QPZmcZsns=&ceOqbLZnbXp_a=&fQONUuVbqrXUn=&upnLDIYjjbqVf=&CjZgq9UZUUajd=&nV7YC6ZfWXfZX=&CEqcmsVmUYeXb=&nzlgFJUYVV_eo=&ewG7OpZmWWaVe=&Wdd8FDZXXpWqi=&oGDsTCZjWcjce=&CXgalqYaihqdh=&KLXILsUmqdrVb=&QGdFliZdXoZdZ=&NyvamHUUhfa_g=&sxZYvyVompekc=&EVvFhFYbUfhep=&pEvYWoWYUXpml=&sYBwgNXmjXdfa=&8WBhsPVlqoils=&p_jLMxUpbXifd=&fh8rXIXhasd_d=&APEQmFYdWUigU=&gNpQ7xWjsUYkj=&W5lB4EVafpXie=&g_hgtBVaijakU=&FrY4igZpVafpj=&9Qx4iMYVhdWeY=&nMcQIVYoWenbl=&WzQdcWYgihmqU=&syC_DLZqoYdhi=&WqFgTNUcaicWY=&N2GFDeVVenXbq=&NffgDEZaodds_=&2_yTB_Z_joXqb=&AiWtGIUcohUVi=&N45Kc8ZhWsqfj=&ZHqjZDVZfrfUj=&tTFWLUYpbrpjU=&bZ9jW6VYkloh_=&a2RdgEUsfhojV=&NKrnNQWrensah=&utrK5AVsp_gjm=&jlIk_mUYok_fs=&KEk6YnYhbnsok=&gcfnOpWUipZfp=&hFAXsPYoorqma=&AatlDMZqZcfXm=&4A5bF5ZXqXXUe=&K_f6BJYpmdbdV=&4lGnisWUiZqUV=&Oiy6VgWnbekYj=&iOnV9PZcjcoqc=&4TxInFVdirpXb=&D4ffMDUapnVdY=&m8J5AGWhaXg_V=&r2Y7jWZmUgrjb=&kcP79AXmeaYjc=&pgegphVdXaYqZ=&Z3jn4vYX_ZbgX=&kXRlbQUigmcls=&4B7kbtWaenVbm=&zcak8pXqYUcXo=&ANFOFrZWXabhh=&TziSFUWsfWrdX=&a6Wg5HZXXXomn=&2iEEIPVqYWiW_=&VWamtQXValY_s=&xZtU2nZigrjgp=&dG67yNYdVVdVp=&griBfuYYpcjXn=&y2tQcwZrVYoYi=&6lNUpXVZYfdlX=&Qh6IQoVYddlf_=&tDdB7dZgfjbos=&gUJE9jWVhoZmm=&jSYvzqXdWsrZg=&k3A3DOXc__VVj=&DTxxqgWVrohma=&NFFYDRXldiXaU=&Y9aM3LYgUeeVn=&KBHuQCVmWsbcd=&_Kwbt9ZVkcUZo=&Dw2wZLVenUrai=&EgDiCbZfnaesm=&QTyGObVUkhriq=&c3Hz2xZdZYsqi=&ZxD4wQWWne_e_=&5icAaSYXfZUfb=&TnmZBQYajhpkq=&piB9hYZpphaYa=&Nf3LHFXse_hka=&ifQL5BYXUrWqU=&zt83WVUockabq=&cpG3KvYisYkqZ=&DzegBhVmoejgb=&ndiRRfZhVmkX_=&DBjHQTZgfhja_=&_3EMY_UdfoYXs=&mSddsEWrqYapd=&hqFjY6ZsiYkdf=&RR7gu_VqrYaYn=&srpdgWXihhYqf=&EwBEsqVcVoZaZ=&sekeqRVhpbmig=&2fByIqZpiqbcl=&dgyMGEWsXWria=&fTFFVIVjrglbZ=&ZG_Z4_ZYdnbk_=&l46YDGZdcpdmh=&mcFvZAWbqnoUU=&sTZm2TXlsXYiY=&i6ehEKYqrZhks=&p2kZ2IVceUhja=&KEoBLiXfeq_fe=&YnKkqWZfdfZXa=&kMZB_WZmcUhVo=&UvmzLpYUorsph=&s9gaiQYWhpXbr=&qzZsN5Uijgsqr=&D5IkRlUXioWle=&3MLe3iVbXfsnX=&iz4P67ZkU_rYj=&rVUGrjYUUjhWh=&62vxNGYaiac_m=&ZEccs7Ygobens=&Kvt_vRX_hnVor=&B6FVT3WrraVZk=&AKdOhyZgejpWY=&T6JPFYYdfcpfs=&bbtlfvZadlnVY=&TbhzwpVm_khZh=&72vNKcWWsndrn=&DfJ7SOXlqlk_h=&vm2YSrVbe_Ynr=&bFopxWZneYlsm=&V2d4DHYWXchhs=&KCukroXgUskZa=&63Wh7zXplkWZe=&xWcFhoXmYsYqj=&TI6VH9UbqWfUb=&6IDdRqYrqWrf_=&KyMjlgZXgqilk=&hsAYurXghhgik=&an3BV5ZpUb_Vo=&qo8GEvZZWlfip=&F8A69wVeZmVhs=&ByzMfeZrboelo=&TdmLJIZkhiVdh=&HybecSXfjUpel=&ntNKELUj_VdZf=&QSygpfYjeXhnj=&I4Y5K8XlYm_ne=&MuSePVXbgprgb=&TMFQLHUZZbdUX=&y9CQjyXYcjo_o=&xCpqyeUUVrVph=&LfyvUYXZclmob=&qjwWerVqh_Yf_=&kV_nlbUZjphbo=&shpqbyXhnqbia=&eC9po6Wc_d_oW=&fb3Z8wWrWpYZq=&eVsBndUVqafgb=&QT7zwxYVidek_=&fPjHLqZlWkgio=&rkuyXWXWsgVre=&pSmdIsVZ_mZ_U=&3eFgJwUknfqof=&spSqWJXsZ_UUh=&JECjbFWifbegp=&ffA87uUoqgcjf=&BktxUMX_nUjad=&vUBZA7UghUnld=&DJAWG4VWogafa=&AvkQYzUmrnekp=&99JDoJXnXnmhV=&av6RsuZmZUUlr=&ukhBnLWrjWcVc=&4LQpIOXobogXl=&J7kkqPYpVpnjs=&fZ3JDVWjbsgnb=&KAZgnzUoWkqlr=&bGkGgJXgkmUic=&3_GBvgZZWXnpU=&IPBSrIUrdedfi=&jWbCzbZapYkWl=&wzz2d_Zjiqjom=&cpmWObVdiieWd=&d3PTWUWnhZcn_=&by8KPuYhskZrh=&3e7YKlUgVVrra=&Rhzu9dUhmmlsp=&efy4q6VgdlfgU=&LrGlgPUjpiWqV=&C5HLJcVrkbUZa=&cmRJ7EZjjUffe=&PqqY95Xhdglag=&xmSMd6ZlnfWUc=&avDhxlXrZdkss=&FeH_IoXgrd_Um=&nMeTbaYsllocU=&Kq6DjfWbVhfXY=&5_BUHeWXZUb_m=&q9A_JWVYergqg=&5bPBc_UhagjqU=&66V3XiXZgWX_a=&DQIIzaYchkeYo=&Dcr4hFYhgeo_V=&V36V2JXfXdgoq=&BT4dpHUaasqrs=&9ysTokVkolkmk=&GyWO_VZhUcsgk=&vORs5iXpeilkc=&uIqBqBXcneYf_=&UWcfTnYWdppl_=&V3nHOnUfof_Zs=&QX58syXkmXkeb=&yhzABUVaispW_=&5VCGveYWYhofr=&jsFxjqUnYqWbX=&g4agT8VZpkioV=&qCvgeFXfiVs_e=&xprmkpYfsppnZ=&uKm3lNVfmgnWk=&iD_hcUXZ_gbnf=&fRusJUZpfUjak=&AyW4ZwYqsmdmg=&iPgcsiUYhgleo=&fonhmjZbZZ_VY=&R4a7g3XWsgioW=&4v5fhCV_dnWhl=&VhItPlVakeWrs=&MhgcDiWsirnkX=&A5gJRsYrYYYgY=&YqUY2JUpardUk=&CXPZHqXrjpiaZ=&bUjg9QUnimbda=&Gw7SaDUmWXllb=&Qgqs_EXqY_Wgg=&fhD58UXXccbjr=&Gvv823WWppedk=&y35SctZfXdlZi=&KzQ8tAZmqdnbW=&hTPdd9WWekUgg=&ptpMGcUdhZZec=&NHizxwXfpnpjj=&QBpK4fUpis_db=&fvVosvYWmpnpi=&QNPhI2XaWYpsf=&Rm34gkXsUpZmc=&ScdYtrYpsbUes=&WAultoWcXjrik=&UZGrMaYbe_meY=&3lup2CUWkrn_Y=&IU3wUYXdZsWmi=&pHZeZhVaVnUrk=&ys226UUdWcVWo=&H9Dva_Uoclcd_=&OJpz4VWZfbdhd=&mOq6WmZWqmcdq=&dbPH5sUjXmkUb=&rhUh3sXVjlmbX=&WgvMdGYZde_rY=&TODCt5ZVVYacV=&6Wy_IKUpbm_Zd=&qHMnvyVUsYUaf=&EQBBYHYoXWhln=&BSFR_8ZgmsiYs=&Ixx6oLXmXYmr_=&aXxV6sUYsbcie=&mL4uj8UUpqZcr=&JcfdnMZrXZfgk=&9ttlGiYoho_hU=&5YTzoIWrqkWfb=&nPUNvdZinncds=&OIMvypUjYemdl=&D3JlFuYXUpgjW=&rXX9ThWlZlYnq=&fUsmf5XmfYZXX=&YucZshUjradUW=&aFJ2jMYlhoZcm=&hk6CI4YqiVale=&Ynk8s7UYjifYV=&M_b7DYV__kafp=&v8QAyvZceYXUc=&n2Mu9YVcgbqpm=&iEqcBFZcVoeoX=&oDRDEmWs_qnXa=&M9hFZRXbsVjYX=&heRzGoXXsabl_=&EXrZFIWlaVlYo=&d2Clz8XkdbhWo=&nxddDIUnUfsii=&fcxrAhWUkUkla=&nj8eaTYilYnfk=&5aEvdcXfYXZqZ=&f7ylzQZnjrZof=&DLAkKaWbgcsbX=&aBPJihVhaWbmg=&pxJxZYZ_ro_dV=&p9E6T6Wkmqkil=&KZO2ReUiUeace=&jiw47jZsammpq=&4Ml8DaUbnbVpW=&HqDMOvXbcZqad=&loF9rJXfXporq=&dgukhLVlUVjnr=&vitFAiZsl_oqU=&GNs8tWWhsVpkX=&KF4cQuXkUsaaY=&Dz4TPuWsmpsop=&jfm_gDXeaWsYn=&2CVcmuZghsXbb=&vyywcrXhYVbla=&wilnuOZqdUfpZ=&dnMdZjYs_phVd=&DCTH9fWdmZeVe=&pUdN6qVWpdsio=&_ZKIfuXpanVZk=&w4q3JyZZdjgsZ=&dU4TQaWZsVWak=&UjXWQJVgaaiiX=&kSAwXAYiabdYg=&mI9MLxXjcpaVj=&_Iy2aLZUsecrd=&urFQaEZrlleXq=&_ZcjvbXofVnUV=&sSX_m4Ujrmfas=&B9u9zZUXqfXWl=&bWZy3lXiqhYi_=&E6KST4VmUdmiU=&kUQAnOXadblsc=&dOuFRGUlo_l_e=&tqXOI7ZpWk_nU=&abvo9sVc_hcrs=&Uxxk7YZkfkpkc=&AZk4n8VbsqdlX=&QJiqQOVaiemob=&jtTJQ4Zb_hUib=&qO4gneYjm_nVm=&mHF_aJWjoqqpk=&mzrVhAXYkWflW=&HtcjEGXlrkVkq=&TsEBcPVWWqobq=&vTrpZmYXmnqqi=&QuIoaNXZjnkdp=&d3WSWcXmqknm_=&cN77LDZlVjbfg=&6Y68ZQYrqkmok=&kjDeOVVqXbbae=&yUfMsEZgearoU=&SgPKTOXUVkeVg=&bJynxIYYcfpZU=&c9HHjTYWYao_p=&HIWgorUjWXfnl=&tgjsCkZZVg_gW=&YxI4aQZmhnnkj=&SGDXlZXnpsVre=&Qruhn6ZVrqWXr=&QeOgpWYffUgmo=&ES_HTuYlgim_Y=&xkOMHzUs_ldVZ=&tu2TQwXsWbdej=&vAcuQBZUfesZi=&Neo6sfZYYZqga=&cqxAMIUoqk_oq=&_5LxSGZgVpUce=&cE6Fy5XhbVWeZ=&YxyKd8XfqVer_=&nCTWWmYYmXYUo=&vGsFVCUcnXinh=&dRc_SyXrVjfZl=&jKKY27YpnsZWg=&ZzDyq3ZjhpUma=&fHphmbVnbVbl_=&OLPc5SWoZ_dop=&5nA4KtZrjZqgm=&Ab_bugUWifici=&4cYg7UYshUbqk=&7CNWqxZZ_snmi=&24Yt8IZllaqUs=&vynCNBVrppsjY=&DtarP7ZggqZVU=&VHsFA2YfeibXW=&3emjAOZWeohXn=&5vKa7gUbmfiec=&dJJ8HyUpXrsab=&hOr5XJXbVeXlc=&TKgmslYmVYkgc=&JAMYrQVirefea=&XSWguFVdnpkd_=&48HjoaZVlYfqf=&UGsIhDUkhbZUi=&zAiV4qUgrpUjp=&uw3eAuUdcbgir=&PHsoNBVpZiVrg=&Z54EqSZlrfYXm=&_226FsYrYdhoi=&wHQQbQXmiZfWq=&jIlws3Zr_Zpah=&GOOvh7VWrVVcj=&L5l5LLZnfs_dr=&tYgsDqVVmkape=&idxjywXbUfiYp=&F8oagQVcnrbkb=&mRXzzbXqVbnjj=&vBGkWJUfUUnZZ=&cHoBOcYleakU_=&WLufGVUeaigii=&Jw6QMzWfUm_of=&rgIEKFVqqVikh=&wPCoykUqZkWX_=&65_miPVrlgchj=&ALluVyXWhnZpl=&JwH3HYYjlliWb=&7fmXIeYaaiVmW=&PDYvoPZgepppd=&VWOpoQUhkebmV=&Xm_VopWfofdjs=&7pO7EsZkcndcd=&vpkymDUgqrefm=&YzfXJQZsnVadX=&rbwrH6Uahldkj=&QRlYtOYeebabm=&ERinFgXdpYbjj=&pZl2r2Yh_pYUf=&ZMrlSYZdc_jgp=&i5MkNcUrYhga_=&MZhxp7VWdae_V=&TWvtNFZZjZgea=&p_YsnKYo_kZZb=&IMhsyTZcmlXnb=&dSmitcZsrcXio=&zx6dKwYrYYpZU=&HSz7pQUcnYhXl=&9EQY5LUccpkWl=&AHsMmUUjeUXeU=&d3CHBfYZVohmq=&Oo3oIxVkZeifb=&6RSNaEUqjrclb=&UGJuupXVUhUZh=&KjTfn8ZiWfkbj=&ujHOWoYirjYol=&QVkSBEUiscabo=&CbYOH5ZbsZabl=&f4TPyJYgrpdYV=&DfekrGXhWZqVo=&3euLlMYdmo_as=&RcVyTYVXapcno=&lX6trfU__XkgW=&3HbpjSZqlnnhY=&ge_bnRUcoiXUd=&F759WIXhn_ile=&bGQ7sJUpjohrf=&YDJ_JSXZ_Xfia=&aFtibJYceokqV=&nEJYsbYgrVfd_=&EY8Xi4WWlllZg=&k3fDsgYqXYndc=&HtrQdIUjolUrY=&HfGH8MYrjabkg=&yWHOHiYdqpopk=&f3qTMkVpmjqUc=&5LAIgWXjjrnWl=&xAN94HYoeldmh=&P5HolMUhbqVbU=&NR2nADWWYYVel=&SDs5aZVecUhsr=&n3CBv6XVbhfUq=&oMYPxtWYkchda=&AJiGMrVphZkbi=&gB_tuhYnUUXhb=&AiXBFQWkaiVmj=&tgftQXZVXWeaY=&oDgZQdUeeoVkd=&7buHsbWgeX_ep=&YCp_LsWYYYYjm=&_qrBueYasaWjU=&duQtyTUrfZrqY=&IFUC9BWlYbqlg=&ywW2e3ZUbflVj=&XntwRlVVgaold=&Q8e9pZUollZsr=&2z2IOoZYbbkjW=&F8McdxUagosqh=&VyF7zCZVriUdY=&8tub9PZfcUVXZ=&qauwldYc_UZbl=&xmkHZdUhesceY=&cjmmjVXecqojc=&KdQekVWrgiWVn=<wdeEVopoXYh=&7irSN8ZVsodYd=&kmRiu9UdeWmep=&r9tGBkZYahbab=&KLHhN2UeYkclj=&fjsNE9VWecsUn=&fqdlfSWZWbe_b=&mLE7KlUi_Wogp=&4i7Y5BYXqrhnd=&cfim9pYooXVop=&dmE59WVofngVa=&TdOTW8VmYecWg=&7sCKeiWcllf_g=&VstQelZlYfeYn=&GLToqXW_kd_ad=&5nayWDVcfsqbc=&BEOwEtXhalmln=&PmSPLvWfVa_jc=&UABWZEZjVYio_=&hXA9V2UW_domc=&7Jyy5UVkgUpbb=&SKKQcSVhWYrfp=&tps6RfUenkcbY=&9iii8OYUsYjoh=&WYVWVOZp_Vdfe=&PZZd8CVVsdYXi=&XYkIkHUeVrpse=&OsASRwUUfgqqV=&fGEK6XUUXkXZX=&hi6qeLZrVjnql=&CgXNctVdemd_V=&zFcK5gWYZhnce=&MIMzpJXrrZsco=&_et96sWbnjcsY=&SiJd8aUdrrjph=&jD8xIvXpsrnis=&SFvwW9XcVeUod=&ubt7SbUeaegsY=&uptZH2Zdljmaa=&RWWZI3VoWmcrj=&dih6w_ZUmlVf_=&T7OdwTWjelsaW=&_B7riiUmgmjUa=&kYDxp_YpchjZW=&paYoRtVhnjbkZ=&ULdzKMUegcnjq=&GBGenhZdWpYYp=&Ig9XP9Zfro_nX=&eoYiwnY_hqo_j=&ari8V2WYoecZe=&9UL5xqZXmZZir=&X5LFXAYcsnVjs=&IPdUDnUjZhocs=&jhSVRdWjekjok=&tONd3LZrrrkeV=&Jecc9iUsVeYng=&8oYS2VWdkqkkb=&sj7FSaVcbfclh=&xvxAUxXinpZVs=&MGC4gZVUrfi_a=&cS3H3pXjpckaW=&cNxgMaZrkemWd=&cbRfp8ZWnUfsf=&bXhxiUWpnhhja=&5zpS8OYjigXsc=&R9Ov45WlWqXnn=&SLlSlUZjjkY_Z=&Ky7OxWUlsb_Y_=&ameHCFWhcgooa=&eRkTSnZlancip=&M4NRFKYhlYfnn=&DYUzLGZdlqnYi=&niU2yDVpVpWmg=&XgDq3lUXkiYUl=&prHvVbYrccspl=&AcsUNOUbVZsZW=&rdJbUVYgglgiZ=&TQBkQSU_hoqeg=&TRiv6dWqWmadf=&IlloJsVgpXjUm=&aMqLeGWriYmUV=&PqeKsZW_cgceV=&ofGDlfVZicdqs=&n73QYPXhWaan_=&9hG9XBZkfVWWf=&qm8ugjVsbfZVs=&PW8IDwXoomUkp=&767lJOYr_gWZW=&8rB93hXeopmpq=&eC_byxZmWpWWf=&Wk3sbsXiXVabo=&MKbgOJXn_XeUW=&yDQUgLVkfrelV=&z9eHLoYii_Wes=&io9aWPUgcpnWi=&CSEkaQXYbgscV=&9WjqaVWln_sZa=&IKuKuuXeUkkYc=&5l_XseVscojhc=&PMoNAiXijm_Wj=&vSVKG6XocdZib=&UtNUuVUZWneXp=&YtNRQlUbqp_YZ=&lJ44eHWWWbsYl=&j389IYUsaUgcb=&ejK9wHWUWaVbr=&MoPWIAWlhgZZo=&9wxL9IVVdkgso=&5eg8OCZfcscqY=&BKTFPIWadfVdh=&v6qnklXperVsZ=&mGFmjzWgsVUoX=&acAYf5ZlVnchr=&nFUgz8UlXgqqh=&UiRew5YoabeZk=&EYIt84UsjqVim=&R__yApXmsYiWY=&56EQkHZs_blqe=&M2P9DDXbdqran=&oGNjeHZZimpaf=&P7Lp_IYfZqkjr=<CNSTZkq_pol=&tImG_MUnWZXd_=&6DmOW_XlhUlel=&c8JicmZcXaqZs=&FyziR3XZbnrf_=&gXk2bFZdVmXhg=&atE7EPYgfrcjk=&AqMOy5ZdorsWY=&WWQtlDZrojkjg=&LAOJs6YpfaWiq=&b8MoWoXeWapn_=&cE83m4U_pjlka=&faTEjfWVbonss=&_cPwA2Vimlmsn=&fAoXxiZqkhVdq=&vx3WiTXdkerkj=&nyoygSVmikqhk=&_jMejjWnsqUqn=&pofRAXVYj_drb=&aBXGwFZsXZYVq=&FHFY6kZdXYkfj=&qBX7JLZqbbjqj=&ZfgCBLUYZUsog=&RxYINtUob_Woe=&8TOWWlYjp_giU=&v8HMepYdlicrc=&F2QGyoUjrZiek=&Z5mitLXni_Xpm=&MPbVsrXlqeVln=&TsUe3sUfXZkfW=&D694ypWlsVjjV=&_q9ONlVsWWmcs=&oqBMiaYoUnbVb=&MyLSd6ZssbWqa=&KbTyBaZbeWsjf=&YWVjPzVdZoj_n=&4bL53hYfY_ffY=&ZGUhKFViem_iZ=&hzohKiWYbm_Yj=&WhlV8RUaYfdgk=&PB4sIOYqVqcXY=&oRw7DdVdkfYfs=&ub9u2gVilmesZ=&Uq3ozUWfXUbkb=&GfNz7VUcrkrrk=&gywzT7XYmXsbm=&V2rKdEWXYlrfX=&yObbv2WpdlVne=&9732mAVUkZZZY=&25k44LYZekejj=&qhsWBCUgsh_mk=&Xm_yhGXslXooo=&dHTEERWnaVhUU=&YsxcE8WeehUkY=&4yXTLrUkkkjhU=&xj2wpjVisjjoZ=&IUoPsbYprYVfd=&jvgOOcVgUoifj=&t_8R6gUYfheWh=&wZCcgOZbmihef=&7UNJOfYd_qYp_=&x5sI8PYqVfmXX=&5GAzPeXoelqip=&bT3rNcZrUpXpk=&42IAuhWZnlcop=&wBxQLbUglgWmW=&f2YDCPVqcei_q=&iAOUivVecibkc=&QK6shKVefg_gl=&kwSRW_UgicmUa=&jgTpqjXpq_kel=&MzR2OyZknmnpc=&IVLUPaVZkXmrW=&hAxTdpX_UgYid=&V2IX4UUpbohoU=&KVhl3CUfim_Xg=&FKsQqLYaspbZU=&PvbwMIYniXbqd=&39gb4OYrnksXq=&xqC_xpUaaWiii=&fsprtZXfUeXj_=&d2fwjPWYjrlol=&CnzSWSY_ZrUrU=&Go6JuDYmXhdfk=&CPvzZLYpdqWWa=&_Yao_hZ_mkUf_=&LVMkPAYYrifko=&WRSJmCUghiVsr=&qlPmnYYho_WsX=&ifJQtnXplXjrd=&cUDZ4qXZepeel=&y_3f9ZXerUrXj=&ECIRmVXrjWhmV=&8qTGbQZVqUdeV=&B6sNhTZ_VYgVl=&rGONdIWnssoZU=&22a2F2XpenXhh=&H4DwzwUlZnpqb=&EwecFmYo_qUqU=&4yUuJsUlnijWg=&Fixh9rZiclYfk=&x4jj_jXYefpUh=&x5RzABYbgbekj=&PazcNGYmXZfsp=&u5VV5rZojrsab=&OUSkrtVVlhbbV=&QazHqrZ_YUfZn=&YoTSNqWcZi_iW=&X5q2WnXqheYVb=&EBNUJoUseWdVe=&E4IPkdXZZmXhn=&RQ4GkKWsiZlmZ=&RjUINyY_Zsfgq=&nufWAjYWoqp_j=&OIU3uoZellrkp=&_JGDa9XUgZrYq=&rVYlY9Wj_oYid=&CE4jYCZqrlccm=&4k5Xl7Wdqgda_=&ujGAufZkid_fm=&jG6moTZhjZdVc=&QLhQSWYfgbfsW=&Foe6YVWnXlXrV=&Atua8HWhgprWh=&332jPHYrZerso=&64aDBhVZkdX_e=&BRxQAoZaqdnUr=&LVR4GFWsnYbkU=&nb9mW8UjdWgos=&MUqE2lZoZimjq=&2_X4PZXiYgeip=&89jznfXo_ccoj=&CYPrjlVWcijfW=&M3OQJTVpnoZbo=&ePj6aJYhkfWbo=&m3XxrHYUhYccc=&thB6orZksopfh=&bO2z9KVWpbqil=&7gRHvAVqbdrnd=&sV7CD3UgUfYjl=&cWr8RgYjcWnjj=&GneebsYXb_Yj_=&QprqIIYlaYea_=&QLZtb8Wmqqioa=&TTmeBrXpmggmZ=&yKQc7RUkqclXm=&WH3AjjWgeYmhX=&YRYTbNZdbUeVh=&h5rKiuZnXXkdY=&RFhkcZY_kcfqq=&TCUY_MYfgUbWk=&sD6UxzZdphsXs=&cSQTiNVpZcVqp=&K2vPKLVWgccXn=&rcE7IkVjd_gkr=&Z5dPN4XV_Vofs=&lVO7lMWUfhanZ=&EzyAXFZbjchhf=&OpjgqjW_fhmWe=&VylVf4UZUV_YU=&cQYxsPYVo_krX=&OpTMLDYemkmhq=&IBdq5BVolXrgg=&xhhIpDVeZYiei=&Hjy8pDVddgrhV=&BwnyItYmkdXnh=&F9b3WjYYXgih_=&KA6QARVqpjWjd=&kcDsyfWWXgUoW=&OttLDlWkcemoW=&jNEnlaXfjmkWY=&HZLqIDZgpglmq=&WariUyZWcjkUm=&CsnbolVlnXqoY=&zoZJQLZdfnnec=&Ang_pFZgVdbcq=&5rgs5RWWeoqaZ=&RYetgZUnVdZaq=&mGg5qkXreZeY_=&ULksgDZgZ_a_f=&FV3T2TZkkZpli=&4yKX_JZbaajqf=&W9_VLTXZrbpUr=&eQSceRXpZqslk=&t7WrqaYdgUYjr=&IoZyvcUojcfha=&euK3ILYUXhZX_=&a87sbBWeskflY=&xEyDJFWZVhUWe=&Z3Zl_qZlZdejX=&S3_ptwVpWlajf=&pqqnwZYkZmih_=&TgVRxaVllmdsX=&T9rSM8ZWbZakj=&Tmtc_YZsrpnkp=&8L5YRGVhaldUU=&2ZWtwmUfesk_h=&p_bOrtZiVeaXm=&_oIAzsUrefkkY=&zuhhpLVXpXalf=&fj3suzYihVhZs=&quBpF5Xgcm_Zo=&mRc4f5ZWdWrsp=&23VNSsWiYUiph=&aJ6QVzZsjsoj_=&PHvbhbUUkcWle=&qRhCdHWicop_g=&nlOlSvUlrpqmi=&MQFiDtVdslrag=&HfZi8FVfhb_jj=&Qh9wsjYeWUdXd=&OY5blRVrrlWdZ=&nhrUwgUeYoqnj=&bi5MRQXeUpkaV=&RYhHLgXkk_XWb=&HlqAWjVnYZodo=&8seDXRVjVhpUY=&d5H4Z6WjZZssf=&3U5tmAXicsgen=&uzcobcXgjUhYW=&sKNlVYZ_lXpVj=&uoHlI_XgfioVg=&hSovMLYZlYeWk=&P_rLIhUkrgUkc=&Gb9EZPUnplpc_=&T6bI8nVYlWWaq=&24oGZqWUXrs_o=&MRaJQ7VojciXo=&cxGZbLVXnnjei=&XiJVzeYhpiVk_=&_RbS5jYisZUnc=&dxps24UifXclb=&a4XICYUksU_lY=&ajpYYcWbgkpnc=&lMRdZuZm_qmpp=&_YijRjYfZmYZn=&CTOeYJUUaVY_m=&A7f3yAUqjgksf=&PM5CstWkr_YhV=&HYxkqfVlVjlUf=&_oB_riVgmmlgj=&4EakT7YVsksYs=&leUdSRYlpmgeo=&R4tewcYgcmkio=&VlVbGGUVrjljs=&Rj5jxBYp_kecr=&_BAXJxYrpjUee=&_4383fXhdnYqY=&6OHptVVgpZabY=&363795ZVsqmYc=&a87CaVXoXYmsp=&XUvI_MXhhWVqr=&q5BfZCYfkeifo=&jiDCUdXXho_Zi=&uFK5WkXfeqbop=&PrZwdbVcmkVZf=&TNbiRcVoraklU=&963DQaVbebcge=&QkvErAVbUdUXp=&aKc2EKWgYppgW=&IiipQGUWUUaph=&V6bcRJZaYgisr=&5M5L8uY_nnqql=&MMhnNyZZVVXeX=&LNclZnVbmYcbp=&Fh43ZMVWpYohq=&WgalqMWflbnfn=&yaHirfXcXnWop=&UAhm6YXqsjila=&QK33GlYY_g_ln=&CXkbJcUUbjbZ_=&FbNA5UUeZVkpZ=&p3bHUjYrasfro=&XZXMCLYYZ_phW=&BrVPuSZcm_ajf=&CAmd2sYsebqnd=&CHvkneYVbnjoY=&rdYJizYeejcZV=&A4bvdXWbcgppd=&Im5eysWrqdV__=&KwUMqeZXUcVhp=&YJBX2vWbnqXkf=&fRoO7FUkenoqV=&PlF3wdZliWds_=&dpAGZZZaWfgWr=&X7ZgLLXdVW_dX=&phkjz4VYVrspg=&RWii8oUcehfWX=&dvRb5DXWipchV=&HkULWpXikdegY=&POhPZsVfepmnV=&PCgACNYbYskak=&GgcI8zWVslWUX=&g2V4nHXrqseXl=&ZtJHYJUqskdYl=&MmrcxOWbdZdih=&gKxLEJVfogqq_=&7U483NZkbdUdY=&vKlA5CYeVqlmZ=&pkrawaZdjqpap=&lx4ZeDVrsWsld=&RjQlJYUggglhj=&hNk2pvYbdpgsn=&qmg9ckVYpljej=&PTSOHnXo_Zonq=&DKe5ccWUUqlkj=&6XeQtnUZjsVrl=&pgOIppW_grab_=&kkPY8VUlccs_d=&T7AMTRXecXaiq=&TUAQqNYVlYlfl=&dfmlWjXjZrgXi=&OlwrUvY_VsWpo=&OTLimcUX_oj_Z=&TPZ4UEYmeVbad=&kAgYvOYkVg_fe=&eJ73qoVobliYl=&CAdXA9Wkd_mdj=&vq6NOzWUgfhmZ=&FQkocQYVji_k_=&rMqZxHUUbVkaX=&BiONNWVisdUbZ=&BXBtR2YYYofcU=&PHJde_XX_mWUr=&Ie6Lq7UeZ_nZs=&mrggiLYrkVikh=&nr6V75UdoXceV=&uHhalLVYrrmjf=&vBgpFzUcnobcs=&QZnxSkXa_kpWa=&CLnBwZXghYiqb=&icHi9qUedgVnX=&6MzD_HZe_frko=&bZrd9fXbaiWjV=&OgOF4OZsUgaao=&ay_CEiUaah_dr=&vlC6qRWZZqgsj=&PjCYc2WrVVZga=&LeBaQfXiamajm=&5uATOPXlboYZp=&n7zhQiYnWXjj_=&ktFp2LVaWpZUf=&Lf9LL2YnbVhhV=&Rdy5REUUncWib=&CoEmNMWfVWVbi=&4r_FJUWmaloso=&O_YkgLYsfWnca=&tGMhZvWrZUeYn=&IFZD8LVWsnkag=&V3zhjMVkfVlcd=&4LvcdtUYehbfZ=&j55uBwWdUachX=&72hU9yVqXbWVf=&5j5AUgVs_hipZ=&WlnquMXepbn_Z=&7NqC48Xjpr_jf=&Ef_uPXWjbXmbW=&dR8dmTUVWiVsk=&d3Fna6VnggdYs=&hT3qeTVkdcoZr=&2yELujUrsbddi=&XiAYLbUqdqdlj=&r5tnXsYkqXprm=&LSMibgYqVmYXp=&NTNXGCUUrdkmZ=&RbWhCvYklimrb=&oPhbEOYonrliV=&SvflZxXkmhsjf=&oHKNCAUZecfrc=&OiqOAmUeXonYp=&fczFi6Vlfqibj=&4OAwjeVaoqsff=&inZPslWqerqbf=&tcLwr8Vaogajf=&CVMZXmYkq_dal=&CXEIjgXpgjbbk=&_elmbiUemhrYZ=&pVun5XWabfhpr=&xN9pCuVq_csbg=&Uk9RCkXrkroVY=&yOVSo2Yfgi_ii=&9XLvCPUY_hqkW=&BUuCMEVWqkZVj=&zMZmTgZZUopkh=&wh548eYmfjqlj=&pYgZfiVkag_Vk=&H_QQk8XrYjWYk=&CdNBt6YlUapee=&QftqyHXdnmoUl=&aPTTanVZkooWf=&vl9EHHXiXqqod=&xLmkJsXgVmdpg=&IbPmLOV_cfejd=&HYwgCdVUoXshY=&BC5VgsZd_rbmp=&8o62QMZYajbp_=&vcU52jYgpkjom=&BUNdU_Zs__akp=&UZxnofWdXXrsZ=&5umajTWdpsZhV=&PLCih3Yeoahli=&cXPol9YVlqeVn=&WroR4nXqXscnq=&JY6HUNVYhmemd=&alNcRqZWcYabm=&PcFgzuZnksaim=&hcXU22WXorjs_=&UQsyESVXgs_rk=&mpmus9UlVneVk=&dHqdnOWqnnrmg=&BjQeYYYrd_VaU=&Pjn8fvXif_egZ=&CmUnPQWhnbdsr=&8mp7e9Ukdjgdc=&8xqHAIVmsoalW=&rN_mQVVVjWXXV=&Y_nRhZUc_VaWq=&x6VVMiUikWjZd=&DFJl8lUZaoeUU=&mk_x6sVnjjfff=&Z_mHPCWeY_UmY=&CfGtOlXobUrpo=&lQuY5UXVcdjsk=&KPrcQSUsa_ikp=&VEYRCtXjlVobb=&A5RaiLXnlWca_=&gJf5nIWWoaobl=&WSQ2wkUic_lp_=&mEv9noWZdlkqg=&BkkiHQZermlei=&q2HigCUkskjok=&NwHsJGVenrchc=&gzWzQHU_pmfoW=&AGS8bJXZnfjXU=&xvGKDmUXknrf_=&Vn2F_FUf_qmad=&NIOU4SUhcjZUo=&xBIrW8XbiloWc=&eMVcHZXdr_ela=&4ZECaaUbln_gU=&IJXVzPVZkrela=&tvQXF3YaXVcsf=&QyjJFQU_ljkkU=&K3fNiPVsdoWac=&eUxvfnUbbandr=&oxnX6pZfrchqm=&D47IUPWoobjme=&QMSR32XdXkprU=&AmvKoKUcZfWVp=&M3bLJxWbjrkff=&dqxgRHWacfhpa=&7kMPatYqjkmqa=&ag7gLpXXYVnrU=&UkJuEnUlceYhl=&6bjLZYUpWYaps=&uoSAeiUdgddYg=&CPS2mXUrmdfji=&tNrW6PVmbXVmW=&zswuKvWic_lUs=&N7FDRkUWVkpkl=&o9tD4KXrWYkUq=&tYUAFxVrZjfsV=&D7KNavXe_sjc_=&rrq97MYnk_jmd=&UE_xIUZWciYha=&qlAwJ2XrbdeU_=&BL7Os2XqWpnsr=&GAmtILWgspZfW=&2QGGr8UZcngZb=&kKbcUKXlZWYjs=&tUJftSYlhmsmh=&_V7CmIUaXebgW=&SrksMhVfpqcpZ=&8LoYhdUbrkieV=&bqpqlIUUqYifl=&cBs76UWaXqfYr=&SGwkhUVimWkde=&lsRi89VfXkZqs=&StZq_yXfmcYqh=&r_Efm3WaYYqcj=&cCzkpCW_hnkjk=&oyxxomYk_gflb=&s39MduZfksaZl=&AwYyGMZbXssjp=&MraEurVrcUloq=&2qzKQsXkWZi_X=&A4XbnGWchViYZ=&BfRq6_YgWajoc=&7Cb24pVepicof=&CvmC9cVloYk_a=&6qcVvHYfUeYpn=&jdL3JcUpqdnXl=&Jihb5jZUgbVpX=&Rm_PWrYecpWUX=&SJaiYIWdaYrmi=&w7kNM8VibsVYo=&RCnRJRUaUhhZh=&MuHiiIUbXWdXc=&QVpXKCZXrnesg=&BO5hgWYiVrdm_=&djDH6QUcfcegl=&_33nQBW_fkahn=&H3gIBDYXljk_Z=&FktsOWUlVfsUo=&IN4cA2YWfeecZ=&_YAB37YrjkkmU=&9AAme9VjXarer=&Zs5qk3ZqZfXeg=&JxsehGYmgbglm=&I_WeSHXc_iaX_=&Odse_7XWkmf_s=&7KpURUZanWmaZ=&uaekDyWphfVjl=&s3DufUVsfrpeX=&RujypGZeejYrl=&TgiBKBZqhohbU=&URgHZuYkpVYcU=&skOMHDXkrXeUU=&RR2D_qZegpihq=&S9vWlmVnfbnqY=&3GMKn6ZrWVnfc=&s2wG46VUimfoW=&EnaO9pYnajqZo=&H2uYyTZbjX_Vp=&5_mVsCVlbl_sq=&C82b6jYYrq_Yl=&DSYhv_Udk_qfY=&FtEoYfZgimoop=>C95uXXfXfbk=&zNoVD3UiiXpUl=&VvBOyWYrjkqsa=&2NwQtWYdabcrn=&e_scuQYaZpclg=&hfQYUOWkkZs_i=&PmIDrPZnmpdlo=&MHgrIbVUfgn_j=&BEROfxWXmkXob=&dtLjhEWrehfkh=&Fo5PlFZjbhecl=&v7L4koWV_ZUs_=&V3DjD8VonhVes=&sHWiPAZUf_VUe=&dsHXDrXesaWmX=&PtsIcXVYfdYiZ=&3X64KVVgUkXlc=&x6tt2WYoggYWq=&WMa8QwWVjZVbh=&YEHRKhUbsiUUp=&GFnNEUXfXghec=&Ca529hXjWarYg=&XH2j9xXjYsdZc=&6Met4ZZfplejs=&QdesDdYe__UVh=&_UoZfuXnqYnVp=&hge84_UVpbXqc=&CzduBZVUWYgk_=&PT7GBFWVXrcai=&nNmlUfYgWdWVd=&KpZNQQZWfnhUe=&afjCDGXVlgbeW=&SMhncSXfWYirc=&WWOI4MZobprrp=&SxEMq9XedaXij=&Xm8HhjZYf_Xab=&EpbJ_LXdmV_Xh=&obARCxYeebfrh=&Eq2YzhVbqfhma=&izxRtbVljieor=&pGGda9VhqisZW=&nDe2I8YZasdsn=&zV577uYiVhWjk=&Kg77VaZseaWXW=&gFxziLYborXpb=&_rcgTcZqilkYh=&EZ5yEeXUdjkjU=&GtDpk4XcglYl_=&ILP8SXXpscjYa=&JOmq2gWilfVhV=&mP6ZhmZdqUoqV=&IfRGBcYdgUjqm=&4p8pSYVrmWbme=&cxXCQoYeaprij=&Jtkg63Yda_gqp=&48T4LiWsqhpWU=&HsSojDUhoebeg=&2CbZvHXrWslml=&sMwYCkUYaehmk=&CxTumAXrUZbmn=&TRBgZhUggdhVh=&npoH5lZpVpbVp=&QPGFITWeagWZZ=&5uYUjfVbmYcel=&WLKbBaXmsccrY=&2Hl6hJWafngoV=&dJTLSpWkYibja=&sHLJtUZWgspcj=&GQpEm6VZXnhcW=&cf4XsEXeVhqcd=&wGBmFtYVXsraj=&IRmzGVWhXcXjm=&s3Eu7BXirlWjs=&S4cHSAZqmsdZa=&avwDrNZgUgrgl=&aqGYoMVfmbcpl=&5krMAYXcWZYaY=&bZDsxTYirjbeh=&AapCCBXcYpUsl=&ZDFoVQXXgUrUY=&_Ak6GGX_samp_=&SLjHy2WchnfcY=&v2abRLZekhnjU=&HAYk2AWrsjjkg=&DSe8BaVYZ_ZlU=&j4Ov3uYirmira=&KNviS_UpcfmYf=&TKkMo4VYcrhik=&gyg8cXYYrbfgc=&LkKvVBUWXrnWU=&oeZqVnXllUfka=&gkwDaUY_poqcV=&TN_hPeWWnkhbi=&jDKmMnUp_Ulrn=&hOR5JZYeZnrmo=&k6yxCIVWosVoh=&hNE8xfZflnXlc=&LXm48pWasXrUW=&L5ehAbZWo__Uj=&zUofZgXrfpcVp=&Karv2vVdrhWrW=&3cZCvdZgppplj=&ay__RRZiYpljV=&mo8pWVZrcogjZ=&i3JcIFVbdknih=&ZW4G3oXqaZrms=&qRxj6KWZqpnXn=&zpfvoyWbobVm_=&ULAqQLYlrVqbd=&caHeRZWWiVZgW=&wIrewAXpprkia=&lT5L2FYmojd_W=&nOXbgpUqgXmbp=&aZEsE6YsXnU_l=&NDroeFUV_rnZn=&IRs4AqVmWbcdW=&geEItpWW_Vacq=&cZrSfEVgZqWbd=&t83VQJWVfdqms=&C3655SWgdgoXc=&339D_DUkUWcdc=&TM3vT_XqmabUa=&cHBeyUUeslZlY=&W2Cz9sZrYVlgV=&VFyoj3Zskpfjk=&eoI7_RZjiYekk=&Qq3VmwYWbiepW=&jTpxyxZef_sjf=&OQXo_fVbnVYUj=&PWVmUiYUqlgrn=&DVddwRUhckirk=&bpqtLiZeVlkqo=&fNfQl7YmX_qjl=&A2uSYCXpeUgdX=&hhCFmtYZgqgZb=&uoIP27WWrqYrX=&y5zZtFUcadkq_=&FFN4qMYXgf_rm=&nsFpRkVscZUYZ=&AcvzksXVifndY=&oiDTGiYWcjXdW=&QOtcPaVniUbVp=&hesOBFYqmojdk=&Ljj4ZjWYsiefk=&Yr4QxTVoVjisc=&K9l9uVVqZcYWX=&ZsEh2VVeWZeqX=&5vIZXpUnerWUh=&y8GSFfYokkfj_=&wShYx8YWnZjip=&Dh8pQFWrUhphq=&vtITMTUh_fZfp=&lwao3MWfirYdp=&tDZxyHWnWmpZn=&PyMaagVkjbjee=&fccewJYe_VdkV=&OF5WB4YjqWmXg=&mMAehMVeseVes=&uNPcqQZkljlhq=&SnzN6UZXseZec=&hlgiDuXhWmmZd=&Ba_SOCZVrshka=&9jyxbCXeZ_VnU=&ZGgwTDUlsagaf=&GVd522Uhmekrl=&SKPeiEWiU_kpd=&TcOj67Ycajngq=&IMY82XXZZfeXd=&fUeC5AWdZbpsk=&HpmKBSWgUpnes=&KNxFFaUibUsoi=&cbmwNaZkZUnWk=&546k_PYasjqer=&F8AtjVUmaoZXo=&rCeduYWmrZUlc=&jK8mQYZrWqbgo=&rE7w4sZsnsigh=&tld2wFVgaaqcr=&DyjLgrXkmkhpU=&TKgOMRUnqodYj=&bely9pXkkhUmi=&_XcObUW_VUdrg=&6hGjNOXffpoaZ=&fiAG4bVWbmUck=&uIdcdDWcXUnbj=&mghmA7XfcVcUb=&qVoYvzXYhmpVY=&XudKAZWZbZWd_=&fdgOYJYgXjnps=&e8nlVeZsmfbfp=&AVBiKtWs_aaUq=&xihVwSXflbbZq=&L3rZaeZhUj_Xi=&KE8bu6ZdnafdZ=&gzTUPWWsfhjcl=&QVsJxiZln_r_W=&iS2ppkVaVrgfc=&rledCNXkap_gh=&XSzvy_UpXrkmn=&AccdR4XcmZkiU=&9E9HU_ZUYmmde=&xJkicIWX_r__d=&WcpvVxWmYd_Yi=&qd5T35Wgkbjgr=&gsaI3nUpVlffZ=&mX7G4pVjXWa_b=&sXhU_HVWnmXb_=&qQWLSlUfehUX_=&O9QlH5Ulk_hp_=&iRpQSlZr_ajbo=&BN2Fd5XcVcoYm=&Y5vhsRWoVWodU=&5DROvaXYVU_se=&P5mCZoZqnZXj_=&dDoUpoZXqdibi=&_YiTUiWqb_sXo=&yirRieWrmVjWW=&QZfuSPUoWnfke=&YyknRQXfWdmbl=&RUXpMYZcbYUbn=&Y_Bq3uYWksorZ=&xjGxKAVZjiqej=&6sSoebXUmcWnZ=&wxRyNUWifqgqp=&ea5sHOWdXiiaq=&BvFuVZZbhgjUs=&hPEKutUWhXrcj=&ku6Q8QXXXmeiq=&AfMChpXsnhhfp=&ijbrqTWeeqZUc=&xe8tfsYpcVobm=&tTyF5TVbakgaV=&Ygs8N_XnVadfa=&gIcwsLZaWnpof=&ux9W6MWhknnXp=&KohLtnXqZhYbl=&tZQCpEZgnpYro=&_mezQsVfokpUp=&nXsBCvZiZjUqa=&kPIsgQZUegZmc=&xRSzdMXebfWqo=&bhrPJhXcapZie=&_tQsdYYkUpsVV=&3R5dYHYYhmieX=&tBKfBUZbWm_Wl=>ZJlbUggsjij=&UxHMuaWmWdssq=&nuQUI7YsblbWl=&OpG5qfUo_nrWl=&yU5E_UVoXdWnX=&JTuzM4Zphqcbn=&bdgRULVeclUde=&xdAxLIUbaUVqV=&Xm8CbcZffemf_=&dCcOkMW_speX_=&LnQqJ6UXlUfcq=&Slb4R4ZYcfrbY=&TfarBEUclqqUW=&yW4ywtXp_lWnV=&vI2A2UZhYjqmZ=&oBPJhQZnjXVpl=&MEMtmOVnWafXo=&k4J6rVUdpcXmj=&dOu4IZYVklVXU=&gK68IeWeirXVq=&Q3pZ9fWVpXckb=&WDbciwUpXfofV=&bHh95FVrXVnsa=&Vv7cosXkXZdmh=&EGWWHcYejdlfW=&tC_9kYUYdrerp=&n698lRVgZejib=&S2w97HVicWref=&8sz4TAWsaboak=&39YHPgUXbiiZa=&iGnoD2VejjXmk=&QnyLSOZWncphp=&DNJYZxVlmdXfl=&8Ei__bUblfrod=&T38MNqYlVelsZ=&OOzuAdZVmYgjc=&6PbIj6UnpqqYi=&2UtEeoYZegcg_=&byjNiQUjmYhcY=&C4HEJyZlYXeVY=&q9bCZxZ_mbqlV=&uzbrLqWehaojV=&_jJXytYmkUsXq=&Q9uslOV_dVlgY=&PTcCIcXslclmk=&8sJDSgWVlkXV_=&eZDwetVnUpoXm=&4BLmdvVrjfhXc=&u74I7HVV_kpig=&nAN64hZmlVVbr=&7pJGBOZi_adeo=&iwSnrJUkqWlYd=&t_ixGTZdXenak=&YbScKGYmpffsf=&XkQ3_XUiognlr=&xxvbYNUcjZmmY=&EiXtz9XgoZaUg=&cSTdxJVdgcVbb=&u8JRaZUnqWqam=&yCXarWUYfpngY=&mKcCWeZgdnr_j=&JUWuKPUsekikn=&SAUp3SUZdcmoi=&OTgSlaXabmhkW=&WdUwXIVUUobVg=&EjHe4BVWkfV_o=&zAygDYU_fahbc=&LbRSasVkjcqXX=&AEepSAZflhVnW=&V83Bd7UmkebkY=&5xtkShUXXVjVV=&vIIqAtXbsqahW=&rLb7AIWqhr_aW=&PUyRKQYUka_hY=&CFtShWUfgmXeo=&OfKx6rWdepmUZ=&nGIHJhUVYqdrW=&lCFUpbXigebVU=&2_vDbNW___ikk=&aItTMLZqfUZfs=&XWYbm3Zed_dnX=&pFFT5YXciWUlr=&jSlao6YrYmVZp=&LO7JxLXdmqbgY=&RAJbypWUbWdel=&SCVPEAXqdUYqb=&R9B9yPWUmXegZ=&ScR9RDVn_nhmo=&qUKjAAVW_glmg=&qQE9gzWZogYgj=&YaMDyrYoeraWk=&zuRAOyUcalqYo=&Om2rpQVmjhmrs=&i2riThZibUXZr=&T5D9xhVjpdlVr=&oDRKskZ_pUZZj=&yG82lLVdeYsWh=&LdYZh7YVqgeUe=&qi8tAkUasqijc=&9UlgsKZWdkqea=&ZqYOUtZgVWVig=&JR_SpPXZaaUhk=&JgfVhwY_nacYe=&iUoi4UUdndcVY=&DWhDUAY_pkddV=&oTQRTSZpsWqrZ=&dsq6ZUVkfqhde=&tEVnyGXsmeiVq=&oCnc_mXdWcXbs=&Z6s7fbUmjpfXf=&bojjdyVpkkdYk=&Rssdt7ZkhZlqW=&xfz5fhUoXXiZp=&jJpzC8XmXgUW_=&D65tZcZXgeY_V=&lpwKQuX_pklfr=&BnUPVxXlXcoVi=&wSE8ToVWh_hYm=&Os7EdEZVeVnWc=&PqPJ8KYa_shgc=&OVGjrpXgmVjeU=&fZFhvTXekWkWs=&xy_tGIXdaUY_X=&5evYGuV_sYYfW=&eZ67IsVUfXfhm=&A8LgjXYqfqeXp=&BtcidfXnghrUn=&6RgNbSVbocafs=&v9S8NcUiobVjr=&uu8JsZUWgjXii=&HyoHiQZksigs_=&4LqAeWWljUUWV=&J9ZZP4WfhoqUg=&hhCF8YWdagZ_V=&6X5sSYZemkple=&N5L4QlUXn_efY=&LJAUp6ZbdeqlV=&UjNmTUYgieZsr=&igegtbYgWq_ar=&7cLapdWVak_ha=&CwBeSlUqecbqs=&VZspK8Ucillr_=&BQLvuoVedUolj=&VcBLtMVsmn_dm=&WZOoYiU_VYUmr=&kTZUTkUefbnWj=&YzPZUPUmWaqXi=&NefPnpVfbqgj_=&lGYdIvXgkVfmn=&IZaTM_WUWrdfk=&8VelzlXqUipiW=&ASz8jTYchVZeW=&IbSBzoYehfmqe=&_bxuS7WkmsaZq=&ItrqrXW_cnajf=&qROJRTYirXZeY=&2JYguYUfVrckY=&TeS6XDZldppW_=&cPogDEYlVZomU=&BFbEONYp_edqj=&TcIfpOY_nlfhk=&mM4VFtZYYlYil=&7qCBDgUahbfXn=&kS4ZfVWlVdobn=&X25EjSWsofrdr=&zCnKBpYgosaZY=&8peSJYVpkWges=&gwHYZ_YUlmd_X=&ldrs4bVbfsVim=&EeK8rKYphnnXg=&nBTs4OWsWrr_l=&9PubpCXdX_iZU=&jmY2AtXUdUUbd=&yOHA8RZcolkmk=&b6PHzlUsi_hrV=&ipBAs3Yfnaerm=&pvt9RSYchdefm=&j7ojuVU_akUVX=&JfXYbJYffm_Ym=&ghkgOcVeYfrsh=&XdeF3_VXbWUla=&_HUeahYkrisfV=&AicmL7ZoYsprh=&POb9bbYrplalp=&6RFICqZViqWaU=&d7WsnBUrs_bhl=&eQtLrwUVpVpYs=&eXW3_YXaapdaX=&pbdxr6YgZcYVX=&sBsqJBVmXZpks=&MFWspgYoomman=&zDjjWqUcncVcn=&Ged4w8Zskdhob=&8A6MfFVklg_lW=&kaUOAFVmjnUqf=&fkHRhpXogVarh=&l5mKtpUZsaksX=&iwNn5SXfkckpq=&nGvwaZVinsnne=&yxE2NKZXhXifn=&asVSFNWqsirhW=&WCM7uLYaeXqXi=&8tCNIhVdcdqlj=&ioIeEzVoaieXe=&gEc_c5Xf_krZh=&3hcbBNVYdnoUm=&o9cVFiYcrmYfl=&JpS3jAYUjkUdc=&PYW7wYWeYs_jX=&MD_mZqXs_nml_=&6aPNSjWmsrigm=&LMBynFXjjWsdZ=&diAbNzWejfVXX=&7Oc3cnYqUhoV_=&7dK_daZWehgpa=&sQMF5UWbcraeo=&ONlDmWXkYVsVn=&QgzOgPYU_lgXh=&O94FAwWjokcWo=&ucsndUWrU_ics=&Pdf4q7WqWbdWZ=&n9t7i3UrUUUsm=&ysVqnXVqXmmlh=&EhW4UiVoXlXil=&QFQ_fxXhVhmko=&4htCfZV_rrhm_=&AmhLIZUsjfbqd=&57nw_MUWoYZkp=&PA9XW3UlVkUqn=&4Ur3kXZminZnU=&npIQaqVVYsZdX=&KvKGP2WWodfXj=&yGBEhWZpcs_de=&DlSElGXknoie_=&pNlKlMYkpVmVY=&NYONq_ZceXloq=&zCPV9jWijmaVd=&75mmOBU_dkmsb=&ewptoLVUrsXla=&uZsDmoZlqjVjq=&UOLWGkWeZbkXf=&Z2sRcOYjYqf__=&luD3UzXjYn_sr=&9WcQDbZ_pcelc=&Ma5kxqYammUVf=&oOO5ejUYXinnZ=&LNwyicZUfpanj=&9gJVb_ZsceWbW=&uRNL6NWkgfpcs=&pRPydVVXdoood=&HuZz9TVpiikiZ=&EJO343YbYlshs=&ib8T6DW_agbmV=&O_Fs6DU_opqZY=&srHzBDUnYqpgU=&bRiHPiVllUses=&aEonUIUXnUihZ=&f5xfp4ZcjXghs=&5wWARjXjefsqo=&5OtVmLWp__bmY=&uiULSrVqhXbhU=&9MTLOcZbmca_V=&HvN5KLYojicce=&VmQhKnYrfUUUs=&ZaDMbFY_Ug_ah=&EqH7QNVZirkrf=&NhCwUqWZWhdk_=&8ttvpMUVaUrg_=&Q_C2nHYcdoloi=&NTq_lkVdcYbjY=&nEAgfDWfgUVgc=&hO4F4qWlbgnWs=&ElW2rqUhVWfnW=&N4GFyAU__cf_n=&wdxF4qVsssdoZ=&HyqS3KVYcUbsk=&Dg9tpzZkee_bV=&Do9ME8YWiaWfq=&BLKzwvZrqeYdi=&Byd3PkZeaVWlp=&L66cwPUlkcbsj=&RZLwyEYaiXd_k=&LzCmhCYkWZqYj=&dGHSFVUYeeWUZ=&sRqt6KZallsbg=&7nTyaNUkmjgWf=&HXkdWuWqb_eUh=&5JJSxaUjgslka=&hO8iw3Urlrokm=&OEHK4wVfgrZof=&QkJEj_Viijsgl=&4ADaiUZUUprWk=&nrCtGkXfmZmno=&XwhBkWWhdlWWX=&Xxd8EeXbcdbZq=&ftBEpzXeffnYm=&7pNuZZWndrXbi=&UIHlvvVchjpn_=&sctOHoUicmmnk=&aKZ6mxWelhgjX=&RwKZ4OZmojXed=&sSuPUyWaZmiiV=&gGLIMeVdesUlb=&iqCanRUfZafmc=&mSWsGlWdjrUab=&zYqbsXYhkharl=&TOwRKGWbqXZgk=&9NX_hdXhrellU=&NJmgd3XZsXalq=&u2z4tOWe_krk_=&wIDirwXeVkgVg=&3TL3BXUVUVrfn=&LYK2ghUolddkh=&ARL3RZYflbXbg=&KbMgcIYngbZho=&8ybpAEWeXhe_e=&9B6nuKUqdrqXb=&_pzS45Uqkaiq_=&9o96PhUqnmjVl=&psfVZ7ZoocUdb=&5H3j_IYXldeqq=&8BIVXIWnWbegf=&7SGPb5VVW_pnX=&c2zjK8YW_mjdl=&j8a6EvWsjfnaY=&wmIzTKXghgbhl=&IFwTmEVYcXWZg=&TdL42AWVoUoja=&wnGw_QYeZrbj_=&7WEq2LZsXcXWc=&TB5zSQWV_oV_c=&5RPqJsZbindbl=&Q3eGoyYjahgVo=&3YlesAW_qigUU=&wIjp4dWkhkmXd=&pTn7VvXsmaUef=&25I44pUYergXf=&9lGlU9Xmrjmsi=&9tT_dwWhhkqi_=&IqC6t4XZqgmUU=&aP2dbNZgikilY=&RFWYUuZaYpeir=&oqHDVsXonigdd=&j6UmQsWYZkfjW=&bo_ASnZqbkndZ=&25CTU3XUheVeU=&dIwPguXpmjlWf=&mmerpuUkeleos=&FfOTt4ZjlpgVb=&IdDi2qV_Zqe_s=&6tw7ZJZniogkf=&zKKGwZZadndUl=&PHjGs7Xsslccg=&dLiKeVVlrpljg=&x8i6LSZZbimgo=&5DH9wEVYoedqn=&Hj6pqZVhXkZeo=&OQym9TVfrkdsc=&FSSiKiXUdrUn_=&uwKcmbV_pcUYi=&JXjCLuZk_Uron=&To5n5dUpqZhf_=&GrmhlBVcljiUm=&tvwtXhUl_hUma=&Y4MYReZjrfqbi=&srxYNZYZdWcne=&O_YMm3VgVrsrp=&pUkpPFUdVkeZs=&SLiOKrUajhhik=&2tei9YXcW_dds=&xnt_UwZ_hljrn=&_o2xXYVgpbgkX=&dowhk5WUZdcsX=&Z4aXomWfYqgXa=&8ZEDYrUjpbqfp=&pYofOvVbj_noc=&OHPqoZYbcX_Us=&MPPloTXgmXncm=&ue5wnjXanclhb=&9QcGe3XnYnlrU=&wDjodRUnpjUme=&LGMteoY_WicVq=&QPNm5kW_rYrbm=&Bo9xbvXdY_fag=&DTnAhKVcVqhVV=&xQBKrLXoX_Yni=&ewNGpqVhajkqg=&eYh3GZV_qhfsY=&x_eRbfZXUpqmg=&8PceUeUcrhne_=&F3Q3b8YWUUbZU=&weEwMHWYmlooV=&kBU7yHYhsqmac=&dbVSN9VUfcpWc=&PM5dplZYUWVjW=&ybOJ7lYdgsUj_=&FgAIqPZhdmrqX=&OxJJZsZmfhbfU=&zMLBt6Wolglfr=&cs5TqvYXUlprf=&PSiugmVWUncoU=&lxY42EV_seYUk=&5bzvL4YXeqdcU=&Yt3HVOVUgmo_X=&rvIBDtZmrjan_=&2fqLUdUkZsb_d=&Lzc3HVWfmbhXZ=&_jkrUEYaasbZn=&TKbLfIUfcenjm=&jP_Zr6WsYifkp=&UL6VTKXreercs=&IbcH3bVc_jUXb=&i4eBMnWbmnhrY=&Z6xdjlYfZiWcl=&UgRxONYhYpofn=&apM8hNYohiZkb=&cPI8D_VoXkoVd=&gCaOV9Zcrimke=&nW3Hn9Whggsrs=&lD449hZ_qaojq=&ZXNmKmVdXZZ_n=&5xSGOVZlYgepc=&IX2F99Unofqc_=&XFLwH9ZigdYmd=&YSQADBZdXek_m=&KWZE72YsYdohj=&gs6qR4WqYkblY=&dxPhYAVoacoVp=&SSQCIsUZcnmaZ=&ryiT9rWbfhZnf=&6mVW3YWlrraWc=&4z5PEiUUZciji=&aEuGBLWgkkaYb=&3kXwCzZZlrnee=&NlfoRhYnXakYc=&s8YouLXfcUdjr=&JpOeoLUapoUpY=&CeXeHuXZZllmk=&eEA38_VW_Yh_e=&5ug_J7VVmWb_f=&OYbbJoUlisddj=&tBZyjwVc_mjmr=&O_L4cEZrmndoX=&uSmNh9Ulkoo_U=&PAykTpXmkUYml=&YfsNNbWqrWiXd=&bZiL4TZVojboY=&CtJzoSWdanqmU=&fvLpwcUdV_hZd=&_fLICsYfbpkWU=&xIIufmWYhYjgn=&ZumxNrUjaUfpW=&4mLGcVYeipapc=&yCoisHWfVgYrl=&MbRuYtZobimVr=&alV3ldWUgXhcd=&PzewyeVaWgYgk=&JOVF8kYZdebik=&JPBPSwWUbUsVf=&l4AiCOXpf_ghh=&k39XBIXZYq_fi=&xVRW3dXWaVXak=&3WvWQ5XYglUaU=&hDYiXkWkrqsaZ=&oCDCAQWVYsXki=&IUENtfZfVafrd=&pxlsZiWrecZja=&yDqZUiXVlklsf=&x4EXH8YhboacW=&TT3x_PVs_U_gk=&iBYvOAWhkqqZb=&bbbClyYqh__qi=&FxHbBjVq_fiZa=&blXSLGUbXf_lb=&Vf2BLaVWZrgWX=&dDvK2UYmafiUW=&3cvWzRXlcmdfc=&4XOKGFXcbppfh=&xYTUN6VephUmc=&P6qufnWroX_n_=&VZ9kSpVZob_di=&eLA9zOWjVgsji=&_hZJfGVmaaWYm=&hBTyTGZlkfio_=&LXZQeuXmpahgr=&hqffqMZodbYha=&hSeUkrVncegjY=&yI6SJKYrXifnZ=&NUu8e4WhYVkqg=&t9qYnLYZeWoaj=&9LNn8xYoUkZhg=&u6JnCWUdrdken=&_6Z7UjXXrdlen=&964qQeUkibaZp=&xXCxLUWUgkgXk=&q8EfX8XeleXaq=&eV5YvJZV_iklj=&8sdeZXYWnrddV=&RwWC_JVamVqmf=&SNscjUYeepkc_=&YVvogtZZ_knoj=&EeurzOYlVnhWf=&iF_iJ4WcjVrXi=&59ha4JWkeophc=&m24_6vXfqYVXb=&7rJrFUVfkY_Xc=&zzPBioUlYUbUX=&ehJPjvYjjjmYl=&HQoguEXdroYlg=&9eAjKrZXgYlrl=&cMQUUBZZUaiZr=&7dkFahUqlYo_b=&TcFPA3VVsXilm=&8BgOHBYbobWnY=&SEwjfHXnrmXnh=&BtcvjtVXbVlgZ=&7ZV4tJZWlqqac=&YEXHbGVqrpWsp=&MiEXJ2Xa_ebec=&NOanifVVmYZcZ=&6atxX9WihjXrX=&twTcAHUVdnk_r=&SuWq7gYchfqnk=>WwuzYkdqhsV=&JWrr4pXWmiVdl=&K2j7w8X_lagrV=&CXmE2oWhenhXn=&_eAt9zVaahqXm=&Fv9WUdUeVnjZo=&6VtLFCZs_lqgk=&sfMkctVighnhj=&x3zFvwZcjjkXX=&7smkpdZnqsfWo=&w4p3EiZUspZYU=&ZeWPUbUYVqYn_=&DjnRGgUnZYqoZ=&EP8hfzXkXUfYl=&OXaTGGUciUkUZ=&NNQFI5UjXqmmi=&jCwgK4ZVVcgUc=&8dKl6gYcWXWeq=&e6UYqWYprmcqU=&WzK8g4VdsUlni=&4LdcrPYnosomf=&7bVTgfWYbVWYZ=&FpJwwcWmkcsg_=&xUdHKaYUZkrco=&Q9X4gLVnXbZfq=&TTTGRJYehcq_Z=&yb_mZiUnpjskk=&xcUlfNYXhVibj=&nbBkjOW_Ucncg=&TU6nyoWgnepZZ=&WvCs6hZYjcrUV=&_vzFJpXfVkhmk=&PAMz2aYWWfWVs=&c6JkQGZbfZWV_=&ubWGhFYaYespf=&AySH7UVg_Wjei=&7Mgm3uVlWWisX=&vPYAufWklZjqV=&3cDnlvVscmgrp=&qzivi2Zchnooh=&qvb_xMXUrrmpq=&rJqWSPUinZofl=&q4tPc_VdsVqbW=&ZaCj5sWqii_WX=&WywyyNXhhklnh=&_f9RhpUrUbqsn=&xIgZMlXXmpVWa=&wHzXMtZpnZWje=&US4cGbWkXh_ah=&iG2X_bZWYdbnU=&gENBoDWnpfepY=&v5MUT_Zqgnrld=&9BWhOYZWdYfZd=&C9pSoXVnZqpkf=&tbJWbCXskUdri=&iwglymUnongrd=&kMrIOOU_ggdYr=&DaDMHbUbVjUhn=&OsBdXqZgsYsaZ=&lr6UkAYefrhlq=&tn5gAxYqcUhml=&hDjOTmYnZihfV=&F4XpP2Vpa_srY=&YjxfoVWWqgdfX=&mRFE7UYdgVmbk=&o3JJ7SXbqWdoU=&XPqpyeXocaVlh=&45xBDiZVngXkr=&PAmEnAUZmalWZ=&x7J9tnZehaVqa=&5GMGBlXhmm_fg=&s_WulwXjpnbsp=&f8A48TUqfrmrh=&dGd9YJWVWlUkm=&zFCdzWXdsgaUX=&bLoJnAUUcjddY=&RrNGSmWrXhnU_=&qOXs8UVjfYcbV=&Jh39leUqk_hfe=&RBYsvCWXgaebi=&QEONJOUWamWnW=&8X65abUdcWqgs=&2mk4QoUp_dpdp=&twGFiRYqrp_gc=&2ONT7PZWp_jVn=&EEnYOsZhpUlsc=&ufJjWgVrkmZsr=&xgd86VUpYYfoa=&F3wGujVlWZhgd=&pxeePKUUpiVYY=&cyuFCrZZYVodb=&XIqWpJUYkWlra=&ATQyl_UbnrWik=&VkXClLUUdddsi=&S3psYXYYWeZeU=&JDe_qIVqgmlni=&KwrZajUWokYok=&_MvNp9YjZmiko=&XfpmDyZhUVYWg=&PMgLHQYogeomW=&XCGR6DWXggsXd=&mEMMPnYmoWips=&s5tRRwWsliZhf=&GX3jpsXbmWjXg=&_QxfctVmgjlZs=&J2HnmRZgbhVfp=&GgdiOyVqXZrrf=&8cTgHNZoUWror=&MOHlqEVkcessk=&qzLshYWsXrnbe=&sjEqTiVc_pklq=&F6sUgaYniloWf=&xC5LVyXlkifZe=&rjEJyKUrVnZfj=&wqSUyJUbjocsi=&c2ylYqV_hhsU_=&PPnXLqUbcipUa=&bTeHHoYUdjjsa=&eez7x9XXhpml_=&4HBiy_YsZlhZY=&9PoAkDZlgdaXb=&5DT6chWbeb_aZ=&xBkQPjZlksbrn=&Uw5DafXoggoYq=&fAXpNhWWhghjh=&2O9wgfUjWXopk=&oVi6_VVgkcgfm=&KMTM56Xcoke_W=&3XEfSbVpYbVgc=&TY4Gb4ZXqXoic=&jNAt9SWjhd_fa=&bxP_NFUob_fnV=&RrkLKnUreiVXa=&F36xEUXe_eecj=&onybsKZmjVpoX=&lHAKyMVlrhbig=&pNatMTVlsbese=&oqiueDVXkl_Va=&evvXg2XZagdnj=&AmqmIqZfWcffb=&uSPcQvWjYeYbX=&o3XBFVVborknj=&uuvFmeXmonlZd=&QKo83WVaniXVe=&3bKEzvVohshZU=&oNu_VpUhgnWnn=&PMaAhyZqpUZak=&ISQijmWUYV_ni=&GH4FtwYrhdbeh=&xFPwBaV_Wjaen=&JKBn2iXepdii_=&NJWHKhYpdVeYa=&DEXuY3Vjnpojc=&Z4dGkAUoa_qrf=&OXjK3sUpVpsag=&TCYU4rVfkVbfb=&lT_NnTVWkqWip=&Z6QQVeZjnWhsi=&tSoMC5YeUdcqr=&Eki9UOWqXUrWf=&hiO8ZHU_pWYdn=&rAGHV2WoUWeUp=&aQbufVWVlbodW=&qIB7MTXshjWnb=&UzxUajY_VlXV_=&QU3hTPXqpqmrn=&IFElJuZo_WoX_=&tIieBVYpefdcV=&Wx9XacXbcoj_g=&3S_A83WWnmocj=&Z6RHtxZ_VsVYU=&lUiQByYloccag=&Oxdem7XYrbpds=&ALxf7IVrecZhm=&TUGaWsUglrXdU=&NCPIlvWhffcmm=&Pu6DhrUVg_sli=&YDHfLgYZlmcpm=&Kpu449X_mYhsa=&VRBS9IZUgprZc=&yeXkBfZjsVflV=&j8M_FeWYmbjY_=&_53KwsYdgpeUh=&YfDeTcZaWUpiU=&Kme6QzYpZaWqn=&pYXoRJUsepsmU=&UcaUnTVkspeap=&zwQjDHXhYidqa=&sNVt4vXYmns_c=&KnwkPqZhklpVg=&Wqh37HZippgnf=&cqYMQyYijdkfi=&JasgExUmYhjod=&xxImFUYeiaddq=&_KTROoUpr_qni=&QdwtouXbcUjac=&qr4ReEZgdbjke=&woijpLXcis_gl=&YEHTgTUaenlZb=&fNASnxZYjeqrY=&KrRxzOXVgWfim=&f3n5FJUmdbfce=&2fq7TCZgflUVW=&5otgqiVgXUeYa=&ypTSVxZleXpqX=&cFYDEtXsgsojY=&cm2GLoWZUplkY=&Ry78n4WmrpVgm=&FaqyHRWjdmVZg=&S9aARvYmheYc_=&LHrtzXWdZXknd=&fzcYm3XrsVrod=&kGVluoZei_jfc=&y55SSmZmZ_nnf=&iZlqgmXnclrcf=&J5UxMnZdYZhco=&dycLXKWh__cle=&eeAzgSUlgpdsn=&8b8ljzUsjVgal=&ZaDfAdYkcoZcm=&RHjUeWXeWeWbs=&WlGlSOU_UrabX=&jpxhaeWfVggUb=&LxPERBXneeqrb=&JXxY4QWjXsbpb=&dnVrpiUcoZsWV=&_NzSiMXlnXrhZ=&XWNqYzYoVmboW=&KDwr5XWfapUke=&j2Hty8Zpf_Vbh=&tsdqlbUVfisUb=&7rQT8xXnVbXpr=&HwPT5GUUVXnl_=&JuCHnPWhiXqje=&iL3EW9Xcdgfle=&M7NvPmYdWUfYe=&Pxr9EjUZhWcml=&x8UkDxXgrd_io=&ptMl8cWksmhsa=&yLThmIYlfU_cc=&mZbJCeZljXeYe=&_K3OleWbhnsng=&DaftDvVbiYVXU=&lLsKLIYXjZejc=&KOSsqgVipZgcm=&NPQo89Uoq_hZU=&hmVHA9ZjopfcW=&jQEuSlYlfmfrp=&Ecf3bUVjXnsYh=&EUwxxNUidU_cj=&OKBX_UZbWkZae=&94txjBYsjdhgd=&XujIINZ_ib_rl=&vY6WkFWXYYsbi=&hEEv8FVdgmmnk=&xSvvPsVffZsXa=&vN2gJdXjaWWgY=&qZYxtQWgsfZqY=&rEAWNMVerlrf_=&CXUuwCWoedeiV=&9I5k5lUdUksV_=&u36AeFYkchYbd=&huBoSEZYYejgn=&Qd39XaYncjqZa=&k8reNKUpm_fXV=&VDI4KBVofhmaY=&Ck3bYwZmqVfmn=&hPoE6_Vfhbhbe=&UdYXv5ZYpsWeW=&wLXf87WW_mpVp=&bhYTHiUqmiokp=&RqLaRaWXnhrpV=&U2rTMjUakcfbV=&Wqv6_JZl_nqVe=&dmKEvQXelUqfc=&GrzIycVrosrgs=&cHyzKzXcUUYjk=&M78khxYY_prrX=&DDxoHMXnljdY_=&egaHy2UmeibUk=&9Wx83_XqjhWcg=&Sq4bA5ZomgbnU=&_NRdYxXWpmiUb=&YIIsWjZdsanZk=&3gSuC_YijfegZ=&Hee_KYXmlWcqm=&Gb9MVxXUhi_Zd=&nvxmXLUsoafdY=&3xGehIUrnbhah=&2s5x_8XedfUVg=&GUAtvpYYpjshd=&IASK5xXYlh_jU=&4TSFQ7Wmblhcn=&oq3OPoWsXpYZl=&ifKQX7Xijf_Wa=&IWdmVGWWaasap=&z2g79BWajaWZo=&eiIaKRYZcUndf=&wA6yieVkmlVVW=&BbUr68ZmVrfik=&q3uuFOXgbgdaV=&pwF4T4YWWYcZf=&nJqPqTWiVq_rX=&uwWzHUZXdkejV=&e9eMSCWjmhbas=&Qr3xG7VjUfsce=&DSw26fVsnUbnd=&tXYwtFVWajgpa=&_7NaodY_Vefhq=&y32_JOYeYmmUn=&ginSCgYgjjggs=&wqnjZ4VXdhllp=&vXeQiRZebjsVg=&Avug9dXrhcgYs=&RMjIQUWVardei=&wLXJ4jXkcjpjk=&HQUa6jZWYraVn=&JZo4R2ZssdUVZ=&4aX7s9UbZ_lhZ=&vuJvviXpoddlm=&YgwmISXYghjaa=&7t5ppmVfdUsb_=&WRuqN9Ujoqrcd=&nM8osaWpWdZU_=&Nx_LsRYbjXYdr=&P_hPPzXoXaYnp=&rXesJ5UkVnplc=&OwpTtnWjWVhfp=&GppYcaWlXforp=&qFFDPBXhaVlVn=&RPPKDuUbesZZ_=&BGH4z9YfUfcin=&vhvQocVrZoWla=&uSGApWYYkasok=&Ooui2aVjWkgZX=&gNSrJfZsc_gZd=&k586QlXefdmZU=&RLWrrFVkUssor=&lHVDbTVdphkbs=&LmFWYOWWiscYb=&9VDv7kXfairmn=&frLIhUXpjfarU=<9CkZUmgpsgp=&OKIhLtUsrYpas=&dRTuPnXgnsend=&JZ_37qWlssZ_r=&GIupR8VlsqeiU=&XQaJQpZUdsVgV=&toSpkwUYe_ani=&ZE3qIbVpVZfpd=&UG62JZYrladWY=&H7AvgOYnodfeo=&NzFkwHWjhlkrZ=&yFfyDFWXaYhWd=&C7RokrYdhVcW_=&Nnme6UVgkmsqb=&DBDVnCUUZkbYg=&n994zdXX_mXmm=&u7bTm3Zoi__WW=&uuSdPcUg_hq_g=&tvjw4ZVokndel=&4DKPNyZbfbj_s=&ZHNT8nVZarfVi=&WWlkUVZdWdXf_=&8vbwN4VcVYmWm=&PM38STXgjdqqf=&Y3iahyWWsZYep=&7MgIpvYkksaWh=&SJdXz6Wofqbeg=&Fqy9YVYrohkmV=&WSisXEWeoZYbo=&NrpzGHYYdfnol=&LFfTdYWVofYaU=&l7sEVEZUpjjXi=&LkMD3nYksrbjd=&WuNqybVY_jVpl=&j_4bt4ZloYVlo=&uDRRW3Xlbpfno=&HXsFieXXkXadi=&NiQ34zXUfsc_c=&QyIAipUUcjWWh=&AiK4YBWkoZcgW=&STiGrnWdVshXo=&zOxD8_Zemqpkl=&vQAdqRWfXZgkn=&_M8FvvWXYisXl=&WeCNjaWqqrmg_=&DcycfJWllXqri=&6RDyynViqWgWi=&7NevgTZjqcedp=&_SuzPJYqhiaqV=&GaVXJ3ZsrbpYq=&AAqOX6VjercbV=&LgrfYxZZdUppY=&t4bxYgVlapdnm=&myPCIGZ_ssr_i=&v9yeLmZmganXa=&Xhara6WYhZVlZ=&Fp6EYLXVhUqcc=&YEsykAUmVYkeW=&CmF4aBYYeXbbf=&xuTlknYpganj_=&fEI8veWecsfra=&wxY7DjXeccUXo=&thsSqcYfahrgi=&IQ3DVVZerXUra=&Ib9UCDVXkpoYa=&iT69UMZqmVf_Y=&pX3c4uZcibZmh=&y4WvyTZlWUohX=&ZpfWKTXjmagaj=&TfhGebUXZfd_r=&FKsALKUWbXlZr=&NmgkooWkblWUY=&_qHvkbXeaUbrb=&AX_qZMZlpjUfs=&xbierKZm_epce=&udwQYHWlabkpm=&FgFJtAXYeamUq=&by3_TVZVoVmWl=&XtXeo5YrXZfig=&WPIivaUYrZbW_=&geLIg3XWpmnjY=&6xvalTZ_jpqen=&9QUNdJWaeWVbY=&PedtdhVdZpkhd=&gmHOQDYWdhXhl=&qCSXIjUWc_ara=&qwNAeYYmhrsse=&O_TuJtYiXXigc=&UG8BNmWlXVYds=&SBcj7gZggkhaj=&5gahDqW_WjqpZ=&8KEnhqVYdcVcn=&SnXrubXcooiXV=&5LZPY5WZbVZee=&zz6HQwUsjWinb=&qsqtwJXhc_sal=&waZDRNX_YjYfo=&RRnDCHZ_YXUcg=&CL3HU8Xs_Ydco=&wTx2HuXkpordb=&_u2fvVZii_fgj=&w8eG9HWlsoUgo=&GQkEVkYiegYZf=&Y2WydGXWajjsi=&DvHjduWfchdp_=&UrDWA8Vamcfie=&X6gIsIWYrghkj=&qHTW6UXjiloib=&2D4GobUnqUVle=&WKnOFhWXVYYlh=&hylZCdVYqmgm_=&9S3uLtYYUY_WZ=&BNRb8mUjbWXjg=&txRa9QUYrnWUc=&nqJlm3ZVs_eqY=&gso7vUWjYrnkV=&AgtyUYYcVmXm_=&vBQ5PQZVVbrlm=&j_U4KmWcgmXak=&S3nv7eWlhpsUo=&cVkHjDUdm_VYh=&Fo5XhSWnfcnlc=&Wak7ZFXVoVnfY=&xl_bN3Zhakoba=&aNibEMVhpWmYm=&GtNZiJUgohcea=&qyAbtCVZZmlZW=&Y6LpXXWjVZXpj=&JuHlSFYkngbns=&hSsbc3Yrqqsak=&I28dvlUnspcld=&I8IhANZgjqZbq=&byV34yYpVhsXa=&PA9uqYYoaakqk=&Oqqse7Wmblmil=&DqRZPiWnjcakb=&gjU9vlXanb_pe=&JaSn3gWUbkUm_=&XcIuVhXko_jea=&kwLJRZXiZbgUs=&x4UV4XUlgapea=&n_aiE9XplsseX=&_hyUilUbismiU=&2O6yOPXphYZeo=&hlmkM5UdriVUi=&CZyK5qZrcVehm=&xSipdSYplsWas=&Ih8_ooUlllcUi=&bDEGvlWZo_emo=&yugMz3YZdbXok=&OekyIsWlijods=&WmmabsUidUomX=&qrwxsQYgahlnq=&K7KDRWUWbkorr=&6jnqpPVVeUcqo=&NE5DVvXaVXXeX=&yeWpbvYihnenr=&I7cY8HYsVcrad=&psM27gY_obmdb=&ti7YoUYcdblcV=&Jo_yAxWcqimls=&LejfkLZonlXcn=&_y8My9WZWoZcm=&r3brz6Xhoajcb=&rGV4VnWVVYme_=&76baoYUX_qsmq=&RH5mhHYoUefem=&Rn2GDRXZcgfkd=&bCO9C3X_qbbVa=&i_Mb6TWcVmoYp=&za6CP4WaVWsak=&gqUIFUVlUljgq=&yFAcx_X_Zbika=&HWPl6sXVUYoqf=&O6phJDXnenbiY=&HZ5gSgUakUdos=&sxWixdVWmeokr=&ITxvkjYeYYfrZ=&s_nCeHVXUsqYf=&MaA4EUVe_XZsr=&IYnUCCUa_eZhq=&eeaFS2UjWnoql=&mSIK4ZZdnd_aj=&8KvEjlXenqW_V=&iqY2_7XqnlYbs=&Qrv8HTUde_sgf=&7mlnrsYZViabh=&V5XpAVWflkmgn=&HM7WsWWgpgXeW=&VI9Rz6WkVqi_g=&2Bvj9AUfUkinr=&nm_xTzZihXnhq=&kh2oMeWZooZod=&TdJTYKVsYZqpc=&gyR2FsXWnl_qh=&skX7NdU_lgWod=&juEaVnWXiUcil=&vLSktoYrfhbYU=&KpzZHAX_qiiYg=&MGh9HmZhsmZsk=&xs8ryTU_nqsjn=&vpbcKZZanpe_g=&MZiWcMXfWkpUf=&9MwLQnZfUmcrs=&4OfgzBYkbpn_o=&wBih_7VipnaVb=&fkpwAVVldfoVZ=&9t45hAYUcWcqm=&hf5mXCY_epbnX=&xDzly6YngXVin=&ha3kxIZfhjZiY=&rd4t5gUskgf_q=&U7Ig5uUasgaf_=&jYJ2JXUcih_kX=&PC5PfWXilsqoo=&HJVhyoUmdpqh_=&KQsNt4Yelsjei=&GMtrcDUshspph=&mEIGfbZimZhhh=&nvaKfhWjfXrcd=&AnQDVSWaesYYo=&WMBPU7ZnqWfsg=&JUwmEFXin_ekd=&nv_Q9uXm_hUkd=&PUIYerXUUdpog=&zTb_b2YiY__Yq=&c9AgbOYmrVUjp=&sNeTkaZchYVhf=&drj3v7V_j_dnZ=&kl8ZP7Xqdripr=&kJLL2_XabnVsX=&3iII7bWYUclji=&QKM8ahWfVpqfd=&OgI4mGUhrdaZU=&EdUithWhXipeX=&468KPwUWqhXUl=&GKiG4fUfpXl_Z=&atAx_MVscrmYj=&GnLMNhVhmp_Xj=&ue8Ev_Wbccbhq=&xQj8qLZsqUnal=&_cygFGVjclWXk=&64G9UyYiZ_hrm=&kqoVBBUhqVrXe=&WgpRExXYqfqos=&8hnc9DWadbebo=&oZq7pJXVYeXri=&GMGJ7KZldWcqj=&4KVQerUaXiVss=&6BP9TiVngsnsm=&gooZVBWdpdWWZ=&TmAqsuWpglh_Z=&3bdjyVZ_YqqbZ=&jCFCatZkXYdXi=&ETDysEWVaZkgd=&WcGmNAYhssrUq=&bUTrFXZ_Vsoaq=&WCv5CFVlneXb_=&byrtISYgrUpge=&aGJJPfYiqrYlZ=&ultDNqZorXl_r=&mzH7PqUadnoig=&w67pHIUnegjgk=&4gWmSUUhkYmoh=&8VyfHVXmoVfqZ=&LU3m3OZplWlUc=&YDM5bgYkUZbpW=&dQG9PtZgdpfVf=&BWnOZrYngZkin=&pCN4HsZdbqdYl=&cZX5jLYcVWmjX=&3THvORVcheear=&vTvYntZWahlXq=&Y83MTpUVfUpiX=&AwZk3nUbjWYUr=&e5oDYlVhnpabg=&jI8wI5YlrcXWg=&NL6Po8Zdcesma=&Q7JPCGXfemnhZ=&5VqW76Vnjoejb=&9GIaF6UidcjUn=&yh3uBDYZdkibn=&O_Y7jyXZUhoUr=&7jScZFZfZYfZh=&dGfdkAWZllYsn=&UZs6TWWnhXZgY=&8v5YLHUjbreUm=&Uc_XA5Vc_bdde=&RBo8yNXgZimYr=&6HrXj5UrqWi_V=&8s9qoVZWrqXbZ=&NwtHotZZjVWhY=&mV2SAHWksgcVf=&PfqiQHUsalWXi=&kAs6uQUmVnniZ=&J6Ah8qYgbgccY=&3I3IwYXmaWphk=&QoUerPXggiYpn=&Pn_2gmUlplfdb=&CsZeyfXljkXXW=&SIUgHFWafbdln=&WDBC68WWdpZVr=&ZxMC3eZfmgVZj=&WG_Km5Zn_ekiV=&B2mXMZVmflerl=&w2OxzPY_nsaig=&ulprjeVbdWrni=&bkPJTPU_sfnqY=&8SH66DYaZYYqp=&I2wK5SUokkUVp=&_cPa39WrUVhir=&kaJbV9Xhieqms=&guJJNuZYmbocW=&GsmW9nZkXWlYb=&LLpPjvYofWjfi=&fRvK6PWUgmnoZ=&Ntbo8rUaWhiql=&dv4AKFYrcgqdd=&wZaJKPVifqmfb=&GASnkcVlahpdX=&ri9vYlVkogklo=&D88JWAYZjkWZo=&WgJ4SpWdqYnme=&2xltFdYsqps_k=&pEQn4mUUcXXgi=&Vlk9P_Yjn_c_k=&aVszyhVdZaaWp=&b5KWSmUVg_fjp=&PkyehhYahZelb=&47jY9AXm_sZad=&OPXBN2ZpcXpei=&7eRwORVbbUpdc=&zfitDiVlskWbo=&W8JfDaYnWqkg_=&R2HN4cVjrUfYY=&Tz6hQmZcgksgo=&lbr727VVnpVY_=&UUU8nvXWdrsdc=&2TPTLHXsaepZe=&GEbvDOWoYVnca=&hN2QM8YbcakoU=&oBSWPGUVnjfsr=&PpZyB9XmogYae=&lB44eRWrcnsrb=&oCZ7dQXpoYo_j=&EMom3yZVYYfok=&ku2w7XWYjdgon=&yGm67xWcaXn_f=&kXMxqtXakXVaV=&CtOfr7VegXc_c=&UDg5_8VpWdqpV=&jQkCMsZrablnZ=&Fdk45tUVUlfcU=&Ln46knVkak_ab=&W5M8ZyXiXhcll=&w7TdEjZZjXmsc=&nCuXVIY_klkkl=&VAeZs9Vsppenf=&uKc46vZrjaeVa=&Mw9j_bWYiikZi=&mGlyZfVmcaeeb=&_mzXCjVedWmVX=&LeKTNbVaWsYom=&ITWzPBUopZ_ed=&eBK4OLYdiUmel=&HhKdhmZdXfjfl=&JesLTSZcmXogY=&gbEItbUrsamZ_=&SQSmuyYefcXkr=&jjFy27WZqVo_j=&mA4i4aWVooppo=&8cDBqdUjrhkVl=&IAkVHcXcUgZlg=&vsTA8TZXZmcXf=&ndy4XrUigra_b=&tS457lXmajcnX=&lVMcqLZ_ehZlo=&cstVraVYnXrYo=&3bhHJAYiZoiYU=&jTxHlKUafadmc=&lqL2dhXookmp_=&nyoLLuUksb_Zk=&YwkXMLXbnaXgp=&FgLfdMYVoaUqi=&Q9lJ29UlXisgc=&HTdTCUXVgfWZh=&IKgxp_XhjqXXs=&K3RyqCXYlUrbU=&c3kSdDZd_ddZW=&Th3MXCZicZsbh=&jPdWuzVYlimkV=&uRaDPaVnofVko=&DGDy9cZhecfnp=&VU3fbMZilhlaW=&FttWWrYpqahZ_=&_HuYfjUek_ZaV=&NIkMgMVn_neWV=&qwrpSIZbXoYga=&Eleuf9XdemcaV=&aCRFObWZqZWaY=&tZYlmyYqnjXhc=&wlubJEVdkYcUe=&vhc8nBV_jda_V=&AhziMRUj_flch=&VWrumfXXXl_Ua=&qjEwfIYoVXqsb=&QYqsxhWiUhoZd=&qWkW3EZhsc_ZW=&sYeffyXmXrWYe=&qeuBkiYdWgaZm=&5tcBZXWohVfaW=&NDhzxHWcq_qoj=&cUvnovVajrbqm=&WpU7MsVZqWeXX=&yM24eNYhVnisj=&98M8XSUqoobha=&YoHD2JYWcfnYp=&_WennSXVVbplf=&RHTMkFWmsghsY=&6I95LgXpqdfYb=&feiVCNZlrqXcm=&ki_aNBZrohZmr=&WbnYKsYWW_fnf=&k5PVctWkisjWf=&dv8lfGXUX__ms=&lkNf7pYplqsdW=&PBBgt3XlrZlaa=&hInhXkUlccmUg=&9myFRFVqpe_hh=&VRIMBhY_s_fXd=&qHSyvbWjrlsVs=&7qWHgzXgonfii=&McR49QYfZdiUm=&OQ2wWAVssrrsh=&qWdwf7YWm_dYi=&7v8BEiYfYqjmo=&8EOAnXZokcors=&rPW_SeYcmWYVc=&g9dM_xXsWfrek=&hzGN4MZnXfZma=&CKrqroYjprUie=&clAQyjUociXlX=&gfm9IPVajiXig=&fALGwqUibrcbm=&d7eRmfWdmV_gq=&tbhPd6Ziqmkbd=&QMwlvSXlgXroj=&yS_k49UWigoXn=&HjNHNFYdlpfne=&nyHlcKUX_Uspg=&GIfGUYUassnqp=&7J63JNXpWfhcp=&6ro6aCXZjdZef=&4bI7ZYV_blYjY=&uX6CZEXepd_md=&5FEbfdZYs_hpY=&SAGKIkUUpdqeV=&MQLSGFXgnZmpb=&KcAlVZXpr__ip=&ggnQIFYV_jVmY=&_HfZQVZgrljoh=&gqTvjhWYXopWd=&NbeNGKWbkUekV=&qIifaDZnXsjlc=&FUXx9LWgYVdch=&OzzGvsYZnakg_=&zNXFLZVfgfllY=&6Iy4OkUobqUld=&9ZNNb9VkXqZpV=&scfTVRUnWZskh=&xPgmtuZYkVijd=&7XyVUvVshkiiY=&VbpXvDXegXVfj=&uKYTFLVaXjndd=&IMoqPBUWo_Vdr=&p3mh5sYjgXdoc=&E2cyh5V_icUph=&EJdmmPWmWiYXr=&XsyaCUUnqgcUp=&trc9NTZaaflnb=&wQRi34UWnagWq=&rvESwCXYbZYqi=&jV8Y55XprfYUo=&6HRkP5XfniYsm=&tl7Zs3Vkmmhgi=&NGWdtrWmgpaZV=&4EsHxhUZakknb=&DGKgMxUmfdmZg=&BhdyaNXljjqrW=&Fy4eOBYVflsab=&yNQdfvV_qXbYY=&jWeYTTU_eWcYm=&xfn4NrYgddXrZ=&tvCBcWXWpnqWr=&ogzvZUUmbsbUe=&BINijeZrZUqng=&ENzlMhVsVrnrm=&J_CwlLUigndnh=&95VIogVpapjVV=&jbtnyrVnUrjjZ=&fsm6d4WUpnipc=&kqtZy9Znngc_o=&N6mAePZj_ZirU=&IMi5JiVsroVZg=&i8KH3sXqirdsW=&AjN5R5UmokocU=&RbSRsJVjofpni=&Tng5ztU_nnXgU=&Wa7BubVoUbshW=&yeORmHWgqhrqj=&Cv9VeJUisjcri=&kbpubWVlnkgpg=&gKP7wZZjmkbpd=&FXgYAvXUmpVol=&r5cie8ZWcpfoi=&tg5G8LYUaimU_=&hDXD49WpYXiZp=&pMuomOUYiUgok=&FgmDX5Xlncboe=&OLVauKZkqaepd=&k84x2sZ_ViYnY=&2Wvi6xYYbpskZ=&_l3I33WgrVVmh=&QulRIUUZXndoV=&8vP484WYnhgmZ=&XS2wrbYesXpZe=&6pnomkXdsWhoj=&TjuduqVeUmdec=&MttTOoZniflgm=&mriVceWUXjiVk=&GgAYOBVhbrnib=&gNqr7aXsYmsks=&PWLmJ9WagYisW=&_6eJrdXidinbr=&kKjwvYVZcVbrq=&d9Zt4lYmclVgo=&cfW_sSYpdWkmq=&Ci7oSCUddU_aj=&f5SuX4Zsghlqf=&KK4j9SXWUcqkq=&OAYGBqXaUokij=&cUHmZsVnsXog_=&SI96U3XdYeamo=&huCmdSYZYmrVY=&rjDsOnXlXpWUj=&538JUZUUgcbbk=&8WJ8cOZlcUdUh=&hBx_lNVfcgiqY=&EXoxj7UjWorca=&yP4grgVlUYmsY=&9B7YsfYXdgm_l=&LNdMMOVsVYUhZ=&4sleEuVeYag_q=&JC3DAdZaepmVb=&XvLMTXV_fZUjo=&SnXwYwXXdVdee=&YdI_dAWeYhnX_=&jaB26uVfqZVhk=&znMo7YUshnVii=&CX4vzKYWnmYkq=&MLtlWkWaYnlYq=&CkVsjLZqdcnfo=&uNrjlxXpYUnVs=&ZsBLOZVkmV_sZ=&YT94LAVZV_aqb=&DTeQRyVibaYaW=&8P7MF4ZhebkaW=&QXzN9RZYhsnXb=&6rQFZuWqfUaiW=&i8s_8WZYlVaZV=&dFo3dFYsglZsZ=&tTp_qkWokWp_V=&LoVDI4WUmljfo=&HGKYvmWdXloiY=&WgH2pEVZfYkWl=&RxZKWzUZnlgUe=&cKOVtOZ_sWoXV=&eHuZ8NWlhXpr_=&Edw4SKZqZfldi=&4MXEkqZspnmUe=&4_KRJVYcajYas=&LtEYxVUcpYjfg=&M69Q3wVVbYs_b=&nRwYAAXfmsfbp=&7zQRiPVdUpar_=&qP3RYsZVhodhY=&OZOwB4XcVppoc=&ObB2HvXUXeidp=&OiaSkWUrlgcpW=&lFaH37ZesrWpb=&RAg7FAUqiknVZ=&reaohoYmbkWiq=&2mlkLpWrWlksp=&vKDBMPZZ_bdVe=&3Lw9NyZilUXYY=&OqqNDWYpidpes=&jyzMsfYsW_Zof=&8oMMqnYneYngp=&RDOavFUkoebXp=&9h2QpGWksnpWU=&QpGUUZYZaZdmo=&HpDSJjXlqkcZV=&wShTfiZgmZYbh=&_lDJVwYVXUoWp=&iDtJqaUbjagUm=&5Zk9OqWgW_YiW=&zb7UPgUVgeXki=&w9e4piWW_Zgrj=&OMvu4UZWYgfYV=&_HbzzRYUXkbjj=&LFtQ3OWnbkdbk=&9pISTHYXkmXkc=&65GNJmZcnh_nU=&7zChRKXppdsoc=&xlBkCtWXcbaX_=&5l7nGJZbWsZcX=&8yNtgDXfUhkk_=&6tbNhaYsamjha=&SqTrYTYXrnUUl=&vRaLRgVWVhopj=&434oFOUdqhchh=&mrkkRTYhaYkeb=&vk_QQcZYdmogs=&sCN9uOZa_Ugns=&gTmJ2fUUfmdVq=&Vz9jDQWbkqpro=&TfSLfRVngXnbn=&ey3wDxXrnd_Wn=&9KPne7UosiiUX=&BIJQYyUprUkje=&qBglUrZcsYnes=&zWaxZHVc_rYUX=&7KagLJWqlchpk=&8TdMo5XcnmeYc=&NAFa45VgWlhjq=&V5NS9kZcrrXpq=&PtuNZuXhYbdgn=&6UdSxGVdeUhcp=&o_PzguWbUmrpc=&3jd2F2WYgemdb=&BjjZURZdeVUUj=&pyvLDfYemqbXa=&BaATAfWYsp_n_=&SXkFgRYbgcmhe=&pWTfVRWs__bXa=&YideLtUkVXWcW=&wulvcZZldogUd=&yCkP_EWcfUmkh=&VXnlO9UmWaadi=&4fvc8NUkmamco=&FhhoNcXhdqfkZ=&mullNbYiobjYh=&M_H5tfVXhbjli=&yKTBbmZUisnYU=&ATREkRYlpXgsn=&jbpgJLYrVmlhW=&jUMyXYZoYoUZb=&qJn9DDYnrbcee=&r8rwwoUhrarcp=&LC8NbIXXsVrYX=&zr6gYpU_ffU_n=&ZzIRDmYppVlXU=&ouBGrKVeso_pZ=&bvhgLOUkdWoak=&_T3geSX_eWfmq=&VbTfDzXaadZkk=&SePnAeVknqmf_=&z5X2EnUcnescm=&JyIxPdVpdrWol=&QjYnRSVb_ijXm=&fbd7fbVora_kY=&VbZW_lWldfUfX=&ZYay6fXlnYpYi=&xNWO9gYadZliq=&w32yQgUrYlXfq=&HPCZkdYimdZih=&ohtE6EXddbgYo=&89_6aOYfhefsW=&tEkuwgZ_lgrre=&XWVXUAXYbspmV=&DYAfDPYVerkba=&uQph4sVZjrbpg=&FovzSaXrasaoo=&QGiEqMXXrVmpo=&R76Y_WZeUokqe=&wQLJQQYgYWYns=&Doc4KAUjnreaa=&TMWstSU_ocrsm=&5pj4b6Zh_qprU=&H4SEetWeaVod_=&Hy2_aOZh_qgZY=&KSRPGBWhkarsc=&eGwoq6Zbj_ggV=&kACylyUgkZqeh=&AkA9LwWlsqnco=&fWf59UXosrfhn=&alnCyvVkgchYY=&iO8vvBVkXfpqn=&lq4lHWWesbWZf=&EnBQ8TZXmif_a=&XdgEiRYrWmdsk=&DYRLDJUrZcYYU=&NQJ5_gVeUirfg=&oSOcRzWefbaad=&FXsd7jXqfXZpq=&Yuoo7QVUhglWY=&a6aqd4Woda_jo=&ZemYa5YhUplcf=&QWuzklWcUilke=&nPvjurUlkdcnh=&l5l2eQXgihYZd=&tYWa7gVaZmdna=&oeTJn2Ydeo_ee=&mnqmCDYYjhbcW=&Gyrxt7Xh_nlrZ=&vNQ7sBWoUs_lj=&_PM9UUUZnV_kp=&A6OwxyWkmqpjj=&lCMeC2Yhkad_X=&_zRKnxUVfbgbp=&KaoWiKVYVkWje=&ikZiE9ZjYcl_l=&Sa_FPIWpohZoo=&4dFR4rZYWVbcs=&IeBNq7ZqUcrkf=&qxOTFiXbfYrrf=&_xFNIHUcWbsii=&uGDF2WZ_Yaji_=&5ygvDlZaqdfV_=&oKMXzQY_Ymfco=&DOfR9GXdnoYXk=&34D3adXoisgsZ=&jO6lMwVmYpmaa=&4QP28SWsV_Veh=&b_rzHXWjoicha=&Vf3LzDZqclfjq=&r9NTKCXlhaV_U=&Fnv58AVdknim_=&Q84_ugVZmbXon=&Wvw544VZa_cpf=&S82je6Zmlm_if=&WJQGD4Zqdolir=&cq2UAwUbllleg=&A444vMV_asjcX=&SYj3yoVsUi_hY=&o5fityZUebcqn=&TYmI6aZq_aimc=&I4LiHmYfoqgp_=&5b6LvmYrgXejc=&Xw44HXUVmYWZY=&8b7Xz5WqcpVVg=&zVuCH5VsdecVb=&teJrVRYUskmbX=&4GQbpQYaUsqUi=&fKJc6eXo_co_r=&LoM2H5Yoc_aWW=&_wPgeYVhddnqr=&4YzwcNVXVdZXU=&g_4mjZYZaaVrX=&8HrjmVUYjhgrX=&CFfRjhUliUYpa=&NgCIBeVZqdcYi=&2yjL2qXXgrlrs=&SNn_ohZXcZWqn=&N2dlZWUYZsmYl=&JPl3diWacjcqk=&lzuYQzUnVXelW=&qe3Gp8WfcpXgU=&A7KW3wUnlprfq=&FNQa25ZfgrU_V=&5VKL6zYi_n_ff=&Afw4f5Xqgnpgb=&7U6x8UZolZaYr=&a5rft9YeVnmYW=&uPrFeQYjsbpdi=&Yr7uaeXamqodW=&3JqONNZjcpXaU=&VZS4W3ZVcqUYi=&oECGWrYmsckfn=&2bWfdMZqmjZmi=&FpJF9lWoprrmh=&CyhihsZo__abr=&64q3BNXbkefim=&_Qy4p2XiVeqnf=&gJY5CYVrlp_Vf=&imKBndYYqgWeo=&kuaK2PZsickUi=&uZQqsZU_qpohh=&8pHKpcXsqWgjl=&tPxlm2UcrUfqk=&4XSlGlW_UcZsk=&mPWuAQZchfagX=&MWpRLcYbiiabg=&hpLcfVYfefkVb=&H5rqqqXgcUkVr=&Mna_idVifgfkm=&YfyWOUVWhocgW=&944dnjXnlYlia=&rnWU9CWVXpmck=&SBcDjpVX_cndl=&x46jP7V_ccZgg=&WdP88wUcsjeZh=&vS7d2NVqXmgbk=&nC7VvHXfpYiXf=&ZAfRcaXlW_okc=&HCpkKJZVkdUiX=&o_AVTvUo_iell=&eEklt9ZZmgibs=&jaIMFoXZk_hjV=&s2hGtIUlmskba=&WcaOY2UpZZboU=&jnVx2YZkiopdr=&naiy7qVU_VsUo=&XWof3ZVbfbkk_=&_iPmqDWqddpdb=&a2axeRV_jXgZY=&po35MCUjjrlhj=&bkZLOWVrgmYci=&evAwiGZqVkfkp=&EwktK5UfkdjVU=&wmfrDBWWdidhc=&R3pl2CWmYXXns=&3tqXkoUipeomm=&uPQbllWXgdbXZ=&2sD9L6Yeoilnb=&QtJhNzYebVUYk=&HzsA2TZfUbqmq=&REm3hJZXZikXo=&fBffXNWjpheas=&j935ifYenkdan=&bOLot7Whmelcm=&4TH9e4UVsUoZh=&cSIPSjVYhphYd=&nrrPlaVogdVVg=&uVm_5wZqmp_is=&tITep3XmjbcZg=&fejbEZZcqiqpf=&29aUIYXVlabaW=&CP6Y9XYjUadsU=&QloR7UYllYjWc=&R7fJ_DVZqYsYZ=&2nDb2XVXVoWig=&9FOSHOXfVmhcr=&ywTtkhXrqlbai=&YkhUr4Ymcmpen=&NRk5K7Ukhmqmk=&XTO7NQYZbpkhm=&CAxjTCX_pfZso=&n_heIjVjhjUZd=&Dz2VEIUcmXmcg=&wkoYrkYUrkajo=&r7wetJZkbcbUh=&8RljjsZlfqgZk=&mzlwsnYrUcofk=&g9CBtkXUcaYcg=&BScAC7Uicarsp=&IFjOBMZrUbdW_=&mf4ymSXcXlqgs=&kw3rl_UZiVmfc=&8nzDTCX_Uhfqn=&KSlONSWVjeclm=&pBs4ubW__Z_hf=&4MVmhIUsZqbfd=&T3g8EyXYclemp=&ZPxogNWmWoVoU=&so9WwNXVVfroV=&V_pMKFVsdraqV=&xBioMzYjospYU=&GpZkkVUWdfonb=&UPyQDwYanbbUo=&6AywhFUWeffYW=&blWsxUYj_goho=&I9HMNfZnrbnqn=&5hkpTCVqqrmiY=&oQ_EdJYhiqYoU=&eopvJnUoimcZc=&S73wbFW_snibb=&a8CJgHViXdheU=&4VVG7HYkgbYgY=&AgtdvlZdfoe_s=&TOLf62ZaZldff=&ZgHORzXXiWVUc=&IvGJlcXZqqaVX=&YlcN8EVZYohri=&pFMsgYZ_raiWj=&NPVXzjUegacmb=&ZweS9MVVnoaUn=&j2VKmOXr_aWhf=&7syFz7Yo_kscr=&C9SRkEZq_hkec=&ZUodd7VWmhh_p=&wM8gmcWbq_mlm=&7_4qbbUlVerfY=&dhTVTxVak__bf=&J7cJUOXkpdojj=&M526M5Xpmgmsf=&JghVG6ZqgU_Wq=&yF__8vXneodlm=&faSZEdUsqrnkW=&VrXesuXZhfgXV=&ldshZGUlschpc=&bVcVuBXkjUdbj=&FoUyI7XokXgVh=&buyBHBUqkXlr_=&NkDsKUXgppsYe=&IIaS3IYZkXYne=&kjSkmoWVkaUcV=&AjOs2aZ_UisYU=&XYOLZzUasU_X_=&hakalhWaVkhqm=&gA36SGYZUgZrV=&8d7LGKWqisnZo=&XmLRA3XoZVfeY=&GwIu9gVUkgoaq=&tItmdYU_aYkdX=&hK6aTaXdYmasg=&aetewPZoleros=&w7XecFUXdgVUo=&F2LNt_XjcXfsg=&Zw3p_HXYVj_Yl=&R7nDQTYeZprYa=&theDsyVeUcWUn=&9q264kZnbjmso=&ecd7hWWoscmpe=&_xOWj4V_Xmsaq=&wc7R7bZfUVihX=&cvmDfBYcoUZka=&WB5BlxXjWUqUr=&PcihqCVq_bani=&ESmFgoUpVZbek=&DrFmvcYUbarfk=&z_cVHhXmcpkgp=&YOKLEjWXe_aYi=&NkbEYGXjnYilh=&fZdlBWVlnXsUm=&BoWp3zWbhnesf=&6JiFeEYhVisUo=&noR4JUVloqqUd=&rRXAV4ZXcpegn=&fpxvYRZshlmbm=&9_vV4qZqekXfh=&5_fLNrVhYhihn=&h8ygfZYqWbped=&ElOZOZVVWbhga=&jyUhDDXorhnhc=&dNHuQkW_dapdd=&y5UP3UXchpmXq=&BDMKlTVgUgdjk=&ppXFiHZcWkVq_=&dsrWtgYccchor=&THM3w3VkjhWnZ=&Z2uFn3VZr_qem=&rrsgbWYkhehbl=&vBFdQaWdeZcpc=&P9J9pRUYcrrnc=&IMfQVPXWUrsco=&s6qWqQUYWobro=&IFKHIJUcqngle=&p_ebBGVjknsgV=&PIPAjZXZYYjkW=&p3Dq58ZibeogW=&J3P_8eXkrmpkh=&i49DoBVjfccWh=&bXSnbxVUVmhXg=&vqMhniZjWkUlf=&LXozzQY_UdsXb=&6qGMWqUhglf_f=&YS3U8cZXehsra=&mC4sbMVbfWYom=&896UlWWolXqVn=&5m47GJVenfVZc=&OR9eNtUUq_flc=&KmUroLVjbkeq_=&h3DQO3UhaZraq=&efXNTWUfkZcrc=&SQD9fOYpoekbZ=&E9_xSMXkmhnXY=&kIEtOIXjolg_h=&48X4KyVnrgXro=&bMkMtLWalXfgV=&tJxehiWgiVh_r=&enf3TgUVWddmZ=&kx77mgZgcYail=&T5G9TnYrdWlnU=&vlELHQWYcVplq=&CrX5AtWfY_skf=&mLY6HGZo_ieXg=&LHLQZrYnhnsXs=&_wIh5XXZrcnVo=&YpOwVcUaWgqfW=&p5tbLBZcV_ogm=&IiLb49Xccn_fr=&z2Jvc7VooishZ=&RNRwmzZqofVWW=&KaR7ImVmsqWYp=&Uh9LlSXUsrbqr=&FMGsheZZZrbff=&quvniuUnUibr_=<68lnXbhmlqZ=&J6f6_JVns_eee=&fMWghKYgaaogZ=&pIO9L7XVs___r=&nXVrISYhkchaj=&9SoL7QWYmnkVY=&WkniFBUaYmXbo=&mYdWxLUdZhgWZ=&MScu_CUpYkobV=&WQyfS_YsgrXmg=&_uzslhVnfjohZ=&MN99uDYZrqpqk=&5YGiedVXkqhdc=&FuWxLoYgYdXiW=&972BskYpXkckr=&nZv6FEYhqqUWV=&YzomsXVnmWpo_=&_DFSeYXkgXkVo=&8uKZHFWikoZii=&oijtMZXrhq_Xg=&WRm98kX_aYljq=&CEXtVWVmYaXqq=&vUdl4KWnrrk_c=&QwMao8WZbpgip=&R4zqymXnrkYYV=&GXnWbhUcoofnp=&B_XxEzViiojUp=&LU2N7lVbffqkZ=&4iAKccVlelmoX=&LLmGsEYpXcXsc=&fyCHC8Yksikdh=&xBE4IxVhpcfij=&lKMFqKWcrbVhZ=&YJG47AWkXnmgf=&qwTZ43WYgcqm_=&Vfo9ydZWipckk=&CjVTimYrdoia_=&48UcijYmUYaei=&B7EewkYYboemX=&nIiCSoZXYjUin=&fgDPTkXjjijin=&6RWMefUelipoY=&5uO_5rVqnhXei=&TXNMcEXjjUXmq=&pJOOhBYdasben=&wGTSjsXejUsUl=&ZRsSDqVUafmWm=&A_iek4Yb_grie=&wR5IgcUsbssij=&2V2oyJWlnipdp=&__YJc8ZVoiZso=&PYAOocYmesiYW=&9iErK3WhWshgk=&Q3ssSIWgXb_iV=&brcbrTYanlogi=&_V_4WvWrkmjnf=&oedPPdYllhlfY=&9vZveHWgphXlr=&L2_FofXqkqi_s=&P2zf7_UfpbZWp=&9mPO3OYhqqXZZ=&VnV9VlVn_qcVh=&NYw6HKXV_adlo=&gPv3cwWjrfim_=&nfZHpsXcdfdfr=&3B6sWxZbhYUfq=&OPqwTeYdirUZk=&UoqoVDV__icaq=&nY_6KpUX_aolc=&XkYgjeVVqXenf=&FKTareYglllUV=&u2gggWUqagleb=&mjpF74Zpjcibr=&vT5G8OVer_aqm=&ZBIjbYWgXdkWb=&DYtctfVddgjbY=&n68Fv2XgdfgZp=&fOccp3YUnhZbd=&ZVDQoTUrebXfp=&7zzrvLUWmnqnk=&ep7mPfXZpioif=&DdLPSKWYddVXZ=&XZIwtfWlhYlbX=&KodeRSYcprkpq=&yDxAHKZapgZpe=&oYXhCeWhsfscj=<MCqHVlXmomX=&Quv69wVsWZpYe=&gyFI3DXgsWp_b=&jTdWgoX_ed_ag=&GaqGiQXVframh=&HOfOZ6XYWdnfl=&I6APJCUXfrlrd=&GwKwe7ZdWjiZV=&KbYfaXZVflUbd=&tdELBdVdmpZkU=&jMLAtZYWksmsd=&ug6wL7WZegbje=&n5HDX3VimiWgW=&uWGLsIZkjmkoo=&exR4E9XfkjYbY=&vpkYmHZUomcdW=&xGoLSxZZYiYdf=&9dvgSaVpaVmbh=&iBnEHKUanVYiq=&YS6ae9YWZjZkr=&GftJWCYkmpYZq=&5Ikt3NUmdWZjm=&8jjcMOXcakpbn=&jIVUf2Vrekeno=&ISZWmFWYgfqhr=&5oXVP8YUgWsfY=&ktGo7VXarbjkd=&lZNYDxUkofVWU=&9MOdJyZ_Ugihh=&WGGMoBXro_pXU=&lM6D7eXmUbeYm=&H9I6ptZcjpmUs=&_PRExBZanYZUU=&hQQB3gUccqdXX=&RYAIEUYYliobi=&UNhof2Wgpnb_q=&pmtnlhUZrqpVW=&g3zNQGVZaXdel=&_gTFuuVjpnjmi=&Td5xjOXorfgsi=&pPWOeFVUfoZhi=&JkD8hRUrZorWp=&3ZlDuaXpbncbh=&gEVP5oXcedZie=&NldR7PUssiVsp=&BArO2gYi_mlsp=&X9WBdQXmcbcfj=&PhSdvUXZjeogW=&Au9_5tZnabhpp=&FAm4ykUmglsbZ=&FWXD3TVfenaYi=&ZGBsENUgrcWfs=&72VurOVkglfhm=&hpUa9qXdgolsa=&LIz9h9Uiarabm=&6X7XQqUmqploW=&YTXfCqVXrjYWi=&RXleVDVUoqqVm=&DBvoS7Wljnhdj=&DVrPMvXnaXjnd=&4lCtN9UqkWnhp=&chH8Z5Wh_Usge=&VPgxSgUZnZhfh=&ik9hQUUVcgYWr=&swlewvZdVf__p=&IXSry2XjpqUba=&K6SXn4VbXffrV=&d48yL7XhdedVY=&3S5OSNYaVkgpU=&rKwdFTZbUYfnb=&9my_wIY_dXZsY=&mCbg3xXjqjcnp=&D3CNwZUg_Zcrs=&dTZ52HZY_diUk=&tMXldgWcYhmWo=&z8bvjqXZgahpW=&z6YRaHUlYUYhX=&yBJLFMXmfXbhY=&DG9GltYViXWgo=&yTKU7vUgdglrY=&B8l4W5VjUcjkY=&MZMftAXe_dleX=&qL9kdAXfdnjgY=&wu75WhVdg_rlg=&udGj2RUmWXWsa=&Q7plUNXYjVrgW=&5Ji_bIZeespcX=&_hlprfUecWpXg=&cmGA69WroWUhW=&OfTqjUWrr_oZl=&iySK93YVebcUh=&zODV4nWYarmlm=&LpNoaRYe_bqiW=&nLNXqOZsmWbhi=&SRKdE4YgVqhpr=&QIrccLZslpbip=&m_rWO9ZsXsXlc=&boXhORXifgmYX=&xdKtKEVaoiaiV=&ajG4UxWZpihqX=&gJNdeQWcZdhiV=&lXQZ78UVpUWYX=&z5_nIiW_leiUq=&dza__qZZiXhpW=&mcBCFNXqXloZq=&WHPUVeUrgceqd=&a9K5KVZrqqgkc=&A4VhFWXUbYoWl=&pWaFIrUiZrWVZ=&7QBj7BUUXceXe=&z45A6OWXlokXj=&6ZdxxbY_eVXmh=&k7lDZRVrjdjgi=&cfrfIUZeUl_jj=&sBMghQWiamqWp=&RzcmvMWqormqd=&2r3iI_Uksbrf_=&OvQBYHYXYWWX_=&5ABYUgZjlgYWX=&3SklcFXprUaqi=&r5naPZXYnWobW=&VowBNCYVZdaYr=&NY4wIIXpebboj=&hoj7guVkVWfco=&l9F2TAZYgcVns=&KpoEYPUrffelp=&oPtPWsUnajppU=&ND64ttYXrrpjg=&FF6swWUlocmaV=&iYYbqUZcjipra=&fEjfV_VraheYU=&8qLEfDWkpWlmf=&Y7TGetZ_f_g_p=&AI2cJ3YmpVgra=&nBmgwFVmnka_i=&oGI9GzXsdaUnf=&_HaMPrX_emXhp=&fYQX7SWeldZgc=&VQD84wY_ndiYX=&2rCfXkZgUYXfo=&zsmGJnUasakrr=&uTe2gGVqkspXq=&ajo6EoUrklefs=&KQTYLjXdsYdsd=&t6v_2eYcokbWs=&HUMhzjWdfibXX=&ObkuEfU_deihb=&V65DtCYqgaXZl=&StJ_ysWpffVjW=&e3CkMJWeYngdm=&eNkGS7YsqUoas=&6yTnihZYrYmjY=&uHHSwcWcWYecp=&rzPNEQZkVjnlo=&NTwtmKUpsmqpo=&vbXGFCVcdgZdl=&5_hE6qZgeUWdf=&d2wAvjWnrWloe=&eP7yLSUrclWli=&EJ_RziWlrWUqW=&RA7CA6UWfbXUe=&Z75lkyVpiYXlZ=&LWKvkAYYmfgWo=&gVA5neVXbekXf=&D8qDOOVpfklbV=&v7EaCgYiniVqa=&7zXUfvX_gsnXg=&ZZpxtRUpoiher=&WiOuQGVfWackj=&hMJJtqYgfbsqd=&fJRFbDXhsUqcX=&OBSTXtXo_bcab=&BxCz5lYWqsjbV=&7slm7PYpYZong=&IssbA2ZViUpfb=&ylh_FCYoUecUY=&ckCtcwUejdbVe=&uWXqPcXbgqgbW=&qqg6j4VZnimmr=&wprxlyUkfVg_d=&xSY3gGXZlksgd=&U82HXtUkeZVrV=&pDlyF6XdohXsk=&g5nJ2xZWdemmh=&J2SAR4WcfcaWq=&sOimpgWoYUXjW=&7xzCmqUhVhmZZ=&z3cLlbZrqWUUp=&UrAyIyWndrehg=&tBcGPSWYsdbee=&OifOt3Wbbdfjm=&HwvUiSYhmfgfY=&49UW5UZVonmsb=&hMxv8KVnoe_ZY=&dekLt5ZnYZjhp=&ysD86TVdlom_i=&spQUS3Vjqddhf=&SstMN8VWYgppl=&YZCy2GUXjZqqY=&wb8NDlXsle_qi=&Ib9ySJUogjlpk=&i5Nc2KZn_fWkc=&dFXAqtYXspanq=&UGIZRMWYqsYad=&U_AKoIWdnZdqn=&HFtSl5YenmrYr=&lhKAhEVWcX_nn=&uB_ThSWganZYc=&5c22T5WhqVmZl=&z2vYI8UgVocYe=&kUHyATWgWXqiq=&4eo9mAYahdnqp=&OwKlwzWkkYYgV=&8koF4UWa_d_la=&DxrDdBYnjqnnZ=&wa7aLLXZhspkV=&dsRyEbViUqpkW=&Krdct6XsUo_kc=&CtKNynZjVaele=&IohU6RVjsniVe=&ANZPtLVYmbmbb=&oYFK8qZlfZYcr=&xpCRCPZmnsXbp=&mFtWBVWnflaek=&FU3TzLXjXnbce=&ypAOb3Z_scX_l=&J2IOJwVssehjf=&G33psFXUYarnW=&eLBxAzWUmqbrb=&q4QhqlVohm_Xf=&XF_YnjYY_mpmi=&A3snpUWiVipde=&gUauI2XaVelsd=&2JtvYwZdsnjUb=&2Gx_BHVZf_ddY=&GPJmjsZlXnedV=&EI5OTHVapmiYd=&73vXlWWshlaqs=&dnT2mrWUqbpfl=&6rb9ZFZlsVajW=&qrC2pNYfnVfZq=&Yl4J_xUekiVnb=&6huslmYWrVbmX=&ILfXy_XUrXWqr=&7HWaweVncgfsl=&OwwwpZWdbVeai=&GGmUPaVloandq=&gQTgh5WlageWq=&7WLgGBWqVmepl=&CnVeskXaXqVnf=&KhEVLMVpc_jXm=&DV7HEFYXaZprX=&KYsK6AZmXrnYc=&_W8AWZZqZhXlW=&ied4x6XnsYikb=&2XtQWkZXWsWdX=&d7RXypYVaVidW=&Qf8xIJYdjeqfk=&ExubulXpnfsWe=&XHyVexZZZqi_g=&wg2rVFXpqp_Ug=&tUYHHuWmYblkU=&97UhHgYbfVrrc=&j8x4iHYilrUhl=&zQSeZFWlYWrgW=&Ehmx6MUVpgshl=&9m5kuoXfXi_ge=&zD3ZsAWsbmjsi=&kH_dlNUfeanjg=&5zmtXMWbgZn_j=&TEffirXmnojZZ=&j9DAcXXicY_WZ=&a4y3LNZnihsdm=&r8tafxUlfZsja=&VNQrlfWhsXYgq=&Cycg7TYlgVmpV=&aeofh7YnhiUUZ=&KOqiYfXgomUfa=&2SSqqEVWaqjk_=&oKcf5RVbbaeYU=&W3bgsCUpefaoU=&yi79bnUpmplis=&fC_dc8ZYmsqej=&LwFs_RXcqajXn=&O4sjtNXrXnmbU=&fOTeiaZUbfqlf=&6Jp9rdUooocWW=&ZLa7UaVWhjsjh=&rp525zWfrhZ_d=&XnZE7gXckYWXe=&_rAY9gVmsWbam=&UOiMewYgomi_l=&Dm_wCTWeZsUec=&yTxeniUdejnad=&n3PLXOXidqVpj=&K9WqVqUn_Umji=&DikMUUYabrrel=&4vPPttXfUZbcp=&23lZP7Vomljsq=&W7FdSbUmnkmkZ=&uRUUPtWVrqmmY=&VE5DMHZbmXomd=&zqeIovVV_drhW=&gRvHGBZkegmkc=&STd7B_WmdYbma=&lZn2VzWdrlcWk=&UHELMfYYUjoXk=&RUEhf3XiZ_Vcp=&gH3kUKVas_dkg=&JnuohWUbqr_lb=&ccr3qNWlfiZrh=&xVEyboU_Zsa_Z=&hQFH7XWgnqhiZ=&84Jp_FXkorqjr=&WnleQ_YUqWsho=&RNw4l8UUYXVdl=&IrLlpPXsW_fcc=&bt_5ImXdYmlVp=&ot6zrOUZriipc=&QevOVGXcUb_Xi=&2VJfQeVsoaZrU=&SlfuiHV_Xhoal=&Zucq6bUYiUbgd=&S_ODwYXoUeZlV=&bfyQ5vZroefdc=&_cBY9RXjfddga=&njAiDZV_ZpbhY=&VOWjnbZbnnsYh=&2tolS4Ymfekjl=&yK9lvrZWhbebo=&IWIo23ZlefrWg=&WaBdh3UinaZqo=&vsC24kZsqgaXc=&TVdYewZchhYVi=&TQUZyYXXYsXlj=&RPpM7IYhWWcYl=&u_8VHwVliVrbd=&dcDZUNVqXrhaV=&RbLaAXVpYXbkX=&bo_7BGWXdXigW=&cQzWIFWdmonVY=&_GUq7CY_ignll=&bYkOztWeblsma=&YVm7f7ZZrakpf=&_dJCwIXribgnd=&LLRIJNY_c_qkq=&geLUfMZpghrcp=&KpJ2a7Vkmolks=&vsUHSwYhUZmj_=&qne9p_XbqVmlh=&KNUOkxUj_bmds=&7MalizWbVjkjj=&aBYHDSYiWnsfs=&mdXELHYsrqmci=&G6SfTWWdhhVVl=&AWDTqFZaoX_lr=&d99EwvZigWmjV=&M9FXQsZdUgZpl=&YOZIjKXdmjibb=&XH4OUbZZrYYoo=&7zu7BhYl_pinn=&qNyVvuYjVVgli=&kDnZNpXWWpqgo=&5lZVdVUUWmspr=&SHdx3dWldX_qo=&o4C_4LVaqWWYf=&4hWIAGWkVXgYn=&mBZ7xbVVgggWf=&RWqIwhVgpsZsU=&8YYTs6Wkha_ah=&MuU2oeZisZVUj=&A9o_ZhZUneUXe=&BnwcMRWbWqdia=&kqqTUvXksneUb=&n45JcSVikWhfb=&uwJZD9YUmsqVh=&j276EeUghssal=&loFrqeYimlWUj=&hsFCq9V__fbbZ=&lm_9dEVpilrlm=&idyCAdW_gibak=&y_vohnYVsqqoX=&IQbrd3UV_VrnU=&ykPaWrUmasg_Z=&Jbwsn_Xhngelo=&9CWKIPXrssV_b=&toMKgFUYUm_gV=&BWLPrsWcmlZrW=&52TPFhYsdsoVe=&aoT8ZnUarYrab=&G_4QBzWmgbkcp=&MjB8n2Udakqmf=&iXjafpXXbgZaV=&bMHUsIYqhVosr=&V48NukYkrlsda=&uruJIKZVYcorW=&bEqavjYUoqkXl=&mVPq3IUqspbWh=&vtCPzwZihbnqn=&95Yx6PZeXacrr=&j6YIILYcrrnXm=&WQS4SRUfqYkmo=&yQVKBqYqcYbln=&82rd8yYalnnsV=&F8du7hUansiYo=&cLTFOLUaajmqk=&iMIu8FXjrqsmc=&LoicZfXYki_VY=&geCTJWWklXhdr=&I2h6sQYWkXeaV=&XrpF2SYYqsaXd=&2PvOFxWrfXneg=&xZp6BUYhdVklW=&TIyIZ7YbcUVjk=&mfHChGVnbianY=&BKXjYTUjZjror=&UCV_cPUniVZXb=&vwm_IWXadhcin=&yE2ZOiXclpVij=&z8cBXoYdrpbrg=&eg8ckyWhcrnfm=&5qsSMaUYdghen=&O4s2cIUgsi_Vc=&R558XMVogWqcp=&fJVS8cXkXcdrr=&dtZGUGZXoYXVo=&DKUsCUXkfqXVm=&YKbuAuYa_rdcm=&V6lCaeUqeshne=&59z8wnXprXoik=&RfBgXsUaYlZYl=&jwIH5IZUVnb_j=&24cLDCYsdeaUs=&oaBQWKYqbhfpW=&qbaKe9UWWWjlm=&Yi34CPVWjiegZ=&OEhWMpXUaiog_=&PEU9sOXhkUhno=&VEWTaeXejgcZk=&IjLipoViiiWpc=&I575yTWd__cfo=&DDwW6yYWpsohW=&PVlWu9UUjlogi=&2aS7TfWjUkchm=&Tmfv_5YYrjVni=&xwIRDGWlksiaZ=&PfftLPXiUjork=&tGe4zjWqoekbs=&sKCrDTVXiekUY=&zJVX3BXY_p_We=&PBIh4TWWeUsem=&dUPbzTVhiXbXn=&krkiUdWaigsdg=&jySOcqWqjrcoa=&JBjHzQUZkorUs=&45MnkoZVpZp_U=&JRuhUGUeh_ipU=&LEYoatUZUpleU=&bG_B77YoncUld=&gSDQRKXUc_brU=&B59h9HUjfa_Vr=&lwn7GlVZmoUjn=&ftEQT8Wfqh_VU=&TtpzUvWWnfWhn=&fGQb8EXUmmrjn=&gx75XIZcYXhrl=&Uspir4XflWefm=&YWCk8PVjW_nlr=&iwhWbfXnkWalh=&ZF_RSAYfscXgs=&gF5EbkYegi_YZ=&NSGzESVgaVnYq=&yOvKNoVfrVhdV=&7NHkDQYsjZpfa=&f9wnLQZVZYope=&2QKKMRXknghbd=&RUg66yUbXUgXj=&wvvmT6VXYYheq=&GRH7gvVhsiZrc=&dlhmDVXZZlsic=&XjxkhYWWeVoXj=&2pD3epXgVVpeV=&RFbVbwVYlqpYh=&KWKAyjWssmace=&5oyGk5Wfgjhsi=&93pFE9UpZmh_c=&Z85a68YdaeoY_=&fmGL8pYWiXXVi=&W7WPzcVmboiYp=&LEbTJ9XsoZYmn=&4pgNJlYqcbXa_=&ytWclGZmmgjZY=&Z2_F8LUnosimn=&DagsLKW_nedVs=&OQEStrZUcfida=&_zeUiGUrcVnns=&5AqlfXYgpldqj=&8wrbZbVpYdggV=&k8ChmpX_fZqmf=&q5Cmr9YWZkoWf=&bKbuL9WarhUiW=&2XX43RYpVUXYr=&VpPAUpZcXhqbj=&MinU5EZikrrYj=&UiDHQVWXaeZfh=&JLU8QyXfYqmhh=&u9BNZKXiUnsVh=&SADt3jXlYdYdY=&GsyhWoZmkqUhY=&5jCDtgWZafqVp=&5Kjvp3VrcUrXs=&aHZ7BaY_kqYZj=&RkRjD7X_omYXb=&7D8BWzZbW_mWn=&gc9V9zUobiabV=&EwOm7JZembmbr=&HOV_hFUahcqjh=&GG75RSYUjpcia=&9lpp_JWWsbXZi=&2s_QWWWlmdklZ=&dG7nZPUUiXgm_=&YAbPwZZmhpXdZ=&CPmG5kXjZgdpb=&9F_IVcXgrimaX=&zZuoupVbpsejc=&zUrpfIXhseVXZ=&I4R5EJYqdfbns=&2c_5h3WgWddlq=&Tx6oDAY_Zjfmq=&_H9IONYhopmrg=&_AzuzRYXfUlqb=&5aovp8Xpkmreb=&7mfSLfVqkea_j=&GeL4MkYUWejnl=&ghMRZqXheb_mr=&MNvxcRYqZs_rp=&9eI9qAUZesmbn=&OQN8gJVgUpVsr=&M9fTJFXYr_aXU=&XqSZ9bWfg_Wre=&nPsHhEUidapiX=&foT7onZprekor=&7t3DJHWa_afYe=&4hlw8uYnifUbU=&AlU6UsZkiadir=&OI9HoOYXif_bb=&33rSqXZeWYici=&JnLBZCUdhXbhb=&EiTKtCWsUXjVo=&8q6eBQVrVrkWU=&FXmGDuYlVpZlV=&zq3caqXUdZgli=&Fqie9dZmg_jYf=&6Vuf8TZXVpaYW=&KScN8yYe_bWjp=&jAh6WyXWWZUVd=&qhQJOlZeXVVXr=&YzmzIMYcmjaVh=&SwkIOAYcZfnqg=&WGf86LXmbjqdb=&9BBx_nVUYnjVh=&lASl4AWZbleif=&wagPKMUi_iW_U=&E_A5rdXdoWnYY=&QNtyl6XXqbVbc=&cPv8ByXrbifkf=&5XFntsVbinnbi=&D2NfbdYhhZkme=&lcMRisXgbilgq=&aHCv3_XZesecn=&X3HuncYcnZonl=&Ql9eJdUnfkmXd=&z5p8jKZlZZbXf=&ccRuiPUXeqdds=&UT3S4jUikfram=&uhajWgYjYrbUc=&DicCSdUodXoiX=&c5V5LcZsiYcdl=&b_SjoEYkpodXi=&qq95oLVeqhqmU=&3R7FSwXdlhmX_=&rsJXjNZbqYVZa=&wfMRHYU_VchiW=&P3pFgPXeZcZld=&Z4iFAqU_ckZUn=&BsLj5ZVhWcssl=&aBhRBpUajXhpU=&RUEun4Vddqdbl=&tNOEKoZhXlUlg=&Z43BViVnicU_r=&wz3g4QVnlcnds=&_xpEptXqopnXp=&E4CMmHVUfdhrU=&dm_V4LUhilqXo=&on9pT8XdolifZ=&tA5XKDYmjiqaf=&ZfyrvpYlidYUc=&jWXgZdVchhYsg=&fEoJmdYZfhqol=&heSMu2UfdfZpW=&muJouJUY_VprY=&Ve7NEHUbiUfrh=&oITQ3pZ_kYjaX=&gCEdCuZUcnirV=&cBbgNLVgcbXXl=&BxrFTTYb_dpac=&V5CvTEYbYcqba=&yTOMaQUfrYhpc=&DNsnMzUrhdXUb=&5Cs6DDZYpesnZ=&ctkVPPUYs_nnf=&24OXLQY_f_oYs=&OoZfIIVgkUoUg=&FmG7xqZqkmesq=&NWxQVfV_lWhnf=&24lieeVUsXqkW=&_gY6uJUmYjXsX=&L7K6aQUqjXUaV=&MHl75jYfUf_k_=&3wWCnwZqsorpd=&ODJzPnXldhhan=&V3T3ccZhWbUmg=&EYWegyUlaf_bm=&gHnE4IUmdlWUe=&SXbT2OXaoacqW=&LcprPcXWbdWcs=&iGh3HQUmscpmq=&_w6KgZWsUeeqr=&w3J_eVVlYXVpk=&RDsXsgZfafsps=&2EtOMbYkfrlXg=&3ontvqUhrmfXW=&ecajefVf_lamk=&TdpD2gXosnpj_=&fnDSoqWsphdkn=&aG2WYSUWemWqc=&ECAI7xWghmWXW=&mzgKINZqlfh_X=&XYkW5nWqdUfhm=&WjpJRtVaflYYZ=&7_TM7DYjpjUca=&uuoOV8YXcmcVX=&XgXE8BWeresZh=&FpHlqXZjdsshc=&L8cM8WWkqZdck=&ms8B3YXWhqWop=&zNt8C3WXbZfWl=&Rp58zaXpdmVdq=&HbiZ7vUi_brhq=&4WRBRlXopg_dZ=&wJYacvZofcqYb=&YhytbVUaYlbqf=&LNM79OVlXobkr=&dyEXCLVbceUae=&Y3s_qFUVYjrYn=&yew9j_Wg_iVfg=&83VOvmZiVfsVg=&AUMNsFWcknjjq=&LSRnZIZeZcanm=&EKJdCVZejYjYV=&hHTBnvVljY_Xn=&8wTBSvVdfposf=&6VdSwGYYpldXi=&pNAniKUioVghc=&Zc7WfxVZqehaf=&Ya4rtsUimliZc=&BQ86kxZhVkcma=&Ks_kP2Wggr_Wc=&p8CiUxXekejqY=&F2wvdfUVdYlgX=&798w7zVsakZhs=&KGobr6YUXYsXo=&a9iYviXrhZann=&VxrgGaZVpYWZs=&oPRzHwYdfobcg=&NNjmAQXZcjfYi=&qNljs7VhnWqWZ=&ei8dl8Vfmnqrh=&py2SODVYYgUVk=&ro3MscVoqaddj=&Rkp6dAV_UkdWh=&qP5S7tZoqcrcl=&ynjRn2YbUdlsZ=&dOahxkXefqnZc=&olH224Wgrjheh=&KTNP7vYpXihcg=&zOlJFIZpjrrea=&25w5UUZhnZmgo=&WsilDIZngbemU=&OtpkTcX_soUcZ=&y8vdclZpbhq_Z=&E2MN45Zqalpql=&tOtTjsXcse_gc=&ELWjYvUdZhsVq=&J49OlYUjWgbZd=&KUjLiBXYjXXsi=&qMw7UmZ_Wqrpk=&ymT9MLZghajcq=&3xG2qXWkqihpe=&CSZHmnUfdVbjd=&xraxLKVZmesob=&u6SnWvXbabpo_=&EncCidVjrXjYg=&fp97ydZgpocdZ=&Wjx9jSVjfbiWU=&K4bUBzWllXXcZ=&HmyHsPVilgXop=&b3At7GYXeemdd=&hBN6h6Ydfndng=&Wnj_unXmjcnZY=&oIwVRzYilWXqo=&UANIgIVrZihoU=&fz8ua7WXgUnsU=&koZeqUUm_fbYc=&yJx8VBU_gehVm=&uIaN2SUmcXrVm=&s3jWNCUjWmagm=&zDcAkkZeoYUjl=&EV5LjhUZjeqbq=&hz_CAYViUZkmb=&4vjSRzYoonZhp=&wUYY_YWpjiqYr=&8c2XYVZnciqWh=&76rroLXkbesrk=&2MGGWpZZhZcnk=&YQVPbgWneUjlZ=&d9q32pUoWVanU=&xRkk2aYdXbrrX=&LOs9QFU_qkY_b=&NJBwX5WgrppoU=&mG9IpPUXZsVlV=&QyXU6PXcdigUW=&JpzwgMUhYpYZn=&e7vXB6Vk_afl_=&T5I3ydVVWjfeb=&xyHLXWXganYmn=&cJnBPxVrieXZW=&CyZOH8XWbafWd=&ozaWIlZrVlisV=&x9Bd7ZZfaaZUg=&Uus8vrZpcafqZ=&fcw5X_WgsXfoZ=&aajACWXlgWXqb=&AuxDAjWWsgUoq=&psmHKKZZokrnp=&9s_Tt6Xm_b_im=&RwlzUwUgprXlW=&p6qrQoWUikXkr=&HfFmB6YWVgbjj=&ADP6vXZdkYmfV=&e5sZCjWlobcgd=&Q7O8fAY_ZhlYe=&S3eNulZqrsZg_=&IqD6lDVVmpsYU=&hpKtHIYgscVrf=&35rzfLUdkemfl=&r4SzCoWggnnWo=&GYsYsCWVW_nXs=&8RWXAFWoUfgZV=&fQ_e9pValbimg=&IUTm2GXXnXlZl=&iE7BOjZpVWhnY=&M7RpuBVimhpr_=&wEQyDdVmcriYf=&3KAeRdYUUYlok=&K_bYktUkiXmoU=&2UuAE5UnXlepq=&IecIFUWf_XZVo=&7tH6e4Ufojeid=&ylmasxWsZjnei=&hIwrYNWlZsodn=&ZONFQoWcUr_cr=&fhTwteZaZbemg=&xG_lMRXenpphb=&3SceBIZUXnXso=&nmoLSgUjWlbUg=&9qPQucWodhhVk=&e6BR6eVYUcYqs=&vpqQWYYsUmlqm=&5TAhSGUWljboa=&3wOQudUo_emoq=&d6QeliVsmmmkX=&4NKtakZfVokpq=&N8lwgPYpakdeZ=&bTGnIrVWWgZ_r=&kL3iicYsqZZeY=&XscAE8UfUgfsV=&AqH2cGUljYl_q=&PnPkziUefboml=&8AGkAoXWaVZp_=&WQaVysUhskcjU=&Iu_mscV_jmfcm=&5xWFSLWjcgoYf=&Ee_mQAYkXWbip=&zELiWxXViacdZ=&I7WNnWUjZYliY=&nYLvSrWjcWWsq=&YvdxGDYnnrksi=&C4LexAVsVfZnn=&qL8sEQZeqppXn=&daz8GVVkVYamh=&AcemNQWdbUgrr=&P7bTuIUgaskii=&ZG8ttpYjhhqih=&PPvJoJVjheUsX=&zKhytSZa_dpqh=&yRtEL_Xl_nmjW=&hLiKXsVrZrVYr=&yzzFXkVddsZmj=&YrUA3WZnWYhar=&gIQn3tUVUZrhV=&dR38epUoVehWp=&M5Bn8UZsqVimm=&wpklLhZ_iaWbX=&D9NxBAVcrYkef=&_viiOKViW_iba=&AQNh4IWceUqlp=&6Z4IZsZeXZrjq=&6SdfLFZc__miX=&4tDyzOZlYkUUh=&roy_cQZZXofrn=&4J2dw3ZXhahXe=&JsAEW8X_dhagY=&J75ZwlXoqsjo_=&GnS3MSUolVZiZ=&m2T6JaZlckmgl=&YwbubVZWsednX=&79Hq2iXUcksgU=&vMMHbOVamadsg=&QN6PEjVegc_ac=&4HnbSUZkbYjpr=&8ylbTKXUmYlrW=&urlhmKXojjnnh=&F4EJPRXccalkW=&grsH3YVVfUcdp=&MjIlziZebcf_n=&SZDopVWnVqZpZ=&efBQwXVnYYUjX=&4uzum_Wqgp_co=&GqGEsiYh_f_fU=&q3g94AVZqhpfl=&TzTQHHYYbdo_o=&b_zio5XgcYXYr=&cwGmN7ZsclYci=&OujTTCUan_Xom=&_tP5X9XYspXmh=&XEZVgYWr_dhbo=&s6pp7vVghVelb=&cS5HaFUUebgnf=&F9pTvtVUaWgnk=&4BSS2GZjWmcVV=&L87SI9XipYbZd=&5oWc7jUrfjjnX=&C2CYmuWVbehXY=&BsvXU_WeUomqc=&DSTq3cWqpjmhe=&DjuuQfVdmkcca=&4pLQPyUeVhefg=&hVuFumWfjpddf=&9RtwCRUonrWam=&Dr3_6vWpdbhcf=&G5lyaTWkjrXXd=&P7hsY8ZhsnabU=&LPbTWMYXegsbV=&os7cA6Yhrigig=&BLGu5yVhkgasV=&ujs_46UbaWarq=&UqUsaDVdqqqZn=&4jQK2nYfe__kY=&7pCTKJXYjh_fi=&cDirrSYpjWckq=&BolKHHXdgYirm=&tkIJzsZhenZW_=&kHLvT5UZ_ngjY=&hAOBoJXikgYWl=&QbyUWKZci_gbU=&I4CuYvZrkfhpo=&Gf5N_CZidrbZk=&PGTUMgXsfcoVk=&L2LvcpYggqpdc=&pyd6H9ViiodWr=&goDUF_Xooecnd=&lABDmxZjcgoVW=&WaEZfbUXc_lck=&Pa9rXbXehaikV=&JBhGHAWrU_gck=&QLTsfrUnkhiYf=&eTkPasXq_lYjW=&N7jft2U__dZcU=&uxkLa8Wmjgoqj=&peK89GWnhWiip=&69SGj3XcX__bo=&SPryQLWpbiXVW=&yJVX3XXZUsVkg=&FanO4HUXYhYsV=&hzsnZ6Vqkok_V=&dtWZXKVdoiead=&o7ms3EUealmdl=&CdnhuVWhbeYZk=&GMBaInWebeXUr=&3iEiDOVsjgaYq=&bRoBo_XaiZYiW=&VYPppRWbklWaU=&ZsAg3TYUVa_df=&ncJPXZWedVpfm=&q5zWH4UrrnibY=&uCM7BeVjpfZrW=&nkduOaZqpbUZh=&oU6rdrWckeahW=&U7KcucYkiXjUn=&HTEsxpWWVmWVb=&dbRCSHXs_rrqk=&A4S7daX_qklil=&rhCI2XZpgfkek=&jaxNQoYnfqnri=&ZI6HKHUZinpas=&K_4rXaXjdWYop=&Jk4QiiXeoUh_b=&BM7mI6YXmYljq=&cDtuJuUgXpqqq=&wpWswqWbWjpbY=&XtwvWxW_Zgcai=&ZplCwcXnfWUrW=&Z3NRu9Yhqlfdc=&HwrbuZUbaXmdY=&se_KETXpYahpo=&hKaDOhWYU_bWZ=&NkcwVLUpUZoqc=&xOsDpRXilhcWe=&TpKy3AZqjZYWW=&EDRwc8ZojjWrc=&Rou8ruUhZYqa_=&jILzMZUmXXUXo=&Eyn8KrXr_Vmeh=&n4tAoRXhVlUkl=&xLQZM8WZjZnZa=&bHKlKmZUWjkjp=&GBxYf2XViqhbb=&6royCWYlcWYgi=&o8i6R9Wfd_sdr=&XCdKssYXa_jqp=&33UZA9XbUhYlg=&MigmKiYmjWYsU=&EYIlsnUhorbrr=&ApzHmoUbhlVVj=&bcagWlXZWaW_j=&UydHoPVrc_csk=&Xe63JxZnXaXkb=&AU3buGYlj_qsY=&eQeiazX_nmjqp=&gozOj7WalbhZV=&IYODqbUfUsafd=&eZGANPUbUqmnU=&7wFPQKXVoWkqj=&RrpsjaVqXqicb=&mgwbURYjaooiU=&pz3QCpXVVZhqZ=&Hu9F8qUWdemsV=&rlwBEhZUbX_k_=&jzvQqoYprUmgW=&DK3I4WWarcsqs=&Hb6xW5YprZlpW=&qR6BZTWcW_sVX=&dZQHvTXeqrUig=&x2pWrOVccboj_=&cICdefUjYgijf=&AjARzPYdhjmgq=&yctjGUYajgbhs=&ocQzCaXjgpf_i=&9zlWKBUXjbmfq=&dT4xkrUoVbqkU=&54M2gOXaWceXn=&o6fkcLZniUkqU=&DpIZpeYeoYaab=&wx6mFQWhciYVq=&hrdWdSXhjfX_Y=&kc6ZdBUrdsjYo=&jZCSFtWqfmkrp=&uRbFSQXXg_VXs=&JP2n9vWjnbVis=&4MvmGwUZbmlYW=&XOCPrAXlnkfkc=&jsgGDUUdaiook=&6iImcnYeqeZln=&LiQYAEUsbnYpd=&FR9uY6YahqZdZ=&NqKyywVggVdin=&MvGC3iZlgXqip=&z9AKeuZbp_UbW=&sgwMbfXlVcnoj=&HGC72GWUZfoYV=&4Tu9G5Xqcpsih=&8yqjKBYgYsmdj=&x8g72OYiUbbsU=&2srRVHVXqibmr=&2pfXAdVniUgoY=&bvCrvaWhfs_pW=&gpvF7gWYcnenY=&oqq_s4Yhbfksf=&qnVrliVcfafgY=&jzYuvoXViXdgo=&EEAn4KUnZpWi_=&k6PUqHVYZopgp=&U6o2otVriUdah=&vKBG5TXfinX_m=&bWtAEwUpsdkhW=&fBcR3rVUe_Ugo=&zr3hExUrkiVpo=&T8z8N7YqjXkYY=&ufanzAVkqfiaa=&7hDEnmZfgiiaq=&l_F3cGYWnYjVs=&uqqALsYqfUXjf=&mE_zXJWjeZfWX=&_DT6TKYUZiWfr=&JvSyIjVgaelYo=&jVyZHHVgrlUol=&5vkwqrWWkhgqo=&AvKDZcYefkeb_=&RhWK4kXU_hdnk=&ot6PwZXimsiYc=&2hZsjUZjVhjYe=&9HvhH3Vdsh_gq=&eteKkIVkpUfcd=&k5xzvwXdnnccs=&tO6owLVdkg_lZ=&KV5tMlWZheaeg=&XuIUibUrhneXr=&BRQEqUUUdjqof=&M5DNFBVUsoYpZ=&ULPAaoWpdsfoa=&BkjQvvYkY_WXc=&weIkkQWhaka_i=&5xIhXaYVhghha=&HaxxYQUibVgfr=&liFHDuXoXclgg=&ip2IvfUplViVZ=&SBkUJJVdUsii_=&W6nbAmXpYpfmo=&rrJ7TlVVZVZfg=&ZYmWQkWmgWpUh=&nFcTgSZlfkhki=&abK2fVVWobabg=&Isygz3Vlki_ZZ=&ijnXFLWblscnh=&tVGvKPVqYf_jc=&MeSZESV_ccbq_=&3XShYNYkfpenn=&DDPDVJZmjagZ_=&_A6e_wValabcd=&Iz6ZscZ_jspXU=&f7hv5mUkfalYo=&9ktL_NYZshnkf=&Ixc6ejWrqngYk=&oPtwrGUngWgYn=&fnLLQQUUpsbnq=&iviLYNX_ZYshZ=&Xvnn6dWdiiWc_=&W2UjEnZ_mbiqU=&oh8gS2Ubbrasp=&tReCArXeZdcgb=&SX8e6ZZcikdVm=&iEfSPtUWlbYci=&4TrLVNWomlZqZ=&AZKW9xZspehrV=&ydF6A8Wanl_od=&oyQCgEUcjmloh=&mJhespZgX_qXl=&uwifTOZggXWWr=&prU6m_WWecknp=&RsJNQAVYdmUlr=&tvhT_FZgkbesa=&XBuyWpWfgfjqV=&GH3NnZZpZa_ii=&Y6l_dXVVXYsdp=&W7TXprUpnfejX=&yzfRsIXYfeVjq=&W_E6jqUYppqYf=&fpeA6sXgdoXqp=&YrPJFIZmfZVrs=&qnVR5QWWpmUZq=&xJLwa8Zhbqpfa=&exrWZxUUZboYb=&C52sOXWipZson=&eZZKTPUWmsgeb=&dfNirtYhnXdVd=&6HsjhjUcUUpUX=&kXDusSUZYfsqh=&dj6d57XYfVjbY=&gUy2PeYdWXggb=&GKeYwBZZrl_sk=&tTYDjMYiXmWqg=&Xr7mapXqXiXZe=&I7DlFvZfnebqr=&ABekutXUsbqrm=&DCIaSmUmZmkVa=&nPhTUoZVleVpq=&SYlVItWsbdZ_X=&3qTo7jVbYfarp=&L4WDjzUbrjYbm=&j2Rb6gVddV_sW=&umcruqWoXXqVZ=&IuvwePZjdnWmb=&Cz3OREVW_cXcp=&6RTwlOZXfnYZc=&XB9L7cZjgYZoZ=&dxPMmLZ_WXehs=&VI8umDWoldcq_=&Xj8mwJZehhjbW=&k4D2guZnifUgb=&WygJqkXkmsWni=&GDHc7fZYsfrlm=&ToudKHZbnZlpY=&cVB3vyWgYcsfn=&hmLyNIZp__gVl=&fil7cZWcUfYad=&nIxIX8UXsacpd=&57YWGGZ_emeln=&eBEWieXrpWfmm=&Wof8deXoZaoZn=&EzVczyXYebUqU=&6QEGvQYpmifgf=&nF_M63WkXlpcX=&TsfqnLWWdqZj_=&prYYoTYpfjelc=&SOZ3E8WZZgllr=&uzuXKUVWkdone=&LPtS2FWqlkrnf=&f5BmsMYkdcckg=&5W7WsJZpaa_Wa=&ohqyQEZocsg_l=&DuZiZTZrYZios=&ntgPtrZleXcXa=&ICEFrjYYfcsaX=&dn3aHUYiUhfok=&bH_2R6Ypklebl=&adderzVrWnhfW=&EN96G4Vee_slo=&YZBO2sYUepWkd=&XVlk2GWocccno=&WQeIPfVXrplnp=&IRwhBpVZsceVg=&JB24nxXrlZagl=&k2UDzrWUVfm_h=&kdc5gjVgosliZ=&5G7miUUYkWqbo=&mQXSuzVUbqspi=&twPoNrVeVgml_=&M9qYlnWkYnUjn=&I5yrcDUlXnWbX=&R3QI7tVWfe_hY=&PvAFhxZssWVok=&SHqzOMVVdWojd=&Zebw4RYqoVUsU=&v9V4nsZknYlrb=&iDzDTrVWjscim=&cTISFKWZscblW=&mpJsTAZcUrkcq=&W7ahEDYdUkXnW=&CqjTmwXpqseYj=&ixTS7rVZndVZa=&wCVfYKXWZjoZb=&L3aihOWrUhmWh=&9lmwLVXVsclbe=&BVFSb4Ynsclhn=&aWibVeW_hWZeZ=&aOtQGxWfUWZXe=&T2imYFZWrnhe_=&teTZl2Um_VXao=&dEGfdlZsp_jll=&CZSfRLXmhrgUk=&HC7qvnYhoeoVs=&BxrKySUgXgi_Z=&IK3BvFZmXldge=&FqWc9IWfhZiUn=&wV_gkdVcmUisY=&mVUCvVZ_ZeYdl=&K87aOHXkcYihr=&ioZyjnYXfqfkr=&FhhhuVZagpmff=&tTklQyYgUnsUl=&9EmizGWrcVkVh=&3v6qnGUYmddjr=&3cIplyVnaXlVW=&LIF5mTVimYogd=&vNPjMyZlpfrbp=&PetHqDU_ZUUlr=&CzHzhxWgpqcef=&tNVV_AYgcc_sX=&n_8OvJUphYcqp=&qAWqWpVjhmobi=&EXhre8WWXpWZe=&ouqyDgWilmdWq=&gwKiapYZsfmXV=&xdBLWJXcjZamj=&r8oOJYZUhhdci=&nbofbUV_geeqk=&GiOMIVYfgremg=&MRqoNxUiUkhZc=&wM3ztuYcmoXiU=&C7kHKUYaVejbd=&4YeUdyYYiUkZ_=&LggTIhVrclWkZ=&9Gds2hWiihcid=&jqWUZ3Zhh_spZ=&9YYHz7XUeZYZY=&ZS7839Vsf_Xrj=&A7NdW5Ygsfsqc=&uMUGXfYlfgkkf=&xox_n7VYlUlrs=&gXBseKUqXciff=&lHehPHWfdacke=&PlD4pAXZcX_Zi=&imf7xhZsipqgU=&__MtoQYXnqjhc=&c7VvzQXrWWgsk=&LK_y5aUWYesWq=&yZBXAdYUWmViY=&O5AQH8ZclUmpU=&vJE6PYWmmsbac=&xqI_h_Xijenjh=&A4L3jNXraYimn=&2BPHeGXgZahUg=&c47zPaYgbriXl=&qWPvcuYphsgna=&XqG68OUklijpr=&E7eOBkZdo_Yii=&3okWjRUaVWhp_=&QpevSlXlladZb=&ExzL7OWlVWgoU=&2yt39yVoemrkZ=&hujGBfWVZqkob=&XK2PavZbqeene=&O5tniWZ_iapaV=&gm637TWpfrWrZ=&BNWsyhVq_Vjjc=&EoZjH2XgeUqkW=&mYmYzFVYZhmac=&H8WbzzXpoVciZ=&EVFtsBUqZ_mnj=&iNI5K4UeZapfa=&QWEqWhZporWnm=&z2sWBaZlihZlX=&u5LCDXUXXg_Zr=&ThQVAOWnjVWWd=&ELgZebZr_saYU=&L98TNJVqooXUW=&xHqVrtUUXUrjf=&DypCYsWlrlsaY=&QDatoHXeVjlao=&l8e4gJWapXrVn=&PqM6TIVhUqVpa=&9T3a5vWUh_lUb=&HYLjOdVs_kokc=&qUwfbCWehYbZe=&ykquJ3YkjnhZa=&lbKfnPUliZ_ka=&4qBd97YZklmgs=&mm6qTUXX_VbWb=&eiPfdHWpobVkY=&4k3VovVabaWes=&TZtPsFZZZg_da=&PIFfbtVZr_ijW=&cIsZdxZVZg_ns=&ENf3IkWfgqpfa=&aUfizzZsjgUhZ=&RHSkhOWsrabia=&xWEJNhVdjhgda=&BRWDGOZrZj_rZ=&GLUp4QUfmsdcm=&Qmafg6XnlXcir=&AD_yxtYhpafcp=&6hYFX_Vhdnsgp=&ysryNSZUgmqfV=&eDCRXcVjhfs_q=&kYBXKuZoi_aqc=&PnP2H_WdnXcZ_=&SG8EdHYWUfXYo=&aekVi4ZreZrfU=&YgVyFnZjZgqml=&EP64YfZmbZqmW=&lTh9rWWa_bUWg=&wScfseYlgrjVU=&pWxSSSUirpVrj=>pkaXZVblfUn=&dcx3BKWoX_Ymp=&LZCBLPYacXclq=&7LXpzRVgshoWm=&Fg2ITKXbocrrg=&7KBXDEWri__ne=&sucNaXVahrXXs=&9PbkjnVUbil_W=&_mJMnRWkmb_ha=&R8NNzwUXnYlYX=&vU9gZsZcYYlif=&LNzYNUZfUYVlh=&ANfgPMXiaYsXs=&juRBM4Usplqns=&Ukru4sXb_ddYV=&Sn_noDUerrpWp=&knnnA2YkYjlbg=&qy2T99WjVoVga=&HMqGVEUoUclaa=&4U3yIEWYfioXk=&3Jg9EXZeXkqbe=&UpFjN_Xaejngq=&uC5wBYUe_geYm=&V5PoF9UVgajZV=&aznZnUXhgUYfq=&lsdVB2UYilVcW=&qxogHRZeabdjU=&BWTJ9GWZkanpn=&gRqNuXXofpiZW=&d2NJHUUVXVebm=&u7lBJjWehnZlX=&QxpA66WVchkYd=&ptQq39VsXppXa=&vAEQAOYUdZnad=&m4cEphVZbVXql=&oOMrdoWfmssVb=&ZRsvaXZgqh_pa=&Z75JTLWUbqhgp=&5tOdGTVrprms_=&IJX9SjYh_U_kd=&4nLG3xYajqeUs=&Ep_guzVpaVeZV=&UEPbFPWgWVknX=&4fkhtuUsbcjXW=&WOWcnVXgbbpaf=&qywUWtZfnZZmh=&YsjiLtWgrmqqf=&WIJTSyZrsfpja=&smyjr8Ulagh__=&lcqlwGXgVjUgq=&3lBt9AXUZWmke=&lmdc55ZakrrVl=&rZDvJqZZhblen=&l6iyTlWphmc_f=&SNfg3qZjUjjap=&2wVX88Wgskjba=&uYAHEAVepVfbr=&FtnARSYjhfqqk=&BjyZ7VUmiaUeb=&tdaFptWsjsqjq=&PIkmyNZeoenif=&pr9PJ6Xqr__ag=&_pskWNYfnrprm=&N7hJRbUmmsdfU=&jORyPwYescmc_=&FdxcNOZcic_ai=&tOimCGXadqVnk=&qbtA8VXpXYXcZ=&edZ3RtZiflpsl=&cmeTYlZZYWaeh=&LUx7NTYgbohni=&7aGXbxYjmjsdj=&zeyinsUsjaZpe=&EimLC3YmgXqop=&KcpeWZWlhofii=&F_4v4YXaYjrbd=&6xMcF2YXXVdbY=&A9qw8nVXgfgZb=&s6szlRYh_llga=&geef75WUYlXsc=&bqFdhQYablmqf=&P3ObHMVnWWibf=&MIx2iYW_daXmZ=&lbMMW4WgUXblj=&SGUaY3UjsckjX=&LjflmUYXpZc_k=&MnFwXMVfhrgWk=&ir92bSVbZUUYX=&NB3N2TZXipWaZ=&gTuFngUVmgsha=&_Qbp6cWnjhkgX=&hkHkPkUUscYUg=&9UFsOrXdlk__q=&pzN3hGXilhnjq=&9ZFTqyXUhhZVj=&K3dBBaXcVaohn=&j76KfMUjaZUVr=&zcc3YGWqrnU_a=&ANIwGsUkYgeWW=&yNOgCLY_V_pfU=&azsoXzWfioged=&vA3NfsZbiipej=&6DGaXpVWkghfU=&tIrXmmYffWbfW=&CGna8xXVVjcYY=&Zj7jB6WgdfXfq=&_Lcw_YXmncgVn=&C2w9dGWoscgap=&qIFRLbXVjonqZ=&nQ4UmKUVpdpXY=&KVLfNRVrhngYW=&BCXYEYZglonZl=&mwTiksYsrVgWo=&K2GKRvVYXoYgq=&4vv9KqWhbfVcg=&wW7mYFVsprUcj=&MgvdF7Z_Ui_r_=&o47JqoXlrfqqX=&oyj7D9Uk__Zce=&yHGIIdZeWeajh=&FAprpxZmUlZVe=&FgtWjDZYlpndq=&D4BcVUXlbYrbe=&RHcMPVYoXrXWo=&SjHOdeZiocgpe=&zu5X7VUfhpWmf=&NLEzPPWiagoka=&vwM4K7ZjY_kXq=&y5uk3CXXmmsbk=&KVl6oDUmjmUis=&A4YlUzUnijXcj=&ScehlyYahZfq_=&9tVMMpXcncfqZ=&DBOqujYhqXdno=&sQc74TUUrWqff=&9ZKk7pUVnqmVa=&depVEtVsVslpn=&gakdjBUjWiafq=&8HDousWsUjbWY=&mn5hLaWhpdmZU=&c5PYJUZpVshWb=&HarwagUWqq_op=&6pQHOOWholmam=&LUtSbTYkWaVqk=&hVMmGDYYpZWsk=&YcZj9KUVspirm=&Ped_P7XrVrVar=&WP6ZGcXqUhqWe=&7QBif9VoqafgX=&ePhRxzWqhaYkV=&oJDR_EVpjbpXc=&x_hISBUqofhWs=&QI_yVaVceUZic=&EQBJuDXkrimic=&LBaxLrYYeVsbm=&_bvVfDUYhZgis=&E9u4MBXpfaaXl=&DyLMQnXViYm_m=&jdZW7vYlmYqhf=&Vy4zwuUYafXas=&cbBGvIWkqhqVa=&6SgeYXWblXsaY=&SnnHNqWbaqddm=&aFc3AaUfsbm_a=&l35ewMVfkdYZq=&yyDZU5VdnUZlW=&iJbTAXVacZnXp=&rxid4fYsjUmZ_=&CVVUBaZcWgZgq=&i95uFOZsqilVn=&khW_OuWicjkfY=&nFEHqSVbjrWoc=&u7EWp_XUdVYqd=&tH8ac8WUffVdX=&4qhtMHYqXVoch=&etWhA8ZWnZjhX=&HEWw6JVYdYUdr=&HOowlYWs_XrXq=&9VAYR7WsesYpU=&v8ged6UfXcmpk=&RsrXHUWesrVgl=&bCuXoxWfYWi_j=&4UK7jbWnliZZs=&aZzoiQVUplcZb=&clfSplZfacfeY=&3mQwu5UgcrnVc=&yTpdSnVeqcdrs=&Aw9XJkVdlVpWo=&qEzjyWUUsjsnn=&FDJr46XfbdZkc=&HUyNBLVidajlX=&jR2cdYZVkaaWp=&AVH22WYYbhiUp=&UmYbfqUnqolYj=&zYJq7EXnXepde=&inAIpcVUsacbf=&9DPZSSWglrpnc=&6_sC2SVWoli_h=&hqgeH8YXcqeYr=&k2QjRlUaUq_fc=&GVyzcKWijnr_U=&3FpDkMYlkoXfh=&jfbdLfZmejqsl=&rdU58NWgamUqZ=&TD3Ip9VWrYXaZ=&QvPscBWZgiXVd=&Hnr4g3Uq_YsYj=&4ajm_NZflYsVU=&XuqZsZWscZpfp=&vCdP8kWhjjrdi=&NFGeLhZkfYbao=&sPRXbqYricdkf=&vZ54fpZshnipm=&APw_bZXg_XYZr=&5Sj4saXfqebXh=&K8fhpyXilYmeh=&zA5ueTZjgYdcq=&Aju8wdZapggeo=&h4GNObZeoYkak=&T4kMIRXjbfY_a=&mQGA7IZYmolWV=&yqQw6iZinirsV=&PKxNJFWmUUYrV=&2hUr4nZhsqciY=&ATJbskUqYigsU=&7lsDNqWjodmig=&jX3G9eZUdeanq=&4HcpfWVrmdcqm=&pHGSQNV_enUia=&blZxa3Wlee_Wa=&zbBKfoZiYWgXr=&koJxEgWdegWkq=&eXIYNkZbphnjV=&Wb_FhlXfsicUf=&lfC9fGYbegZkg=&4sbl_OXqmnabn=&YWiDDbVUWspWs=&oSy9MkZgedUdW=&YcT44IXfrqhZX=&lG7ZY6XjmgfWr=&l2VMglXhigrqi=&p98T45WXkbh_o=&ztUr7nYmVhZrf=&JQCHjNXiZikji=&n4NfsLXZpkrVr=&fZHqHZUqVgWkj=&w2pH94WdfsqXi=&Pp7oxIYbfcqqi=&q5g5QZZYamWjs=&tPs9R2VdllVVj=&PcCKX2WiYZZfn=&rptRBKY_jcVYa=&hYO4eFXqinUnh=&nhIvHwUqoZqag=&I8cdRLXrmpUam=&9atmiEWggckld=&StQKNOZbcfm_s=&YZbPnTUbsndUh=&WSWQXyVhlqXo_=&dEMiaUYhfqqVj=&tFE29gUWpZhcn=&KZITp3Ubpsafl=&i__6CkZhanbgo=&lgCmeEXZdrksW=&rude7tXZdircs=&xRZE9kYihglZn=&4ySLRFZZrddVp=&qkp5yCVmjlarm=&ZboDpBYhemgpi=&LOo8O9XnWXZer=&neJh6uVbehUqY=&O6t_JKZolXcVa=&v4xQ5qXblomXe=&YiTIo6ZXpWfin=&Wl6eROVUsdqga=&eES9qUZZrVfbd=&nX7ZZ4XUdhgoj=&AfahlqUmeicVZ=&HXAzFtVa__rdn=&Fm36JWUUdcbdr=&jBOXqIZaniYpl=&ABwFq9Xd_eYZe=&oNFI27WXrV_kr=&JpSSiMUUmVoom=&C5ZmJDUXkZ_dp=&wjSJK7UkdlaXe=&5gDYjuYsbkgem=&FX46N2XheWpmq=&T_fFeUXUhokhV=&zex8oKUrbhqYl=&QukfyqVm_h_Wi=&ulsLWOXgiqfeX=&gctq4GX_Vmhkg=&aHW42_Wngpmjh=&Qcw5mfZ__jbVg=&TfjEhhWpYkpmo=&jYH6YYVjgqXUr=&VEiPvZVoUr_mX=&Qe3m8wYgmbskb=&dtH4JtXkanVXb=&6IbLOyYjhVWjs=&FNQrrMZbcVVVY=&tRcM2VVqjbmVb=&T79vsaZpiZmWY=&GRG228WiWUrZn=&Zp4mDPWfcmgqX=&bAP5KWXhUngjV=&JGDagPWhdYr_p=&rclAw7Wndcmaj=&prOtTtXcZkglb=&W4FYfgXcqVZkl=&Nx2G3mYjp_cfV=&lZf3TpWXZfXms=&_jOS4UVqbpnfk=&OB9rq9Xhmfr_d=&jWLjGeUWpebrj=&9Cz4duXirhfiY=&kSPhXNV_eh_ol=&NJt_cUYomWj_h=&uUBuSJUlblblo=&FVKpm7Udenjfm=&St5rlSUrZYjn_=&Cy_bllXYUndlU=&CdnL6qXoUbqkr=&r_j_hSWkllojV=&_3wSZUXlcUsbZ=&OB5bEgZhgdipn=&p57i7pWV_mrpU=&VAkRW9XlVoWae=&aUmGjfYmsmlag=&OHzILGXWojffW=&rJXySzZlnfjXr=&vxkVBXZZsaYhZ=&sWjHNpUenprUs=&ZTG8BxXsbdkYf=&u5kke2UhZsUZX=&VfgBXzVcZerYf=&5iRBTHXlbqdXi=&B5UBqcXefcUVW=&SOH7cWZeosjsq=&h5bJwnZlqjjcj=&LvxZZPVXnqoUg=&hgj7mfZnorqej=&NIiuH2V_prs_b=&XmAl9ZZlcfXrj=&sWDjjwXbnadkU=&x_UDQvZZnlaYk=&cCJt_bUaUsXf_=&eAIzdRXecgYfs=&_OP73EWUdiapU=&kTnUyOVsgqgss=&jSFhBMUnnoqXq=&aKWHIwVjadVsW=&Kc5WmoYlaXXqY=&K9X5QGXmWpjlk=&XPkFTlYgsiVgZ=&cTAVSHYdkrl_Z=&Tv49YVYidWhZs=&wBIRA5UiiYVbr=&CsocLGZaZVYps=&LzGaFrXclajim=&UaCyjDVfkbsWa=&_nET2aWWVdqko=&GkfijXYZfibgX=&GzCiILXhkXUsq=&JDIdkpWkYgjdp=&F5zVKcVsXbYVa=&Ia5YjIUlZrddd=&fYBmMiWhZlmbl=&Fs462qWoj_gq_=&hlFMLAZcUUgok=&OUKnVXWoWeqWq=&KxoItbZmklkog=&CLo3tjXdZih_o=&rR8jMNUsrYbrb=&IjKyXOWhcjpW_=&6vtyoMWf_ricY=&exPUGGWlnWZVl=&uVuxX_Zkgrgga=&rCyWbZYgiXbok=&accO3XVackgng=&8szbQlYpc_ZdU=&LDngcPYeUklcq=&qgqoREVhrmX_U=&cEyUswZhZiiUe=&pdUEXWYfqgacb=&6B6EgoWrbgebZ=&X3slfvWWYic_j=&fVJzdaWamholY=&Hz3m7pUgnc_cj=&GpPdYGUXhreUb=&lXzc99YqXcsji=&TmIFkQZpmXkVb=&RvgSCaXVmkdss=&zYHMm8Vcdrkf_=&hl5ZF9VgdncVd=&H6tuaJXskiiqs=&cvlMczYdqkfko=&8cwlTQYakhoiV=&FPEdBmVVdsi_s=&XMPdMXVaaa_oi=&5ArieKUbZrVeW=&7efJb_VfnmpqY=&fAjuP2Yfifjeg=&IcCXDzUYjmn_W=&XvkQTXWWdejjc=&tvPJmmXdnk_ee=&8NLoC2ZaZZ_dn=&fE_BsTXsYoqli=&EcoPXFVekk_ne=&dwSvMOWmhnjbf=&HnsV_TVrnlj_g=&pIAbYyViYmUrX=&7TTM5eZZhakao=&HbXNKLYeUejZW=&rbCFZGYmmWbsi=&5gNnFSXsYXgjV=&8LlEPdXsbocaa=&7NOFjRYXqaeVp=&y_ZNHiUohcsqh=&vpjaElWhnUVrf=&PC9uCZZjmbfgf=&mILySqWcmfsWj=&bemVrVUgqXqm_=&f69v_3XdsblXb=&QZ2UU5Xhkkkfq=&vLGBOIYkardhl=&Vy7pw7Yln_dcY=&uVEPIJW_VUebk=&nAfOJSUmbdYjj=&OgNHJVVfhpjpV=&tCEn_vXirVjaU=&UGxVfvXbVgeeU=<ASt8YUWqenW=&VJYrvAZsadprp=&uDLqQQYlqXpWo=&bbY9yAYm_fYnr=&P5OIUAWcdbped=&bFy2ZwYfXUaYV=&FwdF4CXnsZmnZ=&_gkCz7Z_XrXec=&QNQSiZVqUYcdj=&F8VSydU_fmkic=&2LXLZ2YZbnWmc=&FrrwCBXjYlrXU=&o44ab3Wrissds=&MO74JtZmidVql=&7ftbN_YVZZnaX=&SVRBebUUW__cV=&KpYGzwUjqflW_=&HkfffFWU_Vmjo=&alw6hlWWlZape=&FVMhX7XffUsbp=&J57JsxVslYghh=&YaGHFIYXhmmda=&pF6OVSZaeaajr=&eqweBEWgoVpjh=&9xSNsuVjlqlUX=&lrfj2FYihqcsa=&CuFrVcWWsapWZ=&VFXksMW_oYjed=&2qXfmqVmngYfh=&wIadTBWcqfeaZ=&rQyGYzUXoWXWr=&PFwSHVUrsWqnX=&pkTcNiZji_WiW=&Mfsdo9VehWYVi=&Dc57OrZmjpWss=&iiO3haXZpdqrn=&LiuGFyWYknjh_=&43AN3NWYmjrlZ=&EJd2jVZjgdVrb=&nBaZUEYYYnVWm=&UY9nW2UprdY_a=&VEDKM8ZpVosUl=&SUPLZDUr_flnh=&nA3bdUXsjqeis=&jrfVv8VUcq_ce=&DbCjxbUmmphfb=&leKtTzXdfjVea=&WQW9dkUYjhpcr=&LJRsJfZdqnoUb=&wBZAVgYrYegXs=&xlSckaXdqW_kr=&3HKBXlXljreiZ=&Gr_SsIWonsrVp=&KXVlbNYW_nlkU=&YmzBgOYoqhgdh=&cpCs6WYibjdWc=&vhtdq7ZccsUfl=&RlIuCVVrUlYbo=&jsVwMrZnrmYml=&Z7IyyDXhkedog=&c33hBbUpliYec=&BSO3pdXpnobhb=&X9oEYgVrmdsfe=&vmuKaPVnbfigp=&8M4HjAXXimjfZ=&BhppnwZqXaesW=&fshJoJYfjXWfn=&XhTo37UdfjgVk=&YUS565XglsVUl=&MbwTsEUqrmebr=&xaxlhUWj_Zi_h=&mGdcVHWbqjeei=&VJbZHaWkUgga_=&Q3HvmcU_mrXmd=&HoFjNxXaZVYoj=&hDkzwYVWkrqki=&Wp5UPdWmrU_rs=&mxZ3U2Ulrirkb=&Q9TCQhXkUfqUp=&eTYs7sZnjash_=&_jvlg4XbfYZkV=&sYDUHtWqVZqU_=&9nwyo2ZkocsrX=&jAr96ZXYUUbgb=&ZxNl4IZr_ffos=&wQbg3VXsldsjf=&XbGgkLWehscVq=&cgHaJrYi_qajj=&QtTdGEWagsjja=&7CM74DWsbnjki=&4cumUtZYpXdkn=&5HICO_Wrjeomk=&dmOIjDXrUXZsm=&EshsSBUY_l_Ui=&mOL7lhW_jdWbp=&89O4eSVVmhiWW=&YnWIJDYaodjsa=&5zbjc2YsaijkY=&KbLjgUWfdock_=&eQvi7uZgngW_e=&VAB6TfXrbdgdd=&gcLrcjWmXkndb=&9s2xkeXgbhppi=&zsRhc4VkaifdU=&SHizmEXgXaZbX=&K_NLsnYmdYWqj=&RGPZsAYdUlVsf=&ILtCdkXrafcXg=&AEwlYPYej_lih=&RwURMfZnjsf_k=&t6W7Q4ZXZpojn=&KesAb4UnYVacl=&wcBPsCW_rbqnY=&KJJQy_XnZr_nc=&Vw2tS2Yq_kqiX=&diXyvrV_piejc=&AIE6nXUWn_rhf=&7RMxLxUinjVoU=&K7b6eyZmjnsoa=&4ZopDxZkqXfbi=&SD_fOjUgciXkX=&udcGKAX_rYjfm=&HMe4aLZZoXli_=&R22h9GXphUedb=&oeTkDQUppsiV_=&qBlJXKXig_bmp=&gkqpEGVbrrnVs=&UIUswaYopXZke=&bIw4gxUneYZmo=&MCPWeIWWemgie=&YbmsVGVXldUih=&GIwwLdZejUb_g=&lBp8psUiYjXem=&5Mcpj9ZkUgkY_=&QyPwzCXrehhkr=&5opIv2XadUgc_=&6wx7XXUVd_fUe=<YhkSUaolcsr=&_eZg7gUX_nbkX=&4GRW4KYpUjWki=&p5XrqyVqfUlba=&qFzy7jZjlcmmh=&MVlNguUkbccX_=&3_Vb9ZVskVlWf=&ZkwI3wUamYW_a=&tgppziVqgVqqf=&9AInEKYjcYXrn=&S7VFOcZbkefmk=&6unjZrWcionXi=&XTSsHLXmocneZ=&mauRpsWipbZia=&xkXQZCZVfbhji=&SACv5rZVbaieo=&pa7JuHUUhbkWW=&Kt8pcdUgpZYih=&Qa57BXVWnnh_Z=&LWmIdUYidjpnf=&HDxLuiUZohqcn=&MfY7tPZflposa=&EzQ5tfXWlesgq=&hjvn9MYbXXWsm=&6iFGxhZpinVad=&4r3n5hWZdgiWZ=&42tZwtWjoYaaX=&zakZFzUeXbeWp=&llIBnHWsqjUjW=&YZvKi4Uerfran=&64WxmsZZosnYn=&hAWFpWWXWngVp=&3UCIjhWjmb_js=&xzJP9OYdrbioY=&sSYzgAYoUkmoc=&SBQMFQWgojrgp=&KoNFRgUqXigUf=&wdBKjNYkcngXb=&OHdtulXX_c_po=&EceKwrUcfXclb=&dAAFrAXdlfWke=&PJxr2XYWslUaW=&kHoIcWZdbnmiW=&fAS5daXfklYdn=&XvizKSXbganqX=&p8GODGYfjYsbX=&K9vEB_YprrsVn=&Fr89qRWeenVfo=&4hKqVpWlelmli=&34kgXMZUrWsXq=&XHQtAFYWhehch=&SFPJtKXZarpXY=&CGyMU2YcbbmjV=&kyg7J8Wijel_f=&HTdvtEVbqadhi=&kRFS3kXsgfnUg=&8yY3fFZcab_nn=&Vveq2vXjoYWiX=&69lXf9YVUpafY=&szrCV3VbjXenr=&TzujJxUnhrfff=&YkalxiZcnigmr=&ZS2QrOZWY_hlV=&7xhzbcZhipimg=&ay6eKcWYhpeXV=&GMccwGWqkZVps=&WrnG96XcVbaab=&OszwGhYhdZbqp=&Hu26NvWnmrepZ=&rppZ6LUiZneVq=&3hcsnUX_goiVb=&b7bfFqZhpeghb=&zXhOPjVfVZclV=&tEZpxvUcieqZr=&vxDzx4Xfba_jf=&RSj8yNZdlihfc=&knEkfAZiXZslh=&fkANEkYlmohlk=&kDGQOHWjfkfbj=&5AN8onXneeoka=&O3xkkqYmndmnb=&BhNrikYXoYhho=&6TKOsSXdgpick=&mLN5nCZj_lsji=&PiMmCkZdsjasn=&rzi4j6Ykfkpll=&242zVSXcbhXWq=&vuYKeIYfkk_da=&cHk5ZWZpVkppq=&U_5dokYWnikZW=&2p8xqAYnlXehl=&oHfgSwVbladbW=&nQbZyxV_fVqYU=&FmwHVnYnYanUn=&69yS7MUk_sYa_=&8Dvf4HVh_nmnl=&SdigePZmrimpa=&SDiVu_UYdnZWm=&zLEFrIVfjaplg=&AH3TTkZspjigj=&eLI6MzVnhisjk=&BgFjQIYZormoa=&oA_58pXkfcddj=&qB7SNfYUeorre=&hxezdMUXmnoUr=&cCQfSqVXlanpf=&WhddmXVZfoUZh=&3eT7z6Vp_fmVU=&K5DWZoXXldddd=&ga7yawZWlbUWa=&RDTixJYU_kWUY=&uKN63oUfZakVW=&hyJ5gqUrbjiYU=&4CzkdjVqkbZVn=&vVyd94WUUnXed=&DH2dKvWcUbaWj=&2HnChgUmZVnak=&GDuXVLYlsoXip=&mUBGDtZfdflUn=&mrID9jWallVpo=&S6iL_KYXgndcq=&_2T6MzVjjkUhd=&y9RZSFVjrdgnb=&aNE685Wfmreae=&4ftmq6WanbhXX=&5WGuoFZqaVjWZ=&afWmyHWb_ooZj=&y5uzMwZiqbcik=&rjtboYU_UYfcU=&Sd6x6_XlXdaeZ=&vGqX2eZdpgomd=&nIVPgEUlohleV=&R4hhyLVZYfleY=&BdpPJ8VahhrrU=&6ozuN8XaXYpUg=&caF5I6ZpmqqVs=&lGniPvXanZkqq=&dZwceSUflpjUj=&9WI62mYhWride=&8FSoxxUpbdnWj=&D66ds4VhaYdab=&yuCErxU_cnrjk=&rANzWfZbeXZsX=&U3SbByYpcVeVY=&IsOvEnVYWpcr_=&CWsoqnYcfoffZ=&bHUiMjZdqllfp=&xV5JNWWhneshs=&melYX_UUakglU=&kuiFYJUsborcn=&b5YmXkXnfccko=&klOLdeWhcdUVl=&UjTMChUhsaYVk=&kUHZ2vUUrgYWm=&JNv4OdYkibdia=&apwAAQVklbYUj=&59USgxXkemmd_=&oYwA7KVXociZi=&N7TTGpYfmcmgi=&T8B774UaWsijY=&DyIulBWVajV_b=&8xoZMcYYsbUeZ=&VsMEVuVkeqnXY=&_SUn_IXoldkrg=&OXn573WbWp_Ze=&eqJIpbYrZ_eZj=&qTzgbfXYqfmZq=&MeSPT3UfblWdV=&qMlazJUqr_hZV=&xggzI3XZWsahk=&AJTYYSZXhbVUY=&gHBFsYXsUi_nc=&b2UP_OZlZg_Uj=&A7k535XmqVbZn=&lCZgSNYZUfUmc=&mpDPNgZZgUYpg=&RlshjPZqjsrgd=&X8niuSWkbnphk=&oYv9kPVc_cgYo=&yIF6KJVVZmWWl=&YGOjorUknXqqf=&YHFgqRZVpshbd=&s6BVmgXbVjpXq=&QLEMKwXjpYsXi=&9rp_abWmjnmo_=&LYNBk6ZdjrYcb=&9G_VFsUame_Zk=&qA3Jn5Ugjplnb=&favoW8VYsZYZZ=&XRF_UgYosZUnU=&kGxs4cUslZZ_q=&GYIpNKUaerpjc=&97ir3DUeVceeo=&fGk8NwWihrWWm=&zgAyTFXjnmZrZ=&xMPypOXrglYjg=&5Ac5L3XYhr_jU=&pFMMYdYponsWU=&tqvcMcWcbXeqh=&qsIQ_JVdrYsbs=&C7QhnfVffrfgZ=&e7ZgiNYoYWZjb=&dvSzo2YZsedgl=&eITTV5VX_Ymam=&ZMauFZWjo_amd=&mFZZc4WfVbsdp=&fZ36vAZnhmcas=&O7WsFWVsgmXpj=&26xo43Ufccqrf=&3wCF2vUkmjk_l=&OIR2W3Wkpmhsl=&eu2X_7YWVksks=&olFkIOUZWmnYh=&SICIqlWWZqmkf=&chUVO4ZcfqdaV=&yfsmUSVZceZlW=&WwwRPEWVirqfg=&V5MjQWYlaUXbm=&OmHuiNYljkVqY=&tRW6gcVkWcUYX=&58JRdHVmWfZcX=&wuQNkiVidd_oV=&RoCypBUZ_jYsi=&ChIprmXbrledd=&dKKtkxWZabamg=&LgYU3UZVcindk=&iVnvrMWobqsqo=&XxyIeDUhhoZmV=&9YUmlZWi_ccZm=&Ie8CRdVXVbgoi=&6Px4uzWZoshcW=&hqD3quWVUeb_b=&2cBf5XUmrkabd=&cjdwhJWZbjWmW=&yNuM2CZ_Wirqn=&8JaWvpZrUYddX=&7h5xFFZnWgVmi=&CZv2m4Ukbikfl=&WC27dHUaaYaUg=&kE_eqUWdcpYqp=&HU6ZpbVakrpVU=&buElqCUsmpmke=&iP_hiYZmegXpg=&X95aqrZXckXcY=&BwPhCoZhqYsZp=&uE8Bm8Vlnfkgi=&byysn6ZjYZfXV=&LLw6dYYlnUjdb=&ar5golXsoh_Ud=&cDeQaYZso_XWg=&FMJyxMU_bYgrq=&j_BtgpZX_nfrc=&F4rALfVgreUss=&YVnYvUWrUqbYo=&EO8Iu5X_efqeq=&XMYcnpUlicZeW=&5jQuuNUfXXral=&A8ltInZkopZWm=&QNAwLPUsUYlbi=&mPzaIDWbYdcse=&4G3U27VVpZrbn=&EnwfFjUlkpgnY=&h3jpSxZciWZUb=&hJ8mHYVgsUarf=&EJuWPxVZjWdXn=&FWsOISXnXgehY=&YF8umPYqhdapj=&mv_K_2Wsklanl=&GsQFtjUjUZrkd=&uylT7mZfjYWWW=&n_ZIdfZmjqjbn=&FvkQRKXWWdlV_=&6zKmVtVkrogdm=&hN6itVYdVsZps=&sbMAwqUocglmV=&3AEdNUZglm_if=&YYojOjXlpXUaX=&IDfaLRWsbclZa=&y6xrNAVljjrgo=&ZE5EOsYVgahnV=&C2Zaz7ZVYmqUa=&EN9VdRXqljcoq=&cawlJTW_doVXl=&_xqE4VZgZWeXf=&eWmIXPXYdqsVq=&pva_mkVhfoslp=&urZkWqXdrnfbf=&RjenU4ZqrfWiW=&5HEiOcZXUYoWo=&FzY_ZiXrdUamZ=&WXcf4JUbjoqcX=&K44S4wWkUd_cl=&hjJCqcZjfXlb_=&JLryFhUegbcdq=&3UPqfmZa_ihfs=&TgcyysXanVsmh=&r_s8yiXksZqjo=&RRIpMQZleVhss=&Ebb6keZdcZZeq=&g_3rDJUoWbqep=&lXbRh5Wpfgeog=&rwvK7WXankonY=&MvJVUUXfnfdar=&A9nfCjWZd_lWZ=&dkPeoyZihcfim=&ay4qbFWqd_dcg=&uFuyRGYcibYbp=&bVvB_YVVXkarX=&JZ5kxeXnUddes=&FOGcY9Xrhkeja=&929mu3WspUddf=&nxzYjwUrVhVfo=&ZUVgkjUlWrnhq=&AexspvYkYiaoo=&38k7GuVhifhaa=&4aWypfZiUgWbk=&y3O3HTZkfmW_d=&tz6e2jVjhoVco=&bdptrYWkslYid=&wTpM4CWfslZWh=&c4MidBVmmqg_X=&9NJKDrZfcbZsb=&jsB2gwWpY_Wcn=&eKWdpdYrqVpiX=&sdVQ8fWkmYjdn=&KZiOSZVWaoYXd=&_VwIpnVoWraXl=&7sByNEZcWZkZ_=&BCRlNWZacmqpn=&TomPuaVqUsldU=&ApvFt4VUqUpUa=&cgKH6VYqnkiah=&nBv4vnZfoXpXa=&2xPI4lWfajYVf=&w2Z_ESYVaUsrX=&H4MnycZnclgjq=&aHdlQDWoWXmks=&wxHp7eXmdcksm=&lV7zcRXUlgWh_=&qHQOfOXliqiVa=&febYQhXgblqkZ=&8uohFHWqXkYkq=&AvsHPWWddVVcW=&r9Pe2jZVpjsZk=&Tk6EtbUnpknoc=&JYedZAWk_UrsZ=&P3xGrpXjki_ni=&TJDSOIZsbkXps=&MFRBRvYiVYlcq=&gYctvFZlragel=&xTKB5PXjfdeob=&DI79QXVbqoiXa=&yyzkF4Xlaiq_c=&B6tBdwUafmncW=&gcvUJTVWopVal=&hi9UeOYlfZejm=&u_EGazWVWWbfb=&wJbr4XUkZmmUr=&jUm4vaXrhqngs=&ADOGsWXXXdoYo=&SVOdKzXUXfkVW=&KOea_QVrnYlZa=&wBCxAwWnjdYbj=&Z4lFhCVrd_ahg=&_gg4yPZj_qVrd=&SjZqIlZXagVYr=&drg4NCVlpiVsV=&y4b2yiZgddiXq=&bpMJ6wZpiVYeU=&lnlVsjWVnsWeo=&oHfcV2VndanVi=&ERCm9eZb_cpoh=&CWmZQrVlbdliq=&9VvvD8XsYZnoh=&YJrIQRWj_cUbg=&rWPdTnXmfVYpi=&uH7ztWXmpbbog=&YJnEnmYgWXYmd=&VpBBRzYn_Wirr=&mUrQ2BVrgdnjf=&tqFoAtYsZjeWo=&pu7YhgZUrVmcU=&lbpACRZUjUsmp=&tOXPZFVj_WWjX=&wGGezlX_bZokU=&RpL_khZXikife=&CmNBRwUXnmWhp=&RDbH9IU_cgegr=&dbVcZjUeaUXcd=&gjBMFzXnfgprU=&oykqKdXcleknj=&MEt3fZVdXhWco=&DP_96DWmihreV=&hAhh6qZefgYrs=&iFXSdBYVd_inm=&MMbngPXcY_Yho=&C55GB4Ydlokre=&3l5__LXhaVX_V=&FJ6SbyYfXnkU_=&uhNgggWsYq_Vq=&D7d3PdUdcdiri=&FIhTicXq_Yfo_=&EEgdU2XXYibXZ=&4IwwcCYbcYZk_=&e_7yLwZdiemhb=&6ULYfXU_eZpls=&_H9tRvYhjVkgY=&CyirbxW_lha_q=&jmq4I3WalVaVs=&ZCFOqgXXlgUbj=&XtudAfYZssgim=&Lk6EzaWjemaZc=&ojgTc_VbhkXcX=&5Vj9qxXaeZcfr=&jQMhroWkikpWV=&n3zRBFYngYlWm=&Mub_LTYWVXegi=&9JTNzmVikXVgi=&RMzWwlWUbWodo=&kM6EsQZbcVkWp=&xXLxajWanrcke=&Ta7BTHYVkVhek=&jYVmXxXdjkWYo=&Z6w2uAVdpsqb_=&JNuuJNVkblVbm=&i5v48YXVjZWhd=&orRRzWUdkfosh=&9u8c2WYcp_kpd=&IsLwCoXlfqbWo=&xhsZCWZWXbijm=&exYrZSXnhdlrW=&9cL9tUWap_s_W=&UuDGvLXZkfagV=&GuNczzZkiUsls=&cBLCEzUXkWldl=&uNDkmtXXkbYVU=&PgSynqYcVrpWg=&vnMIJjVacrlZV=&MiMeZxYjrUl_s=&zCN8F3ZcgnWdW=&RqhK4SUsbreei=&2bbmX8WspVUpr=&GlwlajYmnXVaf=&NbYq4JWa_X_ii=&Qe5KTMZXoiopV=&xCeXYKVhjrWr_=&Nb9qiuYiamVaY=&6or9cjUldlgha=&7u2MMgZe_o_Zc=&KHpfsxZUkYmUc=&pQ582JXrhnVee=&hQqswpX_jsidi=&yhs_BjZpWdbig=&cLe3gRYmjkYph=&54zK9NXcpkgWU=&_TRkiSWerjrms=&Y3_2HdZgVofeh=&eB2dxxU_WbVW_=&rNc8KjXspfpVa=&nEUSvRZU_fblW=&fOTP9EZsgpWZp=&cDwChlVlmaqjn=&Y8bgy9Xhqaimb=&WXPCLzUmclVrY=&kE5CnFZorblUh=&tmL68BWimYoka=&zprqdmWgifdlm=&kRIVlGXqmUprl=&ttVE5aVmd_Yq_=&K8_XeFZhcsqbp=&kXwZBwYaZrjbW=&aFzGbSVWqk_le=&BjEc8LVbn_ajZ=&pwo9ceXYoUrac=&QTrAy8XdqUXkn=&rgxYeLW_nfkYe=&9de4nDU_sehca=&9jSQYoVrbgZY_=&UksrsIWhllcob=&jIGRWNVebfbVb=&4bI_TzUqgrVj_=&KWxrEnZkcUpqm=&8UzroqZsqjsiY=&bhmOctVXcbVhf=&SW9tD8YhXWZgh=&iSo4ugXnghemZ=&faRztFZnjZsUU=&vp6I_kZUmpXXq=&n565JKWaibail=&nuUrSmVfqgncs=&w3Z6n6YglVnrV=&J8ZphwW_V_W_f=&VCRXCNWofncpe=&Z4jB8gWm_dWgf=&3PeZn_ZWWbnqh=&nzHLqvYjjWfsZ=&UbsgfKYsdekXh=&AEYZOuViWerVj=&FoIZ3nXmbfosl=&zEWBXJWg__Yha=&8XVOCGYpnok_c=&RpznKVYUWkUcU=&aqrIVCZbYYefW=&ZKxTLdUrp_esY=&AmCfuzWYoZpVa=&N3b4l7ZgoWsjh=&VflgxOUUZXeVk=&86w5G6VXpnfcb=&9m_qd8Xgj_eWj=&WsmR6RUjhVlZh=&qO5o7DUUZjcWc=&dlI3ojYpialoY=&WKL48xWo_rmZn=&urVtxJUograVa=&OTWAaAWhYjhps=&LiHMIMYp_kWjV=&CCQoXMZicieYV=&SbmmI8Zhddlnh=&F8JBRdYYrogkW=&wZ_s5qXfXaVsa=&nbaP7DZpa_lUg=&7PUe7nY_fnrrh=&ORjcgQZdmpUqi=&okuv5TXmpo_gr=&UWpqwJUgapgWa=&uljkCKWqgYZam=&FpK43gX_kWc_p=&3hM8hAVngcYUc=&sO9LNPUWrnWgY=&sMfCnkUUpgkoi=&bfMvttYWUnWfm=<8nWFVsnabVk=&CShXNPYVWUjfs=&NEuolkZhrWerj=&9jCBzTYZplmZn=&9RDQdgXdfsene=&_NJso4YUconiZ=&eZwnQ6ZVZgihs=&QglsHnVqqoihU=&wbIKOXWhlbf_p=&iyVuCDVffYoig=&X49ZSkXl_ZskV=&EyouNBXjk_osr=&YdpixJZYVYVc_=&RwGkJjWqnfhYf=&YrkofkYYcXkfl=&4eXZxkVohgcaV=&65VnQkXVak_bV=&A2ExprUXZi_Wj=&8cHayeUrpYqji=&xECKZiXanjgjf=&G7pL4WYijWkni=&zK7IuYVrjZrUp=&v3VXKCXjZdXj_=&KatSQaUf_Wmkf=&GdfTtEUYjlWbg=&HMzDikVnipmZW=&qsibblYfmUdVf=&Jt6l82Zrioi_h=&XFOkPiXjpdajl=&7OdAl7UoiXhmh=&WH4d_ZWUsgmVq=&zxmdQLYooUgZY=&_4qUwpWm_Xamg=&6a3_CKU_ffnYn=&MYAsUdUalaaah=&7NNIlfVbiVbnk=&kc5E3gZkcegdf=&A4Ay_qWnldiYV=&V5XSKpYZboYsa=&h3jJx5ZfepWUW=&25gBEKVpfhUaf=&wIxfz5WaWfaXe=&mYmpQkUWoYifl=&jeooFiWWUpfmZ=&eVlmCWVXhregn=&eR5u8rUgXmUsf=&YskQC9UWUiXq_=&tjN7kYXZXXarZ=&6tl8oPZWgsadq=&iH66azVYlYbnn=&rTgOR7UVmhYiU=&LgQwAaV_WgZjd=&hcmdsHVhlbdlq=&5wVFtYXmWXhml=&CUCXRzYeXWYmh=&QnPVyFYnqeicm=&XCvGjbVdZqpdg=&4KiwmIXkpUqik=&ILWxbhW_eYhYq=&XCpiHJXmfkYcd=&Q3paEoUjgkYne=&mweQYYYrabjbb=&63NaYeWi_eqol=&BGjaluYlonWqk=&HbywCJZYYllba=&XECvVLWljXnjo=&5LmE_2XWisZdo=&VLHFREV_fXahc=&Gu9cyfUbqiUVe=&oLz94vXpZnXkW=&XJ_IWcUmjdaWj=&BfhyttUbYpUqo=&IeBTMIZVXWgXp=&wu9BWkWekjkXo=&PtOUrDZfoqeed=&G_GIJ5Wepsrpn=&4nnjXjYmbahr_=&OPGnBzYXhdWlj=&wm9HZxUYWYsZj=&gSKXCaXVopb_m=&pNxYjqZlgcadq=&JtnCueXjXVZed=&lwkprwZrfjVmb=&sHOmwxYjXpigU=&YznSKEXYWZdpj=&qtp47nYUlqXop=&FFnS_MUa_leab=&OJAQGaWYaUcdV=&zus7pzYdVfgbY=&PSrTYQYfqYZgY=&pS95faYWglicq=&gSzsDPYXi_lk_=&dmBo8OWrZgZcX=&T_Z2_PUqokbos=&iqahwoUUqmXgl=&PLvsmkUfZnnem=&wfQKfoZakbp_Y=&TfKuVZYcsmlas=&O5NFk_YjiVgWZ=&gTtf6bWeUkorl=&49q8rzYno_jnW=&rCnbHsXjpg_Ui=&XFCAXbUYg_YYl=&FLFJKAZoYkX_h=&BSlEiFYmdWqsj=&Xmusk3UhrVesZ=&9GpcoeXeYmkfm=&S8CvQcZkdfnjs=&b5BpGoWfYWgaj=&457bCCVdsmhio=&USCeP6WlcnVbl=&xNyVgkZlfgdqq=&_C4rxIUobegWZ=&ExcMpgZsmYkks=&KurwKLVfZifjm=&GJD2CLWlhlfip=&r6RpD6ZflamVX=&JawxoFWmbmUaV=&QdgOSyYbbfpnf=&ce5NVUUXZn_dp=&fsvefRUUeWXnj=&8VcpWOUqkdebo=&Zny9GIZk_sUee=&TegDdmWrjbhea=&yGwvliYpnlUfj=&q6v8T9Ucnecks=&PONOx6XlgrUln=&q7GSGRUXjsVhU=&GU97YBUpb_njc=&QTqEWXUrgoYec=&lQK8C6UWlilas=&XSrkmsZhlcYss=&uEfJsiWsojqlV=&yWsCiPVrqsdgp=&XVrULLYorWcgZ=&bURs5bUcgjfsY=&b6IBulY_fcssa=&NSkJa5Zfl_nmp=&KVyO6WZWfoamn=&xdaWDOUmrhaWk=&K5eykIWnZaZga=&Sd5FlrUabiWom=&8FTZnKX_oZcjd=&MqgEtkVlbrsqW=&prOGOgXsslji_=&jN4FmjWkgspkh=&E2MLxMUV_YrVZ=&NlQ2a9XpYnchc=&drjoRMYfqqWWU=&nDOdA8Wmprrgi=&SUNsXtXshmqco=&tkXIkoXahjaVf=&qmvvO2Yqodgnm=&nVYklmUhmWWhc=&tOQHU_Xpni_Yc=&42AjrxVWqYjci=&Av7s9DVskncUh=&DXzikCWgrpUjX=&pyQn73VYjcYhg=&ZPMFWhWVfrgca=&sJJuutYiblhYf=&d_43m8ZYbramZ=&CFRg6OYpnhhXl=&hKvmsmZqcqsss=&d3sPKRVUmaV_i=&Fs9TQFWidqYmj=&xGbPkQXfeqngp=&CfQFAmWmisjqe=&DIi3v8Wasscas=&HPSVIWWYdUlhb=&3nisI7XUdfmcb=&sb_mG8XYefklk=&fXwSmzZbissrf=&LWQclXWoXiqd_=&RMe5aoWpnddmk=&jVKSjTUspfnXV=&yakbBwYepfWib=&6NX5lqUZZ_sYd=&Eq7wdZZlUggUn=&bYvUT4Vnjokhj=&LEeQSwWlpjjqY=&dQ5mwzYlakrYf=&5KfCxKUXgWWc_=&8Q_KClXnisqWn=&Ml7Z5BWdbiXgl=&iLiwHnXlllXer=&El6BQ6Z_plpps=&Ewi48UVmomUXl=&POMWvPVgrklpk=&gToraIZphnc_j=&PaTDn5WYYUlaU=&WWZjzrXjqWV_c=&RW7xMSZYdihUW=&YSCXHIZimbadq=&96u8YEUbcWhdc=&SyM5A3ZkfdbrY=&ZQ9CMsZpf_gXa=&2djSniUbkdrrV=&Ccr2ZyZoimsml=&yzyTfwWjZnins=&2M2Yj_UU_Wemq=&srC2VdZosnpdZ=&jqpLnLW_glqVm=&2K2vjbUnmVcdr=&P3vAiRZUqmiml=&aUWbMPXhWdkbp=&l9Re_zYbidkbp=&oOxYbgXmdhpen=&hQFAupWlkYekb=&BU8HNnXcgmdkU=&O8p9yvZZcisjf=&pWwsMLWbYnZce=&aRs9ckYklsXUo=&v2BmSQZZeZZWq=&jNMBxEW_fWpmV=&t83ISzZlsooVp=&C3slzdXcWWcXm=&95U6sCVprsXhr=&G74EhDZdXpooY=&fg7aISZorrlZr=&DfuacWZjnmsrj=&bTcweuYasZYdj=&LEaHtUZijepqf=&B9tpfAYXnpi__=&dzqGvQVgiZnj_=&Zrm3ShVYiXkdX=&H6H4SBXocildX=&iRL2uQUVqalU_=&VFAqu6VdmYYrn=&OgU2FlXWaYmfe=&4GPA6vWjcnarm=&rTmm9YWmi_WdU=&ghZ8qJWbgrhaa=&iyshirUqZUaqo=&S8_U7uZeaXegW=>LtcnVdWoqXg=&2yy_mbXaknmmh=&XM492qUdUkhcs=&Z_HaZcVsZhXpd=&U6fYPlXUfebgk=&G_MoQfYViWrgi=&yRVtJjZZae_i_=&bcrA2pYVWhg_n=&yUTWahVcqbUnW=&yoTRpEXqgrokc=&ns9rfxZnfjUWd=&sykc32WhUd_jb=&SXIcqZYlZaarm=&gvmPWmYmVZcYp=&jXOdcPV_ZbWfj=&vHU9a3ZVgoqbW=&WCEIPmWVljfUs=&FtoptbXjZlnfs=&JE7SNwUohjrim=&FK9PNsZWU_akl=&e98MjDYojldqb=&UlUDD7Vofckfd=&4y6uGUUcsVisg=&2YomfNVarnbXd=&_scaVfWhhXr_j=&A5MdliVglmnms=&FwYZd8Xkas_Y_=&C4x67lYZcXpos=&GQj26IYooombj=&YvKhTSZljl_bj=&GqSHQEVssfXgl=&XbFMVdViUeepg=&QPsD6bUmdnceZ=&gI5soGUYgagir=&48pv2jUUskZe_=&PNrxYLXkobncl=&uJjkokZghVoph=&CGPrDuZbXXljW=&RxRVl5Ysk_Zhi=&m8tFpwUrXsbUi=&LdKO_vUhVssis=&rJ2gEzWmklgUa=&XpDofCXj_lUrV=&rshjeoUUqghsh=&33lH7VWfeYqZa=&EXQJb6Weechhf=&jDGktTVnsWogl=&UQ5C4MUdXVnea=&eHVga2Xqkm_kf=&gYFI9kVsZU_Wq=&88lXJJVemfhag=&e3OZZ7YfisXZi=&_AhhIMZcqgXls=&fMjhyTWYrsi_s=&SYZxgcUmgpdUl=&YVKL2JVV_efXh=&zsY9kdUXeZVUc=&LVKd_aUYdmWUj=&spQcVCXjdrilY=&aOBMgLXgmkcsU=&TqLMHhWrlYkpe=&XatGHoYlrWWca=&U8TKPSWgdaXZf=&2Z9CzXUeXWZYX=&mYQLycXfdWlpp=&_smHbSVifrn_j=&PfmifoWhZsanl=&iuFgKgV_Uqikj=&AhkIedUrkrYnW=&HMnyshZoZrbgq=&cedpdrVllhZ_m=&zlUFNSYXajjUU=&hnYy6iWgqnaYX=&KTWVkoXkidbpb=&w_ounbWYeYkgn=&cgOKwuWqiionq=&oWJUglUqaeVpl=&b9XOVAUaUnYnm=&vBWddPWednegY=&LEVARdYYWYgZe=&FYUJdNVhkrYs_=&ymn8UMYgg_ash=&yQtrHdZfpXWaj=&panbhMWsWckjk=&LMlVdgZdbrced=&sN54gVVlhrhje=&5RdRSzUXXXUke=&6_plS5YaXemlU=&tSFbTRUhVUdef=&96WJ5ZX_fpqZi=&Cmp4XbXZcogqj=&iTS7yrVrarenX=&8w6FPnYcoseaq=&DDF85WVc_rfZb=&kc72gNZjkpckq=&_bCbmeXognspo=&MnPSgoVnenXcr=&rxWUMBYfaoVrj=&kbfgB4V_eZUkX=&BTo6hjWarldXm=&SDTsayWqgmsbq=&LN3Ia_XYWakWg=&OFKz_XVnZfeia=&gPJAXRUoaZld_=&hElnp4UhnpnrV=&snjm2PVe_gcU_=&z5vqxDZUkbeYb=&jyfO_9WpYogeY=&TsAa3zXdbgUc_=&Rfxxb5Xrlfhr_=&6bvVsnXZkXprr=&J47hSmXqjpqqn=&IOdnwfYrfqoao=&zqnAHwXoekYmd=&myQ4fGZVbXeVm=&2TlrZUWesfcd_=&jRFJoDWUollak=&6JWGglW_jonnp=&ton6HIWrcWpjg=&Rth9k4UWXemnf=&A7XnJ6Xcjnjmd=&Vfd6lKYlmnekU=&RaR8oWXragiYg=&QW_HzzXXqksYi=&ytweWMVrqsUhj=&prDduNX_WqjYe=&mHEsL9ZadkVrZ=&JwtvpiXnVfpsk=&8YlSmxUmZlqag=&qq7HqLZmW_lWl=&G6rhQGXq_sahi=&zws6H2ZngsdWW=&jAk7yfYgqfrrm=&lrz7tmYgZqjar=&8CN4UHVXdbfkc=&UuewNnYskXiXb=&UVG4dXWfjohnV=&F_XdBgZfdphrf=&sbQxywXlVXarU=&5woIgBZsqplZW=&Cm6nJ3VWgWUUV=&HmD3u4VsspapV=&Gh3eo2Yhfblbq=&wjb2TRUlpWgfX=&pK6T7FWVjgh_U=&wSxF7qZlUpVrg=&Eb73rbZilbdgk=&65FLHiVreqgpq=&KyGaIhUUVaUXo=&b_ZSmGUs_pgoa=&SsdiTMXqlYZgk=&B49cYhWWUYkec=&qoXMXGXohaosp=&niwrTrVcfnsWg=&F8TjHsWmnYdlV=&zEN3mvZZVdVcn=&4BC8KjWkbUZfo=&avCsHaUmcYVVf=&HK94ZVXcrrpXg=&IVWVoKYZojqZg=&MdHvarZlbiVdW=&hExJO4Wsl_mbr=&ouXnupWjhfqbs=&meFfBvUeYnpfa=&gF6AlyXaU_eed=&eIaJ2cVqZknYo=&gzdZacXskgdZr=&FwpVVQZisfWXo=&xrXWZ6VobilrU=&iIRnW9XYqYYgo=&9LE2m4Vorjijs=&mND9c6XjWsrml=&r3nYuZYbehqms=&TaFhInXpfbmqf=&FErvE4Woelqoi=&_qj7K5YZmodWY=&HAnYRBXWdYgsn=&GvKwitUcZnqsd=&VnBJVOWjUcaXk=&AbYeH_YhVi_YZ=&L7h8CMWUXhbVa=&FBfYkAZWaoqaZ=&hdkbg4WYoachs=&nFxiZxWZppdoo=&iloozVXgZjXWW=&lBzovCYVfqmXe=&yq7WCxZpXlbkZ=&je3cgIXYVqhid=&ZP7IECXo_dcoh=&BwfahLXsdUrck=&duRWm9UrZsdes=&oVpYJYXqUsjpV=&75KlC9VrZsihc=&tUrFgaUdfZmfe=&WXJypdUsXWZfg=&GjIGVnYZZojWV=&t6jPpNXXcqfmU=&BO7bNjVamlZZX=&nhNCFfYpXjYf_=&sikeT6VndrUmj=&INfSElZjopmkb=&zDkaXfYmdZqab=&wG3esHYlhUbXg=&X4qP24ZjkWcYi=&2kpfjjZilrmZk=&RBMLq9WnpcqoY=&E_4UCeWkpaa_Z=&cJi8tZUokinbb=&olPHPJWoisZdU=&p_cyP3WmZUgeq=&zNepyVVZmWjsm=&TxoVKXZokpoVs=&mz4gU6Yhfpnkq=&xoJgNOUksmXgn=&tS3b4vZ_cZXes=&eaBk_GWcoobZk=&wcfW6EVoqslla=&4bp8EXVUXaXna=&cfunBhUdnrcdp=&KBkOTeXfkcalW=&DR7jSGUVhhkpU=&6TtYbYXgskbsl=&qokAtBYpd_mqr=&o9JcDRWiqdenY=&CyTwzeXfhgdah=&rriIcbVnkkjdk=&oPWbfGYsUXWkX=&OFN3OIXfZmchV=&VanpNfVpnesfc=&V3zPysZfmVscl=&wWzgeSYfkiesn=&ocemmMVgX_rgc=&c_3z2EXdXWaoi=&Suy3BeXhscUrV=&OnqKDIXXkeVfb=&cfC2fkVnVdnjs=&BWunS5Zfifnbg=&kIfZqTVXXicgf=&sJVW4KY_Wimoc=&EfDNQjWonarcZ=&xLzSevZqrsils=&tUqRoMXcdgcqV=&vEpWdHWhiUmjn=&RPnoWPVbmqpse=&E55fmmWZrfqab=&aNv8MBX_UansV=&_WOioWYmkbdXs=&9uZTYnWhgsepm=&LhBPQOZqZWbnb=&ZiByhhWjjXqo_=&ZmpdX9ZYYcrUn=&obbVvjU_cargr=&tr7z8JW_WepbU=&cMLrMNZYodrfs=&wRSlCLWgofZlp=&vnXkVZYmerbqY=&EP2WfbZpjcshj=&sbGwzTUnVepnY=&tWajamUpfsUkp=&Qr7DMaZbeVjep=&eaj_HNZjpp_WY=&INxliZVdYrpid=&nWPIrXYUWYWpY=&Vx_OqQZhoqsen=&lFI4hyXbqimpU=&N4sYD6WcUiobk=&EtcmqzWgWZrYV=&R37AixVqkbnWo=&HCzd2dYVghadr=&zX_dquYeqqblW=&E6n2xXZV_kVab=&UKRLIOYXmeX_n=&PB_WnUYYpbbfa=&oJPu_hXqidhp_=&xEERmwZjhbbjp=&pUuBwMXhkkrll=&d2wtIyY__rpYW=&Nnmy2QZksfaoW=&6TO5ynXleklmn=&dFCMrCYcVbqnj=&PWQUUmYqrklac=&6xqZ6ZWfqqWkl=&lEF9FWUsjngqc=&HwxY2kUcWensd=&KJx5qlUeghfso=&eTulGpWibpqia=&RTVj_jXdklYkZ=&g8ormKVbgqeif=&Bb2dnxWbqssqa=&FRqKEvUYnlpor=&o6R4XpUaamXZU=&FAwp9QXbfUqhV=&bydso6Xq_cnmc=&pPZ3CBWaqbjjm=&BttalYZjocmfc=&IDV5N6UeoZbmb=&43MeAQZlps_of=&j4zsgEZkVkWU_=&GKZmAuYirZbkf=&yXNOmOWgXehrc=&dmjInmUlaeZWY=&JNzftDWaZqojV=&juvjAUXZgnpkq=&4glJwpWcdhqad=&q4ZjgEYYlelaY=&6VAduyYZbqqee=&WTcFQqUgqepcs=&ow2kNXXnZgjge=&qXiYGKVmrksYk=&qm5F2DUfqmfZZ=&Wrl7HlWhlpiZj=&p4RdW9VcikrYh=&2JXupWZVeXYlX=&P98XfbZpdkjYk=&KI3InAVmsnfkX=&nkO7LWVqkkprg=&t4x26rUnljiqo=&3vDNoEWeVmeb_=&pN93mIWoWpoiY=&dUls2PUlVUU_p=&FyZfHHVrYiUo_=&yD_kKqWVgspUg=&Ub_Z3uWk_liZV=&LjRUU5Vegokah=&EwLhveZphsWcd=&VIcS4vXhfUdke=&coTDZcZs_qsne=&ujypbnUVmeq_Y=&fOKtBsVZWgZkb=&vQoT6bXcqpUsn=&P7Pg8gWsfrZYn=&Ay7qO8Vkhdiol=&2lA23_WUb_srk=&apRVB4UYXZbhk=&OEkzWtZYjWidc=&bhcSE7VkdXjef=&9igNScYpZhYan=&wLArniXniiaaq=&LUFcodWXllerc=&vI6MSJXfZgnai=&sVs3DnWiefgre=&HpacJHWYZiaWi=&oonETmVqbpbar=&ElbBPkWoYnanV=&cYvtxAXfqrV_o=&NvpdQmYciZdhq=&PRWfMxXVZeqlZ=&ZSdkcaWgsgnYg=&nJ_pYvWnfoekj=&rtvtreXrrnYZd=<b9BcXedjUXp=&N4HoSiZeWqWnY=&Lnm6CTYcZ_rVi=&IPzOIiUshiWXV=&IgkPI8UmqfpoX=&NfzO8hZdcZXee=&KCq8P_YbhYglg=&ocp9LuWWlqjid=&YYGhUxXoboXnX=&4kCdZfV_pkskZ=&M_bLovWkjfXj_=&NXFAwAWakhehs=&js3nFGXZVshi_=&K7mGLYZV_ca_k=&j6wpNPXgdrskV=&wRZATRVVrhcWd=&LJPTdEZpdkofq=&x6YPkZYUfdWab=&Pm9EgWUbWbbgp=&qYejWJWnrkeZ_=&wAhWNcUnjpkmi=&wD5ID8VidVrkm=&_DefauWkjikrn=&yTOHj3YXlok_m=&S2_l5VUepnWca=&uxkrfkXdqZ_VU=&KFKy77Wrrjgsb=&ziin2mXpgYhlW=&vTrE47Xpljbik=&onsQzEVadrVsX=&3R7hQpV_qeVeU=&rSaW6fZVbnpVo=&D4tHM4ZYdgbns=&tc7Bl5XlVohac=&viUQS8Zrcomkp=&UtSWwEYhhUU_q=&A3spqcVnlj_m_=&5bnYBGWnjgmec=&KEBFWWUXogmkq=&8W3n_GWqVmihl=&H4KiheZimeosl=&qJVFDAXkfrlre=&WwPwUSVWel_pX=&Fdhw8DWjgUgiV=&dBUKVpWXcqkmY=&wzMMuPXssnmjk=&g2Xk_bVddgsWp=&AOT2SRYoeliVo=&C5iy4OUhZWnf_=&65acKAVZqYZsV=&GtqQTAZinbpel=&BJjZB2UbYWVWn=&VoDyXTVfddpmq=&IXy9_hZnbrsmp=&hekPnIYqdVXXa=&Y5mbBVVccY_ad=&ERagWOYgjkjak=&XzvB4xXlYYqWf=&iO2qUfUfqj_id=&KJx_86YhgW_ZX=&c9kTtHUeiaVed=&ys757GWWkeUls=&zB3u9gUagWpnl=&ub5Q7bUlhXgUc=&wOS4XSZYgkX_X=&ocYQbPZjpicke=&NtICsAVessVij=&GJALIvYmYiklZ=&9I6u4bWrsUscd=&faQstMXUmplfj=&k3XaoIYkVUpkq=&nuH3JWZeidYek=&zUchdXUpboboc=&n9jSMYUbYmnUb=&vct2ZrVmnoeXh=&vvp8kUVfgYoXW=&lVygiZXYZnrag=&CSGBegVlsejZ_=&vvo3ntVlU_pfZ=&nlqYWJZWslooi=&cnXSw3VdVckXd=&i9nqJ8YcXVilf=&ACcEZ8UUmkldr=&8IFiPZXcqaXid=&9zVuiQXeifplh=&BauDShVYWsbmg=&LdgGCBXnsdZUs=&9UTjQKYVikcce=&tYR32zV_geVf_=&YQLIioXlnrppm=&NscG5sYsgkYci=&ylwLfoYqnhanj=&KDDHbyXreXWmq=&3usAefYrXgsaa=&zVrg6eXhbsshp=&hIhjSMXqVafod=&FBSv8LWbYdaUW=&aK_4dBXYeYqd_=&F4OKFBZremgaZ=&45FZo2XWjZfXs=&KxsZYmXsebhqc=&UEIPHmYY_eXnr=&XdYu2wUrrpemj=&WH66pIUsiYfXd=&hzSpBSZsXW_Vi=&HCF6fxXghdlXn=&8PpvtMZ_Z_Ypr=&KnM6eqYolsYpf=&ewnN9MWcVplXr=&mPJDovXoYYZ_Z=&8gUbrGXnjppWn=&OlXFqNYclgXds=&k9qaBbUnhfcbn=&paSHYxVmUlWqg=&fGoaxSVodhheb=&kdG2XJUkqpmme=&R2HkLyYXplrre=&uKrbwhXXsh_pW=&qanW_8Yaqgjbb=&SioLrZXfgfemj=&SH6EzWZekorrj=&qPd4mpXprrimh=&6iym3yVkljfeY=&L4z8LMXsalpVm=&lpCvp2Uiemhkr=&ZbnHhUXXlgbkm=&GbFE3QXoVUmkf=&fJFhr9W_lYrgq=&KO9s9kV_kdoUr=&laxg2wYlobUdX=&vO6RHcYpair_V=&aunIPBZoZqdcf=&D64y_hYfbjZaV=&eJXsTeYjlgbVk=&NG8REnXVZrndb=&vMk6wuWXicjfq=&2lDjlsUdmlegq=&8TxbigZsUqinX=&5KffiiUiqcXrp=&oEhbKyXrleglp=&f9b_rrZibcYfg=&lbQqicVkghnoa=&ATODgWYjqVacj=&ANVB3rUkhbjph=&HlPHQuY_pmfne=&rD3SI5Yfgjnhb=&9gOzZEZgpVsYW=&ljCTu4ZXYjmnX=&3qPGM2Xkpghlb=&sakaj5UckhVki=&GldoIZWlpVcYl=&g8d3l3UhfnUrY=&MhkC2SUoqXjhm=&B_FAhnY__a_jk=&GXOMRwYXlfoYq=&bSndU5YaqYdVc=&4B5f49UWXiioW=&UI3tMqXZoi_gW=&zpHVo8YZoesjU=&6H3oaSYdpsXiY=&VK5xKxYolZpl_=&oP6bQLVkUqqVX=&EgB95qUjXZged=&3Q6QmvZlXo_rX=&bY9mjeVgcXcfi=&ZonzB3VjVcclV=&xAhmWcZUWerXc=&7F9nRvYphmfUm=&EdrmShYjblfhf=&U9bqH5YaaqaWh=&zlxweBVdnbcX_=&IgPF22ZiZljfk=&48mOS3ZipWVmm=&fTrFCGWmiksdi=&n9kQqJXYj_iZk=&jeIdytUXespWc=&3lLrXeUkibceW=&LmxQIvWdgYXai=&KXmeFKWmoXrWh=&lddiTcZVckjVV=&y5ynQvVorYUql=&e9RF6CUakhooX=&rhx3poUjeiadf=&aciPCCUdWdmoa=&eX9mKSXscYjVf=&aiFtscZdoYeZi=&DqACQZYdWpfUe=&7ZUmX6WmVijWi=&PRmhDXUgZmmfi=&dqdtIwYZiqZoc=&9gWKTXUgXprnf=&BWwyQjUjcXnsY=&jr2iNQVinanZn=&yfiGDCXZoahhX=&dOH3rMWaYaanj=&wDxaLKUhd_eUm=&S3XXwGZ_WZree=&ZRcsgfZinanUj=&6p98_XYYVsUrf=&aVeNR8Wb_iZmf=&wfd_aXZojnhdp=&cBtegEUhf_dWg=&5R9j9qYVnXVrc=&hWoNkaYqkbaVb=&8gC_jNYbanbVs=&ZSanDVYVsceqk=&OLJrvUVcqqlpo=&nxNYIFXmWlgbq=&d2mv7zXsaXYlY=&WaOlZoXangnhr=&iwFESpVmolVsU=&3BMH8hVWqe_Xb=&k_CeDlXhdjkad=&eeuXzYYbo_anb=&gUHr7LYkkochb=&8wxlSoUiZbomc=&rUi3_JVbmaddr=&rUzeh7Zmbhhbj=&wQbdUoYXkkaUc=&PetZADX_kgren=&jDFehzVVg_Xmr=&imyKOjUZcdYVn=&FF7sRvWWYWXcc=&AIWHLnZdjrn_X=&EXtIaYWakakjY=&xxvyw2ZdfjasX=&SavPe2YXcqodq=&Y8aMb7V_fmsh_=&qBZjTFZUanrhk=&bDyQOTYmoZnXb=&XrFTXQXeiaaih=&V5lQF9Vjqiioc=&kshbFrY_oYZge=&NNSuZAVsqpWck=&vScrz2Z_nYrUq=&zU_6IHVjlmrq_=&UKr4SwZapoiWj=&sStSQPUnVmrVl=&JxxuBKZmsoeog=&Z_KU2MVUZginU=&M8vkvKYbgYqoh=&rff7XbUYhqrhl=&EoQzMfXcVdiZp=&XUfYuxWplfkeZ=&pmtG6zVWsYUss=&yr2zXSWhkYjfq=&qKE4yVWoVcUXh=&AizyIWZcnl_Vm=&ZdDoKaXdfdeU_=&Fn8h3HXjWni_f=&ut7to7ZZchhje=&L5z7XPWmqnook=&tDW8KmYrmUgpW=&ELPZewUajesqb=&WF5PbfVncdhle=&kunwCTVWXkghs=&AibqftUmZqWof=&wh_CnhXicfeWo=&JXHsYJZZpckam=&SEOAKmXpn_mok=&jYRaSVZmZabUh=&WRemllZmnrmrY=&bee5NvZdYlZld=&OhNPCBYUdsnfW=&sYopiwWabg_WV=&9jx8UeUfVrfmo=&X4t5s9WebaaoX=&dAYiYFXrjscYm=&e9k6H8YXicgoj=&hTtVfbZXcVbZm=&7rsPKXXqcembo=&HJuDnxZnmZXUs=&PFTYJrVdgkYXn=&A4aqKGVYUcZrb=&KrihLeVYaVhjs=&vbmnXOWmqjVkb=&aJBLn3YfUm_Um=&VYJgk9XUchYsd=&s23a5yZkhpfrp=&DUkvlkZdmns_l=&c729OiUgrgYUr=&2iAHLMVhifjca=&cjjFGlUZWsdsr=&I4ZK_rUaWsmdh=&nRQG7eZnUnUqk=&iqFeLfUh_WWVe=&SXyQeaVjbclie=&W_CsIBUnipgko=&ARfqNPZUYfYdk=&cBopHtWVidgmf=&Uekw22WnqZkjU=&Jp3eGCZleYWYV=&4EGNv7YfdaXgl=&Ybx6JlYkpadbd=&zhgdJWWlUZUsj=&eyKapVUmrraij=&TX_zHkZgXYffj=&d_8zbAXagXgZc=&coOD8CXsVpWhl=&CD5t8ZYamleqo=&FbvMlQZhZclol=&Z_oeMQXgZfsij=&eB6juTVlYVdXq=&uFLpJ5VbapcUg=&9sjh46VlrdXVZ=&V8gG4WYikrrko=&hCLaghVfZiVqe=&wfTJBYZ_k_gai=&d8JVI7VbdsUkY=>bldKXk_bZYm=&vVLkh_VYemiZl=&FNBjuPWerZ_lh=&WAQMiZYbqifs_=&s8OSC_WdsrcZb=&3pBJ65Zkqealn=&JtXaWoVZpsXqe=&vmuuuhYkaVZUf=&QaDdndZoYalhY=&ffQDLUVZlkqoW=&RcrCbWUodeigj=&89AHJbYUWoich=&yb84uiWrdqdsj=&Fs9yd9WdWjnVd=&jiYwhqWfeebbo=&QnDWkTWZmjkoW=&UFD2NjUdcpkio=&3lRiK3U_ZVoaj=&hkt9AjZqZqarj=&DBxPkYVasWoge=&VoJjaBVYnfgem=&OQI4AtUWhhYdg=&bVnZq_Z_nnoec=&TpWgnfVYd_Z_a=&bmAPb9VYcfajZ=&slCTkiXiifnWY=&QuFNGVXalqpna=&PA5jLIXhYUaai=&HuEfqWUZoijrU=&__v_ogZakWmde=&PZZeSyXcagged=&W5qNUFVssXfln=&cbwWT8ZYaj_ag=&WSo8M5Zms_qbW=&AbMdBIVaaiWaV=&c5VLZNXabjg__=&oLqgQAYXhjksf=&K7o5lmVrrdojV=&Y7tfaYZkcmslV=&OS2buRZapUbnc=&Q9ZZzFVnsojkc=&ZzIRvSWqhkVah=&sGyFj3Vdsdkjb=&2QqSfyXenllcp=&WEwZKGVnhgVW_=&5fQfWgXlmbVil=&HKEJ2rWimaZXf=&l4539_Wrklckj=&umM5NLUqsfXcr=&87ZVPZXinajYr=&FGsdnYVllsYje=&xLZTZbVmecfji=&kD4qixWgbV_VZ=&btOV2iW_Xb_jg=&ZsPEuRZdUqkff=&k69gHRUgdsagd=&FXraWxZVVoaZj=&DEMv6jXh_Ydfd=&jACEeNUoslisY=&KXfs94UkqqpeZ=&sJphfMXlriqfp=&NcR74VYqVmbmp=&WCXuU_UnpmfUr=&4qBxpzXflihXr=&VxBFgYUmqflre=&teNamPZprinkk=&SZ6dGqYpbrXoW=&9aYfuFWkkaXse=&OewLbRWYhphWn=&ibQFHbXadjioW=&7bt3IyZfckUl_=&E6tnddYpm_hgm=&KdjgjkVVqrmaf=&tmlvidX_qUeec=&UeSVA_UbWgnhb=&N7a3cBVfdppZZ=&TQCzepXskWmWj=&3IbBZRXjashrV=&jrAPaIXcqdZeb=&ZBcv_VYbaimjZ=&uDT5hwYXXWmnX=&jIxyVVYeZlZrp=&txyKwhZ__aVgY=&YksHjzVWpj_Vc=&pEi3q4ZelcoYh=&GiG4z3V_afohi=&N5o7kPUebnoql=&LqWPUOWUsfgUq=&Kasse5WWnnmbU=&EnYJ7oYliXoji=&ahapdDWi_rikW=&X4Uh6yVZor_Ym=&OYwn7SYYosUfl=&XLcerQXdoggXd=&rru3XfZeUcYrX=&69Sso5Yqsbgdg=&YcbkJQZbokah_=&flDop7YbdZgbl=&OAsZqYYimmjab=&5SLhbDUpWeeXr=&EiSBirUa_nhoX=&BQFSg7ZUergfm=&LaYRHeWWihqcV=&IBd7x4WrZafdb=&NeSNHzZrrWqfp=&rhwavrUihfmje=&VldEl4Xshjmaj=&VT_qzrZnUkWVk=&9jyeEsZjfZYYi=&dHdbimXohcjnV=&n6hLuQZ_VreXV=&VuCudZZgfXed_=&ySH3fEYolYfid=&xpKY7cUdreUrk=&ZVvNTFVbglbra=&jkPTpVWVpesek=&i9CJGuZcgdbfi=&TPNjKOUoXYmgk=&_OeF2LXVZdcnX=&qDekeeUrndahm=&iFngkfVbWddYY=&mJJy7UZqfhrep=&wYvl4RVWlWsV_=&tnTgStUphlpYp=&9ZuDZcXpiYWae=&dwiA5CUgrsdln=&6U4uMKZYjVbUV=&akFbZcXfZYros=&5Y7vaLUqYbboZ=&OoBQ_DWscohdr=&Ox3XqgXjdUVjU=&yQ6M3SWnVrfbX=&ImdJwjYXmboie=&cAmiIoXhWapmq=&UJGYObX_cYnsV=&3ioMWeXkiafab=&3H4AVvZodjXZY=&I4xMTQW_mqbij=&qWSxlsYhdc_gb=&NrYj5eUloll_f=&QpQjFYZ_XWnje=&KD5flYUeUhqlo=&gTHAvFXbsqsjo=&4nZ6FNUYaeYoV=&LlrfuKYiblbYU=&j9UA8QWsVbVcc=&tQgSUsVhhdahV=&lszEBiUisgljY=&ME9KtXWVgjeZ_=&WgxXijZ_mjWi_=&G45DvQZpUiWUY=&WigLh9YWpgWYY=&tnmhfVYYnqdnl=&wJjjPAVZmVXna=&Ul59lnYpYZiY_=&cLouuHUjhrZUV=&BayQoYVmoZohV=&qcnTDqZqencgc=&rRwbr7Z__kYce=&OeBI8hWfgWqrg=&2vVAtyVplo_dp=&cPK5DtWjoZelf=&AjtSxUWYfXrjk=&JcVfVSUbdXphY=&EueEADZqaaZfp=&I7XKBjZmabhsb=&_GSNW3WUmasrj=&KGVSw3YobfXn_=&e48aTlWnWacZb=&UcpsaNYjobZgi=&mUq4keWYfheWU=&4rVVVqVXhWpeY=&eNo6XjVhi_asV=&q3daOhVkkkZiV=&zHcvN3YjdYpmc=&WmNA8uVVafrfY=&GHzUCpVVfgncY=&nwYFQ7YnejlVZ=&NlBPUKWhfpnnW=&FcF8frUnmdbeh=&VcFgfdUcbnfUo=&9stDSxUnWs_nm=&LZQlq_ZiqmnkY=&fP6pjXUYgddhq=&dsZG7RUUVjW_m=&KUvf6JZfrUYig=&SUKRCvVseZd_c=&hpfzfjXilZU_c=&kCIqzmYjdjprf=&MOwikCZiddWrp=&Xuq7I8Zdddpag=&EjscryY_hsfde=&59dRhuXWlnela=&mRJoa2VrbaeXc=&yuam39Wbdrfmh=&6zeoNiWVqqlqg=&QLYNNIUeYZnoW=&fuUytrYhmZaoU=&eeCYoTWYmWbpo=&s2So_kWl__nks=&jViyOHYocoUVr=&ugdO3SYldYskW=&OEmO2rUoZkcoi=&WKSHNRUegdimX=&Aay6iZZdjdnhf=&n6cdyMVsrZr_i=&EunZYrVobhoml=&4RwvaTYZUrhll=&UYXxE3XVsZodf=&oVbmG_ZiXiZmW=&w2hFN4Ybaqndh=&m7VKicU_jYmed=&G7A8XpVpghjhr=&6RANOrXsnfpdm=&oOGzy4UmqiX__=&UCOMtWXeookXc=&zEMBwrUmqq_Xf=&qlf5v2XnsiWbW=&P2eb63WnfUene=&RL9VkYYZmjXns=&GX_tXkXdjgheY=&dz9Pv9ZWmrXVj=&y2LFJIZcsmVWp=&4VxcdWVhXieaY=&PlPOccXXlcoXU=&P_YrqeW_aboVf=&k_I5ciVgWaVns=&H7TYqmXZcUhdZ=&GZONfGXekUsXi=&KvfboDXapashe=&tUnnDSVUniVXf=&P2zNSUYZ_hmWf=&F3CDCpYmi_Zmr=&2b75vlWogmqal=&VOwLXQXmZdpsc=&qyfECgZhpnUgc=&K3HQLxWkWajfq=&sUnYVrZjoXVfl=&7fYDxFYlkaiUW=&diNKJZZoreUhg=&kmbkGOWqfnoZZ=&Ep3BhyVW_qakb=&5nyJChZidrqrg=&8D49xTVsfdlZp=&TOMSBKWl_sZob=&jCIK_fXXYomgl=&cgAs4ZVhhkjUV=&wPL4WjVjkVqYU=&3nlpT2Vqpdgih=&f6A35eZVhmbgr=&YXkc8wYZZa_rk=&W59qjGUWdWnaU=&qiCrJiZmdViUq=&COZaoSZjmVeUZ=&2uSQqdZgiejiV=&9PGoJYZfimccX=&BQysmnZVp_YWm=&7JmIbuUbqalcp=&8ABagCYdodlpb=&sgcJ8kWkkgkr_=&w4l9VJVnXnrqe=&DQX936UZglkoY=&3XMGV7UYWolYc=&7fkjagUpimoki=&Yq5lZEWepklqb=&ZLbCL7WZVbdor=&8Z_iddUYUrarX=&nLX7ujXWrbVsX=&TtauHlWdZsWgh=&b2YLJlZZsrZbf=&BTEnc3Xaedc_i=&5aHBgFXXVWkaV=&lIQzBNXVbZghc=&3bClJ6Wol__lV=&YjISU6YfasadX=&sFFvNTYsZrhYf=&t7KoUHUiWVUas=&WVrrVgWdfWdgk=&5Idx7aVpihabf=&CwQHiEZqbidni=&AiPYdfVmkebgc=&ARnihWUfcYgrg=&8_giDhUiXWUdi=&SAE_BdYkoa_bk=&DWOTrVYYZZacX=&ZIy4ebWhphp_Y=&zR8NPLWhokmim=&UVoFVQZUpeoes=&VewjilX_gicqV=&urCGfLXmagkhY=&m4xOVDUkqridX=&oGTcLbZleZmiZ=&8eGY33ZkoWelY=&MisqkRYnYlfXU=&ya2NtTWUsndWj=&fhIBqNUlhmeen=&rXaq73UriknZW=&K5vPXMUrnehlk=&_C6L8DVmdsbim=&YkiKRiYkijcj_=&8GhClQXaZoggg=&npaImmWkamlia=&Fr9C73WlfsbkW=&NQuVf6XXbsaYW=&SqKubeUfXVspq=&dFNR2iVqlmskk=&pI_zuqYrV_XeY=&iVhjh5ZYXfkaY=&fZDNpyZhrXddU=&WzrfHiUpanjVf=&4JBU37XsofdWl=&7QusjGZkfmXiX=&wLSF2HWZcVbgs=&f8tvgAUZeZU_l=&2BmxfJV_Wsahe=&6FkUXbVkmVdsk=&Pp86fiZiYaXpj=&_da27sX_UmWWk=&_t8mxfVoXfaWo=&gdXYZqXnrZkmo=&wv9G8gVcY_apX=&_ZfoVWV_ispqs=&_LbM3LUsgZdkc=&gEhJVzVqfbmjr=&A_3YqsXfZpUra=&3yjGRnUnXlnYq=&fL_wQwWelgXsb=&OQLQzsYmqlr_V=&kNMgINXrWfZlW=&iUvdsIUqWWkmh=&_5J7Z5WoqWXmk=&79DGGrZpUfmrV=&sUgnYdUlYlaXo=&Wao3opYbhejns=&8AJ8RuV_fVlXY=&PBjPCzUYkdeno=&mdYWTaWafknol=&XHPqpkZXWWhpl=&B8ds5AXajibn_=&H_faXvZjljdma=&vPd_oRZcgUi__=&3wb2hWWchlopn=&gzgKaDYjqrVfV=&gptPwrWgVWlji=&abmGwOVrqsfjo=&JM254SZdpZhhs=&WDoAXcYrogVqp=&Du_6MoWjojrVV=&pUMdIPYnbiarj=&8ObLfxUVlrYkf=&4sU6mpVrcbfdV=&N9587WZVmhsXd=&hRzq3CYkoUqhZ=&cFxca_WdfWkf_=&L8lw_pWeZZhW_=&TqE8WFYUiiWdb=&9aDNMTZhscqdd=&bGTG4CWbUalkW=&rEpxx3XcoZYdq=&vofPQEYnqjfWp=&xakgnsVYpkXgq=&CiXEKXZ_Vlmgo=&WO2lu7Zmqenls=&SGLW4PWnmb_df=&fzsWoLUfqnVel=&svmzdqWma_ais=&SdnI84Viddqfj=&ZaGOwBXaXWipc=&RklzX8VdsnpYs=&fMpD2cVigZeah=&wh9hNrYrrkXXp=&t5nLiLYsbfhYk=&UDx42JZoqVfUf=&u2NKrMZd_rado=&DWO2VaZWmkpoU=&I2OZAEYZUcXir=&cb93IPUeYmhka=&JKbcPPVpVcaqs=&B2sikSZbhXXnV=&oVka9QZisYql_=&CXwszIWilUhhU=&a4SPU6ZgnjVlj=&C9gBRFYdjjqYr=&Xj3bOYXV_oa_q=&8ufUixZpicobX=&4A8GAYVmUoUis=&7Ahw_bXseXYgr=&WMJu9OXdgfhfZ=&vy_CPXZVkaeka=&VD2GTuXdcWVrZ=&BoyPLbWejpoYr=&Cl6V29XUZqc_Z=&LEQrJYZ_Xjneq=&Z6kU57UWjrYob=&ib7TuqVecscai=&q3lm9iWofUpae=&weVnWMVfndY_b=&uZWddVVbojhpm=&cpMrEDUgcpino=&WiWjvbXlogehZ=&ZXde5yYqkpeqf=&afebZGVVc_nlc=&ftQaLQXlZUd_g=&hIYrFTWnpggYb=&bTthVrVZhaiaq=&eu2WXiWjrsl_g=&mH8Q3mWbXVlsX=&Kl7mEEXjlWbiU=&6Lg4z6Zggqrrp=&8K86PhXnYY__Y=&w_Y58FYgZVmfo=&2YZLZ4WahUesr=&DoJ9MkXcVlqeg=&rUUlKyZWgoUgY=&BbzfKpVYmesna=&94rUaIYimVngr=&3LsrQxXlYbhcq=&Et3QZHXmUbhp_=&folqYdXcXkmlp=&zhwYaKVcppbji=&ygfSduUdVljrs=&EqAGigYodrmgh=&qLjNUaWrsq_XW=&_96xbHXf_oWps=&LWU5o5XUZVUds=&vuCysjVipfikq=&qcb9FKZr_cVdr=&pAftQQXhdU_gb=&fwic2zZsmV_Vf=&OB77jcVXVkqWc=&y4igUKWgVpnsX=&hOfaHUWbaaWmj=&YT7CSpYihWhZo=&8_mHwkVnqfaea=&8tgDUDWlnjYpj=&uOTFtkZpWmbcj=&X49gySZ_XVrgV=&UwE3sNUYWhsip=&uJHRTmWsYsgij=&ThxifjVonmaqk=&N69LrXZfXYbek=&Ys4CVtWUdUUmh=&2hcABUXrkaqWW=&bxgXREWlZqml_=&2A9VseWcWXsoa=&ZlgOJKUn_cobe=&GurjU7Zkblb_Z=&LS3be5VmUhcip=&oSIDJ_Upidecb=&tEs3wBWYqdaZd=&f27JEdZinWcdq=&M8mVOMYjVbeos=&Gq6RmkUdZfifV=&tCaNBUZmekYZc=&aDOWrwUkrcUie=&OZLR_UWmobkih=&q76XHrWmegkVo=&4MZ8emWmpojmq=&TG87CnYiXqlma=&NWZGUnWq_Wqgq=&4OaPcKWbXsXke=&VvgZtNWjaefld=&zrKVhkWVUeooo=&JaW4LbYlpVcrl=&WOFESpVilUsVm=&9KuRKnUfrUfqk=&5JGU45ZplerXs=&ajg9O4Zdisbgs=&MNW6SzZYVqfWl=&d59mfwWkYciaf=&kFRI4qXfWdXdp=&VXJhPQWpimlXd=&b7Dj9gVohoW_k=&LYDC3xXYm_soZ=&hCWaJ7WqaXXns=&bsRlK9XkhXfXh=&Fg2d39Vlhslai=&VkqXc7UlibYlm=&LIWQ3fUXskVir=&jnYiVlUqsmYhi=&_JUhW6ZdhjZoX=&K2cUfuZr_sYVk=&zpkxfvUfoUYfq=&rGYkMnVriebog=&msEY3pXoajhen=&ogy6uzZhlfWns=&LaGD_xZr_q_fV=&goZQAKYUmefUf=&gNYG9QUjrkYnj=&ICtJ6QWpnf_sj=&HGR6GEVbUsnja=&JtHzkqVcXgbnd=&9f4k4CYrsVXVg=&q5dJk9UdWqjbs=&zrxSe9Uidaaqb=&H5lNnTUibrgjV=&HREVsaUjarWdV=&nWLRjQZUp_ibs=&cFxUhMZbrilqc=&xlyxHcZVkqhce=&t46XAbWUmjeUh=&J4KWwkVlaaXbd=&l_jxkmYpjpjYi=&y5Vw_lZ_hVXgf=&hnTULWVlakVlb=&eCaq_lXXjqqal=&QywVljYaVhpgp=&HLlE5JUdf_mjq=&AjTvpkVlbjgXo=&2OIoUuXqVjd_e=&Enxh4BVficsg_=&MHxnT3YWXsa_a=&Lsz5JeVUkqlaq=&ODbgXBZibkYZW=&npsDAZZXknplc=&3vhx6fZbphcVp=&8qdUGTXpYafoZ=&tviZ9TZjmbbjU=&lJsSxPYhUigZf=&RXJE5eVZlgpmg=&RSGPxIZnZZsUk=&qSL6szZsWXadj=&YGLLRdYoZj_VW=&UnmqYUUbZfUXo=&LnEss8WglghcU=&fLwrApWYjongj=&FAFMggUZobVlj=&bQhR7bXiWimVj=&RkbazQZfasYao=&kPrXm_XoqVqhj=&MchBhgXWkVeZh=&2yJc5YVdaVVmX=&sUURfqWgjlqUZ=&x4lYNaVUVgdkm=&FhhIMfVmsaZqr=&cPyHq_Zcqmiqq=&V_pMBNVncYnjV=&jgAk9dWaaqlrl=&BUj8DBWigVXXZ=&uYWXeDWblXanb=&rRHzUYWg_habj=&hhvYBkXVXUbpo=&SU7woWYUilkrj=&CiScr7UphUXUZ=&V_9wr4ZUffUhq=&lP3eHrXsfUrfX=&NR8JojZraldXb=&YKlJuFUaUmXfm=&fiJbAJWXUUoaq=&QAWNduYonejaV=&rDCY8FYZVdo_o=&uHhHgrWlniYds=&dHPEUdVhksakf=>pBMTVnUdams=&d_zfGjVrbUsWW=&DIQjbBWbXoWdg=&Xk2OXoUnkbYaY=&3xZmunYjjZcZc=&kuMG36XZjofVX=&drqw_nVfY_gZf=&hDvDIgVegfYlc=&2oUAmWZUZlipa=&IQLPfJXihfXgh=&lWGRmdVldWqZY=&PMuL5gYelkgko=&pMCbczYZUnreZ=&cGjnGgYflhWfZ=&QcDrxAUrmYZoa=&mdWegUUmqViab=&tZJc6rUXpdbpZ=&4QqpbKZjlYpco=&59GyJCYhWZrnW=&jSr4D6VndWrYi=&HJiC3JYk_jiUV=&7AxNn3UXocnZb=&xCLYRAZUbfakj=&UqlIHnWZgYshc=&pZ3f_DUqVgbZa=&pARL4MYjickYW=&2JiOWCUVmqoqk=&5EbxJpWnfVcfp=&E_W6WMYfrhnjh=&I46oBNU_dV_fm=&X7VgqYVi_bWVg=&95CrBsWca_mna=&YuTvecVa_hcho=&62fvmVUaiXccj=&WYGCwtY_kafkV=&Q5ztU3VVfqWbl=&TkW3PEXlVUnZa=&_6ag4rXWhnnam=&gb2eFXZrjsrgp=&ziQePQVhhhemX=&zmZdECYm_ccnX=&wYNHACVqsgmYs=&jPw9oPVgqqnbh=&nxSMpnWbjgdee=&7gmgrNZfprZWk=&D7yUJwZoedeej=&4ivR86YraoVqk=&XiGyg4Zlr_ddi=&camm3_Znaicol=&BR3afpUkZYYca=&n23YV7ZenmZWl=&fAtQyeZVWUcbW=&EBVkY8UqXloeq=&7StUVhWemchUZ=&M8M8n7ZjoXhZd=&xMXLPYWnZVidZ=&oZwdeQXeXUbfl=&mgRJsUXomhnm_=&spbc9_VdddU_V=&sqPEYQWegYpqf=&_q39rqUViqZhh=&7mtkKGWcmraqd=&XgzJ8fVmnbngk=&bbhyPtVZgqbXs=&FDawhWUaVZXmb=&I_oWo6ZnfWodY=&AqiI2oUmldl_j=&x6rdHbVXc_crq=&9y4SJLYiegrd_=&B6SjWUWWriXfh=&2WD62iUVUmhaZ=&Ns5RhQWiVpoXZ=&c_uLqCWisjlkg=&GoVQZVYsbhllY=&M36xNrVXVZnXV=&6YsqxUZghakUh=&7LYg9yZhWgfrg=&olTs5MXYohigf=&UoKzgDZUZceWV=&gGYayoVcqlqp_=&hTYUsYYVersWV=&OxP8cEVhfbUdj=&Hohz7WVmcjpop=&nfJCreVebhecq=&MidDRBXVjckWi=&3zGut7ZqknoZW=&9bsM8MXiinfqs=&JtVOY7UkiVVqY=&zjmkDgVerfgjq=&sqmbrBWokYinh=&t8AnHZUcpgjog=&kpuYZQXsfWZXd=&6dW8u_UpfZqUf=&vM3doUXejWif_=&XXZqptZ_kXaag=&WuZjcsXlqlbgl=&RI5hDqYhYsrks=&6GTrrDUkXe_on=&UW6QGNWlacdn_=&mkwfiTXWgZjoi=&FE8yRkWsXgp_m=&ElvVYyYkffonr=&VKqzFkVmfpUmV=&xu7NCDXcYcbac=&jaeDPCUXfVVoo=&UqYzEEUfiVWki=&FPd9GiYfsrWWg=&FenfiRUrqYcVr=&ErSgoHZZpimqq=&dpoTWrYgs_fmg=&7FED7PZiVqkWW=&bICFL_Yqs_Xgj=&LJg4znYndlcfY=&bfRHhQYkrmZaq=&ewwxuDUcafXmd=&qvUIp8Vh_ZmWr=&MKPEvcYjeaXXg=&PSgbVPUhYWpZm=&tRTKlEVhfcYjh=&xAEso5WWgcj_h=&lJTBVrUdXpYYi=&tlqfF5WVlonYc=&TEmJOlYcqsfep=&WX3rSUUjUdqiX=&3foqKMZmfosmg=&c3bHWqZdaXoc_=&HVPzFzZlefdod=&Go6YkQUqecgrp=&Nhm8GtUYZfdia=&WbyKeMUmdamgn=&jkBqggVUbo_Yp=&iURiilYfeaUsg=&C_yHDvVWnqsfn=&BKt65YVbjkcdW=&BZexQUYniZmmo=&dN3YdQYi__bkp=&lAT5tIZUmZphe=&_R7iRiWoo_pVd=&gm5yiPZVrbjUb=&8LMFCOYgagoZr=&3XVolDWqqgWlU=&ov5oa4YYsndpU=&XHlUhHVfbpqll=&exdoJeVVlkUUr=&Aze6dWUhmdoWi=&C3W2aKYj_ngW_=&ph9iwRYUrYkmb=&zrgA7hXkgrkhX=&hW7ibMUkmecbs=&V3jhQ3X_ogXca=&uAfxOSXUZljij=&IzEPRAYUmpola=&2hm7EKYZkYUpj=&gAufcEVVZfhVa=&nBgznfYhnllpj=&Qf8lCVYmZmrmX=&2at4VkUZ_jhrX=&UQk3S_Xacp_jk=&aummsqUcXVn_i=&7SQpx6XcYrhfU=&q5X3p4ZhXsVeU=&WxTl3JXbYckVi=&YTbwi2Xhfljqp=&TUhD7dVWllmkc=&PoJ4HFVVYgrmj=&AqA57wVmpXpUb=&Zo82cyYfarVah=&MAJbzXVYXfZVq=&eDe_CaUjkiUgV=&P2r4XWWskai_e=&rooYFNXU_jjrY=&Z_oMuFYesisUr=&aM4oH9UnYhUbg=&kV3zeCXqkrVZn=&iN8dCSUrsj_fV=&MpLbMFYrlfiaW=&5iUbESXcrUrns=&jcIYDdXk_qVhZ=&lTeJLRZX_lj_m=&3Jd38sZkhpera=&j38wAfVqhoY_o=&pX4haMYgUbmcs=&FKA8ohXXsrXbX=&iUkbU7Zipibaf=&XTHwIVXebZ_g_=&VgdA5eXjaUqhU=&kcU2RnYaX_Zll=&GRpHd4VmnanoX=&SpmeSTZqcVrnV=&It4KkpZbUpecb=&UIcKFIZfidUgr=&ZYcCzcYkmiksX=&EieZlHUWdZgff=&_IvlkrVXVobXr=&n6MI5TWdbYmrf=&7aDLD6VfhgkVX=&tKDPf8YUoZZfb=&JKuyAKZXq_ikW=&AapK6rZcnrpcq=&62y3MBWsfq_Zg=&oybFb9Uerhgdb=&zSeznWWdhjpWg=&NT2lnnZigifch=&Jo2SF5ZslZbaU=&nQ6P3ZUgogZUc=&RgcxAeXWgoqig=&DPpcnjXioUicf=&aUhbHCYshXfkr=&tjvWxMUrVc_gX=&iGD8PjWj_npUm=&jCJ7FgZpjXhif=&lFAY9aUWklnjs=&oBYIUdZpmlW_i=&ta_AEpUndgUkf=&NKMWBAWeUmnia=&DzpXaaUoZ_ehZ=&FuX9eoYohocWe=&ZLP_AdVdZnfhb=&HismVTXsXcZkj=&BCmCHMZZcf_Vp=&GUIzovUdVahpb=&m3gnhwVm_pUoX=&uRhadHUr_srre=&DOrvlTWnWfmXb=&5cMJ49YXhgekn=&SkfbMdVac_XdX=&VRBDGLYrmseZq=&bEqhCUZolnrep=&5jzVW9Xgpjfsc=&OgvobWWglXWkp=&BYjj_SUp_XXXY=&LglNhnYUlbgbj=&qgkRvRVngfhVX=&pMnZQWUemeoce=&86xQiPX_eaqeo=&l24QhMXb_pjfY=&nUZdqlXkdgplX=&_ddYs6Xe_Uhrd=&gBtU43Wcsncha=&lnwR44VZjXooi=&eVAL39ZigobVg=&M_amjGXUeqqhU=&goqKu9VmXhpZq=&kiyrTNWhfeYWY=&LweTVVYZVseiV=&jM_yU3UiajkqX=&Y22v_XUWahgm_=&zp82NfYjikYYU=&K4NhShWfkWVof=&uDPsV5ZpfgWal=&jvilPSVrfkqUq=&2VYuT4WeUjaea=&4opAlnXcWYklV=&U2kFv3UbXrgds=&DJzBq2WpprkWp=&2rjPDTVoUUdUZ=&C22765WmoVpe_=&iaLQOSUogZVdV=&5EZ9ZFUhdi_Yg=&5Q4pMfYdkphl_=&TB3VK9Vdfgnmg=&7qD29LUcgrfYa=&5bYZczZUfZYla=&yPmOznXWarjdq=&Ge7AIZYXhdjVZ=&hXP3S7XdnnnkZ=&zALN2KZnmmYbY=&M55PJeWcdsgiU=&ItLlZaWqfnfZb=&r7_zx4Xbqscrq=&RT7n7rYYmWkan=&NHZGBcWeXff_W=&rfB6EMWZ_kaXp=&btCFNrYYprVji=&fWXSjIXpmglYd=&wNtEbqXcUkbhX=&Fq2Q4eXjYihcr=&aW5H2sXbYgnZh=&d_vHXZUUcl_Uh=&rmoCzrYgiXhUk=&9zifrmWUrgseX=&VaWm9OZcYbksk=&dp5NXoZWfnaic=&OMyFK7UUjppnU=&qOIFgDX_r_ain=&ZXp2ivXppeUYX=&BuEhcgVhd_kmc=&JMWvfYZnVgUrq=&YoBvDuXhV_ldf=&bNYFyfZiiZslY=&45F_RaWohlii_=&wrUsGMUVlsdeb=&y3TgsSUlbsXYp=&QmYQF_YhpspoX=&RBVBpgXqW_gel=&JSCjoLUmohWbc=&ir3HqaWV_d_kX=&FUqfIIZbYeWVq=&xLbPGtZsZlsVW=&bwoV3DVVUsjpk=&JaxrlXUlVXYZq=&XD5H8xUlscXqY=&WJtcTBZnVnqmr=&aI94idUfpZlfm=&_iRUdmZsYgjr_=&sE7U65Xhkffcq=&syDYTlUfiZbbo=&vWMxBhWmcqjhn=&zR_TNkXcckUpr=&NbEAQFXingfnq=&AExzMTVffZsph=&9skdnvUZsmVmk=&7gfE_2UZYXnfX=&TcSkGwXsrUdhs=&_rDnMfVskhfae=&VBChx3Vheem_j=&qne7FWUqorjjY=&Wupb6YVXhWbkg=&ZznElpWdVsbfc=&Pg8tg6VpfYrUl=&LhCvAZZkZprja=&Ff_zhuUpniari=&AplrJ7ZfdZdmg=&gNdgMwVUcanmj=&iUMfn7VfjsUam=&3aCHn4YeaoamY=&WxZu3RVoeVVjs=&MC3I9eXlki_UZ=&_tFhZwW_qrbbW=&eH2dXBVgokagl=&O9cwxzVqUkXqd=&5f8G7OUnphfli=&jy5_ysZrmrofa=&qSOoRJX_Urnfp=&rlIvyyZgZsUXj=&RDJfzCUqcrnsa=&TPIFV7Xpb_Uk_=&vXUjl8VrmibXk=&zOYDXmYiYqpjq=&4KGccLUsseahm=&7TcWqQUnbWfbU=&7FEumAVWWZpjk=&o2XaRkV_bZWlU=&H7fXS9WsfkZhp=&NbNc5oXZrikXc=&faTlRGX_UU_cm=&yfesLVXZ_VjUc=&4_bfieWUrcVnl=&B_pO6UVUirclf=&ebzYP_UZfkqge=&smMnMjZZfpWqV=&nf9gPEWfY_osn=&pUkaOMZfrVbde=&4BrECKZUYdlqn=&KSShnrYncVUcq=&6rAEfMZelX_aZ=&Y2sIJkWqlXllp=&vJ8pivWhskWgl=&Me7fkgYmUeinf=&6MYNcnZXeVoar=&8RtD6GXkdbWra=&6OEbg8ZdqiYYc=&tjwSBGZdoZaUZ=&aJHgBZVifjdfs=&fshbdNXnfZqko=&Qwp8riWpcnfsp=&8HcEXyYrcWmkX=&Bhy6mMYhYgqaj=&qkIeVTXUdUfka=&6fkvivYfmdgon=&IEae87VVdajkW=&mZUHKVUfWerYk=&gVeEjTZsmbqXh=&IsuKseZj_ZghX=&OjhNLEZcUWqUc=&OChsihYnUnUqb=&By_Y7LYXYkrhg=&5VNMW9WerYlsX=&zR_p8lVhUn_mp=&Fmli6RXoflsVZ=&UsuUxXYUnXbZV=&8M3hRhXjkmWVm=&ADlFdCWfjdjj_=&ZfphukVmaghoX=&tqkWwIWndimae=&CctLucWfVhWpZ=&UYaS3hXUihnZm=&efraynZ_dmmqq=&vq_XmKXdmesnk=&_MtfbmVYeqihs=&frLip9Yng_plU=&DklKcfZicnUYa=&IpkhlrZlZWgYe=&E6nrJlWadiVZd=&x752i5Wgjlmls=&2G_7FyXiXhZWX=&ofQivIUcf_mbX=&UJ7oFpWgVnofp=&yFWGtaUfbchYg=&dZIGmiUYihoca=&hQo4wSXfrjXfX=&sfRAysZjliooc=&kVn3IgYYcdbho=&QjEExZZndUeaV=&flDJVvXcjbX_p=&jwg5bEV_cVUon=&Cqzse8Zabmccf=&ClOob7VYbWpkk=&J6mbvsVlgWada=&j9Xc5sVlnYhep=&wjAthlVYmbWpU=&e9YxABVhbdirk=&aN_urjZmZfogl=&Af6hwIZUUgUWr=&x6E4ruUnjanbn=&LXtagSZUXsVcb=&ch_h4sVUjbaYV=&LQRid7W_kYgVn=&PEejP4YbZfXj_=&2yoWlXXnmmlWV=&8Le9YRWXdgahf=&uRkiCsW_Ygble=&yxbVnyXWllXon=&jRboxgVsmjlco=&Ao7FTzYqUanUh=&Awl6nDU__beYq=&bMoGXnVehdXpV=&LyLNjwUbmeUoU=&awXxcNVWUcegl=&UpoIUBZYYeXra=&Mww8KyVjVnZpU=&EUEGpPXogVkpW=&9UmwDdV_eafgf=&UwBkbCXXfrk_f=&MjoWmSWgepjYo=&AjiRhaZlsXrYc=&_NDDAbUjkpafi=&jVPfxlVfUfsmk=&gA9upRYnUlmfW=&hUjVs6ZiYZjnj=&pqnclyUVYkhnV=&UXW9xQXYjcosV=&Q9BIxTZUlhXlp=&mB8dQ7UbWpViZ=&t3Gxo_WqYdjpe=&fguKMdYdkZ_VY=&d3WJXCXmUmbWi=&EKM6O8Wdksdbe=&sf2kY8UpqYhmm=&hHPhJAXmqfaoa=&gmJXtRUisqgne=&tkNvwwVocUhnj=&mwlCRJWZkspbp=&zam8l6Yjseio_=>TlIxVa_edni=&AynSUoZndaacd=&g2qLnWUhWpXnk=&fSVXxxZdhfpkl=&cXYZs5VUmflfd=&nUlzKYYrpYWZb=&3iUzo_W_sdgja=&r9zbeNVclYfbh=&bKULNbVpaq_ng=&zoYExpVbYYqgU=&QAAezeWqgparm=&lP3_uhWhhpplr=&7qNQQ2VjdUVip=&5IKax3Y_oggka=&8ZvYpoWbhZ_gc=&EDCL4bUjqjhZp=&RQVsVkUZUkocZ=&T5HRwGZdsrde_=&eA5L92Ujsaknl=&7lmV6TWgsofgc=&uBMRyZVXWmdbc=&KeTGSCZZro_od=&6trF85YpmjUai=&7L5BeRXhYjqng=&mDYakkWgiehZW=&tR5eWCWfhidnn=&fsVReLXirnVUV=&CEtbJtWYZngdg=&ABQoEQWYhkkpo=&SXBnZrZdjedsW=&4IEVzqWbVobf_=&DRaqVsVdkonUn=&Nb9P82YqqYsam=&UbHmN2VklipXj=&umL8U4Wpdhsbi=&x92nr7Yfgeebd=&bGAZhaUhco_Zk=&IV2zLSZXgjjZg=&iqZoVpZ_jsgqi=&5ylKpbXrkq_aq=&24Naz9YmXbsVo=&GAQj6TUgnogUl=&Qas6kNWWknsnn=&4gOlVyVprjpsb=&6yCKxgZZgWsYj=&HQy4QhZqjkanZ=&RA3vidYWipkbc=&56sw9cVW_bUbZ=&Sllkn_UckWeog=&HmIPRpXibnUmY=&qwB52KXWrsaZe=&WfNrKYYrqaoeZ=&gSPAeXXVoY_l_=&OL5trhZpmhYei=&5EcVvMZhmlknd=&6eOitjZhhlskc=&2zNNgIWephmXU=&OZ6sWeYrnUZka=&gZmwmOZVjXZlU=&BzyA2YVVkdXVX=&C9MSWgWhisabb=&cLZVC8VphXr_k=&YmFiSpZrWgir_=&9FqAHgVqciYpn=&BessguWl_jlba=&aJsflVWnssobj=&6bOu68UUXhfbZ=&V3dKLwUljcgm_=&ACMXRxVhVgacr=&fv7T68UhY_nnb=&d_r2_BYpYnYkV=&HKDanQXssZjeZ=&I3evKAZfWVnoW=&qlAEUpYnprb_h=&ksQapoZbaWkUY=&FAvtIPWsXZsch=&tqncbJZeigfpg=&J3lsWrUoUkaZn=&yhWQ_sVsfl_oj=&Mov7MZWhhfphq=&sb9lgOYVqkko_=&C9ZiOSXfolsje=&kWZaU9V_pUiWm=&i77qUHUdqcier=&g4LCx_UifsfYY=&77BpZeWneelnl=&3CoedpYqlrjoo=&bttApXYmdbhcn=&bhAvYXXinfZfi=&iiXIiCUXn_Zqp=&9RhzOPZggVcqp=&3FXAsUYdUheXi=&jKxA46Ym_didZ=&7T5qNLVssdUbl=&Qli9w7WXgafoi=&tNh9BXWsdrlle=&QpucbVYWbXlfi=&Ov7s6BYbfdbao=&icUr4_ZhXq_gk=&loX4ziXsfmcbi=&5wvYGmYlmVYZb=&qc_k7lWjkghfZ=&BFsebKXonVWUV=&IeuXyuVWeYYsd=&f3x9_aXckZosh=&W8ZiyTVrin__f=&uMCN6dV_cUXkY=&QEwkSAWiUmfbV=&HiF95aWZkn_fg=&W_3GtWUZk_WXs=&wh9xk9UbmZWrm=&yzR4pzXjiei_k=&M8DogsXWgcXlk=&h4XEpsYV_Wsg_=&LwbGAxVnccZcb=&RGic8MUcrpmsp=&b67AzvVmUWpmj=&CCyZcXUecglXp=&tYsSicUYUblki=&giJlTsVejjglq=&mpt7EOYiVnscb=&BmitysWmenXZk=&TORkBAXreeenp=&mqlvvjZcficqV=&665gPiYZccfrr=&ZKicMtWgkafYe=&QpvAhJUcsVhsb=&2TENUZWWa_kZW=&8sSlIdUYcZrUg=&8koDfkWdlpjjX=&rHZJceZlshlli=&kHrbivW_YpVnk=&nDpSOcZWkVpgf=&eAYeejUjmUfom=&zwxh7SZUnihXi=&MX6dmRZrggZWm=&K8CxdNVZnUfjU=&cVEScHZeZWpaY=&gk88USXiVWkeh=&IW4rOnXpiib_Z=&sJhdJSYslbsUh=&nUAn6jXhfjnZb=&EbogaAVVesdYr=&T5GQ9RZbXepfi=&Sz4_2eUWXnVYZ=&5utvLQUUZkfnZ=&hF_RmnWnic_WU=&ZzcF24Y_aVXVX=&MUClllUlZsfUj=&W5SvfMYonggXb=&BPbR5BZriVoXs=&uUmu6MXdnhVZc=&9x_i5fWqcWWXc=&ZxsZy6XVpqo_k=&QeSAXRXqXljZs=&zGHwjnWokii_f=&ePZ7jrYZqYXql=&zIXdaaYWgafkr=&QkP5_vZhXbaho=&EblnqyValiYcs=&YNqIjyXbodYUq=&p5pd_AYfsVmaY=&N778qpUsolqmZ=&ewlC8lZiWUUbq=&osXkTnVris_gY=&dHVbCUX_WkeeW=&y3PTb3WYiYUag=&88rVEVXjgcgUk=&E6XT5tYVaZgrg=&ndrSW5YhoVprg=&OwdY5FW_Xeac_=&_eQQVvVUacfje=&FQa_i4VVZmWcm=&Qzt7E7W_ohfob=&iICCiHY_iklsh=&Tai3oNYnnbbqh=&kZP6TBYikrjfp=&AwyjNVUfcpepr=&XFYB9GUqipccb=&WKqifaUpmprUb=&9UaxxtX_qagsl=&3AvLfIWffdrVr=&MsVayHXljelUr=&OYRHiZYWZsllb=&OklsSMZhaaipl=&8jgX24WijYjUk=&gscBeaYqVdqbX=&LdYKxLVll_qfV=&cK5nRJZWWcrmW=&37mg2rXmXcaja=&W7y4INVVY_qap=&qTFFu_ZqcpboX=&YRMgMrWgpdYeb=&OZIiUoWsiUrVk=&B6OxbjWcZbsUU=&dKUp69XbepgUb=&oAWl3SWqdZasc=&sVEEo4Xiogmge=&MTtYJhUhifrnp=&6SuFDFVsgWoem=&w2gbY3XrVrmWj=&cWMrvzWndVZkq=&U3EZ2iWhmsqgq=&hOGRMrZkcYcXm=&Gj9kheZVZmpoZ=&DKZqgnXlcV_X_=&toPCvnYnglakd=&UOuyR3Wndqmqa=&WrXdtJWiapqjq=&6qgnSmYj_WrVc=&yfWu3tZm_Zqor=&Bb4mlGXocYpoZ=&GUFBNSWpisWYn=&YBeiElVWXsrkc=&LC_dtyZZYjosp=&d7NMTzUYfemZb=&PZO2lAYrk_fgj=&GAQpTYYnbcrkg=&h5HhyiWjj_fZs=&pjIlrSUcYXmsk=&G8VNRoZUXsmhq=&ZKUPurYfpjsmd=&9NvynaVYccgqr=&LatPteZfpo_ks=&eetgUaVmcqbso=&QaO3_IVUjkndn=&E36Da8YUoWoeg=&nPsWwJUds__p_=&EGbz4RXUcofrg=&GgvN3DVspnejc=&l_KjsRXdeaYke=&e9qnFbUZooZXj=&eTnEcbVcXZZfZ=&RFxrLyXZYdbcc=&ithoUZVnkemdZ=&RlncF2YdXlYkf=&tRPn6oWagkqYe=&uJ6PbdWg_ebih=&mY6ze5XoXkUbq=&oMo4MkYcjYdo_=&f6gCI7XigrbUc=&3GYV8gUjbWqpc=&EFrDNxVqmg_an=&BuCqjuUocoojg=&XtYmQaVfopXre=&B_N8cZYW_imYl=&jVSuamUodgjZa=&e5524XXoWgUVs=&yDeVRHWjcVfs_=&HsXHtGWWhhhWW=&ULzqqtZZblbdW=&4Vl_YcXVmqfeZ=&qOWPOKU_XfYnZ=&vbtJHqVgjX_jo=&HtpmBoYZ_nhrj=&5krjYCZZZ_ikY=&ORl_O_UVkXrhd=&gafkBhZab_fli=&N9QRZnViolWl_=&xWHgNtYrhVZkV=&hTScaQXWlrook=&UtKHPeWeslXqk=&iZeGJkWiVWUam=&wnzEeDXmjgmYY=&shLgNfWepof_h=&QbfsRAWcZlmme=&MmSjHAVhZrcdU=&Ss4mWJVpmdghX=&NBiGGVVkbVgnk=&wLIzF5XkkhkcW=&LB4ZBZZlWmaod=&h5WMKGZUdh_Zs=&R5fOcGYoYlnUZ=&ESZX3CUXoUXqX=&oqY24gXY_bnhf=&_4ksrNUheVicq=&kdqSsjWrpYiah=&L7fiF4VWrXsYc=&AwaXhJZYassoV=&p_rJ4qXikcYjX=&g_gu7zUfoUkap=&pMkLeGUgmkoUp=&TPqUkpYdpiscs=&8YX4IQZWhWejp=&OesLO3VkXgioW=&FHaxcpXigYelj=&2NttDnXgamkUe=&Ni8_rmWhgpXVo=&crlph3Wl_dadU=&M7dKlDWniWnga=&3ue2K3VXeVhpl=&NttgFmZhqgYdi=&omBgf2ZapZXgi=&x3UyNMZmXb_ka=&IjX7wLZqnqYcs=&qGDavgUqV_jWp=&pOwdgtXjoWVlc=&T4p4FsZXimZbU=&ZNSOUdUqXodiq=&w2zfwQVqhjleq=&ZDPOcdUgirfXq=&AMqDdJWVXcjed=&Tc499ZWYiqsqW=&cMkEXHZVWaYWr=&TrY4gaXjbnmZX=&Nen67nZerrnan=&x9zVubXmegjgX=&3kz5NeWWYYXbn=&HtlTipZWknfZi=&MX2zcBYXZarss=&Z3HpSKVUarhni=&l4AyQCVbdkgjb=&Rjx8c5ZlhYsbV=&dn55_dVnahYhW=&Wd3bdRWUnnmcX=&xdXP9CVfYUXea=&vnzhTOXaUXffg=&EN5SI6UUVYZqh=&84TAtlZqfassm=&LSqgiDUhnWejs=&tGwewUXWh_dhs=&E_mayaVdhclbo=&DbgdxiUenpfYk=&JLvFBkWidrjlW=&EyPhM8YVfZpVh=&NTkSfHYdYrhio=&CJgi74ZesVeqZ=&POeeesXZmVahY=&gfXrTBWVd_oam=&n4yRArV_VVqpr=&PIK8yiVnbdmro=&pM_fEtWlYnWhh=&gBaZkrVnYdeZm=&iOm37_ZkchpWk=&v_GpkyXr_fVch=&Faf3yTWkXonnh=&K6I6BoUcfYVXb=&XacqITZioYjnY=&ckmJNRYelXmes=&pa97CyZWViWbZ=&wRUNleUeqVWUZ=&vZNbwCZpbVWiZ=&83JvE6XVZkndW=&foAziiYVrqfYk=&exu_zAVsVUaYr=&rcDFxMWlfZoea=&fNjWUhVmrkcfU=&Ed_rmsXeVojbp=&_Y4GCSUpopees=&SQ7Tw6UeWgUrq=&_xbsZwWnhX_cl=&HC2ZyxYqqeael=&7WM6CQUVUZlep=&HrXrqGUgUbY_Y=&hwqYgLVYZWddV=&OLwSEnYgdmqsU=&eQCARcXZgqkaW=&yD_hBwZYkXemW=&6agkRfXemsbao=&36xriUYUbodgo=&vFZagOZlaqYUW=&ja9HKXUnnnc_b=&vZULMkVXmqVgj=&4FOPc9WhijXXU=&cXNXiHWqUhhda=&ucMv_cVa_rZWp=&r_4MRjWjhbjje=&u47WT_ZZqedVj=&L5Qz5NWmVs_Zs=&CFoWyXYhej_mf=&aIHtDkYandlrY=&t8P6uKYVeslVo=&V_8IZvXVpbofW=&XcPjP4Xksmghq=&bRecVTYjscnrk=&i_pYZgZjoWYjo=&a_ijgxZXXeUjj=&HXCHD7Xh_aopU=&SDtjAQVilreUZ=&eBhpJmVeZYode=&yMmiMIYmojgYg=&TdLnrAUVorhpg=&As2eUCYhlahen=&kLnpz9VYZapi_=&_dMNHEWVUqlam=&HKN4CiUfeassV=&Q5gqBqYkdXZjm=&bE7l6TZYdpqdn=&tqWFvLXorghjj=&b5bzdAVZdeUcU=&ShKoQcXkXmfjq=&2xaRRkUai_lXX=<HnynZkeXVnY=&5dwzGNZYfUrap=&2Io42aWlr_cbf=&mweTX5VjVqoaq=&g5kQkDZncZoor=&FjGPI9Vrdqe_Z=&ke2TJWXdodVXf=&NIVi72XVVWbff=&7aJB5nViYUfom=&pVtHmOWjieghf=&U9f5ZXZofdkdW=&6jD7KLZVddgZq=&eJCUMvYj_gmfl=&hwSzz7XbdbWge=&QuN5g3WmgXVsU=&FaDbmaUmYljjr=&ImwJ4RVihhqpa=&6jCejAVYnkqWm=&zekKHdZZcideh=&grooqhVgqVpsU=&732cUwYpUUsjW=&pzg4vrXbVXZrq=&psUbnkYiklnbl=&snrzC2WnldZmn=&_XTVyDZ__WbVq=&DEeahyXmhWhqU=&H_54_VWiaYabr=&esyBDzZWbirYr=&5ljVePWifYdcl=&ETPnsEYfUWgop=&QRYgmgYfeiY_Z=&a4F5_RVghamam=&llvFVeXj_nmlY=&IueQuuZVkshhV=&qfXVv8UqjiWbU=&kMdH_QUbaUlgn=&jUuETIVmrXnUn=&GCON_bWeXeimW=&bOR8C_X_Wgaon=&s7XWqnXkdpmbn=&IMcOvkXohWWhV=&roN9D_Wrkglgo=&Gxm7MbYXnhedb=&68HTkoXqgqnop=&7AfSK5UpbfZZZ=&Ru6Gr6YVrhdfg=&pNFy46YglUZbl=&gfsEl9VsqXgcX=&WyGqaGZVbifqZ=&RfpYjLUasbkgp=&k9bT9_XeefXlb=&QSjTUHXWaWfdl=&g5tHwTUfXbnoU=&lDJvftVqlYWli=&FGd3G_YoVriYd=&eAaJgkX_qjgUq=&5ErvtyZoaZeYU=&XqpCTgYfl_slr=&L5w9ZjXbWqhXi=&ALICVyXarl_Y_=&5BaBefZnl_qih=&iGe2FDVbosfmZ=&lGlbjwUahVsVU=&DsoeIcXYcnXer=&pnwpJTUmfajim=&kNkQ_8WhhkW_X=&mp2dnHWbVjidc=&2EewlMUcmcepo=&vD4YHwXbZfqde=&lO3iHmZYo_mXr=&oi92bXYfpldpX=&EmVH57Wibprei=&ykxGsjXfkdcoe=&jxx5oTXgcUsog=&DpqEzCXclYmXf=&MsRzihWfdegfV=&BSjdLhWlhejfo=&a9pVGSXiesodX=&dOUXtTXVXeVZW=&OVAplHVV_YeXY=&rKlKuxWhkclrd=&aE2FqnWYclasl=&HR2kj5ZqZrbj_=&qyjqWoUXbhpmg=&cKasdCUdUrseq=&PAsc63UZaUahX=&mWKnXAXhijhib=&YTaltSZZWlZrl=&mPIEoZXmdqVUe=&MyofTvZWbWaaq=&_ymQnZXmkmXkn=&XDGHHhYbdgsjj=&EufugaZYZfhoe=&ty_z_TVlUmYae=&qceRNOVmjkdVd=&Q9d3plZfkngqf=&lSAmohWWVp_UV=&ipAfQPZeh_khd=&4FFkWFX_aWZad=&PsA9g4YaWqgol=&NVPu7OWcWsVXi=&aY_J5QVmeaior=&s2BpY3XaXipVa=&HM7xItWqsspj_=&cYPsmVXXjfVqs=&K4Pg2UUjkZrWf=&PYYqrOYimhnXm=&5SlQX4XpXhXYb=&hlfWF2WgXqXbn=&tLXOEQUbniWgm=&oRorIZXspkhWV=&TSgohYYbmkooY=&Jkggq5WhfWcXV=&M359WhXkjnhfj=&v4hXThUZ_ddac=&OwuuxMVXbiZag=&U6h8ZeYnqdkna=&MiTse5Vklngpe=&_gNMScZgmXbnU=&QWYm2KWqWmiXl=&NiDWt9ZeY_inc=&jDoPnmZofmWXq=&BZ96GQYlfaZVc=&4huy9KVekjZVn=&n6xpTGWrnVmeh=&fLj2TQXYohqhV=&_Yc4ceUjcbkjZ=&I4HVoCYYjqnhh=&jyPJCfZajUmVa=&v5pw3gVaakfjm=&iNSxeLWkUnldp=&26KeYZWmeomgs=&ZBNcxTWorWVVp=&iGbhGHVdomopl=&za5UQFUW_V_fV=&zkYJwzZhjqUWV=&lQGAZ8XUiUbjh=&_24VuqYaosgfV=&ctYtdiUkVjYhd=&BsZZHUW_gXigo=&TwAT5OVbjnZZZ=&NXnEl9ZUWZnme=&LrbjCDU_emheX=&T_hifwX_Udmdd=&xzONfCXgUgn_j=&eT8KzlWqfbpsg=&OTZNRRZkVgoY_=&APTFHnY_iWogm=&kLv6QgUVZgcVr=&Jy3ujJWhVYbif=&IT9SOKXkfdf_e=&W4GiQgYsokhjg=&XlfEDIWYboZkr=&RjzSsPZVUjZed=&gR3gndZkqVbor=&NDMQ6aWVZWnmZ=&5LNTJQYeiUkdo=&N83fsvYqWqVbX=&uOGFb6Xaqqjms=&CKWbZVUZYocrs=&gHx6YyXiYgbVl=&6xYoFOXYaeblj=&3Fc4M5YdYabja=&LhIxHfYYqjigZ=&xVkZvbVYsqqVY=&4r_XvgWrni_Vo=&JTSuT4XbbXlrl=&l9rnMPUpnneso=&yONs8KXkhdfWh=&aPNtpAXkjoYVU=&LWKitmZmfZlUl=&xJboQbVWmdmnc=&YLtPqaYspUs_d=&4Iacv_WWgkmar=&oDCQj8UVl_knb=&v9LZPgYljdpji=&oK3YufWXclnoX=&zrMKsgUUoqfdd=&k8h6l2XUVomsW=&qiKATUXUnhbhf=&Mg35HeUcUpnao=&FhCccMW_moZ_U=&6T4ErbUiahdsc=&OOkaJJUqmgakp=&QAvxo6Ubeije_=&e33N_NWZlsWqV=&fIb6u2ZVlpVUm=&cW9ZWKUjdXggl=&pbOAEpZips_gc=&e_UYIHZUYef_W=&eEj7QIYpVj_bm=&eIgY_nZYljiXk=&L6YzthYXqrkZh=&LALIZsWXanXVq=&bUupvdZeqiigW=&8XWidBWgcgrdp=&3SOxAHWeXVihU=&PlJXXtUWofhfW=&mq9RUOZpYdekX=&549lAiWYjoiVh=&zBWCeAXoYgqdb=&9jjV7lUmenZbU=&X9NkL7VifoUdn=&_rkCgbVfpXgXi=&iXkpDQYqmclro=&y9yskCUhinjoi=&NfZc6SViakffU=&8ZN4LaWrUjrbW=&B9Ah7pVbijU_h=&TMtg5TXflnhr_=&DP4oGgUVcWiVc=&E3cxA6VofchZZ=&__bSrmUY_mihW=&X66Mj9YVVUgfY=&LlGAifV_UYViq=&Ew3LEHXUfZXgh=&wpKRiRXZhrcZf=&t8c5D6XXZemYY=&rE59tFXim_lYs=&SPJX6OXkjYgoh=&lbr35lXnnaebn=&bqGrchWfkZcUi=&VT5iklVoglqic=&MyFdTpZsnlpho=&8jk4nFWedoajo=&qeaBzIYYeimj_=&vNUoCoVlaaosr=&qsSQ86ZnUd_fb=&rDNF8VZ_XinmW=&KEKhpiWkerrmf=&ExlZphUqqp_jY=&jbcHWrVVX_olV=&zN3b5VU__WbZX=&VaSKobYbUfWbU=&P9KXCDWrekocf=&g9U2gfYlUdjVV=&TbcIJlXdYUl_k=&xxWmcFUaopsdq=&luJSQcVolcZnb=&9ZFg6mWgWehlU=&6ZsqIOXmcXXUi=&7YdlQIUokXbef=&tFfbb8VjZebpk=&WiWSfYXXnYifc=&KgctRzWr_dreb=&HI_vpNUsanoeq=&kXBCYsYldolqe=&uxY5CQZqmrpYl=&Q3eu99VeodVsm=&RoP7gjWXbegrp=&R37lXbZdnWoom=&o5kkK7XhYgpga=&iKMHDXUqVegiX=&kiIQg5UbkpoVg=&4oNc5ZUWXmYlY=&xBcVjfXWjbYYj=&ZlqzTPWarbrrk=&Lo6cynZaUh_ic=&JFGUiAZoZfrnY=&AIKIfdZhaUqWf=&m9svs4Vplcncp=&4NKcJVVUjqYfk=&9CLtSxZZhagil=&fBQEgfYVfakqg=&zSTgWDWkrlcki=&P24BXNYjhhddq=&pGsMPqXrldekd=&Swb_uxYVabUX_=&dbaETnUqhVgmf=&vRSxwJXcZkqf_=&EB2RObXehWZmY=&pjhZfoYU___lX=&eA7hG5YengUaf=&vT22ytWYflUgm=&hl9A5RWkZbcVr=&4tbZScXnqeskd=&YYZy4HZaUnWXn=&ivzfeZUnflXYh=&sOphiRYZcZcYe=&g_dighXrnWpal=&dDPKgsVWZoshl=&z4aMzlVZmmZpl=&w_ACXUYdV_eeU=&4vmBSHUqqdrVY=&EDONtSV_kfl_n=&NoFPzoUbckoWW=&gdDZrJVqbjpld=&qoVNnQZoVj_jg=&klporQYhmXUXV=&o9Xz4tYdqdXjV=&jiEUebWWiafkc=&Z_7gsNWrmplpl=&diYFwqZlhnmeV=&rCrtVBZUj_qXp=&M2hfvoVrdYph_=&nkDt3BWoYcpmU=&efZReYW_W_m_i=&BmEMnYXYlolXh=&J4q_x_YbhoqWo=&O8EjPfWjqragX=&4bwx8EVcdmsng=&2qWd6qXcd_Xcr=&IYQa7MVpfbgpo=&cRVj24YcYrsbq=&UpeyTgXWmcUc_=&7yCBDUZfZodaj=&wuXWm4Ysm_UdY=&NsnC4aVgreiqm=&hzHiVBXUrXeVm=&sG79nIYZZksoY=&8sDMzZYqYUYXq=&pHUVvhVanYko_=&3d85LiWjrmmdj=&p2Z3oDZ_qiZlY=&2LbNFVUfUsdhc=&dfY6_fYapjkZq=&U5h4nDXZWYpbr=&QXh9pvUedflUs=&38NdIQXbspeed=&PfE4fNXklZgUV=&iTVXcGVkkVnol=&LoFRkuVbhpWhX=&tCuNIoYiUjWrh=&jwVHADWikhmig=&JRTWVgYi_heeo=&T4xvdbYgZbcnW=&4mROaLYseseca=&Tn5OWUZlqfhmX=&b3O8CyXddccYk=&dvjlpZUZlfVij=&nqSJpCUXqqllj=&lL87XnVaXgqYq=&4WZznmUapmjmh=&lpAaoCUXVWabW=&yHHm39Vqbck_d=&lv_cesXogjWrk=&FW2auyWcqmsre=&pgJu6RZigcie_=&ger2oaUprahco=&EheaSHYWrZsrs=&CcGkNBUcbqg_g=&ZvSmKnUbmUied=&fTtdZqWVebnqn=&dLMJYwUmlskiZ=&jFsL6TZpnlfZU=&LlVBWtVhoeUYo=&FoytCUYdqjVge=&t9hBJXYrrliUf=&h9Cu2_ZaqfXbp=&lVbXQ3ZYho_nq=&Hix_YBYVmihc_=&4i4xXAUkhgmhl=&Y96meHUakkpVf=&E2EVP3YVcfhqd=&ZMBULJUj_lbfd=&FWgOjCZfUarYk=&gWRBLBXpYiaXo=&zIptkLVjVUpqb=&2f23t9ZeVWlaU=&9VNvqhWhnYsih=&EFasTVXikUhbd=&AAovYYWdcobg_=&DRGPRxVUkZbil=&WIqObEXfZXgas=&ENwdN4VdWlV_b=&fpcOtCUfagfVf=&YIb37rYhlcene=&d9OXzAYpsZrlW=&drsWtIWhkkmbg=&U9fcYAZrWiW_U=&CMdmznXXjWf_g=&fHpsVvUajnoss=&afeyIBZefWbsY=&k_gf2fXcgohjV=&y5pKVnVmcdYfn=&rmXGKRXcfXsmb=&6Ey9eoUmWZihm=&OaJ32_Ufkmqdh=&zMI4YZXdnmarU=&XJCo_CWhUjXXb=&Iern6FYXiVbXd=&xx4TUMWkroWYe=&_KQxwUZXUeVjm=&uWhMRXZYcWphr=&PL5zaPUjpcbhX=&NQbFTxWqmZacn=&GmvBwDVbrnoas=&t4JGIcYjbVUbc=&6lEaMuWfZnbWl=&Xg_8OHUdjcddc=&Mab9cmVYfrjaU=&_VoeKIXiiqkqd=&eOTeBzVshsXnk=&2cu5qYZ_rZsfs=&jCKcXQZfkjo__=&f56XZ6XqXXUZe=&EnOUUsVcndbhp=&eRt5NNWUfrhbl=&ALvDZnXdrkoqn=&DrEk_EXrWnWkY=&MpkdkfXdsUjdY=&NhPmn5VbbbrZl=&hr3VffVhceYhj=&cRNa65WXrcoom=&wjJQAXUdpWhib=&_Vt7xYZldhpd_=&enYGY_YVWXdsd=&FFE9muVqqZWbe=&nAUvq3VXnabrU=&_3MgmBXskgal_=&57hzixVrojg_l=&s5N3vJXbjsoYr=&5qxC55UjhnXae=&La7HgTX_pYhla=&2wPfxSXYXWV_Y=&QXLBItUsqlpjU=&KXJxqCUkUYjcZ=&K9brG7UZqqsoi=&c8Zd4PWnZrodY=&ePjFBRVqkfZlY=&VIvkeYUppooXY=&Z3UBzkYjjhgmf=&ZoohrGYrqjVqj=&wBv74LYcprhXZ=&wLdr_HWcqhhno=&gf8SHhZfVrobo=&bk8IShYUUhane=&vYoCNFZhccmgq=&YqssbNWbXeodk=&QE_DaFWngZXhr=&OOxLfUYmdXqpd=&_Qzz6wYjZldWc=&kfzU5JVcapaYY=&DkWeuoWabafjV=&JZcQKzVogrVrg=&4wtwDbXZVrigZ=&vrqiLZUYcceUp=&gbibRHXYYljhV=&yS8ySgXdZs__n=&ywJqF9Ynppcei=&8Gk8OJUbajjkh=&OS4iSHUXoUYsk=&3ZyNkBU_enhkc=&HOXc23Ub_eYsZ=&d7OEPUWUUYllj=&nwwLBOXklprlV=&khnkK3Xrsgjkk=&uhcvkpZakdlUn=&BpuHo6UZleapo=&nuTEFpZhXjnsa=&8qDgORWUYkYeU=&YZTgqWVhUcsno=&cVYGpDZXVdfnc=&nyw8ucUjd_mpg=&L924GmV_cp_ag=&9KyQhuUeiXqfe=&Eu53RNVsqendk=&aJFdXsW_ehflm=&AViXJdVWrg_Ud=&_gqimrYejkXbV=&2jLOm9ZsUXXrW=&DnGxT7WUhZUeX=&ZHVxf3WgbkUje=&PZvDdCYmWcrrq=&OD6rHBWfgZmlf=&JA7xXWZkhVfnX=&zZJMPSYgdrXdh=&I7ptcGUsamkVe=&7_ZiIIVddgUUb=&sn858BZVUccrU=&bbSR7fYVWWmia=&MUBJ6DX_Vclcc=&Hy9jidWXqldXg=&mqfa4cXdkjeWe=&DiEFWeZUsmVfs=&kv6ZPtYcVXgcU=&xe3K_gYimrqWb=&BeATxHXXnkkgY=&kFbmkdWaa_cqo=&PtYOrUUmdlsfj=&pUocjWZqaXpge=&eW7_oSWeoZshf=&zp9eTNYmUVglp=&pCrpTkZsreYaV=&cXQFwoUcjWlkV=&MGyuATVWboZlc=&FiY2mUVns_ekh=&gMTiJGYXni_Vc=&V2KvJJUfYYjdl=&rF4HVCWo_WneV=&DnmsVZXeU_oWm=&kXAm4_YskmoWb=&qPJHW3Vhibahe=&7PIgSHZiiVore=&rdxc__Xolmlhk=&QlxSWiZfWfYdh=&CZadY9UsohanX=&snrTedYZocUi_=&X5JCfYUdnXUho=&rdnreWZZngmUc=&Qyj3lxZkoiXcm=&Oc7ijoXZVfVUV=&zFL9lAWkUdekq=&IfMBiKXjY_ccf=&LhOrkCYsUVoZW=&gbv5qTUshUlqg=&kEuTU5UjkasZe=&YT_GMJXlflaUh=&nNhS7oWXYs_aZ=&N8ZFzsUYcpUbg=&LsarMmWjpijk_=&jqxxgbYjkVqrY=&HGim4IXrXbUXY=&WA3mFUUhln_nq=&4_5zGNWfn_aiY=&fZvbgCUgljckn=&Y4QTdKXhbmVqU=&pxVWqFYoqZXVU=&TrFwGXZYjkV_c=&pf_ilIXrZk_be=&LM7pEdVfbqobe=&QZ2MA9ViohskZ=&_YVytaXWlnlsl=&Y6sK38Womaih_=&ORPb6WUlqYhZa=&SOHUPFWVXkqhb=&tgsTtLWsWiiXc=&2hqfR_ZVgenfd=&TU_zzfVeZaaqh=&Wfj6tNXbseg_c=&woJvSTYWspWjm=&K9o5puXmdjhio=&B4rQgmVeWZh_Z=&QkOAABXkVagZX=&JlXbfxUqpmbfU=&7RfjFoUalUrin=&uGkgvjYVZdZaj=&52KvvpYhelXqk=&eHJNylZomY_Wm=&7XY9TbVpfiWZi=&cm8vgYVqfsoYf=&jYIcaeVfmpaXq=&R9bZhsYiVpnZZ=&IFEPRhWlalYih=&zliDRWZkpZnmf=&g7ExTLZ_dhc_Z=&snagzlVVVZsYW=&fcwj_yVlVbnUm=&GYVzaTVfggsff=&iqR9khVmfmb_a=&z4LcxHZroeqrj=&Sp9i28Ughnsas=&C3v_HaWidWVhc=&lhltRMYYnadiq=&aFgi6jYlcdsmc=&iBLIbAZVbYpqc=&Q9B7MoUmbidsg=&YTZ4VKZmiVpaU=&ZHag3_ZVhUoYm=&pBgRQUYhqhYqY=&wBM_vUXdmVrWp=&MJSPHIYggsqXV=&WVWNyJU_dnjkV=&rBsEE_WUXeWcm=&k926kUVnYpijf=&gvlQHFUhWWdoj=&VCJJgMUllraoX=&blByfbWrWisfW=&2PCgDFXrkadis=&bGwGfkYhXVpar=&Bv6fjwVpplrUd=&hAwtcrWbUgpbn=&zB9MZPYliqnpi=&xGeOTFXehbUpg=&_XwbEqZfkYaUX=&47DcDAYjfcmjd=&hjtsWgVoWjg_o=&v9bZfnWrUrdfW=&IajajZXoehUec=&VJ9UpcUrpZoXm=&okxdDoWmWoim_=&yvWC3RVWdaWoX=&3W2WsoYkVWdZh=&4tNuC8Vn_klkY=&KkDqtOUikijlV=&9O9Qn2YcrskiU=&6T3r2zUdjrslo=&dfjeQIZWlWZXU=&XdYOqHZVmYpoZ=&yDAgViWkkmknW=&CQkrUhWhofZjZ=&PM7kCVZoUonlk=&Vw2nTSXkjU_bW=&6HKl8tZlmaYpf=&VyVxWHYhdXrWX=&Vgh7yiYjmlYmn=&HqB2ZzXXejgrc=&_3F9stYsXnnUY=&Fg2cBqYaXdnUV=&2XmTRsYanaXcn=&Hwt_ezZZghphb=&SRPCktWigpmUX=&EiLIjeZidhgfh=&rdYrxRVdgfchq=&Mznpg2XYXWagZ=&DncCK8WdXZnpb=&ULgyW6XacWYag=&WEsh4FZZjjdWb=&nLM9SiZqsbaon=&VgZllWVmqZaqX=&wPb96tYVqlZY_=&GdB4TtYjWhbnW=&At2woeY_eqrqY=&tUPsaJXgnqrX_=&b5FSIlYdsj_gg=&2_AX9xYcqfcZs=&7lrJWHYVraecb=&ck6DreUbpbVnZ=&865vulZUqfmqd=&i56YLWXl_nmbl=&kQWfaPUkdsmlb=&Ad4OjzXinoomX=&neUjd2WgbVedW=&Ozd3zYYkqk_VV=&BhDIBgYodXUYX=&bgWSJTXaaXmnf=&xpz3qFZoYsoaa=&QI8jdCVlloXim=&88eEgrWaUoeqU=&8iGyUMVaX_ZlY=&xHLsPkUqic_nq=&WkHcpmUiYZmZh=&zc6rzRUamqsfZ=&2oqMy3Yhcbrdm=&NEn5qrYXXilfc=&I4XUtRWegU_ro=&G7Op8hWodceZg=&sKzj5SYjbqorc=&rz7MAXZfjVgaa=&P7VQMoXbnaemc=&_VGCACX_sWWlo=&4nqlnHVphllWr=&jvmKPpXosfgel=&orVMfWZcsYlks=&JsrYIXVXadZVZ=&RH2h5wYl_Wqln=&V9lrYoXsrWsfl=&wcyEFLVrkaYbs=&tcWhtsUe_geam=&s9HgQxZqefbso=&zfEarDXqXsfdf=&jwcKJwZqWoisU=&VgWbQJWlq_WWr=&PoiRvoV_kbplW=&oTNyHdXpXig_g=&jK3y9SYqorgYh=&8cdDASVfjcX_g=&3EqGo3XphcZWV=&KF_xaVUYgeUjZ=&Fh2tKSWsacqre=&tL_UMWZrYUigd=&Dt5snyXWhnXff=&cWfto9WkhjfZp=&XQXbAbVeekVli=&NP2JdfXksUmki=&cD4h4KWgWhVhY=&JqGoJtVliripY=&t4lFLeWprgeka=&Dpu9jcUgindlb=&9M9p76XWanhrZ=&ItdZzlXsjXmXa=&DYo6TQVVWlUqd=&OFrzLRZcgWjXf=&dLzZeHYWrZnnk=&suwhoaUbZfYkj=&FBsLy9UYjoXii=&u5vsYBWjW_pWb=&i86X9rX_ZkbVp=&npiM7BXrcrkmV=&t7QItoZbpblge=&5SiJz4WgVU_nq=&J5PkjRUVsjbdb=&sXlx6OVrpopcr=&nGOUVlWgrqfZr=&eGd5hSYirmbcd=&HmMxkhYsVoYVW=&jAWgdXXUkVWlr=&TOl2OpW_pslXs=&Z4fnkrYbXchjY=&wROdaHXhYVjpd=&Yv23qJUmaelrs=&VdgKecWmeafZp=&S_vzpXZVZhYlo=&yX8CWLXfraYhe=&DGTTALYZiYfgZ=&_a7bZGYliin_X=&WfjwlNVfWhieU=&a9fxfHXWkYkiq=&nxJLApUdanpYZ=&3oPPDZVWomeoU=&o2h3HtYonYYrn=&NTZucLW_lsdiX=&cCHW4FUpaciXg=&_3ran4Uhnqbqh=&RodBJ2YUUrbma=&_F5bPHVilXXmZ=&vr4AruXcVleac=&WBZdyWXZjVWhl=&vTmQj4UsiZbre=&3QZNUbUhYaZXr=&_HB7DgZcXamWW=&gpxWmlXiWXnns=&xQiHiyYcrYsZZ=&f28VzgZqqnbsV=&AR_uCgVfsVls_=&DQuvmtZokmmqj=&U96bzDXk_oZfc=&aii4VlYnjoik_=&4KvDTnVidecoY=&wPyVCTVZkpcip=&TjNshnWWacXhm=&W4lwLJXrdceeY=&l9C4YTVbZjYZp=&McuLPdXYmrYks=&UwvTXfYefUkld=&gf2EThZVqjfds=&OkgbFuWohc_fZ=&diyHknYVkXren=&_gMIhZZVseYaf=&jKjfDfUaUonbs=&u6ZBD3Xrbophq=&Kg_rcSXsdscqq=&bsPGNQXjkikis=&PaLzm8Ycrnoid=&SiO7W7VXZqciW=&CRj6KCZghsmZr=&UbgbkwYsfiWWk=&7oYDjAYXknsVY=&8NAj89XrWYorY=&iMzzS2YkXlpna=&z7ypwCUnoXZgi=&CWri_zXmsj_lY=&s9aYssVnrb_lm=&XhIB8tXoYerhX=&Rgsqc6VpilkZl=&qxqP_nVZhl_sk=&8hylLvZphlhYr=&x3IZBKWdcsmgf=&PsNsUFZbZXdmb=&TMEvM8VW_sYWb=&d42UyGUZgisfU=&QRChN8XqgpdW_=&FmClLZXnpomrr=&G5rzBGVjeYWbh=&ISU3_MYjqrsXg=&ILvnBKVbec_pY=&7ZyIvhVfiVmZi=&KpMeD6Uk_jfei=&MIBsuGZpmisg_=&mCUpWvXaVprUp=&BiaItKWcbrjeW=&HKHrHYUZskcWi=&LlnG3KUcalpVj=&u6mDKcVfnbdlV=&wdFOfxUeVVafW=&GFRvZjUmneWch=&hKWuCWVisUaps=&Cn9TgrY_qabon=&Aav7O2VVjlsiV=&RnHboaUdmdn_Y=&zKnGhaWrWhhjk=&er32N_VWkgrXZ=&oIXAgiXkcmdXp=&R8Uar5VYlUVZ_=&rwSMxJXmafmZr=&VOHGGNYgkilib=&6vagSaYYgdkVV=&X5TsaBXcYggqZ=&tQMy3KZbZjUlj=&ZNXasyUsscnol=&fMac8OZcWcshd=&x_xE43XgjYZhY=&LpUuqYYslZj_c=&UagVrKVdkadVd=&nV3hadUfncoiZ=&ri6YPVYbeUVgd=&sDedk4WVdka_W=&92qRv3VYXkXp_=&mkXl27Wkf_ncs=&UAWvHmWlmUscW=&8CjhPzYdhsbWX=&dzZXKaY_jUVcb=&K3wjB8UhdgZoV=&7QkozWZXifXWo=&7GnljSVlpeapk=&yYUZJ_XcZc_Yb=&3eeUNVVmpijXb=&qUGmpnZnlk_Zp=&wFPUvQUXnssYW=&IiQ9skZgaXWcj=&U75BLRYaXkorm=&Fbk7b2YcclYeq=&zA8adAXpqsoWi=&lUaZcHXsYh_fr=&hVWtuvWWpVdnV=&X8vCZfUcokohV=&286k8_Ub_abgp=&frIAylYojjcei=&zBHqvzXYZlssb=&AEACpFZnqdalh=&5SXR5eYZsckpX=&hy92EyVpmoUih=&dB5Q3ZWeXnrdq=&SNbZGmYfkdbqh=&EWbA5uXhqqgk_=&UlOOd9YsmYffl=&VQPw29Zamnrha=&XnceC8ZZaefej=&GFn6QoUi_haql=&zExe4sZgeeUjs=&uBOzzvYgsqWeh=&lAZnoJXYUpihY=&OmQKB9YehUUXe=&kvNamMVdjUXng=&nI2yTjYiekhcc=&OYGJTfXUf_YZp=&x_YZJBYaVlkZg=&tFyOFjVk_epgX=&SLsLxhUgrpqpk=&bbX6FtV_aifrc=&JyEUXJYsne_Vs=&7A56MDUeeUnYg=&8q2CbzUUXjigl=&gB2W6TWY_ikoh=&myLLEnVhalhlp=&872S2RWcXaims=&gRTJFfYrYqcYb=&VgOGwbVZcdlX_=&slyobYVaheclq=&ucQ_IGYqWcccX=&x5q8fxWeqWfnl=&FmiYD_WVrhmcW=&kh_JAwVXqjZXq=&SweOqcZmfqqjq=&fHnthEXhmcecc=&qOfXDgXclahZ_=&dh7Zm7ZsjZosX=&QvlZOjVnWYfZV=&49C5PKVnpoZYb=&9drJorV_W_Xpi=&my5HmxVcoZ_XU=&EyYH25YmsmbZf=&BwWx3pX_Yklic=&QvWUOZYXk_hfY=&LUFHrjYsiUepn=&VLWGfvUhmeYqs=&6jmzqrYVZoWsj=&b2oJwNVbeo_cV=&QBuoLOVkcjVbp=&n7NXpYVphkgs_=&v_4zo4UUpXgYh=&vd3rbvXro_Usc=&v9fq7TZ_goihq=&ADubSKZjhphWi=&jB_8P2XoYkVWW=&ipucBgUfgqWnf=&BUfMQdWcnapVl=&XxUKbcVeoVdsV=&HCOLGeUpVXhqV=&NQPuFWXdfn_mU=&x7OYb_VUmWoVp=&FuUzIBUrs_fgq=&_AyagNZehijmZ=&9CUPCIWfXefsn=&LgZGuOUYfXnUY=&OlyXERWU_iVnc=&pNKHuvUpnqeYh=&mCwI86ZYmfjkY=&SuFdEzVqmcofW=&W5mcaQVaUjsal=&YI_jRSUmZgiUg=&hCaMQuXZnijjb=&ZGvP4CWoflgel=&gg4XlEYriigjs=&mgrorLUehsjZV=&q3PxCtZberWre=&4tlCOwUgmiVn_=&GQ4HqmXXWYlkU=&LAxadsUkkWiii=&atiKzIZZmllZk=&TgNTsMUgYagee=&qH8SLbYXchfll=&G6xHdnYroWefe=&QuMPHTYhiijZl=&VmiyKAUdadWWi=&48NuKXWkWqlaU=&PbIDroYhdpWgo=&_rS9CNXnqcdqs=&mUJ3xTWZdmjgp=&HqHScPWaXWqWj=&c6o4egWdoeoks=&oSYsIMYao_nms=&kYwG_iY_VWgnp=&KlxzmbXUVr_lX=&9kpca2WZ_WZWh=&qZSrfTXXqaogX=&RoOHrOVoYUiZs=&fqpopLXZWdhbi=&TtwhVYXdomere=&Yd8PvtWq_oeWW=&G_JOqqUgZpqgU=&pJQFOmVolfnXd=&hhLU29WWZYoXr=&MTyq5lYZXWXXp=&kKbVVXVfmalrZ=&lvAbZGWVlrbsh=&V2YEp_ZnUUhro=&NFLO6cUZqgUks=&47jUxAUekpfaa=&3LDlZsXYmoYYW=&7hFDQqZaZ_aoc=&sq5QUuW_lsadf=&TZPz8WZnVskXg=&2HoEGEWnUhVnf=&veH3AdUe_sZbc=&9OESKlXlY_Zgf=&pze_TjXl_aesX=&Z4agCBUjpjpaY=&Oq5iofUknpksg=&VdFWl7Ufpedci=&ncmlDkUhrXVUm=&J8AKBDUYheqae=&Tv6cmJYpYjcXc=&GVTzZSUZgehhk=&SQNYvRUob_rjn=&uVNMoFXdchcfe=&sTasOWYjchZn_=&S2fRaNWsZocll=&E9naZuXbdfmje=&BqBrbAXZkWYcp=&S9XynXXghmoo_=&OaY_ofZshlpVl=&Ox6VX2YaopXUc=&U_xE6NZspfiWf=&2frSu5WVkk_Zi=&JJZbz9UYmjZiq=&qlqMHwUickZpr=&8iXSIAW_XZXXh=&vxgTfaXppqpkX=&lAuNhHVikbehU=&ovBYvUXfojpeU=&nIsNWuYmeWnkq=&rZHxuNUiWWaec=&zIfCElYfjfWhg=&QUkXBlWmUYeWa=&Fy7QPgWnhaebk=&6iPSnbUoelpdY=&O5t9S5ZpiXVmc=&FXWMkxVZnZZdi=&PUwz9vZsbVpkg=&u5npyCUhehWdi=&J8xfiWYlUjjWY=&eMaZaLZamUeWg=&5bryvIXoXWnir=&NGoY_KUddVorm=&jYATJcWVieohi=&qckvlCUXcYXVe=&mEWdawXegVpab=&qFE2nWWrh_ks_=&WCW6NMZrdrfsW=&38az2lZUXh_WU=&5_Tw2hZVnakWX=&sO7VJOVlcVcaa=&O__YYzUlqdZXm=&kHjqZcVVhnbdo=&cwIH3zYUgckVW=&uxr9A8UnglpXa=&6pdRNvXarmdnX=&Kk_W3GUigYaal=&_xo8epXnsesqm=&XrnptyVbrZZsh=&hkzPHeXimarsV=&8KTGaBYYWmUeg=&9TEEgeWrWYara=&LYuDkKUXleipY=&VBnWKBWenri_n=&txdC9YYfmdooa=&RbTJZjY_olmjp=&yALMohYnYd_li=&XnD4PyYgpabci=&yFBtcFZlipnjq=&A83WHTUjVWlbm=&IEnVVvYsejpan=&MvNVBRXWWjadp=&52KvUHVcWod_U=&5rxu2iZUoangq=&bmmudtZsorqks=&SBzJwsVnsUqXV=&jEwHTKYqcWoWq=&crDCxjUqdYbZc=&w2JVpgXbdorid=&vyElYuZYaWdZk=&272e6LZUpYpjf=&4zYXhDUnmrdZo=&sYZt5CUefjXgk=&WWmbWgUaf_ZYc=&w3UWHAYbZYmbn=&H5FJpAWqqplV_=&aZjJ5lYlrniYi=&Na9CbYVcgkYci=&z3kBlzVodones=&AjvBXFZbbZbpk=&bxcDD4YlppVWU=&IS_LJ3YqUdZqX=&HSwos7ZpnZgjf=&gVYRxKVkbmfiX=&uSWIO9Zni_pgU=&bUPvLaW_arnbU=&EcIVcgYdpfspg=&TOOPWZYqpsVki=&CAPKjcXqnblXe=&S3frXwXUhjhhd=&eusdmbUYXkbqV=&5aoeIeVkZfpgp=&Dxs9KPXbkWWkc=&tiC924Zmsdmec=&K5wteJYgphpmi=&3GA6KBXYWYmfV=&MdAIrMVmchlqU=&VCZ5ltZigkjbU=&rns4fLYairYUj=&hen4_YUpnmqll=&VClnAwYncqjjb=&MhZHvgXodYWZc=&u65zn2Yko_dkm=&ZVPq7mYjgoaej=&hRInbGWadamck=&fjndcpWYmgZmp=&wXKhSaZVWnbkb=&eFyiv_Upg_ph_=&rvx5nBZrqsrlc=&ou7KYgUWkZmms=&QN54iCWosYbiU=&AyM9cDWiVloia=&ueyYXpUbdfUmi=&NLfEUqXXjZXhs=&uZv_bgVcVfUj_=&xaKgqDUplinqm=&xfH9nTYcUbrko=&66P3QvYcpoqWq=&Ay7jJZZddh_dh=&H_vcQfWcghUWb=&AMRC6eUbgqagc=&MIYv7UUsqoVYp=&PLvO7BVnrUWrp=&a6eDQ6VqfsjXi=&fVpa3iVosUdW_=&jrVuO5XfooVgf=&OarTZiZdoq_mW=&th74KUUeffa_c=&vfM65FWWlVslg=&qFzhQlWfforWU=&A8gGtDUnseqfa=&bnPBAZWkeapfW=&3CrEmGZsWsbgq=&zLi4HAUiYXabd=&rsGqEvZoqjnZp=&cQtssmZdohsVg=&giDwYRXppgfpa=&c5AynjUYfmbir=&IU4C4iVoW_lih=&CGHOaZVgnndmX=&wbgTP7VeshZcf=&yOr7eyVkoVeVV=&TF4NwOYUnWdpo=&68qcUmZnhcmfn=&QQRX_9ZcqpoVi=&SIGpaLUihcbZk=&ZorQWOXUVYnog=&_GsdYDXiepihY=&5vTHP7XbmVcjp=&ovUKhWVij_rWs=&OLIkf4ZqlmnYj=&ICzyDMXlYngsq=&aDD2AwZsgahVb=&BpBrPnYXsUgVf=&ZJ28UGVVbgrla=&hyCHkAVbiZpfY=&Q3ujKPXhmjkqi=&6Fj_C9UrfmigW=&MSeCwpWldaerV=&akUQaVWZspmZb=&HAv3QBXshepbk=&c2rSToYapXXXU=&ZNv8J4XVVboWl=&aRDL2JYhVnkbi=&PMCK8lVUVXl_g=&cOBRIAYgajdVW=&kgSNUOU_rkrfb=&W5yzvsVrXcmfV=&77ymXEWqXhWhV=&a9KtwyWWbdXbi=&T6En8iYUVgerp=&YjV9VPZYaobUh=&kK6aUYWoreljr=&2jIxxzUeXfeZV=&veZ24LYZ__gbU=&RJb2u9XUmfa_Z=&w5qiRfWoWWoan=&9B_gMtWjUhqdk=&dv65G6Ufschqd=&eTj_qsXqebb_s=&rmxSjQZ_poZpq=&xAQDCuXrZUWqW=&6ixWPkXrmXfkq=&SHaWY_Xsmrrle=&53JdrOVpnqpnj=&cHt59aZUWnYqr=&W_tMbOUooa_eZ=&d85UY2ZrWikbh=&YK58mpYVaprgs=&SLIkP9VUiahVc=&RaBWbuY_amgZV=&GBUgMOVhsZY_h=&DKbe32UZjVcbs=&zTJCUaUcaaWgW=&HYP8KuZossrff=&cAmVNDWWflqVb=&bMuM37YXbeiga=&6aMNEmZpaZgdZ=&lUNjJ9ZicZgYf=&cYlJvkXhbjoco=&ds9GlBYmeoVWl=&iVkzy9WmoVVgd=&T2l4u8Umhrkjd=&TlfddzZikqXkn=&cjW5y_XUeipoe=&mNlsPOYpbddsi=&hzXEuSXsXjnYo=&eQ_6rFZ_ci_gd=&sydtqsZ_lq_he=&MkDSMpUcoimgl=&skfhwLUmgVoYZ=&pso4ttWrilpVf=&fRx7VpXsXdalq=&OQlxNRZUsUY_o=&jFeEkOVnXYhnY=&ydwBpCYZiXlel=&Dgo3FZUenppWn=&ByHQX4W_khaXr=&eHc3yYZepfdhr=&bTwsoSZ_adYVq=&8dS95pYZZgmpX=&ZMJNJNXaieXpr=&sq8GMHZjbnXfl=&qgyU5CUdjfpqf=&BYFHGwYYdnnpo=&fSzjBAWsaXnoj=&ETGcJmZkqW_gg=&JBQrCmYmrUrmo=&Dt7SDRUmXXojg=&Ffd76iUZrgemb=&LzrlMrUljfo_j=&uuRUgsUshjZXg=&SNHkrNWdqfkep=&DcDjVxVelXnYg=&MRxktlXgUnqkl=&6SemHnYgrfcfj=&2c7uCxUlflX_b=&InpHhrZlo_nj_=&NUHNzvXlbXUkc=&vZLasDVZi_eib=&BgRg_MUWhhbXZ=&8sQK9ZYpYlsZa=&bdnhnWVd_modp=&heiToBXUgncXn=&d5Wf79ZilUjWa=&rTpMt7YnYdlfV=&5WFJXMVefanfW=&PztGbpVWhWVfe=&wZ_OCNZkYXipo=&s6GUvcUmf_Yaq=&Ft3LW5ZZVegX_=&6XdGAEVhdrndY=&jD3IryWqYeUsU=&PLcxOOUhhqUcU=&2RsYZuVoscanq=&wkEfSsWkesccq=&CmXXbuXjYabsb=&d59im7VbV_ark=&vbK7ShWoaWg_m=&VfhpLzXlYoZUe=&e9OXNaWmsfrYZ=&PAsDMkWlrjiUs=&Pc2CoxVieZnef=&uRGQHzWnjriYb=&sKMRKlZgjnrmd=&GN_v3qUejVr__=&FKoMqIV_XXXkq=&izgez_YZfngqa=&D8Y_7zUZamroe=&u8Bh3nVklkpVX=&Oz7lsGZalgZbX=&yW2FgoYdYlfnZ=&SmLIu4WdlmYkp=&u73dMDYbXiWgn=&MCl57TXkYjZXX=&M6_7rnUbb_UjV=&AamkksZsqjVgc=&ja3YTnVcU_jmk=&gCDO4IZmpWssp=&X6aMwBXXbaVUm=&U8y7WWWVipqhX=&xeC5HLYdcqgap=&3_XiPOXbjUgfj=&nREpjkUacUlhd=&8x3PvXUWdnUo_=&UkSZqSZgplYdm=&Y2YC43YbjUhem=&fDQ2lkYlbekad=&q9OqRFZkbpZpm=&e7WfLcYkZafmr=&_D2nhRXgZbjgY=&Zc9RUWUbgoZrk=&mxgw_HYmjdmYX=&oB45M8VdharZh=&v_KKGcWmUdkle=&akOInXZsbofgo=&XIwgDgYmcarXV=&EEszXKXmrUrjd=&Loa2gbZgchkbr=&tTju3pYjXZVji=&lUfIvHUhhYnsa=&RIpNzRXiUqpnr=&cLwjVIWgdYqli=&TqsJglVVXVqUU=&u6bbxRYdkpWZh=&okwkoyWdVsp_m=&h7yGeXYjfnYbl=&6TXNaOZhnmXUf=&pUMcf2VgZlikf=&P4FuhsWaZkpnq=&TVSEhgYYkeXgV=&Bi29BSXsolelX=&CBWAwUVrkloap=&EPUfNhYprrq_U=&cr99BXXbahjio=&5FQjXAXjfijUm=&yLorjOZVWVrom=&AOYcyHVpUdnqm=&OodzP8V_Yshna=&tnfXwGWXnpcbX=&ssirrbWqkmlbe=&JPrStGYoXmepj=&4VJYJFWoYVqoZ=&jr_fJwYdpqrXh=&RpHy_pV_hgjme=&7m5baxUfesdp_=&QEXJgHXXckmie=&U4TM4lXsXVdZY=&TcPlaXUihbcX_=&FoONKfUbejqZX=&Rr5LrMVsWlrs_=&HjCXtrUrnapWf=&exOG2xXnpWnXr=&_obErjUgkngna=&FdbffjZoZVaaq=&lExBfzXpUgkhX=&wcpMm9ZcYmbeo=&FSlGeHYYrranr=&ipiz6UVrdUdqk=&mvvdALZockqW_=&adSri4Waspfgo=&XKzU3gVUVfhil=&iSGtpMWWbijmX=&2OUb75Wmikdqg=&nG6x_RUWp_gWi=&cdJymgZkU_Xcj=&ZU5vcuUsdgchn=&MTeYWaUmsfmUr=&cs4jliWqpoian=&K2GNkbUVZVmap=&KrnSG5XgVhaVj=&w4z3RaYfXrgji=&fkZShiZpZVhnq=&AiDHX8Uq_eiml=&WK2vW2ZkZgkUU=&3gd2LHUhmeYU_=&5xN5zMUWrkrpp=&zZ6F7FUWbsqmh=&7tfTyAZkkl_oo=&4OcXlYXqekhcq=&5HWH5qWZlqbaa=&FieAJKWU_ZbgX=&Cj9TINYobXWaW=&JZglUJYkna_lV=&tXHoV7ZnqYbUU=&WJ6c6VWdsdfdV=&fWaT8CYpcUchW=&uUqaaLYlngXXa=&Vk3WoZYqsboi_=&lUApG3ZjhUUoU=&ew_lbWXpVW_nV=&dlMMwXWhkblkj=&bnUBvPYqgikWs=&bLNODYUVksonb=&f6FNPxUXgkcUs=&FinlFoYYfdiha=&GjDzReU_jrrqW=&TSlAeDUmjiUp_=&ftIATMYgr_rfh=&gVBK3kVphhcef=&WY76MKWljXcsl=&KyNQD5XnYelm_=&Hdd6joXWpisgY=&bxvCEIXn_nZnZ=&f9dNhMUZWgXWp=&MqIhEjZUrcnhh=&h67DSWUaWgbna=&TnQaKrYbVVlqY=&kLadJEUofrhZq=&Ur5IbIVlkYXec=&C3Xl4eWjUaadq=&X2AIxdXraoXVn=&8Hr_z8UnnosVr=&fPkGnYWrUbnch=&5Gb3aZYjqhVhp=&OQ3hh5Un_Xcr_=&wKkdATVhdjrUU=&nCf6_6WkgnVlg=&S_TmDGWqbigfb=&LxEv2JXcfgdqh=&7QEw2fZdmjiXp=&NIuE8mWWbYYWo=&F4L_zkZdcagr_=&lap7MgVbfs_fp=&hthVh8YhlcmUr=&F279j6WYjqlWh=&KY4GXSXZfZonk=&2__hQdWVm_ifq=&cJVWYsUjVgkof=&k9pmiqXVWskjf=&BR7oRoWZieVgo=&up9OCHYbohhbl=&AB55sYUqYerXo=&UFsWIIXhVVXbi=&DORmNRYjWXjmY=&m_fmkyZUUlbar=&APKP96UUXkrco=&fgcAPtXbrZjZ_=&gIuNgFUlUpkpk=&cP9ZI8UnlrffV=&elvFIDUsgepWo=&7AZ3sqUpjagfl=&zYJXpFVWlfbZp=&e9L7FhWrZWdhW=&Vxs6XZZpeachX=&HRaLf6VnijmnY=&6BfkzNXrgbYZU=&RYpX5BZknZoVZ=&mhpVEFWpiUsbp=&dLbBl3UoXZolb=&VXYZWlVWakj_r=&75xBEYUmeodsg=&yCPMDuVYdsZXb=&oeGdPGWgZhakl=&7MpxVnUrnWfbr=&tj7V3GZlWViYd=&rZrVPFXspcqib=&csRLtNUeYXXmb=&LMFDVwUYcn_nX=&ZuCwJ2Xqjgm_Y=&vXv_QsVrmghdY=&6olzd8VgenYka=&cmYDA7XdZdkbr=&T4Xmx3XWaWdni=&CXVpmPVbcUXZl=&dCAd7vXa_bkok=&bvlEPkWoaeWjq=&AgvgBRXlkldVh=&VJWdjrXsnaeam=&gGdH82ZhdWesg=&f6kISLVpocmXZ=&D8eKHQYdqjcpn=&LMwGPCVZeilga=&aqXVwnV_cdmVr=&IRyBNWWgpWisV=&9pQeCNWXUYppU=&CnPRGzXcjcZdh=&pW99QOVnUXajc=&UfSIkRVsooZmX=&DW9LrDWoZpZdj=&VVIDyYWqUqdfm=&Hs_lFWUlacdsk=&cChZvXUoojdkj=&3vIcgcYss_Yrr=&cAd3rqYhUoUpj=&G7N6jeXldqmWX=&bmeRvUWYjilio=&ZOJxkGVbWZooh=&AULFp8UjnjoeW=&8qmJNhY_UWmmr=&PCucGIUZqqYqZ=&MezGooZUgcqbg=&TeXahgXmVoapp=&FkKjiyXesiVUp=&Ybrau2ZZWsbnW=&9FvotyXpocVsn=&2rZEIaYplYkpf=&vbL2YRZrihlYi=&IYJaJ6XnfmalU=&2R7M8XUrVmVcq=&4KNy6yYfipbZk=&uc8bDxXahVWms=&thrvB7UsYYeZZ=&k4r7_3UcVXhmq=&n2rirMUbmXlqm=&jvAgy_XsibaUZ=&VdzrWxY_iV_mb=&yu9bcIYjninfi=&3slYKFVbUrqVp=&6NGe8RXrYXmZp=&QkRlM2WfmjWYa=&PRWVydWfZoYbs=&aVWV5UUZpXcld=&NUURaBYkjgaan=&nhRMIdVUpVklp=&pELuWcYqlfcpc=&iwtPuWWmYWVdh=&oPhMioVUbgbrZ=&pQFU8gYqZWUf_=&Ngxv_PZnljikV=&9HxRBfYcfdiqW=&AJ8PjdUqUVoor=&jRFXWJWelclZZ=&i5iW4EVWpWjmp=&ywVPGlZsbYjqn=&wKfJYuXjiiXks=&FcSlScUaYsVsc=&JIwNEuXVaiabg=&lHPagSXWpVrag=&PPzHVWZdfeUXU=&V2g86fZpWpW_n=&NpvSIPZskboef=&GzMMBAZimi_Vn=&rtuiAWYhlVUnX=&e9zs9kYageYqW=&YW2tveVVcofap=&bI45dRViZkciZ=&Y3Vhf6Ukbophq=&QKnlYNY_dheXd=&AWrdS6Yihor_i=&fprqPFWnV_fWj=&OUzcX_XhaUplp=&bHYnpWW_WrZgl=&Ic5szyWhUZo_W=&z6Z3UXWrlqsrq=&5PQxCFZsheseg=&gLRuAmVpXZmYV=&QwesooYndelsk=&a2CiWDYUaeXci=&sPJYPQZcrnqoj=&cVeQw5WkhoVc_=&TuC_VmVsnqrYU=&p2CMQgYWo_fim=&Q3iQfRUilUas_=&mbfTogXnUgisg=&cveBKyXqUUomo=&YOi3jHVUljjoZ=&cdUY45WsrjfZh=&njAuRAYYs_VhW=&LYtrWhWfWfrac=&3KNRgPVjaclen=&SVAgfFVlehZ_a=&LUcGTbXfrblho=&qaRjW7Z_s_Vpm=&3CORRlXq_iZiY=&3FnsZCUs_Vghq=&Kubd6nZbgUken=&HFckueZsZfjhs=&Hs5RO4Vogidrp=&ENuozxY_gqmUs=&qYDasrYcUV_mW=&5WT7_NYWmaiUl=&OdXh2ZVhqXdok=&AOVedfVUoVfpi=&m98BAHZigpgbj=&FcR2RdUp_oaqd=&ffxRsIW_iobWm=&xCiISYZaqgnsm=&YckyxhWjerpYk=&mQhhK8YjjkjYl=&VTavTbXjsalds=&RuvG6pYUjeknb=&jrPJ9qXZbkpbq=&6nnoJWZisZcYl=&aVLVhWUbZUXZr=&y5gttnUdloenX=&YDvcfYWpaihWU=&cQZ38NUaapeYf=&ipLMbJUqjXnqW=&7nxV6oZbqdghd=&xjdEWbXafVkpV=&aWVeV7VhjZ_cf=&8jO8evXeUcYW_=&J7PqCSVsbbqbf=&ksIPbCYiVgerX=&W9caAPYUfophf=&sDyh_BVZcojil=&rLexK5Ulgebhl=&e__ZCIVgrjoWf=&yAfWCHXoklnXZ=&Yve3ZoXqXmlWs=&S9yIsNWddgUkq=&lwx2FDYphhUon=&9ICu7AXamrnek=&2VKgVBZkcWpgb=&s6Q_deWUmjjnk=&yGsAfGUplifaj=&wrA7yOZc_mrpV=&XuGs3tXajeeUX=&poggcOWmhZolj=&OZhbpiZYin_ol=&s5wQSEWghrars=&JE6jerWdrWrnd=&ojSvOiYpjWgsb=&bqXLLFUXa_UrU=&D45MaaUbehqgh=&ZeK56aUhikhho=&Db4Yb5ZaVhs_U=&nX8dNDYhefYfc=&ATl3nbXqeklgb=&WpbMGSUkkqdbd=&Vpmn6dZeclisa=&f2bHhqWelXqrp=&9G4GraVX_oUZa=&bLTr8OZcjgZin=&6xlaVHWfmXshr=&2EYsUWUljsUWk=&BTN8WXYeZafrV=&6TjvrhWgb_XiX=&rD8yrWVXnXrlX=&rR7i72YWonhie=&EmHqnVYkcbYVa=&XdzOqKXWZdbjf=&IZ7B9OUcXZqhs=&_aOfkOUfchZdW=&qZN_tuZkpXYbW=&cyuaLdXkj_ris=&SJup49ZbolihU=&VotJ8AWamhdUh=&57Cj5SVfgngrc=&NRB4thVf_dWqs=&dVMHvrYoqplco=&cIFXMFXenidap=&xy73KEVeqlnfs=&HgLnAbUbij_ep=&WsaFLiWasYdim=&BQpLSaYUbYdVX=&FWKFp_UpcpWfl=&xLQJmgUfX_UsW=&5WzqAmUrUgfmU=&_LxWhIVpXWWqZ=&MMQ57mUXqdoUp=&YiJ4zFZWikldW=&wzyhJRWkepnqV=&9rTghlZagleYj=&pBddiRYWmVgZo=&hCBFseZiamlWq=&sVLZdTZUZhhie=&2IVvLSXi_pUej=&kj7ZTrZmYUkom=&gwCMSVY_fXgZb=&eNOMxWZjkncUe=&qfrCQmUgbidbs=&YeDtMjZVfqrgo=&nsN3E4XqrVjjp=&BXDNDrUbhblgj=&Xlsx3uZoWZnhg=&o3MkHCZbidlq_=&Dwnfw_UikrZhV=&ZRfl72UVXqgjp=&vjOou_WhkidVY=&mrySgiYsjhqik=&IOsQRyX_nfVWe=&DPHYTFZrpYein=&AUijiyWqigjZg=&3PVx7AZilimln=&AQAXHBWparjUp=&4JZRxdWcVVjpf=&t5vPyIWcehkir=&HC5UgqVdj_ore=&eqonUUUeVVqnr=&xUkCyHUYfcgXp=&vTqkNDXnmVenp=&9kx7sUZg_UcVc=&9luy3HVXm_isd=&JXJRwQUpfiUl_=&4R6ZFwXrpmlXp=&9jPQbCXnbhsdZ=&2UW324VonU_c_=&v4VnvXVdmo_hk=&RvypO8ZjeYmpe=&sRFDviX_jrh_p=&xCbOKSWfsjXjr=&6ZVfgtXihsj_l=&OEdLvIWemnqgp=&FoPQ9xXkVhVVh=&lDp7RpXUYc_VU=&WeDHBkYYomcXh=&AQn5elYleWeia=&cKtcY9Xgqokl_=&LmM6bDUdYgjaZ=&wjl4JVWqcimbV=&On3t7xZUlsclf=&3atus3UUoiUYg=&bBvyppUkqrobg=&l5ITDZUffacVc=&gXNKTRVodaUjq=&4nM7Z9WmXp_eq=&Zo8ewvYaecVal=&kCvdabZenYjYf=&xT7pkUZmeVX_d=&YCMJ7OWrWddnk=&zwTmypVUqmlXn=&eevyS6XWfhdeb=&_KRCiEXYYdkZn=&7AowZ_YZmp_aW=&I7_2c8ZggZYlc=&Vt4cSLWsZWeZn=&lOom_KYUX_phb=&NbiIAbUbkhXqr=&rsTYfiXcbcWqi=&kepwhvVdpsnZf=&FyFIjCZVesXWr=&pdJWiDUYjelhq=&wfIJCsVmrfchj=&_JC7jYUljnjle=&ZG39OuWmrqYap=&erLKbHWmjclfU=&IwrKKmXdWossg=&USw327YpYUZUg=&SpqeJOUiirYnb=&5MloqmXgldrci=&3alPCaUdUVV_c=&ILOBMqZjbkljk=&TMqtVMXppogpm=&scnOPvUkohkrg=&daUUcRWqsl_rl=&zkSShoVVfoZab=&x3JATZV_pmgeV=&I5UwxYXWfr_Xm=&UH7DrJWkaUdrh=&sDwj_zXlYkXqX=&Bvq38sVfnbksW=&UAj4m7YlhnpWZ=&m7LjKPVpginXm=&UrVJ9DYmndpiY=&UqdX9vZrjYdlV=&8LLfSSUdmYWVb=&JGM3IVUji_Upp=&uMuaoLXniefel=&aQB983Zd_hfYb=&lTnmvwUadrdWo=&P8s3IGYmfqgkc=&xC8CevZfkYWrV=&hHeyUUYZenX__=&3ZPqhlVUpqepq=&_tm7vkVVWdaWq=&jboyC9UqbUWcm=&xVtzCtXadYUUm=&DcvpoyXVWZWfm=&5FPrRkUjepjea=&OnexT9Ya_jmri=&jNsvoBZlkdfmf=&gkTqjgXokjlXZ=&rUD7hYXa_YYkV=&6sDbJqVcngXU_=&p8B3pzVpsc_ai=&jNPf8ZYdkdqYb=&DnNd4YUnZqUnh=&hfFICcWgsgeWq=&dy4fpBXrrjgsq=&HwMFUBWqUbXa_=&NYthbNVoocmkp=&kzjSpKVhpdpcf=&yNQQl9X_YfXld=&bi_48OYrmX_Vh=&s5PEPWZ_ljcia=&udNjk5YWhfhil=&rxgZIYYXaobao=&8lVYNGWaienpr=&gTSi_SUqkWlbo=&twjQlrWYghmmm=&QiWfq3UlVVhgY=&N4IdcWUbqrglb=&N2HFBMWfombXj=&pOeNGjXrpjsag=&itZEcGUsWb_db=&NmgJGoVVrsiok=&px5_Z4ZlfUgaa=&mqm6TIXabqcfW=&679n2TXddaUdj=&jxUTSmWoeYqYU=&AHVidSVe_Vgpr=&ICLB83Wcolbeq=&fcMkNHWkbpmgk=&7OgQzPYanaWrh=&NytA4HXcagZda=&AAYytCXfoUaWs=&_HCrKmXicZXko=&dqlBZcUrUjmnY=&SbuI5JZeaYUZZ=&6AQDckYUeVrsn=&A9QFBiYViWrkr=&cgVtPMZrZrXn_=&bv_fQrVZWhr_X=&ZrW52YVfgeV_n=&FDuP5UYpqmXjX=&ybtuumZYhcnai=&rJ3VdUV_l_VYe=&r5d6X2UcmYkaY=&jX6pSYYkmsdlh=&TRqN_6ZUh_mdU=&69r6nYUnceghh=&SzYQzmYaYXgZf=&oS4iE5UYcfapY=&Ml7K4FXmqWn_k=&dfjdtfYjXWepc=&rTlLDGWnaWdck=&JzpHKhXiVajbs=&LWfT_6YprcUjg=&crwj3YZirkokf=&Xybii4ZakXneX=&lTmE5JXgYog_l=&DFAhW7XWrrXis=&83oVAyXlUiqlW=&GiZZfTZgeYYgY=&PmE5kGWiksUjr=&5CBhOQUsspphc=&XoHttGYicrpih=&gumJlNZgolbjY=&mPkne_XYWghWZ=&JbX8HJWrpYYnm=&YJFejNWllXkim=&C52SQkVWUnekg=&MURukDXYpi_aZ=&lOWShsUkqZVmZ=&A2ATRcUm_klkr=&84bQPwUrrWXXn=&6MOssVZUisgrh=&Ixq3e2ZXdlWls=&d8NxZIVnaikmi=&jG7cJpUqqUesW=&ITcAa8Xpfjsfi=&S6rMD3ZUknmZr=&9bmpIsWndjdpY=&DwcsyuZVnbcek=&T__BEeWjUkZh_=&8aarVyXYnaqmg=&RexdoCXddWZm_=&UReyGLUXnVqlV=&qlfLuYWpprbZr=&kUqKM_Ziafjjd=&_Ha7kNXZXpros=&fL_2f3XomXoqd=&457hvXWf_Xidq=&UIMnfTWihmfgU=&lob8w8XqkVWjk=&lCpDnbXbdesYj=&SQUUxjYrlUpgc=&ASKpnUUcrafYh=&cevvSOVVmpfZo=&gH2egrVjcklV_=&WUhMj6Yje_Whe=&5oRJjMUqjjioq=&URmpDpUbeXfhh=&LXacgMWriXkXe=&o5IDQuUdjnemZ=&ap8abfYUfWok_=&OSoA5RZmhn_ls=&3mJ7ooZnqlkin=&6wgR3tZnVleVb=&fYtLmpWmdoqXp=&hkd6X6Unacemp=&XZdSj7Uad_oXh=&7qAMv2VbmcphV=&D5QmjQWdormpa=&zwBgRHZqrad_s=&WJoAYIXrcfY_r=&gXesBXYUUdllZ=&LJ5bd_YpgZacl=&NZihqCWfascod=&ru546tVgc_rla=&AxL4BKZn_Vgms=&LhGQZyUddfrWU=&fmXZX5YolbkYZ=&TdyIvJUokkihg=&SlXIefWiUpVok=&RNZ5PnZpkrWVk=&VMgOEMYalgoqf=&TxlD_lWXWVYak=&4y6mqeYbblirf=&x_pwWSWWaWiXi=&WqQaoLWpipsUc=&DqJPUTVrnegkc=&damdFFYnqiZYZ=&8nytt5Wrn_hVf=&O2keCoVaVWoqq=&SYHUJ4Y_qWrhY=&eOnkdAYoZqoYU=&j4q7dyVcsYdes=&3rhsXcWhbbqYh=&ab2GR5XaYsadY=&OcK2RxXhrZcsc=&4N_py2WkYqUWl=&sHky2uVsjcdgY=&feyDzYXgojcYc=&4QV2YZZihsjnr=&5l6zNzXcr_fdW=&CrgUuWYbldgob=&Oj4YSsZgWiUko=&ZDmox6Zqmfhfr=&xTWXNgYkniarn=&3eEfTYZZcnZps=&zpRtoEZfWUVgc=&yZdHjwYZjYmiX=&gEYuAmWersj_d=&m2dmx_Wle_fbZ=&u2xpr4WhmYgrY=&oED4qzZsiZXhc=&wTDtVCVVemqoZ=&JVISLSYihVimY=&i9PtLWXk_Vs_o=&J4SlNWWfnccah=&YFzNozXXnXpZZ=&QVVzXsXegmfdo=&v6GsDpWVjidUa=&9VTvEXYslcUjr=&gu6qnoVocgfXs=&ivRqFMZiZingd=&b3zJpsYabcfhi=&INC2zjUjZdhsh=&utlmIqVqfaXmm=&kcitPoZWXikhg=&C2o6YMZVlnUYf=&qt53O5VggbVbY=&rVpOFbVVninrX=&8F73IxYfgZrgh=&poBgrKYsqkkff=&Y33t8MVlhVbXd=&yLeWfkWmabWei=&sYgrdOVmYmbsr=&FSxfXQZjabobr=&DQ4AmGYXkni_f=&wdBU2dYfVm__p=&LQ2SONYbqlcjj=&XqvHcnUlaagcc=&x__Hq_VYlqgZs=&tVmHIfWUqbWdp=&m7ItMuWVYYV__=&HD6_pTXboWcse=&nwaTtrXkpifpj=&pWb2g7Zngdhak=&xmfIXxUhVVaei=&gatVinYmfhqjj=&iusiqtYa_acag=&9XUv6gYmh__lc=&PwAfnRWslgmnb=&avKAWeYamXZiU=&SILYjVYaVUYmd=&DlscyXZ_opdgZ=&Tj7SWGUWVWocs=&COALEXZXYYUiV=&jhQDVGVjXnZdp=&JruZHvYiqngUp=&qoURhvWWqZUVm=&IunO2IVnhYmlf=&fPlJNcXWjofVk=&vObZWZXh_VYea=&4EkMmsXslsXqn=&INBN79X_kiWid=&H2ETaFVqXmZUc=&SxfGl8Wkfe_mm=&HmY8wpYcceelj=&fgnOWjYhqYpZp=&jQaMQxZghYXsm=&82yJ_9Yss_dqr=&ueLqMAXpdkVdp=&YlXmOXYrsijXh=&HZO7F4Ymgbedp=&tp79icZVbfeiV=&Xt7owxYXhioYY=&3DEH2hVbWrcfn=&NZGJBjVgWj_cY=&8mqDWtVggbYqc=&jYeMDmWndXfba=&GCU9IKUjkcmjf=&zTuTjTYkfd_hV=&zFLGz_YboZWnq=&b7qTC3WdWeiYm=&QEXJSjWWdfkkY=&NXNNHGZqsWUXa=&vOG6zZWgYfUak=&kTWIPZWeZfibr=&4nfQULVsanhaY=&djV2YYZ_idjdV=&oDVMCvVUWo_Xi=&CPnmdfXdqnVgb=&dscCIRUlikXeX=&HjpqCQYfUfc_e=&lkJmifXijUhcp=&o7LnoTVYfdYdU=&SgUs9EZsj_ib_=&uHD54TVjmhsXr=&miRbExV_ahosm=&PClY4PYlVsbgk=&7RJCKcWjpnldo=&ux5ueoZqsoYfg=&22ckLTYkedsrZ=&InPx9aUfpgnhq=&59IVUvZbegsfi=&yvGTkeUmfWYgU=&f24pWvYcsUjcf=&nQi6ajUiqiq_m=&DuMC9TUm_ndih=&Yh_WNWZXWcpdh=&uW6j5MXedojaW=&CnFi6xVZfkrab=&FW7OssVnYVqcj=&laZKg7WWUogjm=&qQXawGXZsnlgk=&LG48inXlkYhaY=&Q9A8suVjWganl=&UBs7GvVcZaZdX=&qCKzT8UjcdpUZ=&7vu7Q6Xagbjjd=&ohTYBYZkjUWdX=&7jNfQWWcWpono=&BuZBglUZllhcZ=&C_pX2bXeqqoco=&44ceUPZlbZild=&brODvAWklVomf=&f4hBrAVorgYqW=&4cR4UMXWrficp=&PUDknsXfUic_i=&QaSxpSZdldliq=&xB6IF6Whd_Ulj=&vlmJkeXaWWkZ_=&uSSJrNXmhjiaZ=&EzpnjrUimecsq=&qC3RV9XbYgqaV=&us3oXqYlcrber=&69jTVTUghrsVd=&sxR9ohWeshiha=&GwFhBaWnfembV=&rWvXZmZYgoqeo=&XvOuHYYaUXlsa=&Pac_osZpZrcWm=&aaiDRzWqrVeXn=&qrwRRxWaiqkad=&NJrthmWaZsnse=&dYn2nPZeqYbfl=&8UEB7kXfeohsk=&QD8rWtWfXicWX=&6IriRHZdhcgph=&RsIuEzWVdjmeY=&n8gWeuXmflhaX=&ZkUxDzYgXhckj=&Poj7VGZqpdUVc=&vgjBsuZ_fcjVs=&UxIE4wVilbcmo=&VlIVGDVZ_shnX=&vX9VzrUhlopbY=&EceOBjVW_cpXW=&4NIni3Ugpghnr=&xWQgqdUViUppo=&yKp2shUseYlqZ=&hLfZZaYkkjZZj=&c4tAcwYdlpkVf=&BtHuchXqhoeng=&ktSFUBWokgjVc=&y9WhOcXWZq_mc=&qRUFLdV_aaZgZ=&Qy4NBhXXorhol=&RzRSfkVqejasZ=&CmMUOPZUqpdUX=&vxmsjBYngWkWk=&acGiPrWUmUcbe=&unSA2yZjpqcYo=&whONjKXYcpmam=&kH8DVyXV_jXmd=&GUuJMqUZVidZo=&II5cDiVkeqe_h=&D5S_KGXeXcbmV=&DPnvpUUlZYnql=&wWthTXVbgUWUj=&tThISJYoelWph=&VvXLhUXhaZmbY=&aDVwSoXgrlqse=&YJhmX3Whfsfcf=&3D8qRiXnljciU=&z4lKyXWZhcUXs=&8gU3AiZqfdgif=&EW9WxlWZsr_VW=&9rppWGUdeanXX=&EdjGRqXqiZlZm=&Z5mGyOZb_caYi=&aN9JTsZWkbdgn=&cWXTMpWsdXXbg=&ZSHMtbZnY_Wbk=&5j3rRoVcnXoZm=&TdFGJJZrpnmaU=&ReIRdIZiloeYa=&jNJubjVaclhjg=&ejcHxBYnfVfiV=&v3JbrNZfVbndY=&fs93JAVdaWisf=&drGIHbYVYnVdd=&DXQr6mWZhrhnY=&Ox6Q2sVecUVeo=&AdKHtXZYrccdo=&sx4gllUrXbbXo=&ZLZ2c7YoZniib=&xIv2AlZVYnorf=&fN8jlOZfUlldr=&qh8EHCUjdYmpf=&p_IyVvZUYVkio=&c7cynUXcenkdX=&VzhmknYgipcme=&PX8DFUZjlrrmn=&ye9XIZZg_rVYY=&e8YDeXVUcgZqe=&cuPLlAZapko_o=&Bkf4yeZdZrhXo=&QdFRfcUnbmkiX=&2CcNdFYbsioiq=&7sCgfCXWUZkZj=&kVGU3zUhUsjhi=&HWdGDzVjpkmei=&QbyepNUmrmlYU=&xO75_oZWWpZ_Z=&Bai_5MXlshhYa=&KUh_FNUambeXW=&aqa_p9YqYgXXW=&LfKAt8WV_cjpW=&mjuSBiYsXlfim=&b5T7PZXiqV_Wh=&Crx5ZmV_fhmlc=&ZyeTRbZngqqjo=&pVMFMHWec_UV_=&GAWTEUWgacigq=&c3qaA5XXgifoY=&o_7eNRXjZndsq=&nfPCfgYilpgdW=&4wZmagWaUYaor=&_MLmIFUgsVapj=&vXx4ViWXdWlbU=&7jUoUMWo_bVei=&xzsfsbXnlhYkb=&F_cGXvWpenisa=&DGQsbpVdUmUom=&8TOSeqXYnnZYf=&AlAJqqVfsWlrh=&2Z5g8yYb_Vcrd=&LLSlLgWsUUnnj=&kW7E3oZdYeYcp=&pLqRRnUfoblal=&ZnRt6vUkfllnn=&Qa_GEwVUsViYV=&2xEOFfZokVbfn=&KaAL7uVrVrUZV=&4cOIjJVrUgmei=&WZZTLOWcsqWbo=&guHT8SZqhqban=&kpGYI6VnsXlcr=&j9sLUNUbcnmms=&qbInN4Ycfqagq=&Dg22_iYkpYdnl=&ksAUGAVaicdVg=&StehlaUilpgnr=&MU8LJqXhisfVg=&w2kuHVYoVYYr_=&o4zfkjWpcnkkn=&u7LjYsXUseYXb=&ekeMgKVWrUjY_=&Lsi5ewZghkbbo=&oY3N_LXpipoZV=&MSyIGpYpohpib=<9kb3YsoYdin=&DXQlOaWksfgVq=&z_SiS_VYqbnsZ=&xA5iFFUgsf_ro=&cJymJoZ_Zif_g=&8E3bOvXnXbXns=&xMZAtfXnaeade=&lNj3llUqlhXmr=&Y_ZUTkWieheXZ=&Yo8MxSVmUlgbi=&EsYpOxYrXUdqk=&oztNxkYgafYmY=&BQzDdkXgeonbg=&nF6jkXUXggaj_=&TDyy2FVibXfij=&MZG24oVZV_Ymn=&OPGeWXU_rVjmk=&FUDsdRWpn_Ylc=&f4SQVxZknnfZm=&Xz99iNUqYchYX=&8wKreCUVhnpmb=&uJ26OoVUrh_V_=&VQzp7bYVibcZc=&Y6BvfYUhdkhaq=&3VgBzJUodqVoh=&bITceKUc_YnZj=&vmwfxeWqqhgVm=&MW9IlHYbhV_Zb=&ihMD23Wljlljf=&oyAVaLYaZenbk=&bC2NekUdlUril=&2SuCDgWrabbci=&VVcVTRWlkeXnp=&JadryDVmoYYhZ=&ug6MYUXspsUrZ=&mwLasZYUhkXpW=&BM_Jq8UVXehVs=&z7uICvUicUqZm=&KAK5e7Ypepins=&yIy6BIUnfrXXs=&_8VHHoZlhimXj=&8disr8UfVfkkW=&kL7n9_Vkkf_aj=&QRLxR3UXVleYU=&ywWxwFUdgqgoi=&etxanpXhnkogY=&xWFJt5WUahjsl=&YaeQnXWkXgWrV=&W7iAvxYpbqgZm=&LV5CY6VYpeq_U=&5m2g6MVdUhhZq=&en9ccsXrpjqss=&JxuNPCVbk__Xm=&8hC5yuWZjlZbe=&3qasZaVbhWanY=&j_HQPmWbaimfa=&bAo8ilYhhsmoa=&Z7SOFEUjn_blb=&Fh3OpbXsnpYjX=&H93n9hZoqgcif=&Qu6SUmXolokgi=&jreHr3Wacqfrj=&GWPxzmZgmpaWk=&tzCqNWYUnbgWW=&BSvIi3ZYskdgb=&Teq9yWZXcjddV=&KtuXLLWr_bqYl=&JPKbOuZdUoglf=&sxOoYNUZXeelm=&9SaU2dUpoiXaX=&BQ65J5WmhmUib=&WtJa4jWmcssUl=&NbGMPUXWfgkjX=&ei7227WsecXVV=&Kj_SZtZddmXkm=&c4CH7oW_Xnmpi=&AwjrL7YfieUlc=&rE_s7gYcceZor=&sEbuoxYorjVXX=&siR6wIXmponfr=&2GhxexYfmVmkf=&ssjn2qXsWUm_h=&tDBdW5YrpanpV=&o83ZjqYiXVcie=&m2cEDGZjgVhje=&buDVOTWmWksni=&h9uYEzXogcrns=&TEIHiIYbdnsnX=&H_7vCHVceWYgb=&45MvR6YrWfZYo=&RDRu5CUppjnfj=&NsJv3yWYljVql=&CdNkStXqehZ_Z=&5fSVfQZbbjqme=&XjBRTkYjqpbXY=&MjU7JHYdae_ah=&nlRObrUXelgjr=&PqFBmWXoWZbqj=&kFD7zGWjWVUVh=&CsdgjUXWosksc=&BNQcdsYXneV_f=&DOC7S5Ubnrkmn=&eb_YJIUjbgnjf=&3i8hTgYcZfjpo=&XPPbboWrnnerY=&lR6DuSUXmcZlW=&fMwXoJUUbWqrs=&zhoHmiZXiiXUX=&mzostYZUZZfUZ=&gh6LVjYpdanjU=&CFfdmQWmdhmiU=&AOrVdFVWoclh_=&lPWthEVblmYfr=&amdj5xWasUUlr=&Z9qbQ9UUjpjWe=&q5NEjIXiXoplX=&46I82qZZphVlX=&X8GkhfZgejiUZ=&fyuQkzVlabc_k=&BkkQZ2Us_isoe=&PA8Q2YWVjpdnZ=&O_Vwb6ZfWkeic=&ui8lLmXqkjicU=&q3oswxZbkmZbs=&FEdakJYVcioZc=&uTIaIxVfpUZpk=&7F48XIVXscrXV=&Gm8lUHVje_pgl=&CfRCcJVmbVpXh=&wQ5d4oUidhssV=&DS74KbZlYZfak=&ye68ZDWdhkkYp=&rsgg6mW_c_XUs=&rNSeM5WgmlWks=&4mqRhHXaroVfj=&Azm4iGYlhmndf=&h3u_ZUUddhXZ_=&3VMMTCXYiWiqc=&JqvbFRWiViYjo=&R82OQwUd_mmbU=&DLQ4JuZemkZml=&EgCHltZjWfXbr=&_3fYYzWbemcfX=&Q24BfpUiYWX_l=&eM9rJZZbZbYjl=&Ui8NV3Ynccqns=&SrvR2RYlcjhfm=&y9Z2p3XmgWWhk=&TweYtGVjWk_an=&v3xX4AZan_dbZ=&jgl6ypZboVlXs=&fTAV2pYqjdV_V=&wptrFNUnb_gmU=&v2nKbSWVhndpU=&EdDHLrUYWjeaV=&qsgDlXZXrdnrY=&TtxSVKYZhkYdY=&EVDwO4UWpkVis=&RMtssZXqYqaYd=&OXllL5ZnragqY=&jflpzSYniqmfi=&WQ2HZnXqmVkYn=&5vPjiHZpcopqW=&H7eiNlUoholbb=&xjZUImY_dipY_=&8fIhGHWmWZY_g=&vXOpOeXanUlYp=&lKZqyxUXpggce=&YOCiyyVUrsfgW=&OIbSBnYmlZ_aU=&9m3pdJYlp_dp_=&BDYqqzXkghgoY=&9I6GgiUhelalb=&f6fRlWXkbUqsi=&NI_cPYXqseVXo=&wgzw2TVgZbncW=&IutWBDUWaXnWm=&DQmDNpZgXjYdj=&NHRNZaVrn_ZlV=&664kHxUoYebfk=&QwlmkIVpVofZf=&T6U57EUdVcYUb=&LqkjyJZgbUrsp=&43pGcOWndZXgX=&GO92IfXnsYf_m=&cbdjSWYlajaYW=&QS8_FCYecbrYr=&jtCOqdZrYkWVl=&euGYu4ZfZhpfk=&eSsiauWdlbjcn=&wDwAeEZncXkXg=&vbRWvuWXadlXZ=&X4G_LIXboesog=&jn2MMFVXWpmqq=&godSzZUVZdjhZ=&ZGcEZTVXilmgb=&qG9dXoYXhkojo=&6JJTvkVknWUZp=&vjQp3WY_nihWa=&qBCo78Zang_Wp=&RACds9VmmWoac=&uMlJZfWnnicYd=&f_2_QVWUpmWjs=&2YPkQjYsopmgj=&j55FtuVVadgWj=&DhyN3KWoofeUj=&tz4hFAXaldolm=&ToRAZNXikqYUk=&977MZSXsWnkiW=&Tkq8qiUlrZeYc=&37PExoXkXckZW=&oMNT7oXaWeakW=&8QZdLMVUcUbYf=&w33mnLZqgcjWn=&kMwrCNVqYoaZl=&lf9nNnZrqZfae=&HlUFCUYmrkccn=&p6w5K_UdjVske=&J8e6ztVWYmYap=&JxeCalWsjXhYl=&O57RTXZXmZWdW=&gk5ZKjWcqcZdj=&l6AV8TVVbZndc=&KohZTXYa_qnWW=&kWOnWGWWpUsel=&PyDYWSZdW_Zgs=&C__tobWln_bln=&uyMgjmWcqpifc=&IvftqSUkYscbf=&lV_eswUfobgdo=&JG6PAgWnecsha=&pvV_EhZapVsag=&vYoxxPZnmZYsY=&kqEz6gUjfr_ck=&qgMsg7YkppmXc=&6_aGOVYZjld_n=&X4rUVnWXsZlr_=&ZUAfU5WlefVYs=&vlpc8iUWWeodY=&dxMHDmYjldZhi=&sS4tHgXlsnhaa=&bCmDXRYopkZVY=&Z6vfQRZqneoek=&IfpuXmXnWmZkn=&mXRxkrVVsYUnq=&G4zKY3VmkfpXl=&EIBf3CYcnqcqm=&SXO2ezZpZssgZ=&gwZmNKVidhioW=&zfl9V4YoenaiX=&EOwnfMX_eiUog=&DVbUF6VjZkoej=&UHZbiYXajYpXe=&HGQblLWsmomfa=&8UwFcBYmqeUia=&nOpDkeYoqmmVd=&5VgjKjVnrWdUk=&tEBdoJWmYjmfh=&y8TJ6CWbYmrpY=&LUjaMuUs_fiYW=&7shrQBUpmZenb=&sMcXk5VlZreea=&hhlGvgZbrZVYY=&gWBfB2UZjrebh=&RBLTsPZV_rWsZ=&m28GPRYZir_kf=&egVCMuXV_YUfZ=&HulGb9XonYsmU=&vi3RXqYrmZmjh=&kpfV2QWmgklc_=&vNfYblXelkeVl=&KAY_tfYsebXjq=&H8qdG8UcXiVqh=&zXBdpaWbZUdmZ=&cdjkxoVdgaUfl=&zqymHbYeVrXhW=&THj8VyWWZreZl=&SUxJZkYqYXihU=&lPQoxbWelgpcb=&AGiKpKVVlkYad=&mB3RkBXYcraXl=&CBEdTtUnVrXaV=&rolwFGWnVVoVa=&TvuNG8Xchefbj=&9Q62vIZqscrlb=&HfoPDzYbaVUkc=&aXEOfCZWqYkcU=&bZyvmsU_bne_e=&q6nXXVUhkqrhV=&RGFtowVhfbZqj=&X3pA_aXmXZZmr=&QTCYuOUjfXdsc=&GAX3Z_VWhYUVg=&csQ3JHVclmdsg=&fw_PCVYgXkdnZ=&KS56eVXejrkom=&vElUOoZachsnY=&nmJolEWmojoZs=&M7F24GUdlXjpd=&wTamqKUjqUghW=&XXuIRHXpVdgmp=&kCARLOYqroqbl=&dVPTP6UmniVXk=&NTAQ47ZbXhffk=&Vk65J_ZarqYhX=&px6DNrZhlacnb=&gk3XrlUpmibm_=&aO7pj4XgobeqY=&maPsGCXpoUneb=&XBdUOqYnmbrZi=&9frHb3Zp_oUih=&RZjr2YVYood_o=&KZWCKiX_bYsec=&6iZYSQZijcUfc=&iyJ3vhUihhbja=&tkFZW_UYVUnac=&vpxKKkVgVYUkq=&tmQj6eYkoqpkj=&3hDJfMXdiiebe=&GvF_OoYmmjmag=&wcZsdoYi_hZhq=&wEafJtVXWdllf=&mBsdIZUscbWh_=&_6p6IfVnkempi=&DiUc8HXmbWgqq=&5vFkiwUUsm_hq=&aKuZyRYelWeVj=&qwRdLZVhpgXeV=&XfccXQYajZijZ=&JJcQwYXkoXZZf=&XoalYvXUaebld=&dt5ps9XjVrn_j=&uXy6GvVagUfok=&iH8F8oUWd_nbo=&BzeIgIUVr__pW=&5uUfZoYqhnnrb=&4QmfFzUqniiXj=&JcBhZmYgVVdoe=&wNDrgRVmsbrig=&6TxCpyVfUn_dZ=&NPx7TeYZdZfYV=&p8oIgyYWnihVU=&gzTLkRWpddUWg=&7A9PxnYrrhkVk=&cPfSpnZjpndmi=&gQoWCmYVpsUYZ=&X_OXzdYX_riUr=&sQpLQXYmWfcd_=&9OfgEMWieeaYc=&FEtCyNWVsXqeU=&sPgipxXWqaUkf=&NQ9THnUcrj_mr=&Zvok8FYggbnWr=&O5hrjhXna_UrY=&t6UsYLWohsacr=&5DH9DeXnloeWf=&qDzCsUWgnndjn=&nxWyLzUnnXfiZ=&_zKqS6VYqajho=&5DmKl5Vrqsjfj=&MlQfVnYkcmgrm=&SrKNG7WqcVWVX=&h8BipXUfWkZei=&OuBf_iVockZcX=&njfkt9WXfUjci=&KU2BrbWksjYWm=&j_JgaxUZdWZgh=&rnZ5cbVdYZXgn=&jRQvC7XnsZUbe=&MjgdO6YdXfXrn=&9SASpyV_agYZ_=&V_TCu4ZpeXsZa=&c3jqEZUfeWZUd=&SA88zqZWVbrka=&Y5yappUapWlsX=&AoZPRGYjYWqbs=&Ck2QQ5WUjV_cs=&JqthjhVUXnXZj=&29pYrfZZbXYWr=&kl7gXiZYhhXdg=&INEnyMU_dbbgi=&Qkmx72Ufomkfd=&bliRJ6VUha_Yk=&52EOF5VrdXXck=&G73gM7Upghjga=&ezIF4ZZlkXkjp=&B9TrM7Ubo_smp=&VIJvXtYYVYZUs=&3m5UkjZdlVgee=&yZSo62XYmkflX=&Yl9lSNXhmjcUZ=&a9i_2cYae_dja=&KEDXziUeikqZr=&RmAyA3WlUXaVl=&NpQkcTZjZ_agb=&YrgNaDVqXinmh=&WMBoQZXfnZjWm=&pDzciVVfWlnfa=&iEk5EhYkjmWfg=&6Jjaz7ZbpXlfl=&6YdErkWUbmUbm=&gOmzzIWUikgkb=&CgMGkNZjXmnse=&jvlAefXrpaXXg=&trgyLmXelZha_=&TMDoilZhsbaUr=&hYktUdWiXnqlf=&TPDu65Znroscg=&VH4OhBYbfYXns=&mWjzVwWdbpghq=&QB4u3JYfhbamV=&zK4jGzYafcYff=&mLRtZWZmqkerr=&8al4BbVhWdmeb=&CR987YVriac_Z=&QJtPdAZYVWre_=&VLbc2FWrbg_hn=&Vm6sn_ZVralpn=&b9qomSVnoiUUg=&gKGk85VbWYc_i=&EN4qeWVjVp_VW=&7BUjRzZUsVpqa=&SoF4f_VWqhfjY=&9x8bptZaWfscm=&LczwlOYgZWZhj=&bBTWFqVakbefk=&KzlpGcVfhVnUn=&7saLkCZXWWUln=&Z_ID45ZjWWpje=&GPlttKUnnoZUW=&IU_8KIWfmXmpZ=&SGDx3dZolegic=&dC5zAsUfWWnsf=&yA23cDW_jnmmp=&hv35oiV_cglch=&ma5zIJYUgii_h=&snY8vNZnrWlkd=&QEtdGYZkbVjcn=&zL2XXSZmrWbor=&hYD5IbUebUlZf=&CCaNXnYiddgkq=&MpImETVWnlaYg=&LHyPlpZhogomU=&W77gr8Uf_XnWc=&t2BAATUhZksUp=&pPcZUjVprpYgl=&FpdcbdVbiqqjr=&m6GnSHUgjkkls=&GKwnuPZV_eWfa=&IJPX9BVebkhfb=&5hIXJvUnsheXi=&ULvfMbZWVXllU=&CACX6LWUhpmjf=&mZNjX6ZmdmmVf=&FvEVegWpjciio=&t2COgTUoliqWn=&7iXhyPW_rkdsc=&ZQUWQjZk_fqVi=&xLAzuIZgbii_e=&FQWCMoYrn_khZ=&PpIQprZZlqVZm=&sclLbXYdUisYe=&i6e7EoUnashrX=&5VyynCUkjdgrk=&Sfsa9wXbVXXjW=&VpwhGNUiVarYr=&HLpmR8Uf_bYZV=&c6O32gXUaWpcl=&cVpTqCUcimcdV=&fRxMeqXfXZkjV=&JKiXDeVZYkoeW=&hNRzl_VrYdioh=&tcNENXXasoqdb=&ygWErxYYlkbng=&lTu7hlUfUVYhi=&PvIAB8Vhbodjs=&RFLgnZXVasikg=&hDq8laYWUmmid=&4yHOLfUcjeohb=&g287kCUnkpWUX=&PEDRZCZcjmUeb=&pkqWXDYlgaXkg=&MFSoZ5UosVeWY=&6IosENWXYiWdX=&xuN94qXpfgVac=&3rVnqIYYY_k_c=&TPpekZZjUkbYW=&5D235KWigYdnn=&woXHGLXo_dpsf=&8PtL9lWYjsbdj=&yvrZLHZfhUplp=&SWZzUgZaidUUr=&R7RM6nXcnlXrU=&B7ZhYGXjbUeal=&PrLBItVkchgqa=&CmdmKzUZYeXrg=&DyT_6PWrpipia=&bhp5fmVqlUggp=&w3bQiDXh_l_hf=&vthaELWmUVYWm=&7XcsWyUlhneqV=&6m7T2tUb_hYan=&hXJ4m3XsoiWld=&SOvT2nXjjqbqX=&SvSJBAW_kmZkn=&LFeDyuXhhlgea=&glZMO6ZfnbdVk=&mkW8aNVUnicUr=&POvj53Xkcoimn=&LcdsnMZpUopXW=&qf3F_8VbsenVa=&TiSY_jZmhZrqd=&9qEG2PZVikpZZ=&ldbA_kXiolWfZ=&RpiFCvWfqqngp=&oe8z5iUdrfopj=&NDVkUtXbneenn=&jKSL2VZknUrki=&KIW5HbZdjZflp=&CuCHglXimXhZd=&HfDQTDWscebar=&hI3THuXjoYUrb=&WWE6x5WckoVWY=&5M5lQrZ_ZbWUU=&4zoyOFWjXjfaa=&lchAGYWbe_Wfp=&vqSavVWYVbWhb=&2Y6tKmXsfsjVU=&CAbvdzWZp_cfW=&Cb9kvSUsgdgrn=&eHlQhTZgnbemW=&HL5eIaXXWUini=&hQh3F8UdWajjY=&lUq2RJXcpjbba=&gJkvraWYbgUcl=&t4lvIxXseplVc=&DpzuAGZZbcpZr=&wS5sojXUYXlZY=&MGqizAYrhZWoV=&BC6EHMZfeW_Yg=&haaCkjXakgghZ=&HS4znCXcdbUbV=&LikVDhYogmfnj=&cjSlRUUemYfcV=&izplVjVhadrhf=&6DVV5gYcVldrh=&QkLLNkYX_iYXY=&jlyDvnWqgXkXW=&MsSdseVmXdlnh=&bsFpa5XrZliXd=&ciDlivUlZdrsW=&TYuJHpUdcmaYm=&XIQjYmXVihror=&Q7VRYCXefjomU=&nhqT2wUfWVnom=&qlwdi7WjcpYXo=&SPghgCZbsfdkV=&DikVuCUbmhlrf=&q7KcKFYlchkVV=&rdn674ZiiYZZp=&9imBiXX_hpfmd=&JSbCTvYfqkqfb=&_Wy6VEUVsslsf=&qUoQw8WdgVac_=&jQ4pipV_hirc_=&gxY6y9XlkoleY=&vshn6AVjaZehX=&bOoS9fUVVXlVe=&smjLCWUkamZ_q=&vVWg33UsrqiYW=&xc8Lf3ZobahUg=&wsZAfuWqWqfic=&CCNiGZZohgsfo=&DAWLkQWmrlpoa=&pquSUQXicjdXa=&aAhfyvXgXimW_=&RJv7pjVYYkddb=&FIDHi7ZWoUidm=&GlsGrBUVhYhfs=&oWSjlEYWmknkk=&dg9_ZVXilorjk=&lnnYiCYqeXgqV=&iCBS3XZjZbore=&8V48uxYgsbjoa=&LZufPBYWViWrW=&jknVQXVUlZ_bZ=&FnqANjVpdgrpi=&xeTa7eXierjVl=&aB2GTuWgZinln=&W9P3uzWsehsVf=&LcIet5WhUkkWa=&ifeR2zWbbdZih=&2uWhX3VZpifaa=&xmIvAmYVgXhbp=&dScWADVj_bgsc=&W36WXgU_mqVsq=&zucPoWUljqh__=&iUavsnVUhUnXl=&N5n9sbYWncpge=&i8uOQaXVpbrpa=&owpiZRUgXlhbs=&8LkDabVfijqqY=&v7WEPWUomUWZU=&ZIc_CgYjlriVm=&nT5pWLYanqeUk=&qBUV2jUepllhl=&q7xUfTYXkXodl=&iApflpWpkminl=&fXsQgrUaWikrZ=&oyHH9eZplZXqm=&jw3FoeXmgpYj_=&sgXRjHWlpVmdX=&7U7LTvYpacife=&SR3IAqZsZsmhl=&YgjkApYlpiYoZ=&ywpbgpXmZagjr=&ghoHU7Yg_YrYe=&bdMScTUhbiosq=&FXUdaXZsihgil=&KdnJBJZbfplif=&Z93_qbXig_fVo=&prUmP5XmnXiWf=&8Sa3O9VVYqcfl=&gP298PZaWVhkk=&QiVmwNXUikWai=&OcDPw8Xfhasra=&PuOkAaXgWpjaZ=&mYE7nsXWUjplm=&SbHINcX_kaalg=&nfFSJkUeUpXXk=&Gm6egvUd_Z_oX=&6viPiCWnfWjaZ=&MM2vSqZlfrVrV=&ZiGnGpYprVkmV=&OUMrISZhmWkmi=&haCE9tZenkkVc=&uZjFjxWqhqfdj=&SnUj8yUcYYXrs=&syjYwMVfj_kYX=&WGMSTyYcecagc=&Qydp7NZnlrgkc=&L4cCDEWnakoZo=&8VVcGOWVigbrZ=&CZ6U3fV_frpdl=&ZS59yaYWrmaaX=&sQ5sMyUVqYWeY=&USmlEJXchokps=&zXgdJaYmckglm=&oIQQqYV_WmdcZ=&7k7kk2UZmYkVe=&CoKU54WkbYqbk=&kKDLlTUrhdXep=&NVC9ZPXXreclj=&X6KFrJXkZUlkX=&yzlBq8W_maZhb=&P6dc4mXcWofaV=&X_f9WrXXeZeji=&SUgZtGZkdr_gi=&A2QjcOUhqbfhV=&hUYbstWYoZdrl=&hKvgU_UUirqYi=&3Hxou5Upqsckk=&NH4Go2WYafbWf=&ECns9zVedfioU=&Xc2VJsZphoVjc=&B4hLoaUiflpWc=&w2tTIXYZlfrWd=&V3MzcSYjqiidX=&8IiCc4ZUrjVre=&HokNuRXenrppr=&9TjmoFYZdoiXj=&ewB9nLYXWZhlg=&87OxK6VVagsmm=&N8CtH4UZYamXY=&sgZD_6WYegref=&qECXuEXnpnisq=&jqAlqkYjXikZW=&yGHNddZkUpkVe=&ExDaG3YseVmnb=&OjRsSuUadigVX=&fIL2JxUlgVlYd=&8hCSk_YYqqcoZ=&SvTNDRUYbodgY=&__KjOAWnffopc=&7ibVskVloXcpd=&lW9EjlVr_mce_=&UcaZBTU_ndprU=&fJbl_5Ypeaces=&pp6eX_YVUdUel=&JwUadCVWornem=&rMUq3FUfZs_ap=&rT7mEmYbpnqbr=&xjr6_wXdUX__W=&HMtHRxUcbfben=&UVRBmLWWiWjkY=&idfISoYcXVelc=&PStzhtXVlUiiV=&uSaGstWbnkhji=&iKoVSDW_XdoaZ=&wWmfuxUoqbhf_=&8owfk4XdcZbWa=&ulPiCOUViraZY=&W55bqaZWojpVs=&oDpC2NXakk_qY=&IpdCCoWfaaogs=&HvxHQxUfdmsio=&fYVfRSWssqi_n=&QNTVixWrolrcq=&yXLN4KVaWrWhi=&CdFZ2gZZrooas=&Q78QbgVdpZdrd=&g88HToVY_qZsd=&orsYL_XVXkrYn=&pXyFIqWilYXa_=&DudznbYckmjne=&4YsLA4WlrWsdV=&gJQmDYZVZi_ic=&KTz8MnXsaslrU=&jt794OZWilagg=&KUAdsEWnsWjYc=&aTQ6sgYaokphb=&unI7YVUkpVqcl=&I9RsZRVbYbh_o=&ut3rPKZedqqUo=&ZTefcLVWXklfl=&izffR3Wcnoerf=&7Xe7lVVa_Zoao=&KYsrFaXeVUamZ=&USNio5XqUVWie=&iW7fj4WpXsiYe=&3kfmNoWkiWW_d=&bCK5lWW__ZagY=&bhwk_QVVVkkjZ=&XLSdGjXgnsebs=&YNJXhSXZrZdkY=&Hz_75uZlsllcf=&FeoTPIYcnlhbY=&qPVd3oZebck_c=&2dl9YUUWeYUXn=&8Go6fkYhsisls=&5klrilYqs_jUh=&CuIlmPXpbWWYa=&T7MpeXZZjZcaa=&fpnA9zYdhoahq=&IsL26aYUejgp_=&5GbRY7ZrVUXUn=&P7R8s2XWnhrXe=&8VBs4VYgpjfdq=&RiDimdYWdkmhm=&VSEADsYrmjnnX=&qXQGhqYkaqVWc=&HocngjZpoddUk=&97Lj3YUarlYjs=&uQjRGRZaZZara=&idUlzlZUpfped=&fb3XvUVrfdkdm=&BYbHKOW_pnofX=&JLsUFuWrUgYXY=&U6hv_QZXa_pah=&RqkKxFVjcgdql=&vQx6QHYrlnhYV=&3MYn5qXgVmrkd=&ko7ij7YdbWoiW=&5LtAdnZeYdf_W=&sIQa6RVagl_mZ=&BirX9bUjsaZXq=&NoxfMrYZZUphb=&BJcg88Uegglhr=&CNOLOEYYrqXji=&FM5LzhUednqhW=&DYM8lYYeXkWfU=&LW6oHFYnYbcWn=&6bU_TiVZrWYj_=&PzUSOHUZmailW=&FksFh_YgiW_qW=&PRBB_7ZemjpnZ=&l7f7v9Vb__hhe=&lQQqX3UqkjVgf=&vxidbCYZkpdke=&4oEseUVUbaldi=&LreJZwYWokf_U=&Kmy8DOWYjmnZW=&h6arPlYkVkXlp=&xaN6vQUYWo_cf=&YstRT9YkoXslk=&PSiDHzXZgnnns=&bttPPxZqk_VsX=&HRWPCPUchih_p=&QUE47AYXVdbeg=&QAyaBPXpnfkqV=&AsgRzvZdqdVe_=&5Y4avaVaYoaoe=&Gy3ZuOXaUqrii=&cFPAgrZVZeefa=&Zwp5FjZflroad=&RDZZ5pUZhjabo=&YE_IQ7XbpgoqY=&OwgTzmXcomaYc=&HJ4_o6WZYmsoa=&pmqvkFWerkiod=&XA3bV3ZrUaqdf=&x36i2pWbrnWka=&GxvNXOUV_WZ_X=&Pu3G8bUpmoUqV=&97h_YsXfphqjh=&7JkFNqVfmenaf=&_MC4W2XjVbYmf=&gdiyF5Vbrkpal=&tc4I_SUrZnnZo=&JLFsXeVVqcpVn=&lmabitZdccoac=&hnDbaHUqXnsUY=&2BQ2HDZhrWrjr=&6mBh5VZV_iXY_=&R4rJNmWkorod_=&jPSu4lXsnfkgi=&PMWOYVWlnrsVh=&vnzfG9ZYkpUlk=&NwhzfKUqYforf=&DuY5IHUjlbUZV=&dYXsLeUapZZba=&5tD3NmVlcfUdo=&QWbeSCZdVsjWg=&_BGyauYfaVqWk=&kDN6BBZpZZXWp=&FzQwtvVYWreiX=&JHlg6vW_bUpki=&7e_dHPXelUanX=&fss2BzUZVpYgk=&jYE9fFWUUgego=&UzAhNbUU_Xlho=&ef32YFVkpXdcc=&Ur7kmuWfmrsdX=&dGJvQVUchfcUl=&tU2dgRXmsUbUb=&24L_ObVfreXZg=&KwghhQZfZffsU=&_Hv2DuYkVoZde=&I7ix62ZVZccXm=&EEnHyhWergsdW=&WLVWYQZXffnUm=&6wVy8LVUXhr_n=&2QnmqIXksee_o=&FNjzpFYgXjWeV=&J_5ZsIUfbhWfp=&4LEwKAWsmXr_n=&kiHAkhYdchdic=&IFthJeUp_eZkX=&R3uxOOWidZXao=&MzsHiEZVYfkqg=&GNz9mtXqYUVgm=&DpJI4HUcfmsfa=&E3KmCgXoib_qp=&v8btaLWdnmkrl=&ekdB2AZXlknso=&d_EJB9Xdrecr_=&tXTymCWaWdpYY=&X6a69oZsobcmY=&jUSDv5Wepgcja=&77I6uPXg_ncjg=&cG97JAWrcckVY=&o9dfPXUpdb_ck=&qBYNjoYhjZbfh=&TOvNr2YVloUph=&sCCXHOYnYZhXl=&W7SirIYrfXdkY=&OrzOqLUqrpeln=&K4zpujXpcemVq=&7tzryPYVlsWcV=&wbJCppXgqcgog=&q4Fwf9WgWshZ_=&Ey_P4TUhmnqjl=&9iDdEwVlfWXfq=&WEMSlNWfnW_qZ=&IzZp2VUcXsrYU=&qlg3j_XqdpbZs=&QpiPVZV_rgfkg=&UGOnZ7UmnVqmd=&nFbOmoXarmseW=&w5QyamVrbZfUo=&heL7tyYgermqf=&o3usyQUmniige=&lYnPIdVnnZpog=&QohrZuZjZUgXY=&C7WfFwYpjbYei=&JhtqyEVrjXkVV=&cdyMExUcpspVY=&EKzlMzZlssWsm=&Wj8MsLUfdomeo=&xyr4wDYjonaaZ=&HmfwxwXsl_fri=&CdYC8nXZZfcdj=&VHeQbXZXgacUX=&nwkwnTUsqnds_=&bJEbbcXgbWhhd=&BlHTNQZUfUmsc=&jWzLJjUgpjmUm=&bEMyRAVk_qbif=&wgYNkDZblomoe=&BFkA8DYjdmqqZ=&4r7xR9YYegWep=&8isQlqYegaobg=&K7ynHgW_bobcp=&29EnweWibkaXj=&AjtajLYWjmcfV=&yW2b7KWseojg_=&RXxBqnYgk_XhY=&thqWlZYVeZlck=&hH8dRRYseqXsg=&2AnPELUqshbab=&2smsJGUUsfsUs=&TcbU9RVVhhjep=&Wor9uPWgbrqVY=&reoGVAUeYbqg_=&K8tcCHVgqUppp=&ISaODMYanlVWb=&Q93iTlVhjrhUW=&gMh8VwWifdiia=&3kAOwyYaYskoh=&lRwR_dXaigjYV=&ETGZRwUabjgao=&ZnGETcXephpeU=&4oQw8CXlshbcp=&oSwpRjViro_VV=&5NVRRrUe_bVZf=&quPasoVecXVjc=&w2CInwYXoqsWi=&PO8aQqZVchXkV=&uryODaYamfrZs=&ZM9S4VVeajord=&OhlZDMXocekkc=&tu9O43YaahpWf=&FWN79XWZUmsgb=&Bp9wKWWhmUUrh=&gypoZEZYgejir=&FIg9rUXUeXWhs=&qJcy8LUYaeirn=&D48QY2VYUcoge=&gROMfxVX_WioU=&6cH3uKXskjhXr=&AYziLrUqXUiof=&ZJI3vgWcqmkgi=&x9b5m9WbagcqY=&ghlnxwUqkZeik=&wZnKa7VXjp_ha=&wlDoqrWji_VkY=&JfeWBSUnpijYZ=&VI2Om6UXehpcl=&mY9sOwX_aVdss=&d5IwVBW_ocYmU=&6KmdbZZkpmofc=&7uwqg3XaUlWZa=&aKPAeoZcdam_W=&K3eXrAVfdlpiU=&XnlHwAXfomX_i=&p7sQ_IYrpisgo=&Mlnl_zVc_bbnn=&z9fibuXcbacZp=&NgnTL7WsYXjpe=&uN9kOnYXodhqa=&22hJwjXeXigfl=&OEXTkNVUpqhho=&NG6NDTXfhq_ob=&rxPKtlYcqjphn=&dzBmrmVlVqhih=&k9vm23Ukebdap=&SxrPfYUaVpUpq=&CfV6lzXilZcqX=&dIZNQsZdWpleq=&tUntYeYrVWfde=&64Ct_wYpVdbim=&wsveA_VeoXemc=&KwCuRtZqVYWUr=&xhSqVhXq_daVm=&6cizLiWZpoWgg=&aNMHRwYZbahgf=&UEq8hHYkUWoka=&dDEvUyWmedVlZ=&la3pXyXb_Za_p=&2ZF8CHVpcoXfm=&x7WB66XVVmVmp=&GY_gmZYV_W_ja=&y8Ws4GUnWqYeg=&nJgW6AWkiUf_j=&TfuL85YplqsmV=&SP4FfTYbXnonU=&SlY47rXleaWXZ=&aux4cIWnqminh=&swY2itXkgss_m=&yrzWmcVsnW_er=&3dTiT2Vhkpbre=&VXoJ2GZdlcfX_=&gDVb9yZmapgmk=&6RdWExVYi_nip=&dMiuXNZUVZhkg=&XUyufgWUZrcrY=&vnvg2ZVU_XUao=&25RjPbXehZcps=&mLeprCUpZgpWd=&kVppNsXcob_en=&xAbUEtYgnrVlm=&TrHNniWgrWXka=&oGcc_wYfVbVZg=&Ah3ZCjXpfWZhf=&Pl9A3sX_aYgbX=&G8Ck2EYmZkrXq=&7DY98OYbkdoeV=&V6Q2wMUermUkr=&qybJDFWfpsXpV=&QFkLp4WjfVrrW=&eYMDpzUYdbsdb=&VgWyFMXlmllUp=&iG9AbWXYdcjoZ=&Vb_alpYjWfacn=&UhZdlOUlZfeaY=&XUjtT4VUqmgeZ=&lK8NbDXUYaeqb=&gGuKssYZrfXcp=&iCOng2UkkmfVf=&oftM7FUmihiqX=&v6WpyQYZkbYis=&jSW_STZlUgobc=&f4MoLKUcqikjn=&BeFLCUXnoXUcb=&yTAk5LZfXVmeX=&3D_qtEYrlpcW_=&l6JPUeYprkiXY=&izBWdmXpfkmng=&VBgMtdWpego_g=&EZsp9QZpfqXcp=&LrJpAYYfWshih=&PZGtz6ZWqYkcj=&XnHRHDUilWXhe=&LhbtK_ZsoqjVc=&G3xCG4ZpkaqZs=&y2v4CxYZibcUr=&WEXyucUioaojX=&25oTIXYjahiXX=&CFxP2RYhimZVd=&zLicD6ZYldfhq=&UxEeCyXWdXY_l=&nJLYxRZsalsWe=&hoh4f4VhYo_mq=&WIcFTcVrUo_Vk=&HKfxb6UVdWjr_=&u3w46XWaVXWiU=&JE_nhmZfZifYW=&wTytbeXXklUWX=&DkzKm5ZanZkdf=&rpTQwdXUdhqUg=&CjpRxiXgnac_r=&UPdEdIXbalnkm=&cAkIjMZceisVi=&8pdoCuYfshWVp=&7HXQQvUnrYlro=&Kn6mE2YnbokbZ=&UpCCCjWljcbW_=&XWPrMCZfhaoqX=&3d7YTqYa_kZmq=&YHCQU3WnUdmdr=&a8aFkuUhpYmbq=&lEiF92YlqfcYg=&_EHudBZVlfcUs=&bZpa6NZolYYjn=&bPA244Vrqbnjb=&BSz5qoYWkmWdq=&_QLsKLX_ZaphZ=&A6ENgaUbdsZbV=&eEyciNVmV_aks=&UXlIn8Z_ocnsb=&k5hGooYnlbiin=&XogAlLZnhbe_s=&hvkkJqVksZjUV=&Cpy_9ZWarlbZj=&VwjDnVUUdVclX=&Uov8KYXaWnqfY=&79UquxUniepkk=&FGBWfVUgUgXdp=&5wPjFZUksc_n_=&asvdjjWkXnlbZ=&VXaUNEVno_oWW=&S8jzAgVgUqif_=&_zPmciZlVhUjq=&myGfuVVmocfmX=&ulRgqJUjegWkj=&_OAJVyXWndplg=&fZuyT8ZrVfhnd=&gAbrg8XkqdmVd=&HQTjszVVpaWYs=&vxxFYYZXUhaVp=&hjhPbcYphipZg=&Q7p8e2VmVmiga=&AA_bptXVfXi_g=&SrFQXIWaljhmb=&LoB5PDXrjocaa=&5NZUg5Wccblid=&slH5ovYVqijWi=&_RdJBlZWgo_rU=&d8dyPqZlVXmep=&TwesGgWsZks_d=&xvfTw6ZlVnaes=&dfwnwfUgrXZUU=&sHaddtXcWolqj=&Dm8gWmXgiZjlj=&FHWjmfUrnhsgs=&cOhskYYdXkYcg=&BFhUXlYZnUkZV=&9ZvuunVleYgUk=&vPzHdFWebUrgZ=&AgtA4kUmshVsn=&vDf_4nZdfgokb=&xUoD2yYmYhibo=&7QVTuTUkadXpb=&G3snEDXiqdrpb=&AUnl97Vmaloqn=&oDgs6PYpXfeeZ=&DcI3qzWYjejml=&tCgvZvVZsZsmY=&qd9rnTYVYXn_Y=&LL4FCgUffplji=&zn99o7Xe_dXgW=&QTPSCVWVqofeo=&y4rwatWYhohbp=&p7MCCJVbhonfi=&bQ8HW_Y_inefm=&5YFXTqWqqknpc=&AEtr3PYiohkja=&vqAWLPZoldXae=&eqv__lVWjkVrZ=&EXJtx3Ymnlsqb=&3GirtJZd_sqXr=&exvig9WfslmWd=&AIhHoUZbhajZY=&jsnlYJUXmoikY=&AMVWQ6UfUdfpV=&BhhstDZrgflqW=&vib6EyUmqXsmn=&9aHEzOVqZ_ofk=&ybztwmVmercma=&magn5FVsXYVao=&tgFUEXZkggYdk=&6jVI7uVihaZXi=&hTA_WVX_XXZYi=&FXZbg2Upa_ena=&G7rRF8VXcnabj=&VkmMOvUUUgnnh=&NufdBeXahqkYb=&HbgGgzYorf_Ug=&rUfAMcYijepZc=&FHU6UqWUqVhbV=&nzwHOTYfWfdaU=&J8jZ_aVdXprao=&HjRjyPZmoYnoi=&KaT6yCVsV_ona=&bUZzIBZhrposV=&vy3BhqWhndsaj=&ryr9J2UljVoqU=&CmDxpcZWroYlX=&T5JHwuYXsqVom=&VQnF5NZiajish=&UoVtHbUjbkpjd=&q9y2YlVqnWUqn=&heQSeeUgrikne=&ezT7mHVqmgqXi=&zNfmr5YjjhZkX=&wqMte5Z_iZZip=&ju4IB9VedeYks=&gvWqSnZndZadk=&2b28lFYXXapsU=&fe4eEJZicasqZ=&nezQHrUfpoWbm=&c3zIamZXYllpZ=&ftxJtDZfXq_qa=&SnZaCWUsUXVXs=&HPKqMBWgbbnhg=&tD8hZlYjbqric=&n2tCHPVbifbok=&IHVQPeZVdfdkn=&YCQcXNXcioYei=&3nbuN6Vbahbfg=&xIi8__XldWoZl=&IXXZRZZabkahj=&VMG9wJXl_pkhX=&XJKGN_WhZXjqo=&wmJ7YUUjddZUi=&SuDv27Wmedeor=&6GuWHjXUiWkVe=&ixuJxnWshksll=&RXcFxVYsrYXcm=&A2ydpKX_YhsVj=&L_dco9Uijbahi=&GRHJL7VshrXfg=&qzwdukUalopin=&g7g6znWbesfll=&JN8hPxXd_eja_=&4gB3W5VksdVnZ=&8MezUGUmYXUWo=&yNmdNHWkUhVfW=&cj9kqyXUpZcih=&MK6lFuVmpgWsg=&fZTn2EVhUjjld=&wWSmstVrcpYhm=&J32fcPUlncXrj=&BtFL95ZakaZYj=&WZ5p5FVaVmsrj=&ibVjn4UcsXibY=&eknpvzYVXZZkV=&uQfc3AXaVbjfr=&mEz89DVW_kakr=&NaIvl9WelUeqj=&B_asyNWsnW_gk=&Vdn2rpWjgkime=&jIpBSRWWkkaaj=&MDhzQ3WjUbkWq=&CLyENPVaWqVdd=&wJ9aHcZibV_Xl=&PQjolcWnqfqhZ=&w4R8FbYklojmq=&tR8e55UlmmsZc=&BTqFOZZVVhpbl=&zRwbSCXfVcbpV=&4TfB84ZUpbVnW=&WKBrhVZslhmfZ=&xP9zFZUVkedsq=&PgdKvCYiXigqp=&_lMewtYerWorp=&fnxGKfZeUUWVV=&TAw7wdWYVkmUs=&pEKy2LWhlsomm=&adVDyzYkp_mhh=&aYFo4qUriZXhV=&j67y5LW_YVsYj=&XmT7WXZfg_s_c=&pIAnSGXZXiclp=&OURmNsUkXagog=&kZBnSKWpeebnr=&8qL9beYfapoWg=&5CgRIkWqllVle=&XOvFgMUmVnqlr=&yqfB4rUZqdkjc=&VJeZ8UYgkUicr=&nAjBCGUmmWXsf=&XeRwcqVpZpZUe=&vTfAQFXcngkWX=&Bmw57FUZfUrZn=&zN6KNtWsomiqk=&5yhE5qYhZb_ra=&O6_biuWkohgcY=&9GUWo2WmesXsl=&nQ346sXbXsXdl=&ItwidwXflYrcV=&_wvhkVUXdfare=&UVpgpGYjVZrnZ=&E9ZhV6Whdhfcn=&2iMXjeYkdpkfp=&WuGNIbWbocYYW=&hpfsxdWZYbnjc=&PGgkk9U_fZ_km=&uLdECjXfhbbWV=&9hyZIUWofioWY=&89mu5FXrqsbYg=&8CpJ4tXdUYemW=&FkfyguWagqaeX=&UEj3AYWbmUbqm=&ozugl5VnVedgj=&CzBNkJYfhksoh=&A4Qq9FVmeUca_=&6hWzZ4UnaeXsa=&mYtZdnXcrYenq=&_h7hkCXspUhbf=&UwvTI8VaeqlbV=&e66xEnWrmifoV=&5BunlAWhnekUg=&ptpWpiVoZVpWZ=&lEezR9VmnVmVW=&HxvU3qUYe_jid=&KN_I64ViWkakV=&QLcYWEZnnasmZ=&zAeR8bUZsabYb=&F2n53eZX_kbkr=&cLMeb_YYmUgjc=&PPsO3VUsmbkkl=&uLLqJnYsnjlsW=&UNR98zVacZlWi=&sxafrIXabrekZ=&Xb6GKYUspZYWi=&e7qec2Vm_mfZh=&yKD_NMVYn_a_X=&HwX_kKYgpXgcb=&Ky5EP3XXWZXkq=&yxl9VwVUVbnUY=&yewK4tUerUinr=&4YyvvfUWsdage=&2CFBNlWjrnknW=&S6OEtHXbWaWrV=&7kJYbLXssnpr_=&8hKKLrUakpsUc=&coyeT_VffpZYV=&hffrL6YXllmdd=&47I6siWijXiqh=&BOlMPHZefrXVU=&tRjjI2YfXfris=&muLDBMZpmfqrU=&4vuqiIWhbafWY=&PsGYjzXfr_Zdd=&YdlwEMVjXiidX=&a4mRWQUWW_b_s=&dlJol3ZreWYji=&uny4G2ZciUXdZ=&AQDRYkUcW_kZo=&s4jYc3Wfmqrni=&uqmdyaUpqh_Zb=&zv5yUYYolsUbh=&6PrnCiWZpkXc_=&alIIrzWnabW_m=&zOjx3jUcpnoWh=&qPMxsVVmdnnlf=&o8gzhjUoqlqYU=&rWXyEwUhVhldo=&wBPciyUaibWdZ=&jkFT_bZpmrnZs=&bvDbMbWlfXVfX=&_Os6otUqphYWd=&3p5LvTZlplfk_=&VcQIufYUVZZlb=&jeK_d4Xjhfedh=&RFCv2SUjXrfal=&IzPKIBYpnslgV=&JvunfkYXbarhX=&68383wYdhXkrg=&wxEssFWaZUbVU=&CMuDEYUcliaeV=&ujwBJoWkkcdip=&HjubA7ZXYlhqY=&Ktze8zZoshYfg=&4Bwac9UojUa_k=&UzJsHgXcfmbcZ=&3rA98oVYaskm_=&umfGD2XrmUgfb=&XoYxipYmpsjjn=&5pV58vZm_geck=&plQ337XUanjie=&Ibm5ynUsoVgjX=&PHjdk7XnUmpWm=&FYpouuXZbsqes=&eDH8B_WskUhim=&9HcCTiXq_iVdo=&xA8iM6XsUeb_e=&KNRqc6YYiWUgo=&hvHBerXofgqdZ=&_NdYHEVUYUYro=&DQEnIuZoXZdp_=&A5JkZsXjhhYno=&MG3x2yXhVjabe=&vYbAgNYaVs_en=&oGs_yOXUhdpgd=&RMHy7CXicYYVV=&ZW7Y4mUgVcnrU=&WV2IEzUUVpkpd=&zIbxquWkWggqq=&Rh8BynZYWmViW=&DcWDxZUVgWenb=&MwH3MtVfjspZY=&cd_aWFUUVgmhX=&A9OJHQWZYWcnb=&YaXPs3UrWpqhg=&mgT97gVcepYmU=&mw2lfaZelXflV=&B5PPHcUXkldem=&IwwMIdXcYsnXh=&wF2zIRXsgWcXZ=&CiwJWLZpllUV_=&YycR6QVf_qgpo=&J8_Jw2ZekljeU=&AaDGquZfmglWr=&e5pzi3UbgoZf_=&YmgYaZUgW_dYh=&icFiXKXfnUmqc=&fCsm_AWcarqml=&mY52UZVhYYsho=&vXmYCEUiqhnqX=&6L9IQ7VUp_osX=&ycsIZLXVhZsnW=&LaVMXUZirioUo=&WQbLVjYqfpYje=&cfjypwV_kfamc=&ziZrk8UskUaVk=&VDXu4IZaXliYe=&WaSv5wYqraors=&MWK8xgUjZklrl=&3N8hEHYnqYasW=&3szifRVnanjiY=&AHh2omVs_Uhsg=&AbS6rEWdjnbUU=&hEhEmhZpscUVV=&cBfoj_WYbVpnk=&pE5lXaVVaeaXj=&UNy7GJVclnhkf=&lOrjPpWsoWffY=&hDHQqtZqjdnhm=&tsN2R7WWfgXcn=&dF7AjiWkiVjgc=&ShITdlUZoabZq=&iwO2isVdbWr_e=&UR4v4SWiiddVW=&FLnHBkUXZflbh=&jFZYvnXfedWrU=&26JtF8XXoYfUs=&oR4RLKUXqiikW=&pinRSnVssZjVb=&bulWAjWgbmsoX=&v_lFziZjpX_fk=&KgA9wpVdqgVVk=&hPGiEJZZcofp_=&GCb4IlYiikaWs=&PqRCZbVrXfYpU=&PHfjuSVYYYfZk=&KUcWrTXbaV_Wq=&4g5lltXp_fUXn=&QgdFjNVaUXbpr=&iybqjIWhkcY_g=&wwWYFmZ_c_YWb=&bqw_CpYsmWglg=&Yj5CMAUVppc_j=&iv3f6cZUXqrgp=&p7uVHhYUs_bW_=&qSbxW_XVhUkqk=&d_YrESXWccUdj=&rPr3UmXpfiYob=&6rS5eMWebfkqX=&StNzhgVWZffr_=&iDQy86ZXqpWXY=&gjxb9QWcefkkl=&guAH_kWVUeUj_=&Nr4dxtWcsrcVh=&LDGsBWWXhkZXU=&HrfzLOWesjdok=&Nucu7hVoWUXor=&KNerOUYYelmeo=&nEFtkUWVcissn=&DkRRgeXaZ_oUs=&lsr8YwZmcWsle=&4zb83SUaaZsZb=&LlMJosWYmnZVZ=&ZQixmNUskchYh=&gljw4cZenb_hc=&4mIrfRWg_nhZY=&GB3TB3Ykkchhq=&tMsE6nXsYkjkk=&ZKjLUBWjsYnfk=&uHVlDeVYZUqfW=&5orhFnVsl_qqb=&NGt8faXagjYqV=&JaePewZbfbehU=&4AnoK3WUihnhg=&RZtMqkYelnUWe=&FNhBViVrinkZ_=&bmaB5tZ_plglk=&RluF_oVbgshpU=&AID3FCUkjebhe=&4DLK9QXbVlk_U=&D5cGinZbcYpbd=&JaXg2PZ_Ufodi=&e7HQH8Wbbssdr=&PSa_EfVqnXbgf=&bEqvWYXXooYjU=&jDy6JCUcgsUWf=&fLtkEcYUZZXUn=&w_vw9iVepYoUq=&X8I2dKXZl_n_p=&SiQrNsXVdfs_b=&VO9mAuZYgoXak=&wHXKouVcZcgre=&lGFvSzZnhlrUg=&hbmopsZhXneWo=&gFP6akZbsnhlp=&w_ZryIVbVnnpp=&IuGZaMXcrgcln=&roFuquYqssejg=&dmWfejYieebin=&_cGygCXjkVahp=&K87q93Xjkihor=&NlvbLsUdkVcgi=&fWpmHGWgq_igc=&_gkBxFUgsjgqZ=&HPO_XnZhZYlZc=&NY48RRZXclXVn=&XTnLPKZZeZZmW=&9BSHxgW_mjkXY=&TUbC4lUmVbZUs=&M2UYJtVeVesia=&fsCmYwWiWmabX=&jfZxteUUffbad=&APINxUUUodWZc=&GuRhS_XVeaeZY=&QjikMGWsiibhq=&Q8q6RbZlhYVlo=&bLrfB3XagXfif=&qSNEShWpYZkcZ=&vHpXKjZkagabk=&TJRXdhWnWrhdh=&rN9Lp_Zncpajb=&2PnTTbVdhXraY=&PA7XKmXelsV_k=&vKgYncYf_o_Ui=&5L97ryWVspqab=&HUaA4cW_ahafj=&p9Zi4UXWpZscl=&6y3THpYebiYss=&YQ2ibRZlVVUka=&mMUgobUsecWei=&IcpMEHZYmplcm=&eVKrNaZqiphoj=&N2CmHcXsasjkq=&Nz9IyUUhaisqk=&Lj6v7AWskpiic=&WtSNneYacjYZY=&mxihB_WqjkVjp=&48orByZWmepol=&lH3zXUWeosZfX=&YnskNrZnVankg=&VpgOs5Yhdspbn=&8Mp9njUeYYoWl=&WQ8iAqUcW_kss=&DvEWlRYkYgYhs=&X7PxSWXocdfVm=&Fk4qhtZUn_nag=&VxoTOUUlgWrgc=&SsCweoYocersq=&4YdasRZbqpbcc=&h95MQVZcbsqXi=&BY5CCxWVrWari=&fhM7elUdiloaq=&cmQGfrUjYlgqX=&4tMaFTYfbebmW=&3aWKJsXeVgl_V=&JqgglnUhcWemr=&nzsYsOZqfXdVc=&L_oriqZjjjVeW=&CIreT8UodWkUn=&36HZ9aWmrroWU=&VvKdwFXqYWrpW=&5ahoNGUmYZXah=&Bs5dICZkqfjXh=&xTrgPSYbndeW_=&_EDOTWVnkZcas=&nEYUSRZZkogqZ=&6I8qz9UlfVUcZ=&khc8VTZba_lhl=&xwm4D3Vnc_hje=&7iPeuoXfrWoZY=&c3ALz4YnWbjpU=&nUvqRxUmifsdh=&zWclOkXimsjnW=&VA8CzEWrasjpn=&vsvhAaWmcYecs=&MFKvLOXbiqbXi=&OjVJI8WVmesqm=&uuG2SwYiYchhc=&antxbhVYYadnf=&kVrg85ZVhWjrj=&3LRogBYoX_gWX=&lhtyfbVgciihm=&BExo7dZdkV_Yp=&UCYZIkVbrkhZb=&FRBXstUhqUndj=&7_diVJWjoUYkf=&sKojgbVf_YWWr=&8iqF5cZcpUWdi=&QCJz8oWXhpfpf=&qM2l5mUqerflW=&J42h_VUd_cmaX=&YshaXjWYjnWYg=&udrhJvWikZmji=&9ctbXRWhjgXln=&m4ffmbUpUYaZn=&ZcPLsJVhpVaZg=&DqjtkIZhbidkk=&iWrRsyUkoqr_s=&Px7qjXXncirrf=&tvmxAzUnlXrcV=&WN5OpsXbUhnb_=&eJVQhjYjVkgVq=&O6aemrWYVpdik=&MwABRCU_brqml=&bEtEaVUajWfrh=&rVJ_lUVeo_plW=&VHlfo5Wss_bUg=&fElEVNXVZhgkZ=&VLW8_CUrZmjpk=&VRHFL9WYZUkZm=&_FMBvWYUVhiqm=&NDxl8gZXXgVoY=&kzC49vUVbdomX=&KXgEXrVkXZedU=&d6UEb8Vbbjomd=&3Bv5xUUlVXleW=&qkp9COYiVVfna=&QxeijfZXenYp_=&RO5ZItUXUrlXs=&Q8T3FzZclZojf=&ndqCxEZneWcse=&TrfU6YVhgij_s=&yZAzusXjYlf_p=&Oci7_5ZljpXm_=&B9CbePZndaomj=&CVxb5nUsYrog_=&Wxev54ZVshXjn=&YqiLvYW_njfVl=&mac5QIX_ljdkd=&ggXljIWgcseck=&lqxFQ9Urnpfao=&sWHXBnVoXorbZ=&nDvK6HXVhkmhs=&nIWvh2WZUgmio=&2Mif_VXVilsUl=&CmDTDEZYaoacd=&4xMTLIZpciZnr=&56VMAZUpqWlkk=&d929NXWrnWVjX=&WOIypVXfVrfs_=&DeHbA5Yb_b_qg=&vviCPZWcWdVYZ=&3iLK8uWaikmlW=&Dt368FYkrodio=&lyYr5xXZYrVdl=&HEVWIRZ_f_hof=&3gVrhYUbZaYsi=&NSm3NKYpsYoVf=&3koXZWZgi_Zpq=&_DcDUgXpcsX_a=&zkMwRVVZVWgof=&6v78y5YlWhdcZ=&9pZGP8ZqhoUap=&yPc_7DYsk_rka=&OTrskfVeqrsqi=&lQustGYpqWmjj=&x4LNPwVXdUYng=&552S7aVoUVdhc=&ebAfFaXjhhpng=&sPLF2LWbidcsa=&Jyu9dEYaofmii=&iPgorHWidVmXn=&u_cr3_WggbZWg=&9ON2UVZhmpfff=&btr9JZYlgoU_h=&AeJlNTY_dWr_l=&d4twr4YjgWqml=&G2w8XOWeiqrYZ=&ypV_H8XZXmlZo=&YfspA7ZdrhVfj=&WHaToJXgYhlVa=&X3S7zcXgXodbf=&8CZBG2YdUfkgp=&uoRbwMZcokcfb=&cKSRPiY_eVoUW=&MW7lsrWnlhsYq=&ObBu5_UXdibjZ=&k2k7PoWkpUblo=&apx7gkXjWhkbf=&2Nd_Q9ZYknrpY=&ZhOzhyUoYpspr=&sKMolKXjbqolq=&e9rStCUlqmhlU=&y2gUT9Xrdoeci=&34fhihZlkebqW=&_5WAunXd_edbc=&UdeTGIYp_kgYo=&8QmplHZnfWmdn=&h9a2QmYjerZZV=&tWebsyUreq_bl=&HERm63UXUWj_i=&ouzXg_XmafjpV=&5xr7RMVhshqcV=&ptS2KdYpsgmUi=&gVicdSUmnYncj=&ftkKgNVWnkUaY=&UpwnO6WYmbX_q=&EBdGMRXohiYXV=&EN3fu6Wiap_kd=&MMLWDCUUdmchr=&Uzl3DbVkqjorU=&colNakWXWoVeZ=&xGrdF6XekiZUq=&qOol7RWZas__e=&HIvGtuWfsVjrg=&Ei5oLvXjaWaqZ=&2kViOsWUcmWWr=&uzcDJmWsppanl=&fwZsUNV_jpomj=&ynTIXcUl_dalV=&L9UgRtZV_gkcW=&E6STUqWWZjpiq=&w34fRjVlmjUki=&5lLPUiYWs_dhW=&hq_ywyXsZmedl=&Xx7peXUprcbeU=&DKGkaWVlVnsbX=&W7aAipWXjablc=&sUdDILYlcZjba=&Y67CJgXeehils=&PbdjfLUjgjqcb=&2TP3ZHZniopXo=&_OA4O3Ubhkao_=&k8Px9HVUaecmk=&_AOxiTYsjoWg_=&epHBjFXehrbWg=&sr4DnxXgnUYfV=&hJPIljYkoYcs_=&aj9lXbVjVsqWW=&ocSMSWVgrVnWj=&jQXtZUZhqipUc=&xl4ay9XnXcUbi=&JlQioLZqqghZp=&VMPU4KZqYXjjc=&u4zgrEUVlgUff=&XaWht2XVmrloX=&4VxMJ8YimWoXb=&gd3LBKZUhoXWZ=&xvZoOXXkmncho=&vI6uKjVUrihrk=&GEIPqFYkmrWsg=&zeuGsDZfjkgbp=&YLbIP4WjWcj_l=&5fO78FZdcZgoj=&uCnW7IVkbViWZ=&6CXLfIZbfgkie=&lNnBNyXYksYlW=&GeCPHzUkmbqrc=&wv4ZTHWYXimWp=&neDfBgWVpoYhe=&j5WkKZYVaqZfa=&KGupRCZscscnV=&OkHrocYaijcnh=&eWDJ9gZhdrrZd=&6ePOYSVldpYmX=&w6dLOzVsrlfVs=&37g2UuVkfieVr=&nFdthKXgUVdUf=&yUb9sfZjhbVVj=&eTwahPXi_Zdgj=&APoElFWfacbgo=&QJgknXXembppc=&tSTAx6YlrUskr=&bqsHIqWVlggle=&D59Yu4YhrZYYa=&mGqyvUUjclmdp=&GQlJijUVneaUo=&jC4UpsUqkXi_V=&vu9RsyVahqopm=&S3qQhIUf_oaVq=&JRxvXoZUjggjr=&O39_E_VqgUYWe=&rJvrblWUdkcWq=&TAjrKdUphqXsg=&nf3QwOVlmedrd=&bFrU38XjlcbhU=&6PVvJWVkVkqic=&47gzGNXZVXqhr=&LeaOVkYkicksj=&NTKjfGYnhffmZ=&SrbGxZVfgeWaX=&ZSniwOVjqqZjj=&ekAftoUnhqqYj=&NUHwfSWXi_WXU=&_FQi4xZaqdYig=&grdrbkVhj_shX=&jrbxEeVUjUnVj=&qJncboUchqsYr=&2Z5lxLVhhXVqj=&2RIoyZXsbYlah=&Qtd9OFUplXZrh=&CUJ9z8ZXoackq=&mcrfd3U_nrild=&ZUjRLlXaekhqU=&fKcZ_VUphWeUg=&mAjMMEXUUbXkf=&4rFoPjYnagqaf=&U7wUpkVq_cYql=&VDYpqcWVgq__Z=&aIYPDOXfpsiWc=&haKJDPYhm_isi=&KIrCcCYqcbagf=&82Iy87WbVWogg=&_Ks5aHVXc_ZZm=&PR6VpkUbsbekY=&vUfBUrWkeblpg=&XxjxqQXmWcpZs=&Dbtat4VYfVUUX=&o4Z4LXUomqosg=&pZPZmkYVhXrX_=&GQOjatYbnbhcj=&K5AchqUWoVdeY=&J5Ol4eUspoUZU=&hT9cgJZbpmjVd=&YssnOSZlWq_ZZ=&Vi53k6ZmYnkWj=&v6Iwv5WWVcrhj=&WQZedsZXVXfoW=&GZz5KmXoajqjc=&wKRIUOUbWb_g_=&ToBFHwUaXroon=&FAynatUarsdhn=&6fLlmMYVjregq=&UXOYVrZZanjgm=&d9EQHNUqnpsnZ=&x7PhhrZcmWlsU=&CiVCcDVpYVUaq=&CJN6xPVinZkdY=&KjvEl3ZZbpXch=&hoyszOXndpWlg=&5eO7E9YaoaXbj=&VOLEe3UfZXdZ_=&FADWdmYialndb=&JKPwwVXh_aljq=&fHBiq2VhehaXp=&ECYZS5VgWYeoX=&2ZaTiGVljssgf=&9NSs4mZVYicn_=&NgqqZTVfVWcsn=&_WNyGFVmeUkbZ=&2Hp3afXdpXesZ=&HrRjN4ZqjeoZ_=&LJkIk6ZV_kslb=&PjQbaCZdbcmaf=&c_da8kUpbmnqo=&yLxyenWYarilm=&VP4kipXbpmecW=&rE53vdZfoeWVZ=&zbvX9PUmUYodl=&Z4RuVZXkZkg_W=&ENgBfJZrfYsUo=&pJ7XTyWkn_siU=&LGoJU7ZlYrgdZ=&d_zBm3ZYmXmss=&nyMvUoZZnYfhU=&EoiZLoVVisrhX=&dMttWwWfnldWc=&r7LWv6Wc_dkZj=&tWSc_GWnhfmkh=&wm2s2QZXkfspf=&Epm7bYWYnWgpZ=&de3YitZiqnlWc=&wGzpHTVXYZV_X=&5sMNHCYamYUcV=&ezwX6EXUfYUYs=&YrxsFjWUheVWn=&zedoh3Uijanph=&u4nrxMXksjXfj=&oI8YxGWWecYdm=&unY5awXeimsbe=&SNrSsyYipfWcn=&NTHFXyYbZqUgq=&hDHqWYXachYi_=&xoeytwZUWVeeb=&s5B4Y_UVhseni=&3Fm7f6VleqrXo=&WrnIiqZYgrjUm=&DDMRy4VYqaYZn=&3DeSqLZXsahqi=&RdBWaPVqnkrVl=&tgv2aJZcaVnik=&QLxZVuUinrVnf=&hQQOGFWanZfsc=&DiNDtBZbVaibo=&a8lMZQWc_rdjn=&MFYAdEVcZoZnr=&ACDqLlZXcpsqr=&oVoDjBZrWgqaf=&QqnyPcZVWnVXm=&C2fdlvXgcfZZc=&qDK4SeZrbYonV=&JEp_XtYoVh_lU=&tF_2X7WVWUXil=&g6z_dgYfZfmgd=&hZdGBSWWnr_pU=&6_8SSNUqajqdq=&EkMj76XYXalUo=&TCUP9WW_a_haa=&t2oLwmZUoeZdf=&UoopbOU_iUrsY=&Qb25pbZfahcsc=&ZV73DPYaqYa_l=&6BekgIWWmicsZ=&9IgqgJUhmnbpY=&smnZSTWUXrooY=&73swzUW_geY_a=&8tQkaGYlkanfW=&nPaFoOVr_djjb=&x2goXjXfkakel=&Dssl2YUX_frkl=&QvehDOVspcoYg=&bE9tnIVbbas_j=&yoQUWhYjciVY_=&JirQmKWo_hpqX=&_6GgOfYmkWfbd=&zjHtKRXclpUpg=&trNZduXbXWnYi=&SoMIllVlnpZeU=&sd5KANUVdmhYi=&s6maH2Zdcqjbk=&F9SuHtZrZmYer=&LGI2H5WflZkmj=&vJgwJFYiaieUb=&XPRkVjYVrmgfV=&w3bvKfUXVigsg=&JZDJRBXjdjdfZ=&SPr4r9UZcXgbU=&_TMK92ZhZommi=&yC9IMoXYrqcdW=&eFzx4lZsnemUi=&pn7DuFUkfrdYm=&uWpcaqWnjcWia=&_VHm72Xdci_fj=&bTllBiVe_ZYhl=&blexzAUVnpqsc=&Pai_UHVXlcden=&26JUppUolgYaf=&SoG4ZKXbegXmU=&29S3aoVpkVhgs=&sg92k9XXpgimp=&ABG2FZZslWhoe=&Fqvu4HXUpjacq=&zphLn_WiedgWf=&juorVHVUWinXU=&f6gSD5Zmemeqn=&J_uFphZdboplk=&IRsZBoVhkngrW=&7uZa2EVXUerpb=&ArmlMZVbWUdro=&aRu745YYeVrdq=&YRfHFJYZpclhi=&adQxNlYXl_qeh=&NS9arnVdabWVq=&UUayN3VjmsYld=&YoR8aYZifVcis=&8sMObTUsoroUp=&YIXHzsWemYaYe=&AsxNdSUVqkq_Z=&XvuW6pWekYsmj=&or9lThYfloYVq=&AZXjGTZWWmpsh=&2cohb_Zk_kqbo=&MoZYfSXgrahjh=&vDGqI6Willrfe=&axVV6xXrhlVgb=&3eEKelV_mpadh=&uloSoeWkgggbZ=&HM_p4OUkofqel=&y_ohSUY_jsbZb=&76NJkPWlibpjb=&flIV79ZYooV_W=&5igKQfWglVsXf=&dxJr2OZsdkoae=>opBnZ_jsisl=&uU_DyQUrmgZpd=&dOYbQGVcjUlaq=&Kyp4IuXsUgfsr=&jfOnV9ZjUrb_b=&hn8yMLUoqgcVc=&NJXcAxYib__fl=&V89ifiYpoejeW=&_AMfBDWZiZmca=&EGqXpwWmpoWnV=&Si5lMMXWqilVh=&rNBOoHUWjWoVr=&N_6hnlZe_Vdmf=&gTHQENWmlirYs=&jgNMqnZZjemWX=&RXXrORXqrVXmo=&pyRHvRYXhmbh_=&wHGCvPXm_mbpr=&NouNNQVeplnUi=&Kmm8HEZhmfhdg=&MQ7D_hWmc_aaf=&Rp8wL4YWbjomc=&LUV9N7Wnempfd=&wwtahGVgdlll_=&GI6inmYilmbli=&eUFdcEXdZpfek=&aQflTUWdhslfc=&yOKnxWVjgjnd_=&MyoQpjXgZhmZl=&oac6R5VsfrfsX=&nHjmg5Vnb_njV=&MtDGt5XVrcWgd=&DOva6mWVgUsUV=&UrbFjnVsYegno=&lF9_XIXeegmdq=&8EbaIlYemcWcW=&Q9reJxWX_nqqs=&qVglyeYhfbdcZ=&v9D4xZUVWVnXY=&63w399YlpUqhb=&KKYHX9UlXXnfY=&rQlL9zVj_VfVU=&qe8jz6VZcVjbk=&Gclpd4UWikgnU=&pi5h7QWjbYUmb=&MJHVUIUcVmpdr=&eB42XkWVkdgkd=&2lndAdVqXWZmZ=&lwwZnNUrjjZal=&3kVBYbXqVhqqr=&xeNAMqZikdlga=&xIKHKUWpknrjf=&QsY6VxUhoalbV=&LYIQxVVVkcaae=&VPydjAXiUcYYU=&ONoXOSYeaakah=&TWWLEmXZkboos=&HdDcCgZefjnga=&spYao2WXjhbfe=&ybmJ3dZVm_mZl=&ACVhSzWYW_Xbi=&fkapq3Zibcr_m=&VvP5fDVrrlccs=&sfDcnlUbZcshU=&kTYSSrVhpgb_b=&bNzjOMUcYhrfe=&jY3ihlWbXhlcU=&mv5qfKWnqUsXd=&6rnSiKX_Upkqe=&XvfcRdWZgdfkl=&UlAkGSXaZclYf=&W9jbAMUX_ZaXU=&OFCvexVoilrlm=&DDR9qkWbcUlXd=&xdzQvOVprjUob=&HOEJrjWriiffY=&XdeiPpUidjVYg=&LlBNkbVZYkhep=&ONBXIyZhgsanf=&fb6A27Zhegpjp=&LtXuWXXVgndXY=&nlG5uuYpfVmZZ=&optVXHVjkmYYc=&wfoLTsWdgegjs=&a_lBhKZhUUXjq=&HjdEY6UgWaopW=&LprMSWWeZiebW=&uazTjOVlnooYf=&i9AzvZVWldmdW=&OHWCr8XopsUfp=&BYkvJRXcjmZYq=&SsybgUUYVVffU=&lXb5VAXspkfeY=&kWiFYdWjYqkXf=&t8TZ4oZm_oamn=&DySqNcVsZlssq=&Tty_GIVgglfXj=&VSxjGaXpnVrZk=&kHQBcRVasgmoX=&28qJ4EZchaXYm=&kUbcHqWndqobe=&NgdIH7VZfZaa_=&j8dzv2ZmkmUke=&ITXUlNXrmjkfV=&DL3u27XUqbjYf=&SIaYNdZr_Xhgn=&smahgxWVhqsYZ=&R5BzgCZorkpXg=&OCNTFnWfslnmc=&qBZmUJYjib_ig=&U8rMshVpXaZYo=&dpTPbkYfdiVX_=&dbq5ytVa_eong=&NmcUAfUodUqbl=&fYtJE6ZlWsklc=&zPXONJUVcarXh=&QSdxI6UYUbUUn=&o7bwWQYjhdpVd=&ZBUTHXUVnnpXZ=&e8BVlSVombocj=&goiVYlZVoiiZi=&4ZFaakXsllgqj=&ICSsWWUgX_UbZ=&stXQ3nWlglqbZ=&IhI6kVYYbqmqd=&zk5KNQWfkVdhb=&UBA9jvZnaX_Wn=&vJi8_9UYanWn_=&AW8KOLYfeipUV=&DgOmUnWmZo_ss=&6dYgvBVkqYlYl=&N2yaeTUlgZp_n=&TipKU6Wn__dec=&klsWdqZsocfVi=&_wytfXYamhkkb=&AKPgxNU__nVVj=&hhDUhgZdsUjnZ=&og3KAAUal_sWm=&2PCPvsWiWfeWU=&ksnQo3WZbcUkc=&9O4DXyZiijgdn=&ewU_QEZikhcl_=&gfhffJY_frqVr=&BTPlhvUhijaYb=&OTRfbTYXrjsjs=&peWGD5ZqiUgXd=&pcLCpAZerdkjq=&eAzMkrZcppWfh=&ptRuepXephrZY=&IBbsFJWiYbcnn=&zjVcAnVXZaqhd=&ejGdH8WVZbqkm=&78vc4uZrhXmsW=&UbyuBpUWeseWs=&3IosxnXbUokrU=&plKHpoYrVjV_h=&7OrMOxYoijhch=&WKBswVWpcqoVl=&LOjskhZ_rgXkp=&KQ5DdYXoWhaWb=&oSrq4UZmeZjc_=&HQ4yAqUhYjVms=&TpzEsbZWmXjkY=&IohFcdVcVdo_j=&cyl2oJUiZosls=&yBvDkXYeWWpqk=&28Hi24WZmbcsk=&WxJGuhWWoVcZi=&gJmKtUYrdgXZZ=&AEM6K_YbdelWp=&cwt9gUUYmUcpZ=&qzPDLRZmZiUbl=&WnyJJkZqZkkee=&QIA4FmYmoWn_Y=&s2Q4ssUsbjW_j=&VA35lmXiXqaXi=&qjDrpyUaforan=&cd4lDFWdgkdhj=&9CAqLoZUheioU=&qYMPyIU_bXaYm=&xfhPzvWsYUdnn=&sumGVkXr_lifo=&hfuHGxVfUpahn=&GyxNNsYnpmgYk=&aWOu5vX_cbpVc=&mbWcqYXcsebnl=&5oeC9YVgfUqgh=&NdNwXqWWnhfjp=&Jw3tiOZ_lUcaZ=&xDDlBpXdeXhl_=&29y6Q5ZraeUqZ=&BS8tY8VgmYooc=&Hoz5CdWdm_jas=&oakqmvWYgUmrp=&uoDDobUWYXUXk=&GxcW9wZmZegk_=&LY3KelXrbnepW=&p_qhG3YZsbjoa=&S_hyZoWiUeeV_=&QBFsQ7XclYjkW=&xX5akIWVajVka=&EloMSyUekfpee=&HXYvtbXqaqh_U=&w8JEGeVdafkrn=&hSOEF4YsY_krp=&IQJfBaWYinlld=&CGLctuYiXXfrr=&2NVBxFUWigXjb=&maaLWeU_fahnr=&qNIiRaXcqXgrc=&7pPWLOWsqlcbs=&q93ciQZVcheZp=&3u_KzYVWc_kjc=&CgkWANXmbZcop=&b4ymReUflggXp=&MZxJgfYhVsZfp=&3XUBCuYmkrhar=&WfIQMeVqcljhk=&MnQiO_ZmZmddi=&73MYVlXedVcoc=&lwqg7oXgqfnmV=&8LfULCXhnaqgm=&YKXlMKVrqUafc=&UUv_8DXnnU_an=&heWuBaUariZZW=&PspDrDZokVoXl=&4Uo8jUYjZksWU=&aBLrVzUqqZalU=&L5NrcGUkjUVXn=&kNAwtyUnonsjg=&lCX7B8WqUgokn=&3HLVItWiqdiff=&gAHB3WZsbh_m_=&LQHV9YWgpshZr=&4jmSnqZXeadsb=&qfX58wYrpdppX=&5lGzuuV_UcWsW=&Yts867WfXlYbg=&Tsz5kqXlbeZkb=&cTZEtUZqoiigf=&4xvcc7UZrVWsd=&LnMxnLY_Zkhsg=&JVErT_ZnrYZih=&G5nswpYreYhnY=&PiETmzVYf_psn=&ZbEQz6ZXgZoam=&4DStgEXfpdldc=&5J4ZZfWqqdfqY=&h_dbH_Zirmgir=&VsmlUdYpWibjV=&Cxbum8Vfah_gl=&otgjThUZookqa=&cEx_KtWnicqUa=&scigOgXsjWUgZ=&Vv3I95Vhhpk_Z=&UgZ8BZUYrUcgm=&SrKPItXmesndb=&_BHDc9Zbilbjb=&6ALwSKVfdXrga=&2KwKEwYlYggeX=&njzPU5ZfUgfmq=&ukbyT6WqbhZXg=&_cEgLkWcgrVll=&64pdJ7VYZqXfa=&mjhmN8XbjXhi_=&jTDMItUqfgXli=&f4uEdAZZigprU=&4yFrsjXYmghqf=&9FzhY7Wmjbhjc=&FCUMRKXlpYljc=&syMB67XboVkhd=&aNqjECUedjdVf=&KqugVzYdZhrqn=&Kh2V9uVVUcgec=&DfeIbwYlXlYkn=&AvxCVnWllm_V_=&nbvx4OUdqVind=&E8DewtYiXlobb=&FSM_3bVqaiohd=&N5jmxfYsnoboZ=&yMJ5roUgXZmsp=&II6JhcVVajlms=&c5Gwn2ZirsahW=&3KV2BEUgljshV=&UEUHXWZighfpV=&kRF8GFYqophor=&ZiDeGGYlbhfro=&sIcBHrYnUWnln=&UNLDTBXncWeec=&7yTtswWfgdqpk=&fUWP76WjfmkVf=&Vu6qkPWgmWjZc=&AUOIjPV_Y_nXg=&Z4IWoUUoqYdag=&8J9vl9UWojkYa=&RGRF3zXmp_gpW=&LHWOSKVpZbfgi=&k5etT3XmsYfsZ=&csgGxqZeqXn_f=&L3f4pUUso_Zfn=&eqhcvGVZdXbdl=&p5Rgb7YXoohZZ=&W_SkO5Vbq_dka=&iMyoSdXjeVZsa=&LFpX2nZrccokl=&fDFdJsUfWXaYi=&hpOu5PYVbfobW=&XWh3poUphfUgn=&koWpGwYeoqXhe=&JdNKpEUcsjXbU=&oN7l5oVcgilfq=&fzhrZsUbcflnc=&3cnAXAYpqosdl=&bXJITKUfffrbg=&NrlUpiVkUlYre=&tuDSOCWkjYr_n=&l5QBF6Ubeqcsm=&Ngr4uhZmZjprm=&6nGERFUrp_Xia=&QtdUTsVde_Wpn=&wkSQZzWknosao=&DtsludXdicpmU=&NgUiiHWVZliao=&GoFFo5ZYVcboa=&xKJrmQYjqlcfh=&VZfGgcUfhoXpk=&MXijOUUUVqUas=&PxLtVNVkYdYgp=&mWZCraUWaboXh=&gFHVpgUoosafa=&or2bwkZZgdXY_=&MoOW9BUWUVecn=&I8SA8qWlYdWZs=&X5Ozr8UlZdpmf=&grdzMqWWmXVqe=&Cy4kaqVsdcffs=&gdyrA3VoYmddo=&6tJ8DMYgWjlko=&8dsRdWVeeaZbk=&sFxgpKZqZebkb=&bAvTc9Vhfk_pU=&dKHv4SZgWoXZU=&BYcr22U_qjejh=&UxLQn5Vhnnsbj=&_c6MyeWUgph__=&EosRfzWdVogaW=&P6NkOAUbneYYs=&ODoyMQXcbnlhp=&AEGLJEWh_qamm=&DDXbWiXipeWaf=&ZzqrISYZrrmib=&LGYrZOZjnlZWn=&9fSs93Yhoh_U_=&ICKY82Wingbaf=&Xb95PTXkgVlic=&mqhwZbYioZfkU=&_zA4hQUjpjfrl=&z2TJcJYWsqapZ=&yPhRR7Zhqkkfc=&BgVDVIYcnaV_f=&xTW3XRUW_Ubmo=&mw8wwoXVldZne=&apX4thYccfoaX=&Y3DckQWgkYnoX=&wlZcL3UssVYrY=&ED_BYnZ_krYfj=&wPkOxtVoreZfk=&hjsAUjWs_Xdsc=&Vn64JiYcqUaYU=&UrjFRrUYlU_ij=&uXWbdJZdfkkXj=&8N6XNlYgkekr_=&XsvTsIVpn_kV_=&2ZDRf4WoXagrj=&cE7Tm8WhZUfWa=&DZ8rPfXbspipn=&WQkEDcXeZacjh=&qnhVQgYoarUZg=&G864HsXUkYnUf=&lCCM8mUdpgmpY=&7FqzUwYWrVYXU=&UD5CehZgbZmgY=&bh6WVOZcZZeig=&KvDbZIWsZYZZm=&rivo44XbshVgZ=&jVgIFHZkanife=&dYIIwPWbnkiX_=&Dcs7WYXY_mqsp=&ugLGpYXqmgXep=&oYrsCSZrmprjh=&iTvXKqWqfcjpj=&_X3kWlXceYilb=&ntnUbkWrrfbkh=&7jSCVEVrpoXhW=&xmVmrmW_lleUY=&8FnhFjXols_kp=&hcJ6TpVdsflrd=&4d5S4oVUheZin=&rttbo3ZkpgihU=&6zLZdkWZosZpp=&e_iwj8UlZUpgY=&OyozRBVkspmVZ=&I_aDT5WeUrWjr=&jFMP6LXhamojf=&g4QDIrXmqbUbV=&OpTKatZoWdeUW=&o9Ts5VWfsWfn_=&iSN6gaWslsYiY=&aEubXzVlpmgqj=&Rw9yImXhfplqb=&63lwPYUq_cmki=&Q7LllzWUXekq_=&2LhzSRXeia_oZ=&xdSMrTZkYYbeV=&HaonqaWeXUYUi=&RItq9_Vqpjsnd=&d4Ew7KZejUqsh=&MogALhXUhkUpm=&dcMlBKUskXqql=&fMHs3wZYhrZXW=&TFAilYXrqjVdb=&Gn2WM5ZloUWcr=&QrFeYvWXhsZV_=&HdZ9PqYVqsUaa=&nJuxbrWkkspod=&FOOTNLUipkifr=&PTMWbfYVolsfY=&bDfAFIYmVfniY=&5B4zxkYaUdXfe=&w7SlIhWdVeimr=&tRZubkZeZofbX=&dyKbO8WWcsqXf=&BPGhM2WgUkbse=&ejNNSzUqhmeoq=&E7pKEpXnljf__=&naLHA_ViqYdWU=&oj3niwWdhYjqc=&WRq8q6XqhVYXg=&m7VLlaZlisZiZ=&o5YjzcUc_hefr=&RdPYlfZWcmjfr=&p37Jh5XUopim_=&DL_eOgUYbgZiX=&fDZANoUpsbYgX=&rSzx24WskZgpo=&7Vg9kdUo_UWda=&aLFq9oWp_mfkr=&Ge2HIgXpgrZaV=&Nj3ZBHUVWdVWr=&KgQzOrVhbbnrX=&84ycNrYVUWcUU=&irMeMbZZkkfkU=&vJAbErZek_hbU=&csseZqYbYkZeY=&8L3SUtZrWsrZi=&OHcX4KYkql_Ub=&3UMtmAXoin_nb=&NmjpLYVZkoafY=&qu9ZrhXnrVhqX=&_yVkGRZknllja=&oY_KD4WZolVU_=&BYc3rzYaXjofZ=&uh3hVbVYloboa=&EhdHJEXcWeaeY=&sNAJ4ZVcpsVpn=&ZY4N35Wqjhfip=&XB4ABMUikbYkY=&7M2SNVYekYUqo=&bhGOKQWXUm_ai=&XMH4TDXqXsYhn=&tG2_mTX_mYYni=&g_ZorwWZlo_Wj=&IBOur5XeZWgVU=&OTyQdtZYpnjWq=&KNSnn_ZciVsXd=&_baLqgZpXpidg=&IacN2_VrdmsUq=&LXdqqcXnZjbfo=&qeuLFCVYVVhda=&xFexoCVVcoYce=&PM5CP8ZkhVZYk=&7Hb8X2XhmWXb_=&6h6nZCXeVbYkX=&J9DXhvWjUdWnd=&cCZeIAVWWc__j=&WtT9rvUko_hnl=&dIKQiEXjZefld=&SmCirzWidlboi=&Fr2PUEWjheXjV=&cT53XbYZeVbmp=&KARVrEZsncXro=&dzTOtQXd_dpjs=&B9jmlBXYepWml=&7S_rOaYiXdVWX=&bpvNcMWgZacWU=&6GV9GmXXehdsf=&5XNZABUkgaWcf=&muhzVsVrYlVbl=&4Ps6kdUZYWlhq=&QCTsbmXnYkjcW=&JbEnFTZsZhfYc=&G_ELGBVa_ZYrs=&WtweVeYchXbdp=&WRUZrkWkq_fap=&JDDcohVjqjrX_=&CevVuqUaVXsfY=&DeemvFYhiqglo=&dobKgeUjXesVq=&H6_BhKVZmdUYm=&CSj5hiYZrVqWa=&To8IZMXYmsicZ=&KWufe7UmcfjVp=&YxqmDYUbfrfqn=&Anp6pIXspUejk=&aQQswTZlUdUrg=&GrQqxxUiskfdo=&dWs4ENYgVofog=&NL2PzzVdflnfb=&yjuDEtYhsZmpb=&JP_5hrUpVZlUh=&u3LmVOZrcXioe=&Ur_ljFUg_j_a_=&gsE6mqXnWarjs=&eMr2biZXXdesa=&rbSBATXbVmUog=&VlOFEKVhmUjgd=&C_EvqqWhWhoUo=&gAOCuRYqZUoV_=&cwCqBVUfdgbgi=&8lBpGHYUhbaoa=&VxbpfvVaYsVV_=&3ukdIwWpUpYfd=&hVDDB3UVlj__X=&WNyF4yZYXbroi=&jtx7kjVihg_qf=&IDiVVeYZsmVi_=&Www5OiZZ_Unnh=&_Rhf6iUnpkqVW=&muszcxWYmUnYs=&Gne7_dWl_njqc=&WDAR2EXfrXidZ=&aLPtRQWrhnpVo=&kXfmGUWkmobjZ=&3v7iVkVnbqfrW=&ysgH2eUdoknjo=&cw9HhcXlUbqmU=&ZinQ3LZmZhdce=&Gix6HHVcniloe=&vPvUPUYfXmd_U=&b_dOiMUalsqdl=&PHWxzaYr_r_cj=&RfTyCKYUagrmX=&uXFBKaXbUYWpV=&PnfyDMWopWkZb=&vXSC8FVVsokep=&Rp2Q3NWebamoa=&OavZLfVsqdg_r=&OUGYXvXUZYisV=&SxAxvGWZVpdjj=&OtYxeJYigXbac=&MxpvcrUmn_YWa=&4SnZiMYmgiqiW=&O4kDx_WdUcnfr=&_ikqmwXajmegb=&WRPdtgVqcfqgp=&FVzz2aVkUsl__=&aa8V6LXqknbnV=&kgx88DXpr_bch=&8hsbJdXbmrW_j=&MMGBGQWfoWnck=&B2uMbfUp_ohdm=&KSLSQYZWWfarn=&jW3rteYZcjYlr=&dHQbGCWnaajog=&pZ7_PuVijeV_h=&b8i8lqYgkUpZf=&LiMPl7Y_YoV_j=&9rVbl9Udda_Yr=&xNQLzwUgffZjj=&MD3CByZenobkm=&dCfx2AWarlYZ_=&sefGxxVrYWY_m=&jpK_NrUWeejYi=&rDS5pQYpeqUhe=&TrA2CFWXboliW=&zn6JzoUlessnW=&OTrZr5YokaaUj=&XJy9miZdYeYdi=&l7lTjcUZssben=&MQrYrIXoer_hi=&6KpmjWWXeYeqZ=&UzIqLcWdVgk_p=&_AJyL3UnlbkbX=&Wl3LzVXqVpWnn=&r3qEIpXqsiako=&jWiKI_YpfqdVs=&lJ7mtRWhlaXVp=&pIHYSzYdWk_nY=&24PmHfZZlUsr_=&W4Y99uWnqrcai=&QnBmR4UapgZr_=&ch5t6ZUoYcXjX=&iaZRXaZlVsVlX=&4tSeMoXUpkZdp=&NQFDoWWinVaso=&lrcqFGZVVZk_c=&Iuk8zsVgVgfYa=&MZ2zPhVmnrZqY=&6E_QdIVnqXoiY=&gEuzZlVqcqfXj=&lKWvKYZqXXeme=&nraJfIZogrXm_=&NgAguNWmghXn_=&OKt2D5YcfWndV=&HgxjpPVrUndYU=&micNv_ZsniUV_=&h79yhHZscsjks=&LaglRzZhlreVa=&_JVfPaZZdqqac=&7ozYAwWZrWUsm=&9j3jGUZdWdVsd=&pwWgszYdYjaZm=&ja2TcUUeclshs=&sGHI3RVWkUarj=&_kpOgjYdi_Xar=&UogSlPZmrgjfh=&7MzQvZUpVfcgZ=&aXqD_CYppaW_X=&h_759TWXilnaa=&gSKzPqUmrfdpn=&WixsYbXoUhbYq=&9yuuBYU_odXWo=&HXcSDlZdY_hZd=&an_UwxUqlhseh=&Z_r7PNVmkZajq=&mIEEjmWbrWeae=&3mesqVZsXYacc=&EZtHeqVhedWdm=&vBrnSkUnWYbcV=&rUSZyHXVlepWq=&NMRlCXWqXbqgb=&gmj2vCXckWqkf=&3Na3bEZfbpola=&bTD6BdZdlcn_r=&6TnjzUXffopZp=&r9PG_YWc__qlY=&jCzR3eVjjs_pk=&uYX3H6XbWqbhq=&uB4OheUVpmZcf=&rudx8kWpnmYWZ=&WJDBUiZndr_WY=&BsvsgLZVVnjpg=&hP_SUcX_sipUf=&7tlbjKYincgkW=&VIS_4gX_m__io=&vP4BNQZsqpoXf=&vHxwxiVajZWZZ=&JukGd9VkmbZbh=&CsHuVzUiYoasW=&_4widfZYbpb_m=&cOUbVpUYciXed=&j3TvizXmiXofq=&fMoTKcZjlql_f=&xfioCOZcgssYU=&VBCPW2XigUdcl=&O9dgfOYhUeqhf=&YVOsXyWpUrhdn=&pxHwi8YdVni_Y=&jIrassXjaYcra=&qLl9dEZhemio_=&yuadmyWfdZosn=&5PtcqzUoi_piV=&z358aEZofYsjY=&P_YqpXVajWeso=&5WCBdaXVeqlcY=&4qkdeyXiWWUbb=&j7Bwn4X_YesUW=&n8nxXHUVkpcop=&nnxS_eZXjbarb=&WP9_w8YepWUZr=&au7EosZjbjXZZ=&Zmcy_NYpWhamf=&SkKIyDVjiYWpX=&W6hPe2WjjolVp=&MKku2PWjakZhk=&4zfTwoVamjgqX=&csjvkAWjkhicV=&ewFmdzUXoXqqU=&93AzHtVVjVeZZ=&crnRJ6Uqgsbqp=&GRkpvMWhYUohg=&KAXxhhY_XjWiZ=&tFcSppWmYpmjf=&U8hXnpVkccgli=&Cn2JRmXajdjYj=&EABJDJZmmbnmk=&QBR5phZYkYpUX=&Kcdc3TXgekgoo=&8Nn8ylUVp_jUh=&gUqeSiWiqirpZ=&pYqi_DVbYZjgj=&Dt87Z8UdsXdUl=&AQBgPFWYiXmbk=&lXs2cVXhgglie=&hDm9L8Voafebi=&7cxVntYnYidfq=&RrQ9hcUfgWYsX=&ol_hcmUgjVqaX=&76ixueXZopiWi=&nk9fmiYdYgjfU=&JjbbvqUVfVVZj=&gW64_yZbekppp=&RFRZUUZWsYrdk=&wGvTwNW_srpi_=&8Ra3vJXimmqUo=&ZjoLt8XseregU=&xQrKbiVn_cfen=&A2YA7iWgfnesk=&737rItYgoWnnr=&rfJ5I_UhbaWXb=&huyX8MVsibbkZ=&S3Wd3pYkiYUdU=&IwegihVVchqb_=&DU9uOHZimXhUg=&m_UKLrUlsbenW=&CJK2BtWmYjkpf=&aHuFNtZqZdXjk=&Tax4kcUf_ZXcr=&jxtrArVg_VmYk=&QEhdo2XsXgYki=&Sd5W5YYYrbjh_=&2JcmOhWaWkhhs=&XMVpLjXUgVZpi=&QDgYmDXmeUXfi=&pGQGoNWlUcbsZ=&CJq9odZqcrnUk=&CZgAgDWhakdnm=&CA6K8xVminleb=&SwP2ZLXfjhUqZ=&NCrDp4YolUjYs=&xIQrEAXUXrkpd=&5TJSlpXbV_aqi=&uzzWwOVW_bk_l=&Kcg8vIX_gVbU_=&LBHxX3UVikhsi=&Zrdk7RZjlnhUs=&Kt2hkBVsqUZaX=&5dKOGXXValpne=&ENrryyYgrUkaj=&FwwDFDXsUjfXX=&vZ8757ZdnXgYe=&ihIWyZXsXdfen=&T7k8VGXXrYnWk=&9NtZ2oZWgckmm=&CE4fYtZhUmciU=&PsxRfDUk_fagX=&UrmWEiVZpZXZU=&Xq93FvVWddcje=&gWPAzNVsWoljb=&tAguqTXfcpVfc=&KuZpkTUpUWeid=&kCT_sSVjrmjoq=&EJcdqrXVgVsUp=&Ryq7kzUhsdXkm=&KPyE9RZYjlmjb=&nBpciLUfjiikV=&MEdcoTYslgnnk=&NmFG9pYkmUblU=&jvb5mXZdWkshW=&m_5f4bVqqgjm_=&TQobpBWWgVgjn=&TcFfjjZhahoap=&dAS2viXnrkgrc=&VJWhDnXXUUerV=&8zqterYVqZ_cV=&M55VnrXZq_VWX=&j8PnhSYnolWeq=&_UuoBaZrbkmhe=&gSjuBMXUglZUY=&oR94ogUeqYffh=&KpQdbbWiXekek=&_gtWuvUerbVcs=&xAvGwBUVcdVVa=&qfUocwWeUmZcl=&zSTjg6ZajbssW=&9OVposWecbren=&ncJ4ToZUh_clo=&Eb_AD8VXnZae_=&4VpJu9Unggscc=&VOGJFxZoUsgVj=&RFdbBMZnWlsXe=&PSaejhWWooniZ=&525AzAUa_mhhd=&BsxJG7ZXadsWr=&HCt33bVegnclb=&7PBAK_Xpgeqal=&JIDHY8ZksVclY=&aX7_wUXlhYVqW=&cz5aH6YgWVfse=&qSqFCiZeingUU=&rCnS58Yrkhmc_=&oUbmLTXjmWmik=&nqiy4xXUlfesV=&wvlAqGVhcX_fr=&CZHBnbVphqdsq=&r7YFVOWjoepki=&Iu8JyLZpiUZWj=&4gABj9YoWinh_=&9eNBOPZepdljX=&HlCGT5XYVWooe=&LJw8A3YUXsphZ=&wJZ8anZghYdoa=&6W79MrX__ZXs_=&2Z92pKVqcXlsm=&iiTN7KVarZUdj=&mvCN8CXedm_Wg=&FIXibQWXVih_h=&YNw8qkU_kbjXY=&pChTjJWVekmn_=&ptJWRzYhprsUf=&qPvuSpVmc_iji=&m73OngUblmllg=&TZolDNZrlpbde=&UZ6GKoVeYUsdp=&JoDdKXWZ_WcrV=&iFVTlpXgrjhkc=&OPvRnyZgbbddo=&BuPVXCUcXs_pX=&cqvkAzVgjalVh=&jDIyGpWjjboir=&JxsiQeVfYqiqb=&Jb8vNOWjfYdfY=&zOZIZQXql_rra=&aVnzoVVdlWXgj=&PQ7OT_VdXoaUW=&CxtkheUYmUXh_=&mhWEViVdmjnsf=&s9vozbUWcXkmZ=&3KyLYUZelYUbf=&7nglFQYdUlckk=&xH8XQPYilZUpb=&JUnuCVYrmaomj=&5dmttTUeZekjj=&EbSrZkUWegrWp=&c2Tj3dYmasVYY=&7VnYYgXlaqdUg=&ERdOvqVkhhhWq=&hAxRNlYiUldbp=&PMmQgkZsmbbVa=&FlYVJ6XnVfVoh=&fZGQf7Uhl_eZd=&Z4vdwMZpZjncs=&C3B5uTUajgYeq=&gPE_WbWhdniga=&XgIkKbYoUibbl=&AxpbUdZqUYcYc=&TprAHIWlfgsen=&lxqKU6ZlajXUY=&FECtOKXbdkYrp=&PvHBxDXrpeilX=&x6gGClUimne_p=&eLqHtvYjnejbZ=&mpgV_mXbZrfqg=&eoKvkZXaWqdb_=&K4iaAxWYUbhha=&TfVKEmXgcrinl=&27ujVrVisnXsY=&zeW3oRVfVfn_U=&ksxhMgV_encoj=&s7gvMOY_UqZXo=&aFT3uOUYjiZhi=&erAtvbXcjkghs=&edUNIWVbWngie=&NhrNZkXlYcWjr=&66eBZEU__iphn=&5TekdTUcdUcmX=&WNwN5wXs_sjUd=&TMY3UpUnXpbWn=&LbhTCWViliiof=&U6VrknXUiYsbV=&IpmuQDYcakUfa=&WX6Z84VfndhWp=&RnmSBBWhYqaqU=&VsTgfQZkasmgr=&yRJx2hYfdgqdZ=&vdoHWcUaYikge=&iF83TvUkegWmb=&Hcpj7wVlWefcp=&TkVyCeZ__f_VY=&qEBcaRUpohmfm=&bgtWgYZmXaUrm=&v49Zw4Vapmhpf=&VFW5_KYmkfXZe=&3_Pd4WUdoklmi=&RFtUKAYhdqXpY=&tvsCKNVerYqbV=&JnMLbIYan_sYc=&2sJggeYWkgUkf=&awIMStXsgnaka=&iBl8BNYakqmiU=&h28byaYcobXhc=&vASVfHVgWgjjk=&83LIYNUaeeZqj=&5IyVe4VYsZola=&sBdKGzVmUafXX=&BXUE3zVpjdfXm=&SUAqyNWqXdcgk=&gyIKqEXlnlXWs=&cKD7xHWrbbrbp=&ja8rqNXdlWWYa=&odDeKaXaXjclj=&AfQy_GXrphoZl=&yfxMigUnmbjWU=&Bqku7fYVrXk_Y=&gVcTGsXlsZord=&GFIhgpXo_ofqs=&wa7gMiWnmsZre=&GdF_W6UY_bhUc=&tfQCaaUgfkZgb=&4q3yw_VsedocU=&o8aabhXqmocop=&D9Yv8pWgfbVlf=&magnNaYjnbfgn=&tHPv5NZdWlkrs=&agyNgAWhirnXs=&wMO2qOWbbcXgl=&etrgyKZgqcocc=&jFgiUkVYinhYg=&3h8mx4Yrjpnpa=&jWCbPpZolraii=&lgWwnTUpajqWe=&74TnaLUsdnaad=&XCFe4NYm_aZsm=&koMVyEY_bZklr=&XAqsqFWpfVpcV=&dZBVOlYfshhd_=&msGwYEWYnhfdV=&LipaWkVnhrjpd=&ANIEAHXmefrhV=&IQmFMPZfjhbio=&lKO6wPZaWcecj=&3XyLrmWgbeVoY=&43E8i8XjiWbZs=&6dXJFvVeVjnon=&Hi4D8VUkd_WUX=&Gx2BUOXhWarVs=&UiytHGYcbgoiq=&IZ3F5dVqnhWep=&BRLlOqYrpgj_q=&yNzbTnUVrVjmY=&pt6dq8UWUqWYs=&jarDcqXnqVkab=&8VNhg8UdnsrsX=&9SgY7YWZUlVs_=&HmhVbtUehd_Zf=&WseAiGYfmafYd=&S_AFt2WoffkbX=&uY_DqiYjsYqkl=&kzuz7nWgblkk_=&Q5vWPYX_rj_ai=&FmS6eTYjkleff=&SLWkcaYUsWalp=&p69g9eWYapf_d=&YkOnihXmqVUZi=&UtwIApZnnUYrn=&g_CPW9ZnsddVX=&lvmlxSZWWrlXb=&CvqwBVW_YlZmU=&7svH_wWbrYX_Y=&wenoUrWjfWghk=&c6IhVtVsmolpm=&yoVTTpWcWcZem=&FPnPh8YhUijiX=&UIHjVfZsnZdhi=&hxMkKQUlWigo_=&WwYfosUnZjbYk=&k2ci2DVgdfdhp=&9CipOGVWXedjW=&t8PQFBYfmnmnj=&_boTHJYgiijmU=&bwiGUFWdVc_Yr=&X_qZghWiUXVcm=&mdOWRvYgfUUgl=&SOHaM_WkbbrsV=&Z3AqN8YdoVhne=&2DrBxKUUhddsZ=&tAo96FZlermXk=&V9FMKaYrgii_k=&yfWRPXUlseoei=&rCGx5SWYjdWcb=&HKjGCtVYhVYsV=&X46zmpY_gXbeW=&T3njjfZfUsbVo=&TIiRmBZhqpajc=&QXnkH8Zrspahj=&GvF88MVfkhdrk=&WzwBB9WnUXYpp=&rO4IBcYiaVYf_=&UtyKAGXkgXfjY=&YaTB48Vhmidom=&MbHDRzVrcmsfl=&FBi4ioUdgjmZf=&jKVH5fYsXrihq=&DJlqekXbrdlXs=&QkAL4NU_pjZmp=&oXsFbfYhgsnho=&MfomhWYedUdsl=&PS2aZhYXnZdfg=&9yCEKzVkVgVpk=&KHgKazXYgkhar=&FGOOFLXmiclko=&JJcrceYnbdWYd=&TSDOetWoooUXn=&Y4n7dEYmgcg_g=&2p5c9KUljWpeq=&Weyhr_WlUoceU=&x8yp6PVncjZeU=&A8OKdYZYWYilf=&8HjytRYerZsld=&E37gN9WZfgZUb=&SqaCyXYllmbal=&B3c7cuYg_nUmf=&4PqEUAYUZhgkd=&gV6LR3UpnYVgW=&vS5L2RYVbafko=&VSgeu2Y_Wn_gW=&3vBlA4Wpbllsd=&_fzlxkViVaeVU=&qnsRN8ZrjUchh=&BTirOjZpXYnha=&Auw3HwYaZZapp=&bfhgC9XkgUqjm=&NNswu7VdrXmoV=&luM_mKXbjaoZ_=&k7bCuzVcrVleV=&4Nt7OJVfnh_gd=&ZZIMwEWXoUrgh=&hjEWYUWnYsZrs=&QhDhQAUolXgbf=&F_9lQJXUqjmoW=&fVER4JXbbjrWd=&33r6OxWeVapYi=&A48SVeUmalYVW=&acTkwgXslcnoV=&oaTVkWVfcgZUi=&_tdWOSZso_Wrj=&6eksZFYocWnle=&YkWqTzZc_fqhs=&FdMxcPWfrWpaU=&Hn8QiTXaVmXkW=&mwcETJWspqdmb=&IrflF2Urekn_i=&EEAOQbXUXfjoi=&Q8b34xVWnjoqU=&cHdY_9VUbdkim=&3oiXj6XYikomr=&6UTk8SYaks_ie=&wMLrImUnacmYa=&UtRpoQWZUkZXp=&tlF5JvWbVZkeV=&uEAWwwXfahhhU=&VYPAOzZsaXWYk=&bK8XHhYWognhs=&n_v_pgWkebk_p=&qvqADvUVabbVW=&xmrPwuXeiUlog=&bSQVjTVqfqnas=&r8FJlvZm_konl=&GcPhppXXVYVql=&aqwb9_XngmijX=&87CjJ2XigWklj=&4I3TjyY_lqkkj=&GgjCXjUZsUfag=&jnaI4RVekripa=&VnvciKU_nfosg=&gxbW6lZhdWYca=&4GO2htVckjqsj=&ATvE5mVmUZecn=&LhsXqTWeoVZZs=&qq5UunYVmiqrm=&QcL27pZllrndY=&xdC2rxXXcresX=&jlGFVTYYs_ljc=&RMRSdzXsYsmVj=&qM9x5qZVlekZU=&UAIUuLWfpoXsr=&PnedBwVg_UhVa=&lXrdVXVhhlkqV=&Bg3CTHXpVdUrf=&u5csCTZV_fmhY=&jxrNsEZesoral=&TLPtlaZinXV_m=&bAlHqFVWX_dVd=&usxzxlYXgYZbg=&k549qcVdqValY=&C7EpYwYeVdcdr=&QGwdsoYjWgmWd=&E9Fkp_Wshiioe=&6g76mHWnUYsan=&FHERkSWXjigbl=&kxioIOZrUYjrW=&KPyQBnZUqXZhs=&8IJme8VUcrcfr=&AC23gLUZakeco=<gPUrYpYqh_n=&7MYWEzZVaXsVY=&tuExsDWUsmiYg=&K_k4J9V_flak_=&bomuLXWYXkrdb=&Kgis24UVjs_lY=&SfmLLUUYZrnWZ=&LxWmmLYYVpjfq=&X7vHGhWigbUVZ=&9sMoERViojUfb=&ujyX5AZsdjgqc=&uvpOdLUWXffUa=&oK2mMNYVnZbXq=&XyWwEyYpYmWVY=&ZoeerVWslWqhq=&fUnnWXVWadWXo=&MPGcqaZdZcjVh=&sxcHSpVbaV_WZ=&fLzzE9ZZWacrm=&dZO4O_Z_llVoc=&Mg49CuUclXYjV=&VaAEUWXVdYngW=&ddq4ANUZbVaeg=&_zKgHqVUlin_g=&Xw_C5YVaWfUpV=&KAPmSWUdii_pq=&3F74DsWlqdZoV=&FYTlm3VVoelqf=&niSugzZc___Vj=&7_FiDuYlg_jkb=&6FBMCIUjobkYq=&zNp9PCXnUakYZ=&WMcNpvXcqhpYl=&EY7qfPWfrZkUs=&Ydtm84YahVebm=&TkbprnYVkYsZm=&yOOA_VYXfZoXU=&3FPklQZjnYchm=&366lGwYVeks_r=&9MQRXRYUesoqU=&fhHMBWXqkgppk=&YmPDnAZfnp_hl=&TlFdEVVinaZWd=&DQ7O9uZmksdfX=&A83gegVlsleXi=&RleejQXshjphp=&WYVvYhXhlr_ln=&8zewoDYUebeja=&oTHyDFXmWdmZa=&zDjlTBYnrXZZo=&DhpBcBZccjkcW=&I8SzFXZomVsmZ=&ZGJJIxVYkWahl=&m2wYcMU_hoUX_=&FbcpZ8Voadeg_=&9XIfUoUZhbpba=&jNzR97ZoljgYY=&zdMad9Xmsrjqh=&RHpR54Z_ahsoY=&tbeYSwXor_Zis=&CbuMnSWlZgpYa=&BHGaMXZUXdesZ=&XvapMAZWlgkfn=&qyQMe8ZbpUZVZ=&hDeRJOUUkciUl=&eXT6yUZfbqaaf=&mktIESVdi_Vbk=&zDEqORZfkcem_=&b7CvkXXXcpoWd=&ylCTYWY_dndem=&ZbyuvZUn_dkYn=&BrQGzTVfrs_Wc=&UmqNOAUcghcer=&twl23AXilUnkh=&QN7NTNVelpnbo=&oKPr_sUpUbkbk=&fUMQzVXVcdfoq=&lA2zabYUe_cVa=&X_9dl6YjZdZ_V=&iEayqXYbZ__UY=&TfDbszVjYgkbj=&ShyrYNUZldmfs=&JA7kPzYrVfVoq=&IQrHz7WUcoeUo=&OXXx2CXjljYfq=&kw2hM7VjWbmaY=&qRjuy8UUheZgo=&dmNxXdYlnmcpX=&dP4IeyXljqksr=&7pLw3EYgWbZgV=&FhP39wUVfek_q=&_C95LfUqransd=&XO8v7FZXgsjsq=&RPCO4qXdhjsqm=&ll_YhtWafYlar=&zI6H5OUglmZcq=&ARioAtUfoZofW=&nGAquIVUkbgek=&9OTD6tV_sphie=&2rUDo3WfjjeUl=&ZQ4rKQZrfeoro=&_aWjkZZkchqUX=&APNeSNWUrnmnV=&JRANgoWc_oYnh=&IkaGW4Yilqkhq=&engEnvZ_hiYlb=&HzKaaZVVrlWfd=&yfVSFqWXZcgVh=&wAZujHWVpkUnp=&6wnhbNVhYYgdp=&zXIF3jXfZ_jZo=&SlyhgPWhXfokf=>OkXKXdfqsic=&veU6WuZVn_plq=&mOtdpsWanWpoa=&uG7vQeZqbsX_n=&bneW7LXmcbXoX=&TXX58hWinoZcg=&eKkeWWZmWfdkc=&65KeZOXjjoepj=&hzVAf9ZUnhpjY=&GvV94EXVZUWWV=&qMxONaWhWkZbm=&Hdd9P7WjmcnZg=&E8NUBEUpUcY_f=&5dRvRsYq_pYpn=&6tzk4sZofVhej=&Pn5LCmXVVVUqs=&vXEL47ZjjWnpe=&Jilm78Vijlsmj=&R5sMebZsXpdkl=&eOuHE3Yif_Usl=&sMYsmCWmVXZfh=&arZUrbXpadmdh=&iPTRTEYZqinXs=&HGrX9iXfjZmaa=&WEUuoeVliXnj_=&dqNnZ5VfYhpUf=&PjG8T3ZWoc_Vl=&2yYW32UWrepsV=&jZsWEKUanYWYm=&Dfqw8EXdUofZi=&NdPmy4WZjqpbd=&qXhi38YlUYYkp=&q2SrxUYqhbeUY=&VyrfRDVmUVsem=&hPeBg4ZZoihfd=&JhGt29XakiqVX=&V9JDneVplXflZ=&EWAnSgVdhiaoj=&KUz3cpYpgnXiY=&3gaKIpWfVhndV=&BdEfH9ZXrVode=&XZl8_OYUWmllj=&FJbJnPXUkjfUs=&MT4p8LUrVeqYe=&DWrSmlWVXmXXa=&CZtDXhZmm_slo=&fubS2zXWigbYV=&eJn56aVhhheUs=&v4nomjVdXpaVq=&a3VeVjXdlpcYU=&jNXPUFWolWsmd=&H3cpmpUsgcfV_=&KUvkaTWUqjZpY=&vP5SuuVYsmXsj=&7xCMf5YkZZqqf=&uXVokHZZhoXhj=&hSjADnXjgqkh_=&Kl8CsBYVgXksk=&EqNarxWeZhieW=&YcUL5bWfpbosm=&LdNhmQWWlWmWe=&TgkeAhUZYjnVl=&igZUFlZ_ndjfp=&ALPVMxZbasUoj=&VyzsXrUnYhhjZ=&CLGmGRWYXqohh=&bBNbZbXnZefqb=&Mm6N8fUnsZXnV=&ywUZR3ZUWdcmp=&nWPItCUqdnlmr=&ZP4Nq6WkYUhja=&hGxSjaZZoopje=&sgwa4uVZfcZjj=&9axK6CYoijrah=&2zgGS8UkVUXei=&2Y39j4ZVighUX=&WRnIypZhkmr_d=&owOs4wXjr_asZ=&vZZZEuWhUdpge=&sBuYdDVYagaZo=&RmnNilUhfUYop=&5ALtIjVgebbpk=&EdfOhTWfackXl=&BQxQ2TXnrkrpq=&5ylIiPUakhpWr=&MEWJSDUljeoha=&Ck97h3XYYefhZ=&rogLEUWUomffh=&m__crMWZWqals=&QypKjOWoafg_W=&AEz8D2Zfcj_nl=&FjjX9TXderisj=&zyjmlaYjsdorV=&SYYbIBWbkrUWV=&tenVujYcZUopn=&ukSRnDXpeUWWm=&LGTkP9W_nZWcU=&fLk9MRUZqXrVc=&HzW7fbZjdlZio=&UoUt9JZfhrjXh=&LPhrOYWaficc_=&LXN9oHZd_ffsh=&3YpwEpWjUccjZ=&U2snW9XmihoXq=&RzPDvLUprYkUX=&4nQJyqWXopmsm=&HslGtZZVccjXp=&pNxvRaYadfWXp=&iawkSBYeooUfr=&frmY6nZghXZZg=&qpGVuTYn_pqYU=&mBJl2mUXrk_bk=&66VexTYdrY_Wo=&zMbxASUZegVsY=&Co5sW4ZUpkdqd=&X62fq4V_mVn_r=&RcHMc_ZseUUqq=&mA4Hk6WceUqaY=&vdQbL9UhpqfVj=&IKsMPJYYqVjep=&rmqdbKYrcfqlh=&cTiA9lZgcqZVm=&EGCBJ6XbikhmX=&KqfY2RUbqVppe=&r65bt2ZnYdhgg=&heU77YUYdYnY_=&tSPcAJWrVgksi=&b5OKNoZpqqkaV=&_QrLybZrs_nhm=&SYZIgYU_jrpdg=&o_9zwRXqrYbhl=&AEZoBdZfXYWmX=&NmrbeSYaVbcjr=&LyYRI4YqWjlmW=&5OkordVhpsqZh=&DtuCLMXjhZWrX=&MmT8fzYiXrfZp=&EumWYJZXm_XXU=&8b2GxoVkcpVqm=&8SBEgXWo_YWhl=&hgQakXWcVfofi=&Oi4eQFZfkYokp=&PKN62IWnonhgi=&hr7zurUdVVocg=&kxFU9sZWnmlUU=&8bpKHZXpYhkWd=&eJjTH8VbYfZWo=&7USgUKYU_WpoU=&uhFKcNWZXWhh_=&bLOFdbYUqrWqp=&BUdKxZZXXjYZg=&QQmABvWVUoiXj=&ozkvOhYkgjdhb=&EqmBpdVjUVnWm=&jmA4JzYrrdXfY=&wFMuthZYUfrfi=&HXsRx9VlWdUia=&h4dc54YigVZen=&QeSg3TZhgXZai=&uLw6hpZdd_qdp=&heVa6MXrmh_fU=&iXMnQUZqdVlnY=&9ePGPWXnlmbqj=&jel2DGVh_ZYdV=&6dxxDwWjpogsY=&85LrYnYbZgpXp=&FTXaVdYkgjWVs=&R5ioCHYXZpoZh=&gxMonMXUYVhXV=&2psH5HVqccVrW=&p9G4uWXqXYfbh=&N8lI4UWUUWiWp=&rO4boXWcXYrpY=&npliMRZamnle_=&KhI6b3VsYneWY=&5GeaBnZijnYkY=&tgqQtSXoqabYj=&yDrhWaXlmibpc=&3q7hCVUUripmp=&QZPqPKWirUYd_=&lY7OX5XapjYjp=&Thq7e_Zoml_cf=&AYKYtaWeaae_U=&3exlOgY_elgUs=&r6QDLJYjiogpo=&CQoTLJVXpWbrd=&Mgzf4uUhljpWY=&7Xq_OgZUgsXqa=&soUFQhYr_ZVea=&7d8hTEZeZoooh=&sTWv8pUcqisZ_=&Hu_bg5Vf_kpfj=&sWIvEbVcfY_Yb=&QejXURVWUejXX=&5hFm9gXqkrUer=&k_jQkuYaohWdm=&kL3ajrUUXZ_pd=&kmiRIXWmlZVgi=&WuWFU4WibqaqW=&ndmPZUYpWrVfp=&AnUzxlXpleZaX=&w76WqsXnabdYi=&nGQREcXffrokh=&4GaZnVVli_pkU=&UaHCsVWWbWWnp=&umykIOXhkecqb=&LmUzAPXpaecbj=&GWlynfXbbpjjg=&XZoZ2JXebdolk=&65H5JCWZadbUX=&W7Wf5QXXbqXYU=&VUhTkaUrYjfgj=&dnKxqnUmcof_k=&mVQfHOWcjXjgV=&NmeJqfXbdcUip=&AygCRVWVihahW=&UYagzrVlXYnbg=&AUGvtWVkXWZe_=&hoPqhYYamsaee=&f44lj8YVhXYce=&LmgKbMVaZerWe=&CXw2PAZf_pobk=&6cAnS5VVZcsWc=&HQCKuJYpXmbhr=&28WUsWYiicVcY=&NanUEEZpVdUWZ=&ihPsDTZhZpeXc=&TVWcaaVpsYWqb=&D8Vg6gWXaasa_=&mQqJYqZbrkVic=&hj3SNtXZndl_m=&qtYowhV_bbjeh=&bYtgzUYionXWm=&pOJlrjYmjaWho=&P3t2nxZnYggqq=&yx_AtmXreYmqf=&52Xp7PWpWsmZj=&VPRMV7UXloooV=&2obfWQVibUbZs=&eW5iUqYskajjl=&bWkW4JWgVjebr=&XPOkdQXUXYdsh=&p8njiJYXfVhpV=&x6y4XTVncffko=&yDvMteXoijrsf=&kL9XoMVVgYgUX=&p5F7hNYUYgrcq=&VNysBvZhVilaV=&42EuU5VoqZcls=&kviS8zVrbgapa=&wPMl6SXlhq_iV=&saGRbDY_eUgqU=&6QsEuxYbskUbX=&W4JMauZXnf_fk=&PWXAcHYenbjns=&DLxSxXYosaXoX=&RmT8mVYYbkbnW=&xUYz2YZsnqZef=&5KKLU3Uk_dWqd=&Jhz5ObXeWZ_Vm=&BV6Y47UUjZhc_=&85AwwFVqffdcV=&YJpvWzU_kbVsr=&ZRWmw6UbYWrYY=&_Fn5OTYWfsh_o=&tP_fWGWnpXgsX=&de8ljkVUUnVVh=&GvuGM8UZXbdUf=&GXqcBxYfi_iXe=&gsavKgZjs_mek=&PQKOcZUWcnfjg=&SGLQCoZVgsilj=&dBMca7YfqppUU=&VwrKAuZgYVeZg=&eDOTVwWboolki=&kItgWkVrlrUfr=&gUAIYYUssnZWf=&qkRGXhXg_UZrV=&v5lqSeWsqmlVr=&y2hq4ZXZnrhii=&grap5wZkjfasU=&ZtdvGoWoWjjds=&EQ7t2nYYXennl=&aVGi9MZegnVbc=&yPartPYZmnWaj=&N42HuhYZofphY=&BH3CMBVWXihgV=&WAYyneYcVhdbU=&d6n8zeYoYqkrV=&mUa4llVgdbWr_=&Ygc7sFXj_gUma=&6mY9yTYfakcrr=&NWCbSwXdYkYep=&JXXi5vVckjYXe=&2yNRsUYbrea_a=&94CvojVdlkdeq=&hDuFCmUYgrmpc=&yZn4_lYjZXiaU=&ZzdABSVYqsiko=&xnYxaKYYaYd_l=&aaoUEBUkWaUai=&MqNgVhZWkgro_=&UVyPEuYblmUlc=&baoDhLUe_gaZc=&HtXqijWYmnggc=&n5Mw_TVfopmnr=&l2no8KYhrhjUd=&bH75cJWZmZXZW=&K7I9G6WXjWf_l=&Gdn7BLUnbdjlg=&2vGF9vXesZgnU=&w6uJ7fWZcbVcl=&Sct4_vWjW_Yad=&SsfbpgWkZVpiV=&zEkTBzYmjWmic=&_7ZKiZWYWVdYj=&sUpZnvWgkhpep=&QhT9fhXfXkXXY=&SyIsawVWVsipe=&kAqNIDZkWWqpX=&K7HRJDXglWWr_=&8RS2AnYfeUfXo=&2dN96vVindXfn=&2XiZtqXVqpelr=&OaFmiLYhXbasa=&GgEW3VUWqefYX=&QyJq5mYgmpomp=<maKlWe_WUgo=&SaBaBaZZiUnlp=&9DV3fGZcbiVXU=&cGhETbXenUjqd=&DSlP_xZcpbcge=&sz7bw_ZYkVdmg=&hGGE5PWelrYdq=&Iu8NUwXp_ViqU=&NXSFVqXpZdjU_=&tR5VqpWeq_gVc=&eAN_G_UeVlqdX=&IRiV38YkedWbq=&WxFFMHYZkWirl=&z5XcjuU_icgqY=&8valPJVarmcqq=&NfRcdSVkWdinY=&lBm4FJXZlYiVW=&gCNcjIYrbikVU=&GJZ_CJXXpcqXc=&Bf6AN4WnjaUdl=&aYIF3PWiUnasi=&kAgR8cWYqqiZY=&GWdBWLXcgZren=&dX4lXFVlbgVf_=&lsUMV8VfnlXqb=&Y5vEWzYjihhWg=&CVGIXRXYWqk_X=&weey_OXZrfkXo=&iZCz43UgWlZjX=&OtM2y4UahXiWi=&b_cB5jWVZggrb=&Nn8TLYUWZY_fk=&pBagKCUq_ieoZ=&MfzmE5Wqqllnm=&mfwET5UWpfZmm=&DfT_5kXqUgoXq=&KSwt75ZpXpnfc=&wShk9iV_UZj_l=&7qXBfoYdoi_cp=&gAyAiUVXYjUkq=&nXHTxCYnrcVcn=&BocmraZVjVsbW=&YId6tOXpmqcjZ=&Qjq7ywXUkYlaW=&fMgrz9Yroro_W=&Cd3vGYYcdUlon=<v_ZtUZjjjZZ=&dgKpzLWokpVhc=&YVNExuUmUbqVU=&RlcP2EVgaia_k=&yo5rbhVUhofna=&9uIh9gXdWaame=&bzvxtkUibodiq=&J9u46mYqi_Wqg=&CgpoWVYlkrXsq=&u3yi3UXbebX_X=&NpeyVLYhkbYpc=&TezqzrYX_iZmV=&AKIiJ5Yqkimia=&M6rlpJZrf_rnd=&JEv_ypUXYqoUV=&JfEulQXXdsUsX=&g2ZWlMZqghgbV=&nQCS3yUgbXesi=&6RJEeuZqUmnce=&Dk6cBOUgWailZ=&eEJyWDZlohngZ=&rvKlZpYVqlgbh=&ugLZtUYmZVerX=&PqEYapZsUYlra=&jiCSdkWWdZWfU=&NpuYkZVijeXns=&RhAWLWUp_oXmq=&kcYTDOXshVopb=&BxLzQOZhaZaoq=&VIFtSlZrggUja=&W8XPpuVZoYVYi=&I876PMZXhqhlp=&jdPMP3ZWlqs_b=&j2t9DgWigrUVh=&8BrQcyXZg_dfU=&GQAZenWZWnlUi=&PU7J3tWic_dkh=&xXTu6iYqnjqUf=&IZtnNzYqihWsd=&fhv5WQZrjjfip=&KDhtyVXksgsYi=&7wNBZNYa_klgq=&__3PzcXYncbqe=&Q4VR5vYkaaefm=&UeFmdhXlibUUb=&ppZ6FYWqjYafW=&HmMjopXsefXjk=&ZUatlAVs_YaZm=&R825OpYalUgao=&MRzpstZdmssbU=&uGq87NZVgWnW_=&SKIR8EUhZrZaZ=&zak7P5Xbs_apW=&ffnLBWXdislVm=&OF_asHWcXnZgW=&YUXcCfWfackis=&GRZ7fzYUVcVhq=&wLpw3IYVsjXbj=&_4QSqLZjnfr_a=&NLfGynZ_dirbh=&fj_sDtUqVYig_=&8LuY22UnXpfVs=&nL_LNeUjoZaXs=&lkDLQWXdicXeZ=&wdo37ZVnWofqi=&uQEQWJWlZjXWY=&dcTV2NZjcWjhY=&diXmzyWlsWfms=&5duAKQUakVdhV=&mWaYzQXqfsdeZ=&FofNiYWrshekq=&wwGcNPUUWhXpa=&4OWG4kUjZbVeh=&SRpTduVlmcpmW=&RWoeHqViplpda=&fTw79dYpYWpUm=&4E_Ml2XiqVsgi=&4m5LHBVbeYisn=&Ki8WOQWqpZiaU=&GOUL4KXrbYdgd=&anmJwpXnngXbV=&bSHIYBUqUggYU=&7nPfP6ZmW_bms=&5Ru8CdZdhqgsZ=&K9TjPLUa_aabi=&AxIbpnVUXojrf=&f3zmn2VekalcZ=&eKZJDfXjdqsge=&AJjvgGVjc_oeU=&rjBRd8Uoepkcs=&zLGYajW_p_fZr=&mMgvCCW_eUaXX=&SWHsAkZrUhgYp=&v4PIcsUlekckf=&I9bSkQUahcife=&6IE5kxYkYaVZh=&MVqCtTWprshgn=&G2DwvBYjbYkbc=&O8Mwd4ZoWZjhs=&Jf4rENUrmU__b=&OriC8VW_rikhq=&fixBQqZbbeUli=&2MJmdOYcqcaWU=&e2aW5HY_pcYgW=&C87CuiWZjpV_a=&89vcQiVi_sjif=&HnVgLoUclYiek=&dknBIhYsYjbfc=&I5patcUppVllg=&yrS2JMWqVUl_a=&NOSt3PYVjoXmp=&89oGrlXpacscW=&LJfIDNXopcWWo=&kf44pdXmjqhqn=&D2R6WiXldmdXo=&Dc5bUMXahkUUj=&4663NVXWWUVoW=&kg2ovCWfrmomh=&SC2yY2UhW_Ucs=&n_PgaxXsVYjkX=&rOQsnzZnZXqgm=&tSlKEJYaVnpVc=&59D5rPZencYYm=&Aaqq4BYclakrn=&NNstTWVcd_lYs=&TlYfcBUhUdr_m=&V8GYoFZcXmZpY=&2VyhzuYdbksgp=&i_OOvoWZkrjaj=&cP5ud3UglXWXU=&k_NYAaUUhfpah=&MU8cyTVjeXblY=&syJCQnWiXaXoh=&gQPSCZVqbVYZn=&o49DmhWaodmne=&9zV73gVZ_akXc=&raBOz5Xmpafpa=&eIOBNKUWqlbqZ=&g857nhYlkgjnZ=&IVm58vYiqcfXa=&CpERofUUiXfsg=&Bb85NTUVXqWii=&neGIahYnYg_WU=&wnvhv6WiXrWZr=&UdQlIbWXcfXir=&TrwT7CXhniblV=&3hhP4JVYdWYoY=&9crXNvWXWmsoe=&f8rNZ8WiiodYs=&T2AIKsWdnVgsi=&9VH98pYpgWdcf=&NwGJapZZUnmrs=&7mqcGqZhkgskn=&Qn6q89V_jUhml=&zrZThPWkWYWgZ=&TYbpzHUmmbsla=&wxS7p5VZ_faVd=&cXshMwYhhpXlY=&qBVkCUZiXqYfg=&iTrkOmZ_qZiij=&mUQrPRZsrkYYW=&M_8TpUUndcWao=&7Mm9COXXipfpY=&YTNIO3Ydgopqh=&Rz9LaVUZXqiVU=&HrbqWHYahmVpk=&u_JfdrWXqhijg=&a4V4ThWVbnkqp=&Hgn4TlWqWbahc=&KhwZxQVonbjrh=&cT4d8pWgqgijZ=&OWdF_kZsYfodk=&gGZnVFZrXaVaj=&g9dgsBVhndink=&B2eUHzXofdbji=&KOZKpYXaiqrsj=&oXxe2zZfoYWja=&WfvDgUZYcqhXb=&WJGrApVqhpcnU=&BINHBQYoUogVi=&usOdIIZaUeiWr=&uX9QGwVieYsUn=&_SIGDLWUUpV_V=&m7IWhcXjWbcrY=&MHFLLdZabUVh_=&mBy3B3VjibcUY=&qOfKD6UUsskdh=&qjBINfXkqepXa=&7RPSSoVboY__j=&5eKIEsWfWV_pU=&ypDfgpXjoVmks=&ye2V_nV_jplUq=&ZZFDqnWrdmVad=&2bVIqkXlgpcsd=&vIEIa_Zmhrefm=&YkjcmqWrfbf_Y=&ErlAinYX_gWar=&olHTx5ZfZaa_q=&zJjwMyZXnloqa=&7OAVLYVXmcdgo=&umwVLnXWgUaih=&kP2n6yVgska_e=&8bbBWcUqngnZq=&uHQyFnYdVkZmp=&DJCPJpXZjhYe_=&RSb6QWZpZoiWn=&ZDtiNLV_g_iZi=&YevBkYZmmdoje=&DpxFtsX_fY_We=&mV3Ex5Zmsskmg=&TtSN4pYUrsXUk=&nXmd3AYlqrlrc=&VpZujmXgmcibp=&5n5GMPWfbclUa=&6J46PPXgqgbpc=&NXe6nKZarasqf=&oJiiumYgiajen=&iEaLJYZUglrdb=&nr6FtLXbjplmW=&DoDbKNYomkpZd=&4NgSybZ_gZsao=&Fhaym8Xkscgfa=&rWZfJaUgomjYa=&d2RNCYZddrjai=&hzFV78Ydnqieg=&QGbn2wUZlYhYd=&vajGnVYmZe_eo=&JYrxkkYsYmbid=&gFpc7WYqZo_lf=&Ei4J5UVlb_Wcs=&lmPbiNWYdrUjW=&8WhknoXcngeie=&EFIJ5nZXcfkXc=&VUmcTPUqlfUmY=&Weu5mpWjhVWpe=&QwhDlQYpoWemh=&a5hxXbZfshkYW=&QjMirjZkUVU_c=&UYk3AiYUdiXja=&PWWzIDXqdXljj=&kt8EBNVohe_fY=&SzeqKFWXmeiYq=&yM4zg4Vols_XZ=&wogWK_XejVYVl=&Vb9QBoZZXbcYk=&3xVnqSWsaqeii=&gecP4WWcmmnrX=&fJsgaFYVgjraf=&V_fiJYVndkjdn=&YJ_ywQUrrqlhW=&p3UsLPVeWkX_i=&S4VfALUgVbnoU=&yj9ibNUnsdibj=&Nhgv9pUapVgsX=&6mEJsrXZZYdcU=&BLSYUSYigffVg=&JStW8QXUalgaa=&tOFuvDZ_oibfU=&tFUrrvWh_rhpY=&XyOZqzWYigmeg=&b_YgviX_dpXWj=&rnUvRMWjennaa=&9CY7jSVslaYgk=&v6c_VYUhnldrX=&s_uNWeYnrmpkX=&NLvWeqY__iVml=&mOI8pgVliUgda=&CYuuaCX_efbVn=&jY97eSWqnVp_f=&OrT4ywYkgdjoo=&DgTaZ6YfmmekY=&F8Hlo3Ysmkpc_=&GWNFIKVUcoped=&GxzXYkUroWml_=&jb8HXSZqeoaYV=&HOf8LFZoh_roV=&6ZNod6Xckefbr=&5UNJQFWsoYZXo=&6iQUfDWaV_cpo=&6ZYcx6UqZlrce=&MzZgmpZsZjndV=&96Yg7IWpXagWi=&VK8tkiXVfYd_U=&GzphV2WjX_Xor=&lRuuQzXYeljkr=&Ad2FZqWW_qccZ=&chQan2Xrhgbfp=&h42JMVZnhgonY=&9EstTYVgYgkZZ=&lTzViQYoXVmfs=&9R7qzOXgpocdq=&oY8THOV_ZWgrX=&6BHtkgZqWqamk=&5PtyxDZV_pieo=&yg5cyvXjdcdUU=&8XGvA9VlUYgUi=&wSOjioWfsclgq=&r5Os_2ZWajnam=&xF3wEhWkbW_Un=&GZRAQZYWisVqh=&hL3BXvUopmbbb=&PqmStRYZdjnbZ=&I6Ua72ZZmnqec=&7LynU3ZXfUi_e=&nHJnKiUkcefck=&t_5rxdVXlXris=&WntRH7XiXnjoj=&2fseK6WnqnjZo=&FsBfkBXagUfVi=&DkhBmIZYVrree=&lGg4TeYeUVo_p=&zt4DqAXgfnipr=&HooG3jWlmer_j=&drT8J7Xmoi_Yb=&_VBwrTXabbb_n=&fLfGZZXqpsmXh=&59fAJBXkWldYn=&UO3ADKXlhVrWp=&gbfURGUseUnng=&mtccPTViYe_ej=&6Wqk53XbWUoYe=&77nuMCWiVdZZW=&CeeIl2Ukb_fpc=&93iTwQUraXjWZ=&nvHJDZWVhpm_s=&CrmGtZUkcojhi=&Kec52iZpkqphq=&NqVchvZjjefhe=&r3dSXoXerhsiZ=&aou54xXarrnqX=&AHD5stVgVoima=&dCE2t7VfbWaiV=&NeaN3cWnofjgY=&EhujyOZ_dk_la=&P5jY3xYaohZXr=&sSxA8aWpjraco=&6QxR3xYUlsorZ=&vNX3qIXYffqUj=&4GNRLLXomhehf=&iYskVlXdogVbh=&n7eJGJUspVjfk=&U_bdk2UfnmWsY=&o_eFqdYqVfkfa=&9Y2jcDYaZjjcd=&IEEiP6ZlgpeUk=&mqITUeZZqehns=&kztZBRXXkXWcX=&CIM_R4UsdYZlY=&aQiQavWshafVl=&jNulEZUlesaXf=&Lg_vIhWrljsqb=&F2IhMKVrWrfpd=&ZNZgvuZneksrs=&MrcA9yYisbXhl=&N3MvGeZgafpW_=&dixUQSUY_YrZd=&Vxw9HKVoYbZfo=&6egVyfZYdqpno=&_eRSZoVZcWc_j=&xm_zTUYhpcYeY=&PUQnJ3Uhbpfnn=&PpPifHYdrfsXY=&wOauZOVlUhfUs=&AY4qwNYjemcZV=&FZZuGpVmVcYda=&sykSiXZaUWhld=&ifi8IOZaZhqUe=&5iu5RkXmYqe_n=&EOPTjoU_fVhVU=&Zxm7BzXm_fYmj=&XOVNsPYjhan_a=&RRhj_7YpgqsVX=&6aSYKhXmdlWjX=&cF5SmkYeWYWcs=&KddZeAZWsYdjn=&mNcT9qVjdemnZ=&7tQlIJXXkrgYl=&vDCdnDZjUVXWo=&RJIV6OVmslYgV=&ZOPRTsWfnXrof=&Yhmiv5Vlioaed=&RZdXdMWZdssUs=&esZm6_UejrmhW=&BMGJreZcVqhh_=&pcjIlzZgrce_r=&lQ7CV7XghYsWp=&YiyQf2XgYpUih=&a69oAUXXdYdkU=&gyXbinZ_drqfc=&ljEp6gYilnfdd=&MhshMhZYWgVa_=&UndmvGUXi_bgk=&vpbBxtYnapaVi=&yN88a8YZXmqYd=&_eF6uKYZqbVmo=&RjSxAlYppocj_=&VtKVXrVgVaics=&O2GIxaYd_gXWZ=&JNv8vBVmbdemm=&ItRU2AVVUfssh=&NbnweMYhqrcam=&BFq4huZn_g_Va=&nvAsfhYnnselW=&CjUcDpWbcnrih=&5RBnj2YjnWijf=&gpWhYjZasdce_=&Y2OpPwYlcpdne=&9pjbPSUrhpVoj=&naNcoSXXoslUs=&3W8QeXXYg_Xdo=&FigJBlYaUdgXr=&ZYpLJtXejakrj=&qKwdhAU_bmhbi=&G2H3GMVa_rfcq=&oroo7rVssesdX=&3h5sLMVobjciU=&ACLiIQXeigrqk=&6FKmZOWssUlYl=&JsSgITWecempU=&O2x37mUrrqqmf=&U5CjJAXblcg_q=&UmNioAZgaZcqs=&vbyTWiWXqZXjo=&ffJHddWcqWhsU=&2_l_qFUbogYrm=&I6UcUkXZoWgao=&LfQ66TYkabUbW=&Q9FxWNVsbfdZb=&W2Vk63ZmjbsWV=&G8xTY2VXnZmab=&LIDKsYYpjW_dm=&HEiyaPWeUeorW=&3dVfSvUXgUYVl=&Vo5mEPZbpicZn=&pns3hbXXdZXUe=&h_VmLkXVqoZV_=&uGlpLQZdYhbZf=&rKVjVfUWenUjW=&KTIcyIXrroZXb=&sNXSzcZfVZlkh=&aAyFSrYrXifoY=&FSgnPBUkakWnW=&ue54YgYqsafsj=&hKpm_AUkfesZX=&bA5CICVlkjarg=&xN8tJlXikZcjU=&rf7yOKYdnmXnl=&LORbAxUfsUXon=&45l9ZpUYhWZri=&td98NqUkijdXW=&7w9UJOYXsWeoh=&HJEnN5XjlYVUj=&43m2HPWpogljU=&7OknCkXqhYrcX=&rfmRpEZYagkWY=&5wc7R4Zsncqbq=&zxIeykVZdsVad=&dtNoGBUUoYojk=&HEicQjVXdXfmg=&b48kj2XUsmofU=&LcMv_ZUjUnXYd=&9SbtlNVkjWUVk=&Dt5fsDXYsjW_l=&guVk7fYodgbdg=&Fq7FXeWaqjdrr=&ddMaYhWnblZnr=&eUsPknVlciYfs=&MlIIGLXmsfopg=&3Hm8HnYoXjVrd=&GJ2xzVVggeWXo=&RH7tYXVjncUbb=&rMdqXXXZfpbmY=&nKjpT3VYohalc=&vrQR83Ynjmmsp=&trYS7kUebkbYV=&8EsphCWVUdakW=&_FPJWgYadc_Wj=&8iGpmhYqrVomi=&OgF2pIZshVjsg=&PprX_GYWVZsh_=&WRzd7TYpZgpVf=&cpttR_ZVslpWp=&qEF248VXebUmU=&9mBCRgYZUgrrW=&F_mLO5Wpiijgn=&TN9GU6Zmqsere=&GwVQXgZWaUfgf=&Enf7OBYbXZilU=&HIvt9MYnYenWW=&LOXMC3WccbUg_=&_Cp4XdUWsjoYq=&7rljdmZZeZXf_=&t3qhNTYqgcUeZ=&_Xk_sQVhdYqhc=&n9ZJ9rWVXZdal=&yDIpNkUjnhbaW=&rCga_eZfklYcb=&pTP6z8WgbVXbp=&m6Lnk5YrsXlab=&mStUblXXYo_ac=&RWBmMXUhsliog=&9NjRS5Ycdikmj=&_wmWv2Xcgjr_s=&6IOGmjWbhhalX=&tzzU3EWbfdoZa=&SwDAxaWcWbjhY=&OH6v2RYWaalej=&acr8tgXmWrsse=&KT9ccqXWaoacj=&rlxqFfYVgjlrs=&kBZRvCZXVjgWX=&w6agAgZoknUdl=&ouPn3rXUgrsas=&KkJ6cIVXbeqkk=&V3kHhlUrbc_lc=&THAXb4XnWUnsp=&aP4WF4Umsn_Yg=&KQ_GEAUrbbXZc=&YGLhiyWYUUbrf=&VUjDlPWskfkmp=&jSvkBiYsemec_=&APNr6KYsZilkj=&8sMZYGZmeesiY=&_3osQdUWorlec=&CAMIiKXmdfsYs=&TkdY3aVombYnW=&8FOfziYrqXmde=&RDkNHIWV_lXcg=&c7mTJ5ZVbogik=&qz7jWDXmehfrg=&yBlOzhU_rpoWd=&VKYiQJWljjgci=&HuhNcMXhgndnX=&LW2oJaZnrjeYY=&f8xESCVZVXeak=&AWz4l3YXsfcWW=&IO8Qy2ZrejciU=&e7F2x_XU_piei=&siG5QsUdejcVg=&HUniZvZUVocsb=&4JygNXXVnfUZc=&CKi9cZYYWbaXk=&PlSG_PWkXUedk=&7at8pgUglUaWp=&gvZsMnYrkpUjV=&psBJqwVdfppl_=&zYva9cZcplZkd=&n9qTSzZmdUZoh=&VI77rhYUpsalm=&SNE3PlZqWdfda=&PbHE5IVgr_oco=&dqAxgkY_lYfbq=&7kFD5QVWp_nXb=&zBT8QGZkjegUV=&exXvlqYhfb_jf=&cz95PbUfrecXX=&kdOGzmWlUk_fp=&XJyaLFV_pbegk=&Bn5zYHZWX_phV=&VU4M4LWaVqcUa=&Xz2vIVVhfkeba=&9YjmaZXapabjX=&ZEpNMiUkcnlpd=&xzEXWTXpccnka=>384bUqprrlr=&eH6aUOVgiboUr=&rukHlpUpoWkdZ=&SiKaHyVo_Ync_=&pyOcehXhcmWXU=&BnXQJiUelVnYc=&kuY7SkYaVUgnh=&e7VUkGUpomesn=&jHGAy7ZocdYhU=&JmHRQoWiiUksk=&hGI2RMYbXbblZ=&ieNqJnVbidni_=&reCGQlZeqeX_r=&zV72TzXge_Wir=&fHShQwYelgakh=&IITBtoWn_dUWa=&MhiOifVgYZYar=&R8h5HOYgabpl_=&P3Pr7PZfqqUsb=&qHfN3bVipfcjX=&vqtUcUUeZnbfp=&WdoBhsVjfhUfl=&xbdrVnXbqnacs=&DWPtZzYs_mlcp=&LvhiieYq_daZW=&TCo9pCWlbkpdX=&n_YRPEZhnogWX=&RuxXOjVrZrmVU=&aY26GpXUejZdk=&6ngUNxVjXVsZc=>sfUUZsdoUcl=&XrQMATUfchfpc=&VlCkw7UnZkYlU=&c2exypVgjbaVq=&fi2EjYZrqUhgZ=&JKS6_bZYXgqom=&W3WlI7UUjWa_d=&kmgRH5WebqdVc=&PqWyZkVdjsrUh=&Yu3sNrWmp_YpV=&DIPzL7YqsbpmX=&WhAIkzXeUsfZa=&cj6EkVVdaYrsb=&UlSH8AXU_fdcr=&xNC7vVYprlher=&lRHC9bUoWkgYd=&z6UlJzXa_chWY=&GqFFtLXkjrhjY=&2sIi6TXo_YsVm=&FBe9DjUfgsZWj=&AaTncVVejeooq=&S2iTSlY_bjX_r=&83ogbeWjYaiac=&vQaFGlVejVZll=&TgMYNCWUlkWaU=&52e7ngZsir_ch=&pqBo8jVjjiZfY=&pIIMFqYkinWfh=&5gtGmIVrmabbk=&5mHCxiV_fgrVl=&Y5QfhxYirolpl=&9dwLzRU_jjUel=&kyySjdYk_sikd=&WPOErqXdVnjgi=&7TtpRJVWWmenk=&FDPafyVfbmmYc=&cJiTSiW_mcicZ=&wF7gbuVlkm_ej=&LKk2GTXWcroam=&lrCKeOXbqZshZ=&UliatTWcgaoqq=&GjTyeXYmhbreV=&a6Pd2GZcjlWWc=&XrJjyKXesmWmc=&uikgrcYjciXke=&Dtt6wVUrZjbi_=&655usXUmYchsk=&6xTYEmYhdciao=&poV5cgWXloUbm=&ULlCuNVUfZbdV=&Vk3wQvWafrgho=&5YGkZCUajkoir=&BLa5tQUYkWcXZ=&raxtTrVgXdn_q=&wrFV28UbrrXff=&BtxqfZXZWZcsn=&H3n9qpYjsYged=&XOrtfEWUfVUkV=&SHq2PsYcegXgn=&U2Nq7zWppW_ca=&dPhmHbVddgXlj=&aJrV8WUkW_bXZ=&KXTICyYacsUpe=&TIvZZGYfsbWkp=&uNemXsUejfoUh=&pMFV8hXlZmrmY=&hCTClxYaXegUs=&ffVoYrUVYccZn=&wFGdUyYUZribW=&LM_GbcXnolVde=&Jn5egZVWWdUUo=&mu6O9QUeUX_pW=&oeQGw9W_kcWrc=&YZAfYKUeZUlgX=&sjyAmIVmZkgi_=&ehAgrKU_sipiU=&duKWyhVZhmbZg=&d6PSDNVaqjjl_=&BjVuItZgjfUee=&R9HsBbUhqgjjU=&kIxS_fWjpXsjl=&fyuJHHWq_oXma=&Ic9jdIUXYUr_V=&NufIIEVqr_VZl=&zvmBxkVicohqf=&QmmEZ4XXcbige=&jvrqLhZmUhbin=&FOcsOMYfWfc_i=&yjbLqjYghhfqg=&gjubzRUsdXsfg=&tI4vUcVhXrpmh=&FbZUv7WlhmYdW=&YgvmtRXfWZnff=&s6uaVqXqigYsU=&GUio_zXV_oUbd=&TNkNiFVlcggsZ=&VfUmdQWVjgnZW=&P27y8DVhVdjdd=&Eh3pIKZlYqocZ=&tODug6XWgjYca=&C92mbvYlVVdcq=&mXOShXWjrUYlb=&W7u6o9ZemjZWj=&DiWeKHXbUqsXU=&vaFucBWdfaWbf=&XSrpIYXoXjd_g=&f9aIOQVrqcnqh=&zQYKfAYjW_acY=&O25mEGZcrp_ih=&74CU85UXpYbhX=&aVekDKVXYklfj=&v92HVdYrmqaVs=&Inl2JYUYkremg=&Y979zlVkUgphm=&Ufat3eYiYjjoV=&NSrFb8Z_Xrqkb=&VHRPPzX_gliaX=&yJ9V4DYimlhba=&7e6O6hVcdXdUe=&Sr7wvCUXXriVp=&3rCjrxU_iZlaV=&FOHuQrWkdpjnU=&JNAG2HYUfYipp=&TkOz9QZbslkis=&6nmXtRVrqaXXg=&hbABUGUpjige_=&gXbwV2WohbhoU=&9H7Y4ZUXsjZqb=&n8WvqCYXVfXiU=&Ir_QxpYbbZfhp=&8r3GAtZaqrism=&KHEibwWXcWpXm=&qv_tfTYbdqgZk=&yTi6yrXZZjXVk=&B5tGnIZpesXcj=&v7uADBUWliXUa=&E_wKsYVUacqlj=&c4gHOYWlcfijo=&ohd_X2ZsegVYf=&skbagXWlXkjjj=&bVKw_GYgpsWWs=&2lCXqfVZaalWm=&dQoirKZUVWrgk=&fYlChtUbfscah=&fuEaNCVZrUWak=&W7QQCjYboasgp=&WOrB5ZYboYWps=&Wjd7VmYcibcbY=&dkNSJ4YemYsj_=&awOnYvWjiVWcX=&eeZB9dXolflas=&Um_zRmYmZljae=&dDMwX7YqVnesa=&WC8OhrVglXql_=&gXzbOBZrrjfaq=&KtmKa9VVYZZbb=&sDuXJwWaWajUZ=&Y2DdUEVWksaWb=&6hslPtZYngjqh=&Jcn9SLXYekfYq=&TgHoHAWsrhage=&Byj3dtWUgqUjg=&yxaV_eUXcarsV=&rouJLkZnfbsoW=&dAdkPtZXmUoVo=&ErIbp_XhZdUXl=&MDamDlWWbrceW=&4dT4CVVVqXfWU=&jKqffCWdqfpVU=&eNPXr4Xlfo_mX=&Sdd9evWndjbkW=&dwi9zJYhgpdYZ=&hgf6CEZn_pVoi=&uC96NbUsro_la=&L7oUpdV_Xifl_=&NnG4eVWkhnhkU=&SP_pQXVlonkng=&vPPRWRU_Zqqlm=&MdvCUeVgVWmgZ=&h8REC2XXdWWjr=&dZVztjVifVfZa=&JbmnFQZlWpppi=&LvFYnOUbbhbmV=&y2q4QJVgcscWd=&f4dzqlVrofcZc=&oTk_9vUhZWjnd=&In4zuAXeheraj=&whRdGmVoppqXc=&gitU68UlWfkic=&FaAoPOWqXYhVk=&UOM3zRY_pmosY=&wWCtNEWfegfiV=&fc_E9_ZklWpra=&5jENFeZmfii_c=&5mlG7MWfcqaon=&ktWbEtWegZXlr=&YU9OQgZceijmr=&a5pkYKXZpa_gV=&iLfslkXbXpjYZ=&_ul3KqZWnaYnb=&LobooAUgccqli=&LZPIKrWZkpfpZ=&NKNeE4Ufdgrlk=&IJzNzDYkUgZkn=&TNzZ3GZXhVUed=&3YnzaxVphn_ae=&OjEXzUXprrcXp=&KyyezVUYXWcXh=&KqTgjSVlccVYU=&iGPyBiZYjXdYj=&xRyZMxZUcjfYU=&95UQkHVXrVcVh=&w26axBZqqsodX=&AX8uBcYskbrYg=&hoRuTuUkskkmU=&TJFrUsYkVbbYo=&mgJmvVYacUbXg=&R2jLhzZUeapXm=&bGZft5ZVbjlVZ=&6xKjSOZUX_Vkn=&G5AaLmWaXeqp_=&P4YyVDZbfXqVk=&LKEXdfVndZcqj=&ZWUrytYpqZjZ_=&VgBbpvYkkdbke=&skXg_2XbinZmV=&eOYLpKXn_fpml=&2B_6t_XkWXWV_=&LxSXovUWkbcgo=&iQj_9WYj_gbWc=&MLfBp3YhsUeae=&58qvANZiZWYfh=&HchAgRVjj_iqj=&Ke_maCVcniVcY=&ZWP92BXdanigg=&_Ix2nBUkdbjea=&NidDoxYmlXoVe=&mek3JKZZcfWoV=&7eSTe2VkcVZ_c=&DSXGKlXponWXq=&NoHoC9UekUkah=&rZ43xEWeeinZl=&dsdPdkVp_hahf=&RImSxZXWpbkcb=&UgdtnbVXodjXU=&OPNwALWXbpdlf=&bmetUzUco_eUg=&j_qgBQZdU_fUW=&SXNfuSXfXfZmd=&ULOJ3LWXYYbjn=&haAlA7VUoUZih=&OdytDSUefrgbp=&rNzpl4XqgWZlo=&NvbuDfVVYh_ip=&UHcshTYYaWage=&iftYfyVpZofqi=&YSKJOLWrUnXam=&3t_2SkVpqoYin=&hq73ouZdqpVqi=&_6SLF_YUbmYn_=&E9U33mYkqqqbi=&CcAoPmZh_lscp=&aBPIYVYZYglpd=&aKuTbsWpWflZj=&FhwQltVns_ekh=&TFz8OhUiZs_Zk=&dy4qibVpnjnUb=&SdlzCqXUlrY_p=&bOq29NZZpmfaU=&qbNzL8UcskVYl=&oT9qoFVYYnng_=&GYOre5ValireZ=&u5hb8HWpcpWbU=&QvZwSKWWnpnYa=&kpjUhoXidaiVl=&EnkPbiVfUcaiU=&RpRaZBYcljmlV=&ZRhDn7ZciaoXa=&Auh5XmWdZh_eq=&BS2t76Vfkgl_k=&aPbtY6YcefZir=&8dHKy5XXUVXsa=&AKN8KgYoUWcrq=&3TTwdwUrXohnk=&etBLhtZWfmVfs=&ZEgKWJUZZng_m=&NDUZGdZae_g_k=&wAhJHsWjpX_jW=&mY2BvgWVdsXpm=&9BXuvpZeaWbsl=&2nkhnsUeoiYmV=&XyQsABYg_brXU=&It5kMTXfrUUfd=&Pq_7DiUqmgikp=&6xCzkIYhVb_r_=&tYo2NlYU_moni=&HLB_CPZjkqbmi=&eKwGrwVVpa_jq=&DUxTBBYlhUZXe=&qQW6H7YmYacmn=&Gccm_xWUjbmmo=&hHlDDrWYnlfmg=&cJHrmqXgsgWkf=&lYPWcaVcrlgiU=&q2EYZ9XhsVgWq=&8agKbsYZaf_kj=&WRO8KTWVXUVcp=&EIuCWjYlrcUhV=&_evCCFWfgpaho=&5_IipmYZmanZb=&a2QIGMYVgchhb=&LADbpeZinejge=&jih685YkoUrmW=&Z7lZHmXcoVdsk=&RYdw7mYkbkfsr=&rtyXWHZmoaZh_=&AD6b7lXXmdjgr=&N9Tu5NWscsmca=&aEfx6mZYffiif=&iCdOLKUVo_njk=&IZLtymYdYqkml=&Nz599UXngloUg=&9IKlJgZpeemZk=&4gJIeEUeqU_fg=&GvvTQMZoagkqd=&ZCCHkZXrsXfVf=&4aAV_PZdWmpsp=&YjjFgkZqdjYfU=&kQzqIvXlgrsfV=&ur8yVRVcUkUoq=&MWrfFkY_lgjnb=&SDOzYCVnipUWa=&sX5PuCYfrkmkl=&_HiyxtU_nbbdo=&_mycPTXoqkbgl=&EQ4LTzVUYZhmi=&3otY4yVpVckVr=&vLASiuVghaZmk=&MVdB77Zomrphs=&kduHbhWYUlZnY=&pU2jCBUhebm_X=&q3tmXFUpnXVoa=&EXHvHgYfs_Whd=&8KVysIXbqrsXV=&Zrx27cUZroccZ=&ZDFp75UUoYUpq=&9fyBoIWUUZhch=&g8OvRPXaXmdlV=&p4KtEmWWobpZl=&GVzMa7Zkkaqhp=&4LDiMdZmodXpn=&hE5BYXXsXfsqj=&cNLywpZsYigan=&ek3LYXUcZXndZ=&conD9dXsWWsds=&zFQLIYZXVcZVX=&bCDHbIY__Ugoj=&reIEJ2ZgYjacq=&IBZlbdUes_Ver=&2BYDIWZWZngWd=&AEtofeXkapXdf=&VnwfB_UcsZocg=&QvcobDYljjbqo=&H5JRQOYbpXdhb=&kqgocFZmWkpoq=&fB4XAjYhm_UWf=&kZAuexXrVhbsm=&b5BUEdYbXmUgo=&_aXReCVdj_eqc=&_OBTD5WfqdgqY=&Br_UtDXnmggib=&KmXBK4YnhZgra=&4LbskmZkYngdh=&yjkOegUXYUUsn=&gymIEUXgUqjmf=&wV73HIWUhbhjp=&4dilC4Vlhknen=&U87OsUWbggdig=&MlFyq9Uenqjnk=&qV3rhNXZYinjr=&hKMzFGZersnpY=&HrJw72Wqjrklo=&bsRR2KXicWWXj=&2MmWZAZU_jkno=&CXPlJlWcnbglr=&WCTI8SUkirYpl=&behuAjXcbkoaY=&k6LkQTZrmWklj=&G4mJGxVdrbqfh=&oeHLyDVfqnZcU=&mtRTHlWXdr_Zq=&t7ZUj_XdjWdXZ=&FvNDHBVjbcZYn=&OKiWaUZsUrWh_=&xycrD4WkeYfhd=&CYvZc3VUXUcYV=&TJmKkFUXinlgl=&RYSQOFZWfcjfl=&7LoYpsVcjser_=&TZNGIoWYneijY=&GNxw6IUeek_fp=&CrV9ZcVaqkVfj=&8yPbgkYcZrm_e=&rOr3pjWUVWgWa=&KpQIzeUrZrZif=&vPALGxVlkXpUX=&RKErgVXeihqU_=&6cqbIhYWlXrap=&26lYBrWUeVYWh=&KTQpvaXjVsmgV=&pKP8pKYlU_orX=&zIfDKZXrqZWjl=&9oe8drZWlUcfZ=&hElZGLZqjVbnY=&jUo5WOYhllgal=&44NyiyUcjjWdp=&RaSxHlZr_nZnm=&aAQF4wVUg__pZ=&SPBSpGYXcemcV=&JXbv7nZikkqUf=&ff8qE2Z_YjcXk=&cLoYoKZbYeqjV=&GvM7rsZmcippm=&lShNhFUocYVhg=&dmUT5XVsWpWdh=&vVLrxIVViYoZl=&F_zQnYXadZVZX=&JRC5fLYldroco=&pX9CEGYnfsbdr=&DV29CwViqbUmc=&Rxr7SQUfmpoZb=&GwH3cZXdeVrsj=&Ah2D2OZkXXbrq=&rw8SBVZhssZVX=&frkqBtUZWj_Xo=&yRtmnrZniYZpj=&SsOxVsZdWoXkU=&ueKGUwYbjXXZa=&3GLvDEUWYshr_=&GlEqSBXXZUUcc=&COWhpcUnmWjfi=&9DOB2xUgXYbfU=&5fBt8MXYZfjcX=&a2cakaWbWojqi=&W8jzW5UkXZslZ=&zAoLSoZUd_eVa=&uf7bcMX_ciqUq=&_7mIhrUimnYXl=&OW97WUZaj_cri=&cp5qG7UkrcYab=&xSGfDIYcVlVkn=&BpDwV8Vk_qeon=&MjitTRVYmUjij=&BGf4KSUm_dZjb=&OiLAPUUZisVdk=&GN5zNwXYcnqoY=&pWo3rnYnspWVr=&ehl2edUXeeZfq=&VJdtsoUUZmaXd=&iRU8LpVVqskij=&RgjHR2Zpnhdoh=&ecvipeUchfWqf=&YCWJGPZamjZbl=&3yskpWWgjlUea=&yUMIVzXpfbepU=&22wa3pUUiVnmm=&blP9sGYidYhYW=&2OpXmrVp_eWXe=&4vlHHSYhbrVZf=&4oqLHRYXXdgom=&Wx2KnbZYbpgiW=&9COzVPUcXaerm=&ZhyBOEXjhbloV=&CKvcE_WkXZsjV=&pURgt5V_fjVlX=&MZNBmiVfcabWZ=&lgEO3YYifksah=&bUo7EgZlchclW=&trd4trUgfZbkU=&_fLQVPWcVkYYa=&nNnsjgUfgssY_=&47prNgYYYmXZn=&iVRjysYXnUeYs=&YDmBERV_VijUn=&ibeGzbUllXXfn=&TSjWCeXW_achn=&DNzphRXqkYsph=&JeFNUzYmkY_jo=&38Ne5KXlfirpa=&lWyc2qYhbhrqb=&9W_vpCVWYWiog=&lmn6SCUqVndkn=&SzSnK3W_VWYrf=&ktTXl5XnZWqUg=&MNorsUVgWkilh=&KMIR_GUg_Wofn=&YfpVVtXlrqqVc=&RFs3DTVgVfjYn=&7DdvDvWgaXjmU=&UPBztBW_cUVsr=&_toGhxWsaaaXj=&tWvWRoYkdkVdb=&qm7AY3ZUlXmsg=&qMAJ2oYVchqUb=&YxtnPeWln_pXV=&gB778GUqUnb_V=&jQMyGAYaospfi=&BGYVS5XrobsWo=&IiXPTxXrahWWW=&Igo447ZcVjdrk=&2KqN5WYYrVbWk=&cf5QTiZijoZ_g=&rOAM4yXjosmXi=&JwxYOKWUrXaZa=&xQfWTfZrcl_sk=&wQJz7lVsaVYUg=&8YVTaIYriVeik=&riUenQUbbWeVW=&nHxJG5Zhogfrf=&koT225XnjUVcm=&dUCyS4WeehVol=&3Gl_5nVrYjsYm=&cZ4O52VbXjg__=&FlPsjwWXpgdsW=&gDa2CWWrUrZlf=&XZtVFfX_sikiY=&OnUCPyUicjfsX=&CAFP2jWZdhXdm=&pdvWYZXlsgbdZ=&aqCZhaXWapYfU=&3cdt2WVZfVbhY=&Ok62Y_Xrdmerh=&bgxunRYrsYjcX=&e9xvegVjgqoeb=&NjIzFuUcoiq_l=&CVWMxNWsXqmVW=&6N6ANpUiplsYU=&ib_VjCUpUofeW=&Vuv3AnXVeXphl=&ldmAfsZYYaVVZ=&7ITcucUkpllp_=&rwJQcYV_agboX=&b3jlCzYmsbrcX=&43XLj_VWgrgah=&7Jwm3OWkigqnn=&ZjMjNxUVbhWno=&hRwm2NXZbndpp=&SxRdxYZk_egac=&UqtYs4ZhXfebU=&OnjaBAUhWjaXl=&Wu846DZpjjfdV=&8UF9jGXrXXfpk=&oIuuQQXjacjfd=&paf_TqUdkZVZc=&ZXKlgfXVebf_l=&HzyycQZXgjkWg=&7zv9NiZdccqsg=&kcVhBDZ_pnfrU=&YhzLeDZsaUnVo=&F7MRZCXWYohlr=&cO_NW4ZYrcacd=&854xZrYfnkkfX=&KlKUTYZrkceUj=&NO8DAhWalVaXY=&rxXezsZfXeicY=&MOHEjSYfnW_pi=&Yf2BzHYd_sVXf=&bAwxXXZmZanrX=&RDINyLWqWmsno=&Yug9aKWbabjXl=&x_V6IvW_d_rWV=&X6gyfuVehYmmY=&f6gsXFUoplmr_=&5Fi9aQYYkZUfk=&FXE6oLZmsceYq=&S9CTgvZeqaWnr=&P4qkoUZfVVUpe=&_859ZCZcWWhmn=&6JQNXiUrqkYe_=&kOT7kbXb_hpmh=&LebvXMZm_iY__=&ZhbhrWVclWioq=&BD3aAjWWpZaso=&jzuxmmWcWVpYa=&52cSiqWeUiYYq=&r7wO6fXdbcgkX=&uX93OFVWXYebm=&UJ6HvFWmVU_jq=&Q4GlB7YckWWWm=&MD_kxOZfoZma_=&D8chY5YenpWhn=&KcVFdiXZmkbsX=&zgboLzXYXqpfr=&mgsKQoXnpeUqq=&wWtB5gWVqaadl=&_mS5UbVVpokal=&nAlOFqXrdYens=&MTpSu_YdhfmpZ=&q7OnFIYVlqUjY=&MEPWGoVfoVphp=&7nOUHkUgisZgc=&OwSynoUpaefpr=&RV3QwiVoccUoa=&okIHVMUUUcYWX=&8IbAxBZjajWYo=&okb_FrXjlcjge=&YbiRPxXXUjjlk=&sbVIb9UrYUUof=&ffMaJ9WUmhseh=&Umj_WPVWrqj_U=&wilbGRUclorjV=&XrozYvYsgUpma=&vXzxIvXWnYXVo=&E5LezZZohcjXa=&btzcFqZsdZdjU=&pzh_obXWqXXpl=&pUM6PmZZcdgdc=&SJihuZXa_lVla=&pvyuVyYrljXom=&ecaq2FZhmgakn=&IZR8gMUda_s_p=&yO9MpYZclja_r=&AQKsmCUpVYUqb=&Cwt3TNWUabfoo=&befz3oUqYksZb=&Tz3XSBWXVVolr=&mZ4EbcWmWnYer=&fmQkmdWsshYak=&GrHSsaVXgblap=&_FVdGsYpWolom=&AXPIu_Zeldj_l=&xphe_8U_fUflg=&NZJkuAZllhncV=&IWmcrGWeWd_Ve=&79yJSiZrWYsU_=&xZShH4UYUYijf=&VOxznrUnlflll=&NGDZocUkrdfnm=&x_VJLGXepacWb=&8evE5OWUYlgjd=&SCPH8xZekoVfa=&MTELODWnikkbm=&cDLrTVUZ_ijhp=&SPDyArZmi_apU=&Bb8y2MUoadhhs=&VEktHCYVnqske=&TY_IuRYifoo_o=&oqEa76WmgifZc=&QzKbk2VesXlnW=&W2ZPI8WqbgeUi=&L5aFe_UqelXWd=&9LbhEOUsYgjZY=&AABrXyUdVeq_W=&NzUDLDWmbsgfs=&SX732OUslqhob=&dQRMFgXgXrUXo=&_TTDfsVgjaken=&UuUh_IXrnnUkg=&5TIZDpXl_iinY=&mTxHZfXiihiqU=&E8WlVEWUZkdnj=&_o7bCsUYeYdng=&SqSViQUdhVfic=&DYBtniWVrZWVb=&neBWpvUoYqVrZ=&TxraQlVnpoZrW=&D6LSoIWjjaWqq=&q5T5z_Vhls_XV=&Gk4SaaWaldqiW=&eVNDxTVfkfaip=&fTQRYTVcdVYgq=&bmjboJXmsVpgg=&bd5kOEYYdaYmY=&7oQtFZVrrVU_s=&HCr6RtVkrY_Zr=&XBYscxVildYZ_=&uZoyK7VkrUaco=&yypbyeXirVhfk=&9iGclvVpj_gme=&2k92RtXUejXnf=&x5aE5WUrdbnhr=&vW4W26ZharkUk=&P548TMZeo_Ydb=&CZrRVXXYrqZ_X=&Qsx6bBZYipdc_=&LyvMdeVqhZqgb=&AaWTNmVUrsiiV=&WnIrlcWed_clc=&QWux9oUlcYdXZ=&Q9nkMDVqrdfgd=&neYRITYgqUqaW=&yJmZoWYrejkUh=&pGjtP5UpglVdn=&3qDehGYiocor_=&D4R_6TVWrpo_d=&BLMbN2Vdeoibn=&Kicn6XVaXo__g=&kcZfQWVagWW_g=&PsIscbWjnonmY=&lfBSYYYasn_dm=&Zf6kBjUpfWfmV=&jGVpJkXmrpYWc=&fpndS_WWdYUhn=&yhBjinUUnXhld=&8rvSNIWsrepcn=&7h72yCWdXkcr_=&lo2yrPYZUaXWn=&e4UQSMUisebil=&KVflbwYhraYZ_=&uOoETHUsUiqcb=&7PcARQZsh_rXf=&wG6bdwXcirfof=&QJN2i8WhlefWa=&KO9AztX_pXenX=&PvOHDAVkcsXjm=&dUYBgnUbqsWVi=&cW4MmYUZWceon=&gJas6zXeXpoir=&HS76kqYdniV_Y=&5OsHl9XsoYlXg=&2CZ6lvYfnroUh=&JMVvilVhZdZdf=&knQBVfWkkbfps=&qle9ItYVogfsV=&T3WX2MV_lUehj=&l6D_XlWri_nqg=&6sjQOOVgVcslU=&5532VuVVmjVji=&AszwnJWnpinbi=&waOv_xXpZjaZe=&JfoKXcWlskkfe=&rV93gQXboWiep=&ICfJD4VrXUeWs=&N3KUllWgqsqkU=&PoY2BdXaV_kgb=&6yuzQSYWeUWkf=&k7tWG_VjeUl_X=&_VL75mZedgffb=&BeHEGyVogcUjV=&cMDPbjXWmYnZo=&jGbaG5XkfWdqU=&fv4vhnWjhmpmg=&qKxoXZZaVgfnm=&h_fdeNUsegVVX=&hAyNZxVnajfkl=&i9qnWzXeZfqXj=&6EWgQSYlnXVUW=&yku5pHZmUo_qc=&_TImqbZcornik=&P2aM4dZqiqmhr=&XIoPiOY_rrZdb=&euMsUpZUZWbcd=&MVroyZXaXrdii=&qUr5P3UeYl_Zb=&wBfPcmXjggnif=&KJPUoLYlbVjsk=&cW9iUJVqVmgec=&hHCpiUXXdaV_Y=&nROIczWZdcUea=&o7MHAqXnibqoZ=&7LjmpbYrrUpXh=&IZyUILWfXllbc=&46JiJvXpgaepd=&WbVkQFVsZcfjY=&RJvjeIVganidc=&XhJnIZYdepsqs=&uf96V9ZgkpslV=&GFM8SdXdoiVdi=&PX6mxoXb_Yg_l=&K7poJmUnecYoU=&3_vkc6WaZbdWs=&DRHeYcZXjfWm_=&TF_CzjXUokZji=&4O7f4KZgboUss=&fpGf7HXiXhlqZ=&HSDAJOXmef_hf=&yQmvjRYqojp_e=&8bMdxUWfeUUdf=&9oQBQOVjZemhY=&PW34raYsldsYi=&c8Em7IVdcsqZp=&MlOHNuWjsmUpa=&LLyLXCXapa_l_=&eCqIn7VgXhcri=&ayb3auWdrqdml=&GAaQ8UUelh_es=&43Q_MqXZdaadm=&fu8HAPYbhd_cq=&vLlSMmXmiikno=&RhP7xQYfmjcpg=&zRup6FUfaVXoZ=&gWbLkKVirjbpm=&bpEsVWUrjYgrn=&jRMXX5VqaWecY=&m3ibZhYXmXjip=&Pwz_LWXq_kmcl=&Hd6h6SZgsqVWq=&cqLo9mYXggbUq=&N3K_LhZgVoaaU=&bYMc7FVkddh_b=&TkjajIZeqak_V=&tEWZpsX_UdcUY=&WURNPSZ__eX_i=&hrDZ_XVmWYejq=&AMH9IPYisllpk=&K5ZyfyVqgeber=&enn6S5VkroWdl=&fiagB8UVccles=&yOp6B_Vbhn_gm=&GnafsJUVqYbos=&wXtc6eUilWfqc=&cm8BMsWeqcfsa=&pGHObVWZempho=&PIZbQeVlejYiZ=&Avu_uoZsioUVs=&4wM6UvVrZeZZn=&Tl5vDEWgWnYgi=&CWv9mZZeWgmYe=&OKMhr8VVkcXh_=&rNVhKLXiclsjZ=&fcbA7lZeVadZW=&7vbRdoYYcYqkd=&uIL96xUanpoZV=&4KHsvgVqeVUko=&zLDtopYccbgnm=&iNM82dYcWgVnn=&bqdWyLZWanZcb=&A8AYYvWZUgeqg=&4qLy5zZdoiomk=&gFUUQyZqalsqa=&6CxZ8yVeejsjU=&pdysByZXjcnfn=&75738YXqkkZWk=&La9ZaaWiqXoqk=&cS7xlTYlkikYr=&TLmXG5VdYZZWW=&T_IAeDUmWaZei=&QJ3iEkYcWcZZe=&Lo679FVqkgacd=&Q4QV5MXagjbrV=&4qzwkkZ_kdedq=&QroNueVWWhZoq=&NxDA5tVXdljmm=&iKxqbHUnhhsij=&m8fKYpXeVdgWl=&t_2PRhXpqrhYc=&wu6kdvUkqiVne=&yLR5XUZ_sniae=&WOcEq8YUUeYdr=&aCM2u6VaklgnU=&Jor2poXXjlVfp=&6uWncrYYnfoem=&XuMCxDWgUfnlX=&BckexJVZglolm=&bbEXYdVmgfWh_=&hnBj9gVci_Zml=&zYqdEfUVffkWZ=&DJ2tmBWoXsWUh=&MBM4rZUobkbnm=&EbpOyYY_mbbgV=&lHNDCLUmpobZd=&QRXitjViljngl=&XsUR6uYj_moYZ=&nJGcf4ZnUgabg=&SNmr72YXqpWgc=&5jd3S3X_kXhhr=&QkUy4yZWhgppY=&w9EMOeYcUk_ni=&be7yNXZisrYki=&nyzmP5Ybmn_go=&pHKdiPUWdcWlh=&3nmZn6UhbWmmr=&czl3bCWeUUrXm=&CCnNjGXpacgZd=&gIDLZUUUenlc_=&Qyc2tnXW_l_ia=&ZbvGrhWYkhqZq=&ktBzrYXeahhkY=&GWArZJVigcUbg=&Ujc7QaZdZrfhW=&gXo_FfUcisrrs=&af3ekvWdelagV=&gz7NHQVXlZYko=&7ukOb4WsWnkoe=&n99SbAUmbpafi=&XZ3lzIZg_rXXd=&V9OtTuVZoagqc=&5RTAXeUoYYbfo=&KjtxlGWZghgrg=&qc4IE9WplbjUo=&uCayXlUljYbUm=&4JrGqsUVoUsni=&f_tRL4UheiWle=&5GbWiOWZeWplX=&jQXWwKZ_Zbi_W=&EZeGdGXWgborq=&S6CZWIZUhjrYj=&czXOcvUlqa_sV=&QLsSoGYbUeWbq=&_gI9T7WVsaeol=&Lg2_f4UZd_Zka=&xrKnmQZUapgsq=&3w6lJiYUUhhic=&62ydQsXZphgbX=&JgCtdLVprm_Y_=&DABEjIVbnWsql=&CnhN4OYs_inlh=&J26azgYkshild=&uTQbIAUZciakW=&ic58biWUojgfV=&ooo3DNYVf_kre=&rhKM3GZYsZlWW=&GWQqZ2XeindVf=&6L8z3XYrWkggd=&6Em4GeVigcekc=&ilnHiMZUcUqZq=&reosATWmV__nr=&7wauXiVqXVVeg=&apObZ2ZrrVXme=&X4C9K_Ygnn_ap=&EAUaFqVVcZamp=&VGEXlVZUpWnfb=&clVW4jUrrsbdZ=&u5HqRpWqkqrap=&s5uqSFXipcrb_=&VMSUBWWakjsec=&hZGuUoZUincar=&9kfYTiYqnflsk=&sPStC8XqYZdjm=&7OadiZZXpdhrb=&4YwxbJVVsafbr=&QCtO56YaaflV_=&ROGPcvZqfjkbe=&YIjnMXXrUlpXr=&bANBdMUadgfml=&TT9CsAYnhfkYs=&5mvVX3YVihsYo=&k4BtcKXhUgfib=&lMB2IHVer_VgW=&c838SiZfojVfa=&R6u7nfUrmVbie=&HbZkPvZgmZsZl=&cXfDaLXfcrnnU=&UvGbAZZdWVd_s=&vgbHzaUbosdqV=&795T3pYdX_prl=&ny8JuuVcj_oak=&5V4WkZZcljsno=&4nDCCdVXdnnse=&WpesxQWmidoUq=&SWEYAxWcUgqYo=&DQQOk7V_agpiY=&oaCh_4UpsVm_V=&73km2XZh_inYa=&I2kazVYlhqneh=&ZwDlLsUhniUVU=&xe8PEYYrnWU__=&yZh69fYmnYilX=&fxvkj7XkWb_Wd=&ns5quZYjfU_ab=&kuT48gYeldgsc=&AHIOQFYir_sag=&eCArPRWgsjglW=&o3Zu7KXUWcopW=&jjQCYMU_ajprU=&Es4ImqVWZlqor=&6fNhz4UeVelWh=&soMH7TYfWlc_l=&UOuCgNYnXlicl=&a3v_haZYpkWfW=&MkVh3OZVUdZUl=&M7GTMiXpdhqWo=&lapWA6WpZrhcW=&AeXjItWlsqmno=&5XDGnSUidUlec=&wfPctUZssWVVZ=&7pYT8AWcmnni_=&KmgxlZVUlZssh=&Mo87fIYrdoano=&hBlITtXlc_fUp=&BuLWDwYgaeiYm=&bsziu4ZZq_d_b=&Mddaz_ZjXjpUZ=&LU35ANYhUbibg=&DhpRrWXYrWfhm=&zf7VzVWcak_kc=&AIjDtGWkbfkWs=&J6bHhYVXgfZnr=&YkUmyvVcbcfbk=&IpgakkWsUjpjf=&xB2an_UmgqsZm=&C8N4qdXfUqheo=&pvJ5qcXd_bcbk=&n2fB8zWsmfUpl=&6havuQXjlkUaZ=&n9MZEkWqhdorq=&boZktQXbYhrUq=&uvU9qQZfsZrll=&e4T7cUYqojsca=&IY2HBDWjikfeV=&VWHjYaUohfncr=&aYJ_y_W_Wdhga=&PeLzlyYpcXd_q=&zIGtt3ZbmUess=&aOcp27VmgpWeh=&uVKwbCZdbiZpo=&2HhcCWZUdsjnm=&EsQmajXnncVmo=&5tkHyjYhXllnl=&m9yIDsWasjWp_=&yaurU_WobmYUh=&akNSRuXdjVnsi=&ldIHGJYagUjll=&7LBNMxVVapVba=&MXwNLcXWUYYb_=&XyGCLKWhpdqfp=&Bcpp57VkUbeWq=&5_QOyHXsgmVpl=&V6e2jOZmm_dfs=&2LT4FBZk_g_Wa=&hGnF_5Wdnliir=&x_oSmhUdWjqrc=&scNHc3XVUrb_l=&oPZwCTZsmVWfZ=&XF8ZfVVgsiUYe=&CjUOFuVrXrqZi=&r_RY_dWkelmrs=&cuMJNcVjigahW=&GtnLiiVbYkgpl=&HcwI2IViYqZfU=&Nqb9wRUrgbgdd=&oGjXpiUsWsaZl=&BByWwBV_kVmcm=&jixkkJUZoWsmr=&zbXpzGXbpqlms=&eiUTzHUgnqicZ=&uDPa8xWnZshgi=&djBNoyVai_gXh=&6gpwcdYUmciUq=&DXdwviUpmiegm=&ipQYVNZgpbiZq=&m_8GDsZZjrafW=&rpjt6uUoekVnY=&WoxYOTY_bWrno=&o5_Rg5ZjjrkWe=&HmIO4pUankamV=&tCRcOlUWrfrsn=&TZnA76ZaWeXjY=&nAdppWZnjcqlh=&z_MgwjVfgcnpZ=&QZfIvaYml_bpf=&UhOh5zZeZjqYn=&a69QCmVnUrggf=&kpx5GrZVmXjqU=&X_smfmXpcafas=&7fVFbfWmjZkZr=&JzewPNYhbncse=&nnYlFdZaecbZh=&UAXZCGYrjeqWf=&5gY4DvXdnYgV_=&FN5_P8Xhmicli=&NQnxjzVlVVccm=&msgrxsYllasZU=&GG8tdfYnhYVpX=&26WykzZ_am_no=&TOWqneUbleior=&gNHFnDWlWsnVn=&_uFyHXVYkeXYq=&k_bU5bXeshZcY=&MQuoRgWUmrssp=&HFgfWvZgaqgiU=&kq3OuNVc_pWYU=&DLAQ_AXcaZrkq=&Ypmaw_UiakZ_p=&xysxDmVrafc_f=&6_SX53ZVpWXXi=&IvjgfLWXiqchX=&jhwVsYYjcn_oi=&qUWJKfYjssdaZ=&lo48xuVYWdgqX=&Df9YHdU_mnq_q=&hMeUdTXmiegnW=&bVAFcvZdm_nUi=&rRMa4UZpqgeaW=&g9wbuUUqjVpXg=&WOVDgYXgbmisV=&FBBw7zVjXifcp=&InNso6ZrWmmfr=&ig2un6Wmqelef=&D8RVuKYYnkhro=&O8A8LJV_drsc_=&mI9npaXiaWpsf=&WY3BWRXrZppY_=&FdPclOYrWgsei=&Uu_JE4ZodZkXl=&WRbutOWYg_rnY=&oGRgC2Zqrdkqe=&gWixKYZeYXdmZ=&7SRws3Wkqrseb=&3xZsN7UkijUad=&q2kr35UUrV_qZ=&5rxpWRXcWdVs_=&TaYemRUhXihk_=&YOCp3tZ_hnbbi=&q4PmZEViY_gUl=&Exg6ZTVdiknjb=&P4ZPGGUib_def=&bgzYhhZcdeqh_=&DrmayQZhhWXUn=&TrygwKUjlpfkX=&baoIILVamlUal=&cgsOhWXbemfnc=&UTASBZVnrkUml=&VTdyRMYVmolrm=&hfHkbiWhdoclg=&RMTZHjX_XVUbo=&7g3QxWXhpm_od=&DeQ5F5XdqrcUm=&9JyYuvWlngXik=&sM4SyYXhmor_r=&2Tqr7SXaYiqrs=&_yB4aTWWjcYha=&RXsHy4ZUaYeWU=&InZz5SVpoUhUj=&2Fuf57XjrqcUd=&LdUSdpUYqcYmf=&5NMtcRUZkaaUX=&f8JqMGYYrfWak=&iqmAVsXemgnjV=&U2Y8SQUWUsYsn=&XOJomRUgeV_po=&p_mIEQXiqqkXo=&Vv5PXZWesiofr=&xpUE6jZaWrVmo=&YreKsKUlZiljU=&IjRnbYUfoarVU=&wclxv_XnajccZ=&U35Qr2X_fmccb=&Vc8HDGV_sgkWc=&_a4Q28ZnlVoes=&QbxudvUroWbro=&PXKXgXXbrUmii=&apMuFhYedkeUV=&49phh3Vnn_nfc=&J3ZEUCXkZnXZe=&fUjwKPZgggZUc=&gGEqOtYjUoegX=&3gR4QLUoVUkqj=&cIKxBNVsqiiin=&mEUihfYisrZrk=&8Le4_WXagmYep=&_5hbAcYclmW__=&UMdIRqZjcnVXs=&UKnpf8XhhinrY=&iWZXXBViZhmqU=&aX4VyMUrlZr__=&cbL4srYlZrb_h=&ryVCxhVjUbXah=&u_kEtJXaXoacV=&4QsxcSWj_ifWZ=&_GycwMUrYkqmm=&zL78bvYVUVbXU=&bwccy7WeYrXVr=&AyzBnfWsnddss=&GcOzOdUYWqWZW=&lKEYIBYYXcYg_=&_8FuhdW_ojhoh=&Kc7YJhYr_enkn=&BeCrViZgaepbb=&H3MHguWs_VbZY=&guxcXhYekr__V=&RmysISUddjjos=&JfxYqUZkYsnia=&6HuHaHZqmjgVi=&SqjaNHWdsekhe=&9AXu6WVofsfmm=&mhcA5lZVkrVaX=&znio6kZmYgdkq=&egquEUYUjehji=&svmdkQWbUildq=&NQ8MQQYbbflVi=&7g5zAkZnhYgkb=&42BfI4XpWXine=&ZotKRzXVchpkl=&QHdppjVccrmoU=&lzn6vEXcWnmsg=&qvc4ViVsWoqoV=&mGcvkrXhmXjkj=&Pt9d2_Xgl_Yji=&KtRzmkYUadYjY=&54qPtMWUgjhoY=&CIHe4MWscjsms=&f2WATyYerammp=&uZ_N8vZdkdncd=&zLlepBZXnrpV_=&EIxnouYWmdmWY=&D6YVS3V_jrsgn=&Kb5TZ8Urgnbsc=&mm8isZZccieZV=&MEoPmVUejfVas=&hEmsQXZboereU=&ghQ5SGUrVmajp=&mceSSAYd_manr=&7zUmXxYUfrmZj=&QyY78OUVcfhXk=&LhypqgWVhcnkZ=&Avw8FIYdgllne=&pv2eHdVVgaoke=&g5Jf6oWqjXVhW=&4ZqNPhUVarYZh=&VjQWHuZrrmhZf=&ZFISN6ZfWnpnY=&ZnGLxaYqYrdmV=&7JnrBdXrnjkom=&jNuU39YcWaZrp=&mLQIqgUUUkcWq=&45AkZnUiqhgnk=&YH9kUgW_mkXXs=&WleBvWZjrmmep=&myvP6eWWhbklj=&xG7IaaXdmnlie=&aKSEA_YagkUmX=&VbTelTYaci_dr=&bNZY2SVaaom_q=&WpggSnWfWVani=&abMbJqWdqZcU_=&hUg6F7Z_ljkqp=&Jhd4jHVpbbjWm=&4zrkWbUoUkVfd=&N_mSzTYlZbqnc=&bfXpvEUaZViVZ=&YPgpOLUkf_hki=&lvxtnOWWeqVh_=&7WqnKMXUXYVlm=&Tcb9cpWXjfVaU=&5VqiurYfrodlb=&6mxnB7YhrVnmn=&x_eRvAW_gZmZa=&JSE68VWUsYUhi=&l4GCfnXdmeX_q=&uwyqAoVnWaUfU=&XAogppXhYbsjk=&zaABYeYhYqeVf=&eApunwYppacoX=&abjUryXXkZrYc=&q34vevXrXVdkn=&Ad3y8QYYhsrqf=&zNOX9SVXUcUco=&jY7JtWVgWlUVf=&IcjE8ZWUXdUpV=&UxjnBCUWsYUod=&_2CvcRXZdVehf=&Hh9KSJXshWhrW=&8JfgpMXeZopie=&37eRoVWbmgihV=&UGR2xpZihkYsp=&w8K4VMUUYrXok=&Vx6CTvVZkieiq=&G5Jk2BVWgfomW=&MDnUDjWn_UZrc=&UWptSYYreejmb=&WBzMOJWpXb_sj=&qNdWUQYgWdbed=&OibRhFVUUhcXi=&plYrmCVpiq_nV=&X2U34YUXhbaUh=&hx4vLCVbpqbUc=&eler7EUggVrYd=&W6nnLLVmdWkbZ=&Z7cF5SWoqlXWj=&EhbVXEVsaV_Wh=&LOzxtTYdoahWg=&yV4Tg2ZlYinoe=&sc9z4jUYkanXe=&aRuuWVUYlnshe=&wf_OxeXnjbmel=&F9R4cJVZWcbae=&rFUW72YeZVWfb=&CRGW_XYbpdphg=&2nMzNoWhYjbrV=&cUC2v6ZbiUUpj=&uigmFAYXgrUdh=&nxOmxaYefbkbj=&Ope7uvUVbbogg=&NBSeByZpjffWZ=&jxLbX3Z_jlfe_=&64nrbfZZUhpUX=&H35DykUXgXkjY=&VuT2URUiiXYsq=&hrwSVZXmnirac=&sLafXzZnXWZgZ=&DvUyKfVWYlVaj=&lwAGnaYrqhbVb=&Wl2BbdZffVipd=&mxMczJXh_rpUs=&hiOrb9UorXqim=&zZX4ZAZjaanfe=&gLjufHUVsW_eW=&oJFx_dVpYWksl=&JYzr87XfldYr_=&IGuMBCXjmVUsj=&EIfCHiXpfpbkg=&SU9DXMXbrqklf=&e93FzIVbdsYgY=&bzkoo7Ufmn_bs=&JKjkF9ZqkdhZq=&m9DPCbZbd_cXi=&97APvwVee_q__=&vx9q55ZbXjrso=&CuMsXtVjiahrd=&pUjGbxUbmqksk=&rwsrV8YYrnXhl=&aYrkEhVXc_lpp=&C2bA9lZYfUWfX=&cX3B5rVmipaqi=&Ufzqw9XiXmnhd=&9VTcjYVgWieXk=&86bFLoZmpbUfU=&QDdUHGWjfmbj_=&wBLLkQWWjsjeo=&FqoD2SZfeXUbg=&grzuCLVUrlYnW=&cPZWpFWlqfp_s=&q8_5uYZkZgolV=&lAP3wQVabnYkU=&izxBn_VfkrlXi=&Jw52ERWjZqncp=&H3w4NnWooWdnl=&u5uecoWYcarcg=&JACD8UZifikYo=&n7ajPEXqqpWWY=&4f6yUTZfkUqWj=&j4sHJ6UnUYVUa=&QaoMEPYpXXkqp=&Y6OKPrZmo_qnU=&8y98BTZdoYpqa=&nIooLpZqrZYZY=&xU8KOHVogbYjh=&xo_o58Ufhjkeq=&NtXdOzXsrkUcY=&TztkAiUchefrV=&uQPmonYfcl_cl=&zxDdZrVVqoaYf=&8xyRhcZVUjgqi=&6r__GpXWjoYYc=&VFPXT7ZfglZYe=&lxYtqZUrorolg=&s3gFT2Wfhkrsj=&riT_nZXgjgZVp=&BtczDRVVhV_ii=&SgamUHWicmlZW=&IkuSpzYnkZgcd=&RpX3S4ZYpXW_c=&gkzTNdXpgpZcX=&satfMhZmVoiVn=&EwuSJBUcbYrZo=&7E7u6EXUi_hVV=&l7ToS3UYommWl=&IyNcvSViacngj=&VqraXzYmjgpoV=&gO7v76UlalqUf=&rbr2aaUiblpkc=&IiqkYBWfWlrUd=&KetsTdWbjemea=&8HjNZsXWsWhoq=&XoD2kwUUkfqla=&yJBnObYqjcVns=&YlkNukYVpfgXj=&XYXhNcWUahreX=&JKirt2VfmfjVW=&H9ygWnVmbnaeW=&QNlEj9YZXoock=&FcBLuEYlqfVor=&YQxuavYnXVjWd=&Eodf4KUpcaikX=&66MqHAVWrfXsg=&KXYX3GVZf_Vrs=&c7YSuBWZdhYbe=&IN3a_MYoapdpl=&8GkgreYprdWbl=&I2Sb_sYYnXcVc=&odZsTPVXkcfog=&3SSfUbZsf_jfh=&tHhT9FWi_pa_h=&zTkMqcVgmlnU_=&Vbo3jEUmdsVlb=&7OUbiPUUkZUgg=&D9VmRXWifgYbh=&BrkCxzXjVUk_i=&AWoqDuWWWmpjs=&jFWqkqXfUW_fm=&5z2GN3Z__gVWg=&cb2KxzYqUqiba=&szZkvjZs_jkfe=&ff6EdEWoVYreX=&VOrXhDVZssms_=&TPn3DEZgjf_lr=&sa7ryqUao_cpd=&y2bhNUXbXVWbs=&tcEmF9YlgZWgZ=&ypPEycZbsXYko=&gpmP3fYYiihYj=&TBUPdiVci_eek=&mSjRvKUhWcnUc=&gINOD8YVXrfnp=&s99gFgZpefgkj=&4O2ejeUqrobmg=&S9RQauUmmf_af=&5nWvlAZUiUrZV=&UukM7PZaYjmqq=&apZLsPZjaVk_q=&8W6CWcUlqsfej=&LxDe3oYdZnnUi=&5SXTekXddWaog=&hvCe2AXeXdfdp=&aRxvqCYlhledq=&jNzwLYUdfiapi=&LWxUmuYbfrVXa=&AqZE8zXkZVYjW=&R7CbEfYiaaWbZ=&CppRQBYkkdnja=&ZJCvKbUUZfWjs=&iI2QsLUVhemdg=&wjfVoPXZWjprU=&GLHkOJXZWfqmj=&YzRtvWVYWdjlp=&f2NHlCWbrsrdU=&_avE4pVpWgmae=&SiMRzPVUikUlc=&mhp4VGXnfZoaf=&sf_BbjXWadeqf=&HuEKjNWcd_l_k=&KwgvrJYVfkmmo=&EvtchXZdiobUm=&ZB2smaXaphXss=&mDddBsXlesbVX=&heLAFeUmlnqnb=&6gCM37Zeciorm=&HMGOQnZqr_qne=&zmTVg7Yq_mVgV=&RhWojvWfgnmro=&nb7u54YmXojXd=&QCheWAXfsrcol=&CS2amQVapn_fm=&593Ee8YsqqskU=&5VCoCoUkhklUU=&U8pblrWcZgkjm=&zvRskyUifXZrc=&Kq52OrYsUUobm=&ATUJifWcooXdW=&ugbuCgWbarseq=&AG358QWsjYjie=&C2NisZVYklldg=&h9SdFHXmmk_as=&gzlncfXbjkYae=&RCbf9UWqcqhmX=&nSSOTbXoYdabl=&xhEcCRVZ_d_mn=&hr_irXVioZfZf=&PiRUmSWiWoYYf=&y2p9A7Ufdrpef=&fXjibGXiiZqno=&qkr2FjXmcfils=&eWS5oHXm_qpYW=&Ckr6LpYbXaqWb=&TBp_8HUmZmpln=&xuXQFQXXoYZhs=&36uFN_UjYeesn=&D5qrbUZesdWae=&3pjY_JViWUsgV=&8WetGcVgoegei=&YpdRdTUknYsro=&IIA8GpYUoUYbe=&uF9pJiVZqsiXV=&4d5gWvUWZhiik=&kumKZtW_dqUZV=&t884scUgfcmlX=&vD4ZXHWjmZsgr=&luKnwyUdclpXh=&rK9PfDVWgesbV=&lwMOQEWlfmWdd=&qqbpMfVeYaiUd=&FAVyQLWYhelek=&mwqzf7UprohjX=&Emms6rWssVooc=&fX7p7HZsnkiad=&ZjiA_dUfkfhcn=&Qcflq_UYcpohj=&S544S9YZ_kfV_=&lWS_jYUorlnqW=&HLbm3iVgaUlVn=&DfF7qCWqVWecX=&pQc2iBZkXgcqq=&IAPOx2Uorsdgi=&AhnmlpZjfomo_=&otKogyXYgmfaW=&Z9_QlOZcjqnWg=&MYzYmpYkXds_r=&j7qqzwYessgZc=&vYBFAtVhbgdjq=&KJUMgnWhndff_=&wiSrpvYqfZXsX=&wOjGctXoZofoU=&qoCrLpYqhUffp=&HLvEtSUkZmiam=&iOVmSLXbVmVXs=&Utp9aUYjWel_h=&I7mFbdXZZdhjq=&BEbaduVgnVjgc=&9FZflXXacmYUn=&V2Dtq3YVqcYom=&aIqIO9YqdbUaf=&4D8izhXeriZWj=&whosd3YfkjdrX=&yOssokVslqnee=&hMmljHWmkbrsj=&Z3R2peVUfZVgl=&rujepZXajhYaq=&FspbjjUfZ_rb_=&lnaximYhUahhr=&vCo32CWeqrrpi=&H7PpPFYjs_gmb=&zYgGMMUVhccgY=&qztEcvVmrqdjc=&EH6IYBYoneXq_=&CkSH2tZncVhZr=&ZlScy9XoqeaoU=&9jLaVSVcoXqgi=&_XrAkJVlsXaVq=&9wY9ENVqmZiYY=&RRec2FVsimigk=&jyjarCUYalZsY=&Kz4x6CUbjllhe=&CtMpBlVXlnfZp=&rvnhTtUklncUb=&iI6_NfZnhZp_p=&bH_gCIWUXrjrn=&9zBvaVYqVa_em=&wHS3mAVmdierh=&V2qT9XXU_cjhW=&dyRCuyWjaqnWp=&QNJbQCVogcpfl=&7_lji7XZgmgWf=&fT2cvIXlnhniU=&TrtZKWZZpjcde=&NBnmJRZZooiXd=&2tk_W8Xm_ejWY=&AVG_BkUfZWXek=&D9lEZTYbZkmZi=&Qzc9haZfiiapm=&24CqHEUsqsssg=&Z6PAp_Vriigfq=&fkQQo2XUYqbWl=&sZnkFKYfiYkZo=&5AZq49UcaifUg=&OLWhsuZVVhVqs=&KAUgg_UbnncVZ=&sCCp8HUrqZaXd=&V8cHdPVngrWYr=&ImtHPTYjachcd=&t9kahKWpskhjk=&VJ5RNmUX_kkZh=&BhrEw_WsbZqom=&icY9JtYidZYhs=&ii_jaRUVgkksc=&RPaPdAYnno_Up=&MGhXgPVqkqfem=&uHB4BtVnasjiZ=&eWxyk5VrVgadg=&UkAx2PXapgW_m=&rsNCyPVhqpWpq=&NL3ApYVWlWqis=&tOxSt2Ydlaeir=&7XHQBuUbjXc_n=&sqOnoeUggrlsq=&qKNOsAWnhemXb=&dzTZenUjnYcYU=&D_KBP_Ulcopcq=&5RfGdgVVkZebg=&8LaTv6WkikVlm=&vzlA4xWpXVnii=&44r4GBUVooWlm=&l2yF6tZoXeVcZ=&TO3IchVjsfgUe=&lnqHouXedqsYY=&usrpWTXfXVkdX=&D5X8TQXjjajbi=&YnSWA7VmVajXY=&GUmslMZpcnjoU=&82ER7BZgjdfXe=&ZhU5DZYhfYXnV=&LRA8VDYeUkdkn=&yb2v_pYrYYVsn=&oURfRXXYpeYlc=&vea7pvZrUnmZc=&kQ67jTVkgerYe=&sQwWxhVhogVWs=&tQls3KXrdZiZW=&Zt4MWuYdXmlml=&OUSxHlVoj_aka=&8uJJdNYekhqWp=&cUtZ3jUlobiZd=&l6My8xVXeX_rX=&CFoEroYYZnUUd=&ToZF9UWqqqfeV=&YNixnqWYmcWVX=&tBQZntYqpascp=&SqPF8NXcVZacU=&Z9B_5mVerUeql=&wYXtS_XqeYpcd=&SStjcvZl_Ypsr=&MnyQlpZdiaWmo=&J3oE74UW_pgbd=&pl5vjDYWhWViq=&HbUjNYYgUdcjX=&AlTLWvVqeZcbk=&w3FGh7WWhkZiX=&voANxDVZpVWba=&PwsDNSUebgpc_=&UmcSfaUmbanjp=&hAQdVUZhraV_k=&3ByH8_VaWWhpr=&ACpmOeVommkkh=&J5dMWHU_fZkhZ=&NYF_dtUke_haW=&QTPZu5ZjnjbeV=&K5r_vrXsaoYif=&ycbmTcVdXg_rn=&W6wMzGYpqUWjj=&MlJaSnWjcjlmf=&pkkYRLXoWiZnZ=&fnFb4pXcosmlh=&bfprIOVVmonoi=&TBmFp9WU_UbWs=&jfqQftYZgibfk=&DiAH5eZfcVchZ=&hZWIPyWjdsUfZ=&lyT8SaYZsjaeU=&SpkEHyV_o_dYp=&YujzDlZdfifbW=&g9unvuVhqXhZo=&truH2jXUbVeWf=&e6xyTkXpYfqcZ=&3bNOFQVXYbnVh=&t2hfOtXUqokep=&lQq_mAYarXdal=&zP9SigXrihoqc=&3U4TNtZdVWihl=&m_P9YBUqpge_k=&fpPu2JVaeWVdl=&YeWHHaWfZZYhn=&9vn8PwZhZghid=&DlAX4GWhgqfjk=&bzRoWTXnkobei=&XBReOkXWYkqbU=&_UP9YcUjqUhbV=&bft6aCUfbeWsr=&h6b9XgZjrbZqe=&zvdl8CXoh_Xih=&oN5RRAUkYZhcW=&2CnFwGXgqbbdU=&ss5vvrVWacWps=&zzc53YXbidqfl=&FyEPBYUplbnrd=&JiyZHDZmpdYmq=&OgC4LWVZbXqVm=&ETZT7ZUmbhbhj=&oKl8QVZagZZbi=&nNmNEDXWidiep=&vY4Tn5XUYd_dq=&3boF68UZVmrkW=&KMncIEYeVcYmZ=&VHO6KsYl_gXhf=&RU4nmUZYosiha=&kLH3ORVcjepno=&nULElWYakaXVa=&3cFRJHVfcbYXb=&97q_d5VanfVae=&lU2_jaUqVVbVW=&qduLWiYnkjqaZ=&TOQGfCUbbhWei=&ugeMgnZsgfVXU=&Dj3mbtXporViZ=&GmVhHpUWdh_pq=&AjZw5mV_lipdr=&foBiIpZisspfV=&vCwxzaZgecqdm=&RZFVbcUZkcnik=&hFD9oFVVelUdZ=&24FmcJWrmhiVm=&tx2hoaZmhkfpf=&HVP5vVYWYsqXl=&vIhyAYUUmafae=&E7qoOWVUdgprV=&CgjEZ3Yqiajqi=&7psmXaYq_dcbr=&ii8hG2XXoUcia=&2WvA8hVlVUXlc=&93f8DUWmYYeZb=&fNVylHZqmWWWb=&gglqQUXgbic_U=&_7jGsBY_mncpr=&_VG8_5Wa_laUc=&KdjBB_WkbXlpV=&622_IrXjhrlok=&rlXbC9XjV_oUU=&MIkbH2ZjmckdV=&oS6g49Ynjcn_s=&o46GnWXaVZhjh=&P3Cp7_Wg_ccad=&wEAPR5XjcdbWb=&_IEHmgVohqlsj=&q3RPbrYmYUrqY=&lhrNuDYpklXYZ=<iM5tUsjnqXn=&GryYwwXj_hbhf=&u6ZUVeYjlYYZd=&3s8haqZUVfsrd=&SY5YM8XkombXV=&ijjcwIUnrVnZo=&2YkBpDYblVkUi=&ROJTc9WUZWhak=&4YaIwTXXjhVXd=&dFZhEJUUWicki=&47rs4TWbldUbn=&Rv9IYAZimpWUf=&vAvyLQYkmbh_k=&7rOzP7Umibs_d=&W_X8RgYskbjjh=&s4yaajYqYnZlk=&NTSyNnZ_oWf_l=&uffyOGWViVZqY=&hIKI_WZgarpZY=&tlOMeUUfelWcd=&MvfffSUkjdkWl=&sVNjzeYidmqgs=&ERRcGUVfiofbX=&Nl85GfV_ehbsq=&oWEob7X_aZVkV=&XeynNAYdscqVo=&2mBfd9ZqhfrUf=&tuirViYmapqaj=&DDhHvdVhlfUfe=&yLMLmWUbqeYa_=&N_e7j3YpfaYon=&nPwdPrXejpZbf=&xNzsncZcZWZ_i=&TAfbJbZib_bsX=&rakPbhUqggYh_=&ks3SinVpfWhgq=&HjGYOoWkkWUpi=&qJdPJzW_YeXgr=&4FTA3xZkqglng=&SOBrTCUijidfj=&IrXWuuYjg_qe_=&ZsEcsiXeaYVWm=&aMW8MaUnYbqfr=&M6nrAwXnnjaes=&PLk5_AYUUfrqn=&GX2ejeVWWfejn=&u_LxRsUfohoXd=&VnNg7YXogshbj=&Taq5vWXeipY_f=&alIkIeVroWWXh=&MzqycHXafjibZ=&CoElIIYoUmlds=&6PWoZ3XnsefX_=&FPtjLeWrdeknr=&PyeT9hWknXqdr=&mxaaJNZn_hreY=&_RRaURUfjsfan=&xb77KsWfZsf_m=&LJI9SCXbdgXr_=&vHYARaZ_mkaaf=&DXreBIVfYXnaj=&wu9qCQXq_spsn=&dGhuuqXogbqfm=&hbHlUEYXUXcfm=&v2sBqMYXkrVYj=&f6_b9aZWqXkWe=&ph3R4hZfXpbdk=&hdxfsVVfZ_gmb=&vLFS2mWeddjVr=&DHtHWiZhhnq_f=&DGDy5jXWrfYWX=&DMQMpVYUchp_U=&iobDrNUghYbZY=&NTkmzaVpajanY=&p5sL57W_rfWed=&fbqaJZVUd_fis=&IyGJoiVqfnflp=&g3upDLUssmkmc=&ygqImUYqhsUaW=&J96ni2Xccllqc=&_UjxcaYcsbc_q=&6WX9g6XmgbWmq=&SnD92hUer_scm=&3eILXnXc_qcon=&DzqEQcZjneWgm=&6XinBTWiWoYdh=&eu6eQpUbYWrXi=&qBHYthVqgesqg=&W8V6AVUWpoomo=&fMKoIPVVssWsh=&TaKrWwWoqfXor=&wyLuDkX_laVcU=&KU6i_dVVfni_Z=&7FBAKGYWdXbUi=&XXuBHVWohZdXs=&XfbpEqUeUgsbs=&6mG3jbUjfgogc=&Uqn8V7XcoihWU=&M9tyKSVj_erid=&5JPwE3Wbljmrr=&RgCXm_XfbZarm=&9HzMoKWVlofYm=&DUMb5TYYpah_g=&v5sZQCWZgkqmU=&Zq26rBUpoXhab=&Q_8u_MZVmsaVj=&Hgv4IlVeljarX=&yjKSfpWnihosW=&9GPGGMYifckoV=&A32XjeVgZjpsq=&_sMxiJXhbmYok=&nQ8an5WndVqfk=&xC7QQzVhVrkVa=&T8SOXxWnoncVc=&sFCXUyVgmrcjc=&VxoGBnYgWiVkU=&h4k2SIXiXkcrV=&rSJyHmXbecrhm=&l77Y3hYbsbUXW=&OMfqUkUhg__Z_=&rr83MIXifXWda=&Jl7kfrVXoi_Yr=&qGjI3BXpompsW=&hJb5McVpanmfe=&HlwFYGUlgYlph=&DZDt2JWk_njpa=&rpPEaHWbiUmki=&dJzsQnVVWjoUo=&OgcWi9Wrdqbc_=&_o7vN3WhiYjmr=&3NV4gdUfjlgc_=&nTbH8sZUkqhrl=&eoMkbhWkocYkb=&Qjc8GjZWUeXXX=&PtDtk2VgUZkss=&zD3DjGVpXrjYU=&vowikrYehU_qW=&dZgZudYXYgiZp=&soT3NcWbXkc_d=&bN26evVUqUUfo=&gIzBRUXkoacXa=&57RtFaWfg__VW=&mKu7DtZXbUUsY=&vITBaAVfrkdqq=&Jy_EQTZjZdVaW=&pK9YnKYrn_nWe=&DUNWATXshpofa=&9hNe65UboYilY=&noEvwcZncjVgd=&BE9rS4ZjiendY=&jjLTepWqcZsbm=&HTjKzeVo_sicY=&fZKhjnVWcXYiU=&4bVxtYXViWXdg=&PPGeRoXahikZn=&closKKUrndVVZ=&HNDHl_ZZdYmhg=&MHaXmRUkqsorl=&RaF44rYUXXekW=&wRO5cNYohWaeo=&KgbbJRZrkpjar=&5_QsiiVjWVgoa=&SQZVjxWodhali=&elPgaWUsmr__q=&XAI4WFUZgoYhY=&OPkLFxYXmhgYZ=&rtduAiUbgbrbm=&LFYX6UWXZsljj=&I8E3lRWfmsigp=&66DegGWebkgal=&Wt3ty5VlspseY=&26bM9LVeacXsh=&I8tv5HUoVqljq=&hhvubvYakahjm=&PJipZNVmendbm=&XHUlR6XolWnrk=&2OXTDyZZeglUs=&mjywkBWWYYjhj=&NhmmFtYsndogj=&6OGbeVYiZebph=&RnZ7oVUhobYrY=&JUKgNmZUgrlke=&UBVOLxWjnVcjn=&2LAcJ2Wjoqedr=&sTYFLXY__WZld=&JwKw7fYa_iqcf=&KQeYWsXrbZgoj=&bAQBRNVkioUco=&98L2jVYYgYkqc=&n3_pOPW_rlXje=&26r8dpWgfYnch=&PQbDNEXsUfoUf=&ZK2EtaV_clYei=&pT_iOpVfpmcYl=&4iP9F8ZYVfccY=&3gethRVb_erfm=&QsBMcfVhdhmZm=&fLlOvkWmXY_Ue=&_Vt5zXVipZjrU=&FhVH4bY_oV_nX=&TtZUb4XnVqbUk=&CBU3FtXeYrelr=&PpOTXyXloXUZb=&6z5LVdUiipjdX=&OLdEoeX_VnZYl=&99fAdcWojnfbl=&UidiHKYpfdc_g=&OhhJwSWUlsYqn=&BWza9gWUhdclg=&eqObwnVgsnsgp=&OIkAcJWW_gaia=&jNsUJaWfkspig=&btjLyBYrgqWcf=&7vc8EuWqjmVej=&dnkdoOVnWsf_j=&Dv6H_XUdsnWak=&Ur9LrcVkmbUiY=&N2UAjNZiecWbf=&JkW_thZWjasme=&XYlraTVffebUV=&UW9TKyZmdbaZo=&RMhslMZacfVsh=&4UHHnaZmemZZi=&uTMwCQVcrgaas=&gWTTOZYllsacq=&qftaoVVaedrsn=&bU_dDLUbbqhlZ=&q__wEcXkimsqs=&nZ7OjgUclhZfq=&OhbG7hVecVmdb=&jVT7CpYbbWVec=&w26F9iXYriVlc=&tt6Le8UinWWXa=&5Ge_wEYrXnrWh=&kYRz9AYlrnWgW=&IJP2RnVZgrbY_=&XF8NgMYYfhers=&UXUiZMYp_jrUi=&y5R_wmUXsUop_=&ULPuGdWajdsbf=&UwMoMQYahZps_=&ldbtXPUdafcYf=&hVMZeRYeWcVos=&HbomkPXrkaU_q=&N8yPmXYfajiZm=&s2tfV4WaYWlpU=&fIYXvZYrlVanp=&iQBg3sXbqXsej=&CgQ2z6Yejibdh=&RGrqWdVVmhhgU=&iQnkT7Wgnjfgo=&wNKNVnZdnqerf=&vPETBgUrlhU_k=&asJwDvUmVUmmb=&CDbrCmWlWUead=&7JCOHyVXfbnmg=&JKYvosVhYeZpp=&RNmtwwXqfeqlp=&VN4ZauWpqVo_Z=&wozMWcXYcgnhp=&6odu48WjZmnaa=&ZAyeFXZVWXcle=&qsn9EUVadWiXd=&QzexmeVjjjZbj=&yZ7OY4Vpfsrbe=&2o79aHZgVmiid=&hspxTzX_rk__s=&nD6V7AWsnfpWU=&etSAEeYqgjjrZ=&3IPdnlXZW__iV=&BRPDFXVWqohrY=&GeR2fDWonemg_=&b5IwUZZlbkc_W=&HPpSYFZZhXbZZ=&cTPnLSY_anlUl=&Bt_tLbZefUlin=&_T6JBKZd_idrn=&CVMzzdVrfblVf=&TzqHJBYYWqpZs=&Ke87lxXXWohap=&DxunC3VnXcndp=&RffzBjVrprbqW=&9rS2DjYe_ifks=&BSzkhGXippgZ_=&5SCG7TVefWUcg=&BV7CPIY__sgbh=&XececHVeWbhnn=&dgPsEeVmnnmnX=&ItGcZ7UjbUbgk=&3M3LcqXXhsmf_=&ZDhhOpUXeorpp=&_Qe2kQWriiYVW=&KWVOvpUmnioVs=&LhQsgtViaUbhr=&yDXAwmXcUaYik=&3g6ZcFVUVohsX=&w9LVvNUUpZrka=&dtA6zMYhhflcV=&TR2KQkUjgVVmf=&uyLC3pUahlWVa=&OLjdAgWYphrcb=&wyQZ3nZjeaaYd=&pJtk2nUeklWde=&dd6iEuXWYpees=&_qrlR4Ym_rbhU=&FabpijUWijpWn=&sb2JpoZgidWar=&OWvO8_XWWjnms=&FVtu9GUefpnej=&IRkY8jXjqYmaq=&RgXkFhVgWXUUV=&llQeVIZY_nkdh=&GMpVnTVoraqdg=&UjpEoEUsXlgaf=&_SIj32VsicpaV=&mAnY_2UhX_arW=&H2D3ioUr_ZZ_V=&NDqP8KZnqebZb=&xfv7JvZcZofWd=&axq7_uZiVlqlm=&g4Tw65ZckljYb=&dmL7lMYchqXU_=&DbFshLYrrZooj=&YGFQskXjskikW=&lwz_GbZgXaZXY=&7q93BIWhosdkq=&BWsGx2VejVrqW=&9xQuvVUjZWkrV=&Zxm3IWXhXZgXo=&C3SXQbYjZjskY=&EyQkSVXghnZkq=&R4iNatUimfdqn=&YQcQjyZchiqnV=&Wz87ZIVfp_XeW=&dCHPOMWZqZbpY=&xU6MHSZranjoc=&viTs7NXZd_gkd=&3w2ZDpYihnUsf=&YHD__oWbWijnU=&HFvFGzWrjaUia=&pKEmBKWYjVioZ=&yK8KFfXnmoYmk=&RZY8bbUXWrfXq=&U8VkwXVWYjqWk=&ZzysgDYjhlYZg=&uaxCItYXcbgUh=&woHf_qWkUfYVd=&Ga8BeTXYsVpbc=&hc4UkXYfldqZq=&ECFFxOW_cqgpn=&xJktWZYmhaadh=&eHM5e4XVeVijd=&lE8KtjXrqVedZ=&7JwMT4Yffkcas=&Sw68UnZsWhUbp=&TVSx3aVf__YsY=&QXzkh7Ugqfidc=&PTJebYWarWYY_=&bUAIyDYXrrbkh=&NegK3UXWrejfe=&DaYqI6Xo_Xnmk=&fcgpCmYsUpee_=&SMdQfUZki_aqg=&7BPDA3YZnZ_Zs=&vnL9SHXdeYlck=&ms6XyqWfUqsWi=&eB9yWOXargcU_=&2FvIb6ZnZb_oa=&tYYQWQXmro_im=&tQz6nkXeVjiYa=&AC8dkYZmdheai=&5SkEtzVUmeoVV=&WdBl9bWkglees=&vVu4t_YciWeja=&K4X5nJYbiYk_i=&PwoXEDXYfdlgc=&j3GlcwWnUcdsp=&2HUCAKXYhqjiq=&8VVtbMVnbdgWk=&bBIz7wWhedpXc=&XKtAmTY_rgjdV=&G5dKzDZbrWoWn=&nZLHjAYlgcmkf=&84RFPYZj_l_Vg=&LdRsTWXYrjnij=&jAjUQLXUgoYrU=&BjJE4hYjrecrd=&AeHY5nZaqeViV=&v9roRYVlsjjnr=&xbOUaxZijfWYn=&vioBWXUfsU_eZ=&tCsTMAXhVnha_=&FR5tG8XplninU=&q63UcPVnUephn=&CtrB63X_UsogU=&9zTqNOUmVhofZ=&O_xrvRUrkmoiY=&ALMdscUXYfobo=&LZ59HjVsUorsf=&wG73I5VrkXUqW=&pLGd9WZkaiiij=&WkwjvVYkdc_dW=&VQrvesVWlckoc=&bktQIhUbYWnpl=&AJMCvcYVWZmrk=&ILj7lNZphXXpj=&u922AQXsarolW=&PteMdBYahZpWe=&cOk6HqYcflUWl=&q6PqgKWasrWVl=&YsaVhLYbqahjh=&WAc3ITVX_UUln=&3dLS2CXlk__fr=&65Gph_YnVbrhp=&XDBSCdYXVheei=&wTx_LjYkmZkhX=&lp8JPCUldfXUY=&By92DPUVnjUfd=&5A9exuYpeXVnq=&toPZF2UrclfoZ=&pNzNRcZ_lgdle=&IHKndOUelVhaZ=&sQjOmMYZYgihk=&GfeBVOZWUXcVb=&icx6RhYsmgagb=&VyX2PxZiXY_aq=&kZV8MvWeVfops=&fVaX5fXijajfV=&yxCaeKZWegfka=&eKRvEgWYjXqZ_=&sXtnNnXrcWWbr=&i77MXjYcleqfh=&5iIGugWiZcqnV=&hnV_7jUec_qWn=&w5xf6BZneUXec=&C5G3ekYhnhpcZ=&xVpSzmVXjqVfg=&KtsAjbWUhfUZj=&MXqEg5XfrUXaa=&O_NxYhXkalo_q=&c9kV9xY_bcbZY=&7wks26Zlbmgea=&GJPBwhYWl_bp_=&bPPd5pZVfca_n=&oO4mEjYUUkalU=&JGIXYVY_fjaUa=&uzf6shWdebs_Z=&amSdWrYY_qfdb=&T9QDxcZnfYid_=&jQfrxvUmqaglX=&ZcvRUCXeZlkWX=&W2gWM8ZVoVVYV=&fepDymWYfjkWs=&2DRf2rYkrXacZ=&xGahkeVcYnr_Y=&TyGkezWimhnmd=&jDUZ4EWrrYYsf=&qUD53EVkWdbij=&CfP9xXZrlqimg=&yJEsgoVfsgorh=&KRjWiIVrhajXq=&OFXwErZkjUZdc=&X7oFCOYmlZcpk=&pPXYrgZhsolkY=&adLKjGWajXlsX=&Rc_w3aXkciaaj=&xM3eyiYorcZlj=&FZK2xxVrUhZmW=&YROCidZlsVXih=&PxMPQnUZcZZcg=&PtQkwMWZZf_hf=&Ivfm65UnmUpom=&_jzNzxWUXVgbn=&TQQka9XVfZcia=&VxPj9uYghUqVr=&f_TACMYsnrgYZ=&ZAP4BSYmejpqp=&Zh6FOWWrjiiqb=&Qs642lUfeXZec=&VQ4GgkVWaWorf=&TRY9_HXejirlg=&3_atvXVeqbs_g=&lErihgXUocVsW=&uKIj2iWU_rXpq=&OJc44LYZsUehd=&GSJRPFZkWVehW=&a57346Zmrk_ha=&jEGOhyYokmVqa=&8_nQqrYWhoo_Z=&TalBm_UsVYmbe=&6IVqqLVUjbWjm=&XxcHrFWhUUUWf=&e4lciqVYdUiXk=&2M4rTCUargZ_h=&aZNBIwYYmeppm=&dkoOZsXejpenV=&r8PXxvZZdenUn=&OC2wAgUlbWlrk=&5NwnOuXcfVamW=&ybjTkFYmYU_mf=&7qaBklUWpbegl=&7J2e8oWZ_oVoc=&EmTYdRVeVgUss=&7fzJhpVadZUZg=&mEvLkMYYUgdrj=&IUkfqrYpmXYoZ=&GrB4FBYfflabg=&Cxd6UQUYpWbrX=&6URZTZVYrk_ei=&Ci6tbPYgibVli=&QlNtiVVmbfkbZ=&KtsNe9WhmVlnn=&C7ZfXAXiUelqi=&pIFcRkZpWlmcj=&EibMq9VkheXal=&tNpBIJUU_hXph=&KdUKcbYYmidnn=&QZO7jsZlja_fd=&EXrPLcUargZfo=&BTrs3PXnnic_W=&tOKyt7XrXhWf_=&wTyYBcXiZcqrs=&AH4L2VWbjjbY_=&RGkhoOWaqiYbW=&63GqkjY_lhUWd=&vE8ccyVkrjk_k=&cKS9epXhdUfgU=&u7kypmVqdWnho=&UthmUnXpkigek=&f7MKUdYomgchm=&4hq5qdYh_Vcai=&RjCBmoZfVdfpW=&SoBP48WsiXhVa=&tpqAZlXbhXfiU=&vFYyOqYjpseXs=&PxykUgUsirijn=&4O6O9OUmsWrlZ=&s8LFgFYiioplj=&TFHxt2XUsajmh=&BeIvNKXZafa_l=&SVeiNIUrraZdr=&cMCPaKVnllohl=&JdGStaYYnkief=&6ImSdkVsklqah=&Oxj8OhWpbcigb=&NJdm7nVafdgaY=&RAbyGyXrbegks=&IEBKMQVihqYrX=&DIYBSBXamiXUY=&RFJyyrWcUVhd_=&7NIzzgYeV_clm=&3It9EjVcog_gg=&FdcJIhYgopWbX=&vaDCwcWUlnign=&F8fFa2VkoVjkZ=&Zjb7V8XonklmV=&wJeQWOV_Ybfb_=&bNJF97UZUseWU=&8jzSOsYalnc_o=&7yOxDdWipZWgq=&NE3xPRVfohXXa=&4ghVscYkgsqWo=&txKJFOVhZXZVr=&kLPkVAZXk_Wie=&h9ZB6RVmWfdiZ=&htw73mUUmgmiV=&gmlHGPWcWihlg=&DZAU88XcipnmU=&N9PEB7WifrpXU=&lHKzqpZcmXcUj=&6LwTG3U_frkfj=&hRERxyWcjcYjh=&r2xDHbYlrggkl=&2XxLgDZXhXY_e=&qOQlBvYbodjoj=&GSZOeDVorU_ne=&LdEbXMZjgsXks=&A9Mvk4ZbXcfXi=&ngRUGRZZicWsW=&rrt6nTWVZeZas=&qzmSEgWiUbbpX=&7o5e4EYglWnqo=&huXBiPYoZfsX_=&LgOmC_XVqkkc_=&wRR2KYWjliWfb=&RauTprUsmorYq=&NKaKEUW_ogkY_=&YhwyEQVbjVbr_=&AaBpekZmoXhdf=&DqhfOFZardcYk=&B9jNI4Zkflpah=&AkFGltYmcdq_p=&4mBFe7Uh_fWXd=&QkV8zLZpUlhan=&Ya7Ep_XkWgdmk=&27unn7Wlg_nhh=&Ld4px2UhZmnUU=&9HTmfuUmVkVjr=&Lnv_NeVbUVmrn=&u_g_lQUVcXaUk=&S4IIqKYiUqhha=&4zGKSdZqgm_re=&JEGwonZXlmbcd=&xIsPlsWUViskX=&_GjZBmVVimkbX=&n5gBtFVbfpanq=&2qHa8QZcejWeg=&XLjEZbUqmoajX=&dduJI3ZUoosgh=&6TfoEqYgrgipW=&3joqwsUoVq_bg=&vkSbC4UUWYomo=&XKcOPSXVaeYdi=&mCrm9_VrhrXqp=&xh96ZdWgimXhU=&lNnXgEV_qdgng=&K_mgMbZZrgefs=&WM_OMUXiUYVdk=&nh5aE7WljXjep=&59ezVCWqYnqa_=&IUpRbCYgZf_gk=&NTw5UsYjrnsbX=&gzVviuVdilYiZ=&nYlqYvWsiklle=&g6vqt_U_gddhZ=&AEoTDFXbrjrcX=&NpuPQ7ZmVbkgX=&EMuBN2XicmakX=&32utKpZnmhZoa=&rfmW3KUppqhbf=&kWwla9YiobUde=&DcPbAzVfgWljb=&CFpYWQYnodgsV=&_O2VKPYbsms_b=&tQFeZyYrgamWr=&bixbQgVmkakor=&K97dO5WoUZlXd=&xHLJhHWshUimU=&y2jK6BVhginbh=&k5aZCWZhZecip=&Rcf4bBYmjZcVp=&ks4CjGVfbaleV=&Ume5KqXknlWbd=&2RMEhYXsrdakZ=&qI3mEcWkpUioi=&ayDceYZobr_ep=&gHwcj6Xfbdsqa=&64swFSVeWoqfe=&EzTMuEXpdWWs_=&LrTcNiWcZsknr=&ShgJLqUUhc_ob=&gbBi_dXisilmi=&C5Lbf2Xhk_i_h=&XRNPCbUgYssq_=&GZVMaDXeYUl_c=&pVo3zUWhZXkmp=&edJVEUUppjqXq=&dAQzuTVjienfg=&TocXAaX_pbm_U=&crRisuVVkpoYq=&tuvKxgXjfjcqc=&bOLok5Wlaejbe=&s2aN9rUahshgU=&fLlnoVWlZsUfh=&dOYYNWZdjYdbe=&kFevSxYgXjkmm=&NtGQGaXU_mlcf=&FbaLgYYknrfil=&uV8TWEUjjppaq=&PptjdYVcXUphg=&VJDQR7YXZgnge=&TC38rnXrWkWfg=&CjYGxMYlZaqYf=&DOyLxpV__oUnb=&MCwvTXYcksasW=&ShuCYkWZUmpUo=&VQ8hHnUjbhgcb=&56mJikWrUV_pg=&NekhUOVobqakZ=&OwYKzcWcYji_p=&hgwkKyUUpUaZY=&JpOlL7ZmnVUq_=&eO8fM8Zfpjorf=&XhVr_RXWlhosX=&KDTBfoYkhkjj_=&8XoThWXlnkeqk=&xXZKxgUrWUfVe=&lnoSUmXaZnjoZ=&JZG5YsUgUsisl=&frrLqIWagggni=&Kg35ZhVeZhlh_=&B4gTYeUsdpigm=&a2jJnmXkeYYYq=&kryr4bX_ijsmj=&SrUZ4nUX_Xqeh=&IaK4UKYqgalkb=&XPMW_hWWlbcme=&ItcbKZVbfem_p=&kFlNPsXqoedin=&AyKLSHVWcifnW=&SuKrRWXphikXn=&MjlAG8VYraWia=&puLqUEXdiklWm=&5hrIXCVXWZqps=&B7ePXnUXWlefi=&bCkum7Znjl_hn=&MVcISIWormdZh=&r6xcrWWVbgfdp=&cDVYwBYcVqmde=&_HhSmgWkZ_jlc=&cEExhKZrljXaq=&4KDymRXelbkcf=&UrolE_UdZkahU=&3Sy3g9YqXimln=&lZOnA_WUVasXs=&eoQzmlYdlUgpi=&LxIFUjYemecZs=&IZLFmGZlqYdj_=&p35_QCVpcfbrf=&CgsU_zXq_sjqo=&I3DtkVZmXgUam=&iYCLcyWVWXqia=&rqcjFaWrbefdW=&RwN9kYUYnXhrp=&EiwGbLYXVVYdb=&33Ab4tVasjsWa=&5NkCWcVqrUdZk=&tZn5wGXmogUhW=&dak_RhZlXgaef=&2VAoKTWWmdfek=&QME8jTUXbal_h=&PwQSORVqhZdjY=&HwLngmZdldVXU=&DXceqHVXdYVhp=&xcwAkjYXgsonX=&_dIKBOUXsdeYV=&eZ9zhWYenXXnk=&7m_WHwU_hflYl=&oBTeBJYi_ji_W=&2o3C8BUfkgjXl=&t_r66sUjrdlVW=&8mxcNoYbp_lX_=&YpMxMJXXson_f=&fM3JhmXjgo_qi=&NFjoDvVYfZXoW=&j_sPoNU_ojWVo=&w6D8kRUggoklo=&No3C58XsrgjcW=&8hRClmZecrn_g=&haNK9tYr_gqd_=&AYfs_iYcleUYp=&2wFRpRWoXqhXn=&izqVd_Z_cenUY=&SBPJ8BZjmabhW=&MIKJT6Ufnkanr=&LCMddoYZZiesq=&5Bij7XXakniYe=&NYExx9VXslfbp=&6BNpa9UUmjaVr=&N_gdtbZVasfom=&eJ7FpPVsgcUse=&5LSxwvWqUssWq=&isKDYFZ_spXsg=&oSgxJKZrhoY_U=&uvBYvjXVYZpbW=&kDsAkPXkierfi=&XmKBbEVXWmiph=&waDFK8WjadmVr=&omkN7sYkYnepi=&F8PyUKVbUgeae=&CXo78EVdXsnVU=&EdCKd7XnW_Zkc=&QpCz2WVme_mYr=&4VeeJSUlimYdk=&ikRGlTXeZeUYU=&t4jn7nUdegink=&nkG8N3Whspncp=&ZLrBgLYecm_Zr=&vlBLFMYjajjbs=&SMYUPQUhcmdak=&jQXdnFYegmhsb=&MZ4rupUnXigmp=&PGQnypWmepgVU=&3IF_8YZqrUeVU=&vsvytFXkpnYko=&JPG5EsUUhZhoU=&yxmA9nWXpsp_U=&2NdUETWqZsUXl=&r3DrOVUgUXjid=&9Scy6dVjrcjVi=&cr5wltUpoVlZc=&HWUV7ZV_gcdYg=&StKEsgZifVVeW=&nmtl5LYsZmVrq=&b2ZZBFZkmcjWb=&BSlyLkZfjZjaj=&2KrUQRVsfXVeU=&4MxWHtWbjprUr=&zhloIyYfjfnWm=&CCQzwVU_UZZbY=&PVPZ_bWfmkibs=&jeqeTeVfXnZpV=&I67lXRYcqmhnb=&BdUoiEUpeZXdn=&VXPDLEXYVfXeg=&FeqwsXYoqaanW=&5XXupeUjsjfod=&KwycV5VYeUfmi=&_rmYxNWXoUmV_=&htpUu4VkUsgZp=&c53fBDVUUqUcj=&rGEschUc_mlrd=&iLIG_uYspeYel=&ydzXpjVcWlkk_=&sgLTM_Z_ro_gr=&fTubwTXd_VUYY=&t6pxMUWUXjire=&BGwNeCY_mcldh=&ApzdHWWhU_Uck=&mO5epSUniiiml=&p5M9ENZanerdd=&Vz4pIjXYWengc=&NioxtbYoieZmq=&GZWcfIVXYmrbb=&fhnHToVehk_VZ=&HJm2mDXcXqniW=&F59FfWXbn_aYZ=&2FdYfVZ_XWbUj=&PXzQSbWn_knkh=&5KjE6NXoecVhj=&ds42jKWYfdn_Y=&B_eC3EVacq_ij=&8cCtY2Znklnrh=&oc64CIYoeke_h=&fOTqE5Vabhikc=&IrABzeYlecYfm=&G5jy5dXcoWYjj=&5TnSUcVlk_njr=&ukxEHRYqcb_on=&qZoQt8UdibZ_V=&UeSlYjXeemZVe=&c8HOurXYVfspa=&2i2f8PXpX_apk=&n85ypfZdamare=&MzQtYOUZisceq=&x8R5JxWhnYgUU=&h56hWLW_rcpaX=&AO9uR9Wabrcgi=&wX9g72XhnsrpW=&CHHiqSZYoZior=&wCBqbCXpgWgpg=&grRDVEZZnUirV=&znUM6OXVqYceg=&uySfKAXmqUhia=&7l__ptWdhnifc=&9xA8vCVlolors=&WXIGIsYn_agfY=&qC3M9YVacdlgm=&wjBdEAXXicqoc=&mqXOsQYZVaXfm=&QZVMv4XgWkgqe=&mdlFRnWimXroa=&yucGVvWmkUV_c=&a5LUQQXnar_ji=&RmdQU_Yf_sslf=&xYcRXaVVhhqce=&hZ9kFkZUUqZjj=&LBaaLvUpZjhnk=&mO2Md8Xdghlgs=&N7aInMWa_erpX=&5pUAvmU_boqnl=&otconsZZpZVUY=&UtOZ75YlWWiXd=&2j43ciVWlmYqq=&bi_QHhYfXrgob=&uvERP8YYscon_=&P4fzGuVsps_jk=&MXbMyBUhbcUnf=&XmJDAuWg_dshg=&xj6934WVk_qhZ=&JhO9X7Ul_Wrsq=&Xa7SYtZdofZWX=&Twe6aaZmsgZid=&5iRlcOZidnamY=&NlWaCaWqo_rog=&GiaZfGVlWbljU=&KkA9ErVhqjUpe=&bUUhBOUYciUbd=&Wj3f7iZfjoWUa=&XQLW9_XXfafYr=&zUTmYAYVs_XnU=&hd7HWRWpUYf_X=&gzB5UfXWqkjbb=&g_9cs2Wd_nlZe=&Iw3aCcZYUh_gp=&gsfQB8YZbrXgg=&AWbeJQWloXYgf=&lDyvCmUoWUiZb=&AOoxK2UgYhbne=&N5ICeqYWihshY=&mMkJkgVm_fnsX=&ZaNigaWbsYraV=&b8gv3CXVcpf_s=&x6OFxxW_rkfhr=&sGMa8PVgfmheo=&LdPw_YXreghho=&Av8xSOWgdsod_=&dN9XclZWdWkiZ=&vDq6o4VXYVqYY=&WT4wrwUldnZbh=&NrmqwMVlXUcZb=&_yPypOXnWZjgr=&S6q9I7UpobqhX=&vtw6yZUagYaj_=&Z79daaZr_rglr=&lWbIcNYjUfhdU=&VhrUZLVWUmdlb=&Ql9Jh5XVlgoro=&GuWdooYUdXmqi=&ThtpuHUjZjUcp=&Z7rMlSVhZklqa=&nd6YXlZrssksg=&YdCdpzUlsjpXf=&4wmpHzVjacZWe=&enUbVvXpUokZq=&CKylqTVUYormh=&gZdcfpUYWrUXX=&6LAgx6XhfqUpj=&kPh5JkWU_iapd=&nfbkOPYlU_kjX=&CJPDdQYoWVpbi=&Y4wuptWlingeo=&U_crDrXo_hbXW=&yGX67tVirZqjW=&Plkr2VUrgWbbn=&boEcWeZsaVhsl=&AKThzXWlnnjno=&q6EUDzXraYqms=&vumpQfXsZopar=&FZBBRvZlUmU_f=&LkTHzuZceisce=&yyNhUpZm_cXXf=&5z_vnTZgaXWZc=&Q2os2nYmahkZe=&G72J5sYmnbqbY=&KYMkxVUVr_kip=&O9iJtrVsZXnfV=&Klwh7HUsfjfha=&n_Dg2VXrfbjsq=&UEnhRPVschkZs=&TDV6IJX_cjmZf=&6FFVbXUqdpcWl=&hRdEo9ZZ_ccqa=&7ncMuQWsWigrp=&L7LW57ZfssqXe=&EYPs_hVqqohYd=&nT5BpGVkfibke=&SD7Q_qVerpUWf=&xEHXy3VjdnUga=&QHBBaPZojmWqr=&Zcmfn_ZUclgeo=&Y7kNQYWnqsqkV=&hGYmdGVegarqX=&ef7NYCWfjVXZY=&R8cMVUVsoiehc=&UJVErrVaV_UUr=&wuBDcyXhhpgpq=&T2XmaDZanZWam=&JW5QOSXfgaYi_=&QfpLmBXgfjlX_=&Pini5dXboiarr=&jDctOoYkrdbgn=&TnV3BhZiinWZn=&uQmy3MXjrWqdf=&D_9D2iUZYmpaa=&CKqDGnXpmsocn=&gWCidjZjlmXfU=&sj_goCWbkmrZb=&lHhh6iWZqdcZV=&ASP2c7Y_pZUhe=&G7mPmOZbprcka=&vAnmMcZmpibmq=&eAhYCkUljWkhp=&JLSuvCZikicXm=&sBDNVDViVY_ph=&pNYJqXXUjamlc=&thTly8Ydlp_Uj=&z_EFuxYfirgUg=&gm9bFwUerUomk=&t3bcT5Wse_iYa=&USRThqZrUmhWb=&oycCsZUlhih_Z=&DWxspuYopWVZn=&kZbWvjUaagVlZ=&k7l2ReWbjaZcj=&K8UBlTVYhgemf=&PCbfQTYjobhfV=&W3xojeZiefUVY=&PRY5GCUsg_ffj=&5EQfPKZksUVne=&C8matdYrlVdm_=&aPsSOVVgqpafe=&eRDKtrXdkdgis=&83BLj3ZfWpUXp=&krhs3EYjinWif=&75cEVDZlfeVil=&RXEiWvVUepXdY=&L7sDKjUmidYiX=&vI9nUFYiicbje=&9g3kqPYkVUpoo=&x2eliYXrclebk=&vWaWz_XYrUggZ=&8LmoDMWYpjpns=&COzLyBXbpWjem=&7LWVh8XaWqVlW=&AzwgKNUZaklfo=&4bc9ZGWicscpZ=&stDF6lXlWWZZg=&DurfanWfVepga=&3YuGbaXfsnoal=&Fm2FDNWYhWelW=&hCfr8PYeeYmlX=&Pni8JZZbebobo=&yJ8KgUWrYoYlp=&kyoP8DWpjaiok=&WkTNicVcpsqYZ=&i2eSSOWZXd_Vs=&MMnTUoVpihsmm=&HoOTBTUWjdldl=&gpVjOFUqpnVdV=&b7obLbUZUcoWs=&zohQNqUZl_cZj=&fskfVgZloshef=&tpdI8HYeiWscU=&pNqVLkYeYrZ_f=&6KVVaAXXqfZfp=&7ivJDmWpVjZfb=&WBHD9WXebknoV=&foJ6wwXajf_Yn=&CXDmd2UWXZnmi=&7yiMctYqcaqcY=&CcWfT8Zejgqfj=&z4wlj5WZqfanY=&2UNXGRYkeoqli=&lZaDPzVnpklZV=&8ZpOSiXkVVUra=&5GvbG8Viosepk=&RadbecZliaUe_=&NyUacvVfdhlWc=&tqKMYQYZrhm_Z=&ANTnD5VYWqlUX=&6LutSmVUpprrh=&okC6PoVikYckq=&ezpQeJZbkploe=&OGNUCSZforkfs=&xm8234YXjVcVh=&dESNFaYoVhooY=&gLcnBkVsmpVmj=&lYJTsyXZUfalU=&5l7B2xWqgqUeV=&KgrZYoZ_jZfjm=&6Ri4F5VhbolVY=&lHIIbIWkpnefp=&4TGCXuUspXhWh=&G3xcgLVsdldVm=&AdYONYYWsoVfh=&w5brCnZhirhjl=&yoUSYtWehVUgW=&chbcVeVXUkige=&ycUYoZYjZiZf_=&H3g_3bVmoodfe=&9Zwp3vWfmsh_c=&BABucGZqhc_kn=&ZqG6vfZWVrXar=&8frwVIVfWgnas=&Aqr9BjYiXdmiq=&dNsKNFVcebVgo=&W3KJYTVqXWhoq=&d5OuBtUrniqnX=&MMswIPWsVfVUp=&GvJm_xVpWndVh=&iotxMGVcgjrhd=&nXsZ5XWiYhrda=&AeV9TOUihaqYq=&5BDVftXeUepma=&xqjQi3UrpZk__=&iIpBLgY_arYch=&eB3LKZXUedgYm=&cdcRJYXqVpVi_=&BlCaNUYbdoUem=&vzok2FVVkZVfm=&k2AorFWbYsjhf=&fZtx_jZ_brqde=&g4IBjNYWcUXnj=&ImXmCIYfVXsdY=&_NB7KZUnZjiXe=&QBB4GbWbnVUcY=&4TzjvFUXiirXc=&KWGhb3Vmbdjfm=&opl57nZlYhagb=&nOgT87Zjbocab=&bnKnzAWsdasWm=&x_hvGNVgmpmmj=&Hw33TtZebrfqo=&A6zlkBY_rpcUn=&WFSPBhXYdVsam=&Fu34JAWpmfgbn=&5YobjuYXqXqiZ=&Y_AEYNZrf_nUq=&KtHX2XYjggikl=&m8pqyPZ_ZWnsd=&szpDWGXqnfngo=&FWr3o4XZmksfd=&_IWk9HVUpboYb=&XAa8zJVmYggrZ=&IvRt2VZWfkaXf=&BSSaASXabqkYq=&EfK4gAZqsbnpf=&3swVEUZfV_frj=&kTLUBMYXklgo_=&jNNFeiW_ZjkoV=&QEFJs4V_idpdk=&Tv34HRXmleUii=&vpzuUbYfoo_ak=&VD7nanYagfVUr=&D6gIzzUjabZnX=>jaXHUUhjsZW=&IgHEf5WYXokWi=&NC3bdZWibodap=&Gg2k2mZrlXsdc=&B_CXQjXWdnoqp=&Lk4BM3VdjmkZm=&kkgsjDVeZdrgn=&CnevZgYYeZoV_=&9dDRBxYr_YkWh=&JauMTiZoXikZs=&RtX4ILZViZprj=&SahCnRUsUecm_=&MFSohpUhfcWXh=&9Y_aliUceored=&7MtO6AXndYWpZ=&V28GMTZppkoZh=&FTmL2tUmUdYcZ=&v3kgeGWimsigk=&P8NB_FYZWpVno=&Jdv_hHZhsihpi=&_GZaFiZffmahf=&HQ3Y5pWqYlfbm=&h8eNGSVbefnXV=&XqyIdbXhWaUoU=&2BGvO3YeidUXg=&pysoeIYesnpnh=&ApdTHWWqeas_j=&sV7qnhVqUbms_=&hcfm3tUZWogqd=&D5eJ5KWUakXsi=&eruYT5ZlgZsig=&v5y38EYWiVonj=&CLiBEjUfkXoo_=&brhyE_XZ_UirV=&ifpgC5Zpo_oZq=&mr4Lz6WfrXosl=&WLTtsmZcVeoXj=&c64_29Yomimei=&hrOy63UkXqXdf=&a5WGhrZUqpWdo=&vbefBGYYYpVjW=&KWsejcWffomgc=&E7l5WnWakYmqh=&rWRoYHXYXo__c=&NGi2YjXaihapd=&8vAzdeYoplYlW=&k8IzNLWnschbW=&CDsgzzZWVbmhs=&F7qVdxWnZmlgi=&yadv8IVocenYk=&SZpXBVWmnaocZ=&MkcFa7YrVnaab=&2frrcHWjmYUVs=&aQyD_eXlUjUsb=&iOSn52WVbkrZh=&gcoIQjXkUcdio=&8L6wpOWbosdpi=&BE3t6PUqqqoin=&EqARnbXWrlasV=&3WZcqNXqVpraf=&G2hR5FVlZncip=&cgAIj5UlZm_qm=&Dld6KtZWiYp_Y=&h5FVlmXpfYkXp=&OkOdjtUrdoral=&2G_3JGWhdiols=&Cef5qMXpYmWgc=&YL9ZI5XsrbqeY=&a6tTTIYhinXhh=&2NBQX8WihWoja=&xaI2OvVfqdcre=&EzFGMkWUlgd_b=&5n3mNHUclpZml=&3QWwozYgjrbqh=&axygETZgqeZaV=&WdFHMmWheWVka=&D5BaA3WsVbXiU=&zMTnGXVVkVZYb=&7IdfZOXfgdYbW=&sNXjalYrsWdal=&6bSbGyWne_ndn=&Nq7UKKXqmVhcX=&ROgh68YdiosZr=&6mg9KdYgaqUmr=&RYvMgcYWcocXs=&8ecUKyVsplilc=&BrFOC2XgZZmfj=&WLlI4lUcXgacc=&vp2Xh5XhiXrk_=&h_pQyzUaVlnpW=&c3u5xLZafqpnn=&XF8P7WX_hocgr=&a2OGngXkinnlr=&rG47scUUUWrpb=&72pu_EVbgoliq=&wjRBgrVUZldla=&Fr4t5AZmkWaaq=&u8DvbZXefiUqs=&7ilLZtYbp_qUb=&aY3hDzUVa_Xfj=&_nTL7NUkggfjr=&l6yoYVYZnnhrb=&l_LXg7ZqioYdq=&GoQ3DOUkWUbqr=&VnMbueVmobmYm=&fSRxcjXkkl_hq=&A2sDK2VaVYYXp=&qAs5IQUVZrVbY=&Ug4iwDWrXnniZ=&H9Jnm9Xnfifao=&M7VTwWZXkZsfb=&BZUePrVZoZlnU=&NEWN9kXX_rmpp=&CmQfNgXffepiX=&Pv5nqGXcsmqeh=&cKq6PmWhgopfs=&SuX744UgYi_XV=&MGlmurZcZgaah=&PIlIRFXhgoUnU=&ASSe9aXkeZjei=&8DS_5LUnbfgpo=&gs4BlIUZWn_jX=&ms3D8IZsWik_a=&izsvm_Uqjrifa=&qldSj_UWoYhif=&yaYoWHYanmoVW=&Hm7SLYUnfmrpf=&2gWet7X_bpbWj=&JIH5HNYaadjer=&bcj8G9ZrfaeoX=&X7c_McZoYcrph=&PxGhUJYb_rUZY=&ojoV6IXdpoecX=&3YQHXLUZeZkYs=&cZMwg8UqhYbne=&25FYFaZccpjVm=&vuV5Z9WhrnjUo=&suN7NoZbgZjWn=&w2z2WmZldiqcl=&UcqkAvVgUmpcs=&5z28UiWZbfeql=&nUU3h5YiseZoc=&veMttdXWhVfls=&BomRDgUsUUhkp=&Jr4w8jVYXVjes=&JICJEbVrUehWX=&QgkYGwXcnYU_n=&MjPWdpUVmYlcn=&Q9pEldWjmei_p=&5tZcBUWZpcVVk=&ZP4aTIWdbkdrV=&5AuEzlZebVefh=&_4qULlZ_bnprf=&D4PLaCWdYjikh=&CNXGu7ZZ_klpf=&ZkjuguVkXpfYd=&OkO5YmXeqVgkf=&ifFpIfXaVcaUh=&7hlzdgWggkgoX=&v_dbsHWjjnrd_=&xzmiQWWmXWelZ=&BByswlWdcifka=&wVXy4CWYlkb_g=&dymAZtWWXjYi_=&W5MToFWlXdaoe=&Ol5XcaWbfUjmU=&f6FuIrVbgigmV=&jF6o8cZXVloqp=&6yKU2cZVUilgc=&IYMQ63ZaYkUUd=&vTiJ2CWjgifng=&NQkv2qUcob_V_=&7PYiT7V__hUgj=&RbC6kUWiVWdYo=&xoRMV_Zklfloc=&8YNuNIUqjZlmj=&eGzjDBVihZfaj=&WMCsYhUXopnZ_=&YktSeFUjgiioi=&FQf_obZholfVl=&YstGGdWjbiakh=&_qxTA3XYqjido=&5xjbS5UfsUkqp=&IgQhv7XebVlgl=&RJwJoeZcejpoh=&qHWGSlUlmhcen=&XNImFTWUrffUc=&HFw6twWZoXkoj=&R3SIQ2XmfWlXd=&QyNSolU_UdeWo=&BT5frsYlpinc_=&iKVOR2WngpUVV=&cQaQGIXdnmpbW=&YhIu_OXU_mfmW=&GGbUcEZbZaank=&friJRAYWYXoim=&kzFlEfVmbUhUg=&36WqCOWVVVkYp=&zJ6tPbXjYcUlm=&wMU86wZrYcnjr=&g8SmmDZmZWUkb=&LNPrAXYsedaZg=&DIfS2HWqUXkqe=&j4ARgKVpYqXgZ=&7tK_ERWreipho=&GYdTccZmioi_k=&WOUh4rVlkbeXc=&bm8bNsVianWXU=&qkuv4oWhodmfo=&b52e2uZXjoWhW=&diUnfYYdn_kWs=&WoFL4jUbofjqY=&t6RdatXmlYlWn=&xrrtR9UUfiaqp=&JdTFCNXnnfhWn=&YFmPZ9YVbYbfa=&6XObQbXhlm_se=&SO7pvCXhpcnn_=&ulZ6acVmhnrhb=&Ff_uWyUoqjaim=&JQdLsjZidcYUj=&MnCUaDYgrlk_l=&abDyN9ZpUXWif=&AJv6uFXfqropd=&qnIwpbWsggVro=&sFR56qZoVhUqn=&BPS6nrUpfsWqq=&2LJlaSYrkbaWn=&QDmUYYUnppakX=&AcHJ4uVXmWqpj=&dJlRVKUkrkdsY=&WmCF4IYqVegks=&nmTzayWgcqbYl=&quzzMSVraccqp=&CDechVUZqofVZ=&DNRcJaXkbgXYe=&xHGiUBVoalbVq=&QE4TiEUcigols=&pb6lTJVsoskVd=&7b6kkEZkYelch=&A56OAMYqYajaj=&vPwB3PVeZngme=&VbxjxdXijafbh=&JvmrmiWYbVahd=&6rDh_gWbmpiel=&8DXFsnVspskim=&hlToBDZaXafUZ=&7q9gHJZViUbkU=&K_o_52YcZkbnb=&pmU7fmYnrWWlo=&bkXpfFXnmVoal=&SA82b7VUYbUZd=&74cIYUXkYkpXf=&fDY9K7YZdkomj=&jxK3iSXalVkfh=&Dr5wv_XoiXgXj=&6NtWJKWUcViig=&s2TRecWWkrkZk=&tA3NNZYsocgYn=&8bmETpVqXbsbl=&3UnUo_YYZVmfh=&4ataJOWhcg_gV=&n6yzqNYXlZlcd=&_nE8CwVmqir_l=&FeYik5Zgsna_Y=&bVtBKsVsfoXse=&6i_7L9WbVjXkd=&JHZRuhZki_mZW=&A_WC5cUYoinWY=&cYtZgmXakVZVl=&rWD_LYX__li_q=&JUr796XWmebkg=&hM8XFPUbonsXZ=&PjB4pzXhemgcd=&zPInT3UVeoZlq=&SFbkXlWebjYqX=&IojAhNYerjbml=&ByXvD_YpUrqcp=&KLGCDrXrkspZq=&Ao9o3hUjaZenj=&92YLo_Ufkkgnn=&zlrbGVUdWUrag=&HLxWXzUrrYcqq=&hnKahwYfjqZpo=&JPduIbXYWjcid=&pgjpsoZrskhUp=&tRNYy8VUshkYd=&YHWacSWnserke=&LtRd2OWVfmjr_=&MPJTFQUcsmssZ=&8vIqneUkarZlp=&By_cG3UpbgYks=&U2pYbDXfXWgdl=&L85cHkYfjlpsi=&DM4uIqZglgjlV=&kkF9u5WldXlis=&nBA6OxWpommrh=&YgxQCDVjbiifZ=&eoHOC9ZpmgXha=&TpY6hDUdbjUXi=&v__Pi3Yh_lWrU=&uXtbEIXVemafZ=&2vmYcnWV__Vig=&rxdGZaXVqdnYf=&p9wxF5YqmhXgU=&B_eNyMYomXsbd=&3_l_k2Xhjsoak=&Sd8rbXX_sshke=&FqXpaUWcZedcg=&Bhy5x8ZXomkcp=&IHahExVknnrYo=&iClzv7Zah_fni=&u62ISrUkaophm=&MLMDgaUikinhV=&_7adcaUkXrZV_=&BrcJB2VWjcb_X=&Zi6AKpWejkja_=&qXTAzgWoapXgq=&D8QpW2UkbckZn=&W6hts2Ucdqobr=&HfzpdbZlYdbdk=&xUxMkHZU_UZWW=&zh2nRvXWgdWmZ=&ogIDdQUspYjpg=&bhfyVgYsWcnea=&ayx5JqXisVnpl=<xi95UV_qYV_=&if7FBvZYjbmos=&YL8mvfVgjsegn=&cKezJmUecVYmq=&D_yTQTUeegbhk=&PY9r9wVrhWebb=&mexTiQXVcZbV_=&CXNlqZVplmkek=&zYnLo8YnkWUUa=&r4jZLHVd_i_no=&6dKUd6YjqsjYf=&KfVzARWikkcrk=&FCqKhQZqqbccb=&tboZF_Vbfcesc=&SJonbVUfYrqVs=&hWnsL5Z_Zme_i=&ujbygVXXfm_if=&wyNXEwXhrmhZU=&vPjhJrWaebdda=&wDGJbLWWaXgrV=&TKP2dvVbXscen=&Cft99uYqVkdcj=&zQ4JLLZUa_rVd=&8qvIHjV_cba_n=&yTTATQUql_fai=&iXVF4KYpnldbc=&YiVgiSYkaZhrZ=&Xik8W9WdmZYkf=&KH5rjtXfjloYX=&atWnmCZ_rdZ_V=&QHvI4eYU_Zlqq=&3lCRNzZlmanio=&4SOuTZZeecqVs=&meTRfjZZalhbY=&va7tT5ZglXWns=&zdGXbCYilnclq=&QGUNxGZZhgpgn=&2Xtl5_YXfcZae=&nEdpbhVbYqcUY=&w8S8LKUiZXbZi=&q85bByVWWabWe=&lIqouVXegiiie=&vNbMD4WrZkWhj=&ATCvjyXaoj_Ui=&A6GKhtWbXZeqX=&eABWhkXfmZsi_=&qwqF6gVrcloUq=&qJYHRFYksmgid=&8CVo2MWdmjXkV=&v8kc6NWppe_lg=&5pJYM8XrjYYYX=&gotIvoUZrsc_r=&tjzYqsWospm_X=&KghZ2kZckXhfU=&VVKLGZVk_mUkg=&cxLN5UZkpWkec=&ixyfDgWfbXeqj=&LVZaSaUfmfsUe=&j6qpkbUhrpoWU=&vXOHgWXZaiZrg=&jf8YiRWYYlmYa=&Is7QuLWabahYo=&dzFCxLUYZqaZU=&ARy3LNZadslZk=&AQ7UQ3ZfaUiUV=&OUXFghYYicegk=&sFFrC9UnldqfU=&jTRZyGZ_akkXV=&lOsLypYbnbXdV=&ewRE8eZqYpgre=&2RuSr5YqnVeWm=&VYpwiGXejeYar=&deeuHCVm_eeWU=&LUn9Q2Ybbmanp=&OD2kDQXkUcsrU=&UtHSDwWVXbXqY=&wopszDWcqlWbq=&9LTW7CWheckkk=&yvJa65ZlW_XfU=&vVaShBX_phWsa=&DLLTf_VXZ_gor=&ZKyy2YYUpcbdc=&eHcOaIXrqoljg=&5jXSN3UYgkbbW=&XSoOpkZdh_ccq=&f8ZcfjVXl_lkm=&tqHQxeXdi_qpn=&E7WQHWUWUqdbq=&xHVKhkXXkWaUb=&I2Zw9zYbbfqUr=&ZrRdK8VbXXmaq=&6yXSIEVZUYfZp=&GF6GdxYUYqqkl=&th7afgZrZqnlf=&hx2oc2Xcrhhcr=&4rfRYZVhgkbUn=&zGUj_UYginkmg=&ewTWQUY_ZpfqZ=&_2BmKSVfWqnok=&n3MWu6VkUbWbW=&JQVKTRYhrqmWl=&8NqaDYWibXkoa=&jqqKMWWboafrn=&zA3YHbUoYU_Um=&DrWtz8VqXpnck=&xcx4hYVddfs_n=&APHWdtUUdamqi=&7VfPAdUiZidej=&yyAyMHVqnelgZ=&BVyD2xYYlYclU=&MZD2A8XlWfbjW=&RtZ7krYaVbjeo=&dDgdekVppdroh=&VsuugmX__oprV=&O7hc7MWgcprsq=&SvBsUDUXsrsnZ=&GXcTAVXlbp_sg=&RRTPGZZfjYWXe=&7yLo8GWqcqmqZ=&_pP7cdZVodlia=&k5f4dwWUeZmdo=&WYBB_3UZan_lo=&kn8zmVYVohVZb=&2HoZ6HUnarpoV=&yZGgTjZhssUdn=&jC22Y5VXpVncl=&wo3ezZWVen_an=&iX6A3bXXZsniW=&4fBcUsWnqle_W=&mswjbEXdX__cm=&PVSfIBZYbignY=&tOrZXyUkZqqga=&P3iwQkYUUgZXq=&a9EUeDWWnqVcq=&2yC3j5Ucc_fbb=&FVvIbDVrnlVad=&eo9CZsWghlake=&WplDeHYpoWrje=&7ZKJW2YmhYXae=&ehTyjiVcqhqcW=&vQRUvIXbcdWji=&lYD9nSZqdcbcX=&8bqCUYXedXgbV=&rw6j9RVVielok=&i43aEuXogp_nr=&2yvvg_UrYqVbZ=&hkadkYXqpUoro=&sKxcHwUsVVVdX=&yzGwsSVe__epe=&y9lTK9YZlfUbX=&P6CYEXUglkdaW=&NAFNMaZbirXpr=&wWPN_rZbjojVd=&wSXf3ZYanpefV=&8k6WhJXkoVVrf=&XkpGZdZWgmWke=&N4Z29CVklobVn=&4U63nbVbpf_fU=&6vywbSXUgdYYc=&ezsw5cXlYhahk=&Kx4qgnUUdfdbk=&Zxuke8YqpUshs=&BrC6cdWdrclVf=&lqih68We_Vjql=&5C3dpUUVn_mjm=&uPLFS9Zslabfg=&a9vIqIVrlpXgl=&isQktgVmr_Wqo=&kQmcBnYnlWWkV=&IpajlYZssgfa_=&8XaMwPXiXgclh=&yjoMTtUoVdbYh=&xoWvRBVYfbZmr=&Vr4nBLYrfdqXX=&lMGObMVXeqUoV=&vXTh3ZUekdcqn=&4GKxoOXoWedgb=&7zfShoUimokqm=&N_THKaYigogoU=&TF5MdYZfioorn=&DdMTMDVlUqUVk=&6sQoHzYWofkn_=&o9HkV3VYbVeqg=&ka2Y_yZa_pq_W=&mIaNxdUocbYUd=&mrfPYrVrYi_ap=&Wy53ACYUlfk_f=&zsuxdwYimgngl=&souJUpYsgaUlq=&uR5fvcXaoqrhV=&EHNKAnZkgkaZU=&_OsjVvVYqkbZV=&4cSJN5YYhoVld=&a8FXqIZUomhjV=&hdUvnOZeqgcbX=&Ki8TkjUeWpUqX=&pDdT5RUncXYbr=&PY2MDPVYfXrZg=&dX8geXYkZhZaW=&_xHOPaXlimdlk=&yPzNuNYaeccij=&8SQvEQXWncWcf=&WvaWn9YjsbhYk=&sLLB_8WaZned_=&YQOj9cZpUmnZq=&QN2EnCVVshabU=&isib3sXlormpW=&_e73Z9VqZqcfp=&NDPUEZYpoVife=&ShNcz_Vjgmjsl=&g9RiDOYWmeqgZ=&jOviIeXVZflUa=&ohijfwXdkkhen=&_fzhMhV_noYhc=&2IoBmHZlWYkrZ=&QTvlkwYajbkcW=&NNWFEpYsV_ojr=&jpGn7PUkVqpjk=&NM8HKdWlqliaj=&cTaQSAYdlVYmr=&qf3YHnWmjspbl=&rtb8g8VhiWpcV=&8Pv3fuWVbsWYp=&gPOC3XVkXWils=&rEjkssWgrqYei=&OszBW9VhcffbY=&gvR__YYYoganU=&vWUbDlUi_YUgp=&JSvMyuXhZnsrY=&odLaGoWbWlenU=&heFka_VnVaesk=&R43IdAV_YejUo=&nrrM6lZXlag_Z=&Xd5xg3UnnkVaV=&NQep_TYqpl_Yk=&GtHKoRVUZejkX=&hiPvseUaXlUpn=&pPOoDoXpdZYoi=&eeiGDJW__mdiY=&nJeQr2XnbfYWZ=&EgLu5OYZrmkYi=&_jSBW_Yidmqhl=&6P2EBhXmlaYki=&Wi22rDVWsapro=&NqT9yOVqoVWlo=&RKkejhYnUcrZV=&FnTnHdZqoVpbh=&iNON6iWUksjfs=&r9Vi_IZZXbcdi=&nrVirRWVjsnhs=&tO5v2VZalgsir=&StE_TaVYljWiU=&Evm9G9YkpYXZf=&XQLeAJZiohqkW=&fV72ppZplbZVm=&v9g7hdYnehZqX=&daqY8TWpfjZnl=&9ktxQOWn_oVgf=&EtdSbAWmqrlXZ=&sM4uFkWhZk_pm=&XgjuvZWqr__UU=&sPmbOlXqkZYUm=&aEahX_Zr_jelV=&26oDJMUbkjZem=&VVhHWgXjgjkYm=&fW8fKgU_Vlofl=&FfcKLMUlcnrre=&z3_xPAZjsXpln=&JlwYQ5Z_X_VaY=&6eilIuXUUkrWp=&5Gh6HEXUYaqal=&LmccqmUZsemgh=&afYodSZccUbYV=&b66zWtXWndood=&xF2gKKXalXf_k=&UuCzIwUqWqohn=&qX4vEVZqVoVXf=&_AhrzRZk_Xcin=&KdQQzyXpoqjkm=&UbyiTkZZmcspa=&UIQNZGYlnnZbs=&68XkaGWnUcaXq=&SOjzpHYnWkqqg=&oMOmKvYVoZq_W=&j4tJaYUlU_hmX=&IIGEZlWjbecYV=&X8MfKKZlfdVkX=&fG4o2ZZVXXVmq=&9DJfq6YjcihdY=&9LcqazVlpesbn=&v3o8IOZVodW__=&iN4LraWesVllW=&OTpLbMZX_Ugqd=&fhlWbZWnUkqoj=&oRcSFwVkeVmlc=&gosfGNWkUXlgn=&SIO4UTWYclmpb=&Z8fRo7ZdfdVa_=&yUm_tPYZressX=&w2cf78YlqalYi=&E_xIfAXphhdaU=&tdhV5AUjis_gk=&4PxYOdYfidYql=&OkJMv4ZZoqkiW=&ezXgN2ZfcrUck=&hgROuLUoq_qrV=&sNk29cVXnnkZW=&bpNUjsXXnp_d_=&9KQRuaUVYpVpk=&ksCXFXWcjor_g=&QO4DVuWomocYW=&xiLdsRVosccpX=&MHQkU2ZosdhXb=&eFQtw3ZrWWUhe=&wUXcmtWlqZsj_=&8kBQkQYfVrlZY=&OJN_NTXgchiUl=&4Mvn25YrqoXcp=&ud7mt2VldhVrs=&AGICBaUomqhp_=&h3PjV3VYrYkZU=&PbqBK2YfXlcXZ=&TcMZ5RYkfYWpq=&ddrKJcXkrnhYl=&IXccYkUoidmkn=&QUq2fyZpsakZe=&XLogQkVrUfcdn=&pLRsJEYdakVgX=&6PdcQpZecpjUU=&DsUIi9YoUaqZX=&b3c5HTZZlrkfj=&GbPPczZVesbbV=&9RBRSfUpihUpk=&KmTSRAXkohUfg=&p3JeMXVZodnUc=&sWO5o2Ymoesa_=&oWn2G4YaVfcjr=&pL5Qh6Ygnkahr=&YekgpzYoabjoh=&RQRRVSWo_YUWj=&CFP22HYaYWpkV=&DEZcWCYsjr_pc=&k6nHwRXZmcer_=&FuTrlqZZraqU_=&m9lOTiZbsmnoa=&GsM_5iWbfpqhX=&7mnmlbUXjVdfV=&tKKjFVVdgWqmZ=&VE5qnKYYXqZkl=&G3MFXDUXrbinc=&I7wfILWeWUdkm=&bxSoQHWsZVqoY=&gr3St6Wasmlkj=&yk5WhHWqoockp=<yvXoWfqfmZg=&dK7yq7Zoirfqr=&vsprduUifZsfe=&m8iWS7Ui_aisW=&fNyO9VXpeqWac=&9q47aPYknmXgd=&xbF5xaYhVk_gh=&tTGzLUUYa_mbm=&6Mh3B_VbcYYeg=&JaiR_SYjmYoea=&kniRX8YWoemdq=&BFEdrNYrcsagh=&2a9p4lVo_Ygcg=&aO3K4VYYjYUlh=&sTM4iRX_djWVW=&4QyHTKXpecXWr=&uLjltWVlah_cW=&CV8B3fVlkhYsW=&gpIYG5WcXkUkV=&7cLuvgXXnflgs=&7RKlPnWaYVYmo=&Eq6p7MXmpWffr=&YsTQBsWXZsYnq=&7XylHwWhYaWpo=&GkA4F6Wqlnbje=&kRfdgEVarUWbV=&rK9c_YXUqmZbX=&FjNJbwWVUYWsn=&HdrBRtYbelUdg=&4YoLbvYonXgir=&tDISqZUdibbsV=&bGSxcUXonVkis=&yerHiVVlZcZlZ=&PwcewOXpaWhUV=&rTzk3KUaYrljh=&a9eV8eWgkkrZh=&BpKeJ4UZWicUU=&s8ibntXZmqkng=&a97E8AZbbXnZs=&AW82LCZlaZbeo=&a4KrniUqsndce=&CwOpnPYYebijo=&Gkd2OqYoepmoq=&vNablyYlkdf_e=&oafHF4YWlophU=&DDEGAlUcnioYZ=&MvGBc5WYloVba=&DUfGuEUddXsco=&osDLewZbWqXVX=&hfwArEXVWeYiq=&E3zUP_UaXXmfW=&inVsPOWldiqcg=&hc2xAdZhnbf_Y=&sXfeBfXgdrkrf=&uGcR8mZpilXpa=&QoiqeaValZmgo=&LVVk_QWYlljhk=&ILmHjxVlpasVp=&wi7YGaWVoVqb_=&HG2QlEXbjqgVq=&89maLEYmaienm=&i4mHlcXWbmZgn=&ZNBMZyWkrYmkq=&zx7EQDVZWcnid=&IVrkdGUfebZ_V=&4M4mokUgnbZfZ=&zLpODqUihepYr=&8K8HzVWodiegX=&Gc7gWvZjqgaYc=&kF2aa4ZdVbbjU=&3OaPDuVigjabm=&kngYCOZgnmqmc=&ogolLbYedUnpd=&U5ySKLZobYmqe=&EINhg3Vsspmn_=&8Po57dXaleifd=&QBCUsuVZVjr_d=&Qz4dbOZsUleVa=&Ug2N4VUZ_baeV=&qv7NlvZijUsip=&hlYa7eWhndjiZ=&PsMDnCVaeiqdk=&GFVrHmYZfksfs=&gEv4sLZajbWof=&fCs4D3ZqUZeca=&radYqHYjjbZ_c=&fYXfXWVkmaqqc=&EZjtOPVbmm__f=&fAPvTjZZmVirc=&B7cOgqZsUXjsj=&f3oyjxZjfqclc=&wnkSEEV_fUbjY=&Jtwh9nVeffVcf=&CxiAaeWk_WUjl=&O5KwTZVdXmrgj=&fVsUOWZjsnoYi=&xtfD6jZYWd_Vk=&9oCw9JYWimnZc=&YYxyrrXcWVknh=&uBeuFpW_WUVVg=&yXPYZNZsmUobj=&yURPRoYnbdeil=&xNCvNuW_cddVe=&NnpkNUYiZrbln=&QMRk2CUhWWUec=&KxXxnoYco_ahi=&A2nWG6XijbWUj=&S3dNhtUbhe_Up=&jcJjxAZWgscnp=&p3pQmMZgqp_nY=&2bZH3zVXVWriY=&nkfGfqUjijedX=&TfG5BWZbnndre=&damZRGZkqiqn_=&SqsUNbUpppnje=&qNVnm6ZmkfZiU=&iVhZTsXiVkWgn=&jEGNT9Wcoc_gi=&MgqlZvZrUcXf_=&PfbjI8UcmYpsd=&ByAay8Wip__hZ=&dNu8JnVkcfl_V=&6shYDaYccjedU=&nDZ3CZYlkce_e=&dv9wrmUnprrjX=&tvLbUpYUqijja=&2s9nOkWdj_klo=&7o7BFNUecikbr=&K3J2lJUejdeZg=&oW87KdXh_Xpsf=&fiVT8RXlrlqm_=&5iqBrDYnYjmWa=&TYZPq8ZXpWdXU=&2fXYyGUsXUrci=&t8mTarZ_Xlbbo=&55vJqlVlcWsaa=&BYhK9VXckeo_f=&PFTrDOZcmiVrZ=&MjrlmmZnarcre=&hh2YYuXolmYUq=&GHgoZkZhnmrkZ=&qnB6H_UcmiXcW=&f8VCoUVrbaYhi=&jsIIysXlU_pal=&9rIKoSVfheqmb=&4eyIz2Vohffhl=&ip9o7_ZkWjYkU=&hn9GMbVocWYri=&Ahp543XWiXplo=&TaTRDtUf_iXUm=&2QdW32XshgasW=&Ptj9IxXqrochW=&d9eU5CZrkfkXm=&2XmnRnUhfrsen=&GH5t28VhcgZok=&gHQCHiVmf_niY=&kJ4u59VVrhYUp=&w2IL6NWlfecij=&FolcRiYaqnkVa=&iuneMAZjni_mj=&DlYCzzVpZdXjb=&tJAbtMXpYllYb=&6M5PYRZssoocn=&T_WG8MXaccWgc=&Bf57KpUcppjYb=&Vo4lC7Yijcael=&eAlr68ZmqWqlr=&jHJkO6UfgkVih=&z4XwPoWcaci_V=&vQ2TgaVWik_sh=&oabiepVoVoY_V=&x_tWc8XXjqsfs=&UiRUyEWsrm_bW=&MQ9w42WkcXdrq=&UWQKTZUqpiqcc=&8AGrzsVfVnsc_=&BDtM8aWmfZqpg=&fcmsyzZbhafng=&FoYkA_VXsZpWc=&qLCucuYYeUgmo=&dYV9rRVbdmlfa=&pesD7pVpdXbns=&MTiC3KWrh_ejj=&AdnJ7RWkmcjbV=&Q9Y2jdVWjpbsm=&49G9ynVaYefkb=&h28MkmZngXWmV=&UXl9EUVjmWpbj=&vjTSSqXgdqjZW=&P9Zht3Zdflacb=&FVDZKtUeXsXc_=&vosekYZqnWfdq=<mTWaVVdWrYm=&XrN2fMUZfjsVk=&JHYNZkUUcYXhd=&MUrUJUXnioqoj=&NkzURfYqWVpZg=&R6QjmxXgmk_Wg=&HHnH52YeeZVgc=&Nnd_QbVnnmbql=&zCdZDDUkhYnrd=&sERcO_Umrphmh=&2vjIcNWUskmWh=&F4WbjnYcmeVil=&QJ2Qq6WWUnohi=&yDaem9UWkelUZ=&hnPWT7Zcoiodb=&IcKq33Zjmpnba=&OlJqzBX_mahUn=&FTvYhTZrfWbUs=&IHYXOAXppoXnW=&R8tCTyWsi_chk=&FCS3psZesgW_a=&bkWp9VYfen_iY=&PCWdEwUXqqZWl=&K8RLffWriUZUc=&fYBdZZX_VaZah=&UD7cIVYkipkVf=&cfGzykVhgaprp=&p8OWT4Z_Xjkmc=&xG5RS8ZVojWoZ=&Dzt3mwV_jbcja=&qbCVojVaggXYe=&CknqbiUZmkWqi=&sMCaCqUsjpail=&UfB6PzYVfVZhd=&j_DMWvYfUXhlk=&nESxEUZXVjrrX=&zfMToxUrdfffU=&YFQmF7YWcoV_g=&iWcgkuUcXUpfW=&hU7lOcWVrnjhi=&JGgo34VcpcZY_=&9PwurSXlacqdY=&UK3FAwYpbqXcj=&6nZrNgUiUaWfr=&FoX6kmVofhcmh=&gFyIz2Xosi__n=&4gJrUmYrhoXXm=&pTRTwAYUicksh=&R5t6OfXcnXrUn=&LsxRj_WqcVahd=&WIDizoZgWqWdZ=&c_2_DnYokrg_b=&CIONXCXaWgkog=&C3ptDmWZZUZmh=&YQ_lHwZmahUqd=&EVEAjEWWisWsh=&TnfEs6WpmUbVk=&EiltHhYoUpWii=&2z9My4Xnfhpib=&rXgVtFWXVa_lZ=&KKIILLXgpacsj=&qWdqvCWXZnnfg=&DBGzj4VdV_sng=&XaIpvbWbkli_X=&GSt3utZsoqfpi=&KZYvRfYrbiqqZ=&asJ7XyWWj_cmY=&57O_o_VoUsgco=&OjgYVrUlrfZnb=&xL_ijqZZbsZYo=&eRA3luXnY_nrb=&jJs9qWYWYag_d=&A2HVbZWlZhqmp=&OFtzJzY_ZZcis=&8ocBlsWkkilb_=&UaawXgYpYrgcW=&rfBW6eYaZWXqp=&AB9_thZafioVf=&7DVKntZmiWadf=&98nSXlUbdgaef=&DmjlTxZhrhYma=&RYeUyhXXagYer=&VAWtBoVUnU_lb=&Go4Vd5XVnrsko=&YADUhEUaehbda=&RACXiJXcbjqde=&s8qdi5WjgYdgf=&yjkv4fWofdgYp=&KFkr2UVreasqU=&ANNNmLZkXg_el=&AD8ngjZVaUimj=&hDQ9qeYkmkaWX=&5I8gKFWmfXkla=&Te7BBpYalegrp=&vLdUXaUYWlgqm=&p8GC53ZmmmeYc=&x2CqMdWlspUcY=&c3S5QWYqaobXn=&e2lpz2WrcbjYl=&hOJ7tQYopgcUj=&YK8AMVWoUZcVn=&6wVTB_YpsXnUY=&9y_8RcXhoqsmp=&FALvD7UoV_beX=&AH2WDqXneXscl=&USuxRUXUYbVVd=&VjAvcjXmdVprs=&7CupCEYZrqnrg=&sdhJjvVfkjghi=&LhdrNcXUfWhgf=&UFox93XlfeoXj=&aAiVNjZnXkaYb=&UQL9Z8Xloamhb=&6DPM2BXhbisha=&k_GMeSVkggdbU=&cRxRPuVbgWrpb=&qI6nfaWkodZk_=&lSQaHFYhcXVVs=&o_BPXbZamZbXl=&jc_RbdV_jss_f=&HFnPelUYXmroW=&FP3NtlZcUWfpl=&geLQkiXldYYcn=&GzzzeiWjaj_Zh=&BW3qTwVeXrUfj=&Qkvg5FZfblqUp=&GhqfLdYcjjfUa=&z6lTkbYXsZmiW=&4qjfJeZkUfegr=&izwYrMYfrdjqn=&dvbeW7ZWqUkaf=&W9dCFNXnmiis_=&sZBWYlZqnVdgk=&H4yrsyVibbkVc=&AklmRcWnfZdli=&ObRPbeWfXaefg=&u8XdhTZsYgelc=&6SLpVJUhegpcW=&Fym3Q8VbeVffW=&nzXtHjUegngk_=&SOXsN4YgdkY_r=&EBQFQbYnUXjgr=&F2hOeaVqqkWoV=&aMgDDGZjWVgao=&ViPcsrXbUfXac=&or5CgrVhVVmoj=&36a_ALUlbVrhg=&RuyFjOVeZjgah=&VbaeN2WeVijfk=&PkuKFVZVeUXap=&c7Bs3wUVdqYld=&ff7qM3XXdrUVi=&BC5Me7VX__hXW=&lxttbDUeedabX=&blznLEVkqikfY=&YsIGmIWcsqbYo=&nGvgHmVobjZWg=&9IESdMZXZlUkg=&5flhxMWqh_mdd=&Bfwd4gXgjpmkq=&TG4nPZVpeUUpV=&JEjSw3Vl_nhWn=&agpccZYan_mnd=&EQVgTAXohhpgr=&jWm9BmVYVbpli=&kZGcKIXVfeYjq=&E43g_GZqUmYql=&2MKjdrUUkbsdj=&uXJYWIVWZgWeZ=&YnqQrFUojiboi=&nAFkVEXmsscna=&IDjjcPUqngacY=&F8Qt9HYbgYrjq=&MOII8GVnZfqig=&lqicIgVVh_YYn=&MgwbgxYenXdkm=&dHk_u3ZjYUdia=&s39zjeVXZinha=&K33_MzUXhcZba=&B9olGDVeXinZW=&RNmudaXnYYfoZ=&q47_XaUZgUXcl=&WgrbL2WlmrffZ=&zF2lFqWhseffn=&FWxuEkUraU_ee=&uKyNKtV_YZngq=&_jh5MNYWjcWqd=&O5W3oeUf_kggo=&jCbCnRZhapfVe=&ODhPJRVZdfUgW=&UgVkyoVefsVb_=&DFQl4EUeVUrpU=&9iDjDWUs_icck=&Xy6XeGWgkYaUq=&fNSpZaYVnXXpe=&cmybldVeiblde=&O_aFhdVlsanfg=&WGVUvJZhWVein=&mVsJaqZjqorek=&LvV_ZUVUVgkXe=&daJvLoU_Xljsm=&bWtefmXloahjo=&mwl7wFUccXcom=&dyZuqxYbUahUs=&32wS8_WXZfsqg=&RbuNwoZYgmdc_=&Ba73GnUYkon_U=&5j_fDFYagopia=&2v3C9VZosaYj_=&wSKiLPUq_hisg=&pzWmXNWqfsalb=&kIq7f2Vq_qiWe=&psjuPhVUplUci=&FL7AutWbUijnl=&EIq4oZZpnsiom=&fVaLc_VsXqhXW=&OaEWuwUhfcXme=&jRnzNuWnUelVf=&vfg_hXVigYUac=&t349n4Xoe_Vrq=&25j67kZqUbbWV=&7dfu3gVbifXql=&9Qhs7BWZZfrfk=&Ke6UcmYXpgmqW=&8L7kGsWcrdUYp=&7env4NZqpnrhU=&wwD4QhUfnZhWm=&QWOSLUUeherdl=&iWipJLXjohnUc=&3pGBDCUgaWZfe=&nWHjZaZsjpYUg=&4UcEkmVWhWUpj=&wb_nSmWcqnkam=&LWckVYXsVpY_k=&oHDxVBWsslafm=&3ILTthVqblbiX=&U_gCscZkiqkca=&wlgBbVUqklkbr=&X6MECgYpncVoY=&LQhdvmZbdofZY=&s3PKOWUWnZinp=&x2O2cpZ_Voemj=&RQepBDWnYWZno=&9HiheeXnamlnl=&N8vTLZZilZZXk=&lKbeVQYcVr_a_=&nFiN42VkZc_pd=&7BTTlsVqeVicr=&5PHiQoZVVnbqW=&9WffgBZUaVXfq=&aN7nVHUkmeZVZ=&aDGZ5NYabeUZY=&OOeNpZVdkXfnp=&nlMTGFXYojrW_=&joeIUTUZhkbrZ=&iDuOqvZpgUpbj=&hDSzcQYqUaiqW=&7bO4zLWpaghWj=&t_eoi7Zbjcrbn=&gLjdyMUs__cbj=&dQWhLeVrjfhde=&nUIHPfYcepmqo=&ngEn4oYppZiUd=&tJbqlIWifmlen=&XcqSyXUoVWhUn=&sMu7g4Z_kjjeb=&fzmEglWXXdfWi=&pZOguTXcUbnbg=&cDFyLjVldnabm=&Rfi_VEYYbqXgq=&RHCoNsWjnfhUY=&48M5SdXbjbcYo=&D9FlCIWnkZWZd=&YbH4iwVpXUnms=&iyLQLZVjrdWbn=&qcAuNBUppmpea=&bo_jkQYirlUkX=&KaQDARZdpdYZs=&OiGFzWUZjmnlV=&scgXmuVZmsags=&fbyR_VVgjhVgf=&4JQiAxWfpWpgl=&_v4X6RUYVdVcp=&FL9BSqValfZcU=&CiwcWAXspVrsX=&IPMaLEU_iZ_mW=&f7K_bSWZpdrnc=&3ui2QxWWcqk_n=&A6ozyJWndrndf=&enlM4fXXrnbXh=&QNuzxoUYgkmjX=&gU8CfDUlnalgV=&uwVwMOZUseWmb=&NUU2IYUaXqbWh=&bqxbw4XrhXihY=&A6SgYDYjXimkn=&VasewUUhrmVXe=&X52wE4Wlcpsnh=&Eb8uFmXVbseqV=&2xkg6cX_nafUr=&9Nzx3GWnnkqfj=&jpcJbBYmk_cYe=&5lojFQUdooWYh=&i4RtmfWjdUqZm=&cMjz8jXmgdqoV=&FmBmPCWXbdXfp=&66gxEMVaqgaeX=&9YF8IMVqXsocZ=&e_eBXrYfpXVgq=&yQJ2ezYd_fki_=&fxYzIBYjafVrX=&UzDH87YlehfdV=&ihPFU7Yrgldcn=&amr5QhVUZjsqm=&kTOeBTYnl_Zpi=&dZPl3yXhneUqU=&vWD7LxWiqobW_=&gjOtvdUjXnkXh=&fy_ZoYXXgrhZo=&z8dR4GUmjrbYp=&Rdb3bRXhaehUn=&OJYI7ZVWkqrb_=&Fjgx4dVhaYrkb=&lBo3XZWflnfmn=&VGfclrYmXXeXU=&8z5NJbUhYX_oo=&GzHQ3BWhkUVWa=&dLOfc_VXdpYmW=&DqlCHkVXmrYfU=&klXmeiWsb_Xod=&v8aZk6ZVrnndn=&MSAzrlWheerVh=&3qTCxQXlreYao=&e8qH_LXlmXecn=&bboJOoXVfdipX=&d5t4NQYhhXXla=&3ayJndUjba__c=&moxNIrZmgrgfX=&4eTIDxXlZkk_m=&29sCSuUpnbona=&wkCnbyYjhUfrZ=&kiuUrjXpsYUmf=&edIsFRXeqVUXd=&bSvL3pYaopnZs=&OFaZtWVkkXrgd=&GM2EEtWWbiicc=&26gXzjUblrbsc=&PNJMNwYmmZrgZ=&PnoO76Vblajq_=&dJr_HQYdmjdjd=&fZP9y6ZnXenZa=&HyQXDyWkljYnn=&yWNO3RYemojie=&GrygROZYddlnq=&n__wX5ZrZmled=&rvDV4LWeXYnZc=&6ls9kQZjcrkZj=&lNPf2PWqYZnkh=&38DU8JWfarWoZ=&bB33oyYWnikUg=&t86qShWnaUebV=&_cMMuIXcncXke=&OdpHu2VideUmp=&CbcWHEZkgZlhj=&J8Dm7WWbaroki=&I7hkWkXmpeqld=&M6biscWdecYeq=&JvrdbnZsbefke=&y5qllQVfg__on=&zYpdhWVsZisYn=&I7SAFzYVghZao=&mkD5EJYinoiXn=&9pCkPOYb_ckic=&nbj7i9ViaVhhs=&3TRpovZZndjiU=&VhhVUVYcVU_in=&99YgnzXjrnrrb=&KXApAvUgWfibe=&bKQOiAWqrfYao=&CsjRXeUgZYkdi=&8VPcCSWrYnVcX=&f7anOhXsrYrkl=&GJU54CZhVjpWU=&KHlVCTZVXYeYc=&aKrqizXkiXYjg=&HeeQFtUahWXoc=&Z8D8YqYd_ZWre=&oLGsx9W_rfhrj=&QwKGXlXXeriVj=&8QCl6gUjhsYcW=&wCcJTwYVXZcWc=&k5rImUYl_poXp=&yzLv_NYkXfrkm=&JTV9VvV_qmqWr=&J6sdPjXUqmejo=&DUoNijZbmlpgi=&a3u5k_XosfapY=&wVW4jXU_rqorp=&QZQOuCVXpcajm=&pisqnaWkYq_qb=&NlrfsrWWoojYZ=&VXbCJsXUjhnYl=&BlCfBmVkdpqgi=&L5ZhopZcXbVcr=&BgwkYPYemhrfe=&G3GL67XihelZh=&2W_KzpXdecebh=&uMmzwNZebqjhn=&P7tKBvWdqooks=&trWB7IVakkoar=&V3WRnOWmnUckX=&YpD5DlVXkopbb=&Eq_iNhVi_pYYn=&ITKLRPVVZqVmr=&vym6SpYUip_Za=&CmUHKvX__Unpa=&GLPTMkXcbdmrs=&qKKwSsVrepUcU=&TyECCTYncesWi=&F4RTP3UqnZinZ=&qGXMNAVWpmbrf=&o5Svq8Xo_Wsgm=&f6RdvTXYiUchl=&p4hapeZUknccj=&DfvfqSViXYYXa=&4PT9XNUhrVZWe=&DPbO7KWUsbZUo=&mpBrrhWgUhnYq=&BgtSAXVYonZYV=&i5dgJZWqbgids=&vPT_LoYerbada=&Car3ccYsksbUn=&6VR5a7Zldaaef=&V6Q3bBXmlceWZ=&UKhHx_UlsbZor=&BPupa8UhWYsYU=&qdOFZxYoXqobd=&uxdWiUXhlYXab=&HKVJxlWjgb_dX=&6lU8MZVc_Xa_d=&c2YoVEWsl_Wlr=&JKimNfYoipokp=&7L6LHbYdVodml=&IUMARlZgbplgj=&BqcnyqW_dsjmf=&B_ue3hVhgrZdc=&VAf8tTXgVVijg=&fg9QnMVfcbcfd=&bku5jAYeieh_Y=&IjAjIWZaYnrpl=&bSb8ohUgoZpls=&nLNVHAWmWUVWn=&Q5rRJNXeaafjs=&tBnoYhUjlalbX=&DYFf3yZdjVcfn=&XCBLPMVlWXkaY=&xEnAP9WcYe_kg=&3DpszIUhhomcm=&8YNtnFYUbWipq=&axrlMBUhdopbp=&VZl8MJZejebnY=&_JscmuZgZde_n=&xXv5v3ZhYefU_=&HX_rV4ZjicVds=&G_DLv5YckUssm=&TpQoZTYksalkm=&sCFjP4Vq_cUhd=&bXzN6uXjXkhdd=&ftddx4Ujlgaob=&5gULtgWXclVoY=&rQhMX4Zikaenh=&TZ7PWYZWsmZVn=&WHeCf6YikglaZ=&OamtciVbmqpoh=&lwX_LnZhfdX_a=&7MkhoKUciiZeb=&9ruRn2Yrdrrdm=&xGSdfDWiWiZUW=&WEVLHMVXrnUiU=&xl9KybVY_snUg=&2QpoybYcfYiXm=&zwOY7yXlojkfm=&MSvmz4ZpVXkig=&syFcssWsgj_qn=&ZGUi8oXideWZg=&AWl8xUWWoVUWb=&kAHewGVVrnaYq=&2qnrlKUgiksb_=&cIZvNbWfkcXdc=&jOlcIcYlZWhsk=&CtQVI5Ykqldlq=&xP_SFvXjghqWo=&fEwNsrZsjlsZq=&cjVjZIWckmUVs=&5wkUjAXmdZrqg=&iZlrTjZXfqmdg=&mpw9_4ZnkVsbb=&9BK8RCYrajkbZ=&9VBsKkUom_Uih=&CYSMujZqqsopY=&DUAKW_XVhiVfl=&b4hZ9KUmqVgkq=&jKn4zoWgnsVqf=&EhpdDqXWbqUkb=&tACJwlWaUgbVs=&phfWqpZdlabhg=&V7aoNcVpViUi_=&Lmi8_FYVUUiaf=&vfuUd_ZqUbVfY=&xyljjeZZjlWgf=&lS7WfrVpjlYVf=&yE8i2CUhgVadm=&rs33jIYVosXhk=&IhjXJEZrbfbmi=&WAmp3CYWfbbYh=&YQnXMlZbiklib=&iUTJH_XhbiZgW=&qrfpMCUmUZUVY=&mcG2JNXpkmjiX=&wftSPcXfmsogg=&QSTq6WXUp_iYV=&ItUwEMUkgirrg=&vuNYieVcjbqma=&qF44dVXnWognV=&CI42kyUssqbqW=&wYvYsIWeUYdWZ=&FHXDkgXVjUeYa=&joeW28VdhnXWj=&wGda9xWUbhjnn=&cQrvmMY_qhUVj=&Tif88lVsqgrXn=&pK378wVoVWm_d=&rWQXhXYneWqgs=&TwRYF_VcYhfpc=&tOYv9LUpfdpq_=&xovLejZWdl_as=&nlSXTJUrUXeao=&xCX9wiYdoWXpc=&XTwR2kWbUopVU=&exE_ViYfdidZb=&nZJFRTVZpYmnr=&9w6MYdZgrhZeh=&9toZDPYjhUkkj=&UMZQ6aU_ZW_ie=&8dCfGHUYmofU_=&fm9IUiY_YYWrf=&qCGoQ7Uebciik=&PoBHOyZUUldaX=&E2BrHxWaemaYq=&KsSoz5UlgcYre=&JmKkAYUjfheip=&EDJ9AtVmo_qVg=&E8H46eUglWodZ=&jhij5SVmgbgnp=&yF9PwkUpZanqW=&NyOypKYUgVqim=&qcQoTDVeohn_s=&cUYk6IVbVgnbb=&UTSx9xXXaksma=&HBeZurUilgfVe=&n_vNXoWXqlgjY=&XzvKylUbpgiba=&Bo_yKMXUclikk=&2v459dVddbfjZ=&umImNeYehhXYZ=&XsIKRmXZhfeer=&xyb_SuZopkaen=&CzdzDRWefosng=&RnHACnXpfgafX=&AnE8mPXsfihfY=&vJJYK9ZfrUqpY=&VWUuqgXmmYrVV=&MHyS_oVcqhnaV=&XELpFeUpiVnnr=&X9xHzfWqZjkqg=&vltCjWWl_eefh=&vMVQUlZrhiWhm=&trG2LIXabYYkr=&J_HFrrUbqVXX_=&FuDyLOYs_rqeb=&FKkNYRY_YjgZe=&OfcxtdVgg_p_n=&UHZfKOVfVmnWm=&3K9u7mUrflagm=&2IH4bPVkX_ZXe=&Xe2BxvVock_Wn=&maDGt8UnpoZsf=&T4YQg3WsoilmU=&aHNw4vVpqkWbk=&WVrHgAUn_rsdf=&H2gltjUdlaWUa=&gsf78oZfWhpmh=&Hv4XumUVnXlgj=&JjiluAWZsd_a_=&HOqz3AViYUeVX=&gahCLcVksefah=&CC73TVVUicZqh=&ZB8MvCWXlhdkh=&mOEslfUeqUkVc=&OnOMGgWqVgqar=&6qOmrtUbVgcUe=&ljDDo2UYVsad_=&9bSFd8UbVkVqg=&s4XsCnXmcismV=&GJZEnuZ_eerfh=&VBU_C2WjioZmk=&6m9BV9ZlsaZcf=&UxMgO6Vdo_pgs=&vXmEuNWsXWXrb=&jV5HEqUlsWVZd=&MJsuzsUYgfmai=&aVr5kVZeknllk=&VHbNmoYiYrdgf=&ekU7jcZWag_YX=&zLjWvBUdrrUqp=&QBMlI2Ym_rU_d=&mKYGeRXigajXl=&abIUWOWdl_fYr=&uwkmkJYr_ebYs=&AArr8HWpqlZmq=&Yh6z9vUajrcmh=&j7EMneZdjg__m=&kFqybJUaeegbl=&kcUkPtVYoXeob=&M6qWPUYcYdcYY=&_Hop4TWgpZidY=&WHQ6ysVZncXep=&MbOMoQWnkX_qe=&AXAVdAW_dYaZY=&2H6jmHUrperon=&LsJiTeXcdjYZc=&ao9Hv7XUcigpd=&zEBH5GWcnr_ao=&r8kYgiWfrrYgm=&Zns2ZnVhVZdXk=&Mz2xARYeWUVrd=&E5gTMBWfgggdX=&wIYlfgUbqfjYq=&S2xR3TVjpgUak=&fMFLLNWqXfmgk=&JTrbZrZjeZcjX=&B5tiTRUonlZhf=&Up9FA3UUXpVi_=&4_JEXeXcZYprY=&QzinaUYpdYdVZ=&eTfhleUglm_Um=&L34raFY_h_n_r=&bxHscuWcdlfsn=&iK2XgvUol_Vck=&GokWx5Z_p_irh=&lvukdPZfafeYk=&lqMm8gXpqoUXg=&BMWF9BYXsUlWi=&WDuJHCUrqUkkX=&cvKMmfWZd_XWe=&efQgvTYYoYU_c=&IRLRsYZncjbqY=&FKW7dJVjbfpjW=&HyfxCtWVdjZf_=&Vw6EWaZffdWho=&OHje6hWmfXrlb=&Mkk6QxWerghbg=&uhjcA8ZqraXlW=&aPmuCFXsXicol=&zB5z35YbUsjoU=&Ifatg7X_emnWr=&WBQYSYWnpir_p=&SkAD3IWZjjbdp=&gGvKsgZgXklWn=&ikUNZBYsokWlh=&vIkMjPUkspqcZ=&QASCEpXqlkhYn=&chbbLGUjqfWmZ=&3rd6CwUgm_qpb=&2CJumRZhb_pka=&g4lE8hYsmjffg=&QEdhSVYeoV_js=&_UwBwKVYlsfUh=&9eDNiXZnsZUaf=&a_bQ5HWUgfsUY=&XKzd6QUabjnbZ=&JdKnAXYhhWcqZ=&pbqmpqUdXgbdi=&sR4kjzYndhVVY=&JVV_MTYjWeccU=&yNqQ4IUWeeU_p=&OLJy7yWbqcegg=&sXu8eoUZgXdmk=&IwWFAqVlgbhcs=&bsmXekXpjqqfp=&Lke6joUgWZpUi=&onS5YTXXsgbks=&9gQHeAYiWUmea=&bWKvq_XbrnnUU=&W3Hq4iYUjXplZ=&nfviirVrZsZmV=&ZOFzOxZVnYrXY=&JFDHjMYaaaseW=&5G_AB5Vfqromp=&3eIEhQY_bqkmh=&XlHCxrZVqrhbZ=&raNwpmXajq_qq=&53Mr6gVbqYqdU=&rITmlzWeVainV=&oIC3RhYakjcca=&3TxCwHYfiZlcl=&9TJ4Q6XfZrgcf=&ylCSEsZZpaecZ=&6IzjbSXpUXrmd=&nZfuxuXbmlaqk=&HBenhLUU_kUg_=&aHf4MKVhiqm_Y=&lMbgkVXjVgiin=&SXAfM2YXpgepj=&LdcMxCVaohYoa=&PwvsJUUXVbi_n=&aWJYOtU_cfces=&NFYNoRVelcnkm=&7Y74rYUpeUjno=&3bfs8qZUqriac=&MbpVUjXcfqbpn=&Z6qINyXcnVhhl=&RtYpi8XneXfkp=&qawI33WidgXsl=&w_Z5vwWmYqool=&TCJ2zQVbcbdsb=&Nyi9DqYWhXgcl=&cxoQ3rVkfqnfh=&bhr9MvVZmcnlh=&cTSGdoUdkbono=&3X8wQpUsfnXZe=&3x_noXWciZc_p=&gpy33WXWkfshp=&XtiH_wVakdmim=&JiQkGQWhoVVji=&sz5ZCwVYsfqml=&mUCK2lWVaWpjs=&yB_DLGZheVhmg=&ifmXnrXUWoUio=&JDLgmnWqsogqp=&kCl6MqVkUcfli=&r4Xas4XUrcsYZ=&NQychUZjWkhqa=&fXIGWkUljmnhr=&N8g27FWslVeVU=&DIMtGuVXY_Xim=&slmnsaUhobhss=&A4I9klUaa_pog=&qyCg_DZYfXVsY=&rT7mmoYfYhaVe=&Zq82JYVjUcpnZ=&jd4rsoVsncnUg=&B_dRHtVfemhef=&s_x3biUXnZjiV=&3_hof3VbsimkZ=&R9gcFDZrYYchX=&IqWPeLZhodrfY=&htrsIAXkjhVga=&_LjJiKWhieojq=&meEivKUllZara=&YGDjeuZbiWhfr=&_Db7hZZYYfmbg=&ddohFXXUlaibp=&DN_gcIXYieYcY=&kw8TZJXaeVmgf=&aLu8o7UdVUoXg=&3dcmMyZVYfXqc=&x8QCD5WWciefd=&jqTHMAUm_qXWr=&wlJbgEWelZWZd=&vmiCfIYeYaiYr=&aJa7WLZboddgn=&RMGj_JXXighaZ=&629LJ9VnWdqdp=&hIWizcZdWprgn=&j8OYPeZpaUZja=&poUw77YoXliso=&zDdMGrZbadckk=&Ir6I_mUbqcelj=&FdBCrOVWgYbdk=&5uNTUHYlsfZji=&IQUeljUXfgZqk=&Rz9DyDZZoUWcj=&BbDsCYVUVVdga=&APQUGkZbmpjcU=&2YNvmdYbegblU=&eAuTgLUcfomgk=&ZpVFDCVZoYqpl=&NIrhJHVljWUaX=&L6ck82YpqWqdV=&8gs_V9Z_dikja=&E4jph8WdgXUai=&Ntv6tdXkillXr=&NAVNZnYqYfrco=&sGfUkeZk_Ziqk=&ZunpKPXe_ssYc=&hjzjhMZkemXfX=&aeQJAtYnsgrpq=&Bw4lZsX_ecako=&m3t6VhXihiokb=&FdvTj_Y_nXoeq=&EUMbunVdfZrmU=&cRe9eBXfbohfs=&RCddhwVgiUjVc=&ntVVoRZrrUiZo=&oveewKVseaspk=&TRr6r9ZdbdZqf=&87jnM6Y_dcoYU=&4B8ZIzZk_UoWj=&c7aNi3WqlhkXh=&OdJTdJZ_Ykdas=&hXijB6YhUYoeh=&v_Q6_OVhlhXlZ=&aGXAZWXbUghlf=<gtVIXbplnWq=&xxasJRUlX_Zg_=&X22tb8UdfXiqU=&yqz9XiXogrpbV=&brvJUZZbjmZpd=&6woAvoYnXpcjZ=&r3_evaXkgUUYq=&ctxFqeUdqllkV=&8cBPbQVjYW_pe=&87Z3laUdUdgWU=&Kd9SV2Wdceari=&KjXCgSVhgmrUk=&NYFkcJVfZbqnf=&54KqEhVbUkjlf=&O57BCoYVqWnUa=&vm4fM3XkYbdqr=&lXmKhsXdXdmnh=&L3Lx3pXqoZaWd=&7hqKEEZrcUjns=&M3Ts63UWWbrZq=&eJrZJxXnZVjgd=&Yh_SDjYgqXkan=&cJWxkYZmXWbjj=&3Dgrf2VYahZWi=&i3Z79gYYVqhWY=&Y_tmlCYYheejr=&ghvaXrVibXWYk=&lvNeeBXZqhnor=&QcqrAXWiWpber=&OzYuKjXcrjrYj=&StnpBgZhWedrl=&5xffj3UfsjbZf=&m_neThVYVYagc=&WWAshHZkqWm_U=&xHW5sCYbegVkX=&owwIiJZehfdhb=&Fff2CWWVaUedl=&FmV9pqZqnmZmn=&TUzLweXYb_U_c=&pExsrxZjekXes=&cWOeVlZUrXVns=&HnCKt8Yqooanq=&sVLl9KWUYhlaq=&ta6HmTWfksjkX=&zASq5nXo_baYj=&EyeG8SVerapkd=&lPx9VlYonWal_=&RJ8lltYklijob=&WiNtwpVUhsknX=&VPGAp2YWijsfb=&PjKbfrXZlaXpf=&HRVmyxWasUXgU=&3mR5FLVscqfWY=&JmW5P9YmjXghg=&nExPPsZgqpls_=&gHQKdVVXbXlna=&CfxNzRUshnjrW=&aQB5ROWfoYapb=&Vb8FMXUeYhXsY=&PpxsFHXZqVVmU=&_iPpUzZVmhfnh=&GRyiiBU_gkYcf=&G2GUqRU_nrofY=&znsbWqZsaqgkd=&P4O5RBYhdopqo=&798yUDZUjmnpl=&AQRdx6VgVZbXe=&ZyZ4hLVfbrfhY=&_eesulVYbghej=&RndjKqWhferaa=&krHk7UVsYWoWe=&igStH7YfcflUa=&hPHB2fViqasUU=&qf6dwPVa_bshY=&OQAXyQUarscmb=&hF_qgCYcrhklg=&JrVqcOVYbsce_=&pCvVhZZUlmnVc=&KNqE6mWjombqh=&CN5e4YXYYXfaU=&jQNT8fVdkkdrq=&eCiPPOYefdXVf=&lQE5HuYaiZmZb=&Th4kuYVYhg_kW=&L6wXDsZknXYqg=&zCzuWZXZpqWkX=&FrFcuLWVXYrpX=&QeIQGOWUniodl=&XEoqjRXfUWnVi=&IsUQJDZmldfWV=&MW2WFYXfqanXd=&ZmpLa8ZgassiU=&cvEqYqXasqm_j=&_4UZ_6WekYjda=&PmfAROZeWWman=&uYTCzTXWWqhqi=&cY9_YiYlVadYY=&VhldW3V_kejsl=&sEJVrAUhVfXas=&VJiUH_ZZl__kp=&pbwI_dUakrmen=&FhD8NcZilnVaa=&FSidp6YZjjnni=&OfbHMgUarVZkr=&QhRrCUW_qZlmU=&ZuZ2ntXXnncfV=&rlhVsoZlsfdqp=&2qM3knXqnkUkn=&LnYTv7UlaZXUe=&tqI7E4VnWmcXW=&NwnhUpXasYqXn=&rpNwuCVrXdilZ=&4hg_LYWnqalYg=&HWJuaOVXmabnd=&qpK33nXgacVne=&XEhf7QVZjoafm=&JD2sAcVWjfhdp=&UrDD89VXaaUfk=&772g3wXjZeqcb=&QO4Ah4Vrmpmdg=&YMXQFiYmkXkWW=&mSYYlbXoWWhdi=&4f8baRXogcaUn=&lqkMFtWcdogba=&s8APrVYhceWfr=&Uz9sQ2Y_ljqkX=&W2fVkFWenWklX=&eEo_SMZfYmUiX=&NJA3IeZqV_obW=&y3SbOxVin_ngi=&5_7VGNXndojde=&HBPqhrYeWsjli=&3s8BoiWWqdUhd=&A7euqhWqX_ker=&QPRw84Zmipofk=&pEct2jUpheUkf=&oFOaWmZn_nsnW=&ChPWoaUdjmZrb=&7J8S6EVheXjXj=&VK7S8CXZpqYff=&2mYnIcXqZhVVk=&rkvAauUedmqXr=&kbJA7OVYkbhWi=&DkquaFVfsnqos=&alORBOXiUdpsX=&qVrC6vWoanhUb=&u_GWhsXl_gYjl=&SQa4YxXq_lqWV=&Jm9HsbVrYjilk=&jUo8B9Upmikn_=&DJodzHVsrjnXb=&ASGWxMXfeeicY=&EgEBMIZdno_mn=&9sgCAYX_UlhYW=&h8nFI7Y_sfcpV=&sA6R5dXseocbW=&OSFfISXhXmcXb=&VMMaqcWYsp_of=&GGzzZOUVdUZ_f=&Xqv3pWYnoaWnU=&tRUCnCZVan_bg=&K6dSteXrrliYi=&WwzfhZZjUalem=&gZAJueYqasils=&dIKUCcXlpdsrp=&UPkgsFXdef_gY=&SiquBGYhsrosk=&ERWjZCUZcg_r_=&9fp4ovXhWsUnW=&CditpHWmeXgll=&E5icn3YsZpcUk=&FrKZ4HVmdZVee=&lawCFXYbaUWXk=&hmzZ8PYfhZiYf=&lVFKgOXYibhhk=&CdOB6pXkldVkh=&C5XNDYXddgXkY=&Pd32McZiWgq_p=&ue8aucXgVchod=&p3aCirWhpiarc=&Gnh3MsYkqosap=&tTVfwjYiiqUss=&I5BjoRZeqbefn=&txL3IEYrXrbhZ=&ZbXYvFUrdgWgc=&Ef4gk_WZVcgmX=&PgzwU6Wkqcfsb=&FpvcDeXok_dVo=&s2wAyLZWVWgVc=&mt49gvXWiomVc=&H2X6yWZipkdag=&JS8GnJVjqja_Y=&5WiWo6WlXhbeY=&BkcldNYefmkWU=&7vaf9WYnanUXa=&hXOjaEUZYaebs=&jXWwVXXlWobZn=&CI9rYdZjU_j_s=&sloXwTYcZWosd=&gi4ANBWbiXpqX=&UkeUAlUfeneee=&TXZ59LUnkrifi=&ojki34UpWkgjf=&dADyNEWhWsads=&mwQbHjVoVeWgo=&6DPXW2VeaisZi=&qa3yKTYomhjjj=&AkxygNWcnhkls=&lYqi68XWbpjim=&lLBiZ5Xee_XmX=&o9VhbaViVnahg=&_lxfEDVsleXpb=&tKHtU6Xqfcnio=&OhPpw5VaaYbpb=&R2SNHYWWbd_V_=&GwA7YeVcpXmbV=&QzXl_XXhUlXpo=&FG_A6lZasYUjU=&WWmzDNVggYqdg=&jqI3qjUenkkbh=&AXVmUEVoqaVZe=&zOVrX3ViojbcU=&uqc4rcZW_Wpfc=&oSk4QCYlmZZdc=&9SsRURWrpcgXo=&YBr8BNVg_UVkq=&HIaUcxUWajmhj=&ENocqkVfoXrWo=&WZGJI3UsojpeX=&xMhRgRZZaljgl=&a3lDi2UiolUlU=&2F9d_AZl_iem_=&EqeCBzXjUZjpY=&7S4qnGWeVnZjb=&9Nz5DYVmdlWjq=&kMC38MWfpUXli=&ZesFwwZZjkpbk=&qptJaNVamckqc=&7JxK5UYVXseeX=&YPnGLrWeZXXos=&fbc85LVfUgYfq=&r_cwM3VkfWjkh=&otPkUVUqVUk_j=&A8dRNtYgpWmXe=&zZxEwwXWXboij=&tqIsxAVcrodWg=&rmyRwsZfrWWdh=&tTkIZOZj_spfg=&YGZoBYUqeaZpb=&7zirNWWrajjnW=&67BJhgYYdgeUU=&JZlsZWVVsgpfX=&9o8hmqWsVhZg_=&aujdEXVVUUgbV=&2lzoO2UclsXen=&UJShKqXUsmnqd=&pDOxjvXeUiUgV=&hc62wTYYUmUWh=&pMB8NKXiYccVX=&kawzX8Ycgfrcm=&toAwWTWqmeeZo=&j8VpujXfnYVke=&5gKILBVba_Vpd=&kZCBi9Wkiaeji=&diDYYGX_mcUXb=&UBAtqiZbcZoVX=&dS5NjDYfnlmoi=&CooVeqZajUaeo=&UtRYXyW_hbjf_=&HJ8FHxXmegmrV=&JEDUYFVWWVVda=&YhyKmiUgifpcY=&89qOpwXaVX_kW=&iJsjDLWhXclak=&79NqPJVhhelVr=&3P3yXxUjdpgkb=&GHtnHyVcbWpsk=&svbu5sZgZZpdo=&3OTbexVqmnkiq=&FcKcRqZqWnkiZ=&XctLWyVsbZ_eZ=&vhExW7WXpXlea=&RrNQVGXhWYsfs=&LdaFbTYknpqgs=&H3uxeTUcaqerb=&xbxh6zVaVjVVW=&33lIHWVfhgVYX=&HeHnCdWcZcgeq=&BRYChiVkaWacb=&PCYChhZi_rnYd=&j2O2SJYUer_ag=&5okcmNXYkrccU=&GAw_bXWUYpXhW=&eSgCrLWie_ZZj=&gXBzOyWnemVcY=&pjStKnV__qgWc=&HmuuDCZrUXUnr=&jlMFhdWZpffhl=&5BS8GKZqZhnnU=&6iSkvDZZfZb_d=&YfqgjXXiZVsns=&YBAtSiXkjjcso=&K36dNAZXmYfpW=&geqkdAXels_ko=&fjqHoxZqcjjWi=&mFakMUWnirVWf=&XwHi2jVZ_eelc=&kakZWeXilWUma=&yJKqdiYbiWkWY=&4QIO4BZrUjXhh=&qk3xDUVdWsabU=&EcQGHgZriVWlg=&SAbrVGZhonjfr=&7JDY77XfVrZrd=&TRBvrZWojYbUn=&2CLM7NZZYobja=&EJKLgaUpZVUc_=&v2Ys3KYe_fjYj=&hIplbOXgsUbVi=&OD3ZGSYYksjss=&iebID_VqfVfsp=&rVLcPHYUgqYUo=&5AdbzHYimVsaY=&ni6vsFUqmXZUj=&7cyzcaUjWUjUc=&KEchejWldaenY=&pRTLgZW_gseUk=&s7wZ3LWn_eoW_=&E85_XEWXbpilV=&84l_7NUjUorUr=&M6OaQLVWqiXWh=&bT28RGUrrkkZl=&tyCAQIWraeVpn=&CyMMwGXokVYir=&ns3YDWXVmrfdY=&BOSv2NWbWYjcl=&XR8XARYeVVaUe=&uOfAOMUfmchbn=&wZ44f4ZsYdqfd=&JinrKzZVndVmU=&fuFKocWkWdafh=&Kb8uRhZalsZbZ=&u833VlZmljid_=&h4aNqNWZX_kVe=&HNHmL7ZnYhnbg=&A33VTaUWqspfV=&WVB2KCW_lsXph=&LHKAZ_Wjefic_=&F5Bc6aWiUbnpV=&yeYfYIXraldcg=&PhLpirZUsnnpW=&VLspAjUXZohio=&MTs_lCVdadVhg=&vyPAPPYcfbeap=&fQuKr7WVdkrXl=&ClGZtuVikfqaU=&qZrqe7Ybfghpf=&yF4DkdVggkerr=&AD9uF2WshWecn=&JsTlq_WgskiZb=&6EXJYtZWqiqYs=&9tY2ngV_jfcpY=&Aegr7iZ_fmpja=&WAdEiWXdUblnn=&GMHsb5WcVfojU=&Nkl_m8XX_WisW=&W6xjJhUnWgnnr=&pjYHyUV__Xjkb=&bzRg_VYlXWVsm=&K6qFMJVUXpaVc=&KrtslnUladZln=&RwKm3SYrigikZ=&FyewLQXqomXgj=&8SeBd8XrhhqiX=&IiqxEaUgqrqlk=&YAxwCcXYjYZlc=&Tcn47HYfjUmcn=&hzMCZKUVgrfqj=&Ol8nkwUskh_qf=&ZiKpUzWrlgrYp=&HjdqT7XUfphbm=&55Xt78WVnihnW=&cwwP2WZqgZpdj=&uOpaLgYhWniro=&sM5RcBUrpaYdi=&kyCA3aXVhk_Zp=&K5NiJRX_Uiddb=&BbDuFSYn_q_VV=&SmbvlyYn_nsag=&yLjiP6XfrVUcr=&kPJj64Uqemr_n=&yROwOAYqoedVm=&YVavMyXVpgsnh=&nmrrqaZmXobar=&RDM6NgZbiZ_pX=&3YpUFqUVq_gUm=&g8ouC3WamWcse=&8cpbgbXUareZU=&gcK9QNVhZordZ=&vOt5xHXllXcVW=&AJrDFrZZskmam=&OswDj2UV_qha_=&NcRxrcXphVbdn=&I5sTWmWniYkaZ=&wyWX8_XmsUrYb=&IsGM5XZnkrglm=&PumPLnVshWmgj=&NWDHy3WgYjsbq=&VLEzqrUqU_lss=&RuMXvDVZahlWl=&qlHX3GUgplqdZ=&PNzy8jZ_igmqp=&IH6ioSUdaqg_g=&FGKkWdXqXagmp=&TkfIMsUhXmpXj=&bsW23oZmeqZpW=&a5keCwUpUfpqi=&OrZ8ixWfkdson=&C4wWe4ZUccooU=&pIiOzXW_mdrsW=&O8_H7iZegYalf=&LCyBsVZikfipn=&Xb65EEYjr_mYm=&J4oSEyWdol_pW=&_iIli2WkrY_Ye=&ypKwNaUZjccjU=&9TzoLzXrqdWXf=&btFIj_Xgkamqm=&I3PFWdUVo_jes=&vRXahLXVeUeVb=&LtImXJUbgYks_=&hp4LCQUkbsmbd=&KP6spQX__mZqi=&Y3BajQUq_fheZ=&CRFUFjWnirfka=&Rav57ZYheZUoi=&PegjUhXnsYord=&YIlsmvZioYYXr=&Vz_rKiYkeUibj=&MM2y2yZmXkdlV=&ZFW6iWXYaoXXb=&HX_oKRZsjc__s=&NAow4wXarWXes=&m_gWDJZ_jXYmi=&wTQQuCZ_WUVgY=&QBKQq5WfqXUsi=&sbamH5Ugljqab=&AGXAFIXmlhmZj=&DCUtZOUnfagsm=&FaABFkYjlYclb=&SQVKg3UkaoaVr=&l9RWxdXdlgran=&xDvpNyZqfemnb=&Qtk4jKVVljqWk=&Bg4isPXieddb_=&I5ELj9ZZ_jgss=&otFJkXYesnbpe=&hnpdIIUp_aaWg=&rKqIh3ZZsrZUp=&4Ho238Xapkerg=&c_N4lMYkbehU_=&LMKwCAVmlUcoq=&5xvLUTVqcUirh=&Ffq9AJXlmhVqU=&qgRcnMVkihUsr=&HQEwyoWfUorce=&kVUwLOWcaX_dr=&9_vTxjWo_grfd=&HtAl4_XhsmraU=&2yow9dYcignq_=&beVpQZUp_fgje=&x_JiUvYWqjaZq=&ItUAtGY_WViqq=&ZVckT6ZiXrfor=&NLsBccWdneoqm=&YHFvrJVqpmrcZ=&UpZelXVdZeXXe=&gYNwDwWspqoXn=&bp7QSjXqpinhe=&aSiBVzWsnehdX=&5CgsM9UbWhngW=&b9VwyBVqejV_d=&uGijbbYijgjbr=&IUWepUYflsgkq=&gDyu6rVaUcYWf=&T2AW_tZieceXc=&mDKL9NWYnqWZo=&HaVY5oZibZZro=&LR6DebYqqYikm=&QLD2zQVdglZeX=&y_vHSyXiZfh_l=&RMsPFSX_iXcZl=&tzxp_rZgnsphU=&ukc2PVUdieYWn=&YJ7K_tZXhgaaq=&_3Z6R2ZfmlmZb=&t2OAVzYlkespX=&ZTBkqUZVpVasU=&A7bYWEVflimnc=&DhvQjoUVmrbWY=&zhJSuOYniamdo=&xHxV6uV_Vsedl=&uciAD_YVrXWjq=&9V7hilVanilej=&8AUgH7YksZdoh=&h9n94rWacqjnp=&a5mOzrUpklVUc=&WeWxGWZqiffls=&b5ExeUVfgYdao=&uC33i4WoWblWa=&ZHpTPCUWbpdcn=&nLbtl8ZaapWVk=&aeWr4LZ_Xklb_=&u7gpdUYoU_iWd=&6EIaGDXemUVZW=&NWx_xSYefXVYf=&CzzTBOVlmjcem=&acoRCsZqljYal=&OuktlfYZoiWdk=&WfRC2AXkWUpnX=&EReELWUrVrafp=&TjFpuJUXfk_og=&4iI8q2Wsbbmbp=&dBuDekYWpras_=&EDghYSZfU__gr=&RmX2iGXZmjf_e=&TMOk65WYZcek_=&nhHFu2WdWmUkh=&x5J4XWWeliolh=&XuA2XUVmeZimU=&s9SmrvXopcqpg=&GzzryoUnmaVqc=&ybqAiMVljmnik=&2bbfwwXmWbjUY=&F6Sh2XYUUbrVr=&ENGqwJUjsUbaV=&MeH3YBUsjggga=&LdvHaiYbYcZ_d=&agxHahWbZfoml=&pHbQwvVZ___af=&vCHxFuWaWerVb=&KaAsCUVVrlVia=&jcTSwYYragVVs=&PFEWdlVereYgZ=&CMYWPUWbmenqm=&eT4rJ5YUppn__=&ByUuyzZXWpWqc=&5NnNSGYVdZZWW=&cq7735XaYfnas=&hfd7oGUjqraZr=&4WyWLkYhjdVlY=&7gTDRSWpalkk_=&4JIt7aXrUZddd=&w6W_i2YoZgs_Y=&zHR9GTXecdWfY=&CVQVh4Vgpfeee=&yaelTgYhWkhsj=&AmUFzwYVWseai=&eLTDSEXYlbomX=&I2BdxeUZpflWX=&cUd8t2YmVcbVs=&FwLNiDUWan_Wo=&JOqP2UUWpqiVq=&_L2vgvYVjZXsb=&q3CTwBZobsYbg=&H5YpGBXWYmcqZ=&9rwe7wWnlZqdY=&dtkjUHVmVjfef=&EDG7KtVYWpspk=&C5WmXhZWsqnWV=&gJhTbOZnbmVnm=&hbsqhBV_okUqm=&ldI5BJYef_XUh=&QEHq3rXqXpYkY=&6B_PnfYZjZjbX=&fI9K6IYpVWgWj=&lfhZNyWdkVfdg=&XmMuhIVbqYjac=&vY6suhUhWVfUn=&FciygIYXXYpoh=&IGvqshWXhddrs=&6XFVLfXbdbVnf=&_THLQaZedkcXj=&vh3GPsVnVeaXa=&xeqqsTXkfUlqo=&I6GtkHZUsrfch=&33PtnaWcgfasn=&IO9pZMZYmZdVh=&DxlrqkWVqmmpl=&seLqLHVrnYjbl=&fzOWmTYjcqeWn=&6VIcMmUsVidmn=&3Dv2qNYXhpZZk=&cgXwhdYj_groo=&Dm7vI7UYpmajZ=&pd7TRLYqqjmfo=&xY3ETOZhZWqpr=&ATeQAzWmkUlms=&2QvctfUlhjgis=&3ab33PXiYhfjZ=&CfTbYFUZqZsqd=&N9oNAtXinqU_U=&sYU9UBUqkVonW=&7BkJz6Znrmeis=&fH3HfpXjflYnh=&rvHmNZWcWkhfm=&RAtxnbZWUfojj=&_WimSFZiYWdcU=&v9js5SWWsVoqi=&T9JyX6WaUZkjZ=&ylQMMbYcVbaUh=&ZitTXMUVVYi_X=&xL2XAaXab_dZp=&FPhOB_WnVmYda=&VN8AdwWmsqYmV=&J2QFz9XbUeprr=&epOvSZVZhXoYq=&THQMcwZolVbje=&wbRHm2ZpjZili=&aDNTCpXZnfkml=&LMbPozWpgUUkq=&SLFXrTWXnaYce=&l5halgVYskdYg=&bHWcIqZjjiWeq=&eIxbZZWqXlrhl=&kTpmfiXorZkZq=&2OnRVUVlqdjqj=&w2DLcQUrmVdjW=&AFJ97gZ_pbidp=&2zHvSLVUlqYXl=&wOYyJvXWgrhUU=&m6h6rVXfXbWdZ=&okIvUtYYmomja=&6k7ipoZrfigoc=&eNZuGhUbkijff=&cu_tKXUUkWnkW=&rTSESZVrmjXbX=&HgJYSMVpcpsnd=&9mOL6NU_nVWa_=&oDBfKSWiokbX_=&Irk_bhWkmcnsl=&zwqSHSVcddlhm=&IkNQuaYVkfsrb=&yZFLgIY_qYWYs=&3yzwXYUdheeaf=&KkFX_HYVYYnos=&4tWn3vYdaXseh=&7vRMqyVirhnbY=&Pd69wWVaUfspj=&i3G7wGYlYZndn=&DULlbeYehdhhV=&tdwcr_WconqUr=&onlML2Wfdepmm=&HzjGBnYVnbWap=&CRSbvGUXVqWfV=&pAWslzZgWfVmh=&kizYf5WgidUkg=&Aasf8aVlaUaVU=&jDfr54UjaXojf=&O7arkFUWidhad=&YBuWV6UliYWXm=&I_RzYhUgipodU=&I46iSCVssUhcb=&tPoORqUaXYhhb=&wpLaxYZsZUUW_=&HklFdVUhXoWjf=&CyNfplVrWmaZo=&gabeMrXfq_Wef=&gxbj4JYmXaXhV=&N4uFihXiagZ_l=&NhjIFeZpdUYcc=&y4rHGFUWjmgck=&oqwQ4hVUreiVi=&cY6fRGY_apogb=&dd34LCUq_lsck=&5KyPsbZcie_YU=&LXqu9eYsmZmUe=&Ep3e5lXWdWUkV=&6YDluWZlgZlbb=&k8Q5geUkqeedr=&t9NsJWXoanoms=&wC3iOxXZslbnl=&bEE9LxZshkdrg=&Rw6ziEVYndVVX=&mCzDkeW__lfcf=&bDQXWNVnlgUYq=&FFfQ9bUhhYoor=&bUa9xdZ_eo_ef=&Bo4YJfWqcgkid=&_lIwYzYsdiseg=&92AxYMUiaVcbf=&XFJamQUlpXahi=&mhAXXsXjXeocZ=&Nxu9hdVerpdbo=&YAPwvmVfVdsbm=&ulmCAiUWVqoYV=&SuhnGoVosXrdZ=&ko_eS8Vqeifoq=&OklQpeZZogoWp=&l32nyFUmegW_l=&czGB95UkqnjhY=&oBdivVYXsqZVk=&IY6i2kZkaYmfX=&XLIljuUqs_siZ=&rgnLQtZXopikq=&UnAGm5ZgoVaXl=&hoiZWyUpUja_b=&M5VdUsUpUabWj=&SxY6QaVjXqaVn=&FcXY4WZcXbsgb=&YinnEHXYihlab=&5HenRiWakifp_=&ovQGiwYcgfqjg=&aIOOSqUXoVYn_=&IceMCRWkejYal=&jgL4gpU_ggZWo=&_7ObOxXl_frqh=&jBqRoSUnckmZe=&BnEGk5X_qdqgb=&V2hlsLVXofWod=&pAKhpbZWmjrqs=&rVCS5bWVWUnlV=&fERFBPWlXfVZb=&gmOM9RY_rgpac=&HtOKanYgkeZfc=&RziCK7YrpdbgZ=&9SDyPeYboYpab=&7tbCwmUZgqfcZ=&mwncFyXVhoZ_V=&N43hoxXehVbof=&oEIofxVUjqngg=&bDwSEuXYZs__b=&EFin25YhnnpsU=&VjTNiyViWogUq=&qMTX2RUrWfha_=&EMnR7yU_fUkUk=&nubsyrXlVcfgm=&FCzBweXldZqfl=&GfLpMAWnloma_=&wLELMAU_bpllb=&bJeG2XZgqnjoY=&yV6BIBUadadno=&vpcwHfVfVqlej=&BftHxnYliqhrm=&CBHt5pXeliVaU=&TtqhT9Vkmpgip=&aUXbVmZknifj_=&n9w2HXVelpkrj=&bkreN8XhYUjqs=&wTYxo3Urpkoor=&etQdoSXjYWggp=&lbLjLGZ_bnpis=&YWKrN8YplUcci=&rMjHnNWrYcnZd=&usZZpZXknqonW=&mLNs3jVkjZXgi=&GxADYVYhglpkZ=&CNMzh5UjXqVXo=&gBdxXoVWeoUka=&RlWabXWmdgdir=&ftQ3rzUXhgWgd=&4Jr5V3XobhWi_=&E6CQENZYnmofW=&_G7KWJZsVlkfs=&V4I4F7VWgpnZj=&QO7cooVWYamqq=&_zJhCnYgokcbg=&QnY5kFVldc_lp=&q_PO2mWrkoikc=&cZO6WfXZZWmqj=&ga_AwcWpmojpc=&QKdpdbVsaapfq=&EFqBYhYpfcoWW=&rC9mCsYmgj_el=&inKW2eUiZgsnZ=&fQitTLUhobkcf=&6QBYe2UUmhrac=&opPI_GZVsgYsf=&9xzPlcZamnncc=&3PgDaAWmsdbf_=&SQqXVeWphnimq=&6lGpZ4Y_heaqf=&pSDgkcYrslXse=&RQBEDtVhXnare=&HnKcw7UhooqYs=&DvB2rDZrninbU=&GRYUJ7Uplljkj=&3mYZw6WmqWUWr=&WVd5zIZlmkpqj=&m_M8CQWiUchmj=&FEg_HrZUseigf=&ncfmXWXm_giXa=&O5bQiuU_ridVn=&AkdRfhVp_ensY=&df2h8xZiVYkkd=&6dCO6zVqsqYog=&YEmsI9VeUajWd=&kYIzeVVVacrga=&2fqCJlYZYXmod=&dK9JVQYlkXas_=&znQCZkVabrZXj=&EMs8KBXbWgfWi=&fnEBsmWkrYq_b=&_AM6bGWbgoWbh=&KDOpxSYdWYfZp=&tlXT_9UZqldVZ=&3EXR32YofkVgq=&ghERzFVekcpal=&EIBQDRUYmsYiU=&FlV_roXYXbchV=&cdfdezYYhbgfg=&DQVRDDXriiWdj=&OYU_YtYZm_hVj=&xT8rSBVecaZhZ=&RYyfoQYaqsajc=&hwekolWUonlda=&HFosyoVZsgemr=&RHXkYzYggdUqk=&LpPeZSYicrgqU=&CeIr4YYbniahU=&HA5WXUWcoWUeV=&juKrpxWrbiWfe=&pWJFJoUkdXohe=&mCkdrPZdjcoje=&gh2hB7Y__sYls=&D95iwtXkbpgnh=&xZqk58Ucd_UWd=&PCPUEdZbZbdnk=&jbISuiUfbgone=&rhh_5PVUqaUZV=&J5H_YKXpehafn=&YWIEujZspsXUb=&PQovATYmahXg_=&wjilw3ZWdaa_d=&OxT5z7VYUYmql=&VUmMGxW_cnjgZ=&TEMtsHZpho_gl=&Ele8SVZiaVsiq=&ekG9vgXbeohgV=&qySAiIUrlordb=&2AdjC2YaYqVgo=&IawgO9WgmsWdo=&SFpEl3UqYkZqn=&wTXkmCYXnWfUW=&MZFvmoYcXUXqY=&uqnMH2UUcaqZf=&p9FbABUhlfqie=&H7BGENVlidacj=&Qpy4O4ZiUV_oY=&moPev9WnZVhgf=&XweaPDZXXaqVU=&gEZuUEWopmpck=&DYpIl_YcXessr=&mYt6ujYXcXoln=&gaaZYIWbjgbkn=&ywsSyRUckpWfs=&piYvCMYdlerXd=&5alVykZjlblmi=&kE6zxHWhjWUXi=&Remj3HUfdiZVq=&CjLN6bWkqjsV_=&HedqFsWg_sllU=&7pXzFjUbVVm_X=&Wv9kqbXlld_oX=&L7ghnAZgfgnsl=&QwULl7YkpejZY=&jkkAuVYhgWjkr=&HKahoOWcoZVpU=&wqbe23WisdhZm=&s2FjlsZbolUrf=&DUUp2nUZXWZkW=&B8I8AUXXccpdg=&SRdfrdYhkffZk=&xhCFpdXbmqgks=&CEsWuZUmnjfsf=&sXZSouXhdYXYd=&2BtaeGYgVZqXr=&NJjbSvYVZhiWj=&iXtyqeUWhanUd=&rybaftVb_se_h=&VZOEzpZbgjZZU=&RsWTx_UqaWj_f=&GE6UZkWklpXgo=&rutblLXh_WqUW=&2WllqYZpjfZZY=&AyL3F8WdqZmVj=&Rg7XkiXraoZYU=&bXQs42XXncVhW=&XwLPGUZchhlai=&Ajl9YfYicZksl=&VK9rvjZkXWrXr=&qqu8WyZmspbr_=&aMHOWZYmrmeke=&2xcQ8_XpdXVVa=&nLo_bvZrYeXck=&SQSJEoZmVbUhk=&LKTgSAZmmZYgh=&EWg7p_Ujdgcll=&fqQTpNXWfVWdb=&Amc7a2W_cXXZj=&wMOMFuZqbsscU=&kgiD2QV_qYmdX=&RZUxIsYYcfcUd=&iNLDrBXmYXWbf=&yo7hNIXhqdVfo=&8HCVvJUe_jZeW=&9oXfEVUYsfpoe=&2rrkm2YprsXUm=&DRsGDcYVljibo=&HIQVA8YsaqfXs=&ESjBnUVYkdlYp=&KPkElcXkjnmsm=&lLrZjbWpqprkk=&BIeSDIVVXkgcc=&hmS6vhVgpnnUj=&3a5sGnUclfpjo=&T4pgx3VraZnl_=&23nq3wZ_WgVkl=&4vL8UlZh_emsY=&kMqBhHX_sqXsm=&efWeHLZhpVord=&YC3rRoYeeebYc=&cRxFfWZjsncYi=&NCrX9mXXkfocX=&bfM6CQWaUb_hU=&zD8COGZZjmgsV=&6tkg3PWfqscfe=&nwDUD4XXeqbkY=&Ry5dvuXhW_jqn=&8ofSkPVnpjZlg=&py2oPcVkfgkqo=&W7R_vvWlhnZem=&ut6LmVVrVegc_=&KdAvlsVjXsUaj=&CERszvVo_hdUl=&xtgEhIYhekabk=&zDqfnhUo_iUXZ=&45rxaDZqgWmki=&9c_DLDUWeWcdV=&oLRobeXnrhncX=&oMlyKCZpabcrc=&COjlnNYlghqgr=&yvfjviZerhUmg=&ZYlwwXVfiXkWp=&o7t2JkVfejVii=&sCUXyTUfeaUUU=&jiOiajWqWYYYX=&5NUVAdVrVkgop=&iN9RPEYfsdacm=&DBDFjTX_YjpnZ=&pjliUXVmXnlnc=&eMxktqWbYnflX=&SInpjQVUsWjm_=&2mB89_WqgrYhe=&_jrvubXdUfh_j=&VRPlybYUWrfs_=&xglmybV_phkXa=&i3GbKAYZrsZYV=&BovlIQUprkZba=&L4avuBYbheibc=&mAcXw2WmqZaqm=&kzDWTxWnVbpsf=&PgTRqTWniickq=&K4WWrKVgohajo=&6ivs4QUYcbbpX=&H56IGNVhf_WcX=&RzllwjYkn_lnZ=&gv3JA4VeffrZj=&hbbOamZpddhgb=&385skTYshpb_e=&mvuYnLZqnlifW=&U7uQZAZhVkVYe=&SujenMUXVcqcX=&OTwyxuU_dqUXX=&FgfQTxWmYhnlm=&etUI4FXXlsWXW=&pINEPaVricjqX=&ror9DfYUr_XfW=&wjRrKmXYchacW=&mGvkKqUiesgfp=&ZexK8sWbalVYl=&L_Ev6jUnUdlq_=&5M27H4XnmWlYp=&RlmEnKXsmWssn=&9asWxLWniZUbo=&fyhhKiVsYleka=&FFb79KWqWqhWd=&2vicwXWidejkm=&8XjomdXhjiVgV=&mdfnUsUdmanlX=&h_o_X8ZmdpmXk=&K2R8tTZZmdibW=&2GNZgjZpfjcpe=&5egXV4XXsWebZ=&lP87eVVndpcUd=&ek3Fb5XqcbldV=&6tzXTbXaonmed=&_4r7MSXcXWnWm=&MTUgAJUqYcglg=&Hla4euWdUUaWd=&k9T5FlXYdrpgU=&fuBweOXqXqYef=&zaChWnZUbYgZb=&2anlSrYlkWaos=&eeeeemYZsiYqq=&XOtZ7dXapmhln=&RHdJ2aZmUlcmY=&SCoGqiUjcUcca=&9l3paNZcfWqcc=&WrtiA9Yd_ffYg=&ZLsaj2Wnppiaq=&vaqWFQYWhobmf=&J3xtJFXUdrsre=&ew9RYJUrqqYe_=&mLmGbDWdUUVfr=&x_4jqKYbpdUaZ=&JclLn5VnkagVW=&N3jBuyZfphdql=&mfwkJnWVVWdel=&34lsddXdgjlns=&oV44LbZnWenkV=&qosyDUYpbi_gU=&BVatfPZcYmals=&BcOMiXWXikkff=&TGTvYmZq_cjeY=&GLEvHlZgrrkoe=&L_W44IZrWZqcl=&DsTzSaVhXh_WW=&FLe5JKXfkXrVp=&QuxdpQYbXWsii=&_yAgEdZZgo_eg=&cXrZd9Xfalcpr=&H2zmHiYmarjeX=&O4Hfd_UV_bjUg=&kwf6BrVZmqgcj=&OWPLfqXYnjkje=&p277aLWcYsojh=&6F3mC8Zropljp=&vaWvu7XcWmoYq=&LlaXLMZehlhUn=&5MWELiUbbdeel=&p9zwt4Ymmpnjs=&2FEgH9YbWnYpX=&cLZfjPXodZZks=&llfw6nZlkpVUY=&UpKqB_ZYp_hom=&suWMCTVWaoXUo=&4iiFkwUgZpkUj=&_iAEZ6WapYqag=&MWFukGVkZb_Vc=&EvuR84Uprqosb=&oEIB6rVpWliYd=&NRhtWJUflmUga=&bqvUBoUjXcVWV=&u8cegfUlgcVUp=&aE5PaJYsgpgmk=&eINAMBXnUUd_W=&cceCb4UdZpjUZ=&J4OjiXXdfehpa=&dW5UldYo_nY_p=&ZzuV7mZdVgYfY=&Px_GlNWbbn_lp=&ye2NWGVmhXqrZ=&Nwc7vmYjVpjsb=&3P56MnViddZZl=&ZGV_kiWsZhUsV=&7vuDGrXgfZXUs=&odCNZ2WsXmsgW=&_zfH68XXiXUsf=&pTvFUVWVafrjk=&5jwedIZg_WVhY=&KS9HdsUZspViU=&8QYUHxYjsfXnY=&awcba4WeibesW=&rF2misYidlnmj=&bdiINBYYUronl=&msGJg5Xkgnk__=&TwhePhWrhdbkr=&U5jmU4ZZfUsXp=&Ee3ZnQVsWjjoY=&GKAzoUWYjXdXa=&hxl7mxVXXlgYh=&ZANmnZWXhamib=&9qeGfEXlqnadg=&yvUtIXWZnbXfj=&OdkzmvWmqikfp=&Pgf2_dWnfk_ed=&BfaZvcW_Wmkof=&KMkCsUVqdhgcq=&efCpC7Xcm_dcX=&S_gV4kZgmhUfe=&udQ9NKXdqeqpm=&jkQdwWUfcYWnl=&mFUl9DUbjWped=&RLtidpUjWcXnl=&zMdVLUUi_gope=&6exiupVcgspdb=&RyykiZUUbUqqW=&mYnhVtWee_gji=&d3Qzl6UlicVpg=&O8vXCyZXbpXiX=&rdC4EVUpgYnan=&cGjspTZdifVlh=&FiTxTFZXdq_on=&cSJRIFUkWkaZr=&zykW9XWmZqqhh=&BJDGTiWmdjZhd=&mmEaxmWpf__rp=&zxBSK7ZsV_crf=&ymfcjIYskiikd=&H3qhlHWbohnYg=&Xx_XIGYenYhjj=&CrqKN7VVfksig=&e2FJ8xXnrninb=&IHbohvXWkmUWW=&QFjUqqVVmhmpX=&MmityLZgWemjp=&HkVXwHWVddkcg=&2f9ULmX_grnUd=&QbEQW4WekcnnZ=&HenHgmUmo_dql=&VD_KeOVdVpqj_=&67hWuKZkbWdXZ=&bGQa5WXfsYhYV=&I_cQYEWkeXbgV=&iMlFj3Yphcpfi=&m9ikFlZVemZnf=&lze52VVpZokff=&mZeyjQZbk__ih=&lw4AuFZpZdUes=&eLBVtFWVpjhkc=&r7aLCcZZaboso=&YJIHJoXXaYoia=&Z_vMHdXiipofa=&kNn2xsYiXplaY=&u4ShdvYiomgjq=&6_tcRkYVbdmeb=&eLicERX_anieX=&Wf4QAJWdcmdkm=&K2uiw_XibgpUX=&dFYpamWfaXYbn=&h2cPc4UcYmmYp=&_GMtTbVdqcaWm=&fHW4tzXgihVsj=&J5fSHqZrohaVa=&7hKUcMZiWlhfa=&jcSK3bYjcbVVj=&2bBVo_YsnoYiY=&LbnaCnUfgZocf=&bJSvyWZYfjafk=&e42yXiU__aU_W=&4e5vNaVrkXemp=&ZxPJ98WcoeZUn=&eypaQnYZ_nibe=&tvqqTSViqbkWk=&lXuvhrWYYkcoq=&Wi73SXZnbspeg=&9wCUvCWjqgnrd=&kPLiZZXblZbdV=&PT9zbPYnsncqk=&PPBWRaXYpncqk=&npC56_XVjkXmk=&QFL6mrUlrUmmX=&_XrJyFVarcdjZ=&WbCYU7VrlWVgU=&JsOoEsYgs_Vnc=&tvXUkkWhoppmh=&HZKSnbXjnmoWa=&yNJrJPXVYgdqV=&XALAKlWUimgVj=&N775yZVl_liZV=&i4PgAjYlmsj_s=&vx7HToYbmdnic=&mDiSEyYbnsfri=&GlYX_dZalmhbe=&alEXVTZrm_aed=&fxy4lRVpkW_bV=&T4RCYXZeicrpm=&zfFR2DWqrkqek=&8iF8aaYUamYbn=&2E8deXYmpoXjq=&RJJt75Zd_WjUg=&lgmL99ZZmacdi=&Lk6YeFWogcjZa=&5IuvOnZsf_qYh=&bjLBJCZcgkfbZ=&PutwRTZmpeeqX=&O46VXrYlrXZbZ=&tj7OS9UWXorod=&SPdCDiUYbore_=&iuVTANUZZd_mn=&i3Y4M8XmreYZs=&xBJPPCUmichsZ=&TPlpuEXeqndhX=&mjD98TXYdcbjp=&r9EhAXUrgkhbV=&fnmKcLVmhgkVj=&dNryMBZlnsrhm=&jhtm3BUnUYeld=&ZslYZuZmmrebp=&2QLdpYVWbllsl=&jWzUEIXsieoq_=&9rYdYNYdrY_ci=&V8aKxOWbVbmjq=&F_cM5BVZbcYmc=&8fk3HwXdcemWW=&RA6YdLVsWmsWk=&YYSiI9VneUkkh=&DO7DgfUrs_ljX=&5DhpOxWsaUjii=&kNTSzdWeYj_sY=&WHEwRyVjlrop_=&bFLrVhWYkkp_g=&M8v2zXXcgqYrm=&W6B2TMUocpamU=&FpHMZ3Ubr_lWg=&47zBx4Zolbpso=&fp22GTWZqUcla=&RukQTjXgqmmh_=&qLZZsJWVqVbUc=&LZlOOqWfdgZch=&vQHBe8VrXZerm=&I7EwJwVjjbUec=&XbLNCaZaisVhg=&V5CEtDWhjgngr=&lu8fx4VUXjeaZ=&t5vNxDYsUrseh=&Wnp5wmXUXXUeY=&8DN7RKYYhYenb=&o4gAgyUphgebb=&kMaoUoZserbZb=&f4KET3WYrsobW=&3yPUCiXXs_Ylj=&VAxVURVsbbVfm=&Jy_zVTXaeidfq=&XEx6SeVsfXehi=&_WpwPeXbnWekg=&tmAP_DXgUcsWh=&zNh6MXWdmVlhY=&EIz4hZUZlhUrh=&WN9D_HZikeiqV=&85mAqeZrjdihp=&OvUry_YXhpnol=&ABlaoqXndopVY=&2FIJrqVUlgUsf=&vxS8vwYidebfW=&zi9YY4Vc_omk_=&R97COLZq_Vd_s=&tanKqXUlmeVbf=&D3thM3Yidaikr=&egOIKGXonpanX=&aYOml6VnpZdYq=&hidqgXWYlVc_a=&lbEPErWoeirgY=&w9zRgwZapigda=&d9GV8NWejWcWc=&s84MOaUqXeUhf=&XMDvMGYmgcfbg=&dwBbCKYikb_ro=&Vw8qELYgUeaVn=&G78tnrXrgZpnU=&jGypfDUZlqaeZ=&uxEhhFVWmjgla=&dD4G2xYmgbgsn=&goaosBYUUlVhd=&6mVA3WVnjprbn=&8XyTKEZYafZZs=&JRJpznVXlYXXk=&z3_S2EZsnkgbk=&6oTgb3WrVbfjb=&UKOGgGVYoldim=&7mlVnKVddjVla=&BTLZ6WZilkinn=&9ymJb6WWUcWjl=&SkIvT7V_hiUZq=&XN7vkfWlWnVff=&TSgST7YqhWfbk=&tgkTX4Zq_rp_k=&CaSvbSZmnldWp=&NaD8YcWjib_Wo=&nwgKpWUjfflXo=&TbmtDpXdgo_gW=&hVnoRPWdfjXVV=&l4lpXQZeWaUml=&yAv79PWmVgoqc=&K9Bi7sZgqljYb=&rdTIyyYelZUgm=&YZFSNAXioljZY=&F2LUIOW_UXs_l=&zJsnWcWiZrVkp=&HFI7jxXWkoonV=&X4po6pWdZgVVi=&JpqdFUVkpkWje=&4AFzOpZacmsga=&avIceOWZaqmoh=&YLHwuUYiWoedc=&5mheXzYYbsero=&vCxBvNUhhfjjZ=&i_2bm2Ukqeber=&jSYiSfZjfagoY=&VJYvyRXmcrmZU=&g4caf2Xrj_WoX=&IMG5cgWeVdssl=&8lMnmjWgdZasd=&XUpP_LYisbccc=&amXWaoXllkobY=&hFYSRIXkjcijV=&5_uX7HWebY_qo=&YtHCJsUedaeqr=&Gj6ZNLZoisqWd=&oPZegUZgoemak=&QI3DYOZUbUgnn=&MC6ECfXYqmVXa=&FtwPNRZelqXhe=&BU4ATqUYihdsi=&yNURztVkhdese=&PhJsWrXjnajhY=&uWFotSXegiVUr=&O4RDlOWabnaen=&t4bXAIYjnfoas=&H8zZIqUfY_dUZ=&Gb6k6JYfYlkUh=&U3orBgXjWemgZ=&MzdgQvZnWZfkk=&eYwfXfZjVacWZ=&ywqIQYZcf_UUZ=&gF3t5sZZXe_oU=&n5FB9uWoclroW=&BtxXNkWclenss=&SCUHYtXhXUqVj=&ZzKqSDZpfderr=&JQjYIKZjqYgnq=&x_cYB2UnhfXsY=&clHqdcWlogefY=&i2_E2SXmqZYsb=&vlZUMcWYYlmhq=&dDS8uCYkbehe_=&Ow3oIiUsXepoh=&kZwpWBZmknm_U=&VL62BjUafmWeU=&_rAI6dWpaYYfa=&NZmTYHZgpX_Xj=&dcmRAnXmWUskV=&XoBWbhUmVWrqd=&hRBbufWX_XWqi=&G3Hdu6Zlnl_qe=&6o5QTYVeosekm=&xXGTZEYUZlohY=&sDkEMlUnUXXck=&gXeKhqYWfXmro=&uuFjEAUgmWUpq=&XC6aczZUcfnaX=&yzFptxYlgbpfm=&3pmESqXpmYkms=&Y7ElWEXaXmook=&usYXXWVnrgUkY=&helR6mVjlljjh=&4IG_LTUllXhoY=&nouqUvZUnamoh=&vFq_LRUjYXUol=&5gdQ2RX_YdWqe=&WLVAFWWsssV_p=&hNKcUCUdaXWcX=&nj7g6PUmnVfe_=&EO99yfZjdn__k=&BO3963YiWfjfe=&gTtUf5Us_cjgV=&at6i54WohqpiY=&9LweLbUaosmma=&mo22HCV_sspsc=&BO3YfTZsWelZp=&ZGFBspZarpUXh=&UFWXE2XeXjapg=&ka7yhdYlWipbe=&wmhczXVnkgdaZ=&nAMADhYqcfjpf=&Q8gzDgUrhhqad=&IVlJ_MWjjZiZg=&ZazoYJXVjcmiZ=&sqMDweXeobngV=&A_pICtXjUZkq_=&9qYEpaWdW_ppd=&M_cKKNYqmeXra=&xQyjjxYoagWWn=&x8tEu_XgbXmhU=&RdzgD9X_ajgne=&ftYKiQVeoUehZ=&3mUUZdXqWYnlW=&yeaNlUZlkhqe_=&8xhKnVVsXZihc=&Fi3tpHZUnVn_j=&MTiaBIUeXbpdn=&qGpddbZlWlUrf=&sZzjK2ZiZhohn=&GRKRWEYlWWfpW=&dwCypDVUsnsZX=&5RdndPWanVrr_=&kfxPp_WhknX_W=&MYqjckXqVgpfg=&QGywfiXWfmsrV=&FOPwsFUmirdXr=&AxsrjvXgWmrap=&NOTEJFYWb_Yfp=&pY4HDfUdfsdXi=&uPfESOZeeXc_j=&sAkMSsVdXfckn=&zlFNiIVksXrqm=&naWZksVgiqo_a=&QMmjcnWiddp__=&K6_cEAVa_Usre=&XRLsjqVUkYUjd=&eGQO9fXcim_pg=&ZT2vfBYe_frZo=&I8CqIOUXVW_ce=&ckHmURUUlpfUW=&YxJstoVfXhoes=&ZoPzeHYocrnZm=&ZqwmiFUmUboWq=&baHDDaZbXgmmi=&rXF_uuVpZjVXe=&aYxjzcUYWeff_=&htfTXNVmbeakn=&ufEsrvUUWVk_p=&eN8FbYUmlnZW_=&WnJ5hHWVdkaXY=&Tn8bqeXjrgkdr=&JB_QxdVbcWjY_=&ztxrzmVXmVips=&nry_JMXprkena=&vRux2cXijVcim=&CyalaVZspearo=&4peIF6UoqqnZp=&lYvahYYprmpin=&cvSU3oUdbYpno=&rNflVbVh_hnod=&_rLCLNUe_qpZr=&j3cpCAYceYaYd=&o3RpwcVYolVVh=&U67PrDUbWgqse=&fR9jOcZbmjdYe=&vlqvCzYspjmbU=&wnxJagVaiUWZc=&A2IdcpZbWjoVU=&CsJYoUVWjhrco=&AuzKnuZYhdYks=&TBmpQFYqcWmnm=&gC5aNBWf_dbai=&4FAN5aYoqoema=&Psku9qZaXWako=&TFddW6Wpocjsa=&fAJIJjVbXorns=&WyC3JTWmlZhVh=&XVz2YSVo_Zimb=&vP8vTdUeXWlbg=&2qySYDUkrafsp=&a9Tv9pYXWVpoh=&9fW_R5WVsqeXb=&7FqpEHXeVkYaU=&6E4RDeWqqlZcf=&qhwvSmVgdXmWY=&3BzYjqVWXn_sZ=&ZUj2J5Xc_qYnZ=&CuJvIeYpXnZX_=&wnMSPnXciYfXb=&dOFWy2UssZp_c=&Ed2IvMZriUdZa=&uHrhFMVisfqYX=&ZXZbCeXaiWjXg=&QsejthXYbreno=&sNEreaWodgfeX=&QxullfXedcfnf=&SeZZbkUaVlVhi=&UfZyXmWnnkpbe=&vhbalPVUrVgZe=&r_Zzy7XU_gV_s=&t7ofj5Vgimqor=&KKLxr9YXqspWU=&Uc5Gk2YWjXnhg=&OTqAgaYhoqfoc=&SwUOIGYskrZol=&2LC6CnZVifVsh=&wFQStoVhhZnso=&nEsTikYqhrkXc=&bfaMiAVqhbiiW=&U_2f7WZriXrcp=&Zfe7D7UUlVefV=&Clj5RUYjnnda_=&rU2faKZXe_dp_=&d3u3PaXfpqehj=&Xx77_dUpggZYY=&KD4AgvUgfbVsZ=&YhQP7fUeejinq=&UobKagXlrZibX=&BUTMUoUsYZksg=&XnFibmXZmaal_=&6E65L2UohUphm=&z_MRXOV_Uajjp=&2XCL2JUjhboUV=&eTqlJ2VbehiYk=&26iAqgVcqdddl=&7dD6m4VarmgVU=&EVZ8ZEZZoWe_V=&EockBQWZfkUYg=&YOqQMEYfkbddl=&8CEgbZYikgdX_=&wCrJLqZjjXmZn=&agz4NpUpXmhim=&L_FDMlZhlodkb=&8YSYYwYinYkap=&x8ck32YYYViZo=&SJlsKwUWkcldV=&68oKwSUhYk__Y=&rhDHyeUrVfWaW=&JjfMkYYUqYVnk=&AUcNLnU_oj_fg=&gqk2xyYfpZcgg=&EHrYuoVlfeWWs=&BsnpILYdii_ea=&_ZAukiWqnqjoi=&zX8Lv_Wj_pYdd=&Cpud_aUsqVpWb=&E8L97pYljhkVo=&GdW5kYWXXogpd=&yhwdCkUhiepol=&yxaELQVllolp_=&WFfCIhYgemfrg=&CGUMm6Vhifoon=&KXCh6UVjrVVXe=&FinNurZVqnpgj=&uJlkAQZkrXhkX=&tGYOrKUYqrmbV=&p6lkboZgsXYZ_=&95ynRhUfaVrbW=&xcxqbiUaeckcg=&hXs2fWVhXbZnj=&XdSjPDWbp_chp=&2gRBjuXVbrkXe=&Mts_E7XpjfUrp=&XtvdMXYqaZnse=&ZZucfWVqbpbnn=&PRJJBQZ_gpbri=&we8jwbWgbW_hs=&EfqbVQWncpqqk=&H_mGYhYqpbr_q=&BAdmNIWXXkoce=&hteKXbWVflWfj=&BoMhAUYYseq_V=&YEvk46UbqYVok=&pLgSIMWnhjldW=&EzpinbUaoZZng=&_VupunWWooprg=&WwYaghZUbZkoZ=&6FU4ZTUnUWcWr=&s4lSQzXb_mjWp=&7fDpePUlkknqZ=&sjtq4eZbcbUiZ=&WBdgo4Yjrbecl=&EUKpmPYcYfgVX=&kuKanKVelppsm=&FvLdYDVeqhbUf=&uHdbsxXaefoVa=&dyd4TCWVnXiZh=&58k58mVedaiWV=&N9t6SxXajZbrU=&SwqhpfXddsfbb=&T3Bu9eUXqeghp=&fCbC4MWceYohj=&5899Y6XmomZUh=&ulK6VCWZiUphp=&zXwf2qZkceUim=&6IUmqFZVjj_Xo=&n_VQO_Y_UnglZ=&lco7cDV_pgdnd=&Ku5K2sWYVirlj=&ZW4m8XYllfWsY=&Evx58oZjWasag=&m7DldTYsqlUso=&Gz8J99XbWsifb=&oVWYCsYXiqfXl=&G2O7boYjUagaq=&xQyDcBZrfZUZn=&nTgLwrVXjYhYb=&ojnDwAUahasZa=&UVajdtWdlVe_e=&vWDGGlZWedWZb=&v3aJPQZeqgdjh=&U43P6qYigedje=&XwIIoqUYUZUbq=&WitmdHYrkdsqY=&e7PvozUoWiXdU=&P73uvjYnnbWbk=&HiplxUWV_bhbp=&aE4Ar_WjnUfjV=&TALJ_EXolhjk_=&_tgFT8Xlcfkfd=&dg7GLVYdmkdqm=&fLApAPXgmspbe=&b3MKCWWioeess=&IyFzi4Ulblnnj=&jeOEugXbXndha=&KrXUlQYVbnVpf=&F8edlgWXabnke=&NTN_38VnVaofp=&YcuaEaUXXcYhi=&Rh2kFpZfoZiUV=&ZOI6EJXYUcsol=&ZSrBpcUpWidml=&c4EnpnWZaijbU=&3TtZwBXiimZfm=&NwSaafZmiUVon=&C4lVo5ZliZZim=&oqvQl6XYebaec=&WFC9InWUZadfk=&sOVhX4UUhbXgm=&d8isWuVgVUikh=&gd4muBUaUh_li=&Sid277Vemplgk=&4CeIaBYrmYsVV=&tGMIMYW_qgrpq=&d9zFBjYkdbrcd=&yTLpKUWnjUZal=&ONLEH6VZkjgkg=&N3jZ6pVpengaf=&xXBBfgUmonspo=&thjkE8VUWga_o=&vJ4rhhZqkWlrU=&UniNAjUqlUnYq=&q9yZvmYsWrWkc=&aLARlfUrrdWW_=&3PpLlkVbiefXl=&IsLKU8XZeZeqi=&Qy_rOHXfpjVrr=&QLjzknWVekpjg=&DVvFy7UapZjio=&GCqJvmXllhZZV=&2OIWX_Y_mamoh=&9yYqSfZXVgqWZ=&jxklLVV_sVmhZ=&oVQBTMYZ_dVql=&5OOBxWVlojkXd=&cWgzkVXprVgWX=&cvnZsKUnaUmWh=&CWEEUOWioYYoZ=&QuEdfsWlka_Xn=&L27XpkValV_Xj=&8_uMCtWVUfUaf=&Ij4CXiY_prZjs=&qPRfPtXfaapds=&WKRQBPYZokXXX=&rdjlmXUakdVks=&GLDVCwXbascfd=&yr9Fj3XZXnVgr=&ym7MUFXgXZqpe=&DupXGJXcbYdma=&qSNKrAXfskamZ=&lAfJyOUrrcpho=&t4etzGVdWmfcW=&dyQ6SAYhleWre=&XLkfKiYjXmVZq=&hQZwuxUmehmqb=&OxqYvyWi_iqYr=&AguLSnYbeVmVU=&xqI9YcUaeollc=&7y8jeiUkYWle_=&rZpblZUsoobfd=&zwewnOWhj_ifm=&D5D_emYkVbYob=&zKXABRZqdsmro=&JfjG5HWemhkrV=&I2fUnVVasfmoZ=&mhoOqjXkXnXWV=&gVG3kHUlUkaUs=&4EvWtwZoYlYlj=&VxqV5YWeXpbgp=&7BdK8fU_iaVms=&HSYsfzZlnfgqg=&A5wKjgXedmhXe=&zjhOwlVoUfllp=&lw5VVMXbXjUko=&xlxdzWXU_ihpf=&kgRz6cWbsglpn=&6Un5WoUUadkeU=&_g_A9bUpqZlmr=&Rm4dC_UlXlXbV=&zWn4sIXglmeki=&VU5Pw4YlfoUaY=&dWrYRYZr_Zdak=&Siwrb4Wcagkko=&WJxqPKUoobYnc=&3k3SZBVjVpgno=&zNAs8LYrimrji=&pwOq6rWsVcrVl=&2a832eUnkjgYa=&UyoSIVUa_ng_b=&lM4atEYcpZmqq=&YjxR5IVojkebp=&sUOtEKUf_WqVU=&7mguzWXrfphpg=&EI6PKDWoosXWl=&LicqRrXdqcfli=&qBKaEIXrmqjrk=&yhum23V__ndbX=&bI_mz5YcUVnho=&goxZoKZgVUieh=&d4kqn9VVknUmV=&wdFHXSYa_fbXi=&w85B9rZpqWoao=&sR8fHtWlZbVnh=&f5ptM5VacZVlm=&ApkDlyZgVabmr=&Bn7hvtVsemlq_=&wHl_e3Ulfdrra=&ly2snwXlbiinq=&MiDZRmXpYpYYV=&Hs3ep5Y_lUddk=&qUwt5IXnpnlZq=&oETJDDYarqjjm=&XERCENWiZaniU=&JLHrzmU_orgrq=&4QbMRQZcsZXkd=&KAYcEDVXgYZWj=&afZhT7YYbkcnd=&ztSzf4YUfrVrm=&vh5q8_ZfZhenr=&Cm8mHKWXZjags=&DccbY6YirWlom=&hd4QDrXkaZs_Y=&nYS_HSVoagrfo=&nXavNxYVVlfXh=&mBcpAtUjYrZcf=&GYLLaVZqgifsg=&2aL3JfVYUanXe=&58bllgVonoWaf=&ArkDqiX_dqdVb=&AMftQIWVjqaeV=&vvRpQSUsjWZWb=&kmv_OuVmbWWWW=&_dz7bWYUqgUsa=&WimZtfXnUWZpY=&i5ocXKUUVnVcr=&oy3uqvUlpkVcj=&GyBpZZUlcjihW=&i6MElUXekfqon=&kKnZ5zYWlbaqo=&mJgsrNXhmXang=&X4aqccWharlc_=&QZoOBtWXmbfqV=&JDXDBAZlepgUj=&MIJiGHVigpgal=&jcCmq3YnYskWZ=&PGi_dWVYnopiW=&Ii5fxgVXWiXVl=&ymFlFlXaanf_i=&2vxladUecrkmV=&hCvzaEXcZrngY=&iSCJwDWWnmiUc=&EkO87QVZVgngq=&5iLviaVhk__Zq=&hoaVKzZmZYcdX=&tYqCtIXWgscsa=&sGRYnRYjcc_bm=&Tah6tFU_ZqsdY=&8jZ7UFYsXdmna=&FZrrUUZanZqVf=&kPAdMxVYcZn_X=&sPQYJyVcnfXmh=>Va5jUehrshV=&89hrXfVhZYZbl=&sgPblVZalWZce=&84c7OQWWWaepa=&GPPWw4XdqZcYr=&kBp4w9Vlgrh_o=&cxwBPpZUVkZaq=&MOywNpZkcigkW=&TySi9qWscrsin=&v5LjSNVZfiVbe=&NZa9GaZkf_dom=&NbG59QW_brsVo=&aWptktYmWcieY=&DTKfABWobYhVc=&eyitZjVVUhjdV=&CvglTYUkkZrkU=&RiOJZNYhmgZcr=&_2RpqYXb_oshb=&WksxIGUbqnfUj=&CkJRWaZj_lahX=&NNZLvKUqieWWY=&4ka_NlZahhlbj=&APOrJ9UnUhbns=&mdkqswVhbj_dZ=&ra7W2DZhdUkVe=&EiKf3zVsjlqes=&wGm8EQUpZ_dda=&moWi6_Vhson_V=&fGgn7GUjrmjnf=&NoKJJ9WsqnkVm=&okPFfNUmkbYkU=&YO9ByZXshV_qU=&P8cFxXZVsZael=&jX9VcYXlhbfjm=&E9Y4SSXc_orWi=&ZlJWrNYqikcdp=&rjVhYwVkjpYae=&a2f49UWejgerm=&kejlPrXs_nbss=&dMf3fCUfVnZpl=&a7iJRyWi_VpiZ=&8hUSV7Xmhgsak=&ipj9NZYbmqgVX=&xQyxPAYqqqXdg=&bmHhxtWnWlaiU=&z8Ix8lV_cghrr=&iuKRnBZfYhgnc=&xA5BSGVsWedXc=&uxPSWOZYXZfWj=&zoz39IWofjken=&LCE8qgZpjnsrs=&FVPzs2VUVdYbi=&h_Hz7vZZa_aXW=&4N7lNsUniqpkj=&dwhfl9WqjWVdm=&aaV6s2ZasrVjs=&kT9_bqZpl_cmk=&5w6_aWVjla_ns=&fTdyrTWjijVda=&XeHieqVrmWiiZ=&56vRmrWnYoWZl=&kbj58JWfWdnie=&sdneiKUckkrqq=&hs2PkVVUdsWUZ=&5kTPodZmYWYha=&UTsPbeUmjp_qi=&KjDxqDX_cXkeV=&R7TylnVbVajgZ=&iWhZHIXcc_iYr=&kXvdWvUqegWlg=&MPJursVgdZdnZ=&lrLhNjZidackl=&JsXAN6ZgXZnnc=&ajtrPuZrdgaUU=&GG9oOIUffe__Z=&D62xE4VVpfYpn=&qEdnDOYdXlnsg=&aG9YIPWeZpYpb=&eg9mUXWikrUVm=&2LcJIFUdgVVii=&PytYRsZcWgkne=&Q7e_quVsmirch=&GEjtQ5YZhhlWr=&z7CiHRVqUjYec=&yMxBOyUoYkksV=&SrxPvDUXodcoc=&wRwizMZnfUaie=&qAKYjzZiepcdc=&UbUy93Z_dhmqr=&AGCra3WffoWgi=&AlruXqV_XZUsj=&eFV6BSZlsleoa=&THkz8KYaWY_sn=&5fjtAiXq_gmUf=&5GdMwlYhUeYo_=&onXQm4WVZadVq=&auTfcQWkorosi=&FFXpvyYsboipc=&vEMu5SYshidag=&IVIj4aZiWsgYr=&WU9ieIXks_qlf=&afIIhlVY__ers=&eBtu_eXYYZqsb=&4kNvsjWqbWaom=&EKRflVYVfmfok=&BwDbBsYUVXsen=&XQpScBYilqj__=&bYQOwKUWprog_=&SRzJIQVhgU_rd=&lsGDFoYomeYok=&ziMp89Xpqgamg=&COVaAQYhksesf=&QIfEDRVljisWX=&b6MnUTYYaYoWn=&ddK9oBWpWkXbr=&hQHhglYch_Zsb=&OIRucLWgfUjcX=&4vNdBYXdqnbhX=&hkkQRhWdqiYhm=&Ug8zxRXonanrV=&zsNZrWZfnqYpj=&3DpnZvUo_WnZc=&OmaWKzWoogpmj=&jEOSSCWrbhg_b=&jHRvJXZZWdrgl=&MYHIB9WhkfYZk=&I8AeAhZbdqckq=&PMrfFBZVYWhpi=&vSfA4bUpbcfWm=&QqKrjeZoVWjgo=&76bDt8Zlfq_nk=&IVRY8EUrspUYY=&tUsR9jZYYmrjV=&pCrgRdXssnq_X=&SJ_s6EUYgkkdU=&4QmjhgVpsmsoc=&JAEohUUoZUobp=&GgkvRRYongqUX=&9ZFkEIXWhWrpp=&6JIYg4UoZbjkn=&CK44iUUUigXk_=&fXbLYVZobinrs=&COUzifYn_gmZr=&bnwyLgXhidpUs=&qQQPbGUfaUppc=&SYHctwUYXlXWU=&3nzaArWqjkhaa=&P8YOfPYfocmqg=&CwkOdcZefXpom=&W8UsIUZhjXiqi=&nTOSa3XrbZlc_=&hFT6iPUqiaVon=&gQSOQGU_bsgis=&yQQqqgWascfok=&E9XsVgVfsrbrY=&kBDcW9XWodXbp=&TZOmcPZbdoWbi=&qtTk2YZWhUkYs=&WbjDiBXcYZZdn=&qK_uSUYXslVes=&fBaJWEWUgpZXr=&eRwyOXZfUelik=&t8DunLVjWgfVa=&tDavTPWqXmpic=&FiVFtnYWZckdg=&BH_vd5Ybhhjgn=&x6rAB5VleXesq=&EQtVAaWofsUqi=&v8SrGQUpYoqgl=&ye5LLDUgaVnZh=&ravM_UZ_c_qkq=&XzBGMnXsnkohs=&dMk3tDX_kob_c=&txUSqvUsVkhgs=&_ZMJX8Whqjhpd=&uLg8OKUYVWqgY=&VdEuxwZgVlsho=&7qrPFMXmYXUld=&eZuhr3UZZeesa=&94o_VYZVpkWnV=&MN5CyGUfbpcqd=&QUgNidZ_Ygmek=&J8T_oBXXiVVro=&ijJAT6Zochrjf=&mm6ifXXWVpfUg=&eHrr8KXVidfrU=&9WfEphY_Wbilc=&dugAr8W_hUfjd=&2EVp2cZiXYljf=&tUHWnFVUjYqji=&VnDNi2VhdXphc=&PnABaCYYiZZVh=&Up3muBZZkqclk=&4UTyONUgdsq_n=&cvEyxKWgjqVcX=&NV4cIiYnViVlo=&J6Pp6eWsoghjk=&W2FA3sVjbga_g=&OSW5uqYiZpVnV=&TKQetZUjZ_jlg=&vc_GUwWUWmUiY=&tr9OENUrhcpba=&28nmghXffffoW=&ZGGI64WgZYsps=&qQcFBPU_gmV_d=&Dgi4JMWqqofYV=&54NH5bVnXhgWX=&c4qEjTYpZZesn=&Y4FsbeZjWhsfY=&McjC7uVVnsWqf=&lpkI6dUfbeZbf=&WsKyPzWUWdYdd=&DgqUgbUjpYipa=&pf3EsDXesZXra=&kgsiS9Xm_qmam=&zxXWs_Zqcjdpm=&iXRX5fXVVakom=&DWHCb6VqqldWe=&zJNHTlWUZaVoZ=&Qls3AoY_kbjrh=&TFsEmFZq_lWko=&AyCmtPUYWWnkY=&qiVGG7Usk_rqd=&Fhbkm4ZjYXdne=&UbLSOFUkYYpdo=&RLObNLX_cnlfq=&aqCxZrZpoUgeq=&tKx8BVUnUmfWg=&OSJ7akXVllqeg=&QzFabJXZa_iUr=&4RC77UUjYVdXp=&DmQc7hWndXXsl=&H_RrjoUUfiWik=&bav6rSXjl_rbo=&JKdHgFXdmnZiZ=&R_GtunZojcarl=&vgswUsW_XeW_j=&AxKGDpW_Xnlfq=&V288k9UfWZnnX=&E6I_xRZX_pXrd=&I_zGRJXiXfUdc=&tyZGTdXqsc_ek=&aMtJOgWfkVpig=&NlwV6CZmUZbhb=&2F3ZfWZsrrbqn=&Z5MVHLUWdkWdX=&f2978oUslZrla=&QDqRfWYmkWaUs=&ru4MQ2Zmpbocp=&OphAFQYhfqpZc=&RxkM2ZXZgXbmh=&WoPYwKXXpihhh=&RRb58FWmblYac=&Dz5fO2XVVnipa=&fqOlBeVUWXmrj=&GX9lQaWlmc_Wq=&fbqOy6XlVYdlp=&F8ezo3Xpocarb=&5B4JDfYYbfmWm=&6TMTdzXYlecbn=&UFOCGHVhXVlim=&QvwbClW_WfsUl=&urLzJLUclWYqX=&VvXsneWkqmiob=&ryuG9QVfVbgrr=&ObsmuqXnXipke=&pYIvmxYfk_j_q=&sYDUC6XZZZjWs=&PdwZOmVXjkoad=&o9T_42Xpml_di=&8Fvn4xZhhqUek=&FoaIzfUnkaYXe=&sbL4_HXaVmUZ_=&zaIIegYZUjpYb=&5bLAzHWV_ViVm=&W9gjLvZbnW_Xs=&DsqIBkYqUljfU=&wHLwRKZcpZiZs=&ib2xJyWfcndpn=&PpMboIXfpfgjp=&zBdXDUZljZhjk=&vqncF2ZscnZff=&LoRrTyW_UmcWV=&FGkElsVUYrkXa=&WrWD2gUgiecjl=&RX8yBhVjUndbr=&uWJXptV_ifXmi=&CYMlp5WgcZ_ZV=&vMEho7WsmYqqd=&5DevKMVrWYc_V=&2QlByqZ_jWWhj=&zaGaZ3Woqlhfe=&n7ll8fYqa_XiX=&IJpJGsZZpeiVc=&tQSVy4XsZcdbW=&sFlq57YfjgqVc=&eWFGofYnVVhbs=&X2GExWWUlpcYi=&ZxzSRgYfnkXkc=®9WsXWpjdbr=&kMV9EsXqYUqWh=&AyDx2XYdZe_sV=&ErAhSVUgcelle=&xPfNV3Voidpje=&r_9aT2Uhceano=&oTxvyWZckrUWm=&Q9ITJMYgpliWh=&vfGn3uWlelpWV=&UG4F3TYYnoqVe=&yv6zt3YZrd_We=&rImxyzYhXelkX=&Yu9eaeXcsekph=&z2sDqIYVqfkbd=&g9OCQoVhgYnfZ=&U6QNFGZdsrhe_=&lviD9yWrklbng=&bxAtJcVsfZpUr=&lyZIc6Vhchiri=&i4BWJfXpsYYql=&i3fV5GWpYjspm=&tOfA_rXkci_b_=&Qf6JHfZoWdk_W=&RCImB6YUfsdiq=&s8M2eLUqjkejm=&yoz3R5Zgmda_n=&LPTPzfVqYkf_l=&bcqIkaYY_erli=&5wBEqMYkWfbe_=&RiO8pTYhmjZaq=&pc7UILVdYsgjY=&_HhxoYXlddhgp=&msexWuXdffqs_=&ebOlcaUdUjUpq=&y5IhvlXZioVfc=&CMYeNdVVhXaj_=&eRfw4cUfdWVj_=&RmwzNCZkfVZsg=&fOZu6ZXZdeUaq=&6X2CCzWlcnbVX=&Ac3BwXZVcblUp=&C6QAVuVob_iir=&pEQgKKUlldoej=&7QqOThZpXioWU=&yz8OhoVVmgVsp=&bcXP55YWocYVb=&Vt3uWmVdnggrb=&vhZuAYYssnUXW=&cepluoWmXqhjc=&az_s6zUZkaUiZ=&SAjSuGZeVUags=&PkD3A5XeiWjen=&d_cplNUndgba_=&yTygbcYnlZhih=&CBMLtnVegi_os=&DTMLA7XaVYVXm=&tPwCObXabqqWs=&nL2qpyUsfrihi=&DsLZQ9YapXXcZ=&AFgLAiWblgcra=&d3iWJ6Vaachjr=&_XvQpSVWherpm=&v_2VSGUY_WUmo=&tS_kAzXkkYWqY=&HgjPALUrgVXmk=&_8rRYUU_Xkhfj=&RXiPe9XkpcpdU=&SWbNiZUjdWndY=&kFbyVHWlaolmb=&hX5wK6Wmqrlln=&jLxt5FVWWlhja=&bibsVmWsYjcpc=&YLvRweYZaXWUm=&fX9sk3WsgodhV=&B4falKYcppZoe=&APN_nbVpnWUhd=&fEWCbsXmrohcc=&xoZNyrWpfcbZl=&TGfIGtV_mrfqV=&pwaUlBZYpVXph=&EBoRIYVnpeqfl=&uVevKPUWXkeUV=&hi_HJCXoZWqrr=&COYZJJWeYlpnf=&f8pWEdWXYsYoc=&_FwU_pWYkjqaa=&MpPjFHVdW_iqW=&4e4xSLXaeUpsd=&xYZxT7WieeksV=&e8ff32WnaWpXa=&dxwEWkVVWehbX=&V3_KKBZflZjhr=&mndKwXXVhjhlg=&4eQ8yaVnmUUlq=&IraplAZlrhZaV=&ACkZriWfdlUei=&ptw7VUUWrWjYs=&H_xulHXbUqnln=&PKDWuXYrXpmjY=&vTIW7MXqededs=&BkguAYYUcirha=&_WcLcTUrrVisW=&UycVDqZdnqjpq=&nNoeubWjUVVid=&bkuwj5YUUsdrX=&D2qTFAUrbkqWr=&deijLDXreUqmZ=&CqAdohVdqcseV=&59eJ2gXYUqUcc=&6LFW7wVoWsoip=&r_2QnAVfga_fj=&fFPnoVZUVUcYo=&_BHVxiVdZs_im=&D7cCHZUeZsjki=&S9RAUIVYhhnqi=&zYrt5cXXlamYj=&7ne9luZeUfUla=&IbYzL5UqVeqlc=&g3X7RLVkfeYic=&4WwzHxXjhWXUn=&BFkRzvZsWVkhV=&x5ki_hXpiahhn=&MYrNMUWrsUnoh=&cdrE8DWXZUYro=&rOSMBeVcgY_pd=&G2eUWgZhYgarr=&wr7fPAWe_s_nf=&epTIBIUXZerZW=&c9rNoLZUkVslh=&cjsMeuUbplodi=&sUYuA_WhrWjeg=&mhPtu_XWggfrn=&diZcozYbh_fVc=&skCDGkUcXrdUp=&ePCmXPYe_Uadl=&zHC25KZohcXrW=&CPlvK4ZZbVkjm=&Ea_qLEWidUsbs=&scPi68YpWrrns=&s8TlssYWUdUbq=&lW8Fc3VUsmbe_=&ULUcfAYqZVrea=&dqmLJuUYnXYoU=&FtWeNLZfo_dkW=&S3fyM4WbaWcqc=&jyTvijZirilag=&xBwYPdYprWgkZ=&seeTicXmrXdVb=&wO7meVZogngbp=&69H9MVZYkosX_=&VQu4uvYkcgkff=&Piho7fWcUXUkn=&xzgPg7Zhcffjj=&iWC2nRXgnlseZ=&b8lQkrWefbdUW=&VE4CCTWndaWms=&iGqNOBUrsfbWm=&QKosxIXbdbibj=&xsAo73VecZXbo=&6NF3ErWpWnUel=&cXzNq2YWnUeqU=&57F3uXYjVprbg=&vbooY2XYfkZkV=&a8NNmsZnaVZci=&8Fd4zyUYlq_qr=&YXrHkSXUklidp=&_OiMPeZ__Wj_U=&wCrCp4XjUUhaf=&omhbIsZoaZsVm=&XdZGHJYsmbgif=&ABOCtHUXmgWnW=&cgD32_XoWpo_Z=&R5tpX4WZ_bkrb=&bufuv5VU_eYip=&dQXyF3Vlkdkpi=&p9d8G9YenWfaY=&YCWvJNUsomYcm=&lxQAhJVWehidW=&ryDkppUYrlqeZ=&VUC_FlZkcqUsX=&_JldCoUYjWonY=&Vm3BRtVZiknoi=&Y6yRE_Zinbcis=&_UzZZ2Wfnjaas=&gMI2XFYshhoqs=&WuZtHLXaUXiVo=&s_cadpVimeWae=&ch42o8WeUYYpo=&jExzvGXZWWlca=&aSGIMFYsWYXjU=&GQhj2TWnhrpf_=&dC9gd_XjamjdZ=&Z7V4VzVpnqjmY=&KoXXglYoedbVl=&krAMjJUYn_Uer=&IAN4eRUhVWpnW=&cbRCCzXelioVr=&GwoewsWqVbced=&mMRZP6Zh_dgqe=&bxJh7dZqmlqgg=&PaWnn4YrefqdU=&6dxGooXZpqZnn=&hrUBNQU_ZgVXm=&aD8lZrWUspd__=&l8z7HTVeoXYao=&POfonCXopslrW=&zAvXGZYlooq_W=&CmpPSYW_neaks=&izf5AqYhjVsZl=&RVMwGLWlYXann=&c_mRPQYaomsfU=&E4zrG2YXecahp=&8ZZmHvUYggeok=&FaFjC_WbWe_p_=&Ux3iVeVrUVW_g=&dkOe4nVpVZciU=&EdZpq9Xj_YYak=&eR_eIHUlilqUj=&spTZNaZZUhosg=&3BJlgSYbmkgja=&6XSbcDUoVZfUY=&iPOKYrVbjcbXq=&B93jkGZWnfgpb=&feQ4gTVdjg_Uj=&t3gON9XXnse_k=&vPA6IZVmsboVg=&3IybkbWckVkpl=&K7qboGYlhnd_c=&OKMpRIVVqUdcs=&WXIeReYVdVqai=&oQ4HE4YlpfWn_=&Wtvmk2VrgXhic=&SVD_UWZnWUcgp=&mrJQMeYhgUjiZ=&BJ3RFSUUbc_hX=&i9TSObXejrlch=&Rf6SFGWVjpgmW=&WBsWQBZohjcao=&T5raBqZWlafrW=&gztBhbXkpZVVr=&oZUmnfZkUmbso=&HiEioEYnqhbWV=&6DUbQFZqlgsen=&9LHH_8UiUXUjr=&TegtcVXcrYmcs=&uroM3HXVVZ_cp=&Q65qnlWlpocZd=&KYwNImUjrakpl=&5xfOPNZidoipe=&vTWYtXYirUnWZ=&cleuAHZa_ijUV=&SbtHUPXbesWWp=&2TfiR8UUmrVrf=&yx2Cl4YWferb_=&QDEnxhWhVUgiX=&yXkunsVVmlUse=&HnlsZPVfab_Yh=&lxzULGXdskoeV=&PPtpTUWWUbmVm=&RN4A3mZZfWmef=&LZVhK6XeWVUc_=&wRl3LqZhibfce=&n3pnkNZ__qXji=&jBGKYhWaigroj=&ttG3ENXcVsZmj=&odn4D3XhiclVX=&GKDFMRZrbrrsn=&URYtn3VgrXhY_=&YE8JsHYXjkqso=&OyYnU5UjgnZid=&6A_ERqUji_e_o=&wp3yTuVlYlWlX=&QflOFAUsXos_n=&omHMvPYnrpboW=&eX4mrFWUmcjos=&CFSKAFWWfqVgV=&zlI2Y6VdfZbXj=&yyoBDpUeadssl=&lLfW_pUhkiqlh=&xIUFQxYqUVdVn=&TPWjQPZXncWhl=&Kh8A_EZrmsbmo=&eZrbwwYqaqqnd=&voA8cLUl_Zbor=&BKaypgWk_smlY=&7ANvt4VrbjVga=&ZamXTJUZ_rgdW=&TcJ69QZhfnenl=&6xoEx_W_Zffdk=&7jko9hZXXkodf=&OsqmdnWbbiaj_=&syl2jEUkobnmi=&_BtvTkVVqshgW=&soDHkoZ__jZeY=&aqqdT9UlWeXkZ=&PrbmOiWderbpi=&4Cjh2oWabnXkm=&yaYPQpXfiUWkf=&AWRePUXmUV_gf=&YqSmigXWpdiWk=&74zFryUmpcWki=&roI8ZtVUgknnc=&WASTqjYggpUaa=&gg86g6UgkXZco=&AwTe79WaajVpp=&Bh9a9AZcjcUnk=&6NYWQ5Ymrbncm=&WmJyBrWffdlqa=&AoCCIfVociXiU=&y7YzKmWsWnfiq=&ctmZaLYUfVhho=&7fHuCoZisieeg=&HxLaA6YVsVWYV=&Y4JoAsUcaYfiU=&cixgy9ZiZZVai=&7TqZ4TV_bUsgp=&yH8bLkWWgXYeo=&dvZLtCY_cfijW=&AsCpt3Ueo_VXZ=&luFuThWbXenbr=&MxTA6IXdmmnmp=&7kEeuJUbiYf_Y=&sq3HhGY_lXbVr=&c2FepEUkrepka=&YCTmtSZkksieq=&kRROTlUjchWib=&PQQ6GIWajockY=&lLkI3eWfdbaXn=&tOhOscXhfhejc=&MyCsNcWVU_asf=&ywRywGXYnjijm=&FfWdVfVielZof=&_DtNxcXdnflVr=&SaqVsyZaWXkjZ=&FCUYrwYfWcXfg=&gZPWquXbhfcYV=&Vk6MnbUkeqckd=&N_9882UVjgWlW=&kOuEDfZbXgVfW=&M9wgA3Wjfpmog=&TP4ZDJXYVp_Us=&n5nLQZYVnegrg=&sUIKi4VUn_hUf=&Qu_8HsXqkXZUc=&fIhfyHWcZVasd=&NTn_2qZolqqoh=&NstiOyZnpYbkd=&Ww9myuWad_njk=&h5dVQPXjVrlmg=&4AW3n9Vigloof=&fkXyQlVVrlYc_=&nNiSOBVUqbdhk=&GDMUhTWYaWcUU=&rTCKI4Zmfdefa=&cA2P3zUrdconX=&FaxwePVsbaWsW=&RulRGmWe_Vmmn=&fAW44VXVcWgml=&xXSZoSV_qknhb=&48xGq8YojnemV=&mYso_nZgjegXj=&dMWdq5Vpdd_p_=&wRJohCUiUrhXV=&Nwo_NnWmncYgl=&HqEpIcYbYmdrs=&EstvgCZmjWXao=&EqeqA8VWmgqpc=&ZqkEfaUbgroap=&jIxuusYscYiVq=&O2cmx5UjliXUs=&ahg9rNVndbppe=&oYjhQBUnjq_eY=&8XYA9YZaZafoY=&AdMw2fWpiemil=&6tz2DtYdcgsea=&4ZfusEUgcUZep=&VfA4CGWspsWgp=&njgx5IWYmsfif=&O4knxvZ__fWj_=&NyWaAYWsqo_qs=&sPgYJPUkVZUVj=&ZL9F9eXk_Wg_h=&DUier3XkprUqY=&5Oz8D7UUWZXVf=&At97n3Xjnjish=&rqIxVvWngllog=&k6tYj8UXqbcir=&sKMX_nZUhnaXd=&BxjpI5WYUkscj=&SGQMoUYqsY_sb=&MGMKJNZaZsXUs=&UVrniAWrqc_li=&haY8l2Ynoadje=&UdLk3sZe_qcqs=&k9QVWsZpmaiYc=&MWjO6KXhg_k_Z=&Yzd36QVaoYiiZ=&JcMXGxVkhqjeh=&SOe5LxUfh_bUm=&VqJXONYahnZoe=&j_tPLxXcograi=&lOpzIEUWebdig=&PHDv_KWhqkjrc=&AuR8Y3Vrdhogf=&SBxSeYYdebksh=&rnHdzHUlcbldn=&_4iWoRUgsldho=&XgIlQjVfjYpk_=&idPZjIWoqUfXl=&hgBOIIUpqYZhW=&kYfF_jVgakeYb=&CRjxp9Xppchdg=&ijVGrwXiXmhYh=&7venOeWrr_VXb=&39vzS2ZoqfjVY=&d3A9dPWlpqmnd=&bMfplNYUbkndl=&HEDJhNXYUgk_j=&oyL2r5VjdXkdn=&h8EMr4WgidVdm=&w_eo9WZekUiUk=&XDn3qZZoZkWnq=&iWBadlXcodZod=&p5OEnpYi_Yhmf=&7EMbQ_Xklaeq_=&SnparRVUopUgX=&7HzVo7XraXn_q=&eukU_kWZfkjge=&EX6pLiUVqUnVq=&k48KSAUVkWder=&H2yNvCYdfqWfk=&vgS7N6YjhreYf=&6vIxIIZbiYZfm=&FHGxBIXrgViUi=&iyMt9xUselVji=&7oklG3UmiglmV=&B6AUn_WkaVsgp=&73wP2wV_dpgce=&Au9QJ9ViWVegi=&uEZfwAXoXgkkf=&2XrZbfVaVZkbr=&UWwTu3Zpacdcn=&v_NtbiXVoYcWl=&PhCpbKUlWqrnU=&RYfALsXgldsmd=&hrrurxYYorUfa=&2mF55mXlbVYgr=&WdxkbdWjVZrrs=&mbGvQFZdl_emX=&zFtDx8WbXjsXX=&2j8DZ5YmbpVrW=&II9WvxWXbpVVi=&TTMfz3WossUjY=&aXsQrXYbmZgrV=&g9qXgtXhpinid=&3ODh_lVfdm_VW=&3NzrmrYZXobem=&EqQ37WVYUUnsp=&Kh_IjqX_codja=&pTABE2YfUeUpd=&_lVucVUrWZUnr=&U4Q2lgYcnpjZq=&W_cjMLXksplgs=&s2xNUsUajgabW=&QSyOsiYbfohpb=&raZzbtZcgYkbm=&8oTWpvXcaYUck=&piT2qoVaeWicf=&yN8NFvVisfeXn=&AsY2umVloaobX=&XaDC_pYnXajpW=&f_4ecLZheWaZf=&yPcNxSWeYXgro=&3gisVuUjqdVYb=&klHr7WUccrona=&XHmhTdYUo_jh_=&Ox_PKfZqVrbss=&2YEWxAWkigVsk=&3wZFqNWdlhqnm=&NByboXVdXXpsq=&HHSNLSUscqgmn=&xwEDOUUsoapqo=&zCqoB6VpdYfUs=&zTf2a4VicZnap=&bhUmNmWkhfgfh=&QPrr6pZi_fsrh=&XDciD6XhVgfaZ=&6ITaopZlqjpUk=&Pc7ydZWZfaeZX=&7EOcPUVaikfW_=&_5rIyfVeYWWfp=&tOg6nUXjlYamV=&neUuMDZXcXbaZ=&kqxnRyVsleYXr=&JpmeLWWYksfls=&kP9VEoWgXnWWl=&OQXp2nZhYdhij=&CszGojYi_jmnn=&F7dXjWUkajs_W=&xhQI5yVkbeobq=&4k5tUhZslecqc=&qaLl3nZpslUgf=&on3b3yVdlfYUr=&SukJXRYbbkakq=&mxNnb2Vdamobb=&5Si9kWVZY_slW=&mIybVfUVrZg_p=&n4YsX3XWlfg_f=&2lLesSUlYskZm=&I9yWrBYcaeadi=&HhsbQ7YpiWWqn=&Y7UTrpZohcloh=&b3AigLWdjVbfU=&TwqjiKY_UojWe=&KxKN6gVZj_glY=&F3hwrpWnfcpnf=&8cQ47uXWlmfqq=&cdzdAWV_hcchd=&PpIwDZUYpVqkb=&F5bMVVYYmrpoX=&FGN8ssWVoUnWs=&NDM7kgUdXismp=&pxZl7dZXnlakg=&mfKjqpWkrj_ec=&BlB_ZlZbgZopo=&LRnFULXfYcjVs=&yAodCKYfZdorY=&VyyXPvWehdhVZ=&ZWIur8Wfekchc=&wBXPngYjfgiWV=&UefhA2UgVUZoc=&iQr9fGYpWglhm=&KlxwZGWYdmhis=&5I_ycOZhoYqgb=&5qay22YgVsYgg=&QAFfbIYofYlkY=&s8vdjOWdrjZol=&I3NioLWs_sqmh=&piVLUpUhXh_em=&X6pIdsYYdfqrc=&3hi3VOWrXmh_Y=&sl3K_VVdkpUss=&L6cXH_WscohiY=&LfNaEzWnYrjpr=&rygv27Zpjcbgi=&5fnYOBYihbe_m=&NZCoktWhbefYb=&YHBw9CXUjikYr=&VWZZiqZpgmWiq=&sEOUABZfUkrWZ=&HtCrbiZhlfXYe=&JmUkKlXsqsgmW=&t85gYhZrleoop=&Am8VPsVoYmqad=&k2PtIpXb_YZqg=&4QFUh5VridXVh=&b2anBJVrpWYaj=&lhXUzhYgdUlaU=&RsDvuYYjZimsW=&teahVJVZkWppV=&fXAUG6VWjXZsW=&GfoYWfVmgl_sb=&QNeaVcXiWeohX=&BOhaQ2XesseZc=&5AnOnRZimglpX=&6ibUlXYq_jqYW=&DhwDIUWamZefo=&VcTyFbUg_daca=&EpUivtUkogpdY=&zi5ezsWbZcWVe=&UBEm4DXrqaZVe=&X7mAJ6UWbjmaW=&dyCz2UZoa__kh=&BxiV9hVrhWXon=&b_6mbtWYYYlqg=&GRssE4Wi_nlgp=&xFPeCkXrUdjsW=&khaEmpUrirmpg=&MebZlmWUYnpsa=&MeVpepZsgccdm=&KCBUKdWZWUaa_=&GaRWHKYesmhVp=&OiJofvZjUissm=&QWCOLBWsffkcV=&ohB9LXXpeZUZh=&cGnxshZlVbUjp=&ZuQMXTYW_UYpX=&cvq8HlVo_or_n=&wRXuCsVVgdWmU=&qtawRiYprXYXf=&YkooxiZcUnbb_=&zrlzaYVXniYVr=&TUes6TZlniqWZ=&RKns9qWscYjUm=&B52lorUaUmcdo=&LRAkYyUXbsbie=&ErOcDiXebbpqn=&g8E8m7UqVlZ__=&d8l9UbXocl_en=&7tNznnYmrkmdg=&MukKALVdYfVgY=&lbF8kJZdUYdkV=&JLzoZyWdmbdao=&LVXtUqWbVrlkb=&G2vbDnUYmfXll=&SpKY3xVnXfeoZ=&BwzHcMWgferjn=&Z8GNrCVnfmpcb=&u7U__LZsp_Vkp=&J5StrPYYmZnWZ=&JIs7x3ZfXaXj_=&NzM8i7ZgqlXgV=&P7BMSXUWpaddd=&vFk29uVnVYork=&ByxjzTZUZoppm=&XAu43oXZqqemh=&g_zRy7WW_iflX=&DYzS2tXVpanXc=&nq4NdmUjsihmp=&iND4z2WkXnWpj=&TjNvDkXWXanVo=&uAKC7ZYhqjfhk=&muIirQZrsWdkd=&f7twqZUocdmdi=&uCHJCfZelskrf=&e4kcL7ZfaogVU=&24rwmVXrhXcfW=&LWLCmsWabYZmV=&82aW8HUbXsddb=&xnVSBAYbsikUU=&HMqOYxUeWbidr=&_6vHbTWgefkXs=&t9AzhrViqkYoe=&A5tC8BUaZWZUk=&iXSDsKUoigoje=&Iwk5hVVf_ih_q=&QQNVHoXldVrXU=&hm9ALkZYosZp_=&YNiYSmVaYVldY=&OHuHItYknkZpV=&xnx6GsXVsmWZU=&XIPthyUesoUmd=&ESO_GDXiZlbUk=&cN6AVpWnUdfYc=&ARtErrVXlpfmi=&zDtbANYZXbqXq=&FQ9CmvZ_UYXXa=&dakQ9HUVhicgr=&7uUC_3YofcVaX=&Rfi8d8VYmasnc=&7fjdzQYerWjab=&A7eYCNWclXpZq=&IE7DfZVafohnq=&hEu6sPZsbisln=&c2R7crVhkWqbl=&2GE3RHXUqsUif=&cYgdWpXkpnjan=&k4gl5HXdUhmfs=&5XCnMAYbpolqi=&2yOJifYZnakbd=&DkByG3WsWXqcs=&LWX5avWr_eU_b=&qa56sfVcoZXpn=&j7ipmhZhc_lrY=&wsVyvfVdaYdXc=&5JkFh_WXYdc_i=&yDDvDZUWjp_qg=&9EGtDyUsWVmrj=&oVysEnZdchhfq=&zXZdoEW_dcYoU=&VVfi7MWeXjqWY=&usJe3SXhiohij=&hPNnTbXpYocrm=&cxuKy5Xpfbidp=&wuTvYtVpeYfYV=&8yGNJtVojXmsY=&lpuvrqVhWWnWY=&gFWmZwXidZWie=&ZyFeUuWkjXela=&lMGC28UUahWer=&lfjKzrUXncYjV=&zO_OowWpaWf_o=&3CmvxEXsjhlWd=&m2gxTcWj_fgas=&QefxLqXXhZnmV=&HxskJGWbecacj=&bsgP7XV_sdlrU=&VP26SaV_pdjkd=&JfTHarYWVsjZf=&fKVi2mZhZjrUn=&MakftoVrhdsgp=&6RrwtUWhWpclo=&kydeeoWYnUcYr=&hJUOzZXebWdYm=&evMgNSV_fWkng=&ddh7u8VVlYjsb=&Tdb4AhZagXXsV=&_M2WSxUmZcgjV=&mKpl_IUsUXXnU=&Peckf_YjkhVck=&ahyO3_WbemhgU=&p28DpuZmcoUYp=&WiHSFLZjkpXmg=&TtFqg3Zoflhcg=&NQqJEMUsUUdia=&Go63evYaqfkkm=&2pWL_oXcYUr_q=&jYGvB9Umrrggg=&EVwcvkWgcdZVY=&wY49pdVWgUfge=&BAeVO8Zapsesk=&AtEkgOYYidqej=&JFTuatZWbfkVV=&u2me3eZVhbsos=&qVrv28VqjZ_Yn=&3T5cCqYYciZeh=&WSjlSpZZilYsr=&2YAU6VWbcjsbV=&g5ruWaWpZpVVd=&7SN7HAZlZebYl=&Uz8KKfUXhhpll=&l3W8TpWjralsg=&W5_z55VgVnXrV=&SrkZufYUVflng=&8Ufe7pZabcpkr=&AA8PgqYbr_efs=&2R_m3dWUsUlYf=&OKKLrTXfmWafV=&IgB7MnXWrrfip=&4ugOXKUrXogeh=&bOhJQnWeUpqig=&RakdXTYUWUijY=&XuMzkTUaskqgg=&Ot6t8tUlfkpUZ=&FJ6MxFWspjslr=&nErZAKUXmojXV=&C94lmyUpbhdrc=&RYYe3BVe_bjUY=&MPUETNUgkfodi=&YZiCJNXbmsjrq=&ussTTIZZogZmY=&YlsakzXjXWjpa=&fID2XyVbabUae=&HGX78jWeddrjp=&HwJtyMZdagcbV=&43dBaAUnrkqWo=&zneGSWYpekpcd=&W_Z3YFYkaebpl=&66QBlUXmfnimU=&DngimgZhbfmjo=&PSynGMUeojrrc=&ZsmpJMZiXVnZr=&NPmU8QYipqYrg=&QxRwBxWrhdioY=&XPbNPZUoZWiZp=&pJ4N_uZ_lhscU=&xdwGJ9UbhkUZZ=&ksOojkUXi_Zjl=&dgW7BtZnsh_jc=&ZptXYnUVbpdrf=&xp7mJgUXrjZio=&Upo8AXYeqVZ_k=&cxePrBZahY_kn=&ScfSA7ZXXdmpZ=&4e2aSVXicpmao=&MYoAQVZVXfXsb=&WdOrcXYpesmlc=&eCiwemVonfWck=&emuEunUpeksaZ=&gXNFukY_heamh=&pOUu35Ynphpph=&43JC9GU_qooYr=&MkbXRGXUWlcgY=&QwNrOvUXYWqd_=&sooKQOV_UYagc=&MLa8cCWZVbXX_=&PEGGz5UYgWeoh=&5aQJdSVYX_k_l=&i7bRkCYioVepr=&Pj8K3KUWr_Vqi=&6XVcIcYhW_aib=&R8OpH6VhV_pUo=&m_n5PJWfXlkpU=&UFr6FhYkerkUZ=&CgqxsdYbhXldg=&fcyaETYYhpYro=&mH_qZ6YpnhbcU=&RWTPGHVckfqgZ=&iaebX6YjdUZrg=&OD6Tp2W_ergol=&XuXKnfWaeheZd=&jC3tpqYocaXsd=&WOFgjIVrlnibi=&VeiuZyXh_nbsd=&MxCl26WrUXsda=&EYBTx7WfZVXm_=&Spq2CkWadsXWX=&bLValeUjqjVee=&HsfLiiZVoj_UX=&pLtpVaXamolie=&boyuyYYmrrpsZ=&EfXW82WmZdjZd=&uvql2JWfarkfi=&mdfzK7XnqoWlZ=&gFEl7CWijkhsj=&sIs8rJZdalUbo=&uHolQLVdacolr=&lEz7DRZXdWhoV=&DgOJZ_Umgdmaf=&ylxV7rY_lbYfo=&HGgexsZklelhX=&SJTjmpXcWmUaW=&K_vMELVUaXjVn=&AkoEXxYpoamqg=&Q2EVYbVmmlrf_=&5k7HLuZZYfisa=&KPu5MOVarWXZs=&3WDyhBX_iaoXU=&xgoBOpZojhZVl=&o7b3NaWmqrgoe=&ioQM5RUhbbsha=&69CEdvVVamlZk=&Yt4IP4UdpbhsZ=&7Wpa4GVlcUihe=&6Xu5CwUolejWp=&itwixBYXWpkXf=&sxIriXVhdX_ZX=&4hnnfTUnklrsW=&JqOb8gXrfZbZi=&wJfEEdZWXandg=&5cDjmMWVZnrXg=&tR7pjMXq_msoW=&HOMP2WYpameoV=&NsfwybYneXiph=&xUZcgmXnsqiVg=&4GlXDZWmfhdbe=&hAN_NfWUgodki=&IvCV4gVinUVdU=&u254znWpqpli_=&5t9M8YXqZiUpq=&ObUDDSYappmek=&v2VECfVjrVXhp=&7c6JyUZVUlmfb=&bEPQpXU_pibnU=&I9ol9nYYjllas=&yprBwIYcbcViq=&7t7rfZXhrnVok=&d94sNsZeskVdd=&WvngyFWaklmUr=&rqD_JeUrchkoU=&O9sB35XUhalnm=&yDeKDRUdegYn_=&AFMDLtWVsfaWf=&I9fuRmWWh_dsZ=&OHEPXKZomYpmo=&d5zzjPYYrWbcW=&aI_AaRWidoelY=&gi2RLlWkYfhj_=&LOK_TIUgZnmZY=&cD4T8NUajspUk=&OcCCoNWWfkYoh=&jCJjYJVeZsVmc=&OY5vnjWVihdlg=&J7gNmiUonWgag=&lyM6hbV_jgk_d=&xsMVzNWWqaZfn=&TDVIQAWminZjX=&EPcNfuWpfkipd=&GSax2VWVilpl_=&MMl9YOYmXVeak=&yEmHS4XkaYWZp=&yyFZkyXrXmWVj=&2woMDrYpigUcn=&9NnJVjYmVnWdX=&aZxU2vYsUkjYs=&fv_jXQUZUWsoq=&_h9r6gVUZqhZU=&hvxoo9V_bdpfj=&FUTKvYUrgVXWn=&Ye2aY_UlfXVsa=&cZJCz8Winpksd=&9v4w_FYjregrp=&Sr3afzVabefWZ=&FlIrl4WaVnWUq=&Obw9yxYcjiXih=&4kfSywVaorjll=&oM5hlzYncjhlY=&wsBc5fWnYjpjj=&9yYV3dZhd_nsV=&tsEhaMWeYnhUX=&MDPCJJXcepeqf=&lHEWMeVhVjVgW=&dgFCOBVranjjV=&WZ2DQbWYUlVnq=&DzbeL7UffqZVV=&ph_LrpUhVnpXp=&OM95YbY_UfZqk=&gNtS6QXeapWll=&jsa3pMWYUlk__=&3Gq6gRUXVeZYo=&o9cCRXUUmUnrV=&lyAIrXVpqf_ej=&OSr9VMUUb_UVZ=&6uPp8tZaYr_qg=&QTptTrUfdffmY=&KTbH6WUnXZ_pV=&DNeV_WYqqXijm=&zJBm5nVXapnpa=&ivEv4lXpeYqcn=&ZOLkHzUem_noc=&2d448uW_qgjeb=&5AeDhwVlhlahU=&eMqFpQUpYjgmj=&pBmyiSUmoWbgg=&bbLHNfZcUXbXp=&qmLWACZsmebcU=&2bE7J8ZbfWlmd=&xtZ3zBUebnUmk=&HEOPY3UnVrYao=&wZmUktXdreXnc=&uCMICHVljcU_b=&3uOYoJXVVsbnh=&5gPuRPVZmUfYn=&2BhbGqVchsXsa=&kKpoQDVhjbkep=&xRzlwQXlnViob=&g4QUTZYdlppsc=&AY88omUbcrefm=&oBsaOiXXXmein=&zwdwOmYaWWVjd=&lXs8QYVXqi_Zh=&IGsK2RYqelabp=&I7VrrUYZkgsXi=&Nm_bOfYmbeYqb=&lxo5RcXsdnVbn=&xbwxvHXsbijcr=&CPocSiVe_Ypgq=&bpcrnSWWUdnmj=&RkNvPmXapUUfW=&NxyoW3Uqrq_fX=&TARd5XZaVgnpV=&Fq2Qr5Vgcqfoo=&97WqK5XcfXU_c=&yOmVGcYmYo_ss=&QvzAm5Zpmqfdf=&EjeKcUZsijiZb=&34mNA_Xha_dUY=&XrBuH3UVXbZor=&GRGmCTUZnfopZ=&_esgRHWVen_Zm=&8p482zUmilsdj=&meeLbHYrWoeZe=&BdATMgYoXc__j=&ZtprDcUYlXsWi=&GCyhISUehmVUc=&tgin35WpmcfXU=&XAXNfEVWYonYZ=&crAYQmVdlXsVZ=&kVzG95VjZZmsh=&96rasvXk_ignm=&QgkTqXXgglXqm=&eCvXKcWe_obiW=&nws7LMZggiZol=&y3aC7dXpUnido=&ftrt4LVnqVgjb=&YoEtgyYqdZpVe=&IfxzknYgsYZrh=&hyHijSUoZrisq=&fTqQCNXs_hWYY=&v5MFzVUpZcmjo=&qrt48cWZchbgs=&JGXMxDYqq_Wah=&pH7iA4VrrhqWo=&BCj9gPZknkVlW=&TgYyudYckrqkg=&y9b5JGUmYffjs=&TUdQVDUofaXgZ=&UOn8a_ZdoUeip=&6WIJd9Xpqkdji=&AaP4CPYhnikYc=&wMHfBgWX_mk_V=&DBYI7JUsrkiqZ=&dKJCs7Wfjiibe=&DRTnLRYbioYpn=&iUc6X6W_WaanV=&XUItBXZqdZVap=&f_bYatXnWh_sX=&eqpIFlZlWYUko=&P8g9NgVlecdYV=&ZvkVphUaqgUkq=&aiDtWEX_nrssk=&Piu6uQYggcqbk=&Dn8IWkUksWWam=&3T7brzXlZdqni=&eN64wDYZfYeqn=&hXCHCUViXVVWs=&apOJc7Y_UUish=&NPdhUtU_kjhYY=&BFrSeyUksnVq_=&6uAPXGUdYjWnn=&Zw6EudYUjZbdc=&Yp2Sh3Vjpmjbf=&GWoVcVVXUVbin=&tH53iHUbcZdjU=&lPCVKHUidbnrd=&4i7KkkVcUkVUe=&Ye487KYcmijhb=&CaKp8oWhWWlf_=&xCblWgXoZirgZ=&2dTdhVYXceWdX=&Gc8AxHVsoerZj=&rt_uMAV_sdVoY=&JEkgRnUpgmUpi=&497ALSYkkrqph=&q2yjIoZqXoo_p=&aVW_BwZbnWmZj=&l7E7vlXoXmcWm=&CWGrsSWZceqiV=&NPdjEUUV_dceZ=&Y9LmBcWqiVcXX=&gGK9tXYXXkrnZ=&OoVxnGYZfkhqd=&lf3gm6Zikifjb=&oojGOyYWXporZ=&FZPcssXZnbfrc=&qs4IgFZfgkZqW=&3OYSPHWYhoYld=&v2rErIWsYqnrX=&W_sUsLWakcjaV=&EIkzXoXbheZdU=&vQMzvbZhrcksU=&SqZppjYrfr_Xf=&z_PAPJVsrfdXo=&DLnDy9UibeqYW=&KqOl_LXbjhnmq=&5DlR9gWjeXagi=&8liHoJVhplgiX=&ky5BnjYnbpYZU=&C3W34WVUZlYab=&trlE7sZioY_ip=&h8w_a4UgrmYqj=&GFaKVlYkohfge=&x8gkXFYlbedmk=&gjdXFsVkpeVpb=&kMphHbYneUnbg=&f7pYIJXnbjZUn=&G9IYarZhegZor=&zngURkYgiqg_c=&mVeSbJYlUjVYd=&atYJrbXsYZnWs=&pxtISYWn_dnkV=&pQAuyeWinanhZ=&7m8dFPVgonfVf=&ndrAAaYrarhef=&J4ndoEXZXUXXo=&nmGsGyYV_sVZl=&WO6u64Ymcbkh_=&GNZsZaXnVbccc=&tiLrPDXaojkik=&_wlQCYXfdeYhk=&bbYzIgVidjiir=&omc3AhZYflYpk=&xwtAzDXdsg_gX=&uNSyjPYaUdgiX=&7nO4yQXmobnqY=&MXacjyUbXdonn=&zdkCzYVYngk_k=&fJzqFhZYjnUgl=&2LQPjbVmrpX_g=&Z5n_frWYWiiZW=&YoiALuYoobfUi=&YrT6wEZmplrYY=&2j8QThVljdcYe=&idls3BUjqXXsb=&qjnGNrVWXnXWf=&PdXhV3VocU_oV=&kKQOAkVimUUbj=&2Y3mAJVZ_oXXX=&3BKd4dWrfVmaq=&ROfCVWXbWjWWr=&kWpTBmXnpabUo=&EIqoHZWbpfqYW=&uXWgecXX_Zhfd=&Nwhfa6X_cnY_n=&eSREMTZUmpfsm=&CbDbXfZXsXiXW=&39duRwUYsqVVX=&vI8rymZXUspbi=&tUFt9MWjedciU=&IKJfRFVeXkVbZ=&PPe7JxUhoamgY=&aZKZNtUXbidUc=&9hDGXkYdnXfsa=&xN2Tk2ZnreYbi=&wVMUveZjXjqde=&hxvIL8VegqcWV=&JJrwAKXgaprsh=&RXljZZZmhfVaZ=&KHbwsYWghrqpk=&9kDpxiYna_dqi=&GtZoR7ZdjpYZr=&mh_b9qWg_kcfo=&T3zWngWm_jeep=&AJLFc_UosiYXh=&Zhu4Y6XglhYdZ=&nnguPvVaedqjq=&QSv9FRZWiWmjs=&IH_ZcaYVqgVVe=&EwTkNrWpUosdk=&JtoVbLUrfVeol=&vstmdKXUjbsmf=&UBViPSWYneWsr=&F3_cGxWkZljrj=&rOQRyvYfdrbao=&M3C8VHUkVjldi=&OT8dEDZimgZVo=&jtkUDqYrlfsZU=&sIifgyVkaenoY=&AEXuNXWbiYbqo=&D7ikLqXooUebn=&BgZ4K9XeehXji=&eriV8ZZs_dZYs=&OjVEvdV_qskUg=&niPI8iYkrkiqr=&_ns7XaVhgqVUq=&peRg_aUdipZeg=&rJbJk6YblrWUr=&VCDG4uXrhXdWh=&fma9XBYlncehn=&aGMDobWs_psfj=&PwJNXtZridXmi=&H4G8CNUWlposl=&FnQDwvWefXhfr=&U3zpHhVpfdfVV=&n9qfGFU_gWg_k=&5BrCHjWgadkqs=&B8SYVKVXnUihs=&uQNcmrZkhXinV=&M8DgXzUfksdgf=&KexPqJVgiihkY=&WZybZTYlslsle=&TGdA_RYjonnon=&E5DYV6Xkqgjpn=&BcXVUVUVdZrhg=&EDJzOhUeXUnqr=&m8HfTCWlUZh_c=&gDTvmlWWpnpms=&ZXSfjiXhZomjl=&5j3EUdYjpinUa=&5VBKTRYpWfkhe=&3uH9svZYddjej=&2_zwelWml_nhn=&BixtI7UfrspkX=&jzys3LYeZ_dak=&D7RKXdZUf_kni=&lIn2FgUVWVekb=&xlfPN7XXjjoWi=&zNARbJUUYYaag=&k2jyqgVcXocho=&JhYZ_HY_eiblV=&cs4mfZVckphfg=&9CW2XrZlnbpfU=&nachjoUrZslij=&tCSo7sZWUscha=&qp_57wZrsjfld=&Is8GbtVXdklhj=&cp3G4UVWnUqpc=&T7wcz3Y_saUVW=&vzXKpqXlXnnjX=&mdUsOTV__qZnc=&846DkaW_n_Udb=&C4B_CxVgUYckZ=&_pb8FfWrUVj_r=&BCoxlcWjYZooo=&nGqwXcXrYZpp_=&z9KZFwZdnX_q_=&66ANeOZcYcsrc=&4bbGqsWpeccad=&HzZrmNUqpo_ij=&J4ApkRWUfs_rX=&nuNVF3UpXadi_=&uqUDG3Vcllbie=&GQF3pCYUpXjnl=&XlvkouUffppfZ=&T6VkGXYprhisY=&GgOO5iYjaWrkn=&LlSDvGW_ZmknZ=&lllGcSVqoapac=&uB8_k8YfYbslj=&HnmZqaVnjsdWq=&SoJNZJWkXemqo=&thOJS8VapbnZW=&pSSto6YWWjjnZ=&YB5COYVeiqe_l=&d9aezWVUlXmes=&SJRzaVUeaqmbc=&pbrSpOUgqZVhY=&UySYdaWhYfknb=&zkoyYHUpegWbl=&eUn6nJYgnsWeo=&AyrPAjVjlibpX=&z72Q3cWZWYsZr=&7YfyQjVVoWh_g=&b3_eqqUaXkinU=&awzxG2UXfahbq=&pT4wJHZ_cbqas=&kq7dUBVhqieXW=&H9rqKwUrcgnZc=&H_AAmlZcaWqqo=&mhT5s_WoUWVjp=&ntzqsgX_mqZkg=&SzXxA6WqgqmjW=&4ZXxYFZX_isWY=&tyRDq6Zmnmof_=&dJIPgPWhdepXj=&BhZe4cZqVjcpr=&IiWvGiXhnmbem=&2Omm7mVqmkgsr=&plsKRDXcdZdVs=&GzxPgwYhlgnUf=&gY9fmwVdaqZfm=&4Yz9lVYdkkcZj=&C3pRa4Zqoilmq=&8UtbUcXfcXnW_=&BIyJYxYeaZsps=&doiXuGXeaffZl=&A5rBY3UnqUVsr=&KW6OVZVYihY_k=&z8zfDMWnbl_kZ=&kJzLBOZjZfYid=&GLOzbXWnfdXif=&GSNDGMWnnXseU=&HjtuRlZfsU_fl=&eVkdrEW_gXsjg=&jaP_epZWffabi=&scvgLsUhkqdUl=&IllIn6Wabppcm=&sxtT9_YbY_aWj=&gG59jLVcgblWs=&2dKdoAWik_Wek=&sNVeprYVmp_gn=&aXDbnVUmVlckm=&4WTmRtVkfpVrs=&ayhcBZUicpYmZ=&sVI_7cYlgrZrU=&OgkpiTUjkokfV=&CrGAcrUafppZr=&IMCV6IWoqUjbX=&uboXJ_YhgdXle=&8SBnkpVsaeapV=&y_YuYjVamarmg=&TKu4sNVsbkkms=&xBz_vvVXdiUXs=&IQXlvWWdgraes=&uCIhA6WlmY_rp=&ewa2wYUV_sZXr=&ZpGfeEWccqsZp=&JQQbQRXZiXfXV=&RJ4wzKVhdgeka=&YSglyJVlfZspq=&Vg4n8kWlUklXo=&RV7XLNVYgYi_l=&R85fjCUYilcq_=&LioL_2WaZb_Wq=&rS8R7FZYqlpdr=&od7yasZcirpqV=&E22gUkZVnegom=&v7wvE9Vjrl_YV=&WTmCKBXcqegnj=&ATXLNSUsrrorg=&owC3WPVmmUrph=&wLmvxNWiXbhsU=&LeTGDEUWgXsfm=&T74EjfZZX_rWV=&jAZGMJWUhebk_=&8iBsYGZUodobm=&t97hZBYcjc_c_=&WbvTQoUeUjeno=&UOIXwlUdpUamX=&237EvDYisfqZc=&94j7oDUmp_bea=&66HKmgWiVZbhs=&a9VDcAUjaWssi=&hxSeE5ZrUWnog=&yp32d_Yabirck=&ngSJKLUdgjdUn=&FimgoaZelVjaU=&AsDbffVcfgheU=&FL3qxDXjaoahq=&iPR42bWnYVYYg=&oZWLK9ZUjodqU=&M8FEZyXYVYcmq=&l9ZRB8Yjqndnm=&MajprtWlqgnfY=&HHW8cyUhblefo=&CDAuc3Y_qiiqe=&SV79OtXedrika=&IkH5jqYclrrhV=&K_7tLmZlgcirc=&HZSSyWUsmdclh=&cGbjkmUhdr__i=&Uv67TOWcrkifY=&PHSztuXorigmn=&kR4XagWbcdndm=&9Fd6rLUalgoZe=&bFQBEHUnjsera=&pmwBSnVfraqjU=&oaDH3iUfip_YX=&h2WjecUZUYcfa=&U3dhlJUjcmhhY=&k7h9A9YXkmjek=<YgZCZgYXbfi=&dTl9ieZgYegmr=&UcP3DVUsmibUj=&gxk8UrUgZnsoW=&MzWTeRYbdsbel=&D5PaPbXbmZcgi=&pmCPOyZYgoYmi=&PrvPo4Wfgnpqr=&vTgKzYZdojkla=&PiKflGYWlXg_k=&HL_WiHZkcqiep=&CNlsmAUXmgWms=&IBG4oHWXYcqWj=&GMAUhZXce_VdY=&wBl_WxWZVklhm=&ley3aEYjpndok=&jfmXItVcsgmee=&UsUvfvZnmncXs=&i79xjbWifandb=&l_3kDdXXksWXn=&zGkOqbZqUeXjU=&HFSui7WsVmcld=&wpwxiqVWpsYqX=&n_8qixWqcjbVh=&Sx4VNzYcionXg=&c5QEWbYapsWlk=&zdLziZVWncnkV=&yTV3SGYrlYalW=&L_KYHIVeaUXnU=&WgZDnjXgaoaZf=&AkH75vUifgfhk=&NBlrBkYgsml_X=&WeyZDOZYWolml=&tZGsVvVircipW=&QZnZCVZaioYrh=&T5FwhsYUa_hXa=&I9vMXMXpk_Ziq=&Pq6VxXVYjkbif=&3jHqNmZUhYjd_=&WV7CVhV_aaoqb=&8H_lmWXkZacaY=&U3R_yTWsUphfU=&QuHKhrYdelgXn=&wmKbxkXYZaX_i=&zSiGFYVUqfXaa=&Q_Mj_nYehUd_h=&NS4u2BZXVpVcU=&QwPYqLZYkqcci=&fuv7UEYhsUmhf=&sjmjDaZrgVihq=&MwtH9MZ_dqmhY=&aFc3bkYgbjsd_=&hC8ne4XqWln_Y=&HTf3NNWWWUfdo=&hTGdtWVWjjkWs=&uXjHQlUdieriX=&xCV8x5WlicmrX=&xggJoiWggVpYn=&aPURXRUjqeYcs=&Lr2ciwYiigsnh=&7R2NyrVaqlkgl=&M_sjOwUogprjf=&YxAWg6YdrWUoh=&84pBrgUnjqflc=&8LTIwlZchrXbU=&dGbAh9UmWcrsr=&95nJ9nYajVhgZ=&UueiCLWjkchis=&jyaKbdUiUUgWY=&WMC6srUfmaspd=&n69hJeWbqVdbZ=&IkN_q_WrV_doj=&N2pvmzVbrajce=&nf2swDYiqndYb=&jCREsYXsfdiVr=&LrHERpYhhsWUs=&QKERHZWfc_ldV=&lOs_QYVaZUjiV=&xPFBiIWd_qWrh=&sGLP9kWponbnh=&rmUZFfUejnsd_=&q68Va6Zps_fYg=&EK37fPXUropUm=&95OJkEWsriibW=&ccKymNXkrZsrc=&RLvbZNVZm__do=&Hhq5rZXpVjcra=&PavFclXqfoiZW=&HwEEqkVkUo_Zm=&xpmqVaVaVVghm=&Ms4wTEUspnXme=&HWpSTbVqYfpoa=&KKA_q5Vd_qmiX=&xtn52UWjpilgg=&8vk3UsVharrgV=&rr43N4YrofWjb=&VNf4MwWilnYUZ=&8FI6ueYVlokYs=&ZP3Tr7WWmsaVq=&sDguHAZUWaYZX=&hr7VtrYsodsmj=&xXNN5VYprrrss=&HvzmGhYdgkeio=&Pb2LeKYVfoUnk=&KFUC7uZiZmXcn=&RJrHxyWsmifXs=&SeJ8qlXfggk_W=&z4WxBOVXddWr_=&ffUdxkYjoYdgZ=&8UhZIkZXVUVhZ=&h44hJIWVqhWnf=&Csj8sEV_noqkn=&xnYUKFUXlckUk=&H5O_5xUpnpies=&BztxXyXYalrWh=&7y3_FAXfiqpZc=&nXqSORXkVZq_n=&AUid93WgZoenq=&hHD3jEZkgpUoX=&H__JnVWYW_mef=&PNiobPXiqcZnc=&defqMxZn_brqg=&httjKAUZjUsp_=&8do8PaYkqYXVX=&kZRwpiXfVWbXl=&lCYo2kZfqbfqh=&DP6f_TVZilZme=&YWklNKWU_Zqge=&HUxyQEZVnUrYf=&cGCgsGXqaVUgV=&YVAPqdZjepbUg=&oFxBHOXomffZf=&tvffmkUXaVmch=&YyMVzsUgXqssg=&qVVclnVdckpVj=&dPbGEPZ_adrlX=&rdauVgYinc_ri=&Hj7xCwYmqgjVg=&yPYgolWi_dlbi=&g7m4IlUeshbVm=&YnNq45Xpncahg=&X8WwpeUnonVfW=&KqiIKmUpWalsn=&8BFz8VZrhicUa=&niwHqWWh_nlWW=&uXcAK8WWi_pVd=&hevzXOYXXqgnq=&jmA34dXYalbgp=&TOdWsGWsnYdlk=&pK6WIYWWVmZmp=&P8_oxbZlihXWl=&zcE3rrUhVjWqr=&UL_wXuZbZgihZ=&UxWY83VqWdWfq=&WmFpTMZUWsXas=&884tL6ZcXsroe=&WeLqjqW_Wnees=&sd2LRRVglcXnc=&4WkJJPXUUbhos=&aZ7ot8YhZicis=&dTRfWpVbdYVik=&8q_pukYjcWjj_=&4SxzsXVodcWgh=&FrExVcWnimiqi=&UxTzaTWcmgcsl=&RbM_8TWidqisa=&zFvRP8ZelZpl_=&FNOIJvYfUbmnc=&NH2phHWr_cWrl=&YhTdRqZjqjepl=&n3QvptZkbngca=&EhS2ztXdbmdmV=&fhyBeqYmZrWag=&6ygNOBYsbVdpq=&OfjvMGWecXp_i=&H6MOb8WaXWsWm=&hEVmNRVrVpaZa=&JLsLZoZVrfcXo=&tWyvw9ZcrsgZY=&sZNCUPYpakXke=&HfBlQ9ZpbbbUs=&NQWXzEWcqmchV=&UOl87OZarmUjo=&c3ypBdYrsqphr=&FCUTaxUklgpkY=&kieITXVZ_ihpV=&mUSYuqYch_nkb=&U9zfqXWaoosrZ=&zFeopIYdYaepg=&jawMsSZncimsg=&U9J22mUUemVre=&KTeoDUYaedscU=&gJfcxhUmqgdeY=&r9TN_SYehYkjk=&6umOODY_Xqpdc=&dYlAsYWZYdrY_=&Z7iX8WWkqahbc=&7FGbHaXVoWoYm=&sijHzCVjZorjX=&tyFASCUjXimad=&Fb8DZ9YjsdqhZ=&z2GSa5WaomVhl=&mZRrKsUVqbose=&sCfIQdVVgq_Xc=&yCgqtOUgrZqfX=&XL8vTIZdYjoWd=&Q4q2v5WgjYpVb=&Ttb3qFWoVYgVj=&biV4UaUlra_fX=&yh7IZOUlssiZX=&fIhvMkWeYfbUW=&L_YjqYXbqalUi=&WGzWEXYpnhafp=&jeUaKAVZejpUe=&tv9zi3Ukgkjkb=&J6JLmMVipirln=&oouTpdWYslsmb=&JckQ5WVrjlclb=&4QAZrnXUUjagd=&9TVax4UZjqhZZ=&qz9wZNWUsWXcb=&k4ZgcpZjqbiqf=&BPLLr4UddpWsa=&gGw_ZfVmpZbVc=&AIiU4oXijnlZl=&d2UWAVUopehrX=&feEVmtVorilZo=&9DBVIDVncbkXX=&VX2VIvXlUVXXb=&55eJHtXheg_jh=&hnFCQgVbUbrnh=&A_Td72UVmnXcp=&miZw9NWmeWnln=&JpaPGNYpkXUqV=&toN289XohhnrU=&jFa7cSZZehVfo=&Q7D6CuVmihrmU=&fGyy4cWjcYhlW=&wR7_PkUgYlYbf=&bqjpXzZffUihk=&SBzhNgVmYosmW=&KgGqRbWa_agWl=&xWKFKSY_hkalp=&GDu98NUhlYmmq=&XmWYNSUsagaUn=&TSyoFIXWWWVfa=&gUx6ARUb_mngk=&KRv9GCUom_blV=&v74aniZdflggs=&doEtWYYqrhUsb=&KW9C9tUqbZcqm=&OYUsPMXrkoUrZ=&kVVOm3VjUZdkd=&PprvF7ZkjfojW=&jnJkxtU_iZian=&GGf254Xeslq_Y=&vmtVIMWmmcWmY=&dWW2n6ZdVWl_n=&E_FDUxZkhiold=&DHtYV2YVomfZn=&gSCyGbU_qZair=&XDLfP7XVibVck=&VGlAATYqrcblf=&Q5RBHsXiUbjkX=&hSo7GWYnWjVjY=&toS5yHVbXUjkp=&nCcqyjYXbYhZV=&A_AYaEWejWcbn=&ASsYdoYrhobfa=&loor6JVZqYncU=&RGkBOLWckoodh=&RdgUYpWXaeaYn=&wlcbcqWZVbhjm=&zzJiDVYo_XbZr=&RkKu5aYamXWbg=&YCJto4Xobr__Z=&5zP_AdVqirhhU=&BdH_kHXWeVZkq=&QvvX2WYjmeghp=&PUPKUCVZsbgaU=&iPKAO4ZafWlpX=&TucpBqWgmpUla=&KUf_QuZWob_Wi=&WrnEC6YUfh_XV=&IJE5A4UmUofbl=&LXRt6aVndinfh=&XwPvCjVhlVjsk=&KGeXjFVgUb_fj=&CFY6B5Vbogigo=&ReYGVqZss__c_=&tTVZngYWmg_gW=&uA2hBHUgpYl_p=&PW4F9KZpUneUd=&Z8pmeDZZqnYnf=&Fq3IwvUeghahr=&NWT9hsWUkbgde=&AUc4XgXksqgaY=&SdJBpVXej_XeX=&Rn8ZetZcVsYeY=&72Po3WXrXZana=&e_wdt4YkXZdVg=&ds9IPfX_fcpfi=&SytYU3WkingXm=&EvW4QTXokacpe=&oBI3l6YZbWqjp=&GED22rZfXrkXY=&vVKvT7ZdcsWjU=&xqDVoyXYcclae=&rGUJtxWm_fnlc=&AAr8MVUd__klY=&3cFDFQVjWdcar=&buMsDGVdnojkf=&o2BgLXWfidlYe=&sJaPg2Xmagqj_=&o3FyAJZWdcZgc=&mSGvUWVnXkYfi=&zPBUUOYnebmXZ=&XTrnT5Yacdkpa=&8wj5AOZihUmVW=&ivqNfzXgb_pZn=&XQNAVCZUsdrZg=&TPFKCXVpdWgYo=&WeilgBUrXijU_=&_U6oBrYjrjmbW=&ZTibgIWrnUUrn=&Nx2TyyUlafsXg=&Kmd2IFZeVffqm=&HF7pCVUcprmjq=&jeDMLnVndlWpY=&dzK_2nZesYUkg=&_RJJkSWljUoag=&ztWg36VlXbaio=&LNGTpPYbgnpXa=&KGUPd3WZkUsoi=&PSy4S9XUhrdWX=&HrKqO4ZUfYfkb=&NbRonGUdXgXgq=&ALKhZoYkgYner=&3zir_8ZZbZhUh=&iwV2eQVjjpYXi=&blIkLXYplWfdr=&cVKIYWY_nesbU=&GWETW7Ubnfesl=&pnR7EWXiXcX_r=&7nAVUJUoYsfqZ=&PWT7eZVimdUYg=&gkPEtEZabsjgY=&ExLdZNWjXkcYU=&wF3Kj6ViYhmac=&oHDePNVkbdgoq=&uYyF5KYZqonpb=&EH8tECYmWrXdr=&iDtMR5UZfadiV=&MvY5GxVshUUlq=&9aIPPzZlqmknd=&kQD9vaUaYlZhm=&epbtb2XXoZahY=&6znRJUVbf_ohk=&j9shs4WhqssYX=&MtDr5uZakrarn=&IUBIqHWmWblrk=&OozRdBUVXnoia=&7fbadYYggpjeo=&z9Dsg9Vqqpial=&neWHayXgiicgm=&XeNthpUbVhhZf=&VDEaGWWkjVhiU=&pgQnmCYpkXdfj=&Pduuf9Vsbjkrm=&f7YWTdZgXnfWm=&6ZJOqDVmfVnkZ=&fpXOfIUqXpnjn=&5ImK3sUeefaYU=&RxXktMUhfdmaq=&i8e7QNWidsZVU=&Jx6W5cUUhidXl=&eHsvmGZgrhVip=&VxtnOiVfcofY_=&3QwnTJZVbhojb=&bQPeYWVkVscnY=&qQlaZIYpnXcnj=&yEqSlAZllqWXU=&QrN7AsXohZqcq=&7FeWL3YscdXZ_=&rbClfaZrehbcj=&DgN38HXcjkij_=&YKeakHUpgbqcm=&wo8MfgXdohojh=&BZShTsXsfbZhk=&9B3KATXolgcXU=&azHmPtWdfechm=&7mObzPXhVlqlZ=&Akr3abUllkcpi=&gw8amaX_ZekhV=&myEFTaXdW_mVq=&bhHFJNZsdkoUh=&azxxiCWcUrZjf=&LEQHE9ZXserZV=&gyHwF6Vlj_jco=&SZkvFmZodaodZ=&7ftR4WVsV_nXZ=&6za85_XksjWfX=&VtgRysViVllYs=&aBiLFJVgjrWrV=&amOljnUnVckWY=&sSo_vNYosiins=&qyCSROZpYZpXn=&pUJiTwXlVZjap=&8Zz8k7VaWjhso=&BhoP6EZYWslqp=&PeD2BoXhirdYX=&56Gx_yYceebVd=&OzJC8LVhWViWq=&IHi4xWZjsmphe=&DK54DSXenUcii=&rRwen4XlUrbfc=&Ui95PRUnUZedi=&lk3C4WYnaaqqa=&FVCsyYUkWmdkm=&IgMAqkZZUqbVV=&uet7CPWodedp_=&2qGPekVfYooon=&ZLVIr5WbgijrW=&PC5EvMZVraleX=&BruTjVWXlVblj=&8tXHVXXmjnjYp=&UgjDVJUpm_kUq=&KpCtBXUVsfgdW=&Uk6A_3VancXja=&3GAVqmXZYfgZa=&IMK5foZoedqsg=&bnz7y_ZieWkVU=&mcVNYXWsccaln=&BF8Sl6YrUednV=&sjulqgUnlalrr=&DxyMr4YaicmWp=&foog9FZpmgeqd=&bdtpDAWXhqUis=&jRn5UvYicihZr=&ECRCdLUnWkVbj=&GvdgIIXphdVYc=&xuWLCRVgeZlod=&PXw4ZvYUfs_lq=&2Yl_KsUXYooY_=&CCuGkhWYZ_poo=&_PvqeMXfYqXjf=&tQGuugYWXsZVl=&saASMTUd_Ziac=&vAlNqWYidgqcr=&m2O_WQYefak_d=&FMtgVnZapgmol=&J5E8l5X_VZfci=&Cbndt8Zipmlpc=&j3ZUF8YVfiinU=&EefGyWZZeVjjj=&CutvVoYmpqkdU=&D_5QWCYfqckdU=&vEuE7bVflXYah=&MOBxWxXinoloh=&bMCQUvYYhZgXW=&WHL6DpZZVaeZa=&ayybEcXrWhbWY=&xXjRLgX_leekc=&avPYuNZXrpVja=&nEawxfWWafmfs=&wQRgz4XprjXmh=&5sS7bwVUhXmYl=&ncRzRDUrXjari=&eAG6NiUqfghaV=&AlXrXyUVoqnbW=&6BgVWJZi_eWrX=&6eUs54Wflmaqf=&Ur_INAXjsmbnl=&2GsXbPZWmkX_d=&Fbzxx7Vr_iame=&MvPdlJYsomibf=&5lzji9ZjaYrdk=&GEq78BZnqXfif=&oxugM9XjlUrmW=&6GoZP5ZbiUsrn=&yZ4hjvXYmeflZ=&NSsqLaWojnpUs=&hKmKkkVjVUmWX=&2aMsxYZpVXkli=&jcfbhpWpZbmkV=&KIMGs_UbfsVeg=&IKbkqGVWhXskd=&iLoS8aUpdgiji=&grzHsxWarlXUY=&ICvmcSUmapZnV=&C6hKE_VYbkceX=&ded_r3Uejc_XY=&z8FBRHZ_Vjapr=&HDXiPQZeoigrX=&Ihq9kIYoh_pea=&5hBAItWnbqZ_b=&iaKVBEUridklY=&raymu_UXahYg_=&WztOOKUarh_lc=&7MteVsYkXlsqb=&suIk_4WbrViYr=&PbbybZXVajemj=&BvpDHKXYaoqdg=&K4wRnXWgUpVmj=&lZiyH2UUXkUnn=&r96yWAVagarop=&AyvkhaVflgsUm=&OTrAtjZmbqZco=&B8FK7WVYgleme=&9Bj3ZZXohm_gp=&oJl38WYmmgcms=&6ezD_MVpmiVjk=&JgSvJnWYWsoer=&CbDHMpUpcgicY=&QLulc2VlnXkVf=&PefxBPXikojhb=&e3cYnlUodbXso=&4YkmTSZfomrld=&5ZJUzfWlYWefj=&wVVlTMWV_ksVV=&GcmXy8WipUWjj=&ZJwYxgVhnnned=&5nGtQcUbqsVYd=&rCF3X7YiUlekd=&ZsRhUMUiWeqeW=&igZetgZqjmdXd=&Fb5q9AXXdbhcs=&b49s98Vk_hirl=&DyVdgGYghnrml=&o8uYJ6Yoamr_b=&vYSQ9lYUlkVYl=&aWcj4jUUaYfkj=&uXkqf2XkkbeeY=&jUeN89XosZlrs=&YoWDOdXkqZeaj=&8XTfwVYriWYXq=&6_2MzYVkU_nWe=&idrUNHZolVlgl=&QR95QTZmXiUnW=&qgFeooZWrmVVg=&UrJciGUcim_de=&5WkylNYhnUqUf=&pvK5GvXiaVrjW=&7ASeevXUciqf_=&8X9UnIWXiY_sV=&AZPqq9XYjmskX=&DOLmbbVoYVdWo=&VNIQV4XdVVfsq=&IxWPtdWf_lqhe=&JJBqJFZn_ZnpV=&3HEwNtZsknhid=&9uopLIUlYbrUW=&wTfwAWXUrb_Ua=&7xWtTFXYsrjVV=&Fq9vNuYUlhcpn=&Cs9XpoYefWiso=&uaswPeUnbXjlp=&94R9C9Umcjggq=&jKupYGWjdbXli=&Vlh2mgVkZZnni=&e7d5BnWarXXno=&Edi8hBZUbgkaX=&hnzxfRYVUVbdj=&Dwgie4VWVqnYe=&ld38tTYYVXsoU=&tZ8k6yUXWfpUm=&9eEyNkWdsoiVm=&fgrlQXXfnehqj=&TZifZ9VWsXcsr=&qQbaWOUhhm_Zd=&4GNAsMYsXjYr_=&F33LmHWl_eVcc=&_ySaAyUg_kUVY=&4npv6vZmilmbe=&4x57YWXWkcaXl=&OTuhKBZorfnrV=&eTFQoZVsgUgWZ=&5pqaatWlgrkXe=&dcINXiVZeZead=&4Ci7u8VjbWYak=&5wW66PYsXUZqc=&iPQvfkWUUcZgd=&nheHbsVmWYr_n=&wKW6jaYWd_lrc=&UiNjDlXlhr_Yj=&J54U2xVconpqY=&_RFS5kYWpbfga=&GW54lDWabcVlb=&_4GxT5XrdfhYn=&vl85ImYpgrhdo=&IQRd3WWYnVmXm=&ifWUrBWXrXXWk=&WD8bcTVZUiasl=&3wNlc2XbUWhkZ=&7GdNlcZgnX_eh=&vfeXf4YhUUiYj=&Bi5ETUVpsnqdZ=&QAy2czWarcmYa=&OkTwVqYhnfsmU=&MPfJEEXppWsUb=&6TVtVwVUVc_rV=&48QO79Zsrqbnb=&QxNQgrUsgiklp=&ke_zE7UnolaUk=&WQyfRpXbksiks=&T7vVdcUkhfZ_U=&svHabqUeeZZUe=&IrbgkZXWYZies=&BvoSs9Vefacba=&u8q4POWVsicsd=&9RBXnDWsjdlXa=&VOBtXyZnpUdWr=&svI38jWoascpp=&W6yz3xZeqsoro=&rIhQjMYrnUfbY=&7JmGORZoZobVh=&aERo8sX_jYf_e=&atGzLKYUYVcXm=&K9oUsbVVrmsrW=&VCBZkwUpgoXYo=&yEaT2TWVmglck=&TV9vREXjVfndd=&tTrEuBWjnjfsV=&MRh3ZWZYejVmb=&6lKvmwXZXhkeq=&8kokCIVmeqVie=&G9OafUYalY_ad=&H8IS_MUlqcbgp=&oQHm9UWqorVUY=&oc_hM9VYgbjmd=&loDKEsUjsbmcl=&si9UJkYphghgb=&6M9dy_UWsbmlr=&yC4lUMVfobhbq=&UfLJofUcfprdj=&yLCrZaWpXfggj=&a_VoigU_srVln=&y3kqgDV_Ujsqs=&2EWBcNXUcXeaq=&HIueJOVXnXfsi=&P9GDzGYgdjWbl=&Hv3n_EWlsj_cY=&rrFxU8UZbgcoe=&QWHlHzXV_eljX=&ZylD8oUpflrZq=&7vY52dUppmirh=&U7ALeOZbffbYp=&spwmQVVcnsbnp=&DkfvOiYmrbfoX=&_Kyq9uVpmqqls=&ZMWYBVZUWfZXk=&ns6vzOUplkigl=&Ttvws2YrdUql_=&UA_PyzWepVjmo=&zMk4TfYkfoafh=&CNVID2XemYWgo=&QTeGcIVrlWcXa=&_7AmiKXUclkni=&pezJ7jYsZljWk=&WIevnPUajWb_U=&9RBYcfZskahbV=&eKbcc5Zkdknro=&WhIHarZYql_Xn=&cxY4EiZWqspb_=&RhUiBvWnqnYna=&iOsToTZsUgedp=&ekxpn8WWpjgsh=&kTaMnLZmXXZag=&3wFW5ZXqagVda=&7yl3b4XViXZem=&vQI_zfVehcUdp=&HyPxWYWokorfe=&JRxlSSYVkWkpd=&eq5TAKVanbkeh=&L85AuvYZbZYbU=&AAJUiQWbpcWaU=&JzDZAEZh_jVah=&RFCT9jZmkmXWd=&Og3UHcWbpclgh=&olgTiCUghm_i_=&ar6GzpXmpnnh_=&suUhdHVnkahib=&4lZIKCWesjagd=&dMq9ILZdZeUkY=&JlnENTWmljVbY=&aLdNCPVgsh_or=&9_qBYCWZrmssY=&32BmUHYmUkoWi=&JZVAcGUVYehki=&LM3FJaZWaeqUj=&HyNU9sYkkrimi=&kIzTGvYXa_aXU=&__UpYMVoZVZei=&h_52ikVggkrXk=&sgOzt7Xgfffch=&zJxm5ZYejbVeW=&gRH2nUXWVsgdo=&cqPSzCXWsWbbW=&5Zu6_FXj_fkWl=&693eZIZUjceVc=&kKBetbUqfWqdk=&682Ol8Zabe_Ue=&KI8JMGUq_Zmbp=&qqW3C3VsXoZnn=&S3K8hrWXbed_p=&BfRGQaWmbpnng=&taOCbDXUpWYhp=&WmmaS2ZmsihVZ=&rWY29xYWZfX_h=&Cw66jsYYjXZYd=&wBdtsSYYjegen=&jupTs5ZiVkVUn=&wGVKY8Ym_Woje=&RXj8zLZqWfgXW=&7MmdJPUkm_Vqp=&7pDbmhYWlrUVq=&OL3A_oVUmnXmj=&4dw9rsZ_corZf=&49AwplXWkmVVr=&tUdIORVmfYsqk=&snexCHZcXinUn=&pDk5CpVqlUjba=&gc3Jc4Zmcmm_m=&d2g5rPVUdZqph=&rESLSZZjcmXVe=&QDUCAiXc_WWjY=&oiR295VkVqgZs=&gYGDnlWa_hpkU=&cyt_9OXnV_ds_=&YZUbHhVmgrYVg=&HpDpxkZXnkUel=&9nQ8XzWUiZVUf=&HjkfQ5WplYbed=&oMiHq4XofdYUk=&8DY_lPZnaYoVc=&YDCVZvYWqYfXl=&ae2SLgViphmkc=&X27ZpPUlnsfUb=&sjFeOnUZmb_gq=&PSCQTjY_adpe_=&R7aPtIZsghjl_=&L8nfQHYbrcffo=&GEgBiIVcoXkYW=&qZDWLQVsggp_g=&rFkn5nUUabdjq=&O3j5T8ZaYngac=&DqkTHwXd_Yabf=&WaeYKEXkhpgio=&GVDzGRXhsgjsW=&eIiQOoVqddgmg=&KzsJnCYakldhb=&JyCnlWW_XUdaa=&KDQsQlVihcq_l=&CXVRLhVbhmWde=&Rz_mUdXbmbmYj=&zdOCW8Upockol=&jT6FLRU_limXl=&w969qRXhXVkbe=&DVkf9WUYbkk_f=&eQ5c6IZbajhUe=&HoRPf9UramVrW=&P8VtQQUjUeYXd=&MjD58lWh__oig=&uIIT9NVmibXY_=&dRaGa5VldoZjs=&moP5rRWjf_Woe=&wP5Z3xXWcaaib=&om_yBgWUrYhk_=&rjcMF3UlnnUZe=&Wz6wefV_nqe_e=&g5ohp2VhfXYZh=&Wijt3EXijVqeY=&fBJYYdXgdkhpn=&HWw9X_UZXZWmo=&hJRKMOXrharZr=&po5sqjZebdhWl=&hru3UpUicpsoZ=&ylu5dWUXsofmf=&YbzckTWbYipVV=&ptrO7cVbosbXm=&eV8ThwYbemlZU=&IWRquIVe_ebsa=&FxonbiUiXZ_pY=&csus_UYYiXVcZ=&JcPGo9VXoXdje=&K4UoV8WeVaoaj=&JXu2d8YYocaeq=&j9NxvvV_ofgs_=&Le9y2EWXVcfsa=&c_NotpYWUbZmq=&fqs3uQZsonhqb=&83F9mFWbgscsh=&bGf6ocUcgVY_f=&QFehMTWsWYdWj=&Akho93Yhlagln=&RBCqOiVdaVmqY=&Xl7bBpWXmnprk=&u_Sp3YUprWV_p=&nnl4hRZabcmdk=&UHhHwoVhdqmpg=&Tre7M9Zofoqfi=&XVVx2NZdrkcYo=&LMLXFEYpidsUZ=&LQShPDUmoVVUf=&KrjV9hWsiXoUm=&_laUvNWmWsWiW=&yVpBMZVbYdmgg=&vWQ4l6Z_akamc=&ndDzFGUZpsUke=&ZvqQ8OYfooZmm=&pxdQdkZ_hriZV=&dCzTAPWYqWgrU=&xSkNkCXejVlUr=&lx33IQUjm__qg=&3gHQsNXrUWmgh=&62rSdKZjsVljo=&VTHf3aUbrraeU=&mU99jcXWVpcVg=&WtLXVDXeapVh_=&aZeTbjZ_YgsoY=&F2QrZAXfWi_hW=&7FK_5AUliWoml=&p54H3NXkfofbf=&8gdncaXiUhmmU=&JQLZhTZZWrkXc=&bAlYx8XUmmYak=&4dParIXZocong=&ceZub5VfYYXce=&XKsTllZlinfed=&NFrYqcVWjpkls=&DK4RH6UifkX_m=&mH8XbVYdr_goi=&maMdtdVsgpajd=&tTaDbgVphjW_f=&FkzSwoVbYpesa=&mydIsIWrnfeZi=&AnkSH4Xh__gae=&CxrtjBXYhgjsr=&D68t2wVledsfU=&v4ZwmHUd_krZs=&TkV4ItVodoef_=&HTeDBRZaUskp_=&dlceEeWfgqVho=&zrRElIZWhkdki=&oKbvzdVicoqWY=&ZzPuHNXplcnci=&VU_j5PWr_coZi=&FPDEZXUUZrqgq=&PjWnoxWnXobkk=&UwLJx9XWWgmnk=&nxt9EMX_jfcgX=&4qyhmFYY_gdps=&2GVmdpXfbpXbX=&DCt5cfXboplso=&lAnbqVWXikadn=&CftFbyVYprrmf=&WsCAfKYVZeXpY=&XOzWJSYjrqjjg=&_sx9B2ZkgnZqn=&AltnuWWhknUkk=&oSEZCzWs_msXY=&7YbY2jZU_hjns=&pJf38wWklUblg=&ebN_VEYkkZpgo=&bHkf2AW_ZckhX=&sgodniVdkahe_=&8aOVlbWWj_Xmj=&UsK8cVYaWYiUn=&FyYBbfUdeokoW=&jPIEfiXahsedr=&kshSc8Ygmglsq=&vlIIPqVlYgcWi=&Ez4KKPZklZd_e=&3QM64pUX_UXmk=&pa5xSSWbVicjs=&XesXr2XYqp_fs=&EtLk5vUqpoeqp=&qQ2WzRUdaZXZa=&MpOxZcYmdeacf=&cricboYXWiWU_=&4DHOJMYnWZob_=&wBLlvbXUrs_aq=&l_tG3eXVrXYol=&iXXBH6WqgWqVp=&XyY8pZXWeUsrr=&2_ISihXfeUleg=&jznsjTVXkr_be=&Kt2XluVsUWron=&Upk94cVnfhXVj=&YgjIdDYqVheco=&XKNsA7Wgrs_ga=&rC6fHkXjoWesf=&PMnLCDZ_fXfkr=&KeS_m_Vgossqe=&_qvzzTZfkYdXX=&Vo9yOCYUmenr_=&zLG5iwYdepUV_=&lNDeUCWgnWbdf=&G9pk7pWYXbjeg=&TVAaVmWpmqmnq=&nUhpuzZjoVecc=&vMAQWCYcdkpdr=&PRFx7KViXV_bV=&WFkuEFWYcXqUo=&YjXecXZdgbmlq=&zMbul2Voqeibl=&DrIcFYW_lapkm=&eYHOGUUsZbfhk=&SOy25fYjr_slW=&EV4efOVWjfWep=&dYD3iYYZdoplV=&zNUVxVYfXXWor=&Pdc2LVZ_gjeak=&73mKf6Ugbopob=&8VYY3GZWlhkic=&brpXXSVkiieXU=&ZJv4B6VophXYn=&TzR2sTYUXhcnX=&wnJVV3ZYosodr=&u6iwG7ZgckZfZ=&tTOwmTWfojcjZ=&dV2GJwUflqobW=&6J6Jk7YolWngh=&4qaAdYWfpheiW=&lWVOXcU_dldmd=&_kVMLJWngdjgl=&nHBQPdWr_grnV=&otRc2LYlsUWfn=&qI6FZjUZUgfcf=&4ty4dzWakanqn=&4ob9v3XWrbdqe=&LDEhslUreYkXl=&gwqoYjUeYikdr=&HdJzVwZoceYdi=&luil5fWakqlpk=&_O99cWXmZlqVj=&DpuP4UUhqpscd=&W3iCrpXmhodms=&NB2t_eWUfkdla=&RJSPpXZUnkims=&EzHL3bUrYidhs=&YoUYtCYYkshad=&Nx4p_TViqoaZ_=&ZJ6ibwZbmdciW=&aHKg5TXUbpchl=&zdl_WGWdUVYpl=&2t9LXFXfVXoec=&sDIBlGYZgjkVn=&uM7sZdUcmXWic=&5snQCjYcrZmpW=&FO3eo8UsmpZ_d=&u2jClFXosaWph=&B6mkuJWYmkdpm=&AL73aAXob_mqY=&8XW25kWqgeUiW=&f4J9ePYZnrscW=&AFVvXQXenWZk_=&vewnneYoi_hje=&EPfZIVXlceZUW=&6hZuwwVUphWdk=&JPAKsfZdWkZXY=&TuN6ONXkmggoW=&qhtN_dYfsrspY=&XhaM4XYqgpeqg=&45KBkTZfmff_Y=&vgA2EmUdooUWU=&FOntBGWiodpjo=&jACYQgWgXUUVk=&ioLMzrUbddpVl=&aRZx56Wiankqo=&46wxM_Yarjhip=&ejoycLVlhmkac=&EbIYNVUmWonbs=&QlDlzQUUaafbp=&kQqJOkZpbWaWV=&KYMMGlUbpXbVV=&zwOAsCYWbhVkr=&xvw_YGV_rYoXg=&KkH4QtV_ippdm=&phlC7RWamschY=&tULPsxVnrcmZZ=&zr48KwVjiqbea=&HEKhTAXqUUUfk=&xyKHwjZfhhrrW=&6g5FlMYro_nVn=&e5uVCRYikiXgW=&JuTODMWdrYi_s=&YRX5x_XZpnobj=&b93hnYZ_lqioa=&5G4aJMWWZUmak=&WsOOfAWjUgklW=&cYyWdHVsgnoZa=&gJWD3MVpgrbfm=&VlIxkEWh_YdZZ=&jEcjdeVpWihjk=&d2qkHzUkUsXrb=&4k4Di6VgaXcpc=&uQ_xkpVXWmoif=&hJVUhAYmmhjpi=&YHqz_rVipeggm=&8sZBysUkdZkg_=&o3ODd3WZojWcl=&9e3OyMVhcbfkl=&RXktH4UaZhspl=&ZbJapgXncW__Z=&SrlJYOZYcVm_q=&KuwfepYj_gYge=&afSAM9Voohgei=&hlrxWHValW_bn=&UvLXoyWiWXk_X=&V9RhSQZdpUbqo=&OjKsgGZsgd__s=&WRhKE2UXZUjib=&u2aVTUXcfc_Uk=&r9Ewi9VbaneaX=&ZuReeeYdjWdnj=&w6y9UGWibghqk=&i83o6VWniedVj=&Vi_Vb_YfeZok_=&Y_NkrrVfXUfim=&_tZJByWlchnfh=&CYHw54Weisjco=&YHdJDuUhhjhZg=&uFKyRIWhWlnrZ=&ipzBoAZXdWY_r=&5jN5kgWmiqshe=&UHiXefWkiVVgo=&NpugX6WphagXo=&QsYwVaWXpsssi=&YlVUJDUdcWpoh=&dPadC2VibVaa_=&xBFPB_Zshghhc=&cYV5SbWcWcrnr=&BFMy8AUrjhWWn=&D7hrnzVkfUbhm=&GdRZD8YqVVXUh=&2i8prgYWfncqr=&mGgPGdZpilqqs=&hh3jiTZanVlpo=&xqBI7DZgkUniY=&U9qpV7ZprWXrs=&kL8FVPZsgccsh=&9N77GeXsbjZsi=&fFARH8ZsiYgli=&XzVanRXVnYfdr=&gZjq6qWlpelUb=&PW3eb8Zjgncb_=&JR6XaoYVqVaeX=&Nwk69QYhqqiXd=&ZGKmajZUnfrfY=&yX_nnFZdjeYVb=&3xqaP4UVagrW_=&yOhjHuYdYhVhk=&F5D4wAWlmr_qo=&XsHfqsUaninbp=&IFKgDYVgWUfXi=&EJZJHIZXlkVZq=&Y6IMnkVZn_Woe=&ib8fSTUWirmss=&wN3ip5Vrgbkld=&8YGFuJZandob_=&96opB_YaodXlf=&cuHaufWbsjkjW=&AcUM7PUaiiUae=&_B5kY2WolXisZ=&Oz7TigYUVfgej=&cLjjx9Y_l_piV=&bV6ez5UVacXor=&TiNb23Y_iighk=&wJnUVkWYUhcid=&MavadpXWmgieZ=&bCLrg7WloiVak=&tab3Q6VmcjpnY=&pSCp67WlefVmX=&gsrNciXhgWied=&bmhkAcYYn_sfn=&fdIztiUjsZnVb=&z_RixeYhgXYYc=&TuyrHuXfdUaXW=&iWIu2DXhosUZ_=&2JXUxzXgeqjmo=&jhU4GBUUmom_f=&zoCjA5WmjklWl=&EeLISjWn_VXrV=&dl7ICOYcqnmoi=&eDhqAjXedeeoc=&pHlOevXiredlr=&tfMyQpUdYkXjj=&9BDBSyZYVcUrp=&6tsIR2Xds_YkX=&EcJeZ6UhrVeqr=&PwxPJBYioYacm=&igojPtXrZZpcd=&7Zv9NZUpkWshh=&XWOCsbYnYorUj=&4sAqQkYlWphip=&jQYWTQVk_sjWr=&siNhrQZWchnYV=&329ohkZ_rigdk=&uW5bbYUWVZijg=&4AqyoJYgXsZrk=&LY2nbXYXomjfr=&rIgxl7ZhVYkYl=&L6D6_4ZpmkgYq=&76rLiFYfWqsqU=&jOG3HUWkjhlXV=&nobvy9VWWmopg=&7VlnloXYcZXXV=&OqIGOYXkrXpYf=&9frA_PYZm__hc=&JgIwVIVlrefXs=&T5bEuHUo_ihdq=&EudH7xXVphrWj=&4KKVwhViUcskf=&rjLzvSXqdbbpb=&aopFTFUkZaqVr=&VFxOvoZXnopen=&hYqzjGYehXUme=&l3nAdfVomsplq=&mTWKWtUjkbfph=&OaFJkgZslZjhq=&4d7DvjUmlcWgj=&caXoIMU_eonXq=&boxnYQZUXfpYg=&jeWVWlUomUonj=&2REUoyZinrYXf=&MoErEAWeXYjgq=&Y5CINKZ_XVZjl=&TyATXlUrqWWUg=&TMxXgPVpeolUi=&HnDwtAXomiimW=&3v6b7fXUXprmh=&ODnVZFXVhgres=&monCLLUqnqYVm=&JtuvjbWriZWcU=&g5WrmSZ_Upfgj=&XEQo4wVjkfnXa=&WOBP5LZgjenXi=&7bpV8yYceboae=&hek8OtWVhWWrr=&YuDzIOUeeUbfV=&EkoirrVd_faZh=&oKbf2DVbbfqal=&v9WCirWolZpks=&Bp4RoaYXpUhrf=&BMpbxvUUnoabW=&uKdawUWZsdYag=&D3GlCoXjgUl_m=&Rvav4CWnggUqU=&2QsyH8ZXllhUZ=&BdXm5kZViebol=&vh5nqhVipZUko=&vjvurqWldVnlq=&U2wKsSUbbVagr=&5qt9NLUsYlYYj=&QkO_hCZerZ_Zm=&DvlzVHX_npVrq=&kpzsJmYpeUreU=&lwAvKgYpqlqlc=&ux4ThzUcffplY=&tJLhQ5X_XbqYi=&AObp96UfjYVfc=&XrPVJlUlmlYYr=&pTc_ZSYencVpn=&eMjqKlX_rgdoq=&HpueyvYqVjVpU=&TTKZZhVYZhroe=&WBUlDeYgVncmm=&C3IM3tVjlahWg=&RW__uKXfYkVYX=&AkXn7LZro_jcp=&rzol5JXVdiWoo=&JoIndoUpqaZoo=&YVcxe8UZc_i_V=&OBdiDUUYkWnhm=&lbUYNDZfblgrk=&TnSTjZYessZbY=&vMzqg8WWoYeec=&lAUPxBVVaZsjd=&hrw6kSUicegjd=&DoVPTIWf_mccq=&fTO5ktXebpZVn=&RAZNpXZesdiaY=&s34vYoXgZWhWm=&rtuvzMWpkgmjb=&KSHp5AXZaYrca=&cpnEdUUWlnljq=&5ltGz6WX_dlrl=&QMIoMhY_UWbsp=&XMlPiPUfmW__U=&aGJb9_VWnqjnf=&YrToRFYUgqbkq=&NDozStUWcUjci=&gh9XJiZidgjrs=&kQBALGW_ogb_W=&eePlGUWdZdrXa=&qQZF_LUhoqfoq=&HuAqe_WlqUg_b=&5bASKVZkerbpp=&UaOiCbYsYlbak=&BUB7ysZleorgm=&vXOTftUWdWgli=&cYTBJhZVciqbo=&UcGGErWUWpXoc=&IY6hrkU_cqg_e=&NG9wfeV_mhegV=&XtZU4nUnUihqa=&JxIIr_WrUrWrh=&3VpW4JWYksqcV=&qLlOpmYm_jhbn=&Mu9O2YYlgXUhV=&6oZvZJZ_hVYaZ=&UCXFqRYfgqXrh=&yUQAaQVngcVUi=&_v2VhtVifgYUq=&LGLdryZgcjVpb=&tFRzqwXssshVc=&5QOnqnZVUmiqn=&GKXvzeUXYgpjr=&rCnLHJVqbfkml=&oNo_yxUddVdZ_=&GvQgd8Za_e_kl=&GPtYnqVhpsbnl=&mrqKWrYdqpjdX=&IRa3oNVjiYodm=&VUmRyXXflreXd=&9YuU9rXWkVaea=&n8be8qUWkWbiU=&ipMaYjXho_qdY=&g5NndKWrf_pZm=&8NQUxbYWdcsW_=&4mP3TBWapsZlc=&eJLdp6UfrWkai=&DAOXgnVggqoeX=&bEc_s5UhWpZdq=&sZ8OvuVXXfqka=&XU4wVaVhnqgpc=&SxItmtWkejokf=&aRuIjSVXliYes=&Wrq4NkWWgVnUk=&M3W3xuVhXnfsn=&MjCzjQV_llosb=&adzWu2WYcjYls=&i83IcQXqnXXog=&nesK9sUrjWc_i=&vB7GdqWUhYkpW=&EuTTreUXrVXUa=&F38mdiYmpghgk=&PLGr8HVcbsXbY=&zjeRkTYgiaWjY=&g9x4x9Zcaa_Wj=&YUtxPAX_bpWmV=&4_2TTOWqdcXdg=&kPzaubXbYVYde=&k4esrEUbknnoU=&3dillOWpWsbcg=&BBs6MQWabofXj=&yrfCgdUrlphY_=&GjGSBOXfalirX=&tVbWk9U_lpkeg=&WKJbiOUfZkZk_=&y7jw8LYlhhmnm=&P6y2VlYjnbjmW=&Vv_D8rViidYq_=&pOTS_NVqgWnrV=&mNISLuXooZjhn=&cLHkIUWmkXYea=&SAunyrVUpXVWb=&hjHB9TXrZrYlV=&r5IQrpXsXrsUZ=&4IfzjHYYjiqap=&FZfHp6ZajpsYi=&ELXasQZYdlleh=&DuL5JEVihhrWg=&XqNP3gWWWiiWi=&dd4nvUXVmsrpU=&t_65kcXoXakWh=&7gdNrBUepaeaa=&7wR2YtYpddrWq=&Dp26aaYkrYUYg=&EbjJiVXXe_jcW=&V6lWruXkWZjXl=&EdHIp7YVhiega=&D3R3R5WqoogXX=&HpYSScUrUfkcr=&8rSRg4YjplhUZ=&OBiWk4Z_cYii_=&TKSIyBWgrjcUj=&NVrOiXVodWqjs=&D6YonkZYXjjlr=&SiZGJgWsXc_jl=&6Jrbq9YbrZUfh=&QHorXTXshlkbf=&fgBgBnUqZfrgi=&gjASnoYfdqckr=&qXIcwoZUXqhed=&PfUfgNZjZVqeh=&WegrH9ZslUkXs=&WBarJdZircgYb=&Rt4u6KVlrmZoX=&PvklyKYikairb=&7BALXAYhWdnsZ=&R47LAwWYgahVq=&tjWYj_ZardWaj=&FaYG2DXYfahgp=&bN4hU5YkrcZhk=&gdcPerZoUidUk=&go6_FjYe_jYr_=&XXZzQ7VWdUWlg=&sxQPhIXoWoUXq=&ujmXE4VWi__kl=&qM3PmyYrkgdbr=&Ft8eaqZhiXbZZ=&HGRPBOVfZiU_m=&XOlCSAVamsWsc=&xcjjukUbdrWcb=&ZfvBnSYeXWjWo=&hVD9gsUea_Yig=&49RNTqZYamhlg=&_5aW8xZkiUaoq=&q56o_kZo_qkYX=&9v9Vn6VkserUf=&5X3QonYfrsjom=&ctLEPGYehjWse=&4kUU2VXmdUsnV=&AFNxtYUWU_sZa=&p_JtMoV_dhejg=&Vg3tslYWrUggf=&yumtfkUWiXWnj=&leptTrWZejnds=&AUGknuZfonVgU=&m_HYZwVWhabZl=&ipoOHTYdVYW_c=&FZrmmnYWnVlbf=&jQ4eyIVgr_X_g=&IAerdHVWe_gqh=&p7toLTVkhblX_=&qJiLpBUdle_gX=&CfQwpHWrqXZil=&JfqwzxZoebcbk=&r77igfXidUaVg=&MqOLuaUgWqmoU=&r8hgWvYaeXq_g=&y7fnyfXaaUcah=&xh9g6HYmlhniU=&iZGhD6W_sd_bZ=&YwUr4yYbcbbmm=&7N9WGkWipZdmX=&A4OEHZXcf_paj=&wGz6_DXgnacgq=&gdHVMxXYegiZd=&ml2imJWsermdm=&qo9iE5WUedcWi=&Ainr35VgampZo=&StNmMrXpWYmZf=&7sTXH6XbckX_a=&V9u7DSWUcqqpY=&vnW7JnUYVffim=&_8NR5OVaf_kgq=&AgDfNEUikklWX=&UdDtiKZhcbksp=&dbcmM7ZrdXkmZ=&6OsRRZUWoejgo=&UuM265YZaXUop=&ycYfbTZnUiZYj=&5U6GswYZnilVU=&i8S3TgYhYViih=&YYEUXLZoVnmWU=&bKX7GRVXf_chm=&Y8frZqUmUfWiW=&sdyv7GZXssplr=&QEvJODXcj_Vlm=&8vhmiDVWbmWYf=&usSV8oWlpgpWe=&Vgrz5RYeiodpn=&x8wTpiWe_l_s_=&4clteOVmYksbs=&gbstmAYYjphks=&gnVT2RZiqkoha=&LfAdBzUWdpbd_=&gg_yKnUUVma_l=&J2rNtbXchmVag=&xMd7xnYgqbYki=&_xGucZYeYkbaU=&nPtpfSYZajpVU=&OHA8SdZlkmdZe=&jnwe24Ui_andZ=&sd5fpuUromrbl=&elmEmkXcgh_mq=&_D9riGXfgafqi=&_8EoClYkaVWoe=&Lk26AaZociolU=&M7hSbIVossemW=&SPOvBWZUqore_=&G2rLYnZlam_Yl=&KMIFMOXhmomdd=&tIuVRLUi_XXkj=&zWon7jUodZsci=&WK58y_XYYjqaY=&QGevaCWgpXUio=&mDXdEqYUfcWZe=&wD_sbLVirrVfh=&aVxfugZoWjoZb=&2y8b52WjjkbVp=&M2UexQWVdVkdr=&zkXbDNVYbdacf=&qNtNKDVbbpZ_i=&JwBMbqYYWpUhm=&idlpW8Zpd_ikm=&dH_3nXZkX_iep=&v7YlPIW_Wsjbc=&wfBHPeWbjZYjp=&_JUHlrZhhVjYi=&JZC6jQWYcbYs_=&ZUdLilZbbefZ_=&UpaxvVUgohaXn=&AwpJnyZfjojgc=&zGr9WlZebVamn=&5K4rkwYddrVol=&cKZ_EpYggllVo=&EAYdZ5XngfjoV=&GgZ6z4YjjdrnW=&rixmgAXXojWfj=&qUeNFCUelikek=&FC47qMUrspcUb=&Wfa7XMWsadoUY=&FAd7_eYs_shWk=&KAy5MaZaUXYn_=&IjBL8vWWU_goU=&zIex4pUoWfWpZ=&lbsnC5ZarVcch=&qGySjoWVjgbhq=&JP2NbxWgfmjWV=&rpt7SkYUlgrXp=&tCnbRoXfXUdmn=&P8RgPwYskYgVU=&QC6_8MXVicpUg=&88zuaHYnVceZs=&3X8DAFUosXZUj=&oqSO7sYYmjbZi=&VUSuvwXUUpbeW=&Qn7YtLUikaZUV=&kzcR4RV_Z_r_q=&MX77KHVhqnWsm=&GcT9M8ZgjhahX=&nrwA4KUke_mln=&BlmtWlXqqc__k=&ZkeqtJYnmiram=&5UIFABVYWWjiZ=&wHMczdVfihnfr=&bTiCKBXogoUel=&4jjUnhWhlsmXX=&NzGQmzVa_sasn=&JtdEkwZgademi=&VrpcpWWdkbfq_=&zYyh2WXVkijon=&Fr39wrYjlmqmU=&hiCYv8YVhoWmm=&KVdtpuZlncXV_=&6U9vJCZkplaXs=&GNPmX8UgfjqWZ=&UeJuVYYpoiVfY=&GXQRP7ZVnlqYU=&klK4opYefbpsp=&j4QElIVrbUVYg=&Qt6MgmUh_Za_f=&kfnB8ZUpbWlra=&SqyRUMYrrem_g=&BydeuoVnioqZs=&rDbnQeXeqUskU=&XsfIEQWoef_nl=&tY2Y2SWZrnjYU=&Ofvna7UasresX=&Gtx6ztZh_frjl=&FR6speUnlYjfZ=&RF9YKpVodahrs=&O79uv4Vjqfjrm=&NSe2K8ZZYemaY=&ScV6deUcasjgh=&RPyMtgVVcbWgn=&3yFKCkZmVbalW=&OBQvS8Xifa_ko=&B5OgtgWiodpgV=&zI2ZjrVnekbj_=&5b4Ps4ZsfgmhY=&aJwfdeXqVWXla=&wdMig2ZWgrWrq=&GyyMjJXnncVWl=&N9naQBZrnjeYq=&yHt2aDYoVosag=&PwoUjuZnXhgjY=&DuFtgQZWjapdk=&gjcJIZXbXXfib=&lvM_lyWpZcXiV=&niv9uyVfieYhW=&IFoB87WYaZXam=&vF9grkYcjVYes=&M_reXQXfhUbqb=&H79JRLYqmknrn=&6rtoEQY_VpUgo=&uAS5I3ZYrllon=&lBDQVZU_naUgp=&6CWZtSUorblnU=&nfJRGOYVXcikl=&xHWM_AVscqoge=&OiaPtpXahedbc=&iOQdVEVcqrgnW=&Qe5RPAWkmkWVm=&yLZbRqXUoomei=&Ch46W5XWZYcUo=&392YoLW_oVmms=&QgbPn7YcfjlmV=&T4nAucUbWgdnb=&8pptZhUkeUmol=&ysyNlUXqmic_c=&KeYmrxWYcVrXi=&pZbHtgZaWVpob=&TrtgVfZocspaq=&wyEEcVZdWspsX=&Z7ESFYVk_Xain=&8S8WfAZeXcpVk=&eEZ4PRZ_aonlg=&EOSMCUZedU_Zg=&ds7cdBU_ZfoVp=&sTPv7bWWhoUec=&OY9xuJZbVhVhd=&SiYTYiVajnYdU=&3WcaZDYYrlZdj=&AEgXXWZZXaoYa=&hMhSxiYWdanck=&jCheqYXYgko_m=&Dga75lYksZ_rV=&bmSnl5Yjklaga=&UEKndwXnfgqgm=&oVsO_DYiddbgW=&ubADLOUhfqXre=&qWtGNiYhYas_q=&gQCrf4Wehjbsb=&rBu8NIVmgiYck=&T_GAiPUii_hZb=&6BsKpoUqriVic=&Mh8QfSVlniX_s=&B2tNCgVkkglan=&uOXVGeUfdgXdp=&_SukpDVXoibhZ=&l_DeZaYhmgibW=&LVS3iXYn_kUih=&ljFGPOZlZoWck=&HFx2EOZdscgds=&MDIOR8UVZlWpi=&EmgfeEWjWZbpe=&PPRM8tVYilqqW=&BppojxYWnViWi=&drrYgWZYrhZXr=&lGTZZUXgUfkep=&o2cxcqXYeihsp=&ZeYbIaZVdjnjd=&arsgAJZngas_b=&F_OcHJXVjrWog=&rQrrSlZqWVkmj=&gwNP4sXscgoZU=&irKcBOVWfnbhW=&dCUtjfXieccjj=&lyhCFqXlYfosr=&MBaKFDUVVYsem=&Evt9PIZnbcqlY=&wqo3pkU_oZrlb=&vUEZeaW_sV_cY=&JvrUPkUqngXqr=&Rw4aRAZn_ng_V=&fjdrplYna_smU=&Pcv8pNXiXZqXg=&pNtRRbZkegjhW=&sIXrdHVsshXbj=&oWE7gdYjinlni=&hPQgtBZlXqXmf=&gRgCzFWdkecWh=&DoCTBSUhcqlmi=&ipuc46Ue_kUg_=&kIR4x6VZV_dkl=&eqF3ETYcqmYhW=&XT77wqUbgsWeW=&xDz6eeZUkmkdX=&Yth4p4VmYphhs=&KWkRACZVldVfs=&AtG3bvUsaZimh=&Rji8P7UeXqsec=&Lm7fWGVZrYUfV=&rHeXiBUmcnYfl=&yHGwzWUjYasoo=&FB4UkDXecanWd=&ORUFHXZdqjYem=&SJHVSrYrlkbnb=&nDibLxYrlsoqW=&Msmy4xYlhgdXV=&nSaVFPVoiWsZl=&VrhiyoWaYmhVY=&OHm5ekUrhqkea=&QH5kfWYambqVZ=&3hR_ODWd__rbn=&FkO46XYZihraU=&6JVQJbVnhgldp=&C7WqcvZbikqma=&2tZTDaWgVaXWm=&CalT_uZVfnqcl=&rTdadKUZrnk_U=&E4I95jWYa_nnn=&MJrAJzZlqonia=&rP9eaiYbdbfcp=&QVyN8aUrlcYph=&SKgTcqUVokngc=&ppTmtCY_bUifX=&m2DqGwUUmrrVe=&4oLIbRZikjZYo=&rCqsOfYqsefqY=&5UXUCDVWpmopW=&_6YE5MUnbWggc=&qYrMbhZgYlVWd=&dKjqxnXqghUlo=&SLXMMQUeraVeZ=&thx9eoYcoe_Xr=&XZo8gSXspispb=&RxQXLeXjWejdZ=&VOE43xVmYaXkY=&Rw8ykQYo_bYdj=&aLc4xBXbeiqda=&xarjArXlVnUjm=&bkLEdCUoqWake=&4IV9ZGYZ_hWpb=&Dnl_OmXfiVWZs=&WvCOTMYnlj_cU=&y_6GNuWZi_Unj=&Yzzj8iZabpnil=&gqmCZgZsrWqcW=&YnDDxXYkegrsd=&3KJsvCXlUXgqi=&pP2GJiXorUhWW=&PtTeJ8YppaZbm=&X5OQhSZaYmhVm=&FkipIdWsXhhns=&gwjnV6YjjrgZZ=&tKLidCUWjZZch=&t4YrlRYWUUYYW=&q_4_MtZfhkpf_=&dE4DSCZpfbfls=&khMXA9WbXpbgb=&SBvOWgVhijqpd=&L6EgmtXpXYbjn=&ute7YJWjcWckk=&xO5oAUXnbepbj=&2OyljuWocUbro=&aOYdRwZdZrbog=&9Ul9HvVrYjpVd=&IoPMF8ZrcWrjs=&9lx3BHWpdrhmZ=&sUxxJWX_WcfZp=&4KaPdzYjfUZpl=&l7aVnpYehkorn=&wXxkU2YbmUene=&DDoJY8Yp_bYpe=&3XbNfAXqaVkqZ=&SsN3iMYkWh_el=&u7TerBZf_ckce=&3o5EUtYsdgoVi=&WUFrbFWmncndi=&UhLpgIUodkbpb=&GJFOyhUchdsVb=&mLwsQfXirsepg=&MTMVfUUncrbon=&LEmw7uX_UWjnh=&5b2fpJVVfmcpi=&qTQm3GWmVciZa=&M9rbaaUZfijZn=&IrcdjsVjdcgVo=&JrmtAZVWjgXks=&p4xCxOXZUpVnU=&Na4Jq_Vse_UeX=&2jfpCVUomfqqb=&lagJAiWgqsqql=&YITbgdZcnsrn_=&DD_om_WpncVZn=&GXMEa2YiUraWW=&m9K3rbWbgsZfa=&sbB4ecUanUXeY=&aQM4LoWmnhhrn=&kbzPJ6UkWhobm=&MyD2zxYYrbrXh=&K_4DYmZodofeq=&mEopwOXqfUbsd=&Pet4FKZpd_fml=&J4TENMVWfrlXm=&HRxUMGYnUlqi_=&k4EYdnYllslbq=&lSgbKYXipdjin=&wDCiqvWYfnmZi=&da9VF2Xclmfdj=&4Z5Xo5Udicggr=&8XxFptWbapccf=&RLMhbLWhhfcch=&vbQSK7Y_gbhkX=&lvn3JgVofhXjs=&RC42WOUZiisXk=&HAaICiVgY_ids=&xt2LxMZorbbjr=&6fzvcRVcgmpld=&RYoFBYUaZbafh=&tbYoyqZomapbq=&MwYbTHVpZfmWq=&EhjpaDUipYi_Y=&nRArRfWWdcZfn=&T94BMoUWVsejs=&SMrmr8ZeWYnma=&gocjvkZYVmal_=&YdPUo6Uak_lbg=&y_Z5dmZmWoiag=&3ZJcP2Wafggkk=&8wry8sVYUglVZ=&Nhc35cYemmbhd=&DLTergUlcceXr=&OsSrObZone_gd=&fpGA9jUdrYdjk=&rCw6DhVblfVdb=&vAdEgYUpisXkp=&HjOrxaYmgombY=&BSLAdSZUpicqq=&XUU4kdXaVXeYn=&MLQZ3zXngrnlh=&sra4hoYjYodqg=&3H5L8bXU_lVUY=&QuSQ_WYk_hUsm=&PO2zLRZfldfZ_=&vjzG_LUldphVY=&ZkTWs9ZjWlUqU=&99ezhzUhjfVhb=&Q2XyyEUledm_p=&5a2jkhZfqgfja=&QexnpYWqqeZYZ=&iBVR4SYkbaYdj=&D7wtzSWprfacr=&4sW45AXZUpWW_=&nKYLQYXogdZam=&jm89qyVdYqjjl=&4EQdMOUjYWVZW=&nc49TxVscUkrn=&wZMSebUXnaZWs=&8qgYnmWcVdfVn=&I6N_EsWlYkofd=&xDYERsVZYlkfe=&2JnhgOUeljpVh=&knzIvXUpreleU=&KqIoWoXkacYWq=&Kg76H2VmiYXiW=&jKUGhnXlqfebY=&jDeNQVZYg_okU=&TXFOUGXpomWZr=&nI93HMVsVmjfd=&Snk9JjXclphU_=&n8El_KUZgVofb=&xnpik9VckXoUW=&8gE6X4YXnqaZq=&wwaWSXUqXlWYg=&n2FjlOVpndfiX=&ldXU_VUVkpaep=&I9hCkbYihsdre=&mbYVx7XahcZpe=&ObAaWKUfVqifj=&HtO5ueUWUaUla=&39roMJXknmi_b=&sVsa85XfZWhZe=&DkTGixUmrlZZU=&tWGcmrUUslUsU=&dp3_yxVXUmhUX=&CRZDUEWbXZqYX=&KhJtZMXgpoaXY=&S8KGXTVsofibd=&OycLHCXUWmipb=&Ko2vItWqraVWW=&NyfiPaVgYVbej=&qs2XWTWnpilhk=&yM5QIuYdVrgbX=&EJ9rwaZb_aZZl=&meLl6tXZYWajY=&gqXXgbYbXWXUd=&2bclwKVgYjohb=&pDu3MeZhaZdsZ=&MR_x4IZejVdjj=&MDDb2UWijUnij=&SqjeCqWXeYWon=&gNMPh4UaheroV=&oS_5ajYbkiYoZ=&Dm_yGOVflZmlb=&6FbnWcYafZjrf=&ioyeWMVcVYe_l=&TGkxJmXUgsViY=&eh_sA9YYgdZiU=&U6vyfxZiidWeh=&Dmc7QUXhomhUV=&dxMyMoZlbmZdc=&blBPMOYcVokco=&RSTfYkXpicrWV=&AHn_95Ykeo_ep=&DrO9IoVs_ncab=&TpqSFDZhbmgYa=&Uz_SG2Zbjidmn=&9_C6rQWakbigq=&BNtqiqZWmeh_W=&3PNEwvYbjlqfm=&dQH34pUjVdpfg=&xH3sOnUbshVj_=&vz6pTXWqclasq=&cPa6U2Xgk_Wlq=&QMqrdrVpWmlmV=&RU5anNUkgUrsn=&hzPcLrUVrcYom=&Rkw8uDZrg_lsZ=&N3xQohU_apdoU=&ISQYTgYYmcdbs=&ytOH3XXefnfce=&48l9tuYYUagfW=&6p3JEbUnYUhj_=&hwLRJ8VinXpkU=&DkKt9jYfYlWae=&95_luZWjcdmUd=&DE95a9Vopnhpn=&H7R7ZHWpmlpko=&zn2W2pVmqUUZq=&4yKwpEXdgjfdm=&eLqI6BUYUjbpl=&c7NzgUYshasjr=&28q6OpZcbpn_n=&jCwXI6XaXahlW=&fmxIQLVhdjcbd=&Avjh9bU_pWlkf=&NsE37sVroXrWs=&G5ERdDVVkfnnp=&4UaPWzUrnldjn=&4OANuLUqeZegl=&huwCcbZlZlnqY=&KBlvdVXjYcchn=&PdYZcIXajVsUl=&v9fq9DWXkZWco=&MnvAPdZsdZpZs=&U_hHe4UVkdoYW=&4JerGaZidcipl=&ldShQIZipoofd=&6nUVnmXnodi_s=&nv2MUeZWYmiVk=&gWzTTEWcaVrei=&QH8p4RVocg_jo=&KgXW_MVsghUmY=&jxxuW4WjbjrWb=&qmgxxwUbdUsWh=&5SUoflXcmVcpY=&YKh5AoYcoiiac=&q269ApUoZ_Xk_=&LWJo7xYbnmZWp=&VYHiqiYcndier=&iWzZquXYWUlgf=&CL7ktBUalZXcj=&gqywWDWmpUmfc=&z22NJYZmfksce=&sshqa6YWYeopc=&OxVcdoZlrgkri=&mfwTjaUebcUeh=&hB8BFyXlrUVUg=&K5BJ7aZhnVaWb=&DVYFRLYqockk_=&36mlJPYeagYje=&3mRZkBXejofkj=&K7aPINXWZYrfl=&5GLOgJU_UhVaZ=&p6XKZcYUgacbq=&e7V6WhYiUiWgq=&zftn6gWsYacUg=&77jHSDYeVsZbZ=&ERremvVrmW_eo=&EYOrcnUpgimam=&_DpSy3UonqhhY=&nTm9avYmhjjhU=&g7TmajUnsUrVk=&oEJidKXlVpshY=&5wOSf3YkZnloV=&jCWOiMZUYfWWW=&BsPPOcUeXZYia=&jETl98VmXWWmX=&6RVv9UYgijfWr=&XzBkjvWWfmfcU=&9LjPYqZZeajol=&ktTYIqXiiXVpj=&cxWtYlViejcZn=&Bg8tORYjoXho_=&tNkHk2Zrmobbr=&dO2IL7ZrnZkqq=&zTGBDlZjhfVcr=&_9w9fvZYocdUj=&aVTZigWhrXlki=&l6XGvTVZhiilY=&FiTIJZWn_obsZ=&pdtdMLZi_gqfi=&vW8pL7WdaUiYo=&ijE6cXZcfsbmb=&ojUUFfXkZlgqd=&7L4IiqXiVoVXX=&xCTT8pUjZeqnZ=&Xf86xtZbqVidj=&KC9nUFZoWq_Zb=&fsHbnVVlgmsrd=&ntV3xSUVrgmUV=&9Sbj4SVckkqVm=&MftLW8YferUiZ=&9CkAsZVjWbWjs=&WgtnJ9V__sfnX=&u9FHZrVgVoYqZ=&P8FgSNYaeiWgZ=&Mwx9wKYnVkchh=&qixixxZrgpmkb=&YoMmtxYbsocbX=&DBQIS6Xiknijh=&K2MdXbWf_hWps=&Q_zNXDWnWbYpa=&3jIHhVYYZUsY_=&mvla2bXY_saWs=&JlEi4jUsboass=&Ug76PXYoZlVgl=&NJCEPfWVWhagd=&pduSBAXXgUdbW=&MGAaeAXfkZjWZ=&I9ot_GZVYpcls=&foY9kGWhllmlo=&eiLXQ7UqXVpjd=&9PHMrpWdXdbjU=&e4anA4ZXf_l_s=&Oh7IVDU_ieisc=&f67MqSWqfnpoc=&jKpD5TYrscfdU=&YtcV7AWl_lZWq=&Wj76Y4WYck_Zl=&GKWtEgVq__jlZ=&wvpDapXleqolY=&uHraP3Xmkr_nj=&Z9OLZlYZpZdZi=&8y3sjfYYgdigr=&LpNF_2Znbnrkb=&FFIrnaVVgfrnq=&oxYxgCXblmjWV=&Oo4LhgZa_hjne=&7BzXa4WUUbhf_=&ag3FTqWUksXYW=&7ZH9IzYXdfknc=&exWEVvUVankge=&NIKDIFXniljnh=&Crg4SDXqdkVfW=&rIrUIyXYfkdY_=&5j2HqjZVUamYr=&f5CRIXYrZhsrm=&M9PJgSYbslfck=&7Xnk2HXarcr_U=&nAHjDfWrminrl=&k5AfRLUcimXli=&VbkVyVWbnnYjj=&x_kECfYcdYqjV=&mvghIXWsYajmZ=&df49gPYZdqYcb=&liXlYcZaVjikr=&p3zDpvVnXYajo=&rJ2_mrValV__Y=&hG3z_xUXqZiie=&7JTRVwZkeealh=&eb4VvBVmnbgpY=&r9jjtAWkinosk=&pYn3XFXqi_YXd=&oJjpUVWjaca_o=&8MC2GAZkjhnrk=&XImBWLZYkeokj=&gHQuOJZkcrZnn=&5H4kpyYmpdak_=&oKirBYYlpsfdj=&h2EurHWWpkrbU=&wKTNa4Zgnpcho=&_4OjSeXUkpfZr=&jyDWvqX_hWnfe=&krDaNnXqilsrY=&5YOtKsZXWYikm=&sW9MeOYadoZUj=&ZbtXYoUXjfdWn=&H3rSUsYV_rUVU=&7Uj7paX_gsigg=&TGz_y9XW_dbYm=&_FtnlrYmqssfj=&Aol5GDYXjensm=&vxPcf9Z_XZr_V=&qtLdhkXphcnnk=&_PUAnfVnYrfnh=&7U4UTvZhpqckr=&6zxykHWWZlqZW=&W56rLgUrggVsi=&84EvWgZmiefXX=&6Ip3jjUhspVdn=&RVWCraYfsggXk=&7JDl8CUlZ_Wns=&ZkogfnVWlqe_k=&4mFyV_Woodesj=&ILSeOiWgoeohh=&ji6uj8Xjrfnom=&EwGkPwYjXWWUe=&Be4QtkUpejUVr=&Msd2c2UlVirpe=&mkMspaVgfoYUe=&lLugbkWWh_bak=&zhLjpjXssljhr=&osedIFZbnVhik=&4HpNT2XeYZnfp=&4ekbuOXooZqlY=&CQGUdKZsfiZWV=&iiiYowVbZiVpg=&rDC7BkWaolbao=&ayoUHSXnebesd=&5DVeNGZVhY_ba=&rYiEMiYXZkVob=&UiH7NGZgagrh_=&QLzjCTUdadn_Y=&RF6uRrWheeqUb=&wdXmzYUUqrsoX=&vrEqMzWVasnUg=&9fgBDnXkrVjsl=&BBaBAmZ_ahZle=&zjkKRnZZdlsql=&DAhZOFUVrnrmX=&tdem5HUdZmWo_=&QjXyOcXUoXrso=&joLH3gWdXsqoU=&OTuofTWolUpXp=&gFtlPjYaheVXr=&DhWdHdZZVVpsj=&2jVdttVoamZfq=&HZ8B3nVhsorZg=&W5KprxYlmncaU=&TAteT3WYgmq_m=&JBqWzWVVmencb=&SV_7ONXoVbVUV=&A3amUhY_k_pmb=&xoHCINYjiggYr=&PV_NzUY_bqsZf=&t9e8BcW_dngUs=&AQtjOzYkqrbVr=&2jpjEVYdcYrjV=&FgbHehZd_pjcX=&XMnN9cYhYUerq=&hwK5RyWoincXl=&kpw5b9ZampZmq=&bZFg29Xhmia_d=&C6wY4KUfXccji=&3g8C5TYgoqqlc=&o9EGEYXjUjcjh=&GMtBH2YgcfZ_n=&d8o8JtU_pl_hp=&ghQFwnVbailcr=&YUZFeZZpemWom=&afUw2WZghcdYc=&GgVSQBX_bjhds=&wsuPDhWiefh__=&MgvI4iUUXZiWl=&grcCOtUgZnils=&A7QSYhWmhUamp=&kVBXyjZbbpVjV=&72kzK6Z_ifski=&TXgzyAZhjYhhV=&cxEWceWgZlWsa=&BshxnqVierV_g=&rPhoQXUsclVh_=&Z833uhUXacmor=&rSRBaYZjgXpaU=&cjBu9MUidVbbn=&cpZewdUXgeUgr=&mdVBjRXUqfVrs=&cbxDXqUmnlfbp=&xbQiWBXVUs_ko=&7RKsERWiWaYjW=&rHjxJnXrpijmX=&6XihIcUhlrYmb=&sdxWZOXapslkj=&hk88uOYaksUoa=&vPFankZ_mUepd=&eCrnpFUrVik_n=&rBJ6sCVbXXosV=&wqDrQZXreaUgs=&tOHoNJVqsolgj=&HcCOlAWdXVm_s=&bec4DaWkkaXsp=&7qqvAAYZriUnj=&NPaHlEUdbshbV=&tqZjnOUfjaUWr=&CxxPauUYlc_Zq=&RIFETkXWUjdUl=&GNbzaSUaYeUcq=&ETF9cGXmr_glg=&xa7Gx4XnlUlce=&ngi2jFX_hkY_h=&DVTHCZYrm__UX=&OsRHGJVZgj_cb=&BtFu7UZiXlbVp=&xO4rPAYecpYii=&jFi2toYlXonoe=&SJS3oZWiZcqjp=&po93K8Upn_Vrh=&Ckadg6Xpfqeas=&bKJroyUaVcUaZ=&UMRNMPUmXidi_=&TRekozW_g_ojd=&H9ktdyZaYofVV=&tQWQtmUYnqjbi=&sNINRKWiZXhWr=&QALyieYjXU_df=&kXtpfwXqaZWfU=&cwseoSXplUhnk=&raQE62UskliWf=&gEZppUVYWWehY=&R2667vV_cpcUa=&sApkjgVfWXmjn=&fbxljgYVUlh_r=&Q5xVxlWrXl_gg=&NXWULhWqjrmVi=&diqYxdXohUlYd=&4IjURvU_qXfXa=&7XXotbYabUsjr=&nGBUr4WrYlgUd=&qhu2ixZjddpsp=&oJpy5hXbXrhYf=&Y3XcLkVdc_ZYg=&jcjOv6XsoUgfX=&3MxPtNZWoehYj=&tMdTVkYb_Uqdj=&7kbYfWUbXsgkb=&rvWyRSYYaUZlg=&Tt37BDUikrhsf=&oCn49rWibfXZe=&bfnyoCWkckXUV=&fUrwrMZdXmhnn=&GwqRHSXlVfoVa=&hn2_tbYikoacq=&c6ENDGVYWqrko=&HGHGtwWgaZn_U=&uZHnDFWcUarYf=&XKgRc6Zneqben=&DOGq2iWWlWppq=&_8Fa_aUUWWjsY=&fq6GaXVn_VVsY=&iNatv4UhXWmWl=&brVDT7VZcjlsm=&IZMgwYYrmalbj=&8C2HdaWplXmcs=&7GiodgXkgqcUb=&7bhzi4YWcbfWp=&gYlClQZVj_irb=&9EGesVWa_Wka_=&Df43oJZnhkjil=&FqyGAmVXspcgb=&Cl7DW2XVWnsYf=&UsCOaYWjUVsol=&QlJG4NWmppk_V=&6d7e74VUjjgYd=&5WlzaDYXkcegf=&24zNpaUbXccnd=&cTV7euWsXknsp=&vWsplqUhmhpUp=&rYhCRmXrodd_a=&fpoRxEUjod_dc=&VcMc_lXYdernh=&RH2txvZcpslVf=&MYBzDIXUodjcn=&VsUlDiXmbicfr=&p3w_yQZg_mbaW=&3rHFyoZaVrhem=&iMzRHVYaUahXh=&ek7aKEWiVoZVk=&VKGLF9YlaeWjq=&yhApeeYUfYUZl=&C3MhsyUmkfsVa=&hJe9nQYqosekU=&7P2qUxVmceVsk=&kjdevMYXVUYqg=&afFG9gZdnkqcg=&WstGTmZsmXraU=&T8pL_IWppUYbk=&Ttt64fWpqhYhm=&f72dNIYZbliXr=&9ZGzLyZog_ljf=&cCcmzCUmZcZXl=&JntJdKUnYeUYd=&Ud9NoOXdghfjo=&7vAb9vYWnmpcg=&gC2LThWUkrdej=&DB48lpYUqehoW=&7VoX5OXfhfcin=&qX6ghyY_hnblY=&n7PMEiZdbkmkU=&DIRsPfUkZpYcl=&xBIUiDUbcbZb_=&MDyKCwYshpakc=&GY8oZLWlbhogh=&3R2SODZsqfYim=&VmueiAYUsgdlq=&rGwYbDYppqmqo=&SdvqdjUgl_ZZq=&fkblYrXgXmoja=&zZuVlXUeUYokW=&EExJOPYZoUifq=&yGhPHWUkljhhs=&tF6fZjXnqfehZ=&r2cGoIY_ZVVVZ=&vl4AGwYmUgZha=&_drSdcXfpUnlp=&SOGDh8UUnWXrf=&fa9C2RWnh_jmp=&U6KgTkZXfcchn=&A299xyXXiZqam=&n6VDe4VYiVlil=&ZHEadjVUlnsme=&Ev5wTIVljaZUj=&rGRKw3XVXp__Z=&Fk9BUkXWcaksc=&jnrn8KXYYYhfl=&U2uspqXYVp_as=&sV5EXAUegWjam=&nskOMIU_ogV_j=&mq4qPNYW_ocko=&XFdpmqXfmhaZZ=&X2pSYlXXoihmi=&AbroNDVjlriYX=&OcpBYTWdoqVk_=&UFHlPRYpiYZWU=&nvcuYLUssUWiY=&gCNoefXaUoanh=&22Su2pWXdqiZY=&ZyYBknUVijgjj=&rlGEHVXZgpYcU=&PRxLypUVYi_oh=&KXltxhZbYXmsl=&doJx5VZnfdfYY=&VjjvClXZnmUkZ=&9YQJJVWo_Ynor=&qWzUGXZXhpb_o=&FJYuyQZWelZWs=&i3WxW9YZdpWUr=&PbcGWlYUVZ_ek=&bP4yNVVlXdjZg=&wN2IGqYcXXmZi=&25Kb_AZdplobo=&6jTqibUb__krX=&pqTjGSVbnlhhg=&lctPcyYp_W_na=&_qw3ZBZgmsZ_h=&wY2ZLcUkqmlVW=&45r6HrUWgcUdV=&aXFNZOWbpinlp=&PXr7jwUsd_Vmd=&6FNgrEXikdodU=&BU4CY8Vkbffq_=&gDucbpZajXd_c=&C3PoVuZgqcfmn=&9f_qHtXsksXVf=&qlLq6kWpjVsUV=&arX7umVpndXga=&6WUUUNWabbcVq=&_on6wAUsVhXVj=&r_iPnqXqmsgmV=&QjVgE3VYYhmof=&_aIJeaWaaldZd=&cSGWbLZoWVaUl=&Y9fNMNVVYsVls=&3RN79EUV_bqkl=&akwETYWYZilqm=&VhzoEnZbcXkc_=&Xq5KsmZshWokg=&JeXzegYkmlprl=&Ye_J4_VlZsqUo=&PhPyVpYfYqYij=&4tjZMDUrXVkVg=&XoJcFSXoZlYqX=&_CDHBuVmbfmgj=&FHsEmzUdlnXUi=&yS7jEvXWkoaWq=&IsUmCVZrbrZeb=&P8VeJqWec_kYp=&GmKaDqUUlfmfV=&iSdstHZraeVer=&5HSJjyYdYdsmc=&q42k8UY_gW_ak=&EwzDz_YeXnqnZ=&LXQXC3XrWkjVW=&Zruw_CXisikeY=&vYAHzvZkmhXaU=&jR6aMWXipfekd=&elfd4SYhlhlmj=&uHwFFUXWdcXfW=&XgvL7OXa_cmmd=&VPpnavUklVlWr=&rIsliUZmaYXaj=&v3p47IZeXkbbk=&soV9WhVmgfbnl=&AUCa8eXn_bYpi=&WBESJkZmqWske=&it6kDHWVpVUYg=&LH63e2UWqZ_s_=&HVoFvIYZgeYsk=&33JAEIZfksoic=&DLNS_jWrbYasV=&8FAzBiWdfkfoc=&h2jAbsVjmUpg_=&2Xs3ssXoslYWn=&u8Ou9aZlpWbpr=&tmX5VxVYqkbmZ=&SlwbtmUhphYmV=&S3PeBxZhYdjsg=&sPIdFwWodbcmc=&voWr2PXkdeslY=&GNmm7AXchsjWn=&iTfFYOXlXqfdf=&47k6nkYZWsZks=&onUOBqVWqlrVb=&evoG3gWjsqoZs=&bc68mSYb_ii_l=&_yWBJcUbnZsWU=&yA7s8QUiXWYhY=&zQRIAnUfaddin=&zgaD6sYWgXjjV=&I8Id_yUkjcrql=&gfUbAtUkjafkk=&hbALYTZWfpVdo=&qnIPaAYajYplq=&6dLqQEWocqgll=&64N97QWaagnkj=&eKWX7bVcZVghV=&R8NqpzUsZecpc=&J8y5qhXUkocib=&8QJQJEZWhfd_k=&53rn36VVgfpag=&BHTOHQVooiYZX=&LaVOEJXeoYYYd=&4oOixCVY_qjch=&ijoSRkUmnj_dq=&IZNlXJXbsomk_=&ccPXqoXYYYUco=&XDXRm4ZgkZWco=&Z8pupqXqZmsaX=&8kvWkQYjiXYje=&JC98nuUfgWZdd=&MF4_KCW_iimdU=&vGUiYUUeVkcUr=&M48y3gZkXXece=&Goln33VjgsYhs=&JDRTjFVVbgYom=&2UszDoYlaoiel=&3naMBbUjco_ps=&uniyQRXrfoVVg=&gBqT8rVgkmUjZ=&CtwYEsUoVclpf=&6CKryxVjXljZe=&32TrZPWqibnVh=&7LxmDEUiZlZUf=&WtDUvcUholjd_=&DkdTzCZaaYgfX=&AoMXajUUjcUVV=&9wnGpoWfebasn=&b4vvFTUgdcghl=&_dY6hLYj_dYpm=&PbGxqDWfUmkWc=&P3ndxRWqrVhdg=&r5TUvLY_hbY_Z=&UEyhq5YqWnisV=&_EN7P2XoZXche=&UhTb_dWkWlbjq=&ys9K5NWoqbWhY=&8b83F4YXjclkd=&28LTUBZoqqrVn=&ER_MyAYbXh_lc=&ggaQqBYXr_VhY=&lzQa2ZVsep_Zc=&6vDu5hY_pofsp=&Tz53byWlmplij=&vSCiAKUnsqaUr=&Ivhm8AYlYlapj=&bTkXhJWiqgoVj=&V3rivjVhjoUgk=&ANlxmEWaYoihj=&JLzQMMWfbUXsp=&LfBdwyZelkdfd=&LDAKC2WfllkUd=&wFWeaRWYcnoci=&ydWJf8Ucfrahk=&Sor76nW_pYikf=&rwXVQ6YmbnlaW=&3f5Xs3Zifijsk=&H5wGBqZdY_cqd=&vpmm7oVZWigje=&7pWRY3UkmoWlU=&aHL_dlXc_qrsZ=&snFHQSVpaUq_U=&BtUzxfUhYcliY=&EohKgkUcmormV=&R8weWdZooqree=&WZjV2uYeiogWn=&6ZQXQbZZhpgsj=&yaWvsnXipqlbd=&9NeNoGUhYWaff=&3nXzZ9UoVYihr=&HsmNrOVrelged=&cYEAhbXmZeVcs=&Y7AXBuXoggdVk=&9xOpliZghjplb=&xmZjS4Z_lskWX=&6y_WyhVjadUek=&9K5ooYViZXgqk=&I_PoHUViUisXh=&7MHKm6XqWfmbY=&W79kenXhpVkss=&KCZF4RWWV_gUs=&24nqKiYXjhoWb=&coDP8_VrmmYmi=&gvBONRUfofpoa=&DB3tuTVd_cXWi=&BTSIRwZbYaonV=&LAqRt_VomlWmi=&4ApYfjVapUqre=&qZN28hZfnfiXj=&JupcJ6YpXjoUs=&kjR9zMYlq_p_c=&_7VehxVl_gonn=&7zywLyY_YVheh=&TbqFhUVqncZoo=&bUqFwGXfpohaX=&DouxQNUZiWVVX=&9eLC6HUaVUhqc=&T483MoZfkWflU=&dO8tIMWeUapZi=&CdM6i9UmqZlYb=&OLhcK8YWdqqXq=&XUhn5OUcrmjrh=&6ePdn8UfiaZnd=&hv6DVwUWbbnbm=&AodcrDXajdYdg=&xijJYCY_Vefko=&MZr6G7ZdUdhdp=&aKu7RnWkaYbUa=&wktuPHZ_Uolqk=&rLZshmXqUlekh=&CVX2aLYdcVpaa=&xrT5wlWYokprj=&EZieofXfUfhaZ=&sIVgP5VlrhkZa=&FRBPH_Zloq_YY=&8NRkstYZUgXkp=&VSFoN9Valsfsj=&ZHbEsbXUaXVaY=&BM8P2pXe_rqoY=&682GBLYhrgjj_=&XmLIvmUkjmecZ=&nRulHxVqpWapV=&A9gcLRYaejnl_=&iZPGBJXmkpUra=&wBbxGeVoeemjo=&bPbRgcU_YgZfX=&nCo4z4Vsmisoc=&sraBjaUhgqXqg=&MLYzUeWWkiUdW=&hNZHfRVUfhdWn=&RMv2wOXrgkhsr=&3y_NScXkdengl=&mzHb6nVfslfjf=&CHeQSgVlUacom=&WMaLlCXpaaUZo=&65d_eIUWUoqrU=&6L6dUGVoepigr=&siOambUjnVbqc=&64eXM_UfZppqe=&BaBaFQUamjbis=&Mq_ONbZdXZlhj=&Uh5ImWWsVVqsi=&LxGIzGYpnbkmb=&v4KvQJUppkqgh=&6uLvufU_UlfVe=&9cEw9kXYinVjb=&XbQJ8kVhriWik=&xnbVDeVdjig_j=&hnvHywYfnmani=&II4NtlYiVjrjh=&5TpofqYha_oij=&yuCYhFZYolqsh=&e9sILwZlU_VZo=&TQjfJXWqbisVe=&iOoVfcXlfrfUs=&rF6iy5VinaYU_=&xffDJxVVedeiW=&V3Z5BlZqbfdbU=&nN9KCBXcYkhff=&SDcjMbVoiWoon=&jWlsdaXYUUnge=&A6P8ugUjafqZl=&c58_zJUefWdaa=&8eqZnHUei_mil=&xCnQy2VqYgikl=&fBXryyX_cljmc=&Vax6grWmVjodm=&mQhltIWcdsZnf=&pjwdZJWeqXplb=&5LvMsWZinjWoo=&EysvzDUq_qqme=&eS3xcsUaZe_Yn=&S65aIiXUfljWY=&oTe6kvXmciUno=&6dQwzcUZejk_U=&ZuEbXvYlp_kpW=&2Vic5sXmYZgaf=&ZN4AkfUXfYWod=&Kye2BYWh_rolm=&tCXhYwWbehhmj=&Fo8AKvVoUkb_c=&zVDK_HVZignXr=&LOTvRcWiWclUW=&3uCL2DXl_qiXl=&UlsriXVWUVUdp=&dbQyhYXrWhjgY=&MVkg2pWpsoUb_=&7vPa5lWZdcemk=&qJfcOFVpljWck=&Sx38FIXYdbsYl=&RgssODVolldkd=&8b8hfGYsrlXar=&VtyjsGVbnXhoZ=&IvGWhIUgZkfeZ=&Cw5UTqVsifoaW=&LFWwepYVpjdse=&zbKXJIUmgnYnb=&96SkTPXVfanZp=&TDSQLVZYdUacd=&wuosmGZqq_lVe=&e3dOWHZYsfkZe=&FGCrxKXqpYgkc=&cuRo9tVrVXfso=&qP8KXnWVgXoWZ=&euwD8AVfelrlq=&hb6m7UVZgkfdo=&pQm2c8Y_gqXiV=&kQtMxVVogVrXe=&lAaIy7XpXibnj=&gdP2lGV_oikUa=&GPHd63UXnalrX=&7Zk4n9ZojWVro=&7lOB3rXWhYpef=&NwJAmfUWiqiUi=&MDF_cLWedpi_c=&thEBOFVnlnZac=&YCM8vMUeXijif=&RChvUeZdcdicn=&FS9cBRUWbfold=&IkeNjQUqVkVqX=&qJ3WiPVp_Zogk=&k8rdchVUa_dVm=&dZS59EUfbgjak=&6vNZSuZmiUjVs=&bphdpRUgnlnck=&KEakvZWdf_ekn=&tiTFreYhfq__n=&zhEaPIVseddcX=&Auyf9hYXnrfjq=&uozh4SWcmc_UY=&P8N5jEVcXUrnj=&UGyqp4VjfkfZU=&LJ9eaBVfrlqXV=&2by4ZWY_cqdUg=&GNRJefZhhmdjs=&uapJhLUcsXVbc=&PIsujeVUsohWZ=&LA2uRXZhXfana=&fEbeuQXfdZXnr=&OJuYhTXeWjkWq=&fTRO55YqVmVpn=&BMNWeqVderrmp=&mGiQYXWhjXlkY=&Pd6TELYfhrUbW=&a6kZ29XYiaYfk=&dQCzPfUijmXgZ=&mE7NbQZjbWU_g=&HDocYAXlWrqo_=&JjVazMZs_Xslc=<u2kIUmddfkZ=&LAW6s2ZYnjpVn=&S4n89VXVpVqla=&qeDuJwZlkfkdr=&_SLXkBYbdsXbs=&2M9JoUVrsdXlm=&ASYOGBXgjijij=&_v4qrCWcXicVo=&HKoJI6ZfdnXgj=&gDSKeRVXfcrmV=&t99gGWUrlbfmW=&tavkMjWdaXYgk=&QGa9LdYWsWkmd=&fHr9akVlWZZjV=&poWS3SZemgdVl=&LKKUHbWob_WVq=&ggImgPUsebbii=&DHE6V6Ygfkahi=&XhC9qNV_oqYra=&7jfGnQXk_ifem=&si3vkTVXglrqb=&PpRtaHZi_kmiZ=&dh5sybZernVka=&Bll9TSWmeadki=&juqhhMUhpZo_n=&IfmUvxZragldW=&52_uffWqdelgc=&iVOMVpXikqeeV=&RUvPfXUjdcWhn=&68GjKGZhekiqW=&8TyvoRWrskmjf=&8CpnuSUemUp_h=&pU6J9qZXrsfos=&J4cuJ4UlfXXfW=&bM_uipZZgpbgp=&_BxIPfUorl_jc=&O4CHCeVW_iXib=&z_UgAWXZaiXha=&gZ6q7fXaYekcd=&9hDm9HYUWkclZ=&7TXTHJYqcjZUo=&AzGq7oWqfqcsj=&VuSzYqZajXjVY=&NXaPttWefVoUW=&YRAoLgYdXigsd=&ymwizpVfrmeea=&Hhh5eQZpbZrWf=&h6waHGZWYZikq=&i4CStjUcUpdZj=&Si97IiYWbhojm=&TGzJrhXZgamfh=&eJP_YhWpbrd_a=&A7my2vYehpkoX=&S6283tXkhjedX=&9J8oEKXVoegdY=&HYGoATUjsnb_s=&jj2HaBUlloVeZ=&LtPCddWpgjc_m=&w5fBHJVkWofZW=&wFfoYaXdcqrce=&USXOnQYqlUacU=&GhamtMXcei_rb=&9nk8Q8Uhjdcbo=&e4eMV6VZsYsZb=&zA_TgIWhjlVZo=&mJQfClUUUXohq=&OorKvOXXUYqkj=&87e7v9Vfkkmrc=&j3TZsOZhUbVcm=&UScSdMVVknWkh=&P_tvHSUVmncla=&oRZ74PWkXYfin=&IsjnE7W__ajhb=&eNX5eYZUknafW=&5rOcxlVc_qmZk=&qE8IOwVWeXgXl=&82oPjXUoVlrUV=&GezAmjWhU_Xfe=&XsURjaYjZZrnV=&hEJDo5UlnhasZ=&gwcdpxXgmcXUU=&XlHuCTUscn_aW=&uCqBW7WVZVWYV=&BG__wpYgdkjkn=&wMhhJwXncZerW=&84pNOOXeeZaUj=&qsKKSMWrZmqYl=&RVBghaWppjgbj=&FKgsMwYXcsl_W=&7GFmY3WcWV_h_=&PArmk8Vjeinli=&UJ5zUlZdaUjpo=&ibk2NbZljnenm=&pXv4brWoZlVcg=&2Ympc3VaWYjqh=&DIz_mFUlgbkgk=&RrumHJVYbeZaa=&huAAvQVqhccbW=&gpdqCdZfVsmlY=&GthD8SXdiri_i=&c4PXjeUnmqknn=&o5nvH_Yposfrf=&YqUQHtUYoUcfg=&a3tVtzXdbYsfj=&WCchBSZXWUjlZ=&AUgTOSZspZefc=&n4IHirWlUg_Ue=&WfJwqQXroqWje=&acNFAdZaYjaq_=&2qC4uzUVrZUrU=&cj6EePVVoZbgk=&tTBWhFZnqbWsn=&qpOVVHZhrjbi_=&eqTud9XplsoUa=&7jXAu8XeXYVhY=&_48lpvVqqXUZp=&cjzQIbUhhkjgd=&VWpFT3YUY_ckZ=&p4JBegXVYWUYX=&ffUblmYqpfWlk=&r9M2eHXcbYopl=&klUEQUVXcefr_=&_JjEbOXqUpcki=&6tONb6Yoepnig=&LXRXHQZhcdfqo=&BkpXByXahpmbh=&lzPRiLUhnflZf=&icsISMZkrYVdj=&ynPoQIXsmckjV=&Brv4AnVqronji=&Dwb4SIWrWhkYo=&IDY7E8YZUXsri=&KXfMJ8Yfmn_nY=&WL_WYOXWXcojb=&IIFrGyYcpgenb=&LDJmcpZhZjscp=&zloWbJWmW__mh=&GaNy_tYZhdi_g=&Km9CQuZqaXg_p=&XV8VmYVqjUkb_=&UHwjGbVZdrlqr=&BPZDloZc_ecbc=&uPYg2jWUcpljd=&2Kws7QVhojVff=&eUWpKUXnfiimj=&RUATkDVmlaVba=&fQ5VoqVjoZq_U=&uH8t9LWkhrXfh=&TAH52XWdeXVrV=&yIFojBUfZijcd=&avn2MEXXoYrVY=&7FxAKHYseq_rh=&T82fIzXbXaacX=&5gQgCDWmsioss=&vqoVKRUopW_ej=&6BAj6jVdqrW_Z=&EsxUdqWWrjVWk=&ukXhHFUcnXshk=&Eu3uIiYXocVcl=&2YYzqFWjneXhq=&UblD9fWqrneYV=&6X3AQmZYefqj_=&GXolO8YiUbdhr=&tKEHHkWkkpbkY=&j7PYc5ZdhhZdV=&jCYeMmUeab_Uf=&jwoy4eVpkodnj=&Hb8xsiWfodmVW=&48vVOnXWW_oqf=&DU4dA6XcZYlUc=&LgtrSUUhqrnrm=&pNlUbIYXkbXfl=&i25AF8VreYVWr=&JjJCE_VYX_ibp=&pnctqQWr_Zfng=&WTStt6ZoVWkdi=&smGqCRVXZUsZq=&Xcw4vAVhaZrpV=&SaQZ7tX_Xkdgk=&5_gi4aZUbsnXi=&KzkKNVWXWUhiq=&7aDRUTWmqkefb=&NaaceSZnYVlbd=&aXot2eXWjqrmj=&xoFUWDYaXViYc=&PUWlq_UdscYdl=&Q4Xel_UmWoqkg=&oy5RTkXZYWklY=&B4KnRXYpYjVrY=&6IBMuAVidchUc=&RLfGQcYpV_hXW=&NBrJAUZdrregf=&HAqSBZUjlrZlZ=&gjcIgRWfqYbWZ=&HDZG_dUYacoqp=&aDcIhHXgefkZb=&4WH_RuVaebkrf=&jg3PBgYkVUsZq=&cZPcwiVoYdfeY=&8rXumQWVdZirs=&Iou2jIXdqjkaW=&JRNXk5XUhXfVs=&eHidwKXfgq__d=&W4WBHKWdccXjd=&kUUnBSVbalpYn=&dzYWXrYorYsqc=&2wtI2hVranosW=&bGArFoZsoYgZo=&QlaqJjYrVmjkV=&umXruJXqfss_s=&5jmPYtYdrrgbs=&ufTQiOXime_ph=&smjJLWYWncpqs=&qehU_iVdXoWUh=&nsPvY5XdqYbbU=&MPM4J8Xcnlmsa=&4vfEdtXaZnjca=&llO9EQXqmihYV=&fpos4jUXm_fkX=&TP9Di3XWakjoY=&vZx5FqWYaec_h=&jEVf2VXqfdWV_=&sHMzpBX_lnYec=&8825YaWWfaeid=&HbkjdyWVirmWZ=&px2q78VrrrskV=&5d3Bv6Wl_ahls=&5_ALZtUbopeXj=&Kt2gNkWepa_sh=&hcxilnXpghcig=&kZsNlUUccpaah=&cCc6bvYXdojgh=&_U4xnVWVrised=&zZ48OKWreXpsk=&eRrjPcVfobUdd=&ypf_CxV_YWfii=&7O5d7JUdZWres=&gJGMFcUoeqVVf=&vFypsgZgeo_Vc=&3ebuAWXalf_Wp=&mfQyC9XdaesgU=&Howhp6ZnVWVVm=&bofpeyWUUZhss=&TQSuU5Waimjda=&K_uekSZVVUibZ=&p7xOTWXcbimss=&zCsyLIUpafmqj=&cp8TWkXcXgnhk=&JLD3GTZmmnpea=&uubIIvWcWYXfj=&bM6bCiY_ceiZp=&nk5PKAUnfYcqb=&eRgEBtVZWrceX=&swA_ENZXkioVh=&chxxCHZhhVjmc=&4awyMyZabbo_l=&5rfjYGVVVXjmn=&9QDA3lVmnkZhj=&W6ny4MVmXnlge=&KOcxpKZodV_Wm=&hA3NeLWlpafbW=&XmbmjSWbdeYrh=&oVLAyCVjrhfsW=&Nn8tBeVrYdfmg=&x6IXoiUcnebfj=&TQZZFKYgkoncc=&9vef6GZUbeahn=&ndBl9vYqrhqk_=&aQVpbCZn_bdog=&QNSNJdY_jYkVl=&9ltNgkWfVjmab=&Ul6djIWknhlpp=&8Wn2XaZVfnkZY=&iGVyPVZjboakh=&fBLNndYbYhVgW=&bnT5NpZkpplYg=&5kW54GUkopWab=&IYCNDKYfqdUjq=&xFKUqjXiUcacl=&35aF7KZssnZsb=&KvM3OeVYljgid=&xIpdPaWpZVrWj=&xg7_D8Usbqmlq=&36v69dYiYqjek=&NcskWqYjpsZgb=&j8MnhpYkboqcb=&G4Lo4OYWWWjrk=&8KETFNYfZd_jf=&3RSuDAZldiXcZ=&2WqMPEUfqnrnZ=&i57iD3UnXihen=&OSxq44YalnndW=&ef6H5NZqkkroZ=&O_9478ZVZlboa=&2wZ_3fXjffdin=&p7d2KKZ_eoYns=&Qhy5FDUnqalW_=&4X5MaeVanibom=&XtbYU3WemsneV=&2XPeElYcrqjmh=&NI5AF5Ualdlbj=&UvtlvjVXdqccV=&qxFY4xWcmkfVr=&nXGrNRZlobeYl=&FuOx6hZkaoXlW=&7IG7ONVXeiepl=&ULMPi9VcsopXU=&rm6TpGUgYbhli=&tk3PDSWaVdlnW=&fsHSLJVYndsrh=&LHozjWUsrVnVX=&ur3uOrUcZVVXh=&Pc2QcfZsklrUl=&hUsZGwZqfmmYh=&ieNoCrXWgiloj=&7uvKQhXlmXlri=&gAl4qvZidVlpf=&fXOwNBXcXgmsh=&YTTsEjYVcnVkV=&NjlPn9YoYjbZd=&PvCI85ZnZeViU=&3PRfdhXmseVWW=&iStmvaViqXdsq=&KePM_aWigZpW_=&mPZFnlVVeVZsq=&cVGADhUgeU_iW=&HacVzDYhf_oir=&tkcZ6lYniVfic=&jtsVsqZmerdYZ=&pEHWcrYe_VXnf=&bdEQyLZm_prfs=&VCC3xqXdeggne=&3t6fBVYloZbVq=&NR5UL6YX_jYoh=&XPjKqTXarngeY=&mcBp5zYYjkWer=&LkDgCJZggdUkc=&sVd8FwX_qqdaf=&f3hbzuUjsnacn=&yFe9j5YkpZoeX=&RQvU3zVYUeaqb=&DfiR4LZgcgXVl=&BoPk7GXdknlsh=&pOMu5pWiqdcXV=&yavNiHUefWaib=&mhM8NIZflgVfr=&AD9xHNVYZ_VdX=&OEtRVLXqeZo_b=&UygGPsVlihjWc=&3vLSJzUWooilY=&kBmY9vYhisggs=&GYWVluVhVbekX=&k38KelUnZnkca=&TxoM4tXinbXgp=&RYatOYXoqWlcr=&a_b6JhUZYsgUW=&dyExhoUh_ribh=&Ic_HrtXqVqUlj=&DgK9qmXbhgoop=&TawB3yYWhYoZr=&h89ccwUXg_Xfq=&Zaqx97WeXnYdU=&rIeuW_UfhWeqU=&htgTAXZWioc_i=&crxBfAYi_nZUh=&GVEFfiWbmYlsk=&rZNMcZVXocbWc=&CWmePSUXipqVX=&XTrf5bVYiolUi=&rjly_GViallYr=&gCNQR4XUXbeUr=&vyjOa_WccXadd=&nQ3BE2ZUbhnco=&drSEIOXpaYlnr=&DfTgBUWlgsqm_=&RIBtWDZmlbdbW=&VN_XZ8Vcloi_o=&DwYotGVZUqccV=&rgVZWQVooWeZc=&HlnusxWqXZdoq=&tSoLOWUjYnhXX=&KBwV4DUUccanm=&CPA3s2XZkYefi=&vYe7ulWVbaUWf=&HXQ6jvVUdrpjb=&nWA2apWqqddbn=&W3HNnDXYlrXgh=&Gr46N8Wq_nenc=&I4lXfJVodrbsm=&NPzgMhXerm_fs=&udte2iWVqcqWh=&OA6SqOUpZkprU=&MGEdewXWeWkjU=&tz_P5wWfjarX_=&xg7PDXWfllgki=&ZE5SEBZfqcram=&OHQhJSUqpdhZU=&XsOWlvYosa_s_=&PZwgQvVecUieV=&3S95VxWrghbUg=&_8tn45Wpr_ogl=&WKA2cwVqdprqY=&kZxvSoYgYomga=&eASJQUWbhrjjf=&Ioti8lWnVsrWb=&vFWKgRXbengbW=&gm5Fs8XZsZlUh=&2oMszoXbWk_Vg=&AiIsj9WUhaXke=&WTFx5UYYpsfbh=&P4VzVwVVqZhdh=&_nLHjJXaqdqZj=&rLnCFvYqkYWnV=&_tFKOGYpYnnXb=&72irKfWVhWaqW=&cPyJunXsYbama=&3kNA8DXaUib_k=&k_jEmpZsWnmjY=&YGL3_bZdrmqbh=&yaGaoNVrpclom=&mWxEtXZfrViok=&txQicWVWYddm_=&l6kKcWZhegoqj=&RyIoQ2VYZprjY=&IajgdTYlZ_qdj=&iiPM5JUiidVpU=&AteAWBYZqssjn=&3hVv6iXbUqVoa=&K48fqyYi_UiVl=&uVXC79UljiWgn=&NZz8SwXdVjUqd=&rj68jyUfaeaja=&GOyVKoVrsdhpX=&q5hKKWUosnaab=&DS5RrwWsYoVsZ=&abe4esUVU_kUm=&NvgZ6_YqsZkcU=&DHnQPRWZq_dfV=&tjUL4HVbahs_Z=&SCgpNeWkpkXlm=&m7ncCCUsgblag=&nTQUNaUaaepsj=&uYyK9jUroelnV=&CTcltvZmnknrj=&uCnWlMUZfWpkc=&ibMhnrUaipiea=&Yam2TUXjm_gsX=&6mP4jcWiaZeaU=&FK5ABMZXcq_lo=&IiJJqNYdiVirX=&hUdm9AYVild_s=&ULWmtDYlcVrVa=&_QXBBjWboVZrh=&UXD6jcVm_nsoj=&BkM7zHYoXWsXU=&JMqD9qUfYqmos=&_Jsgy5Vkgabdf=&KxgWTDZmmWdll=&cFmGyDX_bqfgY=&id9m_FWWXXskh=&JVsVJBXedsicW=&CmlcStXdmcohW=&vujgndUncqrrs=&x67kWgUk_YbWa=&hUYqOiWYoXXgs=&_ViFPnYbqdrnd=&_qQa8IVVaVpVh=&4DtamGVpdeool=&t37fvtWcYgcfc=&wOocXzZ_fsgeX=&nyByJTYeXVqnm=&nnwGfuWhffXm_=&dtcOGOZWpebZh=&UBdCG7ZdmmkUj=&ux9jpwXlrjVbm=&ISjaWrW_cep_o=&BMS_QhYoffVbj=&lrpJjMVsdbhfV=&SLg8RJVmpc_rY=&25MEpdWqYcbal=&G3jAAIVWanZha=&5OHnxaVpoomcs=&BZ7nQfVqakZnW=&CjrLtqVnkYesl=&xYjmmhVnmiXUj=&xYxsCqZkfcdsa=&kqWHKTYeZZdUW=&JeXINnZpfnZak=&e8_LlFVhacpkc=&AIqX2OVooWhed=&kJwWpUViq__VV=&Rrx8P9VgjjYZU=&j7NykUUjsY_Wo=&Ghc9sFWpXbUhZ=&_RM3bXYhiZdZ_=&ylSbBEYYcZfgW=&yyqPJFZgZkees=&xlvS6BYapiqho=&OvL3G5Znhfeeh=&iyyRZUUjsjohc=&XX523JUfWiUjf=&rclHVJVcrdWrU=&XhNiAdYggbder=&clWbslXs_nsec=&EX235tVrngkbY=&8D9tLGYiWbapf=&Pfk5bbYbflgac=&QBGRpLUkiiUcV=&68mQqYWqpYrqj=&coXJpAVYlf_sZ=&y9kOXDZqmWoVr=&eeB8g5XeasnfU=&_xbdZOUh_c_np=&QXbHdGVdYpqge=&vvvDTcYrdeoVX=&3_HJBcWojsifg=&RNwH2EZrqgkro=&2nHedgYmqgilc=&x8vWgOYognqsb=&2s_vquYssUkkr=&OmnsyLVhdUqkm=&xNAEdWYVaokX_=&DHdhjkUflZrcs=&xlBmJjWfkmr_W=&JWhpTwYmaqpek=&9ns2BAVYqYVeg=&lemAGzUjjYrco=&ezKIPNXrjnXar=&VGKeugUZUYXks=&geIXqLZdYldfa=&rv_gPtZfVpWkd=&ZbHfPNYYrZone=&JqtOn8VWi_lVg=&VdAstIVmigid_=&ylVqUAWUdhoel=&nPtF3jZeoqWXs=&ld6ylYX_WchmZ=&pldfeFYZWUVkm=&JdXb89XWoeofk=&kRW5iRWWsbmgq=&ZGpydKYacdqra=&Ud53LeZgoUbrc=&LOac23UhYgfZU=&GsLjF9ZqVpnsm=&brbVCoZocZ_aX=&oUAIzyXZ_nfUg=&oyagbBWipfXlf=&6ZU8VNWbUVsm_=&zTXFhfZXiZqhf=&HoJlnZUdqUgni=&G53M_gZfnfsje=&d4kX6KUsflemX=&gnUrsmWelUsrn=&laPoX2WqsllWf=&fHBS6pVibldaa=&rFtMt_YYgq_pm=&q9Ai_HWsnVXed=&hY3PdhZhUobgY=&LmNRzOWXehWqr=&6ETS7fZhfdkVn=&IFnbqNUjamigg=&wmuYtFZdncpcX=&lS39qwYfneXVo=&SMPKHOVjllspg=&8JruUZXhkjsZj=&y7tJFfWZfbego=&4JSnZdZsZaehX=&ffMFwNWpplejd=&lUuOvbZchrpnZ=&MECuyoVcXenkq=&7cA25CVXledgc=&wzMAwsYbepbYX=&BpDqwpVZklkdl=&99OYo_VeneYVW=&POe2juWshrUjl=&KMsE_xZpcjsXi=&4zN8EPWcWmf_p=&I9fG6AVqfnUim=&z2HcLXWrcjird=&BhnVYyWhmagdj=&Zcq6zbVirhpdm=&Kc6JQEZYoaZYj=&vDNuDrZopnoVW=&Fmc_itVYsijlc=&GGMR7SYoVdWdl=&QvUTKqYgqWdWk=&B54ReiZijUgik=&ZOWVK2VXmelWZ=&wR99qkUdsaihk=&cChn6sZnlhhbg=&mpo_GqXgfdrm_=&VawV8EUdVsbkf=&jhEdtDXVsomoc=&rnqsHVV_Xhmrd=&2Zg3NeYUair_V=&rmKIFYWVkhZoW=&5Q5PMyZjaibYl=&TkCIZzUfYiojs=&DAzqQIVWX_rso=&QjWeTpUgZWnfd=&MLkbjnZWcrjWm=&RPrDawVpYolei=&RBc5OQX_igXYd=&nNpeJPUosqkeg=&tSeY9TWcihigq=&mWjQNoWdsqem_=&4dkPfqY_ci_ip=&8wquhtWVqlgso=&7YKHhPYadkhjr=&gA9xpwUfeWjqd=&QXgLIlUsrhfqh=&CG5RtEZUgshmX=&wy_GCjWeZmWod=&2fqVMxZbdmUe_=&QfXlS5WbUqlpp=&iOQEJnZnYmdqm=&XpTsh8YfkXgrf=&VTNJMCWXggmfd=&viXpkWWVgpiXh=&hDpnsxWbmqgWX=&AXw2NbXlsklcc=&jRVTAgUVegn_Z=&lT4dRaZkadaeY=&qnttHmUoWUejY=&AMejFzZUcoahm=&9FiFhcVmZgopd=&vnvkeaUWVpmWi=&Iq6atnXYqUhnr=&Gdr7LFW_qfahZ=&4859CDZ_kXgkY=&WmoV5wYabnkfh=&FXeIURUaZZqbj=&jrliu7WmZdncV=&9keyYJXhZgpfd=&QqqkPiVWVpjki=&7b_OKrVgUqiaa=&Se44Y2XmloUjr=&utAskHXUrZadp=&OUwnBvVrqepoZ=&QanppmWdlffeo=&3FGpKSYfcXkbW=&xcjEP2Yhaaqii=&d5goKSUjffYbY=&swFtpWWjZrjqe=&2p42aDUnjYWak=&WU48PJZmbUscl=&EVw3YOWajfhpk=&76WEJ7Vlk_rfr=&nGnyUaZmrhnqV=&FSLCnZXkmYYeU=&wVhDDpZlY_XXY=&eRw9_nUXipUVc=&DnsIExYmZjpgh=&ojdPfwVocoXYX=&eM6U56VdbnrpZ=&GDqvnQXidmmnZ=&hUtkKjVnlc_Vc=&FS8rIpZXdprkk=&rXIStlVfmVXUX=&DRnhGUZms_Vmf=&6GtErrXqi_WZn=&JnsiwRVfbpeqY=&xKVUXfVdYlX_b=&QZJYCLU_ZcZpd=&wc7pG7XaYregs=&s_2rClVkj_YUU=&kXJw6xYglgcso=&8nqSfFYimieYr=&PL5tNiXejU_oX=&97NwosVVhjfgh=&6w3hD9WhplaXi=&zMAIyrU_Vrgan=&MXEmUEUbskZnV=&Z8aQBHZhffbXr=&22ehIwZolYhmr=&t5IZVAXZhsVdr=&bDo7AIUqggbrX=&SozIbjXobagVr=&3xdpxjZjjg_oZ=&lpUQKCWbqUpbs=&WvJuCDUmegbkh=&mzqhVsUqphekU=&7OmdTZVZ_laWV=&CgttmLUscrUcX=&Au4wjtWcqcgm_=&Tlu8RXXZ_nppl=&RwnHMUZ_leYkq=&ywEL6wVfaoqiV=&VMmrlpVYUimfj=&pe5gGYUfhqZl_=&qxj6LxU_o_hoZ=&nTSPgaVUkacV_=&7KPBUiYpZroma=&BSHEEtUencrbl=&MXvKdnXcXdkXh=&E4DMJ_WlUp__W=&zGqNYQW_baefd=&K2MrOOUblnVWV=&YJCZVKWsWjjUq=&qMHDyTVfoXseX= diff --git a/src/test/resources/issue72.json b/src/test/resources/issue72.json new file mode 100644 index 0000000000..428d30ef56 --- /dev/null +++ b/src/test/resources/issue72.json @@ -0,0 +1 @@ +["CgYIARABGH4Sxj0IBBIEdGVzdBoIdGVzdF9hbGwiAUkyEQgAEgJJRBoBMSABKAAwBDgBMjUIARIHQUREUkVTUxogT2hLdlRId2ZsSGdVeGlPWE52Tm9xVXRQT1B0clRyR0YgASgAMAw4ATIrCAISCkVWRU5UX0RBVEEaEzIwMTMtMDgtMjkgMTE6NDY6MzYgASgAMF04AToaCAMSC0NIQVJfVkFMVUVTGgFwIAAoADABOAE6LggEEg1OVU1CRVJfVkFMVUVTGhM4OTQ4NDA3MTAwLjIwNjMxMDg0IAAoADADOAE6JAgFEgxGSU9BVF9WQUxVRVMaCjAuNzczNzIyNDcgACgAMAc4ATolCAYSDURPVUJMRV9WQUxVRVMaCjAuMTM2NzYwMjMgACgAMAg4ATomCAcSDlRJTllJTlRfVkFMVUVTGgEwIAAoADD6//////////8BOAE6KwgIEhFUSU5ZSU5UX1VOX1ZBTFVFUxoDMTE3IAAoADD6//////////8BOAE6IggJEg9TTUFMTElOVF9WQUxVRVMaBTMxOTcyIAAoADAFOAE6JAgKEhJTTUFMTElOVF9VTl9WQUxVRVMaBDEyMzIgACgAMAU4ATolCAsSEE1FRElVTUlOVF9WQUxVRVMaBzYyMDkxNjcgACgAMAQ4ATooCAwSE01FRElVTUlOVF9VTl9WQUxVRVMaBzIzOTEwNDcgACgAMAQ4ATofCA0SCklOVF9WQUxVRVMaBzM3NDU4NDEgACgAMAQ4AToiCA4SDUlOVF9VTl9WQUxVRVMaBzYzNTczMjUgACgAMAQ4ATotCA8SDUJJR0lOVF9WQUxVRVMaCTYyNjI4NDM4MCAAKAAw+///////////ATgBOjEIEBIQQklHSU5UX1VOX1ZBTFVFUxoKMTMzOTIwNzIyMyAAKAAw+///////////ATgBOjAIERIPREFURVRJTUVfVkFMVUVTGhMyMDEzLTA4LTI5IDExOjQ2OjM2IAAoADBdOAE6MQgSEhBUSU1FU1RBTVBfVkFMVUVTGhMyMDEzLTA4LTI5IDExOjQ2OjM2IAAoADBdOAE6IwgTEgtEQVRFX1ZBTFVFUxoKMjAxMy0wOC0yOSAAKAAwWzgBOiEIFBILVElNRV9WQUxVRVMaCDExOjQ2OjM2IAAoADBcOAE6HggVEgxZRUFSNF9WQUxVRVMaBDIxMDIgACgAMAQ4AToeCBYSDFlFQVIyX1ZBTFVFUxoEMjAzMSAAKAAwBDgBOpoICBcSCkJMT0JfVkFMVUUagAhQLjsmdTp1KC1DV3hieFdDQkloPlpIYiVxSkNWNW50W1RKOVV5ckVkRmxhKCMuSWR+YmkpViBNN1lVdTJAJ3ZMWDgwcnczLUEkRTFoMjFvbHNnS1tuIydzaUIteEJVVW9GYmVYJiMsYn0gOz4pKUd7KHUmZDdgMmAzOHR2JFdGXT4ld3EhIlg3XU50YWIyeWtJdkl3TlVsKiIvMlE8QWRKITQ9Q2ZRN0VHMFpzXUReRiBMTVlhOkUifXwkK1ZHM0FqRClOMjtUfihkXmIyayB2Tk5cdWVrJnZ3UEA4YTZDJTF8eks+P246O3lcdUE/ciF5NVpyQ0QgJGh7eVBsNElBdj1lJElEfEIoRUNEa1RVZklEZjFqPFkiPn4lVSsqRmpEeHQlN2JdPVhdWiIsRnEpLyoifkI0Q2cjKGFGPFVRfllkcTYmUU5BPUNQRi0mIyZHZl1aVkJBLjpqMzwhLGp+NjAnKHNPJiYjNE4tNXZ0WXVXbi0kLiJSUXhBLCZXbDxCIHI4VER8WzA4REFjU2dlKFlnICx5MylEdyVWQFFsbE5jPlhXMENjZVUxVk1zXVd0ZFNPNXcqTzoueTR6OjFsfjdXcENffHVaKy1gXEIlJStKJHltQEVxfTVIL2o8a0l4LkEuJV43TGx1PU8mLy53XHgzNzVlXHFyOksmKlwhQ0Y7fntKMiRuWDlaN0tPY00qPmd4LlFRKiI8Nmokc18rIjhHenh0ZilpXCdnICQqMEldcEVlb1J3Ilc2YG1OTUgwTng2QHJTaS5NclBTSEZBaHZyalQ7Tm9eeTIpZDJJJjhxalZiLjIhUzpMSlNgPCE3XiA2NDc+JDQyUX05KHAuZS5IJTNEOkBRNUpbO3gie0YlSkVeKiFCZk1qQWhfLWgzcnZWXixaIj5lVVAxLVVTMS5rWjlwWyJ2Y0h9JkxIVzp9XWlTWStZZ0xGOiViPydWTFdBU2k2PnNxUXp+eWlKSXtEcUZmKDMtWUFlVElTfHdNaH5gTEpXWFV0UFhSN3JeeGQlYXR3KDQ6LS9vTWk0fWU3PVhsUkg9R0RfO0dmJS9yWWE1YXV+MjxVb3UzO2BRelcnKlUqOE1HMX5zfVAqZyZMZHtyZ05jOHpBXz1tclY6XToxVFZsX0dQUThGSXhOWkBRPW4yTndab3RGIE9LSnhDU2NrJTgqZUFXPml7L2YmW1tnPTw+T1I0NHorJzUzNFg9KSZ8MzRERWUmLCVVWkBrXUAqXT9vPCgqQFJSbH0ldydEPDswWmw2VT5RV2sgTm5lKEdJeH5oV0E0RzxweWNUPVhlTCEuL2N5XEtdWF8hUk8+Ul0xKTtAXWRcKHZcJEtXdFhjIlx8RXJKX08uIAAoADDUDzgBOp4CCBgSD1RJTllfQkxPQl9WQUxVRRr/AW4qL0k2IDNzdzZGaiE3IScqeVone0VmfHsqRi09fUJbY3F7MzF2J3A2ayVRfjQ3IVZCVEp8STpfTWdheiNxI1ZXJnUzLjUjKzQ1a00nX2tNOl8oVGRML0tWLSEnWyJ8ZzVgbjc5MmIuIk5VImJhflBmfkhcYnJ3XmAkI29lSj9BISJRXSh8Vj82M2UxdyU/amJNVF05MzVsTid4T3Bzc1hnajFnJDUxO30pRFJaPm9wOzQoL1JCeGA6fV8kdEQ2byJCOl9IJ2AldkhIXzVraixDSHtzLmQ8WHk1ciVTal5pflNTSmJOLEZzTE09fWs7YF1FeipXXUorL0o3N0VrJCAAKAAw1A84ATqgCAgZEhBNRURJQV9CTE9CX1ZBTFVFGoAIMTw8XjUrKHJ9JG9WX1pKcE84O3ZpalNJWUFhaDQySkdcdVAsUnF1VmFJV3p6KyUnWWwkLit7QidAeFZsVWs1V1AvIGVqVUNAeWR+Wz91JDRUa2QvUl1kWWpxdF4uKSptZzdXYH1lckU8aD99SGtBZmN2T181O0d7fngyMjRBdGJAbWQyXVN2Rjx9JD9yTSVGe21BJjc9JTokfl97cHItflh6UX0lRyFoXC5lcFlkTV1ETFJPIEJzLWo7fHwqYzkkNmxALWY0KXpJe3skV1VCaCozWk5iWDlrRSR7JnYuIS5sNzlURV8rI15UYjZIZkhmKSk2RjwzMitEQU0vcC18TSMrI2xPNEl8L2B9czZLWlpsIV1cPXM6UC58KkJtKmlQVkJkS3s5UC5gSWM9RCBqXUY2N1clZFI4IVo6eEhtUWJZenxtbWIvZzA4dz1GXT8pUmVGeSh4d25jJWx+NW1XXm9hOD9VdjZIRThJdn0lfVEuWzg/ZWtXLFFzQUN4alxiPmo7MGsjcGV4Q0M8IzZjdSRoYStoYHQ3Z3hwXyRCO2N5MFFIXmV7XytPR1psd15HVkAoPFdGKyZ0SCp9cyd1WkNjJ3IqLlVAZT4wNipaPmBwRmlkMUJxZjhiUmhzX2siYDFZekVTRlQ5XXhUUHNYbTdmdk5iLzxzcmhGeTlDZU9qJTtQNm57RTdqQldvQDczQUpeYml1JFBFVSFgciJ8fTovM1wpfCEkK3AnfEwgOVZKfnMqWyxqanpOeCpNUU1yLSRvREVOcjp1NiBMbT9IO3dxOjxmTWFdJUQ0XlRTUjZqNE1gVjppSmZHR1MnRl9fZlpnfCtgTHZOPmdec11pazArLlszIyF6e0lnZGYtNFBQd09EaUw6WipxVTspNFBwfC1MXC1sQjg+aUVLMT0ob29SJ30ydCxWKkY9aiouRSQiInFeOC0pWEpHL2xuaDVVLkRRUXxSQjpPWFAnelRSM21QXCNXQ1BoWFlMNmBiSGlcdzJ8J3NXL00tPWgyUm1pL1JedClTcCpfKFNaRUpVTComUiNxc0h1IFpdSjhPcFIkO2RmVkJYOlhFKjlAfmg6W3IiWDtdey8wXj0tSVxsdEErW3M+c2I8YCYwdFlxck99Sl1TaSoqWnAmdlopUC4+MjhofiJBWkBWc0EmMjttIjtsXGpoIz9BcUYtOiYnQkp5N1Q5NU1LbT9qOD9ARDVyNndxRmNzUyp1RiI6VGkmR1o+UjY0eyxGUStAU2Q9MCo5V0MrPSY/RGAjeyNEJmZXPUhvUjtfQnkqTnRPdCttImpmYXRvLjVEbzQ1fEF9SnJ6P3ZsU3ByVi9bSE5kNT43I0Umal01TVMjOypyKDMuNiAAKAAw1A84ATqfCAgaEg9MT05HX0JMT0JfVkFMVUUagAhWenhbdDZZPXB0c3E/emNOY1d6elU7VXA6JUg9Y31cVkFTZjk0Z2RBdWJUUzJ0UEhMI15YP3UrMj4tamZ7PmB4W3FPZmhyPCtTbXkpOT82KiJ9bG5DeiFyVlVcVX0kMHktUkNuSy0uNjogfiFnUzwgSW1+fWJoLyhXT3Qseks6IiViblJ8TnEnS3NfcWZyPE07JlN+OUgsLEEsIDZdMEIqezRBI1hubUh0WlNATjBiQC5tWlJ6KzhpeFN0MEUiXShBO1VPNVZXaGlULCheIW5DNXQtdmJOLm5PLHVzT2AsOGkzQ1ogJXlzd3U3ekYrYXxFN2FnI0FHIH5aT1lnc3lSdWtRZVNJeEs2OXVjImIsdm1HLyJSRlUjSClOel15N2lfYG8wODY3WzwnJ2U8WCpEW3xeOWx8Py04O2soSDN0b2s+NjhJdipSVSdOc31wcCo+J3A1OShvUm8lWGB0IDxcKiFHVlx1RSFCWl0zTmpBYzwhZjdYTERXcXhKRDpsbHs8QSN0Ty5hO1d4PjRRUHZ3eXd+S3ZhPntsd0NnVEksUGd6bVArd0xTPUhHXG0jU0l+UjxaUVgkKkFffE99e1g/OVglfml+cGIgZF1sI2AiSDxsX2ZZZUUqe0NtYjU2LmY3TyRFMix3NlRwLGpUSkdXMHVfOUFuNWYvQ08sOTxCT3YhenstM0JxKilya1cpLiNce0wuIFMlbDlUKnU8TTZiTF1PR087ZztdMFpVK1omY2wxIFpANkBmYi5GWU4ucl5nOzhIIUo3Mi9yI3kpTFFMZ11oTj50RFBWWklZMVVoSWRxZm4mZWN3eSxCPlBpVHBhWXBEazMpdDhmXmNMa1JxLS5tMzhmR0c+U3Bcc2VGSWY8WVlLZFtnb3lrSi1Ab1lcLDBqPy8uMjksLHFBbW58XFZDXzEpNHdtXnooaUlVI0xLQSZQMXA0ayY9JUF9biBLXDNbO01AL0IkT3A6Imo6czA7ay5tXGwhJHc5dyojOilnPyQ5NkJKPXhQUWVrTGcxJlgzPntUYS50UFw+fm1sYEFUbkA7c1JDTEc1YVctb0hzYy8xUkMqL3krT2Z8eUB0V25NZitjbHtuZ3hIa0hWXD1FQTs4RFt+Q2FgeWhZeCtcQT5jXnlBZCRxaXw9PntpcS4wM1g1T35OeWUjIldhU1Z2VnYrOkwqLFc0LlVTSklCKnVWKFFGZiBJSlFOQVspTXpQJj5dNC08QCkmZj4mcl1tYEc1YyBkK34+dTBEXTxXZS1pb29FdjtdU3JRYVt8RkxPRFRdYG5aRDAmYGVnflgsIjtKWXQ9NjVcelZxdV9fdSR1I1AhUXhCZCxCOEN+ZGIlJFN7I2QzdXY7fTNGIAAoADDUDzgBOpoICBsSClRFWFRfVkFMVUUagAhmeFdrY3pUckZJQXlNUFNiQ3VYR25naHNqR2liVXl3U1BCb2tCS1h2aFdmbkVHaHliU3VKbmRrWERuSmhHQ3VFS0xCV0tUR1BZS25Uc2RBVG9LTnZtVmZDZmdPS1dxQmRnSEVVc0lrQ1pEWGRldXZvcE14RVdGRnVpaEVzVUF0SUpXb0d5bHdCVG9LZ3ZpV1NvcGdBTmRhY2ZQcEhTY1NreXFzZmhhdmdhVkVZZ1ZrcXl0QkJKUEtGUFVWekdWWlpFRXVHTVh4VGVDRkZraG9wSnVuWFNwTmZPbldjZXdQQmVaRXREelREd0htYXZ5WWVBb1FOZFJPWWhPbER2dlZWYmdyelJlV3RJQnVHTEJicW5MTGRmTkJnV1htd0hXZUVFYWp5QnprT0VLVHJBZVZxbWJQQVVUQXRsQ29jb2tuQnFnRGNxbGVZSW9sUWFobmhLUlJqYmhYTEhyVWtaYU5jUGhxZ3lITVhFWWpzb29CeVpXTHRYalBnU2xLSldTZmJYaFBNSUZ2Y2dRZWVKeGZsT0JxcHVKRnVnUlBXU3ZKYWV6SEhld2hlVldqYldETWFoUk53UVVDU3hNdW1ybXJndWluaWtVb09reVJmWkJPaHNFWXhUbWFBY3lVbmVERGRsbmROTHdxUnlZYUtTc2dobE1MUGNUenhGSE5wUlVLSER6eVVIZUN6Zm11TlNtYmtrVU1DR21WY0VIaVhHVVR0eXdNYU9Yc1hxaEJadlFoSUdua09kUHhSTFlZVFVDS1VWRmV1WndTV2h1dnpWVk9ESmhydkpZQ0RGWnluVUJCVlFRUmJPUUVxQnVyekN6cklWREFnZ3NFWUJsVGV1TUlLQlRGaGFQZ0ZlSmNib2NscFRNRFR1ZklsYmpjTlB4Z0hzSWVLZXhwdG91Y3dNQXBVUHlJTHFSVkpZa2dDeG5QT2RqS2JxZWxLZk5meElTT2hqSXRDc0dTTUpkaFpuYUxOV1NGa1BNdklPVVBNUEl2UmVhTWxyV3h5SW1DdXZyQlFBdlFTRHBjTURqU3RjY05Gd093WEZZZERXWlhudHpNemVoRmdjbXpvYUhOZU1wcWNVRmR2WVhDekJ3QldlS2xvS2R4T2RXamFNQnh0ZWN5bWtFS3dpQWxQTlpKZXl1SlZDbXJQTXlCUVJVb0VvS3dZaEV4SUJ3UXFDaURsV1JRdnBHUmJrbUV1eXdSZ3h3c2xMYmZFU0NmT3BDVHNMUWVuUGR5cUxpUlpyemx0Z0RzUHJwS0VIaW9FTUZqSVdSdUxFVXVlSXRHbXJTRUVUTm9Teml1eFp1SU1MTlFaWVhubU1HQktXeG1ueXZzUUN5YlBqY05sVEtwc0lBbVhhbFNDIAAoADDVDzgBOp4CCBwSD1RJTllfVEVYVF9WQUxVRRr/AWd1ZGRoQUhZSVlCYXlsU01rbXZqd2JMU3NxbkdNQ1dTQ2R0dXlGUkhldktBWHNvamRFYnFnRk51dWpjZWlOeXNhekR5S3J5dEN5eW56ZnNJVWhyckpVRW5Ic0ZhR1BKdFRZckZudGdsSkVvcHNIeW9JTkhqTFVLQnFXc051YmpwUFFtc3BBZ0Rxa3RIQ1pCenlDVVZQVERlSGJpSnpVbnVTSFZsbnRzU2hLTGNDSGdWcEhuYnhOZkZvQlRDblNOelB0SmhiVHF2V0tKQlJ5WHdrblJlemtRR0RDeWFQVnRHbkhsSkRYeldveHJsQ3pWSlFzYVBkUFV4bE5obE5YTyAAKAAw1A84ATqgCAgdEhBNRURJQV9URVhUX1ZBTFVFGoAIWEliVGJxZGZrak9RSERCQ0xvUVh1UEViSkhDcmRVRkdZRElQSmJueElWdWNYVUxnQ0RIZGlRZmV6WkhlS3BzdlFjd0Z5Q1hlT29lQlNRd01PYVFqZExobWdCYlJWdEpmQ2tPWGN0dmNZak1OdkFZS0RCcW50TExkbnRpa0Z2a0VXelRsZXpBenJhUkRCUGNoS2loZVNrVVpJUUFqQ25BdGp0c05rRExOYU9RQUR4WWJabmJ0U09tbHVZVndienVwSWtCcnFaeFBUdmRlV0NHUHdxZ2laQnhVa2NZU2JHTUV1RHFsclhWYlNQTkt6bkVXcVlqQUVaWE1RekVEQ25IQWpueEtZbGFTWEpPU0NMaEVKVmhZa2dNZUhZbmd3SUREdVlaTGtVYnNNY3huRnVPWXlVV2NVY011SWJidEVqR2NORUtwQ1RhWlRDendKYXRhV0toSk10RUZ6T0tPY0tlVG9pRmFPTE9zVVVBWkRyUlF4UmFVTUxPemRUbmhFT3ludHhRZnNMaUlkRnRjZlVSQUplUUhyd1V3RWR3UU1NeWViT2pnTnlWcGRDcnVJdHJYbW9SQUNBWWhudEhYS2lhZkJib2lkQ2dPcEhjaUFPY3Fud2tWWEpnSWpCRklrS2lpVEdEdG1LY2NITm9LUUFrQWpjTmxkb1FyQW1NTExSdVZhY2NCaXJlRGN1T0VoR1JDc0F5RnZudkV6Z3dkS2h5T01GYldFbWdHZ2VXbWxXUmdqU3FpRVZDWEliU1dCYVlrRGRIWEJZanFHVXloV2tiekRKTFdsdUlXcG1LT1hsd1pzeFVXZ2RmSkZOVnV5VWFTYWx3VFRBREVuSnRIbkNCbGhiSHpLWGtMVXJJd1RMUE9oSHJHSmpNVXpCQ1JrRUdzbWlta3VnSWpWeW9vU3BhenFXaHR6Sm5GekdLR2FXRm1IbVdJSFFLSW12c3RuVEpkbWhnTmZxaHNCbWpvTkxReVBEamNlQk5UU0hCaFZmamVrbGNtTFZ2c2dlV29JVVVxbFpXUWZDbUhobFFvaHREbFpYQVdNR2NGSWtGZEh2SmdXTHJrTUpKZHZ4bW51ZUp3SnJrS2ZSQUFQSmlKYWxhV3V3ck1NdllKTUNFT3JQREZ4b2NBVE9yR1NwQWZPZENKb0RHUnJCR3V4RXJraVRkU3Fyd1V5bER0a2RIVWdjV2J1TlRHakRjd29PVUR2bnZ4dnVZd0RmemhXU1dCSlFhUWJUQWhRcUdQRnJJYnB2WGFtZFZnZnpMVmZ2YnJEVkFWdWxaSVZSWlNaVE9WY1ZtVFBZT0dLTHhHTVRMcmViQVdQSmhTQUN0SFpCZExZQnZTYU1PaVdYRFRBbnpwU3FYVSAAKAAw1Q84ATqfCAgeEg9MT05HX1RFWFRfVkFMVUUagAhMU21lY0tJbWlUaHl1cFpOYllOVlZxalBteFdJc2tmbk5telVIZ0RFU0JLdGF1R0ROY0xMZFdWTWdoZ2RacEFZYU9xRkhUdGdHRlpMS0ZNZ0drWk1ZYlFlTnFSaFhEeldCTU11eEJQdW9VbGRRalRheHZlSlFla0VZZGtkbG9uVHRyQ3puSkl4bEJoUVVESHJVU2dYVGlOdVFwYlhiWGdFQlhEUWZTY1RNeGRKRkptTlhWT29Ha3hjbHhHc0ZKQ0Jkb2ZUdWJnRkFDUGdNdm1Hd2RPWkNzTFdOUGR3aFRMcGFzdmxwdGpRY2FTUXJMeklIUmtaUmZacXhqd3BoRmVPemZtTHhiR3VSSEJET05oZW1BSWx0UlJDb0doT25CQ1pRd3ZVaGJLRk1sekFxblJnYWNsTERpdWhsS29ZSFdOaGp3WWZLQWJ4RWxwZGxVTVVtSm93d1BSc2V2RHdXSExUUUNPS2N5QURYbUFNTnBWcGFVS3J2RUFUQnVWRXNWUHRpZVdnVEVoY3NRTmlBclduVkh5bFBtY0R3VFVUckVlb1NzeEJFU2tTYWVkU0NMWVZPb2pvSmZpbXpsdEZ6T0NIcUxxdUd1RkFkeE9jWVVqQlhJdFRGTWp1QnlEbE12SnF2V2VTa2hGWHFQYlZEY3pZd2ZSbE1Kd05ZdGN5Q1FQYW9ZaXNZSnZvQVFaVXRoZUlWSUJsb0doVXRtZ3hlVllOb2FLU2lxUkttSExkVFlYZ3BlQ0VnTlNUYW5oak9vWGpkR05uVkx6QmdoTEVOU2pKYkZJd2FxcFd2alFHY21jR091cnRjcHZYQWhEWVh6RldMemNPUVh4dW16TUJST0pNYkdSZUV3QUpDc3BOS3pycmxjbnRhd090bklnZENuenZJWlNYU255QnRHb0Z2a2xRcktQR3ZDT1hoV3pnenVDV0hSZ2hqd2lKbEV5YnpnVXZCdGZJakR2Yk9RdmZLdG5WVWlkUVdxQkVYSXFUdVlnVGh4Sm1QdXVOSml5VElhVVJvYldXVWdmcUNHWVdrWENCWkJxQk5GeFJkamRQcEV3VnVtT05FTWljd0RWTUJJemdYQUhOaEt4amRUZUJaWWx2b1VFRXBadWtzRnlqRkhSc0xFSndlRmFpd0FWVENwU3FLQUtkaFZaS1pTTlNhTkFSUWltY3NVcm5pSUdWREpBb1N4VmhaaVhUTFV5TlFvSlFjdUNjTkVZRFZrUEhia3plZ3FEaWZvaVJHdGJSSGJTWWxXVGdiZklvdFhwWXltQ1VVbUJXVkF5c2tzTktsR2NRU0JHUWtSdGlLWXNBQ21aaXREblNNYnN0SHN5Q2xFSHlNdXZIZHdLY2tqeW5VZ2l2IAAoADDVDzgBQOCauMGMKEj///////////8BYLA1aAA=","CgYIARABGH4="] \ No newline at end of file diff --git a/src/test/resources/issue74.json b/src/test/resources/issue74.json new file mode 100644 index 0000000000..d80aa93855 --- /dev/null +++ b/src/test/resources/issue74.json @@ -0,0 +1,45 @@ +[{ +"dataType": { + "categoryType": { + "dataTypes": [{ + "$ref": "$[0].dataType" + }, + { + "categoryType": { + "$ref": "$[0].dataType.categoryType" + }, + "id": 6 + }, + { + "categoryType": { + "$ref": "$[0].dataType.categoryType" + }, + "id": 7 + }, + { + "categoryType": { + "$ref": "$[0].dataType.categoryType" + }, + "id": 51 + }] + } +}, +"type": { + "$ref": "$[0].dataType.categoryType" +}, +"version": { + "available": true, + "id": 6001 +} +}, +{ +"dataType": { + "$ref": "$[0].dataType.categoryType.dataTypes[1]" +}, +"type": { + "$ref": "$[0].dataType.categoryType" +}, +"version": { + "$ref": "$[0].version" +} +}] \ No newline at end of file diff --git a/src/test/resources/json.json b/src/test/resources/json.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/Bug_0_Test.json b/src/test/resources/json/Bug_0_Test.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/Bug_1_Test.json b/src/test/resources/json/Bug_1_Test.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/Bug_2_Test.json b/src/test/resources/json/Bug_2_Test.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/a.js b/src/test/resources/json/a.js old mode 100644 new mode 100755 diff --git a/src/test/resources/json/group.json b/src/test/resources/json/group.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/int_100.json b/src/test/resources/json/int_100.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/int_1000.json b/src/test/resources/json/int_1000.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/int_10000.json b/src/test/resources/json/int_10000.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/int_500.json b/src/test/resources/json/int_500.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/int_array_100.json b/src/test/resources/json/int_array_100.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/int_array_1000.json b/src/test/resources/json/int_array_1000.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/int_array_10000.json b/src/test/resources/json/int_array_10000.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/int_array_200.json b/src/test/resources/json/int_array_200.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/int_array_500.json b/src/test/resources/json/int_array_500.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/maiksagill.json b/src/test/resources/json/maiksagill.json new file mode 100755 index 0000000000..08e7c15928 --- /dev/null +++ b/src/test/resources/json/maiksagill.json @@ -0,0 +1,4 @@ +[{"houseArea":"3.00","images":[{"searchImageUrl":"img\/ibank\/2011\/699\/163\/470361996_2083754467.search.jpg","imageUrl":"ibank\/2011\/699\/163\/470361996_2083754467.jpg","bigImageUrl":"img\/ibank\/2011\/699\/163\/470361996_2083754467.310x310.jpg","summImageUrl":"img\/ibank\/2011\/699\/163\/470361996_2083754467.summ.jpg"},{"searchImageUrl":"img\/ibank\/2011\/399\/163\/470361993_2083754467.search.jpg","imageUrl":"ibank\/2011\/399\/163\/470361993_2083754467.jpg","bigImageUrl":"img\/ibank\/2011\/399\/163\/470361993_2083754467.310x310.jpg","summImageUrl":"img\/ibank\/2011\/399\/163\/470361993_2083754467.summ.jpg"},{"searchImageUrl":"img\/ibank\/2011\/689\/163\/470361986_2083754467.search.jpg","imageUrl":"ibank\/2011\/689\/163\/470361986_2083754467.jpg","bigImageUrl":"img\/ibank\/2011\/689\/163\/470361986_2083754467.310x310.jpg","summImageUrl":"img\/ibank\/2011\/689\/163\/470361986_2083754467.summ.jpg"}]},{"houseArea":"","images":[{"searchImageUrl":"img\/ibank\/2011\/699\/163\/470361996_2083754467.search.jpg","imageUrl":"ibank\/2011\/699\/163\/470361996_2083754467.jpg","bigImageUrl":"img\/ibank\/2011\/699\/163\/470361996_2083754467.310x310.jpg","summImageUrl":"img\/ibank\/2011\/699\/163\/470361996_2083754467.summ.jpg"},{"searchImageUrl":"img\/ibank\/2011\/689\/163\/470361986_2083754467.search.jpg","imageUrl":"ibank\/2011\/689\/163\/470361986_2083754467.jpg","bigImageUrl":"img\/ibank\/2011\/689\/163\/470361986_2083754467.310x310.jpg","summImageUrl":"img\/ibank\/2011\/689\/163\/470361986_2083754467.summ.jpg"}]},{"houseArea":"4"}] + + + diff --git a/src/test/resources/json/object_f_emptyobj_10000.json b/src/test/resources/json/object_f_emptyobj_10000.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/object_f_false_10000.json b/src/test/resources/json/object_f_false_10000.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/object_f_int_1000.json b/src/test/resources/json/object_f_int_1000.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/object_f_int_10000.json b/src/test/resources/json/object_f_int_10000.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/object_f_null_10000.json b/src/test/resources/json/object_f_null_10000.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/object_f_string_10000.json b/src/test/resources/json/object_f_string_10000.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/object_f_true_10000.json b/src/test/resources/json/object_f_true_10000.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/page_model_cached.json b/src/test/resources/json/page_model_cached.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/string_array_10000.json b/src/test/resources/json/string_array_10000.json old mode 100644 new mode 100755 diff --git a/src/test/resources/json/wangran.json b/src/test/resources/json/wangran.json new file mode 100755 index 0000000000..d8efe2e075 --- /dev/null +++ b/src/test/resources/json/wangran.json @@ -0,0 +1 @@ +{"curMsgs":0,"description":"amq","ha":false,"id":36,"machineCount":4,"maxCurMsgs":100,"maxRedeliveries":6,"modified":1323141659754,"monitorSpeed":false,"name":"test","physicalQueueMap":{50:{"id":50,"inRate":0,"machine":{"address":"10.20.165.59:61616","description":"amq性能测试,请勿使用该machine!!!","id":10,"ip":"10.20.165.59","jmsPassword":"napoli","jmsUserName":"napoli","jmxPort":1099,"modified":1318559383989,"name":"10.20.165.59A","port":61616,"recoverLocked":false,"recoverable":false,"slaveAddress":":61616","slaveIp":"","slaveJmxPort":1099,"slavePort":61616,"state":1,"supportHa":false,"useSlave":false},"modified":1319617727839,"outRate":0,"queue":{"$ref":"$"},"receivable":true,"sendable":true,"state":1,"weight":1},52:{"id":52,"inRate":0,"machine":{"address":"10.20.165.59:62616","description":"amq性能测试,请勿引用","id":12,"ip":"10.20.165.59","jmsPassword":"napoli","jmsUserName":"napoli","jmxPort":1199,"modified":1318559325754,"name":"10.20.165.59B","port":62616,"recoverLocked":false,"recoverable":false,"slaveAddress":":61616","slaveIp":"","slaveJmxPort":1099,"slavePort":61616,"state":1,"supportHa":false,"useSlave":false},"modified":1319617590078,"outRate":0,"queue":{"$ref":"$"},"receivable":true,"sendable":true,"state":1,"weight":1},54:{"id":54,"inRate":0,"machine":{"address":"10.20.165.59:63616","description":"amq性能测试,请勿引用改machine","id":14,"ip":"10.20.165.59","jmsPassword":"napoli","jmsUserName":"napoli","jmxPort":1299,"modified":1318559388699,"name":"10.20.165.59C","port":63616,"recoverLocked":false,"recoverable":false,"slaveAddress":":61616","slaveIp":"","slaveJmxPort":1099,"slavePort":61616,"state":1,"supportHa":false,"useSlave":false},"modified":1319617591562,"outRate":0,"queue":{"$ref":"$"},"receivable":true,"sendable":true,"state":1,"weight":1},816:{"id":816,"inRate":0,"machine":{"address":"10.20.153.62:61616","description":"陈海华专用","id":2,"ip":"10.20.153.62","jmsPassword":"napoli","jmsUserName":"napoli","jmxPort":1099,"modified":1317369126743,"name":"10.20.153.62","port":61616,"recoverLocked":false,"recoverable":false,"slaveAddress":":61616","slaveIp":"","slaveJmxPort":1099,"slavePort":61616,"state":1,"supportHa":false,"useSlave":false},"modified":1323141659754,"outRate":0,"queue":{"$ref":"$"},"receivable":true,"sendable":true,"state":0,"weight":1}},"pqMap":{"$ref":"$.physicalQueueMap"},"receivable":true,"routerMaxThreads":1,"sendable":true,"strategy":"round_robin","type":"QUEUE"} diff --git a/src/test/resources/json/yannywang.js b/src/test/resources/json/yannywang.js new file mode 100755 index 0000000000..153fa1c756 --- /dev/null +++ b/src/test/resources/json/yannywang.js @@ -0,0 +1,62 @@ +{ + "description":"","id":1336,"modified":1318310632121,"name":"NapoliClientTest","queueCount":3,"queueLimit":0, + "queueMap":{ + 12109:{ + "curMsgs":0,"description":"","ha":false,"id":12109,"machineCount":1,"maxCurMsgs":100,"maxRedeliveries":6, + "modified":1317290675999,"monitorSpeed":false,"name":"NapoliClientTest_q1", + "physicalQueueMap":{ + 12125:{ + "id":12125,"inRate":0, + "machine":{ + "address":"10.20.144.81:61616","description":"","id":1, + "ip":"10.20.144.81","jmsPassword":"napoli","jmsUserName":"napoli","jmxPort":1099,"modified":1298964982516, + "name":"PT-10.20.144.81-A","port":61616,"recoverLocked":false,"recoverable":false,"slaveAddress":":61616","slaveIp":"", + "slaveJmxPort":1099,"slavePort":61616,"state":1,"supportHa":false,"useSlave":false + }, + "modified":1317290675999,"outRate":0, + "queue":{"$ref":"$.queueMap[12109]"}, + "receivable":true,"sendable":true,"state":0,"weight":1 + } + }, + "pqMap":{"$ref":"$.queueMap[12109].physicalQueueMap"}, + "receivable":true,"routerMaxThreads":1,"sendable":true,"strategy":"round_robin","type":"QUEUE" + }, + 12110:{ + "curMsgs":0,"description":"","ha":false,"id":12110,"machineCount":1,"maxCurMsgs":100,"maxRedeliveries":6,"modified":1317290689942,"monitorSpeed":false,"name":"NapoliClientTest_q2", + "physicalQueueMap":{ + 12126:{ + "id":12126,"inRate":0, + "machine":{ + "address":"10.20.144.81:61616","description":"","id":1,"ip":"10.20.144.81","jmsPassword":"napoli","jmsUserName":"napoli","jmxPort":1099, + "modified":1298964982516,"name":"PT-10.20.144.81-A","port":61616,"recoverLocked":false,"recoverable":false,"slaveAddress":":61616", + "slaveIp":"","slaveJmxPort":1099,"slavePort":61616,"state":1,"supportHa":false,"useSlave":false + }, + "modified":1317290689942,"outRate":0, + "queue":{"$ref":"$.queueMap[12110]"}, + "receivable":true,"sendable":true,"state":0,"weight":1 + } + }, + "pqMap":{"$ref":"$.queueMap[12110].physicalQueueMap"}, + "receivable":true,"routerMaxThreads":1,"sendable":true,"strategy":"round_robin","type":"QUEUE" + }, + 12111:{ + "curMsgs":0,"description":"","ha":false,"id":12111,"machineCount":1,"maxCurMsgs":100,"maxRedeliveries":6,"modified":1318310632121,"monitorSpeed":false,"name":"NapoliClientTest_q3", + "physicalQueueMap":{ + 12127:{ + "id":12127,"inRate":0, + "machine":{ + "address":"10.20.144.81:61616","description":"","id":1,"ip":"10.20.144.81","jmsPassword":"napoli","jmsUserName":"napoli","jmxPort":1099, + "modified":1298964982516,"name":"PT-10.20.144.81-A","port":61616,"recoverLocked":false,"recoverable":false,"slaveAddress":":61616", + "slaveIp":"","slaveJmxPort":1099,"slavePort":61616,"state":1,"supportHa":false,"useSlave":false + }, + "modified":1318310632121,"outRate":0, + "queue":{"$ref":"$.queueMap[12111]"}, + "receivable":true,"sendable":true,"state":0,"weight":1 + } + }, + "pqMap":{"$ref":"$.queueMap[12111].physicalQueueMap"}, + "receivable":true,"routerMaxThreads":1,"sendable":true,"strategy":"round_robin","type":"QUEUE" + } + }, + "type":"VIRTUAL_TOPIC" +} \ No newline at end of file diff --git a/src/test/resources/json/yannywang.json b/src/test/resources/json/yannywang.json new file mode 100755 index 0000000000..202961ed19 --- /dev/null +++ b/src/test/resources/json/yannywang.json @@ -0,0 +1 @@ +{"description":"","id":1336,"modified":1318310632121,"name":"NapoliClientTest","queueCount":3,"queueLimit":0,"queueMap":{12109:{"curMsgs":0,"description":"","ha":false,"id":12109,"machineCount":1,"maxCurMsgs":100,"maxRedeliveries":6,"modified":1317290675999,"monitorSpeed":false,"name":"NapoliClientTest_q1","physicalQueueMap":{12125:{"id":12125,"inRate":0,"machine":{"address":"10.20.144.81:61616","description":"","id":1,"ip":"10.20.144.81","jmsPassword":"napoli","jmsUserName":"napoli","jmxPort":1099,"modified":1298964982516,"name":"PT-10.20.144.81-A","port":61616,"recoverLocked":false,"recoverable":false,"slaveAddress":":61616","slaveIp":"","slaveJmxPort":1099,"slavePort":61616,"state":1,"supportHa":false,"useSlave":false},"modified":1317290675999,"outRate":0,"queue":{"$ref":"$.queueMap[12109]"},"receivable":true,"sendable":true,"state":0,"weight":1}},"pqMap":{"$ref":"$.queueMap[12109].physicalQueueMap"},"receivable":true,"routerMaxThreads":1,"sendable":true,"strategy":"round_robin","type":"QUEUE"},12110:{"curMsgs":0,"description":"","ha":false,"id":12110,"machineCount":1,"maxCurMsgs":100,"maxRedeliveries":6,"modified":1317290689942,"monitorSpeed":false,"name":"NapoliClientTest_q2","physicalQueueMap":{12126:{"id":12126,"inRate":0,"machine":{"address":"10.20.144.81:61616","description":"","id":1,"ip":"10.20.144.81","jmsPassword":"napoli","jmsUserName":"napoli","jmxPort":1099,"modified":1298964982516,"name":"PT-10.20.144.81-A","port":61616,"recoverLocked":false,"recoverable":false,"slaveAddress":":61616","slaveIp":"","slaveJmxPort":1099,"slavePort":61616,"state":1,"supportHa":false,"useSlave":false},"modified":1317290689942,"outRate":0,"queue":{"$ref":"$.queueMap[12110]"},"receivable":true,"sendable":true,"state":0,"weight":1}},"pqMap":{"$ref":"$.queueMap[12110].physicalQueueMap"},"receivable":true,"routerMaxThreads":1,"sendable":true,"strategy":"round_robin","type":"QUEUE"},12111:{"curMsgs":0,"description":"","ha":false,"id":12111,"machineCount":1,"maxCurMsgs":100,"maxRedeliveries":6,"modified":1318310632121,"monitorSpeed":false,"name":"NapoliClientTest_q3","physicalQueueMap":{12127:{"id":12127,"inRate":0,"machine":{"address":"10.20.144.81:61616","description":"","id":1,"ip":"10.20.144.81","jmsPassword":"napoli","jmsUserName":"napoli","jmxPort":1099,"modified":1298964982516,"name":"PT-10.20.144.81-A","port":61616,"recoverLocked":false,"recoverable":false,"slaveAddress":":61616","slaveIp":"","slaveJmxPort":1099,"slavePort":61616,"state":1,"supportHa":false,"useSlave":false},"modified":1318310632121,"outRate":0,"queue":{"$ref":"$.queueMap[12111]"},"receivable":true,"sendable":true,"state":0,"weight":1}},"pqMap":{"$ref":"$.queueMap[12111].physicalQueueMap"},"receivable":true,"routerMaxThreads":1,"sendable":true,"strategy":"round_robin","type":"QUEUE"}},"type":"VIRTUAL_TOPIC"} \ No newline at end of file diff --git a/src/test/resources/jvmargs b/src/test/resources/jvmargs old mode 100644 new mode 100755 diff --git a/src/test/resources/wuyexiong.json b/src/test/resources/wuyexiong.json new file mode 100755 index 0000000000..5fc053ccd4 --- /dev/null +++ b/src/test/resources/wuyexiong.json @@ -0,0 +1,69 @@ +{ +"track": [ +{ +"name": "Android", +"color": "#A6BC40", +"abstract": "Learn about developing mobile handset and tablet apps for Android." +}, +{ +"name": "Chrome", +"color": "#46B0E2", +"abstract": "Build for the modern web with the Chrome platform." +}, +{ +"name": "Cloud Platform", +"color": "#2076BC", +"abstract": "Learn about Google's cloud offerings for developers." +}, +{ +"name": "Code Labs", +"color": "#E4388F", +"abstract": "Get your hands dirty in longer, classroom-style sessions. Bring your laptop. Write code." +}, +{ +"name": "Commerce", +"color": "#4CAA47", +"abstract": "Learn how to use Google Commerce products to improve monetization on the web, in app, and in store." +}, +{ +"name": "Entrepreneurship", +"color": "#97B0DA", +"abstract": "Talks on topics related to startups, venture capital, and entrepreneurship." +}, +{ +"name": "Google APIs", +"color": "#00773F", +"abstract": "Learn about Google's various developer platforms." +}, +{ +"name": "Google Drive", +"color": "#F5851F", +"abstract": "Learn to develop for Google Drive and Google Apps Script." +}, +{ +"name": "Google Maps", +"color": "#4CAA47", +"abstract": "Leverage the power of Google's geospatial technology in your apps." +}, +{ +"name": "Google TV", +"color": "#37505C", +"abstract": "Build apps for the big screen. Learn about developing for Google TV." +}, +{ +"name": "Google+", +"color": "#DC4E30", +"abstract": "Learn about developing on the Google+ platform." +}, +{ +"name": "Tech Talk", +"color": "#A1609D", +"abstract": "Tech talks on subjects such as computer science problems, programming languages, and more." +}, +{ +"name": "YouTube", +"color": "#E72C2E", +"abstract": "Learn about developing for YouTube." +} +] +} \ No newline at end of file diff --git a/vtune.sh b/vtune.sh new file mode 100755 index 0000000000..6ea5ae707c --- /dev/null +++ b/vtune.sh @@ -0,0 +1,2 @@ +export AMPLXE_EXPERIMENTAL=1 +/opt/intel/vtune_amplifier_xe/bin64/amplxe-cl -collect hotspots java -classpath target/classes/:target/test-classes/ com.alibaba.json.test.benchmark.BenchmarkMain diff --git a/x.sh b/x.sh new file mode 100755 index 0000000000..10baea1f22 --- /dev/null +++ b/x.sh @@ -0,0 +1,2 @@ +export AMPLXE_EXPERIMENTAL=1 +/opt/intel/vtune_amplifier_xe/bin64/amplxe-cl -collect hotspots /opt/taobao/install/jdk-1.7.0_10/bin/java -classpath target/classes/:target/test-classes/ com.alibaba.json.test.benchmark.BenchmarkMain