From 18e6b5313856d30519a4fadaaef2cfbddbcfeaaf Mon Sep 17 00:00:00 2001 From: Lam Luong Date: Fri, 6 Oct 2023 08:03:50 +0700 Subject: [PATCH 1/4] Added support for JPEG-LS, JPEG and JPEG2000 transfer syntaxes. --- README.md | 26 +- pkg/codec/README.md | 40 + pkg/codec/codec.cxx | 392 +++++++++ pkg/codec/codec.go | 731 +++++++++++++++++ pkg/codec/codec.h | 32 + pkg/codec/codec.i | 21 + pkg/codec/codec_wrap.cxx | 1142 +++++++++++++++++++++++++++ pkg/codec/decoder.go | 155 ++++ pkg/codec/decoder_test.go | 144 ++++ pkg/codec/export.h | 6 + pkg/codec/lib.go | 6 + pkg/codec/testdata/1.dcm.1.raw | Bin 0 -> 56448 bytes pkg/codec/testdata/1_jpls.dcm.3.raw | Bin 0 -> 4440 bytes pkg/codec/testdata/3.dcm.0.raw | Bin 0 -> 61952 bytes pkg/codec/testdata/3_jpeg.dcm.1.raw | Bin 0 -> 13922 bytes pkg/codec/testdata/a1_mono.j2c | Bin 0 -> 33588 bytes pkg/codec/testdata/a1_mono.ppm | 5 + pkg/codec/testdata/data_details.md | 32 + pkg/codec/utils.go | 41 + pkg/frame/encapsulated.go | 32 +- pkg/frame/format.go | 42 + pkg/frame/frame.go | 3 +- read.go | 78 +- read_test.go | 7 +- write_test.go | 16 +- 25 files changed, 2912 insertions(+), 39 deletions(-) create mode 100644 pkg/codec/README.md create mode 100644 pkg/codec/codec.cxx create mode 100644 pkg/codec/codec.go create mode 100644 pkg/codec/codec.h create mode 100644 pkg/codec/codec.i create mode 100644 pkg/codec/codec_wrap.cxx create mode 100644 pkg/codec/decoder.go create mode 100644 pkg/codec/decoder_test.go create mode 100644 pkg/codec/export.h create mode 100644 pkg/codec/lib.go create mode 100644 pkg/codec/testdata/1.dcm.1.raw create mode 100644 pkg/codec/testdata/1_jpls.dcm.3.raw create mode 100644 pkg/codec/testdata/3.dcm.0.raw create mode 100644 pkg/codec/testdata/3_jpeg.dcm.1.raw create mode 100644 pkg/codec/testdata/a1_mono.j2c create mode 100644 pkg/codec/testdata/a1_mono.ppm create mode 100644 pkg/codec/testdata/data_details.md create mode 100644 pkg/codec/utils.go create mode 100644 pkg/frame/format.go diff --git a/README.md b/README.md index 70bebd94..8ce33b67 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@

dicom

High Performance Golang DICOM Medical Image Parser

-

- +

+ - +

@@ -24,9 +24,15 @@ Some notable features: - [x] Enhanced testing and benchmarking support - [x] Modern, canonical Go. +### Compressed *Pixel Data* +#### JPEG, JPEG-LS and JPEG 2000 +Converting JPEG compressed *Pixel Data* to an uncompressed *Native Data* requires installing one or more additional C/C++ libraries. For information on which libraries are required, see the [DICOM Codecs for pixel data](https://github.com/suyashkumar/dicom/blob/main/pkg/codec/README.md). + +Compressing data into one of the JPEG formats is not currently supported. + ## Usage To use this in your golang project, import `github.com/suyashkumar/dicom`. This repository supports Go modules, and regularly tags releases using semantic versioning. Typical usage is straightforward: -```go +```go dataset, _ := dicom.ParseFile("testdata/1.dcm", nil) // See also: dicom.Parse which has a generic io.Reader API. @@ -54,7 +60,7 @@ wget -qO- "https://getbin.io/suyashkumar/dicom" | tar xvz ``` dicomutil -path myfile.dcm ``` -Note: for some DICOMs (with native pixel data) no automatic intensity scaling is applied yet (this is coming). You can apply this in your image viewer if needed (in Preview on mac, go to Tools->Adjust Color). +Note: for some DICOMs (with native pixel data) no automatic intensity scaling is applied yet (this is coming). You can apply this in your image viewer if needed (in Preview on mac, go to Tools->Adjust Color). ### Build manually @@ -62,7 +68,7 @@ To build manually, ensure you have `make` and `go` installed. Clone (or `go get` ```sh make ``` -Which will build the dicomutil binary and include it in a `build/` folder in your current working directory. +Which will build the dicomutil binary and include it in a `build/` folder in your current working directory. You can also built it using Go directly: @@ -71,21 +77,21 @@ go build -o dicomutil ./cmd/dicomutil ``` ## History -Here's a little more history on this repository for those who are interested! +Here's a little more history on this repository for those who are interested! ### v0 The v0 [suyashkumar/dicom](https://github.com/suyashkumar/dicom) started off as a hard fork of [go-dicom](https://github.com/gillesdemey/go-dicom) which was not being maintained actively anymore (with the [original author being supportive of my fork](https://www.reddit.com/r/golang/comments/bnu47l/high_performance_dicom_medical_image_parser_in/en9hp6h?utm_source=share&utm_medium=web2x&context=3)--thank you!). I worked on adding several new capabilities, bug fixes, and general maintainability refactors (like multiframe support, streaming parsing, updated APIs, low-level parsing bug fixes, and more). -That represents the __v0__ history of the repository. +That represents the __v0__ history of the repository. ### v1 -For __v1__ I rewrote and redesigned the core library essentially from scratch, and added several new features and bug fixes that only live in __v1__. The architecture and APIs are completely different, as is some of the underlying parser logic (to be more efficient and correct). Most of the core rewrite work happened at the [`s/1.0-rewrite`](https://github.com/suyashkumar/dicom/tree/s/1.0-rewrite) branch. +For __v1__ I rewrote and redesigned the core library essentially from scratch, and added several new features and bug fixes that only live in __v1__. The architecture and APIs are completely different, as is some of the underlying parser logic (to be more efficient and correct). Most of the core rewrite work happened at the [`s/1.0-rewrite`](https://github.com/suyashkumar/dicom/tree/s/1.0-rewrite) branch. ## Acknowledgements -* [Segmed](https://www.segmed.ai/) for their help with validation and other contributions to the library. +* [Segmed](https://www.segmed.ai/) for their help with validation and other contributions to the library. * Original [go-dicom](https://github.com/gillesdemey/go-dicom) * Grailbio [go-dicom](https://github.com/grailbio/go-dicom) -- commits from their fork were applied to ours * GradientHealth for supporting work I did on this while there [gradienthealth/dicom](https://github.com/gradienthealth/dicom) diff --git a/pkg/codec/README.md b/pkg/codec/README.md new file mode 100644 index 00000000..7ab23ec3 --- /dev/null +++ b/pkg/codec/README.md @@ -0,0 +1,40 @@ +# Codec +DICOM codec for decoding JPEG/JPEG-LS/JPEG2000 images, with a focus on providing support for [suyashkumar/dicom](https://github.com/suyashkumar/dicom). + +### Prerequisites +To be able to decompress compressed DICOM pixel data, you first have to install the corresponding libraries, that are able to handle the format the data is encoded in: + +- LINUX +```bash +apt-get install pkg-config swig libcharls-dev libdcmtk-dev libopenjp2-7-dev +``` +- MACOS +```bash +brew install swig pkg-config +brew install dcmtk +brew install openjpeg +brew install team-charls/tap/charls +``` + +Generate the necessary C++ wrapper code to allow Go to bind to it. You need to do this each time the dependent *.h or *.cxx files change. +```bash +swig -go -cgo -c++ -intgosize 64 codec.i +``` + +## Usage +```go +import ( + "github.com/suyashkumar/dicom" + _ "github.com/suyashkumar/dicom/pkg/codec" + "github.com/suyashkumar/dicom/pkg/tag" +) + +func main() { + dataset, err := dicom.ParseFile("testdata/1.dcm", nil) + pixelDataElem, err := dataset.FindElementByTag(tag.PixelData) + pixelData := dicom.MustGetPixelDataInfo(pixelDataElem.Value) + encapsulatedFrame, err := pixelData.Frames[0].GetEncapsulatedFrame() + image, err = encapsulatedFrame.GetImage() + ... +} +``` diff --git a/pkg/codec/codec.cxx b/pkg/codec/codec.cxx new file mode 100644 index 00000000..a61f1465 --- /dev/null +++ b/pkg/codec/codec.cxx @@ -0,0 +1,392 @@ +// Copyright (c) 2023 Segmed Inc. +#include "openjpeg.h" +#include "dcmtk/dcmjpeg/djcparam.h" +#include "dcmtk/dcmjpeg/djeijg8.h" +#include "dcmtk/dcmjpeg/djeijg12.h" +#include "dcmtk/dcmjpeg/djeijg16.h" +#include "dcmtk/dcmjpeg/djdijg8.h" +#include "dcmtk/dcmjpeg/djdijg12.h" +#include "dcmtk/dcmjpeg/djdijg16.h" +#include "charls/charls.h" +#include "codec.h" + +/** + * width: cols + * height: rows + * numcomps/samplesPerPixel: number of components/samples/planes (RGB-3/Grey-1) in the image + * prec/bitsAllocated: number of bits per component per pixel + * sgnd/pixelRepresentation: signed (1) / unsigned (0) + * planarConfiguration: color-by-plane (1) or color-by-pixel (0) +* */ +unsigned char * JPEGLS_Decode(unsigned char * dataSrc, size_t length, int bitsAllocated, int width, int height, int samplesPerPixel, int planarConfiguration, size_t * lenOut) +{ + charls::jpegls_decoder decoder; + decoder.source(dataSrc, length); + decoder.read_header(); + + const size_t size{static_cast(decoder.destination_size())}; + BYTE *newdata = new BYTE[decoder.destination_size()]; + + decoder.decode(newdata, size); + *lenOut = size; + return newdata; +} + +unsigned char * JPEG_Decode(unsigned char * dataSrc, size_t length, int bitsAllocated, int width, int height, int samplesPerPixel, int planarConfiguration, int ybr, size_t * lenOut) +{ + if (bitsAllocated == 8) + { + DJCodecParameter param( + ECC_lossyRGB, + ybr ? EDC_always : EDC_never, + EUC_never, + planarConfiguration ? EPC_colorByPlane : EPC_colorByPixel + ); + + int outSize = width*height*samplesPerPixel; + BYTE *outBuf = new BYTE[outSize]; + + DJDecompressIJG8Bit *decop = new DJDecompressIJG8Bit(param, ybr); + OFCondition check1 = decop->init(); + OFCondition check2 = decop->decode(dataSrc, length, outBuf, outSize, false); + delete decop; + + *lenOut = outSize; + return outBuf; + } + else if (bitsAllocated == 12) + { + DJCodecParameter param( + ECC_lossyRGB, + ybr ? EDC_always : EDC_never, + EUC_never, + planarConfiguration ? EPC_colorByPlane : EPC_colorByPixel + ); + + int outSize = width*height*samplesPerPixel*2; + BYTE *outBuf = new BYTE[outSize]; + + DJDecompressIJG12Bit *decop = new DJDecompressIJG12Bit(param, ybr); + OFCondition check1 = decop->init(); + OFCondition check2 = decop->decode(dataSrc, length, outBuf, outSize, false); + delete decop; + + *lenOut = outSize; + return outBuf; + } + else if (bitsAllocated == 16) + { + DJCodecParameter param( + ECC_lossyRGB, + ybr ? EDC_always : EDC_never, + EUC_never, + planarConfiguration ? EPC_colorByPlane : EPC_colorByPixel + ); + + int outSize = width*height*samplesPerPixel*2; + BYTE *outBuf = new BYTE[outSize]; + + DJDecompressIJG16Bit *decop = new DJDecompressIJG16Bit(param, ybr); + OFCondition check1 = decop->init(); + OFCondition check2 = decop->decode(dataSrc, length, outBuf, outSize, false); + delete decop; + + *lenOut = outSize; + return outBuf; + } + + return NULL; +} + +unsigned char * J2K_Decode(unsigned char * dataSrc, size_t length, int width, int height, size_t * lenOut) +{ + // WARNING: OpenJPEG is very picky when there is a trailing 00 at the end of the JPC + // so we need to make sure to remove it. + // Marker 0xffd9 EOI End of Image (JPEG 2000 EOC End of codestream) + // gdcmData/D_CLUNIE_CT1_J2KR.dcm contains a trailing 0xFF which apparently is ok... + // Ref: https://github.com/malaterre/GDCM/blob/master/Source/MediaStorageAndFileFormat/gdcmJPEG2000Codec.cxx#L637 + while( length > 0 && dataSrc[length-1] != 0xd9 ) + { + length--; + } + // what if 0xd9 is never found ? + if( !( length > 0 && dataSrc[length-1] == 0xd9 ) ) + { + return NULL; + } + // https://github.com/malaterre/GDCM/blob/master/Source/MediaStorageAndFileFormat/gdcmJPEG2000Codec.cxx#L656 + OPJ_CODEC_FORMAT decod_format; + const char jp2magic[] = "\x00\x00\x00\x0C\x6A\x50\x20\x20\x0D\x0A\x87\x0A"; + if( memcmp( dataSrc, jp2magic, sizeof(jp2magic) ) == 0 ) + { + /* JPEG-2000 compressed image data ... sigh */ + fprintf(stderr, "J2K start like JPEG-2000 compressed image data instead of codestream" ); + decod_format = OPJ_CODEC_JP2; + } + else + { + /* JPEG-2000 codestream */ + decod_format = OPJ_CODEC_J2K; + } + opj_codec_t * l_codec = opj_create_decompress(decod_format); + + opj_input_memory_stream fsrc; + fsrc.dataSize = length; + fsrc.offset = 0; + fsrc.pData = dataSrc; + + opj_stream_t * l_stream = opj_stream_default_create(1); + if (!l_stream){ + return NULL; + } + opj_stream_set_read_function(l_stream, opj_input_memory_stream_read); + opj_stream_set_seek_function(l_stream, opj_input_memory_stream_seek); + opj_stream_set_skip_function(l_stream, opj_input_memory_stream_skip); + opj_stream_set_user_data(l_stream, &fsrc, NULL); + opj_stream_set_user_data_length(l_stream, fsrc.dataSize); + + opj_dparameters_t params; + opj_set_default_decoder_parameters(¶ms); + if (!opj_setup_decoder(l_codec, ¶ms)) { + fprintf(stderr, "ERROR -> opj_decompress: failed to setup the decoder\n"); + opj_stream_destroy(l_stream); + opj_destroy_codec(l_codec); + return NULL; + } + + opj_image_t *image; + if (!opj_read_header(l_stream, l_codec, &image)) { + fprintf(stderr, "ERROR -> j2k_to_image: failed to read the header\n"); + opj_stream_destroy(l_stream); + opj_destroy_codec(l_codec); + opj_image_destroy(image); + return NULL; + } + if (!opj_decode(l_codec, l_stream, image)) { + fprintf(stderr, "ERROR -> opj_decompress: failed to decode image!\n"); + opj_destroy_codec(l_codec); + opj_stream_destroy(l_stream); + opj_image_destroy(image); + return NULL; + } + + void *vOutBits = NULL; + OPJ_INT32 * ptr; + int adjustR, bitsAllocated; + bitsAllocated = image->comps[0].prec; + if (bitsAllocated == 8) { + BYTE v; + BYTE *newdata = new BYTE[image->x1*image->y1*image->numcomps]; + for (unsigned int c=0; cnumcomps; c++) { + adjustR = + (image->comps[c].sgnd ? 1 << (bitsAllocated - 1) : 0); + ptr = (OPJ_INT32 *)image->comps[c].data; + for (unsigned int i = 0; i< image->x1*image->y1; i++){ + v = (BYTE) (*ptr + adjustR); + ptr++; + newdata[i*image->numcomps + c] = v; + } + } + vOutBits = (void *) newdata; + } else { // 12 or 16 bits + OPJ_UINT16 v; + OPJ_UINT16 *newdata = new OPJ_UINT16[image->x1*image->y1*image->numcomps]; + for (unsigned int c=0; cnumcomps; c++) { + adjustR = + (image->comps[c].sgnd ? 1 << (bitsAllocated - 1) : 0); + ptr = (OPJ_INT32 *)image->comps[c].data; + for (unsigned int i = 0; i< image->x1*image->y1; i++){ + v = (OPJ_UINT16) (*ptr + adjustR); + ptr++; + newdata[i*image->numcomps + c] = v; + } + } + vOutBits = (void *) newdata; + } + + *lenOut = image->x1*image->y1 * (bitsAllocated==8?1:2) * image->numcomps; + + opj_image_destroy(image); + opj_stream_destroy(l_stream); + opj_destroy_codec(l_codec); + + return (BYTE *) vOutBits; +} + +unsigned char * J2K_Encode(unsigned char * dataSrc, int bitsAllocated, int width, int height, int samplesPerPixel, int planarConfiguration, size_t * lenOut) +{ + opj_cparameters_t params; + opj_set_default_encoder_parameters(¶ms); + params.cod_format = OPJ_CODEC_J2K; + params.irreversible = 0; + params.tcp_numlayers = 1; + params.cp_disto_alloc = 1; + + opj_image_cmptparm_t *cmptparm = new opj_image_cmptparm_t[samplesPerPixel]; + + for (int i=0; ix0 = 0; + jp2_image->y0 = 0; + jp2_image->x1 = width; + jp2_image->y1 = height; + + //dump the source image into the components + if (samplesPerPixel == 1) + { + if (bitsAllocated == 8) + { + for (int p=0; pcomps[0].data[p] = dataSrc[p]; + } + else + { + //2-byte + for (int p=0; pcomps[0].data[p] = ((OPJ_UINT16 *)dataSrc)[p]; + } + } + else + { + //always 8-bit, to my understanding + + if (planarConfiguration == 0) //0 = R1G1B1 R2G2B2, 1 = R1R2R3..G1G2G3...B1B2B3... + { + for (int i=0; icomps[i].data[p] = dataSrc[p*samplesPerPixel + i]; + } + else + { + for (int i=0; icomps[i].data[p] = dataSrc[i*width*height + p]; + } + } + + opj_codec_t * codec = opj_create_compress(OPJ_CODEC_J2K); + opj_setup_encoder(codec, ¶ms, jp2_image); + + + opj_output_memory_stream streamInfo; + streamInfo.dataSize = 0; + + opj_stream_t * stream = opj_stream_default_create(0); + if (!stream){ + return NULL; + } + opj_stream_set_write_function(stream, opj_output_memory_stream_write); + opj_stream_set_seek_function(stream, opj_output_memory_stream_seek); + opj_stream_set_skip_function(stream, opj_output_memory_stream_skip); + opj_stream_set_user_data(stream, &streamInfo, NULL); + + opj_start_compress(codec, jp2_image, stream); + opj_encode(codec, stream); + opj_end_compress(codec, stream); + + delete []cmptparm; + + *lenOut = streamInfo.dataSize; + BYTE * vOutBits = (BYTE *) malloc(streamInfo.dataSize), *fillPtr = vOutBits; + for (std::vector::iterator i = streamInfo.chunks.begin(); i != streamInfo.chunks.end(); i++) + { + memcpy(fillPtr, i->data, i->dataLen); + delete i->data; + fillPtr += i->dataLen; + } + + opj_stream_destroy(stream); + opj_destroy_codec(codec); + opj_image_destroy(jp2_image); + + return (BYTE *) vOutBits; +} + +// https://groups.google.com/forum/#!topic/openjpeg/8cebr0u7JgY +OPJ_SIZE_T opj_input_memory_stream_read(void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data) +{ + opj_input_memory_stream* l_stream = (opj_input_memory_stream*)p_user_data; + OPJ_SIZE_T l_nb_bytes_read = p_nb_bytes; + + if (l_stream->offset >= l_stream->dataSize) { + return (OPJ_SIZE_T)-1; + } + if (p_nb_bytes > (l_stream->dataSize - l_stream->offset)) { + l_nb_bytes_read = l_stream->dataSize - l_stream->offset; + } + memcpy(p_buffer, &(l_stream->pData[l_stream->offset]), l_nb_bytes_read); + l_stream->offset += l_nb_bytes_read; + return l_nb_bytes_read; +} + +OPJ_OFF_T opj_input_memory_stream_skip(OPJ_OFF_T p_nb_bytes, void * p_user_data) +{ + opj_input_memory_stream* l_stream = (opj_input_memory_stream*)p_user_data; + + if (p_nb_bytes < 0) { + return -1; + } + + l_stream->offset += (OPJ_SIZE_T)p_nb_bytes; + + return p_nb_bytes; +} + +OPJ_BOOL opj_input_memory_stream_seek(OPJ_OFF_T p_nb_bytes, void * p_user_data) +{ + opj_input_memory_stream* l_stream = (opj_input_memory_stream*)p_user_data; + + if (p_nb_bytes < 0) { + return OPJ_FALSE; + } + + l_stream->offset = (OPJ_SIZE_T)p_nb_bytes; + + return OPJ_TRUE; +} + + +// Writer adapted from above and made it up + +OPJ_BOOL opj_output_memory_stream_seek(OPJ_OFF_T p_nb_bytes, void * p_user_data) +{ + opj_output_memory_stream* stream = (opj_output_memory_stream*)p_user_data; + + return OPJ_TRUE; +} + +OPJ_OFF_T opj_output_memory_stream_skip(OPJ_OFF_T p_nb_bytes, void * p_user_data) +{ + opj_output_memory_stream* stream = (opj_output_memory_stream*)p_user_data; + + return p_nb_bytes; +} + +OPJ_SIZE_T opj_output_memory_stream_write(void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data) +{ + opj_output_memory_stream* stream = (opj_output_memory_stream*)p_user_data; + + opj_output_memory_stream_chunk newChunk; + newChunk.dataLen = p_nb_bytes; + newChunk.data = new BYTE[p_nb_bytes]; + memcpy(newChunk.data, p_buffer, p_nb_bytes); + + stream->dataSize += p_nb_bytes; + + stream->chunks.push_back(newChunk); + + return p_nb_bytes; +} diff --git a/pkg/codec/codec.go b/pkg/codec/codec.go new file mode 100644 index 00000000..8d38a609 --- /dev/null +++ b/pkg/codec/codec.go @@ -0,0 +1,731 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.1.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +// source: codec.i + +package codec + +/* +#define intgo swig_intgo +typedef void *swig_voidp; + +#include +#include + + +typedef long long intgo; +typedef unsigned long long uintgo; + + + +typedef struct { char *p; intgo n; } _gostring_; +typedef struct { void* array; intgo len; intgo cap; } _goslice_; + + +typedef long long swig_type_1; +typedef long long swig_type_2; +typedef long long swig_type_3; +typedef long long swig_type_4; +typedef _gostring_ swig_type_5; +typedef _gostring_ swig_type_6; +typedef _gostring_ swig_type_7; +typedef long long swig_type_8; +typedef long long swig_type_9; +typedef long long swig_type_10; +typedef long long swig_type_11; +typedef long long swig_type_12; +typedef long long swig_type_13; +typedef long long swig_type_14; +extern void _wrap_Swig_free_codec_cffb419519a4d845(uintptr_t arg1); +extern uintptr_t _wrap_Swig_malloc_codec_cffb419519a4d845(swig_intgo arg1); +extern uintptr_t _wrap_new_StringVector__SWIG_0_codec_cffb419519a4d845(void); +extern uintptr_t _wrap_new_StringVector__SWIG_1_codec_cffb419519a4d845(swig_type_1 arg1); +extern uintptr_t _wrap_new_StringVector__SWIG_2_codec_cffb419519a4d845(uintptr_t arg1); +extern swig_type_2 _wrap_StringVector_size_codec_cffb419519a4d845(uintptr_t arg1); +extern swig_type_3 _wrap_StringVector_capacity_codec_cffb419519a4d845(uintptr_t arg1); +extern void _wrap_StringVector_reserve_codec_cffb419519a4d845(uintptr_t arg1, swig_type_4 arg2); +extern _Bool _wrap_StringVector_isEmpty_codec_cffb419519a4d845(uintptr_t arg1); +extern void _wrap_StringVector_clear_codec_cffb419519a4d845(uintptr_t arg1); +extern void _wrap_StringVector_add_codec_cffb419519a4d845(uintptr_t arg1, swig_type_5 arg2); +extern swig_type_6 _wrap_StringVector_get_codec_cffb419519a4d845(uintptr_t arg1, swig_intgo arg2); +extern void _wrap_StringVector_set_codec_cffb419519a4d845(uintptr_t arg1, swig_intgo arg2, swig_type_7 arg3); +extern void _wrap_delete_StringVector_codec_cffb419519a4d845(uintptr_t arg1); +extern uintptr_t _wrap_new_ByteVector__SWIG_0_codec_cffb419519a4d845(void); +extern uintptr_t _wrap_new_ByteVector__SWIG_1_codec_cffb419519a4d845(swig_type_8 arg1); +extern uintptr_t _wrap_new_ByteVector__SWIG_2_codec_cffb419519a4d845(uintptr_t arg1); +extern swig_type_9 _wrap_ByteVector_size_codec_cffb419519a4d845(uintptr_t arg1); +extern swig_type_10 _wrap_ByteVector_capacity_codec_cffb419519a4d845(uintptr_t arg1); +extern void _wrap_ByteVector_reserve_codec_cffb419519a4d845(uintptr_t arg1, swig_type_11 arg2); +extern _Bool _wrap_ByteVector_isEmpty_codec_cffb419519a4d845(uintptr_t arg1); +extern void _wrap_ByteVector_clear_codec_cffb419519a4d845(uintptr_t arg1); +extern void _wrap_ByteVector_add_codec_cffb419519a4d845(uintptr_t arg1, char arg2); +extern char _wrap_ByteVector_get_codec_cffb419519a4d845(uintptr_t arg1, swig_intgo arg2); +extern void _wrap_ByteVector_set_codec_cffb419519a4d845(uintptr_t arg1, swig_intgo arg2, char arg3); +extern void _wrap_delete_ByteVector_codec_cffb419519a4d845(uintptr_t arg1); +extern void _wrap_opj_input_memory_stream_pData_set_codec_cffb419519a4d845(uintptr_t arg1, uintptr_t arg2); +extern uintptr_t _wrap_opj_input_memory_stream_pData_get_codec_cffb419519a4d845(uintptr_t arg1); +extern void _wrap_opj_input_memory_stream_dataSize_set_codec_cffb419519a4d845(uintptr_t arg1, uintptr_t arg2); +extern uintptr_t _wrap_opj_input_memory_stream_dataSize_get_codec_cffb419519a4d845(uintptr_t arg1); +extern void _wrap_opj_input_memory_stream_offset_set_codec_cffb419519a4d845(uintptr_t arg1, uintptr_t arg2); +extern uintptr_t _wrap_opj_input_memory_stream_offset_get_codec_cffb419519a4d845(uintptr_t arg1); +extern uintptr_t _wrap_new_opj_input_memory_stream_codec_cffb419519a4d845(void); +extern void _wrap_delete_opj_input_memory_stream_codec_cffb419519a4d845(uintptr_t arg1); +extern uintptr_t _wrap_opj_input_memory_stream_seek_codec_cffb419519a4d845(uintptr_t arg1, uintptr_t arg2); +extern uintptr_t _wrap_opj_input_memory_stream_skip_codec_cffb419519a4d845(uintptr_t arg1, uintptr_t arg2); +extern uintptr_t _wrap_opj_input_memory_stream_read_codec_cffb419519a4d845(uintptr_t arg1, uintptr_t arg2, uintptr_t arg3); +extern void _wrap_opj_output_memory_stream_chunk_data_set_codec_cffb419519a4d845(uintptr_t arg1, uintptr_t arg2); +extern uintptr_t _wrap_opj_output_memory_stream_chunk_data_get_codec_cffb419519a4d845(uintptr_t arg1); +extern void _wrap_opj_output_memory_stream_chunk_dataLen_set_codec_cffb419519a4d845(uintptr_t arg1, uintptr_t arg2); +extern uintptr_t _wrap_opj_output_memory_stream_chunk_dataLen_get_codec_cffb419519a4d845(uintptr_t arg1); +extern uintptr_t _wrap_new_opj_output_memory_stream_chunk_codec_cffb419519a4d845(void); +extern void _wrap_delete_opj_output_memory_stream_chunk_codec_cffb419519a4d845(uintptr_t arg1); +extern void _wrap_opj_output_memory_stream_dataSize_set_codec_cffb419519a4d845(uintptr_t arg1, uintptr_t arg2); +extern uintptr_t _wrap_opj_output_memory_stream_dataSize_get_codec_cffb419519a4d845(uintptr_t arg1); +extern void _wrap_opj_output_memory_stream_chunks_set_codec_cffb419519a4d845(uintptr_t arg1, uintptr_t arg2); +extern uintptr_t _wrap_opj_output_memory_stream_chunks_get_codec_cffb419519a4d845(uintptr_t arg1); +extern uintptr_t _wrap_new_opj_output_memory_stream_codec_cffb419519a4d845(void); +extern void _wrap_delete_opj_output_memory_stream_codec_cffb419519a4d845(uintptr_t arg1); +extern uintptr_t _wrap_opj_output_memory_stream_seek_codec_cffb419519a4d845(uintptr_t arg1, uintptr_t arg2); +extern uintptr_t _wrap_opj_output_memory_stream_skip_codec_cffb419519a4d845(uintptr_t arg1, uintptr_t arg2); +extern uintptr_t _wrap_opj_output_memory_stream_write_codec_cffb419519a4d845(uintptr_t arg1, uintptr_t arg2, uintptr_t arg3); +extern swig_voidp _wrap_J2K_Decode_codec_cffb419519a4d845(swig_voidp arg1, swig_type_12 arg2, swig_intgo arg3, swig_intgo arg4, swig_voidp arg5); +extern swig_voidp _wrap_JPEG_Decode_codec_cffb419519a4d845(swig_voidp arg1, swig_type_13 arg2, swig_intgo arg3, swig_intgo arg4, swig_intgo arg5, swig_intgo arg6, swig_intgo arg7, swig_intgo arg8, swig_voidp arg9); +extern swig_voidp _wrap_JPEGLS_Decode_codec_cffb419519a4d845(swig_voidp arg1, swig_type_14 arg2, swig_intgo arg3, swig_intgo arg4, swig_intgo arg5, swig_intgo arg6, swig_intgo arg7, swig_voidp arg8); +extern swig_voidp _wrap_J2K_Encode_codec_cffb419519a4d845(swig_voidp arg1, swig_intgo arg2, swig_intgo arg3, swig_intgo arg4, swig_intgo arg5, swig_intgo arg6, swig_voidp arg7); +#undef intgo +*/ +import "C" + +import "unsafe" +import _ "runtime/cgo" +import "sync" + + +type _ unsafe.Pointer + + + +var Swig_escape_always_false bool +var Swig_escape_val interface{} + + +type _swig_fnptr *byte +type _swig_memberptr *byte + + +func getSwigcptr(v interface { Swigcptr() uintptr }) uintptr { + if v == nil { + return 0 + } + return v.Swigcptr() +} + + +type _ sync.Mutex + +//export cgo_panic__codec_cffb419519a4d845 +func cgo_panic__codec_cffb419519a4d845(p *byte) { + s := (*[1024]byte)(unsafe.Pointer(p))[:] + for i, b := range s { + if b == 0 { + panic(string(s[:i])) + } + } + panic(string(s)) +} + + +type swig_gostring struct { p uintptr; n int } +func swigCopyString(s string) string { + p := *(*swig_gostring)(unsafe.Pointer(&s)) + r := string((*[0x7fffffff]byte)(unsafe.Pointer(p.p))[:p.n]) + Swig_free(p.p) + return r +} + +func Swig_free(arg1 uintptr) { + _swig_i_0 := arg1 + C._wrap_Swig_free_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0)) +} + +func Swig_malloc(arg1 int) (_swig_ret uintptr) { + var swig_r uintptr + _swig_i_0 := arg1 + swig_r = (uintptr)(C._wrap_Swig_malloc_codec_cffb419519a4d845(C.swig_intgo(_swig_i_0))) + return swig_r +} + +type SwigcptrStringVector uintptr + +func (p SwigcptrStringVector) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrStringVector) SwigIsStringVector() { +} + +func NewStringVector__SWIG_0() (_swig_ret StringVector) { + var swig_r StringVector + swig_r = (StringVector)(SwigcptrStringVector(C._wrap_new_StringVector__SWIG_0_codec_cffb419519a4d845())) + return swig_r +} + +func NewStringVector__SWIG_1(arg1 int64) (_swig_ret StringVector) { + var swig_r StringVector + _swig_i_0 := arg1 + swig_r = (StringVector)(SwigcptrStringVector(C._wrap_new_StringVector__SWIG_1_codec_cffb419519a4d845(C.swig_type_1(_swig_i_0)))) + return swig_r +} + +func NewStringVector__SWIG_2(arg1 StringVector) (_swig_ret StringVector) { + var swig_r StringVector + _swig_i_0 := getSwigcptr(arg1) + swig_r = (StringVector)(SwigcptrStringVector(C._wrap_new_StringVector__SWIG_2_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0)))) + return swig_r +} + +func NewStringVector(a ...interface{}) StringVector { + argc := len(a) + if argc == 0 { + return NewStringVector__SWIG_0() + } + if argc == 1 { + if _, ok := a[0].(int64); !ok { + goto check_2 + } + return NewStringVector__SWIG_1(a[0].(int64)) + } +check_2: + if argc == 1 { + return NewStringVector__SWIG_2(a[0].(StringVector)) + } + panic("No match for overloaded function call") +} + +func (arg1 SwigcptrStringVector) Size() (_swig_ret int64) { + var swig_r int64 + _swig_i_0 := arg1 + swig_r = (int64)(C._wrap_StringVector_size_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0))) + return swig_r +} + +func (arg1 SwigcptrStringVector) Capacity() (_swig_ret int64) { + var swig_r int64 + _swig_i_0 := arg1 + swig_r = (int64)(C._wrap_StringVector_capacity_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0))) + return swig_r +} + +func (arg1 SwigcptrStringVector) Reserve(arg2 int64) { + _swig_i_0 := arg1 + _swig_i_1 := arg2 + C._wrap_StringVector_reserve_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.swig_type_4(_swig_i_1)) +} + +func (arg1 SwigcptrStringVector) IsEmpty() (_swig_ret bool) { + var swig_r bool + _swig_i_0 := arg1 + swig_r = (bool)(C._wrap_StringVector_isEmpty_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0))) + return swig_r +} + +func (arg1 SwigcptrStringVector) Clear() { + _swig_i_0 := arg1 + C._wrap_StringVector_clear_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0)) +} + +func (arg1 SwigcptrStringVector) Add(arg2 string) { + _swig_i_0 := arg1 + _swig_i_1 := arg2 + C._wrap_StringVector_add_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), *(*C.swig_type_5)(unsafe.Pointer(&_swig_i_1))) + if Swig_escape_always_false { + Swig_escape_val = arg2 + } +} + +func (arg1 SwigcptrStringVector) Get(arg2 int) (_swig_ret string) { + var swig_r string + _swig_i_0 := arg1 + _swig_i_1 := arg2 + swig_r_p := C._wrap_StringVector_get_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.swig_intgo(_swig_i_1)) + swig_r = *(*string)(unsafe.Pointer(&swig_r_p)) + var swig_r_1 string + swig_r_1 = swigCopyString(swig_r) + return swig_r_1 +} + +func (arg1 SwigcptrStringVector) Set(arg2 int, arg3 string) { + _swig_i_0 := arg1 + _swig_i_1 := arg2 + _swig_i_2 := arg3 + C._wrap_StringVector_set_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.swig_intgo(_swig_i_1), *(*C.swig_type_7)(unsafe.Pointer(&_swig_i_2))) + if Swig_escape_always_false { + Swig_escape_val = arg3 + } +} + +func DeleteStringVector(arg1 StringVector) { + _swig_i_0 := getSwigcptr(arg1) + C._wrap_delete_StringVector_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0)) +} + +type StringVector interface { + Swigcptr() uintptr + SwigIsStringVector() + Size() (_swig_ret int64) + Capacity() (_swig_ret int64) + Reserve(arg2 int64) + IsEmpty() (_swig_ret bool) + Clear() + Add(arg2 string) + Get(arg2 int) (_swig_ret string) + Set(arg2 int, arg3 string) +} + +type SwigcptrByteVector uintptr + +func (p SwigcptrByteVector) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrByteVector) SwigIsByteVector() { +} + +func NewByteVector__SWIG_0() (_swig_ret ByteVector) { + var swig_r ByteVector + swig_r = (ByteVector)(SwigcptrByteVector(C._wrap_new_ByteVector__SWIG_0_codec_cffb419519a4d845())) + return swig_r +} + +func NewByteVector__SWIG_1(arg1 int64) (_swig_ret ByteVector) { + var swig_r ByteVector + _swig_i_0 := arg1 + swig_r = (ByteVector)(SwigcptrByteVector(C._wrap_new_ByteVector__SWIG_1_codec_cffb419519a4d845(C.swig_type_8(_swig_i_0)))) + return swig_r +} + +func NewByteVector__SWIG_2(arg1 ByteVector) (_swig_ret ByteVector) { + var swig_r ByteVector + _swig_i_0 := getSwigcptr(arg1) + swig_r = (ByteVector)(SwigcptrByteVector(C._wrap_new_ByteVector__SWIG_2_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0)))) + return swig_r +} + +func NewByteVector(a ...interface{}) ByteVector { + argc := len(a) + if argc == 0 { + return NewByteVector__SWIG_0() + } + if argc == 1 { + if _, ok := a[0].(int64); !ok { + goto check_2 + } + return NewByteVector__SWIG_1(a[0].(int64)) + } +check_2: + if argc == 1 { + return NewByteVector__SWIG_2(a[0].(ByteVector)) + } + panic("No match for overloaded function call") +} + +func (arg1 SwigcptrByteVector) Size() (_swig_ret int64) { + var swig_r int64 + _swig_i_0 := arg1 + swig_r = (int64)(C._wrap_ByteVector_size_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0))) + return swig_r +} + +func (arg1 SwigcptrByteVector) Capacity() (_swig_ret int64) { + var swig_r int64 + _swig_i_0 := arg1 + swig_r = (int64)(C._wrap_ByteVector_capacity_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0))) + return swig_r +} + +func (arg1 SwigcptrByteVector) Reserve(arg2 int64) { + _swig_i_0 := arg1 + _swig_i_1 := arg2 + C._wrap_ByteVector_reserve_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.swig_type_11(_swig_i_1)) +} + +func (arg1 SwigcptrByteVector) IsEmpty() (_swig_ret bool) { + var swig_r bool + _swig_i_0 := arg1 + swig_r = (bool)(C._wrap_ByteVector_isEmpty_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0))) + return swig_r +} + +func (arg1 SwigcptrByteVector) Clear() { + _swig_i_0 := arg1 + C._wrap_ByteVector_clear_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0)) +} + +func (arg1 SwigcptrByteVector) Add(arg2 byte) { + _swig_i_0 := arg1 + _swig_i_1 := arg2 + C._wrap_ByteVector_add_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.char(_swig_i_1)) +} + +func (arg1 SwigcptrByteVector) Get(arg2 int) (_swig_ret byte) { + var swig_r byte + _swig_i_0 := arg1 + _swig_i_1 := arg2 + swig_r = (byte)(C._wrap_ByteVector_get_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.swig_intgo(_swig_i_1))) + return swig_r +} + +func (arg1 SwigcptrByteVector) Set(arg2 int, arg3 byte) { + _swig_i_0 := arg1 + _swig_i_1 := arg2 + _swig_i_2 := arg3 + C._wrap_ByteVector_set_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.swig_intgo(_swig_i_1), C.char(_swig_i_2)) +} + +func DeleteByteVector(arg1 ByteVector) { + _swig_i_0 := getSwigcptr(arg1) + C._wrap_delete_ByteVector_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0)) +} + +type ByteVector interface { + Swigcptr() uintptr + SwigIsByteVector() + Size() (_swig_ret int64) + Capacity() (_swig_ret int64) + Reserve(arg2 int64) + IsEmpty() (_swig_ret bool) + Clear() + Add(arg2 byte) + Get(arg2 int) (_swig_ret byte) + Set(arg2 int, arg3 byte) +} + +type SwigcptrOpj_input_memory_stream uintptr + +func (p SwigcptrOpj_input_memory_stream) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrOpj_input_memory_stream) SwigIsOpj_input_memory_stream() { +} + +func (arg1 SwigcptrOpj_input_memory_stream) SetPData(arg2 OPJ_UINT8) { + _swig_i_0 := arg1 + _swig_i_1 := getSwigcptr(arg2) + C._wrap_opj_input_memory_stream_pData_set_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.uintptr_t(_swig_i_1)) +} + +func (arg1 SwigcptrOpj_input_memory_stream) GetPData() (_swig_ret OPJ_UINT8) { + var swig_r OPJ_UINT8 + _swig_i_0 := arg1 + swig_r = (OPJ_UINT8)(SwigcptrOPJ_UINT8(C._wrap_opj_input_memory_stream_pData_get_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0)))) + return swig_r +} + +func (arg1 SwigcptrOpj_input_memory_stream) SetDataSize(arg2 OPJ_SIZE_T) { + _swig_i_0 := arg1 + _swig_i_1 := getSwigcptr(arg2) + C._wrap_opj_input_memory_stream_dataSize_set_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.uintptr_t(_swig_i_1)) +} + +func (arg1 SwigcptrOpj_input_memory_stream) GetDataSize() (_swig_ret OPJ_SIZE_T) { + var swig_r OPJ_SIZE_T + _swig_i_0 := arg1 + swig_r = (OPJ_SIZE_T)(SwigcptrOPJ_SIZE_T(C._wrap_opj_input_memory_stream_dataSize_get_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0)))) + return swig_r +} + +func (arg1 SwigcptrOpj_input_memory_stream) SetOffset(arg2 OPJ_SIZE_T) { + _swig_i_0 := arg1 + _swig_i_1 := getSwigcptr(arg2) + C._wrap_opj_input_memory_stream_offset_set_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.uintptr_t(_swig_i_1)) +} + +func (arg1 SwigcptrOpj_input_memory_stream) GetOffset() (_swig_ret OPJ_SIZE_T) { + var swig_r OPJ_SIZE_T + _swig_i_0 := arg1 + swig_r = (OPJ_SIZE_T)(SwigcptrOPJ_SIZE_T(C._wrap_opj_input_memory_stream_offset_get_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0)))) + return swig_r +} + +func NewOpj_input_memory_stream() (_swig_ret Opj_input_memory_stream) { + var swig_r Opj_input_memory_stream + swig_r = (Opj_input_memory_stream)(SwigcptrOpj_input_memory_stream(C._wrap_new_opj_input_memory_stream_codec_cffb419519a4d845())) + return swig_r +} + +func DeleteOpj_input_memory_stream(arg1 Opj_input_memory_stream) { + _swig_i_0 := getSwigcptr(arg1) + C._wrap_delete_opj_input_memory_stream_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0)) +} + +type Opj_input_memory_stream interface { + Swigcptr() uintptr + SwigIsOpj_input_memory_stream() + SetPData(arg2 OPJ_UINT8) + GetPData() (_swig_ret OPJ_UINT8) + SetDataSize(arg2 OPJ_SIZE_T) + GetDataSize() (_swig_ret OPJ_SIZE_T) + SetOffset(arg2 OPJ_SIZE_T) + GetOffset() (_swig_ret OPJ_SIZE_T) +} + +func Opj_input_memory_stream_seek(arg1 OPJ_OFF_T, arg2 uintptr) (_swig_ret OPJ_BOOL) { + var swig_r OPJ_BOOL + _swig_i_0 := getSwigcptr(arg1) + _swig_i_1 := arg2 + swig_r = (OPJ_BOOL)(SwigcptrOPJ_BOOL(C._wrap_opj_input_memory_stream_seek_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.uintptr_t(_swig_i_1)))) + return swig_r +} + +func Opj_input_memory_stream_skip(arg1 OPJ_OFF_T, arg2 uintptr) (_swig_ret OPJ_OFF_T) { + var swig_r OPJ_OFF_T + _swig_i_0 := getSwigcptr(arg1) + _swig_i_1 := arg2 + swig_r = (OPJ_OFF_T)(SwigcptrOPJ_OFF_T(C._wrap_opj_input_memory_stream_skip_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.uintptr_t(_swig_i_1)))) + return swig_r +} + +func Opj_input_memory_stream_read(arg1 uintptr, arg2 OPJ_SIZE_T, arg3 uintptr) (_swig_ret OPJ_SIZE_T) { + var swig_r OPJ_SIZE_T + _swig_i_0 := arg1 + _swig_i_1 := getSwigcptr(arg2) + _swig_i_2 := arg3 + swig_r = (OPJ_SIZE_T)(SwigcptrOPJ_SIZE_T(C._wrap_opj_input_memory_stream_read_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.uintptr_t(_swig_i_1), C.uintptr_t(_swig_i_2)))) + return swig_r +} + +type SwigcptrOpj_output_memory_stream_chunk uintptr + +func (p SwigcptrOpj_output_memory_stream_chunk) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrOpj_output_memory_stream_chunk) SwigIsOpj_output_memory_stream_chunk() { +} + +func (arg1 SwigcptrOpj_output_memory_stream_chunk) SetData(arg2 OPJ_UINT8) { + _swig_i_0 := arg1 + _swig_i_1 := getSwigcptr(arg2) + C._wrap_opj_output_memory_stream_chunk_data_set_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.uintptr_t(_swig_i_1)) +} + +func (arg1 SwigcptrOpj_output_memory_stream_chunk) GetData() (_swig_ret OPJ_UINT8) { + var swig_r OPJ_UINT8 + _swig_i_0 := arg1 + swig_r = (OPJ_UINT8)(SwigcptrOPJ_UINT8(C._wrap_opj_output_memory_stream_chunk_data_get_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0)))) + return swig_r +} + +func (arg1 SwigcptrOpj_output_memory_stream_chunk) SetDataLen(arg2 OPJ_SIZE_T) { + _swig_i_0 := arg1 + _swig_i_1 := getSwigcptr(arg2) + C._wrap_opj_output_memory_stream_chunk_dataLen_set_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.uintptr_t(_swig_i_1)) +} + +func (arg1 SwigcptrOpj_output_memory_stream_chunk) GetDataLen() (_swig_ret OPJ_SIZE_T) { + var swig_r OPJ_SIZE_T + _swig_i_0 := arg1 + swig_r = (OPJ_SIZE_T)(SwigcptrOPJ_SIZE_T(C._wrap_opj_output_memory_stream_chunk_dataLen_get_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0)))) + return swig_r +} + +func NewOpj_output_memory_stream_chunk() (_swig_ret Opj_output_memory_stream_chunk) { + var swig_r Opj_output_memory_stream_chunk + swig_r = (Opj_output_memory_stream_chunk)(SwigcptrOpj_output_memory_stream_chunk(C._wrap_new_opj_output_memory_stream_chunk_codec_cffb419519a4d845())) + return swig_r +} + +func DeleteOpj_output_memory_stream_chunk(arg1 Opj_output_memory_stream_chunk) { + _swig_i_0 := getSwigcptr(arg1) + C._wrap_delete_opj_output_memory_stream_chunk_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0)) +} + +type Opj_output_memory_stream_chunk interface { + Swigcptr() uintptr + SwigIsOpj_output_memory_stream_chunk() + SetData(arg2 OPJ_UINT8) + GetData() (_swig_ret OPJ_UINT8) + SetDataLen(arg2 OPJ_SIZE_T) + GetDataLen() (_swig_ret OPJ_SIZE_T) +} + +type SwigcptrOpj_output_memory_stream uintptr + +func (p SwigcptrOpj_output_memory_stream) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrOpj_output_memory_stream) SwigIsOpj_output_memory_stream() { +} + +func (arg1 SwigcptrOpj_output_memory_stream) SetDataSize(arg2 OPJ_SIZE_T) { + _swig_i_0 := arg1 + _swig_i_1 := getSwigcptr(arg2) + C._wrap_opj_output_memory_stream_dataSize_set_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.uintptr_t(_swig_i_1)) +} + +func (arg1 SwigcptrOpj_output_memory_stream) GetDataSize() (_swig_ret OPJ_SIZE_T) { + var swig_r OPJ_SIZE_T + _swig_i_0 := arg1 + swig_r = (OPJ_SIZE_T)(SwigcptrOPJ_SIZE_T(C._wrap_opj_output_memory_stream_dataSize_get_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0)))) + return swig_r +} + +func (arg1 SwigcptrOpj_output_memory_stream) SetChunks(arg2 Std_vector_Sl_opj_output_memory_stream_chunk_Sg_) { + _swig_i_0 := arg1 + _swig_i_1 := getSwigcptr(arg2) + C._wrap_opj_output_memory_stream_chunks_set_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.uintptr_t(_swig_i_1)) +} + +func (arg1 SwigcptrOpj_output_memory_stream) GetChunks() (_swig_ret Std_vector_Sl_opj_output_memory_stream_chunk_Sg_) { + var swig_r Std_vector_Sl_opj_output_memory_stream_chunk_Sg_ + _swig_i_0 := arg1 + swig_r = (Std_vector_Sl_opj_output_memory_stream_chunk_Sg_)(SwigcptrStd_vector_Sl_opj_output_memory_stream_chunk_Sg_(C._wrap_opj_output_memory_stream_chunks_get_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0)))) + return swig_r +} + +func NewOpj_output_memory_stream() (_swig_ret Opj_output_memory_stream) { + var swig_r Opj_output_memory_stream + swig_r = (Opj_output_memory_stream)(SwigcptrOpj_output_memory_stream(C._wrap_new_opj_output_memory_stream_codec_cffb419519a4d845())) + return swig_r +} + +func DeleteOpj_output_memory_stream(arg1 Opj_output_memory_stream) { + _swig_i_0 := getSwigcptr(arg1) + C._wrap_delete_opj_output_memory_stream_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0)) +} + +type Opj_output_memory_stream interface { + Swigcptr() uintptr + SwigIsOpj_output_memory_stream() + SetDataSize(arg2 OPJ_SIZE_T) + GetDataSize() (_swig_ret OPJ_SIZE_T) + SetChunks(arg2 Std_vector_Sl_opj_output_memory_stream_chunk_Sg_) + GetChunks() (_swig_ret Std_vector_Sl_opj_output_memory_stream_chunk_Sg_) +} + +func Opj_output_memory_stream_seek(arg1 OPJ_OFF_T, arg2 uintptr) (_swig_ret OPJ_BOOL) { + var swig_r OPJ_BOOL + _swig_i_0 := getSwigcptr(arg1) + _swig_i_1 := arg2 + swig_r = (OPJ_BOOL)(SwigcptrOPJ_BOOL(C._wrap_opj_output_memory_stream_seek_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.uintptr_t(_swig_i_1)))) + return swig_r +} + +func Opj_output_memory_stream_skip(arg1 OPJ_OFF_T, arg2 uintptr) (_swig_ret OPJ_OFF_T) { + var swig_r OPJ_OFF_T + _swig_i_0 := getSwigcptr(arg1) + _swig_i_1 := arg2 + swig_r = (OPJ_OFF_T)(SwigcptrOPJ_OFF_T(C._wrap_opj_output_memory_stream_skip_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.uintptr_t(_swig_i_1)))) + return swig_r +} + +func Opj_output_memory_stream_write(arg1 uintptr, arg2 OPJ_SIZE_T, arg3 uintptr) (_swig_ret OPJ_SIZE_T) { + var swig_r OPJ_SIZE_T + _swig_i_0 := arg1 + _swig_i_1 := getSwigcptr(arg2) + _swig_i_2 := arg3 + swig_r = (OPJ_SIZE_T)(SwigcptrOPJ_SIZE_T(C._wrap_opj_output_memory_stream_write_codec_cffb419519a4d845(C.uintptr_t(_swig_i_0), C.uintptr_t(_swig_i_1), C.uintptr_t(_swig_i_2)))) + return swig_r +} + +func J2K_Decode(arg1 *byte, arg2 int64, arg3 int, arg4 int, arg5 *int64) (_swig_ret *byte) { + var swig_r *byte + _swig_i_0 := arg1 + _swig_i_1 := arg2 + _swig_i_2 := arg3 + _swig_i_3 := arg4 + _swig_i_4 := arg5 + swig_r = (*byte)(C._wrap_J2K_Decode_codec_cffb419519a4d845(C.swig_voidp(_swig_i_0), C.swig_type_12(_swig_i_1), C.swig_intgo(_swig_i_2), C.swig_intgo(_swig_i_3), C.swig_voidp(_swig_i_4))) + return swig_r +} + +func JPEG_Decode(arg1 *byte, arg2 int64, arg3 int, arg4 int, arg5 int, arg6 int, arg7 int, arg8 int, arg9 *int64) (_swig_ret *byte) { + var swig_r *byte + _swig_i_0 := arg1 + _swig_i_1 := arg2 + _swig_i_2 := arg3 + _swig_i_3 := arg4 + _swig_i_4 := arg5 + _swig_i_5 := arg6 + _swig_i_6 := arg7 + _swig_i_7 := arg8 + _swig_i_8 := arg9 + swig_r = (*byte)(C._wrap_JPEG_Decode_codec_cffb419519a4d845(C.swig_voidp(_swig_i_0), C.swig_type_13(_swig_i_1), C.swig_intgo(_swig_i_2), C.swig_intgo(_swig_i_3), C.swig_intgo(_swig_i_4), C.swig_intgo(_swig_i_5), C.swig_intgo(_swig_i_6), C.swig_intgo(_swig_i_7), C.swig_voidp(_swig_i_8))) + return swig_r +} + +func JPEGLS_Decode(arg1 *byte, arg2 int64, arg3 int, arg4 int, arg5 int, arg6 int, arg7 int, arg8 *int64) (_swig_ret *byte) { + var swig_r *byte + _swig_i_0 := arg1 + _swig_i_1 := arg2 + _swig_i_2 := arg3 + _swig_i_3 := arg4 + _swig_i_4 := arg5 + _swig_i_5 := arg6 + _swig_i_6 := arg7 + _swig_i_7 := arg8 + swig_r = (*byte)(C._wrap_JPEGLS_Decode_codec_cffb419519a4d845(C.swig_voidp(_swig_i_0), C.swig_type_14(_swig_i_1), C.swig_intgo(_swig_i_2), C.swig_intgo(_swig_i_3), C.swig_intgo(_swig_i_4), C.swig_intgo(_swig_i_5), C.swig_intgo(_swig_i_6), C.swig_voidp(_swig_i_7))) + return swig_r +} + +func J2K_Encode(arg1 *byte, arg2 int, arg3 int, arg4 int, arg5 int, arg6 int, arg7 *int64) (_swig_ret *byte) { + var swig_r *byte + _swig_i_0 := arg1 + _swig_i_1 := arg2 + _swig_i_2 := arg3 + _swig_i_3 := arg4 + _swig_i_4 := arg5 + _swig_i_5 := arg6 + _swig_i_6 := arg7 + swig_r = (*byte)(C._wrap_J2K_Encode_codec_cffb419519a4d845(C.swig_voidp(_swig_i_0), C.swig_intgo(_swig_i_1), C.swig_intgo(_swig_i_2), C.swig_intgo(_swig_i_3), C.swig_intgo(_swig_i_4), C.swig_intgo(_swig_i_5), C.swig_voidp(_swig_i_6))) + return swig_r +} + + +type SwigcptrOPJ_UINT8 uintptr +type OPJ_UINT8 interface { + Swigcptr() uintptr; +} +func (p SwigcptrOPJ_UINT8) Swigcptr() uintptr { + return uintptr(p) +} + +type SwigcptrOPJ_OFF_T uintptr +type OPJ_OFF_T interface { + Swigcptr() uintptr; +} +func (p SwigcptrOPJ_OFF_T) Swigcptr() uintptr { + return uintptr(p) +} + +type SwigcptrStd_vector_Sl_opj_output_memory_stream_chunk_Sg_ uintptr +type Std_vector_Sl_opj_output_memory_stream_chunk_Sg_ interface { + Swigcptr() uintptr; +} +func (p SwigcptrStd_vector_Sl_opj_output_memory_stream_chunk_Sg_) Swigcptr() uintptr { + return uintptr(p) +} + +type SwigcptrOPJ_SIZE_T uintptr +type OPJ_SIZE_T interface { + Swigcptr() uintptr; +} +func (p SwigcptrOPJ_SIZE_T) Swigcptr() uintptr { + return uintptr(p) +} + +type SwigcptrOPJ_BOOL uintptr +type OPJ_BOOL interface { + Swigcptr() uintptr; +} +func (p SwigcptrOPJ_BOOL) Swigcptr() uintptr { + return uintptr(p) +} + diff --git a/pkg/codec/codec.h b/pkg/codec/codec.h new file mode 100644 index 00000000..73bb3822 --- /dev/null +++ b/pkg/codec/codec.h @@ -0,0 +1,32 @@ +// Copyright (c) 2023 Segmed Inc. +#include "openjpeg.h" +#include + +typedef unsigned char BYTE; +typedef struct +{ + OPJ_UINT8* pData; + OPJ_SIZE_T dataSize; + OPJ_SIZE_T offset; +} opj_input_memory_stream; + +OPJ_BOOL opj_input_memory_stream_seek(OPJ_OFF_T p_nb_bytes, void * p_user_data); +OPJ_OFF_T opj_input_memory_stream_skip(OPJ_OFF_T p_nb_bytes, void * p_user_data); +OPJ_SIZE_T opj_input_memory_stream_read(void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data); + +typedef struct +{ + OPJ_UINT8* data; + OPJ_SIZE_T dataLen; +} opj_output_memory_stream_chunk; + +typedef struct +{ + OPJ_SIZE_T dataSize; + std::vector chunks; +} opj_output_memory_stream; + +OPJ_BOOL opj_output_memory_stream_seek(OPJ_OFF_T p_nb_bytes, void * p_user_data); +OPJ_OFF_T opj_output_memory_stream_skip(OPJ_OFF_T p_nb_bytes, void * p_user_data); +OPJ_SIZE_T opj_output_memory_stream_write(void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data); + diff --git a/pkg/codec/codec.i b/pkg/codec/codec.i new file mode 100644 index 00000000..09b0ab75 --- /dev/null +++ b/pkg/codec/codec.i @@ -0,0 +1,21 @@ +%module codec +%{ +#include "codec.h" +#include "export.h" +%} + +%include +%include "std_string.i" +%include "std_vector.i" + +// This will create 2 wrapped types in Go called +// "StringVector" and "ByteVector" for their respective +// types. +namespace std { + %template(StringVector) vector; + %template(ByteVector) vector; +} + +%include "codec.h" +%include "export.h" + diff --git a/pkg/codec/codec_wrap.cxx b/pkg/codec/codec_wrap.cxx new file mode 100644 index 00000000..cc3e8ab9 --- /dev/null +++ b/pkg/codec/codec_wrap.cxx @@ -0,0 +1,1142 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (https://www.swig.org). + * Version 4.1.1 + * + * Do not make changes to this file unless you know what you are doing - modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +// source: codec.i + + +extern +#ifdef __cplusplus + "C" +#endif + void cgo_panic__codec_cffb419519a4d845(const char*); +static void _swig_gopanic(const char *p) { + cgo_panic__codec_cffb419519a4d845(p); +} + + + +#define SWIG_VERSION 0x040101 +#define SWIGGO +#define SWIGMODULE codec +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* exporting methods */ +#if defined(__GNUC__) +# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + +/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */ +#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) +# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 +#endif + +/* Intel's compiler complains if a variable which was never initialised is + * cast to void, which is a common idiom which we use to indicate that we + * are aware a variable isn't used. So we just silence that warning. + * See: https://github.com/swig/swig/issues/192 for more discussion. + */ +#ifdef __INTEL_COMPILER +# pragma warning disable 592 +#endif + + +#include +#include +#include +#include +#include + + + +typedef long long intgo; +typedef unsigned long long uintgo; + + +# if !defined(__clang__) && (defined(__i386__) || defined(__x86_64__)) +# define SWIGSTRUCTPACKED __attribute__((__packed__, __gcc_struct__)) +# else +# define SWIGSTRUCTPACKED __attribute__((__packed__)) +# endif + + + +typedef struct { char *p; intgo n; } _gostring_; +typedef struct { void* array; intgo len; intgo cap; } _goslice_; + + + +static _gostring_ Swig_AllocateString(const char *p, size_t l) { + _gostring_ ret; + ret.p = (char*)malloc(l); + memcpy(ret.p, p, l); + ret.n = l; + return ret; +} + + +#ifdef __cplusplus +#include +/* SwigValueWrapper is described in swig.swg */ +template class SwigValueWrapper { + struct SwigSmartPointer { + T *ptr; + SwigSmartPointer(T *p) : ptr(p) { } + ~SwigSmartPointer() { delete ptr; } + SwigSmartPointer& operator=(SwigSmartPointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; } + void reset(T *p) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = p; } + } pointer; + SwigValueWrapper& operator=(const SwigValueWrapper& rhs); + SwigValueWrapper(const SwigValueWrapper& rhs); +public: + SwigValueWrapper() : pointer(0) { } + SwigValueWrapper& operator=(const T& t) { SwigSmartPointer tmp(new T(t)); pointer = tmp; return *this; } +#if __cplusplus >=201103L + SwigValueWrapper& operator=(T&& t) { SwigSmartPointer tmp(new T(std::move(t))); pointer = tmp; return *this; } + operator T&&() const { return std::move(*pointer.ptr); } +#else + operator T&() const { return *pointer.ptr; } +#endif + T *operator&() const { return pointer.ptr; } + static void reset(SwigValueWrapper& t, T *p) { t.pointer.reset(p); } +}; + +/* + * SwigValueInit() is a generic initialisation solution as the following approach: + * + * T c_result = T(); + * + * doesn't compile for all types for example: + * + * unsigned int c_result = unsigned int(); + */ +template T SwigValueInit() { + return T(); +} + +#if __cplusplus >=201103L +# define SWIG_STD_MOVE(OBJ) std::move(OBJ) +#else +# define SWIG_STD_MOVE(OBJ) OBJ +#endif + +#endif + + +static void Swig_free(void* p) { + free(p); +} + +static void* Swig_malloc(int c) { + return malloc(c); +} + + +#include "codec.h" +#include "export.h" + + +#include + + +#include +#include + +SWIGINTERN std::vector< std::string >::const_reference std_vector_Sl_std_string_Sg__get(std::vector< std::string > *self,int i){ + int size = int(self->size()); + if (i>=0 && i *self,int i,std::vector< std::string >::value_type const &val){ + int size = int(self->size()); + if (i>=0 && i::const_reference std_vector_Sl_char_Sg__get(std::vector< char > *self,int i){ + int size = int(self->size()); + if (i>=0 && i *self,int i,std::vector< char >::value_type const &val){ + int size = int(self->size()); + if (i>=0 && i *_wrap_new_StringVector__SWIG_0_codec_cffb419519a4d845() { + std::vector< std::string > *result = 0 ; + std::vector< std::string > *_swig_go_result; + + + result = (std::vector< std::string > *)new std::vector< std::string >(); + *(std::vector< std::string > **)&_swig_go_result = (std::vector< std::string > *)result; + return _swig_go_result; +} + + +std::vector< std::string > *_wrap_new_StringVector__SWIG_1_codec_cffb419519a4d845(long long _swig_go_0) { + std::vector< std::string >::size_type arg1 ; + std::vector< std::string > *result = 0 ; + std::vector< std::string > *_swig_go_result; + + arg1 = (size_t)_swig_go_0; + + result = (std::vector< std::string > *)new std::vector< std::string >(arg1); + *(std::vector< std::string > **)&_swig_go_result = (std::vector< std::string > *)result; + return _swig_go_result; +} + + +std::vector< std::string > *_wrap_new_StringVector__SWIG_2_codec_cffb419519a4d845(std::vector< std::string > *_swig_go_0) { + std::vector< std::string > *arg1 = 0 ; + std::vector< std::string > *result = 0 ; + std::vector< std::string > *_swig_go_result; + + arg1 = *(std::vector< std::string > **)&_swig_go_0; + + result = (std::vector< std::string > *)new std::vector< std::string >((std::vector< std::string > const &)*arg1); + *(std::vector< std::string > **)&_swig_go_result = (std::vector< std::string > *)result; + return _swig_go_result; +} + + +long long _wrap_StringVector_size_codec_cffb419519a4d845(std::vector< std::string > *_swig_go_0) { + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::size_type result; + long long _swig_go_result; + + arg1 = *(std::vector< std::string > **)&_swig_go_0; + + result = ((std::vector< std::string > const *)arg1)->size(); + _swig_go_result = result; + return _swig_go_result; +} + + +long long _wrap_StringVector_capacity_codec_cffb419519a4d845(std::vector< std::string > *_swig_go_0) { + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::size_type result; + long long _swig_go_result; + + arg1 = *(std::vector< std::string > **)&_swig_go_0; + + result = ((std::vector< std::string > const *)arg1)->capacity(); + _swig_go_result = result; + return _swig_go_result; +} + + +void _wrap_StringVector_reserve_codec_cffb419519a4d845(std::vector< std::string > *_swig_go_0, long long _swig_go_1) { + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::size_type arg2 ; + + arg1 = *(std::vector< std::string > **)&_swig_go_0; + arg2 = (size_t)_swig_go_1; + + (arg1)->reserve(arg2); + +} + + +bool _wrap_StringVector_isEmpty_codec_cffb419519a4d845(std::vector< std::string > *_swig_go_0) { + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + bool result; + bool _swig_go_result; + + arg1 = *(std::vector< std::string > **)&_swig_go_0; + + result = (bool)((std::vector< std::string > const *)arg1)->empty(); + _swig_go_result = result; + return _swig_go_result; +} + + +void _wrap_StringVector_clear_codec_cffb419519a4d845(std::vector< std::string > *_swig_go_0) { + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + + arg1 = *(std::vector< std::string > **)&_swig_go_0; + + (arg1)->clear(); + +} + + +void _wrap_StringVector_add_codec_cffb419519a4d845(std::vector< std::string > *_swig_go_0, _gostring_ _swig_go_1) { + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + std::vector< std::string >::value_type *arg2 = 0 ; + + arg1 = *(std::vector< std::string > **)&_swig_go_0; + + std::vector< std::string >::value_type arg2_str(_swig_go_1.p, _swig_go_1.n); + arg2 = &arg2_str; + + + (arg1)->push_back((std::vector< std::string >::value_type const &)*arg2); + +} + + +_gostring_ _wrap_StringVector_get_codec_cffb419519a4d845(std::vector< std::string > *_swig_go_0, intgo _swig_go_1) { + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + int arg2 ; + std::vector< std::string >::value_type *result = 0 ; + _gostring_ _swig_go_result; + + arg1 = *(std::vector< std::string > **)&_swig_go_0; + arg2 = (int)_swig_go_1; + + try { + result = (std::vector< std::string >::value_type *) &std_vector_Sl_std_string_Sg__get(arg1,arg2); + } catch(std::out_of_range &_e) { + (void)_e; + _swig_gopanic("C++ std::out_of_range exception thrown"); + + } + _swig_go_result = Swig_AllocateString((*result).data(), (*result).length()); + return _swig_go_result; +} + + +void _wrap_StringVector_set_codec_cffb419519a4d845(std::vector< std::string > *_swig_go_0, intgo _swig_go_1, _gostring_ _swig_go_2) { + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + int arg2 ; + std::vector< std::string >::value_type *arg3 = 0 ; + + arg1 = *(std::vector< std::string > **)&_swig_go_0; + arg2 = (int)_swig_go_1; + + std::vector< std::string >::value_type arg3_str(_swig_go_2.p, _swig_go_2.n); + arg3 = &arg3_str; + + + try { + std_vector_Sl_std_string_Sg__set(arg1,arg2,(std::string const &)*arg3); + } catch(std::out_of_range &_e) { + (void)_e; + _swig_gopanic("C++ std::out_of_range exception thrown"); + + } + +} + + +void _wrap_delete_StringVector_codec_cffb419519a4d845(std::vector< std::string > *_swig_go_0) { + std::vector< std::string > *arg1 = (std::vector< std::string > *) 0 ; + + arg1 = *(std::vector< std::string > **)&_swig_go_0; + + delete arg1; + +} + + +std::vector< char > *_wrap_new_ByteVector__SWIG_0_codec_cffb419519a4d845() { + std::vector< char > *result = 0 ; + std::vector< char > *_swig_go_result; + + + result = (std::vector< char > *)new std::vector< char >(); + *(std::vector< char > **)&_swig_go_result = (std::vector< char > *)result; + return _swig_go_result; +} + + +std::vector< char > *_wrap_new_ByteVector__SWIG_1_codec_cffb419519a4d845(long long _swig_go_0) { + std::vector< char >::size_type arg1 ; + std::vector< char > *result = 0 ; + std::vector< char > *_swig_go_result; + + arg1 = (size_t)_swig_go_0; + + result = (std::vector< char > *)new std::vector< char >(arg1); + *(std::vector< char > **)&_swig_go_result = (std::vector< char > *)result; + return _swig_go_result; +} + + +std::vector< char > *_wrap_new_ByteVector__SWIG_2_codec_cffb419519a4d845(std::vector< char > *_swig_go_0) { + std::vector< char > *arg1 = 0 ; + std::vector< char > *result = 0 ; + std::vector< char > *_swig_go_result; + + arg1 = *(std::vector< char > **)&_swig_go_0; + + result = (std::vector< char > *)new std::vector< char >((std::vector< char > const &)*arg1); + *(std::vector< char > **)&_swig_go_result = (std::vector< char > *)result; + return _swig_go_result; +} + + +long long _wrap_ByteVector_size_codec_cffb419519a4d845(std::vector< char > *_swig_go_0) { + std::vector< char > *arg1 = (std::vector< char > *) 0 ; + std::vector< char >::size_type result; + long long _swig_go_result; + + arg1 = *(std::vector< char > **)&_swig_go_0; + + result = ((std::vector< char > const *)arg1)->size(); + _swig_go_result = result; + return _swig_go_result; +} + + +long long _wrap_ByteVector_capacity_codec_cffb419519a4d845(std::vector< char > *_swig_go_0) { + std::vector< char > *arg1 = (std::vector< char > *) 0 ; + std::vector< char >::size_type result; + long long _swig_go_result; + + arg1 = *(std::vector< char > **)&_swig_go_0; + + result = ((std::vector< char > const *)arg1)->capacity(); + _swig_go_result = result; + return _swig_go_result; +} + + +void _wrap_ByteVector_reserve_codec_cffb419519a4d845(std::vector< char > *_swig_go_0, long long _swig_go_1) { + std::vector< char > *arg1 = (std::vector< char > *) 0 ; + std::vector< char >::size_type arg2 ; + + arg1 = *(std::vector< char > **)&_swig_go_0; + arg2 = (size_t)_swig_go_1; + + (arg1)->reserve(arg2); + +} + + +bool _wrap_ByteVector_isEmpty_codec_cffb419519a4d845(std::vector< char > *_swig_go_0) { + std::vector< char > *arg1 = (std::vector< char > *) 0 ; + bool result; + bool _swig_go_result; + + arg1 = *(std::vector< char > **)&_swig_go_0; + + result = (bool)((std::vector< char > const *)arg1)->empty(); + _swig_go_result = result; + return _swig_go_result; +} + + +void _wrap_ByteVector_clear_codec_cffb419519a4d845(std::vector< char > *_swig_go_0) { + std::vector< char > *arg1 = (std::vector< char > *) 0 ; + + arg1 = *(std::vector< char > **)&_swig_go_0; + + (arg1)->clear(); + +} + + +void _wrap_ByteVector_add_codec_cffb419519a4d845(std::vector< char > *_swig_go_0, char _swig_go_1) { + std::vector< char > *arg1 = (std::vector< char > *) 0 ; + std::vector< char >::value_type *arg2 = 0 ; + + arg1 = *(std::vector< char > **)&_swig_go_0; + arg2 = (std::vector< char >::value_type *)&_swig_go_1; + + (arg1)->push_back((std::vector< char >::value_type const &)*arg2); + +} + + +char _wrap_ByteVector_get_codec_cffb419519a4d845(std::vector< char > *_swig_go_0, intgo _swig_go_1) { + std::vector< char > *arg1 = (std::vector< char > *) 0 ; + int arg2 ; + std::vector< char >::value_type *result = 0 ; + char _swig_go_result; + + arg1 = *(std::vector< char > **)&_swig_go_0; + arg2 = (int)_swig_go_1; + + try { + result = (std::vector< char >::value_type *) &std_vector_Sl_char_Sg__get(arg1,arg2); + } catch(std::out_of_range &_e) { + (void)_e; + _swig_gopanic("C++ std::out_of_range exception thrown"); + + } + _swig_go_result = (char)*result; + return _swig_go_result; +} + + +void _wrap_ByteVector_set_codec_cffb419519a4d845(std::vector< char > *_swig_go_0, intgo _swig_go_1, char _swig_go_2) { + std::vector< char > *arg1 = (std::vector< char > *) 0 ; + int arg2 ; + std::vector< char >::value_type *arg3 = 0 ; + + arg1 = *(std::vector< char > **)&_swig_go_0; + arg2 = (int)_swig_go_1; + arg3 = (std::vector< char >::value_type *)&_swig_go_2; + + try { + std_vector_Sl_char_Sg__set(arg1,arg2,(char const &)*arg3); + } catch(std::out_of_range &_e) { + (void)_e; + _swig_gopanic("C++ std::out_of_range exception thrown"); + + } + +} + + +void _wrap_delete_ByteVector_codec_cffb419519a4d845(std::vector< char > *_swig_go_0) { + std::vector< char > *arg1 = (std::vector< char > *) 0 ; + + arg1 = *(std::vector< char > **)&_swig_go_0; + + delete arg1; + +} + + +void _wrap_opj_input_memory_stream_pData_set_codec_cffb419519a4d845(opj_input_memory_stream *_swig_go_0, OPJ_UINT8 *_swig_go_1) { + opj_input_memory_stream *arg1 = (opj_input_memory_stream *) 0 ; + OPJ_UINT8 *arg2 = (OPJ_UINT8 *) 0 ; + + arg1 = *(opj_input_memory_stream **)&_swig_go_0; + arg2 = *(OPJ_UINT8 **)&_swig_go_1; + + if (arg1) (arg1)->pData = arg2; + +} + + +OPJ_UINT8 *_wrap_opj_input_memory_stream_pData_get_codec_cffb419519a4d845(opj_input_memory_stream *_swig_go_0) { + opj_input_memory_stream *arg1 = (opj_input_memory_stream *) 0 ; + OPJ_UINT8 *result = 0 ; + OPJ_UINT8 *_swig_go_result; + + arg1 = *(opj_input_memory_stream **)&_swig_go_0; + + result = (OPJ_UINT8 *) ((arg1)->pData); + *(OPJ_UINT8 **)&_swig_go_result = (OPJ_UINT8 *)result; + return _swig_go_result; +} + + +void _wrap_opj_input_memory_stream_dataSize_set_codec_cffb419519a4d845(opj_input_memory_stream *_swig_go_0, OPJ_SIZE_T *_swig_go_1) { + opj_input_memory_stream *arg1 = (opj_input_memory_stream *) 0 ; + OPJ_SIZE_T arg2 ; + OPJ_SIZE_T *argp2 ; + + arg1 = *(opj_input_memory_stream **)&_swig_go_0; + + argp2 = (OPJ_SIZE_T *)_swig_go_1; + if (argp2 == NULL) { + _swig_gopanic("Attempt to dereference null OPJ_SIZE_T"); + } + arg2 = (OPJ_SIZE_T)*argp2; + + + if (arg1) (arg1)->dataSize = arg2; + +} + + +OPJ_SIZE_T *_wrap_opj_input_memory_stream_dataSize_get_codec_cffb419519a4d845(opj_input_memory_stream *_swig_go_0) { + opj_input_memory_stream *arg1 = (opj_input_memory_stream *) 0 ; + OPJ_SIZE_T result; + OPJ_SIZE_T *_swig_go_result; + + arg1 = *(opj_input_memory_stream **)&_swig_go_0; + + result = ((arg1)->dataSize); + *(OPJ_SIZE_T **)&_swig_go_result = new OPJ_SIZE_T(result); + return _swig_go_result; +} + + +void _wrap_opj_input_memory_stream_offset_set_codec_cffb419519a4d845(opj_input_memory_stream *_swig_go_0, OPJ_SIZE_T *_swig_go_1) { + opj_input_memory_stream *arg1 = (opj_input_memory_stream *) 0 ; + OPJ_SIZE_T arg2 ; + OPJ_SIZE_T *argp2 ; + + arg1 = *(opj_input_memory_stream **)&_swig_go_0; + + argp2 = (OPJ_SIZE_T *)_swig_go_1; + if (argp2 == NULL) { + _swig_gopanic("Attempt to dereference null OPJ_SIZE_T"); + } + arg2 = (OPJ_SIZE_T)*argp2; + + + if (arg1) (arg1)->offset = arg2; + +} + + +OPJ_SIZE_T *_wrap_opj_input_memory_stream_offset_get_codec_cffb419519a4d845(opj_input_memory_stream *_swig_go_0) { + opj_input_memory_stream *arg1 = (opj_input_memory_stream *) 0 ; + OPJ_SIZE_T result; + OPJ_SIZE_T *_swig_go_result; + + arg1 = *(opj_input_memory_stream **)&_swig_go_0; + + result = ((arg1)->offset); + *(OPJ_SIZE_T **)&_swig_go_result = new OPJ_SIZE_T(result); + return _swig_go_result; +} + + +opj_input_memory_stream *_wrap_new_opj_input_memory_stream_codec_cffb419519a4d845() { + opj_input_memory_stream *result = 0 ; + opj_input_memory_stream *_swig_go_result; + + + result = (opj_input_memory_stream *)new opj_input_memory_stream(); + *(opj_input_memory_stream **)&_swig_go_result = (opj_input_memory_stream *)result; + return _swig_go_result; +} + + +void _wrap_delete_opj_input_memory_stream_codec_cffb419519a4d845(opj_input_memory_stream *_swig_go_0) { + opj_input_memory_stream *arg1 = (opj_input_memory_stream *) 0 ; + + arg1 = *(opj_input_memory_stream **)&_swig_go_0; + + delete arg1; + +} + + +OPJ_BOOL *_wrap_opj_input_memory_stream_seek_codec_cffb419519a4d845(OPJ_OFF_T *_swig_go_0, void *_swig_go_1) { + OPJ_OFF_T arg1 ; + void *arg2 = (void *) 0 ; + OPJ_OFF_T *argp1 ; + OPJ_BOOL result; + OPJ_BOOL *_swig_go_result; + + + argp1 = (OPJ_OFF_T *)_swig_go_0; + if (argp1 == NULL) { + _swig_gopanic("Attempt to dereference null OPJ_OFF_T"); + } + arg1 = (OPJ_OFF_T)*argp1; + + arg2 = *(void **)&_swig_go_1; + + result = opj_input_memory_stream_seek(SWIG_STD_MOVE(arg1),arg2); + *(OPJ_BOOL **)&_swig_go_result = new OPJ_BOOL(result); + return _swig_go_result; +} + + +OPJ_OFF_T *_wrap_opj_input_memory_stream_skip_codec_cffb419519a4d845(OPJ_OFF_T *_swig_go_0, void *_swig_go_1) { + OPJ_OFF_T arg1 ; + void *arg2 = (void *) 0 ; + OPJ_OFF_T *argp1 ; + OPJ_OFF_T result; + OPJ_OFF_T *_swig_go_result; + + + argp1 = (OPJ_OFF_T *)_swig_go_0; + if (argp1 == NULL) { + _swig_gopanic("Attempt to dereference null OPJ_OFF_T"); + } + arg1 = (OPJ_OFF_T)*argp1; + + arg2 = *(void **)&_swig_go_1; + + result = opj_input_memory_stream_skip(SWIG_STD_MOVE(arg1),arg2); + *(OPJ_OFF_T **)&_swig_go_result = new OPJ_OFF_T(result); + return _swig_go_result; +} + + +OPJ_SIZE_T *_wrap_opj_input_memory_stream_read_codec_cffb419519a4d845(void *_swig_go_0, OPJ_SIZE_T *_swig_go_1, void *_swig_go_2) { + void *arg1 = (void *) 0 ; + OPJ_SIZE_T arg2 ; + void *arg3 = (void *) 0 ; + OPJ_SIZE_T *argp2 ; + OPJ_SIZE_T result; + OPJ_SIZE_T *_swig_go_result; + + arg1 = *(void **)&_swig_go_0; + + argp2 = (OPJ_SIZE_T *)_swig_go_1; + if (argp2 == NULL) { + _swig_gopanic("Attempt to dereference null OPJ_SIZE_T"); + } + arg2 = (OPJ_SIZE_T)*argp2; + + arg3 = *(void **)&_swig_go_2; + + result = opj_input_memory_stream_read(arg1,SWIG_STD_MOVE(arg2),arg3); + *(OPJ_SIZE_T **)&_swig_go_result = new OPJ_SIZE_T(result); + return _swig_go_result; +} + + +void _wrap_opj_output_memory_stream_chunk_data_set_codec_cffb419519a4d845(opj_output_memory_stream_chunk *_swig_go_0, OPJ_UINT8 *_swig_go_1) { + opj_output_memory_stream_chunk *arg1 = (opj_output_memory_stream_chunk *) 0 ; + OPJ_UINT8 *arg2 = (OPJ_UINT8 *) 0 ; + + arg1 = *(opj_output_memory_stream_chunk **)&_swig_go_0; + arg2 = *(OPJ_UINT8 **)&_swig_go_1; + + if (arg1) (arg1)->data = arg2; + +} + + +OPJ_UINT8 *_wrap_opj_output_memory_stream_chunk_data_get_codec_cffb419519a4d845(opj_output_memory_stream_chunk *_swig_go_0) { + opj_output_memory_stream_chunk *arg1 = (opj_output_memory_stream_chunk *) 0 ; + OPJ_UINT8 *result = 0 ; + OPJ_UINT8 *_swig_go_result; + + arg1 = *(opj_output_memory_stream_chunk **)&_swig_go_0; + + result = (OPJ_UINT8 *) ((arg1)->data); + *(OPJ_UINT8 **)&_swig_go_result = (OPJ_UINT8 *)result; + return _swig_go_result; +} + + +void _wrap_opj_output_memory_stream_chunk_dataLen_set_codec_cffb419519a4d845(opj_output_memory_stream_chunk *_swig_go_0, OPJ_SIZE_T *_swig_go_1) { + opj_output_memory_stream_chunk *arg1 = (opj_output_memory_stream_chunk *) 0 ; + OPJ_SIZE_T arg2 ; + OPJ_SIZE_T *argp2 ; + + arg1 = *(opj_output_memory_stream_chunk **)&_swig_go_0; + + argp2 = (OPJ_SIZE_T *)_swig_go_1; + if (argp2 == NULL) { + _swig_gopanic("Attempt to dereference null OPJ_SIZE_T"); + } + arg2 = (OPJ_SIZE_T)*argp2; + + + if (arg1) (arg1)->dataLen = arg2; + +} + + +OPJ_SIZE_T *_wrap_opj_output_memory_stream_chunk_dataLen_get_codec_cffb419519a4d845(opj_output_memory_stream_chunk *_swig_go_0) { + opj_output_memory_stream_chunk *arg1 = (opj_output_memory_stream_chunk *) 0 ; + OPJ_SIZE_T result; + OPJ_SIZE_T *_swig_go_result; + + arg1 = *(opj_output_memory_stream_chunk **)&_swig_go_0; + + result = ((arg1)->dataLen); + *(OPJ_SIZE_T **)&_swig_go_result = new OPJ_SIZE_T(result); + return _swig_go_result; +} + + +opj_output_memory_stream_chunk *_wrap_new_opj_output_memory_stream_chunk_codec_cffb419519a4d845() { + opj_output_memory_stream_chunk *result = 0 ; + opj_output_memory_stream_chunk *_swig_go_result; + + + result = (opj_output_memory_stream_chunk *)new opj_output_memory_stream_chunk(); + *(opj_output_memory_stream_chunk **)&_swig_go_result = (opj_output_memory_stream_chunk *)result; + return _swig_go_result; +} + + +void _wrap_delete_opj_output_memory_stream_chunk_codec_cffb419519a4d845(opj_output_memory_stream_chunk *_swig_go_0) { + opj_output_memory_stream_chunk *arg1 = (opj_output_memory_stream_chunk *) 0 ; + + arg1 = *(opj_output_memory_stream_chunk **)&_swig_go_0; + + delete arg1; + +} + + +void _wrap_opj_output_memory_stream_dataSize_set_codec_cffb419519a4d845(opj_output_memory_stream *_swig_go_0, OPJ_SIZE_T *_swig_go_1) { + opj_output_memory_stream *arg1 = (opj_output_memory_stream *) 0 ; + OPJ_SIZE_T arg2 ; + OPJ_SIZE_T *argp2 ; + + arg1 = *(opj_output_memory_stream **)&_swig_go_0; + + argp2 = (OPJ_SIZE_T *)_swig_go_1; + if (argp2 == NULL) { + _swig_gopanic("Attempt to dereference null OPJ_SIZE_T"); + } + arg2 = (OPJ_SIZE_T)*argp2; + + + if (arg1) (arg1)->dataSize = arg2; + +} + + +OPJ_SIZE_T *_wrap_opj_output_memory_stream_dataSize_get_codec_cffb419519a4d845(opj_output_memory_stream *_swig_go_0) { + opj_output_memory_stream *arg1 = (opj_output_memory_stream *) 0 ; + OPJ_SIZE_T result; + OPJ_SIZE_T *_swig_go_result; + + arg1 = *(opj_output_memory_stream **)&_swig_go_0; + + result = ((arg1)->dataSize); + *(OPJ_SIZE_T **)&_swig_go_result = new OPJ_SIZE_T(result); + return _swig_go_result; +} + + +void _wrap_opj_output_memory_stream_chunks_set_codec_cffb419519a4d845(opj_output_memory_stream *_swig_go_0, std::vector< opj_output_memory_stream_chunk > *_swig_go_1) { + opj_output_memory_stream *arg1 = (opj_output_memory_stream *) 0 ; + std::vector< opj_output_memory_stream_chunk > *arg2 = (std::vector< opj_output_memory_stream_chunk > *) 0 ; + + arg1 = *(opj_output_memory_stream **)&_swig_go_0; + arg2 = *(std::vector< opj_output_memory_stream_chunk > **)&_swig_go_1; + + if (arg1) (arg1)->chunks = *arg2; + +} + + +std::vector< opj_output_memory_stream_chunk > *_wrap_opj_output_memory_stream_chunks_get_codec_cffb419519a4d845(opj_output_memory_stream *_swig_go_0) { + opj_output_memory_stream *arg1 = (opj_output_memory_stream *) 0 ; + std::vector< opj_output_memory_stream_chunk > *result = 0 ; + std::vector< opj_output_memory_stream_chunk > *_swig_go_result; + + arg1 = *(opj_output_memory_stream **)&_swig_go_0; + + result = (std::vector< opj_output_memory_stream_chunk > *)& ((arg1)->chunks); + *(std::vector< opj_output_memory_stream_chunk > **)&_swig_go_result = (std::vector< opj_output_memory_stream_chunk > *)result; + return _swig_go_result; +} + + +opj_output_memory_stream *_wrap_new_opj_output_memory_stream_codec_cffb419519a4d845() { + opj_output_memory_stream *result = 0 ; + opj_output_memory_stream *_swig_go_result; + + + result = (opj_output_memory_stream *)new opj_output_memory_stream(); + *(opj_output_memory_stream **)&_swig_go_result = (opj_output_memory_stream *)result; + return _swig_go_result; +} + + +void _wrap_delete_opj_output_memory_stream_codec_cffb419519a4d845(opj_output_memory_stream *_swig_go_0) { + opj_output_memory_stream *arg1 = (opj_output_memory_stream *) 0 ; + + arg1 = *(opj_output_memory_stream **)&_swig_go_0; + + delete arg1; + +} + + +OPJ_BOOL *_wrap_opj_output_memory_stream_seek_codec_cffb419519a4d845(OPJ_OFF_T *_swig_go_0, void *_swig_go_1) { + OPJ_OFF_T arg1 ; + void *arg2 = (void *) 0 ; + OPJ_OFF_T *argp1 ; + OPJ_BOOL result; + OPJ_BOOL *_swig_go_result; + + + argp1 = (OPJ_OFF_T *)_swig_go_0; + if (argp1 == NULL) { + _swig_gopanic("Attempt to dereference null OPJ_OFF_T"); + } + arg1 = (OPJ_OFF_T)*argp1; + + arg2 = *(void **)&_swig_go_1; + + result = opj_output_memory_stream_seek(SWIG_STD_MOVE(arg1),arg2); + *(OPJ_BOOL **)&_swig_go_result = new OPJ_BOOL(result); + return _swig_go_result; +} + + +OPJ_OFF_T *_wrap_opj_output_memory_stream_skip_codec_cffb419519a4d845(OPJ_OFF_T *_swig_go_0, void *_swig_go_1) { + OPJ_OFF_T arg1 ; + void *arg2 = (void *) 0 ; + OPJ_OFF_T *argp1 ; + OPJ_OFF_T result; + OPJ_OFF_T *_swig_go_result; + + + argp1 = (OPJ_OFF_T *)_swig_go_0; + if (argp1 == NULL) { + _swig_gopanic("Attempt to dereference null OPJ_OFF_T"); + } + arg1 = (OPJ_OFF_T)*argp1; + + arg2 = *(void **)&_swig_go_1; + + result = opj_output_memory_stream_skip(SWIG_STD_MOVE(arg1),arg2); + *(OPJ_OFF_T **)&_swig_go_result = new OPJ_OFF_T(result); + return _swig_go_result; +} + + +OPJ_SIZE_T *_wrap_opj_output_memory_stream_write_codec_cffb419519a4d845(void *_swig_go_0, OPJ_SIZE_T *_swig_go_1, void *_swig_go_2) { + void *arg1 = (void *) 0 ; + OPJ_SIZE_T arg2 ; + void *arg3 = (void *) 0 ; + OPJ_SIZE_T *argp2 ; + OPJ_SIZE_T result; + OPJ_SIZE_T *_swig_go_result; + + arg1 = *(void **)&_swig_go_0; + + argp2 = (OPJ_SIZE_T *)_swig_go_1; + if (argp2 == NULL) { + _swig_gopanic("Attempt to dereference null OPJ_SIZE_T"); + } + arg2 = (OPJ_SIZE_T)*argp2; + + arg3 = *(void **)&_swig_go_2; + + result = opj_output_memory_stream_write(arg1,SWIG_STD_MOVE(arg2),arg3); + *(OPJ_SIZE_T **)&_swig_go_result = new OPJ_SIZE_T(result); + return _swig_go_result; +} + + +char *_wrap_J2K_Decode_codec_cffb419519a4d845(char *_swig_go_0, long long _swig_go_1, intgo _swig_go_2, intgo _swig_go_3, long long *_swig_go_4) { + unsigned char *arg1 = (unsigned char *) 0 ; + size_t arg2 ; + int arg3 ; + int arg4 ; + size_t *arg5 = (size_t *) 0 ; + unsigned char *result = 0 ; + char *_swig_go_result; + + arg1 = *(unsigned char **)&_swig_go_0; + arg2 = (size_t)_swig_go_1; + arg3 = (int)_swig_go_2; + arg4 = (int)_swig_go_3; + arg5 = *(size_t **)&_swig_go_4; + + result = (unsigned char *)J2K_Decode(arg1,SWIG_STD_MOVE(arg2),arg3,arg4,arg5); + *(unsigned char **)&_swig_go_result = (unsigned char *)result; + return _swig_go_result; +} + + +char *_wrap_JPEG_Decode_codec_cffb419519a4d845(char *_swig_go_0, long long _swig_go_1, intgo _swig_go_2, intgo _swig_go_3, intgo _swig_go_4, intgo _swig_go_5, intgo _swig_go_6, intgo _swig_go_7, long long *_swig_go_8) { + unsigned char *arg1 = (unsigned char *) 0 ; + size_t arg2 ; + int arg3 ; + int arg4 ; + int arg5 ; + int arg6 ; + int arg7 ; + int arg8 ; + size_t *arg9 = (size_t *) 0 ; + unsigned char *result = 0 ; + char *_swig_go_result; + + arg1 = *(unsigned char **)&_swig_go_0; + arg2 = (size_t)_swig_go_1; + arg3 = (int)_swig_go_2; + arg4 = (int)_swig_go_3; + arg5 = (int)_swig_go_4; + arg6 = (int)_swig_go_5; + arg7 = (int)_swig_go_6; + arg8 = (int)_swig_go_7; + arg9 = *(size_t **)&_swig_go_8; + + result = (unsigned char *)JPEG_Decode(arg1,SWIG_STD_MOVE(arg2),arg3,arg4,arg5,arg6,arg7,arg8,arg9); + *(unsigned char **)&_swig_go_result = (unsigned char *)result; + return _swig_go_result; +} + + +char *_wrap_JPEGLS_Decode_codec_cffb419519a4d845(char *_swig_go_0, long long _swig_go_1, intgo _swig_go_2, intgo _swig_go_3, intgo _swig_go_4, intgo _swig_go_5, intgo _swig_go_6, long long *_swig_go_7) { + unsigned char *arg1 = (unsigned char *) 0 ; + size_t arg2 ; + int arg3 ; + int arg4 ; + int arg5 ; + int arg6 ; + int arg7 ; + size_t *arg8 = (size_t *) 0 ; + unsigned char *result = 0 ; + char *_swig_go_result; + + arg1 = *(unsigned char **)&_swig_go_0; + arg2 = (size_t)_swig_go_1; + arg3 = (int)_swig_go_2; + arg4 = (int)_swig_go_3; + arg5 = (int)_swig_go_4; + arg6 = (int)_swig_go_5; + arg7 = (int)_swig_go_6; + arg8 = *(size_t **)&_swig_go_7; + + result = (unsigned char *)JPEGLS_Decode(arg1,SWIG_STD_MOVE(arg2),arg3,arg4,arg5,arg6,arg7,arg8); + *(unsigned char **)&_swig_go_result = (unsigned char *)result; + return _swig_go_result; +} + + +char *_wrap_J2K_Encode_codec_cffb419519a4d845(char *_swig_go_0, intgo _swig_go_1, intgo _swig_go_2, intgo _swig_go_3, intgo _swig_go_4, intgo _swig_go_5, long long *_swig_go_6) { + unsigned char *arg1 = (unsigned char *) 0 ; + int arg2 ; + int arg3 ; + int arg4 ; + int arg5 ; + int arg6 ; + size_t *arg7 = (size_t *) 0 ; + unsigned char *result = 0 ; + char *_swig_go_result; + + arg1 = *(unsigned char **)&_swig_go_0; + arg2 = (int)_swig_go_1; + arg3 = (int)_swig_go_2; + arg4 = (int)_swig_go_3; + arg5 = (int)_swig_go_4; + arg6 = (int)_swig_go_5; + arg7 = *(size_t **)&_swig_go_6; + + result = (unsigned char *)J2K_Encode(arg1,arg2,arg3,arg4,arg5,arg6,arg7); + *(unsigned char **)&_swig_go_result = (unsigned char *)result; + return _swig_go_result; +} + + +#ifdef __cplusplus +} +#endif + diff --git a/pkg/codec/decoder.go b/pkg/codec/decoder.go new file mode 100644 index 00000000..49de6d0a --- /dev/null +++ b/pkg/codec/decoder.go @@ -0,0 +1,155 @@ +// Copyright (c) 2023 Segmed Inc +package codec + +/* +#include +*/ +import "C" +import ( + "bufio" + "bytes" + "encoding/binary" + "errors" + "fmt" + "image" + "image/color" + "strings" + "unsafe" + + "github.com/suyashkumar/dicom/pkg/dicomio" + "github.com/suyashkumar/dicom/pkg/frame" +) + +// GetNativePixelData reads a JPEG-compressed DICOM image, decompresses the JPEG data (i. e. conversion to a +// native DICOM transfer syntax) and returns the converted image +func GetNativePixelData(e frame.EncapsulatedFrame) ([]byte, error) { + var ( + dataOut *byte + outLen int64 + comp = TransferSyntaxUIDToCompressionMethod[e.TransferSyntax] + ) + var ( + dataIn = (*byte)(&e.Data[0]) + length = int64(len(e.Data)) + bitsAllocated = e.BitsAllocated + ) + switch comp { + case JPEG2000Compression: + dataOut = J2K_Decode(dataIn, length, e.Cols, e.Rows, &outLen) + case JPEGLSCompression: + dataOut = JPEGLS_Decode(dataIn, length, bitsAllocated, e.Cols, e.Rows, e.SamplesPerPixel, e.PlanarConfiguration, &outLen) + case JPEGCompression: + ybr := 0 + if strings.HasPrefix(e.PhotometricInterpretation, "YBR_") { + ybr = 1 + } + dataOut = JPEG_Decode(dataIn, length, bitsAllocated, e.Cols, e.Rows, e.SamplesPerPixel, e.PlanarConfiguration, ybr, &outLen) + default: + return nil, errors.New("unsupported transfer syntax") + } + if outLen == 0 { + return nil, errors.New("failed to decode DICOM") + } + defer C.free(unsafe.Pointer(dataOut)) + return makeSliceFromByte(dataOut, uint32(outLen)), nil +} + +// GetStdImage returns the converted image in Go standard format +func GetStdImage(e frame.EncapsulatedFrame) (image.Image, error) { + buf := bytes.NewBuffer(e.Data) + r := dicomio.NewReader(bufio.NewReader(buf), binary.LittleEndian, int64(len(e.Data))) + var ( + upLeft = image.Point{0, 0} + lowRight = image.Point{e.Cols, e.Rows} + img8 = image.NewRGBA(image.Rectangle{upLeft, lowRight}) + img16 = image.NewRGBA64(image.Rectangle{upLeft, lowRight}) + samplesPerPixel int + values8 [3]uint8 // red, green, blue + values16 [3]uint16 + cols = e.Cols + a = 0xffff + i = 0 + ) + if e.BitsAllocated == 8 { + for !r.IsLimitExhausted() { + i++ + v, err := r.ReadUInt8() + if err != nil { + return nil, fmt.Errorf("read uint8 failed: %w", err) + } + values8[samplesPerPixel%3] = v + samplesPerPixel++ + if samplesPerPixel < e.SamplesPerPixel { + continue + } + var clr color.Color + switch samplesPerPixel { + case 1: + clr = color.Gray{Y: values8[0]} + case 3: + r, g, b := values8[0], values8[1], values8[2] + clr = color.RGBA{r, g, b, uint8(a)} + } + img8.Set(i%cols, i/cols, clr) + samplesPerPixel = 0 + } + return img8, nil + } + for !r.IsLimitExhausted() { + i++ + v, err := r.ReadUInt16() + if err != nil { + return nil, fmt.Errorf("read uint16 failed: %w", err) + } + values16[samplesPerPixel%3] = v + samplesPerPixel++ + if samplesPerPixel < e.SamplesPerPixel { + continue + } + var clr color.Color + switch samplesPerPixel { + case 1: + clr = color.Gray16{Y: values16[0]} + case 3: + r, g, b := values16[0], values16[1], values16[2] + clr = color.RGBA64{r, g, b, uint16(a)} + } + img16.Set(i%cols, i/cols, clr) + samplesPerPixel = 0 + } + return img16, nil +} + +// Decode reads a JPEG image from EncapsulatedFrame and returns it as an NativeFrame. +func Decode(e frame.EncapsulatedFrame) (frame.NativeFrame, error) { + img, err := GetStdImage(e) + if err != nil { + return frame.NativeFrame{}, fmt.Errorf("get Go's std image: %w", err) + } + var nativeData [][]int + for i := 0; i < e.Cols*e.Rows; i++ { + clr := img.At(i%e.Cols, i/e.Cols) + r, g, b, a := clr.RGBA() + switch e.SamplesPerPixel { + case 1: + nativeData = append(nativeData, []int{int(r)}) + case 3: + nativeData = append(nativeData, []int{int(r), int(g), int(b)}) + case 4: + nativeData = append(nativeData, []int{int(r), int(g), int(b), int(a)}) + } + } + nf := frame.NativeFrame{ + BitsPerSample: e.BitsAllocated, + Cols: e.Cols, + Rows: e.Rows, + Data: nativeData, + } + return nf, nil +} + +func init() { + for transferSyntax := range TransferSyntaxUIDToCompressionMethod { + frame.RegisterFormat(transferSyntax, Decode) + } +} diff --git a/pkg/codec/decoder_test.go b/pkg/codec/decoder_test.go new file mode 100644 index 00000000..e27c68a8 --- /dev/null +++ b/pkg/codec/decoder_test.go @@ -0,0 +1,144 @@ +// Copyright (c) 2023 Segmed Inc. +package codec + +import ( + "bufio" + "bytes" + "image/jpeg" + "os" + "strings" + "testing" + + "github.com/suyashkumar/dicom/pkg/frame" +) + +type testify struct { + in string + out string + transferSyntax string + w, h, prec, numcomps int +} + +func TestMonoDecompresing(t *testing.T) { + for _, tc := range []testify{ + { + in: "testdata/a1_mono.j2c", + out: "testdata/a1_mono.ppm", + w: 303, + h: 179, + prec: 8, + numcomps: 1, + transferSyntax: "1.2.840.10008.1.2.4.90", // JPEG2000 Image Compression + }, + { + in: "testdata/3_jpeg.dcm.1.raw", + out: "testdata/3.dcm.0.raw", + w: 176, + h: 176, + prec: 16, + numcomps: 1, + transferSyntax: "1.2.840.10008.1.2.4.50", // JPEGProcess1TransferSyntax + }, + { + in: "testdata/1_jpls.dcm.3.raw", + out: "testdata/1.dcm.1.raw", + w: 64, + h: 64, + prec: 8, + numcomps: 1, + transferSyntax: "1.2.840.10008.1.2.4.80", // JPEG-LS Lossless + }, + } { + t.Run("decompress_"+tc.in, func(t *testing.T) { + assertJPEGDecompressing(t, tc) + }) + } +} + +func readPPMPixelData(t testing.TB, fn string) []byte { + file, err := os.Open(fn) + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { + if file.Close() != nil { + t.Fatal(err) + } + }) + scanner := bufio.NewScanner(file) + var ( + expectedData []byte + i int + ) + for scanner.Scan() { + if strings.HasPrefix(scanner.Text(), "#") { + continue + } + i++ + if i < 4 { + continue + } + expectedData = scanner.Bytes() + break + } + return expectedData +} + +func assertJPEGDecompressing(t *testing.T, tc testify) { + input, err := os.ReadFile(tc.in) + if err != nil { + t.Fatal(err) + } + fr := frame.EncapsulatedFrame{ + Data: input, + Rows: tc.h, + Cols: tc.w, + BitsAllocated: tc.prec, + SamplesPerPixel: tc.numcomps, + TransferSyntax: tc.transferSyntax, + } + uncompressedBytes, err := GetNativePixelData(fr) + if err != nil { + t.Fatal(err) + } + if len(uncompressedBytes) == 0 { + t.Fatal("failed to decode image") + } + + fr.Data = uncompressedBytes + img, err := GetStdImage(fr) + if err != nil { + t.Fatal(err) + } + + // convert to jpeg using go std lib + buf := new(bytes.Buffer) + err = jpeg.Encode(buf, img, nil) + if err != nil { + t.Fatal(err) + } + var expectedData []byte + if strings.HasSuffix(tc.out, ".ppm") { + expectedData = readPPMPixelData(t, tc.out) + } + if strings.HasSuffix(tc.out, ".raw") { + expectedData, err = os.ReadFile(tc.out) + if err != nil { + t.Fatal(err) + } + } + + n := 10 + if !bytes.Equal(expectedData[:n], uncompressedBytes[:n]) { + for i := 0; i < n; i++ { + t.Logf("read byte %d in binary, expected %08b, got %08b", i, expectedData[i], uncompressedBytes[i]) + } + t.Errorf("read the first %d bytes of %s: expected %v got %v", n, tc.out, expectedData[:n], uncompressedBytes[:n]) + } + if len(uncompressedBytes) != len(expectedData) { + t.Fatalf("read %s: expected length=%d, got %d", tc.out, len(expectedData), len(uncompressedBytes)) + } + if !bytes.Equal(expectedData, uncompressedBytes) { + t.Fatalf("read %s: expected %v got %v", tc.out, expectedData, uncompressedBytes) + } +} diff --git a/pkg/codec/export.h b/pkg/codec/export.h new file mode 100644 index 00000000..c8a20813 --- /dev/null +++ b/pkg/codec/export.h @@ -0,0 +1,6 @@ +#include + +unsigned char * J2K_Decode(unsigned char * dataIn, size_t length, int width, int height, size_t * lenOut); +unsigned char * JPEG_Decode(unsigned char * dataIn, size_t length, int bitsAllocated, int width, int height, int samplesPerPixel, int planarConfiguration, int ybr, size_t * lenOut); +unsigned char * JPEGLS_Decode(unsigned char * dataIn, size_t length, int bitsAllocated, int width, int height, int samplesPerPixel, int planarConfiguration, size_t * lenOut); +unsigned char * J2K_Encode(unsigned char * dataIn, int bitsAllocated, int width, int height, int samplesPerPixel, int planarConfiguration, size_t * lenOut); diff --git a/pkg/codec/lib.go b/pkg/codec/lib.go new file mode 100644 index 00000000..af7bd2b5 --- /dev/null +++ b/pkg/codec/lib.go @@ -0,0 +1,6 @@ +// Package codec provides JPEG/J2K/JPEG-LS encoder and decoder +// Copyright (c) 2023 Segmed Inc. +package codec + +// #cgo pkg-config: libopenjp2 dcmtk charls +import "C" diff --git a/pkg/codec/testdata/1.dcm.1.raw b/pkg/codec/testdata/1.dcm.1.raw new file mode 100644 index 0000000000000000000000000000000000000000..21d755eae71962dc76c2840e21d4b58c6a9a95d3 GIT binary patch literal 56448 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 literal 0 HcmV?d00001 diff --git a/pkg/codec/testdata/1_jpls.dcm.3.raw b/pkg/codec/testdata/1_jpls.dcm.3.raw new file mode 100644 index 0000000000000000000000000000000000000000..6162137395b216ae2d4a7cdbd69adf53b3278bdc GIT binary patch literal 4440 zcmWlZc|6pK|HnV`nK3??VT_}Xdu9xc`y(nL&A9J74T(WoiHyxv+012}3CWftSE-fc zDBsdGW8A51+KAnVvPnX1MPh#aUjIH{f4m;=<0T!JeghN;z*XQX3Z)E4R{=aqDg}su z6G|1JOD6ybg#vy`nkCITTZ;o5=`ac);Q(0<3&x^>k!cu*1u$5E3SdzH#6bfbhZATt z`u{yR6hNl|5UltWD}zGO?Z!cX4x!J}MIBr|7JU^)b`(Qc;4GJ83ZgitenDfgQD`i{ z5wSD`fGR8lyrh#L5GC~-VI{wT5eHj7$^j>D3KN(JtCc`tLa^0sL}Ux1(Kt945%qy6 z2*TmC?SBRWOFQjg)yioUK~pmf{9Kz85GMN5pU2~h`t1<6QWRj3=YPCuQ?n-6dI@% zz?M7_AFFp6#6im>EKC$ZF|as_E9Qe37z^PPF(QP%85aWzkd7UX|n;G(8oEd?-(#DyV0ls*cLlea9ySU|8kbSS1@<2)qpV~JWbR|HX5nn(yM zA`{2_SqP+w=1br}un=L9;~e6;{i6yYUqm^Z6QdZw19&j2!4f7HC7+Mm&hG*RGH|mT z48u@54-3%Q4BXFwlZ6;fS9wbuL1Kl}4p~{L@E1|^050#W;xS7aonB|-Bm=RcD!V}e zL1MJcip)c*40faokXX6Ld5A>LQ}O3H`16!=$%Syp!A1;Dl~k9@7=|plIOm=60_2;3 z5G&`6^i6`w=fQPKw<3y5hIyk2kY$PBHRcy2CINbZP001`vjMZH6agZzT%BeXNdz@g;r{G5vQbj`GrGJD5{P9K{;f(1eW7rZ|g(y`5;IViMh367J)`ph2$-N zr1PSb>A72TKxn#~4?=u2mJ#=|5Qm}ia>&f^vfvQ&-WZfW#Wb0oEw2g%>uN(Rkys>l zq|>=5X>|Jzh*0NPL}Tk0!UU28VKMjs1uB$bacVG^bF2Vef5&!>*Ig3+DdXr`8Hc|g*1}D>`{<<;Y^7{hDVQ+K~XB8x_p|Rq_3hZ z)|hH>+|3k$S@}>siw8&XFaiQOaG>=>@2p!)nESxESRdPK6N*2=n4d zB+i-WUZ3yI_`d5=Se4p{vnC*-+u+m+u|}@j>8ba$tf;i1D;?3)`yP2VL?kDbdF$ zhmXpq7%Ky!?>rZb*VYf(rkK43#(}cy-?WQv>FD55XojfR9POthM+vHmrMYSmql7T) zn*Qp@Y9mC+w}mc6v6*Bc{=5bj>*eSuCK>H*CAof$=rF{1lsB8j1!aBu*wFzS$5V(h zptg}?Z3>t}JewWdBlcb9Zmt z4fxV&I>;d?bfw4FvT7FoNqwrU;`olCtB`lTjH_fkn+n~o(T3+paPJvZXccpWeKbE)`Ro481p72 zQky=H%CX1aRtiZtKuS&oI1p1h0CHBJkBS)xP13V>+Lm`zZj3+?}8yKv)n-+H^<_! zI7dcYB;LC6_F#>kl1_BtJO2<9$v~aVHksm@5a)yCzsJ!EbZGc`57e2nPu3@u4{;f? z3?vRi*Qm?33k!OPE2|#^Q}U-Zujv4y7)g3ec|rDZU_ zH*>g9d28PJq|)P^+8GV4rzM>)Iy(Li{2c}#so zh|WG@%541)dssa!C19~S@nb}5NKNP1xJO>|>fM9)C@m++4F|cb#v=!HONjPIk6F~^ zGUijP{F-ktmh zt=V6FZyZdCem6SV^e~X2AeWh;td?AtWUQtiR$@Z6pLaM%#o!q_a>m;j#{0;2t(t!2 z+YetR;^JCScv_H)*ULA@9S1dbh3=^&PluPDOmF=BD$dns$=v?jtXaZ%tr+9->ytLM z6*E_e7aUeh>Qmd9&=E_&wXMHpNti8!zR5sM*$cHHMR;iIpX8K3eE5j(N9OC|_DOtkQSG3u>Qr#)uT^Qy zemj&cGv9ZZj2-BF)BL7orJ`*u(J-j-ituRmd1s>hq`Lemk)cOO-dQPF zI!*F}=9=!T4;3w3qPW;%Lm#&Lw*9qn*er5>c2A2->VuK6>b=z1@CL2Wb0d$v)IB?$ z^VAMMr?UVX&xyVpFsnn>I@Dlja$f*WI4U_dXuXi8pW?H<;qL=`v?W8om%M5R&KMkIVnKFn>T7#0cyY^Q;&MJ|-nZn>v?Vd=R~OzVnG97~Syq)!E)xAKbk+0I(3D4pspDMv zp8W-%lZ3;MrxdD2TAtV2dSsP3?DJ-WkYtbvn40ELfsAr}yU3gViMii6vU&>9)@a_6 zYMGj!?*7bv(?8quc6E%mPG$Dsog7*^-v>XdGW0niF*w#6U%A4uO5J{XOCm>v(rAK+ zK(V)yaJfhcUm>4+^XsNY-rV|8{Aj#U@ziYVA4_+76QAF^IvE|V(WE z?ZvljVdKLWQV1-fZzcjNRs9ui+$wx8dHnV6iND*Y*1|@oMr*2jn$-7w7{#|9p6@hC zgl@;V=pb_8x&A{sPJWFEaT!Y-`vvo@TT~82-hRG0g}3l-m|FX=6Cau0ZQQ;dW*7Tl z+!}FnWOjrMmTIcHm^?cq`Cv`qr6rVN!_-mO{b%KyLZh5pAD<0q4mKp{1B}- z4Vk_cg=RP^ zoU`xW_P9A`V1DHj@>k15%O6Q{kzeD*qZ3b7u1JV_Mc=NXh`Fjg6WZ$9XY3k{hOYnf zBxlb3?H{6hY008%g{aX$^SR;ooe#H2^^&$X zmX7qw^PiT{D938-Pn{Y%wC$2{t<#^;19@9i^ULx#b^PZaZu+)3*_x&Q=Ox}$-TrQ6 zE4huskm?B-BgoFDtz%``cOrD;=LY<^I3IN%i0dTsZ@FjR(4#T3*5=!+B{h!wl5 zbPOg(o_EOp=2OD0+6pBnD<6#OcLj=*GU2)4c?b?_LS9&n@30Q5XIpH z*7NXlC$!Xd?pq6Ay7D^Za$TrXM8)DY%Gz5g+p7FF$)mY`PuR!#uD`OyHXk!J(RAZX;ZuI>$;;2qHvG~QSYN}MO1$+-x^FUK>AjQ^IAs_n z{;YC^lQ||$$3HuFV65$~ul@1N%{9**F<(lD#~0sBG#s7$EeUTP7Jl?e*s5QbskFvS7*%Fi@AM2*w@=6kFxb%e0mn};YNAV>xOfW(_VL3 z>#=`RKT@i1c6`7uX8my58^2EG x4UZUOCI8lH9$2>WTa~nT$Wz7L@0{0XYc1=iSGC>imyY(&eYWc3rOS)+sQ2@j z_Sm{-7{3vnkKQ%Pwa(sG=E1(*->dq&-sASI_uaeWfJAMb&#-9gOFz&HQjKT->h~9y z7v}dDhgB~h=)Ez=?PwqzQeM4vd3R9t2w7O#4|S-X_`Wgk!_^p#nRm{9&vDqc_CRzW zMi9af>L{%^cF*2(q1d*b9kUkr+XzCb?P2I>9&L<`(w4T@iX&s5t&L<~#fHTfZjB=w zwjI5{I4Hj`{k%5F?PC#g9M-;bdH?d>ApFkY49R7zR!`RU+P3Yh@n_L)T|CY){Np{R z<*X|1UOAA+=lS&21EK7$1=iH6KD=5K7ESxl2cK#8#rZ4xoTa7HL-ki{d!Dwm49S;& z;4hwe*v==}=fP<(6pikYt;ynSbIg>C540y^==9HWJ0FkNUQw$;;#;j*St zw6}4_t+lM<8ojgiz=Oq=NWp`=Y?O^uf6mmRGeT&`6EZIzvD$0cymIg)zd6gu8vk-I z+v;O6UVDwmwtjeMEqi^&w=rx~*!zoPbd(g5@LkTnKg@+K)%BnbTEgJ3EK|_O$z(gsKM>aoy&*wH`NVYD8G5&dfkuE z*59I-HT4O(c)lLrk!WF&H8#JmOmFW^A8_%TcbuUQ*g4Dltnp6YF}bMf+;HA#h_&_6 z>%8tYMCqgRyryX=V zW`CB2SrL@QTCaCew(pj$aN0;-ChsxM!)c5>8NZx`AOyT;nX`LWJB`P=d2`3$*rKC0 zcXa-)58;_gIo3NU;|0sGk)4qBoac7b>BElFKI5XgVli8GobgEyuMLwQTpkX_w}wwL z+k3O+-9h(_17SU;5bVmQ+Fi@@E%t?HT)v*Ap%P*&bJUM5ucg}7r$}>L4|c8wv!>SU zTeOX4F)oI-w>Z6f7txmvE3~!jgP)!*qRn!mMv=xWK_dHM5tO^Sy zBW~ojYwM%I_VN6FGbKB#OJ{GlQ zQ#jXWe#om3YAh!bYk!p(=3K{o8QiF9H>-9_808W93mS_!|88r%R6cV?UURI6vtJur zKA0%}?DE|p{CM6O2``EAs*mt}<3Mn$EOC%EMJWcRu(t-^tIJoHe|h=4@!GxdS@Sh0 ztQNtptXiEE{&{f6?wFH1Y=maNs{+}dH64pZ*>5WxMb4tDSAF@LH_zVE!)y*weZ|+* zNQ)4x_Yi(*(5*6sE{%h;V|KhydU3XVJeYho{BuO;vhby;JNijC;eo4^VfnSlzjv_r z?&Znl*Oz~|{P)X$x%}ICb!X0SbariYLibeP;+NlzKfXf2IN4^*J+nF7I%@IRBSZXT ze0+44ZSdxYJb8UATOFm#j;*Kg)w`B!$8(Gb$K|VS&hv1d<2vKDLFUor*(m1Q$G);@ z-h1%}d?5=Fxu_Zd1GFj2s1Vc#V&PYpza4D<+vPtEzJGoBe0ZHN%3j$SgWyghmII6TN<~& zJ5J-)=9?4IPcL7NI(#tWs!jV=SpXc@7TZQ=Tt;ao@xg(wnc9crsXrZT|Lf&HU;fSI zucqDi4?jRROW00{`AIaWh1t^>7tPpKjIhGPh*G(I&jRf&j~%0@`mis5<~?WG!>eW7 z&aAcebtJTk{IJss++taf^VEHrm@YdSS+{6 zYpspp;(L?Z{_OIvFMogeiz92ke;mK|u;M)5)?J0jhQ<{x*q0T?yt}`OqQ>6lAFC0axoxLO&S_3o?%KXr-L)U@8z;;beIt#_r*Fevi!$CThnKRz9zTm` z`p|rLb6xM6&o?(yq1_*p@6TU;i~VU__N6SW!fO1@!mu)Wk46|bT7`37y0I7-XBp-? zyUHTvxqc$ldj@X8)^FQ(^hUY}?_TeBT^GLE zgOa#Xai|KaT5Vx5R=hPlR*%MM^NLjx<0vloc)c5EW6j#)CtPdu#5msX))->s@L+dV zu#JMq%#DBbBPgM6_?bU2vo>Rxldaaz9tFg081zjsI)oWA%_SabyT1LlCd-PZwpYffIp5s)x zDaPclI1&TXxbvLlmexZU#(wiu9PfD6?<4-@D{CvQQN_#EQ6qJxmW@Xrwba>X+soaq zPQW*5Yw{o7R}z0GzwEmA_#@&b; zVSW(HC;xioIVR<$wH$U~(YY*l#QE3$&g|HpDNamdp=~JwZedk+iv=STwMMRGN7sg9 zLaS$N<~h2P2jNRYV;ir>UF!)}db=W&y|Jy@z`VEB0am{}v;DJ|XB-VPcdhty? z(g~4agpK3G_+;6R(%&rU6@<>1WOwIue3t~IBweXc0gB8i}QePOG zu~6Su8(5z{!DeR}yHy<6yV|hhJI4>N6W_4ZqSnN~+6A$Fgs<}&>Ba!$^;PS|FsGoUYgxK%6qHvKQJtcs>zjBU>+>@OcyDGTpAE_>gSg2i z{pJs&^A361)d+WHZO#66}#ite&@#n?Ps0y zLf1%Rwqs!6IrX)#9`e9-KH0ZE)PgqHlaKOR`0IU9^>?|9zi%Gz`MVY%c4t=H?oUhn z<-Jiuu4A0<_|%#fzdH}}J5@zT#(-6{(5?2Vm6&LBP=b@!`KBsRZ17A+)ShGWRi4r= z4A#n8@gByVQ*?)RJfe4tZ*0?U7_n?|&B~r*eco8@)`xcWPK{_K|JbVC_-mwPxU7?- zs?$1iS(jZ|k~i$ZX0zzMKEJHuiK0jz^qM;NSTyDAW_Vg^9HF|`Pn$iuf=a<-^+v99 z^$<%T3eVo3ao#Ii8#&wK@QF3M!%CE2e{8;r)nQ*ff9p_k`SRW|L%cK3_vUf? z*zf9Q9EN51@^#3vDL${|tb#+^S;W^eoJSnC54w(BW&|qxt=KUU}_Z*Q|}eqsnPHV3hS!jAo-}+uN)E5D4EQJ`bGe#$m0% zvSY$rOAyW@Y%2ndp%~CgXLkLfdLrB$OC_srSCjIdDmR|T9M9|wQI$hzdmm5q*{h!8 zne1r|)^q@KuH0nPc4(aCf%enqwTvHVR=J`Fm|-soq(G z3*lgVYg1UlZ_$Xay;loVm4+%!Xb+t78w|C7`dAB%VA00kjyv(iE-aF(jB`g&L|z|j zl}hVAT`gOM%pSIA*TZ=t;@!dR8qQ}knWG{Y~AcJzL5!xyLi3$%ti@usD<_oA?Y!AEq$r>nyz303l zmR=d$T- >{>P){qEX5j8zc*7Cqkar&XgOt9RXP(JT{#yL(g5#cTcNS0joADKXru ztgtvO31jNO_uYSG#NizJ%cN|{i%?+mw(ory!wouq78Q)@dYQJ@7ucRc$DlHtv4?I* zhrJe9lP}m?&u~t8UDtpA=%)-7!p%=?f$OOg(AQ$CMp)_!f<2$Ai zg=Vel-}`!vv!40K2;jUu>BW|JCM(^Y2)sKO+G`Gz26tx#e9mi8P=-1b<%e>cGrfXx zqYi7?PMs&)8IwMt8xBSbgHVe*VYbJ;JndrbJ4a^Nl_}_kf_B)%-}u#g7B04q%Nu$z z3hx$Q#}%2*)>iGN>T#lTjHvgWpDng6`ytfs(D9ZMOUcW3TD_-M|eA05k9o@xYn zHBVLb)2;AW#%d9Qork}%i#_;JOI16o{*A6}vA`H>!`We76x+HPY0tCfbZeA>_FAKe z-R^ho+O+x>e>e8SvFjlrNtHuiFU`dr?HoPkBR#n5MgNV;Xjd`x8pp~e%Q*MpxHfR> zxR2r99ADh#Avmo)kQRxnPhu!*v$P1d4M+6sr>yN+J(`V0K`IrCPh9iN;#)LmFOH=U z_Qu@CP-TW;*xRwKuv!&zZy=-_`RYPyTn%T;Vho<}b!_Uf8B)$uS&I>U;HSs>I94^< zlr5~;_2!)U>E(-gd_EO~D;4&o$;)JV+H~tSn!MdF`t|MF`ZZ zc)Si@GflHLvnBVDV24qQr@WXRZJu2&7e}JA&kU#l@NGR!leNUAJHxE|$9AN!tBsf&!f8}v$= zCr`#wY<*+ewxVNxBs%)khPm!X^RS*{g<;tYy{d{uPODl^!KlfyAf&U_Io2o4?e0#C zc++S@s|fZCtN2sQvoK}rc+Wi`;}u)rVl7H;ZdGcTVl-aka*Q(H|KJCFA--(k1-2BK z*ZXNCj!pBm zt(LjY+A5FjUX>5SG>c^pXgik|a2USLIpQHDtzwX`)?<{j(skaA6`{}Wymx!*pHBzl zGJn|(KT`%ee0#=Wbs+e%rV@rbcqF^4eCj4}OarQ`j6GdgHnRb@#7=4un&PP12X;_OL%a&#a-tE2EAJUmJ;RqJv5GhGbjO%7 zIM*4g-df04MK=6t?t`h{uVysHfQNpuln%6xZl3FveXtjU;(rw)riQL<+F2zmf3(F+ z(M&u>L(iB`jlcy6Z=T2xVj2r$T-E9dsX$XJ}~$Po43j~EuMdgour zdgc#ErHN}P3#;dfB4dYFqskk_PabSkJpaK|508ge?yA5{40Kmp>*jEV^m3CO-ocku zdesY$;&j_EM@x>2M{mt*kwA;?&Z|~C(z<0aU0|t^``bw2s2^UT{^o*f8PxQhPs5o{ zoawAo#F%2DE&S~#-u4Ol(5+rGhI|8CJ&RjarZKlSU20@JC}V|$evJvfdh`3q)bEex ze62uNH2_5!sXS*JF3{ygI-43X%R3jE9R-Ej!g(C>&h@1uN=oK z9z`$as5yMj$$Fg}XLNE*-p1S%0Ls17K4142MvXXy;>Yd5i0s!QoHwRLj^ z4|+@G@w1u`R>q@RawRdG8dp&y-i$O~r$2D7=S6qp%2rp0o{s*?W6jx8E4>)0>z!#U zRvLMatzNPl;v&Nx5?I3G@PKiCwOaXPdb&D}2)E+AoX=z4J6eRn%d42oCgWXQ(ys^$ z=lYMsdUs8`aTxJp&okKKC*6lIR8Mw#Pa%!}x_X^!Hb%zhxZC{C$n>%ik~Y{1Mf&Tm z!JV`1cpy+dFs@LSyRe1@&Is>~NIbzZ9Tt zjc6;x>?!*+m)91R#|O50_Rg=CuthfT)9P`vFFtH;lgdJS`MrLCI^3MEEr|5KIBKNv zco~l=w~mNqxAhn2#!q%FV{8k_^g-+9aOnk3z^)_W6u)4fF{obH>5O}`)=@uHuV|E! zvj%sIQFgLO&my3ah!Cx%JIiHr@9ucvZ#AIxR$J9T>~ej{2>9M#KicmOVA^1H`CL(^ zPol;V7-)2&5wCd-Hrg?+ViUUAaZ%# z^J#&P0w4;OE{Il@Dka&Uvt>7>%nCh^<<5WOJ<8-5K=c!SwTRGTf8F zR~1U*aD+wKiBHNRd-Mi%uk8}(s;R{z)VpfDK z2E(V-rBokUlz=@LY7C*Lf3J!gW7NO1H!2gS{rP(Zo z#oaGQd$ncX;=3r|WGbM4J;2k5Vj_=IV7C`MS!XMDpa zRJ3=p5#`7RBgHK_?&ISq-_jAjXY3n~zMZ8f@0&BGX&(D$McX!%TDPm zO{ik$!Rn%7rhZa0ZDsBH5N6r?(X`xsvVC_;`AydDt}ncXKb1CzioYTYnvi9ip4WTE z&H}&o=($MbC0Y;35Ik#$)iKPYyw~;Z-f+t(jpO5axQbJZvJ1l@p3dekxx{$% zTNARi5!hQ5NF5#@D*W*=VoY3RV4ab&mEOcBIO7gZmPw2{u4HlkH{*s~tEsANw$MBl zExtG$#`w!mJSbX>LL_Mof3^=JbcF3}&&ureTnv>PigAA7gRO5ci=T`RiYlAE16aH9 zFjdxvWA!R~vbjFQMtj<#3esZNrmY@BsBf^zi)>4yV3~a|jZ5Y9uy$ng0t!RxIu9ya z%jn50-|8nt@J%`H2(Y!8Kd-wpoJQOS@1VJLihlW5dq#yBIK=*PPF1{7sCmtyXbx|( z7n^z8$mmKDR-V8aDAE&(0yWr|HS_>Ce)6}<0WTLH+d9gY_IvIw_i9kFq~!-kZi{PF zv+PD4aMo&;Y~CnSyw&^^m%go6iy9UeH#EW>-tM-1^aH*yeK<(-3M{VXoh!Ky4t({_ zk5y;TF1Nvl2H<1SqE*(%P0!kEG%T}M)!p?6NcnXZOz_`3BXy3J#Yq0s1KhOVrw90I za|~}6#!uvZH0Na0#J%^NvL^nkTf)PmY6CcLnC5*iMx;$B0Zl@lof- zBg$w6jZ%I%c0rbXu_qRJ?YGEHz0{u+9JbU^zaibTx#1^+CY*c3VVRmPr_7F(VXGft z8?x(Fam;V!B)-&UmdI_a&%!jRRe^jURv;b9T2URu>=XbyaIJG)NlSm6BQ88+C;hT! z;EHb8`RzpW^A7v z`k+rXik6t18fbhvpPRM^wXQd(JVV`KV}t~`vAHRarhq)FcdD2MhBSn4O`8voaj->?5TyjXWh^`@em)&+ zd;f5@xN>Wp59cqnpb*t({924w-Nq%>!lCC6=iD#mOnC^ZJW2m?3|sU}+ilw#hA+!H z=_Ur~$D@iN#@NQkkc)qDz$&J!9IonIe0GewQ@_o$WALu`#x~>Qk^CpKRoA6R)+$1~ zimdFI%DD>AHSS_kH6S*r#mBP;j$*?Yo=sG@-pb?dPWt>{a+!7UO%0nrU>g>vym8Jp zG5d7RrwP?4#SYu$B7KV)xq!EurQ?n|b?cGPrV;sYSCZjdUs|H4shl|IE{57KLsJav z7kI25V)JJ+wkLb+VkagP?XpcuW0sAV_NBHl4)@A2@rU(%fdlq+ z4xNUv6$XsLD~yW0`cAvlm5@^tixKFi#eKV|*Km}>V9mM|BE&^?+~#qg$!xwxr}SDS zY7G2}%eJ?U4OPD)vB(kk`7|}4x)8O(5tEJ!BL0+5FcEjI=67+v zKT1IL#WYp;)xl)jC>M_BdjxJ?A9vGRJwvz(jru_7!4VVT33t50%qrn3u#RmD3ms8b zr8^#S85=2I8QiJ>y`T*ESayc0v+DsL-5bbT>@2^j8+^}-Y@?S4^9tAG0VDBjoksh( z>b|+IE%I!yy<#gq!Js)2|1@s-hqrl;Z|@JDvhLGC}MSeKaWv|4Au@xg2og!ap>)rgXXhC8)Unu^Xl0gE7uv5ADP8#2&%>Dy@+R8;A1%<;yh z9>QOv_i9I%|5?%uxs_h}&{~cW&|ERK>gXJrX2yCoW7h*s;ze;`3$1uEX z>igw9zM6MlQ|PK4`0`hCE{YX*x9%<8^;I5aU02v;yzQ0!trTP}UpJE0nrhwH)pztz ztl}_h%jfv-n_e-{Y=Vb-@GD;#*}cOimO(OIcD%hRQX?wQmPw1p?$8cVoYiABp{jy5 z>7$&6RqsuEBCkr*UCZ!%df;q)X)F8H3-n2zdv^JDzRCK_gT+QcpZ#D8P3Ir4V;*0M zm8)YrPvTeeRY%}(bq4>|JOAo^S?-u!8O94duG%e!m*H$tCwx33GKb;6a=852tHvmP zM4lXiNBnAJGUx5XMvBq3z4AfqZ9YL8x(^A9Q;0^>EWdRpNaF$jYFSU^EA>~br`hZtjXO)pqIax|3@4DUEyy`(uM5}yXrgdjd>L7B< zJgEq59!-C;diAf*8p$`^jSF?!s7eygB7hdszpc>nXHm=vH$UKm+C&7J>^?<+h+&D z0Ct53S6Ra{5#qsrG4<##P+qLu-|N()O#VEc~QJ^^g+a2_8Xs);4_nORYkZ%OBS-9m7+-7i|y)#5y;izP_U-~SmL}n|E6CO3d?^!}1yCik;+T~}(z+){Z$A57eTccDh9dGdXAxpvypd83 zVN8@kE}=azuqG#iQ32L}H0_CfEd6?(Kc8n>OKE9`F*QqW9%uirjD04yr>Au`QY zoC!JS!YXx#@79|}(CpKe@=GgpP?f>)to0xID~F4bRsv)*l|$S;|7TtdmgUL=w1KC@ z12szTJ{xqySiG>>To2M;&vt7`zK57LY;pTh1wZXrC44 z&!-1b`m5n753`zXG*=VB&~_YO_-oC_PdTlu!Y10O?Xo`>X^T%~EU{w@4`vi1M;(YY z`sPW#?RzT3f?6LlPdu1;bkc=W8_2)`lH8^(R7wcHdYt-oZ z^d}$kS#>f6R~4y6e1ApXS4VqU-se^!EQ(zr=T&EGoj3jU`|v;(Lu45F2D)WiD#>PC ztUimueVUNwVy;iP$f+U<#(rf~xflj<3v0vHv*`HM^odK*lWV>>@N713EN14L{p1DP z%5N0N$Z;@5s7B$z>R#{p3_rE;>_D&eZJPV+n0J3RxIUk;$hAD+{FEIRU59^bEV(;> z;TpEkmCtFh?|g(Y#c-!x)dxSrmOAmb*VTae*4}1C`9!v&tiG>kzvnciSNU3fkp29c z^ZESN-b<1i;f#ze_Ay32e>CWRGq26u?eiQTp`!A41MOC`4IrJq)YDKovaB220MV6I%xZ+l&&`n8oQ)hmy+TCZQK>m0tbieW!gi<+;F zeXTUY#C-hW!CyK{2U7&r`yUikp)8L}-PIu%id=cUI|aO^F4X9Y=G8H57mEx{m8w0H69V_|ijJ~KZ|G5iFWTt{@e+ukB zq`feI)uiqTH8Or|eUrj8=M%>irs|YxX_w#j`mI=^UVhu2CLNr`22Lxdp`ZJ8jDjzuTu!4`u6h2qnY0w{KYZjzdOga zPA#)Q(Ksn4tIL&E9LspM>kRXlR^`lVo==sJVQF`o*{XUgy)5fH9HH!6cBw7<#JU(T z=2%cxtLCkS$B?SjqQ&=VS=&&ZVG}Ol96$ed>=QRKT6d)4v+ODRS-D#VTOH62grN{_ zG8rCGR55EEUHkR+Y{rVi@W(macXhB8_HT|k^7jY6%_8jERUP#&E{O~GA+g>A#w=|9 z%?_OXdLF##XmLb=9SvdH>)|Sx{MHp2_{uh~4!XXz_V%=>lB6~;qBwF{=Zhq0QUmOC zACYf5P@&=2vq842w_5P4nrfE%&Gb!?`P90H8qHh{wv>V*ZN&`%jKWXR3Cqt9Ezm19 zXhvf-#~eb>%_DgRCs^BfelvQ_H-2!}9_+cAcWld>_(LhGJHit)MGG6Cin;CQ(KNo* zUvZ%Zpbu50&D%sQMeMt&tZg~#>tVk6r4-OyE9Mp$x+1=<$5-_Q3$Je?rSN}RRLS? zFuOFnf-2s!QM`+SZ|8h^h+p{nc;0_Azf}!%*<4D#5i8W0U(|3<<`}s9p#m_Xn6Vsd zT{GOfTb~_j{pFl#zgcN&Ylf27XtJv$&!-KmE!4=!%nDq+v3^AZx6)@9tNYG^=fmEA znEyHXH`CfDbG&sJIVqN_Gkn){|Cvg~;s3!~(|s^j|K;V+r{~)f7kr105Tm750BEK$ zxOU-x3SqF%vx|%J0pw+KY7a+jqc=DuB3Vn#zdLZHI^PbLznwkR5wu^N@a6OQ6~i99 zu=)TE9#efZABqF6Tl&TvOvhLpPBC1Srg%p5#XOf))YM|7ssg&s?UOjI4dN{3TIp5i zt64vpvH$Jme_j6f;ESm*U;bzwKfnC!c>MH-zdxTXyUnXVn%d*lXD4tt)Dg{J` zoOt`){I^UvLc#S5J$hITqBedu@?l56nkT|r=2#!{3Exydh={VORjWMaFGP8(`ay>4 zO1Dh(?%>haJ#6^9%m29i&w2LkyTAB7vOm3egtO-`4tqZM<+Q0&fgzLQ*C%)8ZDsx)~Ef54N=`Jo`RL_)O36Z$uJWWRozxS;i-@ z)(qqxzvg7J>$}6TR<_O0`p;8V4@Kyojz0Xmd4BUi=;uEm8^Vk8@^=x3aNp%>6+^9I z=0Jt~SG5;LSA1q)CY13W4U&#pd}Z9lR|V0^Ixc!_d=}to#q9s!z4D!D)LNsL}Bc&2hTs5XZcJW_Up+R|NinX4zJ)^c~U*qYAJm0 z&BJ(_Z?*nb)r-rYPAgV|T2b@9Y{o+=1U`2ytj~CKZBpii--gOSB@^aT1)hD!=zp8xGbaSz;FSb_Yj&lD?CUxjParnR0SA+YD z!^A&??ket&@m>7Oe4(G}nk)4!5O)S)SC3`b?%>bOjvEWt}0K3!x^idsb zUHj`{>(}#|K72cUpS6`+GSSiK8h^WkP~GMWn48j5Q_yeYG_;_F$pCSULa zCGKi&+hEUE&8w)I%xvwj>uqKewlv@H-)E_V$1B6}J9E^Du5q2{En64m{;nTjzDNA@ z&}08;!OYpUN%L*Fv^kR)?H-cur{MYhzbzC|4KG?*N`2v}>a-@PZu@qy{q0dR{CbeB z%Ak(TCb~jMM_U<>znG(D*z3kPPKjlNs);{olrx~{OPX}TxA*_Fyt?pKvHL-Wd2dDXr(a~k&jSngqt++8QCQkeO5b-n8@YL@U# zcdrIZyu?ybVMc+=P%Go%D%}wolmXt|M+jY97n2^8MmB@5T=(Iit7>pvw|QK5e=NRc zb^fR8YQrDG_hjhxS0}3HEBjRyvK>^POb+@Fm%kd@tL~{5eBC=zMrt*=dO`hAbx%QA ziD{576VVGux5A?ZJQTb1)aO0A640tHOYoLAt+en$H7&$;?Ln@@Ro<-sl%Tl;T=}TF z*IJHfw_1??x?c&t*elDqZsXClo6U3TvNG3C4tT?BS-bDfzl*XhUjKN{&!#nfs3~3= zH2?PUAE%1?Zfu}__(2uLoLnKhr<$?}w#qhb5xeFSIE$~cmlaXh!YGHiUaK$aRQF(6 z@1*y#m>-$G>zJ+a=ut&d59Zb)fEV3C!i$ub*Pv>4G?yYt(suQpO+p7@%rygkg&j(j)4z8M-XM8q!=`ZG2&H87fq1H^*WbsVJ zu5y5_2MwlsR!*t0btLmSSq#6;lhqX|HBR?yeNnB#a+%&wcg#?Z@O3q_yP$lZVfVhP z2l=CQtD=TJU?>%%In_j%3uBe0vCCWZmLjyaO$FaR?1rsJYc}4&cYppVuJ-(7cmKd! zdVA`xbKq;+3rCNOu>XGZ*@2LCAN7EB@9I)GV^DKjyrqA#%3ckj%P_@IXuAqVMdPeE zFZbh7InncJgaidUDO-6+m#D*i(Z@c&}OQlF4;I}#mwCfU3XJ$ zTA#G$=o5o?j_ek?i}6;l5bEd0`2HT&-@jPqZnis*58Vpg%>YSwL*Pw z9`fw2TsCWlqMEq1B6vCqin66ENn*m)2P=Wl6rr2Zy5c44xdVdw%4o~q#g~$vKPP7A zwte-7@J$=y@6V=vtLfp}Dm_n|t+P|K!W-vW*%>wX?LOV}g?8gc;jp)j$`2B?7}s<^$vW&Oa<=X}JF_Tzf~r)B2$)*q}nSpQ2Ms(!mx zX?u5l&T}SxGJYJ+bVwKi<`?5A{TZ31bbg!Fh8#K`Wk5P+vN3#rLo1D{K z9qL$*swF&b{sh%#uGLLt93B$&&`g2N0o{Er$E>1ubE zTMcOijb4`{Vy=~5>rwn_MW_3mG1za~$2#iUy*sI}yCAC1svw~DlVfa)bE>gOpIgJ% zIxww)G7l}nDii**l0+$PACYH0uj`#E{;i9Aw|4V3l_x$f!^}#d-*ZY$S<=ch0+zhu z%r9oW=eLvnpy=nk15viZ+4!gy>j6bA$h?rhI{MRZb70zFe$p((-@Xm1)ov@k6rxX> zK)Jg|TYG@)KB&aWU}HO3x|sg>@8auTc&is>$+(+7ARcC^?$J#K57U| zRxMfYEwAHGHd~9svDj)>qTZq!c-vfnzR;HMrpm@(p7UeP%WMmFyrL)Gx|&wZGt|P} zae%8lS>-L?VQkmU@zxp5kgegUA-Z#>+81+u64uu4pj?H30VeMpqk1-UA?OjV$AFI~ z@7rVb7elui;Ui3ry|qmvUKveb9~JICKlPfcn%2-&q8J$qn@dC8JPhC17RFSfJ8k$w zCDwHXb1&_i;qn?k`N3&fQq7RYz_&Gz`~^qz2epGajehjUw^mjAlrQw-Fg@#zM*7>e z;Qm_Q!D?4<&a1-EZ8aFid-WnjPi&XD$Drrw$M~k?F?gT53d(cP#b0s8^WDE<<{DOb zO%dQ?C8gX4Q5xxena~P`_aO$6<^*PPaD|X75#rt~+z(Ect@J`|-Hiott$JRy;msH- zmdw&{7pmR)(W=9)@pLzbt6|-5=9M){b%iakEW?%Kc0CQkXEhKSP$+kMWZ`b_Uz3DaP;zRCeMFxjd!m6b=D0~F7xL|I9;N^ezE>IrKX%?~Js8O-Mg zzO*Fu#!C7C-?E+vurJ`GQuSQg`2vnE(W znvIy|lepEZ(4x4wXm!$2#eT8g=QrbNvj?qGpcC(yO~>I1cag&H))w56E0=Zc)w-|x ztd+^~S?T~?>kl;kgWt0^T(?FG7kK>g(1@-CRSkqDY|r;;EUwZPzVci|RP({t^%0+@ zfvPH|)ezU-T-)5bta)*f8UiV1xWPd6VAckKofSh#1>%#&%@}BLE0r*ezq?AqH*j=( zK7mGaa`mv5c|kU$3#l&!vnB~?xKmzph@BgEUsU()^vRO9Ct6j&KSp}{{V#j#b2coz>B!)6|vvuN|aZgw4e;n>(4E>KfGo9``6Z0aP zvcdy%z@nS9Aq>a`b=(IHo`fB~m3`Bj_RcCq5{G+SS&klUu-63yX%`betYW=J{ z30LYvJ33ONq`P=vMr`JR71r)WUisM!&KypLW4#(5x~^8lt{CUF+AJMyKCmmpsfK5$ zUVoRqR(Dj5K(kMEXiux*YZVQmRb{R4sEFhbtdz558u^MI_rPAYRZ5)JI;J?M4DG8{ z>sqDj`)0q;w|4BO@9$AP$6`JB&1W>8_EK0q*-C+1)2w<>M?iJ&*~MNneU+F;_eD`) z*ir}ho-rMVkK+ty~mr-tg7aXJiI=pHRV$b2xlWb z`O%#P=AmK|zO7?nF_j2oD0{@St<{#HXFVL!i*frG-CF2VU2xXA+7H5>`Lxfq7)zh} zI;%;1sv?ChJXBJU3d^h64@34sTiuVn zLp0Tiu{;%~^|M)3<4USjkwvK6?%#rS4z)SvtPF0-0 zw6jW}`SE@(N4tCj-w=+`&dj4R+Hq-;mb#bU{rlRHo0}Wc3pGSI#-{8&KN|oANUbu! zPt-5kq4eXK2n_Atzwq_oG1&SoUN%~aA+L`_qs})`Woxg7Ojbk^&NzpGt#A9TkjLGvad|xdW)(F zdY-SwDzCdz)+eTxQ6imMID<~Ww~8&K)8Uj=TeYkg`N|Jn(I$`3roBp4-0%=3$U_vX z6$qZMc7Sg8Du-?A>mE9q2TAtAL2U+K`6g7-&z_f+s~OAe{nTt~5UPtcJ-~1H*27jP z>5?lK<`$w$%`UpSL!s({-OV@IgI#GJochWivzM<@jyl;Q)vwe_&0F9uE_L+M$*I10>q<3C!^>ar=c%qqs0Q{s68H;OwG(rx0@bZS zYm4n&tJ^9e#x8d|hSySf&zsSxl2wP)p?Rj!r?8gUx*9 zc$SoLSX2h;(@w6yuou!e3VUa$JDQ28nW;*CtNw*#HG#^vmdlDfi_;Wcg{U`uLKm-D zV9rSyR1s-|yQlm12D(?AE^>05^%hr*FfFyfS$LPD@1uH$wH&q@nb#vOT2AA_%e+Ww`Vk{4* ztT3#0ZkyitmR@*`rEPH}ej81n;px-9l=#$H7;FS%bc(r^+QxVa5ZfV2P2n2*iv(Qe zleT)^*hme08h1azNOyO%#vPKeu1rF0;k?lfLtEh6-3C>0;mj*?kqmbFCM{`JU}oT| zrK=d}L+$q|1Q=_(-b8^{d92E@Y5`kSWb|k~jM2@B@h6pFF}{|~s?s2hzi9=u;xhEl zoE1xbYZsjk+xxyK9GS{J)7ZJ@udsJxRH9d zidluUc6rBI@#r{zoykXhQ@$(z#rW{nDs&*nZ&iG>*pDq(kE6B8FV3OuR`2ZNL)+_H z@33Q=c|BE#vAD*1ILBRg%TNi}qz|De`WGYn_DV-8T)kU0;mVTM*{H8R6$eqq>;OqIjEs%7{1=ub|;MyMsmo3_g#ja7%g%FOXRYDMj6pUT5mEm|G96hHD;an}{$i+G3pcn8>St$m+ zO(}ezfT}fBO{4g^?=KKXJF+r8wi-FUsj99HEK<=bU^r<_CUhj6@TSO~HYkKiQgo446Y8+ycG z_@=_ur=1hun<2omnqlYEd{?Cm@%_KN`EYd}-;4;p;stY?sc%e{ugsQs$Xz^Xs=VCX z2z%1)5T*(-G<4%#`iY6EhU%;Mx9qjH*(cl52X~(MPA1-VU;@xl!RUk7reN0$znIH85X|>-Y;{GdiD$O_ReHb7`>i!rIXg_L%|-1x3d? ze~-*>Z52tB!H8OOXuXMIV;XdeTi1V#zR2I}0-};7EEcg8;?!q)?z)2dRRz!;I5Jpk zmE|<(x$^Fc8U|PY+6Qs#$sMf^BgJU8r9MUgdHB|UE0YlJS`ZxwFHsv~;T8fI3mNZV zL?>2BoCi55!8f#RfomF)Z#G-{n;y`jq6pq$TPF03xz+EfEtOpEQi}am!Sps>WtbCRcEpvXFZ3kw)>PbTrp!K9TUZ$ z2t2FfGMBk83(^uTIM=?N$%%U?S+Sv@T|2S`*69JYkiB5pr&?X}^n=a#%p2x)9Z9Ds z1-7a`dd1_7l}A|y0ad$igOL5;C*nE^m%O3|SXGSjMyiWnVM1dTL+a}Rr9Ky9HL^$Z zH=mK~{s-Kp%V~&r&U2QWw{s4oYNgV1TDMAvLvWGlpv-3VMEr#aw!#SB@e@y~+iYpu z?dj3CbL}hzdf}@j^?)`p7}i*)kTlb z(^lE9=2<&cu=D`B_^c9hS5)5z)7>YOpzq*_zwV=;7G~7i7XzX}PyO0bWEpW+Fky%% zc+66W;bgJuy;l%nI}BC5sc1EZHTE!f%RErP zLNT^XhO$wr-?qYqY`IVr>{fLVmhl55yxOc!BjE{Qs6e&5r`!YVu797IFf*nL?lE)c zQ}{xXLTFEA)^}5j8vRr+=uPyj`a_j{u&wfhk>6MbXH3I2n4}ge2#gEw6xES&TxHuD za)`!kXQV0qhF^6xg!HMG9yXeyfShLyq8kaFZ)GrRhvl#U^ zOqaXR*w_AgI0nLtZdmfdWcF(w*Zt${?gn%}V4op`araF1%66Z!^(pzU4t%j(b=Z|ld{rOn zha%)zf77W(xGHAM)p8V~nknREnzG+!wor@TAql&b0=9b`Y^w?=Kp5g>Iuw3+I<|`t zd&Ae6&cbYCsFttFWyi!zkQaMSEf9RSyxpBn^j5V%3$27wy{ZV@`Leu9XAppb+m z3&@s05`qE&1jKKvD6%Awghf`{g(c8vD`-D`{l0IUb7tm$m^pLnhpJQeRMk1RZr!@e z=RdFh^BX`P6^sl9XlMWc8b2D~KhFRM^Z^e54>U9m1O77%I0^u0YWz~Kdk>h_#Gqu!pl2&)F8E-vOYy$FoC&c~Z$kZ4>OK=^dXND%Uz!0^*GaH#P1 zV}%t33O4IG!71t6dWM#Sr$^1ekj(rNU3y57b;T%Jf6<Fb>k_RY<>P(*_fT2TmNUo9%FyIJx2c1gOj+m>?LfLh*V5r~!791xhIh)75gx zMjiF9N>4mkSOJ9MB-(`smryON%c$QT3-3mknVqk9x zZd3G;`oU#1nH^xxj!$dK!WK+j3o<@-yhmFP`%BE#d z+t${N)z!~y9nX9|9l~fg8L)PH@mI2P{(b2F-KsY~^GZUds{-_=+eH50iH4N;qahcj z8_OH)aSQ20g&R@hLMIWv46U6Q_$cK;z)E{4Ss+qkv*=I!UJza$7Jdet}WS%pQgrItP19?Mdy z=FKdpXNER9^ck}zKS2vcr-2fVxz0S+kRJAGak25@B($k;ek{)#oeAS+;jKx3{_A|% z=gdpFkKP1dj(}C!`?VzM6jp37SfC;Vl25gPhM%y&acpf9YTOK%>20+TPL{oYNMmuM zn}&mu)>2Ee*lwWfSrv};ruO!k1?yW@5$&}`fi(epZAu4NqYR=g7L}IUBy8bo0f64T zaX-FxR+`M4ny(F{!isFPjbSa7kK_9vkWyVnSq0*loxaF=WFaChuw3vSM5*+vsEo)* zX)xLdYb%!!J>Xtjf(^)q3k(5>$i@*i4S>UeEF0#2WLw->-mc+(@rx)L?+6_|Tm5<5 zGfv`IVi2;oV*cQ`b#Y~ZxxfI54_g|eN}&t(afY}jB?i~+E%^L48L(^1Bb{haXf(_! zx69uUU?MI#c}#*cPQx~;yp~(@C|yQ!3I`{ucrQXKS#D=wQ`~?MGvEWVF5Rj)vldj; zV(PjP^ssPIApIF*pl9bF$Ff;)@%3W4cBjhi;1Od-ErL_dp1)znhg@7J8irL^Enq8b zol2S*AYqHP0iaV478-yosGwKHT9xWa=IilpK;!0u>xC7t8?|3f*lY?vs;WKi!qPeR zSGMYduorZA{~VlkHCm3XC!q5eJ%n|?qpke-(IVVU54;EJ9E826t=dKZ z%`1lAK?__ZY)`8@7KahFEC7F4NLxW=)dqT?P3D$VxN!#jTK{&_%Huor8TZmTMzc&F zLL?^7=DyUX_8&&tysE0eRfx&xI~AIpC^85c(SRu+Oc$7=>2-!+)@oROXLJdcgB)vw z;Et^~ms%V^ZEio4z4*{bcy4fuI^!ljR>~H*YC9IU>IsG+`_n)d`&*q#8I)jV+_5{n zAl*VErlE)iz6sRRMJn^B^n}XpqL&%0T|?H>%@w!@foXt5WZ_9bELkY3$*l?j`jfnf z{@Ey{QfL(9;iM<@TU7>Bq@ysFA^H)88kT_kGL5lBm;DqQYWQ$oh|J{4I_$Sz&58o9 zj#QYqZx6O&3St};Y35D&kgyn1nw?nM{y81OdPW!UN^XP`R!Q1>>+k5`t`mT+jeTy* z(P3&788&COkl$+;ZsIQ@q7HQ zSdlA~L58&8WdKbIg(d298v{Sx3xwUXQqWBT2FsSl%!kl3I07U{Ka8*40u2?Fs0z88wU)U+Czzj6INT}D6t4O5UhK~YI?)5^fhwa z-heuT5|o12G%ke*uhzt0*(LN(!UxCbxj_pOgQO5zG_KXv4D;~%Ufe!RSb>c(P#OHM z_(G|APa^n1k1-k0&{BKs7PaJo^YrjUV-=x^*LTtnR|v_xp6>BFHo|M1EnucwxCWL; zMI%?FOSCn|Qqw{e-y2XU&er}?vt#i*E zr4p%JsD51!|M%H_M`VQ?B97W2IlT`L{}fS&r9BxLbY=$L7o9_ z+=yejC6%BpJe)(drd|aI4YYO_L+@N&+YY7AX5mk8GP?#jkCv*eE>2CaGW3~Ev26*k zSB2GUz7`KZCG9fSViDawV;7VO4Hn?P0XJHy!SvCp01E2?S+4E@VRLImFQ zdDF-41U6n@VyUNt2LfHF*2ZmlKi$dGAOQ_tbzOj`8O;dBdl;x%&^ym)g>(l49-@bF z*-d8%_JJ&vDDY_e)FyQL@?nFdO_X7S5DO|zH-@K=vc*lrjY5%)kjpvl4@Y00NPJiPA$WmIYG0XAI9*iNTUv$ZJ z>}V!s$Di+!RzsbRC)(oV;BU7Co2*jPrqtBprcF1bQex}HZDCMVH_xUIuD;Jq#W=8A zS=37+=T_H-2f$kd);QnS;((7k%iskg8>Mgv#{~4b>2RCU3oB3KovcOrxwph1<{peu zb#;&@d=0qL%X*(Sy|!y?z)^L_z`MlcSEcE0^Y0}gI|)V1gvQuFL}rJyN9K&1$P6PL z6A42}EOn9#rc;S^?~H9(vlu-)>YG+7ry_2NWLthdvy}|0R1J!X0j@@OuBE&0HUi zZmk{3emP{d0uOn9n(9O_D8)$sHQ>4?6Xve4bZq%qR`vn32tHmYr{}73F+tnX& zhf@P9nCQ43oqUMt%B7ovB4WEb)e-deH1l+bR+Bm(T#l$*i#{3`C2{J%NsnKv`@$wI zB`qT~B5vz0RO2HXDynR;7rXE(k)j5UBh2jW6)cn=zjQ>8@jLpgSL3U5U*MOOpG&Jy z`Ol4zXajH~(dIS=hpv9JfZOh`sM)6uy*LS@f2OX51zESnSy+XWL{{^z_sjAECC6!m zBAJwz;3pg&NFm!b8++MM=OTlzHWwr!`LlF>m8HGFdODbk_5`dVBzdil)?rNdAzMhM z+7N1oStzQr!4;{p*DO%T`MQ6uUm=Hqre`+ZfwfHDka7CE))IUPPSo;2{miBjXhnn= zNgQ04+Zayko?R0UOUd4OL_+}$d)8ezaElwL9#Unj^{n7g1*`ewa&opq0OP+69f&9WT>tl9<8`~$C1-^ zOt#$PjtNS28zECvVY@tsD9P+)qv^TgoG8XX*k(z*&_1|OjWVe!>+>(kYN{R^$}*y% zP+U1j9O6$kL{4m0I+DOar20C#>oX6XH59wo#+VR90F7no_t5fcM-fZJRhS@!nEKS4 zYlTPs_$91a#DIqp=kFLsCGEQRVTorWBXZljS@_FY2Uqn|Uha41x6B+Sx@{XP@(gc5 z10Jb|UBrbSrgVu`M10+JM3>NCEG)SA`y0|-(+?KFifvuO9%okcSg8@29xL_ma2Ax}yLMEB?t5@7-% z;!oE1oB}UnQsyhx)b?OeKer9shj(fU?SBFX&n_q!r99(1v|ctJn+UMKJR>n? z5kYL3=gi1^n2&aXIqfH(`g#OYVSUzHaBf2wJ{vid_Jtc) zz^zB+u5~05;XOWc``4EE3!(+SgI&j;`iZ5YNjsWTxy_bX-T&u3He+)>@I`{!zN z+$uAC&(`^R0`E}R5jzFdRc2h=^X;g`iGG=0D7_$Qdn15i1Q#Xr3UM;x0faCT86iI~ zs`)zYvq^5^S+`O7uAmq=wAVXbtKf%1Kc`dPW+F`7mNydr;g#oMpXfn6)YMs8Lxwj| zRw5MO)F>MjUz|Nd0eq( z3FUoNtk%)pk{k_kojPjd$7>q~3_86xI&zW1tPsk5_{t~b^B8X$V49kXIe{Ggy{mMp zbkS=tT-#EVy#vAJMK^sA=w`}IMM<0sYXPyKbcZZAv|3aSJvSMw&;ic~x+XDEJ7)w7 zMKf;Y#>y}(Et)W1E0ByPINTtW7_yfpoYeJ41lezt1j<2IU{y2;a~P7J^4bT-<;Id`btTr|Ib+q5W(p;tOhbGuxuKd4WWTl=Y}J)^hMgx-t5E ziT^{1b7DJ1&_R^>ItiLU7Ri0VKYxs}VFdN`GHh$WVU#yII59CR__EmU^a%t}@FM$d zMiMVsf7|%#iq)nkIT>5^!}9vxzh`^acwh|LE;C&N-FLORVT~c%@9j_tYqG}#6PHMj zvehF8%dI?I8r6}3T4q6~MU}`P^de1A*$phla(V<03KV9`_dl&53VmHMPVhH9!pVmpZ~?jI5iV- zsb|(bs_TOt@pp;|7jarH|QRk|94QC_Pk;A!RFF%xuSHMTI(b z`j5(#0C9K@fBkO2+R%waeUZpT^zGTq!-yS=X#}crZsrz(H+qe9zE+b>%4Xx4J`}AOd59wCVNxneWGAP2&4yD#ZmN!R$HP$mnfod*hOP5H2~EdaN}l z$rn(5+;zyI58__^w%6sE>5$Qaf8DVvWb|yrUFcIOo;jDwjEY{LNP%32V`Bdr-JVW- zpoc&v?GAauyBe)ih{n=ih0hb*+VJk7wz)&PTS;UII;H=!awK84R6DO^9{P!2*&SZ= zvjj|7gPjP6E1$F;A|p=t9?xlHDw0V-bVIXt!BV8WUU9Ja7}3Qn6x$A`2tF8347Mlr zDlZvPJMc}<(ShpRE(~=m8%1L@F3Tf(Q;}l!K99`cM6a7>@+!BAU8IVd_GywJh00PX zBxvqqes%FsH95Juui|mqS9gg&F-|I~+*nT+zGpN2$^43yG89kNWC^mR{ARuRRjD*V zGuS^4&=@lG?1j+}**n?WDaZ-CCj!NXk<-n$86{POO}`Qp(TMiV=LU&RCsH zzi%&vAGLMh3j_vJ5W%`r^uyB`z^te-4ufdalzQKPI%aKRXDF7;qcqLqudGk9d)aMI zKiYM~D2Z_tp)g)d74}>SFFJ}?aXwS^#j(E2i;r*={4x2&_gaq}I%zGX@qBxQFM7<( zR3QuegUyIzJv?~bmLuMF2Aea-r`8`eZL-aX8k@_cyAlcUcj~kfl5Qf-dxgdsHc9>I zuEQTG)j9kZi5@*R9lQR=q9$40>t`>6CC#oA3KAlmbk4pUTK3%U!!3P9bvn5lJ|S)C zq~1?@m>iYxD@S?Rb7j?RH9Nv|mySliprKRUbc&u*DsuweJyeEyo)WwAN3W`D%##u1 zsXt0y*3RT6v5c#CnVtDJJ-1oU>DgVTUXO|4%Qkcq&zLh!;dL|z2tvP`SW{qkfT zVO9+ZYFx&0u@-??C-5|KLWlLC_eg=%6D!JWJHwc5_DYEZ?Q871HMp z7554bWQK#woe1g%xaf9AdhWBMid$!{e*33!i>x{P&VkukP7;MCztgy__aZ)0*|=U# zRQ7$|KUkH*Wlw?S!5l2%Bf49;Fj{Iw1xDbAt)bD#MtCHR+n$AC1LLrzqmJYd>|U% zl+f4wYubyRKGPNUdfqYtE$iXjIyXcJ@+vNdY+l^Te!-Lu1AXaAwyPUOx>f!br!#Gv+0Qm;F=>|1Cfsi@div8!C@u$_OXQc5n2CL@>r`vCJ z8aFnVZA-o$OzV5ZNIx0ul+|+}#` zsv&$O<#Rdyo92>jcqAnsmFIC7<5_u`FqF@~ z5$@|TayR1RF}G*BO~bNd#P*ePZ~BK5iS-{116QV_RYx9YcBWV3d)B?XcCMVf{%270mG$QfheaLSanssa5Ha%9;jF@b ze}Q#sklw6xyLZoE#qsjQN!|brD0f>7=E9ohiI5&?c@CRNwFEkYN=~mBLPrKV3dB`NO@yO5dy$`-Nv&r?^bFBx_v}(4iy|OB`k!1D+8&No* z5}*GiZ!Qu}OX!*Jo0Mf$yAbVinq*VN@H}jH-h?b>;K}bwW@mhs+4P#=&51$riMMxi zLS^JTIgxZn&~BX3N^jG}?WpJ>c?@XwfT-W4iqmA<;K^)x)-!vaaif*Ze8u{sxSL|ITL`#k~i{Mpe5f`QN(CoJ+6UF01vc=ky!BIB@N_N_Nd?3H?lU zt$U~6MV^5ip;l{^iSklYy*6g;@}7RU^tj59zB7_K>608)-q#&k{)_2%$Bp^bx&cQ0 z&k?`vhUbCfm&V+Z7T)E%g(a4~oM`h$pzf(Rr+eLe-0iC88=G<8 zlRfSwDa(jF$kdq`YCR?CiagnPp{FD3;eAI>E?iZ%75ioW+uY|{Q^{GKrTCt{8y1>di1-8+6<*C4(%U=X``(~Z9+tPa|4B+dHxRAo34$u#RBaVU(G zv~-rZ6YyF{%NN&%dC*tY;REuhNmF%vRGA9!l!*^8=l`xyFbv*#I5UNSFm zOrS`rtIPZH=h;Jtj+e7Jn%)h z8Sntck-NE}-u{a4xp#nD17wF7`1_q7vUq%to?D*`BJx)_+r1-y_qizVJtrFwp2YAT z*X8bPO!2u>l1%ncI$TeJ3=uxrANc0;`t&d{A{TleIr}Nv|FS1ZU41sP_{+kj+A-cn zf9GYx!1Hq~I<=L*`S0}CM?SThSo_tw_>DwgImLMYW_5kSn5t0BU7aW2J7pW3zJ-J; z``lD%Ute3zo_pLR3i3T7v&j187xNzO1JZ@ZG2e^hcsini$c_wju;66g^Yl*@!e{<_ zE?h=9|B^jBX!_#*PpPlIqrTm{yYp#6UsvM>s@xl4ga(&2WSsBd5VP(cBdkY26tmoT zVk{})c0Dcc81`Xgc&wK^Dwtl$U5vWRI#rM!<7B*q9U^qf^rNWVR+%)+{ipD(}PoYqg15rarWdXU7g;5qPOfNtN$ zL&Xy9^GMK_@2O+I<<$nwz`q47ic+KNG!c)MS!l8G)5AHT`#QYVcI(UgAMU`~!fTVc z`}6+2U;N~^Tn0l6pt~2KDW+^;a@tl`hqAXeCu{Z;mq+L1nWc8s)kktS#%m}Yx0Riv zwhHz4Q;}u$F`vJ7Cw@LNb(jd^gf>}h=f2~qQ_@+=K4Y)-($w^Kw>Zc1w!Mbeb!yl9 zmersC@@WbK{2E8K1ki1BT7QaS-?E@*q#n!2{WS;mWdYtho1K|P+X~R@x^kl&0aMA} zC;9CDUViyo^TzuU74`VxY*7s{^DUY5`05ws@tp9X%uEG*V=1oH3D)E~W)tu2y|Z(v z*iTby57p9d(cs4kLbAs#kx`%c}wS=nc&zEPmbae;yUCV>ZgOeuAb+wP`Y}MaDNxrGc-#6T2LtlP-RGNWKmh4P)lxM4K ziFfjto{!%3{I)yjvYu64#hKL3%KJO-RMFl6xj=MXqiHzawQq8zaGSn3_v)|eaH&}eD z>pw6~E@*vCoyEkm*FQ3x1#F?l|R%30C?r9tx>M-F4+8{kY%^Ka~{?~`*?F` zhb$T9)t|g(BHTXD&|VyV^*;cgD<3_2p33K)B{C0ZabkTG^HA!fo`VnHS|7BVb8aVq ztz~6Xp$YH<=-tpS($s^sokZ!AmAAP415MSH=7uoMN39Rvuf4|2`Ze2KGtYD`dz|n+ zt1M!s*eU5GEp)`pg6zr@N*p{P?leP3D+P%(W}T$}#HPaP$K7d^k#T?vWHDG`j{SY3 zi^T5e;d+={G+DbJe+)(83@d_(Gf_t)U;d3anSagvb9@KqaMcfAy>q$tWrdQ^WQ%l% z?TBg!$vmcZLWvb%k2wGkZ{}&~Vu2sh#JHc1RN?oWy%xw;c`+Gc<#R(6O|DW!f|uhR zzunl_sUhrEPT!y%4)vOQP$JV25YeU9iJI9@ur3DLWGfp0us|#S#?fQfb&rY?$uqrI z6?y3!Q8jtcJ?W*elweGf9YOL?TJY=guXpC zICm;-fuOn&>|)h#W{(5vY8C#faYLeAUE$hW7yV(^^^IKe8q4B0CmjChSbfcX7HyrosSRQ*`~e3bj6 z7S$>~NVS@Wzo#A`S2LX=Zd;^7Rk~kCvm8ZT-U9`%6p0lT(iF!(fz!6xu<%b*$Hjb+ zuBHEX;GY>yH0kF$da<+PSzBC6SHXgz&6M3eBh{@?3@Fal@-SigX~qA9X1>~>YWqDI z7*O=vV|V*s^W(s`iBW5t3O5h2Y|C~@;w~2ziQi8)lowkh^{_L}Ir*np5wLfT(wKcM zneX?6sKjU&d05489j-X!hhFNHQOkuIf-#ZUhKTCjkmn7Ys2y@IV6CLLLchAJT`!Y7 zbeesSVx`~kYD*<5BFXPh-tNy;HkcKMknvdEoi6YNokXpnKH0cI{vLoR>g5!$_yYF= z5y;Sv&+ucVml^6Snx)iN6I^W^X?yBzj7)!JRImumF{hEIrw*%Yao_SIn*)kMp-M)HFwH zxR^t3;hlgFa+)*Cc~#9BXV?PvYF6&-EB~}S%BMV_(hf3z3wG^D{eRh9@rI=4$aiHa z8)cFHqhZXlZ45jh1Z9I;BX|0n2N;!Mi_w4p0Hz1i0<)?0&Y)CR@|AT`c}Aqy%cIJD z5GhutbZ-i4_O_>J{q^eI)W#=Aa%I>X&Yj~J!rlOKn?Z;f*e~=F&PZSdQYLhkxB&K+ zrWwbKYcw|WZqFPFy@dU6Sog~N?Gk=iesG_*h@(hqBuma%{L`){Plh@suR3`KKAQJv zX|0fJ2Pb>C$#JX^aHoN`!Cp;4h2>to&KtJ)tUd7-^Bx`7Yd@Z0+)Sm?t{b+(;&x4n zC|}AXW6w9-eNSEbTD#kK2;LfRSequfcgm^65UAule6i>B9%>^hZVyU-dkm=u{gsYq zS=TZfBMOH)HrKNe7Tg7&2rde_Ukr zlvnY4X|6cxMI5>jVq>J|3Q0MDW?gU84GM#DsGi_W<`7u6@n8|DigBH7%Ho%_Xgcpl zx4*gZqZTUmkr{qdy?)WxE=Z1wj`3#89x9as&%AECw>phK+M(EJh5kTgo)!w2W>Do( z4bby+lmSJRi6;`%NNEYf+epnwzTf-_Nbsm>Mdir=$GPDD`r$6Xmxn8xxes;cVdp!I z;X)vTSA#cng);dEc`vU6O+g`wM#%MmeStG}xZ%-0k0Ei@vnZ`?Pg3ULBg_xr$d>yTRy~{ zHU#&%{92;_6go>|73J>>Q3MX)rhrqHjfey>D9SqP{UVp1W09#}@NuqS-m8HCz_LhG(P%pRDXcPn zKPt*udRfpxu5oOoC)?LpLsqfmWmEYAHWkHS`LbrBe{AN+h!0MTTHs&&W5SZD8NyS?$kL4Wb8;xH^If+qrvi5)P%9G&*_LpzXyJ zP)0`esS>nrHS{-Ta^+dG^aHi@MQ0kwTG-=;(kiX(g)=xI0TgNY3I0ByYeN>{d@Ygj zgde`Y>S@m5u-!&+Khv`vG?7N5}lsd<8;0&Jc+&|`82jHrv^{LUNo$Pf*8HvfnutWa(1(3 z{P>5(Gv4iQ$J&{D7mUQ0T{!gaYNI#3MV~P?yDc1}PF&cc#Sah6|FnN(qdUf=wAm@B zofA6M_9Pq|XRP8|VV9Vs_4;aIxF&C0pmq|k9%_`dmVV7$zqAQR5T{V$h+cuARD(_%uUArw)8>qM7&Mtxz7IKph?{Hu3Oq>UC( z?4cj8=daG)LqSE=Sdd-7gdiCaQ;M?<=iLZsw(-Uj*<^cB*U?*9tg_>bN~b|~_G$y! zO%<0-bZK%UV0?(vh@)+l%kref7ijvj86HU3%HjRhzk352*b@Oh}XmgMRrf~kp=P_Q&m!etSSsH0eU4L`jIfT2oh?gUA(#ivu*KXz zb4E^{!bwh}>l_fRhT>5YH^3p0yAOj_w>;IC>VXc-j9FkKyD#kAPAr_68O9l2{>kwg z_(#PkW%S8|qAk~X8vudgTl_ABl+pnS%-~p0h{h7B*H9vCw7!2YjiqJ!$GSV%ml#`kWx#b zX=q*(fLz-+Ud1tH#5Acxs=8A00;j7vTqDMAD;(dSGxZ50u1{9{P}G*wO-|$%*&wa2;hSWp)~W{gl}OX#8(;y5iFDF6Tf00A!m006T9000000000000A!m006T900000000000S5sA z|55-90000100jgD00IA8024q!NJvmfNKi;fP)JBnNJvosWB?8T0ZUCHteHp#k{)o)%U4RZv>y=rYw)3d!-W1+-NqJkAQnkx^$!2 zS80=5g>%(-#QzPTx&j+5u3rg-bi)gG5I3hVS#t^;!Gl4{pee~(vH?i5Mj+J#VzPeQ z#>{nB?7vrC5sr}xNReuOUDH;pEP`YZBnAgjfL!O}1?Izjhs=DYr9r(OLW;mO%4GK_ zVNpuSh_2F_Rot%#e}sf}JHAT;T`G^|p&A4qShS7>R9e$*P!wHe#wiHC+EZ6M{A)cr zvQcu8uU?0ZG_fx1+DzrAeC3br29x{NPq8t>79rp{t*}0C*@yjO>pQq)CJE|w^0S;b zvCwI=HrDrvv0Ljn+poCjhsdzrLhAR(Rm+J71ObRNnUYT)a$h3y%k5*TVS2=|@dW%a zqLJ^L*)*ypiX|>G5nb>woK|%%LZN}UcweQ(em%ClYPf-52@_laZKsL_6E(GYB4^tX zlsiKGNs4v9EgeKl403no$xZ`oJ>JSHA>^X0GNX5BLmx0bIoR)^9NNZBkx4~MK;!E? z^t1B^;%TZ|O3SPG_7FH+*Ci9o`N+($XWM2$=)hEVy=Z)$Z_Z<*F_~2q9|>ghTye+S z()4}3Q$y|P;L#2*;#E23L4jww-4FSvnCVKkTKpD2cOhXg+LoeHihO! z0uTcsY4?inqJrr4e-)hDqDoMv+vjztR+dY2U&T(uZ56SSODhz=vF0};1lxAMJcV)~ z_Y4Tco|j<{($$6rzfw7@CIf)Y*1S+6XQ1YfEAjRo&Lm+#IuMKq*sHTz4tT!M3_eo% z@4o%px-Ntms6F<10epjY|vWq$$h1_*JWmh~;qZ}yOs(yra?4WT-D zKM6Z+=598wB^O&;i}bzS(_n-Z8GcAI^qx_G#G3=71@AM#V|wO- z;G-jS_b5DEPBU0fk6YQ|n3l6Sl-PZ`}_VWWACYy)B7)tC3dw5pC=H z6bM0d&Xny=#43o2g=!9S9*QUE%}H?3LG3#Mfmu9lF9TSjFUKq`%ycBi0D%g*IqR$J zv>?=8`ST3u?+$u1OKnWK%T5Y>F+T(7hefJXB4sY5zQVT@HIPQsZG?&! zt#;QebSB#=+>^w17xg${&D5Y1kE${bi+O<(m`R#MY4Ntg7sT)APhPL`l2o{olA!E` zQ`GzWA|pM8Hpue1dh`U<5hptnC>U^6LUXD=_aJXLnoA=`q0|-J+hX!lbp@tHO*G2{ z=4s7l-)7WkA6MRfo&d29n+_P@%Q9b20eU9aOp*Li8D{-a5*nYA_gnskb{>V!P zO6kt=VAHp0Fm(}YYAwYKha^mN;%Ek)W(?s^88nv;rZVAhZehGtd7OIhq%;ewtU+tN zSTUG(EXbzfAg1Fb;`m?7xcpm$9MKMMC#c~!CNA6#GKzFt^zOo|m~S*i_cGEpt>F{3 z*Bq!?E$@=%`%96#CNO)yE})5xZ`t9)shdR7pcT+)%!+PiBBRy5Sy`o=Qm9gMuvZ;< zY5s8)-3E}&gXKf{!ArLT6LY5ZT#*ntdnpQ#A2tzgbjX1f6i~%x%gDkvKP)iC_oQmU#lQd^=w7H zz}!GKz+pNEnSU{_AOA3$Sfdpw0Rr7llvs0i?o#spulOAt%Lboiw=K)uc)^oWi$s3A z?gl8SiHI|g-@xyC7LKFEeTeN>4VyTMiF9svfM@Tnn6=BEYj46IyUoOvBgp<%Xd;M} z^x#;*7a;exUf8-aJLsKqqDcPNu;RA9DTt7`n-(PUWEM^1pVwUxpxmZ=it6TF(w?If zk~C=3OI6Yu6-WB$&JIcdCq4bA^yd7zMP)vFmJKwR|0pJkj?hpV>!}85nfLuAEu@uF zTZq9m*LnC}bi)*bR=nK7|0D5$d3N7avqct(@fVhLB6jXv%?>yMVOz>zc`Y^r2ey&s zBvnlNM0QYjKPo-%agFeTc9+@rGQ3(J#G5Kv=N4y9CjWa&VD9E=x@FQ-E;Ysf0G(dN z=@rYC@r8I=<}Y|PI;k~Wk5Ze~x6Kt%G}XE$P`aT%;Z=M)D0y%1xT6^87&4)bU^Y2s z)%)=Y9?(gm(eXyA7<^ntOpvsM*n|KttG-6-da2kD9|!&9xP;=m_5n_8-_`Kt+><^i zfL05HrP2Pvw3?&vMN5J@)Bf_r<#Z}Dk56}?;bHySn|s_Mr=(+6EIVh(ufI8B;(yvQ zVFX7RC?W*)2hTYk4Ze4p{qoq#znx;L_Dw-Bf|L>>&dP~NwxtT*vn4?id+;S30&$D@ zUwwZh{TCtMbt>?Bu?Q6!;b`PYS@(Yq>)Sq~8f(!XMisDVpbWNQvR_aGiYu^`PQ_qM=SH>(TjX8eSjKmAyj|#3q_N^6 zSz6MJhlY#qpAPf?Cy?Jt@k9rGpv5XcAUQ4K8X;Kj@67I50{P9f^La91$UDu7%3=j6 z(&T{Hm8k$rRP#bQY45Ave6-{dM5Dpc=q;RN%|Xa0NHYk1UYLt|a=G+GFd4n%JWfd+ z6yf^4!M|3hWA^<8x7Dv$KUckX>ejI1m|wNek#ZWF^_B1;+L>)N;rUUmCk9H=m=yMy zOtA><%UBuGg}u<4dhL1oTZaR@tZ^~YUGkh(RBn5SSlhL@O_GuSaSRN8GgCDuImxcYeCu;g`2=o{#D?JfKSN!!H8r{= zcHs5^!91I-q4{r{N=CbM?*q`R7!M*4g-rXW8sjX1q3(f|j(786PwM(670L<){WGp2 zY8d9`78ky0r4-4pcwAzG+7~0R9NlWMJcR|mn<<}%J2C9DTH;H8WOUT+ri@M}_x6Cl zm7f!K^tblZEhq-gb>Cojmw(8e>4?vA!f##IIOU)UgM{a*7>4UTo98w{@R>=Fnob(U zDU7u-iLWdAYQj5YDqkjCN(D;%ceY882kmt)n7IQK4c*0~>kCtmn4 zPV5NH5$qpKb)x?bS+aCwxjy^QeK2+OiiHB`1aOeGzERIg3t@Z9&+Q4Gi8a@oy1mFa zK=!TUF009P{tJK)zk8;*qA{BArizf;IP2L}vei3oIr<_}Qn+rl$lm(2Py_KTS zV`<6hcZB7N7rHVFWmuNAXMto7sG1%B4515(5`OreJ8ku==qiY2ZQaQFc+QX2cDi1lSD9f88k$ zi&jTv5miI3v~wH4*DfMK%wMs6);L~!tLP)|yzqO0|295P3yXJ%sMjDCNi?G5TM-|ZD(}wB(8xi&=0xp3td_=5$-=qu=qmjam3Z*QMKz=dXq{S?Tq&cmQ5fnw{n}~Ey zlQUX)0Z-%y{j1cvllf5Cx>s{CbvEt2?-tpvoN2uX%>PqE!;VlFbiU0Ae#AculA*4) zvou?-1-{d@610<13yo^j-k^5j1%7VaNJbu+s{!xZONiL8ylnMhO*0jNri%~*g zOA5AgCE*D!CKl?`P?m(`2kUqJ$$7%}v$pLL2eMLxQrw86Zj=J~0>AKj81KBu7EESX7q;4R^P8gLt*24Czk_Xy$wo(kB{c_%AM*VL`JnAB6V&~z zi;v$#x+_FoM|8&(T!BQur3E*SBBnS`JPo%{W?jN9+Ki6`Lc(n)Kk63wH1MC z)yWEbp>vt+4$m-X{rRK1A5+zOJEa>Z4O0%OwkeM#_SBFi189zW*0?HBtN$zoL0F=p z1Je}(pYc&GyTdcg5@R4-j9$>o#4_rF2xJ6g^agc^z4ND$AU4;Ey5TtblG8biBe5iR zNc<2iS5E7^hl&bvqnRZkV)M%H7cI-3gGu)zbOal2mqu62kgTD+ik=j8Rg!NoB7!RN zk8=^Ib=);A8mZo_B&ASsZFV-s*OfvYV{b0`5xWKY;YZM5g! z)LtsJ5_C+UoO`;PPF*lI+;q(Wp0Xz#L z)T;xJQCqsRO=o7oM%A~KIJ-aQvjSVSp>9lFb%$PH84?`PF4AaAghUPox!pvY48)6j z)reHC;dw$sq}N(5$_n-S{wk|?V*%$v zEfa)ZTd?K2$H%HoI5P4=wjMa2*nH}5+bf*h%aL4OVmyEnZ9nPU!_TtKHoV-ZC**H6 zHB3Cxs&0wk+hH6UFWXhDU-DsaTz->Mrd<0@u*1mLb^4xTJ?eJBqMX)UJoNf}E zedN$+-1V$pwuv$Ng>?ZiPir3pMtYb|sI>HyPTc!7>Bg`Ltq30K}<$c!@Z2JX| zd%@|FTUptg79Sa5=@aT<%)S9u66V8+hB4K}E?#@Jx%#-(;M&KseMk`dVG^Qu>>qd; z+$u*!Ad@R!l{(OsR6r2=rmaQEbiLmC+B9IertU>7Q!ovE8?l8A!Al^WYi?qhpUrTL z&AB6C<+Q2xR-dLnWx4ayY40Yop!8k)RQnYylIkCCN!pq}9y5y%CZr9rM{LoBKWPXt zW8Hfte(W;U6G5gnr#P&qKLS@B>vYX!@U2*XGk@mH--FvgP|r+!#Vg56#7|m*0)L=1 zb%kG(SAx%_Go^>4YHZ*mUqj-xboTp}Ww59ILM^NxtZ5g#xi$oX$7!pp*VATiQfX5s zkgb)O>Zx5ovsV}x=vgJEl}z=E1GT+@=vb^E-puuqt2sTNR z#i{{@VO@vWG}M!77Ri12Iz{4a>i62pO+ZhJj#} z$g|{Hr-H{Ck~m&o1H_jP+zm4!edko-;4oI=kHai9C+aJq*DeLii^PUX!@+^i4jr-~ zOltFu-rY@%8E2v3?no#X!^0I?x;_jM_+V-cyYVgcLz<_R8y0jq6|s#tbfZ6l3R*6) zAhTQPUe_=y{Ask@z3IEnx+$+u?HD6PQ4W|~SuF(+d0k;D+Vk?mb9W!@I+J|#;x-~x z%+Hsj&UzTWUEwT3VFeTo2(-?vs%}zH6!L`oHYTG0Fc}sEBndmoiT47+OYlc`ZJOfv z-*LzLTakMJr;eu3vzlHmUys2WSbHv2w22jxe7t@T27m48srB&d<0JuDQCsk%d0I>E z2TjD9$B-2HhHAE4msOetc!Xyj?P$}*Gsy8PF@B`fmng4QrFRK44Nv;#4tY7#Sh z;L3}HSW2Z`w=kc6urtbwymyYJ&c6qHNq55;)&N8 z=CxtFGDTqF&YnWnTQ1f>B>AD%Zbm4wbBpsg=B{43OPBux3;_aCyh7mBT>aT1d;>gm z&Xl`ErD?t9-i9|dn+BEPT%#CsOaT2ms>%~q`@ksS{OwX`sXnKFt=wubBt8C!Bc`10v|?^Eb=2AH-}F^p1;)2heOoLvL+rI3-4 zF$Q0OQEm!?%tnqvjMp`vf|V$*rGl?I+h;+hMo6g!6R5VOTRm0OGq7wKg$8*a&>Y|` zyVghjIwNP*B`un;ldcJsz^93EGC1(q+Vlf zi(|I|WQP8-h0}#;gCwU_8>**SK|2$F%YC;GOZP**?*$ZZ1!UR}5s`v%8y@%oq+V`t ztcvVswhn5`s}5?Ct81@$|3s?W)=-hE(w#Iv^wyf3c|xak*ywo_3!2nkETwS$D{-$l zGwmb+GLYdersZRmCSh$&?KpY?II~@^-R}*-Nk~vV;iqob;u8@3 zcN2$`=2E8*h*pBJ?XhVrX`@S`cRFn2geuuOu%fIeuDoDo?fFrQYSED+xJKyj%WrKQ zKvr8$q-!c-S$sQfVS~D`sv$|Bv&w#vKkKX^zs5an^G3=|`t6_JAptl8vP$UR7d7^f zW`T689H0Xf=G|bdTQJ(H8`p!?m_$J%VZuRKbPEf;hIzCeVj8XS=cjHy z#&u#^LHPBusgQ;xj&PQrJCnPh?Te!-o8+~R4#q1SzKD|q+`&$8A9`vB*g?DDiAu8h zYnZtAiwIsdx;1)~%6n>(y`2wNx@*^rXozT|@?@mx!aA|HXZ>7GF&fkzU&*+y2C&Qb z0?>D2_t)ZW7KUL2)#PVeW600HAGp5`$nDlirvq~d&iCd7C&~dKuciTtCPz!173a+r zUYr8BYXzv;_8;ifovj7;aRl1qb$Fx}{Mg|U61HG4Jxa=-Y&Zbmai75uQ)jwbjzo;F#>r{`&1H+y;7kks-T@ z);K1^cHToO9>i8_2y1F|FKBNce(^i$AGG#;@`D4e$}|_WUEo>wB~PC&*{Zm$W*sp<;B&low^V(%GW*pgXj@Lcjd`!8f(JoW{27O2$9SD|e@FSm=jQ z-LAZagS1HNDL7#ZP(G*;p7_37bRUh^Dk_c@+%aTvhc5B+u;7_;lej#r1yH7CE^Dcz z+(CSP*7oovqj?Db7_Q}`GIIv*(L?aniSiXVyW3~gjXZRxtjb^~1!Qg;-x?fjirh_K zr@FzzusAEx=^?Ml5H&?pfw}TRC;KPH7~t5RPq;ra9%6Ea_CbeQ#=%C3%Kmao=eueZ z`jEAm{dTBJ1df!-438s#qAn~i5FfUw`cJo>HBXgJShc|S1QN}%2pD}Wp?;T){gEI4 za%5vQDhIZ-${+C-`|o4B6m8VE9cMJ3i)6pYC2`P3ct4?n024K`sHI$rU*-OLYaC~V zzcbU(9|RhLc3k`^_nfVa{6{fb4VJp<(}Jq>;>U?gvcop06u`qX4+`Fg5C(;xYjmab zlS~Mp?Fc|1Sb=Le5Ew@hLEYBH>8mKDwaQb?Akd0%;A{Zr1uK}b2 zH4`MU{>36WEbUMOQ8iPPXP5<_PBLJs3px$)D$a4ui&i%*KWvaG(H4C=GM05Sy-k5g z=13SW%#w^6P;`x<4B<{4dkVZx>zKi53qDyz+RRWL`q;Zl(xF_4y?TA_d6Y z#19Pl%M`4QN~why#ps*neu4OdH?lceplET}z18vM*wsu)%-@X3(ZZW|4vl~>!)x_7 zphUv5HTgE(s^{p4RH!3P<5?8q70;_BSF!1@k#YP_o9+`zMHW0$_l-kVs2Y8Pz3fKi zF>rFN3nO!w`?>sH^MGjL2zUp`WKcD6w1~!1wmD80nuWW*+RWWM1)sqh_0NY7RDJ8F-hmJ^%#34A+JsQV=Z8{ zwkT>&5HH^pq9=AA%96vF`rzMlA_^A5iEW*2iR3@?-e#g@8s$4M75Uq@2@k`Miq=tyu4*M2eN5BLtyk zz_v}nf^2ydwmZ->i^uvrbob!}4Fl_trC4N&L5q^Ncv$}KTxBZb?$aifAYx%AWr5DQV-*GO`O?6E#=^vLo0P~K7Us+ zmQ+bW6$HqRwTE*d(hUJ)uvUk~_@K?u0Xe3X6Nt%dA4Z(HU3UZG5B|zaIYh5Vr|-SF6oBM< zu-NxlN$0o;|p{M<+Nh!ow29N{;^!csJnV(0kwp_5c*A{?>TK zSpLIuVmWSy9{PrTY`*9TthmTu;IGj+iJgCXb`OV5ynP;4Mel~eP(-4bllo}?Mx2cn zmw>mbS|5R3hiy!#XCootcs`1a;-G17$vK#JVQSR@L9y!LUdNzZB<)7hTKqYJoz9&h zw!`%nWa+<-TJ1qN4SHVb`de+J>Hi77r!eSu$jHgD!%`K-tjT-ZQ>$_UXM`j4!GkBI z$l4&|5tlz4W1uD^?6%(in#fNblTwzI_Wf+My`f**P={V_R9gNGLWUwSc5<1SMvsf} z=+BJAi@TDQ-XPT(YFRUsAF_>52cr06oMVv6{}#<~B8XNxHzew2J$Xf)G0b+YJNyD! zXu#nvl-)geGWT zYE};t3sPXvXHl(b+3>pb^&ol8HXh@RO2be9?6csxI&0@1uw#j{r#Rwl2up4(vVr7Q zvv~9rMQ6kOJRJeehShJ|rNVL9c&Q1a{Gb+Se607SMt{v?73DiQtuSlir>-BGVg;)^ z_1Jfk9trSSHXlrp^~;kHLJoXf?BTX`f-6=MgbYjx6FLPGYi6#rsLH8<(*1rMg0e-G zWFA7{<{iS8-Y*L=<9Z3%Z$FVD@91gU4SNL5T3RbF!Kg0T)*C+)+$~l5zz#$yKmGW# zMuW$CIN_0dkS2|?A2Lga&fcQ4#d$-Fn0;?tbmeWq=3X51J|Ofn8fdUcsK9XKpC+wH zm&>BKvj1#j?Wx;v(yXeUftm(hjfP5-g37AX6-(?SC>tJsqHHuBMTJvy>;zghqoME~ zLT6tqWCTDsIw_kN!IVgvbezmIDLto{}X4~(m|5dP{ z9eW@bVOsPVt)rHxwEb^nAje)zSMdI?qu2F)6ATU7Z6h#qL%TyPC`#2>UzeLW;!lf9bmgf{}%KgY|`4j2!bl9awv4lyfude zYUpf_UGc??!bI0I5g!_s>Rq_JKEgXYhWF2xSkdix$*z9|;eC(>%+a@6d8}T6bzQ7i ztSmCd=l!Bz7NUWk5DArpu^MT-Dd0QEd7I^LVW(9=wjEmp(jQlSrxNkKzL}VVS%kY! z5kM7*ZOPk6G{MnBzv{dg&n!8mFNk9|x_wlFq1lJUfzxQR)y&)I@Z~^hlNVM7*+DJz zkD{c!RRB7Rw;N^ENBx(G2&=W?Z^`PA8o_F{u9K!i z8rds7w*Fu0zv(-{JZQYH<4VYXyJs+GZ#@9~U_+F(A}FRKxnad$d*W8fX?y#_;DCAT zLgxbwDH5dSF$0EE3ucVIFOp%4D2sNK5(B_5{Nc!DmW7)065!04>+4Idpj*<4+YKZ# zYR_S18jq)ZVB1DGsi<@E&!hC0djj|K(%*UY)@DFHsoFuk#Os@L>AQCc3>Js+cNFnF z{TKZn?}yM(PxnJ`IuSdn2sG=DV4;VSd{$c8;?Ruq-sI%|uG`3s)WH~@n ztO;D_hq$9_GHsa8%S{&PRpcYfNA|dm>DKwcXxQQaG3no&^a{PS68f zJU}Tt3u&Wo)yJH6#jgXw?49ZDg^br>Qe5|V2vH>B1O^Z)J7U&9mtDsahQIahQ%l=SyXXAIuzaIe zOAP!(8i<+tqSv#Mun8r6oLstzh1}Q=JpNTc6C+7rO26f%DU>jO@0arO@jLT7EWAVC z;)G|&Df697SEe(#6ZFKI+e3Rp^Pgf!);%M>eSE%GUmo}2Fv;4aPj~~=n+sH>)gW8gbx(ZpTa@4MrXcg(~@-3Ngi`E4j;w;;sA(a$wP(k38(~ zBl*~r4X`%h!@qz*vcVP7EsLy}ADmR76@~YxgWfz)X8{`t*CSuJzhGL=UTc3|fu{NY zI+e%%RH2(Y?F-&{8&6!NHtPGYafOeR=S--JfT#NWC?N!Lb*abOb~TB-&u<=YBsI6c zB|VxgG*MU|bRq4vvfzMu8V=V78{Gyo5sp`w8-VBS0U9an^EkwGP4kvY_c;~P+KUCS z$&Z0P2J}`?9TJe-klJHA9_ohh7XHo%GM*c$3U_i8`DQP>QP)x;_3~6ZTPvNM`SMF# zu+aNufPtBDnSmKsF?#H=j<@oaHN_i)@1`oVtDX~_P9L`~+F~E<{hcK@fQ=#FwOvvw z#hbeQX)2JQ5~CWp8z>FwP+)(S&-u=$D1Y8IE(0HS+AW7;?pYc#>-eshmQ!4?RiSKI z2S(re_1IC2w6##KR31kLh@QpS3Wi$fy8LuQ8od}Y*(kxpt;+pPZ{bb!~Q3mFO4t{h^z zKN6T1zmHxCz4kp3qVKw$f}hAl5aCBykAO+_2>0?(fMHp;aS`wR{Gk^pIiD8b-3dwj<3}*;*vMmV{*7O5u{VAQVDOJIVW^?tnPy zV0L}4#wb^&@=v!n23LzIH!@`|M*?p%2J=*yXalwX7z=po9g`=N%$(+dxNdF^D4Fu*EBP95zKBnx)Od)f;gI(VYb}0FtCO9{O(6r9>mcdFG~K2hAl>Uf{MouaBR76KZ_=Bn`sy^TcbndWpMB1>r$`?m0`WfMTFj6jJc`sT&7q0;gUPqK&i1$}_`$N|~__p@Sucy`ZhK9+w@jJ7^IAunWs#F6{zN-mM-Sk8FUsp-w?>IP{YnZwf-7SfJl*E!; zMr@jpETrGf^xoPrHjoiQzbjVzVT}ItUc~;dw;~=^N8!16Espg8uegx7zh*;%U@KmX z4^CnS`AGw>)Mwp#nrC!pG%~{-8Fl$(jV;J&O#D-2t9GwhLFneU*`^wRe@X-fvk!i> zlxjqUAf>ouj6u~(Fqub_o}9p4=VZtpQntG89ED|I>A-~RjP{_PL`||h(!(Cyr5P6= zL%NR8FB4fu_(;<2jN`yT%4r3D3yd=irKn?2gU#i@hLsx*4RlR&zJRS$w=lXkIMMrS z|3_bX8CzjvkW(_ht@C_-Y$N)FpCrE;)MA;SY!S3rc~hk)`u6gadZsWm!P~zz`|`9v z398U+rWaqJg{hPDKNA_HYBuxdiM{5u%uOS!Fb=OiHnI_SU<&{Rr)=yESr;)vf(=rU z`|ZLVi}Z?$dGwUx%3|I!9#JSfG`W!Na1kU<-ZxPU2i{BMEFKmu{reD7Vni$uuQ>wF^z&y+|&M4w{Y>N0YmBjHw(id0W zpzXH@e(YN}D)Ld331ZNtAPY&8o;4Ax?z=EC-8UA6;H-!|U(Jw@kwSa67k<`p)%uQb z`s}C6qKsc6-1M=XzkVz6>DHjN_#wMMli$pQyMoxc_bB(tqQbhyLM@pTrr;boTVM9; zCQEnYD}aPTE~kw-D#T*=lrU8QMNc`|P~qtaW+(mIxysAQ z+9iGAn{b1vV7Js4_v%`fCh5pz<#|0`8b8L@#kc>PxLI~P3*U?=zk^R}K zCw#J&L2LrNhN0o1R7=Sn^iVjeS&6J?t+@4f)roP*xvha_e(tP|C21JR zyqT$Y*~Ae%L*U(q8?(N9{#JQ02_=&zOUIt)|8RLb&Uk`rt4V*-y@%Ih`>@V1K-2X5 zQZ>4gtw!su3U)6~dr0EaF2$XPip7#goTp z4LML##8vBr-HnX|Dv*siJbS0aSa4L^XHW1_efu_s3w-3J6_y))-k&Tc;}2Aklv|XX z{WDZ?jIkk8Fxyx>EWP!&ky1~v5Sc|WoiYa0Qo{*ZI@zL#a>hBw2op*oqUX37s}>Vl zrC?V%zUs@tek6#IZC$GmprDrgOC#3R$aTdfiG{bE=YeD|9Is*}-L@;H%+BB%>f^+5 z&|J_8J+Weno^w+-mBIc4?W7zFgh5Bg(Cw-?>!#ZS$9D$k^v^WBf~@s> zK;tFJ4xc`%YFfIoY$G$77Qh_U9Sn3Y%#6|EXXYGO-{*^Z)=p|_p6B?UYGn#`>caTE z$%qjR(eA$}O2vkqP<#j~F%uytZHBYK=peS44DHhhmCc}A7qo!yHz(^PyRH`p-rTK3)pXOdG4@PHS=@OhkoPny?ASt)t zvVyE1JQljb0$u`QxB(~+RB5|YM7p9z2M5V>Ts0EpH>kkI%6g+koI%pkE#+^>iIJZUTm(vpUkY3nY*td&;wpdj zhXPx7F$ZW$&1XzE$;k|@Acq);vMhfkO+A53%VdRq$`NV2mdgNLu!M+wC}blpmS;x)<;ZDduX;tKw-*R*nAUEqF8Ur|3&I@7V}aux1hPxmCHls<3z_N2=|P+ zytN>sK$$t*))JV$mc62IrVk9JwIi7zlqh85>uvRWP14|+D)N3XR)2fZzBO-9=Y+dA z2khFYO=B|ip|8l5Brv_r%y0;0d}$h6nSUZ_GGBPWr(!<0STkN7FdV@aEUAllOAQ#R ztz?8^S>izZzj1W{J}5yarf)-~9@B*3WT0b8MFuZ?6Izpslg>>+>4&;7OWTn%Bsd{o zY{<4CZ^T-k-{LuGYcp1w?RkyOsp}2|56IM5EbL5tjb%FAfi4DU&=&j^9H32PX8ezj ztn5GN4m-%c_C@@S{{$;(1WuP&zk8Y)8;oa)tXrcTU?f<*@~B$0l#cqKl9+y{KTBwl zPm^LR%57G%TM`CR9_C^gOyj`*4F#n-@Spee)GpT^@LSOag0Gblh0_Pg7f66l5&E2q z%i6ml_)vrF$Yuql^9GYu-D#X2XM*a2N$!AT2MEof{|YJj!8OvP8GXaepDBB+m-TW2 zB%Lb@*ul3mr}_&M14VS51cA<5w%y5aV{-3!*WRy{H@Tvf3%vHlu}*k^eAdg#lR2(4 zAJ4s}#m_%;y(Js#zg(of;FaN+=F#L7juKh5xh);5@mu=~(}CID7?iDNkNz~mwfJHH z;$1T|&xgg`=OD z=vT4PD*9X(sodl+#EnVd5-B@tlDbHuZgjMMd@NKd_9Bzd1e(f4F95+PJlBcBUEg=0hCWApvJq4&E$#)oF|r z^1Qb>Y{^#Esr+b<4UrOPsgbF#ir7R;HuLBoEkutj?|*%p#pn1%eTM58^wtQP?sZj> ze?LX22)V}{i}&bQqSogjAVR78MKjGT8Dc(O9WN`5X&%`%hDYEbRB@y>KuTl>8{{$< z5as?_k3Upwxz@N{zdid>!O?2{MhJ`-!6Ka8N5O=g4`VnGF1QJs#9*~1(s z8~AQ6HD<>heLTd#cb-2E7uufp6;!?85oRf>v9|PlWWb-p#gVOt8&OV()@#OrHMB~W z0#i(#g3GuhP=5uoiW4_^=5PB~39c4mlE~LRy61(z4MZnbWgiOlzx$WWOCCsa-)TQ! zLG_C+_-0X7fW}G*u!oUoao0pNi(P3ZhBylw7YzA_F%8yM0^@f1&KY6DCt}-S1PV#% z>DO1bZQX)24CpVJam;#=l!`?*#y{63P#v~Kg{S{AVf@zcO}1*J5F3cVwyU>`E)y!= z#uam6myZwOr{q^~3MsVLaNqXJdx)!jb!Cuuu~ujS^kQ%{r1(QaB4@kvkhZ_ub_ZxG zPP&sQtlE&%YQVl?xKkc3b2`8Xyq)n14t_A@^5&BQDeBs#FgwZ!;G`xC(_AB-Z0j>3 z$Q5p%%eJumorL@KGF-T-N>6M8M*_Aypsj}Ns3K5{pC@Vbqte3~9ts;{t_i?;(ZcKE z6{$0%L*YU#LsWt=omqELjv#C5Y@ZfSP`!S*Dk^ENujA|5R)-q*b)n?dzYskd*#M1)zug4E zf9+bhVDwKuM)cW=@=%QVZAau!?)Wbb0kv-`Wsm2uah`Ugw@p2 z1)B)!KS8j#{PsG7S*r-zs}T^{`bcsQcR+O6pJU@sPZt?@lq3Hou7~d!a&d?!3&Axh zC^EViG0%%3XDY^JzaU9RYN_5+Jp@{*J`ce;s%(>mKYua!sgeekX5Sf~%E5>oxF)>_ zksFdf2HTr4V&VkSO=paa ze!{%YVbH>XR`LIoU>3fkrE4IV+#BL zhc=yq;RR>*aq&Oc`nHqAil$}D;jx>T8eVMg1JZa?bm}4yIDW&=e#6T|!@6_eY9K=X z7Ai4hp>%`=Z-vGF!f1Af!BY$VPtqSQ5xvC?DLFjh7u%}`l<3fE+zRaG*K%wbDbi=d zER@j0{9LB#mXGpBZR~Vci-FRXU##T@ zPomhN;ozk9nXNCkYW3>|@lI?|+dC*fXN^Lp%pTqC>5sdkMxub&uGt`%{QpzbykXjo zGCQ^}yw3W#q}ZWx0fqgVk43C$>CY_%w`V|zs*a$y517^;gv8CH^^~cm^t-bJR`Odo z?gFv=?R&P$S_4}nO>R5weJvOeZilT_P{foJ5n*HN+&mF58N8K1mU61P zxtX%XlVaQqW7j@RnI~v4TM27_I*kp{LA)tsi++uEbSBA7E)CJ|&&C2>YNxk%clCU! zr*tLJeE#xYG8)v{02M&$zlJ?C2^ovm(!Oim2yupl18?lX8t%#St$!DD9k#K}Z#c=B z(M^;ZISU}ge1l3FX#Meq__J# zQ+0f13(@pBMr zex+r9t8#VE&uhLIvZ`_Mm5-dR; z1nhI5B@uaQt{KRt2j{?I?9Q=(QQ-0hhasG0Z-s^W!FH2s(5vwT{W?W-%>!92;8`w8 z6jkMNdgNQLOzj9YZJG?J!$WVF_ z;(wCBLd@%7#;+|VAN@{oS<4t!^`9BcjE1G2`t;)z$0A>u>~mPG!@VJsTf6MiR3}gE zaVDk}6*uYN@Df|nT|SWZ6~(}E2}_b;iU^ei!F?mAeTTjx<5GL>C|pgub=FvbCi`F zVwe@>Xcjuuqd`=48#pPE=TyW*vJRqlhV{Dha0pi_7M&62OM?9NuWsZW1_X zRYBDCP??ki7>+Ae3dXF(RW}rQ^&=is|sTh zTgX1{K2c1#4@a!A#Ru^VNsFv{YL;V5t$A1=S44md-v2CG`I-d?2dBH(W@B%oC3 zBO8RAi&HqMB~|Mu>&Ha(G`btJ1-eLhd%LL-1QY>ZVz$n266}?X8_Oe{EP-vCI>kUc z#K;ANNPlqV`c>Rh+DyS-aiTc+CDy}Cydob{AFf*@{}``})T&nYu?I zIM~u$#0!wojTJ5H2^|YNtLlu$J2ac0K~Y??cvS`INc*&^cnBm9ZdW-77Nj3ZWb}xU zxNwE;;xB_!l-UXPR`7dauyQHqmA4jQN-Js<_t_ zEsChUI%^CPg0qcOqVG&+s?%+Hvd>KeBPm&D&Al}1i zitp2g?mo(xX<&#xmb#yKY!Fq4VJ+|`w(U#>X93TtzM|@PdKy~884%V zYCFXkeQp4)RgN@b<-65#<=>g#xwL6{kUVYIGF>F?IjpR% z6&V`rT+m@BYz+kq&K3NG7ChE3P}+JftOY*b)(p#Nwum+p2t+o6cG`Vxg{%bJ%R=FY z3@O@NGe-*`bk&u=8Lt8lIv>Nf95{%Kqt<8;C^v<6*SO``=^f<`m~%FZd*1$j4;lR+ z*Mj@9v=7F<8h$=TzNy8Ja57~;NCkEQsI}=$&J?|(a1Yb zuMj=<%&Hv3pMlmvKDzPKdIm%|sa?wLYvk42RFWdtOYQ8q`QdP65+N`Wkj|7Fay!;% zZI*Lxf5y=R@4F$#q~{map2(gy_1mrP2eolp_+YwVif%yh>?gB@>5$&=ldx8V%c;yr zd|-|{j)%DcWoU^Al{G(nlsqA!;HcvP%yh<{VDVk*7v+j`ObKvvbw1XN=euq4c9+I2 z<`b6SV=2n}`7E=lXd?Iodmmd;&qDs5p)Mc70=ne82(cHQU|BmrQ>+|{p7YK!N>L)U{5ZX?{s%U8pgi1$!)Cb4>pmaZ0N0Z ztorV~qbm|@XBMK7+Snk?%(W=}DpX`@+8%jhGQ_^IRcD+9C4{7zrO#>zh(W&qHJdre zT$~$7St1T*no^PbX-XtEqFiC>q_W8hCSd$L%<$#SLfvG@m<=!=nxfj}2|8@1YnyjN z5rKb8lm=>p>pSk)lz0FrudP=G+D~H@r9MZ>TNnXBd2+Mji}QA}CGYhGcWj*dX&38R zHkBQ4^M7jwa4bN)hZ>)1rn(1Xu!gsOm4YM<<+uSx8k5W789{6F;F-TtccG~% zZ59VdHlZ(L;47stD2utIU`j%lFGx~vC<#S90{$k9Mq6< zI|&fK>iM1lZtq(WKFUMC7#&J=H}q=-0mS22iLJCeGQlGy?W44bGDP8*Wb&P{TH0Rv zP@kErZwKDCg{e#FiLOCDK&0C=9p*twyV50(v6=m-5tGD~-HSoM%;4}+ZQss+)CEs9 z`xozuB@?^vkkUc4Sys|NvAFY;bFS&P%LxIXX3KMP(Rb0SR&hQI5?|7gVjiXb9+-Wr z+%@T(aC?8)k+s;OWLs>#3BGOiVGdyiIrUZaw;f6S$~`bjrqb&T2*IpZ6xT0u>6`b~ zqX|ML7xyec^5hYj%`zAlJ$W}g3TjrW&tPI*HN428K(KwJhFec0V$SMf0tj^o@@Ptq_UEh#V02S z2+$ZvOCq+yNXr2_XVxIZ#uXRrV|wl$oo>NO{+2P+)w>wL-mJBT81y3nu}Re~6wC+X zE4_)Yh2hLKs@(B{{%ov}xlgbbLE}~0&U)Ol`jxA9IB5IGhVnQb1}?8`>P*`fpf8`B zs?!%$bzY4`)CX6Hj{z^y+z<3 zx{^FdMPQ`O)n&f~qZEkANIRDe;>A#IesAQr-uWC%-i>~Jx4*|30PD%p5vy9w7a%QZ zXw&X+gHFKw{9Y`xp{d${46WTs?3qcriR}zI<|&`=@d`X*(>(y4BwsKEf+q6G4ot`Y zM&AvrHV#~qYABwAXU_jYp?9th?*fOzcuRTGj;p76_TfL1)8y2b&0rxMhFCkItz~{2 z>dpQA9}4??uB&&ic9#rbHsB9x#m-AVorED#J|!jV=D5+_Jc{lbhvYC#nS=DD$i%=A zzBFm(CxQuKXg*0z&HLameDjB?YX@XP@qsp~8XzX_>cu|3rKk^vsIIeIcFZFSH~nPY zDJYf*DPV8+AH0?oGoBIXDtm8I0uwauDAo?vR$L2}v!F-$MfAILq%{jIUmOMag{p7V z{G1AHS2Nv)pKLlN#7+MB5XwOa1*?q{{pd#hf`8;sDZGz<<9l| z*~j;`MKzp3u@s7y_ZN)g0i0>@FIDxVX?1+S7WvLrJs%{@E_`C2`KWB-Kcc9tL69Wy zycK{`@KZT9k0Bc;Bq_ks5W>nzjV=N9RYCtdC5LE5a&=1JW_k^L;yMOWod0rFS@7l^ zQEhMPfUf=gxAjQhk$u>#UX-!-wUvm+Se@3uS>>UB1B3Cr5)s_>nh@#qx18!69Y>cG z+sN(D`RXFlnBb&|YcQ!n_PvdkPsc29M!XD_O*ue~c9sadlpO659j+JCWdT5Eh9Mf> z=dE?mkp7K~h5A}yDG>6IUc>(kLrQJ!4MFCs4eZ`m#Z-i`WLlLUk}1c9W!zlXll|Ru zO^ZiSjSl=3Ncp3W>|~fxZALoa3s#+Zlw9P878zsMlk(H51z;cBR7D!b8EVqWuV8k$ z1+iy^f#1iE?CkG59Vj$Kc3!QBEjlvf;u^P7jSm?xQS0RCnWJWdkbFfA z%t6oiO;-01+vf&Zy)2w$(KMLnaVcT1N}eoWnJ^giPQbKO0o&7eWapPIOHIlfNO-iE zDIqa0IV;L9mLQ*`fyKz5XB7l|v=d3s3QJPSqa&gh>>j9}y53WcLgQ~gY<2qlVZ6qhK1b>SLE`SjFWcQZQRRLy;a_RB%=4HjY1ZD;g-!x3 zwFhthHOd&2&u3z)#X>i<=s#|Eqf&$~mxi7~Ic6WPXBelh=jLHkxdiu)elnvpz|ePx zRV%B$Nr^+6MSDJpo)un6cN4DOH=v!>js0BnD=$yzMRa2(=YXNMwaQ#2-p+H_XI$8D z)a=hKI6s&6+)pg1)DiDPRXXV&l|$E?bP8(yAIjtxmMz9UC^;@68ggfTvmv>%%pOdN z;LCzvvghYrOBJ9@bbN=_0wU0C>>rE#j5mvg)Kl&^#Nus80B(P4f@58PF8Z(2D4qwn z?vGsDM+8*j&Lknq#we{w+mIk(Ub1Sbx}`ZAg|MG;EZn-Lv>jOltxm4>b;L#-_gkDr z{^rZ8riPyaj}r$sLGb+ji8fT zOz*OI7h&k}@T;KJN#1)_%e=ZpKg^i#&c+vqtnY+U#z^ua9$FGS&j9-V6{N*?8Fgc> zTeARtbO*MEOsJ*8Yb>3?;PUaU(>79FgVjcdenZxb{17n%E?uglubVsyJ*P+Noj9{7 zUr7h?;STlI(tE&6MDhigGLA>yw3>4T44ZL4i%E|Qr&|SWx7)fmyNIzCHs1by3Av>si68_ktQfcgJhPUagAk<`3G{zGp}TN zrI!dj-F9p8n0X4c;p!AnFrj9Q#mTSK;{}$DGS-3WuBcL z{ae}UV|8ylO0UbZGC7Hyx(kRR#HmG!wj1mk2E<6D4wL>PoB-;n>c2oxdR^|>G++qY zV_)_B4(32|(+$kTqxt^zl~xb1y@D0!08dXcjm+EBr411B>2JhR!IrzDr=L~BBTs9& zTBgv;BQ(XV#W`t8Pi<^dX7+nsQ`yHs5<jF z+O=7us4d}p#n9|e3?0Gf>Hj-~uQZjJy8<=we=;y1dHSYw9; z)dZCSll-qu*Le~9p8*6UY=|&m?z8-SwD-(4{HX-j;7i*X3b+(G%!N za;J8_7cw0#M+O$qKU$|3xs0vaf=Z0e}CR# zbFd&@+C?1i{qOOaioeQYQ+S&HPU=*<@UH6vR%Zsa-O#V{IIKDRq%P50et1SMpB7HH zdW?cDU?f04nm<*u*8AMN8fM<%N~fu;d>23UZiYdrzZOHMt`d_Q@G821$PSd49#@6+ zR7E_f$CnQr6+GDad%{PcJu+Crlmf^)a-VBq1%2NiLOy7$mTY`>U!1VL#xI%^^WYbB zEnNoxL-l7$_yi%1iK4ip?8MK{`Hv3aN8Z*5bmAjzvI)71^cd#=O#J!VvQyO|9} zwcy^Ei8#1;VYc(Z2Jc!Phe~x)_$>fKYS=P58Rrc+v&iryPDxstYLkko3I_y%p?dOj zOg+>&78Wp}jm9g9U)wx6i1f9XL+_(3?1$4U$a^N1n~dW=w=|?23Vy zCO}>@fRy}HY4!u*G&AI~uB&$<@y&JL4W5Q=_k8|^WThGW4}NKZE4D3pHp!EhBli$&r`KvAOVD6wC4@ zK+U(33Q+aF7wYL_aGM7Nq~)zO5CA1^&pJxKv2p`Qqofxrz)x30Ter~gv$2+ZvF!sr zW5W|wGz#0A&)fiHOsmdaB&DDmokdrZ{-3*h2V5Tj{vOWKG7|>VHFHWXij(nCBZvHg zc%Ur^0C|Ywsaw^Zg_KIR#uA6>-yI}+1J)>4EMdwnuf?s)k=b3`-td?mk;C($LrNUz zk1BtOat|lEYf3bYx4>P~# zN^h-(%gfxJQFDUGepb+X!hD*xo>caET>hMcd3e`|F6{EH2hf${NN@@T(<$p?gn>{Cl8%53yM8Vbpa+>24Z$|{_-~kaEOLQj=f4jV zQA@jnzyBl4{j)#?U$Ahf3nuIhzfg0uLO)MN!6u$r%zM#b<=gO^v4mD{_9>tWD+c8T zq9sp;|6LAh^Zl{T^TP*Tv@sy955?AIc8vp>Ufe-?B)JJlNEB)oCQCavVMq;&L$O!N zCKVV#hG=x&)^jMmbx?$PD1kB(F|4Y`?W5q%COo@z1?Cpg0)8QMj-kdM*8pu|@D3@$ zb69bRh0*W?(300LPBYX5U`jVFX2`V@v=#u{9)PhW_vNmc%H{NBT|A*aXdGhh-J6n%MMA0tW2MYW+lH7CuQAcKN4TgQEp-6R?PnG(&U(0ewZf}!W$`X&kYBfIk z%uIwcxfxD6G()f|qE9r$VNU;czqeu520*wEdqVuka*cPXEItV(pJpBsib|n6nAiOv z6$ud@ZTj=*PL@-6s{!gI+f(d*P@Jf=|AX2AqZuVr=F9%v*Aoyej3JRy{GpK3$wLt1 zA2}uvCP%tU_~KQmrRtKETu4G+!qwJL-YfiF2alDP7S}`57960Kv(93{4)${X3(k=y zMO40Pa-~mM>P>3D=Cs%zMQQ#ls`jkqWR2-aw*7XG3l3zRmnO#9Wggo9XP3>vKwD&GcOs%mPExAEsB+Ha7$O@BDJK&2jG$rk-< zMioe*OX+%Zu)?I~-;XoLnfgj+aNdaIa{d}iXy5LM$E4KBOf<69&y(%En&_0JJz z>i6MKP?ap`>gGAXm9!m~hJ-F$mlrs{b!%``OM7voC$8sZ93b#=jA`KrcR7C+RH=1mm>Lyc%TP;)Qq5?D>uSw@Ipt6Sv&b(nH{1VnOr8RC6S~>VvTf8h zMz77BJDyYQ5I1JkTm;xyQ-&yG9z>fDGMSh#i&LAK!tm8O6*svmGYuVx>tuMD`H^}k zM>eCa8ooNC)E3ySXIJ)gztjItbR6F+DM?)g&h*gOI?dk18jG~gq};%>xk`dU0|zQkhSxa}1S=(iFDCea z<;eu*IE&?I5y zs!OsJ}(^@kHRw0YqJgwXPCo+jTRbgcKG*GwUX0lQW(n&1!V6H$3 zOIP!{`6Sj9RIgO+R;?(vp{ihkPXqx@`5W}6X;b7-hz2=oO3CsguyT?Zw0R)y$}qj3 zSg;hlHex}=WlZhU4*8VXIkzgRH?rJjUwC^Q{OQau#*+QXL|Zo!(IHcClQ*`}{Vnyr zQYJgUO#cTPiT52;DzwDT!AVr|Fd&2z9_lzKR~|JP_koJ8yA{wry>xPc{i{MTz4PPL zAS^gw{1+vv9NI1&B+R)}(IRZ`5=Kt?LzOnPx#}{g&R>U;0Id$lo$7;D)>E|gDsAn} ztu=Q0JmKdC{$F3g#D0?V&eWJM`J^7gK98VVV>3LaVK!jIh!7Er+JnO!TZJ;f_1V7r zV6_hG_Tc+~b^m`i*r`V-Y(-uS(mE(tZ3#=8>lT#M*+;&d>)&Hf#~(AM6UZ(y_Ra%{ zNrW`*ht?(AO)u+B(vfIcJJ(PQ3C|Q1KU|1B_kW9v8`%)aBAVuT*f@>h&wsoD`% z%a?vW2gw}~C@nn3J&y#L>WPis zB$#*>*iMVnJa9{dy$q?ZFYZzSX$RP>@TO*^rLDOtZ-cO@nTO(c-hfXp^9ES1g(bL9 zYfJ80G&)VnyZ17I_a)uTe9(c=!fKkm;26)6EBiPZ`3&;&fK6lm3Hjs0@5Io8FM;PT zu&$DV3Q-_38jHE&@dPj6QuxVfw?q%t4jw=I_vRq%aym@){TjxgR%6pCI(w41h6ZT? zf)|@Kg#o0{rC_znuMZ=Dr!eMzb(4=ECwS(kZ#ZB(fTZt{Fv`SGqk-CKw)lGH=vXh> z%#zhQ?Yhes{?mGYV-&{^%Qgzd=dk=Awo&KlC+@*%otn@9rA&~fg)v3_O}V&iELvH@MwNdZm<9f{$lR~~ z$u1%JMhL|p>h)}xxEmr(g2MhIRd&Z+OxF)Pq2;s-F?G<*%F1wDI;H}b2xngT&V`n} z+~&g|vC|iu6b71yEQ$9UD@8iX5sN4rg7Cr^7|V`NjD4tD*UL#b?k&o*=LE9TyZ7-} zO&fuAc`i>`M?*CwhqWM}duDk`K(G@w6z21O*a%TJ}Paz_5V;?dwY_H@HdU8BHB+RD-G zCjrt`x@yCwC`9ac#5KMYCSJ0l zw_>DIb1JRPkm|GQ^MnIk<;wja=tf_~Dt0<5$;XOPZrQ4)9-M!*vE)3yMYd;7O4{p5J1I-om2*VdY7}g-nY7 zL&vhARgeBH)}7gWC+U*bZ)H-|Z-oh5kEXNzRW{9HrbrpQW!l+R)RziJyAK19xw)8x zMXydR1QaD^H%6WL_YEsV(p`8Rjp_G@0Z!#!cDxvDSg|=-klq#VY)xgPWL1Pxj`^7_ z7iw0l7$wb75$ftdYS}{ygpEb`?c1jfpxbeN@M|{>EzBaMrw#=3E4#^SUDC=I1$>aZ za2sR>F!va`gVIUE_|0@Z@F3oBa%QCmz*3CuN{M&WMQYor1Odd^`dd#*AWLVM+j5ho ztMhB_wzLkiNug5Hk_(p;z+MwD0s0)XJRdwLQP^`}wdt=t_BX=H27pqk8?+9rShcTm z5K%KE8E0Jnd7U}lhu&|)nBRb|5yX|MV`8$>vTNSl zRx4}_y(Z`b!pVw|dOwzXO3(Nxfa|5Y>YK&BZ*}9olQXeBXlB2M=}>-lp#-5vfmDiN ziaxN);N<>Z^&WE#oj(s2Fwn=}K3|nZf1`kUk<`-pyFk{pPiNq=p*P*h#1qyp1X&j~ zTJOygEvgobY4^FXgZES_%u^wLj+Re#1;Ll@-C%Ht`o$FM_&$KLe!yhk)E#w`g=^iE1c9glt{9mruCY&AES zDF9BEiOv9f_BHmTWp1*Y9{X_`q0`-dWogQw_-5f6$7l*N&fyf?!DL$7;w=PKbEza=nI22{lYL0$zAcRZ zePmFvhRDZ&cP;!`@}N=EP8E%$Vz^lk?Df0OvRl=IMOV2 zNCcn5#rtfVb&*+Ben*P3JC}tgoNdG4({An&UG%q?Sr3QVY(XtF$e4^BwY*2hA4G|w(SqY9 zGFNZ;kPCEmXj>;{tMrs*PL_^QRqaAj3Q%%dPwm&aF&cfKLw)!8gQ7cUKO5a3m)cHB ztt>>9`I&H;QfZLSRK%-fP_+buKfV7Zql#7DEcs@>t)H*;b6?QlKWAUX7|vwxJSk0h zXbLG0pjfvieA}6sk5j{LZvJI~>CLOM_n{O!FIjK%6IM!UT(>gM+PPh<;uIlp_Lz}D z-tOx>5@094N|9(f&rFulcPXn(5_B$LbD5^3A|jEG&v?X?U&}I*9OvuYKHev$?Gt-A z9gu6l(YA3|p-9WT>PzUhK~LHw@R{0(0nZ6gullV~11OHL1Qh}kH-blZiY^`WsD1h8 zm%f-8^=9s8#{_n3k!8`$lyeL6Z{oj1XkW|reqe~abQcX%kg9X+tbNih2bbPiIZCLO zSzl&?-t-M9d?MU2=tOCL#mU(EZ0DVt>3$%$vF6rICb|&o|f!~b5+4i&x?U1d%J(F)l2TU>-y(?odM=qm%(C58>3X!wX;@RP1{p9 z%eWgZOl6^Knd<*$))wZN6)q4X-75|_na<}BRc4-ovddGzR;byL*RSdiB4irm3LT^{ ze-ogZaP$*`T0`icf&hO}f%Spqhy}sY2V&5i^6}Bx-u}%zrBfne==cSIgI5xo6B_lO zG_}BrWx}ds;4opQv4G1@KCic=+^XWE$R(4i6k47%y}-_Tri3Q!&h0$JGoxme^c9IG z{}LQ*Cg2+Yv|m?gBc)V*E#4p?yra`SWBsYrCn*6L<3)Ia$09V_bbcDq`XzSiW=0aT z%lhp`NBlzDYwo&vl%1ztg$&=M5sm>;_HM*pFQkLFPVUcIS`T7j(;LQ@^M?$j1i zGHB4XgYo<~qU+E<%?3Y}PsPQ#%(EH)Wr_ z$56hZ(bD?)m^LQ8J-D-eUR=>PFsFnxyF;yss}Mk`J!vX=9p13aeDNX`mhB=wGYq6M zsiqRH#7@(@ksn+@+rFJhS+{j)yY+HsZo<3uid;YbxF zL^0rL2+K`PlL)NI<22b2o85)K({);p#W#6gZL80?`<)ZRmSWte#!tA+&aeg1-M{ge zEgfHrrD^WI#@&A9-P?Wh?juhG1xhT1D3JLZ5FPM0Tnk5xxYy*$pWTuGE34*qlT_kK zrvC#^3Eg>uO|4(;YOt0~^8q4YgDrgP$Y-CmT}jO{Dz+QYwTp>{oykFyPa&k88o*e6 z?>;nHg9$BE$i%9TOJK8$QrJCnA$y>JaouQx|h6|7lwzvBrI=nWugkuj0bhvzoGDs!AJMO zd$s%-M}r=C9DTR_dSNglP{Yi>8{CMdB0d!`pktwJjKRc4wW0lxH4blan3A+7dq}jS zQpY8Blqjzevsq5UOK#OMWb&B<#~bioACXqAMPR>KQ+9EGX+cpT#di`)h;X08(A_#F z+t=x}_mX?6rsGVjDu~&PKZsVCqv7ThZw~8Oq!42;_0KooG4`cHB83BqB zE%Xss{-oslH_?HvBvg??^?djS$egnK1m^0w9K=1t7`h;hu`XC}3R2DRVEP$A9fMUS zo4#u!9FnQp=oV6|D6UgGUTzCC9cI(!iV@}g4I{hr1!H!`~czyAK}Q}vqj47)n046b!CdBz0gh#zNg0MW9H^8X`CpppNO;{;@ ziRt?UzReex4zgPNl=F^E%64i+2xF6E+`|OVdyQ$=mZVYC^u49$%I1}&Z4M9pktcYk zuR|;#ub@B4$Z)rX-X}W_a5aK$Bf*ty%0;F&>v}s>3ELHehkS085u~qEprq#;*P9Ab z8SCJw?!ie2$UZrKpA^-;wf1jctqgHzNJL?*%?DCwVOU%G{m5JwP9ukaM4^ghH$j~J z!g^qnMQ>++TN?H~&{zgVcJRWMu+_jZvYu2@mLy^|RsfP;N5XoxMt`D+-=K23N3R!8 zC+Q0!gHQoxp+whz!G!YzuIi-h`v;b`S52Xm$uckZgWnt^n9FqgLOfe52WH$qrsv^! z0rKQ!=&|r#M9`EQ;Q_Lpo$wKVfWC>;iLQUZtI6yk_6tnM;Dcqw;@6!$bGo+U6}133i@+WO#=K>DBwu>!l!EN}2QKUuO0( zt@J(6B+sBpAQ0J(AE(z626!EBmbj06+M4oDX4FA+&=gHO!63dv6Llg0?9zBgU-vdp zy3Ef3R(a?jXGYR8n@gH~)H z&BET5FhD6x99QGnZ^vVe1{d6v1h|p@+JPAE<0(~_pyMN7!{p@fS&E@okw%=1_FEz{ zDrKORS?|E9^@hX;o z?XBy74#lCt9#TqC_xdbOK+dK1r+6_gg6bzGn-8q&CDqB6X+JXO&QDRrR8fzh!$fSw zbYXr(;>6P~Lli!znm?o*0Q*2xa^V_8@v@_{mTH;gb*){O>y!Wu+9nm)t)5JOlPi(y zi!u+}J+N-_2It;Vq$v@MX2``3GHM_^HFNxJf3W#2pJ{(8UAbZ6vNzV3lHPw!8U{f& zs>%Y`opt)biDCK{Ot`K467nJdB}sa5aXc9NY0qyf43|QFH(f9B+S;1B3;GBqp{R7T zZ(^r^QyPZ!qn#QSESamgDH9-c!jZxCDjhk+IiIK$ys!;)Lkc#Prn zs1fnA!Bkxhvpqbv zsabMCb`!%azv;V3@rJgm4mGk^i9@9pBQRVEpU0G*Fe(+z&?&rVB+SnH&tl6jIb#%_ zc0B;HR=MHMELQa+!`{uq5e&6QrX=5_Q43>%G@@<%BPeS|Qsf8x-Q03wwwbHM=XgRI zW^Uw39?%IZzPdW43PdYbB`!!w`{ue==HT8^P+?mro_pcb^!6=_ABSy=gZ zc{zE_x+28$46?omfqOmctk6T#Wx+a4V3GZCrVkSFgLEpVSd9)O)VB-Ds+-ZX?a@`G z(LrgzRd9t^gB{K0%b2iPnpZ3il2(*wI^WmPr4FW%LT4bk@X^5Z*fG%)q2hm@zPfEt zPv_#_B`gMH__Ni+)?6zuu$xYN7P5DD>sZBxa8I~|FSR&kiAV^goI+VGV0%>kelM&v zMz3Kvm$ZUW)#z55);oXXlpTN={8= zgPP?E5eHhlPY}B~iONR<&*sJ(l29Ix0AMO!Elp&KLTP3H7xJ>v(2YQ{hJY2iGLG+% z)>r{X7}d#FkD^dcDS90V;}d|Jq_1Kf(+$6AzWDb3`x`D~nq3&io?t7svYnx3Z3@S6?V5gjRh4WZ zD*}%}2Ho*0LwGU(++Tjh9@BL^M87&@A{iwI;EoILAkvMFlRz>D+pT0>!5lwcsBAAQ z{II!27$agGS{;`}i1{-7bHI&L@T!50* zP6b%!$C2m#=WvFAFh|D?`0M>8U31!)Yx+YX2(r}=REBnFDA@CBbgPt!U#aHCHwH@e z-|>o^0rS56+n0m0I8g1Mc%=E>cAlZ@WXaGDW@6c7E#Omy$!HK_Pt$y!K3VC#fpk!K zY72NS-EjC#(I|gFiM9w3cB@JhG|ZVY&-@i%MWcFKyb(`t?=t1=-lYAG#>zEsnYjiUVo}o)(|vH&0egeha|RkgD;`X`!x09^9EjLFy9Z8| zA&P9ZX{;>7jS1I;V8T~sR$?QNML7Q{J0_HCzt=+bJ4^w3#E$KA35>3IHrbbugWeeq zZqTNViJ9tmd{1=9%Xn|`(4frRKka|rS8!Wv`195THfA0oZ#;W+{}c*OOzWn+Fr@VE z=)Qs}XB}fg4&mCNKsuGrdSe#ro5<%4nw07Ye17GK@y+u}^``P>g9I@J4-;cNVT4eL zbDawW(P+f*?M*;Pw-Fyr1MXhf;t+VHHvWqEPf}q0f$kUU8vJ=qA^-}8*`?my0Bax6 zn4fH63+JypBXmEeAP`SDL3aw~;ANCHb6M|?f+AL(te^>Jf~<(=9OIf;Z?~8qNAq@bUt~8!T}bBY1~@=!_yTZ>lz|>}M*{NnoVK$P zpmyrZ7wK^AbgkDIAw6~NvLdB=+%1s2g-v7Sk7C>uu?Y?g%U# z-T5{M0sevZbt#c0*oV?_@;QI&YjPX1Qcp_dC7A*GB8Xv>m2lz6+1Aa3&6S(ZLA)6{)pRO~1SkHaZhUo2M^$ zU2OtB7pDk(+0a!*m}b29RLJuQ0Yv2Ktmrib&hUV<+7ct?4A3QBVFU(z@mSi_qterL z0go=-wm}BqWwIM(HoErWe=x`X;bJb?y-8BKQ*Z9!>&G3tiyOT!Q0Mx$_HlTTLB1L7 z&gn#c{LFZ15%DZgO+m)IHQw(0lMv4IW=og5YVuO31Jw*p!2G94(Z@b-?0u=QL;Mw$ zc=)Bq+x9GDaohkJpWc-P0cOx;X#G1ex)}0j(mFh@EZXRMA9lv?pgnZIT{qM^03PCG zw8#-04IB|W)^pV(J6fU2&BoTK=Nw{HT_ewSF@BV7VEx4nylO+R)xmp}nXi)4zJFYW zRSJ-VE?NxA1p&YbWV4=1)~M{U4CQ$u8*oSAAjFZSW{!rUw6v&nctZ0SYSmQ; z4<;AF(uqv)`WTBT?-SDn@>zo_-4~p0@oj!+plnpRZI|t01+MYIoj=MD6iJ7>@qJ)` z3P8$y#_W}~8~F%#=Z3(na>^dg9#QE6suUpG^s*#L{3$IhrV#J-D_iVdXEQ8yeJj0| zCzKJ9T1wutTpKgJ4~rVQQyn>+a=m21NggNcv~EZtKR}}a+~$+Gm4A1+wVOSZ1mgiU z?V-A>0aL{A#1E{cYe;+GDH5cWvI0*o~ErfdvL^k^fu(dusnJjqX=lVQrDz` z4r_JPIR3^oMf_q`yVvw2&F!g#g#&f?lDRXKfK0djCeXua}d&V*vS z7*wavVSTbrU?1$&+?MeGDjILnUlKmym~L;#c`C~Re<_&$Dk!LBpgpzC&Cd{=jV?Aqx7Ut2_!ys&s~)#+w@OhU;{o5G}Z6l9(Y`M~fd zM$O~RJeE{OkF_FoqLS%+G%aArI4;=mKUL3_PH&~}c&GUzr74T*Q_N_17QPx(70CeR zZP#P8Rj+O+pd-`5rIb#-Rk82>5jp7?3;l^=nF(9v$XHtL7;MB!S`$tIEE2tj;GPR% z-JTyAQgbtTc1FrJ=9L(|J4y`gOV4T6#&Ve!Ce^UX!(+9%+D@~p2Q>c*UO5>Tp5jpw z_jOa6#nnJ5x)2aTsfowL%XF}c%IiqpHY}}6--`MF3O=y0^kUE1KFk5?0u}wQxIo{O zSrEa}fsqDZH3`+vjXIR95T6IPPMFb^iU7FHr2Oh$6{InWFvIB)YN{#os**n9PZW6o6sb^R}^b+mBbH$(81z6^`Gk<94$?! zWpXYy5e{;Pn38?MI&H_0*v)0R(0u%)D_tbLDzJ>fwVuV^tON*k`=CH*U^2sr$Wuy8 zK_)bKPSN=sh%%`}uU2)$J(>Y!ZQr`F(rnoQ~ay_wBMVI2^2Qz8&7ky@&SVJuGC!a%pAlWwUl5nN``US*J%a;q>yP z*Y)(P#2E=SyK3|JHygmyOPmLH(s*V-y_q_J$MXs|Y+tbgZ~`m$2`6ipf<(CzJU(co zJU`(5J2vt{7aCDkY>2WCVG5x;2N*|iH=VMCGeMspnVr00CPp+2DQ?g&CDAH>tn<}z zi`bGHC$>hgk>+5r;2LHT6u z4QvC!IKfE%wRw5{w`Ad7CMCAzp0R`sRKuLNx%ucC% zE0e@nPv$z%Tvs2+0xHA0h?EXsR_ajFiI29qq^ce*p;0|9hMO8AAYclrqjl4+L+F?k zBR@6Qf{f%K{Tef$qMs&e(*G|C>)SF84w8>;#qGD(9JwwC&3TQ()Jl_alw?y)a%JZE zeczp9$fq)0S5lWhC$XlI_bj+cE7#DF>>9cFo=R>mu#ILC{2>`{33ETI4@4Ot%7jI= Qv=qPE&lP-!Dt31N*$T{VB>(^b literal 0 HcmV?d00001 diff --git a/pkg/codec/testdata/a1_mono.ppm b/pkg/codec/testdata/a1_mono.ppm new file mode 100644 index 00000000..6010cea0 --- /dev/null +++ b/pkg/codec/testdata/a1_mono.ppm @@ -0,0 +1,5 @@ +P5 +# Copyright (c) 2000-2003 Pegasus Digital Imaging +303 179 +255 +¹ºµ³®¨£¤¢¨£¦¨¨¨ª°«®©§«¨¨ªª¨²¬¯³±¶±²¶¶¸º´¹¯µ³¶Æ¿Á¼³À¾¶²¾¼¶½º¯µ±´µ²¼¶¸½¶¶¶µµ·¼¼ÈËÉÑØÔÖÖÔÔÖ×ÖÙÓ×ÓÓÕÑÖÓÑÒÑÒÑÑÓÓÎÍÏÍËÒÌÓÎÍÏÍÐÍÐÐÑÐÍÍÌÎÐÐÉÐÏÍÎÌÎÐÍÎÎÎÍÉÊÏÎÌËËÐÎÐÐÏÑÐÑÏÎÑÍÑÓÌÏËÌÉÊÌÉÈÊËÌÌÌËÌÍÉËÉÈÎÊÌÍËÇÈÈÉÇÊÍÆÇÇÉÈÇÇÆÅÌÅÉÉÂÈÅÆÇÆÄÄÄÇÇÆÈÅÇÆÄÇÆÅÅÄÃÄÇÅÇÃÆÆÄÉÅÇÅÆÅÅÂÅÄÃÃÂÃÉÆûÂÂÂÅÅÃÇÅÃÆÂÅÇÇÄÅÆÃÃľ¼¼¾¾¾À½À¿¾½¿¼½ººº´º¹·¸¼¸·«««££©¤ ¤£¨¬©§­¨©¬¨§¤¦§¦¬¨­®«©ª¬©®«©­®®­²³¬­¬­²®¯´®²®¬±°®¯©°³´³±´¯´°±±°´´¹¹¿ÑÕÒÖØ×Ø×ÖÓÔÔ×ÕÓÔØ×ÕÓØÕÔ×ÖÔÑÏÐÍÈÐÎÏÎÍÎÎÍÌÏÍÍÐÍÑÑÎÓÒÑÓÐÑÐÐÐÐÑÍÊËÏÍÏÍÍÐÊÑÑÏÏÐÌÐÏÍËÎÐÏÎÏÑÏÎÎÏÎÎÊÍËÌÏÊÎÎËÍÈÏËÌËÍÍÎÍÌÌËÍÏÎÍÌËËÎËÊÈÇÍÌËÉËÈÅÁ¾À¿¿ÃÀÀÀÂÄÄ¿ÃÀ½¾½¿ÂÀÀ¾ÁÀ¿¿½¿¾½¹»»½»»´¾³¸»½À³µ¶¶¾¸¾¼¾¿ÀÃÀ½¿½Á¼¼¹¹µ¶µ¶¶¹µ¸¸·¸¸º²²µ²µ³²²·­³º³µ§¯§¡¡¡¢£¢ ¢¤¡£¦©¨©¢¨¤¤¦££¨¢¨ª§¨©¨¥¬©¨«ª®­«­«ª¥¨«­­®®¬°¯®¯¯±¯°±±±­¯®²°°³²±¯®²­ºÉÐÒÔÔÕÕÑÔÑÒÓÔÒÔÔÔÒÖÖÕØÑÕÖÔ×ÒÓÒÏÏÍÏÑ×ÎÎÍËÇÌÏÏÐÔÑÔÒÓÔÒÓÓÒÐÐÔÓÎÒÍÐÐÎÑÊÐËÏÎÊÍÍÏÑÎÎÍÑÎÍÐËÍÐÎÍÍÌËÌÌÊÊÌÌÐÍÎÎËÏÌÎÐÓÏÐÐÊÎËÌÊÉÉÉÇÊÈÅÇÀÀ¿ºÁ¼À¼¸¸µ²¹µ¸´¶¸µ¹¸º··¶¹¸»»¹¼»·¸º¸¸¹º¸µ·³º¸¶´²µ²·¯¹²³³³´¹¸³µµ¹·¸µ¹µµ¹¶¶º·³¶·¹¸»º¼º´¹·¯¯±°­³¯°±³®²´³«§©§¤¡§¡¢£Ÿ¡¡£¤¨£¡¢£¢¥¥¤§§¥«£§¦¤¤¥©ª¤¦¦ª¦§ª¨¨¦¥§«ª¯«¯®­®©ª®ª¯¬°®¬®¬®­¯°°¯°¯­±´·¿ÂÁÅÉÎÉÄÂÃÊÊËÅËÒÌÎÖÑÎÍÇÏÑÒÔÐÒÈÈÈÊÓÔÍÐÌÅÇÅÇÊÆÌÓÍÑÕÒÕÓÔÎÏÓÎÒÎÒÍÑÏÏÐÎÐÉÎÌÊÉÌÏÌÊÊËËÌÉÌÇÈÌËËÇÇËÈÈÅËËÌÍÈËÍÎËÎÎÐØËÉÄ¿ÅÁþ¿½½»¾ºº¹ºº¸º¶·º¹ºµ»±¶¸µ´·¶³¸¶·´¸¸¶¹¼·º¸¸´¶»µ··¸¸²¶µ´µ²²³³°²°²±³³´²´²°µ¶¶µ³´´·¸¸µ¸¹´¹·µ»¸¸¹º¸·³¯¬°¯­²²¯³°´±³º¶³´®­°«¯ª¬¨§§¦«ªª«ªª©ª®¬®¯­°­­°­«¨¦¨¥¥¤§££¥§ §¥¢¢¤§ª§§©¦¬¥¨¨¨¦¦ª­¬¬«©°¬­²®®«°±«±­±°³´¼½¸¾¹¼¸¹½ÃÇÈÄÅÊÉÉÆÇÉÌÍÊÌÊÇÆÆÉÌÇÇÇÈÇÆÂÅƾÈÂÆÎËÍÎÍÍÎÊÏÊËËÎÌÌÉÌËÊÊÊÊÈÊÈÇÉÊÅÅÃÇÇÆÁÉÅËÊÌÉÊÎÌÑÎÊÐÏÌÎÍËÍÏÍÎÌÌÆ»¾¶»ººº¸»º»¼µ»»¹¿½º½¸»¹»¸º¹º¹·º¶´µ´¶·´¶µ°µµµ¶°°³³¶µ³´³³²²²³´¯±´²°³«±²®³²µ´³ºµ¹¸¸½¶¸¸µ¹±·¸´¸´¸¶µ·¶¶²°®®®¯¯±³¯°´°®°³¹º»´´³³´³³±¯±³±«´³´·´³¸¶´¶µ´²´¶´´³®©¨ª«¯¯«¯­ª©§¥¨¦©¢©£¦§¥©¦¨¬¨§«¨­§©©©«¬¬­©ª®¬¯­®¬®±±°²²¯²µ´¸±°ºÁ½¹±º¿µ¾ÁÆÅÅÆÃÇÅÂÇÆÄÃÂÄÁÃĽÆÁÃÆÃÅÁÅÅËÇÇÌÍÊÊËÈÈÈÊÈÈÉÇÊÉÈÉÇÈÈÈËÈÉÅÅÆÆÃÅÉËÌÉÊÍÌÏÎÑÏÒÏËÈÀÃÇÅƾÁ¾¿¿»¼½¼ºº¼½»»¹»¸½º»¹½¹¶ºµ´µ·¹´³²±´±±´³³®²³®´³´³´¬¯´²²¯²²°µ¯¯²­¯¯±°´¶¶±´·µ¹µ¹¶¶¹¶º´·µ³´³®µ´³³´´µµ³±²­²¯ª®­¯¯­±°­°±±¬»¶½»¸¶µµµ¶µ³¸´³µ´´²·²·¶·¹¶¼¸¶¶¹±·º³¶³´µ³·³·¸µ·´´´³¯±°²¯­«¬ªª«¦¨ª§ª¬©©©¦©¨««ª°®®¯ªª¨««««¬«±²±²°³°²¬°²·´±µ´¶»¹¸¾º·¹ÂÇÆÈÊËÊÈÈÉÇÆÃÈÅÁ½¿ÄÂÊÇÉÊÌÉÈÊÈÈÉÊÊÉÌÊÊÇÇÃÂÆÅÊÈÅÇÄÄÅÃÅÆÅÇÅÆÅÄÆÂÈËÉÆÃÂÀ¿ÀÁ¾¼½¿À¿¾º½·»»¸¹»¹µµ¶´¸´±¶²²±®²´´³¶³±³¯²³§³¶·¶¸·²··±¯´®±µ®³¨­´«°°°³®²³°··¸·¸¸¸¸¶¶¶´´´´´±µ³²²³©±´°±±®¯µ¯°°®¯³°¬­­¯¬®¬¬¯­°ª´¶·º¹··µ±¶³³³®²´°´µ±µ¶ºµµ¹·»·¸¸µ¸¶´·¶µ¸·¹º¼¹·¸·¸·¸º±¹»¹¶¸·¹µ³²²´¯°°¤§©¥§£§©©¬­°®¬²°¬«©¨¬§­®­¬®±®°¯¯®±±®²°³´±´¸´´·ºÆÃÉÇÇÇÄÍËÉÎÉÉÅÆÃÇÁÅÆÃÈÇÄÄ¿ÂŹÃÆÅÅÂÈÅÃÅÄÄÆÅÃÁ¿¿ÀÀÁÂÁÄ»ºÃÁ½½¾Ã½Åÿ¿ÂÀ»¼¼·º»»½·»¹¹¸¯¹¶¶¶·¶´´´°²¬°±³³³²²°±­°°¯²®®·¶¸´­´²°´±¯°¯¯®¯±¬°±±²±µ²¸·¶º·¸¸´²·¶·µ¹´³­¯²±®¯¯°®®¬¯¯°­®°±¯®­®®¬²®ª©¨¬ª¬­««ª­¬³±²²¸·¼³­®«­§¦¬®²²´±±²µ¶·¶¹¸¹·¸¸¶¸¸¯¸¸ººº½¸·»·¸»¹¼¾·º¼»¹º¼¹¸ºµ·¹¸º·µ²µ±°¬¨«¬®°¯´¶¶¸¸¶·²¯±®±²±±«©­®¬­««­ª²¯°­®³²²´±¼¼ÂÇÊÊÌËÍÌÈÌÃÈÄÄÉÈËÉËÈÆļ½½¾Á¶¶¿À¿ÃÁÿ¾ÆÂÂÁÀþ¿Á¼¾¿À¼¸·¾½¼ÀÁÀÀ¾¼¼À¼¸»¸µµ¹·¸¹²¸µº¶¸¹´¹³´µ±²±±³²°µ¯³´®±®­­¯¯°±¨´´¯²°­²¬°®¯°²²°³°²´µµ¸¶·¶¸·µ¶³´µµ¶³¶³³°²°¬«­®­¬¬ª«¬«­­¯®­¯°¬¬©¬ª«°¯¬¬ª«¯­¯¨°®¬®¯­°²³´°­ ˜œœŸ ¢®««©©©¤«©¯³±µ··®¹¶·´··¹·¸¹·¶¸»·¹¼¶¹¹ºººº»¸¼»ºº¼»½¼¹º»»¹¸¸·»¹¶¶¹·¸¹¸³¹¸»¿¹»º¹½·¶¶³¬°§«©¦¨§¬¬¬©¬«®²¬°¯±²ÁÅÄÆÆÅËÉÇÇÒÑÎÎÏÎÊÉÈÁ¿¼¼Âº¿À½ÀÁÄÂÅý¿½ÁÁ¾ÃÀÂÀ¶º½¼¶ºº¼ºº»²½´µº¹··¸¸µ¶»µ¹¶¹¸´¸·¶·¸³²±²´²³³®¶±³¸µ´¬­­«²¯¬­­¯°±±±°­²±¯±´´µ¸·¸·²³°´µ¸´¶¶²´²·¶¶³³´­µ°®°­­ª®¬¬¯©¬«­¬ª§¬«¬¯§«­ª¬®¯­­©¬ª«¬¨ª©±«««««¬³µ«ª¤ž™”›•›œœ¤£¥¡¥¢¤¤£¤§¬°´·¯µ²´·¸²¶»¶··¸·¹¶²¸´¸¶¸º¸´º¹¹»º»³»¶°¸¹¹º¶»¸º½º¼¹¹¸º¸¼½½»¿¾¿¾º½º¼¼½½¹·´³¯ª««¬¯­­ªª«¯«­®«­¶µ±µ°¶½½»ÄÏÏÒ×ØÖÒÑÑÍËËÆÊÊÆÇÂÁ½ÂÂÅļ¿¾¾¹½º³·»ºµ¶´¶²³µ°µ²±³µ°³·¸¶·µ¶µµ´±´¹µ¶¶¶´±´´²°­®«°°³´²±±¯®«®®«®®ª­³°²°±¸³¶¸¶µ·µµ¶µ±²®µ²µ´³·°²²³µ®°°±°¯±±®¯°­°ª©®¬ª­­«¬¬«ª¬¯ª©®ª«ª¯ª¬¨¨«©¬¨«©­¨©§©¥ª©¯«¨£œ™™ž˜•ššœ¤¢ ¥£¡¤¥¦¤§ª¬©®¬©±«´«°¹­²µ³¯³²¯²¹²¶¶´··¶²¶µ´¹µ¹¹°·¼»¸º¸¸»¸¼º¸·¸º·À¼¼¼¼À»¾½¾»»¿¼½¾¼»½¼¸¹·³³³²®°««©§¬®°¯®²­«¬°±­­¶³»ÃÊÏÌÔÔÒÎÐÏÏÌÎÍÅžÄĺ½½¸¹ºº·µ¹´²¹¬µ³·µ¯°²´³³­²°¯°³°®¯²²¯²²°¬²¨¯¯±³°³´°µ±²­®ªª®­¯¬¯­«¦ª¨§®©ª´¯¦­²±´´¯³´±·°µ´´¶¯µ´´¶³µ¸¶±²±°±³±°±±±®±±°°³±®ªª©­¬¬ª­¬«¬©ª­©©«¨¬©¥¯¯©±¬«±«¯¯°¯­«© Ÿ¨§­ª§¡›™™š–™—˜¤¥¥°¥Ÿ¥¡£¢¤¦¨¨­ª¦¦§©©¨ª«ªª§ª®¨¦§«¨ªªª¬­¬¨«ª±µ³¼¹¸º­´·¸¶¾¼¶¸»¸»¸¸¹¼·»¾»¼º½·¼º»¾¾¿¹¿»¿º¾½À¾½¹µ·¶¶³°°§­®¬«ª®¦¢ §š›ššŸ¡¬µ´ÆÉÀÀǹ¾º½¹´º¹·®°¯­±±´²²±°³²±³´²¯²®´±²±«­®¯°®¬«ª­®¬¯«¬ª«¬«°°¬¯¯«²¬¯®¨­¦¬ª«­§©¥¥£¥§¨ª¢ª¯§¥¥§¦¯®¥©ª¯­­®®±®³«­²«´µ´·³°²®±®²²®±°­±¯°³¯¯¯¬¬¨®©¬«©ª©««©¬©¬©¯°®³±°±µ®µ±µ³±¹±²³®ˆ¢¢¢¥§¥Ÿ—šš—›––™£ ¥ŸžŸ¢ž¢ŸŸ§¥££¢¡¢£¡¡¢ž¡¦¤Ÿ¡¡  ¡œžž¢ Ÿ£¢¥®¬¯¦–—©±·µ£œ¥¶¯·³»¸¹º»¼½º¸¿º½»¸¹µ²¯¹¹¼¹º¼½¿½¼º¸¹¼¹¶¸¯³´­®©¦—’’”•ˆ”’–Ÿ¦«²ªž¡«¨ª§¢ª¨¨ª­¬®©«ª­®®¬¯®²°«­­°®®¬­¯¯¬°¬¯ªª°«®«¬¬®¬¬°¥§¨ £®®¤ª§§¦¦¬¨¢¬¦©¨¥¨¨¨¬¨§ª±§¤¦¨­§¡¤¤§¤§©¥¦¦£¤ž £¢¦¢¡¡¦¨­®°¯®¬¨¤¨«®¬°±°²°¯·³±±±®°¯¯°¯¯±´±°´µ±²¶´¶³¶·´¶´´²´·³¶´³´´³£¡¤£§£¢£Ÿ  ¡¢ ¡ ¦¦¢£¥¥¦¢Ÿ¥£Ÿ¡ £¡Ÿ¤ž¡žœ¢šš ››£–š˜œž–œš›Ÿ“–ž›š…‰“¢¥¢Š†–™›¨²´¶¸¹´¹¶¸¹¸»³®³«¦¦¦ª®±®¶¶½¸¶¸²³¯®±¯µ³³´¤§œ˜–”‘Ž‹‘—•—›¡˜™—™™˜’™šœ™§¦¨£™¡ª«©¬¦¨«©¦«¬©§¦œš¬¯©§©¤¥¦¦ª¨©©ª­©£ ‚®¥ Ÿ§§£¤©§Ÿ£¨£¥¦¦¨§§¤¥¤¨ ž «ª¤£¦«§¡¢¨¤¥¡¢¢ž¢¥£ž œžŸ¢¤¡¦£ž¢ £¡¬¬¬³­²°´¹³¸º´···¸¶´µ·¸¹·¼··¹²¹¶¸¶¶¶¹¸¶¸¸¶··¹»¶¸–¥¥¡¡Ÿ¥¤¡¢¢¤¡ ŸŸ£¢¥Ÿ¢¨§¦©¢žŸ Ÿ›ŸœŸœ¡£ ž£žœ™‘“›ž—˜œ••••”‹‰“—“Œˆ‹Ž–‚†ˆž£¢¥¯©¦¥¬²®«¯§¦¤¡¡¤¥£ž£¤¥¨­­¨¥¤¡§£¤Ÿ¢¢£™ž‘“’’Ž‘‘““Ž““’•’™•–———”šœ§™™—££¡¡–˜Ÿ¡™«¦¢š™›–§©¨¤¢œ˜¡›œ¡¡¢«¢§©›¥“{ª¨¡§¡Ÿ£ž£¦Ÿ£§  ¤¤¦Ÿ› Ÿ ™š¤£ ¢£  žŸŸŸœŸ¥ŸœœššŸŸœ¢™œž™›žž  ¥ ¡¢¥§¯²¹³¶·µ¸··¶·µ¶¸µ¹·¶ºµµ¹³·»µ¹¶·¹····¸¸¹µ £Ÿœ”¢–™—Ž‡Ž™¤¢š¤¡¦¤¢œŸž›™œ ›Ÿ¡œŸ ž˜”‹Ž˜›˜˜™’“‹Š‹‰‹ŽŒ€ƒŠš‰{€…‰˜œ™”‹ˆ‰Šš’”™™š•‘››”šž›œš–œ¤›™œ—”‘Ž“”’“‹ŽŒ‘‘’’‹‘ŽŽ‘ˆ’’““”œœ–“‘–—“’’”–š•’’œ§¢ ’‹Ž’‹‹““™¦¡¦‰ˆ¤œ £¤Ÿ ¤¢¥«§¨§§ Ÿž™›¡ œš›Ÿ¦««¬¢ ««©ª¥ Ÿ››Ÿžžœ››œ™˜œ›Ÿœ”™•™š—ž›¤¡ž£¡£©¤¨­«²®³°²°³¯±³¬´±°³±¸¼½¾¾½±´²³²¯®²°¶¶˜”‰y}€{rvtwy|„™ œ˜™›Ÿš•‘Š›—–›š™“››š™š›ž˜“Œ„‰‡”˜™˜‰‹‰Ž‰‡Œ‰†Š„{‚‡”…x‚zƒƒˆ›™ˆ{}wu{{yz‚†ƒ„ƒŠŠ•˜‘™Ž‘’“ŽŒŽŠŠŒ‡‹Ž‹‰‹ŒŒ’‡Ž‘ŒŒ‰ŠŽŒŒ‹‹‘‘–Œ”“‘“‰ˆˆ‹‡‰Œˆ‰’˜’}…„……„„Œ‘œŸ™…‡–—šœŸ›Ÿ£¬©ª¡£¤Ÿ¡£ž¤¦¬ª¢¢¤©®ª©¡™ž£©¯­¬¢™œ¢œœ›™œššš™•–™˜›™’Ÿœœ›ŸœžžŸ  ¢¡£¢¥¦«¦­§ ¡¤¦­²À¿ÆÉÊȶ³±²«°°®°¬³}€‡‰€fok`ZZdltrv˜“—Ž‰|xsxs”•™’‹Ž–š™™œ™œœ›•‹…†‡™š›„‰†…Œ„…„~†€†zw{„{z{}~~‚Ž†€uvwzuzy|{x{z€~‹‹’‘ŒŠ‹Š†ŠŠ…†‰‡Š‰ˆŒŒ‰‹ŠŽ‹Š‡‡ŠŠ‰‰ŠŠŒŽ‰ˆŽŽ‘Ž“…‚~yƒ{‚‚‡Šp|…ˆ‡†z|{€}ˆ’wz„Š‰—’‰Ž’–ž› žŸ«¦¦ª¡ž› ›ž¦ŸŸ–œœ£ £¡¡¤Ÿ£¢£¢£¦¥£¤¥¥¢¢ŸŸšžž ŸŸ¡š˜˜šžœšœ–ž™ž–’–—¢Ÿ£¢“‘•™¢­®¯µ±´¸²¯°²¯¬²©¦«¥uyƒ–‡ggibZbfs{w{ˆ…–Œ…€z{y{y€™—“ˆŽ‹’——œ—˜š•›”‹Ž‰’•›˜Ž‰Œ‹ŒŠˆ‚ƒƒ‡ƒ‰„„ˆ†‡Š‡Š‰ˆ‰Œ‹‡„€„Šƒ€~‚‚€€‚‚†”ŽŽŒ‡ˆ‰‹‹‡‹Œ‰‹ŒŠ‹ŒŒŒŠ‰Œ’“ŒŽ‹ˆŠŠŒŠŒ‹‘‹’’‰ŽŽ‹‰yw{y}{x|{„xvvz„‡v}w~u}wh{vy{Œ’Šƒ„ŠŒˆŠ‹™ž›žŸ›Ž…‹†‰‹Œ‘˜›¡ ¢¦¦§ªª­¬«­®¯¯¯©«¬¬­­­£¥¢”ž«©© š™ˆ™˜››››››–ŠŒ—Ÿ•˜”‹‰š£©¬­¬®«²µ­±ª§¬¥©¥¡rsƒž‡faaf\`mr…““–“™™–”•’“•––™›šš–“—™™™—›˜–œ’–•“—••—˜™–——•—–˜—˜“”š–•—˜—š–——š––“˜”—˜“—Ž“‘ŽŠ‹Œ‰‘Š‹ŽŽŽ‹‹ŠŠŒŽ‰ŽŽ‘ŽŒ‘Œ‘‘“’‘‘Ž‘Ž‘Œ‹“Ž‹’’’“Ž”‘‰Œ‰„ˆ‡ƒ~ƒƒ~‚||vww„ˆ„zvwyymbqvuty{‚„}y{‚‡ƒƒ’–“Ž’{}|~„‚”£¤§¬¯©«¬±¤¢§¥­­­ª–™©¬¥ª©”Œ€Š¢¦©’Š{‚ŠˆŒ––’ŽŠ€x‡…Œ™Ž’‹…ˆŒ“–¤§¨£¨¦«°¦¨¤¤¥¦££ nmœ~aacl]blu†•–“™›š›˜›™˜™˜˜˜—––™˜™ž——š—šš—šš™™———š˜˜–—›—™˜—œ˜™›˜›—šš˜—˜™—––™”›™™šš™œœ˜”•˜‹ŠŠŽŽ‘ŒŽŽŠ‹Œ‰‹‹Ž…‹Ž‹’“‘“ŒŒŽ’”Ž’•”’•’”‘’“‘““•’•Ž‘”‘••Œ““‘—“”–’”Ž‰Ž‡†ŽŠŽ€~ru}}‚{|}z{€uzu‚†~‚zƒ‰‰…ƒˆ‰€}{‚€|…‰—”Ÿ§®¢¨ª˜—žŸ¡Œ|‡››’zw}…‰—™‰y~€€}|€Œ‹x{tx|„†ˆ‚…ŽŠˆˆ‰› ž£¡£ Ÿ£ž¤ž¢ mj‚Ÿ}gd`lZgkxŠ“”–”™™—š“”š˜”›˜–—”—˜™—–™—“––—˜›•—˜˜˜”œ”—š•••—˜–™——˜”‘••›™—™–˜™———•˜—•š›•š–˜•’”ˆ€ˆ’Ž“’“™—•—–———˜”—–”’•˜–˜–š™˜–š˜’™–˜–™˜˜™•š——“•—–”•˜˜“”–”–’”—’’“•“–”•“”•Ž””“•““‹•‘’“”‰†””•Ž‘Š‘Œ“’’’’•‘‘†ˆŠŠŠ’’š©¢¤žŸš—˜œ˜•{„˜˜›‹vyuwz|~~{|zx}|~€‰|xtqorx|~ƒƒ†‚††}Š“œŸœ››Ÿ››› ›Ÿ ›mg}™u^_W[Zbpt‰—’“‘š’“™’•˜–š–•”—“’˜“–˜—••—•–”“––˜—™–˜–˜–———Ž–––’—˜“•–•——–—”™•™–”—•–•˜——˜–—˜—–•Ž“‘˜Œ–œ¡Ÿœ¢¥¢¥¤¨§¦¦¤¨¦§©¦§©§©¬¥¥§§¨¦§¨©¨ª¦¤©¥¥¤¡Ÿ¥¥¡§££¤¤££¢¥£¦¥ž¦¡¢£Ÿ¢Ÿ £¢Ÿ¡ž¡¢¡£œ ™Ÿ¡ž£žŸ ŸŸœ¢¡Ÿ¢˜Ÿž¡œŸ¢žŸŸŸŸ¡ž¡ š ž¡Ÿžž—››ž¢«³°­¯¡ Ÿ¢²©©ª¯©§­§·¬±£––ŠŒˆˆ…†„|ƒ|zwxyxuuzrsrrsrrru{ƒ}x||ƒŒ–—˜œ™˜’›šœŸš›œœ›IJU‹mSZQW^[]`cogoxxƒ•’“—––”•’’’‘•“˜–—•”–’“–“˜•“”—”˜•˜—••—””‘•—™––“”™•˜–—––››™š”˜™œš–˜™•˜š•œ˜™˜–—››œœ›¡£¥©¥£¥¥ ¤¥§¥§¥£©¤§£¦©¦¬¢¨ª¨¨ª§¨ªª§¨©¬¦§¦§«©­¨«¬©­®«««««ª¨ª««­©­ª¨¬°«¬ªª«®¬±®­«¨®«¬¬©«ª®®¬­°«±³¯±¯®±­±´­®°­°±®²®®°°­®®®­ª¦¦§¥ •‰‹Ž¢°©®µ¶¼¾¸½¤–œ’—œ³¶°±±¬ £œ–”Žƒwtnkjilpoxxyvq{yˆˆ€ˆ…——”••”˜¤¤¥£¥¥¤Ÿ>E>7462=;79799=692:L]NDJUjppqsvr|~„~xyvsrpxywwuy|wu}rwzpy}zltrtvt|„€ƒ{st„}€}x‹Ž–’–˜”š™šš–›œ ¢¡Ÿ¢ŸŸ¢œŸœ—›”š›ž• œ¦—˜”•šœž››™˜š–––”–™—š••—”–”—–™š™š•——“Ž—šš™”—Ž‰‰“––„Š‚szw„tz|wƒ€€v‰‡‰pslifgnpsvsx~~xx€…{vˆ‰zztx{~ƒ{ƒ„~yytsm‡w{€„Ž~{‚ŽŠ‹‰ŒŠ‡ƒƒ……‡‹†ˆ‰Œ‰Š‹‡‡~„ˆ„‡{‹}‚|ƒ†€ƒyx}€wrw|x€9682D<;?8?CG@<=BG@C@AENcndYVYluousmouuyvtuutmpttrzyyvty{uwyquxtrttlvylw{tƒ}uywƒuuw}€ƒ{‚‰‡Ž’–šš—˜ Ÿž   ¢ ¡ žŸŸž›ž›¡ –¥Ÿ¥™††”Ÿ›žš••¢› ŸŸž Ÿœ™¤Ÿ Ÿœž›››Ÿ–”„ƒŠŽŽ’”…{xrt€…†ƒwvxqyynvwvwyzr}xuyklhnfenlworqy~uyy~su}‚‡vxut~ƒyuustqhpƒxvxx€‡Œ…‰‘ŽŽ’’™”Žƒ†Ž”’Ž„„Œ‹ƒŠƒˆ’†‡‹‡†Œ†€ˆ€‚ƒ†‹‚‹‹‡‚ƒ„ƒvwy}~700//..,2105-3032421136?PPTLT[hjimggiokntopnrpqijpnnqonqpppqvronwutwvunqvqw{€wy|}}sxzzyytprss{‚ƒ˜”š›˜š—ŸžšŸžž¡œœ¡ Ÿž£žœswu‚Œ‹Œ„{‚– ŸŸ››Ÿž›‘–Ÿ¡Ÿ ›”“–›™ˆ†w}yxr}‚qonnksyuqnmnqqpojiqnmqvsvvhlmhiligfhpnollwnkwos}|…€zp{|ƒ}oopmhdpvoswyƒˆ‘‰ŒŠˆ–ŽŽ“•ˆŠ—˜‘†€‰‘‚‰‡„Š‹‘Ž„Š†‡ƒ…~{~{‚ˆ‚††ˆ††‚|ƒ€|‚~00+--(1,/0,../.-0.-+-118DERKTW^hnechfmhipggppsmffkkmhajgelkqvkpmmvkppmnenopvx}sqxy{w|{{xonjimnt}ŠŒ‚†‹’Œ“”—¡™˜ ™–˜–›˜šžœœspinruwpy€kt„š’‰‰†‹‘‡‚…‹‘“Žƒ~„‰‚‚…tsjdsolmkmnqrggjejdskiicicngppotegnbghghdhqqidnpmororsttpx„rwsx|voqqjjborotuz~€†€~yƒ…‰Žƒ‚†“–’“•‹ŒŠ‡‹‹ˆ„‰‡‚}€„{†„ƒŠ~v}€‚z}†‚‚„ƒ1'-*'-)+-(,/..)1+0-.4-138@A:KFFXe`bdekkdimrr^^e__a\_Y`b][__]eceecjhemoiienk_ecepolvmsukqusgfeenkqkmoptqomhjdefikhecebabjp‚v{}cjfxpjl_dbd_`fb_^fafeg{}}{ƒ|vv…uptnmy~‚y}{…†ŽŽ“••”–Ž–˜–žž›œœ˜›–™—š—˜˜•–””“““••”Ž‘’Žˆ†xnfefeedlwnnibeglkdkqknqohklgedbjrw||ƒ‰ˆƒ††€u„Œˆ‘‹‰}{t€‹w~z}€ˆ…~vptoy}zƒz}€~y}†|wzz}NXkef<29,2-+-,+3.22.55DR\^b^eb]aadgffonooeb`b_\]_\[a\[^^bccam_`i]doeaegmcbfeoroolrrtw|ƒ„ƒ‰ŽŽ’Œ“Ž’“‹†ƒ{‚{}sqqhkglovmqqimgywchfacfac`]`^]aacqtxz€„‹|„‡ƒ{~ƒ‡ŒŒ““‘“•”••–š™˜œšž££¤¢  —™›˜—˜š—“––•“•›“””’–“”—“—“”Ž†{pjggllmihloldfechjkplgg`decpzv~€„…‡„|ƒ€~…ˆˆ‹Œ…|uzw|}ƒŠ}{€~ƒƒ{xppuuu|y‚ƒ€ƒ|y~z|~z4Cm^Z=66130/.)5=47667>Xrkeh`cn`^eihgjjprnkgjmfhd^^\`d[X\ad[^j`\gegigdfkge\edilcggoux…‰ˆ‰Š’”˜—‘—”–•‘’‘‘Ž‰‡ˆ‚†‚ƒƒ~y}uxtuwszvxz{||{{ywyz{€w€x€ŒŒ‰Šˆ‡†„€‡‘˜–™˜—––š•šš˜›ž••Ÿ›Ÿ¤§¤¨ ¦¥žŸž˜œ›œœ•Ÿœ˜™š™’˜˜’”“”•˜˜–”‹„wkfgkfjkpnmnj`fcdifeca_cfgu|w}†}ƒzyz|„Š‹Š†‚ƒ††pimo}|ƒ€wzwptt{y~€{{qzƒ„}ƒ|€|z}vw{|;MhU`[F46/4:,/5160<2=AewtjR[bicZ`jfijhpsrhihlinif`Y^]XZ[`\]gk]`a`ihhachf_^ablicabkx~†‡‹Šˆ‹Ž‰Š‘‘“”ŽŽ‘”•’“‘ŒŒ‹Ž‰Š‰Š‰‰ŒŽŽ‹‘Œ‘‡Ž‘‹‰ƒ†zˆŠŒƒ‡‚€„€“š—œ˜œ›š–š™›œœœ›œœœŸž›¢žŸŸœžžžœœ¢¡›Ÿ›žŸ›Ÿž™›”šœŸž—˜‘Œ{woffgemkdjicbfafceg_d^f_mqlx{†w|vsyy}„€ŽŠ‰Œ‚{‹xios‡|‡„wytnrppuu~€{yzy|~w|z|{|{HC]c_gQ330/7'.,+/'8./6NUiV?S__`\cdjhebjm_\__afgej`][X[[\aXZde_\\[b`cd_ghhcjghejhnx}…ƒ†ˆˆ‰ˆ‡‰Ž‹’‹Œ‹Œˆ‘Š’’’”’Œ“–‘“‘‘‘‘ŽŽŒ“‰’‘—”œ“–„ƒ‹”‘†‰…ˆ{€‚ˆ‹…ˆ…y…€}‚€‡‘™˜š›™––˜–™–‘˜’šœ–œ–˜™——™œ ŸŸœ œž›Ÿš›¡ Ÿ¡ Ÿ¥¡¢¡™¤¦¢¦Ÿ›‰~zuqcabjfcdagigfic`g]d^^amlkmsrsqo~€v€…€‚ƒ‡…Šuƒ|t‚‚‡ƒ„†{q‚u}yprt}r€{lxs{x|vtwwy}{z{y6.Kj^iP7?1;>13/:;1=24:JSs]KSYaa]c]cde]`aY^Y\^[cega^\Z^[_`_[b^^]]`cjlovtw~wzz}†„„‡‹ŒŒ‘‘“’”’“‘Ž‘Ž’’‹‘ŒŽ“‘‘—‘’’’Š““–—Ž–yx{‹†yy~€†…ˆ€‡}z}{‚Š–”–‘—“™›’—”’œ™—–“•˜˜—–˜–•  œšŸžŸš™ž™¢¡¡¡¤¦§¨©ª«£©ª¤¡•ƒ||njbb_`a_emiggb`g^rl_afjdkrqkjmv|uw{uqxy~€stuuƒ‰}‚uk|pw|srr||{xhvwx}~xvpu~x}zx>8Pl]dUC3-0-.)25//1155RUaf[XX\dX]_ZiaXZ^Z[XZ[X``eiofmkjgknuurvtvvz~{|‚„~„†ƒ‹‡‰‰‹‰‹“‘“”“”˜Ž“’”—”“–••˜‘•’Ž”ŒŽŽ‚ˆ‰ƒp{Š|€{‚…qrnxx{~z|}Œˆ|‡†{|€|~~Š‹•–”””’‘““˜œ™š——œšœ˜œ˜—–—••–™™˜šžž›™ ¤¤¢¥ª¬­°¬­¡£ž¢¤¦©©©¢š“}yrfsvehnvlbb`bacylhaehgioretniyxx{|yv{rwwttyˆ‰‰xrwlengtwylqpuz{{|†|}€‚tswurztyDGXZb^XD/2+,*,0/*+-*15ITN[`LXY^\W^`e`Weggbhdfcehfpsrvywvsort|‚‡„‚…‡„‡ƒ…†ŠŒˆŽ‰ˆŠ‡‹‹ŠŽŒˆŽ“—”–’•’““““”“–“““––—””“““”ŠŒŽŒ‘…‰Ž†‚|…zx€ˆŠ‡elkqwxzwu|}‡„†Œ‡†‚|~~‡”•––••””“•‘“”Ž–’——š–•—•”““”™™œ–›œš•–—› ž¥Ÿ ¦ž¦©¢Ÿ—š¢¡¡ª¬­ªš’ƒ}yzz€}wsrmebaa]bplfcggojjcnjjmuwnuxox~ywv|xzyˆpv€qejmkftpquotxpr|wtq{|yvilrrs/617FFEG65@;848;86:/6<020KMe]>Smsuuwwu{~€‚ƒ‡‹Š€‡…‡†|k\Xetiebcf}~…ƒ„ƒŒ…‹‰‹ŠŠŠ’ŽŒ‹‰”Ž’’Ž‘‹‹Œ‹’Ž’’‘”‘”’—””•’’”“’˜Ž‹‹ŠŠŽ‹Žƒx„Œ€ppssrphwqjkpƒ}}z{|su‰’’–“–••“’––•—’“‘–”Ž–’•‘—™™—œ¢››š™•Œ†‚‡{}x}~oqnhjhlkitˆ™‚†v‰…‡|nkkoql^f_Zb[etkjhdjpjhbad[agdbjdccgtttnvwt{€|y|xz€‚qwviwtyrlvmqowoootuorrw-+.-><61-3/?8CdtwgN]~z~‚†…†„…‚†‡†…‡„‡ƒzo_bW_j^cXcpgnuw‡ˆŠ‰ˆŽŽ‹‘ŽŒ‹‡‹ˆŠ‹‰‰‚…ˆƒ‚…ˆ‡Œ‡ˆŠ†‰Œ‹ŠŽŠ‹ŽŽ’Œ‘’’“‘’•Ž‘‘Ž”}xŒƒ†ksptutsvzkeq{vxvsun€…‘‹ŒŽ’™”““‘””‘™–ššŒ˜‘“–˜—š˜˜•˜‘ŒŠƒ{{vtwomksfjeaeecklw“tv}|w†z€|yzuonfgg`cajjeaegmljg_fkb_gcfecbhqnimkjpxqzwt|rqokost~~pmilumipklilkjojqlccl)+0=A>9,00*9A=@50/435@;;@8?@Hit‹S]ysg\bgoz{……‚†ƒ€„†mc]_PW^N[_XX[`^glfjahu{ƒˆˆ†ŠŠ‰‰ŒŠ‡‹…‰Šˆˆˆ‰Šƒˆ‰†Œˆˆ‡„‰ŠŒ‹‹ŒŒŽŽŽŽŒŽ”ŒŒ’Œ”…€‚srqmtlqpcdggfnlnupxvw„…Š˜”‘“”—’ˆŠ~}|xz‘‘’‡qx‰ƒmgoika^dde`]dhlzƒ‹ŽŒŽ‘Ž‘Ž‘“’Ž‹‹Š‘Ž•“‘•‘•”“•‰vvkfdbb`j`hicnivsxxuxtq}{~xhjf`_fd_beakqfm{y~|stb^gcdcffgdb_hioq+HWPL/)++--8<76:8:@=?AixlFVklgV\W_ot‚€ƒ‚‚†ƒ€ƒ}~rjeTgURWVTQXbd`_jcgjnp‰„ˆˆ†‰…†‡‡ˆ†…ƒ†‚„‰†ˆŒ†Šˆ†…‰Š‰‰‰ˆ‹ˆ‡ŽŠ‹ˆ†Œ‹ŒˆŒ‰ŽŒ„€olrrwnqtoqe\hdcigffinmptutq‚Ž“’’Ž‹{svqmmkpzŒ‚wyosjbaabda^_ccgrx€‰ŒŽŽ”Ž“”‡ŒŽŽŒ‘Œ‹Œ‰’Ž“Ž•‡}wofa\^b^e`fflkjlnpljjqtzx‡wrld^a``caaalemrovx}obckg`dcdg`dbjinA^eW>2+-0*1799767<><=AmrpXCU`ik]ZX[fkx…„„†‚†„‚~„„€€€wjk[TSRcVQPT\X`lmhdqmp}€†‚}‡‚…„†„…‚‡…††‡…ŠŒŽŽ‹‰Š‹Š‹†Œ‡„ƒ‡ˆ†ƒŒŠŠ‡Œ‹‘…ykhiekktysu~yvrkad`_]^gchiiegxŒ’˜|vskkhhibgcy‹‚wtz€xuyuttwvy{~}~‰‹ŠŽ‘Š‰ŽŒ‘ŒŽŽ““‘’’‹“‘ŒŽ”‹…yrj]c[]aca_bdcc_ce_chjo|ƒ~xiba`\fnwotxzvnwwt}yvpej`]a`hecaccgoHZdX84.8--145-63591;:=apjhQKW^_]`dkufjw‚…„„„|zzy€yzz~odk\ZSOXRROSYY`adXeihlopvqnpu|„††‡‰ˆˆ‡ˆˆŒ‹‹Ž‹‹‡ˆˆ‰†‹‹‹‹Œ‹ŒˆŽ’’Š’ˆoffieejkrvz|„ƒ‰Š…‚vsonedb[]`bbr‡‰‰hefY__[_bbjvw€‚„ŒŒŒ‹‘„Œ‹“ŽŽŒ‹ŒŒŒ‡‹ŽŽŠ’—’ŽŠ•““–”“’‘‘‘”•”ˆ‚{unkk`a`_Z^_Z^^_b_^acfvstvupja_gouxyt{}~{trutz{wk_`aceggebhhea?TYKC+.)$.(&,(,6--0*4.QkpiHJmnppijqpwqt|ƒzu{uyrnulmmtqc[WVTORNMNUYVZ_[\dgchhclg^lol}‚ƒ‚…„ƒ…ƒ‚‡…ˆ‹‰ŠŠ‰ˆŽŒˆ‹‹ƒ„Œ‰Œ……Ž‰Œ‹’“’‹’~dg_ddaflmxo}ƒ‚‚qfcfirsy}{yhefvƒ„€lbc_Zinu{€ƒŠ‰…†‹‰ˆ‡Œ‰‹‘–‘”Œ‹Œˆ‰‡Œ‹‰Œ‹Ž‰Œ‹‹’”•“˜™š–™“”–”—•““‘‘‘ŠŒztmh`\_[\\[[^`U`[fhdlhmjgefpuu|}|rqpstpwxxtrbkungdha_caif<\igI+4./++18677<76<<;VooiKUstrqfhkeljkrrsroqztjmriqrolXXPNOLQRY_ZVcaac^_dhaggcb_jjnz†ˆ‚‡ƒ‡…‡ˆŠŠƒ…€„††Š…‹ŠˆŽ‘‘‹‹‰ŽŒŠŠ„„u_``\``cjnpu~ŽŒ’oeed[cfhm}‰ˆ†ƒŠ„~xsuuv|…‡‹‹Ž‰ˆ‹’‹ŠŽ‹‘Œ‹‰ŠŒŒ”‹Œ“‹ŠŽ‹‡‹‹‰‹Ž””˜–––””‘•’—–––˜–™—•”•••Š…‚tqid^\S_Y[]\\`d`bbheag]kekopztruouy‚„„†ƒqjllrrpugb^Zcg9Xg^E/3)++,79@@<<4:b‚kvcM[VY`Y]cWa[Ydfbhalpukoo`dfbhdgcOKIHKDNQMZVR]\d`fdjowoglbiw††…‰…ƒ‡ƒ†††ˆˆŠƒ}xwz‚ƒƒƒ…‹‰ƒƒŠ‚„zƒ~}~}|ndf_alkc]b`er…{de]\Y^\^_]`bbcw‹ŽŒˆŠ‰Ž…’ŠŽ’‹‘“‰‰ˆƒ‡‡‰ŒŒ‹Šˆ…‰‡††‰ŒŽŒ’ŒŒ‘‹ŒŠ““•“—–—”•“•–”’‘˜™š˜žš ›£¢Ÿ ¡¢¤ ¤§¡¦¥¡›žšœ¢žœ‰‹{qica^\ZZ`ngciftuirturosz~{miy~ƒ…†{~}hbHeiWJ:,47164:979<=>;@:]uaoXNWTX``_`[]UW]Zd_deattioidcaa\XbQMKJHEXRLXPNV[]\Zdjllikkdr|„‡„€ƒ~‚}z€u€xrumjmnu‡ƒ‚€vlnhpqvomqpidcefjjni\bfcpogf^bkfmjc`ajhgq’”Ž‰Š’‘“—’Ž‘’†~{„††ŽˆŠŠŒŒ‡Šˆ‰’’ŽŽ‘ˆ’‘‘•””–™š›™š™žœš§¦¢§¤¨¦¦©¦¦¦§¨¨£§¦¤£¦£ŸŸ¢ ¢¡Ÿ—œ•–‹ytkh`__fomeccipkolqrrvz‚wzmox}stw}„…?QSH@;+0.1245565:9<8@>VjadUJZRWYacb_\STYXg[Xadmiinigfm`\ZTTMOKGPTXNSOMNSYRVckmldhqw|†‚ƒ†ypkiupluwtnfjojgnaivz€ƒwtzge`agcf^b``e`bdifijffdotƒƒspleglcdjkedhjirˆ“–—‘Ž“““—•‘•Œ{†’‹ˆŒ’’”’•“–“˜“•”•–•šœœŸž§£¦£¢¦¡¢¦§ª©¨¨«£­©£§ ¤¤£§¤¢ £¡¡¤¡¢ §¥¢  ¤Ÿ›™•Žˆƒrjgmrrebd`qhagkpornwyt}pqnijouw‚ŒF_^JC59457;9101.174:CEmyoyPO`Z[adhcdbVQ[]g_Ub`e^ckcdmqmm\VVOUTQRZVQTWJLRRSYbdjmhkt||‚}v„q`Y[dZV]fudUb\TW`bcins}~jcab`Zb^ec]aZ\_]cdbfehfgloz{rjbjqphechjmcdejlyŠ‘“’’™’’–”‰’‹”’“‘Š’”’’’“”•—”‘‹Ž”˜•˜š–œ™–žš›œŸ¥Ÿ©«¨§ª§§¨§¨£§¤¢ ¡ £¦¤¡Ÿ¡œœžžœŸœŸ›š™™ œ¡ŸŸ ›ž¤¢Ÿ¡ —”Š‚xjfdflnnqhmwkahklrhqqnvjnndhns{„vDn]WA);14353,0.310:B?OtuojFGTNVYW_^_d[R\[b`]\]c[jf`baddjn`WPLWKU\UQTZSMT_\\bnnxssz|v{w~yaW^UUROR\\QZ[QW[_acekx~f`]hle^_eed_YWZYYZ[cY\_e\bhag\[^ikjmadlggidcrn‹’‘•‘˜’™‘—“”“””“’“–”š™–•’„ŽŽ‰‹ˆ–– Ÿ¡¥§¤¦£¡¡ ¢£¦¦¨¡¦¤¢¥Ÿ¤£Ÿžœšžœšœ˜™—˜Ÿ–œ—’””•–˜œš˜˜•——›ž˜œš˜šœ™œŸ—‘ˆ}ia`_gdmoc^hqkiglcbhnmdnkchbopnx€†:\LF>--1.+4031.2436EDHqxkgIDLLOKNZV]cTXX\dbp][`Z`ka`cd[bujgcYQYZ]ZLRWVLcrpj\jprsotpy€}}vj^RSQVLTUXGXWYbeojwst}zjW_eecaca`c^[[RTX\\^`WZZY^_\a^XY]e\ei_eh_eaZmw‚ŽŒŒ‘“‘Ž‘•“”’””“—•–™™š™ žš™‹x{wvz‘ž¤¦¥¥§­ žž §¢£¥žœ› ™›œ™œ™™˜˜™””“–™š””’•”Ž“•–’’Ž”˜–—•–™••—–™—’“Š}fa]^\`fmc^]kniemaedcjgqohfagmj}Œ9bUM?,4-9723302;:3<8,1+975965<=jmrrEBDCFNNJIPSNMRUWfgan_Ygakd`grknumwphpkurckkjjgjn}„‡yxofddilkknfbSTdVJHNTZgjYWT\u„zhZLY\ox{ƒ€|so|€}~}yrngVVPSXU^b[ZWP[]]`Zdd[e^\ddcookŒ‹Ž‘““ŒŠ‰Œ†ˆŠ’•š–—’‚ntx‰šœ›•”›–upsk{‚ˆ†ƒ‚†~…†‡‰‹’‘”™––”‘“”’‘‘ŠŽŽ’•’“”—•š—•––˜˜—–—”‹ˆ‡~j]`bcf_^[Y[a_b^Z]X]a_mroin`iru€~9[lmJ03,,,>:5>8765347>]qkqPEGCHLJDJJISOLWP[[Xm`NWJ_ePco`cnlhicff\ig\bdWX]ar{pxmsqa`]_beccaYOacMY9CF9JIIKCLGELJGFCDKumikbqz††ˆ†‚Œƒecf\WURU]XZVVVM[Zc\fc_e\[bc]`ahiv……‹ŒˆŽ‘ŽŽ‰‰‹…‹Ž‹ŒŽ“Ž‰‹t€vcnfq}•’„€‚nihkqrlsr|wstt{x‚‡“’”“”—‘Œ‘Œ•‘‹‹‘‘‘“˜”——˜˜™—•š——•”••““‡d`_cfvvihe_]c^Z_X]]ek|‚{yf]nvvqrA^raJ<.-+0.DA6;295;6:Ad{ppLXviibRMJKNUQLRQQWLYVKLLYgX\sikjjmmfc]^onab\UUTajpefadpd_V^ZhfbbUOdbWGDFQYXX[[[`TU_WWRSRh——†‡~~€ƒ…€†klf^YRQRUUQTSY_\`\`febhk]`dXbYafv€‚ˆˆˆˆŒŽŽŒŠƒw~‹‡Ž‹ŽŽ“ƒy†keiily‰ƒvspmfddegdbfijprqnuxs|€„’•’”ŽŽŽŒŒŽ‹Š‘”‘–““™—˜•˜–™™šš˜š–›œ™™–‘–mi^kqƒƒ{{sm`d\YZ^\[ekt{xsglx|vsrBjrdV;5-*+11@9.257:496UtmpFb£¢ªš•Œ|m]XRLJNLLSQRKHOM[edhhj`kioj[f_`lj^XRHTUdygad]`dZZ^ajfaZ\\[eZ=8CLSQOPELEEGPQKMWRe„‚€nvdN[wmtst„‡cYYUROTRZVVY\aZQS\_hfgi_]dgfclqzw‹‹‹Ž‹…shmpy|‚ƒz{…†Ž•˜“seecmir}urribcba\Z\Zaddlggjggnkqv‚‡‹Ž†‹‹‘‹‘’’Žˆ“”“˜“”•–—˜š™›™–˜›š™’–“”ˆˆw{‚~„}wqlea^][ZZXebgdgea|os~{u=Qu`KUH73+,01@7179:2+98[fYmKež”¢¤£ž¡¢ž¢ŸŸ™—™œŸ™œžš™ž Ÿ¢¢¡ £rNVL\OY`g‚Š“’ŽŒ†‚ƒwxh^RMPNT]_IELJGSXUOOJCAD@CLGaluvsynZ_e\VZ^]ba[\`aRPWZXLSJOKHODSRX__fqpx|yz|welojlwshwzrqjnkln`f[_adln‡zhj^c\]dfmmmw_Y]VUUUY]XNbUX[S\Ude`ecsy~~wvmlywzŠ‰Š‹sy€††…„Šzuƒ†––“’–‘—’„nnha[_dblievy„ƒ€{{rmpfeb^YXbctrhjadgfg8O^WU]`ZPM;4//1.C75;=@e|kySi ”£Ÿ ¢¤¥§£¤¡¡¡žŸšžŸ›žšš›šœŸ —˜~UOTSZV][Zv|x|Œ“ž¢œ  œž”“›–ˆ|uh_bYNOVMRWUXX^WUWTVR\Xm‡ŒŒ{^_^ddXVTP_\ZWX\QVTTVOQPNPOMSTWcfxƒ~‚†€{}wwc]gqtlmmuqkkecghimjbhpgjjfga]_]a]gegsY`d^^cdpjdeZXXY]]WabZ^]ijv…opoprruw‡Œ‰Šwqrn{uwyyx€zx„…Œ“‹’‘”}mjg`\^fkbcrqnv€•’‘‹sofdX_ljca`Z^_gi6KbU[kg`[KC7/-/-4>>-@BD@DELUJbd@CLMNJOQaa]mVXNGKKUUIIJIPWVSZYTZWV\Y[`\`[oŽ‰o[MR[[`g|ŠrRWQS_\Xajcuurrvywpp^`rmrgUJMRUfedkcge_`abZ`]`b]ec^_cjlgnz{ywqgs^cedjih]c^b^\c_e_bcbbbgdjlgdiilnipz„—ƒb[e]]djdbhnnvtp}tkrh\WX\W[bhsue__WYbcogfidejbz{j~tld`^Y\]d_^bggdlgjpwzDotefvc_jjnsqaKG:02,39do{Yd›Ÿžžš›˜Ÿœ•—‹“•••–“–—“””——’’yXUOAC@=@=DDNPZiGEHLOHNP[UQceebXDOUKEE7>FQOLRNRIKFIPLNHRO\suxv‚fPPP_YV^chXMGYMNWKUT\bg^agqw€m]cQ`lkv^QnYdgUcfhjkcXf\^j`U]d\a[abdenhpnh`V\UM[^ccc\[]\X[be[[^]]Z_[^b`___`agdcfciok]UdZTe\]bXdbbdftqhmhQ]\Y]X]hhlc]_UVYWY[\pmpjehffd\WXXWR\T\\YffbefcgdqrTqoPXgboutokg]\OPB9.87]nevXkš–‹„‚‡€zusrwwyxyˆŽ‘—™”˜—•tSTI?A=;BWnjnsrdNMIGECZJHLAHJLEBLOVZZJCOOSVibTMMKPQXYOZcl^^b]`\^\la\a\]^ahfabca[]pmg]STOWOMTTXZXYRQYT]\aaT]_a]Z]\\]WYXZU^b]^QP][[V[UTUUYWSLOOaivukrsqvdRbfZbfgfW\Ybc[_]cT\danmg[_VULJLHQLWUTNZ\ZXX[]`cZQaa^wwpaekfoqliY[^N>5Xu{r{…hYY[VZ\VWVYQU[XY]Xa]irz‚„„wlcZa][`[RW`W`mQ@DU\TNUSF>?BGSWRT[[ZVUVL[^MOd^Z^RHA<9:8<9FQHb}‚~…rRKID>CFJHIAFMMDHKJ`_GHCIKRP`YDJDIKOORNK_fc\[[\YWTjZVY]^^oqsm]]^[`gikaQRJUOHSVWWVSRPRT]ZRYRY_aZZX[Y]YX[YXY]YXNJX\aV[gTX][VRNMOTYcsjrrjs]PX]b\_e\YY`ZWZc_ceopoplcSUVYNMMUOOZJXYX^XYW]Y[[RRV\Okdilt}xvkbbhnoqO3\owopnVVMLNTSHFIKNUTVNGPPTY\b`otkjijb[]`c_bd^Ub]W_ic]d_cWTRPUTdgklkmkia`cTSVWUXZURMJAA<>JJRRm„ŒŠƒƒqTGBDBDF?FEFFLOICDGZT@F@GJH]\JKEDGJIJNMV\][UX]]\TT^RSQ[[adgh_\\[_]^adZSFIVHMMPTXTQJSXYYLNPRVU[\T]UX]X^\[U]ZWXOUL`WUai[\URMNZLRPNXghddgimbTZW[^c]hzWX`YYTTbmdgdUQMMSY^[\d`XXSSRYSWXTWVZ`V_\\Q`qqz{wwokswwnlcWANjpiegWUOMJKOEE@BIKRPEBHHNPPTSbgZ`b][ORTUYV]`TOZgc`\bcZcjipmjddmnc_\W_V]b\_YXglabWVPMCA@@GMNp€†xoWHGAB@???C>AGFIC@HRDAG?HIGZXJYMJLNKKGKCQX]XWZ[[MYZNVOQY^R\Z[WZ]^e^S^aaQHRKOPNSW[TFYYW\IOQMWV][NVORWQYX]WXVVXHTJTVT]^`ZLTLQXRXMTX[a]ZdiheXTTQX`acd]YYVPULYf_cTSKMUTc_difeckYQSRVXXVWXVYW\eg]o~wxogjqy}uria^e_Tix…twd[XTOWZIHA?EEDI>=CAFLLHMYPMQPKQLHIKGFPXd^]Y^_]ejkdg]aec]dicmgZcxmdhnoZ[Xb[]ZUWPQGC;FDEHJDCCDFDIMGFLIINLINNKJHNHLKMPRPKEIPU_aX\YU\ivxMRYTYQVXRYXY_SQXPMTMKIIMHNV\OZXVOGZR[WNPKQOMPQOQ[^aNVXWn`eLMRSVYXV``Zfbivx{zggl~}}wp‰›™|__a\dd\[_^\bcde`opeZYcUTUXYacgbYYVMUVaV\c\djpyr|{{{qkekj_RS`ROKJMMLOLMF@NP?EGLEJJLPhbjf]o‰‰Œ‹‘’‘’Ž‘•”’–Š‘‹‹”‹‡‹ŒŽŽ‰‹Š…ŠŠŠ‹ˆ‡‡„…‡ƒƒ|zwjmh]QOQMIJGNFak_fWXSSTMLGDB@CACGFEDDGGGKJLKLMHMMKLIQTRONJOV[eg\b_YTTf_MU\PMSZbhh`aY]UROLJLGIHDLYZ`cc_YVT\NVWMRJONJQJIRW[[JJSL`[YSOVSVVYSQRNWen}{vpgwtt|yqotŠ¡¡zx…vf`cf[^`[^^ed]ZbbaWS\S_hW_cWcN[PNZPegtqkzw€|yv}re`_WTQWNNNFDBDE>DCFMQKOVE?DFDB@ELT]_XUmŒ‡†‰‡ƒŒŒ‹ŽŽŽ”“•‘–’“—™”–˜™Ž‰ˆ’›“†‡ˆ”Š“˜’–’“––Ž•–—›™’”—’Œ‰Œ‡…€|€€ƒ‰‡‡~z€w{tmkc`[VUKGEFGDCEEFLHGHGQQQMKJTERWTY_emojhm[Rdi\[ZSOOYgfjs]UXIZk`acLTTOZa`aa[^dVQMOGKKFKINMMJOVWWYLWSUZNZZUSKORNHOKTQYjrgamty}zrlrz„~‡†€’ “qjh```c[]]Z_Z_^Xc`Y[ckx‚~zqfbbTTlX^bjylqpcbje][YQiyqc`_\WQGGERQIHBOONONQC@PGIGIMITKLMIa‡Š‡Ž‘Ž•˜‘’‘ŒŽƒ|nr…zspelto‹Œ““ŽŒŠ‡Š‹ˆ“Ž‘’Ž“’–”–š••™—•”–•‘ˆwk\UKEDDEDEHCF@DLVLPSYVGTN[RYahl]nrgbgjgZWKU_Z`edic\_pzsrw]Uc\\\]\[_`aQMNL@HGFJJQIIJQT\f^^]\gXV[cXQQX[UOPJTQTXcmopv|vnsw{ƒ~to~ž‘ŽŒzwhd^]f_hqsxwuhrpltoejnv}mjt^USXhdt\a`n\Y\RMglgnhTVmfYYROQXpUGNDGE=B?BB?EJN`VHHE@ACEMQZ[lhs{||‰‰‘’’‘’‘”’Ž“•–ˆŒo^dklimc`cd`kyŒ‡ŽŒŒ‘Ž””ŒŒ‹Œ…‰ˆ‹ŠŒ‹‹Ž’‹„‡‚‚’”‘‘ŽŠˆ‡~qj[MHD>RJCDDEKKJJUZQNM[XM]TP\j†ˆŠ‰zqic^Z^e_iohhjf\M`nijWUZWWWTUY]ZONLGIIIDEGNIIJMOS]ZZ[chg`WVLOS_`\[UPQNOTazxomfw€€}~mm{€‘štvnisn}~‹…ƒ‰|ooh\bfe\W_c\elZ[Zale{x~lqv[cXELTV_]`XUcj``a_VrhLGHBJJJMGLMQODJC@GCCAIHRSTWR]aklkxwŒ‰‹ŽŽŒŒ‘xaTP]ogliadcboqx~|y{~|†‰ŠŠ’ŽŒ‹Š’ˆ‰‡Œ‡ˆŒŽ‰‰uutdkm{ƒƒ‚…‡Œ‘‘Š†wg^POFCB@CEG@KTXOT\X\TZVPW^„‘™”tlb_]`bdb`_`_Z[O]l`ZTWTNJVQTVVRHMGEF>DJAEGHFHNSSXWQVahc[RPUSUUZ]TVUVSPRcoejs‚‹‰|ujor{zyy†—†|ytzoz}{~w}imlVWWXY\[`nkowma`_ccagplXsWJUPaIPkiil]`in\VXGPLERLMDHGD@EGKNMLCMQIPJFHBEFPRXYbefeiyŠš“’——”‘•ƒxp`fRI]gYgk^_ebeioslamiljdqt‰‹Š†Ž“‰–”•Ž‰Ž‹‹‡‹Œˆtiafhc`lkˆ›”“ˆŠ‰‰Ž‹‡„rk]WNJF>B:LQMSV\RXW[]P]pŽŸ£Ÿra\SVb[^\[ZSV\UY]b^SOOOQOMTUU[HNLEGBD@GDAIEENMMQKMSKNWZ[XQSQTRVPPYba`US[]fu}~ƒ{mwmv|vsgx”›“qz‰‚mebbrqww€ƒd[dZ\^c[bjlpo]SSUJKTYd`km]_W^MBRY[_SMV[[acTRPGPG@:ACDFKRni]XQNMKC@CBMWMRZW]dd^^bo†‘Ž—“˜˜•—›–n`Z^XP\aYS\cU^fdcglaUbe^eakruˆ‚Š‰pJWRq‰‰‡…Š‰‹{ldaeggfjl~Œ—Šƒ…Œ‹‹ŒŽŒŠ‰ŽŽ‰‚vqj_ZMDJGLMPYTTZU^]\a”£¢¬‡o^UVTVWRJVNOWONVO]\KQKQKLORNMSFIIFJ@EGAGFKFJMRVRNEPMQYWSdWOOUNQSMU_bfbTS]mr{zno|ƒ…zpojrv{‰}spr†wg_d`ghuw||bVZQZQUQZ\T^^[\XGRXYg`pqh[PPIPRW[hhYUacde`QSMEQDIHHPLQ\oz_RNGGIIFJTQNGBNPTab^cXgm……u……‡ƒ…‘”tTTUXVLXOMYaQW\`gcpdMZbZ]m“‘–™Žw~}xœ˜ŒŽŠ‹~h^^aed`]eejs‚…z‡ƒ€ˆ‰‹‹‘ŠŠ‹‹ŒŒƒƒ€tvtrghc^\[cZ_cS~•šªwi_[YWPMVZMPOFLIKSTSQMKNOKQQONNHFKPPHEEEHHNKIJRXY[IM[TVVN^QFNUVUTMNT\bZPT`hnmovy|ˆ„spz{xxmlnv}qspsnfiYSYabaZQR[ffmg_pmjkil`WSIPNRO[dYTRWNWXYYbdTNVWMQJJSENRPJFFIRIOQSLCKFL`THEGLGHKRXZ`]\VPaawj_rlmmw‚“ƒ`QWNGJSZLTY[OS[YfcfaLS_VMQYd_aZjquz}Š–˜™™——v`fcc^macl_noˆ‘‹”‹ŠŠŠˆ‘‘Œ‹‹‡“’Œƒ‹ŠŒ„†yhmi[``Whm‚’l`[XVNPHPUNPJLHQLNPJKLMHKEKMOULGKIO[PHJIMCJFCPJV^VUKVSSWKM]RMUYWVPTXMVSUYS_jg}…€yzrq„‡ˆ†ylhqz€xceuvc]VYTQUSWZ[ctsw|vtxrl_g^NUTMVW[tjjm`TMTOQNTU]_[\XQQNSROZWSDNKJNUSOSPTQUPJAKNRQVRPXcZfbb^@LP[IJPKURQ][TRZf|†‚€{u‡‘•ymp^cegeimiroz•“Ž‘”‹ŽŒŠŠ“‘“““ŽŽ•‹‡|ecVWWgxaZPLDJJILJGEHELHKGGKLLGHGHKGRPHNLJQWMJFNOFKCEHLMTXLJMNV[GU^faQVYVNKQXXSUQTRVZt‚rm~„†Šƒuoz~uxsownsxiljom]UOUUXY]cfhifafbabl`J^cO]Sdl]kXRWPW_^Y_[ldSWQQLKPNPZY\[\Yin{iLKEIEDKCHKOMJHBCHMUVGLQXkYWZRW[S[b]a[NUECDPTIYUROOMMWWdabXUHFHGILOQRX[c^hp„•’¦¤——}mud\iejadihhmp’˜™–“––˜•”ŒŽ‘ŒŒŒ‹Œ‘“””’‘ŒŠ’•”ŒŒzrgZ^RLLBFHHJFB@FHKJHNGJHLIGIJFLJKPKGIMMJIFCMJEFGDFMJSSMOQYPUGbZ]gZRVMUUPgsbXVNQRSbgm|~{}xpux{„lfo|zq`r{uqmXSMKPJNLYhxvovtxvsqaNGRQQP\ggeda[VW[ZWSSNWPRX]_ZYeec^glXTg_cahaO]QDNE;M@YdESHSW[VKOUUg]W]WRZUW^`XTHA;F;DC?>I]UVZaiaZadjc]`ggjnlnro€‘–‘›”•–š›“—™‘”ŒŽ‰””’‘‘“‹“Œ‘‘}xokZOLCMHA=?@EEHKEHFBKJFHFGEOJEKOJLLJDGBGL?CMNPLOQVWOKKQKFoj\Sba]RRVVR]qZRWY\Z`Ws†urr}ƒ|ohvwnwucho~rdnha``UGRKPUiwjmk`agcfm[\eX]bomong^VNPMPURVcpmmqkZ]b]^ZW]WXa^iir~]DI@BIHHQXc[RLALKJQQTWj_PVNNVUV\_[YKJCLMBKECAHDHOGLKWhXKMS<65031424065686IKCBNQRRVW^e\`a]jcckki…y„˜“—™›’’–•”—˜ž˜“›˜”‘“Œ‘ŒŽŠ‘‘‘‹’ŽŒŠƒ‚€uoaXLDC>>CBIJFCB@HJBDBFDJIJOIFJHGMBELFDENSUJXSRSWQIPFEpeWmyvfSUUUNVTU\X_]]]X„ˆwvˆ|†xkptwvodjy|pfv‚‚qkeTFGXP_\^ilqqz}{syu__^NRZVW[`h`W`dZdXWXafba^[ObYc`fjujknmmX]ODUTVWPMJMMOT[YTWSOIRT^SKVOTQOOVW\NIPCFFKOGEFECCFCLMNZBFKUF8?/64171546383DE>C7AOYITac\[[aeg]de^nnkƒ†’“””””“•–—›˜•œš“š˜›“””ŒŽŽŽ–‹…ŽŒ„yxoaYIFA??FGCB?FJGFDDHJHDIDEBGJIEBEIDBAOMLIPWYdi]TLGHskctw{v]VSIOVWRUSYVSTRgi~ˆŠŽ€qny|v{news}…ses‡vslfkdWIXT[ortt{mhola]aZQXhibbmnjpi[TTVNWVN[hmxtrhimgi^c]_Z[VemlZLMMDKA?CGSgidk]PHEFNEIMFOOQWFGSVVWKSI7BWYNDV`P`^O^\W^`[`al`VZ\[cg}Ž‹’‹‹‹ŠŠ‘ŽŒ’‹‘Ž–˜˜šœ–––™œœ•’†tjdqt‰wqaRKDIBA?B>CI=FGEIGIFBGGCGEHDGKCE?CFJDHPGUWVjja]ÅÊ£uke`mkfhXTTSQNK[]UW[]U_zwr€„ˆƒvmtpiokfhy€{flwkme`\Ubgkjgjmsmwujh^\\QJWZ[dckoxlmneeVUYWYYbjkpqojhqsplwtld`f[\_aaiOSSLFPIQUONNVPWT\^TW^]a_XS]aY_ebfpfin^URMIFHHDQ^;>HEUWSYVLOVD>ACA@AFA?CFB?C@CFEJC@FQMPGKHKPOSUPV{›£ƒe\bp„p^WQgcQ[XUa\WQ[`guƒŠyow†Š„|smtlvkfhuriqukkpgb\\X[j]fgGBJRME=?==HG>CD>BEKGMJ`^[bVPHOfgh‰zpsznrwtttfVQPSMIDOFGFPMcVKOU\Z\[v‰psqk[OIGB:B;>A=<POUVQVNFNGDFFNLKNFJLPSO[bVXLMGHMXgqraZY\\^gg]\WJKIKG?DGLEKSS^RBBQPUYXjypedbsr}‹‰yw}jbVNMPLGB\^IBT^cabbdcg_^`cheo|Ž——n[]XTVQHLMUV[aX[fbQUQeqy‹rk{‡€†‹srysxs`mvxv`ahfikkjmmspvfRPJGEBBFANWU[djpxyxwreejeWYfddjnzvjqvrwy‚ubmghc^a\wi\VKRVZNEFAW\GXVZ\Y…”‹‰’’Œ‡Œ‹ŠŠŠ…Œ‰‹’“”ˆˆˆ†B8?6402546<6CVM^aF|Š„€}xpkpedk`a]^\Xg\]\YZZWV\U^_PMIEGEIT^_[PMONUSXcTLHADFFADCG?IFQU?HBFPSL[cdY[YPacvƒum€y~shqlpmdnn[^_^SS[WWU]XZ\\]Yƒgim™·À¹ƒgaXYULKN\]QYXVT]cYZX\ins|ƒ‡‚vuwƒ‚zhdpsxulicu}€‚}wprkj`_PMTDKMU[WGPplmsqrlhgf\[^cegpppv}pijdbadfbfldjvuppqeSIEPXRRWPNJJIGGKVq•™™˜”’‘Š„Œ‘ŒŒ‡ƒ‰‚‡†ˆŠ‰‡†„‹ŽŠŠA5>.41,4/3.7;NKCSU‚––“–‹ƒ}{}€~{|xtyvx{ntxswlqhoiUUNPRKVY_ZWMQOWU^e`eLHGDD=CCB?E@OPSP@C:BDABJHNIMJEMW^RGGGR][QJKQVb\ZZVPJQIBEHLGKIJQOOQuw‡|z‚¤«­ŒZ_SSRLRWQXP]`QRUaZ\]bjm‚zkp}†‹†vuw}tiijv~s_]`TXmwu{qijc`PFFBGFQNWonjlbtrq{oth]bV_b^`hkqynhs€xqwvmth^c]]ackw]UTFDEQ@a^ITKQKLWUc‹–™˜–˜–™œ—›–’“ŽŠŒŠ‡ˆ‹†…Œˆ‹Š†…ƒA79.45,6261-;=EOVeœ—˜‘˜–™™—š•”†Žz€}ƒz††„Žƒ‡ƒ‚}ƒ†Ž‡„~wysoujfcdcZWOGEHD\SJK=HDEINEMNSNGJNVMBMOKYRKG?LKTXKJQE@NMCEJEEKFHILOOw~ˆ€tsw‹mf_TTOPYlwodgeUVXZflpknssz†‚u~Š|€nhornognxikEUcTUPKFICHKSQILIIR\zukd_^\bca^kpnnohdqrrwr`e_bQUhfqjarvtvor~pNQBFXPK[QRCCRHRYllwŠ”—‘“•Ž•‘””•–‘‘’“Ž„Œ‹‰ˆŠC9<2976::>=4?KHVTYˆ’š—›š–—™•—˜š˜———’”ˆ†‡„‰†ˆˆ‚†ˆ…„ˆ†ƒ‡€‚‰‡‹‡‰…ŠŠŠ‰††‚†„}{uplidfi^ZWYYQYYUXVV[XOVYXKGPLSWTGABLQPGBEKAFJ@=B;@EAEG@I`Œskjx€†§œvp_UQYco…’}`kbddbfpricix‡‹Œwu†ˆŠ‚gilkkifnz€ogkKD@ACA?@E>@@IC?EGIFQWX^bklvxsutwtjd`XLNTbdbhtoWSkz‚mmhqf]_acpuSQOJAAAAOQeqaapebƒŒŽ‘‘”‰‹ŽŠ‰‘Š†Œˆ‹€ƒv4;C8B;9HB?H?ShYa[eŠŽ•’““’–“˜”–š™šš™˜–•‡‹ŒŒŠ‰ƒ‡‰~†ˆ„„€…ˆŠ…‰‰„‰†…………‡Š‹ˆŠˆˆ„}†zyppj]ege_Zbbc^bcTXWNVRX\GGDOUSJKMEKJFC=<<@TkcGMhtt}rxjFJW\_eX^fjstzynsMCHKEEGMP`gZONKKb‡”‘—”””Œ‹ŠˆŒˆ’Œ’{‡†‘K7G726098134BRSYRWz†…„‹‹‘ŽŒ”˜—›—˜˜•“—”•““Œ‹ŠŽ‹‰Š€‡‹‰‰‹Šˆ‡Œ‡†‚‰††‹…ˆŠ…‡†ŠŒ……‡„„„ƒ{vxorqjlnjhnjalknkfibegef[][ZTKLEPC=G>?<7/:Bejaog‰”˜—•ˆ–‰Œ’’“Ž‘’‘“Ž“‹†•’””–„’Œ“”’Ž“’•“•—Ž‘–••‘’”“”’’š‚}{aWefgaUhianmqltƒw}Šƒ‡…€}|€€€|z~…y||€yuy‚yruzfTa]fub‡ˆwxicZ^fXR_c`YXXVZRX]_f`cZ`efnlq†“’€q~„}s‚€{]emisnMBD?GNIERYmqXXpx{€nef`TQ>>H?EVldMKOmp`cc`[NYZY\^ktwmxoQG[hVURGQIKQEDK\cUZ]TSUh…‹Œ’“’–•–——•š–•™šŸœž›¡œ\9>22452;BC46NZX[Vd™—•”•™”•˜•Ž“•”“›•–ž“˜”‘—•’Žš—’‘‹€‹•–ƒ‘––“”–‘Ž••‘”’“„`[]NDcjkuXZeNTOTcon`uz…ˆ†„€ƒ}}{}{{‚ƒ‚~€~}v€ŽŠ}v\^bbu•§š~w`VTNLXeneWTRRVb`dknXapszutkx‡zs|y†„lz…‰€uznkxX_t[GDADJEGNbseRVbbYjQ;FDD@CBDE?ARa\C?EG>Da^wxo}ws~vuug]_HSlbQDKD?E@KJHKOZ\a_QIHK\~ˆŒ‰Š–“‘”˜“’“Š•”—™™š‘˜Žš696//32CLJD1IPRk\g¡ž¡¤™–˜’˜˜Œ–šš ™š™’˜—‹—’‘™˜”—“’–Š•–“›—–•”‘‘‰…Ž””‹”’”’’”†‚h[KKJJVU[mWTXBLFR_^`aXnv‚Ž…‡ˆ‚‡…†ƒ}|xz{~€‚€|~~‚|†‹gRX\{ƒŠœ’{j\g_[MQW_bUW\[Z^_^\bo‚Œ‚xwt‰”uw„…|wu|‚‡~r}ŒƒnimgqmBCEFJBEB\aaqhq~{„qTHJBAA@@giJEBBCAA>:=CL[aYiJFHJf}yqbKWf`WWfkMNOKKCLRWdTRPIQP\ƒ“•“”—Ÿ¡žŸ›¥¡£¡žœž–Ÿw7@99IKDPk[LV\f]hp{ ›˜š›žŸœ›Ÿ›šž›•’‘““––œ˜šš”•–œ˜Ÿšœ¡›”“Š“‘›™—•–—š—”Œ’Œ|œ|XjZ?cXFGI\Wn_af[\VTXQ\UKfZrexŽ–’Œ‡vƒ€yw„•ª”‰†„pufux}~h^cYdgi{‰”ˆwck_W\[a^[__[\dvsky€œ¯¼Á¥ˆ|{s€ƒ…„vƒ‰‹…t}ƒ„€rmb]PGPHBB?AcaXWZ\^h_qkifJCHHVsiMF?JM4;>@FDcxsnFB@>HQ\ckl…xkekeGFMRXUPKQMID\[WLf™’–™ž›œ˜˜ž–™™œ˜¤œ’¡ž¨¡¦—9CKOtcol\reYdkmvt~šœ¡›–˜œ–˜™–˜—›ž›žš˜–‘‘•—˜š˜—•“—Ÿ™››ž˜›š–”‘†Ž““••™”“‘’““•‰†‚hGSMSzUBIEV^uqO[X^hbp\UUD]TRYS}‡Šƒmxu}‚nqzzvta^mqiazx{ƒƒˆ„j`]j‚ƒ€€Œ†r^nomqmg\VXdnwxqtnt~œÆ¾¶ª vtr‹Š…uv‚‡Šnˆ„}pp}q_ZGFCGNPIKJDSeac}w†„wsVECBBU[V`bnpA>E==@F^\MP@?ICFGj~yvt~nc\V^IFPJ\THFLYUVSZ_Ma–”›–”›”’”‹‘•›–•››£¢œ™ƒgnshammudfp\Ygeptt“š¢˜›š›—–”œ—”™—’˜›˜ž˜š””™‘•™™œ—››™™——š™—˜š•™•’––™–•Ž’•ŠeYGLC]wMFPIWoopXTQQ^j\gbU]eY`]Opjmm^bZ\_`dbZe`TV`lpzr‚‡{„‡ƒvZet~Šƒywllwyzyqe_[hx„z€pli‚Ÿ¥°¼¾¦žš”~px……wzxx|r~†„upy†hmxUUPM[ULNMGZq`nwnvda[NV\]]dojplq\=>C88:9D=BHC?Bggd_gukhgqeBDPXXaNPPQGEKGPZv˜œžœ›™™—’’•Ž”––™–Ž…yssvuyfapmnd`[X[aemn–—¢Ÿžœšš•–•›—”›’“–Ž‘•”’šš™›••–‘””‘—œ—™˜šœ“š›žš˜““›’”˜–”“’‰pYZJBGTRRSLOnht€fVLVWQZRMaofij]^V;;7876;8::9I`w~w{„x‡‹ƒ…|uoeekapub__is{|{qaYYox…‹uyŽ“Ž˜Ÿ®ººÉê‘‘~gs‰ts…Š~coƒ‚‚qpwo„†pTJIJIAAE;BSKOHPScwrtqmpjdid_ZTI9?HEAA8ABC54?;DMHAVou‚‡|ui]YEIW[dnII]PYc[cUWb}Ÿš¡Ÿž¡žš—Ž‰†‡{olpwqolntwq[dYWY`wvjdkpv’š¤¨££žœš™›—–—”—’‘™ˆ{w‰—‘”’‘•””˜—–™š––›˜™›˜”›’—–”—–’‰–’‹–wVYOPJPWO_aZhg†ŠŠr\dQ^WZ]NTcQZhWL>3992989889Nxxqm_Ybfx}uu~ƒpfcag`kjdagpj`ihdfgqwwt’¤­Ÿšš ¶ÌÞÖѵuu¢¤ˆ‚ƒ|hz‡rerz…wps‰mPPOUYGCA?9?CIGNU]ryqg]b[T\^g`hY>G?EEA<8>90A:?BPMGE^plz_SL\R?GDFHMTXwg^dV^KONYŽ’–™‰Š‰ƒ†|uYkrcmcuuwn`kc]MWJRWKcYaknr|Š—£Ÿ«£¤¤œ £¦˜šž¢›—œ™œ‚`oOmŽ„’‘”‘••’‘—“–”›™–™›š—˜“˜–˜””—‹‹†cUHTRbfc{oiyxfvz}}Yf|oVJnR]d9@>9>28:;<9;B\bm{xqvqnjhr|‚‚Œ„‚sa[UaxƒobUTXkyzspqhkxvŽš ¢žš•’§»Îѱ{…§«£›wh|…ƒxjonrkp|zxxskhld]UOKHBDB>B>CDDJU\ZlmptqxygcV?<@=:B?4;:;8:7Mmu†|ehci]]m|~‚ŒzaQRQXfxq[W]diwyzvv‡€„‡œ¡©¤ž“‹†ˆq‡Ž’…‘˜}uu‚ukvvvho„‚€gm‰lkhTIHBDAD<CE[wvyqllbdZYbcUNJ>??>>;QLSZagfqmMG]fM@DOkx`VWMSCGU^ohT\WTLXduxys\ouokcmnjY^PO[PYYYZTLMOV]Z^WZmmj_hgcp|ˆ™¤£¨¥ ’—ŽŸœŸž—˜—ŒŠˆ‘Š“—†•p›qz­Šœ“›˜ œš—œ—•““’˜–“ˆ‰’‚xwƒpebnrftqg~|€zˆ~†‘…‡q~wR;?8=V:?><;:<8?OY`^PLHFkvsuz†„}wfY[RU[_kc]dZ^nw–»­¥¨—~}„•¤¦œ{npŒŒ—’ŽˆƒŠŒlp€zkhkt|usu€rgOMNNPLJDFF@B?@?C^g[^]X`jvutsvnK@GDBJCFr|mtsje^RLTmlskRL[}wTCHGJLTQT\JKFPVY`M[a]XEQMNIILICGGU\YTPXXXSSQKKQKWj`{‹plkagr{„’˜šœ’‘†}{ˆ‘‘ƒŽ‘™ž¢š–––š™——š™ožœ‘š–š™š™˜š™–™’”—›ŽŽ‘x}ƒ|w|„}fgm`n[ZkTebi€tt‹Ž—Ž˜‰|Q<;4C48434575;=FFD=DB6€wtjbhg€’†raUZRhyhnejš¯¼ÃÑɱ§–ƒ„ww„{u‰†{q”‘œ›•vƒ–}…†ˆnosrvn}‹‚sq€ŒgKMFCJI>97::=>=Wbiiirqtlqmd\WN>ESVSKLASm]QX^`keSQj~y~eLIXUCAHQG=C9@D?JTipbb\adi^eje^FCGJKKG;A>HQXrxzx^YNKT\ajlx~[EJIKHAEIWcGGEGGLTSSVOMV\RY`SVSKVQSZ[R\ZYQVKLQUY]lwzfk€aaT_msa]aiypbQ[ft€„‘›Ÿ¢¡Ÿ“™ ž‘–ž›˜Ÿ —šŸšŸŸž¡žŸ–™’–~zynxaXWXjpqxow{`bUEMeWPKTUdmb|rŠ‘˜€N7;020)--./-5D?@B@?GC~uiPTZYXYdkpinyztr€‘¥£ž¦¨©»ÌØÜ¿¥¬‚£¶ÃÏÇ°¨¢˜ŠivzyœŽžµÊÄ£‘€}‚|{it|oyuvqy‡q|†tPHMKHB9??:=89=E[ecjurvcdXS[\]fjtkIKFEJLTefdd}vSJfypnhvjXYlcMF-2-+3++,022ENDUIQVejkk^RUPOZk€pxpo}œ®µ«–‘œ—™¡³ÁÀ«†¶®¬ÀÓÎÖÌ£ ¢—zŠ°À¿ÈÏÌ¿•„’Œ€ow|xez„„upky†~_LTJJ]K@CDPB>EDQmhnm`aQJ@CFcqqtqvy_CPUTPQZ^{vzj@Obceimpwof\HJBHLRTRLITIJH^`LFQSRNLRMFDGCIMJIPKHTKHHFHWedprqrr†‚‚yphŽ’w…–oYd]_TolV[o“”•™£¨§£ ªªžÕ  ¥š›šœ“–¦wdoxŸ‘”_[`iilaTNQT_lq‚|VVqtii[INJK[RfkWqhrtƒaC=240.14,;;;LQFCKEBJmsv{s`TX`fap}xs†“˜¥©¸ºµ§”–‘Š‹xf~®Ç«¤ÁÐÌ·œ€ˆ{†–šœ¼»ÈÍÐÀš˜•|tƒ~…ulv‚Štqtrzmd[blgtnTNLKA>:C;BQVf`g`OCF?Hbgf`[]ekmzvl^U_xjfVO^gvŠ‰€zkdq`[\ZYNFDEMEISUcaK@=BGQPQLAKLLMUWSLNFBOLNRHJPY_efuwrup{z~‚f}yo]PQKQGHVahi“’‡’™œœ§ ¢¦›¬‘ªž›¨¢˜“‘˜›ƒ†”“©ž›¤TTe_TVTLJLFSQ]_yuKMSP`MPIINWkeq`o~p}rl;?41.'.+,800?9C;BPNRwttthWTfpchjkv‰¸Ç»ª¦º¸ºÆ¥•wyˆtii—Œœ´œtzk|±Á½¨¢¤››Ÿ ´ ‰‘’|…}‰zo{vuwuŒzsfxvXkshsbMI;<>8BA>A\€xff[KMNU\dqxmnm|}upa``fbcgzr[N^qmxgaqtl}|YMNDMJSQZ^KJKKITVTKENJPNCHJHCHLTPXbQSJQPAHNRW^h~„{‹wr~}’•–qYrSDJKMGL\rˆ†‡‹—žž¤¨ª¬¢œ’ž¨žž§ ›šž¢ £¤›£¡¢šZ[lUOQHDHBHFGWSqiJM;IFFPNRUcVKY^Ylsi‡`JK950674.8,;GJHCGBLDvmiaklcgqnn|}‚‘œ«ª˜¸¿¹½´§—zt¯«qhls{‰‹lhl}vŽ±ÁѾ¬¢´²šƒ}Ž¨€Ž†wx|rs€‰Žzly{lNVMQXgcFE;ACA?AB\n\[aq}{„x~ˆxui[X\gprmu…€qnlo__BGaktƒ€‡‡mx[N^OR\JCDABDEIT\PGFHGDZXNHHOLMPSPMNJTNOOLMHOROoqwttw|„†‚yƒ‹‚ygcib]TOP[[dŠ‹Š‹’œ £ª«ª«¡­¥¥±®­¨¦Ÿž¦¦©Ÿ¢¢¤ œ£€_SLJLKEDCHIGOXmaLF>@@DLRRLZLGXPadex„‡iIJ=00,66-,-1;AEEMLHOi`Ydxvrml‚©Â¹ž¸²{z}£¨¬©§vzŠ£«¬“unccsw€x~lvÍßáÁ«¥Žˆœ¹À´¦™~z‚ˆŒ~ju{‚~rux|iu‚ZTZ[rl]G9B>??8EXrry{v„yvjbPJ\_kyy‚‡vnlmc[]Zv‚aTg|{€wpffZRZWBJLLOMNWQEQQLOHNNCFONGCFGEIHNQNG[]MCGGGMZN\rz‚‰„wsg_`nv‡‹VR\cpWPP_`r‡stˆ’“˜—žŸ¡¡˜ª¬ª¯«¬¸·«« ¨¦¡¨¡©ª¡{QTLEDENG@>?AAGal[SL?@=>CICHEAIJ`T]xjk„pDMB?>778795?HRWBBEHHjpqrxiz¦ËÎÚĦ±¤•yjjsr‹‘}ozŒ’‹“‘ŽˆhnlwŒ‹‚z€ubrn™×ßÅŠŠ¬¢™¨Àżµ•Š‡|qqzvrvƒ†}qjw‹tPSRY]JLNUTPPJBYvuqwfOY^_chXJansiaac[\dmr}skr€wNRc]blox~‚qXXHKNRZYLJK?EGELGACEECDPJNQORSWPKMKKNOYUOBCHTUT]hvw}ƒ†{elkhmtXGMCWK?MP^\XZSwŠŠœŸžž¡©«©ª©©°´­¬§ª¬ª¢¨¬¦ eQVJDGKCD?;:?MCU]fVTGC>?CB;@::@FNITk^\LD>7>BCUCOTLnlrijm}jHL>:95=86578IHGJ<>HBtrlwŒ•©§¯¼¿¬ªª •‘~gVVSabVg{‹‰ƒ‰t\nŠ—“Ž‰‚‚†„{vlY`ov”¦ª™¤©ž™¦¬ ©§‡}{„vv{}igo~}cjxx{t~uPO][AC?EE[wttmmli{x„sLPOLOOVO\PJKFNFEHEHFGNRDKOPQHDCCIHWcYTXMSHGPShkv{‚„…†„™oVfgg]@GKD67;DOG{«Ÿ¡¨¨¡¤¤¤¥¥£˜Ÿœ¥§¨¨©«£ªŸ¢HKQFGK@D6?<;ADHGBJR\aOB?DFJP?[T\nrj|†q†dGK831-82(/,/CM=F;FZU]_=BUG=JIOfargZIRDKZHURObYZgqmhQ>C4?,0,&+3-9DDWLIQSJƨš©³¤››Ÿ§¡’†ƒ€xŒ’Žˆ„m^c_^[Ychtw{wtv‘¡’‡py¨¡‰œ¨§­±¸ËĪ¥­¦|†tp‚u€†uqxr|igiu~rtzƒzmpeb^SUb\aglxcNSeaZXN@BD^ywuqs]\bFOdlzuz|z[GU[^lu}xs‡iFMJWWVWWWYPUCDRIKRROBECCGIIFOTPGLTNTIBJQKRQLVTX`a|vvqbmxt‰†xtM]MLG8HEX]eTTcz¤¦§§¤¨«¨«­ª©©¦¤££¢£¥ ¥•U„ˆfOFBA?=:85;;FEQ^YjhPJLESUIHSZ„og†ug]H=C96302,294?LFOO@KONã×¼¨ÇÉ­¢™›¡œ•‰–}x†“ˆ’Šn]_\Udnhntwwywy”¡•ˆvsˆ¤¸·¬¡•±°¨­®ÌÙʳ—›ƒvx|€”ƒ~xw„{evtiths|‚vthSTMkwo{wknicaLBNWE?>>;CCWr^OLAB?AKSkv}„ckj\ignvv€…~qtgalW[VJLLNIQs]MXZNEOXIUQONIUDHJFIKQVT`XMOMMRM_vu|}‚…Œ{cfwws~ly‰aM`UFCCVXc\X—£¨«£¨¯¬«ª««ª¬®ª¥¥§£§«¨ª£z¤‹UMPJ;IB::=:=@=;7>DGKF=AA>A=JR]hgljx{v€srzfjhgrpt~jMGPLISZOSXMMJKCTPHHEHBLPKFHJPWRTOMOIHOX]\hz~€~uuomredsŒ€~|UHGQCBF@HO\¤¥¬®«¬©®«¶º°«¨¤™§§¥«¨§¥¬¦Ÿ¨rQJNICDECDNCdbHTSU`UNPFVTpulcYSJJEB:47/33.87>MLRNEH?VÕÔÕÙÑÄÌÅ ƒŽŠ˜¨­£‰‚‚‰‚‡y‘«°§ƒjgffpetzqik{ns–Ž„Ÿ«´À¾º®¶ÐÞâÚÒ­mbedaf}„|~ˆ‡ƒw|ƒƒuiorkq~s|\[YZ]ctlt{}pGELJNSagGCDFJBA9;:7ECDCY{z~vqwlafgiszˆ|†aeXj`UZHLJHNTmb_WHIJNLOP\XVLF@BA?LL[fW][GMRHOPdgtz|utia\]evlVZ^TLKJUYH>Jxt‡£¬«ª¬³£¾á¼°¨¦¦§§§© ¤§¥¢œ§lRM9YVCE@;BMMNPNJLIBF=AD_DGSK[mdN\a?G:@<2025102/<8>DLbWgX[oubRNLM;;;75.150+,04CMIKUYQM™¨ÄžƒxvƒŸ½ÌÛÜàÝÈ«…{fpm{’•ž ¦º·³«vec`b{¨¿Ç¿»Í·Š“†ƒ§ÉÕÀ”~acge`^avbli[c[gqzŽŽŠpv„€yl|ƒ{y{„yjkTI\x†v~z~z{fLKF?=A=JDJB[{M><8:Hhzp}|ea[^[WRIQv~jzbSbup^XKNe]ZcZ[OGSMKRBDICGJQ\[`[Y_JCLIGJPXSNUVU\isrv}„“ŒŠ•‚}~l\jjrOA=?DgŠ¦¤—•–•‘†‡–”¢ž¡¤   š—•œ]HiOc>ESCND@9J=@4=FO@765>>XovoWn}dUSIYXBB>D<,40.,3+>GIS@L[]N|Œ”°˜Š‘¥¸ÅÓÛÖ༂„kbjmx}Ž›™¨·¸²±wi‡ˆ„’´Çº¸Îؾ’‚–‹ƒ”Šwt~‚xdSUl{l^khc^Ycp‚Švlzxwmnls{ƒŽ‚u†{WUqˆmh]NMJJBFHBABB?;E=4>Ro`C>>AHpf[c]]t}nxdcLGUe`jpvwo|WMYWqs]olBHAQ[FJDGILPKJJSKMEHONMPSQRTYYc€~ˆ††…€‡€{{v~…x{uoswhJGEOQSm“—‹•šŸ–™žš££  ˜  —¢aLSNGKdFRRKO?;:<2;;;?-0338HWeb^kl\PGJPcI8I=56..0.:+?JGRCJJM]`~±µ¶¼ŸˆŒ“ž¥·Ã²«¡ž¿¬„{nlio—“ ¥’„˜²À³œ™¸¿ÂÁÊÛĤˆ†uomn|Š—špc\hpfbeh_[Vcoeipwxnuqknu~…y…‹‹iFKJNNJHFHHBA<6>:69;7>?BGdw`C>ECIM^plos‚|nia`mxy~‚|€wh\ZW[TPTXVXZRXYceNMCAEDB?970011.502:=12959HHSMTPVTQ[STNDPF<4:;4/3-=LXJQVELRi„„Ÿ·Ì;›‚‚ugo€¥»ÇÁ²Ÿ…qxƒsi`a`^t…‡ ²¾ÎÓ¼©’Œ µÉÏÖØת}‘dkyƒ„‡”Ÿ™‡f]qld_Z\ST<`€vpiz}tdkgwx†…{zzNGEKAECIIYdTG@BE=;?7@@DXkplgtg_YUU^ov€zpsxf[_QRgqz€qocbhUWRSrcKSQGPSIELNOXVjtovy‡ƒ}…€uwnx†‹‚z|xvu{„Š‡‡|q||tgTVUXOOPbdWo‘Œ”••šž  ›ž™žœ›žš«ŸšŸ]l•^@G534/-/./-//8734526CB@FTSQTLUQIJGI@>D::6;<7EOKTAMKTQ=Sx’¤¾º”qlnlzss”ª­ Ž{qnsia\kw„ƒª±¬·»ÑÅ¢•“šºËǤ‰f…‘dbqs’š¬‹fknZYX[NIHIEGMX\C9;2;CCUMDF<[g[Y_Zpwldcsqxqc^eouxmTYkmjhkswveLMIPVS\ZWLPJMdtqywr{‚zzrismxwxˆ‰ƒ}utprz†‘‡…usu‰†Ž†zbS]_nonjW_cwƒ‹‘”‘•žž•š™˜”š™“—œ£”ª‡p šs<=930.*14.+-//42278354:S[WTQXUTI@MIB9563.880GPDXRTV_^6:Ji}‰oi}{ledo‚ƒˆŽ„ibaj{„‰‘ŽŒ“ž¸·§·ÏÖ¿˜”Ž…pk‘Œo\hfj––”–Ÿ‰qkYWX_GA80EJu~teuqllou{qry€u…qPJ?=>?EE<==@:CDC;7O<7=?P^esmqvlcXZ\`cl{qwzxwacdk|‚‡ymUVWY^RdYLEKLKq|{wthgkjgp|‚‰Œ†zwupex}€„}vyqw~……‚…€zux}‡„mx{w…u`ZKTKl‹…Ž‘‘”˜™•’‘Œ†’“‰Š˜“Ÿ•w ™ˆA;84/*-17/0.*4,4;35674=CJQWWSRTH8EDG:1726466GVT\ZNOT[378@Xs|›‹vˆŽŒ…lmso„‘’““‚dn|ƒ‹•—˜•š»Ýγ¾À¸ª‘‚nmu€ƒŠ{gbmjtnv“ž›˜¡•ddcX]L Date: Fri, 6 Oct 2023 09:52:45 +0700 Subject: [PATCH 2/4] Fix ci build error --- .github/workflows/bench_pr.yml | 10 ++++++---- .github/workflows/bench_push.yml | 8 +++++--- .github/workflows/go.yml | 8 +++++--- pkg/codec/README.md | 8 ++++---- pkg/codec/lib.go | 4 +++- pkg/codec/testdata/data_details.md | 2 +- 6 files changed, 24 insertions(+), 16 deletions(-) diff --git a/.github/workflows/bench_pr.yml b/.github/workflows/bench_pr.yml index 440a5f79..961f3520 100644 --- a/.github/workflows/bench_pr.yml +++ b/.github/workflows/bench_pr.yml @@ -13,13 +13,15 @@ jobs: go-version: 1.22 id: go - - name: Check out code + - name: Check out code uses: actions/checkout@v1 - name: Get dependencies - run: | + run: | + sudo apt-get update + sudo apt-get install -y pkg-config swig libcharls-dev libdcmtk-dev libopenjp2-7-dev go mod download - + - name: Benchmark against GITHUB_BASE_REF run: | go install golang.org/x/perf/cmd/benchstat@latest @@ -32,4 +34,4 @@ jobs: git log -1 --format="%H" go test -bench=. -benchmem -benchtime=10x -count=7 > $HOME/old.txt $GOBIN/benchstat $HOME/old.txt $HOME/new.txt - + diff --git a/.github/workflows/bench_push.yml b/.github/workflows/bench_push.yml index f3cc605f..a037a65c 100644 --- a/.github/workflows/bench_push.yml +++ b/.github/workflows/bench_push.yml @@ -13,13 +13,15 @@ jobs: go-version: 1.22 id: go - - name: Check out code + - name: Check out code uses: actions/checkout@v1 - name: Get dependencies - run: | + run: | + sudo apt-get update + sudo apt-get install -y pkg-config swig libcharls-dev libdcmtk-dev libopenjp2-7-dev go mod download - + - name: Benchmark (against HEAD~1) run: | go install golang.org/x/perf/cmd/benchstat@latest diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index bdd3fe4d..65d16df2 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -13,20 +13,22 @@ jobs: go-version: 1.22 id: go - - name: Check out code + - name: Check out code uses: actions/checkout@v1 - name: Get dependencies run: | + sudo apt-get update + sudo apt-get install -y pkg-config swig libcharls-dev libdcmtk-dev libopenjp2-7-dev go mod download - name: Build run: | make build-fast - + - name: Test run: | make test - + diff --git a/pkg/codec/README.md b/pkg/codec/README.md index 7ab23ec3..dd3f3143 100644 --- a/pkg/codec/README.md +++ b/pkg/codec/README.md @@ -30,10 +30,10 @@ import ( ) func main() { - dataset, err := dicom.ParseFile("testdata/1.dcm", nil) - pixelDataElem, err := dataset.FindElementByTag(tag.PixelData) - pixelData := dicom.MustGetPixelDataInfo(pixelDataElem.Value) - encapsulatedFrame, err := pixelData.Frames[0].GetEncapsulatedFrame() + dataset, err := dicom.ParseFile("testdata/1.dcm", nil) + pixelDataElem, err := dataset.FindElementByTag(tag.PixelData) + pixelData := dicom.MustGetPixelDataInfo(pixelDataElem.Value) + encapsulatedFrame, err := pixelData.Frames[0].GetEncapsulatedFrame() image, err = encapsulatedFrame.GetImage() ... } diff --git a/pkg/codec/lib.go b/pkg/codec/lib.go index af7bd2b5..7d99714b 100644 --- a/pkg/codec/lib.go +++ b/pkg/codec/lib.go @@ -2,5 +2,7 @@ // Copyright (c) 2023 Segmed Inc. package codec -// #cgo pkg-config: libopenjp2 dcmtk charls +// #cgo pkg-config: libopenjp2 charls +// #cgo darwin pkg-config: dcmtk +// #cgo linux LDFLAGS: -ldcmjpeg import "C" diff --git a/pkg/codec/testdata/data_details.md b/pkg/codec/testdata/data_details.md index a7e54155..c38b86f5 100644 --- a/pkg/codec/testdata/data_details.md +++ b/pkg/codec/testdata/data_details.md @@ -28,5 +28,5 @@ be mentioned in one of them for brevity. dcmdump --write-pixel ../pkg/codec/testdata/ 3_jpeg.dcm ``` -#### Files a1_mono.jls and a1_mono.ppm +#### Files a1_mono.j2c and a1_mono.ppm These files were sourced from [openjpeg-data](https://github.com/uclouvain/openjpeg-data) From bf55131909e8e90b0005d79a2ace9e44828d65d6 Mon Sep 17 00:00:00 2001 From: Lam Luong Date: Fri, 19 Jan 2024 15:45:06 +0700 Subject: [PATCH 3/4] Optimize memory usage --- pkg/codec/codec.cxx | 5 +- pkg/codec/decoder.go | 150 +++++++++++++++++++++++--------------- pkg/codec/decoder_test.go | 1 - read.go | 6 +- write_test.go | 8 +- 5 files changed, 102 insertions(+), 68 deletions(-) diff --git a/pkg/codec/codec.cxx b/pkg/codec/codec.cxx index a61f1465..5956b2de 100644 --- a/pkg/codec/codec.cxx +++ b/pkg/codec/codec.cxx @@ -173,13 +173,12 @@ unsigned char * J2K_Decode(unsigned char * dataSrc, size_t length, int width, in void *vOutBits = NULL; OPJ_INT32 * ptr; int adjustR, bitsAllocated; + adjustR = 0; bitsAllocated = image->comps[0].prec; if (bitsAllocated == 8) { BYTE v; BYTE *newdata = new BYTE[image->x1*image->y1*image->numcomps]; for (unsigned int c=0; cnumcomps; c++) { - adjustR = - (image->comps[c].sgnd ? 1 << (bitsAllocated - 1) : 0); ptr = (OPJ_INT32 *)image->comps[c].data; for (unsigned int i = 0; i< image->x1*image->y1; i++){ v = (BYTE) (*ptr + adjustR); @@ -192,8 +191,6 @@ unsigned char * J2K_Decode(unsigned char * dataSrc, size_t length, int width, in OPJ_UINT16 v; OPJ_UINT16 *newdata = new OPJ_UINT16[image->x1*image->y1*image->numcomps]; for (unsigned int c=0; cnumcomps; c++) { - adjustR = - (image->comps[c].sgnd ? 1 << (bitsAllocated - 1) : 0); ptr = (OPJ_INT32 *)image->comps[c].data; for (unsigned int i = 0; i< image->x1*image->y1; i++){ v = (OPJ_UINT16) (*ptr + adjustR); diff --git a/pkg/codec/decoder.go b/pkg/codec/decoder.go index 49de6d0a..3dae38ea 100644 --- a/pkg/codec/decoder.go +++ b/pkg/codec/decoder.go @@ -56,87 +56,121 @@ func GetNativePixelData(e frame.EncapsulatedFrame) ([]byte, error) { // GetStdImage returns the converted image in Go standard format func GetStdImage(e frame.EncapsulatedFrame) (image.Image, error) { - buf := bytes.NewBuffer(e.Data) - r := dicomio.NewReader(bufio.NewReader(buf), binary.LittleEndian, int64(len(e.Data))) var ( - upLeft = image.Point{0, 0} - lowRight = image.Point{e.Cols, e.Rows} - img8 = image.NewRGBA(image.Rectangle{upLeft, lowRight}) - img16 = image.NewRGBA64(image.Rectangle{upLeft, lowRight}) - samplesPerPixel int - values8 [3]uint8 // red, green, blue - values16 [3]uint16 - cols = e.Cols - a = 0xffff - i = 0 + upLeft = image.Point{0, 0} + lowRight = image.Point{e.Cols, e.Rows} + img8 = image.NewRGBA(image.Rectangle{upLeft, lowRight}) + img16 = image.NewRGBA64(image.Rectangle{upLeft, lowRight}) + cols = e.Cols + a = 0xffff + pixelValues = make([]int, e.SamplesPerPixel) ) - if e.BitsAllocated == 8 { - for !r.IsLimitExhausted() { - i++ - v, err := r.ReadUInt8() - if err != nil { - return nil, fmt.Errorf("read uint8 failed: %w", err) + decodedBytes, err := GetNativePixelData(e) + if err != nil { + return nil, fmt.Errorf("decode pixeldata: %w", err) + } + buf := bytes.NewBuffer(decodedBytes) + r := dicomio.NewReader(bufio.NewReader(buf), binary.LittleEndian, int64(buf.Len())) + oneByte := e.BitsAllocated == 8 + for i := 0; i < e.Cols*e.Rows; i++ { + var clr color.Color + err := readPixelValues(e, *r, pixelValues) + if err != nil { + return nil, fmt.Errorf("read pixel values: %w", err) + } + switch e.SamplesPerPixel { + case 1: + r := pixelValues[0] + if oneByte { + clr = color.Gray{Y: uint8(r)} + } else { + clr = color.Gray16{Y: uint16(r)} } - values8[samplesPerPixel%3] = v - samplesPerPixel++ - if samplesPerPixel < e.SamplesPerPixel { - continue + case 3: + r, g, b := pixelValues[0], pixelValues[1], pixelValues[2] + if oneByte { + clr = color.RGBA{uint8(r), uint8(g), uint8(b), uint8(a)} + } else { + clr = color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)} } - var clr color.Color - switch samplesPerPixel { - case 1: - clr = color.Gray{Y: values8[0]} - case 3: - r, g, b := values8[0], values8[1], values8[2] - clr = color.RGBA{r, g, b, uint8(a)} + case 4: + r, g, b, a := pixelValues[0], pixelValues[1], pixelValues[2], pixelValues[3] + if oneByte { + clr = color.RGBA{uint8(r), uint8(g), uint8(b), uint8(a)} + } else { + clr = color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)} } + } + if oneByte { img8.Set(i%cols, i/cols, clr) - samplesPerPixel = 0 + } else { + img16.Set(i%cols, i/cols, clr) } + } + if oneByte { return img8, nil } - for !r.IsLimitExhausted() { - i++ - v, err := r.ReadUInt16() - if err != nil { - return nil, fmt.Errorf("read uint16 failed: %w", err) - } - values16[samplesPerPixel%3] = v - samplesPerPixel++ - if samplesPerPixel < e.SamplesPerPixel { - continue + return img16, nil +} + +func readPixelValues(e frame.EncapsulatedFrame, r dicomio.Reader, pixelValues []int) error { + for sample := 0; sample < e.SamplesPerPixel; sample++ { + if r.IsLimitExhausted() { + break } - var clr color.Color - switch samplesPerPixel { - case 1: - clr = color.Gray16{Y: values16[0]} - case 3: - r, g, b := values16[0], values16[1], values16[2] - clr = color.RGBA64{r, g, b, uint16(a)} + switch e.BitsAllocated { + case 8: + v, err := r.ReadUInt8() + if err != nil { + return fmt.Errorf("read uint8 failed: %w", err) + } + pixelValues[sample] = int(v) + case 16: + v, err := r.ReadUInt16() + if err != nil { + return fmt.Errorf("read uint16 failed: %w", err) + } + pixelValues[sample] = int(v) + case 32: + v, err := r.ReadUInt32() + if err != nil { + return fmt.Errorf("read uint32 failed: %w", err) + } + pixelValues[sample] = int(v) + default: + return fmt.Errorf("bitsAllocated not supported: %d", e.BitsAllocated) } - img16.Set(i%cols, i/cols, clr) - samplesPerPixel = 0 } - return img16, nil + return nil } // Decode reads a JPEG image from EncapsulatedFrame and returns it as an NativeFrame. func Decode(e frame.EncapsulatedFrame) (frame.NativeFrame, error) { - img, err := GetStdImage(e) + var nativeData = make([][]int, e.Cols*e.Rows) + decodedBytes, err := GetNativePixelData(e) if err != nil { - return frame.NativeFrame{}, fmt.Errorf("get Go's std image: %w", err) + return frame.NativeFrame{}, fmt.Errorf("decode pixeldata: %w", err) } - var nativeData [][]int + buf := bytes.NewBuffer(decodedBytes) + r := dicomio.NewReader(bufio.NewReader(buf), binary.LittleEndian, int64(buf.Len())) + var ( + pixelValues = make([]int, e.SamplesPerPixel) + ) for i := 0; i < e.Cols*e.Rows; i++ { - clr := img.At(i%e.Cols, i/e.Cols) - r, g, b, a := clr.RGBA() + err := readPixelValues(e, *r, pixelValues) + if err != nil { + return frame.NativeFrame{}, fmt.Errorf("read pixel values: %w", err) + } switch e.SamplesPerPixel { case 1: - nativeData = append(nativeData, []int{int(r)}) + r := pixelValues[0] + nativeData[i] = []int{int(r)} case 3: - nativeData = append(nativeData, []int{int(r), int(g), int(b)}) + r, g, b := pixelValues[0], pixelValues[1], pixelValues[2] + nativeData[i] = []int{int(r), int(g), int(b)} case 4: - nativeData = append(nativeData, []int{int(r), int(g), int(b), int(a)}) + r, g, b, a := pixelValues[0], pixelValues[1], pixelValues[2], pixelValues[3] + nativeData[i] = []int{int(r), int(g), int(b), int(a)} } } nf := frame.NativeFrame{ diff --git a/pkg/codec/decoder_test.go b/pkg/codec/decoder_test.go index e27c68a8..51604a86 100644 --- a/pkg/codec/decoder_test.go +++ b/pkg/codec/decoder_test.go @@ -105,7 +105,6 @@ func assertJPEGDecompressing(t *testing.T, tc testify) { t.Fatal("failed to decode image") } - fr.Data = uncompressedBytes img, err := GetStdImage(fr) if err != nil { t.Fatal(err) diff --git a/read.go b/read.go index a3f7fcfe..82406557 100644 --- a/read.go +++ b/read.go @@ -239,7 +239,7 @@ func (r *reader) readHeader() ([]*Element, error) { return metaElems, nil } -func newEncapsulatedFrame(d *Dataset, data []byte) (*frame.Frame, error) { +func NewEncapsulatedFrame(d *Dataset, data []byte) (*frame.Frame, error) { e := frame.EncapsulatedFrame{ Data: data, } @@ -312,7 +312,7 @@ func (r *reader) readPixelData(vl uint32, d *Dataset, fc chan<- *frame.Frame) (V break } - f, err := newEncapsulatedFrame(d, data) + f, err := NewEncapsulatedFrame(d, data) if err != nil { break } @@ -410,7 +410,7 @@ func makeErrorPixelData(d *Dataset, reader io.Reader, vl uint32, fc chan<- *fram return nil, fmt.Errorf("makeErrorPixelData: read pixelData: %w", err) } - f, err := newEncapsulatedFrame(d, data) + f, err := NewEncapsulatedFrame(d, data) if err != nil { return nil, err } diff --git a/write_test.go b/write_test.go index 3a7a3045..492aef15 100644 --- a/write_test.go +++ b/write_test.go @@ -411,8 +411,12 @@ func TestWrite(t *testing.T) { IsEncapsulated: true, Frames: []*frame.Frame{ { - Encapsulated: true, - EncapsulatedData: frame.EncapsulatedFrame{Data: []byte{1, 2, 3, 4}}, + Encapsulated: true, + EncapsulatedData: frame.EncapsulatedFrame{ + Data: []byte{1, 2, 3, 4}, + TransferSyntax: uid.ExplicitVRLittleEndian, + BitsAllocated: 8, + }, }, }, }), From 4223d14ed45d78a19f6182b8e9147e05e1a0d7fd Mon Sep 17 00:00:00 2001 From: Lam Luong Date: Tue, 30 Jul 2024 20:26:17 +0700 Subject: [PATCH 4/4] update README --- pkg/codec/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/codec/README.md b/pkg/codec/README.md index dd3f3143..90f93dc7 100644 --- a/pkg/codec/README.md +++ b/pkg/codec/README.md @@ -25,8 +25,8 @@ swig -go -cgo -c++ -intgosize 64 codec.i ```go import ( "github.com/suyashkumar/dicom" - _ "github.com/suyashkumar/dicom/pkg/codec" "github.com/suyashkumar/dicom/pkg/tag" + _ "github.com/suyashkumar/dicom/pkg/codec" ) func main() {