From 15d152639374437e86a8342605a77b1a241af86f Mon Sep 17 00:00:00 2001 From: simnandez <jmenent@2byte.es> Date: Fri, 27 Jan 2012 17:41:47 +0100 Subject: [PATCH] [ task #176 ] Allow to use ODT templates. Works with Orders --- htdocs/admin/commande.php | 199 +++---- .../doc/doc_generic_order_odt.modules.php | 495 ++++++++++++++++++ .../commande/{ => doc}/pdf_edison.modules.php | 0 .../{ => doc}/pdf_einstein.modules.php | 0 .../modules/commande/modules_commande.php | 86 +-- htdocs/core/modules/modCommande.class.php | 8 + .../doctemplates/orders/template_order.odt | Bin 0 -> 24494 bytes 7 files changed, 659 insertions(+), 129 deletions(-) create mode 100644 htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php rename htdocs/core/modules/commande/{ => doc}/pdf_edison.modules.php (100%) rename htdocs/core/modules/commande/{ => doc}/pdf_einstein.modules.php (100%) create mode 100644 htdocs/install/doctemplates/orders/template_order.odt diff --git a/htdocs/admin/commande.php b/htdocs/admin/commande.php index 31756a2c67f..705fcf35365 100644 --- a/htdocs/admin/commande.php +++ b/htdocs/admin/commande.php @@ -6,7 +6,7 @@ * Copyright (C) 2004 Andre Cianfarani <acianfa@free.fr> * Copyright (C) 2005-2011 Regis Houssin <regis@dolibarr.fr> * Copyright (C) 2008 Raphael Bertrand (Resultic) <raphael.bertrand@resultic.fr> - * Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es> + * Copyright (C) 2011-2012 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2011 Philippe Grand <philippe.grand@atoo-net.com> * * This program is free software; you can redistribute it and/or modify @@ -375,98 +375,119 @@ print "</tr>\n"; clearstatcache(); +$var=true; foreach ($conf->file->dol_document_root as $dirroot) { - $dir = $dirroot . "/core/modules/commande/"; - - if (is_dir($dir)) - { - $handle = opendir($dir); - if (is_resource($handle)) - { - $var=true; - while (($file = readdir($handle))!==false) - { - if (preg_match('/\.modules\.php$/i',$file) && substr($file,0,4) == 'pdf_') - { - $name = substr($file, 4, dol_strlen($file) -16); - $classname = substr($file, 0, dol_strlen($file) -12); - - $var=!$var; - print "<tr ".$bc[$var].">\n <td>"; - print "$name"; - print "</td>\n <td>\n"; - require_once($dir.$file); - $module = new $classname($db); - print $module->description; - print "</td>\n"; - - // Activated - print "<td align=\"center\">\n"; - if (in_array($name, $def)) - { - //if ($conf->global->COMMANDE_ADDON_PDF != "$name") - //{ - print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'">'; - print img_picto($langs->trans("Activated"),'switch_on'); - print '</a>'; - //} - //else - //{ - // print img_picto($langs->trans("Activated"),'switch_on'); - //} - } - else - { - print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'">'; - print img_picto($langs->trans("Disabled"),'switch_off'); - print '</a>'; - } - print "</td>"; - - // Defaut - print "<td align=\"center\">"; - if ($conf->global->COMMANDE_ADDON_PDF == "$name") - { - print img_picto($langs->trans("Yes"),'on'); - } - else - { - print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'">'; - print img_picto($langs->trans("No"),'off'); - print '</a>'; - } - print '</td>'; - - // Info - $htmltooltip = ''.$langs->trans("Name").': '.$module->name; - $htmltooltip.='<br>'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); - if ($module->type == 'pdf') + foreach (array('','/doc') as $valdir) + { + $dir = $dirroot . "/core/modules/commande".$valdir; + + if (is_dir($dir)) + { + $handle=opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle))!==false) + { + $filelist[]=$file; + } + closedir($handle); + + foreach($filelist as $file) + { + if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file)) { - $htmltooltip.='<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + if (file_exists($dir.'/'.$file)) + { + $name = substr($file, 4, dol_strlen($file) -16); + $classname = substr($file, 0, dol_strlen($file) -12); + + require_once($dir.'/'.$file); + $module = new $classname($db); + + $modulequalified=1; + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified=0; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified=0; + + if ($modulequalified) + { + $var = !$var; + print '<tr '.$bc[$var].'><td width="100">'; + print (empty($module->name)?$name:$module->name); + print "</td><td>\n"; + if (method_exists($module,'info')) print $module->info($langs); + else print $module->description; + print '</td>'; + + // Active + if (in_array($name, $def)) + { + print '<td align="center">'."\n"; + print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&value='.$name.'">'; + print img_picto($langs->trans("Enabled"),'switch_on'); + print '</a>'; + print '</td>'; + } + else + { + print "<td align=\"center\">\n"; + print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').'</a>'; + print "</td>"; + } + + // Defaut + print "<td align=\"center\">"; + if ($conf->global->PROPALE_ADDON_PDF == "$name") + { + print img_picto($langs->trans("Default"),'on'); + } + else + { + print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').'</a>'; + } + print '</td>'; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip.='<br>'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); + if ($module->type == 'pdf') + { + $htmltooltip.='<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + } + $htmltooltip.='<br><br><u>'.$langs->trans("FeaturesSupported").':</u>'; + $htmltooltip.='<br>'.$langs->trans("Logo").': '.yn($module->option_logo,1,1); + $htmltooltip.='<br>'.$langs->trans("PaymentMode").': '.yn($module->option_modereg,1,1); + $htmltooltip.='<br>'.$langs->trans("PaymentConditions").': '.yn($module->option_condreg,1,1); + $htmltooltip.='<br>'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang,1,1); + //$htmltooltip.='<br>'.$langs->trans("Escompte").': '.yn($module->option_escompte,1,1); + //$htmltooltip.='<br>'.$langs->trans("CreditNote").': '.yn($module->option_credit_note,1,1); + $htmltooltip.='<br>'.$langs->trans("WatermarkOnDraftOrders").': '.yn($module->option_draft_watermark,1,1); + + + print '<td align="center">'; + print $form->textwithpicto('',$htmltooltip,1,0); + print '</td>'; + + // Preview + print '<td align="center">'; + if ($module->type == 'pdf') + { + print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'">'.img_object($langs->trans("Preview"),'bill').'</a>'; + } + else + { + print img_object($langs->trans("PreviewNotAvailable"),'generic'); + } + print '</td>'; + + print "</tr>\n"; + } + } } - $htmltooltip.='<br><br><u>'.$langs->trans("FeaturesSupported").':</u>'; - $htmltooltip.='<br>'.$langs->trans("Logo").': '.yn($module->option_logo,1,1); - $htmltooltip.='<br>'.$langs->trans("PaymentMode").': '.yn($module->option_modereg,1,1); - $htmltooltip.='<br>'.$langs->trans("PaymentConditions").': '.yn($module->option_condreg,1,1); - $htmltooltip.='<br>'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang,1,1); - //$htmltooltip.='<br>'.$langs->trans("Escompte").': '.yn($module->option_escompte,1,1); - //$htmltooltip.='<br>'.$langs->trans("CreditNote").': '.yn($module->option_credit_note,1,1); - $htmltooltip.='<br>'.$langs->trans("WatermarkOnDraftOrders").': '.yn($module->option_draft_watermark,1,1); - - print '<td align="center">'; - print $form->textwithpicto('',$htmltooltip,1,0); - print '</td>'; - print '<td align="center">'; - print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'">'.img_object($langs->trans("Preview"),'order').'</a>'; - print '</td>'; - - print "</tr>\n"; - } - } - closedir($handle); - } - } + } + } + } + } } print '</table>'; diff --git a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php new file mode 100644 index 00000000000..8c2493730e0 --- /dev/null +++ b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php @@ -0,0 +1,495 @@ +<?php +/* Copyright (C) 2010-2011 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2012 Juanjo Menent <jmenent@2byte.es> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/commande/doc_generic_order_odt.modules.php + * \ingroup societe + * \brief File of class to build ODT documents for third parties + */ + +require_once(DOL_DOCUMENT_ROOT."/core/modules/commande/modules_commande.php"); +require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/company.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/functions2.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); + + +/** + * \class doc_generic_order_odt + * \brief Class to build documents using ODF templates generator + */ +class doc_generic_order_odt extends ModelePDFCommandes +{ + var $emetteur; // Objet societe qui emet + + var $phpmin = array(5,2,0); // Minimum version of PHP required by module + var $version = 'development'; + + + /** + * Constructor + * + * @param DoliDB $DB Database handler + */ + function doc_generic_order_odt($db) + { + global $conf,$langs,$mysoc; + + $langs->load("main"); + $langs->load("companies"); + + $this->db = $db; + $this->name = "ODT templates"; + $this->description = $langs->trans("DocumentModelOdt"); + $this->scandir = 'COMMANDE_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan + + // Dimension page pour format A4 + $this->type = 'odt'; + $this->page_largeur = 0; + $this->page_hauteur = 0; + $this->format = array($this->page_largeur,$this->page_hauteur); + $this->marge_gauche=0; + $this->marge_droite=0; + $this->marge_haute=0; + $this->marge_basse=0; + + $this->option_logo = 1; // Affiche logo + $this->option_tva = 0; // Gere option tva COMMANDE_TVAOPTION + $this->option_modereg = 0; // Affiche mode reglement + $this->option_condreg = 0; // Affiche conditions reglement + $this->option_codeproduitservice = 0; // Affiche code produit-service + $this->option_multilang = 0; // Dispo en plusieurs langues + $this->option_escompte = 0; // Affiche si il y a eu escompte + $this->option_credit_note = 0; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 0; // Support add of a watermark on drafts + + // Recupere emetteur + $this->emetteur=$mysoc; + if (! $this->emetteur->pays_code) $this->emetteur->pays_code=substr($langs->defaultlang,-2); // Par defaut, si n'etait pas defini + } + + + /** + * Define array with couple substitution key => substitution value + * + * @param Object $object Main object to use as data source + * @param Translate $outputlangs Lang object to use for output + */ + function get_substitutionarray_object($object,$outputlangs) + { + global $conf; + + return array( + 'object_id'=>$object->id, + 'object_ref'=>$object->ref, + 'object_ref_ext'=>$object->ref_ext, + 'object_ref_customer'=>$object->ref_client, + 'object_date'=>dol_print_date($object->date,'day'), + 'object_fin_validite'=>dol_print_date($object->fin_validite,'dayhour'), + 'object_date_creation'=>dol_print_date($object->date_creation,'day'), + 'object_date_modification'=>dol_print_date($object->date_modification,'day'), + 'object_date_validation'=>dol_print_date($object->date_validation,'dayhour'), + 'object_payment_mode'=>$object->mode_reglement, + 'object_payment_term'=>$object->cond_reglement, + 'object_total_ht'=>price($object->total_ht,0,$outputlangs), + 'object_total_vat'=>price($object->total_tva,0,$outputlangs), + 'object_total_ttc'=>price($object->total_ttc,0,$outputlangs), + 'object_vatrate'=>vatrate($object->tva), + 'object_note_private'=>$object->note, + 'object_note'=>$object->note_public, + ); + } + + /** + * Define array with couple substitution key => substitution value + * + * @param array $line + * @param Translate $outputlangs Lang object to use for output + */ + function get_substitutionarray_lines($line,$outputlangs) + { + global $conf; + + return array( + 'line_fulldesc'=>$line->product_ref.(($line->product_ref && $line->desc)?' - ':'').$line->desc, + 'line_product_ref'=>$line->product_ref, + 'line_desc'=>$line->desc, + 'line_vatrate'=>vatrate($line->tva_tx,true,$line->info_bits), + 'line_up'=>price($line->subprice, 0, $outputlangs), + 'line_qty'=>$line->qty, + 'line_discount_percent'=>($line->remise_percent?$line->remise_percent.'%':''), + 'line_price_ht'=>price($line->total_ht, 0, $outputlangs), + 'line_price_ttc'=>price($line->total_ttc, 0, $outputlangs), + 'line_price_vat'=>price($line->total_tva, 0, $outputlangs), + 'line_date_start'=>$line->date_start, + 'line_date_end'=>$line->date_end + ); + } + + /** + * Return description of a module + * @param langs Lang object to use for output + * @return string Description + */ + function info($langs) + { + global $conf,$langs; + + $langs->load("companies"); + $langs->load("errors"); + + $form = new Form($this->db); + + $texte = $this->description.".<br>\n"; + $texte.= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">'; + $texte.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + $texte.= '<input type="hidden" name="action" value="setModuleOptions">'; + $texte.= '<input type="hidden" name="param1" value="COMMANDE_ADDON_PDF_ODT_PATH">'; + $texte.= '<table class="nobordernopadding" width="100%">'; + + // List of directories area + $texte.= '<tr><td>'; + $texttitle=$langs->trans("ListOfDirectories"); + $listofdir=explode(',',preg_replace('/[\r\n]+/',',',trim($conf->global->COMMANDE_ADDON_PDF_ODT_PATH))); + $listoffiles=array(); + foreach($listofdir as $key=>$tmpdir) + { + $tmpdir=trim($tmpdir); + $tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir); + if (! $tmpdir) { unset($listofdir[$key]); continue; } + if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0); + else + { + $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.odt'); + if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); + } + } + $texthelp=$langs->trans("ListOfDirectoriesForModelGenODT"); + // Add list of substitution keys + $texthelp.='<br>'.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'<br>'; + $texthelp.=$langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it + + $texte.= $form->textwithpicto($texttitle,$texthelp,1,'help','',1); + $texte.= '<table><tr><td>'; + $texte.= '<textarea class="flat" cols="60" name="value1">'; + $texte.=$conf->global->COMMANDE_ADDON_PDF_ODT_PATH; + $texte.= '</textarea>'; + $texte.= '</td>'; + $texte.= '<td align="center"> '; + $texte.= '<input type="submit" class="button" value="'.$langs->trans("Modify").'" name="Button">'; + $texte.= '</td>'; + $texte.= '</tr>'; + $texte.= '</table>'; + + // Scan directories + if (count($listofdir)) $texte.=$langs->trans("NumberOfModelFilesFound").': <b>'.count($listoffiles).'</b>'; + + $texte.= '</td>'; + + + $texte.= '<td valign="top" rowspan="2">'; + $texte.= $langs->trans("ExampleOfDirectoriesForModelGen"); + $texte.= '</td>'; + $texte.= '</tr>'; + + /*$texte.= '<tr>'; + $texte.= '<td align="center">'; + $texte.= '<input type="submit" class="button" value="'.$langs->trans("Modify").'" name="Button">'; + $texte.= '</td>'; + $texte.= '</tr>';*/ + + $texte.= '</table>'; + $texte.= '</form>'; + + return $texte; + } + + /** + * Function to build a document on disk using the generic odt module. + * + * @param Commande $object Object source to build document + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @return int 1 if OK, <=0 if KO + */ + function write_file($object,$outputlangs,$srctemplatepath) + { + global $user,$langs,$conf,$mysoc; + + if (empty($srctemplatepath)) + { + dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING); + return -1; + } + + if (! is_object($outputlangs)) $outputlangs=$langs; + $sav_charset_output=$outputlangs->charset_output; + $outputlangs->charset_output='UTF-8'; + + $outputlangs->load("main"); + $outputlangs->load("dict"); + $outputlangs->load("companies"); + $outputlangs->load("bills"); + + if ($conf->commande->dir_output) + { + // If $object is id instead of object + if (! is_object($object)) + { + $id = $object; + $object = new Commande($this->db); + $result=$object->fetch($id); + if ($result < 0) + { + dol_print_error($this->db,$object->error); + return -1; + } + } + + $dir = $conf->commande->dir_output; + $objectref = dol_sanitizeFileName($object->ref); + if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref; + $file = $dir . "/" . $objectref . ".odt"; + + if (! file_exists($dir)) + { + if (create_exdir($dir) < 0) + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + if (file_exists($dir)) + { + //print "srctemplatepath=".$srctemplatepath; // Src filename + $newfile=basename($srctemplatepath); + $newfiletmp=preg_replace('/\.odt/i','',$newfile); + $newfiletmp=preg_replace('/template_/i','',$newfiletmp); + $newfiletmp=preg_replace('/modele_/i','',$newfiletmp); + $newfiletmp=$objectref.'_'.$newfiletmp; + //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt'; + $file=$dir.'/'.$newfiletmp.'.odt'; + //print "newdir=".$dir; + //print "newfile=".$newfile; + //print "file=".$file; + //print "conf->societe->dir_temp=".$conf->societe->dir_temp; + + create_exdir($conf->commande->dir_temp); + + + // If BILLING contact defined on invoice, we use it + $usecontact=false; + $arrayidcontact=$object->getIdContact('external','BILLING'); + if (count($arrayidcontact) > 0) + { + $usecontact=true; + $result=$object->fetch_contact($arrayidcontact[0]); + } + + // Recipient name + if (! empty($usecontact)) + { + // On peut utiliser le nom de la societe du contact + if ($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) $socobject = $object->contact; + else $socobject = $object->client; + } + else + { + $socobject=$object->client; + } + + // Make substitution + $substitutionarray=array( + '__FROM_NAME__' => $this->emetteur->nom, + '__FROM_EMAIL__' => $this->emetteur->email, + '__TOTAL_TTC__' => $object->total_ttc, + '__TOTAL_HT__' => $object->total_ht, + '__TOTAL_VAT__' => $object->total_vat + ); + complete_substitutions_array($substitutionarray, $langs, $object); + + // Line of free text + $newfreetext=''; + $paramfreetext='COMMANDE_FREE_TEXT'; + if (! empty($conf->global->$paramfreetext)) + { + $newfreetext=make_substitutions($conf->global->$paramfreetext,$substitutionarray); + } + + // Open and load template + require_once(ODTPHP_PATH.'odf.php'); + $odfHandler = new odf($srctemplatepath, array( + 'PATH_TO_TMP' => $conf->commande->dir_temp, + 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}') + ); + // After construction $odfHandler->contentXml contains content and + // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by + // [!-- BEGIN lines --]*[!-- END lines --] + //print html_entity_decode($odfHandler->__toString()); + //print exit; + + + // Make substitutions into odt of freetext + try { + $odfHandler->setVars('free_text', $newfreetext, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + + // Make substitutions into odt of user info + $tmparray=$this->get_substitutionarray_user($user,$outputlangs); + //var_dump($tmparray); exit; + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + //var_dump($value);exit; + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + // Make substitutions into odt of mysoc + $tmparray=$this->get_substitutionarray_mysoc($mysoc,$outputlangs); + //var_dump($tmparray); exit; + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + //var_dump($value);exit; + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + // Make substitutions into odt of thirdparty + $tmparray=$this->get_substitutionarray_thirdparty($socobject,$outputlangs); + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + // Replace tags of object + external modules + $tmparray=$this->get_substitutionarray_object($object,$outputlangs); + complete_substitutions_array($tmparray, $outputlangs, $object); + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + // Replace tags of lines + try + { + $listlines = $odfHandler->setSegment('lines'); + foreach ($object->lines as $line) + { + $tmparray=$this->get_substitutionarray_lines($line,$outputlangs); + foreach($tmparray as $key => $val) + { + try + { + $listlines->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlines->merge(); + } + $odfHandler->mergeSegment($listlines); + } + catch(OdfException $e) + { + $this->error=$e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } + + // Write new file + //$result=$odfHandler->exportAsAttachedFile('toto'); + $odfHandler->saveToDisk($file); + + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $odfHandler=null; // Destroy object + + return 1; // Success + } + else + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + return -1; + } + +} + +?> diff --git a/htdocs/core/modules/commande/pdf_edison.modules.php b/htdocs/core/modules/commande/doc/pdf_edison.modules.php similarity index 100% rename from htdocs/core/modules/commande/pdf_edison.modules.php rename to htdocs/core/modules/commande/doc/pdf_edison.modules.php diff --git a/htdocs/core/modules/commande/pdf_einstein.modules.php b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php similarity index 100% rename from htdocs/core/modules/commande/pdf_einstein.modules.php rename to htdocs/core/modules/commande/doc/pdf_einstein.modules.php diff --git a/htdocs/core/modules/commande/modules_commande.php b/htdocs/core/modules/commande/modules_commande.php index 00d3d858f9a..f0a282725ad 100644 --- a/htdocs/core/modules/commande/modules_commande.php +++ b/htdocs/core/modules/commande/modules_commande.php @@ -4,6 +4,7 @@ * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com> * Copyright (C) 2005-2011 Regis Houssin <regis@dolibarr.fr> * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr> + * Copyright (C) 2012 Juanjo Menent <jmenent@2byte.es> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -156,46 +157,55 @@ function commande_pdf_create($db, $object, $modele, $outputlangs, $hidedetails=0 $langs->load("orders"); $error=0; - + $dir = "/core/modules/commande/"; $srctemplatepath=''; - $modelisok=0; - $liste=array(); - - // Positionne modele sur le nom du modele de commande a utiliser - $file = "pdf_".$modele.".modules.php"; - // On verifie l'emplacement du modele - $file = dol_buildpath($dir.$file); - if ($modele && file_exists($file)) $modelisok=1; - // Si model pas encore bon - if (! $modelisok) + // Positionne le modele sur le nom du modele a utiliser + if (! dol_strlen($modele)) { - if ($conf->global->COMMANDE_ADDON_PDF) $modele = $conf->global->COMMANDE_ADDON_PDF; - $file = "pdf_".$modele.".modules.php"; - // On verifie l'emplacement du modele - $file = dol_buildpath($dir.$file); - if (file_exists($file)) $modelisok=1; + if (! empty($conf->global->COMMANDE_ADDON_PDF)) + { + $modele = $conf->global->COMMANDE_ADDON_PDF; + } + else + { + $modele = 'einstein'; + } } - // Si model pas encore bon - if (! $modelisok) + // If selected modele is a filename template (then $modele="modelname:filename") + $tmp=explode(':',$modele,2); + if (! empty($tmp[1])) + { + $modele=$tmp[0]; + $srctemplatepath=$tmp[1]; + } + + // Search template file + $file=''; $classname=''; $filefound=0; + foreach(array('doc','pdf') as $prefix) { - $liste=ModelePDFCommandes::liste_modeles($db); - $modele=key($liste); // Renvoie premiere valeur de cle trouvee dans le tableau - $file = "pdf_".$modele.".modules.php"; - // On verifie l'emplacement du modele - $file = dol_buildpath($dir.$file); - if (file_exists($file)) $modelisok=1; + $file = $prefix."_".$modele.".modules.php"; + + // On verifie l'emplacement du modele + $file = dol_buildpath($dir.'doc/'.$file); + + if (file_exists($file)) + { + $filefound=1; + $classname=$prefix.'_'.$modele; + break; + } } // Charge le modele - if ($modelisok) + if ($filefound) { - $classname = "pdf_".$modele; require_once($file); $obj = new $classname($db); + $obj->message = $message; // We save charset_output to restore it because write_file can change it if needed for // output format that does not support UTF8. @@ -204,10 +214,13 @@ function commande_pdf_create($db, $object, $modele, $outputlangs, $hidedetails=0 { $outputlangs->charset_output=$sav_charset_output; - // we delete preview files - require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); + // We delete old preview + require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); dol_delete_preview($object); + // Success in building document. We build meta file. + dol_meta_create($object); + // Appel des triggers include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php"); $interface=new Interfaces($db); @@ -220,22 +233,15 @@ function commande_pdf_create($db, $object, $modele, $outputlangs, $hidedetails=0 else { $outputlangs->charset_output=$sav_charset_output; - dol_syslog("Error"); - dol_print_error($db,$obj->error); - return 0; + dol_print_error($db,"order_pdf_create Error: ".$obj->error); + return -1; } + } else { - if (! $conf->global->COMMANDE_ADDON_PDF) - { - print $langs->trans("Error")." ".$langs->trans("Error_COMMANDE_ADDON_PDF_NotDefined"); - } - else - { - print $langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists",$file); - } - return 0; + dol_print_error('',$langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists",$file)); + return -1; } } ?> diff --git a/htdocs/core/modules/modCommande.class.php b/htdocs/core/modules/modCommande.class.php index 64ac2ec3c2b..4ce90bc9178 100644 --- a/htdocs/core/modules/modCommande.class.php +++ b/htdocs/core/modules/modCommande.class.php @@ -5,6 +5,7 @@ * Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be> * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com> * Copyright (C) 2005-2011 Regis Houssin <regis@dolibarr.fr> + * Copyright (C) 2012 Juanjo Menent <jmenent@2byte.es> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -89,6 +90,13 @@ class modCommande extends DolibarrModules $this->const[$r][2] = "mod_commande_marbre"; $this->const[$r][3] = 'Nom du gestionnaire de numerotation des commandes'; $this->const[$r][4] = 0; + + $r++; + $this->const[$r][0] = "COMMANDE_ADDON_PDF_ODT_PATH"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/orders"; + $this->const[$r][3] = ""; + $this->const[$r][4] = 0; // Boites $this->boxes = array(); diff --git a/htdocs/install/doctemplates/orders/template_order.odt b/htdocs/install/doctemplates/orders/template_order.odt new file mode 100644 index 0000000000000000000000000000000000000000..abfcae8e85afadaee61b430c5139f96053d6660b GIT binary patch literal 24494 zcmb4q18`+cw{|qa#I|kQwl%Sh6C0CcV%xSSwllG9+cy4r^<C6=Z~b>y?Opq<^{ig# zu2bFXIY&Vn6buCj2oeZL<OjEa?f?@EIS>%gANOw&kd1|niIcmXiGiJ+wS|#^lLf$* z-o@6K4q)JD;YbItGqE)W7&+UR*gDZUnYcMA{FlLg+yCpr`u!#hur;+Xb9VT17)K_0 zM<)X(XGcQ=2l~J4AR!_D4B}r#zhC|c<iFb)7#W#ZoBSRI;6QKW?BMW+cQ+erP#^_q zh(Ce`0{P?d`}&{5!T7EH@57o}0}Px@{t4!viu^gy-;aNngdM=n+3t4%oc~VZ-`U~( z8*g?F05b;@$N!Z6zq9;zasJ`#KZ^GMYvlw0SpV-<`2QwK3mXG76GwU>3nv=`JIDWJ zo?w0(TN}6ooSkTm42;Z8jEwb-DYlIC^&z*6_4RAMF#S0>l;KVlNWYPP-2d~OL;uzq z0c@TAp4W3+i|F0Pdr#lM6ChFL3a=sNteSNDpUbJTAZM|*?V{m%4CbM=sS<fYGrRU^ z(07Y>!S~5`v0N3SwG`2=?SlUL$o!qJv6nf<m+E@_Pg(ZSnB*+Y$1tt$QGTH5TqNH% zoHizP(-t$Ui+!KMTIp)8`*R;w2K^XpuppnRf#-m;MatPTS)s{L?0d<9Zy2*7J%xmE zNL1o!9z=%22(+y`2KK&kO4D8im`l;vJJy>|Yu5@*C~?Esq#;Rb+gT>970QO<H=DJh zv|j{E#Q3AZ<3ag!9#{N;B=6WTtvj|2(iutW=yBt@D4ka^;Qj@@IHvq9YP}CHsn-oK zg?opjjSoGi!XKKhO8M;-dJL-#97-jOs!NY;1MzW`x2i@xgmnY^D<}R&?krEcFuC+8 zam@;H{ON|(Hx=J@pN3WFF#whH&VjZGGZGscbMM5AvXrtasi2cUVyjx0?{qky*-!R{ zBWy7+Q%t8ev~{tpOplBgRXNahL3jokFZw2n*6TvzCp?gHblT#fwdK(l{A#^-^Xi|` zE<<|^wUQuo3O{dQ;suwij!mMsW0+#O25hnz2sPEHe%UKhfit+P+cS{n#wG4g#go^O zOLj`QV)f|ORw|PkJwFllM@R_m4G*RAK~NK>v1AyRIHrqFF9LGyYXgfU2}9WkFAIUt zzlI$XVW-12^76e?NkLLBh44wU0=SqJVzB{N18(BpC{8d#Ku~4!?dP(G@)QMc)nD2n zmlz!?NIP5lftO%k6Mnt9U=Sj*W$bzOhsb<p>ULO80*{v~Q21S<kF)={H4^F4T<sSe zh^E*Yc>OMbIOxf%?6=y@?KS%4A$r<ANKFN=E>82fw`Rukl}!ak+zQwqtVZ@1`MSl) zq<>X6QYA!b|2Nfna3>_L`(c>vANpjF)=iM@gi$m=0gC8hKVdb+$3bs~kX~r;Ye<dZ z3jtzp20E>i)D3<&hn4R+IVxZ@r)YgfsPt{g0nps{)O}g0;y=L`_UH99k6y;}Pc5A* zPc?O_t6%fk$~rmx%JRb%Gs^<_j0f0SH~3ns-Y@R&RWqylpvx1>T*>WD@9n-_F4VA^ z=bw(oA9=V7EE-VjWUG^t&JJX$tDp*Ki0W`@5WF6e=AU-Qz9<~ccG>By;ze^iu!_jB zyx+II*Q}t%{a}J%p6#nrfc74JfR*Fj!O**#=ht8nOQP<EHve9yFW3j(4^8#M8nhe{ zd6$U|0iX7IA~@0X^fIXU`bs(deT{423>lC~^wX!fehA3S@J+B?*<&|&W&j>hSURXz zwH64-9io6Q1#zC%WqJkKv7A498=~eG&5NQ~az5SUb^l-`QOGI6h0=yFLF%+wwaz}L zXgOr3m=(Q$Jq?El_Kbb&B|R#fC+pZNoDH;(1Zqg3*|zvBXhsB7#L_(=pSLC_D?UFQ zO$Os#;is>LZn)bMp_uu_!8Z9inCNNxsrz+-N0FjZ3Og={5p#{BeaPN`;!0aq5aodR z#rIKWd!T33Q6DlC_fwz@484vN&8npIRbDRsws3K_oUvqPUlV=;jEIfcuyNib{#&R| zkK_f?z!YJ}YQ4<tMdtSIjudy2?qPQoQagC5HUH7m@4OiH1qmYepRl#HVozlj=@9bF z`FfvttzlD{C)PeYTT%SgTSb*tCY^8Awc9zLS`M#(5*b*&bC~>j+=7~^)w32prOm=X zHs#IyXfD^xqRkgsle?Z-Iepp2(_CElvn1~1Wx5rIg&yIzl!l2Jo{v__rZiv1Z_()q zT9IWZ4sv3*+!1^CD;wWUZ8Zjro)b!jX{C41JjY77%vsBeg1SO<8+OF4_vH-^D!dGI zT|Z_P!O0?!4~u3mA2Y+JQ5O)tbym)!gj9x)#s+mONiCortt2O7C3Dv)fzP3EU=R$7 zVu47Dt7zp!u2IAK73SwsPt^u52np*SgA1!~%@64`|JFM;RSB^4t0x6@&(M@m+u57I zI<d*R!;~eu6|n=$I_@dE1lHZ?-?o)EXzSE$R>m5&agn$3KwD%nSeYA1Q=bj0;hpY` z;GL4hI^60|U)w<|#hPimo<%u3akX+SSFyIv#kx7UI}E66-v8dOc-L0NGFSbqX?nbG zax)Ojw0RL68E#J-_DYpb$<B2t?Kl|DpLAn{>8L!`mrL?HR)#RkiYR-$;QTO&3|Pl@ zH_6ErfZNUuZY0xzPW;B>70t^~g-k16^|EohfOFs>Xs$pj7_dy^?s>&Q$D}gI)DqcA zo<r2UX=NaiXJ}p&Jy2ZNw#eV^!PmxYyV>dX`EoHn=Jx!MdHt|{zTTFi^{r1og-WmC zD<vT#t%x9|U{=zxwP-W&XP$_=0Iz`aaw_<EjbPCAgNv#8H9CeR5Yo4RuX`ky3a7)G zj%OJDSSJmtHmP<$IbmZU3db3dzRYbiH#&{Oa5&k401pE}>h*;ZU*)F9+jC4IjI2n& z!;5-MrFL#$k;EM8W_BNlJ#f#47PX?MdYicYfFAM;5|FkHK}8w}a?7ge2Jb^K#(rxg zG(>Ho&L_-fi2=L5Z8|9@>2bN3CS|pafOj7f*I`3SG9xBjv5whg7<123hM6;cpoY4Q z0LmE`nUak;B>JtgZiNF|J>dK$U}L%+2L1&=9m7V9&bzk^B#;jEfOvgljUtgg4NiY! z{oBacFU4z;f06?HL>xBoMkmp0iYSGxI(s34qd!PjkN{XmG|9|BHl5u*N5=ueJ>N)Q z+Efjdxtz4l0JY9Q+7w-NjIKU)ofy&EkA9Nw%W1IyRTw1#0qn9<+d6ni{z{n3d}^lz z)gd!zd#|u{xEJC$S~yulUM-bk4M-DinJk+L%pUgRkd`p|r&(ZEw_$+2zSq-J;q*^6 zRB4%T5M@Q(71U%Qi)nhAU$rxNB`OICE?){&<W^APg(#=#NeY=}ib7DNLVSQrDe%w3 z#IeGjNYGkLw$o_hg|&@S15Yh6QR_1NHScZYzl<_jtFKW>X|?sLDK4y_HiX43ROP59 z)Vchss7+{~GR~JtiyTd{MFd6re4X@-#_P@v={QU|UMQ`p=x0c*Z3%8(k|pL;KxTG{ z(C(GWP)fn0#weADQI+snFp52{b<Ixy8B=#;<b+<V)xpIQ;#vei=NF`o%`D;X6FZ2B ztvB9#Lx8e(;A>&DgsPah6D9#e8Xu(DkH_r(xjF-q!-I`HQ?{{@l<><PW1qlJ3yWA% z3j<NPjpX~xzThB2V(!-~@m<MvrY1}}9SFReNrubpgu!PKZimb1p!4R8U<-dCW^TRE zBsS8$Lt_{x7jX^HyF=qBga^d~An#Wv<h)9+Cx*w})H0B@pP2LtU&r3Q1|hA*Y(wGD zc|N-j4Rx5hOg{09?(n$8&K*G-X<}?MMI1Vaf^)o2*-2O~gfH^9mFaa{$mqoi@N%#d z31hPjHP{9y8YelcuE|s%iSa@HNbMJh$hEn{m>eAqE=mP^Ojt_c4{%vYe#8fJzlmZh zz;U01xj(o4*53;b;k{f5PuRbe?PT*b#e`WFw{s+!G6O^gdURm_qCYL*XVhF<M^0pU zq;uk~!sn}2*>w@Xh44|$pH_4|zTULi#aTk0pHAnNf1NM9M3{2eSZDE}b!ZJ$e<aI~ zqa+P(zVVH6N%3Ok7Hc;E2;x>-b5Y6zi%kH}FwokCO7ZkcS>jpLIvQD-`ito~yi|m6 zb1Q9DupQcVLjA;k@e&}1Gyy{^07PWZvt2n*d^1R>&4n)v6{}h-Suy}rl}Iwm6<`~g zue?bpnL4-hMjO83Dm1qmFddyz%D;=x5-wWApNJ;tctT>udGnMUV|mp!35|pu<CQOe zBb2?Tmc1vJy=M|@92ol&i_yCM{N+1JiV?-Ja~3WMy|LWfcqU~dVTEH)9$@Kg^UKeM zgIg_}cQ0a@+S_Mav->bAFQvkdsD5rvlk7;L25}V4kw^Zq!+G($_WO_YC7-OYO)}?q zmX$7^$_Hl7X<znP1wIHRP9g~Reka3*1}~=^(<lc}QEgTOFDkVrP+X6>#bG|3hYin{ z79;jcM!BaLn<f6Nc)8Q7ia9^Tt%|#4c4{6WE>7K+l4Kp$Rv*lWk#mcSoQ7e>N_^*R z2j`bKCgK;hnC|1-iI;K~445fiqAW|Vx?|yuI38w>0dUwoS$OG7wK>r)KQt#=I0pQY z<bnM}>D>hI@h6o|u<Z85tS(gG8tfZp3x~SI37R1VU-@p54Pz0HV&pzGn6@@OVTcKx zU=L$I4CSs%Sr7<*r#{ss&)kdj1B#RYhueO{Tai&=^$c_e1zt4?QCsn4lI&N1Y5K?Y z<UQqU`j(Ur{67w;&EDmbqrZ<!q(=YS8R+ZpGmxW`yS0hqA4l7D&DE&gW<>8vbx2JT zK)vzf_<4j`EVKi#OKtbW*sXt(c{-*fibSi;<YI9cdT1PJv?(_(*hcWO?Lw*HwMtD` z!OMDdaczihii)<%sT-g4Zis5?kb8sHU^f4IB+V}V=I2G`lCArITFVd|X*rAHi#7wQ zpF^RVT5}Y9ttM1iv!-gjv1MUhVu{9nq8g!xNl`8Fz><nHC|m<8_i^b+$obLC_+2V2 z$J_)dubiqFjU84Q;FrpNJk^j|j7$RSeEZ?A(yjSq=k~=`UDDxew+!4%Q=yBv=i6IH z!-B{@jev6aT80uH>2E!DOo?M=xBW)aMaL?i2-vMExFfLf@uj(Gx+1C_XJlsmqqaZN ztmXIj))=;I-7asAw>w6K*W*s!C1jF@ArR7h`QGLZ{Ar3O0+--aQ}^!oOf;QJ=zo}N zi+*VnjBE>M>5xCW1b%Tt^-0iX#_X;uzluQ9=xe43mH=Jj0R}UmPbtEqwV%#U!bcjm zBy`>#a`Es3aX}lWc}`-R1yUN1_~IXCS~Vr)&rK+ph`%Fe-#&3&clgvnU#|r$>LSf7 z=8%MX^3L5Rn6^Fi5jFa4Fq?yh>;;`$tScl=%^r-qS6Es%WAPf_oOTZ1lY<*W9CtQ^ zoLh}?n9z1+*$R<$5!3hqIuU2oAVb^rTpoxT9Oq_tSGk;6{e)Hd(`m>}E<d_nY5Fis zSl%dq3`U>)Xa0m#-3=?BPoAf~TX&_{)yi^w%@2p&##m2!$Hv0o-Ue5|a!Y-D{l+cL z!?#E7Qc{xoIUFS`YBh0;z>eH;`#dBt-)Q19AL@qU77nD8Z;Y~XryQB<Ci^*8Ysi)q z<6vBv#AQX8cZ#*>alV19(;&Iw`>I#aFUdMW2D@?%9>BOikDsXYamA}1`?F-~dBEHi zlqF#u2?1(9?1bPow@_kmc+7f*EEF%(jTv;UN%E)e5`$Exbo~?2b*Krw7wri{H=Jey z)H(YM10kC2Xiwdwp?{?f^$J2T3Cw-HHCsCekMeP?BR~%P{_!bn`4MhE<d*ZKer4TR z(tt^A-oQPD3sXbY=n*U>9rAG)jXS9rEwEgexagwI0jfKYX1Gt|-V?*i!;EsqVptQa zyJ9V(-%wam=UQZ45;XhNm5g(rJ96i@^T4bHp9V(*Y53N$tPBcavmgg)-+dvW?qP$J zqk%uUz4PG$WprS>!>5q>NzXL0rqFAn{gc7+0i+I*$!z8aW>~UeiWA0@y1YyQ#{*gL zZ%1AR6=a%cDI2@6z|1dN$ic`fb1&tA@2wKP?_jCN%VRBN&>m#C3MfQ$O<C|Ff{Fgl z1Z<euPxuiBZjJ9jtQh8W!+T|;wz?RxcOIAw>gt{~Ouw|A%WOzZ^<F*IJv2sMK{u3h zo6qM*m)~z|&kbL+0~Rr9Ko`=zls!K<0#;4+bZ*vlA+}-LTUONLzJFfp6GRUkW{dg^ zeER+%p<A+JB488JpA+pM`=Q?VrBqi5DiJ*nx6CeVuHFbcmvzH=>xe<`J4I@{>6+S6 zk6zBv(&*Hd10vcz<7VB`>7JbYYA8?hHtcxk841d-jOGszWR;N@^ez{877HAiK52^a zuICKohr0TOF2bm9ivABgC<AzVZFw9?bepIGo(~jHRhCr#%(s^TGhUwHUm3WE5H+RQ zN#X;X&r1xx@iEbmow^Z+wa>a&c0Zmo+Rqxm>N{k7gqByPEPs6<wV{y1Lk)~6Vh?KA z!G<U`S>Z<V=FMz1%ac+Wr(+o)2u-aocE|Y<MfWu;S|EyN(3Nu5IT&#QTR8LC{cO*e z2b+g0kWLrR2mB5zbvgqly=xWvNYp*uPLUN;q8#SJv%j&-j=jg^ZO;<v!|Q>+&4?+h ztdI32oxslpavSYFP+&*$)Uc~DS+;z6UDL0=*her%Ba-8Y4VsJR-I~-M{@YJ<HIC-> zSPr1TF;AfM_$@8sK%K=H4ZFfj%j`*oJvi_mLZPheXugz%*a+#G{+A}grk)69t1z~r zz{yrg@v!}1syX$8J$s!q@elfO6IpoZRc$FMhX)^RQIZt)=Oy}D>t*#k@N`%OMqYBp z9`?#IlV-<n_A$o_GX^Wr8yUxK*hU`LEJ9AiN7vQ^n;8eM*!j-}_WZq$)W?W6UjP$# zeUXgscl9_1t%-LjjsEOrFV{sWx??kK+b$SVTr!?L>CEp=Ml$qCedi1be<3{Fjb!*? zl8*(ZcAvL>l?t)}5eLPGj9FTe(dN`{jzx#ZvWnj9(wD)n1{B8%=U=LGTdBW3SN|~m zdT~6TbO|@(r5lC?Y#%MDMac5OhZ5GJRrAjADijXdr;g8kgsLjw_xyo!vQ$j;CJ^}W zhOfQlQS3QX<~1hBcb3B*9Z`=5Bg_0UWx{W<+i=6@MTl=Wh-snGy~KrC&1CT*0}b!n z6YOnN`JNRm&#fPC)(`!*x&fCbJBhG9vD+QonlT8Pvq78~+q{@Bdb0V_p?|q?fHqk- zNNwd54-}XNIcz{X_eD#BmU7Ylv!&UU;Ck{`-(kW<juTxVJ-a$z^ePMqDKBezk9hXO zBs-1(<L7l>O>8eN+mmfvUsXP8LKJL3A~uiV!Lb*Ra1&N9FIX-oU*(G3D#_1XB$smd zzP`)V;QEQCr7KQPiX0zB&s)|}GAX1g7L0b5xuOk|Do#O3RipgWaoD^<IdC5^ItQwB z^3kb70`Y)^%T)QGPmcR{-#^=^FoRZj(7!v~YgGSiA^zzCvz9zxUV#Du{c-=<zc+C* z_+taX!~gq1;9}z7_`8G8OT<XWKty0-YXmU1ur=c)QdJS7<sjnc`^p0_HMKA@;rgek zPy4(3Z$R+d)Yg&fFBLD5vx6<ypY4AxTLT*tM=mELuK&yfaQ$aA*Po95lDJu0*jn)t znL9bzanaMey1LT2GSdMZ%;*_8IXUV7)Dr#e%Gl^%I6G$t>pxM(M)bd%{(mqHj`WOl zjP(Ct|A_GaH>f|b|2ZT80PrtIf8_92ihsIeVqjpQ|LZdm!QWN+Pvv7G;`^soe+<g^ zm4L_Ch|Bmlf56AYz{o_)z(~u)uENO9#mvIRz`;ZRkCNxl5KN3MoPHOc*7$EOgik?* zfklFeMV5tKnTP)0L;kC!k-O3Ftsx&P<9~zyE&mH_W@7snOTs59B&#O__)WIxDZAU) znFDOy>6z&mNMtN*o!toJe`hZL=e+-sx!!ML!qUXZiJqB}!G@8MM9A5~+L)G;nUnKx zSN}2UUta#TR{o%KEF7IIj0pbBz{$YS+Jx2!;B4#kd%+R?CH#|5_(%AA4gQG)82;h# zzf0|YGY|jBnEpoE88{f2IT+ZP|D)jK_*>%&a4`Ny$jrj>x75h|w}H`bQs-YPCUyoQ zdcMCRcXs@(Fg7u@ur)FME0RA}G%t~)ttr64#=yv;ug;c$@&5*A`oF=M|8H=XKj42a zORhg^_aC4BH4T4?|7UXL4@ODF+}Xy^*1*Erk>2T_S2{aev+-6VFXPRdBV0M_)rbB@ zGC8tF8&AX4#!MOO)yDGzqxH8e#|g*J!_H26+pcfx*&SAkWmQ#Ws;8^eGP-Iwa9G$_ zzd1ZPB_WaP*A7HTNDRoE!N+0<qz7jLf(aZ+#GXyt)Z`TeO{r0gY%c071L7KynC+ZA zXZ5;mtnmpL?8pgdw8-!~_*PZv{YX{1!j)-lv`BUBholir9G4bf{m8-o{;EzkWiCTd zM@KWz^;Sm-%q%wE;<aLAxB;zfCfY(mKS9tCkNG5D2Bx%anFNEL-cLOoOQJ-tHpB=I z1J|q)kC$h^Y!1(~!}kTMH>Xy?ixz=<;_s8Lo@^MpUQ%zm%O2oM8}oeG!TjH^I{PIs zCmD=T2^r+|tBdlX@{!;6p8VQ2YSeU>FpCAWV!G9y1W=T}n`8;NH2L96e{^?abX2YD z1U1{+Zr1T`YMHrqr&Aa9XkkRXAK9DM6_#Q?h=%L<4{CSoTKH)&rfPP5P9u#Fm=AO` zzrc0$1-R5kHh~B%6?HSbhBR+cm1Ds$@ZnWhy}mhwJ2Fq)*)cT4b3M5Bf)_sa#(aMn z*)A7s`S67GNB|NcUPRt+g%HYL^tY$IrpWQ<+8uJV8JIKjaMjv^IuSXw7VF3mVaSH} zTUtG{1eUuL;PKzw_ZDe<K~f+*5<Lw*UQzCLiqA>xYoq04`=}+aGkT>I_9$&-sShq6 z{ARQgj#n;+pbv%W88Zcp6`#lZDG6b$)7x--4{@d(E+D?<Nc~FrzJazUsaUtE3B+j+ z`C1I82KBxKUlvgP9Z~{{{*Jzc@WN`|HLT&W2+mYiA)$lcG8-zgTQ5Jgn#3jgE&Ebm ztL-WW%66xe9#QQwbA}fa?7RtwxW$@#$o6E1-l1vl66MiL$4Qn%FK&f`S~muihhJ*Z zu`>ehiIlwtaJe>nF)0odzrKZ3Xm?pT(&y8St6UYT7W)cMW7-d!d3a-iPI1|U^6vYy zRZvn!DJ`M4h#|}7nveaAFVPFrX5Wr)QIbzbJrkAHAm!8E!>-^&AvGcqTLglZy)(Lh zw=H=3IGmk;ekYIgY~6}C@8ik1c4Mw{*Nj28oxR4&VQfEWX*Wn<`R;NxGlr9`$mYK5 zrLTU(jpT|l+OArlS#P<6guavlcH}fq!w7DT0b^eb^d<Z=4O|)`x~Bg}?5;1oX@E(U zhT@OiY$bo*Rbk7AKoWU&m*$6ybg9X1QC-ca{^5C)qm?CY+d!wwTHT!Uj+LhDo|#g> zDL56UwP{MLz@T_-un`Up+gdU0J_aS+o??PL1E()?#$4mqmy|ht+gYeVG_*8mC}xJ) z1>}~tkjroHPEMd6`8QsWah8@R$)h%Vx&Z{J><+0T%p|p(0sK_S(iL5mmS#<7uMz{O zzBa>nBm#coSsSyhOBXWVBs`5A^=F?WvGbA))OXql@0v&GnrHVocB~hb(}>rkc3ym_ zOUS(%Sl-B{G1^1w6(+}Qo2j+*&Lo<hmD>*E=hLR+;xYKI%_tvczqsCC7e3IB!@nhd z2(dk1L+x#<^TyR#MiMKL?<g<(oH(mYXX}2{JcEmg557__hRG?||8N4>3mHySrCna0 z^xN1q3S49Q*vBJ;DDbLw$~T)Vb8aKlRz0i^cfwW_x75TrN70K+YSNK3!<^#>Mr%%D zXF`l-=(Y4I&&Ein4$a5EzuBR_Id}sg_XrN@K+1KV-y9TV*QmSvpNs?FQ3@zRtogkh z@rR)brXtbCkozK7k!`<Mm!<}-h#wt#kMUe$c(ZhVe_=+8tyBZ1KMJc$iszm{j8;9# zfMkG$ydIs@qhwhJ6WZ>)OBFFb=#%1>wZRDcr7Dy@YDVG=iqxRec5F`Go^LcOp^Ty@ zhvZJEMJiPnox=W$(#7G)4@I&r$roQ^OC5r`UP_AEKW`+dQJ?i}@_}n@2N@~A0#+Z= zO~lIuHX9${;iQ9Y+kZFv$no`7fv?cek<(2v>=)kokv9dgH+OYKLo1BPl|i`xGYs#! z-0M%Av~)q~LQjQn<pi)WxTf5#f;Ka1U(?27E9_#8lpjHYp~S_E!O?qIw0scHUL@)c zjzJO>kw_1|eBGv`qznwHva<Pxy34126+T>?Q=<Z#Zz^?)z_rHOS6(nq#3;K#U+#nx zS4G?N)P#o^#SZ?466T|nI06>y_oZlvf<uRR<iH>CC)fQ}2MZkBZKyN2-u-jcT!0`Y z3u7}0!Fo$IGE7Rh8+2fS5O1Oyi4b29Kdx(lBr00i<?3PXuew`EncLXFAo;MB_3U4H z(OQhG>U`|AnJ1b@LQk!oMkZfqU(HUYnV#$54iR01cV_&}7|@gZUx@to?*^Z()=i5a zBpkd-SKb6XQrurp3qW=leQ?#-9upN_eoSn=;FJq?$T+j1%OLO}SN+I8Hh6TYwePEW zN`YDOPNT&-SRQd#k_=$nwTI6X)C;-ieJ)GW$g?&$?se}#$B^;<wfupL>9>vsoZe71 z?#K8*8h@YAUVI<BAZfFgy7iN+0;|%EXuPmQNt-?Zi{;pWA+(OBix*#aI<xr4KAidL z?_P72Ud#djUKC>Qc$Z{(7Za1J8p>XjvKgS6HYeZ+-lDqixyvZEs?I-091&UHz6jFA zwg52%xh1mRA#1ch`Md^_0K{gt$CG4JyWlCPcT>*@iI&qlS~Z%{Nl~{Ul%_Q-Yp%}f zAWKOYy#O%FR6K4mC*=ZkObyv%r=-X7@760FpMl>l?gQ8+-7Q;jY!zd5;p#Z3A#p1z z<Yn&n0#un;T@q6EZ~XT%)a_Vu>rI=46l+Txk3&!-gJXNzL=g~9&gDcm`PWh_rMvdu zRhU*qHl5hOQ%@i9acWncd#h+CI<<K#$7Sv)49ak5cg$6~i^cAg?o;{<d<Af5-^@yO z+)DILSh<$ThOi+F&~s&h_|ts`k>tdiMWao{-6FxQ*SDk{<r-J`d1D74!XOAc8JTYg z-qy7UKy+sDU$&d`))-POcEgnn+eoj{#_V$gh_ztNQ18hLC|N+iyBhCPcNe|;TVYwx zB8&53uO#7ykR+}h+MVtO&V1>sxTZsqv;7h^I40xIs4-?rz)cGH&_O+vyvNL3C*oGC z;6kH4s&ChG-MFzQC1OTpa3m;DU?C+!+My`Rv&oBQn}enSC($JwUAlgB@&RtL$T<{D zid0a3A$9Lbi|Q&quk!JH4@*=Y*Il_jB9qy6a;l5Q&*%%nvdAneEr-&&z2d-(D5r@# zYNeC<8jh74*7w{ydHt*dBob`OI)IvQI%t3o97tx$Ng=j7HRZO2ltjWM)h^!`ob`#; zIdOqUie+m1HPBL{Qvw`5=RT{le9JvH?l@+9OKZZr#Wm9knmrO=amXQ|IAZ--ItQy{ zIsS5U%=$L_x`HJ=aC)E5qnGl;_A~NA;p!K;)AF0jd3@Tuu-G(CvWfE3;GU}~jow-R zRByBYyu<@8FD>C|RCsiRXbc-G3~=<Kf~Z-&IfufN?Jz|g#d$_`uCk(pEV}HiNQzTe z|7LXC1x!0D!~FX9Dc9$`a5*%IF}^oj14jg$wgd(45rp=b_{OzWX-k}=F*3?Tykb?U za2(WRbsTXd@vgJb!ZLK!S)reOO5XUeV%-Avq5?w+rJ)?ocYtMf8A&^^&pHLrV&ooN zB*T2V+*E|X_XA|23R#1n+-vKW@sS@ZXC$Of=sz}ghGQu|Yq2_<X7^!Sv4Xy@fW2Dx z`SqAh;5Qn=L#e;zALeBc)$Lm935I96K;w@cWZd6A2k%u?S7S#pZqGn$iq1_=^@(N4 zbQ*8%=hOA(S7Dz%-Jm(dC2WQ;s@*T*>xtO90$luUTp-Z~)qz!8!Nk$gHg&0|=cB$U z12=4*iPT|G5fxBvrD1SwY)*)S6MGhg@`>Up)J9Lsw}HtX5hS@8w2hCMcO!@G<Q%5K z;Y<b7$j6)8Gw(;qlk+@w_<-#b7(sFEtHFO(G?4IYi+RRzF!GF(V7AoMMB{GBPCS|? z<0FiJH`L<#s8w{iqlYv|!P-Db7XyOw@-or^Mf#Ouj{*{x8G`sD+(NnT)8DtFgIOUh zn{gqaZ-3Gl$a+(Erx35}On$;^Z{rJ?=X2tUuT;XZ$^!U(;+-qMd{SRWJX^~#sc3ec z>xs@K1d?phYLhFkq5>xX%tf*EDRRm~fGM8=g)Rv^J5~e<4=z0~@A9zYc3hL|=?p9k zh8V!HEjHS!r?`_IZ~Z;!TW?D;4XpS63G~d6ZeDGFN8oN<0{Y}Iog;=O{v_rOGk&4@ z=(LF?l9gsBubP^bg=&Le!8SXZ>7HI!oPvZoivbwBdbAR6Vn#xod>fyqY~hnGV;PGF zyxVfNGwXp?v=f4uFA;KFAtq%7vYKwDJeOxONn}IHsTiSIvW(vBQkw8lXa9bCS6B|# zVT@!i_5z-&oBl0y<D#}&nm6b8?MMB*wA~i-pd`~~N7Rb4mEVx5H2m>O`Y?tp@cIVX zg!B{S%ZlRT1<vGMX0g9m(}E1+<F7+e8(bKbK8HCZkAq8uDEqcDdx2qw>9B7_8V>77 z1PFbzz%NzmZ!lIfca^O@yTRk!XBh%}gY!R>iDSZh&Axb~voS|q(|SzWq32q)tp+*Z z!srTr=N~mQEtzf#XgHR}ZhFV4p&r$s2IB!%O73Nb5MQ{aV!hIYR0A<oeKI}fp6cUw zLCO@>lDad~N{Vg2^l`Cq3xGyyVQQ4K`m#_Vsv4;@hj+%j#1E%emWvyt%nJ7Xx;13G zbt{kvi_&5<IKBu(CgpH}a!M1m$z#|K_fx4)-JS)!M|QMDm_x2w>}08Xt+lK>+0o&Z zpAfcD*NtfOH7N4uoj=x%BTf$Lk*y20jHWtr+)pOrD|c^`iLPN+X-P>G6DF7O;Du-M znEj!+>;@CDlQ3>-!R0kic{QJQ9{-p;@<*7+?*{D%C5(RYjBI_--xeuc%@-jSK<VoJ zD@H6VBQagHFxVM&TFGv<zISQmX)b<88#qhQNBT^}{`gXJv}shAbr$nIvc~yg+PRZ# z&G1qPuKq0XyU_U%|9~Qh>w8<>NAE)Mo38@&bAMy8N9nfg1k?vigt~;!Iu=o^@Oh$I zpB|RyJ1g(PYeWyeP0RDI3hdA0%GQ^&7a4tWI+tDlgkgDtA>^9?w<0~pY9Xj7{Dqch z2}MbY5S@dLWPTN|r{*7!jkNm5Dr=i)K5G7Yj9V@a$XX;r5Xq7#1tB@axl-lCB@Suq z1C9NQm(st=x^M%4_lNNzzYqI|PQA&g2!)tH2<wPYOu&nwI+9ifQe<8-d<pfqdfIum zE<Q&;=HIb~@jcjlxZ_Mw?;fl<O(*R-(4Ws%E}51b=?SU)mM{nhnF7t?L<){g9AWFc z+%1<9A_DSVa5L5epNgQ<fs}q!qb>bhP@iY|g%uOEY9C6?vFK~LW_Gu?fJYJ#Gsa7# z!H232N>SXA5bc<+&W$EAIWW84uIQZnU2(lbvb(XxFGb@iHs^Nrf%&JZ+~zV0ttX5d zaZSQ#k+}t;V<j?Su@5NA7x(cMi)`^)C-a43d(^l`*`V<AP*exs^0CA4NIg_;?1$b{ zj{`<xI`-2&diMwQL<1g$g9ZEncN{54&gC%pI|woDIjnVob6kq7<yC?&szb`08HDLw zhG?L;6Ymubnnbka*|gQNC9JM5s*LrotU^K&f$dXhw8=-^G|5cCqnFEORPjf)^y*L) zDtyEBjaGFQ>?-jN%gnRs6mx#RxE2(nFWuCJl%ut@5hrm7hhqW88p^`1?z#4s5pxmU z`X{B3TdtAr<YS4$5Gtr#*WAXbw2};kZ|hw0fCtTv6V{##Sw3t^t~o8s0WfP$Ji0Nc zvusPZ5Doi<0cPo1$xZ~%17b;76l)6$NlL|si7pmH#3qFZP2heggkifTlS5H$b=vP) zB^kS&54#AynK_uzR7FbbwMUrzr2@0LL0_GK+zG{!IU9{he7-+bH5d4d8I_)TMg~yU zGE#|%->FmbTrW%U8ZZ<pCF~*t5RBN25xfE=2$!mtONYI3P3Eb-^fvWd=3-{3lPof| zcGwN#8cF*uRh@$&8>ij)7n#5+%5d7)|I(*Ok)@Fm_$gno5>cdMqZBC1gQ}-ku7<S6 zH_u7JUn8_tiJkQ}W25fMjP0F7AcV)Qcqmwwv~%FmJadn1pRHBQQ0+D6fT-s(g-Ubu z7#(ukQXa0MH#}Joj<{f}GwYiy1%bOm!V!<YU*xBuJYS)+XFP5a+|z{WgiwpgY(%6- zS>JA}nn3$>{!2{!^=GQ>ZSd>Ly!#Lnc5>2mF%#6-aYLfgFSg3wo=&|?kHM%It6MC0 z)Cee5=rMhAJ5sLkiCAO{!`d)0$(vkX&}$1JTgqt;R&K^23z>Z1QTor8NTJbPcDgw~ zHMn*uucy-7rIgoqTw|8~m}VI#?wlVhx*oEF-llOGG%enJdjtp)zFFfGrd08@H2Pcm zA}x6=<i(U6>+(=h{LgV2lKvp*k1p2s4Zpt<Rbs>~=W9whhQ!Kr*+r=y=PY&(tRRUU zw(sH@$RR_*Wj-SBGgXNx8J%%4fW3Jd1G<_qsQd-V5I0MNbW45F5=?84O3~b$=}Ib! z%W^-qzFVY6sLyo?MMuc;qi1w0`&Rj()${soq1Q>PFY$yxqa)~bz$5+G6GyuXd&^YK zn#75cqJ=u?DxB@f*VWADYe&(Ar18caI{aA*_$fO>3G9JS$2{l;a*Zpo<II-c&R;pF z7U_fCL?+cUhW|ctip8z$=c_PubNYxCF5&<|g7e0c`;=s}q1D9_2OI;#q84HhZu9W$ zS~lTfdBnF10ByolscR2)5N>!Q8wzttJdTjLzzge|M{9M@y6}pkTBG-)T1q{;RS|nU zqR($FvZ9IvF)wYBp^HH5=ee!fg2_^@WRe;Dj7`hp^+t2pqi5L`Z=kyAoUtY6V}!9% z9C-4Pv7kq)krPTfi7@&R54AlCzGqhu#OqErOx)oXNA@1Q-@(?uwV6zyqI#TCiO*PN z$PQ=Li%!wQ|8h4<O36B_BKiq6C1jY3{26_JFuJ_@Lo2jlF(#J<v7%?1N5#ItE&*cH zD=MOZZ?TAcW#twHT<~y6=MYs1<OL;Qh2#-{{o|Q9zsw(J-CIOUDFLJoo?L=9p?|wS zML)I+Q0WdR(h`!vf+u@utD^1i7@+F@3ULAkjAlEjg%ts`PnPQ1#RVlz<R)eP11;sg zPE@!V+)=M(i|hOHkQ3HtP370ac$7RKrn}MS76xM14-vYB<ALa(ZNzrC#DJ9_I0p*L z&)j9<w<|4Z>}Rj;2F*6%o~@2O2v^~`(St0bSs}pAH(cR_S}tZXPytxbiVfOtK0wLY zgLs3AR6s1sdjmabwN;|>39%`o=Y1U^^g><`fR*VYW&<t4XqY=1BD4v-16J*M&T?#V zzy+^3tFSM@4Y?!Zd|$Jen`2Z4y1xdLt&-k5AMLsqp)EUp>oYh>M2Ztipha(<s=-}N z*y3fFkO-XMh=mkS{`RJU-B;pJ4rPoypv}uJR^(aa<nCN(b@~ybs&;2zGER$xLF%(E zRLGpO0Z-}&nO)`~OZXM4>SpYK78TR-f|P0rM+qLQ6?M-9&AV4LE6f<6f{oiw3>brg z9mgIU<o57VPIgeX9~yQCIU3zrA9Nl=<I}W><wt6v{9Yb5;!WD8;I12{>6MQJ-3@h9 zD8@8us*dAZLz>tDTO*9b<unB6^Cg_=STTee8PwRUwyZP>=$<6a$5WLU#1Nh8LHgY6 z^|VyNUJ!U9F}D}YzPg9A$0bw7uZRpkX9@9swfdvHWFoy4y8DGWe%`bST0^E<J$9!1 zg%*A;C*}Aq%4w~AZ7ZR9)mU#rD^X8q0V&ZeVfRdP;X???d7GqDidBv9xqhKhx{JzF z+23TIZuPv-;Jncwni*<2XOpBX0QvpfaOSIJfYb&-Jat3JDo<kXka`w(ya$V*4jEb; zK|OTYM9Zc$m;2-bOWRK|?ZT=~xa<YyUZWD!uNJY>7o-bmFb)@|k|)LxmjGo?eEmux zWOD$ZVJ?j^_i}}B)(@SGI^kDllZ~o4ooz@FZ>B&R^|;M~dZGe)3S*0$L!2ZznbBR@ z(9f4T+3nBKOkm0izp`c^_tF&Z+Z1(&F*2-rM|t?N#aJ}6QuDjJ)^sxCBg#6?vbOT8 z!a{fA45AD#Oo4pNuWOZKV2nF08eor5tYS?*F`39R<a4F$*w`0_b;uS*v!V=b?)v;< zJaM-u)?yrAPsGCd$W|WOjJJ_+mQ=ZQxX06qJ+xEY^w#=FT@NNtPhv@Fj8evDSjnZ; z4WDEwZ%i^=4C%<r*e-+dnRO(dZFM@$lqcHGeCs{^rkLD(+#uMLwPALyxDj`&+vZej zxPYB6=v4T1;`f%&DzI~IB6C<1qa`9Q8W-L!?u#@#waLG<@H&e{)ZP0&;#Wl`!B~D= zoi9Zfe9L!bVj)@Q#R=Ys3E>GaO&2BM@LH{Vcf8T!Bwl;J9bx{pcvbY_9nZlgN8HnT z!o~+r>}X@eGA=tomcp$86JJe@=us4=$>@>(RM;=_c?}rv**BhI&<6`Ln~E5sGD6!~ zEcYr$XtPBW@72@tajFxf*Rs{nEDkzF(g{5rcW+4IhItYArGQvLAcN>%r+73vv`M~j z*Ex)TMeb(2F3f9OUs9MuzJtW5x8F+p0@IXo6yyBVXJ56>o3_4*Oxqw_go%)y&@vBA zAe0|1ANXGACS{K<*z&{DQplBa?&qOMvHX<?R~H~^9<0va^}MBg8sySAT@45p24s5w z)fVh*C(wnuo;vuR7EP34A1MO+A;qZr_*h$~Jld>qq&sYCs^`=jiJvq~)1A!<RX)xV z;1u`fY>M#nki}lN*7ckDo^H+}Y@vF~T#_8^EG6r5hzhH?Ae$_KJ`a|UDV8rxrLZS< zZdmPowC3BhtSb?5k6j_;%}iS$Y~52CLAY7!0XgC==<QTa1TpC^Sa{qlI`KO2x^`S~ z;bw{=A1l+IX=$m+Oe|!e*LCammdv46oh|hNO4hEut@nhmxmcjw;PkAH;am0Ebub;W zyM~z_=x-HEV5b=u^nEki)DYCmWoEz@G^VKS@~ITa=LIHojaPO2`F20Mdud7+C`2dr zH1h*PM_o+I;B*tXw1+kg2dPTc-a0>4zBQtZU~O)byiRw?TvjuysQG<V(rM;N66mEI zi6_U>tf$(WrU!1hvOjGcd1J@?0OQ?GWLGTO%N44rFPzFND50{Xa+f|7>4vN1XW`Wj zy8Q<J5x!Zx8uI}bIg4qkjohk?wBrN8&L8G^bznx<^9Jm5BX*uZYK-Vt(&mrQb$xpA zM$wsicZqC|OE?P68mafTJhJFx=j`Xm2n88L&lfpD-j`~x{K3UK{VSHQE7V80W99SB zP*{y;HamujET@?s=n@9xvs3tCJ!LFo&^9)AQuQruIAk1deWZ^cN4e0IddgCQU%3&< zI}E4Z)Lp<pO-n(Cx^HPluh8?$=fq(d4TvQA+{pJbcRx7P>IBSInNgY2ERiXLq7_kH zqEdppvspN17iTojxzb5AyUbFx7SxFR<Z!cmVmxghZkTwM2So@|kYdL#8I=+AEW`~v zrq5i$z#w;R?qQdzlcrtRbX9PCPAkX@ie9MRBf+In*N5xd4B!b|_nX+qd<q%uGm`aZ z?C917+K1+?tbzxa=e>d>nr?op!Z=dZKK4XN2UM{=M||I>6;46-TvZ{wZ!`140a?}0 z`Z54cqb0STUS_QKReocFY^+jHX@MB4sZD(|)MBFsQPH`f+8tLd{%!r}zJ?bLQi`jh zZ%qgt1fpoiZc%sg@TiO$$0rO<Or*%{N1n@7lv&zI_fGotNx)DYR7P;?Cw-y5@Bq;? zJOExWs#;waWlLz^gwq>#=w*%82oXa^_d$S{rZnkH^E22k_oyjMiaclO3xgiE)rfZO z^3M3^m9Iv&N|S7CsM?4rs4qI;8r7DAod!Z;oqabXag)Y^N;FroWoLLs36Yv6`6)Ld z8?!sRW4pmkX}Y4Gd<BV>CxMWC4iy!*-?~3#Bck3k+~ixzcVCy`Ly2NPz25b4d}@>@ zU}bl6(knGj;-*fkkN{qGY>)5XH!`!v?tI~Yw|%`LHbi8yZYdU4Q^Jm!ZBXo?(anB^ zgH20H(igW-1ZFuv(tvrckRe;V1;s3^@{q4NX1!-c1h;&>3%6h|y!rBzpASTpi8m=; zCQHY5lAY*Ym?V-%M`I<+zQ6|kjjq~!ce$gdceoOKcgT!W!IqF6xgG-_pl{z*u{B*j zPr*5WmX^E|v1sDR@4zZ&3%3q;<n#d}&G+=II-Fho%~)<;B-6GJ_C}lsb*Uxq;5>h{ zLtMVX2gF3hb2?ffTK9Wmlb#9pgZ(%AK+I}Ta!5s46N}KISu?S7E7wQM{+O_(5?Gxo z;$UmdhiI24q%(~q?Z*mfxx3dpSSX9KFR{p2!1@||_s6e%_^(XCd1sGsTM*cr@#A?} zgZwi{6Qv&)v`(hR@B`jFfl|(b)A)`1tuh|1%do;@=YANuqz@5^hT>=gLuOdOx4X?; zoV7T+^iCnZeE0sF9sQ@Wltu8;iO)4!ub9rymapx}1}la|1b8^jk5ttDsd)m<Q({1h zP10{v9b1g9aAp1OE6JDK^i}F!HF`9Obi$;_`**<&CTwHIj(A?k{gCbN<u-N<_IQOq z4f#?XD}CRJ_2G=WQFybB&|Hm?)+rRp{W*Djs-}H#l_9QIFR+4C>{ga8P|dYf+#2mO z(?nWAPK|Y24L4y&lDmN7p>U4`=OFCU3KpNWCiN!j@!^xhGGMJ)tTNd4g^uWqCK_Sf z<OA-?AN$rBDczc>+*+wvHTyme2E+=11Z8A^MqDc@zvFGTKlwSA%pq&fp5EcXA;y$% zEp{KtMZ-o1RvCqE@AQMQby_{2ZDXFrnK>y)+Kr-GLY3PWD$B#_cIB|by_STFZrTsw z(8DD2Ci0+JbXm2fw(^&KF`l}DG7Vfml$c7?^>}`0QJT~PkWRuSST8DU#uAQ_rumTW zWmP5W7P=Z2a^v3Kz7cgEOsHnV5BMOIdcYOT>Bu*ae9bfujxAwX^j7D%PIi0)q1Pf0 z!4tZmS$JmS!M)_2aAWrfR(06-mNuHa`J%MWYujxSDtsB}JcTE!dUB%Qsx#9IxgzbE z`80J@j~Zjj<=Inpx^)YZeS9z~7F9LtXt|o9uOB5F#z^@@pQMA40m`b{&SUP*UE%vG zVJ<R?AM0D7;I<=J88|EDb|fU_$uG$f#I@FX2H9wyYAVA!`3CYl>hB03!H2&!Q%uC& z@MQ+D=(;Mq1x)vYjZHHAU~cFNFab^Px;~el?9p!x5N}<t8JrFdp_Vns0?xT&ib47P zldqLy74#JLbQg8%Z4JNa{B0Y3yp7>eSC?$HIiz>An(9dZu|XVv@h|ZAS#V^oU$M3E zQkLD&6y%f1-w@g$COE~Y)3{Mp08Q(l!QPqeuImITMXdqL;txxUJ8kBj39V^nnta&a z21K4}IfJQDLTO`t9F`Hm5r#8t!2Y<ZW!C%-dPp6b;7Fca{W(igQx5xh&oC3ozih5q zER5^CGLC6jw!t&9RitW^-k^ymG3*@-y@-7X$u8#XmhO13^LP!&s&5#hW}e7b@?@GE ze*ewt$Hn2MwDcDEVNr0Xoyuwkcn@B{oysd>r#sZN#}mOv%O*IQochM2y)_YKz)R|b zao?x7qy%LHbuL8`)ywDLK6%q;<Y=;I*EjHT8sl>y_5k|Q(>c81Yz+sqD>OSLEfG&; z@mDOa;U6&86?QB9NglSZdQ!<`f`Ii?`$DHD5nWs4)d6}(EhJV6Vy$(L9-wMRv@Xzs zJ=^+D0Ul#Q&(`N(`cYO@N^FXqO9W!92fqDSv;?{qLEN7u8{m-7p|g$Nwo)srOzj>I zHEKq9wnPLhnwA@njvp@C&@$*3C!xByaMm+Pd6SvAKj~%Va<ys%*fJjG^^fGe&dFN4 zVx0U3;kEUHX8Gy;(p}8bpwxH3lR1w@f<vh2U$L3cXHrOiv#zl(g>eTfhGxXWov&V{ zRqHEx+b~%jio25SG5Qm{Nw@YeaI88pX9WqR$DTlBoF7ZBb^Rk28ElOJH2Kr_kild} z-;_Sw(lv9QE1&%>-9ng{kLLVvuY90+pIbYp01ir5zx2yqx>l=QcfpP<nGLXaC4OZV zOHcN5vRfJ5E>o92Kx2*aArCj_7~HMGNaHTQ18j>`M#9Mp@7}GQkE8vC9%WRmFxPT& zVyFq*Nn2dH11~<S^qo%K%M^KB!TFSrCHL>GRQAb*Q+_1`la3!~HbW|7RqpNs>g8=v zBL+7(F4EldxslKv+9obbpXAFUb9@w6NQ-rbb4x{oIdeB(du>@G+M$l+O<nj(rqwVa zD$Wjz?5s8_l-J<4x-r)KRU#yb%Drycz8z{j$$IP23$6$+t(ZWFlxeFhpfFu1)#)oo zg8@+(_&kt~7_n-UJvCYO#E7O$vm$mLr}qXn_&Y503vv8HsB>rl++nMEaasgpox6oI zmh#HPFa8+hWU(;?8}M@D)6E#iJX**b*t)b)bSEVv){Q2Dya!u6C|BfFZ-8HjW_)VS zFYFgjacKv0-lgl!0=)TMV+)%7aO$82VM=gE)J~A~B!!2sXHAyYNOP^fEamCyD#kp7 zNEODw9kK)jaVbgEmMQl@$tfWY$RLZUlGAGTr#-=2*1&v*J=6M*)8u}Qxv9n?^cIP& zVD92A)7bCmNf6gC^YkPz{CwmJ14R0Evfg-9h3?uG9j0G-^zxf`o7YB84(%DLcQ8^2 z;8HzZZLp9*SCY@c>#?g#X`&3CZJ8X)5_3rT03#zzMwouRjo-enkp+646^3W+?qLvl zy+Uaj=0Q)7XL9e}fk4b*y-#lKWF~27A=O-agUP3h8<U5jQ|-kwD+5p>Q>h)~y86z$ zGX3hYRzK9ZlT504e%KW^e+6lMCpeV#o-y<raq&qroU@PfIGI|mzPP$<OL1-)Pke&k z#}sNu8@Mp)dR&hTlRa5IunftZI#eJ^p`D=czpT|DrcBaQk(x5k%%TC43FR^&sCo%n zHQKb=j9Jj{3xG>yQQVe)cMP;2IG>>Ox7C<>Q;3vCqZYW#+|^vbUxj>z$7UplxoHL! zD&qKdEI>m1&ByK#a?+Syl7szj)ah5us(Cfi;DMIL(0DfPDSJXcqK`#;U2Uk35Oj*E z#~lxR;H79ZVVdyuZvtD@W@d20i&A0o9cyGL7NY#o0u3mgIO@Jho}i+L>k$K%H68ha z7IyW$G5#@z^26%#ftj8#aTd`W#2}x)^~{R}h5Ycs)dx}BFKskO?$*j}Rca@7$e<|u z=Z~Lg5DwpKg~lvM7?mjZT;!kv5Y}4knZ>ulD3##Wv61_@bSF-L3_Xj!>mdtNd&6Qc zNJjA6yP22^ggm*#6iCA<!T}-+c|``rL`$^LWXt88spFpF4B(8`;zJ#F@ZMPyD@p(X zaPc9|m_e|z(tu>WCBO-ZF-?PYG;I7KZtxE?aSlLP4PR@4rRZ&EMDZ=jsd#A{;y0ZP zr3|Pn)6WttdpU(Xq%0qBneqsZ!h73M2F~*~%Kb4)=i=LE)eN65bm;FzVNG9e+O2E) z$+JGDjJBJe;EX2Zg%RCa#dm|Q^rtEazK5xMs+pw7|G!4g0;Z0xTf<PC(&Fw8#ZM_# z?BGRCp;&QucZcHc4#lmwyB(b3?pm}^-2KA;r)j_5uQ&IdOtL4L_0G&*Gi&cmvLDUh z{!Af{{9NTd^lJYF&Vh4Y2lMHQ7(?&<iOunYzI?AnS^mb2#PWC-2feB;K{i6evK7T8 zhcWoKNSW;2dgEZ*JfkMCuJOPwb2`JTA{B)z3E`sW+S#p%OsBjJ9(j)0AHG6hMFLfG zzj^U&P|X*Zk2Cr0GrS?yy2zGEn-tx9=|QW8a03Jfo`ohGrQ@W=TAi0fd~YqI=-qk% zM~NCiF;fk{d|v}vx6;3&$L&#G?-aI6$#tJwRF|FzD?>V2XR<H8Ruy!z#8HKT78I0l zE9PG8#9xyW7#~5;e)Wn<2DIIkYUngjTB*1tp}eq9EIkxR8*sd1qzAu~uh{2V@%Y`; z8-*Z#Ll9Hl33Hq3?%ohDL*z|1qipViS{By=6|-B=aIgr&ESX%>vb9xoy56BTQ<~tr z!{#YB6OQC2<<6XYNNC&aF_p;`#AMsdS0(Hazt7~=p*W8KpnQHMQ2nmaZ7lag2mr^Z zc+34JaynamuLbelMgp0Au<v-+2J2_`A>SS}o~W@4V9zPYnrB6Xm$yfUb#w`j^-_Ez zCQRZ|ci3faKt`e>!{K@rV5`iBh)5BGERO<1Khe>e_oZ5qqIY9c&3hr%hbS%fTiXc& z8O-aD<@pF1(t+G5Miq@243eVBNSg>;Doq4CZ1rr?K$<jqJ#q77MAo-K1DjV!42Fm# z<!?!vqoAkrMmeykEc8)-<S(<^2na&jc>D5Rgo9Sw=4_w$nFTCz?fL*3dg}o0FWemY zFT_ScnRSinU+|KVPeWTZO+S2elbf(_BfQXV=gDBeu&54PT>xn^A06AQ*B({o>VVC6 zmMd7<b?Ag%M@QIMEHogyirdBkdl6ei4oO*dvNqhJhJ(K->vZ3}BpXyIrmj8ZP#y#x zPhe0ap>{Vo_WBpXOxnN@Nw9O;A!WYb{;|{dAhv9hgW;He&J7j$vJvPviG?J|b8Boa zfMM%#i!O0F6ruLar8-7QW3MAI!{dgQh&O9@X)`ifsz2I#D@MekHDQlbcdewBWG9)O zuZ;Kpo4`lCQG+@VlZ-FaZ10;gzt%i2y(GC;-<x6;9lFMaN_d)1SbYfM8Hq!uot~FU z`>v-GNVErjl(|SuVZu@luf1cew@j2^m3B_ldMIkI>b6E-iL1^uL2XZstmU_9x1P^F ze!jSwKFN0l5HIobIfoFOIdegr>>Oim-+Log(2yh8<x{@%eAt#djz3WL9i+k{<Gdux zKIRM=G0<ICWduXqv8w63=X&FQ_3F}oC9@p-_-#*8FP)T^M7;r0oe7W{#8uaoJI2Eq zhIeaB^SmEKQ(_E8eBne)Be1lQq|a?DIe5m{itUcG_C86P7hLtuj-W+Ou0B)jq%QsK z2X2^DP^9II#Tq6z<(?_)F`|_!9LMP_C@;^rU@c%}JmX>){VWE`U{)pMJDMryO(|Yq zYCya#Dgn{@V8DhT5w+H(BjXFxkYd!O#0+maV^^jhhmH(n2?&F&aV2!pQU`w2(E2~h zf<F=YTdGkWx=9a#yt=d1`@Plk(Ldy%fpgI^B}Aw9229dHTgQPuB&uOTmLLcV70%~* ztC8PmaY#g7-%?9`<#OZ2*O_EdR%@sZE%NLoJc`e@dnP4w4rCO?qrI2U8laX{CR@rq zU7)1LCud!+<k*I_xKl-An0EgG>FE4&f5BI@M(${ZOhsO+g%(8+1{p`yGB5c-I12l5 z&uFStlls1!Su0uN9useA3pGjyfD=9$%}nYZN|2a|vIZIz2)d^WcnXDvPb~O2aD7gZ zBvK-OMm2KP5mJA@+B0(Pp+7;1V~*)Dqe6rdHAJV7MrZ1M)`)@Y*v}Gx79x)z+r(K= ziWsNv`E@9ZEjFk_o$3vKFXbT>qHn_h{nlFf$MV<0(&tX=YoX0lkBil-uHoIWr3URW zZqQTGjEJZsOwB{R8=12*RCC(^-qL48Hr()C_(VX0q3E#qslvHRm9<sn8tjQN`F=+9 zR7H7uvV|OU>es^5;lUiwEVMIBXg$SCCYcH6C!Iaok3N&IJqU(iuOuTCx<L!#L1tHX z4e80ujHrKCM8l;$x?4M%Fc0xhS;8gnnxt?5lsB;FLnExZ@#hNF^`B|LW*W!u40JD# zi}}+UUbO45W0v{a9oo<`wb#PPX_$D3oP}*Q;$Sl3S`nv^a-PLX>Fb4Ibs_5<V`aGQ zJET>ICkdp8Jmlcjgt{miYo4mg+KJt;)9tg8H<b5En17bgMYlWXl}2Kh)jqh~eu1D7 zE0za1<s}cFx(dL!(lg%1;z#^s%@wdA9jy0a!`pPZQH7}Cf@Kr7-MOKgd^dO5OLRHO zfP<8Y;Ji6o>}`-v^=AM9x132NZ(jvhkHyuIwxfsNyPG#uXeu)2xb2hglsa+04XIq< z12b^QW$0t)Cp62P)NohqDu)Zm;U+fgU2iK_X!kjgJ!`UrE*eJ#vJp|w3MnFhp?4eG zFN?9|u8>?t7%6FkOqUa=m#EjTpl)6C%#(dYi2;C39FI_A5f?%hbkNn;*u9Wka>Ot4 z_6YZ)+AI2YHn7Qa$rTh0Rs!kL1gvA8#%RvU1yDp(6p28gp&ucY!9`P$Iux~6Z+o=~ zs>=O0;rirERDGn{F?u<O@rKUui8ZyjMf#JBvY-nF^z@h72pKR?x~mfm-+vL`CTG6x z4><!&8{5d<Q?K}Ps`d`+_q@`|;wGiLTBz>C0mn_O(f~a)W2zOBBcr;4E056;P`%D} z1}8plZy8Qtvksb$50CcVHJ)_3#U$~q6y?_l-xAl+F*-@Wf%Uw@h{WeK_>-k9wS^MM zludx1ZZLg-{dP5AOlJ0)qn2cg!X%PF8koyhk2DW9f_c4ML}Lj4@L`a!geLtJ$tC2J z(j{_1Xt2Bx^Muwdzbn76f$L=a2>G`Z&n}@f9V(vhV!n-XlQJl8JJq==aH?<$rSC~L zcq)gcouutKO-!ZPBb86n(2mQvvBG<x_*!vOEPEELMR&Z@D0EZEZgiq{^>6a=3e##} zqI|915dn!pkr;N`oCda(kt)T!9bgs7n)WOJ7s$&wdac-|-4=4Nw<j9-qC<$N#+Fnb zx+5-}730#g*OkR(GJ5><m$64iK9`MeTW`WG#UKBJGSfg8f_bJ|k3}fOz}EhB)@vXq zBBiF=JD0JYb(vy6{#B&;XN?@L6GVBJ^srvIZV(4zqVi;w@HsJzeI34ppgCVGXSrcU zFt&MT8>QNbVB{Cfk$BT0D{|46Ey%p2(?psr4U#i%guXbu_0<*4k39m*d)b^gKzw#6 zzX>o?Ye<hj^ICu`={6=^#d!-ZWPIvLW^Mqmpsi)5BBtGAa3eYyH<%B0@{32EXr8?r z3TJXG&~+(mF_V^Yf;P^Kd1=QIfJ03Fxp0geE4fVxam@>RE;^s$y6IS6s?K#HxbtY> zn|jfg_w&-aM~kY^=>`%Y39=W}VnP&3MEr!*y+;P$6J&M~c3&=6CkiJL_n^ZWHOp<5 zkLJOHwnm$-Cm(-+xe{ph35UdIPR9c6$<W5OJsY6b%2Yw2#CC#vD023s{j1p_U%i)6 zp1a_bTHO^pO<m6yR0VCib2z^l$F$F?j{OnPhc2gVg04#BYgK2tn#f>y-F%k^wt)&F z@^XCHHdLrCNU&F*c-b<e4w}{}U>7`Bj3Ks>wSdjbiX$Pws(H~l`c0JolX$NG4M*H) z7*r=>Kiwv31)#cPly&p7B8^MsO^C^=>|yj$f)mSG>+t-hGy6`~sUldlrT@VWUd%Y} zZPbvTbyo<TAIqYHN=<C7o8aKWJyR22|Ne_^pF>z*D4pW)xO-~*IHyg{Y|LXb!fw=L zHyV0Rd~19Gj2xp<rA}-93uCU=uiqcd>%KqSYf}?7^F1dgE}nX`5*{daQw>ukweWSS z)Y5;%GqTErRocd7#d%x9Ihu3p0qzDPS}tHH9Jt1mn?2UeslCH|semI;2+7xh{MoAU zY6nm5(}<UlTKP~OOP|KO<SsVT6QlWl0LRb@ASmK8jz(o*;1d5s$C7{;S-@Cp*PGk= zVsbP=ktO5Asl~PW^F03~@y-&G&>uZ+_qrrJjW)Y)uitWZrb*VPLPjk{PK!1f;yZkY zJz6)qybBf!3szkFp*&tbN}<tO$nC9r;qzd1|D3YE-~|-D14k|ULfu5Vqv~|D+r2tP zhYmyCIRNwJ{yg-}6kwPZ{gb!8A%yIr)Ht@l?m}@dw0mmjY0Q^^v`JRu<X5M;hb!>d zBYf~Wssb@KoXX?O?jSw1SUvZM1fji!HPO3T#!HWs_%*|M%{E~?9K=PBSjP6uVm|se zNKO2i-%jt=^9yUv)6QlU6Nm?Y9FTfX@gu=L&^j8ZqVjqQu<3wnI0-0YjKeQG+mjiP zxLhKnU>{3C=|s+81x-WFlB|8$sc!x-Kr?>#7Oys%lv@FUsN$3|HjT-~<!)Aq16|w* zmiwx)Xc4Pl?-FL)hI5<js?kC9HotVVH6T&R*&R*bWBZK(btB96@yGrTE1ehiom>DN zy2zUYNH<j#v~cU7PnBJOD+N7!`vcG@fmcSxMq8Vfhd)kM>HA2&>kw9DuF<;zh-Y`P z4G|JPWKP+Tq4||Hmfrh^q{yCWZGQ7emV+EY=u)0?q|>!wiypQFvS&$z=(BZO)wm{! zaPL1($<__a^XCduGJm3@k5ro#d*eb)z$Pwc9#vYivK3J3WMLeFxVf%itM0=XSFxJJ zso{4T8isH>sF10x0@hWZND!{>LQM6vqSnTgc8cAW49G7`66`x;P-cS0+5veVjf^2t zeR(Ulw@=^)u_CPf;LNdmwFI_5N)(wq=kqjJ<4D9rT3jJye6Yz3C3TLtR^yR5CT(wH z7Z=c^Iv*{Hh3q>C{4|joKx;R$7e++^<59xz7EJkR3kQ5bzX6nAZoZ@lojXYSf?sjy z33Z>XWN&lZ(++n{?veH3JKe*H5N~)znLHwmdu#5Hc{CNPUeQ2P49LBp2$!FvOuhks zjP-J>ssD?CioaOcxP&TuHX(lzGMBr7c#7tSAJ-r73>0~EIt3_K31=r!z_TLQt_gxd zH#Z2*r8GE}+NI2QPAK0g+1x(A>{3|3U9S*>>ox+L99c$B)|97|s}nh@6`b|iU6mBu zbcqDrM8mUxS0(fh4Oc5ZMJ(1R2mq6u6|}6Gyz(wMO+|YaR#SE$tnku0*_c~=zu;MY z|7-Q<%?l^1B1dxEUdZo<?c3Eg7-K6fVXGx*g@eBK?^fta=8hXm_SVCmFwGGlmT)js zqdB`3g>9RyhSnTuHQ(yP2wArUq%Jy8j)X>nFJ1SVT%Sp{wF5NWsYQ^TY>6QaA(n}& zVBJJsip;*_dE5NJ?q}eR-nVEV7I{UReh{DirAVwgBK6_n*%KXwQ|+Cs2L}Yi4Cl|K z&HqLPeWFd;=-ECkqWuparCLeFW{wNRov)Q_%|V>RXb2&CgeCiQBmxX!w0SBu^Zb&; zgeQt%W!Zr;S+b9kvfG)gJV$MBZ{A`fnW-=#t@)E2YLH6l`S*plP^g+XfwRRItow5J zM=h)m4Q=095z|q%Bf3d!g*~ULgi=QBGw^12RhVKkJtc(;NIxPKWO&0;k+99<Stzm> zRs8rGB&uz-J6H|Eo7}OkzpZMz^s!bbR@2Z>+?yX9gXm&SA}oBRa;Jbv*76E~U(xYV z@9gBH-}t=MA&&Ss)MQ89X3anJYA{(9crF{r+S$!+aHV5Yr4la3rcU;;#d&bP_TYkt z&#;-vGnD0s&Ek|RgFSLY{p2>cfo|0?pC`c>PCG42didgNb6wr_?S)argRddmvdi|I ze6u<ol`Ct{28uu*li_e;g6G@^X5c#5XZkasBt0Rj#PFT!D@QPjII2dV(uY7Hcsh88 zlxn`lA4CPu>v@MZ7A<$bh)am8l^UVdt8>Tr14`Z9?XK$UW}x&wlxkpu-eO8|#HiCK z7|#lu`MyM+^rvlUFR9K{`SPY4&bZWGP4fJGr=w(4&53E)F)PJR`J3E^Q0~w!d!Bg8 zX5TuR;#7ybF)dG#`iCFYCti661*n$rtUiSAkP!*ohC6EOtheo6%HLp1zvpfV)<^#E zmGx{ryh@f22~M(tCCikElAc-G9_-FA?iGoTBCtb>(+4qss3f9)Dr?3iAI^ICK(><M zEV+iz>kz^TR0$WGmPG?Jms*)wA3=+{g`zhTl{q+@ABou-JfpNF%V$l5R1@dVXl&1E z4B!(hP>wJQK}YB->mFMj<T4k6wY&^N$JV6`b`(Wp6Z~v>Juj1j^zqr)Hm)bAc3ulN zPWr3L=iT>t&=`!adV9=BZ8BI}1GXeG=%%u~iyh7?&t)y`W`m%kO-h~DBN-66I4s;p zUiO)lNGo_6@l7V=e95XZB|ihKgPH`t0r#aYkVRO$*%7mjg=fA=(qnKglBgvgk!;lP zG>AKDz)vW2thPv_EIIeKla`^tEWbOoMrn)q)btQOIt9e93pR`{DWyZK)oc>Q;#|dd zk2*Yye&*D}N~hu4BaIXf!>-MANZzRNJ(x{&!wZB@xy%8=Y3(odLn^ldY!$i$)s~V` z!REu;?i3)o5e-699*F4x_%WOFavg2wxW!%1#7$gLrOgB{>5cM#99El^Fy799a<Z8d zv)RCg?xG2Ons6o+_>U;MDA$d7krY&5ySO*h>#tGuJ3;E%HCvm2fw~US3A4Cux%L#@ z{`+;0No>DY9Mbw3rUCsf5ZJ1(4%EUMb=Ho6WdJTyyC@Xn;a7;jFs+<4T6Z^~c@Cas zn-AuxQ-aDpgl#7nH?Ycqy+ogMQU~2pn2$Xb@EMsN>Z-%m&H2XtZO4ssb|7ZlL6u@O zTVPyW`B$$_6hnTN+$&{?j&(!OUV5~&URJzNEQ*W+<wG*$ltaM=baw|QWARHok9kRG zFd=Kp@(uFf2@Cpas?vRogbM!ULH^jNty!N4kEruKSg6lY;+aa_cT{6|eGW%Y7X9K8 ztql}r*)X%qz~tkvqq8&GEqA!q2Bikbu8j%k0}2#0>-n7Hv~F!1@*mv!0Nz;7v0ew} zb2uh{w2w=hT6{5Bj$L8yXOLv;?F%VFy{BG8V*z!EfM#TU(=l@1CSmRJRc-OgQI+RZ zsrl;pQ}Nt<9QL7LARrPRQNDj)0gm}tJf(!?fDG?IB1~pl=0^H@Hva)ASI4%QcaR|Q zAKV26xU^4=W4uYJdUxZs52gAoTMQb7P5$J9Ja$fB<xR0lJrMd})-Pf5M2oqL2+GI+ z|L7x6z_ViO;u<&dC3cIAXh(G>1*ngUq*iWt7)EJ1Csn8{Gjote1q?`HZwlv}s)}W; z`1{Yc&dzj|nS!3zjl=d=F^6;s`xW~|iH3(l9E2)>X+ib1W_GsnHo{$wnpU$s{l=U( z3&J|$$W10b7{|FdC9>)%d$z<KENsf++ACrz@J@&67<iJh*x5m(l8JfW^d0n2ZMz|L zsOlVeuWeszQ@L8Y@%K55$!^cC{P_G8b{gtb>{$2&BDI3cT-U>l9AoeFLQY1}nDJ5# z=^?_R+Lu{<8V5&h{e$P+YG_bCTwgw+Doh^6mBrmR1I8o6i2X3ah*k4uv&!I(DK9pP zE7qc>y@MC67Fv;<JY8F3CF`~Ej(3nxdGSDX(w2vWfarvK$_wN(42ZuIw;z-9n||`Q z|BU+W6o@A(^)E?1Hvc4B{|?&z@6~@FRDaU4pHSPs<onqC)8{YX?f>iMo^S)dwD8#c z)ASd1`=1^2D+=O|M?`z<%0FFx$8i7M=Ly99OXC0L^A9Zd-<|&XTt5He^b6Dd|8;5j z7nfhy?!UV{fxCa{@Lyd17smU)W<TG8-?7|JQ>$NMczij2$9n%v_0P!PVRld0?q70x zjMVuB@%}ULcZAIo>+YA_kbfuN{fzq?;O18x82b@d|A@qR!rlCg`gxnb&no|!xhed= z<1qeo`MtdUvzwCT{y880GxGNW@Kk<(X-4TU#aLPb2KMPRl*f$*8Un&n<>}~u0PO_X ANdN!< literal 0 HcmV?d00001 -- GitLab