From d0f06efd68e1d77f3e951502ca917b306cdbd6be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 29 Sep 2020 20:25:49 +0200 Subject: [PATCH 001/125] Rebuilt for libevent 2.1.12 See https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/message/QOQW2BJBYMTIEUQIAYVEIX2L5IIOHDZL/ --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index a6d4593..131413b 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -48,7 +48,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 1.4.4.4 -Release: %{?relprefix}1%{?prerel}%{?dist}.2 +Release: %{?relprefix}1%{?prerel}%{?dist}.3 License: GPLv3+ URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -794,6 +794,9 @@ exit 0 %endif %changelog +* Tue Sep 29 20:25:49 CEST 2020 Zbigniew Jędrzejewski-Szmek - 1.4.4.4-1.3 +- Rebuilt for libevent 2.1.12 + * Thu Aug 27 2020 Josef Řídký - 1.4.4.4-1.2 - Rebuilt for new net-snmp release From 4c8bec71a87789945bd68fce7e6c07a63037cfa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 29 Sep 2020 22:52:34 +0200 Subject: [PATCH 002/125] Rebuilt for libevent 2.1.12 (#2) See https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/message/QOQW2BJBYMTIEUQIAYVEIX2L5IIOHDZL/ --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 131413b..6bbbf97 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -48,7 +48,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 1.4.4.4 -Release: %{?relprefix}1%{?prerel}%{?dist}.3 +Release: %{?relprefix}1%{?prerel}%{?dist}.4 License: GPLv3+ URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -794,6 +794,9 @@ exit 0 %endif %changelog +* Tue Sep 29 22:52:34 CEST 2020 Zbigniew Jędrzejewski-Szmek - 1.4.4.4-1.4 +- Rebuilt for libevent 2.1.12 (attempt #2) + * Tue Sep 29 20:25:49 CEST 2020 Zbigniew Jędrzejewski-Szmek - 1.4.4.4-1.3 - Rebuilt for libevent 2.1.12 From 1aab708f1cb35560b30419e965f094b1313480db Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Mon, 26 Oct 2020 14:02:10 -0400 Subject: [PATCH 003/125] Bump version to 1.4.4.6 Issue 4262 - Remove legacy tools subpackage (final cleanup) Issue 4262 - Remove legacy tools subpackage (restart instances after rpm install) Issue 4262 - Remove legacy tools subpackage Issue 2526 - revert API change in slapi_be_getsuffix() Issue 4363 - Sync repl: per thread structure was incorrectly initialized (#4395) Issue 4392 - Update create_test.py Issue 2820 - Fix CI tests (#4365) Issue 2526 - suffix management in backends incorrect Issue 4389 - errors log with incorrectly formatted message parent_update_on_childchange Issue 4295 - Fix a closing quote issue (#4386) Issue 1199 - Misleading message in access log for idle timeout (#4385) Issue 3600 - RFE - openldap migration tooling (#4318) Issue 4176 - import ldif2cl task should not close all changelogs Issue 4159 - Healthcheck code DSBLE0002 not returned on disabled suffix Issue 4379 - allow more than 1 empty AttributeDescription for ldapsearch, without the risk of denial of service (#4380) Issue 4329 - Sync repl - if a serie of updates target the same entry then the cookie get wrong changenumber (#4356) Issue 3555 - Fix npm audit issues (#4370) Issue 4372 - BUG - Chaining DB did not validate bind mech parameters (#4374) Issue 4334 - RFE - Task timeout may cause larger dataset imports to fail (#4359) Issue 4361 - RFE - add - dscreate --advanced flag to avoid user confusion Issue 4368 - ds-replcheck crashes when processing glue entries Issue 4366 - lib389 - Fix account status inactivity checks Issue 4265 - UI - Make the secondary plugins read-only (#4364) Issue 4360 - password policy max sequence sets is not working as expected Issue 4348 - Add tests for dsidm Issue 4350 - One line, fix invalid type error in tls_cacertdir check (#4358) --- .gitignore | 1 + 389-ds-base.spec | 354 +++++++++++++++++------------------------------ sources | 2 +- 3 files changed, 132 insertions(+), 225 deletions(-) diff --git a/.gitignore b/.gitignore index 87144bc..8ba40b0 100644 --- a/.gitignore +++ b/.gitignore @@ -196,3 +196,4 @@ /389-ds-base-1.4.4.2.tar.bz2 /389-ds-base-1.4.4.3.tar.bz2 /389-ds-base-1.4.4.4.tar.bz2 +/389-ds-base-1.4.4.6.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 6bbbf97..d7d8b4e 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -17,7 +17,6 @@ ExcludeArch: i686 %global use_asan 0 %global use_rust 0 -%global use_legacy 1 %global bundle_jemalloc 1 %if %{use_asan} %global bundle_jemalloc 0 @@ -47,13 +46,15 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 1.4.4.4 -Release: %{?relprefix}1%{?prerel}%{?dist}.4 +Version: 1.4.4.6 +Release: %{?relprefix}1%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 Conflicts: freeipa-server < 4.0.3 Obsoletes: %{name} <= 1.4.0.9 +Obsoletes: %{name}-legacy-tools < 1.4.4.6 +Obsoletes: %{name}-legacy-tools-debuginfo < 1.4.4.6 Provides: ldif2ldbm >= 0 BuildRequires: nspr-devel @@ -119,8 +120,6 @@ BuildRequires: python%{python3_pkgversion}-policycoreutils # For cockpit %if %{use_cockpit} BuildRequires: rsync -BuildRequires: npm -BuildRequires: nodejs %endif Requires: %{name}-libs = %{version}-%{release} @@ -205,33 +204,6 @@ Core libraries for the 389 Directory Server base package. These libraries are used by the main package and the -devel package. This allows the -devel package to be installed with just the -libs package and without the main package. -%if %{use_legacy} -%package legacy-tools -Summary: Legacy utilities for 389 Directory Server -Obsoletes: %{name} <= 1.4.0.9 -Requires: 389-ds-base-libs = %{version}-%{release} -# for setup-ds.pl to support ipv6 -Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) -%if %{use_Socket6} -Requires: perl-Socket6 -%else -Requires: perl-Socket -%endif -Requires: perl-NetAddr-IP -# use_openldap assumes perl-Mozilla-LDAP is built with openldap support -Requires: perl-Mozilla-LDAP -# for setup-ds.pl -Requires: bind-utils -%global __provides_exclude_from %{_libdir}/%{pkgname}/perl -%global __requires_exclude perl\\((DSCreate|DSMigration|DSUpdate|DSUtil|Dialog|DialogManager|FileConn|Inf|Migration|Resource|Setup|SetupLog) -%{?perl_default_filter} - -%description legacy-tools -Legacy (and deprecated) utilities for 389 Directory Server. This includes -the old account management and task scripts. These are deprecated in favour of -the dscreate, dsctl, dsconf and dsidm tools. -%endif - %package devel Summary: Development libraries for 389 Directory Server Requires: %{name}-libs = %{version}-%{release} @@ -319,12 +291,6 @@ ASAN_FLAGS="--enable-asan --enable-debug" RUST_FLAGS="--enable-rust" %endif -%if %{use_legacy} -LEGACY_FLAGS="--enable-legacy --enable-perl" -%else -LEGACY_FLAGS="--disable-legacy --disable-perl" -%endif - %if !%{use_cockpit} COCKPIT_FLAGS="--disable-cockpit" %endif @@ -375,7 +341,7 @@ autoreconf -fiv --with-systemdsystemconfdir=%{_sysconfdir}/systemd/system \ --with-systemdgroupname=%{groupname} \ --libexecdir=%{_libexecdir}/%{pkgname} \ - $NSSARGS $ASAN_FLAGS $RUST_FLAGS $CLANG_FLAGS $LEGACY_FLAGS $COCKPIT_FLAGS \ + $NSSARGS $ASAN_FLAGS $RUST_FLAGS $CLANG_FLAGS $COCKPIT_FLAGS \ --enable-cmocka \ --enable-perl @@ -425,14 +391,13 @@ mkdir -p $RPM_BUILD_ROOT/var/lock/%{pkgname} # for systemd mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/systemd/system/%{groupname}.wants -#remove libtool archives and static libs -find %{buildroot} -type f -name "*.la" -delete -find %{buildroot} -type f -name "*.a" -delete - -%if %{use_legacy} -# make sure perl scripts have a proper shebang -sed -i -e 's|#{{PERL-EXEC}}|#!/usr/bin/perl|' $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/script-templates/template-*.pl -%endif +# remove libtool archives and static libs +rm -f $RPM_BUILD_ROOT%{_libdir}/%{pkgname}/*.a +rm -f $RPM_BUILD_ROOT%{_libdir}/%{pkgname}/*.la +rm -f $RPM_BUILD_ROOT%{_libdir}/%{pkgname}/plugins/*.a +rm -f $RPM_BUILD_ROOT%{_libdir}/%{pkgname}/plugins/*.la +rm -f $RPM_BUILD_ROOT%{_libdir}/libsvrcore.a +rm -f $RPM_BUILD_ROOT%{_libdir}/libsvrcore.la %if %{bundle_jemalloc} pushd ../%{jemalloc_name}-%{jemalloc_ver} @@ -477,6 +442,41 @@ fi # Reload our sysctl before we restart (if we can) sysctl --system &> $output; true +# Gather the running instances so we can restart them +instbase="%{_sysconfdir}/%{pkgname}" +ninst=0 +for dir in $instbase/slapd-* ; do + echo dir = $dir >> $output 2>&1 || : + if [ ! -d "$dir" ] ; then continue ; fi + case "$dir" in *.removed) continue ;; esac + basename=`basename $dir` + inst="%{pkgname}@`echo $basename | sed -e 's/slapd-//g'`" + echo found instance $inst - getting status >> $output 2>&1 || : + if /bin/systemctl -q is-active $inst ; then + echo instance $inst is running >> $output 2>&1 || : + instances="$instances $inst" + else + echo instance $inst is not running >> $output 2>&1 || : + fi + ninst=`expr $ninst + 1` +done +if [ $ninst -eq 0 ] ; then + echo no instances to upgrade >> $output 2>&1 || : + exit 0 # have no instances to upgrade - just skip the rest +else + # restart running instances + echo shutting down all instances . . . >> $output 2>&1 || : + for inst in $instances ; do + echo stopping instance $inst >> $output 2>&1 || : + /bin/systemctl stop $inst >> $output 2>&1 || : + done + for inst in $instances ; do + echo starting instance $inst >> $output 2>&1 || : + /bin/systemctl start $inst >> $output 2>&1 || : + done +fi + + %preun if [ $1 -eq 0 ]; then # Final removal # remove instance specific service files/links @@ -497,72 +497,8 @@ fi %postun snmp %systemd_postun_with_restart %{pkgname}-snmp.service -%if %{use_legacy} -%post legacy-tools - -# START UPGRADE SCRIPT - -if [ -n "$DEBUGPOSTTRANS" ] ; then - output=$DEBUGPOSTTRANS - output2=${DEBUGPOSTTRANS}.upgrade -else - output=/dev/null - output2=/dev/null -fi - -# find all instances -instances="" # instances that require a restart after upgrade -ninst=0 # number of instances found in total - -echo looking for instances in %{_sysconfdir}/%{pkgname} > $output 2>&1 || : -instbase="%{_sysconfdir}/%{pkgname}" -for dir in $instbase/slapd-* ; do - echo dir = $dir >> $output 2>&1 || : - if [ ! -d "$dir" ] ; then continue ; fi - case "$dir" in *.removed) continue ;; esac - basename=`basename $dir` - inst="%{pkgname}@`echo $basename | sed -e 's/slapd-//g'`" - echo found instance $inst - getting status >> $output 2>&1 || : - if /bin/systemctl -q is-active $inst ; then - echo instance $inst is running >> $output 2>&1 || : - instances="$instances $inst" - else - echo instance $inst is not running >> $output 2>&1 || : - fi - ninst=`expr $ninst + 1` -done -if [ $ninst -eq 0 ] ; then - echo no instances to upgrade >> $output 2>&1 || : - exit 0 # have no instances to upgrade - just skip the rest -fi -# shutdown all instances -echo shutting down all instances . . . >> $output 2>&1 || : -for inst in $instances ; do - echo stopping instance $inst >> $output 2>&1 || : - /bin/systemctl stop $inst >> $output 2>&1 || : -done -echo remove pid files . . . >> $output 2>&1 || : -/bin/rm -f /var/run/%{pkgname}*.pid /var/run/%{pkgname}*.startpid -# do the upgrade -echo upgrading instances . . . >> $output 2>&1 || : -DEBUGPOSTSETUPOPT=`/usr/bin/echo $DEBUGPOSTSETUP | /usr/bin/sed -e "s/[^d]//g"` -if [ -n "$DEBUGPOSTSETUPOPT" ] ; then - %{_sbindir}/setup-ds.pl -$DEBUGPOSTSETUPOPT -u -s General.UpdateMode=offline >> $output 2>&1 || : -else - %{_sbindir}/setup-ds.pl -u -s General.UpdateMode=offline >> $output 2>&1 || : -fi - -# restart instances that require it -for inst in $instances ; do - echo restarting instance $inst >> $output 2>&1 || : - /bin/systemctl start $inst >> $output 2>&1 || : -done -#END UPGRADE -%endif - exit 0 - %files %if %{bundle_jemalloc} %doc LICENSE LICENSE.GPLv3+ LICENSE.openssl README.jemalloc @@ -592,11 +528,11 @@ exit 0 %{_mandir}/man1/logconv.pl.1.gz %{_bindir}/pwdhash %{_mandir}/man1/pwdhash.1.gz -%{_bindir}/readnsstate -%{_mandir}/man1/readnsstate.1.gz #%caps(CAP_NET_BIND_SERVICE=pe) {_sbindir}/ns-slapd %{_sbindir}/ns-slapd %{_mandir}/man8/ns-slapd.8.gz +%{_sbindir}/openldap_to_ds +%{_mandir}/man8/openldap_to_ds.8.gz %{_libexecdir}/%{pkgname}/ds_systemd_ask_password_acl %{_mandir}/man5/99user.ldif.5.gz %{_mandir}/man5/certmap.conf.5.gz @@ -656,117 +592,6 @@ exit 0 %{_libdir}/%{pkgname}/librsds.so %endif -%if %{use_legacy} -%files legacy-tools -%doc LICENSE LICENSE.GPLv3+ LICENSE.openssl README.devel -%{_bindir}/infadd -%{_mandir}/man1/infadd.1.gz -%{_bindir}/ldif -%{_mandir}/man1/ldif.1.gz -%{_bindir}/migratecred -%{_mandir}/man1/migratecred.1.gz -%{_bindir}/mmldif -%{_mandir}/man1/mmldif.1.gz -%{_bindir}/rsearch -%{_mandir}/man1/rsearch.1.gz -%{_libexecdir}/%{pkgname}/ds_selinux_enabled -%{_libexecdir}/%{pkgname}/ds_selinux_port_query -%config(noreplace)%{_sysconfdir}/%{pkgname}/config/template-initconfig -%{_mandir}/man5/template-initconfig.5.gz -%{_datadir}/%{pkgname}/properties/*.res -%{_datadir}/%{pkgname}/script-templates -%{_datadir}/%{pkgname}/updates -%{_sbindir}/ldif2ldap -%{_mandir}/man8/ldif2ldap.8.gz -%{_sbindir}/bak2db -%{_mandir}/man8/bak2db.8.gz -%{_sbindir}/db2bak -%{_mandir}/man8/db2bak.8.gz -%{_sbindir}/db2index -%{_mandir}/man8/db2index.8.gz -%{_sbindir}/db2ldif -%{_mandir}/man8/db2ldif.8.gz -%{_sbindir}/dbverify -%{_mandir}/man8/dbverify.8.gz -%{_sbindir}/ldif2db -%{_mandir}/man8/ldif2db.8.gz -%{_sbindir}/restart-dirsrv -%{_mandir}/man8/restart-dirsrv.8.gz -%{_sbindir}/start-dirsrv -%{_mandir}/man8/start-dirsrv.8.gz -%{_sbindir}/status-dirsrv -%{_mandir}/man8/status-dirsrv.8.gz -%{_sbindir}/stop-dirsrv -%{_mandir}/man8/stop-dirsrv.8.gz -%{_sbindir}/upgradedb -%{_mandir}/man8/upgradedb.8.gz -%{_sbindir}/vlvindex -%{_mandir}/man8/vlvindex.8.gz -%{_sbindir}/monitor -%{_mandir}/man8/monitor.8.gz -%{_sbindir}/dbmon.sh -%{_mandir}/man8/dbmon.sh.8.gz -%{_sbindir}/dn2rdn -%{_mandir}/man8/dn2rdn.8.gz -%{_sbindir}/restoreconfig -%{_mandir}/man8/restoreconfig.8.gz -%{_sbindir}/saveconfig -%{_mandir}/man8/saveconfig.8.gz -%{_sbindir}/suffix2instance -%{_mandir}/man8/suffix2instance.8.gz -%{_sbindir}/upgradednformat -%{_mandir}/man8/upgradednformat.8.gz -%{_mandir}/man1/dbgen.pl.1.gz -%{_bindir}/repl-monitor -%{_mandir}/man1/repl-monitor.1.gz -%{_bindir}/repl-monitor.pl -%{_mandir}/man1/repl-monitor.pl.1.gz -%{_bindir}/cl-dump -%{_mandir}/man1/cl-dump.1.gz -%{_bindir}/cl-dump.pl -%{_mandir}/man1/cl-dump.pl.1.gz -%{_bindir}/dbgen.pl -%{_mandir}/man8/bak2db.pl.8.gz -%{_sbindir}/bak2db.pl -%{_sbindir}/cleanallruv.pl -%{_mandir}/man8/cleanallruv.pl.8.gz -%{_sbindir}/db2bak.pl -%{_mandir}/man8/db2bak.pl.8.gz -%{_sbindir}/db2index.pl -%{_mandir}/man8/db2index.pl.8.gz -%{_sbindir}/db2ldif.pl -%{_mandir}/man8/db2ldif.pl.8.gz -%{_sbindir}/fixup-linkedattrs.pl -%{_mandir}/man8/fixup-linkedattrs.pl.8.gz -%{_sbindir}/fixup-memberof.pl -%{_mandir}/man8/fixup-memberof.pl.8.gz -%{_sbindir}/ldif2db.pl -%{_mandir}/man8/ldif2db.pl.8.gz -%{_sbindir}/migrate-ds.pl -%{_mandir}/man8/migrate-ds.pl.8.gz -%{_sbindir}/ns-accountstatus.pl -%{_mandir}/man8/ns-accountstatus.pl.8.gz -%{_sbindir}/ns-activate.pl -%{_mandir}/man8/ns-activate.pl.8.gz -%{_sbindir}/ns-inactivate.pl -%{_mandir}/man8/ns-inactivate.pl.8.gz -%{_sbindir}/ns-newpwpolicy.pl -%{_mandir}/man8/ns-newpwpolicy.pl.8.gz -%{_sbindir}/remove-ds.pl -%{_mandir}/man8/remove-ds.pl.8.gz -%{_sbindir}/schema-reload.pl -%{_mandir}/man8/schema-reload.pl.8.gz -%{_sbindir}/setup-ds.pl -%{_mandir}/man8/setup-ds.pl.8.gz -%{_sbindir}/syntax-validate.pl -%{_mandir}/man8/syntax-validate.pl.8.gz -%{_sbindir}/usn-tombstone-cleanup.pl -%{_mandir}/man8/usn-tombstone-cleanup.pl.8.gz -%{_sbindir}/verify-db.pl -%{_mandir}/man8/verify-db.pl.8.gz -%{_libdir}/%{pkgname}/perl -%endif - %files snmp %doc LICENSE LICENSE.GPLv3+ LICENSE.openssl README.devel %config(noreplace)%{_sysconfdir}/%{pkgname}/config/ldap-agent.conf @@ -794,6 +619,87 @@ exit 0 %endif %changelog +* Mon Oct 26 2020 Mark Reynolds - 1.4.4.6-1 +- Bump version to 1.4.4.6 +- Issue 4262 - Remove legacy tools subpackage (final cleanup) +- Issue 4262 - Remove legacy tools subpackage (restart instances after rpm install) +- Issue 4262 - Remove legacy tools subpackage +- Issue 2526 - revert API change in slapi_be_getsuffix() +- Issue 4363 - Sync repl: per thread structure was incorrectly initialized (#4395) +- Issue 4392 - Update create_test.py +- Issue 2820 - Fix CI tests (#4365) +- Issue 2526 - suffix management in backends incorrect +- Issue 4389 - errors log with incorrectly formatted message parent_update_on_childchange +- Issue 4295 - Fix a closing quote issue (#4386) +- Issue 1199 - Misleading message in access log for idle timeout (#4385) +- Issue 3600 - RFE - openldap migration tooling (#4318) +- Issue 4176 - import ldif2cl task should not close all changelogs +- Issue 4159 - Healthcheck code DSBLE0002 not returned on disabled suffix +- Issue 4379 - allow more than 1 empty AttributeDescription for ldapsearch, without the risk of denial of service (#4380) +- Issue 4329 - Sync repl - if a serie of updates target the same entry then the cookie get wrong changenumber (#4356) +- Issue 3555 - Fix npm audit issues (#4370) +- Issue 4372 - BUG - Chaining DB did not validate bind mech parameters (#4374) +- Issue 4334 - RFE - Task timeout may cause larger dataset imports to fail (#4359) +- Issue 4361 - RFE - add - dscreate --advanced flag to avoid user confusion +- Issue 4368 - ds-replcheck crashes when processing glue entries +- Issue 4366 - lib389 - Fix account status inactivity checks +- Issue 4265 - UI - Make the secondary plugins read-only (#4364) +- Issue 4360 - password policy max sequence sets is not working as expected +- Issue 4348 - Add tests for dsidm +- Issue 4350 - One line, fix invalid type error in tls_cacertdir check (#4358) + +* Sun Oct 25 2020 Mark Reynolds - 1.4.4.5-1 +- Bump version to 1.4.4.5 +- Issue 4347 - log when server requires a restart for a plugin to become active (#4352) +- Issue 4297 - On ADD replication URP issue internal searches with filter containing unescaped chars (#4355) +- Issue 4350 - dsrc should warn when tls_cacertdir is invalid (#4353) +- Issue 4351 - improve generated sssd.conf output (#4354) +- Issue 4345 - import self sign cert doc comment (#4346) +- Issue 4342 - UI - additional fixes for creation instance modal +- Issue 3996 - Add dsidm rename option (#4338) +- Issue 4258 - Add server version information to UI +- Issue 4326 - entryuuid fixup did not work correctly (#4328) +- Issue 4209 - RFE - add bootstrap credentials to repl agreement (upgrade update) +- Issue 4209 - RFE - add bootstrap credentials to repl agreement (UI update) +- Issue 4209 - RFE - add bootstrap credentials to repl agreement +- Issue 4209 - RFE - add bootstrap credentials to repl agreement +- Issue 4322 - Fix a source link (#4332) +- Issue 4319 - Performance search rate: listener may be erroneously waken up (#4323) +- Issue 4322 - Updates old reference to pagure issue (#4321) +- Issue 4327 - Update issue templates and README.md +- Ticket 51190 - SyncRepl plugin provides a wrong cookie +- Ticket 51121 - Remove hardcoded changelog file name +- Ticket 51253 - dscreate should LDAPI to bootstrap the config +- Ticket 51177 - fix warnings +- Ticket 51228 - Fix lock/unlock wording and lib389 use of methods +- Ticket 51247 - Container Healthcheck failure +- Ticket 51177 - on upgrade configuration handlers +- Ticket 51229 - Server Settings page gets into an unresponsive state +- Ticket 51189 - integrate changelog in main database - update CLI +- Ticket 49562 - integrate changelog database to main database +- Ticket 51165 - Set the operation start time for extended ops +- Ticket 50933 - Fix OID change between 10rfc2307 and 10rfc2307compat +- Ticket 51228 - Clean up dsidm user status command +- Ticket 51233 - ds-replcheck crashes in offline mode +- Ticket 50260 - Fix test according to #51222 fix +- Ticket 50952 - SSCA lacks basicConstraint:CA +- Ticket 50933 - enable 2307compat.ldif by default +- Ticket 50933 - Update 2307compat.ldif +- Ticket 51102 - RFE - ds-replcheck - make online timeout configurable +- Ticket 51222 - It should not be allowed to delete Managed Entry manually +- Ticket 51129 - SSL alert: The value of sslVersionMax "TLS1.3" is higher than the supported version +- Ticket 49487 - Restore function that incorrectly removed by last patch +- Ticket 49481 - remove unused or unnecessary database plugin functions +- Ticket 50746 - Add option to healthcheck to list all the lint reports +- Ticket 49487 - Cleanup unused code +- Ticket 51086 - Fix instance name length for interactive install +- Ticket 51136 - JSON Error output has redundant messages +- Ticket 51059 - If dbhome directory is set online backup fails +- Ticket 51000 - Separate the BDB backend monitors +- Ticket 49300 - entryUSN is duplicated after memberOf operation +- Ticket 50984 - Fix disk_mon_check_diskspace types +- Ticket 50791 - Healthcheck to find notes=F + * Tue Sep 29 22:52:34 CEST 2020 Zbigniew Jędrzejewski-Szmek - 1.4.4.4-1.4 - Rebuilt for libevent 2.1.12 (attempt #2) diff --git a/sources b/sources index 0d25cf6..b516217 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ +SHA512 (389-ds-base-1.4.4.6.tar.bz2) = 4ce55096ce82b4de40341348ee6e8e785b27759980b5400567033ebeafd4b87317932d005ea213985db9a642aab11799c01e96a0a6df6747a92cbbda0c283c81 SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 -SHA512 (389-ds-base-1.4.4.4.tar.bz2) = e819a736ba30a1b2c35a180dac9815b7f90d1de32050c87f4fd996596ab466b603deca3ab0701eaf4753e820a23dc53f67f68a35397bbbbe41cf655b4a679bef From 6c4e197d982eb26f1b0039e104d8a4cc3ce2ad65 Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Tue, 27 Oct 2020 16:18:54 -0700 Subject: [PATCH 004/125] Backport fix for Issue 2526 - retrocl backend created out of order --- ...retrocl-backend-created-out-of-order.patch | 103 ++++++++++++++++++ 389-ds-base.spec | 10 +- 2 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 0001-Issue-2526-retrocl-backend-created-out-of-order.patch diff --git a/0001-Issue-2526-retrocl-backend-created-out-of-order.patch b/0001-Issue-2526-retrocl-backend-created-out-of-order.patch new file mode 100644 index 0000000..c6f7fed --- /dev/null +++ b/0001-Issue-2526-retrocl-backend-created-out-of-order.patch @@ -0,0 +1,103 @@ +From 67c8b8702a249cb0ef1ebf49b6e87056cd5339f6 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 27 Oct 2020 13:14:55 -0400 +Subject: [PATCH] Issue 2526 - retrocl backend created out of order + +Bug Description: A recent change verified that you do not create + a mappingtree entry before the backend entry was + created. The server created the retrocl backend + in the opposite order which broke the retrocl. + +Fix Description: Create the retrocl backend entry before creating + the mapping tree entry. + +Relates: https://github.com/389ds/389-ds-base/issues/2526 + +Reviewed by: viktor(Thanks!) +--- + ldap/servers/plugins/retrocl/retrocl.c | 10 ++--- + ldap/servers/plugins/retrocl/retrocl_create.c | 38 +++++++++---------- + 2 files changed, 22 insertions(+), 26 deletions(-) + +diff --git a/ldap/servers/plugins/retrocl/retrocl.c b/ldap/servers/plugins/retrocl/retrocl.c +index 4af4d752b..8d6135dad 100644 +--- a/ldap/servers/plugins/retrocl/retrocl.c ++++ b/ldap/servers/plugins/retrocl/retrocl.c +@@ -222,15 +222,11 @@ retrocl_select_backend(void) + slapi_entry_free(referral); + + if (err != LDAP_SUCCESS || be == NULL || be == defbackend_get_backend()) { +- slapi_log_err(SLAPI_LOG_ERR, RETROCL_PLUGIN_NAME, ++ /* Could not find the backend for cn=changelog, either because ++ * it doesn't exist mapping tree not registered. */ ++ slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, + "retrocl_select_backend - Mapping tree select failed (%d) %s.\n", err, errbuf); +- +- /* could not find the backend for cn=changelog, either because +- * it doesn't exist +- * mapping tree not registered. +- */ + err = retrocl_create_config(); +- + if (err != LDAP_SUCCESS) + return err; + } else { +diff --git a/ldap/servers/plugins/retrocl/retrocl_create.c b/ldap/servers/plugins/retrocl/retrocl_create.c +index fb1503520..571e6899f 100644 +--- a/ldap/servers/plugins/retrocl/retrocl_create.c ++++ b/ldap/servers/plugins/retrocl/retrocl_create.c +@@ -192,6 +192,25 @@ retrocl_create_config(void) + vals[0] = &val; + vals[1] = NULL; + ++ retrocl_be_changelog = slapi_be_select_by_instance_name("changelog"); ++ ++ if (retrocl_be_changelog == NULL) { ++ /* This is not the nsslapd-changelogdir from cn=changelog4,cn=config */ ++ char *bedir; ++ ++ bedir = retrocl_get_config_str(CONFIG_CHANGELOG_DIRECTORY_ATTRIBUTE); ++ if (bedir == NULL) { ++ /* none specified */ ++ } ++ ++ rc = retrocl_create_be(bedir); ++ slapi_ch_free_string(&bedir); ++ if (rc != LDAP_SUCCESS && rc != LDAP_ALREADY_EXISTS) { ++ return rc; ++ } ++ retrocl_be_changelog = slapi_be_select_by_instance_name("changelog"); ++ } ++ + /* Assume the mapping tree node is missing. It doesn't hurt to + * attempt to add it if it already exists. You will see a warning + * in the errors file when the referenced backend does not exist. +@@ -256,25 +275,6 @@ retrocl_create_config(void) + return rc; + } + +- retrocl_be_changelog = slapi_be_select_by_instance_name("changelog"); +- +- if (retrocl_be_changelog == NULL) { +- /* This is not the nsslapd-changelogdir from cn=changelog4,cn=config */ +- char *bedir; +- +- bedir = retrocl_get_config_str(CONFIG_CHANGELOG_DIRECTORY_ATTRIBUTE); +- if (bedir == NULL) { +- /* none specified */ +- } +- +- rc = retrocl_create_be(bedir); +- slapi_ch_free_string(&bedir); +- if (rc != LDAP_SUCCESS && rc != LDAP_ALREADY_EXISTS) { +- return rc; +- } +- retrocl_be_changelog = slapi_be_select_by_instance_name("changelog"); +- } +- + return LDAP_SUCCESS; + } + +-- +2.28.0 + diff --git a/389-ds-base.spec b/389-ds-base.spec index d7d8b4e..ae71400 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,7 +47,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 1.4.4.6 -Release: %{?relprefix}1%{?prerel}%{?dist} +Release: %{?relprefix}2%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -171,6 +171,9 @@ Source2: %{name}-devel.README Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download/%{jemalloc_ver}/%{jemalloc_name}-%{jemalloc_ver}.tar.bz2 %endif +# https://github.com/389ds/389-ds-base/commit/67c8b8702a249cb0ef1ebf49b6e87056cd5339f6 +Patch0: 0001-Issue-2526-retrocl-backend-created-out-of-order.patch + %description 389 Directory Server is an LDAPv3 compliant server. The base package includes the LDAP server and command line utilities for server administration. @@ -274,6 +277,8 @@ A cockpit UI Plugin for configuring and administering the 389 Directory Server %setup -q -n %{name}-%{version}%{?prerel} -T -D -b 3 %endif +%patch0 -p1 + cp %{SOURCE2} README.devel %build @@ -619,6 +624,9 @@ exit 0 %endif %changelog +* Tue Oct 27 2020 Adam Williamson - 1.4.4.6-2 +- Backport fix for Issue 2526 - retrocl backend created out of order + * Mon Oct 26 2020 Mark Reynolds - 1.4.4.6-1 - Bump version to 1.4.4.6 - Issue 4262 - Remove legacy tools subpackage (final cleanup) From aa29d088bcef7e8a78124abba9248f8439d3b7dc Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Wed, 28 Oct 2020 12:41:33 -0400 Subject: [PATCH 005/125] Bump version to 1.4.5.0 Issue 2526 - revert backend validation check Issue 4262 - more perl removal cleanup Issue 2526 - retrocl backend created out of order --- .gitignore | 1 + 389-ds-base.spec | 1554 +--------------------------------------------- sources | 2 +- 3 files changed, 9 insertions(+), 1548 deletions(-) diff --git a/.gitignore b/.gitignore index 8ba40b0..1fe4508 100644 --- a/.gitignore +++ b/.gitignore @@ -197,3 +197,4 @@ /389-ds-base-1.4.4.3.tar.bz2 /389-ds-base-1.4.4.4.tar.bz2 /389-ds-base-1.4.4.6.tar.bz2 +/389-ds-base-1.4.5.0.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index ae71400..2b12202 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,8 +46,8 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 1.4.4.6 -Release: %{?relprefix}2%{?prerel}%{?dist} +Version: 1.4.5.0 +Release: %{?relprefix}1%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -171,9 +171,6 @@ Source2: %{name}-devel.README Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download/%{jemalloc_ver}/%{jemalloc_name}-%{jemalloc_ver}.tar.bz2 %endif -# https://github.com/389ds/389-ds-base/commit/67c8b8702a249cb0ef1ebf49b6e87056cd5339f6 -Patch0: 0001-Issue-2526-retrocl-backend-created-out-of-order.patch - %description 389 Directory Server is an LDAPv3 compliant server. The base package includes the LDAP server and command line utilities for server administration. @@ -277,8 +274,6 @@ A cockpit UI Plugin for configuring and administering the 389 Directory Server %setup -q -n %{name}-%{version}%{?prerel} -T -D -b 3 %endif -%patch0 -p1 - cp %{SOURCE2} README.devel %build @@ -624,8 +619,11 @@ exit 0 %endif %changelog -* Tue Oct 27 2020 Adam Williamson - 1.4.4.6-2 -- Backport fix for Issue 2526 - retrocl backend created out of order +* Wed Oct 28 2020 Mark Reynolds - 1.4.5.0-1 +- Bump version to 1.4.5.0 +- Issue 2526 - revert backend validation check +- Issue 4262 - more perl removal cleanup +- Issue 2526 - retrocl backend created out of order * Mon Oct 26 2020 Mark Reynolds - 1.4.4.6-1 - Bump version to 1.4.4.6 @@ -656,1541 +654,3 @@ exit 0 - Issue 4348 - Add tests for dsidm - Issue 4350 - One line, fix invalid type error in tls_cacertdir check (#4358) -* Sun Oct 25 2020 Mark Reynolds - 1.4.4.5-1 -- Bump version to 1.4.4.5 -- Issue 4347 - log when server requires a restart for a plugin to become active (#4352) -- Issue 4297 - On ADD replication URP issue internal searches with filter containing unescaped chars (#4355) -- Issue 4350 - dsrc should warn when tls_cacertdir is invalid (#4353) -- Issue 4351 - improve generated sssd.conf output (#4354) -- Issue 4345 - import self sign cert doc comment (#4346) -- Issue 4342 - UI - additional fixes for creation instance modal -- Issue 3996 - Add dsidm rename option (#4338) -- Issue 4258 - Add server version information to UI -- Issue 4326 - entryuuid fixup did not work correctly (#4328) -- Issue 4209 - RFE - add bootstrap credentials to repl agreement (upgrade update) -- Issue 4209 - RFE - add bootstrap credentials to repl agreement (UI update) -- Issue 4209 - RFE - add bootstrap credentials to repl agreement -- Issue 4209 - RFE - add bootstrap credentials to repl agreement -- Issue 4322 - Fix a source link (#4332) -- Issue 4319 - Performance search rate: listener may be erroneously waken up (#4323) -- Issue 4322 - Updates old reference to pagure issue (#4321) -- Issue 4327 - Update issue templates and README.md -- Ticket 51190 - SyncRepl plugin provides a wrong cookie -- Ticket 51121 - Remove hardcoded changelog file name -- Ticket 51253 - dscreate should LDAPI to bootstrap the config -- Ticket 51177 - fix warnings -- Ticket 51228 - Fix lock/unlock wording and lib389 use of methods -- Ticket 51247 - Container Healthcheck failure -- Ticket 51177 - on upgrade configuration handlers -- Ticket 51229 - Server Settings page gets into an unresponsive state -- Ticket 51189 - integrate changelog in main database - update CLI -- Ticket 49562 - integrate changelog database to main database -- Ticket 51165 - Set the operation start time for extended ops -- Ticket 50933 - Fix OID change between 10rfc2307 and 10rfc2307compat -- Ticket 51228 - Clean up dsidm user status command -- Ticket 51233 - ds-replcheck crashes in offline mode -- Ticket 50260 - Fix test according to #51222 fix -- Ticket 50952 - SSCA lacks basicConstraint:CA -- Ticket 50933 - enable 2307compat.ldif by default -- Ticket 50933 - Update 2307compat.ldif -- Ticket 51102 - RFE - ds-replcheck - make online timeout configurable -- Ticket 51222 - It should not be allowed to delete Managed Entry manually -- Ticket 51129 - SSL alert: The value of sslVersionMax "TLS1.3" is higher than the supported version -- Ticket 49487 - Restore function that incorrectly removed by last patch -- Ticket 49481 - remove unused or unnecessary database plugin functions -- Ticket 50746 - Add option to healthcheck to list all the lint reports -- Ticket 49487 - Cleanup unused code -- Ticket 51086 - Fix instance name length for interactive install -- Ticket 51136 - JSON Error output has redundant messages -- Ticket 51059 - If dbhome directory is set online backup fails -- Ticket 51000 - Separate the BDB backend monitors -- Ticket 49300 - entryUSN is duplicated after memberOf operation -- Ticket 50984 - Fix disk_mon_check_diskspace types -- Ticket 50791 - Healthcheck to find notes=F - -* Tue Sep 29 22:52:34 CEST 2020 Zbigniew Jędrzejewski-Szmek - 1.4.4.4-1.4 -- Rebuilt for libevent 2.1.12 (attempt #2) - -* Tue Sep 29 20:25:49 CEST 2020 Zbigniew Jędrzejewski-Szmek - 1.4.4.4-1.3 -- Rebuilt for libevent 2.1.12 - -* Thu Aug 27 2020 Josef Řídký - 1.4.4.4-1.2 -- Rebuilt for new net-snmp release - -* Mon Jul 27 2020 Fedora Release Engineering - 1.4.4.4-1.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild - -* Wed Jul 8 2020 Mark Reynolds - 1.4.4.4-1 -- Bump version to 1.4.4.4 -- Issue 51175 - resolve plugin name leaking -- Issue 51187 - UI - stop importing Cockpit's PF css -- Issue 51192 - Add option to reject internal unindexed searches -- Issue 50840 - Fix test docstrings metadata-1 -- Issue 50840 - Fix test docstrings metadata -- Issue 50980 - fix foo_filter_rewrite -- Issue 51165 - add more logconv stats for the new access log keywords -- Issue 50928 - Unable to create a suffix with countryName either via dscreate or the admin console -- Issue 51188 - db2ldif crashes when LDIF file can't be accessed -- Issue 50545 - Port remaining legacy tools to new python CLI -- Issue 51165 - add new access log keywords for wtime and optime -- Issue 49761 - Fix CI test suite issues ( Port remaning acceptance test suit part 1) -- Issue 51070 - Port Import TET module to python3 part2 -- Issue 51142 - Port manage Entry TET suit to python 3 part 1 -- Issue 50860 - Port Password Policy test cases from TET to python3 final -- Issue 50696 - Fix Allowed and Denied Ciphers lists - WebUI -- Issue 51169 - UI - attr uniqueness - selecting empty subtree crashes cockpit -- Issue 49256 - log warning when thread number is very different from autotuned value -- Issue 51157 - Reindex task may create abandoned index file -- Issue 50873 - Fix issues with healthcheck tool -- Issue 50860 - Port Password Policy test cases from TET to python3 part2 -- Issue 51166 - Log an error when a search is fully unindexed -- Issue 50544 - OpenLDAP syncrepl compatability -- Issue 51161 - fix SLE15.2 install issps -- Issue 49999 - rpm.mk build-cockpit should clean cockpit_dist first -- Issue 51144 - dsctl fails with instance names that contain slapd- -- Issue 51155 - Fix OID for sambaConfig objectclass -- Issue 51159 - dsidm ou delete fails -- Issue 50984 - Memory leaks in disk monitoring -- Issue 51131 - improve mutex alloc in conntable -- Issue 49761 - Fix CI tests -- Issue 49859 - A distinguished value can be missing in an entry -- Issue 50791 - Healthcheck should look for notes=A/F in access log -- Issue 51072 - Set the default minimum worker threads -- Issue 51140 - missing ifdef -- Issue 50912 - pwdReset can be modified by a user -- Issue 50781 - Make building cockpit plugin optional -- Issue 51100 - Correct numSubordinates value for cn=monitor -- Issue 51136 - dsctl and dsidm do not errors correctly when using JSON -- Issue 137 - fix compiler warning -- Issue 50781 - Make building cockpit plugin optional -- Issue 51132 - Winsync setting winSyncWindowsFilter not working as expected -- Issue 51034 - labeledURIObject -- Issue 50545 - Port remaining legacy tools to new python CLI -- Issue 50889 - Extract pem files into a private namespace -- Issue 137 - Implement EntryUUID plugin -- Issue 51072 - improve autotune defaults -- Issue 51115 - enable samba3.ldif by default -- Issue 51118 - UI - improve modal validation when creating an instance -- Issue 50746 - Add option to healthcheck to list all the lint reports - -* Mon Jun 22 2020 Jitka Plesnikova - 1.4.4.3-1.1 -- Perl 5.32 rebuild - -* Fri May 29 2020 Mark Reynolds - 1.4.4.3-1 -- Bump version to 1.4.4.3 -- Issue 50931 - RFE AD filter rewriter for ObjectCategory -- Issue 50860 - Port Password Policy test cases from TET to python3 part1 -- Issue 51113 - Allow using uid for replication manager entry -- Issue 51095 - abort operation if CSN can not be generated -- Issue 51110 - Fix ASAN ODR warnings -- Issue 49850 - ldbm_get_nonleaf_ids() painfully slow for databases with many non-leaf entries -- Issue 51102 - RFE - ds-replcheck - make online timeout configurable -- Issue 51076 - remove unnecessary slapi entry dups -- Issue 51086 - Improve dscreate instance name validation -- Issue:51070 - Port Import TET module to python3 part1 -- Issue 51037 - compiler warning -- Issue 50989 - ignore pid when it is ourself in protect_db -- Issue 51037 - RFE AD filter rewriter for ObjectSID -- Issue 50499 - Fix some npm audit issues -- Issue 51091 - healthcheck json report fails when mapping tree is deleted -- Issue 51079 - container pid start and stop issues -- Issue 49761 - Fix CI tests -- Issue 50610 - Fix return code when it's nothing to free -- Issue 50610 - memory leaks in dbscan and changelog encryption -- Issue 51076 - prevent unnecessarily duplication of the target entry -- Issue 50940 - Permissions of some shipped directories may change over time -- Issue 50873 - Fix issues with healthcheck tool -- Issue 51082 - abort when a empty valueset is freed -- Issue 50201 - nsIndexIDListScanLimit accepts any value - -* Tue May 26 2020 Miro Hrončok - 1.4.4.2-1.2 -- Rebuilt for Python 3.9 - -* Fri May 15 2020 Pete Walter - 1.4.4.2-1.1 -- Rebuild for ICU 67 - -* Fri May 8 2020 Mark Reynolds - 1.4.4.2-1 -- Bump version to 1.4.4.2 -- Issue 51078 - Add nsslapd-enable-upgrade-hash to the schema -- Issue 51054 - Revise ACI target syntax checking -- Issue 51068 - deadlock when updating the schema -- Issue 51042 - try to use both c_rehash and openssl rehash -- Issue 51042 - switch from c_rehash to openssl rehash -- Issue 50992 - Bump jemalloc version and enable profiling -- Issue 51060 - unable to set sslVersionMin to TLS1.0 -- Issue 51064 - Unable to install server where IPv6 is disabled -- Issue 51051 - CLI fix consistency issues with confirmations -- Issue 50655 - etime displayed has an order of magnitude 10 times smaller than it should be -- Issue 49731 - undo db_home_dir under /dev/shm/dirsrv for now -- Issue 51054 - AddressSanitizer: heap-buffer-overflow in ldap_utf8prev -- Issue 49761 - Fix CI tests -- Issue 51047 - React deprecating ComponentWillMount -- Issue 50499 - fix npm audit issues -- Issue 50545 - Port dbgen.pl to dsctl -- Issue 51027 - Test passwordHistory is not rewritten on a fail attempt - -* Wed Apr 22 2020 Mark Reynolds - 1.4.4.1-1 -- Bump version to 1.4.4.1 -- Issue 51024 - syncrepl_entry callback does not contain attributes added by postoperation plugins -- Issue 50877 - task to run tests of csn generator -- Issue 49731 - undo db_home_dir under /dev/shm/dirsrv for now -- Issue 48055 - CI test - automember_plugin(part3) -- Issue 51035 - Heavy StartTLS connection load can randomly fail with err=1 -- Issue 51031 - UI - transition between two instances needs improvement - -* Thu Apr 16 2020 Mark Reynolds - 1.4.4.0-1 -- Bump version to 1.4.4.0 -- Issue 50933 - 10rfc2307compat.ldif is not ready to be used by default -- Issue 50931 - RFE AD filter rewriter for ObjectCategory -- Issue 51016 - Fix memory leaks in changelog5_init and perfctrs_init -- Issue 50980 - RFE extend usability for slapi_compute_add_search_rewriter and slapi_compute_add_evaluator -- Issue 51008 - dbhome in containers -- Issue 50875 - Refactor passwordUserAttributes's and passwordBadWords's code -- Issue 51014 - slapi_pal.c possible static buffer overflow -- Issue 50545 - remove dbmon "incr" option from arg parser -- Issue 50545 - Port dbmon.sh to dsconf -- Issue 51005 - AttributeUniqueness plugin's DN parameter should not have a default value -- Issue 49731 - Fix additional issues with setting db home directory by default -- Issue 50337 - Replace exec() with setattr() -- Issue 50905 - intermittent SSL hang with rhds -- Issue 50952 - SSCA lacks basicConstraint:CA -- Issue 50640 - Database links: get_monitor() takes 1 positional argument but 2 were given -- Issue 50869 - Setting nsslapd-allowed-sasl-mechanisms truncates the value - -* Wed Apr 1 2020 Mark Reynolds - 1.4.3.5-1 -- Bump version to 1.4.3.5 -- Issue 50994 - Fix latest UI bugs found by QE -- Issue 50933 - rfc2307compat.ldif -- Issue 50337 - Replace exec() with setattr() -- Issue 50984 - Memory leaks in disk monitoring -- Issue 50984 - Memory leaks in disk monitoring -- Issue 49731 - dscreate fails in silent mode because of db_home_dir -- Issue 50975 - Revise UI branding with new minimized build -- Issue 49437 - Fix memory leak with indirect COS -- Issue 49731 - Do not add db_home_dir to template-dse.ldif -- Issue 49731 - set and use db_home_directory by default -- Issue 50971 - fix BSD_SOURCE -- Issue 50744 - -n option of dbverify does not work -- Issue 50952 - SSCA lacks basicConstraint:CA -- Issue 50976 - Clean up Web UI source directory from unused files -- Issue 50955 - Fix memory leaks in chaining plugin(part 2) -- Issue 50966 - UI - Database indexes not using typeAhead correctly -- Issue 50974 - UI - wrong title in "Delete Suffix" popup -- Issue 50972 - Fix cockpit plugin build -- Issue 49761 - Fix CI test suite issues -- Issue 50971 - Support building on FreeBSD. -- Issue 50960 - [RFE] Advance options in RHDS Disk Monitoring Framework -- Issue 50800 - wildcards in rootdn-allow-ip attribute are not accepted -- Issue 50963 - We should bundle *.min.js files of Console -- Issue 50860 - Port Password Policy test cases from TET to python3 Password grace limit section. -- Issue 50860 - Port Password Policy test cases from TET to python3 series of bugs Port final -- Issue 50954 - buildnum.py - fix date formatting issue - -* Mon Mar 16 2020 Mark Reynolds - 1.4.3.4-1 -- Bump version to 1.4.3.4 -- Issue 50954 - Port buildnum.pl to python(part 2) -- Issue 50955 - Fix memory leaks in chaining plugin -- Issue 50954 - Port buildnum.pl to python -- Issue 50947 - change 00core.ldif objectClasses for openldap migration -- Issue 50755 - setting nsslapd-db-home-directory is overriding db_directory -- Issue 50937 - Update CLI for new backend split configuration -- Issue 50860 - Port Password Policy test cases from TET to python3 pwp.sh -- Issue 50945 - givenname alias of gn from openldap -- Issue 50935 - systemd override in lib389 for dscontainer -- Issue 50499 - Fix npm audit issues -- Issue 49761 - Fix CI test suite issues -- Issue 50618 - clean compiler warning and log level -- Issue 50889 - fix compiler issues -- Issue 50884 - Health check tool DSEldif check fails -- Issue 50926 - Remove dual spinner and other UI fixes -- Issue 50928 - Unable to create a suffix with countryName -- Issue 50758 - Only Recommend bash-completion, not Require -- Issue 50923 - Fix a test regression -- Issue 50904 - Connect All React Components And Refactor the Main Navigation Tab Code -- Issue 50920 - cl-dump exit code is 0 even if command fails with invalid arguments -- Issue 50923 - Add test - dsctl fails to remove instances with dashes in the name -- Issue 50919 - Backend delete fails using dsconf -- Issue 50872 - dsconf can't create GSSAPI replication agreements -- Issue 50912 - RFE - add password policy attribute pwdReset -- Issue 50914 - No error returned when adding an entry matching filters for a non existing automember group -- Issue 50889 - Extract pem files into a private namespace -- Issue 50909 - nsDS5ReplicaId cant be set to the old value it had before -- Issue 50686 - Port fractional replication test cases from TET to python3 final -- Issue 49845 - Remove pkgconfig check for libasan -- Issue:50860 - Port Password Policy test cases from TET to python3 bug624080 -- Issue:50860 - Port Password Policy test cases from TET to python3 series of bugs -- Issue 50786 - connection table freelist -- Issue 50618 - support cgroupv2 -- Issue 50900 - Fix cargo offline build -- Issue 50898 - ldclt core dumped when run with -e genldif option - -* Mon Feb 17 2020 Matus Honek - 1.4.3.3-3 -- Bring back the necessary c_rehash util (#1803370) - -* Fri Feb 14 2020 Mark Reynolds - 1.4.3.3-2 -- Bump version to 1.4.3.3-2 -- Remove unneeded perl dependencies -- Change bash-completion to "Recommends" instead of "Requires" - -* Thu Feb 13 2020 Mark Reynolds - 1.4.3.3-1 -- Bump version to 1.4.3.3 -- Issue 50855 - remove unused file from UI -- Issue 50855 - UI: Port Server Tab to React -- Issue 49845 - README does not contain complete information on building -- Issue 50686 - Port fractional replication test cases from TET to python3 part 1 -- Issue 49623 - cont cenotaph errors on modrdn operations -- Issue 50882 - Fix healthcheck errors for instances that do not have TLS enabled -- Issue 50886 - Typo in the replication debug message -- Issue 50873 - Fix healthcheck and virtual attr check -- Issue 50873 - Fix issues with healthcheck tool -- Issue 50028 - Add a new CI test case -- Issue 49946 - Add a new CI test case -- Issue 50117 - Add a new CI test case -- Issue 50787 - fix implementation of attr unique -- Issue 50859 - support running only with ldaps socket -- Issue 50823 - dsctl doesn't work with 'slapd-' in the instance name -- Issue 49624 - cont - DB Deadlock on modrdn appears to corrupt database and entry cache -- Issue 50867 - Fix minor buildsys issues -- Issue 50737 - Allow building with rust online without vendoring -- Issue 50831 - add cargo.lock to allow offline builds -- Issue 50694 - import PEM certs on startup -- Issue 50857 - Memory leak in ACI using IP subject -- Issue 49761 - Fix CI test suite issues -- Issue 50853 - Fix NULL pointer deref in config setting -- Issue 50850 - Fix dsctl healthcheck for python36 -- Issue 49990 - Need to enforce a hard maximum limit for file descriptors -- Issue 48707 - ldapssotoken for authentication - -* Tue Jan 28 2020 Fedora Release Engineering - 1.4.3.2-1.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild - -* Thu Jan 23 2020 Mark Reynolds - 1.4.3.2-1 -- Bump version to 1.4.3.2 -- Issue 49254 - Fix compiler failures and warnings -- Issue 50741 - cont bdb_start - Detected Disorderly Shutdown -- Issue 50836 - Port Schema UI tab to React -- Issue 50842 - Decrease 389-console Cockpit component size -- Issue 50790 - Add result text when filter is invalid -- Issue 50627 - Add ASAN logs to HTML report -- Issue 50834 - Incorrectly setting the NSS default SSL version max -- Issue 50829 - Disk monitoring rotated log cleanup causes heap-use-after-free -- Issue 50709 - (cont) Several memory leaks reported by Valgrind for 389-ds 1.3.9.1-10 -- Issue 50784 - performance testing scripts -- Issue 50599 - Fix memory leak when removing db region files -- Issue 49395 - Set the default TLS version min to TLS1.2 -- Issue 50818 - dsconf pwdpolicy get error -- Issue 50824 - dsctl remove fails with "name 'ensure_str' is not defined" -- Issue 50599 - Remove db region files prior to db recovery -- Issue 50812 - dscontainer executable should be placed under /usr/libexec/dirsrv/ -- Issue 50816 - dsconf allows the root password to be set to nothing -- Issue 50798 - incorrect bytes in format string(fix import issue) - -* Thu Jan 16 2020 Adam Williamson - 1.4.3.1-3 -- Backport two more import/missing function fixes - -* Wed Jan 15 2020 Adam Williamson - 1.4.3.1-2 -- Backport 828aad0 to fix missing imports from 1.4.3.1 - -* Mon Jan 13 2020 Mark Reynolds - 1.4.3.1-1 -- Bump version to 1.4.3.1 -- Issue 50798 - incorrect bytes in format string -- Issue 50545 - Add the new replication monitor functionality to UI -- Issue 50806 - Fix minor issues in lib389 health checks -- Issue 50690 - Port Password Storage test cases from TET to python3 part 1 -- Issue 49761 - Fix CI test suite issues -- Issue 49761 - Fix CI test suite issues -- Issue 50754 - Add Restore Change Log option to CLI -- Issue 48055 - CI test - automember_plugin(part2) -- Issue 50667 - dsctl -l did not respect PREFIX -- Issue 50780 - More CLI fixes -- Issue 50649 - lib389 without defaults.inf -- Issue 50780 - Fix UI issues -- Issue 50727 - correct mistaken options in filter validation patch -- Issue 50779 - lib389 - conflict compare fails for DN's with spaces -- Set branch version to 1.4.3.0 - -* Mon Dec 9 2019 Matus Honek - 1.4.2.5-3 -- Bump version to 1.4.2.5-3 -- Fix python-argcomplete tinkering (#1781131) - -* Fri Dec 6 2019 Mark Reynolds - 1.4.2.5-2 -- Bump version to 1.4.2.5-2 -- Fix specfile typo (bash-completion) - -* Fri Dec 6 2019 Mark Reynolds - 1.4.2.5-1 -- Bump version to 1.4.2.5 -- Issue 50747 - Port readnsstate to dsctl -- Issue 50758 - Enable CLI arg completion -- Issue 50753 - Dumping the changelog to a file doesn't work -- Issue 50745 - ns-slapd hangs during CleanAllRUV tests -- Issue 50734 - lib389 creates non-SSCA cert DBs with misleading README.txt -- Issue 48851 - investigate and port TET matching rules filter tests(cert) -- Issue 50443 - Create a module in lib389 to Convert a byte sequence to a properly escaped for LDAP -- Issue 50664 - DS can fail to recover if an empty directory exists in db -- Issue 50736 - RetroCL trimming may crash at shutdown if trimming configuration is invalid -- Issue 50741 - bdb_start - Detected Disorderly Shutdown last time Directory Server was running -- Issue 50572 - After running cl-dump dbdir/cldb/*ldif.done are not deleted -- Issue 50701 - Fix type in lint report -- Issue 50729 - add support for gssapi tests on suse -- Issue 50701 - Add additional healthchecks to dsconf -- Issue 50711 - `dsconf security` lacks option for setting nsTLSAllowClientRenegotiation attribute -- Issue 50439 - Update docker integration for Fedora -- Issue 48851 - Investigate and port TET matching rules filter tests(last test cases for match) -- Issue 50499 - Fix npm audit issues -- Issue 50722 - Test IDs are not unique -- Issue 50712 - Version comparison doesn't work correctly on git builds -- Issue 50499 - Fix npm audit issues -- Issue 50706 - Missing lib389 dependency - packaging - -* Fri Nov 15 2019 Mark Reynolds - 1.4.2.4-2 -- Bump version to 1.4.2.4-2 -- Fix dependancy issue - -* Thu Nov 14 2019 Mark Reynolds - 1.4.2.4-1 -- Bump version to 1.4.2.4 -- Issue 50634 - Fix CLI error parsing for non-string values -- Issue 50659 - AddressSanitizer: SEGV ... in bdb_pre_close -- Issue 50716 - CVE-2019-14824 (BZ#1748199) - deref plugin displays restricted attributes -- Issue 50644 - fix regression with creating sample entries -- Issue 50699 - Add Disk Monitor to CLI and UI -- Issue 50716 - CVE-2019-14824 (BZ#1748199) - deref plugin displays restricted attributes -- Issue 50536 - After audit log file is rotated, DS version string is logged after each update -- Issue 50712 - Version comparison doesn't work correctly on git builds -- Issue 50706 - Missing lib389 dependency - packaging -- Issue 49761 - Fix CI test suite issues -- Issue 50683 - Makefile.am contains unused RPM-related targets -- Issue 50696 - Fix various UI bugs -- Issue 50641 - Update default aci to allows users to change their own password -- Issue 50007, 50648 - improve x509 handling in dsctl -- Issue 50689 - Failed db restore task does not report an error -- Issue 50199 - Disable perl by default -- Issue 50633 - Add cargo vendor support for offline builds -- Issue 50499 - Fix npm audit issues - -* Sun Nov 03 2019 Mark Reynolds - 1.4.2.3-1 -- Bump version to 1.4.2.3 -- Issue 50592 - Port Replication Tab to ReactJS -- Issue 50680 - Remove branding from upstream spec file -- Issue 50669 - Remove nunc-stans in favour of reworking current conn code (add.) -- Issue 48055 - CI test - automember_plugin(part1) -- Issue 50677 - Map subtree searches with NULL base to default naming context -- Issue 50669 - Fix RPM build -- Issue 50669 - remove nunc-stans -- Issue 49850 - cont -fix crash in ldbm_non_leaf -- Issue 50634 - Clean up CLI errors output - Fix wrong exception -- Issue 50660 - Build failure on Fedora 31 -- Issue 50634 - Clean up CLI errors output -- Issue 48851 - Investigate and port TET matching rules filter tests(match more test cases) -- Issue 50428 - Log the actual base DN when the search fails with "invalid attribute request" -- Issue 49850 - ldbm_get_nonleaf_ids() slow for databases with many non-leaf entries -- Issue 50655 - access log etime is not properly formatted -- Issue 50653 - objectclass parsing fails to log error message text -- Issue 50646 - Improve task handling during shutdowns -- Issue 50627 - Support platforms without pytest_html -- Issue 49476 - backend refactoring phase1, fix failing tests -- Issue 49476 - refactor ldbm backend to allow replacement of BDB -- Issue 50349 - additional fix: filter schema check must handle subtypes -- Issue 48851 - investigate and port TET matching rules filter tests(indexing more test cases) -- Issue 50638 - RecursionError: maximum recursion depth exceeded while calling a Python object -- Issue 50636 - Crash during sasl bind -- Issue 50632 - Add ensure attr state so that diffs are easier from 389-ds-portal -- Issue 50619 - extend commands to have more modify options -- Issue 50499 - Fix npm audit issues - -* Fri Nov 01 2019 Pete Walter - 1.4.2.2-3.1 -- Rebuild for ICU 65 - -* Fri Sep 27 2019 Mark Reynolds - 1.4.2.2-3 -- Bump version to 1.4.2.2-3 -- Address perl provides and requires filter - -* Wed Sep 25 2019 Mark Reynolds - 1.4.2.2-2 -- Bump version to 1.4.2.2-2 -- Remove perl filter change as it broke legacy tools - -* Wed Sep 25 2019 Mark Reynolds - 1.4.2.2-1 -- Bump version to 1.4.2.2 -- Issue 50627 - Add ASAN logs to HTML report -- Issue 50545 - Port repl-monitor.pl to lib389 CLI -- Issue 50622 - ds_selinux_enabled may crash on suse -- Issue 50595 - remove syslog.target requirement -- Issue 50617 - disable cargo lock -- Issue 50620 - Fix regressions from 50506 (slapi_enry_attr_get_ref) -- Issue 50615 - Log current test name to journald -- Issue 50610 - memory leak in dbscan - -* Wed Sep 25 2019 Mark Reynolds - 1.4.2.1-1 -- Bump version to 1.4.2.1 -- Issue 50581 - ns-slapd crashes during ldapi search -- Issue 50604 - Fix UI validation -- Issue 50510 - etime can contain invalid nanosecond value -- Issue 50593 - Investigate URP handling on standalone instance -- Issue 50506 - Fix regression for relication stripattrs -- Issue 50580 - Perl can't be disabled in configure -- Issue 50584, 49212 - docker healthcheck and configuration -- Issue 50546 - fix more UI issues(part 2) -- Do not use comparision with "is" for empty value -- Issue 50546 - fix more UI issues -- Issue 50586 - lib389 - Fix DSEldif long line processing -- Issue 50173 - Add the validate-syntax task to the dsconf schema -- Issue 50546 - Fix various issues in UI -- Bump version to 1.4.2.0 -- Issue 50576 - Same proc uid/gid maps to rootdn for ldapi sasl -- Issue 50567, 50568 - strict host check disable and display container version -- Issue 50550 - DS installer debug messages leaking to ipa-server-install -- Issue 50545 - Port fixup-memberuid and add the functionality to CLI and UI -- Issue 50572 - After running cl-dump dbdir/cldb/*ldif.done are not deleted -- Issue 50578 - Add SKIP_AUDIT_CI flag for Cockpit builds -- Issue 50349 - filter schema validation -- Issue 48055 - CI test-(Plugin configuration should throw proper error messages if not configured properly) -- Issue 49324 - idl_new fix assert -- Issue 50564 - Fix rust libraries by default and improve docker -- Issue 50206 - Refactor lock, unlock and status of dsidm account/role -- Issue 49324 - idl_new report index name in error conditions -- Issue 49761 - Fix CI test suite issues -- Issue 50506 - Fix regression from slapi_entry_attr_get_ref refactor -- Issue 50499 - Audit fix - Update npm 'eslint-utils' version -- Issue 49624 - modrdn silently fails if DB deadlock occurs -- Issue 50542 - Fix crashes in filter tests -- Issue 49761 - Fix CI test suite issues -- Issue 50542 - Entry cache contention during base search -- Issue 50462 - Fix CI tests -- Issue 50490 - objects and memory leaks -- Issue 50538 - Move CI test to individual file -- Issue 50538 - cleanAllRUV task limit is not enforced for replicated tasks -- Issue 50536 - Audit log heading written to log after every update -- Issue 50525 - nsslapd-defaultnamingcontext does not change when the assigned suffix gets deleted -- Issue 50534 - CLI change schema edit subcommand to replace -- Issue 50506 - cont Fix invalid frees from pointer reference calls -- Issue 50507 - Fix Cockpit UI styling for PF4 -- Issue 48851 - investigate and port TET matching rules filter tests(indexing final) -- Issue 48851 - Add more test cases to the match test suite(mode replace) -- Issue 50530 - Directory Server not RFC 4511 compliant with requested attr "1.1" -- Issue 50529 - LDAP server returning PWP controls in different sequence -- Issue 50506 - Fix invalid frees from pointer reference calls. -- Issue 50506 - Replace slapi_entry_attr_get_charptr() with slapi_entry_attr_get_ref() -- Issue 50521 - Add regressions in CI tests -- Issue 50510 - etime can contain invalid nanosecond value -- Issue 50488 - Create a monitor for disk space usagedisk-space-mon -- Issue 50511 - lib389 PosixGroups type can not handle rdn properly -- Issue 50508 - UI - fix local password policy form - -* Wed Jul 24 2019 Fedora Release Engineering - 1.4.1.6-1.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild - -* Fri Jul 19 2019 Mark Reynolds - 1.4.1.6-1 -- Bump version to 1.4.1.6 -- Issue 50355 - SSL version min and max not correctly applied -- Issue 50497 - Port cl-dump.pl tool to Python using lib389 -- Issue 48851 - investigate and port TET matching rules filter tests(Final) -- Issue 50417 - fix regression from previous commit -- Issue 50425 - Add jemalloc LD_PRELOAD to systemd drop-in file -- Issue 50325 - Add Security tab to UI -- Issue 49789 - By default, do not manage unhashed password -- Issue 49421 - Implement password hash upgrade on bind. -- Issue 49421 - on bind password upgrade proof of concept -- Issue 50493 - connection_is_free to trylock -- Issue 50459 - Correct issue with allocation state -- Issue 50499 - Fix audit issues and remove jquery from the whitelist -- Issue 50459 - c_mutex to use pthread_mutex to allow ns sharing -- Issue 50484 - Add a release build dockerfile and dscontainer improvements -- Issue 50486 - Update jemalloc to 5.2.0 - -* Mon Jul 8 2019 Mark Reynolds - 1.4.1.5-1 -- Bump version to 1.4.1.5 -- Issue 50431 - Fix regression from coverity fix (crash in memberOf plugin) -- Issue 49239 - Add a new CI test case -- Issue 49997 - Add a new CI test case -- Issue 50177 - Add a new CI test case, also added fixes in lib389 -- Issue 49761 - Fix CI test suite issues -- Issue 50474 - Unify result codes for add and modify of repl5 config -- Issue 50472 - memory leak with encryption -- Issue 50462 - Fix Root DN access control plugin CI tests -- Issue 50462 - Fix CI tests -- Issue 50217 - Implement dsconf security section -- Issue 48851 - Add more test cases to the match test suite. -- Issue 50378 - ACI's with IPv4 and IPv6 bind rules do not work for IPv6 clients -- Issue 50439 - fix waitpid issue when pid does not exist -- Issue 50454 - Fix Cockpit UI branding -- Issue 48851 - investigate and port TET matching rules filter tests(index) -- Issue 49232 - Truncate the message when buffer capacity is exceeded - -* Tue Jun 18 2019 Mark Reynolds - 1.4.1.4-1 -- Bump version to 1.4.1.4 -- Issue 49361 - Use IPv6 friendly network functions -- Issue 48851 - Investigate and port TET matching rules filter tests(bug772777) -- Issue 50446 - NameError: name 'ds_is_older' is not defined -- Issue 49602 - Revise replication status messages -- Issue 50439 - Update docker integration to work out of source directory -- Issue 50037 - revert path changes as it breaks prefix/rpm builds -- Issue 50431 - Fix regression from coverity fix -- Issue 50370 - CleanAllRUV task crashing during server shutdown -- Issue 48851 - investigate and port TET matching rules filter tests(match) -- Issue 50417 - Fix missing quote in some legacy tools -- Issue 50431 - Fix covscan warnings -- Revert "Issue 49960 - Core schema contains strings instead of numer oids" -- Issue 50426 - nsSSL3Ciphers is limited to 1024 characters -- Issue 50052 - Fix rpm.mk according to audit-ci change -- Issue 50365 - PIDFile= references path below legacy directory /var/run/ -- Issue 50428 - Log the actual base DN when the search fails with "invalid attribute request" -- Issue 50329 - (2nd) Possible Security Issue: DOS due to ioblocktimeout not applying to TLS -- Issue 50417 - Revise legacy tool scripts to work with new systemd changes -- Issue 48851 - Add more search filters to vfilter_simple test suite -- Issue 49761 - Fix CI test suite issues -- Issue 49875 - Move SystemD service config to a drop-in file -- Issue 50413 - ds-replcheck - Always display the Result Summary -- Issue 50052 - Add package-lock.json and use "npm ci" -- Issue 48851 - investigate and port TET matching rules filter tests(vfilter simple) -- Issue 50355 - NSS can change the requested SSL min and max versions -- Issue 48851 - investigate and port TET matching rules filter tests(vfilter_ld) -- Issue 50390 - Add Managed Entries Plug-in Config Entry schema -- Issue 49730 - Remove unused Mozilla ldapsdk variables - -* Fri May 31 2019 Jitka Plesnikova - 1.4.1.3-1.1 -- Perl 5.30 rebuild - -* Fri May 24 2019 Mark Reynolds - 1.4.1.3-1 -- Bump version to 1.4.1.3 -- Issue 49761 - Fix CI test suite issues -- Issue 50041 - Add the rest UI Plugin tabs - Part 2 -- Issue 50340 - 2nd try - structs for diabled plugins will not be freed -- Issue 50403 - Instance creation fails on 1.3.9 using perl utils and latest lib389 -- Issue 50389 - ns-slapd craches while two threads are polling the same connection -- Issue 48851 - investigate and port TET matching rules filter tests(scanlimit) -- Issue 50037 - lib389 fails to install in venv under non-root user -- Issue 50112 - Port ACI test suit from TET to python3(userattr) -- Issue 50393 - maxlogsperdir accepting negative values -- Issue 50112 - Port ACI test suit from TET to python3(roledn) -- Issue 49960 - Core schema contains strings instead of numer oids -- Issue 50396 - Crash in PAM plugin when user does not exist -- Issue 50387 - enable_tls() should label ports with ldap_port_t -- Issue 50390 - Add Managed Entries Plug-in Config Entry schema -- Issue 50306 - Fix regression with maxbersize -- Issue 50384 - Missing dependency: cracklib-dicts -- Issue 49029 - [RFE] improve internal operations logging -- Issue 49761 - Fix CI test suite issues -- Issue 50374 - dsdim posixgroup create fails with ERROR -- Issue 50251 - clear text passwords visable in CLI verbose mode logging -- Issue 50378 - ACI's with IPv4 and IPv6 bind rules do not work for IPv6 clients -- Issue 48851 - investigate and port TET matching rules filter tests -- Issue 50220 - attr_encryption test suite failing -- Issue 50370 - CleanAllRUV task crashing during server shutdown -- Issue 50340 - structs for disabled plugins will not be freed -- Issue 50164 - Add test for dscreate to basic test suite -- Issue 50363 - ds-replcheck incorrectly reports error out of order multi-valued attributes -- Issue 49730 - MozLDAP bindings have been unsupported for a while -- Issue 50353 - Categorize tests by tiers -- Issue 50303 - Add creation date to task data -- Issue 50358 - Create a Bitwise Plugin class in plugins.py -- Remove the nss3 path prefix from the cert.h C preprocessor source file inclusion -- Issue 50329 - revert fix -- Issue 50112 - Port ACI test suit from TET to python3(keyaci) -- Issue 50344 - tidy rpm vs build systemd flag handling -- Issue 50067 - Fix krb5 dependency in a specfile -- Issue 50340 - structs for diabled plugins will not be freed -- Issue 50327 - Add replication conflict support to UI -- Issue 50327 - Add replication conflict entry support to lib389/CLI -- Issue 50329 - improve connection default parameters -- Issue 50313 - Add a NestedRole type to lib389 -- Issue 50112 - Port ACI test suit from TET to python3(Delete and Add) -- Issue 49390, 50019 - support cn=config compare operations -- Issue 50041 - Add the rest UI Plugin tabs - Part 1 -- Issue 50329 - Possible Security Issue: DOS due to ioblocktimeout not applying to TLS -- Issue 49990 - Increase the default FD limits -- Issue 50306 - (cont typo) Move connection config inside struct -- Issue 50291 - Add monitor tab functionality to Cockpit UI -- Issue 50317 - fix ds-backtrace issue on latest gdb -- Issue 50305 - Revise CleanAllRUV task restart process -- Issue 49915 - Fix typo -- Issue 50026 - Audit log does not capture the operation where nsslapd-lookthroughlimit is modified -- Issue 49899 - fix pin.txt and pwdfile permissions -- Issue 49915 - Add regression test -- Issue 50303 - Add task creation date to task data -- Issue 50306 - Move connection config inside struct -- Issue 50240 - Improve task logging -- Issue 50032 - Fix deprecation warnings in tests -- Issue 50310 - fix sasl header include -- Issue 49390 - improve compare and cn=config compare tests - -* Wed Apr 03 2019 Adam Williamson - 1.4.1.2-3 -- Rebuild without changes to be newer than 1.4.1.2-1 (see #1694990) - -* Fri Mar 29 2019 Mark Reynolds - 1.4.1.2-2 -- Bump version to 1.4.1.2-2 -- Fix lib389 python requirement - -* Fri Mar 29 2019 Mark Reynolds - 1.4.1.2-1 -- Bump version to 1.4.1.2-1 -- Ticket 50308 - Revise memory leak fix -- Ticket 50308 - Fix memory leaks for repeat binds and replication -- Ticket 40067 - Use PKG_CHECK_MODULES to detect libraries -- Ticket 49873 - (cont 3rd) cleanup debug log -- Ticket 49873 - (cont 2nd) Contention on virtual attribute lookup -- Ticket 50292 - Fix Plugin CLI and UI issues -- Ticket 50112 - Port ACI test suit from TET to python3(misc and syntax) -- Ticket 50289 - Fix various database UI issues -- Ticket 49463 - After cleanALLruv, replication is looping on keep alive DEL -- Ticket 50300 - Fix memory leak in automember plugin -- Ticket 50265 - the warning about skew time could last forever -- Ticket 50260 - Invalid cache flushing improvements -- Ticket 49561 - MEP plugin, upon direct op failure, will delete twice the same managed entry -- Ticket 50077 - Do not automatically turn automember postop modifies on -- Ticket 50282 - OPERATIONS ERROR when trying to delete a group with automember members -- Ticket 49715 - extend account functionality -- Ticket 49873 - (cont) Contention on virtual attribute lookup -- Ticket 50260 - backend txn plugins can corrupt entry cache -- Ticket 50255 - Port password policy test to use DSLdapObject -- Ticket 49667 - 49668 - remove old spec files -- Ticket 50276 - 389-ds-console is not built on RHEL8 if cockpit_dist is already present -- Ticket 50112 - Port ACI test suit from TET to python3(Search) -- Ticket 50259 - implement dn construction test -- Ticket 50273 - reduce default replicaton agmt timeout -- Ticket 50208 - lib389- Fix issue with list all instances -- Ticket 50112 - Port ACI test suit from TET to python3(Global Group) -- Ticket 50041 - Add CLI functionality for special plugins -- Ticket 50263 - LDAPS port not listening after installation -- Ticket 49575 - Indicate autosize value errors and corrective actions -- Ticket 50137 - create should not check in non-stateful mode for exist -- Ticket 49655 - remove doap file -- Ticket 50197 - Fix dscreate regression -- Ticket 50234 - one level search returns not matching entry -- Ticket 50257 - lib389 - password policy user vs subtree checks are broken -- Ticket 50253 - Making an nsManagedRoleDefinition type in src/lib389/lib389/idm/nsrole.py -- Ticket 49029 - [RFE] improve internal operations logging -- Ticket 50230 - improve ioerror msg when not root/dirsrv -- Ticket 50246 - Fix the regression in old control tools -- Ticket 50197 - Container integration part 2 -- Ticket 50197 - Container init tools -- Ticket 50232 - export creates not importable ldif file -- Ticket 50215 - UI - implement Database Tab in reachJS -- Ticket 50243 - refint modrdn stress test -- Ticket 50238 - Failed modrdn can corrupt entry cache -- Ticket 50236 - memberOf should be more robust -- Ticket 50213 - fix list instance issue -- Ticket 50219 - Add generic filter to DSLdapObjects -- Ticket 50227 - Making an cosClassicDefinition type in src/lib389/lib389/cos.py -- Ticket 50112 - Port ACI test suit from TET to python3(modify) -- Ticket 50224 - warnings on deprecated API usage -- Ticket 50112 - Port ACI test suit from TET to python3(valueaci) -- Ticket 50112 - Port ACI test suit from TET to python3(Aci Atter) -- Ticket 50208 - make instances mark off based on dse.ldif not sysconfig -- Ticket 50170 - composable object types for nsRole in lib389 -- Ticket 50199 - disable perl by default -- Ticket 50211 - Making an actual Anonymous type in lib389/idm/account.py -- Ticket 50155 - password history check has no way to just check the current password -- Ticket 49873 - Contention on virtual attribute lookup -- Ticket 50197 - Container integration improvements -- Ticket 50195 - improve selinux error messages in interactive -- Ticket 49658 - In replicated topology a single-valued attribute can diverge -- Ticket 50111 - Use pkg-config to detect icu -- Ticket 50165 - Fix issues with dscreate -- Ticket 50177 - import task should not be deleted too rapidely after import finishes to be able to query the status -- Ticket 50140 - Use high ports in container installs -- Ticket 50184 - Add cli tool parity to dsconf/dsctl -- Ticket 50159 - sssd and config display - -* Thu Jan 31 2019 Fedora Release Engineering - 1.4.1.1-1.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild - -* Wed Jan 30 2019 Mark Reynolds - 1.4.1.1-1 -- Bump version to 1.4.1.1 -- Ticket 50151 - lib389 support cli add/replace/delete on objects -- Ticket 50041 - CLI and WebUI - Add memberOf plugin functionality - -* Wed Jan 23 2019 Pete Walter - 1.4.0.20-1.2 -- Rebuild for ICU 63 - -* Mon Jan 14 2019 Björn Esser - 1.4.0.20-1.1 -- Rebuilt for libcrypt.so.2 (#1666033) - -* Fri Dec 14 2018 Mark Reynolds - 1.4.0.20-1 -- Bump version to 1.4.0.20 -- Ticket 49994 - Add test for backend/suffix CLI functions -- Ticket 50090 - refactor fetch_attr() to slapi_fetch_attr() -- Ticket 50091 - shadowWarning is not generated if passwordWarning is lower than 86400 seconds (1 day) -- Ticket 50056 - Fix CLI/UI bugs -- Ticket 49864 - Revised replication status messages for transient errors -- Ticket 50071 - Set ports in local_simple_allocate function -- Ticket 50065 - lib389 aci parsing is too strict -- Ticket 50061 - Improve schema loading in UI -- Ticket 50063 - Crash after attempting to restore a single backend -- Ticket 50062 - Replace error by warning in the state machine defined in repl5_inc_run -- Ticket 50041 - Set the React dataflow foundation and add basic plugin UI -- Ticket 50028 - Revise ds-replcheck usage -- TIcket 50057 - Pass argument into hashtable_new -- Ticket 50053 - improve testcase -- Ticket 50053 - Subtree password policy overrides a user-defined password policy -- Ticket 49974 - lib389 - List instances with initconfig_dir instead of sysconf_dir -- Ticket 49984 - Add an empty domain creation to the dscreate -- Ticket 49950 - PassSync not setting pwdLastSet attribute in Active Directory after Pw update from LDAP sync for normal user -- Ticket 50046 - Remove irrelevant debug-log messages from CLI tools -- Ticket 50022, 50012, 49956, and 49800: Various dsctl/dscreate fixes -- Ticket 49927 - dsctl db2index does not work -- Ticket 49814 - dscreate should handle selinux ports that are in a range -- Ticket 49543 - fix certmap dn comparison -- Ticket 49994 - comment out dev paths -- Ticket 49994 - Add backend features to CLI -- Ticket 48081 - Add new CI tests for password - -* Thu Nov 1 2018 Mark Reynolds - 1.4.0.19-1 -- Bump version to 1.4.0.19 -- Ticket 50026 - audit logs does not capture the operation where nsslapd-lookthroughlimit is modified -- Ticket 50020 - during MODRDN referential integrity can fail erronously while updating large groups -- Ticket 49999 - Finish up the transfer to React -- Ticket 50004 - lib389 - improve X-ORIGIN schema parsing -- Ticket 50013 - Log warn instead of ERR when aci target does not exist. -- Ticket 49975 - followup for broken prefix deployment -- Ticket 49999 - Add dist-bz2 target for Koji build system -- Ticket 49814 - Add specfile requirements for python3-libselinux -- Ticket 49814 - Add specfile requirements for python3-selinux -- Ticket 49999 - Integrate React structure into cockpit-389-ds -- Ticket 49995 - Fix Tickets with internal op logging -- Ticket 49997 - RFE: ds-replcheck could validate suffix exists and it's replicated -- Ticket 49985 - memberof may silently fails to update a member -- Ticket 49967 - entry cache corruption after failed MODRDN -- Ticket 49975 - Add missing include file to main.c -- Ticket 49814 - skip standard ports for selinux labelling -- Ticket 49814 - dscreate should set the port selinux labels -- Ticket 49856 - Remove backend option from bak2db -- Ticket 49926 - Fix various Tickets with replication UI -- Ticket 49975 - SUSE rpmlint Tickets -- Ticket 49939 - Fix ldapi path in lib389 -- Ticket 49978 - Add CLI logging function for UI -- Ticket 49929 - Modifications required for the Test Case Management System -- Ticket 49979 - Fix regression in last commit -- Ticket 49979 - Remove dirsrv tests subpackage -- Ticket 49928 - Fix various small WebUI schema Tickets -- Ticket 49926 - UI - comment out dev cli patchs -- Ticket 49926 - Add replication functionality to UI - -* Wed Oct 10 2018 Mark Reynolds - 1.4.0.18-1 -- Bump version to 1.4.0.18 -- Ticket 49968 - Confusing CRITICAL message: list_candidates - NULL idl was recieved from filter_candidates_ext -- Ticket 49946 - upgrade of 389-ds-base could remove replication agreements. -- Ticket 49969 - DOS caused by malformed search operation (part 2) - -* Tue Oct 9 2018 Mark Reynolds - 1.4.0.17-2 -- Bump version to 1.4.0.17-2 -- Ticket 49969 - DOS caused by malformed search operation (security fix) -- Ticket 49943 - rfc3673_all_oper_attrs_test is not strict enough -- Ticket 49915 - Master ns-slapd had 100% CPU usage after starting replication and replication cannot finish -- Ticket 49963 - ASAN build fails on F28 -- Ticket 49947 - Coverity Fixes -- Ticket 49958 - extended search fail to match entries -- Ticket 49928 - WebUI schema functionality and improve CLI part -- Ticket 49954 - On s390x arch retrieved DB page size is stored as size_t rather than uint32_t -- Ticket 49928 - Refactor and improve schema CLI/lib389 part to DSLdapObject -- Ticket 49926 - Fix replication tests on 1.3.x -- Ticket 49926 - Add replication functionality to dsconf -- Ticket 49887 - Clean up thread local usage -- Ticket 49937 - Log buffer exceeded emergency logging msg is not thread-safe (security fix) -- Ticket 49866 - fix typo in cos template in pwpolicy subtree create -- Ticket 49930 - Correction of the existing fixture function names to remove test_ prefix -- Ticket 49932 - Crash in delete_passwdPolicy when persistent search connections are terminated unexpectedly -- Ticket 48053 - Add attribute encryption test cases -- Ticket 49866 - Refactor PwPolicy lib389/CLI module -- Ticket 49877 - Add log level functionality to UI - -* Fri Aug 24 2018 Mark Reynolds - 1.4.0.16-1 -- Bump version to 1.4.0.16 -- Revert "Ticket 49372 - filter optimisation improvements for common queries" -- Revert "Ticket 49432 - filter optimise crash" -- Ticket 49887: Fix SASL map creation when --disable-perl -- Ticket 49858 - Add backup/restore and import/export functionality to WebUI/CLI - -* Thu Aug 16 2018 Mark Reynolds - 1.4.0.15-1 -- Bump version to 1.4.0.15 -- Ticket 49029 - Internal logging thread data needs to allocate int pointers -- Ticket 48061 : CI test - config -- Ticket 48377 - Only ship libjemalloc.so.2 -- Ticket 49885 - On some platform fips does not exist - -* Mon Aug 13 2018 Mark Reynolds - 1.4.0.14-2 -- Bump version to 1.4.0.14-2 -- Fix legacy tool scriplet error -- Remove ldconfig calls -- Only provide libjemalloc.so.2 - -* Fri Aug 10 2018 Mark Reynolds - 1.4.0.14-1 -- Bump version to 1.4.0.14 -- Ticket 49891 - Use "__python3" macro for python scripts -- Ticket 49890 - ldapsearch with server side sort crashes the ldap server -- Ticket 49029 - RFE -improve internal operations logging -- Ticket 49893 - disable nunc-stans by default -- Ticket 48377 - Update file name for LD_PRELOAD -- Ticket 49884 - Improve nunc-stans test to detect socket errors sooner -- Ticket 49888 - Use perl filter in rpm specfile -- Ticket 49866 - Add password policy features to CLI/UI -- Ticket 49881 - Missing check for crack.h -- Ticket 48056 - Add more test cases to the basic suite -- Ticket 49761 - Fix replication test suite issues -- Ticket 49381 - Refactor the plugin test suite docstrings -- Ticket 49837 - Add new password policy attributes to UI -- Ticket 49794 - RFE - Add pam_pwquality features to password syntax checking -- Ticket 49867 - Fix CLI tools' double output - -* Thu Jul 19 2018 Mark Reynolds - 1.4.0.13-1 -- Bump version to 1.4.0.13 -- Ticket 49854 - ns-slapd should create run_dir and lock_dir directories at startup -- Ticket 49806 - Add SASL functionality to CLI/UI -- Ticket 49789 - backout original security fix as it caused a regression in FreeIPA -- Ticket 49857 - RPM scriptlet for 389-ds-base-legacy-tools throws an error - -* Tue Jul 17 2018 Mark Reynolds - 1.4.0.12-1 -- Bump version to 1.4.0.12-1 -- Ticket 48377 - Move jemalloc license to /usr/share/licences -- Ticket 49813 - Revised interactive installer -- Ticket 49789 - By default, do not manage unhashed password -- Ticket 49844 - lib389: don't set up logging at module scope -- Ticket 49546 - Fix issues with MIB file -- Ticket 49840 - ds-replcheck command returns traceback errors against ldif files having garbage content when run in offline mode -- Ticket 49640 - Cleanup plugin bootstrap logging -- Ticket 49835 - lib389: fix logging -- Ticket 48818 - For a replica bindDNGroup, should be fetched the first time it is used not when the replica is started -- Ticket 49780 - acl_copyEval_context double free -- Ticket 49830 - Import fails if backend name is "default" -- Ticket 49832 - remove tcmalloc references -- Ticket 49813 - dscreate - add interactive installer -- Ticket 49808 - Add option to add backend to dscreate -- Ticket 49811 - lib389 setup.py should install autogenerated man pages -- Ticket 49795 - UI - add "action" backend funtionality -- Ticket 49588 - Add py3 support for tickets : part-3 -- Ticket 49820 - lib389 requires wrong python ldap library -- Ticket 49791 - Update docker file for new dscreate options -- Ticket 49761 - Fix more CI test issues -- Ticket 49811 - Update man pages -- Ticket 49783 - UI - add server configuration backend -- Ticket 49717 - Add conftest.py for tests -- Ticket 49588 - Add py3 support for tickets -- Ticket 49793 - Updated descriptions in dscreate example INF file -- Ticket 49471 - Rename dscreate options -- Ticket 49751 - passwordMustChange attribute is not honored by a RO consumer if using "Chain on Update" -- Ticket 49734 - Fix various issues with Disk Monitoring -- Update Source0 URL in rpm/389-ds-base.spec.in - - -* Thu Jul 12 2018 Fedora Release Engineering - 1.4.0.11-2.5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild - -* Tue Jul 10 2018 Pete Walter - 1.4.0.11-2.4 -- Rebuild for ICU 62 - -* Tue Jul 03 2018 Petr Pisar - 1.4.0.11-2.3 -- Perl 5.28 rebuild - -* Mon Jul 02 2018 Miro Hrončok - 1.4.0.11-2.2 -- Rebuilt for Python 3.7 - -* Fri Jun 29 2018 Jitka Plesnikova - 1.4.0.11-2.1 -- Perl 5.28 rebuild - -* Thu Jun 21 2018 Mark Reynolds - 1.4.0.11-2 -- Bump version to 1.4.0.11-2 -- Add python3-lib389 requirement - -* Tue Jun 19 2018 Mark Reynolds - 1.4.0.11-1 -- Bump version to 1.4.0.11 -- Test for issue #49788 -- Fixing 4-byte UTF-8 character validation -- Ticket 49777 - add config subcommand to dsconf -- Ticket 49712 - lib389 CLI tools should return a result code on failures -- Issue 49588 - Add py3 support for tickets : part-2 -- Remove old RHEL/fedora version checking from upstream specfile -- Ticket 48204 - remove python2 from scripts -- Ticket 49576 - ds-replcheck: fix certificate directory verification -- Bug 1591761 - 389-ds-base: Remove jemalloc exports - -* Tue Jun 19 2018 Miro Hrončok - 1.4.0.10-2.1 -- Rebuilt for Python 3.7 - -* Fri Jun 8 2018 Mark Reynolds - 1.4.0.10-2 -- Bump verision to 1.4.0.10-2 -- Remove reference ro stop-dirsrv from legacy tools - -* Fri Jun 8 2018 Mark Reynolds - 1.4.0.10-1 -- Bump verision to 1.4.0.10-1 -- Ticket 49640 - Errors about PBKDF2 password storage plugin at server startup -- Ticket 49571 - perl subpackage and python installer by default -- Ticket 49740 - UI - Replication monitor color coding is not colorblind friendly -- Ticket 49741 - UI - View/Edit replication agreement hangs WebUI -- Ticket 49703 - UI - Set default values in create instance form -- Ticket 49742 - Fine grained password policy can impact search performance -- Ticket 49768 - Under network intensive load persistent search can erronously decrease connection refcnt -- Ticket 49765 - compiler warning -- Ticket 49689 - Cockpit subpackage does not build in PREFIX installations -- Ticket 49765 - Async operations can hang when the server is running nunc-stans -- Ticket 49745 - UI add filter options for error log severity levels -- Ticket 49761 - Fix test suite issues -- Ticket 49754 - instances created with dscreate can not be upgraded with setup-ds.pl -- Ticket 47902 - UI - add continuous refresh log feature -- Ticket 49381 - Add docstrings to plugin test suites - Part 1 -- Ticket 49646 - Improve TLS cert processing in lib389 CLI -- Ticket 49748 - Passthru plugin startTLS option not working -- Ticket 49732 - Optimize resource limit checking for rootdn issued searches -- Ticket 48377 - Bundle jemalloc -- Ticket 49736 - Hardening of active connection list -- Ticket 48184 - clean up and delete connections at shutdown (3rd) -- Ticket 49675 - Revise coverity fix -- Ticket 49333 - Do not remove versioned man pages -- Ticket 49683 - Add support for JSON option in lib389 CLI tools -- Ticket 49704 - Error log from the installer is concatenating all lines into one -- Ticket 49726 - DS only accepts RSA and Fortezza cipher families -- Ticket 49722 - Errors log full of " WARN - keys2idl - recieved NULL idl from index_read_ext_allids, treating as empty set" messages -- Ticket 49582 - Add py3 support to memberof_plugin test suite -- Ticket 49675 - Fix coverity issues -- Ticket 49576 - Add support of ";deletedattribute" in ds-replcheck -- Ticket 49706 - Finish UI patternfly convertions -- Ticket 49684 - AC_PROG_CC clobbers CFLAGS set by --enable-debug -- Ticket 49678 - organiSational vs organiZational spelling in lib389 -- Ticket 49689 - Fix local "make install" after adding cockpit subpackage -- Ticket 49689 - Move Cockpit UI plugin to a subpackage -- Ticket 49679 - Missing nunc-stans documentation and doxygen warnings -- Ticket 49588 - Add py3 support for tickets : part-1 -- Ticket 49576 - Update ds-replcheck for new conflict entries -- Ticket 48184 - clean up and delete connections at shutdown (2nd try) -- Ticket 49698 - Remove unneeded patternfly files from Cockpit package -- Ticket 49581 - Fix dynamic plugins test suite -- Ticket 49665 - remove obsoleted upgrade scripts -- Ticket 49693 - A DB_DEADLOCK while adding a tombstone (RUV) leads to access of an already freed entry -- Ticket 49696 - replicated operations should be serialized -- Ticket 49669 - Invalid cachemem size can crash the server during a restore -- Ticket 49684 - AC_PROG_CC clobbers CFLAGS set by --enable-debug -- Ticket 49685 - make clean fails if cargo is not installed -- Ticket 49106 - Move ds_* scripts to libexec -- Ticket 49657 - Fix cascading replication scenario in lib389 API -- Ticket 49671 - Readonly replicas should not write internal ops to changelog -- Ticket 49673 - nsslapd-cachememsize can't be set to a value bigger than MAX_INT -- Ticket 49519 - Convert Cockpit UI to use strictly patternfly stylesheets -- Ticket 49665 - Upgrade script doesn't enable CRYPT password storage plug-in -- Ticket 49665 - Upgrade script doesn't enable PBKDF2 password storage plug-in - -* Tue May 15 2018 Mark Reynolds - 1.4.0.9-2 -- Bump version to 1.4.0.9-2 -- Add openssl-perl requirement for new python installer - -* Tue May 8 2018 Mark Reynolds - 1.4.0.9-1 -- Bump version to 1.4.0.9 -- Ticket 49661 - CVE-2018-1089 - Crash from long search filter -- Ticket 49652 - DENY aci's are not handled properly -- Ticket 49650 - lib389 enable_tls doesn't work on F28 -- Ticket 49538 - replace cacertdir_rehash with openssl rehash -- Ticket 49406 - Port backend_test.py test to DSLdapObject implementation -- Ticket 49649 - Use reentrant crypt_r() -- Ticket 49642 - lib389 should generate a more complex password -- Ticket 49612 - lib389 remove_ds_instance() does not remove systemd units -- Ticket 49644 - crash in debug build - -* Mon Apr 30 2018 Pete Walter - 1.4.0.8-1.1 -- Rebuild for ICU 61.1 - -* Thu Apr 19 2018 Mark Reynolds - 1.4.0.8-1 -- Bump version to 1.4.0.8-1 -- Ticket 49639 - Crash when failing to read from SASL conn -- Ticket 49109 - nsDS5ReplicaTransportInfo should accept StartTLS as an option -- Ticket 49586 - Add py3 support to plugins test suite -- Ticket 49511 - memory leak in pwdhash - -* Mon Apr 16 2018 Mark Reynolds - 1.4.0.7-2 -- Bump version to 1.4.0.7-2 -- Fix the devel srvcore requirements - -* Fri Apr 13 2018 Mark Reynolds - 1.4.0.7-1 -- Bump version to 1.4.0.7 -- Ticket 49477 - Missing pbkdf python -- Ticket 49552 - Fix the last of the build issues on F28/29 -- Ticket 49522 - Fix build issues on F28 -- Ticket 49631 - same csn generated twice -- Ticket 49585 - Add py3 support to password test suite : part-3 -- Ticket 49585 - Add py3 support to password test suite : part-2 -- Ticket 48184 - revert previous patch around unuc-stans shutdown crash -- Ticket 49585 - Add py3 support to password test suite -- Ticket 46918 - Fix compiler warnings on arm -- Ticket 49601 - Replace HAVE_SYSTEMD define with WITH_SYSTEMD in svrcore -- Ticket 49619 - adjustment of csn_generator can fail so next generated csn can be equal to the most recent one received -- Ticket 49608 - Add support for gcc/clang sanitizers -- Ticket 49606 - Improve lib389 documentation -- Ticket 49552 - Fix build issues on F28 -- Ticket 49603 - 389-ds-base package rebuilt on EPEL can't be installed due to missing dependencies -- Ticket 49593 - NDN cache stats should be under the global stats -- Ticket 49599 - Revise replication total init status messages -- Ticket 49596 - repl-monitor.pl fails to find db tombstone/RUV entry -- Ticket 49589 - merge svrcore into 389-ds-base -- Ticket 49560 - Add a test case for extract-pemfiles -- Ticket 49239 - Add a test suite for ds-replcheck tool RFE -- Ticket 49369 - merge svrcore into 389-ds-base - -* Thu Mar 29 2018 Till Maas - 1.4.0.6-3 -- Remove BR on tcp_wrappers (https://bugzilla.redhat.com/show_bug.cgi?id=1518749) - -* Tue Mar 6 2018 Mark Reynolds - 1.4.0.6-1 -- Bump version to 1.4.0.6 -- Ticket 49545 - final substring extended filter search returns invalid result -- Ticket 49572 - ns_job_wait race on condvar -- Ticket 49584 - Fix Tickets with paged_results test suite -- Ticket 49161 - memberof fails if group is moved into scope -- Ticket 49447 - PBKDF2 on upgrade -- ticket 49551 - correctly handle subordinates and tombstone numsubordinates -- Ticket 49043 - Add replica conflict test suite -- Ticket 49296 - Fix race condition in connection code with anonymous limits -- Ticket 49568 - Fix integer overflow on 32bit platforms -- Ticket 48085 - Add encryption cl5 test suite -- Ticket 49566 - ds-replcheck needs to work with hidden conflict entries -- Ticket 49519 - Add more Cockpit UI content -- Ticket 49551 - fix memory leak found by coverity -- Ticket 49551 - v3 - correct handling of numsubordinates for cenotaphs and tombstone delete -- Ticket 49278 - Add a new CI test case -- Ticket 49560 - nsslapd-extract-pemfiles should be enabled by default as openldap is moving to openssl -- Ticket 49557 - Add config option for checking CRL on outbound SSL Connections -- Ticket 49446 - Add CI test case -- Ticket 35 - Description: Add support for managing automember to dsconf -- Ticket 49544 - cli release preperation -- Ticket 48006 - Add a new CI test case - -* Mon Feb 19 2018 Mark Reynolds - 1.4.0.5-1.7 -- Add cyrus-sasl-plain requirement - -* Thu Feb 15 2018 Mark Reynolds - 1.4.0.5-1.6 -- Fix python requirements for policycoreutils-python-utils - -* Thu Feb 15 2018 Mark Reynolds - 1.4.0.5-1.5 -- Fix package requirements to use Python 3 packages for LDAP and SELinux - -* Thu Feb 15 2018 Mark Reynolds - 1.4.0.5-1.4 -- Only exclude Ix86 arches - -* Thu Feb 15 2018 Adam Williamson - 1.4.0.5-1.3 -- Rebuild for libevent soname bump - -* Fri Feb 09 2018 Igor Gnatenko - 1.4.0.5-1.2 -- Escape macros in %%changelog - -* Wed Feb 07 2018 Fedora Release Engineering - 1.4.0.5-1.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild - -* Wed Jan 31 2018 Mark Reynolds - 1.4.0.5-1 -- Bump version to 1.4.0.5 -- CVE-2017-15134 389-ds-base: Remote DoS via search filters in slapi_filter_sprintf -- Ticket 49546 - Fix broken snmp MIB file -- Ticket 49554 - update readme -- Ticket 49554 - Update Makefile for README.md -- Ticket 49400 - Make CLANG configurable -- Ticket 49530 - Add pseudolocalization option for dbgen -- Ticket 49523 - Fixed skipif marker, topology fixture and log message -- Ticket 49544 - Double check pw prompts -- Ticket 49548 - Cockpit UI - installer should also setup Cockpit - -* Fri Jan 26 2018 Mark Reynolds - 1.4.0.4-1 -- Bump version to 1.4.0.4 -- Ticket 49540 - Indexing task is reported finished too early regarding the backend status -- Ticket 49534 - Fix coverity regression -- Ticket 49544 - cli release preperation, group improvements -- Ticket 49542 - Unpackaged files on el7 break rpm build -- Ticket 49541 - repl config should not allow rid 65535 for masters -- Ticket 49370 - Add all the password policy defaults to a new local policy -- Ticket 49425 - improve demo objects for install -- Ticket 49537 - allow asan to build with stable rustc -- Ticket 49526 - Improve create_test.py script -- Ticket 49516 - Add python 3 support for replication suite -- Ticket 49534 - Fix coverity issues and regression -- Ticket 49532 - coverity issues - fix compiler warnings & clang issues -- Ticket 49531 - coverity issues - fix memory leaks -- Ticket 49463 - After cleanALLruv, there is a flow of keep alive DEL -- Ticket 49529 - Fix Coverity warnings: invalid deferences -- Ticket 49509 - Indexing of internationalized matching rules is failing -- Ticket 49527 - Improve ds* cli tool testing -- Ticket 49474 - purge saslmaps before gssapi test -- Ticket 49413 - Changelog trimming ignores disabled replica-agreement -- Ticket 49446 - cleanallruv should ignore cleaned replica Id in processing changelog if in force mode -- Ticket 49278 - GetEffectiveRights gives false-negative -- Ticket 49508 - memory leak in cn=replica plugin setup -- Ticket 48118 - Add CI test case -- Ticket 49520 - Cockpit UI - Add database chaining HTML -- Ticket 49512 - Add ds-cockpit-setup to rpm spec file -- Ticket 49523 - Refactor CI test -- Ticket 49524 - Password policy: minimum token length fails when the token length is equal to attribute length -- Ticket 49517 - Cockpit UI - Add correct png files -- Ticket 49517 - Cockput UI - revise config layout -- Ticket 49523 - memberof: schema violation error message is confusing as memberof will likely repair target entry -- Ticket 49312 - Added a new test case for "-D configdir" -- Ticket 49512 - remove backup directories from cockpit source -- Ticket 49512 - Add initial Cockpit UI Plugin -- Ticket 49515 - cannot link, missing -fPIC -- Ticket 49474 - Improve GSSAPI testing capability -- Ticket 49493 - heap use after free in csn_as_string -- Ticket 49379 - Add Python 3 support to CI test -- Ticket 49431 - Add CI test case -- Ticket 49495 - cos stress test and improvements. -- Ticket 49495 - Fix memory management is vattr. -- Ticket 49494 - python 2 bytes mode. -- Ticket 49471 - heap-buffer-overflow in ss_unescape -- Ticket 48184 - close connections at shutdown cleanly. -- Ticket 49218 - Certmap - support TLS tests -- Ticket 49470 - overflow in pblock_get -- Ticket 49443 - Add CI test case -- Ticket 49484 - Minor cli tool fixes. -- Ticket 49486 - change ns stress core to use absolute int width. -- Ticket 49445 - Improve regression test to detect memory leak. -- Ticket 49445 - Memory leak in ldif2db -- Ticket 49485 - Typo in gccsec_defs -- Ticket 49479 - Remove unused 'batch' argument from lib389 -- Ticket 49480 - Improvements to support IPA install. -- Ticket 49474 - sasl allow mechs does not operate correctly -- Ticket 49449 - Load sysctl values on rpm upgrade. -- Ticket 49374 - Add CI test case -- Ticket 49325 - fix rust linking. -- Ticket 49475 - docker poc improvements. -- Ticket 49461 - Improve db2index handling for test 49290 -- Ticket 47536 - Add Python 3 support and move test case to suites -- Ticket 49444 - huaf in task.c during high load import -- Ticket 49460 - replica_write_ruv log a failure even when it succeeds -- Ticket 49298 - Ticket with test case and remove-ds.pl -- Ticket 49408 - Add a test case for nsds5ReplicaId checks -- Ticket 3 lib389 - python 3 support for subset of pwd cases -- Ticket 35 lib389 - dsconf automember support - -* Sat Jan 20 2018 Björn Esser - 1.4.0.3-1.2 -- Rebuilt for switch to libxcrypt - -* Thu Nov 30 2017 Pete Walter - 1.4.0.3-1.1 -- Rebuild for ICU 60.1 - -* Mon Nov 20 2017 Mark Reynolds - 1.4.0.3-1 -- Bump version to 1.4.0.3 -- Ticket 49457 - Fix spal_meminfo_get function prototype -- Ticket 49455 - Add tests to monitor test suit. -- Ticket 49448 - dynamic default pw scheme based on environment. -- Ticket 49298 - fix complier warn -- Ticket 49298 - Correct error codes with config restore. -- Ticket 49454 - SSL Client Authentication breaks in FIPS mode -- Ticket 49453 - passwd.py to use pwdhash defaults. -- Ticket 49427 - whitespace in fedse.c -- Ticket 49410 - opened connection can remain no longer poll, like hanging -- Ticket 48118 - fix compiler warning for incorrect return type -- Ticket 49451 - Add environment markers to lib389 dependencies -- Ticket 49325 - Proof of concept rust tqueue in sds -- Ticket 49443 - scope one searches in 1.3.7 give incorrect results -- Ticket 48118 - At startup, changelog can be erronously rebuilt after a normal shutdown -- Ticket 49412 - SIGSEV when setting invalid changelog config value -- Ticket 49441 - Import crashes - oneline fix -- Ticket 49377 - Incoming BER too large with TLS on plain port -- Ticket 49441 - Import crashes with large indexed binary attributes -- Ticket 49435 - Fix NS race condition on loaded test systems -- Ticket 77 - lib389 - Refactor docstrings in rST format - part 2 -- Ticket 17 - lib389 - dsremove support -- Ticket 3 - lib389 - python 3 compat for paged results test -- Ticket 3 - lib389 - Python 3 support for memberof plugin test suit -- Ticket 3 - lib389 - config test -- Ticket 3 - lib389 - python 3 support ds_logs tests -- Ticket 3 - lib389 - python 3 support for betxn test - -* Fri Nov 3 2017 Mark Reynolds - 1.4.0.2-2 -- Bump version to 1.4.0.2-2 -- Add python-lib389 build requirements - -* Fri Nov 3 2017 Mark Reynolds - 1.4.0.2-1 -- Bump version to 1.4.0.2-1 -- Ticket 48393 - fix copy and paste error -- Ticket 49439 - cleanallruv is not logging information -- Ticket 48393 - Improve replication config validation -- Ticket lib389 3 - Python 3 support for ACL test suite -- Ticket 103 - sysconfig not found -- Ticket 49436 - double free in COS in some conditions -- Ticket 48007 - CI test to test changelog trimming interval -- Ticket 49424 - Resolve csiphash alignment issues -- Ticket lib389 3 - Python 3 support for pwdPolicy_controls_test.py -- Ticket 3 - python 3 support - filter test -- Ticket 49434 - RPM build errors -- Ticket 49432 - filter optimise crash -- Ticket 49432 - Add complex fliter CI test -- Ticket 48894 - harden valueset_array_to_sorted_quick valueset access -- Ticket 49401 - Fix compiler incompatible-pointer-types warnings -- Ticket 48681 - Use of uninitialized value in string ne at /usr/bin/logconv.pl -- Ticket 49409 - Update lib389 requirements -- Ticket 49401 - improve valueset sorted performance on delete -- Ticket 49374 - server fails to start because maxdisksize is recognized incorrectly -- Ticket 49408 - Server allows to set any nsds5replicaid in the existing replica entry -- Ticket 49407 - status-dirsrv shows ellipsed lines -- Ticket 48681 - Use of uninitialized value in string ne at /usr/bin/logconv.pl -- Ticket 49386 - Memberof should be ignore MODRDN when the pre/post entry are identical -- Ticket 48006 - Missing warning for invalid replica backoff configuration -- Ticket 49064 - testcase hardening -- Ticket 49064 - RFE allow to enable MemberOf plugin in dedicated consumer -- Ticket lib389 3 - python 3 support -- Ticket 49402 - Adding a database entry with the same database name that was deleted hangs server at shutdown -- Ticket 48235 - remove memberof lock (cherry-pick error) -- Ticket 49394 - build warning -- Ticket 49381 - Refactor numerous suite docstrings - Part 2 -- Ticket 49394 - slapi_pblock_get may leave unchanged the provided variable -- Ticket 49403 - tidy ns logging -- Ticket 49381 - Refactor filter test suite docstrings -- Ticket 48235 - Remove memberOf global lock -- Ticket 103 - Make sysconfig where it is expected to exist -- Ticket 49400 - Add clang support to rpm builds -- Ticket 49381 - Refactor ACL test suite docstrings -- Ticket 49363 - Merge lib389 -- Ticket 101 - BaseException.message has been deprecated in Python3 -- Ticket 102 - referral support -- Ticket 99 - Fix typo in create_topology -- Ticket #98 - Fix dbscan output -- Ticket #77 - Fix changelogdb param issue -- Ticket #77 - Refactor docstrings in rST format - part 1 -- Ticket 96 - Change binaries' names -- Ticket 77 - Add sphinx documentation -- Ticket 43 - Add support for Referential Integrity plugin -- Ticket 45 - Add support for Rootdn Access Control plugin -- Ticket 46 - dsconf support for dynamic schema reload -- Ticket 74 - Advice users to set referint-update-delay to 0 -- Ticket 92 - display_attr() should return str not bytes in py3 -- Ticket 93 - Fix test cases in ctl_dbtasks_test.py -- Ticket 88 - python install and remove for tests -- Ticket 85 - Remove legacy replication attribute -- Ticket 91 - Fix replication topology -- Ticket 89 - Fix inconsistency with serverid -- Ticket 79 - Fix replica.py and add tests -- Ticket 86 - add build dir to gitignore -- Ticket 83 - Add an util for generating instance parameters -- Ticket 87 - Update accesslog regec for HR etimes -- Ticket 49 - Add support for whoami plugin -- Ticket 48 - Add support for USN plugin -- Ticket 78 - Add exists() method to DSLdapObject -- Ticket 31 - Allow complete removal of some memberOf attrs -- Ticket31 - Add memberOf fix-up task -- Ticket 67 - Add ensure_int function -- Ticket 59 - lib389 support for index management. -- Ticket 67 - get attr by type -- Ticket 70 - Improve repl tools -- Ticket 50 - typo in db2* in dsctl -- Ticket 31 - Add status command and SkipNested support for MemberOf -- Ticket 31 - Add functional tests for MemberOf plugin -- Ticket 66 - expand healthcheck for Directory Server -- Ticket 69 - add specfile requires -- Ticket 31 - Initial MemberOf plugin support -- Ticket 50 - Add db2* tasks to dsctl -- Ticket 65 - Add m2c2 topology -- Ticket 63 - part 2, agreement test -- Ticket 63 - lib389 python 3 fix -- Ticket 62 - dirsrv offline log -- Ticket 60 - add dsrc to dsconf and dsidm -- Ticket 32 - Add TLS external bind support for testing -- Ticket 27 - Fix get function in tests -- Ticket 28 - userAccount for older versions without nsmemberof -- Ticket 27 - Improve dseldif API -- Ticket 30 - Add initial support for account lock and unlock. -- Ticket 29 - fix incorrect format in tools -- Ticket 28 - Change default objectClasses for users and groups -- Ticket 1 - Fix missing dn / rdn on config. -- Ticket 27 - Add a module for working with dse.ldif file -- Ticket 1 - cn=config comparison -- Ticket 21 - Missing serverid in dirsrv_test due to incorrect allocation -- Ticket 26 - improve lib389 sasl support -- Ticket 24 - Join paths using os.path.join instead of string concatenation -- Ticket 25 - Fix RUV __repr__ function -- Ticket 23 - Use DirSrv.exists() instead of manually checking for instance's existence -- Ticket 1 - cn=config comparison -- Ticket 22 - Specify a basedn parameter for IDM modules -- Ticket 19 - missing readme.md in python3 -- Ticket 20 - Use the DN_DM constant instead of hard coding its value -- Ticket 19 - Missing file and improve make -- Ticket 14 - Remane dsadm to dsctl -- Ticket 16 - Reset InstScriptsEnabled argument during the init -- Ticket 14 - Remane dsadm to dsctl -- Ticket 13 - Add init function to create new domain entries -- Ticket 15 - Improve instance configuration ability -- Ticket 10 - Improve command line tool arguments -- Ticket 9 - Convert readme to MD -- Ticket 7 - Add pause and resume methods to topology fixtures -- Ticket 49172 - Allow lib389 to read system schema and instance -- Ticket 49172 - Allow lib389 to read system schema and instance -- Ticket 6 - Bump lib389 version 1.0.4 -- Ticket 5 - Fix container build on fedora -- Ticket 4 - Cert detection breaks some tests -- Ticket 49137 - Add sasl plain tests, lib389 support -- Ticket 2 - pytest mark with version relies on root -- Ticket 49126 - DIT management tool -- Ticket 49101 - Python 2 generate example entries -- Ticket 49103 - python 2 support for installer -- Ticket 47747 - Add topology_i2 and topology_i3 -- Ticket 49087 - lib389 resolve jenkins issues -- Ticket 48413 - Improvements to lib389 for rest -- Ticket 49083 - Support prefix for discovery of the defaults.inf file. -- Ticket 49055 - Fix debugging mode issue -- Ticket 49060 - Increase number of masters, hubs and consumers in topology -- Ticket 47747 - Add more topology fixtures -- Ticket 47840 - Add InstScriptsEnabled argument -- Ticket 47747 - Add topology fixtures module -- Ticket 48707 - Implement draft-wibrown-ldapssotoken-01 -- Ticket 49022 - Lib389, py3 installer cannot create entries in backend -- Ticket 49024 - Fix paths to the dbdir parent -- Ticket 49024 - Fix db_dir paths -- Ticket 49024 - Fix paths in tools module -- Ticket 48961 - Fix lib389 minor issues shown by 48961 test -- Ticket 49010 - Lib389 fails to start with systemctl changes -- Ticket 49007 - lib389 fixes for paths to use online values -- Ticket 49005 - Update lib389 to work in containers correctly. -- Ticket 48991 - Fix lib389 spec for python2 and python3 -- Ticket 48984 - Add lib389 paths module -- Ticket 48951 - dsadm dsconfig status and plugin -- Ticket 47957 - Update the replication "idle" status string -- Ticket 48951 - dsadm and dsconf base files -- Ticket 48952 - Restart command needs a sleep -- Ticket 48949 - Fix ups for style and correctness -- Ticket 48949 - added copying slapd-collations.conf -- Ticket 48949 - change default file path generation - use os.path.join -- Ticket 48949 - os.makedirs() exist_ok not python2 compatible, added try/except -- Ticket 48949 - configparser fallback not python2 compatible -- Ticket 48946 - openConnection should not fully popluate DirSrv object -- Ticket 48832 - Add DirSrvTools.getLocalhost() function -- Ticket 48382 - Fix serverCmd to get sbin dir properly -- Bug 1347760 - Information disclosure via repeated use of LDAP ADD operation, etc. -- Ticket 48937 - Cleanup valgrind wrapper script -- Ticket 48923 - Fix additional issue with serverCmd -- Ticket 48923 - serverCmd timeout not working as expected -- Ticket 48917 - Attribute presence -- Ticket 48911 - Plugin improvements for lib389 -- Ticket 48911 - Improve plugin support based on new mapped objects -- Ticket 48910 - Fixes for backend tests and lib389 reliability. -- Ticket 48860 - Add replication tools -- Ticket 48888 - Correction to create of dsldapobject -- Ticket 48886 - Fix NSS SSL library in lib389 -- Ticket 48885 - Fix spec file requires -- Ticket 48884 - Bugfixes for mapped object and new connections -- Ticket 48878 - better style for backend in backend_test.py -- Ticket 48878 - pep8 fixes part 2 -- Ticket 48878 - pep8 fixes and fix rpm to build -- Ticket 48853 - Prerelease installer -- Ticket 48820 - Begin to test compatability with py.test3, and the new orm -- Ticket 48434 - Fix for negative tz offsets -- Ticket 48857 - Remove python-krbV from lib389 -- Ticket 48820 - Fix tests to ensure they work with the new object types -- Ticket 48820 - Move Encryption and RSA to the new object types -- Ticket 48820 - Proof of concept of orm style mapping of configs and objects -- Ticket 48820 - Clitool rename -- Ticket 48431 - lib389 integrate ldclt -- Ticket 48434 - lib389 logging tools -- Ticket 48796 - add function to remove logs -- Ticket 48771 - lib389 - get ns-slapd version -- Ticket 48830 - Convert lib389 to ip route tools -- Ticket 48763 - backup should run regardless of existing backups. -- Ticket 48434 - lib389 logging tools -- Ticket 48798 - EL6 compat for lib389 tests for DH params -- Ticket 48798 - lib389 add ability to create nss ca and certificate -- Ticket 48433 - Aci linting tools -- Ticket 48791 - format args in server tools -- Ticket 48399 - Helper makefile is missing mkdir dist -- Ticket 48399 - Helper makefile is missing mkdir dist -- Ticket 48794 - lib389 build requires are on a single line -- Ticket 48660 - Add function to convert binary values in an entry to base64 -- Ticket 48764 - Fix mit krb password to be random. -- Ticket 48765 - Change default ports for standalone topology -- Ticket 48750 - Clean up logging to improve command experience -- Ticket 48751 - Improve lib389 ldapi support -- Ticket 48399 - Add helper makefile to lib389 to build and install -- Ticket 48661 - Agreement test suite fails at the test_changes case -- Ticket 48407 - Add test coverage module for lib389 repo -- Ticket 48357 - clitools should standarise their args -- Ticket 48560 - Make verbose handling consistent -- Ticket 48419 - getadminport() should not a be a static method -- Ticket 48408 - RFE escaped default suffix for tests -- Ticket 48401 - Revert typecheck -- Ticket 48401 - lib389 Entry hasAttr returs dict instead of false -- Ticket 48390 - RFE Improvements to lib389 monitor features for rest389 -- Ticket 48358 - Add new spec file -- Ticket 48371 - weaker host check on localhost.localdomain -- Ticket 58358 - Update spec file with pre-release versioning -- Ticket 48358 - Make Fedora packaging changes to the spec file -- Ticket 48358 - Prepare lib389 for Fedora Packaging -- Ticket 48364 - Fix test failures -- Ticket 48360 - Refactor the delete agreement function -- Ticket 48361 - Expand 389ds monitoring capabilities -- Ticket 48246 - Adding license/copyright to lib389 files -- Ticket 48340 - Add basic monitor support to lib389 https://fedorahosted.org/389/ticket/48340 -- Ticket 48353 - Add Replication REST support to lib389 -- Ticket 47840 - Fix regression -- Ticket 48343 - lib389 krb5 realm management https://fedorahosted.org/389/ticket/48343 -- Ticket 47840 - fix lib389 to use sbin scripts https://fedorahosted.org/389/ticket/47840 -- Ticket 48335 - Add SASL support to lib389 -- Ticket 48329 - Fix case-senstive scyheam comparisions -- Ticket 48303 - Fix lib389 broken tests -- Ticket 48329 - add matching rule functions to schema module -- Ticket 48324 - fix boolean capitalisation (one line) https://fedorahosted.org/389/ticket/48324 -- Ticket 48321 - Improve is_a_dn check to prevent mistakes with lib389 auth https://fedorahosted.org/389/ticket/48321 -- Ticket 48322 - Allow reindex function to reindex all attributes -- Ticket 48319 - Fix ldap.LDAPError exception processing -- Ticket 48318 - Do not delete a changelog while disabling a replication by suffix -- Ticket 48308 - Add __eq__ and __ne__ to Entry to allow fast comparison https://fedorahosted.org/389/ticket/48308 -- Ticket 48303 - Fix lib389 broken tests - backend_test -- Ticket 48309 - Fix lib389 lib imports -- Ticket 48303 - Fix lib389 broken tests - agreement_test -- Ticket 48303 - Fix lib389 broken tests - aci_parse_test -- Ticket 48301 - add tox support -- Ticket 48204 - update lib389 for python3 -- Ticket 48273 - Improve valgrind functions -- Ticket 48271 - Fix for self.prefix being none when SER_DEPLOYED_DIR is none https://fedorahosted.org/389/ticket/48271 -- Ticket 48259 - Add aci parsing utilities to lib389 -- Ticket 48252 - (lib389) adding get_bin_dir and dbscan -- Ticket 48247 - Change the default user to 'dirsrv' -- Ticket 47848 - Add new function to create ldif files -- Ticket 48239 - Fix for prefix allocation of un-initialised dirsrv objects -- Ticket 48237 - Add lib389 helper to enable and disable logging services. -- Ticket 48236 - Add get effective rights helper to lib389 -- Ticket 48238 - Add objectclass and attribute type query mechanisms -- Ticket 48029 - Add missing replication related functions -- Ticket 48028 - add valgrind wrapper for ns-slapd -- Ticket 48028 - lib389 - add valgrind functions -- Ticket 48022 - lib389 - Add all the server tasks -- Ticket 48023 - create function to test replication between servers -- Ticket 48020 - lib389 - need to reset args_instance with every DirSrv init -- Ticket 48000 - Repl agmts need more time to stop -- Ticket 48004 - Fix various issues -- Ticket 48000 - replica agreement pause/resume should have a short sleep -- Ticket 47990 - Add check for ".removed" instances when doing an upgrade -- Ticket 47990 - Add "upgrade" function to lib389 -- Ticket 47691 - using lib389 with RPMs -- Ticket 47848 - Add support for setuptools. -- Ticket 47855 - Add function to clear tmp directory -- Ticket 47851 - Need to retrieve tmp directory path -- Ticket 47845 - add stripcsn option to tombstone fixup task -- Ticket 47851 - Add function to retrieve dirsrvtests data directory -- Ticket 47845 - Add backup/restore/fixup tombstone tasks to lib389 -- Ticket 47819 - Add the new precise tombstone purging config attribute -- Ticket 47695 - Add plugins/tasks/Index -- Ticket 47648 - lib389 - add schema classes, methods -- Ticket 47671 - CI lib389: allow to open a DirSrv without having to create the instance -- Ticket 47600 - Replica/Agreement/Changelog not conform to the design -- Ticket 47652 - replica add fails: MT.list return a list not an entry -- Ticket 47635 - MT/Backend/Suffix to be conform with the design -- Ticket 47625 - CI lib389: DirSrv not conform to the design -- Ticket 47595 - fail to detect/reinit already existing instance/backup -- Ticket 47590 - CI tests: add/split functions around replication -- Ticket 47584 - CI tests: add backup/restore of an instance -- Ticket 47578 - CI tests: removal of 'sudo' and absolute path in lib389 -- Ticket 47568 - Rename DSAdmin class -- Ticket 47566 - Initial import of DSadmin into 389-test repos - -* Mon Oct 16 2017 Mark Reynolds - 1.4.0.1-2 -- Bump version to 1.4.0.1-2 -- Ticket 49400 - Add clang support and libatomic - -* Mon Oct 9 2017 Mark Reynolds - 1.4.0.1-1 -- Bump version to 1.4.0.1-1 -- Ticket 49038 - remove legacy replication - change cleanup script precedence -- Ticket 49392 - memavailable not available -- Ticket 49235 - pbkdf2 by default -- Ticket 49279 - remove dsktune -- Ticket 49372 - filter optimisation improvements for common queries -- Ticket 49320 - Activating already active role returns error 16 -- Ticket 49389 - unable to retrieve specific cosAttribute when subtree password policy is configured -- Ticket 49092 - Add CI test for schema-reload -- Ticket 49388 - repl-monitor - matches null string many times in regex -- Ticket 49387 - pbkdf2 settings were too aggressive -- Ticket 49385 - Fix coverity warnings -- Ticket 49305 - Need to wrap atomic calls -- Ticket 48973 - Indexing a ExactIA5Match attribute with a IgnoreIA5Match matching rule triggers a warning -- Ticket 49378 - server init fails -- Ticket 49305 - Need to wrap atomic calls -- Ticket 49180 - add CI test -- Ticket 49180 - errors log filled with attrlist_replace - attr_replace - -* Fri Sep 22 2017 Mark Reynolds - 1.4.0.0-1 -- Bump version to 1.4.0.0-1 - diff --git a/sources b/sources index b516217..5f43aa6 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (389-ds-base-1.4.4.6.tar.bz2) = 4ce55096ce82b4de40341348ee6e8e785b27759980b5400567033ebeafd4b87317932d005ea213985db9a642aab11799c01e96a0a6df6747a92cbbda0c283c81 +SHA512 (389-ds-base-1.4.5.0.tar.bz2) = a60299348f5f7c56293e8cfb57544fc28ac2b240ec1546eec96a8884340e971ecd1872e0a316ac532f5a431875f1314eea6cb85fd551f49857e891dd9b0ef385 SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 From d9f3efb8f9f67cc8360f92669f3adce44ade4149 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Wed, 28 Oct 2020 12:42:10 -0400 Subject: [PATCH 006/125] Bump version to 1.4.5.0 Issue 2526 - revert backend validation check Issue 4262 - more perl removal cleanup Issue 2526 - retrocl backend created out of order --- 389-ds-base.spec | 1 - 1 file changed, 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 2b12202..1e73447 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -621,7 +621,6 @@ exit 0 %changelog * Wed Oct 28 2020 Mark Reynolds - 1.4.5.0-1 - Bump version to 1.4.5.0 -- Issue 2526 - revert backend validation check - Issue 4262 - more perl removal cleanup - Issue 2526 - retrocl backend created out of order From ded5ac347340e7dc37ccf0900293f7d3889292ce Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Tue, 3 Nov 2020 14:08:49 -0500 Subject: [PATCH 007/125] Bump version to 2.0.1 Issue 4420 - change NVR to use X.X.X instead of X.X.X.X Issue 4391 - DSE config modify does not call be_postop (#4394) Issue 4218 - Verify the new wtime and optime access log keywords (#4397) Issue 4176 - CL trimming causes high CPU Issue 2058 - Add keep alive entry after on-line initialization - second version (#4399) Issue 4403 - RFE - OpenLDAP pw hash migration tests (#4408) --- .gitignore | 1 + 389-ds-base.spec | 11 ++++++++++- sources | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 1fe4508..4c53006 100644 --- a/.gitignore +++ b/.gitignore @@ -198,3 +198,4 @@ /389-ds-base-1.4.4.4.tar.bz2 /389-ds-base-1.4.4.6.tar.bz2 /389-ds-base-1.4.5.0.tar.bz2 +/389-ds-base-2.0.1.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 1e73447..4293b51 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 1.4.5.0 +Version: 2.0.1 Release: %{?relprefix}1%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org @@ -619,6 +619,15 @@ exit 0 %endif %changelog +* Thu Oct 29 2020 Mark Reynolds - 2.0.1-1 +- Bump version to 2.0.1 +- Issue 4420 - change NVR to use X.X.X instead of X.X.X.X +- Issue 4391 - DSE config modify does not call be_postop (#4394) +- Issue 4218 - Verify the new wtime and optime access log keywords (#4397) +- Issue 4176 - CL trimming causes high CPU +- Issue 2058 - Add keep alive entry after on-line initialization - second version (#4399) +- Issue 4403 - RFE - OpenLDAP pw hash migration tests (#4408) + * Wed Oct 28 2020 Mark Reynolds - 1.4.5.0-1 - Bump version to 1.4.5.0 - Issue 4262 - more perl removal cleanup diff --git a/sources b/sources index 5f43aa6..70352ed 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (389-ds-base-1.4.5.0.tar.bz2) = a60299348f5f7c56293e8cfb57544fc28ac2b240ec1546eec96a8884340e971ecd1872e0a316ac532f5a431875f1314eea6cb85fd551f49857e891dd9b0ef385 +SHA512 (389-ds-base-2.0.1.tar.bz2) = 34395b9fc73965518b4e0fc1ad5e2053bb0bb2fe38367437dd17a5a735d3d11106d510d43939083cbebcdff9c7790b367b44a3a563fb37899105ad24865eaa2b SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 From e0d848b7677a385f7e5a5e03184c8a0a5ccd1ff6 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Tue, 15 Dec 2020 01:01:35 +0000 Subject: [PATCH 008/125] Add BuildRequires: make https://fedoraproject.org/wiki/Changes/Remove_make_from_BuildRoot --- 389-ds-base.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/389-ds-base.spec b/389-ds-base.spec index 4293b51..697a9d6 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -195,6 +195,7 @@ BuildRequires: libtevent-devel Requires: krb5-libs Requires: libevent BuildRequires: systemd-devel +BuildRequires: make Provides: svrcore = 4.1.4 Conflicts: svrcore Obsoletes: svrcore <= 4.1.3 From a5985f5eb8df6db6cdd493ae9bac768e2e9076b5 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Thu, 14 Jan 2021 16:42:31 -0500 Subject: [PATCH 009/125] Bump version to 2.0.2 Issue 4539 - BUG - no such file if no overlays in openldap during migration (#4540) Issue 4528 - Fix cn=monitor SCOPE_ONE search (#4529) Issue 4535 - lib389 - healthcheck throws exception if backend is not replicated Issue 4537 - Use KRB5_CLIENT_KTNAME for client keytabs (#4523) Issue 4513 - CI Tests - fix test failures Issue 4504 - insure that repl_monitor_test use ldapi (for RHEL) - fix merge issue (#4533) Issue 4315 - performance search rate: nagle triggers high rate of setsocketopt Issue 4504 - pytest test_dsconf_replication_monitor fails on RHEL - Fix merging issue (#4530) Issue 4504 - Insure ldapi is enabled in repl_monitor_test.py (Needed on RHEL) (#4527) Issue 4506 - BUG - Fix bounds on fd table population (#4520) Issue 4521 - DS crash in deref plugin if dereferenced entry exists but is not returned by internal search (#4525) Issue 4219 - Log internal unindexed searches (notes=A) Issue 4384 - Separate eventq into REALTIME and MONOTONIC Issue 4381 - RFE - LDAPI authentication DN rewritter Issue 4513 - Fix schema test and lib389 task module (#4514) Issue 4414 - disk monitoring - prevent division by zero crash Issue 4517 - BUG: Multiple systemd pin warnings (#4518) Issue 4507 - Improve csngen testing task (#4508) Issue 4498 - BUG - entryuuid replication may not work (#4503) Issue 4480 - Unexpected info returned to ldap request (#4491) Issue 4504 - Fix pytest test_dsconf_replication_monitor (#4505) Issue 4373 - BUG - one line cleanup, free results in mt if ent 0 (#4502) Issue 4500 - Add cockpit enabling to dsctl Issue 4272 - RFE - add support for gost-yescrypt for hashing passwords (#4497) Issue 1795 - RFE - Enable logging for libldap and libber in error log (#4481) Issue 3522 - Remove DES to AES conversion code Issue 4492 - Changelog cache can upload updates from a wrong starting point (CSN) (#4493) Issue 4373 - BUG - calloc of size 0 in MT build (#4496) Issue 4483 - heap-use-after-free in slapi_be_getsuffix Issue 4486 - Remove random ldif file generation from import test (#4487) Issue 4224 - cleanup specfile after libsds removal Issue 4421 - Unable to build with Rust enabled in closed environment Issue 4489 - Remove return statement from a void function (#4490) Issue 4229 - RFE - Improve rust linking and build performance (#4474) Issue 4224 - openldap can become confused with entryuuid Issue 4313 - improve tests and improve readme re refdel Issue 4313 - fix potential syncrepl data corruption Issue 4419 - Warn users of skipped entries during ldif2db online import (#4476) Issue 4243 - Fix test (4th): SyncRepl plugin provides a wrong (#4475) Issue 4315 - performance search rate: nagle triggers high rate of setsocketopt (#4437) Issue 4460 - BUG - add machine name to subject alt names in SSCA (#4472) Issue 4446 - RFE - openldap password hashers Issue 4284 - dsidm fails to delete an organizationalUnit entry Issue 4243 - Fix test: SyncRepl plugin provides a wrong cookie (#4466) (#4466) Issue 4464 - RFE - clang with ds+asan+rust Issue 4105 - Remove python.six (fix regression) Issue 4384 - Use MONOTONIC clock for all timing events and conditions Issue 4418 - ldif2db - offline. Warn the user of skipped entries Issue 4243 - Fix test: SyncRepl plugin provides a wrong cookie (#4467) Issue 4460 - BUG - lib389 should use system tls policy Issue 3657 - Add options to dsctl for dsrc file Issue 4454 - RFE - fix version numbers to allow object caching Issue 3986 - UI - Handle objectclasses that do not have X-ORIGIN set Issue 4297 - 2nd fix for on ADD replication URP issue internal searches with filter containing unescaped chars (#4439) Issue 4112 - Added a CI test (#4441) Issue 4449 - dsconf replication monitor fails to retrieve database RUV - consumer (Unavailable) (#4451) Issue 4105 - Remove python.six from lib389 (#4456) Issue 4440 - BUG - ldifgen with --start-idx option fails with unsupported operand (#4444) Issue 4410 - RFE - ndn cache with arc in rust Issue 4373 - BUG - Mapping Tree nodes can be created that are invalid Issue 4428 - BUG Paged Results with critical false causes sigsegv in chaining Issue 4428 - Paged Results with Chaining Test Case Issue 2054 - do not add referrals for masters with different data generation Issue 4383 - Do not normalize escaped spaces in a DN Issue 4432 - After a failed online import the next imports are very slow Issue 4316 - performance search rate: useless poll on network send callback (#4424) Issue 4281 - dsidm user status fails with Error: 'nsUserAccount' object has no attribute 'is_locked' Issue 4429 - NULL dereference in revert_cache() Issue 4412 - Fix CLI repl-agmt requirement for parameters (#4422) Issue 4407 - RFE - remove http client and presence plugin (#4409) Issue 4398 - build problems at alpine linux Issue 4415 - unable to query schema if there are extra parenthesis --- .gitignore | 1 + 389-ds-base.spec | 90 ++++++++++++++++++++++++++++++++++++++++++------ sources | 2 +- 3 files changed, 81 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 4c53006..d28271f 100644 --- a/.gitignore +++ b/.gitignore @@ -199,3 +199,4 @@ /389-ds-base-1.4.4.6.tar.bz2 /389-ds-base-1.4.5.0.tar.bz2 /389-ds-base-2.0.1.tar.bz2 +/389-ds-base-2.0.2.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 697a9d6..4900d7b 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -16,7 +16,7 @@ ExcludeArch: i686 %global use_Socket6 0 %global use_asan 0 -%global use_rust 0 +%global use_rust 1 %global bundle_jemalloc 1 %if %{use_asan} %global bundle_jemalloc 0 @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.0.1 +Version: 2.0.2 Release: %{?relprefix}1%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org @@ -195,7 +195,7 @@ BuildRequires: libtevent-devel Requires: krb5-libs Requires: libevent BuildRequires: systemd-devel -BuildRequires: make +BuildRequires: make Provides: svrcore = 4.1.4 Conflicts: svrcore Obsoletes: svrcore <= 4.1.3 @@ -240,7 +240,6 @@ Requires: iproute Recommends: bash-completion Requires: python%{python3_pkgversion} Requires: python%{python3_pkgversion}-distro -Requires: python%{python3_pkgversion}-pytest Requires: python%{python3_pkgversion}-ldap Requires: python%{python3_pkgversion}-six Requires: python%{python3_pkgversion}-pyasn1 @@ -289,7 +288,7 @@ ASAN_FLAGS="--enable-asan --enable-debug" %endif %if %{use_rust} -RUST_FLAGS="--enable-rust" +RUST_FLAGS="--enable-rust --enable-rust-offline" %endif %if !%{use_cockpit} @@ -571,11 +570,9 @@ exit 0 %{_libdir}/libsvrcore.so %{_libdir}/%{pkgname}/libslapd.so %{_libdir}/%{pkgname}/libns-dshttpd.so -%{_libdir}/%{pkgname}/libsds.so %{_libdir}/%{pkgname}/libldaputil.so %{_libdir}/pkgconfig/svrcore.pc %{_libdir}/pkgconfig/dirsrv.pc -%{_libdir}/pkgconfig/libsds.pc %files libs %doc LICENSE LICENSE.GPLv3+ LICENSE.openssl README.devel @@ -583,15 +580,11 @@ exit 0 %{_libdir}/libsvrcore.so.* %{_libdir}/%{pkgname}/libslapd.so.* %{_libdir}/%{pkgname}/libns-dshttpd-*.so -%{_libdir}/%{pkgname}/libsds.so.* %{_libdir}/%{pkgname}/libldaputil.so.* %{_libdir}/%{pkgname}/librewriters.so* %if %{bundle_jemalloc} %{_libdir}/%{pkgname}/lib/libjemalloc.so.2 %endif -%if %{use_rust} -%{_libdir}/%{pkgname}/librsds.so -%endif %files snmp %doc LICENSE LICENSE.GPLv3+ LICENSE.openssl README.devel @@ -620,6 +613,81 @@ exit 0 %endif %changelog +* Thu Jan 14 2021 Mark Reynolds - 2.0.2-1 +- Bump version to 2.0.2 +- Issue 4539 - BUG - no such file if no overlays in openldap during migration (#4540) +- Issue 4528 - Fix cn=monitor SCOPE_ONE search (#4529) +- Issue 4535 - lib389 - healthcheck throws exception if backend is not replicated +- Issue 4537 - Use KRB5_CLIENT_KTNAME for client keytabs (#4523) +- Issue 4513 - CI Tests - fix test failures +- Issue 4504 - insure that repl_monitor_test use ldapi (for RHEL) - fix merge issue (#4533) +- Issue 4315 - performance search rate: nagle triggers high rate of setsocketopt +- Issue 4504 - pytest test_dsconf_replication_monitor fails on RHEL - Fix merging issue (#4530) +- Issue 4504 - Insure ldapi is enabled in repl_monitor_test.py (Needed on RHEL) (#4527) +- Issue 4506 - BUG - Fix bounds on fd table population (#4520) +- Issue 4521 - DS crash in deref plugin if dereferenced entry exists but is not returned by internal search (#4525) +- Issue 4219 - Log internal unindexed searches (notes=A) +- Issue 4384 - Separate eventq into REALTIME and MONOTONIC +- Issue 4381 - RFE - LDAPI authentication DN rewritter +- Issue 4513 - Fix schema test and lib389 task module (#4514) +- Issue 4414 - disk monitoring - prevent division by zero crash +- Issue 4517 - BUG: Multiple systemd pin warnings (#4518) +- Issue 4507 - Improve csngen testing task (#4508) +- Issue 4498 - BUG - entryuuid replication may not work (#4503) +- Issue 4480 - Unexpected info returned to ldap request (#4491) +- Issue 4504 - Fix pytest test_dsconf_replication_monitor (#4505) +- Issue 4373 - BUG - one line cleanup, free results in mt if ent 0 (#4502) +- Issue 4500 - Add cockpit enabling to dsctl +- Issue 4272 - RFE - add support for gost-yescrypt for hashing passwords (#4497) +- Issue 1795 - RFE - Enable logging for libldap and libber in error log (#4481) +- Issue 3522 - Remove DES to AES conversion code +- Issue 4492 - Changelog cache can upload updates from a wrong starting point (CSN) (#4493) +- Issue 4373 - BUG - calloc of size 0 in MT build (#4496) +- Issue 4483 - heap-use-after-free in slapi_be_getsuffix +- Issue 4486 - Remove random ldif file generation from import test (#4487) +- Issue 4224 - cleanup specfile after libsds removal +- Issue 4421 - Unable to build with Rust enabled in closed environment +- Issue 4489 - Remove return statement from a void function (#4490) +- Issue 4229 - RFE - Improve rust linking and build performance (#4474) +- Issue 4224 - openldap can become confused with entryuuid +- Issue 4313 - improve tests and improve readme re refdel +- Issue 4313 - fix potential syncrepl data corruption +- Issue 4419 - Warn users of skipped entries during ldif2db online import (#4476) +- Issue 4243 - Fix test (4th): SyncRepl plugin provides a wrong (#4475) +- Issue 4315 - performance search rate: nagle triggers high rate of setsocketopt (#4437) +- Issue 4460 - BUG - add machine name to subject alt names in SSCA (#4472) +- Issue 4446 - RFE - openldap password hashers +- Issue 4284 - dsidm fails to delete an organizationalUnit entry +- Issue 4243 - Fix test: SyncRepl plugin provides a wrong cookie (#4466) (#4466) +- Issue 4464 - RFE - clang with ds+asan+rust +- Issue 4105 - Remove python.six (fix regression) +- Issue 4384 - Use MONOTONIC clock for all timing events and conditions +- Issue 4418 - ldif2db - offline. Warn the user of skipped entries +- Issue 4243 - Fix test: SyncRepl plugin provides a wrong cookie (#4467) +- Issue 4460 - BUG - lib389 should use system tls policy +- Issue 3657 - Add options to dsctl for dsrc file +- Issue 4454 - RFE - fix version numbers to allow object caching +- Issue 3986 - UI - Handle objectclasses that do not have X-ORIGIN set +- Issue 4297 - 2nd fix for on ADD replication URP issue internal searches with filter containing unescaped chars (#4439) +- Issue 4112 - Added a CI test (#4441) +- Issue 4449 - dsconf replication monitor fails to retrieve database RUV - consumer (Unavailable) (#4451) +- Issue 4105 - Remove python.six from lib389 (#4456) +- Issue 4440 - BUG - ldifgen with --start-idx option fails with unsupported operand (#4444) +- Issue 4410 - RFE - ndn cache with arc in rust +- Issue 4373 - BUG - Mapping Tree nodes can be created that are invalid +- Issue 4428 - BUG Paged Results with critical false causes sigsegv in chaining +- Issue 4428 - Paged Results with Chaining Test Case +- Issue 2054 - do not add referrals for masters with different data generation +- Issue 4383 - Do not normalize escaped spaces in a DN +- Issue 4432 - After a failed online import the next imports are very slow +- Issue 4316 - performance search rate: useless poll on network send callback (#4424) +- Issue 4281 - dsidm user status fails with Error: 'nsUserAccount' object has no attribute 'is_locked' +- Issue 4429 - NULL dereference in revert_cache() +- Issue 4412 - Fix CLI repl-agmt requirement for parameters (#4422) +- Issue 4407 - RFE - remove http client and presence plugin (#4409) +- Issue 4398 - build problems at alpine linux +- Issue 4415 - unable to query schema if there are extra parenthesis + * Thu Oct 29 2020 Mark Reynolds - 2.0.1-1 - Bump version to 2.0.1 - Issue 4420 - change NVR to use X.X.X instead of X.X.X.X diff --git a/sources b/sources index 70352ed..f0a20b7 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (389-ds-base-2.0.1.tar.bz2) = 34395b9fc73965518b4e0fc1ad5e2053bb0bb2fe38367437dd17a5a735d3d11106d510d43939083cbebcdff9c7790b367b44a3a563fb37899105ad24865eaa2b SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 +SHA512 (389-ds-base-2.0.2.tar.bz2) = 42805311e45b2f3305f86da50d5a0128b19cd15aeb4787ccb67b5ceea9f7a7efe42076dff1d47d4d61012453405403c730c245d53431043eb05c125455938c37 From f841ce7ce53f4fadf22908745732d04e5103be5f Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Mon, 25 Jan 2021 22:12:41 +0000 Subject: [PATCH 010/125] - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 4900d7b..2482664 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,7 +47,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.0.2 -Release: %{?relprefix}1%{?prerel}%{?dist} +Release: %{?relprefix}1%{?prerel}%{?dist}.1 License: GPLv3+ URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -613,6 +613,9 @@ exit 0 %endif %changelog +* Mon Jan 25 2021 Fedora Release Engineering - 2.0.2-1.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + * Thu Jan 14 2021 Mark Reynolds - 2.0.2-1 - Bump version to 2.0.2 - Issue 4539 - BUG - no such file if no overlays in openldap during migration (#4540) From 5a5753301ee3744c5fd40df43c1c6f4b7ec8bc80 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Fri, 12 Feb 2021 15:59:14 -0500 Subject: [PATCH 011/125] Bump version to 2.0.3 Issue 4619 - remove pytest requirement from lib389 Issue 4615 - log message when psearch first exceeds max threads per conn Issue 4469 - Backend redesing phase 3a - implement dbimpl API and use it in back-ldbm (#4618) Issue 4324 - Some architectures the cache line size file does not exist Issue 4593 - RFE - Print help when nsSSLPersonalitySSL is not found (#4614) Issue 4469 - Backend redesign phase 3a - bdb dependency removal from back-ldbm PR 4564 - Update dscontainer Issue 4149 - UI - port TreeView and opther components to PF4 Issue 4577 - Add GitHub actions Issue 4591 - RFE - improve openldap_to_ds help and features (#4607) issue 4612 - Fix pytest fourwaymmr_test for non root user (#4613) Issue 4609 - CVE - info disclosure when authenticating Issue 4348 - Add tests for dsidm Issue 4571 - Stale libdb-utils dependency Issue 4600 - performance modify rate: reduce lock contention on the object extension factory (#4601) Issue 4577 - Add GitHub actions Issue 4588 - BUG - unable to compile without xcrypt (#4589) Issue 4579 - libasan detects heap-use-after-free in URP test (#4584) Issue 4581 - A failed re-indexing leaves the database in broken state (#4582) Issue 4348 - Add tests for dsidm Issue 4577 - Add GitHub actions Issue 4563 - Failure on s390x: 'Fails to split RDN "o=pki-tomcat-CA" into components' (#4573) Issue 4093 - fix compiler warnings and update doxygen Issue 4575 - Update test docstrings metadata Issue 4526 - sync_repl: when completing an operation in the pending list, it can select the wrong operation (#4553) Issue 4324 - Performance search rate: change entry cache monitor to recursive pthread mutex (#4569) Issue 4513 - Add DS version check to SSL version test (#4570) Issue 5442 - Search results are different between RHDS10 and RHDS11 Issue 4396 - Minor memory leak in backend (#4558) Issue 4513 - Fix replication CI test failures (#4557) Issue 4513 - Fix replication CI test failures (#4557) Issue 4153 - Added a CI test (#4556) Issue 4506 - BUG - fix oob alloc for fds (#4555) Issue 4548 - CLI - dsconf needs better root DN access control plugin validation Issue 4506 - Temporary fix for io issues (#4516) Issue 4535 - lib389 - Fix log function in backends.py Issue 4534 - libasan read buffer overflow in filtercmp (#4541) Issue 4544 - Compiler warnings on krb5 functions (#4545) Update rpm.mk for RUST tarballs --- .gitignore | 1 + 389-ds-base.spec | 48 +++++++++++++++++++++++++++++++++++++++++++++--- sources | 2 +- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index d28271f..b272f37 100644 --- a/.gitignore +++ b/.gitignore @@ -200,3 +200,4 @@ /389-ds-base-1.4.5.0.tar.bz2 /389-ds-base-2.0.1.tar.bz2 /389-ds-base-2.0.2.tar.bz2 +/389-ds-base-2.0.3.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 2482664..73e901e 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,8 +46,8 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.0.2 -Release: %{?relprefix}1%{?prerel}%{?dist}.1 +Version: 2.0.3 +Release: %{?relprefix}1%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -330,7 +330,7 @@ popd %endif # Enforce strict linking -%define _strict_symbol_defs_build 1 +%define _ld_strict_symbol_defs 1 # Rebuild the autotool artifacts now. autoreconf -fiv @@ -613,6 +613,48 @@ exit 0 %endif %changelog +* Fri Feb 12 2021 Mark Reynolds - 2.0.3-1 +- Bump version to 2.0.3 +- Issue 4619 - remove pytest requirement from lib389 +- Issue 4615 - log message when psearch first exceeds max threads per conn +- Issue 4469 - Backend redesing phase 3a - implement dbimpl API and use it in back-ldbm (#4618) +- Issue 4324 - Some architectures the cache line size file does not exist +- Issue 4593 - RFE - Print help when nsSSLPersonalitySSL is not found (#4614) +- Issue 4469 - Backend redesign phase 3a - bdb dependency removal from back-ldbm +- PR 4564 - Update dscontainer +- Issue 4149 - UI - port TreeView and opther components to PF4 +- Issue 4577 - Add GitHub actions +- Issue 4591 - RFE - improve openldap_to_ds help and features (#4607) +- issue 4612 - Fix pytest fourwaymmr_test for non root user (#4613) +- Issue 4609 - CVE - info disclosure when authenticating +- Issue 4348 - Add tests for dsidm +- Issue 4571 - Stale libdb-utils dependency +- Issue 4600 - performance modify rate: reduce lock contention on the object extension factory (#4601) +- Issue 4577 - Add GitHub actions +- Issue 4588 - BUG - unable to compile without xcrypt (#4589) +- Issue 4579 - libasan detects heap-use-after-free in URP test (#4584) +- Issue 4581 - A failed re-indexing leaves the database in broken state (#4582) +- Issue 4348 - Add tests for dsidm +- Issue 4577 - Add GitHub actions +- Issue 4563 - Failure on s390x: 'Fails to split RDN "o=pki-tomcat-CA" into components' (#4573) +- Issue 4093 - fix compiler warnings and update doxygen +- Issue 4575 - Update test docstrings metadata +- Issue 4526 - sync_repl: when completing an operation in the pending list, it can select the wrong operation (#4553) +- Issue 4324 - Performance search rate: change entry cache monitor to recursive pthread mutex (#4569) +- Issue 4513 - Add DS version check to SSL version test (#4570) +- Issue 5442 - Search results are different between RHDS10 and RHDS11 +- Issue 4396 - Minor memory leak in backend (#4558) +- Issue 4513 - Fix replication CI test failures (#4557) +- Issue 4513 - Fix replication CI test failures (#4557) +- Issue 4153 - Added a CI test (#4556) +- Issue 4506 - BUG - fix oob alloc for fds (#4555) +- Issue 4548 - CLI - dsconf needs better root DN access control plugin validation +- Issue 4506 - Temporary fix for io issues (#4516) +- Issue 4535 - lib389 - Fix log function in backends.py +- Issue 4534 - libasan read buffer overflow in filtercmp (#4541) +- Issue 4544 - Compiler warnings on krb5 functions (#4545) +- Update rpm.mk for RUST tarballs + * Mon Jan 25 2021 Fedora Release Engineering - 2.0.2-1.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild diff --git a/sources b/sources index f0a20b7..64df1ed 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ +SHA512 (389-ds-base-2.0.3.tar.bz2) = 48f0dcd7e4853646ea9bb38ec742f2b421b7bd6477d33070a8c97a764021ab7fa6fc005cb75ea87860b7b70998dc4df87790cf1c2bda3e6c0a9f08d39b00f6d2 SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 -SHA512 (389-ds-base-2.0.2.tar.bz2) = 42805311e45b2f3305f86da50d5a0128b19cd15aeb4787ccb67b5ceea9f7a7efe42076dff1d47d4d61012453405403c730c245d53431043eb05c125455938c37 From cbe869776a61ec919acb632b51525fefacd89f1e Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Fri, 19 Feb 2021 13:04:56 -0500 Subject: [PATCH 012/125] Bump version to 2.0.3-2 Revert Issue 4609 - CVE - info disclosure when authenticating(breaks DogTag) --- ...retrocl-backend-created-out-of-order.patch | 103 ------------- ...9-CVE-info-disclosure-when-authentic.patch | 143 ++++++++++++++++++ 389-ds-base.spec | 8 +- 3 files changed, 150 insertions(+), 104 deletions(-) delete mode 100644 0001-Issue-2526-retrocl-backend-created-out-of-order.patch create mode 100644 0001-Revert-Issue-4609-CVE-info-disclosure-when-authentic.patch diff --git a/0001-Issue-2526-retrocl-backend-created-out-of-order.patch b/0001-Issue-2526-retrocl-backend-created-out-of-order.patch deleted file mode 100644 index c6f7fed..0000000 --- a/0001-Issue-2526-retrocl-backend-created-out-of-order.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 67c8b8702a249cb0ef1ebf49b6e87056cd5339f6 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Tue, 27 Oct 2020 13:14:55 -0400 -Subject: [PATCH] Issue 2526 - retrocl backend created out of order - -Bug Description: A recent change verified that you do not create - a mappingtree entry before the backend entry was - created. The server created the retrocl backend - in the opposite order which broke the retrocl. - -Fix Description: Create the retrocl backend entry before creating - the mapping tree entry. - -Relates: https://github.com/389ds/389-ds-base/issues/2526 - -Reviewed by: viktor(Thanks!) ---- - ldap/servers/plugins/retrocl/retrocl.c | 10 ++--- - ldap/servers/plugins/retrocl/retrocl_create.c | 38 +++++++++---------- - 2 files changed, 22 insertions(+), 26 deletions(-) - -diff --git a/ldap/servers/plugins/retrocl/retrocl.c b/ldap/servers/plugins/retrocl/retrocl.c -index 4af4d752b..8d6135dad 100644 ---- a/ldap/servers/plugins/retrocl/retrocl.c -+++ b/ldap/servers/plugins/retrocl/retrocl.c -@@ -222,15 +222,11 @@ retrocl_select_backend(void) - slapi_entry_free(referral); - - if (err != LDAP_SUCCESS || be == NULL || be == defbackend_get_backend()) { -- slapi_log_err(SLAPI_LOG_ERR, RETROCL_PLUGIN_NAME, -+ /* Could not find the backend for cn=changelog, either because -+ * it doesn't exist mapping tree not registered. */ -+ slapi_log_err(SLAPI_LOG_PLUGIN, RETROCL_PLUGIN_NAME, - "retrocl_select_backend - Mapping tree select failed (%d) %s.\n", err, errbuf); -- -- /* could not find the backend for cn=changelog, either because -- * it doesn't exist -- * mapping tree not registered. -- */ - err = retrocl_create_config(); -- - if (err != LDAP_SUCCESS) - return err; - } else { -diff --git a/ldap/servers/plugins/retrocl/retrocl_create.c b/ldap/servers/plugins/retrocl/retrocl_create.c -index fb1503520..571e6899f 100644 ---- a/ldap/servers/plugins/retrocl/retrocl_create.c -+++ b/ldap/servers/plugins/retrocl/retrocl_create.c -@@ -192,6 +192,25 @@ retrocl_create_config(void) - vals[0] = &val; - vals[1] = NULL; - -+ retrocl_be_changelog = slapi_be_select_by_instance_name("changelog"); -+ -+ if (retrocl_be_changelog == NULL) { -+ /* This is not the nsslapd-changelogdir from cn=changelog4,cn=config */ -+ char *bedir; -+ -+ bedir = retrocl_get_config_str(CONFIG_CHANGELOG_DIRECTORY_ATTRIBUTE); -+ if (bedir == NULL) { -+ /* none specified */ -+ } -+ -+ rc = retrocl_create_be(bedir); -+ slapi_ch_free_string(&bedir); -+ if (rc != LDAP_SUCCESS && rc != LDAP_ALREADY_EXISTS) { -+ return rc; -+ } -+ retrocl_be_changelog = slapi_be_select_by_instance_name("changelog"); -+ } -+ - /* Assume the mapping tree node is missing. It doesn't hurt to - * attempt to add it if it already exists. You will see a warning - * in the errors file when the referenced backend does not exist. -@@ -256,25 +275,6 @@ retrocl_create_config(void) - return rc; - } - -- retrocl_be_changelog = slapi_be_select_by_instance_name("changelog"); -- -- if (retrocl_be_changelog == NULL) { -- /* This is not the nsslapd-changelogdir from cn=changelog4,cn=config */ -- char *bedir; -- -- bedir = retrocl_get_config_str(CONFIG_CHANGELOG_DIRECTORY_ATTRIBUTE); -- if (bedir == NULL) { -- /* none specified */ -- } -- -- rc = retrocl_create_be(bedir); -- slapi_ch_free_string(&bedir); -- if (rc != LDAP_SUCCESS && rc != LDAP_ALREADY_EXISTS) { -- return rc; -- } -- retrocl_be_changelog = slapi_be_select_by_instance_name("changelog"); -- } -- - return LDAP_SUCCESS; - } - --- -2.28.0 - diff --git a/0001-Revert-Issue-4609-CVE-info-disclosure-when-authentic.patch b/0001-Revert-Issue-4609-CVE-info-disclosure-when-authentic.patch new file mode 100644 index 0000000..437bddd --- /dev/null +++ b/0001-Revert-Issue-4609-CVE-info-disclosure-when-authentic.patch @@ -0,0 +1,143 @@ +From 9cb892cb2e36f62275257f3d43e938e2182c793c Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Fri, 19 Feb 2021 12:40:56 -0500 +Subject: [PATCH] Revert "Issue 4609 - CVE - info disclosure when + authenticating" + +This reverts commit b6aae4d8e7c8a6ddd21646f94fef1bf7f22c3f32. +--- + dirsrvtests/tests/suites/basic/basic_test.py | 51 ++++---------------- + ldap/servers/slapd/back-ldbm/ldbm_bind.c | 4 +- + ldap/servers/slapd/dse.c | 7 +-- + 3 files changed, 13 insertions(+), 49 deletions(-) + +diff --git a/dirsrvtests/tests/suites/basic/basic_test.py b/dirsrvtests/tests/suites/basic/basic_test.py +index a206bdb38..a43001ab6 100644 +--- a/dirsrvtests/tests/suites/basic/basic_test.py ++++ b/dirsrvtests/tests/suites/basic/basic_test.py +@@ -9,7 +9,7 @@ + + from subprocess import check_output, PIPE, run + from lib389 import DirSrv +-from lib389.idm.user import UserAccount, UserAccounts ++from lib389.idm.user import UserAccounts + import pytest + from lib389.tasks import * + from lib389.utils import * +@@ -1148,14 +1148,18 @@ def test_bind_invalid_entry(topology_st): + """Test the failing bind does not return information about the entry + + :id: 5cd9b083-eea6-426b-84ca-83c26fc49a6f ++ + :customerscenario: True ++ + :setup: Standalone instance ++ + :steps: +- 1: bind as non existing entry +- 2: check that bind info does not report 'No such entry' ++ 1: bind as non existing entry ++ 2: check that bind info does not report 'No such entry' ++ + :expectedresults: +- 1: pass +- 2: pass ++ 1: pass ++ 2: pass + """ + + topology_st.standalone.restart() +@@ -1177,43 +1181,6 @@ def test_bind_invalid_entry(topology_st): + topology_st.standalone.simple_bind_s(DN_DM, PW_DM) + + +-def test_bind_entry_missing_passwd(topology_st): +- """ +- :id: af209149-8fb8-48cb-93ea-3e82dd7119d2 +- :setup: Standalone Instance +- :steps: +- 1. Bind as database entry that does not have userpassword set +- 2. Bind as database entry that does not exist +- 1. Bind as cn=config entry that does not have userpassword set +- 2. Bind as cn=config entry that does not exist +- :expectedresults: +- 1. Fails with error 49 +- 2. Fails with error 49 +- 3. Fails with error 49 +- 4. Fails with error 49 +- """ +- user = UserAccount(topology_st.standalone, DEFAULT_SUFFIX) +- with pytest.raises(ldap.INVALID_CREDENTIALS): +- # Bind as the suffix root entry which does not have a userpassword +- user.bind("some_password") +- +- user = UserAccount(topology_st.standalone, "cn=not here," + DEFAULT_SUFFIX) +- with pytest.raises(ldap.INVALID_CREDENTIALS): +- # Bind as the entry which does not exist +- user.bind("some_password") +- +- # Test cn=config since it has its own code path +- user = UserAccount(topology_st.standalone, "cn=config") +- with pytest.raises(ldap.INVALID_CREDENTIALS): +- # Bind as the config entry which does not have a userpassword +- user.bind("some_password") +- +- user = UserAccount(topology_st.standalone, "cn=does not exist,cn=config") +- with pytest.raises(ldap.INVALID_CREDENTIALS): +- # Bind as an entry under cn=config that does not exist +- user.bind("some_password") +- +- + @pytest.mark.bz1044135 + @pytest.mark.ds47319 + def test_connection_buffer_size(topology_st): +diff --git a/ldap/servers/slapd/back-ldbm/ldbm_bind.c b/ldap/servers/slapd/back-ldbm/ldbm_bind.c +index 38d115a32..fa450ecd5 100644 +--- a/ldap/servers/slapd/back-ldbm/ldbm_bind.c ++++ b/ldap/servers/slapd/back-ldbm/ldbm_bind.c +@@ -76,8 +76,8 @@ ldbm_back_bind(Slapi_PBlock *pb) + case LDAP_AUTH_SIMPLE: { + Slapi_Value cv; + if (slapi_entry_attr_find(e->ep_entry, "userpassword", &attr) != 0) { +- slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Entry does not have userpassword set"); +- slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL); ++ slapi_send_ldap_result(pb, LDAP_INAPPROPRIATE_AUTH, NULL, ++ NULL, 0, NULL); + CACHE_RETURN(&inst->inst_cache, &e); + rc = SLAPI_BIND_FAIL; + goto bail; +diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c +index f2741aeb4..f5572d78d 100644 +--- a/ldap/servers/slapd/dse.c ++++ b/ldap/servers/slapd/dse.c +@@ -1446,8 +1446,7 @@ dse_bind(Slapi_PBlock *pb) /* JCM There should only be one exit point from this + + ec = dse_get_entry_copy(pdse, sdn, DSE_USE_LOCK); + if (ec == NULL) { +- slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Entry does not exist"); +- slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL); ++ slapi_send_ldap_result(pb, LDAP_NO_SUCH_OBJECT, NULL, NULL, 0, NULL); + return (SLAPI_BIND_FAIL); + } + +@@ -1455,8 +1454,7 @@ dse_bind(Slapi_PBlock *pb) /* JCM There should only be one exit point from this + case LDAP_AUTH_SIMPLE: { + Slapi_Value cv; + if (slapi_entry_attr_find(ec, "userpassword", &attr) != 0) { +- slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Entry does not have userpassword set"); +- slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL); ++ slapi_send_ldap_result(pb, LDAP_INAPPROPRIATE_AUTH, NULL, NULL, 0, NULL); + slapi_entry_free(ec); + return SLAPI_BIND_FAIL; + } +@@ -1464,7 +1462,6 @@ dse_bind(Slapi_PBlock *pb) /* JCM There should only be one exit point from this + + slapi_value_init_berval(&cv, cred); + if (slapi_pw_find_sv(bvals, &cv) != 0) { +- slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Invalid credentials"); + slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL); + slapi_entry_free(ec); + value_done(&cv); +-- +2.26.2 + diff --git a/389-ds-base.spec b/389-ds-base.spec index 73e901e..cb0b508 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,7 +47,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.0.3 -Release: %{?relprefix}1%{?prerel}%{?dist} +Release: %{?relprefix}2%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -170,6 +170,7 @@ Source2: %{name}-devel.README %if %{bundle_jemalloc} Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download/%{jemalloc_ver}/%{jemalloc_name}-%{jemalloc_ver}.tar.bz2 %endif +Patch01: 0001-Revert-Issue-4609-CVE-info-disclosure-when-authentic.patch %description 389 Directory Server is an LDAPv3 compliant server. The base package includes @@ -268,6 +269,7 @@ A cockpit UI Plugin for configuring and administering the 389 Directory Server %endif %prep +%autosetup -p1 -v -n %{name}-%{version}%{?prerel} %setup -q -n %{name}-%{version}%{?prerel} %if %{bundle_jemalloc} @@ -613,6 +615,10 @@ exit 0 %endif %changelog +* Fri Feb 19 2021 Mark Reynolds - 2.0.3-2 +- Bump version to 2.0.3-2 +- Revert Issue 4609 - CVE - info disclosure when authenticating(breaks DogTag) + * Fri Feb 12 2021 Mark Reynolds - 2.0.3-1 - Bump version to 2.0.3 - Issue 4619 - remove pytest requirement from lib389 From d593e73a4afaac15d2cd481e4215dadf82344518 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Fri, 26 Feb 2021 21:19:47 +0200 Subject: [PATCH 013/125] Remove a revert of the fix for Issue 4609 - CVE - info disclosure when authenticating(breaks Dogtag) - Dogtag has fixed own code that failed in the presence of the fix for Issue 4609 --- ...9-CVE-info-disclosure-when-authentic.patch | 143 ------------------ 389-ds-base.spec | 7 +- 2 files changed, 5 insertions(+), 145 deletions(-) delete mode 100644 0001-Revert-Issue-4609-CVE-info-disclosure-when-authentic.patch diff --git a/0001-Revert-Issue-4609-CVE-info-disclosure-when-authentic.patch b/0001-Revert-Issue-4609-CVE-info-disclosure-when-authentic.patch deleted file mode 100644 index 437bddd..0000000 --- a/0001-Revert-Issue-4609-CVE-info-disclosure-when-authentic.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 9cb892cb2e36f62275257f3d43e938e2182c793c Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Fri, 19 Feb 2021 12:40:56 -0500 -Subject: [PATCH] Revert "Issue 4609 - CVE - info disclosure when - authenticating" - -This reverts commit b6aae4d8e7c8a6ddd21646f94fef1bf7f22c3f32. ---- - dirsrvtests/tests/suites/basic/basic_test.py | 51 ++++---------------- - ldap/servers/slapd/back-ldbm/ldbm_bind.c | 4 +- - ldap/servers/slapd/dse.c | 7 +-- - 3 files changed, 13 insertions(+), 49 deletions(-) - -diff --git a/dirsrvtests/tests/suites/basic/basic_test.py b/dirsrvtests/tests/suites/basic/basic_test.py -index a206bdb38..a43001ab6 100644 ---- a/dirsrvtests/tests/suites/basic/basic_test.py -+++ b/dirsrvtests/tests/suites/basic/basic_test.py -@@ -9,7 +9,7 @@ - - from subprocess import check_output, PIPE, run - from lib389 import DirSrv --from lib389.idm.user import UserAccount, UserAccounts -+from lib389.idm.user import UserAccounts - import pytest - from lib389.tasks import * - from lib389.utils import * -@@ -1148,14 +1148,18 @@ def test_bind_invalid_entry(topology_st): - """Test the failing bind does not return information about the entry - - :id: 5cd9b083-eea6-426b-84ca-83c26fc49a6f -+ - :customerscenario: True -+ - :setup: Standalone instance -+ - :steps: -- 1: bind as non existing entry -- 2: check that bind info does not report 'No such entry' -+ 1: bind as non existing entry -+ 2: check that bind info does not report 'No such entry' -+ - :expectedresults: -- 1: pass -- 2: pass -+ 1: pass -+ 2: pass - """ - - topology_st.standalone.restart() -@@ -1177,43 +1181,6 @@ def test_bind_invalid_entry(topology_st): - topology_st.standalone.simple_bind_s(DN_DM, PW_DM) - - --def test_bind_entry_missing_passwd(topology_st): -- """ -- :id: af209149-8fb8-48cb-93ea-3e82dd7119d2 -- :setup: Standalone Instance -- :steps: -- 1. Bind as database entry that does not have userpassword set -- 2. Bind as database entry that does not exist -- 1. Bind as cn=config entry that does not have userpassword set -- 2. Bind as cn=config entry that does not exist -- :expectedresults: -- 1. Fails with error 49 -- 2. Fails with error 49 -- 3. Fails with error 49 -- 4. Fails with error 49 -- """ -- user = UserAccount(topology_st.standalone, DEFAULT_SUFFIX) -- with pytest.raises(ldap.INVALID_CREDENTIALS): -- # Bind as the suffix root entry which does not have a userpassword -- user.bind("some_password") -- -- user = UserAccount(topology_st.standalone, "cn=not here," + DEFAULT_SUFFIX) -- with pytest.raises(ldap.INVALID_CREDENTIALS): -- # Bind as the entry which does not exist -- user.bind("some_password") -- -- # Test cn=config since it has its own code path -- user = UserAccount(topology_st.standalone, "cn=config") -- with pytest.raises(ldap.INVALID_CREDENTIALS): -- # Bind as the config entry which does not have a userpassword -- user.bind("some_password") -- -- user = UserAccount(topology_st.standalone, "cn=does not exist,cn=config") -- with pytest.raises(ldap.INVALID_CREDENTIALS): -- # Bind as an entry under cn=config that does not exist -- user.bind("some_password") -- -- - @pytest.mark.bz1044135 - @pytest.mark.ds47319 - def test_connection_buffer_size(topology_st): -diff --git a/ldap/servers/slapd/back-ldbm/ldbm_bind.c b/ldap/servers/slapd/back-ldbm/ldbm_bind.c -index 38d115a32..fa450ecd5 100644 ---- a/ldap/servers/slapd/back-ldbm/ldbm_bind.c -+++ b/ldap/servers/slapd/back-ldbm/ldbm_bind.c -@@ -76,8 +76,8 @@ ldbm_back_bind(Slapi_PBlock *pb) - case LDAP_AUTH_SIMPLE: { - Slapi_Value cv; - if (slapi_entry_attr_find(e->ep_entry, "userpassword", &attr) != 0) { -- slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Entry does not have userpassword set"); -- slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL); -+ slapi_send_ldap_result(pb, LDAP_INAPPROPRIATE_AUTH, NULL, -+ NULL, 0, NULL); - CACHE_RETURN(&inst->inst_cache, &e); - rc = SLAPI_BIND_FAIL; - goto bail; -diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c -index f2741aeb4..f5572d78d 100644 ---- a/ldap/servers/slapd/dse.c -+++ b/ldap/servers/slapd/dse.c -@@ -1446,8 +1446,7 @@ dse_bind(Slapi_PBlock *pb) /* JCM There should only be one exit point from this - - ec = dse_get_entry_copy(pdse, sdn, DSE_USE_LOCK); - if (ec == NULL) { -- slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Entry does not exist"); -- slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL); -+ slapi_send_ldap_result(pb, LDAP_NO_SUCH_OBJECT, NULL, NULL, 0, NULL); - return (SLAPI_BIND_FAIL); - } - -@@ -1455,8 +1454,7 @@ dse_bind(Slapi_PBlock *pb) /* JCM There should only be one exit point from this - case LDAP_AUTH_SIMPLE: { - Slapi_Value cv; - if (slapi_entry_attr_find(ec, "userpassword", &attr) != 0) { -- slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Entry does not have userpassword set"); -- slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL); -+ slapi_send_ldap_result(pb, LDAP_INAPPROPRIATE_AUTH, NULL, NULL, 0, NULL); - slapi_entry_free(ec); - return SLAPI_BIND_FAIL; - } -@@ -1464,7 +1462,6 @@ dse_bind(Slapi_PBlock *pb) /* JCM There should only be one exit point from this - - slapi_value_init_berval(&cv, cred); - if (slapi_pw_find_sv(bvals, &cv) != 0) { -- slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Invalid credentials"); - slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL); - slapi_entry_free(ec); - value_done(&cv); --- -2.26.2 - diff --git a/389-ds-base.spec b/389-ds-base.spec index cb0b508..dcb2c1f 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,7 +47,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.0.3 -Release: %{?relprefix}2%{?prerel}%{?dist} +Release: %{?relprefix}3%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -170,7 +170,6 @@ Source2: %{name}-devel.README %if %{bundle_jemalloc} Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download/%{jemalloc_ver}/%{jemalloc_name}-%{jemalloc_ver}.tar.bz2 %endif -Patch01: 0001-Revert-Issue-4609-CVE-info-disclosure-when-authentic.patch %description 389 Directory Server is an LDAPv3 compliant server. The base package includes @@ -615,6 +614,10 @@ exit 0 %endif %changelog +* Fri Feb 26 2021 Alexander Bokovoy - 2.0.3-3 +- Remove a revert of the fix for Issue 4609 - CVE - info disclosure when authenticating(breaks Dogtag) +- Dogtag has fixed own code that failed in the presence of the fix for Issue 4609 + * Fri Feb 19 2021 Mark Reynolds - 2.0.3-2 - Bump version to 2.0.3-2 - Revert Issue 4609 - CVE - info disclosure when authenticating(breaks DogTag) From 94b5c174c15def530df06972159c193cf1cdf05c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 2 Mar 2021 16:14:14 +0100 Subject: [PATCH 014/125] Rebuilt for updated systemd-rpm-macros See https://pagure.io/fesco/issue/2583. --- 389-ds-base.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index dcb2c1f..c353fa7 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,7 +47,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.0.3 -Release: %{?relprefix}3%{?prerel}%{?dist} +Release: %{?relprefix}3%{?prerel}%{?dist}.1 License: GPLv3+ URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -614,6 +614,10 @@ exit 0 %endif %changelog +* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 2.0.3-3.1 +- Rebuilt for updated systemd-rpm-macros + See https://pagure.io/fesco/issue/2583. + * Fri Feb 26 2021 Alexander Bokovoy - 2.0.3-3 - Remove a revert of the fix for Issue 4609 - CVE - info disclosure when authenticating(breaks Dogtag) - Dogtag has fixed own code that failed in the presence of the fix for Issue 4609 From fa350ec502c7b670771ebb2f201f89e1e6fcc908 Mon Sep 17 00:00:00 2001 From: Thierry Bordaz Date: Thu, 8 Apr 2021 18:50:11 +0200 Subject: [PATCH 015/125] Bump version to 2.0.4 Issue 4680 - 389ds coredump (@389ds/389-ds-base-nightly) in replica install with CA (#4715) Issue 3965 - RFE - Implement the Password Policy attribute "pwdReset" (#4713) Issue 4700 - Regression in winsync replication agreement (#4712) Issue 3965 - RFE - Implement the Password Policy attribute "pwdReset" (#4710) Issue 4169 - UI - migrate monitor tables to PF4 issue 4585 - backend redesign phase 3c - dbregion test removal (#4665) Issue 2736 - remove remaining perl references Issue 2736 - https://github.com/389ds/389-ds-base/issues/2736 Issue 4706 - negative wtime in access log for CMP operations Issue 3585 - LDAP server returning controltype in different sequence Issue 4127 - With Accounts/Account module delete fuction is not working (#4697) Issue 4666 - BUG - cb_ping_farm can fail with anonymous binds disabled (#4669) Issue 4671 - UI - Fix browser crashes Issue 4169 - UI - Add PF4 charts for server stats Issue 4648 - Fix some issues and improvement around CI tests (#4651) Issue 4654 Updates to tickets/ticket48234_test.py (#4654) Issue 4229 - Fix Rust linking Issue 4673 - Update Rust crates Issue 4658 - monitor - connection start date is incorrect Issue 4169 - UI - migrate modals to PF4 Issue 4656 - remove problematic language from ds-replcheck Issue 4459 - lib389 - Default paths should use dse.ldif if the server is down Issue 4656 - Remove problematic language from UI/CLI/lib389 Issue 4661 - RFE - allow importing openldap schemas (#4662) Issue 4659 - restart after openldap migration to enable plugins (#4660) Merge pull request #4664 from mreynolds389/issue4663 issue 4552 - Backup Redesign phase 3b - use dbimpl in replicatin plugin (#4622) Issue 4643 - Add a tool that generates Rust dependencies for a specfile (#4645) Issue 4646 - CLI/UI - revise DNA plugin management Issue 4644 - Large updates can reset the CLcache to the beginning of the changelog (#4647) Issue 4649 - crash in sync_repl when a MODRDN create a cenotaph (#4652) Issue 4169 - UI - Migrate alerts to PF4 Issue 4169 - UI - Migrate Accordians to PF4 ExpandableSection Issue 4595 - Paged search lookthroughlimit bug (#4602) Issue 4169 - UI - port charts to PF4 Issue 2820 - Fix CI test suite issues Issue 4513 - CI - make acl ip address tests more robust --- .gitignore | 1 + 389-ds-base.spec | 44 ++++++++++++++++++++++++++++++++++++++++++-- sources | 2 +- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index b272f37..a06b6cf 100644 --- a/.gitignore +++ b/.gitignore @@ -201,3 +201,4 @@ /389-ds-base-2.0.1.tar.bz2 /389-ds-base-2.0.2.tar.bz2 /389-ds-base-2.0.3.tar.bz2 +/389-ds-base-2.0.4.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index c353fa7..9aa862b 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,8 +46,8 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.0.3 -Release: %{?relprefix}3%{?prerel}%{?dist}.1 +Version: 2.0.4 +Release: %{?relprefix}1%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -614,6 +614,46 @@ exit 0 %endif %changelog +* Thu Apr 08 2021 Thierry Bordaz - 2.0.4-1 +- Bump version to 2.0.4 +- Issue 4680 - 389ds coredump (@389ds/389-ds-base-nightly) in replica install with CA (#4715) +- Issue 3965 - RFE - Implement the Password Policy attribute "pwdReset" (#4713) +- Issue 4700 - Regression in winsync replication agreement (#4712) +- Issue 3965 - RFE - Implement the Password Policy attribute "pwdReset" (#4710) +- Issue 4169 - UI - migrate monitor tables to PF4 +- issue 4585 - backend redesign phase 3c - dbregion test removal (#4665) +- Issue 2736 - remove remaining perl references +- Issue 2736 - https://github.com/389ds/389-ds-base/issues/2736 +- Issue 4706 - negative wtime in access log for CMP operations +- Issue 3585 - LDAP server returning controltype in different sequence +- Issue 4127 - With Accounts/Account module delete fuction is not working (#4697) +- Issue 4666 - BUG - cb_ping_farm can fail with anonymous binds disabled (#4669) +- Issue 4671 - UI - Fix browser crashes +- Issue 4169 - UI - Add PF4 charts for server stats +- Issue 4648 - Fix some issues and improvement around CI tests (#4651) +- Issue 4654 Updates to tickets/ticket48234_test.py (#4654) +- Issue 4229 - Fix Rust linking +- Issue 4673 - Update Rust crates +- Issue 4658 - monitor - connection start date is incorrect +- Issue 4169 - UI - migrate modals to PF4 +- Issue 4656 - remove problematic language from ds-replcheck +- Issue 4459 - lib389 - Default paths should use dse.ldif if the server is down +- Issue 4656 - Remove problematic language from UI/CLI/lib389 +- Issue 4661 - RFE - allow importing openldap schemas (#4662) +- Issue 4659 - restart after openldap migration to enable plugins (#4660) +- Merge pull request #4664 from mreynolds389/issue4663 +- issue 4552 - Backup Redesign phase 3b - use dbimpl in replicatin plugin (#4622) +- Issue 4643 - Add a tool that generates Rust dependencies for a specfile (#4645) +- Issue 4646 - CLI/UI - revise DNA plugin management +- Issue 4644 - Large updates can reset the CLcache to the beginning of the changelog (#4647) +- Issue 4649 - crash in sync_repl when a MODRDN create a cenotaph (#4652) +- Issue 4169 - UI - Migrate alerts to PF4 +- Issue 4169 - UI - Migrate Accordians to PF4 ExpandableSection +- Issue 4595 - Paged search lookthroughlimit bug (#4602) +- Issue 4169 - UI - port charts to PF4 +- Issue 2820 - Fix CI test suite issues +- Issue 4513 - CI - make acl ip address tests more robust + * Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 2.0.3-3.1 - Rebuilt for updated systemd-rpm-macros See https://pagure.io/fesco/issue/2583. diff --git a/sources b/sources index 64df1ed..a7c9b26 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (389-ds-base-2.0.3.tar.bz2) = 48f0dcd7e4853646ea9bb38ec742f2b421b7bd6477d33070a8c97a764021ab7fa6fc005cb75ea87860b7b70998dc4df87790cf1c2bda3e6c0a9f08d39b00f6d2 SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 +SHA512 (389-ds-base-2.0.4.tar.bz2) = accf7bbcd36c2ff52cca6f4ab3a58b5842938766981ff321b03d2e6adaab9c328253bee5b57cd9f43d0f047aca50f9aea880508ae4ca5d836c65ba7dc67b142a From a04e9ff8f7b65bdb9d3f202cede183b305c0c82f Mon Sep 17 00:00:00 2001 From: Simon Pichugin Date: Fri, 9 Apr 2021 12:19:12 +0200 Subject: [PATCH 016/125] Add Rust bundled Provides and Update License --- 389-ds-base.spec | 97 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 2 deletions(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 9aa862b..304b65c 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,8 +47,8 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.0.4 -Release: %{?relprefix}1%{?prerel}%{?dist} -License: GPLv3+ +Release: %{?relprefix}1%{?prerel}%{?dist}.1 +License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (ASL 2.0 or Boost) and MPLv2.0 and ASL 2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and (Unlicense or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 Conflicts: freeipa-server < 4.0.3 @@ -57,6 +57,96 @@ Obsoletes: %{name}-legacy-tools < 1.4.4.6 Obsoletes: %{name}-legacy-tools-debuginfo < 1.4.4.6 Provides: ldif2ldbm >= 0 +##### Bundled cargo crates list - START ##### +Provides: bundled(crate(ahash)) = 0.7.2 +Provides: bundled(crate(ansi_term)) = 0.11.0 +Provides: bundled(crate(atty)) = 0.2.14 +Provides: bundled(crate(autocfg)) = 1.0.1 +Provides: bundled(crate(base64)) = 0.13.0 +Provides: bundled(crate(bitflags)) = 1.2.1 +Provides: bundled(crate(byteorder)) = 1.4.3 +Provides: bundled(crate(cbindgen)) = 0.9.1 +Provides: bundled(crate(cc)) = 1.0.67 +Provides: bundled(crate(cfg-if)) = 1.0.0 +Provides: bundled(crate(clap)) = 2.33.3 +Provides: bundled(crate(concread)) = 0.2.8 +Provides: bundled(crate(crossbeam)) = 0.8.0 +Provides: bundled(crate(crossbeam-channel)) = 0.5.0 +Provides: bundled(crate(crossbeam-deque)) = 0.8.0 +Provides: bundled(crate(crossbeam-epoch)) = 0.9.3 +Provides: bundled(crate(crossbeam-queue)) = 0.3.1 +Provides: bundled(crate(crossbeam-utils)) = 0.8.3 +Provides: bundled(crate(entryuuid)) = 0.1.0 +Provides: bundled(crate(entryuuid_syntax)) = 0.1.0 +Provides: bundled(crate(fernet)) = 0.1.4 +Provides: bundled(crate(foreign-types)) = 0.3.2 +Provides: bundled(crate(foreign-types-shared)) = 0.1.1 +Provides: bundled(crate(getrandom)) = 0.2.2 +Provides: bundled(crate(hermit-abi)) = 0.1.18 +Provides: bundled(crate(instant)) = 0.1.9 +Provides: bundled(crate(itoa)) = 0.4.7 +Provides: bundled(crate(jobserver)) = 0.1.21 +Provides: bundled(crate(lazy_static)) = 1.4.0 +Provides: bundled(crate(libc)) = 0.2.93 +Provides: bundled(crate(librnsslapd)) = 0.1.0 +Provides: bundled(crate(librslapd)) = 0.1.0 +Provides: bundled(crate(lock_api)) = 0.4.3 +Provides: bundled(crate(log)) = 0.4.14 +Provides: bundled(crate(memoffset)) = 0.6.3 +Provides: bundled(crate(num)) = 0.3.1 +Provides: bundled(crate(num-bigint)) = 0.3.2 +Provides: bundled(crate(num-complex)) = 0.3.1 +Provides: bundled(crate(num-integer)) = 0.1.44 +Provides: bundled(crate(num-iter)) = 0.1.42 +Provides: bundled(crate(num-rational)) = 0.3.2 +Provides: bundled(crate(num-traits)) = 0.2.14 +Provides: bundled(crate(once_cell)) = 1.7.2 +Provides: bundled(crate(openssl)) = 0.10.33 +Provides: bundled(crate(openssl-sys)) = 0.9.61 +Provides: bundled(crate(parking_lot)) = 0.11.1 +Provides: bundled(crate(parking_lot_core)) = 0.8.3 +Provides: bundled(crate(paste)) = 0.1.18 +Provides: bundled(crate(paste-impl)) = 0.1.18 +Provides: bundled(crate(pkg-config)) = 0.3.19 +Provides: bundled(crate(ppv-lite86)) = 0.2.10 +Provides: bundled(crate(proc-macro-hack)) = 0.5.19 +Provides: bundled(crate(proc-macro2)) = 1.0.26 +Provides: bundled(crate(pwdchan)) = 0.1.0 +Provides: bundled(crate(quote)) = 1.0.9 +Provides: bundled(crate(rand)) = 0.8.3 +Provides: bundled(crate(rand_chacha)) = 0.3.0 +Provides: bundled(crate(rand_core)) = 0.6.2 +Provides: bundled(crate(rand_hc)) = 0.3.0 +Provides: bundled(crate(redox_syscall)) = 0.2.5 +Provides: bundled(crate(remove_dir_all)) = 0.5.3 +Provides: bundled(crate(ryu)) = 1.0.5 +Provides: bundled(crate(scopeguard)) = 1.1.0 +Provides: bundled(crate(serde)) = 1.0.125 +Provides: bundled(crate(serde_derive)) = 1.0.125 +Provides: bundled(crate(serde_json)) = 1.0.64 +Provides: bundled(crate(slapd)) = 0.1.0 +Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 +Provides: bundled(crate(smallvec)) = 1.6.1 +Provides: bundled(crate(strsim)) = 0.8.0 +Provides: bundled(crate(syn)) = 1.0.68 +Provides: bundled(crate(synstructure)) = 0.12.4 +Provides: bundled(crate(tempfile)) = 3.2.0 +Provides: bundled(crate(textwrap)) = 0.11.0 +Provides: bundled(crate(toml)) = 0.5.8 +Provides: bundled(crate(unicode-width)) = 0.1.8 +Provides: bundled(crate(unicode-xid)) = 0.2.1 +Provides: bundled(crate(uuid)) = 0.8.2 +Provides: bundled(crate(vcpkg)) = 0.2.11 +Provides: bundled(crate(vec_map)) = 0.8.2 +Provides: bundled(crate(version_check)) = 0.9.3 +Provides: bundled(crate(wasi)) = 0.10.2+wasi_snapshot_preview1 +Provides: bundled(crate(winapi)) = 0.3.9 +Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 +Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 +Provides: bundled(crate(zeroize)) = 1.2.0 +Provides: bundled(crate(zeroize_derive)) = 1.0.1 +##### Bundled cargo crates list - END ##### + BuildRequires: nspr-devel BuildRequires: nss-devel >= 3.34 BuildRequires: openldap-devel @@ -614,6 +704,9 @@ exit 0 %endif %changelog +* Fri Apr 09 2021 Simon Pichugin - 2.0.4-1.1 +- Add Rust bundled Provides and Update License + * Thu Apr 08 2021 Thierry Bordaz - 2.0.4-1 - Bump version to 2.0.4 - Issue 4680 - 389ds coredump (@389ds/389-ds-base-nightly) in replica install with CA (#4715) From 0b0735d1325c103cd94bb856628f460793504c0b Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Fri, 7 May 2021 10:09:32 +0200 Subject: [PATCH 017/125] Fix NVR --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 304b65c..4331a47 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,7 +47,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.0.4 -Release: %{?relprefix}1%{?prerel}%{?dist}.1 +Release: %{?relprefix}2%{?prerel}%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (ASL 2.0 or Boost) and MPLv2.0 and ASL 2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and (Unlicense or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -704,6 +704,9 @@ exit 0 %endif %changelog +* Fri May 07 2021 Viktor Ashirov - 2.0.4-2 +- Rebuilt to fix NVR + * Fri Apr 09 2021 Simon Pichugin - 2.0.4-1.1 - Add Rust bundled Provides and Update License From cf285c29b10949685e7d9437c033a05856655f81 Mon Sep 17 00:00:00 2001 From: Thierry Bordaz Date: Wed, 19 May 2021 11:08:55 +0200 Subject: [PATCH 018/125] Bump version to 2.0.4.3 Issue 4765 - database suffix unexpectdly changed from .db to .db4 (#4766) --- .gitignore | 1 + 389-ds-base.spec | 52 ++++++++++++++++++++++++------------------------ sources | 2 +- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/.gitignore b/.gitignore index a06b6cf..f7e7083 100644 --- a/.gitignore +++ b/.gitignore @@ -202,3 +202,4 @@ /389-ds-base-2.0.2.tar.bz2 /389-ds-base-2.0.3.tar.bz2 /389-ds-base-2.0.4.tar.bz2 +/389-ds-base-2.0.4.3.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 4331a47..f1a8bb2 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,8 +47,8 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.0.4 -Release: %{?relprefix}2%{?prerel}%{?dist} -License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (ASL 2.0 or Boost) and MPLv2.0 and ASL 2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and (Unlicense or MIT) +Release: %{?relprefix}3%{?prerel}%{?dist} +License: GPLv3+ and MIT and (ASL 2.0 or MIT) and (ASL 2.0 or Boost) and MPLv2.0 and ASL 2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and (Unlicense or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 Conflicts: freeipa-server < 4.0.3 @@ -69,13 +69,13 @@ Provides: bundled(crate(cbindgen)) = 0.9.1 Provides: bundled(crate(cc)) = 1.0.67 Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 2.33.3 -Provides: bundled(crate(concread)) = 0.2.8 +Provides: bundled(crate(concread)) = 0.2.12 Provides: bundled(crate(crossbeam)) = 0.8.0 -Provides: bundled(crate(crossbeam-channel)) = 0.5.0 +Provides: bundled(crate(crossbeam-channel)) = 0.5.1 Provides: bundled(crate(crossbeam-deque)) = 0.8.0 -Provides: bundled(crate(crossbeam-epoch)) = 0.9.3 +Provides: bundled(crate(crossbeam-epoch)) = 0.9.4 Provides: bundled(crate(crossbeam-queue)) = 0.3.1 -Provides: bundled(crate(crossbeam-utils)) = 0.8.3 +Provides: bundled(crate(crossbeam-utils)) = 0.8.4 Provides: bundled(crate(entryuuid)) = 0.1.0 Provides: bundled(crate(entryuuid_syntax)) = 0.1.0 Provides: bundled(crate(fernet)) = 0.1.4 @@ -85,28 +85,22 @@ Provides: bundled(crate(getrandom)) = 0.2.2 Provides: bundled(crate(hermit-abi)) = 0.1.18 Provides: bundled(crate(instant)) = 0.1.9 Provides: bundled(crate(itoa)) = 0.4.7 -Provides: bundled(crate(jobserver)) = 0.1.21 +Provides: bundled(crate(jobserver)) = 0.1.22 Provides: bundled(crate(lazy_static)) = 1.4.0 -Provides: bundled(crate(libc)) = 0.2.93 +Provides: bundled(crate(libc)) = 0.2.94 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 -Provides: bundled(crate(lock_api)) = 0.4.3 +Provides: bundled(crate(lock_api)) = 0.4.4 Provides: bundled(crate(log)) = 0.4.14 Provides: bundled(crate(memoffset)) = 0.6.3 -Provides: bundled(crate(num)) = 0.3.1 -Provides: bundled(crate(num-bigint)) = 0.3.2 -Provides: bundled(crate(num-complex)) = 0.3.1 -Provides: bundled(crate(num-integer)) = 0.1.44 -Provides: bundled(crate(num-iter)) = 0.1.42 -Provides: bundled(crate(num-rational)) = 0.3.2 -Provides: bundled(crate(num-traits)) = 0.2.14 Provides: bundled(crate(once_cell)) = 1.7.2 -Provides: bundled(crate(openssl)) = 0.10.33 -Provides: bundled(crate(openssl-sys)) = 0.9.61 +Provides: bundled(crate(openssl)) = 0.10.34 +Provides: bundled(crate(openssl-sys)) = 0.9.63 Provides: bundled(crate(parking_lot)) = 0.11.1 Provides: bundled(crate(parking_lot_core)) = 0.8.3 Provides: bundled(crate(paste)) = 0.1.18 Provides: bundled(crate(paste-impl)) = 0.1.18 +Provides: bundled(crate(pin-project-lite)) = 0.2.6 Provides: bundled(crate(pkg-config)) = 0.3.19 Provides: bundled(crate(ppv-lite86)) = 0.2.10 Provides: bundled(crate(proc-macro-hack)) = 0.5.19 @@ -117,34 +111,36 @@ Provides: bundled(crate(rand)) = 0.8.3 Provides: bundled(crate(rand_chacha)) = 0.3.0 Provides: bundled(crate(rand_core)) = 0.6.2 Provides: bundled(crate(rand_hc)) = 0.3.0 -Provides: bundled(crate(redox_syscall)) = 0.2.5 +Provides: bundled(crate(redox_syscall)) = 0.2.8 Provides: bundled(crate(remove_dir_all)) = 0.5.3 Provides: bundled(crate(ryu)) = 1.0.5 Provides: bundled(crate(scopeguard)) = 1.1.0 -Provides: bundled(crate(serde)) = 1.0.125 -Provides: bundled(crate(serde_derive)) = 1.0.125 +Provides: bundled(crate(serde)) = 1.0.126 +Provides: bundled(crate(serde_derive)) = 1.0.126 Provides: bundled(crate(serde_json)) = 1.0.64 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 Provides: bundled(crate(smallvec)) = 1.6.1 Provides: bundled(crate(strsim)) = 0.8.0 -Provides: bundled(crate(syn)) = 1.0.68 +Provides: bundled(crate(syn)) = 1.0.72 Provides: bundled(crate(synstructure)) = 0.12.4 Provides: bundled(crate(tempfile)) = 3.2.0 Provides: bundled(crate(textwrap)) = 0.11.0 +Provides: bundled(crate(tokio)) = 1.6.0 +Provides: bundled(crate(tokio-macros)) = 1.2.0 Provides: bundled(crate(toml)) = 0.5.8 Provides: bundled(crate(unicode-width)) = 0.1.8 -Provides: bundled(crate(unicode-xid)) = 0.2.1 +Provides: bundled(crate(unicode-xid)) = 0.2.2 Provides: bundled(crate(uuid)) = 0.8.2 -Provides: bundled(crate(vcpkg)) = 0.2.11 +Provides: bundled(crate(vcpkg)) = 0.2.12 Provides: bundled(crate(vec_map)) = 0.8.2 Provides: bundled(crate(version_check)) = 0.9.3 Provides: bundled(crate(wasi)) = 0.10.2+wasi_snapshot_preview1 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 -Provides: bundled(crate(zeroize)) = 1.2.0 -Provides: bundled(crate(zeroize_derive)) = 1.0.1 +Provides: bundled(crate(zeroize)) = 1.3.0 +Provides: bundled(crate(zeroize_derive)) = 1.1.0 ##### Bundled cargo crates list - END ##### BuildRequires: nspr-devel @@ -704,6 +700,10 @@ exit 0 %endif %changelog +* Wed May 19 2021 Thierry Bordaz - 2.0.4-3 +- Bump version to 2.0.4.3 +- Issue 4765 - database suffix unexpectdly changed from .db to .db4 (#4766) + * Fri May 07 2021 Viktor Ashirov - 2.0.4-2 - Rebuilt to fix NVR diff --git a/sources b/sources index a7c9b26..145b639 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 -SHA512 (389-ds-base-2.0.4.tar.bz2) = accf7bbcd36c2ff52cca6f4ab3a58b5842938766981ff321b03d2e6adaab9c328253bee5b57cd9f43d0f047aca50f9aea880508ae4ca5d836c65ba7dc67b142a +SHA512 (389-ds-base-2.0.4.3.tar.bz2) = f7d4f3d9d6a74fd63c0267dd8d2d16e33890d02cb94148411d79f3ab3ff599fad7d8dc19adcab6edf9a29a966a2de76767eb184211eac787455e889cf14c5da3 From b8d7d0ed50f8532fdae81343d1f648c213d40fbd Mon Sep 17 00:00:00 2001 From: Thierry Bordaz Date: Wed, 19 May 2021 15:04:22 +0200 Subject: [PATCH 019/125] Issue 4765 - database suffix unexpectdly changed from .db to .db4 (#4766) --- ...-Issue-4765-database-suffix-on-2-0-4.patch | 182 ++++++++++++++++++ 389-ds-base.spec | 55 +++--- sources | 2 +- 3 files changed, 212 insertions(+), 27 deletions(-) create mode 100644 0000-Issue-4765-database-suffix-on-2-0-4.patch diff --git a/0000-Issue-4765-database-suffix-on-2-0-4.patch b/0000-Issue-4765-database-suffix-on-2-0-4.patch new file mode 100644 index 0000000..19f3c10 --- /dev/null +++ b/0000-Issue-4765-database-suffix-on-2-0-4.patch @@ -0,0 +1,182 @@ +From bbdf47a9252040a5e42e015cb636380b88e9caa8 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Tue, 18 May 2021 19:16:30 +0200 +Subject: [PATCH] Issue 4765 - database suffix unexpectdly changed from .db to + .db4 (#4766) + +* Issue 4765 - database suffix unexpectdly changed from .db to .db4 + +* Issue 4765 - database suffix unexpectdly changed from .db to .db4 - fix some compilation warnings +--- + ldap/servers/slapd/back-ldbm/back-ldbm.h | 9 --------- + ldap/servers/slapd/back-ldbm/db-bdb/bdb_config.c | 1 + + ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c | 5 +++++ + ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h | 11 +++++++++++ + ldap/servers/slapd/back-ldbm/dblayer.c | 9 +++++++++ + ldap/servers/slapd/back-ldbm/dblayer.h | 3 +++ + ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 2 ++ + ldap/servers/slapd/back-ldbm/vlv_srch.c | 2 +- + 8 files changed, 32 insertions(+), 10 deletions(-) + +diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h +index ddac99541..50b0996cb 100644 +--- a/ldap/servers/slapd/back-ldbm/back-ldbm.h ++++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h +@@ -66,14 +66,6 @@ typedef unsigned short u_int16_t; + + #define ID2ENTRY "id2entry" /* main db file name: ID2ENTRY+LDBM_SUFFIX */ + +-#if 1000 * DB_VERSION_MAJOR + 100 * DB_VERSION_MINOR >= 5000 +-#define LDBM_SUFFIX_OLD ".db4" +-#define LDBM_SUFFIX ".db" +-#else +-#define LDBM_SUFFIX_OLD ".db3" +-#define LDBM_SUFFIX ".db4" +-#endif +- + #define MEGABYTE (1024 * 1024) + #define GIGABYTE (1024 * MEGABYTE) + +@@ -143,7 +135,6 @@ typedef unsigned short u_int16_t; + #define LDBM_VERSION_40 "Netscape-ldbm/4.0" + #define LDBM_VERSION_30 "Netscape-ldbm/3.0" + #define LDBM_VERSION_31 "Netscape-ldbm/3.1" +-#define LDBM_FILENAME_SUFFIX LDBM_SUFFIX + #define DBVERSION_FILENAME "DBVERSION" + /* 0 here means to let the autotuning reset the value on first run */ + /* cache can't get any smaller than this (in bytes) */ +diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_config.c b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_config.c +index 65a2405d8..11a65e806 100644 +--- a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_config.c ++++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_config.c +@@ -125,6 +125,7 @@ int bdb_init(struct ldbminfo *li, config_info *config_array) + priv->dblayer_dbi_txn_abort_fn = &bdb_dbi_txn_abort; + priv->dblayer_get_entries_count_fn = &bdb_get_entries_count; + priv->dblayer_cursor_get_count_fn = &bdb_public_cursor_get_count; ++ priv->dblayer_get_db_suffix_fn = &bdb_public_get_db_suffix; + + bdb_fake_priv = *priv; /* Copy the callbaks for bdb_be() */ + return 0; +diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c +index 186c11cc3..455596a92 100644 +--- a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c ++++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c +@@ -6713,3 +6713,8 @@ bdb_public_cursor_get_count(dbi_cursor_t *cursor, dbi_recno_t *count) + int rc = cur->c_count(cur, count, 0); + return bdb_map_error(__FUNCTION__, rc); + } ++ ++const char *bdb_public_get_db_suffix(void) ++{ ++ return LDBM_FILENAME_SUFFIX; ++} +diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h +index 32430e2af..924656998 100644 +--- a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h ++++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h +@@ -13,6 +13,16 @@ + + #define BDB_CONFIG(li) ((bdb_config *)(li)->li_dblayer_config) + ++#if 1000 * DB_VERSION_MAJOR + 100 * DB_VERSION_MINOR >= 5000 ++#define LDBM_SUFFIX_OLD ".db4" ++#define LDBM_SUFFIX ".db" ++#else ++#define LDBM_SUFFIX_OLD ".db3" ++#define LDBM_SUFFIX ".db4" ++#endif ++ ++#define LDBM_FILENAME_SUFFIX LDBM_SUFFIX ++ + typedef struct bdb_db_env + { + DB_ENV *bdb_DB_ENV; +@@ -133,6 +143,7 @@ dblayer_dbi_txn_commit_fn_t bdb_dbi_txn_commit; + dblayer_dbi_txn_abort_fn_t bdb_dbi_txn_abort; + dblayer_get_entries_count_fn_t bdb_get_entries_count; + dblayer_cursor_get_count_fn_t bdb_public_cursor_get_count; ++dblayer_get_db_suffix_fn_t bdb_public_get_db_suffix; + + /* instance functions */ + int bdb_instance_cleanup(struct ldbm_instance *inst); +diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c +index c5ff6cba9..bf56df42a 100644 +--- a/ldap/servers/slapd/back-ldbm/dblayer.c ++++ b/ldap/servers/slapd/back-ldbm/dblayer.c +@@ -1370,3 +1370,12 @@ dblayer_pop_pvt_txn(void) + } + return; + } ++ ++const char * ++dblayer_get_db_suffix(Slapi_Backend *be) ++{ ++ struct ldbminfo *li = be ? (struct ldbminfo *)be->be_database->plg_private : NULL; ++ dblayer_private *prv = li ? (dblayer_private *)li->li_dblayer_private : NULL; ++ ++ return prv ? prv->dblayer_get_db_suffix_fn() : NULL; ++} +diff --git a/ldap/servers/slapd/back-ldbm/dblayer.h b/ldap/servers/slapd/back-ldbm/dblayer.h +index 99acfd1ab..051035f3f 100644 +--- a/ldap/servers/slapd/back-ldbm/dblayer.h ++++ b/ldap/servers/slapd/back-ldbm/dblayer.h +@@ -109,6 +109,7 @@ typedef int dblayer_dbi_txn_commit_fn_t(dbi_txn_t *txn); + typedef int dblayer_dbi_txn_abort_fn_t(dbi_txn_t *txn); + typedef int dblayer_get_entries_count_fn_t(dbi_db_t *db, int *count); + typedef int dblayer_cursor_get_count_fn_t(dbi_cursor_t *cursor, dbi_recno_t *count); ++typedef const char *dblayer_get_db_suffix_fn_t(void); + + struct dblayer_private + { +@@ -178,6 +179,7 @@ struct dblayer_private + dblayer_dbi_txn_abort_fn_t *dblayer_dbi_txn_abort_fn; + dblayer_get_entries_count_fn_t *dblayer_get_entries_count_fn; + dblayer_cursor_get_count_fn_t *dblayer_cursor_get_count_fn; ++ dblayer_get_db_suffix_fn_t *dblayer_get_db_suffix_fn; + }; + + #define DBLAYER_PRIV_SET_DATA_DIR 0x1 +@@ -188,6 +190,7 @@ back_txn *dblayer_get_pvt_txn(void); + void dblayer_pop_pvt_txn(void); + + int dblayer_delete_indices(ldbm_instance *inst); ++const char *dblayer_get_db_suffix(Slapi_Backend *be); + + + /* Return the last four characters of a string; used for comparing extensions. */ +diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h +index 22f2d1103..dbe5dca73 100644 +--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h ++++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h +@@ -142,6 +142,8 @@ void dblayer_restore_file_update(struct ldbminfo *li, char *directory); + int dblayer_import_file_init(ldbm_instance *inst); + void dblayer_import_file_update(ldbm_instance *inst); + int dblayer_import_file_check(ldbm_instance *inst); ++const char *dblayer_get_db_suffix(Slapi_Backend *be); ++ + + /* + * dn2entry.c +diff --git a/ldap/servers/slapd/back-ldbm/vlv_srch.c b/ldap/servers/slapd/back-ldbm/vlv_srch.c +index 4dd3804c9..6fd1b3880 100644 +--- a/ldap/servers/slapd/back-ldbm/vlv_srch.c ++++ b/ldap/servers/slapd/back-ldbm/vlv_srch.c +@@ -30,7 +30,6 @@ char *const type_vlvEnabled = "vlvEnabled"; + char *const type_vlvUses = "vlvUses"; + + static const char *file_prefix = "vlv#"; /* '#' used to avoid collision with real attributes */ +-static const char *file_suffix = LDBM_FILENAME_SUFFIX; + + static int vlvIndex_createfilename(struct vlvIndex *pIndex, char **ppc); + +@@ -514,6 +513,7 @@ void + vlvIndex_init(struct vlvIndex *p, backend *be, struct vlvSearch *pSearch, const Slapi_Entry *e) + { + struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private; ++ const char *file_suffix = dblayer_get_db_suffix(be); + char *filename = NULL; + + if (NULL == p) +-- +2.30.2 + diff --git a/389-ds-base.spec b/389-ds-base.spec index f1a8bb2..5a791ca 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -62,6 +62,7 @@ Provides: bundled(crate(ahash)) = 0.7.2 Provides: bundled(crate(ansi_term)) = 0.11.0 Provides: bundled(crate(atty)) = 0.2.14 Provides: bundled(crate(autocfg)) = 1.0.1 +Provides: bundled(crate(base64)) = 0.10.1 Provides: bundled(crate(base64)) = 0.13.0 Provides: bundled(crate(bitflags)) = 1.2.1 Provides: bundled(crate(byteorder)) = 1.4.3 @@ -69,78 +70,81 @@ Provides: bundled(crate(cbindgen)) = 0.9.1 Provides: bundled(crate(cc)) = 1.0.67 Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 2.33.3 -Provides: bundled(crate(concread)) = 0.2.12 +Provides: bundled(crate(concread)) = 0.2.8 Provides: bundled(crate(crossbeam)) = 0.8.0 -Provides: bundled(crate(crossbeam-channel)) = 0.5.1 +Provides: bundled(crate(crossbeam-channel)) = 0.5.0 Provides: bundled(crate(crossbeam-deque)) = 0.8.0 -Provides: bundled(crate(crossbeam-epoch)) = 0.9.4 +Provides: bundled(crate(crossbeam-epoch)) = 0.9.3 Provides: bundled(crate(crossbeam-queue)) = 0.3.1 -Provides: bundled(crate(crossbeam-utils)) = 0.8.4 +Provides: bundled(crate(crossbeam-utils)) = 0.8.3 Provides: bundled(crate(entryuuid)) = 0.1.0 Provides: bundled(crate(entryuuid_syntax)) = 0.1.0 -Provides: bundled(crate(fernet)) = 0.1.4 +Provides: bundled(crate(fernet)) = 0.1.3 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 +Provides: bundled(crate(getrandom)) = 0.1.16 Provides: bundled(crate(getrandom)) = 0.2.2 Provides: bundled(crate(hermit-abi)) = 0.1.18 Provides: bundled(crate(instant)) = 0.1.9 Provides: bundled(crate(itoa)) = 0.4.7 -Provides: bundled(crate(jobserver)) = 0.1.22 +Provides: bundled(crate(jobserver)) = 0.1.21 Provides: bundled(crate(lazy_static)) = 1.4.0 -Provides: bundled(crate(libc)) = 0.2.94 +Provides: bundled(crate(libc)) = 0.2.89 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 -Provides: bundled(crate(lock_api)) = 0.4.4 +Provides: bundled(crate(lock_api)) = 0.4.2 Provides: bundled(crate(log)) = 0.4.14 -Provides: bundled(crate(memoffset)) = 0.6.3 +Provides: bundled(crate(memoffset)) = 0.6.1 +Provides: bundled(crate(num)) = 0.3.1 +Provides: bundled(crate(num-bigint)) = 0.3.2 +Provides: bundled(crate(num-complex)) = 0.3.1 +Provides: bundled(crate(num-integer)) = 0.1.44 +Provides: bundled(crate(num-iter)) = 0.1.42 +Provides: bundled(crate(num-rational)) = 0.3.2 +Provides: bundled(crate(num-traits)) = 0.2.14 Provides: bundled(crate(once_cell)) = 1.7.2 -Provides: bundled(crate(openssl)) = 0.10.34 -Provides: bundled(crate(openssl-sys)) = 0.9.63 +Provides: bundled(crate(openssl)) = 0.10.33 +Provides: bundled(crate(openssl-sys)) = 0.9.61 Provides: bundled(crate(parking_lot)) = 0.11.1 Provides: bundled(crate(parking_lot_core)) = 0.8.3 Provides: bundled(crate(paste)) = 0.1.18 Provides: bundled(crate(paste-impl)) = 0.1.18 -Provides: bundled(crate(pin-project-lite)) = 0.2.6 Provides: bundled(crate(pkg-config)) = 0.3.19 Provides: bundled(crate(ppv-lite86)) = 0.2.10 Provides: bundled(crate(proc-macro-hack)) = 0.5.19 -Provides: bundled(crate(proc-macro2)) = 1.0.26 +Provides: bundled(crate(proc-macro2)) = 1.0.24 Provides: bundled(crate(pwdchan)) = 0.1.0 Provides: bundled(crate(quote)) = 1.0.9 Provides: bundled(crate(rand)) = 0.8.3 Provides: bundled(crate(rand_chacha)) = 0.3.0 Provides: bundled(crate(rand_core)) = 0.6.2 Provides: bundled(crate(rand_hc)) = 0.3.0 -Provides: bundled(crate(redox_syscall)) = 0.2.8 +Provides: bundled(crate(redox_syscall)) = 0.2.5 Provides: bundled(crate(remove_dir_all)) = 0.5.3 Provides: bundled(crate(ryu)) = 1.0.5 Provides: bundled(crate(scopeguard)) = 1.1.0 -Provides: bundled(crate(serde)) = 1.0.126 -Provides: bundled(crate(serde_derive)) = 1.0.126 +Provides: bundled(crate(serde)) = 1.0.124 +Provides: bundled(crate(serde_derive)) = 1.0.124 Provides: bundled(crate(serde_json)) = 1.0.64 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 Provides: bundled(crate(smallvec)) = 1.6.1 Provides: bundled(crate(strsim)) = 0.8.0 -Provides: bundled(crate(syn)) = 1.0.72 -Provides: bundled(crate(synstructure)) = 0.12.4 +Provides: bundled(crate(syn)) = 1.0.64 Provides: bundled(crate(tempfile)) = 3.2.0 Provides: bundled(crate(textwrap)) = 0.11.0 -Provides: bundled(crate(tokio)) = 1.6.0 -Provides: bundled(crate(tokio-macros)) = 1.2.0 Provides: bundled(crate(toml)) = 0.5.8 Provides: bundled(crate(unicode-width)) = 0.1.8 -Provides: bundled(crate(unicode-xid)) = 0.2.2 +Provides: bundled(crate(unicode-xid)) = 0.2.1 Provides: bundled(crate(uuid)) = 0.8.2 -Provides: bundled(crate(vcpkg)) = 0.2.12 +Provides: bundled(crate(vcpkg)) = 0.2.11 Provides: bundled(crate(vec_map)) = 0.8.2 Provides: bundled(crate(version_check)) = 0.9.3 Provides: bundled(crate(wasi)) = 0.10.2+wasi_snapshot_preview1 +Provides: bundled(crate(wasi)) = 0.9.0+wasi_snapshot_preview1 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 -Provides: bundled(crate(zeroize)) = 1.3.0 -Provides: bundled(crate(zeroize_derive)) = 1.1.0 ##### Bundled cargo crates list - END ##### BuildRequires: nspr-devel @@ -250,6 +254,7 @@ Requires: perl-Archive-Tar Obsoletes: %{name} <= 1.3.5.4 Source0: https://releases.pagure.org/389-ds-base/%{name}-%{version}%{?prerel}.tar.bz2 +Patch0: 0000-Issue-4765-database-suffix-on-2-0-4.patch # 389-ds-git.sh should be used to generate the source tarball from git Source1: %{name}-git.sh Source2: %{name}-devel.README @@ -355,7 +360,6 @@ A cockpit UI Plugin for configuring and administering the 389 Directory Server %prep %autosetup -p1 -v -n %{name}-%{version}%{?prerel} -%setup -q -n %{name}-%{version}%{?prerel} %if %{bundle_jemalloc} %setup -q -n %{name}-%{version}%{?prerel} -T -D -b 3 @@ -701,7 +705,6 @@ exit 0 %changelog * Wed May 19 2021 Thierry Bordaz - 2.0.4-3 -- Bump version to 2.0.4.3 - Issue 4765 - database suffix unexpectdly changed from .db to .db4 (#4766) * Fri May 07 2021 Viktor Ashirov - 2.0.4-2 diff --git a/sources b/sources index 145b639..a7c9b26 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 -SHA512 (389-ds-base-2.0.4.3.tar.bz2) = f7d4f3d9d6a74fd63c0267dd8d2d16e33890d02cb94148411d79f3ab3ff599fad7d8dc19adcab6edf9a29a966a2de76767eb184211eac787455e889cf14c5da3 +SHA512 (389-ds-base-2.0.4.tar.bz2) = accf7bbcd36c2ff52cca6f4ab3a58b5842938766981ff321b03d2e6adaab9c328253bee5b57cd9f43d0f047aca50f9aea880508ae4ca5d836c65ba7dc67b142a From b7bca6f86ee5d95562f61d37cc5367ddcb1cb6a3 Mon Sep 17 00:00:00 2001 From: Pete Walter Date: Wed, 19 May 2021 16:43:41 +0100 Subject: [PATCH 020/125] Rebuild for ICU 69 --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 5a791ca..b645421 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,7 +47,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.0.4 -Release: %{?relprefix}3%{?prerel}%{?dist} +Release: %{?relprefix}3%{?prerel}%{?dist}.1 License: GPLv3+ and MIT and (ASL 2.0 or MIT) and (ASL 2.0 or Boost) and MPLv2.0 and ASL 2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and (Unlicense or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -704,6 +704,9 @@ exit 0 %endif %changelog +* Wed May 19 2021 Pete Walter - 2.0.4-3.1 +- Rebuild for ICU 69 + * Wed May 19 2021 Thierry Bordaz - 2.0.4-3 - Issue 4765 - database suffix unexpectdly changed from .db to .db4 (#4766) From 7f1440cb1e9d3e60a8e016cbb6576bd84247f0af Mon Sep 17 00:00:00 2001 From: Pete Walter Date: Thu, 20 May 2021 00:52:28 +0100 Subject: [PATCH 021/125] Rebuild for ICU 69 --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index b645421..4521777 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,7 +47,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.0.4 -Release: %{?relprefix}3%{?prerel}%{?dist}.1 +Release: %{?relprefix}3%{?prerel}%{?dist}.2 License: GPLv3+ and MIT and (ASL 2.0 or MIT) and (ASL 2.0 or Boost) and MPLv2.0 and ASL 2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and (Unlicense or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -704,6 +704,9 @@ exit 0 %endif %changelog +* Wed May 19 2021 Pete Walter - 2.0.4-3.2 +- Rebuild for ICU 69 + * Wed May 19 2021 Pete Walter - 2.0.4-3.1 - Rebuild for ICU 69 From 7a744575fa57a6b18c4742879dcd3dcb92bff18d Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Thu, 20 May 2021 15:31:42 +0200 Subject: [PATCH 022/125] Enable interval feature of DNA plugin (resolves: rhbz#1962671) --- 0001-dna_enable_interval.patch | 20 ++++++++++++++++++++ 389-ds-base.spec | 6 +++++- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 0001-dna_enable_interval.patch diff --git a/0001-dna_enable_interval.patch b/0001-dna_enable_interval.patch new file mode 100644 index 0000000..5bef2ee --- /dev/null +++ b/0001-dna_enable_interval.patch @@ -0,0 +1,20 @@ +diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c +index bf6b74a99..928a3f54a 100644 +--- a/ldap/servers/plugins/dna/dna.c ++++ b/ldap/servers/plugins/dna/dna.c +@@ -1023,7 +1023,6 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry *e, int apply) + /* Set the default interval to 1 */ + entry->interval = 1; + +-#ifdef DNA_ENABLE_INTERVAL + value = slapi_entry_attr_get_charptr(e, DNA_INTERVAL); + if (value) { + entry->interval = strtoull(value, 0, 0); +@@ -1032,7 +1031,6 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry *e, int apply) + + slapi_log_err(SLAPI_LOG_CONFIG, DNA_PLUGIN_SUBSYSTEM, + "dna_parse_config_entry - %s [%" PRIu64 "]\n", DNA_INTERVAL, entry->interval); +-#endif + + value = slapi_entry_attr_get_charptr(e, DNA_GENERATE); + if (value) { diff --git a/389-ds-base.spec b/389-ds-base.spec index 4521777..6eba10f 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,7 +47,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.0.4 -Release: %{?relprefix}3%{?prerel}%{?dist}.2 +Release: %{?relprefix}4%{?prerel}%{?dist} License: GPLv3+ and MIT and (ASL 2.0 or MIT) and (ASL 2.0 or Boost) and MPLv2.0 and ASL 2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and (Unlicense or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -255,6 +255,7 @@ Obsoletes: %{name} <= 1.3.5.4 Source0: https://releases.pagure.org/389-ds-base/%{name}-%{version}%{?prerel}.tar.bz2 Patch0: 0000-Issue-4765-database-suffix-on-2-0-4.patch +Patch1: 0001-dna_enable_interval.patch # 389-ds-git.sh should be used to generate the source tarball from git Source1: %{name}-git.sh Source2: %{name}-devel.README @@ -704,6 +705,9 @@ exit 0 %endif %changelog +* Thu May 20 2021 Christian Heimes - 2.0.4-4 +- Enable interval feature of DNA plugin (resolves: rhbz#1962671) + * Wed May 19 2021 Pete Walter - 2.0.4-3.2 - Rebuild for ICU 69 From 4b440cd4f3436491d2ef8708def2bbf2fd7aa429 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Sun, 30 May 2021 10:14:25 -0400 Subject: [PATCH 023/125] Bump version to 2.0.5 Issue 4778 - RFE - Allow setting TOD for db compaction and add task Issue 4169 - UI - Port plugin tables to PF4 Issue 4656 - Allow backward compatilbity for replication plugin name change Issue 4764 - replicated operation sometime checks ACI (#4783) Issue 2820 - Fix CI test suite issues Issue 4781 - There are some typos in man-pages Issue 4773 - Enable interval feature of DNA plugin Issue 4623 - RFE - Monitor the current DB locks (#4762) Issue 3555 - Fix UI audit issue Issue 4725 - Fix compiler warnings Issue 4770 - Lower FIPS logging severity Issue 4765 - database suffix unexpectdly changed from .db to .db4 (#4766) Issue 4725 - [RFE] DS - Update the password policy to support a Temporary Password Rules (#4727) Issue 4747 - Remove unstable/unstatus tests from PRCI (#4748) Issue 4759 - Fix coverity issue (#4760) Issue 4169 - UI - Migrate Buttons to PF4 (#4745) Issue 4714 - dscontainer fails with rootless podman Issue 4750 - Fix compiler warning in retrocl (#4751) Issue 4742 - UI - should always use LDAPI path when calling CLI Issue 4169 - UI - Migrate Server, Security, and Schema tables to PF4 Issue 4667 - incorrect accounting of readers in vattr rwlock (#4732) Issue 4701 - RFE - Exclude attributes from retro changelog (#4723) Issue 4740 - Fix CI lib389 userPwdPolicy and subtreePwdPolicy (#4741) Issue 4711 - SIGSEV with sync_repl (#4738) Issue 4734 - import of entry with no parent warning (#4735) Issue 4729 - GitHub Actions fails to run pytest tests Issue 4656 - Remove problematic language from source code Issue 4632 - dscontainer: SyntaxWarning: "is" with a literal. Issue 4169 - UI - migrate replication tables to PF4 Issue 4637 - ndn cache leak (#4724) Issue 4577 - Fix ASAN flags in specfile Issue 4169 - UI - PF4 migration - database tables issue 4653 - refactor ldbm backend to allow replacement of BDB - phase 3e - dbscan (#4709) --- .gitignore | 1 + 389-ds-base.spec | 42 ++++++++++++++++++++++++++++++++++++++---- sources | 2 +- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index f7e7083..cb4664f 100644 --- a/.gitignore +++ b/.gitignore @@ -203,3 +203,4 @@ /389-ds-base-2.0.3.tar.bz2 /389-ds-base-2.0.4.tar.bz2 /389-ds-base-2.0.4.3.tar.bz2 +/389-ds-base-2.0.5.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 6eba10f..4e3e128 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,8 +46,8 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.0.4 -Release: %{?relprefix}4%{?prerel}%{?dist} +Version: 2.0.5 +Release: %{?relprefix}1%{?prerel}%{?dist} License: GPLv3+ and MIT and (ASL 2.0 or MIT) and (ASL 2.0 or Boost) and MPLv2.0 and ASL 2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and (Unlicense or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -254,8 +254,6 @@ Requires: perl-Archive-Tar Obsoletes: %{name} <= 1.3.5.4 Source0: https://releases.pagure.org/389-ds-base/%{name}-%{version}%{?prerel}.tar.bz2 -Patch0: 0000-Issue-4765-database-suffix-on-2-0-4.patch -Patch1: 0001-dna_enable_interval.patch # 389-ds-git.sh should be used to generate the source tarball from git Source1: %{name}-git.sh Source2: %{name}-devel.README @@ -705,6 +703,42 @@ exit 0 %endif %changelog +* Sun May 30 2021 Mark Reynolds - 2.0.5-1 +- Bump version to 2.0.5 +- Issue 4778 - RFE - Allow setting TOD for db compaction and add task +- Issue 4169 - UI - Port plugin tables to PF4 +- Issue 4656 - Allow backward compatilbity for replication plugin name change +- Issue 4764 - replicated operation sometime checks ACI (#4783) +- Issue 2820 - Fix CI test suite issues +- Issue 4781 - There are some typos in man-pages +- Issue 4773 - Enable interval feature of DNA plugin +- Issue 4623 - RFE - Monitor the current DB locks (#4762) +- Issue 3555 - Fix UI audit issue +- Issue 4725 - Fix compiler warnings +- Issue 4770 - Lower FIPS logging severity +- Issue 4765 - database suffix unexpectdly changed from .db to .db4 (#4766) +- Issue 4725 - [RFE] DS - Update the password policy to support a Temporary Password Rules (#4727) +- Issue 4747 - Remove unstable/unstatus tests from PRCI (#4748) +- Issue 4759 - Fix coverity issue (#4760) +- Issue 4169 - UI - Migrate Buttons to PF4 (#4745) +- Issue 4714 - dscontainer fails with rootless podman +- Issue 4750 - Fix compiler warning in retrocl (#4751) +- Issue 4742 - UI - should always use LDAPI path when calling CLI +- Issue 4169 - UI - Migrate Server, Security, and Schema tables to PF4 +- Issue 4667 - incorrect accounting of readers in vattr rwlock (#4732) +- Issue 4701 - RFE - Exclude attributes from retro changelog (#4723) +- Issue 4740 - Fix CI lib389 userPwdPolicy and subtreePwdPolicy (#4741) +- Issue 4711 - SIGSEV with sync_repl (#4738) +- Issue 4734 - import of entry with no parent warning (#4735) +- Issue 4729 - GitHub Actions fails to run pytest tests +- Issue 4656 - Remove problematic language from source code +- Issue 4632 - dscontainer: SyntaxWarning: "is" with a literal. +- Issue 4169 - UI - migrate replication tables to PF4 +- Issue 4637 - ndn cache leak (#4724) +- Issue 4577 - Fix ASAN flags in specfile +- Issue 4169 - UI - PF4 migration - database tables +- issue 4653 - refactor ldbm backend to allow replacement of BDB - phase 3e - dbscan (#4709) + * Thu May 20 2021 Christian Heimes - 2.0.4-4 - Enable interval feature of DNA plugin (resolves: rhbz#1962671) diff --git a/sources b/sources index a7c9b26..5147817 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ +SHA512 (389-ds-base-2.0.5.tar.bz2) = 727da122b16285a8c2bd096a599e106c712e09c3aad32c23311f9e4cd3481792f5fca565fa8dcafcfa5710bda2ec6024edac44ff06cbd2af318ecf3f4563b908 SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 -SHA512 (389-ds-base-2.0.4.tar.bz2) = accf7bbcd36c2ff52cca6f4ab3a58b5842938766981ff321b03d2e6adaab9c328253bee5b57cd9f43d0f047aca50f9aea880508ae4ca5d836c65ba7dc67b142a From d1e505dec61aa58cf5427ced3c92fd46c6141e85 Mon Sep 17 00:00:00 2001 From: Python Maint Date: Fri, 4 Jun 2021 19:58:51 +0200 Subject: [PATCH 024/125] Rebuilt for Python 3.10 --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 4e3e128..6de5759 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,7 +47,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.0.5 -Release: %{?relprefix}1%{?prerel}%{?dist} +Release: %{?relprefix}1%{?prerel}%{?dist}.1 License: GPLv3+ and MIT and (ASL 2.0 or MIT) and (ASL 2.0 or Boost) and MPLv2.0 and ASL 2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and (Unlicense or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -703,6 +703,9 @@ exit 0 %endif %changelog +* Fri Jun 04 2021 Python Maint - 2.0.5-1.1 +- Rebuilt for Python 3.10 + * Sun May 30 2021 Mark Reynolds - 2.0.5-1 - Bump version to 2.0.5 - Issue 4778 - RFE - Allow setting TOD for db compaction and add task From 831791b49bdf93febc34a9593e63b967a76d8fd1 Mon Sep 17 00:00:00 2001 From: Thierry Bordaz Date: Thu, 24 Jun 2021 11:20:43 +0200 Subject: [PATCH 025/125] Bump version to 2.0.6 Issue 4803 - Improve DB Locks Monitoring Feature Descriptions Issue 4803 - Improve DB Locks Monitoring Feature Descriptions (#4810) Issue 4169 - UI - Migrate Typeaheads to PF4 (#4808) Issue 4414 - disk monitoring - prevent division by zero crash Issue 4788 - CLI should support Temporary Password Rules attributes (#4793) Issue 4656 - Fix replication plugin rename dependency issues Issue 4656 - replication name change upgrade code causes crash with dynamic plugins Issue 4506 - Improve SASL logging Issue 4709 - Fix double free in dbscan Issue 4093 - Fix MEP test case Issue 4747 - Remove unstable/unstatus tests (followup) (#4809) Issue 4791 - Missing dependency for RetroCL RFE (#4792) Issue 4794 - BUG - don't capture container output (#4798) Issue 4593 - Log an additional message if the server certificate nickname doesn't match nsSSLPersonalitySSL value Issue 4797 - ACL IP ADDRESS evaluation may corrupt c_isreplication_session connection flags (#4799) Issue 4169 - UI Migrate checkbox to PF4 (#4769) Issue 4447 - Crash when the Referential Integrity log is manually edited Issue 4773 - Add CI test for DNA interval assignment Issue 4789 - Temporary password rules are not enforce with local password policy (#4790) Issue 4379 - fixing regression in test_info_disclosure Issue 4379 - Allow more than 1 empty AttributeDescription for ldapsearch, without the risk of denial of service Issue 4379 - Allow more than 1 empty AttributeDescription for ldapsearch, without the risk of denial of service Issue 4575 Update test docstrings metadata Issue 4753 - Adjust our tests to 389-ds-base-snmp missing in RHEL 9 Appstream removed the snmp_present() from utils.py as we have get_rpm_version() in conftest.py Issue 4753 - Adjust our tests to 389-ds-base-snmp missing in RHEL 9 Appstream --- .gitignore | 1 + 389-ds-base.spec | 68 ++++++++++++++++++++++++++++++++---------------- sources | 2 +- 3 files changed, 47 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index cb4664f..39013a1 100644 --- a/.gitignore +++ b/.gitignore @@ -204,3 +204,4 @@ /389-ds-base-2.0.4.tar.bz2 /389-ds-base-2.0.4.3.tar.bz2 /389-ds-base-2.0.5.tar.bz2 +/389-ds-base-2.0.6.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 6de5759..0136408 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,8 +46,8 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.0.5 -Release: %{?relprefix}1%{?prerel}%{?dist}.1 +Version: 2.0.6 +Release: %{?relprefix}1%{?prerel}%{?dist} License: GPLv3+ and MIT and (ASL 2.0 or MIT) and (ASL 2.0 or Boost) and MPLv2.0 and ASL 2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and (Unlicense or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -62,7 +62,6 @@ Provides: bundled(crate(ahash)) = 0.7.2 Provides: bundled(crate(ansi_term)) = 0.11.0 Provides: bundled(crate(atty)) = 0.2.14 Provides: bundled(crate(autocfg)) = 1.0.1 -Provides: bundled(crate(base64)) = 0.10.1 Provides: bundled(crate(base64)) = 0.13.0 Provides: bundled(crate(bitflags)) = 1.2.1 Provides: bundled(crate(byteorder)) = 1.4.3 @@ -70,38 +69,30 @@ Provides: bundled(crate(cbindgen)) = 0.9.1 Provides: bundled(crate(cc)) = 1.0.67 Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 2.33.3 -Provides: bundled(crate(concread)) = 0.2.8 +Provides: bundled(crate(concread)) = 0.2.9 Provides: bundled(crate(crossbeam)) = 0.8.0 -Provides: bundled(crate(crossbeam-channel)) = 0.5.0 +Provides: bundled(crate(crossbeam-channel)) = 0.5.1 Provides: bundled(crate(crossbeam-deque)) = 0.8.0 Provides: bundled(crate(crossbeam-epoch)) = 0.9.3 Provides: bundled(crate(crossbeam-queue)) = 0.3.1 Provides: bundled(crate(crossbeam-utils)) = 0.8.3 Provides: bundled(crate(entryuuid)) = 0.1.0 Provides: bundled(crate(entryuuid_syntax)) = 0.1.0 -Provides: bundled(crate(fernet)) = 0.1.3 +Provides: bundled(crate(fernet)) = 0.1.4 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 -Provides: bundled(crate(getrandom)) = 0.1.16 Provides: bundled(crate(getrandom)) = 0.2.2 Provides: bundled(crate(hermit-abi)) = 0.1.18 Provides: bundled(crate(instant)) = 0.1.9 Provides: bundled(crate(itoa)) = 0.4.7 Provides: bundled(crate(jobserver)) = 0.1.21 Provides: bundled(crate(lazy_static)) = 1.4.0 -Provides: bundled(crate(libc)) = 0.2.89 +Provides: bundled(crate(libc)) = 0.2.93 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 -Provides: bundled(crate(lock_api)) = 0.4.2 +Provides: bundled(crate(lock_api)) = 0.4.3 Provides: bundled(crate(log)) = 0.4.14 -Provides: bundled(crate(memoffset)) = 0.6.1 -Provides: bundled(crate(num)) = 0.3.1 -Provides: bundled(crate(num-bigint)) = 0.3.2 -Provides: bundled(crate(num-complex)) = 0.3.1 -Provides: bundled(crate(num-integer)) = 0.1.44 -Provides: bundled(crate(num-iter)) = 0.1.42 -Provides: bundled(crate(num-rational)) = 0.3.2 -Provides: bundled(crate(num-traits)) = 0.2.14 +Provides: bundled(crate(memoffset)) = 0.6.3 Provides: bundled(crate(once_cell)) = 1.7.2 Provides: bundled(crate(openssl)) = 0.10.33 Provides: bundled(crate(openssl-sys)) = 0.9.61 @@ -112,25 +103,26 @@ Provides: bundled(crate(paste-impl)) = 0.1.18 Provides: bundled(crate(pkg-config)) = 0.3.19 Provides: bundled(crate(ppv-lite86)) = 0.2.10 Provides: bundled(crate(proc-macro-hack)) = 0.5.19 -Provides: bundled(crate(proc-macro2)) = 1.0.24 +Provides: bundled(crate(proc-macro2)) = 1.0.26 Provides: bundled(crate(pwdchan)) = 0.1.0 Provides: bundled(crate(quote)) = 1.0.9 Provides: bundled(crate(rand)) = 0.8.3 Provides: bundled(crate(rand_chacha)) = 0.3.0 Provides: bundled(crate(rand_core)) = 0.6.2 Provides: bundled(crate(rand_hc)) = 0.3.0 -Provides: bundled(crate(redox_syscall)) = 0.2.5 +Provides: bundled(crate(redox_syscall)) = 0.2.6 Provides: bundled(crate(remove_dir_all)) = 0.5.3 Provides: bundled(crate(ryu)) = 1.0.5 Provides: bundled(crate(scopeguard)) = 1.1.0 -Provides: bundled(crate(serde)) = 1.0.124 -Provides: bundled(crate(serde_derive)) = 1.0.124 +Provides: bundled(crate(serde)) = 1.0.125 +Provides: bundled(crate(serde_derive)) = 1.0.125 Provides: bundled(crate(serde_json)) = 1.0.64 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 Provides: bundled(crate(smallvec)) = 1.6.1 Provides: bundled(crate(strsim)) = 0.8.0 -Provides: bundled(crate(syn)) = 1.0.64 +Provides: bundled(crate(syn)) = 1.0.69 +Provides: bundled(crate(synstructure)) = 0.12.4 Provides: bundled(crate(tempfile)) = 3.2.0 Provides: bundled(crate(textwrap)) = 0.11.0 Provides: bundled(crate(toml)) = 0.5.8 @@ -141,10 +133,11 @@ Provides: bundled(crate(vcpkg)) = 0.2.11 Provides: bundled(crate(vec_map)) = 0.8.2 Provides: bundled(crate(version_check)) = 0.9.3 Provides: bundled(crate(wasi)) = 0.10.2+wasi_snapshot_preview1 -Provides: bundled(crate(wasi)) = 0.9.0+wasi_snapshot_preview1 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 +Provides: bundled(crate(zeroize)) = 1.2.0 +Provides: bundled(crate(zeroize_derive)) = 1.0.1 ##### Bundled cargo crates list - END ##### BuildRequires: nspr-devel @@ -703,6 +696,35 @@ exit 0 %endif %changelog +* Thu Jun 24 2021 Thierry Bordaz - 2.0.6-1 +- Bump version to 2.0.6 +- Issue 4803 - Improve DB Locks Monitoring Feature Descriptions +- Issue 4803 - Improve DB Locks Monitoring Feature Descriptions (#4810) +- Issue 4169 - UI - Migrate Typeaheads to PF4 (#4808) +- Issue 4414 - disk monitoring - prevent division by zero crash +- Issue 4788 - CLI should support Temporary Password Rules attributes (#4793) +- Issue 4656 - Fix replication plugin rename dependency issues +- Issue 4656 - replication name change upgrade code causes crash with dynamic plugins +- Issue 4506 - Improve SASL logging +- Issue 4709 - Fix double free in dbscan +- Issue 4093 - Fix MEP test case +- Issue 4747 - Remove unstable/unstatus tests (followup) (#4809) +- Issue 4791 - Missing dependency for RetroCL RFE (#4792) +- Issue 4794 - BUG - don't capture container output (#4798) +- Issue 4593 - Log an additional message if the server certificate nickname doesn't match nsSSLPersonalitySSL value +- Issue 4797 - ACL IP ADDRESS evaluation may corrupt c_isreplication_session connection flags (#4799) +- Issue 4169 - UI Migrate checkbox to PF4 (#4769) +- Issue 4447 - Crash when the Referential Integrity log is manually edited +- Issue 4773 - Add CI test for DNA interval assignment +- Issue 4789 - Temporary password rules are not enforce with local password policy (#4790) +- Issue 4379 - fixing regression in test_info_disclosure +- Issue 4379 - Allow more than 1 empty AttributeDescription for ldapsearch, without the risk of denial of service +- Issue 4379 - Allow more than 1 empty AttributeDescription for ldapsearch, without the risk of denial of service +- Issue 4575 Update test docstrings metadata +- Issue 4753 - Adjust our tests to 389-ds-base-snmp missing in RHEL 9 Appstream +- removed the snmp_present() from utils.py as we have get_rpm_version() in conftest.py +- Issue 4753 - Adjust our tests to 389-ds-base-snmp missing in RHEL 9 Appstream + * Fri Jun 04 2021 Python Maint - 2.0.5-1.1 - Rebuilt for Python 3.10 diff --git a/sources b/sources index 5147817..caaca22 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (389-ds-base-2.0.5.tar.bz2) = 727da122b16285a8c2bd096a599e106c712e09c3aad32c23311f9e4cd3481792f5fca565fa8dcafcfa5710bda2ec6024edac44ff06cbd2af318ecf3f4563b908 SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 +SHA512 (389-ds-base-2.0.6.tar.bz2) = 3a988207d1883e06c447d61906aa6a39eba229f77d7c6d6e0767fdc81b3c53256d829817d18b06e58460a0ea5ec1bf4e915a2b6aded3bdea23831ff767e31cf8 From 7466cff129a344cc0548f293d582a64ba6fbe070 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Thu, 15 Jul 2021 14:24:25 -0400 Subject: [PATCH 026/125] Bump version to 2.0.7 Issue 4443 - Internal unindexed searches in syncrepl/retro changelog Issue 4603 - Reindexing a single backend (#4831) Issue 4169 - UI - migrate Server Tab forms to PF4 Issue 4817 - BUG - locked crypt accounts on import may allow all passwords (#4819) Issue 4820 - RFE - control flow integrity (#4821) Issue 4706 - negative wtime for compare operations (#4780) Issue 4414 - SIGFPE crash in rhds disk monitoring routine (#4829) Issue 4262 - Fix Index out of bound in fractional test (#4828) Issue 4826 - Filter argparse-manpage from autogenerated requires Issue 4822 - Fix CI temporary password: fixture leftover breaks them (#4823) Issue 2820 - Fix CI test suite issues --- .gitignore | 1 + 389-ds-base.spec | 19 ++++++++++++++++++- sources | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 39013a1..a5a3b57 100644 --- a/.gitignore +++ b/.gitignore @@ -205,3 +205,4 @@ /389-ds-base-2.0.4.3.tar.bz2 /389-ds-base-2.0.5.tar.bz2 /389-ds-base-2.0.6.tar.bz2 +/389-ds-base-2.0.7.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 0136408..6975476 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -44,9 +44,12 @@ ExcludeArch: i686 # set PIE flag %global _hardened_build 1 +# Filter argparse-manpage from autogenerated package Requires +%global __requires_exclude ^python.*argparse-manpage + Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.0.6 +Version: 2.0.7 Release: %{?relprefix}1%{?prerel}%{?dist} License: GPLv3+ and MIT and (ASL 2.0 or MIT) and (ASL 2.0 or Boost) and MPLv2.0 and ASL 2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and (Unlicense or MIT) URL: https://www.port389.org @@ -696,6 +699,20 @@ exit 0 %endif %changelog +* Thu Jul 15 2021 Mark Reynolds - 2.0.7-1 +- Bump version to 2.0.7 +- Issue 4443 - Internal unindexed searches in syncrepl/retro changelog +- Issue 4603 - Reindexing a single backend (#4831) +- Issue 4169 - UI - migrate Server Tab forms to PF4 +- Issue 4817 - BUG - locked crypt accounts on import may allow all passwords (#4819) +- Issue 4820 - RFE - control flow integrity (#4821) +- Issue 4706 - negative wtime for compare operations (#4780) +- Issue 4414 - SIGFPE crash in rhds disk monitoring routine (#4829) +- Issue 4262 - Fix Index out of bound in fractional test (#4828) +- Issue 4826 - Filter argparse-manpage from autogenerated requires +- Issue 4822 - Fix CI temporary password: fixture leftover breaks them (#4823) +- Issue 2820 - Fix CI test suite issues + * Thu Jun 24 2021 Thierry Bordaz - 2.0.6-1 - Bump version to 2.0.6 - Issue 4803 - Improve DB Locks Monitoring Feature Descriptions diff --git a/sources b/sources index caaca22..275c1fe 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 -SHA512 (389-ds-base-2.0.6.tar.bz2) = 3a988207d1883e06c447d61906aa6a39eba229f77d7c6d6e0767fdc81b3c53256d829817d18b06e58460a0ea5ec1bf4e915a2b6aded3bdea23831ff767e31cf8 +SHA512 (389-ds-base-2.0.7.tar.bz2) = 05a307d2bfbf47e60cab236f4b9f931820e33e208579422e85f2823eb19dbd45dbab5758366c1be48cbdcdf5fbf128ab3d6700ec2be1fe61dd63b9b1f855f30f From a8e72d4ac498e53eb440eaafd4c089eacf2f843b Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 21 Jul 2021 10:40:58 +0000 Subject: [PATCH 027/125] - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild Signed-off-by: Fedora Release Engineering From 1feedc33f282692b03dc3688ae16551b6a5453d9 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 21 Jul 2021 15:35:24 +0000 Subject: [PATCH 028/125] - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 6975476..6108dfe 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -50,7 +50,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.0.7 -Release: %{?relprefix}1%{?prerel}%{?dist} +Release: %{?relprefix}1%{?prerel}%{?dist}.1 License: GPLv3+ and MIT and (ASL 2.0 or MIT) and (ASL 2.0 or Boost) and MPLv2.0 and ASL 2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and (Unlicense or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -699,6 +699,9 @@ exit 0 %endif %changelog +* Wed Jul 21 2021 Fedora Release Engineering - 2.0.7-1.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + * Thu Jul 15 2021 Mark Reynolds - 2.0.7-1 - Bump version to 2.0.7 - Issue 4443 - Internal unindexed searches in syncrepl/retro changelog From 839c0c7eb114034b0463d7adb8b3a3c65d5d482d Mon Sep 17 00:00:00 2001 From: Sahana Prasad Date: Tue, 14 Sep 2021 19:19:06 +0200 Subject: [PATCH 029/125] Rebuilt with OpenSSL 3.0.0 --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 6108dfe..4f8b784 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -50,7 +50,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.0.7 -Release: %{?relprefix}1%{?prerel}%{?dist}.1 +Release: %{?relprefix}1%{?prerel}%{?dist}.2 License: GPLv3+ and MIT and (ASL 2.0 or MIT) and (ASL 2.0 or Boost) and MPLv2.0 and ASL 2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and (Unlicense or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -699,6 +699,9 @@ exit 0 %endif %changelog +* Tue Sep 14 2021 Sahana Prasad - 2.0.7-1.2 +- Rebuilt with OpenSSL 3.0.0 + * Wed Jul 21 2021 Fedora Release Engineering - 2.0.7-1.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild From f6889418c5ec70ad8cdac2ab6e1f062fbca0c90c Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Mon, 20 Sep 2021 09:54:09 -0400 Subject: [PATCH 030/125] Bump version to 2.0.10 Issue 4908 - Updated several dsconf --help entries (typos, wrong descriptions, etc.) Issue 4912 - Account Policy plugin does not set the config entry DN Issue 4863 - typoes in logconv.pl Issue 4796 - Add support for nsslapd-state to CLI & UI Issue 4894 - IPA failure in ipa user-del --preserve (#4907) Issue 4912 - dsidm command crashing when account policy plugin is enabled Issue 4910 - db reindex corrupts RUV tombstone nsuiqueid index Issue 4869 - Fix retro cl trimming misuse of monotonic/realtime clocks Issue 4887 - UI - fix minor regression from camelCase fixup --- .gitignore | 1 + 389-ds-base.spec | 105 ++++++++++++++++++++++++++++------------------- sources | 2 +- 3 files changed, 65 insertions(+), 43 deletions(-) diff --git a/.gitignore b/.gitignore index a5a3b57..37e58d4 100644 --- a/.gitignore +++ b/.gitignore @@ -206,3 +206,4 @@ /389-ds-base-2.0.5.tar.bz2 /389-ds-base-2.0.6.tar.bz2 /389-ds-base-2.0.7.tar.bz2 +/389-ds-base-2.0.10.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 4f8b784..709c3ea 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,11 +47,15 @@ ExcludeArch: i686 # Filter argparse-manpage from autogenerated package Requires %global __requires_exclude ^python.*argparse-manpage +# Force to require nss version greater or equal as the version available at the build time +# See bz1986327 +%define dirsrv_requires_ge() %(LC_ALL="C" echo '%*' | xargs -r rpm -q --qf 'Requires: %%{name} >= %%{epoch}:%%{version}\\n' | sed -e 's/ (none):/ /' -e 's/ 0:/ /' | grep -v "is not") + Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.0.7 -Release: %{?relprefix}1%{?prerel}%{?dist}.2 -License: GPLv3+ and MIT and (ASL 2.0 or MIT) and (ASL 2.0 or Boost) and MPLv2.0 and ASL 2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and (Unlicense or MIT) +Version: 2.0.10 +Release: %{?relprefix}1%{?prerel}%{?dist} +License: GPLv3+ and (ASL 2.0 or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 Conflicts: freeipa-server < 4.0.3 @@ -61,86 +65,89 @@ Obsoletes: %{name}-legacy-tools-debuginfo < 1.4.4.6 Provides: ldif2ldbm >= 0 ##### Bundled cargo crates list - START ##### -Provides: bundled(crate(ahash)) = 0.7.2 +Provides: bundled(crate(ahash)) = 0.7.4 Provides: bundled(crate(ansi_term)) = 0.11.0 Provides: bundled(crate(atty)) = 0.2.14 Provides: bundled(crate(autocfg)) = 1.0.1 Provides: bundled(crate(base64)) = 0.13.0 -Provides: bundled(crate(bitflags)) = 1.2.1 +Provides: bundled(crate(bitflags)) = 1.3.2 Provides: bundled(crate(byteorder)) = 1.4.3 Provides: bundled(crate(cbindgen)) = 0.9.1 -Provides: bundled(crate(cc)) = 1.0.67 +Provides: bundled(crate(cc)) = 1.0.70 Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 2.33.3 -Provides: bundled(crate(concread)) = 0.2.9 -Provides: bundled(crate(crossbeam)) = 0.8.0 +Provides: bundled(crate(concread)) = 0.2.18 +Provides: bundled(crate(crossbeam)) = 0.8.1 Provides: bundled(crate(crossbeam-channel)) = 0.5.1 -Provides: bundled(crate(crossbeam-deque)) = 0.8.0 -Provides: bundled(crate(crossbeam-epoch)) = 0.9.3 -Provides: bundled(crate(crossbeam-queue)) = 0.3.1 -Provides: bundled(crate(crossbeam-utils)) = 0.8.3 +Provides: bundled(crate(crossbeam-deque)) = 0.8.1 +Provides: bundled(crate(crossbeam-epoch)) = 0.9.5 +Provides: bundled(crate(crossbeam-queue)) = 0.3.2 +Provides: bundled(crate(crossbeam-utils)) = 0.8.5 Provides: bundled(crate(entryuuid)) = 0.1.0 Provides: bundled(crate(entryuuid_syntax)) = 0.1.0 Provides: bundled(crate(fernet)) = 0.1.4 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 -Provides: bundled(crate(getrandom)) = 0.2.2 -Provides: bundled(crate(hermit-abi)) = 0.1.18 -Provides: bundled(crate(instant)) = 0.1.9 -Provides: bundled(crate(itoa)) = 0.4.7 -Provides: bundled(crate(jobserver)) = 0.1.21 +Provides: bundled(crate(getrandom)) = 0.2.3 +Provides: bundled(crate(hermit-abi)) = 0.1.19 +Provides: bundled(crate(instant)) = 0.1.10 +Provides: bundled(crate(itoa)) = 0.4.8 +Provides: bundled(crate(jobserver)) = 0.1.24 Provides: bundled(crate(lazy_static)) = 1.4.0 -Provides: bundled(crate(libc)) = 0.2.93 +Provides: bundled(crate(libc)) = 0.2.102 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 -Provides: bundled(crate(lock_api)) = 0.4.3 +Provides: bundled(crate(lock_api)) = 0.4.5 Provides: bundled(crate(log)) = 0.4.14 -Provides: bundled(crate(memoffset)) = 0.6.3 -Provides: bundled(crate(once_cell)) = 1.7.2 -Provides: bundled(crate(openssl)) = 0.10.33 -Provides: bundled(crate(openssl-sys)) = 0.9.61 -Provides: bundled(crate(parking_lot)) = 0.11.1 -Provides: bundled(crate(parking_lot_core)) = 0.8.3 +Provides: bundled(crate(memoffset)) = 0.6.4 +Provides: bundled(crate(once_cell)) = 1.8.0 +Provides: bundled(crate(openssl)) = 0.10.36 +Provides: bundled(crate(openssl-sys)) = 0.9.66 +Provides: bundled(crate(parking_lot)) = 0.11.2 +Provides: bundled(crate(parking_lot_core)) = 0.8.5 Provides: bundled(crate(paste)) = 0.1.18 Provides: bundled(crate(paste-impl)) = 0.1.18 +Provides: bundled(crate(pin-project-lite)) = 0.2.7 Provides: bundled(crate(pkg-config)) = 0.3.19 Provides: bundled(crate(ppv-lite86)) = 0.2.10 Provides: bundled(crate(proc-macro-hack)) = 0.5.19 -Provides: bundled(crate(proc-macro2)) = 1.0.26 +Provides: bundled(crate(proc-macro2)) = 1.0.29 Provides: bundled(crate(pwdchan)) = 0.1.0 Provides: bundled(crate(quote)) = 1.0.9 -Provides: bundled(crate(rand)) = 0.8.3 -Provides: bundled(crate(rand_chacha)) = 0.3.0 -Provides: bundled(crate(rand_core)) = 0.6.2 -Provides: bundled(crate(rand_hc)) = 0.3.0 -Provides: bundled(crate(redox_syscall)) = 0.2.6 +Provides: bundled(crate(rand)) = 0.8.4 +Provides: bundled(crate(rand_chacha)) = 0.3.1 +Provides: bundled(crate(rand_core)) = 0.6.3 +Provides: bundled(crate(rand_hc)) = 0.3.1 +Provides: bundled(crate(redox_syscall)) = 0.2.10 Provides: bundled(crate(remove_dir_all)) = 0.5.3 Provides: bundled(crate(ryu)) = 1.0.5 Provides: bundled(crate(scopeguard)) = 1.1.0 -Provides: bundled(crate(serde)) = 1.0.125 -Provides: bundled(crate(serde_derive)) = 1.0.125 -Provides: bundled(crate(serde_json)) = 1.0.64 +Provides: bundled(crate(serde)) = 1.0.130 +Provides: bundled(crate(serde_derive)) = 1.0.130 +Provides: bundled(crate(serde_json)) = 1.0.68 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 Provides: bundled(crate(smallvec)) = 1.6.1 Provides: bundled(crate(strsim)) = 0.8.0 -Provides: bundled(crate(syn)) = 1.0.69 -Provides: bundled(crate(synstructure)) = 0.12.4 +Provides: bundled(crate(syn)) = 1.0.76 +Provides: bundled(crate(synstructure)) = 0.12.5 Provides: bundled(crate(tempfile)) = 3.2.0 Provides: bundled(crate(textwrap)) = 0.11.0 +Provides: bundled(crate(tokio)) = 1.11.0 +Provides: bundled(crate(tokio-macros)) = 1.3.0 Provides: bundled(crate(toml)) = 0.5.8 -Provides: bundled(crate(unicode-width)) = 0.1.8 -Provides: bundled(crate(unicode-xid)) = 0.2.1 +Provides: bundled(crate(unicode-width)) = 0.1.9 +Provides: bundled(crate(unicode-xid)) = 0.2.2 Provides: bundled(crate(uuid)) = 0.8.2 -Provides: bundled(crate(vcpkg)) = 0.2.11 +Provides: bundled(crate(vcpkg)) = 0.2.15 Provides: bundled(crate(vec_map)) = 0.8.2 Provides: bundled(crate(version_check)) = 0.9.3 Provides: bundled(crate(wasi)) = 0.10.2+wasi_snapshot_preview1 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 -Provides: bundled(crate(zeroize)) = 1.2.0 -Provides: bundled(crate(zeroize_derive)) = 1.0.1 +Provides: bundled(crate(zeroize)) = 1.4.1 +Provides: bundled(crate(zeroize_derive)) = 1.1.0 ##### Bundled cargo crates list - END ##### BuildRequires: nspr-devel @@ -243,6 +250,8 @@ Requires: cracklib-dicts # Needed by logconv.pl Requires: perl-DB_File Requires: perl-Archive-Tar +Requires: perl-debugger +Requires: perl-sigtrap # Picks up our systemd deps. %{?systemd_requires} @@ -665,7 +674,7 @@ exit 0 %dir %{_libdir}/%{pkgname} %{_libdir}/libsvrcore.so.* %{_libdir}/%{pkgname}/libslapd.so.* -%{_libdir}/%{pkgname}/libns-dshttpd-*.so +%{_libdir}/%{pkgname}/libns-dshttpd.so.* %{_libdir}/%{pkgname}/libldaputil.so.* %{_libdir}/%{pkgname}/librewriters.so* %if %{bundle_jemalloc} @@ -699,6 +708,18 @@ exit 0 %endif %changelog +* Mon Sep 20 2021 Mark Reynolds - 2.0.10-1 +- Bump version to 2.0.10 +- Issue 4908 - Updated several dsconf --help entries (typos, wrong descriptions, etc.) +- Issue 4912 - Account Policy plugin does not set the config entry DN +- Issue 4863 - typoes in logconv.pl +- Issue 4796 - Add support for nsslapd-state to CLI & UI +- Issue 4894 - IPA failure in ipa user-del --preserve (#4907) +- Issue 4912 - dsidm command crashing when account policy plugin is enabled +- Issue 4910 - db reindex corrupts RUV tombstone nsuiqueid index +- Issue 4869 - Fix retro cl trimming misuse of monotonic/realtime clocks +- Issue 4887 - UI - fix minor regression from camelCase fixup + * Tue Sep 14 2021 Sahana Prasad - 2.0.7-1.2 - Rebuilt with OpenSSL 3.0.0 diff --git a/sources b/sources index 275c1fe..a748bd4 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ +SHA512 (389-ds-base-2.0.10.tar.bz2) = 2ae362386c72c2b6408d7f0ba8e04f3f2b4a750e4c60aa8915fd513994da62f4ac6bf10dcf69b75504611b082527b906cfa0c507d0aaf48b5f729b7acaa80b4f SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 -SHA512 (389-ds-base-2.0.7.tar.bz2) = 05a307d2bfbf47e60cab236f4b9f931820e33e208579422e85f2823eb19dbd45dbab5758366c1be48cbdcdf5fbf128ab3d6700ec2be1fe61dd63b9b1f855f30f From da1ce1e0f715f13a70f81a39fd3c9aac0f2702f3 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Thu, 4 Nov 2021 08:46:01 +0100 Subject: [PATCH 031/125] Use split perl dependencies only on Fedora >= 33 and RHEL >= 9 Resolves rhbz#2016595 --- 389-ds-base.spec | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 709c3ea..c4d6f3a 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -54,7 +54,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.0.10 -Release: %{?relprefix}1%{?prerel}%{?dist} +Release: %{?relprefix}2%{?prerel}%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -250,8 +250,10 @@ Requires: cracklib-dicts # Needed by logconv.pl Requires: perl-DB_File Requires: perl-Archive-Tar +%if 0%{?fedora} >= 33 || 0%{?rhel} >= 9 Requires: perl-debugger Requires: perl-sigtrap +%endif # Picks up our systemd deps. %{?systemd_requires} @@ -708,6 +710,9 @@ exit 0 %endif %changelog +* Thu Nov 04 2021 Viktor Ashirov - 2.0.10-2 +- Resolves #rhbz2016595 + * Mon Sep 20 2021 Mark Reynolds - 2.0.10-1 - Bump version to 2.0.10 - Issue 4908 - Updated several dsconf --help entries (typos, wrong descriptions, etc.) From 3d04292979269e2a8b360ff8e945df5b7a2db562 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Mon, 22 Nov 2021 20:08:03 -0500 Subject: [PATCH 032/125] Bump version to 2.0.11 Issue 4962 - Fix various UI bugs - Settings and Monitor (#5016) Issue 5014 - UI - Add group creation to LDAP editor Issue 5006 - UI - LDAP editor tree not being properly updated Issue 5001 - Update CI test for new availableSASLMechs attribute Issue 4959 - Invalid /etc/hosts setup can cause isLocalHost to fail. Issue 5001 - Fix next round of UI bugs: Issue 4962 - Fix various UI bugs - dsctl and ciphers (#5000) Issue 4978 - use more portable python command for checking containers Issue 4678 - RFE automatique disable of virtual attribute checking (#4918) Issue 4972 - gecos with IA5 introduces a compatibility issue with previous (#4981) Issue 4978 - make installer robust Issue 4976 - Failure in suites/import/import_test.py::test_fast_slow_import Issue 4973 - update snmp to use /run/dirsrv for PID file Issue 4962 - Fix various UI bugs - Plugins (#4969) Issue 4973 - installer changes permissions on /run Issue 4092 - systemd-tmpfiles warnings Issue 4956 - Automember allows invalid regex, and does not log proper error Issue 4731 - Promoting/demoting a replica can crash the server Issue 4962 - Fix various UI bugs part 1 Issue 3584 - Fix PBKDF2_SHA256 hashing in FIPS mode (#4949) Issue 4943 - Fix csn generator to limit time skew drift (#4946) Issue 2790 - Set db home directory by default Issue 4299 - Merge LDAP editor code into Cockpit UI Issue 4938 - max_failure_count can be reached in dscontainer on slow machine with missing debug exception trace Issue 4921 - logconv.pl -j: Use of uninitialized value (#4922) Issue 4847 - BUG - potential deadlock in replica (#4936) Issue 4513 - fix ACI CI tests involving ip/hostname rules Issue 4925 - Performance ACI: targetfilter evaluation result can be reused (#4926) Issue 4916 - Memory leak in ldap-agent --- .gitignore | 1 + 389-ds-base.spec | 78 ++++++++++++++++++++++++++++++++++-------------- sources | 2 +- 3 files changed, 58 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index 37e58d4..0f767d3 100644 --- a/.gitignore +++ b/.gitignore @@ -207,3 +207,4 @@ /389-ds-base-2.0.6.tar.bz2 /389-ds-base-2.0.7.tar.bz2 /389-ds-base-2.0.10.tar.bz2 +/389-ds-base-2.0.11.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index c4d6f3a..b1bf1c2 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -53,9 +53,9 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.0.10 -Release: %{?relprefix}2%{?prerel}%{?dist} -License: GPLv3+ and (ASL 2.0 or MIT) +Version: 2.0.11 +Release: %{?relprefix}1%{?prerel}%{?dist} +License: GPLv3+ URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 Conflicts: freeipa-server < 4.0.3 @@ -65,7 +65,7 @@ Obsoletes: %{name}-legacy-tools-debuginfo < 1.4.4.6 Provides: ldif2ldbm >= 0 ##### Bundled cargo crates list - START ##### -Provides: bundled(crate(ahash)) = 0.7.4 +Provides: bundled(crate(ahash)) = 0.7.6 Provides: bundled(crate(ansi_term)) = 0.11.0 Provides: bundled(crate(atty)) = 0.2.14 Provides: bundled(crate(autocfg)) = 1.0.1 @@ -73,10 +73,10 @@ Provides: bundled(crate(base64)) = 0.13.0 Provides: bundled(crate(bitflags)) = 1.3.2 Provides: bundled(crate(byteorder)) = 1.4.3 Provides: bundled(crate(cbindgen)) = 0.9.1 -Provides: bundled(crate(cc)) = 1.0.70 +Provides: bundled(crate(cc)) = 1.0.72 Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 2.33.3 -Provides: bundled(crate(concread)) = 0.2.18 +Provides: bundled(crate(concread)) = 0.2.19 Provides: bundled(crate(crossbeam)) = 0.8.1 Provides: bundled(crate(crossbeam-channel)) = 0.5.1 Provides: bundled(crate(crossbeam-deque)) = 0.8.1 @@ -89,31 +89,33 @@ Provides: bundled(crate(fernet)) = 0.1.4 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 Provides: bundled(crate(getrandom)) = 0.2.3 +Provides: bundled(crate(hashbrown)) = 0.11.2 Provides: bundled(crate(hermit-abi)) = 0.1.19 -Provides: bundled(crate(instant)) = 0.1.10 +Provides: bundled(crate(instant)) = 0.1.12 Provides: bundled(crate(itoa)) = 0.4.8 Provides: bundled(crate(jobserver)) = 0.1.24 Provides: bundled(crate(lazy_static)) = 1.4.0 -Provides: bundled(crate(libc)) = 0.2.102 +Provides: bundled(crate(libc)) = 0.2.108 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 Provides: bundled(crate(lock_api)) = 0.4.5 Provides: bundled(crate(log)) = 0.4.14 +Provides: bundled(crate(lru)) = 0.6.6 Provides: bundled(crate(memoffset)) = 0.6.4 Provides: bundled(crate(once_cell)) = 1.8.0 -Provides: bundled(crate(openssl)) = 0.10.36 -Provides: bundled(crate(openssl-sys)) = 0.9.66 +Provides: bundled(crate(openssl)) = 0.10.38 +Provides: bundled(crate(openssl-sys)) = 0.9.71 Provides: bundled(crate(parking_lot)) = 0.11.2 Provides: bundled(crate(parking_lot_core)) = 0.8.5 Provides: bundled(crate(paste)) = 0.1.18 Provides: bundled(crate(paste-impl)) = 0.1.18 Provides: bundled(crate(pin-project-lite)) = 0.2.7 -Provides: bundled(crate(pkg-config)) = 0.3.19 -Provides: bundled(crate(ppv-lite86)) = 0.2.10 +Provides: bundled(crate(pkg-config)) = 0.3.22 +Provides: bundled(crate(ppv-lite86)) = 0.2.15 Provides: bundled(crate(proc-macro-hack)) = 0.5.19 -Provides: bundled(crate(proc-macro2)) = 1.0.29 +Provides: bundled(crate(proc-macro2)) = 1.0.32 Provides: bundled(crate(pwdchan)) = 0.1.0 -Provides: bundled(crate(quote)) = 1.0.9 +Provides: bundled(crate(quote)) = 1.0.10 Provides: bundled(crate(rand)) = 0.8.4 Provides: bundled(crate(rand_chacha)) = 0.3.1 Provides: bundled(crate(rand_core)) = 0.6.3 @@ -124,17 +126,17 @@ Provides: bundled(crate(ryu)) = 1.0.5 Provides: bundled(crate(scopeguard)) = 1.1.0 Provides: bundled(crate(serde)) = 1.0.130 Provides: bundled(crate(serde_derive)) = 1.0.130 -Provides: bundled(crate(serde_json)) = 1.0.68 +Provides: bundled(crate(serde_json)) = 1.0.71 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 -Provides: bundled(crate(smallvec)) = 1.6.1 +Provides: bundled(crate(smallvec)) = 1.7.0 Provides: bundled(crate(strsim)) = 0.8.0 -Provides: bundled(crate(syn)) = 1.0.76 -Provides: bundled(crate(synstructure)) = 0.12.5 +Provides: bundled(crate(syn)) = 1.0.81 +Provides: bundled(crate(synstructure)) = 0.12.6 Provides: bundled(crate(tempfile)) = 3.2.0 Provides: bundled(crate(textwrap)) = 0.11.0 -Provides: bundled(crate(tokio)) = 1.11.0 -Provides: bundled(crate(tokio-macros)) = 1.3.0 +Provides: bundled(crate(tokio)) = 1.14.0 +Provides: bundled(crate(tokio-macros)) = 1.6.0 Provides: bundled(crate(toml)) = 0.5.8 Provides: bundled(crate(unicode-width)) = 0.1.9 Provides: bundled(crate(unicode-xid)) = 0.2.2 @@ -146,8 +148,8 @@ Provides: bundled(crate(wasi)) = 0.10.2+wasi_snapshot_preview1 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 -Provides: bundled(crate(zeroize)) = 1.4.1 -Provides: bundled(crate(zeroize_derive)) = 1.1.0 +Provides: bundled(crate(zeroize)) = 1.4.3 +Provides: bundled(crate(zeroize_derive)) = 1.2.2 ##### Bundled cargo crates list - END ##### BuildRequires: nspr-devel @@ -710,6 +712,38 @@ exit 0 %endif %changelog +* Mon Nov 22 2021 Mark Reynolds - 2.0.11-1 +- Bump version to 2.0.11 +- Issue 4962 - Fix various UI bugs - Settings and Monitor (#5016) +- Issue 5014 - UI - Add group creation to LDAP editor +- Issue 5006 - UI - LDAP editor tree not being properly updated +- Issue 5001 - Update CI test for new availableSASLMechs attribute +- Issue 4959 - Invalid /etc/hosts setup can cause isLocalHost to fail. +- Issue 5001 - Fix next round of UI bugs: +- Issue 4962 - Fix various UI bugs - dsctl and ciphers (#5000) +- Issue 4978 - use more portable python command for checking containers +- Issue 4678 - RFE automatique disable of virtual attribute checking (#4918) +- Issue 4972 - gecos with IA5 introduces a compatibility issue with previous (#4981) +- Issue 4978 - make installer robust +- Issue 4976 - Failure in suites/import/import_test.py::test_fast_slow_import +- Issue 4973 - update snmp to use /run/dirsrv for PID file +- Issue 4962 - Fix various UI bugs - Plugins (#4969) +- Issue 4973 - installer changes permissions on /run +- Issue 4092 - systemd-tmpfiles warnings +- Issue 4956 - Automember allows invalid regex, and does not log proper error +- Issue 4731 - Promoting/demoting a replica can crash the server +- Issue 4962 - Fix various UI bugs part 1 +- Issue 3584 - Fix PBKDF2_SHA256 hashing in FIPS mode (#4949) +- Issue 4943 - Fix csn generator to limit time skew drift (#4946) +- Issue 2790 - Set db home directory by default +- Issue 4299 - Merge LDAP editor code into Cockpit UI +- Issue 4938 - max_failure_count can be reached in dscontainer on slow machine with missing debug exception trace +- Issue 4921 - logconv.pl -j: Use of uninitialized value (#4922) +- Issue 4847 - BUG - potential deadlock in replica (#4936) +- Issue 4513 - fix ACI CI tests involving ip/hostname rules +- Issue 4925 - Performance ACI: targetfilter evaluation result can be reused (#4926) +- Issue 4916 - Memory leak in ldap-agent + * Thu Nov 04 2021 Viktor Ashirov - 2.0.10-2 - Resolves #rhbz2016595 diff --git a/sources b/sources index a748bd4..1d4ddf2 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (389-ds-base-2.0.10.tar.bz2) = 2ae362386c72c2b6408d7f0ba8e04f3f2b4a750e4c60aa8915fd513994da62f4ac6bf10dcf69b75504611b082527b906cfa0c507d0aaf48b5f729b7acaa80b4f +SHA512 (389-ds-base-2.0.11.tar.bz2) = 23869b5ec8d0fd2774682b5c2dfd1d60dc99a50f5817e25dca50f1eb62d2553f11f7249c7751d1e010bf0c1a0380ec08f56fc5b3f7d66f439a6e350913912318 SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 From 2351af3f1f20379fbea01c8027558488dedb1c5d Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Thu, 16 Dec 2021 17:30:03 -0500 Subject: [PATCH 033/125] Bump version to 2.0.12-1 Issue 4299 - UI LDAP editor - add "edit" and "rename" functionality Issue 4962 - Fix various UI bugs - Database and Backups (#5044) Issue 5046 - BUG - update concread (#5047) Issue 5043 - BUG - Result must be used compiler warning (#5045) Issue 4165 - Don't apply RootDN access control restrictions to UNIX connections Issue 4931 - RFE: dsidm - add creation of service accounts Issue 5024 - BUG - windows ro replica sigsegv (#5027) Issue 5020 - BUG - improve clarity of posix win sync logging (#5021) Issue 5008 - If a non critical plugin can not be loaded/initialized, bootstrap should succeeds (#5009) --- .gitignore | 1 + 389-ds-base.spec | 48 ++++++++++++++++++++++++++++++------------------ sources | 2 +- 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index 0f767d3..f960344 100644 --- a/.gitignore +++ b/.gitignore @@ -208,3 +208,4 @@ /389-ds-base-2.0.7.tar.bz2 /389-ds-base-2.0.10.tar.bz2 /389-ds-base-2.0.11.tar.bz2 +/389-ds-base-2.0.12.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index b1bf1c2..b256405 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -53,7 +53,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.0.11 +Version: 2.0.12 Release: %{?relprefix}1%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org @@ -66,7 +66,7 @@ Provides: ldif2ldbm >= 0 ##### Bundled cargo crates list - START ##### Provides: bundled(crate(ahash)) = 0.7.6 -Provides: bundled(crate(ansi_term)) = 0.11.0 +Provides: bundled(crate(ansi_term)) = 0.12.1 Provides: bundled(crate(atty)) = 0.2.14 Provides: bundled(crate(autocfg)) = 1.0.1 Provides: bundled(crate(base64)) = 0.13.0 @@ -75,8 +75,8 @@ Provides: bundled(crate(byteorder)) = 1.4.3 Provides: bundled(crate(cbindgen)) = 0.9.1 Provides: bundled(crate(cc)) = 1.0.72 Provides: bundled(crate(cfg-if)) = 1.0.0 -Provides: bundled(crate(clap)) = 2.33.3 -Provides: bundled(crate(concread)) = 0.2.19 +Provides: bundled(crate(clap)) = 2.34.0 +Provides: bundled(crate(concread)) = 0.2.20 Provides: bundled(crate(crossbeam)) = 0.8.1 Provides: bundled(crate(crossbeam-channel)) = 0.5.1 Provides: bundled(crate(crossbeam-deque)) = 0.8.1 @@ -92,28 +92,28 @@ Provides: bundled(crate(getrandom)) = 0.2.3 Provides: bundled(crate(hashbrown)) = 0.11.2 Provides: bundled(crate(hermit-abi)) = 0.1.19 Provides: bundled(crate(instant)) = 0.1.12 -Provides: bundled(crate(itoa)) = 0.4.8 +Provides: bundled(crate(itoa)) = 1.0.1 Provides: bundled(crate(jobserver)) = 0.1.24 Provides: bundled(crate(lazy_static)) = 1.4.0 -Provides: bundled(crate(libc)) = 0.2.108 +Provides: bundled(crate(libc)) = 0.2.112 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 Provides: bundled(crate(lock_api)) = 0.4.5 Provides: bundled(crate(log)) = 0.4.14 Provides: bundled(crate(lru)) = 0.6.6 -Provides: bundled(crate(memoffset)) = 0.6.4 -Provides: bundled(crate(once_cell)) = 1.8.0 +Provides: bundled(crate(memoffset)) = 0.6.5 +Provides: bundled(crate(once_cell)) = 1.9.0 Provides: bundled(crate(openssl)) = 0.10.38 -Provides: bundled(crate(openssl-sys)) = 0.9.71 +Provides: bundled(crate(openssl-sys)) = 0.9.72 Provides: bundled(crate(parking_lot)) = 0.11.2 Provides: bundled(crate(parking_lot_core)) = 0.8.5 Provides: bundled(crate(paste)) = 0.1.18 Provides: bundled(crate(paste-impl)) = 0.1.18 Provides: bundled(crate(pin-project-lite)) = 0.2.7 -Provides: bundled(crate(pkg-config)) = 0.3.22 +Provides: bundled(crate(pkg-config)) = 0.3.24 Provides: bundled(crate(ppv-lite86)) = 0.2.15 Provides: bundled(crate(proc-macro-hack)) = 0.5.19 -Provides: bundled(crate(proc-macro2)) = 1.0.32 +Provides: bundled(crate(proc-macro2)) = 1.0.34 Provides: bundled(crate(pwdchan)) = 0.1.0 Provides: bundled(crate(quote)) = 1.0.10 Provides: bundled(crate(rand)) = 0.8.4 @@ -122,21 +122,21 @@ Provides: bundled(crate(rand_core)) = 0.6.3 Provides: bundled(crate(rand_hc)) = 0.3.1 Provides: bundled(crate(redox_syscall)) = 0.2.10 Provides: bundled(crate(remove_dir_all)) = 0.5.3 -Provides: bundled(crate(ryu)) = 1.0.5 +Provides: bundled(crate(ryu)) = 1.0.9 Provides: bundled(crate(scopeguard)) = 1.1.0 -Provides: bundled(crate(serde)) = 1.0.130 -Provides: bundled(crate(serde_derive)) = 1.0.130 -Provides: bundled(crate(serde_json)) = 1.0.71 +Provides: bundled(crate(serde)) = 1.0.132 +Provides: bundled(crate(serde_derive)) = 1.0.132 +Provides: bundled(crate(serde_json)) = 1.0.73 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 Provides: bundled(crate(smallvec)) = 1.7.0 Provides: bundled(crate(strsim)) = 0.8.0 -Provides: bundled(crate(syn)) = 1.0.81 +Provides: bundled(crate(syn)) = 1.0.82 Provides: bundled(crate(synstructure)) = 0.12.6 Provides: bundled(crate(tempfile)) = 3.2.0 Provides: bundled(crate(textwrap)) = 0.11.0 -Provides: bundled(crate(tokio)) = 1.14.0 -Provides: bundled(crate(tokio-macros)) = 1.6.0 +Provides: bundled(crate(tokio)) = 1.15.0 +Provides: bundled(crate(tokio-macros)) = 1.7.0 Provides: bundled(crate(toml)) = 0.5.8 Provides: bundled(crate(unicode-width)) = 0.1.9 Provides: bundled(crate(unicode-xid)) = 0.2.2 @@ -712,6 +712,18 @@ exit 0 %endif %changelog +* Thu Dec 16 2021 Mark Reynolds - 2.0.12-1 +- Bump version to 2.0.12-1 +- Issue 4299 - UI LDAP editor - add "edit" and "rename" functionality +- Issue 4962 - Fix various UI bugs - Database and Backups (#5044) +- Issue 5046 - BUG - update concread (#5047) +- Issue 5043 - BUG - Result must be used compiler warning (#5045) +- Issue 4165 - Don't apply RootDN access control restrictions to UNIX connections +- Issue 4931 - RFE: dsidm - add creation of service accounts +- Issue 5024 - BUG - windows ro replica sigsegv (#5027) +- Issue 5020 - BUG - improve clarity of posix win sync logging (#5021) +- Issue 5008 - If a non critical plugin can not be loaded/initialized, bootstrap should succeeds (#5009) + * Mon Nov 22 2021 Mark Reynolds - 2.0.11-1 - Bump version to 2.0.11 - Issue 4962 - Fix various UI bugs - Settings and Monitor (#5016) diff --git a/sources b/sources index 1d4ddf2..12d8e74 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (389-ds-base-2.0.11.tar.bz2) = 23869b5ec8d0fd2774682b5c2dfd1d60dc99a50f5817e25dca50f1eb62d2553f11f7249c7751d1e010bf0c1a0380ec08f56fc5b3f7d66f439a6e350913912318 SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 +SHA512 (389-ds-base-2.0.12.tar.bz2) = add9ad43f9ab50e8ab10bba2a2daef3b201adae0367a28b9814f17c6130a8cb6287391352951a6528c9a16d8139133c8b8ac08bc9436b587c8790ac5b30d0cff From c532bb9b68ef2440ec1ac4c51a94f91ffd80d273 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 19 Jan 2022 19:09:45 +0000 Subject: [PATCH 034/125] - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index b256405..199e67e 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -54,7 +54,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.0.12 -Release: %{?relprefix}1%{?prerel}%{?dist} +Release: %{?relprefix}1%{?prerel}%{?dist}.1 License: GPLv3+ URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -712,6 +712,9 @@ exit 0 %endif %changelog +* Wed Jan 19 2022 Fedora Release Engineering - 2.0.12-1.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + * Thu Dec 16 2021 Mark Reynolds - 2.0.12-1 - Bump version to 2.0.12-1 - Issue 4299 - UI LDAP editor - add "edit" and "rename" functionality From 0074e3f5ba449871ebeb53e1cb67aab0648e7e15 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Mon, 24 Jan 2022 13:58:17 -0500 Subject: [PATCH 035/125] Bump version to 2.0.13 Issue 5132 - Update Rust crate lru to fix CVE Issue 3555 - UI - fix audit issue with npm nanoid Issue 4299 - UI - Add ACI editing features Issue 4299 - UI - LDAP editor - add "edit" and "rename" functionality Issue 5127 - run restorecon on /dev/shm at server startup Issue 5124 - dscontainer fails to create an instance Issue 4312 - fix compiler warnings Issue 5115 - AttributeError: type object 'build_manpages' has no attribute 'build_manpages' Issue 4312 - performance search rate: contention on global monitoring counters (#4940) Issue 5105 - During a bind, if the target entry is not reachable the operation may complete without sending result (#5107) Issue 5095 - sync-repl with openldap may send truncated syncUUID (#5099) Issue 3584 - Add is_fips check to password tests (#5100) Issue 5074 - retro changelog cli updates (#5075) Issue 4994 - Revert retrocl dependency workaround (#4995) --- .gitignore | 1 + 389-ds-base.spec | 65 +++++++++++++++++++++++++++++++----------------- sources | 2 +- 3 files changed, 44 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index f960344..03ac955 100644 --- a/.gitignore +++ b/.gitignore @@ -209,3 +209,4 @@ /389-ds-base-2.0.10.tar.bz2 /389-ds-base-2.0.11.tar.bz2 /389-ds-base-2.0.12.tar.bz2 +/389-ds-base-2.0.13.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 199e67e..e9151af 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -53,8 +53,8 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.0.12 -Release: %{?relprefix}1%{?prerel}%{?dist}.1 +Version: 2.0.13 +Release: %{?relprefix}1%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -76,31 +76,32 @@ Provides: bundled(crate(cbindgen)) = 0.9.1 Provides: bundled(crate(cc)) = 1.0.72 Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 2.34.0 -Provides: bundled(crate(concread)) = 0.2.20 +Provides: bundled(crate(concread)) = 0.2.21 Provides: bundled(crate(crossbeam)) = 0.8.1 -Provides: bundled(crate(crossbeam-channel)) = 0.5.1 +Provides: bundled(crate(crossbeam-channel)) = 0.5.2 Provides: bundled(crate(crossbeam-deque)) = 0.8.1 -Provides: bundled(crate(crossbeam-epoch)) = 0.9.5 -Provides: bundled(crate(crossbeam-queue)) = 0.3.2 -Provides: bundled(crate(crossbeam-utils)) = 0.8.5 +Provides: bundled(crate(crossbeam-epoch)) = 0.9.6 +Provides: bundled(crate(crossbeam-queue)) = 0.3.3 +Provides: bundled(crate(crossbeam-utils)) = 0.8.6 Provides: bundled(crate(entryuuid)) = 0.1.0 Provides: bundled(crate(entryuuid_syntax)) = 0.1.0 +Provides: bundled(crate(fastrand)) = 1.7.0 Provides: bundled(crate(fernet)) = 0.1.4 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 -Provides: bundled(crate(getrandom)) = 0.2.3 +Provides: bundled(crate(getrandom)) = 0.2.4 Provides: bundled(crate(hashbrown)) = 0.11.2 Provides: bundled(crate(hermit-abi)) = 0.1.19 Provides: bundled(crate(instant)) = 0.1.12 Provides: bundled(crate(itoa)) = 1.0.1 Provides: bundled(crate(jobserver)) = 0.1.24 Provides: bundled(crate(lazy_static)) = 1.4.0 -Provides: bundled(crate(libc)) = 0.2.112 +Provides: bundled(crate(libc)) = 0.2.113 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 Provides: bundled(crate(lock_api)) = 0.4.5 Provides: bundled(crate(log)) = 0.4.14 -Provides: bundled(crate(lru)) = 0.6.6 +Provides: bundled(crate(lru)) = 0.7.2 Provides: bundled(crate(memoffset)) = 0.6.5 Provides: bundled(crate(once_cell)) = 1.9.0 Provides: bundled(crate(openssl)) = 0.10.38 @@ -109,13 +110,13 @@ Provides: bundled(crate(parking_lot)) = 0.11.2 Provides: bundled(crate(parking_lot_core)) = 0.8.5 Provides: bundled(crate(paste)) = 0.1.18 Provides: bundled(crate(paste-impl)) = 0.1.18 -Provides: bundled(crate(pin-project-lite)) = 0.2.7 +Provides: bundled(crate(pin-project-lite)) = 0.2.8 Provides: bundled(crate(pkg-config)) = 0.3.24 -Provides: bundled(crate(ppv-lite86)) = 0.2.15 +Provides: bundled(crate(ppv-lite86)) = 0.2.16 Provides: bundled(crate(proc-macro-hack)) = 0.5.19 -Provides: bundled(crate(proc-macro2)) = 1.0.34 +Provides: bundled(crate(proc-macro2)) = 1.0.36 Provides: bundled(crate(pwdchan)) = 0.1.0 -Provides: bundled(crate(quote)) = 1.0.10 +Provides: bundled(crate(quote)) = 1.0.15 Provides: bundled(crate(rand)) = 0.8.4 Provides: bundled(crate(rand_chacha)) = 0.3.1 Provides: bundled(crate(rand_core)) = 0.6.3 @@ -124,16 +125,16 @@ Provides: bundled(crate(redox_syscall)) = 0.2.10 Provides: bundled(crate(remove_dir_all)) = 0.5.3 Provides: bundled(crate(ryu)) = 1.0.9 Provides: bundled(crate(scopeguard)) = 1.1.0 -Provides: bundled(crate(serde)) = 1.0.132 -Provides: bundled(crate(serde_derive)) = 1.0.132 -Provides: bundled(crate(serde_json)) = 1.0.73 +Provides: bundled(crate(serde)) = 1.0.135 +Provides: bundled(crate(serde_derive)) = 1.0.135 +Provides: bundled(crate(serde_json)) = 1.0.78 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 -Provides: bundled(crate(smallvec)) = 1.7.0 +Provides: bundled(crate(smallvec)) = 1.8.0 Provides: bundled(crate(strsim)) = 0.8.0 -Provides: bundled(crate(syn)) = 1.0.82 +Provides: bundled(crate(syn)) = 1.0.86 Provides: bundled(crate(synstructure)) = 0.12.6 -Provides: bundled(crate(tempfile)) = 3.2.0 +Provides: bundled(crate(tempfile)) = 3.3.0 Provides: bundled(crate(textwrap)) = 0.11.0 Provides: bundled(crate(tokio)) = 1.15.0 Provides: bundled(crate(tokio-macros)) = 1.7.0 @@ -143,13 +144,13 @@ Provides: bundled(crate(unicode-xid)) = 0.2.2 Provides: bundled(crate(uuid)) = 0.8.2 Provides: bundled(crate(vcpkg)) = 0.2.15 Provides: bundled(crate(vec_map)) = 0.8.2 -Provides: bundled(crate(version_check)) = 0.9.3 +Provides: bundled(crate(version_check)) = 0.9.4 Provides: bundled(crate(wasi)) = 0.10.2+wasi_snapshot_preview1 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 -Provides: bundled(crate(zeroize)) = 1.4.3 -Provides: bundled(crate(zeroize_derive)) = 1.2.2 +Provides: bundled(crate(zeroize)) = 1.5.0 +Provides: bundled(crate(zeroize_derive)) = 1.3.1 ##### Bundled cargo crates list - END ##### BuildRequires: nspr-devel @@ -633,6 +634,7 @@ exit 0 %{_sbindir}/openldap_to_ds %{_mandir}/man8/openldap_to_ds.8.gz %{_libexecdir}/%{pkgname}/ds_systemd_ask_password_acl +%{_libexecdir}/%{pkgname}/ds_selinux_restorecon.sh %{_mandir}/man5/99user.ldif.5.gz %{_mandir}/man5/certmap.conf.5.gz %{_mandir}/man5/slapd-collations.conf.5.gz @@ -712,6 +714,23 @@ exit 0 %endif %changelog +* Mon Jan 24 2022 Mark Reynolds - 2.0.13-1 +- Bump version to 2.0.13 +- Issue 5132 - Update Rust crate lru to fix CVE +- Issue 3555 - UI - fix audit issue with npm nanoid +- Issue 4299 - UI - Add ACI editing features +- Issue 4299 - UI - LDAP editor - add "edit" and "rename" functionality +- Issue 5127 - run restorecon on /dev/shm at server startup +- Issue 5124 - dscontainer fails to create an instance +- Issue 4312 - fix compiler warnings +- Issue 5115 - AttributeError: type object 'build_manpages' has no attribute 'build_manpages' +- Issue 4312 - performance search rate: contention on global monitoring counters (#4940) +- Issue 5105 - During a bind, if the target entry is not reachable the operation may complete without sending result (#5107) +- Issue 5095 - sync-repl with openldap may send truncated syncUUID (#5099) +- Issue 3584 - Add is_fips check to password tests (#5100) +- Issue 5074 - retro changelog cli updates (#5075) +- Issue 4994 - Revert retrocl dependency workaround (#4995) + * Wed Jan 19 2022 Fedora Release Engineering - 2.0.12-1.1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild diff --git a/sources b/sources index 12d8e74..7786e23 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ +SHA512 (389-ds-base-2.0.13.tar.bz2) = ab9429b391b32d4a09ea5fb0ce15fcf31f7c13e781588ce5587a0ed169959938ce59bff857dbf58bb9413208f6c35792c127cad27c7aca6aa53ef66ef4c36196 SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 -SHA512 (389-ds-base-2.0.12.tar.bz2) = add9ad43f9ab50e8ab10bba2a2daef3b201adae0367a28b9814f17c6130a8cb6287391352951a6528c9a16d8139133c8b8ac08bc9436b587c8790ac5b30d0cff From 0dd8948e7cb0dc45d3e98928c51deb57ac5a11d8 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Tue, 25 Jan 2022 14:40:31 +0100 Subject: [PATCH 036/125] Use Rust 2018 edition for concread on EL8 --- 389-ds-base.spec | 5 +++++ concread-use-2018-edition.patch | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 concread-use-2018-edition.patch diff --git a/389-ds-base.spec b/389-ds-base.spec index e9151af..efd7973 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -271,6 +271,11 @@ Source2: %{name}-devel.README Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download/%{jemalloc_ver}/%{jemalloc_name}-%{jemalloc_ver}.tar.bz2 %endif +# Remove this after rust-1.56 lands in repos +%if 0%{?rhel} == 8 +Patch0: concread-use-2018-edition.patch +%endif + %description 389 Directory Server is an LDAPv3 compliant server. The base package includes the LDAP server and command line utilities for server administration. diff --git a/concread-use-2018-edition.patch b/concread-use-2018-edition.patch new file mode 100644 index 0000000..c09bf22 --- /dev/null +++ b/concread-use-2018-edition.patch @@ -0,0 +1,19 @@ +diff '--color=auto' -Nur 389-ds-base-2.0.13.orig/vendor/concread/.cargo-checksum.json 389-ds-base-2.0.13/vendor/concread/.cargo-checksum.json +--- 389-ds-base-2.0.13.orig/vendor/concread/.cargo-checksum.json 2022-01-25 14:30:32.886759088 +0100 ++++ 389-ds-base-2.0.13/vendor/concread/.cargo-checksum.json 2022-01-25 14:30:59.144053695 +0100 +@@ -1 +1 @@ +-{"files":{"CACHE.md":"258e585db81ee9582e1f7e7246026b49b3f617dae4459ec52437024b00ba5dff","CODE_OF_CONDUCT.md":"f32933e0090f012d336e8b2f2301967e8a27cbc896aa3860811a944d05b58964","CONTRIBUTORS.md":"1edff6e840fc50412ac698cd7e5ebe660574760b492d4febe94feb0c066b062f","Cargo.toml":"088f1aa3051cfc8b7861c3eed146e9a5d936e68edaaa85d04054475a8d24224e","LICENSE.md":"32ee9dbf6196874fc9d406c54a888a6c4cbb9aa4a7f35b46befeaff43a78fe85","Makefile":"de35f7df990b5c047785da63ad560ecadac746bf19d2ab8457fc2ba0224ad46a","README.md":"f70aafccb01764a1aa4d83e3f7fbeab245f7bfa3d3bafecea9614439ff97b487","asan_test.sh":"7355f359e34a6198e895c18fbb616fa45a44666c0a82787f704454e83687be4c","benches/arccache.rs":"6f1f23abb2b577c21aa7ee3d4bd7413fcb49a60d59b1220e1afaeda99f4e6b0e","benches/hashmap_benchmark.rs":"306d085f88f7ce40b8709aff37375482f8edb3c891cbb3da5d9d70a95c2d6cca","src/arcache/ll.rs":"2bd7eb2e73f80112765a0e1792edc27b58269dfc419498ef02ad68fb63141abc","src/arcache/mod.rs":"5911e162123373e241a6bf2b6355cda5480f9ff2f3fa2901c08a7010ad82c00a","src/arcache/traits.rs":"09ea380ea38efe3e35c2036a2ae233388a5367706d155c4aa3c9234d03eef8ea","src/bptree/asynch.rs":"69eff00e05b7b85a12468304374422b2ce1d8598b50918b0efe6eb77036249a4","src/bptree/impl.rs":"b54a7d53e23bf0ff23ebd43ea7ab19708cc383766706051f207bfb62f5e64793","src/bptree/mod.rs":"5e8d2004865dd2064a550070ca3b49a1975ac877cd6749f035806335f3a393a1","src/cowcell/asynch.rs":"04a1c424c083625f92524547bd21d20aadec4d20e2eedfff4db90f2aef920d6c","src/cowcell/mod.rs":"621c243c301f80ebcf65a636489c9450e22940bc5bc9cfb1e5db7943f4e3543f","src/ebrcell/mod.rs":"cf2a2042ac41039ca5fb4212f1fec58bfa1695b88f9c7f7864e01dafa84ccf35","src/hashmap/asynch.rs":"f8418906a23cf06e73fb1330988da4ab0f53ae58c4d5fd58ab5105f8fcbcc414","src/hashmap/impl.rs":"9695dcfde2fd6b27766adddd225d6390a44cc757ebf9b2f5879f6f1b9a7f29dc","src/hashmap/mod.rs":"bbd33d7f50a28b9a1254d4aaed72f5122e9f01e68e0c43331f90582a17056657","src/internals/bptree/cursor.rs":"83b250db73eb09e1cf7367e8c33700e9b9659695fd565e813549b7f20f9ba777","src/internals/bptree/iter.rs":"dfcf50a3ff5b052dc719b2c68b0bafcfdd0c0c8d8173f3e227a7dd6c8f1be773","src/internals/bptree/macros.rs":"568826a43238474d1f92f7dbf1671690790b35a3b8c88d0d6c5dd35aca54857a","src/internals/bptree/mod.rs":"67ba38e16d96c0d239b72cf0b7be5f27a7a82a29e3a31afc5477175f92b4c57f","src/internals/bptree/node.rs":"afe7217f187d5d7a086dab3bc6fadbae0456e4f8518aa12153f877590380d585","src/internals/bptree/states.rs":"da1ce34cbe6bc449e9e5172ed1fd2a296f2ac197b17ca855f2d40aada7d32a63","src/internals/hashmap/cursor.rs":"7d9c47d7e31e984670cd2161be54475dc468df5b00df26dc89f9848eb1a587ea","src/internals/hashmap/iter.rs":"f02f372e34d2af685eebbcc4db71cc5985c904c1bbd14dd13f48921ea58e5c5f","src/internals/hashmap/macros.rs":"f1236cd794e0e8d7ee2e89428b60c1c3437f34e6be32217de2d61dddce7c6b90","src/internals/hashmap/mod.rs":"ffa693b755ef92da14b001e08a1154e263bd9540ae993d4f79ddf5979e2dcbd6","src/internals/hashmap/node.rs":"7d86f28969185f28de91b2c816990f231adb2c5985c4cbf0efcfdd07ae94ef9a","src/internals/hashmap/simd.rs":"4ef1fd5a0b6218823eafd727b7ff1a738dfc0c59d1e3afbb2ace8f0513967bf3","src/internals/hashmap/states.rs":"9366f29bdfaeb3ee9744268b5b2283209f791a260045312e8489515f8bd3900a","src/internals/lincowcell/mod.rs":"9caa826c9b6758e79d90c10c5dad4bfeaf46a8773784537750814f700fa13428","src/internals/lincowcell_async/mod.rs":"c38ec2efbd02219ebec68aa0b31e824262941093d1cfb3e441e6c98b375df6ab","src/internals/mod.rs":"18db9c4cb457fd06a85d668a69bd290ad13a7fae971a926015daf148424e19cc","src/lib.rs":"ce9ba3daaa0f8e9ee2e61a61e8134cf4d241522ca30909d6933f37075bd3e549","src/threadcache/mod.rs":"43328459ade4c1abb8174ded0f77f264a3931dbae82991e70765747d519882c6","src/unsound.rs":"60ed0cad28434083fe7cccd17af4995381cdd9e4dfb685da5b14e802150074fb","src/unsound2.rs":"02b72de153d9f5fac901ea59a9ef3d1ce9b8e3e18bc80d9d19b2d6aa8c7b5022","src/unsound3.rs":"019ba913656558f91e9a160cbc05fe78b1e4a44acc1bb74d38281ebea71edd77","src/utils.rs":"d07e962bab8936d5396bc7542af7ce2812504358c4e68dd2322f521c066476cd","static/arc_1.png":"94ff0d24a15d5feda27f0316f8a1ca82291f816d8705b1d0743e03e39791bbe2","static/arc_2.png":"9932b1b8e7f44a833f4ffdb710af984199711d6c9c3349a51ab122a22d0ebbe7","static/cow_1.png":"f340e6d143589efdbbfb8c62c4fdddc97dcb213e0cff2c04f7f93bf380fd36f3","static/cow_2.png":"20f550b67109cd042170da95ff6faecda043d333c55f48ec19ced8bb9dce1eee","static/cow_3.png":"137a24e70196bd628522733b55ed1d92cf3f9936be39d9f0864201424a25bd88","static/cow_arc_1.png":"97a45ad9b55721381aff07e921fedc863209629a4ae4f8c160cad7059ecad795","static/cow_arc_2.png":"178e681ba6e2e0a33a7b6a08b9895b628dad74cda56e9e25b59288376e9f01ce","static/cow_arc_3.png":"37dac32e173b14faf37b502a110ab1e4f47f30710cfc65714b9fef0b79f64307","static/cow_arc_4.png":"f4b962b9ccd9b765523f50b752b9bb85525cbf8a4e6cdc15048f9363579e6719","static/cow_arc_5.png":"d6b122ec844d0d19312cc57667769f2955bc7b8667449b1c13a7359a4debc8a2","static/cow_arc_6.png":"847018f7f5e0813b26c2b636a2ca8549f475339de24a21dd2e0e21d90dbd77f1","static/cow_arc_7.png":"3df9b3d1153c7b1de52a30a46e9bdba75e2412ad51ef158437a356f16b3bd1be","static/cow_arc_8.png":"68f405191ef400b8f854102e98fac92ddd31c274bcff7739e47483a39dba9612","static/cow_arc_9.png":"eb60637be4fb951ac54a1e3de0fd33e0bb2f5a4d19c3519bd8f23c02b8fc240d"},"package":"dcc9816f5ac93ebd51c37f7f9a6bf2b40dfcd42978ad2aea5d542016e9244cf6"} +\ No newline at end of file ++{"files":{"CACHE.md":"258e585db81ee9582e1f7e7246026b49b3f617dae4459ec52437024b00ba5dff","CODE_OF_CONDUCT.md":"f32933e0090f012d336e8b2f2301967e8a27cbc896aa3860811a944d05b58964","CONTRIBUTORS.md":"1edff6e840fc50412ac698cd7e5ebe660574760b492d4febe94feb0c066b062f","Cargo.toml":"188257f3b5f5cba5f526fd3647ce8c5a4c75a70dc95fbedf665a2cf2755aee6d","LICENSE.md":"32ee9dbf6196874fc9d406c54a888a6c4cbb9aa4a7f35b46befeaff43a78fe85","Makefile":"de35f7df990b5c047785da63ad560ecadac746bf19d2ab8457fc2ba0224ad46a","README.md":"f70aafccb01764a1aa4d83e3f7fbeab245f7bfa3d3bafecea9614439ff97b487","asan_test.sh":"7355f359e34a6198e895c18fbb616fa45a44666c0a82787f704454e83687be4c","benches/arccache.rs":"6f1f23abb2b577c21aa7ee3d4bd7413fcb49a60d59b1220e1afaeda99f4e6b0e","benches/hashmap_benchmark.rs":"306d085f88f7ce40b8709aff37375482f8edb3c891cbb3da5d9d70a95c2d6cca","src/arcache/ll.rs":"2bd7eb2e73f80112765a0e1792edc27b58269dfc419498ef02ad68fb63141abc","src/arcache/mod.rs":"5911e162123373e241a6bf2b6355cda5480f9ff2f3fa2901c08a7010ad82c00a","src/arcache/traits.rs":"09ea380ea38efe3e35c2036a2ae233388a5367706d155c4aa3c9234d03eef8ea","src/bptree/asynch.rs":"69eff00e05b7b85a12468304374422b2ce1d8598b50918b0efe6eb77036249a4","src/bptree/impl.rs":"b54a7d53e23bf0ff23ebd43ea7ab19708cc383766706051f207bfb62f5e64793","src/bptree/mod.rs":"5e8d2004865dd2064a550070ca3b49a1975ac877cd6749f035806335f3a393a1","src/cowcell/asynch.rs":"04a1c424c083625f92524547bd21d20aadec4d20e2eedfff4db90f2aef920d6c","src/cowcell/mod.rs":"621c243c301f80ebcf65a636489c9450e22940bc5bc9cfb1e5db7943f4e3543f","src/ebrcell/mod.rs":"cf2a2042ac41039ca5fb4212f1fec58bfa1695b88f9c7f7864e01dafa84ccf35","src/hashmap/asynch.rs":"f8418906a23cf06e73fb1330988da4ab0f53ae58c4d5fd58ab5105f8fcbcc414","src/hashmap/impl.rs":"9695dcfde2fd6b27766adddd225d6390a44cc757ebf9b2f5879f6f1b9a7f29dc","src/hashmap/mod.rs":"bbd33d7f50a28b9a1254d4aaed72f5122e9f01e68e0c43331f90582a17056657","src/internals/bptree/cursor.rs":"83b250db73eb09e1cf7367e8c33700e9b9659695fd565e813549b7f20f9ba777","src/internals/bptree/iter.rs":"dfcf50a3ff5b052dc719b2c68b0bafcfdd0c0c8d8173f3e227a7dd6c8f1be773","src/internals/bptree/macros.rs":"568826a43238474d1f92f7dbf1671690790b35a3b8c88d0d6c5dd35aca54857a","src/internals/bptree/mod.rs":"67ba38e16d96c0d239b72cf0b7be5f27a7a82a29e3a31afc5477175f92b4c57f","src/internals/bptree/node.rs":"afe7217f187d5d7a086dab3bc6fadbae0456e4f8518aa12153f877590380d585","src/internals/bptree/states.rs":"da1ce34cbe6bc449e9e5172ed1fd2a296f2ac197b17ca855f2d40aada7d32a63","src/internals/hashmap/cursor.rs":"7d9c47d7e31e984670cd2161be54475dc468df5b00df26dc89f9848eb1a587ea","src/internals/hashmap/iter.rs":"f02f372e34d2af685eebbcc4db71cc5985c904c1bbd14dd13f48921ea58e5c5f","src/internals/hashmap/macros.rs":"f1236cd794e0e8d7ee2e89428b60c1c3437f34e6be32217de2d61dddce7c6b90","src/internals/hashmap/mod.rs":"ffa693b755ef92da14b001e08a1154e263bd9540ae993d4f79ddf5979e2dcbd6","src/internals/hashmap/node.rs":"7d86f28969185f28de91b2c816990f231adb2c5985c4cbf0efcfdd07ae94ef9a","src/internals/hashmap/simd.rs":"4ef1fd5a0b6218823eafd727b7ff1a738dfc0c59d1e3afbb2ace8f0513967bf3","src/internals/hashmap/states.rs":"9366f29bdfaeb3ee9744268b5b2283209f791a260045312e8489515f8bd3900a","src/internals/lincowcell/mod.rs":"9caa826c9b6758e79d90c10c5dad4bfeaf46a8773784537750814f700fa13428","src/internals/lincowcell_async/mod.rs":"c38ec2efbd02219ebec68aa0b31e824262941093d1cfb3e441e6c98b375df6ab","src/internals/mod.rs":"18db9c4cb457fd06a85d668a69bd290ad13a7fae971a926015daf148424e19cc","src/lib.rs":"ce9ba3daaa0f8e9ee2e61a61e8134cf4d241522ca30909d6933f37075bd3e549","src/threadcache/mod.rs":"43328459ade4c1abb8174ded0f77f264a3931dbae82991e70765747d519882c6","src/unsound.rs":"60ed0cad28434083fe7cccd17af4995381cdd9e4dfb685da5b14e802150074fb","src/unsound2.rs":"02b72de153d9f5fac901ea59a9ef3d1ce9b8e3e18bc80d9d19b2d6aa8c7b5022","src/unsound3.rs":"019ba913656558f91e9a160cbc05fe78b1e4a44acc1bb74d38281ebea71edd77","src/utils.rs":"d07e962bab8936d5396bc7542af7ce2812504358c4e68dd2322f521c066476cd","static/arc_1.png":"94ff0d24a15d5feda27f0316f8a1ca82291f816d8705b1d0743e03e39791bbe2","static/arc_2.png":"9932b1b8e7f44a833f4ffdb710af984199711d6c9c3349a51ab122a22d0ebbe7","static/cow_1.png":"f340e6d143589efdbbfb8c62c4fdddc97dcb213e0cff2c04f7f93bf380fd36f3","static/cow_2.png":"20f550b67109cd042170da95ff6faecda043d333c55f48ec19ced8bb9dce1eee","static/cow_3.png":"137a24e70196bd628522733b55ed1d92cf3f9936be39d9f0864201424a25bd88","static/cow_arc_1.png":"97a45ad9b55721381aff07e921fedc863209629a4ae4f8c160cad7059ecad795","static/cow_arc_2.png":"178e681ba6e2e0a33a7b6a08b9895b628dad74cda56e9e25b59288376e9f01ce","static/cow_arc_3.png":"37dac32e173b14faf37b502a110ab1e4f47f30710cfc65714b9fef0b79f64307","static/cow_arc_4.png":"f4b962b9ccd9b765523f50b752b9bb85525cbf8a4e6cdc15048f9363579e6719","static/cow_arc_5.png":"d6b122ec844d0d19312cc57667769f2955bc7b8667449b1c13a7359a4debc8a2","static/cow_arc_6.png":"847018f7f5e0813b26c2b636a2ca8549f475339de24a21dd2e0e21d90dbd77f1","static/cow_arc_7.png":"3df9b3d1153c7b1de52a30a46e9bdba75e2412ad51ef158437a356f16b3bd1be","static/cow_arc_8.png":"68f405191ef400b8f854102e98fac92ddd31c274bcff7739e47483a39dba9612","static/cow_arc_9.png":"eb60637be4fb951ac54a1e3de0fd33e0bb2f5a4d19c3519bd8f23c02b8fc240d"},"package":"dcc9816f5ac93ebd51c37f7f9a6bf2b40dfcd42978ad2aea5d542016e9244cf6"} +diff '--color=auto' -Nur 389-ds-base-2.0.13.orig/vendor/concread/Cargo.toml 389-ds-base-2.0.13/vendor/concread/Cargo.toml +--- 389-ds-base-2.0.13.orig/vendor/concread/Cargo.toml 2022-01-25 14:30:32.883759169 +0100 ++++ 389-ds-base-2.0.13/vendor/concread/Cargo.toml 2022-01-25 14:30:44.786439411 +0100 +@@ -10,7 +10,7 @@ + # See Cargo.toml.orig for the original contents. + + [package] +-edition = "2021" ++edition = "2018" + name = "concread" + version = "0.2.21" + authors = ["William Brown "] From 1611a2fcbfe0dac4917a97cd81ea52aae5967bbc Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Thu, 27 Jan 2022 11:21:43 -0800 Subject: [PATCH 037/125] Backport #5141, fix startup when directory doesn't exist (#2047323) --- 389-ds-base.spec | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index efd7973..27ee819 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -54,7 +54,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.0.13 -Release: %{?relprefix}1%{?prerel}%{?dist} +Release: %{?relprefix}2%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -276,6 +276,11 @@ Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download Patch0: concread-use-2018-edition.patch %endif +# https://bugzilla.redhat.com/show_bug.cgi?id=2047323 +# https://github.com/389ds/389-ds-base/pull/5141 +# Don't fail on startup if a directory we try to restorecon doesn't exist +Patch1: 0001-ds_selinux_restorecon.sh-always-exit-0.patch + %description 389 Directory Server is an LDAPv3 compliant server. The base package includes the LDAP server and command line utilities for server administration. @@ -719,6 +724,9 @@ exit 0 %endif %changelog +* Thu Jan 27 2022 Adam Williamson - 2.0.13-2 +- Backport PR#5141 to fix startup when a directory doesn't exist (#2047323) + * Mon Jan 24 2022 Mark Reynolds - 2.0.13-1 - Bump version to 2.0.13 - Issue 5132 - Update Rust crate lru to fix CVE From 2ad9ed3121c11501dec6838211164e4f6a2971b0 Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Thu, 27 Jan 2022 12:31:35 -0800 Subject: [PATCH 038/125] Add patch file missing from last commit --- ..._selinux_restorecon.sh-always-exit-0.patch | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 0001-ds_selinux_restorecon.sh-always-exit-0.patch diff --git a/0001-ds_selinux_restorecon.sh-always-exit-0.patch b/0001-ds_selinux_restorecon.sh-always-exit-0.patch new file mode 100644 index 0000000..fd13034 --- /dev/null +++ b/0001-ds_selinux_restorecon.sh-always-exit-0.patch @@ -0,0 +1,33 @@ +From d858b6950e4e0946f8d18d1855923c8d0f89c858 Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Thu, 27 Jan 2022 11:07:26 -0800 +Subject: [PATCH] ds_selinux_restorecon.sh: always exit 0 + +We don't want to error out and give up on starting the service +if the restorecon fails - it might just be that the directory +doesn't exist and doesn't need restoring. Issue identified and +fix suggested by Simon Farnsworth. + +https://bugzilla.redhat.com/show_bug.cgi?id=2047323 + +Signed-off-by: Adam Williamson +--- + wrappers/ds_selinux_restorecon.sh.in | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/wrappers/ds_selinux_restorecon.sh.in b/wrappers/ds_selinux_restorecon.sh.in +index 063347de3..2d7386233 100644 +--- a/wrappers/ds_selinux_restorecon.sh.in ++++ b/wrappers/ds_selinux_restorecon.sh.in +@@ -29,5 +29,6 @@ then + exit 0 + fi + +-# Now run restorecon +-restorecon ${DS_HOME_DIR} ++# Now run restorecon, but don't die if it fails (could be that the ++# directory doesn't exist) ++restorecon ${DS_HOME_DIR} || : +-- +2.35.0.rc1 + From 04994aacbba891d4aecda0765d514503a6374b39 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Wed, 2 Feb 2022 13:52:00 -0500 Subject: [PATCH 039/125] Bump version to 2.1.0-1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue 4299 - UI - fix minor issues with ldap editor (table view) Issue 4299 - UI - fix minor issues with ldap editor Issue 5103 - UI - Add support for TPR to web console (#5111) Issue 2790 - RFE - set db home directory to /dev/shm by default Issue 5127 - ds_selinux_restorecon.sh: always exit 0 Issue 5135 - UI - Disk monitoring threshold does update properly Issue 5129 - BUG - Incorrect fn signature in add_index (#5130) Issue 5132 - Update Rust crate lru to fix CVE Issue 3555 - UI - fix audit issue with npm nanoid Issue 4299 - UI - Add ACI editing features Issue 5127 - run restorecon on /dev/shm at server startup Issue 5124 - dscontainer fails to create an instance Issue 5098 - Multiple issues around replication and CI test test_online_reinit_may_hang (#5109) Issue 4939 - Redesign LMDB import (#5071) Issue 5113 - Increase timestamp precision for development builds Issue 5115 - AttributeError: type object 'build_manpages' has no attribute 'build_manpages' Issue 5117 - Revert skipif line from CI test (#5118) Issue 5102 - BUG - container may fail with bare uid/gid (#5110) Issue 5077 - UI - Add retrocl exclude attribute functionality (#5078) Issue 5105 - During a bind, if the target entry is not reachable the operation may complete without sending result (#5107) Issue 5074 - retro changelog cli updates (#5075) Issue 3584 - Add is_fips check to password tests (#5100) Issue 5095 - sync-repl with openldap may send truncated syncUUID (#5099) Issue 5032 - Fix OpenLDAP version check (#5091) Issue 5080 - BUG - multiple index types not handled in openldap migration (#5094) Issue 2929 - Fix github warnings Issue 5053 - Improve GitHub Actions debugging Issue 5088 - dsctl dblib broken because of a merge issue (#5089) Issue 5079 - BUG - multiple ways to specific primary (#5087) Issue 5085 - Race condition about snmp collator at startup (#5086) Issue 5082 - slugify: ModuleNotFoundError when running test cases Issue 4959 - Invalid /etc/hosts setup can cause isLocalHost to fail (#5003) Issue 5037 - in OpenQA changelog trimming can crashes (#5070) Issue 5049 - ns-slapd crash in replication/acceptance_test.py (#5063) Issue 4890 - Need cli to easely get simple performance statistics (#4891) Issue 5011 - test_replica_backup_and_restore random failure (#5066) Issue 4299 - UI LDAP editor - add "edit" and "rename" functionality Issue 5018 - RFE - openSUSE systemd hardening (#5019) Issue 4962 - Fix various UI bugs - Database and Backups (#5044) Issue 5055 - Improve core dump detection and collection in PR CI Issue 4994 - Revert retrocl dependency workaround (#4995) Issue 5046 - BUG - update concread (#5047) Issue 5043 - BUG - Result must be used compiler warning (#5045) Issue 4312 - performance search rate: contention on global monitoring counters (#4940) Issue 5034 - is_dbi contains an invalid debug message that trigger failure in import_tests (#5035) Issue 5029 - Unbind generates incorrent closed error message (#5030) Issue 4165 - Don't apply RootDN access control restrictions to UNIX connections Issue 4931 - RFE: dsidm - add creation of service accounts Issue 5024 - BUG - windows ro replica sigsegv (#5027) Issue 4758 - Add tests for WebUI Issue 5032 - OpenLDAP is not shipped with non-threaded version of libldap (#5033) Issue 5038 - BUG - dsconf tls may fail due to incorrect cert path (#5039) Issue 5020 - BUG - improve clarity of posix win sync logging (#5021) Issue 5011 - test_replica_backup_and_restore random failure (#5028) Issue 5025 - RFE - remove useless logging (#5026) Issue 5008 - If a non critical plugin can not be loaded/initialized, bootstrap should succeeds (#5009) Issue 4962 - Fix various UI bugs - Settings and Monitor (#5016) Issue 4976 - Failure in suites/import/import_test.py::test_fast_slow_import (#5017) Issue 5014 - UI - Add group creation to LDAP editor Issue 5006 - UI - LDAP editor tree not being properly updated Issue 4923 - issue about LMDB dbi versus txn handling (#4924) Issue 5001 - Update CI test for new availableSASLMechs attribute Issue 4959 - Invalid /etc/hosts setup can cause isLocalHost to fail. Issue 5001 - Fix next round of UI bugs: Issue 4962 - Fix various UI bugs - dsctl and ciphers (#5000) Issue 4734 - ldif2db - import of entry with no parent doesnt generate a warning Issue 4778 - [RFE] Schedule execution of "compactdb" at specific date/time Issue 4978 - use more portable python command for checking containers Issue 4990 - CI tests: improve robustness of fourwaymmr (#4991) Issue 4992 - BUG - slapd.socket container fix (#4993) Issue 4984 - BUG - pid file handling (#4986) Issue 4460 - python3-lib389 ignore the configuration parameters from … (#4906) Issue 4982 - BUG - missing inttypes.h (#4983) Issue 4758 - Add tests for WebUI Issue 4972 - gecos with IA5 introduces a compatibility issue with previous (#4981) Issue 4096 - Missing perl dependencies for logconv.pl Issue 4758 - Add tests for WebUI Issue 4978 - make installer robust Issue 4898 - Implement bdb to lmdb CLI migration tools (#4952) Issue 4976 - Failure in suites/import/import_test.py::test_fast_slow_import Issue 4973 - update snmp to use /run/dirsrv for PID file Issue 4973 - installer changes permissions on /run Issue 4959 - BUG - Invalid /etc/hosts setup can cause isLocalHost (#4960) Issue 4962 - Fix various UI bugs - Plugins (#4969) Issue 4092 - systemd-tmpfiles warnings Issue 4956 - Automember allows invalid regex, and does not log proper error Issue 4731 - Promoting/demoting a replica can crash the server Issue 4962 - Fix various UI bugs part 1 Issue 3584 - Fix PBKDF2_SHA256 hashing in FIPS mode (#4949) Issue 4943 - Fix csn generator to limit time skew drift (#4946) Issue 4954 - pytest is killed by OOM killer when the whole test suite is executed Issue 2790 - Set db home directory by default Issue 4299 - Merge LDAP editor code into Cockpit UI Issue 4938 - max_failure_count can be reached in dscontainer on slow machine with missing debug exception trace Issue 4921 - logconv.pl -j: Use of uninitialized value (#4922) Issue 4896 - improve CI tests report in case of SERVER_DOWN exception (#4897) Issue 4678 - RFE automatique disable of virtual attribute checking (#4918) Issue 4847 - BUG - potential deadlock in replica (#4936) Issue 4513 - fix ACI CI tests involving ip/hostname rules Issue 4925 - Performance ACI: targetfilter evaluation result can be reused (#4926) Issue 4916 - Memory leak in ldap-agent Issue 4656 DS Remove problematic language from CLI tools and UI (#4893) Issue 4908 - Updated several dsconf --help entries (typos, wrong descriptions, etc.) Issue 4912 - Account Policy plugin does not set the config entry DN Issue 4863 - typoes in logconv.pl Issue 4796 - Add support for nsslapd-state to CLI & UI Issue 4894 - IPA failure in ipa user-del --preserve (#4907) Issue 4914 - BUG - resolve duplicate stderr with clang (#4915) Issue 4912 - dsidm command crashing when account policy plugin is enabled Issue 4910 - db reindex corrupts RUV tombstone nsuiqueid index Issue 4577 - Add GitHub actions Issue 4901 - Add COPR integration Issue 4869 - Fix retro cl trimming misuse of monotonic/realtime clocks Issue 4889 - bdb lock deadlock while reindex/import vlv index (#4892) Issue 4773 - Extend CI tests for DNA interval assignment Issue 4887 - UI - fix minor regression from camelCase fixup Issue 4887 - UI - Update webpack.config.js and package.json Issue 4725 [RFE] DS - Update the password policy to support Temporary Password Rules (#4853) Issue 4149 - UI - Migrate the remaining components to PF4 Issue 4169 - Migrate Replication & Schema tabs to PF4 Issue 4875 - CLI - Add some verbosity to installer Issue 4884 - server crashes when dnaInterval attribute is set to zero Issue 4880: Revert removed_config_49298_test.py wrongly modified by issue 4699 (#4881) Issue 4699 - backend redesign phase 4 - db-mdb plugin implementation (#4716) Issue 4877 - RFE - EntryUUID to validate UUIDs on fixup (#4878) Issue 4872 - BUG - entryuuid enabled by default causes replication issues (#4876) Issue 4775 - Add entryuuid CLI and Fixup (#4776) Issue 4763 - Attribute Uniqueness Plugin uses wrong subtree on ModRDN (#4871) Issue 4851 - Typos in "dsconf pwpolicy set --help" (#4867) Issue 4096 - Missing perl dependencies for logconv.pl Issue 4736 - lib389 - fix regression in certutil error checking --- .gitignore | 1 + ...-Issue-4765-database-suffix-on-2-0-4.patch | 182 ------- 0001-dna_enable_interval.patch | 20 - ..._selinux_restorecon.sh-always-exit-0.patch | 33 -- 389-ds-base.spec | 454 ++++-------------- sources | 2 +- 6 files changed, 93 insertions(+), 599 deletions(-) delete mode 100644 0000-Issue-4765-database-suffix-on-2-0-4.patch delete mode 100644 0001-dna_enable_interval.patch delete mode 100644 0001-ds_selinux_restorecon.sh-always-exit-0.patch diff --git a/.gitignore b/.gitignore index 03ac955..c92b5f1 100644 --- a/.gitignore +++ b/.gitignore @@ -210,3 +210,4 @@ /389-ds-base-2.0.11.tar.bz2 /389-ds-base-2.0.12.tar.bz2 /389-ds-base-2.0.13.tar.bz2 +/389-ds-base-2.1.0.tar.bz2 diff --git a/0000-Issue-4765-database-suffix-on-2-0-4.patch b/0000-Issue-4765-database-suffix-on-2-0-4.patch deleted file mode 100644 index 19f3c10..0000000 --- a/0000-Issue-4765-database-suffix-on-2-0-4.patch +++ /dev/null @@ -1,182 +0,0 @@ -From bbdf47a9252040a5e42e015cb636380b88e9caa8 Mon Sep 17 00:00:00 2001 -From: Thierry Bordaz -Date: Tue, 18 May 2021 19:16:30 +0200 -Subject: [PATCH] Issue 4765 - database suffix unexpectdly changed from .db to - .db4 (#4766) - -* Issue 4765 - database suffix unexpectdly changed from .db to .db4 - -* Issue 4765 - database suffix unexpectdly changed from .db to .db4 - fix some compilation warnings ---- - ldap/servers/slapd/back-ldbm/back-ldbm.h | 9 --------- - ldap/servers/slapd/back-ldbm/db-bdb/bdb_config.c | 1 + - ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c | 5 +++++ - ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h | 11 +++++++++++ - ldap/servers/slapd/back-ldbm/dblayer.c | 9 +++++++++ - ldap/servers/slapd/back-ldbm/dblayer.h | 3 +++ - ldap/servers/slapd/back-ldbm/proto-back-ldbm.h | 2 ++ - ldap/servers/slapd/back-ldbm/vlv_srch.c | 2 +- - 8 files changed, 32 insertions(+), 10 deletions(-) - -diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h -index ddac99541..50b0996cb 100644 ---- a/ldap/servers/slapd/back-ldbm/back-ldbm.h -+++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h -@@ -66,14 +66,6 @@ typedef unsigned short u_int16_t; - - #define ID2ENTRY "id2entry" /* main db file name: ID2ENTRY+LDBM_SUFFIX */ - --#if 1000 * DB_VERSION_MAJOR + 100 * DB_VERSION_MINOR >= 5000 --#define LDBM_SUFFIX_OLD ".db4" --#define LDBM_SUFFIX ".db" --#else --#define LDBM_SUFFIX_OLD ".db3" --#define LDBM_SUFFIX ".db4" --#endif -- - #define MEGABYTE (1024 * 1024) - #define GIGABYTE (1024 * MEGABYTE) - -@@ -143,7 +135,6 @@ typedef unsigned short u_int16_t; - #define LDBM_VERSION_40 "Netscape-ldbm/4.0" - #define LDBM_VERSION_30 "Netscape-ldbm/3.0" - #define LDBM_VERSION_31 "Netscape-ldbm/3.1" --#define LDBM_FILENAME_SUFFIX LDBM_SUFFIX - #define DBVERSION_FILENAME "DBVERSION" - /* 0 here means to let the autotuning reset the value on first run */ - /* cache can't get any smaller than this (in bytes) */ -diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_config.c b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_config.c -index 65a2405d8..11a65e806 100644 ---- a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_config.c -+++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_config.c -@@ -125,6 +125,7 @@ int bdb_init(struct ldbminfo *li, config_info *config_array) - priv->dblayer_dbi_txn_abort_fn = &bdb_dbi_txn_abort; - priv->dblayer_get_entries_count_fn = &bdb_get_entries_count; - priv->dblayer_cursor_get_count_fn = &bdb_public_cursor_get_count; -+ priv->dblayer_get_db_suffix_fn = &bdb_public_get_db_suffix; - - bdb_fake_priv = *priv; /* Copy the callbaks for bdb_be() */ - return 0; -diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c -index 186c11cc3..455596a92 100644 ---- a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c -+++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c -@@ -6713,3 +6713,8 @@ bdb_public_cursor_get_count(dbi_cursor_t *cursor, dbi_recno_t *count) - int rc = cur->c_count(cur, count, 0); - return bdb_map_error(__FUNCTION__, rc); - } -+ -+const char *bdb_public_get_db_suffix(void) -+{ -+ return LDBM_FILENAME_SUFFIX; -+} -diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h -index 32430e2af..924656998 100644 ---- a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h -+++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h -@@ -13,6 +13,16 @@ - - #define BDB_CONFIG(li) ((bdb_config *)(li)->li_dblayer_config) - -+#if 1000 * DB_VERSION_MAJOR + 100 * DB_VERSION_MINOR >= 5000 -+#define LDBM_SUFFIX_OLD ".db4" -+#define LDBM_SUFFIX ".db" -+#else -+#define LDBM_SUFFIX_OLD ".db3" -+#define LDBM_SUFFIX ".db4" -+#endif -+ -+#define LDBM_FILENAME_SUFFIX LDBM_SUFFIX -+ - typedef struct bdb_db_env - { - DB_ENV *bdb_DB_ENV; -@@ -133,6 +143,7 @@ dblayer_dbi_txn_commit_fn_t bdb_dbi_txn_commit; - dblayer_dbi_txn_abort_fn_t bdb_dbi_txn_abort; - dblayer_get_entries_count_fn_t bdb_get_entries_count; - dblayer_cursor_get_count_fn_t bdb_public_cursor_get_count; -+dblayer_get_db_suffix_fn_t bdb_public_get_db_suffix; - - /* instance functions */ - int bdb_instance_cleanup(struct ldbm_instance *inst); -diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c -index c5ff6cba9..bf56df42a 100644 ---- a/ldap/servers/slapd/back-ldbm/dblayer.c -+++ b/ldap/servers/slapd/back-ldbm/dblayer.c -@@ -1370,3 +1370,12 @@ dblayer_pop_pvt_txn(void) - } - return; - } -+ -+const char * -+dblayer_get_db_suffix(Slapi_Backend *be) -+{ -+ struct ldbminfo *li = be ? (struct ldbminfo *)be->be_database->plg_private : NULL; -+ dblayer_private *prv = li ? (dblayer_private *)li->li_dblayer_private : NULL; -+ -+ return prv ? prv->dblayer_get_db_suffix_fn() : NULL; -+} -diff --git a/ldap/servers/slapd/back-ldbm/dblayer.h b/ldap/servers/slapd/back-ldbm/dblayer.h -index 99acfd1ab..051035f3f 100644 ---- a/ldap/servers/slapd/back-ldbm/dblayer.h -+++ b/ldap/servers/slapd/back-ldbm/dblayer.h -@@ -109,6 +109,7 @@ typedef int dblayer_dbi_txn_commit_fn_t(dbi_txn_t *txn); - typedef int dblayer_dbi_txn_abort_fn_t(dbi_txn_t *txn); - typedef int dblayer_get_entries_count_fn_t(dbi_db_t *db, int *count); - typedef int dblayer_cursor_get_count_fn_t(dbi_cursor_t *cursor, dbi_recno_t *count); -+typedef const char *dblayer_get_db_suffix_fn_t(void); - - struct dblayer_private - { -@@ -178,6 +179,7 @@ struct dblayer_private - dblayer_dbi_txn_abort_fn_t *dblayer_dbi_txn_abort_fn; - dblayer_get_entries_count_fn_t *dblayer_get_entries_count_fn; - dblayer_cursor_get_count_fn_t *dblayer_cursor_get_count_fn; -+ dblayer_get_db_suffix_fn_t *dblayer_get_db_suffix_fn; - }; - - #define DBLAYER_PRIV_SET_DATA_DIR 0x1 -@@ -188,6 +190,7 @@ back_txn *dblayer_get_pvt_txn(void); - void dblayer_pop_pvt_txn(void); - - int dblayer_delete_indices(ldbm_instance *inst); -+const char *dblayer_get_db_suffix(Slapi_Backend *be); - - - /* Return the last four characters of a string; used for comparing extensions. */ -diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h -index 22f2d1103..dbe5dca73 100644 ---- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h -+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h -@@ -142,6 +142,8 @@ void dblayer_restore_file_update(struct ldbminfo *li, char *directory); - int dblayer_import_file_init(ldbm_instance *inst); - void dblayer_import_file_update(ldbm_instance *inst); - int dblayer_import_file_check(ldbm_instance *inst); -+const char *dblayer_get_db_suffix(Slapi_Backend *be); -+ - - /* - * dn2entry.c -diff --git a/ldap/servers/slapd/back-ldbm/vlv_srch.c b/ldap/servers/slapd/back-ldbm/vlv_srch.c -index 4dd3804c9..6fd1b3880 100644 ---- a/ldap/servers/slapd/back-ldbm/vlv_srch.c -+++ b/ldap/servers/slapd/back-ldbm/vlv_srch.c -@@ -30,7 +30,6 @@ char *const type_vlvEnabled = "vlvEnabled"; - char *const type_vlvUses = "vlvUses"; - - static const char *file_prefix = "vlv#"; /* '#' used to avoid collision with real attributes */ --static const char *file_suffix = LDBM_FILENAME_SUFFIX; - - static int vlvIndex_createfilename(struct vlvIndex *pIndex, char **ppc); - -@@ -514,6 +513,7 @@ void - vlvIndex_init(struct vlvIndex *p, backend *be, struct vlvSearch *pSearch, const Slapi_Entry *e) - { - struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private; -+ const char *file_suffix = dblayer_get_db_suffix(be); - char *filename = NULL; - - if (NULL == p) --- -2.30.2 - diff --git a/0001-dna_enable_interval.patch b/0001-dna_enable_interval.patch deleted file mode 100644 index 5bef2ee..0000000 --- a/0001-dna_enable_interval.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c -index bf6b74a99..928a3f54a 100644 ---- a/ldap/servers/plugins/dna/dna.c -+++ b/ldap/servers/plugins/dna/dna.c -@@ -1023,7 +1023,6 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry *e, int apply) - /* Set the default interval to 1 */ - entry->interval = 1; - --#ifdef DNA_ENABLE_INTERVAL - value = slapi_entry_attr_get_charptr(e, DNA_INTERVAL); - if (value) { - entry->interval = strtoull(value, 0, 0); -@@ -1032,7 +1031,6 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry *e, int apply) - - slapi_log_err(SLAPI_LOG_CONFIG, DNA_PLUGIN_SUBSYSTEM, - "dna_parse_config_entry - %s [%" PRIu64 "]\n", DNA_INTERVAL, entry->interval); --#endif - - value = slapi_entry_attr_get_charptr(e, DNA_GENERATE); - if (value) { diff --git a/0001-ds_selinux_restorecon.sh-always-exit-0.patch b/0001-ds_selinux_restorecon.sh-always-exit-0.patch deleted file mode 100644 index fd13034..0000000 --- a/0001-ds_selinux_restorecon.sh-always-exit-0.patch +++ /dev/null @@ -1,33 +0,0 @@ -From d858b6950e4e0946f8d18d1855923c8d0f89c858 Mon Sep 17 00:00:00 2001 -From: Adam Williamson -Date: Thu, 27 Jan 2022 11:07:26 -0800 -Subject: [PATCH] ds_selinux_restorecon.sh: always exit 0 - -We don't want to error out and give up on starting the service -if the restorecon fails - it might just be that the directory -doesn't exist and doesn't need restoring. Issue identified and -fix suggested by Simon Farnsworth. - -https://bugzilla.redhat.com/show_bug.cgi?id=2047323 - -Signed-off-by: Adam Williamson ---- - wrappers/ds_selinux_restorecon.sh.in | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/wrappers/ds_selinux_restorecon.sh.in b/wrappers/ds_selinux_restorecon.sh.in -index 063347de3..2d7386233 100644 ---- a/wrappers/ds_selinux_restorecon.sh.in -+++ b/wrappers/ds_selinux_restorecon.sh.in -@@ -29,5 +29,6 @@ then - exit 0 - fi - --# Now run restorecon --restorecon ${DS_HOME_DIR} -+# Now run restorecon, but don't die if it fails (could be that the -+# directory doesn't exist) -+restorecon ${DS_HOME_DIR} || : --- -2.35.0.rc1 - diff --git a/389-ds-base.spec b/389-ds-base.spec index 27ee819..0c48ffd 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -53,8 +53,8 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.0.13 -Release: %{?relprefix}2%{?prerel}%{?dist} +Version: 2.1.0 +Release: %{?relprefix}1%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -96,10 +96,10 @@ Provides: bundled(crate(instant)) = 0.1.12 Provides: bundled(crate(itoa)) = 1.0.1 Provides: bundled(crate(jobserver)) = 0.1.24 Provides: bundled(crate(lazy_static)) = 1.4.0 -Provides: bundled(crate(libc)) = 0.2.113 +Provides: bundled(crate(libc)) = 0.2.116 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 -Provides: bundled(crate(lock_api)) = 0.4.5 +Provides: bundled(crate(lock_api)) = 0.4.6 Provides: bundled(crate(log)) = 0.4.14 Provides: bundled(crate(lru)) = 0.7.2 Provides: bundled(crate(memoffset)) = 0.6.5 @@ -125,8 +125,8 @@ Provides: bundled(crate(redox_syscall)) = 0.2.10 Provides: bundled(crate(remove_dir_all)) = 0.5.3 Provides: bundled(crate(ryu)) = 1.0.9 Provides: bundled(crate(scopeguard)) = 1.1.0 -Provides: bundled(crate(serde)) = 1.0.135 -Provides: bundled(crate(serde_derive)) = 1.0.135 +Provides: bundled(crate(serde)) = 1.0.136 +Provides: bundled(crate(serde_derive)) = 1.0.136 Provides: bundled(crate(serde_json)) = 1.0.78 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 @@ -136,7 +136,7 @@ Provides: bundled(crate(syn)) = 1.0.86 Provides: bundled(crate(synstructure)) = 0.12.6 Provides: bundled(crate(tempfile)) = 3.3.0 Provides: bundled(crate(textwrap)) = 0.11.0 -Provides: bundled(crate(tokio)) = 1.15.0 +Provides: bundled(crate(tokio)) = 1.16.1 Provides: bundled(crate(tokio-macros)) = 1.7.0 Provides: bundled(crate(toml)) = 0.5.8 Provides: bundled(crate(unicode-width)) = 0.1.9 @@ -149,13 +149,14 @@ Provides: bundled(crate(wasi)) = 0.10.2+wasi_snapshot_preview1 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 -Provides: bundled(crate(zeroize)) = 1.5.0 +Provides: bundled(crate(zeroize)) = 1.5.2 Provides: bundled(crate(zeroize_derive)) = 1.3.1 ##### Bundled cargo crates list - END ##### BuildRequires: nspr-devel BuildRequires: nss-devel >= 3.34 BuildRequires: openldap-devel +BuildRequires: lmdb-devel BuildRequires: libdb-devel BuildRequires: cyrus-sasl-devel BuildRequires: icu @@ -220,6 +221,7 @@ BuildRequires: rsync Requires: %{name}-libs = %{version}-%{release} Requires: python%{python3_pkgversion}-lib389 = %{version}-%{release} +Requires: lmdb # this is needed for using semanage from our setup scripts Requires: policycoreutils-python-utils @@ -276,11 +278,6 @@ Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download Patch0: concread-use-2018-edition.patch %endif -# https://bugzilla.redhat.com/show_bug.cgi?id=2047323 -# https://github.com/389ds/389-ds-base/pull/5141 -# Don't fail on startup if a directory we try to restorecon doesn't exist -Patch1: 0001-ds_selinux_restorecon.sh-always-exit-0.patch - %description 389 Directory Server is an LDAPv3 compliant server. The base package includes the LDAP server and command line utilities for server administration. @@ -453,9 +450,9 @@ autoreconf -fiv --libexecdir=%{_libexecdir}/%{pkgname} \ $NSSARGS $ASAN_FLAGS $RUST_FLAGS $CLANG_FLAGS $COCKPIT_FLAGS \ --enable-cmocka \ + --with-libldap-r=no \ --enable-perl - # lib389 pushd ./src/lib389 %py3_build @@ -724,406 +721,137 @@ exit 0 %endif %changelog -* Thu Jan 27 2022 Adam Williamson - 2.0.13-2 -- Backport PR#5141 to fix startup when a directory doesn't exist (#2047323) - -* Mon Jan 24 2022 Mark Reynolds - 2.0.13-1 -- Bump version to 2.0.13 +* Wed Feb 2 2022 Mark Reynolds - 2.1.0-1 +- Bump version to 2.1.0-1 +- Issue 4299 - UI - fix minor issues with ldap editor (table view) +- Issue 4299 - UI - fix minor issues with ldap editor +- Issue 5103 - UI - Add support for TPR to web console (#5111) +- Issue 2790 - RFE - set db home directory to /dev/shm by default +- Issue 5127 - ds_selinux_restorecon.sh: always exit 0 +- Issue 5135 - UI - Disk monitoring threshold does update properly +- Issue 5129 - BUG - Incorrect fn signature in add_index (#5130) - Issue 5132 - Update Rust crate lru to fix CVE - Issue 3555 - UI - fix audit issue with npm nanoid - Issue 4299 - UI - Add ACI editing features -- Issue 4299 - UI - LDAP editor - add "edit" and "rename" functionality - Issue 5127 - run restorecon on /dev/shm at server startup - Issue 5124 - dscontainer fails to create an instance -- Issue 4312 - fix compiler warnings +- Issue 5098 - Multiple issues around replication and CI test test_online_reinit_may_hang (#5109) +- Issue 4939 - Redesign LMDB import (#5071) +- Issue 5113 - Increase timestamp precision for development builds - Issue 5115 - AttributeError: type object 'build_manpages' has no attribute 'build_manpages' -- Issue 4312 - performance search rate: contention on global monitoring counters (#4940) +- Issue 5117 - Revert skipif line from CI test (#5118) +- Issue 5102 - BUG - container may fail with bare uid/gid (#5110) +- Issue 5077 - UI - Add retrocl exclude attribute functionality (#5078) - Issue 5105 - During a bind, if the target entry is not reachable the operation may complete without sending result (#5107) -- Issue 5095 - sync-repl with openldap may send truncated syncUUID (#5099) -- Issue 3584 - Add is_fips check to password tests (#5100) - Issue 5074 - retro changelog cli updates (#5075) -- Issue 4994 - Revert retrocl dependency workaround (#4995) - -* Wed Jan 19 2022 Fedora Release Engineering - 2.0.12-1.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild - -* Thu Dec 16 2021 Mark Reynolds - 2.0.12-1 -- Bump version to 2.0.12-1 +- Issue 3584 - Add is_fips check to password tests (#5100) +- Issue 5095 - sync-repl with openldap may send truncated syncUUID (#5099) +- Issue 5032 - Fix OpenLDAP version check (#5091) +- Issue 5080 - BUG - multiple index types not handled in openldap migration (#5094) +- Issue 2929 - Fix github warnings +- Issue 5053 - Improve GitHub Actions debugging +- Issue 5088 - dsctl dblib broken because of a merge issue (#5089) +- Issue 5079 - BUG - multiple ways to specific primary (#5087) +- Issue 5085 - Race condition about snmp collator at startup (#5086) +- Issue 5082 - slugify: ModuleNotFoundError when running test cases +- Issue 4959 - Invalid /etc/hosts setup can cause isLocalHost to fail (#5003) +- Issue 5037 - in OpenQA changelog trimming can crashes (#5070) +- Issue 5049 - ns-slapd crash in replication/acceptance_test.py (#5063) +- Issue 4890 - Need cli to easely get simple performance statistics (#4891) +- Issue 5011 - test_replica_backup_and_restore random failure (#5066) - Issue 4299 - UI LDAP editor - add "edit" and "rename" functionality +- Issue 5018 - RFE - openSUSE systemd hardening (#5019) - Issue 4962 - Fix various UI bugs - Database and Backups (#5044) +- Issue 5055 - Improve core dump detection and collection in PR CI +- Issue 4994 - Revert retrocl dependency workaround (#4995) - Issue 5046 - BUG - update concread (#5047) - Issue 5043 - BUG - Result must be used compiler warning (#5045) +- Issue 4312 - performance search rate: contention on global monitoring counters (#4940) +- Issue 5034 - is_dbi contains an invalid debug message that trigger failure in import_tests (#5035) +- Issue 5029 - Unbind generates incorrent closed error message (#5030) - Issue 4165 - Don't apply RootDN access control restrictions to UNIX connections - Issue 4931 - RFE: dsidm - add creation of service accounts - Issue 5024 - BUG - windows ro replica sigsegv (#5027) +- Issue 4758 - Add tests for WebUI +- Issue 5032 - OpenLDAP is not shipped with non-threaded version of libldap (#5033) +- Issue 5038 - BUG - dsconf tls may fail due to incorrect cert path (#5039) - Issue 5020 - BUG - improve clarity of posix win sync logging (#5021) +- Issue 5011 - test_replica_backup_and_restore random failure (#5028) +- Issue 5025 - RFE - remove useless logging (#5026) - Issue 5008 - If a non critical plugin can not be loaded/initialized, bootstrap should succeeds (#5009) - -* Mon Nov 22 2021 Mark Reynolds - 2.0.11-1 -- Bump version to 2.0.11 - Issue 4962 - Fix various UI bugs - Settings and Monitor (#5016) +- Issue 4976 - Failure in suites/import/import_test.py::test_fast_slow_import (#5017) - Issue 5014 - UI - Add group creation to LDAP editor - Issue 5006 - UI - LDAP editor tree not being properly updated +- Issue 4923 - issue about LMDB dbi versus txn handling (#4924) - Issue 5001 - Update CI test for new availableSASLMechs attribute - Issue 4959 - Invalid /etc/hosts setup can cause isLocalHost to fail. - Issue 5001 - Fix next round of UI bugs: - Issue 4962 - Fix various UI bugs - dsctl and ciphers (#5000) +- Issue 4734 - ldif2db - import of entry with no parent doesnt generate a warning +- Issue 4778 - [RFE] Schedule execution of "compactdb" at specific date/time - Issue 4978 - use more portable python command for checking containers -- Issue 4678 - RFE automatique disable of virtual attribute checking (#4918) +- Issue 4990 - CI tests: improve robustness of fourwaymmr (#4991) +- Issue 4992 - BUG - slapd.socket container fix (#4993) +- Issue 4984 - BUG - pid file handling (#4986) +- Issue 4460 - python3-lib389 ignore the configuration parameters from … (#4906) +- Issue 4982 - BUG - missing inttypes.h (#4983) +- Issue 4758 - Add tests for WebUI - Issue 4972 - gecos with IA5 introduces a compatibility issue with previous (#4981) +- Issue 4096 - Missing perl dependencies for logconv.pl +- Issue 4758 - Add tests for WebUI - Issue 4978 - make installer robust +- Issue 4898 - Implement bdb to lmdb CLI migration tools (#4952) - Issue 4976 - Failure in suites/import/import_test.py::test_fast_slow_import - Issue 4973 - update snmp to use /run/dirsrv for PID file -- Issue 4962 - Fix various UI bugs - Plugins (#4969) - Issue 4973 - installer changes permissions on /run +- Issue 4959 - BUG - Invalid /etc/hosts setup can cause isLocalHost (#4960) +- Issue 4962 - Fix various UI bugs - Plugins (#4969) - Issue 4092 - systemd-tmpfiles warnings - Issue 4956 - Automember allows invalid regex, and does not log proper error - Issue 4731 - Promoting/demoting a replica can crash the server - Issue 4962 - Fix various UI bugs part 1 - Issue 3584 - Fix PBKDF2_SHA256 hashing in FIPS mode (#4949) - Issue 4943 - Fix csn generator to limit time skew drift (#4946) +- Issue 4954 - pytest is killed by OOM killer when the whole test suite is executed - Issue 2790 - Set db home directory by default - Issue 4299 - Merge LDAP editor code into Cockpit UI - Issue 4938 - max_failure_count can be reached in dscontainer on slow machine with missing debug exception trace - Issue 4921 - logconv.pl -j: Use of uninitialized value (#4922) +- Issue 4896 - improve CI tests report in case of SERVER_DOWN exception (#4897) +- Issue 4678 - RFE automatique disable of virtual attribute checking (#4918) - Issue 4847 - BUG - potential deadlock in replica (#4936) - Issue 4513 - fix ACI CI tests involving ip/hostname rules - Issue 4925 - Performance ACI: targetfilter evaluation result can be reused (#4926) - Issue 4916 - Memory leak in ldap-agent - -* Thu Nov 04 2021 Viktor Ashirov - 2.0.10-2 -- Resolves #rhbz2016595 - -* Mon Sep 20 2021 Mark Reynolds - 2.0.10-1 -- Bump version to 2.0.10 +- Issue 4656 DS Remove problematic language from CLI tools and UI (#4893) - Issue 4908 - Updated several dsconf --help entries (typos, wrong descriptions, etc.) - Issue 4912 - Account Policy plugin does not set the config entry DN - Issue 4863 - typoes in logconv.pl - Issue 4796 - Add support for nsslapd-state to CLI & UI - Issue 4894 - IPA failure in ipa user-del --preserve (#4907) +- Issue 4914 - BUG - resolve duplicate stderr with clang (#4915) - Issue 4912 - dsidm command crashing when account policy plugin is enabled - Issue 4910 - db reindex corrupts RUV tombstone nsuiqueid index +- Issue 4577 - Add GitHub actions +- Issue 4901 - Add COPR integration - Issue 4869 - Fix retro cl trimming misuse of monotonic/realtime clocks +- Issue 4889 - bdb lock deadlock while reindex/import vlv index (#4892) +- Issue 4773 - Extend CI tests for DNA interval assignment - Issue 4887 - UI - fix minor regression from camelCase fixup - -* Tue Sep 14 2021 Sahana Prasad - 2.0.7-1.2 -- Rebuilt with OpenSSL 3.0.0 - -* Wed Jul 21 2021 Fedora Release Engineering - 2.0.7-1.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild - -* Thu Jul 15 2021 Mark Reynolds - 2.0.7-1 -- Bump version to 2.0.7 -- Issue 4443 - Internal unindexed searches in syncrepl/retro changelog -- Issue 4603 - Reindexing a single backend (#4831) -- Issue 4169 - UI - migrate Server Tab forms to PF4 -- Issue 4817 - BUG - locked crypt accounts on import may allow all passwords (#4819) -- Issue 4820 - RFE - control flow integrity (#4821) -- Issue 4706 - negative wtime for compare operations (#4780) -- Issue 4414 - SIGFPE crash in rhds disk monitoring routine (#4829) -- Issue 4262 - Fix Index out of bound in fractional test (#4828) -- Issue 4826 - Filter argparse-manpage from autogenerated requires -- Issue 4822 - Fix CI temporary password: fixture leftover breaks them (#4823) -- Issue 2820 - Fix CI test suite issues - -* Thu Jun 24 2021 Thierry Bordaz - 2.0.6-1 -- Bump version to 2.0.6 -- Issue 4803 - Improve DB Locks Monitoring Feature Descriptions -- Issue 4803 - Improve DB Locks Monitoring Feature Descriptions (#4810) -- Issue 4169 - UI - Migrate Typeaheads to PF4 (#4808) -- Issue 4414 - disk monitoring - prevent division by zero crash -- Issue 4788 - CLI should support Temporary Password Rules attributes (#4793) -- Issue 4656 - Fix replication plugin rename dependency issues -- Issue 4656 - replication name change upgrade code causes crash with dynamic plugins -- Issue 4506 - Improve SASL logging -- Issue 4709 - Fix double free in dbscan -- Issue 4093 - Fix MEP test case -- Issue 4747 - Remove unstable/unstatus tests (followup) (#4809) -- Issue 4791 - Missing dependency for RetroCL RFE (#4792) -- Issue 4794 - BUG - don't capture container output (#4798) -- Issue 4593 - Log an additional message if the server certificate nickname doesn't match nsSSLPersonalitySSL value -- Issue 4797 - ACL IP ADDRESS evaluation may corrupt c_isreplication_session connection flags (#4799) -- Issue 4169 - UI Migrate checkbox to PF4 (#4769) -- Issue 4447 - Crash when the Referential Integrity log is manually edited -- Issue 4773 - Add CI test for DNA interval assignment -- Issue 4789 - Temporary password rules are not enforce with local password policy (#4790) -- Issue 4379 - fixing regression in test_info_disclosure -- Issue 4379 - Allow more than 1 empty AttributeDescription for ldapsearch, without the risk of denial of service -- Issue 4379 - Allow more than 1 empty AttributeDescription for ldapsearch, without the risk of denial of service -- Issue 4575 Update test docstrings metadata -- Issue 4753 - Adjust our tests to 389-ds-base-snmp missing in RHEL 9 Appstream -- removed the snmp_present() from utils.py as we have get_rpm_version() in conftest.py -- Issue 4753 - Adjust our tests to 389-ds-base-snmp missing in RHEL 9 Appstream - -* Fri Jun 04 2021 Python Maint - 2.0.5-1.1 -- Rebuilt for Python 3.10 - -* Sun May 30 2021 Mark Reynolds - 2.0.5-1 -- Bump version to 2.0.5 -- Issue 4778 - RFE - Allow setting TOD for db compaction and add task -- Issue 4169 - UI - Port plugin tables to PF4 -- Issue 4656 - Allow backward compatilbity for replication plugin name change -- Issue 4764 - replicated operation sometime checks ACI (#4783) -- Issue 2820 - Fix CI test suite issues -- Issue 4781 - There are some typos in man-pages -- Issue 4773 - Enable interval feature of DNA plugin -- Issue 4623 - RFE - Monitor the current DB locks (#4762) -- Issue 3555 - Fix UI audit issue -- Issue 4725 - Fix compiler warnings -- Issue 4770 - Lower FIPS logging severity -- Issue 4765 - database suffix unexpectdly changed from .db to .db4 (#4766) -- Issue 4725 - [RFE] DS - Update the password policy to support a Temporary Password Rules (#4727) -- Issue 4747 - Remove unstable/unstatus tests from PRCI (#4748) -- Issue 4759 - Fix coverity issue (#4760) -- Issue 4169 - UI - Migrate Buttons to PF4 (#4745) -- Issue 4714 - dscontainer fails with rootless podman -- Issue 4750 - Fix compiler warning in retrocl (#4751) -- Issue 4742 - UI - should always use LDAPI path when calling CLI -- Issue 4169 - UI - Migrate Server, Security, and Schema tables to PF4 -- Issue 4667 - incorrect accounting of readers in vattr rwlock (#4732) -- Issue 4701 - RFE - Exclude attributes from retro changelog (#4723) -- Issue 4740 - Fix CI lib389 userPwdPolicy and subtreePwdPolicy (#4741) -- Issue 4711 - SIGSEV with sync_repl (#4738) -- Issue 4734 - import of entry with no parent warning (#4735) -- Issue 4729 - GitHub Actions fails to run pytest tests -- Issue 4656 - Remove problematic language from source code -- Issue 4632 - dscontainer: SyntaxWarning: "is" with a literal. -- Issue 4169 - UI - migrate replication tables to PF4 -- Issue 4637 - ndn cache leak (#4724) -- Issue 4577 - Fix ASAN flags in specfile -- Issue 4169 - UI - PF4 migration - database tables -- issue 4653 - refactor ldbm backend to allow replacement of BDB - phase 3e - dbscan (#4709) - -* Thu May 20 2021 Christian Heimes - 2.0.4-4 -- Enable interval feature of DNA plugin (resolves: rhbz#1962671) - -* Wed May 19 2021 Pete Walter - 2.0.4-3.2 -- Rebuild for ICU 69 - -* Wed May 19 2021 Pete Walter - 2.0.4-3.1 -- Rebuild for ICU 69 - -* Wed May 19 2021 Thierry Bordaz - 2.0.4-3 -- Issue 4765 - database suffix unexpectdly changed from .db to .db4 (#4766) - -* Fri May 07 2021 Viktor Ashirov - 2.0.4-2 -- Rebuilt to fix NVR - -* Fri Apr 09 2021 Simon Pichugin - 2.0.4-1.1 -- Add Rust bundled Provides and Update License - -* Thu Apr 08 2021 Thierry Bordaz - 2.0.4-1 -- Bump version to 2.0.4 -- Issue 4680 - 389ds coredump (@389ds/389-ds-base-nightly) in replica install with CA (#4715) -- Issue 3965 - RFE - Implement the Password Policy attribute "pwdReset" (#4713) -- Issue 4700 - Regression in winsync replication agreement (#4712) -- Issue 3965 - RFE - Implement the Password Policy attribute "pwdReset" (#4710) -- Issue 4169 - UI - migrate monitor tables to PF4 -- issue 4585 - backend redesign phase 3c - dbregion test removal (#4665) -- Issue 2736 - remove remaining perl references -- Issue 2736 - https://github.com/389ds/389-ds-base/issues/2736 -- Issue 4706 - negative wtime in access log for CMP operations -- Issue 3585 - LDAP server returning controltype in different sequence -- Issue 4127 - With Accounts/Account module delete fuction is not working (#4697) -- Issue 4666 - BUG - cb_ping_farm can fail with anonymous binds disabled (#4669) -- Issue 4671 - UI - Fix browser crashes -- Issue 4169 - UI - Add PF4 charts for server stats -- Issue 4648 - Fix some issues and improvement around CI tests (#4651) -- Issue 4654 Updates to tickets/ticket48234_test.py (#4654) -- Issue 4229 - Fix Rust linking -- Issue 4673 - Update Rust crates -- Issue 4658 - monitor - connection start date is incorrect -- Issue 4169 - UI - migrate modals to PF4 -- Issue 4656 - remove problematic language from ds-replcheck -- Issue 4459 - lib389 - Default paths should use dse.ldif if the server is down -- Issue 4656 - Remove problematic language from UI/CLI/lib389 -- Issue 4661 - RFE - allow importing openldap schemas (#4662) -- Issue 4659 - restart after openldap migration to enable plugins (#4660) -- Merge pull request #4664 from mreynolds389/issue4663 -- issue 4552 - Backup Redesign phase 3b - use dbimpl in replicatin plugin (#4622) -- Issue 4643 - Add a tool that generates Rust dependencies for a specfile (#4645) -- Issue 4646 - CLI/UI - revise DNA plugin management -- Issue 4644 - Large updates can reset the CLcache to the beginning of the changelog (#4647) -- Issue 4649 - crash in sync_repl when a MODRDN create a cenotaph (#4652) -- Issue 4169 - UI - Migrate alerts to PF4 -- Issue 4169 - UI - Migrate Accordians to PF4 ExpandableSection -- Issue 4595 - Paged search lookthroughlimit bug (#4602) -- Issue 4169 - UI - port charts to PF4 -- Issue 2820 - Fix CI test suite issues -- Issue 4513 - CI - make acl ip address tests more robust - -* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 2.0.3-3.1 -- Rebuilt for updated systemd-rpm-macros - See https://pagure.io/fesco/issue/2583. - -* Fri Feb 26 2021 Alexander Bokovoy - 2.0.3-3 -- Remove a revert of the fix for Issue 4609 - CVE - info disclosure when authenticating(breaks Dogtag) -- Dogtag has fixed own code that failed in the presence of the fix for Issue 4609 - -* Fri Feb 19 2021 Mark Reynolds - 2.0.3-2 -- Bump version to 2.0.3-2 -- Revert Issue 4609 - CVE - info disclosure when authenticating(breaks DogTag) - -* Fri Feb 12 2021 Mark Reynolds - 2.0.3-1 -- Bump version to 2.0.3 -- Issue 4619 - remove pytest requirement from lib389 -- Issue 4615 - log message when psearch first exceeds max threads per conn -- Issue 4469 - Backend redesing phase 3a - implement dbimpl API and use it in back-ldbm (#4618) -- Issue 4324 - Some architectures the cache line size file does not exist -- Issue 4593 - RFE - Print help when nsSSLPersonalitySSL is not found (#4614) -- Issue 4469 - Backend redesign phase 3a - bdb dependency removal from back-ldbm -- PR 4564 - Update dscontainer -- Issue 4149 - UI - port TreeView and opther components to PF4 -- Issue 4577 - Add GitHub actions -- Issue 4591 - RFE - improve openldap_to_ds help and features (#4607) -- issue 4612 - Fix pytest fourwaymmr_test for non root user (#4613) -- Issue 4609 - CVE - info disclosure when authenticating -- Issue 4348 - Add tests for dsidm -- Issue 4571 - Stale libdb-utils dependency -- Issue 4600 - performance modify rate: reduce lock contention on the object extension factory (#4601) -- Issue 4577 - Add GitHub actions -- Issue 4588 - BUG - unable to compile without xcrypt (#4589) -- Issue 4579 - libasan detects heap-use-after-free in URP test (#4584) -- Issue 4581 - A failed re-indexing leaves the database in broken state (#4582) -- Issue 4348 - Add tests for dsidm -- Issue 4577 - Add GitHub actions -- Issue 4563 - Failure on s390x: 'Fails to split RDN "o=pki-tomcat-CA" into components' (#4573) -- Issue 4093 - fix compiler warnings and update doxygen -- Issue 4575 - Update test docstrings metadata -- Issue 4526 - sync_repl: when completing an operation in the pending list, it can select the wrong operation (#4553) -- Issue 4324 - Performance search rate: change entry cache monitor to recursive pthread mutex (#4569) -- Issue 4513 - Add DS version check to SSL version test (#4570) -- Issue 5442 - Search results are different between RHDS10 and RHDS11 -- Issue 4396 - Minor memory leak in backend (#4558) -- Issue 4513 - Fix replication CI test failures (#4557) -- Issue 4513 - Fix replication CI test failures (#4557) -- Issue 4153 - Added a CI test (#4556) -- Issue 4506 - BUG - fix oob alloc for fds (#4555) -- Issue 4548 - CLI - dsconf needs better root DN access control plugin validation -- Issue 4506 - Temporary fix for io issues (#4516) -- Issue 4535 - lib389 - Fix log function in backends.py -- Issue 4534 - libasan read buffer overflow in filtercmp (#4541) -- Issue 4544 - Compiler warnings on krb5 functions (#4545) -- Update rpm.mk for RUST tarballs - -* Mon Jan 25 2021 Fedora Release Engineering - 2.0.2-1.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild - -* Thu Jan 14 2021 Mark Reynolds - 2.0.2-1 -- Bump version to 2.0.2 -- Issue 4539 - BUG - no such file if no overlays in openldap during migration (#4540) -- Issue 4528 - Fix cn=monitor SCOPE_ONE search (#4529) -- Issue 4535 - lib389 - healthcheck throws exception if backend is not replicated -- Issue 4537 - Use KRB5_CLIENT_KTNAME for client keytabs (#4523) -- Issue 4513 - CI Tests - fix test failures -- Issue 4504 - insure that repl_monitor_test use ldapi (for RHEL) - fix merge issue (#4533) -- Issue 4315 - performance search rate: nagle triggers high rate of setsocketopt -- Issue 4504 - pytest test_dsconf_replication_monitor fails on RHEL - Fix merging issue (#4530) -- Issue 4504 - Insure ldapi is enabled in repl_monitor_test.py (Needed on RHEL) (#4527) -- Issue 4506 - BUG - Fix bounds on fd table population (#4520) -- Issue 4521 - DS crash in deref plugin if dereferenced entry exists but is not returned by internal search (#4525) -- Issue 4219 - Log internal unindexed searches (notes=A) -- Issue 4384 - Separate eventq into REALTIME and MONOTONIC -- Issue 4381 - RFE - LDAPI authentication DN rewritter -- Issue 4513 - Fix schema test and lib389 task module (#4514) -- Issue 4414 - disk monitoring - prevent division by zero crash -- Issue 4517 - BUG: Multiple systemd pin warnings (#4518) -- Issue 4507 - Improve csngen testing task (#4508) -- Issue 4498 - BUG - entryuuid replication may not work (#4503) -- Issue 4480 - Unexpected info returned to ldap request (#4491) -- Issue 4504 - Fix pytest test_dsconf_replication_monitor (#4505) -- Issue 4373 - BUG - one line cleanup, free results in mt if ent 0 (#4502) -- Issue 4500 - Add cockpit enabling to dsctl -- Issue 4272 - RFE - add support for gost-yescrypt for hashing passwords (#4497) -- Issue 1795 - RFE - Enable logging for libldap and libber in error log (#4481) -- Issue 3522 - Remove DES to AES conversion code -- Issue 4492 - Changelog cache can upload updates from a wrong starting point (CSN) (#4493) -- Issue 4373 - BUG - calloc of size 0 in MT build (#4496) -- Issue 4483 - heap-use-after-free in slapi_be_getsuffix -- Issue 4486 - Remove random ldif file generation from import test (#4487) -- Issue 4224 - cleanup specfile after libsds removal -- Issue 4421 - Unable to build with Rust enabled in closed environment -- Issue 4489 - Remove return statement from a void function (#4490) -- Issue 4229 - RFE - Improve rust linking and build performance (#4474) -- Issue 4224 - openldap can become confused with entryuuid -- Issue 4313 - improve tests and improve readme re refdel -- Issue 4313 - fix potential syncrepl data corruption -- Issue 4419 - Warn users of skipped entries during ldif2db online import (#4476) -- Issue 4243 - Fix test (4th): SyncRepl plugin provides a wrong (#4475) -- Issue 4315 - performance search rate: nagle triggers high rate of setsocketopt (#4437) -- Issue 4460 - BUG - add machine name to subject alt names in SSCA (#4472) -- Issue 4446 - RFE - openldap password hashers -- Issue 4284 - dsidm fails to delete an organizationalUnit entry -- Issue 4243 - Fix test: SyncRepl plugin provides a wrong cookie (#4466) (#4466) -- Issue 4464 - RFE - clang with ds+asan+rust -- Issue 4105 - Remove python.six (fix regression) -- Issue 4384 - Use MONOTONIC clock for all timing events and conditions -- Issue 4418 - ldif2db - offline. Warn the user of skipped entries -- Issue 4243 - Fix test: SyncRepl plugin provides a wrong cookie (#4467) -- Issue 4460 - BUG - lib389 should use system tls policy -- Issue 3657 - Add options to dsctl for dsrc file -- Issue 4454 - RFE - fix version numbers to allow object caching -- Issue 3986 - UI - Handle objectclasses that do not have X-ORIGIN set -- Issue 4297 - 2nd fix for on ADD replication URP issue internal searches with filter containing unescaped chars (#4439) -- Issue 4112 - Added a CI test (#4441) -- Issue 4449 - dsconf replication monitor fails to retrieve database RUV - consumer (Unavailable) (#4451) -- Issue 4105 - Remove python.six from lib389 (#4456) -- Issue 4440 - BUG - ldifgen with --start-idx option fails with unsupported operand (#4444) -- Issue 4410 - RFE - ndn cache with arc in rust -- Issue 4373 - BUG - Mapping Tree nodes can be created that are invalid -- Issue 4428 - BUG Paged Results with critical false causes sigsegv in chaining -- Issue 4428 - Paged Results with Chaining Test Case -- Issue 2054 - do not add referrals for masters with different data generation -- Issue 4383 - Do not normalize escaped spaces in a DN -- Issue 4432 - After a failed online import the next imports are very slow -- Issue 4316 - performance search rate: useless poll on network send callback (#4424) -- Issue 4281 - dsidm user status fails with Error: 'nsUserAccount' object has no attribute 'is_locked' -- Issue 4429 - NULL dereference in revert_cache() -- Issue 4412 - Fix CLI repl-agmt requirement for parameters (#4422) -- Issue 4407 - RFE - remove http client and presence plugin (#4409) -- Issue 4398 - build problems at alpine linux -- Issue 4415 - unable to query schema if there are extra parenthesis - -* Thu Oct 29 2020 Mark Reynolds - 2.0.1-1 -- Bump version to 2.0.1 -- Issue 4420 - change NVR to use X.X.X instead of X.X.X.X -- Issue 4391 - DSE config modify does not call be_postop (#4394) -- Issue 4218 - Verify the new wtime and optime access log keywords (#4397) -- Issue 4176 - CL trimming causes high CPU -- Issue 2058 - Add keep alive entry after on-line initialization - second version (#4399) -- Issue 4403 - RFE - OpenLDAP pw hash migration tests (#4408) - -* Wed Oct 28 2020 Mark Reynolds - 1.4.5.0-1 -- Bump version to 1.4.5.0 -- Issue 4262 - more perl removal cleanup -- Issue 2526 - retrocl backend created out of order - -* Mon Oct 26 2020 Mark Reynolds - 1.4.4.6-1 -- Bump version to 1.4.4.6 -- Issue 4262 - Remove legacy tools subpackage (final cleanup) -- Issue 4262 - Remove legacy tools subpackage (restart instances after rpm install) -- Issue 4262 - Remove legacy tools subpackage -- Issue 2526 - revert API change in slapi_be_getsuffix() -- Issue 4363 - Sync repl: per thread structure was incorrectly initialized (#4395) -- Issue 4392 - Update create_test.py -- Issue 2820 - Fix CI tests (#4365) -- Issue 2526 - suffix management in backends incorrect -- Issue 4389 - errors log with incorrectly formatted message parent_update_on_childchange -- Issue 4295 - Fix a closing quote issue (#4386) -- Issue 1199 - Misleading message in access log for idle timeout (#4385) -- Issue 3600 - RFE - openldap migration tooling (#4318) -- Issue 4176 - import ldif2cl task should not close all changelogs -- Issue 4159 - Healthcheck code DSBLE0002 not returned on disabled suffix -- Issue 4379 - allow more than 1 empty AttributeDescription for ldapsearch, without the risk of denial of service (#4380) -- Issue 4329 - Sync repl - if a serie of updates target the same entry then the cookie get wrong changenumber (#4356) -- Issue 3555 - Fix npm audit issues (#4370) -- Issue 4372 - BUG - Chaining DB did not validate bind mech parameters (#4374) -- Issue 4334 - RFE - Task timeout may cause larger dataset imports to fail (#4359) -- Issue 4361 - RFE - add - dscreate --advanced flag to avoid user confusion -- Issue 4368 - ds-replcheck crashes when processing glue entries -- Issue 4366 - lib389 - Fix account status inactivity checks -- Issue 4265 - UI - Make the secondary plugins read-only (#4364) -- Issue 4360 - password policy max sequence sets is not working as expected -- Issue 4348 - Add tests for dsidm -- Issue 4350 - One line, fix invalid type error in tls_cacertdir check (#4358) +- Issue 4887 - UI - Update webpack.config.js and package.json +- Issue 4725 [RFE] DS - Update the password policy to support Temporary Password Rules (#4853) +- Issue 4149 - UI - Migrate the remaining components to PF4 +- Issue 4169 - Migrate Replication & Schema tabs to PF4 +- Issue 4875 - CLI - Add some verbosity to installer +- Issue 4884 - server crashes when dnaInterval attribute is set to zero +- Issue 4880: Revert removed_config_49298_test.py wrongly modified by issue 4699 (#4881) +- Issue 4699 - backend redesign phase 4 - db-mdb plugin implementation (#4716) +- Issue 4877 - RFE - EntryUUID to validate UUIDs on fixup (#4878) +- Issue 4872 - BUG - entryuuid enabled by default causes replication issues (#4876) +- Issue 4775 - Add entryuuid CLI and Fixup (#4776) +- Issue 4763 - Attribute Uniqueness Plugin uses wrong subtree on ModRDN (#4871) +- Issue 4851 - Typos in "dsconf pwpolicy set --help" (#4867) +- Issue 4096 - Missing perl dependencies for logconv.pl +- Issue 4736 - lib389 - fix regression in certutil error checking diff --git a/sources b/sources index 7786e23..7b86ec0 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (389-ds-base-2.0.13.tar.bz2) = ab9429b391b32d4a09ea5fb0ce15fcf31f7c13e781588ce5587a0ed169959938ce59bff857dbf58bb9413208f6c35792c127cad27c7aca6aa53ef66ef4c36196 +SHA512 (389-ds-base-2.1.0.tar.bz2) = 496195b848566a0ccee272f06a041e2f764a5c8f3d84651a0fc3c7ca9128102ac6e8a8c9ae0945ce1742f39006daa724e394d0481d7c494a9701bf6c8709be51 SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 From 7a69d01ec01d33f878c01341c07a47e0af024bb7 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Wed, 23 Mar 2022 10:49:59 -0400 Subject: [PATCH 040/125] Bump version to 2.2.0-1 Issue 5230 - Race condition in RHDS disk monitoring functions Issue 5193 - Incomplete ruv occasionally returned from ruv search (#5194) Issue 4970 - Add support for recursively deleting subentries Issue 4299 - UI - Add CoS funtionality (#5196) Issue 5225 - UI - impossible to manually set entry cache Issue 5186 - UI - Fix SASL Mapping regex test feature Issue 5221 - User with expired password can still login with full privledges Issue 5218 - double-free of the virtual attribute context in persistent search (#5219) Issue 5214 - CI Test tests/suites/replication/virtual_attribute_replication_test.py (#5215) Issue 5197 - Build break in lib389 with INSTALL_PREFIX (#5198) Issue 5200 - dscontainer should use environment variables with DS_ prefix Issue 5189 - memberOf plugin exclude subtree not cleaning up groups on modrdn Issue 5051 - RFE - ADSync flatten tree (#5192) Issue 5188 - UI - LDAP editor - add entry and group types Issue 5184 - memberOf does not work correctly with multiple include scopes Issue 5162 - BUG - error on importing chain files (#5164) Issue 5186 - UI - Fix SASL Mapping regex validation and other minor improvements Issue 5048 - Support for nsslapd-tcp-fin-timeout and nsslapd-tcp-keepalive-time (#5179) Issue 5122 - dsconf instance backend suffix set doesn't accept backend name (#5178) Issue 5032 - Fix configure option in specfile (#5174) Issue 5176 - CI rewriter fails when libslapd.so.0 does not exist (#5177) Issue 5160 - BUG - x- prefix in descr-oid can confuse oid parser (#5161) Issue 5137 - RFE - improve sssd conf output (#5138) Issue 5102 - BUG - container may fail with bare uid/gid (#5140) Issue 5145 - Fix covscan errors Issue 4721 - UI - attribute uniqueness crashes UI when there are no configs Issue 5155 - RFE - Provide an option to abort an Auto Member rebuild task Issue 4299 - UI - Add Role funtionality (#5163) Issue 5050 - bdb bulk op fails if fs page size > 8K (#5150) Issue 5149 - Build failure on EL8 - undefined reference to `twalk_r' Issue 5142 - CLI - dsctl dbgen is broken Issue 4678 - Added test cases --- .gitignore | 1 + 389-ds-base.spec | 87 +++++++++++++++++++++++++++++++++--------------- sources | 2 +- 3 files changed, 63 insertions(+), 27 deletions(-) diff --git a/.gitignore b/.gitignore index c92b5f1..1140e74 100644 --- a/.gitignore +++ b/.gitignore @@ -211,3 +211,4 @@ /389-ds-base-2.0.12.tar.bz2 /389-ds-base-2.0.13.tar.bz2 /389-ds-base-2.1.0.tar.bz2 +/389-ds-base-2.2.0.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 0c48ffd..c26dbb0 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -53,13 +53,13 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.1.0 +Version: 2.2.0 Release: %{?relprefix}1%{?prerel}%{?dist} -License: GPLv3+ +License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and MPLv2.0 and BSD and ASL 2.0 and (ASL 2.0 or Boost) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 Conflicts: freeipa-server < 4.0.3 -Obsoletes: %{name} <= 1.4.0.9 +Obsoletes: %{name} <= 1.4.4 Obsoletes: %{name}-legacy-tools < 1.4.4.6 Obsoletes: %{name}-legacy-tools-debuginfo < 1.4.4.6 Provides: ldif2ldbm >= 0 @@ -68,42 +68,42 @@ Provides: ldif2ldbm >= 0 Provides: bundled(crate(ahash)) = 0.7.6 Provides: bundled(crate(ansi_term)) = 0.12.1 Provides: bundled(crate(atty)) = 0.2.14 -Provides: bundled(crate(autocfg)) = 1.0.1 +Provides: bundled(crate(autocfg)) = 1.1.0 Provides: bundled(crate(base64)) = 0.13.0 Provides: bundled(crate(bitflags)) = 1.3.2 Provides: bundled(crate(byteorder)) = 1.4.3 Provides: bundled(crate(cbindgen)) = 0.9.1 -Provides: bundled(crate(cc)) = 1.0.72 +Provides: bundled(crate(cc)) = 1.0.73 Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 2.34.0 Provides: bundled(crate(concread)) = 0.2.21 Provides: bundled(crate(crossbeam)) = 0.8.1 -Provides: bundled(crate(crossbeam-channel)) = 0.5.2 +Provides: bundled(crate(crossbeam-channel)) = 0.5.4 Provides: bundled(crate(crossbeam-deque)) = 0.8.1 -Provides: bundled(crate(crossbeam-epoch)) = 0.9.6 -Provides: bundled(crate(crossbeam-queue)) = 0.3.3 -Provides: bundled(crate(crossbeam-utils)) = 0.8.6 +Provides: bundled(crate(crossbeam-epoch)) = 0.9.8 +Provides: bundled(crate(crossbeam-queue)) = 0.3.5 +Provides: bundled(crate(crossbeam-utils)) = 0.8.8 Provides: bundled(crate(entryuuid)) = 0.1.0 Provides: bundled(crate(entryuuid_syntax)) = 0.1.0 Provides: bundled(crate(fastrand)) = 1.7.0 Provides: bundled(crate(fernet)) = 0.1.4 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 -Provides: bundled(crate(getrandom)) = 0.2.4 +Provides: bundled(crate(getrandom)) = 0.2.5 Provides: bundled(crate(hashbrown)) = 0.11.2 Provides: bundled(crate(hermit-abi)) = 0.1.19 Provides: bundled(crate(instant)) = 0.1.12 Provides: bundled(crate(itoa)) = 1.0.1 Provides: bundled(crate(jobserver)) = 0.1.24 Provides: bundled(crate(lazy_static)) = 1.4.0 -Provides: bundled(crate(libc)) = 0.2.116 +Provides: bundled(crate(libc)) = 0.2.121 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 Provides: bundled(crate(lock_api)) = 0.4.6 -Provides: bundled(crate(log)) = 0.4.14 -Provides: bundled(crate(lru)) = 0.7.2 +Provides: bundled(crate(log)) = 0.4.16 +Provides: bundled(crate(lru)) = 0.7.3 Provides: bundled(crate(memoffset)) = 0.6.5 -Provides: bundled(crate(once_cell)) = 1.9.0 +Provides: bundled(crate(once_cell)) = 1.10.0 Provides: bundled(crate(openssl)) = 0.10.38 Provides: bundled(crate(openssl-sys)) = 0.9.72 Provides: bundled(crate(parking_lot)) = 0.11.2 @@ -116,27 +116,26 @@ Provides: bundled(crate(ppv-lite86)) = 0.2.16 Provides: bundled(crate(proc-macro-hack)) = 0.5.19 Provides: bundled(crate(proc-macro2)) = 1.0.36 Provides: bundled(crate(pwdchan)) = 0.1.0 -Provides: bundled(crate(quote)) = 1.0.15 -Provides: bundled(crate(rand)) = 0.8.4 +Provides: bundled(crate(quote)) = 1.0.16 +Provides: bundled(crate(rand)) = 0.8.5 Provides: bundled(crate(rand_chacha)) = 0.3.1 Provides: bundled(crate(rand_core)) = 0.6.3 -Provides: bundled(crate(rand_hc)) = 0.3.1 -Provides: bundled(crate(redox_syscall)) = 0.2.10 +Provides: bundled(crate(redox_syscall)) = 0.2.11 Provides: bundled(crate(remove_dir_all)) = 0.5.3 Provides: bundled(crate(ryu)) = 1.0.9 Provides: bundled(crate(scopeguard)) = 1.1.0 Provides: bundled(crate(serde)) = 1.0.136 Provides: bundled(crate(serde_derive)) = 1.0.136 -Provides: bundled(crate(serde_json)) = 1.0.78 +Provides: bundled(crate(serde_json)) = 1.0.79 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 Provides: bundled(crate(smallvec)) = 1.8.0 Provides: bundled(crate(strsim)) = 0.8.0 -Provides: bundled(crate(syn)) = 1.0.86 +Provides: bundled(crate(syn)) = 1.0.89 Provides: bundled(crate(synstructure)) = 0.12.6 Provides: bundled(crate(tempfile)) = 3.3.0 Provides: bundled(crate(textwrap)) = 0.11.0 -Provides: bundled(crate(tokio)) = 1.16.1 +Provides: bundled(crate(tokio)) = 1.17.0 Provides: bundled(crate(tokio-macros)) = 1.7.0 Provides: bundled(crate(toml)) = 0.5.8 Provides: bundled(crate(unicode-width)) = 0.1.9 @@ -149,8 +148,8 @@ Provides: bundled(crate(wasi)) = 0.10.2+wasi_snapshot_preview1 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 -Provides: bundled(crate(zeroize)) = 1.5.2 -Provides: bundled(crate(zeroize_derive)) = 1.3.1 +Provides: bundled(crate(zeroize)) = 1.5.4 +Provides: bundled(crate(zeroize_derive)) = 1.3.2 ##### Bundled cargo crates list - END ##### BuildRequires: nspr-devel @@ -185,8 +184,8 @@ BuildRequires: libasan %endif # If rust is enabled %if %{use_rust} -BuildRequires: cargo -BuildRequires: rust +BuildRequires: cargo +BuildRequires: rust %endif BuildRequires: pkgconfig BuildRequires: pkgconfig(systemd) @@ -234,6 +233,7 @@ Requires: selinux-policy >= 3.14.1-29 Requires: openldap-clients Requires: /usr/bin/c_rehash Requires: python%{python3_pkgversion}-ldap +Requires: acl # this is needed to setup SSL if you are not using the # administration server package @@ -263,7 +263,7 @@ Requires: perl-sigtrap # Picks up our systemd deps. %{?systemd_requires} -Obsoletes: %{name} <= 1.3.5.4 +Obsoletes: %{name} <= 1.4.4 Source0: https://releases.pagure.org/389-ds-base/%{name}-%{version}%{?prerel}.tar.bz2 # 389-ds-git.sh should be used to generate the source tarball from git @@ -721,6 +721,41 @@ exit 0 %endif %changelog +* Wed Mar 23 2022 Mark Reynolds - 2.2.0-1 +- Bump version to 2.2.0-1 +- Issue 5230 - Race condition in RHDS disk monitoring functions +- Issue 5193 - Incomplete ruv occasionally returned from ruv search (#5194) +- Issue 4970 - Add support for recursively deleting subentries +- Issue 4299 - UI - Add CoS funtionality (#5196) +- Issue 5225 - UI - impossible to manually set entry cache +- Issue 5186 - UI - Fix SASL Mapping regex test feature +- Issue 5221 - User with expired password can still login with full privledges +- Issue 5218 - double-free of the virtual attribute context in persistent search (#5219) +- Issue 5214 - CI Test tests/suites/replication/virtual_attribute_replication_test.py (#5215) +- Issue 5197 - Build break in lib389 with INSTALL_PREFIX (#5198) +- Issue 5200 - dscontainer should use environment variables with DS_ prefix +- Issue 5189 - memberOf plugin exclude subtree not cleaning up groups on modrdn +- Issue 5051 - RFE - ADSync flatten tree (#5192) +- Issue 5188 - UI - LDAP editor - add entry and group types +- Issue 5184 - memberOf does not work correctly with multiple include scopes +- Issue 5162 - BUG - error on importing chain files (#5164) +- Issue 5186 - UI - Fix SASL Mapping regex validation and other minor improvements +- Issue 5048 - Support for nsslapd-tcp-fin-timeout and nsslapd-tcp-keepalive-time (#5179) +- Issue 5122 - dsconf instance backend suffix set doesn't accept backend name (#5178) +- Issue 5032 - Fix configure option in specfile (#5174) +- Issue 5176 - CI rewriter fails when libslapd.so.0 does not exist (#5177) +- Issue 5160 - BUG - x- prefix in descr-oid can confuse oid parser (#5161) +- Issue 5137 - RFE - improve sssd conf output (#5138) +- Issue 5102 - BUG - container may fail with bare uid/gid (#5140) +- Issue 5145 - Fix covscan errors +- Issue 4721 - UI - attribute uniqueness crashes UI when there are no configs +- Issue 5155 - RFE - Provide an option to abort an Auto Member rebuild task +- Issue 4299 - UI - Add Role funtionality (#5163) +- Issue 5050 - bdb bulk op fails if fs page size > 8K (#5150) +- Issue 5149 - Build failure on EL8 - undefined reference to `twalk_r' +- Issue 5142 - CLI - dsctl dbgen is broken +- Issue 4678 - Added test cases + * Wed Feb 2 2022 Mark Reynolds - 2.1.0-1 - Bump version to 2.1.0-1 - Issue 4299 - UI - fix minor issues with ldap editor (table view) diff --git a/sources b/sources index 7b86ec0..669a8f6 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (389-ds-base-2.1.0.tar.bz2) = 496195b848566a0ccee272f06a041e2f764a5c8f3d84651a0fc3c7ca9128102ac6e8a8c9ae0945ce1742f39006daa724e394d0481d7c494a9701bf6c8709be51 +SHA512 (389-ds-base-2.2.0.tar.bz2) = 42c1f70fdadc0c91cfb7e2add021db4ac81f4b02b34b3882d38bf28681a91e06d8beadbbeed2e398f8c321bea318c64ccfa7ef2ef758e0264c79792d8652b76c SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 From e34784505a23561eab1bef08ce0e6d8f0eb845ab Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Wed, 23 Mar 2022 11:42:10 -0400 Subject: [PATCH 041/125] Bump version to 2.1.1 Issue 5230 - Race condition in RHDS disk monitoring functions Issue 4299 - UI - Add CoS funtionality (#5196) Issue 5225 - UI - impossible to manually set entry cache Issue 5186 - UI - Fix SASL Mapping regex test feature Issue 5221 - User with expired password can still login with full privledges Issue 5218 - double-free of the virtual attribute context in persistent search (#5219) Issue 5193 - Incomplete ruv occasionally returned from ruv search (#5194) Issue 5200 - dscontainer should use environment variables with DS_ prefix Issue 5189 - memberOf plugin exclude subtree not cleaning up groups on modrdn Issue 5051 - RFE - ADSync flatten tree (#5192) Issue 5188 - UI - LDAP editor - add entry and group types Issue 5184 - memberOf does not work correctly with multiple include scopes Issue 5162 - BUG - error on importing chain files (#5164) Issue 5186 - UI - Fix SASL Mapping regex validation and other minor improvements Issue 5048 - Support for nsslapd-tcp-fin-timeout and nsslapd-tcp-keepalive-time (#5179) Issue 5122 - dsconf instance backend suffix set doesn't accept backend name (#5178) Issue 5032 - Fix configure option in specfile (#5174) Issue 5176 - CI rewriter fails when libslapd.so.0 does not exist (#5177) Issue 5160 - BUG - x- prefix in descr-oid can confuse oid parser (#5161) Issue 5137 - RFE - improve sssd conf output (#5138) Issue 5102 - BUG - container may fail with bare uid/gid (#5140) Issue 5145 - Fix covscan errors Issue 4721 - UI - attribute uniqueness crashes UI when there are no configs Issue 5155 - RFE - Provide an option to abort an Auto Member rebuild task Issue 4299 - UI - Add Role funtionality (#5163) Issue 5050 - bdb bulk op fails if fs page size > 8K (#5150) Issue 5149 - Build failure on EL8 - undefined reference to `twalk_r' Issue 5142 - CLI - dsctl dbgen is broken Issue 4678 - Added test cases --- .gitignore | 1 + 389-ds-base.spec | 11 ++++------- sources | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 1140e74..d00f37a 100644 --- a/.gitignore +++ b/.gitignore @@ -212,3 +212,4 @@ /389-ds-base-2.0.13.tar.bz2 /389-ds-base-2.1.0.tar.bz2 /389-ds-base-2.2.0.tar.bz2 +/389-ds-base-2.1.1.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index c26dbb0..2b67918 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -53,7 +53,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.2.0 +Version: 2.1.1 Release: %{?relprefix}1%{?prerel}%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and MPLv2.0 and BSD and ASL 2.0 and (ASL 2.0 or Boost) URL: https://www.port389.org @@ -721,18 +721,15 @@ exit 0 %endif %changelog -* Wed Mar 23 2022 Mark Reynolds - 2.2.0-1 -- Bump version to 2.2.0-1 +* Wed Mar 23 2022 Mark Reynolds - 2.1.1-1 +- Bump version to 2.1.1 - Issue 5230 - Race condition in RHDS disk monitoring functions -- Issue 5193 - Incomplete ruv occasionally returned from ruv search (#5194) -- Issue 4970 - Add support for recursively deleting subentries - Issue 4299 - UI - Add CoS funtionality (#5196) - Issue 5225 - UI - impossible to manually set entry cache - Issue 5186 - UI - Fix SASL Mapping regex test feature - Issue 5221 - User with expired password can still login with full privledges - Issue 5218 - double-free of the virtual attribute context in persistent search (#5219) -- Issue 5214 - CI Test tests/suites/replication/virtual_attribute_replication_test.py (#5215) -- Issue 5197 - Build break in lib389 with INSTALL_PREFIX (#5198) +- Issue 5193 - Incomplete ruv occasionally returned from ruv search (#5194) - Issue 5200 - dscontainer should use environment variables with DS_ prefix - Issue 5189 - memberOf plugin exclude subtree not cleaning up groups on modrdn - Issue 5051 - RFE - ADSync flatten tree (#5192) diff --git a/sources b/sources index 669a8f6..3e8875d 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (389-ds-base-2.2.0.tar.bz2) = 42c1f70fdadc0c91cfb7e2add021db4ac81f4b02b34b3882d38bf28681a91e06d8beadbbeed2e398f8c321bea318c64ccfa7ef2ef758e0264c79792d8652b76c +SHA512 (389-ds-base-2.1.1.tar.bz2) = 38feb135847ef409e03642433a84aea84b65f7c0d55cae35e71ff3c541e2c33bb5c1b207096438c7578db7ec98ce8b3fa3a0282d3ca0637ad9e593bc324fb78c SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 From 0853e355f9d662be62ae9e28bd1e7d2649d5bb28 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Thu, 2 Jun 2022 10:03:30 +0200 Subject: [PATCH 042/125] Update tests.yml Change upstream repo URL and remove 389-ds-base-legacy-tools package that is no longer present. --- tests/tests.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/tests.yml b/tests/tests.yml index 4643f2f..1878c82 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -2,7 +2,7 @@ - hosts: localhost remote_user: root vars: - ds_repo_url: https://pagure.io/389-ds-base.git + ds_repo_url: https://github.com/389ds/389-ds-base.git ds_repo_dir: ds ds_tests: "{{ ds_repo_dir }}/dirsrvtests/tests" pytest: py.test-3 @@ -24,4 +24,3 @@ - python3-pytest - 389-ds-base - 389-ds-base-snmp - - 389-ds-base-legacy-tools From 0aaf5d460bc45d8a1d8727412c7bc6525a3b1564 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Thu, 2 Jun 2022 10:26:54 +0200 Subject: [PATCH 043/125] Remove unused relprefix and prerel macros that break rpmdev-bumpspec logic During mass rebuilds NVR is bumped by rpmdev-bumpspec. But it can't handle complex Release: fields such as ours, that has %{prerel} and %{relprefix} macros. It adds .1 after the %{dist} macro instead of increasing the release number. The issue for rpmdev-bumpspec is unsolved since 2012: https://pagure.io/rpmdevtools/issue/18 These macros are unused by us and only cause issues when NVR is bumped. So let's remove them. --- 389-ds-base.spec | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 2b67918..02fb9f1 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -5,13 +5,6 @@ # Exclude i686 bit arches ExcludeArch: i686 -# for a pre-release, define the prerel field e.g. .a1 .rc2 - comment out for official release -# also remove the space between % and global - this space is needed because -# fedpkg verrel stupidly ignores comment lines -#% global prerel .rc3 -# also need the relprefix field for a pre-release e.g. .0 - also comment out for official release -#% global relprefix 0. - # If perl-Socket-2.000 or newer is available, set 0 to use_Socket6. %global use_Socket6 0 @@ -54,7 +47,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.1.1 -Release: %{?relprefix}1%{?prerel}%{?dist} +Release: 1%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and MPLv2.0 and BSD and ASL 2.0 and (ASL 2.0 or Boost) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -265,7 +258,7 @@ Requires: perl-sigtrap Obsoletes: %{name} <= 1.4.4 -Source0: https://releases.pagure.org/389-ds-base/%{name}-%{version}%{?prerel}.tar.bz2 +Source0: https://releases.pagure.org/389-ds-base/%{name}-%{version}.tar.bz2 # 389-ds-git.sh should be used to generate the source tarball from git Source1: %{name}-git.sh Source2: %{name}-devel.README @@ -375,10 +368,10 @@ A cockpit UI Plugin for configuring and administering the 389 Directory Server %endif %prep -%autosetup -p1 -v -n %{name}-%{version}%{?prerel} +%autosetup -p1 -v -n %{name}-%{version} %if %{bundle_jemalloc} -%setup -q -n %{name}-%{version}%{?prerel} -T -D -b 3 +%setup -q -n %{name}-%{version} -T -D -b 3 %endif cp %{SOURCE2} README.devel @@ -459,10 +452,10 @@ pushd ./src/lib389 popd # argparse-manpage dynamic man pages have hardcoded man v1 in header, # need to change it to v8 -sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}%{?prerel}/src/lib389/man/dsconf.8 -sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}%{?prerel}/src/lib389/man/dsctl.8 -sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}%{?prerel}/src/lib389/man/dsidm.8 -sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}%{?prerel}/src/lib389/man/dscreate.8 +sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}/src/lib389/man/dsconf.8 +sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}/src/lib389/man/dsctl.8 +sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}/src/lib389/man/dsidm.8 +sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}/src/lib389/man/dscreate.8 # Generate symbolic info for debuggers export XCFLAGS=$RPM_OPT_FLAGS @@ -484,7 +477,7 @@ find %{buildroot}%{_datadir}/cockpit/389-console -type f | sed -e "s@%{buildroot %endif # Copy in our docs from doxygen. -cp -r %{_builddir}/%{name}-%{version}%{?prerel}/man/man3 $RPM_BUILD_ROOT/%{_mandir}/man3 +cp -r %{_builddir}/%{name}-%{version}/man/man3 $RPM_BUILD_ROOT/%{_mandir}/man3 # lib389 pushd src/lib389 @@ -509,8 +502,8 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/libsvrcore.la %if %{bundle_jemalloc} pushd ../%{jemalloc_name}-%{jemalloc_ver} make DESTDIR="$RPM_BUILD_ROOT" install_lib install_bin -cp -pa COPYING ../%{name}-%{version}%{?prerel}/COPYING.jemalloc -cp -pa README ../%{name}-%{version}%{?prerel}/README.jemalloc +cp -pa COPYING ../%{name}-%{version}/COPYING.jemalloc +cp -pa README ../%{name}-%{version}/README.jemalloc popd %endif From 9f03f8a2325c884c2f8ded7a86a515dec31d3be5 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Fri, 3 Jun 2022 14:06:50 -0400 Subject: [PATCH 044/125] Bump version to 2.2.1 Issue 5323 - BUG - Fix issue in mdb tests with monitor (#5326) Issue 5170 - BUG - incorrect behaviour of filter test (#5315) Issue 5324 - plugin acceptance test needs hardening Issue 5319 - dsctl_tls_test.py fails with openssl-3.x Issue 5323 - BUG - migrating database for monitoring interface lead to crash (#5321) Issue 5304 - Need a compatibility option about sub suffix handling (#5310) Issue 5313 - dbgen test uses deprecated -h HOST and -p PORT options for ldapmodify Issue 5311 - Missing Requires for acl in the spec file Issue 5305 - OpenLDAP version autodetection doesn't work Issue 5307 - VERSION_PREREL is not set correctly in CI builds Issue 5302 - Release tarballs don't contain cockpit webapp Issue 5170 - RFE - improve filter logging to assist debugging (#5301) Issue 5299 - jemalloc 5.3 released Issue 5175 - Remove stale zlib-devel dependency declaration (#5173) Issue 5294 - Report Portal 5 is not processing test results XML file Issue 5170 - BUG - ldapsubentries were incorrectly returned (#5285) Issue 5291 - Harden ReplicationManager.wait_for_replication (#5292) Issue 379 - RFE - Compress rotated logs (fix linker) Issue 379 - RFE - Compress rotated logs Issue 5281 - HIGH - basic test does not run Issue 5284 - Replication broken after password change (#5286) Issue 5279 - dscontainer: TypeError: unsupported operand type(s) for /: 'str' and 'int' Issue 5170 - RFE - Filter optimiser (#5171) Issue 5276 - CLI - improve task handling Issue 5126 - Memory leak in slapi_ldap_get_lderrno (#5153) Issue 3 - ansible-ds - Prefix handling fix (#5275) Issue 5273 - CLI - add arg completer for instance name Issue 2893 - CLI - dscreate - add options for setting up replication Issue 4866 - CLI - when enabling replication set changelog trimming by default Issue 5241 - UI - Add account locking missing functionality (#5251) Issue 5180 - snmp_collator tries to unlock NULL mutex (#5266) Issue 4904 - Fix various small issues lib389 prerequisite for ansible-ds (#5253) Issue 5260 - BUG - OpenLDAP allows multiple names of memberof overlay (#5261) Issue 5252 - During DEL, vlv search can erroneously return NULL candidate (#5256) Issue 5254 - dscreate create-template regression due to 5a3bdc336 (#5255) Issue 5210 - Python undefined names in lib389 Issue 5065 - Crash in suite plugins - test_dna_max_value (#5108) Issue 5247 - BUG - Missing attributes in samba schema (#5248) Issue 5242- Craft message may crash the server (#5243) Issue 4775 -plugin entryuuid failing (#5229) Issue 5239 - Nightly copr builds are broken Issue 5237 - audit-ci: Cannot convert undefined or null to object Issue 5234 - UI - rename Users and Groups tab Issue 5227 - UI - No way to move back to Get Started step (#5233) Issue 5217 - Simplify instance creation and administration by non root user (#5224) --- .gitignore | 2 + 389-ds-base.spec | 225 ++++++++++++----------------------------------- sources | 4 +- 3 files changed, 59 insertions(+), 172 deletions(-) diff --git a/.gitignore b/.gitignore index d00f37a..fbf77bf 100644 --- a/.gitignore +++ b/.gitignore @@ -213,3 +213,5 @@ /389-ds-base-2.1.0.tar.bz2 /389-ds-base-2.2.0.tar.bz2 /389-ds-base-2.1.1.tar.bz2 +/jemalloc-5.3.0.tar.bz2 +/389-ds-base-2.2.1.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 02fb9f1..8e42c5a 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -17,7 +17,7 @@ ExcludeArch: i686 %if %{bundle_jemalloc} %global jemalloc_name jemalloc -%global jemalloc_ver 5.2.1 +%global jemalloc_ver 5.3.0 %global __provides_exclude ^libjemalloc\\.so.*$ %endif @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.1.1 +Version: 2.2.1 Release: 1%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and MPLv2.0 and BSD and ASL 2.0 and (ASL 2.0 or Boost) URL: https://www.port389.org @@ -145,8 +145,8 @@ Provides: bundled(crate(zeroize)) = 1.5.4 Provides: bundled(crate(zeroize_derive)) = 1.3.2 ##### Bundled cargo crates list - END ##### -BuildRequires: nspr-devel -BuildRequires: nss-devel >= 3.34 +BuildRequires: nspr-devel >= 4.32 +BuildRequires: nss-devel >= 3.67.0-7 BuildRequires: openldap-devel BuildRequires: lmdb-devel BuildRequires: libdb-devel @@ -227,11 +227,13 @@ Requires: openldap-clients Requires: /usr/bin/c_rehash Requires: python%{python3_pkgversion}-ldap Requires: acl +Requires: zlib # this is needed to setup SSL if you are not using the # administration server package Requires: nss-tools -Requires: nss >= 3.34 +Requires: nss >= 3.67.0-7 +Requires: nspr >= 4.32 # these are not found by the auto-dependency method # they are required to support the mandatory LDAP SASL mechs @@ -714,169 +716,52 @@ exit 0 %endif %changelog -* Wed Mar 23 2022 Mark Reynolds - 2.1.1-1 -- Bump version to 2.1.1 -- Issue 5230 - Race condition in RHDS disk monitoring functions -- Issue 4299 - UI - Add CoS funtionality (#5196) -- Issue 5225 - UI - impossible to manually set entry cache -- Issue 5186 - UI - Fix SASL Mapping regex test feature -- Issue 5221 - User with expired password can still login with full privledges -- Issue 5218 - double-free of the virtual attribute context in persistent search (#5219) -- Issue 5193 - Incomplete ruv occasionally returned from ruv search (#5194) -- Issue 5200 - dscontainer should use environment variables with DS_ prefix -- Issue 5189 - memberOf plugin exclude subtree not cleaning up groups on modrdn -- Issue 5051 - RFE - ADSync flatten tree (#5192) -- Issue 5188 - UI - LDAP editor - add entry and group types -- Issue 5184 - memberOf does not work correctly with multiple include scopes -- Issue 5162 - BUG - error on importing chain files (#5164) -- Issue 5186 - UI - Fix SASL Mapping regex validation and other minor improvements -- Issue 5048 - Support for nsslapd-tcp-fin-timeout and nsslapd-tcp-keepalive-time (#5179) -- Issue 5122 - dsconf instance backend suffix set doesn't accept backend name (#5178) -- Issue 5032 - Fix configure option in specfile (#5174) -- Issue 5176 - CI rewriter fails when libslapd.so.0 does not exist (#5177) -- Issue 5160 - BUG - x- prefix in descr-oid can confuse oid parser (#5161) -- Issue 5137 - RFE - improve sssd conf output (#5138) -- Issue 5102 - BUG - container may fail with bare uid/gid (#5140) -- Issue 5145 - Fix covscan errors -- Issue 4721 - UI - attribute uniqueness crashes UI when there are no configs -- Issue 5155 - RFE - Provide an option to abort an Auto Member rebuild task -- Issue 4299 - UI - Add Role funtionality (#5163) -- Issue 5050 - bdb bulk op fails if fs page size > 8K (#5150) -- Issue 5149 - Build failure on EL8 - undefined reference to `twalk_r' -- Issue 5142 - CLI - dsctl dbgen is broken -- Issue 4678 - Added test cases - -* Wed Feb 2 2022 Mark Reynolds - 2.1.0-1 -- Bump version to 2.1.0-1 -- Issue 4299 - UI - fix minor issues with ldap editor (table view) -- Issue 4299 - UI - fix minor issues with ldap editor -- Issue 5103 - UI - Add support for TPR to web console (#5111) -- Issue 2790 - RFE - set db home directory to /dev/shm by default -- Issue 5127 - ds_selinux_restorecon.sh: always exit 0 -- Issue 5135 - UI - Disk monitoring threshold does update properly -- Issue 5129 - BUG - Incorrect fn signature in add_index (#5130) -- Issue 5132 - Update Rust crate lru to fix CVE -- Issue 3555 - UI - fix audit issue with npm nanoid -- Issue 4299 - UI - Add ACI editing features -- Issue 5127 - run restorecon on /dev/shm at server startup -- Issue 5124 - dscontainer fails to create an instance -- Issue 5098 - Multiple issues around replication and CI test test_online_reinit_may_hang (#5109) -- Issue 4939 - Redesign LMDB import (#5071) -- Issue 5113 - Increase timestamp precision for development builds -- Issue 5115 - AttributeError: type object 'build_manpages' has no attribute 'build_manpages' -- Issue 5117 - Revert skipif line from CI test (#5118) -- Issue 5102 - BUG - container may fail with bare uid/gid (#5110) -- Issue 5077 - UI - Add retrocl exclude attribute functionality (#5078) -- Issue 5105 - During a bind, if the target entry is not reachable the operation may complete without sending result (#5107) -- Issue 5074 - retro changelog cli updates (#5075) -- Issue 3584 - Add is_fips check to password tests (#5100) -- Issue 5095 - sync-repl with openldap may send truncated syncUUID (#5099) -- Issue 5032 - Fix OpenLDAP version check (#5091) -- Issue 5080 - BUG - multiple index types not handled in openldap migration (#5094) -- Issue 2929 - Fix github warnings -- Issue 5053 - Improve GitHub Actions debugging -- Issue 5088 - dsctl dblib broken because of a merge issue (#5089) -- Issue 5079 - BUG - multiple ways to specific primary (#5087) -- Issue 5085 - Race condition about snmp collator at startup (#5086) -- Issue 5082 - slugify: ModuleNotFoundError when running test cases -- Issue 4959 - Invalid /etc/hosts setup can cause isLocalHost to fail (#5003) -- Issue 5037 - in OpenQA changelog trimming can crashes (#5070) -- Issue 5049 - ns-slapd crash in replication/acceptance_test.py (#5063) -- Issue 4890 - Need cli to easely get simple performance statistics (#4891) -- Issue 5011 - test_replica_backup_and_restore random failure (#5066) -- Issue 4299 - UI LDAP editor - add "edit" and "rename" functionality -- Issue 5018 - RFE - openSUSE systemd hardening (#5019) -- Issue 4962 - Fix various UI bugs - Database and Backups (#5044) -- Issue 5055 - Improve core dump detection and collection in PR CI -- Issue 4994 - Revert retrocl dependency workaround (#4995) -- Issue 5046 - BUG - update concread (#5047) -- Issue 5043 - BUG - Result must be used compiler warning (#5045) -- Issue 4312 - performance search rate: contention on global monitoring counters (#4940) -- Issue 5034 - is_dbi contains an invalid debug message that trigger failure in import_tests (#5035) -- Issue 5029 - Unbind generates incorrent closed error message (#5030) -- Issue 4165 - Don't apply RootDN access control restrictions to UNIX connections -- Issue 4931 - RFE: dsidm - add creation of service accounts -- Issue 5024 - BUG - windows ro replica sigsegv (#5027) -- Issue 4758 - Add tests for WebUI -- Issue 5032 - OpenLDAP is not shipped with non-threaded version of libldap (#5033) -- Issue 5038 - BUG - dsconf tls may fail due to incorrect cert path (#5039) -- Issue 5020 - BUG - improve clarity of posix win sync logging (#5021) -- Issue 5011 - test_replica_backup_and_restore random failure (#5028) -- Issue 5025 - RFE - remove useless logging (#5026) -- Issue 5008 - If a non critical plugin can not be loaded/initialized, bootstrap should succeeds (#5009) -- Issue 4962 - Fix various UI bugs - Settings and Monitor (#5016) -- Issue 4976 - Failure in suites/import/import_test.py::test_fast_slow_import (#5017) -- Issue 5014 - UI - Add group creation to LDAP editor -- Issue 5006 - UI - LDAP editor tree not being properly updated -- Issue 4923 - issue about LMDB dbi versus txn handling (#4924) -- Issue 5001 - Update CI test for new availableSASLMechs attribute -- Issue 4959 - Invalid /etc/hosts setup can cause isLocalHost to fail. -- Issue 5001 - Fix next round of UI bugs: -- Issue 4962 - Fix various UI bugs - dsctl and ciphers (#5000) -- Issue 4734 - ldif2db - import of entry with no parent doesnt generate a warning -- Issue 4778 - [RFE] Schedule execution of "compactdb" at specific date/time -- Issue 4978 - use more portable python command for checking containers -- Issue 4990 - CI tests: improve robustness of fourwaymmr (#4991) -- Issue 4992 - BUG - slapd.socket container fix (#4993) -- Issue 4984 - BUG - pid file handling (#4986) -- Issue 4460 - python3-lib389 ignore the configuration parameters from … (#4906) -- Issue 4982 - BUG - missing inttypes.h (#4983) -- Issue 4758 - Add tests for WebUI -- Issue 4972 - gecos with IA5 introduces a compatibility issue with previous (#4981) -- Issue 4096 - Missing perl dependencies for logconv.pl -- Issue 4758 - Add tests for WebUI -- Issue 4978 - make installer robust -- Issue 4898 - Implement bdb to lmdb CLI migration tools (#4952) -- Issue 4976 - Failure in suites/import/import_test.py::test_fast_slow_import -- Issue 4973 - update snmp to use /run/dirsrv for PID file -- Issue 4973 - installer changes permissions on /run -- Issue 4959 - BUG - Invalid /etc/hosts setup can cause isLocalHost (#4960) -- Issue 4962 - Fix various UI bugs - Plugins (#4969) -- Issue 4092 - systemd-tmpfiles warnings -- Issue 4956 - Automember allows invalid regex, and does not log proper error -- Issue 4731 - Promoting/demoting a replica can crash the server -- Issue 4962 - Fix various UI bugs part 1 -- Issue 3584 - Fix PBKDF2_SHA256 hashing in FIPS mode (#4949) -- Issue 4943 - Fix csn generator to limit time skew drift (#4946) -- Issue 4954 - pytest is killed by OOM killer when the whole test suite is executed -- Issue 2790 - Set db home directory by default -- Issue 4299 - Merge LDAP editor code into Cockpit UI -- Issue 4938 - max_failure_count can be reached in dscontainer on slow machine with missing debug exception trace -- Issue 4921 - logconv.pl -j: Use of uninitialized value (#4922) -- Issue 4896 - improve CI tests report in case of SERVER_DOWN exception (#4897) -- Issue 4678 - RFE automatique disable of virtual attribute checking (#4918) -- Issue 4847 - BUG - potential deadlock in replica (#4936) -- Issue 4513 - fix ACI CI tests involving ip/hostname rules -- Issue 4925 - Performance ACI: targetfilter evaluation result can be reused (#4926) -- Issue 4916 - Memory leak in ldap-agent -- Issue 4656 DS Remove problematic language from CLI tools and UI (#4893) -- Issue 4908 - Updated several dsconf --help entries (typos, wrong descriptions, etc.) -- Issue 4912 - Account Policy plugin does not set the config entry DN -- Issue 4863 - typoes in logconv.pl -- Issue 4796 - Add support for nsslapd-state to CLI & UI -- Issue 4894 - IPA failure in ipa user-del --preserve (#4907) -- Issue 4914 - BUG - resolve duplicate stderr with clang (#4915) -- Issue 4912 - dsidm command crashing when account policy plugin is enabled -- Issue 4910 - db reindex corrupts RUV tombstone nsuiqueid index -- Issue 4577 - Add GitHub actions -- Issue 4901 - Add COPR integration -- Issue 4869 - Fix retro cl trimming misuse of monotonic/realtime clocks -- Issue 4889 - bdb lock deadlock while reindex/import vlv index (#4892) -- Issue 4773 - Extend CI tests for DNA interval assignment -- Issue 4887 - UI - fix minor regression from camelCase fixup -- Issue 4887 - UI - Update webpack.config.js and package.json -- Issue 4725 [RFE] DS - Update the password policy to support Temporary Password Rules (#4853) -- Issue 4149 - UI - Migrate the remaining components to PF4 -- Issue 4169 - Migrate Replication & Schema tabs to PF4 -- Issue 4875 - CLI - Add some verbosity to installer -- Issue 4884 - server crashes when dnaInterval attribute is set to zero -- Issue 4880: Revert removed_config_49298_test.py wrongly modified by issue 4699 (#4881) -- Issue 4699 - backend redesign phase 4 - db-mdb plugin implementation (#4716) -- Issue 4877 - RFE - EntryUUID to validate UUIDs on fixup (#4878) -- Issue 4872 - BUG - entryuuid enabled by default causes replication issues (#4876) -- Issue 4775 - Add entryuuid CLI and Fixup (#4776) -- Issue 4763 - Attribute Uniqueness Plugin uses wrong subtree on ModRDN (#4871) -- Issue 4851 - Typos in "dsconf pwpolicy set --help" (#4867) -- Issue 4096 - Missing perl dependencies for logconv.pl -- Issue 4736 - lib389 - fix regression in certutil error checking +* Fri Jun 3 2022 Mark Reynolds - 2.2.1-1 +- Bump version to 2.2.1 +- Issue 5323 - BUG - Fix issue in mdb tests with monitor (#5326) +- Issue 5170 - BUG - incorrect behaviour of filter test (#5315) +- Issue 5324 - plugin acceptance test needs hardening +- Issue 5319 - dsctl_tls_test.py fails with openssl-3.x +- Issue 5323 - BUG - migrating database for monitoring interface lead to crash (#5321) +- Issue 5304 - Need a compatibility option about sub suffix handling (#5310) +- Issue 5313 - dbgen test uses deprecated -h HOST and -p PORT options for ldapmodify +- Issue 5311 - Missing Requires for acl in the spec file +- Issue 5305 - OpenLDAP version autodetection doesn't work +- Issue 5307 - VERSION_PREREL is not set correctly in CI builds +- Issue 5302 - Release tarballs don't contain cockpit webapp +- Issue 5170 - RFE - improve filter logging to assist debugging (#5301) +- Issue 5299 - jemalloc 5.3 released +- Issue 5175 - Remove stale zlib-devel dependency declaration (#5173) +- Issue 5294 - Report Portal 5 is not processing test results XML file +- Issue 5170 - BUG - ldapsubentries were incorrectly returned (#5285) +- Issue 5291 - Harden ReplicationManager.wait_for_replication (#5292) +- Issue 379 - RFE - Compress rotated logs (fix linker) +- Issue 379 - RFE - Compress rotated logs +- Issue 5281 - HIGH - basic test does not run +- Issue 5284 - Replication broken after password change (#5286) +- Issue 5279 - dscontainer: TypeError: unsupported operand type(s) for /: 'str' and 'int' +- Issue 5170 - RFE - Filter optimiser (#5171) +- Issue 5276 - CLI - improve task handling +- Issue 5126 - Memory leak in slapi_ldap_get_lderrno (#5153) +- Issue 3 - ansible-ds - Prefix handling fix (#5275) +- Issue 5273 - CLI - add arg completer for instance name +- Issue 2893 - CLI - dscreate - add options for setting up replication +- Issue 4866 - CLI - when enabling replication set changelog trimming by default +- Issue 5241 - UI - Add account locking missing functionality (#5251) +- Issue 5180 - snmp_collator tries to unlock NULL mutex (#5266) +- Issue 4904 - Fix various small issues +- lib389 prerequisite for ansible-ds (#5253) +- Issue 5260 - BUG - OpenLDAP allows multiple names of memberof overlay (#5261) +- Issue 5252 - During DEL, vlv search can erroneously return NULL candidate (#5256) +- Issue 5254 - dscreate create-template regression due to 5a3bdc336 (#5255) +- Issue 5210 - Python undefined names in lib389 +- Issue 5065 - Crash in suite plugins - test_dna_max_value (#5108) +- Issue 5247 - BUG - Missing attributes in samba schema (#5248) +- Issue 5242- Craft message may crash the server (#5243) +- Issue 4775 -plugin entryuuid failing (#5229) +- Issue 5239 - Nightly copr builds are broken +- Issue 5237 - audit-ci: Cannot convert undefined or null to object +- Issue 5234 - UI - rename Users and Groups tab +- Issue 5227 - UI - No way to move back to Get Started step (#5233) +- Issue 5217 - Simplify instance creation and administration by non root user (#5224) diff --git a/sources b/sources index 3e8875d..5416ac2 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (389-ds-base-2.1.1.tar.bz2) = 38feb135847ef409e03642433a84aea84b65f7c0d55cae35e71ff3c541e2c33bb5c1b207096438c7578db7ec98ce8b3fa3a0282d3ca0637ad9e593bc324fb78c -SHA512 (jemalloc-5.2.1.tar.bz2) = 0bbb77564d767cef0c6fe1b97b705d368ddb360d55596945aea8c3ba5889fbce10479d85ad492c91d987caacdbbdccc706aa3688e321460069f00c05814fae02 +SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 +SHA512 (389-ds-base-2.2.1.tar.bz2) = 9408cf689b874e862f81c8e1fdd75788fbc5f9a3f5b1f9b0327248448f0f4115d03d0c0f6ce03ef3e12dde8f982641440d61e0420f5e359af2bd53ec1d36dbc9 From 7fe71f3dedb11a36667013e5b38fa7458b2a3363 Mon Sep 17 00:00:00 2001 From: Python Maint Date: Mon, 13 Jun 2022 20:39:22 +0200 Subject: [PATCH 045/125] Rebuilt for Python 3.11 --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 8e42c5a..01cbf9a 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,7 +47,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.2.1 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and MPLv2.0 and BSD and ASL 2.0 and (ASL 2.0 or Boost) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -716,6 +716,9 @@ exit 0 %endif %changelog +* Mon Jun 13 2022 Python Maint - 2.2.1-2 +- Rebuilt for Python 3.11 + * Fri Jun 3 2022 Mark Reynolds - 2.2.1-1 - Bump version to 2.2.1 - Issue 5323 - BUG - Fix issue in mdb tests with monitor (#5326) From 1d58aef426f2a05eddccc84fa0b5d78e66211d50 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Wed, 15 Jun 2022 13:45:44 -0400 Subject: [PATCH 046/125] Bump version to 2.2.1-3 Issue 5332 - BUG - normalise filter as intended Issue 5327 - Validate test metadata Issue 4348 - Add tests for dsidm Bump crossbeam-utils from 0.8.6 to 0.8.8 in /src Issue 5333 - 389-ds-base fails to build with Python 3.11 --- 389-ds-base.spec | 12 ++++++++++-- sources | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 01cbf9a..0251a01 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,7 +47,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.2.1 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and MPLv2.0 and BSD and ASL 2.0 and (ASL 2.0 or Boost) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -213,7 +213,7 @@ BuildRequires: rsync Requires: %{name}-libs = %{version}-%{release} Requires: python%{python3_pkgversion}-lib389 = %{version}-%{release} -Requires: lmdb +Requires: lmdb-libs # this is needed for using semanage from our setup scripts Requires: policycoreutils-python-utils @@ -716,6 +716,14 @@ exit 0 %endif %changelog +* Wed Jun 15 2022 Mark Reynolds - 2.2.1-3 +- Bump version to 2.2.1-3 +- Issue 5332 - BUG - normalise filter as intended +- Issue 5327 - Validate test metadata +- Issue 4348 - Add tests for dsidm +- Bump crossbeam-utils from 0.8.6 to 0.8.8 in /src +- Issue 5333 - 389-ds-base fails to build with Python 3.11 + * Mon Jun 13 2022 Python Maint - 2.2.1-2 - Rebuilt for Python 3.11 diff --git a/sources b/sources index 5416ac2..fbcd532 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ +SHA512 (389-ds-base-2.2.1.tar.bz2) = c0985643d59ffb8e702af48325614c33c141f6469a026e831d9997e5ea9cf8b375453f0f379acf7c38c6b4079e12be9943a3de47ebf34766fce9b70db5b600c4 SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 -SHA512 (389-ds-base-2.2.1.tar.bz2) = 9408cf689b874e862f81c8e1fdd75788fbc5f9a3f5b1f9b0327248448f0f4115d03d0c0f6ce03ef3e12dde8f982641440d61e0420f5e359af2bd53ec1d36dbc9 From c3f89a86c31ed4ae49ca67549a2a9ac0c53cfc70 Mon Sep 17 00:00:00 2001 From: Python Maint Date: Thu, 16 Jun 2022 17:58:54 +0200 Subject: [PATCH 047/125] Rebuilt for Python 3.11 --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 0251a01..9b4c270 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,7 +47,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.2.1 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and MPLv2.0 and BSD and ASL 2.0 and (ASL 2.0 or Boost) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -716,6 +716,9 @@ exit 0 %endif %changelog +* Thu Jun 16 2022 Python Maint - 2.2.1-4 +- Rebuilt for Python 3.11 + * Wed Jun 15 2022 Mark Reynolds - 2.2.1-3 - Bump version to 2.2.1-3 - Issue 5332 - BUG - normalise filter as intended From 459f9c8265cc73719fc51597536922ee5374b9fa Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Tue, 5 Jul 2022 12:21:18 -0400 Subject: [PATCH 048/125] Bump version to 2.2.2 Issue 5221 - fix covscan (#5359) Issue 5294 - Report Portal 5 is not processing an XML file with (#5358) Issue 5353 - CLI - dsconf backend export breaks with multiple backends Issue 5346 - New connection table fails with ASAN failures (#5350) Issue 5345 - BUG - openldap migration fails when ppolicy is active (#5347) Issue 5323 - BUG - improve skipping of monitor db (#5340) Issue 5329 - Improve replication extended op logging Issue 5343 - Various improvements to winsync Issue 4932 - CLI - add parser aliases to long arg names Issue 5332 - BUG - normalise filter as intended Issue 5327 - Validate test metadata Issue 4812 - Scalability with high number of connections (#5090) Issue 4348 - Add tests for dsidm Issue 5333 - 389-ds-base fails to build with Python 3.11 --- .gitignore | 1 + 389-ds-base.spec | 85 +++++++++++++++++++++++++++++------------------- sources | 2 +- 3 files changed, 53 insertions(+), 35 deletions(-) diff --git a/.gitignore b/.gitignore index fbf77bf..6e06a23 100644 --- a/.gitignore +++ b/.gitignore @@ -215,3 +215,4 @@ /389-ds-base-2.1.1.tar.bz2 /jemalloc-5.3.0.tar.bz2 /389-ds-base-2.2.1.tar.bz2 +/389-ds-base-2.2.2.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 9b4c270..bcb766b 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,9 +46,9 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.2.1 -Release: 4%{?dist} -License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and MPLv2.0 and BSD and ASL 2.0 and (ASL 2.0 or Boost) +Version: 2.2.2 +Release: 1%{?dist} +License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and MPLv2.0 and BSD and ASL 2.0 and (ASL 2.0 or Boost) and (ASL 2.0 with exceptions or ASL 2.0 or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 Conflicts: freeipa-server < 4.0.3 @@ -71,77 +71,78 @@ Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 2.34.0 Provides: bundled(crate(concread)) = 0.2.21 Provides: bundled(crate(crossbeam)) = 0.8.1 -Provides: bundled(crate(crossbeam-channel)) = 0.5.4 +Provides: bundled(crate(crossbeam-channel)) = 0.5.5 Provides: bundled(crate(crossbeam-deque)) = 0.8.1 -Provides: bundled(crate(crossbeam-epoch)) = 0.9.8 +Provides: bundled(crate(crossbeam-epoch)) = 0.9.9 Provides: bundled(crate(crossbeam-queue)) = 0.3.5 -Provides: bundled(crate(crossbeam-utils)) = 0.8.8 +Provides: bundled(crate(crossbeam-utils)) = 0.8.10 Provides: bundled(crate(entryuuid)) = 0.1.0 Provides: bundled(crate(entryuuid_syntax)) = 0.1.0 Provides: bundled(crate(fastrand)) = 1.7.0 Provides: bundled(crate(fernet)) = 0.1.4 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 -Provides: bundled(crate(getrandom)) = 0.2.5 +Provides: bundled(crate(getrandom)) = 0.2.7 Provides: bundled(crate(hashbrown)) = 0.11.2 Provides: bundled(crate(hermit-abi)) = 0.1.19 Provides: bundled(crate(instant)) = 0.1.12 -Provides: bundled(crate(itoa)) = 1.0.1 +Provides: bundled(crate(itoa)) = 1.0.2 Provides: bundled(crate(jobserver)) = 0.1.24 -Provides: bundled(crate(lazy_static)) = 1.4.0 -Provides: bundled(crate(libc)) = 0.2.121 +Provides: bundled(crate(libc)) = 0.2.126 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 -Provides: bundled(crate(lock_api)) = 0.4.6 -Provides: bundled(crate(log)) = 0.4.16 -Provides: bundled(crate(lru)) = 0.7.3 +Provides: bundled(crate(lock_api)) = 0.4.7 +Provides: bundled(crate(log)) = 0.4.17 +Provides: bundled(crate(lru)) = 0.7.7 Provides: bundled(crate(memoffset)) = 0.6.5 -Provides: bundled(crate(once_cell)) = 1.10.0 -Provides: bundled(crate(openssl)) = 0.10.38 -Provides: bundled(crate(openssl-sys)) = 0.9.72 +Provides: bundled(crate(once_cell)) = 1.13.0 +Provides: bundled(crate(openssl)) = 0.10.40 +Provides: bundled(crate(openssl-macros)) = 0.1.0 +Provides: bundled(crate(openssl-sys)) = 0.9.74 Provides: bundled(crate(parking_lot)) = 0.11.2 Provides: bundled(crate(parking_lot_core)) = 0.8.5 Provides: bundled(crate(paste)) = 0.1.18 Provides: bundled(crate(paste-impl)) = 0.1.18 -Provides: bundled(crate(pin-project-lite)) = 0.2.8 -Provides: bundled(crate(pkg-config)) = 0.3.24 +Provides: bundled(crate(pin-project-lite)) = 0.2.9 +Provides: bundled(crate(pkg-config)) = 0.3.25 Provides: bundled(crate(ppv-lite86)) = 0.2.16 Provides: bundled(crate(proc-macro-hack)) = 0.5.19 -Provides: bundled(crate(proc-macro2)) = 1.0.36 +Provides: bundled(crate(proc-macro2)) = 1.0.40 Provides: bundled(crate(pwdchan)) = 0.1.0 -Provides: bundled(crate(quote)) = 1.0.16 +Provides: bundled(crate(quote)) = 1.0.20 Provides: bundled(crate(rand)) = 0.8.5 Provides: bundled(crate(rand_chacha)) = 0.3.1 Provides: bundled(crate(rand_core)) = 0.6.3 -Provides: bundled(crate(redox_syscall)) = 0.2.11 +Provides: bundled(crate(redox_syscall)) = 0.2.13 Provides: bundled(crate(remove_dir_all)) = 0.5.3 -Provides: bundled(crate(ryu)) = 1.0.9 +Provides: bundled(crate(ryu)) = 1.0.10 Provides: bundled(crate(scopeguard)) = 1.1.0 -Provides: bundled(crate(serde)) = 1.0.136 -Provides: bundled(crate(serde_derive)) = 1.0.136 -Provides: bundled(crate(serde_json)) = 1.0.79 +Provides: bundled(crate(serde)) = 1.0.138 +Provides: bundled(crate(serde_derive)) = 1.0.138 +Provides: bundled(crate(serde_json)) = 1.0.82 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 -Provides: bundled(crate(smallvec)) = 1.8.0 +Provides: bundled(crate(smallvec)) = 1.9.0 Provides: bundled(crate(strsim)) = 0.8.0 -Provides: bundled(crate(syn)) = 1.0.89 +Provides: bundled(crate(syn)) = 1.0.98 Provides: bundled(crate(synstructure)) = 0.12.6 Provides: bundled(crate(tempfile)) = 3.3.0 Provides: bundled(crate(textwrap)) = 0.11.0 -Provides: bundled(crate(tokio)) = 1.17.0 -Provides: bundled(crate(tokio-macros)) = 1.7.0 -Provides: bundled(crate(toml)) = 0.5.8 +Provides: bundled(crate(tokio)) = 1.19.2 +Provides: bundled(crate(tokio-macros)) = 1.8.0 +Provides: bundled(crate(toml)) = 0.5.9 +Provides: bundled(crate(unicode-ident)) = 1.0.1 Provides: bundled(crate(unicode-width)) = 0.1.9 -Provides: bundled(crate(unicode-xid)) = 0.2.2 +Provides: bundled(crate(unicode-xid)) = 0.2.3 Provides: bundled(crate(uuid)) = 0.8.2 Provides: bundled(crate(vcpkg)) = 0.2.15 Provides: bundled(crate(vec_map)) = 0.8.2 Provides: bundled(crate(version_check)) = 0.9.4 -Provides: bundled(crate(wasi)) = 0.10.2+wasi_snapshot_preview1 +Provides: bundled(crate(wasi)) = 0.11.0+wasi_snapshot_preview1 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 -Provides: bundled(crate(zeroize)) = 1.5.4 +Provides: bundled(crate(zeroize)) = 1.5.6 Provides: bundled(crate(zeroize_derive)) = 1.3.2 ##### Bundled cargo crates list - END ##### @@ -219,7 +220,6 @@ Requires: lmdb-libs Requires: policycoreutils-python-utils Requires: /usr/sbin/semanage Requires: libsemanage-python%{python3_pkgversion} - Requires: selinux-policy >= 3.14.1-29 # the following are needed for some of our scripts @@ -716,6 +716,23 @@ exit 0 %endif %changelog +* Tue Jul 5 2022 Mark Reynolds - 2.2.2-1 +- Bump version to 2.2.2 +- Issue 5221 - fix covscan (#5359) +- Issue 5294 - Report Portal 5 is not processing an XML file with (#5358) +- Issue 5353 - CLI - dsconf backend export breaks with multiple backends +- Issue 5346 - New connection table fails with ASAN failures (#5350) +- Issue 5345 - BUG - openldap migration fails when ppolicy is active (#5347) +- Issue 5323 - BUG - improve skipping of monitor db (#5340) +- Issue 5329 - Improve replication extended op logging +- Issue 5343 - Various improvements to winsync +- Issue 4932 - CLI - add parser aliases to long arg names +- Issue 5332 - BUG - normalise filter as intended +- Issue 5327 - Validate test metadata +- Issue 4812 - Scalability with high number of connections (#5090) +- Issue 4348 - Add tests for dsidm +- Issue 5333 - 389-ds-base fails to build with Python 3.11 + * Thu Jun 16 2022 Python Maint - 2.2.1-4 - Rebuilt for Python 3.11 diff --git a/sources b/sources index fbcd532..da8b92f 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (389-ds-base-2.2.1.tar.bz2) = c0985643d59ffb8e702af48325614c33c141f6469a026e831d9997e5ea9cf8b375453f0f379acf7c38c6b4079e12be9943a3de47ebf34766fce9b70db5b600c4 SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 +SHA512 (389-ds-base-2.2.2.tar.bz2) = 96572dbd5dfb9fb10d353613cc367b8f761f1958d217c7e381a58e9cea13169884453a3f70f7da68289298669371968282c7fdf292c520f389bc2daa394355db From 3ff5ed12ac6ec571690975e602ef151014e396eb Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 20 Jul 2022 18:22:29 +0000 Subject: [PATCH 049/125] Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index bcb766b..c8bbbf3 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,7 +47,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.2.2 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and MPLv2.0 and BSD and ASL 2.0 and (ASL 2.0 or Boost) and (ASL 2.0 with exceptions or ASL 2.0 or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -716,6 +716,9 @@ exit 0 %endif %changelog +* Wed Jul 20 2022 Fedora Release Engineering - 2.2.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + * Tue Jul 5 2022 Mark Reynolds - 2.2.2-1 - Bump version to 2.2.2 - Issue 5221 - fix covscan (#5359) From d9d24b0ede9f1cc0d757e6ac8e5752de942dab01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Zatloukal?= Date: Mon, 1 Aug 2022 15:02:07 +0200 Subject: [PATCH 050/125] Rebuilt for ICU 71.1 --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index c8bbbf3..13d9bf2 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -47,7 +47,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.2.2 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and MPLv2.0 and BSD and ASL 2.0 and (ASL 2.0 or Boost) and (ASL 2.0 with exceptions or ASL 2.0 or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -716,6 +716,9 @@ exit 0 %endif %changelog +* Mon Aug 01 2022 Frantisek Zatloukal - 2.2.2-3 +- Rebuilt for ICU 71.1 + * Wed Jul 20 2022 Fedora Release Engineering - 2.2.2-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild From 165637f066be21238ee4f2a4cb6435e0cc303a28 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Thu, 1 Sep 2022 15:50:20 -0400 Subject: [PATCH 051/125] Bump version to 2.3.0 Issue 5012 - Migrate pcre to pcre2 - remove match limit Issue 5356 - Make Rust non-optional and update default password storage scheme Issue 5012 - Migrate pcre to pcre2 Issue 5428 - Fix regression with nscpEntryWsi computation Fix missing 'not' in description (closes #5423) (#5424) Issue 5421 - CI - makes replication/acceptance_test.py::test_modify_entry more robust (#5422) Issue 3903 - fix repl keep alive event interval Issue 5418 - Sync_repl may crash while managing invalid cookie (#5420) Issue 5415 - Hostname when set to localhost causing failures in other tests Issue 5412 - lib389 - do not set backend name to lowercase Issue 5407 - sync_repl crashes if enabled while dynamic plugin is enabled (#5411) Issue 5385 - LMDB - import crash in rdncache_add_elem (#5406) Issue 5403 - Memory leak in conntection table mulit list (#5404) Issue 3903 - keep alive update event starts too soon Issue 5397 - Fix various memory leaks Issue 5399 - UI - LDAP Editor is not updated when we switch instances (#5400) Issue 3903 - Supplier should do periodic updates Issue 5377 - Code cleanup: Fix Covscan invalid reference (#5393) Issue 5394 - configure doesn't check for lmdb and json-c Issue 5392 - dscreate fails when using alternative ports in the SELinux hi_reserved_port_t label range Issue 5386 - BUG - Update sudoers schema to correctly support UTF-8 (#5387) Issue 5388 - fix use-after-free and deadcode Issue 5383 - UI - Various fixes and RFE's for UI Issue 4656 - Remove problematic language from source code Issue 5380 - Separate cleanAllRUV code into new file Issue 5322 - optime & wtime on rejected connections is not properly set Issue 5335 - RFE - Add Security Audit Log Issue 5375 - CI - disable TLS hostname checking Issue 981 - Managed Entries betxnpreoperation - transaction not aborted on managed entry failure (#5369) Issue 5373 - dsidm user get_dn fails with search_ext() argument 1 must be str, not function Issue 5371 - Update npm and cargo packages Issue 3069 - Support ECDSA private keys for TLS (#5365) Issue 5290 - Importing certificate chain files via "import-server-key-cert" no longer works (#5293) --- .gitignore | 1 + 389-ds-base.spec | 110 +++++++++++++++++++++++++++++------------------ sources | 2 +- 3 files changed, 71 insertions(+), 42 deletions(-) diff --git a/.gitignore b/.gitignore index 6e06a23..70c241e 100644 --- a/.gitignore +++ b/.gitignore @@ -216,3 +216,4 @@ /jemalloc-5.3.0.tar.bz2 /389-ds-base-2.2.1.tar.bz2 /389-ds-base-2.2.2.tar.bz2 +/389-ds-base-2.3.0.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 13d9bf2..ba0e1c2 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -9,7 +9,6 @@ ExcludeArch: i686 %global use_Socket6 0 %global use_asan 0 -%global use_rust 1 %global bundle_jemalloc 1 %if %{use_asan} %global bundle_jemalloc 0 @@ -46,9 +45,9 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.2.2 -Release: 3%{?dist} -License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and MPLv2.0 and BSD and ASL 2.0 and (ASL 2.0 or Boost) and (ASL 2.0 with exceptions or ASL 2.0 or MIT) +Version: 2.3.0 +Release: 1%{?dist} +License: GPLv3+ and (ASL 2.0 or MIT) and MPLv2.0 and BSD URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 Conflicts: freeipa-server < 4.0.3 @@ -70,35 +69,35 @@ Provides: bundled(crate(cc)) = 1.0.73 Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 2.34.0 Provides: bundled(crate(concread)) = 0.2.21 -Provides: bundled(crate(crossbeam)) = 0.8.1 -Provides: bundled(crate(crossbeam-channel)) = 0.5.5 -Provides: bundled(crate(crossbeam-deque)) = 0.8.1 -Provides: bundled(crate(crossbeam-epoch)) = 0.9.9 -Provides: bundled(crate(crossbeam-queue)) = 0.3.5 -Provides: bundled(crate(crossbeam-utils)) = 0.8.10 +Provides: bundled(crate(crossbeam)) = 0.8.2 +Provides: bundled(crate(crossbeam-channel)) = 0.5.6 +Provides: bundled(crate(crossbeam-deque)) = 0.8.2 +Provides: bundled(crate(crossbeam-epoch)) = 0.9.10 +Provides: bundled(crate(crossbeam-queue)) = 0.3.6 +Provides: bundled(crate(crossbeam-utils)) = 0.8.11 Provides: bundled(crate(entryuuid)) = 0.1.0 Provides: bundled(crate(entryuuid_syntax)) = 0.1.0 -Provides: bundled(crate(fastrand)) = 1.7.0 +Provides: bundled(crate(fastrand)) = 1.8.0 Provides: bundled(crate(fernet)) = 0.1.4 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 Provides: bundled(crate(getrandom)) = 0.2.7 -Provides: bundled(crate(hashbrown)) = 0.11.2 +Provides: bundled(crate(hashbrown)) = 0.12.3 Provides: bundled(crate(hermit-abi)) = 0.1.19 Provides: bundled(crate(instant)) = 0.1.12 -Provides: bundled(crate(itoa)) = 1.0.2 +Provides: bundled(crate(itoa)) = 1.0.3 Provides: bundled(crate(jobserver)) = 0.1.24 -Provides: bundled(crate(libc)) = 0.2.126 +Provides: bundled(crate(libc)) = 0.2.132 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 -Provides: bundled(crate(lock_api)) = 0.4.7 +Provides: bundled(crate(lock_api)) = 0.4.8 Provides: bundled(crate(log)) = 0.4.17 -Provides: bundled(crate(lru)) = 0.7.7 +Provides: bundled(crate(lru)) = 0.7.8 Provides: bundled(crate(memoffset)) = 0.6.5 -Provides: bundled(crate(once_cell)) = 1.13.0 -Provides: bundled(crate(openssl)) = 0.10.40 +Provides: bundled(crate(once_cell)) = 1.13.1 +Provides: bundled(crate(openssl)) = 0.10.41 Provides: bundled(crate(openssl-macros)) = 0.1.0 -Provides: bundled(crate(openssl-sys)) = 0.9.74 +Provides: bundled(crate(openssl-sys)) = 0.9.75 Provides: bundled(crate(parking_lot)) = 0.11.2 Provides: bundled(crate(parking_lot_core)) = 0.8.5 Provides: bundled(crate(paste)) = 0.1.18 @@ -107,31 +106,31 @@ Provides: bundled(crate(pin-project-lite)) = 0.2.9 Provides: bundled(crate(pkg-config)) = 0.3.25 Provides: bundled(crate(ppv-lite86)) = 0.2.16 Provides: bundled(crate(proc-macro-hack)) = 0.5.19 -Provides: bundled(crate(proc-macro2)) = 1.0.40 +Provides: bundled(crate(proc-macro2)) = 1.0.43 Provides: bundled(crate(pwdchan)) = 0.1.0 -Provides: bundled(crate(quote)) = 1.0.20 +Provides: bundled(crate(quote)) = 1.0.21 Provides: bundled(crate(rand)) = 0.8.5 Provides: bundled(crate(rand_chacha)) = 0.3.1 Provides: bundled(crate(rand_core)) = 0.6.3 -Provides: bundled(crate(redox_syscall)) = 0.2.13 +Provides: bundled(crate(redox_syscall)) = 0.2.16 Provides: bundled(crate(remove_dir_all)) = 0.5.3 -Provides: bundled(crate(ryu)) = 1.0.10 +Provides: bundled(crate(ryu)) = 1.0.11 Provides: bundled(crate(scopeguard)) = 1.1.0 -Provides: bundled(crate(serde)) = 1.0.138 -Provides: bundled(crate(serde_derive)) = 1.0.138 -Provides: bundled(crate(serde_json)) = 1.0.82 +Provides: bundled(crate(serde)) = 1.0.144 +Provides: bundled(crate(serde_derive)) = 1.0.144 +Provides: bundled(crate(serde_json)) = 1.0.85 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 Provides: bundled(crate(smallvec)) = 1.9.0 Provides: bundled(crate(strsim)) = 0.8.0 -Provides: bundled(crate(syn)) = 1.0.98 +Provides: bundled(crate(syn)) = 1.0.99 Provides: bundled(crate(synstructure)) = 0.12.6 Provides: bundled(crate(tempfile)) = 3.3.0 Provides: bundled(crate(textwrap)) = 0.11.0 -Provides: bundled(crate(tokio)) = 1.19.2 +Provides: bundled(crate(tokio)) = 1.20.1 Provides: bundled(crate(tokio-macros)) = 1.8.0 Provides: bundled(crate(toml)) = 0.5.9 -Provides: bundled(crate(unicode-ident)) = 1.0.1 +Provides: bundled(crate(unicode-ident)) = 1.0.3 Provides: bundled(crate(unicode-width)) = 0.1.9 Provides: bundled(crate(unicode-xid)) = 0.2.3 Provides: bundled(crate(uuid)) = 0.8.2 @@ -142,7 +141,7 @@ Provides: bundled(crate(wasi)) = 0.11.0+wasi_snapshot_preview1 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 -Provides: bundled(crate(zeroize)) = 1.5.6 +Provides: bundled(crate(zeroize)) = 1.5.7 Provides: bundled(crate(zeroize_derive)) = 1.3.2 ##### Bundled cargo crates list - END ##### @@ -154,8 +153,9 @@ BuildRequires: libdb-devel BuildRequires: cyrus-sasl-devel BuildRequires: icu BuildRequires: libicu-devel -BuildRequires: pcre-devel +BuildRequires: pcre2-devel BuildRequires: cracklib-devel +BuildRequires: json-c-devel %if %{use_clang} BuildRequires: libatomic BuildRequires: clang @@ -176,14 +176,12 @@ BuildRequires: systemd-devel %if %{use_asan} BuildRequires: libasan %endif -# If rust is enabled -%if %{use_rust} BuildRequires: cargo BuildRequires: rust -%endif BuildRequires: pkgconfig BuildRequires: pkgconfig(systemd) BuildRequires: pkgconfig(krb5) +BuildRequires: pkgconfig(libpcre2-8) # Needed to support regeneration of the autotool artifacts. BuildRequires: autoconf @@ -228,6 +226,7 @@ Requires: /usr/bin/c_rehash Requires: python%{python3_pkgversion}-ldap Requires: acl Requires: zlib +Requires: json-c # this is needed to setup SSL if you are not using the # administration server package @@ -268,11 +267,6 @@ Source2: %{name}-devel.README Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download/%{jemalloc_ver}/%{jemalloc_name}-%{jemalloc_ver}.tar.bz2 %endif -# Remove this after rust-1.56 lands in repos -%if 0%{?rhel} == 8 -Patch0: concread-use-2018-edition.patch -%endif - %description 389 Directory Server is an LDAPv3 compliant server. The base package includes the LDAP server and command line utilities for server administration. @@ -389,9 +383,7 @@ NSSARGS="--with-nss-lib=%{_libdir} --with-nss-inc=%{_includedir}/nss3" ASAN_FLAGS="--enable-asan --enable-debug" %endif -%if %{use_rust} RUST_FLAGS="--enable-rust --enable-rust-offline" -%endif %if !%{use_cockpit} COCKPIT_FLAGS="--disable-cockpit" @@ -716,6 +708,42 @@ exit 0 %endif %changelog +* Thu Sep 1 2022 Mark Reynolds - 2.3.0-1 +- Bump version to 2.3.0 +- Issue 5012 - Migrate pcre to pcre2 - remove match limit +- Issue 5356 - Make Rust non-optional and update default password storage scheme +- Issue 5012 - Migrate pcre to pcre2 +- Issue 5428 - Fix regression with nscpEntryWsi computation +- Fix missing 'not' in description (closes #5423) (#5424) +- Issue 5421 - CI - makes replication/acceptance_test.py::test_modify_entry more robust (#5422) +- Issue 3903 - fix repl keep alive event interval +- Issue 5418 - Sync_repl may crash while managing invalid cookie (#5420) +- Issue 5415 - Hostname when set to localhost causing failures in other tests +- Issue 5412 - lib389 - do not set backend name to lowercase +- Issue 5407 - sync_repl crashes if enabled while dynamic plugin is enabled (#5411) +- Issue 5385 - LMDB - import crash in rdncache_add_elem (#5406) +- Issue 5403 - Memory leak in conntection table mulit list (#5404) +- Issue 3903 - keep alive update event starts too soon +- Issue 5397 - Fix various memory leaks +- Issue 5399 - UI - LDAP Editor is not updated when we switch instances (#5400) +- Issue 3903 - Supplier should do periodic updates +- Issue 5377 - Code cleanup: Fix Covscan invalid reference (#5393) +- Issue 5394 - configure doesn't check for lmdb and json-c +- Issue 5392 - dscreate fails when using alternative ports in the SELinux hi_reserved_port_t label range +- Issue 5386 - BUG - Update sudoers schema to correctly support UTF-8 (#5387) +- Issue 5388 - fix use-after-free and deadcode +- Issue 5383 - UI - Various fixes and RFE's for UI +- Issue 4656 - Remove problematic language from source code +- Issue 5380 - Separate cleanAllRUV code into new file +- Issue 5322 - optime & wtime on rejected connections is not properly set +- Issue 5335 - RFE - Add Security Audit Log +- Issue 5375 - CI - disable TLS hostname checking +- Issue 981 - Managed Entries betxnpreoperation - transaction not aborted on managed entry failure (#5369) +- Issue 5373 - dsidm user get_dn fails with search_ext() argument 1 must be str, not function +- Issue 5371 - Update npm and cargo packages +- Issue 3069 - Support ECDSA private keys for TLS (#5365) +- Issue 5290 - Importing certificate chain files via "import-server-key-cert" no longer works (#5293) + * Mon Aug 01 2022 Frantisek Zatloukal - 2.2.2-3 - Rebuilt for ICU 71.1 diff --git a/sources b/sources index da8b92f..84cf9a2 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 -SHA512 (389-ds-base-2.2.2.tar.bz2) = 96572dbd5dfb9fb10d353613cc367b8f761f1958d217c7e381a58e9cea13169884453a3f70f7da68289298669371968282c7fdf292c520f389bc2daa394355db +SHA512 (389-ds-base-2.3.0.tar.bz2) = 688ef95106489e3df8161f778aba440ea22b916f8641d612bf428f5c515a2361092a5ab96f5ac6570f09820545394029f1f74221fead65e8504731248f17290e From e4421eca14876e8cff3168ece2bca4504c3fe108 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Tue, 20 Sep 2022 08:52:26 -0400 Subject: [PATCH 052/125] Bump version to 2.3.0-2 Update old pcre-devel requirement to pcre2-devel --- 389-ds-base.spec | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index ba0e1c2..8114554 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.3.0 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) and MPLv2.0 and BSD URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -284,7 +284,7 @@ BuildRequires: openldap-devel BuildRequires: libdb-devel BuildRequires: cyrus-sasl-devel BuildRequires: libicu-devel -BuildRequires: pcre-devel +BuildRequires: pcre2-devel BuildRequires: libtalloc-devel BuildRequires: libevent-devel BuildRequires: libtevent-devel @@ -708,6 +708,10 @@ exit 0 %endif %changelog +* Thu Sep 1 2022 Mark Reynolds - 2.3.0-2 +- Bump version to 2.3.0-2 +- Update old pcre-devel requirement to pcre2-devel + * Thu Sep 1 2022 Mark Reynolds - 2.3.0-1 - Bump version to 2.3.0 - Issue 5012 - Migrate pcre to pcre2 - remove match limit From b82c9972635f6b451786994505b865445a0c3321 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Tue, 20 Sep 2022 08:57:50 -0400 Subject: [PATCH 053/125] Update specfile for pcre2-devel --- 389-ds-base.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 8114554..a0b659f 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -708,7 +708,7 @@ exit 0 %endif %changelog -* Thu Sep 1 2022 Mark Reynolds - 2.3.0-2 +* Tue Sep 20 2022 Mark Reynolds - 2.3.0-2 - Bump version to 2.3.0-2 - Update old pcre-devel requirement to pcre2-devel From 145cec1ec716b5f9c141ee704c0fb956440524c9 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Fri, 18 Nov 2022 08:43:03 -0500 Subject: [PATCH 054/125] Bump version to 2.3.1 Issue 5532 - Make db compaction TOD day more robust. Issue 3729 - RFE Extend log of operations statistics in access log (#5508) Issue 5529 - UI - Fix npm vulnerability in loader-utils Issue 5490 - tombstone in entryrdn index with lmdb but not with bdb (#5498) Issue 5162 - Fix dsctl tls ca-certfiicate add-cert arg requirement Issue 5510 - remove twalk_r dependency to build on RHEL8 (#5516) Issue 5162 - RFE - CLI allow adding CA certificate bundles Issue 5440 - memberof is slow on update/fixup if there are several 'groupattr' (#5455) Issue 5512 - BUG - skip pwdPolicyChecker OC in migration (#5513) Issue 3555 - UI - fix audit issue with npm loader-utils (#5514) Issue 5505 - Fix compiler warning (#5506) Issue 5469 - Increase the default value of nsslapd-conntablesize (#5472) Issue 5408 - lmdb import is slow (#5481) Issue 5429 - healthcheck - add checks for MemberOf group attrs being indexed Issue 5502 - RFE - Add option to display entry attributes in audit log Issue 5495 - BUG - Minor fix to dds skip, inconsistent attrs caused errors (#5501) Issue 5367 - RFE - store full DN in database record Issue 5495 - RFE - skip dds during migration. (#5496) Issue 5491 - UI - Add rework and finish jpegPhoto functionality (#5492) Issue 5368 - Retro Changelog trimming does not work (#5486) Issue 5487 - Fix various issues with logconv.pl Issue 5476 - RFE - add memberUid read aci by default (#5477) Issue 5482 - lib389 - Can not enable replication with a mixed case suffix Issue 5478 - Random crash in connection code during server shutdown (#5479) Issue 3061 - RFE - Add password policy debug log level Issue 5302 - Release tarballs don't contain cockpit webapp Issue 5262 - high contention in find_entry_internal_dn on mixed load (#5264) Issue 4324 - Revert recursive pthread mutex change (#5463) Issue 5462 - RFE - add missing default indexes (#5464) Issue 5465 - Fix dbscan linking (#5466) Issue 5271 - Serialization of pam_passthrough causing high etimes (#5272) Issue 5453 - UI/CLI - Changing Root DN breaks UI Issue 5446 - Fix some covscan issues (#5451) Issue 4308 - checking if an entry is a referral is expensive Issue 5447 - UI - add NDN max cache size to UI Issue 5443 - UI - disable save button while saving Issue 5413 - Allow only one MemberOf fixup task at a time Issue 4592 - dscreate error with custom dir_path (#5434) Issue 5158 - entryuuid fixup tasks fails in replicated topology (#5439) --- .gitignore | 1 + 389-ds-base.spec | 98 ++++++++++++++++++++++++++++++++++-------------- sources | 2 +- 3 files changed, 72 insertions(+), 29 deletions(-) diff --git a/.gitignore b/.gitignore index 70c241e..0e8b0bf 100644 --- a/.gitignore +++ b/.gitignore @@ -217,3 +217,4 @@ /389-ds-base-2.2.1.tar.bz2 /389-ds-base-2.2.2.tar.bz2 /389-ds-base-2.3.0.tar.bz2 +/389-ds-base-2.3.1.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index a0b659f..d4ce302 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -45,9 +45,9 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.3.0 -Release: 2%{?dist} -License: GPLv3+ and (ASL 2.0 or MIT) and MPLv2.0 and BSD +Version: 2.3.1 +Release: 1%{?dist} +License: GPLv3+ and (ASL 2.0 or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 Conflicts: freeipa-server < 4.0.3 @@ -61,78 +61,78 @@ Provides: bundled(crate(ahash)) = 0.7.6 Provides: bundled(crate(ansi_term)) = 0.12.1 Provides: bundled(crate(atty)) = 0.2.14 Provides: bundled(crate(autocfg)) = 1.1.0 -Provides: bundled(crate(base64)) = 0.13.0 +Provides: bundled(crate(base64)) = 0.13.1 Provides: bundled(crate(bitflags)) = 1.3.2 Provides: bundled(crate(byteorder)) = 1.4.3 Provides: bundled(crate(cbindgen)) = 0.9.1 -Provides: bundled(crate(cc)) = 1.0.73 +Provides: bundled(crate(cc)) = 1.0.76 Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 2.34.0 Provides: bundled(crate(concread)) = 0.2.21 Provides: bundled(crate(crossbeam)) = 0.8.2 Provides: bundled(crate(crossbeam-channel)) = 0.5.6 Provides: bundled(crate(crossbeam-deque)) = 0.8.2 -Provides: bundled(crate(crossbeam-epoch)) = 0.9.10 +Provides: bundled(crate(crossbeam-epoch)) = 0.9.11 Provides: bundled(crate(crossbeam-queue)) = 0.3.6 -Provides: bundled(crate(crossbeam-utils)) = 0.8.11 +Provides: bundled(crate(crossbeam-utils)) = 0.8.12 Provides: bundled(crate(entryuuid)) = 0.1.0 Provides: bundled(crate(entryuuid_syntax)) = 0.1.0 Provides: bundled(crate(fastrand)) = 1.8.0 Provides: bundled(crate(fernet)) = 0.1.4 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 -Provides: bundled(crate(getrandom)) = 0.2.7 +Provides: bundled(crate(getrandom)) = 0.2.8 Provides: bundled(crate(hashbrown)) = 0.12.3 Provides: bundled(crate(hermit-abi)) = 0.1.19 Provides: bundled(crate(instant)) = 0.1.12 -Provides: bundled(crate(itoa)) = 1.0.3 -Provides: bundled(crate(jobserver)) = 0.1.24 -Provides: bundled(crate(libc)) = 0.2.132 +Provides: bundled(crate(itoa)) = 1.0.4 +Provides: bundled(crate(jobserver)) = 0.1.25 +Provides: bundled(crate(libc)) = 0.2.137 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 -Provides: bundled(crate(lock_api)) = 0.4.8 +Provides: bundled(crate(lock_api)) = 0.4.9 Provides: bundled(crate(log)) = 0.4.17 Provides: bundled(crate(lru)) = 0.7.8 Provides: bundled(crate(memoffset)) = 0.6.5 -Provides: bundled(crate(once_cell)) = 1.13.1 -Provides: bundled(crate(openssl)) = 0.10.41 +Provides: bundled(crate(once_cell)) = 1.16.0 +Provides: bundled(crate(openssl)) = 0.10.42 Provides: bundled(crate(openssl-macros)) = 0.1.0 -Provides: bundled(crate(openssl-sys)) = 0.9.75 +Provides: bundled(crate(openssl-sys)) = 0.9.77 Provides: bundled(crate(parking_lot)) = 0.11.2 Provides: bundled(crate(parking_lot_core)) = 0.8.5 Provides: bundled(crate(paste)) = 0.1.18 Provides: bundled(crate(paste-impl)) = 0.1.18 Provides: bundled(crate(pin-project-lite)) = 0.2.9 -Provides: bundled(crate(pkg-config)) = 0.3.25 -Provides: bundled(crate(ppv-lite86)) = 0.2.16 +Provides: bundled(crate(pkg-config)) = 0.3.26 +Provides: bundled(crate(ppv-lite86)) = 0.2.17 Provides: bundled(crate(proc-macro-hack)) = 0.5.19 -Provides: bundled(crate(proc-macro2)) = 1.0.43 +Provides: bundled(crate(proc-macro2)) = 1.0.47 Provides: bundled(crate(pwdchan)) = 0.1.0 Provides: bundled(crate(quote)) = 1.0.21 Provides: bundled(crate(rand)) = 0.8.5 Provides: bundled(crate(rand_chacha)) = 0.3.1 -Provides: bundled(crate(rand_core)) = 0.6.3 +Provides: bundled(crate(rand_core)) = 0.6.4 Provides: bundled(crate(redox_syscall)) = 0.2.16 Provides: bundled(crate(remove_dir_all)) = 0.5.3 Provides: bundled(crate(ryu)) = 1.0.11 Provides: bundled(crate(scopeguard)) = 1.1.0 -Provides: bundled(crate(serde)) = 1.0.144 -Provides: bundled(crate(serde_derive)) = 1.0.144 -Provides: bundled(crate(serde_json)) = 1.0.85 +Provides: bundled(crate(serde)) = 1.0.147 +Provides: bundled(crate(serde_derive)) = 1.0.147 +Provides: bundled(crate(serde_json)) = 1.0.88 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 -Provides: bundled(crate(smallvec)) = 1.9.0 +Provides: bundled(crate(smallvec)) = 1.10.0 Provides: bundled(crate(strsim)) = 0.8.0 -Provides: bundled(crate(syn)) = 1.0.99 +Provides: bundled(crate(syn)) = 1.0.103 Provides: bundled(crate(synstructure)) = 0.12.6 Provides: bundled(crate(tempfile)) = 3.3.0 Provides: bundled(crate(textwrap)) = 0.11.0 -Provides: bundled(crate(tokio)) = 1.20.1 +Provides: bundled(crate(tokio)) = 1.21.2 Provides: bundled(crate(tokio-macros)) = 1.8.0 Provides: bundled(crate(toml)) = 0.5.9 -Provides: bundled(crate(unicode-ident)) = 1.0.3 -Provides: bundled(crate(unicode-width)) = 0.1.9 -Provides: bundled(crate(unicode-xid)) = 0.2.3 +Provides: bundled(crate(unicode-ident)) = 1.0.5 +Provides: bundled(crate(unicode-width)) = 0.1.10 +Provides: bundled(crate(unicode-xid)) = 0.2.4 Provides: bundled(crate(uuid)) = 0.8.2 Provides: bundled(crate(vcpkg)) = 0.2.15 Provides: bundled(crate(vec_map)) = 0.8.2 @@ -708,6 +708,48 @@ exit 0 %endif %changelog +* Fri Nov 18 2022 Mark Reynolds - 2.3.1-1 +- Bump version to 2.3.1 +- Issue 5532 - Make db compaction TOD day more robust. +- Issue 3729 - RFE Extend log of operations statistics in access log (#5508) +- Issue 5529 - UI - Fix npm vulnerability in loader-utils +- Issue 5490 - tombstone in entryrdn index with lmdb but not with bdb (#5498) +- Issue 5162 - Fix dsctl tls ca-certfiicate add-cert arg requirement +- Issue 5510 - remove twalk_r dependency to build on RHEL8 (#5516) +- Issue 5162 - RFE - CLI allow adding CA certificate bundles +- Issue 5440 - memberof is slow on update/fixup if there are several 'groupattr' (#5455) +- Issue 5512 - BUG - skip pwdPolicyChecker OC in migration (#5513) +- Issue 3555 - UI - fix audit issue with npm loader-utils (#5514) +- Issue 5505 - Fix compiler warning (#5506) +- Issue 5469 - Increase the default value of nsslapd-conntablesize (#5472) +- Issue 5408 - lmdb import is slow (#5481) +- Issue 5429 - healthcheck - add checks for MemberOf group attrs being indexed +- Issue 5502 - RFE - Add option to display entry attributes in audit log +- Issue 5495 - BUG - Minor fix to dds skip, inconsistent attrs caused errors (#5501) +- Issue 5367 - RFE - store full DN in database record +- Issue 5495 - RFE - skip dds during migration. (#5496) +- Issue 5491 - UI - Add rework and finish jpegPhoto functionality (#5492) +- Issue 5368 - Retro Changelog trimming does not work (#5486) +- Issue 5487 - Fix various issues with logconv.pl +- Issue 5476 - RFE - add memberUid read aci by default (#5477) +- Issue 5482 - lib389 - Can not enable replication with a mixed case suffix +- Issue 5478 - Random crash in connection code during server shutdown (#5479) +- Issue 3061 - RFE - Add password policy debug log level +- Issue 5302 - Release tarballs don't contain cockpit webapp +- Issue 5262 - high contention in find_entry_internal_dn on mixed load (#5264) +- Issue 4324 - Revert recursive pthread mutex change (#5463) +- Issue 5462 - RFE - add missing default indexes (#5464) +- Issue 5465 - Fix dbscan linking (#5466) +- Issue 5271 - Serialization of pam_passthrough causing high etimes (#5272) +- Issue 5453 - UI/CLI - Changing Root DN breaks UI +- Issue 5446 - Fix some covscan issues (#5451) +- Issue 4308 - checking if an entry is a referral is expensive +- Issue 5447 - UI - add NDN max cache size to UI +- Issue 5443 - UI - disable save button while saving +- Issue 5413 - Allow only one MemberOf fixup task at a time +- Issue 4592 - dscreate error with custom dir_path (#5434) +- Issue 5158 - entryuuid fixup tasks fails in replicated topology (#5439) + * Tue Sep 20 2022 Mark Reynolds - 2.3.0-2 - Bump version to 2.3.0-2 - Update old pcre-devel requirement to pcre2-devel diff --git a/sources b/sources index 84cf9a2..5b769d7 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 -SHA512 (389-ds-base-2.3.0.tar.bz2) = 688ef95106489e3df8161f778aba440ea22b916f8641d612bf428f5c515a2361092a5ab96f5ac6570f09820545394029f1f74221fead65e8504731248f17290e +SHA512 (389-ds-base-2.3.1.tar.bz2) = 420250eddbc460f1d4efdbe78f4a0f7191284e959f77013d5a72946ca20b84def96b00fddafe4f98956e1fe461a4d8a21eca0da07d1d6f55ed3c8376dd7629f7 From ac53f0a2be027cba3d2c34768539fe79a5dfdb32 Mon Sep 17 00:00:00 2001 From: Pete Walter Date: Sat, 31 Dec 2022 02:17:06 +0000 Subject: [PATCH 055/125] Rebuild for ICU 72 --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index d4ce302..1deb7f3 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.3.1 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -708,6 +708,9 @@ exit 0 %endif %changelog +* Sat Dec 31 2022 Pete Walter - 2.3.1-2 +- Rebuild for ICU 72 + * Fri Nov 18 2022 Mark Reynolds - 2.3.1-1 - Bump version to 2.3.1 - Issue 5532 - Make db compaction TOD day more robust. From a1e04f6d0540197b56903574d34436392a373451 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 18 Jan 2023 19:34:04 +0000 Subject: [PATCH 056/125] Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 1deb7f3..fcdf7ac 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.3.1 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -708,6 +708,9 @@ exit 0 %endif %changelog +* Wed Jan 18 2023 Fedora Release Engineering - 2.3.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + * Sat Dec 31 2022 Pete Walter - 2.3.1-2 - Rebuild for ICU 72 From 80aafdcae59a519d4b39cc86353df6f893529689 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Mon, 23 Jan 2023 09:22:09 -0500 Subject: [PATCH 057/125] Bump version to 2.3.2 Issue 5547 - automember plugin improvements Issue 5607, 5351, 5611 - UI/CLI - fix various issues Issue 5610 - Build failure on Debian Issue 5608 - UI - need to replace some "const" with "let" Issue 5560 - dscreate run by non superuser set defaults requiring superuser privilege (#5579) Issue 3604 - Create a private key/CSR with dsconf/Cockpit (#5584) Issue 5605 - Adding a slapi_log_backtrace function in libslapd (#5606) Issue 5602 - UI - browser crash when trying to modify read-only variable Issue 5581 - UI - Support cockpit dark theme Issue 5593 - CLI - dsidm account subtree-status fails with TypeError Issue 5591 - BUG - Segfault in cl5configtrim with invalid confi (#5592) Fix latest npm audit failures Issue 5599 - CI - webui tests randomly fail Issue 5348 - RFE - CLI - add functionality to do bulk updates to entries Issue 5588 - Fix CI tests Issue 5585 - lib389 password policy DN handling is incorrect (#5587) Issue 5521 - UI - Update plugins for new split PAM and LDAP pass thru auth Bump json5 from 2.2.1 to 2.2.3 in /src/cockpit/389-console Issue 5236 - UI add specialized group edit modal Issue 5550 - dsconf monitor crashes with Error math domain error (#5553) Issue 5278 - CLI - dsidm asks for the old password on password reset Issue 5531 - CI - use universal_lines in capture_output Issue 5425 - CLI - add confirmation arg when deleting backend Issue 5558 - non-root instance fails to start on creation (#5559) Issue 5545 - A random crash in import over lmdb (#5546) Issue 3615 - CLI - prevent virtual attribute indexing Update specfile and rust crates Issue 5413 - Allow mutliple MemberOf fixup tasks with different bases/filters Issue 5554 - Add more tests to security_basic_test suite (#5555) Issue 5561 - Nightly tests are failing Issue 5521 - RFE - split pass through auth cli Issue 5521 - BUG - Pam PTA multiple issues Issue 5544 - Increase default task TTL Issue 5526 - RFE - Improve saslauthd migration options (#5528) Issue 5539 - Make logger's parameter name unified (#5540) Issue 5541 - Fix typo in `lib389.cli_conf.backend._get_backend` (#5542) Issue 3729 - (cont) RFE Extend log of operations statistics in access log (#5538) Issue 5534 - Fix a rebase typo (#5537) Issue 5534 - Add copyright text to the repository files --- .gitignore | 1 + 389-ds-base.spec | 102 +++++++++++++++++++++++++++++++++++------------ sources | 2 +- 3 files changed, 78 insertions(+), 27 deletions(-) diff --git a/.gitignore b/.gitignore index 0e8b0bf..5262042 100644 --- a/.gitignore +++ b/.gitignore @@ -218,3 +218,4 @@ /389-ds-base-2.2.2.tar.bz2 /389-ds-base-2.3.0.tar.bz2 /389-ds-base-2.3.1.tar.bz2 +/389-ds-base-2.3.2.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index fcdf7ac..e38ed14 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -45,8 +45,8 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.3.1 -Release: 3%{?dist} +Version: 2.3.2 +Release: 1%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -65,16 +65,16 @@ Provides: bundled(crate(base64)) = 0.13.1 Provides: bundled(crate(bitflags)) = 1.3.2 Provides: bundled(crate(byteorder)) = 1.4.3 Provides: bundled(crate(cbindgen)) = 0.9.1 -Provides: bundled(crate(cc)) = 1.0.76 +Provides: bundled(crate(cc)) = 1.0.78 Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 2.34.0 Provides: bundled(crate(concread)) = 0.2.21 Provides: bundled(crate(crossbeam)) = 0.8.2 Provides: bundled(crate(crossbeam-channel)) = 0.5.6 Provides: bundled(crate(crossbeam-deque)) = 0.8.2 -Provides: bundled(crate(crossbeam-epoch)) = 0.9.11 -Provides: bundled(crate(crossbeam-queue)) = 0.3.6 -Provides: bundled(crate(crossbeam-utils)) = 0.8.12 +Provides: bundled(crate(crossbeam-epoch)) = 0.9.13 +Provides: bundled(crate(crossbeam-queue)) = 0.3.8 +Provides: bundled(crate(crossbeam-utils)) = 0.8.14 Provides: bundled(crate(entryuuid)) = 0.1.0 Provides: bundled(crate(entryuuid_syntax)) = 0.1.0 Provides: bundled(crate(fastrand)) = 1.8.0 @@ -85,52 +85,52 @@ Provides: bundled(crate(getrandom)) = 0.2.8 Provides: bundled(crate(hashbrown)) = 0.12.3 Provides: bundled(crate(hermit-abi)) = 0.1.19 Provides: bundled(crate(instant)) = 0.1.12 -Provides: bundled(crate(itoa)) = 1.0.4 +Provides: bundled(crate(itoa)) = 1.0.5 Provides: bundled(crate(jobserver)) = 0.1.25 -Provides: bundled(crate(libc)) = 0.2.137 +Provides: bundled(crate(libc)) = 0.2.139 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 Provides: bundled(crate(lock_api)) = 0.4.9 Provides: bundled(crate(log)) = 0.4.17 Provides: bundled(crate(lru)) = 0.7.8 -Provides: bundled(crate(memoffset)) = 0.6.5 -Provides: bundled(crate(once_cell)) = 1.16.0 -Provides: bundled(crate(openssl)) = 0.10.42 +Provides: bundled(crate(memoffset)) = 0.7.1 +Provides: bundled(crate(once_cell)) = 1.17.0 +Provides: bundled(crate(openssl)) = 0.10.45 Provides: bundled(crate(openssl-macros)) = 0.1.0 -Provides: bundled(crate(openssl-sys)) = 0.9.77 +Provides: bundled(crate(openssl-sys)) = 0.9.80 Provides: bundled(crate(parking_lot)) = 0.11.2 -Provides: bundled(crate(parking_lot_core)) = 0.8.5 +Provides: bundled(crate(parking_lot_core)) = 0.8.6 Provides: bundled(crate(paste)) = 0.1.18 Provides: bundled(crate(paste-impl)) = 0.1.18 Provides: bundled(crate(pin-project-lite)) = 0.2.9 Provides: bundled(crate(pkg-config)) = 0.3.26 Provides: bundled(crate(ppv-lite86)) = 0.2.17 -Provides: bundled(crate(proc-macro-hack)) = 0.5.19 -Provides: bundled(crate(proc-macro2)) = 1.0.47 +Provides: bundled(crate(proc-macro-hack)) = 0.5.20+deprecated +Provides: bundled(crate(proc-macro2)) = 1.0.50 Provides: bundled(crate(pwdchan)) = 0.1.0 -Provides: bundled(crate(quote)) = 1.0.21 +Provides: bundled(crate(quote)) = 1.0.23 Provides: bundled(crate(rand)) = 0.8.5 Provides: bundled(crate(rand_chacha)) = 0.3.1 Provides: bundled(crate(rand_core)) = 0.6.4 Provides: bundled(crate(redox_syscall)) = 0.2.16 Provides: bundled(crate(remove_dir_all)) = 0.5.3 -Provides: bundled(crate(ryu)) = 1.0.11 +Provides: bundled(crate(ryu)) = 1.0.12 Provides: bundled(crate(scopeguard)) = 1.1.0 -Provides: bundled(crate(serde)) = 1.0.147 -Provides: bundled(crate(serde_derive)) = 1.0.147 -Provides: bundled(crate(serde_json)) = 1.0.88 +Provides: bundled(crate(serde)) = 1.0.152 +Provides: bundled(crate(serde_derive)) = 1.0.152 +Provides: bundled(crate(serde_json)) = 1.0.91 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 Provides: bundled(crate(smallvec)) = 1.10.0 Provides: bundled(crate(strsim)) = 0.8.0 -Provides: bundled(crate(syn)) = 1.0.103 +Provides: bundled(crate(syn)) = 1.0.107 Provides: bundled(crate(synstructure)) = 0.12.6 Provides: bundled(crate(tempfile)) = 3.3.0 Provides: bundled(crate(textwrap)) = 0.11.0 -Provides: bundled(crate(tokio)) = 1.21.2 -Provides: bundled(crate(tokio-macros)) = 1.8.0 -Provides: bundled(crate(toml)) = 0.5.9 -Provides: bundled(crate(unicode-ident)) = 1.0.5 +Provides: bundled(crate(tokio)) = 1.24.2 +Provides: bundled(crate(tokio-macros)) = 1.8.2 +Provides: bundled(crate(toml)) = 0.5.11 +Provides: bundled(crate(unicode-ident)) = 1.0.6 Provides: bundled(crate(unicode-width)) = 0.1.10 Provides: bundled(crate(unicode-xid)) = 0.2.4 Provides: bundled(crate(uuid)) = 0.8.2 @@ -141,8 +141,16 @@ Provides: bundled(crate(wasi)) = 0.11.0+wasi_snapshot_preview1 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 +Provides: bundled(crate(windows-sys)) = 0.42.0 +Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.42.1 +Provides: bundled(crate(windows_aarch64_msvc)) = 0.42.1 +Provides: bundled(crate(windows_i686_gnu)) = 0.42.1 +Provides: bundled(crate(windows_i686_msvc)) = 0.42.1 +Provides: bundled(crate(windows_x86_64_gnu)) = 0.42.1 +Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.42.1 +Provides: bundled(crate(windows_x86_64_msvc)) = 0.42.1 Provides: bundled(crate(zeroize)) = 1.5.7 -Provides: bundled(crate(zeroize_derive)) = 1.3.2 +Provides: bundled(crate(zeroize_derive)) = 1.3.3 ##### Bundled cargo crates list - END ##### BuildRequires: nspr-devel >= 4.32 @@ -708,6 +716,48 @@ exit 0 %endif %changelog +* Mon Jan 23 2023 Mark Reynolds - 2.3.2-1 +- Bump version to 2.3.2 +- Issue 5547 - automember plugin improvements +- Issue 5607, 5351, 5611 - UI/CLI - fix various issues +- Issue 5610 - Build failure on Debian +- Issue 5608 - UI - need to replace some "const" with "let" +- Issue 5560 - dscreate run by non superuser set defaults requiring superuser privilege (#5579) +- Issue 3604 - Create a private key/CSR with dsconf/Cockpit (#5584) +- Issue 5605 - Adding a slapi_log_backtrace function in libslapd (#5606) +- Issue 5602 - UI - browser crash when trying to modify read-only variable +- Issue 5581 - UI - Support cockpit dark theme +- Issue 5593 - CLI - dsidm account subtree-status fails with TypeError +- Issue 5591 - BUG - Segfault in cl5configtrim with invalid confi (#5592) +- Fix latest npm audit failures +- Issue 5599 - CI - webui tests randomly fail +- Issue 5348 - RFE - CLI - add functionality to do bulk updates to entries +- Issue 5588 - Fix CI tests +- Issue 5585 - lib389 password policy DN handling is incorrect (#5587) +- Issue 5521 - UI - Update plugins for new split PAM and LDAP pass thru auth +- Bump json5 from 2.2.1 to 2.2.3 in /src/cockpit/389-console +- Issue 5236 - UI add specialized group edit modal +- Issue 5550 - dsconf monitor crashes with Error math domain error (#5553) +- Issue 5278 - CLI - dsidm asks for the old password on password reset +- Issue 5531 - CI - use universal_lines in capture_output +- Issue 5425 - CLI - add confirmation arg when deleting backend +- Issue 5558 - non-root instance fails to start on creation (#5559) +- Issue 5545 - A random crash in import over lmdb (#5546) +- Issue 3615 - CLI - prevent virtual attribute indexing +- Update specfile and rust crates +- Issue 5413 - Allow mutliple MemberOf fixup tasks with different bases/filters +- Issue 5554 - Add more tests to security_basic_test suite (#5555) +- Issue 5561 - Nightly tests are failing +- Issue 5521 - RFE - split pass through auth cli +- Issue 5521 - BUG - Pam PTA multiple issues +- Issue 5544 - Increase default task TTL +- Issue 5526 - RFE - Improve saslauthd migration options (#5528) +- Issue 5539 - Make logger's parameter name unified (#5540) +- Issue 5541 - Fix typo in `lib389.cli_conf.backend._get_backend` (#5542) +- Issue 3729 - (cont) RFE Extend log of operations statistics in access log (#5538) +- Issue 5534 - Fix a rebase typo (#5537) +- Issue 5534 - Add copyright text to the repository files + * Wed Jan 18 2023 Fedora Release Engineering - 2.3.1-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild diff --git a/sources b/sources index 5b769d7..4ae6d85 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 -SHA512 (389-ds-base-2.3.1.tar.bz2) = 420250eddbc460f1d4efdbe78f4a0f7191284e959f77013d5a72946ca20b84def96b00fddafe4f98956e1fe461a4d8a21eca0da07d1d6f55ed3c8376dd7629f7 +SHA512 (389-ds-base-2.3.2.tar.bz2) = 20bf8e2ce1781886e62a9500cdf709d11b860f0f61de44ecb1be7c3a6be1fe306783b6eeb3e37933f494c640dd140e247a4a266091ffd81cf00f58af37e6577e From 8550918238de24692b76766600ebab82d11980b4 Mon Sep 17 00:00:00 2001 From: Simon Pichugin Date: Tue, 28 Feb 2023 11:46:30 -0800 Subject: [PATCH 058/125] Use systemd-sysusers for dirsrv user and group (#2173834) --- 389-ds-base.spec | 26 +++++++++++--------------- 389-ds-base.sysusers | 3 +++ 2 files changed, 14 insertions(+), 15 deletions(-) create mode 100644 389-ds-base.sysusers diff --git a/389-ds-base.spec b/389-ds-base.spec index e38ed14..1cb8c88 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.3.2 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -181,6 +181,8 @@ BuildRequires: openssl-devel BuildRequires: pam-devel BuildRequires: systemd-units BuildRequires: systemd-devel +BuildRequires: systemd-rpm-macros +%{?sysusers_requires_compat} %if %{use_asan} BuildRequires: libasan %endif @@ -274,6 +276,7 @@ Source2: %{name}-devel.README %if %{bundle_jemalloc} Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download/%{jemalloc_ver}/%{jemalloc_name}-%{jemalloc_ver}.tar.bz2 %endif +Source4: 389-ds-base.sysusers %description 389 Directory Server is an LDAPv3 compliant server. The base package includes @@ -492,6 +495,7 @@ mkdir -p $RPM_BUILD_ROOT/var/lock/%{pkgname} # for systemd mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/systemd/system/%{groupname}.wants +install -p -D -m 0644 %{SOURCE4} %{buildroot}%{_sysusersdir}/389-ds-base.conf # remove libtool archives and static libs rm -f $RPM_BUILD_ROOT%{_libdir}/%{pkgname}/*.a @@ -526,20 +530,8 @@ fi # https://fedoraproject.org/wiki/Packaging:UsersAndGroups#Soft_static_allocation # Soft static allocation for UID and GID -USERNAME="dirsrv" -ALLOCATED_UID=389 -GROUPNAME="dirsrv" -ALLOCATED_GID=389 -HOMEDIR="/usr/share/dirsrv" - -getent group $GROUPNAME >/dev/null || /usr/sbin/groupadd -f -g $ALLOCATED_GID -r $GROUPNAME -if ! getent passwd $USERNAME >/dev/null ; then - if ! getent passwd $ALLOCATED_UID >/dev/null ; then - /usr/sbin/useradd -r -u $ALLOCATED_UID -g $GROUPNAME -d $HOMEDIR -s /sbin/nologin -c "user for 389-ds-base" $USERNAME - else - /usr/sbin/useradd -r -g $GROUPNAME -d $HOMEDIR -s /sbin/nologin -c "user for 389-ds-base" $USERNAME - fi -fi +# sysusers.d format https://fedoraproject.org/wiki/Changes/Adopting_sysusers.d_format +%sysusers_create_compat %{SOURCE4} # Reload our sysctl before we restart (if we can) sysctl --system &> $output; true @@ -613,6 +605,7 @@ exit 0 %config(noreplace)%{_sysconfdir}/%{pkgname}/schema/*.ldif %dir %{_sysconfdir}/%{pkgname}/config %dir %{_sysconfdir}/systemd/system/%{groupname}.wants +%{_sysusersdir}/389-ds-base.conf %config(noreplace)%{_sysconfdir}/%{pkgname}/config/slapd-collations.conf %config(noreplace)%{_sysconfdir}/%{pkgname}/config/certmap.conf %{_datadir}/%{pkgname} @@ -716,6 +709,9 @@ exit 0 %endif %changelog +* Tue Feb 28 2023 Simon Pichugin - 2.3.2-2 +- Use systemd-sysusers for dirsrv user and group (#2173834) + * Mon Jan 23 2023 Mark Reynolds - 2.3.2-1 - Bump version to 2.3.2 - Issue 5547 - automember plugin improvements diff --git a/389-ds-base.sysusers b/389-ds-base.sysusers new file mode 100644 index 0000000..32a3452 --- /dev/null +++ b/389-ds-base.sysusers @@ -0,0 +1,3 @@ +#Type Name ID GECOS Home directory Shell +g dirsrv 389 +u dirsrv 389:389 "user for 389-ds-base" /usr/share/dirsrv/ /sbin/nologin From cc94ca8b85307cbe404f46e18f8f838eb1bc2aed Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Fri, 31 Mar 2023 10:21:48 +0200 Subject: [PATCH 059/125] Fix build issue against setuptools 67.0.0 (#2183375) --- 389-ds-base.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 1cb8c88..60e467c 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.3.2 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -277,6 +277,7 @@ Source2: %{name}-devel.README Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download/%{jemalloc_ver}/%{jemalloc_name}-%{jemalloc_ver}.tar.bz2 %endif Source4: 389-ds-base.sysusers +Patch0: 0001-Issue-5642-Build-fails-against-setuptools-67.0.0.patch %description 389 Directory Server is an LDAPv3 compliant server. The base package includes @@ -709,6 +710,9 @@ exit 0 %endif %changelog +* Fri Mar 31 2023 Viktor Ashirov - 2.3.2-3 +- Fix build issue against setuptools 67.0.0 (#2183375) + * Tue Feb 28 2023 Simon Pichugin - 2.3.2-2 - Use systemd-sysusers for dirsrv user and group (#2173834) From 763153ab352c41bea798d80e55aa9700cb48e048 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Fri, 31 Mar 2023 10:24:04 +0200 Subject: [PATCH 060/125] Add missing patch --- ...uild-fails-against-setuptools-67.0.0.patch | 180 ++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 0001-Issue-5642-Build-fails-against-setuptools-67.0.0.patch diff --git a/0001-Issue-5642-Build-fails-against-setuptools-67.0.0.patch b/0001-Issue-5642-Build-fails-against-setuptools-67.0.0.patch new file mode 100644 index 0000000..371cc6f --- /dev/null +++ b/0001-Issue-5642-Build-fails-against-setuptools-67.0.0.patch @@ -0,0 +1,180 @@ +From c0e2f68423ddde9bb91250d3f96dfc8617889514 Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +Date: Mon, 13 Feb 2023 18:39:20 +0100 +Subject: [PATCH] Issue 5642 - Build fails against setuptools 67.0.0 + +Bug Description: +`setuptools` 67.0.0 vendors `packaging` 23.0 which dropped `LegacyVersion`. + +Fix Description: +Replace `LegacyVersion` with `DSVersion` to compare version strings that are +not compatible with PEP 440 and PEP 508. + +Reviewed by: @mreynolds389, @progier389 + +Fixes: https://github.com/389ds/389-ds-base/issues/5642 +--- + src/lib389/lib389/nss_ssl.py | 11 +--- + src/lib389/lib389/tests/dsversion_test.py | 12 ++++ + src/lib389/lib389/utils.py | 80 ++++++++++++++++++++--- + 3 files changed, 86 insertions(+), 17 deletions(-) + create mode 100644 src/lib389/lib389/tests/dsversion_test.py + +diff --git a/src/lib389/lib389/nss_ssl.py b/src/lib389/lib389/nss_ssl.py +index 9e4ac09f8..d5e5c4679 100644 +--- a/src/lib389/lib389/nss_ssl.py ++++ b/src/lib389/lib389/nss_ssl.py +@@ -23,16 +23,9 @@ + from lib389.passwd import password_generate + from lib389._mapped_object_lint import DSLint + from lib389.lint import DSCERTLE0001, DSCERTLE0002 +-from lib389.utils import ensure_str, format_cmd_list ++from lib389.utils import ensure_str, format_cmd_list, DSVersion + import uuid + +-# Setuptools ships with 'packaging' module, let's use it from there +-try: +- from pkg_resources.extern.packaging.version import LegacyVersion +-# Fallback to a normal 'packaging' module in case 'setuptools' is stripped +-except: +- from packaging.version import LegacyVersion +- + KEYBITS = 4096 + CA_NAME = 'Self-Signed-CA' + CERT_NAME = 'Server-Cert' +@@ -249,7 +242,7 @@ def openssl_rehash(self, certdir): + openssl_version = check_output(['/usr/bin/openssl', 'version']).decode('utf-8').strip() + except subprocess.CalledProcessError as e: + raise ValueError(e.output.decode('utf-8').rstrip()) +- rehash_available = LegacyVersion(openssl_version.split(' ')[1]) >= LegacyVersion('1.1.0') ++ rehash_available = DSVersion(openssl_version.split(' ')[1]) >= DSVersion('1.1.0') + + if rehash_available: + cmd = ['/usr/bin/openssl', 'rehash', certdir] +diff --git a/src/lib389/lib389/tests/dsversion_test.py b/src/lib389/lib389/tests/dsversion_test.py +new file mode 100644 +index 000000000..2a420067f +--- /dev/null ++++ b/src/lib389/lib389/tests/dsversion_test.py +@@ -0,0 +1,12 @@ ++from lib389.utils import DSVersion ++import pytest ++ ++versions = [('1.3.10.1', '1.3.2.1'), ++ ('2.3.2', '1.4.4.4'), ++ ('2.3.2.202302121950git1b4f5a5bf', '2.3.2'), ++ ('1.1.0a', '1.1.0')] ++ ++@pytest.mark.parametrize("x,y", versions) ++def test_dsversion(x, y): ++ assert DSVersion(x) > DSVersion(y) ++ +diff --git a/src/lib389/lib389/utils.py b/src/lib389/lib389/utils.py +index 5566184b0..af77e519b 100644 +--- a/src/lib389/lib389/utils.py ++++ b/src/lib389/lib389/utils.py +@@ -42,12 +42,6 @@ def wait(self): + import subprocess + import math + import errno +-# Setuptools ships with 'packaging' module, let's use it from there +-try: +- from pkg_resources.extern.packaging.version import LegacyVersion +-# Fallback to a normal 'packaging' module in case 'setuptools' is stripped +-except: +- from packaging.version import LegacyVersion + from socket import getfqdn + from ldapurl import LDAPUrl + from contextlib import closing +@@ -1218,6 +1212,76 @@ def generate_ds_params(inst_num, role=ReplicaRole.STANDALONE): + + return instance_data + ++class DSVersion(): ++ def __init__(self, version): ++ self._version = str(version) ++ self._key = _cmpkey(self._version) ++ ++ def __str__(self): ++ return self._version ++ ++ def __repr__(self): ++ return f"" ++ ++ def __hash__(self): ++ return hash(self._key) ++ ++ def __lt__(self, other): ++ if not isinstance(other, DSVersion): ++ return NotImplemented ++ ++ return self._key < other._key ++ ++ def __le__(self, other): ++ if not isinstance(other, DSVersion): ++ return NotImplemented ++ ++ return self._key <= other._key ++ ++ def __eq__(self, other): ++ if not isinstance(other, DSVersion): ++ return NotImplemented ++ ++ return self._key == other._key ++ ++ def __ge__(self, other): ++ if not isinstance(other, DSVersion): ++ return NotImplemented ++ ++ return self._key >= other._key ++ ++ def __gt__(self, other): ++ if not isinstance(other, DSVersion): ++ return NotImplemented ++ ++ return self._key > other._key ++ ++ def __ne__(self, other): ++ if not isinstance(other, DSVersion): ++ return NotImplemented ++ ++ return self._key != other._key ++ ++ ++def _parse_version_parts(s): ++ for part in re.compile(r"(\d+ | [a-z]+ | \. | -)", re.VERBOSE).split(s): ++ ++ if not part or part == ".": ++ continue ++ ++ if part[:1] in "0123456789": ++ # pad for numeric comparison ++ yield part.zfill(8) ++ else: ++ yield "*" + part ++ ++def _cmpkey(version): ++ parts = [] ++ for part in _parse_version_parts(version.lower()): ++ parts.append(part) ++ ++ return tuple(parts) ++ + + def get_ds_version(paths=None): + """ +@@ -1245,9 +1309,9 @@ def ds_is_related(relation, *ver, instance=None): + if len(ver) > 1: + for cmp_ver in ver: + if cmp_ver.startswith(ds_ver[:3]): +- return ops[relation](LegacyVersion(ds_ver),LegacyVersion(cmp_ver)) ++ return ops[relation](DSVersion(ds_ver), DSVersion(cmp_ver)) + else: +- return ops[relation](LegacyVersion(ds_ver), LegacyVersion(ver[0])) ++ return ops[relation](DSVersion(ds_ver), DSVersion(ver[0])) + + + def ds_is_older(*ver, instance=None): +-- +2.39.2 + From 4278187fdb1370948d33bc7909803e675d7ad34c Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Tue, 25 Apr 2023 16:18:53 -0400 Subject: [PATCH 061/125] Bump version to 2.4.0 Issue 5156 - RFE that implement slapi_memberof (#5694) Issue 5734 - RFE - Exclude pwdFailureTime and ContextCSN (#5735) Issue 5726 - ns-slapd crashing in ldbm_back_upgradednformat (#5727) Issue 4758 - Add tests for WebUI Issue 5718 - Memory leak in connection table (#5719) Issue 5705 - Add config parameter to close client conns on failed bind (#5712) Issue 4758 - Add tests for WebUI Issue 5643 - Memory leak in entryrdn during delete (#5717) Issue 5714 - UI - fix typo, db settings, log settings, and LDAP editor paginations Issue 5701 - CLI - Fix referral mode setting (#5708) Bump openssl from 0.10.45 to 0.10.48 in /src (#5709) Issue 5710 - subtree search statistics for index lookup does not report ancestorid/entryrdn lookups (#5711) Issue 5697 - Obsolete nsslapd-ldapimaprootdn attribute (#5698) Issue 1081 - Stop schema replication from overwriting x-origin Issue 4812 - Listener thread does not scale with a high num of established connections (#5706) Issue 4812 - Listener thread does not scale with a high num of established connections (#5681) Bump webpack from 5.75.0 to 5.76.0 in /src/cockpit/389-console (#5699) Issue 5598 - (3rd) In 2.x, SRCH throughput drops by 10% because of handling of referral (#5692) Issue 5598 - (2nd) In 2.x, SRCH throughput drops by 10% because of handling of referral (#5691) Issue 5687 - UI - sensitive information disclosure Issue 5661 - LMDB hangs while Rebuilding the replication changelog RUV (#5676) Issue 5554 - Add more tests to security_basic_test suite Issue 4583 - Update specfile to skip checks of ASAN builds Issue 4758 - Add tests for WebUI Issue 3604 - UI - Add support for Subject Alternative Names in CSR Issue 5600 - buffer overflow when enabling sync repl plugin when dynamic plugins is enabled Issue 5640 - Update logconv for new logging format Issue 5162 - CI - fix error message for invalid pem file Issue 5598 - In 2.x, SRCH throughput drops by 10% because of handling of referral (#5604) Issue 5671 - covscan - clang warning (#5672) Issue 5267 - CI - Fix issues with nsslapd-return-original-entrydn Issue 5666 - CLI - Add timeout parameter for tasks Issue 5567 - CLI - make ldifgen use the same default ldif name for all options Issue 5647 - Fix unused variable warning from previous commit (#5670) Issue 5162 - Lib389 - verify certificate type before adding Issue 5642 - Build fails against setuptools 67.0.0 Issue 5630 - CLI - need to add logging filter for stdout Issue 5646 - CLI/UI - do not hardcode password storage schemes Issue 5640 - Update logconv for new logging format issue 5647 - covscan: memory leak in audit log when adding entries (#5650) Issue 5658 - CLI - unable to add attribute with matching rule Issue 5653 - covscan - fix invalid dereference Issue 5652 - Libasan crash in replication/cascading_test (#5659) Issue 5628 - Handle graceful timeout in CI tests (#5657) Issue 5648 - Covscan - Compiler warnings (#5651) Issue 5630 - CLI - error messages should goto stderr Issue 2435 - RFE - Raise IDL Scan Limit to INT_MAX (#5639) Issue 5632 - CLI - improve error handling with db2ldif Issue 5517 - Replication conflict CI test sometime fails (#5518) Issue 5634 - Deprecated warning related to github action workflow code (#5635) Issue 5637 - Covscan - fix Buffer Overflows (#5638) Issue 5624 - RFE - UI - export certificates, and import text base64 encoded certificates Bump tokio from 1.24.1 to 1.25.0 in /src (#5629) Issue 4577 - Add LMDB pytest github action (#5627) Issue 4293 - RFE - CLI - add dsrc options for setting user and group subtrees Remove stale libevent(-devel) dependency Issue 5578 - dscreate ds-root does not normaile paths (#5613) Issue 5497 - boolean attributes should be case insensitive --- .gitignore | 1 + ...uild-fails-against-setuptools-67.0.0.patch | 180 ------------------ 389-ds-base.spec | 163 +++++++++++----- sources | 2 +- 4 files changed, 122 insertions(+), 224 deletions(-) delete mode 100644 0001-Issue-5642-Build-fails-against-setuptools-67.0.0.patch diff --git a/.gitignore b/.gitignore index 5262042..6fac6d8 100644 --- a/.gitignore +++ b/.gitignore @@ -219,3 +219,4 @@ /389-ds-base-2.3.0.tar.bz2 /389-ds-base-2.3.1.tar.bz2 /389-ds-base-2.3.2.tar.bz2 +/389-ds-base-2.4.0.tar.bz2 diff --git a/0001-Issue-5642-Build-fails-against-setuptools-67.0.0.patch b/0001-Issue-5642-Build-fails-against-setuptools-67.0.0.patch deleted file mode 100644 index 371cc6f..0000000 --- a/0001-Issue-5642-Build-fails-against-setuptools-67.0.0.patch +++ /dev/null @@ -1,180 +0,0 @@ -From c0e2f68423ddde9bb91250d3f96dfc8617889514 Mon Sep 17 00:00:00 2001 -From: Viktor Ashirov -Date: Mon, 13 Feb 2023 18:39:20 +0100 -Subject: [PATCH] Issue 5642 - Build fails against setuptools 67.0.0 - -Bug Description: -`setuptools` 67.0.0 vendors `packaging` 23.0 which dropped `LegacyVersion`. - -Fix Description: -Replace `LegacyVersion` with `DSVersion` to compare version strings that are -not compatible with PEP 440 and PEP 508. - -Reviewed by: @mreynolds389, @progier389 - -Fixes: https://github.com/389ds/389-ds-base/issues/5642 ---- - src/lib389/lib389/nss_ssl.py | 11 +--- - src/lib389/lib389/tests/dsversion_test.py | 12 ++++ - src/lib389/lib389/utils.py | 80 ++++++++++++++++++++--- - 3 files changed, 86 insertions(+), 17 deletions(-) - create mode 100644 src/lib389/lib389/tests/dsversion_test.py - -diff --git a/src/lib389/lib389/nss_ssl.py b/src/lib389/lib389/nss_ssl.py -index 9e4ac09f8..d5e5c4679 100644 ---- a/src/lib389/lib389/nss_ssl.py -+++ b/src/lib389/lib389/nss_ssl.py -@@ -23,16 +23,9 @@ - from lib389.passwd import password_generate - from lib389._mapped_object_lint import DSLint - from lib389.lint import DSCERTLE0001, DSCERTLE0002 --from lib389.utils import ensure_str, format_cmd_list -+from lib389.utils import ensure_str, format_cmd_list, DSVersion - import uuid - --# Setuptools ships with 'packaging' module, let's use it from there --try: -- from pkg_resources.extern.packaging.version import LegacyVersion --# Fallback to a normal 'packaging' module in case 'setuptools' is stripped --except: -- from packaging.version import LegacyVersion -- - KEYBITS = 4096 - CA_NAME = 'Self-Signed-CA' - CERT_NAME = 'Server-Cert' -@@ -249,7 +242,7 @@ def openssl_rehash(self, certdir): - openssl_version = check_output(['/usr/bin/openssl', 'version']).decode('utf-8').strip() - except subprocess.CalledProcessError as e: - raise ValueError(e.output.decode('utf-8').rstrip()) -- rehash_available = LegacyVersion(openssl_version.split(' ')[1]) >= LegacyVersion('1.1.0') -+ rehash_available = DSVersion(openssl_version.split(' ')[1]) >= DSVersion('1.1.0') - - if rehash_available: - cmd = ['/usr/bin/openssl', 'rehash', certdir] -diff --git a/src/lib389/lib389/tests/dsversion_test.py b/src/lib389/lib389/tests/dsversion_test.py -new file mode 100644 -index 000000000..2a420067f ---- /dev/null -+++ b/src/lib389/lib389/tests/dsversion_test.py -@@ -0,0 +1,12 @@ -+from lib389.utils import DSVersion -+import pytest -+ -+versions = [('1.3.10.1', '1.3.2.1'), -+ ('2.3.2', '1.4.4.4'), -+ ('2.3.2.202302121950git1b4f5a5bf', '2.3.2'), -+ ('1.1.0a', '1.1.0')] -+ -+@pytest.mark.parametrize("x,y", versions) -+def test_dsversion(x, y): -+ assert DSVersion(x) > DSVersion(y) -+ -diff --git a/src/lib389/lib389/utils.py b/src/lib389/lib389/utils.py -index 5566184b0..af77e519b 100644 ---- a/src/lib389/lib389/utils.py -+++ b/src/lib389/lib389/utils.py -@@ -42,12 +42,6 @@ def wait(self): - import subprocess - import math - import errno --# Setuptools ships with 'packaging' module, let's use it from there --try: -- from pkg_resources.extern.packaging.version import LegacyVersion --# Fallback to a normal 'packaging' module in case 'setuptools' is stripped --except: -- from packaging.version import LegacyVersion - from socket import getfqdn - from ldapurl import LDAPUrl - from contextlib import closing -@@ -1218,6 +1212,76 @@ def generate_ds_params(inst_num, role=ReplicaRole.STANDALONE): - - return instance_data - -+class DSVersion(): -+ def __init__(self, version): -+ self._version = str(version) -+ self._key = _cmpkey(self._version) -+ -+ def __str__(self): -+ return self._version -+ -+ def __repr__(self): -+ return f"" -+ -+ def __hash__(self): -+ return hash(self._key) -+ -+ def __lt__(self, other): -+ if not isinstance(other, DSVersion): -+ return NotImplemented -+ -+ return self._key < other._key -+ -+ def __le__(self, other): -+ if not isinstance(other, DSVersion): -+ return NotImplemented -+ -+ return self._key <= other._key -+ -+ def __eq__(self, other): -+ if not isinstance(other, DSVersion): -+ return NotImplemented -+ -+ return self._key == other._key -+ -+ def __ge__(self, other): -+ if not isinstance(other, DSVersion): -+ return NotImplemented -+ -+ return self._key >= other._key -+ -+ def __gt__(self, other): -+ if not isinstance(other, DSVersion): -+ return NotImplemented -+ -+ return self._key > other._key -+ -+ def __ne__(self, other): -+ if not isinstance(other, DSVersion): -+ return NotImplemented -+ -+ return self._key != other._key -+ -+ -+def _parse_version_parts(s): -+ for part in re.compile(r"(\d+ | [a-z]+ | \. | -)", re.VERBOSE).split(s): -+ -+ if not part or part == ".": -+ continue -+ -+ if part[:1] in "0123456789": -+ # pad for numeric comparison -+ yield part.zfill(8) -+ else: -+ yield "*" + part -+ -+def _cmpkey(version): -+ parts = [] -+ for part in _parse_version_parts(version.lower()): -+ parts.append(part) -+ -+ return tuple(parts) -+ - - def get_ds_version(paths=None): - """ -@@ -1245,9 +1309,9 @@ def ds_is_related(relation, *ver, instance=None): - if len(ver) > 1: - for cmp_ver in ver: - if cmp_ver.startswith(ds_ver[:3]): -- return ops[relation](LegacyVersion(ds_ver),LegacyVersion(cmp_ver)) -+ return ops[relation](DSVersion(ds_ver), DSVersion(cmp_ver)) - else: -- return ops[relation](LegacyVersion(ds_ver), LegacyVersion(ver[0])) -+ return ops[relation](DSVersion(ds_ver), DSVersion(ver[0])) - - - def ds_is_older(*ver, instance=None): --- -2.39.2 - diff --git a/389-ds-base.spec b/389-ds-base.spec index 60e467c..c467d9d 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -45,9 +45,9 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.3.2 -Release: 3%{?dist} -License: GPLv3+ and (ASL 2.0 or MIT) +Version: 2.4.0 +Release: 1%{?dist} +License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and MPLv2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and ASL 2.0 and (ASL 2.0 or Boost) and ((MIT or ASL 2.0) and Unicode-DFS-2016) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 Conflicts: freeipa-server < 4.0.3 @@ -65,39 +65,44 @@ Provides: bundled(crate(base64)) = 0.13.1 Provides: bundled(crate(bitflags)) = 1.3.2 Provides: bundled(crate(byteorder)) = 1.4.3 Provides: bundled(crate(cbindgen)) = 0.9.1 -Provides: bundled(crate(cc)) = 1.0.78 +Provides: bundled(crate(cc)) = 1.0.79 Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 2.34.0 Provides: bundled(crate(concread)) = 0.2.21 Provides: bundled(crate(crossbeam)) = 0.8.2 -Provides: bundled(crate(crossbeam-channel)) = 0.5.6 -Provides: bundled(crate(crossbeam-deque)) = 0.8.2 -Provides: bundled(crate(crossbeam-epoch)) = 0.9.13 +Provides: bundled(crate(crossbeam-channel)) = 0.5.8 +Provides: bundled(crate(crossbeam-deque)) = 0.8.3 +Provides: bundled(crate(crossbeam-epoch)) = 0.9.14 Provides: bundled(crate(crossbeam-queue)) = 0.3.8 -Provides: bundled(crate(crossbeam-utils)) = 0.8.14 +Provides: bundled(crate(crossbeam-utils)) = 0.8.15 Provides: bundled(crate(entryuuid)) = 0.1.0 Provides: bundled(crate(entryuuid_syntax)) = 0.1.0 -Provides: bundled(crate(fastrand)) = 1.8.0 +Provides: bundled(crate(errno)) = 0.3.1 +Provides: bundled(crate(errno-dragonfly)) = 0.1.2 +Provides: bundled(crate(fastrand)) = 1.9.0 Provides: bundled(crate(fernet)) = 0.1.4 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 -Provides: bundled(crate(getrandom)) = 0.2.8 +Provides: bundled(crate(getrandom)) = 0.2.9 Provides: bundled(crate(hashbrown)) = 0.12.3 Provides: bundled(crate(hermit-abi)) = 0.1.19 +Provides: bundled(crate(hermit-abi)) = 0.3.1 Provides: bundled(crate(instant)) = 0.1.12 -Provides: bundled(crate(itoa)) = 1.0.5 -Provides: bundled(crate(jobserver)) = 0.1.25 -Provides: bundled(crate(libc)) = 0.2.139 +Provides: bundled(crate(io-lifetimes)) = 1.0.10 +Provides: bundled(crate(itoa)) = 1.0.6 +Provides: bundled(crate(jobserver)) = 0.1.26 +Provides: bundled(crate(libc)) = 0.2.142 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 +Provides: bundled(crate(linux-raw-sys)) = 0.3.4 Provides: bundled(crate(lock_api)) = 0.4.9 Provides: bundled(crate(log)) = 0.4.17 Provides: bundled(crate(lru)) = 0.7.8 -Provides: bundled(crate(memoffset)) = 0.7.1 -Provides: bundled(crate(once_cell)) = 1.17.0 -Provides: bundled(crate(openssl)) = 0.10.45 -Provides: bundled(crate(openssl-macros)) = 0.1.0 -Provides: bundled(crate(openssl-sys)) = 0.9.80 +Provides: bundled(crate(memoffset)) = 0.8.0 +Provides: bundled(crate(once_cell)) = 1.17.1 +Provides: bundled(crate(openssl)) = 0.10.52 +Provides: bundled(crate(openssl-macros)) = 0.1.1 +Provides: bundled(crate(openssl-sys)) = 0.9.87 Provides: bundled(crate(parking_lot)) = 0.11.2 Provides: bundled(crate(parking_lot_core)) = 0.8.6 Provides: bundled(crate(paste)) = 0.1.18 @@ -106,33 +111,33 @@ Provides: bundled(crate(pin-project-lite)) = 0.2.9 Provides: bundled(crate(pkg-config)) = 0.3.26 Provides: bundled(crate(ppv-lite86)) = 0.2.17 Provides: bundled(crate(proc-macro-hack)) = 0.5.20+deprecated -Provides: bundled(crate(proc-macro2)) = 1.0.50 +Provides: bundled(crate(proc-macro2)) = 1.0.56 Provides: bundled(crate(pwdchan)) = 0.1.0 -Provides: bundled(crate(quote)) = 1.0.23 +Provides: bundled(crate(quote)) = 1.0.26 Provides: bundled(crate(rand)) = 0.8.5 Provides: bundled(crate(rand_chacha)) = 0.3.1 Provides: bundled(crate(rand_core)) = 0.6.4 Provides: bundled(crate(redox_syscall)) = 0.2.16 -Provides: bundled(crate(remove_dir_all)) = 0.5.3 -Provides: bundled(crate(ryu)) = 1.0.12 +Provides: bundled(crate(redox_syscall)) = 0.3.5 +Provides: bundled(crate(rustix)) = 0.37.14 +Provides: bundled(crate(ryu)) = 1.0.13 Provides: bundled(crate(scopeguard)) = 1.1.0 -Provides: bundled(crate(serde)) = 1.0.152 -Provides: bundled(crate(serde_derive)) = 1.0.152 -Provides: bundled(crate(serde_json)) = 1.0.91 +Provides: bundled(crate(serde)) = 1.0.160 +Provides: bundled(crate(serde_derive)) = 1.0.160 +Provides: bundled(crate(serde_json)) = 1.0.96 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 Provides: bundled(crate(smallvec)) = 1.10.0 Provides: bundled(crate(strsim)) = 0.8.0 -Provides: bundled(crate(syn)) = 1.0.107 -Provides: bundled(crate(synstructure)) = 0.12.6 -Provides: bundled(crate(tempfile)) = 3.3.0 +Provides: bundled(crate(syn)) = 1.0.109 +Provides: bundled(crate(syn)) = 2.0.15 +Provides: bundled(crate(tempfile)) = 3.5.0 Provides: bundled(crate(textwrap)) = 0.11.0 -Provides: bundled(crate(tokio)) = 1.24.2 -Provides: bundled(crate(tokio-macros)) = 1.8.2 +Provides: bundled(crate(tokio)) = 1.28.0 +Provides: bundled(crate(tokio-macros)) = 2.1.0 Provides: bundled(crate(toml)) = 0.5.11 -Provides: bundled(crate(unicode-ident)) = 1.0.6 +Provides: bundled(crate(unicode-ident)) = 1.0.8 Provides: bundled(crate(unicode-width)) = 0.1.10 -Provides: bundled(crate(unicode-xid)) = 0.2.4 Provides: bundled(crate(uuid)) = 0.8.2 Provides: bundled(crate(vcpkg)) = 0.2.15 Provides: bundled(crate(vec_map)) = 0.8.2 @@ -141,16 +146,26 @@ Provides: bundled(crate(wasi)) = 0.11.0+wasi_snapshot_preview1 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 -Provides: bundled(crate(windows-sys)) = 0.42.0 -Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.42.1 -Provides: bundled(crate(windows_aarch64_msvc)) = 0.42.1 -Provides: bundled(crate(windows_i686_gnu)) = 0.42.1 -Provides: bundled(crate(windows_i686_msvc)) = 0.42.1 -Provides: bundled(crate(windows_x86_64_gnu)) = 0.42.1 -Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.42.1 -Provides: bundled(crate(windows_x86_64_msvc)) = 0.42.1 -Provides: bundled(crate(zeroize)) = 1.5.7 -Provides: bundled(crate(zeroize_derive)) = 1.3.3 +Provides: bundled(crate(windows-sys)) = 0.45.0 +Provides: bundled(crate(windows-sys)) = 0.48.0 +Provides: bundled(crate(windows-targets)) = 0.42.2 +Provides: bundled(crate(windows-targets)) = 0.48.0 +Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.42.2 +Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.48.0 +Provides: bundled(crate(windows_aarch64_msvc)) = 0.42.2 +Provides: bundled(crate(windows_aarch64_msvc)) = 0.48.0 +Provides: bundled(crate(windows_i686_gnu)) = 0.42.2 +Provides: bundled(crate(windows_i686_gnu)) = 0.48.0 +Provides: bundled(crate(windows_i686_msvc)) = 0.42.2 +Provides: bundled(crate(windows_i686_msvc)) = 0.48.0 +Provides: bundled(crate(windows_x86_64_gnu)) = 0.42.2 +Provides: bundled(crate(windows_x86_64_gnu)) = 0.48.0 +Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.42.2 +Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.48.0 +Provides: bundled(crate(windows_x86_64_msvc)) = 0.42.2 +Provides: bundled(crate(windows_x86_64_msvc)) = 0.48.0 +Provides: bundled(crate(zeroize)) = 1.6.0 +Provides: bundled(crate(zeroize_derive)) = 1.4.2 ##### Bundled cargo crates list - END ##### BuildRequires: nspr-devel >= 4.32 @@ -214,6 +229,7 @@ BuildRequires: python%{python3_pkgversion}-argcomplete BuildRequires: python%{python3_pkgversion}-argparse-manpage BuildRequires: python%{python3_pkgversion}-libselinux BuildRequires: python%{python3_pkgversion}-policycoreutils +BuildRequires: python%{python3_pkgversion}-cryptography # For cockpit %if %{use_cockpit} @@ -277,7 +293,6 @@ Source2: %{name}-devel.README Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download/%{jemalloc_ver}/%{jemalloc_name}-%{jemalloc_ver}.tar.bz2 %endif Source4: 389-ds-base.sysusers -Patch0: 0001-Issue-5642-Build-fails-against-setuptools-67.0.0.patch %description 389 Directory Server is an LDAPv3 compliant server. The base package includes @@ -356,6 +371,7 @@ Requires: python%{python3_pkgversion}-dateutil Requires: python%{python3_pkgversion}-argcomplete Requires: python%{python3_pkgversion}-libselinux Requires: python%{python3_pkgversion}-setuptools +Requires: python%{python3_pkgversion}-cryptography %{?python_provide:%python_provide python%{python3_pkgversion}-lib389} %description -n python%{python3_pkgversion}-lib389 @@ -710,6 +726,67 @@ exit 0 %endif %changelog +* Tue Apr 25 2023 Mark Reynolds - 2.4.0-1 +- Bump version to 2.4.0 +- Issue 5156 - RFE that implement slapi_memberof (#5694) +- Issue 5734 - RFE - Exclude pwdFailureTime and ContextCSN (#5735) +- Issue 5726 - ns-slapd crashing in ldbm_back_upgradednformat (#5727) +- Issue 4758 - Add tests for WebUI +- Issue 5718 - Memory leak in connection table (#5719) +- Issue 5705 - Add config parameter to close client conns on failed bind (#5712) +- Issue 4758 - Add tests for WebUI +- Issue 5643 - Memory leak in entryrdn during delete (#5717) +- Issue 5714 - UI - fix typo, db settings, log settings, and LDAP editor paginations +- Issue 5701 - CLI - Fix referral mode setting (#5708) +- Bump openssl from 0.10.45 to 0.10.48 in /src (#5709) +- Issue 5710 - subtree search statistics for index lookup does not report ancestorid/entryrdn lookups (#5711) +- Issue 5697 - Obsolete nsslapd-ldapimaprootdn attribute (#5698) +- Issue 1081 - Stop schema replication from overwriting x-origin +- Issue 4812 - Listener thread does not scale with a high num of established connections (#5706) +- Issue 4812 - Listener thread does not scale with a high num of established connections (#5681) +- Bump webpack from 5.75.0 to 5.76.0 in /src/cockpit/389-console (#5699) +- Issue 5598 - (3rd) In 2.x, SRCH throughput drops by 10% because of handling of referral (#5692) +- Issue 5598 - (2nd) In 2.x, SRCH throughput drops by 10% because of handling of referral (#5691) +- Issue 5687 - UI - sensitive information disclosure +- Issue 5661 - LMDB hangs while Rebuilding the replication changelog RUV (#5676) +- Issue 5554 - Add more tests to security_basic_test suite +- Issue 4583 - Update specfile to skip checks of ASAN builds +- Issue 4758 - Add tests for WebUI +- Issue 3604 - UI - Add support for Subject Alternative Names in CSR +- Issue 5600 - buffer overflow when enabling sync repl plugin when dynamic plugins is enabled +- Issue 5640 - Update logconv for new logging format +- Issue 5162 - CI - fix error message for invalid pem file +- Issue 5598 - In 2.x, SRCH throughput drops by 10% because of handling of referral (#5604) +- Issue 5671 - covscan - clang warning (#5672) +- Issue 5267 - CI - Fix issues with nsslapd-return-original-entrydn +- Issue 5666 - CLI - Add timeout parameter for tasks +- Issue 5567 - CLI - make ldifgen use the same default ldif name for all options +- Issue 5647 - Fix unused variable warning from previous commit (#5670) +- Issue 5162 - Lib389 - verify certificate type before adding +- Issue 5642 - Build fails against setuptools 67.0.0 +- Issue 5630 - CLI - need to add logging filter for stdout +- Issue 5646 - CLI/UI - do not hardcode password storage schemes +- Issue 5640 - Update logconv for new logging format +- issue 5647 - covscan: memory leak in audit log when adding entries (#5650) +- Issue 5658 - CLI - unable to add attribute with matching rule +- Issue 5653 - covscan - fix invalid dereference +- Issue 5652 - Libasan crash in replication/cascading_test (#5659) +- Issue 5628 - Handle graceful timeout in CI tests (#5657) +- Issue 5648 - Covscan - Compiler warnings (#5651) +- Issue 5630 - CLI - error messages should goto stderr +- Issue 2435 - RFE - Raise IDL Scan Limit to INT_MAX (#5639) +- Issue 5632 - CLI - improve error handling with db2ldif +- Issue 5517 - Replication conflict CI test sometime fails (#5518) +- Issue 5634 - Deprecated warning related to github action workflow code (#5635) +- Issue 5637 - Covscan - fix Buffer Overflows (#5638) +- Issue 5624 - RFE - UI - export certificates, and import text base64 encoded certificates +- Bump tokio from 1.24.1 to 1.25.0 in /src (#5629) +- Issue 4577 - Add LMDB pytest github action (#5627) +- Issue 4293 - RFE - CLI - add dsrc options for setting user and group subtrees +- Remove stale libevent(-devel) dependency +- Issue 5578 - dscreate ds-root does not normaile paths (#5613) +- Issue 5497 - boolean attributes should be case insensitive + * Fri Mar 31 2023 Viktor Ashirov - 2.3.2-3 - Fix build issue against setuptools 67.0.0 (#2183375) diff --git a/sources b/sources index 4ae6d85..a719fd4 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 -SHA512 (389-ds-base-2.3.2.tar.bz2) = 20bf8e2ce1781886e62a9500cdf709d11b860f0f61de44ecb1be7c3a6be1fe306783b6eeb3e37933f494c640dd140e247a4a266091ffd81cf00f58af37e6577e +SHA512 (389-ds-base-2.4.0.tar.bz2) = 2bcfe9fcc41a48639d88109d530334b80ecfd6d7bf640c565bea843206b387a616d5a1a330b801439783467810a092e0027f7dff43755696e66eea9f6c06057c From 66643dd6cf9c404bfb1190a579338804fa87c1f0 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Thu, 18 May 2023 10:11:38 -0400 Subject: [PATCH 062/125] Bump version to 2.4.1 Issue 5770 - RFE - Extend Password Adminstrators to allow skipping password info updates Issue 5768 - CLI/UI - cert checks are too strict, and other issues Issue 5722 - fix compilation warnings (#5771) Issue 5765 - Improve installer selinux handling Issue 152 - RFE - Add support for LDAP alias entries Issue 5052 - BUG - Custom filters prevented entry deletion (#5060) Issue 5752 - RFE - Provide a history for LastLoginTime (#5753) Issue 5722 - RFE When a filter contains 'nsrole', improve response time by rewriting the filter (#5723) Issue 5704 - crash in sync_refresh_initial_content (#5720) Issue 5738 - RFE - UI - Read/write replication monitor info to .dsrc file Issue 5156 - build warnings (#5758) Issue 5749 - RFE - Allow Account Policy Plugin to handle inactivity and expiration at the same time Issue 5743 - Disabling replica crashes the server (#5746) Issue 2562 - Copy config files into backup directory Issue 5156 - fix build breakage from slapi-memberof commit Issue 4758 - Add tests for WebUI --- .gitignore | 1 + 389-ds-base.spec | 41 ++++++++++++++++++++++++++++++----------- sources | 2 +- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 6fac6d8..56929d8 100644 --- a/.gitignore +++ b/.gitignore @@ -220,3 +220,4 @@ /389-ds-base-2.3.1.tar.bz2 /389-ds-base-2.3.2.tar.bz2 /389-ds-base-2.4.0.tar.bz2 +/389-ds-base-2.4.1.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index c467d9d..e123212 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -45,7 +45,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.4.0 +Version: 2.4.1 Release: 1%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and MPLv2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and ASL 2.0 and (ASL 2.0 or Boost) and ((MIT or ASL 2.0) and Unicode-DFS-2016) URL: https://www.port389.org @@ -91,10 +91,10 @@ Provides: bundled(crate(instant)) = 0.1.12 Provides: bundled(crate(io-lifetimes)) = 1.0.10 Provides: bundled(crate(itoa)) = 1.0.6 Provides: bundled(crate(jobserver)) = 0.1.26 -Provides: bundled(crate(libc)) = 0.2.142 +Provides: bundled(crate(libc)) = 0.2.144 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 -Provides: bundled(crate(linux-raw-sys)) = 0.3.4 +Provides: bundled(crate(linux-raw-sys)) = 0.3.7 Provides: bundled(crate(lock_api)) = 0.4.9 Provides: bundled(crate(log)) = 0.4.17 Provides: bundled(crate(lru)) = 0.7.8 @@ -108,32 +108,32 @@ Provides: bundled(crate(parking_lot_core)) = 0.8.6 Provides: bundled(crate(paste)) = 0.1.18 Provides: bundled(crate(paste-impl)) = 0.1.18 Provides: bundled(crate(pin-project-lite)) = 0.2.9 -Provides: bundled(crate(pkg-config)) = 0.3.26 +Provides: bundled(crate(pkg-config)) = 0.3.27 Provides: bundled(crate(ppv-lite86)) = 0.2.17 Provides: bundled(crate(proc-macro-hack)) = 0.5.20+deprecated -Provides: bundled(crate(proc-macro2)) = 1.0.56 +Provides: bundled(crate(proc-macro2)) = 1.0.58 Provides: bundled(crate(pwdchan)) = 0.1.0 -Provides: bundled(crate(quote)) = 1.0.26 +Provides: bundled(crate(quote)) = 1.0.27 Provides: bundled(crate(rand)) = 0.8.5 Provides: bundled(crate(rand_chacha)) = 0.3.1 Provides: bundled(crate(rand_core)) = 0.6.4 Provides: bundled(crate(redox_syscall)) = 0.2.16 Provides: bundled(crate(redox_syscall)) = 0.3.5 -Provides: bundled(crate(rustix)) = 0.37.14 +Provides: bundled(crate(rustix)) = 0.37.19 Provides: bundled(crate(ryu)) = 1.0.13 Provides: bundled(crate(scopeguard)) = 1.1.0 -Provides: bundled(crate(serde)) = 1.0.160 -Provides: bundled(crate(serde_derive)) = 1.0.160 +Provides: bundled(crate(serde)) = 1.0.163 +Provides: bundled(crate(serde_derive)) = 1.0.163 Provides: bundled(crate(serde_json)) = 1.0.96 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 Provides: bundled(crate(smallvec)) = 1.10.0 Provides: bundled(crate(strsim)) = 0.8.0 Provides: bundled(crate(syn)) = 1.0.109 -Provides: bundled(crate(syn)) = 2.0.15 +Provides: bundled(crate(syn)) = 2.0.16 Provides: bundled(crate(tempfile)) = 3.5.0 Provides: bundled(crate(textwrap)) = 0.11.0 -Provides: bundled(crate(tokio)) = 1.28.0 +Provides: bundled(crate(tokio)) = 1.28.1 Provides: bundled(crate(tokio-macros)) = 2.1.0 Provides: bundled(crate(toml)) = 0.5.11 Provides: bundled(crate(unicode-ident)) = 1.0.8 @@ -726,6 +726,25 @@ exit 0 %endif %changelog +* Thu May 18 2023 Mark Reynolds - 2.4.1-1 +- Bump version to 2.4.1 +- Issue 5770 - RFE - Extend Password Adminstrators to allow skipping password info updates +- Issue 5768 - CLI/UI - cert checks are too strict, and other issues +- Issue 5722 - fix compilation warnings (#5771) +- Issue 5765 - Improve installer selinux handling +- Issue 152 - RFE - Add support for LDAP alias entries +- Issue 5052 - BUG - Custom filters prevented entry deletion (#5060) +- Issue 5752 - RFE - Provide a history for LastLoginTime (#5753) +- Issue 5722 - RFE When a filter contains 'nsrole', improve response time by rewriting the filter (#5723) +- Issue 5704 - crash in sync_refresh_initial_content (#5720) +- Issue 5738 - RFE - UI - Read/write replication monitor info to .dsrc file +- Issue 5156 - build warnings (#5758) +- Issue 5749 - RFE - Allow Account Policy Plugin to handle inactivity and expiration at the same time +- Issue 5743 - Disabling replica crashes the server (#5746) +- Issue 2562 - Copy config files into backup directory +- Issue 5156 - fix build breakage from slapi-memberof commit +- Issue 4758 - Add tests for WebUI + * Tue Apr 25 2023 Mark Reynolds - 2.4.0-1 - Bump version to 2.4.0 - Issue 5156 - RFE that implement slapi_memberof (#5694) diff --git a/sources b/sources index a719fd4..e751cd0 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 -SHA512 (389-ds-base-2.4.0.tar.bz2) = 2bcfe9fcc41a48639d88109d530334b80ecfd6d7bf640c565bea843206b387a616d5a1a330b801439783467810a092e0027f7dff43755696e66eea9f6c06057c +SHA512 (389-ds-base-2.4.1.tar.bz2) = c9168b10c5c5e58e2bd2ff6744c88757f0fbb0c1bd3f82ecbe59cdd927c790682cb5f264dd27ab7be719fe3a2a09a16a31e29b024356443ec1b2797eb93557fc From 47834ef75ac7bc7ad45f79e77c32c9b5160c5591 Mon Sep 17 00:00:00 2001 From: Python Maint Date: Wed, 28 Jun 2023 19:02:29 +0200 Subject: [PATCH 063/125] Rebuilt for Python 3.12 --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index e123212..c6a16a2 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.4.1 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and MPLv2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and ASL 2.0 and (ASL 2.0 or Boost) and ((MIT or ASL 2.0) and Unicode-DFS-2016) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -726,6 +726,9 @@ exit 0 %endif %changelog +* Wed Jun 28 2023 Python Maint - 2.4.1-2 +- Rebuilt for Python 3.12 + * Thu May 18 2023 Mark Reynolds - 2.4.1-1 - Bump version to 2.4.1 - Issue 5770 - RFE - Extend Password Adminstrators to allow skipping password info updates From 41a274793a2d5eb749f30b523d69f75c2ecbd4d9 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Fri, 7 Jul 2023 15:27:26 -0400 Subject: [PATCH 064/125] Bump version to 2.4.2 Issue 5793 - UI - fix suffix selection in export modal Issue 5793 - UI - Fix minor crashes (#5827) Issue 5825 - healthcheck - password storage scheme warning needs more info Issue 5822 - Allow empty export path for db2ldif Issue 5755 - Massive memory leaking on update operations (#5824) Issue 5701 - CI - Add more tests for referral mode fix (#5810) Issue 5551 - Almost empty and not loaded ns-slapd high cpu load Issue 5755 - The Massive memory leaking on update operations (#5803) Issue 2375 - CLI - Healthcheck - revise and add new checks Bump openssl from 0.10.52 to 0.10.55 in /src Issue 5793 - UI - movce from webpack to esbuild bundler Issue 5752 - CI - Add more tests for lastLoginHistorySize RFE (#5802) Issue 3527 - Fix HAProxy x390x compatibility and compiler warnings (#5801) Issue 5798 - CLI - Add multi-valued support to dsconf config (#5799) Issue 5781 - Bug handling return code of pre-extended operation plugin. Issue 5785 - move bash completion to post section of specfile Issue 5156 - (cont) RFE slapi_memberof reusing memberof values (#5744) Issue 4758 - Add tests for WebUI Issue 3527 - Add PROXY protocol support (#5762) Issue 5789 - Improve ds-replcheck error handling Issue 5786 - CLI - registers tools for bash completion Issue 5786 - Set minimal permissions on GitHub Workflows (#5787) Issue 5646 - Various memory leaks (#5725) Issue 5778 - UI - Remove error message if .dsrc is missing Issue 5751 - Cleanallruv task crashes on consumer (#5775) --- .gitignore | 1 + 389-ds-base.spec | 114 ++++++++++++++++++++++++++++++----------------- sources | 2 +- 3 files changed, 76 insertions(+), 41 deletions(-) diff --git a/.gitignore b/.gitignore index 56929d8..455f450 100644 --- a/.gitignore +++ b/.gitignore @@ -221,3 +221,4 @@ /389-ds-base-2.3.2.tar.bz2 /389-ds-base-2.4.0.tar.bz2 /389-ds-base-2.4.1.tar.bz2 +/389-ds-base-2.4.2.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index c6a16a2..fc54ecf 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -45,9 +45,9 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.4.1 -Release: 2%{?dist} -License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and MPLv2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and ASL 2.0 and (ASL 2.0 or Boost) and ((MIT or ASL 2.0) and Unicode-DFS-2016) +Version: 2.4.2 +Release: 1%{?dist} +License: GPLv3+ and (ASL 2.0 or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 Conflicts: freeipa-server < 4.0.3 @@ -57,10 +57,13 @@ Obsoletes: %{name}-legacy-tools-debuginfo < 1.4.4.6 Provides: ldif2ldbm >= 0 ##### Bundled cargo crates list - START ##### +Provides: bundled(crate(addr2line)) = 0.20.0 +Provides: bundled(crate(adler)) = 1.0.2 Provides: bundled(crate(ahash)) = 0.7.6 Provides: bundled(crate(ansi_term)) = 0.12.1 Provides: bundled(crate(atty)) = 0.2.14 Provides: bundled(crate(autocfg)) = 1.1.0 +Provides: bundled(crate(backtrace)) = 0.3.68 Provides: bundled(crate(base64)) = 0.13.1 Provides: bundled(crate(bitflags)) = 1.3.2 Provides: bundled(crate(byteorder)) = 1.4.3 @@ -72,9 +75,9 @@ Provides: bundled(crate(concread)) = 0.2.21 Provides: bundled(crate(crossbeam)) = 0.8.2 Provides: bundled(crate(crossbeam-channel)) = 0.5.8 Provides: bundled(crate(crossbeam-deque)) = 0.8.3 -Provides: bundled(crate(crossbeam-epoch)) = 0.9.14 +Provides: bundled(crate(crossbeam-epoch)) = 0.9.15 Provides: bundled(crate(crossbeam-queue)) = 0.3.8 -Provides: bundled(crate(crossbeam-utils)) = 0.8.15 +Provides: bundled(crate(crossbeam-utils)) = 0.8.16 Provides: bundled(crate(entryuuid)) = 0.1.0 Provides: bundled(crate(entryuuid_syntax)) = 0.1.0 Provides: bundled(crate(errno)) = 0.3.1 @@ -83,60 +86,65 @@ Provides: bundled(crate(fastrand)) = 1.9.0 Provides: bundled(crate(fernet)) = 0.1.4 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 -Provides: bundled(crate(getrandom)) = 0.2.9 +Provides: bundled(crate(getrandom)) = 0.2.10 +Provides: bundled(crate(gimli)) = 0.27.3 Provides: bundled(crate(hashbrown)) = 0.12.3 Provides: bundled(crate(hermit-abi)) = 0.1.19 -Provides: bundled(crate(hermit-abi)) = 0.3.1 +Provides: bundled(crate(hermit-abi)) = 0.3.2 Provides: bundled(crate(instant)) = 0.1.12 -Provides: bundled(crate(io-lifetimes)) = 1.0.10 -Provides: bundled(crate(itoa)) = 1.0.6 +Provides: bundled(crate(io-lifetimes)) = 1.0.11 +Provides: bundled(crate(itoa)) = 1.0.8 Provides: bundled(crate(jobserver)) = 0.1.26 -Provides: bundled(crate(libc)) = 0.2.144 +Provides: bundled(crate(libc)) = 0.2.147 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 -Provides: bundled(crate(linux-raw-sys)) = 0.3.7 -Provides: bundled(crate(lock_api)) = 0.4.9 -Provides: bundled(crate(log)) = 0.4.17 +Provides: bundled(crate(linux-raw-sys)) = 0.3.8 +Provides: bundled(crate(lock_api)) = 0.4.10 +Provides: bundled(crate(log)) = 0.4.19 Provides: bundled(crate(lru)) = 0.7.8 -Provides: bundled(crate(memoffset)) = 0.8.0 -Provides: bundled(crate(once_cell)) = 1.17.1 -Provides: bundled(crate(openssl)) = 0.10.52 +Provides: bundled(crate(memchr)) = 2.5.0 +Provides: bundled(crate(memoffset)) = 0.9.0 +Provides: bundled(crate(miniz_oxide)) = 0.7.1 +Provides: bundled(crate(object)) = 0.31.1 +Provides: bundled(crate(once_cell)) = 1.18.0 +Provides: bundled(crate(openssl)) = 0.10.55 Provides: bundled(crate(openssl-macros)) = 0.1.1 -Provides: bundled(crate(openssl-sys)) = 0.9.87 +Provides: bundled(crate(openssl-sys)) = 0.9.90 Provides: bundled(crate(parking_lot)) = 0.11.2 Provides: bundled(crate(parking_lot_core)) = 0.8.6 Provides: bundled(crate(paste)) = 0.1.18 Provides: bundled(crate(paste-impl)) = 0.1.18 -Provides: bundled(crate(pin-project-lite)) = 0.2.9 +Provides: bundled(crate(pin-project-lite)) = 0.2.10 Provides: bundled(crate(pkg-config)) = 0.3.27 Provides: bundled(crate(ppv-lite86)) = 0.2.17 Provides: bundled(crate(proc-macro-hack)) = 0.5.20+deprecated -Provides: bundled(crate(proc-macro2)) = 1.0.58 +Provides: bundled(crate(proc-macro2)) = 1.0.63 Provides: bundled(crate(pwdchan)) = 0.1.0 -Provides: bundled(crate(quote)) = 1.0.27 +Provides: bundled(crate(quote)) = 1.0.29 Provides: bundled(crate(rand)) = 0.8.5 Provides: bundled(crate(rand_chacha)) = 0.3.1 Provides: bundled(crate(rand_core)) = 0.6.4 Provides: bundled(crate(redox_syscall)) = 0.2.16 Provides: bundled(crate(redox_syscall)) = 0.3.5 -Provides: bundled(crate(rustix)) = 0.37.19 -Provides: bundled(crate(ryu)) = 1.0.13 +Provides: bundled(crate(rustc-demangle)) = 0.1.23 +Provides: bundled(crate(rustix)) = 0.37.23 +Provides: bundled(crate(ryu)) = 1.0.14 Provides: bundled(crate(scopeguard)) = 1.1.0 -Provides: bundled(crate(serde)) = 1.0.163 -Provides: bundled(crate(serde_derive)) = 1.0.163 -Provides: bundled(crate(serde_json)) = 1.0.96 +Provides: bundled(crate(serde)) = 1.0.167 +Provides: bundled(crate(serde_derive)) = 1.0.167 +Provides: bundled(crate(serde_json)) = 1.0.100 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 -Provides: bundled(crate(smallvec)) = 1.10.0 +Provides: bundled(crate(smallvec)) = 1.11.0 Provides: bundled(crate(strsim)) = 0.8.0 Provides: bundled(crate(syn)) = 1.0.109 -Provides: bundled(crate(syn)) = 2.0.16 -Provides: bundled(crate(tempfile)) = 3.5.0 +Provides: bundled(crate(syn)) = 2.0.23 +Provides: bundled(crate(tempfile)) = 3.6.0 Provides: bundled(crate(textwrap)) = 0.11.0 -Provides: bundled(crate(tokio)) = 1.28.1 +Provides: bundled(crate(tokio)) = 1.29.1 Provides: bundled(crate(tokio-macros)) = 2.1.0 Provides: bundled(crate(toml)) = 0.5.11 -Provides: bundled(crate(unicode-ident)) = 1.0.8 +Provides: bundled(crate(unicode-ident)) = 1.0.10 Provides: bundled(crate(unicode-width)) = 0.1.10 Provides: bundled(crate(uuid)) = 0.8.2 Provides: bundled(crate(vcpkg)) = 0.2.15 @@ -146,23 +154,14 @@ Provides: bundled(crate(wasi)) = 0.11.0+wasi_snapshot_preview1 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 -Provides: bundled(crate(windows-sys)) = 0.45.0 Provides: bundled(crate(windows-sys)) = 0.48.0 -Provides: bundled(crate(windows-targets)) = 0.42.2 -Provides: bundled(crate(windows-targets)) = 0.48.0 -Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.42.2 +Provides: bundled(crate(windows-targets)) = 0.48.1 Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.48.0 -Provides: bundled(crate(windows_aarch64_msvc)) = 0.42.2 Provides: bundled(crate(windows_aarch64_msvc)) = 0.48.0 -Provides: bundled(crate(windows_i686_gnu)) = 0.42.2 Provides: bundled(crate(windows_i686_gnu)) = 0.48.0 -Provides: bundled(crate(windows_i686_msvc)) = 0.42.2 Provides: bundled(crate(windows_i686_msvc)) = 0.48.0 -Provides: bundled(crate(windows_x86_64_gnu)) = 0.42.2 Provides: bundled(crate(windows_x86_64_gnu)) = 0.48.0 -Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.42.2 Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.48.0 -Provides: bundled(crate(windows_x86_64_msvc)) = 0.42.2 Provides: bundled(crate(windows_x86_64_msvc)) = 0.48.0 Provides: bundled(crate(zeroize)) = 1.6.0 Provides: bundled(crate(zeroize_derive)) = 1.4.2 @@ -542,6 +541,13 @@ else output=/dev/null output2=/dev/null fi + +# Register CLI tools for bash completion +for clitool in dsconf dsctl dsidm dscreate ds-replcheck +do + register-python-argcomplete "${clitool}" > "/usr/share/bash-completion/completions/${clitool}" +done + # reload to pick up any changes to systemd files /bin/systemctl daemon-reload >$output 2>&1 || : @@ -726,6 +732,34 @@ exit 0 %endif %changelog +* Fri Jul 7 2023 Mark Reynolds - 2.4.2-1 +- Bump version to 2.4.2 +- Issue 5793 - UI - fix suffix selection in export modal +- Issue 5793 - UI - Fix minor crashes (#5827) +- Issue 5825 - healthcheck - password storage scheme warning needs more info +- Issue 5822 - Allow empty export path for db2ldif +- Issue 5755 - Massive memory leaking on update operations (#5824) +- Issue 5701 - CI - Add more tests for referral mode fix (#5810) +- Issue 5551 - Almost empty and not loaded ns-slapd high cpu load +- Issue 5755 - The Massive memory leaking on update operations (#5803) +- Issue 2375 - CLI - Healthcheck - revise and add new checks +- Bump openssl from 0.10.52 to 0.10.55 in /src +- Issue 5793 - UI - movce from webpack to esbuild bundler +- Issue 5752 - CI - Add more tests for lastLoginHistorySize RFE (#5802) +- Issue 3527 - Fix HAProxy x390x compatibility and compiler warnings (#5801) +- Issue 5798 - CLI - Add multi-valued support to dsconf config (#5799) +- Issue 5781 - Bug handling return code of pre-extended operation plugin. +- Issue 5785 - move bash completion to post section of specfile +- Issue 5156 - (cont) RFE slapi_memberof reusing memberof values (#5744) +- Issue 4758 - Add tests for WebUI +- Issue 3527 - Add PROXY protocol support (#5762) +- Issue 5789 - Improve ds-replcheck error handling +- Issue 5786 - CLI - registers tools for bash completion +- Issue 5786 - Set minimal permissions on GitHub Workflows (#5787) +- Issue 5646 - Various memory leaks (#5725) +- Issue 5778 - UI - Remove error message if .dsrc is missing +- Issue 5751 - Cleanallruv task crashes on consumer (#5775) + * Wed Jun 28 2023 Python Maint - 2.4.1-2 - Rebuilt for Python 3.12 diff --git a/sources b/sources index e751cd0..f3f28b3 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ +SHA512 (389-ds-base-2.4.2.tar.bz2) = 04c6149fd908db8df4e69c29aea5fbe0011e2c749ab5571132a607cf2cf76abb01abcc5a6f6f9f2de90effd740935942aca29a1b82631baa68d5d3d8fddcb2fc SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 -SHA512 (389-ds-base-2.4.1.tar.bz2) = c9168b10c5c5e58e2bd2ff6744c88757f0fbb0c1bd3f82ecbe59cdd927c790682cb5f264dd27ab7be719fe3a2a09a16a31e29b024356443ec1b2797eb93557fc From c7d3a6be63a73e71b0413158cb6d0aa009f1f404 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Mon, 10 Jul 2023 13:31:58 -0400 Subject: [PATCH 065/125] Bump version to 2.4.2-2 Issue 5752 - RFE - Provide a history for LastLoginTime (#5807) = Issue 4719 CI - Add dsconf add a PTA URL test --- 389-ds-base.spec | 7 ++++++- sources | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index fc54ecf..9dea6aa 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.4.2 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -732,6 +732,11 @@ exit 0 %endif %changelog +* Mon Jul 10 2023 Mark Reynolds - 2.4.2-2 +- Bump version to 2.4.2-2 +- Issue 5752 - RFE - Provide a history for LastLoginTime (#5807) += Issue 4719 - CI - Add dsconf add a PTA URL test + * Fri Jul 7 2023 Mark Reynolds - 2.4.2-1 - Bump version to 2.4.2 - Issue 5793 - UI - fix suffix selection in export modal diff --git a/sources b/sources index f3f28b3..3213dba 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (389-ds-base-2.4.2.tar.bz2) = 04c6149fd908db8df4e69c29aea5fbe0011e2c749ab5571132a607cf2cf76abb01abcc5a6f6f9f2de90effd740935942aca29a1b82631baa68d5d3d8fddcb2fc +SHA512 (389-ds-base-2.4.2.tar.bz2) = ffaab71739b8a08f377b00e30d3b10f430ead8ab5c04e0a7e6d1fa4364764e083474d0eb8277fd02c367d533623d41b7d3c5e5ecab5fd3471d8f49709e2ae264 SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 From a0aa3a1e6a4734ac7f6e524a8850862f75da0761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Zatloukal?= Date: Tue, 11 Jul 2023 22:12:36 +0200 Subject: [PATCH 066/125] Rebuilt for ICU 73.2 --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 9dea6aa..f8ff879 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.4.2 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -732,6 +732,9 @@ exit 0 %endif %changelog +* Tue Jul 11 2023 František Zatloukal - 2.4.2-3 +- Rebuilt for ICU 73.2 + * Mon Jul 10 2023 Mark Reynolds - 2.4.2-2 - Bump version to 2.4.2-2 - Issue 5752 - RFE - Provide a history for LastLoginTime (#5807) From 59f217afda918d7b9373260806022a7ed5d7970a Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 19 Jul 2023 10:53:12 +0000 Subject: [PATCH 067/125] Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index f8ff879..5d916a5 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.4.2 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -732,6 +732,9 @@ exit 0 %endif %changelog +* Wed Jul 19 2023 Fedora Release Engineering - 2.4.2-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + * Tue Jul 11 2023 František Zatloukal - 2.4.2-3 - Rebuilt for ICU 73.2 From 70852658a46b6a6a27168dec2e9ce409209b3a5e Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Mon, 24 Jul 2023 15:32:49 -0400 Subject: [PATCH 068/125] Bump version to 2.4.2-5 Add the bash completion scripts to the appropriate files section --- 389-ds-base.spec | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 5d916a5..7d75085 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.4.2 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -646,6 +646,7 @@ exit 0 %{_mandir}/man1/logconv.pl.1.gz %{_bindir}/pwdhash %{_mandir}/man1/pwdhash.1.gz +/usr/share/bash-completion/completions/ds-replcheck #%caps(CAP_NET_BIND_SERVICE=pe) {_sbindir}/ns-slapd %{_sbindir}/ns-slapd %{_mandir}/man8/ns-slapd.8.gz @@ -724,6 +725,10 @@ exit 0 %{_sbindir}/dsidm %{_mandir}/man8/dsidm.8.gz %{_libexecdir}/%{pkgname}/dscontainer +/usr/share/bash-completion/completions/dsctl +/usr/share/bash-completion/completions/dsconf +/usr/share/bash-completion/completions/dscreate +/usr/share/bash-completion/completions/dsdim %if %{use_cockpit} %files -n cockpit-389-ds -f cockpit.list @@ -732,6 +737,10 @@ exit 0 %endif %changelog +* Mon Jul 24 2023 Mark Reynolds - 2.4.2-5 +- Bump version to 2.4.2-5 +- Add the bash completion scripts to the appropriate files section + * Wed Jul 19 2023 Fedora Release Engineering - 2.4.2-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild From 66c7a2c53f94588e8f4bca36930855be1ce36ce0 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Thu, 3 Aug 2023 14:57:06 -0400 Subject: [PATCH 069/125] Bump version to 2.4.3-1 Issue 5729 - Memory leak in factory_create_extension (#5814) Issue 5870 - ns-slapd crashes at startup if a backend has no suffix (#5871) Issue 5876 - CI Test random failure - Import (#5879) Issue 5877 - test_basic_ldapagent breaks test_setup_ds_as_non_root* tests Issue 5867 - lib389 should use filter for tarfile as recommended by PEP 706 (#5868) Issue 5853 - Update Cargo.lock and fix minor warning (#5854) Issue 5785 - CLI - arg completion is broken Issue 5864 - Server fails to start after reboot because it's unable to access nsslapd-rundir Issue 5856 - SyntaxWarning: invalid escape sequence '\,' Issue 5859 - dbscan fails with AttributeError: 'list' object has no attribute 'extends' Issue 3527 - UI - Add nsslapd-haproxy-trusted-ip to server setting (#5839) Issue 4551 - Paged search impacts performance (#5838) Issue 4758 - Add tests for WebUI Issue 4169 - UI - Fix retrochangelog and schema Typeaheads (#5837) issue 5833 - dsconf monitor backend fails on lmdb (#5835) Issue 3555 - UI - Fix audit issue with npm - stylelint (#5836) --- 389-ds-base.spec | 92 ++++++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 38 deletions(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 7d75085..1353123 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -45,9 +45,9 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.4.2 -Release: 5%{?dist} -License: GPLv3+ and (ASL 2.0 or MIT) +Version: 2.4.3 +Release: 1%{?dist} +License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (0BSD or MIT or ASL 2.0) and (Unlicense or MIT) and MPLv2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and (MIT or zlib or ASL 2.0) and ASL 2.0 and (ASL 2.0 or Boost) and ((MIT or ASL 2.0) and Unicode-DFS-2016) URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 Conflicts: freeipa-server < 4.0.3 @@ -66,9 +66,10 @@ Provides: bundled(crate(autocfg)) = 1.1.0 Provides: bundled(crate(backtrace)) = 0.3.68 Provides: bundled(crate(base64)) = 0.13.1 Provides: bundled(crate(bitflags)) = 1.3.2 +Provides: bundled(crate(bitflags)) = 2.3.3 Provides: bundled(crate(byteorder)) = 1.4.3 Provides: bundled(crate(cbindgen)) = 0.9.1 -Provides: bundled(crate(cc)) = 1.0.79 +Provides: bundled(crate(cc)) = 1.0.81 Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 2.34.0 Provides: bundled(crate(concread)) = 0.2.21 @@ -80,9 +81,9 @@ Provides: bundled(crate(crossbeam-queue)) = 0.3.8 Provides: bundled(crate(crossbeam-utils)) = 0.8.16 Provides: bundled(crate(entryuuid)) = 0.1.0 Provides: bundled(crate(entryuuid_syntax)) = 0.1.0 -Provides: bundled(crate(errno)) = 0.3.1 +Provides: bundled(crate(errno)) = 0.3.2 Provides: bundled(crate(errno-dragonfly)) = 0.1.2 -Provides: bundled(crate(fastrand)) = 1.9.0 +Provides: bundled(crate(fastrand)) = 2.0.0 Provides: bundled(crate(fernet)) = 0.1.4 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 @@ -90,15 +91,13 @@ Provides: bundled(crate(getrandom)) = 0.2.10 Provides: bundled(crate(gimli)) = 0.27.3 Provides: bundled(crate(hashbrown)) = 0.12.3 Provides: bundled(crate(hermit-abi)) = 0.1.19 -Provides: bundled(crate(hermit-abi)) = 0.3.2 Provides: bundled(crate(instant)) = 0.1.12 -Provides: bundled(crate(io-lifetimes)) = 1.0.11 -Provides: bundled(crate(itoa)) = 1.0.8 +Provides: bundled(crate(itoa)) = 1.0.9 Provides: bundled(crate(jobserver)) = 0.1.26 Provides: bundled(crate(libc)) = 0.2.147 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 -Provides: bundled(crate(linux-raw-sys)) = 0.3.8 +Provides: bundled(crate(linux-raw-sys)) = 0.4.5 Provides: bundled(crate(lock_api)) = 0.4.10 Provides: bundled(crate(log)) = 0.4.19 Provides: bundled(crate(lru)) = 0.7.8 @@ -118,33 +117,33 @@ Provides: bundled(crate(pin-project-lite)) = 0.2.10 Provides: bundled(crate(pkg-config)) = 0.3.27 Provides: bundled(crate(ppv-lite86)) = 0.2.17 Provides: bundled(crate(proc-macro-hack)) = 0.5.20+deprecated -Provides: bundled(crate(proc-macro2)) = 1.0.63 +Provides: bundled(crate(proc-macro2)) = 1.0.66 Provides: bundled(crate(pwdchan)) = 0.1.0 -Provides: bundled(crate(quote)) = 1.0.29 +Provides: bundled(crate(quote)) = 1.0.32 Provides: bundled(crate(rand)) = 0.8.5 Provides: bundled(crate(rand_chacha)) = 0.3.1 Provides: bundled(crate(rand_core)) = 0.6.4 Provides: bundled(crate(redox_syscall)) = 0.2.16 Provides: bundled(crate(redox_syscall)) = 0.3.5 Provides: bundled(crate(rustc-demangle)) = 0.1.23 -Provides: bundled(crate(rustix)) = 0.37.23 -Provides: bundled(crate(ryu)) = 1.0.14 -Provides: bundled(crate(scopeguard)) = 1.1.0 -Provides: bundled(crate(serde)) = 1.0.167 -Provides: bundled(crate(serde_derive)) = 1.0.167 -Provides: bundled(crate(serde_json)) = 1.0.100 +Provides: bundled(crate(rustix)) = 0.38.6 +Provides: bundled(crate(ryu)) = 1.0.15 +Provides: bundled(crate(scopeguard)) = 1.2.0 +Provides: bundled(crate(serde)) = 1.0.180 +Provides: bundled(crate(serde_derive)) = 1.0.180 +Provides: bundled(crate(serde_json)) = 1.0.104 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 Provides: bundled(crate(smallvec)) = 1.11.0 Provides: bundled(crate(strsim)) = 0.8.0 Provides: bundled(crate(syn)) = 1.0.109 -Provides: bundled(crate(syn)) = 2.0.23 -Provides: bundled(crate(tempfile)) = 3.6.0 +Provides: bundled(crate(syn)) = 2.0.28 +Provides: bundled(crate(tempfile)) = 3.7.0 Provides: bundled(crate(textwrap)) = 0.11.0 Provides: bundled(crate(tokio)) = 1.29.1 Provides: bundled(crate(tokio-macros)) = 2.1.0 Provides: bundled(crate(toml)) = 0.5.11 -Provides: bundled(crate(unicode-ident)) = 1.0.10 +Provides: bundled(crate(unicode-ident)) = 1.0.11 Provides: bundled(crate(unicode-width)) = 0.1.10 Provides: bundled(crate(uuid)) = 0.8.2 Provides: bundled(crate(vcpkg)) = 0.2.15 @@ -403,14 +402,12 @@ cp %{SOURCE2} README.devel OPENLDAP_FLAG="--with-openldap" %{?with_tmpfiles_d: TMPFILES_FLAG="--with-tmpfiles-d=%{with_tmpfiles_d}"} -# hack hack hack https://bugzilla.redhat.com/show_bug.cgi?id=833529 -NSSARGS="--with-nss-lib=%{_libdir} --with-nss-inc=%{_includedir}/nss3" %if %{use_asan} ASAN_FLAGS="--enable-asan --enable-debug" %endif -RUST_FLAGS="--enable-rust --enable-rust-offline" +RUST_FLAGS="--enable-rust-offline" %if !%{use_cockpit} COCKPIT_FLAGS="--disable-cockpit" @@ -462,10 +459,9 @@ autoreconf -fiv --with-systemdsystemconfdir=%{_sysconfdir}/systemd/system \ --with-systemdgroupname=%{groupname} \ --libexecdir=%{_libexecdir}/%{pkgname} \ - $NSSARGS $ASAN_FLAGS $RUST_FLAGS $CLANG_FLAGS $COCKPIT_FLAGS \ + $ASAN_FLAGS $RUST_FLAGS $CLANG_FLAGS $COCKPIT_FLAGS \ --enable-cmocka \ - --with-libldap-r=no \ - --enable-perl + --with-libldap-r=no # lib389 pushd ./src/lib389 @@ -505,6 +501,13 @@ pushd src/lib389 %py3_install popd +# Register CLI tools for bash completion +for clitool in dsconf dsctl dsidm dscreate ds-replcheck +do + register-python-argcomplete "${clitool}" > "${clitool}" + install -p -m 0644 -D -t '%{buildroot}%{bash_completions_dir}' "${clitool}" +done + mkdir -p $RPM_BUILD_ROOT/var/log/%{pkgname} mkdir -p $RPM_BUILD_ROOT/var/lib/%{pkgname} mkdir -p $RPM_BUILD_ROOT/var/lock/%{pkgname} @@ -542,12 +545,6 @@ else output2=/dev/null fi -# Register CLI tools for bash completion -for clitool in dsconf dsctl dsidm dscreate ds-replcheck -do - register-python-argcomplete "${clitool}" > "/usr/share/bash-completion/completions/${clitool}" -done - # reload to pick up any changes to systemd files /bin/systemctl daemon-reload >$output 2>&1 || : @@ -638,6 +635,7 @@ exit 0 %{_mandir}/man1/dbscan.1.gz %{_bindir}/ds-replcheck %{_mandir}/man1/ds-replcheck.1.gz +%{bash_completions_dir}/ds-replcheck %{_bindir}/ds-logpipe.py %{_mandir}/man1/ds-logpipe.py.1.gz %{_bindir}/ldclt @@ -646,7 +644,6 @@ exit 0 %{_mandir}/man1/logconv.pl.1.gz %{_bindir}/pwdhash %{_mandir}/man1/pwdhash.1.gz -/usr/share/bash-completion/completions/ds-replcheck #%caps(CAP_NET_BIND_SERVICE=pe) {_sbindir}/ns-slapd %{_sbindir}/ns-slapd %{_mandir}/man8/ns-slapd.8.gz @@ -725,10 +722,10 @@ exit 0 %{_sbindir}/dsidm %{_mandir}/man8/dsidm.8.gz %{_libexecdir}/%{pkgname}/dscontainer -/usr/share/bash-completion/completions/dsctl -/usr/share/bash-completion/completions/dsconf -/usr/share/bash-completion/completions/dscreate -/usr/share/bash-completion/completions/dsdim +%{bash_completions_dir}/dsctl +%{bash_completions_dir}/dsconf +%{bash_completions_dir}/dscreate +%{bash_completions_dir}/dsidm %if %{use_cockpit} %files -n cockpit-389-ds -f cockpit.list @@ -737,6 +734,25 @@ exit 0 %endif %changelog +* Thu Aug 3 2023 Mark Reynolds - 2.4.3-1 +- Bump version to 2.4.3-1 +- Issue 5729 - Memory leak in factory_create_extension (#5814) +- Issue 5870 - ns-slapd crashes at startup if a backend has no suffix (#5871) +- Issue 5876 - CI Test random failure - Import (#5879) +- Issue 5877 - test_basic_ldapagent breaks test_setup_ds_as_non_root* tests +- Issue 5867 - lib389 should use filter for tarfile as recommended by PEP 706 (#5868) +- Issue 5853 - Update Cargo.lock and fix minor warning (#5854) +- Issue 5785 - CLI - arg completion is broken +- Issue 5864 - Server fails to start after reboot because it's unable to access nsslapd-rundir +- Issue 5856 - SyntaxWarning: invalid escape sequence '\,' +- Issue 5859 - dbscan fails with AttributeError: 'list' object has no attribute 'extends' +- Issue 3527 - UI - Add nsslapd-haproxy-trusted-ip to server setting (#5839) +- Issue 4551 - Paged search impacts performance (#5838) +- Issue 4758 - Add tests for WebUI +- Issue 4169 - UI - Fix retrochangelog and schema Typeaheads (#5837) +- issue 5833 - dsconf monitor backend fails on lmdb (#5835) +- Issue 3555 - UI - Fix audit issue with npm - stylelint (#5836) + * Mon Jul 24 2023 Mark Reynolds - 2.4.2-5 - Bump version to 2.4.2-5 - Add the bash completion scripts to the appropriate files section From 298baaf1c040510d751e42e1690bf870e5459430 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Thu, 3 Aug 2023 16:21:10 -0400 Subject: [PATCH 070/125] Bump version to 2.4.3-1 Issue 5729 - Memory leak in factory_create_extension (#5814) Issue 5870 - ns-slapd crashes at startup if a backend has no suffix (#5871) Issue 5876 - CI Test random failure - Import (#5879) Issue 5877 - test_basic_ldapagent breaks test_setup_ds_as_non_root* tests Issue 5867 - lib389 should use filter for tarfile as recommended by PEP 706 (#5868) Issue 5853 - Update Cargo.lock and fix minor warning (#5854) Issue 5785 - CLI - arg completion is broken Issue 5864 - Server fails to start after reboot because it's unable to access nsslapd-rundir Issue 5856 - SyntaxWarning: invalid escape sequence '\,' Issue 5859 - dbscan fails with AttributeError: 'list' object has no attribute 'extends' Issue 3527 - UI - Add nsslapd-haproxy-trusted-ip to server setting (#5839) Issue 4551 - Paged search impacts performance (#5838) Issue 4758 - Add tests for WebUI Issue 4169 - UI - Fix retrochangelog and schema Typeaheads (#5837) issue 5833 - dsconf monitor backend fails on lmdb (#5835) Issue 3555 - UI - Fix audit issue with npm - stylelint (#5836) --- .gitignore | 1 + sources | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 455f450..c2b55ed 100644 --- a/.gitignore +++ b/.gitignore @@ -222,3 +222,4 @@ /389-ds-base-2.4.0.tar.bz2 /389-ds-base-2.4.1.tar.bz2 /389-ds-base-2.4.2.tar.bz2 +/389-ds-base-2.4.3.tar.bz2 diff --git a/sources b/sources index 3213dba..1533e82 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (389-ds-base-2.4.2.tar.bz2) = ffaab71739b8a08f377b00e30d3b10f430ead8ab5c04e0a7e6d1fa4364764e083474d0eb8277fd02c367d533623d41b7d3c5e5ecab5fd3471d8f49709e2ae264 +SHA512 (389-ds-base-2.4.3.tar.bz2) = 0cd783f989afe3af7c2f129f7a48c78963479d1066275e01ccef1dbe96b953714eb541c2824c8a3d5088d9e9e98851d3c1a443e811297ab86f23ac70f873985f SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 From 66e89183362f1284b24717fa27f9c1a837dec736 Mon Sep 17 00:00:00 2001 From: James Chapman Date: Wed, 15 Nov 2023 13:39:05 +0000 Subject: [PATCH 071/125] Bump version to 2.4.4 Issue 5971 - CLI - Fix password prompt for repl status (#5972) Issue 5973 - Fix fedora cop RawHide builds (#5974) Revert "Issue 5761 - Worker thread dynamic management (#5796)" (#5970) Issue 5966 - CLI - Custom schema object is removed on a failed edit (#5967) Issue 5786 - Update permissions for Release workflow Issue 5960 - Subpackages should have more strict interdependencies Issue 3555 - UI - Fix audit issue with npm - babel/traverse (#5959) Issue 4843 - Fix dscreate create-template issue (#5950) bugfix for --passwd-file not working on latest version (#5934) Issue 5843 - dsconf / dscreate should be able to handle lmdb parameters (#5943) Bump postcss from 8.4.24 to 8.4.31 in /src/cockpit/389-console (#5945) Issue 5938 - Attribute Names changed to lowercase after adding the Attributes (#5940) issue 5924 - ASAN server build crash when looping opening/closing connections (#5926) Issue 1925 - Add a CI test (#5936) Issue 5732 - Localizing Cockpit's 389ds Plugin using CockpitPoPlugin (#5764) Issue 1870 - Add a CI test (#5929) Issue 843 - Add a warning to slapi_valueset_add_value_ext (#5925) Issue 5761 - Worker thread dynamic management (#5796) Issue 1802 - Improve ldclt man page (#5928) Issue 1456 - Add a CI test that verifies there is no issue (#5927) Issue 1317 - Add a CI test (#5923) Issue 1081 - CI - Add more tests for overwriting x-origin issue (#5815) Issue 1115 - Add a CI test (#5913) Issue 5848 - Fix condition and add a CI test (#5916) Issue 5848 - Fix condition and add a CI test (#5916) Issue 5914 - UI - server settings page validation improvements and db index fixes Issue 5909 - Multi listener hang with 20k connections (#5917) Issue 5902 - Fix previous commit regression (#5919) pass instance correctly to ds_is_older (#5903) Issue 5909 - Multi listener hang with 20k connections (#5910) Issue 5722 - improve testcase (#5904) Issue 5203 - outdated version in provided metadata for lib389 Bug Description: issue 5890 part 2 - Need a tester for testing multiple listening thread feature (#5897) Issue i5846 - Crash when lmdb import is aborted (#5881) Issue 5894 - lmdb import error fails with Could not store the entry (#5895) Issue 5890 - Need a tester for testing multiple listening thread feature (#5891) Issue 5082 - slugify: ModuleNotFoundError when running test cases Issue 4551 - Part 2 - Fix build warning of previous PR (#5888) Issue 5834 - AccountPolicyPlugin erroring for some users (#5866) Issue 5872 - part 2 - fix is_dbi regression (#5887) Issue 4758 - Add tests for WebUI Issue 5848 - dsconf should prevent setting the replicaID for hub and consumer roles (#5849) Issue 5883 - Remove connection mutex contention risk on autobind (#5886) Issue 5872 - `dbscan()` in lib389 can return bytes --- .gitignore | 1 + 389-ds-base.spec | 138 +++++++++++++++++++++++++++++++---------------- sources | 2 +- 3 files changed, 95 insertions(+), 46 deletions(-) diff --git a/.gitignore b/.gitignore index c2b55ed..ec29d90 100644 --- a/.gitignore +++ b/.gitignore @@ -223,3 +223,4 @@ /389-ds-base-2.4.1.tar.bz2 /389-ds-base-2.4.2.tar.bz2 /389-ds-base-2.4.3.tar.bz2 +/389-ds-base-2.4.4.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 1353123..159197c 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -45,9 +45,9 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.4.3 +Version: 2.4.4 Release: 1%{?dist} -License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (0BSD or MIT or ASL 2.0) and (Unlicense or MIT) and MPLv2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and (MIT or zlib or ASL 2.0) and ASL 2.0 and (ASL 2.0 or Boost) and ((MIT or ASL 2.0) and Unicode-DFS-2016) +License: GPLv3+ and (ASL 2.0 or MIT) and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and (0BSD or MIT or ASL 2.0) and MPLv2.0 and ASL 2.0 and (MIT or zlib or ASL 2.0) and ((MIT or ASL 2.0) and Unicode-DFS-2016) and (ASL 2.0 or Boost) and BSD URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 Conflicts: freeipa-server < 4.0.3 @@ -57,19 +57,19 @@ Obsoletes: %{name}-legacy-tools-debuginfo < 1.4.4.6 Provides: ldif2ldbm >= 0 ##### Bundled cargo crates list - START ##### -Provides: bundled(crate(addr2line)) = 0.20.0 +Provides: bundled(crate(addr2line)) = 0.21.0 Provides: bundled(crate(adler)) = 1.0.2 -Provides: bundled(crate(ahash)) = 0.7.6 +Provides: bundled(crate(ahash)) = 0.7.7 Provides: bundled(crate(ansi_term)) = 0.12.1 Provides: bundled(crate(atty)) = 0.2.14 Provides: bundled(crate(autocfg)) = 1.1.0 -Provides: bundled(crate(backtrace)) = 0.3.68 +Provides: bundled(crate(backtrace)) = 0.3.69 Provides: bundled(crate(base64)) = 0.13.1 Provides: bundled(crate(bitflags)) = 1.3.2 -Provides: bundled(crate(bitflags)) = 2.3.3 -Provides: bundled(crate(byteorder)) = 1.4.3 +Provides: bundled(crate(bitflags)) = 2.4.1 +Provides: bundled(crate(byteorder)) = 1.5.0 Provides: bundled(crate(cbindgen)) = 0.9.1 -Provides: bundled(crate(cc)) = 1.0.81 +Provides: bundled(crate(cc)) = 1.0.83 Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 2.34.0 Provides: bundled(crate(concread)) = 0.2.21 @@ -81,70 +81,69 @@ Provides: bundled(crate(crossbeam-queue)) = 0.3.8 Provides: bundled(crate(crossbeam-utils)) = 0.8.16 Provides: bundled(crate(entryuuid)) = 0.1.0 Provides: bundled(crate(entryuuid_syntax)) = 0.1.0 -Provides: bundled(crate(errno)) = 0.3.2 -Provides: bundled(crate(errno-dragonfly)) = 0.1.2 -Provides: bundled(crate(fastrand)) = 2.0.0 +Provides: bundled(crate(errno)) = 0.3.6 +Provides: bundled(crate(fastrand)) = 2.0.1 Provides: bundled(crate(fernet)) = 0.1.4 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 -Provides: bundled(crate(getrandom)) = 0.2.10 -Provides: bundled(crate(gimli)) = 0.27.3 +Provides: bundled(crate(getrandom)) = 0.2.11 +Provides: bundled(crate(gimli)) = 0.28.0 Provides: bundled(crate(hashbrown)) = 0.12.3 Provides: bundled(crate(hermit-abi)) = 0.1.19 Provides: bundled(crate(instant)) = 0.1.12 Provides: bundled(crate(itoa)) = 1.0.9 -Provides: bundled(crate(jobserver)) = 0.1.26 -Provides: bundled(crate(libc)) = 0.2.147 +Provides: bundled(crate(jobserver)) = 0.1.27 +Provides: bundled(crate(libc)) = 0.2.150 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 -Provides: bundled(crate(linux-raw-sys)) = 0.4.5 -Provides: bundled(crate(lock_api)) = 0.4.10 -Provides: bundled(crate(log)) = 0.4.19 +Provides: bundled(crate(linux-raw-sys)) = 0.4.11 +Provides: bundled(crate(lock_api)) = 0.4.11 +Provides: bundled(crate(log)) = 0.4.20 Provides: bundled(crate(lru)) = 0.7.8 -Provides: bundled(crate(memchr)) = 2.5.0 +Provides: bundled(crate(memchr)) = 2.6.4 Provides: bundled(crate(memoffset)) = 0.9.0 Provides: bundled(crate(miniz_oxide)) = 0.7.1 -Provides: bundled(crate(object)) = 0.31.1 +Provides: bundled(crate(object)) = 0.32.1 Provides: bundled(crate(once_cell)) = 1.18.0 -Provides: bundled(crate(openssl)) = 0.10.55 +Provides: bundled(crate(openssl)) = 0.10.59 Provides: bundled(crate(openssl-macros)) = 0.1.1 -Provides: bundled(crate(openssl-sys)) = 0.9.90 +Provides: bundled(crate(openssl-sys)) = 0.9.95 Provides: bundled(crate(parking_lot)) = 0.11.2 Provides: bundled(crate(parking_lot_core)) = 0.8.6 Provides: bundled(crate(paste)) = 0.1.18 Provides: bundled(crate(paste-impl)) = 0.1.18 -Provides: bundled(crate(pin-project-lite)) = 0.2.10 +Provides: bundled(crate(pin-project-lite)) = 0.2.13 Provides: bundled(crate(pkg-config)) = 0.3.27 Provides: bundled(crate(ppv-lite86)) = 0.2.17 Provides: bundled(crate(proc-macro-hack)) = 0.5.20+deprecated -Provides: bundled(crate(proc-macro2)) = 1.0.66 +Provides: bundled(crate(proc-macro2)) = 1.0.69 Provides: bundled(crate(pwdchan)) = 0.1.0 -Provides: bundled(crate(quote)) = 1.0.32 +Provides: bundled(crate(quote)) = 1.0.33 Provides: bundled(crate(rand)) = 0.8.5 Provides: bundled(crate(rand_chacha)) = 0.3.1 Provides: bundled(crate(rand_core)) = 0.6.4 Provides: bundled(crate(redox_syscall)) = 0.2.16 -Provides: bundled(crate(redox_syscall)) = 0.3.5 +Provides: bundled(crate(redox_syscall)) = 0.4.1 Provides: bundled(crate(rustc-demangle)) = 0.1.23 -Provides: bundled(crate(rustix)) = 0.38.6 +Provides: bundled(crate(rustix)) = 0.38.24 Provides: bundled(crate(ryu)) = 1.0.15 Provides: bundled(crate(scopeguard)) = 1.2.0 -Provides: bundled(crate(serde)) = 1.0.180 -Provides: bundled(crate(serde_derive)) = 1.0.180 -Provides: bundled(crate(serde_json)) = 1.0.104 +Provides: bundled(crate(serde)) = 1.0.192 +Provides: bundled(crate(serde_derive)) = 1.0.192 +Provides: bundled(crate(serde_json)) = 1.0.108 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 -Provides: bundled(crate(smallvec)) = 1.11.0 +Provides: bundled(crate(smallvec)) = 1.11.2 Provides: bundled(crate(strsim)) = 0.8.0 Provides: bundled(crate(syn)) = 1.0.109 -Provides: bundled(crate(syn)) = 2.0.28 -Provides: bundled(crate(tempfile)) = 3.7.0 +Provides: bundled(crate(syn)) = 2.0.39 +Provides: bundled(crate(tempfile)) = 3.8.1 Provides: bundled(crate(textwrap)) = 0.11.0 -Provides: bundled(crate(tokio)) = 1.29.1 -Provides: bundled(crate(tokio-macros)) = 2.1.0 +Provides: bundled(crate(tokio)) = 1.34.0 +Provides: bundled(crate(tokio-macros)) = 2.2.0 Provides: bundled(crate(toml)) = 0.5.11 -Provides: bundled(crate(unicode-ident)) = 1.0.11 -Provides: bundled(crate(unicode-width)) = 0.1.10 +Provides: bundled(crate(unicode-ident)) = 1.0.12 +Provides: bundled(crate(unicode-width)) = 0.1.11 Provides: bundled(crate(uuid)) = 0.8.2 Provides: bundled(crate(vcpkg)) = 0.2.15 Provides: bundled(crate(vec_map)) = 0.8.2 @@ -154,14 +153,14 @@ Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(windows-sys)) = 0.48.0 -Provides: bundled(crate(windows-targets)) = 0.48.1 -Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.48.0 -Provides: bundled(crate(windows_aarch64_msvc)) = 0.48.0 -Provides: bundled(crate(windows_i686_gnu)) = 0.48.0 -Provides: bundled(crate(windows_i686_msvc)) = 0.48.0 -Provides: bundled(crate(windows_x86_64_gnu)) = 0.48.0 -Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.48.0 -Provides: bundled(crate(windows_x86_64_msvc)) = 0.48.0 +Provides: bundled(crate(windows-targets)) = 0.48.5 +Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.48.5 +Provides: bundled(crate(windows_aarch64_msvc)) = 0.48.5 +Provides: bundled(crate(windows_i686_gnu)) = 0.48.5 +Provides: bundled(crate(windows_i686_msvc)) = 0.48.5 +Provides: bundled(crate(windows_x86_64_gnu)) = 0.48.5 +Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.48.5 +Provides: bundled(crate(windows_x86_64_msvc)) = 0.48.5 Provides: bundled(crate(zeroize)) = 1.6.0 Provides: bundled(crate(zeroize_derive)) = 1.4.2 ##### Bundled cargo crates list - END ##### @@ -464,6 +463,7 @@ autoreconf -fiv --with-libldap-r=no # lib389 +make src/lib389/setup.py pushd ./src/lib389 %py3_build popd @@ -734,6 +734,54 @@ exit 0 %endif %changelog +* Wed Nov 15 2023 James Chapman - 2.4.4 +- Bump version to 2.4.4 +- Issue 5971 - CLI - Fix password prompt for repl status (#5972) +- Issue 5973 - Fix fedora cop RawHide builds (#5974) +- Revert "Issue 5761 - Worker thread dynamic management (#5796)" (#5970) +- Issue 5966 - CLI - Custom schema object is removed on a failed edit (#5967) +- Issue 5786 - Update permissions for Release workflow +- Issue 5960 - Subpackages should have more strict interdependencies +- Issue 3555 - UI - Fix audit issue with npm - babel/traverse (#5959) +- Issue 4843 - Fix dscreate create-template issue (#5950) +- bugfix for --passwd-file not working on latest version (#5934) +- Issue 5843 - dsconf / dscreate should be able to handle lmdb parameters (#5943) +- Bump postcss from 8.4.24 to 8.4.31 in /src/cockpit/389-console (#5945) +- Issue 5938 - Attribute Names changed to lowercase after adding the Attributes (#5940) +- issue 5924 - ASAN server build crash when looping opening/closing connections (#5926) +- Issue 1925 - Add a CI test (#5936) +- Issue 5732 - Localizing Cockpit's 389ds Plugin using CockpitPoPlugin (#5764) +- Issue 1870 - Add a CI test (#5929) +- Issue 843 - Add a warning to slapi_valueset_add_value_ext (#5925) +- Issue 5761 - Worker thread dynamic management (#5796) +- Issue 1802 - Improve ldclt man page (#5928) +- Issue 1456 - Add a CI test that verifies there is no issue (#5927) +- Issue 1317 - Add a CI test (#5923) +- Issue 1081 - CI - Add more tests for overwriting x-origin issue (#5815) +- Issue 1115 - Add a CI test (#5913) +- Issue 5848 - Fix condition and add a CI test (#5916) +- Issue 5848 - Fix condition and add a CI test (#5916) +- Issue 5914 - UI - server settings page validation improvements and db index fixes +- Issue 5909 - Multi listener hang with 20k connections (#5917) +- Issue 5902 - Fix previous commit regression (#5919) +- pass instance correctly to ds_is_older (#5903) +- Issue 5909 - Multi listener hang with 20k connections (#5910) +- Issue 5722 - improve testcase (#5904) +- Issue 5203 - outdated version in provided metadata for lib389 +- Bug Description: +- issue 5890 part 2 - Need a tester for testing multiple listening thread feature (#5897) +- Issue i5846 - Crash when lmdb import is aborted (#5881) +- Issue 5894 - lmdb import error fails with Could not store the entry (#5895) +- Issue 5890 - Need a tester for testing multiple listening thread feature (#5891) +- Issue 5082 - slugify: ModuleNotFoundError when running test cases +- Issue 4551 - Part 2 - Fix build warning of previous PR (#5888) +- Issue 5834 - AccountPolicyPlugin erroring for some users (#5866) +- Issue 5872 - part 2 - fix is_dbi regression (#5887) +- Issue 4758 - Add tests for WebUI +- Issue 5848 - dsconf should prevent setting the replicaID for hub and consumer roles (#5849) +- Issue 5883 - Remove connection mutex contention risk on autobind (#5886) +- Issue 5872 - `dbscan()` in lib389 can return bytes + * Thu Aug 3 2023 Mark Reynolds - 2.4.3-1 - Bump version to 2.4.3-1 - Issue 5729 - Memory leak in factory_create_extension (#5814) diff --git a/sources b/sources index 1533e82..3a2a57e 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (389-ds-base-2.4.3.tar.bz2) = 0cd783f989afe3af7c2f129f7a48c78963479d1066275e01ccef1dbe96b953714eb541c2824c8a3d5088d9e9e98851d3c1a443e811297ab86f23ac70f873985f +SHA512 (389-ds-base-2.4.4.tar.bz2) = 347e8f5f333e3266b2aad4c6505925ae23834bcdce502b5e318d257da1e59b80c32735ee9b30fe5d1ecff8a062cdf798a616922bf8058108a7c0556acf7b0cf4 SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 From 1f152da46b1263b39745c7f8716e66c926ad80cc Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Thu, 18 Jan 2024 11:08:10 +0100 Subject: [PATCH 072/125] Bump version to 2.4.5 Issue 5989 - RFE support of inChain Matching Rule (#5990) Issue 5939 - During an update, if the target entry is reverted in the entry cache, the server should not retry to lock it (#6007) Issue 5944 - Reversion of the entry cache should be limited to BETXN plugin failures (#5994) Issue 5954 - Disable Transparent Huge Pages Issue 5984 - Crash when paged result search are abandoned - fix2 (#5987) Issue 5984 - Crash when paged result search are abandoned (#5985) --- .gitignore | 1 + 389-ds-base.spec | 70 +++++++++++++++++++++++++++++++----------------- sources | 2 +- 3 files changed, 48 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index ec29d90..915e78c 100644 --- a/.gitignore +++ b/.gitignore @@ -224,3 +224,4 @@ /389-ds-base-2.4.2.tar.bz2 /389-ds-base-2.4.3.tar.bz2 /389-ds-base-2.4.4.tar.bz2 +/389-ds-base-2.4.5.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 159197c..e0d37c7 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -45,7 +45,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.4.4 +Version: 2.4.5 Release: 1%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and (0BSD or MIT or ASL 2.0) and MPLv2.0 and ASL 2.0 and (MIT or zlib or ASL 2.0) and ((MIT or ASL 2.0) and Unicode-DFS-2016) and (ASL 2.0 or Boost) and BSD URL: https://www.port389.org @@ -60,7 +60,6 @@ Provides: ldif2ldbm >= 0 Provides: bundled(crate(addr2line)) = 0.21.0 Provides: bundled(crate(adler)) = 1.0.2 Provides: bundled(crate(ahash)) = 0.7.7 -Provides: bundled(crate(ansi_term)) = 0.12.1 Provides: bundled(crate(atty)) = 0.2.14 Provides: bundled(crate(autocfg)) = 1.1.0 Provides: bundled(crate(backtrace)) = 0.3.69 @@ -68,10 +67,11 @@ Provides: bundled(crate(base64)) = 0.13.1 Provides: bundled(crate(bitflags)) = 1.3.2 Provides: bundled(crate(bitflags)) = 2.4.1 Provides: bundled(crate(byteorder)) = 1.5.0 -Provides: bundled(crate(cbindgen)) = 0.9.1 +Provides: bundled(crate(cbindgen)) = 0.26.0 Provides: bundled(crate(cc)) = 1.0.83 Provides: bundled(crate(cfg-if)) = 1.0.0 -Provides: bundled(crate(clap)) = 2.34.0 +Provides: bundled(crate(clap)) = 3.2.25 +Provides: bundled(crate(clap_lex)) = 0.2.4 Provides: bundled(crate(concread)) = 0.2.21 Provides: bundled(crate(crossbeam)) = 0.8.2 Provides: bundled(crate(crossbeam-channel)) = 0.5.8 @@ -81,22 +81,24 @@ Provides: bundled(crate(crossbeam-queue)) = 0.3.8 Provides: bundled(crate(crossbeam-utils)) = 0.8.16 Provides: bundled(crate(entryuuid)) = 0.1.0 Provides: bundled(crate(entryuuid_syntax)) = 0.1.0 -Provides: bundled(crate(errno)) = 0.3.6 +Provides: bundled(crate(errno)) = 0.3.8 Provides: bundled(crate(fastrand)) = 2.0.1 Provides: bundled(crate(fernet)) = 0.1.4 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 Provides: bundled(crate(getrandom)) = 0.2.11 -Provides: bundled(crate(gimli)) = 0.28.0 +Provides: bundled(crate(gimli)) = 0.28.1 Provides: bundled(crate(hashbrown)) = 0.12.3 +Provides: bundled(crate(heck)) = 0.4.1 Provides: bundled(crate(hermit-abi)) = 0.1.19 +Provides: bundled(crate(indexmap)) = 1.9.3 Provides: bundled(crate(instant)) = 0.1.12 -Provides: bundled(crate(itoa)) = 1.0.9 +Provides: bundled(crate(itoa)) = 1.0.10 Provides: bundled(crate(jobserver)) = 0.1.27 -Provides: bundled(crate(libc)) = 0.2.150 +Provides: bundled(crate(libc)) = 0.2.151 Provides: bundled(crate(librnsslapd)) = 0.1.0 Provides: bundled(crate(librslapd)) = 0.1.0 -Provides: bundled(crate(linux-raw-sys)) = 0.4.11 +Provides: bundled(crate(linux-raw-sys)) = 0.4.12 Provides: bundled(crate(lock_api)) = 0.4.11 Provides: bundled(crate(log)) = 0.4.20 Provides: bundled(crate(lru)) = 0.7.8 @@ -104,10 +106,11 @@ Provides: bundled(crate(memchr)) = 2.6.4 Provides: bundled(crate(memoffset)) = 0.9.0 Provides: bundled(crate(miniz_oxide)) = 0.7.1 Provides: bundled(crate(object)) = 0.32.1 -Provides: bundled(crate(once_cell)) = 1.18.0 -Provides: bundled(crate(openssl)) = 0.10.59 +Provides: bundled(crate(once_cell)) = 1.19.0 +Provides: bundled(crate(openssl)) = 0.10.61 Provides: bundled(crate(openssl-macros)) = 0.1.1 -Provides: bundled(crate(openssl-sys)) = 0.9.95 +Provides: bundled(crate(openssl-sys)) = 0.9.97 +Provides: bundled(crate(os_str_bytes)) = 6.6.1 Provides: bundled(crate(parking_lot)) = 0.11.2 Provides: bundled(crate(parking_lot_core)) = 0.8.6 Provides: bundled(crate(paste)) = 0.1.18 @@ -116,7 +119,7 @@ Provides: bundled(crate(pin-project-lite)) = 0.2.13 Provides: bundled(crate(pkg-config)) = 0.3.27 Provides: bundled(crate(ppv-lite86)) = 0.2.17 Provides: bundled(crate(proc-macro-hack)) = 0.5.20+deprecated -Provides: bundled(crate(proc-macro2)) = 1.0.69 +Provides: bundled(crate(proc-macro2)) = 1.0.70 Provides: bundled(crate(pwdchan)) = 0.1.0 Provides: bundled(crate(quote)) = 1.0.33 Provides: bundled(crate(rand)) = 0.8.5 @@ -125,46 +128,56 @@ Provides: bundled(crate(rand_core)) = 0.6.4 Provides: bundled(crate(redox_syscall)) = 0.2.16 Provides: bundled(crate(redox_syscall)) = 0.4.1 Provides: bundled(crate(rustc-demangle)) = 0.1.23 -Provides: bundled(crate(rustix)) = 0.38.24 -Provides: bundled(crate(ryu)) = 1.0.15 +Provides: bundled(crate(rustix)) = 0.38.28 +Provides: bundled(crate(ryu)) = 1.0.16 Provides: bundled(crate(scopeguard)) = 1.2.0 -Provides: bundled(crate(serde)) = 1.0.192 -Provides: bundled(crate(serde_derive)) = 1.0.192 +Provides: bundled(crate(serde)) = 1.0.193 +Provides: bundled(crate(serde_derive)) = 1.0.193 Provides: bundled(crate(serde_json)) = 1.0.108 Provides: bundled(crate(slapd)) = 0.1.0 Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 Provides: bundled(crate(smallvec)) = 1.11.2 -Provides: bundled(crate(strsim)) = 0.8.0 +Provides: bundled(crate(strsim)) = 0.10.0 Provides: bundled(crate(syn)) = 1.0.109 -Provides: bundled(crate(syn)) = 2.0.39 +Provides: bundled(crate(syn)) = 2.0.40 Provides: bundled(crate(tempfile)) = 3.8.1 -Provides: bundled(crate(textwrap)) = 0.11.0 -Provides: bundled(crate(tokio)) = 1.34.0 +Provides: bundled(crate(termcolor)) = 1.4.0 +Provides: bundled(crate(textwrap)) = 0.16.0 +Provides: bundled(crate(tokio)) = 1.35.0 Provides: bundled(crate(tokio-macros)) = 2.2.0 Provides: bundled(crate(toml)) = 0.5.11 Provides: bundled(crate(unicode-ident)) = 1.0.12 -Provides: bundled(crate(unicode-width)) = 0.1.11 Provides: bundled(crate(uuid)) = 0.8.2 Provides: bundled(crate(vcpkg)) = 0.2.15 -Provides: bundled(crate(vec_map)) = 0.8.2 Provides: bundled(crate(version_check)) = 0.9.4 Provides: bundled(crate(wasi)) = 0.11.0+wasi_snapshot_preview1 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 +Provides: bundled(crate(winapi-util)) = 0.1.6 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(windows-sys)) = 0.48.0 +Provides: bundled(crate(windows-sys)) = 0.52.0 Provides: bundled(crate(windows-targets)) = 0.48.5 +Provides: bundled(crate(windows-targets)) = 0.52.0 Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.48.5 +Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.52.0 Provides: bundled(crate(windows_aarch64_msvc)) = 0.48.5 +Provides: bundled(crate(windows_aarch64_msvc)) = 0.52.0 Provides: bundled(crate(windows_i686_gnu)) = 0.48.5 +Provides: bundled(crate(windows_i686_gnu)) = 0.52.0 Provides: bundled(crate(windows_i686_msvc)) = 0.48.5 +Provides: bundled(crate(windows_i686_msvc)) = 0.52.0 Provides: bundled(crate(windows_x86_64_gnu)) = 0.48.5 +Provides: bundled(crate(windows_x86_64_gnu)) = 0.52.0 Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.48.5 +Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.52.0 Provides: bundled(crate(windows_x86_64_msvc)) = 0.48.5 -Provides: bundled(crate(zeroize)) = 1.6.0 +Provides: bundled(crate(windows_x86_64_msvc)) = 0.52.0 +Provides: bundled(crate(zeroize)) = 1.7.0 Provides: bundled(crate(zeroize_derive)) = 1.4.2 ##### Bundled cargo crates list - END ##### + BuildRequires: nspr-devel >= 4.32 BuildRequires: nss-devel >= 3.67.0-7 BuildRequires: openldap-devel @@ -734,6 +747,15 @@ exit 0 %endif %changelog +* Thu Jan 18 2024 Viktor Ashirov - 2.4.5-1 +- Bump version to 2.4.5 +- Issue 5989 - RFE support of inChain Matching Rule (#5990) +- Issue 5939 - During an update, if the target entry is reverted in the entry cache, the server should not retry to lock it (#6007) +- Issue 5944 - Reversion of the entry cache should be limited to BETXN plugin failures (#5994) +- Issue 5954 - Disable Transparent Huge Pages +- Issue 5984 - Crash when paged result search are abandoned - fix2 (#5987) +- Issue 5984 - Crash when paged result search are abandoned (#5985) + * Wed Nov 15 2023 James Chapman - 2.4.4 - Bump version to 2.4.4 - Issue 5971 - CLI - Fix password prompt for repl status (#5972) diff --git a/sources b/sources index 3a2a57e..6604548 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (389-ds-base-2.4.4.tar.bz2) = 347e8f5f333e3266b2aad4c6505925ae23834bcdce502b5e318d257da1e59b80c32735ee9b30fe5d1ecff8a062cdf798a616922bf8058108a7c0556acf7b0cf4 +SHA512 (389-ds-base-2.4.5.tar.bz2) = 452c2194bdbe6c4c87409469e33de6d134f3a839f329f67cd5e7d92bbc635c7914f76acc85bcdd8e68427234c1c5b00cee83b7f83f293f9df0666dca3dd38375 SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 From fd4c2c06c1990e8cabc75d27957b12115a95c8de Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 18 Jan 2024 11:59:55 +0000 Subject: [PATCH 073/125] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index e0d37c7..35cdde5 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.4.5 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and (0BSD or MIT or ASL 2.0) and MPLv2.0 and ASL 2.0 and (MIT or zlib or ASL 2.0) and ((MIT or ASL 2.0) and Unicode-DFS-2016) and (ASL 2.0 or Boost) and BSD URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -747,6 +747,9 @@ exit 0 %endif %changelog +* Thu Jan 18 2024 Fedora Release Engineering - 2.4.5-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Thu Jan 18 2024 Viktor Ashirov - 2.4.5-1 - Bump version to 2.4.5 - Issue 5989 - RFE support of inChain Matching Rule (#5990) From fd0449a4487fd517947d28979123afc7c6bb7de4 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 19 Jan 2024 09:04:49 +0000 Subject: [PATCH 074/125] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 35cdde5..8430bdf 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.4.5 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and (0BSD or MIT or ASL 2.0) and MPLv2.0 and ASL 2.0 and (MIT or zlib or ASL 2.0) and ((MIT or ASL 2.0) and Unicode-DFS-2016) and (ASL 2.0 or Boost) and BSD URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -747,6 +747,9 @@ exit 0 %endif %changelog +* Fri Jan 19 2024 Fedora Release Engineering - 2.4.5-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Thu Jan 18 2024 Fedora Release Engineering - 2.4.5-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From bff8e548416e349298382bccc6ded2e824102271 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Mon, 22 Jan 2024 20:39:09 +0000 Subject: [PATCH 075/125] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 8430bdf..398c36d 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.4.5 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and (0BSD or MIT or ASL 2.0) and MPLv2.0 and ASL 2.0 and (MIT or zlib or ASL 2.0) and ((MIT or ASL 2.0) and Unicode-DFS-2016) and (ASL 2.0 or Boost) and BSD URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -747,6 +747,9 @@ exit 0 %endif %changelog +* Mon Jan 22 2024 Fedora Release Engineering - 2.4.5-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Fri Jan 19 2024 Fedora Release Engineering - 2.4.5-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From 10d5e9ae35dcf41f6345bab9f5ae20d2c8f8dc51 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Mon, 29 Jan 2024 10:42:17 +0000 Subject: [PATCH 076/125] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 398c36d..96d84b8 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 2.4.5 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ and (ASL 2.0 or MIT) and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and (0BSD or MIT or ASL 2.0) and MPLv2.0 and ASL 2.0 and (MIT or zlib or ASL 2.0) and ((MIT or ASL 2.0) and Unicode-DFS-2016) and (ASL 2.0 or Boost) and BSD URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -747,6 +747,9 @@ exit 0 %endif %changelog +* Mon Jan 29 2024 Fedora Release Engineering - 2.4.5-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Mon Jan 22 2024 Fedora Release Engineering - 2.4.5-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From e374e35b044e47d3b283c92d5818022d0792ab3b Mon Sep 17 00:00:00 2001 From: Simon Pichugin Date: Tue, 30 Jan 2024 12:30:41 -0800 Subject: [PATCH 077/125] Bump version to 3.0.1 Issue 6043, 6044 - Enhance Rust and JS bundling and add SPDX licenses for both (#6045) Issue 3555 - Remove audit-ci from dependencies (#6056) Issue 6052 - Paged results test sets hostname to `localhost` on test collection Issue 6051 - Drop unused pytest markers Issue 6049 - lmdb - changelog is wrongly recreated by reindex task (#6050) Issue 6047 - Add a check for tagged commits Issue 6041 - dscreate ds-root - accepts relative path (#6042) Switch default backend to lmdb and bump version to 3.0 (#6013) Issue 6032 - Replication broken after backup restore (#6035) Issue 6037 - Server crash at startup in vlvIndex_delete (#6038) Issue 6034 - Change replica_id from str to int Issue 6028 - vlv index keys inconsistencies (#6031) Issue 5989 - RFE support of inChain Matching Rule (#5990) Issue 6022 - lmdb inconsistency between vlv index and vlv cache names (#6026) Issue 6015 - Fix typo remeber (#6014) Issue 6016 - Pin upload/download artifacts action to v3 Issue 5939 - During an update, if the target entry is reverted in the entry cache, the server should not retry to lock it (#6007) Issue 4673 - Update Rust crates Issue 6004 - idletimeout may be ignored (#6005) Issue 5954 - Disable Transparent Huge Pages Issue 5997 - test_inactivty_and_expiration CI testcase is wrong (#5999) Issue 5993 - Fix several race condition around CI tests (#5996) Issue 5944 - Reversion of the entry cache should be limited to BETXN plugin failures (#5994) Bump openssl from 0.10.55 to 0.10.60 in /src (#5995) Issue 5980 - Improve instance startup failure handling (#5991) Issue 5976 - Fix freeipa install regression with lmdb (#5977) Issue 5984 - Crash when paged result search are abandoned - fix2 (#5987) Issue 5984 - Crash when paged result search are abandoned (#5985) Issue 5947 - CI test_vlv_recreation_reindex fails on LMDB (#5979) --- .gitignore | 1 + 389-ds-base.spec | 290 +++++++++++++++++++++++++++++++++++++++-------- sources | 2 +- 3 files changed, 243 insertions(+), 50 deletions(-) diff --git a/.gitignore b/.gitignore index 915e78c..3a72004 100644 --- a/.gitignore +++ b/.gitignore @@ -225,3 +225,4 @@ /389-ds-base-2.4.3.tar.bz2 /389-ds-base-2.4.4.tar.bz2 /389-ds-base-2.4.5.tar.bz2 +/389-ds-base-3.0.1.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 96d84b8..9279244 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -45,9 +45,9 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 2.4.5 -Release: 5%{?dist} -License: GPLv3+ and (ASL 2.0 or MIT) and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and (0BSD or MIT or ASL 2.0) and MPLv2.0 and ASL 2.0 and (MIT or zlib or ASL 2.0) and ((MIT or ASL 2.0) and Unicode-DFS-2016) and (ASL 2.0 or Boost) and BSD +Version: 3.0.1 +Release: 1%{?dist} +License: GPL-3.0-or-later AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-DFS-2016 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MPL-2.0 AND PSF-2.0 URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 Conflicts: freeipa-server < 4.0.3 @@ -64,8 +64,7 @@ Provides: bundled(crate(atty)) = 0.2.14 Provides: bundled(crate(autocfg)) = 1.1.0 Provides: bundled(crate(backtrace)) = 0.3.69 Provides: bundled(crate(base64)) = 0.13.1 -Provides: bundled(crate(bitflags)) = 1.3.2 -Provides: bundled(crate(bitflags)) = 2.4.1 +Provides: bundled(crate(bitflags)) = 2.4.2 Provides: bundled(crate(byteorder)) = 1.5.0 Provides: bundled(crate(cbindgen)) = 0.26.0 Provides: bundled(crate(cc)) = 1.0.83 @@ -73,20 +72,18 @@ Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 3.2.25 Provides: bundled(crate(clap_lex)) = 0.2.4 Provides: bundled(crate(concread)) = 0.2.21 -Provides: bundled(crate(crossbeam)) = 0.8.2 -Provides: bundled(crate(crossbeam-channel)) = 0.5.8 -Provides: bundled(crate(crossbeam-deque)) = 0.8.3 -Provides: bundled(crate(crossbeam-epoch)) = 0.9.15 -Provides: bundled(crate(crossbeam-queue)) = 0.3.8 -Provides: bundled(crate(crossbeam-utils)) = 0.8.16 -Provides: bundled(crate(entryuuid)) = 0.1.0 -Provides: bundled(crate(entryuuid_syntax)) = 0.1.0 +Provides: bundled(crate(crossbeam)) = 0.8.4 +Provides: bundled(crate(crossbeam-channel)) = 0.5.11 +Provides: bundled(crate(crossbeam-deque)) = 0.8.5 +Provides: bundled(crate(crossbeam-epoch)) = 0.9.18 +Provides: bundled(crate(crossbeam-queue)) = 0.3.11 +Provides: bundled(crate(crossbeam-utils)) = 0.8.19 Provides: bundled(crate(errno)) = 0.3.8 Provides: bundled(crate(fastrand)) = 2.0.1 Provides: bundled(crate(fernet)) = 0.1.4 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 -Provides: bundled(crate(getrandom)) = 0.2.11 +Provides: bundled(crate(getrandom)) = 0.2.12 Provides: bundled(crate(gimli)) = 0.28.1 Provides: bundled(crate(hashbrown)) = 0.12.3 Provides: bundled(crate(heck)) = 0.4.1 @@ -95,55 +92,47 @@ Provides: bundled(crate(indexmap)) = 1.9.3 Provides: bundled(crate(instant)) = 0.1.12 Provides: bundled(crate(itoa)) = 1.0.10 Provides: bundled(crate(jobserver)) = 0.1.27 -Provides: bundled(crate(libc)) = 0.2.151 -Provides: bundled(crate(librnsslapd)) = 0.1.0 -Provides: bundled(crate(librslapd)) = 0.1.0 -Provides: bundled(crate(linux-raw-sys)) = 0.4.12 +Provides: bundled(crate(libc)) = 0.2.152 +Provides: bundled(crate(linux-raw-sys)) = 0.4.13 Provides: bundled(crate(lock_api)) = 0.4.11 Provides: bundled(crate(log)) = 0.4.20 Provides: bundled(crate(lru)) = 0.7.8 -Provides: bundled(crate(memchr)) = 2.6.4 -Provides: bundled(crate(memoffset)) = 0.9.0 +Provides: bundled(crate(memchr)) = 2.7.1 Provides: bundled(crate(miniz_oxide)) = 0.7.1 -Provides: bundled(crate(object)) = 0.32.1 +Provides: bundled(crate(object)) = 0.32.2 Provides: bundled(crate(once_cell)) = 1.19.0 -Provides: bundled(crate(openssl)) = 0.10.61 +Provides: bundled(crate(openssl)) = 0.10.63 Provides: bundled(crate(openssl-macros)) = 0.1.1 -Provides: bundled(crate(openssl-sys)) = 0.9.97 +Provides: bundled(crate(openssl-sys)) = 0.9.99 Provides: bundled(crate(os_str_bytes)) = 6.6.1 Provides: bundled(crate(parking_lot)) = 0.11.2 Provides: bundled(crate(parking_lot_core)) = 0.8.6 Provides: bundled(crate(paste)) = 0.1.18 Provides: bundled(crate(paste-impl)) = 0.1.18 Provides: bundled(crate(pin-project-lite)) = 0.2.13 -Provides: bundled(crate(pkg-config)) = 0.3.27 +Provides: bundled(crate(pkg-config)) = 0.3.29 Provides: bundled(crate(ppv-lite86)) = 0.2.17 Provides: bundled(crate(proc-macro-hack)) = 0.5.20+deprecated -Provides: bundled(crate(proc-macro2)) = 1.0.70 -Provides: bundled(crate(pwdchan)) = 0.1.0 -Provides: bundled(crate(quote)) = 1.0.33 +Provides: bundled(crate(proc-macro2)) = 1.0.78 +Provides: bundled(crate(quote)) = 1.0.35 Provides: bundled(crate(rand)) = 0.8.5 Provides: bundled(crate(rand_chacha)) = 0.3.1 Provides: bundled(crate(rand_core)) = 0.6.4 -Provides: bundled(crate(redox_syscall)) = 0.2.16 Provides: bundled(crate(redox_syscall)) = 0.4.1 Provides: bundled(crate(rustc-demangle)) = 0.1.23 -Provides: bundled(crate(rustix)) = 0.38.28 +Provides: bundled(crate(rustix)) = 0.38.30 Provides: bundled(crate(ryu)) = 1.0.16 Provides: bundled(crate(scopeguard)) = 1.2.0 -Provides: bundled(crate(serde)) = 1.0.193 -Provides: bundled(crate(serde_derive)) = 1.0.193 -Provides: bundled(crate(serde_json)) = 1.0.108 -Provides: bundled(crate(slapd)) = 0.1.0 -Provides: bundled(crate(slapi_r_plugin)) = 0.1.0 -Provides: bundled(crate(smallvec)) = 1.11.2 +Provides: bundled(crate(serde)) = 1.0.196 +Provides: bundled(crate(serde_derive)) = 1.0.196 +Provides: bundled(crate(serde_json)) = 1.0.113 +Provides: bundled(crate(smallvec)) = 1.13.1 Provides: bundled(crate(strsim)) = 0.10.0 -Provides: bundled(crate(syn)) = 1.0.109 -Provides: bundled(crate(syn)) = 2.0.40 -Provides: bundled(crate(tempfile)) = 3.8.1 -Provides: bundled(crate(termcolor)) = 1.4.0 +Provides: bundled(crate(syn)) = 2.0.48 +Provides: bundled(crate(tempfile)) = 3.9.0 +Provides: bundled(crate(termcolor)) = 1.4.1 Provides: bundled(crate(textwrap)) = 0.16.0 -Provides: bundled(crate(tokio)) = 1.35.0 +Provides: bundled(crate(tokio)) = 1.35.1 Provides: bundled(crate(tokio-macros)) = 2.2.0 Provides: bundled(crate(toml)) = 0.5.11 Provides: bundled(crate(unicode-ident)) = 1.0.12 @@ -155,26 +144,197 @@ Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(winapi-util)) = 0.1.6 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 -Provides: bundled(crate(windows-sys)) = 0.48.0 Provides: bundled(crate(windows-sys)) = 0.52.0 -Provides: bundled(crate(windows-targets)) = 0.48.5 Provides: bundled(crate(windows-targets)) = 0.52.0 -Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.48.5 Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.52.0 -Provides: bundled(crate(windows_aarch64_msvc)) = 0.48.5 Provides: bundled(crate(windows_aarch64_msvc)) = 0.52.0 -Provides: bundled(crate(windows_i686_gnu)) = 0.48.5 Provides: bundled(crate(windows_i686_gnu)) = 0.52.0 -Provides: bundled(crate(windows_i686_msvc)) = 0.48.5 Provides: bundled(crate(windows_i686_msvc)) = 0.52.0 -Provides: bundled(crate(windows_x86_64_gnu)) = 0.48.5 Provides: bundled(crate(windows_x86_64_gnu)) = 0.52.0 -Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.48.5 Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.52.0 -Provides: bundled(crate(windows_x86_64_msvc)) = 0.48.5 Provides: bundled(crate(windows_x86_64_msvc)) = 0.52.0 Provides: bundled(crate(zeroize)) = 1.7.0 Provides: bundled(crate(zeroize_derive)) = 1.4.2 +Provides: bundled(npm(@aashutoshrathi/word-wrap)) = 1.2.6 +Provides: bundled(npm(@eslint-community/eslint-utils)) = 4.4.0 +Provides: bundled(npm(@eslint-community/regexpp)) = 4.5.1 +Provides: bundled(npm(@eslint/eslintrc)) = 2.0.3 +Provides: bundled(npm(@eslint/js)) = 8.42.0 +Provides: bundled(npm(@fortawesome/fontawesome-common-types)) = 0.2.36 +Provides: bundled(npm(@fortawesome/fontawesome-svg-core)) = 1.2.36 +Provides: bundled(npm(@fortawesome/free-solid-svg-icons)) = 5.15.4 +Provides: bundled(npm(@fortawesome/react-fontawesome)) = 0.1.19 +Provides: bundled(npm(@humanwhocodes/config-array)) = 0.11.10 +Provides: bundled(npm(@humanwhocodes/module-importer)) = 1.0.1 +Provides: bundled(npm(@humanwhocodes/object-schema)) = 1.2.1 +Provides: bundled(npm(@nodelib/fs.scandir)) = 2.1.5 +Provides: bundled(npm(@nodelib/fs.stat)) = 2.0.5 +Provides: bundled(npm(@nodelib/fs.walk)) = 1.2.8 +Provides: bundled(npm(@patternfly/patternfly)) = 4.224.2 +Provides: bundled(npm(@patternfly/react-charts)) = 6.94.19 +Provides: bundled(npm(@patternfly/react-core)) = 4.276.8 +Provides: bundled(npm(@patternfly/react-icons)) = 4.93.6 +Provides: bundled(npm(@patternfly/react-styles)) = 4.92.6 +Provides: bundled(npm(@patternfly/react-table)) = 4.113.0 +Provides: bundled(npm(@patternfly/react-tokens)) = 4.94.6 +Provides: bundled(npm(@types/d3-array)) = 3.0.5 +Provides: bundled(npm(@types/d3-color)) = 3.1.0 +Provides: bundled(npm(@types/d3-ease)) = 3.0.0 +Provides: bundled(npm(@types/d3-interpolate)) = 3.0.1 +Provides: bundled(npm(@types/d3-path)) = 3.0.0 +Provides: bundled(npm(@types/d3-scale)) = 4.0.3 +Provides: bundled(npm(@types/d3-shape)) = 3.1.1 +Provides: bundled(npm(@types/d3-time)) = 3.0.0 +Provides: bundled(npm(@types/d3-timer)) = 3.0.0 +Provides: bundled(npm(acorn)) = 8.8.2 +Provides: bundled(npm(acorn-jsx)) = 5.3.2 +Provides: bundled(npm(ajv)) = 6.12.6 +Provides: bundled(npm(ansi-regex)) = 5.0.1 +Provides: bundled(npm(ansi-styles)) = 4.3.0 +Provides: bundled(npm(argparse)) = 2.0.1 +Provides: bundled(npm(attr-accept)) = 1.1.3 +Provides: bundled(npm(balanced-match)) = 1.0.2 +Provides: bundled(npm(brace-expansion)) = 1.1.11 +Provides: bundled(npm(callsites)) = 3.1.0 +Provides: bundled(npm(chalk)) = 4.1.2 +Provides: bundled(npm(color-convert)) = 2.0.1 +Provides: bundled(npm(color-name)) = 1.1.4 +Provides: bundled(npm(concat-map)) = 0.0.1 +Provides: bundled(npm(core-js)) = 2.6.12 +Provides: bundled(npm(cross-spawn)) = 7.0.3 +Provides: bundled(npm(d3-array)) = 3.2.4 +Provides: bundled(npm(d3-color)) = 3.1.0 +Provides: bundled(npm(d3-ease)) = 3.0.1 +Provides: bundled(npm(d3-format)) = 3.1.0 +Provides: bundled(npm(d3-interpolate)) = 3.0.1 +Provides: bundled(npm(d3-path)) = 3.1.0 +Provides: bundled(npm(d3-scale)) = 4.0.2 +Provides: bundled(npm(d3-shape)) = 3.2.0 +Provides: bundled(npm(d3-time)) = 3.1.0 +Provides: bundled(npm(d3-time-format)) = 4.1.0 +Provides: bundled(npm(d3-timer)) = 3.0.1 +Provides: bundled(npm(debug)) = 4.3.4 +Provides: bundled(npm(deep-is)) = 0.1.4 +Provides: bundled(npm(delaunator)) = 4.0.1 +Provides: bundled(npm(delaunay-find)) = 0.0.6 +Provides: bundled(npm(doctrine)) = 3.0.0 +Provides: bundled(npm(encoding)) = 0.1.13 +Provides: bundled(npm(escape-string-regexp)) = 4.0.0 +Provides: bundled(npm(eslint)) = 8.42.0 +Provides: bundled(npm(eslint-plugin-react-hooks)) = 4.6.0 +Provides: bundled(npm(eslint-scope)) = 7.2.0 +Provides: bundled(npm(eslint-visitor-keys)) = 3.4.1 +Provides: bundled(npm(espree)) = 9.5.2 +Provides: bundled(npm(esquery)) = 1.5.0 +Provides: bundled(npm(esrecurse)) = 4.3.0 +Provides: bundled(npm(estraverse)) = 5.3.0 +Provides: bundled(npm(esutils)) = 2.0.3 +Provides: bundled(npm(fast-deep-equal)) = 3.1.3 +Provides: bundled(npm(fast-json-stable-stringify)) = 2.1.0 +Provides: bundled(npm(fast-levenshtein)) = 2.0.6 +Provides: bundled(npm(fastq)) = 1.15.0 +Provides: bundled(npm(file-entry-cache)) = 6.0.1 +Provides: bundled(npm(file-selector)) = 0.1.19 +Provides: bundled(npm(find-up)) = 5.0.0 +Provides: bundled(npm(flat-cache)) = 3.0.4 +Provides: bundled(npm(flatted)) = 3.2.7 +Provides: bundled(npm(focus-trap)) = 6.9.2 +Provides: bundled(npm(fs.realpath)) = 1.0.0 +Provides: bundled(npm(gettext-parser)) = 2.0.0 +Provides: bundled(npm(glob)) = 7.2.3 +Provides: bundled(npm(glob-parent)) = 6.0.2 +Provides: bundled(npm(globals)) = 13.20.0 +Provides: bundled(npm(graphemer)) = 1.4.0 +Provides: bundled(npm(has-flag)) = 4.0.0 +Provides: bundled(npm(hoist-non-react-statics)) = 3.3.2 +Provides: bundled(npm(iconv-lite)) = 0.6.3 +Provides: bundled(npm(ignore)) = 5.2.4 +Provides: bundled(npm(import-fresh)) = 3.3.0 +Provides: bundled(npm(imurmurhash)) = 0.1.4 +Provides: bundled(npm(inflight)) = 1.0.6 +Provides: bundled(npm(inherits)) = 2.0.4 +Provides: bundled(npm(internmap)) = 2.0.3 +Provides: bundled(npm(is-extglob)) = 2.1.1 +Provides: bundled(npm(is-glob)) = 4.0.3 +Provides: bundled(npm(is-path-inside)) = 3.0.3 +Provides: bundled(npm(isexe)) = 2.0.0 +Provides: bundled(npm(js-tokens)) = 4.0.0 +Provides: bundled(npm(js-yaml)) = 4.1.0 +Provides: bundled(npm(json-schema-traverse)) = 0.4.1 +Provides: bundled(npm(json-stable-stringify-without-jsonify)) = 1.0.1 +Provides: bundled(npm(json-stringify-safe)) = 5.0.1 +Provides: bundled(npm(levn)) = 0.4.1 +Provides: bundled(npm(locate-path)) = 6.0.0 +Provides: bundled(npm(lodash)) = 4.17.21 +Provides: bundled(npm(lodash.merge)) = 4.6.2 +Provides: bundled(npm(loose-envify)) = 1.4.0 +Provides: bundled(npm(minimatch)) = 3.1.2 +Provides: bundled(npm(ms)) = 2.1.2 +Provides: bundled(npm(natural-compare)) = 1.4.0 +Provides: bundled(npm(object-assign)) = 4.1.1 +Provides: bundled(npm(once)) = 1.4.0 +Provides: bundled(npm(optionator)) = 0.9.3 +Provides: bundled(npm(p-limit)) = 3.1.0 +Provides: bundled(npm(p-locate)) = 5.0.0 +Provides: bundled(npm(parent-module)) = 1.0.1 +Provides: bundled(npm(path-exists)) = 4.0.0 +Provides: bundled(npm(path-is-absolute)) = 1.0.1 +Provides: bundled(npm(path-key)) = 3.1.1 +Provides: bundled(npm(popper.js)) = 1.16.1 +Provides: bundled(npm(prelude-ls)) = 1.2.1 +Provides: bundled(npm(prop-types)) = 15.8.1 +Provides: bundled(npm(prop-types-extra)) = 1.1.1 +Provides: bundled(npm(punycode)) = 2.3.0 +Provides: bundled(npm(queue-microtask)) = 1.2.3 +Provides: bundled(npm(react)) = 17.0.2 +Provides: bundled(npm(react-dom)) = 17.0.2 +Provides: bundled(npm(react-dropzone)) = 9.0.0 +Provides: bundled(npm(react-fast-compare)) = 3.2.2 +Provides: bundled(npm(react-is)) = 16.13.1 +Provides: bundled(npm(resolve-from)) = 4.0.0 +Provides: bundled(npm(reusify)) = 1.0.4 +Provides: bundled(npm(rimraf)) = 3.0.2 +Provides: bundled(npm(run-parallel)) = 1.2.0 +Provides: bundled(npm(safe-buffer)) = 5.2.1 +Provides: bundled(npm(safer-buffer)) = 2.1.2 +Provides: bundled(npm(scheduler)) = 0.20.2 +Provides: bundled(npm(shebang-command)) = 2.0.0 +Provides: bundled(npm(shebang-regex)) = 3.0.0 +Provides: bundled(npm(strip-ansi)) = 6.0.1 +Provides: bundled(npm(strip-json-comments)) = 3.1.1 +Provides: bundled(npm(supports-color)) = 7.2.0 +Provides: bundled(npm(tabbable)) = 5.3.3 +Provides: bundled(npm(text-table)) = 0.2.0 +Provides: bundled(npm(tippy.js)) = 5.1.2 +Provides: bundled(npm(tslib)) = 2.5.3 +Provides: bundled(npm(type-check)) = 0.4.0 +Provides: bundled(npm(type-fest)) = 0.20.2 +Provides: bundled(npm(uri-js)) = 4.4.1 +Provides: bundled(npm(victory-area)) = 36.6.10 +Provides: bundled(npm(victory-axis)) = 36.6.10 +Provides: bundled(npm(victory-bar)) = 36.6.10 +Provides: bundled(npm(victory-brush-container)) = 36.6.10 +Provides: bundled(npm(victory-chart)) = 36.6.10 +Provides: bundled(npm(victory-core)) = 36.6.10 +Provides: bundled(npm(victory-create-container)) = 36.6.10 +Provides: bundled(npm(victory-cursor-container)) = 36.6.10 +Provides: bundled(npm(victory-group)) = 36.6.10 +Provides: bundled(npm(victory-legend)) = 36.6.10 +Provides: bundled(npm(victory-line)) = 36.6.10 +Provides: bundled(npm(victory-pie)) = 36.6.10 +Provides: bundled(npm(victory-polar-axis)) = 36.6.10 +Provides: bundled(npm(victory-scatter)) = 36.6.10 +Provides: bundled(npm(victory-selection-container)) = 36.6.10 +Provides: bundled(npm(victory-shared-events)) = 36.6.10 +Provides: bundled(npm(victory-stack)) = 36.6.10 +Provides: bundled(npm(victory-tooltip)) = 36.6.10 +Provides: bundled(npm(victory-vendor)) = 36.6.10 +Provides: bundled(npm(victory-voronoi-container)) = 36.6.10 +Provides: bundled(npm(victory-zoom-container)) = 36.6.10 +Provides: bundled(npm(warning)) = 4.0.3 +Provides: bundled(npm(which)) = 2.0.2 +Provides: bundled(npm(wrappy)) = 1.0.2 +Provides: bundled(npm(yocto-queue)) = 0.1.0 ##### Bundled cargo crates list - END ##### @@ -747,6 +907,38 @@ exit 0 %endif %changelog +* Tue Jan 30 2024 Simon Pichugin - 3.0.1-1 +- Bump version to 3.0.1 +- Issue 6043, 6044 - Enhance Rust and JS bundling and add SPDX licenses for both (#6045) +- Issue 3555 - Remove audit-ci from dependencies (#6056) +- Issue 6052 - Paged results test sets hostname to `localhost` on test collection +- Issue 6051 - Drop unused pytest markers +- Issue 6049 - lmdb - changelog is wrongly recreated by reindex task (#6050) +- Issue 6047 - Add a check for tagged commits +- Issue 6041 - dscreate ds-root - accepts relative path (#6042) +- Switch default backend to lmdb and bump version to 3.0 (#6013) +- Issue 6032 - Replication broken after backup restore (#6035) +- Issue 6037 - Server crash at startup in vlvIndex_delete (#6038) +- Issue 6034 - Change replica_id from str to int +- Issue 6028 - vlv index keys inconsistencies (#6031) +- Issue 5989 - RFE support of inChain Matching Rule (#5990) +- Issue 6022 - lmdb inconsistency between vlv index and vlv cache names (#6026) +- Issue 6015 - Fix typo remeber (#6014) +- Issue 6016 - Pin upload/download artifacts action to v3 +- Issue 5939 - During an update, if the target entry is reverted in the entry cache, the server should not retry to lock it (#6007) +- Issue 4673 - Update Rust crates +- Issue 6004 - idletimeout may be ignored (#6005) +- Issue 5954 - Disable Transparent Huge Pages +- Issue 5997 - test_inactivty_and_expiration CI testcase is wrong (#5999) +- Issue 5993 - Fix several race condition around CI tests (#5996) +- Issue 5944 - Reversion of the entry cache should be limited to BETXN plugin failures (#5994) +- Bump openssl from 0.10.55 to 0.10.60 in /src (#5995) +- Issue 5980 - Improve instance startup failure handling (#5991) +- Issue 5976 - Fix freeipa install regression with lmdb (#5977) +- Issue 5984 - Crash when paged result search are abandoned - fix2 (#5987) +- Issue 5984 - Crash when paged result search are abandoned (#5985) +- Issue 5947 - CI test_vlv_recreation_reindex fails on LMDB (#5979) + * Mon Jan 29 2024 Fedora Release Engineering - 2.4.5-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild diff --git a/sources b/sources index 6604548..2e0aefb 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (389-ds-base-2.4.5.tar.bz2) = 452c2194bdbe6c4c87409469e33de6d134f3a839f329f67cd5e7d92bbc635c7914f76acc85bcdd8e68427234c1c5b00cee83b7f83f293f9df0666dca3dd38375 SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 +SHA512 (389-ds-base-3.0.1.tar.bz2) = 56b9df51e1753f77659c417b90c6aa452e6066b91623e3e5a70955d263c40bb6d7541cc86e93e27eb7a6430f6e0edd75c15970126b989f448a37299369a2dbe2 From 1e6b70d7c11c88198742a1301a306e3463d20077 Mon Sep 17 00:00:00 2001 From: Pete Walter Date: Wed, 31 Jan 2024 19:11:29 +0000 Subject: [PATCH 078/125] Rebuild for ICU 74 --- 389-ds-base.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 9279244..062d701 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 3.0.1 -Release: 1%{?dist} +Release: 2%{?dist} License: GPL-3.0-or-later AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-DFS-2016 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MPL-2.0 AND PSF-2.0 URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -907,6 +907,9 @@ exit 0 %endif %changelog +* Wed Jan 31 2024 Pete Walter - 3.0.1-2 +- Rebuild for ICU 74 + * Tue Jan 30 2024 Simon Pichugin - 3.0.1-1 - Bump version to 3.0.1 - Issue 6043, 6044 - Enhance Rust and JS bundling and add SPDX licenses for both (#6045) From a78efd2e114bf3a2c6433444a9d4770053349e6e Mon Sep 17 00:00:00 2001 From: James Chapman Date: Mon, 15 Apr 2024 15:18:25 +0100 Subject: [PATCH 079/125] Bump version to 3.0.2 Issue 6082 - Remove explicit dependencies toward libdb - revert default (#6145) Issue 6142 - [RFE] Add LMDB configuration related checks into Healthcheck tool (#6143) Issue 6141 - freeipa test_topology_TestCASpecificRUVs is failing (#6144) Issue 6136 - failure in freeipa tests (#6137) Issue 6119 - Synchronise accept_thread with slapd_daemon (#6120) Issue 6105 - lmdb - Cannot create entries with long rdn (#6130) Issue 6082 - Remove explicit dependencies toward libdb (#6083) Issue i6057 - Fix3 - Fix covscan issues (#6127) Issue 6057 - vlv search may result wrong result with lmdb - Fix 2 (#6121) Issue 6057 - vlv search may result wrong result with lmdb (#6091) Issue 6092 - passwordHistory is not updated with a pre-hashed password (#6093) Issue 6133 - Move slapi_pblock_set_flag_operation_notes() to slapi-plugin.h Issue 6125 - dscreate interactive fails when chosing mdb backend (#6126) Issue 6110 - Typo in Account Policy plugin message Issue 6080 - ns-slapd crash in referint_get_config (#6081) Issue 6117 - Fix the UTC offset print (#6118) Issue 5305 - OpenLDAP version autodetection doesn't work Issue 6112 - RFE - add new operation note for MFA authentications Issue 5842 - Add log buffering to audit log Issue 3527 - Support HAProxy and Instance on the same machine configuration (#6107) Issue 6103 - New connection timeout error breaks errormap (#6104) Issue 6096 - Improve connection timeout error logging (#6097) Issue 6067 - Improve dsidm CLI No Such Entry handling (#6079) Issue 6067 - Add hidden -v and -j options to each CLI subcommand (#6088) Issue 6061 - Certificate lifetime displayed as NaN --- .gitignore | 1 + 389-ds-base.spec | 32 ++++++++++++++++++++++++++++++-- sources | 2 +- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 3a72004..b2c03ac 100644 --- a/.gitignore +++ b/.gitignore @@ -226,3 +226,4 @@ /389-ds-base-2.4.4.tar.bz2 /389-ds-base-2.4.5.tar.bz2 /389-ds-base-3.0.1.tar.bz2 +/389-ds-base-3.0.2.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 062d701..99f2209 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -45,8 +45,8 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 3.0.1 -Release: 2%{?dist} +Version: 3.0.2 +Release: 1%{?dist} License: GPL-3.0-or-later AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-DFS-2016 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MPL-2.0 AND PSF-2.0 URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -907,6 +907,34 @@ exit 0 %endif %changelog +* Mon Apr 15 2024 James Chapman - 3.0.2-1 +- Bump version to 3.0.2 +- Issue 6082 - Remove explicit dependencies toward libdb - revert default (#6145) +- Issue 6142 - [RFE] Add LMDB configuration related checks into Healthcheck tool (#6143) +- Issue 6141 - freeipa test_topology_TestCASpecificRUVs is failing (#6144) +- Issue 6136 - failure in freeipa tests (#6137) +- Issue 6119 - Synchronise accept_thread with slapd_daemon (#6120) +- Issue 6105 - lmdb - Cannot create entries with long rdn (#6130) +- Issue 6082 - Remove explicit dependencies toward libdb (#6083) +- Issue i6057 - Fix3 - Fix covscan issues (#6127) +- Issue 6057 - vlv search may result wrong result with lmdb - Fix 2 (#6121) +- Issue 6057 - vlv search may result wrong result with lmdb (#6091) +- Issue 6092 - passwordHistory is not updated with a pre-hashed password (#6093) +- Issue 6133 - Move slapi_pblock_set_flag_operation_notes() to slapi-plugin.h +- Issue 6125 - dscreate interactive fails when chosing mdb backend (#6126) +- Issue 6110 - Typo in Account Policy plugin message +- Issue 6080 - ns-slapd crash in referint_get_config (#6081) +- Issue 6117 - Fix the UTC offset print (#6118) +- Issue 5305 - OpenLDAP version autodetection doesn't work +- Issue 6112 - RFE - add new operation note for MFA authentications +- Issue 5842 - Add log buffering to audit log +- Issue 3527 - Support HAProxy and Instance on the same machine configuration (#6107) +- Issue 6103 - New connection timeout error breaks errormap (#6104) +- Issue 6096 - Improve connection timeout error logging (#6097) +- Issue 6067 - Improve dsidm CLI No Such Entry handling (#6079) +- Issue 6067 - Add hidden -v and -j options to each CLI subcommand (#6088) +- Issue 6061 - Certificate lifetime displayed as NaN + * Wed Jan 31 2024 Pete Walter - 3.0.1-2 - Rebuild for ICU 74 diff --git a/sources b/sources index 2e0aefb..73be96d 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 -SHA512 (389-ds-base-3.0.1.tar.bz2) = 56b9df51e1753f77659c417b90c6aa452e6066b91623e3e5a70955d263c40bb6d7541cc86e93e27eb7a6430f6e0edd75c15970126b989f448a37299369a2dbe2 +SHA512 (389-ds-base-3.0.2.tar.bz2) = e17ebc39a256848b6f7e601be3df7dafa38b1148f9b4112824f242839ad6bd9f0472dfb5518b1868ceb3b24a48f232ab3099f3176d31713281ec1f926bdacf88 From d4e20edc5712434e7bbf30bb2e5c62e0162c390e Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Wed, 24 Apr 2024 14:23:54 +0200 Subject: [PATCH 080/125] Enable CI gating --- .fmf/version | 1 + gating.yaml | 15 +++++++++++++++ main.fmf | 17 +++++++++++++++++ tests/tests.yml | 26 -------------------------- 4 files changed, 33 insertions(+), 26 deletions(-) create mode 100644 .fmf/version create mode 100644 gating.yaml create mode 100644 main.fmf delete mode 100644 tests/tests.yml diff --git a/.fmf/version b/.fmf/version new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/gating.yaml b/gating.yaml new file mode 100644 index 0000000..323fbd6 --- /dev/null +++ b/gating.yaml @@ -0,0 +1,15 @@ +--- !Policy +product_versions: + - fedora-* +decision_contexts: [bodhi_update_push_testing] +subject_type: koji_build +rules: + - !PassingTestCaseRule {test_case_name: fedora-ci.koji-build.tier0.functional} + +--- !Policy +product_versions: + - fedora-* +decision_contexts: [bodhi_update_push_stable] +subject_type: koji_build +rules: + - !PassingTestCaseRule {test_case_name: fedora-ci.koji-build.tier0.functional} diff --git a/main.fmf b/main.fmf new file mode 100644 index 0000000..76d16bf --- /dev/null +++ b/main.fmf @@ -0,0 +1,17 @@ +/plan: + summary: Basic test suite + discover: + how: fmf + execute: + how: tmt + prepare: + - name: install required packages + how: install + package: [389-ds-base, git, pytest] + - name: clone repo + how: shell + script: git clone https://github.com/389ds/389-ds-base /root/ds +/test: + /upstream_basic: + test: pytest -v /root/ds/dirsrvtests/tests/suites/basic/basic_test.py + duration: 30m diff --git a/tests/tests.yml b/tests/tests.yml deleted file mode 100644 index 1878c82..0000000 --- a/tests/tests.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- -- hosts: localhost - remote_user: root - vars: - ds_repo_url: https://github.com/389ds/389-ds-base.git - ds_repo_dir: ds - ds_tests: "{{ ds_repo_dir }}/dirsrvtests/tests" - pytest: py.test-3 - pytest_args: "-v --continue-on-collection-errors" - pytest_tests: "suites/basic" - artifacts: ./artifacts - roles: - - role: standard-test-basic - tags: - - classic - repositories: - - repo: "{{ ds_repo_url }}" - dest: "{{ ds_repo_dir }}" - tests: - - basic: - dir: "{{ ds_tests }}" - run: "{{ pytest }} {{ pytest_args }} {{ pytest_tests }}" - required_packages: - - python3-pytest - - 389-ds-base - - 389-ds-base-snmp From 51c0d48236e001270cfb0fddc9826fa4054280c1 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Wed, 24 Apr 2024 14:25:10 +0200 Subject: [PATCH 081/125] Drop unused patch --- concread-use-2018-edition.patch | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 concread-use-2018-edition.patch diff --git a/concread-use-2018-edition.patch b/concread-use-2018-edition.patch deleted file mode 100644 index c09bf22..0000000 --- a/concread-use-2018-edition.patch +++ /dev/null @@ -1,19 +0,0 @@ -diff '--color=auto' -Nur 389-ds-base-2.0.13.orig/vendor/concread/.cargo-checksum.json 389-ds-base-2.0.13/vendor/concread/.cargo-checksum.json ---- 389-ds-base-2.0.13.orig/vendor/concread/.cargo-checksum.json 2022-01-25 14:30:32.886759088 +0100 -+++ 389-ds-base-2.0.13/vendor/concread/.cargo-checksum.json 2022-01-25 14:30:59.144053695 +0100 -@@ -1 +1 @@ --{"files":{"CACHE.md":"258e585db81ee9582e1f7e7246026b49b3f617dae4459ec52437024b00ba5dff","CODE_OF_CONDUCT.md":"f32933e0090f012d336e8b2f2301967e8a27cbc896aa3860811a944d05b58964","CONTRIBUTORS.md":"1edff6e840fc50412ac698cd7e5ebe660574760b492d4febe94feb0c066b062f","Cargo.toml":"088f1aa3051cfc8b7861c3eed146e9a5d936e68edaaa85d04054475a8d24224e","LICENSE.md":"32ee9dbf6196874fc9d406c54a888a6c4cbb9aa4a7f35b46befeaff43a78fe85","Makefile":"de35f7df990b5c047785da63ad560ecadac746bf19d2ab8457fc2ba0224ad46a","README.md":"f70aafccb01764a1aa4d83e3f7fbeab245f7bfa3d3bafecea9614439ff97b487","asan_test.sh":"7355f359e34a6198e895c18fbb616fa45a44666c0a82787f704454e83687be4c","benches/arccache.rs":"6f1f23abb2b577c21aa7ee3d4bd7413fcb49a60d59b1220e1afaeda99f4e6b0e","benches/hashmap_benchmark.rs":"306d085f88f7ce40b8709aff37375482f8edb3c891cbb3da5d9d70a95c2d6cca","src/arcache/ll.rs":"2bd7eb2e73f80112765a0e1792edc27b58269dfc419498ef02ad68fb63141abc","src/arcache/mod.rs":"5911e162123373e241a6bf2b6355cda5480f9ff2f3fa2901c08a7010ad82c00a","src/arcache/traits.rs":"09ea380ea38efe3e35c2036a2ae233388a5367706d155c4aa3c9234d03eef8ea","src/bptree/asynch.rs":"69eff00e05b7b85a12468304374422b2ce1d8598b50918b0efe6eb77036249a4","src/bptree/impl.rs":"b54a7d53e23bf0ff23ebd43ea7ab19708cc383766706051f207bfb62f5e64793","src/bptree/mod.rs":"5e8d2004865dd2064a550070ca3b49a1975ac877cd6749f035806335f3a393a1","src/cowcell/asynch.rs":"04a1c424c083625f92524547bd21d20aadec4d20e2eedfff4db90f2aef920d6c","src/cowcell/mod.rs":"621c243c301f80ebcf65a636489c9450e22940bc5bc9cfb1e5db7943f4e3543f","src/ebrcell/mod.rs":"cf2a2042ac41039ca5fb4212f1fec58bfa1695b88f9c7f7864e01dafa84ccf35","src/hashmap/asynch.rs":"f8418906a23cf06e73fb1330988da4ab0f53ae58c4d5fd58ab5105f8fcbcc414","src/hashmap/impl.rs":"9695dcfde2fd6b27766adddd225d6390a44cc757ebf9b2f5879f6f1b9a7f29dc","src/hashmap/mod.rs":"bbd33d7f50a28b9a1254d4aaed72f5122e9f01e68e0c43331f90582a17056657","src/internals/bptree/cursor.rs":"83b250db73eb09e1cf7367e8c33700e9b9659695fd565e813549b7f20f9ba777","src/internals/bptree/iter.rs":"dfcf50a3ff5b052dc719b2c68b0bafcfdd0c0c8d8173f3e227a7dd6c8f1be773","src/internals/bptree/macros.rs":"568826a43238474d1f92f7dbf1671690790b35a3b8c88d0d6c5dd35aca54857a","src/internals/bptree/mod.rs":"67ba38e16d96c0d239b72cf0b7be5f27a7a82a29e3a31afc5477175f92b4c57f","src/internals/bptree/node.rs":"afe7217f187d5d7a086dab3bc6fadbae0456e4f8518aa12153f877590380d585","src/internals/bptree/states.rs":"da1ce34cbe6bc449e9e5172ed1fd2a296f2ac197b17ca855f2d40aada7d32a63","src/internals/hashmap/cursor.rs":"7d9c47d7e31e984670cd2161be54475dc468df5b00df26dc89f9848eb1a587ea","src/internals/hashmap/iter.rs":"f02f372e34d2af685eebbcc4db71cc5985c904c1bbd14dd13f48921ea58e5c5f","src/internals/hashmap/macros.rs":"f1236cd794e0e8d7ee2e89428b60c1c3437f34e6be32217de2d61dddce7c6b90","src/internals/hashmap/mod.rs":"ffa693b755ef92da14b001e08a1154e263bd9540ae993d4f79ddf5979e2dcbd6","src/internals/hashmap/node.rs":"7d86f28969185f28de91b2c816990f231adb2c5985c4cbf0efcfdd07ae94ef9a","src/internals/hashmap/simd.rs":"4ef1fd5a0b6218823eafd727b7ff1a738dfc0c59d1e3afbb2ace8f0513967bf3","src/internals/hashmap/states.rs":"9366f29bdfaeb3ee9744268b5b2283209f791a260045312e8489515f8bd3900a","src/internals/lincowcell/mod.rs":"9caa826c9b6758e79d90c10c5dad4bfeaf46a8773784537750814f700fa13428","src/internals/lincowcell_async/mod.rs":"c38ec2efbd02219ebec68aa0b31e824262941093d1cfb3e441e6c98b375df6ab","src/internals/mod.rs":"18db9c4cb457fd06a85d668a69bd290ad13a7fae971a926015daf148424e19cc","src/lib.rs":"ce9ba3daaa0f8e9ee2e61a61e8134cf4d241522ca30909d6933f37075bd3e549","src/threadcache/mod.rs":"43328459ade4c1abb8174ded0f77f264a3931dbae82991e70765747d519882c6","src/unsound.rs":"60ed0cad28434083fe7cccd17af4995381cdd9e4dfb685da5b14e802150074fb","src/unsound2.rs":"02b72de153d9f5fac901ea59a9ef3d1ce9b8e3e18bc80d9d19b2d6aa8c7b5022","src/unsound3.rs":"019ba913656558f91e9a160cbc05fe78b1e4a44acc1bb74d38281ebea71edd77","src/utils.rs":"d07e962bab8936d5396bc7542af7ce2812504358c4e68dd2322f521c066476cd","static/arc_1.png":"94ff0d24a15d5feda27f0316f8a1ca82291f816d8705b1d0743e03e39791bbe2","static/arc_2.png":"9932b1b8e7f44a833f4ffdb710af984199711d6c9c3349a51ab122a22d0ebbe7","static/cow_1.png":"f340e6d143589efdbbfb8c62c4fdddc97dcb213e0cff2c04f7f93bf380fd36f3","static/cow_2.png":"20f550b67109cd042170da95ff6faecda043d333c55f48ec19ced8bb9dce1eee","static/cow_3.png":"137a24e70196bd628522733b55ed1d92cf3f9936be39d9f0864201424a25bd88","static/cow_arc_1.png":"97a45ad9b55721381aff07e921fedc863209629a4ae4f8c160cad7059ecad795","static/cow_arc_2.png":"178e681ba6e2e0a33a7b6a08b9895b628dad74cda56e9e25b59288376e9f01ce","static/cow_arc_3.png":"37dac32e173b14faf37b502a110ab1e4f47f30710cfc65714b9fef0b79f64307","static/cow_arc_4.png":"f4b962b9ccd9b765523f50b752b9bb85525cbf8a4e6cdc15048f9363579e6719","static/cow_arc_5.png":"d6b122ec844d0d19312cc57667769f2955bc7b8667449b1c13a7359a4debc8a2","static/cow_arc_6.png":"847018f7f5e0813b26c2b636a2ca8549f475339de24a21dd2e0e21d90dbd77f1","static/cow_arc_7.png":"3df9b3d1153c7b1de52a30a46e9bdba75e2412ad51ef158437a356f16b3bd1be","static/cow_arc_8.png":"68f405191ef400b8f854102e98fac92ddd31c274bcff7739e47483a39dba9612","static/cow_arc_9.png":"eb60637be4fb951ac54a1e3de0fd33e0bb2f5a4d19c3519bd8f23c02b8fc240d"},"package":"dcc9816f5ac93ebd51c37f7f9a6bf2b40dfcd42978ad2aea5d542016e9244cf6"} -\ No newline at end of file -+{"files":{"CACHE.md":"258e585db81ee9582e1f7e7246026b49b3f617dae4459ec52437024b00ba5dff","CODE_OF_CONDUCT.md":"f32933e0090f012d336e8b2f2301967e8a27cbc896aa3860811a944d05b58964","CONTRIBUTORS.md":"1edff6e840fc50412ac698cd7e5ebe660574760b492d4febe94feb0c066b062f","Cargo.toml":"188257f3b5f5cba5f526fd3647ce8c5a4c75a70dc95fbedf665a2cf2755aee6d","LICENSE.md":"32ee9dbf6196874fc9d406c54a888a6c4cbb9aa4a7f35b46befeaff43a78fe85","Makefile":"de35f7df990b5c047785da63ad560ecadac746bf19d2ab8457fc2ba0224ad46a","README.md":"f70aafccb01764a1aa4d83e3f7fbeab245f7bfa3d3bafecea9614439ff97b487","asan_test.sh":"7355f359e34a6198e895c18fbb616fa45a44666c0a82787f704454e83687be4c","benches/arccache.rs":"6f1f23abb2b577c21aa7ee3d4bd7413fcb49a60d59b1220e1afaeda99f4e6b0e","benches/hashmap_benchmark.rs":"306d085f88f7ce40b8709aff37375482f8edb3c891cbb3da5d9d70a95c2d6cca","src/arcache/ll.rs":"2bd7eb2e73f80112765a0e1792edc27b58269dfc419498ef02ad68fb63141abc","src/arcache/mod.rs":"5911e162123373e241a6bf2b6355cda5480f9ff2f3fa2901c08a7010ad82c00a","src/arcache/traits.rs":"09ea380ea38efe3e35c2036a2ae233388a5367706d155c4aa3c9234d03eef8ea","src/bptree/asynch.rs":"69eff00e05b7b85a12468304374422b2ce1d8598b50918b0efe6eb77036249a4","src/bptree/impl.rs":"b54a7d53e23bf0ff23ebd43ea7ab19708cc383766706051f207bfb62f5e64793","src/bptree/mod.rs":"5e8d2004865dd2064a550070ca3b49a1975ac877cd6749f035806335f3a393a1","src/cowcell/asynch.rs":"04a1c424c083625f92524547bd21d20aadec4d20e2eedfff4db90f2aef920d6c","src/cowcell/mod.rs":"621c243c301f80ebcf65a636489c9450e22940bc5bc9cfb1e5db7943f4e3543f","src/ebrcell/mod.rs":"cf2a2042ac41039ca5fb4212f1fec58bfa1695b88f9c7f7864e01dafa84ccf35","src/hashmap/asynch.rs":"f8418906a23cf06e73fb1330988da4ab0f53ae58c4d5fd58ab5105f8fcbcc414","src/hashmap/impl.rs":"9695dcfde2fd6b27766adddd225d6390a44cc757ebf9b2f5879f6f1b9a7f29dc","src/hashmap/mod.rs":"bbd33d7f50a28b9a1254d4aaed72f5122e9f01e68e0c43331f90582a17056657","src/internals/bptree/cursor.rs":"83b250db73eb09e1cf7367e8c33700e9b9659695fd565e813549b7f20f9ba777","src/internals/bptree/iter.rs":"dfcf50a3ff5b052dc719b2c68b0bafcfdd0c0c8d8173f3e227a7dd6c8f1be773","src/internals/bptree/macros.rs":"568826a43238474d1f92f7dbf1671690790b35a3b8c88d0d6c5dd35aca54857a","src/internals/bptree/mod.rs":"67ba38e16d96c0d239b72cf0b7be5f27a7a82a29e3a31afc5477175f92b4c57f","src/internals/bptree/node.rs":"afe7217f187d5d7a086dab3bc6fadbae0456e4f8518aa12153f877590380d585","src/internals/bptree/states.rs":"da1ce34cbe6bc449e9e5172ed1fd2a296f2ac197b17ca855f2d40aada7d32a63","src/internals/hashmap/cursor.rs":"7d9c47d7e31e984670cd2161be54475dc468df5b00df26dc89f9848eb1a587ea","src/internals/hashmap/iter.rs":"f02f372e34d2af685eebbcc4db71cc5985c904c1bbd14dd13f48921ea58e5c5f","src/internals/hashmap/macros.rs":"f1236cd794e0e8d7ee2e89428b60c1c3437f34e6be32217de2d61dddce7c6b90","src/internals/hashmap/mod.rs":"ffa693b755ef92da14b001e08a1154e263bd9540ae993d4f79ddf5979e2dcbd6","src/internals/hashmap/node.rs":"7d86f28969185f28de91b2c816990f231adb2c5985c4cbf0efcfdd07ae94ef9a","src/internals/hashmap/simd.rs":"4ef1fd5a0b6218823eafd727b7ff1a738dfc0c59d1e3afbb2ace8f0513967bf3","src/internals/hashmap/states.rs":"9366f29bdfaeb3ee9744268b5b2283209f791a260045312e8489515f8bd3900a","src/internals/lincowcell/mod.rs":"9caa826c9b6758e79d90c10c5dad4bfeaf46a8773784537750814f700fa13428","src/internals/lincowcell_async/mod.rs":"c38ec2efbd02219ebec68aa0b31e824262941093d1cfb3e441e6c98b375df6ab","src/internals/mod.rs":"18db9c4cb457fd06a85d668a69bd290ad13a7fae971a926015daf148424e19cc","src/lib.rs":"ce9ba3daaa0f8e9ee2e61a61e8134cf4d241522ca30909d6933f37075bd3e549","src/threadcache/mod.rs":"43328459ade4c1abb8174ded0f77f264a3931dbae82991e70765747d519882c6","src/unsound.rs":"60ed0cad28434083fe7cccd17af4995381cdd9e4dfb685da5b14e802150074fb","src/unsound2.rs":"02b72de153d9f5fac901ea59a9ef3d1ce9b8e3e18bc80d9d19b2d6aa8c7b5022","src/unsound3.rs":"019ba913656558f91e9a160cbc05fe78b1e4a44acc1bb74d38281ebea71edd77","src/utils.rs":"d07e962bab8936d5396bc7542af7ce2812504358c4e68dd2322f521c066476cd","static/arc_1.png":"94ff0d24a15d5feda27f0316f8a1ca82291f816d8705b1d0743e03e39791bbe2","static/arc_2.png":"9932b1b8e7f44a833f4ffdb710af984199711d6c9c3349a51ab122a22d0ebbe7","static/cow_1.png":"f340e6d143589efdbbfb8c62c4fdddc97dcb213e0cff2c04f7f93bf380fd36f3","static/cow_2.png":"20f550b67109cd042170da95ff6faecda043d333c55f48ec19ced8bb9dce1eee","static/cow_3.png":"137a24e70196bd628522733b55ed1d92cf3f9936be39d9f0864201424a25bd88","static/cow_arc_1.png":"97a45ad9b55721381aff07e921fedc863209629a4ae4f8c160cad7059ecad795","static/cow_arc_2.png":"178e681ba6e2e0a33a7b6a08b9895b628dad74cda56e9e25b59288376e9f01ce","static/cow_arc_3.png":"37dac32e173b14faf37b502a110ab1e4f47f30710cfc65714b9fef0b79f64307","static/cow_arc_4.png":"f4b962b9ccd9b765523f50b752b9bb85525cbf8a4e6cdc15048f9363579e6719","static/cow_arc_5.png":"d6b122ec844d0d19312cc57667769f2955bc7b8667449b1c13a7359a4debc8a2","static/cow_arc_6.png":"847018f7f5e0813b26c2b636a2ca8549f475339de24a21dd2e0e21d90dbd77f1","static/cow_arc_7.png":"3df9b3d1153c7b1de52a30a46e9bdba75e2412ad51ef158437a356f16b3bd1be","static/cow_arc_8.png":"68f405191ef400b8f854102e98fac92ddd31c274bcff7739e47483a39dba9612","static/cow_arc_9.png":"eb60637be4fb951ac54a1e3de0fd33e0bb2f5a4d19c3519bd8f23c02b8fc240d"},"package":"dcc9816f5ac93ebd51c37f7f9a6bf2b40dfcd42978ad2aea5d542016e9244cf6"} -diff '--color=auto' -Nur 389-ds-base-2.0.13.orig/vendor/concread/Cargo.toml 389-ds-base-2.0.13/vendor/concread/Cargo.toml ---- 389-ds-base-2.0.13.orig/vendor/concread/Cargo.toml 2022-01-25 14:30:32.883759169 +0100 -+++ 389-ds-base-2.0.13/vendor/concread/Cargo.toml 2022-01-25 14:30:44.786439411 +0100 -@@ -10,7 +10,7 @@ - # See Cargo.toml.orig for the original contents. - - [package] --edition = "2021" -+edition = "2018" - name = "concread" - version = "0.2.21" - authors = ["William Brown "] From e6aa4026011a6bc85f267e7cba08414f776ec2b0 Mon Sep 17 00:00:00 2001 From: James Chapman Date: Wed, 15 May 2024 12:25:05 +0100 Subject: [PATCH 082/125] Bump version to 3.1.0 Issue 6142 - Fix CI tests (#6161) Issue 6157 - Cockipt crashes when getting replication status if topology contains an old 389ds version (#6158) Issue 5105 - lmdb - Cannot create entries with long rdn - fix covscan (#6131) Issue 6086 - Ambiguous warning about SELinux in dscreate for non-root user Issue 6094 - Add coverity scan workflow Issue 5962 - Rearrange includes for 32-bit support logic Issue 6046 - Make dscreate to work during kickstart installations Issue 6073 - Improve error log when running out of memory (#6084) Issue 6071 - Instance creation/removal is slow Issue 6010 - 389 ds ignores nsslapd-maxdescriptors (#6027) Issue 6075 - Ignore build artifacts (#6076) Issue 6068 - Add dscontainer stop function --- .gitignore | 1 + 389-ds-base.spec | 106 +++++++++++++++++++++++++++-------------------- sources | 2 +- 3 files changed, 63 insertions(+), 46 deletions(-) diff --git a/.gitignore b/.gitignore index b2c03ac..ead6bde 100644 --- a/.gitignore +++ b/.gitignore @@ -227,3 +227,4 @@ /389-ds-base-2.4.5.tar.bz2 /389-ds-base-3.0.1.tar.bz2 /389-ds-base-3.0.2.tar.bz2 +/389-ds-base-3.1.0.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 99f2209..5b8ca96 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -45,9 +45,9 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base -Version: 3.0.2 +Version: 3.1.0 Release: 1%{?dist} -License: GPL-3.0-or-later AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-DFS-2016 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MPL-2.0 AND PSF-2.0 +License: GPL-3.0-or-later AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-DFS-2016 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0 URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 Conflicts: freeipa-server < 4.0.3 @@ -59,80 +59,80 @@ Provides: ldif2ldbm >= 0 ##### Bundled cargo crates list - START ##### Provides: bundled(crate(addr2line)) = 0.21.0 Provides: bundled(crate(adler)) = 1.0.2 -Provides: bundled(crate(ahash)) = 0.7.7 +Provides: bundled(crate(ahash)) = 0.7.8 Provides: bundled(crate(atty)) = 0.2.14 -Provides: bundled(crate(autocfg)) = 1.1.0 -Provides: bundled(crate(backtrace)) = 0.3.69 +Provides: bundled(crate(autocfg)) = 1.3.0 +Provides: bundled(crate(backtrace)) = 0.3.71 Provides: bundled(crate(base64)) = 0.13.1 -Provides: bundled(crate(bitflags)) = 2.4.2 +Provides: bundled(crate(bitflags)) = 2.5.0 Provides: bundled(crate(byteorder)) = 1.5.0 Provides: bundled(crate(cbindgen)) = 0.26.0 -Provides: bundled(crate(cc)) = 1.0.83 +Provides: bundled(crate(cc)) = 1.0.97 Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 3.2.25 Provides: bundled(crate(clap_lex)) = 0.2.4 Provides: bundled(crate(concread)) = 0.2.21 Provides: bundled(crate(crossbeam)) = 0.8.4 -Provides: bundled(crate(crossbeam-channel)) = 0.5.11 +Provides: bundled(crate(crossbeam-channel)) = 0.5.12 Provides: bundled(crate(crossbeam-deque)) = 0.8.5 Provides: bundled(crate(crossbeam-epoch)) = 0.9.18 Provides: bundled(crate(crossbeam-queue)) = 0.3.11 Provides: bundled(crate(crossbeam-utils)) = 0.8.19 -Provides: bundled(crate(errno)) = 0.3.8 -Provides: bundled(crate(fastrand)) = 2.0.1 +Provides: bundled(crate(errno)) = 0.3.9 +Provides: bundled(crate(fastrand)) = 2.1.0 Provides: bundled(crate(fernet)) = 0.1.4 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 -Provides: bundled(crate(getrandom)) = 0.2.12 +Provides: bundled(crate(getrandom)) = 0.2.15 Provides: bundled(crate(gimli)) = 0.28.1 Provides: bundled(crate(hashbrown)) = 0.12.3 Provides: bundled(crate(heck)) = 0.4.1 Provides: bundled(crate(hermit-abi)) = 0.1.19 Provides: bundled(crate(indexmap)) = 1.9.3 Provides: bundled(crate(instant)) = 0.1.12 -Provides: bundled(crate(itoa)) = 1.0.10 -Provides: bundled(crate(jobserver)) = 0.1.27 -Provides: bundled(crate(libc)) = 0.2.152 +Provides: bundled(crate(itoa)) = 1.0.11 +Provides: bundled(crate(jobserver)) = 0.1.31 +Provides: bundled(crate(libc)) = 0.2.154 Provides: bundled(crate(linux-raw-sys)) = 0.4.13 -Provides: bundled(crate(lock_api)) = 0.4.11 -Provides: bundled(crate(log)) = 0.4.20 +Provides: bundled(crate(lock_api)) = 0.4.12 +Provides: bundled(crate(log)) = 0.4.21 Provides: bundled(crate(lru)) = 0.7.8 -Provides: bundled(crate(memchr)) = 2.7.1 -Provides: bundled(crate(miniz_oxide)) = 0.7.1 +Provides: bundled(crate(memchr)) = 2.7.2 +Provides: bundled(crate(miniz_oxide)) = 0.7.2 Provides: bundled(crate(object)) = 0.32.2 Provides: bundled(crate(once_cell)) = 1.19.0 -Provides: bundled(crate(openssl)) = 0.10.63 +Provides: bundled(crate(openssl)) = 0.10.64 Provides: bundled(crate(openssl-macros)) = 0.1.1 -Provides: bundled(crate(openssl-sys)) = 0.9.99 +Provides: bundled(crate(openssl-sys)) = 0.9.102 Provides: bundled(crate(os_str_bytes)) = 6.6.1 Provides: bundled(crate(parking_lot)) = 0.11.2 Provides: bundled(crate(parking_lot_core)) = 0.8.6 Provides: bundled(crate(paste)) = 0.1.18 Provides: bundled(crate(paste-impl)) = 0.1.18 -Provides: bundled(crate(pin-project-lite)) = 0.2.13 -Provides: bundled(crate(pkg-config)) = 0.3.29 +Provides: bundled(crate(pin-project-lite)) = 0.2.14 +Provides: bundled(crate(pkg-config)) = 0.3.30 Provides: bundled(crate(ppv-lite86)) = 0.2.17 Provides: bundled(crate(proc-macro-hack)) = 0.5.20+deprecated -Provides: bundled(crate(proc-macro2)) = 1.0.78 -Provides: bundled(crate(quote)) = 1.0.35 +Provides: bundled(crate(proc-macro2)) = 1.0.82 +Provides: bundled(crate(quote)) = 1.0.36 Provides: bundled(crate(rand)) = 0.8.5 Provides: bundled(crate(rand_chacha)) = 0.3.1 Provides: bundled(crate(rand_core)) = 0.6.4 -Provides: bundled(crate(redox_syscall)) = 0.4.1 -Provides: bundled(crate(rustc-demangle)) = 0.1.23 -Provides: bundled(crate(rustix)) = 0.38.30 -Provides: bundled(crate(ryu)) = 1.0.16 +Provides: bundled(crate(redox_syscall)) = 0.2.16 +Provides: bundled(crate(rustc-demangle)) = 0.1.24 +Provides: bundled(crate(rustix)) = 0.38.34 +Provides: bundled(crate(ryu)) = 1.0.18 Provides: bundled(crate(scopeguard)) = 1.2.0 -Provides: bundled(crate(serde)) = 1.0.196 -Provides: bundled(crate(serde_derive)) = 1.0.196 -Provides: bundled(crate(serde_json)) = 1.0.113 -Provides: bundled(crate(smallvec)) = 1.13.1 +Provides: bundled(crate(serde)) = 1.0.202 +Provides: bundled(crate(serde_derive)) = 1.0.202 +Provides: bundled(crate(serde_json)) = 1.0.117 +Provides: bundled(crate(smallvec)) = 1.13.2 Provides: bundled(crate(strsim)) = 0.10.0 -Provides: bundled(crate(syn)) = 2.0.48 -Provides: bundled(crate(tempfile)) = 3.9.0 +Provides: bundled(crate(syn)) = 2.0.63 +Provides: bundled(crate(tempfile)) = 3.10.1 Provides: bundled(crate(termcolor)) = 1.4.1 -Provides: bundled(crate(textwrap)) = 0.16.0 -Provides: bundled(crate(tokio)) = 1.35.1 +Provides: bundled(crate(textwrap)) = 0.16.1 +Provides: bundled(crate(tokio)) = 1.37.0 Provides: bundled(crate(tokio-macros)) = 2.2.0 Provides: bundled(crate(toml)) = 0.5.11 Provides: bundled(crate(unicode-ident)) = 1.0.12 @@ -142,17 +142,18 @@ Provides: bundled(crate(version_check)) = 0.9.4 Provides: bundled(crate(wasi)) = 0.11.0+wasi_snapshot_preview1 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 -Provides: bundled(crate(winapi-util)) = 0.1.6 +Provides: bundled(crate(winapi-util)) = 0.1.8 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(windows-sys)) = 0.52.0 -Provides: bundled(crate(windows-targets)) = 0.52.0 -Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.52.0 -Provides: bundled(crate(windows_aarch64_msvc)) = 0.52.0 -Provides: bundled(crate(windows_i686_gnu)) = 0.52.0 -Provides: bundled(crate(windows_i686_msvc)) = 0.52.0 -Provides: bundled(crate(windows_x86_64_gnu)) = 0.52.0 -Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.52.0 -Provides: bundled(crate(windows_x86_64_msvc)) = 0.52.0 +Provides: bundled(crate(windows-targets)) = 0.52.5 +Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.52.5 +Provides: bundled(crate(windows_aarch64_msvc)) = 0.52.5 +Provides: bundled(crate(windows_i686_gnu)) = 0.52.5 +Provides: bundled(crate(windows_i686_gnullvm)) = 0.52.5 +Provides: bundled(crate(windows_i686_msvc)) = 0.52.5 +Provides: bundled(crate(windows_x86_64_gnu)) = 0.52.5 +Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.52.5 +Provides: bundled(crate(windows_x86_64_msvc)) = 0.52.5 Provides: bundled(crate(zeroize)) = 1.7.0 Provides: bundled(crate(zeroize_derive)) = 1.4.2 Provides: bundled(npm(@aashutoshrathi/word-wrap)) = 1.2.6 @@ -907,6 +908,21 @@ exit 0 %endif %changelog +* Tue May 14 2024 James Chapman - 3.1.0-1 +- Bump version to 3.1.0 +- Issue 6142 - Fix CI tests (#6161) +- Issue 6157 - Cockipt crashes when getting replication status if topology contains an old 389ds version (#6158) +- Issue 5105 - lmdb - Cannot create entries with long rdn - fix covscan (#6131) +- Issue 6086 - Ambiguous warning about SELinux in dscreate for non-root user +- Issue 6094 - Add coverity scan workflow +- Issue 5962 - Rearrange includes for 32-bit support logic +- Issue 6046 - Make dscreate to work during kickstart installations +- Issue 6073 - Improve error log when running out of memory (#6084) +- Issue 6071 - Instance creation/removal is slow +- Issue 6010 - 389 ds ignores nsslapd-maxdescriptors (#6027) +- Issue 6075 - Ignore build artifacts (#6076) +- Issue 6068 - Add dscontainer stop function + * Mon Apr 15 2024 James Chapman - 3.0.2-1 - Bump version to 3.0.2 - Issue 6082 - Remove explicit dependencies toward libdb - revert default (#6145) diff --git a/sources b/sources index 73be96d..42ac5f4 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 -SHA512 (389-ds-base-3.0.2.tar.bz2) = e17ebc39a256848b6f7e601be3df7dafa38b1148f9b4112824f242839ad6bd9f0472dfb5518b1868ceb3b24a48f232ab3099f3176d31713281ec1f926bdacf88 +SHA512 (389-ds-base-3.1.0.tar.bz2) = 7b471328ae9efe451d30d0f61bdf207dbce0b8094685132390196d45bda5e3cba29e025ce18e51cee9d8b84f685024208d38a2407e2d3c685bc5d8dfcb86d4ea From b308bcac8dcc50186d7426374f785af75302c0f3 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Fri, 31 May 2024 21:47:30 +0200 Subject: [PATCH 083/125] Convert to %autorelease and %autochangelog [skip changelog] --- 389-ds-base.spec | 517 +---------------------------------------------- changelog | 513 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 515 insertions(+), 515 deletions(-) create mode 100644 changelog diff --git a/389-ds-base.spec b/389-ds-base.spec index 5b8ca96..3093205 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -46,7 +46,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 3.1.0 -Release: 1%{?dist} +Release: %autorelease License: GPL-3.0-or-later AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-DFS-2016 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0 URL: https://www.port389.org Conflicts: selinux-policy-base < 3.9.8 @@ -908,517 +908,4 @@ exit 0 %endif %changelog -* Tue May 14 2024 James Chapman - 3.1.0-1 -- Bump version to 3.1.0 -- Issue 6142 - Fix CI tests (#6161) -- Issue 6157 - Cockipt crashes when getting replication status if topology contains an old 389ds version (#6158) -- Issue 5105 - lmdb - Cannot create entries with long rdn - fix covscan (#6131) -- Issue 6086 - Ambiguous warning about SELinux in dscreate for non-root user -- Issue 6094 - Add coverity scan workflow -- Issue 5962 - Rearrange includes for 32-bit support logic -- Issue 6046 - Make dscreate to work during kickstart installations -- Issue 6073 - Improve error log when running out of memory (#6084) -- Issue 6071 - Instance creation/removal is slow -- Issue 6010 - 389 ds ignores nsslapd-maxdescriptors (#6027) -- Issue 6075 - Ignore build artifacts (#6076) -- Issue 6068 - Add dscontainer stop function - -* Mon Apr 15 2024 James Chapman - 3.0.2-1 -- Bump version to 3.0.2 -- Issue 6082 - Remove explicit dependencies toward libdb - revert default (#6145) -- Issue 6142 - [RFE] Add LMDB configuration related checks into Healthcheck tool (#6143) -- Issue 6141 - freeipa test_topology_TestCASpecificRUVs is failing (#6144) -- Issue 6136 - failure in freeipa tests (#6137) -- Issue 6119 - Synchronise accept_thread with slapd_daemon (#6120) -- Issue 6105 - lmdb - Cannot create entries with long rdn (#6130) -- Issue 6082 - Remove explicit dependencies toward libdb (#6083) -- Issue i6057 - Fix3 - Fix covscan issues (#6127) -- Issue 6057 - vlv search may result wrong result with lmdb - Fix 2 (#6121) -- Issue 6057 - vlv search may result wrong result with lmdb (#6091) -- Issue 6092 - passwordHistory is not updated with a pre-hashed password (#6093) -- Issue 6133 - Move slapi_pblock_set_flag_operation_notes() to slapi-plugin.h -- Issue 6125 - dscreate interactive fails when chosing mdb backend (#6126) -- Issue 6110 - Typo in Account Policy plugin message -- Issue 6080 - ns-slapd crash in referint_get_config (#6081) -- Issue 6117 - Fix the UTC offset print (#6118) -- Issue 5305 - OpenLDAP version autodetection doesn't work -- Issue 6112 - RFE - add new operation note for MFA authentications -- Issue 5842 - Add log buffering to audit log -- Issue 3527 - Support HAProxy and Instance on the same machine configuration (#6107) -- Issue 6103 - New connection timeout error breaks errormap (#6104) -- Issue 6096 - Improve connection timeout error logging (#6097) -- Issue 6067 - Improve dsidm CLI No Such Entry handling (#6079) -- Issue 6067 - Add hidden -v and -j options to each CLI subcommand (#6088) -- Issue 6061 - Certificate lifetime displayed as NaN - -* Wed Jan 31 2024 Pete Walter - 3.0.1-2 -- Rebuild for ICU 74 - -* Tue Jan 30 2024 Simon Pichugin - 3.0.1-1 -- Bump version to 3.0.1 -- Issue 6043, 6044 - Enhance Rust and JS bundling and add SPDX licenses for both (#6045) -- Issue 3555 - Remove audit-ci from dependencies (#6056) -- Issue 6052 - Paged results test sets hostname to `localhost` on test collection -- Issue 6051 - Drop unused pytest markers -- Issue 6049 - lmdb - changelog is wrongly recreated by reindex task (#6050) -- Issue 6047 - Add a check for tagged commits -- Issue 6041 - dscreate ds-root - accepts relative path (#6042) -- Switch default backend to lmdb and bump version to 3.0 (#6013) -- Issue 6032 - Replication broken after backup restore (#6035) -- Issue 6037 - Server crash at startup in vlvIndex_delete (#6038) -- Issue 6034 - Change replica_id from str to int -- Issue 6028 - vlv index keys inconsistencies (#6031) -- Issue 5989 - RFE support of inChain Matching Rule (#5990) -- Issue 6022 - lmdb inconsistency between vlv index and vlv cache names (#6026) -- Issue 6015 - Fix typo remeber (#6014) -- Issue 6016 - Pin upload/download artifacts action to v3 -- Issue 5939 - During an update, if the target entry is reverted in the entry cache, the server should not retry to lock it (#6007) -- Issue 4673 - Update Rust crates -- Issue 6004 - idletimeout may be ignored (#6005) -- Issue 5954 - Disable Transparent Huge Pages -- Issue 5997 - test_inactivty_and_expiration CI testcase is wrong (#5999) -- Issue 5993 - Fix several race condition around CI tests (#5996) -- Issue 5944 - Reversion of the entry cache should be limited to BETXN plugin failures (#5994) -- Bump openssl from 0.10.55 to 0.10.60 in /src (#5995) -- Issue 5980 - Improve instance startup failure handling (#5991) -- Issue 5976 - Fix freeipa install regression with lmdb (#5977) -- Issue 5984 - Crash when paged result search are abandoned - fix2 (#5987) -- Issue 5984 - Crash when paged result search are abandoned (#5985) -- Issue 5947 - CI test_vlv_recreation_reindex fails on LMDB (#5979) - -* Mon Jan 29 2024 Fedora Release Engineering - 2.4.5-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild - -* Mon Jan 22 2024 Fedora Release Engineering - 2.4.5-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild - -* Fri Jan 19 2024 Fedora Release Engineering - 2.4.5-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild - -* Thu Jan 18 2024 Fedora Release Engineering - 2.4.5-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild - -* Thu Jan 18 2024 Viktor Ashirov - 2.4.5-1 -- Bump version to 2.4.5 -- Issue 5989 - RFE support of inChain Matching Rule (#5990) -- Issue 5939 - During an update, if the target entry is reverted in the entry cache, the server should not retry to lock it (#6007) -- Issue 5944 - Reversion of the entry cache should be limited to BETXN plugin failures (#5994) -- Issue 5954 - Disable Transparent Huge Pages -- Issue 5984 - Crash when paged result search are abandoned - fix2 (#5987) -- Issue 5984 - Crash when paged result search are abandoned (#5985) - -* Wed Nov 15 2023 James Chapman - 2.4.4 -- Bump version to 2.4.4 -- Issue 5971 - CLI - Fix password prompt for repl status (#5972) -- Issue 5973 - Fix fedora cop RawHide builds (#5974) -- Revert "Issue 5761 - Worker thread dynamic management (#5796)" (#5970) -- Issue 5966 - CLI - Custom schema object is removed on a failed edit (#5967) -- Issue 5786 - Update permissions for Release workflow -- Issue 5960 - Subpackages should have more strict interdependencies -- Issue 3555 - UI - Fix audit issue with npm - babel/traverse (#5959) -- Issue 4843 - Fix dscreate create-template issue (#5950) -- bugfix for --passwd-file not working on latest version (#5934) -- Issue 5843 - dsconf / dscreate should be able to handle lmdb parameters (#5943) -- Bump postcss from 8.4.24 to 8.4.31 in /src/cockpit/389-console (#5945) -- Issue 5938 - Attribute Names changed to lowercase after adding the Attributes (#5940) -- issue 5924 - ASAN server build crash when looping opening/closing connections (#5926) -- Issue 1925 - Add a CI test (#5936) -- Issue 5732 - Localizing Cockpit's 389ds Plugin using CockpitPoPlugin (#5764) -- Issue 1870 - Add a CI test (#5929) -- Issue 843 - Add a warning to slapi_valueset_add_value_ext (#5925) -- Issue 5761 - Worker thread dynamic management (#5796) -- Issue 1802 - Improve ldclt man page (#5928) -- Issue 1456 - Add a CI test that verifies there is no issue (#5927) -- Issue 1317 - Add a CI test (#5923) -- Issue 1081 - CI - Add more tests for overwriting x-origin issue (#5815) -- Issue 1115 - Add a CI test (#5913) -- Issue 5848 - Fix condition and add a CI test (#5916) -- Issue 5848 - Fix condition and add a CI test (#5916) -- Issue 5914 - UI - server settings page validation improvements and db index fixes -- Issue 5909 - Multi listener hang with 20k connections (#5917) -- Issue 5902 - Fix previous commit regression (#5919) -- pass instance correctly to ds_is_older (#5903) -- Issue 5909 - Multi listener hang with 20k connections (#5910) -- Issue 5722 - improve testcase (#5904) -- Issue 5203 - outdated version in provided metadata for lib389 -- Bug Description: -- issue 5890 part 2 - Need a tester for testing multiple listening thread feature (#5897) -- Issue i5846 - Crash when lmdb import is aborted (#5881) -- Issue 5894 - lmdb import error fails with Could not store the entry (#5895) -- Issue 5890 - Need a tester for testing multiple listening thread feature (#5891) -- Issue 5082 - slugify: ModuleNotFoundError when running test cases -- Issue 4551 - Part 2 - Fix build warning of previous PR (#5888) -- Issue 5834 - AccountPolicyPlugin erroring for some users (#5866) -- Issue 5872 - part 2 - fix is_dbi regression (#5887) -- Issue 4758 - Add tests for WebUI -- Issue 5848 - dsconf should prevent setting the replicaID for hub and consumer roles (#5849) -- Issue 5883 - Remove connection mutex contention risk on autobind (#5886) -- Issue 5872 - `dbscan()` in lib389 can return bytes - -* Thu Aug 3 2023 Mark Reynolds - 2.4.3-1 -- Bump version to 2.4.3-1 -- Issue 5729 - Memory leak in factory_create_extension (#5814) -- Issue 5870 - ns-slapd crashes at startup if a backend has no suffix (#5871) -- Issue 5876 - CI Test random failure - Import (#5879) -- Issue 5877 - test_basic_ldapagent breaks test_setup_ds_as_non_root* tests -- Issue 5867 - lib389 should use filter for tarfile as recommended by PEP 706 (#5868) -- Issue 5853 - Update Cargo.lock and fix minor warning (#5854) -- Issue 5785 - CLI - arg completion is broken -- Issue 5864 - Server fails to start after reboot because it's unable to access nsslapd-rundir -- Issue 5856 - SyntaxWarning: invalid escape sequence '\,' -- Issue 5859 - dbscan fails with AttributeError: 'list' object has no attribute 'extends' -- Issue 3527 - UI - Add nsslapd-haproxy-trusted-ip to server setting (#5839) -- Issue 4551 - Paged search impacts performance (#5838) -- Issue 4758 - Add tests for WebUI -- Issue 4169 - UI - Fix retrochangelog and schema Typeaheads (#5837) -- issue 5833 - dsconf monitor backend fails on lmdb (#5835) -- Issue 3555 - UI - Fix audit issue with npm - stylelint (#5836) - -* Mon Jul 24 2023 Mark Reynolds - 2.4.2-5 -- Bump version to 2.4.2-5 -- Add the bash completion scripts to the appropriate files section - -* Wed Jul 19 2023 Fedora Release Engineering - 2.4.2-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild - -* Tue Jul 11 2023 František Zatloukal - 2.4.2-3 -- Rebuilt for ICU 73.2 - -* Mon Jul 10 2023 Mark Reynolds - 2.4.2-2 -- Bump version to 2.4.2-2 -- Issue 5752 - RFE - Provide a history for LastLoginTime (#5807) -= Issue 4719 - CI - Add dsconf add a PTA URL test - -* Fri Jul 7 2023 Mark Reynolds - 2.4.2-1 -- Bump version to 2.4.2 -- Issue 5793 - UI - fix suffix selection in export modal -- Issue 5793 - UI - Fix minor crashes (#5827) -- Issue 5825 - healthcheck - password storage scheme warning needs more info -- Issue 5822 - Allow empty export path for db2ldif -- Issue 5755 - Massive memory leaking on update operations (#5824) -- Issue 5701 - CI - Add more tests for referral mode fix (#5810) -- Issue 5551 - Almost empty and not loaded ns-slapd high cpu load -- Issue 5755 - The Massive memory leaking on update operations (#5803) -- Issue 2375 - CLI - Healthcheck - revise and add new checks -- Bump openssl from 0.10.52 to 0.10.55 in /src -- Issue 5793 - UI - movce from webpack to esbuild bundler -- Issue 5752 - CI - Add more tests for lastLoginHistorySize RFE (#5802) -- Issue 3527 - Fix HAProxy x390x compatibility and compiler warnings (#5801) -- Issue 5798 - CLI - Add multi-valued support to dsconf config (#5799) -- Issue 5781 - Bug handling return code of pre-extended operation plugin. -- Issue 5785 - move bash completion to post section of specfile -- Issue 5156 - (cont) RFE slapi_memberof reusing memberof values (#5744) -- Issue 4758 - Add tests for WebUI -- Issue 3527 - Add PROXY protocol support (#5762) -- Issue 5789 - Improve ds-replcheck error handling -- Issue 5786 - CLI - registers tools for bash completion -- Issue 5786 - Set minimal permissions on GitHub Workflows (#5787) -- Issue 5646 - Various memory leaks (#5725) -- Issue 5778 - UI - Remove error message if .dsrc is missing -- Issue 5751 - Cleanallruv task crashes on consumer (#5775) - -* Wed Jun 28 2023 Python Maint - 2.4.1-2 -- Rebuilt for Python 3.12 - -* Thu May 18 2023 Mark Reynolds - 2.4.1-1 -- Bump version to 2.4.1 -- Issue 5770 - RFE - Extend Password Adminstrators to allow skipping password info updates -- Issue 5768 - CLI/UI - cert checks are too strict, and other issues -- Issue 5722 - fix compilation warnings (#5771) -- Issue 5765 - Improve installer selinux handling -- Issue 152 - RFE - Add support for LDAP alias entries -- Issue 5052 - BUG - Custom filters prevented entry deletion (#5060) -- Issue 5752 - RFE - Provide a history for LastLoginTime (#5753) -- Issue 5722 - RFE When a filter contains 'nsrole', improve response time by rewriting the filter (#5723) -- Issue 5704 - crash in sync_refresh_initial_content (#5720) -- Issue 5738 - RFE - UI - Read/write replication monitor info to .dsrc file -- Issue 5156 - build warnings (#5758) -- Issue 5749 - RFE - Allow Account Policy Plugin to handle inactivity and expiration at the same time -- Issue 5743 - Disabling replica crashes the server (#5746) -- Issue 2562 - Copy config files into backup directory -- Issue 5156 - fix build breakage from slapi-memberof commit -- Issue 4758 - Add tests for WebUI - -* Tue Apr 25 2023 Mark Reynolds - 2.4.0-1 -- Bump version to 2.4.0 -- Issue 5156 - RFE that implement slapi_memberof (#5694) -- Issue 5734 - RFE - Exclude pwdFailureTime and ContextCSN (#5735) -- Issue 5726 - ns-slapd crashing in ldbm_back_upgradednformat (#5727) -- Issue 4758 - Add tests for WebUI -- Issue 5718 - Memory leak in connection table (#5719) -- Issue 5705 - Add config parameter to close client conns on failed bind (#5712) -- Issue 4758 - Add tests for WebUI -- Issue 5643 - Memory leak in entryrdn during delete (#5717) -- Issue 5714 - UI - fix typo, db settings, log settings, and LDAP editor paginations -- Issue 5701 - CLI - Fix referral mode setting (#5708) -- Bump openssl from 0.10.45 to 0.10.48 in /src (#5709) -- Issue 5710 - subtree search statistics for index lookup does not report ancestorid/entryrdn lookups (#5711) -- Issue 5697 - Obsolete nsslapd-ldapimaprootdn attribute (#5698) -- Issue 1081 - Stop schema replication from overwriting x-origin -- Issue 4812 - Listener thread does not scale with a high num of established connections (#5706) -- Issue 4812 - Listener thread does not scale with a high num of established connections (#5681) -- Bump webpack from 5.75.0 to 5.76.0 in /src/cockpit/389-console (#5699) -- Issue 5598 - (3rd) In 2.x, SRCH throughput drops by 10% because of handling of referral (#5692) -- Issue 5598 - (2nd) In 2.x, SRCH throughput drops by 10% because of handling of referral (#5691) -- Issue 5687 - UI - sensitive information disclosure -- Issue 5661 - LMDB hangs while Rebuilding the replication changelog RUV (#5676) -- Issue 5554 - Add more tests to security_basic_test suite -- Issue 4583 - Update specfile to skip checks of ASAN builds -- Issue 4758 - Add tests for WebUI -- Issue 3604 - UI - Add support for Subject Alternative Names in CSR -- Issue 5600 - buffer overflow when enabling sync repl plugin when dynamic plugins is enabled -- Issue 5640 - Update logconv for new logging format -- Issue 5162 - CI - fix error message for invalid pem file -- Issue 5598 - In 2.x, SRCH throughput drops by 10% because of handling of referral (#5604) -- Issue 5671 - covscan - clang warning (#5672) -- Issue 5267 - CI - Fix issues with nsslapd-return-original-entrydn -- Issue 5666 - CLI - Add timeout parameter for tasks -- Issue 5567 - CLI - make ldifgen use the same default ldif name for all options -- Issue 5647 - Fix unused variable warning from previous commit (#5670) -- Issue 5162 - Lib389 - verify certificate type before adding -- Issue 5642 - Build fails against setuptools 67.0.0 -- Issue 5630 - CLI - need to add logging filter for stdout -- Issue 5646 - CLI/UI - do not hardcode password storage schemes -- Issue 5640 - Update logconv for new logging format -- issue 5647 - covscan: memory leak in audit log when adding entries (#5650) -- Issue 5658 - CLI - unable to add attribute with matching rule -- Issue 5653 - covscan - fix invalid dereference -- Issue 5652 - Libasan crash in replication/cascading_test (#5659) -- Issue 5628 - Handle graceful timeout in CI tests (#5657) -- Issue 5648 - Covscan - Compiler warnings (#5651) -- Issue 5630 - CLI - error messages should goto stderr -- Issue 2435 - RFE - Raise IDL Scan Limit to INT_MAX (#5639) -- Issue 5632 - CLI - improve error handling with db2ldif -- Issue 5517 - Replication conflict CI test sometime fails (#5518) -- Issue 5634 - Deprecated warning related to github action workflow code (#5635) -- Issue 5637 - Covscan - fix Buffer Overflows (#5638) -- Issue 5624 - RFE - UI - export certificates, and import text base64 encoded certificates -- Bump tokio from 1.24.1 to 1.25.0 in /src (#5629) -- Issue 4577 - Add LMDB pytest github action (#5627) -- Issue 4293 - RFE - CLI - add dsrc options for setting user and group subtrees -- Remove stale libevent(-devel) dependency -- Issue 5578 - dscreate ds-root does not normaile paths (#5613) -- Issue 5497 - boolean attributes should be case insensitive - -* Fri Mar 31 2023 Viktor Ashirov - 2.3.2-3 -- Fix build issue against setuptools 67.0.0 (#2183375) - -* Tue Feb 28 2023 Simon Pichugin - 2.3.2-2 -- Use systemd-sysusers for dirsrv user and group (#2173834) - -* Mon Jan 23 2023 Mark Reynolds - 2.3.2-1 -- Bump version to 2.3.2 -- Issue 5547 - automember plugin improvements -- Issue 5607, 5351, 5611 - UI/CLI - fix various issues -- Issue 5610 - Build failure on Debian -- Issue 5608 - UI - need to replace some "const" with "let" -- Issue 5560 - dscreate run by non superuser set defaults requiring superuser privilege (#5579) -- Issue 3604 - Create a private key/CSR with dsconf/Cockpit (#5584) -- Issue 5605 - Adding a slapi_log_backtrace function in libslapd (#5606) -- Issue 5602 - UI - browser crash when trying to modify read-only variable -- Issue 5581 - UI - Support cockpit dark theme -- Issue 5593 - CLI - dsidm account subtree-status fails with TypeError -- Issue 5591 - BUG - Segfault in cl5configtrim with invalid confi (#5592) -- Fix latest npm audit failures -- Issue 5599 - CI - webui tests randomly fail -- Issue 5348 - RFE - CLI - add functionality to do bulk updates to entries -- Issue 5588 - Fix CI tests -- Issue 5585 - lib389 password policy DN handling is incorrect (#5587) -- Issue 5521 - UI - Update plugins for new split PAM and LDAP pass thru auth -- Bump json5 from 2.2.1 to 2.2.3 in /src/cockpit/389-console -- Issue 5236 - UI add specialized group edit modal -- Issue 5550 - dsconf monitor crashes with Error math domain error (#5553) -- Issue 5278 - CLI - dsidm asks for the old password on password reset -- Issue 5531 - CI - use universal_lines in capture_output -- Issue 5425 - CLI - add confirmation arg when deleting backend -- Issue 5558 - non-root instance fails to start on creation (#5559) -- Issue 5545 - A random crash in import over lmdb (#5546) -- Issue 3615 - CLI - prevent virtual attribute indexing -- Update specfile and rust crates -- Issue 5413 - Allow mutliple MemberOf fixup tasks with different bases/filters -- Issue 5554 - Add more tests to security_basic_test suite (#5555) -- Issue 5561 - Nightly tests are failing -- Issue 5521 - RFE - split pass through auth cli -- Issue 5521 - BUG - Pam PTA multiple issues -- Issue 5544 - Increase default task TTL -- Issue 5526 - RFE - Improve saslauthd migration options (#5528) -- Issue 5539 - Make logger's parameter name unified (#5540) -- Issue 5541 - Fix typo in `lib389.cli_conf.backend._get_backend` (#5542) -- Issue 3729 - (cont) RFE Extend log of operations statistics in access log (#5538) -- Issue 5534 - Fix a rebase typo (#5537) -- Issue 5534 - Add copyright text to the repository files - -* Wed Jan 18 2023 Fedora Release Engineering - 2.3.1-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild - -* Sat Dec 31 2022 Pete Walter - 2.3.1-2 -- Rebuild for ICU 72 - -* Fri Nov 18 2022 Mark Reynolds - 2.3.1-1 -- Bump version to 2.3.1 -- Issue 5532 - Make db compaction TOD day more robust. -- Issue 3729 - RFE Extend log of operations statistics in access log (#5508) -- Issue 5529 - UI - Fix npm vulnerability in loader-utils -- Issue 5490 - tombstone in entryrdn index with lmdb but not with bdb (#5498) -- Issue 5162 - Fix dsctl tls ca-certfiicate add-cert arg requirement -- Issue 5510 - remove twalk_r dependency to build on RHEL8 (#5516) -- Issue 5162 - RFE - CLI allow adding CA certificate bundles -- Issue 5440 - memberof is slow on update/fixup if there are several 'groupattr' (#5455) -- Issue 5512 - BUG - skip pwdPolicyChecker OC in migration (#5513) -- Issue 3555 - UI - fix audit issue with npm loader-utils (#5514) -- Issue 5505 - Fix compiler warning (#5506) -- Issue 5469 - Increase the default value of nsslapd-conntablesize (#5472) -- Issue 5408 - lmdb import is slow (#5481) -- Issue 5429 - healthcheck - add checks for MemberOf group attrs being indexed -- Issue 5502 - RFE - Add option to display entry attributes in audit log -- Issue 5495 - BUG - Minor fix to dds skip, inconsistent attrs caused errors (#5501) -- Issue 5367 - RFE - store full DN in database record -- Issue 5495 - RFE - skip dds during migration. (#5496) -- Issue 5491 - UI - Add rework and finish jpegPhoto functionality (#5492) -- Issue 5368 - Retro Changelog trimming does not work (#5486) -- Issue 5487 - Fix various issues with logconv.pl -- Issue 5476 - RFE - add memberUid read aci by default (#5477) -- Issue 5482 - lib389 - Can not enable replication with a mixed case suffix -- Issue 5478 - Random crash in connection code during server shutdown (#5479) -- Issue 3061 - RFE - Add password policy debug log level -- Issue 5302 - Release tarballs don't contain cockpit webapp -- Issue 5262 - high contention in find_entry_internal_dn on mixed load (#5264) -- Issue 4324 - Revert recursive pthread mutex change (#5463) -- Issue 5462 - RFE - add missing default indexes (#5464) -- Issue 5465 - Fix dbscan linking (#5466) -- Issue 5271 - Serialization of pam_passthrough causing high etimes (#5272) -- Issue 5453 - UI/CLI - Changing Root DN breaks UI -- Issue 5446 - Fix some covscan issues (#5451) -- Issue 4308 - checking if an entry is a referral is expensive -- Issue 5447 - UI - add NDN max cache size to UI -- Issue 5443 - UI - disable save button while saving -- Issue 5413 - Allow only one MemberOf fixup task at a time -- Issue 4592 - dscreate error with custom dir_path (#5434) -- Issue 5158 - entryuuid fixup tasks fails in replicated topology (#5439) - -* Tue Sep 20 2022 Mark Reynolds - 2.3.0-2 -- Bump version to 2.3.0-2 -- Update old pcre-devel requirement to pcre2-devel - -* Thu Sep 1 2022 Mark Reynolds - 2.3.0-1 -- Bump version to 2.3.0 -- Issue 5012 - Migrate pcre to pcre2 - remove match limit -- Issue 5356 - Make Rust non-optional and update default password storage scheme -- Issue 5012 - Migrate pcre to pcre2 -- Issue 5428 - Fix regression with nscpEntryWsi computation -- Fix missing 'not' in description (closes #5423) (#5424) -- Issue 5421 - CI - makes replication/acceptance_test.py::test_modify_entry more robust (#5422) -- Issue 3903 - fix repl keep alive event interval -- Issue 5418 - Sync_repl may crash while managing invalid cookie (#5420) -- Issue 5415 - Hostname when set to localhost causing failures in other tests -- Issue 5412 - lib389 - do not set backend name to lowercase -- Issue 5407 - sync_repl crashes if enabled while dynamic plugin is enabled (#5411) -- Issue 5385 - LMDB - import crash in rdncache_add_elem (#5406) -- Issue 5403 - Memory leak in conntection table mulit list (#5404) -- Issue 3903 - keep alive update event starts too soon -- Issue 5397 - Fix various memory leaks -- Issue 5399 - UI - LDAP Editor is not updated when we switch instances (#5400) -- Issue 3903 - Supplier should do periodic updates -- Issue 5377 - Code cleanup: Fix Covscan invalid reference (#5393) -- Issue 5394 - configure doesn't check for lmdb and json-c -- Issue 5392 - dscreate fails when using alternative ports in the SELinux hi_reserved_port_t label range -- Issue 5386 - BUG - Update sudoers schema to correctly support UTF-8 (#5387) -- Issue 5388 - fix use-after-free and deadcode -- Issue 5383 - UI - Various fixes and RFE's for UI -- Issue 4656 - Remove problematic language from source code -- Issue 5380 - Separate cleanAllRUV code into new file -- Issue 5322 - optime & wtime on rejected connections is not properly set -- Issue 5335 - RFE - Add Security Audit Log -- Issue 5375 - CI - disable TLS hostname checking -- Issue 981 - Managed Entries betxnpreoperation - transaction not aborted on managed entry failure (#5369) -- Issue 5373 - dsidm user get_dn fails with search_ext() argument 1 must be str, not function -- Issue 5371 - Update npm and cargo packages -- Issue 3069 - Support ECDSA private keys for TLS (#5365) -- Issue 5290 - Importing certificate chain files via "import-server-key-cert" no longer works (#5293) - -* Mon Aug 01 2022 Frantisek Zatloukal - 2.2.2-3 -- Rebuilt for ICU 71.1 - -* Wed Jul 20 2022 Fedora Release Engineering - 2.2.2-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild - -* Tue Jul 5 2022 Mark Reynolds - 2.2.2-1 -- Bump version to 2.2.2 -- Issue 5221 - fix covscan (#5359) -- Issue 5294 - Report Portal 5 is not processing an XML file with (#5358) -- Issue 5353 - CLI - dsconf backend export breaks with multiple backends -- Issue 5346 - New connection table fails with ASAN failures (#5350) -- Issue 5345 - BUG - openldap migration fails when ppolicy is active (#5347) -- Issue 5323 - BUG - improve skipping of monitor db (#5340) -- Issue 5329 - Improve replication extended op logging -- Issue 5343 - Various improvements to winsync -- Issue 4932 - CLI - add parser aliases to long arg names -- Issue 5332 - BUG - normalise filter as intended -- Issue 5327 - Validate test metadata -- Issue 4812 - Scalability with high number of connections (#5090) -- Issue 4348 - Add tests for dsidm -- Issue 5333 - 389-ds-base fails to build with Python 3.11 - -* Thu Jun 16 2022 Python Maint - 2.2.1-4 -- Rebuilt for Python 3.11 - -* Wed Jun 15 2022 Mark Reynolds - 2.2.1-3 -- Bump version to 2.2.1-3 -- Issue 5332 - BUG - normalise filter as intended -- Issue 5327 - Validate test metadata -- Issue 4348 - Add tests for dsidm -- Bump crossbeam-utils from 0.8.6 to 0.8.8 in /src -- Issue 5333 - 389-ds-base fails to build with Python 3.11 - -* Mon Jun 13 2022 Python Maint - 2.2.1-2 -- Rebuilt for Python 3.11 - -* Fri Jun 3 2022 Mark Reynolds - 2.2.1-1 -- Bump version to 2.2.1 -- Issue 5323 - BUG - Fix issue in mdb tests with monitor (#5326) -- Issue 5170 - BUG - incorrect behaviour of filter test (#5315) -- Issue 5324 - plugin acceptance test needs hardening -- Issue 5319 - dsctl_tls_test.py fails with openssl-3.x -- Issue 5323 - BUG - migrating database for monitoring interface lead to crash (#5321) -- Issue 5304 - Need a compatibility option about sub suffix handling (#5310) -- Issue 5313 - dbgen test uses deprecated -h HOST and -p PORT options for ldapmodify -- Issue 5311 - Missing Requires for acl in the spec file -- Issue 5305 - OpenLDAP version autodetection doesn't work -- Issue 5307 - VERSION_PREREL is not set correctly in CI builds -- Issue 5302 - Release tarballs don't contain cockpit webapp -- Issue 5170 - RFE - improve filter logging to assist debugging (#5301) -- Issue 5299 - jemalloc 5.3 released -- Issue 5175 - Remove stale zlib-devel dependency declaration (#5173) -- Issue 5294 - Report Portal 5 is not processing test results XML file -- Issue 5170 - BUG - ldapsubentries were incorrectly returned (#5285) -- Issue 5291 - Harden ReplicationManager.wait_for_replication (#5292) -- Issue 379 - RFE - Compress rotated logs (fix linker) -- Issue 379 - RFE - Compress rotated logs -- Issue 5281 - HIGH - basic test does not run -- Issue 5284 - Replication broken after password change (#5286) -- Issue 5279 - dscontainer: TypeError: unsupported operand type(s) for /: 'str' and 'int' -- Issue 5170 - RFE - Filter optimiser (#5171) -- Issue 5276 - CLI - improve task handling -- Issue 5126 - Memory leak in slapi_ldap_get_lderrno (#5153) -- Issue 3 - ansible-ds - Prefix handling fix (#5275) -- Issue 5273 - CLI - add arg completer for instance name -- Issue 2893 - CLI - dscreate - add options for setting up replication -- Issue 4866 - CLI - when enabling replication set changelog trimming by default -- Issue 5241 - UI - Add account locking missing functionality (#5251) -- Issue 5180 - snmp_collator tries to unlock NULL mutex (#5266) -- Issue 4904 - Fix various small issues -- lib389 prerequisite for ansible-ds (#5253) -- Issue 5260 - BUG - OpenLDAP allows multiple names of memberof overlay (#5261) -- Issue 5252 - During DEL, vlv search can erroneously return NULL candidate (#5256) -- Issue 5254 - dscreate create-template regression due to 5a3bdc336 (#5255) -- Issue 5210 - Python undefined names in lib389 -- Issue 5065 - Crash in suite plugins - test_dna_max_value (#5108) -- Issue 5247 - BUG - Missing attributes in samba schema (#5248) -- Issue 5242- Craft message may crash the server (#5243) -- Issue 4775 -plugin entryuuid failing (#5229) -- Issue 5239 - Nightly copr builds are broken -- Issue 5237 - audit-ci: Cannot convert undefined or null to object -- Issue 5234 - UI - rename Users and Groups tab -- Issue 5227 - UI - No way to move back to Get Started step (#5233) -- Issue 5217 - Simplify instance creation and administration by non root user (#5224) - +%autochangelog diff --git a/changelog b/changelog new file mode 100644 index 0000000..4500dfa --- /dev/null +++ b/changelog @@ -0,0 +1,513 @@ +* Tue May 14 2024 James Chapman - 3.1.0-1 +- Bump version to 3.1.0 +- Issue 6142 - Fix CI tests (#6161) +- Issue 6157 - Cockipt crashes when getting replication status if topology contains an old 389ds version (#6158) +- Issue 5105 - lmdb - Cannot create entries with long rdn - fix covscan (#6131) +- Issue 6086 - Ambiguous warning about SELinux in dscreate for non-root user +- Issue 6094 - Add coverity scan workflow +- Issue 5962 - Rearrange includes for 32-bit support logic +- Issue 6046 - Make dscreate to work during kickstart installations +- Issue 6073 - Improve error log when running out of memory (#6084) +- Issue 6071 - Instance creation/removal is slow +- Issue 6010 - 389 ds ignores nsslapd-maxdescriptors (#6027) +- Issue 6075 - Ignore build artifacts (#6076) +- Issue 6068 - Add dscontainer stop function + +* Mon Apr 15 2024 James Chapman - 3.0.2-1 +- Bump version to 3.0.2 +- Issue 6082 - Remove explicit dependencies toward libdb - revert default (#6145) +- Issue 6142 - [RFE] Add LMDB configuration related checks into Healthcheck tool (#6143) +- Issue 6141 - freeipa test_topology_TestCASpecificRUVs is failing (#6144) +- Issue 6136 - failure in freeipa tests (#6137) +- Issue 6119 - Synchronise accept_thread with slapd_daemon (#6120) +- Issue 6105 - lmdb - Cannot create entries with long rdn (#6130) +- Issue 6082 - Remove explicit dependencies toward libdb (#6083) +- Issue i6057 - Fix3 - Fix covscan issues (#6127) +- Issue 6057 - vlv search may result wrong result with lmdb - Fix 2 (#6121) +- Issue 6057 - vlv search may result wrong result with lmdb (#6091) +- Issue 6092 - passwordHistory is not updated with a pre-hashed password (#6093) +- Issue 6133 - Move slapi_pblock_set_flag_operation_notes() to slapi-plugin.h +- Issue 6125 - dscreate interactive fails when chosing mdb backend (#6126) +- Issue 6110 - Typo in Account Policy plugin message +- Issue 6080 - ns-slapd crash in referint_get_config (#6081) +- Issue 6117 - Fix the UTC offset print (#6118) +- Issue 5305 - OpenLDAP version autodetection doesn't work +- Issue 6112 - RFE - add new operation note for MFA authentications +- Issue 5842 - Add log buffering to audit log +- Issue 3527 - Support HAProxy and Instance on the same machine configuration (#6107) +- Issue 6103 - New connection timeout error breaks errormap (#6104) +- Issue 6096 - Improve connection timeout error logging (#6097) +- Issue 6067 - Improve dsidm CLI No Such Entry handling (#6079) +- Issue 6067 - Add hidden -v and -j options to each CLI subcommand (#6088) +- Issue 6061 - Certificate lifetime displayed as NaN + +* Wed Jan 31 2024 Pete Walter - 3.0.1-2 +- Rebuild for ICU 74 + +* Tue Jan 30 2024 Simon Pichugin - 3.0.1-1 +- Bump version to 3.0.1 +- Issue 6043, 6044 - Enhance Rust and JS bundling and add SPDX licenses for both (#6045) +- Issue 3555 - Remove audit-ci from dependencies (#6056) +- Issue 6052 - Paged results test sets hostname to `localhost` on test collection +- Issue 6051 - Drop unused pytest markers +- Issue 6049 - lmdb - changelog is wrongly recreated by reindex task (#6050) +- Issue 6047 - Add a check for tagged commits +- Issue 6041 - dscreate ds-root - accepts relative path (#6042) +- Switch default backend to lmdb and bump version to 3.0 (#6013) +- Issue 6032 - Replication broken after backup restore (#6035) +- Issue 6037 - Server crash at startup in vlvIndex_delete (#6038) +- Issue 6034 - Change replica_id from str to int +- Issue 6028 - vlv index keys inconsistencies (#6031) +- Issue 5989 - RFE support of inChain Matching Rule (#5990) +- Issue 6022 - lmdb inconsistency between vlv index and vlv cache names (#6026) +- Issue 6015 - Fix typo remeber (#6014) +- Issue 6016 - Pin upload/download artifacts action to v3 +- Issue 5939 - During an update, if the target entry is reverted in the entry cache, the server should not retry to lock it (#6007) +- Issue 4673 - Update Rust crates +- Issue 6004 - idletimeout may be ignored (#6005) +- Issue 5954 - Disable Transparent Huge Pages +- Issue 5997 - test_inactivty_and_expiration CI testcase is wrong (#5999) +- Issue 5993 - Fix several race condition around CI tests (#5996) +- Issue 5944 - Reversion of the entry cache should be limited to BETXN plugin failures (#5994) +- Bump openssl from 0.10.55 to 0.10.60 in /src (#5995) +- Issue 5980 - Improve instance startup failure handling (#5991) +- Issue 5976 - Fix freeipa install regression with lmdb (#5977) +- Issue 5984 - Crash when paged result search are abandoned - fix2 (#5987) +- Issue 5984 - Crash when paged result search are abandoned (#5985) +- Issue 5947 - CI test_vlv_recreation_reindex fails on LMDB (#5979) + +* Mon Jan 29 2024 Fedora Release Engineering - 2.4.5-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Mon Jan 22 2024 Fedora Release Engineering - 2.4.5-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Fri Jan 19 2024 Fedora Release Engineering - 2.4.5-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Thu Jan 18 2024 Fedora Release Engineering - 2.4.5-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Thu Jan 18 2024 Viktor Ashirov - 2.4.5-1 +- Bump version to 2.4.5 +- Issue 5989 - RFE support of inChain Matching Rule (#5990) +- Issue 5939 - During an update, if the target entry is reverted in the entry cache, the server should not retry to lock it (#6007) +- Issue 5944 - Reversion of the entry cache should be limited to BETXN plugin failures (#5994) +- Issue 5954 - Disable Transparent Huge Pages +- Issue 5984 - Crash when paged result search are abandoned - fix2 (#5987) +- Issue 5984 - Crash when paged result search are abandoned (#5985) + +* Wed Nov 15 2023 James Chapman - 2.4.4 +- Bump version to 2.4.4 +- Issue 5971 - CLI - Fix password prompt for repl status (#5972) +- Issue 5973 - Fix fedora cop RawHide builds (#5974) +- Revert "Issue 5761 - Worker thread dynamic management (#5796)" (#5970) +- Issue 5966 - CLI - Custom schema object is removed on a failed edit (#5967) +- Issue 5786 - Update permissions for Release workflow +- Issue 5960 - Subpackages should have more strict interdependencies +- Issue 3555 - UI - Fix audit issue with npm - babel/traverse (#5959) +- Issue 4843 - Fix dscreate create-template issue (#5950) +- bugfix for --passwd-file not working on latest version (#5934) +- Issue 5843 - dsconf / dscreate should be able to handle lmdb parameters (#5943) +- Bump postcss from 8.4.24 to 8.4.31 in /src/cockpit/389-console (#5945) +- Issue 5938 - Attribute Names changed to lowercase after adding the Attributes (#5940) +- issue 5924 - ASAN server build crash when looping opening/closing connections (#5926) +- Issue 1925 - Add a CI test (#5936) +- Issue 5732 - Localizing Cockpit's 389ds Plugin using CockpitPoPlugin (#5764) +- Issue 1870 - Add a CI test (#5929) +- Issue 843 - Add a warning to slapi_valueset_add_value_ext (#5925) +- Issue 5761 - Worker thread dynamic management (#5796) +- Issue 1802 - Improve ldclt man page (#5928) +- Issue 1456 - Add a CI test that verifies there is no issue (#5927) +- Issue 1317 - Add a CI test (#5923) +- Issue 1081 - CI - Add more tests for overwriting x-origin issue (#5815) +- Issue 1115 - Add a CI test (#5913) +- Issue 5848 - Fix condition and add a CI test (#5916) +- Issue 5848 - Fix condition and add a CI test (#5916) +- Issue 5914 - UI - server settings page validation improvements and db index fixes +- Issue 5909 - Multi listener hang with 20k connections (#5917) +- Issue 5902 - Fix previous commit regression (#5919) +- pass instance correctly to ds_is_older (#5903) +- Issue 5909 - Multi listener hang with 20k connections (#5910) +- Issue 5722 - improve testcase (#5904) +- Issue 5203 - outdated version in provided metadata for lib389 +- Bug Description: +- issue 5890 part 2 - Need a tester for testing multiple listening thread feature (#5897) +- Issue i5846 - Crash when lmdb import is aborted (#5881) +- Issue 5894 - lmdb import error fails with Could not store the entry (#5895) +- Issue 5890 - Need a tester for testing multiple listening thread feature (#5891) +- Issue 5082 - slugify: ModuleNotFoundError when running test cases +- Issue 4551 - Part 2 - Fix build warning of previous PR (#5888) +- Issue 5834 - AccountPolicyPlugin erroring for some users (#5866) +- Issue 5872 - part 2 - fix is_dbi regression (#5887) +- Issue 4758 - Add tests for WebUI +- Issue 5848 - dsconf should prevent setting the replicaID for hub and consumer roles (#5849) +- Issue 5883 - Remove connection mutex contention risk on autobind (#5886) +- Issue 5872 - `dbscan()` in lib389 can return bytes + +* Thu Aug 3 2023 Mark Reynolds - 2.4.3-1 +- Bump version to 2.4.3-1 +- Issue 5729 - Memory leak in factory_create_extension (#5814) +- Issue 5870 - ns-slapd crashes at startup if a backend has no suffix (#5871) +- Issue 5876 - CI Test random failure - Import (#5879) +- Issue 5877 - test_basic_ldapagent breaks test_setup_ds_as_non_root* tests +- Issue 5867 - lib389 should use filter for tarfile as recommended by PEP 706 (#5868) +- Issue 5853 - Update Cargo.lock and fix minor warning (#5854) +- Issue 5785 - CLI - arg completion is broken +- Issue 5864 - Server fails to start after reboot because it's unable to access nsslapd-rundir +- Issue 5856 - SyntaxWarning: invalid escape sequence '\,' +- Issue 5859 - dbscan fails with AttributeError: 'list' object has no attribute 'extends' +- Issue 3527 - UI - Add nsslapd-haproxy-trusted-ip to server setting (#5839) +- Issue 4551 - Paged search impacts performance (#5838) +- Issue 4758 - Add tests for WebUI +- Issue 4169 - UI - Fix retrochangelog and schema Typeaheads (#5837) +- issue 5833 - dsconf monitor backend fails on lmdb (#5835) +- Issue 3555 - UI - Fix audit issue with npm - stylelint (#5836) + +* Mon Jul 24 2023 Mark Reynolds - 2.4.2-5 +- Bump version to 2.4.2-5 +- Add the bash completion scripts to the appropriate files section + +* Wed Jul 19 2023 Fedora Release Engineering - 2.4.2-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Tue Jul 11 2023 František Zatloukal - 2.4.2-3 +- Rebuilt for ICU 73.2 + +* Mon Jul 10 2023 Mark Reynolds - 2.4.2-2 +- Bump version to 2.4.2-2 +- Issue 5752 - RFE - Provide a history for LastLoginTime (#5807) += Issue 4719 - CI - Add dsconf add a PTA URL test + +* Fri Jul 7 2023 Mark Reynolds - 2.4.2-1 +- Bump version to 2.4.2 +- Issue 5793 - UI - fix suffix selection in export modal +- Issue 5793 - UI - Fix minor crashes (#5827) +- Issue 5825 - healthcheck - password storage scheme warning needs more info +- Issue 5822 - Allow empty export path for db2ldif +- Issue 5755 - Massive memory leaking on update operations (#5824) +- Issue 5701 - CI - Add more tests for referral mode fix (#5810) +- Issue 5551 - Almost empty and not loaded ns-slapd high cpu load +- Issue 5755 - The Massive memory leaking on update operations (#5803) +- Issue 2375 - CLI - Healthcheck - revise and add new checks +- Bump openssl from 0.10.52 to 0.10.55 in /src +- Issue 5793 - UI - movce from webpack to esbuild bundler +- Issue 5752 - CI - Add more tests for lastLoginHistorySize RFE (#5802) +- Issue 3527 - Fix HAProxy x390x compatibility and compiler warnings (#5801) +- Issue 5798 - CLI - Add multi-valued support to dsconf config (#5799) +- Issue 5781 - Bug handling return code of pre-extended operation plugin. +- Issue 5785 - move bash completion to post section of specfile +- Issue 5156 - (cont) RFE slapi_memberof reusing memberof values (#5744) +- Issue 4758 - Add tests for WebUI +- Issue 3527 - Add PROXY protocol support (#5762) +- Issue 5789 - Improve ds-replcheck error handling +- Issue 5786 - CLI - registers tools for bash completion +- Issue 5786 - Set minimal permissions on GitHub Workflows (#5787) +- Issue 5646 - Various memory leaks (#5725) +- Issue 5778 - UI - Remove error message if .dsrc is missing +- Issue 5751 - Cleanallruv task crashes on consumer (#5775) + +* Wed Jun 28 2023 Python Maint - 2.4.1-2 +- Rebuilt for Python 3.12 + +* Thu May 18 2023 Mark Reynolds - 2.4.1-1 +- Bump version to 2.4.1 +- Issue 5770 - RFE - Extend Password Adminstrators to allow skipping password info updates +- Issue 5768 - CLI/UI - cert checks are too strict, and other issues +- Issue 5722 - fix compilation warnings (#5771) +- Issue 5765 - Improve installer selinux handling +- Issue 152 - RFE - Add support for LDAP alias entries +- Issue 5052 - BUG - Custom filters prevented entry deletion (#5060) +- Issue 5752 - RFE - Provide a history for LastLoginTime (#5753) +- Issue 5722 - RFE When a filter contains 'nsrole', improve response time by rewriting the filter (#5723) +- Issue 5704 - crash in sync_refresh_initial_content (#5720) +- Issue 5738 - RFE - UI - Read/write replication monitor info to .dsrc file +- Issue 5156 - build warnings (#5758) +- Issue 5749 - RFE - Allow Account Policy Plugin to handle inactivity and expiration at the same time +- Issue 5743 - Disabling replica crashes the server (#5746) +- Issue 2562 - Copy config files into backup directory +- Issue 5156 - fix build breakage from slapi-memberof commit +- Issue 4758 - Add tests for WebUI + +* Tue Apr 25 2023 Mark Reynolds - 2.4.0-1 +- Bump version to 2.4.0 +- Issue 5156 - RFE that implement slapi_memberof (#5694) +- Issue 5734 - RFE - Exclude pwdFailureTime and ContextCSN (#5735) +- Issue 5726 - ns-slapd crashing in ldbm_back_upgradednformat (#5727) +- Issue 4758 - Add tests for WebUI +- Issue 5718 - Memory leak in connection table (#5719) +- Issue 5705 - Add config parameter to close client conns on failed bind (#5712) +- Issue 4758 - Add tests for WebUI +- Issue 5643 - Memory leak in entryrdn during delete (#5717) +- Issue 5714 - UI - fix typo, db settings, log settings, and LDAP editor paginations +- Issue 5701 - CLI - Fix referral mode setting (#5708) +- Bump openssl from 0.10.45 to 0.10.48 in /src (#5709) +- Issue 5710 - subtree search statistics for index lookup does not report ancestorid/entryrdn lookups (#5711) +- Issue 5697 - Obsolete nsslapd-ldapimaprootdn attribute (#5698) +- Issue 1081 - Stop schema replication from overwriting x-origin +- Issue 4812 - Listener thread does not scale with a high num of established connections (#5706) +- Issue 4812 - Listener thread does not scale with a high num of established connections (#5681) +- Bump webpack from 5.75.0 to 5.76.0 in /src/cockpit/389-console (#5699) +- Issue 5598 - (3rd) In 2.x, SRCH throughput drops by 10% because of handling of referral (#5692) +- Issue 5598 - (2nd) In 2.x, SRCH throughput drops by 10% because of handling of referral (#5691) +- Issue 5687 - UI - sensitive information disclosure +- Issue 5661 - LMDB hangs while Rebuilding the replication changelog RUV (#5676) +- Issue 5554 - Add more tests to security_basic_test suite +- Issue 4583 - Update specfile to skip checks of ASAN builds +- Issue 4758 - Add tests for WebUI +- Issue 3604 - UI - Add support for Subject Alternative Names in CSR +- Issue 5600 - buffer overflow when enabling sync repl plugin when dynamic plugins is enabled +- Issue 5640 - Update logconv for new logging format +- Issue 5162 - CI - fix error message for invalid pem file +- Issue 5598 - In 2.x, SRCH throughput drops by 10% because of handling of referral (#5604) +- Issue 5671 - covscan - clang warning (#5672) +- Issue 5267 - CI - Fix issues with nsslapd-return-original-entrydn +- Issue 5666 - CLI - Add timeout parameter for tasks +- Issue 5567 - CLI - make ldifgen use the same default ldif name for all options +- Issue 5647 - Fix unused variable warning from previous commit (#5670) +- Issue 5162 - Lib389 - verify certificate type before adding +- Issue 5642 - Build fails against setuptools 67.0.0 +- Issue 5630 - CLI - need to add logging filter for stdout +- Issue 5646 - CLI/UI - do not hardcode password storage schemes +- Issue 5640 - Update logconv for new logging format +- issue 5647 - covscan: memory leak in audit log when adding entries (#5650) +- Issue 5658 - CLI - unable to add attribute with matching rule +- Issue 5653 - covscan - fix invalid dereference +- Issue 5652 - Libasan crash in replication/cascading_test (#5659) +- Issue 5628 - Handle graceful timeout in CI tests (#5657) +- Issue 5648 - Covscan - Compiler warnings (#5651) +- Issue 5630 - CLI - error messages should goto stderr +- Issue 2435 - RFE - Raise IDL Scan Limit to INT_MAX (#5639) +- Issue 5632 - CLI - improve error handling with db2ldif +- Issue 5517 - Replication conflict CI test sometime fails (#5518) +- Issue 5634 - Deprecated warning related to github action workflow code (#5635) +- Issue 5637 - Covscan - fix Buffer Overflows (#5638) +- Issue 5624 - RFE - UI - export certificates, and import text base64 encoded certificates +- Bump tokio from 1.24.1 to 1.25.0 in /src (#5629) +- Issue 4577 - Add LMDB pytest github action (#5627) +- Issue 4293 - RFE - CLI - add dsrc options for setting user and group subtrees +- Remove stale libevent(-devel) dependency +- Issue 5578 - dscreate ds-root does not normaile paths (#5613) +- Issue 5497 - boolean attributes should be case insensitive + +* Fri Mar 31 2023 Viktor Ashirov - 2.3.2-3 +- Fix build issue against setuptools 67.0.0 (#2183375) + +* Tue Feb 28 2023 Simon Pichugin - 2.3.2-2 +- Use systemd-sysusers for dirsrv user and group (#2173834) + +* Mon Jan 23 2023 Mark Reynolds - 2.3.2-1 +- Bump version to 2.3.2 +- Issue 5547 - automember plugin improvements +- Issue 5607, 5351, 5611 - UI/CLI - fix various issues +- Issue 5610 - Build failure on Debian +- Issue 5608 - UI - need to replace some "const" with "let" +- Issue 5560 - dscreate run by non superuser set defaults requiring superuser privilege (#5579) +- Issue 3604 - Create a private key/CSR with dsconf/Cockpit (#5584) +- Issue 5605 - Adding a slapi_log_backtrace function in libslapd (#5606) +- Issue 5602 - UI - browser crash when trying to modify read-only variable +- Issue 5581 - UI - Support cockpit dark theme +- Issue 5593 - CLI - dsidm account subtree-status fails with TypeError +- Issue 5591 - BUG - Segfault in cl5configtrim with invalid confi (#5592) +- Fix latest npm audit failures +- Issue 5599 - CI - webui tests randomly fail +- Issue 5348 - RFE - CLI - add functionality to do bulk updates to entries +- Issue 5588 - Fix CI tests +- Issue 5585 - lib389 password policy DN handling is incorrect (#5587) +- Issue 5521 - UI - Update plugins for new split PAM and LDAP pass thru auth +- Bump json5 from 2.2.1 to 2.2.3 in /src/cockpit/389-console +- Issue 5236 - UI add specialized group edit modal +- Issue 5550 - dsconf monitor crashes with Error math domain error (#5553) +- Issue 5278 - CLI - dsidm asks for the old password on password reset +- Issue 5531 - CI - use universal_lines in capture_output +- Issue 5425 - CLI - add confirmation arg when deleting backend +- Issue 5558 - non-root instance fails to start on creation (#5559) +- Issue 5545 - A random crash in import over lmdb (#5546) +- Issue 3615 - CLI - prevent virtual attribute indexing +- Update specfile and rust crates +- Issue 5413 - Allow mutliple MemberOf fixup tasks with different bases/filters +- Issue 5554 - Add more tests to security_basic_test suite (#5555) +- Issue 5561 - Nightly tests are failing +- Issue 5521 - RFE - split pass through auth cli +- Issue 5521 - BUG - Pam PTA multiple issues +- Issue 5544 - Increase default task TTL +- Issue 5526 - RFE - Improve saslauthd migration options (#5528) +- Issue 5539 - Make logger's parameter name unified (#5540) +- Issue 5541 - Fix typo in `lib389.cli_conf.backend._get_backend` (#5542) +- Issue 3729 - (cont) RFE Extend log of operations statistics in access log (#5538) +- Issue 5534 - Fix a rebase typo (#5537) +- Issue 5534 - Add copyright text to the repository files + +* Wed Jan 18 2023 Fedora Release Engineering - 2.3.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Sat Dec 31 2022 Pete Walter - 2.3.1-2 +- Rebuild for ICU 72 + +* Fri Nov 18 2022 Mark Reynolds - 2.3.1-1 +- Bump version to 2.3.1 +- Issue 5532 - Make db compaction TOD day more robust. +- Issue 3729 - RFE Extend log of operations statistics in access log (#5508) +- Issue 5529 - UI - Fix npm vulnerability in loader-utils +- Issue 5490 - tombstone in entryrdn index with lmdb but not with bdb (#5498) +- Issue 5162 - Fix dsctl tls ca-certfiicate add-cert arg requirement +- Issue 5510 - remove twalk_r dependency to build on RHEL8 (#5516) +- Issue 5162 - RFE - CLI allow adding CA certificate bundles +- Issue 5440 - memberof is slow on update/fixup if there are several 'groupattr' (#5455) +- Issue 5512 - BUG - skip pwdPolicyChecker OC in migration (#5513) +- Issue 3555 - UI - fix audit issue with npm loader-utils (#5514) +- Issue 5505 - Fix compiler warning (#5506) +- Issue 5469 - Increase the default value of nsslapd-conntablesize (#5472) +- Issue 5408 - lmdb import is slow (#5481) +- Issue 5429 - healthcheck - add checks for MemberOf group attrs being indexed +- Issue 5502 - RFE - Add option to display entry attributes in audit log +- Issue 5495 - BUG - Minor fix to dds skip, inconsistent attrs caused errors (#5501) +- Issue 5367 - RFE - store full DN in database record +- Issue 5495 - RFE - skip dds during migration. (#5496) +- Issue 5491 - UI - Add rework and finish jpegPhoto functionality (#5492) +- Issue 5368 - Retro Changelog trimming does not work (#5486) +- Issue 5487 - Fix various issues with logconv.pl +- Issue 5476 - RFE - add memberUid read aci by default (#5477) +- Issue 5482 - lib389 - Can not enable replication with a mixed case suffix +- Issue 5478 - Random crash in connection code during server shutdown (#5479) +- Issue 3061 - RFE - Add password policy debug log level +- Issue 5302 - Release tarballs don't contain cockpit webapp +- Issue 5262 - high contention in find_entry_internal_dn on mixed load (#5264) +- Issue 4324 - Revert recursive pthread mutex change (#5463) +- Issue 5462 - RFE - add missing default indexes (#5464) +- Issue 5465 - Fix dbscan linking (#5466) +- Issue 5271 - Serialization of pam_passthrough causing high etimes (#5272) +- Issue 5453 - UI/CLI - Changing Root DN breaks UI +- Issue 5446 - Fix some covscan issues (#5451) +- Issue 4308 - checking if an entry is a referral is expensive +- Issue 5447 - UI - add NDN max cache size to UI +- Issue 5443 - UI - disable save button while saving +- Issue 5413 - Allow only one MemberOf fixup task at a time +- Issue 4592 - dscreate error with custom dir_path (#5434) +- Issue 5158 - entryuuid fixup tasks fails in replicated topology (#5439) + +* Tue Sep 20 2022 Mark Reynolds - 2.3.0-2 +- Bump version to 2.3.0-2 +- Update old pcre-devel requirement to pcre2-devel + +* Thu Sep 1 2022 Mark Reynolds - 2.3.0-1 +- Bump version to 2.3.0 +- Issue 5012 - Migrate pcre to pcre2 - remove match limit +- Issue 5356 - Make Rust non-optional and update default password storage scheme +- Issue 5012 - Migrate pcre to pcre2 +- Issue 5428 - Fix regression with nscpEntryWsi computation +- Fix missing 'not' in description (closes #5423) (#5424) +- Issue 5421 - CI - makes replication/acceptance_test.py::test_modify_entry more robust (#5422) +- Issue 3903 - fix repl keep alive event interval +- Issue 5418 - Sync_repl may crash while managing invalid cookie (#5420) +- Issue 5415 - Hostname when set to localhost causing failures in other tests +- Issue 5412 - lib389 - do not set backend name to lowercase +- Issue 5407 - sync_repl crashes if enabled while dynamic plugin is enabled (#5411) +- Issue 5385 - LMDB - import crash in rdncache_add_elem (#5406) +- Issue 5403 - Memory leak in conntection table mulit list (#5404) +- Issue 3903 - keep alive update event starts too soon +- Issue 5397 - Fix various memory leaks +- Issue 5399 - UI - LDAP Editor is not updated when we switch instances (#5400) +- Issue 3903 - Supplier should do periodic updates +- Issue 5377 - Code cleanup: Fix Covscan invalid reference (#5393) +- Issue 5394 - configure doesn't check for lmdb and json-c +- Issue 5392 - dscreate fails when using alternative ports in the SELinux hi_reserved_port_t label range +- Issue 5386 - BUG - Update sudoers schema to correctly support UTF-8 (#5387) +- Issue 5388 - fix use-after-free and deadcode +- Issue 5383 - UI - Various fixes and RFE's for UI +- Issue 4656 - Remove problematic language from source code +- Issue 5380 - Separate cleanAllRUV code into new file +- Issue 5322 - optime & wtime on rejected connections is not properly set +- Issue 5335 - RFE - Add Security Audit Log +- Issue 5375 - CI - disable TLS hostname checking +- Issue 981 - Managed Entries betxnpreoperation - transaction not aborted on managed entry failure (#5369) +- Issue 5373 - dsidm user get_dn fails with search_ext() argument 1 must be str, not function +- Issue 5371 - Update npm and cargo packages +- Issue 3069 - Support ECDSA private keys for TLS (#5365) +- Issue 5290 - Importing certificate chain files via "import-server-key-cert" no longer works (#5293) + +* Mon Aug 01 2022 Frantisek Zatloukal - 2.2.2-3 +- Rebuilt for ICU 71.1 + +* Wed Jul 20 2022 Fedora Release Engineering - 2.2.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Tue Jul 5 2022 Mark Reynolds - 2.2.2-1 +- Bump version to 2.2.2 +- Issue 5221 - fix covscan (#5359) +- Issue 5294 - Report Portal 5 is not processing an XML file with (#5358) +- Issue 5353 - CLI - dsconf backend export breaks with multiple backends +- Issue 5346 - New connection table fails with ASAN failures (#5350) +- Issue 5345 - BUG - openldap migration fails when ppolicy is active (#5347) +- Issue 5323 - BUG - improve skipping of monitor db (#5340) +- Issue 5329 - Improve replication extended op logging +- Issue 5343 - Various improvements to winsync +- Issue 4932 - CLI - add parser aliases to long arg names +- Issue 5332 - BUG - normalise filter as intended +- Issue 5327 - Validate test metadata +- Issue 4812 - Scalability with high number of connections (#5090) +- Issue 4348 - Add tests for dsidm +- Issue 5333 - 389-ds-base fails to build with Python 3.11 + +* Thu Jun 16 2022 Python Maint - 2.2.1-4 +- Rebuilt for Python 3.11 + +* Wed Jun 15 2022 Mark Reynolds - 2.2.1-3 +- Bump version to 2.2.1-3 +- Issue 5332 - BUG - normalise filter as intended +- Issue 5327 - Validate test metadata +- Issue 4348 - Add tests for dsidm +- Bump crossbeam-utils from 0.8.6 to 0.8.8 in /src +- Issue 5333 - 389-ds-base fails to build with Python 3.11 + +* Mon Jun 13 2022 Python Maint - 2.2.1-2 +- Rebuilt for Python 3.11 + +* Fri Jun 3 2022 Mark Reynolds - 2.2.1-1 +- Bump version to 2.2.1 +- Issue 5323 - BUG - Fix issue in mdb tests with monitor (#5326) +- Issue 5170 - BUG - incorrect behaviour of filter test (#5315) +- Issue 5324 - plugin acceptance test needs hardening +- Issue 5319 - dsctl_tls_test.py fails with openssl-3.x +- Issue 5323 - BUG - migrating database for monitoring interface lead to crash (#5321) +- Issue 5304 - Need a compatibility option about sub suffix handling (#5310) +- Issue 5313 - dbgen test uses deprecated -h HOST and -p PORT options for ldapmodify +- Issue 5311 - Missing Requires for acl in the spec file +- Issue 5305 - OpenLDAP version autodetection doesn't work +- Issue 5307 - VERSION_PREREL is not set correctly in CI builds +- Issue 5302 - Release tarballs don't contain cockpit webapp +- Issue 5170 - RFE - improve filter logging to assist debugging (#5301) +- Issue 5299 - jemalloc 5.3 released +- Issue 5175 - Remove stale zlib-devel dependency declaration (#5173) +- Issue 5294 - Report Portal 5 is not processing test results XML file +- Issue 5170 - BUG - ldapsubentries were incorrectly returned (#5285) +- Issue 5291 - Harden ReplicationManager.wait_for_replication (#5292) +- Issue 379 - RFE - Compress rotated logs (fix linker) +- Issue 379 - RFE - Compress rotated logs +- Issue 5281 - HIGH - basic test does not run +- Issue 5284 - Replication broken after password change (#5286) +- Issue 5279 - dscontainer: TypeError: unsupported operand type(s) for /: 'str' and 'int' +- Issue 5170 - RFE - Filter optimiser (#5171) +- Issue 5276 - CLI - improve task handling +- Issue 5126 - Memory leak in slapi_ldap_get_lderrno (#5153) +- Issue 3 - ansible-ds - Prefix handling fix (#5275) +- Issue 5273 - CLI - add arg completer for instance name +- Issue 2893 - CLI - dscreate - add options for setting up replication +- Issue 4866 - CLI - when enabling replication set changelog trimming by default +- Issue 5241 - UI - Add account locking missing functionality (#5251) +- Issue 5180 - snmp_collator tries to unlock NULL mutex (#5266) +- Issue 4904 - Fix various small issues +- lib389 prerequisite for ansible-ds (#5253) +- Issue 5260 - BUG - OpenLDAP allows multiple names of memberof overlay (#5261) +- Issue 5252 - During DEL, vlv search can erroneously return NULL candidate (#5256) +- Issue 5254 - dscreate create-template regression due to 5a3bdc336 (#5255) +- Issue 5210 - Python undefined names in lib389 +- Issue 5065 - Crash in suite plugins - test_dna_max_value (#5108) +- Issue 5247 - BUG - Missing attributes in samba schema (#5248) +- Issue 5242- Craft message may crash the server (#5243) +- Issue 4775 -plugin entryuuid failing (#5229) +- Issue 5239 - Nightly copr builds are broken +- Issue 5237 - audit-ci: Cannot convert undefined or null to object +- Issue 5234 - UI - rename Users and Groups tab +- Issue 5227 - UI - No way to move back to Get Started step (#5233) +- Issue 5217 - Simplify instance creation and administration by non root user (#5224) From eeb80bdcccf9aca1711cf6c20cc37b9ed79e3b8c Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Fri, 31 May 2024 21:54:21 +0200 Subject: [PATCH 084/125] Sync spec file with the upstream spec file --- 389-ds-base-devel.README | 6 +- 389-ds-base-git-local.sh | 23 --- 389-ds-base-git.sh | 16 -- 389-ds-base.spec | 374 ++++++++++++++++++++++++--------------- 4 files changed, 239 insertions(+), 180 deletions(-) delete mode 100644 389-ds-base-git-local.sh delete mode 100644 389-ds-base-git.sh diff --git a/389-ds-base-devel.README b/389-ds-base-devel.README index 190c874..c411a61 100644 --- a/389-ds-base-devel.README +++ b/389-ds-base-devel.README @@ -1,4 +1,4 @@ -For detailed information on developing plugins for -389 Directory Server visit. +For detailed information on developing plugins for 389 Directory Server visit -http://port389/wiki/Plugins +https://www.port389.org/docs/389ds/design/plugins.html +https://github.com/389ds/389-ds-base/blob/main/src/slapi_r_plugin/README.md diff --git a/389-ds-base-git-local.sh b/389-ds-base-git-local.sh deleted file mode 100644 index bc809cb..0000000 --- a/389-ds-base-git-local.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -DATE=`date +%Y%m%d` -# use a real tag name here -VERSION=1.3.5.14 -PKGNAME=389-ds-base -TAG=${TAG:-$PKGNAME-$VERSION} -#SRCNAME=$PKGNAME-$VERSION-$DATE -SRCNAME=$PKGNAME-$VERSION - -test -d .git || { - echo you must be in the ds git repo to use this - echo bye - exit 1 -} - -if [ -z "$1" ] ; then - dir=. -else - dir="$1" -fi - -git archive --prefix=$SRCNAME/ $TAG | bzip2 > $dir/$SRCNAME.tar.bz2 diff --git a/389-ds-base-git.sh b/389-ds-base-git.sh deleted file mode 100644 index 0043901..0000000 --- a/389-ds-base-git.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -DATE=`date +%Y%m%d` -# use a real tag name here -VERSION=1.3.5.14 -PKGNAME=389-ds-base -TAG=${TAG:-$PKGNAME-$VERSION} -URL="https://git.fedorahosted.org/git/?p=389/ds.git;a=snapshot;h=$TAG;sf=tgz" -SRCNAME=$PKGNAME-$VERSION - -wget -O $SRCNAME.tar.gz "$URL" - -echo convert tgz format to tar.bz2 format - -gunzip $PKGNAME-$VERSION.tar.gz -bzip2 $PKGNAME-$VERSION.tar diff --git a/389-ds-base.spec b/389-ds-base.spec index 3093205..28db828 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -1,30 +1,44 @@ +%global pkgname dirsrv -%global pkgname dirsrv -%global srcname 389-ds-base - -# Exclude i686 bit arches -ExcludeArch: i686 - -# If perl-Socket-2.000 or newer is available, set 0 to use_Socket6. -%global use_Socket6 0 - -%global use_asan 0 -%global bundle_jemalloc 1 -%if %{use_asan} -%global bundle_jemalloc 0 -%endif - -%if %{bundle_jemalloc} +%bcond bundle_jemalloc 1 +%if %{with bundle_jemalloc} %global jemalloc_name jemalloc %global jemalloc_ver 5.3.0 -%global __provides_exclude ^libjemalloc\\.so.*$ +%endif + +%bcond bundle_libdb 0 +%if %{with bundle_libdb} +%global libdb_version 5.3 +%global libdb_base_version db-%{libdb_version}.28 +%global libdb_full_version lib%{libdb_base_version}-59 +%global libdb_bundle_name libdb-%{libdb_version}-389ds.so +%endif + +# This is used in certain builds to help us know if it has extra features. +%global variant base +# This enables a sanitized build. +%bcond asan 0 +%bcond msan 0 +%bcond tsan 0 +%bcond ubsan 0 + +%if %{with asan} || %{with msan} || %{with tsan} || %{with ubsan} +%global variant base-xsan %endif # Use Clang instead of GCC -%global use_clang 0 +%bcond clang 0 +%if %{with msan} +%bcond clang 1 +%endif + +%if %{with clang} +%global toolchain clang +%global _missing_build_ids_terminate_build 0 +%endif # Build cockpit plugin -%global use_cockpit 1 +%bcond cockpit 1 # fedora 15 and later uses tmpfiles.d # otherwise, comment this out @@ -33,9 +47,6 @@ ExcludeArch: i686 # systemd support %global groupname %{pkgname}.target -# set PIE flag -%global _hardened_build 1 - # Filter argparse-manpage from autogenerated package Requires %global __requires_exclude ^python.*argparse-manpage @@ -43,15 +54,12 @@ ExcludeArch: i686 # See bz1986327 %define dirsrv_requires_ge() %(LC_ALL="C" echo '%*' | xargs -r rpm -q --qf 'Requires: %%{name} >= %%{epoch}:%%{version}\\n' | sed -e 's/ (none):/ /' -e 's/ 0:/ /' | grep -v "is not") -Summary: 389 Directory Server (base) +Summary: 389 Directory Server (%{variant}) Name: 389-ds-base Version: 3.1.0 -Release: %autorelease +Release: %{autorelease -n %{?with_asan:-e asan}}%{?dist} License: GPL-3.0-or-later AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-DFS-2016 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0 URL: https://www.port389.org -Conflicts: selinux-policy-base < 3.9.8 -Conflicts: freeipa-server < 4.0.3 -Obsoletes: %{name} <= 1.4.4 Obsoletes: %{name}-legacy-tools < 1.4.4.6 Obsoletes: %{name}-legacy-tools-debuginfo < 1.4.4.6 Provides: ldif2ldbm >= 0 @@ -338,30 +346,43 @@ Provides: bundled(npm(wrappy)) = 1.0.2 Provides: bundled(npm(yocto-queue)) = 0.1.0 ##### Bundled cargo crates list - END ##### - -BuildRequires: nspr-devel >= 4.32 -BuildRequires: nss-devel >= 3.67.0-7 +# Attach the buildrequires to the top level package: +BuildRequires: nspr-devel +BuildRequires: nss-devel >= 3.34 +BuildRequires: openldap-clients BuildRequires: openldap-devel BuildRequires: lmdb-devel -BuildRequires: libdb-devel BuildRequires: cyrus-sasl-devel BuildRequires: icu BuildRequires: libicu-devel BuildRequires: pcre2-devel BuildRequires: cracklib-devel BuildRequires: json-c-devel -%if %{use_clang} +%if %{with clang} BuildRequires: libatomic BuildRequires: clang +BuildRequires: compiler-rt +BuildRequires: lld %else BuildRequires: gcc BuildRequires: gcc-c++ +%if %{with asan} +BuildRequires: libasan %endif +%if %{with tsan} +BuildRequires: libtsan +%endif +%if %{with ubsan} +BuildRequires: libubsan +%endif +%endif +%if %{without bundle_libdb} +BuildRequires: libdb-devel +%endif + # The following are needed to build the snmp ldap-agent BuildRequires: net-snmp-devel -BuildRequires: lm_sensors-devel BuildRequires: bzip2-devel -BuildRequires: zlib-devel BuildRequires: openssl-devel # the following is for the pam passthru auth plug-in BuildRequires: pam-devel @@ -369,16 +390,12 @@ BuildRequires: systemd-units BuildRequires: systemd-devel BuildRequires: systemd-rpm-macros %{?sysusers_requires_compat} -%if %{use_asan} -BuildRequires: libasan -%endif BuildRequires: cargo BuildRequires: rust BuildRequires: pkgconfig BuildRequires: pkgconfig(systemd) BuildRequires: pkgconfig(krb5) BuildRequires: pkgconfig(libpcre2-8) - # Needed to support regeneration of the autotool artifacts. BuildRequires: autoconf BuildRequires: automake @@ -387,112 +404,117 @@ BuildRequires: libtool BuildRequires: doxygen # For tests! BuildRequires: libcmocka-devel -BuildRequires: libevent-devel -# For lib389 and related components +# For lib389 and related components. +BuildRequires: python%{python3_pkgversion} BuildRequires: python%{python3_pkgversion}-devel BuildRequires: python%{python3_pkgversion}-setuptools BuildRequires: python%{python3_pkgversion}-ldap -BuildRequires: python%{python3_pkgversion}-six BuildRequires: python%{python3_pkgversion}-pyasn1 BuildRequires: python%{python3_pkgversion}-pyasn1-modules BuildRequires: python%{python3_pkgversion}-dateutil BuildRequires: python%{python3_pkgversion}-argcomplete BuildRequires: python%{python3_pkgversion}-argparse-manpage -BuildRequires: python%{python3_pkgversion}-libselinux BuildRequires: python%{python3_pkgversion}-policycoreutils +BuildRequires: python%{python3_pkgversion}-libselinux BuildRequires: python%{python3_pkgversion}-cryptography # For cockpit -%if %{use_cockpit} +%if %{with cockpit} BuildRequires: rsync +BuildRequires: npm +BuildRequires: nodejs %endif Requires: %{name}-libs = %{version}-%{release} Requires: python%{python3_pkgversion}-lib389 = %{version}-%{release} -Requires: lmdb-libs # this is needed for using semanage from our setup scripts Requires: policycoreutils-python-utils -Requires: /usr/sbin/semanage Requires: libsemanage-python%{python3_pkgversion} -Requires: selinux-policy >= 3.14.1-29 - # the following are needed for some of our scripts Requires: openldap-clients -Requires: /usr/bin/c_rehash -Requires: python%{python3_pkgversion}-ldap Requires: acl -Requires: zlib -Requires: json-c - # this is needed to setup SSL if you are not using the # administration server package Requires: nss-tools -Requires: nss >= 3.67.0-7 -Requires: nspr >= 4.32 - +%dirsrv_requires_ge nss # these are not found by the auto-dependency method # they are required to support the mandatory LDAP SASL mechs Requires: cyrus-sasl-gssapi Requires: cyrus-sasl-md5 +# This is optionally supported by us, as we use it in our tests Requires: cyrus-sasl-plain - -# this is needed for verify-db.pl -Requires: libdb-utils - -# Needed for password dictionary checks -Requires: cracklib-dicts - +# this is needed for backldbm +%if %{without bundle_libdb} +Requires: libdb +%endif +Requires: lmdb +# This picks up libperl.so as a Requires, so we add this versioned one +Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) # Needed by logconv.pl +%if %{without bundle_libdb} Requires: perl-DB_File +%endif Requires: perl-Archive-Tar %if 0%{?fedora} >= 33 || 0%{?rhel} >= 9 Requires: perl-debugger Requires: perl-sigtrap %endif - +# Needed for password dictionary checks +Requires: cracklib-dicts +Requires: json-c +# Log compression +Requires: zlib-devel # Picks up our systemd deps. %{?systemd_requires} -Obsoletes: %{name} <= 1.4.4 - -Source0: https://releases.pagure.org/389-ds-base/%{name}-%{version}.tar.bz2 -# 389-ds-git.sh should be used to generate the source tarball from git -Source1: %{name}-git.sh +Source0: %{name}-%{version}.tar.bz2 Source2: %{name}-devel.README -%if %{bundle_jemalloc} +%if %{with bundle_jemalloc} Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download/%{jemalloc_ver}/%{jemalloc_name}-%{jemalloc_ver}.tar.bz2 %endif Source4: 389-ds-base.sysusers +%if %{with bundle_libdb} +Source5: https://fedorapeople.org/groups/389ds/libdb-5.3.28-59.tar.bz2 +%endif %description 389 Directory Server is an LDAPv3 compliant server. The base package includes the LDAP server and command line utilities for server administration. -%if %{use_asan} +%if %{with asan} WARNING! This build is linked to Address Sanitisation libraries. This probably isn't what you want. Please contact support immediately. Please see http://seclists.org/oss-sec/2016/q1/363 for more information. %endif + %package libs -Summary: Core libraries for 389 Directory Server -BuildRequires: nspr-devel -BuildRequires: nss-devel >= 3.34 -BuildRequires: openldap-devel -BuildRequires: libdb-devel -BuildRequires: cyrus-sasl-devel -BuildRequires: libicu-devel -BuildRequires: pcre2-devel -BuildRequires: libtalloc-devel -BuildRequires: libevent-devel -BuildRequires: libtevent-devel -Requires: krb5-libs -Requires: libevent -BuildRequires: systemd-devel -BuildRequires: make +Summary: Core libraries for 389 Directory Server (%{variant}) Provides: svrcore = 4.1.4 -Conflicts: svrcore Obsoletes: svrcore <= 4.1.3 +Conflicts: svrcore +%dirsrv_requires_ge nss +Requires: nspr +Requires: openldap +Requires: systemd-libs +# Pull in sasl +Requires: cyrus-sasl-lib +# KRB +Requires: krb5-libs +%if %{with clang} +Requires: llvm +Requires: compiler-rt +%else +%if %{with asan} +Requires: libasan +%endif +%if %{with tsan} +Requires: libtsan +%endif +%if %{with ubsan} +Requires: libubsan +%endif +%endif %description libs Core libraries for the 389 Directory Server base package. These libraries @@ -500,19 +522,17 @@ are used by the main package and the -devel package. This allows the -devel package to be installed with just the -libs package and without the main package. %package devel -Summary: Development libraries for 389 Directory Server +Summary: Development libraries for 389 Directory Server (%{variant}) +Provides: svrcore-devel = 4.1.4 +Obsoletes: svrcore-devel <= 4.1.3 +Conflicts: svrcore-devel Requires: %{name}-libs = %{version}-%{release} Requires: pkgconfig Requires: nspr-devel Requires: nss-devel >= 3.34 Requires: openldap-devel -Requires: libtalloc -Requires: libevent -Requires: libtevent +# systemd-libs contains the headers iirc. Requires: systemd-libs -Provides: svrcore-devel = 4.1.4 -Conflicts: svrcore-devel -Obsoletes: svrcore-devel <= 4.1.3 %description devel Development Libraries and headers for the 389 Directory Server base package. @@ -526,16 +546,35 @@ Obsoletes: %{name} <= 1.4.0.0 %description snmp SNMP Agent for the 389 Directory Server base package. +%if %{with bundle_libdb} +%package bdb +Summary: Berkeley Database backend for 389 Directory Server +%description bdb +Berkeley Database backend for 389 Directory Server +Warning! This backend is deprecated in favor of lmdb and its support +may be removed in future versions. + +Requires: %{name} = %{version}-%{release} +# Berkeley DB database libdb was marked as deprecated since F40: +# https://fedoraproject.org/wiki/Changes/389_Directory_Server_3.0.0 +# because libdb was marked as deprecated since F33 +# https://fedoraproject.org/wiki/Changes/Libdb_deprecated +Provides: deprecated() +%endif + + %package -n python%{python3_pkgversion}-lib389 Summary: A library for accessing, testing, and configuring the 389 Directory Server BuildArch: noarch +Requires: %{name} = %{version}-%{release} Requires: openssl +# This is for /usr/bin/c_rehash tool, only needed for openssl < 1.1.0 +Requires: openssl-perl Requires: iproute -Recommends: bash-completion Requires: python%{python3_pkgversion} Requires: python%{python3_pkgversion}-distro +Requires: python%{python3_pkgversion}-pytest Requires: python%{python3_pkgversion}-ldap -Requires: python%{python3_pkgversion}-six Requires: python%{python3_pkgversion}-pyasn1 Requires: python%{python3_pkgversion}-pyasn1-modules Requires: python%{python3_pkgversion}-dateutil @@ -543,20 +582,21 @@ Requires: python%{python3_pkgversion}-argcomplete Requires: python%{python3_pkgversion}-libselinux Requires: python%{python3_pkgversion}-setuptools Requires: python%{python3_pkgversion}-cryptography +Recommends: bash-completion %{?python_provide:%python_provide python%{python3_pkgversion}-lib389} %description -n python%{python3_pkgversion}-lib389 This module contains tools and libraries for accessing, testing, and configuring the 389 Directory Server. -%if %{use_cockpit} +%if %{with cockpit} %package -n cockpit-389-ds Summary: Cockpit UI Plugin for configuring and administering the 389 Directory Server BuildArch: noarch Requires: cockpit -Requires: 389-ds-base +Requires: %{name} = %{version}-%{release} Requires: python%{python3_pkgversion} -Requires: python%{python3_pkgversion}-lib389 +Requires: python%{python3_pkgversion}-lib389 = %{version}-%{release} %description -n cockpit-389-ds A cockpit UI Plugin for configuring and administering the 389 Directory Server @@ -565,34 +605,47 @@ A cockpit UI Plugin for configuring and administering the 389 Directory Server %prep %autosetup -p1 -v -n %{name}-%{version} -%if %{bundle_jemalloc} +%if %{with bundle_jemalloc} %setup -q -n %{name}-%{version} -T -D -b 3 %endif +%if %{with bundle_libdb} +%setup -q -n %{name}-%{version} -T -D -b 5 +%endif + cp %{SOURCE2} README.devel %build -OPENLDAP_FLAG="--with-openldap" -%{?with_tmpfiles_d: TMPFILES_FLAG="--with-tmpfiles-d=%{with_tmpfiles_d}"} - -%if %{use_asan} -ASAN_FLAGS="--enable-asan --enable-debug" -%endif - -RUST_FLAGS="--enable-rust-offline" - -%if !%{use_cockpit} -COCKPIT_FLAGS="--disable-cockpit" -%endif - -%if %{use_clang} -export CC=clang -export CXX=clang++ +%if %{with clang} CLANG_FLAGS="--enable-clang" %endif -%if %{bundle_jemalloc} +%{?with_tmpfiles_d: TMPFILES_FLAG="--with-tmpfiles-d=%{with_tmpfiles_d}"} + +%if %{with asan} +ASAN_FLAGS="--enable-asan --enable-debug" +%endif + +%if %{with msan} +MSAN_FLAGS="--enable-msan --enable-debug" +%endif + +%if %{with tsan} +TSAN_FLAGS="--enable-tsan --enable-debug" +%endif + +%if %{with ubsan} +UBSAN_FLAGS="--enable-ubsan --enable-debug" +%endif + +RUST_FLAGS="--enable-rust --enable-rust-offline" + +%if %{without cockpit} +COCKPIT_FLAGS="--disable-cockpit" +%endif + +%if %{with bundle_jemalloc} # Override page size, bz #1545539 # 4K %ifarch %ix86 %arm x86_64 s390x @@ -615,26 +668,44 @@ pushd ../%{jemalloc_name}-%{jemalloc_ver} %configure \ --libdir=%{_libdir}/%{pkgname}/lib \ --bindir=%{_libdir}/%{pkgname}/bin \ - --enable-prof + --enable-prof %{lg_page} %{lg_hugepage} make %{?_smp_mflags} popd %endif -# Enforce strict linking -%define _ld_strict_symbol_defs 1 +# Build custom libdb package +%if %{with bundle_libdb} +mkdir -p ../%{libdb_base_version} +pushd ../%{libdb_base_version} +tar -xjf ../../SOURCES/%{libdb_full_version}.tar.bz2 +mv %{libdb_full_version} SOURCES +rpmbuild --define "_topdir $PWD" -bc %{_builddir}/%{name}-%{version}/rpm/bundle-libdb.spec +popd +%endif # Rebuild the autotool artifacts now. autoreconf -fiv -%configure --enable-autobind --with-selinux $TMPFILES_FLAG \ +%configure \ +%if %{with bundle_libdb} + --with-bundle-libdb=%{_builddir}/%{libdb_base_version}/BUILD/%{libdb_base_version}/dist/dist-tls \ +%endif + --with-selinux $TMPFILES_FLAG \ --with-systemd \ --with-systemdsystemunitdir=%{_unitdir} \ --with-systemdsystemconfdir=%{_sysconfdir}/systemd/system \ - --with-systemdgroupname=%{groupname} \ + --with-systemdgroupname=%{groupname} \ --libexecdir=%{_libexecdir}/%{pkgname} \ - $ASAN_FLAGS $RUST_FLAGS $CLANG_FLAGS $COCKPIT_FLAGS \ - --enable-cmocka \ - --with-libldap-r=no + $ASAN_FLAGS $MSAN_FLAGS $TSAN_FLAGS $UBSAN_FLAGS $RUST_FLAGS $CLANG_FLAGS $COCKPIT_FLAGS \ +%if 0%{?fedora} >= 34 || 0%{?rhel} >= 9 + --with-libldap-r=no \ +%endif + --enable-cmocka + +# Avoid "Unknown key name 'XXX' in section 'Service', ignoring." warnings from systemd on older releases +%if 0%{?rhel} && 0%{?rhel} < 9 + sed -r -i '/^(Protect(Home|Hostname|KernelLogs)|PrivateMounts)=/d' %{_builddir}/%{name}-%{version}/wrappers/*.service.in +%endif # lib389 make src/lib389/setup.py @@ -651,22 +722,26 @@ sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}/src/lib389/man/dscreat # Generate symbolic info for debuggers export XCFLAGS=$RPM_OPT_FLAGS -#make %{?_smp_mflags} -make +make %{?_smp_mflags} %install mkdir -p %{buildroot}%{_datadir}/gdb/auto-load%{_sbindir} -%if %{use_cockpit} +%if %{with cockpit} mkdir -p %{buildroot}%{_datadir}/cockpit %endif make DESTDIR="$RPM_BUILD_ROOT" install -%if %{use_cockpit} +%if %{with cockpit} find %{buildroot}%{_datadir}/cockpit/389-console -type d | sed -e "s@%{buildroot}@@" | sed -e 's/^/\%dir /' > cockpit.list find %{buildroot}%{_datadir}/cockpit/389-console -type f | sed -e "s@%{buildroot}@@" >> cockpit.list %endif +find %{buildroot}%{_libdir}/%{pkgname}/plugins/ -type f -iname 'lib*.so' | sed -e "s@%{buildroot}@@" > plugins.list +%if %{with bundle_libdb} +sed -i -e "/libback-bdb/d" plugins.list +%endif + # Copy in our docs from doxygen. cp -r %{_builddir}/%{name}-%{version}/man/man3 $RPM_BUILD_ROOT/%{_mandir}/man3 @@ -684,13 +759,14 @@ done mkdir -p $RPM_BUILD_ROOT/var/log/%{pkgname} mkdir -p $RPM_BUILD_ROOT/var/lib/%{pkgname} -mkdir -p $RPM_BUILD_ROOT/var/lock/%{pkgname} +mkdir -p $RPM_BUILD_ROOT/var/lock/%{pkgname} \ + && chmod 770 $RPM_BUILD_ROOT/var/lock/%{pkgname} # for systemd mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/systemd/system/%{groupname}.wants install -p -D -m 0644 %{SOURCE4} %{buildroot}%{_sysusersdir}/389-ds-base.conf -# remove libtool archives and static libs +#remove libtool and static libs rm -f $RPM_BUILD_ROOT%{_libdir}/%{pkgname}/*.a rm -f $RPM_BUILD_ROOT%{_libdir}/%{pkgname}/*.la rm -f $RPM_BUILD_ROOT%{_libdir}/%{pkgname}/plugins/*.a @@ -698,7 +774,7 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/%{pkgname}/plugins/*.la rm -f $RPM_BUILD_ROOT%{_libdir}/libsvrcore.a rm -f $RPM_BUILD_ROOT%{_libdir}/libsvrcore.la -%if %{bundle_jemalloc} +%if %{with bundle_jemalloc} pushd ../%{jemalloc_name}-%{jemalloc_ver} make DESTDIR="$RPM_BUILD_ROOT" install_lib install_bin cp -pa COPYING ../%{name}-%{version}/COPYING.jemalloc @@ -706,9 +782,26 @@ cp -pa README ../%{name}-%{version}/README.jemalloc popd %endif +%if %{with bundle_libdb} +pushd ../%{libdb_base_version} +libdbbuilddir=$PWD/BUILD/%{libdb_base_version} +libdbdestdir=$PWD/../%{name}-%{version} +cp -pa $libdbbuilddir/LICENSE $libdbdestdir/LICENSE.libdb +cp -pa $libdbbuilddir/README $libdbdestdir/README.libdb +cp -pa $libdbbuilddir/lgpl-2.1.txt $libdbdestdir/lgpl-2.1.txt.libdb +cp -pa $libdbbuilddir/dist/dist-tls/.libs/%{libdb_bundle_name} $RPM_BUILD_ROOT%{_libdir}/%{pkgname}/%{libdb_bundle_name} +popd +%endif + + %check # This checks the code, if it fails it prints why, then re-raises the fail to shortcircuit the rpm build. +%if %{with tsan} +export TSAN_OPTIONS=print_stacktrace=1:second_deadlock_stack=1:history_size=7 +%endif +%if %{without asan} && %{without msan} if ! make DESTDIR="$RPM_BUILD_ROOT" check; then cat ./test-suite.log && false; fi +%endif %post if [ -n "$DEBUGPOSTTRANS" ] ; then @@ -787,8 +880,8 @@ fi exit 0 -%files -%if %{bundle_jemalloc} +%files -f plugins.list +%if %{with bundle_jemalloc} %doc LICENSE LICENSE.GPLv3+ LICENSE.openssl README.jemalloc %license COPYING.jemalloc %else @@ -818,7 +911,6 @@ exit 0 %{_mandir}/man1/logconv.pl.1.gz %{_bindir}/pwdhash %{_mandir}/man1/pwdhash.1.gz -#%caps(CAP_NET_BIND_SERVICE=pe) {_sbindir}/ns-slapd %{_sbindir}/ns-slapd %{_mandir}/man8/ns-slapd.8.gz %{_sbindir}/openldap_to_ds @@ -832,7 +924,6 @@ exit 0 %{_mandir}/man5/dirsrv.systemd.5.gz %{_libdir}/%{pkgname}/python %dir %{_libdir}/%{pkgname}/plugins -%{_libdir}/%{pkgname}/plugins/*.so # This has to be hardcoded to /lib - $libdir changes between lib/lib64, but # sysctl.d is always in /lib. %{_prefix}/lib/sysctl.d/* @@ -842,7 +933,7 @@ exit 0 %exclude %{_sbindir}/ldap-agent* %exclude %{_mandir}/man1/ldap-agent.1.gz %exclude %{_unitdir}/%{pkgname}-snmp.service -%if %{bundle_jemalloc} +%if %{with bundle_jemalloc} %{_libdir}/%{pkgname}/lib/ %{_libdir}/%{pkgname}/bin/ %exclude %{_libdir}/%{pkgname}/bin/jemalloc-config @@ -873,7 +964,7 @@ exit 0 %{_libdir}/%{pkgname}/libns-dshttpd.so.* %{_libdir}/%{pkgname}/libldaputil.so.* %{_libdir}/%{pkgname}/librewriters.so* -%if %{bundle_jemalloc} +%if %{with bundle_jemalloc} %{_libdir}/%{pkgname}/lib/libjemalloc.so.2 %endif @@ -884,6 +975,13 @@ exit 0 %{_mandir}/man1/ldap-agent.1.gz %{_unitdir}/%{pkgname}-snmp.service +%if %{with bundle_libdb} +%files bdb +%doc LICENSE LICENSE.GPLv3+ README.devel LICENSE.libdb README.libdb lgpl-2.1.txt.libdb +%{_libdir}/%{pkgname}/%{libdb_bundle_name} +%{_libdir}/%{pkgname}/plugins/libback-bdb.so +%endif + %files -n python%{python3_pkgversion}-lib389 %doc LICENSE LICENSE.GPLv3+ %{python3_sitelib}/lib389* @@ -901,7 +999,7 @@ exit 0 %{bash_completions_dir}/dscreate %{bash_completions_dir}/dsidm -%if %{use_cockpit} +%if %{with cockpit} %files -n cockpit-389-ds -f cockpit.list %{_datarootdir}/metainfo/389-console/org.port389.cockpit_console.metainfo.xml %doc README.md From ebbd5286c6b388ce1e75000cbe46dd707d417acb Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Sat, 1 Jun 2024 19:14:48 +0200 Subject: [PATCH 085/125] Exclude i686 architecture [skip changelog] --- 389-ds-base.spec | 3 +++ 1 file changed, 3 insertions(+) diff --git a/389-ds-base.spec b/389-ds-base.spec index 28db828..39a77d6 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -1,5 +1,8 @@ %global pkgname dirsrv +# Exclude i686 bit arches +ExcludeArch: i686 + %bcond bundle_jemalloc 1 %if %{with bundle_jemalloc} %global jemalloc_name jemalloc From 27db1de21ec34364e3ad9b0d721e90e2dbb60dc2 Mon Sep 17 00:00:00 2001 From: Python Maint Date: Fri, 7 Jun 2024 22:44:48 +0200 Subject: [PATCH 086/125] Rebuilt for Python 3.13 From 60a22a6d735b7c9516846746b3ccb73a5be1e68a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Mon, 10 Jun 2024 07:42:51 +0200 Subject: [PATCH 087/125] Stop Providing libjemalloc.so.2()(64bit) This was removed in eeb80bdcccf9aca1711cf6c20cc37b9ed79e3b8c and it made 389-ds-base-libs and 389-ds-base Provides libjemalloc.so.2()(64bit). Package Requiring it would install 389-ds-base-libs instead of jemalloc, failing to execute with: $ nsupdate nsupdate: error while loading shared libraries: libjemalloc.so.2: cannot open shared object file: No such file or directory --- 389-ds-base.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/389-ds-base.spec b/389-ds-base.spec index 39a77d6..78d17f4 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -7,6 +7,7 @@ ExcludeArch: i686 %if %{with bundle_jemalloc} %global jemalloc_name jemalloc %global jemalloc_ver 5.3.0 +%global __provides_exclude ^libjemalloc\\.so.*$ %endif %bcond bundle_libdb 0 From 230361324399e84b602cf54c467e5d1f8bdcc13d Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Thu, 13 Jun 2024 16:51:14 +0200 Subject: [PATCH 088/125] Drop obsolete perl MODULE_COMPAT requirement --- 389-ds-base.spec | 2 -- 1 file changed, 2 deletions(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 78d17f4..42688be 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -453,8 +453,6 @@ Requires: cyrus-sasl-plain Requires: libdb %endif Requires: lmdb -# This picks up libperl.so as a Requires, so we add this versioned one -Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) # Needed by logconv.pl %if %{without bundle_libdb} Requires: perl-DB_File From 291e311dd330348fc53d78c0d02a205369f13ea0 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Mon, 17 Jun 2024 09:58:18 +0200 Subject: [PATCH 089/125] Drop pytest dependency --- 389-ds-base.spec | 1 - 1 file changed, 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 42688be..75abcc1 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -575,7 +575,6 @@ Requires: openssl-perl Requires: iproute Requires: python%{python3_pkgversion} Requires: python%{python3_pkgversion}-distro -Requires: python%{python3_pkgversion}-pytest Requires: python%{python3_pkgversion}-ldap Requires: python%{python3_pkgversion}-pyasn1 Requires: python%{python3_pkgversion}-pyasn1-modules From 46083690af01f673327744fcfa1d60c5d63c128d Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Tue, 25 Jun 2024 01:05:46 -0400 Subject: [PATCH 090/125] Fix bundled libdb build with RPM 4.20 https://github.com/389ds/389-ds-base/pull/6235 --- ...-rpm-fix-compatibility-with-RPM-4.20.patch | 77 +++++++++++++++++++ 389-ds-base.spec | 14 +++- 2 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 0001-rpm-fix-compatibility-with-RPM-4.20.patch diff --git a/0001-rpm-fix-compatibility-with-RPM-4.20.patch b/0001-rpm-fix-compatibility-with-RPM-4.20.patch new file mode 100644 index 0000000..46e9d8d --- /dev/null +++ b/0001-rpm-fix-compatibility-with-RPM-4.20.patch @@ -0,0 +1,77 @@ +RPM 4.20 drops support for the deprecated %patchN syntax. + +diff --git a/rpm/bundle-libdb.spec b/rpm/bundle-libdb.spec +index 56c5a5111..bd5644c80 100644 +--- a/rpm/bundle-libdb.spec ++++ b/rpm/bundle-libdb.spec +@@ -154,39 +154,39 @@ cp %{SOURCE2} . + tar -xf %{SOURCE3} + + +-%patch0 -p1 ++%patch -P0 -p1 + pushd db.1.85/PORT/linux +-%patch10 -p0 ++%patch -P10 -p0 + popd + pushd db.1.85 +-%patch11 -p0 +-%patch12 -p0 +-%patch13 -p0 +-%patch20 -p1 ++%patch -P11 -p0 ++%patch -P12 -p0 ++%patch -P13 -p0 ++%patch -P20 -p1 + popd + +-%patch22 -p1 +-%patch24 -p1 +-%patch25 -p1 +-%patch27 -p1 +-%patch28 -p1 +-%patch29 -p1 +-%patch30 -p1 +-%patch31 -p1 +-%patch32 -p1 +-%patch33 -p1 +-%patch34 -p1 +-%patch35 -p1 +-%patch36 -p1 +-%patch37 -p1 +-%patch38 -p1 +-%patch39 -p1 +-%patch40 -p1 -b .cve-2019-2708 +-%patch41 -p1 +-%patch42 -p1 +-%patch43 -p1 +-%patch44 -p1 +-%patch45 -p1 ++%patch -P22 -p1 ++%patch -P24 -p1 ++%patch -P25 -p1 ++%patch -P27 -p1 ++%patch -P28 -p1 ++%patch -P29 -p1 ++%patch -P30 -p1 ++%patch -P31 -p1 ++%patch -P32 -p1 ++%patch -P33 -p1 ++%patch -P34 -p1 ++%patch -P35 -p1 ++%patch -P36 -p1 ++%patch -P37 -p1 ++%patch -P38 -p1 ++%patch -P39 -p1 ++%patch -P40 -p1 -b .cve-2019-2708 ++%patch -P41 -p1 ++%patch -P42 -p1 ++%patch -P43 -p1 ++%patch -P44 -p1 ++%patch -P45 -p1 + + cd dist + ./s_config +-- +2.45.2 + diff --git a/389-ds-base.spec b/389-ds-base.spec index 75abcc1..3d73439 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -16,6 +16,12 @@ ExcludeArch: i686 %global libdb_base_version db-%{libdb_version}.28 %global libdb_full_version lib%{libdb_base_version}-59 %global libdb_bundle_name libdb-%{libdb_version}-389ds.so +%if 0%{?fedora} >= 41 || 0%{?rhel} >= 11 +# RPM 4.20 +%global libdb_base_dir lib%{libdb_base_version}-build/%{libdb_base_version} +%else +%global libdb_base_dir %{libdb_base_version} +%endif %endif # This is used in certain builds to help us know if it has extra features. @@ -479,6 +485,8 @@ Source4: 389-ds-base.sysusers %if %{with bundle_libdb} Source5: https://fedorapeople.org/groups/389ds/libdb-5.3.28-59.tar.bz2 %endif +# https://github.com/389ds/389-ds-base/pull/6235 +Patch0: 0001-rpm-fix-compatibility-with-RPM-4.20.patch %description 389 Directory Server is an LDAPv3 compliant server. The base package includes @@ -678,7 +686,7 @@ popd %if %{with bundle_libdb} mkdir -p ../%{libdb_base_version} pushd ../%{libdb_base_version} -tar -xjf ../../SOURCES/%{libdb_full_version}.tar.bz2 +tar -xjf %{_topdir}/SOURCES/%{libdb_full_version}.tar.bz2 mv %{libdb_full_version} SOURCES rpmbuild --define "_topdir $PWD" -bc %{_builddir}/%{name}-%{version}/rpm/bundle-libdb.spec popd @@ -689,7 +697,7 @@ autoreconf -fiv %configure \ %if %{with bundle_libdb} - --with-bundle-libdb=%{_builddir}/%{libdb_base_version}/BUILD/%{libdb_base_version}/dist/dist-tls \ + --with-bundle-libdb=%{_builddir}/%{libdb_base_version}/BUILD/%{libdb_base_dir}/dist/dist-tls \ %endif --with-selinux $TMPFILES_FLAG \ --with-systemd \ @@ -785,7 +793,7 @@ popd %if %{with bundle_libdb} pushd ../%{libdb_base_version} -libdbbuilddir=$PWD/BUILD/%{libdb_base_version} +libdbbuilddir=$PWD/BUILD/%{libdb_base_dir} libdbdestdir=$PWD/../%{name}-%{version} cp -pa $libdbbuilddir/LICENSE $libdbdestdir/LICENSE.libdb cp -pa $libdbbuilddir/README $libdbdestdir/README.libdb From 0dd17702a837ffbdd30e0d21961748c73a4a038b Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Tue, 25 Jun 2024 15:56:38 -0400 Subject: [PATCH 091/125] Use bundled libdb on RHEL and ELN Based on c10s: https://gitlab.com/redhat/centos-stream/rpms/389-ds-base/-/commit/8dfbbc21d054a9e204d35376f764a13ea3df0ac0 --- .gitignore | 1 + 389-ds-base.spec | 2 +- sources | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ead6bde..e611085 100644 --- a/.gitignore +++ b/.gitignore @@ -228,3 +228,4 @@ /389-ds-base-3.0.1.tar.bz2 /389-ds-base-3.0.2.tar.bz2 /389-ds-base-3.1.0.tar.bz2 +/libdb-5.3.28-59.tar.bz2 diff --git a/389-ds-base.spec b/389-ds-base.spec index 3d73439..3e07d5d 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -10,7 +10,7 @@ ExcludeArch: i686 %global __provides_exclude ^libjemalloc\\.so.*$ %endif -%bcond bundle_libdb 0 +%bcond bundle_libdb %{defined rhel} %if %{with bundle_libdb} %global libdb_version 5.3 %global libdb_base_version db-%{libdb_version}.28 diff --git a/sources b/sources index 42ac5f4..8e81e9f 100644 --- a/sources +++ b/sources @@ -1,2 +1,3 @@ SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 +SHA512 (libdb-5.3.28-59.tar.bz2) = 731a434fa2e6487ebb05c458b0437456eb9f7991284beb08cb3e21931e23bdeddddbc95bfabe3a2f9f029fe69cd33a2d4f0f5ce6a9811e9c3b940cb6fde4bf79 SHA512 (389-ds-base-3.1.0.tar.bz2) = 7b471328ae9efe451d30d0f61bdf207dbce0b8094685132390196d45bda5e3cba29e025ce18e51cee9d8b84f685024208d38a2407e2d3c685bc5d8dfcb86d4ea From 1cf86bb6f0034ac56941096b7f117e5acbb38653 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 17 Jul 2024 14:39:40 +0000 Subject: [PATCH 092/125] Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild From 315706ba43a6df08ea97496881178bd711bdc66b Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Tue, 30 Jul 2024 11:52:54 +0200 Subject: [PATCH 093/125] Update to 3.1.1 ... - Resolves: CVE-2024-1062 (rhbz#2261884) - Resolves: CVE-2024-2199 (rhbz#2283632) - Resolves: CVE-2024-3657 (rhbz#2283631) - Resolves: CVE-2024-5953 (rhbz#2292109) --- .gitignore | 1 + ...-rpm-fix-compatibility-with-RPM-4.20.patch | 77 ------------------ 389-ds-base.spec | 78 +++++++++---------- sources | 2 +- 4 files changed, 41 insertions(+), 117 deletions(-) delete mode 100644 0001-rpm-fix-compatibility-with-RPM-4.20.patch diff --git a/.gitignore b/.gitignore index e611085..5b59f1d 100644 --- a/.gitignore +++ b/.gitignore @@ -229,3 +229,4 @@ /389-ds-base-3.0.2.tar.bz2 /389-ds-base-3.1.0.tar.bz2 /libdb-5.3.28-59.tar.bz2 +/389-ds-base-3.1.1.tar.bz2 diff --git a/0001-rpm-fix-compatibility-with-RPM-4.20.patch b/0001-rpm-fix-compatibility-with-RPM-4.20.patch deleted file mode 100644 index 46e9d8d..0000000 --- a/0001-rpm-fix-compatibility-with-RPM-4.20.patch +++ /dev/null @@ -1,77 +0,0 @@ -RPM 4.20 drops support for the deprecated %patchN syntax. - -diff --git a/rpm/bundle-libdb.spec b/rpm/bundle-libdb.spec -index 56c5a5111..bd5644c80 100644 ---- a/rpm/bundle-libdb.spec -+++ b/rpm/bundle-libdb.spec -@@ -154,39 +154,39 @@ cp %{SOURCE2} . - tar -xf %{SOURCE3} - - --%patch0 -p1 -+%patch -P0 -p1 - pushd db.1.85/PORT/linux --%patch10 -p0 -+%patch -P10 -p0 - popd - pushd db.1.85 --%patch11 -p0 --%patch12 -p0 --%patch13 -p0 --%patch20 -p1 -+%patch -P11 -p0 -+%patch -P12 -p0 -+%patch -P13 -p0 -+%patch -P20 -p1 - popd - --%patch22 -p1 --%patch24 -p1 --%patch25 -p1 --%patch27 -p1 --%patch28 -p1 --%patch29 -p1 --%patch30 -p1 --%patch31 -p1 --%patch32 -p1 --%patch33 -p1 --%patch34 -p1 --%patch35 -p1 --%patch36 -p1 --%patch37 -p1 --%patch38 -p1 --%patch39 -p1 --%patch40 -p1 -b .cve-2019-2708 --%patch41 -p1 --%patch42 -p1 --%patch43 -p1 --%patch44 -p1 --%patch45 -p1 -+%patch -P22 -p1 -+%patch -P24 -p1 -+%patch -P25 -p1 -+%patch -P27 -p1 -+%patch -P28 -p1 -+%patch -P29 -p1 -+%patch -P30 -p1 -+%patch -P31 -p1 -+%patch -P32 -p1 -+%patch -P33 -p1 -+%patch -P34 -p1 -+%patch -P35 -p1 -+%patch -P36 -p1 -+%patch -P37 -p1 -+%patch -P38 -p1 -+%patch -P39 -p1 -+%patch -P40 -p1 -b .cve-2019-2708 -+%patch -P41 -p1 -+%patch -P42 -p1 -+%patch -P43 -p1 -+%patch -P44 -p1 -+%patch -P45 -p1 - - cd dist - ./s_config --- -2.45.2 - diff --git a/389-ds-base.spec b/389-ds-base.spec index 3e07d5d..66bec5a 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -66,7 +66,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (%{variant}) Name: 389-ds-base -Version: 3.1.0 +Version: 3.1.1 Release: %{autorelease -n %{?with_asan:-e asan}}%{?dist} License: GPL-3.0-or-later AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-DFS-2016 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0 URL: https://www.port389.org @@ -75,53 +75,53 @@ Obsoletes: %{name}-legacy-tools-debuginfo < 1.4.4.6 Provides: ldif2ldbm >= 0 ##### Bundled cargo crates list - START ##### -Provides: bundled(crate(addr2line)) = 0.21.0 +Provides: bundled(crate(addr2line)) = 0.22.0 Provides: bundled(crate(adler)) = 1.0.2 Provides: bundled(crate(ahash)) = 0.7.8 Provides: bundled(crate(atty)) = 0.2.14 Provides: bundled(crate(autocfg)) = 1.3.0 -Provides: bundled(crate(backtrace)) = 0.3.71 +Provides: bundled(crate(backtrace)) = 0.3.73 Provides: bundled(crate(base64)) = 0.13.1 -Provides: bundled(crate(bitflags)) = 2.5.0 +Provides: bundled(crate(bitflags)) = 2.6.0 Provides: bundled(crate(byteorder)) = 1.5.0 Provides: bundled(crate(cbindgen)) = 0.26.0 -Provides: bundled(crate(cc)) = 1.0.97 +Provides: bundled(crate(cc)) = 1.1.7 Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 3.2.25 Provides: bundled(crate(clap_lex)) = 0.2.4 Provides: bundled(crate(concread)) = 0.2.21 Provides: bundled(crate(crossbeam)) = 0.8.4 -Provides: bundled(crate(crossbeam-channel)) = 0.5.12 +Provides: bundled(crate(crossbeam-channel)) = 0.5.13 Provides: bundled(crate(crossbeam-deque)) = 0.8.5 Provides: bundled(crate(crossbeam-epoch)) = 0.9.18 Provides: bundled(crate(crossbeam-queue)) = 0.3.11 -Provides: bundled(crate(crossbeam-utils)) = 0.8.19 +Provides: bundled(crate(crossbeam-utils)) = 0.8.20 Provides: bundled(crate(errno)) = 0.3.9 Provides: bundled(crate(fastrand)) = 2.1.0 Provides: bundled(crate(fernet)) = 0.1.4 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 Provides: bundled(crate(getrandom)) = 0.2.15 -Provides: bundled(crate(gimli)) = 0.28.1 +Provides: bundled(crate(gimli)) = 0.29.0 Provides: bundled(crate(hashbrown)) = 0.12.3 Provides: bundled(crate(heck)) = 0.4.1 Provides: bundled(crate(hermit-abi)) = 0.1.19 Provides: bundled(crate(indexmap)) = 1.9.3 -Provides: bundled(crate(instant)) = 0.1.12 +Provides: bundled(crate(instant)) = 0.1.13 Provides: bundled(crate(itoa)) = 1.0.11 -Provides: bundled(crate(jobserver)) = 0.1.31 -Provides: bundled(crate(libc)) = 0.2.154 -Provides: bundled(crate(linux-raw-sys)) = 0.4.13 +Provides: bundled(crate(jobserver)) = 0.1.32 +Provides: bundled(crate(libc)) = 0.2.155 +Provides: bundled(crate(linux-raw-sys)) = 0.4.14 Provides: bundled(crate(lock_api)) = 0.4.12 -Provides: bundled(crate(log)) = 0.4.21 +Provides: bundled(crate(log)) = 0.4.22 Provides: bundled(crate(lru)) = 0.7.8 -Provides: bundled(crate(memchr)) = 2.7.2 -Provides: bundled(crate(miniz_oxide)) = 0.7.2 -Provides: bundled(crate(object)) = 0.32.2 +Provides: bundled(crate(memchr)) = 2.7.4 +Provides: bundled(crate(miniz_oxide)) = 0.7.4 +Provides: bundled(crate(object)) = 0.36.2 Provides: bundled(crate(once_cell)) = 1.19.0 -Provides: bundled(crate(openssl)) = 0.10.64 +Provides: bundled(crate(openssl)) = 0.10.66 Provides: bundled(crate(openssl-macros)) = 0.1.1 -Provides: bundled(crate(openssl-sys)) = 0.9.102 +Provides: bundled(crate(openssl-sys)) = 0.9.103 Provides: bundled(crate(os_str_bytes)) = 6.6.1 Provides: bundled(crate(parking_lot)) = 0.11.2 Provides: bundled(crate(parking_lot_core)) = 0.8.6 @@ -129,9 +129,9 @@ Provides: bundled(crate(paste)) = 0.1.18 Provides: bundled(crate(paste-impl)) = 0.1.18 Provides: bundled(crate(pin-project-lite)) = 0.2.14 Provides: bundled(crate(pkg-config)) = 0.3.30 -Provides: bundled(crate(ppv-lite86)) = 0.2.17 +Provides: bundled(crate(ppv-lite86)) = 0.2.18 Provides: bundled(crate(proc-macro-hack)) = 0.5.20+deprecated -Provides: bundled(crate(proc-macro2)) = 1.0.82 +Provides: bundled(crate(proc-macro2)) = 1.0.86 Provides: bundled(crate(quote)) = 1.0.36 Provides: bundled(crate(rand)) = 0.8.5 Provides: bundled(crate(rand_chacha)) = 0.3.1 @@ -141,38 +141,40 @@ Provides: bundled(crate(rustc-demangle)) = 0.1.24 Provides: bundled(crate(rustix)) = 0.38.34 Provides: bundled(crate(ryu)) = 1.0.18 Provides: bundled(crate(scopeguard)) = 1.2.0 -Provides: bundled(crate(serde)) = 1.0.202 -Provides: bundled(crate(serde_derive)) = 1.0.202 -Provides: bundled(crate(serde_json)) = 1.0.117 +Provides: bundled(crate(serde)) = 1.0.204 +Provides: bundled(crate(serde_derive)) = 1.0.204 +Provides: bundled(crate(serde_json)) = 1.0.121 Provides: bundled(crate(smallvec)) = 1.13.2 Provides: bundled(crate(strsim)) = 0.10.0 -Provides: bundled(crate(syn)) = 2.0.63 +Provides: bundled(crate(syn)) = 2.0.72 Provides: bundled(crate(tempfile)) = 3.10.1 Provides: bundled(crate(termcolor)) = 1.4.1 Provides: bundled(crate(textwrap)) = 0.16.1 -Provides: bundled(crate(tokio)) = 1.37.0 -Provides: bundled(crate(tokio-macros)) = 2.2.0 +Provides: bundled(crate(tokio)) = 1.39.2 +Provides: bundled(crate(tokio-macros)) = 2.4.0 Provides: bundled(crate(toml)) = 0.5.11 Provides: bundled(crate(unicode-ident)) = 1.0.12 Provides: bundled(crate(uuid)) = 0.8.2 Provides: bundled(crate(vcpkg)) = 0.2.15 -Provides: bundled(crate(version_check)) = 0.9.4 +Provides: bundled(crate(version_check)) = 0.9.5 Provides: bundled(crate(wasi)) = 0.11.0+wasi_snapshot_preview1 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(winapi-util)) = 0.1.8 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(windows-sys)) = 0.52.0 -Provides: bundled(crate(windows-targets)) = 0.52.5 -Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.52.5 -Provides: bundled(crate(windows_aarch64_msvc)) = 0.52.5 -Provides: bundled(crate(windows_i686_gnu)) = 0.52.5 -Provides: bundled(crate(windows_i686_gnullvm)) = 0.52.5 -Provides: bundled(crate(windows_i686_msvc)) = 0.52.5 -Provides: bundled(crate(windows_x86_64_gnu)) = 0.52.5 -Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.52.5 -Provides: bundled(crate(windows_x86_64_msvc)) = 0.52.5 -Provides: bundled(crate(zeroize)) = 1.7.0 +Provides: bundled(crate(windows-targets)) = 0.52.6 +Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.52.6 +Provides: bundled(crate(windows_aarch64_msvc)) = 0.52.6 +Provides: bundled(crate(windows_i686_gnu)) = 0.52.6 +Provides: bundled(crate(windows_i686_gnullvm)) = 0.52.6 +Provides: bundled(crate(windows_i686_msvc)) = 0.52.6 +Provides: bundled(crate(windows_x86_64_gnu)) = 0.52.6 +Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.52.6 +Provides: bundled(crate(windows_x86_64_msvc)) = 0.52.6 +Provides: bundled(crate(zerocopy)) = 0.6.6 +Provides: bundled(crate(zerocopy-derive)) = 0.6.6 +Provides: bundled(crate(zeroize)) = 1.8.1 Provides: bundled(crate(zeroize_derive)) = 1.4.2 Provides: bundled(npm(@aashutoshrathi/word-wrap)) = 1.2.6 Provides: bundled(npm(@eslint-community/eslint-utils)) = 4.4.0 @@ -485,8 +487,6 @@ Source4: 389-ds-base.sysusers %if %{with bundle_libdb} Source5: https://fedorapeople.org/groups/389ds/libdb-5.3.28-59.tar.bz2 %endif -# https://github.com/389ds/389-ds-base/pull/6235 -Patch0: 0001-rpm-fix-compatibility-with-RPM-4.20.patch %description 389 Directory Server is an LDAPv3 compliant server. The base package includes diff --git a/sources b/sources index 8e81e9f..2836d24 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 +SHA512 (389-ds-base-3.1.1.tar.bz2) = c6aa0aba9779bd4ed6768f140d255474bc5e02455e37db6e8273740e9be81ac90bcab4ea97e117af573cb1d3f56ddd59d063b7715d99261ebf2d497c2801bc41 SHA512 (libdb-5.3.28-59.tar.bz2) = 731a434fa2e6487ebb05c458b0437456eb9f7991284beb08cb3e21931e23bdeddddbc95bfabe3a2f9f029fe69cd33a2d4f0f5ce6a9811e9c3b940cb6fde4bf79 -SHA512 (389-ds-base-3.1.0.tar.bz2) = 7b471328ae9efe451d30d0f61bdf207dbce0b8094685132390196d45bda5e3cba29e025ce18e51cee9d8b84f685024208d38a2407e2d3c685bc5d8dfcb86d4ea From 9d411e6f983b8e7f3cab89e07a76a0c7a013ac33 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Tue, 30 Jul 2024 13:51:33 +0200 Subject: [PATCH 094/125] Replace lmdb with lmdb-libs in Requires --- 389-ds-base.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 66bec5a..2830311 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -460,7 +460,7 @@ Requires: cyrus-sasl-plain %if %{without bundle_libdb} Requires: libdb %endif -Requires: lmdb +Requires: lmdb-libs # Needed by logconv.pl %if %{without bundle_libdb} Requires: perl-DB_File From 6ee4494a7af4f23b93e200ec0e2e4b52d3014fa1 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Tue, 15 Oct 2024 13:21:47 +0200 Subject: [PATCH 095/125] Resolves: VLV errors in Fedora 40 with RSNv3 and pruning enabled (rhbz#2317851) --- ...DB-after-an-update-the-impact-VLV-in.patch | 48 +++++++++++++++++++ 389-ds-base.spec | 2 + 2 files changed, 50 insertions(+) create mode 100644 0001-Issue-6356-On-LMDB-after-an-update-the-impact-VLV-in.patch diff --git a/0001-Issue-6356-On-LMDB-after-an-update-the-impact-VLV-in.patch b/0001-Issue-6356-On-LMDB-after-an-update-the-impact-VLV-in.patch new file mode 100644 index 0000000..35a8b1f --- /dev/null +++ b/0001-Issue-6356-On-LMDB-after-an-update-the-impact-VLV-in.patch @@ -0,0 +1,48 @@ +From 145e7f4aa9d9cf400751a16768b077b533f428cc Mon Sep 17 00:00:00 2001 +From: tbordaz +Date: Wed, 9 Oct 2024 15:20:48 +0200 +Subject: [PATCH] Issue 6356 - On LMDB, after an update the impact VLV index, + the vlv recno cache is not systematically cleared (#6357) + +Bug description: + The VLV manages/uses an index database. + In LMDB in addition to the index there is one 'recno cache' database per VLV index. + This recno cache, related to a given VLV index, is cleared when an update impacts the VLV index. + The recno cache is not systematically cleared upon update of the VLV index. + + The way to clear the cache is to delete the record with key "OK". + When the 'recno cache' does not contain this key, the next + lookup to the cache, clears all entries and rebuild the cache + from the vlv index. + The deletion is done with mdb_del with both KEY and DATA + refering to the same mdb_val. This means it deletes the records + matching if both KEY/DATA. + It should not match the DATA as the "OK" record is just + a flag and all entries with that key should be removed. + +Fix description: + The fix consist to call mdb_del only with key + +fixes: #6356 + +Reviewed by: Pierre Rogier (Thanks!!) +--- + ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c +index 9c2db199c..313eb35ae 100644 +--- a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c ++++ b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c +@@ -2882,7 +2882,7 @@ dbmdb_public_clear_vlv_cache(Slapi_Backend *be, dbi_txn_t *txn, dbi_db_t *db) + ok.mv_size = 2; + rc = dbmdb_open_dbi_from_filename(&rcdbi, be, rcdbname, NULL, 0); + if (rc == 0) { +- rc = MDB_DEL(TXN(txn), rcdbi->dbi, &ok, &ok); ++ rc = MDB_DEL(TXN(txn), rcdbi->dbi, &ok, NULL); + } + slapi_ch_free_string(&rcdbname); + return rc; +-- +2.46.0 + diff --git a/389-ds-base.spec b/389-ds-base.spec index 2830311..ee4e553 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -488,6 +488,8 @@ Source4: 389-ds-base.sysusers Source5: https://fedorapeople.org/groups/389ds/libdb-5.3.28-59.tar.bz2 %endif +Patch1: 0001-Issue-6356-On-LMDB-after-an-update-the-impact-VLV-in.patch + %description 389 Directory Server is an LDAPv3 compliant server. The base package includes the LDAP server and command line utilities for server administration. From 0082bb49b0b97211bc5f21df5b75780d43ca7054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Such=C3=BD?= Date: Tue, 15 Oct 2024 06:56:22 +0000 Subject: [PATCH 096/125] Add exception to GPL license in license tag See https://gitlab.com/fedora/legal/fedora-license-data/-/issues/517 --- 389-ds-base.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index ee4e553..3156d65 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -68,7 +68,7 @@ Summary: 389 Directory Server (%{variant}) Name: 389-ds-base Version: 3.1.1 Release: %{autorelease -n %{?with_asan:-e asan}}%{?dist} -License: GPL-3.0-or-later AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-DFS-2016 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0 +License: GPL-3.0-or-later WITH GPL-3.0-389-ds-base-exception AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-DFS-2016 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0 URL: https://www.port389.org Obsoletes: %{name}-legacy-tools < 1.4.4.6 Obsoletes: %{name}-legacy-tools-debuginfo < 1.4.4.6 From fc8a2a3a6f826df44641b3d216e000fd81a49bf5 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Wed, 30 Oct 2024 11:46:51 +0100 Subject: [PATCH 097/125] Fix source URL --- 389-ds-base.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 3156d65..ea384af 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -478,7 +478,7 @@ Requires: zlib-devel # Picks up our systemd deps. %{?systemd_requires} -Source0: %{name}-%{version}.tar.bz2 +Source0: https://github.com/389ds/389-ds-base/releases/download/%{name}-%{version}/%{name}-%{version}.tar.bz2 Source2: %{name}-devel.README %if %{with bundle_jemalloc} Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download/%{jemalloc_ver}/%{jemalloc_name}-%{jemalloc_ver}.tar.bz2 From cc3b929de3e7dee73e7642d7bbf2b04418ef1ffe Mon Sep 17 00:00:00 2001 From: Pete Walter Date: Sun, 8 Dec 2024 22:02:34 +0000 Subject: [PATCH 098/125] Rebuild for ICU 76 From 409e247670d7d54ba2a554ef25b5e7df6378a1fb Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 16 Jan 2025 08:19:55 +0000 Subject: [PATCH 099/125] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild From 16dbfc769e31172cbdd174264448335c31cfce3d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Mon, 20 Jan 2025 07:16:14 +0000 Subject: [PATCH 100/125] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild From c0a85dde2d1f39e0523e236bf723f9fcd6f37591 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Fri, 24 Jan 2025 09:28:21 +0100 Subject: [PATCH 101/125] Update to 3.1.2 --- .gitignore | 232 +-------------- ...DB-after-an-update-the-impact-VLV-in.patch | 48 --- 389-ds-base.spec | 274 ++++++++++-------- sources | 2 +- 4 files changed, 152 insertions(+), 404 deletions(-) delete mode 100644 0001-Issue-6356-On-LMDB-after-an-update-the-impact-VLV-in.patch diff --git a/.gitignore b/.gitignore index 5b59f1d..18ea466 100644 --- a/.gitignore +++ b/.gitignore @@ -1,232 +1,4 @@ *~ -/389-ds-base-1.2.7.2.tar.bz2 -/389-ds-base-1.2.7.3.tar.bz2 -/389-ds-base-1.2.7.4.tar.bz2 -/389-ds-base-1.2.7.5.tar.bz2 -/389-ds-base-1.2.8.a1.tar.bz2 -/389-ds-base-1.2.8.a2.tar.bz2 -/389-ds-base-1.2.8.a3.tar.bz2 -/389-ds-base-1.2.8.rc1.tar.bz2 -/389-ds-base-1.2.8.rc2.tar.bz2 -/389-ds-base-1.2.8.rc4.tar.bz2 -/389-ds-base-1.2.8.rc5.tar.bz2 -/389-ds-base-1.2.8.0.tar.bz2 -/389-ds-base-1.2.8.1.tar.bz2 -/389-ds-base-1.2.8.2.tar.bz2 -/389-ds-base-1.2.8.3.tar.bz2 -/389-ds-base-1.2.9.a1.tar.bz2 -/389-ds-base-1.2.9.a2.tar.bz2 -/389-ds-base-1.2.9.0.tar.bz2 -/389-ds-base-1.2.9.1.tar.bz2 -/389-ds-base-1.2.9.2.tar.bz2 -/389-ds-base-1.2.9.3.tar.bz2 -/389-ds-base-1.2.9.4.tar.bz2 -/389-ds-base-1.2.9.5.tar.bz2 -/389-ds-base-1.2.9.6.tar.bz2 -/389-ds-base-1.2.9.7.tar.bz2 -/389-ds-base-1.2.9.8.tar.bz2 -/389-ds-base-1.2.9.9.tar.bz2 -/389-ds-base-1.2.9.10.tar.bz2 -/389-ds-base-1.2.10.a1.tar.bz2 -/389-ds-base-1.2.10.a2.tar.bz2 -/389-ds-base-1.2.10.a3.tar.bz2 -/389-ds-base-1.2.10.a4.tar.bz2 -/389-ds-base-1.2.10.a5.tar.bz2 -/389-ds-base-1.2.10.a6.tar.bz2 -/389-ds-base-1.2.10.a7.tar.bz2 -/389-ds-base-1.2.10.a8.tar.bz2 -/389-ds-base-1.2.10.rc1.tar.bz2 -/389-ds-base-1.2.10.0.tar.bz2 -/389-ds-base-1.2.10.1.tar.bz2 -/389-ds-base-1.2.10.2.tar.bz2 -/389-ds-base-1.2.10.3.tar.bz2 -/389-ds-base-1.2.10.4.tar.bz2 -/389-ds-base-1.2.11.a1.tar.bz2 -/389-ds-base-1.2.11.1.tar.bz2 -/389-ds-base-1.2.11.2.tar.bz2 -/389-ds-base-1.2.11.3.tar.bz2 -/389-ds-base-1.2.11.4.tar.bz2 -/389-ds-base-1.2.11.5.tar.bz2 -/389-ds-base-1.2.11.6.tar.bz2 -/389-ds-base-1.2.11.7.tar.bz2 -/389-ds-base-1.2.11.8.tar.bz2 -/389-ds-base-1.2.11.9.tar.bz2 -/389-ds-base-1.2.11.10.tar.bz2 -/389-ds-base-1.2.11.11.tar.bz2 -/389-ds-base-1.2.11.12.tar.bz2 -/389-ds-base-1.2.11.13.tar.bz2 -/389-ds-base-1.2.11.14.tar.bz2 -/389-ds-base-1.2.11.15.tar.bz2 -/389-ds-base-1.3.0.a1.tar.bz2 -/389-ds-base-1.3.0.rc1.tar.bz2 -/389-ds-base-1.3.0.rc2.tar.bz2 -/389-ds-base-1.3.0.rc3.tar.bz2 -/389-ds-base-1.3.0.0.tar.bz2 -/389-ds-base-1.3.0.1.tar.bz2 -/389-ds-base-1.3.0.2.tar.bz2 -/389-ds-base-1.3.0.3.tar.bz2 -/389-ds-base-1.3.0.4.tar.bz2 -/389-ds-base-1.3.0.5.tar.bz2 -/389-ds-base-1.3.1.0.tar.bz2 -/389-ds-base-1.3.1.1.tar.bz2 -/389-ds-base-1.3.1.2.tar.bz2 -/389-ds-base-1.3.1.3.tar.bz2 -/389-ds-base-1.3.1.4.tar.bz2 -/389-ds-base-1.3.1.5.tar.bz2 -/389-ds-base-1.3.1.6.tar.bz2 -/389-ds-base-1.3.1.7.tar.bz2 -/389-ds-base-1.3.1.8.tar.bz2 -/389-ds-base-1.3.1.9.tar.bz2 -/389-ds-base-1.3.1.10.tar.bz2 -/389-ds-base-1.3.1.11.tar.bz2 -/389-ds-base-1.3.2.0.tar.bz2 -/389-ds-base-1.3.2.1.tar.bz2 -/389-ds-base-1.3.2.2.tar.bz2 -/389-ds-base-1.3.2.3.tar.bz2 -/389-ds-base-1.3.2.4.tar.bz2 -/389-ds-base-1.3.2.5.tar.bz2 -/389-ds-base-1.3.2.6.tar.bz2 -/389-ds-base-1.3.2.7.tar.bz2 -/389-ds-base-1.3.2.8.tar.bz2 -/389-ds-base-1.3.2.9.tar.bz2 -/389-ds-base-1.3.2.10.tar.bz2 -/389-ds-base-1.3.2.11.tar.bz2 -/389-ds-base-1.3.2.12.tar.bz2 -/389-ds-base-1.3.2.13.tar.bz2 -/389-ds-base-1.3.2.14.tar.bz2 -/389-ds-base-1.3.2.15.tar.bz2 -/389-ds-base-1.3.2.16.tar.bz2 -/389-ds-base-1.3.2.17.tar.bz2 -/389-ds-base-1.3.2.18.tar.bz2 -/389-ds-base-1.3.2.19.tar.bz2 -/389-ds-base-1.3.2.20.tar.bz2 -/389-ds-base-1.3.2.21.tar.bz2 -/389-ds-base-1.3.2.22.tar.bz2 -/389-ds-base-1.3.2.23.tar.bz2 -/389-ds-base-1.3.3.0.tar.bz2 -/389-ds-base-1.3.3.2.tar.bz2 -/389-ds-base-1.3.3.3.tar.bz2 -/389-ds-base-1.3.3.4.tar.bz2 -/389-ds-base-1.3.3.5.tar.bz2 -/389-ds-base-1.3.3.6.tar.bz2 -/389-ds-base-1.3.3.7.tar.bz2 -/389-ds-base-1.3.3.8.tar.bz2 -/389-ds-base-1.3.3.9.tar.bz2 -/389-ds-base-1.3.3.10.tar.bz2 -/389-ds-base-1.3.3.11.tar.bz2 -/389-ds-base-1.3.3.12.tar.bz2 -/389-ds-base-1.3.4.0.tar.bz2 -/nunc-stans-0.1.3.tar.bz2 -/nunc-stans-0.1.4.tar.bz2 -/389-ds-base-1.3.4.1.tar.bz2 -/nunc-stans-0.1.5.tar.bz2 -/389-ds-base-1.3.4.2.tar.bz2 -/389-ds-base-1.3.4.3.tar.bz2 -/389-ds-base-1.3.4.4.tar.bz2 -/389-ds-base-1.3.4.5.tar.bz2 -/389-ds-base-1.3.4.6.tar.bz2 -/389-ds-base-1.3.4.7.tar.bz2 -/389-ds-base-1.3.4.8.tar.bz2 -/389-ds-base-1.3.5.0.tar.bz2 -/nunc-stans-0.1.8.tar.bz2 -/389-ds-base-1.3.5.1.tar.bz2 -/389-ds-base-1.3.5.3.tar.bz2 -/389-ds-base-1.3.5.4.tar.bz2 -/389-ds-base-1.3.5.5.tar.bz2 -/389-ds-base-1.3.5.6.tar.bz2 -/389-ds-base-1.3.5.10.tar.bz2 -/389-ds-base-1.3.5.11.tar.bz2 -/389-ds-base-1.3.5.12.tar.bz2 -/389-ds-base-1.3.5.13.tar.bz2 -/389-ds-base-1.3.5.14.tar.bz2 -/nunc-stans-0.2.0.tar.bz2 -/389-ds-base-1.3.6.1.tar.bz2 -/389-ds-base-1.3.6.2.tar.bz2 -/389-ds-base-1.3.6.3.tar.bz2 -/389-ds-base-1.3.6.4.tar.bz2 -/389-ds-base-1.3.6.5.tar.bz2 -/389-ds-base-1.3.6.6.tar.bz2 -/389-ds-base-1.3.7.1.tar.bz2 -/389-ds-base-1.3.7.2.tar.bz2 -/389-ds-base-1.3.7.3.tar.bz2 -/389-ds-base-1.3.7.4.tar.bz2 -/389-ds-base-1.4.0.0.tar.bz2 -/389-ds-base-1.4.0.1.tar.bz2 -/389-ds-base-1.4.0.2.tar.bz2 -/389-ds-base-1.4.0.3.tar.bz2 -/389-ds-base-1.4.0.4.tar.bz2 -/389-ds-base-1.4.0.5.tar.bz2 -/389-ds-base-1.4.0.6.tar.bz2 -/389-ds-base-1.4.0.7.tar.bz2 -/389-ds-base-1.4.0.8.tar.bz2 -/389-ds-base-1.4.0.9.tar.bz2 -/389-ds-base-1.4.0.10.tar.bz2 -/jemalloc-5.0.1.tar.bz2 -/389-ds-base-1.4.0.11.tar.bz2 -/jemalloc-5.1.0.tar.bz2 -/389-ds-base-1.4.0.12.tar.bz2 -/389-ds-base-1.4.0.13.tar.bz2 -/389-ds-base-1.4.0.14.tar.bz2 -/389-ds-base-1.4.0.15.tar.bz2 -/389-ds-base-1.4.0.16.tar.bz2 -/389-ds-base-1.4.0.17.tar.bz2 -/389-ds-base-1.4.0.18.tar.bz2 -/389-ds-base-1.4.0.19.tar.bz2 -/389-ds-base-1.4.0.20.tar.bz2 -/389-ds-base-1.4.1.1.tar.bz2 -/389-ds-base-1.4.1.2.tar.bz2 -/389-ds-base-1.4.1.3.tar.bz2 -/389-ds-base-1.4.1.4.tar.bz2 -/389-ds-base-1.4.1.5.tar.bz2 -/jemalloc-5.2.0.tar.bz2 -/389-ds-base-1.4.1.6.tar.bz2 -/389-ds-base-1.4.2.1.tar.bz2 -/389-ds-base-1.4.2.2.tar.bz2 -/389-ds-base-1.4.2.3.tar.bz2 -/389-ds-base-1.4.2.4.tar.bz2 -/389-ds-base-1.4.2.5.tar.bz2 -/389-ds-base-1.4.3.1.tar.bz2 -/jemalloc-5.2.1.tar.bz2 -/389-ds-base-1.4.3.2.tar.bz2 -/389-ds-base-1.4.3.3.tar.bz2 -/389-ds-base-1.4.3.4.tar.bz2 -/389-ds-base-1.4.3.5.tar.bz2 -/389-ds-base-1.4.4.0.tar.bz2 -/389-ds-base-1.4.4.1.tar.bz2 -/389-ds-base-1.4.4.2.tar.bz2 -/389-ds-base-1.4.4.3.tar.bz2 -/389-ds-base-1.4.4.4.tar.bz2 -/389-ds-base-1.4.4.6.tar.bz2 -/389-ds-base-1.4.5.0.tar.bz2 -/389-ds-base-2.0.1.tar.bz2 -/389-ds-base-2.0.2.tar.bz2 -/389-ds-base-2.0.3.tar.bz2 -/389-ds-base-2.0.4.tar.bz2 -/389-ds-base-2.0.4.3.tar.bz2 -/389-ds-base-2.0.5.tar.bz2 -/389-ds-base-2.0.6.tar.bz2 -/389-ds-base-2.0.7.tar.bz2 -/389-ds-base-2.0.10.tar.bz2 -/389-ds-base-2.0.11.tar.bz2 -/389-ds-base-2.0.12.tar.bz2 -/389-ds-base-2.0.13.tar.bz2 -/389-ds-base-2.1.0.tar.bz2 -/389-ds-base-2.2.0.tar.bz2 -/389-ds-base-2.1.1.tar.bz2 -/jemalloc-5.3.0.tar.bz2 -/389-ds-base-2.2.1.tar.bz2 -/389-ds-base-2.2.2.tar.bz2 -/389-ds-base-2.3.0.tar.bz2 -/389-ds-base-2.3.1.tar.bz2 -/389-ds-base-2.3.2.tar.bz2 -/389-ds-base-2.4.0.tar.bz2 -/389-ds-base-2.4.1.tar.bz2 -/389-ds-base-2.4.2.tar.bz2 -/389-ds-base-2.4.3.tar.bz2 -/389-ds-base-2.4.4.tar.bz2 -/389-ds-base-2.4.5.tar.bz2 -/389-ds-base-3.0.1.tar.bz2 -/389-ds-base-3.0.2.tar.bz2 -/389-ds-base-3.1.0.tar.bz2 +/389-ds-base-*.tar.bz2 +/jemalloc-*.tar.bz2 /libdb-5.3.28-59.tar.bz2 -/389-ds-base-3.1.1.tar.bz2 diff --git a/0001-Issue-6356-On-LMDB-after-an-update-the-impact-VLV-in.patch b/0001-Issue-6356-On-LMDB-after-an-update-the-impact-VLV-in.patch deleted file mode 100644 index 35a8b1f..0000000 --- a/0001-Issue-6356-On-LMDB-after-an-update-the-impact-VLV-in.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 145e7f4aa9d9cf400751a16768b077b533f428cc Mon Sep 17 00:00:00 2001 -From: tbordaz -Date: Wed, 9 Oct 2024 15:20:48 +0200 -Subject: [PATCH] Issue 6356 - On LMDB, after an update the impact VLV index, - the vlv recno cache is not systematically cleared (#6357) - -Bug description: - The VLV manages/uses an index database. - In LMDB in addition to the index there is one 'recno cache' database per VLV index. - This recno cache, related to a given VLV index, is cleared when an update impacts the VLV index. - The recno cache is not systematically cleared upon update of the VLV index. - - The way to clear the cache is to delete the record with key "OK". - When the 'recno cache' does not contain this key, the next - lookup to the cache, clears all entries and rebuild the cache - from the vlv index. - The deletion is done with mdb_del with both KEY and DATA - refering to the same mdb_val. This means it deletes the records - matching if both KEY/DATA. - It should not match the DATA as the "OK" record is just - a flag and all entries with that key should be removed. - -Fix description: - The fix consist to call mdb_del only with key - -fixes: #6356 - -Reviewed by: Pierre Rogier (Thanks!!) ---- - ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c -index 9c2db199c..313eb35ae 100644 ---- a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c -+++ b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c -@@ -2882,7 +2882,7 @@ dbmdb_public_clear_vlv_cache(Slapi_Backend *be, dbi_txn_t *txn, dbi_db_t *db) - ok.mv_size = 2; - rc = dbmdb_open_dbi_from_filename(&rcdbi, be, rcdbname, NULL, 0); - if (rc == 0) { -- rc = MDB_DEL(TXN(txn), rcdbi->dbi, &ok, &ok); -+ rc = MDB_DEL(TXN(txn), rcdbi->dbi, &ok, NULL); - } - slapi_ch_free_string(&rcdbname); - return rc; --- -2.46.0 - diff --git a/389-ds-base.spec b/389-ds-base.spec index ea384af..2205ae3 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -66,103 +66,104 @@ ExcludeArch: i686 Summary: 389 Directory Server (%{variant}) Name: 389-ds-base -Version: 3.1.1 +Version: 3.1.2 Release: %{autorelease -n %{?with_asan:-e asan}}%{?dist} -License: GPL-3.0-or-later WITH GPL-3.0-389-ds-base-exception AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-DFS-2016 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0 +License: GPL-3.0-or-later WITH GPL-3.0-389-ds-base-exception AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSD-2-Clause OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-3.0 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0 URL: https://www.port389.org Obsoletes: %{name}-legacy-tools < 1.4.4.6 Obsoletes: %{name}-legacy-tools-debuginfo < 1.4.4.6 Provides: ldif2ldbm >= 0 ##### Bundled cargo crates list - START ##### -Provides: bundled(crate(addr2line)) = 0.22.0 -Provides: bundled(crate(adler)) = 1.0.2 +Provides: bundled(crate(addr2line)) = 0.24.2 +Provides: bundled(crate(adler2)) = 2.0.0 Provides: bundled(crate(ahash)) = 0.7.8 Provides: bundled(crate(atty)) = 0.2.14 -Provides: bundled(crate(autocfg)) = 1.3.0 -Provides: bundled(crate(backtrace)) = 0.3.73 +Provides: bundled(crate(autocfg)) = 1.4.0 +Provides: bundled(crate(backtrace)) = 0.3.74 Provides: bundled(crate(base64)) = 0.13.1 -Provides: bundled(crate(bitflags)) = 2.6.0 +Provides: bundled(crate(bitflags)) = 2.8.0 Provides: bundled(crate(byteorder)) = 1.5.0 Provides: bundled(crate(cbindgen)) = 0.26.0 -Provides: bundled(crate(cc)) = 1.1.7 +Provides: bundled(crate(cc)) = 1.2.10 Provides: bundled(crate(cfg-if)) = 1.0.0 Provides: bundled(crate(clap)) = 3.2.25 Provides: bundled(crate(clap_lex)) = 0.2.4 Provides: bundled(crate(concread)) = 0.2.21 Provides: bundled(crate(crossbeam)) = 0.8.4 -Provides: bundled(crate(crossbeam-channel)) = 0.5.13 -Provides: bundled(crate(crossbeam-deque)) = 0.8.5 +Provides: bundled(crate(crossbeam-channel)) = 0.5.14 +Provides: bundled(crate(crossbeam-deque)) = 0.8.6 Provides: bundled(crate(crossbeam-epoch)) = 0.9.18 -Provides: bundled(crate(crossbeam-queue)) = 0.3.11 -Provides: bundled(crate(crossbeam-utils)) = 0.8.20 -Provides: bundled(crate(errno)) = 0.3.9 -Provides: bundled(crate(fastrand)) = 2.1.0 +Provides: bundled(crate(crossbeam-queue)) = 0.3.12 +Provides: bundled(crate(crossbeam-utils)) = 0.8.21 +Provides: bundled(crate(errno)) = 0.3.10 +Provides: bundled(crate(fastrand)) = 2.3.0 Provides: bundled(crate(fernet)) = 0.1.4 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 Provides: bundled(crate(getrandom)) = 0.2.15 -Provides: bundled(crate(gimli)) = 0.29.0 +Provides: bundled(crate(gimli)) = 0.31.1 Provides: bundled(crate(hashbrown)) = 0.12.3 Provides: bundled(crate(heck)) = 0.4.1 Provides: bundled(crate(hermit-abi)) = 0.1.19 Provides: bundled(crate(indexmap)) = 1.9.3 Provides: bundled(crate(instant)) = 0.1.13 -Provides: bundled(crate(itoa)) = 1.0.11 +Provides: bundled(crate(itoa)) = 1.0.14 Provides: bundled(crate(jobserver)) = 0.1.32 -Provides: bundled(crate(libc)) = 0.2.155 -Provides: bundled(crate(linux-raw-sys)) = 0.4.14 +Provides: bundled(crate(libc)) = 0.2.169 +Provides: bundled(crate(linux-raw-sys)) = 0.4.15 Provides: bundled(crate(lock_api)) = 0.4.12 -Provides: bundled(crate(log)) = 0.4.22 +Provides: bundled(crate(log)) = 0.4.25 Provides: bundled(crate(lru)) = 0.7.8 Provides: bundled(crate(memchr)) = 2.7.4 -Provides: bundled(crate(miniz_oxide)) = 0.7.4 -Provides: bundled(crate(object)) = 0.36.2 -Provides: bundled(crate(once_cell)) = 1.19.0 -Provides: bundled(crate(openssl)) = 0.10.66 +Provides: bundled(crate(miniz_oxide)) = 0.8.3 +Provides: bundled(crate(object)) = 0.36.7 +Provides: bundled(crate(once_cell)) = 1.20.2 +Provides: bundled(crate(openssl)) = 0.10.68 Provides: bundled(crate(openssl-macros)) = 0.1.1 -Provides: bundled(crate(openssl-sys)) = 0.9.103 +Provides: bundled(crate(openssl-sys)) = 0.9.104 Provides: bundled(crate(os_str_bytes)) = 6.6.1 Provides: bundled(crate(parking_lot)) = 0.11.2 Provides: bundled(crate(parking_lot_core)) = 0.8.6 Provides: bundled(crate(paste)) = 0.1.18 Provides: bundled(crate(paste-impl)) = 0.1.18 -Provides: bundled(crate(pin-project-lite)) = 0.2.14 -Provides: bundled(crate(pkg-config)) = 0.3.30 -Provides: bundled(crate(ppv-lite86)) = 0.2.18 +Provides: bundled(crate(pin-project-lite)) = 0.2.16 +Provides: bundled(crate(pkg-config)) = 0.3.31 +Provides: bundled(crate(ppv-lite86)) = 0.2.20 Provides: bundled(crate(proc-macro-hack)) = 0.5.20+deprecated -Provides: bundled(crate(proc-macro2)) = 1.0.86 -Provides: bundled(crate(quote)) = 1.0.36 +Provides: bundled(crate(proc-macro2)) = 1.0.93 +Provides: bundled(crate(quote)) = 1.0.38 Provides: bundled(crate(rand)) = 0.8.5 Provides: bundled(crate(rand_chacha)) = 0.3.1 Provides: bundled(crate(rand_core)) = 0.6.4 Provides: bundled(crate(redox_syscall)) = 0.2.16 Provides: bundled(crate(rustc-demangle)) = 0.1.24 -Provides: bundled(crate(rustix)) = 0.38.34 +Provides: bundled(crate(rustix)) = 0.38.44 Provides: bundled(crate(ryu)) = 1.0.18 Provides: bundled(crate(scopeguard)) = 1.2.0 -Provides: bundled(crate(serde)) = 1.0.204 -Provides: bundled(crate(serde_derive)) = 1.0.204 -Provides: bundled(crate(serde_json)) = 1.0.121 +Provides: bundled(crate(serde)) = 1.0.217 +Provides: bundled(crate(serde_derive)) = 1.0.217 +Provides: bundled(crate(serde_json)) = 1.0.137 +Provides: bundled(crate(shlex)) = 1.3.0 Provides: bundled(crate(smallvec)) = 1.13.2 Provides: bundled(crate(strsim)) = 0.10.0 -Provides: bundled(crate(syn)) = 2.0.72 -Provides: bundled(crate(tempfile)) = 3.10.1 +Provides: bundled(crate(syn)) = 2.0.96 +Provides: bundled(crate(tempfile)) = 3.15.0 Provides: bundled(crate(termcolor)) = 1.4.1 Provides: bundled(crate(textwrap)) = 0.16.1 -Provides: bundled(crate(tokio)) = 1.39.2 -Provides: bundled(crate(tokio-macros)) = 2.4.0 +Provides: bundled(crate(tokio)) = 1.43.0 +Provides: bundled(crate(tokio-macros)) = 2.5.0 Provides: bundled(crate(toml)) = 0.5.11 -Provides: bundled(crate(unicode-ident)) = 1.0.12 +Provides: bundled(crate(unicode-ident)) = 1.0.15 Provides: bundled(crate(uuid)) = 0.8.2 Provides: bundled(crate(vcpkg)) = 0.2.15 Provides: bundled(crate(version_check)) = 0.9.5 Provides: bundled(crate(wasi)) = 0.11.0+wasi_snapshot_preview1 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 -Provides: bundled(crate(winapi-util)) = 0.1.8 +Provides: bundled(crate(winapi-util)) = 0.1.9 Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0 -Provides: bundled(crate(windows-sys)) = 0.52.0 +Provides: bundled(crate(windows-sys)) = 0.59.0 Provides: bundled(crate(windows-targets)) = 0.52.6 Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.52.6 Provides: bundled(crate(windows_aarch64_msvc)) = 0.52.6 @@ -172,48 +173,51 @@ Provides: bundled(crate(windows_i686_msvc)) = 0.52.6 Provides: bundled(crate(windows_x86_64_gnu)) = 0.52.6 Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.52.6 Provides: bundled(crate(windows_x86_64_msvc)) = 0.52.6 -Provides: bundled(crate(zerocopy)) = 0.6.6 -Provides: bundled(crate(zerocopy-derive)) = 0.6.6 +Provides: bundled(crate(zerocopy)) = 0.7.35 +Provides: bundled(crate(zerocopy-derive)) = 0.7.35 Provides: bundled(crate(zeroize)) = 1.8.1 Provides: bundled(crate(zeroize_derive)) = 1.4.2 -Provides: bundled(npm(@aashutoshrathi/word-wrap)) = 1.2.6 -Provides: bundled(npm(@eslint-community/eslint-utils)) = 4.4.0 -Provides: bundled(npm(@eslint-community/regexpp)) = 4.5.1 -Provides: bundled(npm(@eslint/eslintrc)) = 2.0.3 -Provides: bundled(npm(@eslint/js)) = 8.42.0 +Provides: bundled(npm(@eslint-community/eslint-utils)) = 4.4.1 +Provides: bundled(npm(@eslint-community/regexpp)) = 4.12.1 +Provides: bundled(npm(@eslint/eslintrc)) = 2.1.4 +Provides: bundled(npm(@eslint/js)) = 8.57.1 Provides: bundled(npm(@fortawesome/fontawesome-common-types)) = 0.2.36 Provides: bundled(npm(@fortawesome/fontawesome-svg-core)) = 1.2.36 Provides: bundled(npm(@fortawesome/free-solid-svg-icons)) = 5.15.4 Provides: bundled(npm(@fortawesome/react-fontawesome)) = 0.1.19 -Provides: bundled(npm(@humanwhocodes/config-array)) = 0.11.10 +Provides: bundled(npm(@humanwhocodes/config-array)) = 0.13.0 Provides: bundled(npm(@humanwhocodes/module-importer)) = 1.0.1 -Provides: bundled(npm(@humanwhocodes/object-schema)) = 1.2.1 +Provides: bundled(npm(@humanwhocodes/object-schema)) = 2.0.3 Provides: bundled(npm(@nodelib/fs.scandir)) = 2.1.5 Provides: bundled(npm(@nodelib/fs.stat)) = 2.0.5 Provides: bundled(npm(@nodelib/fs.walk)) = 1.2.8 -Provides: bundled(npm(@patternfly/patternfly)) = 4.224.2 -Provides: bundled(npm(@patternfly/react-charts)) = 6.94.19 -Provides: bundled(npm(@patternfly/react-core)) = 4.276.8 -Provides: bundled(npm(@patternfly/react-icons)) = 4.93.6 -Provides: bundled(npm(@patternfly/react-styles)) = 4.92.6 -Provides: bundled(npm(@patternfly/react-table)) = 4.113.0 -Provides: bundled(npm(@patternfly/react-tokens)) = 4.94.6 -Provides: bundled(npm(@types/d3-array)) = 3.0.5 -Provides: bundled(npm(@types/d3-color)) = 3.1.0 -Provides: bundled(npm(@types/d3-ease)) = 3.0.0 -Provides: bundled(npm(@types/d3-interpolate)) = 3.0.1 -Provides: bundled(npm(@types/d3-path)) = 3.0.0 -Provides: bundled(npm(@types/d3-scale)) = 4.0.3 -Provides: bundled(npm(@types/d3-shape)) = 3.1.1 -Provides: bundled(npm(@types/d3-time)) = 3.0.0 -Provides: bundled(npm(@types/d3-timer)) = 3.0.0 -Provides: bundled(npm(acorn)) = 8.8.2 +Provides: bundled(npm(@patternfly/patternfly)) = 5.4.1 +Provides: bundled(npm(@patternfly/react-charts)) = 7.4.3 +Provides: bundled(npm(@patternfly/react-core)) = 5.4.1 +Provides: bundled(npm(@patternfly/react-icons)) = 5.4.0 +Provides: bundled(npm(@patternfly/react-styles)) = 5.4.0 +Provides: bundled(npm(@patternfly/react-table)) = 5.4.1 +Provides: bundled(npm(@patternfly/react-tokens)) = 5.4.0 +Provides: bundled(npm(@types/d3-array)) = 3.2.1 +Provides: bundled(npm(@types/d3-color)) = 3.1.3 +Provides: bundled(npm(@types/d3-ease)) = 3.0.2 +Provides: bundled(npm(@types/d3-interpolate)) = 3.0.4 +Provides: bundled(npm(@types/d3-path)) = 3.1.0 +Provides: bundled(npm(@types/d3-scale)) = 4.0.8 +Provides: bundled(npm(@types/d3-shape)) = 3.1.6 +Provides: bundled(npm(@types/d3-time)) = 3.0.3 +Provides: bundled(npm(@types/d3-timer)) = 3.0.2 +Provides: bundled(npm(@ungap/structured-clone)) = 1.2.0 +Provides: bundled(npm(@xterm/addon-canvas)) = 0.7.0 +Provides: bundled(npm(@xterm/xterm)) = 5.5.0 +Provides: bundled(npm(acorn)) = 8.14.0 Provides: bundled(npm(acorn-jsx)) = 5.3.2 Provides: bundled(npm(ajv)) = 6.12.6 Provides: bundled(npm(ansi-regex)) = 5.0.1 Provides: bundled(npm(ansi-styles)) = 4.3.0 Provides: bundled(npm(argparse)) = 2.0.1 -Provides: bundled(npm(attr-accept)) = 1.1.3 +Provides: bundled(npm(attr-accept)) = 2.2.4 +Provides: bundled(npm(autolinker)) = 3.16.2 Provides: bundled(npm(balanced-match)) = 1.0.2 Provides: bundled(npm(brace-expansion)) = 1.1.11 Provides: bundled(npm(callsites)) = 3.1.0 @@ -221,8 +225,8 @@ Provides: bundled(npm(chalk)) = 4.1.2 Provides: bundled(npm(color-convert)) = 2.0.1 Provides: bundled(npm(color-name)) = 1.1.4 Provides: bundled(npm(concat-map)) = 0.0.1 -Provides: bundled(npm(core-js)) = 2.6.12 -Provides: bundled(npm(cross-spawn)) = 7.0.3 +Provides: bundled(npm(core-util-is)) = 1.0.3 +Provides: bundled(npm(cross-spawn)) = 7.0.6 Provides: bundled(npm(d3-array)) = 3.2.4 Provides: bundled(npm(d3-color)) = 3.1.0 Provides: bundled(npm(d3-ease)) = 3.0.1 @@ -234,42 +238,43 @@ Provides: bundled(npm(d3-shape)) = 3.2.0 Provides: bundled(npm(d3-time)) = 3.1.0 Provides: bundled(npm(d3-time-format)) = 4.1.0 Provides: bundled(npm(d3-timer)) = 3.0.1 -Provides: bundled(npm(debug)) = 4.3.4 +Provides: bundled(npm(debug)) = 4.3.7 Provides: bundled(npm(deep-is)) = 0.1.4 Provides: bundled(npm(delaunator)) = 4.0.1 Provides: bundled(npm(delaunay-find)) = 0.0.6 +Provides: bundled(npm(dequal)) = 2.0.3 Provides: bundled(npm(doctrine)) = 3.0.0 Provides: bundled(npm(encoding)) = 0.1.13 Provides: bundled(npm(escape-string-regexp)) = 4.0.0 -Provides: bundled(npm(eslint)) = 8.42.0 -Provides: bundled(npm(eslint-plugin-react-hooks)) = 4.6.0 -Provides: bundled(npm(eslint-scope)) = 7.2.0 -Provides: bundled(npm(eslint-visitor-keys)) = 3.4.1 -Provides: bundled(npm(espree)) = 9.5.2 -Provides: bundled(npm(esquery)) = 1.5.0 +Provides: bundled(npm(eslint)) = 8.57.1 +Provides: bundled(npm(eslint-plugin-react-hooks)) = 4.6.2 +Provides: bundled(npm(eslint-scope)) = 7.2.2 +Provides: bundled(npm(eslint-visitor-keys)) = 3.4.3 +Provides: bundled(npm(espree)) = 9.6.1 +Provides: bundled(npm(esquery)) = 1.6.0 Provides: bundled(npm(esrecurse)) = 4.3.0 Provides: bundled(npm(estraverse)) = 5.3.0 Provides: bundled(npm(esutils)) = 2.0.3 Provides: bundled(npm(fast-deep-equal)) = 3.1.3 Provides: bundled(npm(fast-json-stable-stringify)) = 2.1.0 Provides: bundled(npm(fast-levenshtein)) = 2.0.6 -Provides: bundled(npm(fastq)) = 1.15.0 +Provides: bundled(npm(fastq)) = 1.17.1 Provides: bundled(npm(file-entry-cache)) = 6.0.1 -Provides: bundled(npm(file-selector)) = 0.1.19 +Provides: bundled(npm(file-selector)) = 2.1.0 Provides: bundled(npm(find-up)) = 5.0.0 -Provides: bundled(npm(flat-cache)) = 3.0.4 -Provides: bundled(npm(flatted)) = 3.2.7 -Provides: bundled(npm(focus-trap)) = 6.9.2 +Provides: bundled(npm(flat-cache)) = 3.2.0 +Provides: bundled(npm(flatted)) = 3.3.1 +Provides: bundled(npm(focus-trap)) = 7.5.4 Provides: bundled(npm(fs.realpath)) = 1.0.0 -Provides: bundled(npm(gettext-parser)) = 2.0.0 +Provides: bundled(npm(gettext-parser)) = 2.1.0 Provides: bundled(npm(glob)) = 7.2.3 Provides: bundled(npm(glob-parent)) = 6.0.2 -Provides: bundled(npm(globals)) = 13.20.0 +Provides: bundled(npm(globals)) = 13.24.0 Provides: bundled(npm(graphemer)) = 1.4.0 Provides: bundled(npm(has-flag)) = 4.0.0 Provides: bundled(npm(hoist-non-react-statics)) = 3.3.2 Provides: bundled(npm(iconv-lite)) = 0.6.3 -Provides: bundled(npm(ignore)) = 5.2.4 +Provides: bundled(npm(ignore)) = 5.3.2 Provides: bundled(npm(import-fresh)) = 3.3.0 Provides: bundled(npm(imurmurhash)) = 0.1.4 Provides: bundled(npm(inflight)) = 1.0.6 @@ -278,82 +283,94 @@ Provides: bundled(npm(internmap)) = 2.0.3 Provides: bundled(npm(is-extglob)) = 2.1.1 Provides: bundled(npm(is-glob)) = 4.0.3 Provides: bundled(npm(is-path-inside)) = 3.0.3 +Provides: bundled(npm(isarray)) = 1.0.0 Provides: bundled(npm(isexe)) = 2.0.0 +Provides: bundled(npm(js-sha1)) = 0.7.0 +Provides: bundled(npm(js-sha256)) = 0.11.0 Provides: bundled(npm(js-tokens)) = 4.0.0 Provides: bundled(npm(js-yaml)) = 4.1.0 +Provides: bundled(npm(json-buffer)) = 3.0.1 Provides: bundled(npm(json-schema-traverse)) = 0.4.1 Provides: bundled(npm(json-stable-stringify-without-jsonify)) = 1.0.1 Provides: bundled(npm(json-stringify-safe)) = 5.0.1 +Provides: bundled(npm(keyv)) = 4.5.4 Provides: bundled(npm(levn)) = 0.4.1 Provides: bundled(npm(locate-path)) = 6.0.0 Provides: bundled(npm(lodash)) = 4.17.21 Provides: bundled(npm(lodash.merge)) = 4.6.2 Provides: bundled(npm(loose-envify)) = 1.4.0 Provides: bundled(npm(minimatch)) = 3.1.2 -Provides: bundled(npm(ms)) = 2.1.2 +Provides: bundled(npm(ms)) = 2.1.3 Provides: bundled(npm(natural-compare)) = 1.4.0 Provides: bundled(npm(object-assign)) = 4.1.1 Provides: bundled(npm(once)) = 1.4.0 -Provides: bundled(npm(optionator)) = 0.9.3 +Provides: bundled(npm(optionator)) = 0.9.4 Provides: bundled(npm(p-limit)) = 3.1.0 Provides: bundled(npm(p-locate)) = 5.0.0 Provides: bundled(npm(parent-module)) = 1.0.1 Provides: bundled(npm(path-exists)) = 4.0.0 Provides: bundled(npm(path-is-absolute)) = 1.0.1 Provides: bundled(npm(path-key)) = 3.1.1 -Provides: bundled(npm(popper.js)) = 1.16.1 Provides: bundled(npm(prelude-ls)) = 1.2.1 +Provides: bundled(npm(prettier)) = 3.3.3 +Provides: bundled(npm(process-nextick-args)) = 2.0.1 Provides: bundled(npm(prop-types)) = 15.8.1 -Provides: bundled(npm(prop-types-extra)) = 1.1.1 -Provides: bundled(npm(punycode)) = 2.3.0 +Provides: bundled(npm(punycode)) = 2.3.1 Provides: bundled(npm(queue-microtask)) = 1.2.3 -Provides: bundled(npm(react)) = 17.0.2 -Provides: bundled(npm(react-dom)) = 17.0.2 -Provides: bundled(npm(react-dropzone)) = 9.0.0 +Provides: bundled(npm(react)) = 18.3.1 +Provides: bundled(npm(react-dom)) = 18.3.1 +Provides: bundled(npm(react-dropzone)) = 14.3.5 Provides: bundled(npm(react-fast-compare)) = 3.2.2 Provides: bundled(npm(react-is)) = 16.13.1 +Provides: bundled(npm(readable-stream)) = 2.3.8 +Provides: bundled(npm(remarkable)) = 2.0.1 Provides: bundled(npm(resolve-from)) = 4.0.0 Provides: bundled(npm(reusify)) = 1.0.4 Provides: bundled(npm(rimraf)) = 3.0.2 Provides: bundled(npm(run-parallel)) = 1.2.0 Provides: bundled(npm(safe-buffer)) = 5.2.1 Provides: bundled(npm(safer-buffer)) = 2.1.2 -Provides: bundled(npm(scheduler)) = 0.20.2 +Provides: bundled(npm(scheduler)) = 0.23.2 Provides: bundled(npm(shebang-command)) = 2.0.0 Provides: bundled(npm(shebang-regex)) = 3.0.0 +Provides: bundled(npm(sprintf-js)) = 1.0.3 +Provides: bundled(npm(string_decoder)) = 1.1.1 Provides: bundled(npm(strip-ansi)) = 6.0.1 Provides: bundled(npm(strip-json-comments)) = 3.1.1 Provides: bundled(npm(supports-color)) = 7.2.0 -Provides: bundled(npm(tabbable)) = 5.3.3 +Provides: bundled(npm(tabbable)) = 6.2.0 Provides: bundled(npm(text-table)) = 0.2.0 -Provides: bundled(npm(tippy.js)) = 5.1.2 -Provides: bundled(npm(tslib)) = 2.5.3 +Provides: bundled(npm(throttle-debounce)) = 5.0.2 +Provides: bundled(npm(tslib)) = 2.8.1 Provides: bundled(npm(type-check)) = 0.4.0 Provides: bundled(npm(type-fest)) = 0.20.2 Provides: bundled(npm(uri-js)) = 4.4.1 -Provides: bundled(npm(victory-area)) = 36.6.10 -Provides: bundled(npm(victory-axis)) = 36.6.10 -Provides: bundled(npm(victory-bar)) = 36.6.10 -Provides: bundled(npm(victory-brush-container)) = 36.6.10 -Provides: bundled(npm(victory-chart)) = 36.6.10 -Provides: bundled(npm(victory-core)) = 36.6.10 -Provides: bundled(npm(victory-create-container)) = 36.6.10 -Provides: bundled(npm(victory-cursor-container)) = 36.6.10 -Provides: bundled(npm(victory-group)) = 36.6.10 -Provides: bundled(npm(victory-legend)) = 36.6.10 -Provides: bundled(npm(victory-line)) = 36.6.10 -Provides: bundled(npm(victory-pie)) = 36.6.10 -Provides: bundled(npm(victory-polar-axis)) = 36.6.10 -Provides: bundled(npm(victory-scatter)) = 36.6.10 -Provides: bundled(npm(victory-selection-container)) = 36.6.10 -Provides: bundled(npm(victory-shared-events)) = 36.6.10 -Provides: bundled(npm(victory-stack)) = 36.6.10 -Provides: bundled(npm(victory-tooltip)) = 36.6.10 -Provides: bundled(npm(victory-vendor)) = 36.6.10 -Provides: bundled(npm(victory-voronoi-container)) = 36.6.10 -Provides: bundled(npm(victory-zoom-container)) = 36.6.10 -Provides: bundled(npm(warning)) = 4.0.3 +Provides: bundled(npm(util-deprecate)) = 1.0.2 +Provides: bundled(npm(uuid)) = 10.0.0 +Provides: bundled(npm(victory-area)) = 37.3.1 +Provides: bundled(npm(victory-axis)) = 37.3.1 +Provides: bundled(npm(victory-bar)) = 37.3.1 +Provides: bundled(npm(victory-box-plot)) = 37.3.1 +Provides: bundled(npm(victory-brush-container)) = 37.3.1 +Provides: bundled(npm(victory-chart)) = 37.3.1 +Provides: bundled(npm(victory-core)) = 37.3.1 +Provides: bundled(npm(victory-create-container)) = 37.3.1 +Provides: bundled(npm(victory-cursor-container)) = 37.3.1 +Provides: bundled(npm(victory-group)) = 37.3.1 +Provides: bundled(npm(victory-legend)) = 37.3.1 +Provides: bundled(npm(victory-line)) = 37.3.1 +Provides: bundled(npm(victory-pie)) = 37.3.1 +Provides: bundled(npm(victory-polar-axis)) = 37.3.1 +Provides: bundled(npm(victory-scatter)) = 37.3.1 +Provides: bundled(npm(victory-selection-container)) = 37.3.1 +Provides: bundled(npm(victory-shared-events)) = 37.3.1 +Provides: bundled(npm(victory-stack)) = 37.3.1 +Provides: bundled(npm(victory-tooltip)) = 37.3.1 +Provides: bundled(npm(victory-vendor)) = 37.3.1 +Provides: bundled(npm(victory-voronoi-container)) = 37.3.1 +Provides: bundled(npm(victory-zoom-container)) = 37.3.1 Provides: bundled(npm(which)) = 2.0.2 +Provides: bundled(npm(word-wrap)) = 1.2.5 Provides: bundled(npm(wrappy)) = 1.0.2 Provides: bundled(npm(yocto-queue)) = 0.1.0 ##### Bundled cargo crates list - END ##### @@ -475,10 +492,12 @@ Requires: cracklib-dicts Requires: json-c # Log compression Requires: zlib-devel +# logconv.py, MIME type +Requires: python-magic # Picks up our systemd deps. %{?systemd_requires} -Source0: https://github.com/389ds/389-ds-base/releases/download/%{name}-%{version}/%{name}-%{version}.tar.bz2 +Source0: %{name}-%{version}.tar.bz2 Source2: %{name}-devel.README %if %{with bundle_jemalloc} Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download/%{jemalloc_ver}/%{jemalloc_name}-%{jemalloc_ver}.tar.bz2 @@ -488,8 +507,6 @@ Source4: 389-ds-base.sysusers Source5: https://fedorapeople.org/groups/389ds/libdb-5.3.28-59.tar.bz2 %endif -Patch1: 0001-Issue-6356-On-LMDB-after-an-update-the-impact-VLV-in.patch - %description 389 Directory Server is an LDAPv3 compliant server. The base package includes the LDAP server and command line utilities for server administration. @@ -614,7 +631,7 @@ A cockpit UI Plugin for configuring and administering the 389 Directory Server %endif %prep -%autosetup -p1 -v -n %{name}-%{version} +%autosetup -p1 -n %{name}-%{version} %if %{with bundle_jemalloc} %setup -q -n %{name}-%{version} -T -D -b 3 @@ -627,6 +644,8 @@ A cockpit UI Plugin for configuring and administering the 389 Directory Server cp %{SOURCE2} README.devel %build +# Workaround until https://github.com/389ds/389-ds-base/issues/6476 is fixed +export CFLAGS="%{optflags} -std=gnu17" %if %{with clang} CLANG_FLAGS="--enable-clang" @@ -680,7 +699,7 @@ pushd ../%{jemalloc_name}-%{jemalloc_ver} --libdir=%{_libdir}/%{pkgname}/lib \ --bindir=%{_libdir}/%{pkgname}/bin \ --enable-prof %{lg_page} %{lg_hugepage} -make %{?_smp_mflags} +%make_build popd %endif @@ -719,6 +738,9 @@ autoreconf -fiv %endif # lib389 +%if 0%{?fedora} >= 42 || 0%{?rhel} >= 11 + sed -i "/prefix/s@sbin@bin@g" src/lib389/setup.py.in +%endif make src/lib389/setup.py pushd ./src/lib389 %py3_build @@ -733,7 +755,7 @@ sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}/src/lib389/man/dscreat # Generate symbolic info for debuggers export XCFLAGS=$RPM_OPT_FLAGS -make %{?_smp_mflags} +%make_build %install @@ -741,7 +763,7 @@ mkdir -p %{buildroot}%{_datadir}/gdb/auto-load%{_sbindir} %if %{with cockpit} mkdir -p %{buildroot}%{_datadir}/cockpit %endif -make DESTDIR="$RPM_BUILD_ROOT" install +%make_install %if %{with cockpit} find %{buildroot}%{_datadir}/cockpit/389-console -type d | sed -e "s@%{buildroot}@@" | sed -e 's/^/\%dir /' > cockpit.list @@ -920,6 +942,8 @@ exit 0 %{_mandir}/man1/ldclt.1.gz %{_bindir}/logconv.pl %{_mandir}/man1/logconv.pl.1.gz +%{_bindir}/logconv.py +%{_mandir}/man1/logconv.py.1.gz %{_bindir}/pwdhash %{_mandir}/man1/pwdhash.1.gz %{_sbindir}/ns-slapd diff --git a/sources b/sources index 2836d24..c1a976f 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ +SHA512 (389-ds-base-3.1.2.tar.bz2) = 13f86f61b7da6380de6731f56e2bfae00e969d48acdff024f78ed6d9cff1474e5c8d1c25269031aa2466642482f55ed7b72d3844ec588b824aeb9c0ad79aab1d SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 -SHA512 (389-ds-base-3.1.1.tar.bz2) = c6aa0aba9779bd4ed6768f140d255474bc5e02455e37db6e8273740e9be81ac90bcab4ea97e117af573cb1d3f56ddd59d063b7715d99261ebf2d497c2801bc41 SHA512 (libdb-5.3.28-59.tar.bz2) = 731a434fa2e6487ebb05c458b0437456eb9f7991284beb08cb3e21931e23bdeddddbc95bfabe3a2f9f029fe69cd33a2d4f0f5ce6a9811e9c3b940cb6fde4bf79 From ca8f74ff676b86678d0e3f2aa3796445edd570bf Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Sat, 25 Jan 2025 17:22:27 +0100 Subject: [PATCH 102/125] Replace python3-magic with python3-file-magic --- ...nv.py-python3-magic-conflicts-with-p.patch | 53 +++++++++++++++++++ 389-ds-base.spec | 4 +- 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 0001-Issue-6544-logconv.py-python3-magic-conflicts-with-p.patch diff --git a/0001-Issue-6544-logconv.py-python3-magic-conflicts-with-p.patch b/0001-Issue-6544-logconv.py-python3-magic-conflicts-with-p.patch new file mode 100644 index 0000000..fb128ec --- /dev/null +++ b/0001-Issue-6544-logconv.py-python3-magic-conflicts-with-p.patch @@ -0,0 +1,53 @@ +From 1417198b95ca3e618ac26e748ec4bde6417c105c Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +Date: Sat, 25 Jan 2025 13:54:33 +0100 +Subject: [PATCH] Issue 6544 - logconv.py: python3-magic conflicts with + python3-file-magic + +Bug Description: +python3-magic and python3-file-magic can't be installed simultaneously, +python3-magic is not packaged for EL10. + +Fix Description: +Use python3-file-magic instead. + +Issue identified and fix suggested by Adam Williamson. + +Fixes: https://github.com/389ds/389-ds-base/issues/6544 + +Reviewed by: @mreynolds389 (Thanks!) +--- + ldap/admin/src/logconv.py | 3 +-- + rpm/389-ds-base.spec.in | 2 +- + 2 files changed, 2 insertions(+), 3 deletions(-) + +diff --git a/ldap/admin/src/logconv.py b/ldap/admin/src/logconv.py +index 566f9af38..2fb5bb8c1 100755 +--- a/ldap/admin/src/logconv.py ++++ b/ldap/admin/src/logconv.py +@@ -1798,8 +1798,7 @@ class logAnalyser: + return None + + try: +- mime = magic.Magic(mime=True) +- filetype = mime.from_file(filepath) ++ filetype = magic.detect_from_filename(filepath).mime_type + + # List of supported compression types + compressed_mime_types = [ +diff --git a/rpm/389-ds-base.spec.in b/rpm/389-ds-base.spec.in +index 1b408be0f..74bcb4576 100644 +--- a/rpm/389-ds-base.spec.in ++++ b/rpm/389-ds-base.spec.in +@@ -200,7 +200,7 @@ Requires: json-c + # Log compression + Requires: zlib-devel + # logconv.py, MIME type +-Requires: python-magic ++Requires: python3-file-magic + # Picks up our systemd deps. + %{?systemd_requires} + +-- +2.48.0 + diff --git a/389-ds-base.spec b/389-ds-base.spec index 2205ae3..ce816d1 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -493,7 +493,7 @@ Requires: json-c # Log compression Requires: zlib-devel # logconv.py, MIME type -Requires: python-magic +Requires: python3-file-magic # Picks up our systemd deps. %{?systemd_requires} @@ -507,6 +507,8 @@ Source4: 389-ds-base.sysusers Source5: https://fedorapeople.org/groups/389ds/libdb-5.3.28-59.tar.bz2 %endif +Patch: 0001-Issue-6544-logconv.py-python3-magic-conflicts-with-p.patch + %description 389 Directory Server is an LDAPv3 compliant server. The base package includes the LDAP server and command line utilities for server administration. From 78d0143425db8d9cc3062a642e1658e13f68a9fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Sat, 1 Feb 2025 19:52:34 +0100 Subject: [PATCH 103/125] Add explicit BR: libxcrypt-devel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Esser --- 389-ds-base.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/389-ds-base.spec b/389-ds-base.spec index ce816d1..f18573e 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -387,6 +387,7 @@ BuildRequires: libicu-devel BuildRequires: pcre2-devel BuildRequires: cracklib-devel BuildRequires: json-c-devel +BuildRequires: libxcrypt-devel %if %{with clang} BuildRequires: libatomic BuildRequires: clang From 6343e0d4435ad5bb662439f0cbec8d1e5d845ebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 25 Jan 2025 11:09:08 +0100 Subject: [PATCH 104/125] Drop call to %sysusers_create_compat After https://fedoraproject.org/wiki/Changes/RPMSuportForSystemdSysusers, rpm will handle this automatically. --- 389-ds-base.spec | 5 ----- 1 file changed, 5 deletions(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index f18573e..45015d8 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -851,11 +851,6 @@ fi # reload to pick up any changes to systemd files /bin/systemctl daemon-reload >$output 2>&1 || : -# https://fedoraproject.org/wiki/Packaging:UsersAndGroups#Soft_static_allocation -# Soft static allocation for UID and GID -# sysusers.d format https://fedoraproject.org/wiki/Changes/Adopting_sysusers.d_format -%sysusers_create_compat %{SOURCE4} - # Reload our sysctl before we restart (if we can) sysctl --system &> $output; true From 1e3c90db195128edeb73b29989e4fe89aa7676e9 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Fri, 14 Feb 2025 14:43:03 +0100 Subject: [PATCH 105/125] Update to 3.1.2-5 - Resolves: Issue 6489 - After log rotation refresh the FD pointer - Resolves: Issue 6554 - During import of entries without nsUniqueId, a supplier generates duplicate nsUniqueId (LMDB only) - Resolves: Issue 6555 - Potential crash when deleting a replicated backend --- ...-log-rotation-refresh-the-FD-pointer.patch | 146 ++++++++++++++++ ...g-import-of-entries-without-nsUnique.patch | 165 ++++++++++++++++++ ...tial-crash-when-deleting-a-replicate.patch | 116 ++++++++++++ 389-ds-base.spec | 3 + 4 files changed, 430 insertions(+) create mode 100644 0002-Issue-6489-After-log-rotation-refresh-the-FD-pointer.patch create mode 100644 0003-Issue-6554-During-import-of-entries-without-nsUnique.patch create mode 100644 0004-Issue-6555-Potential-crash-when-deleting-a-replicate.patch diff --git a/0002-Issue-6489-After-log-rotation-refresh-the-FD-pointer.patch b/0002-Issue-6489-After-log-rotation-refresh-the-FD-pointer.patch new file mode 100644 index 0000000..7e09f90 --- /dev/null +++ b/0002-Issue-6489-After-log-rotation-refresh-the-FD-pointer.patch @@ -0,0 +1,146 @@ +From 18c42eec08d3de1e485461b510ba91c0c4e39cf7 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Fri, 31 Jan 2025 08:54:27 -0500 +Subject: [PATCH] Issue 6489 - After log rotation refresh the FD pointer + +Description: + +When flushing a log buffer we get a FD for log prior to checking if the +log should be rotated. If the log is rotated that FD reference is now +invalid, and it needs to be refrehed before proceeding + +Relates: https://github.com/389ds/389-ds-base/issues/6489 + +Reviewed by: tbordaz(Thanks!) +--- + .../suites/logging/log_flush_rotation_test.py | 81 +++++++++++++++++++ + ldap/servers/slapd/log.c | 18 +++++ + 2 files changed, 99 insertions(+) + create mode 100644 dirsrvtests/tests/suites/logging/log_flush_rotation_test.py + +diff --git a/dirsrvtests/tests/suites/logging/log_flush_rotation_test.py b/dirsrvtests/tests/suites/logging/log_flush_rotation_test.py +new file mode 100644 +index 000000000..b33a622e1 +--- /dev/null ++++ b/dirsrvtests/tests/suites/logging/log_flush_rotation_test.py +@@ -0,0 +1,81 @@ ++# --- BEGIN COPYRIGHT BLOCK --- ++# Copyright (C) 2025 Red Hat, Inc. ++# All rights reserved. ++# ++# License: GPL (version 3 or any later version). ++# See LICENSE for details. ++# --- END COPYRIGHT BLOCK --- ++# ++import os ++import logging ++import time ++import pytest ++from lib389._constants import DEFAULT_SUFFIX, PW_DM ++from lib389.tasks import ImportTask ++from lib389.idm.user import UserAccounts ++from lib389.topologies import topology_st as topo ++ ++ ++log = logging.getLogger(__name__) ++ ++ ++def test_log_flush_and_rotation_crash(topo): ++ """Make sure server does not crash whening flushing a buffer and rotating ++ the log at the same time ++ ++ :id: d4b0af2f-48b2-45f5-ae8b-f06f692c3133 ++ :setup: Standalone Instance ++ :steps: ++ 1. Enable all logs ++ 2. Enable log buffering for all logs ++ 3. Set rotation time unit to 1 minute ++ 4. Make sure server is still running after 1 minute ++ :expectedresults: ++ 1. Success ++ 2. Success ++ 3. Success ++ 4. Success ++ """ ++ ++ inst = topo.standalone ++ ++ # Enable logging and buffering ++ inst.config.set("nsslapd-auditlog-logging-enabled", "on") ++ inst.config.set("nsslapd-accesslog-logbuffering", "on") ++ inst.config.set("nsslapd-auditlog-logbuffering", "on") ++ inst.config.set("nsslapd-errorlog-logbuffering", "on") ++ inst.config.set("nsslapd-securitylog-logbuffering", "on") ++ ++ # Set rotation policy to trigger rotation asap ++ inst.config.set("nsslapd-accesslog-logrotationtimeunit", "minute") ++ inst.config.set("nsslapd-auditlog-logrotationtimeunit", "minute") ++ inst.config.set("nsslapd-errorlog-logrotationtimeunit", "minute") ++ inst.config.set("nsslapd-securitylog-logrotationtimeunit", "minute") ++ ++ # ++ # Performs ops to populate all the logs ++ # ++ # Access & audit log ++ users = UserAccounts(topo.standalone, DEFAULT_SUFFIX) ++ user = users.create_test_user() ++ user.set("userPassword", PW_DM) ++ # Security log ++ user.bind(PW_DM) ++ # Error log ++ import_task = ImportTask(inst) ++ import_task.import_suffix_from_ldif(ldiffile="/not/here", ++ suffix=DEFAULT_SUFFIX) ++ ++ # Wait a minute and make sure the server did not crash ++ log.info("Sleep until logs are flushed and rotated") ++ time.sleep(61) ++ ++ assert inst.status() ++ ++ ++if __name__ == '__main__': ++ # Run isolated ++ # -s for DEBUG mode ++ CURRENT_FILE = os.path.realpath(__file__) ++ pytest.main(["-s", CURRENT_FILE]) ++ +diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c +index 92664e57e..31176c2dc 100644 +--- a/ldap/servers/slapd/log.c ++++ b/ldap/servers/slapd/log.c +@@ -6750,6 +6750,23 @@ log_refresh_state(int32_t log_type) + return 0; + } + } ++static LOGFD ++log_refresh_fd(int32_t log_type) ++{ ++ switch (log_type) { ++ case SLAPD_ACCESS_LOG: ++ return loginfo.log_access_fdes; ++ case SLAPD_SECURITY_LOG: ++ return loginfo.log_security_fdes; ++ case SLAPD_AUDIT_LOG: ++ return loginfo.log_audit_fdes; ++ case SLAPD_AUDITFAIL_LOG: ++ return loginfo.log_auditfail_fdes; ++ case SLAPD_ERROR_LOG: ++ return loginfo.log_error_fdes; ++ } ++ return NULL; ++} + + /* this function assumes the lock is already acquired */ + /* if sync_now is non-zero, data is flushed to physical storage */ +@@ -6861,6 +6878,7 @@ log_flush_buffer(LogBufferInfo *lbi, int log_type, int sync_now, int locked) + rotationtime_secs); + } + log_state = log_refresh_state(log_type); ++ fd = log_refresh_fd(log_type); + } + + if (log_state & LOGGING_NEED_TITLE) { +-- +2.48.0 + diff --git a/0003-Issue-6554-During-import-of-entries-without-nsUnique.patch b/0003-Issue-6554-During-import-of-entries-without-nsUnique.patch new file mode 100644 index 0000000..b5cdbd3 --- /dev/null +++ b/0003-Issue-6554-During-import-of-entries-without-nsUnique.patch @@ -0,0 +1,165 @@ +From 29fcbd19a8483ff0f9e82b674b52dd4d9293df50 Mon Sep 17 00:00:00 2001 +From: tbordaz +Date: Thu, 6 Feb 2025 18:25:36 +0100 +Subject: [PATCH] Issue 6554 - During import of entries without nsUniqueId, a + supplier generates duplicate nsUniqueId (LMDB only) (#6582) + +Bug description: + During an import the entry is prepared (schema, operational + attributes, password encryption,...) before starting the + update of the database and indexes. + A step of the preparation is to assign a value to 'nsuniqueid' + operational attribute. 'nsuniqueid' must be unique. + In LMDB the preparation is done by multiple threads (workers). + In such case the 'nsuniqueid' are generated in parallel and + as it is time based several values can be duplicated. + +Fix description: + To prevent that the routine dbmdb_import_generate_uniqueid + should make sure to synchronize the workers. + +fixes: #6554 + +Reviewed by: Pierre Rogier +--- + .../tests/suites/import/import_test.py | 79 ++++++++++++++++++- + .../back-ldbm/db-mdb/mdb_import_threads.c | 11 +++ + 2 files changed, 89 insertions(+), 1 deletion(-) + +diff --git a/dirsrvtests/tests/suites/import/import_test.py b/dirsrvtests/tests/suites/import/import_test.py +index 68f39257a..3e43bac31 100644 +--- a/dirsrvtests/tests/suites/import/import_test.py ++++ b/dirsrvtests/tests/suites/import/import_test.py +@@ -14,11 +14,13 @@ import os + import pytest + import time + import glob ++import re + import logging + import subprocess + from datetime import datetime + from lib389.topologies import topology_st as topo +-from lib389._constants import DEFAULT_SUFFIX, TaskWarning ++from lib389.topologies import topology_m2 as topo_m2 ++from lib389._constants import DEFAULT_BENAME, DEFAULT_SUFFIX, TaskWarning + from lib389.dbgen import dbgen_users + from lib389.tasks import ImportTask + from lib389.index import Indexes +@@ -690,6 +692,81 @@ def test_online_import_under_load(topo): + assert import_task.get_exit_code() == 0 + + ++def test_duplicate_nsuniqueid(topo_m2, request): ++ """Test that after an offline import all ++ nsuniqueid are different ++ ++ :id: a2541677-a288-4633-bacf-4050cc56016d ++ :setup: MMR with 2 suppliers ++ :steps: ++ 1. stop the instance to do offline operations ++ 2. Generate a 5K users LDIF file ++ 3. Check that no uniqueid are present in the generated file ++ 4. import the generated LDIF ++ 5. export the database ++ 6. Check that that exported LDIF contains more than 5K nsuniqueid ++ 7. Check that there is no duplicate nsuniqued in exported LDIF ++ :expectedresults: ++ 1. Should succeeds ++ 2. Should succeeds ++ 3. Should succeeds ++ 4. Should succeeds ++ 5. Should succeeds ++ 6. Should succeeds ++ 7. Should succeeds ++ """ ++ m1 = topo_m2.ms["supplier1"] ++ ++ # Stop the instance ++ m1.stop() ++ ++ # Generate a test ldif (5k entries) ++ log.info("Generating LDIF...") ++ ldif_dir = m1.get_ldif_dir() ++ import_ldif = ldif_dir + '/5k_users_import.ldif' ++ dbgen_users(m1, 5000, import_ldif, DEFAULT_SUFFIX) ++ ++ # Check that the generated LDIF does not contain nsuniqueid ++ all_nsuniqueid = [] ++ with open(import_ldif, 'r') as file: ++ for line in file: ++ if line.lower().startswith("nsuniqueid: "): ++ all_nsuniqueid.append(line.split(': ')[1]) ++ log.info("import file contains " + str(len(all_nsuniqueid)) + " nsuniqueid") ++ assert len(all_nsuniqueid) == 0 ++ ++ # Import the "nsuniquied free" LDIF file ++ if not m1.ldif2db('userRoot', None, None, None, import_ldif): ++ assert False ++ ++ # Export the DB that now should contain nsuniqueid ++ export_ldif = ldif_dir + '/5k_user_export.ldif' ++ log.info("export to file " + export_ldif) ++ m1.db2ldif(bename=DEFAULT_BENAME, suffixes=[DEFAULT_SUFFIX], ++ excludeSuffixes=None, repl_data=False, ++ outputfile=export_ldif, encrypt=False) ++ ++ # Check that the export LDIF contain nsuniqueid ++ all_nsuniqueid = [] ++ with open(export_ldif, 'r') as file: ++ for line in file: ++ if line.lower().startswith("nsuniqueid: "): ++ all_nsuniqueid.append(line.split(': ')[1]) ++ log.info("export file " + export_ldif + " contains " + str(len(all_nsuniqueid)) + " nsuniqueid") ++ assert len(all_nsuniqueid) >= 5000 ++ ++ # Check that the nsuniqueid are unique ++ assert len(set(all_nsuniqueid)) == len(all_nsuniqueid) ++ ++ def fin(): ++ if os.path.exists(import_ldif): ++ os.remove(import_ldif) ++ if os.path.exists(export_ldif): ++ os.remove(export_ldif) ++ m1.start ++ ++ request.addfinalizer(fin) ++ + if __name__ == '__main__': + # Run isolated + # -s for DEBUG mode +diff --git a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_import_threads.c b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_import_threads.c +index abbecad4b..4820eed6a 100644 +--- a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_import_threads.c ++++ b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_import_threads.c +@@ -610,10 +610,20 @@ dbmdb_import_generate_uniqueid(ImportJob *job, Slapi_Entry *e) + { + const char *uniqueid = slapi_entry_get_uniqueid(e); + int rc = UID_SUCCESS; ++ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + + if (!uniqueid && (job->uuid_gen_type != SLAPI_UNIQUEID_GENERATE_NONE)) { + char *newuniqueid; + ++ /* With 'mdb' we have several workers generating nsuniqueid ++ * we need to serialize them to prevent generating duplicate value ++ * From performance pov it only impacts import ++ * The default value is SLAPI_UNIQUEID_GENERATE_TIME_BASED so ++ * the only syscall is clock_gettime and then string formating ++ * that should limit contention ++ */ ++ pthread_mutex_lock(&mutex); ++ + /* generate id based on dn */ + if (job->uuid_gen_type == SLAPI_UNIQUEID_GENERATE_NAME_BASED) { + char *dn = slapi_entry_get_dn(e); +@@ -624,6 +634,7 @@ dbmdb_import_generate_uniqueid(ImportJob *job, Slapi_Entry *e) + /* time based */ + rc = slapi_uniqueIDGenerateString(&newuniqueid); + } ++ pthread_mutex_unlock(&mutex); + + if (rc == UID_SUCCESS) { + slapi_entry_set_uniqueid(e, newuniqueid); +-- +2.48.0 + diff --git a/0004-Issue-6555-Potential-crash-when-deleting-a-replicate.patch b/0004-Issue-6555-Potential-crash-when-deleting-a-replicate.patch new file mode 100644 index 0000000..b19d661 --- /dev/null +++ b/0004-Issue-6555-Potential-crash-when-deleting-a-replicate.patch @@ -0,0 +1,116 @@ +From f5e5b5939d0f65a9abf1f301bdfb1ff707a26d9e Mon Sep 17 00:00:00 2001 +From: progier389 +Date: Thu, 30 Jan 2025 14:44:39 +0100 +Subject: [PATCH] Issue 6555 - Potential crash when deleting a replicated + backend (#6559) + +Problem: connection cleanup may try to access a freed replica +Solution: Ensure that the replica is still existing before using its pointer + +Issue: #6555 + +Reviewed by: @tbordaz, @droideck (Thanks!) +--- + ldap/servers/plugins/replication/repl5.h | 3 ++ + .../plugins/replication/repl5_replica_hash.c | 36 +++++++++++++++++++ + .../plugins/replication/repl_connext.c | 2 +- + 3 files changed, 40 insertions(+), 1 deletion(-) + +diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h +index 6e5552f54..027d8634d 100644 +--- a/ldap/servers/plugins/replication/repl5.h ++++ b/ldap/servers/plugins/replication/repl5.h +@@ -29,6 +29,7 @@ + #include "repl5_ruv.h" + #include "plstr.h" + #include ++#include + + #define START_UPDATE_DELAY 2 /* 2 second */ + #define REPLICA_TYPE_WINDOWS 1 +@@ -710,6 +711,8 @@ PRBool replica_is_updatedn(Replica *r, const Slapi_DN *sdn); + void replica_set_updatedn(Replica *r, const Slapi_ValueSet *vs, int mod_op); + void replica_set_groupdn(Replica *r, const Slapi_ValueSet *vs, int mod_op); + char *replica_get_generation(const Replica *r); ++bool replica_check_validity(Replica *replica); ++ + + /* currently supported flags */ + #define REPLICA_LOG_CHANGES 0x1 /* enable change logging */ +diff --git a/ldap/servers/plugins/replication/repl5_replica_hash.c b/ldap/servers/plugins/replication/repl5_replica_hash.c +index bb7b054c6..275e5f7a8 100644 +--- a/ldap/servers/plugins/replication/repl5_replica_hash.c ++++ b/ldap/servers/plugins/replication/repl5_replica_hash.c +@@ -27,9 +27,18 @@ struct repl_enum_data + void *arg; + }; + ++struct repl_enum_validity ++{ ++ Replica *replica; ++ bool is_valid; ++}; ++ ++ + /* Forward declarations */ + static PRIntn replica_destroy_hash_entry(PLHashEntry *he, PRIntn index, void *arg); + static PRIntn replica_enumerate(PLHashEntry *he, PRIntn index, void *hash_data); ++static PRIntn replica_validity_cb(PLHashEntry *he, PRIntn index, void *arg); ++ + + + int +@@ -192,6 +201,21 @@ replica_enumerate_replicas(FNEnumReplica fn, void *arg) + slapi_rwlock_unlock(s_lock); + } + ++/* Check that the replica still exists */ ++bool ++replica_check_validity(Replica *replica) ++{ ++ struct repl_enum_validity data = { replica, false }; ++ ++ if (replica == NULL) { ++ return false; ++ } ++ slapi_rwlock_rdlock(s_lock); ++ PL_HashTableEnumerateEntries(s_hash, replica_validity_cb, &data); ++ slapi_rwlock_unlock(s_lock); ++ return data.is_valid; ++} ++ + /* Helper functions */ + + /* this function called for each hash node during hash destruction */ +@@ -224,3 +248,15 @@ replica_enumerate(PLHashEntry *he, PRIntn index __attribute__((unused)), void *h + + return HT_ENUMERATE_NEXT; + } ++ ++static PRIntn ++replica_validity_cb(PLHashEntry *he, PRIntn index __attribute__((unused)), void *arg) ++{ ++ struct repl_enum_validity *data = arg; ++ Replica *r = (Replica *)he->value; ++ if (r == data->replica) { ++ data->is_valid = true; ++ return HT_ENUMERATE_STOP; ++ } ++ return HT_ENUMERATE_NEXT; ++} +diff --git a/ldap/servers/plugins/replication/repl_connext.c b/ldap/servers/plugins/replication/repl_connext.c +index 19cb39665..7b3041e1f 100644 +--- a/ldap/servers/plugins/replication/repl_connext.c ++++ b/ldap/servers/plugins/replication/repl_connext.c +@@ -61,7 +61,7 @@ consumer_connection_extension_destructor(void *ext, void *object __attribute__(( + * a replica. If so, release it here. + */ + consumer_connection_extension *connext = (consumer_connection_extension *)ext; +- if (NULL != connext->replica_acquired) { ++ if (replica_check_validity(connext->replica_acquired)) { + Replica *r = connext->replica_acquired; + /* If a total update was in progress, abort it */ + if (REPL_PROTOCOL_50_TOTALUPDATE == connext->repl_protocol_version) { +-- +2.48.0 + diff --git a/389-ds-base.spec b/389-ds-base.spec index 45015d8..f7fa436 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -509,6 +509,9 @@ Source5: https://fedorapeople.org/groups/389ds/libdb-5.3.28-59.tar.bz2 %endif Patch: 0001-Issue-6544-logconv.py-python3-magic-conflicts-with-p.patch +Patch: 0002-Issue-6489-After-log-rotation-refresh-the-FD-pointer.patch +Patch: 0003-Issue-6554-During-import-of-entries-without-nsUnique.patch +Patch: 0004-Issue-6555-Potential-crash-when-deleting-a-replicate.patch %description 389 Directory Server is an LDAPv3 compliant server. The base package includes From 07e8a882bcc19f5d1ef3cf5a0b7d58a0354dafd5 Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Wed, 5 Mar 2025 08:11:56 -0500 Subject: [PATCH 106/125] Fix build of bundled libdb with GCC 15 GCC 15 defaults to C23. libdb is obsolete and the last release was over a decade ago, and therefore cannot be expected to compile to the latest standards. --- 389-ds-base.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/389-ds-base.spec b/389-ds-base.spec index f7fa436..28da748 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -715,6 +715,7 @@ mkdir -p ../%{libdb_base_version} pushd ../%{libdb_base_version} tar -xjf %{_topdir}/SOURCES/%{libdb_full_version}.tar.bz2 mv %{libdb_full_version} SOURCES +sed -i -e '/^CFLAGS=/s/-fno-strict-aliasing/& -std=gnu99/' %{_builddir}/%{name}-%{version}/rpm/bundle-libdb.spec rpmbuild --define "_topdir $PWD" -bc %{_builddir}/%{name}-%{version}/rpm/bundle-libdb.spec popd %endif From 250f86dedd1f8aea78637ba7d3d8832fb77ed31d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= Date: Wed, 2 Apr 2025 12:18:27 +0200 Subject: [PATCH 107/125] python3-lib389: Remove manually specified runtime Requires The requires are automatically generated and their manual repetition is forbidden by packaging guidelines. > Automatically determined dependencies MUST NOT be duplicated by manual dependencies. https://docs.fedoraproject.org/en-US/packaging-guidelines/#_package_dependencies Even further: > Packages SHOULD NOT have an explicit runtime dependency on python3. https://docs.fedoraproject.org/en-US/packaging-guidelines/Python/#_dependencies I kept the Requires for python3-libselinux as it is not generated. I have not checked whether or not this dependency is actually required. --- My main motivation is this: https://github.com/389ds/389-ds-base/pull/6719 Once released upstream, the runtime dependency on python3-setuptools will be redundant. By deleting it now, I reduce the risk of having it in the spec even after the upstream change lands. --- 389-ds-base.spec | 9 --------- 1 file changed, 9 deletions(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index 28da748..e841ef9 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -606,16 +606,7 @@ Requires: openssl # This is for /usr/bin/c_rehash tool, only needed for openssl < 1.1.0 Requires: openssl-perl Requires: iproute -Requires: python%{python3_pkgversion} -Requires: python%{python3_pkgversion}-distro -Requires: python%{python3_pkgversion}-ldap -Requires: python%{python3_pkgversion}-pyasn1 -Requires: python%{python3_pkgversion}-pyasn1-modules -Requires: python%{python3_pkgversion}-dateutil -Requires: python%{python3_pkgversion}-argcomplete Requires: python%{python3_pkgversion}-libselinux -Requires: python%{python3_pkgversion}-setuptools -Requires: python%{python3_pkgversion}-cryptography Recommends: bash-completion %{?python_provide:%python_provide python%{python3_pkgversion}-lib389} From 7ab459a547177ff70e608af6b22b4442627bdb91 Mon Sep 17 00:00:00 2001 From: Python Maint Date: Tue, 3 Jun 2025 13:57:04 +0200 Subject: [PATCH 108/125] Rebuilt for Python 3.14 From 9c09966b8bf53a72bd9afd62e784e0967ea03a40 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Mon, 16 Jun 2025 14:20:58 +0200 Subject: [PATCH 109/125] Resolves: Issue 6776 - Enabling audit log makes slapd coredump --- ...bling-audit-log-makes-slapd-coredump.patch | 39 +++++++++++++++++++ 389-ds-base.spec | 1 + 2 files changed, 40 insertions(+) create mode 100644 0005-Issue-6776-Enabling-audit-log-makes-slapd-coredump.patch diff --git a/0005-Issue-6776-Enabling-audit-log-makes-slapd-coredump.patch b/0005-Issue-6776-Enabling-audit-log-makes-slapd-coredump.patch new file mode 100644 index 0000000..0574286 --- /dev/null +++ b/0005-Issue-6776-Enabling-audit-log-makes-slapd-coredump.patch @@ -0,0 +1,39 @@ +From a383eb3e33368b6aa638e1e3c87507829648c00f Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +Date: Wed, 28 May 2025 12:50:01 +0200 +Subject: [PATCH] Issue 6776 - Enabling audit log makes slapd coredump + +Bug description: +`slapi_ch_strdup` function is declared with the `returns_nonnull` attribute, +indicating that it can never return NULL. +However, its implementation explicitly returns NULL when the input is NULL. +This contradicts the attribute and misleads the compiler, which results +in a removed NULL check. + +Fix Description: +Remove the `returns_nonnull` attribute from the `slapi_ch_strdup` declaration +to align with its actual behavior. + +Fixes: https://github.com/389ds/389-ds-base/issues/6776 + +Reviewed by: @mreynolds389, @droideck (Thanks!) +--- + ldap/servers/slapd/slapi-plugin.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h +index bdf867518..62393133d 100644 +--- a/ldap/servers/slapd/slapi-plugin.h ++++ b/ldap/servers/slapd/slapi-plugin.h +@@ -5813,7 +5813,7 @@ char *slapi_ch_malloc(unsigned long size) __ATTRIBUTE__((returns_nonnull)); + char *slapi_ch_memalign(uint32_t size, uint32_t alignment) __ATTRIBUTE__((returns_nonnull)); + char *slapi_ch_realloc(char *block, unsigned long size) __ATTRIBUTE__((returns_nonnull)); + char *slapi_ch_calloc(unsigned long nelem, unsigned long size) __ATTRIBUTE__((returns_nonnull)); +-char *slapi_ch_strdup(const char *s) __ATTRIBUTE__((returns_nonnull)); ++char *slapi_ch_strdup(const char *s); + void slapi_ch_free(void **ptr); + void slapi_ch_free_string(char **s); + struct berval *slapi_ch_bvdup(const struct berval *); +-- +2.49.0 + diff --git a/389-ds-base.spec b/389-ds-base.spec index e841ef9..ba34753 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -512,6 +512,7 @@ Patch: 0001-Issue-6544-logconv.py-python3-magic-conflicts-with-p.patc Patch: 0002-Issue-6489-After-log-rotation-refresh-the-FD-pointer.patch Patch: 0003-Issue-6554-During-import-of-entries-without-nsUnique.patch Patch: 0004-Issue-6555-Potential-crash-when-deleting-a-replicate.patch +Patch: 0005-Issue-6776-Enabling-audit-log-makes-slapd-coredump.patch %description 389 Directory Server is an LDAPv3 compliant server. The base package includes From 5ed75f148c68d5313fffb46a4524ea871dea0880 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Mon, 30 Jun 2025 11:49:06 +0200 Subject: [PATCH 110/125] Update to 3.1.3 --- 389-ds-base.spec | 177 +++++++++++++++++++++-------------------------- 1 file changed, 80 insertions(+), 97 deletions(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index ba34753..bc97e8c 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -66,9 +66,9 @@ ExcludeArch: i686 Summary: 389 Directory Server (%{variant}) Name: 389-ds-base -Version: 3.1.2 +Version: 3.1.3 Release: %{autorelease -n %{?with_asan:-e asan}}%{?dist} -License: GPL-3.0-or-later WITH GPL-3.0-389-ds-base-exception AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSD-2-Clause OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-3.0 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0 +License: GPL-3.0-or-later WITH GPL-3.0-389-ds-base-exception AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR LGPL-2.1-or-later OR MIT) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-3.0 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0 AND Zlib URL: https://www.port389.org Obsoletes: %{name}-legacy-tools < 1.4.4.6 Obsoletes: %{name}-legacy-tools-debuginfo < 1.4.4.6 @@ -76,89 +76,81 @@ Provides: ldif2ldbm >= 0 ##### Bundled cargo crates list - START ##### Provides: bundled(crate(addr2line)) = 0.24.2 -Provides: bundled(crate(adler2)) = 2.0.0 -Provides: bundled(crate(ahash)) = 0.7.8 +Provides: bundled(crate(adler2)) = 2.0.1 +Provides: bundled(crate(allocator-api2)) = 0.2.21 Provides: bundled(crate(atty)) = 0.2.14 -Provides: bundled(crate(autocfg)) = 1.4.0 -Provides: bundled(crate(backtrace)) = 0.3.74 +Provides: bundled(crate(autocfg)) = 1.5.0 +Provides: bundled(crate(backtrace)) = 0.3.75 Provides: bundled(crate(base64)) = 0.13.1 -Provides: bundled(crate(bitflags)) = 2.8.0 +Provides: bundled(crate(bitflags)) = 2.9.1 Provides: bundled(crate(byteorder)) = 1.5.0 Provides: bundled(crate(cbindgen)) = 0.26.0 -Provides: bundled(crate(cc)) = 1.2.10 -Provides: bundled(crate(cfg-if)) = 1.0.0 +Provides: bundled(crate(cc)) = 1.2.27 +Provides: bundled(crate(cfg-if)) = 1.0.1 Provides: bundled(crate(clap)) = 3.2.25 Provides: bundled(crate(clap_lex)) = 0.2.4 -Provides: bundled(crate(concread)) = 0.2.21 -Provides: bundled(crate(crossbeam)) = 0.8.4 -Provides: bundled(crate(crossbeam-channel)) = 0.5.14 -Provides: bundled(crate(crossbeam-deque)) = 0.8.6 +Provides: bundled(crate(concread)) = 0.5.6 Provides: bundled(crate(crossbeam-epoch)) = 0.9.18 Provides: bundled(crate(crossbeam-queue)) = 0.3.12 Provides: bundled(crate(crossbeam-utils)) = 0.8.21 -Provides: bundled(crate(errno)) = 0.3.10 +Provides: bundled(crate(equivalent)) = 1.0.2 +Provides: bundled(crate(errno)) = 0.3.12 Provides: bundled(crate(fastrand)) = 2.3.0 Provides: bundled(crate(fernet)) = 0.1.4 +Provides: bundled(crate(foldhash)) = 0.1.5 Provides: bundled(crate(foreign-types)) = 0.3.2 Provides: bundled(crate(foreign-types-shared)) = 0.1.1 -Provides: bundled(crate(getrandom)) = 0.2.15 +Provides: bundled(crate(getrandom)) = 0.3.3 Provides: bundled(crate(gimli)) = 0.31.1 -Provides: bundled(crate(hashbrown)) = 0.12.3 +Provides: bundled(crate(hashbrown)) = 0.15.4 Provides: bundled(crate(heck)) = 0.4.1 Provides: bundled(crate(hermit-abi)) = 0.1.19 Provides: bundled(crate(indexmap)) = 1.9.3 -Provides: bundled(crate(instant)) = 0.1.13 -Provides: bundled(crate(itoa)) = 1.0.14 -Provides: bundled(crate(jobserver)) = 0.1.32 -Provides: bundled(crate(libc)) = 0.2.169 -Provides: bundled(crate(linux-raw-sys)) = 0.4.15 -Provides: bundled(crate(lock_api)) = 0.4.12 -Provides: bundled(crate(log)) = 0.4.25 -Provides: bundled(crate(lru)) = 0.7.8 -Provides: bundled(crate(memchr)) = 2.7.4 -Provides: bundled(crate(miniz_oxide)) = 0.8.3 +Provides: bundled(crate(itoa)) = 1.0.15 +Provides: bundled(crate(jobserver)) = 0.1.33 +Provides: bundled(crate(libc)) = 0.2.174 +Provides: bundled(crate(linux-raw-sys)) = 0.9.4 +Provides: bundled(crate(log)) = 0.4.27 +Provides: bundled(crate(lru)) = 0.13.0 +Provides: bundled(crate(memchr)) = 2.7.5 +Provides: bundled(crate(miniz_oxide)) = 0.8.9 Provides: bundled(crate(object)) = 0.36.7 -Provides: bundled(crate(once_cell)) = 1.20.2 -Provides: bundled(crate(openssl)) = 0.10.68 +Provides: bundled(crate(once_cell)) = 1.21.3 +Provides: bundled(crate(openssl)) = 0.10.73 Provides: bundled(crate(openssl-macros)) = 0.1.1 -Provides: bundled(crate(openssl-sys)) = 0.9.104 +Provides: bundled(crate(openssl-sys)) = 0.9.109 Provides: bundled(crate(os_str_bytes)) = 6.6.1 -Provides: bundled(crate(parking_lot)) = 0.11.2 -Provides: bundled(crate(parking_lot_core)) = 0.8.6 Provides: bundled(crate(paste)) = 0.1.18 Provides: bundled(crate(paste-impl)) = 0.1.18 Provides: bundled(crate(pin-project-lite)) = 0.2.16 -Provides: bundled(crate(pkg-config)) = 0.3.31 -Provides: bundled(crate(ppv-lite86)) = 0.2.20 +Provides: bundled(crate(pkg-config)) = 0.3.32 Provides: bundled(crate(proc-macro-hack)) = 0.5.20+deprecated -Provides: bundled(crate(proc-macro2)) = 1.0.93 -Provides: bundled(crate(quote)) = 1.0.38 -Provides: bundled(crate(rand)) = 0.8.5 -Provides: bundled(crate(rand_chacha)) = 0.3.1 -Provides: bundled(crate(rand_core)) = 0.6.4 -Provides: bundled(crate(redox_syscall)) = 0.2.16 -Provides: bundled(crate(rustc-demangle)) = 0.1.24 -Provides: bundled(crate(rustix)) = 0.38.44 -Provides: bundled(crate(ryu)) = 1.0.18 -Provides: bundled(crate(scopeguard)) = 1.2.0 -Provides: bundled(crate(serde)) = 1.0.217 -Provides: bundled(crate(serde_derive)) = 1.0.217 -Provides: bundled(crate(serde_json)) = 1.0.137 +Provides: bundled(crate(proc-macro2)) = 1.0.95 +Provides: bundled(crate(quote)) = 1.0.40 +Provides: bundled(crate(r-efi)) = 5.3.0 +Provides: bundled(crate(rustc-demangle)) = 0.1.25 +Provides: bundled(crate(rustix)) = 1.0.7 +Provides: bundled(crate(ryu)) = 1.0.20 +Provides: bundled(crate(serde)) = 1.0.219 +Provides: bundled(crate(serde_derive)) = 1.0.219 +Provides: bundled(crate(serde_json)) = 1.0.140 Provides: bundled(crate(shlex)) = 1.3.0 -Provides: bundled(crate(smallvec)) = 1.13.2 +Provides: bundled(crate(smallvec)) = 1.15.1 +Provides: bundled(crate(sptr)) = 0.3.2 Provides: bundled(crate(strsim)) = 0.10.0 -Provides: bundled(crate(syn)) = 2.0.96 -Provides: bundled(crate(tempfile)) = 3.15.0 +Provides: bundled(crate(syn)) = 2.0.103 +Provides: bundled(crate(tempfile)) = 3.20.0 Provides: bundled(crate(termcolor)) = 1.4.1 -Provides: bundled(crate(textwrap)) = 0.16.1 -Provides: bundled(crate(tokio)) = 1.43.0 -Provides: bundled(crate(tokio-macros)) = 2.5.0 +Provides: bundled(crate(textwrap)) = 0.16.2 +Provides: bundled(crate(tokio)) = 1.45.1 Provides: bundled(crate(toml)) = 0.5.11 -Provides: bundled(crate(unicode-ident)) = 1.0.15 +Provides: bundled(crate(tracing)) = 0.1.41 +Provides: bundled(crate(tracing-attributes)) = 0.1.30 +Provides: bundled(crate(tracing-core)) = 0.1.34 +Provides: bundled(crate(unicode-ident)) = 1.0.18 Provides: bundled(crate(uuid)) = 0.8.2 Provides: bundled(crate(vcpkg)) = 0.2.15 -Provides: bundled(crate(version_check)) = 0.9.5 -Provides: bundled(crate(wasi)) = 0.11.0+wasi_snapshot_preview1 +Provides: bundled(crate(wasi)) = 0.14.2+wasi_0.2.4 Provides: bundled(crate(winapi)) = 0.3.9 Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0 Provides: bundled(crate(winapi-util)) = 0.1.9 @@ -173,8 +165,7 @@ Provides: bundled(crate(windows_i686_msvc)) = 0.52.6 Provides: bundled(crate(windows_x86_64_gnu)) = 0.52.6 Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.52.6 Provides: bundled(crate(windows_x86_64_msvc)) = 0.52.6 -Provides: bundled(crate(zerocopy)) = 0.7.35 -Provides: bundled(crate(zerocopy-derive)) = 0.7.35 +Provides: bundled(crate(wit-bindgen-rt)) = 0.39.0 Provides: bundled(crate(zeroize)) = 1.8.1 Provides: bundled(crate(zeroize_derive)) = 1.4.2 Provides: bundled(npm(@eslint-community/eslint-utils)) = 4.4.1 @@ -195,6 +186,7 @@ Provides: bundled(npm(@patternfly/patternfly)) = 5.4.1 Provides: bundled(npm(@patternfly/react-charts)) = 7.4.3 Provides: bundled(npm(@patternfly/react-core)) = 5.4.1 Provides: bundled(npm(@patternfly/react-icons)) = 5.4.0 +Provides: bundled(npm(@patternfly/react-log-viewer)) = 5.3.0 Provides: bundled(npm(@patternfly/react-styles)) = 5.4.0 Provides: bundled(npm(@patternfly/react-table)) = 5.4.1 Provides: bundled(npm(@patternfly/react-tokens)) = 5.4.0 @@ -299,6 +291,7 @@ Provides: bundled(npm(locate-path)) = 6.0.0 Provides: bundled(npm(lodash)) = 4.17.21 Provides: bundled(npm(lodash.merge)) = 4.6.2 Provides: bundled(npm(loose-envify)) = 1.4.0 +Provides: bundled(npm(memoize-one)) = 5.2.1 Provides: bundled(npm(minimatch)) = 3.1.2 Provides: bundled(npm(ms)) = 2.1.3 Provides: bundled(npm(natural-compare)) = 1.4.0 @@ -435,18 +428,7 @@ BuildRequires: doxygen # For tests! BuildRequires: libcmocka-devel # For lib389 and related components. -BuildRequires: python%{python3_pkgversion} BuildRequires: python%{python3_pkgversion}-devel -BuildRequires: python%{python3_pkgversion}-setuptools -BuildRequires: python%{python3_pkgversion}-ldap -BuildRequires: python%{python3_pkgversion}-pyasn1 -BuildRequires: python%{python3_pkgversion}-pyasn1-modules -BuildRequires: python%{python3_pkgversion}-dateutil -BuildRequires: python%{python3_pkgversion}-argcomplete -BuildRequires: python%{python3_pkgversion}-argparse-manpage -BuildRequires: python%{python3_pkgversion}-policycoreutils -BuildRequires: python%{python3_pkgversion}-libselinux -BuildRequires: python%{python3_pkgversion}-cryptography # For cockpit %if %{with cockpit} @@ -508,11 +490,6 @@ Source4: 389-ds-base.sysusers Source5: https://fedorapeople.org/groups/389ds/libdb-5.3.28-59.tar.bz2 %endif -Patch: 0001-Issue-6544-logconv.py-python3-magic-conflicts-with-p.patch -Patch: 0002-Issue-6489-After-log-rotation-refresh-the-FD-pointer.patch -Patch: 0003-Issue-6554-During-import-of-entries-without-nsUnique.patch -Patch: 0004-Issue-6555-Potential-crash-when-deleting-a-replicate.patch -Patch: 0005-Issue-6776-Enabling-audit-log-makes-slapd-coredump.patch %description 389 Directory Server is an LDAPv3 compliant server. The base package includes @@ -609,7 +586,6 @@ Requires: openssl-perl Requires: iproute Requires: python%{python3_pkgversion}-libselinux Recommends: bash-completion -%{?python_provide:%python_provide python%{python3_pkgversion}-lib389} %description -n python%{python3_pkgversion}-lib389 This module contains tools and libraries for accessing, testing, @@ -628,6 +604,12 @@ Requires: python%{python3_pkgversion}-lib389 = %{version}-%{release} A cockpit UI Plugin for configuring and administering the 389 Directory Server %endif +%generate_buildrequires +cd src/lib389 +# Tests do not run in %%check (lib389's tests need to be fixed) +# but test dependencies are needed to check import lib389.topologies +%pyproject_buildrequires -g test + %prep %autosetup -p1 -n %{name}-%{version} @@ -737,19 +719,10 @@ autoreconf -fiv %endif # lib389 -%if 0%{?fedora} >= 42 || 0%{?rhel} >= 11 - sed -i "/prefix/s@sbin@bin@g" src/lib389/setup.py.in -%endif -make src/lib389/setup.py pushd ./src/lib389 -%py3_build +%{python3} validate_version.py --update +%pyproject_wheel popd -# argparse-manpage dynamic man pages have hardcoded man v1 in header, -# need to change it to v8 -sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}/src/lib389/man/dsconf.8 -sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}/src/lib389/man/dsctl.8 -sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}/src/lib389/man/dsidm.8 -sed -i "1s/\"1\"/\"8\"/" %{_builddir}/%{name}-%{version}/src/lib389/man/dscreate.8 # Generate symbolic info for debuggers export XCFLAGS=$RPM_OPT_FLAGS @@ -779,7 +752,8 @@ cp -r %{_builddir}/%{name}-%{version}/man/man3 $RPM_BUILD_ROOT/%{_mandir}/man3 # lib389 pushd src/lib389 -%py3_install +%pyproject_install +%pyproject_save_files -l lib389 popd # Register CLI tools for bash completion @@ -835,6 +809,9 @@ export TSAN_OPTIONS=print_stacktrace=1:second_deadlock_stack=1:history_size=7 if ! make DESTDIR="$RPM_BUILD_ROOT" check; then cat ./test-suite.log && false; fi %endif +# Check import for lib389 modules +%pyproject_check_import -e '*.test*' + %post if [ -n "$DEBUGPOSTTRANS" ] ; then output=$DEBUGPOSTTRANS @@ -1011,18 +988,24 @@ exit 0 %{_libdir}/%{pkgname}/plugins/libback-bdb.so %endif -%files -n python%{python3_pkgversion}-lib389 -%doc LICENSE LICENSE.GPLv3+ -%{python3_sitelib}/lib389* -%{_sbindir}/dsconf -%{_mandir}/man8/dsconf.8.gz -%{_sbindir}/dscreate -%{_mandir}/man8/dscreate.8.gz -%{_sbindir}/dsctl -%{_mandir}/man8/dsctl.8.gz -%{_sbindir}/dsidm -%{_mandir}/man8/dsidm.8.gz +%files -n python%{python3_pkgversion}-lib389 -f %{pyproject_files} +%doc src/lib389/README.md +%license LICENSE LICENSE.GPLv3+ +# Binaries +%{_bindir}/dsconf +%{_bindir}/dscreate +%{_bindir}/dsctl +%{_bindir}/dsidm +%{_bindir}/openldap_to_ds %{_libexecdir}/%{pkgname}/dscontainer +# Man pages +%{_mandir}/man8/dsconf.8.gz +%{_mandir}/man8/dscreate.8.gz +%{_mandir}/man8/dsctl.8.gz +%{_mandir}/man8/dsidm.8.gz +%{_mandir}/man8/openldap_to_ds.8.gz +%exclude %{_mandir}/man1 +# Bash completions for scripts provided by python3-lib389 %{bash_completions_dir}/dsctl %{bash_completions_dir}/dsconf %{bash_completions_dir}/dscreate From a800aa34d13461058eb228789e59bc220d3fe1a8 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Mon, 30 Jun 2025 11:57:30 +0200 Subject: [PATCH 111/125] Update sources file --- sources | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sources b/sources index c1a976f..c18aedb 100644 --- a/sources +++ b/sources @@ -1,3 +1,4 @@ -SHA512 (389-ds-base-3.1.2.tar.bz2) = 13f86f61b7da6380de6731f56e2bfae00e969d48acdff024f78ed6d9cff1474e5c8d1c25269031aa2466642482f55ed7b72d3844ec588b824aeb9c0ad79aab1d SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 -SHA512 (libdb-5.3.28-59.tar.bz2) = 731a434fa2e6487ebb05c458b0437456eb9f7991284beb08cb3e21931e23bdeddddbc95bfabe3a2f9f029fe69cd33a2d4f0f5ce6a9811e9c3b940cb6fde4bf79 +SHA512 (389-ds-base-3.1.3.tar.bz2) = bd15c29dba5209ed828a2534e51fd000fdd5d32862fd07ea73339e73489b3c79f1991c91592c75dbb67384c696a03c82378f156bbea594e2e17421c95ca4c6be +SHA512 (libdb-5.3.28-59.tar.bz2) = cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e + From 53a2fcc07b564796846bd1113de07404ee5a5141 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Tue, 8 Jul 2025 09:46:38 +0200 Subject: [PATCH 112/125] Remove old patches [skip changelog] --- ...nv.py-python3-magic-conflicts-with-p.patch | 53 ------ ...-log-rotation-refresh-the-FD-pointer.patch | 146 ---------------- ...g-import-of-entries-without-nsUnique.patch | 165 ------------------ ...tial-crash-when-deleting-a-replicate.patch | 116 ------------ ...bling-audit-log-makes-slapd-coredump.patch | 39 ----- 5 files changed, 519 deletions(-) delete mode 100644 0001-Issue-6544-logconv.py-python3-magic-conflicts-with-p.patch delete mode 100644 0002-Issue-6489-After-log-rotation-refresh-the-FD-pointer.patch delete mode 100644 0003-Issue-6554-During-import-of-entries-without-nsUnique.patch delete mode 100644 0004-Issue-6555-Potential-crash-when-deleting-a-replicate.patch delete mode 100644 0005-Issue-6776-Enabling-audit-log-makes-slapd-coredump.patch diff --git a/0001-Issue-6544-logconv.py-python3-magic-conflicts-with-p.patch b/0001-Issue-6544-logconv.py-python3-magic-conflicts-with-p.patch deleted file mode 100644 index fb128ec..0000000 --- a/0001-Issue-6544-logconv.py-python3-magic-conflicts-with-p.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 1417198b95ca3e618ac26e748ec4bde6417c105c Mon Sep 17 00:00:00 2001 -From: Viktor Ashirov -Date: Sat, 25 Jan 2025 13:54:33 +0100 -Subject: [PATCH] Issue 6544 - logconv.py: python3-magic conflicts with - python3-file-magic - -Bug Description: -python3-magic and python3-file-magic can't be installed simultaneously, -python3-magic is not packaged for EL10. - -Fix Description: -Use python3-file-magic instead. - -Issue identified and fix suggested by Adam Williamson. - -Fixes: https://github.com/389ds/389-ds-base/issues/6544 - -Reviewed by: @mreynolds389 (Thanks!) ---- - ldap/admin/src/logconv.py | 3 +-- - rpm/389-ds-base.spec.in | 2 +- - 2 files changed, 2 insertions(+), 3 deletions(-) - -diff --git a/ldap/admin/src/logconv.py b/ldap/admin/src/logconv.py -index 566f9af38..2fb5bb8c1 100755 ---- a/ldap/admin/src/logconv.py -+++ b/ldap/admin/src/logconv.py -@@ -1798,8 +1798,7 @@ class logAnalyser: - return None - - try: -- mime = magic.Magic(mime=True) -- filetype = mime.from_file(filepath) -+ filetype = magic.detect_from_filename(filepath).mime_type - - # List of supported compression types - compressed_mime_types = [ -diff --git a/rpm/389-ds-base.spec.in b/rpm/389-ds-base.spec.in -index 1b408be0f..74bcb4576 100644 ---- a/rpm/389-ds-base.spec.in -+++ b/rpm/389-ds-base.spec.in -@@ -200,7 +200,7 @@ Requires: json-c - # Log compression - Requires: zlib-devel - # logconv.py, MIME type --Requires: python-magic -+Requires: python3-file-magic - # Picks up our systemd deps. - %{?systemd_requires} - --- -2.48.0 - diff --git a/0002-Issue-6489-After-log-rotation-refresh-the-FD-pointer.patch b/0002-Issue-6489-After-log-rotation-refresh-the-FD-pointer.patch deleted file mode 100644 index 7e09f90..0000000 --- a/0002-Issue-6489-After-log-rotation-refresh-the-FD-pointer.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 18c42eec08d3de1e485461b510ba91c0c4e39cf7 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Fri, 31 Jan 2025 08:54:27 -0500 -Subject: [PATCH] Issue 6489 - After log rotation refresh the FD pointer - -Description: - -When flushing a log buffer we get a FD for log prior to checking if the -log should be rotated. If the log is rotated that FD reference is now -invalid, and it needs to be refrehed before proceeding - -Relates: https://github.com/389ds/389-ds-base/issues/6489 - -Reviewed by: tbordaz(Thanks!) ---- - .../suites/logging/log_flush_rotation_test.py | 81 +++++++++++++++++++ - ldap/servers/slapd/log.c | 18 +++++ - 2 files changed, 99 insertions(+) - create mode 100644 dirsrvtests/tests/suites/logging/log_flush_rotation_test.py - -diff --git a/dirsrvtests/tests/suites/logging/log_flush_rotation_test.py b/dirsrvtests/tests/suites/logging/log_flush_rotation_test.py -new file mode 100644 -index 000000000..b33a622e1 ---- /dev/null -+++ b/dirsrvtests/tests/suites/logging/log_flush_rotation_test.py -@@ -0,0 +1,81 @@ -+# --- BEGIN COPYRIGHT BLOCK --- -+# Copyright (C) 2025 Red Hat, Inc. -+# All rights reserved. -+# -+# License: GPL (version 3 or any later version). -+# See LICENSE for details. -+# --- END COPYRIGHT BLOCK --- -+# -+import os -+import logging -+import time -+import pytest -+from lib389._constants import DEFAULT_SUFFIX, PW_DM -+from lib389.tasks import ImportTask -+from lib389.idm.user import UserAccounts -+from lib389.topologies import topology_st as topo -+ -+ -+log = logging.getLogger(__name__) -+ -+ -+def test_log_flush_and_rotation_crash(topo): -+ """Make sure server does not crash whening flushing a buffer and rotating -+ the log at the same time -+ -+ :id: d4b0af2f-48b2-45f5-ae8b-f06f692c3133 -+ :setup: Standalone Instance -+ :steps: -+ 1. Enable all logs -+ 2. Enable log buffering for all logs -+ 3. Set rotation time unit to 1 minute -+ 4. Make sure server is still running after 1 minute -+ :expectedresults: -+ 1. Success -+ 2. Success -+ 3. Success -+ 4. Success -+ """ -+ -+ inst = topo.standalone -+ -+ # Enable logging and buffering -+ inst.config.set("nsslapd-auditlog-logging-enabled", "on") -+ inst.config.set("nsslapd-accesslog-logbuffering", "on") -+ inst.config.set("nsslapd-auditlog-logbuffering", "on") -+ inst.config.set("nsslapd-errorlog-logbuffering", "on") -+ inst.config.set("nsslapd-securitylog-logbuffering", "on") -+ -+ # Set rotation policy to trigger rotation asap -+ inst.config.set("nsslapd-accesslog-logrotationtimeunit", "minute") -+ inst.config.set("nsslapd-auditlog-logrotationtimeunit", "minute") -+ inst.config.set("nsslapd-errorlog-logrotationtimeunit", "minute") -+ inst.config.set("nsslapd-securitylog-logrotationtimeunit", "minute") -+ -+ # -+ # Performs ops to populate all the logs -+ # -+ # Access & audit log -+ users = UserAccounts(topo.standalone, DEFAULT_SUFFIX) -+ user = users.create_test_user() -+ user.set("userPassword", PW_DM) -+ # Security log -+ user.bind(PW_DM) -+ # Error log -+ import_task = ImportTask(inst) -+ import_task.import_suffix_from_ldif(ldiffile="/not/here", -+ suffix=DEFAULT_SUFFIX) -+ -+ # Wait a minute and make sure the server did not crash -+ log.info("Sleep until logs are flushed and rotated") -+ time.sleep(61) -+ -+ assert inst.status() -+ -+ -+if __name__ == '__main__': -+ # Run isolated -+ # -s for DEBUG mode -+ CURRENT_FILE = os.path.realpath(__file__) -+ pytest.main(["-s", CURRENT_FILE]) -+ -diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c -index 92664e57e..31176c2dc 100644 ---- a/ldap/servers/slapd/log.c -+++ b/ldap/servers/slapd/log.c -@@ -6750,6 +6750,23 @@ log_refresh_state(int32_t log_type) - return 0; - } - } -+static LOGFD -+log_refresh_fd(int32_t log_type) -+{ -+ switch (log_type) { -+ case SLAPD_ACCESS_LOG: -+ return loginfo.log_access_fdes; -+ case SLAPD_SECURITY_LOG: -+ return loginfo.log_security_fdes; -+ case SLAPD_AUDIT_LOG: -+ return loginfo.log_audit_fdes; -+ case SLAPD_AUDITFAIL_LOG: -+ return loginfo.log_auditfail_fdes; -+ case SLAPD_ERROR_LOG: -+ return loginfo.log_error_fdes; -+ } -+ return NULL; -+} - - /* this function assumes the lock is already acquired */ - /* if sync_now is non-zero, data is flushed to physical storage */ -@@ -6861,6 +6878,7 @@ log_flush_buffer(LogBufferInfo *lbi, int log_type, int sync_now, int locked) - rotationtime_secs); - } - log_state = log_refresh_state(log_type); -+ fd = log_refresh_fd(log_type); - } - - if (log_state & LOGGING_NEED_TITLE) { --- -2.48.0 - diff --git a/0003-Issue-6554-During-import-of-entries-without-nsUnique.patch b/0003-Issue-6554-During-import-of-entries-without-nsUnique.patch deleted file mode 100644 index b5cdbd3..0000000 --- a/0003-Issue-6554-During-import-of-entries-without-nsUnique.patch +++ /dev/null @@ -1,165 +0,0 @@ -From 29fcbd19a8483ff0f9e82b674b52dd4d9293df50 Mon Sep 17 00:00:00 2001 -From: tbordaz -Date: Thu, 6 Feb 2025 18:25:36 +0100 -Subject: [PATCH] Issue 6554 - During import of entries without nsUniqueId, a - supplier generates duplicate nsUniqueId (LMDB only) (#6582) - -Bug description: - During an import the entry is prepared (schema, operational - attributes, password encryption,...) before starting the - update of the database and indexes. - A step of the preparation is to assign a value to 'nsuniqueid' - operational attribute. 'nsuniqueid' must be unique. - In LMDB the preparation is done by multiple threads (workers). - In such case the 'nsuniqueid' are generated in parallel and - as it is time based several values can be duplicated. - -Fix description: - To prevent that the routine dbmdb_import_generate_uniqueid - should make sure to synchronize the workers. - -fixes: #6554 - -Reviewed by: Pierre Rogier ---- - .../tests/suites/import/import_test.py | 79 ++++++++++++++++++- - .../back-ldbm/db-mdb/mdb_import_threads.c | 11 +++ - 2 files changed, 89 insertions(+), 1 deletion(-) - -diff --git a/dirsrvtests/tests/suites/import/import_test.py b/dirsrvtests/tests/suites/import/import_test.py -index 68f39257a..3e43bac31 100644 ---- a/dirsrvtests/tests/suites/import/import_test.py -+++ b/dirsrvtests/tests/suites/import/import_test.py -@@ -14,11 +14,13 @@ import os - import pytest - import time - import glob -+import re - import logging - import subprocess - from datetime import datetime - from lib389.topologies import topology_st as topo --from lib389._constants import DEFAULT_SUFFIX, TaskWarning -+from lib389.topologies import topology_m2 as topo_m2 -+from lib389._constants import DEFAULT_BENAME, DEFAULT_SUFFIX, TaskWarning - from lib389.dbgen import dbgen_users - from lib389.tasks import ImportTask - from lib389.index import Indexes -@@ -690,6 +692,81 @@ def test_online_import_under_load(topo): - assert import_task.get_exit_code() == 0 - - -+def test_duplicate_nsuniqueid(topo_m2, request): -+ """Test that after an offline import all -+ nsuniqueid are different -+ -+ :id: a2541677-a288-4633-bacf-4050cc56016d -+ :setup: MMR with 2 suppliers -+ :steps: -+ 1. stop the instance to do offline operations -+ 2. Generate a 5K users LDIF file -+ 3. Check that no uniqueid are present in the generated file -+ 4. import the generated LDIF -+ 5. export the database -+ 6. Check that that exported LDIF contains more than 5K nsuniqueid -+ 7. Check that there is no duplicate nsuniqued in exported LDIF -+ :expectedresults: -+ 1. Should succeeds -+ 2. Should succeeds -+ 3. Should succeeds -+ 4. Should succeeds -+ 5. Should succeeds -+ 6. Should succeeds -+ 7. Should succeeds -+ """ -+ m1 = topo_m2.ms["supplier1"] -+ -+ # Stop the instance -+ m1.stop() -+ -+ # Generate a test ldif (5k entries) -+ log.info("Generating LDIF...") -+ ldif_dir = m1.get_ldif_dir() -+ import_ldif = ldif_dir + '/5k_users_import.ldif' -+ dbgen_users(m1, 5000, import_ldif, DEFAULT_SUFFIX) -+ -+ # Check that the generated LDIF does not contain nsuniqueid -+ all_nsuniqueid = [] -+ with open(import_ldif, 'r') as file: -+ for line in file: -+ if line.lower().startswith("nsuniqueid: "): -+ all_nsuniqueid.append(line.split(': ')[1]) -+ log.info("import file contains " + str(len(all_nsuniqueid)) + " nsuniqueid") -+ assert len(all_nsuniqueid) == 0 -+ -+ # Import the "nsuniquied free" LDIF file -+ if not m1.ldif2db('userRoot', None, None, None, import_ldif): -+ assert False -+ -+ # Export the DB that now should contain nsuniqueid -+ export_ldif = ldif_dir + '/5k_user_export.ldif' -+ log.info("export to file " + export_ldif) -+ m1.db2ldif(bename=DEFAULT_BENAME, suffixes=[DEFAULT_SUFFIX], -+ excludeSuffixes=None, repl_data=False, -+ outputfile=export_ldif, encrypt=False) -+ -+ # Check that the export LDIF contain nsuniqueid -+ all_nsuniqueid = [] -+ with open(export_ldif, 'r') as file: -+ for line in file: -+ if line.lower().startswith("nsuniqueid: "): -+ all_nsuniqueid.append(line.split(': ')[1]) -+ log.info("export file " + export_ldif + " contains " + str(len(all_nsuniqueid)) + " nsuniqueid") -+ assert len(all_nsuniqueid) >= 5000 -+ -+ # Check that the nsuniqueid are unique -+ assert len(set(all_nsuniqueid)) == len(all_nsuniqueid) -+ -+ def fin(): -+ if os.path.exists(import_ldif): -+ os.remove(import_ldif) -+ if os.path.exists(export_ldif): -+ os.remove(export_ldif) -+ m1.start -+ -+ request.addfinalizer(fin) -+ - if __name__ == '__main__': - # Run isolated - # -s for DEBUG mode -diff --git a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_import_threads.c b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_import_threads.c -index abbecad4b..4820eed6a 100644 ---- a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_import_threads.c -+++ b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_import_threads.c -@@ -610,10 +610,20 @@ dbmdb_import_generate_uniqueid(ImportJob *job, Slapi_Entry *e) - { - const char *uniqueid = slapi_entry_get_uniqueid(e); - int rc = UID_SUCCESS; -+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - - if (!uniqueid && (job->uuid_gen_type != SLAPI_UNIQUEID_GENERATE_NONE)) { - char *newuniqueid; - -+ /* With 'mdb' we have several workers generating nsuniqueid -+ * we need to serialize them to prevent generating duplicate value -+ * From performance pov it only impacts import -+ * The default value is SLAPI_UNIQUEID_GENERATE_TIME_BASED so -+ * the only syscall is clock_gettime and then string formating -+ * that should limit contention -+ */ -+ pthread_mutex_lock(&mutex); -+ - /* generate id based on dn */ - if (job->uuid_gen_type == SLAPI_UNIQUEID_GENERATE_NAME_BASED) { - char *dn = slapi_entry_get_dn(e); -@@ -624,6 +634,7 @@ dbmdb_import_generate_uniqueid(ImportJob *job, Slapi_Entry *e) - /* time based */ - rc = slapi_uniqueIDGenerateString(&newuniqueid); - } -+ pthread_mutex_unlock(&mutex); - - if (rc == UID_SUCCESS) { - slapi_entry_set_uniqueid(e, newuniqueid); --- -2.48.0 - diff --git a/0004-Issue-6555-Potential-crash-when-deleting-a-replicate.patch b/0004-Issue-6555-Potential-crash-when-deleting-a-replicate.patch deleted file mode 100644 index b19d661..0000000 --- a/0004-Issue-6555-Potential-crash-when-deleting-a-replicate.patch +++ /dev/null @@ -1,116 +0,0 @@ -From f5e5b5939d0f65a9abf1f301bdfb1ff707a26d9e Mon Sep 17 00:00:00 2001 -From: progier389 -Date: Thu, 30 Jan 2025 14:44:39 +0100 -Subject: [PATCH] Issue 6555 - Potential crash when deleting a replicated - backend (#6559) - -Problem: connection cleanup may try to access a freed replica -Solution: Ensure that the replica is still existing before using its pointer - -Issue: #6555 - -Reviewed by: @tbordaz, @droideck (Thanks!) ---- - ldap/servers/plugins/replication/repl5.h | 3 ++ - .../plugins/replication/repl5_replica_hash.c | 36 +++++++++++++++++++ - .../plugins/replication/repl_connext.c | 2 +- - 3 files changed, 40 insertions(+), 1 deletion(-) - -diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h -index 6e5552f54..027d8634d 100644 ---- a/ldap/servers/plugins/replication/repl5.h -+++ b/ldap/servers/plugins/replication/repl5.h -@@ -29,6 +29,7 @@ - #include "repl5_ruv.h" - #include "plstr.h" - #include -+#include - - #define START_UPDATE_DELAY 2 /* 2 second */ - #define REPLICA_TYPE_WINDOWS 1 -@@ -710,6 +711,8 @@ PRBool replica_is_updatedn(Replica *r, const Slapi_DN *sdn); - void replica_set_updatedn(Replica *r, const Slapi_ValueSet *vs, int mod_op); - void replica_set_groupdn(Replica *r, const Slapi_ValueSet *vs, int mod_op); - char *replica_get_generation(const Replica *r); -+bool replica_check_validity(Replica *replica); -+ - - /* currently supported flags */ - #define REPLICA_LOG_CHANGES 0x1 /* enable change logging */ -diff --git a/ldap/servers/plugins/replication/repl5_replica_hash.c b/ldap/servers/plugins/replication/repl5_replica_hash.c -index bb7b054c6..275e5f7a8 100644 ---- a/ldap/servers/plugins/replication/repl5_replica_hash.c -+++ b/ldap/servers/plugins/replication/repl5_replica_hash.c -@@ -27,9 +27,18 @@ struct repl_enum_data - void *arg; - }; - -+struct repl_enum_validity -+{ -+ Replica *replica; -+ bool is_valid; -+}; -+ -+ - /* Forward declarations */ - static PRIntn replica_destroy_hash_entry(PLHashEntry *he, PRIntn index, void *arg); - static PRIntn replica_enumerate(PLHashEntry *he, PRIntn index, void *hash_data); -+static PRIntn replica_validity_cb(PLHashEntry *he, PRIntn index, void *arg); -+ - - - int -@@ -192,6 +201,21 @@ replica_enumerate_replicas(FNEnumReplica fn, void *arg) - slapi_rwlock_unlock(s_lock); - } - -+/* Check that the replica still exists */ -+bool -+replica_check_validity(Replica *replica) -+{ -+ struct repl_enum_validity data = { replica, false }; -+ -+ if (replica == NULL) { -+ return false; -+ } -+ slapi_rwlock_rdlock(s_lock); -+ PL_HashTableEnumerateEntries(s_hash, replica_validity_cb, &data); -+ slapi_rwlock_unlock(s_lock); -+ return data.is_valid; -+} -+ - /* Helper functions */ - - /* this function called for each hash node during hash destruction */ -@@ -224,3 +248,15 @@ replica_enumerate(PLHashEntry *he, PRIntn index __attribute__((unused)), void *h - - return HT_ENUMERATE_NEXT; - } -+ -+static PRIntn -+replica_validity_cb(PLHashEntry *he, PRIntn index __attribute__((unused)), void *arg) -+{ -+ struct repl_enum_validity *data = arg; -+ Replica *r = (Replica *)he->value; -+ if (r == data->replica) { -+ data->is_valid = true; -+ return HT_ENUMERATE_STOP; -+ } -+ return HT_ENUMERATE_NEXT; -+} -diff --git a/ldap/servers/plugins/replication/repl_connext.c b/ldap/servers/plugins/replication/repl_connext.c -index 19cb39665..7b3041e1f 100644 ---- a/ldap/servers/plugins/replication/repl_connext.c -+++ b/ldap/servers/plugins/replication/repl_connext.c -@@ -61,7 +61,7 @@ consumer_connection_extension_destructor(void *ext, void *object __attribute__(( - * a replica. If so, release it here. - */ - consumer_connection_extension *connext = (consumer_connection_extension *)ext; -- if (NULL != connext->replica_acquired) { -+ if (replica_check_validity(connext->replica_acquired)) { - Replica *r = connext->replica_acquired; - /* If a total update was in progress, abort it */ - if (REPL_PROTOCOL_50_TOTALUPDATE == connext->repl_protocol_version) { --- -2.48.0 - diff --git a/0005-Issue-6776-Enabling-audit-log-makes-slapd-coredump.patch b/0005-Issue-6776-Enabling-audit-log-makes-slapd-coredump.patch deleted file mode 100644 index 0574286..0000000 --- a/0005-Issue-6776-Enabling-audit-log-makes-slapd-coredump.patch +++ /dev/null @@ -1,39 +0,0 @@ -From a383eb3e33368b6aa638e1e3c87507829648c00f Mon Sep 17 00:00:00 2001 -From: Viktor Ashirov -Date: Wed, 28 May 2025 12:50:01 +0200 -Subject: [PATCH] Issue 6776 - Enabling audit log makes slapd coredump - -Bug description: -`slapi_ch_strdup` function is declared with the `returns_nonnull` attribute, -indicating that it can never return NULL. -However, its implementation explicitly returns NULL when the input is NULL. -This contradicts the attribute and misleads the compiler, which results -in a removed NULL check. - -Fix Description: -Remove the `returns_nonnull` attribute from the `slapi_ch_strdup` declaration -to align with its actual behavior. - -Fixes: https://github.com/389ds/389-ds-base/issues/6776 - -Reviewed by: @mreynolds389, @droideck (Thanks!) ---- - ldap/servers/slapd/slapi-plugin.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h -index bdf867518..62393133d 100644 ---- a/ldap/servers/slapd/slapi-plugin.h -+++ b/ldap/servers/slapd/slapi-plugin.h -@@ -5813,7 +5813,7 @@ char *slapi_ch_malloc(unsigned long size) __ATTRIBUTE__((returns_nonnull)); - char *slapi_ch_memalign(uint32_t size, uint32_t alignment) __ATTRIBUTE__((returns_nonnull)); - char *slapi_ch_realloc(char *block, unsigned long size) __ATTRIBUTE__((returns_nonnull)); - char *slapi_ch_calloc(unsigned long nelem, unsigned long size) __ATTRIBUTE__((returns_nonnull)); --char *slapi_ch_strdup(const char *s) __ATTRIBUTE__((returns_nonnull)); -+char *slapi_ch_strdup(const char *s); - void slapi_ch_free(void **ptr); - void slapi_ch_free_string(char **s); - struct berval *slapi_ch_bvdup(const struct berval *); --- -2.49.0 - From c01eeaf809f3266f883ffaf387c7c0484ecd885d Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Wed, 9 Jul 2025 12:47:41 -0400 Subject: [PATCH 113/125] Fix checksum of libdb sources [skip changelog] --- sources | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sources b/sources index c18aedb..6ab8ee9 100644 --- a/sources +++ b/sources @@ -1,4 +1,3 @@ SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 SHA512 (389-ds-base-3.1.3.tar.bz2) = bd15c29dba5209ed828a2534e51fd000fdd5d32862fd07ea73339e73489b3c79f1991c91592c75dbb67384c696a03c82378f156bbea594e2e17421c95ca4c6be -SHA512 (libdb-5.3.28-59.tar.bz2) = cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e - +SHA512 (libdb-5.3.28-59.tar.bz2) = 731a434fa2e6487ebb05c458b0437456eb9f7991284beb08cb3e21931e23bdeddddbc95bfabe3a2f9f029fe69cd33a2d4f0f5ce6a9811e9c3b940cb6fde4bf79 From ad5313fd7316925b517c661f1f69665a76c6068d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 23 Jul 2025 15:39:11 +0000 Subject: [PATCH 114/125] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild From 11a2e0852168f57b03b839a82a441ef33d138e19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Zatloukal?= Date: Wed, 6 Aug 2025 09:52:20 +0200 Subject: [PATCH 115/125] Rebuilt for icu 77.1 From f4f2109f94fe17fc6f86b01c178f91d2febd85b8 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Mon, 11 Aug 2025 13:37:27 +0200 Subject: [PATCH 116/125] Rebuild for https://fedoraproject.org/wiki/Changes/389_Directory_Server_3.2.0 --- 0001-Issue-5120-Fix-compilation-error.patch | 48 + ...ue-6782-Improve-paged-result-locking.patch | 127 + ...lation-failure-with-rust-1.89-on-Fed.patch | 33 + ...nd-creation-cleanup-and-Database-UI-.patch | 488 + ...dd_exclude_subtree-and-remove_exclud.patch | 515 + ...iq-allow-specifying-match-rules-in-t.patch | 45 + ...I-Properly-handle-disabled-NDN-cache.patch | 1201 + ...tor-for-improved-data-management-685.patch | 2237 ++ ...essSanitizer-memory-leak-in-mdb_init.patch | 65 + ...8-AddressSanitizer-leak-in-do_search.patch | 58 + ...ssSanitizer-leak-in-agmt_update_init.patch | 58 + ...hema-attribute-table-expansion-break.patch | 55 + ...ilter-is-not-fully-applying-matching.patch | 169 + ...essed-log-rotation-creates-files-wit.patch | 163 + ...ng-access-JSON-logging-for-TLS-Clien.patch | 590 + ...f-Replicas-with-the-consumer-role-al.patch | 67 + ...ser-that-is-updated-during-password-.patch | 360 + ...01-Update-changelog-trimming-logging.patch | 53 + ...ue-6430-implement-read-only-bdb-6431.patch | 20249 ++++++++++++++++ ...ULL-subsystem-crash-in-JSON-error-lo.patch | 380 + ...-if-repl-keep-alive-entry-can-not-be.patch | 98 + ...k-password-hashes-in-audit-logs-6885.patch | 814 + ...y-leak-in-roles_cache_create_object_.patch | 262 + ...e-changelog-trimming-logging-fix-tes.patch | 64 + ...llow-system-to-manage-uid-gid-at-sta.patch | 32 + ...6468-CLI-Fix-default-error-log-level.patch | 31 + ...apd-crashes-when-a-referral-is-added.patch | 97 + 389-ds-base.spec | 98 +- 28 files changed, 28455 insertions(+), 2 deletions(-) create mode 100644 0001-Issue-5120-Fix-compilation-error.patch create mode 100644 0001-Issue-6782-Improve-paged-result-locking.patch create mode 100644 0001-Issue-6929-Compilation-failure-with-rust-1.89-on-Fed.patch create mode 100644 0002-Issue-6822-Backend-creation-cleanup-and-Database-UI-.patch create mode 100644 0003-Issue-6753-Add-add_exclude_subtree-and-remove_exclud.patch create mode 100644 0004-Issue-6857-uiduniq-allow-specifying-match-rules-in-t.patch create mode 100644 0005-Issue-6756-CLI-UI-Properly-handle-disabled-NDN-cache.patch create mode 100644 0006-Issue-6854-Refactor-for-improved-data-management-685.patch create mode 100644 0007-Issue-6850-AddressSanitizer-memory-leak-in-mdb_init.patch create mode 100644 0008-Issue-6848-AddressSanitizer-leak-in-do_search.patch create mode 100644 0009-Issue-6865-AddressSanitizer-leak-in-agmt_update_init.patch create mode 100644 0010-Issue-6868-UI-schema-attribute-table-expansion-break.patch create mode 100644 0011-Issue-6859-str2filter-is-not-fully-applying-matching.patch create mode 100644 0012-Issue-6872-compressed-log-rotation-creates-files-wit.patch create mode 100644 0013-Issue-6888-Missing-access-JSON-logging-for-TLS-Clien.patch create mode 100644 0014-Issue-6772-dsconf-Replicas-with-the-consumer-role-al.patch create mode 100644 0015-Issue-6893-Log-user-that-is-updated-during-password-.patch create mode 100644 0016-Issue-6901-Update-changelog-trimming-logging.patch create mode 100644 0017-Issue-6430-implement-read-only-bdb-6431.patch create mode 100644 0018-Issue-6663-Fix-NULL-subsystem-crash-in-JSON-error-lo.patch create mode 100644 0019-Issue-6895-Crash-if-repl-keep-alive-entry-can-not-be.patch create mode 100644 0020-Issue-6884-Mask-password-hashes-in-audit-logs-6885.patch create mode 100644 0021-Issue-6778-Memory-leak-in-roles_cache_create_object_.patch create mode 100644 0022-Issue-6901-Update-changelog-trimming-logging-fix-tes.patch create mode 100644 0023-Issue-6181-RFE-Allow-system-to-manage-uid-gid-at-sta.patch create mode 100644 0024-Issue-6468-CLI-Fix-default-error-log-level.patch create mode 100644 0025-Issue-6768-ns-slapd-crashes-when-a-referral-is-added.patch diff --git a/0001-Issue-5120-Fix-compilation-error.patch b/0001-Issue-5120-Fix-compilation-error.patch new file mode 100644 index 0000000..f298e7a --- /dev/null +++ b/0001-Issue-5120-Fix-compilation-error.patch @@ -0,0 +1,48 @@ +From a2d3ba3456f59b77443085d17b36b424437fbef1 Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +Date: Mon, 11 Aug 2025 13:22:52 +0200 +Subject: [PATCH] Issue 5120 - Fix compilation error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Bug Description: +Compilation fails with `-Wunused-function`: + +``` +ldap/servers/slapd/main.c:290:1: warning: ‘referral_set_defaults’ defined but not used [-Wunused-function] + 290 | referral_set_defaults(void) + | ^~~~~~~~~~~~~~~~~~~~~ +make: *** [Makefile:4148: all] Error 2 +``` + +Fix Description: +Remove unused function `referral_set_defaults`. + +Fixes: https://github.com/389ds/389-ds-base/issues/5120 +--- + ldap/servers/slapd/main.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c +index 9d81d80f3..c370588e5 100644 +--- a/ldap/servers/slapd/main.c ++++ b/ldap/servers/slapd/main.c +@@ -285,14 +285,6 @@ main_setuid(char *username) + return 0; + } + +-/* set good defaults for front-end config in referral mode */ +-static void +-referral_set_defaults(void) +-{ +- char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE]; +- config_set_maxdescriptors(CONFIG_MAXDESCRIPTORS_ATTRIBUTE, "1024", errorbuf, 1); +-} +- + static int + name2exemode(char *progname, char *s, int exit_if_unknown) + { +-- +2.49.0 + diff --git a/0001-Issue-6782-Improve-paged-result-locking.patch b/0001-Issue-6782-Improve-paged-result-locking.patch new file mode 100644 index 0000000..015f1a5 --- /dev/null +++ b/0001-Issue-6782-Improve-paged-result-locking.patch @@ -0,0 +1,127 @@ +From dcc402a3dd9a8f316388dc31da42786fbc2c1a88 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Thu, 15 May 2025 10:35:27 -0400 +Subject: [PATCH] Issue 6782 - Improve paged result locking + +Description: + +When cleaning a slot, instead of mem setting everything to Zero and restoring +the mutex, manually reset all the values leaving the mutex pointer +intact. + +There is also a deadlock possibility when checking for abandoned PR search +in opshared.c, and we were checking a flag value outside of the per_conn +lock. + +Relates: https://github.com/389ds/389-ds-base/issues/6782 + +Reviewed by: progier & spichugi(Thanks!!) +--- + ldap/servers/slapd/opshared.c | 10 +++++++++- + ldap/servers/slapd/pagedresults.c | 27 +++++++++++++++++---------- + 2 files changed, 26 insertions(+), 11 deletions(-) + +diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c +index 5ea919e2d..545518748 100644 +--- a/ldap/servers/slapd/opshared.c ++++ b/ldap/servers/slapd/opshared.c +@@ -619,6 +619,14 @@ op_shared_search(Slapi_PBlock *pb, int send_result) + int32_t tlimit; + slapi_pblock_get(pb, SLAPI_SEARCH_TIMELIMIT, &tlimit); + pagedresults_set_timelimit(pb_conn, operation, (time_t)tlimit, pr_idx); ++ /* When using this mutex in conjunction with the main paged ++ * result lock, you must do so in this order: ++ * ++ * --> pagedresults_lock() ++ * --> pagedresults_mutex ++ * <-- pagedresults_mutex ++ * <-- pagedresults_unlock() ++ */ + pagedresults_mutex = pageresult_lock_get_addr(pb_conn); + } + +@@ -744,11 +752,11 @@ op_shared_search(Slapi_PBlock *pb, int send_result) + pr_search_result = pagedresults_get_search_result(pb_conn, operation, 1 /*locked*/, pr_idx); + if (pr_search_result) { + if (pagedresults_is_abandoned_or_notavailable(pb_conn, 1 /*locked*/, pr_idx)) { ++ pthread_mutex_unlock(pagedresults_mutex); + pagedresults_unlock(pb_conn, pr_idx); + /* Previous operation was abandoned and the simplepaged object is not in use. */ + send_ldap_result(pb, 0, NULL, "Simple Paged Results Search abandoned", 0, NULL); + rc = LDAP_SUCCESS; +- pthread_mutex_unlock(pagedresults_mutex); + goto free_and_return; + } else { + slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET, pr_search_result); +diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c +index 642aefb3d..c3f3aae01 100644 +--- a/ldap/servers/slapd/pagedresults.c ++++ b/ldap/servers/slapd/pagedresults.c +@@ -48,7 +48,6 @@ pageresult_lock_get_addr(Connection *conn) + static void + _pr_cleanup_one_slot(PagedResults *prp) + { +- PRLock *prmutex = NULL; + if (!prp) { + return; + } +@@ -56,13 +55,17 @@ _pr_cleanup_one_slot(PagedResults *prp) + /* sr is left; release it. */ + prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set)); + } +- /* clean up the slot */ +- if (prp->pr_mutex) { +- /* pr_mutex is reused; back it up and reset it. */ +- prmutex = prp->pr_mutex; +- } +- memset(prp, '\0', sizeof(PagedResults)); +- prp->pr_mutex = prmutex; ++ ++ /* clean up the slot except the mutex */ ++ prp->pr_current_be = NULL; ++ prp->pr_search_result_set = NULL; ++ prp->pr_search_result_count = 0; ++ prp->pr_search_result_set_size_estimate = 0; ++ prp->pr_sort_result_code = 0; ++ prp->pr_timelimit_hr.tv_sec = 0; ++ prp->pr_timelimit_hr.tv_nsec = 0; ++ prp->pr_flags = 0; ++ prp->pr_msgid = 0; + } + + /* +@@ -1007,7 +1010,8 @@ op_set_pagedresults(Operation *op) + + /* + * pagedresults_lock/unlock -- introduced to protect search results for the +- * asynchronous searches. ++ * asynchronous searches. Do not call these functions while the PR conn lock ++ * is held (e.g. pageresult_lock_get_addr(conn)) + */ + void + pagedresults_lock(Connection *conn, int index) +@@ -1045,6 +1049,8 @@ int + pagedresults_is_abandoned_or_notavailable(Connection *conn, int locked, int index) + { + PagedResults *prp; ++ int32_t result; ++ + if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) { + return 1; /* not abandoned, but do not want to proceed paged results op. */ + } +@@ -1052,10 +1058,11 @@ pagedresults_is_abandoned_or_notavailable(Connection *conn, int locked, int inde + pthread_mutex_lock(pageresult_lock_get_addr(conn)); + } + prp = conn->c_pagedresults.prl_list + index; ++ result = prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED; + if (!locked) { + pthread_mutex_unlock(pageresult_lock_get_addr(conn)); + } +- return prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED; ++ return result; + } + + int +-- +2.49.0 + diff --git a/0001-Issue-6929-Compilation-failure-with-rust-1.89-on-Fed.patch b/0001-Issue-6929-Compilation-failure-with-rust-1.89-on-Fed.patch new file mode 100644 index 0000000..38450ca --- /dev/null +++ b/0001-Issue-6929-Compilation-failure-with-rust-1.89-on-Fed.patch @@ -0,0 +1,33 @@ +From 8e341b4967212454f154cd08d7ceb2e2a429e2e8 Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +Date: Mon, 11 Aug 2025 13:19:13 +0200 +Subject: [PATCH] Issue 6929 - Compilation failure with rust-1.89 on Fedora ELN + +Bug Description: +The `ValueArrayRefIter` struct has a lifetime parameter `'a`. +But in the `iter` method the return type doesn't specify the lifetime parameter. + +Fix Description: +Make the lifetime explicit. + +Fixes: https://github.com/389ds/389-ds-base/issues/6929 +--- + src/slapi_r_plugin/src/value.rs | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/slapi_r_plugin/src/value.rs b/src/slapi_r_plugin/src/value.rs +index 2fd35c808..fec74ac25 100644 +--- a/src/slapi_r_plugin/src/value.rs ++++ b/src/slapi_r_plugin/src/value.rs +@@ -61,7 +61,7 @@ impl ValueArrayRef { + ValueArrayRef { raw_slapi_val } + } + +- pub fn iter(&self) -> ValueArrayRefIter { ++ pub fn iter(&self) -> ValueArrayRefIter<'_> { + ValueArrayRefIter { + idx: 0, + va_ref: &self, +-- +2.49.0 + diff --git a/0002-Issue-6822-Backend-creation-cleanup-and-Database-UI-.patch b/0002-Issue-6822-Backend-creation-cleanup-and-Database-UI-.patch new file mode 100644 index 0000000..92cfbe6 --- /dev/null +++ b/0002-Issue-6822-Backend-creation-cleanup-and-Database-UI-.patch @@ -0,0 +1,488 @@ +From 388d5ef9b64208db26373fc3b1b296a82ea689ba Mon Sep 17 00:00:00 2001 +From: Simon Pichugin +Date: Fri, 27 Jun 2025 18:43:39 -0700 +Subject: [PATCH] Issue 6822 - Backend creation cleanup and Database UI tab + error handling (#6823) + +Description: Add rollback functionality when mapping tree creation fails +during backend creation to prevent orphaned backends. +Improve error handling in Database, Replication and Monitoring UI tabs +to gracefully handle backend get-tree command failures. + +Fixes: https://github.com/389ds/389-ds-base/issues/6822 + +Reviewed by: @mreynolds389 (Thanks!) +--- + src/cockpit/389-console/src/database.jsx | 119 ++++++++------ + src/cockpit/389-console/src/monitor.jsx | 172 +++++++++++--------- + src/cockpit/389-console/src/replication.jsx | 55 ++++--- + src/lib389/lib389/backend.py | 18 +- + 4 files changed, 210 insertions(+), 154 deletions(-) + +diff --git a/src/cockpit/389-console/src/database.jsx b/src/cockpit/389-console/src/database.jsx +index c0c4be414..276125dfc 100644 +--- a/src/cockpit/389-console/src/database.jsx ++++ b/src/cockpit/389-console/src/database.jsx +@@ -478,6 +478,59 @@ export class Database extends React.Component { + } + + loadSuffixTree(fullReset) { ++ const treeData = [ ++ { ++ name: _("Global Database Configuration"), ++ icon: , ++ id: "dbconfig", ++ }, ++ { ++ name: _("Chaining Configuration"), ++ icon: , ++ id: "chaining-config", ++ }, ++ { ++ name: _("Backups & LDIFs"), ++ icon: , ++ id: "backups", ++ }, ++ { ++ name: _("Password Policies"), ++ id: "pwp", ++ icon: , ++ children: [ ++ { ++ name: _("Global Policy"), ++ icon: , ++ id: "pwpolicy", ++ }, ++ { ++ name: _("Local Policies"), ++ icon: , ++ id: "localpwpolicy", ++ }, ++ ], ++ defaultExpanded: true ++ }, ++ { ++ name: _("Suffixes"), ++ icon: , ++ id: "suffixes-tree", ++ children: [], ++ defaultExpanded: true, ++ action: ( ++ ++ ), ++ } ++ ]; ++ + const cmd = [ + "dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket", + "backend", "get-tree", +@@ -491,58 +544,20 @@ export class Database extends React.Component { + suffixData = JSON.parse(content); + this.processTree(suffixData); + } +- const treeData = [ +- { +- name: _("Global Database Configuration"), +- icon: , +- id: "dbconfig", +- }, +- { +- name: _("Chaining Configuration"), +- icon: , +- id: "chaining-config", +- }, +- { +- name: _("Backups & LDIFs"), +- icon: , +- id: "backups", +- }, +- { +- name: _("Password Policies"), +- id: "pwp", +- icon: , +- children: [ +- { +- name: _("Global Policy"), +- icon: , +- id: "pwpolicy", +- }, +- { +- name: _("Local Policies"), +- icon: , +- id: "localpwpolicy", +- }, +- ], +- defaultExpanded: true +- }, +- { +- name: _("Suffixes"), +- icon: , +- id: "suffixes-tree", +- children: suffixData, +- defaultExpanded: true, +- action: ( +- +- ), +- } +- ]; ++ ++ let current_node = this.state.node_name; ++ if (fullReset) { ++ current_node = DB_CONFIG; ++ } ++ ++ treeData[4].children = suffixData; // suffixes node ++ this.setState(() => ({ ++ nodes: treeData, ++ node_name: current_node, ++ }), this.loadAttrs); ++ }) ++ .fail(err => { ++ // Handle backend get-tree failure gracefully + let current_node = this.state.node_name; + if (fullReset) { + current_node = DB_CONFIG; +diff --git a/src/cockpit/389-console/src/monitor.jsx b/src/cockpit/389-console/src/monitor.jsx +index ad48d1f87..91a8e3e37 100644 +--- a/src/cockpit/389-console/src/monitor.jsx ++++ b/src/cockpit/389-console/src/monitor.jsx +@@ -200,6 +200,84 @@ export class Monitor extends React.Component { + } + + loadSuffixTree(fullReset) { ++ const basicData = [ ++ { ++ name: _("Server Statistics"), ++ icon: , ++ id: "server-monitor", ++ type: "server", ++ }, ++ { ++ name: _("Replication"), ++ icon: , ++ id: "replication-monitor", ++ type: "replication", ++ defaultExpanded: true, ++ children: [ ++ { ++ name: _("Synchronization Report"), ++ icon: , ++ id: "sync-report", ++ item: "sync-report", ++ type: "repl-mon", ++ }, ++ { ++ name: _("Log Analysis"), ++ icon: , ++ id: "log-analysis", ++ item: "log-analysis", ++ type: "repl-mon", ++ } ++ ], ++ }, ++ { ++ name: _("Database"), ++ icon: , ++ id: "database-monitor", ++ type: "database", ++ children: [], // Will be populated with treeData on success ++ defaultExpanded: true, ++ }, ++ { ++ name: _("Logging"), ++ icon: , ++ id: "log-monitor", ++ defaultExpanded: true, ++ children: [ ++ { ++ name: _("Access Log"), ++ icon: , ++ id: "access-log-monitor", ++ type: "log", ++ }, ++ { ++ name: _("Audit Log"), ++ icon: , ++ id: "audit-log-monitor", ++ type: "log", ++ }, ++ { ++ name: _("Audit Failure Log"), ++ icon: , ++ id: "auditfail-log-monitor", ++ type: "log", ++ }, ++ { ++ name: _("Errors Log"), ++ icon: , ++ id: "error-log-monitor", ++ type: "log", ++ }, ++ { ++ name: _("Security Log"), ++ icon: , ++ id: "security-log-monitor", ++ type: "log", ++ }, ++ ] ++ }, ++ ]; ++ + const cmd = [ + "dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket", + "backend", "get-tree", +@@ -210,83 +288,7 @@ export class Monitor extends React.Component { + .done(content => { + const treeData = JSON.parse(content); + this.processTree(treeData); +- const basicData = [ +- { +- name: _("Server Statistics"), +- icon: , +- id: "server-monitor", +- type: "server", +- }, +- { +- name: _("Replication"), +- icon: , +- id: "replication-monitor", +- type: "replication", +- defaultExpanded: true, +- children: [ +- { +- name: _("Synchronization Report"), +- icon: , +- id: "sync-report", +- item: "sync-report", +- type: "repl-mon", +- }, +- { +- name: _("Log Analysis"), +- icon: , +- id: "log-analysis", +- item: "log-analysis", +- type: "repl-mon", +- } +- ], +- }, +- { +- name: _("Database"), +- icon: , +- id: "database-monitor", +- type: "database", +- children: [], +- defaultExpanded: true, +- }, +- { +- name: _("Logging"), +- icon: , +- id: "log-monitor", +- defaultExpanded: true, +- children: [ +- { +- name: _("Access Log"), +- icon: , +- id: "access-log-monitor", +- type: "log", +- }, +- { +- name: _("Audit Log"), +- icon: , +- id: "audit-log-monitor", +- type: "log", +- }, +- { +- name: _("Audit Failure Log"), +- icon: , +- id: "auditfail-log-monitor", +- type: "log", +- }, +- { +- name: _("Errors Log"), +- icon: , +- id: "error-log-monitor", +- type: "log", +- }, +- { +- name: _("Security Log"), +- icon: , +- id: "security-log-monitor", +- type: "log", +- }, +- ] +- }, +- ]; ++ + let current_node = this.state.node_name; + let type = this.state.node_type; + if (fullReset) { +@@ -296,6 +298,22 @@ export class Monitor extends React.Component { + basicData[2].children = treeData; // database node + this.processReplSuffixes(basicData[1].children); + ++ this.setState(() => ({ ++ nodes: basicData, ++ node_name: current_node, ++ node_type: type, ++ }), this.update_tree_nodes); ++ }) ++ .fail(err => { ++ // Handle backend get-tree failure gracefully ++ let current_node = this.state.node_name; ++ let type = this.state.node_type; ++ if (fullReset) { ++ current_node = "server-monitor"; ++ type = "server"; ++ } ++ this.processReplSuffixes(basicData[1].children); ++ + this.setState(() => ({ + nodes: basicData, + node_name: current_node, +diff --git a/src/cockpit/389-console/src/replication.jsx b/src/cockpit/389-console/src/replication.jsx +index fa492fd2a..aa535bfc7 100644 +--- a/src/cockpit/389-console/src/replication.jsx ++++ b/src/cockpit/389-console/src/replication.jsx +@@ -177,6 +177,16 @@ export class Replication extends React.Component { + loaded: false + }); + ++ const basicData = [ ++ { ++ name: _("Suffixes"), ++ icon: , ++ id: "repl-suffixes", ++ children: [], ++ defaultExpanded: true ++ } ++ ]; ++ + const cmd = [ + "dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket", + "backend", "get-tree", +@@ -199,15 +209,7 @@ export class Replication extends React.Component { + } + } + } +- const basicData = [ +- { +- name: _("Suffixes"), +- icon: , +- id: "repl-suffixes", +- children: [], +- defaultExpanded: true +- } +- ]; ++ + let current_node = this.state.node_name; + let current_type = this.state.node_type; + let replicated = this.state.node_replicated; +@@ -258,6 +260,19 @@ export class Replication extends React.Component { + } + + basicData[0].children = treeData; ++ this.setState({ ++ nodes: basicData, ++ node_name: current_node, ++ node_type: current_type, ++ node_replicated: replicated, ++ }, () => { this.update_tree_nodes() }); ++ }) ++ .fail(err => { ++ // Handle backend get-tree failure gracefully ++ let current_node = this.state.node_name; ++ let current_type = this.state.node_type; ++ let replicated = this.state.node_replicated; ++ + this.setState({ + nodes: basicData, + node_name: current_node, +@@ -905,18 +920,18 @@ export class Replication extends React.Component { + disableTree: false + }); + }); +- }) +- .fail(err => { +- const errMsg = JSON.parse(err); +- this.props.addNotification( +- "error", +- cockpit.format(_("Error loading replication agreements configuration - $0"), errMsg.desc) +- ); +- this.setState({ +- suffixLoading: false, +- disableTree: false ++ }) ++ .fail(err => { ++ const errMsg = JSON.parse(err); ++ this.props.addNotification( ++ "error", ++ cockpit.format(_("Error loading replication agreements configuration - $0"), errMsg.desc) ++ ); ++ this.setState({ ++ suffixLoading: false, ++ disableTree: false ++ }); + }); +- }); + }) + .fail(err => { + // changelog failure +diff --git a/src/lib389/lib389/backend.py b/src/lib389/lib389/backend.py +index 1d000ed66..53f15b6b0 100644 +--- a/src/lib389/lib389/backend.py ++++ b/src/lib389/lib389/backend.py +@@ -694,24 +694,32 @@ class Backend(DSLdapObject): + parent_suffix = properties.pop('parent', False) + + # Okay, now try to make the backend. +- super(Backend, self).create(dn, properties, basedn) ++ backend_obj = super(Backend, self).create(dn, properties, basedn) + + # We check if the mapping tree exists in create, so do this *after* + if create_mapping_tree is True: +- properties = { ++ mapping_tree_properties = { + 'cn': self._nprops_stash['nsslapd-suffix'], + 'nsslapd-state': 'backend', + 'nsslapd-backend': self._nprops_stash['cn'], + } + if parent_suffix: + # This is a subsuffix, set the parent suffix +- properties['nsslapd-parent-suffix'] = parent_suffix +- self._mts.create(properties=properties) ++ mapping_tree_properties['nsslapd-parent-suffix'] = parent_suffix ++ ++ try: ++ self._mts.create(properties=mapping_tree_properties) ++ except Exception as e: ++ try: ++ backend_obj.delete() ++ except Exception as cleanup_error: ++ self._instance.log.error(f"Failed to cleanup backend after mapping tree creation failure: {cleanup_error}") ++ raise e + + # We can't create the sample entries unless a mapping tree was installed. + if sample_entries is not False and create_mapping_tree is True: + self.create_sample_entries(sample_entries) +- return self ++ return backend_obj + + def delete(self): + """Deletes the backend, it's mapping tree and all related indices. +-- +2.49.0 + diff --git a/0003-Issue-6753-Add-add_exclude_subtree-and-remove_exclud.patch b/0003-Issue-6753-Add-add_exclude_subtree-and-remove_exclud.patch new file mode 100644 index 0000000..a134041 --- /dev/null +++ b/0003-Issue-6753-Add-add_exclude_subtree-and-remove_exclud.patch @@ -0,0 +1,515 @@ +From 9da3349d53f4073740ddb1aca97713e13cb40cd0 Mon Sep 17 00:00:00 2001 +From: Lenka Doudova +Date: Mon, 9 Jun 2025 15:15:04 +0200 +Subject: [PATCH] Issue 6753 - Add 'add_exclude_subtree' and + 'remove_exclude_subtree' methods to Attribute uniqueness plugin + +Description: +Adding 'add_exclude_subtree' and 'remove_exclude_subtree' methods to AttributeUniquenessPlugin in +order to be able to easily add or remove an exclude subtree. +Porting ticket 47927 test to +dirsrvtests/tests/suites/plugins/attruniq_test.py + +Relates: #6753 + +Author: Lenka Doudova + +Reviewers: Simon Pichugin, Mark Reynolds +--- + .../tests/suites/plugins/attruniq_test.py | 171 +++++++++++ + dirsrvtests/tests/tickets/ticket47927_test.py | 267 ------------------ + src/lib389/lib389/plugins.py | 10 + + 3 files changed, 181 insertions(+), 267 deletions(-) + delete mode 100644 dirsrvtests/tests/tickets/ticket47927_test.py + +diff --git a/dirsrvtests/tests/suites/plugins/attruniq_test.py b/dirsrvtests/tests/suites/plugins/attruniq_test.py +index c1ccad9ae..aac659c29 100644 +--- a/dirsrvtests/tests/suites/plugins/attruniq_test.py ++++ b/dirsrvtests/tests/suites/plugins/attruniq_test.py +@@ -10,6 +10,7 @@ import pytest + import ldap + import logging + from lib389.plugins import AttributeUniquenessPlugin ++from lib389.idm.nscontainer import nsContainers + from lib389.idm.user import UserAccounts + from lib389.idm.group import Groups + from lib389._constants import DEFAULT_SUFFIX +@@ -22,6 +23,19 @@ log = logging.getLogger(__name__) + MAIL_ATTR_VALUE = 'non-uniq@value.net' + MAIL_ATTR_VALUE_ALT = 'alt-mail@value.net' + ++EXCLUDED_CONTAINER_CN = "excluded_container" ++EXCLUDED_CONTAINER_DN = "cn={},{}".format(EXCLUDED_CONTAINER_CN, DEFAULT_SUFFIX) ++ ++EXCLUDED_BIS_CONTAINER_CN = "excluded_bis_container" ++EXCLUDED_BIS_CONTAINER_DN = "cn={},{}".format(EXCLUDED_BIS_CONTAINER_CN, DEFAULT_SUFFIX) ++ ++ENFORCED_CONTAINER_CN = "enforced_container" ++ ++USER_1_CN = "test_1" ++USER_2_CN = "test_2" ++USER_3_CN = "test_3" ++USER_4_CN = "test_4" ++ + + def test_modrdn_attr_uniqueness(topology_st): + """Test that we can not add two entries that have the same attr value that is +@@ -154,3 +168,160 @@ def test_multiple_attr_uniqueness(topology_st): + testuser2.delete() + attruniq.disable() + attruniq.delete() ++ ++ ++def test_exclude_subtrees(topology_st): ++ """ Test attribute uniqueness with exclude scope ++ ++ :id: 43d29a60-40e1-4ebd-b897-6ef9f20e9f27 ++ :setup: Standalone instance ++ :steps: ++ 1. Setup and enable attribute uniqueness plugin for telephonenumber unique attribute ++ 2. Create subtrees and test users ++ 3. Add a unique attribute to a user within uniqueness scope ++ 4. Add exclude subtree ++ 5. Try to add existing value attribute to an entry within uniqueness scope ++ 6. Try to add existing value attribute to an entry within exclude scope ++ 7. Remove the attribute from affected entries ++ 8. Add a unique attribute to a user within exclude scope ++ 9. Try to add existing value attribute to an entry within uniqueness scope ++ 10. Try to add existing value attribute to another entry within uniqueness scope ++ 11. Remove the attribute from affected entries ++ 12. Add another exclude subtree ++ 13. Add a unique attribute to a user within uniqueness scope ++ 14. Try to add existing value attribute to an entry within uniqueness scope ++ 15. Try to add existing value attribute to an entry within exclude scope ++ 16. Try to add existing value attribute to an entry within another exclude scope ++ 17. Clean up entries ++ :expectedresults: ++ 1. Success ++ 2. Success ++ 3. Success ++ 4. Success ++ 5. Should raise CONSTRAINT_VIOLATION ++ 6. Success ++ 7. Success ++ 8. Success ++ 9. Success ++ 10. Should raise CONSTRAINT_VIOLATION ++ 11. Success ++ 12. Success ++ 13. Success ++ 14. Should raise CONSTRAINT_VIOLATION ++ 15. Success ++ 16. Success ++ 17. Success ++ """ ++ log.info('Setup attribute uniqueness plugin') ++ attruniq = AttributeUniquenessPlugin(topology_st.standalone, dn="cn=attruniq,cn=plugins,cn=config") ++ attruniq.create(properties={'cn': 'attruniq'}) ++ attruniq.add_unique_attribute('telephonenumber') ++ attruniq.add_unique_subtree(DEFAULT_SUFFIX) ++ attruniq.enable_all_subtrees() ++ attruniq.enable() ++ topology_st.standalone.restart() ++ ++ log.info('Create subtrees container') ++ containers = nsContainers(topology_st.standalone, DEFAULT_SUFFIX) ++ cont1 = containers.create(properties={'cn': EXCLUDED_CONTAINER_CN}) ++ cont2 = containers.create(properties={'cn': EXCLUDED_BIS_CONTAINER_CN}) ++ cont3 = containers.create(properties={'cn': ENFORCED_CONTAINER_CN}) ++ ++ log.info('Create test users') ++ users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX, ++ rdn='cn={}'.format(ENFORCED_CONTAINER_CN)) ++ users_excluded = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX, ++ rdn='cn={}'.format(EXCLUDED_CONTAINER_CN)) ++ users_excluded2 = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX, ++ rdn='cn={}'.format(EXCLUDED_BIS_CONTAINER_CN)) ++ ++ user1 = users.create(properties={'cn': USER_1_CN, ++ 'uid': USER_1_CN, ++ 'sn': USER_1_CN, ++ 'uidNumber': '1', ++ 'gidNumber': '11', ++ 'homeDirectory': '/home/{}'.format(USER_1_CN)}) ++ user2 = users.create(properties={'cn': USER_2_CN, ++ 'uid': USER_2_CN, ++ 'sn': USER_2_CN, ++ 'uidNumber': '2', ++ 'gidNumber': '22', ++ 'homeDirectory': '/home/{}'.format(USER_2_CN)}) ++ user3 = users_excluded.create(properties={'cn': USER_3_CN, ++ 'uid': USER_3_CN, ++ 'sn': USER_3_CN, ++ 'uidNumber': '3', ++ 'gidNumber': '33', ++ 'homeDirectory': '/home/{}'.format(USER_3_CN)}) ++ user4 = users_excluded2.create(properties={'cn': USER_4_CN, ++ 'uid': USER_4_CN, ++ 'sn': USER_4_CN, ++ 'uidNumber': '4', ++ 'gidNumber': '44', ++ 'homeDirectory': '/home/{}'.format(USER_4_CN)}) ++ ++ UNIQUE_VALUE = '1234' ++ ++ try: ++ log.info('Create user with unique attribute') ++ user1.add('telephonenumber', UNIQUE_VALUE) ++ assert user1.present('telephonenumber', UNIQUE_VALUE) ++ ++ log.info('Add exclude subtree') ++ attruniq.add_exclude_subtree(EXCLUDED_CONTAINER_DN) ++ topology_st.standalone.restart() ++ ++ log.info('Verify an already used attribute value cannot be added within the same subtree') ++ with pytest.raises(ldap.CONSTRAINT_VIOLATION): ++ user2.add('telephonenumber', UNIQUE_VALUE) ++ ++ log.info('Verify an entry with same attribute value can be added within exclude subtree') ++ user3.add('telephonenumber', UNIQUE_VALUE) ++ assert user3.present('telephonenumber', UNIQUE_VALUE) ++ ++ log.info('Cleanup unique attribute values') ++ user1.remove_all('telephonenumber') ++ user3.remove_all('telephonenumber') ++ ++ log.info('Add a unique value to an entry in excluded scope') ++ user3.add('telephonenumber', UNIQUE_VALUE) ++ assert user3.present('telephonenumber', UNIQUE_VALUE) ++ ++ log.info('Verify the same value can be added to an entry within uniqueness scope') ++ user1.add('telephonenumber', UNIQUE_VALUE) ++ assert user1.present('telephonenumber', UNIQUE_VALUE) ++ ++ log.info('Verify that yet another same value cannot be added to another entry within uniqueness scope') ++ with pytest.raises(ldap.CONSTRAINT_VIOLATION): ++ user2.add('telephonenumber', UNIQUE_VALUE) ++ ++ log.info('Cleanup unique attribute values') ++ user1.remove_all('telephonenumber') ++ user3.remove_all('telephonenumber') ++ ++ log.info('Add another exclude subtree') ++ attruniq.add_exclude_subtree(EXCLUDED_BIS_CONTAINER_DN) ++ topology_st.standalone.restart() ++ ++ user1.add('telephonenumber', UNIQUE_VALUE) ++ log.info('Verify an already used attribute value cannot be added within the same subtree') ++ with pytest.raises(ldap.CONSTRAINT_VIOLATION): ++ user2.add('telephonenumber', UNIQUE_VALUE) ++ ++ log.info('Verify an already used attribute can be added to an entry in exclude scope') ++ user3.add('telephonenumber', UNIQUE_VALUE) ++ assert user3.present('telephonenumber', UNIQUE_VALUE) ++ user4.add('telephonenumber', UNIQUE_VALUE) ++ assert user4.present('telephonenumber', UNIQUE_VALUE) ++ ++ finally: ++ log.info('Clean up users, containers and attribute uniqueness plugin') ++ user1.delete() ++ user2.delete() ++ user3.delete() ++ user4.delete() ++ cont1.delete() ++ cont2.delete() ++ cont3.delete() ++ attruniq.disable() ++ attruniq.delete() +\ No newline at end of file +diff --git a/dirsrvtests/tests/tickets/ticket47927_test.py b/dirsrvtests/tests/tickets/ticket47927_test.py +deleted file mode 100644 +index 887fe1af4..000000000 +--- a/dirsrvtests/tests/tickets/ticket47927_test.py ++++ /dev/null +@@ -1,267 +0,0 @@ +-# --- BEGIN COPYRIGHT BLOCK --- +-# Copyright (C) 2016 Red Hat, Inc. +-# All rights reserved. +-# +-# License: GPL (version 3 or any later version). +-# See LICENSE for details. +-# --- END COPYRIGHT BLOCK --- +-# +-import pytest +-from lib389.tasks import * +-from lib389.utils import * +-from lib389.topologies import topology_st +- +-from lib389._constants import SUFFIX, DEFAULT_SUFFIX, PLUGIN_ATTR_UNIQUENESS +- +-# Skip on older versions +-pytestmark = [pytest.mark.tier2, +- pytest.mark.skipif(ds_is_older('1.3.4'), reason="Not implemented")] +- +-logging.getLogger(__name__).setLevel(logging.DEBUG) +-log = logging.getLogger(__name__) +- +-EXCLUDED_CONTAINER_CN = "excluded_container" +-EXCLUDED_CONTAINER_DN = "cn=%s,%s" % (EXCLUDED_CONTAINER_CN, SUFFIX) +- +-EXCLUDED_BIS_CONTAINER_CN = "excluded_bis_container" +-EXCLUDED_BIS_CONTAINER_DN = "cn=%s,%s" % (EXCLUDED_BIS_CONTAINER_CN, SUFFIX) +- +-ENFORCED_CONTAINER_CN = "enforced_container" +-ENFORCED_CONTAINER_DN = "cn=%s,%s" % (ENFORCED_CONTAINER_CN, SUFFIX) +- +-USER_1_CN = "test_1" +-USER_1_DN = "cn=%s,%s" % (USER_1_CN, ENFORCED_CONTAINER_DN) +-USER_2_CN = "test_2" +-USER_2_DN = "cn=%s,%s" % (USER_2_CN, ENFORCED_CONTAINER_DN) +-USER_3_CN = "test_3" +-USER_3_DN = "cn=%s,%s" % (USER_3_CN, EXCLUDED_CONTAINER_DN) +-USER_4_CN = "test_4" +-USER_4_DN = "cn=%s,%s" % (USER_4_CN, EXCLUDED_BIS_CONTAINER_DN) +- +- +-def test_ticket47927_init(topology_st): +- topology_st.standalone.plugins.enable(name=PLUGIN_ATTR_UNIQUENESS) +- try: +- topology_st.standalone.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config', +- [(ldap.MOD_REPLACE, 'uniqueness-attribute-name', b'telephonenumber'), +- (ldap.MOD_REPLACE, 'uniqueness-subtrees', ensure_bytes(DEFAULT_SUFFIX)), +- ]) +- except ldap.LDAPError as e: +- log.fatal('test_ticket47927: Failed to configure plugin for "telephonenumber": error ' + e.args[0]['desc']) +- assert False +- topology_st.standalone.restart(timeout=120) +- +- topology_st.standalone.add_s(Entry((EXCLUDED_CONTAINER_DN, {'objectclass': "top nscontainer".split(), +- 'cn': EXCLUDED_CONTAINER_CN}))) +- topology_st.standalone.add_s(Entry((EXCLUDED_BIS_CONTAINER_DN, {'objectclass': "top nscontainer".split(), +- 'cn': EXCLUDED_BIS_CONTAINER_CN}))) +- topology_st.standalone.add_s(Entry((ENFORCED_CONTAINER_DN, {'objectclass': "top nscontainer".split(), +- 'cn': ENFORCED_CONTAINER_CN}))) +- +- # adding an entry on a stage with a different 'cn' +- topology_st.standalone.add_s(Entry((USER_1_DN, { +- 'objectclass': "top person".split(), +- 'sn': USER_1_CN, +- 'cn': USER_1_CN}))) +- # adding an entry on a stage with a different 'cn' +- topology_st.standalone.add_s(Entry((USER_2_DN, { +- 'objectclass': "top person".split(), +- 'sn': USER_2_CN, +- 'cn': USER_2_CN}))) +- topology_st.standalone.add_s(Entry((USER_3_DN, { +- 'objectclass': "top person".split(), +- 'sn': USER_3_CN, +- 'cn': USER_3_CN}))) +- topology_st.standalone.add_s(Entry((USER_4_DN, { +- 'objectclass': "top person".split(), +- 'sn': USER_4_CN, +- 'cn': USER_4_CN}))) +- +- +-def test_ticket47927_one(topology_st): +- ''' +- Check that uniqueness is enforce on all SUFFIX +- ''' +- UNIQUE_VALUE = b'1234' +- try: +- topology_st.standalone.modify_s(USER_1_DN, +- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) +- except ldap.LDAPError as e: +- log.fatal('test_ticket47927_one: Failed to set the telephonenumber for %s: %s' % (USER_1_DN, e.args[0]['desc'])) +- assert False +- +- # we expect to fail because user1 is in the scope of the plugin +- try: +- topology_st.standalone.modify_s(USER_2_DN, +- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) +- log.fatal('test_ticket47927_one: unexpected success to set the telephonenumber for %s' % (USER_2_DN)) +- assert False +- except ldap.LDAPError as e: +- log.fatal('test_ticket47927_one: Failed (expected) to set the telephonenumber for %s: %s' % ( +- USER_2_DN, e.args[0]['desc'])) +- pass +- +- # we expect to fail because user1 is in the scope of the plugin +- try: +- topology_st.standalone.modify_s(USER_3_DN, +- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) +- log.fatal('test_ticket47927_one: unexpected success to set the telephonenumber for %s' % (USER_3_DN)) +- assert False +- except ldap.LDAPError as e: +- log.fatal('test_ticket47927_one: Failed (expected) to set the telephonenumber for %s: %s' % ( +- USER_3_DN, e.args[0]['desc'])) +- pass +- +- +-def test_ticket47927_two(topology_st): +- ''' +- Exclude the EXCLUDED_CONTAINER_DN from the uniqueness plugin +- ''' +- try: +- topology_st.standalone.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config', +- [(ldap.MOD_REPLACE, 'uniqueness-exclude-subtrees', ensure_bytes(EXCLUDED_CONTAINER_DN))]) +- except ldap.LDAPError as e: +- log.fatal('test_ticket47927_two: Failed to configure plugin for to exclude %s: error %s' % ( +- EXCLUDED_CONTAINER_DN, e.args[0]['desc'])) +- assert False +- topology_st.standalone.restart(timeout=120) +- +- +-def test_ticket47927_three(topology_st): +- ''' +- Check that uniqueness is enforced on full SUFFIX except EXCLUDED_CONTAINER_DN +- First case: it exists an entry (with the same attribute value) in the scope +- of the plugin and we set the value in an entry that is in an excluded scope +- ''' +- UNIQUE_VALUE = b'9876' +- try: +- topology_st.standalone.modify_s(USER_1_DN, +- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) +- except ldap.LDAPError as e: +- log.fatal('test_ticket47927_three: Failed to set the telephonenumber ' + e.args[0]['desc']) +- assert False +- +- # we should not be allowed to set this value (because user1 is in the scope) +- try: +- topology_st.standalone.modify_s(USER_2_DN, +- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) +- log.fatal('test_ticket47927_three: unexpected success to set the telephonenumber for %s' % (USER_2_DN)) +- assert False +- except ldap.LDAPError as e: +- log.fatal('test_ticket47927_three: Failed (expected) to set the telephonenumber for %s: %s' % ( +- USER_2_DN, e.args[0]['desc'])) +- +- # USER_3_DN is in EXCLUDED_CONTAINER_DN so update should be successful +- try: +- topology_st.standalone.modify_s(USER_3_DN, +- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) +- log.fatal('test_ticket47927_three: success to set the telephonenumber for %s' % (USER_3_DN)) +- except ldap.LDAPError as e: +- log.fatal('test_ticket47927_three: Failed (unexpected) to set the telephonenumber for %s: %s' % ( +- USER_3_DN, e.args[0]['desc'])) +- assert False +- +- +-def test_ticket47927_four(topology_st): +- ''' +- Check that uniqueness is enforced on full SUFFIX except EXCLUDED_CONTAINER_DN +- Second case: it exists an entry (with the same attribute value) in an excluded scope +- of the plugin and we set the value in an entry is in the scope +- ''' +- UNIQUE_VALUE = b'1111' +- # USER_3_DN is in EXCLUDED_CONTAINER_DN so update should be successful +- try: +- topology_st.standalone.modify_s(USER_3_DN, +- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) +- log.fatal('test_ticket47927_four: success to set the telephonenumber for %s' % USER_3_DN) +- except ldap.LDAPError as e: +- log.fatal('test_ticket47927_four: Failed (unexpected) to set the telephonenumber for %s: %s' % ( +- USER_3_DN, e.args[0]['desc'])) +- assert False +- +- # we should be allowed to set this value (because user3 is excluded from scope) +- try: +- topology_st.standalone.modify_s(USER_1_DN, +- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) +- except ldap.LDAPError as e: +- log.fatal( +- 'test_ticket47927_four: Failed to set the telephonenumber for %s: %s' % (USER_1_DN, e.args[0]['desc'])) +- assert False +- +- # we should not be allowed to set this value (because user1 is in the scope) +- try: +- topology_st.standalone.modify_s(USER_2_DN, +- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) +- log.fatal('test_ticket47927_four: unexpected success to set the telephonenumber %s' % USER_2_DN) +- assert False +- except ldap.LDAPError as e: +- log.fatal('test_ticket47927_four: Failed (expected) to set the telephonenumber for %s: %s' % ( +- USER_2_DN, e.args[0]['desc'])) +- pass +- +- +-def test_ticket47927_five(topology_st): +- ''' +- Exclude the EXCLUDED_BIS_CONTAINER_DN from the uniqueness plugin +- ''' +- try: +- topology_st.standalone.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config', +- [(ldap.MOD_ADD, 'uniqueness-exclude-subtrees', ensure_bytes(EXCLUDED_BIS_CONTAINER_DN))]) +- except ldap.LDAPError as e: +- log.fatal('test_ticket47927_five: Failed to configure plugin for to exclude %s: error %s' % ( +- EXCLUDED_BIS_CONTAINER_DN, e.args[0]['desc'])) +- assert False +- topology_st.standalone.restart(timeout=120) +- topology_st.standalone.getEntry('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config', ldap.SCOPE_BASE) +- +- +-def test_ticket47927_six(topology_st): +- ''' +- Check that uniqueness is enforced on full SUFFIX except EXCLUDED_CONTAINER_DN +- and EXCLUDED_BIS_CONTAINER_DN +- First case: it exists an entry (with the same attribute value) in the scope +- of the plugin and we set the value in an entry that is in an excluded scope +- ''' +- UNIQUE_VALUE = b'222' +- try: +- topology_st.standalone.modify_s(USER_1_DN, +- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) +- except ldap.LDAPError as e: +- log.fatal('test_ticket47927_six: Failed to set the telephonenumber ' + e.args[0]['desc']) +- assert False +- +- # we should not be allowed to set this value (because user1 is in the scope) +- try: +- topology_st.standalone.modify_s(USER_2_DN, +- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) +- log.fatal('test_ticket47927_six: unexpected success to set the telephonenumber for %s' % (USER_2_DN)) +- assert False +- except ldap.LDAPError as e: +- log.fatal('test_ticket47927_six: Failed (expected) to set the telephonenumber for %s: %s' % ( +- USER_2_DN, e.args[0]['desc'])) +- +- # USER_3_DN is in EXCLUDED_CONTAINER_DN so update should be successful +- try: +- topology_st.standalone.modify_s(USER_3_DN, +- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) +- log.fatal('test_ticket47927_six: success to set the telephonenumber for %s' % (USER_3_DN)) +- except ldap.LDAPError as e: +- log.fatal('test_ticket47927_six: Failed (unexpected) to set the telephonenumber for %s: %s' % ( +- USER_3_DN, e.args[0]['desc'])) +- assert False +- # USER_4_DN is in EXCLUDED_CONTAINER_DN so update should be successful +- try: +- topology_st.standalone.modify_s(USER_4_DN, +- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) +- log.fatal('test_ticket47927_six: success to set the telephonenumber for %s' % (USER_4_DN)) +- except ldap.LDAPError as e: +- log.fatal('test_ticket47927_six: Failed (unexpected) to set the telephonenumber for %s: %s' % ( +- USER_4_DN, e.args[0]['desc'])) +- assert False +- +- +-if __name__ == '__main__': +- # Run isolated +- # -s for DEBUG mode +- CURRENT_FILE = os.path.realpath(__file__) +- pytest.main("-s %s" % CURRENT_FILE) +diff --git a/src/lib389/lib389/plugins.py b/src/lib389/lib389/plugins.py +index 31bbfa502..977091726 100644 +--- a/src/lib389/lib389/plugins.py ++++ b/src/lib389/lib389/plugins.py +@@ -175,6 +175,16 @@ class AttributeUniquenessPlugin(Plugin): + + self.set('uniqueness-across-all-subtrees', 'off') + ++ def add_exclude_subtree(self, basedn): ++ """Add a uniqueness-exclude-subtrees attribute""" ++ ++ self.add('uniqueness-exclude-subtrees', basedn) ++ ++ def remove_exclude_subtree(self, basedn): ++ """Remove a uniqueness-exclude-subtrees attribute""" ++ ++ self.remove('uniqueness-exclude-subtrees', basedn) ++ + + class AttributeUniquenessPlugins(DSLdapObjects): + """A DSLdapObjects entity which represents Attribute Uniqueness plugin instances +-- +2.49.0 + diff --git a/0004-Issue-6857-uiduniq-allow-specifying-match-rules-in-t.patch b/0004-Issue-6857-uiduniq-allow-specifying-match-rules-in-t.patch new file mode 100644 index 0000000..46f6e8c --- /dev/null +++ b/0004-Issue-6857-uiduniq-allow-specifying-match-rules-in-t.patch @@ -0,0 +1,45 @@ +From 4fb3a2ea084c1de3ba60ca97a5dd14fc7b8225bd Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Wed, 9 Jul 2025 12:08:09 +0300 +Subject: [PATCH] Issue 6857 - uiduniq: allow specifying match rules in the + filter + +Allow uniqueness plugin to work with attributes where uniqueness should +be enforced using different matching rule than the one defined for the +attribute itself. + +Since uniqueness plugin configuration can contain multiple attributes, +add matching rule right to the attribute as it is used in the LDAP rule +(e.g. 'attribute:caseIgnoreMatch:' to force 'attribute' to be searched +with case-insensitive matching rule instead of the original matching +rule. + +Fixes: https://github.com/389ds/389-ds-base/issues/6857 + +Signed-off-by: Alexander Bokovoy +--- + ldap/servers/plugins/uiduniq/uid.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/ldap/servers/plugins/uiduniq/uid.c b/ldap/servers/plugins/uiduniq/uid.c +index 053af4f9d..887e79d78 100644 +--- a/ldap/servers/plugins/uiduniq/uid.c ++++ b/ldap/servers/plugins/uiduniq/uid.c +@@ -1030,7 +1030,14 @@ preop_add(Slapi_PBlock *pb) + } + + for (i = 0; attrNames && attrNames[i]; i++) { ++ char *attr_match = strchr(attrNames[i], ':'); ++ if (attr_match != NULL) { ++ attr_match[0] = '\0'; ++ } + err = slapi_entry_attr_find(e, attrNames[i], &attr); ++ if (attr_match != NULL) { ++ attr_match[0] = ':'; ++ } + if (!err) { + /* + * Passed all the requirements - this is an operation we +-- +2.49.0 + diff --git a/0005-Issue-6756-CLI-UI-Properly-handle-disabled-NDN-cache.patch b/0005-Issue-6756-CLI-UI-Properly-handle-disabled-NDN-cache.patch new file mode 100644 index 0000000..8a36611 --- /dev/null +++ b/0005-Issue-6756-CLI-UI-Properly-handle-disabled-NDN-cache.patch @@ -0,0 +1,1201 @@ +From 64289e4e4fcab868f099fdf6f3a9b77e9a8f78a5 Mon Sep 17 00:00:00 2001 +From: Simon Pichugin +Date: Thu, 10 Jul 2025 11:53:12 -0700 +Subject: [PATCH] Issue 6756 - CLI, UI - Properly handle disabled NDN cache + (#6757) + +Description: Fix the db_monitor function in monitor.py to check if +nsslapd-ndn-cache-enabled is off and conditionally include NDN cache +statistics only when enabled. + +Update dbMonitor.jsx components to detect when NDN cache is disabled and +conditionally render NDN cache tabs, charts, and related content with proper +fallback display when disabled. + +Add test_ndn_cache_disabled to verify both JSON and non-JSON output formats +correctly handle when NDN cache is turned off and on. + +Fixes: https://github.com/389ds/389-ds-base/issues/6756 + +Reviewed by: @mreynolds389 (Thanks!) +--- + dirsrvtests/tests/suites/clu/dbmon_test.py | 90 +++ + src/cockpit/389-console/src/database.jsx | 4 +- + .../src/lib/database/databaseConfig.jsx | 48 +- + .../389-console/src/lib/monitor/dbMonitor.jsx | 735 ++++++++++-------- + src/lib389/lib389/cli_conf/monitor.py | 77 +- + 5 files changed, 580 insertions(+), 374 deletions(-) + +diff --git a/dirsrvtests/tests/suites/clu/dbmon_test.py b/dirsrvtests/tests/suites/clu/dbmon_test.py +index 5eeaca162..bf57690c4 100644 +--- a/dirsrvtests/tests/suites/clu/dbmon_test.py ++++ b/dirsrvtests/tests/suites/clu/dbmon_test.py +@@ -11,6 +11,7 @@ import subprocess + import pytest + import json + import glob ++import re + + from lib389.tasks import * + from lib389.utils import * +@@ -272,6 +273,95 @@ def test_dbmon_mp_pagesize(topology_st): + assert real_free_percentage == dbmon_free_percentage + + ++def test_ndn_cache_disabled(topology_st): ++ """Test dbmon output when ndn-cache-enabled is turned off ++ ++ :id: 760e217c-70e8-4767-b504-dda7ba2e1f64 ++ :setup: Standalone instance ++ :steps: ++ 1. Run dbmon with nsslapd-ndn-cache-enabled=on (default) ++ 2. Verify NDN cache stats are present in the output ++ 3. Set nsslapd-ndn-cache-enabled=off and restart ++ 4. Run dbmon again and verify NDN cache stats are not present ++ 5. Set nsslapd-ndn-cache-enabled=on and restart ++ 6. Run dbmon again and verify NDN cache stats are back ++ :expectedresults: ++ 1. Success ++ 2. Should display NDN cache data ++ 3. Success ++ 4. Should not display NDN cache data ++ 5. Success ++ 6. Should display NDN cache data ++ """ ++ inst = topology_st.standalone ++ args = FakeArgs() ++ args.backends = None ++ args.indexes = False ++ args.json = True ++ lc = LogCapture() ++ ++ log.info("Testing with NDN cache enabled (default)") ++ db_monitor(inst, DEFAULT_SUFFIX, lc.log, args) ++ db_mon_as_str = "".join((str(rec) for rec in lc.outputs)) ++ db_mon_as_str = re.sub("^[^{]*{", "{", db_mon_as_str)[:-2] ++ db_mon = json.loads(db_mon_as_str) ++ ++ assert 'ndncache' in db_mon ++ assert 'hit_ratio' in db_mon['ndncache'] ++ lc.flush() ++ ++ log.info("Setting nsslapd-ndn-cache-enabled to OFF") ++ inst.config.set('nsslapd-ndn-cache-enabled', 'off') ++ inst.restart() ++ ++ log.info("Testing with NDN cache disabled") ++ db_monitor(inst, DEFAULT_SUFFIX, lc.log, args) ++ db_mon_as_str = "".join((str(rec) for rec in lc.outputs)) ++ db_mon_as_str = re.sub("^[^{]*{", "{", db_mon_as_str)[:-2] ++ db_mon = json.loads(db_mon_as_str) ++ ++ assert 'ndncache' not in db_mon ++ lc.flush() ++ ++ log.info("Setting nsslapd-ndn-cache-enabled to ON") ++ inst.config.set('nsslapd-ndn-cache-enabled', 'on') ++ inst.restart() ++ ++ log.info("Testing with NDN cache re-enabled") ++ db_monitor(inst, DEFAULT_SUFFIX, lc.log, args) ++ db_mon_as_str = "".join((str(rec) for rec in lc.outputs)) ++ db_mon_as_str = re.sub("^[^{]*{", "{", db_mon_as_str)[:-2] ++ db_mon = json.loads(db_mon_as_str) ++ ++ assert 'ndncache' in db_mon ++ assert 'hit_ratio' in db_mon['ndncache'] ++ lc.flush() ++ ++ args.json = False ++ ++ log.info("Testing with NDN cache enabled - non-JSON output") ++ db_monitor(inst, DEFAULT_SUFFIX, lc.log, args) ++ output = "".join((str(rec) for rec in lc.outputs)) ++ ++ assert "Normalized DN Cache:" in output ++ assert "Cache Hit Ratio:" in output ++ lc.flush() ++ ++ log.info("Setting nsslapd-ndn-cache-enabled to OFF") ++ inst.config.set('nsslapd-ndn-cache-enabled', 'off') ++ inst.restart() ++ ++ log.info("Testing with NDN cache disabled - non-JSON output") ++ db_monitor(inst, DEFAULT_SUFFIX, lc.log, args) ++ output = "".join((str(rec) for rec in lc.outputs)) ++ ++ assert "Normalized DN Cache:" not in output ++ lc.flush() ++ ++ inst.config.set('nsslapd-ndn-cache-enabled', 'on') ++ inst.restart() ++ ++ + if __name__ == '__main__': + # Run isolated + # -s for DEBUG mode +diff --git a/src/cockpit/389-console/src/database.jsx b/src/cockpit/389-console/src/database.jsx +index 276125dfc..86b642b92 100644 +--- a/src/cockpit/389-console/src/database.jsx ++++ b/src/cockpit/389-console/src/database.jsx +@@ -198,7 +198,7 @@ export class Database extends React.Component { + }); + const cmd = [ + "dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket", +- "config", "get", "nsslapd-ndn-cache-max-size" ++ "config", "get", "nsslapd-ndn-cache-max-size", "nsslapd-ndn-cache-enabled" + ]; + log_cmd("loadNDN", "Load NDN cache size", cmd); + cockpit +@@ -206,10 +206,12 @@ export class Database extends React.Component { + .done(content => { + const config = JSON.parse(content); + const attrs = config.attrs; ++ const ndn_cache_enabled = attrs['nsslapd-ndn-cache-enabled'][0] === "on"; + this.setState(prevState => ({ + globalDBConfig: { + ...prevState.globalDBConfig, + ndncachemaxsize: attrs['nsslapd-ndn-cache-max-size'][0], ++ ndn_cache_enabled: ndn_cache_enabled, + }, + configUpdated: 0, + loaded: true, +diff --git a/src/cockpit/389-console/src/lib/database/databaseConfig.jsx b/src/cockpit/389-console/src/lib/database/databaseConfig.jsx +index 4c7fce706..adb8227d7 100644 +--- a/src/cockpit/389-console/src/lib/database/databaseConfig.jsx ++++ b/src/cockpit/389-console/src/lib/database/databaseConfig.jsx +@@ -2,12 +2,16 @@ import cockpit from "cockpit"; + import React from "react"; + import { log_cmd } from "../tools.jsx"; + import { ++ Alert, + Button, + Checkbox, ++ Form, + Grid, + GridItem, ++ Hr, + NumberInput, + Spinner, ++ Switch, + Tab, + Tabs, + TabTitleText, +@@ -852,12 +856,29 @@ export class GlobalDatabaseConfig extends React.Component { + + {_("NDN Cache")}}> +
++ ++ {this.props.data.ndn_cache_enabled === false && ( ++ ++ ++ {_("The Normalized DN Cache is currently disabled. To enable it, go to Server Settings → Tuning & Limits and enable 'Normalized DN Cache', then restart the server for the changes to take effect.")} ++ ++ ++ )} ++ + + +- {_("Normalized DN Cache Max Size")} ++ {_("Normalized DN Cache Max Size") } + + + + + +@@ -1470,7 +1491,7 @@ export class GlobalDatabaseConfigMDB extends React.Component { + {_("Database Size")}}> +
+ + +@@ -1641,6 +1662,23 @@ export class GlobalDatabaseConfigMDB extends React.Component { + + {_("NDN Cache")}}> +
++ ++ {this.props.data.ndn_cache_enabled === false && ( ++ ++ ++ {_("The Normalized DN Cache is currently disabled. To enable it, go to Server Settings → Tuning & Limits and enable 'Normalized DN Cache', then restart the server for the changes to take effect.")} ++ ++ ++ )} ++ + 0; ++ let ndn_chart_data = this.state.ndnCacheList; ++ let ndn_util_chart_data = this.state.ndnCacheUtilList; ++ ++ // Only build NDN cache chart data if NDN cache is enabled ++ if (ndn_cache_enabled) { ++ const ndnratio = config.attrs.normalizeddncachehitratio[0]; ++ ndn_chart_data = this.state.ndnCacheList; ++ ndn_chart_data.shift(); ++ ndn_chart_data.push({ name: _("Cache Hit Ratio"), x: count.toString(), y: parseInt(ndnratio) }); ++ ++ // Build up the NDN Cache Util chart data ++ ndn_util_chart_data = this.state.ndnCacheUtilList; ++ const currNDNSize = parseInt(config.attrs.currentnormalizeddncachesize[0]); ++ const maxNDNSize = parseInt(config.attrs.maxnormalizeddncachesize[0]); ++ const ndn_utilization = (currNDNSize / maxNDNSize) * 100; ++ ndn_util_chart_data.shift(); ++ ndn_util_chart_data.push({ name: _("Cache Utilization"), x: ndnCount.toString(), y: parseInt(ndn_utilization) }); ++ } + + this.setState({ + data: config.attrs, +@@ -157,7 +167,8 @@ export class DatabaseMonitor extends React.Component { + ndnCacheList: ndn_chart_data, + ndnCacheUtilList: ndn_util_chart_data, + count, +- ndnCount ++ ndnCount, ++ ndn_cache_enabled + }); + }) + .fail(() => { +@@ -197,13 +208,20 @@ export class DatabaseMonitor extends React.Component { + + if (!this.state.loading) { + dbcachehit = parseInt(this.state.data.dbcachehitratio[0]); +- ndncachehit = parseInt(this.state.data.normalizeddncachehitratio[0]); +- ndncachemax = parseInt(this.state.data.maxnormalizeddncachesize[0]); +- ndncachecurr = parseInt(this.state.data.currentnormalizeddncachesize[0]); +- utilratio = Math.round((ndncachecurr / ndncachemax) * 100); +- if (utilratio === 0) { +- // Just round up to 1 +- utilratio = 1; ++ ++ // Check if NDN cache is enabled ++ const ndn_cache_enabled = this.state.data.normalizeddncachehitratio && ++ this.state.data.normalizeddncachehitratio.length > 0; ++ ++ if (ndn_cache_enabled) { ++ ndncachehit = parseInt(this.state.data.normalizeddncachehitratio[0]); ++ ndncachemax = parseInt(this.state.data.maxnormalizeddncachesize[0]); ++ ndncachecurr = parseInt(this.state.data.currentnormalizeddncachesize[0]); ++ utilratio = Math.round((ndncachecurr / ndncachemax) * 100); ++ if (utilratio === 0) { ++ // Just round up to 1 ++ utilratio = 1; ++ } + } + + // Database cache +@@ -214,119 +232,131 @@ export class DatabaseMonitor extends React.Component { + } else { + chartColor = ChartThemeColor.purple; + } +- // NDN cache ratio +- if (ndncachehit > 89) { +- ndnChartColor = ChartThemeColor.green; +- } else if (ndncachehit > 74) { +- ndnChartColor = ChartThemeColor.orange; +- } else { +- ndnChartColor = ChartThemeColor.purple; +- } +- // NDN cache utilization +- if (utilratio > 95) { +- ndnUtilColor = ChartThemeColor.purple; +- } else if (utilratio > 90) { +- ndnUtilColor = ChartThemeColor.orange; +- } else { +- ndnUtilColor = ChartThemeColor.green; ++ ++ // NDN cache colors only if enabled ++ if (ndn_cache_enabled) { ++ // NDN cache ratio ++ if (ndncachehit > 89) { ++ ndnChartColor = ChartThemeColor.green; ++ } else if (ndncachehit > 74) { ++ ndnChartColor = ChartThemeColor.orange; ++ } else { ++ ndnChartColor = ChartThemeColor.purple; ++ } ++ // NDN cache utilization ++ if (utilratio > 95) { ++ ndnUtilColor = ChartThemeColor.purple; ++ } else if (utilratio > 90) { ++ ndnUtilColor = ChartThemeColor.orange; ++ } else { ++ ndnUtilColor = ChartThemeColor.green; ++ } + } + +- content = ( +- +- {_("Database Cache")}}> +-
+- +- +-
+-
+- +- +- {_("Cache Hit Ratio")} +- +- +- +- +- {dbcachehit}% +- +- +-
+-
+- `${datum.name}: ${datum.y}`} constrainToVisibleArea />} +- height={200} +- maxDomain={{ y: 100 }} +- minDomain={{ y: 0 }} +- padding={{ +- bottom: 30, +- left: 40, +- top: 10, +- right: 10, +- }} +- width={500} +- themeColor={chartColor} +- > +- +- +- +- +- +- +-
++ // Create tabs based on what caches are available ++ const tabs = []; ++ ++ // Database Cache tab is always available ++ tabs.push( ++ {_("Database Cache")}}> ++
++ ++ ++
++
++ ++ ++ {_("Cache Hit Ratio")} ++ ++ ++ ++ ++ {dbcachehit}% ++ ++ +
+- +- +-
++
++ `${datum.name}: ${datum.y}`} constrainToVisibleArea />} ++ height={200} ++ maxDomain={{ y: 100 }} ++ minDomain={{ y: 0 }} ++ padding={{ ++ bottom: 30, ++ left: 40, ++ top: 10, ++ right: 10, ++ }} ++ width={500} ++ themeColor={chartColor} ++ > ++ ++ ++ ++ ++ ++ ++
++
++ ++ ++
++ ++ ++ ++ {_("Database Cache Hit Ratio:")} ++ ++ ++ {this.state.data.dbcachehitratio}% ++ ++ ++ {_("Database Cache Tries:")} ++ ++ ++ {numToCommas(this.state.data.dbcachetries)} ++ ++ ++ {_("Database Cache Hits:")} ++ ++ ++ {numToCommas(this.state.data.dbcachehits)} ++ ++ ++ {_("Cache Pages Read:")} ++ ++ ++ {numToCommas(this.state.data.dbcachepagein)} ++ ++ ++ {_("Cache Pages Written:")} ++ ++ ++ {numToCommas(this.state.data.dbcachepageout)} ++ ++ ++ {_("Read-Only Page Evictions:")} ++ ++ ++ {numToCommas(this.state.data.dbcacheroevict)} ++ ++ ++ {_("Read-Write Page Evictions:")} ++ ++ ++ {numToCommas(this.state.data.dbcacherwevict)} ++ ++ ++ ++ ); + +- +- +- {_("Database Cache Hit Ratio:")} +- +- +- {this.state.data.dbcachehitratio}% +- +- +- {_("Database Cache Tries:")} +- +- +- {numToCommas(this.state.data.dbcachetries)} +- +- +- {_("Database Cache Hits:")} +- +- +- {numToCommas(this.state.data.dbcachehits)} +- +- +- {_("Cache Pages Read:")} +- +- +- {numToCommas(this.state.data.dbcachepagein)} +- +- +- {_("Cache Pages Written:")} +- +- +- {numToCommas(this.state.data.dbcachepageout)} +- +- +- {_("Read-Only Page Evictions:")} +- +- +- {numToCommas(this.state.data.dbcacheroevict)} +- +- +- {_("Read-Write Page Evictions:")} +- +- +- {numToCommas(this.state.data.dbcacherwevict)} +- +- +- +- {_("Normalized DN Cache")}}> ++ // Only add NDN Cache tab if NDN cache is enabled ++ if (ndn_cache_enabled) { ++ tabs.push( ++ {_("Normalized DN Cache")}}> +
+ + +@@ -487,6 +517,12 @@ export class DatabaseMonitor extends React.Component { + +
+
++ ); ++ } ++ ++ content = ( ++ ++ {tabs} + + ); + } +@@ -533,7 +569,8 @@ export class DatabaseMonitorMDB extends React.Component { + ndnCount: 5, + dbCacheList: [], + ndnCacheList: [], +- ndnCacheUtilList: [] ++ ndnCacheUtilList: [], ++ ndn_cache_enabled: false + }; + + // Toggle currently active tab +@@ -585,6 +622,7 @@ export class DatabaseMonitorMDB extends React.Component { + { name: "", x: "4", y: 0 }, + { name: "", x: "5", y: 0 }, + ], ++ ndn_cache_enabled: false + }); + } + +@@ -605,19 +643,28 @@ export class DatabaseMonitorMDB extends React.Component { + count = 1; + } + +- // Build up the NDN Cache chart data +- const ndnratio = config.attrs.normalizeddncachehitratio[0]; +- const ndn_chart_data = this.state.ndnCacheList; +- ndn_chart_data.shift(); +- ndn_chart_data.push({ name: _("Cache Hit Ratio"), x: count.toString(), y: parseInt(ndnratio) }); +- +- // Build up the DB Cache Util chart data +- const ndn_util_chart_data = this.state.ndnCacheUtilList; +- const currNDNSize = parseInt(config.attrs.currentnormalizeddncachesize[0]); +- const maxNDNSize = parseInt(config.attrs.maxnormalizeddncachesize[0]); +- const ndn_utilization = (currNDNSize / maxNDNSize) * 100; +- ndn_util_chart_data.shift(); +- ndn_util_chart_data.push({ name: _("Cache Utilization"), x: ndnCount.toString(), y: parseInt(ndn_utilization) }); ++ // Check if NDN cache is enabled ++ const ndn_cache_enabled = config.attrs.normalizeddncachehitratio && ++ config.attrs.normalizeddncachehitratio.length > 0; ++ let ndn_chart_data = this.state.ndnCacheList; ++ let ndn_util_chart_data = this.state.ndnCacheUtilList; ++ ++ // Only build NDN cache chart data if NDN cache is enabled ++ if (ndn_cache_enabled) { ++ // Build up the NDN Cache chart data ++ const ndnratio = config.attrs.normalizeddncachehitratio[0]; ++ ndn_chart_data = this.state.ndnCacheList; ++ ndn_chart_data.shift(); ++ ndn_chart_data.push({ name: _("Cache Hit Ratio"), x: count.toString(), y: parseInt(ndnratio) }); ++ ++ // Build up the DB Cache Util chart data ++ ndn_util_chart_data = this.state.ndnCacheUtilList; ++ const currNDNSize = parseInt(config.attrs.currentnormalizeddncachesize[0]); ++ const maxNDNSize = parseInt(config.attrs.maxnormalizeddncachesize[0]); ++ const ndn_utilization = (currNDNSize / maxNDNSize) * 100; ++ ndn_util_chart_data.shift(); ++ ndn_util_chart_data.push({ name: _("Cache Utilization"), x: ndnCount.toString(), y: parseInt(ndn_utilization) }); ++ } + + this.setState({ + data: config.attrs, +@@ -625,7 +672,8 @@ export class DatabaseMonitorMDB extends React.Component { + ndnCacheList: ndn_chart_data, + ndnCacheUtilList: ndn_util_chart_data, + count, +- ndnCount ++ ndnCount, ++ ndn_cache_enabled + }); + }) + .fail(() => { +@@ -662,197 +710,214 @@ export class DatabaseMonitorMDB extends React.Component { + ); + + if (!this.state.loading) { +- ndncachehit = parseInt(this.state.data.normalizeddncachehitratio[0]); +- ndncachemax = parseInt(this.state.data.maxnormalizeddncachesize[0]); +- ndncachecurr = parseInt(this.state.data.currentnormalizeddncachesize[0]); +- utilratio = Math.round((ndncachecurr / ndncachemax) * 100); +- if (utilratio === 0) { +- // Just round up to 1 +- utilratio = 1; +- } +- +- // NDN cache ratio +- if (ndncachehit > 89) { +- ndnChartColor = ChartThemeColor.green; +- } else if (ndncachehit > 74) { +- ndnChartColor = ChartThemeColor.orange; +- } else { +- ndnChartColor = ChartThemeColor.purple; +- } +- // NDN cache utilization +- if (utilratio > 95) { +- ndnUtilColor = ChartThemeColor.purple; +- } else if (utilratio > 90) { +- ndnUtilColor = ChartThemeColor.orange; +- } else { +- ndnUtilColor = ChartThemeColor.green; +- } +- +- content = ( +- +- {_("Normalized DN Cache")}}> +-
+- +- +- +- +-
+-
+- +- +- {_("Cache Hit Ratio")} +- +- +- +- +- {ndncachehit}% +- +- +-
+-
+- `${datum.name}: ${datum.y}`} constrainToVisibleArea />} +- height={200} +- maxDomain={{ y: 100 }} +- minDomain={{ y: 0 }} +- padding={{ +- bottom: 40, +- left: 60, +- top: 10, +- right: 15, +- }} +- width={350} +- themeColor={ndnChartColor} +- > +- +- +- +- +- +- +-
+-
+-
+-
+-
+- +- +- +-
+-
+- +- +- {_("Cache Utilization")} +- +- +- +- +- {utilratio}% +- +- +- +- +- {_("Cached DN's")} +- +- +- {numToCommas(this.state.data.currentnormalizeddncachecount[0])} ++ // Check if NDN cache is enabled ++ const ndn_cache_enabled = this.state.data.normalizeddncachehitratio && ++ this.state.data.normalizeddncachehitratio.length > 0; ++ ++ if (ndn_cache_enabled) { ++ ndncachehit = parseInt(this.state.data.normalizeddncachehitratio[0]); ++ ndncachemax = parseInt(this.state.data.maxnormalizeddncachesize[0]); ++ ndncachecurr = parseInt(this.state.data.currentnormalizeddncachesize[0]); ++ utilratio = Math.round((ndncachecurr / ndncachemax) * 100); ++ if (utilratio === 0) { ++ // Just round up to 1 ++ utilratio = 1; ++ } ++ ++ // NDN cache ratio ++ if (ndncachehit > 89) { ++ ndnChartColor = ChartThemeColor.green; ++ } else if (ndncachehit > 74) { ++ ndnChartColor = ChartThemeColor.orange; ++ } else { ++ ndnChartColor = ChartThemeColor.purple; ++ } ++ // NDN cache utilization ++ if (utilratio > 95) { ++ ndnUtilColor = ChartThemeColor.purple; ++ } else if (utilratio > 90) { ++ ndnUtilColor = ChartThemeColor.orange; ++ } else { ++ ndnUtilColor = ChartThemeColor.green; ++ } ++ ++ content = ( ++ ++ {_("Normalized DN Cache")}}> ++
++ ++ ++ ++ ++
++
++ ++ ++ {_("Cache Hit Ratio")} ++ ++ ++ ++ ++ {ndncachehit}% ++ ++ ++
++
++ `${datum.name}: ${datum.y}`} constrainToVisibleArea />} ++ height={200} ++ maxDomain={{ y: 100 }} ++ minDomain={{ y: 0 }} ++ padding={{ ++ bottom: 40, ++ left: 60, ++ top: 10, ++ right: 15, ++ }} ++ width={350} ++ themeColor={ndnChartColor} ++ > ++ ++ ++ ++ ++ ++ ++
+
+-
+- `${datum.name}: ${datum.y}`} constrainToVisibleArea />} +- height={200} +- maxDomain={{ y: 100 }} +- minDomain={{ y: 0 }} +- padding={{ +- bottom: 40, +- left: 60, +- top: 10, +- right: 15, +- }} +- width={350} +- themeColor={ndnUtilColor} +- > +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++
++
++ ++ ++ {_("Cache Utilization")} ++ ++ ++ ++ ++ {utilratio}% ++ ++ ++ ++ ++ {_("Cached DN's")} ++ ++ ++ {numToCommas(this.state.data.currentnormalizeddncachecount[0])} ++
++
++ `${datum.name}: ${datum.y}`} constrainToVisibleArea />} ++ height={200} ++ maxDomain={{ y: 100 }} ++ minDomain={{ y: 0 }} ++ padding={{ ++ bottom: 40, ++ left: 60, ++ top: 10, ++ right: 15, ++ }} ++ width={350} ++ themeColor={ndnUtilColor} ++ > ++ ++ ++ ++ ++ ++ ++
+
+-
+-
+-
+-
+-
+- +- +- +- {_("NDN Cache Hit Ratio:")} +- +- +- {this.state.data.normalizeddncachehitratio}% +- +- +- {_("NDN Cache Max Size:")} +- +- +- {displayBytes(this.state.data.maxnormalizeddncachesize)} +- +- +- {_("NDN Cache Tries:")} +- +- +- {numToCommas(this.state.data.normalizeddncachetries)} +- +- +- {_("NDN Current Cache Size:")} +- +- +- {displayBytes(this.state.data.currentnormalizeddncachesize)} +- +- +- {_("NDN Cache Hits:")} +- +- +- {numToCommas(this.state.data.normalizeddncachehits)} +- +- +- {_("NDN Cache DN Count:")} +- +- +- {numToCommas(this.state.data.currentnormalizeddncachecount)} +- +- +- {_("NDN Cache Evictions:")} +- +- +- {numToCommas(this.state.data.normalizeddncacheevictions)} +- +- +- {_("NDN Cache Thread Size:")} +- +- +- {numToCommas(this.state.data.normalizeddncachethreadsize)} +- +- +- {_("NDN Cache Thread Slots:")} +- +- +- {numToCommas(this.state.data.normalizeddncachethreadslots)} +- +- +-
+-
+-
+- ); ++ ++ ++ ++ ++ ++ ++ ++ {_("NDN Cache Hit Ratio:")} ++ ++ ++ {this.state.data.normalizeddncachehitratio}% ++ ++ ++ {_("NDN Cache Max Size:")} ++ ++ ++ {displayBytes(this.state.data.maxnormalizeddncachesize)} ++ ++ ++ {_("NDN Cache Tries:")} ++ ++ ++ {numToCommas(this.state.data.normalizeddncachetries)} ++ ++ ++ {_("NDN Current Cache Size:")} ++ ++ ++ {displayBytes(this.state.data.currentnormalizeddncachesize)} ++ ++ ++ {_("NDN Cache Hits:")} ++ ++ ++ {numToCommas(this.state.data.normalizeddncachehits)} ++ ++ ++ {_("NDN Cache DN Count:")} ++ ++ ++ {numToCommas(this.state.data.currentnormalizeddncachecount)} ++ ++ ++ {_("NDN Cache Evictions:")} ++ ++ ++ {numToCommas(this.state.data.normalizeddncacheevictions)} ++ ++ ++ {_("NDN Cache Thread Size:")} ++ ++ ++ {numToCommas(this.state.data.normalizeddncachethreadsize)} ++ ++ ++ {_("NDN Cache Thread Slots:")} ++ ++ ++ {numToCommas(this.state.data.normalizeddncachethreadslots)} ++ ++ ++
++ ++ ++ ); ++ } else { ++ // No NDN cache available ++ content = ( ++
++ ++ ++ {_("Normalized DN Cache is disabled")} ++ ++ ++
++ ); ++ } + } + + return ( +diff --git a/src/lib389/lib389/cli_conf/monitor.py b/src/lib389/lib389/cli_conf/monitor.py +index b01796549..c7f9322d1 100644 +--- a/src/lib389/lib389/cli_conf/monitor.py ++++ b/src/lib389/lib389/cli_conf/monitor.py +@@ -129,6 +129,14 @@ def db_monitor(inst, basedn, log, args): + # Gather the global DB stats + report_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + ldbm_mon = ldbm_monitor.get_status() ++ ndn_cache_enabled = inst.config.get_attr_val_utf8('nsslapd-ndn-cache-enabled') == 'on' ++ ++ # Build global cache stats ++ result = { ++ 'date': report_time, ++ 'backends': {}, ++ } ++ + if ldbm_monitor.inst_db_impl == DB_IMPL_BDB: + dbcachesize = int(ldbm_mon['nsslapd-db-cache-size-bytes'][0]) + # Warning: there are two different page sizes associated with bdb: +@@ -153,32 +161,6 @@ def db_monitor(inst, basedn, log, args): + dbcachefree = max(int(dbcachesize - (pagesize * dbpages)), 0) + dbcachefreeratio = dbcachefree/dbcachesize + +- ndnratio = ldbm_mon['normalizeddncachehitratio'][0] +- ndncursize = int(ldbm_mon['currentnormalizeddncachesize'][0]) +- ndnmaxsize = int(ldbm_mon['maxnormalizeddncachesize'][0]) +- ndncount = ldbm_mon['currentnormalizeddncachecount'][0] +- ndnevictions = ldbm_mon['normalizeddncacheevictions'][0] +- if ndncursize > ndnmaxsize: +- ndnfree = 0 +- ndnfreeratio = 0 +- else: +- ndnfree = ndnmaxsize - ndncursize +- ndnfreeratio = "{:.1f}".format(ndnfree / ndnmaxsize * 100) +- +- # Build global cache stats +- result = { +- 'date': report_time, +- 'ndncache': { +- 'hit_ratio': ndnratio, +- 'free': convert_bytes(str(ndnfree)), +- 'free_percentage': ndnfreeratio, +- 'count': ndncount, +- 'evictions': ndnevictions +- }, +- 'backends': {}, +- } +- +- if ldbm_monitor.inst_db_impl == DB_IMPL_BDB: + result['dbcache'] = { + 'hit_ratio': dbhitratio, + 'free': convert_bytes(str(dbcachefree)), +@@ -188,6 +170,32 @@ def db_monitor(inst, basedn, log, args): + 'pageout': dbcachepageout + } + ++ # Add NDN cache stats only if enabled ++ if ndn_cache_enabled: ++ try: ++ ndnratio = ldbm_mon['normalizeddncachehitratio'][0] ++ ndncursize = int(ldbm_mon['currentnormalizeddncachesize'][0]) ++ ndnmaxsize = int(ldbm_mon['maxnormalizeddncachesize'][0]) ++ ndncount = ldbm_mon['currentnormalizeddncachecount'][0] ++ ndnevictions = ldbm_mon['normalizeddncacheevictions'][0] ++ if ndncursize > ndnmaxsize: ++ ndnfree = 0 ++ ndnfreeratio = 0 ++ else: ++ ndnfree = ndnmaxsize - ndncursize ++ ndnfreeratio = "{:.1f}".format(ndnfree / ndnmaxsize * 100) ++ ++ result['ndncache'] = { ++ 'hit_ratio': ndnratio, ++ 'free': convert_bytes(str(ndnfree)), ++ 'free_percentage': ndnfreeratio, ++ 'count': ndncount, ++ 'evictions': ndnevictions ++ } ++ # In case, the user enabled NDN cache but still have not restarted the instance ++ except IndexError: ++ ndn_cache_enabled = False ++ + # Build the backend results + for be in backend_objs: + be_name = be.rdn +@@ -277,13 +285,16 @@ def db_monitor(inst, basedn, log, args): + log.info(" - Pages In: {}".format(result['dbcache']['pagein'])) + log.info(" - Pages Out: {}".format(result['dbcache']['pageout'])) + log.info("") +- log.info("Normalized DN Cache:") +- log.info(" - Cache Hit Ratio: {}%".format(result['ndncache']['hit_ratio'])) +- log.info(" - Free Space: {}".format(result['ndncache']['free'])) +- log.info(" - Free Percentage: {}%".format(result['ndncache']['free_percentage'])) +- log.info(" - DN Count: {}".format(result['ndncache']['count'])) +- log.info(" - Evictions: {}".format(result['ndncache']['evictions'])) +- log.info("") ++ ++ if ndn_cache_enabled: ++ log.info("Normalized DN Cache:") ++ log.info(" - Cache Hit Ratio: {}%".format(result['ndncache']['hit_ratio'])) ++ log.info(" - Free Space: {}".format(result['ndncache']['free'])) ++ log.info(" - Free Percentage: {}%".format(result['ndncache']['free_percentage'])) ++ log.info(" - DN Count: {}".format(result['ndncache']['count'])) ++ log.info(" - Evictions: {}".format(result['ndncache']['evictions'])) ++ log.info("") ++ + log.info("Backends:") + for be_name, attr_dict in result['backends'].items(): + log.info(f" - {attr_dict['suffix']} ({be_name}):") +-- +2.49.0 + diff --git a/0006-Issue-6854-Refactor-for-improved-data-management-685.patch b/0006-Issue-6854-Refactor-for-improved-data-management-685.patch new file mode 100644 index 0000000..9192e5a --- /dev/null +++ b/0006-Issue-6854-Refactor-for-improved-data-management-685.patch @@ -0,0 +1,2237 @@ +From b975dfa3be2a9a5a237dd6383fedaed971893e27 Mon Sep 17 00:00:00 2001 +From: James Chapman +Date: Fri, 11 Jul 2025 10:16:13 +0000 +Subject: [PATCH] Issue 6854 - Refactor for improved data management (#6855) + +Description: Replaced standard dictionaries with defaultdict and +introduced @dataclass structures to streamline data handling. +Improved reliability and readability by reducing explicit key +checks and default initialisation logic. Simplified nested +structure management and ensured consistency across components +such as ResultData, BindData, and ConnectionData. + +Fixes: https://github.com/389ds/389-ds-base/issues/6854 + +Reviewed by: @mreynolds389 (Thank you) +--- + ldap/admin/src/logconv.py | 1307 ++++++++++++++++++++----------------- + 1 file changed, 698 insertions(+), 609 deletions(-) + +diff --git a/ldap/admin/src/logconv.py b/ldap/admin/src/logconv.py +index f4495ca35..162447b4d 100755 +--- a/ldap/admin/src/logconv.py ++++ b/ldap/admin/src/logconv.py +@@ -16,11 +16,11 @@ import argparse + import logging + import sys + import csv ++from collections import defaultdict, Counter + from datetime import datetime, timedelta, timezone ++from dataclasses import dataclass, field + import heapq +-from collections import Counter +-from collections import defaultdict +-from typing import Optional ++from typing import Optional, Dict, List, Set, Tuple, DefaultDict + import magic + + # Globals +@@ -159,9 +159,191 @@ SCOPE_LABEL = { + + STLS_OID = '1.3.6.1.4.1.1466.20037' + +-# Version +-logAnalyzerVersion = "8.3" ++logAnalyzerVersion = "8.4" + ++@dataclass ++class VLVData: ++ counters: Dict[str, int] = field(default_factory=lambda: defaultdict( ++ int, ++ { ++ 'vlv': 0 ++ } ++ )) ++ ++ rst_con_op_map: Dict = field(default_factory=lambda: defaultdict(dict)) ++ ++@dataclass ++class ServerData: ++ counters: Dict[str, int] = field(default_factory=lambda: defaultdict( ++ int, ++ { ++ 'restart': 0, ++ 'lines_parsed': 0 ++ } ++ )) ++ ++ first_time: Optional[str] = None ++ last_time: Optional[str] = None ++ parse_start_time: Optional[str] = None ++ parse_stop_time: Optional[str] = None ++ ++@dataclass ++class OperationData: ++ counters: DefaultDict[str, int] = field(default_factory=lambda: defaultdict( ++ int, ++ { ++ 'add': 0, ++ 'mod': 0, ++ 'del': 0, ++ 'modrdn': 0, ++ 'cmp': 0, ++ 'abandon': 0, ++ 'sort': 0, ++ 'internal': 0, ++ 'extnd': 0, ++ 'authzid': 0, ++ 'total': 0 ++ } ++ )) ++ ++ rst_con_op_map: DefaultDict[str, DefaultDict[str, int]] = field( ++ default_factory=lambda: defaultdict(lambda: defaultdict(int)) ++ ) ++ ++ extended: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) ++ ++@dataclass ++class ConnectionData: ++ counters: DefaultDict[str, int] = field(default_factory=lambda: defaultdict( ++ int, ++ { ++ 'conn': 0, ++ 'fd_taken': 0, ++ 'fd_returned': 0, ++ 'fd_max': 0, ++ 'sim_conn': 0, ++ 'max_sim_conn': 0, ++ 'ldap': 0, ++ 'ldapi': 0, ++ 'ldaps': 0 ++ } ++ )) ++ ++ start_time: DefaultDict[str, str] = field(default_factory=lambda: defaultdict(str)) ++ open_conns: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) ++ exclude_ip: DefaultDict[Tuple[str, str], str] = field(default_factory=lambda: defaultdict(str)) ++ ++ broken_pipe: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) ++ resource_unavail: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) ++ connection_reset: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) ++ disconnect_code: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) ++ ++ restart_conn_disconnect_map: DefaultDict[Tuple[int, str], int] = field(default_factory=lambda: defaultdict(int)) ++ restart_conn_ip_map: Dict[Tuple[int, str], str] = field(default_factory=dict) ++ ++ src_ip_map: DefaultDict[str, DefaultDict[str, object]] = field( ++ default_factory=lambda: defaultdict(lambda: defaultdict(object)) ++ ) ++ ++@dataclass ++class BindData: ++ counters: DefaultDict[str, int] = field(default_factory=lambda: defaultdict( ++ int, ++ { ++ 'bind': 0, ++ 'unbind': 0, ++ 'sasl': 0, ++ 'anon': 0, ++ 'autobind': 0, ++ 'rootdn': 0 ++ } ++ )) ++ ++ restart_conn_dn_map: Dict[Tuple[int, str], str] = field(default_factory=dict) ++ ++ version: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) ++ dns: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) ++ sasl_mech: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) ++ conn_op_sasl_mech_map: DefaultDict[str, str] = field(default_factory=lambda: defaultdict(str)) ++ root_dn: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) ++ ++ report_dn: DefaultDict[str, Dict[str, Set[str]]] = field( ++ default_factory=lambda: defaultdict( ++ lambda: { ++ 'conn': set(), ++ 'ips': set() ++ } ++ ) ++ ) ++ ++@dataclass ++class ResultData: ++ counters: DefaultDict[str, int] = field(default_factory=lambda: defaultdict( ++ int, { ++ 'result': 0, ++ 'notesA': 0, ++ 'notesF': 0, ++ 'notesM': 0, ++ 'notesP': 0, ++ 'notesU': 0, ++ 'timestamp': 0, ++ 'entry': 0, ++ 'referral': 0 ++ } ++ )) ++ ++ notes: DefaultDict[str, Dict] = field(default_factory=lambda: defaultdict(dict)) ++ ++ timestamp_ctr: int = 0 ++ entry_count: int = 0 ++ referral_count: int = 0 ++ ++ total_etime: float = 0.0 ++ total_wtime: float = 0.0 ++ total_optime: float = 0.0 ++ etime_stat: float = 0.0 ++ ++ etime_duration: List[float] = field(default_factory=list) ++ wtime_duration: List[float] = field(default_factory=list) ++ optime_duration: List[float] = field(default_factory=list) ++ ++ nentries_num: List[int] = field(default_factory=list) ++ nentries_set: Set[int] = field(default_factory=set) ++ ++ error_freq: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) ++ bad_pwd_map: Dict[str, int] = field(default_factory=dict) ++ ++@dataclass ++class SearchData: ++ counters: Dict[str, int] = field(default_factory=lambda: defaultdict( ++ int, ++ { ++ 'search': 0, ++ 'base_search': 0, ++ 'persistent': 0 ++ } ++ )) ++ attrs: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) ++ bases: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) ++ ++ base_rst_con_op_map: Dict[Tuple[int, str, str], str] = field(default_factory=dict) ++ scope_rst_con_op_map: Dict[Tuple[int, str, str], str] = field(default_factory=dict) ++ ++ filter_dict: Dict[str, int] = field(default_factory=dict) ++ filter_list: List[str] = field(default_factory=list) ++ filter_rst_con_op_map: Dict[Tuple[int, str, str], str] = field(default_factory=dict) ++ ++@dataclass ++class AuthData: ++ counters: Dict[str, int] = field(default_factory=lambda: defaultdict( ++ int, ++ { ++ 'ssl_client_bind_ctr': 0, ++ 'ssl_client_bind_failed_ctr': 0, ++ 'cipher_ctr': 0 ++ } ++ )) ++ auth_info: DefaultDict[str, str] = field(default_factory=lambda: defaultdict(str)) + + class logAnalyser: + """ +@@ -272,136 +454,14 @@ class logAnalyser: + self.notesP = {} + self.notesU = {} + +- self.vlv = { +- 'vlv_ctr': 0, +- 'vlv_map_rco': {} +- } +- +- self.server = { +- 'restart_ctr': 0, +- 'first_time': None, +- 'last_time': None, +- 'parse_start_time': None, +- 'parse_stop_time': None, +- 'lines_parsed': 0 +- } +- +- self.operation = { +- 'all_op_ctr': 0, +- 'add_op_ctr': 0, +- 'mod_op_ctr': 0, +- 'del_op_ctr': 0, +- 'modrdn_op_ctr': 0, +- 'cmp_op_ctr': 0, +- 'abandon_op_ctr': 0, +- 'sort_op_ctr': 0, +- 'extnd_op_ctr': 0, +- 'add_map_rco': {}, +- 'mod_map_rco': {}, +- 'del_map_rco': {}, +- 'cmp_map_rco': {}, +- 'modrdn_map_rco': {}, +- 'extop_dict': {}, +- 'extop_map_rco': {}, +- 'abandoned_map_rco': {} +- } +- +- self.connection = { +- 'conn_ctr': 0, +- 'fd_taken_ctr': 0, +- 'fd_returned_ctr': 0, +- 'fd_max_ctr': 0, +- 'sim_conn_ctr': 0, +- 'max_sim_conn_ctr': 0, +- 'ldap_ctr': 0, +- 'ldapi_ctr': 0, +- 'ldaps_ctr': 0, +- 'start_time': {}, +- 'open_conns': {}, +- 'exclude_ip_map': {}, +- 'broken_pipe': {}, +- 'resource_unavail': {}, +- 'connection_reset': {}, +- 'disconnect_code': {}, +- 'disconnect_code_map': {}, +- 'ip_map': {}, +- 'restart_conn_ip_map': {} +- } +- +- self.bind = { +- 'bind_ctr': 0, +- 'unbind_ctr': 0, +- 'sasl_bind_ctr': 0, +- 'anon_bind_ctr': 0, +- 'autobind_ctr': 0, +- 'rootdn_bind_ctr': 0, +- 'version': {}, +- 'dn_freq': {}, +- 'dn_map_rc': {}, +- 'sasl_mech_freq': {}, +- 'sasl_map_co': {}, +- 'root_dn': {}, +- 'report_dn': defaultdict(lambda: defaultdict(int, conn=set(), ips=set())) +- } +- +- self.result = { +- 'result_ctr': 0, +- 'notesA_ctr': 0, # dynamically referenced +- 'notesF_ctr': 0, # dynamically referenced +- 'notesM_ctr': 0, # dynamically referenced +- 'notesP_ctr': 0, # dynamically referenced +- 'notesU_ctr': 0, # dynamically referenced +- 'timestamp_ctr': 0, +- 'entry_count': 0, +- 'referral_count': 0, +- 'total_etime': 0.0, +- 'total_wtime': 0.0, +- 'total_optime': 0.0, +- 'notesA_map': {}, +- 'notesF_map': {}, +- 'notesM_map': {}, +- 'notesP_map': {}, +- 'notesU_map': {}, +- 'etime_stat': 0.0, +- 'etime_counts': defaultdict(int), +- 'etime_freq': [], +- 'etime_duration': [], +- 'wtime_counts': defaultdict(int), +- 'wtime_freq': [], +- 'wtime_duration': [], +- 'optime_counts': defaultdict(int), +- 'optime_freq': [], +- 'optime_duration': [], +- 'nentries_dict': defaultdict(int), +- 'nentries_num': [], +- 'nentries_set': set(), +- 'nentries_returned': [], +- 'error_freq': defaultdict(str), +- 'bad_pwd_map': {} +- } +- +- self.search = { +- 'search_ctr': 0, +- 'search_map_rco': {}, +- 'attr_dict': defaultdict(int), +- 'base_search_ctr': 0, +- 'base_map': {}, +- 'base_map_rco': {}, +- 'scope_map_rco': {}, +- 'filter_dict': {}, +- 'filter_list': [], +- 'filter_seen': set(), +- 'filter_counter': Counter(), +- 'filter_map_rco': {}, +- 'persistent_ctr': 0 +- } +- +- self.auth = { +- 'ssl_client_bind_ctr': 0, +- 'ssl_client_bind_failed_ctr': 0, +- 'cipher_ctr': 0, +- 'auth_info': {} +- } ++ self.vlv = VLVData() ++ self.server = ServerData() ++ self.operation = OperationData() ++ self.connection = ConnectionData() ++ self.bind = BindData() ++ self.result = ResultData() ++ self.search = SearchData() ++ self.auth = AuthData() + + def _init_regexes(self): + """ +@@ -564,22 +624,22 @@ class logAnalyser: + """ + print("\nBind Report") + print("====================================================================\n") +- for k, v in self.bind['report_dn'].items(): ++ for k, v in self.bind.report_dn.items(): + print(f"\nBind DN: {k}") + print("--------------------------------------------------------------------\n") + print(" Client Addresses:\n") +- ips = self.bind['report_dn'][k].get('ips', set()) ++ ips = self.bind.report_dn[k].get('ips', set()) + for i, ip in enumerate(ips, start=1): + print(f" {i}: {ip}") + print("\n Operations Performed:\n") +- print(f" Binds: {self.bind['report_dn'][k].get('bind', 0)}") +- print(f" Searches: {self.bind['report_dn'][k].get('srch', 0)}") +- print(f" Modifies: {self.bind['report_dn'][k].get('mod', 0)}") +- print(f" Adds: {self.bind['report_dn'][k].get('add', 0)}") +- print(f" Deletes: {self.bind['report_dn'][k].get('del', 0)}") +- print(f" Compares: {self.bind['report_dn'][k].get('cmp', 0)}") +- print(f" ModRDNs: {self.bind['report_dn'][k].get('modrdn', 0)}") +- print(f" Ext Ops: {self.bind['report_dn'][k].get('ext', 0)}") ++ print(f" Binds: {self.bind.report_dn[k].get('bind', 0)}") ++ print(f" Searches: {self.bind.report_dn[k].get('srch', 0)}") ++ print(f" Modifies: {self.bind.report_dn[k].get('mod', 0)}") ++ print(f" Adds: {self.bind.report_dn[k].get('add', 0)}") ++ print(f" Deletes: {self.bind.report_dn[k].get('del', 0)}") ++ print(f" Compares: {self.bind.report_dn[k].get('cmp', 0)}") ++ print(f" ModRDNs: {self.bind.report_dn[k].get('modrdn', 0)}") ++ print(f" Ext Ops: {self.bind.report_dn[k].get('ext', 0)}") + + print("Done.") + +@@ -618,12 +678,9 @@ class logAnalyser: + self.logger.error(f"Converting timestamp: {timestamp} to datetime failed with: {e}") + return False + +- # Add server restart count to groups for connection tracking +- groups['restart_ctr'] = self.server.get('restart_ctr', 0) +- + # Are there time range restrictions +- parse_start = self.server.get('parse_start_time', None) +- parse_stop = self.server.get('parse_stop_time', None) ++ parse_start = self.server.parse_start_time ++ parse_stop = self.server.parse_stop_time + + if parse_start and parse_stop: + if parse_start.microsecond == 0 and parse_stop.microsecond == 0: +@@ -634,12 +691,12 @@ class logAnalyser: + return False + + # Get the first and last timestamps +- if self.server.get('first_time') is None: +- self.server['first_time'] = timestamp +- self.server['last_time'] = timestamp ++ if self.server.first_time is None: ++ self.server.first_time = timestamp ++ self.server.last_time = timestamp + + # Bump lines parsed +- self.server['lines_parsed'] = self.server.get('lines_parsed', 0) + 1 ++ self.server.counters['lines_parsed'] += 1 + + # Call the associated method for this match + action(groups) +@@ -658,16 +715,11 @@ class logAnalyser: + """ + Process and update statistics based on the parsed result group. + +- Args: +- groups (dict): Parsed groups from the log line. +- +- + Args: + groups (dict): A dictionary containing operation information. Expected keys: + - 'timestamp': The timestamp of the connection event. + - 'conn_id': Connection identifier. + - 'op_id': Operation identifier. +- - 'restart_ctr': Server restart count. + - 'etime': Result elapsed time. + - 'wtime': Result wait time. + - 'optime': Result operation time. +@@ -679,182 +731,173 @@ class logAnalyser: + Raises: + KeyError: If required keys are missing in the `groups` dictionary. + """ ++ self.logger.debug(f"_process_result_stats - Start - {groups}") ++ + try: + timestamp = groups.get('timestamp') + conn_id = groups.get('conn_id') + op_id = groups.get('op_id') +- restart_ctr = groups.get('restart_ctr') + etime = float(groups.get('etime')) + wtime = float(groups.get('wtime')) + optime = float(groups.get('optime')) ++ nentries = int(groups.get('nentries')) + tag = groups.get('tag') + err = groups.get('err') +- nentries = int(groups.get('nentries')) + internal = groups.get('internal') ++ notes = groups.get('notes') + except KeyError as e: + self.logger.error(f"Missing key in groups: {e}") + return + + # Mapping keys for this entry ++ restart_ctr = self.server.counters['restart'] + restart_conn_op_key = (restart_ctr, conn_id, op_id) + restart_conn_key = (restart_ctr, conn_id) + conn_op_key = (conn_id, op_id) + + # Should we ignore this operation +- if restart_conn_key in self.connection['exclude_ip_map']: ++ if restart_conn_key in self.connection.exclude_ip: + return None + +- # Bump global result count +- self.result['result_ctr'] = self.result.get('result_ctr', 0) + 1 +- +- # Bump global result count +- self.result['timestamp_ctr'] = self.result.get('timestamp_ctr', 0) + 1 ++ self.result.counters['result'] += 1 ++ self.result.counters['timestamp'] += 1 + + # Longest etime, push current etime onto the heap +- heapq.heappush(self.result['etime_duration'], float(etime)) ++ heapq.heappush(self.result.etime_duration, etime) + + # If the heap exceeds size_limit, pop the smallest element from root +- if len(self.result['etime_duration']) > self.size_limit: +- heapq.heappop(self.result['etime_duration']) ++ if len(self.result.etime_duration) > self.size_limit: ++ heapq.heappop(self.result.etime_duration) + + # Longest wtime, push current wtime onto the heap +- heapq.heappush(self.result['wtime_duration'], float(wtime)) ++ heapq.heappush(self.result.wtime_duration, wtime) + + # If the heap exceeds size_limit, pop the smallest element from root +- if len(self.result['wtime_duration']) > self.size_limit: +- heapq.heappop(self.result['wtime_duration']) ++ if len(self.result.wtime_duration) > self.size_limit: ++ heapq.heappop(self.result.wtime_duration) + + # Longest optime, push current optime onto the heap +- heapq.heappush(self.result['optime_duration'], float(optime)) ++ heapq.heappush(self.result.optime_duration, optime) + + # If the heap exceeds size_limit, pop the smallest element from root +- if len(self.result['optime_duration']) > self.size_limit: +- heapq.heappop(self.result['optime_duration']) ++ if len(self.result.optime_duration) > self.size_limit: ++ heapq.heappop(self.result.optime_duration) + + # Total result times +- self.result['total_etime'] = self.result.get('total_etime', 0) + float(etime) +- self.result['total_wtime'] = self.result.get('total_wtime', 0) + float(wtime) +- self.result['total_optime'] = self.result.get('total_optime', 0) + float(optime) ++ self.result.total_etime = self.result.total_etime + etime ++ self.result.total_wtime = self.result.total_wtime + wtime ++ self.result.total_optime = self.result.total_optime + optime + + # Statistic reporting +- self.result['etime_stat'] = round(self.result['etime_stat'] + float(etime), 8) ++ self.result.etime_stat = round(self.result.etime_stat + float(etime), 8) + +- if err: +- # Capture error code +- self.result['error_freq'][err] = self.result['error_freq'].get(err, 0) + 1 ++ if err is not None: ++ self.result.error_freq[err] += 1 + + # Check for internal operations based on either conn_id or internal flag + if 'Internal' in conn_id or internal: +- self.server['internal_op_ctr'] = self.server.get('internal_op_ctr', 0) + 1 ++ self.operation.counters['internal'] +=1 + + # Process result notes if present +- notes = groups['notes'] +- if notes is not None: +- # match.group('notes') can be A|U|F +- self.result[f'notes{notes}_ctr'] = self.result.get(f'notes{notes}_ctr', 0) + 1 +- # Track result times using server restart count, conn id and op_id as key +- self.result[f'notes{notes}_map'][restart_conn_op_key] = restart_conn_op_key +- +- # Construct the notes dict +- note_dict = getattr(self, f'notes{notes}') ++ NOTE_TYPES = {'A', 'U', 'F', 'M', 'P'} ++ if notes in NOTE_TYPES: ++ note_dict = self.result.notes[notes] ++ self.result.counters[f'notes{notes}'] += 1 + + # Exclude VLV +- if restart_conn_op_key not in self.vlv['vlv_map_rco']: +- if restart_conn_op_key in note_dict: +- note_dict[restart_conn_op_key]['time'] = timestamp +- else: +- # First time round +- note_dict[restart_conn_op_key] = {'time': timestamp} +- +- note_dict[restart_conn_op_key]['etime'] = etime +- note_dict[restart_conn_op_key]['nentries'] = nentries +- note_dict[restart_conn_op_key]['ip'] = ( +- self.connection['restart_conn_ip_map'].get(restart_conn_key, '') +- ) +- +- if restart_conn_op_key in self.search['base_map_rco']: +- note_dict[restart_conn_op_key]['base'] = self.search['base_map_rco'][restart_conn_op_key] +- del self.search['base_map_rco'][restart_conn_op_key] +- +- if restart_conn_op_key in self.search['scope_map_rco']: +- note_dict[restart_conn_op_key]['scope'] = self.search['scope_map_rco'][restart_conn_op_key] +- del self.search['scope_map_rco'][restart_conn_op_key] +- +- if restart_conn_op_key in self.search['filter_map_rco']: +- note_dict[restart_conn_op_key]['filter'] = self.search['filter_map_rco'][restart_conn_op_key] +- del self.search['filter_map_rco'][restart_conn_op_key] +- +- note_dict[restart_conn_op_key]['bind_dn'] = self.bind['dn_map_rc'].get(restart_conn_key, '') +- +- elif restart_conn_op_key in self.vlv['vlv_map_rco']: +- # This "note" result is VLV, assign the note type for later filtering +- self.vlv['vlv_map_rco'][restart_conn_op_key] = notes ++ if restart_conn_op_key not in self.vlv.rst_con_op_map: ++ # Construct the notes dict ++ note_dict = self.result.notes[notes] ++ note_entry = note_dict.setdefault(restart_conn_op_key, {}) ++ note_entry.update({ ++ 'time': timestamp, ++ 'etime': etime, ++ 'nentries': nentries, ++ 'ip': self.connection.restart_conn_ip_map.get(restart_conn_key, 'Unknown IP'), ++ 'bind_dn': self.bind.restart_conn_dn_map.get(restart_conn_key, 'Unknown DN') ++ }) ++ ++ if restart_conn_op_key in self.search.base_rst_con_op_map: ++ note_dict[restart_conn_op_key]['base'] = self.search.base_rst_con_op_map[restart_conn_op_key] ++ del self.search.base_rst_con_op_map[restart_conn_op_key] ++ ++ if restart_conn_op_key in self.search.scope_rst_con_op_map: ++ note_dict[restart_conn_op_key]['scope'] = self.search.scope_rst_con_op_map[restart_conn_op_key] ++ del self.search.scope_rst_con_op_map[restart_conn_op_key] ++ ++ if restart_conn_op_key in self.search.filter_rst_con_op_map: ++ note_dict[restart_conn_op_key]['filter'] = self.search.filter_rst_con_op_map[restart_conn_op_key] ++ del self.search.filter_rst_con_op_map[restart_conn_op_key] ++ else: ++ self.vlv.rst_con_op_map[restart_conn_op_key] = notes + + # Trim the search data we dont need (not associated with a notes=X) +- if restart_conn_op_key in self.search['base_map_rco']: +- del self.search['base_map_rco'][restart_conn_op_key] ++ if restart_conn_op_key in self.search.base_rst_con_op_map: ++ del self.search.base_rst_con_op_map[restart_conn_op_key] + +- if restart_conn_op_key in self.search['scope_map_rco']: +- del self.search['scope_map_rco'][restart_conn_op_key] ++ if restart_conn_op_key in self.search.scope_rst_con_op_map: ++ del self.search.scope_rst_con_op_map[restart_conn_op_key] + +- if restart_conn_op_key in self.search['filter_map_rco']: +- del self.search['filter_map_rco'][restart_conn_op_key] ++ if restart_conn_op_key in self.search.filter_rst_con_op_map: ++ del self.search.filter_rst_con_op_map[restart_conn_op_key] + + # Process bind response based on the tag and error code. + if tag == '97': + # Invalid credentials|Entry does not exist + if err == '49': + # if self.verbose: +- bad_pwd_dn = self.bind['dn_map_rc'].get(restart_conn_key, None) +- bad_pwd_ip = self.connection['restart_conn_ip_map'].get(restart_conn_key, None) +- self.result['bad_pwd_map'][(bad_pwd_dn, bad_pwd_ip)] = ( +- self.result['bad_pwd_map'].get((bad_pwd_dn, bad_pwd_ip), 0) + 1 ++ bad_pwd_dn = self.bind.restart_conn_dn_map[restart_conn_key] ++ bad_pwd_ip = self.connection.restart_conn_ip_map.get(restart_conn_key, None) ++ self.result.bad_pwd_map[(bad_pwd_dn, bad_pwd_ip)] = ( ++ self.result.bad_pwd_map.get((bad_pwd_dn, bad_pwd_ip), 0) + 1 + ) + # Trim items to size_limit +- if len(self.result['bad_pwd_map']) > self.size_limit: ++ if len(self.result.bad_pwd_map) > self.size_limit: + within_size_limit = dict( + sorted( +- self.result['bad_pwd_map'].items(), ++ self.result.bad_pwd_map.items(), + key=lambda item: item[1], + reverse=True + )[:self.size_limit]) +- self.result['bad_pwd_map'] = within_size_limit ++ self.result.bad_pwd_map = within_size_limit + + # Ths result is involved in the SASL bind process, decrement bind count, etc + elif err == '14': +- self.bind['bind_ctr'] = self.bind.get('bind_ctr', 0) - 1 +- self.operation['all_op_ctr'] = self.operation.get('all_op_ctr', 0) - 1 +- self.bind['sasl_bind_ctr'] = self.bind.get('sasl_bind_ctr', 0) - 1 +- self.bind['version']['3'] = self.bind['version'].get('3', 0) - 1 ++ self.bind.counters['bind'] -= 1 ++ self.operation.counters['total'] -= 1 ++ self.bind.counters['sasl'] -= 1 ++ self.bind.version['3'] = self.bind.version.get('3', 0) - 1 + + # Drop the sasl mech count also +- mech = self.bind['sasl_map_co'].get(conn_op_key, 0) ++ mech = self.bind.conn_op_sasl_mech_map[conn_op_key] + if mech: +- self.bind['sasl_mech_freq'][mech] = self.bind['sasl_mech_freq'].get(mech, 0) - 1 ++ self.bind.sasl_mech[mech] -= 1 + # Is this is a result to a sasl bind + else: + result_dn = groups['dn'] + if result_dn: + if result_dn != "": + # If this is a result of a sasl bind, grab the dn +- if conn_op_key in self.bind['sasl_map_co']: ++ if conn_op_key in self.bind.conn_op_sasl_mech_map: + if result_dn is not None: +- self.bind['dn_map_rc'][restart_conn_key] = result_dn.lower() +- self.bind['dn_freq'][result_dn] = ( +- self.bind['dn_freq'].get(result_dn, 0) + 1 ++ self.bind.restart_conn_dn_map[restart_conn_key] = result_dn.lower() ++ self.bind.dns[result_dn] = ( ++ self.bind.dns.get(result_dn, 0) + 1 + ) + # Handle other tag values + elif tag in ['100', '101', '111', '115']: + + # Largest nentry, push current nentry onto the heap, no duplicates +- if int(nentries) not in self.result['nentries_set']: +- heapq.heappush(self.result['nentries_num'], int(nentries)) +- self.result['nentries_set'].add(int(nentries)) ++ if int(nentries) not in self.result.nentries_set: ++ heapq.heappush(self.result.nentries_num, int(nentries)) ++ self.result.nentries_set.add(int(nentries)) + + # If the heap exceeds size_limit, pop the smallest element from root +- if len(self.result['nentries_num']) > self.size_limit: +- removed = heapq.heappop(self.result['nentries_num']) +- self.result['nentries_set'].remove(removed) ++ if len(self.result.nentries_num) > self.size_limit: ++ removed = heapq.heappop(self.result.nentries_num) ++ self.result.nentries_set.remove(removed) ++ ++ self.logger.debug(f"_process_result_stats - End") + + def _process_search_stats(self, groups: dict): + """ +@@ -873,10 +916,11 @@ class logAnalyser: + Raises: + KeyError: If required keys are missing in the `groups` dictionary. + """ ++ self.logger.debug(f"_process_search_stats - Start - {groups}") ++ + try: + conn_id = groups.get('conn_id') + op_id = groups.get('op_id') +- restart_ctr = groups.get('restart_ctr') + search_base = groups['search_base'] + search_scope = groups['search_scope'] + search_attrs = groups['search_attrs'] +@@ -886,33 +930,34 @@ class logAnalyser: + return + + # Create a tracking keys for this entry ++ restart_ctr = self.server.counters['restart'] + restart_conn_op_key = (restart_ctr, conn_id, op_id) + restart_conn_key = (restart_ctr, conn_id) + + # Should we ignore this operation +- if restart_conn_key in self.connection['exclude_ip_map']: ++ if restart_conn_key in self.connection.exclude_ip: + return None + + # Bump search and global op count +- self.search['search_ctr'] = self.search.get('search_ctr', 0) + 1 +- self.operation['all_op_ctr'] = self.operation.get('all_op_ctr', 0) + 1 ++ self.search.counters['search'] += 1 ++ self.operation.counters['total'] += 1 + + # Search attributes + if search_attrs is not None: + if search_attrs == 'ALL': +- self.search['attr_dict']['All Attributes'] += 1 ++ self.search.attrs['All Attributes'] += 1 + else: + for attr in search_attrs.split(): + attr = attr.strip('"') +- self.search['attr_dict'][attr] += 1 ++ self.search.attrs[attr] += 1 + + # If the associated conn id for the bind DN matches update op counter +- for dn in self.bind['report_dn']: +- conns = self.bind['report_dn'][dn]['conn'] ++ for dn in self.bind.report_dn: ++ conns = self.bind.report_dn[dn]['conn'] + if conn_id in conns: + bind_dn_key = self._report_dn_key(dn, self.report_dn) + if bind_dn_key: +- self.bind['report_dn'][bind_dn_key]['srch'] = self.bind['report_dn'][bind_dn_key].get('srch', 0) + 1 ++ self.bind.report_dn[bind_dn_key]['srch'] = self.bind.report_dn[bind_dn_key].get('srch', 0) + 1 + + # Search base + if search_base is not None: +@@ -924,49 +969,51 @@ class logAnalyser: + search_base = base.lower() + if search_base: + if self.verbose: +- self.search['base_map'][search_base] = self.search['base_map'].get(search_base, 0) + 1 +- self.search['base_map_rco'][restart_conn_op_key] = search_base ++ self.search.bases[search_base] += 1#self.search.bases.get(search_base, 0) + 1 ++ self.search.base_rst_con_op_map[restart_conn_op_key] = search_base + + # Search scope + if search_scope is not None: + if self.verbose: +- self.search['scope_map_rco'][restart_conn_op_key] = SCOPE_LABEL[int(search_scope)] ++ self.search.scope_rst_con_op_map[restart_conn_op_key] = SCOPE_LABEL[int(search_scope)] + + # Search filter + if search_filter is not None: + if self.verbose: +- self.search['filter_map_rco'][restart_conn_op_key] = search_filter +- self.search['filter_dict'][search_filter] = self.search['filter_dict'].get(search_filter, 0) + 1 ++ self.search.filter_rst_con_op_map[restart_conn_op_key] = search_filter ++ self.search.filter_dict[search_filter] = self.search.filter_dict.get(search_filter, 0) + 1 + + found = False +- for idx, (count, filter) in enumerate(self.search['filter_list']): ++ for idx, (count, filter) in enumerate(self.search.filter_list): + if filter == search_filter: + found = True +- self.search['filter_list'][idx] = (self.search['filter_dict'][search_filter] + 1, search_filter) +- heapq.heapify(self.search['filter_list']) ++ self.search.filter_list[idx] = (self.search.filter_dict[search_filter] + 1, search_filter) ++ heapq.heapify(self.search.filter_list) + break + + if not found: +- if len(self.search['filter_list']) < self.size_limit: +- heapq.heappush(self.search['filter_list'], (1, search_filter)) ++ if len(self.search.filter_list) < self.size_limit: ++ heapq.heappush(self.search.filter_list, (1, search_filter)) + else: +- heapq.heappushpop(self.search['filter_list'], (self.search['filter_dict'][search_filter], search_filter)) ++ heapq.heappushpop(self.search.filter_list, (self.search.filter_dict[search_filter], search_filter)) + + # Check for an entire base search + if "objectclass=*" in search_filter.lower() or "objectclass=top" in search_filter.lower(): + if search_scope == '2': +- self.search['base_search_ctr'] = self.search.get('base_search_ctr', 0) + 1 ++ self.search.counters['base_search'] += 1 + + # Persistent search + if groups['options'] is not None: + options = groups['options'] + if options == 'persistent': +- self.search['persistent_ctr'] = self.search.get('persistent_ctr', 0) + 1 ++ self.search.counters['persistent'] += 1 + + # Authorization identity + if groups['authzid_dn'] is not None: + self.search['authzid'] = self.search.get('authzid', 0) + 1 + ++ self.logger.debug(f"_process_search_stats - End") ++ + def _process_bind_stats(self, groups: dict): + """ + Process and update statistics based on the parsed result group. +@@ -975,7 +1022,6 @@ class logAnalyser: + groups (dict): A dictionary containing operation information. Expected keys: + - 'conn_id': Connection identifier. + - 'op_id': Operation identifier. +- - 'restart_ctr': Server restart count. + - 'bind_dn': Bind DN. + - 'bind_method': Bind method (sasl, simple). + - 'bind_version': Bind version. +@@ -983,80 +1029,74 @@ class logAnalyser: + Raises: + KeyError: If required keys are missing in the `groups` dictionary. + """ ++ self.logger.debug(f"_process_bind_stats - Start - {groups}") ++ + try: + conn_id = groups.get('conn_id') + op_id = groups.get('op_id') +- restart_ctr = groups.get('restart_ctr') + bind_dn = groups.get('bind_dn') +- bind_method = groups['bind_method'] +- bind_version = groups['bind_version'] ++ bind_method = groups.get('bind_method') ++ bind_version = groups.get('bind_version') + except KeyError as e: + self.logger.error(f"Missing key in groups: {e}") + return + +- # If this is the first connection (indicating a server restart), increment restart counter +- if conn_id == '1': +- self.server['restart_ctr'] = self.server.get('restart_ctr', 0) + 1 +- + # Create a tracking keys for this entry ++ restart_ctr = self.server.counters['restart'] + restart_conn_key = (restart_ctr, conn_id) + conn_op_key = (conn_id, op_id) + ++ if bind_dn.strip() == '': ++ bind_dn = 'Anonymous' ++ bind_dn_normalised = bind_dn.lower() if bind_dn != 'Anonymous' else 'anonymous' ++ + # Should we ignore this operation +- if restart_conn_key in self.connection['exclude_ip_map']: ++ if restart_conn_key in self.connection.exclude_ip: + return None + +- # Bump bind and global op count +- self.bind['bind_ctr'] = self.bind.get('bind_ctr', 0) + 1 +- self.operation['all_op_ctr'] = self.operation.get('all_op_ctr', 0) + 1 ++ # Update counters ++ self.bind.counters['bind'] += 1 ++ self.operation.counters['total'] = self.operation.counters['total'] + 1 ++ self.bind.version[bind_version] += 1 + +- # Update bind version count +- self.bind['version'][bind_version] = self.bind['version'].get(bind_version, 0) + 1 +- if bind_dn == "": +- bind_dn = 'Anonymous' + + # If we need to report on this DN, capture some info for tracking + bind_dn_key = self._report_dn_key(bind_dn, self.report_dn) + if bind_dn_key: +- # Update bind count +- self.bind['report_dn'][bind_dn_key]['bind'] = self.bind['report_dn'][bind_dn_key].get('bind', 0) + 1 +- # Connection ID +- self.bind['report_dn'][bind_dn_key]['conn'].add(conn_id) ++ self.bind.report_dn[bind_dn_key]['bind'] = self.bind.report_dn[bind_dn_key].get('bind', 0) + 1 ++ self.bind.report_dn[bind_dn_key]['conn'].add(conn_id) ++ + # Loop over IPs captured at connection time to find the associated IP +- for (ip, ip_info) in self.connection['ip_map'].items(): ++ for (ip, ip_info) in self.connection.src_ip_map.items(): + if restart_conn_key in ip_info['keys']: +- self.bind['report_dn'][bind_dn_key]['ips'].add(ip) ++ self.bind.report_dn[bind_dn_key]['ips'].add(ip) + +- # sasl or simple bind ++ # Handle SASL or simple bind + if bind_method == 'sasl': +- self.bind['sasl_bind_ctr'] = self.bind.get('sasl_bind_ctr', 0) + 1 ++ self.bind.counters['sasl'] += 1 + sasl_mech = groups['sasl_mech'] +- if sasl_mech is not None: +- # Bump sasl mechanism count +- self.bind['sasl_mech_freq'][sasl_mech] = self.bind['sasl_mech_freq'].get(sasl_mech, 0) + 1 ++ if sasl_mech: ++ self.bind.sasl_mech[sasl_mech] += 1 ++ self.bind.conn_op_sasl_mech_map[conn_op_key] = sasl_mech + +- # Keep track of bind key to handle sasl result later +- self.bind['sasl_map_co'][conn_op_key] = sasl_mech ++ if bind_dn_normalised == self.root_dn.casefold(): ++ self.bind.counters['rootdn'] += 1 + + if bind_dn != "Anonymous": +- if bind_dn.casefold() == self.root_dn.casefold(): +- self.bind['rootdn_bind_ctr'] = self.bind.get('rootdn_bind_ctr', 0) + 1 ++ self.bind.dns[bind_dn] += 1 + +- # if self.verbose: +- self.bind['dn_freq'][bind_dn] = self.bind['dn_freq'].get(bind_dn, 0) + 1 +- self.bind['dn_map_rc'][restart_conn_key] = bind_dn.lower() + else: + if bind_dn == "Anonymous": +- self.bind['anon_bind_ctr'] = self.bind.get('anon_bind_ctr', 0) + 1 +- self.bind['dn_freq']['Anonymous'] = self.bind['dn_freq'].get('Anonymous', 0) + 1 +- self.bind['dn_map_rc'][restart_conn_key] = "anonymous" ++ self.bind.counters['anon'] += 1 ++ self.bind.dns['Anonymous'] += 1 + else: + if bind_dn.casefold() == self.root_dn.casefold(): +- self.bind['rootdn_bind_ctr'] = self.bind.get('rootdn_bind_ctr', 0) + 1 ++ self.bind.counters['rootdn'] += 1 ++ self.bind.dns[bind_dn] += 1 + +- # if self.verbose: +- self.bind['dn_freq'][bind_dn] = self.bind['dn_freq'].get(bind_dn, 0) + 1 +- self.bind['dn_map_rc'][restart_conn_key] = bind_dn.lower() ++ self.bind.restart_conn_dn_map[restart_conn_key] = bind_dn_normalised ++ ++ self.logger.debug(f"_process_bind_stats - End") + + def _process_unbind_stats(self, groups: dict): + """ +@@ -1065,27 +1105,31 @@ class logAnalyser: + Args: + groups (dict): A dictionary containing operation information. Expected keys: + - 'conn_id': Connection identifier. +- - 'restart_ctr': Server restart count. + + Raises: + KeyError: If required keys are missing in the `groups` dictionary. + """ ++ ++ self.logger.debug(f"_process_unbind_stats - Start - {groups}") ++ + try: + conn_id = groups.get('conn_id') +- restart_ctr = groups.get('restart_ctr') + except KeyError as e: + self.logger.error(f"Missing key in groups: {e}") + return + + # Create a tracking key for this entry ++ restart_ctr = self.server.counters['restart'] + restart_conn_key = (restart_ctr, conn_id) + + # Should we ignore this operation +- if restart_conn_key in self.connection['exclude_ip_map']: ++ if restart_conn_key in self.connection.exclude_ip: + return None + + # Bump unbind count +- self.bind['unbind_ctr'] = self.bind.get('unbind_ctr', 0) + 1 ++ self.bind.counters['unbind'] += 1 ++ ++ self.logger.debug(f"_process_unbind_stats - End") + + def _process_connect_stats(self, groups: dict): + """ +@@ -1094,15 +1138,18 @@ class logAnalyser: + Args: + groups (dict): A dictionary containing operation information. Expected keys: + - 'conn_id': Connection identifier. +- - 'restart_ctr': Server restart count. ++ - 'src_ip': Source IP address. ++ - 'fd': File descriptor. ++ - 'ssl': LDAPS. + + Raises: + KeyError: If required keys are missing in the `groups` dictionary. + """ ++ ++ self.logger.debug(f"_process_connect_stats - Start - {groups}") ++ + try: +- timestamp = groups.get('timestamp') + conn_id = groups.get('conn_id') +- restart_ctr = groups.get('restart_ctr') + src_ip = groups.get('src_ip') + fd = groups['fd'] + ssl = groups['ssl'] +@@ -1110,61 +1157,63 @@ class logAnalyser: + self.logger.error(f"Missing key in groups: {e}") + return + ++ # If conn=1, server has started a new lifecycle ++ if conn_id == '1': ++ self.server.counters['restart'] += 1 ++ + # Create a tracking key for this entry ++ restart_ctr = self.server.counters['restart'] + restart_conn_key = (restart_ctr, conn_id) + + # Should we exclude this IP + if self.exclude_ip and src_ip in self.exclude_ip: +- self.connection['exclude_ip_map'][restart_conn_key] = src_ip ++ self.connection.exclude_ip[restart_conn_key] = src_ip + return None + + if self.verbose: + # Update open connection count +- self.connection['open_conns'][src_ip] = self.connection['open_conns'].get(src_ip, 0) + 1 ++ self.connection.open_conns[src_ip] += 1 + + # Track the connection start normalised datetime object for latency report +- self.connection['start_time'][conn_id] = groups.get('timestamp') ++ self.connection.start_time[conn_id] = groups.get('timestamp') + + # Update general connection counters +- for key in ['conn_ctr', 'sim_conn_ctr']: +- self.connection[key] = self.connection.get(key, 0) + 1 ++ self.connection.counters['conn'] += 1 ++ self.connection.counters['sim_conn'] += 1 + + # Update the maximum number of simultaneous connections seen +- self.connection['max_sim_conn_ctr'] = max( +- self.connection.get('max_sim_conn_ctr', 0), +- self.connection['sim_conn_ctr'] ++ self.connection.counters['max_sim_conn'] = max( ++ self.connection.counters['max_sim_conn'], ++ self.connection.counters['sim_conn'] + ) + + # Update protocol counters +- src_ip_tmp = 'local' if src_ip == 'local' else 'ldap' + if ssl: +- stat_count_key = 'ldaps_ctr' ++ self.connection.counters['ldaps'] += 1 ++ elif src_ip == 'local': ++ self.connection.counters['ldapi'] += 1 + else: +- stat_count_key = 'ldapi_ctr' if src_ip_tmp == 'local' else 'ldap_ctr' +- self.connection[stat_count_key] = self.connection.get(stat_count_key, 0) + 1 ++ self.connection.counters['ldap'] += 1 + + # Track file descriptor counters +- self.connection['fd_max_ctr'] = ( +- max(self.connection.get('fd_max_ctr', 0), int(fd)) +- ) +- self.connection['fd_taken_ctr'] = ( +- self.connection.get('fd_taken_ctr', 0) + 1 +- ) ++ self.connection.counters['fd_max'] = max(self.connection.counters['fd_taken'], int(fd)) ++ self.connection.counters['fd_taken'] += 1 + + # Track source IP +- self.connection['restart_conn_ip_map'][restart_conn_key] = src_ip ++ self.connection.restart_conn_ip_map[restart_conn_key] = src_ip + + # Update the count of connections seen from this IP +- if src_ip not in self.connection['ip_map']: +- self.connection['ip_map'][src_ip] = {} ++ if src_ip not in self.connection.src_ip_map: ++ self.connection.src_ip_map[src_ip] = {} ++ ++ self.connection.src_ip_map[src_ip]['count'] = self.connection.src_ip_map[src_ip].get('count', 0) + 1 + +- self.connection['ip_map'][src_ip]['count'] = self.connection['ip_map'][src_ip].get('count', 0) + 1 ++ if 'keys' not in self.connection.src_ip_map[src_ip]: ++ self.connection.src_ip_map[src_ip]['keys'] = set() + +- if 'keys' not in self.connection['ip_map'][src_ip]: +- self.connection['ip_map'][src_ip]['keys'] = set() ++ self.connection.src_ip_map[src_ip]['keys'].add(restart_conn_key) + +- self.connection['ip_map'][src_ip]['keys'].add(restart_conn_key) +- # self.connection['ip_map']['ip_key'] = restart_conn_key ++ self.logger.debug(f"_process_connect_stats - End") + + def _process_auth_stats(self, groups: dict): + """ +@@ -1173,7 +1222,6 @@ class logAnalyser: + Args: + groups (dict): A dictionary containing operation information. Expected keys: + - 'conn_id': Connection identifier. +- - 'restart_ctr': Server restart count. + - 'auth_protocol': Auth protocol (SSL, TLS). + - 'auth_version': Auth version. + - 'auth_message': Optional auth message. +@@ -1181,9 +1229,11 @@ class logAnalyser: + Raises: + KeyError: If required keys are missing in the `groups` dictionary. + """ ++ ++ self.logger.debug(f"_process_auth_stats - Start - {groups}") ++ + try: + conn_id = groups.get('conn_id') +- restart_ctr = groups.get('restart_ctr') + auth_protocol = groups.get('auth_protocol') + auth_version = groups.get('auth_version') + auth_message = groups.get('auth_message') +@@ -1192,15 +1242,16 @@ class logAnalyser: + return + + # Create a tracking key for this entry ++ restart_ctr = self.server.counters['restart'] + restart_conn_key = (restart_ctr, conn_id) + + # Should we ignore this operation +- if restart_conn_key in self.connection['exclude_ip_map']: ++ if restart_conn_key in self.connection.exclude_ip: + return None + + if auth_protocol: +- if restart_conn_key not in self.auth['auth_info']: +- self.auth['auth_info'][restart_conn_key] = { ++ if restart_conn_key not in self.auth.auth_info: ++ self.auth.auth_info[restart_conn_key] = { + 'proto': auth_protocol, + 'version': auth_version, + 'count': 0, +@@ -1209,19 +1260,19 @@ class logAnalyser: + + if auth_message: + # Increment counters and add auth message +- self.auth['auth_info'][restart_conn_key]['message'].append(auth_message) ++ self.auth.auth_info[restart_conn_key]['message'].append(auth_message) + + # Bump auth related counters +- self.auth['cipher_ctr'] = self.auth.get('cipher_ctr', 0) + 1 +- self.auth['auth_info'][restart_conn_key]['count'] = ( +- self.auth['auth_info'][restart_conn_key].get('count', 0) + 1 +- ) ++ self.auth.counters['cipher_ctr'] += 1 ++ self.auth.auth_info[restart_conn_key]['count'] += 1 + + if auth_message: + if auth_message == 'client bound as': +- self.auth['ssl_client_bind_ctr'] = self.auth.get('ssl_client_bind_ctr', 0) + 1 ++ self.auth.counters['ssl_client_bind_ctr'] += 1 + elif auth_message == 'failed to map client certificate to LDAP DN': +- self.auth['ssl_client_bind_failed_ctr'] = self.auth.get('ssl_client_bind_failed_ctr', 0) + 1 ++ self.auth.counters['ssl_client_bind_failed_ctr'] += 1 ++ ++ self.logger.debug(f"_process_auth_stats - End") + + def _process_vlv_stats(self, groups: dict): + """ +@@ -1231,33 +1282,37 @@ class logAnalyser: + groups (dict): A dictionary containing operation information. Expected keys: + - 'conn_id': Connection identifier. + - 'op_id': Operation identifier. +- - 'restart_ctr': Server restart count. + + Raises: + KeyError: If required keys are missing in the `groups` dictionary. + """ ++ ++ self.logger.debug(f"_process_vlv_stats - Start - {groups}") ++ + try: + conn_id = groups.get('conn_id') + op_id = groups.get('op_id') +- restart_ctr = groups.get('restart_ctr') + except KeyError as e: + self.logger.error(f"Missing key in groups: {e}") + return + +- # Create tracking keys ++ # Create a tracking key for this entry ++ restart_ctr = self.server.counters['restart'] + restart_conn_op_key = (restart_ctr, conn_id, op_id) + restart_conn_key = (restart_ctr, conn_id) + + # Should we ignore this operation +- if restart_conn_key in self.connection['exclude_ip_map']: ++ if restart_conn_key in self.connection.exclude_ip: + return None + + # Bump vlv and global op stats +- self.vlv['vlv_ctr'] = self.vlv.get('vlv_ctr', 0) + 1 +- self.operation['all_op_ctr'] = self.operation.get('all_op_ctr', 0) + 1 ++ self.vlv.counters['vlv'] += 1 ++ self.operation.counters['total'] = self.operation.counters['total'] + 1 + + # Key and value are the same, makes set operations easier later on +- self.vlv['vlv_map_rco'][restart_conn_op_key] = restart_conn_op_key ++ self.vlv.rst_con_op_map[restart_conn_op_key] = restart_conn_op_key ++ ++ self.logger.debug(f"_process_vlv_stats - End") + + def _process_abandon_stats(self, groups: dict): + """ +@@ -1267,38 +1322,41 @@ class logAnalyser: + groups (dict): A dictionary containing operation information. Expected keys: + - 'conn_id': Connection identifier. + - 'op_id': Operation identifier. +- - 'restart_ctr': Server restart count. + - 'targetop': The target operation. + - 'msgid': Message ID. + + Raises: + KeyError: If required keys are missing in the `groups` dictionary. + """ ++ ++ self.logger.debug(f"_process_abandon_stats - Start - {groups}") ++ + try: + conn_id = groups.get('conn_id') + op_id = groups.get('op_id') +- restart_ctr = groups.get('restart_ctr') + targetop = groups.get('targetop') + msgid = groups.get('msgid') + except KeyError as e: + self.logger.error(f"Missing key in groups: {e}") + return + +- # Create a tracking keys +- restart_conn_op_key = (restart_ctr, conn_id, op_id) ++ # Create a tracking key for this entry ++ restart_ctr = self.server.counters['restart'] + restart_conn_key = (restart_ctr, conn_id) + + # Should we ignore this operation +- if restart_conn_key in self.connection['exclude_ip_map']: ++ if restart_conn_key in self.connection.exclude_ip: + return None + + # Bump some stats +- self.result['result_ctr'] = self.result.get('result_ctr', 0) + 1 +- self.operation['all_op_ctr'] = self.operation.get('all_op_ctr', 0) + 1 +- self.operation['abandon_op_ctr'] = self.operation.get('abandon_op_ctr', 0) + 1 ++ self.result.counters['result'] += 1 ++ self.operation.counters['total'] = self.operation.counters['total'] + 1 ++ self.operation.counters['abandon'] += 1 + + # Track abandoned operation for later processing +- self.operation['abandoned_map_rco'][restart_conn_op_key] = (conn_id, op_id, targetop, msgid) ++ self.operation.rst_con_op_map['abandon'] = (conn_id, op_id, targetop, msgid) ++ ++ self.logger.debug(f"_process_abandon_stats - End") + + def _process_sort_stats(self, groups: dict): + """ +@@ -1307,26 +1365,30 @@ class logAnalyser: + Args: + groups (dict): A dictionary containing operation information. Expected keys: + - 'conn_id': Connection identifier. +- - 'restart_ctr': Server restart count. + + Raises: + KeyError: If required keys are missing in the `groups` dictionary. + """ ++ ++ self.logger.debug(f"_process_sort_stats - Start - {groups}") ++ + try: + conn_id = groups.get('conn_id') +- restart_ctr = groups.get('restart_ctr') + except KeyError as e: + self.logger.error(f"Missing key in groups: {e}") + return + + # Create a tracking key for this entry ++ restart_ctr = self.server.counters['restart'] + restart_conn_key = (restart_ctr, conn_id) + + # Should we ignore this operation +- if restart_conn_key in self.connection['exclude_ip_map']: ++ if restart_conn_key in self.connection.exclude_ip: + return None + +- self.operation['sort_op_ctr'] = self.operation.get('sort_op_ctr', 0) + 1 ++ self.operation.counters['sort'] += 1 ++ ++ self.logger.debug(f"_process_sort_stats - End") + + def _process_extend_op_stats(self, groups: dict): + """ +@@ -1342,6 +1404,9 @@ class logAnalyser: + Raises: + KeyError: If required keys are missing in the `groups` dictionary. + """ ++ ++ self.logger.debug(f"_process_extend_op_stats - Start - {groups}") ++ + try: + conn_id = groups.get('conn_id') + op_id = groups.get('op_id') +@@ -1352,31 +1417,34 @@ class logAnalyser: + return + + # Create a tracking key for this entry ++ restart_ctr = self.server.counters['restart'] + restart_conn_op_key = (restart_ctr, conn_id, op_id) + restart_conn_key = (restart_ctr, conn_id) + + # Should we ignore this operation +- if restart_conn_key in self.connection['exclude_ip_map']: ++ if restart_conn_key in self.connection.exclude_ip: + return None + + # Increment global operation counters +- self.operation['all_op_ctr'] = self.operation.get('all_op_ctr', 0) + 1 +- self.operation['extnd_op_ctr'] = self.operation.get('extnd_op_ctr', 0) + 1 ++ self.operation.counters['total'] = self.operation.counters['total'] + 1 ++ self.operation.counters['extnd'] += 1 + + # Track extended operation data if an OID is present + if oid is not None: +- self.operation['extop_dict'][oid] = self.operation['extop_dict'].get(oid, 0) + 1 +- self.operation['extop_map_rco'][restart_conn_op_key] = ( +- self.operation['extop_map_rco'].get(restart_conn_op_key, 0) + 1 ++ self.operation.extended[oid] += 1 ++ self.operation.rst_con_op_map['extnd'][restart_conn_op_key] = ( ++ self.operation.rst_con_op_map['extnd'].get(restart_conn_op_key, 0) + 1 + ) + + # If the conn_id is associated with this DN, update op counter +- for dn in self.bind['report_dn']: +- conns = self.bind['report_dn'][dn]['conn'] ++ for dn in self.bind.report_dn: ++ conns = self.bind.report_dn[dn]['conn'] + if conn_id in conns: + bind_dn_key = self._report_dn_key(dn, self.report_dn) + if bind_dn_key: +- self.bind['report_dn'][bind_dn_key]['ext'] = self.bind['report_dn'][bind_dn_key].get('ext', 0) + 1 ++ self.bind.report_dn[bind_dn_key]['ext'] = self.bind.report_dn[bind_dn_key].get('ext', 0) + 1 ++ ++ self.logger.debug(f"_process_extend_op_stats - End") + + def _process_autobind_stats(self, groups: dict): + """ +@@ -1385,43 +1453,47 @@ class logAnalyser: + Args: + groups (dict): A dictionary containing operation information. Expected keys: + - 'conn_id': Connection identifier. +- - 'restart_ctr': Server restart count. + - 'bind_dn': Bind DN ("cn=Directory Manager") + + Raises: + KeyError: If required keys are missing in the `groups` dictionary. + """ ++ ++ self.logger.debug(f"_process_autobind_stats - Start - {groups}") ++ + try: + conn_id = groups.get('conn_id') +- restart_ctr = groups.get('restart_ctr') + bind_dn = groups.get('bind_dn') + except KeyError as e: + self.logger.error(f"Missing key in groups: {e}") + return + + # Create a tracking key for this entry ++ restart_ctr = self.server.counters['restart'] + restart_conn_key = (restart_ctr, conn_id) + + # Should we ignore this operation +- if restart_conn_key in self.connection['exclude_ip_map']: ++ if restart_conn_key in self.connection.exclude_ip: + return None + + # Bump relevant counters +- self.bind['bind_ctr'] = self.bind.get('bind_ctr', 0) + 1 +- self.bind['autobind_ctr'] = self.bind.get('autobind_ctr', 0) + 1 +- self.operation['all_op_ctr'] = self.operation.get('all_op_ctr', 0) + 1 ++ self.bind.counters['bind'] += 1 ++ self.bind.counters['autobind'] += 1 ++ self.operation.counters['total'] += 1 + + # Handle an anonymous autobind (empty bind_dn) + if bind_dn == "": +- self.bind['anon_bind_ctr'] = self.bind.get('anon_bind_ctr', 0) + 1 ++ self.bind.counters['anon'] += 1 + else: +- # Process non-anonymous binds, does the bind_dn if exist in dn_map_rc +- bind_dn = self.bind['dn_map_rc'].get(restart_conn_key, bind_dn) ++ # Process non-anonymous binds, does the bind_dn if exist in restart_conn_dn_map ++ bind_dn = self.bind.restart_conn_dn_map.get(restart_conn_key, bind_dn) + if bind_dn: + if bind_dn.casefold() == self.root_dn.casefold(): +- self.bind['rootdn_bind_ctr'] = self.bind.get('rootdn_bind_ctr', 0) + 1 ++ self.bind.counters['rootdn'] += 1 + bind_dn = bind_dn.lower() +- self.bind['dn_freq'][bind_dn] = self.bind['dn_freq'].get(bind_dn, 0) + 1 ++ self.bind.dns[bind_dn] = self.bind.dns.get(bind_dn, 0) + 1 ++ ++ self.logger.debug(f"_process_autobind_stats - End") + + def _process_disconnect_stats(self, groups: dict): + """ +@@ -1430,7 +1502,6 @@ class logAnalyser: + Args: + groups (dict): A dictionary containing operation information. Expected keys: + - 'conn_id': Connection identifier. +- - 'restart_ctr': Server restart count. + - 'timestamp': The timestamp of the disconnect event. + - 'error_code': Error code associated with the disconnect, if any. + - 'disconnect_code': Disconnect code, if any. +@@ -1438,9 +1509,11 @@ class logAnalyser: + Raises: + KeyError: If required keys are missing in the `groups` dictionary. + """ ++ ++ self.logger.debug(f"_process_disconnect_stats - Start - {groups}") ++ + try: + conn_id = groups.get('conn_id') +- restart_ctr = groups.get('restart_ctr') + timestamp = groups.get('timestamp') + error_code = groups.get('error_code') + disconnect_code = groups.get('disconnect_code') +@@ -1449,17 +1522,18 @@ class logAnalyser: + return + + # Create a tracking key for this entry ++ restart_ctr = self.server.counters['restart'] + restart_conn_key = (restart_ctr, conn_id) + + # Should we ignore this operation +- if restart_conn_key in self.connection['exclude_ip_map']: ++ if restart_conn_key in self.connection.exclude_ip: + return None + + if self.verbose: + # Handle verbose logging for open connections and IP addresses +- src_ip = self.connection['restart_conn_ip_map'].get(restart_conn_key) +- if src_ip and src_ip in self.connection.get('open_conns', {}): +- open_conns = self.connection['open_conns'] ++ src_ip = self.connection.restart_conn_ip_map.get(restart_conn_key) ++ if src_ip and src_ip in self.connection.open_conns: ++ open_conns = self.connection.open_conns + if open_conns[src_ip] > 1: + open_conns[src_ip] -= 1 + else: +@@ -1467,7 +1541,7 @@ class logAnalyser: + + # Handle latency and disconnect times + if self.verbose: +- start_time = self.connection['start_time'].get(conn_id, None) ++ start_time = self.connection.start_time[conn_id] + finish_time = groups.get('timestamp') + if start_time and timestamp: + latency = self.get_elapsed_time(start_time, finish_time, "seconds") +@@ -1475,28 +1549,29 @@ class logAnalyser: + LATENCY_GROUPS[bucket] += 1 + + # Reset start time for the connection +- self.connection['start_time'][conn_id] = None ++ self.connection.start_time[conn_id] = None + + # Update connection stats +- self.connection['sim_conn_ctr'] = self.connection.get('sim_conn_ctr', 0) - 1 +- self.connection['fd_returned_ctr'] = ( +- self.connection.get('fd_returned_ctr', 0) + 1 +- ) ++ self.connection.counters['sim_conn'] -= 1 ++ self.connection.counters['fd_returned'] += 1 + + # Track error and disconnect codes if provided + if error_code is not None: + error_type = DISCONNECT_ERRORS.get(error_code, 'unknown') + if disconnect_code is not None: + # Increment the count for the specific error and disconnect code +- error_map = self.connection.setdefault(error_type, {}) +- error_map[disconnect_code] = error_map.get(disconnect_code, 0) + 1 ++ # error_map = self.connection.setdefault(error_type, {}) ++ # error_map[disconnect_code] = error_map.get(disconnect_code, 0) + 1 ++ self.connection[error_type][disconnect_code] += 1 + + # Handle disconnect code and update stats + if disconnect_code is not None: +- self.connection['disconnect_code'][disconnect_code] = ( +- self.connection['disconnect_code'].get(disconnect_code, 0) + 1 ++ self.connection.disconnect_code[disconnect_code] = ( ++ self.connection.disconnect_code.get(disconnect_code, 0) + 1 + ) +- self.connection['disconnect_code_map'][restart_conn_key] = disconnect_code ++ self.connection.restart_conn_disconnect_map[restart_conn_key] = disconnect_code ++ ++ self.logger.debug(f"_process_disconnect_stats - End") + + def _group_latencies(self, latency_seconds: int): + """ +@@ -1530,49 +1605,57 @@ class logAnalyser: + Args: + groups (dict): A dictionary containing operation information. Expected keys: + - 'conn_id': Connection identifier. +- - 'restart_ctr': Server restart count. + - 'op_id': Operation identifier. + + Raises: + KeyError: If required keys are missing in the `groups` dictionary. + """ ++ self.logger.debug(f"_process_crud_stats - Start - {groups}") + try: + conn_id = groups.get('conn_id') +- restart_ctr = groups.get('restart_ctr') + op_type = groups.get('op_type') +- internal = groups.get('internal') + except KeyError as e: + self.logger.error(f"Missing key in groups: {e}") + return + + # Create a tracking key for this entry ++ restart_ctr = self.server.counters['restart'] + restart_conn_key = (restart_ctr, conn_id) + + # Should we ignore this operation +- if restart_conn_key in self.connection['exclude_ip_map']: ++ if restart_conn_key in self.connection.exclude_ip: + return None + +- self.operation['all_op_ctr'] = self.operation.get('all_op_ctr', 0) + 1 ++ self.operation.counters['total'] = self.operation.counters['total'] + 1 + + # Use operation type as key for stats + if op_type is not None: + op_key = op_type.lower() +- self.operation[f"{op_key}_op_ctr"] = self.operation.get(f"{op_key}_op_ctr", 0) + 1 +- self.operation[f"{op_key}_map_rco"][restart_conn_key] = ( +- self.operation[f"{op_key}_map_rco"].get(restart_conn_key, 0) + 1 +- ) ++ if op_key not in self.operation.counters: ++ self.operation.counters[op_key] = 0 ++ if op_key not in self.operation.rst_con_op_map: ++ self.operation.rst_con_op_map[op_key] = {} ++ ++ # Increment op type counter ++ self.operation.counters[op_key] += 1 ++ ++ # Increment the op type map counter ++ current_count = self.operation.rst_con_op_map[op_key].get(restart_conn_key, 0) ++ self.operation.rst_con_op_map[op_key][restart_conn_key] = current_count + 1 + + # If the conn_id is associated with this DN, update op counter +- for dn in self.bind['report_dn']: +- conns = self.bind['report_dn'][dn]['conn'] ++ for dn in self.bind.report_dn: ++ conns = self.bind.report_dn[dn]['conn'] + if conn_id in conns: + bind_dn_key = self._report_dn_key(dn, self.report_dn) + if bind_dn_key: +- self.bind['report_dn'][bind_dn_key][op_key] = self.bind['report_dn'][bind_dn_key].get(op_key, 0) + 1 ++ self.bind.report_dn[bind_dn_key][op_key] = self.bind.report_dn[bind_dn_key].get(op_key, 0) + 1 + + # Authorization identity + if groups['authzid_dn'] is not None: +- self.operation['authzid'] = self.operation.get('authzid', 0) + 1 ++ self.operation.counters['authzid'] += 1 ++ ++ self.logger.debug(f"_process_crud_stats - End") + + def _process_entry_referral_stats(self, groups: dict): + """ +@@ -1581,33 +1664,36 @@ class logAnalyser: + Args: + groups (dict): A dictionary containing operation information. Expected keys: + - 'conn_id': Connection identifier. +- - 'restart_ctr': Server restart count. + - 'op_id': Operation identifier. + + Raises: + KeyError: If required keys are missing in the `groups` dictionary. + """ ++ self.logger.debug(f"_process_entry_referral_stats - Start - {groups}") ++ + try: + conn_id = groups.get('conn_id') +- restart_ctr = groups.get('restart_ctr') + op_type = groups.get('op_type') + except KeyError as e: + self.logger.error(f"Missing key in groups: {e}") + return + + # Create a tracking key for this entry ++ restart_ctr = self.server.counters['restart'] + restart_conn_key = (restart_ctr, conn_id) + + # Should we ignore this operation +- if restart_conn_key in self.connection['exclude_ip_map']: ++ if restart_conn_key in self.connection.exclude_ip: + return None + + # Process operation type + if op_type is not None: + if op_type == 'ENTRY': +- self.result['entry_count'] = self.result.get('entry_count', 0) + 1 ++ self.result.counters['entry'] += 1 + elif op_type == 'REFERRAL': +- self.result['referral_count'] = self.result.get('referral_count', 0) + 1 ++ self.result.counters['referral'] += 1 ++ ++ self.logger.debug(f"_process_entry_referral_stats - End") + + def _process_and_write_stats(self, norm_timestamp: str, bytes_read: int): + """ +@@ -1620,6 +1706,7 @@ class logAnalyser: + Returns: + None + """ ++ self.logger.debug(f"_process_and_write_stats - Start") + + if self.csv_writer is None: + self.logger.error("CSV writer not enabled.") +@@ -1627,23 +1714,23 @@ class logAnalyser: + + # Define the stat mapping + stats = { +- 'result_ctr': self.result, +- 'search_ctr': self.search, +- 'add_op_ctr': self.operation, +- 'mod_op_ctr': self.operation, +- 'modrdn_op_ctr': self.operation, +- 'cmp_op_ctr': self.operation, +- 'del_op_ctr': self.operation, +- 'abandon_op_ctr': self.operation, +- 'conn_ctr': self.connection, +- 'ldaps_ctr': self.connection, +- 'bind_ctr': self.bind, +- 'anon_bind_ctr': self.bind, +- 'unbind_ctr': self.bind, +- 'notesA_ctr': self.result, +- 'notesU_ctr': self.result, +- 'notesF_ctr': self.result, +- 'etime_stat': self.result ++ 'result': self.result.counters, ++ 'search': self.search.counters, ++ 'add': self.operation.counters, ++ 'mod': self.operation.counters, ++ 'modrdn': self.operation.counters, ++ 'cmp': self.operation.counters, ++ 'del': self.operation.counters, ++ 'abandon': self.operation.counters, ++ 'conn': self.connection.counters, ++ 'ldaps': self.connection.counters, ++ 'bind': self.bind.counters, ++ 'anon': self.bind.counters, ++ 'unbind': self.bind.counters, ++ 'notesA': self.result.counters, ++ 'notesU': self.result.counters, ++ 'notesF': self.result.counters, ++ 'etime_stat': self.result.counters + } + + # Build the current stat block +@@ -1675,8 +1762,7 @@ class logAnalyser: + + # out_stat_block[0] = self._convert_datetime_to_timestamp(out_stat_block[0]) + self.csv_writer.writerow(out_stat_block) +- +- self.result['etime_stat'] = 0.0 ++ self.result.etime_stat = 0.0 + + # Update previous stats for the next interval + self.prev_stats = curr_stat_block +@@ -1705,7 +1791,9 @@ class logAnalyser: + # Write the stat block to csv and reset elapsed time for the next interval + # out_stat_block[0] = self._convert_datetime_to_timestamp(out_stat_block[0]) + self.csv_writer.writerow(out_stat_block) +- self.result['etime_stat'] = 0.0 ++ self.result.etime_stat = 0.0 ++ ++ self.logger.debug(f"_process_and_write_stats - End") + + def process_file(self, log_num: str, filepath: str): + """ +@@ -2254,45 +2342,45 @@ def main(): + sys.exit(1) + + # Prep for display +- elapsed_time = db.get_elapsed_time(db.server['first_time'], db.server['last_time'], "hms") +- elapsed_secs = db.get_elapsed_time(db.server['first_time'], db.server['last_time'], "seconds") +- num_ops = db.operation.get('all_op_ctr', 0) +- num_results = db.result.get('result_ctr', 0) +- num_conns = db.connection.get('conn_ctr', 0) +- num_ldap = db.connection.get('ldap_ctr', 0) +- num_ldapi = db.connection.get('ldapi_ctr', 0) +- num_ldaps = db.connection.get('ldaps_ctr', 0) +- num_startls = db.operation['extop_dict'].get(STLS_OID, 0) +- num_search = db.search.get('search_ctr', 0) +- num_mod = db.operation.get('mod_op_ctr', 0) +- num_add = db.operation.get('add_op_ctr', 0) +- num_del = db.operation.get('del_op_ctr', 0) +- num_modrdn = db.operation.get('modrdn_op_ctr', 0) +- num_cmp = db.operation.get('cmp_op_ctr', 0) +- num_bind = db.bind.get('bind_ctr', 0) +- num_unbind = db.bind.get('unbind_ctr', 0) +- num_proxyd_auths = db.operation.get('authzid', 0) + db.search.get('authzid', 0) +- num_time_count = db.result.get('timestamp_ctr') ++ elapsed_time = db.get_elapsed_time(db.server.first_time, db.server.last_time, "hms") ++ elapsed_secs = db.get_elapsed_time(db.server.first_time, db.server.last_time, "seconds") ++ num_ops = db.operation.counters['total'] ++ num_results = db.result.counters['result'] ++ num_conns = db.connection.counters['conn'] ++ num_ldap = db.connection.counters['ldap'] ++ num_ldapi = db.connection.counters['ldapi'] ++ num_ldaps = db.connection.counters['ldaps'] ++ num_startls = db.operation.extended.get(STLS_OID, 0) ++ num_search = db.search.counters['search'] ++ num_mod = db.operation.counters['mod'] ++ num_add = db.operation.counters['add'] ++ num_del = db.operation.counters['del'] ++ num_modrdn = db.operation.counters['modrdn'] ++ num_cmp = db.operation.counters['cmp'] ++ num_bind = db.bind.counters['bind'] ++ num_unbind = db.bind.counters['unbind'] ++ num_proxyd_auths = db.operation.counters['authzid'] + db.search.counters['authzid'] ++ num_time_count = db.result.counters['timestamp'] + if num_time_count: +- avg_wtime = round(db.result.get('total_wtime', 0)/num_time_count, 9) +- avg_optime = round(db.result.get('total_optime', 0)/num_time_count, 9) +- avg_etime = round(db.result.get('total_etime', 0)/num_time_count, 9) +- num_fd_taken = db.connection.get('fd_taken_ctr', 0) +- num_fd_rtn = db.connection.get('fd_returned_ctr', 0) +- +- num_DM_binds = db.bind.get('rootdn_bind_ctr', 0) +- num_base_search = db.search.get('base_search_ctr', 0) ++ avg_wtime = round(db.result.total_wtime/num_time_count, 9) ++ avg_optime = round(db.result.total_optime/num_time_count, 9) ++ avg_etime = round(db.result.total_etime/num_time_count, 9) ++ num_fd_taken = db.connection.counters['fd_taken'] ++ num_fd_rtn = db.connection.counters['fd_returned'] ++ ++ num_DM_binds = db.bind.counters['rootdn'] ++ num_base_search = db.search.counters['base_search'] + try: +- log_start_time = db.convert_timestamp_to_string(db.server.get('first_time', "")) ++ log_start_time = db.convert_timestamp_to_string(db.server.first_time) + except ValueError: + log_start_time = "Unknown" + + try: +- log_end_time = db.convert_timestamp_to_string(db.server.get('last_time', "")) ++ log_end_time = db.convert_timestamp_to_string(db.server.last_time) + except ValueError: + log_end_time = "Unknown" + +- print(f"\n\nTotal Log Lines Analysed:{db.server['lines_parsed']}\n") ++ print(f"\n\nTotal Log Lines Analysed:{db.server.counters['lines_parsed']}\n") + print("\n----------- Access Log Output ------------\n") + print(f"Start of Logs: {log_start_time}") + print(f"End of Logs: {log_end_time}") +@@ -2302,12 +2390,12 @@ def main(): + db.display_bind_report() + sys.exit(1) + +- print(f"\nRestarts: {db.server.get('restart_ctr', 0)}") +- if db.auth.get('cipher_ctr', 0) > 0: ++ print(f"\nRestarts: {db.server.counters['restart']}") ++ if db.auth.counters['cipher_ctr'] > 0: + print(f"Secure Protocol Versions:") + # Group data by protocol + version + unique message + grouped_data = defaultdict(lambda: {'count': 0, 'messages': set()}) +- for _, details in db.auth['auth_info'].items(): ++ for _, details in db.auth.auth_info.items(): + # If there is no protocol version + if details['version']: + proto_version = f"{details['proto']}{details['version']}" +@@ -2323,7 +2411,7 @@ def main(): + for ((proto_version, message), data) in grouped_data.items(): + print(f" - {proto_version} {message} ({data['count']} connection{'s' if data['count'] > 1 else ''})") + +- print(f"Peak Concurrent connections: {db.connection.get('max_sim_conn_ctr', 0)}") ++ print(f"Peak Concurrent connections: {db.connection.counters['max_sim_conn']}") + print(f"Total Operations: {num_ops}") + print(f"Total Results: {num_results}") + print(f"Overall Performance: {db.get_overall_perf(num_results, num_ops)}%") +@@ -2344,111 +2432,112 @@ def main(): + print(f"\nAverage wtime (wait time): {avg_wtime:.9f}") + print(f"Average optime (op time): {avg_optime:.9f}") + print(f"Average etime (elapsed time): {avg_etime:.9f}") +- print(f"\nMulti-factor Authentications: {db.result.get('notesM_ctr', 0)}") ++ print(f"\nMulti-factor Authentications: {db.result.counters['notesM']}") + print(f"Proxied Auth Operations: {num_proxyd_auths}") +- print(f"Persistent Searches: {db.search.get('persistent_ctr', 0)}") +- print(f"Internal Operations: {db.server.get('internal_op_ctr', 0)}") +- print(f"Entry Operations: {db.result.get('entry_count', 0)}") +- print(f"Extended Operations: {db.operation.get('extnd_op_ctr', 0)}") +- print(f"Abandoned Requests: {db.operation.get('abandon_op_ctr', 0)}") +- print(f"Smart Referrals Received: {db.result.get('referral_count', 0)}") +- print(f"\nVLV Operations: {db.vlv.get('vlv_ctr', 0)}") +- print(f"VLV Unindexed Searches: {len([key for key, value in db.vlv['vlv_map_rco'].items() if value == 'A'])}") +- print(f"VLV Unindexed Components: {len([key for key, value in db.vlv['vlv_map_rco'].items() if value == 'U'])}") +- print(f"SORT Operations: {db.operation.get('sort_op_ctr', 0)}") +- print(f"\nEntire Search Base Queries: {db.search.get('base_search_ctr', 0)}") +- print(f"Paged Searches: {db.result.get('notesP_ctr', 0)}") +- num_unindexed_search = len(db.notesA.keys()) ++ print(f"Persistent Searches: {db.search.counters['persistent']}") ++ print(f"Internal Operations: {db.operation.counters['internal']}") ++ print(f"Entry Operations: {db.result.counters['entry']}") ++ print(f"Extended Operations: {db.operation.counters['extnd']}") ++ print(f"Abandoned Requests: {db.operation.counters['abandon']}") ++ print(f"Smart Referrals Received: {db.result.counters['referral']}") ++ print(f"\nVLV Operations: {db.vlv.counters['vlv']}") ++ print(f"VLV Unindexed Searches: {len([key for key, value in db.vlv.rst_con_op_map.items() if value == 'A'])}") ++ print(f"VLV Unindexed Components: {len([key for key, value in db.vlv.rst_con_op_map.items() if value == 'U'])}") ++ print(f"SORT Operations: {db.operation.counters['sort']}") ++ print(f"\nEntire Search Base Queries: {num_base_search}") ++ print(f"Paged Searches: {db.result.counters['notesP']}") ++ num_unindexed_search = len(db.result.notes['A']) + print(f"Unindexed Searches: {num_unindexed_search}") +- if db.verbose: +- if num_unindexed_search > 0: +- for num, key in enumerate(db.notesA, start=1): +- src, conn, op = key +- restart_conn_op_key = (src, conn, op) +- print(f"\nUnindexed Search #{num} (notes=A)") +- print(f" - Date/Time: {db.notesA[restart_conn_op_key]['time']}") +- print(f" - Connection Number: {conn}") +- print(f" - Operation Number: {op}") +- print(f" - Etime: {db.notesA[restart_conn_op_key]['etime']}") +- print(f" - Nentries: {db.notesA[restart_conn_op_key]['nentries']}") +- print(f" - IP Address: {db.notesA[restart_conn_op_key]['ip']}") +- print(f" - Search Base: {db.notesA[restart_conn_op_key]['base']}") +- print(f" - Search Scope: {db.notesA[restart_conn_op_key]['scope']}") +- print(f" - Search Filter: {db.notesA[restart_conn_op_key]['filter']}") +- print(f" - Bind DN: {db.notesA[restart_conn_op_key]['bind_dn']}\n") +- +- num_unindexed_component = len(db.notesU.keys()) ++ if db.verbose and num_unindexed_search > 0: ++ for num, key in enumerate(db.result.notes['A'], start=1): ++ src, conn, op = key ++ data = db.result.notes['A'][key] ++ ++ print(f"\n Unindexed Search #{num} (notes=A)") ++ print(f" - Date/Time: {data.get('time', '-')}") ++ print(f" - Connection Number: {conn}") ++ print(f" - Operation Number: {op}") ++ print(f" - Etime: {data.get('etime', '-')}") ++ print(f" - Nentries: {data.get('nentries', 0)}") ++ print(f" - IP Address: {data.get('ip', '-')}") ++ print(f" - Search Base: {data.get('base', '-')}") ++ print(f" - Search Scope: {data.get('scope', '-')}") ++ print(f" - Search Filter: {data.get('filter', '-')}") ++ print(f" - Bind DN: {data.get('bind_dn', '-')}\n") ++ ++ num_unindexed_component = len(db.result.notes['U']) + print(f"Unindexed Components: {num_unindexed_component}") +- if db.verbose: +- if num_unindexed_component > 0: +- for num, key in enumerate(db.notesU, start=1): +- src, conn, op = key +- restart_conn_op_key = (src, conn, op) +- print(f"\nUnindexed Component #{num} (notes=U)") +- print(f" - Date/Time: {db.notesU[restart_conn_op_key]['time']}") +- print(f" - Connection Number: {conn}") +- print(f" - Operation Number: {op}") +- print(f" - Etime: {db.notesU[restart_conn_op_key]['etime']}") +- print(f" - Nentries: {db.notesU[restart_conn_op_key]['nentries']}") +- print(f" - IP Address: {db.notesU[restart_conn_op_key]['ip']}") +- print(f" - Search Base: {db.notesU[restart_conn_op_key]['base']}") +- print(f" - Search Scope: {db.notesU[restart_conn_op_key]['scope']}") +- print(f" - Search Filter: {db.notesU[restart_conn_op_key]['filter']}") +- print(f" - Bind DN: {db.notesU[restart_conn_op_key]['bind_dn']}\n") +- +- num_invalid_filter = len(db.notesF.keys()) ++ if db.verbose and num_unindexed_component > 0: ++ for num, key in enumerate(db.result.notes['U'], start=1): ++ src, conn, op = key ++ data = db.result.notes['U'][key] ++ ++ print(f"\n Unindexed Component #{num} (notes=U)") ++ print(f" - Date/Time: {data.get('time', '-')}") ++ print(f" - Connection Number: {conn}") ++ print(f" - Operation Number: {op}") ++ print(f" - Etime: {data.get('etime', '-')}") ++ print(f" - Nentries: {data.get('nentries', 0)}") ++ print(f" - IP Address: {data.get('ip', '-')}") ++ print(f" - Search Base: {data.get('base', '-')}") ++ print(f" - Search Scope: {data.get('scope', '-')}") ++ print(f" - Search Filter: {data.get('filter', '-')}") ++ print(f" - Bind DN: {data.get('bind_dn', '-')}\n") ++ ++ num_invalid_filter = len(db.result.notes['F']) + print(f"Invalid Attribute Filters: {num_invalid_filter}") +- if db.verbose: +- if num_invalid_filter > 0: +- for num, key in enumerate(db.notesF, start=1): +- src, conn, op = key +- restart_conn_op_key = (src, conn, op) +- print(f"\nInvalid Attribute Filter #{num} (notes=F)") +- print(f" - Date/Time: {db.notesF[restart_conn_op_key]['time']}") +- print(f" - Connection Number: {conn}") +- print(f" - Operation Number: {op}") +- print(f" - Etime: {db.notesF[restart_conn_op_key]['etime']}") +- print(f" - Nentries: {db.notesF[restart_conn_op_key]['nentries']}") +- print(f" - IP Address: {db.notesF[restart_conn_op_key]['ip']}") +- print(f" - Search Filter: {db.notesF[restart_conn_op_key]['filter']}") +- print(f" - Bind DN: {db.notesF[restart_conn_op_key]['bind_dn']}\n") ++ if db.verbose and num_invalid_filter > 0: ++ for num, key in enumerate(db.result.notes['F'], start=1): ++ src, conn, op = key ++ data = db.result.notes['F'][key] ++ ++ print(f"\n Invalid Attribute Filter #{num} (notes=F)") ++ print(f" - Date/Time: {data.get('time', '-')}") ++ print(f" - Connection Number: {conn}") ++ print(f" - Operation Number: {op}") ++ print(f" - Etime: {data.get('etime', '-')}") ++ print(f" - Nentries: {data.get('nentries', 0)}") ++ print(f" - IP Address: {data.get('ip', '-')}") ++ print(f" - Search Filter: {data.get('filter', '-')}") ++ print(f" - Bind DN: {data.get('bind_dn', '-')}\n") ++ + print(f"FDs Taken: {num_fd_taken}") + print(f"FDs Returned: {num_fd_rtn}") +- print(f"Highest FD Taken: {db.connection.get('fd_max_ctr', 0)}\n") +- num_broken_pipe = len(db.connection['broken_pipe']) ++ print(f"Highest FD Taken: {db.connection.counters['fd_max']}\n") ++ num_broken_pipe = len(db.connection.broken_pipe) + print(f"Broken Pipes: {num_broken_pipe}") + if num_broken_pipe > 0: +- for code, count in db.connection['broken_pipe'].items(): ++ for code, count in db.connection.broken_pipe.items(): + print(f" - {count} ({code}) {DISCONNECT_MSG.get(code, 'unknown')}") + print() +- num_reset_peer = len(db.connection['connection_reset']) ++ num_reset_peer = len(db.connection.connection_reset) + print(f"Connection Reset By Peer: {num_reset_peer}") + if num_reset_peer > 0: +- for code, count in db.connection['connection_reset'].items(): ++ for code, count in db.connection.connection_reset.items(): + print(f" - {count} ({code}) {DISCONNECT_MSG.get(code, 'unknown')}") + print() +- num_resource_unavail = len(db.connection['resource_unavail']) ++ num_resource_unavail = len(db.connection.resource_unavail) + print(f"Resource Unavailable: {num_resource_unavail}") + if num_resource_unavail > 0: +- for code, count in db.connection['resource_unavail'].items(): ++ for code, count in db.connection.resource_unavail.items(): + print(f" - {count} ({code}) {DISCONNECT_MSG.get(code, 'unknown')}") + print() +- print(f"Max BER Size Exceeded: {db.connection['disconnect_code'].get('B2', 0)}\n") +- print(f"Binds: {db.bind.get('bind_ctr', 0)}") +- print(f"Unbinds: {db.bind.get('unbind_ctr', 0)}") ++ print(f"Max BER Size Exceeded: {db.connection.disconnect_code.get('B2', 0)}\n") ++ print(f"Binds: {db.bind.counters['bind']}") ++ print(f"Unbinds: {db.bind.counters['unbind']}") + print(f"----------------------------------") +- print(f"- LDAP v2 Binds: {db.bind.get('version', {}).get('2', 0)}") +- print(f"- LDAP v3 Binds: {db.bind.get('version', {}).get('3', 0)}") +- print(f"- AUTOBINDs(LDAPI): {db.bind.get('autobind_ctr', 0)}") +- print(f"- SSL Client Binds {db.auth.get('ssl_client_bind_ctr', 0)}") +- print(f"- Failed SSL Client Binds: {db.auth.get('ssl_client_bind_failed_ctr', 0)}") +- print(f"- SASL Binds: {db.bind.get('sasl_bind_ctr', 0)}") +- if db.bind.get('sasl_bind_ctr', 0) > 0: +- saslmech = db.bind['sasl_mech_freq'] ++ print(f"- LDAP v2 Binds: {db.bind.version.get('2', 0)}") ++ print(f"- LDAP v3 Binds: {db.bind.version.get('3', 0)}") ++ print(f"- AUTOBINDs(LDAPI): {db.bind.counters['autobind']}") ++ print(f"- SSL Client Binds {db.auth.counters['ssl_client_bind_ctr']}") ++ print(f"- Failed SSL Client Binds: {db.auth.counters['ssl_client_bind_failed_ctr']}") ++ print(f"- SASL Binds: {db.bind.counters['sasl']}") ++ if db.bind.counters['sasl'] > 0: ++ saslmech = db.bind.sasl_mech + for saslb in sorted(saslmech.keys(), key=lambda k: saslmech[k], reverse=True): + print(f" - {saslb:<4}: {saslmech[saslb]}") + print(f"- Directory Manager Binds: {num_DM_binds}") +- print(f"- Anonymous Binds: {db.bind.get('anon_bind_ctr', 0)}\n") ++ print(f"- Anonymous Binds: {db.bind.counters['anon']}\n") + if db.verbose: + # Connection Latency + print(f"\n ----- Connection Latency Details -----\n") +@@ -2465,7 +2554,7 @@ def main(): + f"{LATENCY_GROUPS['> 15']:^7}") + + # Open Connections +- open_conns = db.connection['open_conns'] ++ open_conns = db.connection.open_conns + if len(open_conns) > 0: + print(f"\n ----- Current Open Connection IDs -----\n") + for conn in sorted(open_conns.keys(), key=lambda k: open_conns[k], reverse=True): +@@ -2473,12 +2562,12 @@ def main(): + + # Error Codes + print(f"\n----- Errors -----\n") +- error_freq = db.result['error_freq'] ++ error_freq = db.result.error_freq + for err in sorted(error_freq.keys(), key=lambda k: error_freq[k], reverse=True): + print(f"err={err:<2} {error_freq[err]:>10} {LDAP_ERR_CODES[err]:<30}") + + # Failed Logins +- bad_pwd_map = db.result['bad_pwd_map'] ++ bad_pwd_map = db.result.bad_pwd_map + bad_pwd_map_len = len(bad_pwd_map) + if bad_pwd_map_len > 0: + print(f"\n----- Top {db.size_limit} Failed Logins ------\n") +@@ -2495,27 +2584,27 @@ def main(): + print(f"{count:<10} {ip}") + + # Connection Codes +- disconnect_codes = db.connection['disconnect_code'] ++ disconnect_codes = db.connection.disconnect_code + if len(disconnect_codes) > 0: + print(f"\n----- Total Connection Codes ----\n") + for code in disconnect_codes: + print(f"{code:<2} {disconnect_codes[code]:>10} {DISCONNECT_MSG.get(code, 'unknown'):<30}") + + # Unique IPs +- restart_conn_ip_map = db.connection['restart_conn_ip_map'] +- ip_map = db.connection['ip_map'] +- ips_len = len(ip_map) ++ restart_conn_ip_map = db.connection.restart_conn_ip_map ++ src_ip_map = db.connection.src_ip_map ++ ips_len = len(src_ip_map) + if ips_len > 0: + print(f"\n----- Top {db.size_limit} Clients -----\n") + print(f"Number of Clients: {ips_len}") +- for num, (outer_ip, ip_info) in enumerate(ip_map.items(), start=1): ++ for num, (outer_ip, ip_info) in enumerate(src_ip_map.items(), start=1): + temp = {} + print(f"\n[{num}] Client: {outer_ip}") + print(f" {ip_info['count']} - Connection{'s' if ip_info['count'] > 1 else ''}") + for id, inner_ip in restart_conn_ip_map.items(): + (src, conn) = id + if outer_ip == inner_ip: +- code = db.connection['disconnect_code_map'].get((src, conn), 0) ++ code = db.connection.restart_conn_disconnect_map[(src, conn)] + if code: + temp[code] = temp.get(code, 0) + 1 + for code, count in temp.items(): +@@ -2524,7 +2613,7 @@ def main(): + break + + # Unique Bind DN's +- binds = db.bind.get('dn_freq', 0) ++ binds = db.bind.dns + binds_len = len(binds) + if binds_len > 0: + print(f"\n----- Top {db.size_limit} Bind DN's ----\n") +@@ -2532,10 +2621,10 @@ def main(): + for num, bind in enumerate(sorted(binds.keys(), key=lambda k: binds[k], reverse=True)): + if num >= db.size_limit: + break +- print(f"{db.bind['dn_freq'][bind]:<10} {bind:<30}") ++ print(f"{db.bind.dns[bind]:<10} {bind:<30}") + + # Unique search bases +- bases = db.search['base_map'] ++ bases = db.search.bases + num_bases = len(bases) + if num_bases > 0: + print(f"\n----- Top {db.size_limit} Search Bases -----\n") +@@ -2543,10 +2632,10 @@ def main(): + for num, base in enumerate(sorted(bases.keys(), key=lambda k: bases[k], reverse=True)): + if num >= db.size_limit: + break +- print(f"{db.search['base_map'][base]:<10} {base}") ++ print(f"{db.search.bases[base]:<10} {base}") + + # Unique search filters +- filters = sorted(db.search['filter_list'], reverse=True) ++ filters = sorted(db.search.filter_list, reverse=True) + num_filters = len(filters) + if num_filters > 0: + print(f"\n----- Top {db.size_limit} Search Filters -----\n") +@@ -2556,7 +2645,7 @@ def main(): + print(f"{count:<10} {filter}") + + # Longest elapsed times +- etimes = sorted(db.result['etime_duration'], reverse=True) ++ etimes = sorted(db.result.etime_duration, reverse=True) + num_etimes = len(etimes) + if num_etimes > 0: + print(f"\n----- Top {db.size_limit} Longest etimes (elapsed times) -----\n") +@@ -2566,7 +2655,7 @@ def main(): + print(f"etime={etime:<12}") + + # Longest wait times +- wtimes = sorted(db.result['wtime_duration'], reverse=True) ++ wtimes = sorted(db.result.wtime_duration, reverse=True) + num_wtimes = len(wtimes) + if num_wtimes > 0: + print(f"\n----- Top {db.size_limit} Longest wtimes (wait times) -----\n") +@@ -2576,7 +2665,7 @@ def main(): + print(f"wtime={wtime:<12}") + + # Longest operation times +- optimes = sorted(db.result['optime_duration'], reverse=True) ++ optimes = sorted(db.result.optime_duration, reverse=True) + num_optimes = len(optimes) + if num_optimes > 0: + print(f"\n----- Top {db.size_limit} Longest optimes (actual operation times) -----\n") +@@ -2586,7 +2675,7 @@ def main(): + print(f"optime={optime:<12}") + + # Largest nentries returned +- nentries = sorted(db.result['nentries_num'], reverse=True) ++ nentries = sorted(db.result.nentries_num, reverse=True) + num_nentries = len(nentries) + if num_nentries > 0: + print(f"\n----- Top {db.size_limit} Largest nentries -----\n") +@@ -2597,7 +2686,7 @@ def main(): + print() + + # Extended operations +- oids = db.operation['extop_dict'] ++ oids = db.operation.extended + num_oids = len(oids) + if num_oids > 0: + print(f"\n----- Top {db.size_limit} Extended Operations -----\n") +@@ -2607,7 +2696,7 @@ def main(): + print(f"{oids[oid]:<12} {oid:<30} {OID_MSG.get(oid, 'Other'):<60}") + + # Commonly requested attributes +- attrs = db.search['attr_dict'] ++ attrs = db.search.attrs + num_nattrs = len(attrs) + if num_nattrs > 0: + print(f"\n----- Top {db.size_limit} Most Requested Attributes -----\n") +@@ -2617,14 +2706,14 @@ def main(): + print(f"{attrs[attr]:<11} {attr:<10}") + print() + +- abandoned = db.operation['abandoned_map_rco'] ++ abandoned = db.operation.rst_con_op_map['abandon'] + num_abandoned = len(abandoned) + if num_abandoned > 0: + print(f"\n----- Abandon Request Stats -----\n") + for num, abandon in enumerate(abandoned, start=1): + (restart, conn, op) = abandon +- conn, op, target_op, msgid = db.operation['abandoned_map_rco'][(restart, conn, op)] +- print(f"{num:<6} conn={conn} op={op} msgid={msgid} target_op:{target_op} client={db.connection['restart_conn_ip_map'].get((restart, conn), 'Unknown')}") ++ conn, op, target_op, msgid = db.operation.rst_con_op_map['abandoned'][(restart, conn, op)] ++ print(f"{num:<6} conn={conn} op={op} msgid={msgid} target_op:{target_op} client={db.connection.restart_conn_ip_map.get((restart, conn), 'Unknown')}") + print() + + if db.recommends or db.verbose: +@@ -2639,15 +2728,15 @@ def main(): + print(f"\n {rec_count}. You have unindexed components. This can be caused by a search on an unindexed attribute or by returned results exceeding the nsslapd-idlistscanlimit. Unindexed components are not recommended. To refuse unindexed searches, set 'nsslapd-require-index' to 'on' under your database entry (e.g. cn=UserRoot,cn=ldbm database,cn=plugins,cn=config).\n") + rec_count += 1 + +- if db.connection['disconnect_code'].get('T1', 0) > 0: ++ if db.connection.disconnect_code.get('T1', 0) > 0: + print(f"\n {rec_count}. You have some connections being closed by the idletimeout setting. You may want to increase the idletimeout if it is set low.\n") + rec_count += 1 + +- if db.connection['disconnect_code'].get('T2', 0) > 0: ++ if db.connection.disconnect_code.get('T2', 0) > 0: + print(f"\n {rec_count}. You have some connections being closed by the ioblocktimeout setting. You may want to increase the ioblocktimeout.\n") + rec_count += 1 + +- if db.connection['disconnect_code'].get('T3', 0) > 0: ++ if db.connection.disconnect_code.get('T3', 0) > 0: + print(f"\n {rec_count}. You have some connections being closed because a paged result search limit has been exceeded. You may want to increase the search time limit.\n") + rec_count += 1 + +@@ -2663,29 +2752,29 @@ def main(): + print(f"\n {rec_count}. You have a high number of Directory Manager binds. The Directory Manager account should only be used under certain circumstances. Avoid using this account for client applications.\n") + rec_count += 1 + +- num_success = db.result['error_freq'].get('0', 0) +- num_err = sum(v for k, v in db.result['error_freq'].items() if k != '0') ++ num_success = db.result.error_freq.get('0', 0) ++ num_err = sum(v for k, v in db.result.error_freq.items() if k != '0') + if num_err > num_success: + print(f"\n {rec_count}. You have more unsuccessful operations than successful operations. You should investigate this difference.\n") + rec_count += 1 + +- num_close_clean = db.connection['disconnect_code'].get('U1', 0) +- num_close_total = num_err = sum(v for k, v in db.connection['disconnect_code'].items()) ++ num_close_clean = db.connection.disconnect_code.get('U1', 0) ++ num_close_total = num_err = sum(v for k, v in db.connection.disconnect_code.items()) + if num_close_clean < (num_close_total - num_close_clean): + print(f"\n {rec_count}. You have more abnormal connection codes than cleanly closed connections. You may want to investigate this difference.\n") + rec_count += 1 + + if num_time_count: +- if round(avg_etime, 1) > 0: +- print(f"\n {rec_count}. Your average etime is {avg_etime:.1f}. You may want to investigate this performance problem.\n") ++ if round(avg_etime, 9) > 0: ++ print(f"\n {rec_count}. Your average etime is {avg_etime:.9f}. You may want to investigate this performance problem.\n") + rec_count += 1 + +- if round(avg_wtime, 1) > 0.5: +- print(f"\n {rec_count}. Your average wtime is {avg_wtime:.1f}. You may need to increase the number of worker threads (nsslapd-threadnumber).\n") ++ if round(avg_wtime, 9) > 0.5: ++ print(f"\n {rec_count}. Your average wtime is {avg_wtime:.9f}. You may need to increase the number of worker threads (nsslapd-threadnumber).\n") + rec_count += 1 + +- if round(avg_optime, 1) > 0: +- print(f"\n {rec_count}. Your average optime is {avg_optime:.1f}. You may want to investigate this performance problem.\n") ++ if round(avg_optime, 9) > 0: ++ print(f"\n {rec_count}. Your average optime is {avg_optime:.9f}. You may want to investigate this performance problem.\n") + rec_count += 1 + + if num_base_search > (num_search * 0.25): +@@ -2699,4 +2788,4 @@ def main(): + + + if __name__ == "__main__": +- main() ++ main() +\ No newline at end of file +-- +2.49.0 + diff --git a/0007-Issue-6850-AddressSanitizer-memory-leak-in-mdb_init.patch b/0007-Issue-6850-AddressSanitizer-memory-leak-in-mdb_init.patch new file mode 100644 index 0000000..34034e4 --- /dev/null +++ b/0007-Issue-6850-AddressSanitizer-memory-leak-in-mdb_init.patch @@ -0,0 +1,65 @@ +From 9d851a63c9f714ba896a90119560246bf49a433c Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +Date: Mon, 7 Jul 2025 23:11:17 +0200 +Subject: [PATCH] Issue 6850 - AddressSanitizer: memory leak in mdb_init + +Bug Description: +`dbmdb_componentid` can be allocated multiple times. To avoid a memory +leak, allocate it only once, and free at the cleanup. + +Fixes: https://github.com/389ds/389-ds-base/issues/6850 + +Reviewed by: @mreynolds389, @tbordaz (Tnanks!) +--- + ldap/servers/slapd/back-ldbm/db-mdb/mdb_config.c | 4 +++- + ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c | 2 +- + ldap/servers/slapd/back-ldbm/db-mdb/mdb_misc.c | 5 +++++ + 3 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_config.c b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_config.c +index 447f3c70a..54ca03b0b 100644 +--- a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_config.c ++++ b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_config.c +@@ -146,7 +146,9 @@ dbmdb_compute_limits(struct ldbminfo *li) + int mdb_init(struct ldbminfo *li, config_info *config_array) + { + dbmdb_ctx_t *conf = (dbmdb_ctx_t *)slapi_ch_calloc(1, sizeof(dbmdb_ctx_t)); +- dbmdb_componentid = generate_componentid(NULL, "db-mdb"); ++ if (dbmdb_componentid == NULL) { ++ dbmdb_componentid = generate_componentid(NULL, "db-mdb"); ++ } + + li->li_dblayer_config = conf; + strncpy(conf->home, li->li_directory, MAXPATHLEN-1); +diff --git a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c +index c4e87987f..ed17f979f 100644 +--- a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c ++++ b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c +@@ -19,7 +19,7 @@ + #include + #include + +-Slapi_ComponentId *dbmdb_componentid; ++Slapi_ComponentId *dbmdb_componentid = NULL; + + #define BULKOP_MAX_RECORDS 100 /* Max records handled by a single bulk operations */ + +diff --git a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_misc.c b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_misc.c +index 2d07db9b5..ae10ac7cf 100644 +--- a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_misc.c ++++ b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_misc.c +@@ -49,6 +49,11 @@ dbmdb_cleanup(struct ldbminfo *li) + } + slapi_ch_free((void **)&(li->li_dblayer_config)); + ++ if (dbmdb_componentid != NULL) { ++ release_componentid(dbmdb_componentid); ++ dbmdb_componentid = NULL; ++ } ++ + return 0; + } + +-- +2.49.0 + diff --git a/0008-Issue-6848-AddressSanitizer-leak-in-do_search.patch b/0008-Issue-6848-AddressSanitizer-leak-in-do_search.patch new file mode 100644 index 0000000..618c459 --- /dev/null +++ b/0008-Issue-6848-AddressSanitizer-leak-in-do_search.patch @@ -0,0 +1,58 @@ +From 510e0e9b35d94714048a06bc5067d43704f55503 Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +Date: Mon, 7 Jul 2025 22:01:09 +0200 +Subject: [PATCH] Issue 6848 - AddressSanitizer: leak in do_search + +Bug Description: +When there's a BER decoding error and the function goes to +`free_and_return`, the `attrs` variable is not being freed because it's +only freed if `!psearch || rc != 0 || err != 0`, but `err` is still 0 at +that point. + +If we reach `free_and_return` from the `ber_scanf` error path, `attrs` +was never set in the pblock with `slapi_pblock_set()`, so the +`slapi_pblock_get()` call will not retrieve the potentially partially +allocated `attrs` from the BER decoding. + +Fixes: https://github.com/389ds/389-ds-base/issues/6848 + +Reviewed by: @tbordaz, @droideck (Thanks!) +--- + ldap/servers/slapd/search.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c +index e9b2c3670..f9d03c090 100644 +--- a/ldap/servers/slapd/search.c ++++ b/ldap/servers/slapd/search.c +@@ -235,6 +235,7 @@ do_search(Slapi_PBlock *pb) + log_search_access(pb, base, scope, fstr, "decoding error"); + send_ldap_result(pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, + NULL); ++ err = 1; /* Make sure we free everything */ + goto free_and_return; + } + +@@ -420,8 +421,17 @@ free_and_return: + if (!psearch || rc != 0 || err != 0) { + slapi_ch_free_string(&fstr); + slapi_filter_free(filter, 1); +- slapi_pblock_get(pb, SLAPI_SEARCH_ATTRS, &attrs); +- charray_free(attrs); /* passing NULL is fine */ ++ ++ /* Get attrs from pblock if it was set there, otherwise use local attrs */ ++ char **pblock_attrs = NULL; ++ slapi_pblock_get(pb, SLAPI_SEARCH_ATTRS, &pblock_attrs); ++ if (pblock_attrs != NULL) { ++ charray_free(pblock_attrs); /* Free attrs from pblock */ ++ slapi_pblock_set(pb, SLAPI_SEARCH_ATTRS, NULL); ++ } else if (attrs != NULL) { ++ /* Free attrs that were allocated but never put in pblock */ ++ charray_free(attrs); ++ } + charray_free(gerattrs); /* passing NULL is fine */ + /* + * Fix for defect 526719 / 553356 : Persistent search op failed. +-- +2.49.0 + diff --git a/0009-Issue-6865-AddressSanitizer-leak-in-agmt_update_init.patch b/0009-Issue-6865-AddressSanitizer-leak-in-agmt_update_init.patch new file mode 100644 index 0000000..e2823b5 --- /dev/null +++ b/0009-Issue-6865-AddressSanitizer-leak-in-agmt_update_init.patch @@ -0,0 +1,58 @@ +From 7b3cd3147a8d3c41327768689962730d8fa28797 Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +Date: Fri, 11 Jul 2025 12:32:38 +0200 +Subject: [PATCH] Issue 6865 - AddressSanitizer: leak in + agmt_update_init_status + +Bug Description: +We allocate an array of `LDAPMod *` pointers, but never free it: + +``` +================================================================= +==2748356==ERROR: LeakSanitizer: detected memory leaks + +Direct leak of 24 byte(s) in 1 object(s) allocated from: + #0 0x7f05e8cb4a07 in __interceptor_malloc (/lib64/libasan.so.6+0xb4a07) + #1 0x7f05e85c0138 in slapi_ch_malloc (/usr/lib64/dirsrv/libslapd.so.0+0x1c0138) + #2 0x7f05e109e481 in agmt_update_init_status ldap/servers/plugins/replication/repl5_agmt.c:2583 + #3 0x7f05e10a0aa5 in agmtlist_shutdown ldap/servers/plugins/replication/repl5_agmtlist.c:789 + #4 0x7f05e10ab6bc in multisupplier_stop ldap/servers/plugins/replication/repl5_init.c:844 + #5 0x7f05e10ab6bc in multisupplier_stop ldap/servers/plugins/replication/repl5_init.c:837 + #6 0x7f05e862507d in plugin_call_func ldap/servers/slapd/plugin.c:2001 + #7 0x7f05e8625be1 in plugin_call_one ldap/servers/slapd/plugin.c:1950 + #8 0x7f05e8625be1 in plugin_dependency_closeall ldap/servers/slapd/plugin.c:1844 + #9 0x55e1a7ff9815 in slapd_daemon ldap/servers/slapd/daemon.c:1275 + #10 0x55e1a7fd36ef in main (/usr/sbin/ns-slapd+0x3e6ef) + #11 0x7f05e80295cf in __libc_start_call_main (/lib64/libc.so.6+0x295cf) + #12 0x7f05e802967f in __libc_start_main_alias_2 (/lib64/libc.so.6+0x2967f) + #13 0x55e1a7fd74a4 in _start (/usr/sbin/ns-slapd+0x424a4) + +SUMMARY: AddressSanitizer: 24 byte(s) leaked in 1 allocation(s). +``` + +Fix Description: +Ensure `mods` is freed in the cleanup code. + +Fixes: https://github.com/389ds/389-ds-base/issues/6865 +Relates: https://github.com/389ds/389-ds-base/issues/6470 + +Reviewed by: @mreynolds389 (Thanks!) +--- + ldap/servers/plugins/replication/repl5_agmt.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c +index c818c5857..0a81167b7 100644 +--- a/ldap/servers/plugins/replication/repl5_agmt.c ++++ b/ldap/servers/plugins/replication/repl5_agmt.c +@@ -2743,6 +2743,7 @@ agmt_update_init_status(Repl_Agmt *ra) + } else { + PR_Unlock(ra->lock); + } ++ slapi_ch_free((void **)&mods); + slapi_mod_done(&smod_start_time); + slapi_mod_done(&smod_end_time); + slapi_mod_done(&smod_status); +-- +2.49.0 + diff --git a/0010-Issue-6868-UI-schema-attribute-table-expansion-break.patch b/0010-Issue-6868-UI-schema-attribute-table-expansion-break.patch new file mode 100644 index 0000000..5cd424c --- /dev/null +++ b/0010-Issue-6868-UI-schema-attribute-table-expansion-break.patch @@ -0,0 +1,55 @@ +From 81af69f415ffdf48861de00ba9a60614c0a02a87 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Fri, 11 Jul 2025 13:49:25 -0400 +Subject: [PATCH] Issue 6868 - UI - schema attribute table expansion break + after moving to a new page + +Description: + +Used the wrong formula to select the expanded row for Attributes + +Relates: https://github.com/389ds/389-ds-base/issues/6868 + +Reviewed by: spichugi(Thanks!) +--- + src/cockpit/389-console/src/lib/database/databaseConfig.jsx | 1 - + src/cockpit/389-console/src/lib/schema/schemaTables.jsx | 4 ++-- + 2 files changed, 2 insertions(+), 3 deletions(-) + +diff --git a/src/cockpit/389-console/src/lib/database/databaseConfig.jsx b/src/cockpit/389-console/src/lib/database/databaseConfig.jsx +index adb8227d7..7a1ce3bc2 100644 +--- a/src/cockpit/389-console/src/lib/database/databaseConfig.jsx ++++ b/src/cockpit/389-console/src/lib/database/databaseConfig.jsx +@@ -8,7 +8,6 @@ import { + Form, + Grid, + GridItem, +- Hr, + NumberInput, + Spinner, + Switch, +diff --git a/src/cockpit/389-console/src/lib/schema/schemaTables.jsx b/src/cockpit/389-console/src/lib/schema/schemaTables.jsx +index 609d4af15..446931ac2 100644 +--- a/src/cockpit/389-console/src/lib/schema/schemaTables.jsx ++++ b/src/cockpit/389-console/src/lib/schema/schemaTables.jsx +@@ -465,7 +465,7 @@ class AttributesTable extends React.Component { + + handleCollapse(event, rowKey, isOpen) { + const { rows, perPage, page } = this.state; +- const index = (perPage * (page - 1) * 2) + rowKey; // Adjust for page set ++ const index = (perPage * (page - 1)) + rowKey; // Adjust for page set + rows[index].isOpen = isOpen; + this.setState({ + rows +@@ -525,7 +525,7 @@ class AttributesTable extends React.Component { + ]; + + render() { +- const { perPage, page, sortBy, rows, noRows, columns } = this.state; ++ const { perPage, page, sortBy, rows, columns } = this.state; + const startIdx = (perPage * page) - perPage; + const tableRows = rows.slice(startIdx, startIdx + perPage); + +-- +2.49.0 + diff --git a/0011-Issue-6859-str2filter-is-not-fully-applying-matching.patch b/0011-Issue-6859-str2filter-is-not-fully-applying-matching.patch new file mode 100644 index 0000000..8263631 --- /dev/null +++ b/0011-Issue-6859-str2filter-is-not-fully-applying-matching.patch @@ -0,0 +1,169 @@ +From e4bd0eb2a4ad612efbf7824da022dd5403c71684 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Wed, 9 Jul 2025 14:18:50 -0400 +Subject: [PATCH] Issue 6859 - str2filter is not fully applying matching rules + +Description: + +When we have an extended filter, one with a MR applied, it is ignored during +internal searches: + + "(cn:CaseExactMatch:=Value)" + +For internal searches we use str2filter() and it doesn't fully apply extended +search filter matching rules + +Also needed to update attr uniqueness plugin to apply this change for mod +operations (previously only Adds were correctly handling these attribute +filters) + +Relates: https://github.com/389ds/389-ds-base/issues/6857 +Relates: https://github.com/389ds/389-ds-base/issues/6859 + +Reviewed by: spichugi & tbordaz(Thanks!!) +--- + .../tests/suites/plugins/attruniq_test.py | 65 ++++++++++++++++++- + ldap/servers/plugins/uiduniq/uid.c | 7 ++ + ldap/servers/slapd/plugin_mr.c | 2 +- + ldap/servers/slapd/str2filter.c | 8 +++ + 4 files changed, 79 insertions(+), 3 deletions(-) + +diff --git a/dirsrvtests/tests/suites/plugins/attruniq_test.py b/dirsrvtests/tests/suites/plugins/attruniq_test.py +index aac659c29..046952df3 100644 +--- a/dirsrvtests/tests/suites/plugins/attruniq_test.py ++++ b/dirsrvtests/tests/suites/plugins/attruniq_test.py +@@ -1,5 +1,5 @@ + # --- BEGIN COPYRIGHT BLOCK --- +-# Copyright (C) 2021 Red Hat, Inc. ++# Copyright (C) 2025 Red Hat, Inc. + # All rights reserved. + # + # License: GPL (version 3 or any later version). +@@ -324,4 +324,65 @@ def test_exclude_subtrees(topology_st): + cont2.delete() + cont3.delete() + attruniq.disable() +- attruniq.delete() +\ No newline at end of file ++ attruniq.delete() ++ ++ ++def test_matchingrule_attr(topology_st): ++ """ Test list extension MR attribute. Check for "cn" using CES (versus it ++ being defined as CIS) ++ ++ :id: 5cde4342-6fa3-4225-b23d-0af918981075 ++ :setup: Standalone instance ++ :steps: ++ 1. Setup and enable attribute uniqueness plugin to use CN attribute ++ with a matching rule of CaseExactMatch. ++ 2. Add user with CN value is lowercase ++ 3. Add second user with same lowercase CN which should be rejected ++ 4. Add second user with same CN value but with mixed case ++ 5. Modify second user replacing CN value to lc which should be rejected ++ ++ :expectedresults: ++ 1. Success ++ 2. Success ++ 3. Success ++ 4. Success ++ 5. Success ++ """ ++ ++ inst = topology_st.standalone ++ ++ attruniq = AttributeUniquenessPlugin(inst, ++ dn="cn=attribute uniqueness,cn=plugins,cn=config") ++ attruniq.add_unique_attribute('cn:CaseExactMatch:') ++ attruniq.enable_all_subtrees() ++ attruniq.enable() ++ inst.restart() ++ ++ users = UserAccounts(inst, DEFAULT_SUFFIX) ++ users.create(properties={'cn': "common_name", ++ 'uid': "uid_name", ++ 'sn': "uid_name", ++ 'uidNumber': '1', ++ 'gidNumber': '11', ++ 'homeDirectory': '/home/uid_name'}) ++ ++ log.info('Add entry with the exact CN value which should be rejected') ++ with pytest.raises(ldap.CONSTRAINT_VIOLATION): ++ users.create(properties={'cn': "common_name", ++ 'uid': "uid_name2", ++ 'sn': "uid_name2", ++ 'uidNumber': '11', ++ 'gidNumber': '111', ++ 'homeDirectory': '/home/uid_name2'}) ++ ++ log.info('Add entry with the mixed case CN value which should be allowed') ++ user = users.create(properties={'cn': "Common_Name", ++ 'uid': "uid_name2", ++ 'sn': "uid_name2", ++ 'uidNumber': '11', ++ 'gidNumber': '111', ++ 'homeDirectory': '/home/uid_name2'}) ++ ++ log.info('Mod entry with exact case CN value which should be rejected') ++ with pytest.raises(ldap.CONSTRAINT_VIOLATION): ++ user.replace('cn', 'common_name') +diff --git a/ldap/servers/plugins/uiduniq/uid.c b/ldap/servers/plugins/uiduniq/uid.c +index 887e79d78..fdb1404a0 100644 +--- a/ldap/servers/plugins/uiduniq/uid.c ++++ b/ldap/servers/plugins/uiduniq/uid.c +@@ -1178,6 +1178,10 @@ preop_modify(Slapi_PBlock *pb) + for (; mods && *mods; mods++) { + mod = *mods; + for (i = 0; attrNames && attrNames[i]; i++) { ++ char *attr_match = strchr(attrNames[i], ':'); ++ if (attr_match != NULL) { ++ attr_match[0] = '\0'; ++ } + if ((slapi_attr_type_cmp(mod->mod_type, attrNames[i], 1) == 0) && /* mod contains target attr */ + (mod->mod_op & LDAP_MOD_BVALUES) && /* mod is bval encoded (not string val) */ + (mod->mod_bvalues && mod->mod_bvalues[0]) && /* mod actually contains some values */ +@@ -1186,6 +1190,9 @@ preop_modify(Slapi_PBlock *pb) + { + addMod(&checkmods, &checkmodsCapacity, &modcount, mod); + } ++ if (attr_match != NULL) { ++ attr_match[0] = ':'; ++ } + } + } + if (modcount == 0) { +diff --git a/ldap/servers/slapd/plugin_mr.c b/ldap/servers/slapd/plugin_mr.c +index 9809a4374..757355dbc 100644 +--- a/ldap/servers/slapd/plugin_mr.c ++++ b/ldap/servers/slapd/plugin_mr.c +@@ -625,7 +625,7 @@ attempt_mr_filter_create(mr_filter_t *f, struct slapdplugin *mrp, Slapi_PBlock * + int rc; + int32_t (*mrf_create)(Slapi_PBlock *) = NULL; + f->mrf_match = NULL; +- pblock_init(pb); ++ slapi_pblock_init(pb); + if (!(rc = slapi_pblock_set(pb, SLAPI_PLUGIN, mrp)) && + !(rc = slapi_pblock_get(pb, SLAPI_PLUGIN_MR_FILTER_CREATE_FN, &mrf_create)) && + mrf_create != NULL && +diff --git a/ldap/servers/slapd/str2filter.c b/ldap/servers/slapd/str2filter.c +index 9fdc500f7..5620b7439 100644 +--- a/ldap/servers/slapd/str2filter.c ++++ b/ldap/servers/slapd/str2filter.c +@@ -344,6 +344,14 @@ str2simple(char *str, int unescape_filter) + return NULL; /* error */ + } else { + f->f_choice = LDAP_FILTER_EXTENDED; ++ if (f->f_mr_oid) { ++ /* apply the MR indexers */ ++ rc = plugin_mr_filter_create(&f->f_mr); ++ if (rc) { ++ slapi_filter_free(f, 1); ++ return NULL; /* error */ ++ } ++ } + } + } else if (str_find_star(value) == NULL) { + f->f_choice = LDAP_FILTER_EQUALITY; +-- +2.49.0 + diff --git a/0012-Issue-6872-compressed-log-rotation-creates-files-wit.patch b/0012-Issue-6872-compressed-log-rotation-creates-files-wit.patch new file mode 100644 index 0000000..b4c0445 --- /dev/null +++ b/0012-Issue-6872-compressed-log-rotation-creates-files-wit.patch @@ -0,0 +1,163 @@ +From 48e7696fbebc14220b4b9a831c4a170003586152 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 15 Jul 2025 17:56:18 -0400 +Subject: [PATCH] Issue 6872 - compressed log rotation creates files with world + readable permission + +Description: + +When compressing a log file, first create the empty file using open() +so we can set the correct permissions right from the start. gzopen() +always uses permission 644 and that is not safe. So after creating it +with open(), with the correct permissions, then pass the FD to gzdopen() +and write the compressed content. + +relates: https://github.com/389ds/389-ds-base/issues/6872 + +Reviewed by: progier(Thanks!) +--- + .../logging/logging_compression_test.py | 15 ++++++++-- + ldap/servers/slapd/log.c | 28 +++++++++++++------ + ldap/servers/slapd/schema.c | 2 +- + 3 files changed, 33 insertions(+), 12 deletions(-) + +diff --git a/dirsrvtests/tests/suites/logging/logging_compression_test.py b/dirsrvtests/tests/suites/logging/logging_compression_test.py +index e30874cc0..3a987d62c 100644 +--- a/dirsrvtests/tests/suites/logging/logging_compression_test.py ++++ b/dirsrvtests/tests/suites/logging/logging_compression_test.py +@@ -1,5 +1,5 @@ + # --- BEGIN COPYRIGHT BLOCK --- +-# Copyright (C) 2022 Red Hat, Inc. ++# Copyright (C) 2025 Red Hat, Inc. + # All rights reserved. + # + # License: GPL (version 3 or any later version). +@@ -22,12 +22,21 @@ log = logging.getLogger(__name__) + + pytestmark = pytest.mark.tier1 + ++ + def log_rotated_count(log_type, log_dir, check_compressed=False): +- # Check if the log was rotated ++ """ ++ Check if the log was rotated and has the correct permissions ++ """ + log_file = f'{log_dir}/{log_type}.2*' + if check_compressed: + log_file += ".gz" +- return len(glob.glob(log_file)) ++ log_files = glob.glob(log_file) ++ for logf in log_files: ++ # Check permissions ++ st = os.stat(logf) ++ assert oct(st.st_mode) == '0o100600' # 0600 ++ ++ return len(log_files) + + + def update_and_sleep(inst, suffix, sleep=True): +diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c +index 06dae4d0b..eab837166 100644 +--- a/ldap/servers/slapd/log.c ++++ b/ldap/servers/slapd/log.c +@@ -174,17 +174,28 @@ get_syslog_loglevel(int loglevel) + } + + static int +-compress_log_file(char *log_name) ++compress_log_file(char *log_name, int32_t mode) + { + char gzip_log[BUFSIZ] = {0}; + char buf[LOG_CHUNK] = {0}; + size_t bytes_read = 0; + gzFile outfile = NULL; + FILE *source = NULL; ++ int fd = 0; + + PR_snprintf(gzip_log, sizeof(gzip_log), "%s.gz", log_name); +- if ((outfile = gzopen(gzip_log,"wb")) == NULL) { +- /* Failed to open new gzip file */ ++ ++ /* ++ * Try to open the file as we may have an incorrect path. We also need to ++ * set the permissions using open() as gzopen() creates the file with ++ * 644 permissions (world readable - bad). So we create an empty file with ++ * the correct permissions, then we pass the FD to gzdopen() to write the ++ * compressed content. ++ */ ++ if ((fd = open(gzip_log, O_WRONLY|O_CREAT|O_TRUNC, mode)) >= 0) { ++ /* FIle successfully created, now pass the FD to gzdopen() */ ++ outfile = gzdopen(fd, "ab"); ++ } else { + return -1; + } + +@@ -193,6 +204,7 @@ compress_log_file(char *log_name) + gzclose(outfile); + return -1; + } ++ + bytes_read = fread(buf, 1, LOG_CHUNK, source); + while (bytes_read > 0) { + int bytes_written = gzwrite(outfile, buf, bytes_read); +@@ -3402,7 +3414,7 @@ log__open_accesslogfile(int logfile_state, int locked) + return LOG_UNABLE_TO_OPENFILE; + } + } else if (loginfo.log_access_compress) { +- if (compress_log_file(newfile) != 0) { ++ if (compress_log_file(newfile, loginfo.log_access_mode) != 0) { + slapi_log_err(SLAPI_LOG_ERR, "log__open_auditfaillogfile", + "failed to compress rotated access log (%s)\n", + newfile); +@@ -3570,7 +3582,7 @@ log__open_securitylogfile(int logfile_state, int locked) + return LOG_UNABLE_TO_OPENFILE; + } + } else if (loginfo.log_security_compress) { +- if (compress_log_file(newfile) != 0) { ++ if (compress_log_file(newfile, loginfo.log_security_mode) != 0) { + slapi_log_err(SLAPI_LOG_ERR, "log__open_securitylogfile", + "failed to compress rotated security audit log (%s)\n", + newfile); +@@ -6288,7 +6300,7 @@ log__open_errorlogfile(int logfile_state, int locked) + return LOG_UNABLE_TO_OPENFILE; + } + } else if (loginfo.log_error_compress) { +- if (compress_log_file(newfile) != 0) { ++ if (compress_log_file(newfile, loginfo.log_error_mode) != 0) { + PR_snprintf(buffer, sizeof(buffer), "Failed to compress errors log file (%s)\n", newfile); + log__error_emergency(buffer, 1, 1); + } else { +@@ -6476,7 +6488,7 @@ log__open_auditlogfile(int logfile_state, int locked) + return LOG_UNABLE_TO_OPENFILE; + } + } else if (loginfo.log_audit_compress) { +- if (compress_log_file(newfile) != 0) { ++ if (compress_log_file(newfile, loginfo.log_audit_mode) != 0) { + slapi_log_err(SLAPI_LOG_ERR, "log__open_auditfaillogfile", + "failed to compress rotated audit log (%s)\n", + newfile); +@@ -6641,7 +6653,7 @@ log__open_auditfaillogfile(int logfile_state, int locked) + return LOG_UNABLE_TO_OPENFILE; + } + } else if (loginfo.log_auditfail_compress) { +- if (compress_log_file(newfile) != 0) { ++ if (compress_log_file(newfile, loginfo.log_auditfail_mode) != 0) { + slapi_log_err(SLAPI_LOG_ERR, "log__open_auditfaillogfile", + "failed to compress rotated auditfail log (%s)\n", + newfile); +diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c +index a8e6b1210..9ef4ee4bf 100644 +--- a/ldap/servers/slapd/schema.c ++++ b/ldap/servers/slapd/schema.c +@@ -903,7 +903,7 @@ oc_check_allowed_sv(Slapi_PBlock *pb, Slapi_Entry *e, const char *type, struct o + + if (pb) { + PR_snprintf(errtext, sizeof(errtext), +- "attribute \"%s\" not allowed\n", ++ "attribute \"%s\" not allowed", + escape_string(type, ebuf)); + slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, errtext); + } +-- +2.49.0 + diff --git a/0013-Issue-6888-Missing-access-JSON-logging-for-TLS-Clien.patch b/0013-Issue-6888-Missing-access-JSON-logging-for-TLS-Clien.patch new file mode 100644 index 0000000..0327c55 --- /dev/null +++ b/0013-Issue-6888-Missing-access-JSON-logging-for-TLS-Clien.patch @@ -0,0 +1,590 @@ +From a8fe12fcfbe0f81935972c3eddae638a281551d1 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Wed, 16 Jul 2025 20:54:48 -0400 +Subject: [PATCH] Issue 6888 - Missing access JSON logging for TLS/Client auth + +Description: + +TLS/Client auth logging was not converted to JSON (auth.c got missed) + +Relates: https://github.com/389ds/389-ds-base/issues/6888 + +Reviewed by: spichugi(Thanks!) +--- + .../logging/access_json_logging_test.py | 96 ++++++++- + ldap/servers/slapd/accesslog.c | 114 +++++++++++ + ldap/servers/slapd/auth.c | 182 +++++++++++++----- + ldap/servers/slapd/log.c | 2 + + ldap/servers/slapd/slapi-private.h | 10 + + 5 files changed, 353 insertions(+), 51 deletions(-) + +diff --git a/dirsrvtests/tests/suites/logging/access_json_logging_test.py b/dirsrvtests/tests/suites/logging/access_json_logging_test.py +index ae91dc487..f0dc861a7 100644 +--- a/dirsrvtests/tests/suites/logging/access_json_logging_test.py ++++ b/dirsrvtests/tests/suites/logging/access_json_logging_test.py +@@ -19,6 +19,8 @@ from lib389.idm.user import UserAccounts + from lib389.dirsrv_log import DirsrvAccessJSONLog + from lib389.index import VLVSearch, VLVIndex + from lib389.tasks import Tasks ++from lib389.config import CertmapLegacy ++from lib389.nss_ssl import NssSsl + from ldap.controls.vlv import VLVRequestControl + from ldap.controls.sss import SSSRequestControl + from ldap.controls import SimplePagedResultsControl +@@ -67,11 +69,11 @@ def get_log_event(inst, op, key=None, val=None, key2=None, val2=None): + if val == str(event[key]).lower() and \ + val2 == str(event[key2]).lower(): + return event +- +- elif key is not None and key in event: +- val = str(val).lower() +- if val == str(event[key]).lower(): +- return event ++ elif key is not None: ++ if key in event: ++ val = str(val).lower() ++ if val == str(event[key]).lower(): ++ return event + else: + return event + +@@ -163,6 +165,7 @@ def test_access_json_format(topo_m2, setup_test): + 14. Test PAGED SEARCH is logged correctly + 15. Test PERSISTENT SEARCH is logged correctly + 16. Test EXTENDED OP ++ 17. Test TLS_INFO is logged correctly + :expectedresults: + 1. Success + 2. Success +@@ -180,6 +183,7 @@ def test_access_json_format(topo_m2, setup_test): + 14. Success + 15. Success + 16. Success ++ 17. Success + """ + + inst = topo_m2.ms["supplier1"] +@@ -560,6 +564,88 @@ def test_access_json_format(topo_m2, setup_test): + assert event['oid_name'] == "REPL_END_NSDS50_REPLICATION_REQUEST_OID" + assert event['name'] == "replication-multisupplier-extop" + ++ # ++ # TLS INFO/TLS CLIENT INFO ++ # ++ RDN_TEST_USER = 'testuser' ++ RDN_TEST_USER_WRONG = 'testuser_wrong' ++ inst.enable_tls() ++ inst.restart() ++ ++ users = UserAccounts(inst, DEFAULT_SUFFIX) ++ user = users.create(properties={ ++ 'uid': RDN_TEST_USER, ++ 'cn': RDN_TEST_USER, ++ 'sn': RDN_TEST_USER, ++ 'uidNumber': '1000', ++ 'gidNumber': '2000', ++ 'homeDirectory': f'/home/{RDN_TEST_USER}' ++ }) ++ ++ ssca_dir = inst.get_ssca_dir() ++ ssca = NssSsl(dbpath=ssca_dir) ++ ssca.create_rsa_user(RDN_TEST_USER) ++ ssca.create_rsa_user(RDN_TEST_USER_WRONG) ++ ++ # Get the details of where the key and crt are. ++ tls_locs = ssca.get_rsa_user(RDN_TEST_USER) ++ tls_locs_wrong = ssca.get_rsa_user(RDN_TEST_USER_WRONG) ++ ++ user.enroll_certificate(tls_locs['crt_der_path']) ++ ++ # Turn on the certmap. ++ cm = CertmapLegacy(inst) ++ certmaps = cm.list() ++ certmaps['default']['DNComps'] = '' ++ certmaps['default']['FilterComps'] = ['cn'] ++ certmaps['default']['VerifyCert'] = 'off' ++ cm.set(certmaps) ++ ++ # Check that EXTERNAL is listed in supported mechns. ++ assert (inst.rootdse.supports_sasl_external()) ++ ++ # Restart to allow certmaps to be re-read: Note, we CAN NOT use post_open ++ # here, it breaks on auth. see lib389/__init__.py ++ inst.restart(post_open=False) ++ ++ # Attempt a bind with TLS external ++ inst.open(saslmethod='EXTERNAL', connOnly=True, certdir=ssca_dir, ++ userkey=tls_locs['key'], usercert=tls_locs['crt']) ++ inst.restart() ++ ++ event = get_log_event(inst, "TLS_INFO") ++ assert event is not None ++ assert 'tls_version' in event ++ assert 'keysize' in event ++ assert 'cipher' in event ++ ++ event = get_log_event(inst, "TLS_CLIENT_INFO", ++ "subject", ++ "CN=testuser,O=testing,L=389ds,ST=Queensland,C=AU") ++ assert event is not None ++ assert 'tls_version' in event ++ assert 'keysize' in event ++ assert 'issuer' in event ++ ++ event = get_log_event(inst, "TLS_CLIENT_INFO", ++ "client_dn", ++ "uid=testuser,ou=People,dc=example,dc=com") ++ assert event is not None ++ assert 'tls_version' in event ++ assert event['msg'] == "client bound" ++ ++ # Check for failed certmap error ++ with pytest.raises(ldap.INVALID_CREDENTIALS): ++ inst.open(saslmethod='EXTERNAL', connOnly=True, certdir=ssca_dir, ++ userkey=tls_locs_wrong['key'], ++ usercert=tls_locs_wrong['crt']) ++ ++ event = get_log_event(inst, "TLS_CLIENT_INFO", "err", -185) ++ assert event is not None ++ assert 'tls_version' in event ++ assert event['msg'] == "failed to map client certificate to LDAP DN" ++ assert event['err_msg'] == "Certificate couldn't be mapped to an ldap entry" ++ + + if __name__ == '__main__': + # Run isolated +diff --git a/ldap/servers/slapd/accesslog.c b/ldap/servers/slapd/accesslog.c +index 68022fe38..072ace203 100644 +--- a/ldap/servers/slapd/accesslog.c ++++ b/ldap/servers/slapd/accesslog.c +@@ -1147,3 +1147,117 @@ slapd_log_access_sort(slapd_log_pblock *logpb) + + return rc; + } ++ ++/* ++ * TLS connection ++ * ++ * int32_t log_format ++ * time_t conn_time ++ * uint64_t conn_id ++ * const char *msg ++ * const char *tls_version ++ * int32_t keysize ++ * const char *cipher ++ * int32_t err ++ * const char *err_str ++ */ ++int32_t ++slapd_log_access_tls(slapd_log_pblock *logpb) ++{ ++ int32_t rc = 0; ++ char *msg = NULL; ++ json_object *json_obj = NULL; ++ ++ if ((json_obj = build_base_obj(logpb, "TLS_INFO")) == NULL) { ++ return rc; ++ } ++ ++ if (logpb->msg) { ++ json_object_object_add(json_obj, "msg", json_obj_add_str(logpb->msg)); ++ } ++ if (logpb->tls_version) { ++ json_object_object_add(json_obj, "tls_version", json_obj_add_str(logpb->tls_version)); ++ } ++ if (logpb->cipher) { ++ json_object_object_add(json_obj, "cipher", json_obj_add_str(logpb->cipher)); ++ } ++ if (logpb->keysize) { ++ json_object_object_add(json_obj, "keysize", json_object_new_int(logpb->keysize)); ++ } ++ if (logpb->err_str) { ++ json_object_object_add(json_obj, "err", json_object_new_int(logpb->err)); ++ json_object_object_add(json_obj, "err_msg", json_obj_add_str(logpb->err_str)); ++ } ++ ++ /* Convert json object to string and log it */ ++ msg = (char *)json_object_to_json_string_ext(json_obj, logpb->log_format); ++ rc = slapd_log_access_json(msg); ++ ++ /* Done with JSON object - free it */ ++ json_object_put(json_obj); ++ ++ return rc; ++} ++ ++/* ++ * TLS client auth ++ * ++ * int32_t log_format ++ * time_t conn_time ++ * uint64_t conn_id ++ * const char* tls_version ++ * const char* keysize ++ * const char* cipher ++ * const char* msg ++ * const char* subject ++ * const char* issuer ++ * int32_t err ++ * const char* err_str ++ * const char *client_dn ++ */ ++int32_t ++slapd_log_access_tls_client_auth(slapd_log_pblock *logpb) ++{ ++ int32_t rc = 0; ++ char *msg = NULL; ++ json_object *json_obj = NULL; ++ ++ if ((json_obj = build_base_obj(logpb, "TLS_CLIENT_INFO")) == NULL) { ++ return rc; ++ } ++ ++ if (logpb->tls_version) { ++ json_object_object_add(json_obj, "tls_version", json_obj_add_str(logpb->tls_version)); ++ } ++ if (logpb->cipher) { ++ json_object_object_add(json_obj, "cipher", json_obj_add_str(logpb->cipher)); ++ } ++ if (logpb->keysize) { ++ json_object_object_add(json_obj, "keysize", json_object_new_int(logpb->keysize)); ++ } ++ if (logpb->subject) { ++ json_object_object_add(json_obj, "subject", json_obj_add_str(logpb->subject)); ++ } ++ if (logpb->issuer) { ++ json_object_object_add(json_obj, "issuer", json_obj_add_str(logpb->issuer)); ++ } ++ if (logpb->client_dn) { ++ json_object_object_add(json_obj, "client_dn", json_obj_add_str(logpb->client_dn)); ++ } ++ if (logpb->msg) { ++ json_object_object_add(json_obj, "msg", json_obj_add_str(logpb->msg)); ++ } ++ if (logpb->err_str) { ++ json_object_object_add(json_obj, "err", json_object_new_int(logpb->err)); ++ json_object_object_add(json_obj, "err_msg", json_obj_add_str(logpb->err_str)); ++ } ++ ++ /* Convert json object to string and log it */ ++ msg = (char *)json_object_to_json_string_ext(json_obj, logpb->log_format); ++ rc = slapd_log_access_json(msg); ++ ++ /* Done with JSON object - free it */ ++ json_object_put(json_obj); ++ ++ return rc; ++} +diff --git a/ldap/servers/slapd/auth.c b/ldap/servers/slapd/auth.c +index e4231bf45..48e4b7129 100644 +--- a/ldap/servers/slapd/auth.c ++++ b/ldap/servers/slapd/auth.c +@@ -1,6 +1,6 @@ + /** BEGIN COPYRIGHT BLOCK + * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. +- * Copyright (C) 2005 Red Hat, Inc. ++ * Copyright (C) 2025 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). +@@ -363,19 +363,32 @@ handle_bad_certificate(void *clientData, PRFileDesc *prfd) + char sbuf[BUFSIZ], ibuf[BUFSIZ]; + Connection *conn = (Connection *)clientData; + CERTCertificate *clientCert = slapd_ssl_peerCertificate(prfd); +- + PRErrorCode errorCode = PR_GetError(); + char *subject = subject_of(clientCert); + char *issuer = issuer_of(clientCert); +- slapi_log_access(LDAP_DEBUG_STATS, +- "conn=%" PRIu64 " " SLAPI_COMPONENT_NAME_NSPR " error %i (%s); unauthenticated client %s; issuer %s\n", +- conn->c_connid, errorCode, slapd_pr_strerror(errorCode), +- subject ? escape_string(subject, sbuf) : "NULL", +- issuer ? escape_string(issuer, ibuf) : "NULL"); ++ int32_t log_format = config_get_accesslog_log_format(); ++ slapd_log_pblock logpb = {0}; ++ ++ if (log_format != LOG_FORMAT_DEFAULT) { ++ slapd_log_pblock_init(&logpb, log_format, NULL); ++ logpb.conn_id = conn->c_connid; ++ logpb.msg = "unauthenticated client"; ++ logpb.subject = subject ? escape_string(subject, sbuf) : "NULL"; ++ logpb.issuer = issuer ? escape_string(issuer, ibuf) : "NULL"; ++ logpb.err = errorCode; ++ logpb.err_str = slapd_pr_strerror(errorCode); ++ slapd_log_access_tls_client_auth(&logpb); ++ } else { ++ slapi_log_access(LDAP_DEBUG_STATS, ++ "conn=%" PRIu64 " " SLAPI_COMPONENT_NAME_NSPR " error %i (%s); unauthenticated client %s; issuer %s\n", ++ conn->c_connid, errorCode, slapd_pr_strerror(errorCode), ++ subject ? escape_string(subject, sbuf) : "NULL", ++ issuer ? escape_string(issuer, ibuf) : "NULL"); ++ } + if (issuer) +- free(issuer); ++ slapi_ch_free_string(&issuer); + if (subject) +- free(subject); ++ slapi_ch_free_string(&subject); + if (clientCert) + CERT_DestroyCertificate(clientCert); + return -1; /* non-zero means reject this certificate */ +@@ -394,7 +407,8 @@ handle_handshake_done(PRFileDesc *prfd, void *clientData) + { + Connection *conn = (Connection *)clientData; + CERTCertificate *clientCert = slapd_ssl_peerCertificate(prfd); +- ++ int32_t log_format = config_get_accesslog_log_format(); ++ slapd_log_pblock logpb = {0}; + char *clientDN = NULL; + int keySize = 0; + char *cipher = NULL; +@@ -403,19 +417,39 @@ handle_handshake_done(PRFileDesc *prfd, void *clientData) + SSLCipherSuiteInfo cipherInfo; + char *subject = NULL; + char sslversion[64]; ++ int err = 0; + + if ((slapd_ssl_getChannelInfo(prfd, &channelInfo, sizeof(channelInfo))) != SECSuccess) { + PRErrorCode errorCode = PR_GetError(); +- slapi_log_access(LDAP_DEBUG_STATS, +- "conn=%" PRIu64 " SSL failed to obtain channel info; " SLAPI_COMPONENT_NAME_NSPR " error %i (%s)\n", +- conn->c_connid, errorCode, slapd_pr_strerror(errorCode)); ++ if (log_format != LOG_FORMAT_DEFAULT) { ++ slapd_log_pblock_init(&logpb, log_format, NULL); ++ logpb.conn_id = conn->c_connid; ++ logpb.err = errorCode; ++ logpb.err_str = slapd_pr_strerror(errorCode); ++ logpb.msg = "SSL failed to obtain channel info; " SLAPI_COMPONENT_NAME_NSPR; ++ slapd_log_access_tls(&logpb); ++ } else { ++ slapi_log_access(LDAP_DEBUG_STATS, ++ "conn=%" PRIu64 " SSL failed to obtain channel info; " SLAPI_COMPONENT_NAME_NSPR " error %i (%s)\n", ++ conn->c_connid, errorCode, slapd_pr_strerror(errorCode)); ++ } + goto done; + } ++ + if ((slapd_ssl_getCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo, sizeof(cipherInfo))) != SECSuccess) { + PRErrorCode errorCode = PR_GetError(); +- slapi_log_access(LDAP_DEBUG_STATS, +- "conn=%" PRIu64 " SSL failed to obtain cipher info; " SLAPI_COMPONENT_NAME_NSPR " error %i (%s)\n", +- conn->c_connid, errorCode, slapd_pr_strerror(errorCode)); ++ if (log_format != LOG_FORMAT_DEFAULT) { ++ slapd_log_pblock_init(&logpb, log_format, NULL); ++ logpb.conn_id = conn->c_connid; ++ logpb.err = errorCode; ++ logpb.err_str = slapd_pr_strerror(errorCode); ++ logpb.msg = "SSL failed to obtain cipher info; " SLAPI_COMPONENT_NAME_NSPR; ++ slapd_log_access_tls(&logpb); ++ } else { ++ slapi_log_access(LDAP_DEBUG_STATS, ++ "conn=%" PRIu64 " SSL failed to obtain cipher info; " SLAPI_COMPONENT_NAME_NSPR " error %i (%s)\n", ++ conn->c_connid, errorCode, slapd_pr_strerror(errorCode)); ++ } + goto done; + } + +@@ -434,47 +468,84 @@ handle_handshake_done(PRFileDesc *prfd, void *clientData) + + if (config_get_SSLclientAuth() == SLAPD_SSLCLIENTAUTH_OFF) { + (void)slapi_getSSLVersion_str(channelInfo.protocolVersion, sslversion, sizeof(sslversion)); +- slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " %s %i-bit %s\n", +- conn->c_connid, +- sslversion, keySize, cipher ? cipher : "NULL"); ++ if (log_format != LOG_FORMAT_DEFAULT) { ++ slapd_log_pblock_init(&logpb, log_format, NULL); ++ logpb.conn_id = conn->c_connid; ++ logpb.tls_version = sslversion; ++ logpb.keysize = keySize; ++ logpb.cipher = cipher ? cipher : "NULL"; ++ slapd_log_access_tls(&logpb); ++ } else { ++ slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " %s %i-bit %s\n", ++ conn->c_connid, ++ sslversion, keySize, cipher ? cipher : "NULL"); ++ } + goto done; + } + if (clientCert == NULL) { + (void)slapi_getSSLVersion_str(channelInfo.protocolVersion, sslversion, sizeof(sslversion)); +- slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " %s %i-bit %s\n", +- conn->c_connid, +- sslversion, keySize, cipher ? cipher : "NULL"); ++ if (log_format != LOG_FORMAT_DEFAULT) { ++ slapd_log_pblock_init(&logpb, log_format, NULL); ++ logpb.conn_id = conn->c_connid; ++ logpb.tls_version = sslversion; ++ logpb.keysize = keySize; ++ logpb.cipher = cipher ? cipher : "NULL"; ++ slapd_log_access_tls(&logpb); ++ } else { ++ slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " %s %i-bit %s\n", ++ conn->c_connid, ++ sslversion, keySize, cipher ? cipher : "NULL"); ++ } + } else { + subject = subject_of(clientCert); + if (!subject) { + (void)slapi_getSSLVersion_str(channelInfo.protocolVersion, + sslversion, sizeof(sslversion)); +- slapi_log_access(LDAP_DEBUG_STATS, +- "conn=%" PRIu64 " %s %i-bit %s; missing subject\n", +- conn->c_connid, +- sslversion, keySize, cipher ? cipher : "NULL"); ++ if (log_format != LOG_FORMAT_DEFAULT) { ++ slapd_log_pblock_init(&logpb, log_format, NULL); ++ logpb.conn_id = conn->c_connid; ++ logpb.msg = "missing subject"; ++ logpb.tls_version = sslversion; ++ logpb.keysize = keySize; ++ logpb.cipher = cipher ? cipher : "NULL"; ++ slapd_log_access_tls_client_auth(&logpb); ++ } else { ++ slapi_log_access(LDAP_DEBUG_STATS, ++ "conn=%" PRIu64 " %s %i-bit %s; missing subject\n", ++ conn->c_connid, ++ sslversion, keySize, cipher ? cipher : "NULL"); ++ } + goto done; +- } +- { ++ } else { + char *issuer = issuer_of(clientCert); + char sbuf[BUFSIZ], ibuf[BUFSIZ]; + (void)slapi_getSSLVersion_str(channelInfo.protocolVersion, + sslversion, sizeof(sslversion)); +- slapi_log_access(LDAP_DEBUG_STATS, +- "conn=%" PRIu64 " %s %i-bit %s; client %s; issuer %s\n", +- conn->c_connid, +- sslversion, keySize, +- cipher ? cipher : "NULL", +- escape_string(subject, sbuf), +- issuer ? escape_string(issuer, ibuf) : "NULL"); ++ if (log_format != LOG_FORMAT_DEFAULT) { ++ slapd_log_pblock_init(&logpb, log_format, NULL); ++ logpb.conn_id = conn->c_connid; ++ logpb.tls_version = sslversion; ++ logpb.keysize = keySize; ++ logpb.cipher = cipher ? cipher : "NULL"; ++ logpb.subject = escape_string(subject, sbuf); ++ logpb.issuer = issuer ? escape_string(issuer, ibuf) : "NULL"; ++ slapd_log_access_tls_client_auth(&logpb); ++ } else { ++ slapi_log_access(LDAP_DEBUG_STATS, ++ "conn=%" PRIu64 " %s %i-bit %s; client %s; issuer %s\n", ++ conn->c_connid, ++ sslversion, keySize, ++ cipher ? cipher : "NULL", ++ escape_string(subject, sbuf), ++ issuer ? escape_string(issuer, ibuf) : "NULL"); ++ } + if (issuer) +- free(issuer); ++ slapi_ch_free_string(&issuer); + } + slapi_dn_normalize(subject); + { + LDAPMessage *chain = NULL; + char *basedn = config_get_basedn(); +- int err; + + err = ldapu_cert_to_ldap_entry(clientCert, internal_ld, basedn ? basedn : "" /*baseDN*/, &chain); + if (err == LDAPU_SUCCESS && chain) { +@@ -505,18 +576,37 @@ handle_handshake_done(PRFileDesc *prfd, void *clientData) + slapi_sdn_free(&sdn); + (void)slapi_getSSLVersion_str(channelInfo.protocolVersion, + sslversion, sizeof(sslversion)); +- slapi_log_access(LDAP_DEBUG_STATS, +- "conn=%" PRIu64 " %s client bound as %s\n", +- conn->c_connid, +- sslversion, clientDN); ++ if (log_format != LOG_FORMAT_DEFAULT) { ++ slapd_log_pblock_init(&logpb, log_format, NULL); ++ logpb.conn_id = conn->c_connid; ++ logpb.msg = "client bound"; ++ logpb.tls_version = sslversion; ++ logpb.client_dn = clientDN; ++ slapd_log_access_tls_client_auth(&logpb); ++ } else { ++ slapi_log_access(LDAP_DEBUG_STATS, ++ "conn=%" PRIu64 " %s client bound as %s\n", ++ conn->c_connid, ++ sslversion, clientDN); ++ } + } else if (clientCert != NULL) { + (void)slapi_getSSLVersion_str(channelInfo.protocolVersion, + sslversion, sizeof(sslversion)); +- slapi_log_access(LDAP_DEBUG_STATS, +- "conn=%" PRIu64 " %s failed to map client " +- "certificate to LDAP DN (%s)\n", +- conn->c_connid, +- sslversion, extraErrorMsg); ++ if (log_format != LOG_FORMAT_DEFAULT) { ++ slapd_log_pblock_init(&logpb, log_format, NULL); ++ logpb.conn_id = conn->c_connid; ++ logpb.msg = "failed to map client certificate to LDAP DN"; ++ logpb.tls_version = sslversion; ++ logpb.err = err; ++ logpb.err_str = extraErrorMsg; ++ slapd_log_access_tls_client_auth(&logpb); ++ } else { ++ slapi_log_access(LDAP_DEBUG_STATS, ++ "conn=%" PRIu64 " %s failed to map client " ++ "certificate to LDAP DN (%s)\n", ++ conn->c_connid, ++ sslversion, extraErrorMsg); ++ } + } + + /* +diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c +index eab837166..06792a55a 100644 +--- a/ldap/servers/slapd/log.c ++++ b/ldap/servers/slapd/log.c +@@ -7270,6 +7270,8 @@ slapd_log_pblock_init(slapd_log_pblock *logpb, int32_t log_format, Slapi_PBlock + slapi_pblock_get(pb, SLAPI_CONNECTION, &conn); + } + ++ memset(logpb, 0, sizeof(slapd_log_pblock)); ++ + logpb->loginfo = &loginfo; + logpb->level = 256; /* default log level */ + logpb->log_format = log_format; +diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h +index 6438a81fe..da232ae2f 100644 +--- a/ldap/servers/slapd/slapi-private.h ++++ b/ldap/servers/slapd/slapi-private.h +@@ -1549,6 +1549,13 @@ typedef struct slapd_log_pblock { + PRBool using_tls; + PRBool haproxied; + const char *bind_dn; ++ /* TLS */ ++ const char *tls_version; ++ int32_t keysize; ++ const char *cipher; ++ const char *subject; ++ const char *issuer; ++ const char *client_dn; + /* Close connection */ + const char *close_error; + const char *close_reason; +@@ -1619,6 +1626,7 @@ typedef struct slapd_log_pblock { + const char *oid; + const char *msg; + const char *name; ++ const char *err_str; + LDAPControl **request_controls; + LDAPControl **response_controls; + } slapd_log_pblock; +@@ -1645,6 +1653,8 @@ int32_t slapd_log_access_entry(slapd_log_pblock *logpb); + int32_t slapd_log_access_referral(slapd_log_pblock *logpb); + int32_t slapd_log_access_extop(slapd_log_pblock *logpb); + int32_t slapd_log_access_sort(slapd_log_pblock *logpb); ++int32_t slapd_log_access_tls(slapd_log_pblock *logpb); ++int32_t slapd_log_access_tls_client_auth(slapd_log_pblock *logpb); + + #ifdef __cplusplus + } +-- +2.49.0 + diff --git a/0014-Issue-6772-dsconf-Replicas-with-the-consumer-role-al.patch b/0014-Issue-6772-dsconf-Replicas-with-the-consumer-role-al.patch new file mode 100644 index 0000000..6bfa2b6 --- /dev/null +++ b/0014-Issue-6772-dsconf-Replicas-with-the-consumer-role-al.patch @@ -0,0 +1,67 @@ +From c44c45797a0e92fcdb6f0cc08f56816c7d77ffac Mon Sep 17 00:00:00 2001 +From: Anuar Beisembayev <111912342+abeisemb@users.noreply.github.com> +Date: Wed, 23 Jul 2025 23:48:11 -0400 +Subject: [PATCH] Issue 6772 - dsconf - Replicas with the "consumer" role allow + for viewing and modification of their changelog. (#6773) + +dsconf currently allows users to set and retrieve changelogs in consumer replicas, which do not have officially supported changelogs. This can lead to undefined behavior and confusion. +This commit prints a warning message if the user tries to interact with a changelog on a consumer replica. + +Resolves: https://github.com/389ds/389-ds-base/issues/6772 + +Reviewed by: @droideck +--- + src/lib389/lib389/cli_conf/replication.py | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/src/lib389/lib389/cli_conf/replication.py b/src/lib389/lib389/cli_conf/replication.py +index 6f77f34ca..a18bf83ca 100644 +--- a/src/lib389/lib389/cli_conf/replication.py ++++ b/src/lib389/lib389/cli_conf/replication.py +@@ -686,6 +686,9 @@ def set_per_backend_cl(inst, basedn, log, args): + replace_list = [] + did_something = False + ++ if (is_replica_role_consumer(inst, suffix)): ++ log.info("Warning: Changelogs are not supported for consumer replicas. You may run into undefined behavior.") ++ + if args.encrypt: + cl.replace('nsslapd-encryptionalgorithm', 'AES') + del args.encrypt +@@ -715,6 +718,10 @@ def set_per_backend_cl(inst, basedn, log, args): + # that means there is a changelog config entry per backend (aka suffix) + def get_per_backend_cl(inst, basedn, log, args): + suffix = args.suffix ++ ++ if (is_replica_role_consumer(inst, suffix)): ++ log.info("Warning: Changelogs are not supported for consumer replicas. You may run into undefined behavior.") ++ + cl = Changelog(inst, suffix) + if args and args.json: + log.info(cl.get_all_attrs_json()) +@@ -822,6 +829,22 @@ def del_repl_manager(inst, basedn, log, args): + + log.info("Successfully deleted replication manager: " + manager_dn) + ++def is_replica_role_consumer(inst, suffix): ++ """Helper function for get_per_backend_cl and set_per_backend_cl. ++ Makes sure the instance in question is not a consumer, which is a role that ++ does not support changelogs. ++ """ ++ replicas = Replicas(inst) ++ try: ++ replica = replicas.get(suffix) ++ role = replica.get_role() ++ except ldap.NO_SUCH_OBJECT: ++ raise ValueError(f"Backend \"{suffix}\" is not enabled for replication") ++ ++ if role == ReplicaRole.CONSUMER: ++ return True ++ else: ++ return False + + # + # Agreements +-- +2.49.0 + diff --git a/0015-Issue-6893-Log-user-that-is-updated-during-password-.patch b/0015-Issue-6893-Log-user-that-is-updated-during-password-.patch new file mode 100644 index 0000000..14d3720 --- /dev/null +++ b/0015-Issue-6893-Log-user-that-is-updated-during-password-.patch @@ -0,0 +1,360 @@ +From b5134beedc719094193331ddbff0ca75316f93ff Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Mon, 21 Jul 2025 18:07:21 -0400 +Subject: [PATCH] Issue 6893 - Log user that is updated during password modify + extended operation + +Description: + +When a user's password is updated via an extended operation (password modify +plugin) we only log the bind DN and not what user was updated. While "internal +operation" logging will display the the user it should be logged by the default +logging level. + +Add access logging using "EXT_INFO" for the old logging format, and +"EXTENDED_OP_INFO" for json logging where we display the bind dn, target +dn, and message. + +Relates: https://github.com/389ds/389-ds-base/issues/6893 + +Reviewed by: spichugi & tbordaz(Thanks!!) +--- + .../logging/access_json_logging_test.py | 98 +++++++++++++++---- + ldap/servers/slapd/accesslog.c | 47 +++++++++ + ldap/servers/slapd/passwd_extop.c | 69 +++++++------ + ldap/servers/slapd/slapi-private.h | 1 + + 4 files changed, 169 insertions(+), 46 deletions(-) + +diff --git a/dirsrvtests/tests/suites/logging/access_json_logging_test.py b/dirsrvtests/tests/suites/logging/access_json_logging_test.py +index f0dc861a7..699bd8c4d 100644 +--- a/dirsrvtests/tests/suites/logging/access_json_logging_test.py ++++ b/dirsrvtests/tests/suites/logging/access_json_logging_test.py +@@ -11,7 +11,7 @@ import os + import time + import ldap + import pytest +-from lib389._constants import DEFAULT_SUFFIX, PASSWORD, LOG_ACCESS_LEVEL ++from lib389._constants import DEFAULT_SUFFIX, PASSWORD, LOG_ACCESS_LEVEL, DN_DM + from lib389.properties import TASK_WAIT + from lib389.topologies import topology_m2 as topo_m2 + from lib389.idm.group import Groups +@@ -548,22 +548,6 @@ def test_access_json_format(topo_m2, setup_test): + "2.16.840.1.113730.3.4.3", + "LDAP_CONTROL_PERSISTENTSEARCH") + +- # +- # Extended op +- # +- log.info("Test EXTENDED_OP") +- event = get_log_event(inst, "EXTENDED_OP", "oid", +- "2.16.840.1.113730.3.5.12") +- assert event is not None +- assert event['oid_name'] == "REPL_START_NSDS90_REPLICATION_REQUEST_OID" +- assert event['name'] == "replication-multisupplier-extop" +- +- event = get_log_event(inst, "EXTENDED_OP", "oid", +- "2.16.840.1.113730.3.5.5") +- assert event is not None +- assert event['oid_name'] == "REPL_END_NSDS50_REPLICATION_REQUEST_OID" +- assert event['name'] == "replication-multisupplier-extop" +- + # + # TLS INFO/TLS CLIENT INFO + # +@@ -579,7 +563,8 @@ def test_access_json_format(topo_m2, setup_test): + 'sn': RDN_TEST_USER, + 'uidNumber': '1000', + 'gidNumber': '2000', +- 'homeDirectory': f'/home/{RDN_TEST_USER}' ++ 'homeDirectory': f'/home/{RDN_TEST_USER}', ++ 'userpassword': 'password' + }) + + ssca_dir = inst.get_ssca_dir() +@@ -646,6 +631,83 @@ def test_access_json_format(topo_m2, setup_test): + assert event['msg'] == "failed to map client certificate to LDAP DN" + assert event['err_msg'] == "Certificate couldn't be mapped to an ldap entry" + ++ # ++ # Extended op ++ # ++ log.info("Test EXTENDED_OP") ++ event = get_log_event(inst, "EXTENDED_OP", "oid", ++ "2.16.840.1.113730.3.5.12") ++ assert event is not None ++ assert event['oid_name'] == "REPL_START_NSDS90_REPLICATION_REQUEST_OID" ++ assert event['name'] == "replication-multisupplier-extop" ++ ++ event = get_log_event(inst, "EXTENDED_OP", "oid", ++ "2.16.840.1.113730.3.5.5") ++ assert event is not None ++ assert event['oid_name'] == "REPL_END_NSDS50_REPLICATION_REQUEST_OID" ++ assert event['name'] == "replication-multisupplier-extop" ++ ++ # ++ # Extended op info ++ # ++ log.info("Test EXTENDED_OP_INFO") ++ OLD_PASSWD = 'password' ++ NEW_PASSWD = 'newpassword' ++ ++ assert inst.simple_bind_s(DN_DM, PASSWORD) ++ ++ assert inst.passwd_s(user.dn, OLD_PASSWD, NEW_PASSWD) ++ event = get_log_event(inst, "EXTENDED_OP_INFO", "name", ++ "passwd_modify_plugin") ++ assert event is not None ++ assert event['bind_dn'] == "cn=directory manager" ++ assert event['target_dn'] == user.dn.lower() ++ assert event['msg'] == "success" ++ ++ # Test no such object ++ BAD_DN = user.dn + ",dc=not" ++ with pytest.raises(ldap.NO_SUCH_OBJECT): ++ inst.passwd_s(BAD_DN, OLD_PASSWD, NEW_PASSWD) ++ ++ event = get_log_event(inst, "EXTENDED_OP_INFO", "target_dn", BAD_DN) ++ assert event is not None ++ assert event['bind_dn'] == "cn=directory manager" ++ assert event['target_dn'] == BAD_DN.lower() ++ assert event['msg'] == "No such entry exists." ++ ++ # Test invalid old password ++ with pytest.raises(ldap.INVALID_CREDENTIALS): ++ inst.passwd_s(user.dn, "not_the_old_pw", NEW_PASSWD) ++ event = get_log_event(inst, "EXTENDED_OP_INFO", "err", 49) ++ assert event is not None ++ assert event['bind_dn'] == "cn=directory manager" ++ assert event['target_dn'] == user.dn.lower() ++ assert event['msg'] == "Invalid oldPasswd value." ++ ++ # Test user without permissions ++ user2 = users.create(properties={ ++ 'uid': RDN_TEST_USER + "2", ++ 'cn': RDN_TEST_USER + "2", ++ 'sn': RDN_TEST_USER + "2", ++ 'uidNumber': '1001', ++ 'gidNumber': '2001', ++ 'homeDirectory': f'/home/{RDN_TEST_USER + "2"}', ++ 'userpassword': 'password' ++ }) ++ inst.simple_bind_s(user2.dn, 'password') ++ with pytest.raises(ldap.INSUFFICIENT_ACCESS): ++ inst.passwd_s(user.dn, NEW_PASSWD, OLD_PASSWD) ++ event = get_log_event(inst, "EXTENDED_OP_INFO", "err", 50) ++ assert event is not None ++ assert event['bind_dn'] == user2.dn.lower() ++ assert event['target_dn'] == user.dn.lower() ++ assert event['msg'] == "Insufficient access rights" ++ ++ ++ # Reset bind ++ inst.simple_bind_s(DN_DM, PASSWORD) ++ ++ + + if __name__ == '__main__': + # Run isolated +diff --git a/ldap/servers/slapd/accesslog.c b/ldap/servers/slapd/accesslog.c +index 072ace203..46228d4a1 100644 +--- a/ldap/servers/slapd/accesslog.c ++++ b/ldap/servers/slapd/accesslog.c +@@ -1113,6 +1113,53 @@ slapd_log_access_extop(slapd_log_pblock *logpb) + return rc; + } + ++/* ++ * Extended operation information ++ * ++ * int32_t log_format ++ * time_t conn_time ++ * uint64_t conn_id ++ * int32_t op_id ++ * const char *name ++ * const char *bind_dn ++ * const char *tartet_dn ++ * const char *msg ++ */ ++int32_t ++slapd_log_access_extop_info(slapd_log_pblock *logpb) ++{ ++ int32_t rc = 0; ++ char *msg = NULL; ++ json_object *json_obj = NULL; ++ ++ if ((json_obj = build_base_obj(logpb, "EXTENDED_OP_INFO")) == NULL) { ++ return rc; ++ } ++ ++ if (logpb->name) { ++ json_object_object_add(json_obj, "name", json_obj_add_str(logpb->name)); ++ } ++ if (logpb->target_dn) { ++ json_object_object_add(json_obj, "target_dn", json_obj_add_str(logpb->target_dn)); ++ } ++ if (logpb->bind_dn) { ++ json_object_object_add(json_obj, "bind_dn", json_obj_add_str(logpb->bind_dn)); ++ } ++ if (logpb->msg) { ++ json_object_object_add(json_obj, "msg", json_obj_add_str(logpb->msg)); ++ } ++ json_object_object_add(json_obj, "err", json_object_new_int(logpb->err)); ++ ++ /* Convert json object to string and log it */ ++ msg = (char *)json_object_to_json_string_ext(json_obj, logpb->log_format); ++ rc = slapd_log_access_json(msg); ++ ++ /* Done with JSON object - free it */ ++ json_object_put(json_obj); ++ ++ return rc; ++} ++ + /* + * Sort + * +diff --git a/ldap/servers/slapd/passwd_extop.c b/ldap/servers/slapd/passwd_extop.c +index 4bb60afd6..69bb3494c 100644 +--- a/ldap/servers/slapd/passwd_extop.c ++++ b/ldap/servers/slapd/passwd_extop.c +@@ -465,12 +465,14 @@ passwd_modify_extop(Slapi_PBlock *pb) + BerElement *response_ber = NULL; + Slapi_Entry *targetEntry = NULL; + Connection *conn = NULL; ++ Operation *pb_op = NULL; + LDAPControl **req_controls = NULL; + LDAPControl **resp_controls = NULL; + passwdPolicy *pwpolicy = NULL; + Slapi_DN *target_sdn = NULL; + Slapi_Entry *referrals = NULL; +- /* Slapi_DN sdn; */ ++ Slapi_Backend *be = NULL; ++ int32_t log_format = config_get_accesslog_log_format(); + + slapi_log_err(SLAPI_LOG_TRACE, "passwd_modify_extop", "=>\n"); + +@@ -647,7 +649,7 @@ parse_req_done: + } + dn = slapi_sdn_get_ndn(target_sdn); + if (dn == NULL || *dn == '\0') { +- /* Refuse the operation because they're bound anonymously */ ++ /* Invalid DN - refuse the operation */ + errMesg = "Invalid dn."; + rc = LDAP_INVALID_DN_SYNTAX; + goto free_and_return; +@@ -724,14 +726,19 @@ parse_req_done: + ber_free(response_ber, 1); + } + +- slapi_pblock_set(pb, SLAPI_ORIGINAL_TARGET, (void *)dn); ++ slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); ++ if (pb_op == NULL) { ++ slapi_log_err(SLAPI_LOG_ERR, "passwd_modify_extop", "pb_op is NULL\n"); ++ goto free_and_return; ++ } + ++ slapi_pblock_set(pb, SLAPI_ORIGINAL_TARGET, (void *)dn); + /* Now we have the DN, look for the entry */ + ret = passwd_modify_getEntry(dn, &targetEntry); + /* If we can't find the entry, then that's an error */ + if (ret) { + /* Couldn't find the entry, fail */ +- errMesg = "No such Entry exists."; ++ errMesg = "No such entry exists."; + rc = LDAP_NO_SUCH_OBJECT; + goto free_and_return; + } +@@ -742,30 +749,18 @@ parse_req_done: + leak any useful information to the client such as current password + wrong, etc. + */ +- Operation *pb_op = NULL; +- slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); +- if (pb_op == NULL) { +- slapi_log_err(SLAPI_LOG_ERR, "passwd_modify_extop", "pb_op is NULL\n"); +- goto free_and_return; +- } +- + operation_set_target_spec(pb_op, slapi_entry_get_sdn(targetEntry)); + slapi_pblock_set(pb, SLAPI_REQUESTOR_ISROOT, &pb_op->o_isroot); + +- /* In order to perform the access control check , we need to select a backend (even though +- * we don't actually need it otherwise). +- */ +- { +- Slapi_Backend *be = NULL; +- +- be = slapi_mapping_tree_find_backend_for_sdn(slapi_entry_get_sdn(targetEntry)); +- if (NULL == be) { +- errMesg = "Failed to find backend for target entry"; +- rc = LDAP_OPERATIONS_ERROR; +- goto free_and_return; +- } +- slapi_pblock_set(pb, SLAPI_BACKEND, be); ++ /* In order to perform the access control check, we need to select a backend (even though ++ * we don't actually need it otherwise). */ ++ be = slapi_mapping_tree_find_backend_for_sdn(slapi_entry_get_sdn(targetEntry)); ++ if (NULL == be) { ++ errMesg = "Failed to find backend for target entry"; ++ rc = LDAP_NO_SUCH_OBJECT; ++ goto free_and_return; + } ++ slapi_pblock_set(pb, SLAPI_BACKEND, be); + + /* Check if the pwpolicy control is present */ + slapi_pblock_get(pb, SLAPI_PWPOLICY, &need_pwpolicy_ctrl); +@@ -797,10 +792,7 @@ parse_req_done: + /* Check if password policy allows users to change their passwords. We need to do + * this here since the normal modify code doesn't perform this check for + * internal operations. */ +- +- Connection *pb_conn; +- slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); +- if (!pb_op->o_isroot && !pb_conn->c_needpw && !pwpolicy->pw_change) { ++ if (!pb_op->o_isroot && !conn->c_needpw && !pwpolicy->pw_change) { + if (NULL == bindSDN) { + bindSDN = slapi_sdn_new_normdn_byref(bindDN); + } +@@ -848,6 +840,27 @@ free_and_return: + slapi_log_err(SLAPI_LOG_PLUGIN, "passwd_modify_extop", + "%s\n", errMesg ? errMesg : "success"); + ++ if (dn) { ++ /* Log the target ndn (if we have a target ndn) */ ++ if (log_format != LOG_FORMAT_DEFAULT) { ++ /* JSON logging */ ++ slapd_log_pblock logpb = {0}; ++ slapd_log_pblock_init(&logpb, log_format, pb); ++ logpb.name = "passwd_modify_plugin"; ++ logpb.target_dn = dn; ++ logpb.bind_dn = bindDN; ++ logpb.msg = errMesg ? errMesg : "success"; ++ logpb.err = rc; ++ slapd_log_access_extop_info(&logpb); ++ } else { ++ slapi_log_access(LDAP_DEBUG_STATS, ++ "conn=%" PRIu64 " op=%d EXT_INFO name=\"passwd_modify_plugin\" bind_dn=\"%s\" target_dn=\"%s\" msg=\"%s\" rc=%d\n", ++ conn ? conn->c_connid : -1, pb_op ? pb_op->o_opid : -1, ++ bindDN ? bindDN : "", dn, ++ errMesg ? errMesg : "success", rc); ++ } ++ } ++ + if ((rc == LDAP_REFERRAL) && (referrals)) { + send_referrals_from_entry(pb, referrals); + } else { +diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h +index da232ae2f..e9abf8b75 100644 +--- a/ldap/servers/slapd/slapi-private.h ++++ b/ldap/servers/slapd/slapi-private.h +@@ -1652,6 +1652,7 @@ int32_t slapd_log_access_vlv(slapd_log_pblock *logpb); + int32_t slapd_log_access_entry(slapd_log_pblock *logpb); + int32_t slapd_log_access_referral(slapd_log_pblock *logpb); + int32_t slapd_log_access_extop(slapd_log_pblock *logpb); ++int32_t slapd_log_access_extop_info(slapd_log_pblock *logpb); + int32_t slapd_log_access_sort(slapd_log_pblock *logpb); + int32_t slapd_log_access_tls(slapd_log_pblock *logpb); + int32_t slapd_log_access_tls_client_auth(slapd_log_pblock *logpb); +-- +2.49.0 + diff --git a/0016-Issue-6901-Update-changelog-trimming-logging.patch b/0016-Issue-6901-Update-changelog-trimming-logging.patch new file mode 100644 index 0000000..d44fee7 --- /dev/null +++ b/0016-Issue-6901-Update-changelog-trimming-logging.patch @@ -0,0 +1,53 @@ +From 048aa39d4c4955f6d9e3b018d4b1fc057f52d130 Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +Date: Thu, 24 Jul 2025 19:09:40 +0200 +Subject: [PATCH] Issue 6901 - Update changelog trimming logging + +Description: +* Set SLAPI_LOG_ERR for message in `_cl5DispatchTrimThread` +* Set correct function name for logs in `_cl5TrimEntry`. +* Add number of scanned entries to the log. + +Fixes: https://github.com/389ds/389-ds-base/issues/6901 + +Reviewed by: @mreynolds389, @progier389 (Thanks!) +--- + ldap/servers/plugins/replication/cl5_api.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c +index 3c356abc0..1d62aa020 100644 +--- a/ldap/servers/plugins/replication/cl5_api.c ++++ b/ldap/servers/plugins/replication/cl5_api.c +@@ -2007,7 +2007,7 @@ _cl5DispatchTrimThread(Replica *replica) + (void *)replica, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD, DEFAULT_THREAD_STACKSIZE); + if (NULL == pth) { +- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, ++ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl, + "_cl5DispatchTrimThread - Failed to create trimming thread for %s" + "; NSPR error - %d\n", replica_get_name(replica), + PR_GetError()); +@@ -2788,7 +2788,7 @@ _cl5TrimEntry(dbi_val_t *key, dbi_val_t *data, void *ctx) + return DBI_RC_NOTFOUND; + } else { + slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, +- "_cl5TrimReplica - Changelog purge skipped anchor csn %s\n", ++ "_cl5TrimEntry - Changelog purge skipped anchor csn %s\n", + (char*)key->data); + return DBI_RC_SUCCESS; + } +@@ -2867,8 +2867,8 @@ _cl5TrimReplica(Replica *r) + slapi_ch_free((void**)&dblcictx.rids); + + if (dblcictx.changed.tot) { +- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, "_cl5TrimReplica - Trimmed %ld changes from the changelog\n", +- dblcictx.changed.tot); ++ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, "_cl5TrimReplica - Scanned %ld records, and trimmed %ld changes from the changelog\n", ++ dblcictx.seen.tot, dblcictx.changed.tot); + } + } + +-- +2.49.0 + diff --git a/0017-Issue-6430-implement-read-only-bdb-6431.patch b/0017-Issue-6430-implement-read-only-bdb-6431.patch new file mode 100644 index 0000000..a950aa4 --- /dev/null +++ b/0017-Issue-6430-implement-read-only-bdb-6431.patch @@ -0,0 +1,20249 @@ +From d893eaca07fd64bcb0b7939bff848acc02ed218a Mon Sep 17 00:00:00 2001 +From: progier389 +Date: Sat, 26 Jul 2025 17:24:44 +0200 +Subject: [PATCH] Issue 6430 - implement read-only bdb (#6431) + +* Issue 6430 - implement read-only bdb on F43 + +Remove bdb support from Fedora 43+ +Implement read only bdb package to support : dsctl dblib bdb2mdb +--- + .github/workflows/pytest.yml | 8 +- + Makefile.am | 72 +- + .../tests/data/bdb_instances/instances.tgz | Bin 0 -> 13258634 bytes + .../tests/suites/clu/dsctl_dblib_test.py | 4 +- + .../suites/lib389/config_compare_test.py | 4 +- + .../suites/upgrade/upgrade_bdb2mdb_test.py | 278 ++++++ + .../slapd/back-ldbm/db-bdb/bdb_bdbreader_db.h | 289 ++++++ + .../back-ldbm/db-bdb/bdb_bdbreader_glue.c | 519 +++++++++++ + .../slapd/back-ldbm/db-bdb/bdb_layer.h | 5 + + ldap/servers/slapd/back-ldbm/dbimpl.c | 5 + + ldap/servers/slapd/back-ldbm/dblayer.c | 34 +- + ldap/servers/slapd/protect_db.c | 4 + + lib/librobdb/COPYING | 8 + + lib/librobdb/COPYING.RPM | 848 ++++++++++++++++++ + lib/librobdb/README.md | 30 + + lib/librobdb/lib/bdb_ro.c | 713 +++++++++++++++ + lib/librobdb/lib/robdb.h | 51 ++ + lib/librobdb/robdb.spec | 67 ++ + lib/librobdb/tests/test.c | 175 ++++ + lib/librobdb/tests/test.db | Bin 0 -> 24576 bytes + m4/db.m4 | 42 +- + rpm.mk | 22 +- + rpm/389-ds-base.spec.in | 59 ++ + rpm/is-robdb-used | 45 + + src/lib389/lib389/cli_ctl/dblib.py | 18 +- + src/lib389/lib389/topologies.py | 1 + + 26 files changed, 3271 insertions(+), 30 deletions(-) + create mode 100644 dirsrvtests/tests/data/bdb_instances/instances.tgz + create mode 100644 dirsrvtests/tests/suites/upgrade/upgrade_bdb2mdb_test.py + create mode 100644 ldap/servers/slapd/back-ldbm/db-bdb/bdb_bdbreader_db.h + create mode 100644 ldap/servers/slapd/back-ldbm/db-bdb/bdb_bdbreader_glue.c + create mode 100644 lib/librobdb/COPYING + create mode 100644 lib/librobdb/COPYING.RPM + create mode 100644 lib/librobdb/README.md + create mode 100644 lib/librobdb/lib/bdb_ro.c + create mode 100644 lib/librobdb/lib/robdb.h + create mode 100644 lib/librobdb/robdb.spec + create mode 100644 lib/librobdb/tests/test.c + create mode 100644 lib/librobdb/tests/test.db + create mode 100755 rpm/is-robdb-used + +diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml +index d8434dfbb..0e65e05ba 100644 +--- a/.github/workflows/pytest.yml ++++ b/.github/workflows/pytest.yml +@@ -101,7 +101,13 @@ jobs: + sudo docker exec $CID sh -c "systemctl enable --now cockpit.socket" + sudo docker exec $CID sh -c "mkdir -p /workspace/assets/cores && chmod 777 /workspace{,/assets{,/cores}}" + sudo docker exec $CID sh -c "echo '/workspace/assets/cores/core.%e.%P' > /proc/sys/kernel/core_pattern" +- sudo docker exec -e WEBUI=1 -e NSSLAPD_DB_LIB=bdb -e DEBUG=pw:api -e PASSWD="${PASSWD}" $CID py.test --suppress-no-test-exit-code -m "not flaky" --junit-xml=pytest.xml --html=pytest.html --browser=firefox --browser=chromium -v dirsrvtests/tests/suites/${{ matrix.suite }} ++ if sudo docker exec $CID sh -c "test -f /usr/lib64/dirsrv/librobdb.so" ++ then ++ echo "Tests skipped because read-only Berkeley Database is installed." > pytest.html ++ echo "'Tests skipped because read-only Berkeley Database is installed.'" > pytest.xml ++ else ++ sudo docker exec -e WEBUI=1 -e NSSLAPD_DB_LIB=bdb -e DEBUG=pw:api -e PASSWD="${PASSWD}" $CID py.test --suppress-no-test-exit-code -m "not flaky" --junit-xml=pytest.xml --html=pytest.html --browser=firefox --browser=chromium -v dirsrvtests/tests/suites/${{ matrix.suite }} ++ fi + + - name: Make the results file readable by all + if: always() +diff --git a/Makefile.am b/Makefile.am +index 551b5f096..944f8d7c8 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -99,6 +99,9 @@ else + DS_DEFINES = -DBUILD_NUM=$(BUILDNUM) -DVENDOR="\"$(vendor)\"" -DBRAND="\"$(brand)\"" -DCAPBRAND="\"$(capbrand)\"" \ + -UPACKAGE_VERSION -UPACKAGE_TARNAME -UPACKAGE_STRING -UPACKAGE_BUGREPORT + endif ++if WITH_LIBBDB_RO ++DS_DEFINES += -DWITH_LIBBDB_RO=1 ++endif + DS_INCLUDES = -I$(srcdir)/ldap/include -I$(srcdir)/ldap/servers/slapd -I$(srcdir)/include -I. + + +@@ -184,11 +187,15 @@ endif + ldaplib = @ldaplib@ + ldaplib_defs = @ldaplib_defs@ + ++if WITH_LIBBDB_RO ++DB_LINK = @db_lib@ -llmdb ++else + if BUNDLE_LIBDB + DB_LINK = -llmdb + else + DB_LINK = @db_lib@ -ldb-@db_libver@ -llmdb + endif ++endif + DB_INC = @db_inc@ + DB_IMPL = libback-ldbm.la + SASL_LINK = $(SASL_LIBS) +@@ -326,6 +333,9 @@ bin_PROGRAMS = dbscan \ + # ---------------------------------------------------------------------------------------- + + server_LTLIBRARIES = libslapd.la libldaputil.la libns-dshttpd.la librewriters.la ++if WITH_LIBBDB_RO ++server_LTLIBRARIES += librobdb.la ++endif + + lib_LTLIBRARIES = libsvrcore.la + +@@ -1196,19 +1206,26 @@ libslapd_la_LDFLAGS = $(AM_LDFLAGS) $(SLAPD_LDFLAGS) + # libback-bdb + #------------------------ + DB_BDB_SRCS = \ +- ldap/servers/slapd/back-ldbm/db-bdb/bdb_config.c \ +- ldap/servers/slapd/back-ldbm/db-bdb/bdb_instance_config.c \ +- ldap/servers/slapd/back-ldbm/db-bdb/bdb_verify.c \ +- ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c \ +- ldap/servers/slapd/back-ldbm/db-bdb/bdb_misc.c \ +- ldap/servers/slapd/back-ldbm/db-bdb/bdb_perfctrs.c \ +- ldap/servers/slapd/back-ldbm/db-bdb/bdb_upgrade.c \ +- ldap/servers/slapd/back-ldbm/db-bdb/bdb_version.c \ +- ldap/servers/slapd/back-ldbm/db-bdb/bdb_monitor.c \ +- ldap/servers/slapd/back-ldbm/db-bdb/bdb_ldif2db.c \ +- ldap/servers/slapd/back-ldbm/db-bdb/bdb_import.c \ +- ldap/servers/slapd/back-ldbm/db-bdb/bdb_import_threads.c +- ++ @db_bdb_srcdir@/bdb_config.c \ ++ @db_bdb_srcdir@/bdb_instance_config.c \ ++ @db_bdb_srcdir@/bdb_verify.c \ ++ @db_bdb_srcdir@/bdb_layer.c \ ++ @db_bdb_srcdir@/bdb_misc.c \ ++ @db_bdb_srcdir@/bdb_perfctrs.c \ ++ @db_bdb_srcdir@/bdb_upgrade.c \ ++ @db_bdb_srcdir@/bdb_version.c \ ++ @db_bdb_srcdir@/bdb_monitor.c \ ++ @db_bdb_srcdir@/bdb_ldif2db.c \ ++ @db_bdb_srcdir@/bdb_import.c \ ++ @db_bdb_srcdir@/bdb_import_threads.c ++ ++ ++if WITH_LIBBDB_RO ++ # db-bdb sources are compiled within libback-ldbm.so and linked to librobdb ++ DB_BDB_SRCS += @db_bdb_srcdir@/bdb_bdbreader_glue.c ++ DB_BDB_WITHIN_BACKLDBM = $(DB_BDB_SRCS) ++ ROBDB_INC = -I$(srcdir)/lib/librobdb/lib ++else + if BUNDLE_LIBDB + # db-bdb sources are compiled within libback-bdb.so + DB_BDB_WITHIN_BACKLDBM = +@@ -1222,6 +1239,20 @@ else + # db-bdb sources are compiled within libback-ldbm.so + DB_BDB_WITHIN_BACKLDBM = $(DB_BDB_SRCS) + endif ++endif ++ ++clean-bdb-ro-src: ++ /bin/rm -f $(DB_BDB_RO_BUILT_SRCS) ++ ++build-src: $(BUILT_SOURCES) ++echo-src: ++ @echo V2 @db_bdbro_srcdir@ ++ @echo V3 @db_bdb_srcdir@ ++ @echo V1 $(patsubst %-ro/,%,$(dir $(DB_BDB_RO_BUILT_SRCS))) ++ @echo V4 $(DB_BDB_RO_BUILT_SRCS) ++ @echo V5 $(DB_BDB_WITHIN_BACKLDBM) ++ @echo V6 $(libback_ldbm_la_SOURCES) ++ + + #------------------------ + # libback-ldbm +@@ -1298,11 +1329,24 @@ libback_ldbm_la_SOURCES = ldap/servers/slapd/back-ldbm/ancestorid.c \ + $(DB_BDB_WITHIN_BACKLDBM) + + +-libback_ldbm_la_CPPFLAGS = $(AM_CPPFLAGS) $(DSPLUGIN_CPPFLAGS) $(DB_INC) ++libback_ldbm_la_CPPFLAGS = $(AM_CPPFLAGS) $(DSPLUGIN_CPPFLAGS) $(DB_INC) $(ROBDB_INC) + libback_ldbm_la_DEPENDENCIES = libslapd.la + libback_ldbm_la_LIBADD = libslapd.la $(DB_LINK) $(LDAPSDK_LINK) $(NSPR_LINK) + libback_ldbm_la_LDFLAGS = -avoid-version + ++if WITH_LIBBDB_RO ++libback_ldbm_la_LIBADD += librobdb.la ++libback_ldbm_la_DEPENDENCIES += librobdb.la ++ ++#------------------------ ++# librobdb ++#------------------------ ++librobdb_la_SOURCES = lib/librobdb/lib/bdb_ro.c ++librobdb_la_CPPFLAGS = $(AM_CPPFLAGS) $(DB_INC) ++librobdb_la_LDFLAGS = -avoid-version ++librobdb_la_LIBADD = ++endif ++ + #------------------------ + # libacctpolicy-plugin + #------------------------ +diff --git a/dirsrvtests/tests/data/bdb_instances/instances.tgz b/dirsrvtests/tests/data/bdb_instances/instances.tgz +new file mode 100644 +index 0000000000000000000000000000000000000000..70122eeb0149a919e034e94699fd183df6db1121 +GIT binary patch +literal 13258634 +zcmd41Ly#~~(`H$=ZQFL$TefZ6wr$(CZQHhOn-l$ae?1*N9Wk?e}C%|>jRN|IoB1QR9TUTe4iOo(|qm|Jbm8Q-L?TUmV +zh~7uJ;)VfViehiFv8m+7r6e$eNc+7w#SO +zNu<1oK(4NRyJ#rorT_29+*74>d~e0`N!y@jk7kt}%jAn7 +z|Fz{7`T_s_Z9aWr`2} +z)YPuDbgHghYU)&3g|5N(y^qxS{bb$oQ3Ff(UhYOkvM@w9DTt|b`gJ+=u36tD3?=RK +z$OZEemyr*9$m&Mu$GiWO^%Wq{QGlpik5?)kqVqvKZ*T-(UhVY#j@12??Rmf5J^L6f +ze^9x}lnw8_6R67twIJxS|4q^R{^;GfQiL)lx|EIUefigi9Wk&4ul-G3xcPlu?R}qi +z{k7Od;;Ojja_Rj}1}@p!;@^1efemKo;N!8+{Y!%P%9|LOI2eoK9j%4E2 +z6iC%12i2fmkOw0db8Dfa%^)? +z3e#8YovL|GmB}mRyj-_lk(=eS>`bRpNgnH`Mp<5XiRi%^#W&W8P)@H_+1={YHJlfE +zZ6rav9wzcdh+7vEMqH)K+*;&U%cXBkhu+ogTIiR{&QIrow@rH;>-HMftrhHBOXyjP +z%-L0^R+tO6`cRGC|LM_t?>P5G-mb-dwOsk8Y}Yk@y{vvnhJ^auw69#~yA*e-r*fS< +zS{>B+K3w(edA|k1(*CQgFYH4UD;4$IECZ=X-U|3~y6fM5RpXV-tC|1qyy +zJ?rPw!1eb6diJDOm1UnfdHKDDUiGB+by&Z=0@jxC)ey0mfjG!*1!)9B;e`2=`-XFg=6({Yt?yfSMAB!&Q4%!(CnR8nO% +z+GH^4V-$k}*GcMVFphM=lT=XscCbw;f}Je5i_SLAne0WLdCf|(sH`Fwg&~{leDA%M3Lz#$2eY7I0;gs-GMDYD=z0nLL~5@W}8B%AK26k@f=L3yt@qW +zk8{%|7turia*kAxF^d;7UqaJuIc%#iB4tGLnH6^zul~s8f$W>vCY!VhYWAUPv*ruI +zA@W{DN#$l?o$C9EzUEi_mjmJJF>f4y15mGv+%M4VdUq9HKr(DFZ@lm4K|nd=-_O^2 +zQshfkf*od2)YxD0s!JptODr#}c50cB9%`unA1|lrxIFe$3SMQZ+Hf6t{ +zUH{*{U5dI@KW#dTdKLZ5NjOU?t$ceJXhXFPqB?&%xB76wnv=ZU#5DV-6Dv1TRjNNg +zIAWD?DV-&01k`!SgI2gDi0#|S&L~RD@neF1zGM8L`Xl^G)m}hCSyLB9>*4z&^<5 +zb0CK=mY{P2`IcKB$@@?9doaDHeF}uT_5%R+FCj4OUJiDJnCVRdBM^+S_yhhFq}!nK +zK0wwL=q~-!R*hko#QICp|8lxY2YT!QC?eCo1b6fqERwyWhz*R)KK +z%^c_+{%`a?~-76!z%}cae|$!5Q;%;&u5WXvRyOI>T=eCFbw#BELu0 +zUqiRPCF`DR)zB$_DCLzOS{FZSrXP<=9$ymdd@*p*ad)9Hm*e{Yiy!kKR;hXM>#!pcU(7;Z;f3$ +zU+<^)-v&)j1Iuw)Z`?1BZ-YM%U%Vfd&Tf9X1cPI3cDOSIbpbCzOG}r~&}IVG3&;9u{su8#17?y|5j@>}{%1^_!)8OQwg`jbJmzdXX3WdNOL-OWdpnRFxw +zAF5a7q)R(!)>IhuZQ>a_y8(>W`fOqx7>ab0isJwW%Xet!5#0Dn>>FSR!i)AJyKM47 +zJ8p);2R;43l(iZH6B27wS3mKh9fyTe40_HZ$=xqU5B>K8HVP)Zpz5!K8DR6dxZ~HR +z_5bjOstebjaIL2~T?ovYcamP0FZPFD4=gzg;Ee(R)Tr`O)Q?dnTS=4567@V-D +z$%uk?EQMH>D@+jdVy~oXl8%~K5+Oz?wLe3CcAunAq#B0VMUHmI*_0I!1Ugr>2V=n| +zt~Tu-8BTmfmthGGQ#(i$ +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 +z^rEpNev-*piXg=H4en4`8c^mxcOYBB +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 +zeL&C((my4TqObGQ_v=kw*K50G +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 +zZ435wf`Y$)m@IBLVw+lzV^(7wcf)W#AFhr +z0cVhma+HfpSYhPEhGX+i;@;EtfJ0r%j*Qp!%zq%s( +z>%0ZZls3zgqypuuSFjxD&8kRjR)fmP_AnsPv|rahK=}a@960bL>j(N};LpUagRp^^ +z?27CE5k>5Kx1OlAc~Kxda9dV~QgXuxRuWbE6l;K5YOB-Oq+S+BVZ@OFB9KZpN`$yO +z7~~HCQcz4ehe#-_I!i@Y+M>m}YzO@eMps-A8DTFx=3$o^QNf1@-c#@N7h2Ho53XEQ +zUKkq{k+7tX<cIPVlg$x#oj8zEDt*v-FbbB{`H#1`aLiU-x58i +zyho0U7`*~K(WD{bXNS18X4!cJP^#BPmb<6k1E*!fWvY#NJ;#;Xl6q@C%C7k41_$k@ +zMle3Sr$ELftxNBUk~IHx+K3;JTkYvNFM^vGORSMlGm}Zpw~N_@*Izli_qO#0@C9c8S#~8)ADph +z7**SIMu2YAVJu>FoGyz3x5&0xS(^2|7%4`7%NjLd?;b$|+-k2MH86)b*V?UKgjrMO +z_S=%hYeUwKJ$aw=0sY?Tn1l{py=Yw+ca*n5&BBxN5kwZ~p{ +z24W~X`c8I9`M4A}cyId)HCGB9-1#L;i}RcjbwUGTshd}UvkUBBdF5Hm_e%4&GIiNd +zpcE))X#lV2|6*^LK8XGQ$lma3TrM-g7d+iu!7wmS0rp;GvCKML@AAfAeq{io-uoTV +zpDl3H2$s0i~)!Qo0eD!mAcO10zjKiNX5sd +z0TwC9HbF~diHK_w+1s%(W)>lWA$yn$I-8Eq7HprUYy4YQE|iB)O{2XSPJn5=D&UhB +zPX_lKvJ}wO=)wzSJII<5JgLlMOnb~+8YxR=F1wka#*zuzp>JGUAc?t#8qJQ% +zO$27t6`BI(1ckDR7Lu3>mJ)rqu69SgD3`K^9}@bcPYY78%<(?!WO!->RCP?JtiY}E +zqldKHo=*~woKGMLkhA3Wut0f?#%9*(2xSII2t6u*nOz@)|vS8!y1Q`YKmB6`W15Lm*LhaU*H?6bhxQuB)vAd_u +zi^}3|l0&eITHCpt7%ci;g=JCTDn0M#^@v|b=?Gm2`Qk3NF3};Ux@8>Y=cz|nBlp+9 +z@~JI2t{Tu%PsnoW)G} +zw?{NDX4hIlMVmG(w(eT`fxOT}WA?|42E^|3s;vj6Nljk2LsKLi*8w@1u!DEYyE{fC +z&v_jg{QC1|<^_(!-3zYMs{7|cadxE}3GngeB^g&Nn>Q4If6;y{gmIw&B}*bggE>L$ +zo!&+)GoOo1B{N{i2n^ncf2D~d2g%^|`B4Qc4ln>~e}V*2}wFe}a-kcfhkDkwG<$ +zf>WO|w*(USxMS<^AkAwMdgAlqqqdIo&mDT2~cLk+PrhDx$hH +zM9~g+lwoVsugt25FqYjlC7XOVtE|mwQzDx#!g@Aau3RXY!hP|LOd_c4TxKtd&S8yc +znU{VN+^*4Jz_Bw*DPAy={Y`Ts1gTp`p|V@~DIxIeJjgxDfu`*wi7S{zAchmSaRs7- +zWBa6iHGC+~<{hNrhF33CG5$M) +zv%cI&`t;0Wll6piSUDtrW>f$caF*b489419J>_Er=Y)$t?~Dbb*A3cFX=U9%yW*4IXZe?!iw_SuIzh@mKE@g1c)w +z^agoG7wfRjb#DEC*Edc>2&L2_H-gBk5%~7Ny_hnc^piS0mN$pAXg%K-&@A%w)cY!W +z#~#_3_L4bkD1aIPt{mnBaGUVt4Clq5Pl|y!BN$}K!=TR$Bb~iLs0pWQGT};r1ml=9 +zRuPWd&V&cxB5L&gAfVCkH3ozQ1_#+y4~9|AZ-GP> +zwAQ~u9k>m{ls3&=zVQCP3mi#4mhEjK{9$yOZ}!Pm%V#UJEZaN8G7^i7Q<(pFDN!8Q +zQY^#;PAgd%3Ra9+yM8>QLc?4JsWwM@e#F;m0Cnjf>CvR}wtxf`!+7=K>Q83A{RJ=!# +z@3X-X1f$IYPd(WxVYf#X-H?(|eO_PAfoKTz3>j}65Wcqm>yi;wI}ify@`UgmF*w27 +z2v?HSRG~RyYEmDU^6B51K)UV=gw2co;2$gjCRcF3AB6%+lSBcb9)1-%qmAr5f9jZR +zL)rU)i5l0q&O5NYRj#J-(dv|nm2;>s$Maeuzq|kx9HyaVMnn#cgch4h^7UL}XDl)| +zOB^zQX`{>I*$r<{Y$^qP(JXC9geteO&GbO<(c{nQ%Bl^m#S2?5gW+4n1j0)3mK=qa +ziw#lR1eS<78a52S;d7Dw70hWRehC`VG>&`~}68 +zg;RJ%4!d+ZJ@Kw-d`dewm(xeq3RcMzrgO`YC^Ps>{!4gIXx`Ms>Q~A)6P6*D6xybj +zjqhlj8AXd-C)&xxT4sB8vhKCObs%`ODuLo4CR(UPhoX@`oZhW2M9a&Qj%=#vxc=l1 +zpM)U{O)IgeWxOXO9%aV)$xG468HhPO(E@A5ixnz@YRz*Nrefhu;C*djsCPgJ45O5c +zP+umY*e@v(1t>x@k;s-UlP;}IYc`=1x@LjrpjsL*eS$C;b=!#UEEb&;-XY3P6h_q) +zSaLw`698yHIVqHno}LoEV|ZQKk+LAo#Zn`q#Q_U>T1(W<^cl%5pyzr}KU5T=D1tCK +zKqIjP8V&M9E(1>fdw=98Xi7?>-!v`Ci=7%Gpw~b{JXPJ)kJw6xb-8?NhL)Y*mT_fG +zHfVEoY_OiQDh3}8Q-eMF92UPsd_Q_HOAD*vLLBjkO?R@>G*yju?r2tAuBfXV0nq0> +zoRAl)?sJM^a4d)W@4JK;-nn~YVHDW=0>Ws5+d)U>u}ltO%rPDkcTdb?AqY?_HuUV@ +z7tKyLa9KIrLpx1H5;`c3zmy;VaB5c&HpbF)H^si7HXIU%hv|i@hph5Fa1K6UqT_&S +z&qct+aUMD#Mg2)U07M}cY|S!lZ3HJhDiP49<2Xna&-6n*EHdI{;+vF< +zns4A?<#$P=kl!Gc!%PeNl1(?tsOdzxR;z;*fXN>CsO^-mKi^IL(Ta~1p>9x}|FRkw +zdoPHqnI7sL%vst?woQ+U&s(d(>n<;6zrMB|x5g%Q=7S9T>fwSS0x*`%RGA!|_`?%UN?8((Mr>$a^j +zpr-~M8yj{b!FFmCwu^^TlVU<-7PepyG23d;7F3{H9s*X_Ot23Qk61!|O#uvEFQO^j +zXK6WKSg}ebO?x^ukm}j?Q>3v?mmq7z>uCa)^lU<;urKzn +zss=0YOGOyFg2Q|x{5uxyq`FyI$C4wpcpN +zKi9Ij#TtA_5&gl??hViYDh#8P9>-nsj1nsAA7k&49pR6=Q4PFFS)$RD{z`9`fs25N +z`Mxpu^G1}9mBTlN51T38+Z9940MNcE!5WRn3wLi^9D3!mKY+@p-4P#`33?EsUTWoE +zc^&FG>Jt<@UyJz__2T_x+7gGgY)NcQluuMgJtA5F=kOLpA@GY>Df9N_5n%N&HdUH` +zM$J`JYM?uyIwO6M1N4(Gn!-S)*@yjc&Si(DOwRZUo1xjye{$KLTN~;52F?L^LT9H3 +zi?LU2So&jm3t#XsISMXHBZ81tts)iJ1*rm`-h!EsvX{xd8Gi|?XNrUB+3JMIs-`2R +zkH{+ZrO5fw_aNlCgDh-tAQf3}c8xb8X*w#rKwsp^N3U>THy; +zTSApa6{Zx$_Nj5%f%^D`^+5P2-egJ39jez+3-As005)u@>*~~kL)&sijuaRh=3tM- +z+Nc+N)vtMuf|Y{_*quEFX7`nf%_O>)7ElemngtH)L+pd>}Pyx +zn3_o38~(27tK8UmTXp(RkDfhi*67hc=QExeRTza$BZZYz{6R?M +z^U@M+X^Xt~?5VYB@tI*F2;21(?@dd$+3wq^U>+Tv+> +z7^25!chlW0)Neeo^gn4yW`mVW83PV9C(SQbxZSosNF@_|Oy5DJ@-b^O{S|NBilt`M +zWWqBr1$5JsnX1VTThPCmR4e?sOU3vx*~egE2rzfCO}0dB0}7 +zIwI{?%`H)uAd_py-vhG`fVq2FVo!w9N`wb|V`7-fQe$vNwrzUY +za0k9vT1y(2wx>-8&FvN;9TXv7FNETXXa)Aeg2p$P3BQbRF{mZd)n$G^m8h2&QHyb)ykhGWtvG%->D3gvAY2|1`~h +zv|3xSQC|Y}XL0-3l2r4_REC%mz{)#o7S5=>!K2`Ri4Qi9NSyVLA->?A{;=8Fmg_a= +z^7UqlVUNnIjDQp9YKIaVf0fHY_*-*>IN~6xENBAJ#XAtXtMltu*J-Yy--a+ykhi^S +zQ^XOFwlF;Ode_(fWZ0w3GA(fNI)`%iRN2x4QU84Lwa(p71?uF^B`DMrdS+;o3+Udm +z-U0;hZuM{u0iPDUTOeLKn4|)bJJ4PXIC-)2A^{Ho8LIUOm^r;jYKLH7~|r*rl0?kxC6fI1dth9d#Ii;EDHyZuIg=-Z9g +z6<7)H0s_(cqvzxKDpM^eq)&z&>9mS_FJeH3dX<3TQzN%?gDI=;4hcU>e+5^?JOfA4 +z>g)2i0D-_R{7b`TjQkFyqau$UPoIDS4Plfd=Kz4nIr02e9r_eXaezN{B-z#3nx(z5 +z+KW%OZ+j1PzQQoy@GgQ(IM9FVqo*&~T6)BHFDId-wPz7S_4_L&_&agUEuP|=gB@>Q +z-{&V$Rbfp?-G}{OHw_g2{yh+Hrw6yk76@Zo=fPR$O@s&3^-g@br+aq@HM}%&1VgHnUR|~D%^X5_lv^PK5PS_{Z0mQcOq{0 +zcJP(iy18|5DMq`;z;1IQvO$3IsR?=M>|o4l^5wa!u2&#|p3LJPu= +zaym1K1j&oELk}jx937%${pZq=`?OG-C`5mpYWj0@y_0him3x17XH(Oy0;m($=%oCH +z>OC_qimiu;{;7#jM~VJ@gm73Y{II)Zo5b*11I>mnsx@;$3n99_SFanBrnul>Z+z3c +z_I$Q?t)k~2m!l|dVlwUo1o@Z2qpqdxP?ec?e@g3m;jiD4hwmb!W{Nn)oY*&68sWM0 +z%s51$g*Z0xQtjj9lHv6(A2nFSG|_Qn9nwtY&?O?jlmu@jfQWfHh5hMwi +z4AkTyJx&a~sh@4PDp)X@vSiSyzm +z^l~CqM0OMVdaI>vATo_yZV*{c|QyaIPmsPz9sgBvpC4I|B)U2H_u2d&14DM|0WqB4=Y3x +z4sz>-(@Ruf}xpQrkLseg>Hn{SG*u4E|53-^^Rzo`Hw +zm@IqT?w4U7-oobK`-Yk(q8zj3?_?j*&Cx#}{ir_6%1bpe%{@ayIK`4DmWj^fLH{tH +zu!}3m&hfugB0s*0<5IMx$B0R27#SQXvB_PDH7a>aE0M}*$(&0EPwB85#U?9=Aj&JO +z2D>v32<4?sx}tta<;kR0Dm&Sx8E;9+(BG0F8i&P3qA1P+hOCT)j!_G?1Lf9sDEBSz +zNsgcMIb-Y|+h(8ZCT|YPZtjyE{0K?#$+pml7G@S8Ytu*R2TcyoZDb-*!wKQ<-UMH- +zAhsf#?%e^$v8$^C1HSE$z3j6$C8d$nj#jqSv#TvK(yMcS|0Qd!j`WR-%@Ll6BaG}^ +zjM9MhuC0pn9=ywht*bGuqE6q@C}uyuXAi+-gS0L;!BPI@4fzoj1YthwRZvSgeFy7@S@K+*|0iZ3tuvcytl-jo%;B@%ll!Fj?QiAC>@GJFQixQs==i!@oSS0n_P|D(Fg2fjId +zKG)s}d)Dm8k5lNj9bmr~_DGhIyOPDRYaK$F(B1Q8&X@iGUnM%d=&(9ELI}a9G1ZUc +zg}S6`fI>b>qW{Lf%+SlQ9QfIPbe8rg5jr +zS^N38661roN#3!i{y`;#lZxp3`f2(PNMBss$QteQ +zgBo=m>cyg;cv0zDrxcs2jhQATleSzhJsNt^C)w0l$r^pEP#fT8&>XuhwQ8e-jH&GB^sziA2&L44VNk4>k#p|B! +z$WDtT+Kg2KDl~(2wHD>FOMI+N5vihj#iM4=XA5%m@ynfpWIr_J7-OYy8K@PV>J7sw +z@%$f*9j^b^#txXr)!`aKTdP$+pLohymskbkl$!KK@cw6ZYv1C{WHBF26;3IbtE6&m +zzWlY!W=xCR($!M$OhjV~1rJD!|1*g2?a!(JTIE%8Jo1i{NH2nVY2; +zk|C;F&gOF@H=3#-Qa2STuf0fBGuy&qjxHtLvv;-cS=Naqb5}NgOqRiTnb?S({TzwE@UBr#6t` +zQ+7lpBf6jzUEf!CN~J;r-y2KKdTk>0ZYsVKT$B(2p}X +ztkds9)mZ(5xL;Y{-eC;#$ai071~?Sk(LiD$W_g@nh>|U_KVa@QlOMh_&O1Rte+N>^>~iz +zJ|tU_b1RM&er7`Q3rv^Ev2D}7QpC&viINW5cRzL+&|ufRzPCB$0=_H?rK{k+RX;z%XLYZsdr8Q>-H2j3S#WE~!iH +z=%mG*Rf389$;a}WyXDw)(Z*q>9*iw$rXq535}(Il97+3L6+l%23hUY9rCh0^&I0#4f7y!Jg%>EVT9(U63HK4E2tWq$B5~M +zxVIu#lxTTg{wGeG~YnD}l-zMt9pTkrA4&xA@eGG7xrXl{8p +zn?BB-hkfaqhkHaqFg~*;N*hxf&+&{I{{FjGO7Htc<-rx7O1t1LvB-80T{5$`SI<~Y +z8UOTLF&pZxiD4;-_S{dUiUE=`QTCAP?>y&YjQ0uzo&C0gGFO?2)XdQ(f0R7w9QWr3 +z{F9tb2R#5PjOpp{^(m`JZFQpjuL8pkJ#|7FR* +z|I3m=4GJC)EQ~DBnk{blFD)5Uh8h8|Oz-~Fl2MlR|FdLx1dO}C$=>CpoQ%0055N>O +zO#Y`OWBwmY#)>GSWNKN(SpU_p$N$EXaZc+LR+{`k$G4>R<`*MM2IMQNY}UsjGtSms +zWKwF*d0o&RUB7KN@_$sXL2dGAip3IYrlyth@cjkxB8w3{sAs@hg>2B_-i+t@`s`TFi4Ze{N<11+ +zZR;$U5_tb|Mdt~m$TD5~(>`4Px|y|Fy(EsST&1RPs0r5t?>!THWj +zgv15U8zQZNq5sxZJW6v&wFGm|S+=7N@+Mw5WDCkuWYy2(N*E)Uy0MS6!QZ%J?dTbC +z_vXfa&ilml?d;Q#oL38PXupLL8MQO^_~x=X`N}tzgauvE5G^j14mGY(f<0nik%I3S +z3j&(GbIwjngd3amPENMq8S64#r3qPpVAO_*RO#=p_gk$SXI71zOB;FFa1vncS7^@L*)Nq%BUxW5ZAMv +zT~i_YH!CaBCnh8Bxw-suVy=)Lk*de)U#~ndqW^r0pJa{pHNaO9`#e#5AWM&YQaNuF +zXM4zQY_ds=d6qMtQ#HKa==ukaJT?`hpDB)_e()i)GBz*_=!oA&=`mmEf75)`z-xvW +zjrj$s6mEanR5}8_dux6iM$8!hA615ET)nE-@Q--oJ?vzE#Mb|sv|u3o?@0@`|Aw?M +zOZkViP)`0g(xUCxhQpUNE}iyF-F6_HV~xJkDK}w%3dMkUQS`KzOD_1`xA^N&kiODW +zb8x5jlj66g!s%{OgCOcZa*U-y=qC9@jqB=Y_A^|+{(N>K{Vt;N&@Q!D;O26#QMFu+ +zdf%W*rp(g_f23qobVNa#Xf(D>hfV7DqcF%E3jqejd80nl_8Z2ketZ+t5RY)tE+%#- +zO-3cr9X*4H=ag!Z8u5A5NH=ygzi!YUD~mJuKW1P1`)88O^0V&Zs*hLr3R!uJCS#-$ +zAmp+0cGl#%X)^L%yL8!lhon?Jc&sC};kL$AWiT!82OKrRe{p +z={T}hcplDw_E}2s#9|J8k+E7{@F}oN8oIwR_tof{Agr+>I~m*49>xOG5D-OJGj7n( +zt=iEi1P>*6q?5O_`QtfE@$+-)a4@zf$*Crqt=WyM8E1c|G`rpRPal0wqN{8PB%7Bm&8`UtSj7m-LS@R)|#rwM_+O|6{dlKkt`5`hgDGj1lCE+r +zn1GW=N)fb%rwO+H(R}`Z2RSLyW3Q&7IHZSJ%;6-@-Hxn%rTowF2cJLjcPHEwBEhv1 +zqfH0i>vVV{DH@RMUhAsTuzcWsmmc~KkmdJCFi0+$**( +zQ??ccau|@&ELgD$)QlKj62E1iymtW_qM +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 +z?+|YzmT)nBw6<)<9k=$*JZQQ`H1sAK7uf +zMH@XHM|5U(?l0jlyi-|bN(=|wpX0VvmpdmiGFTUtBE;XDD|MO#jKfID +zXC~dOI5dF}0|g&8$}=41;C^}Pt2kf0gr5-X1YJ)bw>kZONH6N^!H0oD$UYMVBRCt4-7>( +zgo+(PQ6`}glTe;as3W)5gszb7>%>*aBE(|r@5ZVr|q&WTPIPpU8`FW`_9k%9BUMtg}aHixTRv% +zr1-p7+xq$(T@iaGNnW@e|E#_AIieu;pk2Ij2iEJn88yB1Sv-bJ-n3YR`Svj3>qo!} +zXuoYg9b(iv{#UoUYx|w;ww*r5Y{VXW(wA2AKWn4gZ8g3vD^><{$tja^Ys{=X~HCM|4*J1XGdjcoB3hfSwP$I +zuRRaI4Fi-&E8oLroIykwY#AKG^4_h4)NA|zCmm}4ZG8ECu+vX3TKmzSQJl9icj(uU`>w|Axj +zi5b{MLCx+XKTc;V?6TFKVBqtj)EL12b_g&~*$}WWk?8Y3QB%7D+zoBz^B-KN*j^G@ +z2E0LIrXOJc^$|f(3UosM^WgiasA>Wo4vU2_BzlUSH0dj(WEP_zR)om=`{)66hn7g+ +zSH1#t&nz@NEGg-L#MEpeMn=?wcvGdvE1KCQ +z!J-l%&uXWOWHaUZ+-|}>Txz7gzC5Nvh{6#{O6Rv{`d8v$?7l)S~@)PoHaqSHf0o67SmMp_5j +zD_sM1&Q74S;!@!wDE$sG{nnG`HhsFnptZ5Sq^?4^<7Z{7or0X#SCwC-fr_ThWum~CKn40wGR@7OGL@`Ri({;rJPZOofOaIMl}v8B_=Tw)KD +z@ba!Vb~aV;(AsNs(s0)>xBsfOm9%@fn1iDcqc@&*>%MORVX3_=XJpFF7ilZ$uCY@v +z`dQK#aJ{~wQPq^jc{}B(J2$Vtk(#?O`^!jCMbjAIZE2*q6yXOwdd-JGd9R=aFQSnU +zCl01bBHV<(<27rQlfHb(DvT}t`Bi=b&K@p}P +zfp?E05fG@^@0rbcqDuoISADHzT3D{TI|APX@thLt*gW)fi#~DAo +z$`vN9;&1O4?j&{BkSr8)vl;{&eUuA-98O)PWvbO!Ys$^d$1cYIX*`~YealO80u1WM +zR8UZ}IahnT-dQbH->3CmO%~pu-G@m##YC$}+P* +za5$slf@_o65_jL6vklTL;lnhE4$odlvf=M;BPU^LVKFVJRDp9`-I$bg0zQi=O|J~Z +znLA2{j|*&{lLMWWO|w+e)zst}0#s6jfE}FE4|q9-000-TpfbSc$2AzsbimWCIihSS +zJvFs*=)3o$O;S3^iW#N^RvYvJaY!O!#cDG0?jG7g06HyX%1d{ +zKEEA7mB}5UWcLuL22;%i$$%3=?;RNW8w};+gV}^8!{pyQzDyql3PZ2_p)9nc<8+J@ +z?+B7`TCr&iXEuRVTmph*Qks8%ib#nFQq5=b5KX*f4gMPJiU +zCs{>RugxpK+*?9S(pkfPOy4v>#&h~~^WNOvpCFTZj(uL{G4|=LHum)XaP#u`)Cy3{ +z!N0+4u%46J@R`th%t|+R=F`cAU4mp>Q@PId>XG>bPg)f+L}xNqBATC{eL|v;0ElUt +zQ4`yY-xNot-ohi*QTStyef+GFon4ENCO7UU0UyBzkl<9_GQxScl}F4%N$tle<&W6P +z@ubGAr^Z-K(~2}{z%L+WR;uw!b#XM+Fuj3qRmL)5i>$Ld=7Qx7*eAcU-My_#hgFIh +zT6JW8*f#xKnEK@+nuv8$Jn22 +zw)F)qu$MY&$Sw5|O{Aqg9ovI%R6}e8TkZ$}Zy#PuTJL{E~=U>j(q4szH%i^p%DSz +z_}q2(4mJ!4t9~?htv%dKFFcnHfN;lELMn=;A8xcxhU!gA(uZvX-K#mfUo=o!hI2tc +zPED~&*Y@j!x<%W-^mLo7qHuLBDLW2GE;G%N9d75GyZ6c{pAD6}`v`Yc#U$<2vS*WD +zQ)W-;B0#X%esb5pjcIwURZ;~1__{fGKJxU0wfn_gLwCvMV-UpDUmcbZ246EniE>r{cdauH|K2DyirewmBiUF`+T=rIHL$ +z5_qoNZnG?|Wi$CCXs$+CTDSCY!*iVab8GHiow78r{rUj#v!|*0dOpHtu-ZDtezAV^ +z?l+qeH<*WU7NbrNNbHt1vQ*PBX`{a-0RC>l5vZVI2co`Ya;;92i#8E?kKK-&+ocaK +z3hF6mY&CBRB=;3NJfyPbsG^bqc2^w`Zr(*2+ +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 +zna5B;yL|F#p|`Ff{`rtlg0j~1{ep7Cx +z(}jqYC8uOW{tm@K2kHQ!yyf*VRC&K2b#&q^qR_Iuo^R|qv&pYs?@&(FQ{x@;lbWfq +zGL1mrTy5>IB4)!57i{5d#{JS{7S^c<|6@x6uHxL}9IquJyI{McSdy$Q)yb}rJ|fM} +zK2T~!{Tx$pHp}q-IQ;ihg-5DzZlq}w$X&%jXHvPM1(S`Os`y>joUQ-$$c@!6Ry0WS=QQ^NFpC%F&jtLZ$37TtBdk2P@=ATs? +zVByu=S`sKoxRKy^?seuBpI08cy-LC>MP~Qn7dg9v0 +zGA9M<*{rv}Rc!(^#c%(nf-9q~M>c1Z$A06cUl7Oh^U;mmOJ9q>PCxJKTx-nS;Qm{# +zHYuP?%i{SV2XdvuF~ML#pMOW`rtE#YHl44P(jMA~4;u@${oxNoK5GvOFQ**z9PuBM +znPv518Uqg&hdEO?%0D6lW1VUr*R3q__Gq;?<$UEF5GB^<&Un(S{bBTDR{9cQiEH@6 +zISl8q{+jiqa~RQ}z3_B#?~gmr1-fkI6nooRw76C}=woH`+-D;_(WZ(5?2{AFjo6X0 +zvQeIVmxTrt)pVYJzWTST^DY#R&x+<{1O$m|zVIvOH~A$lF)H-EP~N)Hla)ymlkzvDv*#-tF4dWC--jh`ZV<<`>lxg9UHj~-EaI97vmIP$|u7QOwTVmeL6t_xPX67L{qvr>l+iZ4FHA^>(SJ_BC +z@vK(ORKuTI6R|H^-Q|B~L6_d|n7Rv>Dpwgsw60aWSsH^2KccN1v7}+8D4j9U6^h_D +z$An#D`B7uHOB=kCp`|?RTLOGOZhF2g+Qz|^Y9B?%WGs#qddl|{*C0W%lOXgsHahLY +zsQL4L&<6VP5NLY0=#Y){9G(R|bq{VN-PbZmbW$4INEtfRR9?a3L%*SUxYpLeIhH15 +z@j7zSe=8{(Ii6b{B1hPaAGe`ol6g+pY&X(r?9JhN=}`a4D1o646`J`Ms(3{29*cwa +z9Y}qbd +zgUH->k`eO=LYWrzpHnioOI`Fk*rhz|AOZ8sH6|&|>Ox^pPi#}k;(jA&L`H4%wj!|{ +zIJC#77^G1lpEdHpRla4L^nC_pm`_Ds8Fnh|+<KvW>Q+#3@x?xO86jSF*NY`mXO9%^AC9>md_r`>f;R3D4$xmqnVUe +zdpsna1SKD0#H2zfA&R%}*0#h<-S^!qe2{1@oP2xGDB{o6o*j<)1|=@$yGHA#Zob{r +zol|&x^=G{n@XFsNSNGnfpE)JhXI +zv$VsRToqD0Qku+)FdNAmr;F-c^4p08 +zH`Ez`b>H^-LcObCAgOk;xy)OgP4qoy(5n0Q?J4AAf?KE!TH{niGRt$FTaC?Gf80W` +zX9s_4gTL(-$AmZ0Hb*nXHFowM{*SlQfA1r9uQTZkHa$|VcwlG#m*yyM+fr8 +zRd}THO^$BBfj8!eh|C42+jKIi&L8bioo{Rv;gV-)TuiATSDF=D^oO}(@s}1{PzBt{5Ta`yT1AdG=q4{8x|AWRn +zgR|8yl}Ep@ru5HGH^hz^`_yws_M4Npx9m9Gb`l+0f{x=}<2oc*tbaVp-@CDy@YJF8 +zG5R8khK!C-o#1}ioI2SUL$+1O<&)nN%t&U>V2-NOp_yqvcQDENF}Sw#oP+(6M*$N0 +zU+a$+Ws!sK?@Mzkp88e3VbqrP{d38qy&|%Hk-wEiNKR7?HmpI>XwU-P+;rh+Ts&u^ +zwdcxnP)D)kcfTWyG|r*(){XVp8A)|n9WAg$@@PjoAEs&wHW_@6j~dfRbk1%3#sh7+ +zpH(3}e$pLDS$oK6Z>gbcAY03=m~Emlad)GsS%fq~(vrGEQh(NbTPpABq&VjS&8}9` +z*PXhsWs>;>9?XwVFK?~3>eoB!oa5|lO$iJC6M;CLlCDepV_%}!w* +zR%U0}Ccj!CN878@2X_>+gM_9v4{IY(M}4XdX}i0&sFGY4j@Y>GX_G`!cbh3kOr%$B +zWt+($Pk`M!{W&w{wLWw-B7EN~wr? +z#%GO6(&wJa*D~RcvF#Q5R3n$?*LwdUqP0aQ(tmRI-fjAbRJ+gQkS(wC_JNMen%SP# +zM}^sJfp*Mk?(@P_Hg{K9G0#ug#yf%$-x-zrXqv_l%D7 +ztpta+wwUMKAbn5w@6cSWwKlgi$tx|IgY*Bahy7~A3|MeXe=O`&z0r+|zXXdv%iHe9 +zO|EBnOdWM0*u-%0udlP-e>JqQ{S@X%PYAO4uA8~MzE(){8xOXpYS+`lTczF}P; +zHP;mf1@vBjJRfz>TRk9{xY)|AFlg{=o2Ym!EPl5SbCZv4^z1ch^WELD4$jAbFBGW56z{3aEbwY5=u6S3|$QBLn&TD?&vO!MI=|6u2_r$>51oLRmk +zyN>P%kKdcBU##U`;oaTjb1i!I8a-u0U+BpOOPgk6-Gg|$r(6A~cOqO2O_UCSiTu4i +z(Kd|_Iyda?w40w;u|<$nIQnO=BFKJKsH>NnEyW?-x!VZt8k|6&hdh?BD +zswXRb>jvP=$0I>W8(gCNj^5GZ?tsMy9|}UXR0W|y% +zL$0&8=GJ%5Dtu%UD;x!7PQ%k|f8P6pJqs~|mPqn#*PvOO-n-WOM$8azJln%xnfFn* +zHm>-ZSofEK_mMq{H{6p^_Z%#*oj9rf;$yv!;A_K~hEegcx_fg&N^b{$*6(9%KDM&= +zZb02ahQs*5o@krq?!_gY``rIXy_2k?O|mHgzlk5aa7NhI9W#54*>*RjgO0hbHyj1K +zSG@RX+`@%0ZI!igY;UgoDx7%&De7CD8%D0&%E4L-DN)~=a_pIpM>^}6u7o!7+_Z3J +z6VLLZmxeB+S9IHT%E^TwJW@aBZqrP{f8V`M{pmiCORV`~CU$+UJX?<&c;^D=uMoF| +z+RLAH1Vy|qvAGaW{wuck?q~;Q3~h5KlWZ`5`PznaZSKegN3AiU-ag-e6H@#5vi^PT +zGjTKfNYYV52OaLf&f?eNGBhgcb`JjArXASvq$>amA9-p=mb +zoA|w3IFUB5qZ(Y?Gjj?|EY%y4HH}b|`Rr>r)25)Q`uSSO8}y-s;A7^sRMWG6X;P|& +z=RzUR18~(ljfWYg%G-y3FWPQwWw36xkKl37)W}vSHh%BoamDLc*p;F*N6Px5PT4FP +ztvR;0Ct5L@GA6R}AEJ6j6R8~61Veje&hP26b-{y_am5xN+NFjIJ1UY9r2!x5?VjuS6k@ +zR>+F7s@tv;d^pLdT*f8&&wT4wuXphUPPy@P@j{oAf3^)ub{)ny=523kE7}y2l~8%C +zCnRFway&ZgWK5fc^LjDIk8`lBOOLKi>{S|>)T@Rb2GcE1+W$Vvr}PD!-`iLS^*y1> +z*pir1%+%W%;d*qo+T!Rr>xQ}4Ln}!!;&(5D=I_=cpUgjc79*}4fHhf{T@YXIJz({I +z$^q+utMjXms(ZAKB`lLBUNrEf1@4zd0DXt +z`*ZJ0<-9=ZIE07jGzEjle^UgY*7aOP@MsuMF03Q(6GgX85|K$eKiuUF0002|7g&fm +zqxG~PqdtPoT$Q8p3H4K1zs!|2-tR{B^@jQWktt{{D_DQMH;kJTdmc)cf9t^Cdt^vs +z*rmJ1&A*29N2Y9=G**f!iOdp6HcBJ!WO-aZ>2tGWEUlX~7L=i1&ACgFe~JutxL2L9 +zFJGbE8`hoC8&=q^ANl89E!iDPwZU=L-L3wad)qRDek>~(@K*N5mPGnf&~ccgS8Gy_ +zK~s-I)9kG?h_m*F>?#C04paWBqa+3UrCB|3|#wNiYOQvTzHISv!=^o9r+@`)V=oSs%}Ro +zn!5ug4s-X_;F}*6+eE+kxOC?>m<;+hthN>!35wQ5H1%~ktTPtt^pT-^Vw<4g +zz?i`u3eT;NJg}WZEQv%RF>zLhhJxPTQ@ZR?yxlHG6$YpxN+P!?M~#C1D5cwUISj5V +zbe`pJSf_F~WOw2s8e=HT{Hh%lj=e>xu9%Qv +zvSzwTU5T7z32XO&!qbVCUqNdyD(4F)yBs*_ljy<;W<;}03obg48Wjf*U~+2niGn07 +z4c16%*Gz$n!kr`I;1`)3Ouj-hPhXg|Gca9WOgH^rcspzqlpnJow;D6J<1BhS +z!Axupzk6O3UKtf<)l^Ey-NPnDK4|i$V^0)JI??_JK?d{sCDK*uK+Zp#U^=v7yL=nA +zyr11jX)UEQ7URzI(y=z=<}vS5OvjCaD&28J^=kVXw_p|50)(kfv}d0pgZ(FDa`oyB +zRM^k*owso|8+r`Rvxj>7B~sHdqI14J=bl1_>QidDiVl=WHc~oE>9`bZl;hAunnGrD +z2UoNK$upoe+L6dD@z#mG~=ka+CNI^ +zk4ntfJC=;q?ClLJZbwiK;&Jq0Bf&4V$^zHP7*EpJ&zYu!yTufQaT6UO*%(1^$2GZ3 +zM%dG;M7?2;+8tDxIx6fSoOQHTiGAfqcN{W3^{jyJt?WX!h=d93p*>Z6;SbYM+dUe* +z{A*@^^{*MT3R%D;Q>yJJWSILi$*)%D!@F}|ddpc`o9OE1m*$R3Ou;5aW;8YPp~t7A +z5qKO@x=|WXtJE`8_mzDmzJtN#Hi9HB$A~?IWtGw$)m^UtPH$MRs5fjtb9hb~%N|lD +zy5k&@BuSB&0@v<8TFU9x-#5|WbqzL6rS$GRq6ulN)RE-dxYI;{-Q7foN;XCmx#JXF +z4&9_Nymoo6OZgyfM-v??-DnoT3#`5Qm8o8_-CQB>%tlnrp!NVpx-OwNHZqW2kkXR4yceSGv&C)%2oQE>yFOpeA_;mEo|`&s^}J5csrO6WC8wc&(p +z0HWwIl2Dvw{x>IZ>q(Iru~BgY{!5KNzBpAKzK&#r7SRn#_32urh8>iYB&$6-i^!lG +z4Bn-T{D=&ePslL!0Zrn(PPZTBmF+}S$t(F|O0`1W_7!1-9?oLh=NFt8?K(BJF(Tg` +z2mL`2R@B33^R8`Om^5$^^*Ts4Mx?sqn8(!dc4);KiMt)jh9=G5z*(Pu==-Kvr`dfO +z^!@%xZV|H^BP!i-AZjxUP +z4M>SPeX#-VJZdDk8Lm*=DoKAeAU5hF(|5}4Z*D+h@+s9?eG=)>u|lN1LV=%PW_hvB +zxrn;_X$|iF9~!?zy3vJ^}VZ{LqVGFj-rI-HvF2(l&r8@ns +zL>fL;D7079IjZw~ch%6O$B>aAKU`4<@8@inGi}r>ay1by`h^!6Ctp>oWE(1GJ};t6 +zTd+oA$}NKyc_pPfy-ybI#0B}J~c +zqBYdLD5XP_u}P7EPzn^$5iqHfu5%5&*k_x47}wT2~xuqiiDZu +zSH*Lr38tof4BWe6!1OO8fx)C~vGZ$1ot@>wyrOb97+<+csV0{5h5G8AG0H7RKzGPn +zjyTb-#?>__p1I?Q>WMJs&}JTarm@AKBob~c-YDG{u827*J2sSWV<4AQl-Ds`L|wLH +zMgpHnnVhEX^5TaROyjr0wvYw63o@8oF6E}@<2;gNmFn)F7gUV2XBAJ%O&MiBOXm;IN!!>%9-be%f8!g3dY_U--`Yes +zi;R<7)GC$dWMjHTbc~lObskf{qlwO$+9(x=)9VZeM8Y#Z%AM-GmjvFSw7^-$ZzWPh +zmxJ(_LXz()zuJzFx?3pg`rs_%en~{ihNkq3Cs#J+wZ?4k4U>~X7Ha$8EdNPamR}{u +zNYvj|GIlhBh^^I8vELa9zN}T^EBb{gkqKPVSX2gmCdfir*92$rCuCL!J;<+$?_WO2 +z#BMt$$V%aIb5pdPXAW0t9Oin=0w!su`%Z5d^Q?bnaCv+!Y-CQl7a45UFNw&UalG^-TA3`dK2jy; +zhAhbQDAkAxJ{ckNtqEXgmm_>yWKg3fIwLAhj;d8&vWKoH8B5dArkFsdXiL4=Y(kc0 +zFd6Et+I3IiI;u(A-9)dYH7E+)ajWx*zx0N^99wMj +zZ7HRvs(0?er4!8A1zfX8h+z+5n@Z{D)PMWXX_oI-gsgArH9wUxu~QH+DT5oR_w$l+ +z1S5HDlcC4=Z{Vz~3E9B+iftkjtrl$E&$G$<4cUK~BZFhsMTlSSrJtHomQs6#>)%2- +zO6BEHKNTw|foqNj4-kR>brG1u5s@d$=yIOivUXJYI=df=phr;W-cI&Mv$g9IiGj*{ +zja%kApciFLM(mo?z0wNhhVB@lPiL8op+s|kL@FrkbhloDSrK|4ZX_mJVf7Yu@vpkK +z!PRBimL}^&y^4#G9p$QUT|KDB&(THCI6J!Y_mOUG*~Z>Q>Ht`dsc4eXhU1ty7 +z7D8-OPNY$S`N}th!)Qmh@#d=T#}G&eElf2PU3$zg4}UM>GP_EDhcvXKKYF~`?$yBT +z^>;-OcxVx1ST{4`H~SF2-H&#<+IJ$Y1e7cvn +zMB(BSYqFBzumdL_;o}d}Y$zHIx_zdpmcOtcpv?xeS(fE9+tlZ(}@lAKxs7m2S?pEce}w +zx3h}#7KEU5I>lDLEPXy`qiO6O}5XiU4mm6L>!n!z^ +zWXoUJKcEfw*azvlsP>?|whaZ=ghh@w&)O_r^FU;92;Z&&Q3QcZFA(Bx72-?etCvm` +zaxjE{TgX^C5&ESg?9ybx(utf5DEI($vgP!_#sT!j1>P>fd2fk$mgu^Lc5&#h&AZh-zGOfnK^5KmdJoD=Y}i8}v=_?^Mm~?S<=4;pP-t76 +zCRAbpyDWLr|bQLkFOaL%jrs{;;{8#eOW!X0Qz9)n>Ibn15T>__VGs=BlMh +z68fAf`d0>8kj69mj~_*e(=HA|o1p|a-8<<_5`Ka;zXKQX!fZx(I36|Q;2HbI_^O`& +z=aZRUlTVZLj=sf346R<-pmN*C)=~*i1@vER82ABu{}Dd=c|P9D+J33pE)Lm_H>b@i +zRBjbyS?XhaK;&Jndg1H_rm}qoMPDpMdfhPry0=DmG17KzQ#}L;?)Rlgzi1&reCdUY +zS&*jTpj$Mj`ymTN!@UHOrX%d=@I1sv(?M6HxMleZ+nk~AlFhO-nX(^mzHN=m3yvIb +zP9r+Pnz!)gA*++&u+N~6@bPxETknb>HqiW~lZ+Zr@Dow@EKRmD^ozFSS|-gy#=k;y +zt#Nrfs3z^kWIOk=!X~I3V!NXknSWP{qA`6td5I_P#Mt`3*Q~E*#37(T9F*69&tr&wBhAn4@m|wL +zEfw`{Eq*}7+a++&&5-O|`a<8nv(R(FZ2wSdXG0QUvu>w!=fCGp-q%r~MF}uhMYb}q +zXeBfMm5rW7>xl5wjXjU>(VN72BhymdD-?C4df!->o^ +z!K9Fxhfrsw&g7ijG$UixknTn~_0nL$94=z$a=K+X#z@_%^%S2f6`3)Uj39Kk!K8|l +zb32_mDLnPe-EJ`&Iwsac{{uM=x<4SZd5JpNEQYDJ|Kr6zvFfEGEKTFrrLlfTL$xM%6alddA*C{#l|Oawh@_L%aK+z +zw(-NE{994ub~H}xu`tAf>`@7E=2@fCHr^f9Yd&u0n!7>xD^CpbsE}F2JlRkvn4Y5} +zDjM_g6Zc`d+AXvvINRIuAxF3I+pU=Qw$nkFkwJxeg+@-Eg^l|aLF8h&DSWFa5r)m! +zyakE5#v!*vTg*m!VQ>rFwN@SvEz9dO|D(6j5$jVG^L>BTrAC}3ZrbNGI4y|0ph|=d +zji9Xbj%C@aE8zhzmbYMcM4g0(#Db^;R35CVvtTjdbG36VhYTMr)nV?5AYJVr3)EHB +zXmG0#ACPfmv3Pu~lHjn<^cOn{^cx4=F^i=#?8XsUmgU7u9c6xSs)x}2?NXwb+fY$n +zo_dQbKb`fi2x1lbp*Bf#?7;`!&5Q#}Ot*bmRBHydfE9^zlUYMY*w +z*V{AVRq}dl^>i+6b*KR7xHu(($j`Q7c>sc}viW^3!TXvZ* +z4Kf_=S5%%e7N@F!p2xNh6Lt0XIlZZV%M6XL3hY<$5+{nW+n+!Nnoh%x4pHqg%v=@O +zqV0XE!~_IPdEf#EC&OX0H0hTpuP=s7vFONgyZ1!oudrsTnRy6vI|U!0v_g3u9&)#` +zMtMm&9}Y6!M!`R;JG5A!(Ls^p%>|UArE#I&|ClHbFFxaDYK`(5gMV0dpCmXeoOV$6 +zHJ2oROrc+|40BtM!=iMhi2>%8SlSw52rD*iv�FM>@ZLjO++IYC;|-YK{wkL$yel +zAAXFr=~etW3T=b4KoxUYG+i?oTZPp^ZPP~imWbye&aZk2fu39@;jz7LpV9<1{PMnY +zLR^{rF(e^Ffn!V8z26$;)w}P*Gb>t1 +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 +zljm|(t_W$exK7EuE3F;f;-BTL +zH4PW>RCQ-6nUx_7TzBLgx_{`T@J>@%@v+#@h50!8+(&#saU!jc`%n%Uf6NC1vC!~Q +zAH63ZR(|C8BR~l(Q$e5vmg``k1pavw15;qRCI+U!GF@o704^Kh +zQZl08;==f#urxzxV<$ +z1(s=3A36Tu{|GG;e=r5W6aZ7;BX=P%1(xYTA36SD3M>f08D|8+l9asSgs3w-1vhjuw4AX6aZ5IOo4yWg$&5iKOm|@$yK40)5T^( +zD)HunWKPb(Uw2QcsPf27hcBeKurpq5dHRN3($LaIJgvIyjrOddzOL4FYHK)y&R=&{ +zOxgA3OqpwLL`1f-%0Ku*9o6Zv88@8fewoa4m1Iqloc!zhZom8`hV-w)qR_@E1&$bSQScN|8?q*9dxGNq$rMLnHF0#wYp;e^{R}Beu +zyp=;Q&Rmkdrbx;9LTFV=t}ujN&rDAYW>RO`*HE!!+_ye|2!hnWyC$FTc^ST}ggk#~lIy0000000000000000000000000 +z0000000000000000002~y~K-%1D@uP8nOZ-6R#NA@c#MjZm0000000000{Qp2P +z_;>yYz^4|&(x~CO9a_L5W`~Au_b1+@cQ4y{T=b^4CR+mP^JdL4FCWD0000000000000000002^cfkqw)+cpl +zT1Ee-{~ayh??s{SJo|dQg!)qJ?}&-{J71la7L(%E2P>`^{hNL>ROsFZE0$Bk=Y{|P +z000000N~$(Ec5SuJ0fnf)z&q~Gy-hF0RR910000000000008(mA-fQZ_x}>) +zHIEvu`}h3q*l~P+XU6u9(8{&-|La!@00000000000000000000{>`wfqxSgb7AH(K +z{2fVHZ$giSPFlYBJO0XF00000007|M2eU&%xBHV%UVQQimt%A8_Rn9P`F8K>#|KyL +zvNIq5edoW=*9ias000000000000000004h~OjYTIzFFb@N2Sca_2mHo00000 +z0000000000000000000000000006+hr_#3n>$d_pp8w_Rtxtd2Ks$eM#VVNY{*fU7 +z00000000000000000000000000000000000fPYHXW(t8%b~FE;|8Qr6r2lVyc>n+a +z0000000000000000I(cX-viIBU;gs_C;ymn_Wb(r_h0P1{l{m!E|2}Wc2$Nk_KcVA +z#O}ZUKb-^s0Pvs1j9}i*?zQy}N4WhhA#0BgKMN|ZkpI(frUC!}000000000000000 +z00000000000Q~ooA=UR_1fu??_h2yGAtA2vl)ji?000000000000000;C}=~m+96* +z6g+3}Kl{T%|0S5AfA6120{#zs_X6ESwLgx&4_Zo}yvn0cP!P~YkXJyUF*cTbMT`F;4#cXlEVdB{T^|J#o7PkZ*H +zC8Q-Jn7iH?e)E7KOVV=R_`Ca`FMQ_d9&>%c|0@d0Lmu*whdksV4|&K#9`cZfJmet{ +zdB{T^@{or-y!TON|FWz9XWut24|&K# +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 +zM&+hI-t9ACL!@}Z +z*8hYng#!oEePvnV!R#)Rt157C5ap`j%GJF(%4`=^q~F}f2A$e0GgI#j5fk<735{UT +z5W_rS>uol{t0882!q&TN!WfOP&lw_Qp#FaYR1E~GI0DpQDNt}C3e?uPKpn$C&5#0B +zjDf1fKo!RTH5dc66$5oF2B?)7s2NhA;7U=T;9(S~n___4Dgz}0_4@#oy%FTj%l?2! +z;B!Yc90ut%fyQJiMNQuP6uzP0If=g9kz(T(uEosgX~j4`cTx66(3Id-+|1_=Yd8!_ +z2Kbsri6u$Yq#d7Qq2M`V-HH^xX(l{OcPo^9Q>s`p24)QOHH{P72RGn53LYl;nsUYV +zRBFLU_@``NQ?l4T8Xl(jn#PFj$<+7o0{@GshQpvB!B;j|EEo*w|FhwHNj3aEVpitNY$!*Vb?aMZLOQi@l(jyhBa0MI@^tn=DL$ +zGekrRE6NkLrrL<*v~>huHiiQSlYM0)#e)O8Os<-}((TAAHY)2mZ7tVa)T>)= +zv1=Q+=HgymhsA!Wio3L>+p(g^*tUgRQB1yT>0{?Owd;$?b(TK%X{Xj_VX`&CH_i~T +zOwZn@A=Y@p)(jg#(B6Dc*gD2WJVRRt@~&YV5L0}vF`}5@Tsx5u&qfYJT7G{V>_ycVi&MWi8yyPy^j=Df)j#xRK1HlBhVJxp4 +zCpIT^nU-$}G!LMb*LOP>ZV5CeQJV&InU>cDf}_OdRBCxcw_|mYaZ?htDZR_ou_e%) +zLUq)4JFXNNJLADiOTW>}ad&XBND&rZ?^5736u6`*ab+mOPy4dp;E({0G* +z+wwTDBH7nALR>MBdbgq5F{jA5ZVNZ3xL3E&V*jv+JfQB?>57b-22tzkxDShab>CR* +zPZyE%EPX8L)ar`Kk1fmsji99s<80bQp2`aoe4m0!p0Ebi5vwAk+} +zBBxmT*aw~3w=K*pXGr*yp53Ss{z`k3DgZUa?H$TfqdCAO`TR=WpH%^um_fO^h +z`4xc5cY9NLY8VH&6dyH4m^Uvb_gT=}L +zU8Ycy&p%3R%sqY4bUb@?Aiau9s@>bi-lS*m)DYA8+@Ys0n(9=>x?=L%&rXMk0XE_h +zS}{~?tl?TL%(EKe`d_Yu6^S-NMJp!nk={{RtGgYqR|iT`sRd(BUo=f>2$UpJZ)UFU +zc05pQe6yZAS42JmuTDT +z=?w+f|FzioeFOJ;&gyPQdXX`A3zwcUt5=5~UBE@3(z8P~#ND2-b-0aqg0^N>0DqE= +z_!I42LR-gHfU-5hJ?j>_HK>vxF_sY>)G2h +z!ZK$_cu3FgvM^6*gbGjCkZKdAXoR<&A>m#<`zMXC))O{l+k{7G!#G|!o&zfqd~Jip +z6$83VQ|kjOlBlV5+^faCx>FYW!$qXR(#M`P+aE3_t(HDk>C_r545bk&Jz+z#O;}1B +zhE;&J(QZQq@4u@8_)~1cZjJCTZ5UGl+Vb6ofqdIA4!Bc%{#?FojOb3Le05x)nC!Fk +zvB^&DKntUGhJ;7;>_m-FN_$6D0BWq;JAkK#a-cB9N9Boy$z7)Xb%DZx)cyu;T2ZfV +zq{Tk1nA~mYV--%VPEB4e>eUezJ5x+vR*{#Bdv$`v{$vq3*V4!S*{MBbVdiOsUS~+i +zacZBjFh*xc*raF2TbO~)kZ`|KyGTvuSQz*Z?GC4QmxcM`&8I`ePlH#p3AAGR7AaA1 +z;#M0miq9Q)^rC4=k@0vPH^IW(N-Ofj#(~uFoJYGILyL@)ws0#|d-~YLPVF`ebBl&J +zH~31}J6g{^t`RZ?RLCh +zWL#CpyJI7#8DY28K~a}sCEd{s^5T8#{kuifU?8|N`rxVB?hQf7^rp()G8@Z +z@Jdmj;NnrB;EEWiTQN|t!~nGl1GNePRX0-#6kJpWN(Sn80P0Z))bt2Y&r5-V6H%Z} +z#0Bax1k}+Opr&J>;2Ke&rpEyFJO=6n2I{dGpk^STK92zkt`r4oItFS~3{WRzpk$za +zAE3@apw|2b)aNlkok2i-8yBem!a%(i1JoJ})ENxa8YxilN>QNT;!&XBiWsOnF;K6? +z0JR1KwFUzfQ$fK+WuRoBeg~k2K%mkhK-EZrf)i1oK8pv`uD>9lCd2@hhJk`>M1e|+ +z0jdTA^%(+cCv4=R3Tg?ipeDuu1y_m!m4<;D5Cha_GEg#5zYkEmVOw|i1x13G{`{$n +zrj%mi@oKKd!o2VizMZY3Q +zD^%pWX6C#zM2yk1hs?}}&JZzA&jvKaK-#;`6ShvY5mRXEtP0>taa$Fh2|f-0lGmb+Bf?Fg!kSyf!BimWyFv7b4$YBOVThJ@*Q_FIjR +zMjLM7mFZ$$7PX_g+i^l=v=5~0IbEhr2|i`En3qE>uj+P8RvDMqaFgK+Nh;&=YHndo +zx8p69aZ@I>yq0@Q-K(2rwlA#a7S?q;R;!F1HQZ`-uWqB+enmxIH8awpB5eXP%^oo8nDJ43=WJnJ0pfHWfujzJVtBv{9+)fpF(%i@X!>OHOW?puNgxmD&R~iBK^KZ8achTPYJe9}+ +zF3m>`61mJS6ImSy=83^n4shu{DoYHG5QEtq;Ie&Gvd9hUGIiAixGbuxn)|e&+p)PS +zz-3TfwcUE`x +zU>h-(R*VwUw>{qNP+9Cp&CI|4a3!orax13sxr3-B#bl?3m`^J<--7#4UrO(&r89eV +zXN!!JYPr{UJl^eiNo{n#+0LoS1!m@TXNb5%&tB3H<2_;P9X4VS?Ik^7>mr+wKpSr2 +zm1!Kv%k(J+hx_I%{E~;?Vace8wzZ~NsTa@HWXF>WwP5ljP^e02^%KcgxhJuoC=^E +z=r&B_l{sQ_PM2wFRbWLLHMOSOF+y#eTFt$xB2St7*zcWMg_&t`hJ-avt<}u9oFO4k +z&$elVLfWvP0<lic2WXoG@p%i@4L+t-#Xx(9Wcd^Le! +zy6DcLeAQe)MfRDQkTWDC>e*V2aI+`uoo*9`(B4~lDw6|+**+>sEF9Ej+FuhW%%b*J +zcRS9gjQeZ3Giq|AxsToM)b2Jjr<@@nSI@E*X1%$OwK}zenOSdPem3{9UZ-}hnc3$I +z2~+j#HyRe-VT;+&M-w6DfHex32y#Uv^%SNQridDm7`nt!lP%FC~GgZb_HQY?N;-Ad+ +z_f_NtGxI~so<8;`r}i#0^BPf~V2dHP^Ly2c2uky{m5>}+S71?}lCRKOrF?2)0bN=%^2^fvO +z8w(SM*oc+1Vi4andmI)Do)dj40T1!Z<}f4QMpV)YH9U;oQScBy=7WEV?Dbd!4@cUF +zCuv0v-!yj|CTc!@ECCPk+vejog0iu0>j1uNCL?gT#XgU8b@vfrA4mdnRR1qU`BZSv_~Ks8?5Ju^%iZU6wu;?dO2CPPUC8Y3sNO +zP!`$AF_;78Xd6dTmq}R{sLU73Q@c#chCpSqSUHRX<%vGmP_aCPYOC*dxQmST6soPR +z+u<%Ywl#2tMdW&QuP)zWFDxeaTl&~(PAzF+o-y~aPdc?-7G|7=xZe}DjL~8$*ZpVGa#{Ko&nWA3Z8jJl*G5Ldq$#8~*C3^NAjj+lS_NLneK_kp{ +zhJ-RbYtRUXG{Q5^kU;6#F&bgHC+runCXRiie+rf9HEH@|^zGR1X7%bUPVJ)_;#qjke-=?N8h!O> +zVa)612M&YERJUR@?_UegiTYZ@}|)bb1rD +zf$00O2jJGH$osLcz(e$Y>^(>1hv)Lc^WWv+c@x|dwf}|R9-iO(h4jh97WDA^b$HHy +zJUl-DH#|iip5Oh2w33?qIBM_i!<(Y^!b9}%d^y}A6?u66hcD2>^ZVc-dU$>h{8QxN +zIs9b!;W@lO^x^sacvn;jJVX!ACp|7dn~8LJRc=Ln~pLzgH4drZ&XLMxtl=qf0w50vcW9$2gd +z>??ZqAzGmnONP0wJI=M(&smrrn3?QWOcdLwNKG6<5##h)FhL6=c9X67vqaAo>jW2v?xz`m+yAEvEJvAi~{Ti2=eX$WHv5UT>> +zR<6*(obdoxiqDlxQEI?;>)CO%bxP3WR~h|F$xRwU*8{|cfVhiGH3Ol@Cfvj;M}-{q +zW_x`L^C)e&GicgTWZbcsY;^*|Y_}m(%-hbLurR;Sh9t3hYgqTPQ~PqMFuVseHwK#P +zxwl%G(H@{2=2K=+9ZLawm!3UL8^#4q9m|YUi^z;pVL}gB@qA!K4fkpb5N6th4SZWt +z$nkKC{b38^q77L=)4NNI@2W{}Com+t4HHH87H&=}5JuR9hxxXwkmJKv`_pD-zX!Bs +z_}a!$zGBkY2@K=ihDBmwRaiH$Q`?{s9_;~zHG#rLZl{I$hX+teK58hnUj^8&^z1C! +zd%IZJz@2GjGHCCFpovr&$)zOW1l|I-H&5hta!;Cpu-qn0<*6|tN4MGD-NG0>fEw@f +zCr}F(le?V2JHzcABvv+tb!VO0v!y~t52)N0sI23(t;}2x@Q?8Mvnl&Bz~<=LU9@+Y +z7|aPd7Pi_yH8ZRS__KWed@57~*aLc2M|CS)Tsp;qDp@SD7VsZJcV!EWkQ{`(laP#q4Kt^@75QSx_>Sw2nP&UU7Uo`Bv2pfQ&|VX0Z{*&G +zpXnz(JC;_gfx)^!`ws3`GxG_|9Pd^v5(}!rx|B|BorZX{2Ncu<3L3da3-g@^lqLDf +zhEh!`z@F2yGimGXVnGAf-pZuY)(JsVnaWtUlq_=sYk}LECm!6%m74*v+(u00%f^Hp +zqS-FCFqIxqHs0q-pp=Wr9Zq1K;kFJE%NxVG4yU%Gl*s4-<=X<~b=-TY->f6aK&}(?gD>t@aaU<~`alR?OSQO*S*zJU}_fryNZ! +zF9z)2^z0L~p-^nD4(n!hYCq5jYkNR*ZJ>EOcf|sP=WId}-!_<%7=G=iGlG5K7INhZSN#B_uS3?fWmW)zdprI=(QOyFmVVgiE*6PPJuB4g6um^=~IB|a9Z +zOlC+iIXN3)a&J6LPRvG_+$+TdE)vD$D})IQB213YMwr}-FgZ3`ipf_96PSrGfuAW_ +zncRyofgc1{CSS>z$e8p$CVzyOyc)seloXTOF(xzPVRAdhWTq68QwWpyFeay@nB0yr +znTargL4*m+jAC+1iplL5lbHw;7(|%BOc@gylm5nJ9mFJ3nY?M3}(LC?+SRn2g1k%s`mHAi@M@ +z%9zNQ^fxAkurBc*k;>$$7))@_1E +zL@JYQF__?<$;!Bx;GW4!DJF1{C?;PcOkfaWf_o+_F(%TU$;)3OOkgI)1ouoDJDZPCb(w;g9sCt +z8O7w76qBJC6WlX_L4*m+lrfPp>2FNnK9iRtmC4;PnBbnt1936IJ(CBdn7~D%nD7V_ +z7{r+1p2-6k6KT)nWgcMyGchK(XYv5XMA|di$IF<=nDjp;k3&rMMld-o#bhSNByP`S +zCdNeCGkNhe!sJVg$!RGjGchK(X99x=6POvr&p2>!|nBbnt1}P?Rktik?5hgH*F~L2P4Hy$?&*bHc2osozF~L2P4Hy$? +z&t%_4850?k{>NlE#H22Q$x$gL=?IfIiX2l8!KepDEfifkA``%#<;aG3jqi;69TFBbCW*QcT{)J(H4nn7oC1CM8l# +z;382>&LK=-5MlBr?wOPzOx}p;nVdtIz)XY*{7liFNeRLPeh}O +z#sv3F$}uJ}JrlQ#iHu4AV=^0JvLk}Y2`MId7?Zd?lRS(`OwZ&5!sH2z$q6YYc^DJi +zGl4;b3CxUQazctp9>xUsOkfaU0yAYyWK8-S6S&Xht4L+?L<}alXR;zLCb(y^LW&7o +zB#Oy-gb55{OmNR+1;!+%XL2540y8ltxM#8gV-nLdIWJ=(W77YaR6tDjM=&`f#iS5p +z61Qhkh%t%jnVdnG{D?6*BgLc;V}g4oFo-aLnNdv6NHHnInBblX3?fWmri_VOfDfzU=U-1dnT0_lbD{#C4>pg#F*foNhQW4 +zre|_V#ze-X|1rsgnAAov`AmvQD#Bz{+@47)!sPLop2=qjlhGKH&!m{7B1~4}o(T*h +zOkiddlh34>q#{h3ZCY>@SGA8|x$-NMh +zmm`>bDaB+m#w2dfWHQDirf2dc!elSTMv_0KdI2MW8F7Tzkk^?zM|u=XUxn8 +zw0EpnxQm-+2Er1XFo~x|ha8OA&a^NF+FKYjbrl)A7L$jZz&pq7%@(=sVO_6N+gmCm +z^Zvmh$2g09Tq`rh1N_5%{!D7YGQf`1v%6_;u2{JvtXuEYt}hkl^?=G_`fk9Jfu`#3~9i_tf9uV9f2sUs@kIw*X)t^plt2M-b-+l$; +z4)Em;r&849XCLeVM4FBG1D{*4{hFz6sj;q@e6*Cflg}MTEh!?0!1-Hj#N&MKr0v&C +zOO_aysL9S!;(55pFkfy4b^OfAudh}#hILPLYJb!a!P~EZrbJ)U5Nef*+zYQc!bUvIH%;As +z&9rKn@%tk3E*P9P`7oac(5j{E9=y{Gz7($C5Ig4E%tH? +zotv8G1Tf({>o!aFZ;=vwJULPpm$*nL0;vO5J;9YrCTQOii +z)U!|1)&)TmRb-?VllwKqnjRq51jI&;vjE~58j{NLUh-M +zb>DPq=V^rddVsqw;NHOn%#7Uw+H!nt1rxSRGxV(F20@f#6PVvl$5Y+k`uK{}?J%3|NPrHPMQqhp&S4 +zJ+7Z})2Ng)Yg8?k|Jnqa+VdULVyO%?gKQlj~tE1+qFuPK{)^K5xoH`=Kk +zT}n*mo9?n+Gp#B%u3AD~fY*H5Mr89%v#i%l->Zz@FD3t~Auhqp9ADFTDz^x*HF{P> +zTc-z2xy8oZCFF4p@l+2es16it<4P=mc)~`E=F3JwG^<^^ejVL#{^B(GNZqUT+j)u +zBi+`yqFBoXTL7`hMwobILdcQYVo$X&pLu|CfKNG`%2Jb`cLKuzx8W8suP&@>?bJS| +z5&p<4v#A}+$YB~`aSv$T5@>#&d&>-jhit-ZUYSpI6ajXxp8XSTm=iR06dOC1kXN0+ +zu+VKt6jyBJMp%Hb(k2Y$+lGf6uUhP{wlcXM&^FZ9mQKC9lr%VjVXE7ZFRs`X){Sv$ +z$CL__`L@v^$A@P7hb_!H4`|ExwIx%&#egOCY!_|F5#8Ivx<042uT)6v0fk!wg@Yq1GVL86H0@t%3^j27voVM)lhp{5wK16NMVRcvnCz8evRcMO#-#r-c^YEU6~W|5 +zDJCCdO!mdY-P-P*nY=B<1ZK*Z$e8puCNlwBbvS~_ +zBQcoZ%4Bz3OmJngTZ#!>B#Ox@gb55{OmJng8)FhvnXE#XJQ9Nmu1t1gOkygNRWc?r +zCjF1elMs_{BABd`VsZ#$61OrrgfWS!Ox7VxE@Dj9NijKuF~OC|At@#oF(&Jzm>j~G +z;L7BX6cd;!V4QF@ZgkYY|MI +zi@^j}CI{kTf-92)QcU0?QB2k#OkfaWf-92)7?YUFWDUaPxfo1vWpV&x5>uJ1kui}m +z>3>W%LrgA5Fj+6f#DOu1TbVd8CNY)CdW6Y!jLCW_CJu}Vu1p+KOs->0)=M#QU`%jj +z;*eqjGi6Lq?o`(BA8733&I2j5hm%V +zGO<-5OkfaICb#_sVUi@p1YR>znY>$tFo8i-nN0nQjERg%|6@{o6{P>s`5PwF^b$-y +zF(XXU<5ec_nGq&%9#tl{>JcV22or@~f(dO#m}H>Jq{S@7qy}MfhhBooVKc%6UNcge +zd|;Mh0yAYyWK8-S6WBAUi(sOP!30$%2VaPb393xqd_jr{TqKIg;|LQN#F(JU#P$Nl +zL|U2L_Bg^s6@v+?Ox}F~VYl-BTV2tu1xSglNOALbe{=LBTTmA%7m6; +z(tCQ#RO)`n8=v)Hzu%Way){`${0*=WwIwOCb%-$BgF(R62%1X +zGl4;j39d}`U`%2v6THu4Weg^`GTDPMiK$HFeI_y{Hvp5TASM?hm`L}TeDV>-ByMH$ +z5ym8@GQs;yzQdSE_nFWiVN7sk@{tsi?=U9PeI|!L!kFO7{L&g04i?=yJ`V6B9MOjboOnJLBO6s}C3kB14Ik5(qnOEH0qL@~kpOkfaU(vB;W=Mg3_h$|Dk&t#?) +z6L`&NW%4}21O{Xe$@>@+={}Rg?;uRzHKUcuJ5o$wri_V0vCy5g7=xgAjSk&Ca+;kVk#57&tyXkCb%+r4Pz2hnaKN0WK3=VCVz#P +zT#8^K-DmR2Cm55smB}X*fYtEV3IDyM1d=lns}JN`DkTQBgF(R62XMQ`%GXEVN!rAlNy8x +z45G^9Z+M?cx)c+5&1hv(gD`sHx;Ig`R(Tw4o7}d;nf!Vs}|;a4`@sBwGE}-RguX!a8rK +zc8o??%C`*)Ip(z5KQuG%dO%y2uPvYQ6#;g?o+W9+T+v+{))_mseHvkN4=Ah(6mI3R +zEkJnGCJf=J;Z(jFu>a7r!)WgmG#`~ +ztw6}I3HR{+bjrRIuygh7A=;ZCG})IKHx-fNONA*tAozSBSi^nV0))9X;Thha9CB=K +zv2V68muYWK&=gu?45`V)f_;EE(!QE4q80zO>MBUD38Xi2H5TT-n>v7EfLn2km|k|_ +zxAScIW@am#AL>@j6dND7aNW_;VsEi99$K+<)m6~AEznrUtt93E +z_D((f5v|a|;I2SP6*shnSqw90xD|uMk`))OJ6^KbUutEB!{8*hB3CTg!JT_(4q$D1 +zwt`k{T6Gn)R|VR)ax*Q=X?RkGTcHr!AHHzi@qVj)gPC~^21mLTbH(;r?$?Ls0QNaO +zd!4o>1Wmb%jkzkat`k_(+}2ygf_kp86%d1L#NB*ZddN}IYHv3)@6*(4sPc}3m`Vxh-BV1m{O_$dqU4n +zrmeRHO-i*j3vC!B=IspYCOWkf +zONCo|K;Di(UM+W`g?WlL%om%hxXCR*xWy(s&MQ+wj<;IuZ&{chX+vtz)Unvup&~!% +z1cq$4VVc<75Y}Do)MjV|72lQ?a*SxTziMWH6BurD8%B#Oc7}Bdr&dua6!2|%A;)>M +z{d@~Uc|hAZUt1!zZZWyf2@JE`h78f&7}kB`)P7ScWcL8~wt%~id%Bfb-~nwTeQi0E +zZy8{d^=vKe9UL^}FE!>Dlgmnl89ktIXP~f}yRQWZx7mazcq*0Jzl8ijBm9-85<`w@ +zE%s>^=9C9eDLyKfBGshO3B0Lp?_`my3+oPbYM;>vWDnpP0^BZcoSA9x0Dqd#KZ;sV +z4A{5z>>Ap8SI}fHGTIlDtVS^OfXdoH<#z6p1qeo)Fp&2Tp*E=idsffhL3D#%Z7Uo~HB1vrg>fS) +zM_Tc8?p4rO8))3leOEREu>aPx18Bv~V#!0tuRDge+Fvp=Z@|paZpB?$srF +zwaln2BC|?~i9MkF`9OIM*W3b#SvF!L?@9_eRFGl(`!2%46wjLVmj4?2ONz-`DA +zn|E@n%|N)|$AlbL%=RlS%wIh~Io{WnKuujtZg&F147XvB7|aPdWK7~y&TDZ`j35hgH*FoBs-Ok4;P7{r(;5hi6)OyEgTOk4;P +z7{r(;WlUsD`X7^Kh{@^*CbOiNbRbMzaWUyYn810A$t;A45@Rw;ib)5;1ZGAt>5yWg +z#F)&IV$y*yftgWEI;5B=WlUsD`oA(c2rCmYf(a$X#Dy{GiiZiDk7Cj##e~9`%te^M +zAi@M@MltC^n7|;$WG=#ll41f+iel1*Fo8jg$y^x|8I%6Uq#k1O=x>+^)1{bvjxbTi +z#pH8@37kim@Y4|{SqKx?bSWmEBTQgs6qC=Tm}DVL;Ag^>$>#_Ym>I?7b15cSGA1%6 +z{f|jGtW26Cm@JoKqQsbd6%P|QAI0P=DJIJiCcI?7loXSxGA1%6Hvkh@nYbgEtdnBWhB5gj9wu-; +zipe)pOx9scaL)t=5hgG*ipe(!6Bxvp;GW4kDJJlwC??+^OkfaWBKJ&WOl|-sJ0T{I +zMKFo!nVdwJP;oIii7IoNlm5p +z0#Ax!A|Om)5Mv_uOk_-M04A?POx8p&iRqb~MVR>GVsaK?0_QO%xM#8eV-nLdIg2oX +znNdv6N-UtqlN*2u +ztV~WsFnLUh$qtOk*YPlc^HEH`mSXZ4#sv3FU=U#fGozS%jWB^hj0x_UJSN2io)pF8 +zYlI05Voc55F=>XC$y*Uj9+YCT9Am=A!vxMpG2x|{ +zJcu#DJrfv2n83^^COpCf1~DeMXY!yF6L?Y-6CPm#gBTOJXCh;A12EYOF^TLmnJev? +zTsn;~>4=NTX@m)!$C%)r$t;YCv}eMfMwr0NC?=<+n9RbMNP8w1Pa{lVW)zdtQcPya +zn8=vi08C(IawUSvMkyv87?X?fFoE+?OfE_>*@!X0Jrfv2n83^^CKnMVFo-e1J(G=6 +zOyEgTOfDi!U=U*>_e^9=ZU82A5R=G0lS45*lcNZesc|tmiZFrm2ooFbnPebL+G2Vp +zM-e74Gm6PkDJB^R6Zn~M&*Uh=1ZGAtIV!~@L&ikLr2jEl0V|VNBbeMH#bheRR#pGR#i8~%9a6XEOTZ)MRV}g4oFo-aLnNdvK2oo5@ +znBbm?L5c}HDT;|3VFH5~6S-$1V{!v9*#R+$>@ztO(=$1NFj*HDlM@INIFB*GJ(DpQ +zlbD{#34{sEjAC*^ipdy^Nlee=1i}PnMlm@d#bk_(iHu4AW8#LD$%he4{w&309meE* +zJWSwx6qEB(O#X~9!95cgM3}(LC?@9-CNPLG!99~dOEG~bMKL*#Fo8jgiQF@hF}VSl +z?1z{{_L&@t>6x5CnE2viat2`n=P@R@XEG0C64Ns|gD`=aQB2NAF`0)kiRqb~L72eI +zC?;p5n9P$gkukXen83;;5W&PK#l(j(xfBl*I3LC2k`xmo#sv3FU=U#fGozSXLYTlH +z#sv3Fj8aVCNl{ELAxvNpV6wJroFDhnk)nizv=bk$gFmHkKKh>@u6xYUxyaLewMR{cI)NdWM82dRW=6T`lyU>_yZ^yoQtw^FyM|Dd3b1GN>@?b{2%0Fhky=JB +za02TTw{@f_?%;xEKo +zwXLPXC|)^&+My=@Q7R1R0nJ+j&0Dz1tw0!V6CUD~S=91nfE}%8_tJ(DK~u+4V@EN$ +zu@e}^xeW`&6;<4b79dQp2`l-w0rHpB$Nj~V!o7eva$kg-DN=6spZ;IJc;fmp9yf44 +z%FUNjZl+*vW}>fxgh9j&%#3pLCE^AKF*h^OS3ypZasy9_a`PqP1_m)VGyi9Q6=YaV +z=9dyvdVu(RK&;`o7C_9k5zp|hJc5Z*iV6HRpa>>p +zTufXD6F84CQ6fwTjEPc;i3?!@GozTe{tx!?bR8zJu3}P8V=@;pnME*xBEbYY +zRZQv$CQw97W)V#0(wM+QDkd-@NWlb(h{-G+6CIPz$K)fxWVM3HTpAOY2BcsT%ZN#g +zU;^ui$y|cTi-^fw8j~2o1UgkrVl*Z%A|`WbOkf(2f(dl0n8avIUeqzsG3k6v*1?;} +z1O=19G$!*A6BrS69VW1@VsebeWH7;`bvnTWiUbqrR53Y5Fo7b$qn^Ajemn#=^I0V$Zw&xpxa1QS>%m^5Q%@&Li4MU$C) +zMKFO*6_c-MOdcSZz;_zZG1&J4OaoFdfld{ZuV_pj&@s_5=>kmP&BUZ&GL6P0fSACD +zpzAP!brqA-G$zv!6U2>=u|PeL}Ow{Of;DZOaoFdfld{Z +zOEe~S9TOds&c~!TyqR?W36pk1|_KcO%=(T!j-m}Djwp-3=+ +zP6d;~PY5PZB$x~!nMtY}jR`!YU@`|r1Syz6kzg`N&rEboIv~EIwm?MU4RL^nG`FS+(2Wp1u=mULDyjd>nbLn)0o_Vn2^lmA`}TG +z(5YhbIl%;qhzZF|Qa8|;z(Xn~Fd|671d51>o|)*FbO9!R0Zf#0CWGnBWC2VAQZU() +z5tDBSCa{i}kjy0c1Y$yGCbPdGm_VnB$u~46Par0AW-kkVfQfR>WH6nXEP!c13MQo)F^LdNU>z|bnMu-sn9!NY +z>TZ-(3ng|Oh{&O5sCy8=u|N|Lok6NVnQ;L)N~pXcu2(rMg%FCKoK#~GZP(?F2Llk +zfQfR>WH6nXEP!c13MR)gVse3C0_%tg$xM>JKuqY&WcCGu33RHMT%a-e1!6*HCi7q# +zkb((xs+e4$G5Lj#iH=Fmz)nq1L5=@{|#pFvGlb;bx;5!WZ|mDF!YJFCvW{~r8T +z$A2!aX&x+Gp4SkTy}hH}TcpF=(&oCbi8C;4vwV0*^6-8k*WugVC^z&?G>qm7ie>&S +z3;&eIdsmyiuE1{BTcvQk(ry +ziS1AY`?NuPG{Ozy4pp+FLUR13XndF?>`9xMkclyh1rct1D!AGaSncvX)+lph6I>rI +zRxa~43*YXEcbC@fOq=(IO#6-E@Gjuy7I=5*r*PAY=4Lo@14D$a;|A7MZjRF2^dj6m +zfT;=;2{+KGa&we$14Y8keVD5BqPc;GRBm91kircV2{-pomw7p4`q98_XqNLfCi8X* +z*-n{R>Su;Vszz`*r855y3qQ=`oz!NpEwR;BuqzDAqmimXTx}(r6Oz3*MZLqM!+X-^ +zs*tJ5$P`4X#;1ZS9f6fD-;zeTYHXsa57$sG^Xn{po5$N-TDdcA-WxLQH8R7S<&`zb +zmD_~_Zkg%tXYP$OWOH>DGC#+{zwhymZ?o4`+PEV9l6tn%D9&h>3-=`pHwpKv@OJ;8OGtWe-dULhq?Dq!dc +z>nbMn#FG<~5ED#Qphz%*P8AcJcmhSl1XGnsG$!zniV03Ufg)luQ^!QV3bNC$f_&m# +zz(hHT@_;5)!HFlYX2b+1p1?X{f~m@rh>0du!HFl(sbWG;JgI*YG0~(dIPnBJRZQrK +zCs&@-G131atn>dN>@9dRxn03z1dYin5GhzX`DP$ZZ@r-}(qJb@x&f~m@E8WVU(#RMmwKoK#SrDLLF()pMOfQfPv +zn3S5EINyphz%*P8AcJcmhSl1T&L6XiVTC6%(9z0!73`&rEbox&V{+0TbmU +z$~jGDf)h{P%ZLe1Jb`t@1T&Lo5fe>jf)h`mQ^kaycvAl?Vxq}RaN-Gcs+iCdPp&+x +zW1?fy`IuaWHc(OJlCOGi~))5oTOddx}G?@ubJb_LX +z6MEuF{o{yc>nbMn#FG>A +z5EINyphz%*P8AcJcmhSl1T&L)G$!zniV03Ufg)m}XC^u(U4Y3Ez(hHTa!!+(;KY-w +z88N|$C$Nr~U}o|PVxq}RaN-Gcs+iCdPwHPmOf;DZPCS856%%^m$(2`hOms{-ACr;r +zW|E~~(u2mNKf$CfF=)%uGrMCR6Cl +z#E%nCpi{x*9nHj(5`qbQCz6?bj1y0wQ^Djz&BT)u9TOdsF2DrdOv)8ZZlW>SjhJMd +zcmnGxCYp&SHz6jNnLv?X0-Y)*IPnCEhzVvUH_@2DLn8WCfF9G$!{VCK)H5z`BZwX5z^(!~`=FC=yJdQ^f=)oX!OUbB +zjR`!YVuBM-pop00nTd``7hv)yz(hG`GL6nmj^M++X_)5bO9#tX0k%TWG0QtX~ZPs#1mLoG0{vs +znTeQSW&%Zm33RHM;KUOsA|{xb%%m}ahg3{(;t3QH6FoE0G3f$KJ_JmZb0*X1%;X48 +zJUN{a6P$Pg>xcF!AY`iH=DZVDctlqMS3~HJJ%cJju_92~IqLb%M#CF*8|2FnL>(nc&0|=u|P$ +zOgvdcFoExcnF&rjfld_@&BT*MIwm?MU4RL^nN%s57^a +z1d0R`=u|Pmi6>A*OfWOaqcMSpR7`N<2^0|%Ju}fU=>kmZ02Ae$39rdaaN>zKBPKZU +z1lAD~%uH4yCYsCyC!Rp3iiu|8$x6gTlbPVe6X;Yi(M&v9sbivJ()pNt4R0m|3MRQU +zCRW5Gpy|bmfEy5|6 +z?|F}Ro^*I)+ME+M)f$);&GO;R$-_0mVW&@Ol&g9ss)ln7B{Cni@P!`l)HZuVsjZ=s +z9cW-mo8^^TlPmWK2OKihIhzQ{-uY2)Pf6M- +z6gp+*X+JY6(vXu13eJGw_DyJ%8-^zu`g1K6?D~-Gofh>@l%)M>bI*{er%}A2SZJQ8$u%yHw^|Ec`%^^=2u$HEli^Ha%t#A8D4O+mq3K!V3;r +zyx%WQjns|h62&qfu<+|W)`e~M@kO@rW$ccS9G@PI_mv83gndp~e9kZSi*UnI!TX(o +z``x}-p7xt(|!oIY5Zpbv(C{AgXg}q5(i_qkf +z#rb}5eWaxuH@{5gD=qvgqiDrb)xn18igmUDU}a)xo+maIveong~b1M~Ap&LD1EB|Fr>dzIvSz<9%;DP# +ze{yIve}=T^-HX?Pzjg(F?ezUO6tklFlch!5ga`S#GC$kG`#t%wbywv@`;(_O3Nu~4 +z`{1Ej(ft0>DFMc#I0NsxedC~bYczk9bZW2gpFhu)`HwC9E1vv?ZT6fZTTU6fEhKxV +zN42FRfWvwS@^>q +zZ?1HBU)o#{G8Gt^Db4cXy~)E{1j!{c^Zm^FNJBTSpiJf~Ec^+Nw_lsRpxjna%GQTv +zZ&uVhSz5VGSmKtMv3};UNW-91FzOBzI(+*)-r;R_uENF@vus%Qj*WWnmZVK-^Zc+W +zU|`ln8v3MyZLUC@)0b|P3%Vr=hHwK*Wd5jyztLm8P0HP#HXjR{ZZ?QNYnF4jC3E)* +zCmg4xx&hpjN}12G@Un1_@q#vcpx72DXRn0h`21+Rr_{DnSm2b!r~TrnNJ~yCc*Gev;`U8! +zlv{=;TKaRT3f3Ny|%5x_l3N@>_ael^1PEF4`@837yRret;+cX6cmwD8U3eRZNc3nDo{$(J|?KOvVBx +z6$&P98k4;Qlc*&VCa|tx@~wr!`ndw^h4L1O}cQpF@pFo7b$WX)`XNd=7wJfva* +z!%q}Uphz%zcD9a*j!EZZ@&#ZrQ^DkQ8j~jpCW|v-@+83o))AA}2_~;1CNpVFz95(! +zL`=S*F}VdXnMq^v1;GS5RZPC1F}X#@M8~A_F*yjBJf&dr9*s#oV)ASzOkiEbLYZNy|{CQM*m#bhOoiI-sV0lt|$LSq7dQpKc!U;;(Nq<~=Z +z2#pCmq+$ZYPZUg`h?o@UnCO^vJ|^{m$t(pE&6~+n1d~-6F?ot$0_%tgzL^|EOlHxT +z)Duk3BPR7UCUX#zSu`f~1QX~~F{!69nWJN(W77GUoCi!^P%!z3#w3B5tj>f9tgD!; +zrZM>lF~K*J7idi2PpX*22qsWOOfWNffyM+LQZa$yCkiG|L`?L|M8~8HFgbQD*rQ3w +zOkUKynJgukjL(S4Qi2Jr6HH#fH&2@_aXF?oi@yqr9TOds&d1~Cd&yX^D|>gCg*5O7U-Dhm~=iS?SRP!1(P6+NeVH^c+LdYRZKMJ +zOoE6BzL{*GF@Zm+VseRK0!73GGm{N8Ch(Ao2@F3`Fo7asqGu*LCY_JTFFv^z>@h*f +zOa{|$CJXVLNzY7}%)@gguud=;MBYr=Hxf+7)0xRjpAby?5KK0FLSxdMU;>>aGpYWB +zU;>>ACeM9BW71v6M8~A_G3f)C6#sXUBToo`kcvk4uZ*Gd^0Jg +zF@Zm+VDfy3U;;&g$wbUdifK&XAqA6lF#JTp1d0Tcae8K=W6}kfd=8i>naN=K&14~- +zGbzo837#{7b;N|cnY8~BF`+Y)mp&($>_ALDr!lz^F`+Y)>dy%#(5YhbIgQDUIwm?M +zosY>5z+|a{$zNzpjv*!)&zZowiV1zr9Nm1QRGCCYYHlr7?kr +zR7_y_iGm3f5feQ#(J|=)Og;lll+0wm=FJ4pncSQa6Fg@E>jaa1_-3*bF`+Y)mp&ty +zR3avy(U=THOz6y{`ZIzFbgGzqMq@Hm$3(}Z^D(IeOpFR99vTxjVv_Nk39PG_(C19P +z^AJq-e)fOrVIE=$VO*Nf%&p1~5@Fll_`E +z6Fg_KJR>G}&IHyG6MQpy4KblJlb6mAOim&uXJ|}jASQHXQhkPC0-Y)*XJ|}j=$Po3 +zbUr300h8wxO#Vt^@*QH5@tg^)tC-N|OuqXoVuEib&(WB`pHwlqKrn$KVuG2;b2KLK +zkctTmKT$A&B4VOvCORfvfXS!Vf<1n(WF`-2-c0bE$?%Mr;5idmCz#xiZzfv_CWkbc +z$)^O9TM?5_X-xVNOrR4plTQgI(5YhbDUC@#9TOds&d20dz~mkUlRwayyo#7)JZA#y +zDkk(flkfgOFnIvqOzxpEfj_BY@+H9piUgB4Ff+M_#snTxF@fPH3MNn_nEaQXndq2w +z0Vbya6D2cwK=WpT=S&{ThzXuEfpx?L-%Ngkm}oMSQv{PgA||J3Om0U^G?~dMf(dl0 +zn4F?9xn0LZ$E5Qy`6FQRjDm@u#^fu+B;z>~SXVKj&zXGZM@;a|(FoQGy8+ +z5fjWzo}n>;hg3{p_=$oE6cH0WGtn{W0!&T-CQ4>9l8j~@Ii6%2SK`?<%6_XP*CS!C=bWA!QlcxcbM-@!|Ok?sMVv^yU +zi720mmJS=;w_CTPPcGL?Rd|2ZmAP$w*tNg!3m<(`G=G>>^UBxPf-XnElP`E8G0 +zm1{O7Yjz3C4i(7!Hx~X*Pks{=$tCsBsdDo*;RcGx4W=rO(%is9DmO45Md1dD$c>(= +z=-hMxH)nyHS+>*;p~s+*=xbg?m&sd_sf5tk@H7H^Jh!hTZB(t +zzF&Cq=Seltc#|t|lhgM(tY=5_^Q4;Xg6oZ0GC$hFzvjvR`mU>T&E90q7U3Vi*Q6?E +z2{+KGTvET`EX~bb$c-jd!HFl(sdA&4cygD{jm}NybMsH&=H>T9yC*;N@>Mx|PcnP6 +zu-WB%0v7I!=J%4aU%q%PSmF$nxP8+-`FBX!JA_Z&zP_-oVseqj% +zn3$&%OtJ_jCQYh>6HlO1#Y8jlB#U4I-w9I{oOlAADkhqVCs{fsIwqZu$tb|2T*0KA +z#sn5rOv0Hkfpry=FpWt$!GxVnFo7b$1UgkraN-FR2_|MtRmy2h;2{+goOl97g3050 +zs-k1k1(?9Z6VprulbJLoUl2@wml2aM2qv(On9L-YOh!yJsR~X!fld_@&BT+*h>0du +z!HFl(sbZp;crsbXM8~A_G5H-}vO>XR1&s+TsF-}42@_aXG5MCpWCda}hhPFlf(dl0 +znBc?{C?Y19s;ruT;1QRABCdUaTu#T9_ +zAeiJJCYn?QC!Rp3iiu|8Ne*J7NmX#-33RHMXeOTI=$Po3bUr2wU{a-EQbl6|3o0fJ +znJ|HM6_W-UlPbgnGZQEhOrTT61Sg(A5i!Bcq>9D_9#S#Ei6>A*O!Uk|$D|7|fr%$3 +zB{N|)nMpmtM9hduJ;4Ol5fjWz3J?=bW`Yw>pi{*}Gx4MVG0|iuIPnBJRZKJ!PYQHQ +zbWA!Q6A>`s6ihf86If6&iDkkB)>TYmG$tHkf|&^v2`12~VuBM-poo}YX2Q{!z(Xn~ +zIPnCEh>4z==$Lc?CNS~jqLP`!G?~dUg2~*Bm>eURz&gR?5@sd?2__dcnF&rjfld_@ +z&BT*|1QYm9n3>?j6X;Yi(M&uUsAHmI()pOo1xywzm@K9-fdv(luQFi*>nbK+(U>eI +zn8YwMfg-^KI#o;_tgD!ur!iTDm|$iCMS=-*s+i!!6DT4kn3=4iF@c9vOwN<7 +z!B9j@^vp!Zqzf>Ci60dM!HFl(sbZp;crsqcM8~A_F?kU%VHHeR8WUJhF%dIi0_!R!B8>@)m|$iCMS=-* +zs+i!!6DT4kn3=FNCh(Ao2~IqLB4VOvCORfvfC)@Ixu|3&F->N2j$qQ75tDNS6Ie$~ +zFf*Btm}oK+oOlAADkhqVC-V^#O=f}nbLfXiU~4CYYH(kzfLyDkeDb1d50WW+v-tOyD6E6P$PgMZ`qUOms{-ACrH< +z#FGU|W-_17Op>1vOa^Dd1RB*ti?B{GS%{fQPlCw;Iy3nJC!Rp3f=OC4@uVlg1ill= +zOqy}x33Mu${97~eq^FLFj!EZZG8ix^RWK=~F@XgIlOIEwFoAUilWQRwlTw1oe9TOs +zNHBp;1(W~a#1kkIOcr8hQc7b24=I?m;lvXt5=`dlnTd``7hnPtPZlVd$$UC9Nq$Z+ +z*`E=U&j}{5j+kI(ax-E=XC^=3#1rULG0{vsxfwB`Gm~bVcmka&CYp&SH|v<_m~=iS +z`vH^X3MR{GOkhF985fjWzphz%*P8AcJcmhSl1T&N6G$!zniV03U +zfg)m}XC^u(U4RKpJXxS*CiCgcB>5S^X!OY|#8WVU(#RMmwKoK#~GZP(?F2DpPo-9x@llgRJk~~8&IhPTW +zGXxV@M@%p?nT43pnaK}0@dP?mOf(ZuW+5hYX3~rkPoPu9L^JVZmX3*zN#|p74lr4( +zV6v9R1Qt|GE@Z+4)>TX{(3q@6OfWNnBEbYYRZMW=2^0|%%uLqOn7~6SCOGi~iinAx +zndq2w0VXi<k+rv#H}88P{kU;^s|lOSd${Rt*VG?@ubJb_LX6V1ev{sa^F +zPMDeC#1rULG0{vs>91p=W77GUOan~rRWP}i#sn5rOuo#739PG_d`V++FTo^$nF$mL +zCeW#3f)h`mNH7UvW^yl$2|T1?f)h`mNHF +zf(fi6CYYJzBPN>61Sg(Ar;3SY;z>SYqRC8f;t6!Bm}n-R>gCOGi~iiinjCRQ2~cu2(rC!RnNG0`&<9g|F$ +zw8&?o4-J08`i<|~cUR$5g|C;aIRAd)@PhwY@a-38E9|4Mj@tA11OJ(D=0amSUJ#8B +zl-BKT3SM*uF1me#J@K0bxovB*ZI5uo(a!T0evK!7w;;D|O1AA1HaLBk8q@K?(fBke +z`(M!u_N-S{C9}5*J%V#u&BY;8v5}b`$+=edp`5)bnY~LW3Cw9VJHw`>2Il9HoI%{S +zN_MD$`Aoc=&L0-dpDES+CwjqNUT!NdWy3~h57cjo=8u$WQqc?cM!FK*h3;*Aq{NvWOa_z80Z8rC21^Wy<@3-*Pp8OQl +zyC-Ugaw|&M*Wvj)Ec~B6`RAcNK2h6~`~HJAoyg@BwVJcS +zrfmjhX|-I{D^WFq%PD1#hf_>HKXXr{Dm!Mct+3S=vn!0uU6HB@TvZX96HYOc{mhC; +zRaVSiRc@;)WgCplz-qZ_c%rI5*HF=F=0YaU$jq;nt0pEIx^V?%?A}m{S?*_sM;b=N +z>;6dI52u)Eer8Rip%2$m-fB*TOev$-ty(S^k|^lQ4XkK2mxfHGMsa$iU|h_;x5&1) +zjCF@nqQx(cjuedK_Lj2W8O2_af}t_{;u7293ihE;N_^Na&W;p}=jw}E&9lO$_YC5* +z)p9|fM8PPozO>bRHEil{5KAI;ePi}16}BnG?7iWXIMXjaAF1mRv%g(td%J}78pYgd +zxo%{lZV>l&Wvh8?$TZd{-V&)B6SJ=>wyi2>&xcat3x07>q;7c3o+z;;Dp;FAG*!!W +zgA;WVx$#A<=00K54uiO~TIPBsS_VsPqqy%*<(@CS)uUh7YCAe(vPzC$6L3}jA +z4dM<}wwgzUOrwnA{SUM;uuO0ZK5kA9X +z;Vqv0LaFB8Cob5Jm)VY&u{_{YK%#aW_vTB>n}QFz0uMTU5l?yl^$=Q +zba+!!aHT7-(&>vfroDrr-l@{z9Zf;W9msX~wtKuo1$pJ3v1$sMuM;p`DzESIKQtozPyStqqYTUcko^)WNaEq&*zsJIV;jv~5@`0MM&m=J +zb$gnEzjp+F@A5s}n2z5Sjb};gb_phDJ1<)Jxt{nGL0-2bxo*F(z~S59n2ryR#%D=w +zo1211T!AA_-<8I6yiYWKtJJnl*x+vG7h3qBC;yYj*2+2mdi&e_AyW3WuP@lMifvit +z>`?>ruMaM#^Ls_}CrQ~YUth3qtFUb=W|tb7J0m$0xbh-)=%oYg{Ld`>=brpi@EK$R +z*TnZ-&Rk4__4Ke?dU{pFK+UBYg6#o&cLtT +zz7cEcQ_LbilNYJY<=%YR+7$fK75LKWYleDnKT{E@?Z>UyU~LM%>j=E-@;wXn7yQhi +zNbS|PKa@{xOP<;*{Kw(@80riB%!Wu+x0pSr%$8HaZVRWFp?<~~sT#oLRJNKYhfI@= +z%)i;wINfjk;$o+t8x-m1G%b7wjh*Z7WX}=Eon8o!=~j1@#m3(LEPR-cDO+- +ztCkD;B?`uHi;G*$4~0!%8N}*HLC=`IzRXr%!oC+yiR1j@ua@ijC+fy>iDK3kPKgWr;)V#T5icrwDjfz<*nu`A=4G3*eB95G-h94Vq0IqnnNj(@r!dKE#qVMRFN%J +z#s&@InrgYFPoiZMm-W)qO~D>VX4$ez*iDySZ|85Y@D5M@Xem2=_JVy|k!@QU>%91S +zJ0G&}^k5WE{y*+s+cDSi<)@p1E?2GFr-hLs^;j3v(dxu56 +zGo{0un}Ua3fx}Lp>D34(lhe{$tUA=l-rXiR%&M7{l_ +zl{HPl1J1w!w{K))+B-Sw&5>5_6{3!I{(TGog2y{wkfn`DX{S)=^qp-?d;3Sd`I5A~ +zDJZxD>m0t{H>SO#qTacZv_)uhweuS+eA;8}Cdj!vlet@k-tKn(MhoxsSVv2_`!e5)GM*1MzDK2mg7Q}6|6;03pD +zzQ;OEkfS@2(fz_8M?1g8!k2pD(*?P3bF!@um)b4tbG7r!E&O+$crQUN+?6ccCfx7# +z&GN+WkP3GQXWi|5e+$3c6CWnX!k(nCS@5}h*2Z+aFdFYI3A>tttDS+>Zr|OF>G;%W +ze1atG7bZB``5hL%(i5K{$m=#I*VPEWceeBYwD6-m@yXJ+iH?++l3?Uc7CFTf5Q_WCAIBs3Z@-_w9D7+N_~p?r1dGj +z$dmss+gdrNS0ZNwmsQFhy>zghA7bHu>B)~kJvWilo7+~-{@uX56v^q%mA|s4DR`4J +zaFg428+^vYer9$gXFPZOr8P~#Wv;+7r|%o6kMlE+M{=$NK9pUQXwaissLiPHhqXb7XF-`NxpyMgGb2(pE@rPSvelNcZ-!FLGk#`Fq-rErTgrZKWU?YvLu2-;5?fUTTNO$% +zReq)*QZ=4yC~7qqgiUn@W>vLZ)hAIkifbrsHMfLK0}V`Rq@i!jUQl5xC}tOjQ_L(s +zvo_MuBWABFv(=TbZyTAh)pEngM8hDiuCmoUK4cniWNwW#jEUK~VjEY^#zHCPML#n* +z(l9(`Zz-|0RIuv}jJaBF7@TOB$PFxNHTMjgwiv`Gs^x-SiGmT_z*6>DI3@P=i$9AL +zWXJ4#D{Om<+2uy@&Pc%oZgCMiJe(3I`NbzA1z9os;&R*KQuZsOIG|cC7@jET&(&A7 +zn%9O*YmMT(YPn!yqOKb^rHtJjN{P$-;;=~Fh?sp!sclLnn;%Mvi~M3*VbdQC;xiGhH+QI<{ii{E +zxmxDBC%B;;TheO&UD(7J#Ht84FlJ{fZLuPDZa5`Q@r$b>T%VXdR&I-xvaLq3XSLii +zB+=5Bn_tmtejsFez$nhDmRrUpT6%DSGL{deM5|vM8)+FCvj<9Tfl79wL9DEnTlyth +z#&GM4Tg~RM>5@Twv085FnP?f#rApXfI3-T>i{?nq-?n@xXa8{Ye{=eBS?MR5f}0(I +z%`V>)p8OyBtd( +zZ#91rGJRoWY6f3U=TDC2=SYk83SYi5z193o*z`XJrVZ*nqxm;Wr?v_+?bBP$kA_T- +z8kzT@es?s#k96wCqZjPom)O3qU|%*c7ok2en!ixW+t?J$b_KGXzE2y|-o8=qZBpKL +zp~l_L53}&U_IO7Ka^Bu#-WK7M%lEv;J5M^iQOI+(^NTF}DUUZ>kPp`+4{sL^yM4Kh +zY40sj??~zJ-lm}B2uLp9y2iA3LDbt_TDeomb++>-Ec`7V@9l!Ta(i;+K4FQYo&T+c +zf5hW0kXCMK3PxRlsMD8hOnZAqy*EqJR-w?{&QG=QK96^-AWQp_(k5Y@tDQGl_=_Iz +zU`g8D6l`+_+T6bGjcMx*QR@&XcTZDryCbmO9E +zkkfapF&*z4jZciUOp^+0nu7bBfqib@@Wym}QZzn7D%>lab@<-%#K%d6`(k~4tI +zk}XZa5=WrK2cf4e`FYqln9_6RQc3}e_7HZawZobRB% +zD_OHmSZ1HyYJM(cdd|pvy#I1Ke?c_AyR>MhFl_zoR`af~=^g{~CDg}6^Y4-t{X2ZY +z{$`o&%@X!cM&iwhn`O>K*)GKY@7qNFOJkZWR +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 +z`((GyknsYu;U}(jTvraAqpyw2NZPaD5 +z&E)nnx#O<#6m>af8ySTmXSjPg-ErApGkvu`xl2~=xV)^5x~jaH+>I%BOu|S}S1-4b +zyZ&VAW`DWkD%ljdyNtf6T<*9UGu<%=qgienoZxzK#V=eqaPkdyXJyv0h6|*mf<@ki?PuF4!6I`-* +zvtL{uY3Y>;{@xY%z0>#4M!BU&;-_o=SUxPr2S(#lq;)&e<||6Z#Fa0iY! +ze0-zaGBD9Ho=X+U{2LY?ZpD<^wxrGWut_#B8~<`y&YAvat2*@6k3Y9f>Fm>JVdUs6tP#gsG5z-S|vF3Z#{ +ze{#p2{wZ>aEIl$t?zp2o-Ek>qGd%)>+_@}Mm;9wWuJmsvcgV`r#2C5bit;vcC#FnI +zz>qtxTux=WPC +z#-xm3QZbug0!4xebgGzyX-vupCh(oqHxnolOrTT8M8~9)|Cwv&lYoixX7VcyCNl{p +zlQLp5lVCE5#soe@#pDZu2^0~NnFNzbh{;SElP?G+(21DLB$!M>OlH!Ue4%5aW77GU +zd=8krt6=gijmeXU$(&4>Jc*dhp)vWEVDc-(tCYYH(kzfLyDkd=+lWN2SGZQEhOrTT8M8~AFF!`V*($d +zVse^b0!73GGm|?I6HR7vnqUH*hzVvUcOWL3%;dC=iH=Fv5tEFW +z$+L)wCNnutFnI?tIZtEqEMkJ02^0w?(5Yf_p2p-^!~`=FC=yJdQ^!Qdq_Z)Bb0*&@ +zZzj)aFu}}ZTt-YVGZ{x?0w1Dca*|*IMZ^R%lW~ZNCNnunFo90Q1T&Lyh>0dMIjLi! +zW77GU{1q_qDVT^fCXXW~88ef|5fe>jA`(oVLrg>(lgAMg%uJw2Fo8}L6OqQ`al`~O +z6DSf)pi{?0$E33{fpaF`DQ_nK)?k8}$-Io1U}iFp#soe@#pE2p1d50WW+w9x6HR7v +zj$i_vhzVvU^AHnFW^zu)M8~A_G5G;7Iig^4iN@p=#3W;8@(N<2$xJR0O#Y3ST%s{~ +z1u?zm_z(q?L!S^#phz&8jG0Lfg2^O0GkNtBf(djIOyE1InMn_V349TfnH>B?$3(}Z +z^D)^9m^gpJVDh^VjY$c?wn`lhnLsU#YCzwDH +zF~Q8_Cd7o!OkVw*U;>?p31%iYAtrQYa`1B<6CIPz$K*4>=lY0=82#v{uhzVvUP$ZZ@r;160#^gc7 +z1TzyT5=@{|$3(}ZvoV2lCa)@QCSPbU!OUc4Mocg>nMq>;AEIJ%hF}6k!~`>wnTQFU +znY?<2U;>?p31%iU5feHyIe13LM8~A_G5K%6EUtV;$aRUsYjSRm?sXmaSu>*1M(XrnLF)u<0X%xH?kTClyS( +z0!gPY)hKh_65J4Oe2L5-v+y^2;W25|E$Wqy=}|D7kEBdyz;Hm?bp))>XRo8@);lWiM?1uowMjdIJF +zL`xR8zFg+lSokZRc%L?Vs?3%uVS`3-Vzb<~JK45F=<$a+GQaUp%IK}gWjUu;B4-4b +zRmvWH=%CE>^)o+<@i~LMp +zq&Am(^PW{{^D|-7{}`CI$Yp9!9sEsoGD_W#9dl5jIMvUrj@0(yzF)j5ZT>N2`q9XA +zZ0H`>Sv6RssUV1rOXer@W1wWN3_{%D{QsJ>$BVSVu>>=IW%SB4lnYGcw_d{)s@P+h6J8BJFa;pjgE? +zrnOM!yRG~{)_b*7xg%+*51E&i8Sl9ySJuWW8-!&}*?5P~Xb87vF)jHrf85GH!g?2V +zJD5B>Q)D_+W?XYgma5}YoglbmtnI@4Ztfx0cAM0+HE9_WGCxx$ +zK6puPs*X3+2`{_2f40jx{bM;}n6m{k|Am#mm9@?6cAPD=pDi^FEfWha$;)=cm+cky +zJ7w{1pEx(%GAR+b*Xh64%~i0roNmX_eEZR2Q#2^s7Da6RrN}N}flC%w`^2%~mdr%p +zxXXXs!%c3NTgJp%hBC1dlRYTgW<_jMrO3XdWl+#Os9e1IlAOCYo?9(6xVe?>GBYX0 +z^kWVc$^1Q5{!=zOOv>FOoO5v(*=WCRhpEVJDlk14lA{@sXtpHO3Y5{y8TYU3w!R+G1cDZw4 +ztaB{mFO>N%D?gHrUMqF)NLpSDnJs0a@siwK8}Duqwm4<+E}u9n+&Pg+!Sz2liVN(;C8lzC +zPOhW><;tXGPRRU5nekuqFI>KG>yDL4%fCbBA!WvbaN`a2KRBk9*r(;2e)Z||^5qMJ +z>VI$?DY73aFuhuCY?^=J^8IvotxQ@b1kDr5jnl)8x7PpQSe0*IRc!hKzNy}~RsVzI +z+XDNyC8o#Aj9zP;&KVWU8Nw_rk@*{~ +z{Hv@jOKNIJTIL1K^UB4WF3C;x@uuy9j>-QcOmbv?>skd9AC1YUO$3vpsW5@(Dkev1 +zOyDIdCN_cz3<)NmG!aaW5=>x-nAiv=J{lAFri#f?f(Z-}6Pu2Sj!F74$puW#DVVIG +zF*$^o97u)9A;jbWjma8kyOGG$scT6HF!tX-wdxj){&* +zx-o&yCpe`zqmWO6bkCYVf4(wM+YR7^GyOkjwZU@|$0m}rv827<}IG?-vAIfIJCOZix@J%(D?4&V)lR73kCTYgx|3GJQtAfc3G$xxcnY@w;6L_vBlUHa=;3X<1 +zYY8SWB$zym$>bG+2@ElrtRmRFlao1QQryGFhu*qGOVNOlATmA1auvqA__6 +zF-e(Bo=V(msM@&}Hm^_D=U^01*#sp64nCO_K8x!bE +zPAHh1*IPg3079#6*)!^gRiM2@DA)-(xc2 +z2_`VaWP*Dpr)W&zn`$!Q2_`VaWTNkx=$P~ZCW`@+j}=TbdnPX;CMlE2i-?IPnc$wu +z6Nrgs&*VkK1e3{&G$v0VCYn8y7ZDRoCNI*Mz)2kw9g}op0-ebZ3MM~lFu`OJNQnt1 +zlK_ngyhOzW_e@}jm|!vqASRk*f_o-EYB0fM5w8 +z@0pz1N-)Vtl}z5)N-%-vB$?cRdnWw|CI))XgxyLo8A_6gdn=7eKZ40Dde7vr{) +zL6V8jNicySNhUYqo=G*034BvYCP$qF6Bv?YGDF`p(J|=-Os)n@{-R()@0pzX17eaY +znY{4_#Dq>JH{hO00b)Y$nXrFAOh__u|AEG&05PHWOiug(F(Jw1*dJ(2;G~X;j!C*P +zfzG5x!Q@>HCM20Ozn&5kl1z@gPGbTuQ8B?i6Br^UB$@bLM@;BsawG1UysN>4B$K1B +zBPMh*nW68Q=$P~ZCZhn8KP#BfdnTuL5lre*CX-zR6L^lv1oup?K}_g96LuHDWDh2j +zT{I@wASU#l$%$PA6Zoc@Om@+jz)2kw9g}op0-Z^*f{B~PWDh12HWeoDTumk{jS0L& +z#RT_EU`Q~j!(_q|Okjw~1ouqbG$!y(HJPvk6BuGL(f3SrOnL#6Ie^JW3MTZP$*JcN +zla$HidBjAMOmNR+1!6+)nXu0zCYVf~r!iT9n9zGBC!R-4Fqu40V*)32Oms}rjR|xn +z? +zVh6zlzNsdY9W*9zQpZHcB+ZyS3!TX{1(T;~OzyyB@=_{H;JKPiUZOF9m#CQFo(T*I +zCQC4xyhJd8Atn>tGkKcE1iq;zla~l4FvMi?v)eNf<&PqTqsI^K)90Pff4WoQ%lF?` +z{`c|qv75UGnKm8XVC6el@1Sl+XOX?Lz~nDCPQ4^cd-PvY|G(*%)ZYl)oKd);H&ISK +zi`=BlF3%!2n(Ts`D0d?_^d<`XEOLX{xr}bY_|G(+RlV_n-Iihg$iG~}@F20o9V0Q7*+`vmz +zZg3L?hR6+O7aww?$u78w@`;8U%q~9UMw4BBUYjV%LYdbw`5D}JG667AZakSuZ=#&q +zOE5W;GP~?0n80()F1U#@7crqXQP{l%lMgYw?4>c8i;kRIDg~1_X-q!E?DASFOyIeiU0$OxftRS5;3f(T2_|PSySzp)fgxrW+(dbk +z#st2pW|!9pCNRY8^7Gn6(J}d%T%UC-V4~c3GLzm!IrRc!k}{dRfS72K32vf1jF`}y +zDC`S}2_};lXiOePOz2IN6E7epm`q-vF@cjhCORhR#spfGZxu|w*I%$pFAax$%V4Y@$>X +zOtMoZlWKwqJSWM7#Z8n9f{9nNiBe54F<>&OrZLGNnDClSlxl(rd{a#()ifq>QpZHc +zB+Z!o23nO&1(P}&69Xm_cPdQaxtdJeG$!y81rrW8QD8_g$;M>jCYZpGB$HQh6Qz#E +z1iq;z6F0#Gh9sFB{dsMo=$QOWFqsCJC^w#PnoX3a5tEe3aS#G0|+I)DcYJn`$ztqcMS#Iwm?M>Ba;) +zlL`fsW*QSOCX?n=n80&2nKaXwz)Mt2a1#ZF1e0b=Cd~vB7-BNPO_XLD6Zoc@OqvNM +zFvMi?^V&qwG5MKbk^`71H=b~sO_V0YBxN#bLQFKt1UFGC5fjZON)uv&$)t(Kq!KaF +zY@#$FCYVf`XiVUwj){&*x-o&yq*cL0(qMwgL`aDVCKG|i1YV+If}1EXL`*Q52#AR$ +zncyahq`?G}iGY}BlF83&6Gg}5XM)Laz(l$6gwt%I)Dlc8QznyIf(bmwWP+P0S%`^d +z6Q!15V#8!oOJkCSm}oXpY6&LrO*NU+(wM+W9TOdsG-DEm&Ll^{q>0AFhRNjRRG7eX +zHJQ9jV*)QxF~Lm~7!ph>F`2wfFo7W^6Wl~;qA`JQs>$SKf(Z;Unf$yqQFKgxCYa0s +zOq3f>IL)5Pe#9hYGTD!qXp#x;nJhz0G6 +zM8_oEm_TRJqF@ryV1miycuGt#nH;AvftRS5;GPK#5fe-%#}N}vGQmBQhz1i(CdUyI +zO)}BwdnOG8lPD&W1{#xG +z#6+`a(m*hQZ>q_pfyM+*>X_)5q#G0HOc(_dfyN|?$%IRV2|QPm2}ffBFHteUJrfub +zOe9Pu9Ki&Jm`rfbM4&N&Z>q_JBbdMtlZn1(qGQqvm@EQJlp9Yt&7R3W@hIgFTS +zk_qmaY(`8pdnShw6HF$DX-qaFCYn8y!-xqclfyJ7a8k!a$0XgDKxfjaVA8F@1e3|> +zl$c;LIZa~%FHteUJrfurCYVf4BPN<;f_o<28cZ;moJLGE$wc2X(J|=-O!{AxGd@>t +zJlUYxGucKk$x4|_wh>I=IY}l~+%p+SFtKU&OtukBCSo$#Mq@INV6suOXR?i80^d}V +z$u=4jIH_ZzW0Gb}=0j&PT*0K4#$+NU6IUus;JKPiTr?)|5(SeDxMu=Gf=L!86Boe* +zh9sG+#XXZ+8WZ@YnoL{-6Bv?YvR>aa(J|=-Os)k?lp9YrX!cB=LQGO7lcx|9I+<8; +z&!hw~(d?N#g_vM6d5XrQ1ToRJ?1h*Ir|lgvsPpf(Z;Unc$wu +z%QPnNO*NUkN-%*TCKG+nM8~8TFqsFKC^w#L(CnEUKul65lLLr}CYj)#$!f$zvuAPu +zF~MYVfW~AsVxrkIIe?g8GC4qF0w;A$bWGBX33MiB6-+K@Fu`PUA|)o6Ois|4z)Mt2 +zaL)vWhzTZ>6Nrf>nc$wu1q~*cOimysnq;Eyndq4G0wzNN6XnK}4VpcZ8iL8Pl*y!q +zU;@uEnc$wuSj0rLXHr8jxet>`4UNfI#6+`aQbRC-Z>q_phQb7V9T;mJ%d`~AeB8>9 +zV7=E$(vGC%P{?d5GaB_@Qh!O#t%>K>3+J5NF*Z6$%H1c-bjo7!|Egb7@0%_2TW5S^ +z-d1M(8~g|Vidg1V%z#4EJMf?J!9L?J!Xc_?UpsN8r8hJ+jVJFvoM935`-!C$FD`?ONijWERQvOH;7 +z8#4d1%-9WoG5W?DM=`4kOb6hbYIcFYQl<89^GvtG5VOnjq(yf5zjtvzw#yZLVii|1 +znFTWcu9d%r_1++5*Cs9Rh0N2+jK8`hXV=8D>xDB;?oHM^Ny^?QWIJVJvClXyTrnXL +zXm&Fyxy=Gj||Of5m#yCC8nAvNzwS~`Q~&T?b_aO;(cK$gp&<>98c%dJ<% +zT8A+?r7}O(%I{~rnNnqa(y~5iUSDopcuB6@7nimQxo+;xcDZ#ztaSjx6zjjFUj8}! +zlKMMOm=lYBfha25TXm0i+H*1rY2|@FO +za^v)H2}O0w$CUueHfB$10uF*(y|)iUXLth`NU=6 +zmJx}-XCD6oCs)tf#&kQ@m)O_mo9+wAwuuqjLMgH>X;~ODpDYtMgj)tB0&%xL?&1>d +zGSerkoiAZ`D@we4N`7x((*ybe0`btGr?r8%x^uaU~;bplLG{k#*~;GAec1L +zn7~U^OjZ$0V2GF;Aeb~FCI@ItRuN3@)nIafVA6<~9H22-rDI|l6EZ(jCO&vcZmNzq +z)d?@VxPP|GIsIcfW0Jk>~@?jw4W_C4J{K3F3HPw#FyDnhq-9XhJg8i}`jVWxH=bK9G`P8y?J_ed#`OEStToyI +zlZb-JdK!}!#N=QqOj;0=gES`V2_~N*ChKWTS`d?i1d|pTlg|*7^)x0eh{-{MNehk1 +zXF4Wwj{Xl}>Hdc>-yE6Wx?aI#0gcI*m`v(ZVFJ(9WKvIK0xwZ9SxGQ~A;Bbq$)uiO +z0z*tDD+wkGXiVUnYBH%On7|N|$x0m)9TUr4A@j#&;-*XT=56uKy9Kk06Wis^fw9i9 +zjK5IkyR7_3HhQhpy(4LPF=V!siN;HEcWu18LD=Gy#k+jstZ?TE8k3_0lP@uu9HlWij+oeJOpX#v;G60{ +zgdL?ZIj&=(V +zA(%X(!32}ZA;d(JOxEa_=$ND*6FXq?m4eAe8WTTak}{e25fe=^*+?*nBPJVZO#Fxm +zCKEr6NgOfRNMqthOfZ@FX-wieCORhR$D|56lgSDuBWO$(VlvsD3KMv)CX?+nCh!sk +zla2=nCNLzJ?$M8_okn3Mu0p`S46 +zu+o@#2qw8HlZl650?$b@X}1zg8VDv)D~*YVV6qUCiHF9dfnf5TmBz$FFoAEX$;3lr +z(x79aW6}$lKxcAD!Q@U2CYVf~Nr?$2lV@m5;3X<14-!mZh?rn9c?L0|lgU3HB$(W( +z!32}ZGl&VDOkxk}nCO_KAConJ$rlPH>u5}lAtou4$uY!)PA2W^2qxzclXWyE#}E@t +zCdX(@&LJl2XiSbFCYVf)(U_dmG0`#U1x%nbF)5hLq%k>($z)F|OyIeiO!m;2z)Mt2 +zRuD{JNH7sFnd~8$zz~zk3WCW@8WZ@YnoRZ(Okjw~WQC52j!F74F#;y73MQ2_CSHPx +zkTRKg2`2CylSw7PghNa!X-vEXlarWCyfh{pVp2(C;w6~CH`Qd~r7_`jOms|o0Tbv< +z+7wJSXfVNKaxf((m`o1Rn7~U^OjZ+2V2GGtGC7EtXp+flg2@IACYVePA|{$-vRcPP +z$0YrjJPMe!DVS`aF*%8tq)a9!5fe=^*+4MqKuk8!n4CmRFqxdBG3h`|Hqe-yL`*Q5 +zoTM@7&@s_5Nk1l+pfg#dU^0cq#E!{iXDUqKxtdIN(wM+YR7`Ns1cn5Y&6rGf5=>x- +z$prUIrqGzcH`QdalVAcvOeXrCiH=DxU~(5=@~MJ}X3yjmg30ET$>bG+2|UMSf_o;1 +z5fjax$twgCJ0_D?XiN?xCYn8yR|qEXO*NUkLSu4R$3(}Z7cha&#IImt)?k9kXp#x;nV2=0U^00QG0`Lwea}S4q!%#R2$+1SV4~SG +zc?&T~nM~e7Of<;^_e{P*Of-8YZy_d_Ox~g~`3f=7?3uiUm|!w_i^k+D9TOdsUcdx8 +zlP48S7SovYU^3a43KMv)CX;c@EM3YSPJrf<1Uckfwn0&2ZqS-SEASNl3NdPg?Boo{-Ng^hi +zJ(B=pg2^O6W0FKnGyCX-zR6BuGL!9A0!X-wdo +zYBJeHFo7W^6MfG_$D|i9DFaNx3MTZP$rCKWq&8(TVF@Pi9Fqy|nYa)Wde6kl5=?et +zGGS>`{>8O +z_ip`{)a$=jIIX`5@{hjbvyp7yY*(I@4c-O`KH*0wJ_ZQ{5UGcgd!Zjmr +zmiZg3Jj)ugq`JlDe+;Z}`d7HQ-~Q>WY*-L6jF9RUp8qlMjm!Uyhr5C`{MYX<%1d^{ +zm+Tdu9(J?LzhvbfWDP&Sa9e!IZsBeh7lxC=BZe8$lAF)}82H5FpX=oIvW8E8e^EZO +zH-4sCcyq+fGQZBs|BE$z0K?t!Gd04)9_}_cIZOW~^*KYBr6n?dqm_S^wPi_74N1$q +zpm|=oc+(}hsXpGcUAW+u#oK)16XBLV%#0$LFShExq@MqdjSlK|B#P{b0#l$|oO(&_ +z-V^WMDfHV5t;)3uH=}57N-?|aKyE|_YnUWu>=UkmgS)K!FImI)gD=W;)$zJI!R_MO +zul-0i42&42OLaN#{uo%{@qgpw-iG0nh+(m`WUDZ`VYbW{S@}P+hQAKJC@-mtFR2xt +z-Zxw3ud?#bvW84)$)a}&CUBBqQa_tuGMHcjKL}#-u8xVm)|mFS#y|cNFi~zinL=-( +zJn<62q=d>Yh{-PrCi~{on0!JoxfU_`gvR8T1e3k<2_`Tkn7~ODlTT<&en~KCm`^Z) +zA;APr>X_)5r1`eSz0j(76imuBm|%8!HYFx=2_`qtn0OGAGXxVDA|`VQCO04^b7@S@ +z5KQ1CVltOtasy&Am&W9bj){&*`Z2KrCd!Q`Q|L{UCwz!W%4A|iOcv0XLhP>NxCtCR^{&sCJ$*a!DRA6N=)VvOm3ku`8#5Aj$i^q#AF`90w;A$bWGBW$*-X^8KYn_gvR80OeWQ-FoA<=XL1FN +z$r!}s9fAoA2_|=9XL1F>`dO#G0`zeKPE+hiE`t~ +zVa+Crn_x0MWilxunB1l5OhN>cF^EZs#-xZ~@@wo&U`Q~5lPV@58j~V|$(`7lz>r`9 +zCv{A8Owx@BbSBRznEXnE2_}=LQ(}Uh$#pa)&mbm$C78evF~QE{I>bcNnf#St0w)m@ +z>`bmhOf;RzUv*4$Owy0ZgMf*0Ba;)lY10QZlp1J1(Qi#N=&dbxr)Z*9>nB5 +zf(Z-}6YNZ`LQFKB$$JD7IEk2GXL1!{qUlWD(=pL8Nk1mP0Zfz|PY!D~QJM)RFQ-f< +zzd=kiok=UfZhzWKkFeI43Nfnb;8k653CfJ$4kYEBQbxd?j(v1mpCZ8&p +ztkqzG$)qVICfJ$Gr!n~yF*!>xfgxgooymN}MAMm^C78fT!~{E&`G|?8GdZhcqGOVN +zOsW7A<;Ii4nmrQ%F-e(Bst^-RXVOM6`4ll}qcN#MOt3S7A;APrs+hFVm{cJq*qOkP +zU;-y~Oms}rjLApPnaoo#nLuN*29rr`Doo&@+L;WaF`0*${E1)!LxRaU>`aCcOg`3h +zCVwKBz)6D1S?o-P5lr9*!OrAQIwm?M>Br>PfQfSB$zjc&$;$+j)hUz7uL&j}YdVup +z2`2LplTT?(eoZj>2s;xP5=`Kvipi%mCch?_oWsrph6EEhsbivJl5R|(GdZSU@;ePC +zm`wJk!~{E&n`lgqAtoOZOkjwZU}tg@Vxs9xJ|vjHNyG#@lba9|O=t340w+~WzNRsG0x`kP1cn3?IH_ZzW0Gb}Zi3EasDjA= +z8k2FDOtz)M1P-d5Nk1Bsp#+nbKN3t}NHCd+ok>4}$t=1v@&A!v0w)P3Gq5x1M=*gO +zgmfmy{-|T3W0HPM3NFeSZ!0&Rm^FJQE`rI}l*y!kU^0vDOil+0CPN7(CxbL51q73u +zurq-n!30h!n7kFFF)1LJ%*4(Fh6EEhsbivJl5R|(GufkHQmnxQlgU#lF~QE{8XA*5 +zh{<0FCNM-yurs*^F`+vX|6d3ua1t@W&g2@zgzij^{YA$_$0YrjtN=`u8&AxdJ(D*O +zla$G11!6*XCZ|6qnCwAJKBqBRftX-t0z-lcoK!LSoW^7YVuGCs3<)N1QpZHcB;A-m +zXL5&v$ut_1=P;SO#FW)n7~QI1Ur+_hzZ@9 +z9Q(75iH=G7F}WKsQEogjYxYcDRWSMS#oyU~*{^@!KEHT=-8#*+3dduK64_}xw_PZh +znIrRMRzAoYhDjNFF8`AHyOA5ZRXH6d+}wfOglTT>MsBcGfg#}rPO995X>RUDZm?B> +zA>js2>fGquq?;RPRX+U4EW5b84?mI(vm=JVQbwInJ!78C|INx@$r}F8+>3HXO+2Gs +zc-P6je)*Tw!$I{Q!sgQ4z)O^0Qs43s;Rc4t4Yn$CksG>I@#Bpra1yz}R%I@7L$@l& +z^czofZhC>6hk={(|LUA7W%$nj80hEmS35Z;Yxo=hZ +zK1573H=aCr|VVXKlsFyS?=3f_1ECkZC-GpW~SWe`l@2f@kGa@7ci*=Od<*<5gHSCpklHh6(*I4iKbP-8&AB5 +ziRQ+WO2hhP>NxCtCR>h`ZV$)zUhhUPG5)*7y +zvS>`;B`PL(;|UBA6Kqwo5ED(Sf;XPPNyG$Ol`O!OkQXG0}7;c;gA2L`<+V$wf>wor!+q +ziH=DxV6qu7`AWg$D;g7cpkk7;Gue!oXgU+T@g$0vXl^{&jF@0&0z-lcoK!K<+<3AX +zF~QCRh6EEhsbivJl4eZSL1!{i!DJ$h$$IQe2ByLU4yv8WKpGQxiHZr{cmhL$$p-99 +z1``Y)tFoBaQCYl>hRwE|Z +znZS@>0w;A$bWGBX33Mj+DVW@+!2~;#u_-aZ&SWf&3A{wb1aCZnA!34^$ymfh)0yCn +zCvXxm!OmnXVxs9x^czofOnL#6djXSH1(Q}96L_FvlCm?o7ctRvCV1n?eTa$X#*=#y +z6YNZ2NHBquDkhp6Pwquburq-n!30j~nCO_K8x!bEzEm*zQiBP0CJRzxf}P0%8WVVl +ziV5C$0znhqndmp3=$P~ZCXWCnZ3-rBG$!ys#Uy2C +z@(5z0=}hp(lP?hy&5b9IAST$Ez>r`9Csj-|H=aC#m|$lDLxKsM)G^U9Ni!z@g3e^2 +zg2_S}lNfd;BT``k2i4AG1dR#2M8yPeJb@v>qysyX5d@R(G@S|FcmgL0Ch#+Ba;)6T5{ +zb|#Av6HRBL-*}>9(hHbu0ZhJDF!`Fs1RkiEr0h(#ASRm51aCa)K}<9^o@_x(urq-n +z!30jKm}qW1*@Bp0X97cl37ph1(J@IgCX=8u8Kht`h{j|xb|!sOVFCx$&ZIAm3A{wX +zguxq6U`Q~Tf}KfUg2`06GkFqkJb{x06Zo0b&ZIBF1bz_GnQYQ;Jkc@f1x)fU${CLZ +zf5N0HNMiyI6ilY1>`d|rCR6FoWDDMSGKgSe*W7rLPcWH;oe2yHCU8>0u +z_?gts1cn3?IH_ZzW0G!6pflO2V6sz#33et|r^Ez1ldEY=;3X<1c;g8S5fki8u0~Ag +z&g4nF@dQpHCfJ!=jhN7#$tL~A6CIOYz+^dK^0|V^=QJkpK*c0wXR;hIp*xc;c;m@V +z#6)xB$#TR5I};cZOyH!7iRQ+W<%kJ(CNLzJz)2mG{~u!_fBf2_>$Yv{)91>)>*+fc +z4o>{?&iKT{cJ9`Z(&payi&PGOk(ApW7Sp#q{K%54gBqxN=xPd0|5a|hBAoee_6J9C +zfxWoIR1VL7<1@|=XHI6`yQMN|nG-Und2eB5((><+c}SVDAl%r_ +z{@|EaVxN|8`qjQB**Mo{d^p_r4f})RNRjDzMSfN;gAL?GMc&-QTH +z?Q%tCtYSD*QEJKw%HHV_?^vn1K51csW~SV@=#t#LFJ8G-$Z~Tf?Q-k*SnCx`PO;3d +zw(=KP?|^PcOOd^$z;v|SIPsEPxhGz^Q;2wE;~<~0G~7CbVM=6vrj_Sd@5F8gQ)=(b +zGc5|q-fnknWC5&~+;tHQQI^1$qBCy}(-|yiv+vS$gv6c+xXo<-dlx;I2 +zw#m}6eM!s2pm}1sI6d4lArUz4^dEO~>)Yj)$+4FHOsq)eO;)~*wT+Y_dyA&l_I;wYb39%hCylS^fOjFo?ejb7F5I8F)3}fv +z9UY0zm4xb~#TYV+Wg-)1`X>S#-2M$N?#p(W85Cp2F>Qr1-(%$mvC*rg%{!8oeIdAP +z;re#DGwuIh8T@ +zi|xgQrck+YFT7+-EORLH-s06s%R@o)L*>R(Fq|4|?88heGVN|SARAZsjHAPim!AK@ +zF|E)(t<-cQ443$f+2O`4=E$w9la{q1^FPas-77E1jeTQ{qnK3%rUUTJu|DIy;l|kW +zKR8yE+P}>+-3r5*KI4XP;~?hSMXQsRAA;r|%8h+5$=SQ&**k;`k8B*}GnR)dhB29? +zGC$hNKh1it>UK1i*c8UCjymj +zf2E6yw96HPVin_<)5k9 +zwB*bDaV!4_>s{3CVDjutk?ByGam^)Js*X!_g5Z*kkNS)w!>wZyfz2-eW)HWR_0H;c +zbQan>OHKWQvh5cU+m%w*-lU~4Xf7-lXNPkpB?2W*e~FtbZMKb>@EB{y4meK84T5MlhX!^8V9Ck@=+8uAI5mtL-agtBGKb$i%5xC&-k9Bf2 +ztZh`cV@8R6M!xBekZhX}vE3>y+m^H#LS}E7SQ%~^mV>$I^S8?_BV#R7naO!Fzun3gveDVyj>-A< +z$;GA*%EX5*$+_F&xx0lsU9z~=Cr$`6W0^yRrhk-+1H#OxL|~@NKhwh*+GQp)#tdgn +zrKX#Ma&&qmI#v?ula@z==10rLMVDk@UwrdcVTzk8ZI?U8$2zC>4kix)Cg=Z^IhYx+ +zctg^XA2jEe8)t_ze|#G;q3)qWOx{LJ4$_!xAej6eG1)+4@-|{}kYMsQjmh5;lMOT` +zZzCoL2_|pTn7~OL6CIN@NBkGy-;1wTFd0K*au>OWPTG+Q6L_v-vV+D1UZP^MoL~Y& +zg2|oF6HImxOkjwZEGL+Zp)rAPs+jB`n7|M*S*~NEW0L-R=zay5e4=2omd4~Ig2|mJ +zlgUd26L^lvWG%tu8N_5Qjmb*{le;jPyhLO23}UjD#^fb}34BvcCNI&Lz)2kw9g}op +z0{>q8ih{{K8cZ;mJev{|OeW9Ln7~U^OjZ$0V2GGtGIj@^GA|~r;Onit5CKDfx$)||PdKwcS +zVuH!UM`Hpfbxd?j(v1oHckI_Fn9QRw`52SQ-c*>tb2XXlr7?k*sFF`29+n9QRwfp4nGWG}%4hL}uN>X_)5q#u*t0Vba*nAm7cUL%;COPNewBbdN* +zOeQvh$uY#lMq~0C!Q^91Ca=+$979ZOG$yYROyHYpGI@>01WxLh=$ND%6X;C-p+7gAz^$>aqZ6L^V=$r^$Q3=tDdCNCf+nq;zuV6sVr2_};l5ED%@S)*g3W0HPM +z9tTXmQZU&_V{!^HNtsMeAtst+vXNkN5i!|FV{!^H!DMoZ#^fSmvXRE*6k>wO-_@w=2;G1ePanqQX_)5q#G0HOpFR91{xC{lSy4FOyIeiOzLP%;3X<1D+neqB$#lROzH?GFvMiC +zf?#5xF@bNY$)t{80z*tDD|AeBOwx}@1z^&uV4~SGX(pI(DU(Sv!33UTGQm9)FJhwE +zGifH6@R&@RX-vF`iDu8FnP39nRFg?FjR~C8G0`zeHzv@Thzce)4JMdOno?qd$)t(K +z1YV+If_o+~L`*Q5G$AIMWP*DpHVr12OqviAO)}B_zn7}vHWKv5ofgvUnea}S4 +zq!%z*3YdJVV4~SGd6{6cA!RaonP39XF`3|=$w9J60w;A$bWGBX33MiJDVW@+!32}Z{*;(tGTBdK0xwZ9!95cgA|{wj_9G^m +zWP*Dp_h~S}WU?PI(IgXn&qT+h7cf~5n0%>VqS-S!j+mrOCdUyIO)|kflP?hy&7R3| +z!~~PcaT=2^5fjax$#KL4lgV)!6F8}3qGOV7OrSG)RKa8+jmdYIOd3*Q0?*ZC(m-PZ +zFHteUJrfubOgb=`G!RT+h{*)^Ocv6Zz&F)o(m*hQAtn=j&qT+h7cemaCZd9gX3vBp +zm~^B}CLF;8o?|k>J(H7&iDu7)Bba=L$%LaZIff9!32}ZVZ=m}O!Pey +z9g|+b@NCOwFWX3yj_VuH!! +zG>r+I)G^U9Ni!z5L1!{j!DJAP$y7`x+frcy&(&nIjm89CqF}NG_e@|&FqwkMWE;T* +zh9sFhj(aA9XiVUnYBJeIFo7XSCQs^nCORg)fJxy+IpaUUpD@{?*)wqwOs1qvCN6>r +zJSWNIG2AoRNieZ%_Doy^lc|_YTr?&-2__EBo{5WK0^d}ViHpVrPU@KGn4}vM=uGx0 +zn3QTT!DRAON=z`BJVj#yFHteUJrfurCYVf~LQLpn@;L69lxi@+WbzbZLMM|a^*s|E +zlU~4NC1CQof{A9&vw;zj#`+uHw+;)83`-d22^tirYWM#eLA8j1GxJZ{EI!@toCHo5Q$Edx*IwITb%waZqC9+Zx-b4?eXqCLciPQc3JvPJ>c)> +z;{LerqlEEFpRp{QIgA;Qng#?D#(bag>Tt#QHtKSRD!HOxtYS3NSkPrT5;CtUGyX1IF@k9< +zHD#6=i>u^{A+d@HOhtYd^=s?f9IZw6)&f&YC}EuJGn&E`BikIUrS_aW)9`ZRwN>PH +zhc3(6p!saMacGs?Iy%;x!L*c^)&~>D`+UZQ;npc_)bFjYl3NGFS~D4@u*=dGGA}AK +z-c=>H4vn==WIFRrPlghguXkv33@@?|FEDKnCB!RzVp%w67&E-I%W`edd~LaSLshC@ +zT;FARCTM=9T)e7E&dH2*j+DB`F-r@(ET4wV^UB0uSIId;V>uIAqk>yw@i#2)9gbbHwuOu_DvSGI2wd+%hQEGLDHAc3FBt=0Rm*ewEA& +zjxpnz$@!+zP(qyJ6CVmQ{n{LditL99Os|yVFR%|K!~s6BILr)bbC^o(rhJpJT+FGG +znaMGxKhsv!WqB)Teyd!ZTqQH(V$4XUt<*F!m=Ftn;;8oWeYrXPO#Hh}ZkXHQ~+yZH_04?N1h(z78eCkv{RR +zaOY4aQPO2`1kH|e*E>Qg?HWD?^(lbQr%YJn#BvcEKdc^Pn8>=g?D5}3|UfLgRtVZ1zne~LV@{+h+(Ew +z*Y){%$9tvrX?dn0@E?T5|F8^Nu6M_9KO+ +ze@;Ev!w<9ads)L6>CBIxpTB$;3jFzhS@}t<;U6nE$&Eu}jT4z~^G%P#pMS#2|Hyj# +z2;`QB9{w6D?`FN@rR;`|z!Il_iJQB-J?Whv@eY%+_XuZP-1n@vpVYjogItD^^kzrA +zSyFR@Q0eU9o2>jY*1JHEo43cC_Xv`!hq~sWBar3sH#xbN+mqf25$~;1<+hH%GPi%3 +zi~EfA4j0I6C_VfLE8oC+$4JuNj)36w3vO;hd(yiw;vFPOyE~|R9t2t18JG461D!qm +zHY=ac+GY!KR&_k9PN;Qp|J9znd>u+hpv2>U-^snf+9pX^`-JIEZg+dqHacRPD>YSj +z1YUOglldmu&8=-u+Hxbdfl|}%j=*Y{f3=6ZwLNK@8L>@~n)V4}ojrVwl`m#(a|C%= +zb$nT!u;10ge{1D4S=%&eSxraaUXTAXC)d)Rv`voK7DztqZ~Wo<(RIZ_vo +z)C$KvJ^W-Ve~7h>lOpvUfwG*cP$&eL6CE6 +z#()3$yko!7p)s*nL9I*cQ*&Efg%8(`9jm%*)G+zYS-OU}{QDqsokb +zzWzeeFgjwGE7g7f=kwH^C@`NMF^rY!5`RALcrV}nUa{%lhoA4^|6}E^U=3GGOD_HS +z{N<~IUVOfXf6&VRAJ*{Rm`!ry=vZS0bEL$y7XG}?%2%<51kA~$DDdZRvhuI7hA&}0 +zIo8;p`Sytw9f5~k{)au>ZLHxtn5+MfTbE@($XruqTwWztToJ3dipeZAy%$Othxm-Y +z3Rh&brMeX*VVveOt_oKSXmeB)+bar9t>wnyRdU6cSjAALwWRCv+m*mdr-nS%V*peZXLvQ7I#?^L35&9>{BJ@Tp7z5%nUE-qV7d$bJXYA>x)dDU_!L| +z#PQ*ru}poT>F?#@72%vwZH}b{_N67Jdx8nLKInEfY6<5IZ*wdywV%y1%?l;On|$KB +zaL%AM$Jt{0*+SFBaC^nOxju`5 +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 +z0fnY_EYJ7wS6cZ$u!b@3upFail12C5xBrJm +zVXW{ObHWvqnby26OHRn#Qf6FVMJ{#hvUG;b!^@0?;nu-zj+_#EPQGbrC}EuEGj0mE +z_G_c=KCO~l$HrPmFfFBBmdQc${rKV;rsCO%L_Uw)bp2m8cdhI2C79Q7sk`h3&Ma`BdM&J<>8o@q=d +zAztSb9}MRVXoG7V6WfJkvFX!bLag$M!@@aZ+8k#K>}N|%n}P}PexG<-IAn566XF)1*f-2v+2)vBV4qxK +zDlHSst7K+ajG4q7%ImURA2PpECaw)L1DQj`rhk-)k5|b|-xxEBF%@)Ko(q|cWnx8` +z8Q$hFmD=0#OgD!T;tZd-KFkbibF>xP+X_uxp1m?!hQES8Y@>oW1tD!H?N +ztaA*LC@=*=32~}Vw1hMNcI1Sd@gLs}O>$+0flwSwEjjfeTKea4%@nLRMy9iD$M&w +z4A)9$b_jC=^Sdm+3z~mdZafb2g%QIb>C6wGoTqLIhWXTp;dUu|Yeyi%?ay#=@3tqs +zgCpJ>r0iOu&eL=G4pc$Tu8(JL7tXl3hgt7!Qu9_J+ug%2vGQkFZ-yW@*TtJ_g=P*=|CSFj*U4RL9ku-VUu;VG(n6OnJeDso +z{~zVcX)Ish9i)6Yh2;y()$%1mmoG3^%a;f#U(A~FB|^#7>ukn#ooyjs54=<)^r +zyk5TOFYiP7vht_$C7>x^>Ph+HPg%a)jOEMwbol~vwS0M>lrLXt%9r;^`SLZE +zFB9qV1^&ERzQCN6FYxEp@&)E<`LdEOUtq46FM9dXJLSt)P`+$b%9pq3@+E-f3(Ws# +z`SKYlU*H{BzI;Z?m#?vWxsNVi;Loe&%Y9hB*y!>F=4$z3qsteVtL2N0lrI}K<%>-( +zU-a^&*UFcLP`(^e%9nF=`SK{1FXvK~FJEK%0`DN@%U4*wz+5d~*3jk4LM&g_kn-g_ +zP5H8hlrJ#H@?{MvUtq45FNf&z1?GDBqL(kdRK9HN2=qIxlrLXv%9pQ5`SMlD^2Ltj +z%SO6N`J6*oOTrFR=lk(*W +zP5AHheYRY5?&fPlcbkL0?5MifUO2??WKG;t==Bi`<2r%AK8%+Zln +zntfjs43e;AVQCWR!_r}CXxe3PLBT{j_Sm@0a&uWBKy3w0x<;<;z@JzO3cTmzQYy0&`rx +zcxm|pb94Dp&zCPSSIZZ*d`VC9 +z%a?WBGEJFJHp6e1Z8tEnkwf +ze1Uu5^5r5eUtn%7U(WL73(U>s%UN8$%$1feXL0%Bm6k7Oarpv2Z!TYE^W_Wtyjs4f +z{MLd2{&!b94D3HD6$^mM?1glAh&D5|%GsWBC&1%NIe*7nuL^@+FGP7q|y4 +zU!u5t5wv`9^5qNsyt#aF((*-WzQEjEzDUg%n48NNYQA`-<%?>*sO3xAmM^2`jsNdt +z=I^}wnnuREE(*50(J%g<%&v1}7uxQMWL)%qa^BgNTxz^dDY@P*4u9L@pZ_p(29pQB +z66QO|y!)HH-zF)|c%QyacqbVziV@j<(fHlF#+xpao9yD?ckkl6Va4L6a8ujk#tSf# +zw;oN3FGm{5X8zG+_`6-BJv(yjy9;e)A~))7_->o|>vZR{ZQH&aN&h||e8)`ul@fnW +zd=&JWE1K~8=fgoSek!JI+mYn4uY~%`P5tGTp1<6#uKV2E@haD)&T{8_*b8HSQjUMQ +zb-c&wg|YMSFSlNG{4Y0{8-KYCti!+D+Lf^v#$Hp0f4Q|U`~HQod87DWZt(NQUv4kM +z9RG5IpEv$;dkW^pUv5{qSZ8@Q%++6R>MytS{N>iJ^gDgteBS|<$vlddpFiDz3Hy2FS~5Pe)ulM*+VmDegCnF_vco5 +z>$3h-x+1u`isT{b20U`(%UnR*2}-K(tS!HlrzcK8+LqBm +z|CvkYuaosPwM%&IqdoQ<`|I_hsY~qA+scFfDiQ4#h>neDUE9L5szQG)_aAE%T94*S +zZ(p|es25E=V@*TjbJFmYnNj1DcDD>Lv+;}5pG_wldHz?G&w +z;`_H_CfK(yTJYt|!s2azZTN0~{xVtd{oBiu-@mK8g})pVKZPN_fA?~Nz3i_AU+pj0 +zyJW@pFE2~rtI7p?H>QYsUHV*K&B%ne+bB=B(e{OP!hKiFeMS7z%l$?4=|J>~NLH`5 +zaDGK7zsk>FU)CtHdNyZWsg2DS`fVe$wZ@GU2^F&vSdO{eybp?ijoDR{!8HszkJZAUZBm+r2IPX;lc` +zTjq23PIzbLduC?apQ;z`0WtRj@!0&N^MQH?d;}v>+qo^=S{Z7s@V7Mz?XqU=YHeVS +z(BF3H@KXQyh$TtqyY-G+3!)FVh!KlhrEkUr?Bkh}N$y>@N?&TQPl2BNE;( +zMtQy%Z9iNmn(mD?b&m&ECY|5bIp8gSk@Hu#g$GrH237fQZ4~EI{mHTpLxnys+d$_> +z{F7x1@%xuUmRWtW49<=3U*5cof3gg2V*LNobf1{~{+lr{#7~wj!0%t)vkX6321ES* +z<&_hY-@oPWNBomz@J!?XmFD(k_{lODVyNjhG5P&VF6Z&vI%duF`m_<>^Ig6_cby1J#pzBL +z=;RhrwxG34VFIrv_eUGW`A*H}`)HwDp?~Yr;ma5C#G<5gTfM_s5Vf_4#FEy;n&8}W +z5q&&x=}rDxTei@{F5Tid^NeTWI16DGyU?>`k& +zPM8!Y>1CKd_8}$<@%xuI_&6rzgh_Fd-W_|t4>5sfnwa=FCUB*~L}8NR?_YMfTj=xN +zG%y)2VS?Yk9J0|86a4<=%^Nu;a1#@gsfY;-2^0MO#h5I*OX%~iH!!)HW0FhBWRVpn +zaBe1(MH~~jiHXSs!~}+jNe(5GMTiLuDVa<_Os?jbz%$KcvIsGOAtjRu3KNA%>M{8# +zU}C(dzx#BK$#%pf$1<60M@-%%?VveC|$uS8KCX`G9 +z9Fsc2WG2TXK$uW632;o{N`;BSB-NO}&SZjt$z2?iw<(#dvcd$;&1ABQV*)oZF`0yz +zzz{Kci;~GI!~}+vOeP^FcX3SMnPxIsg_yvQlF1~6iNYlHnEVnj`P9I~%`w@7n7n0~ +zO!goqa8Aj@jhO5sOxzrkJ&4KMluY(;O!g5bZjQ+w!~~vcCX+oJ6Sz`gqA*D{Ca^R4 +zy@AQo5+;;PHd|ss$z(If1a4wtG7T|-Az?zvWHVtRC6j50$q)rZ7>M +zq#l!B114V@n9Syw94AaHlgV+yL`o*J5tIKROlEUTjuR%7OpbF*{)aG`%`rJnm{2k~ +z&M|>26($Ok6k{?Pb|yUyOs?RV+(^k}ffXijZYGlj922;SfytWjhzSf4lN%_REI>?P +zh{Lk}ljV~Ulb=eMP%>FZnDAt>da}YqVUl`G +zCIcp)T}mcvq@KwE!o)I}93V`1GFe7FllKS{sb_M4Frj2}fMfC=VIuWR4iF}kOb&2N +z;7Wyw!X(w0z|N%5z~sjqlPXFkE37bqb2FK&;F!QoOiZX}0z<^4l9I^^!~}+vOsHq_ +zV~z#lSCQGa^ +zfpasNEa8~IO-xLvX97dSWFjS#C5Q2@JCkP&Ozz{D{E?E$8Y@iT+)O5GI3{ot6BFv0zz{L{ +z10|C+hzSfSnNZKFL +zaue)Kt~4;|z%l7f$z;A2CU9;hlldGIxQT(uW7IQ&A!5>tlF59;1csPQ9;Tj22aX9m +z(@ZAw5fd0+Vw)H7Lxm^>== +zOezqQ-jqx#I3|k_lgFi=Nd;m8&oq-s1;+%g{6S)poc8IUb#IKi?6ND~x%5SavuDiz +zJ~Y!4t{>T0b}o=B^j4SN-B)vCJiaLD+*0qb7uakqBEF3azokWRn86E#N>vWC@>^$D7(B$-0K_cL%-&Rj+&My^jR+bufCej3GeyQ +zp7S~OP@!#bi-@mOFRA|_eeq->aASP&FEc3F;?z>u;FHBoNjn7}j5?6Mp&fgxp=A7&FpVe)VO`K%`Z +z6XS~~k4a6G-H6FL%j~inF@bZ+F4RQXPMAndl--EQdde=lIVRf)6RC-^8!>@rn%QMH +z#{{lan5cgdmg;{I23wW)4NN9Wm{2k)wZw#yNh!w!Zen6WO%xasCX`G{2@@%qP!nac +zgb5{+Qo=+^CO^z3io)dI9Fu1O6XS~~k4a6GqlAfNGC4|^NXdknDF02ENKKTZgb5{+ +zqa2g}CQPIz%2C3ElF3ny30$c#QJAC{lkKooxy``j8ji`&D48s_!UWFEWU`oJ0yi-+ +zp(Y9p5tAnt#353`A)F!?vfS1L>tCaJ~*b|%veOzz>Bd_u`&wG}3CZYGn}922;Si3v4PV2GG}Ovz+5Vgf@- +zCe%c^hhqZIG?U3{!~}+vOn#V66otvZIVR%(6XS~~k4a6Gy@<)jmdRu%3fgvW7_o<0;6~_dgX(p3} +zhzSfanVkM%Hc=EN|K^zF11827PtHh9lq$qzm}N4lLQLQslgWG3L|KKHd>}PZst}XA +zDVbDpOjaQ#A4yG=D#QeyX(p2@jtN|;Fj1JK8WY%=lp2`)r-TV5ll7LEP%>H1F@c+y +zm{89IhJ*TH{o}#Q5UL8L4M-kT9`K +zCI<-%ViPSSWNSIJEImj{jkT8*YCI<-a*QyMk_q)p{z8~YJ(FXE +z2_=(b9FxBgCQ{Gj7-2%mG?U3LjtN|;Fj1JK +z8WY%=95pccF9{P$Ca+s!LdoQHjtShv#Dsb#FeFSUnY>PzNXdkHCjTX2LdoQH!bD0Y +zs%N4wNdqRc02AYjCugLd$zj68GMOAEOr&H&J(JG~6RBr%m@uJaa+qWCIbkC8Ob!z! +zluQnDOyEj|iNYk+n842DMFW$ca7@loGFfYd37nhBWG%-8Zen6WJrfurCjX#hvKBFc +zAte*)nf!!f0?#y)$y&q&hLlWH&qQI82231)iSfmgGg8k)M@;@-va-1-cdL}wz0?#y)iOw;BD-|XRlT>2@JCh3rCND{tP%_zOi3uf> +zZ5$K0iHQmIOkhZuP%_y@m`KTldL}PPm{2m=Mwm#+MDY23Tn7}iQWU_Z2 +zVgf@y85!q7VMvS_RvB2Ki~i7%h@eGg5Uh)WWD3&0^7qaV#wmw +zA*+L@%KZm?HP^+5tPKt+7q+~B?dC{PzqW97d8oS5U+k+Hk?=N*@-&RL*Vc)edt)`- +zV36nj5atvc?F#k4xX+tI3ELuTDB=);VSt +zs+ZJ9uWu0}R<({;5L{E~pVTO{>zcK8+LqBm|Cvkw#Mg9He8kG&nF{|oUsJn;*FO3O +z^^*F_&xtO-eB;tLQQ&|0*>#TWLfc)DjN|azGs?4gw7mlUH|`49u8m~$(H7_0e_v?p +z5XsmNzdbpgynK5hoMU$R@%W^3XuV^9f$cBw+tax@qpx-{b9~bI_j<>b1-6_>i4T5z +z@;x_a+aHGCfnfpLvyqa@d7K;g?dj88(p}qe=lGrW0`~Fr`9H&9qSw&3vJi8h#{+5hb#!LsPs>46h+rH7q!z$MhpE3 +zm;SM@=BoIRmBCXL{(tyt+9kY2qdi4A_L6#0(NZgbO+r)saSEM9RPTZ7nZd^&{^m@mi3v7u65;tYYO*wH>#<_7NouVT2j|%_A +zMp1NGbJ5jWMvlV*5wn0s(Mwl?YPT=(x@YrGyXdC$OPGRNcnanYHg)k{aOkUxbg*(K%K-K0ZmV}V +z3!=6bkyz52SQDIEE~1YIqIX8l5764Og&ub4USH;@o`A`33`{0+OqL-gD=d@AGQ4ajtM-|{1;(9!~}-) +zFT#oyCJGbh$&C +z#4?#|Buu1aG8HkINSI9Jm~13WD4A^Jm`o&0rgBU+5+;;PHgZfRDohk6X~1N-(C3{r +zF!_Uo2_=&wmY7g7Il?i4o0yo)LQG&tm{2k~LYPR&WENub2MH5OCPxSpDVfYtm?%tA +zkI9vQ$y){{6F4S|5R*qNlgT2)1kNd$Oh8O}5hfEjCW{c0M=6;s;+XUzOeSzl79l3^ +zOf#7*;+XVOm?%tAkI8GWGr8HoWF5!kQA#G;tuTReGns7Xn7~a;Or|3yFhooqp=7ch +zF@Yf^lj(@bI*tiE(@ZAY5fd0vGMTP0QJAD2liL83QwAneI3}+VCYH(MHNr$nCQ}fT +zCkT@%9Fx}w6G|qpaZH{dOr~&5UL#B>nY_j^c|u{LFi8U@urt|VVDhnq2_=(&B_@#iHXTf!~}+f2_=&NVIn1ynTW~95+;;P0)&Z_OlB%f6eg+1q#t1Nj)BP}j>#&- +z_@6=L!MC6iSglVOC(B#y}{!~~vcCX-bhlVJ)Ig-IGP +zft|?|1Cs+BlMg7F?6JZG&dp@9hhqXaF)?u?CNM-yPEj)1gP6dOl8GBJIlwW2XPU`m +z4`KpCN+xcFiNYlHnA{JToG~zÝUm{=y0&4h`ROr{|w&k`onI3}A36G|qVIVR5% +zCet`3n+X$2CYw1X&niq5CTYL~b|zmNnEXS+gp$c|OH3%49Osz8O-xK?BPK8;OemQg +zCrqSdG8-}ZhlB|wljDSmluTwTOcW-m$D|`*^5!K>{8GJFp+vD>j)FeWU`Jh;mO2DJ(EWW6RBsijxeEQvW{c&2w@`iOx6)5luXuf +zOde5~C`{6T3G7Tt3`|Z*m{2k~V2KGOlLH(RxQU4g^-N$$m{2k~K$!4kvYUD)rzA`$ +znH(TYcrw|mdL{~!G+>een4B~)k$NU85R+=lWU>M=fpbbG)H4}Em`FX76^Ka2r +zv1Kw@f|$TLB@^nI^e0TDp2-r##7)U$3CE;AVIuWRmLMkZOf#7*;h6MSm?%tAk4Xe} +zCRqk1WgHVXC6k?2n83N2Om=ci;3g&})H8u0Vp2@WWG7+*LrNypGb!Vkz%$KcvJ)|Z +zAte*lGf|kN0h8MSlMf6`q@KwJ!o)I}Y#>aeWI{cYafFG~Guc3xP%_!TF&RggNIjDc +zgb5{+4IGnk3KNA%8Zd#KNv(lNOu~ec$stQjD487Mn7~a;OsHo9L&AiT$sxi-N+#4Z +ziAk7HGC4$;NXbO?OcW+*z+@m`@~(l2)H7Lwn8YoU$r{82&MBEt&twE)BK1txASO+e +zOxAErMi3@a&twf^0?#y)$r_Hy2!)BlBn_Cr&O|dX335!DD4F=JFoAP3nfN&-a1#>~ +z>Y2b0F^N+$@gpWMq+~)plOV?go@pi%KVkwyN+zmjqA*DVCJzE89~qcPJ(I13iDfd` +zN|;E=gnA}(2otGivh{mR#NF;550C%RWtVk$d-eC9Q!u})u)Zx{l)KNY-wr>V=ear8 +z{(e)buyqO89*LB6(RRQ;>-0Lu^g>&3&NrfDP;<%U+LY1uQut??8nE?=l+;nsJx3-A*s@C{|V6alyh6ijfL>k(+h38a;=2ZB<^wso8 +zc+cl~&ga_O>V^BVnEOZZ{)>{%h4qfyf@nb`>#DZ!lB!UCx&PHhk=3O+tG~87+dio< +zdS4`KkT!Od(3iXPhkfp03Gdi!&)7WsCk4@8wTQC$t!2xDQ!7MtMj(1!B&%;*_?wE* +zH&y^F?oW6_qdcL}cD*3#ZV_`9w$51@{IWtsJ%MQF$oZby%Q-^-$fe)uYsyS` +zU(WTsJjOnkxMW4HI0m9 +z?16(Zp2ef=*EekvwjT#Fc_XW0JM=~l-T=3?N_T=T*Uxo8)0=Az=GP-Gb +zI(#~)&M~ymwkPq8$QaO^(OEmW7d{=UY_|n$(<4Qlw30mg*9Ep0BSn|Dg@;szhE(`ZHHxB+%|#hnQLeqAUet7o +z)!Y)VUYvB+);qKUo4rL;FKw+}8|+{1U(zTVu4rz!R?Es3`c9WV)mL+W!dpAaQ#;ze +zx4`CZ5ycBzi&q9?6~g8T*g8iVdTLsZ(9gK^JA5^n39pvx(Z<*xtP?f2#%lV;)Ph54qCT7``dNGeP7JoA>My^(pgpKs49$J8_DXU +zti+agBHYaOvH +z*u6qTCj_EBBic3Ez+9pK(WUqHHQki(Zpra%$+u4{h&~z7x@%j;*!$LrrW;~Sz2d=D +zNvEyOVJnPgMYMr!;aTOOS(W~$8ih8XS?jEQktcMIOaIQ-ba{NvvZQluonvibw0Db` +zv!Zp*lHk@V5$zg?J{mdSMGNH%eYi_M>}wjB@P@{CULIv1To}EzMI=_WCKd!wREp^E +zK=g&k`Sxw$xs{>075=Y$O+6CcwmeT;uKn`<8-?wSPE++!zRaiFpA%gcw02n$Oy=6( +zgoCF8wkskT2j*Y!F3#~R&bLn}u>CTU(Op|S#@-XoM+a;-MKX@gzu?Ww_T=T+>kDix +zoxTwn?VB@tYbT4xC!PE29nTclK8InC=8VDG&74NPv7 +zFeyb$UbV!e6ft>~W0FspOh!y#NSKr&Ca)4EJekazjF{w0m{2l#l`!GSWcp- +zia92`5tA}XCc8N%I|-9wj>&Gs1fFRolieH>xKd%FFiABgkW8i;nA|O4Ldm4m5)(=$ +zr5ux~gvnII1crnOC6iLZL`o)85tFGBCX`G{2@@%qOjVdDOj3`@QNU!Dfr+#;fddm0 +z%VcttFp-kUEX3p+!ekc5b=<)w$b2FJN=9u&$OeP>EFhoqAqGYldF@Yf^lL?4PAC3t;(@Z9d5fd0v +zGMS(-QJAD2lO2G`^h=l=mUbp^U|{l;Wir`;n7}zDlj(@b2Et@I$7Ba$GLDkT4vxtN +z!elzfWCvmb&oq@2_=&fj>#_wlPQP^3<(oT +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 +zN@n^mc&CiKqpeZI`!*AKzRQHZ4-r +zzAao_87i*u#~MXZ=jNimT0^eT6E3}zujcxA@uH-2b-iP3f$e84qIgMb@tWYca$$Qk +zV9Sg&^w(;$g?`ATKkut~FyYlkd9=~?Ed{n|Eh4_4HNGMktPr*r0=6EJhTd)AITfKf +zRsM&3HFqYw=W{*h$JpD~3HOg;?yKYdS0$afb&lM^=v|Sl>)OKk<)Qpae_^A@>ffBz +zNn4#~|6@V)*O9EtwXvgx{;*4b-{R!7x$lpUo1b)M);nqnqQ#NgPHo{&D?^`F +z_|G?r+RK}3dulUt?3?O^yKBsy8ILVVI?vWS9w>-D)*@nyTVtz(t>ykuqp0oCTsv4B +zI7;XXU3#vs>8^x#V76yqp8ef|=rb*1#QfF~%Y%(YDpnr@6I7A2kA +z>K)F4sI5gLmb50;1m~8E=;MLtosshcw6<)ahh4hYm-)s|&WSGfee{=%E3}SVrzM@) +zb&l*p+g*{2m$qK;E*|AsJlbCIO{uWC0=8=-8GW?Hx%S@|+B!rsp4ocAo0sFs%eNQ8 +z`OgEkdmdcnJ6v}Z?-eRrX)?8R?HNuTDD?%IxR(~{19b&h_8wp$`4 +zFK)fyos#XDl4t)6p80&h);&`4+|~=;uX8+K=i6T_uzd+v_Gm5{tYwT6`U01pICBwvLgao^9bF6`>(j{vnN` +zD5JTkn^rW&o>eDmZi&_OiC3>qI<-27R%m;$MO3eCEuI(bU+K?p6b;ulH+0al@`OIs +zrGMkA>6q}=j`q~%*!LFN2DFIcm951~gRv@M>m0C+i8NfPY579G!=?LuH3Je}ZH(vq +zDEou;qNZ=GW_UclFqo(mwvhpwHR_FD63q1#>h7e057cx+|T +z`CXmkyTa(@En>v7))9+>-K#{jXCPV_(XP@4juCoqm%iTDbWOs$CEv3p+di!@dVfS4 +zq}fN=`__x5Ua_WO@!*1_(^l_@7DTm(*1jz~t1>jJ!hg0=oFDuz#$>qA=bbY!xgcS( +z2{AcgiOD9!?)VX_G^IYF3g;+V`vOfE>6Y(h*<5GI>ACbJbL3X{}h +z((at-a^#Imm^j9BOy(mdeKuNQG9NL4bHwDA;}MgNh{;pqIVSTFlfD}flldHzj);kK +zJjY}{Vgk=JF`3UXfh!dz3X>EklmEC!=<~W7m@MX)^rd7{VTB2to5`etV*)oZFmbpL +z6Br^UeJGh!ASN)xWb&j7FMOJSlgNj)Yv04DDlm`vuFyh@l@ +zCX-hQ6P`?dIT4Juh8eM +zG%z_SVM57dza=J=O!jk3;3g&}GY}IP5+;;P_7f&NnLIfIF*zw=Ldj%5VZxJ%eTKqB +zVUl`GdI2WCF)*3PF^_UC;Og=O)naVLKB}^=nNhx6>C6lR$ +z$rQq5D#xUhFrj2p$}yQjm`vrEloBSCOiDQ>aHYaTVUlW0U}y4yfyvhrCX`H$T4F-U +za837k_hnShvN5GE5iCW{dh8zqy)9Fq*fWCF)zF=7JGG?U3O!it~ +z0_SEj*~>A3o0ynT&jf~u$)}V|_97-Qq+~)plUj}mJkv}jdl3^DQZi9J6NO0{Fc|@u +zoG~zwdL~;46U$_>g)otl3H3}g!bIwsY#~f2nQY;hXoQK>Guc9zP%_!VF@Y-;CJK{O +zV*)#qCIgf65+;;PLYA0NG6``^;3g&})H8u0VM56yM3_j)gnB0DB}^!pga{KUnW&zL +z!XyotbOKD?yoAY@QqN=|Vsfu#GFgb2z&R$9-%`({8)9-+>X|G=Oomf3S;#TzhM0UM +z^-LBbCh$x%nJna(z?BLUg-MDrnE^YK0R|?kIVQs?nN(R}0_SEjsp6QxO$3 +z5tDlp2>Q`#4?$z +zCro%U`7QNK#u6q{&tyGeLdj%3$7C#FBK1tx6DE{Q)^kkYN`;BSB-NO}&SaB;$!Q4_ +zN+t&_F`;B~kYfTjF)^W@2@DAnN+t&h6P`>yqn^oW2@^^t2MH6NOukS(6NO0{FzExB +zoHQ_zdL}ColS7utWF=w(=afvSXL37XBK1sGA|{6^nXKfP+)kKCJ(HD)2|UwGCM!86 +zaHYaTVUlW0U}y4_fyrKu$ze(+HCC9wxtUCAI3{ot6BFv0zz{JxM9HKEF@Yf^6Y81l +z<(R-T&16!8n81*diRzgsOwxeKy@1JS0~4udvWYOUOeUKM6DgTc&txWHBK1r*5hj#O +zHgQa55++j5WD{XR$z&791g=z=C`?j~3G7VH8kjUom{2k~W{C+UlVcncxQU4g^-N$$ +zm{2k~Mwm#+gnA~;5+;;Pju9qOGEqGfg-IGP=?<8@ZD1nxOqL=h&s!#wrHBcfQ!=5R +z$w0zH>X|G>OkSX5vXo;okT8*YCQA_$c&3?5mU2wsN`;BSB*mEg1$HJ67?^C~n7lyA +zWS12taBe1(T^tj*iHQmIOkjwZJWt7F7h(cKN+#4Z*}^e_XPU`m7h(cKN+zmjqA*DV +zCU*cP9~hWOJ(Jf76U$`sI$ep8iJdT!dM2+ECX`HG=a|5i +z3KNA%sxg6`$uR?yFCzcK8+LqBm +z|Cvkw#Mg9He8kG&nF{|oUsJn;*FM@~&#}K=FPgfRzZ +zOX}gb$9PFS{0^8esXxrQf!`kECG}s;Dfb`rHC-1Uu{L-|xrpWkqBlpher;iYdB|Vscl(+~B)ngY +z@_aGcez;CF-TSY7N&R1j3VojE!%JU0d60AS?M8e_{aPz-;M~kEYdJS?6O)@sSZjnK +za?`pIUsAsoxq%^Nmq}P_e2{Yk&or~kTI2?XlwBsNTI0X6*4Q-i{|-zXfJxNA#LY3$ +z5tG(3D@=661kMQ)H)0YZOxzq39WnW~3^CC;CLzMa%`wpt6L_YHiOw;BD-|XRlT>Gy +zyM;dQI|GxKB}_^YlWmrmlp-eEI3{ot6O(C(2@DC7Qp98%VN%L5nTD9WEMZcLm~10V +zN;xLe6ebFj)OY0P0w!M>n9Sywgb5SNWD+J!q+~K1F=-=AW^+u!gb5{+Fvp~gFqzFU +z2@@uiOu`%!xKd%FFi9~c*WD%bd7TYR+H*{LU^0o%v%&<$3o@peL=6Q$-3^AEJI9_3*FiAZo+2=%;U)Np2fPvu7n9DllUu^m|!yb`W21|+{DCWGGYQl!UU5^%PWKl +zPbT+IMoe-gOfZ==ze1SsWb)u-g^9u>^_WZmOnz%%GJ|8Xk1(-HCV$^YnDAtB-wed$ +zZNg**$7CO2g306$`#2_V6DBh_Ci@5zOeW{{aZKP!g^9u>)tJD}WQ>8yjU1D;luVXc +zVFKr7GFiqkft#3^Ohimzh?uOQWU>q~fgvT6iHOOK920n^nM{@;CNQLAGErfoFiAZo +zg@8%Kz@(UC;zLZ1O@aZIWRlVXmE4>5sfn#sh+ +zF@Y-;CJK{OV*)#qcMVJ?NtjSF*=UIgC6kRD6S#?q$yCGyhJ*|Or&HoRbiqqNj)ad04ARsn9Sms93f0BlgSanL`o*J5R*R=CbKvuM+g&2CPz3X +ze#h7e{oyn~RCcQZ(k5e*PWQ7Two5^Gm#{_O-Vln|S +zfgxh@7$uWMhzSfSnM^=TdUH(RnPxIsgqXmPlF0;xiNYlHm^=)ad~9Gconx{cF?q}~ +znQTW);GB}lbi`ymVKSX#vK=vboRZ0Qj>&q$WID%WJ7NOQG?U48jtN|;Fj1JK8WY%= +z>@qOcS{L`o)85R;!tm{2l#jWCgt$rOc& +z!X)*WOb1M21}3~`axp-dSSFJIVIn0H>Y02(nDCxSV}LNBWD?+*d_tJ;p2>v(VM56y +zz%hX<6($OkRAT}=lW7JfcXLcWqGYnl3KKXtlgTQM3EafQgnA}0L`=?5GFgR~z>ty& +z^-S*On7}j5WU>k|fgvRm)iY6;qydvB0h3P+OnA@a;vU50jAb&}gP6cMB@^nI93)J5 +z&!lk=V)79slRX@hgMBWGB9~g!i18^W=l*c +znQZ2mz)eg{sAmF0!i18^X2L{DCe$-|PQrwe$!5YtN+zmjqA*DVCNBaeUmBS3p2@}I +zgo$M`IZl{J$%J|)=Li$tGif|dm{2k~&M`ShnDCy-h2w+?C6nVE6Sz`gqA*D@CjSLH +zlfDKfT{$LqQZiX!g$bOS$z%b?1a4wra)Np$Fhor5pk%TDF@Yf_lcUr#>B=#IXPU`m +z0b&9}OeP`KGf|kN0h2tyr2Y~nC#0T9C1P@iWiqKmOyC@o$r0+AtVB$XNj;NF#NX}p`Ch$x%nN)I2;7Wyw!X(w0z|Q1#1CvK3OemSGv&4jw$vTb++{DC$ +zdL}R=OemSGBTRTQIZ8c~Ma)2=5 +z$>a$2Ogty&^-KnEOyHSjGFgI{z>t!O>X|4^(tycWz~mDH6RBsi6ET@(nM`&fCU8#4gnA~M +z2otGivJ)|xP03^@$7B;>BK1smA|~)mGnwq8t1<@BH+U0HGJ1RqWRQNw=6k5k-Ekm>C+N1TNsZ*@!mUwV+(s{Vv@j^k=-Xela +zTZ3zZgUbC&8^!r6n$KUWJ(w-@T`ql^uj&4TH#Eu<8g17LqV5(kXJPA{mBBA7MAQ?A +zc8;9yslA*d^p9NnoxY~bg!koK&&y-%BkM%dt+A%Q@x(+GRjjj+Pv{o+(R#*A^H;SU(%|%_chJ2xqaOpu`&7g$0VT>nhl)YP_ +z?Zy^SysEW$L9nb+*zOM4o{KcJYYUI742`Ssf9k90mhjf*d1`a*&Gn+DeXQojczjWC +zM3u1h4cKgvhHh=)U{z>NxqoY;Xz1G9FhDz>ZGX95G>r_{Mn)P2w}m^EhdNdIvl~U$ +zwar-_v~GF!x9f!azL>j1y#Ml~v#QQfRT#ZClGR6BoooMNVYEYwC|lNAwkUW@m55#w +zi2gj1)lC~aM(F)qda2LdC*eJv?>U`qf39A*2gTeE#mCJH_Nf%n8v@aZk=hPz;SH6c +z4Hf>c8%1rq=GtD`-W+>Py>NGnxo?k;Tbgt>)jI|hMDruHSGI-ktqL6~_wQ{KwcVO) +z2Wriugucb4+kNig@z}zo(^K#Gt{^(MMU0r&I$~L{dxeNj2t<2Ev}?41xkCS=OYiM# +zx+&q^lH=KuZ=Y5WeKMkT*S3tY_pK96H^iEH#e=JoPFtPBRv68SXan2Av&uuWD*aD2 +z3T;5M)>-=^Pv{<({++Ms^7x!(N$1)+$J)YZ?-ns4A*EBHU4UO@<=nIka?c2h0D?@WD{9pN+dL+DU +zd7idh`{lDX3ELZIr|P48ng28MoanNkwabd&f(rld4xbj89b%a`#k*){FNSlfLT{D( +z_xUofi+5QYyrJB`49bQ=Wxg}>oLI5Eb;aV~#INoZ`h70_ +zh%fU?7_M!7WL~gWrGGSBIW(4eW&DvjXD^1=RfN`6`LBWD&9Tgk_#>->AAf$Y&;u_0 +zSH8@)ndii*d9A0G1&3AmKZGCZ8q3U#pL+i6#qfcu(6itNC$!$dcfSDq*`aV0$=H)TJ%_NLA=mx&MH#=DPTh +zwZS3f{uPa)=*s4zep*qs(5qc~v9D%Cyn24pnN{zoEwIgO5!DM@t5*i&6~gv%z}7y} +zaJ80|BlLG%`Ypbi+Y;WaTu;^*`|Wk2=H^&UM!a}+Fjg*XPX%lbL>dOQg-4W!MpXJA +z^VQs)@M_r}EzkZ%ov3*rR?|5iU!HV^>Kvg$+u%q;-?nfv*KnPgxxlw +zgh`gdL?x5dCzGv!$ut9#yE!HwAtv8iV)7AU0_TLu-H6G9gvs3;laCM+xYESrBaX>~ +zgvs3;laCM+xYESrBaX>~3KNA%8Zd!m@|}Un%N&z$36rm^FoAOuldm`?FB2xi5fd09 +zCUB*R$ybO83<;Crh{?+w6Zjz$ldljH7!oGK6($Ok)MGOLg16&K<1b+{@-Bu+@(skK +zhZQFO`vzhH=ZMKq?m|r3BPI{t#V~1k12KUs4NU(22FIj5Vgmn6_^-JxzJZv)l?Emk +z-r$(DSC}YFQjf_XNG3}SOmaCUJrI-gbyk?bxq-<)>NqC3h{?!%5EB?8CUB*JNumxh +zfgxh@lY0=8T#gC+kby~S9by7Q#N?rS6ebFj)MN50U^3ajgzrp}?;$2@EiriyF@bZ! +zgmxx35+;0S(()c+0#}-tyvH%Qkuc#qlZ)>mCUB*R$$K1=8xd!FlSv$t +zwS>uUtuTRe6O-R^OePT~v@?MrVggs1nEVzofgxc+JCjKq6Zjz$liwmHFeFUW&O~97 +z227R%CKC-z_|7Ex8^q*sOH6))n7}zjH6O#yH +z0z<-tb|ydLn7|L2m_!g07!oFGXQD7k116<_$y5UqzB5UFh?sn2iOGkE37iuqv@^Mz +zFyT9smJbmVxYESrLypPagbCl7T>KC*fh$c+KIE9(tuRrTqyZC1CVw(8d5&Z95n=MV +z6((?QV)8l1~>V*)>9V)8L!0z<^)gxZ-XOwxc!31DLMOv2L6

6}TViqwF@bZ!gmxyG +zgo(5>IfaCShr3 +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 +zcZXE(>k-#E#6Rl +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 +zzCc|IU-qx1!-!7Vdr +zFWh{o(!!V7S>a0*hc8#;3|}g6__8nS<_pxd@Z})6`7)jkU+T%t7pUvui;oUppst56 +zK017Xx*onjT?=2Tvcear8{vx)zVuJ{@;rnuw`k$Zm2~(rn}jb=|4I0AfZTk6zk$P- +zz2xQ#)b;S?1v-3zx*oo~fWw!HtndZuTKH0(6~4TH!U#Kcj1FI*u7@wj=7pUvuOA8KP +zd|Ba33l3lWBz##+hcB>S4_}~;!xz}Ehc8gq!j}VCH(#J`gfB+;(m&yg55kwI7QV#k +z@THoBFHrw!_|k^M7x)__d}+hsi=TuqwRHFb`}Odp7Kbl;vu?gXT?=0hW!-#%x)#3d +zCpTZBbokO>+RR}M<~zsUy7saG1BR^s_Pxy;;s3ex +zKcVm9vuazO{ih!>1A|PdTr)f!&i9Al`^$V_YPZ`|?P@Gx=R{FpQY`E9{_5dv8M`TJ +zYqT&MI?&-Asou|E2x=VF3{KWebGN&>)YV+cCL<`YJl6Xa45`?Qn2kYZiri{Shb3=F@(VNL +zsC8npcNhk{HG%>+!~(Na^-#t>IAR-YRW9p51qV{SANLm?h$Hiiq`~ +z!8-?ayH{7ZR+q6aMv*f=*86o#=`BA}Mg^7IWb?>$_#uDjyhk_^N9M7~-mm?!BcsSU +zKIUAYuGx{X|14_z!lL}51FhMf>iq_W&>Bb0LzB&uxwp%a*y#}AA5xYF +zdp{-1Ew4agwL|=rPmJhxFRyehFK54uqC{S-_tTh?&5xAnLFInAb4)sX&L4s=FY}3s +z-R`YbuC1l4J&F?3V~J&I_x6l^Wz+^=l9fA$rNbFtDB~3dENDSRYj4v|Hg8>^zPzmM}e`kgwo`mtr`AeT(Zg@Cz>5DN? +z#9#Jb*Mu&`GH+d=zJLLnba)=lT>3O76!9R8^-V}|JH&tEi&l2KO(iZ<1zQ(Ef%&oC +zuf<69Uc@{RWJbs}6Vl;T-cZ(OWQF`Vsu`cG8Nt<5A#tulgs+sVhYx1#=7`N~W#)CD +z!wsp!J0;bJnB~FVuP$@u3M5uJ#N&KmM7P^q=`xqIEm0K6i}ij*R$Ajn%=930zuY<| +z9gg`!@R4#pFtOXsRk^rQmW`so^jKh-s&3ENmq%^z(Pg=HSUTM83w3*iOdOd9B+cWv +z(Pc>d$RWZWi{#E3 +z>9EZcg83JG!rbi+mAXQe><m|iI^{qcQo0V6r(ECa|t!vYE!@J%Y(=7!xRB +zOuiwQY{r;Ckzn!~#^gO36WF9uF358kiU-lfFNh +zJOP;eT*E}5G5Jq|i8B`_u&!g`q%jdNCVwF(6DVR#{*z$h#F#)4WAbNmG7)G@V3UrC +z6Jr8JjLBb&lZk;zKVb4DV6v$9Wb&7+lgUPm$ul`I*@!WLb%F^wnY=+T$vT;A#F#uo +zFxg0B@&>^q>twPKV*;HzCL3u?-Y_sRFzI_t{sEZ$n}*2;G$#Kdm^_vX6Ij8J!JtiXnlQInxFOA7AjL9lTE=*uu!{k;6jfodyGLf82polTq +zg)v#}z?eW0V={r9OuRHEut~$@XAX=B6fq_fjgyIiNk3rn8DOGiCKKtC$sG@3Oe%6> +z@*u_p)(Ix$Wb!=0gg%+9dJtn$K`?oc#^iZ|34JoT{XvWgbn2KqNMrK6fr)`h-(#{5 +zFj=Qz@&_7|PY5QDa!q0!4B%S%)#Xl3=oq +z#$+GH1b!1anXJQ@K&Ot$IvSIG1||k3eUHhlfXSU2CcmRG`FDcJrd*i7x{k>v8k65) +zOkN}>6DVR#{+(d531b39jL8e+Wb!*26WF9vFMq#rOj37BY^$%|Ph +zlZP-S59Y+=A&d#E6HLg-fk{7L^6|y+ptrQlrTFiD2>ojY%EG1b!1anLL0ofleKh2WU*{3``76`W};O0h3i4CU4T1yhJd`dCvsa +zbxgAEnY@WHxr>}kpolSfiC{wRnLrU^awj>Nyh&pMn{-UbJrgKmOztvHCI%+`fXNBK +zM9WO>$~u{ldnR}1#Dv^4fpvljIhiyPOtMZUtdj}3X9Ar%CRz7P +z8VyVgO!^*^-vK6@G)$UlOk{#d&U+@Xu49sQ&!m}PLQW=7#F)qg6LQZ4iUbpKGHIqU +zflWFl2`0wL#K5E6&t!26&!jddCgh$8tP@Pg$>eo{N!H1P+%u^qm}K2Ed7WUAbuuCMOrTT8BjowU +zCVh{|-vE;>8YUqclMaGO&U+@Xu49sQ&m=@JAtw_kVoW*+Cgh$86bUBeWD=q=flWFl +z2`0wL#K5E6nmvCQu}p7$*}0lYYSD7+|7hChumQOvpWx>vCd3?wP{c_0A +zK?6$WpZSK2ROp?p(9@79RepW-qf357^?OqFholJ}Vb__HsAznwXo0%wg_euq7kr@? +zyux3hm=`OWqpqrx?%cQtiHjX#kS}7F{D@W^N}bpyE%XVu!KOvAqLJ!}rk0E0cf6r@ +z{K5<q3+BlX5d>ihO1^}lQbZkD>zd!#`dmLl;(hjpls@(ekMl)0tM$-$g)el4SNIIp^J7JG)%x9%Z{t!V +zPIZW{@J07L^&_fpNY(F@{`}BVBtGL1|HT&#R9C&yb}>A`8=Bx3u7u8OV@1={Rd2Li +z4BzPq-RTqV=8L$eenhKwrdI8jzJlM>;SfjhMYGitFST6^FZ74r@d&?%&grqDW$KCN +z+b)KG;S2r3E1czv?s)1)bYj2pk$Pj|N#9O9x#=V-T07=l#myI4#{7u#52W&UNIQJO +zT3EO-Ry0J-fA#3aaG5t$<`?GkMc1kMd!!f;r>B33j(t^f7Wi(#K9DunkuQ1_iWn2<)G;}VF@Yk+~aJ!xn9HMdKwd0&@uTU7bdW- +zWAX)!$@K)2g%}ekVoab@$K(r)2^0w?3o$0w)0n^}9g{CGCQu}pEHp4NFzI_tz6DH{ +zXqYUaG5Ho_awI1v-(pN)onW#AWAZ4$WC@MQw-^)X)G_&%#^h0g$r2iqZ!sp&sblgj +zjme`1CI%*bkIA!u$xIECnKUM_pkwlBE=*uu$K+EQlbHmQ1sD@3Voab@$K+Ft2^0w? +z3os@#X-r^~j>)GO6DSf)78sZqnDjj+3SeT^Ffr4ZC>WDxb7G=kOkka0V#b)*2qtD4 +z69r=eojN88jfst5Vx}=sFecEcW1`TQ*bGbzO!^*^3xLTA4U-i#Ca|Dm@?|beU|q-L +zOB$0E1d~M=6DVR#pi{@>ONmYIB? +zm6?2pF}aWvlkYGluud=`naOhmldR0-JB$f*>X>{-WAYrqBr7xd4r2nHIws%Im^^1- +zVqntunB)N_12s$r(wM-4hRJ;&=E4NlHB5f~A&tpEjERY4CQ!tfK&OVuogZRMpolS< +zLNb$qG$yb~!(`2e7!xRBOePtbiGfMqV`7P13=f*DWhN#%Gr1>%G0Dq?2{h^fJgj3( +zrjX2}6k{@(&P?u&U`(J>!^9S$F)78Ez;D8t$=wl*33O_hSR*thr3NMjCVh`d9bj^~ +zhRNkLCa|Dm@>woSU|q-LGa8f22__^nfg;8PI(1Aw!ncVXY#-uJMCf{I8V4Yw>GLr`gCUj86|=+rU!hQ{Op +zf(f0O-2Dy41Uhw0zM(OBz`(@7r0+4Q1Wd+jn2e_}fdw6tPjX=b>pCW%(3p%Tn2^i_ +ziWn2<)G_%4V**8j3CT>x)0n^}9g|NmCQu}p7@3KINk3pB114H#VxlvXdt{7BWll_F +zj0vn0Oh{&8C795e$-Oeh1Uhw0WEvAI!Gz9C?v^no(5Yi0)0kKdObkr=9+P8$$pQ_N +z1vDnGpks0}7bdW-V{($lWC6j1WF}C=m_VnF$w`a}6bU9IGg&}m0-JP9PGU@;NH8%n +z69bcez~n4oqGcu~Iy1TFEXL$mPE5{XOkka0LNb#l2qtu9a_?D;33Te1oTV{&f?z^t +zCU>93m_VnF$ypkcCk#vsO!^*^Ie^Is4U-WxCa|Dm@^LOqU|q-LV;YkY7?VblnLrU^ +z0-ZW0A7f0Qh%xyU$xKGjn7}3-laDbbP{f$LWMn1=CjEfPR~N&BUe+>`#;nZbD~!pU +zoS1xtF@bfA$*)Leax2E<<*dx)D~t(r>X>{*V{$9T1b!3AOuoXHK&Ot$S2QNK8kiWE +z^gSkT0w&jLm|RO^0t-4OCvsr|>pCVUXiTmpn2^i_iWn2<)G;}MF@Yk%gk&by(wM*| +z9g`Cn6DSf)jLgKqq#rPe0VY~z(wLQ*#4sjr=ENk1F@bf03CTX^i6Odd8cF)-+*{n83P@$#EK!X#^9J +znLrU^0-ZW0$1x^QB$$xQWEzbLY|=3~jxm8E!NkZ+3{3g~lhc5SmYFnWWhSRFCL3~M +zavEa->jV>$ncPP($;wPlV@#k^$K*7P$$bQqtjy#z#soTbOit67+-G27VAA)Pd=Hr1 +zq+xOsjR`F1n4HRm39RdwoT4$giC{u96DVR#pi{@>6vhOK1QU{(+(csnn{-T0VN9S% +zFflR{1CxHhBa8_YF(wSjO!8<@1=L@_4NsbdnQF{#9uz;7a%NfcuOojN8_8k0%`69bdJ$D|Q3 +znWJGchsFdJbWA?ag$bZ>X@9NG1)*c +z$;wR5U`(J>$K(u+$p!-x1CzeTqy{iCX_%O3OkhFB$XEU_vqzC}K>Y +zQ^({O#srE46Ox&jXiQ*}j>$2M2^0w?MrLAQ(g&C%+z%x$A2DjkfNg6Z`8I2=!rP-$ +z)6+YJo5rf$4N}H~6njuvDVsb^7uxi9M+khopQDVoHO|<#Nr`bhzFVs`m-&_`r?b?#2>VV+H$W1O*ny0;ANq +z`=t|J;h%h9ka~D;#@-mQHCh={2RdAzI=ovt>=z2+sAgiaW+c~Ig~VcqDDi=r-R{ZIM^E$O)k96EGjNqMDbh}rVxmH)PcSVqMZp>Mr +zHXW26@*w55pmLpTo}Lb$_k_;-glFT(JS*8efSXsr?vEhnf|zrJx~4v3{~}`h!m8wV +zpf&qaYwDzX{DL`-nkOfl$8c{~BXP7tY~Y;})!2cI{r-sUeyg&i1H}%eV%w#sd`P)I +zs5~k+595-RNZjfW(|lq;x4W>yRanOEiK4{tSmGMBc(-)WkCYKX!hfaBf +zclpE&wfK;9y+_y|N8E@cH;rRUkr;4@PCikrO4~E`rBU1a7G-k>l6Iz~{ZhLZDO-ce +zV7YS~x4aCApE|^=`NXx|?&amK<<;yB5tNt{OPJIx4bnLeQtl5b%jC|P>F^3qXoXL> +zgHJ5#c5f|pZLMU#i=f1^SYnvky)R=AM{LL|e8(rocDvJ+u5>v&@bGJh`A~gGEa8hD +z=YB-_J5u@e(hjfiU#%^uXh^K+N;SWx?P9phANtrM{0Cn&L(M-VUEvY-!uo_*(L%NU +z&bEtTpD*O|3UR)uiu)1O?@QI!N$Z%UNW9S@{wH5#gW{pos%_E)pHKmv3t~kh)KzQR +zE{0$5hF!R%B9FHAr9Gy%dQ-hgi!OZRLJMC$^HdVMxWo%s(1%}50*Qj%MOZ9%l +zj0iHf$~F1v@G5`kghzOX56n>K9+KvIg!(wD8Ii1+#?_P}@vuYO#0QGi!`m}UXbd?V& +zR|b^_WpiFS{FX2DmRI;2?;P6gZmDp!l(Fwdk#kJUdA-`SCu9FHY8z=$%H-zZ>F{KK +z=w*-aW*jw-N;c2n-Y!96qeHCWoo02-&Wzm|wIwXdmJSr#mWu6_mUxAhIBL#IHk-K3 +z`c;vf0M%x-sEwQG3^JJzbq?m$}(q_*sk-tZx1QBZkO?i`d3+k7FLS5WxG=x%qY +z(iJLae~6;Q;8HWFDA-- +z8WR}cpkZRpiOErn39MsG7l8`8pRSu&!hBHI2z?jES-sV**8t33Te1e2p=I +zBF02sj4@eFV*;CWOuojLKoMhdda;3tfl1$E@-kquLBnJrjR_2J&@gGviOClj6Idsh +zEX0`1BbY3tG5G>x0-ZW0U(lG$BbY3tF@XUN8Ya-GWAX)!$vguS1CxHh1WqO~4U^3@ +zCd~wsZ*yS+>pCXi(wJ-}m@L7VKoMgCojNApVoab&Fj;~z*-T>sn{-UR#h5^mV6w!( +z#K5HQF*yjBtk*DEKw|;}95hV0oS1xyF@bf0$pVZ?A;Dw;jmf7N6X?`2`IN?_kYKWa +z#smg9XqZ5!j>)GqCWQtj1}1%vi3%qZNyCJtG2sX%N-j)bUB^VBF<}WNW{e3GF(%Nd +zW1?V8phz$=V@y~Y6WF98J!Jtl7eCL1+OvN97G;GkjBnG=&QF($B1 +zFd>=Aa)L=#X7VM*1Uhw0zN9f(PB6*JOkjY6h6!})n0!fNvfRMLz@#5Afs;wMhRIeM +zlTL!kceyZubsdxMXiT;eOh{$|MT`k_>X>|oF@Yk%gk&aLX-r^~j>&fz6DSf)jLgKq +zq#rQZe!-ph$l6{^meQHYIT+xeVKO=wCf|IBF@bfA$zqb3491w4>C8m_5Mu(J8Ya;X +zX-o!VOyD<-x)i{lg#iv4CeW#2a^^!Clfeci1}1%vNdcTpc59fF)0m9Ln6yT6VFK$K +zCSOHpOv*7POG#z|MT`k_YM8_#7!xRBOcs;Oq@2bCHfflgj$llnh%s4WWF`hC{ea2y +zfXRazCUjjV>$ +znM@>@(3y$+3C09Ebxb~?F_}m(p)-@SFu*~>1Uhw0KA|z0XkcPs()XA&!O7$;4U@ZQ +zOjZ+2 +z$Cw03W-=0E(wvo8J!Jtk}5 +zWb(3x$zI5+WAZbM$@?TTfg;8PI(1CG!k9o2V-h5p$jV>$nG_LBvNDqs7!&B! +zF*!kFQbaJx%1mH@gN6xo>X@9MF)1=IF)--|OyFd4TEoOiWAZk^B$f*kSl2O$(U>?1 +zCL}X~BE|$dbxdLy6DSf)NM_=sF@a4wCNYc&6bU9qW@2E{512FnCfYrd_p>q+7~r5` +zvNV*;HzCdX+^rV~uEG7}i!pkV@?Iwr?yOr{%{7?|`u +zCNVgfyr*GuKaI&|g30Mzn83P@$!Qvs`w1o_Gl3$;1Uhw0PGd}$P16BogR +zWF}C=m_VnF$vKP(6bU9IGjY+Fz$P7&a~KmS5=@ND#K5E8#8I1~_P#yq*)2&oL&jPB0;v$<+jt +ztjy$dj0tq=n0!uSay7vuD>H!s4jLxVsblgvjmgypCI%+`fC-#TPHC8Iq%nD&U~(oG +zCa|t!a)!oaBf*4ZCQ!tfK&Ot$8H@=O2__^n*+^pon{-UhU`(J$FflR{1CxHhWIte{ +z-7|SQD>H!s4jLwGPE3wrOkka0LNb#n1e2`HTI(1Br(U?pjm}F%pFu*~>1Uhw0 +zj?tJ*F);bRgvo{9+~>Mw(BOdsE}NP)QQ^!t?XyA3`=N;KkX4!3fwt7Aw(OSP@FQhpQ2CkMna_o) +zkhs(#zRxELyWOE`*VYntmQ}gB19cxrb?=Zq@F8VsPkawd)~XO$>Q42>nOQl+|#{r#xzX^X;kAZbrZIwZ~X2z%nFb9l0ID!058 +ziNAG-8~Mad-R@9{D^$UX7RA|tw(Lx8*)N^*BE=O{hRL1dxvgbL{L&%bz$c2j-CN6D +zTdUcX5tO((mYDLtK2rZ0aHHKsc{(dqArnv9a&ki^p1?ZchNLP>2{&1(3YmBUojNyJ +z6Hk^BZn9DpGVugDb#AgIo-8%E`9H)>de8q~FoCm6yN1crG$w5XlbjPzU|q)~YvRe% +z1QU{~KoMgCojN9D;t3Q9CL~pPn#Ke+>6nm-Cr~7q7^#YZNk3q+2QblYqI6}YDrDlx +z@|>8Ei6^j*G3g+w%2lP869bdJ +zKbdTSlgS$zCU?-7EGL-coOlB3Iwn~YPwv2&bdgjAiWn2<)G;9wPoRh~=^&}f9W*Ae +zNymgtJb@y{BxR&31}6Q0$*%wt?IucBR;ofKo`iB@LMEQTI>CgbDmM^JvQiZ?@dP?` +zOtL1P+(0nNN>#|j6X?`2$(nd_gMo>GNk3o$CzEp;CXdmWga{@%C!WB%j!D+Ulg9`q +zBvpYT#soTbOvuC&C=yIas`40(32f3aArnuaNH8%{6$6ugz~m5MqTNL4%1Twp#FMQ# +zF(DIAV4Yw>Qk7W*ldM#QOgw>39h0nyC$k79S*Z${cmka|CRr0tW*L|mnDjj+-EcDb +zK*PjNW3rWCl5^q-tm~L$O+2v^Oh{$|MT`k_>X?v;Cr~7qkj%tRV*;CWOvuC&C=yJJ +z%*4Q?A29h1V4~eb>B`DX$i$O$PE5$e6Idshkj!Ky!6Yj)ArnuaQ^zE0;>k*aNmgb; +zCZ0g2j!D+Ula&T01}6Q037kwa8YXTUlQh93=fo3O*D=YOc;Y6Qkjw;%7!&B!F(DIA +zphz$wnTeam1UBiIkclTyB$ybPiGfMqW3qPJ1$W*I?Iy}tIx|^8CY}t=g~^R%;t8x{ +zOh)0%BsBnIGMdgz7L$o5(5YdvfS!2LG5})&zX@k1Hih5n}?K8YabL;t3QnCZlj> +zk}jb!flV4FOUT3%C}K>;7@3KINk3rnOTa|Ci87YXOjeMICp&XuLMEQTI>7{ICaKE^ +zCUj=9m`pr@P8}0^;z`S81QR+lxtUBnfleJ0dg93sml>ECnDhfCa5DKw!(=Uu$xebv +z&WR_mu46(^JUPCWV1hG~b5O*XK&OrgnRo(4f(gz{(ralGg(X~or#F#**jtQA~0!4xe&P>ve)0n^}9TPI~1d0R` +zBQr5D=?6@90Vdi#lS5gV37L2@J0~V&;t8x{Ob(FDWH`p8AuBT>6HlO1$Aq4E(lQ)l +z0>6o5CS>9Xbn2MU6Hk5^ZeU_y()XBD!O7%#4U=1FOlA{Ia!x#fbsZCW;>qz_FeZmc +zW&%Zw33Te1kclTy#F!i)naM3QCa_7zgiJhvBF5yPk(n5n^aCa@0Vdi#lS5gV37L4} +z&xr|{cmnGL6Ox%+Lomt8OvuC&=+rTxC!VxiLomt8OvuC&=+rTxC!YLpje&`QNk3o$ +zCzGg#iG#+(PcX?j@dVa&Oz4Rx#~lO{l9@meV*;HzCS>9X6bU9IGjY(Ez$P6NGVuh8 +z1QR1OF)--|Ob!4h+C7s)S(yo$c(OhxCS>9XtP@N~W-^svl9ic|i6_vhV?s|nX_-ne +z$;wQ~#1rV$F*#0sz3Ydm1||k3eUHg;IGOxG!{lBXll26XoD)xAUB`r;cyjz+f(gk? +zpolSnP8}06@dSzl6Ox(SOJf3?bWF&^6DSf)jLgKqq#rQ(HDIFMGdYx%nUIMmf60jn +znRo*01QU{(+(;O*$rI;t3Q9 +zCPrprVA2nm?6~00`?Yq@S +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 +zX^7X)5 +z?IXDEQX-OoDN)JTyGY)Sc-}r~xRc2Dd*$&VGHzDm9+#7*beLL%!YLGTLiM-J(=ZCn-34f>4*Xb5U@X?vQ_NB$PrDg1$0TR6?9G$9cJ(x6K +z7cgB{B^yHBc?tjL4&Uc4;n4``o*wHS%xzoFJ{us>h2iLErMEF@{vu%dqDmguMS2_J +zy>-%dw{UBObWe_TkK?lb_F&RHc=1!dAx`17r%n;W$gtsRCA(hQwRsT{$6Lf-@rKa4 +zb0oVdp1oUo!zKKjH{7B$?vSq7w1|j5vWV~Th7;?~k;cY&W4+{Z3sYc|*D*fURQ-J3Lb2TeJZ +zOi8GHWWt~4_O&>K=OUziOsxGfuC0)Whb`hgyvL~2>`t0D22HU_#@0oY9dTu!w8SZ# +zj*#}OSbHwVl@PJhB2MQ$b9(LF#kTG;c3UN5?jpV8V(sI&?s6gywun1<>-b)KPMIyI +zh%KqoG5P-hlevJ&{uCx}t1+2`n9R?F$t1*Nz8aIaDJJ(JCU2`TnS_|krAWVwCkAYok{<9CK~~hr&5@lQe(0RFk1~n!hQ%qnb#RR@n`k%S(pqRiH!GGrZSjR-i +zr2jEt0h8aRF!?}@$vng)V`efBG0|iuA5cvGf|z`u#$+C1f|&^vDJHNojmZaUOy(gb +zn3+J4Vgf65Oms~88OrVIEU}mxjG0|iu +zpHWO;C1Qe^$tJ`^lbL*`W1?fy|ClTVOb(?mc~_0ebi^cMW-=Wy(PSp?QcP@!$-8Py +zrXwbpnLv?Z0xQ#)ysO4!I%0yE2^1+Nuu{iF$E3e8u_n!fds3Z=O@j$$CZ>#-U}j=c +zV*;C`F_9@IP((~HGch41n#@F|n7~TJ1Tzy8Vxq}RWE~S7lm5qK8({Km3X>1jm@Gp~ +zGG->r5ED&i@*%~f4>9>rjma{^1TzyTQcPfF8j}yzm@Gp~Ff)N7#ROLBnCO`FHzu0_ +zlT>HYr@;g>lkFKX!OUd48WY$gjmZ}j6DT4kn3-%xOf;Fv7Zej%iI`w!vK=weWF}we +znCO`FKPE%ZlHC97xQNLwUsGc;m|~KjF*6xVF}X~gnLP9w#bgA<C6O*6cbpfW1?fy&zRh3Nty?bOLZnA)R@e`%%mt2Cetx9 +zDN1ASUX}HJQm96q7lK$s1}+Mo~(WDJIWgW^xCROs+vpGG->%ASRm3SCYYIQKuk25Ntj{+ +zD-jdSOg11Un#?4uW1?fy|ClTUOb(W-=8q(PSp?P)yb%Chw>*nTnWT +zW&%Zu39L+G@{SslsfYOhnT(jcuEr#bVq(I~1d0?BSeeG; +zbu}hg6chMP>C6O*6cbqa{|Y8VbEiV=!Suxn7q3<5nU>fs+%zuiS*FzNkn&uFxzfw5 +z3AGPP_*-1Q7N>AFLfVJK+9z;r#q5hg;>ihn<|;LNljc~^lwZk|huTLa{7c+E$sq_4 +z(w-A*&*!=eiFni^nt0D*McJJ+Zwu-#ssBIdCG~%XNtEkSy~|`ZH)c##N;7d|!c?VH +z%?)gl<|atFfgCV*9FuJs%{V +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 +z^h^~qxt6r&#@cf@uDr**G+;TCdrq+}r;IJB +zlq+kAaZJp38P`9DUTx1B0v7X}mZwO;wbka0wZ{Zy&#R0(^oN*+>6+Q!G)Msjn@dd#;6Ot)9b3u;N* +zWwEv)+>6UuPaq-Jc;&oM+oTTrizT)f%h_p_a#<~D8x?Dt%55y_G2a(7eO4(yQcK!~ +z#@Z%wv10Zw!Gt{BE1N=X<2vlIa$9~OJ0h5nXL{vTA#NC#U)p1SH(+|VN*+~9xCt>X +zn|r2=U0*5R8{)=t&y@F=CkITEtK?a=gqs@UvN*Psl>-Tx^U66PZeoYMquAC_#y%QI +z$gEdh8scVfOAC9<D&npws0P`@E;7^7tGm)>v+|KSZol*aE~ +zKVvT~ww0E#Rj>zd5iNXlMkqJ2`#5Rb8EJtu6Kt5o#7e#V~IAFnthEpP}2 +zW}Hkgv%So^Q1e&2kCPLP@e}pZ%kWii3Yc!HV&;XK`=Gu%eqz7$t+P+OU=fG#p35at +zuqR${Kx%Xdu1L}|CG5FTDcITRuWtf*Q6fpt%&_MYrRG4Vzs2EeaS7`p +zNzYATPnJ^CAgy%viJw@+MZ9OOL~8cNYYs_E9Kyj!(lasaS*R$xI{lK%Cpm@ANYXPR +z?3trnycVTTTxJnpIbk@-) +z9=C{(@z!O^${n5lNiN?cr|@#W)bVxXQg(B_g +z^v`qq1c%_^qj?gM4#uUO(k54*c%Mc5jE|0$h_pX0?Ug#+!iY#RIx`%-MA>?v(|^?A +zJL(eFN0QN-!qF^cYlCER_KC7ZT+B!3N@VNa_|`+xGKX*|l8jCaM;9u+yE^@^x_qxX +zg>NFs=!kH1j?!BvZFl#Hw^~F$Z+NYI3(5VDJJsR@&)BnyY+0r3>y^xZ4xLRJhJ_7R +zDcRk@GxoYNTU`;ms*1TWlsla(Eo3jbwWUw|kwtuuH=KYya$~tUTw=H6vft2So*yvH +zuVQ`=TPzA2#wv|{!87)^OKfkKv!g1RH=uq=*f3wI_%?XPKC9F=tAu?Y_Pf*~{)RW? +zDiw*~8T+v!+p$vi-^*J1M0?Qm?L +zO-OTzP=~#`&{n;iZ4M-uwO%GSRGrIJm-Lw1gC=7ov!a$%kB(JO_?Rl~G;app3k2w}F#j2PQq4rBU +z>|C*pD`VL}f?>SO;!t~jhrPSd*1eqdRWh4vN&ARc`(&=Wq{o~Hnub=&g|);uGG?5@ +z)9^sr^?yUfrMP_m9Gf3P3f@DEwarmWj_cc +zqIhkawIZDR@hSui1w +z^~!gI+D3D+vL3T7V6s)o%W6s6j2JhF%U|AO-WxFOt&%SZahG=3^Gj^`rg0rb +zJ?2M)rk+Z9Tc~?bhkfaC+tOn8P%t4+^vZXKy2o_bmzLXnh3s`zvZ0oA=f%2*bH36Z +z^EUz0H&yb8Q1>Mr_HD(sZDp)EkdPU#yg1aI-(gP_+7ioIf2F*+mUNGZbx-E9zI&k4 +zKVyb<0`jvLk(Bz#?AH8?IHd_eyWLg^|4B +z%Q;&}?x=1D$@C%ja?m_DZJf&a+9w@UUUF(%Aj}8T;F1wzrGehhXbpSj6vm +z!(gT2yZ6u7XBFFKm9e+M*1xle5AcTbbGDG?A+hEO+_7Tz1^D|LETWe;bj;a8x~~fx +zmMSN9NDHZA&{uz>ems}$^&PPqHTY>U{)dnQPv +z^+3FJm(=PKY9dL`lCWpE(%R7JuW|Zn+`^Jb(lamYnXa@RlJXpVV!cHy<2~~wQnM>w +z(#9Q`Bvz>k7`xfyU-ddov)OY%ybNkjggd>rpbyC>6 +zNNL&K=|Ai8oplQ5dFx<_tlSr0xksAh?h|KO#ACd5szg>EjIZ1&-QyCfBT1_iH8qJuQ>X|7cJsO-g>h{!aL*P2I&!}&=E;m$AzueDdD}H +z{mj{3jnBCXpo#@g;TA9d2PEAH7ytvR69o?h{8_ +z#Ql79f<&YPacP$%xCCn?8C?>N4p*dxPX8vSZcg}mWE>$i~HVX@pxxvUcQ +z^;@6n6USS`U-5v2u25CG*aQXOo7BVZ%b@#J8WGv9B$) +ztu0|ch5atGh)?r|$;yeur)TV671_QjWzPo^%yus`I8;5p!=77g%PnK!j=EY>JtkIt +z8P{CcW1bZ>9jjzEgsO*g&86&DmCR$cq0%CGy6WGyjHh#9lFrZRR-rTo*7aV*zV +z-eaB^FiotIuc{@+sWD>~x1yB&IFOKQz4Dllabk!4RI%+;8M`HrkbmZtZwVP^aB~ZL +z%%g**{gv|STGBQw)^;g3x1`7XLC|EVlq*7Q*&X&5%WN+evDRQhUgDLvhS~;m8<+Q( +zp9+|ss*)$wlD6DfTMoCeyvKZVz;tt!JTKHXt-~HGvc*c-zCc3W?v)3JxbYqK{9;>v +z8CzZ{SJe`3OpLpXd#13*JSS*+zEa*0;)Zk2l(Jt}%8%6&Zg7mdgky_)%)bqqm`b@i +z#N~9@*>YP)A-g!3kmq{kjUjGChrOfJ)=|RtRLMhYN%#0z_egGOS&#Y7fa%UEd0{Q- +zzAV-~g!3(D#Xv%~dgW=M?nxbXUy03E&d#Wm%WFyZs95(@Zd*~0*&H-|Q7J!KOS*@~ +zx+ijpV%8r_$TPgMIh6bN{l`i6cW?hs?no{xxw_N8%i-JQ67J^>-%Z{^a)-onCvbJW +zt2_P0Zr>XY;SapwG9~+vbcI9MXFi!=uJSSugmS;yf1ETn#vALUWDy(mKiMZvv4~Id +zhEHINX|dc9+}nxOo&GPKzAxRvFy8Qw$y-SC$XN3fZr1tLo&G0Wz9*c*zhJ*?FH;d} +z&gPE6SNX`{`^Y8KnolNVzeVig4MUX^-@SdtzP8x5wv4^^)hGMJ-&@27c|#xUH#F8f +zk^8EcJr19Li$(k^Z(kN3=$NNZiZwMkMOeWGL$ +zxAGUSKJE19xqNv};hjj*Gb-%4MyaXq^tZTuD;>gN-jgelnx=ToZYk{Q6CbgNao#gj +zQTBEEmpFY(+`_y_(qjmFrYXw7PXAViZ>vjyyH6#e?2aq@rCw*Bn6!w4dF$m8$=egp +zJ0R6N1ZN~^of5X*sO0VJ^q0AOWlkZ;TgNDQ`=xiB!ha)4>yWVZ3Z-RFr+>EF_nbp` +zfw$&Kq~&0|Wv8^x)hFI-5kKXvVTvE3pXdFxz>tlS%4c}QC15Sk)M>%_2ip%UKJ>3_xLd&MclB1!9r +zuyu|Su9F^d_lZj_qK~)EkVyDYe8~=JtgBBfv50T-(UHoM#!ml1r|+O!m>5Y$uL?&m +zRhBeKryar{`RHZJl0%*Tc@Ez^mvDO|8C?*LW-C&oBslxTs70K{M`ue!s*6iaQm3O& +z{EJ1j@zG_<)*YSx=`P=Nr|@nh866dlUZZTS@AMya`%Dhuw|q2LB3ql{TX##JyZXdO +zEn*KJ9jf&1>+~;k`j)wc>mtdhAsn5i^d9W=Z+G~%y96^IT`ZB_-SOW2(vV*od(4CV +zsT|XMD#48RGL@m+FGT&ne8n!I66zK&GbNNeiK{DN|53#Z3+4XTbDT8pi8mgQ +zT(Cz~&=jncZ{-cW%odV6G?qJ&d%L%$)4$s7`_du&8Me5^%ltCbJcyfhp{CP6!Rede +z7OsN&U0!BEsQH5DIH}kfuV|3&ata}+=Xsfxq2^A{and_E);yhCTgXoJxAciWwumQr +z!w1Y3(wrM>&f(U=SAE#wd)OuXj5qW^eMGEzGWS(UkNJGilvT+T)spIwvFa&YZV_7= +zOfd7k%tN8-AszPS<+kQxR(-i+Fu`PbnbJ`8s1AE|nXS5rt*&B>wWK;fRy~w!U*2PG +z3z*ufnEYB&JvmlAj%zPxa{>vb#LHY6YM;_!Hx}89rR=Fdg4yC_Mu#q572IQfF=*OY +z$=p{<+Q-J)r*m8(n;%RtbG*#@PT%DOFQg2CAOS$_R2s){*hO{I%Le_nu^#pRq~A?9Ef&x4l@%8mi=iTGEymYa7nJSlVNb229Z^d3dPpk`DXE +zV%x?t_P#(uzQ-#s3bo~T*kgsZ*mCwSmGY)q(l#R2Hkpf+^qBjCrV*8LQ7z#{#<(e5 +zei2(9Ovv-S@_e=@$(Vmf6@MmZ_4B +zwS>!$aYMO|);*ouR>;l>CgeF@d3~rmtHZvn)V8gJ{UVr<$9d&D +zL*1jfL|Kp79x&Ofm>rwXCJldI{72^UQ0{k69Vgkl;@OSTE~oJKFHREe1ZLF +z_yS)g9lm^{4qq;8qTvgCPC9(~i#mLPx*oph;mg2;FWVt}xiuBO%ut6f1j84o|1f-c +zlZG#_2Zk?uY50=B@CCM@;Y$+37pSMhmp9en3)Iu$%bV)(K2V1*P}jp3 +zJ$xCM@Wl_|%NMEeWwSbbv19lG^&f^W8)^6gdtmtT84X{yWB3AF(C`JePKPg>F?`vm +z4qu?24qrB^! +zk0d_qoI!u2k;wuPdTvesGr+U|>LoUk>TGU0+e*g`{1@>cg3iR9P%u^Ii?%zzx5x!iG_WKRiP{N*;* +zqWb0bi$eO#E!&dmm)qb|-yfTqyv6*{di`0KcITqC~w^fDom)j@{{pAMx +z(O+)xRno_12A@(Lo0$@zzubnje1B}l2K&)pZt(f~FE{;{+ra#C8@8awJb364-w>zp +z+Rl@zV>9C(pugOp{)1m`^M6HuxxpUvm)q9M=`XkJ2k0+1*n<9Y8}k7D6>3q{n7pKYDCt?1TET8U5JIKpmSI|JE6M)|k~7kIjsj +zubNrDWgk5@lQlon%<|>**vy2t)W>FuPJTbLY}iMS%?zKfnpwVnA3ZiRY(AY?hW+TV +z8TcycV>6elkIjr(O^?mM=cJC!EZwI*HUoA2*o=N`W?+uZ>}u%~cNCqvIJ4|fADbCr +zq%+G<|G}}DDIt1n2KJ!GW|s2w*i4p@&Mddg|EB^pN`44AfJ{W+sQ! +z$7YI7eLu52i>JqC;H%POGdDwBKQ^Nun;DQ}Glkc0A-UH-dGXlHWhd3gX6~oQW^zwv +zIySTW$oDhL6|e_AHZx)&omqx0QpaYdom3y2fqLrS%O;$p$7WzZdTb{DBt15>>xgP* +zdH$31*vznnbY>a$qsM08^Yvph`mvdTIW{wLQ>TB(@WmHrmUlm;npvKHh8~;Q^;CwL +z<<&o@$7V)tQXiZ7J3Tg&dxjpHfvxGWnJH)Ju^HGp^^ePs{ak%)2L3*EY=-^0`q<3y +z#dKyFJ|}f-2EHoJEJIyCHlrV#8JJ@;GfyU%*T!EwHuLk5>SHq{PkukM{1d4EAe|Yr +ziXNMRJ?OES>2J_uGsRDSKeN0EwxEd&Y@IqbbK6LIY-Zdl)v*~4>ZxNhqgSbq&5WnV +zW+uErkIle-^w>=P8~U*s{n*Sv9hF~v?4qu?24qv=9eA%lBU!a}}U+OgBiv`1%jWm3L{V;slsE03l_%dMO%R3OhthpGz +z?A3%X2Wa?Gmoa>~9>bS+)Zxo23||h=@TFc8z8s+8%N`70U_TnZz*k9!FV}0rmo+qe +zfzL^YF9+1&3)J=SMGs#FCVY7V!k1O4@Z}Hc@MSNCFHrws`0@!2UtkXmUw%)+mpTkz +zU<(?))MNMp^>q01i8_3NdOCdhL><1Y!tmwyG<<=tis1{?_3%XxUj`<8xe>ybr&Hm} +zX?6JWa|~ZjX9{25#P9|7pyA723}0Z2bog>w9lk(49lo5V;S21C;mc_nzPzCcU!JDn +z%N`70U_TnZz~}4XiypoVQ24UB(?6s>6~4Tw312>^;maEt!)!aqx5*0i5z;;~ +z);@(Z77_6|i@1*W+|+AtE40DeF)JBs7pd7Duh}n!orJM@FTQ-42BjF$J@C|nfMG<1061(_vO!mzHvECTA4pZ_P +zl4f_nq<;5ul{~DAwCszw?2%@>iF~Q|;;a3+73D;nY7vj{)=9ngQ)RYOMeLR!u}%+P +zd{wzL$wlNVyz=T$+pvWHu*-MYDSQn?oFDbK@+^$Kh!oV +z;a}wTz2XpFjF7gRSX(|9DU1V!xd~3aQ)J^2k-iz<`=X_;ETx=2l#7Fac +z?Y?pwyt%AOp3_Bo55#+SNw2zyyx1#08tNXJ@Nakd;2I1*IDPdfr}I +zWGgLYgOyAdY?6A_U-stY_b>K`B28u9e2RSk&j5ct|NV=~p@{#=ygB)OTl1f@qRMZ?>H{2@&2TFXV6qs2`|OG79Nz_ +z>I&JJS3XIYtG$dRq<-h}%w6a0rOR!l#q8to{8BITlTdCBS9<7vipfZdNz?smOmqnCO`F +zKPFEACJ&@Ac|eT`JV;}5Boii2ASOrDm^?r+`4M9BfEtr05EJZ7o={`*BgEtZH6~9W +zCfJ!gp~eJO>X_)5^fxBZnY@?6~OkB{J@F`4qH74*N +z-I=sz!UUeDJCjy5Ca_5wlNyQ%6e%Wd>`YoICQ!uAq=sU`t1*GkOm`-&6cZ?7XHuhM +zqGQtkn6v;U>r$AkQ)2=T(wJoIOj-~VO=q%>Vq!r|)~PXRK}@hSX;EWhK}^=EF=;_e +zurp~MZ^R<6A3ZVbS9f9 +zCJ_xL*qKO(iKa8zq+_CE(*Ky$1176dn5M16xu`{VxV=@IXS*6CLo?-%@neI&L)tJCa9TOdse#T@qbS6)xFnLmq2|P%5CeLNU +z1fHimljqc!z$R%-Hc(8UNHJN1oyl_)6DVS5vVmgqq#6_W%yeh+9K{5R*qLn5G0`#U +ze@qSoCTmletW{$I57L-q>`V?LCYsJ`V@;G5INCvQ~}BVZ;PG +zlf!CEV5N?Uj!A!G0-ed4~%(dSHbOa=gxo#*XYKTge=RA}Z*;6VzLi5WYSofH#zPCJu3an58I +z#bkwM&SWRWWCC_3JJpyBqnO;TnKRi*F@euacP2a4n7~RM6CIO&#$*C?CVNtt>``L^ +z57M29GZQB8Jl&Z%)tJC0DNHJG&IF1SlZn`wI4LGjq@BqfIA^j)jR|~ax-)T7OrS_R +zliTz;6CINQz~phjBsFJJp_wy*2Wd<)b|#M_ChE@QPMkAYj+kiXOddx}urqmFjmdJv +zL^EgdIAVgG$>VBFV5N?Uj!A!G0-ecQDNNqdV1k{=OBpf2&g3OECa_5w6Pz=FB4UD_ +z$xDcdx-+>0=S<$xV1k{=ONfcOGr3KlGtn^_08APHlhm9^g=WqK9;7h&b;i!5fnoyB +zu`|IrldBLD&74UC#pDU>Od8afT!olu=1dwWCh(c*&ZI$&39QsH(J|>~OrC(wy7cyZ2&(odB3u;VYlQbqcX97iv$*-|9d4XaAMeIy)&g6G$OyD!qoyiLn +z6DVS5qR*M=m<#|WM*x%5oJoad&IBH$G0E7O96?Mpoe9pFJb;*J=1h(tCfJ!AQDgD| +zVxpNdIf9sAXL3Z139QsH(J|?7OrSIQR|=DVX)wXg8M4vO!F&O|%>Hw3}oJoad&IBH$Fu6NpXHrKof#=wn +z;GD^&h>2#-q>f^87j`CfYD_LgOf+*Qbrci$%yef`r^WX_)5^fM-RL1*%t6ehn> +zV*(G-oyoCGn85RNXL3x932c(a1m{ekNHMt^JCkD+6DVS5f^#OnQDXw1neI%EQB0tS +zorykYqGK`um^1?>sX3Dh&7285NMn+*GigRlG@S{~nfwGX(af1NBPQ6HG^;WB31Xs| +zGigRlurp~^V*)F6Oms~88x!bELMco_8ceV=Y0HQSb|!6VOkk5VCOBsTMZ^R@C|y6AuV`t4`nKcw{+Z{K=;ArUXPhz{N`Mae#T`hvgM;VX6t +zmH$3Tet4VElcz8EuWpR|ZS_B4j#TWASL~HO +zg6}lOA|Buk6O|KBpT6LK+2MQHB|Hc#Zw?zqC?}4bzTkh@>3i5M+`=0+FF8j}?2Vr| +zBxO4YQ{-i4hN`C|{EZG@qf1!Ldv5HtHy7HPm$SzL#B)Q~Ge#-cFP(4--}0UzO6$I) +zxjA5Ju3~b#NNZ!fwO(p<3waSzJuy~2nrkm3;u4D}@t*0u_V#j{v5?KFVy^5WH3#A~ +zyQCHuVHSFsEur=y3I9r$Z>3ZCg!kn1+S^KPZ6$0hNIXNso+}k)kF>;1n8{v-3AN`W +z{F2+Z)gc^>koM8B_Gw&q5xXr&JTtYc(rBE&c( +zW}Lt^6%#RN5$E&PYn8mc(mQTp6mPwv*S@0IwxW!^J3y=jVQZe!a!^|5Ao7pB^0gu3 +zw1oex!*|vtJQg9w8L_rO+}!2t{s6Jg4_ikmD;tyM4+5qSs^si0va%t*vQE0kEf^!D +zZBndlEcaqL5pyhJ6K|cUgbyUm_XSM%RmqFGNcdnpyizz +z;G=_j?fJ`X`NizsAc>9)N3T|v)Jq55L>}dpZwqnR3I82#-)V>NM?QL)vgD97&mruO +z5N=eAo6508MD$ohD<55=NIR3}#X-}bD&>t`MA{vf_Dh{kB5(7`Lqpx;xuwNKeAgn* +z;iK2|+LxBtmX@>E1xR#OIGU?$ZIV8B5cxi@d~>LKdcwcV;albs?&PDl{%`Mc_y~TL +zb)~M@-g=H??}}$PO1qrG-~WAz7>0!nS1H-epI`77yM1psgg@|x%arUx(iIM2A3UEB +zHY`vYpZNTO-{tbToI->*lx;mn8XMw`b<*nR7ZdSDi}+{WV1nYIc*PEBf=gHqE9Zv| +zqm+u4&oB6&aQdEb3ztH1R@jiMR5VE+{cbT4y%w>SH*DK_j-1#LKe10*;1o{6AB_$h +z49bbapI`95?DjqE5T1tOji?Q@HX_)Cj;f%gpRwdXFkvrFKs>X;o?NA- +zNeVj%bDx*FIn+Kq;a}qLEpZ8V@ScUecCN_Am9iZH;<-8O8KEc*NwY6t@>MZ2LhX|i +z{$8iA*DVZ=5aalmaU_>hM#PyG(aBqO`198eIL^Q`Qm +z6Wy^_+)hLU!bD&dT350fjspw~tcO7v1SiP@#)+g?&EVP^;|Wv*O*CUmVDMRY!P(Ac +zc9og%5J>K~F1vsCb$7k_tM@e1BvC7U}*baNuQ +zQySbvkbwn7Q3hrnM>~Q%Od1ALG9ea!Hd&~G&LnL-vG!nCr +z(v}xP<`+$JZYPoI5>lLrn6uon+1S +z#G3WeJ{OUv`Q=rSu3o92*%dH5eX=JuDCr24+XJQizr!TfI~u!INp6(VrTJ(p +z=h#EPV6t>Fi^+!+lQ9`F`H*4)=M~W=}R$z--MWa +zNHKw%8YUmInDjL;F)+zKCR5?R7jIWFsbDb~gP4RfVFKqGCSewn3W~|n+bAY5q?o`> +z4U;g%1cnroM{c8-RIr%9hcryW6cZRyOqSecU}9jBeN3JQOde4&naX1FImKjmMod1Z +zn7}z=GL>R-Jz_GI#pH8}3Eb2$`JBb%dc4U-cT6Br^U(|EvVTuWyBPLTQCL4OjhK4E5!tch)JP=iGfM>G1&u{EKxDh?M#kSOipCPVDJF1J!=#O30z7F +zOg^QUz)cO4PgzXH8<-fFWFM2CA(_0VVq#`7c?vO+GhqVf8YVJ}i5W4$oe2ynCU8^3 +zM5dU)5HZ1>iJ8R&KBQqHQ%qopm>4?~1CwsR#RSd~6Wp0xjhL`Iliz+uF@c*JCZDmGT#cBpJComkMlpe#8YZ8y +zm|SgOVqnq@m_Rc5NX29!i^(R$s1BH#JPYqnN-DF~Ob5 +zLKYMFkcP>36cZRCCdSUhz@!^6*#elTJ(E%F&cyr)#iTqVCZAAD;2bf*oyjo7gx#6^ +z_7jQ;+|)4ngvDeSV#4lBe*X!@1a4}We8OTf%)rFJB>R}uK{9cvn3z~h$`O-DCQRU5 +z!z99DVnR%CX97ct3Eb2$iBL>nh?wBc#Kd9(AJQ<1P)uNmm>4?~1CwsR|+7nf#z)@)(QBVZ`KACQRU5!{ii;$zzBK?o41vF@c*JCZ{MSFhopnXYv?} +z34BPy*McvNiBZ|qyjF@~xF@bZ6$qTqM89*^<(Cth< +zqL{!<4U>;pOa@R);5XsUcc|le<_!zz=t$UzNVPKkYcjS*qIoZbORQcU0+F~Ob5O^AtZXL6Kc0yi~Gjgj-8H1SUb|yzCCU8^3l0F)%+afjgMxOhWv;SBtccS7cOOx*ZL!`rW4aGWW%pQ+^g +zgoyX5sCTH6zdda!51GqN+>}W5m8syorocRx@7{J&ofog}D>RhzXR5fTBGo;G>M|nE +zvx-MO-khYPy4+q}%D0-hL7k*|Yod9RRO2SxI6ucns)wY4iaU_k +zZDI55D(;?6qHIbi^-{9Q_kKHR9TIPyAPg!Z;ySBX?6FNwItCTn2bJ?5SIK|qBzfx+ +zd0V9lCy}jwd32<3q)=bV|J@{C7AYK-3SRFFT<`YX)J_U>%5V2h!wT)C7 +z>(iE1A@eGed}k+V+?iOgRvPK@mA8|Y(eakcgh}N@Tx=E3cx-)=j)P_PgC)GzBEAFhRww3o92n#tjydjed+cM +zY$w97xG+HAD~MQN6}_HVo+9l?TV{mJGfeWNP9oJOqzzJsi^#M6^3##79>VN0B34?( +zPd%{#NyqGR`|MKwt1yZ6iN+=>Yc@${H<8EsZ^Y~ek+bf?Yime(v{?ToHzq_K8LO02AkW{48l09dEcym^f)^+VXkG +z{JDv%gW>RaLyoY&f?sxYH{llextWoM_g}u?SX^XZT*mLN;?BZ{`otS@g~bI+)0Puq +z^Bq;(moOX{Zx}0_DdwMo@0{c3o{3cVNCk6TfgGprqjpk#S-koRA-9x2946k&qTcJ2 +z{7q@g{;+v*756}-da%$?$>&ya<(;H?W1@Mx)Z9e4YCl&PsU9b^77?-0DlYJNrzah) +z#rD>6zAHq$bE4j!O3fB2&q=sNer`mh^@>!m(HUrT`$o2t*5UEi9HFIxUmhafNm1`O +zrDkW^GA?8uXX0*%w2nyyrKW)7@~vnmt>faYy@jqaBATt@X^(e^qHIfBQXzB7B=_hf +zd0P^B8>PN(A`kV;RguEWg+Y}>9A*`t_1LaRI_fLz^~L-mlYD!maJ(?Th#wIqw&79R +zRHbo!+Hzmm{7sd-I#Sp>6R};0w#S_OxClQ)T +zJe&y=IM*{fQh;@@#>OE4aKB6BPKNz6F8@sG-EPprkKDGlSvK5q!}@(VKHf@n80tsWKu&h +zftwm8H7q901||k3*~g?6Fey|qX=E{}K}?op!UWDWOqQ^iG$JOLOkhYcsXR{Y0w#l0Olnz7@(`1SnJ|HK4U>f| +zCbbk38zvJNQcUs?lZ6x$7*b4XFqzb{n81fLOcqj1U`R26?=+H$kxa6kOuo4k?Deg> +zGqLHC$uf#bV@6DtQB2^RVp4<2UlVvO>2Ph`+n=qLyqnN-=4U=Uo +zCI<{m3{0|*Nef^yNyTIri^&4SWN{`;;9SFGF^kDA!~~NG3@IiH5R=6e6Br^Um`rxD +zn81fLOcqm2V2GF)$;3z|-H=R90w(It#HLFo%PA(&jF>E^n7}z=g306%VxmhX%PA&N +z#AG>($sxoG3f$K +zW~-R&V=-BSm}Kmkz`2Hru4l3jF~MX4LyE~7!~}aLFhoo+ne1aRfe&ezV9x}Gh>4L* +zjAYUc$>e*$MBSOhbjbvJCdrJLV9x~35fe-%?;|FN%k=r1eo+zFH(8$ +zRZN~`F{waIGWJa1T*E}yGkF#QFkU|*<`X3dnQLRVuC#rI7dt{nY@9Ru*swbdnQK^6J5{b4a9^^CM&RK +z0yi~GbUl+d3``76vX9Apz+{Aq$yOGV>k*TTJrg+BFwyl)wo**?U^0Or#pHU#1bZeh +zq?j~fGTF*v0w2;a!JY{WDJJlpMlvyyNw$+o1Tax|CVOs3H1Tn#$2@DYvOeVWoOyENrCfGB9A!1@A6C;^)Lozu9n5a9G +zJ-TFqJ(IH;F~Ob*oFgWfOx{6EbjbvJCT9^7UC-nl#6*`&uxA1{HB59plXnbE3{0|* +z$t1vJpo+;R7L$>PNyeTDoNJiqdM2AFCJ$mVfg#0YBw~U+6BtrV7GN^j#9{&;(lEiE +z2@EMF@SR37F_KBPlgZbYg1ru@JCg@>$pm{QyE0;eJrg*mm@L3#vY%oCLrf;vGuefh +z=z1pmDJJlnFqvS_1a4}W=z1pm4NMG7vX99@z@$LMq=Cice#9hW&jijjOmsby2E+uD +z2@EMF_ai3QGl3yug2|+T#RNX2VS+sq7$PP{GBJ`#HzboNV506!9@Hfh?3sL<5fkj0 +zz&T=q$)p7_(Ipe?nS6_w=z1nCh>0$lV9x|@YMAJHCM^ag|8Fo!z4CzlSG{`o>~YoT +zU*4tg%X<|*Kl01JJ7y&N@vFvnk_B~%1+~&HH<5Gv^1Mh(j&QJoh=o?M#bXM1;3#=jCGv1!rRKqXn1wtOEle{Yh9 +zbdu!OL~@h#jN3Q2opg2S)=pQY(QOT*5*1tW4h(oR7 +zpFIV?9ea-C)F*N_NFTX;fAAFCsno5Nt~oS?h`+LmpLq)AjXg)|>JoLelFRKI4G+0K +zS};XSc6cJE)O(B4 +zyg6;@3Y!O2aix*g{;6P|JJ8tVJJ3#AFORogDYO(3ahFxR-{UP*YBr=T%fse)6=&}x +z%G!joMVjgKec4W0`@~yw1)-FP9aeF?$9qH4(N$vas^Fil;w+s+*_=>zN`0G%T;!Lp +ziWH7c1#6oEwJzU6kL~uPqrS*qU&gyb#CBWMcDa(bO*-QA{p7LrQX03UEzgI{&zs~c +zI!R+)qOn#w;P#DaCxs*8g#(4-6-2zlD!${fjZZp`SK22P@dHirHJxO^_QZnqQo59g +z`>o<)kL`}6<6x2fU>WbNl50B2f(?lU+oW%uL|)^U`$k%Z3Cl}}c-$&Z^4JQJj^(BH +z<(2%b5V745wT)7u^-`jV$Y#GhC(<$@6&&0Y80_+uwi97=T)0daSI&PLBC*?}vCEX1 +zTho?TL*`da@|cJ)QrKI{|7eo?bP{PxLfRJ{%AE(A(=F-&5EqOnQJ +zn$2m;zr*GURdQvdYd|VE#~paT$tSjxu0ipxaYCwyh_6^hizhZiNp4769APu5;?^EI +zOLG5m@I=8-CFj()mxAk?0_$DAhdc#;eDEB}S(nJ!DwVVp5;0^ICwmHRR&q8=AGv+~ +zJp~Uxc#hOe5LdaR<=Q!rDh3x9hl_^>PRu+#V5^5djnaJ1kSrB43#Qt$_N +zV0e>nqo=_1;5jmHdt%;t>A6FNM0~_5{=-vH4#Ta9d7Gqr-M-u4=A>xBIAz}V-(Ct% +zZ3;|v`F`UmSoPpJa&&#-Xr1&X{HA|d#Vb7pOJTSvakO6gxykn)+?)_Cn5*QkO}UyjFnP0~?aVy~{? +zt3$+_ANA%b%{!!;Cc@44bCV*~V^cw;DWJG~YuZWmgm`NYp|Fgv4-xN_sCR%;Q9SLQf +zw8llaTm9V1NNYc#tDK0>SjDu*)+6Z{RAwJk!fyx@TmPu-MkTLSs&x~&zhC}Uq%bEH +ztZ)a8H2L1}*sfIac1qVb`L?!`!U6HZF~a;}BEDu7mw9Y6mBw{x%e1ihtt$D^PSUs` +z(YQ@I>m>4@{Bo~I%TQrb2@wxl#fhHSTmzHLm@EZMcK?D&T!+atipi{um`tOX%wjQt +zhiI65Nil&TVls_lG7B-8#$xg%#RP65CetV;vk;SMEGAzXm>8I3ACm-N5>PQY&0=Cl +zOlD-l#EzKEU@eHHF_}Rzfg!~NZW@>vm}EJb +zv_F)#^qi$8lW{C2Pfn(o^vi_F6O$<>{a8%kAsQwhQcPe-F%c$HO!`qwR!?Rz`H*4) +zHz_9Yo3v!ok75Ep1e3{!1||k3*~erDVB%IW3A30~QcQ%~GGS6lFCQOzhCev9=PEbttA|@wTOqL=h(4U-crCQA{M=@b(f +zQcU2cfr)`hwlR4)ZRz>0noM{dCb%;hl@Sx%nT%pFfrn_A9HyAS5HZ1>$tc7`w=+3R +zF@c+i3GPfrAtt(=$zcN%1C#7y;sZ>)DkiNgCLCgtac9CICc2$TE5(FIOj=n?IK%{Z +zCNQL!z)cO4Ru&TuF~OY)3@IjX)4;^QB-@xQ0Zi0n(x$@%cP2A3VuCx987wC75Dk;# +z6cZRCCb%=1ftcuaCdVlza1$}XoyiQuM7J|JZeU_yl6_1%0F!rBOxjpXoNJlW$l|?xC0@aAyKT +ziV57*F!_eX$rlDD1}53ZR}W515E5CNhhO1u@CEGqE5hx}AwkF?kv>ky%VEhzagYU`R26n;IrEi-`p>!JP>V +zDJF2!z{J2L+n7MlrpVKSKROpf+o +zF@cAun9TlwVgf^o$soEj`DYJ`$>r?MWZDN56Szq+f#0O=OiuQon7|LAJCj)-7?>EC +zWFM1tXG!iKnts9L&Jcsi{}fS724&ir{7^(Oxt!gZObJm;dQ(hhgcwZ1MHG|4bZ2rH +zh7=RHsbVrW#9(r+h++c2N!^+J2t$eq+%zyTFv&J1&@<_$CX)?1Oz6%ea#co5=+5Nm +zRV*g(5Dk;hC?+sOOz6(!pI0F!?9OD`XA~2-iI~ux$;qn_6Lx1Z>oWrr1C#7y@*!aI +z7ZsE5SWF&5Ofv0Ees~BmVRt4|zN46IKuo@4F?k3vp*xeqFr=8kO%0RpSWF&5Oz6(! +zM;KB};HH6zfl0P8fu6}`HJOy^Frhn>$k2?K(4EQAp)4lw5Dk-0C?+sOOz6(!pF+;Ij3Ei0-oy=ka5796=MlpdQVnTN&|D24Nusf4!$0#On6EUGXlarGX6Lx1Z>zILw +zfl2l;`5R#JR~3^}EGBsTcHPe8BZ>*!q?o{O(sm~ODJJkkaA)$7fr)`h_Az-DF!?VPldoA!enl~< +z&$u)B6~$z`ZfEi}#pGJVH92`1;~zLog%Wqo_~D4MLkP~p(=`d?nGaA^6g6DvE1NN4Y~iqCkwbCZri +zMfO2u{Du&*O^(|7D|vNNt&_-q@XP%pg~L<93TL3g?VIAU-K^womX5f61KLU9uz2AB +zVSWV>Z?cN7d2D$~F)?BH!tk{}gHIAxtVGV!2g3?6D0< +zIwqCdCzbMFgo&+B)HYFBut~b#P2@bkydcstI2HWX9hlzatM}MOBpu5u?8}S!2gAfR +zHfo!tMAxM)v%=Xg>fZB{Mag9>xtc{%&bjYJ`J01 +zsFLsMBr`W9X4XqzHu>K2#I96k?v!q6B67K3o){6vq=LStfY0T#d15n@jSjPOL8xZ=UyT7Ddj(`+)cRte(qP1+?p3II5t(-Hx=^>P2BB~ +z-0?zr5kCyhuk&+{L~<9uaKTYtZZ9w8!zOM!JY+;Xcc5^1{Nl9bv5@&O6ZakrC&U|i +z2ouZrtrfco_pqNE9%)$p!Ue~~Qv1Y8{w5gC^KotsU9y>7xB4a;vF9KPF0%M +zr!CcCb88hRM5=qIf;Fx{jnfxxC)NGp)uV*gQX(d;VqcHm)U` +ziJBeKf+oWK+Rqh4TJwaKVj>>0icfgFvy%>?$S#!ed#kvmokUrmQ0gSfNw_Ed+>l7? +zh*WTmGqA?(o8$4`nslT#CzQ=n(oN(Zez_=8*gqBQ>kia5`J5ix=%iy%rMDBQD=#9^0Kt? +z@9@}eNji>~+K*TA1FPhcPO@NQV!?K4R}+!%^~+NuEmx+3_csOZcloM4w!)<2V6pvR +zIUfrV+w7>Vw-VhVO?MJ`iC-QWX~|6m4><#e+`e(`q-8|BWuOqR;O!w|yEST?phS13 +zE&W2~ekS?qPBL?QV&-~jhs(F9od{RPg~u5lfHEN&Us?Jk`BJi +z&X@2nhDj_Z8p~ItTFK`o@*uxFKOziF1y{HO9ZkM>+leqFE=&++7x6>FBsMG>o1&~) +zpSIi+Hh)zmuj(Xg)+N?#mCR0`+)lds#=Axefl?x#w~9kNv1^s&#yejQvPoy?y^YkWBv<{@)CP_1#g1$-}<@RBDv#)!=sm{ +zEmOkgH>$XQh0l`Qe(~Hh=}X0Vu{B)IqAqPw&#}fhpV{9I!XSzME+K3 +zo|ACP{M?vG^+=(ils{wQ`b4USrGoj+K)&0T-%hG?Po&aM7-BWy(5+8`m{v| +znFSL!yOT8UOw_EE@?5@(cG5aJ-g=o(SWd(xR`IOI+b8L0DYLhf@CQxY*iKTjEm5;s +zin#kJ2gzU +zQ%qopm@G0dF)+zKCcgtrzEv@?v6#G0F*(wh36s|;CUB0J*eE7%ASN~zlh-LGpEgoV +zUS~0R12M6&n7mFgf$!8Xd7Z@sZW@>v$t2s!WEv6I{$0i7F&!qDOkU222_}=5Sxn#| +z8YW9ACNM-yFqyoJnCOzpQi{oAI!rK`yo{LWlF3p769bd%WAaD9GSWMuifr)`hmNEIwWFoE| +zp<*(C#pDJ|ChId{0_R#XSzEOk5NbIH$?vB`d{bE5&4wmBqwG +zF}VSgiHpT#E5+m$D~pMXVglc(B@-8m3EVU=F)+zCCa^PkUd7}t9VVDep38^{CX?q_ +zOyD6JCXY}|V2GGtGIC77?>ECWFM190Fx6cCXce1 +zyos1(OeSw4CTuc!=~0Tw=ZMLpEGBOvCYVg#WHI?1F?p258@@(_wpQipi3U$>adV1kN#;ETfq0MogBmm>i&(EX8DUfW>4tVzP|I +zb1=$qB?n*E2bUm|!wF#9{(B4NMG7vW*GsOjfCw+`(ezVi{CO={_@v)e^gP7=gCO(P@e5aO7d@Lq#)4;^Q +zB-@z4&g7hm$x}K^Fq!PjhzTZ>eJm#M5DgRTnZOV+!DO-zG0`Ox?3p~J!vvGbKEyKumN!llKu5OeXKMm|Q?ibUl;z +z5fe-%@3WY|O#>4HlPqI$Gwe(Ts+ja)F&Tx)WL+jq;9N^4>sUD@NCyNQ(G%ztR$u=gi +zGuftMQm(@UlgYCgF~MZ=EQ<*|M8gDoCNM-yFqu4yn6Sy@0qmKS>oCD&@+@M)CKKN1 +znHZRK111jxCf});=z1n^ASM};$s33Xn@oO(J(I(TiLPhz24aHA+!-$ElXYvMO +zg306!78AH>U}9jBZA@Ti@@o~7i7X~BVlvs92@^QilF3#U6L^S*3HD52NHN)k$z&_V +z1csPQuxB!n#RR@nOD0<>CNRWgV)RT5Ou7M+djXS(iixgg@*2ftSH@)W8pQ<8F_~b` +zWItk}>zTYpF?kV_$!jbo`wB0sF*C)VS>qI +zcScMwne1jUfrn_AV9x}GhzTZ>-H3@UnPAUku?`bVCc6<6T{1CxCI%+mfXU;4$te{R +zUC-nl#3W-fc?U7kB@^tKoIy--ndGvVz;|lN +zWD~^%hL}vU+%xGSyIVG2H+g7}9_!y&e)7;;@IU|OpVR6q6+GUVNk?muy|s*Q2@&t~ +zsCTf^ye)0%3Yoi1T<=Kh&{Qzb8OU?{u5Tx;SHxQ{7YZwhIMOQa@_2KVn)tAr1jxCxy^*=GEa`u|OT +zq<$W7^R>#2u8Fdra&v#i?6RM71Lv4su!+)u+~}Gp`zbdZW|#deHx0;*u8Fdras%I~ +zWtaUdHw|Y=*Mw-n1m)h6c+J=!o)i)>Ybw0tWR6!ht0>UxK*8`W?iCYtF*xB`?j65_KmlW6k1A&n6Qe2 +zJ>F{-WnXyX+Umt*#(;@)jDo4yEGs-y6mzzZ6VIU&raW^ +zc2eCVUOiOEEg|AZR`D8-_eLeZHf=c^HczbL?&>7@n-cl;($Oa0n;!3#O8!nMzlm_= +zer{r1?m~~B*7Q`fDc4bo5Neg14YoZ*an80^x$>bo5NsEDr +zfk`)D0$Y`siix1Z1e3|$jF@0D*~?-A5798eCJGD@6HF$15ffc9!6u5J!vvGbUc^L~ +zOqLp$7?@-qlQn>e`os1x9h1oh +ziU|y9GC6@wltC;e@SR#R*+4OYAx$Q24;h#km}DQ53cy5t1V6U9w2nVvD3xG5%Z +zPLs)Z*hHzPn4Hu#QQQ=h8JJAmEGG37lkas+6gR~LzEevkZWfbz0}}(2ZomX~CVNy& +z=Ib!QWb%AQOfZ=|&td`((J;X#3JehwOeW7GCTub}flZY8I!rK`Jdc>L$)xQO0}}(2 +z>|?S7Fj3!la$46!c?&Vgm`vV6OxR@d9X3&pBPO~g%3FvDCX=^VOpYTax+cn7hzTZ> +zw^&S$8<-fFbOR=^GkH+OWD<+X+n7wYWx@o`wPdo5#RMLrVS-H*7*b3QVKUi9F@Yf_ +z6KtYPVljd5)RM_IiU|xcnLKP@VqlVeOzsCv)Hj}-)-_SQ6q7?4lZlsN0_T`au!(XI +zG0`ATRZN!aFu`Q9CnF}9 +zO!lytz(X`lu!#ag!~~Pc9>heKOt6WvT!#rJlRb!uE}1MbFflO6J|<59Ch8kcPV1T| +z?;<7{lgYb?i7uI76D5wA=$a_+A|{wj-eoa~BPO~g%DadOCX;trOyUM61}53ZY6jOeUK%VFKq`GTF>x0uRwJ!6pg}DJD-~GTBTqfgvUnY@&=~F@f*YlF4R@ +z2@ElrEHp4NFv&h9cLOHs8&6K_dM2+@OrFS?OkSm!z&R!p?3wIEOmsbyS1Be>VlsJ^ +z#bhsHqU)KwN-=@&)RM`oEGBymObkrA0TbAnysKiu>oCD&@?u6zFqyo_Vge7*Fu|S) +z3=tDdCNCl;x@3Yq6JCc2CX*Kt6J0VfdL{-Y-GIpoz(jrH$!T5B?$U+SxnAjGTE64 +z6FAqB$xap%c!-7x_Do<%F-c%D*-0^hAtn>-napM}f$!9k$xez13^AD)Jre_yZotG0 +zn5b_&Ij!rNh!m4V#$+N=OyC@o3HD3^h>5OeB2rAwV=@t0Oah3Bu4f`rOyE1UWFoSd +z1Pn|JOu7LR*qK~ZF?m{t2_}p@B*+$RAz@!^6DLzMX{;0n3WDeUi +zxzt248JsDZ{M1A-fpeNnZpWU<28zinwrA4bL@^mclgSTFEG8Q$CUe=I$%Q7034EuT +zOwKj2m~1dGF)--{OkiiSS;eGOhY3w4%AYf0LX*jvKeL#?Lo`gVX97dSgeH^DKO-h= +zGPwhLCZ#$|Xflca88Km#$!w!%Vqnq@m@EWL)Hj~YVS6T*{(_ifN+v)31u|+pfQkCXlR0e9J1*&Hsk944{5TVLLnl$TCzSP)O5Vn_Wkc9pS|wLS3NKFuYu$m0Cf~E|q%bF5m?zX1^NURK?UBOq!u%p4 +zZncVcd2CaYj`_v*`Q`jKRr2ai(zq_sxK&!>B=Vzv`N~M)s8sN*GjP`J>*KLqopekp +zu}`Yte;p#Wo1(Tc%7PtfOF_t7V3PAAEqSTnw@ra>T|S|mw2Y6p^c0qt@q0qVHZ5u! +zs6^}1mXjg#Ns~OdlSH>BqMM{A+`ifEq-9jRWrz^3Bw}x?xWN+}nskh-u#YR|D^2p0 +zPBL>xV&*#OZWobn^2^I2LSJETIsapo{8U8fnF`+G3f$uKebG*YK5-#e;7fTqOk#bb +zvFjCSQ`+)&*!*Ob%y$xLb3)oFjc@X8ZYN#+<6WbL*~LVB)haIa#O_Es0!8*f8824J +zwobBULt@P~>9mu`cE8*&(ltzYx`c>dS;bpDv4W)I=~DaCmHgZgiQN#5jZ%{JQo4!A +z7QZ|m6N@q%M|+ +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 +zHM{Vx>9#8a>{YI++MOOaEKiN*Gb<^1RS +z8ZV0fu!>iB3MMM^x+13>`z!4Gi}_`*G+q=}Tg6UKL2u>g|3pqX7MIu;SMU$O=U=yq +zk9rC&-nWW0^o}=-5a6%Y!{_g`itl*}CP?Jy&P4uNDaUnDEU}6odA$9V{JM@{oikA9 +z_6=`Od#{UnuTb*qrK3&0H$C1fmHeF@!ThE`zRNeSJ?)(u_2wwebyBnQqNrHKJdgK! +zi8OCYG}lW?(?wCTifcUHIZDmij$ocEkmvLrX-|6xM7=jDHMJeVMt5LAlW&*Dn=6r; +z`b5nJDeAf?K4BFT9&c|&+0qf5=?u(t`)+AZdkdo8v5K;zBe*mAq}z5vT8` +z_Oz{6)OL;1xUnO6y*qHA$@iMamM4+M9f`(u(h}E2@d2xN!ebjOk;ZL_#?2DE-=RHi +zyEf@RopxOmpR|hSJ+a{&#wy7j9l>Xs +z0?)X77Ef%3M3Ng4$!$`vJExtu^n7J^pqJD4!B@vp+)zJP70JC^NS!-&%F(CNzNv`6 +z`jy=m#VV^9@~H24NSE_}tK$A=>DhEauV}$FN?qr%Q;zZqdwDT$GI4&G&x{uIRq8Gr +zJLNcBVn1BLKeli8Me(mz@sFN@Im*2M96RNhSZ1GC!f%B~UuPBn%TsV-+A7j;WxS!6 +z055rf&qu7{ZJvTS%m>FC#tVy!_%ZPL-&n5Mx_`WSv;c2;2&cFye(teIb+0x@Lz%sygx_!C#zd+| +z3Js +z@`FMtuGG(68)+Tg<|r(-7nbwKLn&^RpBory9WJz#oVOedo0nH{53VMygX68^1$Y}u +zIK|!I=axoV`?NWPa=TE`@@acz!xkv(3< +zzgs1*SWQ~`#al)R@zV2_i(zxWD!F(y5&Fl4(E_{>C7hC{_~pkULa#Q*-ZJ~%68=?_ +zJSHNH6!w<#KZa9sAHQ545eBq5_zF8;%)_f5Ruf@dT<9&dm7TY|9WuXdlEpf2>+Xa&zLjdBUb*exXSY{_?&Da_W?$yvSZ&#y<-m +z{md%f=qboo>Jl)ov>z_wr@XS~qWC+j_?@TVOL)YncWzyF1b_P&o6J(T<{9l;!DAjj>y +z#^b$FBKft6{2kJ~riBx*KFdG3qi^;YqK$2&$MH9HbD +z>!bxP-~H`rZ(-CsNU7P@5sW$mQMYff$9t_rl#K~xyCgMT6n$24g~vNfBFegivQ>h& +z2eqfYL!#bW6=icrFzF8TZSt*aPuqq@ZIhL}^-`_tqPWm1{>@{%Od@$(6M37Y3b${H +z$9A)lw^=&kz9Qsm}m+lT)wB<)3&+MSPy09 +zmX6?HXJD|~cdaLOqeN!bCT8xC?ryp$K5rH8^TcjbW^Rzaboo|!Vs}bJTAPrzNVhmI +zieFg80#7Vok!m}FK6hY6lW$LZIyN#Io32P3I)WXpK!?)@uSSu`nk|Vn8>R8?i{cGd +z@l{W3j6~M#NUT{WnO#1vJsm5I#s(>CwsizgI|HZPz9F92wGv5gOeD8U?>Ai(MXR{d +z6PqQGxX-~(7L}RxqIsf_Sl%vm|)LvI`@_9>f$XsmVCP%uy8n}w&UK!8r +zC2acB!j52xGf?98P4*PrtRzPXn@ah=Szfv*_P2^#JOy9FN5{l-`v~RbeAxWbMX}u~ +zj`kFsh55jE?pWdQQwuwSKez%vIDP-)Dfn>UD$+1C-q2r|_{_qN;B!rZ=Ul!=ZatRb +z9`|!Ok%r;I{xu6bg7>-uUpM*uFrVq?)3te +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 +zWQ)$#@AO8Ih0Q@*^1<%>+^%Ne$O +zNmBU&b1Yxrqp0Nz%+>Pc6kEQ)oR=@Wd}*KZ#R=uh9Ho32!( +zyimSKO8KJMdGRRKCDmEng(Ie1W-IzDQWUq%`G=gyoB@DPJTk +zU*Pp>`C?_u7kE7{UwHY_KIKc79(nNlSoil+b%%3Z**E>zHs+TxxLtW^wU~0Bk=3tL +za=smt6RH2ck}SXEk^j*;NBs^m>p$Ag_??ty#yogbKBIn7jPse;oVJv@Y$-37Zzi1Fd%}JN*xN)Gr5HtSzZGm2dHrcRVP+*?Kqr_W;>@ +z$EkmQlV8dyrrv3OU9D(V{~_sZejUHgPrlY8H@D8=zq#?>+}h_iw~oh>rVrO&{>|;t +zT=qA&E>m%5dA;6mZnLZLH@B`+nVsbcFjsza>oyg4mf%>LO- +zF8<~={0qI`+`3Q3FN}qk;%{zUC*v2!!d&^yZO|9&Z*DMGesdf31^(vN=@sS+V>7?N +z-`qOC!hB)uurKg8H+a4Bo15bb_BS_pJ^#&(|K`?Czqw6owRY^h_wpCUZaBt#VeFvq +z@XuyC@74Rl*bni~W(I%9{@D!7l|P#q{vH0=OsBof7smGg4*zTh-dg#ynfn*Be>MZJ +zSN?3K6z2G6Gw^!l&t~p`x$-+%zg5i6^5Zb)e>TJaY^HtwZ03rysqDr5FaO!h&D+>N +zo7wpCKff^c;r@DmHZ$f^{IeN&DgN2a5SS}}HnZvFe|}-?UGNt8XEX46<M +zrq>c?XSo>W%Ad{jS;FirFNL}CXEQyQ;LdX1*UT5j_Fckvmif+dd+jXu51)2+?Ol?{ +z*erJHp2K`$?A-?Zvzgu{dOORTs{Z+fvG>4B@y}*9R{iq}W0%8R`LmgxCCtupo&o=C +zrf&)EEax3#zA!eU1b3EUj(;`-A4T0+hPm=*GqYUmpUuFW|Je-xvl+cVoB2xKdcWhg +zPMte;xMG;*hKhInZ|zGK%GLJcn?y^UERFO@4}@F#CIdgz`QZyPU9mxJ&UJ;3b$MoM +zNREw+#AZg@Hl(a`LKgVKzi>E85ymF-Q +zQ=a)r_?fePrl-Tj9g=~JT7O23=i?^1xJ$fvu#lN=J`$4MT_WylqT|a`*8L&NGK1;< +zaB*LuvdEliFcqAa4{S~x*eM>UmQBSzQ%<-zOK8ZIy;U~vBA0two3kO$(NJJ+3Cix- +z5qHOE$u@CBjci)#GYtwi3{D2BYW!7oo*_+g!@zh$hEQKdItwlHWUs~M{lVq#7me;nS(8Ca(kOK}FOS%k7_nLG +zRwqmSeUc%Z(_83MBzp(gywAGqgWH_D3LU%h%u9{Z&EcHU!h&4$ppa}I7_m=|R&7jK +z7lte+3{qJ*r*kr}yw<r|dmOBj6J?G^` +zTM~X**oaO?DIo~W9r9S6naeG267aysU +zr7WLh4h#K~f#y2@=xWbaS8PC=b5@~aR-XCpkQ^HxiQN)iyCG$r7_xW`lG7E-X>1h8%n@|AoDO}lK7@P4( +z%DO#dx!qv;_TSFRmA&JYqlEoE9!XiR4_W?XFqMQW$Nlw!bAN$jf4=$e@R_>#Ooidf +zp2D)ekEE>k2QBv-P4B|VtaxQ-;V1YYhk}+vM$_nU<@CQ^aQ>9<_^HU;H7L8Uh`9Sl +z$L~y83xbvcqiIsOcvLblzuG^))^ksjTs$IP+)bz~F#lvQJsB?UC=}0=z4L9}qb_$w +zo3psUQJimXFq-SR-v&twi4_e%z%b^a06o-Ho-fHr4Np(7{HydWgI +zhezDEL`ycLtP?_(g9ej5+|VrI( +z?P6h#EZKb0uyD>0VOPHSZ$_z0IA=gIFs{ZwuFi9Plbn+o&*>v9C^An8%Jy*)`;chW +zu9S66(6YuT-FjZG+LKtcUK~>EDQJ@GhsEo=2onlq?=qYBCzrizoAcm2$HBQ~w^15# +zUS6~#v1qG!vQCz|`J}>deNUmZQ1(u+c@MhmBio#%MUHr`d1gqq4~^KTMLET&7X(lSeHobn&^!3l=aP!WrabyKP>bW_7$0j +z8l-~rvbZ@R?i4-MvQ+Goa>7EE(3mTG_u9M#)x#5zXTZWBk> +z$kI}uG$`CMI2m}Y#{XKKXK0h$GBDnfAtbl{PcgX?FzKOSvYExCKVkBa9wzWy#pEFt +zlg)@p{>z973=xz5gvmpQ2@DaFxi2Fon^{cYMJgr_Ato?HOyFm7OgJX##^l>eflgbd +zUdAN9ip69lV)BeGCMyvWc#fFNtwK!xh?u~TFjk8?1egp{FxkmsauZ>)R1Xt)u41y3#bhU9 +z@(Cpq7$PP&5hhC!6Br^UA5${f$zlR8QZZSIn7|M*fuG5f2~Q^JP9`S-lbp-Rv9p-`88Ly+M9IXCn7~OD6FZB^pE)KR +zlk{Wq?|{k83MQ|zm^@0DtkA;*o~xLwU@>`>Frj1uL&W4!!ej+v0z<-tlF6$qCh#H^ +zlNE>w3<(pSOn5SBhh*{tV4`#;pJ$*#qS2@DaFt0F@c}SlL=2I=}so0OMy;>N@sF4 +zn@slD5R+|snC!G6Ch#0Fxr&lWEn)&gOePgJ#AF*{vdzX~Qj3_tXToH%+lH9HNd*)5 +zAXLEDa!fcT>Br<*z~mYQljm4WZX-+{*24sztC&2@V)7heLdgV%h{8E&9!5-HNSN?s!jnlmB$Mv}6Qwh`noTBqRv{)|=wh-8F@fiV2_=)a2@^J% +zRIEZwz939iv6#F~n6SxY_bS8$PO6x!VljD}W5O{>KPE=NWUzus1&hgbgvk;;OyIeS +z$r2Wm3dE$2k_ikElj{hRC5QE0GKG9 +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 +ze@Tt!yMkkKcHc<$jnN8I_)_4;f2W +zPs}eD@2T@lg_9E^*;&!~*6^jk@~)7^3jcnqZQ)Y@R|N$^Nw<5uYh5B +z;^;2%*J{rPaB@r}droxx`joY6$Wm@FJ#=0kzcDesLaeCq{MaNHcZwGe6e{P+-fwN* +z$u9Q|(eYcwqjjDPm;0(VXYpJ|aiO_5D7(i;+#{j~c8ev|vT1?OG$C9(G8u?g`=hm< +zwM}yIn0P}6A!nX>S5S6Oinx15ODa;q_FvYLYyv(YsDyd2$~h;9(q*2<=dKGW)OLwBL2K=#T(OVVI+o|i|g +zPmI_mcB_%4#XhNjIA^fXCtvpdyUjbmWxuA)xofUtSD|^SLAo!T(^uG4WF8ch?N>$Y +z1EWb#VghfXV)8X&0z<-N3Su&eFqy()@-<=tCkc}&h{+_vWD1MP*Bld$N%}GQ5it3y +zg2`zXliw32)Acay#cPPnZEQ`rYHz6iH^)PwyCd8yCiwV4mipj@_2@DaF%9{|Ao`}f{ +zH?f#}jF`Yl!~{N*noN2kCh$QhnS9JK;h3Z!lji`FKPs4f%VKgnVp2I(50l#wlNYA4 +zn0$+vj3rFIWih!OF?n$+Vgf_N1Wu}$e9K~TJ7NN#Nlhj&L`>i$$An{&ZcLT|CQ35d +zufb$8VsgDMCX*49>sd_TO;k*dA|@~-OeP~H*Apg_Sxk;1CUBB4nT(iRPnb+*F*(XH +z;h3Z!lWzeNpMpt*#bhO6GEEPYm4wMO7Ly2KvY#-Cu$ZhQOr{|wFhoq?q>4#|#bhO6 +zG7T|-Az}h2IVK#FbYrqKW$pNtl1!FqFrm(5xGpBtnG9z!fj3bx`3y0EAz?zD$#B9% +z)0upRn7~QGggTSqgo&mz`HW-2F-borZv!TORxmlqVsbxWqT89=Pnc*rlaq+aGQ#8} +zi^=_j33VngL`>kMipfb9lluu1>P%pWn7~Pn3CASen5+Oylw|Ug1{3N`ZqdbrI+I&i +zOyEsaOpYTaFeFTGSWKQI +zOmsVwCkYcxXYvDL@)Ke51B=O%gb8&fFhoq?q>9N8EGAD9Ce)e05HW$1921U7nlW)L +zPFXu5EB?8CdJg5bVW?=)pRBwAtrDVF@evd +zb|zgB6Zjz1nS8`C;h3Z!lM2A3R>361Vp4#Z6zg^-1&GPLn$9GIm}C+rAr_MY#N>C> +znZOV+fs-mGAr_MY!~{N*+L^!*F@cjD6OKu`F?kp;QIbie1{3N`#_D21oyk}h6L=F9 +zlP?hy7!oGbnT#b&G@Z$phzXn|OsF#%OPFXnlP@_Y9Fz28auhImTfyXe7L#R!iEd}I +zj4;u3Cf_3_m4wOnEGEkc6Y5N0h?u}h6_f8-OqLNQ)S18#F@cjD6OKu`F@Zf3w~|bX +zHJDImlBtUcbtaiCCh#UICPxqx7!oGbnPd_sn$F}1Vge@#6Y5Md2@_3ca)e{TF-bor +z2LO`;3MLIKCdGt_Zf84 +zq>;r$AWWz;fgxf7Cpjh@lXPPOdnR@zndGpTNYt71(Zl2J3!bH=Ve8n;0 +zn4}+*2w?KAg2^cslTyM&w=*dvOf;RzDa53nFge9yQc9RmX97dS1Wu}$oMJI4B}}L@ +zfgxf7Cpjh@lXPPOdnPd@nFtz8s58mZ#e_POEEW@Z6BU!s5fc~^Ce)c^5hj|>t +z37k|hkyuR3gb8&fFhoq?B*%nfl5R|3&m^WKlNJpo)S1lE#e_POSu7^-CMqW1ASN&* +zOsF%NMVM$hlW!0cI7ygLXEKX0(R3!?a7;KR>BpoEFgdJXa)!lZ9bux|nXDsBG@Z#A +z#H58VIm2SIjxeFl1crzSoK!J6!(y_IFrm%_hKLEA_Dn`9$)pd9$#m*W +zI_qIFjXIOgEGF5Q06Wjm7-A0j4j5;1|#q;@8q5fk_z*qNOA +zkYmCzNk1lA0F#=_n4Au>nB*fSIl7%mK4LPJ?My;J#H0^mA_ZAY@)471)S18#F@ci` +zCTD^yCi#d7d?vLsfgxf7Cpjh@lXPPOdnO~5WU@taHk$<-_-@FprIUmzwh +zBuuC?xtcIxJChS%ASQ5fO>)@5WcH +zy8J)ke@zz3)%N3?Qr5)Cf{w4MQN?%f62;4lYaPtMr +z4gBj-zN8-hAOF99Nj?1QQNE-e{te)l)Q7%6Zs6a5@+I{W{FA~jsfT|(%9qr`zXA12 +z>S2i7z)6*xFIaBiUyt%7_3)WgZeWPqz{&rk+{iVu>1v;8X}FfV!L$bS1#62NevNdImhb&nJQ&G5~XEHFO&M#JbJWX;#pLj!-(2^^AU$c2F +zF8B0kbW_T@F2uj2{$J?E6Wc1_X7A-Mso!;sx$$KBH2f;arMlcq!>@u|s^R7sa`PQ= +zbByI?8h#bzQsQPB^Hq>1z9VjqvD{3v5b}30&JMOKzjL8BGCOL@7LS0O95R-*0Ch#U|c7fY~l`bDq?bn9wzTjMNIBsF@ZNx +zF@f8F6ii@P+mqm{4b8XEA{{Q89trfD}w%NSIJ(Vkb;Aok;{Sfs=#@btZPg +zMAMl>I3^sE^kXs&FxjPG@)?WCNWw(7GZ{&kXgZV65R+2E1g;1|OhytW)S18#F@cjR +zCZDmGj3i8`Gl3yu0w*~p9FufoVozB+o>G!YsRk43Odin1ggTQ4SWMteR7~JDAO#Z` +z5+>A{JV2OeI+K%#37jNMs55zhFwt}-Cpjh@lk{Wq7+|tb!Q?oL$xOmTw=kMipg;nlbM7GbtW)GOyDHPgkzF!OjZLXN-~LSFrm)G +zp^FK1CJq)8coP*9xD80b1crnObtVqNMAMo4fSABZ!h|{#2VtV=On%^)a7@yVNngNZ +zlY+@dEGFF%6G68#>5iC`X*!dS5R)vz1g;1|Ou8c`k5Oj=L&OA5s+fGlV$vNkfzPCN +zCNM-y;3UU{W0Gb}nrta+$C*kp$zm~ioH~;tJxm^>&ZLON1l~l&1a1RTFo7XrB2Z^i +zgqW0RI+GA$0w)m@_)KbNQiPbm2cga+#4+KRq#u*J0F&nxOul3>xt1`|?M$vEOf;Rz +zmx#$e!UV1eLQJkDOsF$~Az}h2RZPBQF}ap7q0R(`hzXqJm~c$ejS1|T%v6%eJ`E<+ +znXJ&oggTQIEGFx+nEd{Of;Rz5yZqyn7|c5h{;gGggO%#A|`NB#pDQ!$xy4b@nDj$T;4`V62@DYvILR^Ln4}vM +z*fVh`$z&FbNh@_Gck5x2pw8rO787_A6%)7(NWlb#h)D}|CU+wy=QW+l3B&|WA|~*e +z)XwB?!~{MFbtWe`CLELWV`2eJUQ#gmip69iVWQiaOe9P+oyk{-iJvfmD}oS{iG&Gt +zCNM-y;G~MlS1cwI2@~o}V2GH&NsbA}B;A<6o{2+ACVmYj)S0Z-#e_PO)hs6PCMqUy +z8<2tt3<(qJOjZ*nn$F}DVge@#6Y5M>6DFF@9PsEGAqMZ&csQWXgZTK +zhzXn|OsF$)5+<6?N%O +zjV^n?HfOxR5zjYY49T$$k=PZ{8JknqtszU1K{AGg-pRo3I{#hOp68onAtNq~5ccJn +zR~V&R!oq05oGW{G*#4Eiq<$D|qI6fXOJ|mwe%PvnbM?6Ci>=DhT$USn6NQ^ua9@zZ +z4GfW+KG>@KJr}v@&9*92g2)Y=L~h_SDXq$>T;v8m2(~ISgO>uSe8*4u<_jU&-67(> +zB07F^%32<>6c|j#aB=TsprXz{zuNO$lU$q;FCHOO=9!lnO}B)LM+?QdvbVzKo$qo_ +zZgUprIf@I+4F;2NUOuoPabUYxQX`v6eWt8%@z7)-TH}w_dAhmWSMo2ZZ*!LBJ4%bp +zGlR1I+K7EzUgm7Y~aUcM&oR%twN<`{szdOLYA9 +zly!g5vfpSL9xfgtROWL`EIW+S!1MB=io~KV;)`{%l;M-+hwC$hgN3p;$L6hf*|XZ5 +z2a6n~x#p2ZY20}^vNI9cD8BoD117ME(p||en>3hUs}f$UiwU+WM;Ei0z?-O;(2XZB +zBuubX`TJtRgl$!((2XZ>k}$zm<LR2@}0m +z<;VVn3EQenq8m^02^03llTd%c1Y4COFhoq?q>2f9*5JcK#p2 +z()}O8hQTJvRwbF_YcRo9C2Y{e1Y4D(1{M=|6BQG>@dSp13AQSKHxMRlt1^XdJb{yh +z3AQSy41@{Ws>}>?OgJX#$K)Zv%d

NB6F8}2!rpjt?k2(nTa}+-h?soBG2xiV>Bj^%QMM|{F2#nlNE+JPGwcOm*cpDW2^sRk43OzzXgggTS^SWMteR7~i`6BrUE)S28zm}oi^y72@~5+>A{ +z+((#bI+K$e6OKvxG5I}U@~VOfd*jJ(HxnkhoypCFiKa858&Cd5n6NjVgl;BGs55~f +zVge^sOxPPw&fQFyP-g-|#N=-r6OKtcU;>*cpDW4aZyHRfGkHQ66Y5N!U@?I=Q8A$# +zPhd!xP-pT4VWR0w=*AN`NtjS)@&sX`=}dm$m~c$ek4aC!WTS!!d*jJ(T@aH6x}8ZE +z#NA{JWQBqIup9_1Wpnr)R{a?m}oka?>QzMlk{V9Jz!FyV8Y&b^4nm-M7J{; +zOqggo6T0zaAz{MacoG^+m{4Z|L&OA5s+h1ho}3#@m{4Z|L&Rhu$An|j4w%56$(u?t +zS*XE;I+J^KF`>@nUKSI06BQG>@dSp133Vp-5+<6?gl;^6lY|L%CifC1n$DzwW5O{> +zKPD>ylPU!h_QsRnrV=K)oykNIujToCU8>4guU_P+*HDZ +zIujToCMP&19Fumy1olkcRFcUF4JOo?l<8tZokN%}Dv4w!6FFkx>z`K>o%a!j`~>5Z6tt?5kY#*-<8347y7 +zs5fGAoH`R2A|`NB#e}`_I~5GJ~v$qj^wrZb@%Pu?L+*c(qmHxMS&nZOV+fs-mG?2RYqZXisk +zGl3yu@(#y@W6}P#Ng#e_PO2U$$u +zO;k+i#uFG4Ce)ccNSJ6k6T0yPP7)^6nLJ3CXgU*#W5O{>KPFECCa)=&us5Fkb}M0` +z+nL--m}oi^y7A;3VZz>c61tTzq0R(`hzXojF=1~!Id>~zLY)Z=5tDNq6OKtcU;=w4 +zKP$=PoCXu>OrFxkggTR_SWMteR7~i`6BrUE)R{a*m|$npB7YspA2_T>hYlZo_x*S8 +zGM6g6Tl&lNw(jONqr;VJ4_|QZ&vWcAF#rARUfHzPXX+NN93U*KTAi}K60+QHFrB<` +zR<7(5ugnsDg8v(D30V#qOpk;sR~)|J{HcI{N&UDQ&zDVdPSpLOK8iVxUdAVw9qH2#gq}o&7B-i(d*AEjW(e7J!bPxaM}NF_>%grz|Drs+2QA+lO}k+@C|=o1_^HtRB>YSZ|B`z9 +zz-ZOZlyzayvd}0^4d-Mf1Iw%Z%WFONH_168<2l`hV+FGJNt^eA%ib}%Xj{sw+AiTji%?y&&rj9?G03{|qr4h<&Msw~mPWEEm^M1#p*#N;i) +zWG{=!D#YXnVX}(F8d4({cWCBCPWEo+y95I0* +zVM58|6&4eCk&4N3!~}+f2~Q?GnY2SPflZW`lw|Ui1`}#k{-BG=BZ$dQ8cZme93o6K +z$>b5lksYOyHo3 +z$wMqA<%r4eD4D8E&9zslDh?v07@CX`GnSxn$X +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 +zf{P+dL}&8yc$nag#$Y1mOmIH4v)g*@OYTu +zg)x}iHfMs@$6zucXL8sN6SwG0aM2HwJP{^h&IA|zF!6}aQ* +zHEmY)8?KzeYL+mtMWhG%T=|z>q1OlZgB4~UxBUz!?;c1R?mBB`&swY*$TyJKKM<`O +zE+(s?&$ZyPE8}|9Q{1ht5ND1-RzTKxj{4M-dTC&lPwT@@qccSFtH8`N*uulkZw +z`jf(Sbw%W#)~lcEP72l)y;m_({sPpzutEJxyq?sb6ss#LAs4!j`qU4eQP1yA8nWK3 +zK1UeN6_MZI;`3+JA>GZBb(sJsQ5>38>(!swulkx}`kQCyPW&fMqBt~fu2=8uZoX>0 +zS$(3&a6(0Xjn66kjJmkHIa0UnY{f|VW~kY`LH!QiGp)ZlRCfiR$h%PU?gn*wceB@e +zv-*n4aHWKlL0|h_m)j>_pLb}aya;NFHmDbNm(CdOTFtPl+pG^GUujBzX}GSrh`h31 +zy{Ef0SXWx;v#s7?JO4&|)L?aKk)c#Y_H0nc3ciyEZk((GJ1stS+8H(3T^c{!b=|_I +zFxL7v+7kw=bBYZ)1i9AXYoC6(ed+a`H6!KO4$Z0c>Wc23@Zqk@ZR};U^#=0w1o!tO +z=yV0-F^8```f_{L_3QN`<-9|azh1pg@LjLFalHu)GS;)m*Aw60lc9@M`fN2jY{VNC +z_YGFZ5{B3!^8NMPQ-Uw0=0?f^P;B;bJI-*^x^t3sO)B!M4P01vPQq~4Y%@FCVx5b8 +zIZ6FFvAVS-h-`TEhOk@9Du=GhJ0a=~}>$c-)gKysV42>Cju^>>8nvWtAS +zZ98mN-l&ibR-Y;~oGKvOH*hI}Z%gBiEe+r^i;oLG!xeXTMCx`G`)t`eY^UC+NFA)+ +zRbuE@l6ekah5T|w?)A$iaHGw~tvJK&?bZbicg3}_ac1lL$fpbI*G<)>smKoPE_6cWAb+=Qeli;&jJKNcnoMNbrH$8{iPIGCr>K442cbOVja6pRIL=t?Uig +zlEG@8Fbp>UcbkvPKf_gZ4+QD*3w^ed9kvhOa77MQ=NB3BRpcdy&n3I;%Dhh30gc7S +zrJmu+x(DKhyPOtw1!Fz(hAVNfx~kYvMUdqVpDXpUEARSX%}Du5ho);iSJ^!fG2AuM +z#*Ub+LEhi{vi_KVT76e{(%)XaSuG(zfXT=gY|^e0Wx)d8GDacCZ0ul{Lw +zQk<@?giKhk{vBSA>`$7mD|#0vQ5+h_dNtLZ^wq03tIri0&J~bvd0z3UXPi<0tUJkr +zizS9kB^kLv-DbGzYo6BM9Hz@;w~v&61T`ORP#?s_DgDh+x)a6Z6Yf`h>Mdu~%etFK +zUcFhpO=;LxNWQXOeHCvc>u*ldZL{MfibJz>z4~KZjP7qv)mRZZlwH#L$htYdUJPaoUXZqOj@rl5_~6X +zZ=5^?PBK1q=^1rScWIigN9nU2-C^7EM*EV%>K?+-Q$!9xU;B#7?ZMY~?guGmpL**V +zbz*nV)Zwn9X7;GXnv8rsQ~GkL-ssS*S9xs9a-qJt=VC_@P;dDu$n9~kSdbfz{LtaaNq{016qrZOFP3=zu{60 +zR`V(YUqZ&O=Tw4^uDwBjPcZ4jFv%T-N$Yr+RQh2ubX%BI`eB0CMVPeuVRBZ4N$Yr+ +z;3Uc@Ool|5;3SG4CTB&Mw2p^Kr5`4E&oP)(j)%!v2__Ou?mSH5F-$^7VNx?5CJ}y^ +z&^U?m4=};&qcGWnlPG?e)c9eN@o#>Z;G!QU5q_9d{oD@|T=c^v{onjBsTmIwywNC3 +z3^<803KLxP!vr5wf{6r^JM2vU3U76VthoRGz$9b5GpXL;he^ZjVDkJ9KTPntA13Ld +zGco&Nf{T7Pz+d?KPVF-tI!U~=bS +zastis%NfbX!UJzj-Iul&y#SfDMewZ8=oe3`bVKPUA$zy();G!QUuZqs(z<8M8 +zjmBVtlPIGw!9_nz@G&K4A~};g?M%8cOh%uX9G~D!cKTuR`fXvd(+?B8?uW^%qBD8Z +z4-;Gzoe55&jKbt~5hgf^;)ltbewg5M5}nCTKTPnRV=&n{9wu)}Fp*$#=V5XQ!({O& +zOkNoelkFl*a1!MoV1n1jV1kn!bEf?xafz;b`d6z`(c8MB1}YQ^2&Ia;El#$ +zf|DqtFu_F;CXzFeoXPj#OuoP{8GUAQe1bF4`eAbIwlLB9VS?91n265gT@fY|oC!{% +zjKbua2osz{@x$a@5hfFyiPjGjyyqB9wBup&t^^YaCU+ht3ouNgM`2Po9wu@TCOC=m +z4=};&V=%!<6hBPr{4gmOoe3`bVImh{@~9ssxafz8Msy~1<6(j~8iNT=qKv`>7yU57 +z$CR9jYxi +ziwF~(MDfGqgdZmOoJ42xgdZk&&oP)hF&-u-B$!Arx$`iwVVGo%!lZdTOw=Mwa1!Mo +zV1n1jV1kn +zNuTIUaM2HwToEQ){V>5rKTMpWGie$R6THzFOmGrq6ehUnhY3EWOvsrW6Ja7c6I}GeL@&Zb%$eY# +z2ouqn92*Z4ywMm;#GDB(iZGF!iR4Va2WR5MFd2Pj(l^1Gh&dDQZDAtjOz^r06VaKl +zB1|SY6ESDv6=5tDCaeS#2_|!(z?^7yU3o|UK$URbs|h|n=`@d +zV=$SJGkHmbiResl(GQb#B22`b2`-8-5uM3P<6(j~8iR?LGr>g>CXzFeoXPj#Og_gj +z8GUB5a=bI~i8+%?w}pwAGr{X3OhjjLT7=1XXEG?}OfHEqnUFI%Ey85HGZ_(cCV0;= +zm`uo-oR(lB!Q{@vq#VOUJ_?h@@i18+!sNC&6TChKlLLXiI_97i7=UvGimq31fP@WOvIcC-g68l6LKc)5=ITKtI +zVInyb$(ei)&V8GUBbHNlyPITO!qVIt;C@VW>S(V5sqm`rdcV$Q@P!em0u#4f^Q +zf-@0wCV0;=m`uo-*d>@qFuC(ES&3m1KMIqE@i55{VRGA?30@zA$%LFqgC8cTg>CXzFeoXPj#OnNa)MxU8fPjDt;&ZO_QFcEVmcwK~v=uA3Am`rdc +zV$P&bgvo@QNv8;t3C={!nczLgU@{?R(ka2@Ujim0+xve1)n3M1RndCQyrHf3;Q8e* +z-J5ju_jSKNz37svVBXfchvy|F%~hSBe17?*?;d=7?s-_aXSw&^*Lc4;U2dz=Z$Eb0 +zd-DqeH+Ze(rwcqQ+CQv_@7ul?dds7Y&WcAN*=RiL+cHDYtTDQ`qzJ>@+l+ThI>jAi +z?3==?d>!);yD5V2n2m;P9fYStfvf|Be%B;Wu@#c7M)&0z!Z7zT +z?l5ED9nN=Tp&=Vjcsk}FD@*iM_eayVVM1S(CJb{mjCa{IiZe6zxQHsBZWdw>hx5Am +zXvp>z;Tc#9$vMWezQHAkJsS;NzkuZH_~i=3?wtf&6!eyFH#%KULh_o?J-84J*^V2X +zu4{~aZ{*;Ji(|aYGAOQ&@pSEtrfq#DH<(7L3!t~W#pujhh^(_B7xq;TXWo64eKDMG +zo`3h%A={q`PxC#<`b$E8V)g!;BUw6VI1vf5b`|{ITmH4tnNx|vHYX8j<*JZ{F6v*l_xz8V+{M|4YOL&^Iku^2(v9rGO>4Ijd(GBL} +zy;@DqtnHBO4C9-#@ar!KPxBmPEyEjvY{Y8gK~^O`@J*xBb(pccV}Q$A`){7EZzEWB +z4P%d*{k!LVrS~E>DuOSag{*D(?IcChwl4{N^H28Q9BKarG&Dznb_)NHZANGNlaSO$ +z@TCfTG=tIE{yZd;jAwly7qRYW(Eb?omU|;uE|k#cPovZ)7*E%{2v*(9*wdp1M_hkm +zy!0$&Eit+2`N(>b(3eJob{cxibBxaR$06BaJnK7|CTNaC@B@XA)Zv$@f@Z+zrWc_h +z+aTfTxeHnAiN5NbDBAV`q0fl~?N2~&`9-6%eGeqFjc0v3rwf`>M)%G%VOZVDc5bXs?Fe@=&AG^)6!%$K~gtft^fojf6fnYH+0DDQJj| +z1Qk1=xBPvhv*I~OE|Bp9&p^@^#^>CFtS=CK)lE^fO>J`1*=We-AUp#!BrC)C9DHHq +znw+jvjNKVGI8yN>G_Z*jXD9lqS-GJ3%IHqXptvETuexfopveg5bM8h%wgZG`U;`vy +z!n%F{u`41$#WRrHXgupXnj&aEHM$4yM? +zGtpOlDvGxC5c*S*gCiBYpy5B59k2(5FQYj<}wK +zhN?u0JHU9l&c@Oo(-U&hn645ND)zAe1Mc$cM8+`Ei@Z_MC`>vhIExD;8- +z@rRUy*pDN49scb4j82!Au`9y)=E=e^cY^V*jsaO8o%lCT*T^$-M=$HYJp6la`9~&a +zRuLrUn%t{(bFU8Bx(QG7Y-Byt^4MA5YPq2K+T=bznNoki*cZw8=B3CwAFqIUh_%K6 +z*U>c#`>M%QLBq*-T@@rZFF5zSPp5*0ZPCE>0bbk|Pupe?dY-~ReB5>I!UuoXL%9g=$T;LVY&YG_EB1ls?I-$0a%RsV^x9}MG5 +z1^iRa8J+FVK{8Wu?s;G7BE+ti@uh=!Vcdo7#;?6$tokNnpBGl;(^WzPFQ?S!7*Cfw +zp0-68-SmCPx|-;#E{&sY^9X(ZRAHEVpYRO)1d>O>`GKE8vee{0nM|n%7*E&EFjjq$ +zvG0^s`AYK;n;s8b2N?VHuqt0^E@H3C_<>(QZ~1`9*-k(*)^yglbE=?eGP!q7q12x; +zp01-ZR{b4g-x5~k>sf@@Ei%4m85*)JAv^<*KyqCK-?Ib_*>)42o)yR%NAy+eVrbh# +zgkBd1+SfpDIcajXmqC&@o%LN$5H$HF_w^)USnXlF*AppjF`*xb9UO6e&UmlODYcLB +zbcKhp+_Qu}7Hj4v6NrJ`}&JS#X-g1k{=^9|{&Pkx+LFg^73}?AALeFAx{(FyEvxbkJPi$1Qz-7wjQzE+Dql_xVqcT-1Nh$e +zsmbX&&DdAOgNkD4EnjSMR&0XgY5cS9LG0BqJ|`Cq+4c~gfo+g1m+?6((U46>cslMw +z)*_;>Iy;WGWfJ=A*ujyC&Crk?4=RcvnPocb+ma+`+D+~)iNY{t +zI{a_HnDFS9AnUV)et4QN%&j9l1J6RTE3C>lPyr3c;(-f)c3m=-^ALJ624vyud=24g +zo<^x({2jiqU!3-xW|hgk`sHcg4XeLpysHx^^?AnraOMZk`=LwIl1d{r2 +zUZ;Kx^V{TXS3**jxb>`W-c&(TXL8S*La812?HrV`>TekPYJ4hxzpR(xAF_z>lrBM5 +zyU9JT1s^@1@RY7V)+nN{nokupUKwAC8=fJP(^bRR(_=vU!_ZsaY;v}*hGaYz-BZwz +zKZW8fgg!r+Qui?SlQO)$W&!Nwu#Vp#0`$LuZ4#EB#Qf# +z(09ZRj&cYb%XqrzFjjquvD30DUr!!l +z2gCS*2O(L7udF4A9hC7sSnt7vXW(a$48`RYh}BF2u5*k%Tvp}Fc>uBXVSElgtw#w@ +z&T?dJF}mrc$f`EFQxYide=(k}Vj0V|6M7b_6fs^pA6ava?i74sv=W|yO^~dNsPg43 +zL98>w1QuIUdI6EJfD2 +zL|^sVSladkp|8TNv%q)<=OgPSlly3bFwFg)@g7a0xW8b^O`>f}3H?QU!D^tPYC6TK +z3H`|QtO9I86XFOe-WGr``v40j;96OWhVD!{DyBZ-pdIT_c3GNEvxc%C-legZQ(&^I2H?BKZE2-+*ECZhT$0$w}9xY9!?Q7*Gz7JKf6l8Ghl$E +z+~i(8X>i2#Ff?R_^UbqXUH%`Qu90uc-*a^x{GWtAGx}|pZD>wBZJSEyPsD(%p5tE( +zTpIaq~=Zm$LiMNCF0SiAXlRZFE;nO8Kiow6`0A0qL_u@KOQ^m1gKV|1TP6o%D2<2@;-xR>xPAfC2`6Z)K(!IAb2(2x@c+E+nx +zErxrtpt)#r?@SPe)fX7=&Lm3hVmw`!!&q)3q0djF)V=tnj8zXY_GOs)3lY0a#`i2m +zRt1K8EN#;gdR_eBNP7u148(wTHT0IVCTIIPNL~u#d$20Eo1E?CkQ~N1o-AlC$@rZ6 +z(2(t#$?2+N?3x%*f#0Ob4K(G#t-a<-tw&`r|TGFcj8upWxOeJiu)U5cg7EnxJ-<9 +z@IGXX#20rAZ98IgAH}W2hlFQf6(nCWxsOf}hPiIWdo-EiUdLO-)3!@S_uz75olf*s +zUyPw`n+g3ze1$YJ-lK^W_XXqWx+-J27D8W@L~*xpZyv^Szh&&n`0{)Ju`h@59r$*( +zjqr3VN7f`le+s{uQfN382P)P=Z+V5uSwTY5WpZDhOmQDD_9ZgDV<{T4WfPu`9Aw=^ +z^i}VQr)_D3zCQ+3;1Ahua#pN^qygU?{Q3Nm_JNO6 +zzV-QyZCw*OG+czu&&cvHE+VF#JPZT0hpc^h3SBfA}DOtd>^7@a^s|-^Y#YM`~#$H|!t4eBb8ydq2SK-^q`4 +z>yX^=fAd?%|F7Nfx0ha1{w740^+?4hr=Mw@eX)!h`S4bHo#MOB712raw)~}UWU$<~ +z_fG{yQSwzUp1!v7s~{dwyFR&DzIVvCZb&}2`83Hb>EH6pte?I8oa3=`YntzU0yIPZvMa!Rb +zp82_@_+o4F-&$-A-xplsH4LfBCkrqUy@&EhjG=ufFxXbE@ygS6_@gJ@ER?ue7>{ +zXS{dois8!X?(*u9Z#+Hay5p}tb@RI;$Jf33=Ob|~OP{{7VAHT6`>kt9o+HPPKYL~I +zl_cB1x9_*GS;wo7JW~CY>yMtjWckfsefAaf-TL>vSHANMU-RAnSMN}{@6kt{SNdLu +z|6!^=zb2x(OQ?RHztQ#lhs#1ozQ|vE>l=Bq!c+0HuP^og{<$lsAA0#hwfoS8=h3=7 +zuUMZyylT&%zjfjx{Qj?s&DQ7LC->~R_Q$_8_`0io_NbA)YL(~c%8}s*>6;^;zBKY~ +z9H+VY?`PcKrfszOp7p-xKEM6V^DWiG|K3sU_Vzaa`CHos`kTJ$V@Lk;|Gcr|)Rph( +z=Z^de+JouO8U0M*ZPkJZL2Gnggcl;&GNvV(e%IU*L3b8-mLNWkeGguUVDlLL9KmhW +z>_tiYGz3aAY92*NHJS}5$)tH2HSg1`Ld{0a6R5dHvl;QR>@(0FL0>VegK2MpX9X&) +zbq+&A5FKA&nZx~r1q~szj#10$ +z0meH^xURAV3n>M*1R+IbixiF)*rp3dRW_NhrNEXXY*E=_g;$NvPhmwgyBk)-vvJTh +ziG2vVVps)qMX_4wieuBEE0WbfS1h{%8p7!+vvY5nB%!{ba+*-D@?;`5hE+4UA@odhZWL`R@Z_MTdZ!B-Lg}rHceda(I(uPiG^=O4 +z3c+b|K7g7UoI`LZh|Vae3=w7*cxIxtM(2lcD2#r|oGYU@nsa06;{}z=gcT;|HP{-= +zz5-ii?B{SOgnpLEmDArb-b~@F(fK^e-sdbp*+%DMD7(h_Fv>PLpFyYgIai}oM(0j+ +zs>ZnmoiaITv}>QU80|7TA4j`toSV=tlXExf-{*V?^&6d9)L-M&pnj8cFRF@VLt)+| +zRt587*qJadirotH;@CIP8c;i(TN((7Iea- +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 +z(!TlYpIS8bYlHs&TZC@>W_gZ45*2i$Vdhenv8 +zMt24Xy7C{=FJX{=2}1zCgyH;FUxVT;T2A(Tv2_g%q12D6=C5(KS`Uqy0 +zw1kkWsW;(?;+Al73-vWTQPL7j7E`alZN)7zaufAA+*Z;ONR_^nYKEo7Y8hEd^}x~+btt)( +z>VQ4P>Ijmg24GJK7euP4CYV#qg^?Sni!i5z3nAA~r(j1h7fzN@{jj5i3nojbV^I3z +zhyVPKA66B6WxSf|gH^U_ZLY+;~V41>Qhy=ElQ{aPV*FF>_;+A`bi~`qJEZL=g;X +z(G>HVLyAc7KhcZkHHQ^4@JsZtc}LIE0v`b=VpKUPZLo)nttaXVIY9bwnEkYEZa2^^kTF +zFr#{N>S1jdcmWlgQ=7Cg;4SolIrWG(1ROxK&8>&DQQ%GVnz{9`HXOWy9yhl(Y2(1V +z=&HH(h&CA1p=5K}A#Ef$fnGM39oEV~GumV>YtqJo4)mG1?1(lLG@&Kt-b31Ga0Yjsd69$L72v +z?hw$36lVJ&cNAzxRjste&HrtQ5gFypIHyaMQBf;zFRkPu+TLxN? +z#%ySE$AV7eG#ie%L%|WW!aQ`y9Sv;gta<3LI|3X>d(A^l?s(9JM$FOcBZpQ}!46r0 +zd>T2KA{;W6dhJ(B9%OijG-1f&K1a0 +z$r;qsj&mw`1{p#{Ix-7drjb*qRgO$m%M3D#n(H`G(2_!?P)|5cs9Ms=aB8|^TS3co +zGMU=!*rsYpBjc#0jw=N%sbo5}$8kl~l0gPjGDlK@dK#HP6*-br>KSAtmFZ|MP^Xa7 +zscnvCl{%f2QAv){0`+tRk>+= +z47J#Cu^=~P+Xu +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 +zo#E#ON*dCVwlh%BHLGQ}usiY%vB +z$}Xd2~7Wt|%)DT%jtE9~sYKp9+wbC?(8Y4?-jns{y=7^2f%ZO3m +z5LrmwvcRZUI+FHlyw@I&q^TT9`%xPXslp*u3PY++O2Q*)cqC2bNZMM2AcPo45)g2q8!Xf-Y)B2to)_fS|`_Ap{`= +zsX)-l2tf!zDiD-`5QGq<0zv%;CkO~BqA_O4>sX$OJLJ&fb3Iq)z1pR|S&|eF`94Ry_u;c$}q|lG2j|@E- +z`9s&%SFP9o4}S)okH2;JTc`3{cRT*p;cuPFZ(TC}*8PM1*8LBE2Azik8FAA?Wz%CV +z-pqlU9x9t2*S~lol{lc0Su|@LIS-y=7PmEqoCQJFqFLj~Mer_baa*HFCEUqen$V81Zz6<*|cBY +z6RhddEwo2&4c2t($#hV@5v=LfV`-;c8yxGcOGTND3X2k>F5wB%1D*1;P4`h}xPy9@q5$<(huxnaJ(W%}iR}vHo>tXLIb0H!Pq| +z8E@n@>C5Tma-Wgcs4t=COU=k@)>qM+9$9UO1PVC((D#-A-v8ux$Uvy9C(r)(d-H068MZAafhNrIrvzK +z7K#&FV1$*pLos3_46uV*C|+!X33kvOiWVC5vN|nf5nEx5)wx5lVlxb}NiCEhE`@0} +z>GnnmC+uhWnm10I4==HNw>L(d4L@NAG;h4P7(QeN+}>#60zV^~*CIw|Zq!rPUKSM< +z_3S-w9;zGr&wpd7>jTTOL@9*1aCkFC352+CdaYtTO!4)OsWh<|y7_vgx2IR%ovE;< +zkpl2Sq?$o;)NB=h+TV8d(S}JlpBXA}7Nz?{RoC$O`D^Jx)&!IUUA%wZoH6 +zilB#AJ3ZN?6h`@|!;?u$V33bGJyxhOH#zL-VhP;MH#zOu;#7E@A92_-#VUA`A932P;tcqV +zmpDRcViEXwi8GWX*1!lq=m=$ql`y~$Izu^P9Zc{#M<`t^g6cD}xVL(a&;X4opq!bXo +z17Sca0qOV-gaIi9gzrEYkWxVS4ukwp<^-<81h95=(H>d)VD^` +z=}Ynfr3s#Yd<^F=;QR%J`3rAfIkVrkfI4K1k@=jpAl=6}?%$Vhl8xi|9tV(imtmSJLa`BgR0Zxs+~` +z*BJxNrj6b%KQ?L`%!O2wxkhc1xq@CL?=xx}%_6#0ZZm3|%@VpxzGX}_n2T|Or_uz^ +zA3lp?^1k0=@~R=sh}#=0HbIC9&6^+yOflh}iV_vj&DLvEN>{o3r4{e=#XEf!?)3fB +zY#jUgUygk(6j2b%lgsUMMH*D_<_9Xg1;PSWPRhOWL^gOhsqp5DWUzBl?#&bV;N_yiTPR{7m9HRW5jyi^^3l?;r#r1gSvK(+EL$m5a(%E`LP`LI_g1 +z)AuiJ2tf!zDiD-}5QGq`lG +zz}IHWp}&>y1$;hR0sV{22voJ&(&?|{U4g20+dTRQxg}85X3M7kDqjm!`E2?0&vH#* +zq}7&5e=VN~jI`VG=)cLE10!uVEB&4PG%(_`71F=T#6WSYnMR+N?SbNUb1r>PZVVK+ +znOXET`AVSJXU?ae%9VkERx^XXA|DA1w41r~V|iU*pv}yoZ^@4X13t5Wej#%MwXJ44 +zeNo;QsBJgr(GTRdKy90uP2Z4j1!{d}K0PMa1twbY5v2AAdI66F;gO&V;5Tf&dn!g$ +z!K3W3HWe>w;E(LEdn#JE;X$@ro3aQGyu)_8r((sq@C-YyO(lr!FvE^p|8Oy$N|fu2 +zi6*m{>XI50jpj0Xsl45oXf{{VJLDHeUW1O8_f9uOis=pVX=A!EvW#w*cNo*nk=1mM +zJdrnn1z|xd+Zl0qGd=!@Dg208W;Nk<25x64Y-glp;dTaYXDDoEESQVi8MvLHu$|$! +z5w|mNJ40nVBMrARa63a~J7eMF_<=Ki;H>b0bNS^+iAaen=+*K8qrNdxL_P9SqrN#( +zLcQ{BW4a--n4T-o{C}s!n7s%=2ti5^)Qk{>5TpV@IS4`DcL+NE;4Sr!MaM=(MIHL} +zp}!p_^!6PxdVTO~oxw0`|4b@zKqIqg);Mw=JjX0TSUDo2ZMw3do +zlesjjg7I>Kzx&1L@BRtIdHGe$W +z1|PA0w?CR_a4*}T`7LBCyvcUB{jp>-JjKQ}e*(D_K4;@@PZV)N3(M9#apZg$X4!5} +z3^^P6S&!z4Cl|vw>v4Oci3@sIwdS#qY8YkJZci-P1cPi;^CS=gN7<-597QUila*@W +zIC23TVWsYH45@;HY)}iwlNy+0gYIxNapP~C+HYJp282gGzWR|5OKSrLgaN4p)QSON +zKq>+4#egs%m4G@hAPh()pe76m15yd79RtFER07(E0bxKY0d-+O7?4UpjTjIHq!LgY +z2802r1k{27VL&PYbz(pmkV-(!7!U@e5|9rA!hlo)!t+2FkWxT+9tZbk^7?4sxcpeA?QVIyq17Sc)0pWQd3`i*;JP(8c +zDFuY*fiNJYfbcvJ2BZ`ao(IB!lmf!@Kp2oxKzJVLdmhl}%>84{gL7v^MLqWPTZih# +zCLjHe8A5B#Lv<6o{v~SOLTLtvx+3wkSL(r`&PWO!l9Aw0cO;tbmj%K4j>v44Ayxkz +zJyZDYx-rTYMHWH}&vtsU$jLCwdmNq&vI6>fkJFPwPKR+`?eL_NBIx1OPER%|g;750 +z@MMw_804c)kCm*4qrB7+P9uwzNr!UrAU3{ngS`JgkLL&{*1?{tLIzyG(6 +z?fIGmO2>fsPG>lq*g^24j&LSf4Tt$rXV^+Mz;T}Ju&0Ry(9Dya_AGG{yudph_6)Hc +z4BqLq=ZMqbeZI+IPZvwzZobKB&lab`>->nro+(zrll+L&ZWU+1XS~D_N)wB~$4i`{ +zEU^Yg_(4Y~L#%`We$W}p5$j-r*EvGzVkz|UI%g*HVn7&>N0i4fVE^9IYIGGJsT9e52 +za1$GLSyRamVKytO^v@z!z}c+G<)1@th83*8(w|7KgKJs8%b!AShk0yArGGZL3NB_l +zT>fOT3r=U_mHs56!)3ecxpt#MwUa +zKK)d#3=FiI8T1wTNMNAd%%va8>jDF9W)6KzejFI^nFaIofD|F}W@<(fa+rd42ETku7d?2q?PovMteSy4oeJ*`hYJt2qJ&SVrVj$0_&!?ZrrGeg7J%he19}4ug +z>$&tJc~zjdP0yik$`1m)KD~f`E^`7kt$I2gmiGi|+Vy#KTy722wCUM&RK5|Y@#*>W +zs9YNuYt=L95qT&u)~@H#Nx3U9)}~vjkjDaJKE040mnng=)<_zCL3Rbo+9Px6`*L%j +ztSyp7Uze{2%6yUe^fPG-47Elw=!i4}L+xLCKwnOP!GJIzw%$DzBdXw0c37K=7d7xl +zcGx`?E!^-R+pSGmga_VXyWLZ<;#_!!9oME3#CDirmX%*lfWd$;psyUzmlI$xAPnd$ +z2lV9x7z_vl`pN-)IROR(!hpVVKwnOP!GJKJuN=^q6JRhP4CpHd^yLH?3AR-?`msa* +zF+S+ae*1urn=g{V&PBO5PvnD_iwbX{h=o+XzI$A{9398+_(tg_+be3Gy=i6&rLzm0GKHomu +zIyzTg(dTQit)-{Q_xgPMZD-OrnbB9Z*LE^pBJb*}+GjhRX2~smRV}tsda8V_uWG+- +zJ)I-h^o{JbokCa1C;CSA*~;jAd2`=Li_K2Yke~LA?6+;8F*32Qc&~X9T_oH4iuakP +z(G0nVlRSG&(Vo#x1GeYGuSDP1ey>Z{#vuBRz-UEjoB^Au{6v~OacSw;)w +z?R^t1rk$QCzv!FTZ*HK`GQKZwuYM9;DEIZ{?bA=A=~C;g(O7ucPziReilJ`dWIr{GhLQzkVjQ$eg~Kz52Kkj(?R337);G3a-#}w!N?+OD +z$Vqgu?CLAq7dee)%FTUcEs;~{De~36vi*@WXp*$`4egDrp~ced8`>9HNAslKH`EeY +zOUq=WZ)ktyOqw7I`s(*aPNvJ`1AX=TBBxWUytJ>rB~nW5^6kF*{gL%FRi4>5y*F|S +zT`iyPo8A{GqlNO0zUh{Too6uM-KsBp&d6LOaC}pFSo+MHSJK3nqlS+0&GApeN&mvdC +zCRXYS&mp%!2^*{oCz4vIV}q`63aN*DwzD!kn_LZq?R15ci5J$hqm|(#as%vUM_u7m +zvIk;Wa;1HixC|;-vdcb4+z5+VXQe$+Tmx6KPM1AJ+zOd&Q>A^j_yJtNHo5G{0^k&O +zq|%-wu7_LL5tltx{1B2@No8o3xB{wJi7PZm+ziF+U}Y##TnDx6pevLjZihTpR~ecu +zu7Vm?=L#i@T~Nj*D?>>_hk7>Y3Z;rWAc5sqdS{8t!Oikr-Z|nXSjG-idK1O9a5X#N +z@}`K}z{*IacedC89!6Z=WU&+MOjLT4L>+jUaCuY3Zb)V8E2n0OE8$$W-ZeEx+yblF +z;mWB*Q42S)!>*|mQ4fV|cjeSGUP}K%l-oGLL>JFAdbU +zMY3sFz8$FdMe^yCJToxe8p));kxvJv+ar1OkMfSdbX&wq-;pN*)4oU{jmmy}rox&= +z7ChVNEAX;7;yxTC>Ti!1=Jlnn_l{<9yg@ +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 +zXD*jDnE;&3hAXW}Utl#BN +zA-BUkwxiNNn_LAKvmGvfGT8;Ev++uQ64Bu{HtzDLk~_e{vMW8a$mQT-*)Go +zo=Q(5xfXV?9+xMD+y>dKy3#Y7?0{-k?eZj(olwd~D?Lf14tBCpmnW6%hGbS+8JZd=$i^t#q-{}lz6FUfg)Dg}k +ztKl#|>I_@S1~|@>9riS_0GfHS)1D7l0LTO?V_;`sklqJ@{2tViuWr&q9zz;e@Ibt15 +z@H$5*T`YxOUgr#Di?uMuCmo?oVS^z)=?q!LnJ~@s9o{st5cczYr#DNS3@`Bm4sV87 +z0YBjfoZcL9I(*29!<#OOz|V=(n=MKq%!R|7DM}#3h0|*l>tTwocTA;;#n8>wE*@*b +zugmZ~TID@D4!;emJ9ZueBII2WE_$F->hu^ncZ +zrFAcU$ci7bDtySAHV;2!#Sd8(K4e{xh`VOEYo@Ymb|LPX;jWp=uGuvRK?p%A5X8T2 +z5HvIK&}#kYhCRpk%*^bx-1z7MS}qff;wE!By+XDd#f|0?xGjr%$^5ejO +z&n%!{$lO3}tC>z;l=lT{+s%3O1Gz0w+h%6dH{@G^TA!IukI8j`iB^0xDLtA_{fkJFPwPKR+`?eL_NBIx1OPER%|g;750@MMw_ +z804c)kCm*4qrB7+P9uwzNr!UrAU3{ngS`JgkLL&{*1?{tLI(WsS-`U?EU +z9*tVXsDJh1x9azdjk`Tj#0f1dTl2(`^I@1}yFD@FZ0Kh_nkSxI4CAcF?TIEX=wa2G +z$3m)MlvTSuv1AhrvQf>GKnNUVqwa7Nsen#as)ggo1#pCwy2CM~3J$VCEgVm3V3G~G +z!_mb3ZQ9WP4&J)a+KfhxMy+DhRy1lfY89g{K%+*ZRx#=yqEVw!s~B}08Z{cVic!x- +z2*SgPDu)#_5P}ebR3K;xLJ%HSR5`48Rue)HLXZLk{Zke~5JHd&1kFPTLI_fUpqmkb +z5Q0=7C<`G7AxH&+Rv-i+1gSvK7K9*#AQcGuF+vbRkP-ypi6Dd^B?!tv2>J#gXy)DD +z6$iq)^@1p-|!Nj&tQk7+?prP`ua%6YSu3@zCN~`)5*#0~(n{v&ND0 +z;5lY-TVu#s5M(WyHJ)4q@3I!RHJVhyoy?_KE#yMr%;mPml5^m3Hmq3_$R+Rz8+QAn +zNIA5zBF!I1w!q7*$nB3I8{uKruleK2Hu#A3yZzBbgL~Ny&2J%F;Z3%~?T;m!;VCw* +z`4h;cfTv!C2ED9K3t7Zg7-MzrP^{PtLu^tDC5TI5noYXBQNjuPS-$3t6X(NAEZ^;o +z5og0s*a6KOFD`};*#WmVTDZW^h~~A3Y6vsp_Qr}$5Mn~}CI|vkOt`0_L)sVL%v=N0jUJkf&pPbDgkw3Kp2opK+PBs2BZ>@4+Fx0 +zR06{DKp2oxKzJSq15ycSIi3f?fRqBl^FSDoQb2ef2m?|I2+spyKuQ7Oc_0i(DIh!# +zgaIi9gy(@UAf#Nr5p_m^m59NwnsO1MM +zLIolo@_1c&Xr9P{8eUfs$`>h6#wW`|d7=R7`D8_?P((ul&oB4R73tvS`4!&zVm2(} +z2g<#QTjW#V);PMpSx(<&3ESN@+9r)PFXzh?jI +zgVy8E%*@c={{jaqvZGo!fozB4?5NuwB^=Pqk~MprI1gT6$!>d$I13EcsoCSjMesiB +zblamvCEU$6X?Baa5MF1S-1b;;4m`<@X!Zng34F$mxI#=&mb$|Vczfb=a6;q5#QnP +zr<0{{FW=$xXOp$?CLeeBGl>nJ;^R)gm7EEm^K6GFjVy!~p6&Exk&|JV_c%NmWCir| +z9;YXVoDSo>+TlqjMbN{mot|t`3Zs0~;mIT=Fvv%p9xGW7M|r6uoJJNyCogq|v&boM +zgbzBx8Kf8v@kHB6^lwWcZqFE9o_|&+s+cmePyl6^5_bW}~;t_l&9r+d^6?GmNSx +z+Y0&vd6!YuXe*)@$}L7!v#o@Je9ahXuq~$N$Th}DldYIuFP|_*8g0wyCGuutq}jHb +z{!o5u6gQX)Xt_)@ikr;k^a|N-6gQen=oY!rC~h`a(VOKf#z2F)h;EcCje#a}CB05Q +zVhl8zOX)UwoiWgC+UV`_W23ggTu3#UYt%NGE9h17KBKnLETUWGHlw!LETOyPTgF6# +zxfqAxD-FZHaQFlc3f`%OEyM$Y?R1A@$+>{PXQBrF$PT-wqJF-DWK9!eRJI!|>0`$6@&2;4u8}flc8~YK0 +zf)gEP5;Y|aPIQ?G^Z|K$aH7*prBBN*f)m|(6m698!MqNA77faM!MrX#j@~J?U|y#_ +zhdwS}4CZy~F|K)}v{Q%n8s%($gW^nS0s+!EjI_tIwN!Flk(MIS$8Cc`lKy5)DcOf1JVo*bw%Q7 +zuhfG>oskqeBqPD0?npGb_EyarDMAq3H%$OnS;T@efQ%S(gxosnc3l5Yp= +zyCbo*Tb>!5?uaDON9EJO>8?lueNf&JobHUI(r4s}U=o{;5QGq<0znppAcPkn^kR9H(c7%s=xy=?qozS$NN2u}0WHRWoZ)O@2f>dz!kJ_>U_k$! +zLqk8!#DFj$1#JB3DHsq2q!LgP2802r1XPRxVL&PYNsLgaN4p +zvN-^=nqQkyM{GWmQU$!D8S|0EX$e66+&`Y*CC +z;A^+#QYo(p_}Xka^tbZ8fX`Fz(ni+pN}?dQDOl!^JJ$z +zOPmBR@J@$4Lo5e_cRKAk;xu@lZ*thv#S*xiZ*tnR#i{T*KjN@widFC=KjO4o#ToD! +zFL8v@#Gdcr7_(DnVL*Y2b~BGg#vi7|?(H`SYoBF(3>` +z;rsbh<1io$NF|^w3-PfK&pC!GJIzm4GrZAPh()phOG^15ybn +z7X!k8R04{}fG{AHfO0S(3`ixQ6b$I^7SPQ7W6jBPqoSf7+wt!MgzEnH^q{)2W5+5| +zfv +zx|IrfEHLKN3+Zv05-4kpq|p~-SD>stGMBzDHwVhvB3blx`D&od7nx5#leWN6Yb1k? +zNHZ|h9?7K>QV$HZMRMqvj0A>!kpem`3j+16k#zc!d_ZYT-ur)=2`07L(s0ZEzuIxt +z)97<@Um&ktpG)7BS|G1Y&!Swu7|8SK^XVsYX`r`N&!8{MhXTFrdM^D)UKQwV({t#X +z@`FIHPcNXK%bY;X_cEYQFd+J>{Qr1NVL*ZD_DCN6qr4+9-4?OZcjSq{v@cRfqcZUc +zgaN5cdd=9goHrc!QcIQ{uR&0hUvS|so3tJ$ZYPP66KzM2-j +zl$Odj`fB#;>uD6^vAW98Y;hITusT;LS?q!`Hdz@;5<1kgNmnRU+yMzJztTHPTn=uQ +z@AA$OH^DM?pwgQtu7#`F0hc#L+y+)gD!sGC4)8GI@+OO&U}vJznZf= +zC5ang4?FIfN+p4#f0tJXXgQVpZ5+U?TYpqV9W +z_Be4Kyugy(_84&%7_3vX$BT>p7kl^O9Y=K~`d{x?>tQ|HQtRQD{E}71&$iW;-4Cl3 +zENsAFcR-X$0AoP7NMM@=E4I~YJ#5R8CNM?=ilC}%3=J@3+>SJHIw}qs6 +zcolhdTUc6x-=P=uo;GO?euL)dJ?+wByp1AyPe_`N-=v%Lp0Fh0ee|B*)F#cwjZ~mF +zwM&ce7J5K$3Q5&?Ep64C!cr{)y{3=0NptZETCR__OEq{WJ*|(1qy=~b-K~#?rKR{i +z`b@8Bi_StXW$88T(S>*u9oB0?(RsL)Ht99t=n}k}UeSl!qH}N)E!KzIql@tldQu+_ +zMd#!7bca41j!L+fKGs{>qO;LYWqM0{bP?W4kLWF-Xf-Cm!v=;BBxAcj&=v>@F +zb^1hmv<4MIeIgWHfIDcfJ`s*C#r^b^?r2kHp@-6RN4v5RzfE1bBc#m3tI4lB!pai- +zF1@4=wkdP)a+d1J9vI1-A*~oa8;=&5LH!|L-II*6-h>UkD8!(x2 +zBd!kfGMr0&5m%SF1`BCR#MNo8#1(Wl;_5cnp^c=-NQb!`YbY8S=`!okK}uw#(_D=% +zG9x41=6X!0%1CR6xeOQ3qmkAwb1m9wN2ImWT!l`0JJQ;1)?*&6k4$!$D{v`2ADQej +zU06l?Ba@w`6F1PM$Yi&~(nLTaAS(g+ML;4TD*??H0f~UD1azwiNCadhpb`;~2*^r6 +z+eJVkAS(f_76FNXtORtg2uK8EC7@gpkO;_1KwCsWA|NXPNg^N-kd=TG5s(PTNg4dvnY9*HeT3_wSR`;Fr_q9=zi3 +zSACjtS0Z*&iPn5X$;4yykk;I%q~cN9t~K{6Ie3EJ(3<;|WbCEY+V~O0hR5kyZM;uO +z$052`8}C)}@FabqjrW@g7^Ym!b;Qg-o%%FapP7OW(iY9tYi8p!bXIfqn@QM1k~VV0 +z%)()cY9oDS8V-`8jr5wiI6|g2(r+eWH&tq_N6buof*#dc`^;1vpdDIkubG1}dRuGl +zH!OD<#HA*GLCr%%H%S*-8kkOsFc&7)Y$1AD3wd#I%B7AphC`twZ?hxfJ3f? +z`;GIyfhsu>QjKD7V5Xc84MwpqP%dXewQtfhg=2wjElapDxLtzMvm7xlg|L3k>hig^9-14^m?6T +zd?ws%^!l8YJOv7k&0c3IFM?}~%|2%Z&xRGo8L!j9%i$j5jL%uclfY*D2ZLaE8aRyI +z-dHIwfo5a3FIK^G!DU?V#vHs7T8#_7SQSr%bfdx>oXPW{(WvkR%Xua&FowLrGF}S1 +zj3HmJlBa^*kiEfDUJL<4_5~|=4mb_&4LW!Q1P$&BR`F!WGwQwZnY<9LH0piva&CjA +z#z}9yj62{iCU +zx(sJgd&Jfyt-%@Ojo3P+m3SGw5V3Vj>o9}nM0z@;<+zX{k)AH84rkI$k)BRzHLjue +zB0b&GdQ72$NK=Qj4Cm1Uk)|$bEf&$%NK>b@3Rlu=k*02`9~sp*QY!2;S8sp*Wa#O3r#q^3K%4zp-+ +zWVj=`92e7*k>Rdr9hT7@k>SqhYOJG=Bg5U%^_WIwk(Q3=GMrD3L|VF{Yq5l`kF<0~ +zSK(@UE7H;(t;bxdi%fJxSD-`~ndpkTu#)yhCOV@|Tu)y`Cc2{=Fp<(Cjt=EAoK0O3 +zN0+h&^T{7^bSf)x8NC#7bSvvHljcVTJCxK +zl}aN2(I~1vyg5QYP5sq0OWkPCkiP{UmfB#?mcIkDS?5N3mV6t0n{_tWbLIOWpEYc> +zXUez0)vTexo+AS+W2ZOTZStM)U3R*`o+p0~GFkP;feiU3xSUlt3}nl9!yZMlNGq1oo^V(llMa^E8ZB$kiQKL +zthgbNEq@oP+0l)GEctfW$&NMza^?G>m~Gn_$dq@&Hny!HkR$JbRqWixfKA>Fd)T># +zK%Tr0a@eYkV;S>d;b7O;kEVr!?b2QD9ym1QoCw9EX~AUl2^4Il8TVg3#zS0D#w4MIcm>A +zsQ~{6Mbw_dQW+B6r1l(=O7I`(J+-Gts>FY$0=4O&l#l-pJ)kxnmP+w|(pI(UkW`F+ +zPp_#>JyHe!6D?Oq4@!mjcl5M6dRTJcujp=d^pIr7U(jdjXpdBdzosm;=3sONzCef7 +zn#0kV_#SOiYYs(=@HKixt?7xD<7c#39X=Q>z*p!=b@*_!3_qqj)Zs(X5`2q3R)>3{ +zmG~8vsVxVi`S=n&qP854mf{C=z1ngpT8wYdTWU*Bv;x1NI(6dU?`_J=o>ys5)}kEW-&>)R9AG +z367Jgj`Wz7I7yXi>p?RgU#3Sb&FdWa>uH~ThCB;GMykhNBwq$UGdkV&0(l{5MyJPK +zBCmmWjRv)}hI +z*d3T5&xTH;*b^v{m%(Y{s5?*~FM?ynQBR;mUJK`qZSFw6Tn$H!ZJt1}yb8`4=iGrp +zxfV_s=R5(sTn`tGRqnAF@?7XOR(ZyX&%vBy1@FE4;0 +zV~=O7Sat$8F1p7G<)v`axab+P%NttMpz?T+R1`7mhg_QZ<$Y8W>zxMPJ}f)V3_CuZmCVbZ8@2WRlv +z&}~$Bf<=58ylf1)g9UsMJYfuZf+c({d}zq-U_P&g0Yml#i}@-TGq^ig$ZH{Ha8JmhE`yW=zXTbhk7M-D05P?`5E31C{8_?aCtDNe}7GA*C9((RRH#tkmKj +zdP5&?Q|97kTCI<_D>b;Ap4G=g$^w+>UVS{QEX95Fh3;xIXQ7XBbyvH&5O1bF-4!zD +z;We~HcZJO*cn_V`N7~Fe*hG>((rzxs7K-X4A#*-9lcJA=O$l4c)LYxk+1N;xdTYD6 +z2zSw=dTYq6#sKZmTf=582I*~mvdx@}SJHZYvfZq~yXbj+GGs2m8)?5j88(;V0ZO{z +zXP5G1H-yAU*Wb%X*B(~ukEQUfFv@BhV@Z4y4720@SQ@_`CfM=DSR(hsAlvParSk1C +z&UQD(lKB=GVHfS$$(Xi8sMh?4&=Q +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 +z32a8KH#U%s4MDtIoqj0@hF +zgI7YUalsd>;)#%MRCt3kc|J566~16O&x8fWkT+PyOJSEWfa=Uj{!jI^FgHc_C;!El;T|iHYv8zX!ZTJPyWoPc$32!W#L<#CF8;O0W(2tSrTS^o8zfGiRZXa&=d` +zxe#xrKHU{E=ixQ9MR$eGC3p{=)koUQIoL#!KGJS3#ukd|BO!A>Hj|={giQ%s$<$lh +z%-PsTmAW-?y!Is_j%<&AEL9EwXL}mQlI1JmB)jMzOP6niDR!~ZnZVr;W;uRm3cm_o +zWI2t_B>oN1S+C!j#=i;gv))E$BHsuPvdw;HD!&$9XPX!az6~R-TqiA-wxw!cVjG>Z-EhZ +z!5>TKJ7AJsXbdKB4|KB%e=vn#4KK5b#$Xb^9G+l9{$Luv4nAZl!NU$qNy6yj(_9E*iG3URa|j%5OZ1O!<* +zdbUSEkbod75L6~0NI;Mk2wEi|NE|)0a`fyD0YL(Stb88*_X2_h1X=k!`me$Qf&>Iv +zfgrnpAOS&EAgEG6kbod75VTJ~kbod75R@h$NI;Mk2+9!!?S +zAZYrrk?CsVz_c-aVY+4OFHinCZPl83r5yYldQEHUmy+=aE!RemNH+WtJ*|!QN$L0l +zx?3CVmGbZ>^qDr=A5Fk^%F=3%L^Ci#hqao%XbL_+o3xtVXf{4guV^*>(Ih-fi?!h+ +z(JXwDp45i>qG|XD-JuQlMspGAV{N!UnuuLgrnMZ2X5!=Yh}O~5TiZ0+=^zNKs57N1A|2^>~jd0HG+6o(bB +zfmd05V?2pB!Bgy{Kc2>$;S+YUF`md9;W4()A5Y~0c!%w4j3@Ie;S`(l$J6k>vSjM{=xv-023|Cw)~T+V_;#xd_enOp|98^?SDm2w)C8aurMrE&>eXYBM1RLHro +z);RASaLAQ#zj59-P$efqs!{9>%#`z?!6^0x%H>R`Hja7&WpXL(G>-ZLm2xT+8{52r +zQn?tm8QXk;3ONT>8RxtKhg<=BjB~y~m7EMY#wzdFOt}y?8>@U{<+2TGjT7FnGT8yU +zjT64HN;w@W3}Mukj5<{qwJ>TcM%^TgS{StzquwrzS{StzqdqQ-S{StzqkijK;;U8h +z)#@VLMUU#OA+s6-v_o$Vo3$9ExAn<3b1q&<>-EWYvj*>?=k>{uxd3mZ{rY6sT#5%M +z>2CxC{ih&k`rTht-ucsngoL)*Xa3bxp;*;k_my-RylC{godtX$=ti%{S;E)A`^ILs +zGoR0c2aU}hXE9$1uN!CF&O*Kfo-xjNoOZqrJ~wLJu^D_0^cc0CSP@?iqsDP}tbi|u +zVdJ
JFG!r1MO<@5P4XzcdHiur07H!iqigOoK47q~^d=Wfh40(bjd@X!v$nIc1uZ96b_5_RhDi|}kJ6OnTA!cw-(9Y{2Zq&Qu +zGx%KSH>`bF|JJ)=G6M`5dpu*svJ<#*(LGiuFNKrFMbDUB-T+fZj@vnd&w{X#<8c;o +z5m3C4FNIUalqYWI8zAwm_eDS=pd!8kUNug-;|071o-$5);w9V#pBVex@qE4j9y9iN +z;>Fwv?-*16I-t5=ihx8wRswoY1SA5o5|CH}iGVBxB-TJ8AS(f(SObZGECnRiKq4SZ +z0f{w`2*^@EVhtn$vJ%i1q2BQvI0RR0)hktS%IKC1q2BQvI0SC1q2BQvI0T(2nhN^hoI?u +z&e$3zPaU{)YHIpS=1=|`ZyEbQpwJ&S3Qa$EF*9=Mll7P0xitO3nzvmca~@tpTXa|0 +zT!Qz|S$(92oGNZ6FHl}x?0&76&mRH?UG0;0bYKqP?3 +z3J`r$oD>p3WCe)+dWHZZ0Yp}SC|>}P03s_ubdvxg0Yp}Ss9FG#03s_u)FgoD4;_g9 +zd#|2dVS7Ho&tr&X0Nl97r`~gW}mZyXTu8P +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 +z53HW*`aV=$R-h8W}iU^W&%S0&kHw +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 +zpH?R_&i;Coo5!9fCw)D^%`=cK +zXF(nP6Dw6$cz3m%8MN0EoCha0R~D{k6*=-^*r&PD@Mf(kELGrscClMZ#w+M)b+k)L +z#~bJ~)sY~thg6o+q0E4==1Ah-WfghyZ18EWMEo|(={7ggmUiR>AGWO52W +z&CYb01tfKv%jpAma4iJf!D_fi8_B|9Z6povXR?j&VR9b-9w}`~A~?OV891nplwz~m +zoWhSYp2jb*+AcGf%nl_JnzRucj%Xw4xRY@k-^X|!znd!COb=DIE2)s@i)TQ;H(=v8 +zv-(`ViMD&lRTT5^it54_G)1%!=1uS*P=fF}=tP%&b)>O=4yF1Kn +zwAvFdgF&se0-b7WA=a{!seGKBOy=9^?M}0v-tJZ$Q00!#hAL020{gYe6ueR!4x1}z +zeYa_&d)@JBxX}||1ukte4e!z>b5Umd@^~Jb%HRs^Z#Q?*{*aOfr@V0oobmU?9V7-gN_u^haN&^MNhkFrjmJyD(qSF;A6 +zJy~7?-({zL0}1jRxSUn{29kzy>*^tmjv2d@Bc0zz^WDKT*yVNR<1?zuf%m9`Df~IM +zxl74{YqS-OPw|REQt3=hSxBQ*q(MN1<$fQp=b?gY)@FqMw4A^i!Ok7S%cf2 +zDHnmkPP^?kxg0)a)$V}|xd497j=7%*Z^;`GAHJex>~$7lq3THE +z-=QrX<~-WcrKG@I&6SGRXpU5V8@=Rqmf#%P5;lQe@;EColMN;EhuP*1a|xa8GRtYc +zCn&*#+F%mDmi~?v`vOTrsdY79&s6mUa))y8b9FFHPKBfFP3<1{haE~CNc0PKzdGEm +zq`?YpxGS25pKButcpZ~7cmtEO`JE(%%&jDam0TF`1ydp5b=q-Q9Vx>WbugWuU~)RY +z$j)?|X;k74&IOw`l8J-bNGdikp2c@Fp383{v(4N>54mGSIHHa?uvKkN<0lzU=Toe< +z+f1a&4s$kbcgHV-es_E!oM827{C#%3Ln($U-SK&Fr6*Q~PiU=axJzqJ=J&AUo#y@Y +zh9{l`OTF;|n9y2FF`$koa6j$nR0`oKPplNjwAN&FYU4?~nVrnxF1EYVlzE~mNrB0UMC+hhBV(&emno75@ +z;c+ZjD2fH?qmCjVMS4d>MMXfQN|oM&^bRTtB5jlo(xo>kArJ_Rv`DX^g(M=<5+Jk? +zNC^4X%>D1&JIyoyy?6e#zJHyyvKA*N+e0MJv!A`6{k|s$G2{W-H<;Lg<**gLh2XFi +zwuP;0WI@kn6|%f1X@Is5W45sO9K!1vqC%GTq+cu8Wd{8W(9ihW{S5px*a3hYz~9~h +z@UBur2E3k^pY%L8;1yPW%+oac*o$&bPm2Ms@Nx!E#q49@!r#JgFXUuJh6x{n8!mj# +ziVPRt2fwlKCQCg`_@ErOr~d-u0DHE$iq8R0M3y`&96P{$(3E!}CQSG=ylH@YKc;dZ +zPbG=jRC$4-nzYaKlIOz#8`Y%!rox_n158hZdEwtK9J(%j82({^>FJ8hLQHu1ad`GX +z`ZpNSg)mj0^PYSvK4P91vN(@m_y^LDVlFS-Qk6aguN*k7;=|!tpeoG_UmMVPvckB~ +z_Z)KG(@w=l%5(mj^bxp6b{Zq*)I$DsyRh=JaMpz@0}rzWUz9V#-4~n((it!k3j$ds +z&-<9u_sj8l4rhC)%!l>uH$Ckso|SgQRMJy&Ae{wsaG>|u%Jl`|XDgNqwyHiyJd>{b +zuzPxBHE_WNvl>|8^#i5{F{lC4{TPLX@)s*|3+3SuB~R&Vuy5d;*~W)48Uq+cjL?A4 +zvlaaXNa%|9!WmT`22Y>sumkYC0n9-RW&pDvBet;eVnu0TB^)B_$#RYSohOS5>|1zv +zcEAC+T6W2cm8%Op;gE}-C0POA!uhfTj>1s`icA>s0mWk&j)ja+h>&N$DvTMAa$KA;F*>czy$9dKrmxC2M|XvXBM!}R$LaaPa%Sy#Oq`pPogS} +z3C@y5Jr0k}LNjBK13}+n3I>GRmkF=&DUTIaPw>`6C9Ua628K+uyvix=Sj_?9)mY$QyJuJM8FOJ>;V4$ +z4&Wr%0e~IA-`)W%g@U6daMbj-kD5Y0fTJdG)bzKHnwr5z6Kpj9{zg+7Y&5|}^KWl7 +zNu2IW|GA-ITrLqz?A+GsE-fcRIn65|6vU_Q4n)WPCaoF&ZnPosk$6t%=SLBP}=?LZWA=}9oh%>*=F4l}*F +z342&o>K$8>pP4sK4YUxXeW6nMb!(`oy3A;#TY1r1v%HfIy`*2dNokP2ZT(}N7QRr? +z+{ezqp~FMHkSNpF+^9OR(Qp-OfYc(BOy5pCqy;VDMj=9UfuVe;6}qy$oTqE!=K0sR +zzh{lO@drOTpAO6PXHj&P8^4)v_%MG?;k4+5ELXdm;uVh;)iUz^4&IIQJ1pJf5Wv%N +z-izltLoZh+cSlV6)>)skK7@{fsJjytuN_|NwDN_C5G!kt +zhm7JjSMcde3i_8ZO +zwQ1d@!am8l+X_w*c7`t|mU-;gW!_Hmb(zEn%#ROUoxAJwW3e~c-pQsCC0Q#`dShA1 +z9(Pf=WMbxVJ)+U#*cGXy$Ju*{)Bwwq5d68ETLfxPoDj`EDLeMd%PB-BvH3s8Cv9u26cN2I=+)IPwyjT8^0ujw*a +z=igjzcOh|2t~pPvO)F$PT;}ax`fg^z(r3cAwq!rucT1Ot`K%W1gv`4Oi^TO1u`n0Y +zpz7+-7znKanX;4(4sOuaLO}U%i!lNXe5;F<&;!YUNkF(4w +zqBB;PG((3Li;k2$j-ObX=_)&Y8b91F6+nOB@dC{;TH}+;b#Zva>T_`w&uD>V=ZExH +zvb_bLpUmlKdx&k9pJApKjZlhwS8qGWu{8+r(02;TE2`LQS)GjOOs&%b;%Jw7>D>#H +zCfYWzB0dw;wc)y3F2a>e5_$eT0!u+Q$+7_T1Wc3Zqy=+Jy0#YPx$lYhH +zkBX91-QgDikRp>>W*D)xZ5>+ +z55Kk%V}{cuYS%tbSyJ`aGwkVmN~4m=q|p*$R?||C^L$8=!$waJ)83dmm9DN~wvjUN +zSwePo!uQi@&i-cME)sWYU-Ow})(QUcs?gS*$wv_K;V)qmB?3sj)AA-~(o8Ym`FzUa +z+B84UuvQQr;w(qyRXyc&d-&{5FkjX58k$zYBBZ?0tE}-}(&Tt*u-8&Z*{a#?mU}|N +z7lmp+|7Z}A7;?^`{Dj3NqTczBk~u0hGhLq=grBE;Tfs;rB3xZ3w!(JG9fe@9*=ClJ +zY;Bm{a$m@8OfOn#*k+>;J^8*iZ|(dU+XvFM2zrOT4eVP6J@J@*&EI~D)ZiZRjx|}G +z`9$T5=nVKSkWG*N@a*I7hVI!$%Eg~?df`RS9a>NJrRs=K7<}$C&pX`@Zm3Y1NIj-m +z62e9F$?jsT+pQ6xjiqUJ3H8$FI{QSDE#0)-#_AMDyQJt>gx$s!ZPOH2S?r0I;U%v) +zrJAR;j9n_iH$<82$)XPQh74OR^lrgDV<%}EWT9}0M90+8?=tXwADR1rJ6lw}^I9D4 +z1+?z$0Rr(cPe$W@CasMS+7WlZns}}@ulEThkCHnT+kCiKd=GBY=hn;oo|v0j&9KC91NQg~~Lw~YAC;allZ9~0>1njMMA(0;9l +zoT4is-UEHoDe``Cwh9C-5;wAqC!JYFId4|#U`gBwnH5!*$If}0VSglv|Io=U3q3xo +zwr8IXeuT&Xo@H+4*UKuU%17(aSxN=M@|)0(HA)dY +z5Tl8a!_>x~=0`tZMcF{sYvU>JT=-9-Y;Ib5wZv@W57;ejeVP1{^99@K^k$Cl=B4G^ +zHQ&$ijb7@}yc{*wKHv7D%_Zg`PaKC1uc>{MguYtrOEbG<*UJ(&I1&jZq)Rji#>BK< +za}bp$qZ3xJBvCHaRe$+cWrVxv9dZbj-zWl0G&b(q>o3)7ZqSQQ$i6(mB&<)vYQ1e{ +ze&>*i!s|9`+ooAa+VHDnnhB +zUv%{`kPKwdDu;^aIsFqcEVb+&M+54 +zo<@l6oWR|u&CHOTH{*9{CV9~LG5^@e$@XUajD3jEo5L5c8+)i6u`hSohWKmSYR*7K +zrb3p{6-K43n|J6kbC;)J0mjvwxRQc7gpuxby=O{`xKZa9RBu-&{oKWA$w_$T-D|_m +zK>`j*4rD1CfiCU6$@uBJb@`=vIWCfKBk_0!L~sM_ChbCYMf0fTJ687lH*OwrmUfOM +z6JKp5Z#l>MT;A6U#S+Qht8cv7iKKQa`xw>9=Q+QHhNM#bTxKKH +zI3DM@t4c#Q*L!E=xRmL^+8Zb;6+}$TQvUMcHP`Tp1F1v1I<4M}_IOwc%v@ty;wE|> +zg8U|rn-BoIz+mEvK+hsHd3%W0z0w*>ct+sX^6m*+L1$3QoqCfFAH8R}+O~_)pH0hp +zNgt_pylsBvO(C`J#|f{=WHYT;(wKR~gPd=V)n2A5PIGdKIKehDkSU)OV)W&f=%qvc +z=}}(8p<|uC_0e+d6+gspVyHuZvIN>=FFI~OSK2gH(=DLcqoQM? +zXwkv@*0&{-8A%ijC7R+zxk=ffxYKllnv_&|iw!orz0|!>as`m*<@aG4u$z2V!hig> +zxK^~CUbj&QdcNHvv({O&hx*Gp4U^4J&KW%G9O_8&?f7C$C-^sajkJCu&eXk)k{o^MLa|r}|x=XJehBE@e&z=}|eGpS;8b +zcA;E6_4eG;aE`Qoqq>{-XN?h~F`rQ?*0=@R|?y{yZJ`D~887VMX00Ui=10frz(}f7~=itkWG7fA}tz +z$xAs01wSzA7>in|J#AnZWNzfT;~$A!kmBLQ2X5+8s~Z$!x-3Z{OQZSzJWpdQ@&2|2 +z)h+s#TjN~b1>M?~UJa6jn>Fiav0YaE`aA(O>*I(7
Rd2I%@(JQdsI(=1q)(5|19 +zt4nPhp03qPs^`+{o11S%&2whB$4~Yq==*dxaX2|Xmp1aa6Or4s;;@rSl#w^F(Jbj+ +zelM+vLrm}34r~V+wr=bt7%SimV{_ZB=AR&cc!Jc7o+)T*n1IMPTYS@dTF*PJV29Kp +z$Bqpue4m`YQfyg*nJISINpl*K`7c+Ee2bbWk#OM$61%U${yYVd3 +zyYYDkn|6-wz;@;fzW3Cf^x$QiJ>IXCVt70-_^zo6b*`WXb38Ek6-GJS^20!C^_lVk +zNs`WZSL2%&rb)kxuc^IS{FTtg5cN-utTwI9X-QQp37<9|)G|c*gg^1)FOffEKbLo7 +zjv9kYOzAq8nKU$cHNlVnPvCUp{Oil%D4Ov)@t6{eh5C;Q&o%dL9Pi@o8JlX(bK_|- +z7LS)A;?^#rIt|z#3FsBERZ%-5nd*Q2k3qL9x_(N;s=acdD9aBuBf+7!J%u>1)Vd{ZP{E>3TD~Z-XIjb&mOi5%m +z^2wUifgbgTo7<>Vx1PEmeRkg}d&+zvT{V)=7Zdr48#DX9IQF$6YamYxa^J>r?6JW< +z!LyZ%jv7Hx9e#(0LzV_?gQ9T5aQiu?o|QV$M%DQ{CuT032^V2BKUpbYsnIsN%Jcf% +zYsK^A7yaTrS4;02zJ4#D!iJCx_ShZWKCPWm_ew@A!;U?xvL{Y%Q3a` +z2onnvTN7s!`<@8($nFRE* +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 +z7#jrX7@FLzZ5ZEbFt^v!4=REk& +z_`viQv&(4r_>SdETkN&us`hb1k=#CW@m2#7)wy$jHZG31k+bWHe{x{7d*Rf5>D*8v +zy@dF<)cuLy;hQjq%<$Epdbfcm{)Zz9>Nt5g=f8D6Qs(4q^4JEwalFF>b!V}#=xJqr +z+7Qa7l0`zcI83ID+3tm8k9J@Nv`xIUWyzaG!jDUH`6RPJ$^=9nw^S*+H1|rNq4(rm +zA&33Cu}6eU7C*|$JK>?CZ7fpqoxw5ZRLO4ZO1Qd-RDnT2nm74CgNuKH*SmIfah0Tk +zp)%!3NlAP9a`glyIOUQ=bO +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 +zs7)oa4f1Z3-nT-k~L%7Et_z4C$ +z`_{w6)TrjSk`zZA)xr-xU$!RSMXW&t3%!TyyDcuzXSe)eqkHao)&7M)2<6Wytdr*A +zmr4mkaqJ2Y1wkX}CqNS<;AX +z%;0a{V;-PzHDVxuf#6I$j$KGEt{>YVRh#?Gjz`>EpDMaAs88$N^U>)a?K5?h8jDRY +zMu}q_9}8#5xJ!jV-%J=bS86LI_|em|NK2if%~kH}n-R7po)_ptuXQT8>bK`AM+4Mi +zcn(h-NhNcC3w?5qSox1@Y?#j4wYJEC7+Q8s*1Ob{Gor^SA@}4tsb6M`y +zDd;zMY24CWv?ftf#+Z3C#4R*1+r2Z#J7TXVi=P&%-k!Q+>v-_w$(xW5-&a4HV2|s0 +z!|?7*$EB2_{e?L}FnGP70mXd9(jX>S@w8SCRd09v0JKMWH&y8YAt}v1M=fGu?ArVs +z*X8#+d-w{ZCS#_wgd8VLJBE3rh)I2Ax3dLzD&4ib!W%vq&>E*a?!U_$7(jW5ZXvjM +z7N-XmBiw{0RnVbGr2XL*?~p^gwwBJ3ccW_yA9jB~6ftc)9*LANj?u4y;(aZ5uexn6 +zceOb6EUj>er;Qm-HForDO4_R7-fjnJZ3e(c-};PkrZ0psWg0hfc)|rk9kTrca!=C2 +z0xbgtx=WR-(ImT$(dK$yA|x)I9!O0xGjQH899OfVTM)VZ`+hKcpV=F-iCa7uyzUk_ +z#xiOJgS_7?=ZWPr5Z$v6ygd1A*j(0Mm_+GJ@Tct7&me~d=goyH-YTzSyDBdb5rLnh +z1`tS6P +z373{-hBW)nK&6Fk&9z{o!f)%|1kFS{t|T~n%|Lz3f@h&nbwYtwO%r^5uYId4dWaO6 +zvc5Qmd)S@X{64Wh{?5(*yV%?5b-r^W2_>iwP6LthW;d5v8oqlzCW)Z3<+~EylSfDx +zQ6KAj>x|&w3878aAKO`)*eGg6hh)M(z4omSN56Q;E1FVGP3>B`gxhQ3V*k4(~z +zLBG%DQ*lJk{`p6|A>VIpbdI505v$AD*k?1k$oZ9`8C||$3BR|FN(reUZ}Hnzi|Gap +z8*ar`&B8dp-lFuesQ`Z-#qBu{71@-SU>h!Ov)Af&I-TzMjj31i#Zz=EPaPY4r8leF+O4=XDC)Cs*$JG(_wQbjPX|(C_BE{-h)w&ceu5eMx +z&fYXqEk8yzd1X*mx!G>phxHac+J}In6-3OO#P%?khhV)F6}EQLcd5q^s=`gmjf$0n +zYizBV3463pRBC>rtmN)?Xmc_ba_H%_OvkMdC(F7f&P=q&ca-gZrM)to@3gCOWssr{ +z(qW1+^u=FEdUre^f6c#oLQ!V?NwbM5cObo;dvt>~?Qa&Pfvp&%O^K7pa=|jt-2{?o(8<*_A5GCq^oY!pm5Cyp_f5oM{N=J8!=K +z=VOmpGwdg(6xFZ9Je^%MbG%80M3!r!^=L`;2b|!PXP%CYT{iX2h!WZT+!Qf$XeIh$ +z2G#@Tld-oo+^?AKD>o-|;GdWJ{>~76%sHG;ZGQ&W0h +z+}d2Gg6xI@JC*G%-^>QgFC&UZ4Z+g42hDePJ_Rz1C5G1@_q8F+RHtzM1UltEX6+d}v?#w}|Gx8Bx4J67?Ch;rY(9@{uM)Yj%;9_Zexe +zq(7|+DJehLL7DR04%+U;LQo*IZxT|u^*?X>*$NJ;eMEW!{_+~Q3!w3Dul>8~J +z1>E7^{p)Y=U};6BADN4Y&5Z18xJtOeE}zbKfkdtDk6U|jaK6)*BGn(a_Suy=#z2Oe +zOP7?%m=0~9@7%t(6eq9MflRW^M$>v$3E^<3-fo1rEhExrdyT3?P$VJDR~p%= +zP101~1YGhYGf#?~*~P6HT>2_4G&0l;L82&D%KKrX{H&IJPyg$G@y5~zzzQJ +zQxNy!YGETrYH%5>GSFvz`1;bW$}vxC^<%168`+zENqZ49hxXjBkUnKlgSQ7*cql8X +zFrMAT&>{w9e+ssMj%H&uA1A+HQKHLd(kJ(HsOCYtMM&1zIi7ySTH;_(?3DlZs9gwU +zB2(#<2iLRj@4VR*93hf2C&#Kws?c0zXZBhugL8L+5^4Wst#M2Qfs{ +z;=MhtjUC&F4goS^Y{g+X( +za6ZK5$YNSq7B^E+kVm%SVp`CvGU8O+9i}F)=@xaQlr+_-><1>nS?4N~?i-u|68pXn +zwUoOZHu2rb5CYRzxjc`*`Y2{jTxxxX;kis{cz>8!V0k8$lgO@FjKGZp1_ +z$8IjV+okXH;*Q77S)Fvjq2_NrZd!EK=ZFTB8(u;5n7kJ5PZk`?3(PxXtv)Dm;s#xP +z-k;@lf~S}PKk9CRqta!YlJ4Hqi|91Lp<{EeI-`{kb}|OL*l``g6rYU2lnKk2LF?86 +zPhc6W!T{UF!)dlz)-$-5G}z7}6wGS&@r+K&{@&=;`IarH|HZd%c|P8+A`V^fad5iA +z$3XauXx*_1yiz^9q3#&5V>9R*l5;_7<6#fNSbVsGp-f}BdfB!n27B>ybl+X`t$RWg +z{L@?WxATUk>^;N9wTUp3Sr-H75>w2XJ*UBRE+N|JQ!HD9;hrrqQzSEbr7NI!Yi^H< +zHdm%57{sK1{JuY3j#c9jZb>jNqb$8)#JQYTUa!Osj`}q9x_YN1p{Iiq9lc)ELnR(4 +zv(pOONl1t*(2_9Dv0XYAij{ZY{McR*xcDVy{e^$QYi4tYS{BTfy=&gdcu$rzCm|%b#9qro1sZ-6~!%o5G3joz1iq +zkxrjWe5>iPkv}|Ao0So|91fmEKB!B@Ria-LN +zq!|IUi2$-SXcGa_477=W`d82<0-_l>GXScHK${4VW}r<3*uR1{5pYoil+FJF4!;%y +ziUBAFz#s(B18`>WRgV4qDmXI$&;w8mfM^EJ3;^0=Iyf@`thvCM!Pm;6f23+~H4zZg +zz?lJ1wgzVgfJG6wv=k^?gG)<+Xa>#W=qiO)m +zOaJ}{`=etpFM)XpuonXe0B4zhNUdL;1ed%6RFR;44Ma0=mI<7y!TnDFGy`Xue^dqi +z>Lh4igZA}bNXB1}0hhf0npA)E6c}c}8UHI-1;qdq17HyTAu|7U5)=bq5(2{vuqgRj +z0N5D-XbspId`$-a0bo!JzRIzGOiRCB()_otf;Q2=WaZC<3ABm6rUXCV#0I=g4v-#z +zcSZov15gZrXa?Fuf0m(tIS+OQKr{naIRd9@@SbV^V$?6x`t<=Y%mC8;*MSO(0VoE* +zAp8v`fBO^^17H#Y!wjJI|2j}Xo9Hjd&3}*duU-LMO$5jT@XiPTMGNIoKHhGY#wv0E!~8GXScH{;!&4{z_$j;Ro0m097sE%m9!FU}pe!20&^87yzzv +z{8v`~B|ZQ90oWM;(G2VifKxR%Gx!y${+(d|JO(=hfNTwR24H9K7n1SUW5CU@Kr{oF +zmj05G|Lg$#$`3#uf=f$*vNgE0^q-Z_pB{iV5m2`NAKFBJ;j0e7tvEoR2Uw&6r9IHT +z2B=Vf@)N*2wg55>xEJ~>Q2f&v(6RV)S^nospko1mQqZyZbAtWzC19BSg17(V0JN|F +zg4_UBHUC|}|FB5?lQ#kkvtRJ`pB#W<0L(p54E_w9|Ic|)41l=@472}41Aaj-CQox(_i|k1F%T_?FaCi&jTz{!6Nl9h$BD@Sfu`rSHC+0 +z&N2Z66kO#9L^H5R1sV(=Hz{numu1*czd +z^}jp-?d!iFH-91B0wDdXR{&?3fGh!LnE*u*ILrJx$9{ShoMi$i2Pg(WGy`Xuz^NLX +zWdhI)oMnEs9Qrv`gWp&U$TVP>0pjp$0iYOwVgL+60F;7a@Kuie{3>V@0q6lJ20%0e +zX9fW6F}Sb=fMY*bWWX>3NcUd{Dkuh^82lw1ehsUj7yy$H7-nB9`~gu4b_RbzZvK0u +zfAtFB%m9!F;LHG^C<12&U+36QuYxlJ06hT30ElMb%m6r5gEIpFnt?Neua-kUr|SRN +z%-}D5)d9FkAMhgqi&Wsu2iR@>cLCrkM?ifBzlsP5rQjV~07(emu?0wfkNK*s`zW}ssMoT@>`0;Ii&@n^*sXkP=M6chtc41fpf +z0D1t50T9hV`})r^^e^W@F#w_&xXKaG%mnX@0912?A^PLWLvi0_jWcQpq(S@ +zSP}{G0oo@(fZGvh=?Mtr8;CL_OGXOq$Py$y0D(624w9FqWbOwLK!-*HGBzL_XalEl +zx`c?V%!=C@{~5Wms_XLeqGF95O`iNNV}4`KxuPR-%X`zz%pf|VCo_YjnVG?-=4V5; +z%?z?BGC+=|$jo4iU7x-e6NOrfiHc@s1})WQ20=41(MBWm>3cEJ!rCKYwyS^{FoOnR +z_yIF$5*i?X(*2vpzzm9J-_Fcn?NtZj>$GlL-qW9Lc`xCxUeDbCEx@ac8 +zuBDXt`jk<(KZ~zJttA#kGx2pxwfH({CcZvter|u3SbRT;#U>l942lO<2FU{(TO!A? +zGDw7ni(L!O7hkR1LWkP +z0dlFe0rE@dv-v?xRBA0IDw>Ijq9YO$bw?y7+7@XsQ4#E=z$-sOt;Iw|GXvyQYcWyL +z?AzJ$Ze`GT-yp<$tqj&)bwHOk{tTbKr%QC{r4xMf2l4d@qc%P_%%TmQfvQQ}w&j;c +zW|>>y{P;aHXc9KeUh(#p4>q>64M{AR!HcH9`2#ax1`BdO*SsBmOSokQ%pedrG!$wKA|WD6P)|X3!*L2FxIdR0R#QO`%_aC^KLNg}^Rg22Da{zzlXX +ztzot#`de_dGO#jOko&oY8GIz+>Z=Z%%PiHROLU1Yxv`}eYi?{QqPVeT!EP3iwxh=R +zr&yZBT|IY5-f98S2qDbIogl%wseB>}}v$SCr +zVmt#?Ow{WZhhdq)%%X*-W|`p!%%EuI`mS8RiiwJ5Vxm-QF;O-}Vxm%OGlOi3#6+dm +zVxpp%Ti&ZF@-o1rncYOy6p4w7W?lx^Qtf4c*%XP1LaoI_Vxk2xo@>NJMKdu`OZCGq +z**EPgUtw0;y1Gd5buQR`*F`h&bxXDQI-4SiMKnd?>s}!@%o2xF0W)9*4Z`pPW-xN>_>>tigWXJP +zm`z%rC}jrBptL>>C1_kb}o +zXc965X21;049pD5O|rnuVD4AU49aT`C#(`?`w9$@vngT*1ylp%B;mJU26w#bfG*Wi +zN_<`RZkp5z$!Cf2F$==*cg?5a2U2(VwO1=&GRF(OtZ`;QZz;1 +z!Yp&9f|Wt=z|5dX;F_FlSzMD-G;>YPtkZ|K{Q3K$(cEJcxuagSOqgEn%P>~Qf+H#(9G5PV>@(|>UVe<;2p0z +z5MSq?M3dUew=XVe)sR?}KR-5*6X{dId+5?Eewx(afhM&`ph<11)}#i_G^w*rdr4^o +z*Uuzum?aLU0%pJrmT)*(0y7vnc6@4<8Gc}8Fmmkpv|%=BeWH{ZFoOo+LnT%~C6a@B=G@=3&FE6@S1gGhhY{!suF;zziIQjpJ3W$ys2DYjPg%dewnL +z`jaysP1~0D^k-Y%OPc7?&;UO_a(!3L^qqeynmMFjU8F<$Ni*l4swt9K6wRD}YN>Yq +zDVrkkb*QzCEu9=T%o2xF0W)9*4Z`pPW-xN>_>>tigWXJPm`z%rC}jrBptL>VPiMrCNwB6tw+yXfSxFCUrsi +z63F`sY0u#%NW;_I>sX21+W>$7EH21zq!P)g4X +znuk^fq1NK-qM4YeIwJ9Pc0}UqY>Iw+`qP4-=g$lU%picu44A<}XFk_B3|ll~27^dH +zKVk;W!-iSN{R~uQzziCM%wT5G!qbM?QgXiqS259o-RwvD_zPwR$pZuAXo}1XW{w@6 +z8X#}lz_UFtgQA%&?=98tObeQs8I0}FQK}z*UJ&&BnW2Cg1WK6!GuW3Ac}@6%WB=p7 +z`j>zAyWjopcYpUE|J}d;H~-?_maNewy0oA?bB)9z`czG7(M*#%G>^}ZG^s^1v&>ni +zoy)9t=vdG&3%Q?x$_$vn5)LOzUEkb$WhM{IGNUOn%bYoO +zcq%4h1`BdO*D!-nYb%4InV4v7hmKNhmKih?6U{m;CR*r-ye2$4BDcIZ&AcYOrTPzl +z&L!@?f(CLTeJT(WH4m%|0>f4YBgc+Uz5gi|2UZ3}Gb;ltgJRJ_LBlNMeg-NtU4YR57Pn232EZEI{q>sN~fSf!qK#r!!0Qt^W9k|$c7NtYD{P+Jb>Q??h7PS4f +zGz{9IN$uu9Vi73Sq&5i~X5EPnSktl3BSfEh4@fBMVAFG-bs +z1}J|Ntxo_m17^Ssm_h8D`QZFhv&8wQ1-n^5+Kw9Uf2y9#Vc0~el|eG_v0)ay +z{|r>Si5Bc8fxN50%Al>vmiJiTni(_+#YD_tLGI_8hS}fL4DNi@fhINoTAI}KXH9C! +zio_!Q`6*$xuRvl^_RkCwrOY5n$PAc46DgR+3`(sXhAo;oq+hw3L;6WGx4gGh|5PRU +z8*>3OU$BiTUm4u}ssr(L$r@dv +zOLWOC?->lbOhkke~$-E>Vop6!R{-NSfoEoEXtoH7D+;hg~Vb( +z?&lh25Na*4NSaA3YAGeLD4IzuW}SZetBoy5GrJtCBifl*pk-Y8`T%wT`tF1}8t +ziLXPj_r=%DAQ9LF%zzm%12cn2p+2}Kr&(fVkSk;}gX&uBa!jU~8H8G!86?fj3~F&; +zWl%ITGia$66J=8*CJMC{6D_Pg5@x#!m;p0r5QZNxgC-#}UwatsI~YyX(qm|rbuE@G!tL9REw{(DUw)(T8po{ +zWonou4yOWUzziCM;RnoM~a!GlP_HF_D;PL5$}b +zGlOoK8fLBd16G*-twvgv&>R0x2LnP44A=!+|M;{hu;!z4UoeLYEsK>w(abeDvrbzX^s>M;IoT2InHjw0RR@~X{FB(&(#p3+{`TRG-?7Uv{n;+Z +zLa8n98|?b@y~LtcQ_P@fCb6iclwFQVGrJs5RQcv-iAB*&V$o9VV&B{BI-#6dW~jAY +zjy>dQn4LoI?$6AC88isP512s{j~Ot7-Arqk-E9D;&}9b9ptL>bA_ddzCJMDSKu($&AfK-TuK#IeP&6|@ +zPAwM`70tXEwmKpMxO)IA)oV<5(Fa&8!Sss=e}~76)#5FR8XNh>plCvpOOxgN2rOg#5e-BM+$)3a_I@CkBEU`$Y^;&2J +zikmg!>xDLWwHaK1{EZqLTapAewiHUuGH+4q{7V~KHf`X!n_&h;Gb;ltgJRJ_LBp&= +zg8{3|fEnyYDKlsiS{Z~Nm}NE(8)lQ%CrX(CGiVS-*TM{%gv@{$>}FcStQCL2Dl=dP +zrS)0B44Q<@fEgr_s-R&uX?>!U888E8-~!EyG1-lO+T~b8vCDD6Zf-&A{l2uDsCq72 +z-V>$HKP4fV0W)YK1=DPKFSUO2miPMM*Mi->|IC9QHzs=Hs}AgPY}IgmSNXGDj&v!B +zR0ZPeSC_o~!N!)NnHyVLs-1tj&90LcwqX`>KLhp0ZBo+%UJIDPDIjlrW(G~dPjGt0 +z)q8$0%UrOV6Is21;@wXr7Rdv*yhl^yFl_Vi*M!-=0<+9o9*eINrOY5n$PAc46DgR+ +z3_`7~42ouMd2gxq%8#I#n-NmW#YAGF1u>p$%nYg{vdgih+AZ%vGrJtKDH0Qji5A3o +zt`QSuQzRyuJ0dfK;MjqIVxmxMF;US>Ow>{>CJLH~iBhfK8WX+oRR?C7`6tn&w({j# +zXkUTEBK_I9%tEQeB1!06X8AKSD4IzuYAI!xW714wQA;U_MbS)R(NZn3$fn5or%>y+ +zCKlCdeJT)N2TGX%Gw6|h_yIF0nu)JdvzbBB%*_ZHX4>U=()?_EZkUDK&p>4c%%DNI +z1Ekb$86*!3kfSLwGnhGccq%4h1`BdO*D!-nYb%4I +znV4v7hmKPH`169G=g$lU%zzm%12IvlwXLPe5?f1a{raPBEq&{&4(JkHO4-Q*x +z!Ghe+HOwH?+RC74CMFu&p`%pWdE^HDV< +z7U|C=EOQT&kETa6V7yDj%%3wn-(5wlsE$>A$Ti#2pZFx_c+45epZDmk2`|y=+c`u7OE!f@r +z&uaaH#zb#_)d5|iOT88=Y5F>k;?SjOX_UY}FYqd&B7wvr%=t-TaY3pZ|CCsiY)dTW +z9{8|z=3KjPz-(UuGhhY@!YUA7CkdGWGw7}=n8pl3t;N?#Gci#$QR3^OnfN-j{0EJ% +zyAe8}pIwfj)(*o~N91DP=!jhG8yq_>OB!aa_ybm%K^p@z2%s{9CSk+uwEwvKvz5Vu +z-BivKFt7jI%piFnCW@v=Oq4Ve6O}zMgQA(3sHOVDAG@pRpBeslm;p0bko&pDE$^{b +zUI4b3AKJxVo`n8S%LUE +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 +z7yCBNTJ~m!{ts +zWbe`Wr!r^fpMn7ge%SIJJ5S6qqX&L4%ba!kDAhmh5c>RiX21*)Og!gzTR#B?sAOXUG8#h +znmPZJ{_Oly`m^&-CFjmREwsTc=nci~ANlR+PumZN|8D)!Z`sxCD{z-%(ae_jf~)gS +zO+vdIL#-tiMKfF8TdHk&51NUIvR|^XrE{c)S>kXiU#r`uA0mzcCjugF-1Y +zUWtwF!i1A!wmRU42%N#`d`H@*>@=$zTYAwFr?u9-+GRrKr7GD?5#MjXg +ziLbjO5)-{h^416Obq6IOYYs5rFGcnPrD&PDp +zCQ2TPiAt@-L?_M9?ayMOQfo0$(M(Jf9g&!*J0daBhC;u7FD5FQiHTaO#YCSN^-8Vt +z4`QNdio`@>q6IOYYs5rFGcnPHFkk;uOq4wQI%1-Cd)0x&BFyAE!nbI85GUL +zM5*Fd237_OVm#Ma8Ep4LFOM2#t@s00nE^9s5Wb@E_6KIrBy5;P?>__8${@VP%3!jA +zX8<#UCZUL5oXX#YnX-H&p>4c%%DLSe!vWxgv{WR?!Owq=?7*|H2XRR$nW>6 +z1GCI9=SN%K=Tz|U)GV`v!;LNJ&u(lvwc=Z!-Plqzb7M=XwfEB9q}JJ&HnxOXODu|J +zHny}>JO30kv$5q?7j*We#NyjXEE4Hcft5k=z{((b;AVu#ajXoIW>yBHPCp(lvH7V= +z@;BxJX21-(=LtVx2FzeV?&lgYQA#y4sHEt(8DqPjS{bBUFoQs;l|l2688Cy=`Yd1u +zq1I*wMKd#lY?;gqie_KOF2^vGnF?Z};(?Vx^1#X{%N5NUO?K88rOIAVy%IkNS_MC +z*9&&D2jl(UN-Vl5GRq9LmRK~?%rYk@c={_dUAlPOG +zMKimJ62M}jCSk*@oAUvy%zzm*2qz~nGgxAv0dn{OGboyw8DyAgW>7RUGnm?;qn0ns +z4Bqoq2NH|=lW0;Gly8Cg;lSfBh_BP1oy!b=7GKXCJ3O_^G5nbs6wSofE!A#$51NUu +z$9Cu_)sH_f2zvg^P{0fVrObdCbZi!Wzzm9J%wQ1d=SR$-XePdn<*}O)nr7nb=!o2m +z&@{8-fEhFinE^A{&9sIYGguJxSY?mDU~6f>m>Dz)nZbTDc+XcIh_B=C +z@gTkq**l#4Twwkle_l9>v*+h+Y)KMGEEZbWy&wz>ODwv7)uaYcHK|22yBzIuEEX*k +zG|WQoXP`0zX0RKj%%Djqu?Rmf%WNJt%tG#GpfUqy&>)Pig&8ynnE^A{&9sJD$o&jd +zX21+e>$89vGzpmjGe{y;LBlNMeg-NtU +zFeAH(LaiN!jfIB`G*_hhr-iCi{Gq_h0Lu^DjF5i744A=!+|M;G(42Jo*teG%yz8qD +zT;COc4~a#|p2Q-p)Ae0VGfiq(r^G^Hu_DHEjl?2prb#WeHp}d$$oZ$}i)?HunmPY8 +zhY5#p*(*PSW^Q?pj>s+VO*1i(m}sHri5eSQY6)v&OEyJjnbj1TWfslMGFz&DUnTh) +za{)6blrjTmP+Fe_%%Et-3`*(E43cJM2DL&qGboyQUmBG8d>cGYpy412WdH?Z0 +zA5~?+9HWLVeFM6bM5=;@S>kXi(4-d4m_b2Qle*v*4YQE@8K}&F8H_@|@{}1g3B}jp +z2NH|sVZ$useg-NtUY8NPt7zJ`-WOu85GT& +ze@e9$6BW(uCd#JB0J)o@hFQq{3{+;o3>t*t2j9OLyz{FLG^wRpbcrsN>}0|BuS?TL&GftA667|%8Ca_pw4Vb+R2 +zV3ip#g9c&v0W)Y4Hq5dqnF_27!fUJyCL4GLFf$lAc6@4Pzzi1Tey(YlOX-MC}jrBpg|aZzzmv%5{vKy +zW>7S97&ey24#Nh=jvZOUEaZL$Dl=dPOE{dc$_$!>4YO|l2dr8dEZEI{q>sPgFl_R` +z%pjT~hhb-q9iBQ2J2}De4)&j_WU!KzM^6iK8%Q62!TG1=LH8W3$Ae&788nB)M4{GJ +z22H|-*^(r0!PUy3oyf{yaspf4ml((ln8AYF&oxU(+tm65Dl=dPfxsD`%pf^-EMNxA +zU^mlt2>l95!wla0RR=Ei&A*C^ebb-4q_kwkOG;Dx#MhNCn`IWw%ra{!WtN#VGs~=| +zD4NvP`i1|60`k5Bv&`nfLh6uuJQSE^Hc=!Nq1I-Z&C-Th>+yh9X3$n;mN_|rS>_T0 +znE^9cko&o232Bqu&sb#!%pedrm;p0bko&ntOf+)r +z_>>tigPBDOPa9^F)+b7t0W)9*b`$mB&TgV2irqvDcC&!A9W@5X)pOZenkcokG#SVY +zm_ZXMm}YBfsr9_I^u1qo;9}qUd)U}gvga}FcS>@6Pfie6^G3~uTBU0*VTCLuFm26vI_R&m4Zld>;h +z^0I~*Fau^_fZS6%ccv9l43N`++?iIhGv}X*X3jsAT08%gG_$qzYAJB>jg>*s%=xF5 +z>JNY1y}FqHM;wNY*8Mv-gZF>cfhINGQlM2L0@EWCjazKi4$Ow&1t)Ju|qW{uh2ACYmA23^okl +z^m}H&448pkjjGlIca8qeAbgpRSgHUTR(F>in +zKUf)rTALXZ%?yyQwfW*31LUHamjMnU{ru=J55H{dc>dQb1*^xK*F`h&^_4bXd?UV2nu)JB +z6#Di1sY(4*^;-Uh56plW#6pZ2l-6efGf0{-gHm*6&^$ED47E1PESfnCTOE;E=0eNV +zFnde8{)%2^zzj<3vw#^i3C%LY4{U5{9yZKADfV$t1$#3Hb&N!?)A$@dMj%f52~nV)JjsqGWY;1rNIJ~M+8Ms0j%2F&0@*5CHI +zVYUUorSF*mGk7C1KjE1fG})K|GuX|vhS`$nZ^4xrFoP3Wf7@qf&?ICA%;0V8I{B{} +zW}8C408wVZ3{JrI#?Q>4NyrSC!EUBC%$7ud3$9iMRt9hNfY<+!88iu*0W)|d%v(P+ +z%r=F70iw)+8N3ylpZ-H;&?ICA%wRXu8fHtPzXew-11p0QS%2H-@7WAK%c~CD8s(-4I{EfMQ88CzWLDY<~-A}Cy7VIX0ysN;?2+fkuF4fGSc;IG) +zXx+c(S>}GDdHw|(Tf!=sLDB4q8KhLZGc9OlW{`?*Wl%ITGl-7p$pATNCMIgB{`-HZ +zBq@JmE@&Vp(x(C|gXV#i!3NUCMAGANo^8Dz_1Wl%Kx8?FpK%c~AFsbS6! +zHny}sn`MS@*w~UZv$3W8+4-lU*$1=CQfrAt(aigwaw%n&Su``tjE?Ao#3E@Xv5;6S +z^gL1H{8Op5!?4*D+45d$ZI)Ry6BD&m|GrA{H|7FnP$*>v%%HSB3z$LCj2V>Dn;9g{ +z%nWLUY-Uh2Gc#zZ{_w}nJNsvb{~ZJ5?Axsj$`5`W0QMe_tPB?HrhvS!z%Iukftf*~ +z)Go&)p_r%)gBdV`1u>p$#6(3iD}!pN#6&a44o|HNLajGrqR;cH15IlDJ>2qMviIR{ +zc@$^2@qhdUx)eOv)TQ|EvNwG#u(74UtVz|Rc49CKwk9=c#tcf-nL+c=U5=sFW|>7Z +z=bx%0a{ehhBIlo?BXa(!X(lH6v`*cSZL`d5ip(-gt<5qw*!AgqF;O)|Vxpp%S!Ojw +zVxpv(nCL{6Z+;dN70qmUZ>hHB{WiN!DCc6|P;1xZR2nNL%Jr))??p2)(Wxrm{46HQ +zrbtXwYAq%@X?|{h788|Pi;0S6Vxnq_#6(FmG0}!XzkV+!Dw_T6VxrIUsskHa%A6$@ +zY0eUhTuMnS+MhcZTY=(cjrh9kpBW@d#n;;edwJ9_`_yqRVDhp?le%Cx3FLhR5{nnG +zZ+>unS2RTuizcDNu$St8VHnJyX!f^DEcRK<>3_bhvMIwW1y%+{Gb@7xvz0-!v|)Cs +z?+eKMRKpCIL4z +z-<9o{l|i*kRt7Jf&*lf$ca>V(*itmJv89?K8(WfQW(M0L{rt!*vuI{xOG~wlEt|d2 +z3j@VOq1Iv|G0}n;&oyGAqM4ZJRg$+ph>4PiVxm%OG0{usv-v?xRBA0IDw>Ijq9YO$ +zbw?y7+7@XsQ4#E=z+u=>YcWyL%=xEO>y4P`bG_<7lbU}LO{ymK)db)8!7MXrrb#XL +zG|O!IX;MS2HK|22P3l{l)co((3mnqljFlx8Z3EA38Z%%93vxf#*w_-Xy^&a~YkgKS +zgBhY$1`C$J4445ku(74WOdDI0B{sHH%VK6wG_$d#Rmd +zD4LlWR7WHx%8tl2IkQfC|IM-mEyH37u +zn630Bn>AJj3wD!0-c=wbI>r0#&j!fR6y4rh`q^G}ph=Cthg;qkMA0m>x=6Fk^k=io +zlWy_mXS2+rnOSD3wI=l@wa&iOq=s7GZc^hvN&`48UcoOL4z>-fEhIFm;p1`&9sKued>RKTW0W;n!#s#)qz=N#dez11=ZRoI~OW+{ZG2| +zmFiNG=bnPls%_{I#F +z!EUC#sP+Qh-crL1m_ccM7FZcH_m}}QNFr51!|W{{@QPk$zzmpyE$_CxrxIs@E$^?k +zvh~51_e%F|c~3ubGeW4fE$>M)Ti$EkU}aD=v*o>|+LrgtUg(8^VxmxM1LTFZ$19vZ +z%Lit_3>t*t2h5G+3# +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 +zCMS5bnhl_pF +zy$89v6wR1HDZPy?Ni*?vt&q(!i)J>q +zv{c*Jl1-8LI@DTx{dL9HiRiZ!h>2?HU}cazu;o2N95GSaO~PznftYAv?NLD9SKu&g +zk-z{sQEGskBs4Q9t6&DqU_p%M8Y_dMnUz5`RAvS<#|}@e3_`8V42ouE1})WQ20=52 +zVY6j2GcYq)5aYS#`-+J^|Emt@5?yN9$qu0HFa2>U(4>a!X;KrS4(VrX#|)Uk0+Fg_ +zl=1}-Mh!Dy2D?!zu_&4`17@(BW?%M@ei+9BXdZawN3<;8)ym*Yyz0QY%#t;_M3+i-vf#VYrOCyUPTK_%i>X8P +zUb-a`elBo+#4R&m21_`cEP)xk&}sVvGhhb0nbt5H5ZI5H0W%nde&s1MXr?g(X0XDg +zv8G|xia%hL888E8V3ui?Im__MQy2RVM)Um0Vc21se|+RHZ2FPIu%Xs2_Dz}@AlJIV +z%AjcGFl}I2AAhX3!uEKVSwU$Bs{#0W;Xmw1(NF^@&nu +zzzj<3vw#^i37NsV8GMOX9f+^v@9`kMUQoUT=C=uN|A?2ArawEES^jL6xlOQ-kIXX7 +zG8g22u3-kD)@GSWGqcPWN#6P(u_&6EWzIVNZ>^fnc#3Iz%EVEmtC8V9A?!M2= +zfEhFh!wC<l$ +z|3bC)0rUFLtqhU}Rt7Uftqc}O_-n#!Ux8WX!rG&Nysv;6G!MGx*u?`Y11p0DVKhZn +z22H|-S?lqDRWVUpm6btQ1v6+8iiw!Pg51wF4YNt>6Q#_683Y1nd>)=MgC-#}U{n8AYF&o#`TNyrSC!OWtCrwy}7>l3BS;43nNFY>AbM{zRW7GHONuupdA +zQp--xQpML{pqkWXsU|i2fEg6co|r+&xs5GFGlyZbDRN^=(aeo4(Gfk_<(M>c7&ba0 +zF9U3v+45fNSBGJfX12VST8poXW)8!qT8oK_W@ZMteiajSQ`9i)=6t{^GhhY{!teuT +z&?Gc72tQy3MKd#l3^UCPie_d8Q#*7Nax;T$irn&EYVBr(Y>Hf*$DVdH+PGS6*Fy5MPV0n@GVlx4eg1i?5SrVxlW; +zzW7FbT{IJ4r$i)Lb?YKp`}Ni#9gl{Q~|BPJ@EiHTaOznfi-m-M(`%Z`8AO%!TvH&G4F +z#6-D%wVSADCMHT17ZYVu^rd2=FZ8MdiA9*RyByn`B^Kq+5{smn#G?FJVo@}cSfpA@ +zEQ)3}w&YSuV$n@e!z`C$Qvowz1`WdS17L%+=Lkd#jJE3>NHWL2d)-<1g6dm@IJ^Hku+cgPCK8r@to5 +z_7&Ljo(+{P@1qkKAg?fx88Cwdxu0v8L8!HrLD9?rIn~STwUTNVT@hF`FVQgHmf7 +zTe2y#v8B}7F2|yojV;v_+2xot6BAWaBql1F+1S!j?Jmb`io`^r)?y+t(SjJyHDaQo +znV6`h+F{tBnV2Y>A~Dgz+M{5$uYegag9Kp}FoPtanL)Mg%%EsyW)RC`w<&keWoA$f +zm6<`(%*>!x$YusbvoAF>_)@Pra1+i`a~%+U-1;w +zb@;RRdW&73zW2(H@MmUFG!tL9RJ+SDXePeShDu@~u~-n}xyJQfC(X~s=Z0A;{(x0x +zzziCMTj2coJu_$$Hq5dqnF_27!fUJyCL4GLFf$lA_8gGUEzRDiVxsVx!#lATHg$TPS4)NkV483|=(-%^#RSsI`?r(#*=B +z)~{lsqL~45O1PM)Xl8(19g&$q(#)3k=!k52Z<^Wip6gdJQ8qCbL# +zDSvkUsc7c>Q>nEr?@2R>MKwj@>!O+SPc7BXKV?&7mKka-vG^(yiv;qn0xJV6gNAuH +zj++tY35%6Md5v4%Tg9ymie^>@spVD%%`_{6Xo{>1sw4U$v&^=P1+Z_{SQ%8;VrGy$ +zurjbRC^yLhyBs$~`dQ$u42ot}1})WQ20=5s99ya%f8H(k^Zy7l2$V7dX3)#i@B?O0 +zG-C#{P9G9|W)L(J6UFlQJ9*{D7kt$LU7|}ZJ9Md)XO^blp8mA^H{yRGfxNFke4RuQ +zU(XP=v1K9ckXT48c3TBA2(^}26wRy*QmrKxMKg&-YPpp`H$@Gzkoy^^%zzm*2*VGU +zL6fjy7QO!rRI|(lyV;NQ@fXBI$pbM_G(~Pkm^pTMDkfqE3vxf#FoRHQD}$n$m}qQ= +zj#6!7OVCVAH0$*Dvauzpvag_FmN=XWm;p0b=*;IDW-xN>__Sdbz5fhUG0}qE%qZUd +zR7{jS5EDgHBqnMeiiw!Pg51wF%plbIdsrF#5C7_4{@w3>_q*Ty-GBUd|Nh_ni+{VI +zEqj^(x>FxrmRZ4|jV-C=&Oa5+m_Z6TGgw%AgqknlaH?Sj%pgHn17RUGia&)eU;>I%mvJ#P|6IL +zL1}#!FoU8QGbp7uKu($&AXi-K{8Q1)`=45>z5gkjA_L@5>tFxpvqJ~}_fP$Q)BHdB +zR3NdaE>@G;%9jSaufQxb{aIpBD3w?w37G*i*f%PDl2|NAwfH*Q;Qcrpe}Ne=g9Kp} +zSQ(5QV+I|niLc8ET +zR7YfH5FOEzm?&vxX3$do_ilL)rWqiITHEEAG_%XG)Y>k`qM2QexqcNB70tZ=DMNiR +zQFTOOqUeY|xEUd7CML@DtC%R8B3nyKt-tx*ME~r+|8M{K;Y|ns{Qvq7|MGwRFaHmT +zMg7Gk7UjFCK;Vqe +z!&7F^BxDB6U^mkmX07-GR+#}aSdjakzxbd28%?SvHANu{G^vB;JwI~Gd+h*o{wdwtjV+}8e +z$PAbPGcYqSGblI70yBfTUokT%ukkX#UNne_ie_d8E!AcQ$uuj2Xo}1Xx@BsZB@U+o +zX21*@gy9FwVC2~GDKlUOyP4K7o3uVr$_$u6X?+%a>t=BAssl}G{>8nDC}KOWA`0(6 +z=6bu8X9nuGu1gN-H_aT<4-$A|^+JbimRWNa=bvV;IouYxg0vkq-bLE0rPgAiqM4W|)!NLUXeK7ArbtYbG!qlm`c+I+G!qlGR6GBaO_43{q1Mhn +z)!e}Hs}3}&n$$sX79Y_iy0lN14)>`%{=EA) +z=Kojxx(MgDmWi*E2X;Bm5Pc9|H~s8#jIKp|oit+x)v}1Mi)P~M?3Anwie`2>R!3xI +zkTertM@M9rW7Eto$6UYK<(N&8U5=&JVxnw{#6;B;+2vR?6BAWaBqmCliHWKy5)&28 +z#6&ICb~$EKWS3*8wE=R^&KhQk!>NE7FoOnR_yIE*Id*)?44A=grZvnatxuFP17=WK +zp9RdINyrSCK@zD78fLBdTUfn()q!1(3%Y2RV+`_r +z%`{DFsI~aIo1%um*`T;P8QImL6?q?T;EmpFTO6d7GEdL#Mf6n!O+Xx~1CnU6;JNpqco(IwJ9P(oB4vxtf=hc2m?#+!ZKp)-VHR&>##ya2R%*U@wmv +zX4hTF9p6|PEZEI{q>sNKCVBz;<_EhRqbU*-%^W*C^=8;G24+w+6BD&mi;03}VxqAf +zI!d+IgeTJ)W{Jb8fEh4@24SF-8H^k|K6Nuf_yIF0nwc5I^4OO5;MlPvYnX-H&p>4c +z%wP$J6IPi)ldxenHU5cGD}x2Q*^l(`7t9Qj2cL0faQ&(Sx|DwpO{yk!wDz^9ZGS6J +z+^o^0c5@)H2&`&Sw+Z(0sA1Nf=zvvC>Vn;@DQPaZg= +zUnq4*e=wToM-Ibo+raZ9W>7R^2Gz3I<(M?H%dyrCRt7~gyBu4p?Q+bfNK6!JEhgGt +z7{5Gfm?aLU0%pJr8icQCy#0Y0j2t^YWd_V(H`5wslh!9nnE^A{kofiQnL(3~88Cx& +zMr~9!%v$jWtTF>;zzhtK4Uo44c>Q|=i(X+5Z<7)}T9TycxD=_TU1| +z;(?VxGSJGPdKxQ(qM4O}l|iwn3&cdB*5C4$_vdcL*3#y|XY1QfEg6c +zn8B>m%%C`SENGa8+|NL@G6*NIG6*Ml`YSV-Id**N&b06YD}!d*KCMrbGK0UJ8Qgl+ +zf$O{a@8Mi#`ml_%$E0DzlyKBDQcK? +zb3R~|88CweVfX70tv%E!7Xd +zWZ$%}fEnC2gWIn<(4;QtqW988pQ=e+P`(wUy}d?aaa;CIP20u3;jI#jW*{?Q1`BdO +z*D!-KVLlb<=g$(0qM3~?*(^ycie?gvS*N`WaG@izu_Zd9CmUOmW;V9m=z`Am+s2k` +zivGjy&U^-{_&WW-F2_QtU5?38yByD@|N5WIplHSnYK3fOaLudBZ_Errt<4OIW_CHY +zRNLhkG;=dTbwp+cNi#EpT)&zbT(v+~-*n!&0>#Z5X21*@gx9b<`^Eryn_w@G8fMv) +zOa)d33wE;~>EkbmiC)0I`N7N}nj$gL%(25$G0|-&xc#aF7yE9@(d#3+M3)wnXRe`3 +zw{_`tiKR&`nu)JpC3)+E#G+^>zMggZ&_X``yj$+){}E>JN%wCemKiXEh0c7gVFpDr +zW-#kCGgu;F!|b-oFW~b~!wi_g5)LOnUhhf7HtPDnu9iKMLR(1a-VwnLmXb?_L +z@bp(^aFbf+Uorz`u$yW7wEi5BH~z^Cm_ccM7FZeFqSpDB%zzmrk*c6!c7eM4{>coO +z0W)wjLTpz0;F_FfiJKA5`=1;CbTdND&TM&4rrBB=YHiDV(#&q6Tk?GRrIkU^>@#gG +z-FVf3Cbj<_uJ20s)TEw@+|AFLR849VDVU~7)ub-8p>vHb@3$5DRkk&$MYGS;q@Lhb +zVv%ma4445kFv~2pc70c~q#ExO2je@c|v^4=_Mn0;#V7chBQV`Wf1mz6=H +zlo?#{>gpT29K#Qo0W(+-z7Auf7gb1$2XePkUdT6D-<_Be51N_(nyN0lLzAK7fIgwAih3f +z)a}pW>*^xK*F`h&b+s%G=_k#^*Bc7``n{Dw(M){ZQZ2sz#Hd$loqw>)G1OXoy}9Ig +zWnjbX0(JNOlNm6BPhfjR-F+XJL9>n-FoWGpYna`q{uj7q2F&12>A$XL22Da{zznXL +zbLTe=vrBznK<1|!X21-XfdR4s^1Z@*U2lM#)?OjI;;{^@2%wE3z7x!cCvsj(WQkZajvnkWn88mpEk^Hcb^OR +zJk)4XHK`54@B?PhBs9xp2D_QoFk99An}}rw%%HSB3z$KZkQp$8BvKVL%x|8(T`PZEQ)J+1OI+1}lT2nT;*g5s8VC +zW;V7|M`VDUH1lTIT)(>5x0|Ac-g^Oxn>A(z)pId}M5*0G+XQ=g)G%A=OEzn)3>NGr +zfxNH41)48l-~8bGQ#3_lq9)<53A23#-{j0-^Hm4p>uouDeMFb&(t`5LHFRmSJ$+tf +zX;O=3;_FvQ-ufW1D4IzuW}SWzUvIMOgmn$Gkoy^^%zzmz;qVlbm!FwIlhBs;@B{Jn +z6|b(oX_$rF&p>4c%%DMd4a>7{m_d_}88Cz0Olz2h+|NK|2F&1G+28O_X3!*L2F&0M +z)H?r98fGE)Gfmzgwk{^?wpum7n@Et)z1 +z)KdN7kGB*&|GV`9X21*<Y)NE!@G;z`(s;Rg=GjvPBaZJ6D}-s+dkfEhFhCntDv%liu1m;p1` +z&9o(?t)TIC4KrW{rS(~0Ww61nlkb@UGe{y;LBs46a(91b2F!pNI1C%}X@_AKSYm7G +zN%M32v#q5yJF~SknfCs>iH27lh_CbS;k|U}p59AWYrzNar7QRR%fl~KlD{z*NG!si +z%`$tj7#N!o*iR)E3wE<0w}JHW7c{BKgZFPz&$XW!Bo7{UVSHx5;VCm<1_{C{urg?- +zHOyL%2dtW9cH3oT5PrZ6nuHCrizes3e_9z>88iqdC$P(LiE_+<8SG}-64LH7fK&7` +z17=WKp9NM1%|K?r43bDy&@ej__XSv<)i48Qzzoa`GL1DeXsQ0gpZ9ZV{DpJvzE|tB +zo*6U`43KAtS{WqGT$7WNEi;3nnXRSSvKS!O0^HWpRBOA5vMGA^-9*!?4m7Fx_i&eE +zx~KShLHSmY_VyaLyf3uD3FLhR5{u-4bD7me+VY+xwBRBT8pp6*9&4i*NCr+X5#CXYBwVU&E7x0zQ8RrU?KmRnn>fk|Q5wdr +zc?nvH#WulS9x;PU^=AfGM5=EZX0LdA%Lit_4DQC{C1{yJbB`HZsy{QhB2sc?nu(&?ICAm+H?9u836MG|WCJ`vN8}YnTBuxEqs~pk)SEyt?{^8CYIky9nyadT4ulu?#ARLXqiEi +zkQrR6KQp)@Qhn1fyCLxl;QUy_48FJ-jITQIUb_B!*z(@0;k|S(3b*yaE$^z(aeo4E!A#p37WaF<*Eg`{Kg^ug|$b*Y*zs@ +zU$43>t*Y;DR>y|C1S9sy{O*UR@P*&+!Ii +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 +zWkz;wWl$urNI>6jAU0SxgiQ4>3_V +zfj3q!(UKW3g9W*tYnVZ(wV0@ACML=zN=#HV6BErkZDY$yQzRxTwH6a)%jBAzQft@b +z6wT}=s-{Rxlr(cQLN!HZ21PUPe`=}r{-i2Hzb;8E+J1v+UPTlXkys?nBo?)ll2{bYBo?XV5{sgl>$|EW +zl2|0oY;1{+$Sv89Rmt*tL +zE$^Y$b~zT!9EPoq$jo4&Wonp3XFda!88Cy=`Yd1uO+s7V!w+nEZyq+xLhfgvG6QDN +zAPhfX22Da{zzlXXtzi~&KLeE+FoV+iEMNvrLT11Wl1Nq1Fblb#fyxY+0W+|*bY(;x +zYCcZ|?t9e%U7|~Li7tJ9U7A(v!7Ouyhx>ZaxkG(q2Fzdugi#~0XqHMW!VkHAQBbMKia& +zw^Y03J)0siQK+?;NKCXK#&eCBsAwi8YN>Y1d(ccwluePCXkqP9Fxywa446TJunL$# +zlF-bcT6bnpG&3`Z8w61^nMvjV;BoLjf}gwYIS(X=YkXiUftf)xMFz+-#|}@;48jkXLD9_2 +zprzW(AZTW0Ft$TSseb%JOLU1YdF4l& +zv+KK(D7L((Kil#?ETWE&#MkLZ;_K*I#MenPiA61?Bo;+8@pVhJ_&S>+yBtHU#n%gK +zkA&H-0%pJr8ie5o%%Dlg44A=grZvo%!GfU2Dtr6|yBq_?%%Dlg4445kFf%YSC^yLh +zGlRKbF*7KyvE{uN4Pv6AnVCULwV6RO&B`E}A~S<-nHpw^!>NE7FoOnR_yIE*Id*)? +z44A=grZvnqwf^o`9X#0O*ncpIg~XzSEeo8>+*GY+W7VV<%_J7-t(w%L*$;j$Gj;k9 +zE<2>3Olz2h+|NK|2F##A7${{1O+tx9SOPOBnz`6Fmd7sk4UQd~vW8j6{R~uQzzmjf +zIAN6;GzlAK(fiLpwK7<+oBc>1f5FWN$pbTkXo}p7Fmvqi)XabxEXe&_!wf>Ltqh80 +zW(H$Bbd+i{gP@t1Xx3>l(LzV`ASNoc{>#HJRg%9k7nm7@A20)Eu)lAAax+3%Lc=VZ +zlBvMTAe_L;AR)>On8EjL2KT?}z%B0!ka%3smh#7`K$ALp|M6+t-@HV +zkH27-WAeZ*$7qV|a-2DKcxsm;Ggy%OxrP~pT3ZrJHX=Z@jQvHWN=Mr~cK?6CFJ{5?Gng><}fnh6ykz>cFw!FvUz{;R#W@TVy +zP%K&~XqbiE&p>4c%wRW4nL(4VVKz1XiBczB-xk&Gw3ul +znD+Kvj)~7>0W)9*yHUyvl5EU?8I;y%0W%1-{)%@Kz2#L0HnyZWf3UHoWW_GWitSwA +zRpxACOVZ57mQ-uAOtZ`dF`jEA7TFY;WtLh?ERu&3i&AT|%%YjZqMD+wII$@Be=M-& +zy%ykB2HCP$8NASG`$NO5^?1Olm?#z=Vxj?@%wV9_`J;weH|GOZ9fn=7n{AbCj4%AR +zRtD#gzwuAA%xH?N44P?fMwp!7(EvF(cC-p+a6_I?_1nszXl8(%O_7+WXeK5~wH6a~ +zQ`9g!6ZZvJp4Bh|X3!uEKVSyuq`LLbhFSFfGf>4u3wE;~>EkbmiEaV^>`O6GG(}>f +znPZ2iKWeAeszCP8Y7R{W0x+%}6UrH=`rRbLT +zlIq8wt7O*te98HbZ`G6QC?(3#IQ%%Esymf2Fx41#86nXx?nV3wIQbIbefM(9Ms +z9fr-O$YI#IBYJWe_LNb#KRXOtYHgNTG&3`(rpPQaX(lGxQ0Uk1#Y9CjGlQ1u4}a_> +zZvV{izhi(LtvfSd2Bq~`zzm9J%wQ1d=SR$-d1!zfYHeoF{ZhlM6@S1gGhhY{!teuT +z&?ICA%wRXu8fKH$CrX*YXETF0z3Sl6EHeU;5C3SEnX=+y-v#AcK-!KPhxE(-ZEQ)D +z+Srl|w6UdnOlH6g7Q}e2v9YCSW|mnEm09M@vBOj6pF*uA7DY3&%$8~!TY_fJKV{2g +zmbnl_CCqjeFau`LAPhfX22Db<%7Ty +zac7weBK=%rW{^#hnL(+wnL+Z+miJO?Ti%OiW(L(1nHeO_%nWM%DkdtLnHjWH+wz`G +zk(emdT1+G+S`g#8Mod&R6BD&mKm3w?)4qZq)C}JEssl~xf-e5H!2EFF@fRc(>CawL +z8bFm;%p5yBb+K=FtHh#cCb4L#mRJPM>~b92p`%nk{=6XQ`7=WSGYFJ217^^%S@;1n +zD4H>YL8PA_F@vI+U5>Fl{vf_inu)KYBl2e0rkP!i(Gfk_<(M?H%Q4m3%pjX0GlOV~ +z%nXudVxm%OF;UUX%%G*(%pjYhA9Q2O!m{;ajhJX*?U69sRlp3GL4z>-fEhFinL!u> +zGboyw8N~9~%pf>+Y|R>GA@?&-nE^9c!r_EfX3!*TnB7sN~%X{*` +zmiK6i%nW9Z9iEyQgex$EqM4aNOSLWUK{GRhu^l=}wQF*cX$`Z);Z(p3m_dUuP|6HO +zjvb$x8H67&gQA(4K`f7Lc@K^qJFe#zD77+Ju$wm^ +z{jIM$aD7+*JzU=v=Ir{e1yS^p(vmf^%=Blo%vh|MWhTwcGE1#BsYNrh%$91i%v=tN +zuS2aR77J^SgxRhFX21*@gy9Fwph?IKn89wQHO!d7f}qDLd;EpB#Mc!Kofe3Rk|koI +z8KPpMGe(`V>(ggj-oq-a42ouAqLykgQP9km_f%^!Q7ypja*U41F2|;smjSj^Km4)~ +z_2kbC1!AHADl=dP3!V8~^V^e{sM@ZES-1ZKR;>&s8+djIW)LW422H|-+0c&kBQa5U +zjhJY%foA}Joo4XnR~^tLx->VSD^E44W&aY3^k<1h`txJMEZWc+sG8L702;`N^r=9T +z+KyvmOLQ$?XOp@RBfQoygX94-D7F5lKm55$@;By!Pk?Q9 +z#n)B_yP4K7+vN?+fEg^v{anKgnuN@N8O$tNc-k;y1`C4T%i!%F5fcSanL(3~88Cwd +zxu0tqX3St)#|MdDf5Z%Ch%y6aFb{`Uo*Ez*&76Nq&9+(QmqY;v!OCTF10p5 +z&Zfw1%B9w>$tjw-Ca0RBuktqKx4-JZEHnS&Zft4QaAQmQv-mpvSz;lvSP( +ziBd69vs6qJ-oOl)!GajiHDaQonV4v5hmJxnCQ2UK*ivdOCd#JB#+FiRF;US>OcWiF +zn5a7t)6;QaVKGiVYv%+5Of1z4Wd +zSQ#wX&3>ehzhGla^1%70Xo{>1W{w@6{+ck`S0E-z_p!@ybOJMj6$UZ`X0Rala}6^H +zwYD-Sn%U);YAq%znmyX(SXwS75)&40hhb-q9iG}vRBA0I%BDz6 +zRBCNzP&5-0m0Ft_B+bM`)f9<|ie_(!iFUl|K$F^k4^3*irzUkl`4*72qef!U{@g%L +zq)!Fn>#~3Gb)r;!J#y^$v|-kIJYZFm+E!(k>g6-fEhFinE^A{&9sKur1gnX +zX21+e>$89vGzpmjGe{y;LBp&Sf50j;UW!6?o#iDs=3U6PtS +z_}-G#YhpZqsh3$a)5|QkUb0lS=-j+1X5{FX& +zGhhY{!teuTFmmj?s!SAqzzm9J23xY2s%KC%bIbdb4&6(&!Iom0!In~MJ%db&^bAU^ +z^$dz;dIl}k|5PFQ8*>0ND3me-W>8w60nDIi#tcg7HIS2L8pyRn)-x!YX&|>$e`O8i +z&8H5Ouk$aid>#8J=Q7)zm9KLvrF@%zzmzWae{>n-NBiomU%XU8xzcs%NlZ +zH#3U2SCxs92Oa~Ar06Rv6YV~AK$qxJib4iRQad?teODN`Bvq2SAjWfyibc`P`KM`{ +zb{2AjEy+WJEv425TQVs!@?L7KVo@|xv51W5YpYlk +z>H8&RqN15=a$2fglXI90Jupz2DAZb+=zYsXyH6e5NKzM+?}6TrJb&L0Di-O_Di$Ri +zDi+C76$=%M1-YMNm_ewuibc{)#iBAO6^o*oip8wc23v|_=KvLpP-_*7PMMaF*7^An +zVwnLmXb^@UC|@@NnE^A{W?IASQ0NyR$_$vnHbj}h0@IiQGuUR@p4KNy?F{S;D)G+% +zJA-B^GhhZuqzY)5wc-z0Wd_WE8JH&O9kOYnB8q9E!D#N6OcR+V+P9m8*U2h9M7^plE`)W{-@yeG|!yq8)lUl+}cyth<4 +zq@PKVUS_DZk@w!5G|Uo*Qvfqy1`WdS178>u@pc*>~jpP50Zweoe*%wgD; +zYKLKiX198o2MYc8y(!14#@^`}lv@Ao?&k{0-chFR`VrvPQ51-sct`uGca2FU|GgGh?>3}%jM^m +zj$sC&)^-L(v+t^WJ!U?KtI9-0Gi9P#r%gE?v+K!H!z|=}1}ZaP21_`6ipk5*%%Dlw +zFpJ!O2C6dAg5B&Ref$MwqU3=xQ6xpmL^H=utI9;oU_tKZ7-kS^ZD&w4QzjbIp|e!q +z{$iKLXMeL(gEEW=6Nox4B +z@^#V7U5;hWDi)Okt5{5xgnJ=ZvFN0z)O-PlQw%d;1`WdS1LfS43|ll)zMj&dd#S$pupsF9GeZC~U!WEc7(M->vrP}*XK{Hd1V>)z}YEzEMw1!#Ya0*}s%%DLSC}jpC +z$Mg)+2~K%CGYFdL8N~M3`%f!OYnUYtrvPTa43=;>VU-z-96PTz%%;RYQEF$fU^k0M +ze~+gQZXLx*`*##)a^`#0`14;Ev?YIL2-uSyy0ifEidogAMfrLWrk9x<(#s5#>Sey< +z)#W#Onc)YL)S{VQW=pkRX3$J8^F<1D`HhOjv?sVHVZ$tOI0Y~RX3!uEKVSwU$Ih!p +z-Y?bv!XB7G(M&Hhw#Ryzm!!Jj*!dqDW+C@8P?-TUSi<2|aQ^lsGiVYv%%;RYQEF$f +zU^n|nAAdp5AbFr?5J{1q!OXGKs-8jk0W&C?=^3lp;i^bE#y=q%Mn-jit!v&7*P +zzzmo{gD_Ca3`UOW8Ke_9|5O}12Q`>?zAj%AwK_RdMm_d_}88CxwrZvo#ME?k`b_R9^3vxflFoPx`GhhZYixyTJ +zW`{z*08wVZ3>H8bG0dPz$PAdlHq#nrOQL@SS33hcgVOp8U=cxm_M3+)_ +zGJr18rOH7wz?5U>2Mx2s1atwS%zzmzfG}d1L6h)%Nm5hvj{=xM(agoZsn*UvbyC(a +z3%Q?x$_$u6gYeJ>?*Cn8&?Ib_E$sk~;HrGRU^n|nAAiBczR3d@`$kgaV&9o#r&SmG +z9@@aYJuri!nQL-ds$J|GG;^`l2Pzif2h3pP*m;#1FoOlTpJN(klh!9nnE^8h1kU(8tuliqAv0hG+e~Yi +zwc-z0Wd_V(LGI@mX3!*L2Fze)(ZXuOY|{EfDKlUO%)m3@-8=J4coD@j;R|-NfV7Pm +z*W^^rbz|hcQ2O_q4;7NXF$dTg*cp_YWI$kSMqsbn8MIYtAO}j7iJEE5fEh4@y9K%Z +z1MCdm>8S%1iv=*KSd^@&SfoFHC%UvyH#mxMF0*LnTxO}Y^G`?Y`t<$xaxOC^`6xie +zqG;y)Q%kk;Plp71AfAfFCsn?hI641Rg+bSMWidl9vuLK5`6$UpAM`RaDN-gXwN@s2 +z$b1ezC=-=hD-#vXl!+=SQYK28DH9!w^!<`DQPE79sHIw&=r9+0V4yNlsI@YYGSPw< +z&oRnGMKfihM@c^VpiGoJR3<95RwjDLd=5V-6O~#k6BW&ri6SFXChCkxndn%gm5GXA +z4*||Ug<5|lWuo_b>OjRJ&DmhfqdFXYP_bx#E@4@~;S}?g=u(>Sae#`&g9#sgP_ZbM +zs8}2m>@f{K2H1NnF#~3hAglmpkW^#_%-})O-~2)Oy3|_vx@e|+T?v&b$E2C^b!oXN +z$D)}j$CheSj+rc(atyULob5EGzpmjGe{y;K*OvRf50j;U5{~mgoDJv=#y;D@N2!GbgEOU1LDb?D@d(q5|Et$efQZp%9 +zNm3V}co@SBm_dTD0+_)u!5)?xW}W^IShX`)u$u((R)CTBN3b7$@cvUIMS7V{LN~Td +zPH^|H%zzm@q#bYnU}sP?QzpuM$w+|znyumJOlG36Lpi=9EU)XrdXf>TBR_NNLNtYl@$lwq#$ni`nKDsqUX_WGW-Ftm@AuS!US`RjUS?Y7og`I~+U6)pt&&FuIR6v| +zDoIV6Nm5I#^)icQD@kg}{T!fT!3;v{6Q#^x=GbY~U`wR#%%FLwml{R~uQzziCM;Rnp1N!T!p+?3{r1!bb-fu2Dm +zMao1o$4;xtM9g48?&lb05Nd5_P&88}8q=Y(R67hCG*c#;b^6rab^a-t)-X#PP65n- +z88iq3rOaUD*m<>K7Po3 +z;&2T3`^|@Oeg3ysR$bo}Jg_rp9xNek1&!BZR4h6vQn84nNcsAJT~EGe2FzeV?&p|> +z*;B~9`ZF_N27$mCpQlx3(8OZ~%wU^o4YOApz*Fcl17@%w_j3$0Xc965W-zm8VYOlQ +zOxzb>`7DMRFau_wXD|HcgaCQI3|r=Tirg)ckw6*f-r%`FcV5R*?4g7&o>oq`?W~ +zy#N)9;w+O7ROEj +z%%IfT&R|TqPOEkXrPg)^MKe2tsvs#7CCyyyTS<|@mZF)SK}+?=zw{Qje`fgaC=*5Y +z&J37AX?+GTgQ6KT7)1Jhi5WBxHIPHC^$a>+YM8a+4_IXe%%DLSe!vWxgv@{$Y%{H4 +zHfepLlo>FC()tWw22Da{zzmW|6;LpH&!-Mt?7N_g%Gb)*C2SdBt)iQfAO3RIvy@U)z}YCVIXnKIF=)5=5(8IfypA|vwTN7KwTIW5(m{3xcmCZ_~jnMj!^ +zbDjuLCQ6zq6SY+TP$BsnbHE?o4Bqvr14(Mhp1T~=I`7=&7^37Z$I4Khe_EiKUS_Ga +zB(<5Qml7RU*b+S)=bwUO=Zvgj7IHrWl^HODB^*vzWd=>chS`+(Cra%M7VKsp>EkaLY)KwC +z{}f4)p25tq)2g09_yIF0n&}y|RD1s^Xr^Z{rbB0`cK#`u)-X#PP65n-88iq3rOaUD +zn4Up8!6|QN20=4DgV-MH8LTj^VU{?Y0)BThc;BZE=+Z)d(Dpawpy{5H)CJ{R@z{+R +zuY+dF*O@G-Sd1IN^J>E^aX1Aq17^@53_oB7 +zBgd4l(+QNXi(||n_Qq!+|J&Wq3xdA#OGh!vM9g48?&lcipTZLC42ouYnMVr!_&qZy +znz`6_)@gU9tz=WT4YQE@8K}&F8LZ%Nj9~^%!iHJo{xeXOi5Bc;M)B^d26A|f^G}%( +z=^2bhbHA!g#0(bXevV-Vq1JW=MKfihRBJnfqM0($tkcRw3mH+AiQf6C14-(_pG1-> +zNtL83Uso3CUAkn+AO0z#g(Pu~asH`j=KND_)|9Vjj-6JWe+soW@?JD^{;8$f`KO?n +z^G}&FDPPwHT=_cdILg?3{r1!bb- +zfopOiDN-hyId)oACYqe!{D}7t6|#`_Ofh-}qZ4>0Je}Z9&mdD4W{@;v2BS_hgG#v0 +z0d@u<*vdpjGd+XKh?I#IlA?y$l$Iw-m5JI9m_Y!Q88iuq|>Loof#z4O3gQc$_$u6gD_BPXV5HV2FzfaX$`Y2KVSxXX7Jum9o*_= +zMs@sSy*@D%3Ko|nsb&8LTN0%PTgv_owxo3%Y)OCidp*`W_kv(J$8X+=UjRQl~Cy!B+c{;YKN?6P&Css +zNVV28D4ID8oBLNigHDPXW}Tc5SY-yxpg|aZ@cWvT~0 +z0l%*N{+Q@q* +zMMmC3t(C8Phu$zt98LkufEhFh!w;Cj$g%S(GhhbWOlz1;TAwIo2F#$eJ_DFRlaLuO +zgCtS~G|XD@2dpv!X21+IkTsA~i8DY0c`%y$B@JW^k9IKRTYZ`yV*zj_zTWIB@dLZBPmk8o;h|}{Uu?x7oe9p7|s2X +zUgqco?s8mVATwYF3vxflFoRHQJAp5VZ$tP{~4%u2H`b!29pik1DF{!2_1%I1`BdO$281B?q{Gf +z17;8iobh>DWd=<`X21-#nRX1b_kZfZyL2ncx4`^x;PDsS@}BOjS!|Kdj8Q#e#C(w|i<%AbwAr$4J$gg>iTB+XPTYAdB;Q8ZJrXsI^x +zo=K6xmQZUW?+bg6gxOXAGhhY{!teuT&?ICA%wU^o4Krr2An38n9)H36PXS|Q&?ICA +z%zzo_8R!|5n`D5V!JMz?8I;#}46rv1%0xvoJ%g5NJ%ePLok1i;dIp^`HOvx+Qvfqy +z1`WdS17yr#p>q4b{aafNs(S=sI|eC-oH1@5{FX& +zGhhY{!teuTFmmj?$_$vnHq#nrlh!9nnE^8>tvy +zZ$Mj*2f^0MESed4Pn0SXH3^l8!V;JPGguJgIYybNXr@dwr9)>SS0+jxDif7jD-&f> +zWU!^w+RX?>Gi9R4h?I#sBXToBB}K|aMKfihmTJ>PnG`7#MN*_pq)fCR#&e7^QPE79 +zsHOVmL*`9;0nC6IEXe&Fa{%Pe^3;LBmiS|w{#1_Q%;v0OQL^We(l%BVi=vr|MXI%m +zMKev3DoITuRY1e66@S1gGhhY_nfV;U44Q<@fEmmzT3BtEOUrc6{xkup)yOqr;q+WDtUid>Tu +zYVG{f!rmicwiUn(m_dUu{D2uW37G*i*k)S8j2SEldhD{tUvN!M!1(tvgU|HTfh2W7 +zwf1Bu-BXgt%Mz)G$jNP65n-88isP517HovGXc3U;zzj5yqb1=nzy+3QAP+`!zodbzfxK@w3A4Qb +z(?ppRnIE4;amLiJ5mIb?6K-xyk-|pPyn4>cZ +zGzh~Fm_f6S88CxwrZvo7r~VhXWd_Wkv_1ovL6eXf +zFoPsg1vJbq^?d=EpJJE+GhhZr-lHYqV&4Up7DWd=<`X21-#nbt5n6#4~-GK067!DoBwK>51O*^MnJE6Ud?e#+NXn^wL~_jdj% +z4Al9jq}l)bOTug~fEh4@()tWw21!C@zzmv5!8B$NYOQ=-G;M^mjxpFW>9k&EaqJwRml2v@=+95oW*)n1N}cO5HV(lO=ivu|qaZlr+;b +zsLg?$LD5VDxuyE|Xdr*Srw){_^DnM^9p?N|`MPpoJzfRs +zR|hi#X3!uEKVSw;JcBKh6P(^{z5S^|cD%;RuFC()tWw22Da{zzmW|70@ti#UHTB4445k +z&_I4m1Nk#PbwHQs5?!K8Z_=gB*5bv#u6*73!CnqJq^I{wlGNsbyBxzXR4kgMDi)XO +z&kTxJF9I57t@s00nE^9+H6|}n$_$!>%-~Y}nZXMp)i({ZN$V4(%zzoZ8k3ixWd=<` +zW^k$g%-{u)>YIjHEB=60X21+yjmb;UGJ_@|Gq_ZLX7GYY^-aTU()vUxGhha<#^fbv +znL(3~8CI +zF?k7EX3!*L2AAs33|%ZOoyddcLGeZC~Uqj-DOV}Qv6j{#m_^2I-T +z3@~}KR;+>e@dx%tG#GpfUqyP+Fe>%%DlwFq;zp +zM5&#@g56vI`Ex#X;FkCPd;G`SZRNT6i(dRAU7|}XI2>aPwlqr{W|4-@K$WC+a-d>y +zss0zZWd=>chFNE#16C!eofKUrsTU~T{zro?$peEeb4FyarM$*r*vSU&9fBDY%?!4* +zR2ytbrr8-p)?{a3XRsi~bBr=k(aia$mg<`i!}j?-mY4xESdjZUrh&YLRXc<58asm- +zpQlwjgC-#}U!;MS2Fk +z2XB}q4yOQSzziCM;Rj#d3_j~q2Xtux5~Hdtl+7ZBF43iuoecQ$y0j1c=f9wrnLKd* +zsd(Tn$LFNF@{h{bRa#TNE}AJ{SIXip$E2CN9Iwgq(=Y7|ie}2!E!E1`&q(!@U=N>_ +zuS2bsuX~5yFnh$?TRt!YX3!uEKVSyUJ!ZfRwwcy2dy5A=qL&#kgVOp8UX21-R +zNEOg9`=sm(n7oW(2F!pNXdr7KrxIs?267sZ2C@cn6DgSH{8Om426EC&1Np^P;NlxQ +zgQA%Ra%#CUQPJ#=_ZZ;ked>TN(WR7~44_NjpDxwT>(v1UTWY7~UAk0jcR4ok8fLBd +z16G*Wnd^Y7cL)6Y-!HF7XNAO$v-p-(MF1^e| +zDKluYF#~3hM5=&>*^=lV!Ic>>gS~BmCqI@L$PAdlHq(}ncBu6URA#^on1S<8(USOh +zdQ>FTe6!T4f!sXY5c+h2Tcf2-0%f8^sWMTs)XpH>f*HKl3_kBu2YQ+P_b}K}25PV+ +zWY1tr=cy_dMKeiisn_W +zG}AyXwbnpRnzFhMKcZLmTE7Ta~6l$%3+&lD!S>kXCU77Ke4Pkw}2D_!YXlc>RG|`l-obwoEqN3UJGSTOL>OlEA{~mgo>7II-3(B{Gw718oSkzun#UfFv +zV$lq2n01~wU{x=3!EO@BdjXQv&Ga%OBXUhn(@ZZjGNL=Z%%quKW~#L^Q6@#oM3EFJ6D7@*iAt^Y +z42ouMd2gw9%X=n8?o11{Rwi25dnC-Z0+<0aXb^@UFoPx`GhhbWOlz1ig9Sm4UH143 +z8pr`-X3!-3Lz%&6f9gPzIx5orDqW&W3(7Oc{GoJdp?&`97!`}6nZcG+Yv-Sucn!0V +z`x&T`)Nle*j_nQ1ph?&;n=_JFRlZ)Zn+3UTupj@3!ItEK!Insh47Lme`)$ejCuXo9 +z_j3$02(`8|D4IF{bes!4NVU5hgJ#M^vraqz^uVR@L&Gd_I0Y~RX0U|A38l@xh5wvBG=?J&0LeyQvK(@<`#D^;0cgF`%?!uDi;0MQn3hsRKNtgqL~|8l0zyMO+4qHLakLS7VPHL`o4h7Pch7Z88isP517Fd +zMjd=+2FzfaX$`X@_$__U446S_eFiXtCL1$g21%p}XqYXD{t;Z60W)9*|M>gOha-l( +z)A!7P8Ei9cPwNxO%zzm%17;BY>5m3mnk5>@3wE=Bw2c^drd7^m$}v%DXOIlMZJ0&w +zKLb?*dBJWH$Xfw+25nW&Kg9-D&!9=DOvDTpO6xO#86?e^K`FgnX7lh<`MPBNZ2@)$=@zcZ2|r*4%{|xT +zWZrIPP=3G+Lahz96wO@hn|YKe$D)~weOs#UzT99-BKl1Mb_U4eXok4TY&cM!~ +z68{XaGYGY|Gbozb8DyGdXHYb=Gia%{Gf1X2%tG#Gpngd+_ySKI(53m$eO_(*i!^jL +zP`%6rC{lN2qRhFJiIjS*FessNCUalS_3(gA`RqHYYpV0nVvxYER_+u93Y2FzeV?&p{W@)k<-4FJ<1WXbnVv!BOL_)lI&@k!Cy>ZE!1a;TRX +zszsN+CtX_b!MDViax9uT|1_khze%<8Psu$=YN)k}MJGiKv&7*Pzzmo{gE0Jn8H^k| +zuQCH>u+6lF*`)P}Qf9ymO6xO#88iu*0W(MGQ0ZmP96PQ4aSrLH=)NsL#iD4Y +zm)TOSmznfaz7Dn4%Umc#CCs)0m;p0r5QZNxgC-#}UHs@~P-|tPqM2T1OSN8R(Ck((v(#EI^SDa-u+%V198LkufEhFhAJKUI +z12Y&oc3w5u5~({gIAGV4?;B>5)+b7t0W)Y2J_Y2J&&;4n$PAdlHq#nrt@s00nE^An +zrth!%k{L7!nE^9+6{)TTH_RrjPn0qPX21+g6Rl1YeW9lg=n`F`OLS>jm$D`K<^bjE +z&JXr-P)X_n%qzzEr!Wi^i)N{cMfe0WD4IE>-%@?&F2_p88fGE)GfW(stYk< +z-Hh<1o;pym=)bs;_Y@8li}Ys|i}Gh9@9EDf7U9n-7D+P|i`q)5SQO1vELy6Kyk}Bm +zuqD*m$os88iu*0W)9* +zdIow1LQk+u=w{ih_M_n&4G +zc(Hn+Tw<^#rTWKTD1Ad{WXdtsTA8S5<}SzF`&~skNR#(M-=EGNK!!rAaeAgUE=!OwZuUJ$0aBk$-U& +zi!x^wi!^8D>)cAIShPPMZn9Po*fGl2W&g||QL231OjEuNKVSyTU_p%M80G7tneufe +zMatL7L*?sIYvt=qikyEcwRZlgXr_D}8PS(1Ul)+K0_+Uz3=-xQU}w-IY?!qk4_H+u +zTG)FekhcPye`+UkO-`ildIn8G?>|jWaHoMB96MVDGYGY|Gboz5Kr{0tJAdIqJ|dIq^e)-x!z)-x!Y=^0c~q)e1F`$Lq8zT8s>j^gxAjV{rpa`z5UzK$$X +z`MPLkLkrC+`G|lu3O0D%WlV*AbrPj(sMKe8vRBL6TqM4pS +z?q8LOIw@+H1|H}%} +zHew{H=?4z!7fKz{PX;mrX3$wxFpU|6S{rOhni*`V(uIme(ac~=YPnu!(ac~=Wkht!Yn^fHSFdYQ>g +zy-dB#eY;7R?FBFcX0VM?W{@Og2F!pNC|@gIzk}Vh+@>B60m?+mMB6A;CTf=IWkyn@ +zm)SgQm`z%rC}jrBpg|Zp4KrvGG6QC?&9sJDEB=60X21+e>ob5EGzpmjGe{y;K*Ma( +z`a~%+UMy{q^7d=}&+9)4%&a +z?*7;R{(t|U`~TDYKYa?2q_%4QZGri*9UFhajV+lcn{o`{a7cgV*lG2bgxOwzBvq0+ +z3jN9|Ge{CL17@(qrHOCMAk^BPQcLmLiyr-6%a$G2oC(O12m;p0r5QZNx +zgC?QDmhb~+P&D)8M{JKh`4JpDXJietkoy^^%zzmz;c&t#GiVYv%C9AjrNIl-yDd;3#`Y&wpf!3n1$TWKxGEZUomTY>!Vj21(M->vrCQG*Xr^Z{rbB0`)-y<^HOvx+Qvfq4Gq`x_K$2Sj +zhe=WwlrIf-FTlCXg_=kKc`v}od-I^}Z;J<#)Y1FTt9qHC){@jFVZ*HTc)+S8wXI6| +zI;?^jGzpmjGgy%OIi_JYX?>!U88CxD;Ed1HDl=#jG6QC?&9sJDEB=60X21*<$P0GUa@$Zm{t*r2%DLQ`mMCQg +z#{~Ori5W11CQ>lXE$^k)&Oa5+jFvt~^3eyQrAagApIWMasF3`PIe-~3gS|r3Ze +z)O1f3i&>OzPcPq;MyIyAavyu0aW9QX|S?lqDRlUr%DkJZc +z6PR*bVjweM1`BdO$1EXjlKUB}%zzmL0%v?OgPC9ttIU8IY%^^`=pS%6eP9O6U_tKZ +z7-gc7W9L<7zzk*cu&UQ9Dh6l$$!P&E72pZvId>cAtV +ztr~Yfm$2k-%mH+XE-fg}9HW;RS)`Hoq8T%ob=r&7#j$fh!z|=}2C5`AoZy>JQa?Hj +z+Z55uOdcp-mtZSjC)2!G9Z8Y$b<#}vx>6QXjzu#sR<~4pu{x6?Wuj1PWuk?>N5X6? +zfEh4@24VOCGiVYr17@(zw1ycoSP=BsWskq0fgCVq22Da{zzmpyo`If0xk(1-8O-^L +zo!;MS2Ef%Jkx?1G+T-ALe4;79~@TAxftd^7f~N +zsFh^&DCU<0@?L-`$E1Ra#Su6kzBlEVBvi3bvDmf>W)NzvVo@}+Gia$+u?U)d>xcB6 +ze@YVE*%>4W>Gp8Uw1%ab2dI&?49Hy;)R +zJ%45hUuAzziCM;Rnp1xyKBc!8X$x +zW^eI;NAxlSW>8w60nDID$PAc45~%_jW}lRO0h5<8%zzm%gMS!#Pac?ZETWilOauC+ +zryS1|@%~frz|P=BlJ(*nI|Dm|a+3^bn7stvE55Naurp{721-At8C-elK$04N4|h2( +zNT4LO2E5$mn9}Gj$0#Y>e*C8jS#aPfM#Z8~s$!9Tzzmo{XH~&8W-#gW`3`nwkTsEg +z9FD)h446TJumbE1Mvk3UnE^8>t7K!rrw&vs +z!kkqs+MGQ_)T-fKx?-A<_wr{`jte!Bg4texTi)9bx-gbVp8_PQ3wE;!^Z3_QEIKJt +zu?V$Ru_&6USX4&D44A<}MiMc4nPb9rUM)3Wz~L0b446TKF#N#IVC2|&)y{w!Y%{H4 +zHfepLlo>FC()tWw22Da{zzmW|70@ti#UHTB4445kaLaqNB+eJ{gqm+wij;|(hkIH- +z*ueb~GiV+dd5@IE&Y)RpXAo||42ot(OEYCLO;j{9TAE3b(b7zcjFy&Kf4`wwQo3{r_RKrgds_D$c|a!(QE>*9f( +zLGr+3faA8{RK)r5*9ytsm;;Ve?gIEy05f0)fxsD`r&T?JCR@X-^?1OlGEr^7HINgf +z%%DkV$}#+a88CwdF`i>Ikc(y-$WuCW7IF>bVG*ga|MJitx%?!3=7O8w)G;>J5 +zrTXsYQuF+cIe-~3g9W*tWArk^512vGj2X;2?J>aO*g2qK7IHrW)y^QCz|J6?z?9<> +z0~=;@MiQ&a*9&&DrnrswgWu81Oe#1G8%dF#!4bPYeeW@5@<5p=k|JfInPaC_Wg=#puR4j^SuJ3x3t{m_dW^B`lwP!wi~) +z%zzneGp%7ZX?>!U88CzA%KnCbWCl$_X21;IK&|KhO2e!bf50j;UdS|Z5DVn(^r_|atIY~3u@ga5-GzgMvc*}GA( +zpi9M~g#hO=!(Jt+og7F~L#?YM3PsrvPTa3>t*t2h3pP*m;#1FoSKTHOwZhPn0qPW>8w6 +z0nDID$PAc45~%_jX07-GR+#}a_)5*-@TmhgwzO*e`LFwb*6|niWM@#M`z5+Wmm20X +zL?x+7vs+23BsEyHz(ZybYHj4bXm<1Q9dI~dRmGxNs$!vHu^{(zOv7v?FFA~{GYGFS +z*fQhuw8{*Q3HGqW4445kF!ElhyNi93B}U$jyqB9~z%L22y#PIfhs@{j12ZU;GJ_-` +zGhhbHK$)oOIC=)nl7&)F>hTbuOmv(JJuE2`MN;JaQ?s;T_K3H)e9$wfoXcU@L@6_9 +z?lA*qkVLA0hS^&@;1RvdfEjc~5-4Q`O~P-|3=W?v>8SRq>(=U0yBuz-C#?zbQgp(MC}X~tjGILkrde( +z6wO?dlPL=`D4J;?r&`+?RLcuw=vq|d{rObdCGzee9^4T}cph?IK +zn87yF8fLBd16G*-M&?ICA%-{{wdj798%qFc*lrjTmzzj?|#@x(DQ;y9N +zhhZ1&W&vp%F-G1i=Q8r1D0LV%8R%w&@&jhT3>L(Ajxq9HG&AyE36+uenPaC_j{$~S +zD-#vXjFz@k8+i|!xfvl-CeuU8aHgNx$86?eAEGmVSq!!IoELy5nEHWuF8w60nDID$PAc45~%_j +zX07-GR+#}aUIOW +zt{QZyMA3`YGeq?=)BYu?>7J$>i)LP|ZmGWexzs#=V-8>j%wR$8=NN-6;Rnp1XvPd? +zoj#pTVg^C8Z?R%=!3@33;DN)iNdkvqBVRG)xUj3RGq}{|OR07kcHR~!6D>&f?N19) +zS#25uT$2+hHS%6LmzxnTr2pkVGJ~R-p1~l}_e;#6axP_}Ox=}!l6nmP-uAzziCM;Rnp1xyKBc!8X$xW^eI;NAxlSW>8w60nDID +z$PAc45~%_jW}lRO0h5<8%zzm%15=Kd?c$fT&_FJtXdtHnX&`GL@7qnnY%jnx(M$Ee +z_=Xu2jF~}_kQp!oW}r-@Oq6bN88AL|V6Y`+Mfv(gCGf>J%Gcq~23ua}(u;2zW-o#F +zif@#!yK?7{{!3Us`-T}b<(L68cp>hu{ib2|3h93dT4uluUX9613^Ri!Av0hG+e~Yi +zU6J?&aQ+s<44ACurok7veG*L^nYjO?=_CP#kqEKto +zM7=|Am_6d{EgzTxGiVToA25UF9y4GD+e~Yiy~P6_(aQ{8n8Ezifr`b8|HCf6QLzZw +zyHT-t)Ssgdbg5{jVv*h|N$uo7k{W8QVo`fR?>}9pKrh7G`%gu)8}HJUTD!631+Ol@ +zG1yXSZLpCjoo^$cF{>hc>s +zgHmffgG`DXhAp*r7`AApXYfLsFTT+;NSf&xR8pi&R5a5wXsLeZ!?5wxfh0BmB$Ctx +z(%zznO(B}33*f5*4K2gdHm_ccM1~7vr +zAv0hGNu&yBn6=^$SY-yxfEk!_jF!Yl4diBt2J&Du_e-W6tHW!`F`1@;9BQqBoHR4# +zSo;P$gQA%Ra!d6)PdUE)4>AL0upswy%r7r-^{(I887$aM0eLULXlb*gx42uhU8EPZCAzer3v-M^`k5R!q+c1WBsF=cd|hg-d|fnCv8bd-`8sK)Vi6gU +z@^#Wo`MRZA`8ty#Q;wn5&Ode8uwj-soC5SRE9YVciBe`Ta_qdy446R@sR9~ilh!9n +znE^BCj3iLX44Q<@fEjEvtzp)RKVX#^FoV+i3}6OLLT11Wl1LTMFq^bKQOXRM0W&a7 +z)V(v)L`4+SL<@GafV7PmqotK|dH*RDDqnE^9k2FgUr +zMCm3OuvZ0Ikm?^k`+s3!54sWazUQCvsRL7v_2)F@nD%eVu|!Atx@cy~F>_44%%Yhj +zRg&5{Xfmx~)|u#lRc62p8iavTX3!)w*b;tVScx>FoU9*!Isz_e>B*V +zIhVnf$cPNKG|lu3u4F;a^;^#%lOjEXQfobf=cKywk9r1?6d7zun&}x-Qlv~&G}AL^ +zseaGFmaG3YX21*<g3*~D^BQT +zCJ*#7OR)7ai)PB#l@#e^Ce2hVDrHf=E}AJ{w^Zw8W>RG2J=9wHy7%u5v&7*Pzzmo{ +zgE0Jn8H^k|uQCH>u+6lF*`)P}Qf9ymO6xO#88iu*0W(M7Sp#|BZW3mD0iOJLs{22a_3y;5jcPQo*6U=nE^96kofiQ +z8)lQ%CrX(CGk66Wuj7^(GzpmjGuUQY!>kp5z$!Cf1_u(q{yj5j5;6m3u+FH1$cEXZ +z^@&nuzzmpy!Ita8EKkW{u%(D%uw}t+7Lc|P^S8U7H~#IF|FWJz@W9TXGcr2^JA-nQ +z3}~3O9uHWxGiX0x27yv$&?ICA%zzmfd9P_-7icC+oPUZftP3=gW-idIl*P{A3C&iX +zI-pBW{tvtQnJ&?#lAR2oOGPv1pE`wfv2QX>#Uj+&`KKxjdjIKqBJ@PU^)icQH{O4$ +zq{xjePZ)Lmv%!{9YlAICGv({Zh;EdxlV-|92MYc8y)seKO!>O@ugXM4Gi9R6hzzzQ +z&0OD=`&VV6PKrv+7jQVmFau`LAPhgyGZ;B`Uez-QKVSw$Gd+V(JK+P_)-x!Y=^0Gv +z(7jaOd{_|l{Fxzu88Cwdxu0VufDPDNU9vM+u$u+B4Wy61VB|enV&wfO7y9jcJ%gEJ +zr`2B)W_tk|$eB<%|1>&*2J%w|E?7DY3IEiKi~KLyPUwxpKpWgh234@(WR#Niac446TK@DYvIKQM!lW9L=9 +z%v%%HSB1DHY4j2SS4ZJId@TRUWfEk!ejVOy#lhRvkN +zlw-)b^G^$-GYPY;0A|1p8ie5o%%Dlg44A<-(;8;XU_sCiOQ8$@u8VyG#>}8e$PAbP +zGtfY;YNwt-vcv_Nk+oDrHe7Dw^pTv{dUEuQK$jkL>G(s#Ed6l`kfcgd8-xQsPfN^T?U3~hie?(fE!75FGAYtC2({KT&@)&N<2l9!nng1`gO+MNgP@r* +zQ6@#oL<@V5g4tdGGhhY@!U|vpNkTn?O5K@3(d?UPATK_3pnP54u6!K@ksIaf1=aYW +z_jCO-!+*zMOJ$LInPvaXfEg5vI^dUt*t*t2h5;J$PAdlHq#nr%wR##W0yVt +zf?M7L#>}8e$PAbPGte{8GblI706l{_U(qutuQ5&3n+9c~qM4pSOSPUsGR@8)k|I5W +zPMI2JiNh&?88CweVfev2nZfE)2ae*z-{a1dMnuW-1oto~9g|Y)0Ng +zttF{NGZl->V&5rA9sWDY*UHxmazDo~17@%w_j8QFmPx0*|5O}12Pj{cRNwwoA+y%! +zDl=dP%;00G`H+*ZEZG?p&2E`NDLpf2mNv{n?q{GX6UDYbnW+7M88iv)3?g-B2F8x{({E +zupswy3^NF|wlgT2ISf0dLuaXWGeXcznP}GO(@|ArqGVdbEO9smFau`LAPkf;gOOv( +zMCk;~pg498XqZh}pD1Mp%wP$JlOHgHGYOZUI&iTsU255h!k~&p3Kw1KdarubOfUKVSw$Gv(_nS}0!^%^ZfE(xH2)zWJ~q==n2405f0)3vxfl +zOaL3Ox4L9!uwXX}avMk=f5DVvvc!~QBt@niXO5j#O*w`uFoU9*oKmPyGJpiH!2H~UB*e?iY6d7w-bNs*qx%(3&{BVo1|;5Ow%m_gA@FLTyuz04&NHq1iqXP`0zX0U|A$r6}Bldxg7R1P|Vt1{7o +z-RvWM`~|(t}mZ26c0Zz17;8i +zobkyFl4IupX21-#nRcw>Yaom;X21*<f1C<#tg9afp +zm|3*2YG)9Bzzm9JrX1()u_?#m*g2qK7IHrW)y|+ZGG@RGW)>~1Hq2J?lEWA~g9W=; +zQ``Xi@sF5tOdhxyA(A3DBMb!lZOP3Dhcs@;qbH2Wrc2CsPPK*b`= +z*}2R%=NlD^Dk=Q^=0k<#Z_EKI76DY{>nJ~mv&{eS*IVMTX +za>c2*tYR_P!2MFgY|{EfDKlUO4Z=VvGiVa3ScD}ogQA%!$80uw46tbCW`sDS( +zk@HWb*2+Yg6gmG?YHiA~XlBZ>k|I-%Ni$Q9l@uux70on|TdLiRkV%m;QK+>tkuuSO +z7|$`vL`5@YqLykGXa>!ci83itCR*5g6wLMlm;p0L5LN&)ND}H9RO-$Qie}$H&)`*0 +z9VlOyw<}*qLBt{b71j7*Au7dZ2++%{EK)DC?4KDhgJMw!xUpr@X*aeM$Ibz+?+Ufn +z%Pg9?u_d)!FSBT7}E+}8YY%joIOZ#*0wi4-6z_uaKiUG_y0Pl*P^< +zX{LN#TL(LXqM4mROSPRrCPgmx4YfAqIF@41s|~Zn;S|6Om_dUu{D2vZ96PTv17@(z +zw1(NF^@&nuzzj<3Gk_U137G*iNFr50!>kp5z$!Cf2FySMSpzwhI0H102cx-P(m>Wg +zZXyNKOcRA#Z#R%%_tb$y`tkSpXym&6+94vR6rJGEI_NYHiA~XeLRm +zq-Z-yUHC5~khcO1w$x6|&LC0hFl>{sVb*#)U{x=3VegSZ-U?s_?L;p2jnrK)vq|V; +z-^mH?{*@UpgN2MFV(bixW_AXdFWDIs&0Or8YOQCGNs*pGskNR#CPjJ%rPg`|MKe8v +zN{W<;l4i<8l@uux70uj?&{FMYgiMO`3_`7yiIj;J#CVQTCMudK6SY*|e8{|MFMt^^ +zgIVrh`P6|Vb^gCoFSBLOBc&lqr}v~iQkqO#LfYF6RK+54U}lgIHQ2J?2a?qA17^@n +z+YtH%h%y6aumHk{QNC`LG6QC?&9sKulIS17)y}}qptL>%m_d_}88Cw+QUx^34uyUJ +zqRfC96aqVd88iu*0W;WUTElEf^pD_bXJBWrAop_&GiVYr176; +zU;%^?!wi~)%zzneGp%8^B>G2iwKK3YD6P)`X3!*L2FxIdQ~?dML!n=QC^LBNQwI*| +zmwP&-AF_8EsxR87F3bULY)SERV@n;JbYn}h)Kf%JT4M%DGiFdJtcpd^%wgD;YB#oI +zQlw%LYVG_}Y&=}-yCBtfKQBZ@Vm1DPTi(MDm;o~=tfNayqy^&(;8+W +z_cKtL0W)Y221=PhldxfyJJcyanP|ao_K`mRf}TP0K+hnOB0YndW2aROxE-mcTl&>p`RK8A{DPOl#|40NUZcC$GH1!q%Pj9d2b8dE +zx+h)w#&v15<=<9smyi~j=m1w0i)LxVOp>~S<&79gYPbb6XcB(aN$LtYm_ezv!ItEK +z!ImK%y3gBx{Ix>zH|Bs+^MZK7S9{wX&H%0xvoPkv-l^!J+&3xb|MGXyXLX0RalbIb&=0eh=Ub_NS}vmm#D +z^zj#ryeCVHyhl>x{L{>_)2fm8a0O;iG&4=qQf=ftXlCSnOoz@=ef!gbpy$sF0n8v! +z$_$u6>`j@$dsL8=i6)(P{%L_`dIqsQ-g_qe4No1YSk#|H#Uf-+#iH$1l3FxVu}A|| +zv1q1AQbVm(EILnZn6=^$SY-yxpg|aZzzmv%%zzneGp%7ZX?>!U88Cy=`V3$OO+seC +z43bC{&@gMoAF#>{m;o~|@}6BHj{&w+|M{=`TpE92PwNL8xL;xh%>yIvGeqqSl4hnH +zhv~!nB|U?pnZcG!SsaF~4YVyt@KS3#gG`FN|5R%2Fl^DxXlW%yMoW`s +z&OcRBq)b#aGg{hG{r1DKZ+YrKlA3=KN$P^~HS>GFbo?VK7VXas%7`9YsDY1$_$u6gE0Jn88iu* +z0W;WUTElG8`a~%+U{}c=2QUqe|AW}EZX^} +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 +zX21+ap +z9&Bt^gqP9{h76u*_hf(Atun0W(;T`#EM$ +z>l3KVfEfe=XMCPk?F^cw%zzneGp%9Pia%hL88Cwdxu0X0L6eXfFoT&z3#$#YN$V4( +z%zzm%1EZzg%F{qDqP(_&y!X_B!It`aNK(`OJw=qwPQA>|5B74UowLxAv0hGNu&yBn6=^$SY-yx;JLED;UAenlaLuOgEvs?`M=UI +zo3uVr$_$tRGtkR?SscCm#$nhZieBb|-MqlnyME(lgvz>bsvy&GR?r +z0A>(CeWe-fK6RjC5r2<6DSTxO4EK02nwiL~byth<; +z{7dIe{WHUVhZ!(~1-YMNT7R^2D45xgW}jZpkWqrKLgdyAe_L?Ae`XNGvUFpGXoul4L`6mXr?V8 +zZ3T_jW0(OmXb^@U*clwK>&f@bfEjEvtzq^QajZ888E8@ZH^vu=~`3qd0S$@l;%P6esN8jV;ft_^B;Fe0F0?`m-Bb%D`RU^+2b? +z4{mI!p1$)>MKdGsl@z(LC23~L@mQqqmsBi@W=7sys-1s2%!M8psC*r2ZLp;)hYhnw +zyuIZEGhhY{!teuT(A;AN%wU^o4YRj+z$1E@0W&DA&j4o7BxDB6Ac<4~4YNn1Kee268HK252Cs0cjv>AUBbMY3@u5wbnpRnrR@v*a}>HV`oq_(?CuwS0*Z& +zxhAJFqVKJNy#3SxU7|}ZJC}a{;$Km|4rwyjQad&0pJJ!x{8Mo3oE$XFTJZ<0N>Z7@ +z5)LP4aX1Aq17^@543sj1kz?moJ%jKAW>7TKGl=c6oUWl;zR7o#ufr;sL6eXfFoOlTpJN(k +zlh!9nnL+Pcn86HDW{@;fzRvxtok7velw&6I%0!iOc^Nj<+RLz+6nPo8)LPFVlOh-U +zmRg%~EShN`S5l;boHR4#SV@sGQPIqlV@tIu$4rX!3_`7yiIj;J#CVQTCMudK6SY*| +ze8{|MFMt^^g9W*tV;aa?D77;Pudy?j@p)Q(&CcK*o;pyz&OeFrby~Obb!Cyt*XiC4 +z>CZbgK_)OQt^iXW>7$72FxI|KDSbOnMpIf%u;$4i{_z`_fYHCR4h{W +zuLjr|gdZ>iW>8w60nDIiX0YX|JU{)C88i>|GDEEmwp7mL{8MB^Zg~%mooiGLvuEPI +z0Ly1F%zzmz;c&t#Gk8v_Yya3V>-2xXs-3}t-RvWM`~^LOYruc@r7}?@Mao1o$4;v* +z(43s$_8-iE8Ke?tfSp0n%r!YLf{R;rfbnX~BxG#JIj|V8D6F`KRQ8k@r$-6Pui=vr|MN75oyD}-VGYGX-zV7XL!z^()1uz3<&>##yUX21-RNEOg9YsDY1$_$tRGw}Y?vj)UfPG}$(Q8bVT +zqq$$wK-NIsx0{67UVvNPuNuJ9FPTBXm>DDqnE^9k2FgUrM4#N`J)Sx+*pjlMeBEV3 +zl>)><4tnkp5z$!Cf1_u(q{yj5j5;6m3u+FH1$cEXZ^@&nuzzmpy!Ioz; +zELS;Uu%(D%uw}t+7Lc|PN +zapc%}wPDtkngOeJ2A^!@(O)h;*cnVtaQCmwU?AATl5299!Ghe+F?(A70L8-(%-~Y` +zFPy;nrx~BGGK2Sd>Oe0u|0H^u3(9we>MzOv=5JIi%KiM(4mwTea2%#AHA)oyGFni*`#lu0jhp%9fY+X`R?%%DLS +ze!vWxgnF6b2h5;oX38;(nR*6AGd+XMm-GxWDbh12wbnDpq{v~|QfobfqM4pSB}IA$ +zNi#izN{W<;ie`ESE!BDknG`7#g<2~UDHAP-@f@Q}R5Vj2YN@{Yka^Qyz}I31@AK4w +z^7SlA?s9BVqDyosS=0f_*Of&oUnkR)uS>9%uZw2N*QM6V*GV(w>q?50uZw2N*Dck` +z*O?T3EftFeykC#8GbkR|87$b%0lMDld*$m+in>dZNS^|j0W)Y2M(VDYIdbg0+AwQ9 +z9&{pLx$H@uY<+#K^I|F90Aop|364EBQpRvjem_Z8?u +z0f*BEX21*<O`a~%+U8S&Q +zE%o=1q^AA5%Q2gsdYPRc?B$?|Qb}t2vtDNSfr>@5RK+6vfEg6c9EQ!UlqtuenM3-S +z6n#I3^cRw!>oF=8rPhlTi~5-%pn;r7p91U*4zT~^dpm;xpQj}|gOOwBRXYPagAE(F +z|92Z^lh!9nnE^8>tJjIvocn6NOqU6BW%| +zlT#UyGErtk%0z=m-!CZ>by8GnzJS9ih8Zw}24VPtp25hm^J>GaD>VaF?F<&|W*_O} +zFDMfw5B_C<@Ov!j86*$%3<{-s21!LdgV702?cE=Lt&seUIiPcnMEVq9XV4j$X`&gT +zb_V4&%0vr!``ynAQJwi5|A?JI0Cmj_-tDOaNoxE(?j)&_)bQSg^iz_W{;Xm#_~vQJ +zU`sRYmxS3~fQm(K)>JIY512uckQp$81-YMNm_ewuUS`qEjV&$JZfpsfnR1+U`gCu> +z?N8fsKmSLVL7^RE$^8WDHD}iD-%6rK8GJPkV~yKkc(y-$dwdnAScZ< +zkdH^$nv(FeLjmy$>oaEPuW +z)V=O|Nvb5ZdnkcYNouo>88CxwrZvo7r~VhXWd_Wkv_1ovL6eXfFoPsg1vJbq^?d=E +zpJJE+GhhY=TMV|O5@&$Hmb4y&Ee2bfNWnCZ0ft%|Y)P6KY_X7G+r9VlOya426#4t#nO +zd*uAA2rH{}>8Z$F{j8T+l{<&@lcjo@kwr3tq!}})9QXT3QZum{1Ki~pYOQ=-G}Fth +zj7a%9Ga`36&N_V>JGuLLl=A$63}6NURA#^o7BcfWMlZ8y#td4jnL*IZ#lF`Im`^0! +z#lD$Px!AYVTF>AKqpp9}Gng}?8$E-hnVvx##y&@*VVF#~3>&9sKulIS17l^HOD()tWoFoXAe +z>OlEA|0K%SM}qhGz4Ep4brUI=X5>AZjmpJZ<$ZxAMoZIojFwhs%WcZZG}A<()(fMh +z@A=e$>$~Fb;V#FNJ=b?V?8uHkxV|elYp(Aq_mrd_6YQ}j(t_SlJpK`PIkq2c*Cb{h +zC|^H-{rH3Ob!06DTbiW}vjKsDwKI6Zs~6ue17@(zw1(MB;JxA-X21*<6LZ3Cy5ioM!N@PaU|+vHl*)*9#h{d>#I5%CX&huR5J5Rlcsh +zATvmm>SZ=dnE^9MB2_@ctQCL2Dl=dPosk4enL(3~88CxwrZvnatxuFP17=WKp8?FE +zNyrSCK@zC~8fLBd16G*wZju3}93yo%@}4yFGHj(Rb_PW=(?l)RAOEr~_w#>*88Cwdxu0V^6CRbK +z@4yV+_o)NAM3-jGSy`n^bSa5c0m|2vLP}DDX1B`Mm18>pR5bJcQ%m*T&!y)18*>0N +zUf1J%yJ&R_|LlOHgHCSk)YlaeXmJ1Ado +z?;Gq4n8AYF&oOoelM~#0WCqOO9i&>BC}?(LXHZ)1F2_un+~rtm?fg^G%*cC7^^d>q +z@3O~VsMNk-9s$Zku`SR*p7D8FRVFH$=^13oVrS4yYnX-H&p>4c%%DLSe!vWxgblM! +z&IhdO87$b%KGMfu_`~lE-ubBm6^k(EI~9vb^X}!)A^lO5PQ_&vi(;B{nXy@ONIz-j +z{8Op5B(-SfkbXuq-W3>k)A;%MS2EB +zGd+WrYCVHYij;{WDN-g1Bpm>t!w!$P;E;0nC6IGzh~Fm_d_}88CxwrZvo%!GfUg +z6ir><6)T~00g}|Rf9Ic~Z0BO% +zrkO+f(>Cosg>*>2nCARbskQS@nH1?|R#N2rQ_)N>v!(i%qgQA%Ra%_)p^bC?_dIptH=@}%=^bBf; +z{73H@y!%rJbcrr4?8PGHm&!8RAID#iq%J650eLS##iB@{e4Qv&u}BiCSd30^I-T_A +zzg9^8#vITlv>*vWK!fXY^k;LPen65gG!3@GLvR{29*>k6BW&ze`=|A{wb3p=bu8Ym5G#z +z7Q}dtQ6?&yDHF9+JO30kQzpu!NSSD1?@=(@3t$G!AVF9G%pggqXHcm-Gbozr8N~MZ +zkAD8?{hvCZOLQq^Cj;~{D~r_2Ec@5Xtc{*tX3|VAvnqFbnME_b%$91s%uI^(GDEHP +zG8gt93A3#LX21*@gy9Fwph?IKn87yF8fMI3LD0KbbNnL?!v>6*L6eXfFau_wXP{?L +zZju52vLLrRNs+;p<6P*sC4()6QiCnYQf9ymn1P*vok6-u25cofD^mT#LR2dL5WozI +z2d0VAE$j>;bvI3vG&4<9O0R)jG&4=qQf-=ON{7xQ{5^XH@Bh?+yBx!uKRTCLIj}?e +z3##Feelbn?y8K!BI+>FC()tWw21PSwP)e_S +zoitOvt{t-Sbt)yy1N-+Oe1Z79|yn7N!5k +zA^ogxD_?hhu!OWuMvo9HNtL8F2*VE~sm(x1YWM*&D4ID8n=>y4TZ(30tUkWPeo2|AXr^b-QtkZHVJ`H* +zKxLv(Yh@y3q6IOYW0Z-CX39j5l6>?*nJ9UvOjK&EO!ScX9DYzHDz#Q7Dw-)1MMk7d +z)ESX7(XmJ?6BWT80vv`7wN@r7ni(xkwN@r7nwchgl;ooiLz(DvJar&RJ^V}j_7~F2 +zTu{CR=7$51zo24~{;XnA{;Xm#a_qF~UAiM%W(Es3a38}ALahz9JkaU*gNj9{wTea2 +zOvNHKTg9SireZOO^!?IMvH1VlyYjdi^S;es>}$vp*>{pHTQzo}>_U<~M3y9J8eq +z`u?Xb(F|w?669VS!!1YP2Q&jjGnxUEZJGh18Mhq8I$fBz^Ubh`Y20!|YR#DeOqn<{ +zKx)mI0iqda23V^3W>}OIab^J2nll4LGd>K9rJ4`J0-AAVfTh~57gBS04{-p^0HBm+ +zKr_I-O5g`H14J{Lfmo-FWSkjD;30+?kb5yuX$CX{r1daBz8QR%R~@i@4SywUUyEhW +zE}!jd=+A6lW95S|Q!Ie9Oz6*?Wg?W)3?KdDivrJS<@nKjNk-czhRXi17F> +z397;4yAad3@{SCgEANnLY+oa_=E^&w8Qa%bs(E}D?1?~_DHcF8pcz0Aq5zr!Bq3*+ +zphD&>6Vi;cOjIGWeT`_wStgch&N5+A^j~XVO8~f}7`BNJ4_FyUup4P$`>SDmS{}W7EI6#KE7%Ky$)~pO*Qp5o=Qftl( +z5Y0FTx{WD3shnlz{M7U(R{eX#TL{q~eYY!d;s=FC7s?Ezt?Pyo$a{-WV`cjq$et0~ +z*U&xLu|PCq`x<&HlT;?D62w>>!}c|*1$lgzxS3EW)&A^Qh-t>-yI@kp0S{OiNU$5}c>61nY!ktZh+B>brEC*n?$Hcr29QW7fMx*H +znr$LPGq#Cfn#48{q8ZynSgQG&aKtpWiI7^eO@uNcwuwMSWW{tNVvt!2sJ1>v#63d=HI~LGAx!3|SR6hSCMXF0lh>}o|$&KNbBk}{90nGr* +zz1R%L+>2w_zLuM@(+m*7J_gVX +zfNawY5Y0Ht6zgP&nS@D?b3uSQ$XKpcx>Vu`>81$?`t1GC(;OABM$J&4*#- +z66`nP@nKk`)_fRNTzGJ`REkt9zm*Ur-@42~`DoFAktC{jcg0Og*IsFiAy3VUh}Yz?FBT)=W|n&A8==k|H@t +zD*SWO184>ar8EPY0n&OHKr=uzqZ!Z)6s8$h-ckL^#TG;}9^Zwfnu{$kDf;iUuO*;c +zY78p_!~<3a66{7Y-u_Y~X9f~#4+vz10%!&_0}Mit+jGkilMurU>#+c=Nk}uG87Ry&3^T0w0<6*uXa*AG +zUK~R+z$By@{QoqA@Aj$#&N9WK#3U7q5+BkBqQv97BqaxukS0n)#aLyM$|O}14n>y0 +zBo#A|NhYaWw>XvSl5K1#B@4?Hss(u~LCV5u&JLf}2b +z0W<@ef#QuQF~$_W%E~~V%Y6Etl>ve=+eDCu{}nU%ey=)UlFB3%xjPO>MZyA=M;t(1 +z`rp(gNS;3vz!O`Bx5Y2c@ +z4wh=Z@&nL}Z6aYhR3z1Qy(9=ayp14$W&lu1GoTsZ@)Y<1%>dDiW*`vh50_{Lh-RD_ +zfbv+znE|93pML@w5g&%dG~<>d$cX&8O$2H7-`R4Mf^Nw%oEZQfurk0r-~bt9EvyU> +z%~%;g&E_@{qS=3?GWd?KI$)9t%$Z3lHfJWOz?_Y^*aB(B#TMkxTx@|f<17=YHD{TK +zW?XE6r4&0Bh-RE+!cvMI3!D^TnBfkx0IM_ungIqO@B^9wCL!C`zz=8!h-PeGvwe+N +zBq0F949LA0s5Aqbfx;-I8DJ7(n28d9h*DMt66{8CqzmuBhhZTP_%JL;ia0Y6bFA)bm<|<5H6MnBOv5mPI1~lY3}^-zgaD;910lzXu5xAo +z{D5YFXvUcVD3AFtEZ|sCMuuSqx!<6;X+ +zin!PUX~xACkP&f~32DZ~7A)0VY=KD;+eAREIm^WLJBAs=p(uchEhy)r89i_2Li +z&JPsJK_N<+q+);O@m;_V*s;JYWyb>e0nGr>jL$#8Qi|`TLp1xZyq8V_wEsj5&vFDj +z;L1Dj8lL6I%0NQm4`Wyv0NG|`fSJb10H`%914J`c23V^7fB8=+zToen8PE(Q$h|m* +zWwp|X9iHM +zd1e}9DYqPvmVdqFi2lT%4ZuK#NEZdLGLT?5666-7J;FQi%rrLbbAT-7Sm9N^ +z3{d0*cK^;Z)4uDg4ya4iC84!Tx=LO8f2d24Ie#*MNh-)9x!8he#^;})mUFQM(Ts~N +zP`TN@#(5Ej8IXH1P-zA<0}Mjo2Q&jrLJTvI`-_3f_O%4NQ5@;QJFtBXdBFBHNQ&6L +z7IUodD%(Uf0||03j-eREl0=_ +zZaJd*m0OO8W?Xp}B`ZaF4BJGAW^5CI;+1V8OfyyntPF6@gP6uP5m0Nki4e`$CW30s +zHW8v3w~4S+^OzjSGz>E!_hO)aWd`5(RR`=?fZvBdI~MF%Kv94J>{y6p&z~I&R7bI6 +zfoaB$1yXBnIZ8-_r65g#7@7gi0L#4?sN8bI4CG=9NZn}$n1?h2pw?e?ETFjm*#NG* +z(+niYy*P$uKr@ga_u?3u0T6GR0iqdanPQzTd^(9M?|^2UWr}sW@Fm`yWkRN5m_Zzh +z0%!&_0}MidQksE~V?|dn%s}oh1}fV`66{8CqzmuBnE~Vh+e9EK;>wp|+eE^2s7R{WCIU2Ln@FtFY!gYyh +zG-LZ3r7WCfBAUtAz801Rg^#MrmZK1O4{-p^fMy^;?!_^z3_$8mGe9(>8Hjb7W`HqSl4{N}A=4xw4Jf_i{bm95K*{IBruu}m$*$N9%~tKn+Vd3 +z17xJ!+$MrF`@09o-}zMsoMj?&X2$}WGoQ;u=FAgYAkFyv6D+HEd>8g-32C4ND9Vjt +z`x>_m*}evTz{M8%1p9ai!%RwEA~%NZYYBEEL2d!kg?HfdPanZ9_XAhnK~ltyg_vW7 +zSGn>o*9JZ|mrJ1#32BcghV5&i6R>>^oq#U`1Wq91%K#C_Xa+)&rWr`!SWyfs10dLJ +z6Je&YO#}p+Z6ZW7&J18u#F+u28P9SQRjx%so@;bZf}q3O2m)vZGy@58FOCrbOn^P9 +zmpC(!U^f!v79d@C2hI#2OE@zCNfBoTVvZGF<;(!M0?h!?jH{(ss(EG_pcz+7h3Qa{ +zRP&e|$TSQyh(l4pzs?N4_p1(=q$2lZk}5&@pus8@z~?ey*N=-W$e-Di># +zGe8*;ABM$J&4*zD&G^a>m=v*1#5R!xF&4-C%i2WW{Z$9lCF&BC9T>oscO+c@GF_5T +zdHv}awy(vN8fTfn`wL0P_BBvzwyzP**uIA9&h|B;8Qa%Tt=YcDITD5$kb5yuX$CX{ +z3_{=sGy_aRp5+MqfM$Sb#^;|vc`V~B6Xsl;WrB>zjtBcfnsH_TG9rJ@G9k@4Gk|K% +znE_0SI5Plh&F7yW%{VhaYRxtgq8VofSgN`54wE9biGW(OO(dcAfG|@ifM!55z#s&E +zKr_H3q#4i*6lNNR8O=a~po1z~cn2Pn17J)uz$E-z&EUJg>VUIMv1D+TiM+ok011nN +z?nzzxAJZkF&Hlx!c9M_=GEo6s*|ESZ#V})%`aQ7!**%%00=J+UU=seVN$O|d{f~X7 +z86dUhL;8>hd>B@c4t>bmmEWQecn@&^QgZ}z5I{4a82|)|@mYA4l>wp|+e9$4;qhIV +zX&7ce?!`c*8PE(c2!S8a3@`~X%y4opz$zD8B-oAONEhCLl>y`dSKdKV#Fck3$BJqX +z2s6b3*d`Jf&4){D6A7K5@KIH^iBM8RGoTqrkb7|q%>bx1D+5F`KL3QJn$JH0n(@pu +zu}*VlfYPC&01PvTLs0a{-W{uZ8WXA%?Ug49U +z3hRPcS=hdY{>=6@+t+|aVvZGFW&4`#YYB2Mj-eRqyhEB9@sxL@*11OaPzbz-IDqYI094L0u^#}8i4lmevNDihHxlF) +zAYFI|ZaG38uuTM#BF+rN94oxaHWBaxngOC2+eBEZx#b9G#x{{K9V(J)yIv9m9o|L| +zKr;X+r5Vr+aCr*+fM$SbMl%qI^oL6{14J{<3_y9znE|F5X9gf6;>ie@X6|;9kR}C< +z-;SXf&yaQ(jkOyoNfux9SA~DAbud+=spj)ffM#qHiFKN7A_*B0SKdKJ#FckUGp?3msaAUlOI*bQFpweA +zMFDIRVIHtD02pRvAmmul)xYn|w7=t32TW3#q)JLd#T6kE7R9WSy7WJ#OA?&+uf*`V +zOvDlX-8E2WOlw!vM(Try~VyWg?jxZ_u`#Kg95dBwT +zSQ#K5uriQfH-8CxlK&J>Y{5wp+eARE`N|K-H<|&>0I-N=fXh>))@&0Ynz2oU5-PTd +zAkEk<b%65uzE}L|CfXCW1*3+eAREx$=(dcMLO#Ls0gI%AmmulRhj|K +zKw+j~n2EF=qLgMpGeBAo184@AgfxTyKW6Z^yy}1*3+fV<9hd=7m;V3g5+uxD4Ztvi +zI1~jiNoA7CB$bOTTx|Kv3jOI1a?25BO?>`|i!Hws<`Z-N+y|cJ2-KR3Es$nhY!Q|P +zc7?C%D}_SfJ;VVt1De5~l>V>dX$CX{334xv;laL8s%ZwOQ^e!Dz9G+_3pQt&h-N(4 +zSFF>8XRz~N-#?J*bAo;Rj9~`kUJO)L1}Nv^0Qn;n<$j{Xa)*14Z{q`y%?x81Db&xiI@I8%>a{-WQVK+gi!F#_MFE^;$}`R1zGsq(nZ_g)s5RTy +zAL%6j1BMw^d;wPfMMS!O@wI1HW92}KembfrdJ&>Nrk@>CaDsX4>KRvOY(2Rjs^B-3}lFOQNTxC +zf&%uJ131eRFre@flT;?DCohXFJLOhTFg%>WV!1z?zA#TQ_eW+E;p+DPUn1M7@3{S7#2%45B3E# +zv-`W+*An3T7h~8aLOft)z{)_Jj!3x5$^g-fl>w4)wuvy)SQ!AdW@UhA#>xOoH7f%^ +zGgbyLDdGT`17rzeERNwe5l)IQ%&_7Muu3za8DJ0sKcE?45@MLaq(l_J$^du`D+7@Y +zd;l=bK*+J8tAEqVy97A@#Td>EkXnD38T?(ZI$*~F{XVEm)FmdV{+wlE9&pPM5rwl% +zY&R0*7DG|~P5As1%x;;aB9wBmMLxlPyF@df8A#}Qh+}95K&`ph0%^v@mXDGw?*rS{ +zh-PdPiFMkaZ6dks`iymKUjwz~EEA_pl92W}>i*nkngPuKgAn)uXPKCFGy|G}!c4<3 +z`*Z651#W2uGy|mdFo0%&Nk}uG89*YT01UG)^<4roe~+OV&93X>{1mFK8fh8Ou +zL+jxHnFD0S?FPb3u>fup!K8@WLM%1!a+3Y=QRA#g@;S6W{#I +zjs>C_7h8}yvwi(dYW?v`wy%L&bFl@Na!Aep2)RG~Bh7$jfI$fSfU`_YJemQ`Kw+j~ +znEh!3_#C=41DXNSdKf@6z$By@&c=EE6g*4B#vi +zy3gM;%aow$e>sM4h6OxeW$?!g>svpvGGJw(aN31o_D$?b{gRadHVK*mfHBPg^NnUe +zGoTr;GT_QPauXQ9m3L6ra669VSld1>;CHz?qkR{j+0ba3l>xRY4v;}!L^D7%<2Df#a+(3683)L)ZeV2~ +zOoxiDVweHB7Xy`M@V{XOf8VPPs7ur(EITj*P)v5jqQosnEJ{pLAw-#^LYmPGXa*99 +zgkoq0K(M*x2s?LtFC9{A&N30rxaEkYTKO$fb9fJN0L_4AfaPB72Q&kk0bmi$KrF*j +zuF?z;&A8==w45vNm}y*W0cy>~7DO|yykn{6mLs4U7h7QM%f%L4zhjs|9Et*H1~dZ< +zLf{8910lzXu5#ra_yNrT(ToFR(8-i>%Ms>WJSIn!4t{XaGNI;qb +zFw#SgK2*5O@!9 +z0L_4Apm-xnj4_3;vNDihHxS4Q1#p`Pv*f!=^}oOj{?1n&FiB;SirgIs@c1rZ;GAV5 +zn(_H3=$>3`K{Vs>T~N!Jq%ujBAjaYt&N6XQgkgpiUw~Db0nGq|5cmPj0Fw~I4CMY| +zpt3RmUc<^jWCI@nOf$eF3!qGoTp&1d8!lc$H>=Nk}uG87Ry& +z3^O42VxZCtXa*AGUK~R+z$By@&eEtcjHQU$Ns+gpToPdihh+{PU9Ss5Uj +z@hnG>5pkA@X~s4YmTI+^Xxs_!Ar8PmhDa9$urk0rU}YeNDBDC5iUU>#tPB*k3Zaxs +z03nE>8PE)n*24hK3=qwDOb)DH*(Sm~#4rPLF9s^jfM$R}2>gI%fJw;80QdpT0MU#y +z1I`Q(izEbKm;t#L1C?e#Gf)_%Gy_aR3^S1Xi-F3@K!V*Uj&$K2{sk-V%Q29Fp@^x# +zSAKw`$j7#1Z(Y+oaq@nwKm +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 +zngPu~g4~N^Xa<;sGy|G}m_-tty| +z&I}OEI6y`j5oZQ4BjPFVpR4jWKXZVLlOm+%5^yMrp&8H&FbIJkaDXi2SkYAsv(Gz| +zfBG{kgKt~R=f1SK_b=J8z)WM3$|RLZDi>Q&*22XW +z$PzBLe377h`6CxwAkDbgf>IV%24C^&t8Z8t0JUaifM~|W7L*ZjmI*T=F1CEF&0l=O +z#TJ|tAvKqPLs1OPfM$R}2>gJHEkceJUBxi_att5=nZL)dGWgP5zVMpD7m+KDbm1M? +zCW1U*o9Js;{^1+8iNqW$yqXGOrdR+^d56}+nSsy=c(AV&2GR`vApKuwFf;>5Gn&C? +zMZh;dvob(5V`TuWfA-_L(f>{uY-VEY>SGdmVvxbc@ivSR^h#*PJ2Yj!NY;?-B*aFz+wnn^06 +z89NpzBVxw_W<=~*e67u2e8Y|fPKuD4OTeKhhGsxBz#s&Ez%551$BM3EnEjzCBLS9w +zh+$>$rMZ0JHJoLNY~TZcX$F5J)wh1+$p|z9334xv!7%$K_N0DEGx&!3f8hsg6Nw>8 +zGx(PJfAJ;FfM!55-~btw&>SE`mT-XlMS}9>j~pOFnsI>qWrFfWzQW3Yl>t;@7{E5s +zSG@Y_8&(EDtvNG51vm%DP^~#YMl>_x0QoCz{^FZlqkAaii$C#af20}wE6qUOs}5w; +zCF;_j)rha-sY|d}vqQon0f(X(CaFwPAqY_blT;zcimqaq;kJYTtL#{O!(YB|944tE +zCn!8z%dQs+k$`kj43F>n0+V0<$i)^3JrM;#i2gWdnF6EvaEY@_kQ8y2328<%_)7i1 +z_=aYHXvX8auvE*ID^^bx1D+5R~ +zRtBsL0E=Ko#L56_IV%H1Gai$JG9u0lAkDbt2-TVcWSkT!oSBP(N;9AtU=RX7-~bu3 +z6vGU6Y6Mv2%s_(OD2{aD9XLRSJYbs$Bt>i!i8)qymD@xjC$Rg6J`5}WRR>H`1;+pJ +z61NctnI~F)2V#h+hNPoD*_BEmz7hAAYbLCxbF7%OsY!iW`h;1Uai6n@zIEHN^L^HOD +zK1s5?4{Q@b9gfk+xiR6nk+eC<99|O4M +z2-KQwB1AJj{{+>VZ6ZW7KL7MdlI4A1n+PXG7-m53#XzMQ&SVl39~ZciLH9L#wLBqzjs(O%Lyo$)1?y;XK%ws&g4!V`7}{7(6gpXX_yoax>CR^8*RA3vzu +zWynJlw-I*chO+mG3r~z!)2RPAST-=*N6-Iq|3Q5o*YDAPOw+@0%SM+tQF>MX{vjDZ +z4ldE>@S(16`WEEPo7p)$+~Q5$`Nr-t=i^&jCxk}6TW2!$@aB+T2hN)R?%u%t>Sl}P +z{4#&CTj(i`x>K(>teNpVFLP|mhv`O>CIU-H`aa +zEW7g=9sQ$YWxecVE-eNeQuRI=nNUhU#bZGF)?JNLAHR>hA2;u+dyq}^mK6V2=>tZ@ +znRp*kjaM^xd&=9@@ls-1P}!j_K9@Yh67RkkCEJ}>_vpNtqi4;0mpv&x{cUJL#%?Fi +zg1oRy@9=lwrGv)l8(Qd{h|msoPI7;!A69pk%bGO>`)pmBX-*!LD7)C+=Hi*1O)Tme +zEDd^L-9OG#x!sNRTc#`uOi$3vaZMhy&dH{GVAihu@h82~T57fq3EVNkJaXkRo66Bk +zFKX2B3Uu#K?8E;p39y&B6a+Of*gro_-+$?#i@oE5N*U}wZT{}31&`bKj;UVVs;0sI +z--3(XOub*u;n=|~&&nsp573&QDtlDTZCIH=i;KPE?q!EAH9sA;bN1Y%!8_{oj2Wz4 +zN$17H#Z`{vJXCIa^X!}K%?GVAZ*Meoo@20OzGcGRd9JF@+s7&Azug^^ck#{mu6`|S +z_GaBxIlH2BWzG8zwtFg74~p=36J%WdKzaN4xU{*dOXDqbRo~rdeI>_TyWwMXJ*XPNa$G3-64Kx-un8=99ks3uUL9UwJ29oUosssd?N=%fJvplQhyRG5 +zr(M=Re$sBRSKrCg&Mz8tv2Q~aqhFeqb2RT*ad7pI{}`4bZHKq8?yBRrRcqr#OMmaV +zYqqzrkMA+=!2Gd!3lC~WA2n)kctYPI+_sLHThB5b^B);a&z+@`TiIx6fNdSC{sto# +z#prf*&GBq<>`<_N*u?yp55M2~nGYUae!MF+{nGs@tL7gw@!y_ubV2Ol!zShKHw{R8 +zU9YpPQ~kj*oo&xl#~;>jH&j)5z=MfV9j%IAkGUCU*u$%SC0WK^_vSZChcw@#W}Vz^ +zpL+Mec=dol%bbMJx9ZU?rkxz?cG7Kbo1vyVkGc(X8ME8T;l%}whpk37AF}mv%9*F5 +z%&xpD5&B}9PfUwZt*2hgOD-2W-Z$j(tnj&F0_?Us4$`OV0&XF|qWO}Vsf +zWB8o8t(-@gZVe9~?{IU5rOBa~9XdF_FD{Ufcs+`~c)!q@Sy9aw3 +z+?^Sl{bY&xB*W?6bN8NowkN{>O~!+f{f9>H4Q_F<=0@$bj!S!H>h8K>*G1blaj;WI +z(NagwMPrn?s&D# +z?VCHI@Ry#Tt(K^BJTYV5KD)4YA3)x7&YrUevpUAUQ|@=7UV!K8fq~@`dL};^P;j7% +zVPlol7>(&~es+F#=xtg~i3Am;RLk_0*1=Bw%wFxOR&&NlU5!o=?_U_XRI1j+DCf0N +z^!YaRo2WRJPE3rnKHU8M`z%*gwX!#3&9CV{Rga17-2b#ur~RH0{afiIM5#VEt8E*h +zA?sW}VSsPf9rGv3mTBs=wJA7fQ0e{np8dPlzrI@I__*!b^_5 +zS>Jh9JFQ=&q4KVI2jVXJhB%&hkYJ^i8W8KJ>8ozwpZp@ybf#hKn>R`6Ns*>em7cF& +zv2;ek<|Fa3`OZV<1i4n9SUymB(jdn`+ZIka!BOjE*-6H-q@Bi1#?<|dfIppma$#JK=c-HvTE9>Se +zdsQyx-*~L*ldjd8Q37jO`keKStj6}tZ?)5CEzSr>?q1w9Lo>tyr;YV(b9O>pc_{6rSO?Om3;ko$m=-Bq7=XD8ijrg%k +zbNh;Owzmr&s_H&;NN9-KSg(|8z0d5M7k{>=W=g>L6ZQOTkIs8yd2QkJ1Lxl!>Tem{ +z*KMrnoY`GwUwd_D%84jE!%!?dnTt`np}Bji397+Qud8Xt~*|Tyk^f% +zXCHh0+|uue@r&3!7v7#WGxF``GJHu}6}zX#Zx(~~KxZG{nl9P3R9s9dIJDEBJ)UIo_CHSyo<8Z@EOFnV9 +zgz?;+BaWq>+Fdz{?6ruu +zI$K+o7isL?y6;r`_~?#)YW^`RB5OP4`Z0 +zp8EbtA6ZE4#usaD44i6T&2GD$?cDb}U-$1Y=47X^N^Z3^T_d$zFCEhyy{ApzJqOm; +zaNS*ZhU(07t?ynRb-{SBTjyMd($aF?KG5>)Ic|^7 +z%Qf%DyuWrg?8wuW&-+{2bdQ?mFjC`-%sw2F{p+pHS3K|EzkE6A*8R?h+r+M^=2acT+Gfo_F&74qgdc{EHez6Pl +z6BqZldKTL#E@NBjUBAOxo$~L;$In|ezo&JNMShDHgnN(5d*}H!e(T$u9j-fU+SNZ8 +z*17+@f-C!`#lE;1`7*b0qV;8$1f>fy?HJjHC8xDh>&&^|Q>k2n=1$wayS3~>JqCIB +z1*-0y+I!Wrscp(Ct@T%P3esP1=yLbvu>mgDy?c)D>esqsxdg*)wiEVg*m1>{dv;uEc&u%Uwmb6td`njcMecyMT +zGW@H=<^(tlaI4e3!#Ynml6YY +z5;IC`WyWc52t1#an-RP7^iR(pg;#dd>E2u`D`rlk!CmwmudT3;_gy$Iz)~q|hEli8 +zr`~xT>Q8+dvu{X~OBy-}SNEi^v5q$~9b2vP!Uyg2n(WO=wr-?hG=5xl$FyWCZ^uq1 +zjbw4rp_K#QijT~k9;rz!coJ)WVZX8Aqre8alOTl{(^t^6c7`)OcXpM2~4&6iMFKT$$S_i+bGfigM +ztXhz-y34?v^8+SUbzBf{)5E86V(OMdW>0N$`o1oBocZ`^uh+iw!e0;UntEP!x{~Gl +zyLK1b)Nicf7}#~bZ;!JreH+JJec^a^&BZ5c{c_`b?KWJY(y8!&toJjeoFNNzje1^h +zYdBRUN^|pD3zLv;X>rz#R=xJg8JyOjvPH%8t%ZNRL2mq}d-Hdd +zzLnM>Zb{D@`!j|#*=rG*AJMnIk8y13wW)ip< +zr_c9J$$b~I|h0g)lHW@v<_O75)u3Ul}9y`*}tVU +z4aU9c?CG8}%d2->_O<~=RosV_2~?ip5HL0R-R*LvKAM;FqSn<5EMsE|3&-?~A8pSx +z9lyWI#?&Pa0sGTV)V<|4e(Ldw(S`2zlrERh^UWKpN^SZo +zmkIRMDCVo7xw!ZHM;6cA{d$-*-e#?_@zRS&6I%^gICoZZuGTN^7Bl)d2CFW9*f_09 +z+>)MGt@jLe$k0o@ePqFdY+Z}1Q};SMo(T+cO$)NFIp25c>EW-@P1~m6xrXNag+2RrtzWsS){p58HzuDn +z=+>g!(U6ysp>upocrRYrLnFV;9&ekRY<<)9YUZZ0JdcX0i`yseeYe5-tg=d0+U=)R +z{nE1ax>WF%{j}J`#V%uqOv`Un*ZM}Y9ZwnLuASo*cWy&s;I#L738g1!n~ZebVA!Y4 +z#u>h6Gm@V_dG_Rsq-}_o_CgcmU;T$@cX3rZpX-uk^L*^0GxK{+Joz>$d8t>-v#cXS +zLtMhbj?A8V@_h6ohlPi=#!Tok+SJWmcbn^x@g_UQw7xdDUCS{hDT7YbE%6;)qiP|9RWh%KO_M-{3j8 +z`SIr!r{?G9M>H6`LwjD1%De;J@>|S^p7?l+F@{TKy+bXYBGVYQz(l@KxZnG~9cRubJxb|>-$c(tusIw#HEi`|B +z-uPW*lgYuZR}N^qo28WP9-?2Tw&CbHhNENV?$NSYJUaD`|Dg*7`x9&}%(M;{_AH8x +zT-tN7&4mWC)OG${Q$m~TUV3x%>h3`wQD4(q_xbHr9!<;Lvj;mCTLXHSLoP +z7Yz3*|L{z6>y(SV7wwyW(MtJfuG+1|)mqiF)a@2CuK6pUs*A%Step4RZ+!gzb>--t +zDSnI6r`ugQ&J63+YX&jnS6?p^=xc0kXnU!$|KbM+=3lyU +z(D%}L(qX2-w%>|#k1peP?bP!g*Rqpq;M$yUQ-8<7(`RJux*7TG!g!O%9vzcI +z-`sq^^xeb6pw=4}Uzl~f)C12QV|qLeKUCMfXHvyEkr9u(&dqz6KFv+jr2Nj_3!HT) +z&G4I&ko)VRlpjX6cx|n`=T&rp|6T9X`A0f;ban0+aWX7WgL8857hNedWUF)6gC(-blf#&@{9Ve{;mhV(=LvwGu~t2v_*%;wAxVlej2La`Kdl;mA4@ +z_3Mu_eEI6v9j5)Z&Ye)*xzgOnS7s)wEl-JEvOiL*<=(|lkM+=Mo0u0CVKH*v*=9Dj +zu@Qj&-W!G~?*ZPh= +z;XO0TCFoAv9qqIttY^mSY-juUbqB2$##=4*YFE61i(Lo*%o`f@FShl|Y@T6a;kWpH +z&+tkK(JrOsX7G5bZzGB@3-^E>1ho+mT +z${uKETUw{g?-_Hk{i{gjd6`QFyni2&7@yQxLq*jncjImE*g>av8s+ZVr(3qX&gA5w +zW@l3(-1ZgEyx1t${n#oOtAw#VmvpUPIp*;@qmg}d5>DQ#5%IPlc$w^coBI1hItLsW +z(Bo43UrW2+SUe@~ZKy0`aM}~qS9LDlyQDO=i~s!bsoNs-*1J5inp&-L)s2CDUgeIp +zm{OsH^H$plE?WNS+r4e)w7D?0YkhasO8!l(4y@BWZulZVd5*=R`K5b=+FaCly#4h^ +z{Q{#*zmi%EStMPQR43UdJ;JjGx`|+KF{C%h%mBEMM>P>9{7zz+aZo(%Hpxh +zR2`3>w)AK;fZ6Hy>g~oEFGykW=omi@Wkl}7am<~ +zpF2%ivyu4#jSY((lTzPP4^q>y4-8z(C +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 +zjqek!8M5E8Ww%}Z +zJh!*D?mBQpy`AgF>?#%Mv2sS;hF*~&mnWC(vd{TRuQ_}AzByd$&dpJMN?W;j%}TpD +zV`}-4-QPXbsN*)P=77N`&bSQGx%E>Cr@NE&I@PUMY2+~T^L^{ZnKjw%RIk~>U7`2P +zuOA+t@}k#|<%aJoS-E}0tNEAXJbNc4RlGjUW?18O4YeW;X^ahVtLaq1Jv?!4vp&76 +zlpUz&Rq3Jrii5kC`re$>G4t3ljqxK#RO~YH-RvrRCaozyNU!~&>tUx1_w+6~+T9?! +z-&5nmO$HAbxuxN_ZpD7_>YMV@iME%!)n0x)`EBHdlq1jjYTl1;Uw6y9mSH8$rY!Y( +zv#g89m2pS)jDBlPv~Rj+MDC^&w}K+7n_TQRt{}v8|1p<+ncZ!Mc{V)$*89=pYR|_E +zHs2OLN4;C*qb-m0cjp{UBW_K;G#*Yj1T_1R?o3HQntoOEq +zts7+Z3+vn@;^eGj*^Sn3@A^~Hw%HvkH|XcT!}`dCagRpaS^SGv_>lJ3cl}s<#K2O; +z?2?MP>Opg?oc2&6e#ZQ!9Bp8^!K0p-uvOb@BNa=WS%^8 +z=A5(F*=y~!&&xQ852g%b*J=w6PueTpFKKRO(4I=AL~TW!ep*!B^qzn2z<%~Z>=zAa +zsZ{gjZw&t_*6#-nco&yvz>iI1o_Ps*rSr_j)1>aMo!Pu`&U#lxJA088760p_4=^@K +zX|(9yUaG>d=%N_Kw)?q`bkZ%LPwj~M)~ltKLG7+s;K0Pb<6ist&Z`koxU`?hHlA@o +zmVA`Mn=Xmg~e>}FE$7;Z)q^vud36ApVxnF*x +zkZX?iAW_seYP?0{AP38K={PBTXH6z?@4Zypa2>!H8RukAS%JHyux-MWJ+*Ok{K>>W +z9K_=YSULzy?v8w=MqvBg1JXtJKdH<#Q%_7l5LZzUn)x_PE$LiD;dsP_p574*>B +zMrnVeTIsb$??vA+dXWNfAGQZQ_AI1`ATVebNcGHFHGro@p_Mzwn{Gq*+`UHXL3C>vmYeak +z@$D4w;M**~FhdZ;#O1;Ha{8GeN>q$QAhgyHQP^IobDI$64n{K8)Qz5N!LI~eB| +zi5i#9DOiyR$R3Ef{j(N8gI5dclObk)FNfRhI}+?tH#{E(lDcAkU0lrcHeDs8<#y3q +zjt}?R`8n1a?QlL=enh%Vc~YKUo{N{6yY^QeR_rIRfnITPsI0s*ldE8`%)&{di=9rD +zxv&rPL%Fd3nhTcH3w-WCv9OH)GvmJjDj9F_F%{(49y +zLp7#rFhZ>)mha~{-e7mfeBy^A*HVfG9&Yw}l+Y_acHHJdROPoHbz8%Mu~1S2BF1h? +z0~xyPmA2%)RX7gP!;X@EUA}%DW1!V`PFZpb+h4r_Xn%l_j)jwDXBPv4^SrIxU>~V0 +z|Dl9t>!i-}J>Oog9p(dAW5&_^?K!69_r4}?Z$)JuHsA$_JkBqMG7Pp@sPhCol9vLMIrD%cWD7g%xL=?Z$Ob;7m{s7kj1-%YAwpH+gL +z37x+F!CTqRvRGlI;M*9K@H8Em-H^4o+>m`Xxq;p^lAg8oqLDq=Fq4D*X7`?*d-~>r +z#Y;Z71zS2xF(AiW?N;*e7kAF)kaqc|fT4UxTv)yjPA^HOi7WdikBhhi;TE>^Rw#tg +zMdQLqxe?R0CMygTe!hYYKzrc&*I2}UNF%k=f}xAOiILaB` +zd`!C2U8^ua>1i*q?@QqukD&)5el(j|^S@>>QMzb~?T=0(s6c-qWf^qw!Iv=_l-Okz +z6T1H77psHSNkS3@55KG|!IpZLDYfWNA=)oYh}zAXlzpSy{rP{ym1%kKuwNcbYGtGz +zBEfLUj2HA?l(gJ1ut9Cmx+3YeweLa_(d;WPU;;)@3V?dBIu;<_)s<@|1CL+xmxW=bmvfDlBTvK;78DqLEudN^olP~ +z)HMsw+W9P&7yf?K?Da9Yj~mDy*bV~9FXzAE>vQ0A{z^wm-5iPEXz0JD8;$OFMS&TL +zrG!Uc7l}VRhxjRsO;a~;-yQHAYwZ#Q^k!g?2n1b10W6-tyhvD5hfirSOw?IQql0Os +zmnr{Mu#Dm0q;?;|%c0mH{VTn^r!j7E2{Vi1a|-ee0eu}ijSU$NE8M__$~2gKwvd)i +zrinA4_S>hb_sMvH`BOhlN(dDfLS#GQWNmD50~@kzi(t$Dd#jWD>?!iM!L;@r*YDXpBVBWlJH8>Xoe +zr5b#JZZ$&{9PU6i1)X;v9}ODWb;syCDLoqZ +zY%=K^2%?m}UYA_PaQEUBp8f3Cb2wn77t;O@W5}j#s^Bcp?-+Z!0bh6dP4MH?;XC+_D6<_K#bU6e +z+TRA)v<0$Sk10Cf6j+ap{asVo&}I)Vw^Y`EXTQ&}c@PPo8&UR^E%s^wLc`MV|8^0% +zd^RrMNEWOL$3}X5CJrKz9)+9<8N2w5`M%&Db>_`XjUE)ZKAEA14|<-Q-Nn>Mq#%r4 +z$lGj=*Q-3GDkScHocS*)_P)tws9UU%1FX1vJ+w!h`bx2`XYRdXF^U}~5RV&n9k_6L +z0l4ayoi;w(=K!3_t*Y%+i89Z!y0t7>e^w8x<8^Z!;d^AuJ#*B^J#$RSJ?l1%8cEh(FaX2MD +zSB7CD(hX@&cMf|tUH<|p+JWnlJ4w9wU{ooU4w)*RjV;_QI0J5cTzF;q>>s48|1OI| +z@683&yB_~qOZ9%*YxFvZZp{sZz)#erMAgvbp6_g*2lq>UBzNH4v|lcnbV#K`HfT($ +z1ktVS+2@yXK6v?RVZ)0C&Ca2XO<$6El|HgdI?3dlaP0vtid@3ChArBOD@vF8=x(lLm`1||6q3iKPLl$CJ*;LFC +z(D{W*!#_D^R|1GZ-^!)Vg*#Du5qtd64>MKEZUcv{Yudc11Z7bbH719`g}S?Y4%2_- +zq)>HbNjD^Led)gQTqX5RF19%kTe$nsVj+X=i7|XZT-06!fh}#I=Og~|O4!y?_aFW& +z3N`>MMu^2~Jben^e2mr%>#{nKATG>R$E6<#rf>JZ^d;nX3A^*;e}mh7_z_%EAITLC +zxive^%ON$tHU2OP9x@=OI=mX+Q^_ +zYTx;xajs4bIu3c^BmmYRpxSrhwCHXgEkF27{Jncg^}SifLF_9MLKGJ!INn6aF$SykjAVBn@xw431X)W=IBEnAvTq +zQIaIK6nup>)t3kMv#HxsKn=_`{V9;taySo6YizBD3wbXZO=_%YE`}OdjA~ykrl6h~ +zEGA8~lplytV$CGAT3T7qiaud}C#lO@1_Hu%tifp52bD)Zz>hwVGqzMLWa{hEkg$d) +z%~sEZ+dISY8e%d1rCP{sGn>?!M;ZnR70W^!E045BF|2B>N%ic7H`{XNQERl*m;mz$U!NQ|2V)C&51TG@CE8Q}UJwwm7lBXv20}Fqr%a!1wRJ#k +zjfA@?=j9sJyyxqGFRWaF7x-xZR^v%}+Tq+V+_G^l3tgjXcb(R6UWt^CgsN>k$A|hl +zL`aWlcd#DjVD7RCUTyTgP84|_L8llNs;E5kuE5nNY7GilW5-#&aIe95zhImWlv~aq +zi;d`ri{Nmk8UGp)(!k=qTeR%sS61TO5ZqOCip=#3xJ~nsV)JLb_4$*6LXr};(~MsV +z_kYrh{nJL +zQ9uC*T`Y8c`iyDQul~&LU&tAOgXq=@_z~p~lG~{H4kS9)#g2c(`MK^K{h>tH6n#s| +z{q3TF^7Kk*!*7%EkH?F|h&xh903*bwgEwfD$0&h(`9`J0vihik7o=-Rye~&2Nm_rb +zGWW6UtK-2d`1?Myr*2*cS@QnP=z+qiFqjtm1gMXQI4?YuG~D};bogmDiMvEc8iwCD +zcE`_wg|!1O?&Qjr4Q+mu@O@!){(#Dl*w@?cjSV!0T9ej8*O%Ug&zx|>TaS+ac%|M^ +z_1gVe32jggo7Fo1UNFIjeGQTaWTWSaC@Pzdo7ElPcGt6k6vxf3Mpr0-r1g<_c=``T +zl<@aGW-d?zk6{L1xfMy)ZcD#OBw&L9XIw`PxBCr4PUA_bd#RX+a7UaoW-N3P<`=A^ +za?|n^fb5!x2$x6! +zgB+EsP7zrYKQCtX*63DO|jxVOm;kv}0kVH|PzZBl(lF*=hPEMbh1=!fpgA`TY4_K8S8@ +zNldo!UE6gz`hO$yS$sj`9%qLt+VoK%vg7V@&je_$G+OU1A@;}X==6l9$8nsk8sp%} +zqd56_KH=+|lc)6$bJ^wX^5w0!FW;d@N-E(LzwuG0?_jQ?j}VqtBuY;D>8ZN?b5Kqv +z#Ge5te%sR(c05DjzLCYcI%ZUV|$IqS#borr1;l2Ip#y`=^|nFHA((+ +zWIsUKTnGtm!nb@BxNzPLCKsa>!Y7z*n9}fM_ibigVPgk +zv`qg4!p$Z9;v?4oXt@VuL$9r1!JSizHWuZXNEt-mL4Go+&Nh1LEsghIWZQp%gX|wA +zD|^flP*Tvh=_T{&T({>$iM&}^LD-BjFM>)fL +zhaLXIa9CV{Y4j~U{Ig%05QlMs)9*0Vw<*yj@qhz4;?J?6OyS}eL~7A`yfs>sGRN!P +z0TATG=GyWvM(~p19HDd2@}fox=AWDL_WT8t(N4s$HFR;ZTZn07SnnxYZC;9`Dj@`R2{=*~_OKGf- +zbx`!(pDFoeGX%(TQTmWTX8TA|MIi(fXHZ}o-D;Vc0(8s;-!f5QocZ-mnM(j>$btfv +z7xys#9nZ0>Us!fiZbisCD(9M4#4p|j;YE9g^9ay5YpgVI+BnKB$igMBhnogLSF*8m +zu{i{P^oz$vs+RZbqx-`eJCE#N(Fcq;IL11Ox4pOipVVucRUU+(3_allT@^VawplU$ +z+%yBO)+U9oOc6%(!t~STzPycH*OD2j%8Eoi3oGvR1tMsfCRg4Ai-&jOPx$`1Bf5eO +zoImE{uQQOp{xw4h +z?)&+HaS(KMK(ME2_JqhjT)eB{NH{w+ym8cV!7;kBdE?E1B*b}r7qw6y_M3nehi?X2 +z-3>FUP-yTP|HW6E&yV;wYC!5;G@GH7qYn@SJ9VbN^&ruAj2V23g`5>)0m`CW>fKbA +ztDDdazG2N+co<`1sFL#gYnGC~`|Hr+k~M!NqSZU3GP+F%%Vlo9!*6lZbaZ;P@QI=% +z<&XvfRh!)-5)S|s|{ZT`{h%8IKh>S;}$gGhuCsaJ{tqvW%)ToG{J6b}*n1f-? +z4k~->TgUx37hr#F^nCgyZ`qEZagNH&OW?O^)l +z)d!p?WN2e&+#S!K?DrVH;`zK?4HI8Yo<%j*8@{_T`ik1)MyI=IBw}%{jIkhu6Cgu> +zGY47F)d*7>uwI>>B|pvew=h>chV*gM{$jG(z`k +zsht_y5D$S`=q_znM0M**-OU&O8GSUuBIrJHxd)a1^*OzLg&LfsToBz_DEmS-;0Nf6 +zFP1J=;g{veDJ%vm{P6h>GSr%~&XC_p1l6Fq`ZjeaWR57LznY-i`|udUIC~Pdty9l< +zz37@l@cj%2sn}a)8%1>x3c_{-1ZDP?xoorIE{p`b&`@VY%GNnE9ogUpHdw0mg(M}+ +z^T7p(bAL^&t!m#YQex08ShTYeH~Jat&@5>OX^)i7clh0j)^03@)BUhhdwa4;W68#=3#j)e>&syX0$LRJ#L<-0+V4t)$HE^9j3g0VnJT5 +z^2v+oSbYxC!9}Lx-Pl~JVq)K1yN%emhKu(HpQpRH3&2G@=RK!MFU%>$)yQzUZV4#I +z>-QRd0kDt=Hv-LI8N+Fl8HeL2$)*5MlM_H76G1ywAJ8GH8b0mt@PV(7p4j4RC~0`} +zK(Nm*e|^_zXmXd;e$sQ|rVR#+(xn{mp4z}XT2KIEP|XA>2J{~B$1^uXLpcK^-!8t# +zo|!;zdmUp8`@l1dY{t# +zxd&o;lBVFG&N!z>j2&bg;A%G-$@1^LnmvPi`EL~ZuZ}H#4424C +zYO6g+UOZL!+44wV>$u6T4JuA8J;~h|Pb==YT_|)`WKWK*fG4f=CVAe7GB>F)1{1Yt +z=q!7@s>BWj^vP~`gG$id?tJU;q1uf{I<0SF`3J0}A_hVmR!nw%w7Tw`v&~W4XJSuK +z^0D2-yHRXWqIc6r%X<4J?+gB?GaMJGUD-jBQFg%T=S$2BA1#{tGo>9P5U-mQ9%lQ{ +znbK-wwnn5QC_8E09bq-hwuvvJ#qWj0G>DP>c6QlmrH$JWx2E_-|* +zYb$F2>VWc^u1DX^OH_-SBi8AK=|?|CX>BYMBU7AGQe8jtqaZyC>x3ty$vf5@lx;5dWm{H&|wJn&48dDTRxwibzqh3Z<}MBHx50NlaKXV_To6+%by11T)zWnbZ(_ +zzeU8B>|^;EhIN7%&>1Wjs?)i7VjJTgH~lJVnZ%@z1k!P*#nNm{36IaB0FAqxUb!-+ +zXO^Fz-JHUSv@ruL5!AdKU?zJE3UkKlT55P|huJIl0ivm(fQ|`O#oJqT=qK3vz5 +zd`+301Xr|X<@V~|kzvEfto=2qgJI)EWyyybe-`ZB&cI;QQT1d4vs(T_FR!*2KmZ68 +zrcG~57sS7MWs6lUHl6loz1}{=G-01!iH0bLbb4V>fu~(bPGeNF_OUz8GRBk@=c*Cz +zt%;a-XKksld2IF3u9i3O^H*o`!TYZ0lfChz +z&7;!7hoz+E?1v~lln=JuAJ}`{q`;5hrdVr#D|ka+KjkWC$hz*AYrT(-O5&z)KM@}n +zs4RKyhg8q)yAm#vB|jJ5gpk +z=%}i(V+RnH1qqJ`Zs*MNAG-XW~^slxGiqw|4tm2os-g5$tvqW79Io6)2vR6`DPoJn#UgqW>_=PskOOyTWJ~|rtyx| +zxr_KsYwV$(N$kuaOvz;0Y63c9)#YFETF7xJHb%E!96fO}U)sksBEvGr$bA!7$G_v? +zMpOhKGd3n39hA*D8#^c2_xN7gd(P(2sPmJXP(0VqYnr`u;8Sfo;Ev#nU9gE57X64z +zh!Hr%4wRrTR?02@Q48>9-JMO(>wUiJRBH_T`HgQLR^M9l8FkZ-ml5nc%=u)j?3A$< +z@TyPm1&Y^OwDfBkwgBGK*%ErRT`~3^wY?A9!%TS7;GVo1u$waPho6!Z%L6ifT9w6-)P)+s`~ah+KKH +zu~aB#fcv2~OS7A@C+cPJ&He7jmb3dDnYfe_pDV3j(&hLgZnsQBls(JE`0CdavU^U;s* +zW(v^k`kIHVYvw60mmT`__(N%{dMmvxJSs*M1HY6d9Q?J(=#BQv5*r%8ozwFj@5zvg +z9P+|X*?vR%jZ0D7UD)zqAQysVJj8nx70LnsBg0X!7R$!cx+|b&2NEp?+z@)R!6L0q +z>@M%bUqD_1|Lht3Ak5E|P@mO1@`NZJ@Q)>%DV@JRZjJ6jwh*#v;O11bMXbhQXdg +zmVt36tk9L)RfgQDbXq;}x2|hBX}|Zw58iMU9!n{Cz+Jz7LsyCI6EZP6`SO0asthK9oQZ +z@93{MX%|QfIn^7fbsv9`|3}6o!e*L8HhK80tfWzV=Dq}5xI2bRy}1yF$Ea*et?-Ms +z;PCQJ76XsEZK@wlezX|&VGq)W=v_XR+83WmD*Fy4v{UW7moS0`%y)IlU%!4=GEJR% +zLCc1IeIjvX6vG_QFt&l&KA@iAXvGN!44X-O6#UkG>%ucwpZCo(nteZ8{{dTG5}xx= +zkwdt~k(?KYk*;pEga-*&zQ^|Y91p@`P0j^#FjBkdw#>q-;$t+EhVnEr_V7-Fl+U!mVU5c(=8+Lgbr%XSsXgD^8 +zsvkf9MpaVp1yTHgUt96f#To?P888z$40W)GYXLeEQ=B4H8F>l$!!RRI#6T|%7NWOo +z7YM5GA_tc|Rl+MX_==x)y31J(`p>L!o171xYvJc0g`BVRwL!f$>)0wLVwD-drj>Ht%t%d9Z4<_*t{tpY4aaQNlqaJx6THA2ou80Y9v+PCUP$om-v +z4$_$x2}-Tg5p*4e@1i*TN^-c}YNp^Hr;}W)HQ{v|bz*Ze5{?AnfZ!D&29G_#~OAEd1gWT~9{r +zsvT$D_dxp>6k6r01%m)c?$WzR=CKD{EU8c6FSc7o;j#?-&R?ICUU|LYU|z-9$45!1 +zt1BTep7cB{;!4F3?Xx{$@*u)(nekV_G7EmJ%swASF8~nfu=s-(Io?AK@OKkZ$^;<` +zKUQpXX>6r2QVeK$P!a5j*#toe9D^RNRLGE?SwS1vLCDI?>OB97FrhQh2jz5cBl=M) +z|NMu_Vkcl3yO>%h$<;t`&C`mLy;N*K`v+L=$1U|gpUEc5wR^1WLe5bP4nTTr5V=o8 +zi>67sd*Qy1i1i;hY|#Su;i-arPlEvP1 +z^O8)PYS#D&*xcpy+!oCE1n;Ev^VA%%I1PV#&@dH$Rs1(Y?|@ES@mYG4jG_1$J4~DT +zM51E6&dVC@@fSj~VB5r`vnWdMKtga4!wE`>6HpEYbW5Y~XvkqEt)Pu=I1DBS{r +zGkJ~A=R$ta?i0&w|9H*l=?^1X^z*|wQt_cURL(IZ=msS2AO_)@4(G?8pr=vn;nF1S +zcfa;*YGzIlD;?)h^2J_=QalBvOE@|bDaFuEy8L0|QOk9-NT{C1NdMl367R4Vy~Jd& +z38CdXL!}&3Un0bSDJ_3IJ~M{7)|9C6{N~QFd_Rs)-krFMuJsC2=xg*~KWlcvmsfG@ +zhm$oYWJCOMkpA2p?O1_{82dX1Q9*b{#cP_1#xc7QA@}X8IEPOKvwF4TL$?3UL7&TV +z{t3JHkzRCuJ@Y>URFV8@9)oJub@RVk!Yb2PLwx_X;)t+!#F-T6%fDb}s(5QM@Qjr1 +zfnW=}ofz8nL1*9>k;}#v0qkg^|IuIVuVB~03Xc7=If89hxKY>xwIa{=Jh*&$!dK~c +z=#29zZF-ify;W4I5?^0Tog7U@B>nn*t9iKGO6`X)7r-cY-L80uwp7D7{Bz(?>L@%S +z!>QXrwACmqGOR&z1M>sFugT_yZOP%XNHq4rM{9?gs~_1sP7W3A>>W%l-}3@xrYVlZTfrbhl?mAv5W!M~$T< +zR}c9R3FD#BW#`+cwBB~zwx>c$1Ie?7-F3`W{jaSutTUzK@|DCFidP}q9Cv;iKw>8) +z%%Qx~Kk<^y|8KLmm5J5=a(jcT0=o`cQ&#(4-f7KDjokvpBwznOEZR~zmeDvS$-0f`r~F0Vmqrnx11lT0KOE?z2zZ=JpX1?$`n=bmyG +zc`fceX1Ko%^Yp@T1#GC`#Pj+Km^d}AHuU;L5IPLGl|So73|8Gtl02?)hx$!<$KTFtdx|aM0|~bCC>RO +z)j|I0$ZTE)%^lSfuO9QrL!Ope$5yZ)!3EDu{>ra_8}xeDX%~8ttq2j@PWQwl|+ +zQ+>vbYI9`il5ns4=jm7b25dNZt-5iTRK8jNE+G%iySQ2yXgN!lmDvg^IT&uU?|Xhj +zGD=e_RU9#;qz{Qij<-sAJ~#7Qe>uyru%&jE(qftPTz2>X=+Avw#|$l}S{f{<_i(5C +zkWlK;$n~-?PuASxOb%%EuW|Ba=fD1iiG?9Iwu}VA{%`L{dILfU)Cf%?&0UWB_)6b) +z?`^UL6(ngZH1VWK$k({+K$O*45gyg~Za;vt_T$B@M~dk)Wjsr&isN1oABXTO9b9jY@WV%-NtpQ)sVyK&1}78j4m(~)K6>8Lc+78UN#imKFvqm3E6ZI=df29*|H(_v)XENxp +zD2Ch_U|hkpU4zw0YJ;Q1z)~-$1u@I1UA)>pIktIu)s7bGDcA~@QOA)ePLY;l#j+Gj +zez=p#n3b&=7{gO$DVU(BYJ3KG5}iv{UZG29?QU~v8gGfcWSw?>+fed*?0{ZeM?1&xBG;3()ZtWd;#aT4 +zD#+D~WyX7U;*j`VWUqbIm<<##MAe2#)TlVc-FLcKQBHgDain0!&@$1>Si?1+A&fuk +zNA(=G!!G;2uozC`Xdad=em~IY3rKf#WFlvvgK}x`o1`Y<7n}EG@0*KM(;->OB29w5 +z^GlKRSbJNUDW@?-VYL+Xqo$M71sDAZr^&sN+b3ea{7UKy>J^?pMJ#<-|-%CJdQzx6%QxxYWf0^O3xArMZH*D|*H*M_p4AEBPPM3cHhskK_C9 +zvh)A$G%iC3k0FGApji<&Uy<2@o)!mWOE4paxS!akz{aod>plz5jP-urO|emQ43=k3 +z;Pb|KEhr8eyQG(pk&wW*5UT!3t=L~|Y +zOu}ey9p`>iyws90SDJi!s~bcNJj|%!4|6;CQ>1BC8aupSv-jTLv^4YrN62BJadh4& +zfvz<(;nr8-3xVw6|60!n>M)@>zsCOCty^iQkzM&X1lyIUbfU?3 +zd802jGoh;~BxJ_rb_5vHTxUI3=>H|(`LTjM6Q_pu+n*M>T(M7b9=YKoW{cP~a_K}? +z6U?>w#hQ2M&&1w@)*k}MuiEu_R(5kB7Qus?7^2@8BEZR3NnRzfPgjD=PCqA+ILEK% +zVHQp_)8+hd#m>tj5oCqG#-Ssp_#N~@)hwqo^tvx~C46TG2D=Vc%2cgj=6h|6AKw+Y509kz`#ZHQmW`_$1zSj@ZeB +z$EqjL<-y<-y#;+)*U2=xmOixm>zklXr!f)j4|(HrV674F4i_4X+$qQq4t+sNC{MU8 +ze@sCHaKrH9H`bNj?Jg)$M4Pj=ajSHU(@_g!%fC+h_JU3#=pEo{M@2yeg7BpmrcbeG +ze*p@e66*;3O_3JT8F@d~2`!PEC}$y@sNJUZVwI_$abg +z7``)XM(E}xc)@gg>x64K6pUn$y5qyv9|~+K1!ArFnS)1=o-$z|zcoIL77^fvdSX(? +zis*r*CiNheDd{l;hC%C2)IGcP7I-!xZrlYBBF@d4*dKhS#lqq!Kyj*HUzE +zjd>c_u$)GEvF-ox48x4PbNx +zm>h!@iC(e?n(zbt3v{GoW!pAnE>Y%UjI$!rd)IZh&-&i422M^A;t#6 +zpqh;B2g)l{HFF>snPhxK3{M>}J9lfcwP96MUJ+$wZg}{f4eApm?*0zMTH_ch1Pi@c +zVEotZ(c%dd)Tbl~gx_c@?%$O!|7MaWW{wLb4gUZSmUv*^k%GU6o7K2f=ogdXwhRX& +zpQ~L{1ubmJ7+B*5HvD;_tvIOhpxOyoai8Cb|74(rF+uefsIpZ^_?yX^z-ekncEOD` +z&wDZN6aWzq8yjPPQ&s~G>S#}e$z4r9?O^hUGG(Gjb5Mx3V%iUC>EEc0fOn(ek~0Ue +zV8L;oJU{)52)x$_FbCFV)irxva|g{UybKI;X;+ii#4RT=0nTz|I#?$7r064!F-zTMOfkCl?HF5!xrj-fiZxlv5A? +zFc?hF>#=7$i6jXFWoVG`bA3(fz)@A~`uUt%heC?JkG>p_k(|2v8$LAHP&ZlN7!pmX +z?jDn$orguNuO3n+RACz=8|ui!iE74SU}YW?Kfr>|beYj_g}|&a*f|}a(CrG^xRRi> +z9eR`;F|79%*i||t9s^2u2JCwPEtf +z*qiX%J!cPO(bWP@><=MAQH}8P)N5X4dEmJxe&Upn^Y^=ELIJAFipncKta*RkV|3o( +zpXqIV7D8LA5C9&|dn%Ym@6(6&So?L$T1GSdyyf7?+o7Y=VPQZ5x=VmqYh0y8u=n?s +zC8AUWVVc9m40tiHqz)q0zSef3c~BoVabAiCmP-26A7~xRKhE3 +zPG1z%;n%)bJBGk~XxTBKU3%|;`H-n1_-L1&_YOzGuA~wk@(UjOPod}ZK|WPts8v4u +z(A5-K?e$oa{$Q}4Lnl)}!@}}&l2(ZBkG$6xS%dO^ePOgU{#2L%OX#wenm-iKmDz+& +z)x?R7<<}LAY-?_{Q9UKXIc*Ci4d<->imwmi;(sf6U#lAfg%^K{DPv&|Y@PZgfAm{I +z=izcqrfrH80~(b^3W=9G)0r@#mq+6bR((`fUQuIZzK!Ax0`;j8=LLk4h7%Yogq*AI +zokiH(+Gd6|hpNh{D4RaIYWE$GXV#m;9`>EwrezjBu`(BRXdw8gnV%*$??h8N+5G?Y?>i6vyV#k*q`sYvZICQ0t5twEYF|d2Q63a!c9vLAaFg +z7U01xz7mR0e#KxGm&Xf|UQtu5SuG#SO`cPSjU{T3orT+;qm$W?jq +zhROb~rMBWeL3Z(NS*}R*n!13z=4t}DM=+je!kG5t&a+h+WfZW1Gm2pWcfM`!)coyq +zAy2nLV7*ZZyfQJuhRmy-kR{1r$5YtmU2&!|Cf0Y1gRQC=@K+D5Woc=I}F!M?*vxX&g%&IEpUVbQmz-H&2gE6JvjO=6QqSj1)R{0Le33owZf4$5((yZyzAQKQMYXb&*7>%!l|}P@ +ziKzB5Bmtim479)8cCqaxkb2{zGds%Xll(+#VJa3{V;8!p&MQDu>`?RWLY~)|bn}&k +zjA4GJOH88Q`mCTw48`?{RMAh#LgBeOPHQ$>pD((v-btR#?D|=bgLjag;=2qblv6%= +zUgn~4U44T`Iq8W{f)l=+W4^ncYJTU}!6og;Wss>7Zu?b9z_!0R9)}P6`eZ9t(8!YN +zfLDwsaR9Km61!J5D?yo1qK!rv1FHC)?z= +zM;^g?UD?2fugzBEHM{SW1&jYWrFe0U0C@0d|1bxry<$uFL$PtBA)cm_$VefIJLBhq +zAC&sN48ws*@cOP)JHNd>DG5Q1pP*6wl*R`-Of;#@0)*_%86KOLWd{u)OIe4spVcZSbouCgmqs( +z0$jqhwKT94(RbW`kw1vPL-zzr{ls_Qn{Udk3P(eFI76=E1ElAQh;Pq${Gukm{f+#& +zQ@d~M<&gEV&WpHBxbr9mF`O;D6<;a2AJJ)?{^_Bow}@)z3uDFf2goy8smCqjrZ|hM +z*3!!Ts--`6hX +zKl_ThU(0F#C0NcgM(D-+6W;mey|Ezqvyr_ooZijcAJq{4Xad8UkN=b=)qI3W#kj}0 +zobYQ|<37{;rxYmQ(69ZZUx9M})6>!05xUOEa;1>}@7s-3Q-3~Yb~@jNeUAA3OJ_ZM +zl?9*Vv6Tg1e-P(PQG_VRry5WlkI~-k-)~!zxwBU2qzVKx`XL{5Sao0f>#;!ws+(% +z4xS8WMX7l_!+52A(dKxXb)_xrU@7llK5X>Mrqz5s}bXM046w+vG5Tk}fq(Kcb? +zj*tcU{1eVtZGPoXiUWfpyf+hTTY6XfzX60u0M|E8`$|6P?n%PqWMSg-*0%^|IGXg* +zga+>k9gdeeuF~ubuV4WF;ew6L2i1guc`1yU7^J1e5|F!_jjLQr~=FW@2}?ipSL9%H&No3+uSI7 +z_dnVq;&@U5bzcT7-{XfQTz{xZ?v<{E#+4@Hd_T9hZGw&_1HxLM8U!`GAx?s%)on4A +zNiq*3H6INxKS7V5U7M{lxKHQy9L4F1qfNWp?HCIdgPb4#0*Q~$yeGSBFOtPzkM2Ba +z_bf|^>$Y`lIB?x5{f;d#bZ-7Ib$;AV>dPaSB$nJ4MmaC*&u8e+>_iR1o95Nsj@~g` +zOr)60L!zXV7U_+&V*Kogo`Ld1DWhmB_7=9ZBj>j6^K1)v=IclAHznMYBa2kLT0C6> +zlSWyw8qJmWEos5HkbOGs2rGyrc8X%C2;|K}@(mN55-h@!3gs4a_ +zks1;p5ikToAP`7G2uaRD=l!3rXRY($taX;ZPb^lR{p@{T_ul({uAMy1w|+@JFB0$d +zH()qm^lV%!)%wcj@9aOerS-xq0DT&t9yVV={2q6*_P+eHvX5g1)424ipU$oR5mXci +zzVYAH-!JU3^Fg<^&ErHn57s$1J|_-zthsKeX5EvK)l$56L+cs^FqhU-YkNWm{J-CzJH-SYF4xd`+7gZY&K(ouM~&J4Pu`Z4h@ynOF+Ee>s-=GX|GZd@ +zY9#UE|Iv!0ByXib+saH%+yb +z4{rJO=R0WDv4y@}JMA +zeti&bR>lcvmf4;ARqW9bAR5zWyEJDK@n81W6C7Li=nLy=Qh +z!6ato>dr1o$X$V7$|1=xF87P21ejMQFMXhy{?;BM^eHQIwc_1Z5}nyIdZB>-JSHy< +zEwbkhPHqIWzmH4Gp${`CoG0f69?fCOv1bk{&41~>v9;{~x5w-U|CN9t&cd6xX+?!S +z#h{lNqo#h_7j?nqvTo0HM;?zc-=Tk9z7+AaXFY!QV`wGss02_nj`0+*9`EsGy^jZH +z-Jo%=dqulY2ee~zIPuM8T!q~!^t|s@*?_S$~2870izIIyNJYUf+ddUs=$$O-1zjLh6No-vJI3wJT8swAD +z2cc4Ri9KCp4FaJHW*V`tUmGai>l;X;%lG|^J}1-wcr=G8-G}dCJUXinFv~-HosMy$ +zSzo8`Lta`n9kYF7YhP@IO1FF@tX!~t+vbrii71$C!iM|I@tRp7TQ=nB@_n8$^=3KxQ;R6cmV}rT +z?zbtX%D?VHduE~PrTNFFx@ +z;{T`qAbt7Sy@(4z)9Mw0)|v2R$dv|!>dz*%fmeEc(N#m))pYbd(f+D~^jYTdDjow~ +zhpUw4A8)5yCSz~oyt+EBx}&P4`Il%~7C_&greWX<-I2%98C&Aj|GS%9*K-OHr_Fb- +zrlX(B@V`cCXDk@hE~wOQzLDl9PIb*`a^L8V$@8y8oakxS?C6%}_P_fOEX}{hJTplQ +z7%|fQK01NdRQd9*;kYTea%q0zbeBLR*UmJ8E!jAF!GfC8A@YBsc_9(Uh3?NN*|Ob7 +zGT|XHmxkn*>$J+vz_x61WJ>71alBOLLAt|2#Tn3ER-LXbiEjhGR6)0VGzT|fWVg>! +zpHv^fhYqhiH6*{>^3Q$E^26~NTL9Pky|Uq_pgD^#y8zR-ZFvh{G&13*oFk7-2XP;U +z7E~W7EDixRyMOb793$!SsiB#$Ee}FX0c_&*p$ZWvdUD&}N8bJ4b;D~uBu-m!4!>1@B|4XlcMbdrvqmNkq`y{xgJ#R4hA>F8r +zlmUSmDu(kx?RjmtDiALR4>cF-dEB>g-ur$gTwTM0g!okSXrJavi@a^i)8sy`m4s)w +z-HuAkMwI!X-={<|x?oV!;XKG!E(rN~T=4%^PNtHV%w?ggrTH?4-6URx7kG3blQJ4Tv*%sY +z`d2-B0dNKw4&A>yu=`KLtt)Lu65V?)+iSdX +zJ^X&dd&qV%n#O3;1nv?XWcN*>LN7sg*I2;-VPB*UIC9Z&8HfHtQ +z{rc>^*^^UyU-*p>z~hMf;ru=IW5y4TslJwaUi|CrQ+FfM%}+;N{{7c~2zTzy2dMr2 +z>#;YVdoN!#Hwd^~dATyos#-^?ar~Ezs|HS$S6vOnfBA*Sf`V>nLLwv`e~;1S6L(-} +zH{%G4FNUxQ6%5(|0#t&GP8Aen&IFu3^=*b6Pg6tO%t=l!$qHPdILqDSHIlBYjnbe(p +zVO}i$Zbn7Yyp^I+2|*1wszo1))po_drOC8xd$&sj|895xz=V+6ub|0#>MP-XQAri6E3pfFFJUS7z8+w|aL9sze*W2EIc-bl&x>N-`P}dqJ}| +z=oOU5u)4F|79I!64NV$~AAT@DIBF)foy$>+vCOmb^DxPth8U_Dl`MHh85I%19Onr` +zc^TCS$MMukmI)yhzRAOrd_@~F@Oz+auQ$x3ib{>mgjxx{*4KQ{o1{BY_<@?kknYqE +zXwe57EZ)h0J>06223=PMx^dfg?;n5(sclDT+xPJUL8eJz_rtDHQjLvVRS%;t +z(%JAL^qxWQM*WBuy)?VLy08B6t*01lPgODz-NPz$aE$u$WpW&g6pa__O#mc$I30-A4TA$_6@c +z+{da&?IOHrKs3p=(|vM+BL*dCF0?K@J)Uc>+x@%vlUO~XV(IFZ^a6^ybG$(ZQ|bEB +z)uE-+zsYgBhkOR>nK&eq(f8XK<%j7t$dgyJTY1dnp9dvH5Qd7#lCcVSR?_(D!Q!Zq +ziX@|?OUH0Iv85@h#p`Qaf4#0^pAYr^#nN#}+GG*ht(qtL*T+^=wu+(0N^R^M$V|IL +z4}`D4!u~s2u#y|vFW;pyH&0LmQ(u1w#e+8HG%I4q3LNum3%g=ITNw%FO=xy{%rrk; +zVkow+;=|0sr-p?_6kx(y)lv7RW@}45R^~5+-Wa87JotkNwvzZ3W|cQPJer%nR|Df^kish#3YR +zK5gS?PoJx()eXD{&cTf63kW7xU1`zUKx#2Xl`2~+KlN@49_@dde{=MycR&+!_vVH` +z(n92N5^`pS@L>L^YXdH*@iBXLbK&BP34GI=R4LMNejV6GJHD-(dz?S`J`HcXhnvQJ +z0gdQB&TdZ!jpZqU4eN+4US4~|XeFUHWzm=J4x<(S{o_>slaT`Fg)eU@N8_){e4KMj +zs@2qW3e9?F*JXM<7F*UHzkd5*rde?LGYy0*3L6CM&xUPn8jtw2 +z*GKH$&!62QsWNX~OyVcfo5yG05%bieL))Me24L2M8>-WUV8&{G08KMAurb@YqjFz- +zLveXj9PZlM-vyhAhbvzub~1*@(TX-DWA +zJXaHhLvYtrL)hhP#I^dAtI;JheM2p%O)@`h(%e9l(UZrH6~(Ut?B(eqL`M$9PA_te +zC@M9b7UntO`Ye9jf~gzWi}#bIpMGLN(l*hoW7x +zV+v8vH|F3`zU$qyM~9XJhm9@;5_1!$ib*qNkCSt30;AR(@6)jAw~4@mU&(eCPu +zg^H`%6x1sak&!=$DaR>fGi3~RMB}N*s_7URp*A= +zH3}Lbvit>V3%!k^db|qV7C=U*!4{xV-!?X-HA)uj5mJ>zo968|bR`8Z@aXeJ^#bMw +zJHVk%{!+U;&-Nm>)Oy$P>_SSk|H4$;+NuV!i}k6Y9DFAV->2DvZXKB0i=5%MwV)~c +zLRX7-%Bf-pjDLFY6T4&9`|W3Gmnph18|EUh3s(dw2f#8a05G$PY&?szqCL@pGXEA+ +zFhv5Sy!v;q1lySFaTkds8s`<$y#i-dT)Ufy5xXD0g;5dZwm}TvSySGj +zqBdRFIVzkHYv%r8YxO#uq@5WW!kcJ2l)UD?0t#EtmJJ+i%3c63QNCS^K8&sQe3}<= +zo2%z;jx5y~Oq99no_8UsW0F1U5%c6XUi&ff0Y@jfh!a +zQm_}nS<%#^nC%tleUm(HzIB9I(0$IsyG0B9R#_;zUno-LFjmmz1Zrj58rYF39vT7F +z`yM{`=l&tR(fJ?9Wvd~{(534%kgJYQyF8TIsGL;GzYT)$qZ +ze~+HZ&?GfS+=cTH6(gqog((Y7Ldjn!@HUFdL*4GxI>#6rMcPAmMjL&Z?Pb)QWB_5L +z0x^WdxP|hBe3>?7RJTL(2+^+(MG9Aw?*Rk$k{x5yE9C +zc@4C5)m70`22-RFG%=;Z5iX;GWSUCd_&{%5PyA+t)xSBnJ%LHI5`m92Ve%m4b>D~# +zh0VWNLxbxnqey#=@J?S}X5(QJx7e$_ktz=wL1I^t+s3}kq%!Kl;Z0d~MX{`Z^4;zt +ziPB#EyA$S#_)BmItaf&n2sAyMC~oCTu|_Bf+E|nDW*h0#_gvB|W%jJGIYkJNB_fy* +z>&rZ_X6BxyX;V;XAQln+HTPTEdj#@`KGBwxd +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 +zvYgYXT9!=)QSu$s +zC}$<~YrnqUtJaewUr}L5l$$&6@^a-~Z?~h7U3WzO=!9XngP-T^-b*i{+rEmiv9r?% +z*=0M7!sTC3n^Fh?Ud_&&vS!muPJ_{c$G@*R{b$4d;?&f0W0o||nUrp@Ht +z#@Wc1F0Dlwt+7s-YeQs9s+g4CYL~?>Z1EZxByr(xg +zX;{)FdE9?09}ir=J6DbZSj^=(`7Qgq7KP*j@tV?ZIgqa%vB~=e_5s2uAS(dO2rFx +zS5>|vDLEQhw39}?E(%4NB-J`K!c(FpNn-6=`Tj*&t-;n+NzjhkZuS$y`v`sdNS&0#A}>*W~zRPucF{vccDlSn3w=n0g18cdPjnSG?sif46f{e9k%FLBC5FX93W$J=+|KvRC2KS{E6uE^69$ +zqP*7?-7ST!N_507p6;=o7;l%9&-Vf{2R_&zK8^|{Io4m*rf{V(;@dMH6u$rK#qG=7 +zwBhry0-m_#>~4P7VIlmpq^;4KRZuz}u_vzbn)rAAgqqsTmT@m1Gt2G~)w6P9>8#zY +z+dCIq9s4t^v#M5or=Wg+sAZp<-D4dhC}09DHm`^mg4)ix +z8`*)KS~`Q?n=hPmvsdYS&6JFLwW~>``}%(U+xqJe>B=?SALW&;J9Nhe0rY-1u)_RK +z6#mnDNCkGBs-BIpUknZObx7)VOgQk&ekktPR!W$V+4WC2jX=O-mTvlrS{1c6+F$y( +z0zM&k)T4I3IRu+t>1tXpbFtt)=d`|F93YI$>c8>Osz`|ad^i`Cb_D=tc#N}K3h#DN +z@|-p_G`U|3O#8vFP^dsl3xx&l;98uGo_Vk4=Qh8j)@gb}jBoyOg5kRQ`<0!Ce>635 +zW#Br~{9XCDn1k1It +z{N()P==tYGROOE3Ck_puL1RdV8>9|!evCGMR7Af0)BnCO +z_9u#;hgQcXxs!ZA +z;VNC45?acx({oz0ru$rM#J!LtutVd8^-a~Mal%80^Ic#4AJlpH3C6ZYnHYtkyMLc{ +zqH6do9$S|`Zf^ueI)yX3)(bB1`7BN3+qIS3YXpybkj{)YMG+C#&>Tf*V625%ev`4V +z_Z^7vX@n~@kv$V(&7o?}dCie;(x|TL!hSJCi6-1^H|1O +zy3{ahmiMlfn-v@iY6eW`funV2v+Z{`?ANi) +zF5vC?mBby(^ZAATn-K;n*mE+`2V?4p-X&n-@g-P1Yp)RHkN5zBdL17-S>ttl?5P4^ +zYN9~l1d2}IALM#|(BwVk=84yy-HgDuSzgHJUfl>3DOhSTXZY*2Jc(F)SIO7aFJBtB +z+F1Jo-KU1H>HjIYHdD6Me`DI?r#Yy~(OXd}@bKZDYUg^_qv8a$+E_|ul|)?YjMjpk +zXrxw%3HZ(AR`N-GBl8QYUPG(nHb%`!K1rDEzwv!v=)&GaBl-N!Ke_%6&|X&R$|gFc +z8N${(Wn@-SJKo?MpyLAjb4NYVaJ?rB>vN#j6fjxRQ;a>Q=fe9KI0qAknVTvhMa169 +z=Rq@fHW$Pg*6x)F?K__?;uP09db&H=f5q6=5W^ffISK9O!)IKSony6uk&At!#we)< +zgqnpN@tD82KnCPse{CNbAZh*+U>**_q5~b|S>E3NtUfc +zGAeq2Ln&aV>rvdcnXx8e$I}0K;TDLqFnAF+SJ~}6!kg$m#Jgt@G36XpDBHP~(&m!; +zz4lp?Sd4I&9OfZT+q=jeK4wC56R4G}OdTjoCRSTmtmiL+m +zH%!ept;g#sS=?}>BYhj&Jt_IW8m-?;Hy4CJZA0K$-ayBpBD?M2J1F7UYs1}(e&D{sW1@$t?C6}x@#REJZmZ^tvpi)BS8qNQ9tjZmZ+3=$s8PxXz+P}kvK +zM#y*9QJY~|x_f_B@bV6Ow}3vh?@sSf^)2{jJuA#Z@1uW`-8x8Qfuor7$B?bY$RHW7 +zAp7m^b;eN;E}!o~qLt&U2wMkF@w=hyU(@zCm`{;ZPEq7u>Nj(W{LR(6f$83Q7TWg) +z*MC@)x{ftqkeGLiDa57@mzWo%&Q2669;h3@?yPia{fB> +zvWqZCvdjKx;slj^=y_Y_E+}HeyB}tuXhj(Ct3$^KW*MF;#wZ8pc)15p$BLGJKZ

$ZUxkkN$abJ5< +z^k(3wZ{KK%>RReaiB^vD6pISrno5>|N2FTDJBL4~9Sj;;Z8vpE)Je#*eenZcWrq8Q +zwKq!Xny6FA7Pa)EP>$P$2@Q(Jg1o+I)`9Nps`LAbfj%?i;WHiKG?i;Zldn?lhpA8s +zbybLRml)gGlf5^FCWqC7HE)Ph-^Ogq`0r2=qoQ!{JnpB@eWpN}!(%H|wISi#LLK!F +zl~0n^yh_gBNfkc^_b!!%wpR%2Dvl=8dj)45u19g#M7{J)?GCtKBq!7?6j~ZXqI`@k +zyA4&(%IW5?!k9rsA7dMF*|HP0tG-inG0Oq+b^G-4;j+W(tN6O&yvN4DZ9T@7d{Gci +z4#jH<%@ZT7eNGFPZYm{&M=?LgyXB^O8%1d~Upsp4#Fz+ae_vHr^v(9_lXaNpXfi#l +zx#y^>fN!m};@#4+s=1Hr3Eure!}6eHH*P4=Ork&QD$%~90GC#0X|<8og~iB*>-Wg> +z)2vU^;E-ssQC_$M^GfXg+!30w1m7v4z(w3C4Wdm6KY@wM(g~XeW|@3@dQ65xe2i5h +z30na^gYV#VklxvAvWLA7_R;0{bC11Ct2D;< +z2D1Wu2DPBw?D3NE{kH{K^%WtVLUQeu-%2W2yuPVZ^q$!({=nz7EWSWo*2}fU&uNMa +z!g7vu$%XXd>vBCE7n~;2V+}EJS8siKymE1Pqwck@7({jxUe)&pe0O5 +zOwl{?M3Y|%Zd@(ebGQWaz +zPoNp0#J*L6A9U2~vssX3TE&9hYI+pvr?aMkwW!#*pzwt4&|311AcCGX$Q|01C +zbjQd)y(vS+?%G`)ILNKj6WPKwftoP%!BmxvVXGiOIm`rnz@bHjRZyU +zdeKu;$@nXepr-zyMw$6X=>hhUo93}VF=*XW>4;}C5ono!fk0`sDM@hN#&2kTT|7k;`pwn=Ct`-8A6YwG7wcF6Q$@Sb8*XxQCtyi(*kD0xmh>jUoW@Plo9`9WJT +z7eO%WKjE_hvs_38=C+c=#{QbwWK9Y38Drjm__LstIDWNUbBk5Agi&+K1+6YrYfMu0 +z!kI~}fYqEV#q{{(i-ZZKfT>j`a}aE!S44ZmQ`4I>F4SQryl4dGIya^}wMR=%4+H=76;8dszWK(9KS{)U%g9#$9bTW=`>dyd`)J@p;}eZHkB*$Y&}$*B +z_9x$2J&ndt&xoW64ior=EJCm?ZzF(Iha{~tjfyniYPx$zlSqu=%WHc?aFh9f=xH)P +zP9?10u%h*W +zo75FO#|HKD($z}34sK*Es6kI-nY@QwNR+tS_Kj!==SF#0MAYe%N`7+zJ|m}PfE@)}){kOP+to$KJ&H5W&qglwI&mY9Y~MdW(|P#-S{6V|?cVy!nwlQEhcen(EN7 +zGUu%^Zls9&emnnDjAltZrVK;aety%{JK~>%*E2pZZ8bRUBK2|?>xd;PRqom32?Rnt +zdQ3YXCm}LQjni`7v|O)@c^L8>zwonP53?dtq`_jyd;5zk7O_y!)gz^VSrTX+4uZQ! +zmnHRkqtV@SNwC__wiRakK?o8<47i*=8YPON(?bZYbD$$IbR(~x!;){Y*GZNrQbF&G +z;ls#IP@kIi&{|D+>*y&S3b!EMz{Qts% +zn=6|WcBYeQauKPGE=7u8KKHanKWGU!>D-#J?J4JhI6wQARIJ=Fd_Kq96JsEk2Y96p +zX9F!A{O7TRwyo>FJEtK7apjvRTFV>+dvH-O=;7v*7MbTQ0=t&^R-JFuItMiO-pZ1z +z#Uh9yV{k9@gA&M1@`00u%N+vwBh7Wjb&NAvz`W4X|8^$Xz1;lfRiP1y8<*IOaNc(6 +zw5Ys@h~0dnJJ$&^d1RQ2>U_>BJ9%88`RuXb6=nb2Qm87Tomwqu3VO&)X3W{-@!pLS +z-8bbQPOB8Z`(ppgr3~~l#!5u}PQSli*W-hG7av39E*CAmrJDnQ&7FUpo%k#Hg2ANn +zPB|?XKHwzbgdKr@F!GoLYkL9S8yo@PVqO5=m(0-;o*$trvyPnaDQ{j#)YUk_c`j8E;@Mo;&IwV%Q;@Z1+IDqwvvvK54JVk?3Y(6 +zCtm>SML(LXXH&Y&ZhG_=B2!qO8s@d4UI2n(f399&+5BQQdc;kXz*)7WXV$f!d2As5 +zc+1^TzU9+jzBW#j3kH9H#NRTGX!ua|MY_&{NM*a_`wf;@Pq$%{KZev)%g8e8+17M7uz5F;0HhW!4H1$gCG3h2S511 +z4}S3fcg{v^-cYOdxBNXa^~SQ^wv<;!E@2zjrWKD +z_yKs9d}t)$IkaB5NS;LL+uZsAU%X(D37 +zJrAr9W|*bt>X4&LbPb@=3UK^2YshvGnGEH?rw$PFIoOAPnXBZ@G5kZj74`5J3orRw +zH20l)$W;HBc1wd7I>vw2%SMvX9{)XngWGug=L|G^WuN$#$Cq8_e@$kz +z>^5HiI)4$p$3Y*=@el0bJ6ND6&oTzP4;-I&Dh +zHRd{U=k9eMBR$kzQ?#D^iQpbx6gh&oj@f5&}fWGl`?74p%zXrPt +z%NQBf;x>uTT2;6;@TD5pOJ9s?u<49$F-B0t6cjRrCRp+PjJO}x8GYM*>dU$>u#_Zh +ze*QM%np=&!TTpM5JHfI`mp=?`AQ0~k@UQX{zm2)ul9#=9oR-5P#gpL|M8OtA{ItCz +zqkJX45`UP_b4PIV?T}fo`2YR4E2q$V5I!HIF~$#BL#@Yl5`einMP1_%6wQrpL3azO +z3kvds_ytj-h|_oyzVKkyH|#7fx@3X+mp4IqFQ7FowD4!EwJ;cB`uriZC5-z*En2F(Ob +zHDH}_ivcnmsc;>*3S5W(jvvkQ<3+=0f7IM^@i}WDy{$zCT0Yjc!@bK{$5qQp%T?>Xjw8@b +z;fzi1BIREAyM5dCbnV>ruhHE838RU&boKPMbm9F7ks>lgL`Ycn4W`WAq|M}bZ)k7O +zgz#iMQUDo`T(8P!i?Z|CBkvbKe)zcfC+LCP&Shj)duntVPc2pxt_aseLtm%s=5BZ* +z%FmgQP5O@;9q&JmJhGl^l*MPrVkzTA(_Q5{DaB;*SP;2YLp2%U2|yO*sRU6*>oy#HOdDr*N1v5G-wab82&1 +zx@DoAj9X~$;ijbd4;l?Jy2nT2bH~kORPzR}SfS}^`@iWwTRwtC+9R<@C`Z_~TsmI5lw=kdB%iL0hfC>Zj(ugV +zD6<8)>(fTl3_pboPNsJIT)TF=DEGw(a(DA!XMXd*kKZ_yI@CCHpB+W=B}I9a#VA80 +zAj%LFAGRO3@3d{Q?MDxx`_bKqJ6|U~rDC%~MMASfvpF(VX4Pr}G7C^|UZZNc;GPKV>+H&F!y=LOdVXOwfdYp3Jz6mv%2HcKX3x_`)W +zCuPTSM?hfHGYCZUl;K(;Q;?QO0S?*>o~l=Fg4;ZkmhboG--m{YyPOBLd7&MACs)?_0x9hIl4MDcMZ9d|2 +zCl)3i`$?%5;PYKDz@Y}R^O2{ye|nci)$ofP5}Wby!{LD0UM4{t*w`a(kB8o9tJn>K3p4~5Gh;S +zzsGf2GgjLyqNpR)o79oHyynbgmt@I4_%xrP>{fFq9?%a4v +z)P^J1M@qd0LrIajg1Il%HiV%7;?ks_#n|+|3X;yazwa2Uc9xJIbKkv&s4y=Vqq{Zz +zN5d`WcRG)QzXXF(5pQRzT^ro$^lD>VHH)$G{n92aP!BVxviVB^m@*_g9i4FM^tso4%b-YF$aT7Yu +z@4I&fA|PsYDI#gTPA +zDGMI8@4qn{IDAs^)z)^`J!K7j_C4qzW>BV-6xMOaSOEk@n>&{1CDF!H4yvAr_Yr|#*FkM>>XN{ +zHndla9B@lJI7Ro5co9~RnjWHkRI`iA9_i&CUkA+tnpb!cD+ +zDyXYF;vk37eG*6p=wi{D-ti^xIyJr9mU;s@Njg6%5Fmbv3D5FLwAYh}<7!1zK~7xHGjaLAf`xqc3AX~vAgP4x4pbz^ +zT0KFe)6^=)Pmw^tb?G^8)3hp?TQY3?5;C7vQMWg>vfau8hN~rzS1eJfP)`s_QB7-MYfPjt +zsg*y-bP!EgDjVfc?GDyf@Qr7M1Cvp8k+7}F|BFzwfU29@_Wf6+6lj4$aVzfb?(XjF +z7I$~sxD+W)ad#{3Y^1omySqE=yz!lT&XsrXeQ%76tc)ZpnJdYh^Y@=C)LH4oQ7an+ +zbb5}5N?*XMOLo8l(+giSOU@1f?S*X<*O$JIvHQmD!m$Q#I;c-6wmslO^FxWjm&jfS +z)Bb`!^T)u#ab=Q%Lo%1Hts|2ySf +zT|faNa0Wn;;Gw*72Q^y{;mf5Db7D>u7tq+is4ZVDx8L<`R)wg8ka4Ab0Mvi$D7;NI +zg#U6Ox}K1l8e!)CEbP47HL7i0FlXl`wVV)rFWt06bfOqD7Ay|S7SXh8v$oj8!XYRy +zW2YFhw!9@2J-;j6Ca{KMsh~6_ui)OlqBf?u&G018b$=E$A@52_SuB;7S?aLLw$?wW +z-Xy@w$~l#mfs=mhVkU`tIv9}Z)nMN=Wg|Z!ACf=jl15f}u5Dc4YsP>3&B@8-R^GgQ +z>LcR7dVHOY@kULAnR6Z+FUPb+)Ob|AS?gL{>3+aaT5IG>{Tu<>&3Lm{TgQfs09v8%{z%RMS2hcyCVC-WbF##sW|B&Wo049V!uD47!uCX|wPaC8CVrrfP>Hq}XpdJPB;O#XN);we +z*GwxP8D8nKXy`M!AgP5Uy%xUa>QgKXpN|VlZ^(jw`Efc>o0RJiakDx=+$!BllFQc0 +z7_|_}m1wnS4`?HXx%NV?x2~J++FXtQ9`)u6j^`CP){WvlI&9|A&(@K%mXM`$het;* +zKgO$lI^au|7(XW#(WPbQB2&U3W$g^M;J@-16xsU%i)_fTD00rhgCU-jMg@IgBz2rn +zWjbnc&LGv*-V*Nq*0hMn*LWk8&D>2-CsoIQ#~?{3A$2Y#&PBL_m>zP96#8yNiH-p0 +zw@r04htIdc`)*NYABTB=VmRY>7>n@qyG{fC%P(WX=iiONKj7-~!D%;6j&PRs}8KH9TJfmDlM?y%*e>UhcA*6aX? +z(GN!Z4Wrgx51a%;ys8v^qmPg}c1^ZaNWphVhRz`UUpzWq`mtxH{8;4A7`5!?#1_Lk +z3L1Q;;kA9(s9!4Cjq58zS;$iFTAXs@i_ys)u?*0WZx5)+PhZ8R8BLb^YeQryorQNg +zl2XS;t<1F4vfVH>LK6l)wj460ehyl>hD|QLCRpAdjxpSj7q5QZ^>Q82=W+f%)2K{T +zx4tWvDj(hNO?IQWPuMoBOfjYEY71eo+72-Km0EHDmfM9Pr_8&u#e0Ace|x_uCdIN` +zW+{qhMFhmymQhQoHdh>BggF6Cq7GASG}@9UstfMO2=9u+c2SGw?7*JK+Z$P5-@=_L&@O61NjKs>ac +z*MEW-jbu+bvz-D@O|x3CcepIF1gel&R=?=}79^e_Q6r15Y4k7nLlHLdEfUh-!@eKJr1G_GN*Y +zkI!HcfJp>kDwK6B(j3I5ZNPg559I*Z*+2@c#(e8pt5MYPUuNV06Z0@Uz$Af_lLMrT +z_T2(TOHk1A#>=o29~c<>`zl}2KES~Q2>RKn0GizI8yKMvK+73?GY2H^jwd^iLs +zf}kKDC`esLnSF$taPDp78^F|#b_=MEV*pG(g;7utE6o|O?D_0NISh>4kT`zv1{ON9 +zZCom}AZguip#Q~em;hmuao;z<{5SLhR1IdlSt&iJg3ip^7Ylm3AN)2T1EfroM1XraOooF_dmid;pJxkKN9;UjE6v|>>aX}zZ{=!r{f1Pg~eX)QycAzbb&stPjr^NoS%M!Z$D{m6JFI +z_D}xnuRMer&iQ=}t|?=$uGQ!03=V$rr51|eGZ|=QJfl?KHr^MTYK80)?Ewr2G%XZ1dnEQ~zVdl!0E7zM?h +zOG-Emd|@&dv^Hdj>wp6I8K0T6jGxcSSo6iL_Ho{<_9;JTEqG;*%f+wHRjd!-_lszI +zSRpGWGJXyn$j0d=ecg5&V$$K@W4KDRobg^&MfsySAr|vWIr}Q9cGi$*)mYkuxj?<& +ztm70VY3W`uV}l$MVX>l6I2SnJs*!FR&Y(8b+M+jCC>9$rrNLNFBioy5G{x5U!~DlP +z<8KWicIm41G$_P0JImX0xFd~1A5f=a)MX;ldncn|Rn)SlMCuoht!Q!d-D6hVj3VQC +z2iAhcL=b*Z=q5Y9gfj6y@58)D +zGS9ZWLWOB^k2h2P#B8F#$ZhJ-H){fd$r=bY8`!h2K?sz{EX1A6tY +zBPvvC~Qj0l|MTj5`| +z3$66N|NL6Sqw-#3SXS;Rr{#0*`U*Hutr;e+m(CyhFtY{p@ +z>X^IMxYaTWse6fj3wTc_Gry9PTR}hO=+<6Q&H5qVJ#J2osDQ}+o~pnrv5@4rJ6xA} +zB(*7(0Ab$WZKO{W#iF%V-(v@J!{ul#PIpZh@^z#^IAflf=P%BhPfYB%L25!JupGbj +z2hnRhH+Z02gU7EL8_&Qq*kewhZ6d3C5K2+4Cl~sC=ib6{btqKbU_Q=C>Pp8VX$aQ7 +zz&7l9`9Rp%H%FRx4;`nzEr`RypkoWK{xNUa$a0Z0J$;S0qG?@AaR~!pj`jHW5B~o+%W+saD^m +zRiSWh^Q%BIZ6miP;hpQE7dnyvCpsNzZa|{WWXlmdiB^``ikE@yR7%mjo=e?obh;1{ +zO68elv0gy&A4mcpOY>tMI@8=RuA0v9O(=N +z>Srcu-V15_e{~J0g0gFD{`K}TtD0)}JxZW5%ey|0eAQAKD}+-T!blPOE+M?gDcRFO +z_K{DTav%zUX47k}-B{H&T4Me5QPe5rclZ|B%`pjITAy<5E%3;qy80vN-H)V-8sftE +z`?5-Zhg)7O#vOGb-XMp9yDEQyEOMYKz=v5On7g0CZ)D2jrE1O +zFtao4xb7h?f?ig+LxBa*OItN2g!gR@xTpksok-bh+rMt#WkaA#?MXAr>~SM~ez@hue0LRbUdJLv$G +z$m)EY496<&x^0{O7ISeHW}9!DTsGu;e^lAkLZAolqvI%s3QFr&b>2j-ZkYcNpl!C< +z^6=V0v|sbH18hV}tk;qY)7DT{9bsqa_0|ozR?W(h>BMHxQ^U_EFZS8R{jZ$F1P*m{ +zeF^) +z;AfBZ&R1ciR;`RJ=Lj~cqVADx(cbFIP(_0;B<=cLvwGNePn~nMDDuqA!b*Uj-9A<+ +zk;1dih^`8bqvn;9>@Z~%w2@AY{K@W=dJ?e#+J|`;Xj(;O2hq+O(N~(Sqj5H7#w{Mb +z`;C~G?j)ZY8LRJtd6-(DtTmaW8%C`d$GntV5*_d>||r6e!XJC-pr3HX3M%QxFTg<90qQ=@g*vm2$iny~XOy^7n-yq$k&o +zzWVb;?zu+n<%<1@4eCWZ +z*ge0oJPogUbs<_uWJx=DOmWMuMPF61t=wAYyr3qBf!?>dxyHbr(d(RQdhtC$@e!wYR{RZUDm)pzHyX%%_j$GaO5 +zJonu9IUpH2jW3_lmI_rvKe2woZ#iVDp=0OsYO~X2ro#8xY5-0h?W-A*tIdYZXzX2n +z=J+qC@CSbQ5;X5GwC{tJ33rz8@RoZ8~nO;ZFti?P+5p@HXamqCKdWeIMk*TRfgw$|XNmV&LZYSqKzMHF6n*#D{cC3Ch#m^geO(%u#&R0G>JwJ7CSNgjp0g^d>*5PQL(t|(V&hFK#qxgGkSIUz6`%+R0 +zp2pz>*RE()$p;_BijK5+tdo%s0Yh*U!KI`OeyQA|Rcm-TV@m5Z!TC%y+rD01I@}lqsTp(FWu&5=4L{RUzEpG%FW|iAMv8)k;1MC4K}`Uc4Xuy28Q5rFCHZ(+P+**P&n@e-VJ`ABx>%5*T5If?Cs_>&r{7EzUvx*8u64NkDEt@EOd*|NR95 +zeI%Z(2IN+OkpH2A@NWi+?~_)%0sId}-#VaX`$6v2?UzTh)x~}+cQ>U8rQ@?5rKm;g +zsb0>RD?DV#ClD=SXcu)mwEt@Yu&zGyK-cFa5syV9PHg)fGq01u+ +ztP6fu=Mx(Oo=rFB9qvLN4>RuIH^yPS|EZb*6ELXn1EAX{KsMk2^k~U^Z8T3Bt*Ru< +zEc;#OJEQ#N67@d>ppk`wykAsXknPZFtRD^NOdeb16or}?a6DS&*M+UxRk4?#bHwbQ +zh(I!vz?YUoCi2&Gk!MeuP$<5@)(OiNWH*#45g!Re|0fvSLFJR-V|ao%F%S%Hpz_J! +zuj{@Hk(7Vb^6H^u*#ey-G7SWSOR0P^It@<|iHobTy?P>9wz4k}L6L}mci^CWbr#s7 +zW7(>{4Q4_``UwS10?7ZU@uZNvLR?nNnyT>@& +zhXvr<4fURbzO=tRAnBDut_7bW|C6;I0F&2S1gVay9J|!z8*3JjB3h^{{BNcfnqC0U +z_RuF;vx90VbfEkzU|C*SQG2F +zxu5MffDC}WJCK1;zy#{1GpeBHV>@j2M;|};Gi)`X?B~8&)J=QnGM}2gVh7tD^5aU& +zJw*PkyfoVo7`n?gyy!YGe)Rb(JN?oVLlE42KXU>JnAqq#*wr;VMqRj3<0|%ZJ1brg +zOyx~|HYr2Q{<-CBf84YHTs<>Y0k6C_3O5gzPq;q3mrw6}IJa)zd7@kh1t?(%reBu! +zgau8Ekgs!Gn!;vhcNHUMA9K{d`=^uqUk&L^-%a_I+nx1p4c +zm@`Vq(9Yf9Tt^9+>9({z@W5^bJ_2DMv+I~Il-BoL!XeB2$eHi=Ma#s6Y&DRC?e$vC +zfAKIPdW*0sq2MctN!{3*W(EJ+$bYb#OA$#}r>Dg}!hHuZ_Kf{oyMEID!aYFNG +z_C-*;V=cAOi;;=V8@0z*IKk|$133Ps*S`dbm2xva|KD%uU%@x7_PSP6Y)e0-gV-RN@w*xrHJV(f9yv%(<%X{ZqofDv_7 +zdX4Yjnom|v2&W%+^biV?O;Uw_gP1Vp0N8KOT+B|19b13qQP<|Km566fhcGrohsajD3@1)|tXmg^@$#;!H@5-A*U-PD-f!Lt +zM=&LA3U`xHrc6eK4fmo#`a!lzdxwrkXbQu3tzeZ=)Yp)imGml*W+@?mEaSicZ`4BO_j?_kWHYF +z!74rRt)oFI`_Bq2a&c!{Cqgi`aW8+ +zB}ckJv}zu$YcUsQFapzXlm=eKKmM=x>UKV)>2l=T+pQR9dcC-xcBrh$B#{#%a;Dl` +z`@ohEtTzQuT~~O}cx1F}{x7-@rmA9tvQ@)!efknrgH8?0)X9+{e@>K1w6);a&gU_K +z)VEd~QfxyU@)VX6BtHiOl0sdr%j}@mJbn`c6_jeaZ4Lo>gYE^qcs!$Aq`BY^ +zz?HpzRgts-ng~6hiEsu&GEy_d4GhPq(jYb5e@#sD5OSJEUReW}bSg9+*CRXku +zLCGQO&lE!9Z|GDPY)RS{O#7bIX3w>Yjtw1_hr&U@gI4=^bElH9ejRzKH}M7T93xc` +zgG)2I#O2>HKE^>1QeBLMvM7Zl!vRDd@(x5Dp7~Eruh2bIu8UQWK9pB +zw4?u?%)p*$-MS=@B68&>y|6fb(l*=8`XSg{>Cd>gd(!ms^4gtghnfIG<>*G65OBHE +zH-7cn^V-XIv9VTiR#wzc_uy)*smz&dTBp{m$C#2hbAG%mV=SVl{p{dq+%|3H>tpYG +zPfpk2`3zgNh8LYtSnern;^D+++_bolL9Q`crLWbgvCn#!#~CEY35&y< +z$Jr+aRQXJNA`|U~cdS?7ki9GUmpa3XqqE-@=2`Ac&i{zUk8hAf+P+j>5>Uyk)xS?r +zwU+TmHKicFK`t>b0a5?IVSEx8;rEHc*a!BQpaZ=Z?QiyWCX)d2zjDHV=g+@^d;tvT +zf9rs@j9wH~wO=mHUKBaJ5&!p7{~2h*BjGNwU(ugltoDa(bu3R_{#3%gO8zG +z8Lzsy%CLV;y+OYG2!VM959uodOhp~Q2~Yu5q63`HIzFBQqW^1t{KpL61}*693b^*Z +z1g@3TAlW^4;D66;|IIj7>{*0SxlP!j_a$ckpi#tUFwISme2sP>82%QxhW9s;+3ExZ +zFNu$U3(@xg3gTNpHMG^A>88*rlr9%YVMCY)v;l-yu*OrWPXyEKwP^(aS-gW3;Aq;a +zgFyK&KpET#I2UdYq8cc52++aXfa}Y2krpPS8!a3|M$=R2v{;E9^h0g8e21`a;dz4x +zZ(BZ%d|Wl;znLKJfc6u!GMRx>JnsO{9T4Q1t6I?Wj_(roU*q5w^SRuP1Od;pNnvG_ +zbX3#1A3CEHoa^-LOQ+?K_2h2&!!>i@J( +zJBhX98AY{$oJ|5yt^yLF;->N +zERuza_MOSwQvFE}=)Bk*ZJluoA1vWRfHc!L2x!l?!>naxRoI%({R3g$CnxK8sDHM{4 +zwTgSyA_bC$z?j#dq*pC6AYvE7`>K^+aD57vWnr2GaI;C@AmRYi3_y1a(7r(=0qi5d +z^%)|L(H}oBEd@b7F#`w;WjIkm$*;pVs@I7G#k1y4KW-?n9^Sy4KQ5nFk2}T+536)Ot-$F_T=1 +zF~YMYYhq(N+xzN7PECuo!pd_w@bg>eVuQ=G_Xb1POZ&?mt$GAgg4dPn^+x)l;D2_X +zD^E$Rfq!SAza3@s@xS_T4Der2@&9w!nq-sz}x +z>-?|gSM12R2QW5VCr&${F^DY(vks)a?~HqU?{0o{j?~g?d9yV?yynffnmHF8@^a}T +za*=^|EHblg$GEz^iA0*Ua&EPnMvL3}_m2cC8T*>-mZ2*gn5pI2PK13Hy&Y<0Rb#<_ +z4$4=tg4?Kc>G9xF?Hjo9{_KA2Q;#B(2pzaI(n#7gqcx3bYik)^<5&GCnn>r++8wb> +zvsz=?y{37;qZd5gnCIXCKR5k+kKQttoPa5(uDAaY;Uak+`=w55>6Bd~!McPYgiN!F +z$b|$`UrlIVJmwc>w%=?%~;>W2=LlU*fT>N%y&iC*`f5&dqbTvpB+b?`8F2 +z5grtIvJvKfy0rSxCCm5v&;q{iAgk#E14`cOAMWu3+TYEev=*XGUnYe`Rfu3|ocSkw +z4ReJjUsUE8WTl>Kk^hK}gZ5Ee*HU>Z)}yxS*K!j>j-+rERh>L7eB4Pmn$&Tlc+g8@ +z!nr+0>1Ri3g1Po?SA|%?r%x4qb|bkaGgM{4R4~l&sR8;c%5E~EBrWRLiP$3-w&^hK +z2|QsW?!A6q#{EU|a~I^GPnT{jszvbMp3m%kRz52%m=t|Ivdyzsynvyqg5Ngkjzsfu +z^cAspmp|8AtzCw(Hid}yMk>@R>dZ^11zfV%e8T&c7&`uOEH+bp5(ZHT{TL^wG(2>6 +zHzxg$euh4pm$=xhDk5Dkr+V7&c&6`ehAs-a9j)U=DJ%A7l8P!Or|6|+NZ +z<8L`XcAT-mS!*bSm(=sk(;R#~AWsN}^`iaYU$oAev$_gL+hpGx;vOC9<%CQcnQZDH +z9zq#OuZkNf3@0y5UTPVjqaqd@Yt>=>Iibe1rCE_pCsh8~RM1FLq0cDb7p4E>r_A*M +zss{0y_P0#@T+gVVY%25o+p&EWYM6_S&%<yQ2!O4}i;MxVso^gg^h6K(pPIuk +z8=8a{1K26O?H#K9>b0a1+tWplX#uT!@1!fTJiJ%o<)XhC9Fg1)%XR;Uf)rOaxopKc +zyG{06&z!dW)x0%noi^Wmc!8*vr6nDlc@fmJes_CQiVyZjp)DvKfjo-Sc6D3b>^>*; +ztq5gi@zpk6$+joo@^XG{iKu)y`O!cMgvap_qJ2e1-|>MP +zV!CfoiV8p&j(~^N#bnf9&-oc-zh$JU`izA`@uD@Jm?oymsk%$|S9YH>8Z6}}r?#VMEfV|6t?#ywIV|b}gQYe0(Vajvp}F`8 +zNEO8nW2$*sU4N=7bY*UG#DnPZm{T}Er_(PiKt9ywj(sTC#r_^69Qc0oi&+8tRTq`& +zv}TD(Vui3YPTBjc1RXY3Btnk3g0FX&warTbtYz>n>?&5cqc*-G~SR%R>(1+@uW+Qdap@+AQmAO=@YBQ +z{#myt=j&T2C-Yb9`OL2YT7Q1<4mhv=Czh9MzckKry{#&tz3!Q~M|67nW!b>@uC%~CYNxQTurk{G;T&l!dS*D{9-3c? +zxwk7L=V_Frcu|de!Ig!1tdwo*hN_vO^rX54oiT%sH)`n7K)_%XZY#4EbK%kX#e}3cpTikj;;`DQilh+b{k*+h^>WJ@$jg~Mc?R~DcHm2T*{wU}XvNATBv4Af +zuHJG8XPN97pVITeJ*OrL)VWiZd|!9BklZTllCo58d}c7O*I&94W8F)Q%oX+~i6A@X +z92}4$6LwE`o0s}JLTYm?d^TG+N_3wxz+s`GUfdBB!o&4xm2&LiH-#%dZ_tPXN!3Se +z(c#~l80##z_g~|T7gNudQswqvY3shjZS5|98Jl0^lqN-`m0LNnPS4jSg)4SB!oK$& +zT1W)_AnBw?3)?r*z@(UBTF9eXtSS;bqb(cl&Jkk?SMERf;1qgqn3}$Wg4OU^p?s`< +zaDkb)zZFLHfE_viI^7PN*6cTrt-(~t&-7Sq*qWx+N_8mDW5O85GF;|4m`bRkN;%pn +zb?9WWI=h^SSSK&7A2VuaJE5es{#}1&&rU8^2O+RRt{E|PilYX;?&~Eotyx<3D$M9W +z&0jan)ZBTWngsF!&H0{5a4pLVGKBTdi%PjFj9Gn8inNOfO4%vTC70_N1Ik=9I>#nH +zu+16yg&rUms(OZI(~MuD8PUr$W5CHXjL`dGEeewnjEBkENa$GvzJAO56Q5R~)GqNw +z==D_~>OoYd>rhFvekR@IHg>OBPsLb(b@~RefZ4d%zKB}5EM!>TwuoI#05(qCAx|_l +z#bOSnZCW}EwzXh#xVs<8$U1cWhpc_)Utp`ttqJZHBC>fg-noKK_LzchW~6{EzR^Qo +z*vCsp?{ZA#0_NV7)S=J$8={@9nX{F?)B6$UTYx5*c)07xHQ+V*5DFu-f0*v&_Gi5(R;GZ!*8uQi+MP~I+ +ztlPJU6|q=MRM@Mg2>71z`|&IIO)eRlU#H$be1|2G*X#{WXwsGdPpGi12l7n$!QU#? +zQqkP2%DW3@gTHVtyA(TO{sMD~|B`5w1D%qN5$GgunVTM^S0O=C_rlR3GD(NDE%D{O +z>ukR;;!uhQ(#V!6X-w4c#ask@Prdf5xsFufD>~xR=m+|Z?#r`cO_~Un=(z?e?X~;~ +zmVP!V5#0x`@SLIPDOX@r8dH0PMIFs{dfpTc;<}b--8j3Lf7@`*8f`7Dgktv)aIFFL +zXsx23Gdfd}P=1x9&NO65U@%4|OS|>l?;GA9v>ogbmEV7d!M4hPX=<)-s&B1nsqb4` +zGSD$NMXng)rJuztomV46?T>E^40~%1&vrXzsDaTizaw +z9g!Ak35XYU8**Jnef!R#(9pJ;hq?BH>9x}0t~SY#Mtu|U2>Y?PM21!WTdL6~*IzJi +zoSDgZ2#NVBNis5(8K8iUZ%DSK4%()OAGJ+)a@ZD%vcDJ5%H(A9!1U23!L1ilc~e$| +zzu+CkV%aVBJ1VCia~_?`wyh)?Wr9B4CWW&0JW@_`Z4_?BA7=&`w%_ipiXX7^@{)D9 +zY*^RnQHiOsRcxFUiz?dnWNVIKlReq#8X3?vb@e18*(q2q1URUj6)a_hI>oSKe^@ID +z*x^%F96a3SgG$@^!wB><7g1`E;}@S0vIV1@S;JGrnxU3U-3v5460#C;Q`{6Md&Gw_ +zz~M-y`pazeml8K3NSv&FG)Akm$s^B6L5_AyelBJ6^thvu6M2~q3UJgjbh4RO1EsD +zPp0=Q(W-eE%2flj(w^^IKgGsTI&ng+L-D+{u+}3NKR!im8&z>-gMgR+6Q;+ +zWU?9h%G@X_y3!vC*Z#`#^^@rGvh^{$UN5yrq)%LqJA4hzjxKe3!r84ZS?8 +z?Y7-d&i8#KFHHx{F>T^5 +zJBPSO?1{UVY4RdvlGuaj8gUA22R7;NvXd&=i(_n{=Z%Chmls+|g#-o542Vt{>b9Ca +zv~|-=YGn+ukE#+Kva!+y(@_t&N$u;Ti&9LD4Z7_58ARWgQlFK``9{#!!Tm8^(H8<- +zn*sCpLnkI91?~bNi*X6rvvNMd61$-&d?dN1K<`*#8x58ZaodpWTS83y>Ak8b^P7{> +z-e;{tJ*SS$AU +zrpxKSpKxK)V!Bv=4&*70o#CzEnnd@SMmI$m?W^P873pl8=5a^H$*8HD1*0Aap3U?M +z;YWXI3lX3vOOg*diuSmxb=Z{c4zBMjO?!{$dF0?T|bL`?w5&w=?5J09Tn*! +zc6j0xv~O4}!&%|8U)H&;FX7khUzYl+bc5|CBA0`>^c%j}x8l!=AR!7u>IsRd&6?gS78YiO*fYrmpV@S`2t=pt!iINo1n+gysUzxTr)g3-;BGhcCkB|FduYHchtz1p}JkM$1)+^})A7mQW@Wu_gqC0Pw_z96MS|u1= +zz&W}K9=$Me4)UB6x+1M|{6ejlf`r0AhDn9byGW{x%meA6F=5h@x3iQT +z2-82Z7fiOsU6NNoS6DYXT()Z{>@-O1>hJC_FEqK?8MYW;KPc|UpB +zS=g_9r9S?y@A0WcDvys6X)uTw)*r}~%aAz_j&p*{xccUkuTN}MhBUAuPyXC-9%(H> +z8!;O3g08>W``pOoR^)#Q*Eh4>h#;_+CU>Z(;Ayh=Rg}Cv6;v(B7|PJXqY&(3t~Hl~ +z#buYTAj1SL{^7quyLv$^)}9^IUSzcVY8!LagwY#El;}Rv$JxS#);OLfKI#Bk<@u;% +z6wkag*{43>4#p}{j@O)%JNEo!V8P1`5)Cy7Mzj=FopQ7p**i*tOR^Z$-t!W{z|9TD +z`u?#XN*nh5= +zv>xLfFQ!>#EcCCho!zOMw096utXAQ+F<=Mke;xQ`SsFTiTacUan}$M5Kx)@CBhVs8 +zZu>U50owLmM7XKBu^vU^EZtw`xqr+ul?2``7_$QsAgV52ow$br`+}SoOIYn98&$~>S +z4v7gUGJ-2O-zk|gzrM*)5m9@XQ{fX|$x-2~tn=8H%UoX{9XRs*5$Ei5Pl!h#bK_yn +z@;PxnS|)6kXb`I!i9eB%>7wwEf&13uptTalJ0>d&L)14y0<$ndZ@{P|jUDKhMn{k=~7@+_2e7(Y+<&_b6LfBQ2VrI7D1 +z^SQ>WcOq7f#Myd7zVKX?@CH2>$O==RjgVqd*N4Xc`bym}66flDl2O?X_k#Qu%oHKK +z$XZb+LPcWdExMob-KU1cg)|pI1uV7NYRHa6)j3d_;6Kb{>tZ?pFJ|fA(ejn^f +z>B^#S`UCrQ3}L;lut{`tiO`}0yP<8D`CL>j4yCkwjcj}6tBFpRUY$wIO_WQ~t6X2e +z586G?tf +zau;~N7n0KA8*bT=sVFj=32=zwC?@8vZIr=cVtQL-6p&v1H +zL}R39G2#h5zxEt=)uPJ@hv8n1lfy~!>hb5rw4XVj7SKkulieeFVmon)m*nwyMI|>w +z30st{%?OX#A9F=gDXIobKi7r!ji~_E@5*E`27COF6yg*l*b9op(+K8loutPQKX)sA +zio@PA8rZuD;9|s1;fzbn%`VxT#Xbdb*-%~GbD}e`Ff`=G7Dev`tP140BlH-ChT@G9jO!F~7!N`r8`eRG}yh@CsEIbVLXrE@)_ro)S^wCE1 +zJJaa5kQQGZGEDkM+dRz1(YwQdAkNv;ZE{1bx9UZhfFq^2cN&6+kHA2|Gvugbqv?Kbn>~Rp}(lZ-t)=TEY+Yj%`T-OWnZYA**v!t^IQ)3*cw8Ai^+#r +z>E0tM!h-Bnb@^n~pg)@J8Nz;YJXgbh8PA{D{7^gPwtCNJb>AL5XFMVMBgh9INBKT_ +zyvC+he@bUa#r}7|Is)!&kVfX=`^B13-a0ezH$m?78fNMWw2$5hE~5Q9nTOIQez2_R +zbvNg9vk9V%koRU!)zhOdEKum7rHO9bQ(e}DPsY}(6YuO; +zUhCvyN*uPN`Q<1lJ7A^;XJuKQ>e#WFW)_H|;ue9es_qtnjjqnA%!gnKyAWAzBW+S$ +zOU!6ny!55*HD2|RW(dl|K8~`1T;(FQnzejkXLE5{TzvOe+fb6mOz_)qTPUHokmKjcnP9!14}9 +z3nPa!#5UsS{&&YMDEO*cbU%X+N#ja^$ui4|>q7VnQ#FGXc8fL3H->0w=bbKgZU>KY=>$-0|7l+B|!Oxd9d{}aS +zlV8t9>>N{3-@P+^l_)7yoQ+y|R?I>7aC;la2p}n7itVgHaST +zoi8{9CpZLmcZcBa6hR7icZURbcMtBtr6>w_*TUTb6z-PH+NV!X@1E(I(|3LI{)%V4 +z$P<5?SPc_U+UuE#u^`Lt!Q0mLUM5_irmq_(RfJhU_@Vi;u@3*AicLy3Tl^wj{9k5G +znacR9%yPYaAp!`VNn-x7mPPu?GG)E=*y$hhwRKS6*g6#{qyI@S=OQXxmgq+fJ6%yQ*68B~4k5VY6Ts;RKaa1%n~C +zk4?iauy{~Nrs^?k`kE5HqUX2?v<{2#!L&^Urf3tI!^~2U)N!- +z6pnDi>Ioh&9O{h?w>3=u3J5AFd8LZukILSRAh6GJiGJTj=tOaF7C(ZJlAuT9R!gE! +zYp#s^Nu6>Qe~;SuLqx;C7Mu9|kKlr6VoiGwZc5+9>QOyOD&%4V3l%1efmJcAogl2e +zmmsVikbpE@y)&4ZDgJ8xo$s-)u=}r(8_pjn0-lT5j9SIcZm;(hP~^wT!3Opc+|`%W +zrGJEVW-wYJ=)I=JI8vH_CW!sV?w~IoXgh3UfNm}u65943!vliy`wPccv#EyECy2u` +zo`8v>KCPc0({GbtQe1kZ2|#bzD`|VDKu`Alao~ukbI#28AFnc9_(zY_PH*xoxMuRG +zW(CZa&vuZOfMdp9!H^VVqb<=x??-YTey_rf)fF(f`_abN-kN=z>5^Qm6TI{?yW)86 +zxa6I|?`4ok?!eBTZvi5!13}shI{)r`wKliMbYXCIJ`e0@aPRQ`Ztpu2;@v>FF1Tv2 +zwf?8_eNG|J)j81qWFQ_w@6uxDZ0`-ex7jbr7q0OSSV(F%>~87mzWu$A^G_BJ^47moaLQO7D8&<4KU-GzH%-S)q0 +zWXK~G?aV!ViYE(t-k0+hjMGJ?u328m}GhzC#~~|C(kni_BsufiWN2_`ILiwnEp2nZ76etz3Gs +zIlr<{aH`*~Vi)z(|ND)J@jUf@bEv$dafR!Vyf%}z8`S3RUDwfOK^ExoRMgEBFlY^W +z*?YO3mQ?X!xO(({)JL12?zz+ +zKSFQLBB3{(E}CnvKF*Gp`*fI1VDIC(E!95{2(HurSYw12<+)2xj)vmS30_2c>3vXY +z!*u+b?bax7f=E$ATMvKA>p^!AyHT^qG~VA<2{?{g_VdC^z% +z<)3n7eTaN+%M@^Rr1#cTiedyPPFUMD8;$bQpOG+}pze#lvr^-GCwH7L7J>0AKYCeq^{F7i@sH7R3BDaEXxQ;6*T7)qJM(Rj9$%V +z843?mD(sgG**o2oO*m;gj`xsH;5qhpL(k+R#r9@>i1rbHTd(<8{EmXzYbAJ$3{$7S +zaUVSMemXJPX5P*}>eCg(9W@C4AeHy{<-zd#6QiHml#4*N$P6bEue)KL+8@E!NF2BQxsasRx85W&Y*pNa&_~J(ot@ccGu4WnsNzV=sLQD8Op!0Q+~P-< +zTQmEe2R2+Y2-<|!{{4l1zg<>n7j5ny8|YjOhCg;7j4Lo}^GNt5)QpOKhkC4cZLe~8 +zSLWqVD{@Z6pT7v@{gttejdU&GkjStSf)Wltb1BYxk_9|a#a^)lxLPji-s3-U)H7ML +z3yuto)3&g?)bj=&p;uY`;#jBRFOWZI0-tLwXs$6&>PB07j7?&^Te6!-6!zMWw0LMS +z*g{YodL2~1p~9)9RrGD|{Hi=ofOnsdvjAZ?@7<>0QM=~6@XkL+{DK17%O*K5ePbF; +zM^R6{&t>+Jo?rZ8QO%%rx#CgHK;EZJTdcvUZb92O9mPHjX0pHY+iH*BLXdzRV=@3CSngmGV7Z2@j$>>`fVlus0_qoVfAuiFhK1dON7%0IV +zVoueezOU6It??fov9-wW2y^^`KQ(=Eo!npl#2sB`0h+_TFc(d6 +zJR8yfc>XizP*#z}R44~1uw}L2ghu^wh-p!6L{SAYEnsnbJ7YpV-$rl-DWh7z?C({bC70n?h@Os +zk43-g?q@4wH`7`{GcRqu!d^3)KlCHbqTn}9?+}5jN%9U%Mr3ckw+ye+`70Vt_}zZHH`UILl~fimbEPiX^1)l}E78Dx0C4Xk~@e*NXYHTOMyj` +zC(ZH2?ys>OAH$`v%-dc{X0{(V$=y14-8rt#xAQnM7!x~stggz#W;AGbjfWLW5(sT~ +zPq`F%8V0Blq7ypm_uXPztkD#iczX#A)YwW~UcJXk=g~;)y(ekYoM&VUn(MJ-H@n@5 +zEKgxPieGaEF4;T7LhhWyh5YprTK+l3QCw(8KZAt}&L7oGFifUFou}CE9zy@rIoNvC +zAv&ABZe+QPdVzU50oJWk7dUnlt*dJ@w<3=GoB2qaGw;)(TflV2QI7*iTBbs6Hh147 +zY!Zf)yEi84;$K2&Juu(}`+Uz|$d1=_c_3Iw;3GDWZ=orX=@b0%A)B2p40V}~t-)!X +zyrDOCMVZo=314aT)7~xSP)bx`yL!7(IoCpnzHK=hxvJrx2^ofE6BEnsop)NSm}j@{ +zyj`VdDsAs@H&E6;;t}DJoCAjoEPvbRTSi@6FWDJ?HeNWJnvRHf;9Knz?CD0mrmkKvR$=-e*_b90%y6}Ip8Sm2;z`hvT|CtS^D~%%n;dSnP1t^JkXP2o}WLvk{ +zo(9dRJGqvUP}sLSuM|*O%ber+-ST&n>`f9%k~gXja!g(SoW*@HJ_tlY>axcfxvgAS +zh%YLe>Gq%V)RHrti&Ynqb6sB6E#9R_H7F;N$^6GvjGxN4q-H9`MvPo<+Ss{cu+A%T +zE`q&4iEAaD!!}})%>`yE%T$eh^0Hwl)Y6>S^O1%Jh^UUDs`|x{;pI1+LZ(QR=O-DC +z`GW7#H;Sog*o^2nAxgQQ?XGC~n~?9|68$pJ+BoB?XV|GXf`95)q&EH&dTBdO+8H!J +zU@%ogX14Cl-!a_~PC==e4hq}QjWPW_T>9~h(XctKlAfcHxdt#V!Z1e>iwGOdi&Dur +zJ2Qq~owbsVy^=ggcWW$Z(thf6IKB(*k&uo9)?_x`ndlR13IlJs}6@S4#skK4%l!QGTnY@A*3hiC_ +z9Z;PfhLcAO7@}ED~t@{3;?6Jk? +zWqLB)y&xfECrWsX#UFr^*Gr`7I@)yGizfRpA2Fgt{JTDQW?4;nD_F|6R*q7B4$JLE +z9K}85aQ{!$5-5i}+;KqNh4;jOJ`Vlu9^GdsNdD=C`!GB9@?%Ql^OFty@A=%$K@GN& +zB5b~@eY;F9{}p5M5pWx2_}Q1AQTTh~E|jI8(8PAhq?|Ev1S9fK3i3e~)Ad{=vRD`T +zH#YnP2#!h8+=7% +zUvY5{=Q3>*mCU5xFNa@mpqFzQ-+N(^1j?D+eecDnnV?OK>rL&b +zpDCduWC$MlH^D-5fx!CzCs+hVb`j-7oZ>jXW9~!LaX4N=UpG~qQ|6>H_MK$n??>fl +z=#%>6^1HK(KUCo}akpmAE8l;T#_5YjwKOW$5pK6n!9em*C`#vMO<2h(YA>G8rPl>R +zcLoYw-9%+;BR#4W0&PhZLQU~L4tQtHc_Loz?mqySf6ALiuydzU%jz;7P`(dk>+iWm +z????bwRiGoYfB=-AM^Bb121cbd9nvZ1<7biCp7rO720^T6f{Gn6}&s^q@2RH#_{Sj +zcKj7OzoBfa6Sp5&ZPKHmqCW1um&D0`To +zQ|Dh>%D3vx-aAOGN3Zl0=|+V0To{<&|K1pSaVR|GznZzz4V3y1QX;b$kg3zB^8;AO +zY+kX@XSIzu9Y||$S`zwpl9?AmU-n*p+f+tM#blQJ@z5ck>G%3=K};z{ +zsp54R?6NnTErXo^r{Hkb&l|*|E9QJlsyS1(49D{B!LzV8jR2%^6e3{2$d@s6^`9ez +z!;7Uc7W*C$^N87^z`CFC^Dxu<(e4WT9;sot3X4CBIBN3^;U5MVa5+xa1?~qPe%e5C +zO+OWmUtX4XfW#dBApFZRIDF~_?cTSNv%OY0!t&FdDz7Z;@vHAR#b8w$>P +ztY8I-`F%1ME23Jm_$~t`ubvlwQvs@KnBF-rJ)qWqz&txIqj%g=7cbi&1YUSg-INPBDyPQfq;f3Lj|2Bw&iXr)Z@+~25+6_ +zs!`Ja0+V>HyQCTJ9qs-+4TjPIb3Kl5kutW6GzBDT_I~Q*US|Lyr&72BQ>Xo`6Rfr> +zr%qvDw25Tf45<2WYP$9iov#D~oxTlR+5&rzXj2R`7*?*kUiRC%-^@XE# +zW`KT1J!N8{fc&&AJkQU4eq2M?NG;KJ30TU;o?@%&bA#2Kheqyh`G*I>W5$Y2$HNFO>av(E1FU +z*AkV7ztJLj*KRd}|H9@^3{Cl~=d$xB2~IFDTIab8A4?{u6>~S2q||Lh>?9(|_xG@a +z$BIqZI#5s9wU#sLuSF4I? +z@mW!!yk2=KBSCOOYzBQyb9z@<2YG#rrxG{B+T~_Zjz18nc_d}ewS?+LU399g)u()$0&v>6tfw>2+0>k;@BSHP7r$r`){74)t>1FZpp5n1V5_FIO5rYD<3X)@wR4N>0piz +z@@A8;zPi@>ec=!J?fU3LdEP=)@eIC+$OX7^zxFKkA6QAe+qY2CVZxE-0krm^w9#uq +zE0iL~CG;$&o!_2x`>OB=$L_^8k$Ge+ekk)Q_hJ4Y0-~1>pQqBbYpXJCOVN{mfXwkZ +zph@yOfx<2@WFFVhVwmHFS5Y6a5H$>EK)_?BRbVo|La2+;-hRsX704xtZ?6p +zZNsL^bS)Ani<$)w#5_hZ(#uGH40ZXQAc29Cy-D4gr!G`)R+PFV>SUCGzIVt13DRWP +zAL~>mQ{po{u4fbXeO_|iceavz538AVs46?y6#Z}eg@bZ6&T +za%WfQ(WKpg(8(BL_;noN$Y){p8fz@7V6F5~LjU?Uhh-ys+U=Ej%S`O7yly?1P9`{_ +zoVFl^U52HIr39FhsfvsviL$Xf4XdGTbs@_X^)PCuq+ +zh3S(N8U5p`P*}oaxgC;l4a#dUV0(Ep>!9Hs%l)n@3rRqkYk>##OOL!3g{c{OFubB? +z-;p7i$1JRTWlb{(!pa01H*?MJ*rI!9THp5S2bimq!{VKT7}Gpk{z;ywJr_>iM~{Y2 +zXrnoPsGAv!D%g}mP3O+ORV*1qB9wh_u%!r%i1sYqL(9#gC#MP$-^Gh1CPG`MMK7J= +z{NrUNFdus31X`hcMC^y^rA855#0p1JDk)IGMscj!-H}qo4`LC>NV>JPF8&R5 +z`d0sV|HP4(X)Vg5XK95UTw<40!BSCK=VAooz2<~VvyFgj6Yl-y0g6q{J`$It31NB( +z$`K;WN)|SZ^b|@ZbtzMH%ob<#qUHHbbVwCuW}7%K(Pzt4pkSK90j5WaWb~4|)Vsvq +z$cB8wx-sVagMc(&F4*1t@E0n +z9T0M}F3n~a@TB4Ll^s+cM|H(%VWE2{HlZ78VvDo)eFEw<|hJd=;Ol##5P3JK9 +zK*y1^Rqa$FPN!xDDg%gw6%5oS&il1L!ejX0#=ik9Antr47KmjxEUgnyovZsB$+m^Z +zZUX&EZ4(#spE2u$vgz2 +zWPaXA^7YPK734_s({&tEP@oNYE5l82o2MMJCZV1@D8nuNeliG$a0#>6rw%%SH(wV% +zcH~ts5_=b6i_97west2jF&Si&8%}i&WCMcX+AFZ&3N>}Er8O&yCB%X~lA|*pPAZHx +zzI0fJ4KkrAGY_(tG{_()z)#0T-qIvTL%XAo!>NEgTXn|q_ggeOWWYeK;E$HuyzZ{+ +zzF!|&24XTj)~!U)je~6|KIuK-tfU@h_C^7&)AkQq=nl8_Z-X(VA{06O39LD(;-j866m##%2@@l +z3LvpH?h{!(ebjN4C1mwsWfEZVY@7`!(q@t>-BWJVjKTnBnFjyxYcwptwkwl#jG(Uy +zCL7@~Pskhng#F2P$4a+?yUZJXWn?{sM3lwAOclBC%?w2$#`F>c;3kdEm7RNj9lt9( +z=0-htA@B!J=z{CWC;Bd9X*gO%4I}5{@BI5||g +zF*fol(LD6k>v>5zxKtsS#8mA4LkSbdaL$HoY>rfnQsNqYrtB*{PAeEY=d4slX8Lwg +zlvDT6KDWHS2b=>m?N#SFIKFCP^=$#JL-;7_X5;2pLjQT|MA +z#vR{YxcASa7?#iE`i&G$wE28&h5Jp2$}Rj6*!CrLY^gw(XA_v(5*=ZgtQcKtAE(dX +z&-9Y}_%Bs5^@YpK?d+uhs0J$yP?uUNT%cST+FJbVwh1x+Z>og;zf>iO4hIYOcALV$ +zf2ooazuz6;=%2X8|68gA&cQofT=U=L%LKI0=_B)I%fs$>Hxt4*z=p|LQK@xQB*&HsfenYQ^iRdQJS +z|D{TPh~#%zH_dr1JP4aUi2PVGpZOXS`iB2MR0+|DhI2*m7Sd`762P;V#AJl)Y%=FP +z_<2WpsQ+h!BnOOa7KO;#vzR&=gf{9hJ*~vX!ySY~5)cFS`x=>-&%sx}?k(?b>S-Hv +z=AaT!h--;!tNM#}Q1A2V(mz3yiMvz)eAB{1yB~5O*Sfgh=}i-YQqz4*Vp`SL55pmVX7n5yuJbty +zC&$LL6h4%iQl7O8C0qN?-;5llaGoFRykEDv)R`*EOomw*$#PY&E6eJvhVMh{b5Mk& +zS80vpHU1U#Rf%)bG;~Au?k37)$aqjkOTLvB>_$m(w}R&Ncve6-fW2d$%+=qn2iyp0 +zE-Zk;!RT~f{+YZl44p<I}lFT+%wpp`B+`Y8Ce46f&dW +z|HYW2(t{62)^LBmu{Iqb^lqQHe9*Z#`QAobzCQ3U{~dd{2Q}OMfzY)Q6%FZ>+hpD7wZ6dEI&vrt*sDRtNvs2Ks2=g +zCk=2M)(8>6m0G7_`8(0(B1pH<{mVw;&S(Z9s1ULiJa#aS=vq->X5xj7r&LeAe-X?y +z##ZFJeRZ`JAQ4%WwpAMAxORBIhqw6k1;&~YZpZmK{bQlDHmZlF4&xR0H&ZwbqIS-> +zMS$kQm91K@aaPr1FcZ3RmvaSIW^?{1OG5VPTf8sl(E+SLV`Xu}%jBcAaDI?F7g>>q +zza&8^^B|AlPX|P>bk%({&KX|W7IUY~er8`Mx>us+*%w;qS4Bvqhij+&Kqdc*j$&PX +z+Ba*)`>pw*6E^gcEs6G%ZnGpbJCy_Gs(HAG~pMpb8Eo!gaK>uPqJkFl@7u +zdqlKb@HT&>UCiV=`AkEP(TZ>bB*-;TF8F=_fQEHd<pZT(S|M+95v_FVj(*~y{V(M}PgS_Oo)HzzPPt4q*P-kgr$pU#rwA>3sZvu!U(vl>m|Kj +z%nhc4*irjN<`DwA%kGH7R*CO#Z3UyIT +zWyx|(l`<_3fzl$apW<2ip{AO?atlx>CGI|=BocM0#BX8Jiu;-*G@oY(Udvav$x01G +zpq8{ScsSVP+GzNSZEogcQoince%tz7zIzdO+dZEJZyw&%>T#Q)t8V1>oZU#*GW0^? +zDR`t6HH1BRb-j<4NsSg;0jMCD##CibP-QI;6%+0uoTep!PA5zsku$L#;9F-NC91I> +zOc&$`i#5$TP9EzX(-Gj%tL8JQ&ak0Ex!jv$G0~^$Sqrj6yT4)gL}xY*#SiVry3;SK +zIkBL#t4<||@IZWwltLxvbtKg6-=>KY+424 +z`PoK!;@y;nwNsJQhl}Zb;bY0oQfRlKC1{|kq36~}e0sTQL%po;Hs@(c+~(G56~!b3 +zGYMWK$tTaF*9+EivG%DYHSV#=LrVQaRd@2PUao-;i~Vb(WuVdPdDz|DL9#O8Z^s=xbDHQ|V5Pvqwr +zt`m;cs-d&R=Rq1ggz`C-`OEPmbhQ=+KsS3;RTe@`LW1H#M1`bPh9aN`byF%ou6aim +zbTwekm(#?8XjxSjmZOOITjtDiwFsHc_(7|gW7UG}FO$-cBDMfs}&<$9KuWQ34rM0DA>*2@B&)mcJu!MP(jI>X(>bw) +z*M?)oAb=u$0}l~L(lkz_>mr%Emw?i^@4v#a45tsOk^2>3^2I$MxYpj_L#FxMs3F|I +z=x&P|8}_n6(wiispEgSTW+fbf$tdiZW>OVaY~i~Z)f1GK>k-ED_HK&q9lO;-5uXSS +z-B|r(yRzWcZ9dw*ld1kV=d%;udd*J$lEUoAUq}Xf8f!ELy;i8}Rn~WqK4o2AdK-Pe +z)w|>3j~yGk36N)1cOU${o%V-Pbji?Z!H)05!sbYIvYLOWnpAMNNxZ9U!c1|Ju8nSs +zU(ZNJ*^h4`^5eItV#-lEd%3%%l4In6<%;L!hpj5svBqiuTLX@{xAl_&v&TxG=kM~l +zRm+LAQ2pSheI_R2qL-+-T-RD1NAz58HX4W8?92(rauArBADZ|aKMfdb{`a{@AY*}m7 +zupvF}ldCS9IfXSV0<9O(WYiGO(o3475um+s0L?y5%Kur(E(v(^RX4+{!*Lk8;XC*F +zmo$N-fh+Gid;9pzo!iby^}wd8!;nGOPy1~B-t!?{2X#gO68^bHm6wklxY4U#{!AQ- +z-uK$MyIdmX%-$@((|(?n366Ih-XQYJ#Wrq$?vicm(Vg(MVcQBHJWv^e?67~e#5BmY +z{bGq4sn`vvB)t`my7#(`V7}uszcAwDx%zm5(LH5NK4OxUe~{)>@*X7|;>7Gsz;-C? +z@@3MC#8C!-xMtMdpqq>S!eH2Sp`+|{i6 +z&+CF5M$`m~t2bo#g!-M>p`A+Z-hR{V%jqB_;Rv1jvkQ7NB!7d)12nF=T)lDlG^m%& +z76?F7LF(RVovQuVij-DLc5b>|qu|u@37KI^_yu)mP0egsDP&V^kIxt#HU{t6HH1v{ +zRrvkF46_{co@4o#3NESFeXvpF_s3nd8h5Ta?0)B$@aHKy&(!I&u>V_M`C#Uj)3>?5 +z=G(T>tWah2h>)HYWPEeJdaxL%{I#s&lDu3r>!*rQmJ_|+`g!YvkA@!^t#hXU)t9uk +z!j^M72UZDV%mIHcm3s_*H%4_%6ti6K_lH+!egs%Ecvr~hYEwkO)Ibk3bKTCoKydTVR)~Mq@%B%d{k9{za6pEBQ57KYr{a}Y#UT#hZy`Z-;2(5oGGef-l +z)Akle9@OB=V1T7kQy19)4O?qxpu#p{*l6gfr})iJS8dA= +zwrdaH#vy67K;8I)0ny0BsZze-!Fd5ITkrna*zc`E5d)1r?_iNHD00+uZ06Ka@Rj4~ +z#nM;68Rg=@;Z8%kGaJYB+O2{=E<9{vn?RRMbHKbCYe%`#_w=cPyh@N?ZR=vW8m#h- +ze!ti-_ESdO;HjJf55CGBT_;tvi=lROV`(i~ak9K~=>#&8-k*CrTh>kA_ij0C{<|q} +zQ%+_H7V+8w*Ml{w;Z3=C|G_c;3vnL})(keNB4&^BG&#owWAr*?lu1?*mTw(pQ1tB= +z11tV8>o#@J%pqzfhL?dgX4TR?oV868SKFAo>4<&U2oo5D;hsF-_BCs +zwibbcpweC|uqsEK1tQr0n=kKPR>jv6Qt1)Pes4K3I2xXBqz+<|bU;=HXgi*IvV_~7 +zUGU|7{<)}!X2RIo=KgM$EfX13)KqRnbH?|nNPBr%Jx%;@!74YWO))ITNvCqi&)t#! +zt7+LU$hyn6c^Y73E#9m!%;E56Is}`jdlz7J=4th&?X>h*yz2KoaxG+4qn%1GeF<+V +zh)bzV(zXHxs@{QNpm>IoQEkdG8J-IxqO}83gXUsa1 +zzmtB`WZdFk;rA8jWSb1MD(U14q-_dn?BM*HvMBF-_w=^vw7>Wk-~iFj>PTY4Q_7T$ +zkh7|&kBgVptzdt2I`|?YEbQczHQC +z+$GX~5#c0-bgVfV3i{sJ?Av(@>w%|N9XL@qWO=&iExb_;}^8s@(N@uvLtpNiHt8&3FsJ(o`%4I!W5YRXKD(>Di^gjxmv0uA2~9RRr$KXEP=~3;D{r-qd`#_CS8J;7Z2y>Njm&IhCOlcB% +zX*ZJRTJ;%gUS8dLuG>_s*7k<;^XL8P(D_?{rLB{lTX}vSLtahY(g6Xjus7E_E@pSS +zwy$Gk?36xJj>VG802*TBcFNYh6l*9Lf+ZuQdk~>$hPeOKKZH~gZMNO}ZPF0vZ?iw> +z(#6HWWwP(Hu=DAKxJ{|PS*kdvUFi{nSgS1ul1#+CdXuAp?=O}m+y(0_hPdt?zWKRE +zX0qtO;$!pkn;*VxnTBe>EU7bC8rXmg+A94-uAFB6oQ*_7mXu@Xb%*z12XDlOCK4ie +zhRT8uqS(hrX!ce{tbr7CQAcs1hy8AcDX_)b#LH&M7ESY!Dfv2k%&ck(zS`J3Y5$kK +z-2!=<40)QNgq-VwD3`{%w950spObEe&zJapQMoR+F12_hGnjQTcigZtrcWS%3<+dy +z&$qq`_4gKBR47RFx-!aByUX-U;qLBSGNlE1OffCE +zMW>Yn&2n`IOGVQ)lUesu_OfEQVa-#-VR_~I9(&WoTpd!WzI^8GiHfVkM936R2l=*) +zc*XmN?KhBUraKYW8m>Y$3q3c`nT2KV%jL~atH6l8|1P2C7P_YL +zY_*wl3LAJhiNsXsTiw=cTYDYWRP@+A;!e;N$Oss0kYfb;qn$iPWHfyqSmSg&&h_!< +z|A(xvb?wLi%0PLqe9$`cxM*0f&QBqdN8;RC|Cpk;IvP8d6JESEIrlicRUCx2K7dCu +zEoWC##`A_HYDT&iz}Kc@405CGT#2QsNs}@YZ;$zWy|$&D+fGt%?EOPHHZh9KT*-E! +z!7+}$&4FZZO&=*dQ|V%*9Hqcb-=JEcA4nPP}N<8IvDAxbc$5uwQWgtH!RX% +zpAk(qD(&*c6=Vj!Ou1Fs%Z%~OLu8<~I0^Y$Id2E!RHu(ni0(ALDM0KaFg#$6@ByG# +zVh6sTBwO-0Gi$@yTO$hw{^Xf-On1ehIYn|065jqAwxz|nA$l{ge +z()mQfnENqjQ<_$Pu_y3gT!=G{{%Eu!NBWY?1 +zrau_uXbPcbk0)1XlhN$m^elgq(w1`50F~pU)&45@!e^HjntO%g^Z&8`e0xg+;m@)`8>pt5A|Z_NBh~@Se6{t +zt*+$^wk@PhC%=Eu9x`dpXBsw?`2{4atb<8-+c9t!XjGpxfLfqC@kb32m;=D^7+<8m +zrM3$!13f1N(2c3kNp0&clWMdR@5Mx7O5?h+eCkHs)a#~pTS%R*A?!iK(tsu)+p^eqamxnkI<19e7h0H2L1icDakm`J> +zpW7nygS>2kx)W?W6TKUp?FWCyJfbh{VDH4KyxbJ(18W_ovRnvWY3H2GIAZnjdPk;T +z529{9R~4y{T7{!b(=!)C=ZvE7nJ*rK4lbBMyR@A$ick+J&V1L2EiL0!?mP3Ysb3xr +zku#T42tWAHHY9B0e{G*;&v4gBErZ;|dn|x-eF4YPk?xDNj7E&VNoncYcxSY~-V36S +zwF}?4ieJ6@HUIGTQPX7-UYF1ks)qt0l<8egrvp~14!@}7(z4Q*BKHj+OzWb#=>r+3!ACjdupHykQSYeyeUJjNoK4l0($f +z&qeHNPO-B~XVx^AL#tDAzdCHEtm_*8wN|6e9s}YQhPI1sij=ol<>$aT!`Vh2FS3KL +zx3sfseB<8J$P4MJkQ(WSE0(poH;QmB#)*!{4e+=95U&lAHvL4KC)#4}GF-RgYt15C +z=-no-wL9~G1T{m1w-1s75&E_Qy}4o5G+tf<-`bYEd90UO5WknKP(iw!h)0I1DA2)k +zlxR*KD_$hJ19l_@M?|ehtH({c(##SWTOS;ksD9@Ysj^k9X-p`D_vKC}^8x04ayWMY +zUdP1C`OezLWy38!e0M%u4M%)PrZmE}`9uu4?M9WJi_-emqvTf90Fz0C)uqybdh}aP +zi>F)_9Zubkju{ +zRgJE4J|#aI{m7A;Dn|EpV>D=MLA8-7w7b?Vv9)pHD8Ry4ZHIQtl4|atfqK3LCeFjn +zMQqaN4d33Z`Mul5%S)hIn=k;>K0i=1>unMn`%rs;+Hi=h&H0;#2H4h;{MNVt=gjx` +zmv2fXH{VgiRsMFOBZ9c%=Cb=;x0$(ya!!WcO0Rx`T#>h79wW^rj@Qpm_sP#Mr{!>$0{?_w&)Z@ +zSW{Ui#eT$`_`{KK0ninuw|vn6`Pk@toI{c-Rk4u8CB(lJ^CFF11fl67N8&4t +zcqT9X`ZOVXbtTKI;mNZ_##a&oq5NN2x~3R_R1)py!osvs(7YKlgbxtDZfUDRC}b|>Vg`kL5-pRWHWXtQw%?|c6ezn{P2caFzGW1ui0rbX)&erwHFfOj5RaT +zt_^&)kAChgG|-2KNQJH`3fpTLoGtnJt)>CSf2G?ogHN+H(rZW2pg)m8MdiDv`{@0{ +zV#RZv_U?M!PW3*I_DtU3wTbgupZ(nn{f%lFS0&D&c)H9^7Vlp*?-b>v6J%_{oeLFp +zUF73_j$fOTYQ95S;aYzbRy6mQy=C-ds<>0=vKgMSb{wVlhK@dUmlq1(bh?~FUaGy? +z49Fe~j$Txz;`5cKALr!0$Uk7Av80Di;w4<^TOphbb5qO91$Q@qs?q$uWs>Y{LQ(6l +z6PVh65*DN=c}{qx8x?{FK;;(UMM182?7Zlmo`@+1+-GFH5bhL@4I%nfuoaMA?auCt +zhKAsTSUrVe7jth0tHFfEnA<++DrUfO1aOf&cBxHjqLDh&-&q>H$fx}z#1-N2b;)}u +zEA{m~x~SPQd(y11z2<6k4?8?xv@@-F-I%Q|`>Um4^L?dJog4u(c?308ka0f`C>-9* +zd`4Jz^VhuXn%jx(M(09;ND&Wf|2;=YOMSW#)3?7^6lWt^TYp?xzWTxzQBi~XTD)6* +zJw|}B-WZ0Tw=z^&m~Opj?2dd((_2ty+R^_h8`|vKq8Hepr_dT(Qcf8ifK=x3Ly +zmPx4Wk}LdZ^4XXw#P!rK(_&O#?%+?6*t`|;xK~`=>Tu!ouGC*-&RFyZ2zwqo6a})= +z#&@(vx6c+^*EQQ}>Vo-ksKHx(AB)q@lhFwBxk&OmovQ4e4co}+Xy{)o&#hNg(|?qA +zJ}NdvNg8koXJBQtL0nJ#2DA8#WH1>{B$ylkUHlm;%g$fUT^aKg(c7Vr6gzeT1<}y&8XW)NP$#>R$QMU6_fZ>95qz6e$G?|QzW&nfQOD)7-jhwb3$uFbZj=Or&-RDT^4du+D +zr8RwG9tZu+>wqJEY1Boc1c`F4>6CSDgPeiMMiyVPHM`i0aO5Sq?H^5qm?Wz&Yndsm3YeyBQ +zmF~yjqG;BMn2L~)-#?fyq`w+yk*v391l}d&FwhtL(Ep@WdHJOy4~ISclRbW+p>NB% +zWIj84ba^}0P4VP-dQzP-3jys^roC><^RdmhH@3x?Wsono7N1txUA0Y3>2j^E4Z)!u +zIrgrk58i~u=v_*YO;2*eS*AV%?#bz_Y-4g8To?+@CYYGHga?1ZDumOy7IAA^Cz`|noP;58*IWU5|A9WSlTRm0&&O*&(a5cJAZaR=~BG+0Lp^i@W+S^=~zmLz*7l3Ig0&v*zO> +zTH>jn%PI{SE3|xtrDXRY*WKT^3Ti=B=n=O5A6>kv#Qy16mj}^(h?NDf;sEGn81iur +zLgz0NuNJkQ?GS?}7RHuSd6o-QnKdDZ$$(}(7h +z)dqW=58tnAweoI!^jNyY@;0vhkqRc+p=u-8)$a4t$&+QR11F`%b-x*nu0BgmY|%$p +zH`}J?YF&DD2|Qt5`SYT@g|dCn%=7lo4>yKwJ9@06>Z?8%h1aA|Hr +z95e0C3?4CCe}8+Tlt1jc(xSf6x_Vqe;mdNhOo^W8Hly1owpr#?eAS+qOGX`#C3K!l +z=)bSp|Jhder`xmJ6zjB~36uTf$DLZsp2{4~dISIDp^JNNtD-KX*bJ8@e6vqU_tlW! +zt$8d6bv!_JOu9R;oPZ@@_2^yCJnv0chGfjd=$S9al{S2FJmV`&%X;Z>;cCeF*O`Wk +zlsgR=%~R6s$hgo3PkTf3tJ{v!kf`;K{5{)#uB!F;J430oM-`)XHf81oD;cjdv^^lU +zcI*eua^5e;6XZ?L1&^8LpW6sB)%EPnRxtaxa9=-v?`bK&rK^lE!wb*PqH11O7}cHc+qo})CbY)KCx2kXkgp)0dp~vmJq%it)py_SSM?ejb=B~tOIz~} +zm+PYLKF5E$o?~NQ*Ir;x?)Mn3vxIy&{@YRv)OX>9Gi?Il<)rH0vfW6g +zCig#PS7lwo7*u?J_J>7(oC>C2|`RM+4jN^<^!3zwKo{ +zEXxk_d~l5F{fCR^*&y2w+2ffuXzb@E=cUe&-L6Y3&OtuvHS#>yDVS>UVfRK~wTJF) +z7lWlvb-%XqQa?Y1Nnv(7H%rQ=>c7@U=gs7Gm!qeco!-rozRCKb`e==ryrFXR2(!(b +z_JVOdcsG{w{;tXX1EoO)FK}T7@ypipJcOxgW&Tm9jm>B}m-jyLEtI-)_HC}5(>Z9M +z%85T+4#wAonQ3>#UR=76|F6!4xrsk|V{O& +zPNw}$%gfFR*FwJ5#u$wJa-jZvXwsFqcjvJevR73e{_a-h6D@xXV|8s!4i(&tH&@x0f+w#Nt#stsFUtsR1lgHNT +z3BOWu0*y;D+S0=OPTYj{PnI`6_5Wl6NRNSs`f07)JA8E9z`wtET9kW|wEDbBL8Ies +zxfQnea^rIO?bhx)wR+1R^s(mz1Jm@-<610xzx>H(lAL`iHtOBY?p;}L^6nWfW5;u@ +zMIUgv*M0X%rGuXN8Q&AWRsRumm0LAK`UEMKqmjPzPBXW!46(D?8Nn*(+5@Up%C98L +zheuZ)_1b>aJCdj>JPPl&8*;t(YX2W+)JE6F{lA$W6P}fE)o73ZSHJUtHg($!lb(7h +z!bj3#RBd3JZQ^c(W=|tO(xC9em(d?R{sC9U)n|sK!c5CkscNQIQBzBs-Bn7(|J&m) +zr$enhITzn*>m_D-Y((9u&*FpjUr5YV)<+ +zAfKfCun{75WtEsPt`8@>bs&_PUbE-UD>tFb|)q7&A +zW*|Q~#Ud)EA8p^Cn?9>fw&)xvn$Nrcb?RntGs<0kJhM4$#M?&UXyTP@GEQ{Si^!qG +zY?)u)2=XSe_ib%7^f(1i(rTyI-ByDepH?EvPK~5n+lKi+PF*#Y-(ZbvWeW)pyX};d0jOr@doY`wd(E>E4gc{@uM-v#vemS*DNc{2cyswuZ-|Cr51@ +zxvJ*)_@okL^870gmHLpo+P^EAKD+YDqt@3mcbDNs`|8Y=Ix~mCyAB5@z}Djnu%W)* +zcl(X;2D8Z-MBbyTvd_;en@p$op6qfsX#JA)So>+WO5HuX?2IwLm9^H>3xlqb)YBaY +zp4qPdN6p-D`l_4nYRmTn_VW%66%ARe45uZpNd2|Yu{nR$`T|X@?~cVM0%7aN4YywE +z9=HvARH~3SGh^zMlKy9XhUSVc`vqQVYA#ITQ2sn?S7Y!Kv=1BI +zIUI4rV1jQ=kY8(yYUD_B=GBR>9Ud|VJ$GS_&g5flZ_0&LNjI53--llan+$TQnmPEa +zIq5OZ(MmYRGNP9`*Dt8bKeY8%4pMl6mGzw|YBV&Wk(oWyF$!&^B#1z!Dh5{p+t{7? +zz5lYu&-Z){udtofQf)Nss{h~Lwl`J`zM-v^h4}wO+aC45ZTqL1J8k=YYK{tRbB|jj +zE_ukU|7lQxp*Jm2)ryTFS +zqAq)nS@QY_v#G+Dim!BwKNH<_V|!*kFtTQ|x%&*8lP`&{%)=PLm?3!#gF*2|r5Df^ +zV!XMc1PfzKf=9%!Rx_Z$wIb=Ce){S6fE3tx&1%$8A|Eb}Io`OzY;w3Om8d8q3jf_Z +z%>DQ1Zy%IS=A6`8sp+^;RV?UR*|((^R) +zRM``6diYdFFriU?LylkZZYg@ab)5PLA^#QYvv$NW8rgfIUQs;^aap +zIClE`7_Q^JP-1$o&a;SFFM3y!l@v1PYPpifF~;FHF&Bpp1_4##_sKTzlbxS+_l@OF +zuM9sCH{3N_ku2!VMA7VLaO|Ad^`~1Lpw-kO6JYwBN{T4Kzh!GccEUbQJ)`XD`-~^z{fsArs#O~W8?xXE;_CwyxuzcMWGxh$5<{_j1JM7z# +ztJ&_jOwj5L=-bGyjka(ks8oQ{#xZw!WkvcvKC5-k{1Tudw6;?3v>mmG`sq0B@nf-4 +zl_Z0S9fvismi*W*foWLK$t1v04kbv$ctow}9@LUCfUx!spaCLI1 +zR;0Qc;kzTF(s-LH%yo-bzhs@Ph!D0~;THx#r$uE-l3WnryvYPB4N#+ccTs=kO95d_ycipAGxxP=(_`+N +zMF*|gZAO!cm|Ij(1vp-mt<5B8$GAXjLhp<&+n%DqiG5(_txdSzbRgAFZ$+ndMo;O1 +z#J}PEwyhp@qf74%ODCYkhq_A-zEyz|C4yT3^)%u@OXR#%)rtjHAzX40V6swe)u=N%vHH5Z3Q~Q@*CAJQja?m7wgB5_^qn +z>elUDpe8Sspp0`dz1Fn>zI@!S+G+F;R|5NCd^KD;_f>{l+CiG?rHsNh+3|(tlBZA3 +zq$YBCQspi$1R6x&* +zmo@q|lFUkJGBRjctL&JXp_`sp9p&%IYsQfVz9kl>v=4t1&UOqsK3$JOXlau{;lpn# +zb3l2{14+j_ufE^2w}!SC!&OxtN=gf9|27&(eU)#$*_z(i{n6p_04Vgy`2dak{Ji_% +zOyn&~*T%retAxh~q>;{+=V6r}CcE!P8oW2x)G!^f$ymr7>!xQ`-CTCxYJD8$f8I$E +z<+7Tq)>p~5S|)mFp72sNwQiF(YU>3F5UW5o8|aoi{vZN$wk6=cWy2tW01ucw)e?w7 +z!*cATU_koCdQ|)6B^&*PS?4E>!53|{*?K#FwUBgWj%3i1!H-WFYc&VruV_E8w8(jU +zS{qaDs?m2ykX6`;;R-V1PtY_fiHa!J{!YEVS6???^*Kjg(rsz^HRYx0MdxXt5n#8A +z5Z4tgObe$0)SLjQ3)MeL|4rr#Q$i(&0~tghXcf5ewpSzFx~SKznRD^s{`>v?r|M38 +z?R%B4ztEoYQp=(1QHUp0%l4@MH{?A_2Z268>iw~x|-6PL~m*xO8egREvkT_$BRn3rS11ipE_1GSRFLcFk(#aM_+|p$}T}*9Sz$&^<8>Ss7>B9Wpu-vidY=TOH%)Dl#x4-}V;P$ua +z{C};B-rm`C*2p%vqNlBWIrp~A-H1E43NYH%OLg-_g(ce_CU%Q)&z8I|Z#RjWn+1bn +zQ2mxfX-=ZlB_?3EIEYj-pd*nWF4pAqLuRG^pmBg@3Gn!Gs~EH|yoa`hq9O7CUjZNq +zw5ry;$e2GV^@kT-$PaIP=i*Rta&N+_o;$il%f4SOZ8Egv0p7Xt19Qowp!wR2+vRut +zZ>mBkFJu+*o;O~OdJJ4uX>;kKqGJ7#D=Hlcrp3#qZ#?EMx!GAyIyZLy +zLP)wV6@b64cJj!&^#x^v1kTx~m)a6JncGK{b3vsZc|f=X7M}#XeytMzV$T(71-=mhyf6UCb#W2^1HZd`axpddRBN~P +zt$o?PwB)!=PU*5*QEx~4ql?)+_HTlV+?VYymCZjLiQ_%Z Z1tvmwki7)c5z&zMVATre@0+C^R+aQ;+}=U4{e2+ +zoHQkOSM3nXfCv!9-B_FBA7HX8k5cd+J2?0UnfCoJH1WfRzQK3CzVSR=r!p$pu;PiZ +z`^J&XxW4Mmh8mQ^`hvsqnVPf4`A59EdL2M{9x9FludTjsHjLC@&T51V1>cRj+37Wt +zw-;wqM%|Dmnl8K={?eCo~_=WEf5D(%GK?;W1i +zT{6zE+MPfvN3|SDZ@lDm0yWs66W}ghO#0OKc=9zl8yR}fkuptxhg($rEfZCpAx{|) +zmFy|hR?W3~W%WJ(R06H;g%VL)wc_|U)zDU->>Sjw*WG>Z%3fM|w>q3!))1~==Gd$j +zY{sgbP{<>Zws#JNTSVPV8)yQt(N~kYFQ*e5aS^gjkEb`5H9{jmujJG8FMWAO8D`yRIEY{q)3$mf~kHSCr@rE;E{NB1;d +z4>2!ctl7Ep7A%$vHcCgbQQI;ZTj-W$?y~BWd2QOeTzz!ZSEOEMNRMm|WqUL`DATWJ +z!1MP>tFNznpWEQSui331&+5}kPu+}N&egp!W*^xjZ{s3^8hpVS2yV}i@s#WMt@N`=z0s$0?L?82EWaKOCG({t<)+Opf0P#v-tmrDvujoL&wml`sUE>9 +z?!LK8*&h{?C&<5bb4y-6L?my_r0bMK9Y#S!@~3#*$+D>AH%;(l6qh@Rj!H&_ilV%y +zM!X0cTZ6S^+J54pcZbwas+Ns#%kcV;G{(QwuV_uoa^9ecpZF0StdLGN(qG@U}8ABAa +zP{E?>3l7FGh@!#5B~PY^e@L#-(Qo-w@On5T<;~6 +z+8KKNEB2o?P9n=uc*33>+n!XE*Mw_k%KHuffSA0-Pgv5%iPQ37B5ukTcn@0b&x|OC +zN6Q68)tj+@qpgUh~oOBH2;hp(1#eMhbz4Hsv?y|U36xJO6 +z17qOi^Y6c9o)mCT*&C~N$VF*{3-5cQ4z6mvJ45WrCq@nv7#!WCO%Gq0K4 +z)4M3|={C8icZEn9<1jT~k#nGkTYnGncq`Q5wvgMRz&EQU+DI82$sH0mwRx{SH%UmL +zLHJ|^Qz?=@!-p6>^W;io2PEKRgCMQnWXun +z(kSqF18Iw7-OZf!9o!f1#}FgftERcHRA_Q78sV_9M(^sc1(bf@^-{-(+-KjRIR;FY +zEv>L5UjCZSGRxNMV`lun^YrIfwzQ9#@i|xY7%W?_qQ-|$QVv6jz9+ +zqjy(4MKANtV_I=sqlK$iF|ET27J4hek9wxJ&Z%?00cur0V3)YykD(Ar?A|%ltWBhFF!+^y>sZ&8; +z&0-<`j@~cV3ZMr%L;W2?amE{*$}>+P9-8QHs#jJc{nB|n#SzBv3I8ROD7o2rZHXGW +zWcLedaGf5H_3XsK1$2^Ur(8>Z}PR;3`iI`!(ToOQbz5NIc*dSTN@| +z^BGI}6z!rnJv(NYS?=mjuRD_&-;%9sXNBb&OwEoN##K;uCgT!zCXraK0iAEK(sm8k +z!wifGGR2iOGz?f2N@1+caAlmGp^cQQR|_?aIeo=oWOht6o<7*v4PhR2wF*ZE-lP@F +zNL^eJe^b2seR?s{UDj0<$6ni?o2{}F6m2ecz#>g5B7E3TS~b)^>v>mO8f8g0KV-z+ +zBqEplL_RlLMedExl1uK6_t{CQUzsf3l8}+-h4$?FAZuFjq>Vo&gfa;#2^n!V;iCkV +z;~U$G^@LVF&_S84}%mBl@ca; +z%4@TNMVyf#xhmmTdz&O9T)kjO3%UO5T$5n%`(qiYvw8s)XXXcIdx*MHg^H&OETt@M +zFj@Ex?&AfE`|JCY49(X|2}f>dBP%@H(O&~I;9Kt}pYwL~Am@0+$v?h#Vs+QfDI4bp +zdC|KnH#hvGj2(_BK}%n0X)aKZSMAV^C%M|IQMC@7bf*eePTe~)^%HcmTG&gn&VT5o +z;o!v4<=$JauG3xLpBor>um1Y}B!iHyEX@pZsKs_K;Xshe)<0~b;7ZW=Dt+}B+!051!vw-q87;k#jQM}Ur +z153Z@0!)6Aojt5-p09U}$Jgd6CC!IIQ4I-J!b9%*e9SDEp*)q{(l$;_2n +zEa~Hhfgwxr?Xv2qtM4sGlTWs8VPDCtDF!XA|toTD;BBX*Cj156F-IX>3d5 +z%9YwlKX%@$L9hUS@yKN<*H^#u+Q_F*%X}T4P2Xn+ZK?R0yH7T0fwDzpq-lafk*%_> +zG}9Jb$2*d~eG5Ekyk5B2n=vi1+}tfLf`+1#Rl+;nI!J^tlEQn1T +z{4^#9_6a|H+*P&3_gI;pYdFN#^f*{2vz)T|`l7Mazc9iLb&idPZPZQ90D7<#GkL%c +z6;-#$rzsbeAKrRqqH`yl7o8$sXRsJ&Z*Q_#fVoFyyd``%jv6e`neD}!0#4%fjDzzF +z(F~bgft}V{)mXq)caOb+|2({_@Q6F4%a@&>U!rn)+0^I?*YHZ8A3pZA{4dqKV<~|a +zChbNl-^PE{XXT%nAN*B+=2pzfzLvW9PbM+G*Ez?*A@1dhA~jnqh;6^{u&h~f&lZ0= +z;A*p0{nARu;~KhmRRy}xg{YQaC6Qr*^htfjx}_6!XPqkkmEv$9 +zQcQ5St^{Ng;~W4a5Ag|z0Ry(R(4$YqB;yl5eUxPIfVJ8Au9fLc?r3ENplI1K%_O|W +zk5JArfq(xwQMwdZpsK?8VtomBqQ~R?xHPTbeDeNk;KelQS4E-YHt7#mK5r^o-I~we +zH}7a8Ti_({2Fvx6Qm=#F}JLJ2h#Z +z9XHR`flj+bts)L7hBS#Pp|~fuib~@fQpr^R6A08a8czUtQ_Fgcg$g43&UI;Tv6X2$ +ze(m7cdUp(Cv$i7)QRmT?j5ekO$A}{NbV6l3_ZNxnZYAAhmCa~k=w(9&Yd +zXzW}bxT39w^D-1_F{a!Uz3(-=sd8ias)wp!qpKI0@v7Ls&{oohvFU^&x^pp25*q~; +zwVAuVpkx<@*jPZpz$Ug&mKrgi{cSyc>K}ZPzq)kkud!g)=kY!s#rR$<+wfd6xIv7i +z^5dR$ZG_si?VdcvbU0$+dJ>_&gnmSd~Vs?S7Azll%F?tDm&BXQ^G5 +zdIx7Uync!+;&?Wt4ixox7`_ofPJ*|)I>7ysdD7^%e%t1!eah+!>v~(Hs|Ob>y-scg +z>!NTEj%UNCZe0H>W^+&qB}&nhZ*C4-2-!0vA~Uo*ltdZOa92}&jz)4Bi=Eb&#`9?@k1@!6ml +zd{dy-zAlZpzgmEtNH&i8YM2_xNj64PQgl*;TaRQ{#N`9YZ!{^u`K+pAhs%uioe-*T}t?_~k}d +z=~^LD5ny`WXc!Sk$-H3zBNEjx*=1Vl +z@ucwRE6j(jTUI`}YG=mXjEv-$mfr%o5Aq{JEz2*cpGehE>iLMwk}Kgo9e4+Bf7(4$ +zw-WO0rHWgXyUMieQ5{K!$-2kLAzr%>X3~pGaaYN8X0UY9df-<>zI|ua*YJ-h59exR +z21`F#|F?Rc@_6D+hih5CNNexck}d}wF)Wimc5mroRUD?SEH-@js4e)$<%O2KoU!Xn#gqO!?)vf!^ABS2khjVx +zRrc=XqEy_aAa3QU{$u`@fNXcE-L{2s6~Xt0JV+Oy0a1i&d2B}H=v9#f&Wj39tBh<8 +zbsdpS3wC|8v}R7NBls@5h?ehc%?pmey6}&p*oAdMANz%Lz#SYW0_u9Exjg@fKZe^P7nG0S$ua +z1W<&l;{YFKjlen?grzw)i3ar;S&K9ZXzq~6MCyt8mZzCH{e9=73GC(Vucy2wHd=I6 +zydb*LPEB&*_v26GVMG#2hN7er%OUvZJ{HIZt{y +z1D}g7n@`y|M&}+Dl}UIp;NW<1Q~YPb#M$TcRk*>*sI)>0@f2Tly7m1A^0g+YU}T#L +znJ{w|bV%#BNd)nqsbgpRi<-Oi%044jL;y=X@Odf1Yr-1eJ@i*abj^Y0wLB%l%&Ge8 +z>_ad_BJ=$!rLZk}Y(e@u^%Nhrvnko5acl#`_zZ4b&u<&}3{;(2f!6MGYH9|Y9!}afsFK1i<11FC2rCaDlNq5-u1_qQY)!_8S}mHUL3CE?T4ErR5JRJ +z+x)PsKSQXhFhr1o!!SB;5zqE57O9`TG?N=$^UMgN8D+Qpx>6_EZXhW)JUCL6Jtp2X +z!h$vr&KUdw7q-|Y=&yEyBWrrv5MsB^=$Xs}k8`<^6_s~7V>-pu%A@niZm7p0DzVo! +zWm@^7oD=)c%oO2WjOG;fNh9j+zpRnkU&T>vfkrpqdj&{-C)tNFf8oZuU!Y0RrmWAEk#?4>7H%?6qQbA(7^kbL?v2MK1#l?usWA#*7?41Mjfz89m`PgkUT0oV9Tge9S|e#cRexQxtzO(i6^2e|LBjE${LN<0CS@R3Ht6?S67I +z7b0WbQ)${I1)q@~p_69M{U3ch>@!)Eqwg0H`G|oXwLgvG3*wY4NKGg6nlEZ24Md-w +zd%@36r9GAXTyAvox0M+?=G3pA!DH#qC2s?5YVqky_Kl$5!ng+Ke`7EED)mTDq>Z4I`&2svWaT6~|m&@H6EK=FEI8-a95FqsY9%%|QJzUQYu +znET7vTV0Y$r4v>*AXsPIsFMdMQ|$j+4sglKq?&lTL(L9+U+~)g6ujgH0b+}M`qcGQ+U5?Fg9X}Pep{Lcp>J;L)^ +zAO7-)eov?O-2Zfg|Hqob{9d-wh^uU&QBV{SSEM9Kt`z>VJA&f&@&$oDoU7RNd5p{a +zZS&u!Xs4w3osvJq{}S!u?_H6eQ2Gq|9r5M=@tt#<|ltXgu4>|av9y*HqiE~!#KC8MbylXU`` +z#ti&h?zXSI5?qY9N#AbLz$tu?#m?9RX-|yAy2O?3tq;c0Li5$AbqT4oP%P@MRFP@r +zfsz(7;Cw*zJR@00G^)MvzH{oT*FcGIng;O$*YZUYcyx!fs>;P>4!Q_;dx&|J-PhN@cRrs%>ZGM}ugg>^nRZ +zNCn{p-ncR`BfQ*7feL6twp)yqB(_Ct4q@4fomfX1F{=YI$`+cz`N^nJnqIUCohd>| +zxcFO41-S=i3m*)OjXx$^F*r(_7DenKY0-$tx&j+;i|q559Q24eLX+N39u~||d1!%a +zgm+k++2wpB2xMpZm;Dt +zLmxPrHoC6P-vT`p=502BZ~|YPRll#H58Mqsx<0f!*Ag(Ji@2z*5z!yxBKpXbr6ZWC +zHdYmGsst+G#sR}9%HBE((x{yEk*9DS-ODQr)!!oAqjpd?M__lD;x*+dOGm1UPp-7J +z0V>LrF8V?hj>rv1Qc*);!@|Sm--G=aTuJ#bbT&l7<$L4Uu47@t!aM^^FT^fEfV@ZT +z18t4K9y8(B(X5(c)(6s3qzf7#T!15iY!L2Avqb%w;qltMR1K1Btps==G~T+6h*S;} +zI}L?h@-=iF<(D!x1YqLW()S2F*OVoMnvm(K^$W*cDtTK1%3s{$0UKyNPZ9w$78aRQ +zzd&Malo3IYnqh%tmxSBF5(*yXCWFze&B&bvZp3k+KM$?fJHwqS?0y@=ny02y*kpa!=xnzds0vV?-YJ4ZK1-^pOAhDOG| +z!@DJj=|;~;1kexGHXphuM&C-1dni;)+!_&4SA+r=16N0?4XC)6*9?icdkJpE7mkPy +zG)u(${m@FJuqdPk2~@(FIa0)~%n*&h`YI6!M=~8G +z&kV(HEQveu0`yJkOK`R#9}OL>L?B$rbXu(f;s(tLZhXCz3y_ +zP{X8BNjp>ke`=8UTW0U@s_(by3Ror;G#WN6?2tUpU?Lfz+Ua;JP0@(xtqULt@Kde8 +zuos$~fmgG-uQ5KeVPD6rarI|fnQ%To>2cd!>;Js{y)PVm^M9e$wjd$btB;MT{F +zT=-urR_u>1fTXBCZ5%p_fiz0gaw)Ru_+4@muH__;P4zbPfm^{HGnfFnt+{~P-!hJ( +z_%utzPJSq&x1j{5K|-KM0N-?crxFhh?WjZmH^}rFM(3eC2N?BaZsbnj9a0QVda0(R($lLVX8YUGO3==~A +zI)Tw8dlZ5}hKK|e67B$*$41aYw^QrgNYS=CH4!i(#FJ5!-OUo*4SJ&=%D^}*%^>!)c1i;U{(z(!gu~P`sTquLAGp;F +zI(ZHTiP+Mek%<2Q;b<#DL9`z_hOtTCJ2n*l8?9NI!DlCI)8XGL5hhcX38U+736Sfs +z&?ex$KM?&5MS14}nAYaD8W_1XIh#SY5oTBff{3D=Z8t{;KdGrh1&~= +z3Nis8qA0e_@>V-Jh(<#i^G0c)LNWnCvkDlmM0o9#P?f$*r4>WSQVJCbLL}TgER!1X +zqa@yGkPZqrch5+~UWiE2icnCyli_RWP0pyHrA07AB)Eu(3<=YZeoVg0gw2l`D7D<9 +zrD-zwY=m&6*`Lfh;)f0~AQVFyE$Q57M=U}xvuYkdsYK}P@MzQ9-vz +zYHB@cw~NHzMtInmh@zyr0Cu&xJqBQx(IrO|g3SpavGyY(d&9)d`K-{pB!YeD)))=d +zWKM?x_QDaTDkhc02#rdr^upU^_`)Rgy&Wwz?j}TV_;(D9(5v7 +zOvicu^Jr8e2shAW#=xR^IvzVsvtplbmcZ|m?=qdlo-TR3t!BjsLSz14Ae>y7=6liz#5W>Zv`Ic^ldyFC5f54P8?7QSk@m?5GV|B +zs8)N>fi25c37x$3IevJwB%G!BX|;joI=&K~AUKwaTUiiCZlK +zBpVH$3)ewOBbjAw3q{I^mRA{e&}ryxks$Fa{ooTI`r`G2kyY#*$qAeeqHxQ~3|CL%y9L$S_GheEp7oKHVbz)Bj61X +zE%}^M!&OnC7#0$Epp&^tTx*crod^i%RthM^G%ZB`XNrLRH#)GT9u?Qgvuf+a(vT$K +z03%uS)f5^+RPmEEI+VZUG`i}Jkz%88uT^(@5k)xFpRQ8$d!DcAhD +zX(9UB6oGKqaxOdxP*5a6W67}pAX+-4A3>*)w?t5Q;DOHUEsJnx>M3!fd>#<}v1uXt +z$`k>*8%2#5>mFAm5e~vaEW#zQAV{Z+42#+vGs12QTHTLiO3iI%#L);!nAHZQM8!_Q +zZZxb-l6%-ykkCn8n%iQlmKmh5RLn@s +z6JQ{=GhmaKNsOftP-UwP8Kxq^T%e)W*s85U8Cz)J6wjG2wZ4H!8Q +z&(1zXL;yui3$904RD~FuYp&$f?M_N=D~mI;wk-gc8Lp}pikq+OFmok=h{y=c%WmaR +zl^#K-)e6PUm#@Vw=(1CQiAJXeqmDKXwQfv7U^66{(b;iSb|IdF@xMk<-NPlY5J;yu +zv=$*aOuz)TWTI)H`qi3$T;`BY+@&dkXg31|yTYHk}#AHs?>+c;Emnc=Ee0gaIGZ*)u>E8=muv(o8kfN+3_V1HU|Kqc|nb6-nz +zfgtY7K!Oy3(qw!cz|}M@L~BeD%;Eq^*V<;JXSj0$nBA;)9mp+RZLl{J2|mn@z6Y*t +zuI$ib90m=Sz^ovh;;32#N-ifa4Y;I74(kQ{fwgrRj +zNSaa`hq|}Sa8dd_)U1wocK5VoUB^%)7Byt{J?+uQ4ovUbpE +zO*4_;_>L?sv0E2}>2pEDA3(0u0!A|Vmt@0@v=>UM6IXcE+eDdLK-ANb7FCcba9xP$ +z_pF(Gel`2QKmUc`zYzRC2m!#(?p(eFPz$r`pEEoJMq64!n(tKr)_ogru`=QHt8s{? +z^}`Fine97&S`{rw_4NY)3n{zi_e|fIEi2|!HjZso_D!babxS*!L8)@ +z7YmTiWcz2xa>D_|$u1mg?7C +zp)27<{I1!9D=C+W*_=$9<@J{07bYc*`K=3$!x4u5rGChF2JD;zu#faDe%Jd>rcb3m +zl8e)hKwfvFwJs#Be0Jw>-l!w>wsEaS!?0FxvK}61-ukl=jW>T~&`})T8_AUY^ +zAXRY3JkDr1{EbnyZXUL%Rl?W`V_|%ISQu;AN5C6)E^#4=`eA_N(3xComV@1Fffw?` +z2EOEbJ01(l+W|$oZ`}{aE)offysz{W=^oTlfAeU<$f4h*+Cw&l}KMnsl=@u +zp{X0QH^+E0$}+H>tuRX=^p%w28P*TS;sdy#>$e)C)b{nM%6neOH|(d#YXR#K=*n`o +zq7V2-P{~%sHD*F+^^YTTVt6ykI)*=XV#?50QtHu@KZ5G$Wi*?ao**k{%Cl2L`CZ(4 +z{!7jY6n4vvH=}Gso>0zoMl2T6S5oG7^IvjQoDqvV!Ky7!?p$v+hQ5-rs{i*2mY6rA +zoQ9u6zl<=d +z#m$qHBFrff-Uf&mX`&TgajHO}mz|O+#qSyqr%a2VVzfyna@PoaX1*BOpg45{iQ1UF +z-J4a`r0B?Ivr=AkiWR#_Hc4O<#NBm+=OD}e5QW<;-sG7LsJ9q1o6dK`+$k?MVD5`h +z{+;)<{s>}j5wqq!>^f~#*1}`JaC3Qze`j@56wAD>6iOeKv$tzBbBy*yx(AC>LWUz; +zMncd=^DX;HN)a}2FsaxZXiWKvme^|M)y-kea`YYd7!B*`#J+62epsR`b#} +zn>^=Uv@S?pIj@9iM6W^mZ>@ySR4t@WDW_p4l^yc*XgW>^_N_*eZ2Ev>KTmycW>PGqWsXb5c5-SSj}_LBqKNiu8u|f8eag!`xR?`FD&c +zf+RvEJ=}uQ7z7WeE>-HkVw0lE8n+dF8Ycgdjdw5?9Zu;KRp4^el@!HX!NQq;wwsql +z5{lW>l@xWP9^^~v3$Pkb5G(KtY7W>E#A-S|m=WP!T&f6E0kIqA{xA-Md?T4q?A~b6 +zyGo>x%zBLSWNpK#*!6c){I2cORDqv3#VECV-8E%^nMF~WP#(w*6sM#yMNOUz82^qs +z!YZ7mnMTD#geEW~d29HAR+_ScOgGW2U}kY3$sQ$~ZUpkW-4kTFsD4Kx +z^q_IJAwoDLq3maIWBr6zz2*-r&0y*HvhOzxf%Vfa2vA|cs3bgvO%QZ?o_KY +za|C()0|t&wK7m(S`7@W~D*UpQaBSLMEf*T-!D5S4a$O+XPXgu<@TjVXe$b+4ii@Z&H8{(aik9YFNACieOB;Kte^ +zDLY{_y)UXUo6`6jxTNMC4qC{H-HYMoBa_M_;=d_yrwLb6@({Ht}$y8{m|n8^1N_0rJM5uf@(hl*vGBwux}AEm7r=1xS%UbkG!Ln +z?l%lz?(_10JG3!)*vAEn9~qOGwxe&Le-0mMgUl#Pc}*(UM6|3Q1)=pMk135X_8NpF +zPz9rSo#b??GArP-S$zj*c~y2P+7iP~N$`~z*SfV5>2StJ#6;kFVS*hmB(l)!|6uP- +zpqje&{cp9ctyZlA4#-eNZIvo@KrIN=3dB064p<~ftya*8s1OxGNLvRKgcPl|qJSn2 +zQ8cLvDuECc5huWC@MsuPL>Y2SKp_caI{&pzJSX`t?xpWOxsUta{w&s#_1oFuNY2@x +z^UaS9kKIrHHS;&bUTM-i@41g%wKaUF&!lEA=BT^P +zg31kA!SF@ummv*#J^J~CG&6eaD_PMXdPiKTojthda7}*`cq9Iv% +zH^FyfGJAF?rzH<8#ZR02DrgFy3+l!fU{Tpj^J1I#NU~p_^^}GeDV}T~g6kTR8i*_Qkk7Yw6^-T0;8zAu;gfukL~%KsRc-L} +zq1iV9L8pBt +zG4{T`z&3nShn^iDZhZx~`Ls}HuRAWcpXuGEow`VR-^0pW(#;jGU*%WgDDCW;$uIiX&A(#4wVb7! +zjpc)LW;nLMi@AEeEAvKlVrjWfrB|n1a(I0*^>FYi-n$wffUXqCQ%KO(F{hUAKDCSk~{B8(N2AzFGC)j#Kt6b2WWNggQ=Iu}E*Yzl*dE^Ub2|Y@EfcCY2a($P4FY +z>V31+X+ExFTk~5_K5JaXVbhGVs@sYo>?fCQ`<YGcq$< +zn)7+?y)*p$OG$BAS41`0u@f6BUL_lax*aveNj|Pmvd$V^*2*6NA%5BTq%~SmF_F{P +z&*So632uVvZRYL0)R{SkfSl$9REhyjEw~=-vF%xrqH-;3?ouKB{lR8TOqydlf`z@% +zhWq9+ +zpGm$7mpvPFn>m>`zs#28f2P}3k~XcOj%66xSSmB?M>gag_DibV=chPXui0?@B-I&e=~b0&(4v`n+Cnupwhq-)PJU!;7LjA(90X=j)7bYLv1>gHWEmlQZv +z4(>9+-Dg9*WkGHJ5!_|=lfS;p1h=0}t}4s9RRoq`;vD10VG +zb6%hFzJHXstgZUqGEfCpqcxT@zHx3SXI{mRmVpUp!98Y@&%WEGSRT0f{Ikk(?-Q~} +z;q&0nlGk6OaZV^F3wv{qc@f-WZh3u;;l0qf8-`(~^Y|s}FC?^{n-q@WJIxQKl3Ib4=q2%BrHn +zUtZqG*;{oekMwBiV>cgcEoXgFU2&zymhoFnDbo;hWX$UY;evV%xY731o@^GaDP&t- +z9qF_(9i#ZK;Mf1BBWWcrhn%c;DB$KZ%6uOz@8f;Il040l3~o9P|5c+gx+p8!HTYqmX0%ESj_a%%7wf;YF}KZaDKNDRtp#6HBq# +zkSTLH+hI~Y^+@hC6X>W<>))j4!rqYd4V7Y%Dk>)e0^*!s1 +zSe9<~!!qlQUnnOk?veHO`AR->wQ(GCRAL4)j3q6ou8V7yR5|CDh$3I0XW7Ba<2X~| +zdqlrJ>QqcBejgW}@u&5EGMe&m>mlpC +z=`t1#nMYgyI;dWX(#}SUEa~zuDF~{r=Sde@nMI+=_q?a&kCF_PN6a?+X3f=&laNmO +zuC|_Gcf^8W)b9)kN!w3I7kF#$L}%(0;xj@{6#J^n>DoqT4x6>QUjIzU3Aq$h{W7@U +z9A9cp^-h}WTFHbq)b01BkKJbV0O?7*UiieIpPf?_d7?SlCD?!fsWzZ)#Y3LFUITuO +zq9RdZkQ#TO9H-@AB^_ePpg%=vXD^mm{!33J`OMXSrM-SRo_M7BOfqk=yiOMuvUIZz +zmY8z^oSN8ps}G}Dx?A_6fs#=97H5y+ZEUtLV%bM}- +zv63}USFzh7F2^c#vcl)OTP@?PdO1(YK{+pi4Tk*O9Xh)D$crngr-@rnD_M&4iz*O- +zt}xA;{3O>6`F)0rmNb@&r?=_XH9tjMzYD%X(ks%8Cbvol?X9NamYae@esdcQ2bnWS +zy2Nkm!k^@5bu6$NuoMnHn78g$SW?k&?@`zl#kAVVIjgE`;wne)+x>+>X6TaOS4p^q;v=Etq4y3*2+7& +ztYwyrXy9}`z8HU++N7i^>Jwy +z5tiS3(44ZFQ&$mv*QcLyd5EDo<#_Y57~c!EOJ1)l>kpS8-+fA@Th`r6ryG&)yvdL&9a+u;8C7Cu68GKo>?#{0C~E!$}FbT63` +zC#kJ#&NLY4V_eIZw=$B|&vf+HL2q)}>nz@O?@?)kX{yoGZ=kE#DCp;OKJTymRPTr! +z^jM!67tYrTIY871DQ007X`l8McR%_Wtj9j1@dIroxODL?mO9zRuJz2?``)Ot5|#qwrD{x{6y4-ENevgHk+9>W*6 +z>2Dnw^?M`>@RhL&6I%M@i>Ia6F#y}p~u +z1?zKZmL)-M1$oDL?dt(e!;6$%Zr0_^8LZFeUSBqC3@_&DmPJ;r(KMBA=X$<=69}vj +zjXzu7(uuy1&s?n>_WG(ZM0+uh|H!u7;ccd~bhqw5RHYo3Ts|XX^w5i5^?Ua7?+#SS +z=lZxuNxge&9Ji4bUa-LtGE>O@{CK^{ETbt3R$2m<^#zG^Vo@<`WQdVl%*<8;!j>fcdHv +zsklEhH(Ba(+fO)oTV%CM!}KxHoEdpXjV{9~9$N0GaxP|(_PLZwS?*gUpXnlfoH44w +zn6QfYwKFny%ZVd +zh9JMjjDCB4TyLjct}rVdg{;@-m&-6kq08;3b@V{?A6qwgeIgn9$oWVf>E^f>DK}48 +z--Y5eHHd3laJ3=7;I88U3H#Zz6VG+C5w|yQpXnww +zB712o39|kMpGTJGx^5)a`foN!ZVx&)qL!k20Iij;Bqi +za68v~ze2}~-s$t8qe7craMzNt%k^fi6fE0!^okz_Qmo>Z#m*n +z-Rzj`d@6V1i&KTSGlH5o6lNfC)ys8H(i4}1VtDBP* +zLcMN6K5ewghkZgFL>cYkF{@hlaH;a;1^vCMi=|$stmYE0(6ZB~bVn{J`-G;mN``Ol +zm)@j7n;NH)8h@V}Uq`FH>^;<5ov_h+tKayxmk-6<*5(;s#HRcG!Nkh?Wi?W?&3hHX +zr<~ub4f`5{NP)UclPgv#sg28SGsIt4$*<6>YfgB_Ivx34UGwA9s%NEW({C;whb59p +zt(tcwKU1z}^x*8!jU6&WQ<}Lpk>$*y7SAnczCjuHqWNOU^0sGlN-IZu#QqSmtEeo@ +zSh|z>>hi*tQeJu8A*rgld2T*UtsSdrTW>bkC9!k*)rB#+k}tN@ZDj6r{T!t%Ic!*e +zIhs=>!B)rS5yHwqnyF9P3`PP@!lC^ymLxy8{T=sdt7#H!1D`G69wY28) +zUD>W@emx(3KDLTu*kRgs|HRygkestQXH2b2a>X}}Idr&&; +zfJjl4QMYi1&;7Qdro5xF43D}zby8@0TvbD8#ujys^kVv_8Fh`{84cgWh})L9#!FSh +z*;SKF<$d0}%nogBHU5Uhaorw0kF3Jkb3N`!4H%p$Lg%U)%4>%$FRkcZw{?7~*`lH5t)Yio+Qh^N0BM+asYStFc)t7y1iB=lV*#!pj;$)0tIYW|n%@+zz@Y +ztyxVmHUX&g~8q58_I6K1FH80xmnl9=YU&|QWVr~OF51+zw*>uxQ-LgOs>6#MeQ!6q;L +zA5C?)PA$;K_Zi|B6SkDLH37@?5b;jOs2cf8Ieu_*K@6%oO8H}caD +zyh6SU-7wdjmz?>k`HX(k0PXB3^R>SwUYV%Rm&wgDoRV17$<c4X4 +zzcNL%{`AAC?FFXB^Svjyei!{T|8!n{vNn|TV#~U`@zIj}&wk|8n_dc4S41kv=sCHXacfB{YoYo4B_yZlq|vaxw?ueoBikh=t4Zgxs0Mwh +zeH>S5ywXQkv(NCN$zEXe +zjZK>pd!(1p`)2Kw}s)>Wuq1&s`yOe58Ta!_)4L!{*&y*n; +z*H9c~Y-G27_sXQ)F|IMF%(v>~^_meeKAz2AJ*HQe7VTNQ&KR@l1xhQZo-xpGeq7~a +zSEebWX?%}88OY-iw`m^f35Ftd&}89RRdYyP?#;HBeev({_o=oy@V}=_|_3yV=w<&hNT)=Ehgl{pSj) +z@$U(HyR^OBx;0qw>bE>D;w{a%`&{Dj?0_(~A@SAsC-P#(>=RSH=2E4qVbPk3Y2H+m +zq;g49bbzLUTt)x>$McBv8vU9BDP+?tQ%|4KLWh+ZTkkDtN?=hg{D#yQ-=-FoUO=L* +z_>c-5*EgP3p|yvF!=2bZ8rN#W=*#X#uabJ<^*H@EuMF|wq`^#QhdgcDnol7z@{PWm!0`xe(KSgAEk=|JDvLyysYcgm%zhptbDg~ +zUxLDnPJIa^t)PZpZ}SfVMh2H`2uEyjv@v$0yM%uU1$E@C^W*~SdQMp_xYc_9MA~R2pvZNXoSD9 +z;CJ{K_^we$UVujU8_Ur@UC%rE4tM+jXas14ju(7r1ZV`XSi!LT=3+tFk9j@b0l!Fa +zruosHDc3bLtlbaukd}Wi((c3mg`ydibmoTw`=v9VUSdWSY!lL%9|qd}&U|`=Z88Wk +zeJ6gfvEH5e^q5}A{#Q=C|H8T2$e#IMdHBC@#WZ&6MIbSoJnB39D|G5bfJm_SI{hnj +z?pdmn9PR9{@GqQr|CK3F1|42QPzD`{1j?Y}OAgAQ1D8M*meuz}pcY7HC6 +z9bIOyf!xs@5$qXsct-?#1|2We|0zFO%6{=EcfsOK-HKi=em7v<$PeaEnbg#6&O(nt +zLqAGR&VT1%*2MXrOnp9J!293G%03)GB9UCL`ny~oI;7_P%!X(0UTT>V^6cA1e_pNo +zy*}mANmsMNMbrVP%0H<>*C*h*?V{Y +zw_g|k-jl}U{PW+rF1DZnDPaztLrj^X>^q| +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 +zu;JUWLCkpd4FJH)P0=A&5j*a|z*u +zgs2x9=Sp09`O?n0kQAJdkPsJFN~6yPrq2!Vw&e3o^^I{A=?$tCGfJzUz7nmv%DxmD +z6DtjUap+2(Kofht?YVKYQ_hta^Iv=)5|on{*HRaCETtCwRD +z!v5H8?BR`{sRe$|P!r9Ux=oi^cHlQnF!B8qM`)&3y&K6r*c1 +zE$(4Hk0L!y(_3yZUE*)Hb#rx9lxob6-Z_V|w8ogNJtNJ2FO4yNg3MKQCYrCht*4OY +z+7iwFQ8hgu6@AuXY8AF#@tJXH+UdM1ZQh@lsKylXX-SfA>99$UFf6*H?U+d9`>`kFCuS*u-oFC`itZG7+qVMkLj9YpK9c+laftweVDptqw6wZkn6T4 +zzYvap{)gadV}BZ<)(T`P1}v0EGJjz +z`{plSF(s~_Zl$T&H&A&${igb}^`+kFiB+XJPknTeTekSsvC?$2%y-N$3#K{Zg4ax>kSpWrnAmeu+=l^6AOC27M?6 +ztJ|whbyubuGM>dqiZGs(+U!qh4x}`TQPH$o{qiitNJfe<4~nboCFY-nbSERfxb8zG +zUgnIwTKy7P_99t!lVT(5F@gnf#eFv8COuo6L{noEzQAl1GA7+G7^l<7hvid$(AhScdo#Lq@$t!%yYvT +z=Y}xOxmL2nKUQV0lxYsso9VnTp)im_OH@npT~wMRKD~xd-(PR0KMWH_1X2_UYRS|@ +zt$vFvJ6fhmt2fgV!-V5`g2q4{O_8Y8$H}snMq$~EEMzJfxkN^`NKJ@VO7-@qcn9ie +z-T_RN6GJtilC5%7X}0s}m-%#Ey_wDl6S@Xcn1MPPGk~dbW~c@-RKppnAq&<9=m@p%dQshtZ +zOH@nZTvVDwKKi)cj9v*7*6;)axd!1to_IlmXhE_lZdfHdZGeigPR0n1!Wc1G$S^W; +zh>Qri2H{1nxFlIrvPUf`Nz!_GD82kdnCKHZdYz9VWF$apLL#{03CW@fd(@H%Nm|k8 +zO3@4vCK@S6@9@zxd{kL)MpMItbe;g^8iXiMykWN}ZaAZID5G)^qtb~{IiQkV>8N6? +zkZE%3&8Rj^=*<;)^8~qEgD{sTR__t1lhhJ*qE_Um)U%>6%~x5-b}}-Hj1)*sh?|tk +z38ZiWbTkf$>C>O#Gpv$r8X-qd^U(%AdZ^xva-`JKKuT$Vj#f%yia%zEhcd*2D%oNu +zm1d4ivn~qL1ZN>A8Oh)pgnlHZxIaTYj3IWYWQ(0ungue?@4t`4JReT_AoJWH^Q;18W0>$muHeI- +zQ+2d~0nGVM4Av-R>T2+;YqOBmWaL?o!v^74uK46$(MiY073}%WD$n^c&v2P%C77-c +z6At4FhJopm1DM55jN(au=3uGBl?jgNh?E)`K#AgBasy{F#FVkCM}+eERu%Gx|_U&DbLv%u!1Y +z?$!oRQU;Gx278IH;4yOg6Fxns-b`-`6FP7OrGXUpK#F?+B_mPf>srY^=cLM>Bg+Qg +zPvXi8)Y0hv%yYvS=Nu~8=bTlV6MXcp)P#6Rsc0Yt4WOVT9c{QjGkhq6HClwpKa-=G +zWCYZYdYFt{<{E^>TyefLBix0-`c#C;N6P7U`Dm`xgy^{9 +zd{;)eLnS-hS(QCsmK`q3rbJ=ctSqE28A+C!kOfkzH;Iz#ucPG#GEJW-<>Qrd9}y;Z +zlcVuuBwcDks8TAEL^1eN41p9w0L4I}^z_%!dImC`2Qi$TD%s8hRE#hgW4Vm6Eed1! +zXCWzMge)~79IiOdiD4Qg!o0lX=qWNXk&Kjb4Z;i((=<})HC2RpO^~Cld~`>>8NCrE +z+|L#4=Lu+mI@&3JW||`-ZEz(!%|*oslrh%GG@12g^lX^$B2N&>H3%bl;*vyB2}doN +zuv;toLaArS8008Sb2v)v8iaFs;t7eO2^_UVuv;sdq!f))io8UaXp9_{^HEW~ +z8P$gghjRsrK+3d0%CrE=G!o^qzm9e}kXbpHVVWSqL_TsfnU9w6Q9->KRfh?gTmh43 +z5E{5*HAfWZTFLhLSf%-1rdcG@Y>dJ*v$GH$8CfMYAvIF!LVwD_Kpl;}TN^V@8RMml +z86(2TYw5j8jsXofo +zRp6LHvyc!nQn5YNAmjuxiw81_hck-7^fw;t>8Yb-?A8W@cstd<%m +zoqY5n8A%``bI3>?S5QjQ(cDSQa|0OX94pzZ5psGqpRVDfiBc2dD5cT^Df9pxjZR{+ +z#wzujqp<7+S%`>?#E=oa)P%e*r4A3I(DtY$QxmlMbuvwMy%|NNRK;%5)MU|AP*2k8 +z*T^*I>do|vVZsO!z%) +zG7?8d%w*&psR{X6O6?gy=}FSj;{BPM^gw0$*GtVIG%@t4BD~fYwPzF`9O=INf +zQ$D({-i$s76W-+t?(z&mcdl5lS0qRf36j+k!5*z>s!{|lDPK9di;rF=BS~arJ{c({ +zBjcqew& +zK@1f3n0nDUi(M^BKDiWo}pHdS@ +zsR56;$9&}E+!*ilacG-*{nC6iE4?jvr2P_ +zPk&i&rtb+8j^+tYa0MrL2H}rf@xdg~!9=y>AV(WKLaARb%l<)@{jE%s!$+H?CghHk +zn(0r;4AjwRyS2gNmBBtr{SQ%Cw)OT>YC_~vDlI{j?^MY?H&B(mL6%LGWyeKf*)y|{ +zU1TJPYY--J#rcj5)_4)7kI6!&aRo^{!F;YkIG-oZAI4z0i!k};a#}mgnGMoo8Oknwn&O$u6f>k_& +zu!bv6=7<*TR!bJ_)q0IpdVQ(X{}_ca=42tK$;eu%32Bg0L;WeCffPxCT2hjr_3~DF +zeJaAdrpeJfK5DEtqrZd+d-DV|5@kq$jwaco6-`%)Mu{-d6ghf*b7mh;5w-6Hi~ +zkvc&wQ73CfpDIPuM3~4!j+*(XPHIAWNU8k-Dg6Q{{YW|*$Dirr$nY6l$@XzkY5ZlH +z)lrxxK1_IuD>%gygo4|}K&H=dhR={nwvVey^R-O#gG}>n6sFmng}9TEOsNT>OQ}K< +zg`J?5n4MIbK$&KZOtUNs(`?B?yvfK!|k_X8>0cTLgJw)4ch{3)||f|avU +z4Z>^FpFIotk~I+m}XCy +z@I9{Jz4$3QnoZOL&z2G<4B!b0xd!2zkSD@|iHKKkrXLCu{>T$N=Ng31dE#ZeMZUus +z=Y}%Q4Pvk+DD|;XSoY>DWE>eeBQ+sIxZ-7rqGcRW{?JPHx&Er`HL~nwQCK#Nb1=^R +z%{UhZ;@o{poI7S0=k6164t&~9oC9TRoQt=QbKqI6ac-7PoRizdIWXNC=fLzgaW2a) +z&Vgfk6X(M1;@o|kI439K9GGAe=dxg&gK@5l#kofy&YiWyx#f0o?ko}Kz^CoRIZ(F7 +zxs~>D?hz5^{v_huF8erlmWXp;`kOdMw~KS&n5=QGz&_5MCE{GXO`Kb9ALr;W&cQg> +zwc^~a*Ksbw66dPy;#>p~=OWsVa}h+G+h!N%z_Y%Ib9qFZtG17G5k#B=)2(r?z&_4Z +z5pk}`KF&oDaSlB3n>bfx7w5pU!8ixwTvv*7{Xv{_v&6YTyEx}Y#5wS3J8=$_-^4ko +zU7Q2YYK?Q8Fe1+R+r>FB{Y{*c5^-*~U7Q2Q^d`=6?cyAm{wB`(6LF4YALqcc!8ixI +zb6u%Bw;IH`Tb4MNVi)Ib5pfQD+D@DUWow)x*~dBXtkyW^W)tV0*u^<8-5Te>^fz(t +zf?b>g$7GFj9Q*FvEt@#^gotxsf=!&e0OK5tb6qUXm4P^S#uDe2*u}XsM4SVkwiD+- +z*&64__HnL^h;w`*&IQ`XxidtZ1JkW>Zm)fJ4jhv;&hhNy+!-Ryk!<4J61zCZf!#S6 +z=ek&&3j}d4$=aQ(w2gB~M0YN^{q7ui#GCG1lwF(y&-y0LiHJBSwTp9L`kU??m~M@8 +zJo`9TNyNE&yEq4?zv<3_Cw>#>D(&JNcs3a4V4Ukpac&}rbE_WI`tnQR_{WQB`ks`?^p-H;M|^iT<()x~jFL$_@r9#;vnz`+_u+DPZ{?l-kBpMd +zT=C{(f(pL-!sX4_okZ=Oc+o2!7W7V5&`jCV4@{C?JaNKN0hgaSRL^!GF%Nu287;*! +z2gx(1D93FV-Qfy0^D}2C&-`SjIY_Ao76tv-f}QzAdnQ42=9oZPk1g$?S~`$X_BAGy +zhY7v-nG^KvvRTYB5~a_gpjj>0x*ghedqt^7v7p6SL6c==P9{n4QE@O=u#BJSsb^=; +zWM&6YRQIt=A9-dErE<5(>lhXkniVueR_0)mh>nRxJb_C+RyI&o)|;UTq_FN|nI7^? +zSEZ6;ruDc_?LkI9X~7)#Y8`(O?cxen)?=PdD$nkWB!5gu4iifG^pBK|iK3gw1TXpY +z?t1oof9CwJDf^`uy_cLmPMNw(bdrZ5A7vr)WS+fEk~KVW?NLEaJ?7a@<>|^8{}rXT +z6r=Z-(6ZEdf82wd@4;hp|Oz0ja%;ckv +zN>Q?zHtjxj8W|bif{Bu}qU|Cz7ejoq5SC2Sjp5^u2}xnXB0l<|p6wIB^qEB|m15|7 +za&)vZW~YeC!;s-w$O@UJuSrtH6Z;+&aQNszJ)0HCWX+_|q!>C}j(RKgKbvWOQmSMT +z5+T#{G)c@{vH6&wTlGE6{rl+`gFcZtOh3}bes3o8y#UI!ML|s)YcYrJDu)4#oxMWM +zv}020%0)rTWe$BAJ4uxOi-K-|@efrF!x#Y{hMH+)DOI{CC`#twcBGA6=+7+tnsUD2 +z5EkT=6%-;bM#k~56MB?jkVZ;p{fJ#GDi0aHPde2r`{$9C4k}p)q!4&6M>Yq +z*AHPq!C66GG7W8dGd72#z4Mc35?3$}9PDJddvE0(#}cFD!ZGm$p1=tdKb5-=QQk=s +zz1lGu6Xt~pWBKlWdbYz?Ob36;&ih#A7xK&xl;aXa3CFOYO<6%7%9ai=N#-0A&*2Fs +z@iRYHj*A!F;R$-xV@vz1mVU@s8i)zUg$d8_GaZ#@lFc;F`&3VI(D)YYOp^A@c9D{c +z1^HwJv1Dc47@q!^FfdGblb`vap6waH^qfU0mSUOj$umbQ*Xl#U$Hn4=itpM{K) +zc@8s4P97DX0Wwv@mI`Zf6B%C7=5ao-dCBLXr?var#6$3?y~HUO_IUK#DjT) +z(e+sNAXWB9jPWE)=ny76z^6MXgOkiO`h6;$jCi$R!5pppC(%@{V17N8JxrDT9wR&e +z6NZNgReX9+JzM3^RDDg!B_l2^m^@J{j~8iq81haQGE>I*z$EF*6DJ=P@c8IZJ=>YY +zO#6!RsT4y8$t@fy`uD^7_vAEnJm*dnIzPsVk%b<#78~# +zZ1GH{IDpc4A47fQXb+`+x5)PxhJ<7y%zem}x2ZsVU^3-@v$o%ApSujp$W&Y=TwErgh|44)4427nTqe82 +zY-Pg5WfCyORwhzhCjAMSNNr`}4`l*n^7dtt0%S7EB9nc#GMP=tWOaKo0pnJgthSZO +zK0+o$G66+gCbJ2dtj1*miiAvvWHQQDCg5PLGP#Y*1QZFGOoB3jGI{$lc>-iI)glwy +zWWrgG%j8zOGFgwy1dJ0hA(F`jLMFD!Bw;-+lUsyL*4xVD0wI&BwlaBw%Or)6$rD?d +ztcEgyGI{$lAp@BVvdARCRwkbjGWnrBnSgPtOn$JHNdhht9+6By5tqqlgiLO82$^`=%A^dJ37L>dnXOEgK$$?9ynUHSflQ`YWRhwt +zlQ2RiYub|u7`Mt~jjc>l37HVd1QcP$p0&Z(k-8flNNK$YhtTOokFNS=pXUz_?W=D{W=63zx|%BAI|9 +zE|Z~zOjhDD0YzLUKM={}BU_n(gSE<}0GA0U;xf4bdnQmOogkBkMoIUZmY&HfyJWH! +zm&qUP%497r6EKd;|oWx}UibOJ5i_7E>LMCf%WpWaiNugcOkcnN-M1jlXB_R`qtxRH}OrT8OzDzy@GU;xS$@xvHTqXmEWYXPMCg5N#GD*FP +z%LEj0nT&!x6DX6nFOy&I8ztSxSb8P{ZIj7DVxP&5_GB`T*k=O9ahVJtlF2b#CZLEX +zlR3mblO4EBX4~yEIflz*v~ADixBIwEKE!2`a^F@aUqhKdnY?|O>;WpF$pjQ} +znT#T2LhLgEMO-HPh-5OrRwm$JtuncR%LEh&nZTY2lu0MZL6z@eOD4oVljH5m +zgxF^S#&MbKBa+E!TqdAMBoktv$#Fs^cKb|D6Ed;wnfxZhW%3On6Pc|{zJ)S@GI{$l +zxea78$s&_OwlY~w$fVtUCScqu6T5vThX|Pv$pjQ}nXD#cLhLgEMM5S-GMQv66L7Fr +zncTx=0*Zu8V9x}~q!VOP0c2w7ne4YqCd59IXYI;_*k=O937HVdB!`fRT{0o|nLHz8 +zVz)j16(F! +z37I^wmB}0^6DX6nFO$@$%OGO^odl1<3Ou4f|0WpbL3iQHBu>!3`aOy0gs)&iM0T4a)BE0ZaN +zOlly1zo`KJxPl?cJQF$c>F3H`@uKTI!3W?>9w~PppiDR- +zH%hoi#ayl+jPD+^t{F@CS(~s&^aHpC9)}61^W8UqV!SqiBN}j2umjBOFL$4)oU>1E +zl1h>F=FS+|TWx_5I_tZp8I5bT72j6{}V>6bJq)pf^dU|pqCfpV# +zY~{PZqnz`{O`~MMG4TMNU=)}+R_;DbIVb(5QS$9k@wZ&T623dbu^F4QT{|aH^Z*YT)2^hD^?Wde$XOs3&7iLsRlc#u^lRk%z*k&wwW +zC=)1?w=a`xMoITIU%Zydk6+lz{zU3tT4e<1$(Eg{@4k;W7a; +ztunc0E0gzenSf&=lF2n(CSayjCf96b@;;Oal*!wd$uJ<3K#NQQZDj%mtTK_dClfGk +zm5J0=CV{w2ew>2K1Qcf +z?aSmgkjW&AOeWdNxP$q9*CWnAb)>ve+##Sa^z$%j`?a2g;TV?XZRwio*nGih_ +zP{d^dW?E(P1eXaY5;7rrCTnbE0v=?Q$rD^Aph(CB_DrBmIzc9dKqi)+$&YqDlR{i3 +z-?b}~LR=UDF!mJ^h|!V>zNeeGI`RjOp0-tfN?@5M9*X@Arrfv +zNii-HFw-iNVq2L^C1hgPGbzSp0%lreQfw=esZb_RCU0LRPk>CeSY)!rRwiJ;DwE3g +zWCF&mGO4tc$reH;M9%~iahZUbR+&`dG66+GCPdF*w+gRC;C#AO1CgiK)11j?in +zWKv+1bg#AaOrG2IObT$BeA%u{3UHZ#aa<;KM9-uzE|Xfjo=E{N6EM>%lLA|r^u=WY +zj)~}*6yP!eGp#Zyu$4()C=)1?w=a_~flL-yWU|0kCSbrSlZWle1dLl{^3YZ$3vih{ +zCweBJh|2`bw94cmE)!71Wl~4%le@Mu +znE+)1W%BlAk^^M2!6K6lwlV<&R+*HyClfGkl}Wj+Og0cQA$lgDh|2`bw92F$mkB5m +zG9h{<8*F6)9%PkCIW7}WBxC}6CQv4wAd?~>6HCwJxn0ks2$xB8yD}-lWdgJ(D6_CSayjCPlU~aUo=4*E1=?WddeeWm04-6Bj5GD3iA@lV~6lszoMLTbY0X +zt4xsgWCF&mGC^!*LM3EE^h`hzmkF3@l?j5&1QZFG5IqyBtxUj!tTI7xnSdf86WB9> +zGU)`FlmeMpdM3~9dM2f~OxoI&NhvN9FiyyX=$ZHuGO_EKl;Sc0Gp#ZywUvo4Arrfv +zNhvN9Fw-iNQd^n$LYY9BynUIp0hz>EWD;j96EI+viK0E3fN`r#6t*&nBVi2|1iC=xOudM0tUG64^=%0z+71QZFGz@7<|$=jF7qN_$p_raE)iGyv=WZ6|* +zChxT;6EM-b10IayG8sbjOy0p|GT63fvivG86EM>v6Y5o4nY@F`1RN9IGg)#KmkF3@ +zkqP;#txVp5GJ!IA`!abC$YiEPCNphi0tPHH`R;yuG6CZjnS|W8mB~z8CJsc;1QcG6Ca+Oo*Pz2tp>dJ(K0PaG8LaR+-$gmB|P~Cbm73CAV;yfSFdA+_II) +z2q+UMleaIEoj@ilEizeYD-$qamC57wWCF&mGI?w(la+)_h@J^3;xYj>EOvHScz`2HrsK>;Cm|$iCMS=;u)G!eV +zCQw97Ff(!JF@Z}OCL+NEiinAsnV6Ui045&*CTeD4(Pt*Ne?TxfnHQ4}2qtijm|$kI +z5HZnbCO`RrU;-~SOg_+KvJf%RXC^=XfM5bIHB3IxW3tf1#KffkF*ymCJfLFofF2V# +z&@efh4-+`oFgdHo?u^~^YnMt!DGkJ?(GCMCOZxKx3oM7@4W+o#ECQlkNleY*a@KVF%Ej=b92`2DO +zn3=pqFoBmECU5C68EIl-V$%PZ%mz$uQZcznj|m)Tn0%ZM6FAo}`B;z1O$3u>%uJw2 +zFoBmECLa?_phz%z3Nw?N^q9aU4U>-vCQu}p{L0KsOic8ceD~3d%dgnBZP1|c2fp8= +zKo%<`KRxwW$QQT$wago>qv4ZhirqviAD6 +zRCu@4&@1CgYECjWMec19a(+c}MWmIY#UJ_BS8&bxOyN#p$Wu!c{t`FuXRTA^LTB>3 +zSh+u19^~vt&nVW#N$Y62aKG?YfcraZ9U?dWB>7$JvOx5*5O)=v&rMp3--J-=F_ +z@K3w>pRm@4?)ye*+>vSAFZ`u>iNgQO&0oY?FO^sQIQd;{Vkr8ApZg8GoR+lSAg^*H +zzl;4S82wRz6Itu(`@T_D?a!>*BYX_sG}_G{V6Btn(?5j;4*uvXLGFHdxh!cNE}y;w +zcA^BL4~DoKS?k98zEMu^$(%kU6#5maEJ9r>)=tgF8vW76Aa@TNzP{JjTsjx +z@Zw~6v^;mea5}*KlMN4%TleN%&2eY5gR)#uS{pO1yM@*eSJbK0PD-DWJ_pYv{ +zZ;LCQxk*ov+;UJ@>sO>7Mx<**+w^SgygzzA$UV}j*k+~M1~Kz0>HTrVvoPryDc3dT +zT<^!7?>nTz3rgL-Ox-Tw_7G?5RN5w|+r~1-Y7~Bqn{Q%0ljP)qoa@fG^G=7fN^fyFy(gihMkG^L$tAmmgCRv48If)h +znZj)BmQeIVKldt|njx1Q66X84{hbOkGR;h5=rV;5yLk_rDv^b4IoHyJ^L4wl{(>Ux +z$O!v|u7DzKiAY1m?(xj>a)p1_&Cg*|SNHmsS9q7#&7-p&7xwK}1AD6?v- +zFfqtg!pnt8>qvQ3-Kp~3sV!6Z +zRySYIhD+quZ8?`M;cT;0>n|v+J2I{N1v#KlTO!m@v3)#aD_8haZvIL(e08tSR^heP +z(DUL-cy=;uk?Wg;q+g-#j8MzO_L6tIL +z?8&*lNjOK@rE;-tL^d`#6n)aq9qm-wMyK0mFvm(2zS+&!vL2gUw2hznn)ccy=LIFXCzCuRjP)y0Swy;2 +zWTs|g2mR55LGE5Qb$zezaH;ojCH+ENNi9yMM$0Apg%1PVH*9K%EbPs>o{Br4a!8g7 +ziqM!5b_-mHo8GA~lhVv6rlVTnm$~^j*woBkUq_91c_}^4Azgk!*?b_gdAo2Vs7Q+< +z(k8KcNH&(M=pRg81WY_CCN@1Lu)smZWKCX7J|UREIbvcXnB0Mw*z}luLNI}s8YZ9U +zF}VXVvFR~^1r91E@KVF%6Fnw(n3$ND3;-t2DAeyCR57_hkI7ev$%pwcfpZO$5A~Sb +zfS4>Im_U(W0xva8J|vhx5iwarFu6gG30%@J`H)}&MZ{#0iHV6x|6}qdV6sugWT_q# +zSm2;y@>O0;&Jj%D95Go+FnI(qS*pk69Ki%$YM7kUWAX@MvQ&==EO1aUftMO4=k%C7 +zVq#)q(*Kyuh0df<#iT%wi3KtFLq1I4T*KrKdQ1ukCe*bA6DSf);H8Gi9|$H;B$)j8 +zT7pS|9uv5vVe$up2^0w?w_j^wVq((&m;}G|6};&F9usP@9urvLpkiXli%EiD0_Oyi +zA1@}DR1r*S7wa)e5KQ2uhDkz?Nfp5az6t+pE?D58VgfHUOcHubs!U8wOa=fG=uB3r +zn9SB=(u|nAmk$#-*D!fckI8Jr06bUBqQp4muf(aB6lj{g3v-Oz3B@L7J2qsWO +zOs+FAF)`_XOkM#@?pHA}WG1k{LB*swFD9Q6OyC?b!OUb0Vq(ZlJ|mdGOAV9H^q8zc +zObnR`EO1aUftMO4pXo7KV`5@r(*KyWLT55p#l)h=q!uwbnGX{<*DyJ$$Han|U}geE +zf(g9TFgZyufg)mpnTbV@30%@JIY}^qB4T1@CMG5WfJrN0Qm4pXc7h4K)G%q+V^WKl7%~%B;GkjxFEvcs^_bL}n3$Lh04C6x)T@}- +z^q90GCTH?t0_PegXY`oZ5EINyphz%*ml`H#2qsWOOfWOC=`n#z8YX85CQw97%*@2Z +zWB@P`0Fw4n>Sm2;y +z0xva8I`o(@CMG5({f|jKbS6bACS&xN*btMq^I-z#8YXY+F&RTJkuWoXBEbY+YM8uD +zFo7b$M8wQwj2;uXq+#+l!32r~lTXad#KdF(FnJy@x$k>SBtvEb3mjBTY=b +zJtp0V$w&DxfpZO$kMx)tAoQY(}Okjb7ib;1~OuitPz&T=qnaLK!#E_YMK`?=r8YW-pG1-Ec7%~%B +z;GkjxFEvcQ&||X2#Kgp;|1l|o&SaR1$xuBeV+bbgzt4vWoU538{ChnnLkT8JF*AW8 +z!318am?VEsFo7b$WHDwYL-m-zB^8rTeorugBEe*dnVFcF3;-s9Z+!*#t8*qx^_j^z +zSm2;yGA17;pT-F$a858;jG0LV!NjJ|OvE_B1YW9`B;tBZDhMXkGB#6+K&oP`ArDkkt!!{k#vCij|{n3(iGCN0pJT&ZF* +zNsq~D#N?fPn83M)$vb*XCLt!6nLv?X0xva8-XWMk5i!BcWRe~exTIn74#5P9h>4k* +zn3xOzCcgzt)H#!-`po1UEO1aUS)CUXkzfMnhzVvUw;?9_%tRCkCh$_jMATz)8)Bl* +zOwPgr2Ne@|sbM1OF}cme#KdF(FoDiwt%}JaJtk)mlMnJ?0_PegALubzgqUDv0!4xe +zywouHfM5be!~`>wMS4u&l7`6#1QRGCCT3=0Vln`j90yF)Ig_RO%;X#_a8NNhlNXb- +z1QR$%OfWOqgqY|v6Y(s;1YT;GoYiBp2{F-UCTC%RgNg~f)G#@#$7GXYT~zhRg&OIH;J+%Ztg!1QR$Xm_#r$xtU=cnA}V-fo~d3G80(fpke|qHB3I%V{)^J$-gHiz0cj@{lSo-g9lwQ756E;mcIY~ +z&tFSts};ZJ!yUrdfFj);ktT@D#Y}O9!hh-JC$Xt3dVPn>y@#vmb$00vkr~SzuA!&I +zmDFX))I?c0kaJOSC*_cAB2%1=ZSY4o1i3pq6=r&x8P0T6DZJOs_pzzL^5(rc*P*!c +zkVBeuLD}4x*}Pjg5>lj5{qsla>!5eJUFF8A=jIr4b2=Y4aISH4TF;FYxxrKgii8_@ +zsd00fa05l;22&NQo*THNadVn*14ZPWFlo$P8l+SJ8j9OOJ@m;B0JuFgicLz2B)Y1!=~@&=s_lP*TH^sVik+SI+f% +z!uhaWqAw`Io{VrvnCa*CbSm8=(%n;;xNVX +zH=Z2J%METkfpg>rQxy+#V@OqS;|aXfxG`)z@gO&bR0TJlz)OuA!^RVj$<4ndH`zV^ +z(U>HmcUhuhGF^|!dc-8}#uGT#FfnXAnU0uXsscrV3B1%W!Hp+SL`*PMnXbnKE@_zH +z#uF$aCT6N)Vln`j90N?$NtD+OsS0j9S)UgZ+;{@#hzX`DcOoW+R0TJlz)KAi!^V?4 +z5fekIf*ViZrG|-N;|ZK=m>4#mEJI8%Re>VG +z1YT;G;KmauA|{xsEYo8Gmo!Xp;|UZI6EjsYF&O|%qJW7yiSoK3Rl$uX>AaZW#uGS4 +zOfXgPA|{4Z1vj3+OAQml#uG1MVn|hR;|aXfFfnXA@tT;JnDjp;CD56SRWTW^$D|lB +z$-D6c&NWO78&8H4OdiHm1&Ra{c&TB68&9A}FloS4Ww;&_xTIl%8&9A}FnP#KRZL6< +z0F%(SzJmWzCs7_Yq$;@aq&P1oxbXze2__Ags?-on7(=Rp8&BY+hKXV0Ne#gSz6nzm +z+;{>nHB1Z}Pijm|OiTs<6X;BCQ8AgL$K)_#l6T_?oNJgEHlEBuOfWNnBEbY+YM9{0 +z6DT4kn3>GcV*-~nOmO1~6cH0MGchq408Cy5Ow>t~hYgttZag`h7Zcog0_TVcW+v+p +z6GLW#8&BY+hKXV0$vVWukeT4d6L_g%V%T`H&cwvTr2jDypfj1TVlqXK35}TK-FO1$ +z8YYH~CsPm;%uJw2FoBmECb;ngiiinjCR6m7z$Fb6+;{>-#Kg=@OiTsyp{CsBF~nF($@S)LaY+;{@# +z1d|JxncPY+={960xbXyDYM2-{p4>_>fp5ah1UH_*OAQml#*L8VuG0o6bUBqQo{r{oX!OUcV9uv5vVS*b^poo~5nTd(X +z0ATVuV4}{M^cXS|+;|eriwSN#fpf$JGn0*oi6Jw=jVJI@!^E)hWFul?$V_nK3B1%W +zF>E~9Xkubw(*KzBLT9o<#blNqlP!oz-i;@4u3=)>crpty!OR4T1QU3vVS*b^poo}Y +zW-?2U30%@J!Hp+SL`=-g#KdF(FyR3cbB)I%hIYpP8({jVD9%VRAigJb`n9$!L<9WJ(Dp +zWAvHHV%&HFFI7wy>NlR8DJ7V|H<8TbM%;J;FI7x#&~H5Xy41wP#AE<4fzG5%#pDt_ +zCOZ(5ycgG)!>g2^0|%Gcz$U830UJz(k!h8K=)oR^Y~yioBTM +z#uGS4Oh{&uu_Gq>%w#ccJb{-QCi;yhXY7cHJ~O!yH=e*t4HNywldtV2CMG5WfC+Ra +zcdM9OtHnHB9sy +zPtN=tG0|rxH{!+! +z#HrWTf4@}W_{-}5UO%U=DOV=_dU!UrHWWSY=Z<$OwsC3OEM{IQJu0DiCL}!z<+|-T +z*Ubs%`*!KU3rgL#Ox-@=_5j!3sk9ACw@qe_RVaM7n;*k^E|-%#bFOC-&O7bW?H82f +z?o9Ha@Q`1TZiz_q#kT28x=i7tZhi~vS=s9=F7*~y(tF}c>e^&#gj~`n91JMZ0}*MY +z$V|+}ZV5zh32}?q)HQO+9^u0fH>y)%CZw5>3|+18RyQAJQ$@0HFy~qtcP@2E^DZbt +zQ%2Y!bOjY@c|_VGb`N5fS1Npsn}3&0jqLR;uktRhpg&3|se)u`w!C?l;0!6!^oVq) +z*gZBII~R(s@NoGTN0;Qqz;EWpeMfoNHym8M8|p#qQzRSS}dN1-L=* +zAHzS5c$KyObX3 +zpn?<5E6r2W%@;AVi|@|4-itfmb5M;?oS1GdWR6zT_rd>l*F~rjvH7u`-}=^+de>Ca +z&)BK+aH$~OY+=?+zdPspEaAMtPJIZ)QR(LC%vWXfBk-FmBGhAI?VxO|Fc>WiaBp=g +zwHKvpFJ>$i^vQ%0z9<>KLY})T=Q^5juCY^hh_z#x<{H{!r>ZU}tvfTV2ZUC?Le)kn +zn^;@Sw3jM;i<_@w!%KR7?PcEfD!MzagjXcPgXQ|YLQz1W?u}5B#P*A`v6euzCB#kc +zRN5z|+Y6btYI=QK3C~N0i{<)5IahJqS?r+Zi0#v|F~J`dg4~8qrM)=aK9uRMRCuSG +zKgWj0$@2c3O9@1K16;0Cu?Gho{^`5DuUyUoCB}va%xn+OO +z^-bLQjYAqDwvErmCI_OEL)`36rS0N$+h}H9jlx^pd^78@$aPIQmnZJ@IHZybO5LGM +za;vZ;$gS>F+NP!33Yhg(3cudXr&-VNUSGP>n=Yr{a7Z&RD9Qbq +zWMgAP(Sv?2#HOb9`ig73hfC=>2_W2~P8qwnY +z&9}ajW!{rj^gp2ZXoMOfHjig!7u}b0?MpasvQr;FeqL!Foo=4N9G!Y!&UJOd`CB_x +zFE+3J&9}azRocv+lo9?ExI=3C!a72dCE=z_Qsz9bnQFV8)Yb5+HiRSs&QSUV#dTjh_g3UWW{RBDUTwZoX^ +zD*7us^@vzIn5nH)_*HKHG#f7L_0?8+Yb)q>2Q}t`(z-9xx=W}JDO7QUqQ%;A*_a%P +z7Wui|YscN_bi_e1lxSE$5n-a2~T$9}AlL%t+tR9o~1d{|}vR;o#1TlG5kI8z13B1%WS+B<=Vq#)q(*K>wy@1J76_W#c +zOco+0_vXU{&NWQ#)njsiVDc_@CQu}pEJRH1C73{wU~&pOlLLB8;F5;Py#x~|5=`JX +z&CbN^O!~Vs`2;YreUHhzhR(!8FnKvICLV$boD)n=VQ2Cp!32ufnRo~$FC!)%Jti*_ +zOyHZaGw~2i;H8F%M~}&iCMG5({g26)fXVeLCcoBW@&ID8E*~avu3@rHkIAnQ6YNZ& +zNHBQ-F4>fjRcc_M3 +zc0DE|2_`Lf<--KdRZO0_OOMHRg2^20OrS_G8A&iXd>6q4iUgA@u`}7O#{@2^m^^zI +z!32r~6ZlQDGch}p{_ac?-^GU9qGl#@^qt9bZi30ae3<;&O)!CTg2|QGnFI+YP$Zp6 +zi<@Awk6`k&TaQVQU;^JnI+G)Af(g7-F@X=k%p_=HVq((&nEVnjxkAO{2|Xq^Atpb| +zhY6f(nEXtS$rFePb|z3HnB0Vz{ET1%MZ^R`dwjCci~Y>h+kk5=`KmursMAn7~U7lX^WSttKWWCjF1e9|4oaDkd#@ +zOzuNW*5<M?0SOt3S7BEjT7#AGeO1d50Wb|x))OyH7+$y$O56cH1%Gch}p +z0q9IR024JcdBM<`Y#^BYEiWb;2qtijm|$ljASQ;+WCOwEZ-~hTJthKTV(3gZ5KQ2u +zhRFs!CW48HiAn!svIsC4tzxoUkI6K|B=4LFoNJgE=1g`IOx9s%0!4z!G{gkwOrS_G +zS&N;?ZapS&Ny7x^OrS_Gf!{Pc6SFhv@6P0p-^GS}sAeYX44nzinLLvh6Pz=FbAriQ +z>`a~~m_QLb6Pz=71~DW6YNZ$)MEmdG)!>L1d51>*_oJ~$pCaF +zp93apX0p!Enc$qsXL&KfITJWXOt3R~4KXovCOBvE8De6XGkFa$F?1$4X96!ZObl}- +zubG&bnDjp;n*fs;DkcZ@nB0JvjVdNb^q4$?nB<)^fpZNL +z!<@+x!~{DNC=yH_K}>MY1d50Wb|y#kn7}0s6Pz=FB4T28CT3?c0G-JffQg!!{MFEz +z;GD^~c`?B`6F5gquroP4<}oHO|rF)_@UoIp$roe9pFz)KAi!<@+p6B84Y{>Nk# +zU@}C-WSbt70)k0h-Z>LES24N6FlVxjU@`?e6DSf)3J4}N&Y3`wU@{pylWlrT;F5~T +zoj7L#MS=4;CNIUmiw&8tW+qegorw$QOm^kN5c?CT3^S-<^pFn5db_Q-;n2=S+^~#RTU};GAIcBz7jhC73`F +zI}@BUIf|GV=1hJ|FoAEv&IIR7;H8F%Vb0{YCMG5({g27}fXQ_#CeP?GS%aA5oil-R +z4HLth$uo!vb|z3Hn5;oeaLxpZhzWKk&*(9MOByCPX97jUnnocO;>B;aiS>Bd&El)V3c50*8K0F)i4Vr(X +z{@>`2)W38VxKUG;rwqLdPNIC3mm8c!fpg>rdza(LjiGnJNtCaU8^a{ZapcC(yWk`W +zywtccOrjkB58)=YGD1xe+b!9c5QqvPZf2*_J}KQkis`PVx5Sn30`rg5|2u6wu>v=R +zDmT0I+*pvCypt$!u5n|SMA=2Sp|E#>BH_k@+~6b%6bU!CWACy{&kbDCxWP#jC=zbq +zH~%Agmt2L3$$!qqlb2xQ38$til%aRQNtEWinBXJ|oD)oL$KK^A!32ufyWk{BGh$+x +zL^(<@fp5az1t(G9rG|-N66L6giP^jKfA10oOy;VXH0v>`MNINeqQJR^iD43@88N}$ +z1&RcdTEqk=QJ{#JVDHkb#{@2EnBXJ|6cLmEl-|X}2kmgLyyTAf=M#(Bnq6X +zn0#iKMA<3>X~1x&6~G5Mt)lhuex-boZV*Dx_mqWlsu!OjGV1e4W> +z2~MIw5i!Be{66ICIMBka5!$}l)sbON6M0wT3#KffkF}V{knXF>6UysQ= +z#3b(|3Y=@07$#Bn6HH#m&IF1ClX-{`ctg +zq`x~8*m$x*%}ic5bS5~7ax5<`ctgq`x~8*m%;V +zW+o3CIuo2TIh+?0oHK!Qg2_YJnY=(Sfg*M$IA?MgF)_@Uyg)F4Z^F(5=S<+GhKXU$ +z#WIg<{= +z#4u;_I$~nzOmNNwUTT;a=1g8UF)=aee@wi9$xIcKLwZb>BPMz0OyFF@#4u-ah+xu# +zoe2~PCd&~MoHKzU!6bv7$ss)^a7n`i=S-kTFoEARI}@`r>F>@2HlB2;nMseKGr>8N +zXkJWk&IHa0CK>EZc!CKOu`|IrlPF?hm^0xCCh$$znc$oWywor;%$e{eCMG8Rk4Yb3 +zvO>k=IXxy@5R<%fCUCA{Vwf{|4l%*b1d0TcErC$m<%PDl;oW=fpZm;8}xG~Uv4Fsj3b@N*H9#w +z3?-N>$2k)y5=_RD&Lp>0j|p5-FM^+- +zG08h;0_Peg`Z<#?_YzDFVP^tGg30BG3C@{7kzjHVJCnV7OyH7+3C@{7kzfM9X?7-N +zXVTxD32Z!>sb(gJ44nzinS}CUf^#NtPB1x$oe4`Yfg*M$IA;<CLfsaj7K!aMvavdUv@Xcq&W3HhzP2)NTNRy-E8*qI@K9OaE0hEj +zYMuE<>Lb!fk(ro{-4cl2654h53P0D)x3b|Px%FVqWs5s)4r<;7rL`&3xlG$3RHl7?&Q0nCK@_&PNavLuZ1M +zDDYClL_dkr6EQI{G3kFy)&VBdR7?)&FNWlLLB8;F5+3PNG1OVDgdKnV6Ui04A{U>BnrILFwsw<^t@`b6YFxiBd;3NtZ5fki8eyzs@E@_zHBnlJ}6SFfh +zF&O|%VB^UVH8c6h(3#*Q$~Sp2!ATT2M@+CYc@r@)bS5~7@(p65pF}zTCSqdfOmGqf +zUTT==CsBIdG%+zT>3>Y7044=0CfoIxj3Sr_c_&feT*c(LVG?CK!DIn;CQu}pj3Sss +zaS{cJ1e5vLnQYf%0+&=w-oQx|C=yH-n4O7<$pByi8&8~SX0kxvnZ$4sWq&?Q-o!~1 +zI479Q$Ic{3Fo7cJOaz=n*-tR}onaCsNHBqKBAv+zoJ4__DkktDIEfN8F)=aee@vbN +zOlGT?JfX+rX2c}#Bnq5sm>4EeoxDDNXChDnrH5EFf8 +zasnq&;H8F%VG`vP6B84Y{>Ov@Oe`uUje1P1h)Lc_6gbx~F-)Q~5=?mPOrS_Gu_7io +zi2_A}35T6YqaG8uq+x=SC{QGr@MdRXVln`jz{V4&nwjv1&IBh>!g(>lNfbCIm~hyc +zv=U69h@A;eqJ$9>!z4;8!34euI}@BlftMO4hDnrG6B84Y{>MZDOl&G9EqY8mh)Lc# +z6FAo}G0d5?AST$EK#^eLK}>MY1d50Wb|x))OyH7+3C@{75iv146BCmGzyvm)IMvLA +zH*_XAXOhZ`3C@|oIbwpHiGY|GIuo2TNg*bNITHafF?1$4X96!ZObl}-f{BTVN&jQA +z6fha1VzOJ0$#ldd@0S8Dz@%8kNOmNQRjl7uPoC%y0OuDc$;Rq&B#LfigOx{3D409$N!34euI}@BU +zftMO4hB*_?#Kgp;|1s$SOqQ#d9MNOqMNIO}nZUV*iDAy<2x5Yr2^0w?Uc?0FOrVIE +zU}thfj|p7TFu^$!C?Y0iXJTS90GPnWlXGfj^0lEe!8wz@yqMse37jJ)*qNL_Obnd~ +z&YAQfCWbka6NrhSGr>6%c&TAxm@_$HVq#*_|Co#eOopnMY|~>hoM5s!@03>ZA4jWHa +zsF}$ueP`msIg>s4FnJW`OyHbgG7~$K0Ko)`q%+x!b0&KTCciMunFI(X@J*yMc?{=F +z;H8QQdVxV;F5+3&Y3_FF)=$66O#eJ1U8^JD({*K`m%Di7y(ci|i)MF89uvk03!)Gb? +zTB_+PJLPClYDcGQXE4pBJ+9da=TSR#pIAGLX|AHbvQv*VD7AyrwG)`y@*Y=n!dYvl +zYQ@?y9lqKcZ+j_iOJu2e5o*0yJG{f!Ugd4Cpt~K^&<3S_e7b!EW2^3Qt&TfaJE%ns +zO8bm-`w*tBl0FvCQl1DkU2LD+;cKh#w$;$ZcB-a9X&;$xpT;m{JuW)o?66Z0Hz@5x +z)9sU(?s7Vs$WpT+luK+M*Wv4~@s25_hbFSpB@yW^(RL9trmDyFcHH^4LmJVb*e0fJ +zg-la5eXm{miD(7rN(~Wdv}l{u;X70AJyT6@ +zif5&tMx+}>+bm{YX^(4E!nxlr-P547U6gLSn3-46<9a{gwA!UrVq0N{?^w0>SQ+g} +zWTldbv{`H$%&f2MaXlM%KI@PsHz;kEblVtaeNB&RS=_nI@%`WA?(n6{yy+^sFP@bi +zi%5e-W_*XQxZGP@P1o2ZM}xwQPBSx@!=*j0ISJ*0vjklweUYf{C^CHrEks03M>!|W}RM0&RX=sDeJwDw%f>~bO +z56UlN4E#LyIAYL +zCT&tIL(-Os%&yJ%bj8X;(YO4Z&rbbBw2WnT)zA};Jl)6db@M-9t^b6p1!;?gsj8q8 +z&pqA8Pj&N8v(`_bK0V#NKyLizowL4^Ro;^o^gkTb_BrQs)=QJt3G%A%-Z|@=UFMx# +zMZX9Cy#M3oFJ`T?Y14^1~uV!kS;kHh^N-Ta%Zb(Wxxn=fL+R|-n& +zu1sr_Ap84x!Od@G!z<+atzEIAV6-T}o$AbmM<&Bp%k{gvVlAO)ou7M>4O;}IzA00` +zLr4bu_=ntlhW&mUN>{8T5G@ID^E-24Ycf1tmJfEtHv6NSgPfBMFBKGdM@HT+^alF) +zoSPradM*)^qMezd1Hx`U7wF7+rY1et%SGF|V%5QDb%0B-p3!pAe&JMr`$uQaGbHJ` +zOm5lP6}vJNecsRgmh}_~O3T4a%Qj(cu#dmP&40#v#tKTy{!Ggr;e3cI=*)R8O?oEC +zbqBg)Px_-z2DvqzInNDAPl5dXpRn)a+ugj4^~@8Lx;>e?L&6e2*VLKwOiFqd$;s_q +zvDbpp*8*I+Gv^te^vscyyM%{Aef)AaA7wqW1SNSWQ?gYU8|>pN-2B_@_kY8_D|Rpt +zJs9F9b>>o6BvTj5B~8MIe(qH^HA5~r)D@fWkIoNrH+SYz*CkVhvd}1Sfj&Ov=BKl% +zD+NW^l@XeRE`J~YhMV`YsTK0(tzEI1!RX8Y_ikq{H8PpHTHd_7D|RFlb^5ud*px+3 +zHaBH9?-0%f`}l|5d=Hx%D);W~imeDlSA@6)ow<}XnVK&59_)%e=8rxWS6RrCW#TKf3k +zx%pqP))n%qzl&#mvn#!`%jtd3we;~ +zADeET$*d`*r@{Rny7>=S>-$i*q?^YuYv5BK^hX~IazACQJy0K>Zl1z?Rng=6HsLI= +zQ)LZG?TB>kRK`+9S0%F4!U*+%SUaS{*IemsE~k$=sA*#DWTv@-{wk5B3L;dMSUa-A +zS6l6^Eu(84l&wLjEl$@CW!fuyTy1e@n}aHDP->^7YsWFLJSd)}Dk9Y7V*At%pRLSm +ztD?`uv(%;tHA-xs$h4LBxQ->9>+RH?4NCjibo)$(DW!`OS!zy%S|_#_boiJmFH=Ex +zB(l`F2z9I2K8oqC?s092JGVHfl?_V!th8+qGp4e~wIlA_;gH6Qwu?J_V=BC3YUs=3 +zS?LE6=_=7y#59%B_d2BOMcd2{-|ABD>Pq^T@vQW-h;*@NvoNbGdR%`@I2YNaA2ukq +zQEA(B=1f_SYg5Acja_9%3av8ojw +zrZDM>9#>z&IovLlH7Lx8G&7YcE~9G_S!rQJdO&1`bodTedJmV=FF2%WA~TseTtWXe +zk(CM}QkBSz?C{amUb>8?9Fna;VT#ktP^P1@$Mt&L`MN_YZcvyhX=WVLQA3Z5XQhgW +zbh+3)wZpf(%)7jb{wSW6HbtaSV)sNQTHfR06V8ox>COhFdu+OUCbOlKo|VW-b0X3@ +zvAdwdx24LvrGowQM&nJ +zX0~^2SL}&U^hbW~SFE)i>P6}1Va(AjYrA3}2cjQ`xY4ZjOQ?@bH&0{MJhHYc_DV4N +zN`U(x_?@v4>K3ti6!X<%YrA6q^hf_0-7Cxu^zoAMe>-}6yXD&QB8D1i{ +z?&yli!KfVIdfD(`L8;%HsoyCSh5Gm_-Td=xc$%QpAI#Km6JXg^XD)0@hR4YD`@3Sv +zKr|WR#Oi<))8F`$yl!iuPrSb_vxXZXxTrMlRYToC@{vBi;Ny)-zF1 +zS`K7dwhPY(x%)bEo|2?znB20jE4DTeT^r(V=*)TMCp|OemP5j1e;>cg%~!FWg@RJI +zJyX{xJQ?WYzjE^y)-zkK+tn4jJrw=K&$V^tJjF@RayhwGSQ6~xSG)N$tY?&i_$m$Rv>1f^tmrsSY- +zi@%TmrJKKvO)Zv7b_gE^xlL^9MnMs_W`w=M{6HW7zMHqQskySSyDP?pq8t3&vz@ur +zsMZ`N)Q@*k6Lt +zzXZ5{vDQCq+N3m(PdATXWllEt_wu33vt&#{q_j8L~PC;KdzkKmN~socrd`7h5F10aJ?eQ$dM5r-h?W7K0d%3s0nr7lzijGjr#oAent+dBACgE(dQ};F~ +z?H8rnFJ^2NJ+3ne=R7-gv)EqP;cKh*ww2NA6Ip6mgz}2*gBhl>$8|XFJnW#RG$`$s +zbo&^Fsp)Yok2{w;s0CvC^bTKlnYX)&&c?HpFCq;RZR0z9W6Hf_s_6>5WN%Pxqtmt- +zOjBu(>+*y%WS88cZ5Y#3MSp3Re$k-V2B&QknAPPyu3sjcx7np1i?%TxzST9}Go|#R +zL{_>cBHb_AhIjbRRC&)-(BC+uAq`5~_;lL{W?prV>*l!gW`}fLgVHu5-8O_dR!N8B +zS*boE6^U(=JAB6~yvJ(j>2|5QL1`PAZkxueFY9sLnQ(q?mmX?R+J>gvCNb%9`i(?Z +zni-LtV%xY5U%JLyTuKj5WTi_Z(%m9+5mQ{%<9avleAgk3Y*3hqX{L}lTuraDOLvIO +zSmtm|k84WYImIE(ZcvzMX{Laot7s{nm6(V$Mr0;+_&UnH9o6*1@vKBgq~#(ri&xiWFD!FjCuswEdkL%L7^HK-JLVa=4I$G`>&g`n9|7@pzAzJ>t>$uXmH`BONxD2j3 +z;!cNyS}aA(ux$75vkfnYap>7l{vzXbxxVtMhF&Lc~;NF4y +z#0d2xvH5>?9amNz%&gib{3yu%80z&Asz_|kKz&bU)gj?JKX(A?S4OC{V)IwKjw`1d +zGpBb8ufXr$5O?0-pyrFseNf+#IlW)_XP}S&&dm>D!_2Q#hPg!*6~ +zU+3nNYNe?h)h=H>@)kzBC!0AlD!0inaKoEkSN=XD)n0GF%|n?-S|*ef%eG +zehC|%Cn)uMGWCZ9*izS-3r|Xh7s>MWu9y&v3IVRGGZ!A749}6}UBc#2AHTxQpJ2nY +z1VuiSDcULw3-Xg>p-y@O+?;|C^hi#(J(4l$KqYmL}o6zmGre<{x1_E9APZU9ri* +z=;Q!*vNPuyne<#O*X{0#JsFDL?&q3Wk3~@Gnlg1eginHfJmcoOSE>gs_4hY#QY?Qz`k8gST=?C`XMF`_-hwLn4|eMBPo2+MFG^akkPEv%KI_|6 +z?cG&ID}L@J);dEjJS1H9=HedLgoN{PJN19yYGKkkS8m)b1Y?VPTnppQg%0XPs4q#T +zT%zT#M~^Fw`!kJugujHiix!;8QsoiqGO_tzM~^G3wr5r~3Qt5A_qg6mIIp%-tHfp* +z>P?wdJA{ux(m@cVZpoS)gL4E)aUq;-ybdYAAZ +z{Qe_x=OYekMT62jD_uK?u~hcBcEz2$9MlA{_TmnorNV2ep=Zal)J+lUYO%J6X)dGJ +zIH()M+L;}`+EQe%74ReEjZbWfdOl6Pj)wuIjhcu%>u}w+a#xZAV=uz>kR34Eo6WgYC_~w;)=T*_~$FtId +z5vfpYo5&n1?{S3_PLExxYf#$8rrTyR>r3hBiL7*GL|QAh6?FL4S9#Z0(4Qx=(%6V} +zi`X`bNmuu{ym6=3A+2ao+GeGhK}>OFk84ldxyK<*5SfcRe8m;s;u?BRJS*K4k**e* +zBIa-zz0M)sATl#Md~~UouB4xeXQed}$s#fqhOX#wNeSmtyR^DNVMe8y=}bpikL%%t +zv&SxN5xWO<_?B0CmzUFr5?N_dM7mAv9^K(vUgM3H(hD4twL$4FN_P)qqE$Vvuj9_I +z9nx^IdqRhAOSyMTHSLOLB`P8<6}yW&eA!ZOwvvw7rHu_r_waQ06sF)8Yr0}XPF&|L +zD5tl%p6TN+ar1uGI#n*roj&W^RqEYUNe7(I^zm^we=VDuC0ZskyDI2EJE)!1`JDB# +zq;;a)_}%HVzN#{BRTZ7EQx~89dR$8}TOd6R>B1>W6|v=+##_6a|VUf1LLZNhnGEm#)UQgtUsck_?Nk@k$0e-`o&RlqW +zGJLH(ce~IS?Bnlo^M7H(7YWMTeVMtt1j7#0KEBY+H?rZ0g3@{*)4E+~4RZCJxo}A` +zJWOug*A=S|MC(IbNoOuRKN+4Ww;mFT{C)gxH($+$7Ya)K_Dp@F&=Tn5&%61_?DtDh +zyJB^rXwuKU)|m?zC&SBSd8<$o?Bj27^B=O|QGy~jX5`(15bEP+y7?n)c#14Hb;Wx9 +z(cU2USZ6N0GU*v47wzqe4GTnvg}6&u&sBm_v^!IDP^k9z@sGQC2kTiZ7wr&E1-S=U +z&y9l8vNhAPSGY3J$G_+1uVy`S<(A!DvFAh4wSMlI&YWj*(z8Tv+0hj{AB>(4aNn|? +z!Gcn^H&eG$m>lZkXS?~MtY?~_)E&&!Z4+(}a|?4oBxtcT_h+a`!XfF1jD-EK7N#&-_NEd3W{(bBWxGAAm{1KrAm^iVY0BV +zE4CpJ-4NoIb>>p@lc|}qa7dWx@8kEl`5HF0P*65+&unfKjs*Jnzqf>j*`RCZw6uGylE0*&| +zb3twpeWF`Hw^VvTBQ#bE(P`{SW=dAOS +z)|qnSAz|X1OL|-*6V82h>Mu|qnY3OlugWCP`exVs-|z+MTKJOGhc8gq!j~ioU*PvK +zd`X(&iy6KQSoqQe;mavCe7RR2zD&pP<=%YZ%Q*~R;3^4UzQFJW>RR}6N*}%~#qi}6 +z318r!hvCa9628Dc55t#JBz%GUTKF5S!aeXX81B-;mbJ)Up9UpzQhdSOO%8!(Y)cy +z*BHJ;_2CQDweSV%TKKY2AHH}oeA!6C7kG!^%SIBuKpn%EjU;@5x)#1f_2CQD&G5wx +zUj`<8Spnh8EH!)?rw?Cz7`{OLe}^wSNcaL*F?@l#8oq47@MV@heEHX1Bz%Fo7QXDz +zhc8gq!WXEM@CE8x__Bk9FYx;qzChg!U(E1jV8WLg2wy^K_>$0vFNZLEN#qM(9>wql +zu9EP@hv5sBASOYvId#Bz$?)5Wf79gfBh}U*H`H +zU$$WQ0(BC;Jci*5)V1*CJ$?8Bbu)Z1! +zf*>*{kRlR9ZVzI0s$;*msY+iW$@5#Ab9(RRtUiCeE46;Vb$`!V?^<`Q{hWPr-amSM +zYWroMLz^#97vYNtUs@-8Spnh8WF>sr$%ikOD13qXe}pgpLz^#fDTXhMHeaBwhA)%( +z@a0PiUnXPt@{4Bk1?o!plGJRzKwSx6uF~cU{0@dMDY5w?!k5+yUoL*{=y*-pd~s;P +zm;D&NyrvtzT%z!0KOeq8T@7ELu7odFHJdLlVfd1w%@^py@FhW;FHpzuVO5qFCmGC7=;mdSQ_(Gd6 +zP*=m34Se_lbv1l}I)*P$SHqVL7{0*oQ}_aP5x$7$~i-p3M<9zr6bv1lBj^WESP5AN-hA)i57wE(A +zB}w56)G>TXQTPINHGDbFhc8eU;fn}gS|@z*L-=w@313$5;fsU97pVVd_;LZm7r2zd +zmkSuayiVcEB|dz)M&S$8)$rv4AHG0c4PP$s;S1E&@Z|!AFYx;mzFZLDiwIv@EqvJq +z;mZ*ve9>&a45#o#ck?Ah;R{@f;R~bi1?p<}a)b|Grc?NG1j84&AB8VRFnodgQTTEM +z!xy+-4PS=y;R{?Z!WR*~v`+YP4Z;_ugf9+F_(Gd6Q2)>H#X{kWX7dH=YWPB%FDXs< +z62|a_QTSrv!xy+-4PT&+;R{@^hA&W8!xzow3)DsUBEpx}318ae9Zed)VspZd(7-NI +z$Kt2iUy^I_)t2o2CVwK?OL?7A^0xh{75^CipMRJ+{+2lXI=e-A2N^r;W*2`c!99L< +zVD~jvss87(&Y!31{xMu7=hEL3?_HdZ>&e&ddYYO3;ZR?IG5u%@`&UZY=^uZhg_X}em +zhr04VqkaMYFSk|rm)np4{^bVu!@t}z1NfI4+ze_5b+GE&oRR%dO`EZfAKV)Rn*7G8W*@ +za=Y!^3uAkKi+{Pb-~R6x#y)u?|CbwFuTZlL>iCx%T(A7)_8`=izue$a@t@7S1aT)W3&YbK2Z07Di@c(RP^~ry~Fm@Ew|Kp#{bXkf!%Wx_FvzcB?ac3Fo +z%0HW#HHZIaGwpW%`-QR3&cS~+(`_lYvs?ys<)6*;Sjz1z&xgA5&t|$V#hqpN9sFlA +zJ(r4|WwEo|T06_V4}I_G*nQsho#oEs=!LN@Y^<%<19NU{)274QmGp&*>tCzzU1}Wu +z!pT?GbezQG|FX)xo!JZKTwxg%@r+9ELGGP@9VRjL4gb&0xx&3tcJ)c7COMhkU4u84 +z|GC=zM<@=9!0XCadHZ&n#N^=#-{j;_1?ESPhxU^tNd$cc4lNyZ;;B@$gJ1tn!`CY}=eG?AZGFv8~?c;6Z+Cm7jKIPmUhz_uV!B +zKWlyetZ`p!WMyq)Wxb`$d?p{X%JBB(=&1E6%i*ATM5*zCW;UuKu6en?cT_bq7I};# +zLS=)K{yo(`czv1EH6`I_$h9{Vn(710H7Vli8QrrvWoZeR;aeD?hTchkR*f&K&ONe` +zHS~`)beD2Um^{EL!@K>X<&`PRvVeJ+!FX>oE8iBs{`NBWtVY%_IM&cnl8TtT+$#U< +zbahTRS_3m6Ll=y#uLsB<#b8Q6*@a{6FEhpjFn`hr!WNHd9+qB5_S7Ul7 +z)v)j)Pk2D6J~Qe6w8r;ooqK2_tM3=P{;EHdJ-}>tMQp>Pk!>kU=YYAhA$(Iao3bT- +z{ncge`Hf5(5|i3Vy9$~7s8#0QjOlD@mvER0?WTOwJ3-cz5xM^2Wv{!Ag?o6yGec6h +zqkyr8I18W{LIj#8&U?)hzt5=lXkOrDPtH{Z`rG%+Bq7 +zg=Gvn^!JwG(Tx6wuKC;5`PNjstDV_Tz`@pd#%gbVr*TX!waNi!c6WNQe}3;P|9+Ef +z=W&bzoMDHq{rg4bc_&!*q)2wp=%yPEUGx9B#s{y(bY{=(eTB_f7oV}k`&Nf>O#Z!9 +zUf|4r1&XWV@S49GcL+LrM6yRmXAC@a&3~rO2XB#eW=Gz$jKf)cbJ^R7tt@aVB^DNDzIxud~&Q!^X2B|Zw?^5>q{$jXMq%Gya)g-m|L +zD)TRqb-LOm9A$;}vV2ojkhwA<*WXd@-BZVmJv_#lp|WmCe|eoRTJ82Wva(*W>+f7P +z^$0RopNMN*w0upkeLT9=yRw=YANE{-<+9Y0$K)@q^6O65^n{~FuDwU0X>EYn#zwBcLe{&! +zhJ~N;gu8@t`X>FwH9pN7%H3TXSx%o=PFHDWF_Z7G%J2b<=#H%^%Y=Y=f+2ioGuu%a +z-?7$vxt4{edal3FUm9J=DWF$n_VLdmpc3;Ve&hcBsB* +z(tobb2j9PN+WI9N%ZlyG@=Q+!neB#%?cQi)b;@#Y&0`s1~}c#S*R$fPzg +zskbyVpUGcaWq3b%bjtda3PbqbX0~!${QCR-+z&Uhmcg->j?!yIOkQD?|KV)voNy!y?eMV} +zLwI;IOKgrOHh9~0$YJuTypv{DA{xAtumCnB*WPrG!Zik4Z>iA}~omCSw7U6AC6Lcue3x#bkmW +zCSwVc2|Okz5R(Ih$q62lv4qJ4!~}|n33RHMoZvATOPEYROrVIEK&QY&V3KZ3CNp`} +z0R@u-8cZf5CeP?%G8r*>hQ|bMqGIwrVgg0NWHMs%3}G^v$K-p&1Ud=(OxBOp!=wvhvSBQb$w9>ACc@+(k4YEAWZhWA1d50W +zbgGyfa6%!GY`}Ht^M&(16&)v^s +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 +z<1vAosF?2J0$>gNiGZC1y0wx0hlfw!onmv=v +zh{-3qlgVbp1kPzPp*@p32@}np$!5f4A5A8kc}(skOf-8Yn-LTEO?5Ka%wqzb0uzBr +zx-o&w(PZM%!vxON$;8ED0yj}Hp*<5QA|{{EWa2_hph%Mm?U{VUV*a5Nh@G72{1XSV4~SG*-4n_P9{4E6U}5odnQW>6V0BOrp2<$ageH@nJSNa7FcFxf8xzP(&MTPwU4sctCi`_Up~+-Fj|tpF#f0`uph%d| +zWU`+y(M%?^XYzLqCN!DsCrmVxiP$p{n6v^WJpq%i6-+dHCL0iw=X58N4TuSx(_}(> +zCPN4l&7R2y#N>IJOg8YC3?WQ3dnOwY6ZlPaGTFdm0-XXAfk~P%`72~5_b8bBmdE6I +znoK^>!vxON$>akb6S#?r3GJCc5ixm=CX){k6DZPTLVG5^VO9+RgD6V0BDKHV3q#F~+OkPni`GUvf3QZ=m9wucpAlUE57&7R47gb7V1@9~&Gr@%yDl5R{O +zGr6i@a!rE?O(uR_OlUIk^O(R*R7_~k1d4GKSwX`C=7flA$-5e7p)VfpeTpZl^tyc8Ezfzh~lHg_v~1$)t7_ +zk4ZbkQAiKiMdfg(;OchH{68Xgn)O=U9KTaB1N5hs(;V$bCNT})c0 +z?~DJcL#K9aa>wEa6+T_|{QL`_F1z>qisoM4%Tukg$!VJ$jjT;s>_PJ{rQz3`*_2iB +zDQ|dt*0AtgPqMso~VDewAazAI&tqI4jeEY6q)8f+blOd_6w5!B4Fu#q2Pp-KPpYTxo&_fw5bx*;ZYmM#`C*>078aW=J$u6!e9*%mNwGlcs! +zvz43TE7yB}SI5HLJmCjJEg6!pn8}l^@@LMbp$Uht#Qs{YX}BSLTQf^+i6_>0zpQ29 +z$)4~_p_cYZ|Le8B*K6FDoK3wFj%1NNSzv0Lv7H&e%3mbsIT~p)! +zuZj~ayF(=V)@VlAx7Ymnb-shu?msxQheR{Bd2gUdbcJo&7~fRkoi}hilkc|5e{^P>p|~wRW0kjWt-BC9$3?QcMrX|a_L~2#8sA%W +z?*3355y{Ss&ZzXB=|7&y9;^IX_bj<0c_fQ!0Cva_Sd9{={5|C2i3 +zbJgzOLUCXudvf&HTJJvxjA!zzR{5IK)h6M{EVO6ln<|3L)g|J(JvwT=cT*iRcJ&w^ +z2$f|d{WI!($Ew|*I9)@cqqccRRl7Geva+tRvcXbW9+UT2<#MNMN_5ZalqDxyCsYr@)?5Vj3M_t`QMeX0*K08>wc- +zr#!}cLk+`{{wdYIDYfodPS=ElL&~#DMW%}Z=DIiH>Ku)3Oj&#Zv(I209%>kv^e1Y3 +zi8^=NMwZh%meWP*QOx9Z +zcS-sO)cJl>?cUwU>buA4he&&KnOtR+%bd2H=98d?3oSbZ-kR>I`=R(Y+nsdvILwAem0 +z&s1Uvk85UAw#KKd_Rgwh;X6FxB_XMkw5!PUQ)&2>kkmHmA5-faQ{z6~$fS-jDN`~P +zn8HEU)G5+5GU}~JSw0JzUn&ionwfV)+`G*?tlGVyk+pP*wG5J`$}2*34F}jj!D7{h@}1?VfPwP)i@_wR|R@w#s)oo3ay**9z>fm6)anSkrBh +zrh(B!r8ia0!WK_>dMLB{4_6%>?_3(sSm$jwa1xVmw93`a>_O2C^LN+$`PIJsT6by1 +zNtQh^lHEO;vDtgD#{GYs+3lj6p7`#X|K=Ls&2{eE;e1piJ1e?rt9M@iNlbp%DnH@O +zesS&>uFgHxnZ07}6?SYx{Ma^cMm00$d5kxO$_6FX0~Tje9wCCo;r6{BP;6{E9)jT6f=2> +zRrWev!xD~$5_?XrsfWRMOEW9q5-(rl-BHVo6FkP}Lk;bc{@Jy@*){HSPFIhFqrS*q +zUto#_nX7%obxSn5&O4=!83%fd#!y3#q~BZTTUqV?T_bDg7HhacYRNOb7G$pB5!du+ +z)~b}HebBtNG(4x7Wvz*4ZStrENuJ&E7b-&Wca)!t1+eo7eO`8ME +zHZEf88lAlBqzgn3OA+3wP$>A{xAtunNViMvpF%Tv>JSHK;1UgkrLOdo0fr-E*{gcTim`vs=n2h5w +zIZT+G(8C1IRZLFsn2aM#CLktIL`lgWt5vxLcH9+U486X;Yi`JTt*S;Ay8kIDCl +z33RHMe9vR@tiVKIl738Pz+}=_!K5pX$q2&apdKc0u3~bK$D}J_^3GVq1d50WbgGyf +zL`SaB>kBD9xz#Q9g}w^@|c`KOh)Kpat1Mh +zbHwD=6A_aK5Rbc11~GvmVIndUfk`W1@)2NSQ!vqFCg%{7g}RuWLrmbDFrm!kNy0>v +znVdsRpi{-<9FNJ9go!3IIfs})r;5or9+M{pCIXXIzyv0f=M+rt;W7DOLhcKbc1d50WbgGz~LQJ4Ym{4YN50434q+)UkF@YjsA~F+!Nh@IT1z@s5!9tCK(DQ9eGSL36leQn83M;$pIddj);koG7~5wCeW#3asV-bB4Y9wWhNbYOyD9F +zlLLqe6cLlhMP?!}X$4GbuR1z@WWA1wQInYj5tB?^OoE6BoFgWWQD#zvn3QQUlOSRO +zohl|l9+M)(1fGd9lOSROohl|l9+M)0iNK^4FoDTrhJwim9+N7<A_=?LzsN6hY6gkn0(D+ +z(gQIGQ)U81!~{B3Ouj};poo}+C^PB7V*(ecn0$?xKoK!HCo&U(Nh@ITK47BknS?c& +z$yvlCM;DW`hzXn{CLzj9W+EmHn#|-ZVgj8iCTDp}W+Eo=Oq7|NMNFVm#pEoH$xMNX +zz@!y0fyrdHg2`welX}ABxE>~Ou3~bW$7D2NLYWB^5fkWCF*%NyK#?$^%w#l=30$ON +zavU*%B4Hvj6M;!9VDc$oqU@Q3HJQl;#H3yqlM9FmoD(LLnJgnrG?~c-!~{B3OfK-4 +zEF(-bnaKsj1UgkrF7TKv6PO50(vL|LCX*=&CPR5lB*Nr~9wu +z6Ut0Xgo!3I2_q)ZsbUi5F)^2#beSQF_}!62^0|%=u|L?e1(`m5iyxa +znMr#d6Szph%uy_WBLCj_uv1&6*JBF-WRJ`c$OzTCRBfe6w70>&nmy>v`tSqhUVIb7MeB$Sku@@QvZCItDa+)5 +zd9ooqx|w+^b +zd2XrkiBM)wsiMTxr_^`|&b!7k2TMgutSO5jXbzSdUkGK^)m(KPF0>!cH+_7=4rUzU +zF+Ls2l%ZH+ACYV7YB1KWzs#xz#i}|;BbHfHmZJglQG;<46#K@iGNj$brX^WBm~pnp +zI3-l|WzAK`!d&~pLeutA<7K$0W2`DuT4=MTEa!vfdrFO`px7-|b%XR{p6M0%&HFsY +z*F$A(lKzZZUq+4lU?VH*5G(61WfqtY2brrw#C2En~F=dt- +zi<;Sy3EUI&Y^s7Vhl{mxgk> +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 +zCKK8-G3#PNdnRyBn9yYM4q>91OlZ%kB9 +z0FxC8CZF+`{6LuK?wP>3iiu{=ZE>ba}JrgJ*Ch(hLG7*zWx+jyZU|SAe-DL|omX(M>7K +z#en&u!Pu*rMK{Ky72cI~?)w^9!@yWWFR7)3$!)FjYNxGt!qKDH-XqUcUIWaldCjb +z-pppNjnCffJy*lRD?Q;(q53}3vV10=w92EMw(NvsS%H07iRs<|v)vZ44U9%Az42-m +zHhaSNh3bbV{XMIFJ!{Hl4=?{_uspBh<9yI4zK$(L`EgRH4Xq-k_?<%X2yA3^i*(r`(r +zrEAiEU!CvEYPa0TT6)A@I;|j}I9naY4&2O2^&(70nz6xqu+H7ZnLW>Og>70F-?YVB +z+dP@cPOEHnW>1N33SPSApI7UfSL6N;{x{k)l07E6DSYXg|Ic;4zSZt^&TNC@3Y)Pd +zK4Xpdt@vanFR;pgb!HbqabtW&h4+y<_eAI%9myUVopI^XHUIc(-}qYhL(c5y9aq?~ +zHSuGcyq~}`{oN`Lab_=uVnzH|rT3rJ?k}KocqDszbkwSprDM=sQEHsq%toz=kJ{wj +zRO9}0BP(kcE9)y&()n_iXi+ +zS2N>Gk8yOU?1rR2TJ4M0x>q)`vf;6YHd0QZsWQM^<07uE(eh0x%gKQGq`}y&nU!yh +zmsfaa*ST4Mxq3ugqod^;QkGcIJhaqU5^Ct0^iQetd8^&-M%K_H)-Y6R$z}5Itg_kZ +znjDR;O<7(GnvES>70-IZ+o^_y=Xk=sLplAW9tBMPlU45HwB4F;ROZ_&i%s)O +z!%u{AdP+BCS^&x@=S{j;d?^TFv*n5!q?(A&3DdCuwZ=Y6ddN{zE +z?uaxEj;`FAvfLFg-(?7Ahg!0d{vWD+Kh(NkYGf_LVl8c@*9uMV1z6LBNK?0HVpGa; +zDPX>22={7ciH-3@h4=M3_w+{AGBDQCOX@giPRi1@^Si!wHSVw4pJ3TtBH6b`GuC_8 +z^cu_L-d6cn&g@W|D=ecjp0U<@u-5&IGka=u(<<-HJ;yTneyjYgGy7PZD{RxI_@?#V +z+B)|jxXH*!_JHW7X%8OPneMd8A33uxw7J5L +zZH*sW?R^d&W}_+`XF=ljJU=`_iRX6T7u>trN)9#LzkpKtIoHh+WmebYv>+p7$Vi@GWj=F`EjQ! +zCz|LbF!|qr$?D52^O@@Fm`n|DnEX#JV$x%x4kmxjMNGO+rCX)jkCc#|9 +zr02wcV{#aZhzWEmm`o3Fm|V$4OyHRmOn!nQVgj846M;#(F1lS`8-S5tAEr +zF&U4T+{j}BH&HS97BPV$VKN>uxsfm#&tvi}Vgj9n$#}%%M#5w~kIAjAn9LzeCLtzJL`sm +zgqT1lVKNRe=}nl7<1slTFcFxfACnru#HnBs;xQ>DOmg%vDJ4vDcuYcwNdaLJ;xQ>D +zOmYwtC?Y1%sbUi1F)1ZXau5?JA|}u&FcFxf8BeMk%F?z(nM`isG1*3$Nf$j#wo+!&g~tSLqGECoF@YjtQc0Of7sOJCh5oIO~B;$3MOZGOzuZaDs?lH`w^2Zn#|-3VsZ;%a)!s` +ze#B%eWhPKWOrTT6EX!bFpqL=clY!X(0DVkJx{Gl3#v0-Y)*5grpOVM3V+6cH2X6qpE1(v8Xdl%?$v +zWipws!GtoCLAsbwW-^G!1a6{Y@(p4FMZ$zKlR<=uCNud4F@a9Pgff#sgo!3I`9@$O +zFiAfq9|I;IDVUt&F?oV8(alVrAWSrw$vMPiK4Ef>$K(mZgfbH-A|}wOVsehhc{5N3og@VZsJSHy_Cc2r)%Y=z0Gx-5A`3qt41CPne +zgb8IPP()0iQ^n*59+Q^|6Ut1Wh?qd9z(in@W=!6NJ(Js%$)q2T$-|VHbkM_O7G)+K +zcue3XDkcXI6DT4kGbuCafS5d_$xIF)CeVqPz%!|tNe9FP9)vQJ0|FC)N%}F_2$<9= +zm;`xD3K5f;x|vBKV)BqCGYKLl{RopFk4Yh7GK(@3C?Y1%sbUi3F)2h$;F;9S1d50W +zbP7xaCh5im_DpV5CX=@{m{4YNt1c##ncT`_0yj}HIf|G-kuagmCNnvVm_R3CLYYZ_!bFpq92S@eOwy0Zhk(f*1(OCIlg9`X-OS`M!bFpq +zG$1CA5+)5iCXW#&l$k&gF@a7MlLj7>#|RV3OrVIEK&QY&V3KZ3V9(?OWimOd!GtoC +ziMp6jW-^h-1a6{YauP9tB4I+A$wb0LlbM`EOrVo6q0D3=VWP=QP6|u}Ch5oIZ-9wc +z!Q>*3$qR&uZf5cVVWP=QE+Qsp36qOFCNB^sl$k&gF@a7MlZ!kiFAye_nLrUSflh&m +zz$D$6z@EusWipw-V{)1@lkR$$oTAL6JC6z6M8)K5!~}|n$w|sgx+5khG?~fQhzWEe +zCh$yZX3`xofd`??cYzIuutWAYGUa#A-lc?dB%p~+0nA|?|Ele0V~ +z4Ba>1OcpDX$vzDxl$qSAiwR{W +zck-CPO;k*dBPLKJOeizClQ7X_CdUyI=p;-iGr5y6(PSpa1ttQM^kZ@!F!@x$o2Zx^K}?`Xm{4XigfP)$CPxqx=p;-iGZ{jdXfl%{ +z0uzBr`Z4(&FmWrGgn3M!CQNiQlcxz2O=c2COr9r9!aOEV6DE|IKoK#4P8E|dkIB=7 +z31ucwL`7inMJ0<0p_|p;_46` +zwJ~Mc9Wd`U7zc;S21r!}rXLN)j?HY(8}U8syrb%vG1Fr#3zhYd%1W4=WtDe0T>}!1 +zhGKg|o=FNa*RY7|zG(R>Z&occ-r_ON4>fd1`ghd&cGS2pH?oFyv4*}r$4Apt-2jXb6>cPx?32`DRqR-)dxK8L_e~ +zsVdL3&|thLR5na1%VqK=t31Q$8lP~K<=M-MObw+*shRCr9pAIjTVBJA%RI)Rp|XKV +zf3(IIt#fyBx^7B1a`Npt#ip47=DH)|8XPU(nzD=zm`59o*`bCk@sj%g4KJy`3fz3D +zaKnG`a^mAIi)1&YYc +zm6NP#y2p55sA_o9pHc10sCDNzva&(3vJL_h@x_z>+b^Cx0h=fTmD!~mkI7w>s=tNB5nbcIJ9by6xf~m^>uLLGy +zc1i#2QURFMT*u@K%@4unmrupJYK4LP4QWYp7CeW#1 +z;@5ofBp)$>XHruYC?Y1^1SaD1S?T|L))TOaGEkXJHfu1UROMz}Oej^kna2cfqGCc{ +zJb@x%LaEBlgbAOj?4vK9Kqp~BsmjfS37@L$|5jikFiAfqhXIq16-+c=JefzB=%y<3 +z2opY4`Ix?VvY9Z^eDP!+VM3`26cH2XR58(f@njxhLa7QA5tGdV6M;!9U;>*c?Rr(Spe5$hlkibM> +zl738f1129Tm}tIu@(5v~o2ooQnDD8}$MnUM2MH6+7f&7`Oej@>B4PraDkhpQo;*UB +zP^tn&#NyAL4k?DB>k9F0VcZ@ +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 +zkqS0B15Iw<C`aX}5 +z!r_U+DZ;rjB3`nHLp|23lw~{8=DlIlj}7vD9c0({Mh6zV1_`e(EUq^(20$)zV +zA6vu^Jn@`vJ6~br%Xrx+kLe)No}^SSZEzDg-!JnKVO%QM?hed!_;z{X6T0n-D{YHQ +z_oXZN4RJ5)HC7(m5;@{K6IZ!s+XZk-$ +z8nmX(SA|Sh89C4E7fEhjB6pZjU%~&Ef%{b?cc4)5XKUL0M9B1nk$W1}a}&8^go-MD +zUV9Vae&XkDisbhAF4<3)*iKjQ|AOLg{M?{O<9K1VWKEm*giSv(a38;Zku;7@G|mu? +z{mGg(-xxN%Xy9rhjTe2F?8ho>$IAGBz-Jof=PDzOBZbwctZDNDA=3j!?p4^CpJ*H` +zd<7rmWXN>V$jyv2cKI&ZzbdnRRmBet5$}~z?|5a-zO=a_WU4T7^CHzVQo*H;z*3j* +zz8I;_OH>aN8Y}p(4BW3H)dPj6pI2@~(AsJB2-cBaj3Vbfv*cW(z#>XXWTsoUW@6(g@Va0W|W6S3MZt3*Es{% +zxqUarNMUZGaEx$w6~7=vtk*@Yla;3ZY4f8Y)1yZD&JNOaFu81tG}+~=h>@15iIyS4 +z+zKMDwuoPOtV6r)C(3OnN_nqQ&g&q{_9mC@l0J14d6-|WjI@jtYAcC2*CL+qSf_W} +zYpZODV*ZXWu}+Cv7b(&0Qqo1_C4Twwh%g`(9P0{gG) +zTBWEyZGItaT5FIWhzMhaBUStqgIv);q#a3VpX758x!NxmMudE!t(b_1E#iZo_`+^` +zTZyf$g6|5E_>yRRpt5PVG}B4sRepI=r1OeY@TfCz)a{!RBb^fyojF3FlHV92@ww4> +zzOw0H+B_>{nq`!)k91B;1y4Bwr(C{`G18fz=o~Dh%86*Uh+lf*i~nbL{Ue02&m0~gr +zI}<2UOomfTHZP}`K#^iH6FZZwEGF=fiivGG#RQ5J6ZoBaXQFo|ecYM+GjusPXvuBg +zVKR&DOzakl$*yde{Ki5tfpv<>OzcdY6cZ@Y&SaB?VzP^3@+%9AiIZXipNV!Rk6S1v +zuv5hZJ_vRuP8|~+lfK8~AYgKhipdi!CRK>Z!`U!_bq$k;SxlZlOt3S7BE_T%F?pC` +z0!73GJCi3^OyD66lZPoLP()1h&P4A_`o1&y=VyS)LKPFXGqJCyn7o%2ll2r6SVv5- +zGkFOyVLOve>nSGhAtvitOkP4v*v{nf^%N7>sbR97#pER&6CIPj$K+nXWRi->9u|}9 +z5tEhKFoAUqla(wcdnhK)V`lQS3}!q?kYvJChoU$qR@{4U5T(6chMN +z*qPK&Okk&mNezq1i#jGcCVh{|M}Wx!6_Z0OCTkIsHQ6wMbq$j>EGCB#6YNZ&NHJN9 +zn5?0gKoK#)&g2k_2|T1>vW8*;MZ`q!O!UsAA3Bo@fQg!!JfG2-Y@nF@Ju4;~C?>Fu +zm|$me5;4i>Og2zV{*IVzU@!J;lU~oe2~vCQ}fT6%-RFQcO(PnbfnGz(X1)D<~#Vq?o|()H@Ts +zGwJKjknF(J|?JOhmw>K*gky#e_plR%gQm)-_C4vzRm@CfJ!kkz&Fj +zCaWnXP()0yGihWofrm6qR#Qx%h?wY|iQbv?LuV2NOw`Q8oY9%oQcUEmnAB2CU>z~R +z&ZGq~$>>aKDJC*vQp;k}f|z7}N4qgqUQV +zGl6vtlZ-i&{S=cgu`_`p#bgm;f^#NNq?mkxoymR{6L?6&1m{ekNHKxmsdpxNXVTZ5 +z$)|vcnwfl=(V5_!$!l3L!8sFHr!&3Bfs&gV`{-jB_TiPBB@6or#-b0!7-HbmN@KL5j)0Gv-X(6chMNv@=QL +zoC)kyF@X<)b0%&b6CIPj$K-jy4mt +zoCy>W6YNZ$Vljb-G)!>L1d51>-kIo~Nk4QZp93apW^xzXnGl>a`6w$UIA;RuhzWKk +zuOKFDXVQ&xCLbXt8FMDDASP^QlEyg`*r{QXF=z6Mj){&*-(zA1Os1%q>}4^z1u@Aw +zX9DXQCK+=kdnqPC>`b6YF}VdX!8sEsQcO-^XR?>Y1Rl~b!8sEsQcU1?>Ya(+ne=sM +z(h8WUnMp9CGr>6%F)JoGX9DXKlT+B4cqt}O#LfigOhm*aW6s1&F@ev7oe9pFz)lU5 +zj5!mpj){&*-(&J6V6sTXiLM#LoRoC&OJm}JbE97asAGl3$-WFumNb0$zkOt3RK +z%whr$X_(-g2^0|%y))4}lYZz-+5i(ZGYMvNCOBvEbyiGp&IHyG6YNZ0M@%w06Pz>o +z8ZpV3GkF~`$>>aQ&IER9m}JbEysl%SW77AS+y$77Q!&}aVloRc$vS5O>l!8*b0)he +zCU)#hphz*9g_z)+2^1+Nk7H-Di^T*U(lEg}6DU$l;CJesiQbv?b!YO)<=~*Snwi)$ +zIuo2Tc|I#9IA;Ru6qCoXGkJkx0!8dhaL(j;#3WFyD)w}>xz;?pFu +z=|FPRR>|b@aj|r~Fd84DY}(r%{K6Ud!tER9iC-g;?j6bQebOmMk0@Hijh^@&66xNW +z?A{|i?(}^bOUK7W<#?axcGdlH_bn=IoJ5 +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 +z<_MI!d^}R1<5W4=Sm9 +zwSP`iPNwhu`g!{I0AhajRr*hg)TP$8-E~K_V7PMT(wG0;ZEm{@|6Set5NZ3`u77jW +zzq$3#H@6X%_TZplYKk+siTUO>Gep0+4Qk5r&242d{pL2(!hCb9gu438ZLEcUa~pV$ +z`R0~mq2Jt~u6}d7+QEKvgSz_7ZHa^Z<_2~3o7-HdtKZy)-Nt-#TLg9eo16a4t$)6` +zZ9SXf-YEX=o7>N?WWTu$KGgfo?PpN`-Z!_=57TdM@H6N)w-FE1Z*EXmzq#G=TlSk9 +z)YWfpxBZrWa~m?B`Q~;V)KzMR&u6~5-Tqtp&28v>`pvDF{pL1ozW&W^lK#!DzrMNs +z@g&Ka`q}^Fju3{9UEdzu<_K(a`IdVMezpA3-W#}c*0%>s-GR3pzCU^jW+*uarK=sj +z-CNJ4IQ7fg>_46)4GqbLos!G#n+kRHZs9wizCGEnSNiMFg-B3hp;9rVD0A3v!jE`=yVEEbKC`3!DC7;JTqcI9hOxa%P7#fB3?# +z-phrdu6`$*_SpsdSEaVED*0a7RHMo1ki5Brm +zkM|0R%-Nruvt2sl@;&15-l;Tik>4uo-{UP*YPPr2>xI+a!BOuuin2p0 +za`%WgTSTA7J6$5mfuyok+T`kCZsBeZb~^*zZr{LI+InTwI$p`!*B;#I2<&wER(PyG +zkm&uwJ!04*&huDrQu205@49^>J=Uuw(zGMlv`;$j=n-GEi0eGoBBg0-JH3WGZ5LGbg9n^}18(1>SUP@fG=7Crv|swr;d{jspP>{TY!BY-2;A)Q{WzA6 +z&yU7)6sbY-IeWyoMV#)5Undc%J}K>&+8sUO>lV@Gi7!z$ZD|kAbOmNQeecE6@sZK^ +zjmoB-?ZKn&fXU%|))UW_$fo_tP1~g}Ts`71En=4^K3M7A-5y-x3@mZ`Zi%Ji1=09) +zrTaj8@Nq}rahK2Ri7%2!_x5D>UTM&fd0pm#+n);za{AsVIh(?(xW}z*50wqvFIi$<;q>T{z7`O4B+?_6N6 +ztcUujXhDH;W-`>PY+n`gw{L&0M|{X4Uhou*Q_f6(=K{TqJH?gwxvL`8Q`_vhCAQoO +z{;_~n}-h11*Y +z=SpnnD)?_hDfu^kc~GQfyfC-4tM}UaI?^&a(K16gQQT!N2%EeHxhB#wtj&I+!givJ +zkB3vth1^}{2ScU@jq<`e(vqKO87w5qyUeeLOs^Z|nUR($ZQ8x{#L*+#!=~W|xulK= +zBNDVNjd>NV)AuDgS~|o)!@%3rEWMzlT%uP`_Le5k|Jz`AQpK +z!gEHsu#O1%31P6%R^DZPEo6GlDCgG^VM;<6C$v@Z<3cI9%r9RP>73eTUtD5aT)}@7 +zO39D<X%PfXX8x8V6if6}HV~{FmXB +zJkBrQ8|fS+q$<12_K?YLSLn?H!BTO +zA{Us~YoIac$9g+2A=&D)dBdnLu$BX(QFVIJ>QO3jY;V4geB_AT*vZ;^`>$BqIwWenR>`Yx4_3MZ?>c-hd8{*(yo1tp4&R;JDNG507=2M4I*_o9d-C?jG@Wi+Ivwohh;R*Qc%XqSlehvWE8HGtR&> +zZeMOJZJiyp<|@nfOP@M=#1@Mvc&v*h65W!F?v@rhedl6n>!_%;K#A^b55DRSJm&Bn +ziKUqf?0dw`7BS_C&#EJxw?yLul%n13!LiQ3Shw#QPy7an6zxnF9gyyE^oUPc#GiWN +zw<$&2r4L=cM?LX7B_eG}O1q_-oju|Q7O}t+pQA`S+k-xLV8j2J*Jj3_yDp$oFTHnW_*HZ$=o``QfD)z@b7&(haswjE+#o4MjFeQjp@q2AYK +zDsE+8n}O%m*Jd_Do&K2&o>yO+c@XOAYcr$QFt5#Qgu4FPjQ-k8|GYM{?QoB{<;`>7 +zy*Bfo>}xZ_7tz;dp#HtrW~N@Cug$>EpnqtdaDl!yv;A=IYcr;wv#-s-^Xh9e>wZpO +zn;Efzd2QxysH?BdjN8DxHuEUd)z@Z5ZJ@8sym^j!ZDz~{{k0kWwVD2UZKim{qa^p% +z9pAk+Gvh7xwVCnswVB+vvb{D__FV64GfUxT(AQ>4pX+^X<}s+Nug#2F!MrwO96?{3 +z8MA`EHgnZk=CzrTE9h%8P^YiWj9o!rn}NFe+RTC->}xYn*TWY*eCem~WnFu4&`vdc +zDa#07KBnPIY1Z)NhZw%BW5XAyYvIc}8opeW5x%UW;S1EY@a6Yx_yTn;eEB^azCc|I +zU!bmrFFP~B7pUvuiypr8Px#`5@Wr5pFE_B^OBseQQ2&1TvYLi3@G~%cSxv(isB7WN +z(`@(xbuD~(nuaesGQtx*EQ`oe{pgtA{Uo_|k9T%O4?p`42UG`2!oitibRE +z>fZ}rc4GJfKZAxZJ1~5Kx)#2C%7!mc*TR=iY54M1M)>k64PV~Q2wy&>;R`&kg)jfX +zhA;5E9=_<|OaII)kN*(Dm$l!8FS|0rm*3Iwr9Nx;@^cJdK4ilesB7WNhctY7DQweSV%TKKY-4PT(Hhc9~g(m&zLTM)kdmm0qOlMP>X +zVfX^|?}sm6(C`I*28J(R(D3DL3}1f5hA;5E7QXxn!@Z}l|U!eZI@MRxPzQE6*;mdBEe1W +zFHqOQmnUiXQl1gMKwS-AsxrctCu#Unf#J&!+3=-O4`1}~rT@a0mmz%l{JZewK*r?D +z!!&$p$U6D*1com!v*8QWweSV%YWPx-5x%@k!*0$YzVuJ{QV!vZTMb`~Z1{2zCtslc{qUuMhA;3lFnoc!8opFv_;LdqzEoiN +z0(C8XIn9PIP}jnj(`@(xbuD~>x*EQ?Gs2hCdibJ;FZ~w2cp!ZFnHs({v*C*o!xyN3 +zFMO%Q@CAMb4PVMJe1WPgh +zHa2{L=e6(!>NI?T=e6(!>T3A1FJtlr>U#L1hcEpTzPKQK39I2tj16C^Fnodf_rsSq +z8ot2K!0@GwhA(amU+UQK1)kT!mpU50?9P~cfw~&L9L$(}fw~&L?8V8KFdM$?*C$`} +z@TLF4m(dWu>{P>-x7qMzDuyp_XA56eVfX?+gN83FF?@l#7QSRmzKq831t(wTWrQy{ +z`2uweUvTmT>RR}+lMP>>u7@vr_|i||3rxPetA;PDGQyWnX!x=+YxwdL3|}%PU!bmq +zFF5%!FC%=x$rq?=;mdJ0e1W_6z5;9ojx6|s`&JAw>?z&_Y(eah*%dyt)rA^L)v^kWIAt@$99nDo@BIM +zdd%%x93w4L5-sC|L=_PSTg2_2`1o#nex(hL!7$46I!MuhWYJdX9v6{s^kbF#E397@!j#uyc{O+VbS!Je^1 +z@4_Ixhc9dDLTyCN+kQ^AGq +zz^e}5i5O`alW55o62(M3Vi9?db&(R?o;KUUrXGX*cn2xkk}TRSjdc=vh5x%#%7y$g +zBL2-HPV&UB?Y18&wPjp_!A}X1_|?()L`B+{Hgh2p92OH1@>9VLj=%<&@4*-mrYD5q +zLR$q9Z59#kj8Qi2PMZ&gOb3nfqznjUPkdarJyl^#mGJ{t9wyuypQ#b% +z`fr)jVqQ8&v{U_a&tJ}R7#Xaqm&Qyye;H3HuU!9a@1L08TS&A^FicRSr!K=z?N4Us +zFZUkm4@G(w**gnK@1FqHf6E+F4i9O6VLpGk_YMpw(!*ijT}XQWV%AO1^e4>5VajIij5Oo~)E&ZoufKM=q1zlVZ}$ +ziT){i5E;ENhA=0Tr+W`p>d1Bh2I)O-?!QR) +z9=P10ofDHT`~M7+1AxgY6_a@^Cht*9evuWE_b4W?j+o4&n9M*-=CPQ(M=^n&8Yb_t +zn9M*-=CPQ(M=^n&8Yb_tn9R^I(J|?JO#a$LxHtZ!V)77+$uAHSIU6Rhu3;jxm^_4- +z6jDr}NHKw(8YVKu1d51BA;sh&787_#!$hW-KoK!1)G^U9>HE&)C}5%vy}Y-8#pEN3 +z$-lB<@)5-Z))A8h6q7pfWiUDV2E}A#HcXy-gJJ^f6q9RjrI-w& +zn9RPF!Q|;TC?>E|#pH=MSWE^{OyD!oKXd)=4T=fuR53a928+oc9TOdszQ<%DbS67g +zOiEcyMp8@~L)kEabrq8*Lo6nx6qD<3qnJREVgfr=OqxOz6DU$luDy+7Qp#ci52=_u +z6QY@)^YhiinAxndq4G115U_la(qaY-V!w +z9g4}1vSRWM#RS$76UaD1$71p$#3Ygp6IjuQ1h>4z==$P~aCiQ^Hitjp;7cw%F +zwI2$Igu3_>qi^)=o$qSg7K#^hsJ2gx`rkFsHV)A>; +zOqQ~kz(X1)A5%=ANHICCXC^u({eVd$V4}{MypWNZoS~S!m=%*V6cboSOfWNVnCO`F118X!L{v;_SWI3-OrqH^fpra& +zD2quAVuG0o6e%XKQ^O=mF@Yjtf|*GTiwQiWVG^a7KoK#~GZP(?e!yfuV4}{MypWNZ +zyh|}zmlczDDJHOvm|$j-hnQq!Cht;AV5f%3yDTPoh)G6f@-D>$c50Zs%VLtJW1?fy +z_n3SPorzz?WEqReI>hADY?#2hhRLTaCd&{L%uJw2F@c>LCZAGFpoo}YX0nXM1Rl~b +z`IKS;MZ`qUOms~80h1$ui8^QULPlotA;sh$Suy#LVgl=k31%imh)G6f@*%|pc50Y> +z$YN52m}F!oA5u(Ur-sRgEG9)dCORhlfC+Ra9V#Z9SWNzbn0%296IjYT~ijLhVHipim@n7mIhfpx?LGn4BOlZ?#deToU} +z)G&FU#pF7~BqK9-THfpra&&sj{? +zASRfZK#^hsJ2gx`r)}fQdS1vNj_#IY%-1JS!&WC?>Fum|$kI5HZQfOwLhEV5f%3ITn+J +zh)G6fa*kpGJ2gzsv6w8>G0`#U2TY(d`5zUN$5>20M@-tXVFK$KCT%Pxk0BBQtrMVgfrgOx|WO8A~yN&xD!D+Y}SnsbTUqi^_`xfZd}W6f2T?N6JnA(Pc87j=+j2b0k)(n6Q-?igvAmS`C&)K(C&)*>c6 +z*5TduM7b?d%D--uXLgY2-eh!_lynn$pkFSD2qRL#vF^YDhtKVaPwlqnSJ{pf^Vf$- +z{EBG&Hl=90^r6f5s3(4>B5g^Vr-V(<8sya-MB0{=8YG|77mpEPa6*_Qw3QO^yhXgj +z6Ti9J-d1L7tK!EQ65PrR_(9w@N|D)_HM +zB)&KrAFOommX2|dz8 +zdhZQ>;gbDyiS2X+|1T*1#?K9kG>#W$pIMhS?+KfJWZ*vj-9^$kI?*^oIQExyY4eR? +z(~AbKCenD_3zzK2Ds0Ef_q8AB$xGrseAY^*L$h`_X)qCpTgPaVRP8zwHk;X+Y +zT(W;vX8Wp&9~vUwE2G}=%A9>^b4AEhVdUmTs%NBvOC5owF5i7IQk|Em9wsza@Lw6Y +zUq`A33f1LATxt=|c)U5?_UZ~-bs67kQ6<~_;gda1@uxO_jyN2>zpjl6l*t +zoi5*s7%7~QC>$j0FDIhWB8ENI(MsN4>0PJqUmokAZu{Nkw!2IDr^3XV6SdA!ns!RZ +z-9#Skmwyr|9F+>LaR)9sd?#b1a9pBrmN2)N9~CCn2~q1jW!bj0`Nv_?2L}0(4zg@( +za@ii~ey6WBMp}j?S|$r8%81x$5yyC}*C^2)Y4hQ*=|O{he+P-~Ohyk#k2#2Zk6*qy +z(lT90ln^ms5jT6RcXiwIi*5Pk{H_p*-x`gNP>LF)15P6U!Y_}E2oqDmdz^uL+`a{# +z_)SXDF6l$JZ&Zv36B5Emfv+TDfkpIs;(3a6AZ=b0GA%O7b32H%KPhdO+Fe9m?3Xu3 +zItK`g%ZXTJ5#RH~M|Rs6SJ)Pp@gIdrd}uU2TiH}EncPI4?w22obdF60ziLI;?tw?JCyFNY4crSQ_vu9jC2l91=FrT+UXl`@+>J>ezSW2>9d#Y +zLrZK!EBH4J+&>?>NOA`yawiJ)XI7`p&ai2Pf%}h0?pUF|il1QM-huUziQH*I#rvz% +z%yq%fUb3Gqx1BEKUwZTq>Aj5}idDAR#r#Mk=X&TOX`Gs993spoWpKV*8}$TdK5 +zVxloeI9AE8d*l%5y+7#LOZL^pw$_29#XHT`(Sn2{CU`PyMg-r4@9cR3XN5K +zu7RuQAk90H&HJQg2jQyyTw$a-UuZ2RVv|K&=J77|6CIPj$K=<5$xIcKgDfU@A||V{VFK$K +zCaYLX4pL0MeU4%RMT*Ith{-C72^1+N-#kY#ImluH4{4aJqL@IDVgkQY$3*W;`nofb +z0h7Y-F!?s4GqF-k{+tyPE5!uXDJI`wXChKepopD`m16Q|#Kg*CB2rA?Ght_9rI^4@ +z4HGMiiKt_uW77ASTmnp%sF*y@V)7frWNkJ~U|qvxEsM$XhzWKkP^6gr1~FMnF@Yjt +zf}P3pEGF=fhRIrr2^0|%y))7O%+(Kn=K2yaS)^i;(V1+dm|V_^$wrC^tRp7anFJA& +zjLu{u#pE(#vXR9kh?rz_CL1Xxuv5ciBa2B;$3(}Z?=cw)m<;?5lRs@?F&RWLnX^0_ +zCa|tza^rFa6ZaO1$tc>Hh)|@M45FCKT~0B9BE=+!b|$B`u$aI@DkcTXDJD>)n85GU +zI}^P#>Eq7C5V{;3G+E6|MzNjAEf$K&wrrT(WTBYAI>jW1b|$YoC?-&(oyi;v#bg`B +zG~ikLi{4HH<` +zFnO58!H@<$yL9h1JtqyjLRpklI{#pG(lWMwu?U|qvxC5y>!ipgH=OrS_Hxf(H9Nil&U +z#iRi{lie&P@Q{YdN{R^-DJJkc_0B}^O!~Sri2x>QX0kV@F`b0xF@c9POx93Lpop00or&I=^h0NI +z0WeWBlf4<8$p(taU$bJefnoydhzWKke?m+$I+G0)lfNP+8(2*KgqUP>CL1Uwuv5ci +z1B=O@bWC(i`W}4x5O!UsAuRD{EF9!!bqh=;Q&ge{V&g99gnBbfVtW!*u +zVrTMuiU}04Gr>8NClM2N&gA&-DJJllurt9q6WFO?!p@nz_In)@9h1Jt!YWOODtX97Dl +zOxQV-*ZevrIwpOO$!fr4nu^Ij7L)miN!B?NSl2LN=Ss$vzencu2zp=S-kTF@fKycP4sg($}5Ir+|r?nS7AZnc$qs%ULnOITKi?n4H1R +zq?kN{nBbfV6cH2bOn%2=0uO1J;G78*5fi;L(L0lV +z=uExGCC8SGl88N +zChVNaYk$@;(J|?JOmYE}p(-ZZSWI##Ce2yrOkiEbuCh$A;&P4A_`nod-Uk(nsU(HMk*v>@6Ig^HLnEV0f +zOkka2G6y>o7sUjMv@>bOIg*u#6>ZI&qO;DAI_P;P8AdQAUJ2@(lOC7>3d8X +z0h8G(CQq`MEJaMR&Y8fvhDpYp$&-i)b|z4ym@Gw1aLxpZhzWKkPqLW6LmDPHX97jU +zMDI-W&ZHkYlg|MYH8Uw-I};J-OwMG*1m{d(9WlYqzL@6^gSlkfJv^3Ndt??9Ku*qK0)VloFY +z!8sEsQcRk$GihKkfrm6qaLxpZ6chNJdS{|{CVkzRv;rn-X5!80OmNPmIV&bOX9DXK +zlV`ZXZ1a@keWXzc~>zL@6^gSl6fJvc>NfV1n +z4PugY&IHyqOfu$7nh+E0OrS_HsX4(mw +z4KPtN6K_Umf^#NHR!nft1lAD~>`WxYB%?FIITHmj$(S>d5R;6~1m{d(r-n(!oQd>* +z2$M_CKVbXepuqzNTsigptF?Db*X~t-TNM)8l?qamgK$6fa|}UbZYn4_1CrY}Ge%k`C0a)bot6CN5b@rk +zA5#B+(;@Y(=SabFLFGnbxq*Kj>LK;;KmPX*sfTrqn+@zF3jFI)52=TL12g>GLy=q& +zij*7pH=rI;e_{ijM1dl5bGY|h;ZqXJ4LqcAvw=>cKoPk)Ok}%7{EesJu5Np7u`Rcp +zuMZLLtx@j?Wln?C;3V8H{M^V$^~6+gsWY(D?VIoM-lWXgC7p5ma$=-+n>t+oc~;|9{bqCx*8#2M2w6>vu;%TAyPMsTWt!vBtct+^nEujj&F+ +zsd=vVkownmQf{D#y~_$Z)|iLftYF6)cT#TPGhy$tf{r!9PK}!tY^t*Jl0CI6d1jaN +zjhk=-{ai_;dPFLi;|?@9d@hf7YPUVN%GOxS&khss6;bbP%AD=e8JF)7kM~Zcc}v=y +z8#Xl>xYZq`d0Vo%L27pTlo+WVoT#28w3ZSvY7vV(-kZDat!1{>Dt?TCE9)RNJCZf~ +zbWHwVzVW0GFu7aBVX}_JOFLCaYOYp3yPU{}9&qe+X*SCfJ$0%3=Z!X_(YfOrVIE=$(m +zJ51skoyjVSNl{izR#8k~onoS3XL5jI0!8dhR#8lf5R+9bCI=`c@R_hPSw%5{of;;q +zSWFJ+nCO`FJthKR!mF70SWG0u#F`BgSl2MIvY7ZNCUNXcphz*15ECoK1d0?B1v?WT +ziwQiWVPd72K#^h+*EG3f+MHmjJNVlnAPOg3i21lBc7HnNzU +zLQJqTfg;7E8!_2PF@Yjtf}P1J787_#!(=1H1d51>-kIo_^gSk_H!cSUEmSj;>1=1R +zaXH0gST;=7FQ=HmI>jUpJCm&x6DZQoq-HtAWEjQ7vYf?aE5!sp6YWekET@>jP8AdQ +zAUKJ#RmVifr0+2q1DKSlm^fKXc2Z1gEZH!Dbrq9!78VmH#bi2mCQzi9?4+2~S|}z^ +zq?qJkXX0crfrnH~tQLw16e%Xt_0B}cq#rQ(3t*yVCezu@WaGmWlgg}^JWMfxb;JZa +zlP3@pwlk@Dm|{|im^{p4@&sbSb|xDhrkKD^4U>miOrFp&(J|?JO!fmNt5i&0VljCa +zFVN%0l@*>6LFm@(Tq?jB>Oll}5 +zP^6eNVQ2CpiwQiWVNydefg;7^u-=*InDhfCX8{v6GdY~mnXI9htjUVW8j1<5BPQ6H +z970SoI+HaNlQoFR8Wxj7h)G6gvW8*;J2gz!u$UauG0`#UdrZy&CXcF^oMbV%h?r!Z +zGl6vtlZ-i&lZXj+CQzi9TtrN8&IF2x33etYSxn#|4HKL*fg)m}cP2U}{ea0^mxF^| +zRWp+ZGddHTGnt$f6Pz=Fb&AO{>`dw@CQ!uA1m{d9BPJPhCiN5(_)OTD;G7BU)G*1I +zGpW}x(J|?JOy&Y6KUOh0#$xgeVv=>v1lBc7GUiNz~R&ZH4B$>>aQ +z&g6c?BxBB`5i!Z=OmNNwc50Yp%$YRmnCO`FJtijr6RV0z3yaC8h)LEt6IjGtn{W2Ta}tOw`Qed`4%2b0!P3 +zVuEufuud_FVrR0SVgg0%OmNO*A!3p-XR@DS0-p&x6Pz=Fof;+?b0+(BOms~89+O(Y +zz~R&g2MUlF^yqoXKN|NyePX5yT{; +zGr>6%*r{QXF=ui_$3(}Z?=eXLCN>q50Emc8UpnCfb>_pF*yR5tW`02g~jAU#3bvS39M_FWXzeof|y`u0!50+ +zhlmNznLrUS!Or9r787_#!vyC{pop00or#V~KVWhiFi|s;*E2d3oHMyOD<(K+0_zkL +z2|JU$6cZ?7XM%GkHzOt)b0&K!Ch(cCGr>6%*r{QXF=w(@$3(}Z?=j&46Hdj%%VOd~ +zOtQ|Iz`BM>#+-?lV)8n6CQzi9_z)AEGl3$-M8eL*%VGi#X_(-g2^1+Nuctry!{TeV +zZXGaS{Jz>pS1~s#)Ska5IX$)Acl*Ih_OB{zUzPEf!o)iu>b+8#vmQ-S)y#TVW-CcZhgzjC!XjH3!n>xgpbBBUcb< +z%}WKNjzHAqdn`s;XC_()3PL%5Bt*OmqTW%8(vUW{g-mTmZd?aZ_9T^hX_MQxBt}}N +zBwEJ_omE5}Xc4!1tmC`wV=8T9O87FPd}{~EJCMxVDpk6Oe1l)ML<)xq`z!dr8RTC@ +z3J0cw*SP}MIeqWPNa4^#VXkm@8UIO`ScgTe*C|c)Y4a;#)1wCYp$^itE7^2Vn(Xk^ +z$4JYFM9WlRZV3^OS;W;I>+Rk46UDX@<-FG**L09&+mp-oN}oE3yvZ*Qi?mD-YD-b@|F-M3|Zoh6wo; +z{Cgo1|3Nf9L@C;nHop)uyWDB#;H!u@ +z-69_L#3y&#+bV5sCHybLBtA15U!rWRZPU^Euz^IU!-(z +zPn+#w6ESdGHe4jRe?0to!FVO-!nw=AZH~Y;mv6bJ;8%;jB{^G@IeVm1VF3|C7V%b3 +z!A(leF6k||Z-l2{<)Uv%!;WObKFL+LfQTN8Xz>&jDGlLsmxC)^ft60*XKiOm!PscQ +z%}Td;_>%o}neB8HKhnUxwc#RZ9Fb_8D$M@JnzZ>xVbl8t?i(l$N;FOsj+OE+zJ7>s +zd46tLq|tZylKohfZFMm}&Bz^xho&VOhYG6`aCK0~^tq8c0L4j(#!wDDEVj2@M5z?Vyr{a4LsF!BZ8AV3RBw$&y*!6qj*B +zR$X*O(L|??MvA-oh}q;x-Cb$2wj}etZf5x0pSjHQ*Dt+(-{*VHzxQXR?OxY4KVsocZqMv!bX(fIF=R>^82d#zZ*wAV +zm(b54ON)KdaItVSH>6bN|8C(&xUJW9+8au24HfJ%gY=+SIFxIsWJd*M>osBP$Y|5v +zwE6y^>3*Yht5}$y3ao7QuXK7JipYf%;)VUWv*j}XgoXdXZS5Idv@31i6Ey8HN+U1I +zi|P}Lb_mb8WGTldEf8CBxZ@QvUufZ5+}8X~`|(O!O%Xf6C|!S14)0Bbw+bhmvUHnI +zS}(TrP6gIG{p%gxHn(+Hr#)V7i=xEKWU0m{ +z<%`_dRG{7AZ+Ch7yJJ^(+UJ(o=2o!x1?AXH;n?`-hJ9)C^q^_FQ7RBS@=}5G&HnRF +z?_&|UV^X}MC%3VTeK9DmquyWMY(f#qO(reVFdpW#+ZaXU%3X +zu4w&c;hOccW&Ump|5taxg2%p>>+2KsI|Qf8I}U!x_2Ggs(fYQwOM$PN{a-n~vT#Ud +z?(#9e5gU7OQ~n!X9TYU}HZo7QUyvI|#~TN8Q@(>&2L(+x8JVeKqwvNL_M^qNqvh;B +z;LZ&`rk~h2f?E+?n>HT|nI1AQpTeC(;*I&-H}JpUj*#i3fmtgyzWj!ciH=G3F_{FI +z>{Kv$o5o}q!K7nGCQODAOfJr#F?pL{G8Zw~Nn#$-BTa!V#mrXwb| +z(3reWF!3WM&(oNg5R(-I6Br^Um`t9hF@cLzOjZy~V2GIL$wbGb8!)K>Oq68e*I;rR +z!DL-VOl~8XtfMi3AEILN1!AH}CN%_;^N2|ejmhhXi6)uU5KQ1s6_Xkolh<`jbWF03 +z$vnVhzk4IrFo7Y#qzjYDei{?FNX29s +z!32f`lTJOE=$Lc^Cf2mMXP1&pHfk^_B$${pVp2#jG1Hj94^c6Z2qvAHWMU`Xo)n4}Ps +z7imm3AttK`CNM-yFqynaV*(ecn5-h0zz{LflZlQ=H(;_3Fj108N`ndROzask!JUbn +z#sq$dipiIVi6)t>BbcNSlXWyE0mMX;Ox6)h;7%2jbu=ac9TOds>|@gNf}H!v=F6De +z^=Ar`|MVc349T=J`KkxOWH7xmnfYgeNpFJ5y3I5uJqae`7ZXfiNHFP7lF8c5G$wG7 +zf=T{jf(Z->CjIneqGOVMOvYK#=AQkPWYU|)WEk0*h((z&8A^60XNqV{;D;!f%ncGu +z`q9Z`qJ?0xgZi)l>Yhp3o*hM3UFWa1iv$(xAD8XA+|BPMh* +z$y-A(fjd=9*3g*zUdKeoB>R|L4VdgwF!>9O$#BFZ)6V3p;fM*nGnx4pf=MZ2vWv## +zYQ$tI!32f`lbx7McF~x?MJgss2_`TknC#G#iH=D(U{akn_uQ!@lTr;PWM?88GGan@ +zCT9#ZCh$X4Ohkgo4oxztCYU%7lWH0hH^Bt%#AH%UFo8Q&OsZ*2+&U&YCfUbi31D(S +z!Q=xPlNpFfrk%-GGY}JcXEO5xg2~&6$pIRZC5Q?3OkjwZU@|#CV*(ecm|)KYhKPxt +zOms}T0Tbw%>{OD;+Zs&B&P049BPL{La^?{l6Zj!2Cg%_nO)|lr$=?wZx@WTCkBEsT +znPATZ?o=_MdnT*?sAHmIl6_1@04CcNOx~g~89*>;$hb2ZKrq>>*_pgWFu4{n*-m3J +z0x`j!2@DA)m6%Mn)0n_TDkj)7fg!=9LQf_-Cf$Gu^h_$1WO6Ny$$s3K+?@%NeYi8Z +zo5lowh>FR_1d|F)GQpn7Q-}%OGuiN4f(hJ-$pm{QaHon1-7{JBTOAV}lk8(+1WcY) +zFgZhGawB4rac6QPVxrlZoFSOF5R+$VOpJ&L_Do=im|!w_mc|4wQZd1v2@DYvJ(=j3 +zbOR>PGpSUPiA#eC?o2EhF~OaQg~kMah>A%VG0`Lw?3siR6S`-z!H1Y=k_q-q;7%12 +zx@WS=r(>dHl6_2O0w#MEOx~d}8Hbo;+?k9+Of)-_cL*lS5R<($CNmKe?3uujVDc^| +zlf5)1aFL1$_Do<%FnLE$CORhFfC=FRl1e13( +z$pm{QuOcRN&t${z2qthRCKK$Lz?~{4bkAhf?{rLbOtO#3uK<%56ihy(F}WQv$+$DQ +z9Wl}DOg4y|bWFMd6X=<|t0a@J +zHJISe-DkkR<6HPL~p2@!u6S`-z;ZKN(CYfN*1nyKZp?fB){-k4~ +zW0HML1_CBq6-?fwG3i4vS(tHW(uZL3GtJKAO@hfN#AGXt$v}e1LF}2pkYI8HCX=l+ +zCUB90$zkl7z>r{ay`D^TOtO#30qB|Bpd^z~G$!}q&ZI08Cimjbq>RP{eu#=mh+uL( +zolIW9p2=>4$%~qviIZRgcamh%ggq0uQ^5rO7huoCsbivJl6_2m3Ya{tVDcV~$#sZH +z#+}J^h>2!r@*ctD8N}pi8k3(QCfGB9A!35bH7mRv&P3v6muV|r@6Taxxpq13<)~3~ +ziSlxjKV8ahd8tWe7W)uCAC}Vq|U?b0=}- +zaN~%O=_v#AUvSCWi|-(> +zFxjDCvV+D14pdB*WWof_RZN!9nCu{!ti)sjLxRb8!~~ltFeI3)!ep|8#sn@>F~KGZ +z3<)OiJN4IR>95bq^6Rq>Koez^l1x@=lF4d<$-#`6tR|SiIl*KVCX<&4CNRWgf=!fz +zh>50&@)E%W{w7Q&*hGOlRZKKZl$Uf&bWF03$wPq2a|$NU(U`!2iph#hn83M;$qE{i +z=MWQ2CNLzJJcO8F69tBd2_}>0XiVTD6%%Ztzz{LflZl>8x*?fB6J?c>Ojc@=Ne#i| +z^Ng6(5KQ14F~MYV0x{7f6KtY&@s_5$v!4`04Dns +zO!m>3z=4X%vP_u3xr)g$8k2nllM9$kU`Q~z12MrS3JeJ*-(oV^M`HpPshD6B1%?C@ +z_?>z((UVEGlL<6YzEzUR1x+%s5=>5J#KcN4fpdb%x0p=41QQryGQlRwNyJ3cMDY?# +z;BUfYf=v{-Q^iEnMDgmF=$K?5lP3U^BMK%*XiVTh#bi|`OyFF_WEG9c5yS+O2@DA) +zPar1PM1dh(lOC7$v!510h28XCR=Ds;6TCT +zmy0uD0_O@Qro}WSTL>m&Fqy!RVA7Xh@(?yrU`Q|-i^*gQjR{<&V8UV(1%?C@_?>z( +z(UVD*lgWe7L>a3jlQDEMdDucQsmp{3+^9ay1?L2lv6xI81QQsNWb#XFqSO&g%$g>O +zgJ1%G6GcdrGQpn7(Ttd2&jij1CeLFsd4*sCLrf;vGdYTwXnH2E +z5KQ22!eoLy6Sz~wMAI{QMaM+PB>R}G089=lm>i@rfddtjj6D-LS25A_Ob#L@m`q?u +zFj;|^V9x}GhzTZ>gES^^k%|fSOkjwZ=*dJ+Cf$%spl9;Dl1!e{BopkJe3KCq?3uth +zVuH!!Bx0gTCfGCi1~Jj}Oim&unq-1K6Sz~wMAI`lsbivJl6_2a0h2lflR6p`I8ZUk +z*fW816%$R*q>fnZTVYCYqi}i;jtoN%k=*1WXzfOd4oR;6TMBW6uQ6RZKKJlLmsxrDX +zNG8xTk(6ZesV13V&!i(GCfGB9bHoIbi61f1BopkJbRZ_0o{1kZ(IgY>nZTVYCYqj! +zU&lnpB>R{Q0Zg_jm~5jlfdd7Ta~XRkaIRo-Uehz#MliVzlL-t7CPN4&pJUGih6Iz@ +zm`t|On7~B}CT-X=fg!;Jey5&H^kkCdWbzsGOlB*|F~Ob*3=tDOndr&n +z|4TBFKM0qO95u3z9sCI*AK|da35n3a|d&Mzg(I&UmY}EZDicjF37og@!Wn~T{-)A1M|3; +z+mkClw=`{jDrkDj$UF<@x$)c~TzMrs^TYv}`I(RTiI{8K^Mn0#vF&s@`!5*&#>ey$ +z8;5gK!b{WU-67LY4a~>WF3638DQ>k`ohp|jb0Dk8TIi?>eZh7`&C77JhOw$A9Z4=J_{DQDj{NRM2U^R^`N +zb_*2_S+e+~abn>ZuA!9u+9>rA3rC~^*E{^zySz6=j*7jNmqO)HoA6&C&*x3zDl{dk$}cnRw{ac(r1U&_84l4E_svFoC9>eA+yL#9;*=^>FD${ns`#~P&a +zi?XmiA?y{r&9YSGlL|#HpKB|U`9l`|VR!7dPJ3Iit*x9*2IbhiaI9x^!!BWxLzb5L +zq)}qW=v3f{!+*r(9UGB5M#ejGIDZAZE-1&Qg=6{A4g1sP$wAX(qjZDVF+LSI)$Bjz +z^sbA@9r^K&$k@fwa?~c6fU{d{!>_+XH`Kt`c(}_xxb*TWsrF +z&c112{(1a@oZBm&JCdslSEtR6kZFm5c~Hz9%GFh}BMi)6;Cx^_cRW}Ad3D-s44Fa( +zrdG^d=J~;Xy3BUEgnjk(CYhP&V}2>-u7hEvZAuY4(8xHCUyvKe#T)x@Q`)N2=J$f8 +z_l!(E3`fQrbGV}w?CKLuGPB6X%n=(md4903D6*|6V-Fgb3vf~2cw;WN;*09E`SXzJ +z4g>Qc3U!OWD&Q+0!TNxh^`j +zE^R&ziubRe$bR}WNr{!$EN~9vtMv}*GA;l{CI0`uA@xmO&0#V+cPX0-IF$_f~J&F>Tyxd +z+m*=MF7$KB(r}+-5DN!$Ln>u{goS^~Z5`cdZ>X>}6tl~W((Pj5ByM35J1QhwM~1Dp +zM4Psz&G&~)pBSWCv9Nb4u+r&Y>F|CYkqi6B3&(P2OJ)8C3*Xmmy*j#Rd)mAwWV**7 +z{rsZ5Xh&kvKH-68Sz6$eriv|j-0@Aq?H%t@YY1QUO3^9 +zrS(2(sMs`$wM@$Y9Ob#I?2Wd=J5=?3kla(|khY*v4G$tzvCUB>U$x0fNLpmlpCfUd23&3Q( +zg2@{+CUL}MZ6-|MT*YK9jmaB`$svLX3<)N2#AGeO1cr#oA%e*pG$wG7ipg4n2@DaF +zLpmlpCfUd2?Ms1P?K3W8@|Y%>EFqZWXT)R)!353;ChIYo>?D}L5R=Igf=NDNvV_KD +zC&2{%CQK$v2qti+ipdfhlbt#yIwsl2J60vD;6tR|SikYED8Q%@#(GRbx_c^@#jMZrXqOjZy~ +z*o>I0Aeg{8VuH!!dBjAMOjZy~Sj1!njmh(fi6)t>Aeg|NDkdvvOrF;<(J{$BCT{>H +zYZXjhr!i?mOlmS=0_Q3wH8du#BPN(kU`Q}&LriK2CNM-yFqyngV*(ecnA8wVV2GIL +z$wW^k-H=S)1x%EkNm7$cmJv+mX2fI}!353;CJ9U?`w1p6#ALFJU@{jmSw>^BpI`!i +z6DE^o1QWPZ#bg_i61esX2Jx{RZOfjCOp9;iOB?p1QS1E +zVkMZskYJL)WWv*!z(p!1R)Pr(2`2D6^<<(alWZrGj{p;8XOh$;lT`$hjTtdnMKFPL +z!~~Pci-?IPnXDq1Y(z{}(U`o5m}rv8DuM~zsbaE<#^gmE6CIQ6W6}kfY*H`@(3qqU +zlXaOefpZm;bu=ac!~~NG3<)MF#AF@81crzSCX)b-30$ONvW{Q^L&QW+CVDc-elmIF +z&zAzdCMi3UVRSN?znEasI};{%Ehd=2Il*KoNhV#J2_`Tk$z;xAf=O?J$?c0NOfGCD +zn84pelF7Wq1QWPZ!36#g@-$a+vyO?5N%k@65115R#^gWEG$z{!CUY#AFoAOglRGRF +zCSNxbOoowU@*NBbCff)mb1eiD7!pi|l4O!@rZItw6in{45KLf5FoEBxClfuHWI35U +z@>jq_*_jNZlga$$1e4N?m@Frlz&T<Lrf;vGr1Nqp?fA5b`ebAZ^C4PJrlT7#f0veBzNhU=$K?5lS;tEs9@rzF>xU# +z8G9yhu3|#>Oulv#O!i|kfg!=fg_vN^1cn5YeV9z#G$wG7iV5~iU`Q~5->D}PJ(*-X +znS214C_9t=nq-1KlVuq(!JY}6BPN(k4j?9)WP&}DWrzvgGr4d8G0`Lw?3uuwDkgN# +zBzZu`M8_oin7j*^{7S*(k2EG$88BI`VB(`O`2;b^*fW816%)E=^0f~!!DIqMg2^X{3HD52h?rn9@zI#T +zMJguPGl3yuq9+qQnRG)kc?U32b|xQbk_q-qW@W?#dnRyBF!>OZ$zFm93^AEt&tw*2 +zLibEA>?N4M--O8odnRzFiV58_N$%A#(J{$BCaVCGhZIbHM`Q8_#3W94liH=G3 +zG5HoSc|yVDPc$aqBPJPpCUCA|LibF*{u5$?$pnT3lkX7|?3ut2F~MZ=CmIvDNW}zu +zCNM-y^kkwZlWs^RZ(a)YGATQg>2xv)V9#VwCQSZ>Jrg)5nB0uXWGlf0h9sE?*fSYK +zF!`gVXR?)G0)G=pCa17x0(UByz#oD=ldU=?Iwsl2WGrA(u3+M%G1)^f5i<5n;9SAv +zq^4)$B$!OcWCBBi$sU4ve1wawh8S{S(@vUHi{iRxVdFAUuogrb;kyF+UJ(r=9aP_h2&V@aBNC+ +zL!Dr9$3sf19Fk +z^EAy3{MVs;Nj>}@|Hofa59ca3@J^H~UsC@y{MVy=Nj>~GpnOUFcQ7Q}z<&eEm(=^0 +zlO_rbk(+~8zE?Q?G|dfMq;doAL{Yw^9)`%xL7kib_1`O;+L<VUsC_b +z=fKTvm%j>f`XTB|>H}*?t?~Vg+^iwBMmR@q4qf?@`mWcIn?rPVSwm`#?;|&B=vw1z +z$ju=-yR0F#Mz~YuW(}QPUemex-_MObB6I(DVZs0=xe6xrG$sXz$FR1-`*88N9Qn7}!~#M?wLIYuynA^t;HHNnJ#m{il493z;(--Q1VR!uO0J5@}o +zX-tmknCO^fKbc5?Nuh#C6OD-#F8x*?gg0VcB*Of<=4Ex{y~5tFq96F5gqFqsI5i6)t>C78qz +zleIJ^0%D>`CTj^MaHopNS{f5U$3({@`D}PJ(*$s34?mBz$NFoC}blZlmJ0(YvISZPeWIwm?M +z*~cUan9Nl$IYMJ%Lrhj>!UWD$OjgmD96?MlnZS@>Vna+;5lmo+m|!wFLSq6KshF%H +zn7|M*(UXauOu8YNdj)-rj+kIFIfa;LlF2%PNf%hB^ +zVxmbV>j)-rr;5os8k18xCORhB$7C2_(p$k~3yn#Cg2{%(nJ|HK1(PQh)0k`_m`uiG +z0z-mHe}c)z#RL-=5=D}PJ(*-Vnfx<&DbQ=4vNM@X +zClkAcV6rn4Ccm)|OyHbgG6|E3gJ1$fl1w&O2qrrTCXZWaOdJFg_?t*F*<>M@z?}*v +z@P}Zn(V=6aW0HML_5&u@DwsS)V^WEjWbB#1xr&LVXYv$cg2@Di1d~d{1bZehL`*Q5 +zJVj#y7pa(F&jf~uiJnaKWRm@4^3Trz6J=*InNB8l?3uiq5fkj0z&T=q$>deUgiaF~Ob*3<)OiJN0CuCzEU^6A>^`b|x=s +zk_q-qUe1UK_DtZMU~&YL$twgC7-BNPp2^FIiKb`r3c&>aCQK&SGl4r*Of)@{S9DBt +zOtO#3M}WyJ1(Sm`CaVyWj6D-LS25A_Ob#L@m`q?uFj<9|V9x}GhzTZ>gES^^k%|fS +zOkjwZ=*dJ+Cf$%s&H*OM&g4Z+GQpn7w;3_Po(Y^ICYVf4A|{$-f<2RO5fe?%jd9EMk(eX9DLcCYqi}9l^wm$pnT3ld*^i +z_Do<%Ffm~=siQH0i&RXoX97cl3H(kyndr$R+sWkPOMzael%0uLlT5H@@_a^2uxA42 +z1QQb`lcNL^7-BNPp2_owiKb_AlwbmX6DAYvnZTVYCYqkfQ5_QYmy1}Or(sMV9x~35fe-%Er^LGnPAUELQFJ0lNQ88lT5H@0(YvIXnH0sIwm?M +z*~erZU@}3$q=Cj{He!;oX9DLcCYqi}1Ht4=OeQcSn9N2@uxA28g2{PICJi(uaFL1$ +z_Do<%FoEBxClfuHWILIB3YaK6lP@*N1bZg0XT$`1CU8zLIgiQYIKc#lm`t!|@;YLo +z>6siSn84qJ$pm{QaHooire|_o$3({@`CF~lTe&jij@Of)@{!-xqc +z6BrUq9z#s9X97dS1e3{O8WXrk#RPjMFhorBWTGdNZb&BQ0TX3s@}(x3V9z9(5fkj0 +zz&T=q$;6MCXp#x`Op=I+rf1?uOf<;^dnRzFiixIY;@2_JG08qAlL3?d3MSiVOokCm +zIy3f6;9SAv2Tjjp8^L5gCKDJEOokCmQrI(rA;DxGCX;P6CUB90Nf-7^U`Q~5->D~) +zEGCnV`F}`=y+6x4VLh?t%1aem9{Bu3%@-$X-Z*xjaNqjZ{t%k{&ZWNBO3(bM|E%N! +zu_dR?e!RkVyqL9yQqmlsv_Wj?$<>r4&4+@fLq=&#t=y6uZyCbXR3^=L22FPwrJKc; +z32pXxu`OQCb_G+?CZE((OzJGS-xqTtDt` +zIs2_adZJe5dd9gC99xn!KOZtN2B}KqhP2t)N?ThIJ3Ew;run2Ak?Y@PZ!5R8m9j~r +z)Vo&h7#{B!z|E~ln(qsm?lVfWYUPfJ@s3`czl`OBDaq=SCWswl+U)*Po4=BsY>+Bz +z<&J^zj`7^a;-uLeGJR=~9;=l*ddE9Paj6nE5K2jteUe$s{oA&aa?XF={O{ZWT;KHK +z_Q2L=|5m4WvAf_u{U5#ZZimjr?ST@P|E*^4@7)CxqdEJ9Ynr{gCV!A(uJbX=#oTYU +zos{eA6ZJa;r^`DI=0Ec>KM`}gV7@I;zeo6L#15+Y4Mz)=l7wk(#Ln;A*->X7Ll2Bs6{y~739M$c>)Zn4iunjZ?9 +z9x^f~V18$~pnvqt4{x5ce^X-nrhafgGnl$Kib|lJ*P;dv1(Q +z-67Pwy7-Y6{%N;ov>;DyNKD-(oN;=8?e^RiJ+@hx>g?hdSokw;PmUlTt4|!;Aslmg +z^CD@_^Ij%1LW()6idnO2SbYCL6McCl%;!PI* +zyxTJ@8r{<#=ydoyUEZFNwDqd6b$B#yZ+l=zvww%vyTon1U6Av(B=U9(6^<@GWZ`GJ +ztv`w8?G)Z|c?Y_!*9dac_C(WO;icv--X1i`PVXyjYn~uC?MpOm5mq|8_=ha~=Wgpz +zL2lZUXxb@UaC!Si($=fP))CP~d)ougHT$1)dRIi!);q%1zR^Xyg$Ep6e5-{obX%th +z@}ixIMf-)@n!OE?v~^V2Ix8C9+8#LJ^q+8e~r|{xxAwy>DYDQ*y!k-2I0eI?;qT;iP1Ux+XFW@ +z`)_u7?}?;iw}fLk(aUdn=;C7*eu6u8y&wy9386t~Z|>sXu<$l_Y+iK3=JvoOr+<>e +z`)(v18yJq=6y30+J#fV3H#K{ocgJ!Cc|${D!#3f(vx|Ss!YAFAU-Qr&nCI}%b9tvn +z(y@YYY(lhiUwdFvvwxG*Yj($G3v%bSMCTr%*Kcl3ntRS~^7nFh|2+9@iW%->3}WtJ +zuCHuq50o_fOPpQ<%q>1h}sx_!;;v6qxT$)Yl11 +z?YAb)zY3auWn})e|3bQ8UbvuVbipoR^{0gi=htk732CVQu!- +zN?TzOJH*IbTPwGYi?{aS3d@t`vq95YBQvO0ZXFqK&EZ-q*qUI9dDzF?DYi~(vvWl@ +zu8ciwU{=-2t$pLIxg1xTG`EFJa}CUWwQ}pAcW22Ix*r5kJI!n}B4Kdzyi{n{WsE*AFW7M3N=&jd}+7^Ts* +za>uZ6%q$k>atlk7=1)SVSqAB6wQ}L0c;N)@Y;n^3Xvp-vLHdo@(xc5jt;{y9gxwQL +zNh5vI&&8I(ZT4xEw&O)?fl-=TE4SpuTl#Uw%ai6<&=fOD{lu0LZT6ZHTTKP~a4;o3 +z;FE3>Tk_lN@giHijD5o(t*wWo|&68^`4rvz4KgG}9;j +zO5}RA*$R6gH-3rnmASETZWsq|MG2;)QlE6K*fFlnKDXF5x19Ybn35j#NrS|Wk(|FIY34(w +zbq49-TDfCrykio#v51`zITrL;0E)V +z;evtD1)cAmvrj3tO{rvWns=~^f7ZhP!d*}pUGV*T=j=zzZAVMlf6PDF#Sgadd))=2 +zqGv9>ch0_|*tVja{T#0UZwo)sUGVJ&#=+u4ffd$R}1y1kJBWcgAVb9>`)IGu(hxgxZPp{~)UG0IX4*yh_cWNZ{a~o0`2ZMbe(}Vb2}W +z>MiYoMNa=Bhxb#rXNVwI?@3he6vD19eyD}t=k|<>M)$S{gl50s^sbGhJ$HsZ{iD&{ +z?STyr{|1+Lp4&5BkfS>j(fvZd<}QAVg)eqnX9#lM)V@YVUHmr|KG$uX5?xf+9(cgz|FqfL +z5=mS0!`8Xc@MhsQXBWTF!k=|p2MKbxJ`vs_oN#sV`4;}L+d4KHZfFlAn*9l?_2l+cWi1@*wG&Fy8LUKy@w*{*qCtawy3bJJ<#s-w>!LD?pRMj-mojN +zVY@KN)y3an;a_&g#tZU>eTfZQ1bB;3BpoXZ$A&~V>}e02clgh{yu;kFYX!M;d!lo% +zaH_eB=Pmp?ckE6Cv2jetyp0_tKg~&UT@f{kEjJIA|(1 +zGBd>7OMf^i=WI#j>=sHk-j>Yps;!SMqzgud3vP+l|NHZE_VRLDc_|w*GJ9cueYjvu +zv_AFuIs55i+v#%lU-J%i@&B>#ecT0CM;BcD{G5GCg>6bP`_uV{y7=W5{=eJ>r&m2n +z2c1J*ywAedx(iY;?-_3#!L2A^55o07vGBih7kmM8<=+D?t!WSZ+Ts7T%X^o*;5(QP +zi#JZ@a*LAYz9Cbcfmu>3SM`ZkjplMo+0&sEGtkHURIJKrvo}`Q8jIN#M&=H&Y7$pf +z#O8)l%oHE9LagfBX0Ix@Rh6=>MrKH@Ts10QHHd4iNSe8zi8C^DYvroR@zx$(VHw*H +zOfk!R%qX#Sbep}f)K*x@P79`(dwfiR*qX<+6erC!AyeGI*lOk0p7GWZ99O~~4yBl} +zK86unhqT$bN?S(}J2#YKru&$6Vrze{qdaL&1x+cV)T34|93C$mzzwNLnoEPGQlm6O +zES%V8Zz!@gl(DX0O0xK*abn>ZuA!9u+9>rA3rDos7nax-ROc)^{SOyhR0h5aMLQ1=6iysdyLX8wQ|eE +zcuOztcp2*nrle}0lqa@~X|o?MwH>cyCm5uPTDfIlyk$IBQ=BwE95Q`jkk;4AExqF{ +zqqukp`$i}wP4Y=5v1M4BJzi3|NOi8Ry +znk#aXxw%D2^RSR47D|hsXcZ}xdmL|;~g-p{8(mi5FPMh6dVe=QW>q05%PM>5G +zJ9=^(%aZ07gQgda(%4$LBRAeLgxgq|G|vy3<{PEyV#kCwd#c!$DrbA1I?%;$Hh*B+ +zVqpF@{X)86K)B$>XwD8{t9@qDe09)twUKed{MK;6;AqYs;Vp;vpYDQQ(fa?KK4&j4 +zv6WY_M)(-4!Ruciwe=;Cj;@PBj{oFDtBoI5$**n^u=#_ope|6<{< +za~J$$?4xqy;CSOi?&yD(wg-Oh^#9!972O4AVLm3_IFvgoFKrLp((J#*>HV3z;Cq;> +z|1hw$J@A^#|LbP&3+4|}%*{S#t=QO~`zE!tJ@9Xb|KBceuSnW+RoF8;I(2V*puX8( +z@ANKpdu|uxsaq0LcMA&~UHr!u{ua0AC()@pg)=U1j@xsMARpVFIJQ?f*4)J(v+&h! +z&z$J7E$xA7r@z|a4M)(PKN?15uYhui3l9?HM7+)q4}wTZJZP7r)ZNUvPW+ +z3Uc-CM0K68$mP8)lJ-msd-9{z``ZI^n*DQ}-h17iS%Mthnuyj5f}@LXxA2qPo*M)? +zT9=462%XK|Q<1c1a@aFJnzy+<(9h}b=kUH6Nm~bmtv5#Vb_hFMUHk|O|CHN0T9ES^ +z5_#K%cbwi|xvh6an>GvAJG=OwTKM>ux#9&M@@UUGEt|FH1m-PY>`xv4JE +z)F51F?&42c_$S=fdC^6i+XG{q{xJ^k=}6i-Fl@akx@bpx;5nE7fo5-`+nOuLiy9J( +zwh5m)yLisRcet&+qv2icf!iGZ+g#phk+iiSY@HAd?`sdNZ}zWudRe!1wjhVMCBl1z +zgrkd3S@_=W*j0i&XM1AKUSVIe*A+>}#)V_IN9Sy558UhY-|O&x;*JfD&eVQ+ijNVETl)4M8?j@=QC^^I=WEtni#yky~LyJOP?dBe`chW!G(%Q2FUjS9zR +zMLV~)2TnQtrySnzBI#KFaO{R?XPvOg)y2=Z@Bw$hpP5JH+<$sLFBl%pxzu{j-nZD+ +zx14>`!2FZHkS^#GF1Rk5)6sg)URPnOD`uA%ncKzONnCjmJ0j53#ouk=|LQI{13!cO +zYxAk5F8+Xpf6!f!fO-FT?pW@0S9N>fE0=#{vv<3@AjCX+h{3X4*%0G?`ZSc +z6tlp`OcfjRxT8N*w+B9U`agDfFT$McF4NWRf!CV-uQ|PIV7}hR3>6!{_nef^)FsX| +z2>)*O{t4#lKcuzUbIWYGC2U_VX1XIjLAJbcG +z9nKY&B+U&W(?SDtf34g)INmyuYbi>ar-e+%4UAQ6?bl{+DYvzhvhh%g>F;AI#nyow +zSCKTcK@)3aX4lHC`SI4?Tt`{b><^m!MrN|uI=0Q;QEKa`WP1lwQjt%(N-P}LW*<^) +z8&b}`ZIB+Rl?!{t3rBJdB}ua@WLjpB9uy0Qat)R2D1%g1D;Exo7mnu^7AMVevp-$V +z-fxs{t(6P&#1AA+Vo7^R7|a^cu`;V|xOB|9jXl1hBiHDb%SHv6<<+q81_ +z{a{M^wNJ_sTSjunOOj?!$YeE0i)!VTq4AbUTul)>A(WD?_em?omcDKFnsQrBDf>kz +zB@OjS_lhlpxOhd`pAG6MpXU-U{5Otbejw`XE>>V9Erv$sBy_KXaBZiyb-+8#LO^dED0qi#<>K|Z!SajZ_Lc6IS{ +zEWF_MOcLZ{`xDihg*>OXB9ivZ40{GftLxhXO%8vP%R45L_Dl(Ta--D^Lb$n$KVjk5 +zyFGISIl4I!-6hO%ct4D!J%hrYf@pL{dq8mcH#B>XMADwIVbAPnbequW?BX|B__W*F +zLy+@!CGxfl{ajuA)fV32wvLPD?Q0KIH2W)@USlL}y)|qd9L?J!yyNix%WdryZQ9jN +zHZv%z4v@fw}i|~NcTNO!L3&YkS(M5aO1D`tlpSrw5+}3LaIlMg)-YcAF +z?&6PI_!_tMPC*WDNrZO`>mA;hcW-ffX|YdCu;{oI2rNmv@#s_LJzGox+E%E`E@O-{X#r6l7skUT-q$1PSbjJ*H`=*bnCI-`@3Zh9xnqL_xwAgexkEVR>f$F`_!r%=vC+Gft +z{r<#)&B92hw+!Y>eauL)@!}gN=|IO^A`KFNR6$4W(HeP`Fp2UKk!pHX6 +zN%Q!iX}poSUTpl~jg#`3t%)=B!fP96C$GFJ_`3_~g0bO(+0irGgnw_EoizUtH2q*? +zde+KS!{b#0xZH}QxjbkpH!?HDs)=p(#v)r|8GAICVpjW@@nY2&uCbK;#>n&)t46fh +zt4eHD6>L>7#Z>v2La{2JYb{Ee3qz(B15;BgSM`rqjpbTPlje?)X^4R-6Px5V;&V-d$rkH%4{tq>~SMAp;m4k6K@^LwNxg}`9V{@k-0%^9p7f>ifvpu +z+ZIeQkNKEkV(X|jdq;__qk`RNV9d30>#%t1WNt`N(%d^_+Gdaz*UE)`;)SERA*Jlw +zp_DYhC*3U;=Cs)xDr^nK>@uTtyI44hTUf-73Z%ZTVt`<;!$s`SLuyd>-FV}zI^GX<;xeae5tv-e33QFm)FViC6#gc +z@+B@`zMz*cFjto^Uy$X?Ce8BY3$lE%B@N3LyRv+lPcL6&T)x2k$IF*@$?^q$1}Utq2-UzU;Oi(RvPS*9;v^yN#pEnm#AeBqVli$pJ90=RsUGA&7M1wfZ;E|=doeyQ>6m|hK3VX~>x8uDOIiI#W&3L}IgxgROiK*RgJSMb +zuC9_DVPO6u-y_)*U6a)U!1VR0@6ON1G&AhxZ{&6AKbOt_Ysch`vbyiL{~=~yFXIz3 +zfk#r0`DOJPO!+!V{<7-^<*~9ElKhyA&z0FDo%{y*6J?hvmwV+;x>k{gF=gp!{K`I4 +zp3lk;B|lPDH0jwV(@gRsvecAEN%mydi~1)w{gYewd~)m6)WvV^dG_*SGn?s8ZvAg1 +zkIlgRN1xor1<5Bj_!;Dr+lV0f0cS +z%tC!~dlcr%C$~Ws^2x2|S?aNwAr}3UoBqkIyFR%UUG=D(JLAdApWG(?mHy;bL_WFY +z{x#Dlx84V@JT|iceg^sE*6ZMv$7a^UT>0cSXgT%C&3G00D! +zH<*)8ZbO%oPi`<*KDo_$lK$idbN!Q>{>iPIKDn)F5A^D%eA`m*L)2q4lRhJl&Gb5y +z;jx*ei^*d%1J_WG%~Zf#d2D9r8uHl8mb27jGdXL>V>2*U9-F!5_w-{kFjpR%nfH78 +zu^E^vkIhVjx$>E;-)+=mGqYi?KQ^O3Hq$+i%@lu-V*Y&9<;P|o8BRYov+cl@$7X&3 +z^B+AnGk7U^YzBS?d2D9DQu5dg%$3JxrthL3n}NCV*vzfF$YV2oW>SyMTn}^Qv6=oe +zsmEsS*hL8{=S-#4BQqCDCUVdz5Xf^fN%;N^~*i24! +zrpIQA&tB;)PjSA-{>Zf&GaiIo#kfwv6()Fq_Yfj^4LuO +zLeg1=x$@Y|c#(c=2Il%>Gx}pQ-SgN?pIJ$B&us@Ucb4D$fa)v{TS*?9f%%Ufo0)ll +zJT?PAgFH5KEzFh2X8O+}o#n;!V>5kckfRe`xMAn{<|8t~@p~_8k4#49u0sX7bLF$7Z%3qB_f?&XLDvwjH86%M;I$$7bMq +z<*}JnkI;|J!1elLGx}pQ-SgPY@VCy{`wm`m`LUUuGpNq;UE9fHGj%gEb(V*d$7V*p +zML#wJbLFv_{I|$sGbIP8&hqHD$YV352d;FM%LmYp&A|1_V>26JP9B?q>y^i59)`K{ +z*v#N1)MGR2V6HD;^yN$UEMH1s`Es?ge0h>yzU;*13(SAKeEFCxU*Kop^5tW)d@04{ +z%iZ+y1+G_@FL&eeWi`Egfw{VTSxqlrV6HA-R+Ht+)tcqYYJK^lFJHQC`EnyHU!GN# +zFK6iGivgD}XEH5cN^$uDKZ7h^N^toCb9MQ$f?mGdh|8B1WclLIEMHcT_A3}yK; +zj$XdJjmsC9|9JVbj4WT^XW;T>8Ckx-TwT8GrI#--SC=n)$?|2pX88hhW%;sGvwYc0 +zmM?X&q8?`O-bhm+i28d0Sb& +z{9UtrSw)sFF#qxL8U`^JMt~*Q?8y$LZw@T(2)*^yN!8EnnU| +zXYadr@#W=9rDplEl`LP%GcI2S;PT~7dier#b@}opS-xDOS-!kUmM_=h@}&>Ge1YrL +zN!t&!?7VKq@E$$3z6$T9_~Jy(+AA-scyE)- +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 +zWscuzf +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 +zSnjXe`MsbQk)nY?CTVqlVaOs)V-cB+`X +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 +zP`!t4IeT@`UV1}zBUK~fRfG7P +zaw1-46Ww0lI3=$>Wt|$bOf{LW?jU)45_y}YlWyTbukS|X&;}{bP0UmM<`t2u{>k7W +zci@mqP`thY-OiSUj+PRxIZS-RqQ2?Mq3tPaXV{WmX)cYl3`z!bJ%Pq1;iWdxGBn;Y +zk#8;{;y#;rr`K1YRBujMSBEX}O0%PbC>s*W4yn*3oNgm6{o^e;JYP!0cAGfa>$|es +z*;(S~Ea%o&nyno~*`84LN&}jRT;!L36)6~(3~p-*Y;y}sz4q(7oqLKLdlqt@5V6mW +z+J`E+yQB|X!oR%sK1$<`l=Z2Q|TK=C+Z}G4ak}e4v7eBxL#D#N+|Mt80x!`p`G#TwL&Rh*#pDshWG;)zHxv^%iI~i# +zm^^}*%w;k8#=ykDB=eXI223`on7qSc(vM=YINc4|-}R%I+``_FJ>wmU$!Nsn9Tt;* +z6q8%8qnN;uVge^MOx|HJ=|?ev@1!LY7*b5&q=AWnNro|b7XBUkE7fE&n#JTcdP8<( +zVLD81r8i`sT*zVqFVQdwQ%qn;F4mZVKMoNVge@-lQ|TVdl8d4EGAzWm>8I39+Rs9lR6cX6D%f|ASP*d +zCYK;4x}C`hipd>_$q5#dOAr&>nZS@@0w*<0POz96V=);@F*%iXXEKyx@~LiT@*c%x +z7Gm-qi^))m$!Xk~z>s1BCpApoV=);@F@f)-?Mz@uF@ci?CI%*%#svNy`}@>nGK$=!&FZf7D>OyDG9f;*GD5fk0cL^d!nFv&b7e*{dP +zS26jF#pFiBB<;@RM#Mz7Gx>~Sat<;1jK$$+re31}2%uq(5M?@d74qzRhCNhhj1nG9huxfXXO +zCFwAkjysbQ787`hib)_uF@Yh)WE$>FN+>4Rusf3@A&Lo{q?o{W(sm{#6chL&bZ2rr +zWME=ol6g$Z0Fx(FOg>^UxePH$yEC~AF=2NmuYE)@*@c*V#A0$8VuCvp7*b5&q=v~y +zEGCyBCb%VDJF1I!{mJylTnBX?o41vF@ci?CI%*%#sqpM}dW*sKD +zGr2u2Cb%=Xoy7!RqG1xDn7|M*!JWzNhzYwhITE3mz)8decP6(ZChX4Sc*MZOz$EjS +ztN={*tC)PsVlopkNxL(diI}iElh;0_n0$hme9B@n6EVS^2@EMFa8kqMQx=n%hzagY +zU`R26lLjURCYib9qCb%D!b|&vqO!5(v +zcUerbC?*2#OkhYcfs-00@3NR=QB2@FX*&}bQcU2afr)`hrZIt@iCIl1`79KUmD& +zXOeG-@RND2h={vv;?3UJ%x))F?BL2cxl-mkh_o>w?UdHIh`ib_Pm1tklfiaZpxq-3 +z^u{jjcFr$x%rEC|`(L{4;eYRs)c<}3aI-(q$0fWC|05g}&A&>?+9quhXA*IQO?=#& +zAAw(~J&CN%(z|ZqKfL)jDs>yA%iwq5H#YGjZ~jU6m8whBZIj#{VH~_f;|6|vngZXs +zg-2kB+{~nZy$gPO)IU-Wzl`*c)E_xXxq*|&%}mM-{Pw7Sq#nKqa&yw)CWG9hN;zMp +zT-`yIY)&lMC4K24a;;w;5NRICuP!0tDVsRWYtQd?t}b<~uHfc{i2cf_eXJ7QBPE)M +zZ1KwrBF$5h!C_5-VQ!(cjqu~*d_R6t8TVm`#IBFV`YDAwQ`VP5mX}TP_y|9SKUm8B +zV3PZH5NSt3+9FN&5IM&$S4H@2o~t0@1e%95bC|TR3cRj)&Z~k}H$juxgdTpZ3 +zn_sBZy%t4oPLcd!(fsL3-O(t^O*L{ehyE!@7$P^PC^u1-n`-1{4$UqwL~c$Q++^;? +zlh{p><}ChjIS~tNVzbvisoQzD!m+xDn_!Z!=pfPEiRdQj4L6bJ_~nNp&3%)>hundO +zTtchYKD^r*FLT68xt=hI^@_%Rr4(*SS+|ER6_v6n!VgUb>pg*6n}q)%m@H3Od&|#W +zz{IY@WCq0~H!UVJC?>fqCh!ss6SxgX#RP_k$qb4~E@Co+#pDBu37kYsW>8FW5tA7# +zCLb7>7?@=K9=c}0s1B +zC$;SIC5y=t#H4^?0z--koHVjarm~BHiFSR~@9zUl)MOIVVKR$iQkWK#Srn5(787`h +zh6&sTq+$X?#AFu5q!2Ng#bR=rVge@-lUWp#Ld0Yii^*vN69bdXW6}wj1XN7EVKJ#i +zOy;J;q!uxm%VP2k#UzH9z!gChlUl@NF2w|f6cae9Ve$=&NiAYBmtq1#iV2)FFflO6 +z@D162y(eYuJy%U86Ie{vUPmz*kPeeI*HKIcu$aJ0G)&+&AQclBQcPA~M==>dF2B+Oz`PBDS+q^;;-NHKwv1||k3na1Q^z(h?Z +z2XvU=&g6=;nBdOj3KkQ1iG~T>2BcyFL&OAkCRZRPx}C|#6cad!nBdOj3dBUWGx^xS +z#K0u;n4AJkj;NS?#bUA&F-f~KS&5kFb|zm@Ob#F>a77TsWF=yPI};dEOyH!3$yY2U +zD-jdinZS@@0w)bj3`{bO$+DES_fa*O+@-?=cP3-fVuCx9F)SwV5)Bi$4M@cVhKLF7 +zOvWH4x}C`hiV2)VOmJs11~Jj?Oimb>7?@-plf!_CPsOB##pF)JB<;@RPQ*mFGijli +z+=ZCH6+sk}I}sDynZS@@0w*<0T3Af(L`-mJ0z--koHQ^oFv&C~D*+QVnS8Co1a~HL +z(qe);lQ}FV@DdFZxD80f1crzS?o8$&Cc2%;DT)c4L`-mJG6yly?MzM?m>8I39+Nm= +za$LovmBr*C#3b#`M7J~f +z#K6SBB=eZG0wzaQOul9@S%a9Q-I=UGOmsVwuPG+S5fiu~h+?t^F~OY)3@IjXQp4nH +z7LzrI3GPf_NHKwv1||k3nZ^WqCS7VWap*9?oyp|1nBdN2GK&ekM8gDb15z=8A!33% +zlgWsQZfEi##RN_wCb%=1jF{+lCLbD@7?@-plK@~Ms+hT^5;4J@ +z$)$)1yEAcoWME=ol6g$t15Ey`V)9oOlck7B+MUT##Dv|MJn&bF$#%p9t_Y%-EJaLk +zX97ct37ph0`74XbQp5yzCNQL!z)1rW1CvZ+0zH$xYBH(NVS+o8k!dl(oykZR6L^V+ +z3ET#xVgf_N1a~GQ5fgT2vhIC~37kYsaAz_SF=2Nmj`s~r3`{bQi3c$8s+dGrOiYML +z+MS6BF=2Nm4@4*?6^IF35kxUDAttypfg!~NPHLD$SWHZa3GPf_NHKwv1||k3nZ^Wq +zCVSOn@}UkB+?mWsiwW*bX0VvROEgU2HXs!f7$PRPGns*yusf4=pHfWVBw~U)lNpE! +zyEAcoYG7hul6g%24w(E!#pDc&$peT<+MUS*hzYwhdEgAis2c5O*enDJIY9b|&vqOyDHN1iq8DGZ{=VfiHqPlXneF{(oW8{lXs{zvx-Yrpy4NY3|vI`1qibCi{G +zVUu|`ykvAdX9#~{!Tl-g10l-;Ci9yxoDy&7#ZO(x?Yy;-n3ws@qaqC*e>(4+TI!fu +z!Cei*MSgQ$q#>7o@rL_T*89Vje^i>gpE^q#ddC|^@+(TX{qQr#_|11l8sdLC?_5#g +z_`Zm{0fy84<~5Oqf&BOL?@w9Jhb-q!=H4A7Z$~0;ikW&K5z>Uc-Xt7vBmD3bSg^m|XxK~W(#yifE +zhB5JmVf>3Xtw>qNhb-ew<|`r%=bt|BTv6;;QO11*Kl35Kd03?3+|%cs-O}#Ma=j6&Eq3gWB7(r +z?t7EDf23+;GMMKILIMLonk&~L7Yv<&9? +zaw1N*iGtTRq1(w!S8S +zN^YIB%|+z@@XLcD1*4L|a#x_-Bh2vHuTgThOCNZI!EK~qWV~Q7zqp);SKGu_y!KqB +zu|8#;6|&4S$=7s{#yyF~&C*#nk#F?Nk4Bn%@zWL((ZJ;Y6O%ba-0-rB$rn0I4p2<| +zX)!rKG4ZpQz)LhtR#Qx1h?pFpnD`Ns11u)1DJEa&FgZXm@gpV&SWH$Mm>8I39+UBa +z$p2Ghh?rn9c@r_wC6l!jlXE&uFqyoGnCOzpS_2aUlgwk%A2506 +z0w!k +z{7fyGY+^BilLjURCK<-$ZrGWORWaGcVsb4e6L&gH;JKDe+$<*W5*3rTY!nk1QcR{} +zGI3K(U`Uh6F&o8X7mEq}Of8wXDJC$a$s}MiFflO6JSI~ClaEzQ?qxA~5-~}eOrAtc +z*ktmTdnqP2BPRErz^|Y8^GI^cF1YV+HvWj8?L&OA=$?J#-n@oxc=POaiM6Obkpi +zk4X+-aze#q8H-6B#Y9M(OzJ2m@EnuLGKxt)VzP|Iq>f@DVlt^?G08_vma&-BQB2@x +zYRROI#RN_om>8I38WY%=m{m-CEG8l*lSAn+f#+H>ImBWDFVQfmrkKExVj^HNIYcpm +zAtsY*iiwZK1b(KLOb$^@V2H`2+Q7uXB=eXQ04AqYOjfd(G$JNxlSw0DqDv+#DJFKr +zWF?D9BVvNdq>;tMj+m@uF=<3hFqt&6n7~N`69bb>V*)!9S;Zu#!vvFwlok_ACK8JY +zyhOuf4aEe8hzTYW2{F+nlQk5Rm<|(6CK6(zOD1a!Obkpik4ZLQ@}7#xQWleK6q7Y+ +zlgT!U2|UMSvXo*n0Wn$1VzP~5vKEucHWrf!h{;kGlWi0e_?cQV*~Vf5Ck;#tOfrng +z8Q7W3RWUihVzL&K$xG=lf#+H>d5OgYUZP=wJrfvGOx9pBd5K~ILrf;vGdaLw0zXqr +zCNEJ;V2H`Y=$ROpTm(#}0VbcQnCN;Y`w)|~$z&g5qDv;&Gr0>f(e+IBAtsni_OY1U +zg_!7iCi@T*OeXtSOyHz}iGfL`F@c@QQ5BP~b(ml>c_S?*m`vVaF@cw8m|)KYhKLC! +zlQ$3(T{6L*$=5neFqyo8nCOy;(K9hHxd@m{0!%(sG12u*>M17eX_HAk#RQ&XGQpn7 +zJj6uTGpVPT{1cN&J&Vaa#6;IKsi&C0&(xAhJ&OsPG%ztR$uuUgGkI9WOyDINCfGB9A;qK}lZikvfgvUn?3o;AF@c|{B@=;S0z*tDM$g2+QVhbeLc=c`Gd@m`vVcF@cw8m|)KYhKLC!leZ8PT{6L*NskT_OeSw3 +zCc0!|^h^v)E&?Wf&ylQuzkLCd$8b62nGB?uICMRejTDn9 +zm`paZm<*(tICVXfjT963nOZX0$YKH~4NMG7GK|TMurnF1VzQmZWC|t|S2|4Kxt2^^ +zEGF<06_dxXX97ct$z)6>E{X{ZX)^gE_Dr_3n844}l8K9A0z;Zi)*C$&1Cxt@$>o5_ +zM=B<|p2-u4N!n!c1Y*J_lSi;;Qh}K0dL~aGCYVf~U@@scOmsbyClC`%CQq=Kz)1rW +z1CvZ+0y~qvDkdN5Fu`Qy4g?fyqU{WHey%zKV&iXR?!G@_gE4vXf#0&oP-`&*VzPMAtLfNilf=lgUmN +zlPeJuUC(4E#RPt)mP~fCn7~N`69bb>V*)#q+f+0$lV9(?}#6;IK*^iiDGTF~!avx%%>zV9FOfZ@3XEA}31||k3nZ^WmCZDO8 +z{Gh`GlgY8Pm|!wF#$p05(J;ZD2@DYvOeV(=6J0XFp2-h7OfZ=oLriqZ|0PQTDV4yPE>t +zZsD=El<%gfy_b@^qdhpl6&TVCrPH1safnUa<&BM!h_pK)ZIa-2hqhF#Fd7@6NITnu +zYg~af9${WvDmFbDo2*ECrO8b_;&z)@;f>9ZNbROXZJqSIt4I97CXV&SrYf~t+k+NQ +z;F~7lXj>{aDH@xvT)5t$N4(7@e&&r0kw|x4qI;Y4mZwLYViRBR#>Oh$d)kAkra;Oq +z^!n^n(){)hE5#yj{(rAq$6W64!hs%fgiUv% +zZHYzo((O0S?Xq4Sw!Bhlu8uUEh54?;qV3Y>H_h#0{%-xTW8~zf#K}78_4#wVtY3vK +zH&mKW|8O>yKQ@{_S2?*^`f0)3u3xTqs3BD&;#GtAoboPfS;$gmGS7%qO>A{G6ge6e +zaxaFGY5s71tFx-aQB}@Wg_7nfzque%HHmL2>arGuEzOnY)iv~fhc0Vp*g~2Fr^(#6 +zhO~@`w+!M7%Db$KLzcxR^Q;=uGBMuLhi_iU9S$YUcE5Q-q-9L2v$@pKT)|DMG*{G+ +zmcj9s@jPGLW#z(_)=KlkHKe6)yk#`sS;7UvN%IuH*&1mX-s*$bWv`PMT4JjBOFX+!N +zF5|ukCFL5wJTy`;y488A#Br*eTNg^ocl+fVBL!3VX+>SuAz{m|N_klgY3>(qzJ#Av +z+GYJDY{{>b7e$)0TAhc>9fylKdpIc<`sLb4b8mk2!Y=E9kmZ0$9#cb_bK=d}{OXD> +z>%5R|ydq?;Ytr5BM{5x`H=LBG`Q_CS +zeqgJ!wan34%E4_YHKcPyymJsgzr4$OTgY;oNuE_hIw!_E`|yEVcE3C!(mAHp +z87OrGD!3_?azzd4931Z)&#y1;vRcEIZ!6`8Ye;9`c;{#yu0shYW^HZ~niBtRp#n;yI)Et+h+rgC(B8yG_EMz4;TBti94@O~Q_A +zKTZA;YqlOEb#;llZIas~jDz_te)BbvoF15OPSov^z6)H}#a#2S^%z;SJF#e!^yFLD +zby+_SSw1$I>&Bi<~=O~NzNT0uXUDq$Sp}?G8D-^u0%le0qm>bpwG+a}d{dVaYMMIw275_y}YlWyTbukS|X +z&;}{b-6Jlti6_0jEQuVdOB~uJ9r6gdZK+=_dT0+SO##I%)V8I33!J9C| +zTz4SXC4A79@(qsqu2!nIwFetLfhA4CKCdrFBGr2m)tjZLyGMM;CMLYTzKXJ=Jy_@p +z6ncc|Z7E-V)Hgv<>f3|0O@UgsVDb9qN<`V5P08{32B?m)Rq2z%{AmE2v@2QJ}XZ7F-7sQogfaZ7vf3QyprCIN1HkVs>F +zqH&|N(%mEe!6ts?wGWd>>+5AJIU>~jk%+EVr#qW1pE +zlAY3>t{$<)CKh<@(Nj<4~*KcRH9p@ +zhde#ve47~X+NVe)x;Ig{K^o@n5le02d*0X}rLe9&SnmqddxX(#so1Zhu}c))WSuH+F?Yq^${QkJR4OBObSj4sUFMQoEr&IN2ST +z>=Hg~OT`99V^=G++uDQAdjggw0d5bHNbR0P?Plp4caQk6P3-c<`YPQ!+Jg&RfdwAn +z+O||IKN_2$bl0~BA8QIc<`%5p*j$NpZ%%aYlKQ+kyUW_!+8F5L65hV{RMI@cZ?25w +z4CVVf?{5#5GzCiBLM6=q-?yT?c#PC-N!0C@-0%)l*b=TZ*F_E(zE +z!hA?HKVLbSfVp~mkhQS~ui@(X{EYMaQpfidT>ntgTw{XIEejnjC0uhjX`bXabCIgy +zt+e0ij0T&uI7*ilf%oeCw*>-^>+k(N<>b4i!=aM-fC(tKA9 +zX&Dx8nauM=+@x^Qe5K!fU!P+7Tz*e6x7;LOA1RpJ>Repp +zSiF#XDwLG(^~;w;3Uc_xrCru9!j@T;@+~!_U`V`R0)MKw%epRXIahh%c9d4I%Ttzr3 +z&+y9+MEE|f&Vvgb2TQn@P4f5%KZZY8%KZ>d%KiOvS%e?l>g38DTrp=h$ptlppA_f& +z@~sQItVctZqb7M$4dKVe`QdzP1vfmDluP~c<&n;Dt}vI8Eja=Ci5%|I9yP{#7LB-wnq|)}};OowUg%{HOS7@|U}|V7@1jwOM-CE&PW! +z|3;;5gLK(jGrO!$ge*^(%umBR@}l{rQAQP`+LNpHgUH% +zf3$M)=aXlCxkd;+|D#Qu=*|Bje;sKU5^tEme_zb~5kCK@P5jyG>m||KwtB?NY@*xi +z8>i&ew+9zB1s1u5+uKsU*-_t6C2yB>(k1-l_4QE>?P#a>2&H^^QD3fds9vgW>Jb}l +z;u5cKjzkV^P8`}LDXt#4Zp&FI2fe=D5~<#isNN#wdV0hwY~o8^-*|~s*C(nsN=w|r +zooy*!LDZM6RPSmJMqPoZM;PYyT`m!2OG4Q#NliVXU=!DPee)!uY)mLSrCOKpO6OPvFZYp}8$(pA@yvSE3uFIqn{Du}wVXwGWX< +zv@Q|dCcWY55hvNigI@bsCAz0Qm}m+l+`{^{l>Me?td~-_qdhpx6&U6b;BGpJ6mClt +z)=RfG^@vZ|#5=sP*-GJN>9ku|=Z)Pc5otq0+96GM^@yL?#C-3CTesSSf+w)1NjT7! +zij9fJ<|xwU_F%g^(C!j?ys_RAsojyN-6Bo)^oUp5#FxFX@e--6PtO|HSsZVfD7jx-W^D&aOF_E=XDhbT#vbw^SrIqI2M{z4IE +zk9e<5{4a0*3Hv(IFe=`V#lKk2-4CDl+r%1geiG*Nayt0DcFQBoC&e53^4~wYx;^-y +zEAXI4xY3*cPnc`}0Ikc~KWy1rX-XBn3aCCyI1+$&NrqScvQ;>a%NN-O2c8d5Mc +zUNDj0Q`BX>JZ$k)%C<xUqp`^_D<@u2d +zx72l6hleeDE9K=iq_bbV^Adi3X_xi0u;toH`Q}JxR;x2m?g$ifYr{!-o?muEI(zf$ +z7j{`+2w7e*$zy9sXHL8`n_pkiWxXk6xyf|lnz~kJve=O<<9dJdY>&8M?WY&6a-4fM +zl|Lw&f0dH8P1+Qk(Ph0fWVzI2_QHI2G=Hd)wM%-}CH%KHzmHP)?+?!Wa!DP$!)p_5 +z-uyzP?q46Aah_P{I8nmA_U*Gh;`KK1FW&rbCah!rK^lDieVh1eZ~i|ftRoFW;|&w} +z7av*P9=zQhxZNd0y!oeKuHI7TT;3j>*%X-R7H;w8pM!b-ctZ}q!m+$P__`=F)Hg!O+ua_lYYNo4g=Jpf^%A|Nu1EabCeHNwu2J%~ +zOD8=-me+TgL=J699NH}%YU&XW*~DtEuTVL(v7O%LnDPya`lc&~wzmfrPasvy5w|d) +zE#Kmz4?`{t^HU%2p!pgRk?}n(azf!$ZTH@*vzqE;SyuN7?sotKb-YXS03H5C$ +z-{`1smZEHG4@&NU-t%@l?}f>TgHG=oD+ +zj=hhX;IXx7CmawktsPq%(fjlK)Y!Sfdry)^0^RGahrM0jwaQ&@)%#Yb>R7d^Zq==N +zcGm9x!&9Gr`0i&vvmM&I-gCR^P6juZ2R2vwE~rmBFN-=aiVZ6Ee^};w)$1G*8?^Ie +z@ba?2yyrjQD^tqxs{G*w4WW?K(F(1Kig9n-&5@WvFwcYrbBz!>zo-|xb9@I +zUqzr_x$jVY(%CKQyfU_M^U2_@%D^pUzEZC<&CeDV#}{t&e_3%xb2+pY@420hCxcVU +z15+w}W9pO6^r&-iELw6h_&{0UfeN41>zwLm(T(xwc7MG5jFxa{9lQ+}``NTj@o78! +zC1t+K`eeg^Xv5X9Y3ol0Z>R{|Q0^0#I@Tu}+D98Mjrlj7434b~_{w}$-iASb<}Zo+ +z*ZWsioY8J~Xve(`z5L9-J?`J)KUwMPQlD(NB-(I6Z1s+l!Dq_?&sO-B)h8RSi8geK +zo!jboMvFMKsosV$eztl`eDzNM%rf83`eZ}jXv3sf>xPrTgB5{;<-T9)lMP*>4WnYM +zh5ogbXS7)kE$B^u=l1(p+W)+AZqxSJFTe40n(gkCV|_Q*@;`6V}oQ`ogl^_kU{wc-4BCp>A{?zAjxVJIOiKRsn1S!)}aXSwozmOrR5zq6|} +z$NEFA<>7Gtd9M8IQ})tYTWOvp?S65sW5Tka+A=1bKlp^FZnnEF$J$bxu&k+$%|F>(W@)-_;6G}wJS4Zv%XS6@zDb98mXIU%rA_Kx1{anR!tp5rnA|0zE+2M?C +zCp-)0x);p0-jo-ad_T(=+L+P7bu{~w{qv@qO_p^-tjTyaNv;ws@5y`5KTpF$! +zaKbZYwtGyD_0!r!i4t!+zQbKFDcSx40-BG*?(t_-^dx%SPrF3XEt6Lt+d;jw1At=ZP6Y7>zq)seKYE6rt{ +zbIKkG*{0@37TnKVJsMquT_Ff&RoU;E?Yx^ZH(k0w-!3ocrEccqZR(owCVyTWy4Yv$E +z;Ynn=6WP{aZe-Q{tffn1OMh3VhnAfTwm&$@-6_ku{=400w2K{DnKykvtb6j%PVRUZt +zqy6a6`gyBH#tI5g1{YQaqGi4V^~tKC(W)7-*gF5TiZj{`4(*t?s)wJ&isG@&et+c| +zZJ0xQ)?1~*m;co8mL-<1V--j=&c=$s1K=`tXhc8q&!k2&;zEIr= +zUjjUQd0Pr!sIG@EK`DF*@bD#o@a2>kz8qBHiwa-bE_~TY;fua|D0zn%zI5T?OY0qG +z;mdG@FB`@1h3ZE5LUlcSStErn8+rJ$7U4^8F?@Lh;S1Gy_~JqMLUkj2c~=ZysII~n +z6~44h`0@yaFSGRUWw;o=Fb5A`sQ&x#rILp)bPt3tRM*2755kw7V)(KK;S1G`@FgUM +zFH|?emyj5~P~8Y$sIG@Ev!w7Pq{0^!zO-5RawCN=qxA6Q2{C+m4&e*ce;2;2MfgJZ +z;Ni<72w$jfgfE|n;S1G`@Z}R8zRZ-umrr>3GD`|yKH=dD{k;*sj1t2a`g;|=sPLtY +z!k4eV@pL-7{9O3rk;0ePdHAx%G<^9C;mg-z_(F9feEFJ(FEgd^ +z?~U+<>O6d*zc<1cs_Ws)+2vyRLUk3ssPLt2!k2>-zS#BfWt{%P~8Y$_KM*P)s66l>U#LHRtjIJuEG~J +z`O-F%FW*u4@{1n6JSc`QL4+?<|6TZU7LzY@4<5e!ipdwM8{x}aV)#OJBYb&_hcAyv +z;S1IE@WmsAFK_YiWeviYU&QcbtqNaM_|kUa%N7b>^d&|~Y4W8v!WYxYmstp3wus>i +z)s66l>U#K+kiwTOJbXzad>Jl=FJ}?HP@RV_4B-pajqv4tF?^xA3SU(C(l+7CSqfh~ +zdiXL+3STh!LiOK=FE8=%h3nP?t#QF +z-_Ale(|ha>Y?blPWwSnR8NP-Y!0Njw-}#tSgmWfAt>nNf4xBj;JK +z93Np1G7R;5>RYwd>iRFY-VWihnfs`&|8nc$ +z;E&CmcT|{J?&(mE&8Wv_+Ul{H%!}`1Y2zO~_sea_$Ko%yO#aI)?PIfFZXI_2HnTjR +z?!kY#wcq{Q%<=49O +zf4NP1RQ%;eb@j_l{c>xgUvA4!2HSU@a&Bh1!(L%#dDvI{v6=RJO=gxC-N7H5>9$;W +zY-TRi^~Yv#h%TuYY9-C2*&9u#9GqaB*Ebm-=?y;GB`iPIsY<&8+7slR9_1`@P80YG +zV=opTo9R43y)ah2Ft)8;7<;kzP1b!t_}mL)dld*X%Ma!9$7Z@0n9VHDKKk1WV@G<$ +z$7ZOm|2x2Rs_T!6HDvjl0jiF!tRe!V6=2FXc1KRR7&$GZUWXkIm3M_+v98 +zsIEUY(`6EWVeB2^V>6v5@fXHYU4Lxmf+ON%GgQ|fn;CvYd~Am5`eQTwsIEUYvvIfZ +z!q~w_)MGR1v6(h|Z05gyOs3y)&$-8DuKuU^*vz{}e|ur9&k`eQT8 +z?hzlGp}$YXV>7Jx>+wfBc5dG;bNqo7#~+x&*Hau=ar{hia(3jIE{Wj&vcUcdAHDXk +z)l--0uFJO8)Uv86(W+jt{o9lFmReg&o~1*$u1_L3s5~&J(sy}1tGlSN?tE9qJf`(? +zX!N@BSV3{pzM|H)BF{3tnHB7epL-#b?}mC-H?Xm;lgpLEw3QC+q_?U|tEVN~O>g(l +zvkY%$vF-8L7Jq9ci?pkbWQH@kCW4(S1N63XuX8}Fr{_F(ai(=dh&eBcO3N@}d(%{?Jo}PbFcLBmhKlfTp-&Sj+my8L3)!r>7E3dWZH~uE{Hx2D<;LoB +zZ;^Gi%x2m_hql&RHLKOrGt=EO+q$uqImbuOy%p2HxtvArsg86FXIz*F&Mgl}FJ1O^ +zt7jQ%7gMTtF>Rui%kED8_C|jy +z@?A_>e6io;=lL!sD)PmC-R@5QwgBT%aTgPPrt!~Z&+}bOROE~OdfuJ1v+}^d%YA3- +zS$@05{64OY&9s{wn)v2eZ$tZ5 +zk2TwE&9XifVh!D+=UzEvds5ZJ#+PLJolnyYwr+ixFFgv +zA=W0CTtS!|*8Bb?A|_7)6SKvB6P^Sn;$pw9OE@OEz+{Pt$& +zV!z4Nz(ic^*KGyIq*lU&FZLT#4NSzvemz$xOzeF_wkL8Ui<{Y=4e@g?BKQ4V&oVkR +zX7qI(&0^Zu4(%GRb8M^U=o~k_SUES6)yx)diZ9&Z-&MvUf2od44A&@32D=ionHF?t +z9&dW)0K()$9h196Om=Wg-ZSk?c5qDSIy#fPI40wP$z38QJ2)oqqchndVlp0>+$CbN +zgJVLUX>=w#L`=pjOcW+B03YN!bD+WzcFO{EH`prGh4krer~0OFH+B1 +zIybiTa|Pxw?UX~KjY+ZAO-cK6A)7rnVrgcro8zq|{-Q>n4mLx+Y}RYCU1+F&`k_XR&h+I2u#qKybVmG&SVwG%24BdI!g(E5~H}9U>+hI3^>|nQRa- +z>B=$Ld54I}2961RrqP*f5HabhFj1JK9+Pa!OfJwd*(zc(0-Z^P876ey=u9d^Oz0*$ +zCM6Dz2^Bdem!dPN;FwU6cP85$9FwggCiIy`XHvm2p(5{0iX93Qg-Pl$xr{LRYEToyp@OCf5Oz#Udt;0~2&6kBgXGr!Y~N +zv;iiRnLMUr^09;oI+NE-F+peYnurPA#K2@Z$ApT&1f9uiz(nj!wk_wFd@Nyt&g3;< +zB6cRl%M~UHlhk8!5n*yj$7GR+NfF1S!n89f;+W8NbS8^9CRYHHMIt6e9Ft0PCPgA9 +zR{)bmA|^!~6Z%Y}Gbs`=xk6#0Flhr!C^N~^G4YC+RH8H4Z-xn7H#(F3A|`Yb1Cs)d +z2^Bde73fU%b4;j+&ZK~2;uSHW&onxd{Tvf2qBAK_m?%tAkI7`hi+Q9i0j0Oa=fGY0hLb$K)<_CYwb}1^^Rj&SW#kgg(>gOg4*{ +z3{aRTOj3`@2b7si&@p*h#N;k?CNG*{Lf4JX!UUbk0aHxSnH&%?p_>?( +zV9tb!zyzJi0bn9^CYUq%O2P!4$pK&@btY=gL}Ahfm<%CIKGHFf=1fXBCf}QOCM6sb +zx{l5Sb0${<6KT$*gk$nAbS5PtCRYO!Y0jjCV?v*4bS5PtCRZy=6eewe31udK(=qv{ +zh{?aunfS~wq3cFx;uA5Un;4j2&V-5_lkd@)_&6q1L}!9IlYfes&}SN*iH~DKMRX== +z&O~9-2AEt+n0%&VBF&jR3rtKqlV^d6)R|z;Q_C`?k1$z_z8bki}}Bx2GRok_VF +zCUo8COv*(}=q5TQH(<_$iX4**(V3KUOsL2^lj|{OvPr~*KGWz-$~h)f9s?$(oylXsMC?qi!<BuvnmylRRGI+IsLOz0*CCYUp!A}~Q`@+vS9JCo}%XYzrB +z2|ANkfr;3eEKqYM3X?X# +zb^{aB&SW<*kvbF1nJfk-(wxa|V1mwMw}{DNU=p9jw<^dh75G+#kIn`^uMA8q^X>4a +z-}ILzc6dkp@CN^DmuE0-xkLMJZ~8ncZi^o-^xs?QyY~8{EPb4MNqt5)*MhlByV9Y( +z>~#)`?I}sxC)L^}~;2S^{kldUNPHxdx$v)N1fAS +z(e+9D^pNeX+{nssO_xM4UJ;0w`x5oc)vnRi$2ByIY41C<5#EL?V$(J!?H`3~qjDqH +zH?wJl@oB~WV`aYAy$wTR({}pDma#}qb!24NH82tMl?8kiKBu=~TC3+oru#&;^^IEA +zFeTd1E9T#xw4bWAoyv=J2)Fb}1c#LehE@7TwFNhmn6~bdBewOqmj9yv@H;l9UF7OC +z$NDb)H{P|{a$PuWH2qI%uDfuy_0GJA$D2MR)_te{QaZTRp21 +zZ}vYvY7)~fa%fL_)6-(}_Z>MK{Jbpid4=zOIyobn-XV5)tAFCiNlZK9(5~{PJ0~`= +z!<*xWOZ@lJ7kS2^{neX3HFo%kBWHvEu23(jSML>0?W-W~C2qdaxmhWWHNFXM_ArEdND|+^uv%y7WfkhR*TR%C<(x*hz +zd&P?OesebXeR<&fN?%8B`knVSvH6?g^LO|kzicYgo_A=Az3C5AaeaLLHveDBePKG; +zGnzgoHvg$_L`?1lCQ~^kROFb@Nrj2Rq_O3E*Nk~g>+jH>@;0Q!Ru?Djt7>hl@*>ll +z+3KC~)^+}w6}}tmS +zWIo5_`NCWkpDR0JjyIVPil$wU#8!yFSj2}~w(OhyBfi6SP46($Ok)MHXWm_&6< +zR*0C?029;BqyU&q5iyB!OkM^iQ4x~@U^0bcLPd@Vois3sikK7tlPMe%DsoKdq{2jD +zl4?vQFm2u4Iwq4vOuj&8Qf!LJ1dhod5tF-t$%h;hDgu)U9Fsx7WP*svha3|+2}~w% +zOa=jy2_hyRDohk6smEj?Ve+MpiBrVn6^_a0rk%+`V3HwX@+HUQZea4Ih{-}=lEE>d +zBFBVI8kl@3VzLmJATyyN$AnHQOcW-m#)LAHpLI;`moPzRvd@HuBFBVIDohk6DaK?mWhMi4OwJcEnS{<{ +zqZuZ2(8x?Wi;@)Ziv$T6Xl1}0yNm@EY*$V{lnF`<(R6NO2tF`>-lHXW0zL`+^sXR_TC6J#d+L`-f2 +zCWkmCR0Jl-O!@&6DKk05F`<*d1er-cU?OEEhZH6Xlhk8!3t>{HV^SbuQpGWO&9pPQ +z1(-;gNgc=JHegaGVsZ;GL1scljtQMKFsTzUxdoUYGod2Kgib0<6eg+0gff$_bxf8^ +zn4mM+Yl;anlPMx5Ujvh)91|)66J#b+fQgiu9OanMNnnD^WC}2mGLxeU6NO3YF?oP6 +zIiX`B&6&IfOiVkI2Y`u`nVjI5d<{%ah?qP8OpuvSkz+z94NOjmm^=VXkeN`CV?rkt +zCJK`jWAc9~Gr2~`WQd5#edtWKm|;Q(jm)H%h{-j;TOr*@@ +zBZY~=B=wls2$P78i8N=TaZLVg+L_pZiIkZ{I3^DRlZc3k4VWM^p(4kGP8yg*L`-bJ +z1epmHIVN;cVWKceH71mqoYpaUM8X7}$#bTdATyaMVsaXoe8w@MA}~Q_G833cnaO7y +z6FLb@keSQ`CQ@ednZiV2l6p+m5+>j2m`HObL11FqnXCmSQfBfU$K*6H`A)=SEigf5 +zLPd@Vois4{PQ+v_FhOQQMUDxbRG27CQjEz(l$mtWF=;Pi(t~#<``4LaLI;h^tpN$N3~-Nd@z +zT6+$YvErP`+hrV+?xvl|Y>r8PF*C8%a!fjLOm43gF`3OVxd@pF6*(q!QpdznD`GO6 +zW6}?q2^BdebW&lWFiABgl$jLjm}E(q@Xloaqo$Z3Gr2^>q!5^V%rT)NFhOQ=2`~{e +z6YIwu6FLb@keOTpOvKFOrjHdS3X{}hawlQ(m5zxxXY%$xfQe~mawjkmGZWia9Fsy| +z@|B3moxlW{2^Bdebke}&D-n}BfeA7bDsoKdq{2jDl4?vSGs)30xm3htJ35oC922(e +z%VCedli99a*UJafG6muP+`-VS`aMl$zJL7ol6tze(YstAa+3pYKH%I?5!@hExd7aV +zsfzUj&JCReH%L`305@W)a?=Nj8^ulPxyd7L!vEbeJl6f@@Y!Jd%D{#)Uzs=kR=Q9U +z@4nuj)h~l-xel$?n|^+*`}W^nQlAHI#8kx==G^3fo3O}D9=JiOLPgFEoiw-!i`?Xa +z8>A{!5^-HZGi(k3zOzZ_a0Z~Ed1O{{xi +zynC_#JrNV6DicIZ=qCEclYDGEp&~FrsxkqXh^dMd8&BvYFhQy^0hoxX%1vtHiNd4} +zF!>u{@{NwkHzFo#^hD&06H +zPf4i?HlEN)jtPAyV|`XPjtPAcq$+CTiNd4}Fu9&E`CP~3a}g7|pkuOYvKc1Vb4;F+ +zQWb1G83|0JjVIT0OrAulLPd@Vois3!HlAG1F`@5d>|&%M$AnHQOcW-m#)MLp7j#Ts +zkT99ZF}czd6Qn9vikQ$%3{0@`go?lfsmhhWL`qe#@q|tS6Qn9v0uw1!Q5#PbCT)Pp +z-GoV0$0RCZLKh57rkG)JH!zV>6>L0t0hmY|PwoaLNL8rFF`<(NCep@}yMYN(6)JK} +z=%m6#VUlW0C{b4p(4kGPAW_kCMm|`X39*`bWGAjO!ASLbTY$) +z4jP$BClM36iGc|=o=}lvatkt(P8<`9l$l`T37zDa(04L2lTI8H`Xb0o)W#EqNgH62 +zLzskgOhO_ibV0}D7Sqfmhht)qG81e(NdqR*#*-Y5$<4@2sK_y)lLjWz#*-Y534JFc +zGod2Kgib0<6eg+0gff#-9g|WC6J#bMO))`cGE&5ZZen19jVDwDCdf=i0uw1S!NwCh +z2~3cgj07f9W}-HpC`{S_lO=@7*E%L&iT1ewVg5fi$JfeALAP!X6Q +zGZ_O+q|5{xPv|5tL1r=rm`It4+IXTcX#-4F5GKcUOpc3~&;@HuBFBVIDohk6sm6pd6PJ#OOTq-1$xu^FkeLh> +zF`=6nm|)`x6@dvdlcB&w%1p5FgiZnzWF|v_iIkbBjVB6|Ho(M6m_&3;A|fVq!N9~c +zGqC~_DKo*w6BjU%HlA342{IEZa!lx?fr+&7#0pH1nNX2qLMIg_3X@c0LYYa6j!BDz +z2{MxzrkEfznIU3AH!(25#uF+66J#bcfQgiuVB-m$1SZH#W&jf@Gf^8)6eewe$r{4s +zI~|knL`>*{fr)8mvIdw)nF%(Yv;Y%nFLGMO@yo;oHyMNBe~nRGD2gbo^+Ne2-Vx`~cS9X6g&kz+CinMntZ$y6~jIf0EQ +zbdqC2-^s{KI&e(ri}1|k3$^h?VbTVe%xPlXzp6clNw`+Tgf8fqOfk(&=5S1=ikZo` +z*m%;DV{%;Dcru4$G8vf(6*(q!QpY4BZ9JL7F`@5dWF}PPn9xauiNYk+m{4X?tYcCv +zVS>zLgefM-Oh$;9&`k_XuaF6Dxdw +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 +z42w3*jICbhA6CI4BdQ~Jg +zOlT5ii{87;kuc$@N;uaP6P~IZ&J{7Cn;4j2;|Udk2~Smi&IKl7sxk>1Pv|5t;i<~; +zTwo%mD$~`*6NO0|U~(s6^0bbLxbfuI@xa6^Rr!8AFcDLg3D|h@J}?nCo`l8&6P~IZ +zq9VtHP8yhq8&8_X0~4OA{6s~L37u4!C`?k_nb0K47QHihU&4f^D&c!fG2yAo;d?|( +z=q3gx*my!kV8T*1QcQR5HDsoKd +zq{2jDl4?w75@nv=nT!xI*@;x;Ix|d4kg8lKVnR1DFu}$XDsoJUk*ZwBG1(!dD%f~J +zCpjkcos3lFI*ti_5u_?=!WVTuVd6NiWi +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 +z>N<4m;-q~-$o6Wk<-c=&WNBR*)B3v(-M%-+C! +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 +z*&<>>pK0_iPWwEOEUXeYjxK$=eVeI +zcr3azY41{N>yj6_q?t|I5udifU-HKrYaBtC=o?SgN|Pv$0Ta{STP~oxi3=BS~@qj^m7H~Fzu8>>+NkA5o_I)v_BWJ*>fY7X4bkn-df^cTgD*2jn3p{jtLdfnG`5Y6eg+1WD;SbZ#-Em +zO`_}uCZ?UqZeSvHCYVH7227+$l-VepJvtIGKv@f=Gdgv_!O1e}88V(T +zqp6N(CPqL&%a&;B(MVyIk51=g(pjYG*pfWo>*kz!?&nWw7p-3^Y;bihU#RQ5tncz*7msm{T&(tQ9*C{4Y#L47g0}}(2-p9lQn5Y|1p3~h# +zX+li0P9{x=iEc8%n07Ef|%%TqBJ2UIGHrDm{<%<3`}x>31lXs +ziixbl1SgZ`teD_r(#&E4AEIG`H&LL7nBZj6jF{*q6TFEc>oCE|q!}^MO(yFNObkqV +zACoD7iMsLRIo(Z^28zkqtdmIt#RSfAGQpcDOA!;@O_Tm4! +zch97bVscZ~$)t{A0_Sux`48SR8AUPa(cLqtqnNC~$)t|OWE91O=ck{XVS=G0)M79nfNItP^6Pd+PG(8V3Gq&<^U$@#*>Whp2-V{N!H2a1;m7%O#XxS +zOm0I=boWeNKumBld4a{`HpE1C&*TNf1SgXhSWIp+FflO60Va@{{6fX#v~rnfx9x(M=}CJre_y9AGjEFi|(2WOVmTc2G>7 +z%Q~6tpqRipP9}KIWCmiQyJxb4V&cZhWCx4M48%lt&twP11pZ8IGTFgmGQ+^cz@+yv +zxd55T3Kf%Iu$Z`UGI=u_CUCAzCU3Hsz=vp<;5`#4QcRx1$>dFn2^4WM!FwjZU@?I| +zQ=3fQq?kYvCllkIiGfKDFu4veQ8%7sboWeNLQJwwCNCi-y2%9Znb;8%-93|+5EGnC +zUSct^BPP0gCNCi-IGMb}Vq!NiF)+yiCXktgRZPz5Fu}>>y{wqvWbz)134Dl#3Ene- +zB4UD*$$N;2ZZg4pCg*gR;AHY1VxpT&jC&>qCON=l24JFYJjv+pnKV*NGFc~+Mv4iX +z<79&OOjaN!x_ccd7zNh6EN3dBTr&!mxJ0)M79nKZJPtS~S!Fv$TXkeRquOu{TC +z1Sb7c++vH=O>#+aBIi|9pNWDp(lL8J-n$4>VuO_6S=QTyX@aZZ3C+; +z#kHhnNU~-UmtSlxkESgPf|kc)HT~M$O=Yg866@>LmdUZ230zaD_3LQbGB9WCd&6b=jLEw&rTfv|3U#Fs0LCY1f)=6z{ +zbFs@@Zao=ETb>MBhQ(UPa?K@O_P3(8^;MR;Yf0kE;z{9sTXA2a83t4h1$9pjh*mHuw4x*ZKXHZ@eYo6BTP8PY6Wmb44 +zcP(iioNS)RB}=>PJyF}>D!I6pa6^*ZByL){1{u1k()$-&R +zH-XzxN#2%JUcI!%EBw)YGHn?Ww0tj?uRy&al~*Sn@(DlUO*bm_o1~c;bC><65!+9z +zEkA?Lm>V}0DD``#`!ATg>;#P-P +z#+&|Sf08r}NH&e`O!V`SpMu{BQlsd3en(OTmTO8tC{^Bl_ +zj_?70Xq`vc*PaPXhzFJ^2kJV)iZ7&ig>F93S0d|nrq*qh3j96dY=`&;ADAqWb$e6m +zHcP90!kz7zfH@u*p{(285srI9alZh|P$Z&kO(}aM$+c1qWJd&J`o(Zna_ +zD$@3ju;33p>JeUT&m<g8L#4?F=Z%%dZ +zlAiMl=h`!gQSroeO5W(pu6&>5{b$DCyBoXvd4&&mCft8;j}BU@V)?_lf#h6m+7c$0 +zM{Ji@TX^!IOp@tRf9Q}$_ziEGs^m3FGd;pi@{&OQ-nC+E+_X@s|F`|`-RDAX{0TSX +zo)&WMWrz4f-js6xB(b79^LWJec(vsZWUWm8p7~eQMm&PM+OmagON0~Y+jgc_Zk5K8 +zIqzr4*%d?MrmK~e+uzTGd*)QSUN5p9l9)8eM(O3Nl` +zVJ3X-diqz2{H^=6j};E2`k$(frarvo^qgGI^gXQ +z6^B^B2WCs;z_!$Z21)Vsh>}Cxzz1$p)@|wt7x+R2Ug2naCNMM}xLR4ay(7HOA6o4Z +zV1bH6)-|No)k$$*kNA{BO!0yKin6mKT<8rI`h{!TGXYaPFhx=Jc7!*0LK}R7jSno9 +zh*FnQc1zvf9x>w(`|{4qBvP<7Rj^0e?h(B08Rw+9^LnLVb4R$s7pm|IQQkRRDcCI? +z^$P!L&p7+VoimkvTRXzD{h>EJ!moH|fkgK0P3_w(t@ZVYcR9o_dFM!p?Ax8%w?q2I +zFAQwYI4_So$0)1!bcA2@gkJOsYuYo;8{*D^%IaOxo!%a?)ghXB=RAq5-jQ0}D8X`w +z_Kb5}+_^}JZ|MlX>kGZ>6_V{4=is<=juPJ{J>~BampjA|@0=l#cw?$?lQh!TBbGYE +z!+c_hQdr*+-s=tR^$X+LGl?tXiSdeV)lf(HT2JU&pKwciCb2M{$Wx?xN$~cF35Pg^ +zPt2Bxv@InyNFAOY@%IkV#V2l3Hf-t$PxpnUdxc}|nZ(d|;%a5X_Kxst{*cWhyu>H+ +zC9+2Dpc8FbkqQBC;vm<lPb`&4 +zcU`J`x72UI;x2pN{`*4k*Q)Qyw1xhy8s+E+mv}-YKA{Tgj-X{yEPn#GttqE(jKSpF4I-<7K0Cfz@HahF~DYqaT`jOnI$Vn(d#qL$dc-Ro;xBpAT}4llCi=^*-@gC;a$65|`pXTTSAV(P0(JG58+=vz +z%k62X8^7F)Uv9biX-a-8?=!Aa)ZyHzuX2a +zq`%ytuKseH_%Zv-t=}vE{pI%fW%QTZum_o6ZZ%L>sTuJg^ULi4sH?x+hCWDtxxrVZ +z!i;>-_~mB&a?9B-w=d4P2M&KEmA6&uH+V^xy*OekuC~mN<=^<5_etL7RNgMBWZ;r6 +zyEkgPugdbnSpGsV}!?_#++Rh2GFYzi+GB|YI4 +z&Om*7&|-@#RanntFqh@Yt3tOH&?iti>>RUY0I*p#T9Gq +z%W-90_Wcpt{%Xs_TGE=IY#qUIm0kAb5!>==%XP8VDQ)h~VpnImH62M?+(Efd%sjfy +zJ)*=lqQY8QC0ErF^YEm3D%VidWxpb7^H<4^n0XM_P;UK8mHgvcV(yzXkKtC8blG2s +z+U}^5e-JZ|XmhWsbe$}+E{dk*Yl8A4G4tRy_sMeC$x`dL)pEaD(mXoZJcOH9(Ph6S +zV!NeUURX<-rzV^Gac`Ab1Cg}6E+`konkTfm-zs&zRcW14C0Epv=Ap^v$=v$lF8ke4 +z+gDZcQ?;bIf3kTTmn^aVKAM)N2W4BVc~qM_S?QWqWE~t$%a;e``(oSxZd!Sl{aD0y +ztXdvgOSrK~E|1$^VST7dzAMI!1*!oyBEiVhou2^SZZev-O{TC72FRJBNoT4$;Az3YGdXADwX@DRUhuvHrI1a&BEwXvpIJKrZQ^{JNa(%bM=Z;04#sJ2`iYgz{Nx>U<<>EGTS@q$C_ +z#|JKx$lR@|xqGB~kKk+11SZ7;*DG^3cZ65^LMy!jyVtHg6X+KY%v26+?Fi5HhYomz +z1AL%BA_w-S4s4dz`Fh0F4l&LLMoQ$s?$m)DlHwNzwPymC#{*-Ob$dF(`#hn2K4EQp +zCU8SMFi^R;CACNV+#xRE1M?)ZZbxceqg3b-_O@pN$GG?i{Za +zG)PB1!f$!!RHdM?BRty^n(Y&AZqGOu#+`Y}#hqO};@=$NWZpSjBKx+b_BBY~czVS5 +z9pW>*^Co5WrjGCgUuc3?IMSYR4vjmnR#tEC2*2nL-RTjUcxS#uRyU+p*GZrIdPL44 +zcJddOc6Ef8ctcD4!o2p3(-e13QQ~_$!cTcZPx%BZ?_4U8cwH*KTS|F*#I!@~&nGUE +zNa5C0;T~zPNAS025|iSI>y^UI9pPJjpk;pEh+pxEkrI)1r=%THhhG@no=IFDPmEDE?CA)<<_W## +z6CP^MByNZ&1}Yaft@MbpLtM%y=1FA3j?{)m=_ZfR*q%v@izgN--CH`sANWEac!hto +zXA*hK4pOK%;AHkJZS{H2D*CVR` +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

<_BQ!mtLsi7`Oev6NF)hKEkjt +zY$+6B7@lA$!Ge!44ESTTdOKnhzgM(jt0C!uHDI2l1nc<#VHib) +z(QV9_Gg;2y-A##Reu?4)KSbR3X`{4F%9)F1byFD{rS09@2wt4lZ_fJ7ITAXo2=TP< +zhoXt~mmifYaD#+lwi3cHdIw7h5`6qw35&I;(SMJG*34Se&>E63EDRg>I`*KAA_zk! +zc3LLdogfT51Qdq#V~3@vgkgAsr34E;wEae-h%gLqcvlHwSQr+DofMTY99kV1o#^B~ +zl2{GN`&Y_ULKqf?g<&Tk5r(<&(Vrq_!$*6=fSdM)*-GfqAG8sc62LJ&2X_<{arR_S +zv=fwu9a<_4!%8eAgkcmdO9>Wyl!n1kjKVNU2^M^mhS~7(?voOUeLH0eeug;4g`i^z +z5}J#r-9|n7g9xc7Fxg75_Lh_@zzNo(hL*5M-Bi15>_rW&Aqm66uyL3vuWyXbp)4ADR+QAZlvI#AdskW+`F&LR|eS +zE>EQe0^mPG`YKn-YKyMkwwj_$Upt;iEJRs|v$xC4^z%k)?z%3IccuuQV8KUe +zm<=CoO2EiU!)zr;@X@9OI|B;C!Z6^#Rzett(kvx}VJLtRio@IBshMbRg3>SqWGSId +z30Re-1Peae8wPYR+GC43-1%W%+?4PuRXj<^Un0KUr`^D~;XhKpIRkPmCA@eWfn$ex +zSfy(Ls4IdtM9rz(VkSSZmQ)S?8oY++GT^&S@02t0UeA` +z9Nvx+t#;lOh8|%d31JvT%ThuZ1|C^T*g~tRC_`~v9*lsJ(~licf(0L?VR()O +zAEjYbHw!*W!$2xVC=PFfB4(o92};8bErnrNiKT=vjG|>JAq<0lEG2|tD1Z@)!`q;U +znP_hU3qDH2xIrxVC=J8uEchr513DO?IK1s4e6%S60fk|<62dTwmZgL+3_P-w5Qd=u +zMko$%gCb_4y$QlF1Y{|}f{)TLoX&!e(lDTd5sG^WK1#!E_-IoCR(%ODTqf{fzmR8$ +zM+ddZockfX5mJTTFTGIjVf1oov%0Aa{Sq14`~}yLi)KCkO)G8X3P6FS1PMOM73dwp +zFk6Y2AXf;(QSXkh8WQV)7hxC;38M)^sB*Jnb#lw2n?Pzv!Z2M3@8la1_{G#C0OuL8U}PQ+GC43-1%YN +z`-yH@rTDRepCT^%Y{|%_Gb4N?>wycZz|avpyHNx%^|0@o+O&L*x6ZFz +zfg8k9Lb(E^z*2$*A6i55UN<%Fb#Q{Eg!OZ9M^QV5Qs@V+PGBiv`$Am(DlSj7rvwW= +zTHe8lEcoch4mh0!A7L2K!3f3SZDH6;N(jTS5=#kT7*=H|Aq)eLEG2|tD1Z@)!`q;U +znP_hU3qDH2xIrxVC=J8uEchr513DO?IK1s4eDvrK1QdqZN(jR!T9y*RF!0DyLKubu +z7@;`44T_kF_9h6!5Rjz=3qDH2a5@V%TT;mOo&lKSd$`znDO9^2Zm}e=$TGR-` +zfDXn8=rI54!Mm)6|kd=VOSUj +z9N0<-!%&)~gfI*RFhX&78$2}=?M+Y`hJY+3SW9uGVK|)yA8kqiIvAn2m*Ar`%!ZHB +zFsv#Jvy~8rfk&1S!Y~xT2*u%T@YGDSH-VJ_g<;$vVVJE13qDH2fDT4`Y%zyBKTJQ- +zIjTb#MjvA-Aq)${77nrCLu*JcJci5Mzfv~jA>y4uE0dvoeKnG(4beMnj;9XWj^5mKf5u*Bn +z&;M7qm0-a~X_yTkrD2#}7-lO$f{z}AXJpg +zN4son_$XJrG`YfDX{aZJVYU*iMU60whJ?}T?I;tjop+5lJU&x|Gq5tCFf0s5Fj^m_ +zVFLwW7}dd2B9iyQ#P{r_hlg8B0+%HWvz5@M1iK-zmg2N^0Si7fB}nkmrUV;4O2cgU +zXm1$NLKtQ%Aq+zSj8Gg^4xXBc_9iF|LqL`iO2e=!O9^2ZHP2Fl1RtegHhh$Z+3-;s +zX2VCD62LD;C=PFfB4(o939RiI+ZW>MS8;iwJtbHfP#A_)Ss73mhSOOYP#6YuFhX&7 +z`$fU4jcDM$7kz +z`rEnwu5ty~$WlVN0$qrugmML-z*52nP)ruVHR0}~<_@h8_B_;G^Xo?8kzSmUk$0 +z7JQV3fnSVJ9Nvx+t#;lOhK1pXu3|MLVHicrQbHI89$8A*LaQ)r9Pe_QV!=mgm<=DL +zVK#h}hJjR!P#oTN88hZgmNO^~JG2yrVI`IltPCg&qoi3GP#6Y&F+y=+*vm?=;G;AQ +zs|v$xC4^x>fu)2n32#;X2XZJ +zE?~ij){ul@D1Z^(L)gOBrkQAO0t-G$!?;1hFk1!$v!(w3qBw+(H+epoKmj~x(&rG%DuASO$RD9DVD#LW%o +zcpEQ0Jlxqw3B$s0ScnLD$$}3pVX+o9G$mN@p(#OvkCu0A_|Vn``g0TL-7F=9VN?f8 +z31JwmpQVJ;*crCybMK|`hI@xQJ4|Vq-H=}FT{iRe!~DsD4^0WBVN^FuiKuK6&N1%4 +z6owrQNf;J}wJG5QB&>$Sf{!qaJBiWiZTA~SC?_y_ex?X#5Qc?eVK_ob@Ye;xFg(Xn +z!r2`ScXQo)DGWOlVC{&~8j?08fO(b@tfjcpFrb6cO?EjyOc-`lhtjapFfbXa1ZycS +z3`1!ad}s~ng~o73-%goA9wNRFbSy!_$Eau1Lu6=k`&gwdL$gc!IZ+1O4(E6qFFicm +z*+(f?fI}=LSc@9kLYD;}ni5*xp}JX0kl>>yFxl|Y6PQ>u3Bzn9Sn#1WB&A_^f~ACM +zOz<9f7q--K?km4?AP&y>)kKM;_mg!YDERhAOMF!0DyLKubu7@;`44T_kF_9n34Lt7Up4dYg` +zlwd8zg<%veMo)`3Qq2p)j_S~+1VTDX2^M^44T+TjX-Wvgz#~fuVHgTvgyNAqivfx` +z#)Y{o_~<7(+@Kd4!vV8n#|(amI8)G(iuG?s3M;(Zs6R!FGS%{qt%Py~S_4Z7)}lta +z0zDj~X)9Pg*lG4r%{AVL@?YJ4SGfW=h^52}ohzbp6$?HzC0L6Zni9e=@W@iaeIQ0z +z5@GK~RWM=y>h?<(e6+lKDVBFpxk?yDYi23If)A}B8AZH6oCuy{Dd9d4BU~Pg5cX~q +zZ-x6;w_ggwO2cRvp-QmeqcjYqS@02t0YZ#W9NrG&shcmoccuszAPft`!f=F=2+KpP +zh9nHbb1WsC-O+G2*S(j*utNd;La>^BKB}|E1GP8SOBHUq76^zFx<^9*adh`bd&=Z(! +zC6p^b0+tda_;@8(z+Dkiw^1a@fA!#9k`mfw!|h`!Aq=AwSW2+qLt7Up4Z{;GC4^xp +zfDwut-i2)@yYrH@wKu^k3)00Kza^31L_m +zwh+@O0`EN!tx(UExx%nRY1UF)d&96QYbj1^NWw5c!cu|-AEjZWV2q{;vGwTLQe0^m +z0xAu&m0-b#){wL}3{S9>FpUY`GraSVbF7AB6!F@XhJqZUmz7W&MxSIUp)`zAU@5_Z +z53M1w;6qb_1Rp&q!G@1ECD`!s!nz=_Z>LPb&k)DB5Ogd-LUYCNM#uur+kM}x3Q48S +z>ZUUEOJL|QcZGkcTL}_;l!ifXVVJFiHYL~%Nf;J}Eseq`0`H;9trP7|uzZf)!*Qdmmn972 +z2C| +zVK|)yAEjYH2O|`Rw>^Z9_J$##Fw9m$7)H^uln{o2N0t)8FciQD#o=vG#7wj|K^TUB +zEG1a*Q5uHRS@2OB26Qk&aWBC~X_yTkZA!qZFD{0g_$7)H{19>9r;XA!+3e)MH1>Y! +zg?bO8mrI+~O=aj8-_TC1#CrUjR@%xHxRWd;NbpgvP_6(b*-E^)xdO#&Q9>AoCs<0b +zo;wtV;c1LkZ@aq-#$MhC{0ZqZ6INC}sC0t0CFG5Q6~&+^D~b%M+tM +z+}XRrurMqPJE;y~SQxfc2NZGQnCK|(Y=ST>3=6|fszVqShAq_rMVvTB7&bhOW?A7( +zDpo_%-Y_uFQiAovlrW5cheU#a3rLjDr*?LO@W#)S+PHnR4XXr(Pf +z<4&@acwr5VZe(reMiGm*BTckBfusbhn`(In11MLpm0-b#){t0xOEe`&@bNrX2*W6@ +z|5%A2YvYUdLR_4{YDmH`oWfE<7)HutDIp9)0gO-_-gZVo7bmdbqcn^g#DWj4A!$b_l3V3HXPl1Pea2 +zhNLtMPq36=!ABTIL&E4`mw*w%76DPb74Bc%e#wH5_J$D%gkiQ4tPCg&13DPp#*8_W +zO@c(KWE)#gLU&u4Wql4OH&ixQFSPRCcpR9))21h!- +z4DC=ryKFEGO9|GZhL*6DE8q#15+wNO2~1#Kxq_{PmUmj-0h6IhuogAKFqFm!#Z8sF +zo_j6#Ec6T*qyAU7-xY?1VPG;;38i7S62dS%$5O(5AV$M!hH)n`TD|QtJcVJ00<0ZTT0_#N1TfE1g0&+m3}q#2^M^44M}Mjp72nKWtHN`3Vw>X?6V~!m(FyC +zKIIBPj-`Z$w-J{Yxrwn#`#B#8TA?r4Ypg6KoO#>k!A7L0uV}#}q#31Jv`WGNvGLjjCX9Nq>+%tU(=SnyFA#tmY@M`;*NXTe8l +z7|_88#o=ua;iCuPA)qkKRzes?(Xx~fhJi4w_4qeU3060y +zDWTt-VLz4RbiN|gfI*|vXl^pp#VlG4sU~}W}>|btPCg&;|2-C +zY$aImQ5ptxFxq2_Io$bS9z7{h=KhtkArBGn3|g5q)m^7gZ?GPCp_R4_4acyQcrgwA +zoPsfm0Hz-Hee+QyC6p_0gIG!^SD+MFO0eKVYe*h-Q$qx>7xJFg6PPAiL?uqxzk2Xe +z7W-B2K1B5IkgkdOv5sJgx&u!#d1Ou?(qcqHhk2WR1EEar(Vc-`d6o2q(ePMGkl>><%!ZHBFdIIeZAvVy6hBt*L&RmD +zEg8A=%yTk=DRF!sIOjRXxHOkk+N^FWL&E^9Zt9t#&E-Y*r*_#O3QGyrqDHv__{I1f +zo4ZG3;|=!?cXpUC3=XlB5QfDCIkNk^l>2F*H +zvW4YR)^mrn(w3qBCk-9WvXNdIMF7*tHji|SOLIvHi?ygxu7ClQE7(d1!(a+a2@-s? +zyhC>ohS^F8!@@8y8L9;9msVjIN@IlLrpm(>eeS*V-kBm?fG{i!1CyajXj6i%gfI-x +zv6P4iIZxRej+n+9-aIMq5AbSJ0&r6rW-Gy3iqjer3qCX@Nbu371Umx?!)*BI(H|rd +zVVJFiFboASLUB|%cxoovo1jez2*^@GX&6>zDIpA_=2=RR;G;CmhL6%P8$L?IZ1`wX +z0{F!U#o=vG#7wk1fwetj`$Am(DlSj7rvxhl3d67}D+79h;f(jMlnr@?cxTYcq^X`h +zuZ(Q^$@PMip&bh7|926lVJV^CoY7=hO0c@AmUqA}M$=Y2PC%h&z-X$_e56MorCfm< +z#8To#%oX^~QKkSEd}vCr_LgW$2*Y3&O9^jd(iDm?>`;J}0fk|}Sr}$3!GaI1AsI!& +zc;uazEG4{jc`!oQ*N)?hdnpV%6kzQw(HfE-{Q>4#O0bsV!Z4tN(M@(aKTH^QREN^A +z(l9U?sst+o3d2yE1s_^N5{97wM(3RcWn?RD3&X;&FzlpeSPe-ShUZvHIJ={^*l5@r +z?lAW#8`YV@os_o}*MAlYxUrVvwCx!dd}vB&QvxN;Qi22@{b!-<3@8i>!+--@2^M^4 +z4T+TjX-WvgPynOV+u*60Xm5fxB_JS6i5D;p|CS+rf{?#N{K&t^mj2Io%=7=%AQmdR +zZbKQ`p@4pKhG|$zXnBY7WGSIs0T8m35Qd=uMko$%gCb_4y$LM%{4eE-=idqzd}s+v +z%R3YmONnS4<94&c +zI8%hV!Y~SvrGzldZb+;QC=3HS7$cy={Hq7=vKo>n*JOwg)fasJzq+ji3qDH2Z1~W& +zXIL4K){ul@ls`)e5`6UN4?6=2!@@A&z*d3IccuuQV8KUem<=CoO2EiU!)zr;@bO?%BBO7o +zOd$^uUkEyuAmL+VDT7NW5?qDaWkVNYDZ%Qdw9+<;MC};&-(@Kg!O-qs9*hunhA7?& +z_pffhRIUJ$SW0Ml$4*$v6)1m}5+wL|kSokXKE_?BJAq)eLEG2|tD1Z@) +z!`q;UnP_i%*VYU*&F!0DyLKubu +z7@;`44W62b_9n10pfHRZ^x|PSV0P@7!4DB<3OZ7;{!Kml<6`aDtSnaxQhx&zQn8d^ +zJ^oEAZB{p>DZzT+g{B0ln`(K7IHFv^R^r9W710!xFbq$yln{oIx>-t)GN3=JAqm66 +zFczYrO0eKVYe-7NSRt{LFpUW-v1s-Ltd??mm@w>+N*ES~Ekz{^!xJneSnv^s(U34& +zz3sFg;Fd=>!R3k3o+-ivVOSUzh9i_j*rtsz99kV1o#+%!GMg`14axgg%2h%b7KVjk +zC-e}8x$x0XbZq$O(I3D~Khd$3VC{$s!@{t2TLX$XY1}p!1H!O@1C(a13xr`|*ixRX +zr8uo2h4I3W+47Z48QGiQt`g1s62%FAh`8_5MroUri{{f=iyB&KD_6i>EG43Gj7=AZ +zGrzlr1|!jptYu^riEg6Z3E?l^>8IO0>A$pYs^uLFpj^RLf(0L1Lt?>)ri3?%6M>j4 +zC4^xpfYDT;v(9C20_(rRp*197SQxhCMHYO7VJMB!c+WfV(Sz{lqQWp+32jQCXjw`K +z!@wg;31JutV1(lEHYj2y+M6H@LqL`iEcnpY1=^H=Cs;~&t9T>TyfEybAM2M^?G3|o +z+LT}`!GaI1A+g{?Q$iSq0vOTw;B5~#J%nKh$WlTWhE-Wg2*ZE^O9>Ku^dLMNK1#!E +z_-Ipt4Iiap;1?qlhqplyGtuq@*1Ev>=wYMY;13DP(vBezj{4iESdd^3hf_LHaBF~NDE$81Z^5M?r +zvf!iT9UDHhbpa~_(i)O5jOu17VFM`k;3f<^I3Wxx4WnU%Dj^KBm0-a~7)C?FX!W+u +zE&(Hi9Tvq~;r`X_m%^|xEDSp-A67#WhT%Du63*^u7*E}NDGWOl&`)%*5=#jde6%US +zhL6%P=!y}Fo3LeX&m{6;QM_de(tNu8PgNRL8n*aH7=|ZUO0Y7ZFbpPQw0c_@hPORb +zf|UVj4M|T*0P`#*SU*e&!zfyeo))jcBs}3>L+TTFuwTeS#G`}SWX^rXT&9!DV|7y* +z+Oyke4tL%fSf%}(kBn?m=a(0Gu6u@#UI}O3_OP4kkFP;MQi25^VHo(u +z7zO!pb5Ta-7?`*{y7*1g+Aq=B6vy@=Lht`mcBJiHQ254Ai+m}e2u*n7lzsJQ5t5$M`;-N#R$dWZBWEav^zm**rBD;Fs#HzRxq4%|EcNXtZf-j<=YyhG_JSNumxu)3*o1?Y#-dPk$9Y_t=EVTS^&2VQ6miM6*x +zQ$ou-c0&?|fk&1S(epG~;6^>cc*A3$M>vDhu+s2*znOV +z8{noi%vOR0AKJQrl>uo=2*XeSBN`vP4W62b_9iF|LqL`i!Z57LQbHI;&9jss!AEJB +z4IiapHhi=<%!ZHBFz|~Jio@HWh?!`20&87h`$Am(DlSj7rvxhl3d67}D+3C{a5^gk +z3d4X7Mko$%3&UPgLKudXSV{=PuqsOlVHkL1De+=q*soOaBq4u^_;#Om1LNYm!)2&v +z(?e+8RECD=tVPZLh@m4}Hk^AMFHMO%w|S&vT$)QNZB{qc@(u=IbyF?xP)V$AN^3~M +zFsg&4gz*Nd&;@k6G*=jQD4+-7(Z*Ry=s|cCElUX&d}s~HC<5=9|M15pb~!(crNnbS +z5;xbquj1k1&OTLX7=4nZgwimImZgN!FshrS1PMNR^oI=}ZA!4=qcqHhkJ2#kixG;$ +z+n|V<}mM_DS{`2VPP1U3{^sV!)zsl +zVR(+EL`29Lh(r6YZT}X;^6(nAE1kf20Hp +zKD35Jf{%MY(JiYKKUVNl#ATl?8M$<(3%p}3YLqKbFfue-2^VbcUc?}kwsM7X#edXI +zg<&Wy46~IGhM@pPC~kP?*+N&lY!Hy8gwimq%2GlY1{7FIkl^F5G^`&xklV>hu;8OK +z%!beZ#x9$+4ovWayuAMkM;Kd>ZyHYF_8!ODQbFqCG&=YIjiW$s_k +zUVibq7-t@SUF789Z|g3s_S3cu*%qu^dF|=R>D4|-J}cMX<(3Zqw2JSCEiY9olDuWh +zRRz}-xRx{1;!=gP^sn`C?sozPG%hdn5=Z))sH_L)6n?FcgtK8MOGdG^zzxR68 +zDa~{4YVqXqoqk7)KJoqf!G@zZ_HX>4_tXB*uK2n1zsIx7aR2v@YuDl8qGyZ{X4@q0G^cgOJz>8?Mh +zSLMle|FYY*e|ElA_eQhRY#etzZ~A}ot*m-}M!T;9a(CWcX-efgJ7+ff^v%WNKArxg +z#D+p2uWoqkcIv_x&J~`UG11)P8B@N$=E0eN%9JR$an70>zwiI7R*vSqTb#eV_SXD; +zyE_Gxdh>Lzvl|!rPg`HOYolL3@Am7zCsUvDJ-+>6olD0rJuMJBV14 +zPERh3=z6hzhLO`>o$8aUdbLrHYCmo@=fHt7JsY=f-Se{(sdsdpdwkEvNu}ydx;uK$ +z_pRO<*lq8rd?(gspHZw_I=|yBd*2?}Y{`j@U5jNn{n;Bo&#T$%!tC*Drfh$`;i7pp +za}{~8dQ6LTpPgQHsL=Ocyiu)g_h+kzl=-Gb&&nMdr90iP>aWKR6)HWp^t0lN??3tc +zP@fECe0}rRjT`!nwv4J#_vn+g2U851KPp}6G1F%y+0nJt@GXZH&1(|wTVF^q=ycZE +zhYCIG((KD?ZCea~Ki%o3!?(mu`0=78r3-x6H)iPFU3$KD-N&cXRIAzT+T{2d +zcUG@C^n8gz70$M<_htwvY1n@FmiRLgo-KNH)%WXfFI+x3=c^rhj>!3H#@*Mi +zzh2LG`i^?Xr#D}B_|G+e?H$lXC3}KqY`77_@5hIyHXh9~uG*ElWgBG9)URxhZ8;Jw7@DcV +zxNK{Vo*X#7dC|c3t!m9}uz6;utLbAVO`0=J!WGOP@D=rhVd@t;FtrJ=Ygnl|8Unk;9*L?D*$L9SU?9 +zR$y0$VatZSvhbB*CyVWx86#1muBmSvY}>3_!7p2E{c>KG7Fh~cu2SunZQEOHFSP5! +zogeM`sCtp2!>Wy}yfVwAX5XG_`%afj>GqU)yd>{W>k9Wg`r`)wdky*U?F+czv{fmdGHRbX{)pDOqAJ^E$N&H`1J->&fC&GZ3ZfAC?^%s#u{ +z>d+-`uchbj>}hfOhu?q6602X?Oi2>NiDDRcd}Hpf7S^A2^PlrAZ)~rcV#2A7Szj$W +zrP!beIifxw_$)J@UY?MnWS5FHi!6K4<>as5PaZlUN8b&Tvc6jQ){&CC2FD%K_Qa2W +z<$N|FL)itFcgO8sd;ZfE-wZ6;xk`g^Q{O+C{$_*EOMkfRmjjuH$^Iv=Pl^*bDa(gdHYFRls?XF78Jf&UTWGD%tCzYp +zJQri&?7n|=e>Y`?dmC~zU7NY!wbFZimJM9ix6$(9<%W;!)qCcjt7cD%9k{9A*h7U< +z+_?AFgk;Uj=UlYnY|8F4pJX`sqdLbXL*ySrz< +z-a6Nc6GNTdhy-yiuF6;RSdIxfdj4_lO!@WYo1DMaaMm}o->lhcSQPgSH*L=h%?*l;8oDT5wh?kfC+9gjZ|LDfJ{4E(Yu@Fxj>X$%yZ%+jqk9i0xHNkDwRDYJCzzXK +z?C};|8a#fZTFq>q;2Oh|A!4b#&~OR_4B(LEoxW1`&j>Rm5Sy3>tu`>en)@G +z{$$#d<7Zn9xH;g)rbN3MJ-s&M`}R3LJryI(j`_FhF^K{x&!lC5dHrOgIs+M1+) +z+cT?s6!+`a?Nre>D{hV1rP#Tu?|&VzuG0SUx2L?b=8v`vFNxeLEq_2K#UU+-Vmy+XsI +zpSNu`zs=}{(~maU-?US)>OYklyK;Bg(qE)Gp8S5g38jaAxxaG3ZQHhH-JWGf*6rD{ +z&B>Of%jGNsV!ij?iQMa|`j>2&w#}5B1vBR@n6*IWwUukN9+Rg?k%IFoSA4%kl@=X; +zSzEbn>yLiSx;b65fq?}R`AzS>Bh7{q@iU%(SgFsw)ECDd+R>`>>UcLkxmNYU&kKg+ +z9lN1cz~x?5dl#GfZK7NO18R`$Ub0T$cV)8~=SOzV*K}0LVZUXn-hNO~pRDOuCa!R@@rDFfc1*kc(WJH;%BNbCJjuiH +zQ&P@Z(Q?L)3w6@_72A|Iex17Cj2qJTn{{>m%9COGw#;c7wm6Vt@BJ%_##D&YyLQW4 +zJxd*WCvVT>x9`kEt`1mMy*x_(mCxw33j(@^xEZV`zGf2Yf-c7{U+w<`)`pvHP;;MS!zXj=Lf~P +zSY~zkA8zj`w>#eb-aUL4b~i?j_3YTWHFdA{c>42ueG{B6vGdP+9}ORIciuk>zpYhk +zfp5&x`y2Himm%=ZgdMxLrWrV+YtrrcN-iHdPD_{!*{a +z{YQVk`rC}((xpy(wccyFKmO{kT%{}2Og}d9owAG9*K8dtTTI`|f5&?|INhawe;s>t +z*Kbm@ooAcIYSMZ3f>9Yql)Zm==*q@p{Hne&^vI0_iJO1)v+tb(@dGXnnDffO^qDJk +zZtF8J{<}B-IeVkYm?D*`bZNEe>-7nmUp)GxWs_02l2sa-Edty&% +zUgUJ;EIr=rv1!Tnni+PstbL{%n{92?bSOon8Y8%!^| +z>FZGm=JdKhX7i+Gqqa5~7rV*jQL~C?NZK#(@i%)aO}a3&e6o4T6FjVt;e5Zp3hXU8 +zu-K+i#kO258&GV~f>FhGbjx%naD3tUUymwZt9te%Hyh@Ob@k!ji?i%q_PBn5!dn(+ +z9sYN>%5jo)f9FE#k2+qhzpHher&Ipj9lKbApL=!R8?(#ang{1sjCU(d%pGU_ZeH3~WNB3QpYLyP-x}5~K788wqfSLycJ}YnZ1(G&Q+`^vs*{+PAWr{| +z$Lk%sUu@gN96i4|J?DdN!(s(|{b#a4X{$Z0P&Gy5?t+-|@iU*QDYk5RefN&Qe_MAx +zaCTU$VX*>6G??}A>wTuT>2fq(hIRKonHzL__4OF%K6~@an=Q5nJo>}0-j?pyM<@OJ +z*}^BWN{`AGZ`YwS)W(glW`F>u!uWR|08}i`p<`j*0 +zr0DU=yiNI*=S+NlrBAMBThdMLpLx#1{1b-dPt`R;s(v{qR8G;ON#E0NCf&Y!>8KI; +zcf7ed>73*h_tanVXixV3;{sX@_#<_qD%(m|${#nNK-~3B<5XzY`D~S}bH{9Z>&qf{ +z3Zz)jDZ~B#aoQ&?zar7LTHm+&w^fs`&!;%_Ps^l%qgFmRy!o{ +zw9gN(qzbJ6PWc~?B`W#pH@<^5bey?r-L|i{q*(G{iXU~ +z(Bk;4fJ!3@R=Tw^#e#v2me(ttaOS=#sYVsb60ghpPjmWI{J2Th1I;rA9Q`{@^UiZ7 +z_gpiw#fVb-{`$RHmoJZ&Y~i$u`ToecEE` +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 +zvi3`V`udqvbzVLB?(KQsTF~ +znAmJdjvsn0Su=Cls3vi*Eu8(~wpim^pRLpT{6Fum>EV-m`Nv~&W5>v8rMo+a9;88Xh#>@&96E+L +zpYi*??>^_Z&u{NPso{Q}`(Eq5)^%NLNkruj#jT-+z-#R8$b?(WM;+~yo*i71VUx4^ +zKaGu$!r9}R63m97roGU-9*8vR;fA5YGA2y+B|0RHusgidCb*`4gPw90xjpol+oxYX +zYE(YxZU-Ot#EYya@oPQH5f9Hdp`$LpY%y_I@O|W1xg9F*+qNSvP^P^j=c{b-T_JO? +zuHt(N**T?LroLB~jhRxn+PS4-mRQnx0_K}}+{Tw467WVz;-^8mkR}IR5v-S%9@bwz +z3k(YoEm&IkTOs34$dNaP4KceboHc!#iWs!~R;l{Dl +zBj!K5-`(DlJ=k=-dUL&NM15e?krgj^9Y+iWE-5b62`-+nQY&;{S2xSsF3@yzqs_0q +zRuvoJt}4I_G_*N!Qar7`DR>2$GltTJXqPM}YMZv8wPSGEoJqS^YZw*-;(+W1+y~R|NweQZ#Q=_h<(;@sgK3_oB#Hu*qxS?nxCu_;-%tEV +zxBP7iiwd^KCsLBk8110yA5sf?_SBydXEw2eN?gH(Z+y!v?uG7n#txd7n(JjZCsN{0R2;+MR&Th*ARgsz4RPaYV{&ElMQPO67?pYDta(391Un#Jv%`93v69G=!C +z`pfh?8#1i4RA|55_W$Bq`2l*!r5I5PSbGBTcQh;j?0syVt;PfeCOI{23xoQ(8q+7j +zZ`EX*qwzx=xc$e;`qrsh?-0or2x(_R{o0$j)%Z1mdJ<||9r?B)11Y4#DsAKo^w +z!Z&3FsNfxa=8j9dXw*SsGWHzk&9e_S|SOO?r8v8^N%O +zgSq&C9GH^^aO|XfKpQhmH$I|Yfxa}*BGg%4x-B79H0(#W8Q}U!Bo*QHYSU*tqrCkF +zzTdQeX&n7dQdg|`%0TT|uGe29<3A3FG4Ps%4;ZMk(8EodK0jtok*8rW^?`A^Sm0os +zxETA4#Ic98RuRdKulJc#urxRzOFid^j|2D_9Tsvg_}PQ+LH#$|30ew2q>(&lmH3T_ +zFwVaVx&Nk|XgLMpPq?by5QkMkZnFmeT@U^S;}kLB{`X)1cWKD_*v5n#*G!!fcMx!i +z6)L1Dr%KvmK1LiCeQp1hVB6r{UMolypKgGLx^*h{X>3@iGat+FqoP#qK +zu5rY(zRAp~L(<8PO=qcdkJ0>Xyzg~;q?3M)C)nASGv%{^flK%5;IbB!Et1;(UyPSCD-ywUMuA)@6X)?<% +zq=+7qgv|u0JT@@@_9dgNZkdCNtYf|4;N0%#sgg#R5w6eRV-|2^4z2IRj2aWQH +zXHmf(@A->S#fsZaSO9S9N%N|u-Rtgzzyy&YRe*3AMP;Jh?C3{bJ;<>f-3v&uK`$ec +zHH-rG)C?KZMuHq0DAUmn(hE8P*cIgRo(Ha9vD}VEz#3{Zvh-!&NwBZSi9%NH=XSGs +zA%LiYasalNWb~eo9D4mgyS}WO9R0MaI9g!ht`D75JouV*2SseBlpCuL8kH})leHDX +zC{)#qo%~CQQ2@!S&C!36ch@}V1ynG_XSmT-cCnXlF%ds! +z9y)4ZhdiCJBUV;FpktE!r-DPZU-X{QJ}SYl9($~xuW%MsXB2vBt}t?{|J=uJRWQS$ +z)I_Xix-z;ZR`nu+yg$80X9UKVTeEzwB-Qc6fEa!uMavKnIjXg!g;=7m%ED*%+AT$@f1*bxXjiTG6|1 +zxxA$-(AO;{Tnn(eDyb8H6Bd{Df8OhVNTGkf`ZqU|T-ruwq?(7W?>B?p|NX|^BtK)= +zHz>J;x4=hv)C)B!qNRM3S*3)RiA0uME*cj6r2VU(9VJ52Ug!+6;(CIJ-O+=FRaF<-B3q_V(rW*(zpk*baojOQs#MdSjU0#1A)I8MAI~-1X +zg}2BXXa11@ULh!KR982da|h0_#;-+-cyld7ftT8+#;oG^4}lS0^nX{OwpLw!IE2nP +zz9R7WQ1l08mFSeDB$6%NTNB*%wtiAm%FTy!hm{aeUPI*Clc=r<&)6U5Wewl;p|~$+ +zK7=4?SW8jMVBr3)4+X&j@C0?omP=R$HG(%H>?9w1%W;3=NBX9Glnl=^I3lU*`%90; +zgXN@H;U3yg_+lw@THj4wu@@!))Ax#%c$Z1Gp)dwnpXUeE5AUSLP9oQ}nkrQEr;-dq +z-simWeUI(z`P1M$x*y4^&J`N$#uawz6m&>#Y=M0cI>PvY8S^~++ +zW&Og>gR|(vYILm6A;@;q>GF^h2x?XJ=`*}`#H>SUziovZm +z4S%}&5w+5W&B@e2F{A9u=1g$lBMb5wn+J6Czq9ll;bzYuiIgWF?EZlDV+8fQ7FEwbcx$U@M&gw;1lPkt +z#mC}WAa3H?W~cJ3+?mTeiQG4X2I1cJ_Rh!64iGeRxmos;9BPd;>I@4id+|T=asO!CRg)$V +zhil5=h+HepMRx}WKxT60hv=9n)mY_t)mU{kC3U5}31v(S7uLP9!fyk%>;gTuBiL!W +z5s-;a>$rnZdqRJ;^%ny7Tre7;x2sjXRr-h?r!{k{@oCK5AD?!OY>t&L1FvDPpKfWf +z5FUKQA{-G@JaM#-dhPH0g_))^6sN{>;A!vL(kCxn0;y0$l?8zSsiXGWXVM#<@SJsb +z%;|AG@Cz~6_k+NY1c!|GH6NeHwDwfr#u4T|pIzpOqmS`P94D=gtGPWr%PLgO%=Y$l4AbzRA-@74I@%AW)pt9e8BBU%#X#{$7iJJ)-8r#i{$L-USrx%_LNgv(4!;;?4#F~+>R-=)xgmGGau$g +z%a%)OXXjH(AZ|oQc55^hm)bM7=jPEr)!?mM7g7Oa#;RUqgXG!rZ1OgV#o-&T_wU#7 +z#r@Bhep`0MkzQ!k1cVCR5C9RLzOO%GS`a9x2hI_r-6^6UC*!jQ34asnrSyLB@lz(j +zV%|;Z@_br`1!d#?i-S2@jgqs;gnmGf5&-k0M}q&>(9y#$z0dt+F?g1}dSMx{+ +zuIJK6wnP#e|DYnl-m8%l;gwE?%`rW_M_OH9aZN6j{m?c)B~we$lVI3pS!YwD!=<0~ +z%G(}u+$OSXDGJ_$t}@nKVrW-4pozpjml(R&Tqg=$_nzc8C$F39?|+50$g7xSN-kgW +zIsev1ed|QcA2en+mdfPHv_F6rc&xGIS$7HXn{zb_rdhy9>7Rb2zR|UnI#Dii(!Noc+0UAd*NY(br)bE#S<^9(}ylqk2 +z_CHxu59fm|I(3&K$_Nb_M|g)fCTL_*5@zV`td6XHLUJK8Be4pV7_8;iFiP<+I`OGA +zyvo3+U$jVZJr(;GOoU_7B3_?Z5lw_}p7{CPi8s;k0=Ol*ml3SWc!floWzMJ4<}aq4 +zVs^@}ioX`*1F*#yNatLCXNrF@NDOKoV3cJ_QV|UahLzBNVHlc|cm*kOCUdu4{8m;P +zU-aQrI*`)onj$&4i!lQ84m$BGWF>pGm~Y3H!&UA_NG-?bd{GU;kh|`-8x^(JZ|Loi +z!ucU-NaJInA!dbfWxj0bp5sN%?&gm-nL(+&0LTYBa(T+Tswx%z*(S}n4`*6| +zqI}lW#ZSbFr#pUz0>MlEH%b>o3Fdu(`w#YM5~&NuChxhN9G_PP_-UfIPu`r6a-QZe +z>bzmmf>#Jc@Vxocb(8G;3TqLqx+>amwn?*V2mVT@eKs?U&2Jp1vsncX?QSRf6|*0v +z`W)av1Ujg^@z5W9p{OWN!6Exh(>l65BPJ(GHIrd;t4fXemflzuwEnsvoQlLCzZeObEG9W`&F_`Z56)281A+} +z%}f{|lwfGHHVHHsq=zZf<83$Ti)*;3=1eXa;Q4p>G8UtV6-S<%nLOv5H#o6O)j2Pd +zW}+A~*Q}c~)2K1Y2_No_KXdO@Vk1>o(zE1|Is?SXTvy+{%57Os_T|WG#R#RDWG;I$(m +zG(j(iGP+4f397}-Q{ArBP2ZSyY1)Kg4@_+2_-z{soFT3baGjgYMl#l{nD-SC--CEY +zLepFhSFQKkkkl3M$dbkpZZd9uXu*A2V1SWs-83*wiw7BfuCWH+DJrElC4S=h=ve59xcE%(6i*&WTo?X-0Oh0lozRs +z1AKUJ?I&WA>{?DekJGH+BE#h~G6**up@pCCqAk*|;h@=c8;*}Lt8LK=|pMV|dzf?jwK$h{2#EPE) +z*kVkib9F0jw8QZk6R*@zFOvXx@cqUttoq#<-PBi#CEJ7Q&(f=+_k@knPshr_70a+g%B>rfNESPbWSqns<3Ih#}~uI{cWA1 +zBMHmxB9-jQnz+_F$rf4NKdR6UZ{%K@@G3s04x(Fm!=s+Ktk9u;BVR6g&Ag=5C*59awy%FKViFKuwuI+79E(0)n0WT79=1P+0sPs7e{&bwR0Sc3(Va% +zYvz6po5wF29qnJ2lc(XzC9~|DvtRR3bA6jX)iD?hJZIpW*4;#hC%i3qG1jyS990V1YY7)5wDLBcMOf0$JYl;mG=pSRfZVr +z<)#Fb>Rb)m58`$|doO5aw*gg?87| +zKYyxMesK&x@!9W82y +zXQHn^zP!sAVQ`~mYjq?^)Ckz^c$%@CD@SxlZO1BCPUFm~Qzu=78`PHut3)XBC!MCaQs5v%aSf^y8;s5c3yAgEj1CB2 +zewlh6?y9}t4DzBT!deW-d92y+D*@;J$ySb;q0BVAq{*b7yLaV{KdU6X4{^*L*$80m +zR1g!4U^ihHIlhh^znQw+!Joj`4f6HK@f|NXTcnWcKeHm&#-PYe^DvQ@D79aJ58V&U +zVI(jYpy7LoYlZbP9Odwsk5Xse_kNCV%?qX>(Az$0BXWE^dt2T02lhdrPH?eKFy$o5 +za}r^S2*Hw)3UBI-Z&Ka24Fx7#wOv*Rg-ao2>!v(Y<8$8c;wH9fIcKMgl@ca1)%gW@ +zfl}Cqpq5x*L{o2kgxu8RAB;&o`L;{ZYBPINS%P^?u_N6Jq^>@(f4vtiZ+{eo=I-%T +z`1ab&>?JfU--%aVuF?G%D#p7^8Z}-`LUc`I#*&l%c;h5yN^JpYda@l&Pj!5L=vUq4 +zWYbH9RCo#q8K7&OIrapUX5K9SU=H)PS}og%60Y1&P2|-Coo>C6%`l$EG|t6y%=tAQ +zJJ}ne*3OvIRcbj7;nq_WYtxB10+ +zArey=%mRdPYQrA1KYz;KK>%Bf@f0Fo#@_hLpa8&xA^swTYSwC}@^5}{e_J;^VUT>O +z)iM`Ol#X`bQ)zB&BSY7)ILqQddOx5jJ{6V|rC&Epk`%c{Lwh$LG*IITc|7_SS>tNK +z6K7~uHM91U`|07ts0rr~G)-z|0`>Rm&mNu=>*|2_yVRpdNe50HJ}@_EMmrKJxdWws +z>*-HzA4)?2w*PG#3KNq7X&xBb*IkMw38tI`KE7-Oy3EB5L4%Z_eh9okb;%8=c9U3U +zo#0~V7r|Iebt{?4j^@w+g8SrSnrwbNk^>(XKOw3tg=kBX<)~;Km`UO&2K&;C=C!ow +zZCCmSBik~@LM606Mr(q-Ri`E5^W}BnV5BonekyJN_nn#KHdf(-P0pNAX$+&DrYIea +zTn!*|TS|*k5QF1I4{8$h472zpWvzYAa19&PMgOWA;^$}S +zP$pPg2;y#>Vt`Ur%~&e(is>-(8vc+sCL$5X>Qy`1kGRdedAannGu!)POW6dxyZjg~ +zskVJEEUZy0gYb2H&=%=j%@~Jn1PGiA)6|mU9mfRvc{X5PMV?5BH?|CzBBmq__!@b7 +z6XrcIFBj^I@@dDEGj9f6mU=Y3~&g_iCOntJfi4}5$w*#+uf +zHQqxfMRu9ax2FPIV{+jaKH(1=wC*pF>`Ol%z8vke8VkX1|E#u&o>28h;>5ct7l +zz}a)pfhGi*MgDG-N?x|};RW|RrWoy_wDWs92Zj;y&zC(MkbSGerzVXO1#d*5>kGCV +zKuj2$r;QL2Ht@bR#{|x{lg`2FQX%f!yMG9*xg!Py6j*5C%eATAl&Q|Zs6GHSWBiC@ +z!s^+zvrx}TH1@motAyDeMnlFVcF~Yv;Hcx>_mu_E48OltPdou`3eBt0D#?1-P?I&- +zTk7xXvPGfmSBX>AEr&k{EAJBv@wRO&$p)4g9n82ekW0x@eaQ3EsO>3C+%JFwjyz6!VBa(0p>bobVc +zk&AyRrk*q(WVC=Vt|G~LFJPodLT=_mYy#%u$#n4RZvJ0S4}n+59pv`As!+c)O!zW$ +zBY1DN4r6|e*-lmj_1n!Qo@i-{m|P1WqmebZkkZ0iT-BNl +z`SqU27JQ5dh?3`4rJwUa#Q?|F_%Ov)+@|fIgwPP^S;8YrddUNrPD69JTdR6aBi+ML03An2rFbK7PgbqTH$Kl?-&dUFmfaPCH3!Ef| +z>T_i6#WmRk&|Kg6P(TA)rf6Zz4$qOts;3tP^RcylUZ_*MDfZy*^*m;WcuvwhFe2(= +z;kQ!_*Yi@j?Cy=w*)(7`(0$%JN$%Mxoq&P%>KeK02SHz7)M6iCK6dw-aLDgm=j#w9 +zf+fO|Kb$J`asHU4;#%=|E+UQ*U>Jz+l| +zAI*m)KzyC6l;7N~+1|wib6{pc3y-mp7zd|Xb^YF(M7>uqkYVl6?`O{|5ctpg^(S5) +zc!odc)D@F21;A+*c@^;*RX}0ldYx?qpLn-}d}}E{hoOVQu-?rJ3C!+d_2(DCfp;`u +z#wM|rt?G9kwY~8X>aSATfMdDRzJnTdj3;AV{jLm8#ApR2=mZ*F8taR6`iJj67%M)b_>Xh +z{9Xo;D$Df=XX4Yho6t`;+SJZ1R99y)p;i}%?`B<=GmyI>1Q>XY|(KevmeB2$;T6dVVk +z76j)%w_O?ob_h%na|XaJq#2_r@2<0tr%213xskjY(IGW&&TN-3GmQzBmFWN?BIAq@ +zUkdTwlY=JpgWhyT*gwAVQXoe@$suy(=Ac%u<2;UA%fImfV+q8@-S(A1m@KTC)m?T< +zgydd^6&waZ`xV35xca3a0I9XUyr3(0 +z0A2mChAo0tDhjq=L#s<-A4+2{OF5}NMg}E#aB%+IWb;Vs<3tZ|d<>m> +z__9rwGWk;%Gh*i4A|{5MQA&0H6MK(my;YW!w?Srlpm0rGEAOXiCzF1-LR_@6{uO;?pvfWfu|*iN;``OGNWmYu_ysfYgo= +zDKpE_CJ(Wdn=I%07OHma)coXs%xxmgTX?~y758YYrrxQuA;!sPo)mRLnR=?#drUyI +z7Ybo_=tZ)6bqiAL80E8}{(4aHJk>W;Nl(ORQ~L-}5>&Rjz`8n$Meg{~F#Mp49&3dG +zR4-pWzk~1BO&SLp&JhwCHhOP=dh5N_*si>LI>~qE_wB@85C7QxGqABh$LO?CKSe58 +zu}GK~rcRUjG4c@{tCbu>oyUxz$s005U<<5ye=b*c@sZe?wP(;zPBV>|>(&!7+NK{@({8qi1p@cOg|wl-zi2)$R#*Lwt}!>= +zW769Qf%Ok_r!U;sH11q&7WX%>Vx2X!6C%6!K)&yhXUNM8$=ey*g3mX<{Xtq-j#2NU +z6+R`p9+2%*(tkMy~_R%7EXt>sTt=Q$X~AkL`C}UjdzY8JSg;*fDPcSlerj|wwj}nB +z1RB4~dSCR&jBF7 +zZb)b6{T6LTOrD$$@YrhjZYNTjIl>0rI$nerBAvTE`{5zw1t1|(x;UY{qD=-MLhExA +zN`-wbpR*ofdM$DPYzGC@Q~34(`n@z>gvE!hB!gxI!YIOmDh1a=`zzwdS^gAAE1x5V +z$cYeo#p&olRO!EvKg9nSWK3gBT0k-sA6R_pEOpmxgOQgJGXni}aLqm@WP`<*E^$=I +zsh6>zDTxiqbABLFDpS9I=mlgl#lLr>JIJUijeoCkB0aAGKE+0M|M;r15W?-fqp@DQ +zE`>v0DR$@%-c^2E6(gPF1)>w*j#EonCEe+Ul+YpBj27%)Ki)SprCVQ>S=FQ0gVOUw +z=S8`=U6Q-2KP&gpvT}WY_6ju!R+}H$o^L_W00}gC(?@2?Yq@``+PLryEa? +znJnW2i6I`j4GQO6Jtq=G!?3L&^#R6XWkx&@jWeNH>MkPv +za#CyxSqj?AQnIMFT@f!#w9u;bKrIMTSgXaM-B(Q25_`k*uK#d`*UbVzTTPJd0MH23 +zT^NAemc!@J4IGXMYscEH5b<-q=Kdcg6WaGbno6J~Ey&AEa-1Al8_eeVOWNfOzQ%DE +zXL3C_lgj-}^)25?Q1)w}|=1kVz%F7`Y=m)JT-%WMJ%g?Gw +z5UOMEQ|$s+<}pFvbDyLsE=wWOjGn^vZ;k)Lt!+=M^6?HjC0ikTSf#|gIh$S0!Zaq> +zS_ae?A^X@1g)lm@P7=rHbgCjAcA%ae{zjC@C!R#+;8<|m<%_Rw;D5lsHz5PzanT#w +z5_7X=YI~krF_(pQap*(vl#|&d9>csOot-Qt4@&g4qPU~K1q2((t2_-JDLCwS?1zvm +zE^Fq*iL|Q%@B&J{Tw728Y@(#AkIMCNlgE;j=#d$xpZ?1yq8H)T@%_XQRY_eX?uQ0v +zm(D97?Jy8Vdsx^;@le6!Ym7{X^^e;jcfPd~$LS0Rm=&|y;`mMeTs;qWeCReY{LI~#w_=e@yCQmJdOs)q}2d}G2;~jZo +zg4`1C7O2!_F5T7-qCV2CUu9qy&I-MZ;Dy)|LqtUgy*jk?AldX^u13{vFp>{CP3u*e +zuUB2eur^of_o>I8Tn77cI#_W(1>|=3q5XmDIIuGN-m0v>5G@S}hIMk>QF-klY6Q$! +zYPakuQckep=~I&ao>@C&{s$`SZS$wLh>q%06`yUNF70%*gHw71yW8ko*7bB({j9n! +zddazGDAkzeou!zlfid!QmfrZL5h7%&fP`BB-gGDmM3?@HfwT8DMRHb>(z$5zI(a`Q +z;jq{?xt(a31wndguR~QyX*})aX--{92Y(+UZ4{#cvUhaS{FVJ|%liY`u{v`Xim9nF +zSf#eVYlFh83U_04D4py6veB=4MjaCtE%+!l?nyJO-DJ(KtnHCcEJxteH^9p7Thf81 +zg~E5vvn!9GGW-n+egWKYF}g+;^`m+f_eUEqad)%^Hem*r&ms1crn9=bZ59wdp{u>s +z$8SJyw1sX6?|ncep4a#>(1`N*iZf5be?gW@pv7Mq3F(|$rnm(}%JGr;QsC1!v@DM@ +z1D8nehxdm&MH!-49i6WfGJ@D@z6JHt_<)B{Q=3UZy_M5hco-Q(<}AwfvEueA-%Fix +zqe?*@)F6Cae`f8JE)i`s$8UszUq<{>U<9h4XjIpB`RtJiZg=tNhq!o(2cs~NoMhpd +znxJ{?Qb{YGR%M#b$J{4&N|*;e^Vs2=KJ%>8V*5oCR07y|Cz!64Zewqd8BW|jW!!=C +z)gtiR`O6*f=N!ftt(NR84NZQ;&ATo!KSG1q^04V>q74er-#r;NZ#HZyT=aA+g2;kS;tep42x_}H7qim +zgCQ +z^sm12)AqEaQpK-37mq$Zy|BS~DFjao`xQ}d0F(IkP4ehI=~@u)mE@3PNbW4@3TXI+ +zHy&O~f8U2cS=IR&BAkr>9@{~lvus3Pq!wuvb_QNrFuPZt9U%5knn6uYDIa>7S9jhU +zKgp9Bptzw=U_Zv%?_Dsy>O9WvB?LGUKaRDUcDkcyqyqZ7<($N4ge^JO4a~jn#GuLc +zKC-Rj8Wvj`{@|z|f+l03>az09hQ(mP)IslE$~J2D;}N+@W$-H1?wl6J<QMl^g5%eEiYolYcIxSZH7ZAorZF*_)iNKj)v=DcQ`Ab +z3$F4Kh5E{Vwm6)zxbjiuvBe%MIIVS^3?2<#WUChRUl*-ciOP1LvA8m%eFFAhKX*_K +zorK(Ob%$^mjk>ITdVPoxdcORrdUsEZBMYWrHhRiS~Ejn!>A7H*00)f>vPW%zTKKa +z#^;|3?u!i}7V0qRFSVc&@9D5Qbqrdy&76w&cz555179(CSE9)V$i4GcV@A-4KD79+8ox +zqq8~wW2cn@|F{F}sODPiP$443B`UhGJ!Yl)B*W)+ktV=>+(6R-l|jv6Z{*}%d&b)p +zO1qP?SliO+k0J0b%^}JHrWSaaUytI^f6&vrHq92dajCg(+q9pqH7|zzrPzX-KI~SyTi7oK;rC} +zk?~PONke@c{?I7Up1=nwZceuKR%nzc_6`>)Xc?tEbZx*d>Wa$NuM-gyYX>hq&vu-Q +zY=)XS89v&2H;XJl2eQ*fGqT2?laF)L5E2hKTfQ8(*++k<(sBLRjr{|0X7>S%_wxBe +zkmk8@SJL}|@KZLX71m;0cR{5Vr8mz_tmk0O%^osUXg$jvf +z80EtY?*C}`MD-Odx5(wW+ypD1bO5Nkad7_^&w0dGRy9?8L +z+Ve)nkutm#}g%Z +zeFWWT9hymuc0uRouJwFV?Jd-kh7G-h0+W&aJ>0t$zTcMCgJk`uoi%l{($L%-*AF1k +zci@-)ud_%E1`(@1A9twy${ZhQ4XFLXH?^C*o$+S;@<`3T6 +zO!D@bWROxPwVNS*dno^Zbp?NN6Eg(GfiifsUx9h^QO)yFE|(kSHWY|wSpVlSCg4`N +zyy;rP_gEmF>#e0H|8^6K&FQDos)|hG6vQ*nSYsoQz_N +zwhd<`^)r+aoxCH8YqeaOeBs62wdWDcRG(k?V|gh_>eNg8jA10@3PG9Ev^f)}ZhBZ1 +z7>%6m;oe<}{6>=RVR@W;2>c!Y>k+Ngg@EpfQfV%uz!xeA$i*t@wKXAbMbR!G=i9r- +z3^%V-y(ViN5p}$^hinml7O#Nhsi{ce9{l5{QyOd`_{c#Dh07P%Qb?(DQvzZs~?q9w=^jV5L@8Ld%6O4WMaGd?~>MO63;q%bNwmy}YQ7n6W-7 +zA%h#tF4>0!A +zpU%h;Z@b?IaPaJ?k}?Y;xcdLyZ==M{{J+d!FwKXreI?ws +zzLW$hE)e}YEP91tDmlxp74o*I#xj}p)wbNt*UtN%RGO&sFtC&Vd%O~d+x83&hA>TbZuL7oDP6yuX4`Ad)=}QKQv8hwj65JNBSCX +z5jOe?;SG`)?NSV!4uJ83?#s1ziinc1_l5OWirVkq{KohZLw7no2Ic^@yvWt!(7DFK +z0hQ(r1J$#1e}aC8-hC+45wKVmIM}w#HB9hz!`Ly~iV%9!X_b;VBCuo2K8wBv|Jj)% +zXixzH6WM(-t1clb@s&7ipW*`Sl~rj-^fnW2o&N01=>uKh$B{m~=`%N#_z_j9hqvej +zvoqJ+uHOapbs{ui8Gfj1pZPj-!rNh>kx2et?uDO8e4RND>1UI~r6mxLJ)CBY1M&X- +zvYU{GGy1TgFST3u+ILMX+5C>Rj>AiY!VIa;`E+x8J1x?DM_8A1I&bPnoL}7n`5-KhJgW)SqSlJuZx2ORxp*=+xNOI!rGB9CWiz +zS{)xib3U;D2TT1H&HC3sFa(Z`M)>lU$Nv{iDMWO{7&gZVjO!7bMJ(@W#JX-@X!2nQ +zOC+8A*>I-T&0_mI5Y7OEtu7vL5Z~SQp@Ky)gos(tbKB>&nL5`|Y~!__0{^USll1jY +z)`~+W5fhmzpE1{;KH5Raw^(V`-*v1V09mZSZ){e4QAu*ar()0Hcx!D-)M&> +zqpR*fqK3^X;KG75hl^qIY-b1XV2#O)CdRCqmSOU|@!s$NBi4SubDqN8-_ty^yoT0v +z6kRc3o%4-6X_ZA+4_d(8hO)CIQLT02Ewaxu_^G(};;%oT%r{51@geRJOhf!l#f$^# +z$s~ME#z(br;WUw)tm +z=EF~ZZv_2U4~;j)|Jp+%3}n(<8d$3d6xeI~&s-th%(bFd*^nxg7dy^>o_xMlkSP@s +z8LFvH<9_3mhR-S#)-JYwre{?uq&)x7?>R#8_omBbG@g0*{U=Rklt$WKcndYx3rj4X +z7db%k<|96ziOuDjt;-~zFb@PJF|8ma1y_kkL}VraiEZS=3bmZe6I6J{Bl}Y=C&>BxZ|?p*QWSuN-AHZBIP!)G&|<1Rn>#w3Pj>F&ovm?U;(ZZjta +z3&BzLAC)K6Ce(OMoQ-cY@i-ZcOuX_m!7Bf+v>t?}M54H9JM%5nwZO{Ok@A1o^FyG? +zJa-(Awoi+n6yJZa&J65-$2uD=M|mUom)-dx_7DFas>5m=9%Yh<4M75%+lyTv`YeQ| +z#E$yspE&Q!w7j4B=TP>!+xTCO4XOR@oTBwtZ{s_s$B`-LdA4CJ5eVeKF`L+P +zjau@nzan5>t$R)nLOpyUXF#O*p?PsmI3rqkB=%4kI=5wB6J#gfLCRponqd8~3znzA +z@cvRe>iW#OnfsvY5p-`wcc@HGid86qbDEq{LIq+fDjdj69(S!QW2`mgZ2Z=zVl0@# +zLUiK`iy&ez`v@t7@4eLv;j~LAn=BoSxp#wL^G`p1Hv;^r^lTGn?ttu^(hm2zR7Z=J +zwXOLtM#{ABm1r>IKfNgS_4P42U=|kCRDl$uN(z!i_}S(U@cEg>_}1Gw{SKY##%)Qso>l( +z%*-~;ckA)CfB-Y3!H{vRyRNZ=nut%p=Ri)`7)= +z&$9!wN8&wi7Fw$MR|hi@WpM)I14&{`1DV!b>Pb4u4s~_kc-3DMzt(-7oII{>rE9Ij +zg|kCpUA;62jrluc5f4jpXb?W>S0yyU!a{O&JX563@kKql#aL%6v+%R^Gb)weOIcQ8`hC0Wa8(ukvtl(AYN@A~PAbk`u5}nR +zvl_k_b7`OIW)2g;#xzcGrg&SRe`tnfG^^l0CGVUMSa&`ZjeblL3-o5Qw>PsU~ +zeqlff(zr|x#Q`$r_CuGE13uoA?TjSsKusD7M6Dcatq<#w%>0yXb#{)#T5waZxx&ba +z*9!(UKKLXL&S6TOwzKtN+UMqW$M#;Z;B|m#MoCu;KJbxz=UQ*`_q#7MYd4MT@~f4z +z6twfd*GdBa=C^FmK2)%iwNI*e;ACcnOKNb}Gf{xnQU4mByl?T;!)1Kh@eq`c$+2T% +z0|jg*Bi4BIxz`AkR*1Js+Mp#?tOa9f7A?`#fVE8gnnKZ&(A3odoa75_v|z#c=EGXL(@KOKQvbv +zs>RLJe3di9<8oMU)_wRdf9I^ob(2qsJ&U2w4)7oO0kRmOI2f2f1kII9JK>(EWw2}c +zx#SE-XxU#F-<`n&x+Pr+D +zm1l;SDIPTf{f=R>-(A1TnG&3|_u-ij)SL-_-FSkLKk-NgwUbp03U7M++DMLE&0zOH +zQ`*F}JI&u0N^AM!;%ug^5`Z*C8$~6`6y&8lqUdtS& +zppk?ZSwlz%=nv5=EqLY+^QsL~;N?|l1}Ja96`MxLRw`~bQ$+ZI9<}Yxp=~ey7kSjL +z+KFB)FlNoEba&1D#or!(%P(lWgLAri5F6lj2%uc3fQ;GKfF5Ta2mNmC0}r)_*T~nl +zXpuECKwe)*H8qTfH5N%&WTW0I5tkgcfu*II+m##=@yZJ(4vV4C9gl!R=jaMR(M~;`;fVHLlGpOI_yUgwH*=w@TDO+3U;zQBE<)K-*d%Vb@Up3(3%ll +z8qbmMl3qA3*H{{r_~?WvJ$)G{7pJ4nnbl)&OiI|M;--HWg +zLFnn4Bw{^H@anf;7vACQ1;Vhh=P4-7qeh_@C*lY@S=F@3pVG)5Pq +z_B$-cF~H0S>Y!}%hg|tJk(u1woL&a;Oybgf06)@JXy#Yd`AU*n>zlMU9&ilX5n1bF?4$BKq!F>cmF> +zw7kX&=4?j`SRuvax*_#>us25mn8@ol{n?94HJhR3rq^-O4Q&eXb`kgM_!uhVBVVv4 +zq|#CUHgo*-`}JAcF=Ss8&=MA}ySNkcVR#F8H`N4~SwZ7NwfUbF#xb7hu=QqK!2KJ? +zu<`r8WiI7l3uk%$;=8XUh|FAmz)192`JXKVbTsVi7{kgpzUpXe*;P)M#2sEG&IE$t +zE-qH#F3H*EkW25zpN2ZBRm+)e3eGu?+l^Zx{CR!UQyb)-o0MI?hkCsU_s;xUL8tpK +z9t}&iaBc}VQ`Rn(l=Bm~)Cv0f*#zEU{^dkZHpeZ1**(E2u1l9^y40VRvG8B=+Zx#a +zdEN{0)w{6Hc-eXEYdl$ZW32sAbsq>i9~kS@CO`0j`A3raX742x$=sS_kAzB6G{iU0 +zyU?W!-@j#BDJX02mA}*Tj?%k6ID5~7ZJBC%G0Bwu<(`MeMo*ou?c8J)-2bsFd%;)< +zM;-D_TJ=pbW5$UteH>057Gg5*+0PA}Mx=yaBP+q9BZKElgP8W9W-STS-fQREg4MWT +z&`Td^T#SOi>U@0u8@(07@&c~wHL`^En|%X#Ci%`bVeB#Mwl$quxRV5ue2JT|XPkAJ +zZx($#_xfg~_EengAG;wKVZ*u~&|}B(pRlA8_)pQQs6el4m5*fZLziI&Wj|t;i6foq +zC4+phq8VD+d!fqlm}&jlPNUqZPfh8A6QA6EHAhe%-?$|kRxFmGTs4z7s@^i1)O+UO +zb=D;F5~#jLDS)SG@3!%2akH8ckwa<=r{I&FY}3qZz%owHk;+wU@hB_NhzAaqTi$4y +ztPe6=!pos~nlZR##+D|lkTp2}w6v&Ubad=?*axiI6nMKjeSeZ8WWZh9Zf0uE|Bfq^ +zSliyVwN=xVJx-gZBzdYi>IB8w25aRd4o4l{QWx_nuS3Ns)qry4psIe)_x2igZubT1 +zO5g}CZm^2MkYfKwpkSQC(BMtohpP;sh5`cK)iykUo^IScj2_ct4)_)%I|aRu4#rs? +zwJz!2o`Kc95GZ*oaOblZP5%s@9ox5}x9%HUR%A$g+G<~A5L!i_#D)gDxgLZqzG%U< +zp<+iye^X_Ki5jMBF*2)04Vd>N{)IlM7|Ah&8uJeX(AXzWYRc=&tE|3WcGHfJ^9A?B +z$;Ee;sJZCV$D)_}bKz~2Qs8I00({ydc#Socalkm4cS3sD$PW$0`@rMO;K+1-uhdpy^GPCLRIXcvf=mTQ3gO^?bgm43yslRT%HW$h71x1!&`{S2*-Z~w%+ +zCb$yyJaYe?ZqNIX&k6FIe`h&!A&gAH*^zzf-ucE(I +zTx^ocV*lpJ@pAs9ihE2yd_I`#D|+@P!X#>TUHXS&jVZhXRjM+}poCC3;8_XzFb6&( +zD=V_NA+=GvZ)jEAVqbAh)SzYEYIfz)+7TMy!G +zth{+|sp))!Fm+R^=fjW?puMe7BsI_2cJ*j`RYX(JJ6+0$g;wMggw0vq*)8c-7JB!! +z|Gmt;YsOlfrr!gmw?X))(&M8QXykc4%P6hNI1+5b2Wx3cd1Uyes6H-PE{UcIZd}w! +zokhYY%0v>va@L4}s0(e#S+0>I5h+gUz`R`giH<;eu|qf +zEgCRtv93Od$Vm|5^clQEC3Iy`Jhip-c8qRm5gQ=nysK$uEvKa|Jax4+vYd=i+j22C +zWu*~wAJBOoXJEo)f~f>jS{jKQ;wl_V%iU;6oj;B>-hBMpV122+J8pS5Lv{Yc1+R%z +z!;yFY4y*>5Aj5|3GMUu0b51Jn6X8gR_DgPfx2+d`YeQFFnsMN#UG}x#t$vJHQAh`v +zS;l`y)YcZ)2%5zheh)*puIJ%j-Y+B@jnNN$MxPeOC%@ygkYgbQ$0_&(jl-jdb2$g& +zJD(;R=75Al)(+{NXR+S1maI?TRkX^+=fkv{{~k00-Ag@}_hO5BT2?75v4k@Trd+l~ +znZ#v%wy(rGR)#V~kBZ_s6p4$6zy6TkbNFj%gl;HYQn4=J#-UTQqPHi@s++#*I&<&d +zIuu4lbIyB}Eh1kP4exg!7P&oH5*wDCL1dFaS!6elV25ND-ZtX%2-nGlw; +zbeY;qmt1^Niq4BZ6%_aRzhmduY-&pVNSy;e)u}j+Wtab*LZ}L%x~T-NyO%&^WLQmA +zdEU*>axQej+^CDY5sOu~`a5cfkq(!wgpe@xZ4UvRWu+$teJ&-=Dt@8$eeBcu)A7y6 +zd0n>4CYXHK;>`NEX;;8mU7+~I*7;s?7vRzs649fxn~m7gE_vI3{(T}GTR=$i`D?5b +zOq_@;4O;#l5s|8i($fx**FPJv^^&x>xy_jZzt2q|=|crkcT4s&z8%&rkqdOxxTzGgx+oV8P(EK6=ZYv#qeDIur}s`bXAgIH^$hf8rw@j;oRJ$x +z+wGc4FA3oG?ANXyqIaNr-Lx4QB%&~f3WZBb3Yv#M{cUoxfv9InAI^)4(AFRKWOP?ZD0N>)RZ8zC6Y_#0K14^XPaY +zz!>M_dR6mug9IevSk?0`*l112C4u=cF~g$0{n2-cyM=iTxh(qKJ2=wbyv<{|k@cja +zq9o8j^FD{mY#HEwiOsysT3y!`UToM&&OviVY)T7>*6!;GtIa8&-=`>Jxy5q6Q2rmi +z(13xgAbLnp*nE2|k9XJx-)6Wmc5cMv<=e;m0}{??mP`}P(<3?ZA|bWUwiZtQ9rZd& +zLq~bpHsiW87j+DP_ACdep1iJlyS$EN@8|-NMG&B$j?8+V7=`>X_Wg+Yk&jFW4#v`9 +z7L0~2=FPl5`IWy>)Y*CDZC-)$lV2|{Od?^i^lGcpGJ$f~3_a*OaLke+Nax9S)tgxc +zr@g*|T>7B^%g*dmgcJ~)UA?>L{mi4r)hap-_r9CWFsJVdrK!eT91r@>BgDS(jc1K;}m?C&kF0H5;}Rp0o=H@@+WZ+zn$-}uHizVVH3eB=M? +ze2A!T2y%-0W4hkA(xGhfL{B2iWAaSi<0$(~%Du*o*6*Wg{Hsya)|qr!>U!_s@L$73v-0c?z8~&(dBYuSLLWjR! +zMfA%<#LGO4<;P082y=n3NZ&0x4b8kkw_s)OJ`!A2d@bF=B2`Y+eAspke9JjkB{TU> +zR!?vgv`P(e(^(pXvAaABx~7Q?^TE0Vrz98b`A1TA?B-5|^AM^HkDs(ggv|9 +zJ0}xjBuAbv21`00>ngqK_|u)6N7uV{EG6q~&-WcIGA}T_g^0Yg3tO_6B>vnrd9~wo +zf}%^LZo^54!Q+2c^2@w=OlDedWWZA%RY6wM-J%)B%S4@7j?U|gFhrTVZIZJqyc`RQ +zs>>au#zob7xl+qCwO;O-<>->xx7hZ=MQD5NHU7fb{{D~ShUa#{-SFeU#S?(L&Mx?p +zM}#DEm9dO`}Z_{-;jbc05H(E%TmqRhWY_@ +zx;Y%xeIOk0;Rfu(C*UPO7r*k^`NNgZR2iW0h%(j5sP{J}+4nYc)5c{W+OTnG6Lq{b +z-%n0XYaG_jH|1icf@j&ScoE*(r%8t9Y<(+e8rnvkY#sCqkcrgX4PP?mZc=S$LTYhH +z(6}Hb+Hf&M{y4+%n4N5m5Ot(QVwa(PLbbJp +z(K-$~ARqJ$+hculL`bx?mFnl?7rlLZB7F171Y_b^h9A2%!%tX9&!{8k<0#v5J$0m9 +zq=*cfhnE4tq*`J=8VQx#LhG>v3kRR+hw(z9a*?I$t3|d@%m%C!a`q@L%!wM?#Pp_B +z7LhJE-@nU8a_oheBHP>icaR90(0qBj+}22#43+a?Gwy0f>_%I+RT4=Wy81PXh>xz{ +z*P9M0;g>L^s1_~Ga*^-_D8S|8xu9uyC0&2LbfiltKqN*x@FNP#&A1~c2ZinAe)jRB +zH9Pr4({495p>7b^QJXCz5!&@(McR>N)X>@7)*R7HA)Kf|AyWI@h=qMXbL>QT3AO7m +zA~bd`3{B^cY!;@=#$c$qt?RSSHv=0%BzPk*i4l#~+hBiKr*03T>lx15!v`G&c1Df? +za4a9nEve1nf~jyHK#FS-zNTXlzODDxchldb^^|Bw#K!y`tnU6y@zgW);o8FpDk*2W +z(C9#pY;gdlpeA6&{D<7dDbEEPxY|y?pgJx<#91cBV}bId@7ej-eoSy5J1w{`z#&-| +zcW^RVk1Vo$wSdyDy|ead)+rziJ#~;@r&w4Y;Y=Qq@%1Ck5@!U2XUJ$GB?`5kx;;p( +zZw32cbtkBdZTQNae9E8)!n#rdgOY*(j`I4(hejxlo!WER&;6^o*@v +zpD$uUi4+xP5lxvXyL~@AG~$AexV?qQnovYUY|w@`kk7Z}lI9W88?r_sF&Gf#ynV_cS<*A8<*Pl0I +zX-p>?w}J^JEfVwj2nJ~jhy+@Q5l|f{^ML3JH1j>UA+>GWCG(IU%|#1NPe&}UMsT3)5;oJz?>4 +z9a01xv@x@w6Nmp1A@@;Z8oq$8i$H0&Gr|geaY%$OX&&0LJe*c7Lu(~&a4TpAq*S6* +ztYLKh(GI<vO +z(cEYYX5p63Jo0NuJB_|Q9y{(5S+z;OgOF(-1E4^b0Lg?C4<6%JM{IReBV=`1PtM_A +zh#vGT)ON2vb4UsXYP%;f4oTZrZ;_%EcMWj0cj1z-*;vJ0V|;D*U}7gvDBz;3?oQBB +zS9e@uaAKWo41HmE#6l-o2%!^MN;|-;a}i|Hti*xtOmr2q^LEs)5epm7q~hd`VW#N$ +zMX|c5XlF94ExNsWdKLBEp9|l +z*nntzn&y9M!y85p@ +zGeEp4j;C8Ssb&iI#D{J>dWEy5c|)BmyoRI!*5UI6@6VdGo6#*{%C%Q&yb=}d=S4q2 +z{o@Oh%G1T4l0Wn{glav1G??Q`4h(Gw)ta-@&eD@MNlyT_+HT5(t7nUFWla*}l1jTq +zd&U+6m$_D_(@XCpbdQ})bS1xXZwUR;WvA`t9mCFzXK~gcuH*+I4WSBeBLyQOePhKN +zuH*;V4WSBiEJ10=F3vV*+tNXUq~Yp$qk`V +zuq)Ym4n^Q5IfvA0{IN-5rVHUi+lNH@WQoHp9u+uF@j*1Ne0F5%YdLjS(E8R3hj8K>Z0h<*V*vA#0g2` +zru821-x3%+(&L%*+_t5Om7W96T!4=w$^UG&h|hee0IXz_JglGbaF}tzsH;71#@%;xz4!#GPZ-wz)ql& +zQzbk=xm;p1Ecj+&O%6F2s?sKDf*ZPs?@qSU#UN*TvpWkW#m))Xx{7_#TG=9o$4wHu +zUY6n}v8p-akWKc7Mjj!gVSi|jVArlD2G-jGEAf+Ey>6oG8vuw;u2gb&HBwXE!h&hW9 +zkljKYUx)Q=&fh7+CmB9e#11UlwX1=XN^z68uGP?D82V#Dk#a#YT+iV}Ddb2~!#*LG +zwcd2l`sAjrX0%3jQC_kt_NuxBiP&kaq-zOmJ3WS-!=TBPNp|hGWWX3}EX=+i0gX~F +zhhM`6^AgXnrCX1OD@xzjVuef|P3eni^I4tKlQvPEz)@F2OJOn%1sJ=>FW|6-6DEjS +z#}qhBLlD&vtf2?LCSXq!T$Kvtl5vRP^qw*7m$jU6p{i?Mo!`4ixge_y8-r^i?x8SJ +zNx(TlGE4O}OLg`o@G#HmEta)E4!YGce)XzOI`C#VCC +zHM$@W{-?&gOJX$vBY>JLPNn1BC$tsZ8lH&lhT;`+Bf|D+X2zi@yh<lELGuAa;sA`k%k`QJ_+!l_b +zGEm^Fp-er~d1HQ-8-&xxk&7%)Br2?mYsAcVQvIv;;S>)Rju*D2O{JZuB4^AK6x1bV +z%#lt~9k(KbKZNZJKNCLO|16)s&ZYBd`{ME$V+RqDPnsma&9P+`Ja;im@&-$2_=_l@U*_lrZTx +zZQkxC-5Z@Bt)na<(LCx_fc8G;maRjbuC}ZUqE>0dobTPB_UI_uY%@VaaDHZS>)>gP +z|DMnM8mPi=(_s|jNt#*d+DyMfAW +z8IRQVl(uGM+5%=rW=Bi;AXYR1*v}yW`wxj}1`%5rT}SEyPt=FoDzE*E%uj54m0_Ie +zqbpV+O)b9u=7PE@363e$t@4b6R+r^}~+S2oaJsl!`ZtOa@dQho0+@nrQJ?ff$mhTo=WrlEF +zhgj~rfwFU0({T~z=GfRNjF=7^>`u_CxEZOfARvu-QS2TQpG}Y$DVX}u8bS|AUM-7D +zE%o7wi4#Wu+I#~*R +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 +z3j`oHY_VPzLrD~XOxOr+tCIKFDv7ih +zTKrncCJeWyYpCWEBU_{*zq09ql^I +zZO)Ym-2_v{0et>G8E*wI(Jav9wmmUxNZI<34+MjNQVhTJfXmoyt)IpCbK!UA8OT$k +zPY0dFr6QPkJRn+L4**RrV7Lq?Yy*2(XTRPnXD|O=spqx;d*AVmQwtmi;G(^8{2bzU +zo~h1l*?_Hp&*m;<^+@`n%2)%9t>5(>Q> +zbrS%F=|WTQ`$`*PpcYH|LF +z^kU7ZBAApEVJnJbAj-4#yTrKayG0lVt4+HSrulsn+EDuDw9_|{ +z4f6!!hU*1+;F#TKD_{-Tg?OQcQufT_ecS%B@{5(F@;aN!8ABJOkP{9dmyxu1`qQY% +z66OB2kV|buv7IpFTOvVxTv4d0qi3I@TqpgMUK_?bRoT&BNcFwAWmmGTYhR&s%clNw +z&+K5~&R~!d{8DR^VBZ{%@V5to-De1wQEd8xD!MLk=i|r{V_pqp{@!JLy0z!j!fBsoFkRRLq`6g7cx}E<*lBY +zVQ;HrXVe>`lJmW+GY_0`1Ae>Sc=191y+_U7{bAswY1VA8j)`XCA2Xq3>@E5_NbewS +z=xau~+>!cA{6~J?l%16f+{o~7fwu0=tj7xCMZWj-LOocvV!1uJ$;nU4Z(s%P#WAec +zV>?gNb@wvlhO+1qiE!3evK(li4l&OHLpK%^VS;s1?8u%%S~|oy9r)Ak +zGDPn5>C-AsjxqZU*(>q=i4Zw~Al+P7u(Gkgf1@0}H&O2a=M3`B_Xwv0``tf&&|-NE#Zdc&i9!oF_vBf9v&V9rIz+PeOu +zO5f?&d{xiJF5H*A&?Frfir~zsvZOIU3xBLT^P$F +zG^GOz4ap$*Vp2IG)`j(Y?EGRw|C~h;Y{?ckQUGR+lI3*i@B5PSmeWt$u%IT^%XO^5Nu$q)!^FK!Qfi?NBofx@rB7uRze5Vv**$&2MhMI*QJ +z@5kFLKq}>UyxsA2_@e?op&q73Z<3JXhV2?!z~H`BulTTSNG?Rx^gWEVw49zPryL6; +zNg!gNTG4Bj6G7OpSN9Ms0G!ecp8yZT)AHvR;c2L*8vjhl=FFb& +zOU6g@D2={9=6;J3A(2-JF%w|3D35UaBAo$>L6ofLHVJ=nAk^>vb_c{`TLeHFa$bnk@!V^%RY{L8Fz +z=y^}zo1w&E;B_zjOUflk6_$iBN*95Ibg}=|KSp0WUK&5A)hqYRJ7Sq!xx2h5Qga~SMvlKdLNAl{UWwLIuq2H^Tu-eqv)|KL`F-%u(U5N{C +z8K8Uy76Swav4aR@zTEZxu0K~JBsb=kz~seXkP-s78e9_f-IH^> +z;JhWQS`U%<_?NdbJ@C_~f8GT*p6}{f!rqPW2k>IhKVLtR+8v&BXpQpI +z2!49{R+4T#R2!{%g{`fDT(8So_j@@FJP$vQ$+Xy~NQ?R`Pdh!3ZqX4!9Fk&qqAf*~KzC2e8H0Lnt?=W)I~S9L#!yQ=>0h24#S#U!OsSQh#*N&Wr(j;*hX +zB+s0dx?DP*QCYk@=LQQ7ZN8c*Ym#cVa-?!K@?O1%yRc#q=TH0uI#-NHv>TlZXA# +z!$a8)gIard5%qZ>Y!5G@HV+<}%>L`mt%=S +zV8ngex+O62cT>A4FbPfUg`f8ChPTnMAOOxot^-OZ{_6;Or?d2T_+@WEUGYT@N%=_* +zNfup!=a0(8FG4%%@PDG>1*Ry{l;oYlRO>}aEu*BCoem%eD2#(l@_#!y4t?-kDZt&! +z)y1{_0pYi;oY`dHjm)t7UjpM-mMT+|2ymFdS|>Jk34H0?|CG1=R1g>VtoWBFN#fo4 +z!zhNMY-HHN-Y51mixYD4dZ&4jI~kwPA2t+A6f+c)J1T4TzVoY0g2GWm0vX@6Gx8}v +zNij)N415%mYjmvR*2k-?y@mLzFpmXvH!3Nu8*{ZoefqW5iG-=Eb7wY;=6>qpx_ms7 +zVB!)9`%{ZGx8M_pJ$*|zFnHnNlK#@er5MSgpS#H2^TO|LgaSbk#b8z8{wv +z6qe3tomf*=d|U4B4$iky8(q80Hdv0^Ox5Xx9+@OE#p2^D+X!DbW8PU;cCY!&KZ$t~ +zw<|c-OCmh!2#DK7OQrY(ons{ORsIr|PF}jSCJvFv168jN&+*!Vy)f4`QMdTSnf@_R|n_B3Dj +zGPN7dd5C<+TxZ?hnXq`ABB!pK7mLmTWU0vyr176|Vd?y9d;e=m)Fd5HrMQPrr|Xvv*xyd{=!4LXy}dsS;=&p5mwj-rWN{JdOcRQmTxZc9?8J8xPSiVg%~|Dw^R_BOf-6gn +zZq~%-Z<1+b8sp#j_xDpk6cxYd9kFsAPS~)HtW$Hys}ED=Rj(N7A(T_ZucvN*0^m9k +zxbvFF`-0{oj(`92x$plF2~vFaXTRgtX;4w<4-XX{Uift(Pwi?e*x4_(dE=1 +z8Y_=9eZk!;=(+S$jq2DJx7^IqFJr$BgcU^Ii;WDP@wC9#S$B<2HfpJfh6a39A9fw3 +zsjml-UAzo>KAchWL-&|GXPVgdD@^46)NFiLQUUCCeem81BeHzuRFtFM*1_OFyK9Q~ +z{Efl7fVL7;RBf3gGqJC*r(xYJJ^v=oe+?4w!I#$_I&MCHbVA|9In4@x+-Bo$r{5?!|YDvIlB5gEv#c*h_O^kHM@e6_AR?dh#2m +zjmUmK>B^5^;_tsd?jn9c-$&+%=DJp@o9m;3b=8=Tig2eH30Rd1)Ur`nM)kKXpZw_u +z3a2$E6;h4j&YirUo9Ui6b5&$gSWdOkDTfgcG;C6WdnQ*$%gP%ewa2nVUWPgCeJ#_t +z-~7{ckfJ_yreZqpb`PY&X&rMdE^XU}^fqnI@#Ek)42E;^7@aJ6jg0ICpJC=FN7qJC +z(k``C_H{jFGEdQ;_);vhB8KIg%*Q=|rg_8}MIAx2-TVtp^TMHK$um^%*(*?rId|>7 +zPF;4!t`4GB==S>f_KNu!|LI))1<|Gh0I@MJd~_p{J{Ayd!H5L@ +z)4Mu!=+GyPpvM7Cx6*CVgYHi*OA5kr-A?X;b%K}Ipr$ADid8E +p-2n*wJ^0U-v7>KuoPIQ2d!PBQ{|*1e0(@QdS=9&np+Egb{vR}l^_Bnt + +literal 0 +HcmV?d00001 + +diff --git a/dirsrvtests/tests/suites/clu/dsctl_dblib_test.py b/dirsrvtests/tests/suites/clu/dsctl_dblib_test.py +index 4d5a54eee..9fc9caa05 100644 +--- a/dirsrvtests/tests/suites/clu/dsctl_dblib_test.py ++++ b/dirsrvtests/tests/suites/clu/dsctl_dblib_test.py +@@ -11,7 +11,7 @@ import pytest + import ldap + import os + import time +-from lib389._constants import DEFAULT_SUFFIX ++from lib389._constants import DEFAULT_SUFFIX, BDB_IMPL_STATUS + from lib389.backend import DatabaseConfig + from lib389.cli_ctl.dblib import ( + FakeArgs, +@@ -22,6 +22,7 @@ from lib389.idm.user import UserAccounts + from lib389.replica import ReplicationManager + from lib389.topologies import topology_m2 as topo_m2, topology_st as topo_st + from lib389.utils import check_plugin_strings ++from lib389.cli_ctl.dblib import get_bdb_impl_status + + + log = logging.getLogger(__name__) +@@ -92,6 +93,7 @@ def _check_db(inst, log, impl): + + + @pytest.mark.skipif(is_bdb_supported() is False, reason='This test requires bdb support') ++@pytest.mark.skipif(get_bdb_impl_status() == BDB_IMPL_STATUS.READ_ONLY, reason = 'Cannot read with read-only bdb') + def test_dblib_migration(init_user): + """ + Verify dsctl dblib xxxxxxx sub commands (migration between bdb and lmdb) +diff --git a/dirsrvtests/tests/suites/lib389/config_compare_test.py b/dirsrvtests/tests/suites/lib389/config_compare_test.py +index 3eb3d0ea4..fca33665f 100644 +--- a/dirsrvtests/tests/suites/lib389/config_compare_test.py ++++ b/dirsrvtests/tests/suites/lib389/config_compare_test.py +@@ -13,6 +13,8 @@ from contextlib import suppress + from lib389.topologies import topology_i2 + from lib389.config import Config + from lib389.dseldif import DSEldif ++from lib389.cli_ctl.dblib import get_bdb_impl_status ++from lib389._constants import BDB_IMPL_STATUS + + pytestmark = pytest.mark.tier1 + +@@ -47,7 +49,6 @@ def test_config_compare(topology_i2): + + assert Config.compare(st1_config, st2_config) + +- + @pytest.fixture(scope="function", params=db_types_and_states) + def set_db_type_and_state(topology_i2, request): + """ +@@ -72,6 +73,7 @@ def set_db_type_and_state(topology_i2, request): + return (dbtype,state) + + ++@pytest.mark.skipif(get_bdb_impl_status() == BDB_IMPL_STATUS.READ_ONLY, reason="This test cannot run if bdb is read-only") + def test_get_db_lib(request, topology_i2, set_db_type_and_state): + """ + Check that get_db_lib() returns the configured database type. +diff --git a/dirsrvtests/tests/suites/upgrade/upgrade_bdb2mdb_test.py b/dirsrvtests/tests/suites/upgrade/upgrade_bdb2mdb_test.py +new file mode 100644 +index 000000000..d9647b120 +--- /dev/null ++++ b/dirsrvtests/tests/suites/upgrade/upgrade_bdb2mdb_test.py +@@ -0,0 +1,278 @@ ++# --- BEGIN COPYRIGHT BLOCK --- ++# Copyright (C) 2025 Red Hat, Inc. ++# All rights reserved. ++# ++# License: GPL (version 3 or any later version). ++# See LICENSE for details. ++# --- END COPYRIGHT BLOCK --- ++# ++ ++import os ++import logging ++import pwd ++import pytest ++import re ++import socket ++import subprocess ++import tarfile ++import time ++from contextlib import suppress ++from itertools import permutations ++from lib389 import DirSrv ++from lib389._constants import * ++from lib389.cli_base import FakeArgs ++from lib389.cli_ctl.dblib import get_bdb_impl_status, dblib_bdb2mdb ++from lib389.config import Config ++from lib389.dseldif import DSEldif ++from lib389.idm.services import ServiceAccounts ++from lib389.nss_ssl import NssSsl ++from lib389.passwd import password_generate ++from lib389.replica import ReplicationManager, Replicas ++from lib389.topologies import topology_m2 as topo_m2 ++from lib389.utils import ( ++ get_default_db_lib, ++ escapeDNFiltValue, ++ resolve_selinux_path, ++ selinux_label_file, ++ selinux_label_port, ++ selinux_present, ++ ) ++from pathlib import Path ++ ++log = logging.getLogger(__name__) ++DEBUGGING = os.getenv("DEBUGGING", default=False) ++ ++# Environmaent variable used to generate the tarball ++GENTARBALL = "GENERATE_BDB_TARBALL" ++CURRENT_FILE = os.path.realpath(__file__) ++TARFILENAME = f'{Path(CURRENT_FILE).parents[2]}/data/bdb_instances/instances.tgz' ++ ++class MigrationHandler: ++ def __init__(self): ++ self.hostname = socket.gethostname() ++ self.uid = os.getuid() ++ self.gid = os.getgid() ++ self.idir = os.getenv("PREFIX", "/") ++ self.inst_list=[] ++ self.username = pwd.getpwuid(self.uid).pw_name ++ # Determine the instances names ++ with tarfile.open(name=TARFILENAME, mode='r:gz') as tar: ++ names = [] ++ for member in tar: ++ match = re.match('.*/slapd-([^/]*)/dse.ldif$',member.path) ++ if match and match.group(1) not in names: ++ names.append(match.group(1)) ++ self.names = names ++ log.info(f'MigrationHandler has following instances: {names}') ++ ++ ++ def replace_dse_line(self, line, old_hostname): ++ if old_hostname: ++ line = line.replace(old_hostname, self.hostname) ++ if self.idir != '/': ++ for name in ( '/etc/', '/var/l', '/run/', ): ++ line = line.replace(f' {name}', f' {self.idir}/{name}') ++ if line.startswith('nsslapd-localuser:'): ++ line = f'nsslapd-localuser: {self.username}\n' ++ return line ++ ++ def remap_dse(self, path): ++ old_hostname = None ++ tmppath = f'{path}.tmp' ++ with open(path, 'rt') as fin: ++ with open(tmppath, 'wt') as fout: ++ for line in fin: ++ match = re.match(r'nsslapd-localhost:\s*(\S*)',line) ++ if match: ++ old_hostname = match.group(1) ++ fout.write(self.replace_dse_line(line, old_hostname)) ++ os.remove(path) ++ os.rename(tmppath, path) ++ ++ def tar_filter(self, member, path): ++ fullpath = f'{path}/{member.path}' ++ # Do not try to overwrite existing files except dse.ldif ++ if os.path.exists(fullpath) and not member.path.endswith('/dse.ldif'): ++ return None ++ # use the current user credentials ++ member.uid = self.uid ++ member.gid = self.gid ++ # Security: reject tricky files that may be in tar ball ++ return tarfile.tar_filter(member, path) ++ ++ def relabel_selinux(self): ++ if not selinux_present(): ++ return ++ for inst in self.inst_list: ++ log.info("Performing SELinux labeling on instance {inst.serverid} ...") ++ dse = DSEldif(inst) ++ ++ selinux_attr_labels = { ++ (DN_CONFIG, 'nsslapd-bakdir'): 'dirsrv_var_lib_t', ++ (DN_CONFIG, 'nsslapd-certdir'): 'dirsrv_config_t', ++ (DN_CONFIG, 'nsslapd-ldifdir'): 'dirsrv_var_lib_t', ++ (DN_CONFIG, 'nsslapd-lockdir'): 'dirsrv_var_lock_t', ++ (DN_CONFIG, 'nsslapd-rundir'): 'dirsrv_var_run_t', ++ (DN_CONFIG, 'nsslapd-schemadir'): 'dirsrv_config_t', ++ (DN_CONFIG, 'nsslapd-tmpdir'): 'tmp_t', ++ (DN_CONFIG_LDBM, 'nsslapd-db-home-directory'): 'dirsrv_tmpfs_t', ++ (DN_CONFIG_LDBM, 'nsslapd-directory'): 'dirsrv_var_lib_t', ++ } ++ # Generates the path -> label dict ++ selinux_labels = { dse.get(pair[0], pair[1], single=True) : label for pair,label in selinux_attr_labels.items() } ++ log_dir = os.path.dirname(dse.get(DN_CONFIG, 'nsslapd-accesslog', single=True)) ++ selinux_attr_labels[log_dir] = 'dirsrv_var_log_t' ++ if os.path.isdir('/run/dirsrv'): ++ selinux_attr_labels['/run/dirsrv'] = 'dirsrv_var_run_t' ++ ++ for path, label in selinux_labels.items(): ++ with suppress(ValueError): ++ selinux_label_file(resolve_selinux_path(str(path)), label) ++ ++ for port_attr in ( 'nsslapd-port', 'nsslapd-securePort' ): ++ port = dse.get(DN_CONFIG, port_attr, single=True) ++ if port is None or port == '0': ++ continue ++ selinux_label_port(port) ++ ++ def dirsrv_instances(self, ignore_errors=False): ++ inst_list = [] ++ for name in self.names: ++ inst = DirSrv(verbose=DEBUGGING, external_log=log) ++ try: ++ inst.local_simple_allocate(name, binddn=DN_DM, password=PW_DM) ++ except FileNotFoundError as ex: ++ if ignore_errors is not True: ++ raise ex ++ continue ++ inst.setup_ldapi() ++ inst_list.append(inst) ++ nss = NssSsl(dirsrv=inst) ++ nss.openssl_rehash(nss._certdb) ++ return inst_list ++ ++ ++ def extract_instances(self): ++ with tarfile.open(name=TARFILENAME, mode='r:gz') as tar: ++ tar.extractall(path=self.idir, filter=self.tar_filter) ++ ++ # Fix the dse.ldif ++ for name in self.names: ++ self.remap_dse(f'{self.idir}/etc/dirsrv/slapd-{name}/dse.ldif') ++ ++ # Create missing directories ++ os.makedirs(f'{self.idir}/var/log/dirsrv/slapd-supplier1', mode=0o750, exist_ok=True) ++ os.makedirs(f'{self.idir}/var/log/dirsrv/slapd-supplier2', mode=0o750, exist_ok=True) ++ os.makedirs(f'{self.idir}/run/lock/dirsrv/slapd-supplier1', mode=0o750, exist_ok=True) ++ os.makedirs(f'{self.idir}/run/lock/dirsrv/slapd-supplier2', mode=0o750, exist_ok=True) ++ os.makedirs(f'{self.idir}/var/lib/dirsrv/slapd-supplier1/ldif', mode=0o750, exist_ok=True) ++ os.makedirs(f'{self.idir}/var/lib/dirsrv/slapd-supplier2/ldif', mode=0o750, exist_ok=True) ++ os.makedirs(f'{self.idir}/run/dirsrv', mode=0o770, exist_ok=True) ++ ++ # Generate DirSrv instances ++ self.inst_list = self.dirsrv_instances() ++ ++ # Relabel ++ if self.uid == 0: ++ self.relabel_selinux() ++ ++ ++ def remove_instances(self): ++ for inst in self.dirsrv_instances(ignore_errors=True): ++ inst.delete() ++ ++ ++ def migrate2mdb(self): ++ args = FakeArgs() ++ args.tmpdir = None ++ for inst in self.inst_list: ++ log.info(f'Migrating instance {inst.serverid} from bdb to mdb') ++ dblib_bdb2mdb(inst, log, args) ++ inst.start() ++ inst.open() ++ self.reset_agmt_passwords() ++ ++ ++ def reset_agmt_passwords(self): ++ pw = password_generate() ++ ++ for inst in self.inst_list: ++ # For some reason inst.sslport is None although nsslapd-securePort is defined ++ for service in ServiceAccounts(inst, DEFAULT_SUFFIX).list(): ++ service.replace('userPassword', pw) ++ replica = Replicas(inst).list()[0] ++ for agmt in replica.get_agreements().list(): ++ agmt.replace('nsds5ReplicaCredentials', pw) ++ del pw ++ ++ ++def strip_path(path): ++ return re.match(r'^/*([^/].*)$', path).group(1) ++ ++ ++@pytest.mark.skipif(get_default_db_lib() != "bdb", reason = f'Requires bdb mode') ++@pytest.mark.skipif(os.getenv(GENTARBALL) is None, reason = f'Requires setting {GENTARBALL} environment variable') ++def test_generate_tarball(topo_m2): ++ """Test Generate the tarball for test_upgradefrombdb ++ ++ :id: 0325c4fe-da66-11ef-98fc-482ae39447e5 ++ :setup: two suppliers ++ :steps: ++ 1. Check that replication is working ++ 2. Generaters the tarball ++ :expectedresults: ++ 1. Success ++ 2. Success ++ """ ++ idir = os.getenv("PREFIX", "/") ++ repl = ReplicationManager(DEFAULT_SUFFIX) ++ for i1,i2 in permutations(topo_m2, 2): ++ log.info(f'Testing replication {i1.serverid} --> {i2.serverid}') ++ repl.test_replication(i1, i2) ++ for inst in topo_m2: ++ inst.stop() ++ tardir = Path(TARFILENAME).parent ++ os.makedirs(tardir, mode = 0o755, exist_ok = True) ++ this_dir = os.getcwd() ++ with tarfile.open(name=TARFILENAME, mode='w:gz') as tar: ++ os.chdir(idir) ++ for inst in topo_m2: ++ name = inst.serverid ++ tar.add(strip_path(f'/etc/dirsrv/slapd-{name}')) ++ tar.add(strip_path(f'/var/lib/dirsrv/slapd-{name}/db')) ++ os.chdir(this_dir) ++ for inst in topo_m2: ++ inst.start() ++ ++ ++@pytest.mark.skipif(get_bdb_impl_status() != BDB_IMPL_STATUS.READ_ONLY, reason = 'Already tested through clu/dsctl_dblib_test.py:test_dblib_migration') ++def test_upgradefrombdb(): ++ """Test upgrade from bdb to mdb ++ ++ :id: f0f02d12-da4f-11ef-966f-482ae39447e5 ++ :setup: None ++ :steps: ++ 1. Extract bdb instances from the tar ball ++ 2. Migrate the instances to mdb ++ 3. Check that replication is still working ++ :expectedresults: ++ 1. Success ++ 2. Success ++ 3. Success ++ """ ++ ++ handler = MigrationHandler() ++ handler.remove_instances() ++ handler.extract_instances() ++ handler.migrate2mdb() ++ repl = ReplicationManager(DEFAULT_SUFFIX) ++ for i1,i2 in permutations(handler.inst_list, 2): ++ log.info(f'Testing replication {i1.serverid} --> {i2.serverid}') ++ repl.test_replication(i1, i2) ++ handler.remove_instances() ++ ++if __name__ == '__main__': ++ # Run isolated ++ # -s for DEBUG mode ++ pytest.main(["-s", CURRENT_FILE]) ++ +diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_bdbreader_db.h b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_bdbreader_db.h +new file mode 100644 +index 000000000..f50d961e9 +--- /dev/null ++++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_bdbreader_db.h +@@ -0,0 +1,289 @@ ++/** BEGIN COPYRIGHT BLOCK ++ * Copyright (C) 2024 Red Hat, Inc. ++ * All rights reserved. ++ * ++ * License: GPL (version 3 or any later version). ++ * See LICENSE for details. ++ * END COPYRIGHT BLOCK **/ ++ ++/* ++ * This file provides the part of the Berkeley Datatabase 5.3 API ++ * definition that are refered within 389-ds-base project ++ */ ++ ++#ifndef DB_H_ ++#define DB_H_ ++ ++/* Needed for configure */ ++#define DB_VERSION_MAJOR 5 ++#define DB_VERSION_MINOR 3 ++#define DB_VERSION_PATCH 280 ++ ++ ++#define DB_INIT_MPOOL 0x000001 ++#define DB_INIT_TXN 0x000002 ++#define DB_INIT_LOG 0x000004 ++#define DB_INIT_LOCK 0x000008 ++#define DB_REGION_INIT 0x000010 ++#define DB_FREE_SPACE 0x000020 ++#define DB_FREELIST_ONLY 0x000040 ++#define DB_TXN_NOWAIT 0x000080 ++#define DB_ARCH_ABS 0x000100 ++#define DB_ARCH_LOG 0x000200 ++#define DB_RDONLY 0x000400 ++#define DB_STAT_CLEAR 0x000800 ++ ++ ++ ++#define DB_DUP 0x000100 ++#define DB_DUPSORT 0x000200 ++#define DB_RECNUM 0x000400 ++#define DB_FORCE 0x000800 ++#define DB_SYSTEM_MEM 0x001000 ++#define DB_THREAD 0x002000 ++#define DB_CREATE 0x004000 ++#define DB_PRIVATE 0x008000 ++#define DB_MULTIPLE_KEY 0x010000 ++#define DB_MULTIPLE 0x020000 ++#define DB_RMW 0x040000 ++#define DB_RECOVER 0x080000 ++#define DB_TXN_WRITE_NOSYNC 0x100000 ++#define DB_AUTO_COMMIT 0x200000 ++#define DB_RECOVER_FATAL 0x400000 ++#define DB_LOCKDOWN 0x800000 ++#define DB_TRUNCATE 0x1000000 ++#define XDB_RECOVER 0x000000 ++ ++enum { ++ DB_FIRST = 1, ++ DB_CURRENT, ++ DB_GET_BOTH, ++ DB_GET_BOTH_RANGE, ++ DB_GET_RECNO, ++ DB_LAST, ++ DB_NEXT, ++ DB_NEXT_DUP, ++ DB_NEXT_NODUP, ++ DB_NODUPDATA, ++ DB_PREV, ++ DB_SET, ++ DB_SET_RANGE, ++ DB_SET_RECNO, ++ DB_UNKNOWN, ++ ++}; ++ ++ ++ ++#define OPEN_FLAGS_CLOSED 0x58585858 ++#define OPEN_FLAGS_OPEN 0xdbdbdbdb ++ ++#define DB_DBT_USERMEM 1 ++#define DB_DBT_MALLOC 2 ++#define DB_DBT_REALLOC 4 ++ ++#define DB_MULTIPLE_INIT(pointer, dbt) ++#define DB_MULTIPLE_NEXT(pointer, dbt, retdata, retdlen) ++#define DB_MULTIPLE_KEY_NEXT(pointer, dbt, retkey, retklen, retdata, retdlen) ++ ++typedef enum { ++ DB_SUCCESS, ++ DB_NOTFOUND, /* Should be 1 because btree_next returns 1 when there are no more records */ ++ DB_BUFFER_SMALL, ++ DB_KEYEXIST, ++ DB_RUNRECOVERY, ++ DB_NOTSUPPORTED, ++ DB_LOCK_DEADLOCK, ++ DB_OSERROR, ++} db_error_t; ++ ++enum { ++ DB_LOCK_DEFAULT, ++ DB_LOCK_NORUN, ++ DB_VERB_DEADLOCK, ++ DB_VERB_RECOVERY, ++ DB_VERB_WAITSFOR, ++}; ++ ++/* DB_LOCK_YOUNGEST mustt be a define because it is used in STRINGIFYDEFINE */ ++#define DB_LOCK_YOUNGEST 9 ++ ++typedef struct db DB; ++typedef struct db_env DB_ENV; ++typedef struct db_txn DB_TXN; ++typedef struct db_cursor DBC; ++ ++typedef enum { ++ DB_BTREE, ++ DB_HASH, ++ DB_RECNO, ++} DBTYPE; ++ ++typedef struct { ++ int compact_pages_free; ++} DB_COMPACT; ++ ++typedef struct { ++ int st_nactive; ++ int st_ncommits; ++ int st_naborts; ++ int st_region_wait; ++} DB_TXN_STAT; ++ ++typedef struct { ++ int st_maxnlocks; ++ int st_ndeadlocks; ++ int st_nlockers; ++ int st_region_wait; ++ int st_w_bytes; ++ int st_wc_bytes; ++ int st_wc_mbytes; ++ int st_w_mbytes; ++ ++} DB_LOG_STAT; ++ ++typedef struct { ++ int st_bytes; ++ int st_cache_hit; ++ int st_cache_miss; ++ int st_gbytes; ++ int st_hash_buckets; ++ int st_hash_longest; ++ int st_hash_searches; ++ int st_page_create; ++ int st_page_in; ++ int st_page_out; ++ int st_ro_evict; ++ int st_rw_evict; ++ int st_page_dirty; ++ int st_pagesize; ++ int st_page_clean; ++ int st_page_trickle; ++ int st_hash_examined; ++ int st_region_wait; ++ ++ ++} DB_MPOOL_STAT; ++ ++typedef struct { ++ int bt_ndata; ++} DB_BTREE_STAT; ++ ++typedef struct { ++ int st_nlocks; ++ int st_maxlocks; ++ int st_region_wait; ++ int st_ndeadlocks; ++ int st_maxnlocks; ++ int st_nlockers; ++ int st_lock_wait; ++ int st_nobjects; ++ int st_maxnobjects; ++ int st_nrequests; ++ ++} DB_LOCK_STAT; ++ ++typedef struct { ++ char *file_name; ++ int st_page_in; ++ int st_page_out; ++ int st_cache_hit; ++ int st_cache_miss; ++} DB_MPOOL_FSTAT; ++ ++typedef struct dbt { ++ u_int32_t flags; ++ u_int32_t size; ++ u_int32_t ulen; ++ void *data; ++} DBT; ++ ++ ++struct db_cursor { ++ DB *dbp; ++ int (*c_close)(DBC *); ++ int (*c_del)(DBC *, u_int32_t); ++ int (*c_get)(DBC *, DBT*, DBT*, u_int32_t); ++ int (*c_put)(DBC *, DBT*, DBT*, u_int32_t); ++ int (*c_count)(DBC *, void *, u_int32_t); ++ /* fields only used by the implementation */ ++ void *impl; ++}; ++ ++struct db_txn { ++ int (*id)(DB_TXN*); ++ int (*commit)(DB_TXN*, u_int32_t); ++ int (*abort)(DB_TXN*); ++}; ++ ++struct db_env { ++ int (*close)(DB_ENV*, int); ++ int (*lock_detect)(DB_ENV*, int, int, int*); ++ int (*open)(DB_ENV*, const char*, int, int); ++ int (*remove)(DB_ENV *, const char *, u_int32_t); ++ int (*set_flags)(DB_ENV*, u_int32_t, u_int32_t); ++ int (*set_verbose)(DB_ENV *, u_int32_t, int); ++ int (*txn_checkpoint)(const DB_ENV *, u_int32_t , u_int32_t , u_int32_t); ++ int (*txn_begin)(DB_ENV *, DB_TXN *, DB_TXN **, u_int32_t); ++ void (*get_open_flags)(DB_ENV*, u_int32_t*); ++ void (*mutex_set_tas_spins)(DB_ENV *, u_int32_t); ++ void (*set_alloc)(DB_ENV *, void *, void *, void*); ++ void (*set_cachesize)(DB_ENV *, u_int32_t , u_int32_t , int); ++ void (*set_data_dir)(DB_ENV *, const char *); ++ void (*set_errcall)(DB_ENV *, void (*)(const DB_ENV *, const char *, const char *)); ++ void (*set_errpfx)(DB_ENV *, const char *); ++ void (*set_lg_bsize)(DB_ENV *, long); ++ void (*set_lg_dir)(DB_ENV *, const char*); ++ void (*set_lg_max)(DB_ENV *, u_int32_t); ++ void (*set_lg_regionmax)(DB_ENV *, u_int32_t); ++ void (*set_lk_max_lockers)(DB_ENV *, u_int32_t); ++ void (*set_lk_max_locks)(DB_ENV *, u_int32_t); ++ void (*set_lk_max_objects)(DB_ENV *, u_int32_t); ++ void (*set_shm_key)(DB_ENV *, long); ++ void (*set_tx_max)(DB_ENV *, u_int32_t); ++ void (*log_flush)(DB_ENV *, u_int32_t); ++ int (*lock_stat)(DB_ENV *, DB_LOCK_STAT**, u_int32_t); ++ int (*log_archive)(DB_ENV *, void*, u_int32_t); ++ int (*memp_stat)(DB_ENV *, void*, void *, u_int32_t); ++ int (*memp_trickle)(DB_ENV *, u_int32_t, int*); ++ int (*dbrename)(DB_ENV *, DB_TXN *, const char *, const char *, const char *, u_int32_t); ++ int (*stat)(DB_ENV *, DB_TXN *, void *, u_int32_t); ++ int (*log_stat)(DB_ENV *, DB_LOG_STAT **, u_int32_t); ++ int (*txn_stat)(DB_ENV *, DB_TXN_STAT **, u_int32_t); ++ /* fields only used by the implementation */ ++ char *db_home; ++}; ++ ++struct db { ++ int (*close)(DB*, u_int32_t); ++ int (*compact)(DB*, DB_TXN*, DBT*, DBT*, void *, u_int32_t, DBT*); ++ int (*cursor)(DB*, DB_TXN*, DBC**, u_int32_t); ++ int (*del)(DB*, DB_TXN*, DBT*, u_int32_t); ++ int (*get)(DB*, DB_TXN*, DBT*, DBT*, u_int32_t); ++ int (*get_type)(DB *, DBTYPE *); ++ int (*open)(DB*, DB_TXN*, const char*, const char *, DBTYPE, u_int32_t, int); ++ int (*put)(DB*, DB_TXN*, DBT*, DBT*, u_int32_t); ++ int (*remove)(DB*, const char*, const char*, u_int32_t); ++ int (*rename)(DB*, const char*, const char*, const char*, u_int32_t); ++ int (*set_bt_compare)(DB*, int (*)(DB *, const DBT *, const DBT *)); ++ int (*set_dup_compare)(DB*, int (*)(DB *, const DBT *, const DBT *)); ++ int (*set_flags)(DB*, u_int32_t); ++ int (*set_pagesize)(DB *, u_int32_t); ++ int (*stat)(DB *, DB_TXN *, void *, u_int32_t); ++ int (*verify)(DB *, const char *, const char *, FILE *, u_int32_t); ++ void *app_private; ++ u_int32_t open_flags; ++ char *fname; ++ int pgsize; ++ /* fields only used by the implementation */ ++ void *impl; ++ DB_ENV *env; ++ DBC *cur; ++}; ++ ++char * db_version(int *major, int *minor, int *patch); ++int db_env_create(DB_ENV **, u_int32_t); ++int db_create(DB **, DB_ENV *, u_int32_t); ++char *db_strerror(int); ++ ++#endif /* DB_H_ */ +diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_bdbreader_glue.c b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_bdbreader_glue.c +new file mode 100644 +index 000000000..7e8e7861a +--- /dev/null ++++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_bdbreader_glue.c +@@ -0,0 +1,519 @@ ++/** BEGIN COPYRIGHT BLOCK ++ * Copyright (C) 2024 Red Hat, Inc. ++ * All rights reserved. ++ * ++ * License: GPL (version 3 or any later version). ++ * See LICENSE for details. ++ * END COPYRIGHT BLOCK **/ ++ ++#include "bdb_layer.h" ++#include ++ ++int db_close(DB *, u_int32_t); ++ ++/* ++ * This file contains the stub that transform usual bdb API (limited to the function 389-ds needs to export a db and a changelog ++ * to bdb_ro callbacks ++ */ ++ ++#undef slapi_log_err ++ ++#define LOGK(k) (((k)&&(k)->data && (k)->size) ? (k)->data : "") ++#define LOGN(v, names) (((v)> sizeof names/sizeof names[0]) ? "Unexpected value" : names[v]) ++ ++int db_cursor(DB *db, DB_TXN *txnid, DBC **cursorp, u_int32_t flags); ++int dbc_close(DBC *dbc); ++ ++void slapi_log_err(int loglvl, char *module, char *msg, ...) { ++#ifdef DEBUG ++ static FILE *fd = NULL; ++ va_list ap; ++ va_start(ap, msg); ++ if (fd == NULL) { ++ fd = fopen("/tmp/mylog", "w"); ++ } ++ fprintf(fd, "[%s]:%d ", module, loglvl); ++ vfprintf(fd, msg, ap); ++ fflush(fd); ++#endif ++} ++ ++/* ++ * Dump a memory buffer in hexa and ascii in error log ++ * ++ * addr - The memory buffer address. ++ * len - The memory buffer lenght. ++ */ ++void ++hexadump(char *msg, const void *addr, size_t offset, size_t len) ++{ ++#ifdef DEBUG ++#define HEXADUMP_TAB 4 ++/* 4 characters per bytes: 2 hexa digits, 1 space and the ascii */ ++#define HEXADUMP_BUF_SIZE (4*16+HEXADUMP_TAB) ++ char hexdigit[] = "0123456789ABCDEF"; ++ ++ const unsigned char *pt = addr; ++ char buff[HEXADUMP_BUF_SIZE+1]; ++ memset (buff, ' ', HEXADUMP_BUF_SIZE); ++ buff[HEXADUMP_BUF_SIZE] = '\0'; ++ while (len > 0) { ++ int dpl; ++ for (dpl = 0; dpl < 16 && len>0; dpl++, len--) { ++ buff[3*dpl] = hexdigit[((*pt) >> 4) & 0xf]; ++ buff[3*dpl+1] = hexdigit[(*pt) & 0xf]; ++ buff[3*16+HEXADUMP_TAB+dpl] = (*pt>=0x20 && *pt<0x7f) ? *pt : '.'; ++ pt++; ++ } ++ for (;dpl < 16; dpl++) { ++ buff[3*dpl] = ' '; ++ buff[3*dpl+1] = ' '; ++ buff[3*16+HEXADUMP_TAB+dpl] = ' '; ++ } ++ slapi_log_err(0, msg, "[0x%08lx] %s\n", offset, buff); ++ offset += 16; ++ } ++#endif ++} ++ ++char *db_version(int *major, int *minor, int *patch) ++{ ++ static char version[200]; ++ sprintf(version, "Read-Only Berkeley Database Stub %d.%d.%d", DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH); ++ if (major != NULL) { ++ *major = DB_VERSION_MAJOR; ++ } ++ if (minor != NULL) { ++ *minor = DB_VERSION_MINOR; ++ } ++ if (patch != NULL) { ++ *patch = DB_VERSION_PATCH; ++ } ++ return version; ++} ++ ++int nothing() ++{ ++ return DB_SUCCESS; ++} ++ ++/* ++ * Define libbdbreader callbacks ++ * Note: slapi_ch_calloc, slapi_ch_malloc, slapi_ch_realloc ++ * are not directly used because their prototype is ++ * slightl ++ * slapi_ch_calloc are slithly different ++ */ ++void* bdbreader_calloc(size_t nbelmt, size_t size) ++{ ++ return slapi_ch_calloc(nbelmt, size); ++} ++ ++/* ++ * Redefines all the callback because bdbreader_malloc and ++ * slapi_ch_malloc prototypes are slithly different ++ */ ++void* bdbreader_malloc(size_t size) ++{ ++ return slapi_ch_malloc(size); ++} ++ ++void* bdbreader_realloc(void* pt, size_t size) ++{ ++ return slapi_ch_realloc(pt, size); ++} ++ ++static void bdbreader_free(void **pt) ++{ ++ slapi_ch_free(pt); ++} ++ ++static void bdbreader_log(const char *msg, ...) ++{ ++ char buffer[512]; ++ va_list ap; ++ ++ va_start(ap, msg); ++ PR_vsnprintf(buffer, (sizeof buffer), msg, ap); ++ va_end(ap); ++ slapi_log_err(SLAPI_LOG_ERR, "libbdbreader", "%s", buffer); ++} ++ ++int dbenv_open(DB_ENV *dbenv, const char *db_home, int flags, int mode) ++{ ++ if (dbenv->db_home == NULL) { ++ /* If not set by dbenv->set_dir_lg() */ ++ dbenv->db_home = slapi_ch_strdup(db_home); ++ } ++ /* Initialize libbdbreader callbacks */ ++ bdbreader_set_calloc_cb(bdbreader_calloc); ++ bdbreader_set_malloc_cb(bdbreader_malloc); ++ bdbreader_set_realloc_cb(bdbreader_realloc); ++ bdbreader_set_free_cb(bdbreader_free); ++ bdbreader_set_log_cb(bdbreader_log); ++ return DB_SUCCESS; ++} ++ ++int dbenv_close(DB_ENV *dbenv, int flags) ++{ ++ slapi_ch_free_string(&dbenv->db_home); ++ slapi_ch_free((void**)&dbenv); ++ return DB_SUCCESS; ++} ++ ++char *db_strerror(int err) ++{ ++ switch (err) { ++ case DB_SUCCESS: ++ return (char*)"DB_SUCCESS"; ++ case DB_LOCK_DEADLOCK: ++ return (char*)"DB_LOCK_DEADLOCK"; ++ case DB_NOTFOUND: ++ return (char*)"DB_NOTFOUND"; ++ case DB_BUFFER_SMALL: ++ return (char*)"DB_BUFFER_SMALL"; ++ case DB_KEYEXIST: ++ return (char*)"DB_KEYEXIST"; ++ case DB_RUNRECOVERY: ++ return (char*)"DB_RUNRECOVERY"; ++ case DB_NOTSUPPORTED: ++ return (char*)"DB_NOTSUPPORTED"; ++ default: ++ return (char*)"Unknonwn error"; ++ } ++} ++ ++/* lg_dir is used to store the database directory */ ++static void ++db_set_lg_dir(DB_ENV *penv, const char *lg_dir) ++{ ++ penv->db_home = slapi_ch_strdup(lg_dir); ++} ++ ++int db_env_create(DB_ENV **penv, u_int32_t flags) ++{ ++ DB_ENV *env = (void*)slapi_ch_calloc(1, sizeof *env); ++ ++ env->close = dbenv_close; ++ env->lock_detect = (void*)nothing; ++ env->open = dbenv_open; ++ env->remove = (void*)nothing; ++ env->set_flags = (void*)nothing; ++ env->set_verbose = (void*)nothing; ++ env->txn_checkpoint = (void*)nothing; ++ env->txn_begin = (void*)nothing; ++ env->get_open_flags = (void*)nothing; ++ env->mutex_set_tas_spins = (void*)nothing; ++ env->set_alloc = (void*)nothing; ++ env->set_cachesize = (void*)nothing; ++ env->set_data_dir = (void*)nothing; ++ env->set_errcall = (void*)nothing; ++ env->set_errpfx = (void*)nothing; ++ env->set_lg_bsize = (void*)nothing; ++ env->set_lg_dir = db_set_lg_dir; ++ env->set_lg_max = (void*)nothing; ++ env->set_lg_regionmax = (void*)nothing; ++ env->set_lk_max_lockers = (void*)nothing; ++ env->set_lk_max_locks = (void*)nothing; ++ env->set_lk_max_objects = (void*)nothing; ++ env->set_shm_key = (void*)nothing; ++ env->set_tx_max = (void*)nothing; ++ env->log_flush = (void*)nothing; ++ env->lock_stat = (void*)nothing; ++ env->log_archive = (void*)nothing; ++ env->memp_stat = (void*)nothing; ++ env->memp_trickle = (void*)nothing; ++ env->dbrename = (void*)nothing; ++ env->stat = (void*)nothing; ++ env->log_stat = (void*)nothing; ++ env->txn_stat = (void*)nothing; ++ *penv = env; ++ return DB_SUCCESS; ++} ++ ++int db_open(DB *db, DB_TXN *txnid, const char *file, ++ const char *database, DBTYPE type, u_int32_t flags, int mode) ++{ ++ slapi_log_err(SLAPI_LOG_INFO, "bdb_ro", "%s: db=%p txnid=%p file=%s database=%s " ++ "type=0x%x flags=0x%x mode=0x%x\n", __FUNCTION__, db, ++ txnid, file, database, type, flags, mode); ++ if (*file == '/') { ++ db->fname = slapi_ch_strdup(file); ++ } else { ++ slapi_log_err(SLAPI_LOG_ERR, "bdb_ro", ++ "%s: db_home=%s\n", __FUNCTION__, db->env->db_home); ++ db->fname = slapi_ch_smprintf("%s/%s", db->env->db_home, file); ++ } ++ slapi_log_err(SLAPI_LOG_ERR, "bdb_ro", "%s: db->fname=%s\n", __FUNCTION__, db->fname); ++ db->impl = bdbreader_bdb_open(db->fname); ++ db->open_flags = OPEN_FLAGS_OPEN; ++ if (db->impl) { ++ if (db_cursor(db, NULL, &db->cur, 0) != DB_SUCCESS) { ++ slapi_log_err(SLAPI_LOG_ERR, "bdb_ro", ++ "%s: Failed to create cursor for %s database\n", ++ __FUNCTION__, db->fname); ++ db_close(db, flags); ++ return DB_OSERROR; ++ } ++ return DB_SUCCESS; ++ } ++ slapi_log_err(SLAPI_LOG_ERR, "bdb_ro", ++ "%s: Failed to open %s database\n", __FUNCTION__, db->fname); ++ return DB_OSERROR; ++} ++ ++int db_close(DB *db, u_int32_t flags) ++{ ++ bdbreader_bdb_close((struct bdb_db **)&db->impl); ++ db->impl = NULL; ++ db->open_flags = OPEN_FLAGS_CLOSED; ++ dbc_close(db->cur); ++ slapi_ch_free_string(&db->fname); ++ slapi_ch_free((void**)&db); ++ return DB_SUCCESS; ++} ++ ++int dbc_close(DBC *dbc) ++{ ++ slapi_log_err(SLAPI_LOG_INFO, "bdb_ro", "%s: dbc=%p dbc->impl=%p\n", __FUNCTION__, dbc, dbc->impl); ++ bdbreader_cur_close((struct bdb_cur **)&dbc->impl); ++ slapi_ch_free((void **)&dbc); ++ return DB_SUCCESS; ++} ++ ++int dbc_del(DBC *dbc, u_int32_t flags) ++{ ++ return DB_NOTSUPPORTED; ++} ++ ++int copy_val(const DBT *from, DBT *to) ++{ ++ switch (to->flags) { ++ case DB_DBT_MALLOC: ++ to->size = from->size; ++ if (from->data == NULL) { ++ to->data = NULL; ++ } else if (from->size > 0) { ++ to->data = slapi_ch_malloc(from->size); ++ memcpy(to->data, from->data, from->size); ++ } ++ return DB_SUCCESS; ++ case DB_DBT_REALLOC: ++ to->size = from->size; ++ if (from->data == NULL) { ++ to->data = NULL; ++ } else if (from->size > 0) { ++ to->data = slapi_ch_realloc(to->data, from->size); ++ memcpy(to->data, from->data, from->size); ++ } ++ return DB_SUCCESS; ++ case DB_DBT_USERMEM: ++ to->size = from->size; ++ if (from->size > to->ulen) { ++ return DB_BUFFER_SMALL; ++ } ++ memcpy(to->data, from->data, from->size); ++ return DB_SUCCESS; ++ } ++ return DB_NOTSUPPORTED; ++} ++ ++ ++int store_val(int rc, DBC *dbc, DBT *key, DBT *data) ++{ ++ DBT k1 = {0}; ++ DBT d1 = {0}; ++ ++ if (rc == DB_SUCCESS) { ++ rc = bdbreader_cur_getcurval(dbc->impl, &k1.data, &k1.size, &d1.data, &d1.size); ++ } ++ if (rc == DB_SUCCESS) { ++ rc = copy_val(&k1, key); ++ } ++ if (rc == DB_SUCCESS) { ++ rc = copy_val(&d1, data); ++ } ++ return rc; ++} ++ ++ ++int dbc_get(DBC *dbc, DBT *key, DBT *data, u_int32_t flags) ++{ ++ static const char *flagnames[] = { ++ "0", "DB_FIRST", "DB_CURRENT", "DB_GET_BOTH", "DB_GET_BOTH_RANGE", ++ "DB_GET_RECNO", "DB_LAST", "DB_NEXT", "DB_NEXT_DUP", "DB_NEXT_NODUP", ++ "DB_NODUPDATA", "DB_PREV", "DB_SET", "DB_SET_RANGE", "DB_SET_RECNO", ++ "DB_UNKNOWN" }; ++ static const char *errname[] = { ++ "DB_SUCCESS", "DB_NOTFOUND", "DB_BUFFER_SMALL", ++ "DB_KEYEXIST", "DB_RUNRECOVERY", "DB_NOTSUPPORTED", "DB_LOCK_DEADLOCK", "DB_OSERROR" }; ++ ++ slapi_log_err(SLAPI_LOG_ERR, "bdb_ro", "==> dbc_get(key=%s flags=%d:%s)\n", LOGK(key), flags, LOGN(flags, flagnames)); ++ ++ int rc = DB_NOTSUPPORTED; ++ DBT k1 = {0}; ++ DBT d1 = {0}; ++ ++ switch (flags) { ++ case DB_FIRST: ++ rc = bdbreader_cur_lookup_ge(dbc->impl, NULL, 0); ++ if (rc == DB_NOTFOUND) { ++ rc = bdbreader_cur_next(dbc->impl); ++ } ++ rc = store_val(rc, dbc, key, data); ++ break; ++ case DB_CURRENT: ++ rc = store_val(rc, dbc, key, data); ++ break; ++ case DB_GET_BOTH: ++ break; ++ case DB_GET_BOTH_RANGE: ++ break; ++ case DB_GET_RECNO: ++ break; ++ case DB_LAST: ++ rc = DB_SUCCESS; ++ while (rc == DB_SUCCESS) { ++ rc = bdbreader_cur_next(dbc->impl); ++ if (rc == DB_SUCCESS) { ++ rc = bdbreader_cur_getcurval(dbc->impl, &k1.data, &k1.size, &d1.data, &d1.size); ++ } ++ if (rc == DB_NOTFOUND) { ++ rc = copy_val(&k1, key) | copy_val(&d1, data); ++ break; ++ } ++ } ++ break; ++ case DB_NEXT: ++ rc = bdbreader_cur_next(dbc->impl); ++ rc = store_val(rc, dbc, key, data); ++ break; ++ case DB_NEXT_DUP: ++ rc = bdbreader_cur_next(dbc->impl); ++ if (rc == DB_SUCCESS) { ++ rc = bdbreader_cur_getcurval(dbc->impl, &k1.data, &k1.size, NULL, NULL); ++ if (rc == DB_SUCCESS) { ++ if (k1.size == key->size && memcmp(k1.data, key->data, k1.size) == 0) { ++ rc = store_val(rc, dbc, key, data); ++ } else { ++ rc = DB_NOTFOUND; ++ } ++ } ++ } ++ break; ++ case DB_NEXT_NODUP: ++ rc = DB_SUCCESS; ++ while (rc == DB_SUCCESS) { ++ rc = bdbreader_cur_next(dbc->impl); ++ if (rc == DB_SUCCESS) { ++ rc = bdbreader_cur_getcurval(dbc->impl, &k1.data, &k1.size, NULL, NULL); ++ } ++ if (k1.size != key->size || memcmp(k1.data, key->data, k1.size) != 0) { ++ rc = store_val(rc, dbc, key, data); ++ break; ++ } ++ } ++ break; ++ case DB_NODUPDATA: ++ break; ++ case DB_PREV: ++ break; ++ case 0: ++ /* _get_and_add_parent_rdns set the flags ==> probably a bug ++ * (according BDB C API) ++ * But lets assume it is a DB_SET ++ */ ++ case DB_SET: ++ rc = bdbreader_cur_lookup(dbc->impl, key->data, key->size); ++ rc = store_val(rc, dbc, key, data); ++ break; ++ case DB_SET_RANGE: ++ rc = bdbreader_cur_lookup_ge(dbc->impl, key->data, key->size); ++ rc = store_val(rc, dbc, key, data); ++ break; ++ case DB_SET_RECNO: ++ break; ++ } ++ ++ slapi_log_err(SLAPI_LOG_ERR, "bdb_ro", "==> dbc_get(flags=%d:%s) rc=%d:%s\n", ++ flags, LOGN(flags, flagnames), rc, LOGN(rc, errname)); ++ if (key && key->data && key->size) { ++ hexadump("Key", key->data, 0, key->size); ++ } ++ if (data && data->data && data->size) { ++ hexadump("Data", data->data, 0, data->size); ++ } ++ return rc; ++} ++ ++int dbc_put(DBC *dbc, DBT *key, DBT *data, u_int32_t flags) ++{ ++ return DB_NOTSUPPORTED; ++} ++ ++int dbc_count(DBC *dbc, void *countp, u_int32_t flags) ++{ ++ return DB_NOTSUPPORTED; ++} ++ ++int db_cursor(DB *db, DB_TXN *txnid, DBC **cursorp, u_int32_t flags) ++{ ++ DBC *dbc = (void*)slapi_ch_calloc(1, sizeof *dbc); ++ ++ *cursorp = dbc; ++ dbc->dbp = db; ++ ++ dbc->c_close = dbc_close; ++ dbc->c_del = dbc_del; ++ dbc->c_get = dbc_get; ++ dbc->c_put = dbc_put; ++ dbc->c_count = dbc_count; ++ dbc->impl = bdbreader_cur_open(db->impl); ++ ++ slapi_log_err(SLAPI_LOG_INFO, "bdb_ro", "%s: dbc=%p dbc->impl=%p\n", __FUNCTION__, dbc, dbc->impl); ++ return (db->impl == NULL) ? DB_OSERROR : DB_SUCCESS; ++} ++ ++int db_del(DB *db, DB_TXN *txnid, DBT *key, u_int32_t flags) ++{ ++ return DB_NOTSUPPORTED; ++} ++ ++int db_put(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags) ++{ ++ return DB_NOTSUPPORTED; ++} ++ ++int db_get(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags) ++{ ++ int rc = bdbreader_cur_lookup(db->cur->impl, key->data, key->size); ++ if (rc == DB_SUCCESS) { ++ rc = dbc_get(db->cur, key, data, flags); ++ } ++ return rc; ++} ++ ++int db_create(DB **pdb, DB_ENV *env, u_int32_t flags) ++{ ++ DB *db = (void*)slapi_ch_calloc(1, sizeof *db); ++ db->close = db_close; ++ db->compact = (void*)nothing; ++ db->cursor = db_cursor; ++ db->del = db_del; ++ db->get = db_get; ++ db->open = db_open; ++ db->put = db_put; ++ db->remove = (void*)nothing; ++ db->rename = (void*)nothing; ++ db->set_bt_compare = (void*)nothing; ++ db->set_dup_compare = (void*)nothing; ++ db->set_flags = (void*)nothing; ++ db->set_pagesize = (void*)nothing; ++ db->verify = (void*)nothing; ++ db->get_type = (void*)nothing; ++ db->stat = (void*)nothing; ++ db->env = env; ++ db->open_flags = OPEN_FLAGS_CLOSED; ++ *pdb = db; ++ return DB_SUCCESS; ++} +diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h +index 0be6cab49..24c4b0621 100644 +--- a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h ++++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h +@@ -10,7 +10,12 @@ + #include "../back-ldbm.h" + #include "../dblayer.h" + #include "../import.h" ++#ifdef WITH_LIBBDB_RO ++#include "bdb_bdbreader_db.h" ++#else + #include ++#endif ++ + + #define BDB_CONFIG(li) ((bdb_config *)(li)->li_dblayer_config) + +diff --git a/ldap/servers/slapd/back-ldbm/dbimpl.c b/ldap/servers/slapd/back-ldbm/dbimpl.c +index f3bf68a9f..f00779c3c 100644 +--- a/ldap/servers/slapd/back-ldbm/dbimpl.c ++++ b/ldap/servers/slapd/back-ldbm/dbimpl.c +@@ -454,6 +454,7 @@ int dblayer_private_open(const char *plgname, const char *dbfilename, int rw, Sl + li->li_plugin->plg_name = (char*) "back-ldbm-dbimpl"; + li->li_plugin->plg_libpath = (char*) "libback-ldbm"; + li->li_directory = get_li_directory(dbfilename); ++ li->li_flags = SLAPI_TASK_RUNNING_FROM_COMMANDLINE; + + /* Initialize database plugin */ + rc = dbimpl_setup(li, plgname); +@@ -541,6 +542,10 @@ dbi_dbslist_t *dblayer_list_dbs(const char *dbimpl_name, const char *dbhome) + li->li_plugin->plg_name = (char*) "back-ldbm-dbimpl"; + li->li_plugin->plg_libpath = (char*) "libback-ldbm"; + li->li_directory = slapi_ch_strdup(dbhome); ++ /* Set SLAPI_TASK_RUNNING_FROM_COMMANDLINE to tell that ++ * read-only bdb is usable with dbscan ++ */ ++ li->li_flags |= SLAPI_TASK_RUNNING_FROM_COMMANDLINE; + + /* Initialize database plugin */ + rc = dbimpl_setup(li, dbimpl_name); +diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c +index a47846c50..d45d5b0e4 100644 +--- a/ldap/servers/slapd/back-ldbm/dblayer.c ++++ b/ldap/servers/slapd/back-ldbm/dblayer.c +@@ -164,8 +164,21 @@ dblayer_init(struct ldbminfo *li) + return ret; + } + +- +- ++/* Check that export locking file is not set */ ++static bool ++not_exporting(void) ++{ ++ pid_t pid = getpid(); ++ struct stat astat; ++ bool res = true; ++ char *export_lock = slapi_ch_smprintf("%s/exports/%d", getFrontendConfig()->lockdir, pid); ++ if (stat(export_lock, &astat) == 0) { ++ res = false; ++ } ++ slapi_ch_free_string(&export_lock); ++ return res; ++} ++ + /* Get the db implementation plugin path (either libback-ldbm.so or libback-bdb.so) */ + char * + backend_implement_get_libpath(struct ldbminfo *li, const char *plgname) +@@ -177,6 +190,19 @@ backend_implement_get_libpath(struct ldbminfo *li, const char *plgname) + /* mdb ==> lets use default (libback-ldbm.so) */ + return li->li_plugin->plg_libpath; + } ++ if (PR_FindSymbolAndLibrary("bdbreader_bdb_open", &lib)) { ++ /* read-only bdb is used ==> should be using dbscan or ns-slapd db2ldif ++ * bdb_init is within libback-ldbm.so ==> lets use default (libback-ldbm.so) ++ */ ++ if (((li->li_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE) == 0) && not_exporting()) { ++ slapi_log_error(SLAPI_LOG_FATAL, "dblayer_setup", ++ "bdb implementation is no longer supported." ++ " Directory server cannot be started without migrating to lmdb first." ++ " To migrate, please run: dsctl instanceName dblib bdb2mdb\n"); ++ exit(1); ++ } ++ return li->li_plugin->plg_libpath; ++ } + if (PR_FindSymbolAndLibrary("bdb_init", &lib)) { + /* bdb_init is within libback-ldbm.so ==> lets use default (libback-ldbm.so) */ + return li->li_plugin->plg_libpath; +@@ -1462,9 +1488,9 @@ dblayer_is_lmdb(Slapi_Backend *be) + } + + /* +- * Iterate on the provided curor starting at startingkey (or first key if ++ * Iterate on the provided curor starting at startingkey (or first key if + * startingkey is NULL) and call action_cb for each records +- * ++ * + * action_cb callback returns: + * DBI_RC_SUCCESS to iterate on next entry + * DBI_RC_NOTFOUND to stop iteration with DBI_RC_SUCCESS code +diff --git a/ldap/servers/slapd/protect_db.c b/ldap/servers/slapd/protect_db.c +index eb61e0a23..6ea311b87 100644 +--- a/ldap/servers/slapd/protect_db.c ++++ b/ldap/servers/slapd/protect_db.c +@@ -424,6 +424,10 @@ add_new_slapd_process(int exec_mode, int r_flag, int skip_flag) + * but it in the importing dir so no other process can change + * things while we are doing ldif2db with the -r flag. */ + add_this_process_to(import_dir); ++ /* But also add the process in export_dir to differenciate ++ * from and import task ++ */ ++ add_this_process_to(export_dir); + result = 0; + } + } else { +diff --git a/lib/librobdb/COPYING b/lib/librobdb/COPYING +new file mode 100644 +index 000000000..ac042d4a4 +--- /dev/null ++++ b/lib/librobdb/COPYING +@@ -0,0 +1,8 @@ ++ ++The library code in ++https://github.com/389ds/389-ds-base/lib/librobdb is derivated from RPM project ++ https://github.com/rpm-software-management/rpm project ++As it is derivated from the RPM lib code, this code may be either distributed ++under the terms of the GNU General Public License (GPL) or under the GNU ++Library General Public License (LGPL). ++The complete text of both licenses are in COPYING.RPM, the RPM license file +diff --git a/lib/librobdb/COPYING.RPM b/lib/librobdb/COPYING.RPM +new file mode 100644 +index 000000000..f153e80b7 +--- /dev/null ++++ b/lib/librobdb/COPYING.RPM +@@ -0,0 +1,848 @@ ++libbdbro is derived from RPM lib ++(See https://github.com/rpm-software-management/rpm/) ++so the following RPM license apply by replacing "RPM" by "libbdbreader" ++ ++--------------------------------------------------------------------------- ++ ++ ++ ++RPM is covered under two separate licenses. ++ ++The entire code base may be distributed under the terms of the GNU General ++Public License (GPL), which appears immediately below. Alternatively, ++all of the source code in the lib and rpmio subdirectories of the RPM source ++code distribution as well as any code derived from that code may instead be ++distributed under the GNU Library General Public License (LGPL), at the ++choice of the distributor. The complete text of the LGPL appears ++at the bottom of this file. ++ ++This alternative is provided to enable applications to be linked against ++the RPM library (commonly called librpm) without forcing such applications ++to be distributed under the GPL. ++ ++Any questions regarding the licensing of RPM should be addressed to ++rpm-maint@lists.rpm.org ++ ++--------------------------------------------------------------------------- ++ ++ GNU GENERAL PUBLIC LICENSE ++ Version 2, June 1991 ++ ++ Copyright (C) 1989, 1991 Free Software Foundation, Inc., ++ ++ Everyone is permitted to copy and distribute verbatim copies ++ of this license document, but changing it is not allowed. ++ ++ Preamble ++ ++ The licenses for most software are designed to take away your ++freedom to share and change it. By contrast, the GNU General Public ++License is intended to guarantee your freedom to share and change free ++software--to make sure the software is free for all its users. This ++General Public License applies to most of the Free Software ++Foundation's software and to any other program whose authors commit to ++using it. (Some other Free Software Foundation software is covered by ++the GNU Lesser General Public License instead.) You can apply it to ++your programs, too. ++ ++ When we speak of free software, we are referring to freedom, not ++price. Our General Public Licenses are designed to make sure that you ++have the freedom to distribute copies of free software (and charge for ++this service if you wish), that you receive source code or can get it ++if you want it, that you can change the software or use pieces of it ++in new free programs; and that you know you can do these things. ++ ++ To protect your rights, we need to make restrictions that forbid ++anyone to deny you these rights or to ask you to surrender the rights. ++These restrictions translate to certain responsibilities for you if you ++distribute copies of the software, or if you modify it. ++ ++ For example, if you distribute copies of such a program, whether ++gratis or for a fee, you must give the recipients all the rights that ++you have. You must make sure that they, too, receive or can get the ++source code. And you must show them these terms so they know their ++rights. ++ ++ We protect your rights with two steps: (1) copyright the software, and ++(2) offer you this license which gives you legal permission to copy, ++distribute and/or modify the software. ++ ++ Also, for each author's protection and ours, we want to make certain ++that everyone understands that there is no warranty for this free ++software. If the software is modified by someone else and passed on, we ++want its recipients to know that what they have is not the original, so ++that any problems introduced by others will not reflect on the original ++authors' reputations. ++ ++ Finally, any free program is threatened constantly by software ++patents. We wish to avoid the danger that redistributors of a free ++program will individually obtain patent licenses, in effect making the ++program proprietary. To prevent this, we have made it clear that any ++patent must be licensed for everyone's free use or not licensed at all. ++ ++ The precise terms and conditions for copying, distribution and ++modification follow. ++ ++ GNU GENERAL PUBLIC LICENSE ++ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION ++ ++ 0. This License applies to any program or other work which contains ++a notice placed by the copyright holder saying it may be distributed ++under the terms of this General Public License. The "Program", below, ++refers to any such program or work, and a "work based on the Program" ++means either the Program or any derivative work under copyright law: ++that is to say, a work containing the Program or a portion of it, ++either verbatim or with modifications and/or translated into another ++language. (Hereinafter, translation is included without limitation in ++the term "modification".) Each licensee is addressed as "you". ++ ++Activities other than copying, distribution and modification are not ++covered by this License; they are outside its scope. The act of ++running the Program is not restricted, and the output from the Program ++is covered only if its contents constitute a work based on the ++Program (independent of having been made by running the Program). ++Whether that is true depends on what the Program does. ++ ++ 1. You may copy and distribute verbatim copies of the Program's ++source code as you receive it, in any medium, provided that you ++conspicuously and appropriately publish on each copy an appropriate ++copyright notice and disclaimer of warranty; keep intact all the ++notices that refer to this License and to the absence of any warranty; ++and give any other recipients of the Program a copy of this License ++along with the Program. ++ ++You may charge a fee for the physical act of transferring a copy, and ++you may at your option offer warranty protection in exchange for a fee. ++ ++ 2. You may modify your copy or copies of the Program or any portion ++of it, thus forming a work based on the Program, and copy and ++distribute such modifications or work under the terms of Section 1 ++above, provided that you also meet all of these conditions: ++ ++ a) You must cause the modified files to carry prominent notices ++ stating that you changed the files and the date of any change. ++ ++ b) You must cause any work that you distribute or publish, that in ++ whole or in part contains or is derived from the Program or any ++ part thereof, to be licensed as a whole at no charge to all third ++ parties under the terms of this License. ++ ++ c) If the modified program normally reads commands interactively ++ when run, you must cause it, when started running for such ++ interactive use in the most ordinary way, to print or display an ++ announcement including an appropriate copyright notice and a ++ notice that there is no warranty (or else, saying that you provide ++ a warranty) and that users may redistribute the program under ++ these conditions, and telling the user how to view a copy of this ++ License. (Exception: if the Program itself is interactive but ++ does not normally print such an announcement, your work based on ++ the Program is not required to print an announcement.) ++ ++These requirements apply to the modified work as a whole. If ++identifiable sections of that work are not derived from the Program, ++and can be reasonably considered independent and separate works in ++themselves, then this License, and its terms, do not apply to those ++sections when you distribute them as separate works. But when you ++distribute the same sections as part of a whole which is a work based ++on the Program, the distribution of the whole must be on the terms of ++this License, whose permissions for other licensees extend to the ++entire whole, and thus to each and every part regardless of who wrote it. ++ ++Thus, it is not the intent of this section to claim rights or contest ++your rights to work written entirely by you; rather, the intent is to ++exercise the right to control the distribution of derivative or ++collective works based on the Program. ++ ++In addition, mere aggregation of another work not based on the Program ++with the Program (or with a work based on the Program) on a volume of ++a storage or distribution medium does not bring the other work under ++the scope of this License. ++ ++ 3. You may copy and distribute the Program (or a work based on it, ++under Section 2) in object code or executable form under the terms of ++Sections 1 and 2 above provided that you also do one of the following: ++ ++ a) Accompany it with the complete corresponding machine-readable ++ source code, which must be distributed under the terms of Sections ++ 1 and 2 above on a medium customarily used for software interchange; or, ++ ++ b) Accompany it with a written offer, valid for at least three ++ years, to give any third party, for a charge no more than your ++ cost of physically performing source distribution, a complete ++ machine-readable copy of the corresponding source code, to be ++ distributed under the terms of Sections 1 and 2 above on a medium ++ customarily used for software interchange; or, ++ ++ c) Accompany it with the information you received as to the offer ++ to distribute corresponding source code. (This alternative is ++ allowed only for noncommercial distribution and only if you ++ received the program in object code or executable form with such ++ an offer, in accord with Subsection b above.) ++ ++The source code for a work means the preferred form of the work for ++making modifications to it. For an executable work, complete source ++code means all the source code for all modules it contains, plus any ++associated interface definition files, plus the scripts used to ++control compilation and installation of the executable. However, as a ++special exception, the source code distributed need not include ++anything that is normally distributed (in either source or binary ++form) with the major components (compiler, kernel, and so on) of the ++operating system on which the executable runs, unless that component ++itself accompanies the executable. ++ ++If distribution of executable or object code is made by offering ++access to copy from a designated place, then offering equivalent ++access to copy the source code from the same place counts as ++distribution of the source code, even though third parties are not ++compelled to copy the source along with the object code. ++ ++ 4. You may not copy, modify, sublicense, or distribute the Program ++except as expressly provided under this License. Any attempt ++otherwise to copy, modify, sublicense or distribute the Program is ++void, and will automatically terminate your rights under this License. ++However, parties who have received copies, or rights, from you under ++this License will not have their licenses terminated so long as such ++parties remain in full compliance. ++ ++ 5. You are not required to accept this License, since you have not ++signed it. However, nothing else grants you permission to modify or ++distribute the Program or its derivative works. These actions are ++prohibited by law if you do not accept this License. Therefore, by ++modifying or distributing the Program (or any work based on the ++Program), you indicate your acceptance of this License to do so, and ++all its terms and conditions for copying, distributing or modifying ++the Program or works based on it. ++ ++ 6. Each time you redistribute the Program (or any work based on the ++Program), the recipient automatically receives a license from the ++original licensor to copy, distribute or modify the Program subject to ++these terms and conditions. You may not impose any further ++restrictions on the recipients' exercise of the rights granted herein. ++You are not responsible for enforcing compliance by third parties to ++this License. ++ ++ 7. If, as a consequence of a court judgment or allegation of patent ++infringement or for any other reason (not limited to patent issues), ++conditions are imposed on you (whether by court order, agreement or ++otherwise) that contradict the conditions of this License, they do not ++excuse you from the conditions of this License. If you cannot ++distribute so as to satisfy simultaneously your obligations under this ++License and any other pertinent obligations, then as a consequence you ++may not distribute the Program at all. For example, if a patent ++license would not permit royalty-free redistribution of the Program by ++all those who receive copies directly or indirectly through you, then ++the only way you could satisfy both it and this License would be to ++refrain entirely from distribution of the Program. ++ ++If any portion of this section is held invalid or unenforceable under ++any particular circumstance, the balance of the section is intended to ++apply and the section as a whole is intended to apply in other ++circumstances. ++ ++It is not the purpose of this section to induce you to infringe any ++patents or other property right claims or to contest validity of any ++such claims; this section has the sole purpose of protecting the ++integrity of the free software distribution system, which is ++implemented by public license practices. Many people have made ++generous contributions to the wide range of software distributed ++through that system in reliance on consistent application of that ++system; it is up to the author/donor to decide if he or she is willing ++to distribute software through any other system and a licensee cannot ++impose that choice. ++ ++This section is intended to make thoroughly clear what is believed to ++be a consequence of the rest of this License. ++ ++ 8. If the distribution and/or use of the Program is restricted in ++certain countries either by patents or by copyrighted interfaces, the ++original copyright holder who places the Program under this License ++may add an explicit geographical distribution limitation excluding ++those countries, so that distribution is permitted only in or among ++countries not thus excluded. In such case, this License incorporates ++the limitation as if written in the body of this License. ++ ++ 9. The Free Software Foundation may publish revised and/or new versions ++of the General Public License from time to time. Such new versions will ++be similar in spirit to the present version, but may differ in detail to ++address new problems or concerns. ++ ++Each version is given a distinguishing version number. If the Program ++specifies a version number of this License which applies to it and "any ++later version", you have the option of following the terms and conditions ++either of that version or of any later version published by the Free ++Software Foundation. If the Program does not specify a version number of ++this License, you may choose any version ever published by the Free Software ++Foundation. ++ ++ 10. If you wish to incorporate parts of the Program into other free ++programs whose distribution conditions are different, write to the author ++to ask for permission. For software which is copyrighted by the Free ++Software Foundation, write to the Free Software Foundation; we sometimes ++make exceptions for this. Our decision will be guided by the two goals ++of preserving the free status of all derivatives of our free software and ++of promoting the sharing and reuse of software generally. ++ ++ NO WARRANTY ++ ++ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY ++FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN ++OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES ++PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED ++OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS ++TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE ++PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, ++REPAIR OR CORRECTION. ++ ++ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING ++WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR ++REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, ++INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING ++OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED ++TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY ++YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER ++PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE ++POSSIBILITY OF SUCH DAMAGES. ++ ++ END OF TERMS AND CONDITIONS ++ ++ How to Apply These Terms to Your New Programs ++ ++ If you develop a new program, and you want it to be of the greatest ++possible use to the public, the best way to achieve this is to make it ++free software which everyone can redistribute and change under these terms. ++ ++ To do so, attach the following notices to the program. It is safest ++to attach them to the start of each source file to most effectively ++convey the exclusion of warranty; and each file should have at least ++the "copyright" line and a pointer to where the full notice is found. ++ ++ ++ Copyright (C) ++ ++ 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 . ++ ++Also add information on how to contact you by electronic and paper mail. ++ ++If the program is interactive, make it output a short notice like this ++when it starts in an interactive mode: ++ ++ Gnomovision version 69, Copyright (C) year name of author ++ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. ++ This is free software, and you are welcome to redistribute it ++ under certain conditions; type `show c' for details. ++ ++The hypothetical commands `show w' and `show c' should show the appropriate ++parts of the General Public License. Of course, the commands you use may ++be called something other than `show w' and `show c'; they could even be ++mouse-clicks or menu items--whatever suits your program. ++ ++You should also get your employer (if you work as a programmer) or your ++school, if any, to sign a "copyright disclaimer" for the program, if ++necessary. Here is a sample; alter the names: ++ ++ Yoyodyne, Inc., hereby disclaims all copyright interest in the program ++ `Gnomovision' (which makes passes at compilers) written by James Hacker. ++ ++ , 1 April 1989 ++ Moe Ghoul, President of Vice ++ ++This General Public License does not permit incorporating your program into ++proprietary programs. If your program is a subroutine library, you may ++consider it more useful to permit linking proprietary applications with the ++library. If this is what you want to do, use the GNU Lesser General ++Public License instead of this License. ++ ++--------------------------------------------------------------------------- ++ ++ GNU LIBRARY GENERAL PUBLIC LICENSE ++ Version 2, June 1991 ++ ++ Copyright (C) 1991 Free Software Foundation, Inc. ++ ++ Everyone is permitted to copy and distribute verbatim copies ++ of this license document, but changing it is not allowed. ++ ++[This is the first released version of the library GPL. It is ++ numbered 2 because it goes with version 2 of the ordinary GPL.] ++ ++ Preamble ++ ++ The licenses for most software are designed to take away your ++freedom to share and change it. By contrast, the GNU General Public ++Licenses are intended to guarantee your freedom to share and change ++free software--to make sure the software is free for all its users. ++ ++ This license, the Library General Public License, applies to some ++specially designated Free Software Foundation software, and to any ++other libraries whose authors decide to use it. You can use it for ++your libraries, too. ++ ++ When we speak of free software, we are referring to freedom, not ++price. Our General Public Licenses are designed to make sure that you ++have the freedom to distribute copies of free software (and charge for ++this service if you wish), that you receive source code or can get it ++if you want it, that you can change the software or use pieces of it ++in new free programs; and that you know you can do these things. ++ ++ To protect your rights, we need to make restrictions that forbid ++anyone to deny you these rights or to ask you to surrender the rights. ++These restrictions translate to certain responsibilities for you if ++you distribute copies of the library, or if you modify it. ++ ++ For example, if you distribute copies of the library, whether gratis ++or for a fee, you must give the recipients all the rights that we gave ++you. You must make sure that they, too, receive or can get the source ++code. If you link a program with the library, you must provide ++complete object files to the recipients so that they can relink them ++with the library, after making changes to the library and recompiling ++it. And you must show them these terms so they know their rights. ++ ++ Our method of protecting your rights has two steps: (1) copyright ++the library, and (2) offer you this license which gives you legal ++permission to copy, distribute and/or modify the library. ++ ++ Also, for each distributor's protection, we want to make certain ++that everyone understands that there is no warranty for this free ++library. If the library is modified by someone else and passed on, we ++want its recipients to know that what they have is not the original ++version, so that any problems introduced by others will not reflect on ++the original authors' reputations. ++ ++ Finally, any free program is threatened constantly by software ++patents. We wish to avoid the danger that companies distributing free ++software will individually obtain patent licenses, thus in effect ++transforming the program into proprietary software. To prevent this, ++we have made it clear that any patent must be licensed for everyone's ++free use or not licensed at all. ++ ++ Most GNU software, including some libraries, is covered by the ordinary ++GNU General Public License, which was designed for utility programs. This ++license, the GNU Library General Public License, applies to certain ++designated libraries. This license is quite different from the ordinary ++one; be sure to read it in full, and don't assume that anything in it is ++the same as in the ordinary license. ++ ++ The reason we have a separate public license for some libraries is that ++they blur the distinction we usually make between modifying or adding to a ++program and simply using it. Linking a program with a library, without ++changing the library, is in some sense simply using the library, and is ++analogous to running a utility program or application program. However, in ++a textual and legal sense, the linked executable is a combined work, a ++derivative of the original library, and the ordinary General Public License ++treats it as such. ++ ++ Because of this blurred distinction, using the ordinary General ++Public License for libraries did not effectively promote software ++sharing, because most developers did not use the libraries. We ++concluded that weaker conditions might promote sharing better. ++ ++ However, unrestricted linking of non-free programs would deprive the ++users of those programs of all benefit from the free status of the ++libraries themselves. This Library General Public License is intended to ++permit developers of non-free programs to use free libraries, while ++preserving your freedom as a user of such programs to change the free ++libraries that are incorporated in them. (We have not seen how to achieve ++this as regards changes in header files, but we have achieved it as regards ++changes in the actual functions of the Library.) The hope is that this ++will lead to faster development of free libraries. ++ ++ The precise terms and conditions for copying, distribution and ++modification follow. Pay close attention to the difference between a ++"work based on the library" and a "work that uses the library". The ++former contains code derived from the library, while the latter only ++works together with the library. ++ ++ Note that it is possible for a library to be covered by the ordinary ++General Public License rather than by this special one. ++ ++ GNU LIBRARY GENERAL PUBLIC LICENSE ++ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION ++ ++ 0. This License Agreement applies to any software library which ++contains a notice placed by the copyright holder or other authorized ++party saying it may be distributed under the terms of this Library ++General Public License (also called "this License"). Each licensee is ++addressed as "you". ++ ++ A "library" means a collection of software functions and/or data ++prepared so as to be conveniently linked with application programs ++(which use some of those functions and data) to form executables. ++ ++ The "Library", below, refers to any such software library or work ++which has been distributed under these terms. A "work based on the ++Library" means either the Library or any derivative work under ++copyright law: that is to say, a work containing the Library or a ++portion of it, either verbatim or with modifications and/or translated ++straightforwardly into another language. (Hereinafter, translation is ++included without limitation in the term "modification".) ++ ++ "Source code" for a work means the preferred form of the work for ++making modifications to it. For a library, complete source code means ++all the source code for all modules it contains, plus any associated ++interface definition files, plus the scripts used to control compilation ++and installation of the library. ++ ++ Activities other than copying, distribution and modification are not ++covered by this License; they are outside its scope. The act of ++running a program using the Library is not restricted, and output from ++such a program is covered only if its contents constitute a work based ++on the Library (independent of the use of the Library in a tool for ++writing it). Whether that is true depends on what the Library does ++and what the program that uses the Library does. ++ ++ 1. You may copy and distribute verbatim copies of the Library's ++complete source code as you receive it, in any medium, provided that ++you conspicuously and appropriately publish on each copy an ++appropriate copyright notice and disclaimer of warranty; keep intact ++all the notices that refer to this License and to the absence of any ++warranty; and distribute a copy of this License along with the ++Library. ++ ++ You may charge a fee for the physical act of transferring a copy, ++and you may at your option offer warranty protection in exchange for a ++fee. ++ ++ 2. You may modify your copy or copies of the Library or any portion ++of it, thus forming a work based on the Library, and copy and ++distribute such modifications or work under the terms of Section 1 ++above, provided that you also meet all of these conditions: ++ ++ a) The modified work must itself be a software library. ++ ++ b) You must cause the files modified to carry prominent notices ++ stating that you changed the files and the date of any change. ++ ++ c) You must cause the whole of the work to be licensed at no ++ charge to all third parties under the terms of this License. ++ ++ d) If a facility in the modified Library refers to a function or a ++ table of data to be supplied by an application program that uses ++ the facility, other than as an argument passed when the facility ++ is invoked, then you must make a good faith effort to ensure that, ++ in the event an application does not supply such function or ++ table, the facility still operates, and performs whatever part of ++ its purpose remains meaningful. ++ ++ (For example, a function in a library to compute square roots has ++ a purpose that is entirely well-defined independent of the ++ application. Therefore, Subsection 2d requires that any ++ application-supplied function or table used by this function must ++ be optional: if the application does not supply it, the square ++ root function must still compute square roots.) ++ ++These requirements apply to the modified work as a whole. If ++identifiable sections of that work are not derived from the Library, ++and can be reasonably considered independent and separate works in ++themselves, then this License, and its terms, do not apply to those ++sections when you distribute them as separate works. But when you ++distribute the same sections as part of a whole which is a work based ++on the Library, the distribution of the whole must be on the terms of ++this License, whose permissions for other licensees extend to the ++entire whole, and thus to each and every part regardless of who wrote ++it. ++ ++Thus, it is not the intent of this section to claim rights or contest ++your rights to work written entirely by you; rather, the intent is to ++exercise the right to control the distribution of derivative or ++collective works based on the Library. ++ ++In addition, mere aggregation of another work not based on the Library ++with the Library (or with a work based on the Library) on a volume of ++a storage or distribution medium does not bring the other work under ++the scope of this License. ++ ++ 3. You may opt to apply the terms of the ordinary GNU General Public ++License instead of this License to a given copy of the Library. To do ++this, you must alter all the notices that refer to this License, so ++that they refer to the ordinary GNU General Public License, version 2, ++instead of to this License. (If a newer version than version 2 of the ++ordinary GNU General Public License has appeared, then you can specify ++that version instead if you wish.) Do not make any other change in ++these notices. ++ ++ Once this change is made in a given copy, it is irreversible for ++that copy, so the ordinary GNU General Public License applies to all ++subsequent copies and derivative works made from that copy. ++ ++ This option is useful when you wish to copy part of the code of ++the Library into a program that is not a library. ++ ++ 4. You may copy and distribute the Library (or a portion or ++derivative of it, under Section 2) in object code or executable form ++under the terms of Sections 1 and 2 above provided that you accompany ++it with the complete corresponding machine-readable source code, which ++must be distributed under the terms of Sections 1 and 2 above on a ++medium customarily used for software interchange. ++ ++ If distribution of object code is made by offering access to copy ++from a designated place, then offering equivalent access to copy the ++source code from the same place satisfies the requirement to ++distribute the source code, even though third parties are not ++compelled to copy the source along with the object code. ++ ++ 5. A program that contains no derivative of any portion of the ++Library, but is designed to work with the Library by being compiled or ++linked with it, is called a "work that uses the Library". Such a ++work, in isolation, is not a derivative work of the Library, and ++therefore falls outside the scope of this License. ++ ++ However, linking a "work that uses the Library" with the Library ++creates an executable that is a derivative of the Library (because it ++contains portions of the Library), rather than a "work that uses the ++library". The executable is therefore covered by this License. ++Section 6 states terms for distribution of such executables. ++ ++ When a "work that uses the Library" uses material from a header file ++that is part of the Library, the object code for the work may be a ++derivative work of the Library even though the source code is not. ++Whether this is true is especially significant if the work can be ++linked without the Library, or if the work is itself a library. The ++threshold for this to be true is not precisely defined by law. ++ ++ If such an object file uses only numerical parameters, data ++structure layouts and accessors, and small macros and small inline ++functions (ten lines or less in length), then the use of the object ++file is unrestricted, regardless of whether it is legally a derivative ++work. (Executables containing this object code plus portions of the ++Library will still fall under Section 6.) ++ ++ Otherwise, if the work is a derivative of the Library, you may ++distribute the object code for the work under the terms of Section 6. ++Any executables containing that work also fall under Section 6, ++whether or not they are linked directly with the Library itself. ++ ++ 6. As an exception to the Sections above, you may also compile or ++link a "work that uses the Library" with the Library to produce a ++work containing portions of the Library, and distribute that work ++under terms of your choice, provided that the terms permit ++modification of the work for the customer's own use and reverse ++engineering for debugging such modifications. ++ ++ You must give prominent notice with each copy of the work that the ++Library is used in it and that the Library and its use are covered by ++this License. You must supply a copy of this License. If the work ++during execution displays copyright notices, you must include the ++copyright notice for the Library among them, as well as a reference ++directing the user to the copy of this License. Also, you must do one ++of these things: ++ ++ a) Accompany the work with the complete corresponding ++ machine-readable source code for the Library including whatever ++ changes were used in the work (which must be distributed under ++ Sections 1 and 2 above); and, if the work is an executable linked ++ with the Library, with the complete machine-readable "work that ++ uses the Library", as object code and/or source code, so that the ++ user can modify the Library and then relink to produce a modified ++ executable containing the modified Library. (It is understood ++ that the user who changes the contents of definitions files in the ++ Library will not necessarily be able to recompile the application ++ to use the modified definitions.) ++ ++ b) Accompany the work with a written offer, valid for at ++ least three years, to give the same user the materials ++ specified in Subsection 6a, above, for a charge no more ++ than the cost of performing this distribution. ++ ++ c) If distribution of the work is made by offering access to copy ++ from a designated place, offer equivalent access to copy the above ++ specified materials from the same place. ++ ++ d) Verify that the user has already received a copy of these ++ materials or that you have already sent this user a copy. ++ ++ For an executable, the required form of the "work that uses the ++Library" must include any data and utility programs needed for ++reproducing the executable from it. However, as a special exception, ++the source code distributed need not include anything that is normally ++distributed (in either source or binary form) with the major ++components (compiler, kernel, and so on) of the operating system on ++which the executable runs, unless that component itself accompanies ++the executable. ++ ++ It may happen that this requirement contradicts the license ++restrictions of other proprietary libraries that do not normally ++accompany the operating system. Such a contradiction means you cannot ++use both them and the Library together in an executable that you ++distribute. ++ ++ 7. You may place library facilities that are a work based on the ++Library side-by-side in a single library together with other library ++facilities not covered by this License, and distribute such a combined ++library, provided that the separate distribution of the work based on ++the Library and of the other library facilities is otherwise ++permitted, and provided that you do these two things: ++ ++ a) Accompany the combined library with a copy of the same work ++ based on the Library, uncombined with any other library ++ facilities. This must be distributed under the terms of the ++ Sections above. ++ ++ b) Give prominent notice with the combined library of the fact ++ that part of it is a work based on the Library, and explaining ++ where to find the accompanying uncombined form of the same work. ++ ++ 8. You may not copy, modify, sublicense, link with, or distribute ++the Library except as expressly provided under this License. Any ++attempt otherwise to copy, modify, sublicense, link with, or ++distribute the Library is void, and will automatically terminate your ++rights under this License. However, parties who have received copies, ++or rights, from you under this License will not have their licenses ++terminated so long as such parties remain in full compliance. ++ ++ 9. You are not required to accept this License, since you have not ++signed it. However, nothing else grants you permission to modify or ++distribute the Library or its derivative works. These actions are ++prohibited by law if you do not accept this License. Therefore, by ++modifying or distributing the Library (or any work based on the ++Library), you indicate your acceptance of this License to do so, and ++all its terms and conditions for copying, distributing or modifying ++the Library or works based on it. ++ ++ 10. Each time you redistribute the Library (or any work based on the ++Library), the recipient automatically receives a license from the ++original licensor to copy, distribute, link with or modify the Library ++subject to these terms and conditions. You may not impose any further ++restrictions on the recipients' exercise of the rights granted herein. ++You are not responsible for enforcing compliance by third parties to ++this License. ++ ++ 11. If, as a consequence of a court judgment or allegation of patent ++infringement or for any other reason (not limited to patent issues), ++conditions are imposed on you (whether by court order, agreement or ++otherwise) that contradict the conditions of this License, they do not ++excuse you from the conditions of this License. If you cannot ++distribute so as to satisfy simultaneously your obligations under this ++License and any other pertinent obligations, then as a consequence you ++may not distribute the Library at all. For example, if a patent ++license would not permit royalty-free redistribution of the Library by ++all those who receive copies directly or indirectly through you, then ++the only way you could satisfy both it and this License would be to ++refrain entirely from distribution of the Library. ++ ++If any portion of this section is held invalid or unenforceable under any ++particular circumstance, the balance of the section is intended to apply, ++and the section as a whole is intended to apply in other circumstances. ++ ++It is not the purpose of this section to induce you to infringe any ++patents or other property right claims or to contest validity of any ++such claims; this section has the sole purpose of protecting the ++integrity of the free software distribution system which is ++implemented by public license practices. Many people have made ++generous contributions to the wide range of software distributed ++through that system in reliance on consistent application of that ++system; it is up to the author/donor to decide if he or she is willing ++to distribute software through any other system and a licensee cannot ++impose that choice. ++ ++This section is intended to make thoroughly clear what is believed to ++be a consequence of the rest of this License. ++ ++ 12. If the distribution and/or use of the Library is restricted in ++certain countries either by patents or by copyrighted interfaces, the ++original copyright holder who places the Library under this License may add ++an explicit geographical distribution limitation excluding those countries, ++so that distribution is permitted only in or among countries not thus ++excluded. In such case, this License incorporates the limitation as if ++written in the body of this License. ++ ++ 13. The Free Software Foundation may publish revised and/or new ++versions of the Library General Public License from time to time. ++Such new versions will be similar in spirit to the present version, ++but may differ in detail to address new problems or concerns. ++ ++Each version is given a distinguishing version number. If the Library ++specifies a version number of this License which applies to it and ++"any later version", you have the option of following the terms and ++conditions either of that version or of any later version published by ++the Free Software Foundation. If the Library does not specify a ++license version number, you may choose any version ever published by ++the Free Software Foundation. ++ ++ 14. If you wish to incorporate parts of the Library into other free ++programs whose distribution conditions are incompatible with these, ++write to the author to ask for permission. For software which is ++copyrighted by the Free Software Foundation, write to the Free ++Software Foundation; we sometimes make exceptions for this. Our ++decision will be guided by the two goals of preserving the free status ++of all derivatives of our free software and of promoting the sharing ++and reuse of software generally. ++ ++ NO WARRANTY ++ ++ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO ++WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. ++EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR ++OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY ++KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE ++IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE ++LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME ++THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. ++ ++ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN ++WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY ++AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU ++FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR ++CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE ++LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING ++RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A ++FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF ++SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH ++DAMAGES. ++ ++ END OF TERMS AND CONDITIONS ++ ++ How to Apply These Terms to Your New Libraries ++ ++ If you develop a new library, and you want it to be of the greatest ++possible use to the public, we recommend making it free software that ++everyone can redistribute and change. You can do so by permitting ++redistribution under these terms (or, alternatively, under the terms of the ++ordinary General Public License). ++ ++ To apply these terms, attach the following notices to the library. It is ++safest to attach them to the start of each source file to most effectively ++convey the exclusion of warranty; and each file should have at least the ++"copyright" line and a pointer to where the full notice is found. ++ ++ ++ Copyright (C) ++ ++ This library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public ++ License as published by the Free Software Foundation; either ++ version 2 of the License, or (at your option) any later version. ++ ++ This library 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 ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with this library; if not, see . ++ ++Also add information on how to contact you by electronic and paper mail. ++ ++You should also get your employer (if you work as a programmer) or your ++school, if any, to sign a "copyright disclaimer" for the library, if ++necessary. Here is a sample; alter the names: ++ ++ Yoyodyne, Inc., hereby disclaims all copyright interest in the ++ library `Frob' (a library for tweaking knobs) written by James Random Hacker. ++ ++ , 1 April 1990 ++ Moe Ghoul, President of Vice ++ ++That's all there is to it! +diff --git a/lib/librobdb/README.md b/lib/librobdb/README.md +new file mode 100644 +index 000000000..a79bca9ea +--- /dev/null ++++ b/lib/librobdb/README.md +@@ -0,0 +1,30 @@ ++# DESCRIPTION ++ ++This project provides basic functions to walk/lookup Berkeley Database records. ++It is derived from [GitHub - rpm-software-management/rpm: The RPM package manager](https://github.com/rpm-software-management/rpm/) project. ++It reuse a single file: https://github.com/rpm-software-management/rpm/blob/master/lib/backend/bdb_ro.cc ++ ++renamed as a C file, suppressed librpm adherences and adding back a simple ++interface to be able to use the relevant functions. ++ ++# Build ++ ++make clean rpmbuild lint ++ ++# Example ++ ++See test/test.c (Using a 389ds entries database as example, It shows how to dump the database and look for records) ++ ++# Running tests ++ ++dnf install -y dist/RPMS/*/*.rpm ++make test ++ ++or ++ ++make localtest ++ ++ ++# LICENSE ++ ++Same as lib part for rpm: GPLv2 or alternatively LGPL (See COPYING and COPYING.RPM for full details) +diff --git a/lib/librobdb/lib/bdb_ro.c b/lib/librobdb/lib/bdb_ro.c +new file mode 100644 +index 000000000..db10cc812 +--- /dev/null ++++ b/lib/librobdb/lib/bdb_ro.c +@@ -0,0 +1,713 @@ ++/* Part of this file content is derivated from: ++ * https://github.com/rpm-software-management/rpm/blob/master/lib/backend/bdb_ro.cc ++ * Commit: a45134e7d428ad4f40e629408f24de9a6b955200 ++ * i.e: ++ * git clone https://github.com/rpm-software-management/rpm.git ++ * git switch --detach a45134e7d428ad4f40e629408f24de9a6b955200 ++ * lib/backend/bdb_ro.cc ++ */ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "robdb.h" ++ ++static void* (*bdbreader_calloc_cb)(size_t, size_t); ++static void* (*bdbreader_malloc_cb)(size_t); ++static void* (*bdbreader_realloc_cb)(void*, size_t); ++static void (*bdbreader_free_cb)(void **); ++static void (*bdbreader_log_cb)(const char*, ...); ++ ++#define NEW(structname) bdbreader_calloc_cb(1, sizeof (struct structname)) ++#define DELETE(var) free(var) ++#define free(var) bdbreader_free_cb((void**)&var) ++#define xmalloc(size) bdbreader_malloc_cb(size) ++#define xrealloc(ptr, size) bdbreader_realloc_cb((void*)(ptr),(size)) ++ ++#define rpmlog(level, ...) bdbreader_log_cb("bdbro", __VA_ARGS__) ++ ++ ++/* Note: the only changes in the following copied code is to convert back ++ * the C++ statments to C: ++ * new xxx is replaced by NEW(xxx) ++ * delete xxx is replaced by DELETE(xxx) ++ */ ++/************************************************************************/ ++/************** Start of code copied from librpm ************************/ ++/************************************************************************/ ++ ++#define BDB_HASH 0 ++#define BDB_BTREE 1 ++ ++union _dbswap { ++ unsigned int ui; ++ unsigned char uc[4]; ++}; ++ ++#define _DBSWAP(_a) \ ++\ ++ { unsigned char _b, *_c = (_a).uc; \ ++ _b = _c[3]; _c[3] = _c[0]; _c[0] = _b; \ ++ _b = _c[2]; _c[2] = _c[1]; _c[1] = _b; \ ++\ ++ } ++ ++struct dbiCursor_s; ++ ++struct bdb_kv { ++ unsigned char *kv; ++ unsigned int len; ++}; ++ ++struct bdb_db { ++ int fd; /* file descriptor of database */ ++ int type; /* BDB_HASH / BDB_BTREE */ ++ unsigned int pagesize; ++ unsigned int lastpage; ++ int swapped; /* different endianess? */ ++ /* btree */ ++ unsigned int root; /* root page of the b-tree */ ++ /* hash */ ++ unsigned int maxbucket; ++ unsigned int highmask; ++ unsigned int lowmask; ++ unsigned int spares[32]; /* spare pages for each splitpoint */ ++}; ++ ++struct bdb_cur { ++ struct bdb_db *db; ++ ++ struct bdb_kv key; /* key and value from the db entry */ ++ struct bdb_kv val; ++ ++ unsigned char *page; /* the page we're looking at */ ++ ++ unsigned char *ovpage; ++ struct bdb_kv keyov; /* space to store oversized keys/values */ ++ struct bdb_kv valov; ++ ++ int state; /* 1: onpage, -1: error */ ++ int idx; /* entry index */ ++ int numidx; /* number of entries on the page */ ++ int islookup; /* we're doing a lookup operation */ ++ ++ /* hash */ ++ unsigned int bucket; /* current bucket */ ++}; ++ ++ ++static void swap16(unsigned char *p) ++{ ++ int a = p[0]; ++ p[0] = p[1]; ++ p[1] = a; ++} ++ ++static void swap32(unsigned char *p) ++{ ++ int a = p[0]; ++ p[0] = p[3]; ++ p[3] = a; ++ a = p[1]; ++ p[1] = p[2]; ++ p[2] = a; ++} ++ ++static void swap32_2(unsigned char *p) ++{ ++ swap32(p); ++ swap32(p + 4); ++} ++ ++static void bdb_swapmetapage(struct bdb_db *db, unsigned char *page) ++{ ++ int i, maxi = db->type == BDB_HASH ? 224 : 92; ++ for (i = 8; i < maxi; i += 4) ++ swap32((unsigned char *)(page + i)); ++ swap32((unsigned char *)(page + 24)); ++} ++ ++static void bdb_swappage(struct bdb_db *db, unsigned char *page) ++{ ++ unsigned int pagesize = db->pagesize; ++ int type, i, nent, off; ++ swap32(page + 8); /* page number */ ++ swap32_2(page + 12); /* prev/next page */ ++ swap16(page + 20); /* nitems */ ++ swap16(page + 22); /* highfree */ ++ ++ type = page[25]; ++ if (type != 2 && type != 13 && type != 3 && type != 5) ++ return; ++ nent = *(uint16_t *)(page + 20); ++ if (nent > (pagesize - 26) / 2) ++ nent = (pagesize - 26) / 2; ++ for (i = 0; i < nent; i++) { ++ int minoff = 26 + nent * 2; ++ swap16(page + 26 + i * 2); /* offset */ ++ off = *(uint16_t *)(page + 26 + i * 2); ++ if (off < minoff || off >= pagesize) ++ continue; ++ if (type == 2 || type == 13) { /* hash */ ++ if (page[off] == 3 && off + 12 <= pagesize) ++ swap32_2(page + off + 4); /* page no/length */ ++ } else if (type == 3) { /* btree internal */ ++ if (off + 12 > pagesize) ++ continue; ++ swap16(page + off); /* length */ ++ swap32_2(page + off + 4); /* page no/num recs */ ++ if (page[off + 2] == 3 && off + 24 <= pagesize) ++ swap32_2(page + off + 16); /* with overflow page/length */ ++ } else if (type == 5) { /* btree leaf */ ++ if (off + 3 <= pagesize && page[off + 2] == 1) ++ swap16(page + off); /* length */ ++ else if (off + 12 <= pagesize && page[off + 2] == 3) ++ swap32_2(page + off + 4); /* overflow page/length */ ++ } ++ } ++} ++ ++static int bdb_getpage(struct bdb_db *db, unsigned char *page, unsigned int pageno) ++{ ++ if (!pageno || pageno > db->lastpage) ++ return -1; ++ if (pread(db->fd, page, db->pagesize, (off_t)pageno * db->pagesize) != db->pagesize) { ++ rpmlog(RPMLOG_ERR, "pread: %s\n", strerror(errno)); ++ return -1; ++ } ++ if (db->swapped) ++ bdb_swappage(db, page); ++ if (pageno != *(uint32_t *)(page + 8)) ++ return -1; ++ return 0; ++} ++ ++static void bdb_close(struct bdb_db *db) ++{ ++ if (db->fd >= 0) ++ close(db->fd); ++ DELETE(db); ++} ++ ++static struct bdb_db *bdb_open(const char *name) ++{ ++ uint32_t meta[512 / 4]; ++ int i, fd; ++ struct bdb_db *db; ++ ++ fd = open(name, O_RDONLY); ++ if (fd == -1) { ++ return NULL; ++ } ++ db = NEW(bdb_db); ++ db->fd = fd; ++ if (pread(fd, meta, 512, 0) != 512) { ++ rpmlog(RPMLOG_ERR, "%s: pread: %s\n", name, strerror(errno)); ++ bdb_close(db); ++ return NULL; ++ } ++ if (meta[3] == 0x00061561 || meta[3] == 0x61150600) { ++ db->type = BDB_HASH; ++ db->swapped = meta[3] == 0x61150600; ++ } else if (meta[3] == 0x00053162 || meta[3] == 0x62310500) { ++ db->type = BDB_BTREE; ++ db->swapped = meta[3] == 0x62310500; ++ } else { ++ rpmlog(RPMLOG_ERR, "%s: not a berkeley db hash/btree database\n", name); ++ bdb_close(db); ++ return NULL; ++ } ++ if (db->swapped) ++ bdb_swapmetapage(db, (unsigned char *)meta); ++ db->pagesize = meta[5]; ++ db->lastpage = meta[8]; ++ if (db->type == BDB_HASH) { ++ if (meta[4] < 8 || meta[4] > 10) { ++ rpmlog(RPMLOG_ERR, "%s: unsupported hash version %d\n", name, meta[4]); ++ bdb_close(db); ++ return NULL; ++ } ++ db->maxbucket = meta[18]; ++ db->highmask = meta[19]; ++ db->lowmask = meta[20]; ++ for (i = 0; i < 32; i++) ++ db->spares[i] = meta[24 + i]; ++ } ++ if (db->type == BDB_BTREE) { ++ if (meta[4] < 9 || meta[4] > 10) { ++ rpmlog(RPMLOG_ERR, "%s: unsupported btree version %d\n", name, meta[4]); ++ bdb_close(db); ++ return NULL; ++ } ++ db->root = meta[22]; ++ } ++ return db; ++} ++ ++ ++/****** overflow handling ******/ ++ ++static int ovfl_get(struct bdb_cur *cur, struct bdb_kv *kv, struct bdb_kv *ov, uint32_t *pagenolen) ++{ ++ unsigned int pageno = pagenolen[0]; ++ unsigned int len = pagenolen[1]; ++ unsigned int plen; ++ unsigned char *p; ++ ++ if (len == 0) ++ return -1; ++ if (len > ov->len) { ++ if (ov->kv) ++ ov->kv = xrealloc(ov->kv, len); ++ else ++ ov->kv = (unsigned char *)xmalloc(len); ++ ov->len = len; ++ } ++ if (!cur->ovpage) ++ cur->ovpage = (unsigned char *)xmalloc(cur->db->pagesize); ++ p = ov->kv; ++ while (len > 0) { ++ if (bdb_getpage(cur->db, cur->ovpage, pageno)) ++ return -1; ++ if (cur->ovpage[25] != 7) ++ return -1; ++ plen = *(uint16_t *)(cur->ovpage + 22); ++ if (plen + 26 > cur->db->pagesize || plen > len) ++ return -1; ++ memcpy(p, cur->ovpage + 26, plen); ++ p += plen; ++ len -= plen; ++ pageno = *(uint32_t *)(cur->ovpage + 16); ++ } ++ if (kv) { ++ kv->kv = ov->kv; ++ kv->len = pagenolen[1]; ++ } ++ return 0; ++} ++ ++ ++/****** hash implementation ******/ ++ ++static int hash_bucket_to_page(struct bdb_db *db, unsigned int bucket) ++{ ++ unsigned int b; ++ int i = 0; ++ for (b = bucket; b; b >>= 1) ++ i++; ++ return bucket + db->spares[i]; ++} ++ ++static int hash_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl) ++{ ++ uint32_t bucket; ++ unsigned int pg, i; ++ cur->state = -1; ++ for (bucket = 0, i = 0; i < keyl; i++) ++ bucket = (bucket * 16777619) ^ key[i]; ++ bucket &= cur->db->highmask; ++ if (bucket > cur->db->maxbucket) ++ bucket &= cur->db->lowmask; ++ cur->bucket = bucket; ++ pg = hash_bucket_to_page(cur->db, bucket); ++ if (bdb_getpage(cur->db, cur->page, pg)) ++ return -1; ++ if (cur->page[25] != 8 && cur->page[25] != 13 && cur->page[25] != 2) ++ return -1; ++ cur->idx = (unsigned int)-2; ++ cur->numidx = *(uint16_t *)(cur->page + 20); ++ cur->state = 1; ++ return 0; ++} ++ ++static int hash_getkv(struct bdb_cur *cur, struct bdb_kv *kv, struct bdb_kv *ov, int off, int len) ++{ ++ if (len <= 0 || off + len > cur->db->pagesize) ++ return -1; ++ if (cur->page[off] == 1) { ++ kv->kv = cur->page + off + 1; ++ kv->len = len - 1; ++ } else if (cur->page[off] == 3) { ++ uint32_t ovlpage[2]; ++ if (len != 12) ++ return -1; ++ memcpy(ovlpage, cur->page + off + 4, 8); /* off is unaligned */ ++ if (ovfl_get(cur, kv, ov, ovlpage)) ++ return -1; ++ } else { ++ return -1; ++ } ++ return 0; ++} ++ ++static int hash_next(struct bdb_cur *cur) ++{ ++ int pagesize = cur->db->pagesize; ++ int koff, klen, voff, vlen; ++ if (!cur->state && hash_lookup(cur, 0, 0)) ++ return -1; ++ cur->idx += 2; ++ for (;;) { ++ if (cur->idx + 1 >= cur->numidx) { ++ unsigned int pg; ++ cur->idx = cur->numidx = 0; ++ pg = *(uint32_t *)(cur->page + 16); ++ if (!pg) { ++ if (cur->islookup || cur->bucket >= cur->db->maxbucket) ++ return 1; ++ pg = hash_bucket_to_page(cur->db, ++cur->bucket); ++ } ++ if (bdb_getpage(cur->db, cur->page, pg)) ++ return -1; ++ if (cur->page[25] != 8 && cur->page[25] != 13 && cur->page[25] != 2) ++ return -1; ++ cur->numidx = *(uint16_t *)(cur->page + 20); ++ continue; ++ } ++ koff = *(uint16_t *)(cur->page + 26 + 2 * cur->idx); ++ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx); ++ if (koff >= pagesize || voff >= pagesize) ++ return -1; ++ if (cur->idx == 0) ++ klen = pagesize - koff; ++ else ++ klen = *(uint16_t *)(cur->page + 24 + 2 * cur->idx) - koff; ++ vlen = koff - voff; ++ if (hash_getkv(cur, &cur->key, &cur->keyov, koff, klen)) ++ return -1; ++ if (!cur->islookup && hash_getkv(cur, &cur->val, &cur->valov, voff, vlen)) ++ return -1; ++ return 0; ++ } ++} ++ ++static int hash_getval(struct bdb_cur *cur) ++{ ++ int koff, voff; ++ if (cur->state != 1 || cur->idx + 1 >= cur->numidx) ++ return -1; ++ koff = *(uint16_t *)(cur->page + 26 + 2 * cur->idx); ++ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx); ++ return hash_getkv(cur, &cur->val, &cur->valov, voff, koff - voff); ++} ++ ++ ++/****** btree implementation ******/ ++ ++static int btree_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keylen) ++{ ++ int pagesize = cur->db->pagesize; ++ int off, lastoff, idx, numidx; ++ unsigned int pg; ++ unsigned char *ekey; ++ unsigned int ekeylen; ++ int cmp; ++ ++ cur->state = -1; ++ pg = cur->db->root; ++ for (;;) { ++ if (bdb_getpage(cur->db, cur->page, pg)) ++ return -1; ++ if (cur->page[25] == 5) ++ break; /* found leaf page */ ++ if (cur->page[25] != 3) ++ return -1; ++ numidx = *(uint16_t *)(cur->page + 20); ++ if (!numidx) ++ return -1; ++ for (lastoff = 0, idx = 0; idx < numidx; idx++, lastoff = off) { ++ off = *(uint16_t *)(cur->page + 26 + 2 * idx); ++ if ((off & 3) != 0 || off + 3 > pagesize) ++ return -1; ++ ekeylen = *(uint16_t *)(cur->page + off); ++ if (off + 12 + ekeylen > pagesize) ++ return -1; ++ if (!keylen) { ++ lastoff = off; ++ break; ++ } ++ if (idx == 0) ++ continue; ++ ekey = cur->page + off + 12; ++ if ((cur->page[off + 2] & 0x7f) == 3) { ++ if (ekeylen != 12) ++ return -1; ++ if (ovfl_get(cur, 0, &cur->keyov, (uint32_t *)(ekey + 4))) ++ return -1; ++ ekeylen = *(uint32_t *)(ekey + 8); ++ ekey = cur->keyov.kv; ++ } else if ((cur->page[off + 2] & 0x7f) != 1) { ++ return -1; ++ } ++ cmp = memcmp(ekey, key, keylen < ekeylen ? keylen : ekeylen); ++ if (cmp > 0 || (cmp == 0 && ekeylen > keylen)) ++ break; ++ } ++ pg = *(uint32_t *)(cur->page + lastoff + 4); ++ } ++ cur->idx = (unsigned int)-2; ++ cur->numidx = *(uint16_t *)(cur->page + 20); ++ cur->state = 1; ++ return 0; ++} ++ ++static int btree_getkv(struct bdb_cur *cur, struct bdb_kv *kv, struct bdb_kv *ov, int off) ++{ ++ if ((off & 3) != 0) ++ return -1; ++ if (cur->page[off + 2] == 1) { ++ int len = *(uint16_t *)(cur->page + off); ++ if (off + 3 + len > cur->db->pagesize) ++ return -1; ++ kv->kv = cur->page + off + 3; ++ kv->len = len; ++ } else if (cur->page[off + 2] == 3) { ++ if (off + 12 > cur->db->pagesize) ++ return -1; ++ if (ovfl_get(cur, kv, ov, (uint32_t *)(cur->page + off + 4))) ++ return -1; ++ } else { ++ return -1; ++ } ++ return 0; ++} ++ ++static int btree_next(struct bdb_cur *cur) ++{ ++ int pagesize = cur->db->pagesize; ++ int koff, voff; ++ if (!cur->state && btree_lookup(cur, 0, 0)) ++ return -1; ++ cur->idx += 2; ++ for (;;) { ++ if (cur->idx + 1 >= cur->numidx) { ++ unsigned int pg; ++ cur->idx = cur->numidx = 0; ++ pg = *(uint32_t *)(cur->page + 16); ++ if (cur->islookup || !pg) ++ return 1; ++ if (bdb_getpage(cur->db, cur->page, pg)) ++ return -1; ++ if (cur->page[25] != 5) ++ return -1; ++ cur->numidx = *(uint16_t *)(cur->page + 20); ++ continue; ++ } ++ koff = *(uint16_t *)(cur->page + 26 + 2 * cur->idx); ++ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx); ++ if (koff + 3 > pagesize || voff + 3 > pagesize) ++ return -1; ++ if ((cur->page[koff + 2] & 0x80) != 0 || (cur->page[voff + 2] & 0x80) != 0) ++ continue; /* ignore deleted */ ++ if (btree_getkv(cur, &cur->key, &cur->keyov, koff)) ++ return -1; ++ if (!cur->islookup && btree_getkv(cur, &cur->val, &cur->valov, voff)) ++ return -1; ++ return 0; ++ } ++} ++ ++static int btree_getval(struct bdb_cur *cur) ++{ ++ int voff; ++ if (cur->state != 1 || cur->idx + 1 >= cur->numidx) ++ return -1; ++ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx); ++ return btree_getkv(cur, &cur->val, &cur->valov, voff); ++} ++ ++ ++/****** cursor functions ******/ ++ ++static struct bdb_cur *cur_open(struct bdb_db *db) ++{ ++ struct bdb_cur *cur = NEW(bdb_cur); ++ cur->db = db; ++ cur->page = (unsigned char *)xmalloc(db->pagesize); ++ return cur; ++} ++ ++static void cur_close(struct bdb_cur *cur) ++{ ++ if (cur->page) ++ free(cur->page); ++ if (cur->ovpage) ++ free(cur->ovpage); ++ if (cur->keyov.kv) ++ free(cur->keyov.kv); ++ if (cur->valov.kv) ++ free(cur->valov.kv); ++ DELETE(cur); ++} ++ ++static int cur_next(struct bdb_cur *cur) ++{ ++ if (cur->state < 0) ++ return -1; ++ if (cur->db->type == BDB_HASH) ++ return hash_next(cur); ++ if (cur->db->type == BDB_BTREE) ++ return btree_next(cur); ++ return -1; ++} ++ ++static int cur_getval(struct bdb_cur *cur) ++{ ++ if (cur->state < 0) ++ return -1; ++ if (cur->db->type == BDB_HASH) ++ return hash_getval(cur); ++ if (cur->db->type == BDB_BTREE) ++ return btree_getval(cur); ++ return -1; ++} ++ ++static int cur_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl) ++{ ++ int r = -1; ++ if (cur->db->type == BDB_HASH) ++ r = hash_lookup(cur, key, keyl); ++ if (cur->db->type == BDB_BTREE) ++ r = btree_lookup(cur, key, keyl); ++ if (r != 0) ++ return r; ++ cur->islookup = 1; ++ while ((r = cur_next(cur)) == 0) ++ if (keyl == cur->key.len && !memcmp(key, cur->key.kv, keyl)) ++ break; ++ cur->islookup = 0; ++ if (r == 0) ++ r = cur_getval(cur); ++ return r; ++} ++ ++static int cur_lookup_ge(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl) ++{ ++ int r = -1; ++ if (cur->db->type == BDB_BTREE) ++ r = btree_lookup(cur, key, keyl); ++ if (r != 0) ++ return r; ++ cur->islookup = 1; ++ while ((r = cur_next(cur)) == 0) { ++ unsigned int ekeyl = cur->key.len; ++ int cmp = memcmp(cur->key.kv, key, keyl < ekeyl ? keyl : ekeyl); ++ if (cmp > 0 || (cmp == 0 && ekeyl >= keyl)) ++ break; ++ } ++ cur->islookup = 0; ++ if (r == 0) ++ r = cur_getval(cur); ++ else if (r == 1) ++ r = cur_next(cur); ++ return r; ++} ++ ++/************************************************************************/ ++/************** End of code copied from librpm **************************/ ++/************************************************************************/ ++ ++static int cur_getcurval(struct bdb_cur *cur, void **keyv, unsigned int *keyl, void **datav, unsigned int *datal) ++{ ++ int ret = cur_getval(cur); ++ if (keyv) { ++ *keyv = cur->key.kv; ++ } ++ if (keyl) { ++ *keyl = cur->key.len; ++ } ++ if (datav) { ++ *datav = cur->val.kv; ++ } ++ if (datal) { ++ *datal = cur->val.len; ++ } ++ return ret; ++} ++ ++/************************************************************************/ ++/********** exported symbols - see description in bdbreader.h ***********/ ++/************************************************************************/ ++ ++struct bdb_db *bdbreader_bdb_open(const char *name) ++{ ++ return bdb_open(name); ++} ++ ++void bdbreader_bdb_close(struct bdb_db **db) ++{ ++ if (*db) { ++ bdb_close(*db); ++ *db = NULL; ++ } ++} ++ ++struct bdb_cur *bdbreader_cur_open(struct bdb_db *db) ++{ ++ return cur_open(db); ++} ++ ++void bdbreader_cur_close(struct bdb_cur **cur) ++{ ++ if (*cur) { ++ cur_close(*cur); ++ *cur = NULL; ++ } ++} ++ ++int bdbreader_cur_next(struct bdb_cur *cur) ++{ ++ return cur_next(cur); ++} ++ ++int bdbreader_cur_getval(struct bdb_cur *cur) ++{ ++ return cur_getval(cur); ++} ++ ++int bdbreader_cur_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl) ++{ ++ return cur_lookup(cur, key, keyl); ++} ++ ++int bdbreader_cur_lookup_ge(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl) ++{ ++ return cur_lookup_ge(cur, key, keyl); ++} ++ ++int bdbreader_cur_getcurval(struct bdb_cur *cur, void **keyv, unsigned int *keyl, void **datav, unsigned int *datal) ++{ ++ return cur_getcurval(cur, keyv, keyl, datav, datal); ++} ++ ++void bdbreader_set_calloc_cb(void* (*calloc_cb)(size_t, size_t)) ++{ ++ bdbreader_calloc_cb = calloc_cb; ++} ++ ++void bdbreader_set_malloc_cb(void* (*malloc_cb)(size_t)) ++{ ++ bdbreader_malloc_cb = malloc_cb; ++} ++ ++void bdbreader_set_realloc_cb(void* (*realloc_cb)(void*, size_t)) ++{ ++ bdbreader_realloc_cb = realloc_cb; ++} ++ ++void bdbreader_set_free_cb(void (*free_cb)(void **)) ++{ ++ bdbreader_free_cb = free_cb; ++} ++ ++void bdbreader_set_log_cb(void (*log_cb)(const char*, ...)) ++{ ++ bdbreader_log_cb = log_cb; ++} ++ +diff --git a/lib/librobdb/lib/robdb.h b/lib/librobdb/lib/robdb.h +new file mode 100644 +index 000000000..2c1a663bf +--- /dev/null ++++ b/lib/librobdb/lib/robdb.h +@@ -0,0 +1,51 @@ ++/* ++ * License: GPL (version 2 or any later version) or LGPL (version 2.1 or any later version). ++ */ ++ ++struct bdb_db; ++struct bdb_cur; ++ ++ ++/* Callbacks - All callbacks must be set before used any other functions */ ++ ++/* Set callback for the calloc function */ ++void bdbreader_set_calloc_cb(void* (*calloc_cb)(size_t, size_t)); ++ ++/* Set callback for the malloc function */ ++void bdbreader_set_malloc_cb(void* (*malloc_cb)(size_t)); ++ ++/* Set callback for the realloc function */ ++void bdbreader_set_realloc_cb(void* (*realloc_cb)(void*, size_t)); ++ ++/* Set callback for the free function */ ++void bdbreader_set_free_cb(void (*free_cb)(void **)); ++ ++/* Set callback for the log function */ ++void bdbreader_set_log_cb(void (*log_cb)(const char*, ...)); ++ ++/* Open a database instance and get a db handler */ ++struct bdb_db *bdbreader_bdb_open(const char *name); ++ ++/* Close a db handler */ ++void bdbreader_bdb_close(struct bdb_db **db); ++ ++/* Create a cursor on a db */ ++struct bdb_cur *bdbreader_cur_open(struct bdb_db *db); ++ ++/* Close a cusrsor */ ++void bdbreader_cur_close(struct bdb_cur **cur); ++ ++/* Move cursor to next item. returns -1 if no more records */ ++int bdbreader_cur_next(struct bdb_cur *cur); ++ ++/* Get cursor current status. returns -1 if no more records */ ++int bdbreader_cur_getval(struct bdb_cur *cur); ++ ++/* Position the cursor on the key. return -1 if not found */ ++int bdbreader_cur_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl); ++ ++/* Position the cursor on smallest key >= key. return -1 if not found */ ++int bdbreader_cur_lookup_ge(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl); ++ ++/* Get cursor current key/data pair. returns -1 if no more records */ ++int bdbreader_cur_getcurval(struct bdb_cur *cur, void **keyv, unsigned int *keyl, void **datav, unsigned int *datal); +diff --git a/lib/librobdb/robdb.spec b/lib/librobdb/robdb.spec +new file mode 100644 +index 000000000..8d3a27e0f +--- /dev/null ++++ b/lib/librobdb/robdb.spec +@@ -0,0 +1,67 @@ ++Name: robdb ++Version: 1.1 ++Release: %{autorelease -n %{?dist}} ++Summary: Provide basic functions to search and read Berkeley Database records ++ ++License: GPL-2.0-or-later OR LGPL-2.1-or-later ++URL: https://github.com/389ds/389-ds-base/tree/main/lib/librobdb ++Source0: %{name}-%{version}.tar.bz2 ++ ++BuildRequires: gcc ++# Requires: ++ ++%description ++ ++ ++%package devel ++Summary: Development files for %{name} ++License: GPL-2.0-or-later OR LGPL-2.1-or-later ++Requires: %{name}-libs%{?_isa} = %{version}-%{release} ++ ++%description devel ++The %{name}-devel package contains the library and the header file for ++developing applications that use %{name}: A library derived from ++rpm lib project (https://github.com/rpm-software-management) that ++provides some basic functions to search and read Berkeley Database records ++ ++ ++%package libs ++Summary: Library for %{name} ++License: GPL-2.0-or-later OR LGPL-2.1-or-later ++ ++%description libs ++The %{name}-lib package contains a library derived from rpm lib ++project (https://github.com/rpm-software-management) that provides ++some basic functions to search and read Berkeley Database records ++ ++ ++%prep ++%autosetup ++ ++%build ++%make_build ++ ++%install ++%make_install ++ ++%{?ldconfig_scriptlets} ++ ++%check ++make localtest ++ ++ ++%files libs ++%license COPYING COPYING.RPM ++%doc %{_defaultdocdir}/%{name}-libs/README.md ++%{_libdir}/*.so.* ++ ++%files devel ++%license COPYING COPYING.RPM ++%doc %{_defaultdocdir}/%{name}-devel/README.md ++%{_libdir}/*.so ++%{_includedir}/* ++ ++ ++%changelog ++%autochangelog ++ +diff --git a/lib/librobdb/tests/test.c b/lib/librobdb/tests/test.c +new file mode 100644 +index 000000000..92cf35e8d +--- /dev/null ++++ b/lib/librobdb/tests/test.c +@@ -0,0 +1,175 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++typedef struct { ++ void *data; ++ unsigned int len; ++} DATA; ++ ++ ++void print_record(const DATA *key, const DATA *data) ++{ ++ unsigned int id = 0; ++ if (4 == key->len) { ++ unsigned char *pt = key->data; ++ /* In test.db the key is a big endian 4 bytes integer */ ++ id = pt[3] + (pt[2] << 8) + (pt[1] << 16) + (pt[0] << 24); ++ printf("Key: %3d Data:\n%s\n", id, (char*)data->data); ++ } else { ++ printf("ERROR: Unexpected record key size\n"); ++ } ++} ++ ++void mylog(const char *msg, ...) ++{ ++ va_list ap; ++ va_start(ap, msg); ++ printf("bdbreader:" ); ++ vprintf(msg, ap); ++ va_end(ap); ++} ++ ++void myfree(void **data) ++{ ++ if (*data) { ++ free(*data); ++ *data = NULL; ++ } ++} ++ ++int main() ++{ ++ struct bdb_db *db = NULL; ++ struct bdb_cur *cur = NULL; ++ DATA key = {0}; ++ DATA data = {0}; ++ int rc = 0; ++ char keybuff[6]; ++ int fail = 0; ++ int count = 0; ++ int expected_count = 14; ++ ++ printf("HERE[%d]\n",__LINE__); ++ ++ /* Initialize all callbacks */ ++ bdbreader_set_calloc_cb(calloc); ++ bdbreader_set_malloc_cb(malloc); ++ bdbreader_set_realloc_cb(realloc); ++ bdbreader_set_free_cb(myfree); ++ bdbreader_set_log_cb(mylog); ++ ++ db = bdbreader_bdb_open("test.db"); ++ if (db == NULL) { ++ perror("Failed to open test.db"); ++ exit(1); ++ } ++ cur = bdbreader_cur_open(db); ++ if (cur == NULL) { ++ perror("Failed to open cursor"); ++ exit(1); ++ } ++ ++ printf(" ********* Dump the dtabase content: *******\n"); ++ ++ do { ++ rc = bdbreader_cur_next(cur); ++ if (rc !=0) { ++ break; ++ } ++ rc = bdbreader_cur_getcurval(cur, &key.data, &key.len, &data.data, &data.len); ++ if (rc == 0) { ++ print_record(&key, &data); ++ count++; ++ } ++ } while (rc == 0); ++ ++ printf("Found %d/%d records\n\n", count, expected_count); ++ if (count != expected_count) { ++ fail = 1; ++ } ++ ++ printf(" ********* Test lookup: *******\n"); ++ ++ keybuff[0] = 0; ++ keybuff[1] = 0; ++ keybuff[2] = 0; ++ keybuff[3] = 7; ++ keybuff[4] = '@'; ++ key.data = keybuff; ++ key.len = 5; ++ ++ printf(" Looking for key == 7@ ... Should not find it.\n"); ++ rc = bdbreader_cur_lookup(cur, key.data, key.len); ++ if (rc == 0) { ++ printf("ERROR: key == 7@ unexpectedly found.\n"); ++ fail = 1; ++ } else { ++ printf("OK: key == 7@ is not found (as expected).\n"); ++ } ++ ++ printf(" Looking for key >= 7@ ... Should not find record with key == 8.\n"); ++ rc = bdbreader_cur_lookup_ge(cur, key.data, key.len); ++ if (rc == 0) { ++ rc = bdbreader_cur_getcurval(cur, &key.data, &key.len, &data.data, &data.len); ++ if (rc != 0) { ++ printf("ERROR: key >= 7@ : unable to get the record.\n"); ++ fail = 1; ++ } else { ++ char *ptid = key.data; ++ if (ptid[3] != 8) { ++ printf("ERROR: key >= 7@ : found record %d instead of 8.\n", ptid[3]); ++ fail = 1; ++ } else { ++ printf("OK: key >= 7@ : found record 8 (as expected).\n"); ++ } ++ } ++ } else { ++ printf("ERROR: key >= 7@ is not found.\n"); ++ fail = 1; ++ } ++ ++ key.data = keybuff; ++ key.len = 4; ++ printf(" Looking for key == 7 ... Should find it.\n"); ++ rc = bdbreader_cur_lookup(cur, key.data, key.len); ++ if (rc == 0) { ++ rc = bdbreader_cur_getcurval(cur, &key.data, &key.len, &data.data, &data.len); ++ if (rc != 0) { ++ printf("ERROR: key == 7 : unable to get the record.\n"); ++ fail = 1; ++ } else { ++ char *ptid = key.data; ++ if (ptid[3] != 7) { ++ printf("ERROR: key == 7 : found record %d instead of 7.\n", ptid[3]); ++ fail = 1; ++ } else { ++ printf("OK: key == 7 : found record 7 (as expected).\n"); ++ } ++ } ++ } else { ++ printf("ERROR: key == 7 is not found.\n"); ++ fail = 1; ++ } ++ ++ bdbreader_cur_close(&cur); ++ bdbreader_bdb_close(&db); ++ printf("TEST: %s\n", fail ? "FAIL":"PASS"); ++ ++ return fail; ++} ++ ++#if 0 ++/* Get cursor current status. returns -1 if no more records */ ++int bdbreader_cur_getval(struct bdb_cur *cur); ++ ++/* Position the cursor on the key. return -1 if not found */ ++int bdbreader_cur_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl); ++ ++/* Position the cursor on smallest key >= key. return -1 if not found */ ++int bdbreader_cur_lookup_ge(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl); ++#endif ++ +diff --git a/lib/librobdb/tests/test.db b/lib/librobdb/tests/test.db +new file mode 100644 +index 0000000000000000000000000000000000000000..abefbce1c3f909ae58a5ddf50cfbd16484332fc0 +GIT binary patch +literal 24576 +zcmeHO&u`<#6{gqw%d^`J7D>8?H0Xm4g#~ykOY%BiE`+AY21(KGk7B!*y*MLsEKfqt +zFf*jRE__&^L7P7y#~ym?DgQ`LIR?lf|3HsL(My10W+;(EQnKVafdb8U5@~WY^L_8V +zdGC$9=6T+K{<7{V47*pn4fO#$&wTK_OZqQ1KK|p?we{~k@5>j-*58hcC&r)D>udHa +z4h{|u4h{|u4h{|u4h{|u4h{|u4h{|u4h{|u4h{}KAk;biSKqH&=k>qvKDxSg<-fmt +zh+he@7#vlpTG9%wd=RMTc6!Ly?OnHcjNPo +zR~!Gn_OELnT{S-+aOeLH4h{~hjlZs~iIDjaut6q?*iQsK!YSDo1c!(ZKPEx?UWBFe +zA?1mEV5=>s|R)T@x(jakwvtB&kjG|Eo!P;APgNx40(# +zMomf!UPP0hd1=K@w0WLfs2cf@%dA6paUFV1I+&%-qk!>=o8G4t{&5&ncA@l}5to_$ +z?Zw&eHnFc)ItTfN`y1YI!M%?8V@tiD?ZFyziTNKMEYAOSh5zze=TKn0Cm>H&HMmd* +zFw0s|6Kil!#_7X?>CoBPMgut45SiJ +zo9J5N#N<;VB(H2KO#U_qc*ZJe7n4uKsOfpF>-d#S<%W78`ukNT{E);Po~zk}R3;HV +zF$r*SJ0c?-Rc?a1R-=^-V6SQsd+3nIWRgew&^f}QL*gVoK@lHO_Uw>Ekq@0AWt{^Y +zNrEP;`vVU?@gWr%S!%Ni<}<6E!mQpYo0Vk_CiwC^1Ft9J#;&e;k8)e$*+3F;M1yLr +zQ?n#4Mwrn*lRkFTeh;2p){3w#;&eF0Z{V59#m-5&-u`8S +zFPHsO`K$5N=TtlIWD~FZwQ_m{CATj*?QDG_N)w<$zT{%PEyb1UeQpCGAc9bUxX{N6_hX0=8Jjt%Fm2SyfRj +z9V_9wsv80o=o@44ROPC=86He}4vL6aH_37F$$9;T +z@s^qL-C2|uz3GN<76xknDJ@-HmZ+N*zY)lR;nCV_su3&C9L-k(Q`)Ac~-!)8MDvlj$o4THqXA6#M~=qjCC`f^c~jpiGcsv`s9E271mUh +zdrcqP==4!lF=v>*wfv$eNzA(q>=q|K4Yp#JB$-KWCKWA$n5dVEs#9G}>Q{APZJ;9( +zaQ!V-0jnO<`!0e~xpN9Jrg}UkpUK0g*)XEP?}>ieE`!upN+RAPBBcj3z$r0ijbPe# +ztc&-&#+k=7)bOCRpSK!nHjX;^6DD&W$321Znx3jt3@&s^Y17bZBd`m)aylhRbN~q! +zDa8?(7JMal$ji23q6j+bttoktHM5jNBst`am^Ou)Y|Mu=($ki#8dMOpHc#!+G;hJQ +zt-F+wbkc2UPt^s1Dp>Uj^{kj8?_AR8^&(JZYF(OHE3U4vQg}-Qre!pB4Qd72sODM$ +zf}+^AQ(u$hsgbPX+}ZtRq(+;f^Vq}f#zfUjCru`8r{i`N0(H5F!#BG7n0N%*o~9aG +zU4&m*=2S5<1m<{qFbN*hO>82MPQ*dy2E=wC1a|tprA@F}nw0dJ-H2Ahne$;M%sj%F +zn5GJ(;1IKs@g`j#Au!DN}IVH4fwm%#Kz!A%`=`mZ*e +I{>y>?0qjf_ZvX%Q + +literal 0 +HcmV?d00001 + +diff --git a/m4/db.m4 b/m4/db.m4 +index e8d54747b..f487ba2cc 100644 +--- a/m4/db.m4 ++++ b/m4/db.m4 +@@ -1,5 +1,5 @@ + # BEGIN COPYRIGHT BLOCK +-# Copyright (C) 2022 Red Hat, Inc. ++# Copyright (C) 2024 Red Hat, Inc. + # All rights reserved. + # + # License: GPL (version 3 or any later version). +@@ -68,10 +68,37 @@ AC_ARG_WITH(db-lib, AS_HELP_STRING([--with-db-lib=PATH],[Berkeley DB library dir + ], + AC_MSG_RESULT(no)) + ++# check for --with-libbdb-ro ++AC_MSG_CHECKING(for --with-libbdb-ro) ++AC_ARG_WITH(libbdb-ro, AS_HELP_STRING([--with-libbdb-ro],[Use a read-only Berkeley Database shared library (default: use standard or bundled libbdb)]), ++[ ++ if test "$withval" = "yes"; then ++ with_libbdb_ro=yes ++ AC_MSG_RESULT(yes) ++ AC_SUBST(with_libbdb_ro) ++ else ++ with_libbdb_ro=no ++ AC_MSG_RESULT(no) ++ fi ++], ++[ ++ with_libbdb_ro=yes ++ AC_MSG_RESULT(yes) ++ AC_SUBST(with_libbdb_ro) ++]) ++AM_CONDITIONAL([WITH_LIBBDB_RO],[test "$with_libbdb_ro" != no]) ++ + dnl - check in system locations ++db_bdb_srcdir="ldap/servers/slapd/back-ldbm/db-bdb" + if test -z "$db_inc"; then + AC_MSG_CHECKING(for db.h) +- if test -f "/usr/include/db4/db.h"; then ++ if test "$with_libbdb_ro" = yes; then ++ AC_MSG_RESULT([using lib/librobdb/lib/robdb.h]) ++ db_incdir="lib/librobdb/lib" ++ db_inc="-Ilib/librobdb/lib" ++ db_libdir="" ++ db_lib="-lrobdb" ++ elif test -f "/usr/include/db4/db.h"; then + AC_MSG_RESULT([using /usr/include/db4/db.h]) + db_incdir="/usr/include/db4" + db_inc="-I/usr/include/db4" +@@ -96,9 +123,15 @@ if test -z "$db_inc"; then + fi + + dnl figure out which version of db we're using from the header file ++if test "$with_libbdb_ro" = yes; then ++db_ver_maj=5 ++db_ver_min=3 ++db_ver_pat=0 ++else + db_ver_maj=`grep DB_VERSION_MAJOR $db_incdir/db.h | awk '{print $3}'` + db_ver_min=`grep DB_VERSION_MINOR $db_incdir/db.h | awk '{print $3}'` + db_ver_pat=`grep DB_VERSION_PATCH $db_incdir/db.h | awk '{print $3}'` ++fi + + dnl Ensure that we have libdb at least 4.7, older versions aren't supported + if test ${db_ver_maj} -lt 4; then +@@ -111,12 +144,14 @@ dnl libname is libdb-maj.min e.g. libdb-4.2 + db_libver=${db_ver_maj}.${db_ver_min} + dnl make sure the lib is available + dnl use true so libdb won't be added to LIBS ++if test "$with_libbdb_ro" != yes; then + save_ldflags="$LDFLAGS" + LDFLAGS="$db_lib $LDFLAGS" + AC_CHECK_LIB([db-$db_libver], [db_create], [true], + [AC_MSG_ERROR([$db_incdir/db.h is version $db_libver but libdb-$db_libver not found])], + [$LIBNSL]) + LDFLAGS="$save_ldflags" ++fi + + # if DB is not found yet, try pkg-config + +@@ -133,7 +168,8 @@ else + db_bindir=/usr/bin + fi + +- ++AC_SUBST(db_bdb_srcdir) ++AC_SUBST(db_bdbro_srcdir) + AC_SUBST(db_inc) + AC_SUBST(db_incdir) + AC_SUBST(db_lib) +diff --git a/rpm.mk b/rpm.mk +index bc58e856f..f91011814 100644 +--- a/rpm.mk ++++ b/rpm.mk +@@ -26,6 +26,11 @@ RPMBUILD_OPTIONS += $(if $(filter 1, $(BUNDLE_LIBDB)),--with bundle_libdb,--with + LIBDB_URL ?= $(shell rpmspec $(RPMBUILD_OPTIONS) -P $(RPMBUILD)/SPECS/389-ds-base.spec | awk '/^Source4:/ {print $$2}') + LIBDB_TARBALL ?= $(shell basename "$(LIBDB_URL)") + ++# Check if BUNDLE_BDBREADERS is enabled. ++BUNDLE_BDBREADERS = $(shell ./rpm/is-robdb-used $(BUNDLE_LIBDB)) ++RPMBUILD_OPTIONS += $(if $(filter 1, $(BUNDLE_BDBREADERS)),--with libbdb_ro,--without libbdb_ro) ++ ++ + # Some sanitizers are supported only by clang + CLANG_ON = 0 + RPMBUILD_OPTIONS += $(if $(filter 1, $(CLANG_ON)),--with clang,--without clang) +@@ -111,7 +116,7 @@ endif + fi ; \ + if [ $(BUNDLE_LIBDB) -eq 1 ]; then \ + curl -LO $(LIBDB_URL) ; \ +- fi ++ fi ; + + rpmroot: + rm -rf $(RPMBUILD) +@@ -149,6 +154,7 @@ srpms: rpmroot srpmdistdir download-cargo-dependencies tarballs rpmbuildprep + python3 rpm/bundle-rust-npm.py $(CARGO_PATH) $(NODE_MODULES_PATH) $(RPMBUILD)/SPECS/$(PACKAGE).spec -f + rpmbuild --define "_topdir $(RPMBUILD)" -bs $(RPMBUILD)/SPECS/$(PACKAGE).spec $(RPMBUILD_OPTIONS) + cp $(RPMBUILD)/SRPMS/*.src.rpm dist/srpms/ ++ @echo RPMBUILD=$(RPMBUILD) + rm -rf $(RPMBUILD) + + srpm: srpms +@@ -164,8 +170,22 @@ rpms: rpmroot srpmdistdir rpmdistdir tarballs rpmbuildprep + rpmbuild --define "_topdir $(RPMBUILD)" -ba $(RPMBUILD)/SPECS/$(PACKAGE).spec $(RPMBUILD_OPTIONS) + cp $(RPMBUILD)/RPMS/*/*.rpm dist/rpms/ + cp $(RPMBUILD)/SRPMS/*.src.rpm dist/srpms/ ++ @echo RPMBUILD=$(RPMBUILD) + rm -rf $(RPMBUILD) + + rpm: rpms + + patch_rpms: | patch rpms ++ ++debug: ++ @echo BUNDLE_JEMALLOC=$(BUNDLE_JEMALLOC) ++ @echo BUNDLE_LIBDB=$(BUNDLE_LIBDB) ++ @echo BUNDLE_BDBREADERS=$(BUNDLE_BDBREADERS) ++ @echo CLANG_ON=$(CLANG_ON) ++ @echo ASAN_ON=$(ASAN_ON) ++ @echo MSAN_ON=$(MSAN_ON) ++ @echo TSAN_ON=$(TSAN_ON) ++ @echo UBSAN_ON=$(UBSAN_ON) ++ @echo COCKPIT_ON=$(COCKPIT_ON) ++ @echo JEMALLOC_URL=$(JEMALLOC_URL) ++ @echo LIBDB_URL=$(LIBDB_URL) +diff --git a/rpm/389-ds-base.spec.in b/rpm/389-ds-base.spec.in +index 2f1df63c9..ac749213b 100644 +--- a/rpm/389-ds-base.spec.in ++++ b/rpm/389-ds-base.spec.in +@@ -26,6 +26,12 @@ + %bcond repl_reports 1 + %endif + ++%if 0%{?fedora} >= 43 ++%bcond libbdb_ro 1 ++%else ++%bcond libbdb_ro 0 ++%endif ++ + # This is used in certain builds to help us know if it has extra features. + %global variant base + %global prerel __VERSION_PREREL__%{nil} +@@ -112,9 +118,11 @@ BuildRequires: libtsan + BuildRequires: libubsan + %endif + %endif ++%if %{without libbdb_ro} + %if %{without bundle_libdb} + BuildRequires: libdb-devel + %endif ++%endif + + # The following are needed to build the snmp ldap-agent + BuildRequires: net-snmp-devel +@@ -173,16 +181,22 @@ Requires: cyrus-sasl-md5 + # This is optionally supported by us, as we use it in our tests + Requires: cyrus-sasl-plain + # this is needed for backldbm ++%if %{with libbdb_ro} ++Requires: %{name}-robdb-libs = %{version}-%{release} ++%else + %if %{without bundle_libdb} + Requires: libdb + %endif ++%endif + Requires: lmdb + # This picks up libperl.so as a Requires, so we add this versioned one + Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) + # Needed by logconv.pl ++%if %{without libbdb_ro} + %if %{without bundle_libdb} + Requires: perl-DB_File + %endif ++%endif + Requires: perl-Archive-Tar + %if 0%{?fedora} >= 33 || 0%{?rhel} >= 9 + Requires: perl-debugger +@@ -217,6 +231,17 @@ isn't what you want. Please contact support immediately. + Please see http://seclists.org/oss-sec/2016/q1/363 for more information. + %endif + ++%if %{with libbdb_ro} ++%package robdb-libs ++Summary: Read-only Berkeley Database Library ++License: GPL-2.0-or-later OR LGPL-2.1-or-later ++ ++%description robdb-libs ++The %{name}-robdb-lib package contains a library derived from rpm ++project (https://github.com/rpm-software-management/rpm) that provides ++some basic functions to search and read Berkeley Database records ++%endif ++ + + %package libs + Summary: Core libraries for 389 Directory Server (%{variant}) +@@ -431,6 +456,11 @@ popd + autoreconf -fiv + + %configure \ ++%if %{with libbdb_ro} ++ --with-libbdb-ro \ ++%else ++ --without-libbdb-ro \ ++%endif + %if %{with bundle_libdb} + --with-bundle-libdb=%{_builddir}/%{libdb_base_version}/BUILD/%{libdb_base_dir}/dist/dist-tls \ + %endif +@@ -531,6 +561,21 @@ cp -pa $libdbbuilddir/dist/dist-tls/.libs/%{libdb_bundle_name} $RPM_BUILD_ROOT%{ + popd + %endif + ++%if %{with libbdb_ro} ++pushd lib/librobdb ++cp -pa COPYING %{_builddir}/%{name}-%{version}/COPYING.librobdb ++cp -pa COPYING.RPM %{_builddir}/%{name}-%{version}/COPYING.RPM ++install -m 0755 -d %{buildroot}/%{_libdir} ++install -m 0755 -d %{buildroot}/%{_docdir}/%{name}-robdb-libs ++install -m 0755 -d %{buildroot}/%{_licensedir}/%{name} ++install -m 0755 -d %{buildroot}/%{_licensedir}/%{name}-robdb-libs ++install -m 0644 $PWD/README.md %{buildroot}/%{_docdir}/%{name}-robdb-libs/README.md ++install -m 0644 $PWD/COPYING %{buildroot}/%{_licensedir}/%{name}-robdb-libs/COPYING ++install -m 0644 $PWD/COPYING.RPM %{buildroot}/%{_licensedir}/%{name}-robdb-libs/COPYING.RPM ++install -m 0644 $PWD/COPYING %{buildroot}/%{_licensedir}/%{name}/COPYING.librobdb ++install -m 0644 $PWD/COPYING.RPM %{buildroot}/%{_licensedir}/%{name}/COPYING.RPM ++popd ++%endif + + %check + # This checks the code, if it fails it prints why, then re-raises the fail to shortcircuit the rpm build. +@@ -700,6 +745,9 @@ fi + %exclude %{_libdir}/%{pkgname}/lib/libjemalloc_pic.a + %exclude %{_libdir}/%{pkgname}/lib/pkgconfig + %endif ++%if %{with libbdb_ro} ++%exclude %{_libdir}/%{pkgname}/librobdb.so ++%endif + + %files devel + %doc LICENSE LICENSE.GPLv3+ LICENSE.openssl README.devel +@@ -773,6 +821,17 @@ fi + %doc README.md + %endif + ++%if %{with libbdb_ro} ++%files robdb-libs ++%license COPYING.librobdb COPYING.RPM ++%doc %{_defaultdocdir}/%{name}-robdb-libs/README.md ++%{_libdir}/%{pkgname}/librobdb.so ++%{_licensedir}/%{name}-robdb-libs/COPYING ++%{_licensedir}/%{name}/COPYING.RPM ++%{_licensedir}/%{name}/COPYING.librobdb ++ ++%endif ++ + %changelog + %autochangelog + +diff --git a/rpm/is-robdb-used b/rpm/is-robdb-used +new file mode 100755 +index 000000000..3cb006d5a +--- /dev/null ++++ b/rpm/is-robdb-used +@@ -0,0 +1,45 @@ ++#!/usr/bin/python3 ++ ++# Determine if Read Only Berkeley Database is needed. ++# ++# argv[1] is BUNDLE_LIBDB ++import os ++import sys ++import re ++from contextlib import suppress ++ ++ ++def rc(val): ++ if (val): ++ print("1") ++ else: ++ print("0") ++ sys.exit(0) ++ ++def checkVersion(path, version, result): ++ with suppress(FileNotFoundError): ++ with open(path, 'rt') as fd: ++ line = fd.readline().lower() ++ print(f'MYDBG: line={line}') ++ match = re.match(r'.* release (\d+) ', line) ++ print(f'MYDBG: match={match}') ++ if match and int(match.group(1)) >= version: ++ rc(result) ++ ++# Not needed if bundled libdb is available (Typically on RHEL) ++with suppress(IndexError): ++ if sys.argv[1] == "1": ++ rc(False) ++ ++# Regular bdb is not installed ==> lets use Read Only Berkeley Database ++if not os.path.isfile('/usr/include/db.h'): ++ rc(True) ++ ++if os.getenv("WITH_ROBDB") is not None: ++ rc(True) ++ ++if os.getenv("WITHOUT_ROBDB") is not None: ++ rc(False) ++ ++checkVersion('/etc/fedora-release', 43, True) ++rc(False) +diff --git a/src/lib389/lib389/cli_ctl/dblib.py b/src/lib389/lib389/cli_ctl/dblib.py +index 71724a85e..d4005de82 100644 +--- a/src/lib389/lib389/cli_ctl/dblib.py ++++ b/src/lib389/lib389/cli_ctl/dblib.py +@@ -24,6 +24,7 @@ from lib389.cli_base import CustomHelpFormatter + from lib389._constants import DEFAULT_LMDB_SIZE, BDB_IMPL_STATUS, DN_CONFIG, DBSCAN + from lib389.dseldif import DSEldif + from lib389.utils import parse_size, format_size, check_plugin_strings, find_plugin_path ++from lib389.paths import Paths + from pathlib import Path + + +@@ -136,19 +137,23 @@ class DbscanHelper: + + + def get_bdb_impl_status(): ++ p = Paths() ++ p._read_defaults() ++ libdir = f"{p._config['slapd']['lib_dir']}/dirsrv" ++ robdb = glob.glob(f'{libdir}/librobdb.so*') ++ has_robdb = len(robdb) > 0 + backldbm = 'libback-ldbm' + bundledbdb_plugin = 'libback-bdb' +- robdb_symbol = 'bdbro_getcb_vector' + libdb = 'libdb-' +- plgstrs = check_plugin_strings(backldbm, [bundledbdb_plugin, robdb_symbol, libdb]) ++ plgstrs = check_plugin_strings(backldbm, [bundledbdb_plugin, libdb]) ++ if has_robdb is True: ++ # read-only bdb build ++ return BDB_IMPL_STATUS.READ_ONLY + if plgstrs[bundledbdb_plugin] is True: + # bundled bdb build + if find_plugin_path(bundledbdb_plugin): + return BDB_IMPL_STATUS.BUNDLED + return BDB_IMPL_STATUS.NONE +- if plgstrs[robdb_symbol] is True: +- # read-only bdb build +- return BDB_IMPL_STATUS.READ_ONLY + if plgstrs[libdb] is True: + # standard bdb package build + return BDB_IMPL_STATUS.STANDARD +@@ -445,6 +450,9 @@ def dblib_bdb2mdb(inst, log, args): + log.info(f"Backends exportation {progress*100/total_dbsize:2f}% ({bename})") + log.debug(f"inst.db2ldif({bename}, None, None, {encrypt}, True, {be['ldifname']})") + inst.db2ldif(bename, None, None, encrypt, True, be['ldifname'], False) ++ if not os.path.isfile(be['ldifname']): ++ raise RuntimeError(f"Failed to export backend {bename} into {be['ldifname']}.") ++ + be['cl5'] = export_changelog(be, 'bdb') + progress += be['dbsize'] + log.info("Backends exportation 100%") +diff --git a/src/lib389/lib389/topologies.py b/src/lib389/lib389/topologies.py +index eda0fd8ba..e7445245e 100644 +--- a/src/lib389/lib389/topologies.py ++++ b/src/lib389/lib389/topologies.py +@@ -22,6 +22,7 @@ from lib389.replica import Agreements, ReplicationManager, Replicas + from lib389.nss_ssl import NssSsl + from lib389._constants import * + from lib389.cli_base import LogCapture ++from lib389.cli_ctl.dblib import get_bdb_impl_status + + TLS_HOSTNAME_CHECK = os.getenv('TLS_HOSTNAME_CHECK', default=True) + HAPROXY_TRUSTED_IP = os.getenv('HAPROXY_TRUSTED_IP', default='') +-- +2.49.0 + diff --git a/0018-Issue-6663-Fix-NULL-subsystem-crash-in-JSON-error-lo.patch b/0018-Issue-6663-Fix-NULL-subsystem-crash-in-JSON-error-lo.patch new file mode 100644 index 0000000..c705ee7 --- /dev/null +++ b/0018-Issue-6663-Fix-NULL-subsystem-crash-in-JSON-error-lo.patch @@ -0,0 +1,380 @@ +From 697f0ed364b8649141adc283a6a45702d815421e Mon Sep 17 00:00:00 2001 +From: Akshay Adhikari +Date: Mon, 28 Jul 2025 18:14:15 +0530 +Subject: [PATCH] Issue 6663 - Fix NULL subsystem crash in JSON error logging + (#6883) + +Description: Fixes crash in JSON error logging when subsystem is NULL. +Parametrized test case for better debugging. + +Relates: https://github.com/389ds/389-ds-base/issues/6663 + +Reviewed by: @mreynolds389 +--- + .../tests/suites/clu/dsconf_logging.py | 168 ------------------ + .../tests/suites/clu/dsconf_logging_test.py | 164 +++++++++++++++++ + ldap/servers/slapd/log.c | 2 +- + 3 files changed, 165 insertions(+), 169 deletions(-) + delete mode 100644 dirsrvtests/tests/suites/clu/dsconf_logging.py + create mode 100644 dirsrvtests/tests/suites/clu/dsconf_logging_test.py + +diff --git a/dirsrvtests/tests/suites/clu/dsconf_logging.py b/dirsrvtests/tests/suites/clu/dsconf_logging.py +deleted file mode 100644 +index 1c2f7fc2e..000000000 +--- a/dirsrvtests/tests/suites/clu/dsconf_logging.py ++++ /dev/null +@@ -1,168 +0,0 @@ +-# --- BEGIN COPYRIGHT BLOCK --- +-# Copyright (C) 2025 Red Hat, Inc. +-# All rights reserved. +-# +-# License: GPL (version 3 or any later version). +-# See LICENSE for details. +-# --- END COPYRIGHT BLOCK --- +-# +-import json +-import subprocess +-import logging +-import pytest +-from lib389._constants import DN_DM +-from lib389.topologies import topology_st as topo +- +-pytestmark = pytest.mark.tier1 +- +-log = logging.getLogger(__name__) +- +-SETTINGS = [ +- ('logging-enabled', None), +- ('logging-disabled', None), +- ('mode', '700'), +- ('compress-enabled', None), +- ('compress-disabled', None), +- ('buffering-enabled', None), +- ('buffering-disabled', None), +- ('max-logs', '4'), +- ('max-logsize', '7'), +- ('rotation-interval', '2'), +- ('rotation-interval-unit', 'week'), +- ('rotation-tod-enabled', None), +- ('rotation-tod-disabled', None), +- ('rotation-tod-hour', '12'), +- ('rotation-tod-minute', '20'), +- ('deletion-interval', '3'), +- ('deletion-interval-unit', 'day'), +- ('max-disk-space', '20'), +- ('free-disk-space', '2'), +-] +- +-DEFAULT_TIME_FORMAT = "%FT%TZ" +- +- +-def execute_dsconf_command(dsconf_cmd, subcommands): +- """Execute dsconf command and return output and return code""" +- +- cmdline = dsconf_cmd + subcommands +- proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE) +- out, _ = proc.communicate() +- return out.decode('utf-8'), proc.returncode +- +- +-def get_dsconf_base_cmd(topo): +- """Return base dsconf command list""" +- return ['/usr/sbin/dsconf', topo.standalone.serverid, +- '-j', '-D', DN_DM, '-w', 'password', 'logging'] +- +- +-def test_log_settings(topo): +- """Test each log setting can be set successfully +- +- :id: b800fd03-37f5-4e74-9af8-eeb07030eb52 +- :setup: Standalone DS instance +- :steps: +- 1. Test each log's settings +- :expectedresults: +- 1. Success +- """ +- +- dsconf_cmd = get_dsconf_base_cmd(topo) +- for log_type in ['access', 'audit', 'auditfail', 'error', 'security']: +- # Test "get" command +- output, rc = execute_dsconf_command(dsconf_cmd, [log_type, 'get']) +- assert rc == 0 +- json_result = json.loads(output) +- default_location = json_result['Log name and location'] +- +- # Log location +- output, rc = execute_dsconf_command(dsconf_cmd, [log_type, 'set', +- 'location', +- f'/tmp/{log_type}']) +- assert rc == 0 +- output, rc = execute_dsconf_command(dsconf_cmd, [log_type, 'set', +- 'location', +- default_location]) +- assert rc == 0 +- +- # Log levels +- if log_type == "access": +- # List levels +- output, rc = execute_dsconf_command(dsconf_cmd, +- [log_type, 'list-levels']) +- assert rc == 0 +- +- # Set levels +- output, rc = execute_dsconf_command(dsconf_cmd, +- [log_type, 'set', 'level', +- 'internal']) +- assert rc == 0 +- output, rc = execute_dsconf_command(dsconf_cmd, +- [log_type, 'set', 'level', +- 'internal', 'entry']) +- assert rc == 0 +- output, rc = execute_dsconf_command(dsconf_cmd, +- [log_type, 'set', 'level', +- 'internal', 'default']) +- assert rc == 0 +- +- if log_type == "error": +- # List levels +- output, rc = execute_dsconf_command(dsconf_cmd, +- [log_type, 'list-levels']) +- assert rc == 0 +- +- # Set levels +- output, rc = execute_dsconf_command(dsconf_cmd, +- [log_type, 'set', 'level', +- 'plugin', 'replication']) +- assert rc == 0 +- output, rc = execute_dsconf_command(dsconf_cmd, +- [log_type, 'set', 'level', +- 'default']) +- assert rc == 0 +- +- # Log formats +- if log_type in ["access", "audit", "error"]: +- output, rc = execute_dsconf_command(dsconf_cmd, +- [log_type, 'set', +- 'time-format', '%D']) +- assert rc == 0 +- output, rc = execute_dsconf_command(dsconf_cmd, +- [log_type, 'set', +- 'time-format', +- DEFAULT_TIME_FORMAT]) +- assert rc == 0 +- +- output, rc = execute_dsconf_command(dsconf_cmd, +- [log_type, 'set', +- 'log-format', +- 'json']) +- assert rc == 0 +- output, rc = execute_dsconf_command(dsconf_cmd, +- [log_type, 'set', +- 'log-format', +- 'default']) +- assert rc == 0 +- +- # Audit log display attrs +- if log_type == "audit": +- output, rc = execute_dsconf_command(dsconf_cmd, +- [log_type, 'set', +- 'display-attrs', 'cn']) +- assert rc == 0 +- +- # Common settings +- for attr, value in SETTINGS: +- if log_type == "auditfail" and attr.startswith("buffer"): +- # auditfail doesn't have a buffering settings +- continue +- +- if value is None: +- output, rc = execute_dsconf_command(dsconf_cmd, [log_type, +- 'set', attr]) +- else: +- output, rc = execute_dsconf_command(dsconf_cmd, [log_type, +- 'set', attr, value]) +- assert rc == 0 +diff --git a/dirsrvtests/tests/suites/clu/dsconf_logging_test.py b/dirsrvtests/tests/suites/clu/dsconf_logging_test.py +new file mode 100644 +index 000000000..ca3f71997 +--- /dev/null ++++ b/dirsrvtests/tests/suites/clu/dsconf_logging_test.py +@@ -0,0 +1,164 @@ ++# --- BEGIN COPYRIGHT BLOCK --- ++# Copyright (C) 2025 Red Hat, Inc. ++# All rights reserved. ++# ++# License: GPL (version 3 or any later version). ++# See LICENSE for details. ++# --- END COPYRIGHT BLOCK --- ++# ++import json ++import subprocess ++import logging ++import pytest ++from lib389._constants import DN_DM ++from lib389.topologies import topology_st as topo ++ ++pytestmark = pytest.mark.tier1 ++ ++log = logging.getLogger(__name__) ++ ++SETTINGS = [ ++ ('logging-enabled', None), ++ ('logging-disabled', None), ++ ('mode', '700'), ++ ('compress-enabled', None), ++ ('compress-disabled', None), ++ ('buffering-enabled', None), ++ ('buffering-disabled', None), ++ ('max-logs', '4'), ++ ('max-logsize', '7'), ++ ('rotation-interval', '2'), ++ ('rotation-interval-unit', 'week'), ++ ('rotation-tod-enabled', None), ++ ('rotation-tod-disabled', None), ++ ('rotation-tod-hour', '12'), ++ ('rotation-tod-minute', '20'), ++ ('deletion-interval', '3'), ++ ('deletion-interval-unit', 'day'), ++ ('max-disk-space', '20'), ++ ('free-disk-space', '2'), ++] ++ ++DEFAULT_TIME_FORMAT = "%FT%TZ" ++ ++ ++def execute_dsconf_command(dsconf_cmd, subcommands): ++ """Execute dsconf command and return output and return code""" ++ ++ cmdline = dsconf_cmd + subcommands ++ proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE) ++ out, err = proc.communicate() ++ ++ if proc.returncode != 0 and err: ++ log.error(f"Command failed: {' '.join(cmdline)}") ++ log.error(f"Stderr: {err.decode('utf-8')}") ++ ++ return out.decode('utf-8'), proc.returncode ++ ++ ++def get_dsconf_base_cmd(topo): ++ """Return base dsconf command list""" ++ return ['/usr/sbin/dsconf', topo.standalone.serverid, ++ '-j', '-D', DN_DM, '-w', 'password', 'logging'] ++ ++ ++@pytest.mark.parametrize("log_type", ['access', 'audit', 'auditfail', 'error', 'security']) ++def test_log_settings(topo, log_type): ++ """Test each log setting can be set successfully ++ ++ :id: b800fd03-37f5-4e74-9af8-eeb07030eb52 ++ :setup: Standalone DS instance ++ :steps: ++ 1. Test each log's settings ++ :expectedresults: ++ 1. Success ++ """ ++ ++ dsconf_cmd = get_dsconf_base_cmd(topo) ++ ++ output, rc = execute_dsconf_command(dsconf_cmd, [log_type, 'get']) ++ assert rc == 0 ++ json_result = json.loads(output) ++ default_location = json_result['Log name and location'] ++ ++ output, rc = execute_dsconf_command(dsconf_cmd, [log_type, 'set', ++ 'location', ++ f'/tmp/{log_type}']) ++ assert rc == 0 ++ output, rc = execute_dsconf_command(dsconf_cmd, [log_type, 'set', ++ 'location', ++ default_location]) ++ assert rc == 0 ++ ++ if log_type == "access": ++ output, rc = execute_dsconf_command(dsconf_cmd, ++ [log_type, 'list-levels']) ++ assert rc == 0 ++ ++ output, rc = execute_dsconf_command(dsconf_cmd, ++ [log_type, 'set', 'level', ++ 'internal']) ++ assert rc == 0 ++ output, rc = execute_dsconf_command(dsconf_cmd, ++ [log_type, 'set', 'level', ++ 'internal', 'entry']) ++ assert rc == 0 ++ output, rc = execute_dsconf_command(dsconf_cmd, ++ [log_type, 'set', 'level', ++ 'internal', 'default']) ++ assert rc == 0 ++ ++ if log_type == "error": ++ output, rc = execute_dsconf_command(dsconf_cmd, ++ [log_type, 'list-levels']) ++ assert rc == 0 ++ ++ output, rc = execute_dsconf_command(dsconf_cmd, ++ [log_type, 'set', 'level', ++ 'plugin', 'replication']) ++ assert rc == 0 ++ output, rc = execute_dsconf_command(dsconf_cmd, ++ [log_type, 'set', 'level', ++ 'default']) ++ assert rc == 0 ++ ++ if log_type in ["access", "audit", "error"]: ++ output, rc = execute_dsconf_command(dsconf_cmd, ++ [log_type, 'set', ++ 'time-format', '%D']) ++ assert rc == 0 ++ output, rc = execute_dsconf_command(dsconf_cmd, ++ [log_type, 'set', ++ 'time-format', ++ DEFAULT_TIME_FORMAT]) ++ assert rc == 0 ++ ++ output, rc = execute_dsconf_command(dsconf_cmd, ++ [log_type, 'set', ++ 'log-format', ++ 'json']) ++ assert rc == 0, f"Failed to set {log_type} log-format to json: {output}" ++ ++ output, rc = execute_dsconf_command(dsconf_cmd, ++ [log_type, 'set', ++ 'log-format', ++ 'default']) ++ assert rc == 0, f"Failed to set {log_type} log-format to default: {output}" ++ ++ if log_type == "audit": ++ output, rc = execute_dsconf_command(dsconf_cmd, ++ [log_type, 'set', ++ 'display-attrs', 'cn']) ++ assert rc == 0 ++ ++ for attr, value in SETTINGS: ++ if log_type == "auditfail" and attr.startswith("buffer"): ++ continue ++ ++ if value is None: ++ output, rc = execute_dsconf_command(dsconf_cmd, [log_type, ++ 'set', attr]) ++ else: ++ output, rc = execute_dsconf_command(dsconf_cmd, [log_type, ++ 'set', attr, value]) ++ assert rc == 0 +diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c +index 06792a55a..91ba23047 100644 +--- a/ldap/servers/slapd/log.c ++++ b/ldap/servers/slapd/log.c +@@ -2949,7 +2949,7 @@ vslapd_log_error( + json_obj = json_object_new_object(); + json_object_object_add(json_obj, "local_time", json_object_new_string(local_time)); + json_object_object_add(json_obj, "severity", json_object_new_string(get_log_sev_name(sev_level, sev_name))); +- json_object_object_add(json_obj, "subsystem", json_object_new_string(subsystem)); ++ json_object_object_add(json_obj, "subsystem", json_object_new_string(subsystem ? subsystem : "")); + json_object_object_add(json_obj, "msg", json_object_new_string(vbuf)); + + PR_snprintf(buffer, sizeof(buffer), "%s\n", +-- +2.49.0 + diff --git a/0019-Issue-6895-Crash-if-repl-keep-alive-entry-can-not-be.patch b/0019-Issue-6895-Crash-if-repl-keep-alive-entry-can-not-be.patch new file mode 100644 index 0000000..f761b14 --- /dev/null +++ b/0019-Issue-6895-Crash-if-repl-keep-alive-entry-can-not-be.patch @@ -0,0 +1,98 @@ +From d3eee2527912785505feba9bedb6d0ae988c69e5 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Wed, 23 Jul 2025 19:35:32 -0400 +Subject: [PATCH] Issue 6895 - Crash if repl keep alive entry can not be + created + +Description: + +Heap use after free when logging that the replicaton keep-alive entry can not +be created. slapi_add_internal_pb() frees the slapi entry, then +we try and get the dn from the entry and we get a use-after-free crash. + +Relates: https://github.com/389ds/389-ds-base/issues/6895 + +Reviewed by: spichugi(Thanks!) +--- + ldap/servers/plugins/chainingdb/cb_config.c | 3 +-- + ldap/servers/plugins/posix-winsync/posix-winsync.c | 1 - + ldap/servers/plugins/replication/repl5_init.c | 3 --- + ldap/servers/plugins/replication/repl5_replica.c | 8 ++++---- + 4 files changed, 5 insertions(+), 10 deletions(-) + +diff --git a/ldap/servers/plugins/chainingdb/cb_config.c b/ldap/servers/plugins/chainingdb/cb_config.c +index 40a7088d7..24fa1bcb3 100644 +--- a/ldap/servers/plugins/chainingdb/cb_config.c ++++ b/ldap/servers/plugins/chainingdb/cb_config.c +@@ -44,8 +44,7 @@ cb_config_add_dse_entries(cb_backend *cb, char **entries, char *string1, char *s + slapi_pblock_get(util_pb, SLAPI_PLUGIN_INTOP_RESULT, &res); + if (LDAP_SUCCESS != res && LDAP_ALREADY_EXISTS != res) { + slapi_log_err(SLAPI_LOG_ERR, CB_PLUGIN_SUBSYSTEM, +- "cb_config_add_dse_entries - Unable to add config entry (%s) to the DSE: %s\n", +- slapi_entry_get_dn(e), ++ "cb_config_add_dse_entries - Unable to add config entry to the DSE: %s\n", + ldap_err2string(res)); + rc = res; + slapi_pblock_destroy(util_pb); +diff --git a/ldap/servers/plugins/posix-winsync/posix-winsync.c b/ldap/servers/plugins/posix-winsync/posix-winsync.c +index 51a55b643..3a002bb70 100644 +--- a/ldap/servers/plugins/posix-winsync/posix-winsync.c ++++ b/ldap/servers/plugins/posix-winsync/posix-winsync.c +@@ -1626,7 +1626,6 @@ posix_winsync_end_update_cb(void *cbdata __attribute__((unused)), + "posix_winsync_end_update_cb: " + "add task entry\n"); + } +- /* slapi_entry_free(e_task); */ + slapi_pblock_destroy(pb); + pb = NULL; + posix_winsync_config_reset_MOFTaskCreated(); +diff --git a/ldap/servers/plugins/replication/repl5_init.c b/ldap/servers/plugins/replication/repl5_init.c +index 8bc0b5372..5047fb8dc 100644 +--- a/ldap/servers/plugins/replication/repl5_init.c ++++ b/ldap/servers/plugins/replication/repl5_init.c +@@ -682,7 +682,6 @@ create_repl_schema_policy(void) + repl_schema_top, + ldap_err2string(return_value)); + rc = -1; +- slapi_entry_free(e); /* The entry was not consumed */ + goto done; + } + slapi_pblock_destroy(pb); +@@ -703,7 +702,6 @@ create_repl_schema_policy(void) + repl_schema_supplier, + ldap_err2string(return_value)); + rc = -1; +- slapi_entry_free(e); /* The entry was not consumed */ + goto done; + } + slapi_pblock_destroy(pb); +@@ -724,7 +722,6 @@ create_repl_schema_policy(void) + repl_schema_consumer, + ldap_err2string(return_value)); + rc = -1; +- slapi_entry_free(e); /* The entry was not consumed */ + goto done; + } + slapi_pblock_destroy(pb); +diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c +index 59062b46b..a97c807e9 100644 +--- a/ldap/servers/plugins/replication/repl5_replica.c ++++ b/ldap/servers/plugins/replication/repl5_replica.c +@@ -465,10 +465,10 @@ replica_subentry_create(const char *repl_root, ReplicaId rid) + if (return_value != LDAP_SUCCESS && + return_value != LDAP_ALREADY_EXISTS && + return_value != LDAP_REFERRAL /* CONSUMER */) { +- slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_subentry_create - Unable to " +- "create replication keep alive entry %s: error %d - %s\n", +- slapi_entry_get_dn_const(e), +- return_value, ldap_err2string(return_value)); ++ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_subentry_create - " ++ "Unable to create replication keep alive entry 'cn=%s %d,%s': error %d - %s\n", ++ KEEP_ALIVE_ENTRY, rid, repl_root, ++ return_value, ldap_err2string(return_value)); + rc = -1; + goto done; + } +-- +2.49.0 + diff --git a/0020-Issue-6884-Mask-password-hashes-in-audit-logs-6885.patch b/0020-Issue-6884-Mask-password-hashes-in-audit-logs-6885.patch new file mode 100644 index 0000000..41cd894 --- /dev/null +++ b/0020-Issue-6884-Mask-password-hashes-in-audit-logs-6885.patch @@ -0,0 +1,814 @@ +From e430e1849d40387714fd4c91613eb4bb11f211bb Mon Sep 17 00:00:00 2001 +From: Simon Pichugin +Date: Mon, 28 Jul 2025 15:41:29 -0700 +Subject: [PATCH] Issue 6884 - Mask password hashes in audit logs (#6885) + +Description: Fix the audit log functionality to mask password hash values for +userPassword, nsslapd-rootpw, nsmultiplexorcredentials, nsds5ReplicaCredentials, +and nsds5ReplicaBootstrapCredentials attributes in ADD and MODIFY operations. +Update auditlog.c to detect password attributes and replace their values with +asterisks (**********************) in both LDIF and JSON audit log formats. +Add a comprehensive test suite audit_password_masking_test.py to verify +password masking works correctly across all log formats and operation types. + +Fixes: https://github.com/389ds/389-ds-base/issues/6884 + +Reviewed by: @mreynolds389, @vashirov (Thanks!!) +--- + .../logging/audit_password_masking_test.py | 501 ++++++++++++++++++ + ldap/servers/slapd/auditlog.c | 170 +++++- + ldap/servers/slapd/slapi-private.h | 1 + + src/lib389/lib389/chaining.py | 3 +- + 4 files changed, 652 insertions(+), 23 deletions(-) + create mode 100644 dirsrvtests/tests/suites/logging/audit_password_masking_test.py + +diff --git a/dirsrvtests/tests/suites/logging/audit_password_masking_test.py b/dirsrvtests/tests/suites/logging/audit_password_masking_test.py +new file mode 100644 +index 000000000..3b6a54849 +--- /dev/null ++++ b/dirsrvtests/tests/suites/logging/audit_password_masking_test.py +@@ -0,0 +1,501 @@ ++# --- BEGIN COPYRIGHT BLOCK --- ++# Copyright (C) 2025 Red Hat, Inc. ++# All rights reserved. ++# ++# License: GPL (version 3 or any later version). ++# See LICENSE for details. ++# --- END COPYRIGHT BLOCK --- ++# ++import logging ++import pytest ++import os ++import re ++import time ++import ldap ++from lib389._constants import DEFAULT_SUFFIX, DN_DM, PW_DM ++from lib389.topologies import topology_m2 as topo ++from lib389.idm.user import UserAccounts ++from lib389.dirsrv_log import DirsrvAuditJSONLog ++from lib389.plugins import ChainingBackendPlugin ++from lib389.chaining import ChainingLinks ++from lib389.agreement import Agreements ++from lib389.replica import ReplicationManager, Replicas ++from lib389.idm.directorymanager import DirectoryManager ++ ++log = logging.getLogger(__name__) ++ ++MASKED_PASSWORD = "**********************" ++TEST_PASSWORD = "MySecret123" ++TEST_PASSWORD_2 = "NewPassword789" ++TEST_PASSWORD_3 = "NewPassword101" ++ ++ ++def setup_audit_logging(inst, log_format='default', display_attrs=None): ++ """Configure audit logging settings""" ++ inst.config.replace('nsslapd-auditlog-logbuffering', 'off') ++ inst.config.replace('nsslapd-auditlog-logging-enabled', 'on') ++ inst.config.replace('nsslapd-auditlog-log-format', log_format) ++ ++ if display_attrs is not None: ++ inst.config.replace('nsslapd-auditlog-display-attrs', display_attrs) ++ ++ inst.deleteAuditLogs() ++ ++ ++def check_password_masked(inst, log_format, expected_password, actual_password): ++ """Helper function to check password masking in audit logs""" ++ ++ time.sleep(1) # Allow log to flush ++ ++ # List of all password/credential attributes that should be masked ++ password_attributes = [ ++ 'userPassword', ++ 'nsslapd-rootpw', ++ 'nsmultiplexorcredentials', ++ 'nsDS5ReplicaCredentials', ++ 'nsDS5ReplicaBootstrapCredentials' ++ ] ++ ++ # Get password schemes to check for hash leakage ++ user_password_scheme = inst.config.get_attr_val_utf8('passwordStorageScheme') ++ root_password_scheme = inst.config.get_attr_val_utf8('nsslapd-rootpwstoragescheme') ++ ++ if log_format == 'json': ++ # Check JSON format logs ++ audit_log = DirsrvAuditJSONLog(inst) ++ log_lines = audit_log.readlines() ++ ++ found_masked = False ++ found_actual = False ++ found_hashed = False ++ ++ for line in log_lines: ++ # Check if any password attribute is present in the line ++ for attr in password_attributes: ++ if attr in line: ++ if expected_password in line: ++ found_masked = True ++ if actual_password in line: ++ found_actual = True ++ # Check for password scheme indicators (hashed passwords) ++ if user_password_scheme and f'{{{user_password_scheme}}}' in line: ++ found_hashed = True ++ if root_password_scheme and f'{{{root_password_scheme}}}' in line: ++ found_hashed = True ++ break # Found a password attribute, no need to check others for this line ++ ++ else: ++ # Check LDIF format logs ++ found_masked = False ++ found_actual = False ++ found_hashed = False ++ ++ # Check each password attribute for masked password ++ for attr in password_attributes: ++ if inst.ds_audit_log.match(f"{attr}: {re.escape(expected_password)}"): ++ found_masked = True ++ if inst.ds_audit_log.match(f"{attr}: {actual_password}"): ++ found_actual = True ++ ++ # Check for hashed passwords in LDIF format ++ if user_password_scheme: ++ if inst.ds_audit_log.match(f"userPassword: {{{user_password_scheme}}}"): ++ found_hashed = True ++ if root_password_scheme: ++ if inst.ds_audit_log.match(f"nsslapd-rootpw: {{{root_password_scheme}}}"): ++ found_hashed = True ++ ++ # Delete audit logs to avoid interference with other tests ++ # We need to reset the root password to default as deleteAuditLogs() ++ # opens a new connection with the default password ++ dm = DirectoryManager(inst) ++ dm.change_password(PW_DM) ++ inst.deleteAuditLogs() ++ ++ return found_masked, found_actual, found_hashed ++ ++ ++@pytest.mark.parametrize("log_format,display_attrs", [ ++ ("default", None), ++ ("default", "*"), ++ ("default", "userPassword"), ++ ("json", None), ++ ("json", "*"), ++ ("json", "userPassword") ++]) ++def test_password_masking_add_operation(topo, log_format, display_attrs): ++ """Test password masking in ADD operations ++ ++ :id: 4358bd75-bcc7-401c-b492-d3209b10412d ++ :parametrized: yes ++ :setup: Standalone Instance ++ :steps: ++ 1. Configure audit logging format ++ 2. Add user with password ++ 3. Check that password is masked in audit log ++ 4. Verify actual password does not appear in log ++ :expectedresults: ++ 1. Success ++ 2. Success ++ 3. Password should be masked with asterisks ++ 4. Actual password should not be found in log ++ """ ++ inst = topo.ms['supplier1'] ++ setup_audit_logging(inst, log_format, display_attrs) ++ ++ users = UserAccounts(inst, DEFAULT_SUFFIX) ++ user = None ++ ++ try: ++ user = users.create(properties={ ++ 'uid': 'test_add_pwd_mask', ++ 'cn': 'Test Add User', ++ 'sn': 'User', ++ 'uidNumber': '1000', ++ 'gidNumber': '1000', ++ 'homeDirectory': '/home/test_add', ++ 'userPassword': TEST_PASSWORD ++ }) ++ ++ found_masked, found_actual, found_hashed = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD) ++ ++ assert found_masked, f"Masked password not found in {log_format} ADD operation" ++ assert not found_actual, f"Actual password found in {log_format} ADD log (should be masked)" ++ assert not found_hashed, f"Hashed password found in {log_format} ADD log (should be masked)" ++ ++ finally: ++ if user is not None: ++ try: ++ user.delete() ++ except: ++ pass ++ ++ ++@pytest.mark.parametrize("log_format,display_attrs", [ ++ ("default", None), ++ ("default", "*"), ++ ("default", "userPassword"), ++ ("json", None), ++ ("json", "*"), ++ ("json", "userPassword") ++]) ++def test_password_masking_modify_operation(topo, log_format, display_attrs): ++ """Test password masking in MODIFY operations ++ ++ :id: e6963aa9-7609-419c-aae2-1d517aa434bd ++ :parametrized: yes ++ :setup: Standalone Instance ++ :steps: ++ 1. Configure audit logging format ++ 2. Add user without password ++ 3. Add password via MODIFY operation ++ 4. Check that password is masked in audit log ++ 5. Modify password to new value ++ 6. Check that new password is also masked ++ 7. Verify actual passwords do not appear in log ++ :expectedresults: ++ 1. Success ++ 2. Success ++ 3. Success ++ 4. Password should be masked with asterisks ++ 5. Success ++ 6. New password should be masked with asterisks ++ 7. No actual password values should be found in log ++ """ ++ inst = topo.ms['supplier1'] ++ setup_audit_logging(inst, log_format, display_attrs) ++ ++ users = UserAccounts(inst, DEFAULT_SUFFIX) ++ user = None ++ ++ try: ++ user = users.create(properties={ ++ 'uid': 'test_modify_pwd_mask', ++ 'cn': 'Test Modify User', ++ 'sn': 'User', ++ 'uidNumber': '2000', ++ 'gidNumber': '2000', ++ 'homeDirectory': '/home/test_modify' ++ }) ++ ++ user.replace('userPassword', TEST_PASSWORD) ++ ++ found_masked, found_actual, found_hashed = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD) ++ assert found_masked, f"Masked password not found in {log_format} MODIFY operation (first password)" ++ assert not found_actual, f"Actual password found in {log_format} MODIFY log (should be masked)" ++ assert not found_hashed, f"Hashed password found in {log_format} MODIFY log (should be masked)" ++ ++ user.replace('userPassword', TEST_PASSWORD_2) ++ ++ found_masked_2, found_actual_2, found_hashed_2 = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD_2) ++ assert found_masked_2, f"Masked password not found in {log_format} MODIFY operation (second password)" ++ assert not found_actual_2, f"Second actual password found in {log_format} MODIFY log (should be masked)" ++ assert not found_hashed_2, f"Second hashed password found in {log_format} MODIFY log (should be masked)" ++ ++ finally: ++ if user is not None: ++ try: ++ user.delete() ++ except: ++ pass ++ ++ ++@pytest.mark.parametrize("log_format,display_attrs", [ ++ ("default", None), ++ ("default", "*"), ++ ("default", "nsslapd-rootpw"), ++ ("json", None), ++ ("json", "*"), ++ ("json", "nsslapd-rootpw") ++]) ++def test_password_masking_rootpw_modify_operation(topo, log_format, display_attrs): ++ """Test password masking for nsslapd-rootpw MODIFY operations ++ ++ :id: ec8c9fd4-56ba-4663-ab65-58efb3b445e4 ++ :parametrized: yes ++ :setup: Standalone Instance ++ :steps: ++ 1. Configure audit logging format ++ 2. Modify nsslapd-rootpw in configuration ++ 3. Check that root password is masked in audit log ++ 4. Modify root password to new value ++ 5. Check that new root password is also masked ++ 6. Verify actual root passwords do not appear in log ++ :expectedresults: ++ 1. Success ++ 2. Success ++ 3. Root password should be masked with asterisks ++ 4. Success ++ 5. New root password should be masked with asterisks ++ 6. No actual root password values should be found in log ++ """ ++ inst = topo.ms['supplier1'] ++ setup_audit_logging(inst, log_format, display_attrs) ++ dm = DirectoryManager(inst) ++ ++ try: ++ dm.change_password(TEST_PASSWORD) ++ dm.rebind(TEST_PASSWORD) ++ ++ found_masked, found_actual, found_hashed = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD) ++ assert found_masked, f"Masked root password not found in {log_format} MODIFY operation (first root password)" ++ assert not found_actual, f"Actual root password found in {log_format} MODIFY log (should be masked)" ++ assert not found_hashed, f"Hashed root password found in {log_format} MODIFY log (should be masked)" ++ ++ dm.change_password(TEST_PASSWORD_2) ++ dm.rebind(TEST_PASSWORD_2) ++ ++ found_masked_2, found_actual_2, found_hashed_2 = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD_2) ++ assert found_masked_2, f"Masked root password not found in {log_format} MODIFY operation (second root password)" ++ assert not found_actual_2, f"Second actual root password found in {log_format} MODIFY log (should be masked)" ++ assert not found_hashed_2, f"Second hashed root password found in {log_format} MODIFY log (should be masked)" ++ ++ finally: ++ dm.change_password(PW_DM) ++ dm.rebind(PW_DM) ++ ++ ++@pytest.mark.parametrize("log_format,display_attrs", [ ++ ("default", None), ++ ("default", "*"), ++ ("default", "nsmultiplexorcredentials"), ++ ("json", None), ++ ("json", "*"), ++ ("json", "nsmultiplexorcredentials") ++]) ++def test_password_masking_multiplexor_credentials(topo, log_format, display_attrs): ++ """Test password masking for nsmultiplexorcredentials in chaining/multiplexor configurations ++ ++ :id: 161a9498-b248-4926-90be-a696a36ed36e ++ :parametrized: yes ++ :setup: Standalone Instance ++ :steps: ++ 1. Configure audit logging format ++ 2. Create a chaining backend configuration entry with nsmultiplexorcredentials ++ 3. Check that multiplexor credentials are masked in audit log ++ 4. Modify the credentials ++ 5. Check that updated credentials are also masked ++ 6. Verify actual credentials do not appear in log ++ :expectedresults: ++ 1. Success ++ 2. Success ++ 3. Multiplexor credentials should be masked with asterisks ++ 4. Success ++ 5. Updated credentials should be masked with asterisks ++ 6. No actual credential values should be found in log ++ """ ++ inst = topo.ms['supplier1'] ++ setup_audit_logging(inst, log_format, display_attrs) ++ ++ # Enable chaining plugin and create chaining link ++ chain_plugin = ChainingBackendPlugin(inst) ++ chain_plugin.enable() ++ ++ chains = ChainingLinks(inst) ++ chain = None ++ ++ try: ++ # Create chaining link with multiplexor credentials ++ chain = chains.create(properties={ ++ 'cn': 'testchain', ++ 'nsfarmserverurl': 'ldap://localhost:389/', ++ 'nsslapd-suffix': 'dc=example,dc=com', ++ 'nsmultiplexorbinddn': 'cn=manager', ++ 'nsmultiplexorcredentials': TEST_PASSWORD, ++ 'nsCheckLocalACI': 'on', ++ 'nsConnectionLife': '30', ++ }) ++ ++ found_masked, found_actual, found_hashed = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD) ++ assert found_masked, f"Masked multiplexor credentials not found in {log_format} ADD operation" ++ assert not found_actual, f"Actual multiplexor credentials found in {log_format} ADD log (should be masked)" ++ assert not found_hashed, f"Hashed multiplexor credentials found in {log_format} ADD log (should be masked)" ++ ++ # Modify the credentials ++ chain.replace('nsmultiplexorcredentials', TEST_PASSWORD_2) ++ ++ found_masked_2, found_actual_2, found_hashed_2 = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD_2) ++ assert found_masked_2, f"Masked multiplexor credentials not found in {log_format} MODIFY operation" ++ assert not found_actual_2, f"Actual multiplexor credentials found in {log_format} MODIFY log (should be masked)" ++ assert not found_hashed_2, f"Hashed multiplexor credentials found in {log_format} MODIFY log (should be masked)" ++ ++ finally: ++ chain_plugin.disable() ++ if chain is not None: ++ inst.delete_branch_s(chain.dn, ldap.SCOPE_ONELEVEL) ++ chain.delete() ++ ++ ++@pytest.mark.parametrize("log_format,display_attrs", [ ++ ("default", None), ++ ("default", "*"), ++ ("default", "nsDS5ReplicaCredentials"), ++ ("json", None), ++ ("json", "*"), ++ ("json", "nsDS5ReplicaCredentials") ++]) ++def test_password_masking_replica_credentials(topo, log_format, display_attrs): ++ """Test password masking for nsDS5ReplicaCredentials in replication agreements ++ ++ :id: 7bf9e612-1b7c-49af-9fc0-de4c7df84b2a ++ :parametrized: yes ++ :setup: Standalone Instance ++ :steps: ++ 1. Configure audit logging format ++ 2. Create a replication agreement entry with nsDS5ReplicaCredentials ++ 3. Check that replica credentials are masked in audit log ++ 4. Modify the credentials ++ 5. Check that updated credentials are also masked ++ 6. Verify actual credentials do not appear in log ++ :expectedresults: ++ 1. Success ++ 2. Success ++ 3. Replica credentials should be masked with asterisks ++ 4. Success ++ 5. Updated credentials should be masked with asterisks ++ 6. No actual credential values should be found in log ++ """ ++ inst = topo.ms['supplier2'] ++ setup_audit_logging(inst, log_format, display_attrs) ++ agmt = None ++ ++ try: ++ replicas = Replicas(inst) ++ replica = replicas.get(DEFAULT_SUFFIX) ++ agmts = replica.get_agreements() ++ agmt = agmts.create(properties={ ++ 'cn': 'testagmt', ++ 'nsDS5ReplicaHost': 'localhost', ++ 'nsDS5ReplicaPort': '389', ++ 'nsDS5ReplicaBindDN': 'cn=replication manager,cn=config', ++ 'nsDS5ReplicaCredentials': TEST_PASSWORD, ++ 'nsDS5ReplicaRoot': DEFAULT_SUFFIX ++ }) ++ ++ found_masked, found_actual, found_hashed = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD) ++ assert found_masked, f"Masked replica credentials not found in {log_format} ADD operation" ++ assert not found_actual, f"Actual replica credentials found in {log_format} ADD log (should be masked)" ++ assert not found_hashed, f"Hashed replica credentials found in {log_format} ADD log (should be masked)" ++ ++ # Modify the credentials ++ agmt.replace('nsDS5ReplicaCredentials', TEST_PASSWORD_2) ++ ++ found_masked_2, found_actual_2, found_hashed_2 = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD_2) ++ assert found_masked_2, f"Masked replica credentials not found in {log_format} MODIFY operation" ++ assert not found_actual_2, f"Actual replica credentials found in {log_format} MODIFY log (should be masked)" ++ assert not found_hashed_2, f"Hashed replica credentials found in {log_format} MODIFY log (should be masked)" ++ ++ finally: ++ if agmt is not None: ++ agmt.delete() ++ ++ ++@pytest.mark.parametrize("log_format,display_attrs", [ ++ ("default", None), ++ ("default", "*"), ++ ("default", "nsDS5ReplicaBootstrapCredentials"), ++ ("json", None), ++ ("json", "*"), ++ ("json", "nsDS5ReplicaBootstrapCredentials") ++]) ++def test_password_masking_bootstrap_credentials(topo, log_format, display_attrs): ++ """Test password masking for nsDS5ReplicaCredentials and nsDS5ReplicaBootstrapCredentials in replication agreements ++ ++ :id: 248bd418-ffa4-4733-963d-2314c60b7c5b ++ :parametrized: yes ++ :setup: Standalone Instance ++ :steps: ++ 1. Configure audit logging format ++ 2. Create a replication agreement entry with both nsDS5ReplicaCredentials and nsDS5ReplicaBootstrapCredentials ++ 3. Check that both credentials are masked in audit log ++ 4. Modify both credentials ++ 5. Check that both updated credentials are also masked ++ 6. Verify actual credentials do not appear in log ++ :expectedresults: ++ 1. Success ++ 2. Success ++ 3. Both credentials should be masked with asterisks ++ 4. Success ++ 5. Both updated credentials should be masked with asterisks ++ 6. No actual credential values should be found in log ++ """ ++ inst = topo.ms['supplier2'] ++ setup_audit_logging(inst, log_format, display_attrs) ++ agmt = None ++ ++ try: ++ replicas = Replicas(inst) ++ replica = replicas.get(DEFAULT_SUFFIX) ++ agmts = replica.get_agreements() ++ agmt = agmts.create(properties={ ++ 'cn': 'testbootstrapagmt', ++ 'nsDS5ReplicaHost': 'localhost', ++ 'nsDS5ReplicaPort': '389', ++ 'nsDS5ReplicaBindDN': 'cn=replication manager,cn=config', ++ 'nsDS5ReplicaCredentials': TEST_PASSWORD, ++ 'nsDS5replicabootstrapbinddn': 'cn=bootstrap manager,cn=config', ++ 'nsDS5ReplicaBootstrapCredentials': TEST_PASSWORD_2, ++ 'nsDS5ReplicaRoot': DEFAULT_SUFFIX ++ }) ++ ++ found_masked_bootstrap, found_actual_bootstrap, found_hashed_bootstrap = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD_2) ++ assert found_masked_bootstrap, f"Masked bootstrap credentials not found in {log_format} ADD operation" ++ assert not found_actual_bootstrap, f"Actual bootstrap credentials found in {log_format} ADD log (should be masked)" ++ assert not found_hashed_bootstrap, f"Hashed bootstrap credentials found in {log_format} ADD log (should be masked)" ++ ++ agmt.replace('nsDS5ReplicaBootstrapCredentials', TEST_PASSWORD_3) ++ ++ found_masked_bootstrap_2, found_actual_bootstrap_2, found_hashed_bootstrap_2 = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD_3) ++ assert found_masked_bootstrap_2, f"Masked bootstrap credentials not found in {log_format} MODIFY operation" ++ assert not found_actual_bootstrap_2, f"Actual bootstrap credentials found in {log_format} MODIFY log (should be masked)" ++ assert not found_hashed_bootstrap_2, f"Hashed bootstrap credentials found in {log_format} MODIFY log (should be masked)" ++ ++ finally: ++ if agmt is not None: ++ agmt.delete() ++ ++ ++ ++if __name__ == '__main__': ++ CURRENT_FILE = os.path.realpath(__file__) ++ pytest.main(["-s", CURRENT_FILE]) +\ No newline at end of file +diff --git a/ldap/servers/slapd/auditlog.c b/ldap/servers/slapd/auditlog.c +index 1121aef35..7b591e072 100644 +--- a/ldap/servers/slapd/auditlog.c ++++ b/ldap/servers/slapd/auditlog.c +@@ -39,6 +39,89 @@ static void write_audit_file(Slapi_PBlock *pb, Slapi_Entry *entry, int logtype, + + static const char *modrdn_changes[4]; + ++/* Helper function to check if an attribute is a password that needs masking */ ++static int ++is_password_attribute(const char *attr_name) ++{ ++ return (strcasecmp(attr_name, SLAPI_USERPWD_ATTR) == 0 || ++ strcasecmp(attr_name, CONFIG_ROOTPW_ATTRIBUTE) == 0 || ++ strcasecmp(attr_name, SLAPI_MB_CREDENTIALS) == 0 || ++ strcasecmp(attr_name, SLAPI_REP_CREDENTIALS) == 0 || ++ strcasecmp(attr_name, SLAPI_REP_BOOTSTRAP_CREDENTIALS) == 0); ++} ++ ++/* Helper function to create a masked string representation of an entry */ ++static char * ++create_masked_entry_string(Slapi_Entry *original_entry, int *len) ++{ ++ Slapi_Attr *attr = NULL; ++ char *entry_str = NULL; ++ char *current_pos = NULL; ++ char *line_start = NULL; ++ char *next_line = NULL; ++ char *colon_pos = NULL; ++ int has_password_attrs = 0; ++ ++ if (original_entry == NULL) { ++ return NULL; ++ } ++ ++ /* Single pass through attributes to check for password attributes */ ++ for (slapi_entry_first_attr(original_entry, &attr); attr != NULL; ++ slapi_entry_next_attr(original_entry, attr, &attr)) { ++ ++ char *attr_name = NULL; ++ slapi_attr_get_type(attr, &attr_name); ++ ++ if (is_password_attribute(attr_name)) { ++ has_password_attrs = 1; ++ break; ++ } ++ } ++ ++ /* If no password attributes, return original string - no masking needed */ ++ entry_str = slapi_entry2str(original_entry, len); ++ if (!has_password_attrs) { ++ return entry_str; ++ } ++ ++ /* Process the string in-place, replacing password values */ ++ current_pos = entry_str; ++ while ((line_start = current_pos) != NULL && *line_start != '\0') { ++ /* Find the end of current line */ ++ next_line = strchr(line_start, '\n'); ++ if (next_line != NULL) { ++ *next_line = '\0'; /* Temporarily terminate line */ ++ current_pos = next_line + 1; ++ } else { ++ current_pos = NULL; /* Last line */ ++ } ++ ++ /* Find the colon that separates attribute name from value */ ++ colon_pos = strchr(line_start, ':'); ++ if (colon_pos != NULL) { ++ char saved_colon = *colon_pos; ++ *colon_pos = '\0'; /* Temporarily null-terminate attribute name */ ++ ++ /* Check if this is a password attribute that needs masking */ ++ if (is_password_attribute(line_start)) { ++ strcpy(colon_pos + 1, " **********************"); ++ } ++ ++ *colon_pos = saved_colon; /* Restore colon */ ++ } ++ ++ /* Restore newline if it was there */ ++ if (next_line != NULL) { ++ *next_line = '\n'; ++ } ++ } ++ ++ /* Update length since we may have shortened the string */ ++ *len = strlen(entry_str); ++ return entry_str; /* Return the modified original string */ ++} ++ + void + write_audit_log_entry(Slapi_PBlock *pb) + { +@@ -282,10 +365,31 @@ add_entry_attrs_ext(Slapi_Entry *entry, lenstr *l, PRBool use_json, json_object + { + slapi_entry_attr_find(entry, req_attr, &entry_attr); + if (entry_attr) { +- if (use_json) { +- log_entry_attr_json(entry_attr, req_attr, id_list); ++ if (strcmp(req_attr, PSEUDO_ATTR_UNHASHEDUSERPASSWORD) == 0) { ++ /* Do not write the unhashed clear-text password */ ++ continue; ++ } ++ ++ /* Check if this is a password attribute that needs masking */ ++ if (is_password_attribute(req_attr)) { ++ /* userpassword/rootdn password - mask the value */ ++ if (use_json) { ++ json_object *secret_obj = json_object_new_object(); ++ json_object_object_add(secret_obj, req_attr, ++ json_object_new_string("**********************")); ++ json_object_array_add(id_list, secret_obj); ++ } else { ++ addlenstr(l, "#"); ++ addlenstr(l, req_attr); ++ addlenstr(l, ": **********************\n"); ++ } + } else { +- log_entry_attr(entry_attr, req_attr, l); ++ /* Regular attribute - log normally */ ++ if (use_json) { ++ log_entry_attr_json(entry_attr, req_attr, id_list); ++ } else { ++ log_entry_attr(entry_attr, req_attr, l); ++ } + } + } + } +@@ -300,9 +404,7 @@ add_entry_attrs_ext(Slapi_Entry *entry, lenstr *l, PRBool use_json, json_object + continue; + } + +- if (strcasecmp(attr, SLAPI_USERPWD_ATTR) == 0 || +- strcasecmp(attr, CONFIG_ROOTPW_ATTRIBUTE) == 0) +- { ++ if (is_password_attribute(attr)) { + /* userpassword/rootdn password - mask the value */ + if (use_json) { + json_object *secret_obj = json_object_new_object(); +@@ -312,7 +414,7 @@ add_entry_attrs_ext(Slapi_Entry *entry, lenstr *l, PRBool use_json, json_object + } else { + addlenstr(l, "#"); + addlenstr(l, attr); +- addlenstr(l, ": ****************************\n"); ++ addlenstr(l, ": **********************\n"); + } + continue; + } +@@ -481,6 +583,9 @@ write_audit_file_json(Slapi_PBlock *pb, Slapi_Entry *entry, int logtype, + } + } + ++ /* Check if this is a password attribute that needs masking */ ++ int is_password_attr = is_password_attribute(mods[j]->mod_type); ++ + mod = json_object_new_object(); + switch (operationtype) { + case LDAP_MOD_ADD: +@@ -505,7 +610,12 @@ write_audit_file_json(Slapi_PBlock *pb, Slapi_Entry *entry, int logtype, + json_object *val_list = NULL; + val_list = json_object_new_array(); + for (size_t i = 0; mods[j]->mod_bvalues != NULL && mods[j]->mod_bvalues[i] != NULL; i++) { +- json_object_array_add(val_list, json_object_new_string(mods[j]->mod_bvalues[i]->bv_val)); ++ if (is_password_attr) { ++ /* Mask password values */ ++ json_object_array_add(val_list, json_object_new_string("**********************")); ++ } else { ++ json_object_array_add(val_list, json_object_new_string(mods[j]->mod_bvalues[i]->bv_val)); ++ } + } + json_object_object_add(mod, "values", val_list); + } +@@ -517,8 +627,11 @@ write_audit_file_json(Slapi_PBlock *pb, Slapi_Entry *entry, int logtype, + } + case SLAPI_OPERATION_ADD: { + int len; ++ + e = change; +- tmp = slapi_entry2str(e, &len); ++ ++ /* Create a masked string representation for password attributes */ ++ tmp = create_masked_entry_string(e, &len); + tmpsave = tmp; + while ((tmp = strchr(tmp, '\n')) != NULL) { + tmp++; +@@ -665,6 +778,10 @@ write_audit_file( + break; + } + } ++ ++ /* Check if this is a password attribute that needs masking */ ++ int is_password_attr = is_password_attribute(mods[j]->mod_type); ++ + switch (operationtype) { + case LDAP_MOD_ADD: + addlenstr(l, "add: "); +@@ -689,18 +806,27 @@ write_audit_file( + break; + } + if (operationtype != LDAP_MOD_IGNORE) { +- for (i = 0; mods[j]->mod_bvalues != NULL && mods[j]->mod_bvalues[i] != NULL; i++) { +- char *buf, *bufp; +- len = strlen(mods[j]->mod_type); +- len = LDIF_SIZE_NEEDED(len, mods[j]->mod_bvalues[i]->bv_len) + 1; +- buf = slapi_ch_malloc(len); +- bufp = buf; +- slapi_ldif_put_type_and_value_with_options(&bufp, mods[j]->mod_type, +- mods[j]->mod_bvalues[i]->bv_val, +- mods[j]->mod_bvalues[i]->bv_len, 0); +- *bufp = '\0'; +- addlenstr(l, buf); +- slapi_ch_free((void **)&buf); ++ if (is_password_attr) { ++ /* Add masked password */ ++ for (i = 0; mods[j]->mod_bvalues != NULL && mods[j]->mod_bvalues[i] != NULL; i++) { ++ addlenstr(l, mods[j]->mod_type); ++ addlenstr(l, ": **********************\n"); ++ } ++ } else { ++ /* Add actual values for non-password attributes */ ++ for (i = 0; mods[j]->mod_bvalues != NULL && mods[j]->mod_bvalues[i] != NULL; i++) { ++ char *buf, *bufp; ++ len = strlen(mods[j]->mod_type); ++ len = LDIF_SIZE_NEEDED(len, mods[j]->mod_bvalues[i]->bv_len) + 1; ++ buf = slapi_ch_malloc(len); ++ bufp = buf; ++ slapi_ldif_put_type_and_value_with_options(&bufp, mods[j]->mod_type, ++ mods[j]->mod_bvalues[i]->bv_val, ++ mods[j]->mod_bvalues[i]->bv_len, 0); ++ *bufp = '\0'; ++ addlenstr(l, buf); ++ slapi_ch_free((void **)&buf); ++ } + } + } + addlenstr(l, "-\n"); +@@ -711,7 +837,7 @@ write_audit_file( + e = change; + addlenstr(l, attr_changetype); + addlenstr(l, ": add\n"); +- tmp = slapi_entry2str(e, &len); ++ tmp = create_masked_entry_string(e, &len); + tmpsave = tmp; + while ((tmp = strchr(tmp, '\n')) != NULL) { + tmp++; +diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h +index e9abf8b75..02f22fd2d 100644 +--- a/ldap/servers/slapd/slapi-private.h ++++ b/ldap/servers/slapd/slapi-private.h +@@ -848,6 +848,7 @@ void task_cleanup(void); + /* for reversible encyrption */ + #define SLAPI_MB_CREDENTIALS "nsmultiplexorcredentials" + #define SLAPI_REP_CREDENTIALS "nsds5ReplicaCredentials" ++#define SLAPI_REP_BOOTSTRAP_CREDENTIALS "nsds5ReplicaBootstrapCredentials" + int pw_rever_encode(Slapi_Value **vals, char *attr_name); + int pw_rever_decode(char *cipher, char **plain, const char *attr_name); + +diff --git a/src/lib389/lib389/chaining.py b/src/lib389/lib389/chaining.py +index 533b83ebf..33ae78c8b 100644 +--- a/src/lib389/lib389/chaining.py ++++ b/src/lib389/lib389/chaining.py +@@ -134,7 +134,7 @@ class ChainingLink(DSLdapObject): + """ + + # Create chaining entry +- super(ChainingLink, self).create(rdn, properties, basedn) ++ link = super(ChainingLink, self).create(rdn, properties, basedn) + + # Create mapping tree entry + dn_comps = ldap.explode_dn(properties['nsslapd-suffix'][0]) +@@ -149,6 +149,7 @@ class ChainingLink(DSLdapObject): + self._mts.ensure_state(properties=mt_properties) + except ldap.ALREADY_EXISTS: + pass ++ return link + + + class ChainingLinks(DSLdapObjects): +-- +2.49.0 + diff --git a/0021-Issue-6778-Memory-leak-in-roles_cache_create_object_.patch b/0021-Issue-6778-Memory-leak-in-roles_cache_create_object_.patch new file mode 100644 index 0000000..dab3729 --- /dev/null +++ b/0021-Issue-6778-Memory-leak-in-roles_cache_create_object_.patch @@ -0,0 +1,262 @@ +From 572fe6c91fda1c2cfd3afee894c922edccf9c1f1 Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +Date: Wed, 16 Jul 2025 11:22:30 +0200 +Subject: [PATCH] Issue 6778 - Memory leak in + roles_cache_create_object_from_entry part 2 + +Bug Description: +Everytime a role with scope DN is processed, we leak rolescopeDN. + +Fix Description: +* Initialize all pointer variables to NULL +* Add additional NULL checks +* Free rolescopeDN +* Move test_rewriter_with_invalid_filter before the DB contains 90k entries +* Use task.wait() for import task completion instead of parsing logs, +increase the timeout + +Fixes: https://github.com/389ds/389-ds-base/issues/6778 + +Reviewed by: @progier389 (Thanks!) +--- + dirsrvtests/tests/suites/roles/basic_test.py | 164 +++++++++---------- + ldap/servers/plugins/roles/roles_cache.c | 10 +- + 2 files changed, 82 insertions(+), 92 deletions(-) + +diff --git a/dirsrvtests/tests/suites/roles/basic_test.py b/dirsrvtests/tests/suites/roles/basic_test.py +index d92d6f0c3..ec208bae9 100644 +--- a/dirsrvtests/tests/suites/roles/basic_test.py ++++ b/dirsrvtests/tests/suites/roles/basic_test.py +@@ -510,6 +510,76 @@ def test_vattr_on_managed_role(topo, request): + + request.addfinalizer(fin) + ++def test_rewriter_with_invalid_filter(topo, request): ++ """Test that server does not crash when having ++ invalid filter in filtered role ++ ++ :id: 5013b0b2-0af6-11f0-8684-482ae39447e5 ++ :setup: standalone server ++ :steps: ++ 1. Setup filtered role with good filter ++ 2. Setup nsrole rewriter ++ 3. Restart the server ++ 4. Search for entries ++ 5. Setup filtered role with bad filter ++ 6. Search for entries ++ :expectedresults: ++ 1. Operation should succeed ++ 2. Operation should succeed ++ 3. Operation should succeed ++ 4. Operation should succeed ++ 5. Operation should succeed ++ 6. Operation should succeed ++ """ ++ inst = topo.standalone ++ entries = [] ++ ++ def fin(): ++ inst.start() ++ for entry in entries: ++ entry.delete() ++ request.addfinalizer(fin) ++ ++ # Setup filtered role ++ roles = FilteredRoles(inst, f'ou=people,{DEFAULT_SUFFIX}') ++ filter_ko = '(&((objectClass=top)(objectClass=nsPerson))' ++ filter_ok = '(&(objectClass=top)(objectClass=nsPerson))' ++ role_properties = { ++ 'cn': 'TestFilteredRole', ++ 'nsRoleFilter': filter_ok, ++ 'description': 'Test good filter', ++ } ++ role = roles.create(properties=role_properties) ++ entries.append(role) ++ ++ # Setup nsrole rewriter ++ rewriters = Rewriters(inst) ++ rewriter_properties = { ++ "cn": "nsrole", ++ "nsslapd-libpath": 'libroles-plugin', ++ "nsslapd-filterrewriter": 'role_nsRole_filter_rewriter', ++ } ++ rewriter = rewriters.ensure_state(properties=rewriter_properties) ++ entries.append(rewriter) ++ ++ # Restart thge instance ++ inst.restart() ++ ++ # Search for entries ++ entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, "(nsrole=%s)" % role.dn) ++ ++ # Set bad filter ++ role_properties = { ++ 'cn': 'TestFilteredRole', ++ 'nsRoleFilter': filter_ko, ++ 'description': 'Test bad filter', ++ } ++ role.ensure_state(properties=role_properties) ++ ++ # Search for entries ++ entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, "(nsrole=%s)" % role.dn) ++ ++ + def test_managed_and_filtered_role_rewrite(topo, request): + """Test that filter components containing 'nsrole=xxx' + are reworked if xxx is either a filtered role or a managed +@@ -581,17 +651,11 @@ def test_managed_and_filtered_role_rewrite(topo, request): + PARENT="ou=people,%s" % DEFAULT_SUFFIX + dbgen_users(topo.standalone, 90000, import_ldif, DEFAULT_SUFFIX, entry_name=RDN, generic=True, parent=PARENT) + +- # online import ++ # Online import + import_task = ImportTask(topo.standalone) + import_task.import_suffix_from_ldif(ldiffile=import_ldif, suffix=DEFAULT_SUFFIX) +- # Check for up to 200sec that the completion +- for i in range(1, 20): +- if len(topo.standalone.ds_error_log.match('.*import userRoot: Import complete. Processed 9000.*')) > 0: +- break +- time.sleep(10) +- import_complete = topo.standalone.ds_error_log.match('.*import userRoot: Import complete. Processed 9000.*') +- assert (len(import_complete) == 1) +- ++ import_task.wait(timeout=400) ++ assert import_task.get_exit_code() == 0 + # Restart server + topo.standalone.restart() + +@@ -715,17 +779,11 @@ def test_not_such_entry_role_rewrite(topo, request): + PARENT="ou=people,%s" % DEFAULT_SUFFIX + dbgen_users(topo.standalone, 91000, import_ldif, DEFAULT_SUFFIX, entry_name=RDN, generic=True, parent=PARENT) + +- # online import ++ # Online import + import_task = ImportTask(topo.standalone) + import_task.import_suffix_from_ldif(ldiffile=import_ldif, suffix=DEFAULT_SUFFIX) +- # Check for up to 200sec that the completion +- for i in range(1, 20): +- if len(topo.standalone.ds_error_log.match('.*import userRoot: Import complete. Processed 9100.*')) > 0: +- break +- time.sleep(10) +- import_complete = topo.standalone.ds_error_log.match('.*import userRoot: Import complete. Processed 9100.*') +- assert (len(import_complete) == 1) +- ++ import_task.wait(timeout=400) ++ assert import_task.get_exit_code() == 0 + # Restart server + topo.standalone.restart() + +@@ -769,76 +827,6 @@ def test_not_such_entry_role_rewrite(topo, request): + request.addfinalizer(fin) + + +-def test_rewriter_with_invalid_filter(topo, request): +- """Test that server does not crash when having +- invalid filter in filtered role +- +- :id: 5013b0b2-0af6-11f0-8684-482ae39447e5 +- :setup: standalone server +- :steps: +- 1. Setup filtered role with good filter +- 2. Setup nsrole rewriter +- 3. Restart the server +- 4. Search for entries +- 5. Setup filtered role with bad filter +- 6. Search for entries +- :expectedresults: +- 1. Operation should succeed +- 2. Operation should succeed +- 3. Operation should succeed +- 4. Operation should succeed +- 5. Operation should succeed +- 6. Operation should succeed +- """ +- inst = topo.standalone +- entries = [] +- +- def fin(): +- inst.start() +- for entry in entries: +- entry.delete() +- request.addfinalizer(fin) +- +- # Setup filtered role +- roles = FilteredRoles(inst, f'ou=people,{DEFAULT_SUFFIX}') +- filter_ko = '(&((objectClass=top)(objectClass=nsPerson))' +- filter_ok = '(&(objectClass=top)(objectClass=nsPerson))' +- role_properties = { +- 'cn': 'TestFilteredRole', +- 'nsRoleFilter': filter_ok, +- 'description': 'Test good filter', +- } +- role = roles.create(properties=role_properties) +- entries.append(role) +- +- # Setup nsrole rewriter +- rewriters = Rewriters(inst) +- rewriter_properties = { +- "cn": "nsrole", +- "nsslapd-libpath": 'libroles-plugin', +- "nsslapd-filterrewriter": 'role_nsRole_filter_rewriter', +- } +- rewriter = rewriters.ensure_state(properties=rewriter_properties) +- entries.append(rewriter) +- +- # Restart thge instance +- inst.restart() +- +- # Search for entries +- entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, "(nsrole=%s)" % role.dn) +- +- # Set bad filter +- role_properties = { +- 'cn': 'TestFilteredRole', +- 'nsRoleFilter': filter_ko, +- 'description': 'Test bad filter', +- } +- role.ensure_state(properties=role_properties) +- +- # Search for entries +- entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, "(nsrole=%s)" % role.dn) +- +- + if __name__ == "__main__": + CURRENT_FILE = os.path.realpath(__file__) + pytest.main("-s -v %s" % CURRENT_FILE) +diff --git a/ldap/servers/plugins/roles/roles_cache.c b/ldap/servers/plugins/roles/roles_cache.c +index 3e1c5b429..05cabc3a3 100644 +--- a/ldap/servers/plugins/roles/roles_cache.c ++++ b/ldap/servers/plugins/roles/roles_cache.c +@@ -1117,16 +1117,17 @@ roles_cache_create_object_from_entry(Slapi_Entry *role_entry, role_object **resu + + rolescopeDN = slapi_entry_attr_get_charptr(role_entry, ROLE_SCOPE_DN); + if (rolescopeDN) { +- Slapi_DN *rolescopeSDN; +- Slapi_DN *top_rolescopeSDN, *top_this_roleSDN; ++ Slapi_DN *rolescopeSDN = NULL; ++ Slapi_DN *top_rolescopeSDN = NULL; ++ Slapi_DN *top_this_roleSDN = NULL; + + /* Before accepting to use this scope, first check if it belongs to the same suffix */ + rolescopeSDN = slapi_sdn_new_dn_byref(rolescopeDN); +- if ((strlen((char *)slapi_sdn_get_ndn(rolescopeSDN)) > 0) && ++ if (rolescopeSDN && (strlen((char *)slapi_sdn_get_ndn(rolescopeSDN)) > 0) && + (slapi_dn_syntax_check(NULL, (char *)slapi_sdn_get_ndn(rolescopeSDN), 1) == 0)) { + top_rolescopeSDN = roles_cache_get_top_suffix(rolescopeSDN); + top_this_roleSDN = roles_cache_get_top_suffix(this_role->dn); +- if (slapi_sdn_compare(top_rolescopeSDN, top_this_roleSDN) == 0) { ++ if (top_rolescopeSDN && top_this_roleSDN && slapi_sdn_compare(top_rolescopeSDN, top_this_roleSDN) == 0) { + /* rolescopeDN belongs to the same suffix as the role, we can use this scope */ + this_role->rolescopedn = rolescopeSDN; + } else { +@@ -1148,6 +1149,7 @@ roles_cache_create_object_from_entry(Slapi_Entry *role_entry, role_object **resu + rolescopeDN); + slapi_sdn_free(&rolescopeSDN); + } ++ slapi_ch_free_string(&rolescopeDN); + } + + /* Depending upon role type, pull out the remaining information we need */ +-- +2.49.0 + diff --git a/0022-Issue-6901-Update-changelog-trimming-logging-fix-tes.patch b/0022-Issue-6901-Update-changelog-trimming-logging-fix-tes.patch new file mode 100644 index 0000000..b1adff0 --- /dev/null +++ b/0022-Issue-6901-Update-changelog-trimming-logging-fix-tes.patch @@ -0,0 +1,64 @@ +From dbaf0ccfb54be40e2854e3979bb4460e26851b5a Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +Date: Mon, 28 Jul 2025 13:16:10 +0200 +Subject: [PATCH] Issue 6901 - Update changelog trimming logging - fix tests + +Description: +Update changelog_trimming_test for the new error message. + +Fixes: https://github.com/389ds/389-ds-base/issues/6901 + +Reviewed by: @progier389, @aadhikar (Thanks!) +--- + .../suites/replication/changelog_trimming_test.py | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/dirsrvtests/tests/suites/replication/changelog_trimming_test.py b/dirsrvtests/tests/suites/replication/changelog_trimming_test.py +index 2d70d328e..27d19e8fd 100644 +--- a/dirsrvtests/tests/suites/replication/changelog_trimming_test.py ++++ b/dirsrvtests/tests/suites/replication/changelog_trimming_test.py +@@ -110,7 +110,7 @@ def test_max_age(topo, setup_max_age): + do_mods(supplier, 10) + + time.sleep(1) # Trimming should not have occurred +- if supplier.searchErrorsLog("Trimmed") is True: ++ if supplier.searchErrorsLog("trimmed") is True: + log.fatal('Trimming event unexpectedly occurred') + assert False + +@@ -120,12 +120,12 @@ def test_max_age(topo, setup_max_age): + cl.set_trim_interval('5') + + time.sleep(3) # Trimming should not have occurred +- if supplier.searchErrorsLog("Trimmed") is True: ++ if supplier.searchErrorsLog("trimmed") is True: + log.fatal('Trimming event unexpectedly occurred') + assert False + + time.sleep(3) # Trimming should have occurred +- if supplier.searchErrorsLog("Trimmed") is False: ++ if supplier.searchErrorsLog("trimmed") is False: + log.fatal('Trimming event did not occur') + assert False + +@@ -159,7 +159,7 @@ def test_max_entries(topo, setup_max_entries): + do_mods(supplier, 10) + + time.sleep(1) # Trimming should have occurred +- if supplier.searchErrorsLog("Trimmed") is True: ++ if supplier.searchErrorsLog("trimmed") is True: + log.fatal('Trimming event unexpectedly occurred') + assert False + +@@ -169,7 +169,7 @@ def test_max_entries(topo, setup_max_entries): + cl.set_trim_interval('5') + + time.sleep(6) # Trimming should have occurred +- if supplier.searchErrorsLog("Trimmed") is False: ++ if supplier.searchErrorsLog("trimmed") is False: + log.fatal('Trimming event did not occur') + assert False + +-- +2.49.0 + diff --git a/0023-Issue-6181-RFE-Allow-system-to-manage-uid-gid-at-sta.patch b/0023-Issue-6181-RFE-Allow-system-to-manage-uid-gid-at-sta.patch new file mode 100644 index 0000000..1d9b8b5 --- /dev/null +++ b/0023-Issue-6181-RFE-Allow-system-to-manage-uid-gid-at-sta.patch @@ -0,0 +1,32 @@ +From b34cec9c719c6dcb5f3ff24b9fd9e20eb233eadf Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +Date: Mon, 28 Jul 2025 13:18:26 +0200 +Subject: [PATCH] Issue 6181 - RFE - Allow system to manage uid/gid at startup + +Description: +Expand CapabilityBoundingSet to include CAP_FOWNER + +Relates: https://github.com/389ds/389-ds-base/issues/6181 +Relates: https://github.com/389ds/389-ds-base/issues/6906 + +Reviewed by: @progier389 (Thanks!) +--- + wrappers/systemd.template.service.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/wrappers/systemd.template.service.in b/wrappers/systemd.template.service.in +index ada608c86..8d2b96c7e 100644 +--- a/wrappers/systemd.template.service.in ++++ b/wrappers/systemd.template.service.in +@@ -29,7 +29,7 @@ MemoryAccounting=yes + + # Allow non-root instances to bind to low ports. + AmbientCapabilities=CAP_NET_BIND_SERVICE +-CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETUID CAP_SETGID CAP_DAC_OVERRIDE CAP_CHOWN ++CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETUID CAP_SETGID CAP_DAC_OVERRIDE CAP_CHOWN CAP_FOWNER + + PrivateTmp=on + # https://en.opensuse.org/openSUSE:Security_Features#Systemd_hardening_effort +-- +2.49.0 + diff --git a/0024-Issue-6468-CLI-Fix-default-error-log-level.patch b/0024-Issue-6468-CLI-Fix-default-error-log-level.patch new file mode 100644 index 0000000..d79aa08 --- /dev/null +++ b/0024-Issue-6468-CLI-Fix-default-error-log-level.patch @@ -0,0 +1,31 @@ +From 403077fd337a6221e95f704b4fcd70fe09d1d7e3 Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +Date: Tue, 29 Jul 2025 08:00:00 +0200 +Subject: [PATCH] Issue 6468 - CLI - Fix default error log level + +Description: +Default error log level is 16384 + +Relates: https://github.com/389ds/389-ds-base/issues/6468 + +Reviewed by: @droideck (Thanks!) +--- + src/lib389/lib389/cli_conf/logging.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lib389/lib389/cli_conf/logging.py b/src/lib389/lib389/cli_conf/logging.py +index 124556f1f..d9ae1ab16 100644 +--- a/src/lib389/lib389/cli_conf/logging.py ++++ b/src/lib389/lib389/cli_conf/logging.py +@@ -44,7 +44,7 @@ ERROR_LEVELS = { + + "methods used for a SASL bind" + }, + "default": { +- "level": 6384, ++ "level": 16384, + "desc": "Default logging level" + }, + "filter": { +-- +2.49.0 + diff --git a/0025-Issue-6768-ns-slapd-crashes-when-a-referral-is-added.patch b/0025-Issue-6768-ns-slapd-crashes-when-a-referral-is-added.patch new file mode 100644 index 0000000..ba3b8a8 --- /dev/null +++ b/0025-Issue-6768-ns-slapd-crashes-when-a-referral-is-added.patch @@ -0,0 +1,97 @@ +From ec7c5a58c7decf94ba5011656c68597778f6059c Mon Sep 17 00:00:00 2001 +From: James Chapman +Date: Fri, 1 Aug 2025 13:27:02 +0100 +Subject: [PATCH] Issue 6768 - ns-slapd crashes when a referral is added + (#6780) + +Bug description: When a paged result search is successfully run on a referred +suffix, we retrieve the search result set from the pblock and try to release +it. In this case the search result set is NULL, which triggers a SEGV during +the release. + +Fix description: If the search result code is LDAP_REFERRAL, skip deletion of +the search result set. Added test case. + +Fixes: https://github.com/389ds/389-ds-base/issues/6768 + +Reviewed by: @tbordaz, @progier389 (Thank you) +--- + .../paged_results/paged_results_test.py | 46 +++++++++++++++++++ + ldap/servers/slapd/opshared.c | 4 +- + 2 files changed, 49 insertions(+), 1 deletion(-) + +diff --git a/dirsrvtests/tests/suites/paged_results/paged_results_test.py b/dirsrvtests/tests/suites/paged_results/paged_results_test.py +index fca48db0f..1bb94b53a 100644 +--- a/dirsrvtests/tests/suites/paged_results/paged_results_test.py ++++ b/dirsrvtests/tests/suites/paged_results/paged_results_test.py +@@ -1271,6 +1271,52 @@ def test_search_stress_abandon(create_40k_users, create_user): + paged_search(conn, create_40k_users.suffix, [req_ctrl], search_flt, searchreq_attrlist, abandon_rate=abandon_rate) + + ++def test_search_referral(topology_st): ++ """Test a paged search on a referred suffix doesnt crash the server. ++ ++ :id: c788bdbf-965b-4f12-ac24-d4d695e2cce2 ++ ++ :setup: Standalone instance ++ ++ :steps: ++ 1. Configure a default referral. ++ 2. Create a paged result search control. ++ 3. Paged result search on referral suffix (doesnt exist on the instance, triggering a referral). ++ 4. Check the server is still running. ++ 5. Remove referral. ++ ++ :expectedresults: ++ 1. Referral sucessfully set. ++ 2. Control created. ++ 3. Search returns ldap.REFERRAL (10). ++ 4. Server still running. ++ 5. Referral removed. ++ """ ++ ++ page_size = 5 ++ SEARCH_SUFFIX = "dc=referme,dc=com" ++ REFERRAL = "ldap://localhost.localdomain:389/o%3dnetscaperoot" ++ ++ log.info('Configuring referral') ++ topology_st.standalone.config.set('nsslapd-referral', REFERRAL) ++ referral = topology_st.standalone.config.get_attr_val_utf8('nsslapd-referral') ++ assert (referral == REFERRAL) ++ ++ log.info('Create paged result search control') ++ req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='') ++ ++ log.info('Perform a paged result search on referred suffix, no chase') ++ with pytest.raises(ldap.REFERRAL): ++ topology_st.standalone.search_ext_s(SEARCH_SUFFIX, ldap.SCOPE_SUBTREE, serverctrls=[req_ctrl]) ++ ++ log.info('Confirm instance is still running') ++ assert (topology_st.standalone.status()) ++ ++ log.info('Remove referral') ++ topology_st.standalone.config.remove_all('nsslapd-referral') ++ referral = topology_st.standalone.config.get_attr_val_utf8('nsslapd-referral') ++ assert (referral == None) ++ + if __name__ == '__main__': + # Run isolated + # -s for DEBUG mode +diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c +index 545518748..a5cddfd23 100644 +--- a/ldap/servers/slapd/opshared.c ++++ b/ldap/servers/slapd/opshared.c +@@ -910,7 +910,9 @@ op_shared_search(Slapi_PBlock *pb, int send_result) + /* Free the results if not "no_such_object" */ + void *sr = NULL; + slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr); +- be->be_search_results_release(&sr); ++ if (be->be_search_results_release != NULL) { ++ be->be_search_results_release(&sr); ++ } + } + pagedresults_set_search_result(pb_conn, operation, NULL, 1, pr_idx); + rc = pagedresults_set_current_be(pb_conn, NULL, pr_idx, 1); +-- +2.49.0 + diff --git a/389-ds-base.spec b/389-ds-base.spec index bc97e8c..425ddee 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -10,7 +10,11 @@ ExcludeArch: i686 %global __provides_exclude ^libjemalloc\\.so.*$ %endif -%bcond bundle_libdb %{defined rhel} +%bcond bundle_libdb 0 +%if 0%{?rhel} == 10 +%bcond bundle_libdb 1 +%endif + %if %{with bundle_libdb} %global libdb_version 5.3 %global libdb_base_version db-%{libdb_version}.28 @@ -24,6 +28,11 @@ ExcludeArch: i686 %endif %endif +%bcond libbdb_ro 0 +%if 0%{?fedora} >= 43 +%bcond libbdb_ro 1 +%endif + # This is used in certain builds to help us know if it has extra features. %global variant base # This enables a sanitized build. @@ -399,9 +408,11 @@ BuildRequires: libtsan BuildRequires: libubsan %endif %endif +%if %{without libbdb_ro} %if %{without bundle_libdb} BuildRequires: libdb-devel %endif +%endif # The following are needed to build the snmp ldap-agent BuildRequires: net-snmp-devel @@ -437,6 +448,9 @@ BuildRequires: npm BuildRequires: nodejs %endif +# For autosetup -S git +BuildRequires: git + Requires: %{name}-libs = %{version}-%{release} Requires: python%{python3_pkgversion}-lib389 = %{version}-%{release} @@ -457,14 +471,20 @@ Requires: cyrus-sasl-md5 # This is optionally supported by us, as we use it in our tests Requires: cyrus-sasl-plain # this is needed for backldbm +%if %{with libbdb_ro} +Requires: %{name}-robdb-libs = %{version}-%{release} +%else %if %{without bundle_libdb} Requires: libdb %endif +%endif Requires: lmdb-libs # Needed by logconv.pl +%if %{without libbdb_ro} %if %{without bundle_libdb} Requires: perl-DB_File %endif +%endif Requires: perl-Archive-Tar %if 0%{?fedora} >= 33 || 0%{?rhel} >= 9 Requires: perl-debugger @@ -490,6 +510,35 @@ Source4: 389-ds-base.sysusers Source5: https://fedorapeople.org/groups/389ds/libdb-5.3.28-59.tar.bz2 %endif +Patch: 0001-Issue-6782-Improve-paged-result-locking.patch +Patch: 0002-Issue-6822-Backend-creation-cleanup-and-Database-UI-.patch +Patch: 0003-Issue-6753-Add-add_exclude_subtree-and-remove_exclud.patch +Patch: 0004-Issue-6857-uiduniq-allow-specifying-match-rules-in-t.patch +Patch: 0005-Issue-6756-CLI-UI-Properly-handle-disabled-NDN-cache.patch +Patch: 0006-Issue-6854-Refactor-for-improved-data-management-685.patch +Patch: 0007-Issue-6850-AddressSanitizer-memory-leak-in-mdb_init.patch +Patch: 0008-Issue-6848-AddressSanitizer-leak-in-do_search.patch +Patch: 0009-Issue-6865-AddressSanitizer-leak-in-agmt_update_init.patch +Patch: 0010-Issue-6868-UI-schema-attribute-table-expansion-break.patch +Patch: 0011-Issue-6859-str2filter-is-not-fully-applying-matching.patch +Patch: 0012-Issue-6872-compressed-log-rotation-creates-files-wit.patch +Patch: 0013-Issue-6888-Missing-access-JSON-logging-for-TLS-Clien.patch +Patch: 0014-Issue-6772-dsconf-Replicas-with-the-consumer-role-al.patch +Patch: 0015-Issue-6893-Log-user-that-is-updated-during-password-.patch +Patch: 0016-Issue-6901-Update-changelog-trimming-logging.patch +Patch: 0017-Issue-6430-implement-read-only-bdb-6431.patch +Patch: 0018-Issue-6663-Fix-NULL-subsystem-crash-in-JSON-error-lo.patch +Patch: 0019-Issue-6895-Crash-if-repl-keep-alive-entry-can-not-be.patch +Patch: 0020-Issue-6884-Mask-password-hashes-in-audit-logs-6885.patch +Patch: 0021-Issue-6778-Memory-leak-in-roles_cache_create_object_.patch +Patch: 0022-Issue-6901-Update-changelog-trimming-logging-fix-tes.patch +Patch: 0023-Issue-6181-RFE-Allow-system-to-manage-uid-gid-at-sta.patch +Patch: 0024-Issue-6468-CLI-Fix-default-error-log-level.patch +Patch: 0025-Issue-6768-ns-slapd-crashes-when-a-referral-is-added.patch + +# For ELN +Patch: 0001-Issue-5120-Fix-compilation-error.patch +Patch: 0001-Issue-6929-Compilation-failure-with-rust-1.89-on-Fed.patch %description 389 Directory Server is an LDAPv3 compliant server. The base package includes @@ -500,6 +549,17 @@ isn't what you want. Please contact support immediately. Please see http://seclists.org/oss-sec/2016/q1/363 for more information. %endif +%if %{with libbdb_ro} +%package robdb-libs +Summary: Read-only Berkeley Database Library +License: GPL-3.0-or-later WITH GPL-3.0-389-ds-base-exception AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR LGPL-2.1-or-later OR MIT) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-3.0 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0 AND Zlib + +%description robdb-libs +The %{name}-robdb-lib package contains a library derived from rpm +project (https://github.com/rpm-software-management/rpm) that provides +some basic functions to search and read Berkeley Database records +%endif + %package libs Summary: Core libraries for 389 Directory Server (%{variant}) @@ -611,7 +671,7 @@ cd src/lib389 %pyproject_buildrequires -g test %prep -%autosetup -p1 -n %{name}-%{version} +%autosetup -S git -p1 -n %{name}-%{version} %if %{with bundle_jemalloc} %setup -q -n %{name}-%{version} -T -D -b 3 @@ -698,6 +758,11 @@ popd autoreconf -fiv %configure \ +%if %{with libbdb_ro} + --with-libbdb-ro \ +%else + --without-libbdb-ro \ +%endif %if %{with bundle_libdb} --with-bundle-libdb=%{_builddir}/%{libdb_base_version}/BUILD/%{libdb_base_dir}/dist/dist-tls \ %endif @@ -799,6 +864,21 @@ cp -pa $libdbbuilddir/dist/dist-tls/.libs/%{libdb_bundle_name} $RPM_BUILD_ROOT%{ popd %endif +%if %{with libbdb_ro} +pushd lib/librobdb +cp -pa COPYING %{_builddir}/%{name}-%{version}/COPYING.librobdb +cp -pa COPYING.RPM %{_builddir}/%{name}-%{version}/COPYING.RPM +install -m 0755 -d %{buildroot}/%{_libdir} +install -m 0755 -d %{buildroot}/%{_docdir}/%{name}-robdb-libs +install -m 0755 -d %{buildroot}/%{_licensedir}/%{name} +install -m 0755 -d %{buildroot}/%{_licensedir}/%{name}-robdb-libs +install -m 0644 $PWD/README.md %{buildroot}/%{_docdir}/%{name}-robdb-libs/README.md +install -m 0644 $PWD/COPYING %{buildroot}/%{_licensedir}/%{name}-robdb-libs/COPYING +install -m 0644 $PWD/COPYING.RPM %{buildroot}/%{_licensedir}/%{name}-robdb-libs/COPYING.RPM +install -m 0644 $PWD/COPYING %{buildroot}/%{_licensedir}/%{name}/COPYING.librobdb +install -m 0644 $PWD/COPYING.RPM %{buildroot}/%{_licensedir}/%{name}/COPYING.RPM +popd +%endif %check # This checks the code, if it fails it prints why, then re-raises the fail to shortcircuit the rpm build. @@ -949,6 +1029,9 @@ exit 0 %exclude %{_libdir}/%{pkgname}/lib/libjemalloc_pic.a %exclude %{_libdir}/%{pkgname}/lib/pkgconfig %endif +%if %{with libbdb_ro} +%exclude %{_libdir}/%{pkgname}/librobdb.so +%endif %files devel %doc LICENSE LICENSE.GPLv3+ LICENSE.openssl README.devel @@ -1017,5 +1100,16 @@ exit 0 %doc README.md %endif +%if %{with libbdb_ro} +%files robdb-libs +%license COPYING.librobdb COPYING.RPM +%doc %{_defaultdocdir}/%{name}-robdb-libs/README.md +%{_libdir}/%{pkgname}/librobdb.so +%{_licensedir}/%{name}-robdb-libs/COPYING +%{_licensedir}/%{name}/COPYING.RPM +%{_licensedir}/%{name}/COPYING.librobdb + +%endif + %changelog %autochangelog From a4238f09daadf68bae09ea46ce9ee5e8eff83d59 Mon Sep 17 00:00:00 2001 From: Python Maint Date: Fri, 15 Aug 2025 15:24:07 +0200 Subject: [PATCH 117/125] Rebuilt for Python 3.14.0rc2 bytecode From 8a64e863edc89b38cd48dfa1ff101db5d93062a0 Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Wed, 20 Aug 2025 17:32:26 -0400 Subject: [PATCH 118/125] Fix build --with-bundle-libdb, enable for ELN While the goal is to ship no BDB backend in RHEL 11, this currently cannot be built without one. As such, building with a bundled libdb and then dropping the -bdb subpackage from ELN CRB gets us as close as possible to that state for now. https://github.com/389ds/389-ds-base/issues/6944 https://github.com/389ds/389-ds-base/pull/6945 --- ...ue-6430-Fix-build-with-bundled-libdb.patch | 33 +++++++++++++++++++ 389-ds-base.spec | 3 +- 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 0026-Issue-6430-Fix-build-with-bundled-libdb.patch diff --git a/0026-Issue-6430-Fix-build-with-bundled-libdb.patch b/0026-Issue-6430-Fix-build-with-bundled-libdb.patch new file mode 100644 index 0000000..b1c5fb8 --- /dev/null +++ b/0026-Issue-6430-Fix-build-with-bundled-libdb.patch @@ -0,0 +1,33 @@ +From 8d0320144a3996c63e50a8e3792e8c1de3dcd76b Mon Sep 17 00:00:00 2001 +From: Yaakov Selkowitz +Date: Wed, 20 Aug 2025 17:43:30 -0400 +Subject: [PATCH] Issue 6430 - Fix build with bundled libdb + +Description: +The libbdb_ro change (#6431) added a `WITH_LIBBDB_RO` automake conditional +and a `db_bdb_srcdir` autoconf substitution which must also be defined when +building --with-bundle-libdb. + +Related: https://github.com/389ds/389-ds-base/pull/6431 +--- + m4/bundle_libdb.m4 | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/m4/bundle_libdb.m4 b/m4/bundle_libdb.m4 +index 3ae3beb49..a182378f1 100644 +--- a/m4/bundle_libdb.m4 ++++ b/m4/bundle_libdb.m4 +@@ -27,7 +27,10 @@ else + AC_MSG_RESULT([libdb-${db_ver_maj}.${db_ver_min}-389ds.so]) + fi + ++db_bdb_srcdir="ldap/servers/slapd/back-ldbm/db-bdb" + ++AM_CONDITIONAL([WITH_LIBBDB_RO],[false]) ++AC_SUBST(db_bdb_srcdir) + AC_SUBST(db_inc) + AC_SUBST(db_lib) + AC_SUBST(db_libver) +-- +2.50.1 + diff --git a/389-ds-base.spec b/389-ds-base.spec index 425ddee..87d27e5 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -11,7 +11,7 @@ ExcludeArch: i686 %endif %bcond bundle_libdb 0 -%if 0%{?rhel} == 10 +%if 0%{?rhel} >= 10 %bcond bundle_libdb 1 %endif @@ -535,6 +535,7 @@ Patch: 0022-Issue-6901-Update-changelog-trimming-logging-fix-tes.patc Patch: 0023-Issue-6181-RFE-Allow-system-to-manage-uid-gid-at-sta.patch Patch: 0024-Issue-6468-CLI-Fix-default-error-log-level.patch Patch: 0025-Issue-6768-ns-slapd-crashes-when-a-referral-is-added.patch +Patch: 0026-Issue-6430-Fix-build-with-bundled-libdb.patch # For ELN Patch: 0001-Issue-5120-Fix-compilation-error.patch From 0fbd2343c96fd8db241a2a1cc81d24be3275f9c1 Mon Sep 17 00:00:00 2001 From: Python Maint Date: Fri, 19 Sep 2025 12:06:10 +0200 Subject: [PATCH 119/125] Rebuilt for Python 3.14.0rc3 bytecode From c134ea11dbe628d837af28c3a3f7d673628fe68d Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Tue, 16 Dec 2025 15:24:48 -0500 Subject: [PATCH 120/125] Issue 7147 - entrycache_eviction_test is failing (#7148) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue 1793 - RFE - Dynamic lists - UI and CLI updates Issue 7119 - Fix DNA shared config replication test (#7143) Issue 7081 - Repl Log Analysis - Implement data sampling with performance and timezone fixes (#7086) Issue 1793 - RFE - Implement dynamic lists Issue 7112 - dsctrl dblib bdb2mdb core dumps and won't allow conversion (#7144) Issue 7053 - Remove memberof_del_dn_from_groups from MemberOf plugin (#7064) Issue 7138 - test_cleanallruv_repl does not restart supplier3 (#7139) Issue 6753 - Port ticket47921 test to indirect_cos_test using DSLdapObject (#7134) Issue 7128 - memory corruption in alias entry plugin (#7131) Issue 7091 - Duplicate local password policy entries listed (#7092) Issue 7124 - BDB cursor race condition with transaction isolation (#7125) Issue 6951 - Dynamic Certificate refresh phase 1 - Search support (#7117) Issue 7132 - Keep alive entry updated too soon after an offline import (#7133) Issue 7135 - Not enough space for tests on GH runner (#7136) Issue 7121 - LeakSanitizer: various leaks during replication (#7122) Issue 7115 - LeakSanitizer: leak in `slapd_bind_local_user()` (#7116) Issue 7109 - AddressSanitizer: SEGV ldap/servers/slapd/csnset.c:302 in csnset_dup (#7114) Issue 7119 - Harden DNA plugin locking for shared server list operations (#7120) Issue 7084 - UI - schema - sorting attributes breaks expanded row Issue 6753 - Port ticket47910 test to logconv_test using DSLdapObject (#7098) Issue 6753 - Port ticket47920 test to ldap_controls_test using DSLdapObject (#7103) Issue 7007 - Improve paged result search locking Issue 7041 - Add WebUI test for group member management (#7111) Issue 3555 - UI - Fix audit issue with npm - glob (#7107) Issue 7089 - Fix dsconf certificate list (#7090) Issue 7076, 6992, 6784, 6214 - Fix CI test failures (#7077) Bump js-yaml from 4.1.0 to 4.1.1 in /src/cockpit/389-console (#7097) Issue 7069 - Fix error reporting in HAProxy trusted IP parsing (#7094) Issue 7049 - RetroCL plugin generates invalid LDIF Issue 7055 - Online initialization of consumers fails with error -23 (#7075) Issue 6753 - Remove ticket 47900 test (#7087) Issue 6753 - Port ticket 49008 test (#7080) Issue 7042 - Enable global_backend_lock when memberofallbackend is enabled (#7043) Issue 7078 - audit json logging does not encode binary values Issue 7069 - Add Subnet/CIDR Support for HAProxy Trusted IPs (#7070) Issue 7056 - DSBLE0007 doesn't generate remediation steps for missing indexes Issue 6660 - CLI, UI - Improve replication log analyzer usability (#7062) Issue 7065 - A search filter containing a non normalized DN assertion does not return matching entries (#7068) Issue 7071 - search filter (&(cn:dn:=groups)) no longer returns results Issue 7073 - Add NDN cache size configuration and enforcement tests (#7074) Issue 6753 - Removing ticket 47871 test and porting to DSLdapObject (#7045) Issue 7041 - CLI/UI - memberOf - no way to add/remove specific group filters Issue 6753 - Port ticket 48228 test (#7067) Issue 7029 - Add test case to measure ndn cache performance impact (#7030) Issue 7061 - CLI/UI - Improve error messages for dsconf localpwp list Issue 7059 - UI - unable to upload pem file Issue 7032 - The new ipahealthcheck test ipahealthcheck.ds.backends.BackendsCheck raises CRITICAL issue (#7036) Issue 7047 - MemberOf plugin logs null attribute name on fixup task completion (#7048) Issue 7044 - RFE - index sudoHost by default (#7046) Issue 6846 - Attribute uniqueness is not enforced with modrdn (#7026) Issue 6784 - Support of Entry cache pinned entries (#6785) Issue 6979 - Improve the way to detect asynchronous operations in the access logs (#6980) Issue 6753 - Port ticket 47931 test (#7038) Issue 7035 - RFE - memberOf - adding scoping for specific groups CLI/UI - Add option to delete all replication conflict entries Issue 7033 - lib389 - basic plugin status not in JSON Issue 7023 - UI - if first instance that is loaded is stopped it breaks parts of the UI Issue 6753 - Removing ticket 47714 test and porting to DSLdapObject (#6946) Issue 7027 - 389-ds-base OpenScanHub Leaks Detected (#7028) Issue 6753 - Removing ticket 47676 test and porting to DSLdapObject (#6938) Issue 6966 - On large DB, unlimited IDL scan limit reduce the SRCH performance (#6967) Issue 6660 - UI - Improve replication log analysis charts and usability (#6968) Issue 6753 - Removing ticket 47653MMR test and porting to DSLdapObject (#6926) Issue 7021 - Units for changing MDB max size are not consistent across different tools (#7022) Issue 6753 - Removing ticket 49463 test and porting to DSLdapObject (#6899) Issue 6954 - do not delete referrals on chain_on_update backend Issue 6982 - UI - MemberOf shared config does not validate DN properly (#6983) Issue 6740 - Fix FIPS mode test failures in syncrepl, mapping tree, and resource limits (#6993) Issue 7018 - BUG - prevent stack depth being hit (#7019) Issue 7014 - memberOf - ignored deferred updates with LMDB Issue 7002 - restore is failing. (#7003) Issue 6758 - Fix WebUI monitoring test failure due to FormSelect component deprecation (#7004) Issue 6753 - Removing ticket 47869 test and porting to DSLdapObject (#7001) Issue 6753 - Port ticket 49073 test (#7005) Issue 7016 - fix NULL deref in send_referrals_from_entry() (#7017) Issue 6753 - Port ticket 47815 test (#7000) Issue 7010 - Fix certdir underflow in slapd_nss_init() (#7011) Issue 7012 - improve dscrl dbverify result when backend does not exists (#7013) Issue 6753 - Removing ticket 477828 test and porting to DSLdapObject (#6989) Issue 6753 - Removing ticket 47721 test and porting to DSLdapObject (#6973) Issue 6992 - Improve handling of mismatched ldif import (#6999) Issue 6997 - Logic error in get_bdb_impl_status prevents bdb2mdb execution (#6998) Issue 6810 - Deprecate PAM PTA plugin configuration attributes in base entry - fix memleak (#6988) Issue 6971 - bundle-rust-npm.py: TypeError: argument of type 'NoneType' is not iterable (#6972) Fix overflow in certmap filter/DN buffers (#6995) Issue 6753 - Port ticket 49386 test (#6987) Issue 6753 - Removing ticket 47787 test and porting to DSLdapObject (#6976) Issue 6753 - Port ticket 49072 test (#6984) Issue 6990 - UI - Replace deprecated Select components with new TypeaheadSelect (#6996) Issue 6990 - UI - Fix typeahead Select fields losing values on Enter keypress (#6991) Issue 6887 - Enhance logconv.py to add support for JSON access logs (#6889) Issue 6985 - Some logconv CI tests fail with BDB (#6986) Issue 6891 - JSON logging - add wrapper function that checks for NULL Issue 4835 - dsconf display an incomplete help with changelog setting (#6769) Issue 6753 - Port ticket 47963 & 49184 tests (#6970) Issue 6753 - Port ticket 47829 & 47833 tests Issue 6977 - UI - Show error message when trying to use unavailable ports (#6978) Issue 6956 - More UI fixes Issue 6626 - Fix version Issue 6900 - Rename test files for proper pytest discovery (#6909) Issue 6947 - Revise time skew check in healthcheck tool and add option to exclude checks Issue 6805 - RFE - Multiple backend entry cache tuning Issue 6753 - Port and fix ticket 47823 tests Issue 6843 - Add CI tests for logconv.py (#6856) Issue 6933 - When deferred memberof update is enabled after the server crashed it should not launch memberof fixup task by default (#6935) UI - update Radio handlers and LDAP entries last modified time Issue 6810 - Deprecate PAM PTA plugin configuration attributes in base entry (#6832) Issue 6660 - UI - Fix minor typo (#6955) Issue 6753 - Port ticket 47808 test Issue 6910 - Fix latest coverity issues Issue 6753 - Removing ticket 50232 test and porting to DSLdapObject (#6861) Issue 6919 - numSubordinates/tombstoneNumSubordinates are inconsisten… (#6920) Issue 6430 - Fix build with bundled libdb Issue 6342 - buffer owerflow in the function parseVariant (#6927) Issue 6940 - dsconf monitor server fails with ldapi:// due to absent server ID (#6941) Issue 6936 - Make user/subtree policy creation idempotent (#6937) Migrate from PR_Poll to epoll and timerfd. (#6924) Issue 6928 - The parentId attribute is indexed with improper matching rule Issue 6753 - Removing ticket 49540 test and porting to DSLdapObject (#6877) Issue 6904 - Fix config_test.py::test_lmdb_config Issue 5120 - Fix compilation error Issue 6929 - Compilation failure with rust-1.89 on Fedora ELN Issue 6922 - AddressSanitizer: leaks found by acl test suite Issue 6519 - Add basic dsidm account tests Issue 6753 - Port ticket test 47573 Issue 6875 - Fix dsidm tests Issues 6913, 6886, 6250 - Adjust xfail marks (#6914) Issue 6768 - ns-slapd crashes when a referral is added (#6780) Issue 6468 - CLI - Fix default error log level Issue 6181 - RFE - Allow system to manage uid/gid at startup Issue 6901 - Update changelog trimming logging - fix tests Issue 6778 - Memory leak in roles_cache_create_object_from_entry part 2 Issue 6897 - Fix disk monitoring test failures and improve test maintainability (#6898) Issue 6884 - Mask password hashes in audit logs (#6885) Issue 6594 - Add test for numSubordinates replication consistency with tombstones (#6862) Issue 6250 - Add test for entryUSN overflow on failed add operations (#6821) Issue 6895 - Crash if repl keep alive entry can not be created Issue 6663 - Fix NULL subsystem crash in JSON error logging (#6883) Issue 6430 - implement read-only bdb (#6431) Issue 6901 - Update changelog trimming logging Issue 6880 - Fix ds_logs test suite failure Issue 6352 - Fix DeprecationWarning Issue 6800 - Rerun the check in verbose mode on failure Issue 6893 - Log user that is updated during password modify extended operation Issue 6772 - dsconf - Replicas with the "consumer" role allow for viewing and modification of their changelog. (#6773) Issue 6829 - Update parametrized docstring for tests Issue 6888 - Missing access JSON logging for TLS/Client auth Issue 6878 - Prevent repeated disconnect logs during shutdown (#6879) Issue 6872 - compressed log rotation creates files with world readable permission Issue 6859 - str2filter is not fully applying matching rules Issue 5733 - Remove outdated Dockerfiles Issue 6800 - Check for minimal supported Python version Issue 6868 - UI - schema attribute table expansion break after moving to a new page Issue 6865 - AddressSanitizer: leak in agmt_update_init_status Issue 6848 - AddressSanitizer: leak in do_search Issue 6850 - AddressSanitizer: memory leak in mdb_init Issue 6854 - Refactor for improved data management (#6855) Issue 6756 - CLI, UI - Properly handle disabled NDN cache (#6757) Issue 6857 - uiduniq: allow specifying match rules in the filter Issue 6852 - Move ds* CLI tools back to /sbin Issue 6753 - Port ticket tests 48294 & 48295 Issue 6753 - Add 'add_exclude_subtree' and 'remove_exclude_subtree' methods to Attribute uniqueness plugin Issue 6841 - Cancel Actions when PR is updated Issue 6838 - lib389/replica.py is using nonexistent datetime.UTC in Python 3.9 Issue 6822 - Backend creation cleanup and Database UI tab error handling (#6823) Issue 6782 - Improve paged result locking Issue 6829 - Update parametrized docstring for tests --- 0001-Issue-5120-Fix-compilation-error.patch | 48 - ...ue-6782-Improve-paged-result-locking.patch | 127 - ...lation-failure-with-rust-1.89-on-Fed.patch | 33 - ...nd-creation-cleanup-and-Database-UI-.patch | 488 - ...dd_exclude_subtree-and-remove_exclud.patch | 515 - ...iq-allow-specifying-match-rules-in-t.patch | 45 - ...I-Properly-handle-disabled-NDN-cache.patch | 1201 - ...tor-for-improved-data-management-685.patch | 2237 -- ...essSanitizer-memory-leak-in-mdb_init.patch | 65 - ...8-AddressSanitizer-leak-in-do_search.patch | 58 - ...ssSanitizer-leak-in-agmt_update_init.patch | 58 - ...hema-attribute-table-expansion-break.patch | 55 - ...ilter-is-not-fully-applying-matching.patch | 169 - ...essed-log-rotation-creates-files-wit.patch | 163 - ...ng-access-JSON-logging-for-TLS-Clien.patch | 590 - ...f-Replicas-with-the-consumer-role-al.patch | 67 - ...ser-that-is-updated-during-password-.patch | 360 - ...01-Update-changelog-trimming-logging.patch | 53 - ...ue-6430-implement-read-only-bdb-6431.patch | 20249 ---------------- ...ULL-subsystem-crash-in-JSON-error-lo.patch | 380 - ...-if-repl-keep-alive-entry-can-not-be.patch | 98 - ...k-password-hashes-in-audit-logs-6885.patch | 814 - ...y-leak-in-roles_cache_create_object_.patch | 262 - ...e-changelog-trimming-logging-fix-tes.patch | 64 - ...llow-system-to-manage-uid-gid-at-sta.patch | 32 - ...6468-CLI-Fix-default-error-log-level.patch | 31 - ...apd-crashes-when-a-referral-is-added.patch | 97 - ...ue-6430-Fix-build-with-bundled-libdb.patch | 33 - 389-ds-base.spec | 210 +- sources | 3 +- 30 files changed, 176 insertions(+), 28429 deletions(-) delete mode 100644 0001-Issue-5120-Fix-compilation-error.patch delete mode 100644 0001-Issue-6782-Improve-paged-result-locking.patch delete mode 100644 0001-Issue-6929-Compilation-failure-with-rust-1.89-on-Fed.patch delete mode 100644 0002-Issue-6822-Backend-creation-cleanup-and-Database-UI-.patch delete mode 100644 0003-Issue-6753-Add-add_exclude_subtree-and-remove_exclud.patch delete mode 100644 0004-Issue-6857-uiduniq-allow-specifying-match-rules-in-t.patch delete mode 100644 0005-Issue-6756-CLI-UI-Properly-handle-disabled-NDN-cache.patch delete mode 100644 0006-Issue-6854-Refactor-for-improved-data-management-685.patch delete mode 100644 0007-Issue-6850-AddressSanitizer-memory-leak-in-mdb_init.patch delete mode 100644 0008-Issue-6848-AddressSanitizer-leak-in-do_search.patch delete mode 100644 0009-Issue-6865-AddressSanitizer-leak-in-agmt_update_init.patch delete mode 100644 0010-Issue-6868-UI-schema-attribute-table-expansion-break.patch delete mode 100644 0011-Issue-6859-str2filter-is-not-fully-applying-matching.patch delete mode 100644 0012-Issue-6872-compressed-log-rotation-creates-files-wit.patch delete mode 100644 0013-Issue-6888-Missing-access-JSON-logging-for-TLS-Clien.patch delete mode 100644 0014-Issue-6772-dsconf-Replicas-with-the-consumer-role-al.patch delete mode 100644 0015-Issue-6893-Log-user-that-is-updated-during-password-.patch delete mode 100644 0016-Issue-6901-Update-changelog-trimming-logging.patch delete mode 100644 0017-Issue-6430-implement-read-only-bdb-6431.patch delete mode 100644 0018-Issue-6663-Fix-NULL-subsystem-crash-in-JSON-error-lo.patch delete mode 100644 0019-Issue-6895-Crash-if-repl-keep-alive-entry-can-not-be.patch delete mode 100644 0020-Issue-6884-Mask-password-hashes-in-audit-logs-6885.patch delete mode 100644 0021-Issue-6778-Memory-leak-in-roles_cache_create_object_.patch delete mode 100644 0022-Issue-6901-Update-changelog-trimming-logging-fix-tes.patch delete mode 100644 0023-Issue-6181-RFE-Allow-system-to-manage-uid-gid-at-sta.patch delete mode 100644 0024-Issue-6468-CLI-Fix-default-error-log-level.patch delete mode 100644 0025-Issue-6768-ns-slapd-crashes-when-a-referral-is-added.patch delete mode 100644 0026-Issue-6430-Fix-build-with-bundled-libdb.patch diff --git a/0001-Issue-5120-Fix-compilation-error.patch b/0001-Issue-5120-Fix-compilation-error.patch deleted file mode 100644 index f298e7a..0000000 --- a/0001-Issue-5120-Fix-compilation-error.patch +++ /dev/null @@ -1,48 +0,0 @@ -From a2d3ba3456f59b77443085d17b36b424437fbef1 Mon Sep 17 00:00:00 2001 -From: Viktor Ashirov -Date: Mon, 11 Aug 2025 13:22:52 +0200 -Subject: [PATCH] Issue 5120 - Fix compilation error -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Bug Description: -Compilation fails with `-Wunused-function`: - -``` -ldap/servers/slapd/main.c:290:1: warning: ‘referral_set_defaults’ defined but not used [-Wunused-function] - 290 | referral_set_defaults(void) - | ^~~~~~~~~~~~~~~~~~~~~ -make: *** [Makefile:4148: all] Error 2 -``` - -Fix Description: -Remove unused function `referral_set_defaults`. - -Fixes: https://github.com/389ds/389-ds-base/issues/5120 ---- - ldap/servers/slapd/main.c | 8 -------- - 1 file changed, 8 deletions(-) - -diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c -index 9d81d80f3..c370588e5 100644 ---- a/ldap/servers/slapd/main.c -+++ b/ldap/servers/slapd/main.c -@@ -285,14 +285,6 @@ main_setuid(char *username) - return 0; - } - --/* set good defaults for front-end config in referral mode */ --static void --referral_set_defaults(void) --{ -- char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE]; -- config_set_maxdescriptors(CONFIG_MAXDESCRIPTORS_ATTRIBUTE, "1024", errorbuf, 1); --} -- - static int - name2exemode(char *progname, char *s, int exit_if_unknown) - { --- -2.49.0 - diff --git a/0001-Issue-6782-Improve-paged-result-locking.patch b/0001-Issue-6782-Improve-paged-result-locking.patch deleted file mode 100644 index 015f1a5..0000000 --- a/0001-Issue-6782-Improve-paged-result-locking.patch +++ /dev/null @@ -1,127 +0,0 @@ -From dcc402a3dd9a8f316388dc31da42786fbc2c1a88 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Thu, 15 May 2025 10:35:27 -0400 -Subject: [PATCH] Issue 6782 - Improve paged result locking - -Description: - -When cleaning a slot, instead of mem setting everything to Zero and restoring -the mutex, manually reset all the values leaving the mutex pointer -intact. - -There is also a deadlock possibility when checking for abandoned PR search -in opshared.c, and we were checking a flag value outside of the per_conn -lock. - -Relates: https://github.com/389ds/389-ds-base/issues/6782 - -Reviewed by: progier & spichugi(Thanks!!) ---- - ldap/servers/slapd/opshared.c | 10 +++++++++- - ldap/servers/slapd/pagedresults.c | 27 +++++++++++++++++---------- - 2 files changed, 26 insertions(+), 11 deletions(-) - -diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c -index 5ea919e2d..545518748 100644 ---- a/ldap/servers/slapd/opshared.c -+++ b/ldap/servers/slapd/opshared.c -@@ -619,6 +619,14 @@ op_shared_search(Slapi_PBlock *pb, int send_result) - int32_t tlimit; - slapi_pblock_get(pb, SLAPI_SEARCH_TIMELIMIT, &tlimit); - pagedresults_set_timelimit(pb_conn, operation, (time_t)tlimit, pr_idx); -+ /* When using this mutex in conjunction with the main paged -+ * result lock, you must do so in this order: -+ * -+ * --> pagedresults_lock() -+ * --> pagedresults_mutex -+ * <-- pagedresults_mutex -+ * <-- pagedresults_unlock() -+ */ - pagedresults_mutex = pageresult_lock_get_addr(pb_conn); - } - -@@ -744,11 +752,11 @@ op_shared_search(Slapi_PBlock *pb, int send_result) - pr_search_result = pagedresults_get_search_result(pb_conn, operation, 1 /*locked*/, pr_idx); - if (pr_search_result) { - if (pagedresults_is_abandoned_or_notavailable(pb_conn, 1 /*locked*/, pr_idx)) { -+ pthread_mutex_unlock(pagedresults_mutex); - pagedresults_unlock(pb_conn, pr_idx); - /* Previous operation was abandoned and the simplepaged object is not in use. */ - send_ldap_result(pb, 0, NULL, "Simple Paged Results Search abandoned", 0, NULL); - rc = LDAP_SUCCESS; -- pthread_mutex_unlock(pagedresults_mutex); - goto free_and_return; - } else { - slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET, pr_search_result); -diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c -index 642aefb3d..c3f3aae01 100644 ---- a/ldap/servers/slapd/pagedresults.c -+++ b/ldap/servers/slapd/pagedresults.c -@@ -48,7 +48,6 @@ pageresult_lock_get_addr(Connection *conn) - static void - _pr_cleanup_one_slot(PagedResults *prp) - { -- PRLock *prmutex = NULL; - if (!prp) { - return; - } -@@ -56,13 +55,17 @@ _pr_cleanup_one_slot(PagedResults *prp) - /* sr is left; release it. */ - prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set)); - } -- /* clean up the slot */ -- if (prp->pr_mutex) { -- /* pr_mutex is reused; back it up and reset it. */ -- prmutex = prp->pr_mutex; -- } -- memset(prp, '\0', sizeof(PagedResults)); -- prp->pr_mutex = prmutex; -+ -+ /* clean up the slot except the mutex */ -+ prp->pr_current_be = NULL; -+ prp->pr_search_result_set = NULL; -+ prp->pr_search_result_count = 0; -+ prp->pr_search_result_set_size_estimate = 0; -+ prp->pr_sort_result_code = 0; -+ prp->pr_timelimit_hr.tv_sec = 0; -+ prp->pr_timelimit_hr.tv_nsec = 0; -+ prp->pr_flags = 0; -+ prp->pr_msgid = 0; - } - - /* -@@ -1007,7 +1010,8 @@ op_set_pagedresults(Operation *op) - - /* - * pagedresults_lock/unlock -- introduced to protect search results for the -- * asynchronous searches. -+ * asynchronous searches. Do not call these functions while the PR conn lock -+ * is held (e.g. pageresult_lock_get_addr(conn)) - */ - void - pagedresults_lock(Connection *conn, int index) -@@ -1045,6 +1049,8 @@ int - pagedresults_is_abandoned_or_notavailable(Connection *conn, int locked, int index) - { - PagedResults *prp; -+ int32_t result; -+ - if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) { - return 1; /* not abandoned, but do not want to proceed paged results op. */ - } -@@ -1052,10 +1058,11 @@ pagedresults_is_abandoned_or_notavailable(Connection *conn, int locked, int inde - pthread_mutex_lock(pageresult_lock_get_addr(conn)); - } - prp = conn->c_pagedresults.prl_list + index; -+ result = prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED; - if (!locked) { - pthread_mutex_unlock(pageresult_lock_get_addr(conn)); - } -- return prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED; -+ return result; - } - - int --- -2.49.0 - diff --git a/0001-Issue-6929-Compilation-failure-with-rust-1.89-on-Fed.patch b/0001-Issue-6929-Compilation-failure-with-rust-1.89-on-Fed.patch deleted file mode 100644 index 38450ca..0000000 --- a/0001-Issue-6929-Compilation-failure-with-rust-1.89-on-Fed.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 8e341b4967212454f154cd08d7ceb2e2a429e2e8 Mon Sep 17 00:00:00 2001 -From: Viktor Ashirov -Date: Mon, 11 Aug 2025 13:19:13 +0200 -Subject: [PATCH] Issue 6929 - Compilation failure with rust-1.89 on Fedora ELN - -Bug Description: -The `ValueArrayRefIter` struct has a lifetime parameter `'a`. -But in the `iter` method the return type doesn't specify the lifetime parameter. - -Fix Description: -Make the lifetime explicit. - -Fixes: https://github.com/389ds/389-ds-base/issues/6929 ---- - src/slapi_r_plugin/src/value.rs | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/slapi_r_plugin/src/value.rs b/src/slapi_r_plugin/src/value.rs -index 2fd35c808..fec74ac25 100644 ---- a/src/slapi_r_plugin/src/value.rs -+++ b/src/slapi_r_plugin/src/value.rs -@@ -61,7 +61,7 @@ impl ValueArrayRef { - ValueArrayRef { raw_slapi_val } - } - -- pub fn iter(&self) -> ValueArrayRefIter { -+ pub fn iter(&self) -> ValueArrayRefIter<'_> { - ValueArrayRefIter { - idx: 0, - va_ref: &self, --- -2.49.0 - diff --git a/0002-Issue-6822-Backend-creation-cleanup-and-Database-UI-.patch b/0002-Issue-6822-Backend-creation-cleanup-and-Database-UI-.patch deleted file mode 100644 index 92cfbe6..0000000 --- a/0002-Issue-6822-Backend-creation-cleanup-and-Database-UI-.patch +++ /dev/null @@ -1,488 +0,0 @@ -From 388d5ef9b64208db26373fc3b1b296a82ea689ba Mon Sep 17 00:00:00 2001 -From: Simon Pichugin -Date: Fri, 27 Jun 2025 18:43:39 -0700 -Subject: [PATCH] Issue 6822 - Backend creation cleanup and Database UI tab - error handling (#6823) - -Description: Add rollback functionality when mapping tree creation fails -during backend creation to prevent orphaned backends. -Improve error handling in Database, Replication and Monitoring UI tabs -to gracefully handle backend get-tree command failures. - -Fixes: https://github.com/389ds/389-ds-base/issues/6822 - -Reviewed by: @mreynolds389 (Thanks!) ---- - src/cockpit/389-console/src/database.jsx | 119 ++++++++------ - src/cockpit/389-console/src/monitor.jsx | 172 +++++++++++--------- - src/cockpit/389-console/src/replication.jsx | 55 ++++--- - src/lib389/lib389/backend.py | 18 +- - 4 files changed, 210 insertions(+), 154 deletions(-) - -diff --git a/src/cockpit/389-console/src/database.jsx b/src/cockpit/389-console/src/database.jsx -index c0c4be414..276125dfc 100644 ---- a/src/cockpit/389-console/src/database.jsx -+++ b/src/cockpit/389-console/src/database.jsx -@@ -478,6 +478,59 @@ export class Database extends React.Component { - } - - loadSuffixTree(fullReset) { -+ const treeData = [ -+ { -+ name: _("Global Database Configuration"), -+ icon: , -+ id: "dbconfig", -+ }, -+ { -+ name: _("Chaining Configuration"), -+ icon: , -+ id: "chaining-config", -+ }, -+ { -+ name: _("Backups & LDIFs"), -+ icon: , -+ id: "backups", -+ }, -+ { -+ name: _("Password Policies"), -+ id: "pwp", -+ icon: , -+ children: [ -+ { -+ name: _("Global Policy"), -+ icon: , -+ id: "pwpolicy", -+ }, -+ { -+ name: _("Local Policies"), -+ icon: , -+ id: "localpwpolicy", -+ }, -+ ], -+ defaultExpanded: true -+ }, -+ { -+ name: _("Suffixes"), -+ icon: , -+ id: "suffixes-tree", -+ children: [], -+ defaultExpanded: true, -+ action: ( -+ -+ ), -+ } -+ ]; -+ - const cmd = [ - "dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket", - "backend", "get-tree", -@@ -491,58 +544,20 @@ export class Database extends React.Component { - suffixData = JSON.parse(content); - this.processTree(suffixData); - } -- const treeData = [ -- { -- name: _("Global Database Configuration"), -- icon: , -- id: "dbconfig", -- }, -- { -- name: _("Chaining Configuration"), -- icon: , -- id: "chaining-config", -- }, -- { -- name: _("Backups & LDIFs"), -- icon: , -- id: "backups", -- }, -- { -- name: _("Password Policies"), -- id: "pwp", -- icon: , -- children: [ -- { -- name: _("Global Policy"), -- icon: , -- id: "pwpolicy", -- }, -- { -- name: _("Local Policies"), -- icon: , -- id: "localpwpolicy", -- }, -- ], -- defaultExpanded: true -- }, -- { -- name: _("Suffixes"), -- icon: , -- id: "suffixes-tree", -- children: suffixData, -- defaultExpanded: true, -- action: ( -- -- ), -- } -- ]; -+ -+ let current_node = this.state.node_name; -+ if (fullReset) { -+ current_node = DB_CONFIG; -+ } -+ -+ treeData[4].children = suffixData; // suffixes node -+ this.setState(() => ({ -+ nodes: treeData, -+ node_name: current_node, -+ }), this.loadAttrs); -+ }) -+ .fail(err => { -+ // Handle backend get-tree failure gracefully - let current_node = this.state.node_name; - if (fullReset) { - current_node = DB_CONFIG; -diff --git a/src/cockpit/389-console/src/monitor.jsx b/src/cockpit/389-console/src/monitor.jsx -index ad48d1f87..91a8e3e37 100644 ---- a/src/cockpit/389-console/src/monitor.jsx -+++ b/src/cockpit/389-console/src/monitor.jsx -@@ -200,6 +200,84 @@ export class Monitor extends React.Component { - } - - loadSuffixTree(fullReset) { -+ const basicData = [ -+ { -+ name: _("Server Statistics"), -+ icon: , -+ id: "server-monitor", -+ type: "server", -+ }, -+ { -+ name: _("Replication"), -+ icon: , -+ id: "replication-monitor", -+ type: "replication", -+ defaultExpanded: true, -+ children: [ -+ { -+ name: _("Synchronization Report"), -+ icon: , -+ id: "sync-report", -+ item: "sync-report", -+ type: "repl-mon", -+ }, -+ { -+ name: _("Log Analysis"), -+ icon: , -+ id: "log-analysis", -+ item: "log-analysis", -+ type: "repl-mon", -+ } -+ ], -+ }, -+ { -+ name: _("Database"), -+ icon: , -+ id: "database-monitor", -+ type: "database", -+ children: [], // Will be populated with treeData on success -+ defaultExpanded: true, -+ }, -+ { -+ name: _("Logging"), -+ icon: , -+ id: "log-monitor", -+ defaultExpanded: true, -+ children: [ -+ { -+ name: _("Access Log"), -+ icon: , -+ id: "access-log-monitor", -+ type: "log", -+ }, -+ { -+ name: _("Audit Log"), -+ icon: , -+ id: "audit-log-monitor", -+ type: "log", -+ }, -+ { -+ name: _("Audit Failure Log"), -+ icon: , -+ id: "auditfail-log-monitor", -+ type: "log", -+ }, -+ { -+ name: _("Errors Log"), -+ icon: , -+ id: "error-log-monitor", -+ type: "log", -+ }, -+ { -+ name: _("Security Log"), -+ icon: , -+ id: "security-log-monitor", -+ type: "log", -+ }, -+ ] -+ }, -+ ]; -+ - const cmd = [ - "dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket", - "backend", "get-tree", -@@ -210,83 +288,7 @@ export class Monitor extends React.Component { - .done(content => { - const treeData = JSON.parse(content); - this.processTree(treeData); -- const basicData = [ -- { -- name: _("Server Statistics"), -- icon: , -- id: "server-monitor", -- type: "server", -- }, -- { -- name: _("Replication"), -- icon: , -- id: "replication-monitor", -- type: "replication", -- defaultExpanded: true, -- children: [ -- { -- name: _("Synchronization Report"), -- icon: , -- id: "sync-report", -- item: "sync-report", -- type: "repl-mon", -- }, -- { -- name: _("Log Analysis"), -- icon: , -- id: "log-analysis", -- item: "log-analysis", -- type: "repl-mon", -- } -- ], -- }, -- { -- name: _("Database"), -- icon: , -- id: "database-monitor", -- type: "database", -- children: [], -- defaultExpanded: true, -- }, -- { -- name: _("Logging"), -- icon: , -- id: "log-monitor", -- defaultExpanded: true, -- children: [ -- { -- name: _("Access Log"), -- icon: , -- id: "access-log-monitor", -- type: "log", -- }, -- { -- name: _("Audit Log"), -- icon: , -- id: "audit-log-monitor", -- type: "log", -- }, -- { -- name: _("Audit Failure Log"), -- icon: , -- id: "auditfail-log-monitor", -- type: "log", -- }, -- { -- name: _("Errors Log"), -- icon: , -- id: "error-log-monitor", -- type: "log", -- }, -- { -- name: _("Security Log"), -- icon: , -- id: "security-log-monitor", -- type: "log", -- }, -- ] -- }, -- ]; -+ - let current_node = this.state.node_name; - let type = this.state.node_type; - if (fullReset) { -@@ -296,6 +298,22 @@ export class Monitor extends React.Component { - basicData[2].children = treeData; // database node - this.processReplSuffixes(basicData[1].children); - -+ this.setState(() => ({ -+ nodes: basicData, -+ node_name: current_node, -+ node_type: type, -+ }), this.update_tree_nodes); -+ }) -+ .fail(err => { -+ // Handle backend get-tree failure gracefully -+ let current_node = this.state.node_name; -+ let type = this.state.node_type; -+ if (fullReset) { -+ current_node = "server-monitor"; -+ type = "server"; -+ } -+ this.processReplSuffixes(basicData[1].children); -+ - this.setState(() => ({ - nodes: basicData, - node_name: current_node, -diff --git a/src/cockpit/389-console/src/replication.jsx b/src/cockpit/389-console/src/replication.jsx -index fa492fd2a..aa535bfc7 100644 ---- a/src/cockpit/389-console/src/replication.jsx -+++ b/src/cockpit/389-console/src/replication.jsx -@@ -177,6 +177,16 @@ export class Replication extends React.Component { - loaded: false - }); - -+ const basicData = [ -+ { -+ name: _("Suffixes"), -+ icon: , -+ id: "repl-suffixes", -+ children: [], -+ defaultExpanded: true -+ } -+ ]; -+ - const cmd = [ - "dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket", - "backend", "get-tree", -@@ -199,15 +209,7 @@ export class Replication extends React.Component { - } - } - } -- const basicData = [ -- { -- name: _("Suffixes"), -- icon: , -- id: "repl-suffixes", -- children: [], -- defaultExpanded: true -- } -- ]; -+ - let current_node = this.state.node_name; - let current_type = this.state.node_type; - let replicated = this.state.node_replicated; -@@ -258,6 +260,19 @@ export class Replication extends React.Component { - } - - basicData[0].children = treeData; -+ this.setState({ -+ nodes: basicData, -+ node_name: current_node, -+ node_type: current_type, -+ node_replicated: replicated, -+ }, () => { this.update_tree_nodes() }); -+ }) -+ .fail(err => { -+ // Handle backend get-tree failure gracefully -+ let current_node = this.state.node_name; -+ let current_type = this.state.node_type; -+ let replicated = this.state.node_replicated; -+ - this.setState({ - nodes: basicData, - node_name: current_node, -@@ -905,18 +920,18 @@ export class Replication extends React.Component { - disableTree: false - }); - }); -- }) -- .fail(err => { -- const errMsg = JSON.parse(err); -- this.props.addNotification( -- "error", -- cockpit.format(_("Error loading replication agreements configuration - $0"), errMsg.desc) -- ); -- this.setState({ -- suffixLoading: false, -- disableTree: false -+ }) -+ .fail(err => { -+ const errMsg = JSON.parse(err); -+ this.props.addNotification( -+ "error", -+ cockpit.format(_("Error loading replication agreements configuration - $0"), errMsg.desc) -+ ); -+ this.setState({ -+ suffixLoading: false, -+ disableTree: false -+ }); - }); -- }); - }) - .fail(err => { - // changelog failure -diff --git a/src/lib389/lib389/backend.py b/src/lib389/lib389/backend.py -index 1d000ed66..53f15b6b0 100644 ---- a/src/lib389/lib389/backend.py -+++ b/src/lib389/lib389/backend.py -@@ -694,24 +694,32 @@ class Backend(DSLdapObject): - parent_suffix = properties.pop('parent', False) - - # Okay, now try to make the backend. -- super(Backend, self).create(dn, properties, basedn) -+ backend_obj = super(Backend, self).create(dn, properties, basedn) - - # We check if the mapping tree exists in create, so do this *after* - if create_mapping_tree is True: -- properties = { -+ mapping_tree_properties = { - 'cn': self._nprops_stash['nsslapd-suffix'], - 'nsslapd-state': 'backend', - 'nsslapd-backend': self._nprops_stash['cn'], - } - if parent_suffix: - # This is a subsuffix, set the parent suffix -- properties['nsslapd-parent-suffix'] = parent_suffix -- self._mts.create(properties=properties) -+ mapping_tree_properties['nsslapd-parent-suffix'] = parent_suffix -+ -+ try: -+ self._mts.create(properties=mapping_tree_properties) -+ except Exception as e: -+ try: -+ backend_obj.delete() -+ except Exception as cleanup_error: -+ self._instance.log.error(f"Failed to cleanup backend after mapping tree creation failure: {cleanup_error}") -+ raise e - - # We can't create the sample entries unless a mapping tree was installed. - if sample_entries is not False and create_mapping_tree is True: - self.create_sample_entries(sample_entries) -- return self -+ return backend_obj - - def delete(self): - """Deletes the backend, it's mapping tree and all related indices. --- -2.49.0 - diff --git a/0003-Issue-6753-Add-add_exclude_subtree-and-remove_exclud.patch b/0003-Issue-6753-Add-add_exclude_subtree-and-remove_exclud.patch deleted file mode 100644 index a134041..0000000 --- a/0003-Issue-6753-Add-add_exclude_subtree-and-remove_exclud.patch +++ /dev/null @@ -1,515 +0,0 @@ -From 9da3349d53f4073740ddb1aca97713e13cb40cd0 Mon Sep 17 00:00:00 2001 -From: Lenka Doudova -Date: Mon, 9 Jun 2025 15:15:04 +0200 -Subject: [PATCH] Issue 6753 - Add 'add_exclude_subtree' and - 'remove_exclude_subtree' methods to Attribute uniqueness plugin - -Description: -Adding 'add_exclude_subtree' and 'remove_exclude_subtree' methods to AttributeUniquenessPlugin in -order to be able to easily add or remove an exclude subtree. -Porting ticket 47927 test to -dirsrvtests/tests/suites/plugins/attruniq_test.py - -Relates: #6753 - -Author: Lenka Doudova - -Reviewers: Simon Pichugin, Mark Reynolds ---- - .../tests/suites/plugins/attruniq_test.py | 171 +++++++++++ - dirsrvtests/tests/tickets/ticket47927_test.py | 267 ------------------ - src/lib389/lib389/plugins.py | 10 + - 3 files changed, 181 insertions(+), 267 deletions(-) - delete mode 100644 dirsrvtests/tests/tickets/ticket47927_test.py - -diff --git a/dirsrvtests/tests/suites/plugins/attruniq_test.py b/dirsrvtests/tests/suites/plugins/attruniq_test.py -index c1ccad9ae..aac659c29 100644 ---- a/dirsrvtests/tests/suites/plugins/attruniq_test.py -+++ b/dirsrvtests/tests/suites/plugins/attruniq_test.py -@@ -10,6 +10,7 @@ import pytest - import ldap - import logging - from lib389.plugins import AttributeUniquenessPlugin -+from lib389.idm.nscontainer import nsContainers - from lib389.idm.user import UserAccounts - from lib389.idm.group import Groups - from lib389._constants import DEFAULT_SUFFIX -@@ -22,6 +23,19 @@ log = logging.getLogger(__name__) - MAIL_ATTR_VALUE = 'non-uniq@value.net' - MAIL_ATTR_VALUE_ALT = 'alt-mail@value.net' - -+EXCLUDED_CONTAINER_CN = "excluded_container" -+EXCLUDED_CONTAINER_DN = "cn={},{}".format(EXCLUDED_CONTAINER_CN, DEFAULT_SUFFIX) -+ -+EXCLUDED_BIS_CONTAINER_CN = "excluded_bis_container" -+EXCLUDED_BIS_CONTAINER_DN = "cn={},{}".format(EXCLUDED_BIS_CONTAINER_CN, DEFAULT_SUFFIX) -+ -+ENFORCED_CONTAINER_CN = "enforced_container" -+ -+USER_1_CN = "test_1" -+USER_2_CN = "test_2" -+USER_3_CN = "test_3" -+USER_4_CN = "test_4" -+ - - def test_modrdn_attr_uniqueness(topology_st): - """Test that we can not add two entries that have the same attr value that is -@@ -154,3 +168,160 @@ def test_multiple_attr_uniqueness(topology_st): - testuser2.delete() - attruniq.disable() - attruniq.delete() -+ -+ -+def test_exclude_subtrees(topology_st): -+ """ Test attribute uniqueness with exclude scope -+ -+ :id: 43d29a60-40e1-4ebd-b897-6ef9f20e9f27 -+ :setup: Standalone instance -+ :steps: -+ 1. Setup and enable attribute uniqueness plugin for telephonenumber unique attribute -+ 2. Create subtrees and test users -+ 3. Add a unique attribute to a user within uniqueness scope -+ 4. Add exclude subtree -+ 5. Try to add existing value attribute to an entry within uniqueness scope -+ 6. Try to add existing value attribute to an entry within exclude scope -+ 7. Remove the attribute from affected entries -+ 8. Add a unique attribute to a user within exclude scope -+ 9. Try to add existing value attribute to an entry within uniqueness scope -+ 10. Try to add existing value attribute to another entry within uniqueness scope -+ 11. Remove the attribute from affected entries -+ 12. Add another exclude subtree -+ 13. Add a unique attribute to a user within uniqueness scope -+ 14. Try to add existing value attribute to an entry within uniqueness scope -+ 15. Try to add existing value attribute to an entry within exclude scope -+ 16. Try to add existing value attribute to an entry within another exclude scope -+ 17. Clean up entries -+ :expectedresults: -+ 1. Success -+ 2. Success -+ 3. Success -+ 4. Success -+ 5. Should raise CONSTRAINT_VIOLATION -+ 6. Success -+ 7. Success -+ 8. Success -+ 9. Success -+ 10. Should raise CONSTRAINT_VIOLATION -+ 11. Success -+ 12. Success -+ 13. Success -+ 14. Should raise CONSTRAINT_VIOLATION -+ 15. Success -+ 16. Success -+ 17. Success -+ """ -+ log.info('Setup attribute uniqueness plugin') -+ attruniq = AttributeUniquenessPlugin(topology_st.standalone, dn="cn=attruniq,cn=plugins,cn=config") -+ attruniq.create(properties={'cn': 'attruniq'}) -+ attruniq.add_unique_attribute('telephonenumber') -+ attruniq.add_unique_subtree(DEFAULT_SUFFIX) -+ attruniq.enable_all_subtrees() -+ attruniq.enable() -+ topology_st.standalone.restart() -+ -+ log.info('Create subtrees container') -+ containers = nsContainers(topology_st.standalone, DEFAULT_SUFFIX) -+ cont1 = containers.create(properties={'cn': EXCLUDED_CONTAINER_CN}) -+ cont2 = containers.create(properties={'cn': EXCLUDED_BIS_CONTAINER_CN}) -+ cont3 = containers.create(properties={'cn': ENFORCED_CONTAINER_CN}) -+ -+ log.info('Create test users') -+ users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX, -+ rdn='cn={}'.format(ENFORCED_CONTAINER_CN)) -+ users_excluded = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX, -+ rdn='cn={}'.format(EXCLUDED_CONTAINER_CN)) -+ users_excluded2 = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX, -+ rdn='cn={}'.format(EXCLUDED_BIS_CONTAINER_CN)) -+ -+ user1 = users.create(properties={'cn': USER_1_CN, -+ 'uid': USER_1_CN, -+ 'sn': USER_1_CN, -+ 'uidNumber': '1', -+ 'gidNumber': '11', -+ 'homeDirectory': '/home/{}'.format(USER_1_CN)}) -+ user2 = users.create(properties={'cn': USER_2_CN, -+ 'uid': USER_2_CN, -+ 'sn': USER_2_CN, -+ 'uidNumber': '2', -+ 'gidNumber': '22', -+ 'homeDirectory': '/home/{}'.format(USER_2_CN)}) -+ user3 = users_excluded.create(properties={'cn': USER_3_CN, -+ 'uid': USER_3_CN, -+ 'sn': USER_3_CN, -+ 'uidNumber': '3', -+ 'gidNumber': '33', -+ 'homeDirectory': '/home/{}'.format(USER_3_CN)}) -+ user4 = users_excluded2.create(properties={'cn': USER_4_CN, -+ 'uid': USER_4_CN, -+ 'sn': USER_4_CN, -+ 'uidNumber': '4', -+ 'gidNumber': '44', -+ 'homeDirectory': '/home/{}'.format(USER_4_CN)}) -+ -+ UNIQUE_VALUE = '1234' -+ -+ try: -+ log.info('Create user with unique attribute') -+ user1.add('telephonenumber', UNIQUE_VALUE) -+ assert user1.present('telephonenumber', UNIQUE_VALUE) -+ -+ log.info('Add exclude subtree') -+ attruniq.add_exclude_subtree(EXCLUDED_CONTAINER_DN) -+ topology_st.standalone.restart() -+ -+ log.info('Verify an already used attribute value cannot be added within the same subtree') -+ with pytest.raises(ldap.CONSTRAINT_VIOLATION): -+ user2.add('telephonenumber', UNIQUE_VALUE) -+ -+ log.info('Verify an entry with same attribute value can be added within exclude subtree') -+ user3.add('telephonenumber', UNIQUE_VALUE) -+ assert user3.present('telephonenumber', UNIQUE_VALUE) -+ -+ log.info('Cleanup unique attribute values') -+ user1.remove_all('telephonenumber') -+ user3.remove_all('telephonenumber') -+ -+ log.info('Add a unique value to an entry in excluded scope') -+ user3.add('telephonenumber', UNIQUE_VALUE) -+ assert user3.present('telephonenumber', UNIQUE_VALUE) -+ -+ log.info('Verify the same value can be added to an entry within uniqueness scope') -+ user1.add('telephonenumber', UNIQUE_VALUE) -+ assert user1.present('telephonenumber', UNIQUE_VALUE) -+ -+ log.info('Verify that yet another same value cannot be added to another entry within uniqueness scope') -+ with pytest.raises(ldap.CONSTRAINT_VIOLATION): -+ user2.add('telephonenumber', UNIQUE_VALUE) -+ -+ log.info('Cleanup unique attribute values') -+ user1.remove_all('telephonenumber') -+ user3.remove_all('telephonenumber') -+ -+ log.info('Add another exclude subtree') -+ attruniq.add_exclude_subtree(EXCLUDED_BIS_CONTAINER_DN) -+ topology_st.standalone.restart() -+ -+ user1.add('telephonenumber', UNIQUE_VALUE) -+ log.info('Verify an already used attribute value cannot be added within the same subtree') -+ with pytest.raises(ldap.CONSTRAINT_VIOLATION): -+ user2.add('telephonenumber', UNIQUE_VALUE) -+ -+ log.info('Verify an already used attribute can be added to an entry in exclude scope') -+ user3.add('telephonenumber', UNIQUE_VALUE) -+ assert user3.present('telephonenumber', UNIQUE_VALUE) -+ user4.add('telephonenumber', UNIQUE_VALUE) -+ assert user4.present('telephonenumber', UNIQUE_VALUE) -+ -+ finally: -+ log.info('Clean up users, containers and attribute uniqueness plugin') -+ user1.delete() -+ user2.delete() -+ user3.delete() -+ user4.delete() -+ cont1.delete() -+ cont2.delete() -+ cont3.delete() -+ attruniq.disable() -+ attruniq.delete() -\ No newline at end of file -diff --git a/dirsrvtests/tests/tickets/ticket47927_test.py b/dirsrvtests/tests/tickets/ticket47927_test.py -deleted file mode 100644 -index 887fe1af4..000000000 ---- a/dirsrvtests/tests/tickets/ticket47927_test.py -+++ /dev/null -@@ -1,267 +0,0 @@ --# --- BEGIN COPYRIGHT BLOCK --- --# Copyright (C) 2016 Red Hat, Inc. --# All rights reserved. --# --# License: GPL (version 3 or any later version). --# See LICENSE for details. --# --- END COPYRIGHT BLOCK --- --# --import pytest --from lib389.tasks import * --from lib389.utils import * --from lib389.topologies import topology_st -- --from lib389._constants import SUFFIX, DEFAULT_SUFFIX, PLUGIN_ATTR_UNIQUENESS -- --# Skip on older versions --pytestmark = [pytest.mark.tier2, -- pytest.mark.skipif(ds_is_older('1.3.4'), reason="Not implemented")] -- --logging.getLogger(__name__).setLevel(logging.DEBUG) --log = logging.getLogger(__name__) -- --EXCLUDED_CONTAINER_CN = "excluded_container" --EXCLUDED_CONTAINER_DN = "cn=%s,%s" % (EXCLUDED_CONTAINER_CN, SUFFIX) -- --EXCLUDED_BIS_CONTAINER_CN = "excluded_bis_container" --EXCLUDED_BIS_CONTAINER_DN = "cn=%s,%s" % (EXCLUDED_BIS_CONTAINER_CN, SUFFIX) -- --ENFORCED_CONTAINER_CN = "enforced_container" --ENFORCED_CONTAINER_DN = "cn=%s,%s" % (ENFORCED_CONTAINER_CN, SUFFIX) -- --USER_1_CN = "test_1" --USER_1_DN = "cn=%s,%s" % (USER_1_CN, ENFORCED_CONTAINER_DN) --USER_2_CN = "test_2" --USER_2_DN = "cn=%s,%s" % (USER_2_CN, ENFORCED_CONTAINER_DN) --USER_3_CN = "test_3" --USER_3_DN = "cn=%s,%s" % (USER_3_CN, EXCLUDED_CONTAINER_DN) --USER_4_CN = "test_4" --USER_4_DN = "cn=%s,%s" % (USER_4_CN, EXCLUDED_BIS_CONTAINER_DN) -- -- --def test_ticket47927_init(topology_st): -- topology_st.standalone.plugins.enable(name=PLUGIN_ATTR_UNIQUENESS) -- try: -- topology_st.standalone.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config', -- [(ldap.MOD_REPLACE, 'uniqueness-attribute-name', b'telephonenumber'), -- (ldap.MOD_REPLACE, 'uniqueness-subtrees', ensure_bytes(DEFAULT_SUFFIX)), -- ]) -- except ldap.LDAPError as e: -- log.fatal('test_ticket47927: Failed to configure plugin for "telephonenumber": error ' + e.args[0]['desc']) -- assert False -- topology_st.standalone.restart(timeout=120) -- -- topology_st.standalone.add_s(Entry((EXCLUDED_CONTAINER_DN, {'objectclass': "top nscontainer".split(), -- 'cn': EXCLUDED_CONTAINER_CN}))) -- topology_st.standalone.add_s(Entry((EXCLUDED_BIS_CONTAINER_DN, {'objectclass': "top nscontainer".split(), -- 'cn': EXCLUDED_BIS_CONTAINER_CN}))) -- topology_st.standalone.add_s(Entry((ENFORCED_CONTAINER_DN, {'objectclass': "top nscontainer".split(), -- 'cn': ENFORCED_CONTAINER_CN}))) -- -- # adding an entry on a stage with a different 'cn' -- topology_st.standalone.add_s(Entry((USER_1_DN, { -- 'objectclass': "top person".split(), -- 'sn': USER_1_CN, -- 'cn': USER_1_CN}))) -- # adding an entry on a stage with a different 'cn' -- topology_st.standalone.add_s(Entry((USER_2_DN, { -- 'objectclass': "top person".split(), -- 'sn': USER_2_CN, -- 'cn': USER_2_CN}))) -- topology_st.standalone.add_s(Entry((USER_3_DN, { -- 'objectclass': "top person".split(), -- 'sn': USER_3_CN, -- 'cn': USER_3_CN}))) -- topology_st.standalone.add_s(Entry((USER_4_DN, { -- 'objectclass': "top person".split(), -- 'sn': USER_4_CN, -- 'cn': USER_4_CN}))) -- -- --def test_ticket47927_one(topology_st): -- ''' -- Check that uniqueness is enforce on all SUFFIX -- ''' -- UNIQUE_VALUE = b'1234' -- try: -- topology_st.standalone.modify_s(USER_1_DN, -- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) -- except ldap.LDAPError as e: -- log.fatal('test_ticket47927_one: Failed to set the telephonenumber for %s: %s' % (USER_1_DN, e.args[0]['desc'])) -- assert False -- -- # we expect to fail because user1 is in the scope of the plugin -- try: -- topology_st.standalone.modify_s(USER_2_DN, -- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) -- log.fatal('test_ticket47927_one: unexpected success to set the telephonenumber for %s' % (USER_2_DN)) -- assert False -- except ldap.LDAPError as e: -- log.fatal('test_ticket47927_one: Failed (expected) to set the telephonenumber for %s: %s' % ( -- USER_2_DN, e.args[0]['desc'])) -- pass -- -- # we expect to fail because user1 is in the scope of the plugin -- try: -- topology_st.standalone.modify_s(USER_3_DN, -- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) -- log.fatal('test_ticket47927_one: unexpected success to set the telephonenumber for %s' % (USER_3_DN)) -- assert False -- except ldap.LDAPError as e: -- log.fatal('test_ticket47927_one: Failed (expected) to set the telephonenumber for %s: %s' % ( -- USER_3_DN, e.args[0]['desc'])) -- pass -- -- --def test_ticket47927_two(topology_st): -- ''' -- Exclude the EXCLUDED_CONTAINER_DN from the uniqueness plugin -- ''' -- try: -- topology_st.standalone.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config', -- [(ldap.MOD_REPLACE, 'uniqueness-exclude-subtrees', ensure_bytes(EXCLUDED_CONTAINER_DN))]) -- except ldap.LDAPError as e: -- log.fatal('test_ticket47927_two: Failed to configure plugin for to exclude %s: error %s' % ( -- EXCLUDED_CONTAINER_DN, e.args[0]['desc'])) -- assert False -- topology_st.standalone.restart(timeout=120) -- -- --def test_ticket47927_three(topology_st): -- ''' -- Check that uniqueness is enforced on full SUFFIX except EXCLUDED_CONTAINER_DN -- First case: it exists an entry (with the same attribute value) in the scope -- of the plugin and we set the value in an entry that is in an excluded scope -- ''' -- UNIQUE_VALUE = b'9876' -- try: -- topology_st.standalone.modify_s(USER_1_DN, -- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) -- except ldap.LDAPError as e: -- log.fatal('test_ticket47927_three: Failed to set the telephonenumber ' + e.args[0]['desc']) -- assert False -- -- # we should not be allowed to set this value (because user1 is in the scope) -- try: -- topology_st.standalone.modify_s(USER_2_DN, -- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) -- log.fatal('test_ticket47927_three: unexpected success to set the telephonenumber for %s' % (USER_2_DN)) -- assert False -- except ldap.LDAPError as e: -- log.fatal('test_ticket47927_three: Failed (expected) to set the telephonenumber for %s: %s' % ( -- USER_2_DN, e.args[0]['desc'])) -- -- # USER_3_DN is in EXCLUDED_CONTAINER_DN so update should be successful -- try: -- topology_st.standalone.modify_s(USER_3_DN, -- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) -- log.fatal('test_ticket47927_three: success to set the telephonenumber for %s' % (USER_3_DN)) -- except ldap.LDAPError as e: -- log.fatal('test_ticket47927_three: Failed (unexpected) to set the telephonenumber for %s: %s' % ( -- USER_3_DN, e.args[0]['desc'])) -- assert False -- -- --def test_ticket47927_four(topology_st): -- ''' -- Check that uniqueness is enforced on full SUFFIX except EXCLUDED_CONTAINER_DN -- Second case: it exists an entry (with the same attribute value) in an excluded scope -- of the plugin and we set the value in an entry is in the scope -- ''' -- UNIQUE_VALUE = b'1111' -- # USER_3_DN is in EXCLUDED_CONTAINER_DN so update should be successful -- try: -- topology_st.standalone.modify_s(USER_3_DN, -- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) -- log.fatal('test_ticket47927_four: success to set the telephonenumber for %s' % USER_3_DN) -- except ldap.LDAPError as e: -- log.fatal('test_ticket47927_four: Failed (unexpected) to set the telephonenumber for %s: %s' % ( -- USER_3_DN, e.args[0]['desc'])) -- assert False -- -- # we should be allowed to set this value (because user3 is excluded from scope) -- try: -- topology_st.standalone.modify_s(USER_1_DN, -- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) -- except ldap.LDAPError as e: -- log.fatal( -- 'test_ticket47927_four: Failed to set the telephonenumber for %s: %s' % (USER_1_DN, e.args[0]['desc'])) -- assert False -- -- # we should not be allowed to set this value (because user1 is in the scope) -- try: -- topology_st.standalone.modify_s(USER_2_DN, -- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) -- log.fatal('test_ticket47927_four: unexpected success to set the telephonenumber %s' % USER_2_DN) -- assert False -- except ldap.LDAPError as e: -- log.fatal('test_ticket47927_four: Failed (expected) to set the telephonenumber for %s: %s' % ( -- USER_2_DN, e.args[0]['desc'])) -- pass -- -- --def test_ticket47927_five(topology_st): -- ''' -- Exclude the EXCLUDED_BIS_CONTAINER_DN from the uniqueness plugin -- ''' -- try: -- topology_st.standalone.modify_s('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config', -- [(ldap.MOD_ADD, 'uniqueness-exclude-subtrees', ensure_bytes(EXCLUDED_BIS_CONTAINER_DN))]) -- except ldap.LDAPError as e: -- log.fatal('test_ticket47927_five: Failed to configure plugin for to exclude %s: error %s' % ( -- EXCLUDED_BIS_CONTAINER_DN, e.args[0]['desc'])) -- assert False -- topology_st.standalone.restart(timeout=120) -- topology_st.standalone.getEntry('cn=' + PLUGIN_ATTR_UNIQUENESS + ',cn=plugins,cn=config', ldap.SCOPE_BASE) -- -- --def test_ticket47927_six(topology_st): -- ''' -- Check that uniqueness is enforced on full SUFFIX except EXCLUDED_CONTAINER_DN -- and EXCLUDED_BIS_CONTAINER_DN -- First case: it exists an entry (with the same attribute value) in the scope -- of the plugin and we set the value in an entry that is in an excluded scope -- ''' -- UNIQUE_VALUE = b'222' -- try: -- topology_st.standalone.modify_s(USER_1_DN, -- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) -- except ldap.LDAPError as e: -- log.fatal('test_ticket47927_six: Failed to set the telephonenumber ' + e.args[0]['desc']) -- assert False -- -- # we should not be allowed to set this value (because user1 is in the scope) -- try: -- topology_st.standalone.modify_s(USER_2_DN, -- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) -- log.fatal('test_ticket47927_six: unexpected success to set the telephonenumber for %s' % (USER_2_DN)) -- assert False -- except ldap.LDAPError as e: -- log.fatal('test_ticket47927_six: Failed (expected) to set the telephonenumber for %s: %s' % ( -- USER_2_DN, e.args[0]['desc'])) -- -- # USER_3_DN is in EXCLUDED_CONTAINER_DN so update should be successful -- try: -- topology_st.standalone.modify_s(USER_3_DN, -- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) -- log.fatal('test_ticket47927_six: success to set the telephonenumber for %s' % (USER_3_DN)) -- except ldap.LDAPError as e: -- log.fatal('test_ticket47927_six: Failed (unexpected) to set the telephonenumber for %s: %s' % ( -- USER_3_DN, e.args[0]['desc'])) -- assert False -- # USER_4_DN is in EXCLUDED_CONTAINER_DN so update should be successful -- try: -- topology_st.standalone.modify_s(USER_4_DN, -- [(ldap.MOD_REPLACE, 'telephonenumber', UNIQUE_VALUE)]) -- log.fatal('test_ticket47927_six: success to set the telephonenumber for %s' % (USER_4_DN)) -- except ldap.LDAPError as e: -- log.fatal('test_ticket47927_six: Failed (unexpected) to set the telephonenumber for %s: %s' % ( -- USER_4_DN, e.args[0]['desc'])) -- assert False -- -- --if __name__ == '__main__': -- # Run isolated -- # -s for DEBUG mode -- CURRENT_FILE = os.path.realpath(__file__) -- pytest.main("-s %s" % CURRENT_FILE) -diff --git a/src/lib389/lib389/plugins.py b/src/lib389/lib389/plugins.py -index 31bbfa502..977091726 100644 ---- a/src/lib389/lib389/plugins.py -+++ b/src/lib389/lib389/plugins.py -@@ -175,6 +175,16 @@ class AttributeUniquenessPlugin(Plugin): - - self.set('uniqueness-across-all-subtrees', 'off') - -+ def add_exclude_subtree(self, basedn): -+ """Add a uniqueness-exclude-subtrees attribute""" -+ -+ self.add('uniqueness-exclude-subtrees', basedn) -+ -+ def remove_exclude_subtree(self, basedn): -+ """Remove a uniqueness-exclude-subtrees attribute""" -+ -+ self.remove('uniqueness-exclude-subtrees', basedn) -+ - - class AttributeUniquenessPlugins(DSLdapObjects): - """A DSLdapObjects entity which represents Attribute Uniqueness plugin instances --- -2.49.0 - diff --git a/0004-Issue-6857-uiduniq-allow-specifying-match-rules-in-t.patch b/0004-Issue-6857-uiduniq-allow-specifying-match-rules-in-t.patch deleted file mode 100644 index 46f6e8c..0000000 --- a/0004-Issue-6857-uiduniq-allow-specifying-match-rules-in-t.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 4fb3a2ea084c1de3ba60ca97a5dd14fc7b8225bd Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Wed, 9 Jul 2025 12:08:09 +0300 -Subject: [PATCH] Issue 6857 - uiduniq: allow specifying match rules in the - filter - -Allow uniqueness plugin to work with attributes where uniqueness should -be enforced using different matching rule than the one defined for the -attribute itself. - -Since uniqueness plugin configuration can contain multiple attributes, -add matching rule right to the attribute as it is used in the LDAP rule -(e.g. 'attribute:caseIgnoreMatch:' to force 'attribute' to be searched -with case-insensitive matching rule instead of the original matching -rule. - -Fixes: https://github.com/389ds/389-ds-base/issues/6857 - -Signed-off-by: Alexander Bokovoy ---- - ldap/servers/plugins/uiduniq/uid.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/ldap/servers/plugins/uiduniq/uid.c b/ldap/servers/plugins/uiduniq/uid.c -index 053af4f9d..887e79d78 100644 ---- a/ldap/servers/plugins/uiduniq/uid.c -+++ b/ldap/servers/plugins/uiduniq/uid.c -@@ -1030,7 +1030,14 @@ preop_add(Slapi_PBlock *pb) - } - - for (i = 0; attrNames && attrNames[i]; i++) { -+ char *attr_match = strchr(attrNames[i], ':'); -+ if (attr_match != NULL) { -+ attr_match[0] = '\0'; -+ } - err = slapi_entry_attr_find(e, attrNames[i], &attr); -+ if (attr_match != NULL) { -+ attr_match[0] = ':'; -+ } - if (!err) { - /* - * Passed all the requirements - this is an operation we --- -2.49.0 - diff --git a/0005-Issue-6756-CLI-UI-Properly-handle-disabled-NDN-cache.patch b/0005-Issue-6756-CLI-UI-Properly-handle-disabled-NDN-cache.patch deleted file mode 100644 index 8a36611..0000000 --- a/0005-Issue-6756-CLI-UI-Properly-handle-disabled-NDN-cache.patch +++ /dev/null @@ -1,1201 +0,0 @@ -From 64289e4e4fcab868f099fdf6f3a9b77e9a8f78a5 Mon Sep 17 00:00:00 2001 -From: Simon Pichugin -Date: Thu, 10 Jul 2025 11:53:12 -0700 -Subject: [PATCH] Issue 6756 - CLI, UI - Properly handle disabled NDN cache - (#6757) - -Description: Fix the db_monitor function in monitor.py to check if -nsslapd-ndn-cache-enabled is off and conditionally include NDN cache -statistics only when enabled. - -Update dbMonitor.jsx components to detect when NDN cache is disabled and -conditionally render NDN cache tabs, charts, and related content with proper -fallback display when disabled. - -Add test_ndn_cache_disabled to verify both JSON and non-JSON output formats -correctly handle when NDN cache is turned off and on. - -Fixes: https://github.com/389ds/389-ds-base/issues/6756 - -Reviewed by: @mreynolds389 (Thanks!) ---- - dirsrvtests/tests/suites/clu/dbmon_test.py | 90 +++ - src/cockpit/389-console/src/database.jsx | 4 +- - .../src/lib/database/databaseConfig.jsx | 48 +- - .../389-console/src/lib/monitor/dbMonitor.jsx | 735 ++++++++++-------- - src/lib389/lib389/cli_conf/monitor.py | 77 +- - 5 files changed, 580 insertions(+), 374 deletions(-) - -diff --git a/dirsrvtests/tests/suites/clu/dbmon_test.py b/dirsrvtests/tests/suites/clu/dbmon_test.py -index 5eeaca162..bf57690c4 100644 ---- a/dirsrvtests/tests/suites/clu/dbmon_test.py -+++ b/dirsrvtests/tests/suites/clu/dbmon_test.py -@@ -11,6 +11,7 @@ import subprocess - import pytest - import json - import glob -+import re - - from lib389.tasks import * - from lib389.utils import * -@@ -272,6 +273,95 @@ def test_dbmon_mp_pagesize(topology_st): - assert real_free_percentage == dbmon_free_percentage - - -+def test_ndn_cache_disabled(topology_st): -+ """Test dbmon output when ndn-cache-enabled is turned off -+ -+ :id: 760e217c-70e8-4767-b504-dda7ba2e1f64 -+ :setup: Standalone instance -+ :steps: -+ 1. Run dbmon with nsslapd-ndn-cache-enabled=on (default) -+ 2. Verify NDN cache stats are present in the output -+ 3. Set nsslapd-ndn-cache-enabled=off and restart -+ 4. Run dbmon again and verify NDN cache stats are not present -+ 5. Set nsslapd-ndn-cache-enabled=on and restart -+ 6. Run dbmon again and verify NDN cache stats are back -+ :expectedresults: -+ 1. Success -+ 2. Should display NDN cache data -+ 3. Success -+ 4. Should not display NDN cache data -+ 5. Success -+ 6. Should display NDN cache data -+ """ -+ inst = topology_st.standalone -+ args = FakeArgs() -+ args.backends = None -+ args.indexes = False -+ args.json = True -+ lc = LogCapture() -+ -+ log.info("Testing with NDN cache enabled (default)") -+ db_monitor(inst, DEFAULT_SUFFIX, lc.log, args) -+ db_mon_as_str = "".join((str(rec) for rec in lc.outputs)) -+ db_mon_as_str = re.sub("^[^{]*{", "{", db_mon_as_str)[:-2] -+ db_mon = json.loads(db_mon_as_str) -+ -+ assert 'ndncache' in db_mon -+ assert 'hit_ratio' in db_mon['ndncache'] -+ lc.flush() -+ -+ log.info("Setting nsslapd-ndn-cache-enabled to OFF") -+ inst.config.set('nsslapd-ndn-cache-enabled', 'off') -+ inst.restart() -+ -+ log.info("Testing with NDN cache disabled") -+ db_monitor(inst, DEFAULT_SUFFIX, lc.log, args) -+ db_mon_as_str = "".join((str(rec) for rec in lc.outputs)) -+ db_mon_as_str = re.sub("^[^{]*{", "{", db_mon_as_str)[:-2] -+ db_mon = json.loads(db_mon_as_str) -+ -+ assert 'ndncache' not in db_mon -+ lc.flush() -+ -+ log.info("Setting nsslapd-ndn-cache-enabled to ON") -+ inst.config.set('nsslapd-ndn-cache-enabled', 'on') -+ inst.restart() -+ -+ log.info("Testing with NDN cache re-enabled") -+ db_monitor(inst, DEFAULT_SUFFIX, lc.log, args) -+ db_mon_as_str = "".join((str(rec) for rec in lc.outputs)) -+ db_mon_as_str = re.sub("^[^{]*{", "{", db_mon_as_str)[:-2] -+ db_mon = json.loads(db_mon_as_str) -+ -+ assert 'ndncache' in db_mon -+ assert 'hit_ratio' in db_mon['ndncache'] -+ lc.flush() -+ -+ args.json = False -+ -+ log.info("Testing with NDN cache enabled - non-JSON output") -+ db_monitor(inst, DEFAULT_SUFFIX, lc.log, args) -+ output = "".join((str(rec) for rec in lc.outputs)) -+ -+ assert "Normalized DN Cache:" in output -+ assert "Cache Hit Ratio:" in output -+ lc.flush() -+ -+ log.info("Setting nsslapd-ndn-cache-enabled to OFF") -+ inst.config.set('nsslapd-ndn-cache-enabled', 'off') -+ inst.restart() -+ -+ log.info("Testing with NDN cache disabled - non-JSON output") -+ db_monitor(inst, DEFAULT_SUFFIX, lc.log, args) -+ output = "".join((str(rec) for rec in lc.outputs)) -+ -+ assert "Normalized DN Cache:" not in output -+ lc.flush() -+ -+ inst.config.set('nsslapd-ndn-cache-enabled', 'on') -+ inst.restart() -+ -+ - if __name__ == '__main__': - # Run isolated - # -s for DEBUG mode -diff --git a/src/cockpit/389-console/src/database.jsx b/src/cockpit/389-console/src/database.jsx -index 276125dfc..86b642b92 100644 ---- a/src/cockpit/389-console/src/database.jsx -+++ b/src/cockpit/389-console/src/database.jsx -@@ -198,7 +198,7 @@ export class Database extends React.Component { - }); - const cmd = [ - "dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket", -- "config", "get", "nsslapd-ndn-cache-max-size" -+ "config", "get", "nsslapd-ndn-cache-max-size", "nsslapd-ndn-cache-enabled" - ]; - log_cmd("loadNDN", "Load NDN cache size", cmd); - cockpit -@@ -206,10 +206,12 @@ export class Database extends React.Component { - .done(content => { - const config = JSON.parse(content); - const attrs = config.attrs; -+ const ndn_cache_enabled = attrs['nsslapd-ndn-cache-enabled'][0] === "on"; - this.setState(prevState => ({ - globalDBConfig: { - ...prevState.globalDBConfig, - ndncachemaxsize: attrs['nsslapd-ndn-cache-max-size'][0], -+ ndn_cache_enabled: ndn_cache_enabled, - }, - configUpdated: 0, - loaded: true, -diff --git a/src/cockpit/389-console/src/lib/database/databaseConfig.jsx b/src/cockpit/389-console/src/lib/database/databaseConfig.jsx -index 4c7fce706..adb8227d7 100644 ---- a/src/cockpit/389-console/src/lib/database/databaseConfig.jsx -+++ b/src/cockpit/389-console/src/lib/database/databaseConfig.jsx -@@ -2,12 +2,16 @@ import cockpit from "cockpit"; - import React from "react"; - import { log_cmd } from "../tools.jsx"; - import { -+ Alert, - Button, - Checkbox, -+ Form, - Grid, - GridItem, -+ Hr, - NumberInput, - Spinner, -+ Switch, - Tab, - Tabs, - TabTitleText, -@@ -852,12 +856,29 @@ export class GlobalDatabaseConfig extends React.Component { - - {_("NDN Cache")}}> -

-+ -+ {this.props.data.ndn_cache_enabled === false && ( -+ -+ -+ {_("The Normalized DN Cache is currently disabled. To enable it, go to Server Settings → Tuning & Limits and enable 'Normalized DN Cache', then restart the server for the changes to take effect.")} -+ -+ -+ )} -+ - - -- {_("Normalized DN Cache Max Size")} -+ {_("Normalized DN Cache Max Size") } - - - - - -@@ -1470,7 +1491,7 @@ export class GlobalDatabaseConfigMDB extends React.Component { - {_("Database Size")}}> -
- - -@@ -1641,6 +1662,23 @@ export class GlobalDatabaseConfigMDB extends React.Component { - - {_("NDN Cache")}}> -
-+ -+ {this.props.data.ndn_cache_enabled === false && ( -+ -+ -+ {_("The Normalized DN Cache is currently disabled. To enable it, go to Server Settings → Tuning & Limits and enable 'Normalized DN Cache', then restart the server for the changes to take effect.")} -+ -+ -+ )} -+ - 0; -+ let ndn_chart_data = this.state.ndnCacheList; -+ let ndn_util_chart_data = this.state.ndnCacheUtilList; -+ -+ // Only build NDN cache chart data if NDN cache is enabled -+ if (ndn_cache_enabled) { -+ const ndnratio = config.attrs.normalizeddncachehitratio[0]; -+ ndn_chart_data = this.state.ndnCacheList; -+ ndn_chart_data.shift(); -+ ndn_chart_data.push({ name: _("Cache Hit Ratio"), x: count.toString(), y: parseInt(ndnratio) }); -+ -+ // Build up the NDN Cache Util chart data -+ ndn_util_chart_data = this.state.ndnCacheUtilList; -+ const currNDNSize = parseInt(config.attrs.currentnormalizeddncachesize[0]); -+ const maxNDNSize = parseInt(config.attrs.maxnormalizeddncachesize[0]); -+ const ndn_utilization = (currNDNSize / maxNDNSize) * 100; -+ ndn_util_chart_data.shift(); -+ ndn_util_chart_data.push({ name: _("Cache Utilization"), x: ndnCount.toString(), y: parseInt(ndn_utilization) }); -+ } - - this.setState({ - data: config.attrs, -@@ -157,7 +167,8 @@ export class DatabaseMonitor extends React.Component { - ndnCacheList: ndn_chart_data, - ndnCacheUtilList: ndn_util_chart_data, - count, -- ndnCount -+ ndnCount, -+ ndn_cache_enabled - }); - }) - .fail(() => { -@@ -197,13 +208,20 @@ export class DatabaseMonitor extends React.Component { - - if (!this.state.loading) { - dbcachehit = parseInt(this.state.data.dbcachehitratio[0]); -- ndncachehit = parseInt(this.state.data.normalizeddncachehitratio[0]); -- ndncachemax = parseInt(this.state.data.maxnormalizeddncachesize[0]); -- ndncachecurr = parseInt(this.state.data.currentnormalizeddncachesize[0]); -- utilratio = Math.round((ndncachecurr / ndncachemax) * 100); -- if (utilratio === 0) { -- // Just round up to 1 -- utilratio = 1; -+ -+ // Check if NDN cache is enabled -+ const ndn_cache_enabled = this.state.data.normalizeddncachehitratio && -+ this.state.data.normalizeddncachehitratio.length > 0; -+ -+ if (ndn_cache_enabled) { -+ ndncachehit = parseInt(this.state.data.normalizeddncachehitratio[0]); -+ ndncachemax = parseInt(this.state.data.maxnormalizeddncachesize[0]); -+ ndncachecurr = parseInt(this.state.data.currentnormalizeddncachesize[0]); -+ utilratio = Math.round((ndncachecurr / ndncachemax) * 100); -+ if (utilratio === 0) { -+ // Just round up to 1 -+ utilratio = 1; -+ } - } - - // Database cache -@@ -214,119 +232,131 @@ export class DatabaseMonitor extends React.Component { - } else { - chartColor = ChartThemeColor.purple; - } -- // NDN cache ratio -- if (ndncachehit > 89) { -- ndnChartColor = ChartThemeColor.green; -- } else if (ndncachehit > 74) { -- ndnChartColor = ChartThemeColor.orange; -- } else { -- ndnChartColor = ChartThemeColor.purple; -- } -- // NDN cache utilization -- if (utilratio > 95) { -- ndnUtilColor = ChartThemeColor.purple; -- } else if (utilratio > 90) { -- ndnUtilColor = ChartThemeColor.orange; -- } else { -- ndnUtilColor = ChartThemeColor.green; -+ -+ // NDN cache colors only if enabled -+ if (ndn_cache_enabled) { -+ // NDN cache ratio -+ if (ndncachehit > 89) { -+ ndnChartColor = ChartThemeColor.green; -+ } else if (ndncachehit > 74) { -+ ndnChartColor = ChartThemeColor.orange; -+ } else { -+ ndnChartColor = ChartThemeColor.purple; -+ } -+ // NDN cache utilization -+ if (utilratio > 95) { -+ ndnUtilColor = ChartThemeColor.purple; -+ } else if (utilratio > 90) { -+ ndnUtilColor = ChartThemeColor.orange; -+ } else { -+ ndnUtilColor = ChartThemeColor.green; -+ } - } - -- content = ( -- -- {_("Database Cache")}}> --
-- -- --
--
-- -- -- {_("Cache Hit Ratio")} -- -- -- -- -- {dbcachehit}% -- -- --
--
-- `${datum.name}: ${datum.y}`} constrainToVisibleArea />} -- height={200} -- maxDomain={{ y: 100 }} -- minDomain={{ y: 0 }} -- padding={{ -- bottom: 30, -- left: 40, -- top: 10, -- right: 10, -- }} -- width={500} -- themeColor={chartColor} -- > -- -- -- -- -- -- --
-+ // Create tabs based on what caches are available -+ const tabs = []; -+ -+ // Database Cache tab is always available -+ tabs.push( -+ {_("Database Cache")}}> -+
-+ -+ -+
-+
-+ -+ -+ {_("Cache Hit Ratio")} -+ -+ -+ -+ -+ {dbcachehit}% -+ -+ -
-- -- --
-+
-+ `${datum.name}: ${datum.y}`} constrainToVisibleArea />} -+ height={200} -+ maxDomain={{ y: 100 }} -+ minDomain={{ y: 0 }} -+ padding={{ -+ bottom: 30, -+ left: 40, -+ top: 10, -+ right: 10, -+ }} -+ width={500} -+ themeColor={chartColor} -+ > -+ -+ -+ -+ -+ -+ -+
-+
-+ -+ -+
-+ -+ -+ -+ {_("Database Cache Hit Ratio:")} -+ -+ -+ {this.state.data.dbcachehitratio}% -+ -+ -+ {_("Database Cache Tries:")} -+ -+ -+ {numToCommas(this.state.data.dbcachetries)} -+ -+ -+ {_("Database Cache Hits:")} -+ -+ -+ {numToCommas(this.state.data.dbcachehits)} -+ -+ -+ {_("Cache Pages Read:")} -+ -+ -+ {numToCommas(this.state.data.dbcachepagein)} -+ -+ -+ {_("Cache Pages Written:")} -+ -+ -+ {numToCommas(this.state.data.dbcachepageout)} -+ -+ -+ {_("Read-Only Page Evictions:")} -+ -+ -+ {numToCommas(this.state.data.dbcacheroevict)} -+ -+ -+ {_("Read-Write Page Evictions:")} -+ -+ -+ {numToCommas(this.state.data.dbcacherwevict)} -+ -+ -+ -+ ); - -- -- -- {_("Database Cache Hit Ratio:")} -- -- -- {this.state.data.dbcachehitratio}% -- -- -- {_("Database Cache Tries:")} -- -- -- {numToCommas(this.state.data.dbcachetries)} -- -- -- {_("Database Cache Hits:")} -- -- -- {numToCommas(this.state.data.dbcachehits)} -- -- -- {_("Cache Pages Read:")} -- -- -- {numToCommas(this.state.data.dbcachepagein)} -- -- -- {_("Cache Pages Written:")} -- -- -- {numToCommas(this.state.data.dbcachepageout)} -- -- -- {_("Read-Only Page Evictions:")} -- -- -- {numToCommas(this.state.data.dbcacheroevict)} -- -- -- {_("Read-Write Page Evictions:")} -- -- -- {numToCommas(this.state.data.dbcacherwevict)} -- -- -- -- {_("Normalized DN Cache")}}> -+ // Only add NDN Cache tab if NDN cache is enabled -+ if (ndn_cache_enabled) { -+ tabs.push( -+ {_("Normalized DN Cache")}}> -
- - -@@ -487,6 +517,12 @@ export class DatabaseMonitor extends React.Component { - -
-
-+ ); -+ } -+ -+ content = ( -+ -+ {tabs} - - ); - } -@@ -533,7 +569,8 @@ export class DatabaseMonitorMDB extends React.Component { - ndnCount: 5, - dbCacheList: [], - ndnCacheList: [], -- ndnCacheUtilList: [] -+ ndnCacheUtilList: [], -+ ndn_cache_enabled: false - }; - - // Toggle currently active tab -@@ -585,6 +622,7 @@ export class DatabaseMonitorMDB extends React.Component { - { name: "", x: "4", y: 0 }, - { name: "", x: "5", y: 0 }, - ], -+ ndn_cache_enabled: false - }); - } - -@@ -605,19 +643,28 @@ export class DatabaseMonitorMDB extends React.Component { - count = 1; - } - -- // Build up the NDN Cache chart data -- const ndnratio = config.attrs.normalizeddncachehitratio[0]; -- const ndn_chart_data = this.state.ndnCacheList; -- ndn_chart_data.shift(); -- ndn_chart_data.push({ name: _("Cache Hit Ratio"), x: count.toString(), y: parseInt(ndnratio) }); -- -- // Build up the DB Cache Util chart data -- const ndn_util_chart_data = this.state.ndnCacheUtilList; -- const currNDNSize = parseInt(config.attrs.currentnormalizeddncachesize[0]); -- const maxNDNSize = parseInt(config.attrs.maxnormalizeddncachesize[0]); -- const ndn_utilization = (currNDNSize / maxNDNSize) * 100; -- ndn_util_chart_data.shift(); -- ndn_util_chart_data.push({ name: _("Cache Utilization"), x: ndnCount.toString(), y: parseInt(ndn_utilization) }); -+ // Check if NDN cache is enabled -+ const ndn_cache_enabled = config.attrs.normalizeddncachehitratio && -+ config.attrs.normalizeddncachehitratio.length > 0; -+ let ndn_chart_data = this.state.ndnCacheList; -+ let ndn_util_chart_data = this.state.ndnCacheUtilList; -+ -+ // Only build NDN cache chart data if NDN cache is enabled -+ if (ndn_cache_enabled) { -+ // Build up the NDN Cache chart data -+ const ndnratio = config.attrs.normalizeddncachehitratio[0]; -+ ndn_chart_data = this.state.ndnCacheList; -+ ndn_chart_data.shift(); -+ ndn_chart_data.push({ name: _("Cache Hit Ratio"), x: count.toString(), y: parseInt(ndnratio) }); -+ -+ // Build up the DB Cache Util chart data -+ ndn_util_chart_data = this.state.ndnCacheUtilList; -+ const currNDNSize = parseInt(config.attrs.currentnormalizeddncachesize[0]); -+ const maxNDNSize = parseInt(config.attrs.maxnormalizeddncachesize[0]); -+ const ndn_utilization = (currNDNSize / maxNDNSize) * 100; -+ ndn_util_chart_data.shift(); -+ ndn_util_chart_data.push({ name: _("Cache Utilization"), x: ndnCount.toString(), y: parseInt(ndn_utilization) }); -+ } - - this.setState({ - data: config.attrs, -@@ -625,7 +672,8 @@ export class DatabaseMonitorMDB extends React.Component { - ndnCacheList: ndn_chart_data, - ndnCacheUtilList: ndn_util_chart_data, - count, -- ndnCount -+ ndnCount, -+ ndn_cache_enabled - }); - }) - .fail(() => { -@@ -662,197 +710,214 @@ export class DatabaseMonitorMDB extends React.Component { - ); - - if (!this.state.loading) { -- ndncachehit = parseInt(this.state.data.normalizeddncachehitratio[0]); -- ndncachemax = parseInt(this.state.data.maxnormalizeddncachesize[0]); -- ndncachecurr = parseInt(this.state.data.currentnormalizeddncachesize[0]); -- utilratio = Math.round((ndncachecurr / ndncachemax) * 100); -- if (utilratio === 0) { -- // Just round up to 1 -- utilratio = 1; -- } -- -- // NDN cache ratio -- if (ndncachehit > 89) { -- ndnChartColor = ChartThemeColor.green; -- } else if (ndncachehit > 74) { -- ndnChartColor = ChartThemeColor.orange; -- } else { -- ndnChartColor = ChartThemeColor.purple; -- } -- // NDN cache utilization -- if (utilratio > 95) { -- ndnUtilColor = ChartThemeColor.purple; -- } else if (utilratio > 90) { -- ndnUtilColor = ChartThemeColor.orange; -- } else { -- ndnUtilColor = ChartThemeColor.green; -- } -- -- content = ( -- -- {_("Normalized DN Cache")}}> --
-- -- -- -- --
--
-- -- -- {_("Cache Hit Ratio")} -- -- -- -- -- {ndncachehit}% -- -- --
--
-- `${datum.name}: ${datum.y}`} constrainToVisibleArea />} -- height={200} -- maxDomain={{ y: 100 }} -- minDomain={{ y: 0 }} -- padding={{ -- bottom: 40, -- left: 60, -- top: 10, -- right: 15, -- }} -- width={350} -- themeColor={ndnChartColor} -- > -- -- -- -- -- -- --
--
--
--
--
-- -- -- --
--
-- -- -- {_("Cache Utilization")} -- -- -- -- -- {utilratio}% -- -- -- -- -- {_("Cached DN's")} -- -- -- {numToCommas(this.state.data.currentnormalizeddncachecount[0])} -+ // Check if NDN cache is enabled -+ const ndn_cache_enabled = this.state.data.normalizeddncachehitratio && -+ this.state.data.normalizeddncachehitratio.length > 0; -+ -+ if (ndn_cache_enabled) { -+ ndncachehit = parseInt(this.state.data.normalizeddncachehitratio[0]); -+ ndncachemax = parseInt(this.state.data.maxnormalizeddncachesize[0]); -+ ndncachecurr = parseInt(this.state.data.currentnormalizeddncachesize[0]); -+ utilratio = Math.round((ndncachecurr / ndncachemax) * 100); -+ if (utilratio === 0) { -+ // Just round up to 1 -+ utilratio = 1; -+ } -+ -+ // NDN cache ratio -+ if (ndncachehit > 89) { -+ ndnChartColor = ChartThemeColor.green; -+ } else if (ndncachehit > 74) { -+ ndnChartColor = ChartThemeColor.orange; -+ } else { -+ ndnChartColor = ChartThemeColor.purple; -+ } -+ // NDN cache utilization -+ if (utilratio > 95) { -+ ndnUtilColor = ChartThemeColor.purple; -+ } else if (utilratio > 90) { -+ ndnUtilColor = ChartThemeColor.orange; -+ } else { -+ ndnUtilColor = ChartThemeColor.green; -+ } -+ -+ content = ( -+ -+ {_("Normalized DN Cache")}}> -+
-+ -+ -+ -+ -+
-+
-+ -+ -+ {_("Cache Hit Ratio")} -+ -+ -+ -+ -+ {ndncachehit}% -+ -+ -+
-+
-+ `${datum.name}: ${datum.y}`} constrainToVisibleArea />} -+ height={200} -+ maxDomain={{ y: 100 }} -+ minDomain={{ y: 0 }} -+ padding={{ -+ bottom: 40, -+ left: 60, -+ top: 10, -+ right: 15, -+ }} -+ width={350} -+ themeColor={ndnChartColor} -+ > -+ -+ -+ -+ -+ -+ -+
-
--
-- `${datum.name}: ${datum.y}`} constrainToVisibleArea />} -- height={200} -- maxDomain={{ y: 100 }} -- minDomain={{ y: 0 }} -- padding={{ -- bottom: 40, -- left: 60, -- top: 10, -- right: 15, -- }} -- width={350} -- themeColor={ndnUtilColor} -- > -- -- -- -- -- -- -+ -+ -+ -+ -+ -+ -+
-+
-+ -+ -+ {_("Cache Utilization")} -+ -+ -+ -+ -+ {utilratio}% -+ -+ -+ -+ -+ {_("Cached DN's")} -+ -+ -+ {numToCommas(this.state.data.currentnormalizeddncachecount[0])} -+
-+
-+ `${datum.name}: ${datum.y}`} constrainToVisibleArea />} -+ height={200} -+ maxDomain={{ y: 100 }} -+ minDomain={{ y: 0 }} -+ padding={{ -+ bottom: 40, -+ left: 60, -+ top: 10, -+ right: 15, -+ }} -+ width={350} -+ themeColor={ndnUtilColor} -+ > -+ -+ -+ -+ -+ -+ -+
-
--
--
--
--
--
-- -- -- -- {_("NDN Cache Hit Ratio:")} -- -- -- {this.state.data.normalizeddncachehitratio}% -- -- -- {_("NDN Cache Max Size:")} -- -- -- {displayBytes(this.state.data.maxnormalizeddncachesize)} -- -- -- {_("NDN Cache Tries:")} -- -- -- {numToCommas(this.state.data.normalizeddncachetries)} -- -- -- {_("NDN Current Cache Size:")} -- -- -- {displayBytes(this.state.data.currentnormalizeddncachesize)} -- -- -- {_("NDN Cache Hits:")} -- -- -- {numToCommas(this.state.data.normalizeddncachehits)} -- -- -- {_("NDN Cache DN Count:")} -- -- -- {numToCommas(this.state.data.currentnormalizeddncachecount)} -- -- -- {_("NDN Cache Evictions:")} -- -- -- {numToCommas(this.state.data.normalizeddncacheevictions)} -- -- -- {_("NDN Cache Thread Size:")} -- -- -- {numToCommas(this.state.data.normalizeddncachethreadsize)} -- -- -- {_("NDN Cache Thread Slots:")} -- -- -- {numToCommas(this.state.data.normalizeddncachethreadslots)} -- -- --
--
--
-- ); -+ -+ -+ -+ -+ -+ -+ -+ {_("NDN Cache Hit Ratio:")} -+ -+ -+ {this.state.data.normalizeddncachehitratio}% -+ -+ -+ {_("NDN Cache Max Size:")} -+ -+ -+ {displayBytes(this.state.data.maxnormalizeddncachesize)} -+ -+ -+ {_("NDN Cache Tries:")} -+ -+ -+ {numToCommas(this.state.data.normalizeddncachetries)} -+ -+ -+ {_("NDN Current Cache Size:")} -+ -+ -+ {displayBytes(this.state.data.currentnormalizeddncachesize)} -+ -+ -+ {_("NDN Cache Hits:")} -+ -+ -+ {numToCommas(this.state.data.normalizeddncachehits)} -+ -+ -+ {_("NDN Cache DN Count:")} -+ -+ -+ {numToCommas(this.state.data.currentnormalizeddncachecount)} -+ -+ -+ {_("NDN Cache Evictions:")} -+ -+ -+ {numToCommas(this.state.data.normalizeddncacheevictions)} -+ -+ -+ {_("NDN Cache Thread Size:")} -+ -+ -+ {numToCommas(this.state.data.normalizeddncachethreadsize)} -+ -+ -+ {_("NDN Cache Thread Slots:")} -+ -+ -+ {numToCommas(this.state.data.normalizeddncachethreadslots)} -+ -+ -+
-+ -+ -+ ); -+ } else { -+ // No NDN cache available -+ content = ( -+
-+ -+ -+ {_("Normalized DN Cache is disabled")} -+ -+ -+
-+ ); -+ } - } - - return ( -diff --git a/src/lib389/lib389/cli_conf/monitor.py b/src/lib389/lib389/cli_conf/monitor.py -index b01796549..c7f9322d1 100644 ---- a/src/lib389/lib389/cli_conf/monitor.py -+++ b/src/lib389/lib389/cli_conf/monitor.py -@@ -129,6 +129,14 @@ def db_monitor(inst, basedn, log, args): - # Gather the global DB stats - report_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") - ldbm_mon = ldbm_monitor.get_status() -+ ndn_cache_enabled = inst.config.get_attr_val_utf8('nsslapd-ndn-cache-enabled') == 'on' -+ -+ # Build global cache stats -+ result = { -+ 'date': report_time, -+ 'backends': {}, -+ } -+ - if ldbm_monitor.inst_db_impl == DB_IMPL_BDB: - dbcachesize = int(ldbm_mon['nsslapd-db-cache-size-bytes'][0]) - # Warning: there are two different page sizes associated with bdb: -@@ -153,32 +161,6 @@ def db_monitor(inst, basedn, log, args): - dbcachefree = max(int(dbcachesize - (pagesize * dbpages)), 0) - dbcachefreeratio = dbcachefree/dbcachesize - -- ndnratio = ldbm_mon['normalizeddncachehitratio'][0] -- ndncursize = int(ldbm_mon['currentnormalizeddncachesize'][0]) -- ndnmaxsize = int(ldbm_mon['maxnormalizeddncachesize'][0]) -- ndncount = ldbm_mon['currentnormalizeddncachecount'][0] -- ndnevictions = ldbm_mon['normalizeddncacheevictions'][0] -- if ndncursize > ndnmaxsize: -- ndnfree = 0 -- ndnfreeratio = 0 -- else: -- ndnfree = ndnmaxsize - ndncursize -- ndnfreeratio = "{:.1f}".format(ndnfree / ndnmaxsize * 100) -- -- # Build global cache stats -- result = { -- 'date': report_time, -- 'ndncache': { -- 'hit_ratio': ndnratio, -- 'free': convert_bytes(str(ndnfree)), -- 'free_percentage': ndnfreeratio, -- 'count': ndncount, -- 'evictions': ndnevictions -- }, -- 'backends': {}, -- } -- -- if ldbm_monitor.inst_db_impl == DB_IMPL_BDB: - result['dbcache'] = { - 'hit_ratio': dbhitratio, - 'free': convert_bytes(str(dbcachefree)), -@@ -188,6 +170,32 @@ def db_monitor(inst, basedn, log, args): - 'pageout': dbcachepageout - } - -+ # Add NDN cache stats only if enabled -+ if ndn_cache_enabled: -+ try: -+ ndnratio = ldbm_mon['normalizeddncachehitratio'][0] -+ ndncursize = int(ldbm_mon['currentnormalizeddncachesize'][0]) -+ ndnmaxsize = int(ldbm_mon['maxnormalizeddncachesize'][0]) -+ ndncount = ldbm_mon['currentnormalizeddncachecount'][0] -+ ndnevictions = ldbm_mon['normalizeddncacheevictions'][0] -+ if ndncursize > ndnmaxsize: -+ ndnfree = 0 -+ ndnfreeratio = 0 -+ else: -+ ndnfree = ndnmaxsize - ndncursize -+ ndnfreeratio = "{:.1f}".format(ndnfree / ndnmaxsize * 100) -+ -+ result['ndncache'] = { -+ 'hit_ratio': ndnratio, -+ 'free': convert_bytes(str(ndnfree)), -+ 'free_percentage': ndnfreeratio, -+ 'count': ndncount, -+ 'evictions': ndnevictions -+ } -+ # In case, the user enabled NDN cache but still have not restarted the instance -+ except IndexError: -+ ndn_cache_enabled = False -+ - # Build the backend results - for be in backend_objs: - be_name = be.rdn -@@ -277,13 +285,16 @@ def db_monitor(inst, basedn, log, args): - log.info(" - Pages In: {}".format(result['dbcache']['pagein'])) - log.info(" - Pages Out: {}".format(result['dbcache']['pageout'])) - log.info("") -- log.info("Normalized DN Cache:") -- log.info(" - Cache Hit Ratio: {}%".format(result['ndncache']['hit_ratio'])) -- log.info(" - Free Space: {}".format(result['ndncache']['free'])) -- log.info(" - Free Percentage: {}%".format(result['ndncache']['free_percentage'])) -- log.info(" - DN Count: {}".format(result['ndncache']['count'])) -- log.info(" - Evictions: {}".format(result['ndncache']['evictions'])) -- log.info("") -+ -+ if ndn_cache_enabled: -+ log.info("Normalized DN Cache:") -+ log.info(" - Cache Hit Ratio: {}%".format(result['ndncache']['hit_ratio'])) -+ log.info(" - Free Space: {}".format(result['ndncache']['free'])) -+ log.info(" - Free Percentage: {}%".format(result['ndncache']['free_percentage'])) -+ log.info(" - DN Count: {}".format(result['ndncache']['count'])) -+ log.info(" - Evictions: {}".format(result['ndncache']['evictions'])) -+ log.info("") -+ - log.info("Backends:") - for be_name, attr_dict in result['backends'].items(): - log.info(f" - {attr_dict['suffix']} ({be_name}):") --- -2.49.0 - diff --git a/0006-Issue-6854-Refactor-for-improved-data-management-685.patch b/0006-Issue-6854-Refactor-for-improved-data-management-685.patch deleted file mode 100644 index 9192e5a..0000000 --- a/0006-Issue-6854-Refactor-for-improved-data-management-685.patch +++ /dev/null @@ -1,2237 +0,0 @@ -From b975dfa3be2a9a5a237dd6383fedaed971893e27 Mon Sep 17 00:00:00 2001 -From: James Chapman -Date: Fri, 11 Jul 2025 10:16:13 +0000 -Subject: [PATCH] Issue 6854 - Refactor for improved data management (#6855) - -Description: Replaced standard dictionaries with defaultdict and -introduced @dataclass structures to streamline data handling. -Improved reliability and readability by reducing explicit key -checks and default initialisation logic. Simplified nested -structure management and ensured consistency across components -such as ResultData, BindData, and ConnectionData. - -Fixes: https://github.com/389ds/389-ds-base/issues/6854 - -Reviewed by: @mreynolds389 (Thank you) ---- - ldap/admin/src/logconv.py | 1307 ++++++++++++++++++++----------------- - 1 file changed, 698 insertions(+), 609 deletions(-) - -diff --git a/ldap/admin/src/logconv.py b/ldap/admin/src/logconv.py -index f4495ca35..162447b4d 100755 ---- a/ldap/admin/src/logconv.py -+++ b/ldap/admin/src/logconv.py -@@ -16,11 +16,11 @@ import argparse - import logging - import sys - import csv -+from collections import defaultdict, Counter - from datetime import datetime, timedelta, timezone -+from dataclasses import dataclass, field - import heapq --from collections import Counter --from collections import defaultdict --from typing import Optional -+from typing import Optional, Dict, List, Set, Tuple, DefaultDict - import magic - - # Globals -@@ -159,9 +159,191 @@ SCOPE_LABEL = { - - STLS_OID = '1.3.6.1.4.1.1466.20037' - --# Version --logAnalyzerVersion = "8.3" -+logAnalyzerVersion = "8.4" - -+@dataclass -+class VLVData: -+ counters: Dict[str, int] = field(default_factory=lambda: defaultdict( -+ int, -+ { -+ 'vlv': 0 -+ } -+ )) -+ -+ rst_con_op_map: Dict = field(default_factory=lambda: defaultdict(dict)) -+ -+@dataclass -+class ServerData: -+ counters: Dict[str, int] = field(default_factory=lambda: defaultdict( -+ int, -+ { -+ 'restart': 0, -+ 'lines_parsed': 0 -+ } -+ )) -+ -+ first_time: Optional[str] = None -+ last_time: Optional[str] = None -+ parse_start_time: Optional[str] = None -+ parse_stop_time: Optional[str] = None -+ -+@dataclass -+class OperationData: -+ counters: DefaultDict[str, int] = field(default_factory=lambda: defaultdict( -+ int, -+ { -+ 'add': 0, -+ 'mod': 0, -+ 'del': 0, -+ 'modrdn': 0, -+ 'cmp': 0, -+ 'abandon': 0, -+ 'sort': 0, -+ 'internal': 0, -+ 'extnd': 0, -+ 'authzid': 0, -+ 'total': 0 -+ } -+ )) -+ -+ rst_con_op_map: DefaultDict[str, DefaultDict[str, int]] = field( -+ default_factory=lambda: defaultdict(lambda: defaultdict(int)) -+ ) -+ -+ extended: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) -+ -+@dataclass -+class ConnectionData: -+ counters: DefaultDict[str, int] = field(default_factory=lambda: defaultdict( -+ int, -+ { -+ 'conn': 0, -+ 'fd_taken': 0, -+ 'fd_returned': 0, -+ 'fd_max': 0, -+ 'sim_conn': 0, -+ 'max_sim_conn': 0, -+ 'ldap': 0, -+ 'ldapi': 0, -+ 'ldaps': 0 -+ } -+ )) -+ -+ start_time: DefaultDict[str, str] = field(default_factory=lambda: defaultdict(str)) -+ open_conns: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) -+ exclude_ip: DefaultDict[Tuple[str, str], str] = field(default_factory=lambda: defaultdict(str)) -+ -+ broken_pipe: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) -+ resource_unavail: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) -+ connection_reset: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) -+ disconnect_code: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) -+ -+ restart_conn_disconnect_map: DefaultDict[Tuple[int, str], int] = field(default_factory=lambda: defaultdict(int)) -+ restart_conn_ip_map: Dict[Tuple[int, str], str] = field(default_factory=dict) -+ -+ src_ip_map: DefaultDict[str, DefaultDict[str, object]] = field( -+ default_factory=lambda: defaultdict(lambda: defaultdict(object)) -+ ) -+ -+@dataclass -+class BindData: -+ counters: DefaultDict[str, int] = field(default_factory=lambda: defaultdict( -+ int, -+ { -+ 'bind': 0, -+ 'unbind': 0, -+ 'sasl': 0, -+ 'anon': 0, -+ 'autobind': 0, -+ 'rootdn': 0 -+ } -+ )) -+ -+ restart_conn_dn_map: Dict[Tuple[int, str], str] = field(default_factory=dict) -+ -+ version: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) -+ dns: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) -+ sasl_mech: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) -+ conn_op_sasl_mech_map: DefaultDict[str, str] = field(default_factory=lambda: defaultdict(str)) -+ root_dn: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) -+ -+ report_dn: DefaultDict[str, Dict[str, Set[str]]] = field( -+ default_factory=lambda: defaultdict( -+ lambda: { -+ 'conn': set(), -+ 'ips': set() -+ } -+ ) -+ ) -+ -+@dataclass -+class ResultData: -+ counters: DefaultDict[str, int] = field(default_factory=lambda: defaultdict( -+ int, { -+ 'result': 0, -+ 'notesA': 0, -+ 'notesF': 0, -+ 'notesM': 0, -+ 'notesP': 0, -+ 'notesU': 0, -+ 'timestamp': 0, -+ 'entry': 0, -+ 'referral': 0 -+ } -+ )) -+ -+ notes: DefaultDict[str, Dict] = field(default_factory=lambda: defaultdict(dict)) -+ -+ timestamp_ctr: int = 0 -+ entry_count: int = 0 -+ referral_count: int = 0 -+ -+ total_etime: float = 0.0 -+ total_wtime: float = 0.0 -+ total_optime: float = 0.0 -+ etime_stat: float = 0.0 -+ -+ etime_duration: List[float] = field(default_factory=list) -+ wtime_duration: List[float] = field(default_factory=list) -+ optime_duration: List[float] = field(default_factory=list) -+ -+ nentries_num: List[int] = field(default_factory=list) -+ nentries_set: Set[int] = field(default_factory=set) -+ -+ error_freq: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) -+ bad_pwd_map: Dict[str, int] = field(default_factory=dict) -+ -+@dataclass -+class SearchData: -+ counters: Dict[str, int] = field(default_factory=lambda: defaultdict( -+ int, -+ { -+ 'search': 0, -+ 'base_search': 0, -+ 'persistent': 0 -+ } -+ )) -+ attrs: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) -+ bases: DefaultDict[str, int] = field(default_factory=lambda: defaultdict(int)) -+ -+ base_rst_con_op_map: Dict[Tuple[int, str, str], str] = field(default_factory=dict) -+ scope_rst_con_op_map: Dict[Tuple[int, str, str], str] = field(default_factory=dict) -+ -+ filter_dict: Dict[str, int] = field(default_factory=dict) -+ filter_list: List[str] = field(default_factory=list) -+ filter_rst_con_op_map: Dict[Tuple[int, str, str], str] = field(default_factory=dict) -+ -+@dataclass -+class AuthData: -+ counters: Dict[str, int] = field(default_factory=lambda: defaultdict( -+ int, -+ { -+ 'ssl_client_bind_ctr': 0, -+ 'ssl_client_bind_failed_ctr': 0, -+ 'cipher_ctr': 0 -+ } -+ )) -+ auth_info: DefaultDict[str, str] = field(default_factory=lambda: defaultdict(str)) - - class logAnalyser: - """ -@@ -272,136 +454,14 @@ class logAnalyser: - self.notesP = {} - self.notesU = {} - -- self.vlv = { -- 'vlv_ctr': 0, -- 'vlv_map_rco': {} -- } -- -- self.server = { -- 'restart_ctr': 0, -- 'first_time': None, -- 'last_time': None, -- 'parse_start_time': None, -- 'parse_stop_time': None, -- 'lines_parsed': 0 -- } -- -- self.operation = { -- 'all_op_ctr': 0, -- 'add_op_ctr': 0, -- 'mod_op_ctr': 0, -- 'del_op_ctr': 0, -- 'modrdn_op_ctr': 0, -- 'cmp_op_ctr': 0, -- 'abandon_op_ctr': 0, -- 'sort_op_ctr': 0, -- 'extnd_op_ctr': 0, -- 'add_map_rco': {}, -- 'mod_map_rco': {}, -- 'del_map_rco': {}, -- 'cmp_map_rco': {}, -- 'modrdn_map_rco': {}, -- 'extop_dict': {}, -- 'extop_map_rco': {}, -- 'abandoned_map_rco': {} -- } -- -- self.connection = { -- 'conn_ctr': 0, -- 'fd_taken_ctr': 0, -- 'fd_returned_ctr': 0, -- 'fd_max_ctr': 0, -- 'sim_conn_ctr': 0, -- 'max_sim_conn_ctr': 0, -- 'ldap_ctr': 0, -- 'ldapi_ctr': 0, -- 'ldaps_ctr': 0, -- 'start_time': {}, -- 'open_conns': {}, -- 'exclude_ip_map': {}, -- 'broken_pipe': {}, -- 'resource_unavail': {}, -- 'connection_reset': {}, -- 'disconnect_code': {}, -- 'disconnect_code_map': {}, -- 'ip_map': {}, -- 'restart_conn_ip_map': {} -- } -- -- self.bind = { -- 'bind_ctr': 0, -- 'unbind_ctr': 0, -- 'sasl_bind_ctr': 0, -- 'anon_bind_ctr': 0, -- 'autobind_ctr': 0, -- 'rootdn_bind_ctr': 0, -- 'version': {}, -- 'dn_freq': {}, -- 'dn_map_rc': {}, -- 'sasl_mech_freq': {}, -- 'sasl_map_co': {}, -- 'root_dn': {}, -- 'report_dn': defaultdict(lambda: defaultdict(int, conn=set(), ips=set())) -- } -- -- self.result = { -- 'result_ctr': 0, -- 'notesA_ctr': 0, # dynamically referenced -- 'notesF_ctr': 0, # dynamically referenced -- 'notesM_ctr': 0, # dynamically referenced -- 'notesP_ctr': 0, # dynamically referenced -- 'notesU_ctr': 0, # dynamically referenced -- 'timestamp_ctr': 0, -- 'entry_count': 0, -- 'referral_count': 0, -- 'total_etime': 0.0, -- 'total_wtime': 0.0, -- 'total_optime': 0.0, -- 'notesA_map': {}, -- 'notesF_map': {}, -- 'notesM_map': {}, -- 'notesP_map': {}, -- 'notesU_map': {}, -- 'etime_stat': 0.0, -- 'etime_counts': defaultdict(int), -- 'etime_freq': [], -- 'etime_duration': [], -- 'wtime_counts': defaultdict(int), -- 'wtime_freq': [], -- 'wtime_duration': [], -- 'optime_counts': defaultdict(int), -- 'optime_freq': [], -- 'optime_duration': [], -- 'nentries_dict': defaultdict(int), -- 'nentries_num': [], -- 'nentries_set': set(), -- 'nentries_returned': [], -- 'error_freq': defaultdict(str), -- 'bad_pwd_map': {} -- } -- -- self.search = { -- 'search_ctr': 0, -- 'search_map_rco': {}, -- 'attr_dict': defaultdict(int), -- 'base_search_ctr': 0, -- 'base_map': {}, -- 'base_map_rco': {}, -- 'scope_map_rco': {}, -- 'filter_dict': {}, -- 'filter_list': [], -- 'filter_seen': set(), -- 'filter_counter': Counter(), -- 'filter_map_rco': {}, -- 'persistent_ctr': 0 -- } -- -- self.auth = { -- 'ssl_client_bind_ctr': 0, -- 'ssl_client_bind_failed_ctr': 0, -- 'cipher_ctr': 0, -- 'auth_info': {} -- } -+ self.vlv = VLVData() -+ self.server = ServerData() -+ self.operation = OperationData() -+ self.connection = ConnectionData() -+ self.bind = BindData() -+ self.result = ResultData() -+ self.search = SearchData() -+ self.auth = AuthData() - - def _init_regexes(self): - """ -@@ -564,22 +624,22 @@ class logAnalyser: - """ - print("\nBind Report") - print("====================================================================\n") -- for k, v in self.bind['report_dn'].items(): -+ for k, v in self.bind.report_dn.items(): - print(f"\nBind DN: {k}") - print("--------------------------------------------------------------------\n") - print(" Client Addresses:\n") -- ips = self.bind['report_dn'][k].get('ips', set()) -+ ips = self.bind.report_dn[k].get('ips', set()) - for i, ip in enumerate(ips, start=1): - print(f" {i}: {ip}") - print("\n Operations Performed:\n") -- print(f" Binds: {self.bind['report_dn'][k].get('bind', 0)}") -- print(f" Searches: {self.bind['report_dn'][k].get('srch', 0)}") -- print(f" Modifies: {self.bind['report_dn'][k].get('mod', 0)}") -- print(f" Adds: {self.bind['report_dn'][k].get('add', 0)}") -- print(f" Deletes: {self.bind['report_dn'][k].get('del', 0)}") -- print(f" Compares: {self.bind['report_dn'][k].get('cmp', 0)}") -- print(f" ModRDNs: {self.bind['report_dn'][k].get('modrdn', 0)}") -- print(f" Ext Ops: {self.bind['report_dn'][k].get('ext', 0)}") -+ print(f" Binds: {self.bind.report_dn[k].get('bind', 0)}") -+ print(f" Searches: {self.bind.report_dn[k].get('srch', 0)}") -+ print(f" Modifies: {self.bind.report_dn[k].get('mod', 0)}") -+ print(f" Adds: {self.bind.report_dn[k].get('add', 0)}") -+ print(f" Deletes: {self.bind.report_dn[k].get('del', 0)}") -+ print(f" Compares: {self.bind.report_dn[k].get('cmp', 0)}") -+ print(f" ModRDNs: {self.bind.report_dn[k].get('modrdn', 0)}") -+ print(f" Ext Ops: {self.bind.report_dn[k].get('ext', 0)}") - - print("Done.") - -@@ -618,12 +678,9 @@ class logAnalyser: - self.logger.error(f"Converting timestamp: {timestamp} to datetime failed with: {e}") - return False - -- # Add server restart count to groups for connection tracking -- groups['restart_ctr'] = self.server.get('restart_ctr', 0) -- - # Are there time range restrictions -- parse_start = self.server.get('parse_start_time', None) -- parse_stop = self.server.get('parse_stop_time', None) -+ parse_start = self.server.parse_start_time -+ parse_stop = self.server.parse_stop_time - - if parse_start and parse_stop: - if parse_start.microsecond == 0 and parse_stop.microsecond == 0: -@@ -634,12 +691,12 @@ class logAnalyser: - return False - - # Get the first and last timestamps -- if self.server.get('first_time') is None: -- self.server['first_time'] = timestamp -- self.server['last_time'] = timestamp -+ if self.server.first_time is None: -+ self.server.first_time = timestamp -+ self.server.last_time = timestamp - - # Bump lines parsed -- self.server['lines_parsed'] = self.server.get('lines_parsed', 0) + 1 -+ self.server.counters['lines_parsed'] += 1 - - # Call the associated method for this match - action(groups) -@@ -658,16 +715,11 @@ class logAnalyser: - """ - Process and update statistics based on the parsed result group. - -- Args: -- groups (dict): Parsed groups from the log line. -- -- - Args: - groups (dict): A dictionary containing operation information. Expected keys: - - 'timestamp': The timestamp of the connection event. - - 'conn_id': Connection identifier. - - 'op_id': Operation identifier. -- - 'restart_ctr': Server restart count. - - 'etime': Result elapsed time. - - 'wtime': Result wait time. - - 'optime': Result operation time. -@@ -679,182 +731,173 @@ class logAnalyser: - Raises: - KeyError: If required keys are missing in the `groups` dictionary. - """ -+ self.logger.debug(f"_process_result_stats - Start - {groups}") -+ - try: - timestamp = groups.get('timestamp') - conn_id = groups.get('conn_id') - op_id = groups.get('op_id') -- restart_ctr = groups.get('restart_ctr') - etime = float(groups.get('etime')) - wtime = float(groups.get('wtime')) - optime = float(groups.get('optime')) -+ nentries = int(groups.get('nentries')) - tag = groups.get('tag') - err = groups.get('err') -- nentries = int(groups.get('nentries')) - internal = groups.get('internal') -+ notes = groups.get('notes') - except KeyError as e: - self.logger.error(f"Missing key in groups: {e}") - return - - # Mapping keys for this entry -+ restart_ctr = self.server.counters['restart'] - restart_conn_op_key = (restart_ctr, conn_id, op_id) - restart_conn_key = (restart_ctr, conn_id) - conn_op_key = (conn_id, op_id) - - # Should we ignore this operation -- if restart_conn_key in self.connection['exclude_ip_map']: -+ if restart_conn_key in self.connection.exclude_ip: - return None - -- # Bump global result count -- self.result['result_ctr'] = self.result.get('result_ctr', 0) + 1 -- -- # Bump global result count -- self.result['timestamp_ctr'] = self.result.get('timestamp_ctr', 0) + 1 -+ self.result.counters['result'] += 1 -+ self.result.counters['timestamp'] += 1 - - # Longest etime, push current etime onto the heap -- heapq.heappush(self.result['etime_duration'], float(etime)) -+ heapq.heappush(self.result.etime_duration, etime) - - # If the heap exceeds size_limit, pop the smallest element from root -- if len(self.result['etime_duration']) > self.size_limit: -- heapq.heappop(self.result['etime_duration']) -+ if len(self.result.etime_duration) > self.size_limit: -+ heapq.heappop(self.result.etime_duration) - - # Longest wtime, push current wtime onto the heap -- heapq.heappush(self.result['wtime_duration'], float(wtime)) -+ heapq.heappush(self.result.wtime_duration, wtime) - - # If the heap exceeds size_limit, pop the smallest element from root -- if len(self.result['wtime_duration']) > self.size_limit: -- heapq.heappop(self.result['wtime_duration']) -+ if len(self.result.wtime_duration) > self.size_limit: -+ heapq.heappop(self.result.wtime_duration) - - # Longest optime, push current optime onto the heap -- heapq.heappush(self.result['optime_duration'], float(optime)) -+ heapq.heappush(self.result.optime_duration, optime) - - # If the heap exceeds size_limit, pop the smallest element from root -- if len(self.result['optime_duration']) > self.size_limit: -- heapq.heappop(self.result['optime_duration']) -+ if len(self.result.optime_duration) > self.size_limit: -+ heapq.heappop(self.result.optime_duration) - - # Total result times -- self.result['total_etime'] = self.result.get('total_etime', 0) + float(etime) -- self.result['total_wtime'] = self.result.get('total_wtime', 0) + float(wtime) -- self.result['total_optime'] = self.result.get('total_optime', 0) + float(optime) -+ self.result.total_etime = self.result.total_etime + etime -+ self.result.total_wtime = self.result.total_wtime + wtime -+ self.result.total_optime = self.result.total_optime + optime - - # Statistic reporting -- self.result['etime_stat'] = round(self.result['etime_stat'] + float(etime), 8) -+ self.result.etime_stat = round(self.result.etime_stat + float(etime), 8) - -- if err: -- # Capture error code -- self.result['error_freq'][err] = self.result['error_freq'].get(err, 0) + 1 -+ if err is not None: -+ self.result.error_freq[err] += 1 - - # Check for internal operations based on either conn_id or internal flag - if 'Internal' in conn_id or internal: -- self.server['internal_op_ctr'] = self.server.get('internal_op_ctr', 0) + 1 -+ self.operation.counters['internal'] +=1 - - # Process result notes if present -- notes = groups['notes'] -- if notes is not None: -- # match.group('notes') can be A|U|F -- self.result[f'notes{notes}_ctr'] = self.result.get(f'notes{notes}_ctr', 0) + 1 -- # Track result times using server restart count, conn id and op_id as key -- self.result[f'notes{notes}_map'][restart_conn_op_key] = restart_conn_op_key -- -- # Construct the notes dict -- note_dict = getattr(self, f'notes{notes}') -+ NOTE_TYPES = {'A', 'U', 'F', 'M', 'P'} -+ if notes in NOTE_TYPES: -+ note_dict = self.result.notes[notes] -+ self.result.counters[f'notes{notes}'] += 1 - - # Exclude VLV -- if restart_conn_op_key not in self.vlv['vlv_map_rco']: -- if restart_conn_op_key in note_dict: -- note_dict[restart_conn_op_key]['time'] = timestamp -- else: -- # First time round -- note_dict[restart_conn_op_key] = {'time': timestamp} -- -- note_dict[restart_conn_op_key]['etime'] = etime -- note_dict[restart_conn_op_key]['nentries'] = nentries -- note_dict[restart_conn_op_key]['ip'] = ( -- self.connection['restart_conn_ip_map'].get(restart_conn_key, '') -- ) -- -- if restart_conn_op_key in self.search['base_map_rco']: -- note_dict[restart_conn_op_key]['base'] = self.search['base_map_rco'][restart_conn_op_key] -- del self.search['base_map_rco'][restart_conn_op_key] -- -- if restart_conn_op_key in self.search['scope_map_rco']: -- note_dict[restart_conn_op_key]['scope'] = self.search['scope_map_rco'][restart_conn_op_key] -- del self.search['scope_map_rco'][restart_conn_op_key] -- -- if restart_conn_op_key in self.search['filter_map_rco']: -- note_dict[restart_conn_op_key]['filter'] = self.search['filter_map_rco'][restart_conn_op_key] -- del self.search['filter_map_rco'][restart_conn_op_key] -- -- note_dict[restart_conn_op_key]['bind_dn'] = self.bind['dn_map_rc'].get(restart_conn_key, '') -- -- elif restart_conn_op_key in self.vlv['vlv_map_rco']: -- # This "note" result is VLV, assign the note type for later filtering -- self.vlv['vlv_map_rco'][restart_conn_op_key] = notes -+ if restart_conn_op_key not in self.vlv.rst_con_op_map: -+ # Construct the notes dict -+ note_dict = self.result.notes[notes] -+ note_entry = note_dict.setdefault(restart_conn_op_key, {}) -+ note_entry.update({ -+ 'time': timestamp, -+ 'etime': etime, -+ 'nentries': nentries, -+ 'ip': self.connection.restart_conn_ip_map.get(restart_conn_key, 'Unknown IP'), -+ 'bind_dn': self.bind.restart_conn_dn_map.get(restart_conn_key, 'Unknown DN') -+ }) -+ -+ if restart_conn_op_key in self.search.base_rst_con_op_map: -+ note_dict[restart_conn_op_key]['base'] = self.search.base_rst_con_op_map[restart_conn_op_key] -+ del self.search.base_rst_con_op_map[restart_conn_op_key] -+ -+ if restart_conn_op_key in self.search.scope_rst_con_op_map: -+ note_dict[restart_conn_op_key]['scope'] = self.search.scope_rst_con_op_map[restart_conn_op_key] -+ del self.search.scope_rst_con_op_map[restart_conn_op_key] -+ -+ if restart_conn_op_key in self.search.filter_rst_con_op_map: -+ note_dict[restart_conn_op_key]['filter'] = self.search.filter_rst_con_op_map[restart_conn_op_key] -+ del self.search.filter_rst_con_op_map[restart_conn_op_key] -+ else: -+ self.vlv.rst_con_op_map[restart_conn_op_key] = notes - - # Trim the search data we dont need (not associated with a notes=X) -- if restart_conn_op_key in self.search['base_map_rco']: -- del self.search['base_map_rco'][restart_conn_op_key] -+ if restart_conn_op_key in self.search.base_rst_con_op_map: -+ del self.search.base_rst_con_op_map[restart_conn_op_key] - -- if restart_conn_op_key in self.search['scope_map_rco']: -- del self.search['scope_map_rco'][restart_conn_op_key] -+ if restart_conn_op_key in self.search.scope_rst_con_op_map: -+ del self.search.scope_rst_con_op_map[restart_conn_op_key] - -- if restart_conn_op_key in self.search['filter_map_rco']: -- del self.search['filter_map_rco'][restart_conn_op_key] -+ if restart_conn_op_key in self.search.filter_rst_con_op_map: -+ del self.search.filter_rst_con_op_map[restart_conn_op_key] - - # Process bind response based on the tag and error code. - if tag == '97': - # Invalid credentials|Entry does not exist - if err == '49': - # if self.verbose: -- bad_pwd_dn = self.bind['dn_map_rc'].get(restart_conn_key, None) -- bad_pwd_ip = self.connection['restart_conn_ip_map'].get(restart_conn_key, None) -- self.result['bad_pwd_map'][(bad_pwd_dn, bad_pwd_ip)] = ( -- self.result['bad_pwd_map'].get((bad_pwd_dn, bad_pwd_ip), 0) + 1 -+ bad_pwd_dn = self.bind.restart_conn_dn_map[restart_conn_key] -+ bad_pwd_ip = self.connection.restart_conn_ip_map.get(restart_conn_key, None) -+ self.result.bad_pwd_map[(bad_pwd_dn, bad_pwd_ip)] = ( -+ self.result.bad_pwd_map.get((bad_pwd_dn, bad_pwd_ip), 0) + 1 - ) - # Trim items to size_limit -- if len(self.result['bad_pwd_map']) > self.size_limit: -+ if len(self.result.bad_pwd_map) > self.size_limit: - within_size_limit = dict( - sorted( -- self.result['bad_pwd_map'].items(), -+ self.result.bad_pwd_map.items(), - key=lambda item: item[1], - reverse=True - )[:self.size_limit]) -- self.result['bad_pwd_map'] = within_size_limit -+ self.result.bad_pwd_map = within_size_limit - - # Ths result is involved in the SASL bind process, decrement bind count, etc - elif err == '14': -- self.bind['bind_ctr'] = self.bind.get('bind_ctr', 0) - 1 -- self.operation['all_op_ctr'] = self.operation.get('all_op_ctr', 0) - 1 -- self.bind['sasl_bind_ctr'] = self.bind.get('sasl_bind_ctr', 0) - 1 -- self.bind['version']['3'] = self.bind['version'].get('3', 0) - 1 -+ self.bind.counters['bind'] -= 1 -+ self.operation.counters['total'] -= 1 -+ self.bind.counters['sasl'] -= 1 -+ self.bind.version['3'] = self.bind.version.get('3', 0) - 1 - - # Drop the sasl mech count also -- mech = self.bind['sasl_map_co'].get(conn_op_key, 0) -+ mech = self.bind.conn_op_sasl_mech_map[conn_op_key] - if mech: -- self.bind['sasl_mech_freq'][mech] = self.bind['sasl_mech_freq'].get(mech, 0) - 1 -+ self.bind.sasl_mech[mech] -= 1 - # Is this is a result to a sasl bind - else: - result_dn = groups['dn'] - if result_dn: - if result_dn != "": - # If this is a result of a sasl bind, grab the dn -- if conn_op_key in self.bind['sasl_map_co']: -+ if conn_op_key in self.bind.conn_op_sasl_mech_map: - if result_dn is not None: -- self.bind['dn_map_rc'][restart_conn_key] = result_dn.lower() -- self.bind['dn_freq'][result_dn] = ( -- self.bind['dn_freq'].get(result_dn, 0) + 1 -+ self.bind.restart_conn_dn_map[restart_conn_key] = result_dn.lower() -+ self.bind.dns[result_dn] = ( -+ self.bind.dns.get(result_dn, 0) + 1 - ) - # Handle other tag values - elif tag in ['100', '101', '111', '115']: - - # Largest nentry, push current nentry onto the heap, no duplicates -- if int(nentries) not in self.result['nentries_set']: -- heapq.heappush(self.result['nentries_num'], int(nentries)) -- self.result['nentries_set'].add(int(nentries)) -+ if int(nentries) not in self.result.nentries_set: -+ heapq.heappush(self.result.nentries_num, int(nentries)) -+ self.result.nentries_set.add(int(nentries)) - - # If the heap exceeds size_limit, pop the smallest element from root -- if len(self.result['nentries_num']) > self.size_limit: -- removed = heapq.heappop(self.result['nentries_num']) -- self.result['nentries_set'].remove(removed) -+ if len(self.result.nentries_num) > self.size_limit: -+ removed = heapq.heappop(self.result.nentries_num) -+ self.result.nentries_set.remove(removed) -+ -+ self.logger.debug(f"_process_result_stats - End") - - def _process_search_stats(self, groups: dict): - """ -@@ -873,10 +916,11 @@ class logAnalyser: - Raises: - KeyError: If required keys are missing in the `groups` dictionary. - """ -+ self.logger.debug(f"_process_search_stats - Start - {groups}") -+ - try: - conn_id = groups.get('conn_id') - op_id = groups.get('op_id') -- restart_ctr = groups.get('restart_ctr') - search_base = groups['search_base'] - search_scope = groups['search_scope'] - search_attrs = groups['search_attrs'] -@@ -886,33 +930,34 @@ class logAnalyser: - return - - # Create a tracking keys for this entry -+ restart_ctr = self.server.counters['restart'] - restart_conn_op_key = (restart_ctr, conn_id, op_id) - restart_conn_key = (restart_ctr, conn_id) - - # Should we ignore this operation -- if restart_conn_key in self.connection['exclude_ip_map']: -+ if restart_conn_key in self.connection.exclude_ip: - return None - - # Bump search and global op count -- self.search['search_ctr'] = self.search.get('search_ctr', 0) + 1 -- self.operation['all_op_ctr'] = self.operation.get('all_op_ctr', 0) + 1 -+ self.search.counters['search'] += 1 -+ self.operation.counters['total'] += 1 - - # Search attributes - if search_attrs is not None: - if search_attrs == 'ALL': -- self.search['attr_dict']['All Attributes'] += 1 -+ self.search.attrs['All Attributes'] += 1 - else: - for attr in search_attrs.split(): - attr = attr.strip('"') -- self.search['attr_dict'][attr] += 1 -+ self.search.attrs[attr] += 1 - - # If the associated conn id for the bind DN matches update op counter -- for dn in self.bind['report_dn']: -- conns = self.bind['report_dn'][dn]['conn'] -+ for dn in self.bind.report_dn: -+ conns = self.bind.report_dn[dn]['conn'] - if conn_id in conns: - bind_dn_key = self._report_dn_key(dn, self.report_dn) - if bind_dn_key: -- self.bind['report_dn'][bind_dn_key]['srch'] = self.bind['report_dn'][bind_dn_key].get('srch', 0) + 1 -+ self.bind.report_dn[bind_dn_key]['srch'] = self.bind.report_dn[bind_dn_key].get('srch', 0) + 1 - - # Search base - if search_base is not None: -@@ -924,49 +969,51 @@ class logAnalyser: - search_base = base.lower() - if search_base: - if self.verbose: -- self.search['base_map'][search_base] = self.search['base_map'].get(search_base, 0) + 1 -- self.search['base_map_rco'][restart_conn_op_key] = search_base -+ self.search.bases[search_base] += 1#self.search.bases.get(search_base, 0) + 1 -+ self.search.base_rst_con_op_map[restart_conn_op_key] = search_base - - # Search scope - if search_scope is not None: - if self.verbose: -- self.search['scope_map_rco'][restart_conn_op_key] = SCOPE_LABEL[int(search_scope)] -+ self.search.scope_rst_con_op_map[restart_conn_op_key] = SCOPE_LABEL[int(search_scope)] - - # Search filter - if search_filter is not None: - if self.verbose: -- self.search['filter_map_rco'][restart_conn_op_key] = search_filter -- self.search['filter_dict'][search_filter] = self.search['filter_dict'].get(search_filter, 0) + 1 -+ self.search.filter_rst_con_op_map[restart_conn_op_key] = search_filter -+ self.search.filter_dict[search_filter] = self.search.filter_dict.get(search_filter, 0) + 1 - - found = False -- for idx, (count, filter) in enumerate(self.search['filter_list']): -+ for idx, (count, filter) in enumerate(self.search.filter_list): - if filter == search_filter: - found = True -- self.search['filter_list'][idx] = (self.search['filter_dict'][search_filter] + 1, search_filter) -- heapq.heapify(self.search['filter_list']) -+ self.search.filter_list[idx] = (self.search.filter_dict[search_filter] + 1, search_filter) -+ heapq.heapify(self.search.filter_list) - break - - if not found: -- if len(self.search['filter_list']) < self.size_limit: -- heapq.heappush(self.search['filter_list'], (1, search_filter)) -+ if len(self.search.filter_list) < self.size_limit: -+ heapq.heappush(self.search.filter_list, (1, search_filter)) - else: -- heapq.heappushpop(self.search['filter_list'], (self.search['filter_dict'][search_filter], search_filter)) -+ heapq.heappushpop(self.search.filter_list, (self.search.filter_dict[search_filter], search_filter)) - - # Check for an entire base search - if "objectclass=*" in search_filter.lower() or "objectclass=top" in search_filter.lower(): - if search_scope == '2': -- self.search['base_search_ctr'] = self.search.get('base_search_ctr', 0) + 1 -+ self.search.counters['base_search'] += 1 - - # Persistent search - if groups['options'] is not None: - options = groups['options'] - if options == 'persistent': -- self.search['persistent_ctr'] = self.search.get('persistent_ctr', 0) + 1 -+ self.search.counters['persistent'] += 1 - - # Authorization identity - if groups['authzid_dn'] is not None: - self.search['authzid'] = self.search.get('authzid', 0) + 1 - -+ self.logger.debug(f"_process_search_stats - End") -+ - def _process_bind_stats(self, groups: dict): - """ - Process and update statistics based on the parsed result group. -@@ -975,7 +1022,6 @@ class logAnalyser: - groups (dict): A dictionary containing operation information. Expected keys: - - 'conn_id': Connection identifier. - - 'op_id': Operation identifier. -- - 'restart_ctr': Server restart count. - - 'bind_dn': Bind DN. - - 'bind_method': Bind method (sasl, simple). - - 'bind_version': Bind version. -@@ -983,80 +1029,74 @@ class logAnalyser: - Raises: - KeyError: If required keys are missing in the `groups` dictionary. - """ -+ self.logger.debug(f"_process_bind_stats - Start - {groups}") -+ - try: - conn_id = groups.get('conn_id') - op_id = groups.get('op_id') -- restart_ctr = groups.get('restart_ctr') - bind_dn = groups.get('bind_dn') -- bind_method = groups['bind_method'] -- bind_version = groups['bind_version'] -+ bind_method = groups.get('bind_method') -+ bind_version = groups.get('bind_version') - except KeyError as e: - self.logger.error(f"Missing key in groups: {e}") - return - -- # If this is the first connection (indicating a server restart), increment restart counter -- if conn_id == '1': -- self.server['restart_ctr'] = self.server.get('restart_ctr', 0) + 1 -- - # Create a tracking keys for this entry -+ restart_ctr = self.server.counters['restart'] - restart_conn_key = (restart_ctr, conn_id) - conn_op_key = (conn_id, op_id) - -+ if bind_dn.strip() == '': -+ bind_dn = 'Anonymous' -+ bind_dn_normalised = bind_dn.lower() if bind_dn != 'Anonymous' else 'anonymous' -+ - # Should we ignore this operation -- if restart_conn_key in self.connection['exclude_ip_map']: -+ if restart_conn_key in self.connection.exclude_ip: - return None - -- # Bump bind and global op count -- self.bind['bind_ctr'] = self.bind.get('bind_ctr', 0) + 1 -- self.operation['all_op_ctr'] = self.operation.get('all_op_ctr', 0) + 1 -+ # Update counters -+ self.bind.counters['bind'] += 1 -+ self.operation.counters['total'] = self.operation.counters['total'] + 1 -+ self.bind.version[bind_version] += 1 - -- # Update bind version count -- self.bind['version'][bind_version] = self.bind['version'].get(bind_version, 0) + 1 -- if bind_dn == "": -- bind_dn = 'Anonymous' - - # If we need to report on this DN, capture some info for tracking - bind_dn_key = self._report_dn_key(bind_dn, self.report_dn) - if bind_dn_key: -- # Update bind count -- self.bind['report_dn'][bind_dn_key]['bind'] = self.bind['report_dn'][bind_dn_key].get('bind', 0) + 1 -- # Connection ID -- self.bind['report_dn'][bind_dn_key]['conn'].add(conn_id) -+ self.bind.report_dn[bind_dn_key]['bind'] = self.bind.report_dn[bind_dn_key].get('bind', 0) + 1 -+ self.bind.report_dn[bind_dn_key]['conn'].add(conn_id) -+ - # Loop over IPs captured at connection time to find the associated IP -- for (ip, ip_info) in self.connection['ip_map'].items(): -+ for (ip, ip_info) in self.connection.src_ip_map.items(): - if restart_conn_key in ip_info['keys']: -- self.bind['report_dn'][bind_dn_key]['ips'].add(ip) -+ self.bind.report_dn[bind_dn_key]['ips'].add(ip) - -- # sasl or simple bind -+ # Handle SASL or simple bind - if bind_method == 'sasl': -- self.bind['sasl_bind_ctr'] = self.bind.get('sasl_bind_ctr', 0) + 1 -+ self.bind.counters['sasl'] += 1 - sasl_mech = groups['sasl_mech'] -- if sasl_mech is not None: -- # Bump sasl mechanism count -- self.bind['sasl_mech_freq'][sasl_mech] = self.bind['sasl_mech_freq'].get(sasl_mech, 0) + 1 -+ if sasl_mech: -+ self.bind.sasl_mech[sasl_mech] += 1 -+ self.bind.conn_op_sasl_mech_map[conn_op_key] = sasl_mech - -- # Keep track of bind key to handle sasl result later -- self.bind['sasl_map_co'][conn_op_key] = sasl_mech -+ if bind_dn_normalised == self.root_dn.casefold(): -+ self.bind.counters['rootdn'] += 1 - - if bind_dn != "Anonymous": -- if bind_dn.casefold() == self.root_dn.casefold(): -- self.bind['rootdn_bind_ctr'] = self.bind.get('rootdn_bind_ctr', 0) + 1 -+ self.bind.dns[bind_dn] += 1 - -- # if self.verbose: -- self.bind['dn_freq'][bind_dn] = self.bind['dn_freq'].get(bind_dn, 0) + 1 -- self.bind['dn_map_rc'][restart_conn_key] = bind_dn.lower() - else: - if bind_dn == "Anonymous": -- self.bind['anon_bind_ctr'] = self.bind.get('anon_bind_ctr', 0) + 1 -- self.bind['dn_freq']['Anonymous'] = self.bind['dn_freq'].get('Anonymous', 0) + 1 -- self.bind['dn_map_rc'][restart_conn_key] = "anonymous" -+ self.bind.counters['anon'] += 1 -+ self.bind.dns['Anonymous'] += 1 - else: - if bind_dn.casefold() == self.root_dn.casefold(): -- self.bind['rootdn_bind_ctr'] = self.bind.get('rootdn_bind_ctr', 0) + 1 -+ self.bind.counters['rootdn'] += 1 -+ self.bind.dns[bind_dn] += 1 - -- # if self.verbose: -- self.bind['dn_freq'][bind_dn] = self.bind['dn_freq'].get(bind_dn, 0) + 1 -- self.bind['dn_map_rc'][restart_conn_key] = bind_dn.lower() -+ self.bind.restart_conn_dn_map[restart_conn_key] = bind_dn_normalised -+ -+ self.logger.debug(f"_process_bind_stats - End") - - def _process_unbind_stats(self, groups: dict): - """ -@@ -1065,27 +1105,31 @@ class logAnalyser: - Args: - groups (dict): A dictionary containing operation information. Expected keys: - - 'conn_id': Connection identifier. -- - 'restart_ctr': Server restart count. - - Raises: - KeyError: If required keys are missing in the `groups` dictionary. - """ -+ -+ self.logger.debug(f"_process_unbind_stats - Start - {groups}") -+ - try: - conn_id = groups.get('conn_id') -- restart_ctr = groups.get('restart_ctr') - except KeyError as e: - self.logger.error(f"Missing key in groups: {e}") - return - - # Create a tracking key for this entry -+ restart_ctr = self.server.counters['restart'] - restart_conn_key = (restart_ctr, conn_id) - - # Should we ignore this operation -- if restart_conn_key in self.connection['exclude_ip_map']: -+ if restart_conn_key in self.connection.exclude_ip: - return None - - # Bump unbind count -- self.bind['unbind_ctr'] = self.bind.get('unbind_ctr', 0) + 1 -+ self.bind.counters['unbind'] += 1 -+ -+ self.logger.debug(f"_process_unbind_stats - End") - - def _process_connect_stats(self, groups: dict): - """ -@@ -1094,15 +1138,18 @@ class logAnalyser: - Args: - groups (dict): A dictionary containing operation information. Expected keys: - - 'conn_id': Connection identifier. -- - 'restart_ctr': Server restart count. -+ - 'src_ip': Source IP address. -+ - 'fd': File descriptor. -+ - 'ssl': LDAPS. - - Raises: - KeyError: If required keys are missing in the `groups` dictionary. - """ -+ -+ self.logger.debug(f"_process_connect_stats - Start - {groups}") -+ - try: -- timestamp = groups.get('timestamp') - conn_id = groups.get('conn_id') -- restart_ctr = groups.get('restart_ctr') - src_ip = groups.get('src_ip') - fd = groups['fd'] - ssl = groups['ssl'] -@@ -1110,61 +1157,63 @@ class logAnalyser: - self.logger.error(f"Missing key in groups: {e}") - return - -+ # If conn=1, server has started a new lifecycle -+ if conn_id == '1': -+ self.server.counters['restart'] += 1 -+ - # Create a tracking key for this entry -+ restart_ctr = self.server.counters['restart'] - restart_conn_key = (restart_ctr, conn_id) - - # Should we exclude this IP - if self.exclude_ip and src_ip in self.exclude_ip: -- self.connection['exclude_ip_map'][restart_conn_key] = src_ip -+ self.connection.exclude_ip[restart_conn_key] = src_ip - return None - - if self.verbose: - # Update open connection count -- self.connection['open_conns'][src_ip] = self.connection['open_conns'].get(src_ip, 0) + 1 -+ self.connection.open_conns[src_ip] += 1 - - # Track the connection start normalised datetime object for latency report -- self.connection['start_time'][conn_id] = groups.get('timestamp') -+ self.connection.start_time[conn_id] = groups.get('timestamp') - - # Update general connection counters -- for key in ['conn_ctr', 'sim_conn_ctr']: -- self.connection[key] = self.connection.get(key, 0) + 1 -+ self.connection.counters['conn'] += 1 -+ self.connection.counters['sim_conn'] += 1 - - # Update the maximum number of simultaneous connections seen -- self.connection['max_sim_conn_ctr'] = max( -- self.connection.get('max_sim_conn_ctr', 0), -- self.connection['sim_conn_ctr'] -+ self.connection.counters['max_sim_conn'] = max( -+ self.connection.counters['max_sim_conn'], -+ self.connection.counters['sim_conn'] - ) - - # Update protocol counters -- src_ip_tmp = 'local' if src_ip == 'local' else 'ldap' - if ssl: -- stat_count_key = 'ldaps_ctr' -+ self.connection.counters['ldaps'] += 1 -+ elif src_ip == 'local': -+ self.connection.counters['ldapi'] += 1 - else: -- stat_count_key = 'ldapi_ctr' if src_ip_tmp == 'local' else 'ldap_ctr' -- self.connection[stat_count_key] = self.connection.get(stat_count_key, 0) + 1 -+ self.connection.counters['ldap'] += 1 - - # Track file descriptor counters -- self.connection['fd_max_ctr'] = ( -- max(self.connection.get('fd_max_ctr', 0), int(fd)) -- ) -- self.connection['fd_taken_ctr'] = ( -- self.connection.get('fd_taken_ctr', 0) + 1 -- ) -+ self.connection.counters['fd_max'] = max(self.connection.counters['fd_taken'], int(fd)) -+ self.connection.counters['fd_taken'] += 1 - - # Track source IP -- self.connection['restart_conn_ip_map'][restart_conn_key] = src_ip -+ self.connection.restart_conn_ip_map[restart_conn_key] = src_ip - - # Update the count of connections seen from this IP -- if src_ip not in self.connection['ip_map']: -- self.connection['ip_map'][src_ip] = {} -+ if src_ip not in self.connection.src_ip_map: -+ self.connection.src_ip_map[src_ip] = {} -+ -+ self.connection.src_ip_map[src_ip]['count'] = self.connection.src_ip_map[src_ip].get('count', 0) + 1 - -- self.connection['ip_map'][src_ip]['count'] = self.connection['ip_map'][src_ip].get('count', 0) + 1 -+ if 'keys' not in self.connection.src_ip_map[src_ip]: -+ self.connection.src_ip_map[src_ip]['keys'] = set() - -- if 'keys' not in self.connection['ip_map'][src_ip]: -- self.connection['ip_map'][src_ip]['keys'] = set() -+ self.connection.src_ip_map[src_ip]['keys'].add(restart_conn_key) - -- self.connection['ip_map'][src_ip]['keys'].add(restart_conn_key) -- # self.connection['ip_map']['ip_key'] = restart_conn_key -+ self.logger.debug(f"_process_connect_stats - End") - - def _process_auth_stats(self, groups: dict): - """ -@@ -1173,7 +1222,6 @@ class logAnalyser: - Args: - groups (dict): A dictionary containing operation information. Expected keys: - - 'conn_id': Connection identifier. -- - 'restart_ctr': Server restart count. - - 'auth_protocol': Auth protocol (SSL, TLS). - - 'auth_version': Auth version. - - 'auth_message': Optional auth message. -@@ -1181,9 +1229,11 @@ class logAnalyser: - Raises: - KeyError: If required keys are missing in the `groups` dictionary. - """ -+ -+ self.logger.debug(f"_process_auth_stats - Start - {groups}") -+ - try: - conn_id = groups.get('conn_id') -- restart_ctr = groups.get('restart_ctr') - auth_protocol = groups.get('auth_protocol') - auth_version = groups.get('auth_version') - auth_message = groups.get('auth_message') -@@ -1192,15 +1242,16 @@ class logAnalyser: - return - - # Create a tracking key for this entry -+ restart_ctr = self.server.counters['restart'] - restart_conn_key = (restart_ctr, conn_id) - - # Should we ignore this operation -- if restart_conn_key in self.connection['exclude_ip_map']: -+ if restart_conn_key in self.connection.exclude_ip: - return None - - if auth_protocol: -- if restart_conn_key not in self.auth['auth_info']: -- self.auth['auth_info'][restart_conn_key] = { -+ if restart_conn_key not in self.auth.auth_info: -+ self.auth.auth_info[restart_conn_key] = { - 'proto': auth_protocol, - 'version': auth_version, - 'count': 0, -@@ -1209,19 +1260,19 @@ class logAnalyser: - - if auth_message: - # Increment counters and add auth message -- self.auth['auth_info'][restart_conn_key]['message'].append(auth_message) -+ self.auth.auth_info[restart_conn_key]['message'].append(auth_message) - - # Bump auth related counters -- self.auth['cipher_ctr'] = self.auth.get('cipher_ctr', 0) + 1 -- self.auth['auth_info'][restart_conn_key]['count'] = ( -- self.auth['auth_info'][restart_conn_key].get('count', 0) + 1 -- ) -+ self.auth.counters['cipher_ctr'] += 1 -+ self.auth.auth_info[restart_conn_key]['count'] += 1 - - if auth_message: - if auth_message == 'client bound as': -- self.auth['ssl_client_bind_ctr'] = self.auth.get('ssl_client_bind_ctr', 0) + 1 -+ self.auth.counters['ssl_client_bind_ctr'] += 1 - elif auth_message == 'failed to map client certificate to LDAP DN': -- self.auth['ssl_client_bind_failed_ctr'] = self.auth.get('ssl_client_bind_failed_ctr', 0) + 1 -+ self.auth.counters['ssl_client_bind_failed_ctr'] += 1 -+ -+ self.logger.debug(f"_process_auth_stats - End") - - def _process_vlv_stats(self, groups: dict): - """ -@@ -1231,33 +1282,37 @@ class logAnalyser: - groups (dict): A dictionary containing operation information. Expected keys: - - 'conn_id': Connection identifier. - - 'op_id': Operation identifier. -- - 'restart_ctr': Server restart count. - - Raises: - KeyError: If required keys are missing in the `groups` dictionary. - """ -+ -+ self.logger.debug(f"_process_vlv_stats - Start - {groups}") -+ - try: - conn_id = groups.get('conn_id') - op_id = groups.get('op_id') -- restart_ctr = groups.get('restart_ctr') - except KeyError as e: - self.logger.error(f"Missing key in groups: {e}") - return - -- # Create tracking keys -+ # Create a tracking key for this entry -+ restart_ctr = self.server.counters['restart'] - restart_conn_op_key = (restart_ctr, conn_id, op_id) - restart_conn_key = (restart_ctr, conn_id) - - # Should we ignore this operation -- if restart_conn_key in self.connection['exclude_ip_map']: -+ if restart_conn_key in self.connection.exclude_ip: - return None - - # Bump vlv and global op stats -- self.vlv['vlv_ctr'] = self.vlv.get('vlv_ctr', 0) + 1 -- self.operation['all_op_ctr'] = self.operation.get('all_op_ctr', 0) + 1 -+ self.vlv.counters['vlv'] += 1 -+ self.operation.counters['total'] = self.operation.counters['total'] + 1 - - # Key and value are the same, makes set operations easier later on -- self.vlv['vlv_map_rco'][restart_conn_op_key] = restart_conn_op_key -+ self.vlv.rst_con_op_map[restart_conn_op_key] = restart_conn_op_key -+ -+ self.logger.debug(f"_process_vlv_stats - End") - - def _process_abandon_stats(self, groups: dict): - """ -@@ -1267,38 +1322,41 @@ class logAnalyser: - groups (dict): A dictionary containing operation information. Expected keys: - - 'conn_id': Connection identifier. - - 'op_id': Operation identifier. -- - 'restart_ctr': Server restart count. - - 'targetop': The target operation. - - 'msgid': Message ID. - - Raises: - KeyError: If required keys are missing in the `groups` dictionary. - """ -+ -+ self.logger.debug(f"_process_abandon_stats - Start - {groups}") -+ - try: - conn_id = groups.get('conn_id') - op_id = groups.get('op_id') -- restart_ctr = groups.get('restart_ctr') - targetop = groups.get('targetop') - msgid = groups.get('msgid') - except KeyError as e: - self.logger.error(f"Missing key in groups: {e}") - return - -- # Create a tracking keys -- restart_conn_op_key = (restart_ctr, conn_id, op_id) -+ # Create a tracking key for this entry -+ restart_ctr = self.server.counters['restart'] - restart_conn_key = (restart_ctr, conn_id) - - # Should we ignore this operation -- if restart_conn_key in self.connection['exclude_ip_map']: -+ if restart_conn_key in self.connection.exclude_ip: - return None - - # Bump some stats -- self.result['result_ctr'] = self.result.get('result_ctr', 0) + 1 -- self.operation['all_op_ctr'] = self.operation.get('all_op_ctr', 0) + 1 -- self.operation['abandon_op_ctr'] = self.operation.get('abandon_op_ctr', 0) + 1 -+ self.result.counters['result'] += 1 -+ self.operation.counters['total'] = self.operation.counters['total'] + 1 -+ self.operation.counters['abandon'] += 1 - - # Track abandoned operation for later processing -- self.operation['abandoned_map_rco'][restart_conn_op_key] = (conn_id, op_id, targetop, msgid) -+ self.operation.rst_con_op_map['abandon'] = (conn_id, op_id, targetop, msgid) -+ -+ self.logger.debug(f"_process_abandon_stats - End") - - def _process_sort_stats(self, groups: dict): - """ -@@ -1307,26 +1365,30 @@ class logAnalyser: - Args: - groups (dict): A dictionary containing operation information. Expected keys: - - 'conn_id': Connection identifier. -- - 'restart_ctr': Server restart count. - - Raises: - KeyError: If required keys are missing in the `groups` dictionary. - """ -+ -+ self.logger.debug(f"_process_sort_stats - Start - {groups}") -+ - try: - conn_id = groups.get('conn_id') -- restart_ctr = groups.get('restart_ctr') - except KeyError as e: - self.logger.error(f"Missing key in groups: {e}") - return - - # Create a tracking key for this entry -+ restart_ctr = self.server.counters['restart'] - restart_conn_key = (restart_ctr, conn_id) - - # Should we ignore this operation -- if restart_conn_key in self.connection['exclude_ip_map']: -+ if restart_conn_key in self.connection.exclude_ip: - return None - -- self.operation['sort_op_ctr'] = self.operation.get('sort_op_ctr', 0) + 1 -+ self.operation.counters['sort'] += 1 -+ -+ self.logger.debug(f"_process_sort_stats - End") - - def _process_extend_op_stats(self, groups: dict): - """ -@@ -1342,6 +1404,9 @@ class logAnalyser: - Raises: - KeyError: If required keys are missing in the `groups` dictionary. - """ -+ -+ self.logger.debug(f"_process_extend_op_stats - Start - {groups}") -+ - try: - conn_id = groups.get('conn_id') - op_id = groups.get('op_id') -@@ -1352,31 +1417,34 @@ class logAnalyser: - return - - # Create a tracking key for this entry -+ restart_ctr = self.server.counters['restart'] - restart_conn_op_key = (restart_ctr, conn_id, op_id) - restart_conn_key = (restart_ctr, conn_id) - - # Should we ignore this operation -- if restart_conn_key in self.connection['exclude_ip_map']: -+ if restart_conn_key in self.connection.exclude_ip: - return None - - # Increment global operation counters -- self.operation['all_op_ctr'] = self.operation.get('all_op_ctr', 0) + 1 -- self.operation['extnd_op_ctr'] = self.operation.get('extnd_op_ctr', 0) + 1 -+ self.operation.counters['total'] = self.operation.counters['total'] + 1 -+ self.operation.counters['extnd'] += 1 - - # Track extended operation data if an OID is present - if oid is not None: -- self.operation['extop_dict'][oid] = self.operation['extop_dict'].get(oid, 0) + 1 -- self.operation['extop_map_rco'][restart_conn_op_key] = ( -- self.operation['extop_map_rco'].get(restart_conn_op_key, 0) + 1 -+ self.operation.extended[oid] += 1 -+ self.operation.rst_con_op_map['extnd'][restart_conn_op_key] = ( -+ self.operation.rst_con_op_map['extnd'].get(restart_conn_op_key, 0) + 1 - ) - - # If the conn_id is associated with this DN, update op counter -- for dn in self.bind['report_dn']: -- conns = self.bind['report_dn'][dn]['conn'] -+ for dn in self.bind.report_dn: -+ conns = self.bind.report_dn[dn]['conn'] - if conn_id in conns: - bind_dn_key = self._report_dn_key(dn, self.report_dn) - if bind_dn_key: -- self.bind['report_dn'][bind_dn_key]['ext'] = self.bind['report_dn'][bind_dn_key].get('ext', 0) + 1 -+ self.bind.report_dn[bind_dn_key]['ext'] = self.bind.report_dn[bind_dn_key].get('ext', 0) + 1 -+ -+ self.logger.debug(f"_process_extend_op_stats - End") - - def _process_autobind_stats(self, groups: dict): - """ -@@ -1385,43 +1453,47 @@ class logAnalyser: - Args: - groups (dict): A dictionary containing operation information. Expected keys: - - 'conn_id': Connection identifier. -- - 'restart_ctr': Server restart count. - - 'bind_dn': Bind DN ("cn=Directory Manager") - - Raises: - KeyError: If required keys are missing in the `groups` dictionary. - """ -+ -+ self.logger.debug(f"_process_autobind_stats - Start - {groups}") -+ - try: - conn_id = groups.get('conn_id') -- restart_ctr = groups.get('restart_ctr') - bind_dn = groups.get('bind_dn') - except KeyError as e: - self.logger.error(f"Missing key in groups: {e}") - return - - # Create a tracking key for this entry -+ restart_ctr = self.server.counters['restart'] - restart_conn_key = (restart_ctr, conn_id) - - # Should we ignore this operation -- if restart_conn_key in self.connection['exclude_ip_map']: -+ if restart_conn_key in self.connection.exclude_ip: - return None - - # Bump relevant counters -- self.bind['bind_ctr'] = self.bind.get('bind_ctr', 0) + 1 -- self.bind['autobind_ctr'] = self.bind.get('autobind_ctr', 0) + 1 -- self.operation['all_op_ctr'] = self.operation.get('all_op_ctr', 0) + 1 -+ self.bind.counters['bind'] += 1 -+ self.bind.counters['autobind'] += 1 -+ self.operation.counters['total'] += 1 - - # Handle an anonymous autobind (empty bind_dn) - if bind_dn == "": -- self.bind['anon_bind_ctr'] = self.bind.get('anon_bind_ctr', 0) + 1 -+ self.bind.counters['anon'] += 1 - else: -- # Process non-anonymous binds, does the bind_dn if exist in dn_map_rc -- bind_dn = self.bind['dn_map_rc'].get(restart_conn_key, bind_dn) -+ # Process non-anonymous binds, does the bind_dn if exist in restart_conn_dn_map -+ bind_dn = self.bind.restart_conn_dn_map.get(restart_conn_key, bind_dn) - if bind_dn: - if bind_dn.casefold() == self.root_dn.casefold(): -- self.bind['rootdn_bind_ctr'] = self.bind.get('rootdn_bind_ctr', 0) + 1 -+ self.bind.counters['rootdn'] += 1 - bind_dn = bind_dn.lower() -- self.bind['dn_freq'][bind_dn] = self.bind['dn_freq'].get(bind_dn, 0) + 1 -+ self.bind.dns[bind_dn] = self.bind.dns.get(bind_dn, 0) + 1 -+ -+ self.logger.debug(f"_process_autobind_stats - End") - - def _process_disconnect_stats(self, groups: dict): - """ -@@ -1430,7 +1502,6 @@ class logAnalyser: - Args: - groups (dict): A dictionary containing operation information. Expected keys: - - 'conn_id': Connection identifier. -- - 'restart_ctr': Server restart count. - - 'timestamp': The timestamp of the disconnect event. - - 'error_code': Error code associated with the disconnect, if any. - - 'disconnect_code': Disconnect code, if any. -@@ -1438,9 +1509,11 @@ class logAnalyser: - Raises: - KeyError: If required keys are missing in the `groups` dictionary. - """ -+ -+ self.logger.debug(f"_process_disconnect_stats - Start - {groups}") -+ - try: - conn_id = groups.get('conn_id') -- restart_ctr = groups.get('restart_ctr') - timestamp = groups.get('timestamp') - error_code = groups.get('error_code') - disconnect_code = groups.get('disconnect_code') -@@ -1449,17 +1522,18 @@ class logAnalyser: - return - - # Create a tracking key for this entry -+ restart_ctr = self.server.counters['restart'] - restart_conn_key = (restart_ctr, conn_id) - - # Should we ignore this operation -- if restart_conn_key in self.connection['exclude_ip_map']: -+ if restart_conn_key in self.connection.exclude_ip: - return None - - if self.verbose: - # Handle verbose logging for open connections and IP addresses -- src_ip = self.connection['restart_conn_ip_map'].get(restart_conn_key) -- if src_ip and src_ip in self.connection.get('open_conns', {}): -- open_conns = self.connection['open_conns'] -+ src_ip = self.connection.restart_conn_ip_map.get(restart_conn_key) -+ if src_ip and src_ip in self.connection.open_conns: -+ open_conns = self.connection.open_conns - if open_conns[src_ip] > 1: - open_conns[src_ip] -= 1 - else: -@@ -1467,7 +1541,7 @@ class logAnalyser: - - # Handle latency and disconnect times - if self.verbose: -- start_time = self.connection['start_time'].get(conn_id, None) -+ start_time = self.connection.start_time[conn_id] - finish_time = groups.get('timestamp') - if start_time and timestamp: - latency = self.get_elapsed_time(start_time, finish_time, "seconds") -@@ -1475,28 +1549,29 @@ class logAnalyser: - LATENCY_GROUPS[bucket] += 1 - - # Reset start time for the connection -- self.connection['start_time'][conn_id] = None -+ self.connection.start_time[conn_id] = None - - # Update connection stats -- self.connection['sim_conn_ctr'] = self.connection.get('sim_conn_ctr', 0) - 1 -- self.connection['fd_returned_ctr'] = ( -- self.connection.get('fd_returned_ctr', 0) + 1 -- ) -+ self.connection.counters['sim_conn'] -= 1 -+ self.connection.counters['fd_returned'] += 1 - - # Track error and disconnect codes if provided - if error_code is not None: - error_type = DISCONNECT_ERRORS.get(error_code, 'unknown') - if disconnect_code is not None: - # Increment the count for the specific error and disconnect code -- error_map = self.connection.setdefault(error_type, {}) -- error_map[disconnect_code] = error_map.get(disconnect_code, 0) + 1 -+ # error_map = self.connection.setdefault(error_type, {}) -+ # error_map[disconnect_code] = error_map.get(disconnect_code, 0) + 1 -+ self.connection[error_type][disconnect_code] += 1 - - # Handle disconnect code and update stats - if disconnect_code is not None: -- self.connection['disconnect_code'][disconnect_code] = ( -- self.connection['disconnect_code'].get(disconnect_code, 0) + 1 -+ self.connection.disconnect_code[disconnect_code] = ( -+ self.connection.disconnect_code.get(disconnect_code, 0) + 1 - ) -- self.connection['disconnect_code_map'][restart_conn_key] = disconnect_code -+ self.connection.restart_conn_disconnect_map[restart_conn_key] = disconnect_code -+ -+ self.logger.debug(f"_process_disconnect_stats - End") - - def _group_latencies(self, latency_seconds: int): - """ -@@ -1530,49 +1605,57 @@ class logAnalyser: - Args: - groups (dict): A dictionary containing operation information. Expected keys: - - 'conn_id': Connection identifier. -- - 'restart_ctr': Server restart count. - - 'op_id': Operation identifier. - - Raises: - KeyError: If required keys are missing in the `groups` dictionary. - """ -+ self.logger.debug(f"_process_crud_stats - Start - {groups}") - try: - conn_id = groups.get('conn_id') -- restart_ctr = groups.get('restart_ctr') - op_type = groups.get('op_type') -- internal = groups.get('internal') - except KeyError as e: - self.logger.error(f"Missing key in groups: {e}") - return - - # Create a tracking key for this entry -+ restart_ctr = self.server.counters['restart'] - restart_conn_key = (restart_ctr, conn_id) - - # Should we ignore this operation -- if restart_conn_key in self.connection['exclude_ip_map']: -+ if restart_conn_key in self.connection.exclude_ip: - return None - -- self.operation['all_op_ctr'] = self.operation.get('all_op_ctr', 0) + 1 -+ self.operation.counters['total'] = self.operation.counters['total'] + 1 - - # Use operation type as key for stats - if op_type is not None: - op_key = op_type.lower() -- self.operation[f"{op_key}_op_ctr"] = self.operation.get(f"{op_key}_op_ctr", 0) + 1 -- self.operation[f"{op_key}_map_rco"][restart_conn_key] = ( -- self.operation[f"{op_key}_map_rco"].get(restart_conn_key, 0) + 1 -- ) -+ if op_key not in self.operation.counters: -+ self.operation.counters[op_key] = 0 -+ if op_key not in self.operation.rst_con_op_map: -+ self.operation.rst_con_op_map[op_key] = {} -+ -+ # Increment op type counter -+ self.operation.counters[op_key] += 1 -+ -+ # Increment the op type map counter -+ current_count = self.operation.rst_con_op_map[op_key].get(restart_conn_key, 0) -+ self.operation.rst_con_op_map[op_key][restart_conn_key] = current_count + 1 - - # If the conn_id is associated with this DN, update op counter -- for dn in self.bind['report_dn']: -- conns = self.bind['report_dn'][dn]['conn'] -+ for dn in self.bind.report_dn: -+ conns = self.bind.report_dn[dn]['conn'] - if conn_id in conns: - bind_dn_key = self._report_dn_key(dn, self.report_dn) - if bind_dn_key: -- self.bind['report_dn'][bind_dn_key][op_key] = self.bind['report_dn'][bind_dn_key].get(op_key, 0) + 1 -+ self.bind.report_dn[bind_dn_key][op_key] = self.bind.report_dn[bind_dn_key].get(op_key, 0) + 1 - - # Authorization identity - if groups['authzid_dn'] is not None: -- self.operation['authzid'] = self.operation.get('authzid', 0) + 1 -+ self.operation.counters['authzid'] += 1 -+ -+ self.logger.debug(f"_process_crud_stats - End") - - def _process_entry_referral_stats(self, groups: dict): - """ -@@ -1581,33 +1664,36 @@ class logAnalyser: - Args: - groups (dict): A dictionary containing operation information. Expected keys: - - 'conn_id': Connection identifier. -- - 'restart_ctr': Server restart count. - - 'op_id': Operation identifier. - - Raises: - KeyError: If required keys are missing in the `groups` dictionary. - """ -+ self.logger.debug(f"_process_entry_referral_stats - Start - {groups}") -+ - try: - conn_id = groups.get('conn_id') -- restart_ctr = groups.get('restart_ctr') - op_type = groups.get('op_type') - except KeyError as e: - self.logger.error(f"Missing key in groups: {e}") - return - - # Create a tracking key for this entry -+ restart_ctr = self.server.counters['restart'] - restart_conn_key = (restart_ctr, conn_id) - - # Should we ignore this operation -- if restart_conn_key in self.connection['exclude_ip_map']: -+ if restart_conn_key in self.connection.exclude_ip: - return None - - # Process operation type - if op_type is not None: - if op_type == 'ENTRY': -- self.result['entry_count'] = self.result.get('entry_count', 0) + 1 -+ self.result.counters['entry'] += 1 - elif op_type == 'REFERRAL': -- self.result['referral_count'] = self.result.get('referral_count', 0) + 1 -+ self.result.counters['referral'] += 1 -+ -+ self.logger.debug(f"_process_entry_referral_stats - End") - - def _process_and_write_stats(self, norm_timestamp: str, bytes_read: int): - """ -@@ -1620,6 +1706,7 @@ class logAnalyser: - Returns: - None - """ -+ self.logger.debug(f"_process_and_write_stats - Start") - - if self.csv_writer is None: - self.logger.error("CSV writer not enabled.") -@@ -1627,23 +1714,23 @@ class logAnalyser: - - # Define the stat mapping - stats = { -- 'result_ctr': self.result, -- 'search_ctr': self.search, -- 'add_op_ctr': self.operation, -- 'mod_op_ctr': self.operation, -- 'modrdn_op_ctr': self.operation, -- 'cmp_op_ctr': self.operation, -- 'del_op_ctr': self.operation, -- 'abandon_op_ctr': self.operation, -- 'conn_ctr': self.connection, -- 'ldaps_ctr': self.connection, -- 'bind_ctr': self.bind, -- 'anon_bind_ctr': self.bind, -- 'unbind_ctr': self.bind, -- 'notesA_ctr': self.result, -- 'notesU_ctr': self.result, -- 'notesF_ctr': self.result, -- 'etime_stat': self.result -+ 'result': self.result.counters, -+ 'search': self.search.counters, -+ 'add': self.operation.counters, -+ 'mod': self.operation.counters, -+ 'modrdn': self.operation.counters, -+ 'cmp': self.operation.counters, -+ 'del': self.operation.counters, -+ 'abandon': self.operation.counters, -+ 'conn': self.connection.counters, -+ 'ldaps': self.connection.counters, -+ 'bind': self.bind.counters, -+ 'anon': self.bind.counters, -+ 'unbind': self.bind.counters, -+ 'notesA': self.result.counters, -+ 'notesU': self.result.counters, -+ 'notesF': self.result.counters, -+ 'etime_stat': self.result.counters - } - - # Build the current stat block -@@ -1675,8 +1762,7 @@ class logAnalyser: - - # out_stat_block[0] = self._convert_datetime_to_timestamp(out_stat_block[0]) - self.csv_writer.writerow(out_stat_block) -- -- self.result['etime_stat'] = 0.0 -+ self.result.etime_stat = 0.0 - - # Update previous stats for the next interval - self.prev_stats = curr_stat_block -@@ -1705,7 +1791,9 @@ class logAnalyser: - # Write the stat block to csv and reset elapsed time for the next interval - # out_stat_block[0] = self._convert_datetime_to_timestamp(out_stat_block[0]) - self.csv_writer.writerow(out_stat_block) -- self.result['etime_stat'] = 0.0 -+ self.result.etime_stat = 0.0 -+ -+ self.logger.debug(f"_process_and_write_stats - End") - - def process_file(self, log_num: str, filepath: str): - """ -@@ -2254,45 +2342,45 @@ def main(): - sys.exit(1) - - # Prep for display -- elapsed_time = db.get_elapsed_time(db.server['first_time'], db.server['last_time'], "hms") -- elapsed_secs = db.get_elapsed_time(db.server['first_time'], db.server['last_time'], "seconds") -- num_ops = db.operation.get('all_op_ctr', 0) -- num_results = db.result.get('result_ctr', 0) -- num_conns = db.connection.get('conn_ctr', 0) -- num_ldap = db.connection.get('ldap_ctr', 0) -- num_ldapi = db.connection.get('ldapi_ctr', 0) -- num_ldaps = db.connection.get('ldaps_ctr', 0) -- num_startls = db.operation['extop_dict'].get(STLS_OID, 0) -- num_search = db.search.get('search_ctr', 0) -- num_mod = db.operation.get('mod_op_ctr', 0) -- num_add = db.operation.get('add_op_ctr', 0) -- num_del = db.operation.get('del_op_ctr', 0) -- num_modrdn = db.operation.get('modrdn_op_ctr', 0) -- num_cmp = db.operation.get('cmp_op_ctr', 0) -- num_bind = db.bind.get('bind_ctr', 0) -- num_unbind = db.bind.get('unbind_ctr', 0) -- num_proxyd_auths = db.operation.get('authzid', 0) + db.search.get('authzid', 0) -- num_time_count = db.result.get('timestamp_ctr') -+ elapsed_time = db.get_elapsed_time(db.server.first_time, db.server.last_time, "hms") -+ elapsed_secs = db.get_elapsed_time(db.server.first_time, db.server.last_time, "seconds") -+ num_ops = db.operation.counters['total'] -+ num_results = db.result.counters['result'] -+ num_conns = db.connection.counters['conn'] -+ num_ldap = db.connection.counters['ldap'] -+ num_ldapi = db.connection.counters['ldapi'] -+ num_ldaps = db.connection.counters['ldaps'] -+ num_startls = db.operation.extended.get(STLS_OID, 0) -+ num_search = db.search.counters['search'] -+ num_mod = db.operation.counters['mod'] -+ num_add = db.operation.counters['add'] -+ num_del = db.operation.counters['del'] -+ num_modrdn = db.operation.counters['modrdn'] -+ num_cmp = db.operation.counters['cmp'] -+ num_bind = db.bind.counters['bind'] -+ num_unbind = db.bind.counters['unbind'] -+ num_proxyd_auths = db.operation.counters['authzid'] + db.search.counters['authzid'] -+ num_time_count = db.result.counters['timestamp'] - if num_time_count: -- avg_wtime = round(db.result.get('total_wtime', 0)/num_time_count, 9) -- avg_optime = round(db.result.get('total_optime', 0)/num_time_count, 9) -- avg_etime = round(db.result.get('total_etime', 0)/num_time_count, 9) -- num_fd_taken = db.connection.get('fd_taken_ctr', 0) -- num_fd_rtn = db.connection.get('fd_returned_ctr', 0) -- -- num_DM_binds = db.bind.get('rootdn_bind_ctr', 0) -- num_base_search = db.search.get('base_search_ctr', 0) -+ avg_wtime = round(db.result.total_wtime/num_time_count, 9) -+ avg_optime = round(db.result.total_optime/num_time_count, 9) -+ avg_etime = round(db.result.total_etime/num_time_count, 9) -+ num_fd_taken = db.connection.counters['fd_taken'] -+ num_fd_rtn = db.connection.counters['fd_returned'] -+ -+ num_DM_binds = db.bind.counters['rootdn'] -+ num_base_search = db.search.counters['base_search'] - try: -- log_start_time = db.convert_timestamp_to_string(db.server.get('first_time', "")) -+ log_start_time = db.convert_timestamp_to_string(db.server.first_time) - except ValueError: - log_start_time = "Unknown" - - try: -- log_end_time = db.convert_timestamp_to_string(db.server.get('last_time', "")) -+ log_end_time = db.convert_timestamp_to_string(db.server.last_time) - except ValueError: - log_end_time = "Unknown" - -- print(f"\n\nTotal Log Lines Analysed:{db.server['lines_parsed']}\n") -+ print(f"\n\nTotal Log Lines Analysed:{db.server.counters['lines_parsed']}\n") - print("\n----------- Access Log Output ------------\n") - print(f"Start of Logs: {log_start_time}") - print(f"End of Logs: {log_end_time}") -@@ -2302,12 +2390,12 @@ def main(): - db.display_bind_report() - sys.exit(1) - -- print(f"\nRestarts: {db.server.get('restart_ctr', 0)}") -- if db.auth.get('cipher_ctr', 0) > 0: -+ print(f"\nRestarts: {db.server.counters['restart']}") -+ if db.auth.counters['cipher_ctr'] > 0: - print(f"Secure Protocol Versions:") - # Group data by protocol + version + unique message - grouped_data = defaultdict(lambda: {'count': 0, 'messages': set()}) -- for _, details in db.auth['auth_info'].items(): -+ for _, details in db.auth.auth_info.items(): - # If there is no protocol version - if details['version']: - proto_version = f"{details['proto']}{details['version']}" -@@ -2323,7 +2411,7 @@ def main(): - for ((proto_version, message), data) in grouped_data.items(): - print(f" - {proto_version} {message} ({data['count']} connection{'s' if data['count'] > 1 else ''})") - -- print(f"Peak Concurrent connections: {db.connection.get('max_sim_conn_ctr', 0)}") -+ print(f"Peak Concurrent connections: {db.connection.counters['max_sim_conn']}") - print(f"Total Operations: {num_ops}") - print(f"Total Results: {num_results}") - print(f"Overall Performance: {db.get_overall_perf(num_results, num_ops)}%") -@@ -2344,111 +2432,112 @@ def main(): - print(f"\nAverage wtime (wait time): {avg_wtime:.9f}") - print(f"Average optime (op time): {avg_optime:.9f}") - print(f"Average etime (elapsed time): {avg_etime:.9f}") -- print(f"\nMulti-factor Authentications: {db.result.get('notesM_ctr', 0)}") -+ print(f"\nMulti-factor Authentications: {db.result.counters['notesM']}") - print(f"Proxied Auth Operations: {num_proxyd_auths}") -- print(f"Persistent Searches: {db.search.get('persistent_ctr', 0)}") -- print(f"Internal Operations: {db.server.get('internal_op_ctr', 0)}") -- print(f"Entry Operations: {db.result.get('entry_count', 0)}") -- print(f"Extended Operations: {db.operation.get('extnd_op_ctr', 0)}") -- print(f"Abandoned Requests: {db.operation.get('abandon_op_ctr', 0)}") -- print(f"Smart Referrals Received: {db.result.get('referral_count', 0)}") -- print(f"\nVLV Operations: {db.vlv.get('vlv_ctr', 0)}") -- print(f"VLV Unindexed Searches: {len([key for key, value in db.vlv['vlv_map_rco'].items() if value == 'A'])}") -- print(f"VLV Unindexed Components: {len([key for key, value in db.vlv['vlv_map_rco'].items() if value == 'U'])}") -- print(f"SORT Operations: {db.operation.get('sort_op_ctr', 0)}") -- print(f"\nEntire Search Base Queries: {db.search.get('base_search_ctr', 0)}") -- print(f"Paged Searches: {db.result.get('notesP_ctr', 0)}") -- num_unindexed_search = len(db.notesA.keys()) -+ print(f"Persistent Searches: {db.search.counters['persistent']}") -+ print(f"Internal Operations: {db.operation.counters['internal']}") -+ print(f"Entry Operations: {db.result.counters['entry']}") -+ print(f"Extended Operations: {db.operation.counters['extnd']}") -+ print(f"Abandoned Requests: {db.operation.counters['abandon']}") -+ print(f"Smart Referrals Received: {db.result.counters['referral']}") -+ print(f"\nVLV Operations: {db.vlv.counters['vlv']}") -+ print(f"VLV Unindexed Searches: {len([key for key, value in db.vlv.rst_con_op_map.items() if value == 'A'])}") -+ print(f"VLV Unindexed Components: {len([key for key, value in db.vlv.rst_con_op_map.items() if value == 'U'])}") -+ print(f"SORT Operations: {db.operation.counters['sort']}") -+ print(f"\nEntire Search Base Queries: {num_base_search}") -+ print(f"Paged Searches: {db.result.counters['notesP']}") -+ num_unindexed_search = len(db.result.notes['A']) - print(f"Unindexed Searches: {num_unindexed_search}") -- if db.verbose: -- if num_unindexed_search > 0: -- for num, key in enumerate(db.notesA, start=1): -- src, conn, op = key -- restart_conn_op_key = (src, conn, op) -- print(f"\nUnindexed Search #{num} (notes=A)") -- print(f" - Date/Time: {db.notesA[restart_conn_op_key]['time']}") -- print(f" - Connection Number: {conn}") -- print(f" - Operation Number: {op}") -- print(f" - Etime: {db.notesA[restart_conn_op_key]['etime']}") -- print(f" - Nentries: {db.notesA[restart_conn_op_key]['nentries']}") -- print(f" - IP Address: {db.notesA[restart_conn_op_key]['ip']}") -- print(f" - Search Base: {db.notesA[restart_conn_op_key]['base']}") -- print(f" - Search Scope: {db.notesA[restart_conn_op_key]['scope']}") -- print(f" - Search Filter: {db.notesA[restart_conn_op_key]['filter']}") -- print(f" - Bind DN: {db.notesA[restart_conn_op_key]['bind_dn']}\n") -- -- num_unindexed_component = len(db.notesU.keys()) -+ if db.verbose and num_unindexed_search > 0: -+ for num, key in enumerate(db.result.notes['A'], start=1): -+ src, conn, op = key -+ data = db.result.notes['A'][key] -+ -+ print(f"\n Unindexed Search #{num} (notes=A)") -+ print(f" - Date/Time: {data.get('time', '-')}") -+ print(f" - Connection Number: {conn}") -+ print(f" - Operation Number: {op}") -+ print(f" - Etime: {data.get('etime', '-')}") -+ print(f" - Nentries: {data.get('nentries', 0)}") -+ print(f" - IP Address: {data.get('ip', '-')}") -+ print(f" - Search Base: {data.get('base', '-')}") -+ print(f" - Search Scope: {data.get('scope', '-')}") -+ print(f" - Search Filter: {data.get('filter', '-')}") -+ print(f" - Bind DN: {data.get('bind_dn', '-')}\n") -+ -+ num_unindexed_component = len(db.result.notes['U']) - print(f"Unindexed Components: {num_unindexed_component}") -- if db.verbose: -- if num_unindexed_component > 0: -- for num, key in enumerate(db.notesU, start=1): -- src, conn, op = key -- restart_conn_op_key = (src, conn, op) -- print(f"\nUnindexed Component #{num} (notes=U)") -- print(f" - Date/Time: {db.notesU[restart_conn_op_key]['time']}") -- print(f" - Connection Number: {conn}") -- print(f" - Operation Number: {op}") -- print(f" - Etime: {db.notesU[restart_conn_op_key]['etime']}") -- print(f" - Nentries: {db.notesU[restart_conn_op_key]['nentries']}") -- print(f" - IP Address: {db.notesU[restart_conn_op_key]['ip']}") -- print(f" - Search Base: {db.notesU[restart_conn_op_key]['base']}") -- print(f" - Search Scope: {db.notesU[restart_conn_op_key]['scope']}") -- print(f" - Search Filter: {db.notesU[restart_conn_op_key]['filter']}") -- print(f" - Bind DN: {db.notesU[restart_conn_op_key]['bind_dn']}\n") -- -- num_invalid_filter = len(db.notesF.keys()) -+ if db.verbose and num_unindexed_component > 0: -+ for num, key in enumerate(db.result.notes['U'], start=1): -+ src, conn, op = key -+ data = db.result.notes['U'][key] -+ -+ print(f"\n Unindexed Component #{num} (notes=U)") -+ print(f" - Date/Time: {data.get('time', '-')}") -+ print(f" - Connection Number: {conn}") -+ print(f" - Operation Number: {op}") -+ print(f" - Etime: {data.get('etime', '-')}") -+ print(f" - Nentries: {data.get('nentries', 0)}") -+ print(f" - IP Address: {data.get('ip', '-')}") -+ print(f" - Search Base: {data.get('base', '-')}") -+ print(f" - Search Scope: {data.get('scope', '-')}") -+ print(f" - Search Filter: {data.get('filter', '-')}") -+ print(f" - Bind DN: {data.get('bind_dn', '-')}\n") -+ -+ num_invalid_filter = len(db.result.notes['F']) - print(f"Invalid Attribute Filters: {num_invalid_filter}") -- if db.verbose: -- if num_invalid_filter > 0: -- for num, key in enumerate(db.notesF, start=1): -- src, conn, op = key -- restart_conn_op_key = (src, conn, op) -- print(f"\nInvalid Attribute Filter #{num} (notes=F)") -- print(f" - Date/Time: {db.notesF[restart_conn_op_key]['time']}") -- print(f" - Connection Number: {conn}") -- print(f" - Operation Number: {op}") -- print(f" - Etime: {db.notesF[restart_conn_op_key]['etime']}") -- print(f" - Nentries: {db.notesF[restart_conn_op_key]['nentries']}") -- print(f" - IP Address: {db.notesF[restart_conn_op_key]['ip']}") -- print(f" - Search Filter: {db.notesF[restart_conn_op_key]['filter']}") -- print(f" - Bind DN: {db.notesF[restart_conn_op_key]['bind_dn']}\n") -+ if db.verbose and num_invalid_filter > 0: -+ for num, key in enumerate(db.result.notes['F'], start=1): -+ src, conn, op = key -+ data = db.result.notes['F'][key] -+ -+ print(f"\n Invalid Attribute Filter #{num} (notes=F)") -+ print(f" - Date/Time: {data.get('time', '-')}") -+ print(f" - Connection Number: {conn}") -+ print(f" - Operation Number: {op}") -+ print(f" - Etime: {data.get('etime', '-')}") -+ print(f" - Nentries: {data.get('nentries', 0)}") -+ print(f" - IP Address: {data.get('ip', '-')}") -+ print(f" - Search Filter: {data.get('filter', '-')}") -+ print(f" - Bind DN: {data.get('bind_dn', '-')}\n") -+ - print(f"FDs Taken: {num_fd_taken}") - print(f"FDs Returned: {num_fd_rtn}") -- print(f"Highest FD Taken: {db.connection.get('fd_max_ctr', 0)}\n") -- num_broken_pipe = len(db.connection['broken_pipe']) -+ print(f"Highest FD Taken: {db.connection.counters['fd_max']}\n") -+ num_broken_pipe = len(db.connection.broken_pipe) - print(f"Broken Pipes: {num_broken_pipe}") - if num_broken_pipe > 0: -- for code, count in db.connection['broken_pipe'].items(): -+ for code, count in db.connection.broken_pipe.items(): - print(f" - {count} ({code}) {DISCONNECT_MSG.get(code, 'unknown')}") - print() -- num_reset_peer = len(db.connection['connection_reset']) -+ num_reset_peer = len(db.connection.connection_reset) - print(f"Connection Reset By Peer: {num_reset_peer}") - if num_reset_peer > 0: -- for code, count in db.connection['connection_reset'].items(): -+ for code, count in db.connection.connection_reset.items(): - print(f" - {count} ({code}) {DISCONNECT_MSG.get(code, 'unknown')}") - print() -- num_resource_unavail = len(db.connection['resource_unavail']) -+ num_resource_unavail = len(db.connection.resource_unavail) - print(f"Resource Unavailable: {num_resource_unavail}") - if num_resource_unavail > 0: -- for code, count in db.connection['resource_unavail'].items(): -+ for code, count in db.connection.resource_unavail.items(): - print(f" - {count} ({code}) {DISCONNECT_MSG.get(code, 'unknown')}") - print() -- print(f"Max BER Size Exceeded: {db.connection['disconnect_code'].get('B2', 0)}\n") -- print(f"Binds: {db.bind.get('bind_ctr', 0)}") -- print(f"Unbinds: {db.bind.get('unbind_ctr', 0)}") -+ print(f"Max BER Size Exceeded: {db.connection.disconnect_code.get('B2', 0)}\n") -+ print(f"Binds: {db.bind.counters['bind']}") -+ print(f"Unbinds: {db.bind.counters['unbind']}") - print(f"----------------------------------") -- print(f"- LDAP v2 Binds: {db.bind.get('version', {}).get('2', 0)}") -- print(f"- LDAP v3 Binds: {db.bind.get('version', {}).get('3', 0)}") -- print(f"- AUTOBINDs(LDAPI): {db.bind.get('autobind_ctr', 0)}") -- print(f"- SSL Client Binds {db.auth.get('ssl_client_bind_ctr', 0)}") -- print(f"- Failed SSL Client Binds: {db.auth.get('ssl_client_bind_failed_ctr', 0)}") -- print(f"- SASL Binds: {db.bind.get('sasl_bind_ctr', 0)}") -- if db.bind.get('sasl_bind_ctr', 0) > 0: -- saslmech = db.bind['sasl_mech_freq'] -+ print(f"- LDAP v2 Binds: {db.bind.version.get('2', 0)}") -+ print(f"- LDAP v3 Binds: {db.bind.version.get('3', 0)}") -+ print(f"- AUTOBINDs(LDAPI): {db.bind.counters['autobind']}") -+ print(f"- SSL Client Binds {db.auth.counters['ssl_client_bind_ctr']}") -+ print(f"- Failed SSL Client Binds: {db.auth.counters['ssl_client_bind_failed_ctr']}") -+ print(f"- SASL Binds: {db.bind.counters['sasl']}") -+ if db.bind.counters['sasl'] > 0: -+ saslmech = db.bind.sasl_mech - for saslb in sorted(saslmech.keys(), key=lambda k: saslmech[k], reverse=True): - print(f" - {saslb:<4}: {saslmech[saslb]}") - print(f"- Directory Manager Binds: {num_DM_binds}") -- print(f"- Anonymous Binds: {db.bind.get('anon_bind_ctr', 0)}\n") -+ print(f"- Anonymous Binds: {db.bind.counters['anon']}\n") - if db.verbose: - # Connection Latency - print(f"\n ----- Connection Latency Details -----\n") -@@ -2465,7 +2554,7 @@ def main(): - f"{LATENCY_GROUPS['> 15']:^7}") - - # Open Connections -- open_conns = db.connection['open_conns'] -+ open_conns = db.connection.open_conns - if len(open_conns) > 0: - print(f"\n ----- Current Open Connection IDs -----\n") - for conn in sorted(open_conns.keys(), key=lambda k: open_conns[k], reverse=True): -@@ -2473,12 +2562,12 @@ def main(): - - # Error Codes - print(f"\n----- Errors -----\n") -- error_freq = db.result['error_freq'] -+ error_freq = db.result.error_freq - for err in sorted(error_freq.keys(), key=lambda k: error_freq[k], reverse=True): - print(f"err={err:<2} {error_freq[err]:>10} {LDAP_ERR_CODES[err]:<30}") - - # Failed Logins -- bad_pwd_map = db.result['bad_pwd_map'] -+ bad_pwd_map = db.result.bad_pwd_map - bad_pwd_map_len = len(bad_pwd_map) - if bad_pwd_map_len > 0: - print(f"\n----- Top {db.size_limit} Failed Logins ------\n") -@@ -2495,27 +2584,27 @@ def main(): - print(f"{count:<10} {ip}") - - # Connection Codes -- disconnect_codes = db.connection['disconnect_code'] -+ disconnect_codes = db.connection.disconnect_code - if len(disconnect_codes) > 0: - print(f"\n----- Total Connection Codes ----\n") - for code in disconnect_codes: - print(f"{code:<2} {disconnect_codes[code]:>10} {DISCONNECT_MSG.get(code, 'unknown'):<30}") - - # Unique IPs -- restart_conn_ip_map = db.connection['restart_conn_ip_map'] -- ip_map = db.connection['ip_map'] -- ips_len = len(ip_map) -+ restart_conn_ip_map = db.connection.restart_conn_ip_map -+ src_ip_map = db.connection.src_ip_map -+ ips_len = len(src_ip_map) - if ips_len > 0: - print(f"\n----- Top {db.size_limit} Clients -----\n") - print(f"Number of Clients: {ips_len}") -- for num, (outer_ip, ip_info) in enumerate(ip_map.items(), start=1): -+ for num, (outer_ip, ip_info) in enumerate(src_ip_map.items(), start=1): - temp = {} - print(f"\n[{num}] Client: {outer_ip}") - print(f" {ip_info['count']} - Connection{'s' if ip_info['count'] > 1 else ''}") - for id, inner_ip in restart_conn_ip_map.items(): - (src, conn) = id - if outer_ip == inner_ip: -- code = db.connection['disconnect_code_map'].get((src, conn), 0) -+ code = db.connection.restart_conn_disconnect_map[(src, conn)] - if code: - temp[code] = temp.get(code, 0) + 1 - for code, count in temp.items(): -@@ -2524,7 +2613,7 @@ def main(): - break - - # Unique Bind DN's -- binds = db.bind.get('dn_freq', 0) -+ binds = db.bind.dns - binds_len = len(binds) - if binds_len > 0: - print(f"\n----- Top {db.size_limit} Bind DN's ----\n") -@@ -2532,10 +2621,10 @@ def main(): - for num, bind in enumerate(sorted(binds.keys(), key=lambda k: binds[k], reverse=True)): - if num >= db.size_limit: - break -- print(f"{db.bind['dn_freq'][bind]:<10} {bind:<30}") -+ print(f"{db.bind.dns[bind]:<10} {bind:<30}") - - # Unique search bases -- bases = db.search['base_map'] -+ bases = db.search.bases - num_bases = len(bases) - if num_bases > 0: - print(f"\n----- Top {db.size_limit} Search Bases -----\n") -@@ -2543,10 +2632,10 @@ def main(): - for num, base in enumerate(sorted(bases.keys(), key=lambda k: bases[k], reverse=True)): - if num >= db.size_limit: - break -- print(f"{db.search['base_map'][base]:<10} {base}") -+ print(f"{db.search.bases[base]:<10} {base}") - - # Unique search filters -- filters = sorted(db.search['filter_list'], reverse=True) -+ filters = sorted(db.search.filter_list, reverse=True) - num_filters = len(filters) - if num_filters > 0: - print(f"\n----- Top {db.size_limit} Search Filters -----\n") -@@ -2556,7 +2645,7 @@ def main(): - print(f"{count:<10} {filter}") - - # Longest elapsed times -- etimes = sorted(db.result['etime_duration'], reverse=True) -+ etimes = sorted(db.result.etime_duration, reverse=True) - num_etimes = len(etimes) - if num_etimes > 0: - print(f"\n----- Top {db.size_limit} Longest etimes (elapsed times) -----\n") -@@ -2566,7 +2655,7 @@ def main(): - print(f"etime={etime:<12}") - - # Longest wait times -- wtimes = sorted(db.result['wtime_duration'], reverse=True) -+ wtimes = sorted(db.result.wtime_duration, reverse=True) - num_wtimes = len(wtimes) - if num_wtimes > 0: - print(f"\n----- Top {db.size_limit} Longest wtimes (wait times) -----\n") -@@ -2576,7 +2665,7 @@ def main(): - print(f"wtime={wtime:<12}") - - # Longest operation times -- optimes = sorted(db.result['optime_duration'], reverse=True) -+ optimes = sorted(db.result.optime_duration, reverse=True) - num_optimes = len(optimes) - if num_optimes > 0: - print(f"\n----- Top {db.size_limit} Longest optimes (actual operation times) -----\n") -@@ -2586,7 +2675,7 @@ def main(): - print(f"optime={optime:<12}") - - # Largest nentries returned -- nentries = sorted(db.result['nentries_num'], reverse=True) -+ nentries = sorted(db.result.nentries_num, reverse=True) - num_nentries = len(nentries) - if num_nentries > 0: - print(f"\n----- Top {db.size_limit} Largest nentries -----\n") -@@ -2597,7 +2686,7 @@ def main(): - print() - - # Extended operations -- oids = db.operation['extop_dict'] -+ oids = db.operation.extended - num_oids = len(oids) - if num_oids > 0: - print(f"\n----- Top {db.size_limit} Extended Operations -----\n") -@@ -2607,7 +2696,7 @@ def main(): - print(f"{oids[oid]:<12} {oid:<30} {OID_MSG.get(oid, 'Other'):<60}") - - # Commonly requested attributes -- attrs = db.search['attr_dict'] -+ attrs = db.search.attrs - num_nattrs = len(attrs) - if num_nattrs > 0: - print(f"\n----- Top {db.size_limit} Most Requested Attributes -----\n") -@@ -2617,14 +2706,14 @@ def main(): - print(f"{attrs[attr]:<11} {attr:<10}") - print() - -- abandoned = db.operation['abandoned_map_rco'] -+ abandoned = db.operation.rst_con_op_map['abandon'] - num_abandoned = len(abandoned) - if num_abandoned > 0: - print(f"\n----- Abandon Request Stats -----\n") - for num, abandon in enumerate(abandoned, start=1): - (restart, conn, op) = abandon -- conn, op, target_op, msgid = db.operation['abandoned_map_rco'][(restart, conn, op)] -- print(f"{num:<6} conn={conn} op={op} msgid={msgid} target_op:{target_op} client={db.connection['restart_conn_ip_map'].get((restart, conn), 'Unknown')}") -+ conn, op, target_op, msgid = db.operation.rst_con_op_map['abandoned'][(restart, conn, op)] -+ print(f"{num:<6} conn={conn} op={op} msgid={msgid} target_op:{target_op} client={db.connection.restart_conn_ip_map.get((restart, conn), 'Unknown')}") - print() - - if db.recommends or db.verbose: -@@ -2639,15 +2728,15 @@ def main(): - print(f"\n {rec_count}. You have unindexed components. This can be caused by a search on an unindexed attribute or by returned results exceeding the nsslapd-idlistscanlimit. Unindexed components are not recommended. To refuse unindexed searches, set 'nsslapd-require-index' to 'on' under your database entry (e.g. cn=UserRoot,cn=ldbm database,cn=plugins,cn=config).\n") - rec_count += 1 - -- if db.connection['disconnect_code'].get('T1', 0) > 0: -+ if db.connection.disconnect_code.get('T1', 0) > 0: - print(f"\n {rec_count}. You have some connections being closed by the idletimeout setting. You may want to increase the idletimeout if it is set low.\n") - rec_count += 1 - -- if db.connection['disconnect_code'].get('T2', 0) > 0: -+ if db.connection.disconnect_code.get('T2', 0) > 0: - print(f"\n {rec_count}. You have some connections being closed by the ioblocktimeout setting. You may want to increase the ioblocktimeout.\n") - rec_count += 1 - -- if db.connection['disconnect_code'].get('T3', 0) > 0: -+ if db.connection.disconnect_code.get('T3', 0) > 0: - print(f"\n {rec_count}. You have some connections being closed because a paged result search limit has been exceeded. You may want to increase the search time limit.\n") - rec_count += 1 - -@@ -2663,29 +2752,29 @@ def main(): - print(f"\n {rec_count}. You have a high number of Directory Manager binds. The Directory Manager account should only be used under certain circumstances. Avoid using this account for client applications.\n") - rec_count += 1 - -- num_success = db.result['error_freq'].get('0', 0) -- num_err = sum(v for k, v in db.result['error_freq'].items() if k != '0') -+ num_success = db.result.error_freq.get('0', 0) -+ num_err = sum(v for k, v in db.result.error_freq.items() if k != '0') - if num_err > num_success: - print(f"\n {rec_count}. You have more unsuccessful operations than successful operations. You should investigate this difference.\n") - rec_count += 1 - -- num_close_clean = db.connection['disconnect_code'].get('U1', 0) -- num_close_total = num_err = sum(v for k, v in db.connection['disconnect_code'].items()) -+ num_close_clean = db.connection.disconnect_code.get('U1', 0) -+ num_close_total = num_err = sum(v for k, v in db.connection.disconnect_code.items()) - if num_close_clean < (num_close_total - num_close_clean): - print(f"\n {rec_count}. You have more abnormal connection codes than cleanly closed connections. You may want to investigate this difference.\n") - rec_count += 1 - - if num_time_count: -- if round(avg_etime, 1) > 0: -- print(f"\n {rec_count}. Your average etime is {avg_etime:.1f}. You may want to investigate this performance problem.\n") -+ if round(avg_etime, 9) > 0: -+ print(f"\n {rec_count}. Your average etime is {avg_etime:.9f}. You may want to investigate this performance problem.\n") - rec_count += 1 - -- if round(avg_wtime, 1) > 0.5: -- print(f"\n {rec_count}. Your average wtime is {avg_wtime:.1f}. You may need to increase the number of worker threads (nsslapd-threadnumber).\n") -+ if round(avg_wtime, 9) > 0.5: -+ print(f"\n {rec_count}. Your average wtime is {avg_wtime:.9f}. You may need to increase the number of worker threads (nsslapd-threadnumber).\n") - rec_count += 1 - -- if round(avg_optime, 1) > 0: -- print(f"\n {rec_count}. Your average optime is {avg_optime:.1f}. You may want to investigate this performance problem.\n") -+ if round(avg_optime, 9) > 0: -+ print(f"\n {rec_count}. Your average optime is {avg_optime:.9f}. You may want to investigate this performance problem.\n") - rec_count += 1 - - if num_base_search > (num_search * 0.25): -@@ -2699,4 +2788,4 @@ def main(): - - - if __name__ == "__main__": -- main() -+ main() -\ No newline at end of file --- -2.49.0 - diff --git a/0007-Issue-6850-AddressSanitizer-memory-leak-in-mdb_init.patch b/0007-Issue-6850-AddressSanitizer-memory-leak-in-mdb_init.patch deleted file mode 100644 index 34034e4..0000000 --- a/0007-Issue-6850-AddressSanitizer-memory-leak-in-mdb_init.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 9d851a63c9f714ba896a90119560246bf49a433c Mon Sep 17 00:00:00 2001 -From: Viktor Ashirov -Date: Mon, 7 Jul 2025 23:11:17 +0200 -Subject: [PATCH] Issue 6850 - AddressSanitizer: memory leak in mdb_init - -Bug Description: -`dbmdb_componentid` can be allocated multiple times. To avoid a memory -leak, allocate it only once, and free at the cleanup. - -Fixes: https://github.com/389ds/389-ds-base/issues/6850 - -Reviewed by: @mreynolds389, @tbordaz (Tnanks!) ---- - ldap/servers/slapd/back-ldbm/db-mdb/mdb_config.c | 4 +++- - ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c | 2 +- - ldap/servers/slapd/back-ldbm/db-mdb/mdb_misc.c | 5 +++++ - 3 files changed, 9 insertions(+), 2 deletions(-) - -diff --git a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_config.c b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_config.c -index 447f3c70a..54ca03b0b 100644 ---- a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_config.c -+++ b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_config.c -@@ -146,7 +146,9 @@ dbmdb_compute_limits(struct ldbminfo *li) - int mdb_init(struct ldbminfo *li, config_info *config_array) - { - dbmdb_ctx_t *conf = (dbmdb_ctx_t *)slapi_ch_calloc(1, sizeof(dbmdb_ctx_t)); -- dbmdb_componentid = generate_componentid(NULL, "db-mdb"); -+ if (dbmdb_componentid == NULL) { -+ dbmdb_componentid = generate_componentid(NULL, "db-mdb"); -+ } - - li->li_dblayer_config = conf; - strncpy(conf->home, li->li_directory, MAXPATHLEN-1); -diff --git a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c -index c4e87987f..ed17f979f 100644 ---- a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c -+++ b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c -@@ -19,7 +19,7 @@ - #include - #include - --Slapi_ComponentId *dbmdb_componentid; -+Slapi_ComponentId *dbmdb_componentid = NULL; - - #define BULKOP_MAX_RECORDS 100 /* Max records handled by a single bulk operations */ - -diff --git a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_misc.c b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_misc.c -index 2d07db9b5..ae10ac7cf 100644 ---- a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_misc.c -+++ b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_misc.c -@@ -49,6 +49,11 @@ dbmdb_cleanup(struct ldbminfo *li) - } - slapi_ch_free((void **)&(li->li_dblayer_config)); - -+ if (dbmdb_componentid != NULL) { -+ release_componentid(dbmdb_componentid); -+ dbmdb_componentid = NULL; -+ } -+ - return 0; - } - --- -2.49.0 - diff --git a/0008-Issue-6848-AddressSanitizer-leak-in-do_search.patch b/0008-Issue-6848-AddressSanitizer-leak-in-do_search.patch deleted file mode 100644 index 618c459..0000000 --- a/0008-Issue-6848-AddressSanitizer-leak-in-do_search.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 510e0e9b35d94714048a06bc5067d43704f55503 Mon Sep 17 00:00:00 2001 -From: Viktor Ashirov -Date: Mon, 7 Jul 2025 22:01:09 +0200 -Subject: [PATCH] Issue 6848 - AddressSanitizer: leak in do_search - -Bug Description: -When there's a BER decoding error and the function goes to -`free_and_return`, the `attrs` variable is not being freed because it's -only freed if `!psearch || rc != 0 || err != 0`, but `err` is still 0 at -that point. - -If we reach `free_and_return` from the `ber_scanf` error path, `attrs` -was never set in the pblock with `slapi_pblock_set()`, so the -`slapi_pblock_get()` call will not retrieve the potentially partially -allocated `attrs` from the BER decoding. - -Fixes: https://github.com/389ds/389-ds-base/issues/6848 - -Reviewed by: @tbordaz, @droideck (Thanks!) ---- - ldap/servers/slapd/search.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/ldap/servers/slapd/search.c b/ldap/servers/slapd/search.c -index e9b2c3670..f9d03c090 100644 ---- a/ldap/servers/slapd/search.c -+++ b/ldap/servers/slapd/search.c -@@ -235,6 +235,7 @@ do_search(Slapi_PBlock *pb) - log_search_access(pb, base, scope, fstr, "decoding error"); - send_ldap_result(pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, - NULL); -+ err = 1; /* Make sure we free everything */ - goto free_and_return; - } - -@@ -420,8 +421,17 @@ free_and_return: - if (!psearch || rc != 0 || err != 0) { - slapi_ch_free_string(&fstr); - slapi_filter_free(filter, 1); -- slapi_pblock_get(pb, SLAPI_SEARCH_ATTRS, &attrs); -- charray_free(attrs); /* passing NULL is fine */ -+ -+ /* Get attrs from pblock if it was set there, otherwise use local attrs */ -+ char **pblock_attrs = NULL; -+ slapi_pblock_get(pb, SLAPI_SEARCH_ATTRS, &pblock_attrs); -+ if (pblock_attrs != NULL) { -+ charray_free(pblock_attrs); /* Free attrs from pblock */ -+ slapi_pblock_set(pb, SLAPI_SEARCH_ATTRS, NULL); -+ } else if (attrs != NULL) { -+ /* Free attrs that were allocated but never put in pblock */ -+ charray_free(attrs); -+ } - charray_free(gerattrs); /* passing NULL is fine */ - /* - * Fix for defect 526719 / 553356 : Persistent search op failed. --- -2.49.0 - diff --git a/0009-Issue-6865-AddressSanitizer-leak-in-agmt_update_init.patch b/0009-Issue-6865-AddressSanitizer-leak-in-agmt_update_init.patch deleted file mode 100644 index e2823b5..0000000 --- a/0009-Issue-6865-AddressSanitizer-leak-in-agmt_update_init.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 7b3cd3147a8d3c41327768689962730d8fa28797 Mon Sep 17 00:00:00 2001 -From: Viktor Ashirov -Date: Fri, 11 Jul 2025 12:32:38 +0200 -Subject: [PATCH] Issue 6865 - AddressSanitizer: leak in - agmt_update_init_status - -Bug Description: -We allocate an array of `LDAPMod *` pointers, but never free it: - -``` -================================================================= -==2748356==ERROR: LeakSanitizer: detected memory leaks - -Direct leak of 24 byte(s) in 1 object(s) allocated from: - #0 0x7f05e8cb4a07 in __interceptor_malloc (/lib64/libasan.so.6+0xb4a07) - #1 0x7f05e85c0138 in slapi_ch_malloc (/usr/lib64/dirsrv/libslapd.so.0+0x1c0138) - #2 0x7f05e109e481 in agmt_update_init_status ldap/servers/plugins/replication/repl5_agmt.c:2583 - #3 0x7f05e10a0aa5 in agmtlist_shutdown ldap/servers/plugins/replication/repl5_agmtlist.c:789 - #4 0x7f05e10ab6bc in multisupplier_stop ldap/servers/plugins/replication/repl5_init.c:844 - #5 0x7f05e10ab6bc in multisupplier_stop ldap/servers/plugins/replication/repl5_init.c:837 - #6 0x7f05e862507d in plugin_call_func ldap/servers/slapd/plugin.c:2001 - #7 0x7f05e8625be1 in plugin_call_one ldap/servers/slapd/plugin.c:1950 - #8 0x7f05e8625be1 in plugin_dependency_closeall ldap/servers/slapd/plugin.c:1844 - #9 0x55e1a7ff9815 in slapd_daemon ldap/servers/slapd/daemon.c:1275 - #10 0x55e1a7fd36ef in main (/usr/sbin/ns-slapd+0x3e6ef) - #11 0x7f05e80295cf in __libc_start_call_main (/lib64/libc.so.6+0x295cf) - #12 0x7f05e802967f in __libc_start_main_alias_2 (/lib64/libc.so.6+0x2967f) - #13 0x55e1a7fd74a4 in _start (/usr/sbin/ns-slapd+0x424a4) - -SUMMARY: AddressSanitizer: 24 byte(s) leaked in 1 allocation(s). -``` - -Fix Description: -Ensure `mods` is freed in the cleanup code. - -Fixes: https://github.com/389ds/389-ds-base/issues/6865 -Relates: https://github.com/389ds/389-ds-base/issues/6470 - -Reviewed by: @mreynolds389 (Thanks!) ---- - ldap/servers/plugins/replication/repl5_agmt.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c -index c818c5857..0a81167b7 100644 ---- a/ldap/servers/plugins/replication/repl5_agmt.c -+++ b/ldap/servers/plugins/replication/repl5_agmt.c -@@ -2743,6 +2743,7 @@ agmt_update_init_status(Repl_Agmt *ra) - } else { - PR_Unlock(ra->lock); - } -+ slapi_ch_free((void **)&mods); - slapi_mod_done(&smod_start_time); - slapi_mod_done(&smod_end_time); - slapi_mod_done(&smod_status); --- -2.49.0 - diff --git a/0010-Issue-6868-UI-schema-attribute-table-expansion-break.patch b/0010-Issue-6868-UI-schema-attribute-table-expansion-break.patch deleted file mode 100644 index 5cd424c..0000000 --- a/0010-Issue-6868-UI-schema-attribute-table-expansion-break.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 81af69f415ffdf48861de00ba9a60614c0a02a87 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Fri, 11 Jul 2025 13:49:25 -0400 -Subject: [PATCH] Issue 6868 - UI - schema attribute table expansion break - after moving to a new page - -Description: - -Used the wrong formula to select the expanded row for Attributes - -Relates: https://github.com/389ds/389-ds-base/issues/6868 - -Reviewed by: spichugi(Thanks!) ---- - src/cockpit/389-console/src/lib/database/databaseConfig.jsx | 1 - - src/cockpit/389-console/src/lib/schema/schemaTables.jsx | 4 ++-- - 2 files changed, 2 insertions(+), 3 deletions(-) - -diff --git a/src/cockpit/389-console/src/lib/database/databaseConfig.jsx b/src/cockpit/389-console/src/lib/database/databaseConfig.jsx -index adb8227d7..7a1ce3bc2 100644 ---- a/src/cockpit/389-console/src/lib/database/databaseConfig.jsx -+++ b/src/cockpit/389-console/src/lib/database/databaseConfig.jsx -@@ -8,7 +8,6 @@ import { - Form, - Grid, - GridItem, -- Hr, - NumberInput, - Spinner, - Switch, -diff --git a/src/cockpit/389-console/src/lib/schema/schemaTables.jsx b/src/cockpit/389-console/src/lib/schema/schemaTables.jsx -index 609d4af15..446931ac2 100644 ---- a/src/cockpit/389-console/src/lib/schema/schemaTables.jsx -+++ b/src/cockpit/389-console/src/lib/schema/schemaTables.jsx -@@ -465,7 +465,7 @@ class AttributesTable extends React.Component { - - handleCollapse(event, rowKey, isOpen) { - const { rows, perPage, page } = this.state; -- const index = (perPage * (page - 1) * 2) + rowKey; // Adjust for page set -+ const index = (perPage * (page - 1)) + rowKey; // Adjust for page set - rows[index].isOpen = isOpen; - this.setState({ - rows -@@ -525,7 +525,7 @@ class AttributesTable extends React.Component { - ]; - - render() { -- const { perPage, page, sortBy, rows, noRows, columns } = this.state; -+ const { perPage, page, sortBy, rows, columns } = this.state; - const startIdx = (perPage * page) - perPage; - const tableRows = rows.slice(startIdx, startIdx + perPage); - --- -2.49.0 - diff --git a/0011-Issue-6859-str2filter-is-not-fully-applying-matching.patch b/0011-Issue-6859-str2filter-is-not-fully-applying-matching.patch deleted file mode 100644 index 8263631..0000000 --- a/0011-Issue-6859-str2filter-is-not-fully-applying-matching.patch +++ /dev/null @@ -1,169 +0,0 @@ -From e4bd0eb2a4ad612efbf7824da022dd5403c71684 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Wed, 9 Jul 2025 14:18:50 -0400 -Subject: [PATCH] Issue 6859 - str2filter is not fully applying matching rules - -Description: - -When we have an extended filter, one with a MR applied, it is ignored during -internal searches: - - "(cn:CaseExactMatch:=Value)" - -For internal searches we use str2filter() and it doesn't fully apply extended -search filter matching rules - -Also needed to update attr uniqueness plugin to apply this change for mod -operations (previously only Adds were correctly handling these attribute -filters) - -Relates: https://github.com/389ds/389-ds-base/issues/6857 -Relates: https://github.com/389ds/389-ds-base/issues/6859 - -Reviewed by: spichugi & tbordaz(Thanks!!) ---- - .../tests/suites/plugins/attruniq_test.py | 65 ++++++++++++++++++- - ldap/servers/plugins/uiduniq/uid.c | 7 ++ - ldap/servers/slapd/plugin_mr.c | 2 +- - ldap/servers/slapd/str2filter.c | 8 +++ - 4 files changed, 79 insertions(+), 3 deletions(-) - -diff --git a/dirsrvtests/tests/suites/plugins/attruniq_test.py b/dirsrvtests/tests/suites/plugins/attruniq_test.py -index aac659c29..046952df3 100644 ---- a/dirsrvtests/tests/suites/plugins/attruniq_test.py -+++ b/dirsrvtests/tests/suites/plugins/attruniq_test.py -@@ -1,5 +1,5 @@ - # --- BEGIN COPYRIGHT BLOCK --- --# Copyright (C) 2021 Red Hat, Inc. -+# Copyright (C) 2025 Red Hat, Inc. - # All rights reserved. - # - # License: GPL (version 3 or any later version). -@@ -324,4 +324,65 @@ def test_exclude_subtrees(topology_st): - cont2.delete() - cont3.delete() - attruniq.disable() -- attruniq.delete() -\ No newline at end of file -+ attruniq.delete() -+ -+ -+def test_matchingrule_attr(topology_st): -+ """ Test list extension MR attribute. Check for "cn" using CES (versus it -+ being defined as CIS) -+ -+ :id: 5cde4342-6fa3-4225-b23d-0af918981075 -+ :setup: Standalone instance -+ :steps: -+ 1. Setup and enable attribute uniqueness plugin to use CN attribute -+ with a matching rule of CaseExactMatch. -+ 2. Add user with CN value is lowercase -+ 3. Add second user with same lowercase CN which should be rejected -+ 4. Add second user with same CN value but with mixed case -+ 5. Modify second user replacing CN value to lc which should be rejected -+ -+ :expectedresults: -+ 1. Success -+ 2. Success -+ 3. Success -+ 4. Success -+ 5. Success -+ """ -+ -+ inst = topology_st.standalone -+ -+ attruniq = AttributeUniquenessPlugin(inst, -+ dn="cn=attribute uniqueness,cn=plugins,cn=config") -+ attruniq.add_unique_attribute('cn:CaseExactMatch:') -+ attruniq.enable_all_subtrees() -+ attruniq.enable() -+ inst.restart() -+ -+ users = UserAccounts(inst, DEFAULT_SUFFIX) -+ users.create(properties={'cn': "common_name", -+ 'uid': "uid_name", -+ 'sn': "uid_name", -+ 'uidNumber': '1', -+ 'gidNumber': '11', -+ 'homeDirectory': '/home/uid_name'}) -+ -+ log.info('Add entry with the exact CN value which should be rejected') -+ with pytest.raises(ldap.CONSTRAINT_VIOLATION): -+ users.create(properties={'cn': "common_name", -+ 'uid': "uid_name2", -+ 'sn': "uid_name2", -+ 'uidNumber': '11', -+ 'gidNumber': '111', -+ 'homeDirectory': '/home/uid_name2'}) -+ -+ log.info('Add entry with the mixed case CN value which should be allowed') -+ user = users.create(properties={'cn': "Common_Name", -+ 'uid': "uid_name2", -+ 'sn': "uid_name2", -+ 'uidNumber': '11', -+ 'gidNumber': '111', -+ 'homeDirectory': '/home/uid_name2'}) -+ -+ log.info('Mod entry with exact case CN value which should be rejected') -+ with pytest.raises(ldap.CONSTRAINT_VIOLATION): -+ user.replace('cn', 'common_name') -diff --git a/ldap/servers/plugins/uiduniq/uid.c b/ldap/servers/plugins/uiduniq/uid.c -index 887e79d78..fdb1404a0 100644 ---- a/ldap/servers/plugins/uiduniq/uid.c -+++ b/ldap/servers/plugins/uiduniq/uid.c -@@ -1178,6 +1178,10 @@ preop_modify(Slapi_PBlock *pb) - for (; mods && *mods; mods++) { - mod = *mods; - for (i = 0; attrNames && attrNames[i]; i++) { -+ char *attr_match = strchr(attrNames[i], ':'); -+ if (attr_match != NULL) { -+ attr_match[0] = '\0'; -+ } - if ((slapi_attr_type_cmp(mod->mod_type, attrNames[i], 1) == 0) && /* mod contains target attr */ - (mod->mod_op & LDAP_MOD_BVALUES) && /* mod is bval encoded (not string val) */ - (mod->mod_bvalues && mod->mod_bvalues[0]) && /* mod actually contains some values */ -@@ -1186,6 +1190,9 @@ preop_modify(Slapi_PBlock *pb) - { - addMod(&checkmods, &checkmodsCapacity, &modcount, mod); - } -+ if (attr_match != NULL) { -+ attr_match[0] = ':'; -+ } - } - } - if (modcount == 0) { -diff --git a/ldap/servers/slapd/plugin_mr.c b/ldap/servers/slapd/plugin_mr.c -index 9809a4374..757355dbc 100644 ---- a/ldap/servers/slapd/plugin_mr.c -+++ b/ldap/servers/slapd/plugin_mr.c -@@ -625,7 +625,7 @@ attempt_mr_filter_create(mr_filter_t *f, struct slapdplugin *mrp, Slapi_PBlock * - int rc; - int32_t (*mrf_create)(Slapi_PBlock *) = NULL; - f->mrf_match = NULL; -- pblock_init(pb); -+ slapi_pblock_init(pb); - if (!(rc = slapi_pblock_set(pb, SLAPI_PLUGIN, mrp)) && - !(rc = slapi_pblock_get(pb, SLAPI_PLUGIN_MR_FILTER_CREATE_FN, &mrf_create)) && - mrf_create != NULL && -diff --git a/ldap/servers/slapd/str2filter.c b/ldap/servers/slapd/str2filter.c -index 9fdc500f7..5620b7439 100644 ---- a/ldap/servers/slapd/str2filter.c -+++ b/ldap/servers/slapd/str2filter.c -@@ -344,6 +344,14 @@ str2simple(char *str, int unescape_filter) - return NULL; /* error */ - } else { - f->f_choice = LDAP_FILTER_EXTENDED; -+ if (f->f_mr_oid) { -+ /* apply the MR indexers */ -+ rc = plugin_mr_filter_create(&f->f_mr); -+ if (rc) { -+ slapi_filter_free(f, 1); -+ return NULL; /* error */ -+ } -+ } - } - } else if (str_find_star(value) == NULL) { - f->f_choice = LDAP_FILTER_EQUALITY; --- -2.49.0 - diff --git a/0012-Issue-6872-compressed-log-rotation-creates-files-wit.patch b/0012-Issue-6872-compressed-log-rotation-creates-files-wit.patch deleted file mode 100644 index b4c0445..0000000 --- a/0012-Issue-6872-compressed-log-rotation-creates-files-wit.patch +++ /dev/null @@ -1,163 +0,0 @@ -From 48e7696fbebc14220b4b9a831c4a170003586152 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Tue, 15 Jul 2025 17:56:18 -0400 -Subject: [PATCH] Issue 6872 - compressed log rotation creates files with world - readable permission - -Description: - -When compressing a log file, first create the empty file using open() -so we can set the correct permissions right from the start. gzopen() -always uses permission 644 and that is not safe. So after creating it -with open(), with the correct permissions, then pass the FD to gzdopen() -and write the compressed content. - -relates: https://github.com/389ds/389-ds-base/issues/6872 - -Reviewed by: progier(Thanks!) ---- - .../logging/logging_compression_test.py | 15 ++++++++-- - ldap/servers/slapd/log.c | 28 +++++++++++++------ - ldap/servers/slapd/schema.c | 2 +- - 3 files changed, 33 insertions(+), 12 deletions(-) - -diff --git a/dirsrvtests/tests/suites/logging/logging_compression_test.py b/dirsrvtests/tests/suites/logging/logging_compression_test.py -index e30874cc0..3a987d62c 100644 ---- a/dirsrvtests/tests/suites/logging/logging_compression_test.py -+++ b/dirsrvtests/tests/suites/logging/logging_compression_test.py -@@ -1,5 +1,5 @@ - # --- BEGIN COPYRIGHT BLOCK --- --# Copyright (C) 2022 Red Hat, Inc. -+# Copyright (C) 2025 Red Hat, Inc. - # All rights reserved. - # - # License: GPL (version 3 or any later version). -@@ -22,12 +22,21 @@ log = logging.getLogger(__name__) - - pytestmark = pytest.mark.tier1 - -+ - def log_rotated_count(log_type, log_dir, check_compressed=False): -- # Check if the log was rotated -+ """ -+ Check if the log was rotated and has the correct permissions -+ """ - log_file = f'{log_dir}/{log_type}.2*' - if check_compressed: - log_file += ".gz" -- return len(glob.glob(log_file)) -+ log_files = glob.glob(log_file) -+ for logf in log_files: -+ # Check permissions -+ st = os.stat(logf) -+ assert oct(st.st_mode) == '0o100600' # 0600 -+ -+ return len(log_files) - - - def update_and_sleep(inst, suffix, sleep=True): -diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c -index 06dae4d0b..eab837166 100644 ---- a/ldap/servers/slapd/log.c -+++ b/ldap/servers/slapd/log.c -@@ -174,17 +174,28 @@ get_syslog_loglevel(int loglevel) - } - - static int --compress_log_file(char *log_name) -+compress_log_file(char *log_name, int32_t mode) - { - char gzip_log[BUFSIZ] = {0}; - char buf[LOG_CHUNK] = {0}; - size_t bytes_read = 0; - gzFile outfile = NULL; - FILE *source = NULL; -+ int fd = 0; - - PR_snprintf(gzip_log, sizeof(gzip_log), "%s.gz", log_name); -- if ((outfile = gzopen(gzip_log,"wb")) == NULL) { -- /* Failed to open new gzip file */ -+ -+ /* -+ * Try to open the file as we may have an incorrect path. We also need to -+ * set the permissions using open() as gzopen() creates the file with -+ * 644 permissions (world readable - bad). So we create an empty file with -+ * the correct permissions, then we pass the FD to gzdopen() to write the -+ * compressed content. -+ */ -+ if ((fd = open(gzip_log, O_WRONLY|O_CREAT|O_TRUNC, mode)) >= 0) { -+ /* FIle successfully created, now pass the FD to gzdopen() */ -+ outfile = gzdopen(fd, "ab"); -+ } else { - return -1; - } - -@@ -193,6 +204,7 @@ compress_log_file(char *log_name) - gzclose(outfile); - return -1; - } -+ - bytes_read = fread(buf, 1, LOG_CHUNK, source); - while (bytes_read > 0) { - int bytes_written = gzwrite(outfile, buf, bytes_read); -@@ -3402,7 +3414,7 @@ log__open_accesslogfile(int logfile_state, int locked) - return LOG_UNABLE_TO_OPENFILE; - } - } else if (loginfo.log_access_compress) { -- if (compress_log_file(newfile) != 0) { -+ if (compress_log_file(newfile, loginfo.log_access_mode) != 0) { - slapi_log_err(SLAPI_LOG_ERR, "log__open_auditfaillogfile", - "failed to compress rotated access log (%s)\n", - newfile); -@@ -3570,7 +3582,7 @@ log__open_securitylogfile(int logfile_state, int locked) - return LOG_UNABLE_TO_OPENFILE; - } - } else if (loginfo.log_security_compress) { -- if (compress_log_file(newfile) != 0) { -+ if (compress_log_file(newfile, loginfo.log_security_mode) != 0) { - slapi_log_err(SLAPI_LOG_ERR, "log__open_securitylogfile", - "failed to compress rotated security audit log (%s)\n", - newfile); -@@ -6288,7 +6300,7 @@ log__open_errorlogfile(int logfile_state, int locked) - return LOG_UNABLE_TO_OPENFILE; - } - } else if (loginfo.log_error_compress) { -- if (compress_log_file(newfile) != 0) { -+ if (compress_log_file(newfile, loginfo.log_error_mode) != 0) { - PR_snprintf(buffer, sizeof(buffer), "Failed to compress errors log file (%s)\n", newfile); - log__error_emergency(buffer, 1, 1); - } else { -@@ -6476,7 +6488,7 @@ log__open_auditlogfile(int logfile_state, int locked) - return LOG_UNABLE_TO_OPENFILE; - } - } else if (loginfo.log_audit_compress) { -- if (compress_log_file(newfile) != 0) { -+ if (compress_log_file(newfile, loginfo.log_audit_mode) != 0) { - slapi_log_err(SLAPI_LOG_ERR, "log__open_auditfaillogfile", - "failed to compress rotated audit log (%s)\n", - newfile); -@@ -6641,7 +6653,7 @@ log__open_auditfaillogfile(int logfile_state, int locked) - return LOG_UNABLE_TO_OPENFILE; - } - } else if (loginfo.log_auditfail_compress) { -- if (compress_log_file(newfile) != 0) { -+ if (compress_log_file(newfile, loginfo.log_auditfail_mode) != 0) { - slapi_log_err(SLAPI_LOG_ERR, "log__open_auditfaillogfile", - "failed to compress rotated auditfail log (%s)\n", - newfile); -diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c -index a8e6b1210..9ef4ee4bf 100644 ---- a/ldap/servers/slapd/schema.c -+++ b/ldap/servers/slapd/schema.c -@@ -903,7 +903,7 @@ oc_check_allowed_sv(Slapi_PBlock *pb, Slapi_Entry *e, const char *type, struct o - - if (pb) { - PR_snprintf(errtext, sizeof(errtext), -- "attribute \"%s\" not allowed\n", -+ "attribute \"%s\" not allowed", - escape_string(type, ebuf)); - slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, errtext); - } --- -2.49.0 - diff --git a/0013-Issue-6888-Missing-access-JSON-logging-for-TLS-Clien.patch b/0013-Issue-6888-Missing-access-JSON-logging-for-TLS-Clien.patch deleted file mode 100644 index 0327c55..0000000 --- a/0013-Issue-6888-Missing-access-JSON-logging-for-TLS-Clien.patch +++ /dev/null @@ -1,590 +0,0 @@ -From a8fe12fcfbe0f81935972c3eddae638a281551d1 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Wed, 16 Jul 2025 20:54:48 -0400 -Subject: [PATCH] Issue 6888 - Missing access JSON logging for TLS/Client auth - -Description: - -TLS/Client auth logging was not converted to JSON (auth.c got missed) - -Relates: https://github.com/389ds/389-ds-base/issues/6888 - -Reviewed by: spichugi(Thanks!) ---- - .../logging/access_json_logging_test.py | 96 ++++++++- - ldap/servers/slapd/accesslog.c | 114 +++++++++++ - ldap/servers/slapd/auth.c | 182 +++++++++++++----- - ldap/servers/slapd/log.c | 2 + - ldap/servers/slapd/slapi-private.h | 10 + - 5 files changed, 353 insertions(+), 51 deletions(-) - -diff --git a/dirsrvtests/tests/suites/logging/access_json_logging_test.py b/dirsrvtests/tests/suites/logging/access_json_logging_test.py -index ae91dc487..f0dc861a7 100644 ---- a/dirsrvtests/tests/suites/logging/access_json_logging_test.py -+++ b/dirsrvtests/tests/suites/logging/access_json_logging_test.py -@@ -19,6 +19,8 @@ from lib389.idm.user import UserAccounts - from lib389.dirsrv_log import DirsrvAccessJSONLog - from lib389.index import VLVSearch, VLVIndex - from lib389.tasks import Tasks -+from lib389.config import CertmapLegacy -+from lib389.nss_ssl import NssSsl - from ldap.controls.vlv import VLVRequestControl - from ldap.controls.sss import SSSRequestControl - from ldap.controls import SimplePagedResultsControl -@@ -67,11 +69,11 @@ def get_log_event(inst, op, key=None, val=None, key2=None, val2=None): - if val == str(event[key]).lower() and \ - val2 == str(event[key2]).lower(): - return event -- -- elif key is not None and key in event: -- val = str(val).lower() -- if val == str(event[key]).lower(): -- return event -+ elif key is not None: -+ if key in event: -+ val = str(val).lower() -+ if val == str(event[key]).lower(): -+ return event - else: - return event - -@@ -163,6 +165,7 @@ def test_access_json_format(topo_m2, setup_test): - 14. Test PAGED SEARCH is logged correctly - 15. Test PERSISTENT SEARCH is logged correctly - 16. Test EXTENDED OP -+ 17. Test TLS_INFO is logged correctly - :expectedresults: - 1. Success - 2. Success -@@ -180,6 +183,7 @@ def test_access_json_format(topo_m2, setup_test): - 14. Success - 15. Success - 16. Success -+ 17. Success - """ - - inst = topo_m2.ms["supplier1"] -@@ -560,6 +564,88 @@ def test_access_json_format(topo_m2, setup_test): - assert event['oid_name'] == "REPL_END_NSDS50_REPLICATION_REQUEST_OID" - assert event['name'] == "replication-multisupplier-extop" - -+ # -+ # TLS INFO/TLS CLIENT INFO -+ # -+ RDN_TEST_USER = 'testuser' -+ RDN_TEST_USER_WRONG = 'testuser_wrong' -+ inst.enable_tls() -+ inst.restart() -+ -+ users = UserAccounts(inst, DEFAULT_SUFFIX) -+ user = users.create(properties={ -+ 'uid': RDN_TEST_USER, -+ 'cn': RDN_TEST_USER, -+ 'sn': RDN_TEST_USER, -+ 'uidNumber': '1000', -+ 'gidNumber': '2000', -+ 'homeDirectory': f'/home/{RDN_TEST_USER}' -+ }) -+ -+ ssca_dir = inst.get_ssca_dir() -+ ssca = NssSsl(dbpath=ssca_dir) -+ ssca.create_rsa_user(RDN_TEST_USER) -+ ssca.create_rsa_user(RDN_TEST_USER_WRONG) -+ -+ # Get the details of where the key and crt are. -+ tls_locs = ssca.get_rsa_user(RDN_TEST_USER) -+ tls_locs_wrong = ssca.get_rsa_user(RDN_TEST_USER_WRONG) -+ -+ user.enroll_certificate(tls_locs['crt_der_path']) -+ -+ # Turn on the certmap. -+ cm = CertmapLegacy(inst) -+ certmaps = cm.list() -+ certmaps['default']['DNComps'] = '' -+ certmaps['default']['FilterComps'] = ['cn'] -+ certmaps['default']['VerifyCert'] = 'off' -+ cm.set(certmaps) -+ -+ # Check that EXTERNAL is listed in supported mechns. -+ assert (inst.rootdse.supports_sasl_external()) -+ -+ # Restart to allow certmaps to be re-read: Note, we CAN NOT use post_open -+ # here, it breaks on auth. see lib389/__init__.py -+ inst.restart(post_open=False) -+ -+ # Attempt a bind with TLS external -+ inst.open(saslmethod='EXTERNAL', connOnly=True, certdir=ssca_dir, -+ userkey=tls_locs['key'], usercert=tls_locs['crt']) -+ inst.restart() -+ -+ event = get_log_event(inst, "TLS_INFO") -+ assert event is not None -+ assert 'tls_version' in event -+ assert 'keysize' in event -+ assert 'cipher' in event -+ -+ event = get_log_event(inst, "TLS_CLIENT_INFO", -+ "subject", -+ "CN=testuser,O=testing,L=389ds,ST=Queensland,C=AU") -+ assert event is not None -+ assert 'tls_version' in event -+ assert 'keysize' in event -+ assert 'issuer' in event -+ -+ event = get_log_event(inst, "TLS_CLIENT_INFO", -+ "client_dn", -+ "uid=testuser,ou=People,dc=example,dc=com") -+ assert event is not None -+ assert 'tls_version' in event -+ assert event['msg'] == "client bound" -+ -+ # Check for failed certmap error -+ with pytest.raises(ldap.INVALID_CREDENTIALS): -+ inst.open(saslmethod='EXTERNAL', connOnly=True, certdir=ssca_dir, -+ userkey=tls_locs_wrong['key'], -+ usercert=tls_locs_wrong['crt']) -+ -+ event = get_log_event(inst, "TLS_CLIENT_INFO", "err", -185) -+ assert event is not None -+ assert 'tls_version' in event -+ assert event['msg'] == "failed to map client certificate to LDAP DN" -+ assert event['err_msg'] == "Certificate couldn't be mapped to an ldap entry" -+ - - if __name__ == '__main__': - # Run isolated -diff --git a/ldap/servers/slapd/accesslog.c b/ldap/servers/slapd/accesslog.c -index 68022fe38..072ace203 100644 ---- a/ldap/servers/slapd/accesslog.c -+++ b/ldap/servers/slapd/accesslog.c -@@ -1147,3 +1147,117 @@ slapd_log_access_sort(slapd_log_pblock *logpb) - - return rc; - } -+ -+/* -+ * TLS connection -+ * -+ * int32_t log_format -+ * time_t conn_time -+ * uint64_t conn_id -+ * const char *msg -+ * const char *tls_version -+ * int32_t keysize -+ * const char *cipher -+ * int32_t err -+ * const char *err_str -+ */ -+int32_t -+slapd_log_access_tls(slapd_log_pblock *logpb) -+{ -+ int32_t rc = 0; -+ char *msg = NULL; -+ json_object *json_obj = NULL; -+ -+ if ((json_obj = build_base_obj(logpb, "TLS_INFO")) == NULL) { -+ return rc; -+ } -+ -+ if (logpb->msg) { -+ json_object_object_add(json_obj, "msg", json_obj_add_str(logpb->msg)); -+ } -+ if (logpb->tls_version) { -+ json_object_object_add(json_obj, "tls_version", json_obj_add_str(logpb->tls_version)); -+ } -+ if (logpb->cipher) { -+ json_object_object_add(json_obj, "cipher", json_obj_add_str(logpb->cipher)); -+ } -+ if (logpb->keysize) { -+ json_object_object_add(json_obj, "keysize", json_object_new_int(logpb->keysize)); -+ } -+ if (logpb->err_str) { -+ json_object_object_add(json_obj, "err", json_object_new_int(logpb->err)); -+ json_object_object_add(json_obj, "err_msg", json_obj_add_str(logpb->err_str)); -+ } -+ -+ /* Convert json object to string and log it */ -+ msg = (char *)json_object_to_json_string_ext(json_obj, logpb->log_format); -+ rc = slapd_log_access_json(msg); -+ -+ /* Done with JSON object - free it */ -+ json_object_put(json_obj); -+ -+ return rc; -+} -+ -+/* -+ * TLS client auth -+ * -+ * int32_t log_format -+ * time_t conn_time -+ * uint64_t conn_id -+ * const char* tls_version -+ * const char* keysize -+ * const char* cipher -+ * const char* msg -+ * const char* subject -+ * const char* issuer -+ * int32_t err -+ * const char* err_str -+ * const char *client_dn -+ */ -+int32_t -+slapd_log_access_tls_client_auth(slapd_log_pblock *logpb) -+{ -+ int32_t rc = 0; -+ char *msg = NULL; -+ json_object *json_obj = NULL; -+ -+ if ((json_obj = build_base_obj(logpb, "TLS_CLIENT_INFO")) == NULL) { -+ return rc; -+ } -+ -+ if (logpb->tls_version) { -+ json_object_object_add(json_obj, "tls_version", json_obj_add_str(logpb->tls_version)); -+ } -+ if (logpb->cipher) { -+ json_object_object_add(json_obj, "cipher", json_obj_add_str(logpb->cipher)); -+ } -+ if (logpb->keysize) { -+ json_object_object_add(json_obj, "keysize", json_object_new_int(logpb->keysize)); -+ } -+ if (logpb->subject) { -+ json_object_object_add(json_obj, "subject", json_obj_add_str(logpb->subject)); -+ } -+ if (logpb->issuer) { -+ json_object_object_add(json_obj, "issuer", json_obj_add_str(logpb->issuer)); -+ } -+ if (logpb->client_dn) { -+ json_object_object_add(json_obj, "client_dn", json_obj_add_str(logpb->client_dn)); -+ } -+ if (logpb->msg) { -+ json_object_object_add(json_obj, "msg", json_obj_add_str(logpb->msg)); -+ } -+ if (logpb->err_str) { -+ json_object_object_add(json_obj, "err", json_object_new_int(logpb->err)); -+ json_object_object_add(json_obj, "err_msg", json_obj_add_str(logpb->err_str)); -+ } -+ -+ /* Convert json object to string and log it */ -+ msg = (char *)json_object_to_json_string_ext(json_obj, logpb->log_format); -+ rc = slapd_log_access_json(msg); -+ -+ /* Done with JSON object - free it */ -+ json_object_put(json_obj); -+ -+ return rc; -+} -diff --git a/ldap/servers/slapd/auth.c b/ldap/servers/slapd/auth.c -index e4231bf45..48e4b7129 100644 ---- a/ldap/servers/slapd/auth.c -+++ b/ldap/servers/slapd/auth.c -@@ -1,6 +1,6 @@ - /** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. -- * Copyright (C) 2005 Red Hat, Inc. -+ * Copyright (C) 2025 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). -@@ -363,19 +363,32 @@ handle_bad_certificate(void *clientData, PRFileDesc *prfd) - char sbuf[BUFSIZ], ibuf[BUFSIZ]; - Connection *conn = (Connection *)clientData; - CERTCertificate *clientCert = slapd_ssl_peerCertificate(prfd); -- - PRErrorCode errorCode = PR_GetError(); - char *subject = subject_of(clientCert); - char *issuer = issuer_of(clientCert); -- slapi_log_access(LDAP_DEBUG_STATS, -- "conn=%" PRIu64 " " SLAPI_COMPONENT_NAME_NSPR " error %i (%s); unauthenticated client %s; issuer %s\n", -- conn->c_connid, errorCode, slapd_pr_strerror(errorCode), -- subject ? escape_string(subject, sbuf) : "NULL", -- issuer ? escape_string(issuer, ibuf) : "NULL"); -+ int32_t log_format = config_get_accesslog_log_format(); -+ slapd_log_pblock logpb = {0}; -+ -+ if (log_format != LOG_FORMAT_DEFAULT) { -+ slapd_log_pblock_init(&logpb, log_format, NULL); -+ logpb.conn_id = conn->c_connid; -+ logpb.msg = "unauthenticated client"; -+ logpb.subject = subject ? escape_string(subject, sbuf) : "NULL"; -+ logpb.issuer = issuer ? escape_string(issuer, ibuf) : "NULL"; -+ logpb.err = errorCode; -+ logpb.err_str = slapd_pr_strerror(errorCode); -+ slapd_log_access_tls_client_auth(&logpb); -+ } else { -+ slapi_log_access(LDAP_DEBUG_STATS, -+ "conn=%" PRIu64 " " SLAPI_COMPONENT_NAME_NSPR " error %i (%s); unauthenticated client %s; issuer %s\n", -+ conn->c_connid, errorCode, slapd_pr_strerror(errorCode), -+ subject ? escape_string(subject, sbuf) : "NULL", -+ issuer ? escape_string(issuer, ibuf) : "NULL"); -+ } - if (issuer) -- free(issuer); -+ slapi_ch_free_string(&issuer); - if (subject) -- free(subject); -+ slapi_ch_free_string(&subject); - if (clientCert) - CERT_DestroyCertificate(clientCert); - return -1; /* non-zero means reject this certificate */ -@@ -394,7 +407,8 @@ handle_handshake_done(PRFileDesc *prfd, void *clientData) - { - Connection *conn = (Connection *)clientData; - CERTCertificate *clientCert = slapd_ssl_peerCertificate(prfd); -- -+ int32_t log_format = config_get_accesslog_log_format(); -+ slapd_log_pblock logpb = {0}; - char *clientDN = NULL; - int keySize = 0; - char *cipher = NULL; -@@ -403,19 +417,39 @@ handle_handshake_done(PRFileDesc *prfd, void *clientData) - SSLCipherSuiteInfo cipherInfo; - char *subject = NULL; - char sslversion[64]; -+ int err = 0; - - if ((slapd_ssl_getChannelInfo(prfd, &channelInfo, sizeof(channelInfo))) != SECSuccess) { - PRErrorCode errorCode = PR_GetError(); -- slapi_log_access(LDAP_DEBUG_STATS, -- "conn=%" PRIu64 " SSL failed to obtain channel info; " SLAPI_COMPONENT_NAME_NSPR " error %i (%s)\n", -- conn->c_connid, errorCode, slapd_pr_strerror(errorCode)); -+ if (log_format != LOG_FORMAT_DEFAULT) { -+ slapd_log_pblock_init(&logpb, log_format, NULL); -+ logpb.conn_id = conn->c_connid; -+ logpb.err = errorCode; -+ logpb.err_str = slapd_pr_strerror(errorCode); -+ logpb.msg = "SSL failed to obtain channel info; " SLAPI_COMPONENT_NAME_NSPR; -+ slapd_log_access_tls(&logpb); -+ } else { -+ slapi_log_access(LDAP_DEBUG_STATS, -+ "conn=%" PRIu64 " SSL failed to obtain channel info; " SLAPI_COMPONENT_NAME_NSPR " error %i (%s)\n", -+ conn->c_connid, errorCode, slapd_pr_strerror(errorCode)); -+ } - goto done; - } -+ - if ((slapd_ssl_getCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo, sizeof(cipherInfo))) != SECSuccess) { - PRErrorCode errorCode = PR_GetError(); -- slapi_log_access(LDAP_DEBUG_STATS, -- "conn=%" PRIu64 " SSL failed to obtain cipher info; " SLAPI_COMPONENT_NAME_NSPR " error %i (%s)\n", -- conn->c_connid, errorCode, slapd_pr_strerror(errorCode)); -+ if (log_format != LOG_FORMAT_DEFAULT) { -+ slapd_log_pblock_init(&logpb, log_format, NULL); -+ logpb.conn_id = conn->c_connid; -+ logpb.err = errorCode; -+ logpb.err_str = slapd_pr_strerror(errorCode); -+ logpb.msg = "SSL failed to obtain cipher info; " SLAPI_COMPONENT_NAME_NSPR; -+ slapd_log_access_tls(&logpb); -+ } else { -+ slapi_log_access(LDAP_DEBUG_STATS, -+ "conn=%" PRIu64 " SSL failed to obtain cipher info; " SLAPI_COMPONENT_NAME_NSPR " error %i (%s)\n", -+ conn->c_connid, errorCode, slapd_pr_strerror(errorCode)); -+ } - goto done; - } - -@@ -434,47 +468,84 @@ handle_handshake_done(PRFileDesc *prfd, void *clientData) - - if (config_get_SSLclientAuth() == SLAPD_SSLCLIENTAUTH_OFF) { - (void)slapi_getSSLVersion_str(channelInfo.protocolVersion, sslversion, sizeof(sslversion)); -- slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " %s %i-bit %s\n", -- conn->c_connid, -- sslversion, keySize, cipher ? cipher : "NULL"); -+ if (log_format != LOG_FORMAT_DEFAULT) { -+ slapd_log_pblock_init(&logpb, log_format, NULL); -+ logpb.conn_id = conn->c_connid; -+ logpb.tls_version = sslversion; -+ logpb.keysize = keySize; -+ logpb.cipher = cipher ? cipher : "NULL"; -+ slapd_log_access_tls(&logpb); -+ } else { -+ slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " %s %i-bit %s\n", -+ conn->c_connid, -+ sslversion, keySize, cipher ? cipher : "NULL"); -+ } - goto done; - } - if (clientCert == NULL) { - (void)slapi_getSSLVersion_str(channelInfo.protocolVersion, sslversion, sizeof(sslversion)); -- slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " %s %i-bit %s\n", -- conn->c_connid, -- sslversion, keySize, cipher ? cipher : "NULL"); -+ if (log_format != LOG_FORMAT_DEFAULT) { -+ slapd_log_pblock_init(&logpb, log_format, NULL); -+ logpb.conn_id = conn->c_connid; -+ logpb.tls_version = sslversion; -+ logpb.keysize = keySize; -+ logpb.cipher = cipher ? cipher : "NULL"; -+ slapd_log_access_tls(&logpb); -+ } else { -+ slapi_log_access(LDAP_DEBUG_STATS, "conn=%" PRIu64 " %s %i-bit %s\n", -+ conn->c_connid, -+ sslversion, keySize, cipher ? cipher : "NULL"); -+ } - } else { - subject = subject_of(clientCert); - if (!subject) { - (void)slapi_getSSLVersion_str(channelInfo.protocolVersion, - sslversion, sizeof(sslversion)); -- slapi_log_access(LDAP_DEBUG_STATS, -- "conn=%" PRIu64 " %s %i-bit %s; missing subject\n", -- conn->c_connid, -- sslversion, keySize, cipher ? cipher : "NULL"); -+ if (log_format != LOG_FORMAT_DEFAULT) { -+ slapd_log_pblock_init(&logpb, log_format, NULL); -+ logpb.conn_id = conn->c_connid; -+ logpb.msg = "missing subject"; -+ logpb.tls_version = sslversion; -+ logpb.keysize = keySize; -+ logpb.cipher = cipher ? cipher : "NULL"; -+ slapd_log_access_tls_client_auth(&logpb); -+ } else { -+ slapi_log_access(LDAP_DEBUG_STATS, -+ "conn=%" PRIu64 " %s %i-bit %s; missing subject\n", -+ conn->c_connid, -+ sslversion, keySize, cipher ? cipher : "NULL"); -+ } - goto done; -- } -- { -+ } else { - char *issuer = issuer_of(clientCert); - char sbuf[BUFSIZ], ibuf[BUFSIZ]; - (void)slapi_getSSLVersion_str(channelInfo.protocolVersion, - sslversion, sizeof(sslversion)); -- slapi_log_access(LDAP_DEBUG_STATS, -- "conn=%" PRIu64 " %s %i-bit %s; client %s; issuer %s\n", -- conn->c_connid, -- sslversion, keySize, -- cipher ? cipher : "NULL", -- escape_string(subject, sbuf), -- issuer ? escape_string(issuer, ibuf) : "NULL"); -+ if (log_format != LOG_FORMAT_DEFAULT) { -+ slapd_log_pblock_init(&logpb, log_format, NULL); -+ logpb.conn_id = conn->c_connid; -+ logpb.tls_version = sslversion; -+ logpb.keysize = keySize; -+ logpb.cipher = cipher ? cipher : "NULL"; -+ logpb.subject = escape_string(subject, sbuf); -+ logpb.issuer = issuer ? escape_string(issuer, ibuf) : "NULL"; -+ slapd_log_access_tls_client_auth(&logpb); -+ } else { -+ slapi_log_access(LDAP_DEBUG_STATS, -+ "conn=%" PRIu64 " %s %i-bit %s; client %s; issuer %s\n", -+ conn->c_connid, -+ sslversion, keySize, -+ cipher ? cipher : "NULL", -+ escape_string(subject, sbuf), -+ issuer ? escape_string(issuer, ibuf) : "NULL"); -+ } - if (issuer) -- free(issuer); -+ slapi_ch_free_string(&issuer); - } - slapi_dn_normalize(subject); - { - LDAPMessage *chain = NULL; - char *basedn = config_get_basedn(); -- int err; - - err = ldapu_cert_to_ldap_entry(clientCert, internal_ld, basedn ? basedn : "" /*baseDN*/, &chain); - if (err == LDAPU_SUCCESS && chain) { -@@ -505,18 +576,37 @@ handle_handshake_done(PRFileDesc *prfd, void *clientData) - slapi_sdn_free(&sdn); - (void)slapi_getSSLVersion_str(channelInfo.protocolVersion, - sslversion, sizeof(sslversion)); -- slapi_log_access(LDAP_DEBUG_STATS, -- "conn=%" PRIu64 " %s client bound as %s\n", -- conn->c_connid, -- sslversion, clientDN); -+ if (log_format != LOG_FORMAT_DEFAULT) { -+ slapd_log_pblock_init(&logpb, log_format, NULL); -+ logpb.conn_id = conn->c_connid; -+ logpb.msg = "client bound"; -+ logpb.tls_version = sslversion; -+ logpb.client_dn = clientDN; -+ slapd_log_access_tls_client_auth(&logpb); -+ } else { -+ slapi_log_access(LDAP_DEBUG_STATS, -+ "conn=%" PRIu64 " %s client bound as %s\n", -+ conn->c_connid, -+ sslversion, clientDN); -+ } - } else if (clientCert != NULL) { - (void)slapi_getSSLVersion_str(channelInfo.protocolVersion, - sslversion, sizeof(sslversion)); -- slapi_log_access(LDAP_DEBUG_STATS, -- "conn=%" PRIu64 " %s failed to map client " -- "certificate to LDAP DN (%s)\n", -- conn->c_connid, -- sslversion, extraErrorMsg); -+ if (log_format != LOG_FORMAT_DEFAULT) { -+ slapd_log_pblock_init(&logpb, log_format, NULL); -+ logpb.conn_id = conn->c_connid; -+ logpb.msg = "failed to map client certificate to LDAP DN"; -+ logpb.tls_version = sslversion; -+ logpb.err = err; -+ logpb.err_str = extraErrorMsg; -+ slapd_log_access_tls_client_auth(&logpb); -+ } else { -+ slapi_log_access(LDAP_DEBUG_STATS, -+ "conn=%" PRIu64 " %s failed to map client " -+ "certificate to LDAP DN (%s)\n", -+ conn->c_connid, -+ sslversion, extraErrorMsg); -+ } - } - - /* -diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c -index eab837166..06792a55a 100644 ---- a/ldap/servers/slapd/log.c -+++ b/ldap/servers/slapd/log.c -@@ -7270,6 +7270,8 @@ slapd_log_pblock_init(slapd_log_pblock *logpb, int32_t log_format, Slapi_PBlock - slapi_pblock_get(pb, SLAPI_CONNECTION, &conn); - } - -+ memset(logpb, 0, sizeof(slapd_log_pblock)); -+ - logpb->loginfo = &loginfo; - logpb->level = 256; /* default log level */ - logpb->log_format = log_format; -diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h -index 6438a81fe..da232ae2f 100644 ---- a/ldap/servers/slapd/slapi-private.h -+++ b/ldap/servers/slapd/slapi-private.h -@@ -1549,6 +1549,13 @@ typedef struct slapd_log_pblock { - PRBool using_tls; - PRBool haproxied; - const char *bind_dn; -+ /* TLS */ -+ const char *tls_version; -+ int32_t keysize; -+ const char *cipher; -+ const char *subject; -+ const char *issuer; -+ const char *client_dn; - /* Close connection */ - const char *close_error; - const char *close_reason; -@@ -1619,6 +1626,7 @@ typedef struct slapd_log_pblock { - const char *oid; - const char *msg; - const char *name; -+ const char *err_str; - LDAPControl **request_controls; - LDAPControl **response_controls; - } slapd_log_pblock; -@@ -1645,6 +1653,8 @@ int32_t slapd_log_access_entry(slapd_log_pblock *logpb); - int32_t slapd_log_access_referral(slapd_log_pblock *logpb); - int32_t slapd_log_access_extop(slapd_log_pblock *logpb); - int32_t slapd_log_access_sort(slapd_log_pblock *logpb); -+int32_t slapd_log_access_tls(slapd_log_pblock *logpb); -+int32_t slapd_log_access_tls_client_auth(slapd_log_pblock *logpb); - - #ifdef __cplusplus - } --- -2.49.0 - diff --git a/0014-Issue-6772-dsconf-Replicas-with-the-consumer-role-al.patch b/0014-Issue-6772-dsconf-Replicas-with-the-consumer-role-al.patch deleted file mode 100644 index 6bfa2b6..0000000 --- a/0014-Issue-6772-dsconf-Replicas-with-the-consumer-role-al.patch +++ /dev/null @@ -1,67 +0,0 @@ -From c44c45797a0e92fcdb6f0cc08f56816c7d77ffac Mon Sep 17 00:00:00 2001 -From: Anuar Beisembayev <111912342+abeisemb@users.noreply.github.com> -Date: Wed, 23 Jul 2025 23:48:11 -0400 -Subject: [PATCH] Issue 6772 - dsconf - Replicas with the "consumer" role allow - for viewing and modification of their changelog. (#6773) - -dsconf currently allows users to set and retrieve changelogs in consumer replicas, which do not have officially supported changelogs. This can lead to undefined behavior and confusion. -This commit prints a warning message if the user tries to interact with a changelog on a consumer replica. - -Resolves: https://github.com/389ds/389-ds-base/issues/6772 - -Reviewed by: @droideck ---- - src/lib389/lib389/cli_conf/replication.py | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/src/lib389/lib389/cli_conf/replication.py b/src/lib389/lib389/cli_conf/replication.py -index 6f77f34ca..a18bf83ca 100644 ---- a/src/lib389/lib389/cli_conf/replication.py -+++ b/src/lib389/lib389/cli_conf/replication.py -@@ -686,6 +686,9 @@ def set_per_backend_cl(inst, basedn, log, args): - replace_list = [] - did_something = False - -+ if (is_replica_role_consumer(inst, suffix)): -+ log.info("Warning: Changelogs are not supported for consumer replicas. You may run into undefined behavior.") -+ - if args.encrypt: - cl.replace('nsslapd-encryptionalgorithm', 'AES') - del args.encrypt -@@ -715,6 +718,10 @@ def set_per_backend_cl(inst, basedn, log, args): - # that means there is a changelog config entry per backend (aka suffix) - def get_per_backend_cl(inst, basedn, log, args): - suffix = args.suffix -+ -+ if (is_replica_role_consumer(inst, suffix)): -+ log.info("Warning: Changelogs are not supported for consumer replicas. You may run into undefined behavior.") -+ - cl = Changelog(inst, suffix) - if args and args.json: - log.info(cl.get_all_attrs_json()) -@@ -822,6 +829,22 @@ def del_repl_manager(inst, basedn, log, args): - - log.info("Successfully deleted replication manager: " + manager_dn) - -+def is_replica_role_consumer(inst, suffix): -+ """Helper function for get_per_backend_cl and set_per_backend_cl. -+ Makes sure the instance in question is not a consumer, which is a role that -+ does not support changelogs. -+ """ -+ replicas = Replicas(inst) -+ try: -+ replica = replicas.get(suffix) -+ role = replica.get_role() -+ except ldap.NO_SUCH_OBJECT: -+ raise ValueError(f"Backend \"{suffix}\" is not enabled for replication") -+ -+ if role == ReplicaRole.CONSUMER: -+ return True -+ else: -+ return False - - # - # Agreements --- -2.49.0 - diff --git a/0015-Issue-6893-Log-user-that-is-updated-during-password-.patch b/0015-Issue-6893-Log-user-that-is-updated-during-password-.patch deleted file mode 100644 index 14d3720..0000000 --- a/0015-Issue-6893-Log-user-that-is-updated-during-password-.patch +++ /dev/null @@ -1,360 +0,0 @@ -From b5134beedc719094193331ddbff0ca75316f93ff Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Mon, 21 Jul 2025 18:07:21 -0400 -Subject: [PATCH] Issue 6893 - Log user that is updated during password modify - extended operation - -Description: - -When a user's password is updated via an extended operation (password modify -plugin) we only log the bind DN and not what user was updated. While "internal -operation" logging will display the the user it should be logged by the default -logging level. - -Add access logging using "EXT_INFO" for the old logging format, and -"EXTENDED_OP_INFO" for json logging where we display the bind dn, target -dn, and message. - -Relates: https://github.com/389ds/389-ds-base/issues/6893 - -Reviewed by: spichugi & tbordaz(Thanks!!) ---- - .../logging/access_json_logging_test.py | 98 +++++++++++++++---- - ldap/servers/slapd/accesslog.c | 47 +++++++++ - ldap/servers/slapd/passwd_extop.c | 69 +++++++------ - ldap/servers/slapd/slapi-private.h | 1 + - 4 files changed, 169 insertions(+), 46 deletions(-) - -diff --git a/dirsrvtests/tests/suites/logging/access_json_logging_test.py b/dirsrvtests/tests/suites/logging/access_json_logging_test.py -index f0dc861a7..699bd8c4d 100644 ---- a/dirsrvtests/tests/suites/logging/access_json_logging_test.py -+++ b/dirsrvtests/tests/suites/logging/access_json_logging_test.py -@@ -11,7 +11,7 @@ import os - import time - import ldap - import pytest --from lib389._constants import DEFAULT_SUFFIX, PASSWORD, LOG_ACCESS_LEVEL -+from lib389._constants import DEFAULT_SUFFIX, PASSWORD, LOG_ACCESS_LEVEL, DN_DM - from lib389.properties import TASK_WAIT - from lib389.topologies import topology_m2 as topo_m2 - from lib389.idm.group import Groups -@@ -548,22 +548,6 @@ def test_access_json_format(topo_m2, setup_test): - "2.16.840.1.113730.3.4.3", - "LDAP_CONTROL_PERSISTENTSEARCH") - -- # -- # Extended op -- # -- log.info("Test EXTENDED_OP") -- event = get_log_event(inst, "EXTENDED_OP", "oid", -- "2.16.840.1.113730.3.5.12") -- assert event is not None -- assert event['oid_name'] == "REPL_START_NSDS90_REPLICATION_REQUEST_OID" -- assert event['name'] == "replication-multisupplier-extop" -- -- event = get_log_event(inst, "EXTENDED_OP", "oid", -- "2.16.840.1.113730.3.5.5") -- assert event is not None -- assert event['oid_name'] == "REPL_END_NSDS50_REPLICATION_REQUEST_OID" -- assert event['name'] == "replication-multisupplier-extop" -- - # - # TLS INFO/TLS CLIENT INFO - # -@@ -579,7 +563,8 @@ def test_access_json_format(topo_m2, setup_test): - 'sn': RDN_TEST_USER, - 'uidNumber': '1000', - 'gidNumber': '2000', -- 'homeDirectory': f'/home/{RDN_TEST_USER}' -+ 'homeDirectory': f'/home/{RDN_TEST_USER}', -+ 'userpassword': 'password' - }) - - ssca_dir = inst.get_ssca_dir() -@@ -646,6 +631,83 @@ def test_access_json_format(topo_m2, setup_test): - assert event['msg'] == "failed to map client certificate to LDAP DN" - assert event['err_msg'] == "Certificate couldn't be mapped to an ldap entry" - -+ # -+ # Extended op -+ # -+ log.info("Test EXTENDED_OP") -+ event = get_log_event(inst, "EXTENDED_OP", "oid", -+ "2.16.840.1.113730.3.5.12") -+ assert event is not None -+ assert event['oid_name'] == "REPL_START_NSDS90_REPLICATION_REQUEST_OID" -+ assert event['name'] == "replication-multisupplier-extop" -+ -+ event = get_log_event(inst, "EXTENDED_OP", "oid", -+ "2.16.840.1.113730.3.5.5") -+ assert event is not None -+ assert event['oid_name'] == "REPL_END_NSDS50_REPLICATION_REQUEST_OID" -+ assert event['name'] == "replication-multisupplier-extop" -+ -+ # -+ # Extended op info -+ # -+ log.info("Test EXTENDED_OP_INFO") -+ OLD_PASSWD = 'password' -+ NEW_PASSWD = 'newpassword' -+ -+ assert inst.simple_bind_s(DN_DM, PASSWORD) -+ -+ assert inst.passwd_s(user.dn, OLD_PASSWD, NEW_PASSWD) -+ event = get_log_event(inst, "EXTENDED_OP_INFO", "name", -+ "passwd_modify_plugin") -+ assert event is not None -+ assert event['bind_dn'] == "cn=directory manager" -+ assert event['target_dn'] == user.dn.lower() -+ assert event['msg'] == "success" -+ -+ # Test no such object -+ BAD_DN = user.dn + ",dc=not" -+ with pytest.raises(ldap.NO_SUCH_OBJECT): -+ inst.passwd_s(BAD_DN, OLD_PASSWD, NEW_PASSWD) -+ -+ event = get_log_event(inst, "EXTENDED_OP_INFO", "target_dn", BAD_DN) -+ assert event is not None -+ assert event['bind_dn'] == "cn=directory manager" -+ assert event['target_dn'] == BAD_DN.lower() -+ assert event['msg'] == "No such entry exists." -+ -+ # Test invalid old password -+ with pytest.raises(ldap.INVALID_CREDENTIALS): -+ inst.passwd_s(user.dn, "not_the_old_pw", NEW_PASSWD) -+ event = get_log_event(inst, "EXTENDED_OP_INFO", "err", 49) -+ assert event is not None -+ assert event['bind_dn'] == "cn=directory manager" -+ assert event['target_dn'] == user.dn.lower() -+ assert event['msg'] == "Invalid oldPasswd value." -+ -+ # Test user without permissions -+ user2 = users.create(properties={ -+ 'uid': RDN_TEST_USER + "2", -+ 'cn': RDN_TEST_USER + "2", -+ 'sn': RDN_TEST_USER + "2", -+ 'uidNumber': '1001', -+ 'gidNumber': '2001', -+ 'homeDirectory': f'/home/{RDN_TEST_USER + "2"}', -+ 'userpassword': 'password' -+ }) -+ inst.simple_bind_s(user2.dn, 'password') -+ with pytest.raises(ldap.INSUFFICIENT_ACCESS): -+ inst.passwd_s(user.dn, NEW_PASSWD, OLD_PASSWD) -+ event = get_log_event(inst, "EXTENDED_OP_INFO", "err", 50) -+ assert event is not None -+ assert event['bind_dn'] == user2.dn.lower() -+ assert event['target_dn'] == user.dn.lower() -+ assert event['msg'] == "Insufficient access rights" -+ -+ -+ # Reset bind -+ inst.simple_bind_s(DN_DM, PASSWORD) -+ -+ - - if __name__ == '__main__': - # Run isolated -diff --git a/ldap/servers/slapd/accesslog.c b/ldap/servers/slapd/accesslog.c -index 072ace203..46228d4a1 100644 ---- a/ldap/servers/slapd/accesslog.c -+++ b/ldap/servers/slapd/accesslog.c -@@ -1113,6 +1113,53 @@ slapd_log_access_extop(slapd_log_pblock *logpb) - return rc; - } - -+/* -+ * Extended operation information -+ * -+ * int32_t log_format -+ * time_t conn_time -+ * uint64_t conn_id -+ * int32_t op_id -+ * const char *name -+ * const char *bind_dn -+ * const char *tartet_dn -+ * const char *msg -+ */ -+int32_t -+slapd_log_access_extop_info(slapd_log_pblock *logpb) -+{ -+ int32_t rc = 0; -+ char *msg = NULL; -+ json_object *json_obj = NULL; -+ -+ if ((json_obj = build_base_obj(logpb, "EXTENDED_OP_INFO")) == NULL) { -+ return rc; -+ } -+ -+ if (logpb->name) { -+ json_object_object_add(json_obj, "name", json_obj_add_str(logpb->name)); -+ } -+ if (logpb->target_dn) { -+ json_object_object_add(json_obj, "target_dn", json_obj_add_str(logpb->target_dn)); -+ } -+ if (logpb->bind_dn) { -+ json_object_object_add(json_obj, "bind_dn", json_obj_add_str(logpb->bind_dn)); -+ } -+ if (logpb->msg) { -+ json_object_object_add(json_obj, "msg", json_obj_add_str(logpb->msg)); -+ } -+ json_object_object_add(json_obj, "err", json_object_new_int(logpb->err)); -+ -+ /* Convert json object to string and log it */ -+ msg = (char *)json_object_to_json_string_ext(json_obj, logpb->log_format); -+ rc = slapd_log_access_json(msg); -+ -+ /* Done with JSON object - free it */ -+ json_object_put(json_obj); -+ -+ return rc; -+} -+ - /* - * Sort - * -diff --git a/ldap/servers/slapd/passwd_extop.c b/ldap/servers/slapd/passwd_extop.c -index 4bb60afd6..69bb3494c 100644 ---- a/ldap/servers/slapd/passwd_extop.c -+++ b/ldap/servers/slapd/passwd_extop.c -@@ -465,12 +465,14 @@ passwd_modify_extop(Slapi_PBlock *pb) - BerElement *response_ber = NULL; - Slapi_Entry *targetEntry = NULL; - Connection *conn = NULL; -+ Operation *pb_op = NULL; - LDAPControl **req_controls = NULL; - LDAPControl **resp_controls = NULL; - passwdPolicy *pwpolicy = NULL; - Slapi_DN *target_sdn = NULL; - Slapi_Entry *referrals = NULL; -- /* Slapi_DN sdn; */ -+ Slapi_Backend *be = NULL; -+ int32_t log_format = config_get_accesslog_log_format(); - - slapi_log_err(SLAPI_LOG_TRACE, "passwd_modify_extop", "=>\n"); - -@@ -647,7 +649,7 @@ parse_req_done: - } - dn = slapi_sdn_get_ndn(target_sdn); - if (dn == NULL || *dn == '\0') { -- /* Refuse the operation because they're bound anonymously */ -+ /* Invalid DN - refuse the operation */ - errMesg = "Invalid dn."; - rc = LDAP_INVALID_DN_SYNTAX; - goto free_and_return; -@@ -724,14 +726,19 @@ parse_req_done: - ber_free(response_ber, 1); - } - -- slapi_pblock_set(pb, SLAPI_ORIGINAL_TARGET, (void *)dn); -+ slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); -+ if (pb_op == NULL) { -+ slapi_log_err(SLAPI_LOG_ERR, "passwd_modify_extop", "pb_op is NULL\n"); -+ goto free_and_return; -+ } - -+ slapi_pblock_set(pb, SLAPI_ORIGINAL_TARGET, (void *)dn); - /* Now we have the DN, look for the entry */ - ret = passwd_modify_getEntry(dn, &targetEntry); - /* If we can't find the entry, then that's an error */ - if (ret) { - /* Couldn't find the entry, fail */ -- errMesg = "No such Entry exists."; -+ errMesg = "No such entry exists."; - rc = LDAP_NO_SUCH_OBJECT; - goto free_and_return; - } -@@ -742,30 +749,18 @@ parse_req_done: - leak any useful information to the client such as current password - wrong, etc. - */ -- Operation *pb_op = NULL; -- slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op); -- if (pb_op == NULL) { -- slapi_log_err(SLAPI_LOG_ERR, "passwd_modify_extop", "pb_op is NULL\n"); -- goto free_and_return; -- } -- - operation_set_target_spec(pb_op, slapi_entry_get_sdn(targetEntry)); - slapi_pblock_set(pb, SLAPI_REQUESTOR_ISROOT, &pb_op->o_isroot); - -- /* In order to perform the access control check , we need to select a backend (even though -- * we don't actually need it otherwise). -- */ -- { -- Slapi_Backend *be = NULL; -- -- be = slapi_mapping_tree_find_backend_for_sdn(slapi_entry_get_sdn(targetEntry)); -- if (NULL == be) { -- errMesg = "Failed to find backend for target entry"; -- rc = LDAP_OPERATIONS_ERROR; -- goto free_and_return; -- } -- slapi_pblock_set(pb, SLAPI_BACKEND, be); -+ /* In order to perform the access control check, we need to select a backend (even though -+ * we don't actually need it otherwise). */ -+ be = slapi_mapping_tree_find_backend_for_sdn(slapi_entry_get_sdn(targetEntry)); -+ if (NULL == be) { -+ errMesg = "Failed to find backend for target entry"; -+ rc = LDAP_NO_SUCH_OBJECT; -+ goto free_and_return; - } -+ slapi_pblock_set(pb, SLAPI_BACKEND, be); - - /* Check if the pwpolicy control is present */ - slapi_pblock_get(pb, SLAPI_PWPOLICY, &need_pwpolicy_ctrl); -@@ -797,10 +792,7 @@ parse_req_done: - /* Check if password policy allows users to change their passwords. We need to do - * this here since the normal modify code doesn't perform this check for - * internal operations. */ -- -- Connection *pb_conn; -- slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn); -- if (!pb_op->o_isroot && !pb_conn->c_needpw && !pwpolicy->pw_change) { -+ if (!pb_op->o_isroot && !conn->c_needpw && !pwpolicy->pw_change) { - if (NULL == bindSDN) { - bindSDN = slapi_sdn_new_normdn_byref(bindDN); - } -@@ -848,6 +840,27 @@ free_and_return: - slapi_log_err(SLAPI_LOG_PLUGIN, "passwd_modify_extop", - "%s\n", errMesg ? errMesg : "success"); - -+ if (dn) { -+ /* Log the target ndn (if we have a target ndn) */ -+ if (log_format != LOG_FORMAT_DEFAULT) { -+ /* JSON logging */ -+ slapd_log_pblock logpb = {0}; -+ slapd_log_pblock_init(&logpb, log_format, pb); -+ logpb.name = "passwd_modify_plugin"; -+ logpb.target_dn = dn; -+ logpb.bind_dn = bindDN; -+ logpb.msg = errMesg ? errMesg : "success"; -+ logpb.err = rc; -+ slapd_log_access_extop_info(&logpb); -+ } else { -+ slapi_log_access(LDAP_DEBUG_STATS, -+ "conn=%" PRIu64 " op=%d EXT_INFO name=\"passwd_modify_plugin\" bind_dn=\"%s\" target_dn=\"%s\" msg=\"%s\" rc=%d\n", -+ conn ? conn->c_connid : -1, pb_op ? pb_op->o_opid : -1, -+ bindDN ? bindDN : "", dn, -+ errMesg ? errMesg : "success", rc); -+ } -+ } -+ - if ((rc == LDAP_REFERRAL) && (referrals)) { - send_referrals_from_entry(pb, referrals); - } else { -diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h -index da232ae2f..e9abf8b75 100644 ---- a/ldap/servers/slapd/slapi-private.h -+++ b/ldap/servers/slapd/slapi-private.h -@@ -1652,6 +1652,7 @@ int32_t slapd_log_access_vlv(slapd_log_pblock *logpb); - int32_t slapd_log_access_entry(slapd_log_pblock *logpb); - int32_t slapd_log_access_referral(slapd_log_pblock *logpb); - int32_t slapd_log_access_extop(slapd_log_pblock *logpb); -+int32_t slapd_log_access_extop_info(slapd_log_pblock *logpb); - int32_t slapd_log_access_sort(slapd_log_pblock *logpb); - int32_t slapd_log_access_tls(slapd_log_pblock *logpb); - int32_t slapd_log_access_tls_client_auth(slapd_log_pblock *logpb); --- -2.49.0 - diff --git a/0016-Issue-6901-Update-changelog-trimming-logging.patch b/0016-Issue-6901-Update-changelog-trimming-logging.patch deleted file mode 100644 index d44fee7..0000000 --- a/0016-Issue-6901-Update-changelog-trimming-logging.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 048aa39d4c4955f6d9e3b018d4b1fc057f52d130 Mon Sep 17 00:00:00 2001 -From: Viktor Ashirov -Date: Thu, 24 Jul 2025 19:09:40 +0200 -Subject: [PATCH] Issue 6901 - Update changelog trimming logging - -Description: -* Set SLAPI_LOG_ERR for message in `_cl5DispatchTrimThread` -* Set correct function name for logs in `_cl5TrimEntry`. -* Add number of scanned entries to the log. - -Fixes: https://github.com/389ds/389-ds-base/issues/6901 - -Reviewed by: @mreynolds389, @progier389 (Thanks!) ---- - ldap/servers/plugins/replication/cl5_api.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c -index 3c356abc0..1d62aa020 100644 ---- a/ldap/servers/plugins/replication/cl5_api.c -+++ b/ldap/servers/plugins/replication/cl5_api.c -@@ -2007,7 +2007,7 @@ _cl5DispatchTrimThread(Replica *replica) - (void *)replica, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, - PR_UNJOINABLE_THREAD, DEFAULT_THREAD_STACKSIZE); - if (NULL == pth) { -- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, -+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl, - "_cl5DispatchTrimThread - Failed to create trimming thread for %s" - "; NSPR error - %d\n", replica_get_name(replica), - PR_GetError()); -@@ -2788,7 +2788,7 @@ _cl5TrimEntry(dbi_val_t *key, dbi_val_t *data, void *ctx) - return DBI_RC_NOTFOUND; - } else { - slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, -- "_cl5TrimReplica - Changelog purge skipped anchor csn %s\n", -+ "_cl5TrimEntry - Changelog purge skipped anchor csn %s\n", - (char*)key->data); - return DBI_RC_SUCCESS; - } -@@ -2867,8 +2867,8 @@ _cl5TrimReplica(Replica *r) - slapi_ch_free((void**)&dblcictx.rids); - - if (dblcictx.changed.tot) { -- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, "_cl5TrimReplica - Trimmed %ld changes from the changelog\n", -- dblcictx.changed.tot); -+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name_cl, "_cl5TrimReplica - Scanned %ld records, and trimmed %ld changes from the changelog\n", -+ dblcictx.seen.tot, dblcictx.changed.tot); - } - } - --- -2.49.0 - diff --git a/0017-Issue-6430-implement-read-only-bdb-6431.patch b/0017-Issue-6430-implement-read-only-bdb-6431.patch deleted file mode 100644 index a950aa4..0000000 --- a/0017-Issue-6430-implement-read-only-bdb-6431.patch +++ /dev/null @@ -1,20249 +0,0 @@ -From d893eaca07fd64bcb0b7939bff848acc02ed218a Mon Sep 17 00:00:00 2001 -From: progier389 -Date: Sat, 26 Jul 2025 17:24:44 +0200 -Subject: [PATCH] Issue 6430 - implement read-only bdb (#6431) - -* Issue 6430 - implement read-only bdb on F43 - -Remove bdb support from Fedora 43+ -Implement read only bdb package to support : dsctl dblib bdb2mdb ---- - .github/workflows/pytest.yml | 8 +- - Makefile.am | 72 +- - .../tests/data/bdb_instances/instances.tgz | Bin 0 -> 13258634 bytes - .../tests/suites/clu/dsctl_dblib_test.py | 4 +- - .../suites/lib389/config_compare_test.py | 4 +- - .../suites/upgrade/upgrade_bdb2mdb_test.py | 278 ++++++ - .../slapd/back-ldbm/db-bdb/bdb_bdbreader_db.h | 289 ++++++ - .../back-ldbm/db-bdb/bdb_bdbreader_glue.c | 519 +++++++++++ - .../slapd/back-ldbm/db-bdb/bdb_layer.h | 5 + - ldap/servers/slapd/back-ldbm/dbimpl.c | 5 + - ldap/servers/slapd/back-ldbm/dblayer.c | 34 +- - ldap/servers/slapd/protect_db.c | 4 + - lib/librobdb/COPYING | 8 + - lib/librobdb/COPYING.RPM | 848 ++++++++++++++++++ - lib/librobdb/README.md | 30 + - lib/librobdb/lib/bdb_ro.c | 713 +++++++++++++++ - lib/librobdb/lib/robdb.h | 51 ++ - lib/librobdb/robdb.spec | 67 ++ - lib/librobdb/tests/test.c | 175 ++++ - lib/librobdb/tests/test.db | Bin 0 -> 24576 bytes - m4/db.m4 | 42 +- - rpm.mk | 22 +- - rpm/389-ds-base.spec.in | 59 ++ - rpm/is-robdb-used | 45 + - src/lib389/lib389/cli_ctl/dblib.py | 18 +- - src/lib389/lib389/topologies.py | 1 + - 26 files changed, 3271 insertions(+), 30 deletions(-) - create mode 100644 dirsrvtests/tests/data/bdb_instances/instances.tgz - create mode 100644 dirsrvtests/tests/suites/upgrade/upgrade_bdb2mdb_test.py - create mode 100644 ldap/servers/slapd/back-ldbm/db-bdb/bdb_bdbreader_db.h - create mode 100644 ldap/servers/slapd/back-ldbm/db-bdb/bdb_bdbreader_glue.c - create mode 100644 lib/librobdb/COPYING - create mode 100644 lib/librobdb/COPYING.RPM - create mode 100644 lib/librobdb/README.md - create mode 100644 lib/librobdb/lib/bdb_ro.c - create mode 100644 lib/librobdb/lib/robdb.h - create mode 100644 lib/librobdb/robdb.spec - create mode 100644 lib/librobdb/tests/test.c - create mode 100644 lib/librobdb/tests/test.db - create mode 100755 rpm/is-robdb-used - -diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml -index d8434dfbb..0e65e05ba 100644 ---- a/.github/workflows/pytest.yml -+++ b/.github/workflows/pytest.yml -@@ -101,7 +101,13 @@ jobs: - sudo docker exec $CID sh -c "systemctl enable --now cockpit.socket" - sudo docker exec $CID sh -c "mkdir -p /workspace/assets/cores && chmod 777 /workspace{,/assets{,/cores}}" - sudo docker exec $CID sh -c "echo '/workspace/assets/cores/core.%e.%P' > /proc/sys/kernel/core_pattern" -- sudo docker exec -e WEBUI=1 -e NSSLAPD_DB_LIB=bdb -e DEBUG=pw:api -e PASSWD="${PASSWD}" $CID py.test --suppress-no-test-exit-code -m "not flaky" --junit-xml=pytest.xml --html=pytest.html --browser=firefox --browser=chromium -v dirsrvtests/tests/suites/${{ matrix.suite }} -+ if sudo docker exec $CID sh -c "test -f /usr/lib64/dirsrv/librobdb.so" -+ then -+ echo "Tests skipped because read-only Berkeley Database is installed." > pytest.html -+ echo "'Tests skipped because read-only Berkeley Database is installed.'" > pytest.xml -+ else -+ sudo docker exec -e WEBUI=1 -e NSSLAPD_DB_LIB=bdb -e DEBUG=pw:api -e PASSWD="${PASSWD}" $CID py.test --suppress-no-test-exit-code -m "not flaky" --junit-xml=pytest.xml --html=pytest.html --browser=firefox --browser=chromium -v dirsrvtests/tests/suites/${{ matrix.suite }} -+ fi - - - name: Make the results file readable by all - if: always() -diff --git a/Makefile.am b/Makefile.am -index 551b5f096..944f8d7c8 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -99,6 +99,9 @@ else - DS_DEFINES = -DBUILD_NUM=$(BUILDNUM) -DVENDOR="\"$(vendor)\"" -DBRAND="\"$(brand)\"" -DCAPBRAND="\"$(capbrand)\"" \ - -UPACKAGE_VERSION -UPACKAGE_TARNAME -UPACKAGE_STRING -UPACKAGE_BUGREPORT - endif -+if WITH_LIBBDB_RO -+DS_DEFINES += -DWITH_LIBBDB_RO=1 -+endif - DS_INCLUDES = -I$(srcdir)/ldap/include -I$(srcdir)/ldap/servers/slapd -I$(srcdir)/include -I. - - -@@ -184,11 +187,15 @@ endif - ldaplib = @ldaplib@ - ldaplib_defs = @ldaplib_defs@ - -+if WITH_LIBBDB_RO -+DB_LINK = @db_lib@ -llmdb -+else - if BUNDLE_LIBDB - DB_LINK = -llmdb - else - DB_LINK = @db_lib@ -ldb-@db_libver@ -llmdb - endif -+endif - DB_INC = @db_inc@ - DB_IMPL = libback-ldbm.la - SASL_LINK = $(SASL_LIBS) -@@ -326,6 +333,9 @@ bin_PROGRAMS = dbscan \ - # ---------------------------------------------------------------------------------------- - - server_LTLIBRARIES = libslapd.la libldaputil.la libns-dshttpd.la librewriters.la -+if WITH_LIBBDB_RO -+server_LTLIBRARIES += librobdb.la -+endif - - lib_LTLIBRARIES = libsvrcore.la - -@@ -1196,19 +1206,26 @@ libslapd_la_LDFLAGS = $(AM_LDFLAGS) $(SLAPD_LDFLAGS) - # libback-bdb - #------------------------ - DB_BDB_SRCS = \ -- ldap/servers/slapd/back-ldbm/db-bdb/bdb_config.c \ -- ldap/servers/slapd/back-ldbm/db-bdb/bdb_instance_config.c \ -- ldap/servers/slapd/back-ldbm/db-bdb/bdb_verify.c \ -- ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c \ -- ldap/servers/slapd/back-ldbm/db-bdb/bdb_misc.c \ -- ldap/servers/slapd/back-ldbm/db-bdb/bdb_perfctrs.c \ -- ldap/servers/slapd/back-ldbm/db-bdb/bdb_upgrade.c \ -- ldap/servers/slapd/back-ldbm/db-bdb/bdb_version.c \ -- ldap/servers/slapd/back-ldbm/db-bdb/bdb_monitor.c \ -- ldap/servers/slapd/back-ldbm/db-bdb/bdb_ldif2db.c \ -- ldap/servers/slapd/back-ldbm/db-bdb/bdb_import.c \ -- ldap/servers/slapd/back-ldbm/db-bdb/bdb_import_threads.c -- -+ @db_bdb_srcdir@/bdb_config.c \ -+ @db_bdb_srcdir@/bdb_instance_config.c \ -+ @db_bdb_srcdir@/bdb_verify.c \ -+ @db_bdb_srcdir@/bdb_layer.c \ -+ @db_bdb_srcdir@/bdb_misc.c \ -+ @db_bdb_srcdir@/bdb_perfctrs.c \ -+ @db_bdb_srcdir@/bdb_upgrade.c \ -+ @db_bdb_srcdir@/bdb_version.c \ -+ @db_bdb_srcdir@/bdb_monitor.c \ -+ @db_bdb_srcdir@/bdb_ldif2db.c \ -+ @db_bdb_srcdir@/bdb_import.c \ -+ @db_bdb_srcdir@/bdb_import_threads.c -+ -+ -+if WITH_LIBBDB_RO -+ # db-bdb sources are compiled within libback-ldbm.so and linked to librobdb -+ DB_BDB_SRCS += @db_bdb_srcdir@/bdb_bdbreader_glue.c -+ DB_BDB_WITHIN_BACKLDBM = $(DB_BDB_SRCS) -+ ROBDB_INC = -I$(srcdir)/lib/librobdb/lib -+else - if BUNDLE_LIBDB - # db-bdb sources are compiled within libback-bdb.so - DB_BDB_WITHIN_BACKLDBM = -@@ -1222,6 +1239,20 @@ else - # db-bdb sources are compiled within libback-ldbm.so - DB_BDB_WITHIN_BACKLDBM = $(DB_BDB_SRCS) - endif -+endif -+ -+clean-bdb-ro-src: -+ /bin/rm -f $(DB_BDB_RO_BUILT_SRCS) -+ -+build-src: $(BUILT_SOURCES) -+echo-src: -+ @echo V2 @db_bdbro_srcdir@ -+ @echo V3 @db_bdb_srcdir@ -+ @echo V1 $(patsubst %-ro/,%,$(dir $(DB_BDB_RO_BUILT_SRCS))) -+ @echo V4 $(DB_BDB_RO_BUILT_SRCS) -+ @echo V5 $(DB_BDB_WITHIN_BACKLDBM) -+ @echo V6 $(libback_ldbm_la_SOURCES) -+ - - #------------------------ - # libback-ldbm -@@ -1298,11 +1329,24 @@ libback_ldbm_la_SOURCES = ldap/servers/slapd/back-ldbm/ancestorid.c \ - $(DB_BDB_WITHIN_BACKLDBM) - - --libback_ldbm_la_CPPFLAGS = $(AM_CPPFLAGS) $(DSPLUGIN_CPPFLAGS) $(DB_INC) -+libback_ldbm_la_CPPFLAGS = $(AM_CPPFLAGS) $(DSPLUGIN_CPPFLAGS) $(DB_INC) $(ROBDB_INC) - libback_ldbm_la_DEPENDENCIES = libslapd.la - libback_ldbm_la_LIBADD = libslapd.la $(DB_LINK) $(LDAPSDK_LINK) $(NSPR_LINK) - libback_ldbm_la_LDFLAGS = -avoid-version - -+if WITH_LIBBDB_RO -+libback_ldbm_la_LIBADD += librobdb.la -+libback_ldbm_la_DEPENDENCIES += librobdb.la -+ -+#------------------------ -+# librobdb -+#------------------------ -+librobdb_la_SOURCES = lib/librobdb/lib/bdb_ro.c -+librobdb_la_CPPFLAGS = $(AM_CPPFLAGS) $(DB_INC) -+librobdb_la_LDFLAGS = -avoid-version -+librobdb_la_LIBADD = -+endif -+ - #------------------------ - # libacctpolicy-plugin - #------------------------ -diff --git a/dirsrvtests/tests/data/bdb_instances/instances.tgz b/dirsrvtests/tests/data/bdb_instances/instances.tgz -new file mode 100644 -index 0000000000000000000000000000000000000000..70122eeb0149a919e034e94699fd183df6db1121 -GIT binary patch -literal 13258634 -zcmd41Ly#~~(`H$=ZQFL$TefZ6wr$(CZQHhOn-l$ae?1*N9Wk?e}C%|>jRN|IoB1QR9TUTe4iOo(|qm|Jbm8Q-L?TUmV -zh~7uJ;)VfViehiFv8m+7r6e$eNc+7w#SO -zNu<1oK(4NRyJ#rorT_29+*74>d~e0`N!y@jk7kt}%jAn7 -z|Fz{7`T_s_Z9aWr`2} -z)YPuDbgHghYU)&3g|5N(y^qxS{bb$oQ3Ff(UhYOkvM@w9DTt|b`gJ+=u36tD3?=RK -z$OZEemyr*9$m&Mu$GiWO^%Wq{QGlpik5?)kqVqvKZ*T-(UhVY#j@12??Rmf5J^L6f -ze^9x}lnw8_6R67twIJxS|4q^R{^;GfQiL)lx|EIUefigi9Wk&4ul-G3xcPlu?R}qi -z{k7Od;;Ojja_Rj}1}@p!;@^1efemKo;N!8+{Y!%P%9|LOI2eoK9j%4E2 -z6iC%12i2fmkOw0db8Dfa%^)? -z3e#8YovL|GmB}mRyj-_lk(=eS>`bRpNgnH`Mp<5XiRi%^#W&W8P)@H_+1={YHJlfE -zZ6rav9wzcdh+7vEMqH)K+*;&U%cXBkhu+ogTIiR{&QIrow@rH;>-HMftrhHBOXyjP -z%-L0^R+tO6`cRGC|LM_t?>P5G-mb-dwOsk8Y}Yk@y{vvnhJ^auw69#~yA*e-r*fS< -zS{>B+K3w(edA|k1(*CQgFYH4UD;4$IECZ=X-U|3~y6fM5RpXV-tC|1qyy -zJ?rPw!1eb6diJDOm1UnfdHKDDUiGB+by&Z=0@jxC)ey0mfjG!*1!)9B;e`2=`-XFg=6({Yt?yfSMAB!&Q4%!(CnR8nO% -z+GH^4V-$k}*GcMVFphM=lT=XscCbw;f}Je5i_SLAne0WLdCf|(sH`Fwg&~{leDA%M3Lz#$2eY7I0;gs-GMDYD=z0nLL~5@W}8B%AK26k@f=L3yt@qW -zk8{%|7turia*kAxF^d;7UqaJuIc%#iB4tGLnH6^zul~s8f$W>vCY!VhYWAUPv*ruI -zA@W{DN#$l?o$C9EzUEi_mjmJJF>f4y15mGv+%M4VdUq9HKr(DFZ@lm4K|nd=-_O^2 -zQshfkf*od2)YxD0s!JptODr#}c50cB9%`unA1|lrxIFe$3SMQZ+Hf6t{ -zUH{*{U5dI@KW#dTdKLZ5NjOU?t$ceJXhXFPqB?&%xB76wnv=ZU#5DV-6Dv1TRjNNg -zIAWD?DV-&01k`!SgI2gDi0#|S&L~RD@neF1zGM8L`Xl^G)m}hCSyLB9>*4z&^<5 -zb0CK=mY{P2`IcKB$@@?9doaDHeF}uT_5%R+FCj4OUJiDJnCVRdBM^+S_yhhFq}!nK -zK0wwL=q~-!R*hko#QICp|8lxY2YT!QC?eCo1b6fqERwyWhz*R)KK -z%^c_+{%`a?~-76!z%}cae|$!5Q;%;&u5WXvRyOI>T=eCFbw#BELu0 -zUqiRPCF`DR)zB$_DCLzOS{FZSrXP<=9$ymdd@*p*ad)9Hm*e{Yiy!kKR;hXM>#!pcU(7;Z;f3$ -zU+<^)-v&)j1Iuw)Z`?1BZ-YM%U%Vfd&Tf9X1cPI3cDOSIbpbCzOG}r~&}IVG3&;9u{su8#17?y|5j@>}{%1^_!)8OQwg`jbJmzdXX3WdNOL-OWdpnRFxw -zAF5a7q)R(!)>IhuZQ>a_y8(>W`fOqx7>ab0isJwW%Xet!5#0Dn>>FSR!i)AJyKM47 -zJ8p);2R;43l(iZH6B27wS3mKh9fyTe40_HZ$=xqU5B>K8HVP)Zpz5!K8DR6dxZ~HR -z_5bjOstebjaIL2~T?ovYcamP0FZPFD4=gzg;Ee(R)Tr`O)Q?dnTS=4567@V-D -z$%uk?EQMH>D@+jdVy~oXl8%~K5+Oz?wLe3CcAunAq#B0VMUHmI*_0I!1Ugr>2V=n| -zt~Tu-8BTmfmthGGQ#(i$ -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 -z^rEpNev-*piXg=H4en4`8c^mxcOYBB -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 -zeL&C((my4TqObGQ_v=kw*K50G -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 -zZ435wf`Y$)m@IBLVw+lzV^(7wcf)W#AFhr -z0cVhma+HfpSYhPEhGX+i;@;EtfJ0r%j*Qp!%zq%s( -z>%0ZZls3zgqypuuSFjxD&8kRjR)fmP_AnsPv|rahK=}a@960bL>j(N};LpUagRp^^ -z?27CE5k>5Kx1OlAc~Kxda9dV~QgXuxRuWbE6l;K5YOB-Oq+S+BVZ@OFB9KZpN`$yO -z7~~HCQcz4ehe#-_I!i@Y+M>m}YzO@eMps-A8DTFx=3$o^QNf1@-c#@N7h2Ho53XEQ -zUKkq{k+7tX<cIPVlg$x#oj8zEDt*v-FbbB{`H#1`aLiU-x58i -zyho0U7`*~K(WD{bXNS18X4!cJP^#BPmb<6k1E*!fWvY#NJ;#;Xl6q@C%C7k41_$k@ -zMle3Sr$ELftxNBUk~IHx+K3;JTkYvNFM^vGORSMlGm}Zpw~N_@*Izli_qO#0@C9c8S#~8)ADph -z7**SIMu2YAVJu>FoGyz3x5&0xS(^2|7%4`7%NjLd?;b$|+-k2MH86)b*V?UKgjrMO -z_S=%hYeUwKJ$aw=0sY?Tn1l{py=Yw+ca*n5&BBxN5kwZ~p{ -z24W~X`c8I9`M4A}cyId)HCGB9-1#L;i}RcjbwUGTshd}UvkUBBdF5Hm_e%4&GIiNd -zpcE))X#lV2|6*^LK8XGQ$lma3TrM-g7d+iu!7wmS0rp;GvCKML@AAfAeq{io-uoTV -zpDl3H2$s0i~)!Qo0eD!mAcO10zjKiNX5sd -z0TwC9HbF~diHK_w+1s%(W)>lWA$yn$I-8Eq7HprUYy4YQE|iB)O{2XSPJn5=D&UhB -zPX_lKvJ}wO=)wzSJII<5JgLlMOnb~+8YxR=F1wka#*zuzp>JGUAc?t#8qJQ% -zO$27t6`BI(1ckDR7Lu3>mJ)rqu69SgD3`K^9}@bcPYY78%<(?!WO!->RCP?JtiY}E -zqldKHo=*~woKGMLkhA3Wut0f?#%9*(2xSII2t6u*nOz@)|vS8!y1Q`YKmB6`W15Lm*LhaU*H?6bhxQuB)vAd_u -zi^}3|l0&eITHCpt7%ci;g=JCTDn0M#^@v|b=?Gm2`Qk3NF3};Ux@8>Y=cz|nBlp+9 -z@~JI2t{Tu%PsnoW)G} -zw?{NDX4hIlMVmG(w(eT`fxOT}WA?|42E^|3s;vj6Nljk2LsKLi*8w@1u!DEYyE{fC -z&v_jg{QC1|<^_(!-3zYMs{7|cadxE}3GngeB^g&Nn>Q4If6;y{gmIw&B}*bggE>L$ -zo!&+)GoOo1B{N{i2n^ncf2D~d2g%^|`B4Qc4ln>~e}V*2}wFe}a-kcfhkDkwG<$ -zf>WO|w*(USxMS<^AkAwMdgAlqqqdIo&mDT2~cLk+PrhDx$hH -zM9~g+lwoVsugt25FqYjlC7XOVtE|mwQzDx#!g@Aau3RXY!hP|LOd_c4TxKtd&S8yc -znU{VN+^*4Jz_Bw*DPAy={Y`Ts1gTp`p|V@~DIxIeJjgxDfu`*wi7S{zAchmSaRs7- -zWBa6iHGC+~<{hNrhF33CG5$M) -zv%cI&`t;0Wll6piSUDtrW>f$caF*b489419J>_Er=Y)$t?~Dbb*A3cFX=U9%yW*4IXZe?!iw_SuIzh@mKE@g1c)w -z^agoG7wfRjb#DEC*Edc>2&L2_H-gBk5%~7Ny_hnc^piS0mN$pAXg%K-&@A%w)cY!W -z#~#_3_L4bkD1aIPt{mnBaGUVt4Clq5Pl|y!BN$}K!=TR$Bb~iLs0pWQGT};r1ml=9 -zRuPWd&V&cxB5L&gAfVCkH3ozQ1_#+y4~9|AZ-GP> -zwAQ~u9k>m{ls3&=zVQCP3mi#4mhEjK{9$yOZ}!Pm%V#UJEZaN8G7^i7Q<(pFDN!8Q -zQY^#;PAgd%3Ra9+yM8>QLc?4JsWwM@e#F;m0Cnjf>CvR}wtxf`!+7=K>Q83A{RJ=!# -z@3X-X1f$IYPd(WxVYf#X-H?(|eO_PAfoKTz3>j}65Wcqm>yi;wI}ify@`UgmF*w27 -z2v?HSRG~RyYEmDU^6B51K)UV=gw2co;2$gjCRcF3AB6%+lSBcb9)1-%qmAr5f9jZR -zL)rU)i5l0q&O5NYRj#J-(dv|nm2;>s$Maeuzq|kx9HyaVMnn#cgch4h^7UL}XDl)| -zOB^zQX`{>I*$r<{Y$^qP(JXC9geteO&GbO<(c{nQ%Bl^m#S2?5gW+4n1j0)3mK=qa -ziw#lR1eS<78a52S;d7Dw70hWRehC`VG>&`~}68 -zg;RJ%4!d+ZJ@Kw-d`dewm(xeq3RcMzrgO`YC^Ps>{!4gIXx`Ms>Q~A)6P6*D6xybj -zjqhlj8AXd-C)&xxT4sB8vhKCObs%`ODuLo4CR(UPhoX@`oZhW2M9a&Qj%=#vxc=l1 -zpM)U{O)IgeWxOXO9%aV)$xG468HhPO(E@A5ixnz@YRz*Nrefhu;C*djsCPgJ45O5c -zP+umY*e@v(1t>x@k;s-UlP;}IYc`=1x@LjrpjsL*eS$C;b=!#UEEb&;-XY3P6h_q) -zSaLw`698yHIVqHno}LoEV|ZQKk+LAo#Zn`q#Q_U>T1(W<^cl%5pyzr}KU5T=D1tCK -zKqIjP8V&M9E(1>fdw=98Xi7?>-!v`Ci=7%Gpw~b{JXPJ)kJw6xb-8?NhL)Y*mT_fG -zHfVEoY_OiQDh3}8Q-eMF92UPsd_Q_HOAD*vLLBjkO?R@>G*yju?r2tAuBfXV0nq0> -zoRAl)?sJM^a4d)W@4JK;-nn~YVHDW=0>Ws5+d)U>u}ltO%rPDkcTdb?AqY?_HuUV@ -z7tKyLa9KIrLpx1H5;`c3zmy;VaB5c&HpbF)H^si7HXIU%hv|i@hph5Fa1K6UqT_&S -z&qct+aUMD#Mg2)U07M}cY|S!lZ3HJhDiP49<2Xna&-6n*EHdI{;+vF< -zns4A?<#$P=kl!Gc!%PeNl1(?tsOdzxR;z;*fXN>CsO^-mKi^IL(Ta~1p>9x}|FRkw -zdoPHqnI7sL%vst?woQ+U&s(d(>n<;6zrMB|x5g%Q=7S9T>fwSS0x*`%RGA!|_`?%UN?8((Mr>$a^j -zpr-~M8yj{b!FFmCwu^^TlVU<-7PepyG23d;7F3{H9s*X_Ot23Qk61!|O#uvEFQO^j -zXK6WKSg}ebO?x^ukm}j?Q>3v?mmq7z>uCa)^lU<;urKzn -zss=0YOGOyFg2Q|x{5uxyq`FyI$C4wpcpN -zKi9Ij#TtA_5&gl??hViYDh#8P9>-nsj1nsAA7k&49pR6=Q4PFFS)$RD{z`9`fs25N -z`Mxpu^G1}9mBTlN51T38+Z9940MNcE!5WRn3wLi^9D3!mKY+@p-4P#`33?EsUTWoE -zc^&FG>Jt<@UyJz__2T_x+7gGgY)NcQluuMgJtA5F=kOLpA@GY>Df9N_5n%N&HdUH` -zM$J`JYM?uyIwO6M1N4(Gn!-S)*@yjc&Si(DOwRZUo1xjye{$KLTN~;52F?L^LT9H3 -zi?LU2So&jm3t#XsISMXHBZ81tts)iJ1*rm`-h!EsvX{xd8Gi|?XNrUB+3JMIs-`2R -zkH{+ZrO5fw_aNlCgDh-tAQf3}c8xb8X*w#rKwsp^N3U>THy; -zTSApa6{Zx$_Nj5%f%^D`^+5P2-egJ39jez+3-As005)u@>*~~kL)&sijuaRh=3tM- -z+Nc+N)vtMuf|Y{_*quEFX7`nf%_O>)7ElemngtH)L+pd>}Pyx -zn3_o38~(27tK8UmTXp(RkDfhi*67hc=QExeRTza$BZZYz{6R?M -z^U@M+X^Xt~?5VYB@tI*F2;21(?@dd$+3wq^U>+Tv+> -z7^25!chlW0)Neeo^gn4yW`mVW83PV9C(SQbxZSosNF@_|Oy5DJ@-b^O{S|NBilt`M -zWWqBr1$5JsnX1VTThPCmR4e?sOU3vx*~egE2rzfCO}0dB0}7 -zIwI{?%`H)uAd_py-vhG`fVq2FVo!w9N`wb|V`7-fQe$vNwrzUY -za0k9vT1y(2wx>-8&FvN;9TXv7FNETXXa)Aeg2p$P3BQbRF{mZd)n$G^m8h2&QHyb)ykhGWtvG%->D3gvAY2|1`~h -zv|3xSQC|Y}XL0-3l2r4_REC%mz{)#o7S5=>!K2`Ri4Qi9NSyVLA->?A{;=8Fmg_a= -z^7UqlVUNnIjDQp9YKIaVf0fHY_*-*>IN~6xENBAJ#XAtXtMltu*J-Yy--a+ykhi^S -zQ^XOFwlF;Ode_(fWZ0w3GA(fNI)`%iRN2x4QU84Lwa(p71?uF^B`DMrdS+;o3+Udm -z-U0;hZuM{u0iPDUTOeLKn4|)bJJ4PXIC-)2A^{Ho8LIUOm^r;jYKLH7~|r*rl0?kxC6fI1dth9d#Ii;EDHyZuIg=-Z9g -z6<7)H0s_(cqvzxKDpM^eq)&z&>9mS_FJeH3dX<3TQzN%?gDI=;4hcU>e+5^?JOfA4 -z>g)2i0D-_R{7b`TjQkFyqau$UPoIDS4Plfd=Kz4nIr02e9r_eXaezN{B-z#3nx(z5 -z+KW%OZ+j1PzQQoy@GgQ(IM9FVqo*&~T6)BHFDId-wPz7S_4_L&_&agUEuP|=gB@>Q -z-{&V$Rbfp?-G}{OHw_g2{yh+Hrw6yk76@Zo=fPR$O@s&3^-g@br+aq@HM}%&1VgHnUR|~D%^X5_lv^PK5PS_{Z0mQcOq{0 -zcJP(iy18|5DMq`;z;1IQvO$3IsR?=M>|o4l^5wa!u2&#|p3LJPu= -zaym1K1j&oELk}jx937%${pZq=`?OG-C`5mpYWj0@y_0him3x17XH(Oy0;m($=%oCH -z>OC_qimiu;{;7#jM~VJ@gm73Y{II)Zo5b*11I>mnsx@;$3n99_SFanBrnul>Z+z3c -z_I$Q?t)k~2m!l|dVlwUo1o@Z2qpqdxP?ec?e@g3m;jiD4hwmb!W{Nn)oY*&68sWM0 -z%s51$g*Z0xQtjj9lHv6(A2nFSG|_Qn9nwtY&?O?jlmu@jfQWfHh5hMwi -z4AkTyJx&a~sh@4PDp)X@vSiSyzm -z^l~CqM0OMVdaI>vATo_yZV*{c|QyaIPmsPz9sgBvpC4I|B)U2H_u2d&14DM|0WqB4=Y3x -z4sz>-(@Ruf}xpQrkLseg>Hn{SG*u4E|53-^^Rzo`Hw -zm@IqT?w4U7-oobK`-Yk(q8zj3?_?j*&Cx#}{ir_6%1bpe%{@ayIK`4DmWj^fLH{tH -zu!}3m&hfugB0s*0<5IMx$B0R27#SQXvB_PDH7a>aE0M}*$(&0EPwB85#U?9=Aj&JO -z2D>v32<4?sx}tta<;kR0Dm&Sx8E;9+(BG0F8i&P3qA1P+hOCT)j!_G?1Lf9sDEBSz -zNsgcMIb-Y|+h(8ZCT|YPZtjyE{0K?#$+pml7G@S8Ytu*R2TcyoZDb-*!wKQ<-UMH- -zAhsf#?%e^$v8$^C1HSE$z3j6$C8d$nj#jqSv#TvK(yMcS|0Qd!j`WR-%@Ll6BaG}^ -zjM9MhuC0pn9=ywht*bGuqE6q@C}uyuXAi+-gS0L;!BPI@4fzoj1YthwRZvSgeFy7@S@K+*|0iZ3tuvcytl-jo%;B@%ll!Fj?QiAC>@GJFQixQs==i!@oSS0n_P|D(Fg2fjId -zKG)s}d)Dm8k5lNj9bmr~_DGhIyOPDRYaK$F(B1Q8&X@iGUnM%d=&(9ELI}a9G1ZUc -zg}S6`fI>b>qW{Lf%+SlQ9QfIPbe8rg5jr -zS^N38661roN#3!i{y`;#lZxp3`f2(PNMBss$QteQ -zgBo=m>cyg;cv0zDrxcs2jhQATleSzhJsNt^C)w0l$r^pEP#fT8&>XuhwQ8e-jH&GB^sziA2&L44VNk4>k#p|B! -z$WDtT+Kg2KDl~(2wHD>FOMI+N5vihj#iM4=XA5%m@ynfpWIr_J7-OYy8K@PV>J7sw -z@%$f*9j^b^#txXr)!`aKTdP$+pLohymskbkl$!KK@cw6ZYv1C{WHBF26;3IbtE6&m -zzWlY!W=xCR($!M$OhjV~1rJD!|1*g2?a!(JTIE%8Jo1i{NH2nVY2; -zk|C;F&gOF@H=3#-Qa2STuf0fBGuy&qjxHtLvv;-cS=Naqb5}NgOqRiTnb?S({TzwE@UBr#6t` -zQ+7lpBf6jzUEf!CN~J;r-y2KKdTk>0ZYsVKT$B(2p}X -ztkds9)mZ(5xL;Y{-eC;#$ai071~?Sk(LiD$W_g@nh>|U_KVa@QlOMh_&O1Rte+N>^>~iz -zJ|tU_b1RM&er7`Q3rv^Ev2D}7QpC&viINW5cRzL+&|ufRzPCB$0=_H?rK{k+RX;z%XLYZsdr8Q>-H2j3S#WE~!iH -z=%mG*Rf389$;a}WyXDw)(Z*q>9*iw$rXq535}(Il97+3L6+l%23hUY9rCh0^&I0#4f7y!Jg%>EVT9(U63HK4E2tWq$B5~M -zxVIu#lxTTg{wGeG~YnD}l-zMt9pTkrA4&xA@eGG7xrXl{8p -zn?BB-hkfaqhkHaqFg~*;N*hxf&+&{I{{FjGO7Htc<-rx7O1t1LvB-80T{5$`SI<~Y -z8UOTLF&pZxiD4;-_S{dUiUE=`QTCAP?>y&YjQ0uzo&C0gGFO?2)XdQ(f0R7w9QWr3 -z{F9tb2R#5PjOpp{^(m`JZFQpjuL8pkJ#|7FR* -z|I3m=4GJC)EQ~DBnk{blFD)5Uh8h8|Oz-~Fl2MlR|FdLx1dO}C$=>CpoQ%0055N>O -zO#Y`OWBwmY#)>GSWNKN(SpU_p$N$EXaZc+LR+{`k$G4>R<`*MM2IMQNY}UsjGtSms -zWKwF*d0o&RUB7KN@_$sXL2dGAip3IYrlyth@cjkxB8w3{sAs@hg>2B_-i+t@`s`TFi4Ze{N<11+ -zZR;$U5_tb|Mdt~m$TD5~(>`4Px|y|Fy(EsST&1RPs0r5t?>!THWj -zgv15U8zQZNq5sxZJW6v&wFGm|S+=7N@+Mw5WDCkuWYy2(N*E)Uy0MS6!QZ%J?dTbC -z_vXfa&ilml?d;Q#oL38PXupLL8MQO^_~x=X`N}tzgauvE5G^j14mGY(f<0nik%I3S -z3j&(GbIwjngd3amPENMq8S64#r3qPpVAO_*RO#=p_gk$SXI71zOB;FFa1vncS7^@L*)Nq%BUxW5ZAMv -zT~i_YH!CaBCnh8Bxw-suVy=)Lk*de)U#~ndqW^r0pJa{pHNaO9`#e#5AWM&YQaNuF -zXM4zQY_ds=d6qMtQ#HKa==ukaJT?`hpDB)_e()i)GBz*_=!oA&=`mmEf75)`z-xvW -zjrj$s6mEanR5}8_dux6iM$8!hA615ET)nE-@Q--oJ?vzE#Mb|sv|u3o?@0@`|Aw?M -zOZkViP)`0g(xUCxhQpUNE}iyF-F6_HV~xJkDK}w%3dMkUQS`KzOD_1`xA^N&kiODW -zb8x5jlj66g!s%{OgCOcZa*U-y=qC9@jqB=Y_A^|+{(N>K{Vt;N&@Q!D;O26#QMFu+ -zdf%W*rp(g_f23qobVNa#Xf(D>hfV7DqcF%E3jqejd80nl_8Z2ketZ+t5RY)tE+%#- -zO-3cr9X*4H=ag!Z8u5A5NH=ygzi!YUD~mJuKW1P1`)88O^0V&Zs*hLr3R!uJCS#-$ -zAmp+0cGl#%X)^L%yL8!lhon?Jc&sC};kL$AWiT!82OKrRe{p -z={T}hcplDw_E}2s#9|J8k+E7{@F}oN8oIwR_tof{Agr+>I~m*49>xOG5D-OJGj7n( -zt=iEi1P>*6q?5O_`QtfE@$+-)a4@zf$*Crqt=WyM8E1c|G`rpRPal0wqN{8PB%7Bm&8`UtSj7m-LS@R)|#rwM_+O|6{dlKkt`5`hgDGj1lCE+r -zn1GW=N)fb%rwO+H(R}`Z2RSLyW3Q&7IHZSJ%;6-@-Hxn%rTowF2cJLjcPHEwBEhv1 -zqfH0i>vVV{DH@RMUhAsTuzcWsmmc~KkmdJCFi0+$**( -zQ??ccau|@&ELgD$)QlKj62E1iymtW_qM -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 -z?+|YzmT)nBw6<)<9k=$*JZQQ`H1sAK7uf -zMH@XHM|5U(?l0jlyi-|bN(=|wpX0VvmpdmiGFTUtBE;XDD|MO#jKfID -zXC~dOI5dF}0|g&8$}=41;C^}Pt2kf0gr5-X1YJ)bw>kZONH6N^!H0oD$UYMVBRCt4-7>( -zgo+(PQ6`}glTe;as3W)5gszb7>%>*aBE(|r@5ZVr|q&WTPIPpU8`FW`_9k%9BUMtg}aHixTRv% -zr1-p7+xq$(T@iaGNnW@e|E#_AIieu;pk2Ij2iEJn88yB1Sv-bJ-n3YR`Svj3>qo!} -zXuoYg9b(iv{#UoUYx|w;ww*r5Y{VXW(wA2AKWn4gZ8g3vD^><{$tja^Ys{=X~HCM|4*J1XGdjcoB3hfSwP$I -zuRRaI4Fi-&E8oLroIykwY#AKG^4_h4)NA|zCmm}4ZG8ECu+vX3TKmzSQJl9icj(uU`>w|Axj -zi5b{MLCx+XKTc;V?6TFKVBqtj)EL12b_g&~*$}WWk?8Y3QB%7D+zoBz^B-KN*j^G@ -z2E0LIrXOJc^$|f(3UosM^WgiasA>Wo4vU2_BzlUSH0dj(WEP_zR)om=`{)66hn7g+ -zSH1#t&nz@NEGg-L#MEpeMn=?wcvGdvE1KCQ -z!J-l%&uXWOWHaUZ+-|}>Txz7gzC5Nvh{6#{O6Rv{`d8v$?7l)S~@)PoHaqSHf0o67SmMp_5j -zD_sM1&Q74S;!@!wDE$sG{nnG`HhsFnptZ5Sq^?4^<7Z{7or0X#SCwC-fr_ThWum~CKn40wGR@7OGL@`Ri({;rJPZOofOaIMl}v8B_=Tw)KD -z@ba!Vb~aV;(AsNs(s0)>xBsfOm9%@fn1iDcqc@&*>%MORVX3_=XJpFF7ilZ$uCY@v -z`dQK#aJ{~wQPq^jc{}B(J2$Vtk(#?O`^!jCMbjAIZE2*q6yXOwdd-JGd9R=aFQSnU -zCl01bBHV<(<27rQlfHb(DvT}t`Bi=b&K@p}P -zfp?E05fG@^@0rbcqDuoISADHzT3D{TI|APX@thLt*gW)fi#~DAo -z$`vN9;&1O4?j&{BkSr8)vl;{&eUuA-98O)PWvbO!Ys$^d$1cYIX*`~YealO80u1WM -zR8UZ}IahnT-dQbH->3CmO%~pu-G@m##YC$}+P* -za5$slf@_o65_jL6vklTL;lnhE4$odlvf=M;BPU^LVKFVJRDp9`-I$bg0zQi=O|J~Z -znLA2{j|*&{lLMWWO|w+e)zst}0#s6jfE}FE4|q9-000-TpfbSc$2AzsbimWCIihSS -zJvFs*=)3o$O;S3^iW#N^RvYvJaY!O!#cDG0?jG7g06HyX%1d{ -zKEEA7mB}5UWcLuL22;%i$$%3=?;RNW8w};+gV}^8!{pyQzDyql3PZ2_p)9nc<8+J@ -z?+B7`TCr&iXEuRVTmph*Qks8%ib#nFQq5=b5KX*f4gMPJiU -zCs{>RugxpK+*?9S(pkfPOy4v>#&h~~^WNOvpCFTZj(uL{G4|=LHum)XaP#u`)Cy3{ -z!N0+4u%46J@R`th%t|+R=F`cAU4mp>Q@PId>XG>bPg)f+L}xNqBATC{eL|v;0ElUt -zQ4`yY-xNot-ohi*QTStyef+GFon4ENCO7UU0UyBzkl<9_GQxScl}F4%N$tle<&W6P -z@ubGAr^Z-K(~2}{z%L+WR;uw!b#XM+Fuj3qRmL)5i>$Ld=7Qx7*eAcU-My_#hgFIh -zT6JW8*f#xKnEK@+nuv8$Jn22 -zw)F)qu$MY&$Sw5|O{Aqg9ovI%R6}e8TkZ$}Zy#PuTJL{E~=U>j(q4szH%i^p%DSz -z_}q2(4mJ!4t9~?htv%dKFFcnHfN;lELMn=;A8xcxhU!gA(uZvX-K#mfUo=o!hI2tc -zPED~&*Y@j!x<%W-^mLo7qHuLBDLW2GE;G%N9d75GyZ6c{pAD6}`v`Yc#U$<2vS*WD -zQ)W-;B0#X%esb5pjcIwURZ;~1__{fGKJxU0wfn_gLwCvMV-UpDUmcbZ246EniE>r{cdauH|K2DyirewmBiUF`+T=rIHL$ -z5_qoNZnG?|Wi$CCXs$+CTDSCY!*iVab8GHiow78r{rUj#v!|*0dOpHtu-ZDtezAV^ -z?l+qeH<*WU7NbrNNbHt1vQ*PBX`{a-0RC>l5vZVI2co`Ya;;92i#8E?kKK-&+ocaK -z3hF6mY&CBRB=;3NJfyPbsG^bqc2^w`Zr(*2+ -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 -zna5B;yL|F#p|`Ff{`rtlg0j~1{ep7Cx -z(}jqYC8uOW{tm@K2kHQ!yyf*VRC&K2b#&q^qR_Iuo^R|qv&pYs?@&(FQ{x@;lbWfq -zGL1mrTy5>IB4)!57i{5d#{JS{7S^c<|6@x6uHxL}9IquJyI{McSdy$Q)yb}rJ|fM} -zK2T~!{Tx$pHp}q-IQ;ihg-5DzZlq}w$X&%jXHvPM1(S`Os`y>joUQ-$$c@!6Ry0WS=QQ^NFpC%F&jtLZ$37TtBdk2P@=ATs? -zVByu=S`sKoxRKy^?seuBpI08cy-LC>MP~Qn7dg9v0 -zGA9M<*{rv}Rc!(^#c%(nf-9q~M>c1Z$A06cUl7Oh^U;mmOJ9q>PCxJKTx-nS;Qm{# -zHYuP?%i{SV2XdvuF~ML#pMOW`rtE#YHl44P(jMA~4;u@${oxNoK5GvOFQ**z9PuBM -znPv518Uqg&hdEO?%0D6lW1VUr*R3q__Gq;?<$UEF5GB^<&Un(S{bBTDR{9cQiEH@6 -zISl8q{+jiqa~RQ}z3_B#?~gmr1-fkI6nooRw76C}=woH`+-D;_(WZ(5?2{AFjo6X0 -zvQeIVmxTrt)pVYJzWTST^DY#R&x+<{1O$m|zVIvOH~A$lF)H-EP~N)Hla)ymlkzvDv*#-tF4dWC--jh`ZV<<`>lxg9UHj~-EaI97vmIP$|u7QOwTVmeL6t_xPX67L{qvr>l+iZ4FHA^>(SJ_BC -z@vK(ORKuTI6R|H^-Q|B~L6_d|n7Rv>Dpwgsw60aWSsH^2KccN1v7}+8D4j9U6^h_D -z$An#D`B7uHOB=kCp`|?RTLOGOZhF2g+Qz|^Y9B?%WGs#qddl|{*C0W%lOXgsHahLY -zsQL4L&<6VP5NLY0=#Y){9G(R|bq{VN-PbZmbW$4INEtfRR9?a3L%*SUxYpLeIhH15 -z@j7zSe=8{(Ii6b{B1hPaAGe`ol6g+pY&X(r?9JhN=}`a4D1o646`J`Ms(3{29*cwa -z9Y}qbd -zgUH->k`eO=LYWrzpHnioOI`Fk*rhz|AOZ8sH6|&|>Ox^pPi#}k;(jA&L`H4%wj!|{ -zIJC#77^G1lpEdHpRla4L^nC_pm`_Ds8Fnh|+<KvW>Q+#3@x?xO86jSF*NY`mXO9%^AC9>md_r`>f;R3D4$xmqnVUe -zdpsna1SKD0#H2zfA&R%}*0#h<-S^!qe2{1@oP2xGDB{o6o*j<)1|=@$yGHA#Zob{r -zol|&x^=G{n@XFsNSNGnfpE)JhXI -zv$VsRToqD0Qku+)FdNAmr;F-c^4p08 -zH`Ez`b>H^-LcObCAgOk;xy)OgP4qoy(5n0Q?J4AAf?KE!TH{niGRt$FTaC?Gf80W` -zX9s_4gTL(-$AmZ0Hb*nXHFowM{*SlQfA1r9uQTZkHa$|VcwlG#m*yyM+fr8 -zRd}THO^$BBfj8!eh|C42+jKIi&L8bioo{Rv;gV-)TuiATSDF=D^oO}(@s}1{PzBt{5Ta`yT1AdG=q4{8x|AWRn -zgR|8yl}Ep@ru5HGH^hz^`_yws_M4Npx9m9Gb`l+0f{x=}<2oc*tbaVp-@CDy@YJF8 -zG5R8khK!C-o#1}ioI2SUL$+1O<&)nN%t&U>V2-NOp_yqvcQDENF}Sw#oP+(6M*$N0 -zU+a$+Ws!sK?@Mzkp88e3VbqrP{d38qy&|%Hk-wEiNKR7?HmpI>XwU-P+;rh+Ts&u^ -zwdcxnP)D)kcfTWyG|r*(){XVp8A)|n9WAg$@@PjoAEs&wHW_@6j~dfRbk1%3#sh7+ -zpH(3}e$pLDS$oK6Z>gbcAY03=m~Emlad)GsS%fq~(vrGEQh(NbTPpABq&VjS&8}9` -z*PXhsWs>;>9?XwVFK?~3>eoB!oa5|lO$iJC6M;CLlCDepV_%}!w* -zR%U0}Ccj!CN878@2X_>+gM_9v4{IY(M}4XdX}i0&sFGY4j@Y>GX_G`!cbh3kOr%$B -zWt+($Pk`M!{W&w{wLWw-B7EN~wr? -z#%GO6(&wJa*D~RcvF#Q5R3n$?*LwdUqP0aQ(tmRI-fjAbRJ+gQkS(wC_JNMen%SP# -zM}^sJfp*Mk?(@P_Hg{K9G0#ug#yf%$-x-zrXqv_l%D7 -ztpta+wwUMKAbn5w@6cSWwKlgi$tx|IgY*Bahy7~A3|MeXe=O`&z0r+|zXXdv%iHe9 -zO|EBnOdWM0*u-%0udlP-e>JqQ{S@X%PYAO4uA8~MzE(){8xOXpYS+`lTczF}P; -zHP;mf1@vBjJRfz>TRk9{xY)|AFlg{=o2Ym!EPl5SbCZv4^z1ch^WELD4$jAbFBGW56z{3aEbwY5=u6S3|$QBLn&TD?&vO!MI=|6u2_r$>51oLRmk -zyN>P%kKdcBU##U`;oaTjb1i!I8a-u0U+BpOOPgk6-Gg|$r(6A~cOqO2O_UCSiTu4i -z(Kd|_Iyda?w40w;u|<$nIQnO=BFKJKsH>NnEyW?-x!VZt8k|6&hdh?BD -zswXRb>jvP=$0I>W8(gCNj^5GZ?tsMy9|}UXR0W|y% -zL$0&8=GJ%5Dtu%UD;x!7PQ%k|f8P6pJqs~|mPqn#*PvOO-n-WOM$8azJln%xnfFn* -zHm>-ZSofEK_mMq{H{6p^_Z%#*oj9rf;$yv!;A_K~hEegcx_fg&N^b{$*6(9%KDM&= -zZb02ahQs*5o@krq?!_gY``rIXy_2k?O|mHgzlk5aa7NhI9W#54*>*RjgO0hbHyj1K -zSG@RX+`@%0ZI!igY;UgoDx7%&De7CD8%D0&%E4L-DN)~=a_pIpM>^}6u7o!7+_Z3J -z6VLLZmxeB+S9IHT%E^TwJW@aBZqrP{f8V`M{pmiCORV`~CU$+UJX?<&c;^D=uMoF| -z+RLAH1Vy|qvAGaW{wuck?q~;Q3~h5KlWZ`5`PznaZSKegN3AiU-ag-e6H@#5vi^PT -zGjTKfNYYV52OaLf&f?eNGBhgcb`JjArXASvq$>amA9-p=mb -zoA|w3IFUB5qZ(Y?Gjj?|EY%y4HH}b|`Rr>r)25)Q`uSSO8}y-s;A7^sRMWG6X;P|& -z=RzUR18~(ljfWYg%G-y3FWPQwWw36xkKl37)W}vSHh%BoamDLc*p;F*N6Px5PT4FP -ztvR;0Ct5L@GA6R}AEJ6j6R8~61Veje&hP26b-{y_am5xN+NFjIJ1UY9r2!x5?VjuS6k@ -zR>+F7s@tv;d^pLdT*f8&&wT4wuXphUPPy@P@j{oAf3^)ub{)ny=523kE7}y2l~8%C -zCnRFway&ZgWK5fc^LjDIk8`lBOOLKi>{S|>)T@Rb2GcE1+W$Vvr}PD!-`iLS^*y1> -z*pir1%+%W%;d*qo+T!Rr>xQ}4Ln}!!;&(5D=I_=cpUgjc79*}4fHhf{T@YXIJz({I -z$^q+utMjXms(ZAKB`lLBUNrEf1@4zd0DXt -z`*ZJ0<-9=ZIE07jGzEjle^UgY*7aOP@MsuMF03Q(6GgX85|K$eKiuUF0002|7g&fm -zqxG~PqdtPoT$Q8p3H4K1zs!|2-tR{B^@jQWktt{{D_DQMH;kJTdmc)cf9t^Cdt^vs -z*rmJ1&A*29N2Y9=G**f!iOdp6HcBJ!WO-aZ>2tGWEUlX~7L=i1&ACgFe~JutxL2L9 -zFJGbE8`hoC8&=q^ANl89E!iDPwZU=L-L3wad)qRDek>~(@K*N5mPGnf&~ccgS8Gy_ -zK~s-I)9kG?h_m*F>?#C04paWBqa+3UrCB|3|#wNiYOQvTzHISv!=^o9r+@`)V=oSs%}Ro -zn!5ug4s-X_;F}*6+eE+kxOC?>m<;+hthN>!35wQ5H1%~ktTPtt^pT-^Vw<4g -zz?i`u3eT;NJg}WZEQv%RF>zLhhJxPTQ@ZR?yxlHG6$YpxN+P!?M~#C1D5cwUISj5V -zbe`pJSf_F~WOw2s8e=HT{Hh%lj=e>xu9%Qv -zvSzwTU5T7z32XO&!qbVCUqNdyD(4F)yBs*_ljy<;W<;}03obg48Wjf*U~+2niGn07 -z4c16%*Gz$n!kr`I;1`)3Ouj-hPhXg|Gca9WOgH^rcspzqlpnJow;D6J<1BhS -z!Axupzk6O3UKtf<)l^Ey-NPnDK4|i$V^0)JI??_JK?d{sCDK*uK+Zp#U^=v7yL=nA -zyr11jX)UEQ7URzI(y=z=<}vS5OvjCaD&28J^=kVXw_p|50)(kfv}d0pgZ(FDa`oyB -zRM^k*owso|8+r`Rvxj>7B~sHdqI14J=bl1_>QidDiVl=WHc~oE>9`bZl;hAunnGrD -z2UoNK$upoe+L6dD@z#mG~=ka+CNI^ -zk4ntfJC=;q?ClLJZbwiK;&Jq0Bf&4V$^zHP7*EpJ&zYu!yTufQaT6UO*%(1^$2GZ3 -zM%dG;M7?2;+8tDxIx6fSoOQHTiGAfqcN{W3^{jyJt?WX!h=d93p*>Z6;SbYM+dUe* -z{A*@^^{*MT3R%D;Q>yJJWSILi$*)%D!@F}|ddpc`o9OE1m*$R3Ou;5aW;8YPp~t7A -z5qKO@x=|WXtJE`8_mzDmzJtN#Hi9HB$A~?IWtGw$)m^UtPH$MRs5fjtb9hb~%N|lD -zy5k&@BuSB&0@v<8TFU9x-#5|WbqzL6rS$GRq6ulN)RE-dxYI;{-Q7foN;XCmx#JXF -z4&9_Nymoo6OZgyfM-v??-DnoT3#`5Qm8o8_-CQB>%tlnrp!NVpx-OwNHZqW2kkXR4yceSGv&C)%2oQE>yFOpeA_;mEo|`&s^}J5csrO6WC8wc&(p -z0HWwIl2Dvw{x>IZ>q(Iru~BgY{!5KNzBpAKzK&#r7SRn#_32urh8>iYB&$6-i^!lG -z4Bn-T{D=&ePslL!0Zrn(PPZTBmF+}S$t(F|O0`1W_7!1-9?oLh=NFt8?K(BJF(Tg` -z2mL`2R@B33^R8`Om^5$^^*Ts4Mx?sqn8(!dc4);KiMt)jh9=G5z*(Pu==-Kvr`dfO -z^!@%xZV|H^BP!i-AZjxUP -z4M>SPeX#-VJZdDk8Lm*=DoKAeAU5hF(|5}4Z*D+h@+s9?eG=)>u|lN1LV=%PW_hvB -zxrn;_X$|iF9~!?zy3vJ^}VZ{LqVGFj-rI-HvF2(l&r8@ns -zL>fL;D7079IjZw~ch%6O$B>aAKU`4<@8@inGi}r>ay1by`h^!6Ctp>oWE(1GJ};t6 -zTd+oA$}NKyc_pPfy-ybI#0B}J~c -zqBYdLD5XP_u}P7EPzn^$5iqHfu5%5&*k_x47}wT2~xuqiiDZu -zSH*Lr38tof4BWe6!1OO8fx)C~vGZ$1ot@>wyrOb97+<+csV0{5h5G8AG0H7RKzGPn -zjyTb-#?>__p1I?Q>WMJs&}JTarm@AKBob~c-YDG{u827*J2sSWV<4AQl-Ds`L|wLH -zMgpHnnVhEX^5TaROyjr0wvYw63o@8oF6E}@<2;gNmFn)F7gUV2XBAJ%O&MiBOXm;IN!!>%9-be%f8!g3dY_U--`Yes -zi;R<7)GC$dWMjHTbc~lObskf{qlwO$+9(x=)9VZeM8Y#Z%AM-GmjvFSw7^-$ZzWPh -zmxJ(_LXz()zuJzFx?3pg`rs_%en~{ihNkq3Cs#J+wZ?4k4U>~X7Ha$8EdNPamR}{u -zNYvj|GIlhBh^^I8vELa9zN}T^EBb{gkqKPVSX2gmCdfir*92$rCuCL!J;<+$?_WO2 -z#BMt$$V%aIb5pdPXAW0t9Oin=0w!su`%Z5d^Q?bnaCv+!Y-CQl7a45UFNw&UalG^-TA3`dK2jy; -zhAhbQDAkAxJ{ckNtqEXgmm_>yWKg3fIwLAhj;d8&vWKoH8B5dArkFsdXiL4=Y(kc0 -zFd6Et+I3IiI;u(A-9)dYH7E+)ajWx*zx0N^99wMj -zZ7HRvs(0?er4!8A1zfX8h+z+5n@Z{D)PMWXX_oI-gsgArH9wUxu~QH+DT5oR_w$l+ -z1S5HDlcC4=Z{Vz~3E9B+iftkjtrl$E&$G$<4cUK~BZFhsMTlSSrJtHomQs6#>)%2- -zO6BEHKNTw|foqNj4-kR>brG1u5s@d$=yIOivUXJYI=df=phr;W-cI&Mv$g9IiGj*{ -zja%kApciFLM(mo?z0wNhhVB@lPiL8op+s|kL@FrkbhloDSrK|4ZX_mJVf7Yu@vpkK -z!PRBimL}^&y^4#G9p$QUT|KDB&(THCI6J!Y_mOUG*~Z>Q>Ht`dsc4eXhU1ty7 -z7D8-OPNY$S`N}th!)Qmh@#d=T#}G&eElf2PU3$zg4}UM>GP_EDhcvXKKYF~`?$yBT -z^>;-OcxVx1ST{4`H~SF2-H&#<+IJ$Y1e7cvn -zMB(BSYqFBzumdL_;o}d}Y$zHIx_zdpmcOtcpv?xeS(fE9+tlZ(}@lAKxs7m2S?pEce}w -zx3h}#7KEU5I>lDLEPXy`qiO6O}5XiU4mm6L>!n!z^ -zWXoUJKcEfw*azvlsP>?|whaZ=ghh@w&)O_r^FU;92;Z&&Q3QcZFA(Bx72-?etCvm` -zaxjE{TgX^C5&ESg?9ybx(utf5DEI($vgP!_#sT!j1>P>fd2fk$mgu^Lc5&#h&AZh-zGOfnK^5KmdJoD=Y}i8}v=_?^Mm~?S<=4;pP-t76 -zCRAbpyDWLr|bQLkFOaL%jrs{;;{8#eOW!X0Qz9)n>Ibn15T>__VGs=BlMh -z68fAf`d0>8kj69mj~_*e(=HA|o1p|a-8<<_5`Ka;zXKQX!fZx(I36|Q;2HbI_^O`& -z=aZRUlTVZLj=sf346R<-pmN*C)=~*i1@vER82ABu{}Dd=c|P9D+J33pE)Lm_H>b@i -zRBjbyS?XhaK;&Jndg1H_rm}qoMPDpMdfhPry0=DmG17KzQ#}L;?)Rlgzi1&reCdUY -zS&*jTpj$Mj`ymTN!@UHOrX%d=@I1sv(?M6HxMleZ+nk~AlFhO-nX(^mzHN=m3yvIb -zP9r+Pnz!)gA*++&u+N~6@bPxETknb>HqiW~lZ+Zr@Dow@EKRmD^ozFSS|-gy#=k;y -zt#Nrfs3z^kWIOk=!X~I3V!NXknSWP{qA`6td5I_P#Mt`3*Q~E*#37(T9F*69&tr&wBhAn4@m|wL -zEfw`{Eq*}7+a++&&5-O|`a<8nv(R(FZ2wSdXG0QUvu>w!=fCGp-q%r~MF}uhMYb}q -zXeBfMm5rW7>xl5wjXjU>(VN72BhymdD-?C4df!->o^ -z!K9Fxhfrsw&g7ijG$UixknTn~_0nL$94=z$a=K+X#z@_%^%S2f6`3)Uj39Kk!K8|l -zb32_mDLnPe-EJ`&Iwsac{{uM=x<4SZd5JpNEQYDJ|Kr6zvFfEGEKTFrrLlfTL$xM%6alddA*C{#l|Oawh@_L%aK+z -zw(-NE{994ub~H}xu`tAf>`@7E=2@fCHr^f9Yd&u0n!7>xD^CpbsE}F2JlRkvn4Y5} -zDjM_g6Zc`d+AXvvINRIuAxF3I+pU=Qw$nkFkwJxeg+@-Eg^l|aLF8h&DSWFa5r)m! -zyakE5#v!*vTg*m!VQ>rFwN@SvEz9dO|D(6j5$jVG^L>BTrAC}3ZrbNGI4y|0ph|=d -zji9Xbj%C@aE8zhzmbYMcM4g0(#Db^;R35CVvtTjdbG36VhYTMr)nV?5AYJVr3)EHB -zXmG0#ACPfmv3Pu~lHjn<^cOn{^cx4=F^i=#?8XsUmgU7u9c6xSs)x}2?NXwb+fY$n -zo_dQbKb`fi2x1lbp*Bf#?7;`!&5Q#}Ot*bmRBHydfE9^zlUYMY*w -z*V{AVRq}dl^>i+6b*KR7xHu(($j`Q7c>sc}viW^3!TXvZ* -z4Kf_=S5%%e7N@F!p2xNh6Lt0XIlZZV%M6XL3hY<$5+{nW+n+!Nnoh%x4pHqg%v=@O -zqV0XE!~_IPdEf#EC&OX0H0hTpuP=s7vFONgyZ1!oudrsTnRy6vI|U!0v_g3u9&)#` -zMtMm&9}Y6!M!`R;JG5A!(Ls^p%>|UArE#I&|ClHbFFxaDYK`(5gMV0dpCmXeoOV$6 -zHJ2oROrc+|40BtM!=iMhi2>%8SlSw52rD*iv�FM>@ZLjO++IYC;|-YK{wkL$yel -zAAXFr=~etW3T=b4KoxUYG+i?oTZPp^ZPP~imWbye&aZk2fu39@;jz7LpV9<1{PMnY -zLR^{rF(e^Ffn!V8z26$;)w}P*Gb>t1 -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 -zljm|(t_W$exK7EuE3F;f;-BTL -zH4PW>RCQ-6nUx_7TzBLgx_{`T@J>@%@v+#@h50!8+(&#saU!jc`%n%Uf6NC1vC!~Q -zAH63ZR(|C8BR~l(Q$e5vmg``k1pavw15;qRCI+U!GF@o704^Kh -zQZl08;==f#urxzxV<$ -z1(s=3A36Tu{|GG;e=r5W6aZ7;BX=P%1(xYTA36SD3M>f08D|8+l9asSgs3w-1vhjuw4AX6aZ5IOo4yWg$&5iKOm|@$yK40)5T^( -zD)HunWKPb(Uw2QcsPf27hcBeKurpq5dHRN3($LaIJgvIyjrOddzOL4FYHK)y&R=&{ -zOxgA3OqpwLL`1f-%0Ku*9o6Zv88@8fewoa4m1Iqloc!zhZom8`hV-w)qR_@E1&$bSQScN|8?q*9dxGNq$rMLnHF0#wYp;e^{R}Beu -zyp=;Q&Rmkdrbx;9LTFV=t}ujN&rDAYW>RO`*HE!!+_ye|2!hnWyC$FTc^ST}ggk#~lIy0000000000000000000000000 -z0000000000000000002~y~K-%1D@uP8nOZ-6R#NA@c#MjZm0000000000{Qp2P -z_;>yYz^4|&(x~CO9a_L5W`~Au_b1+@cQ4y{T=b^4CR+mP^JdL4FCWD0000000000000000002^cfkqw)+cpl -zT1Ee-{~ayh??s{SJo|dQg!)qJ?}&-{J71la7L(%E2P>`^{hNL>ROsFZE0$Bk=Y{|P -z000000N~$(Ec5SuJ0fnf)z&q~Gy-hF0RR910000000000008(mA-fQZ_x}>) -zHIEvu`}h3q*l~P+XU6u9(8{&-|La!@00000000000000000000{>`wfqxSgb7AH(K -z{2fVHZ$giSPFlYBJO0XF00000007|M2eU&%xBHV%UVQQimt%A8_Rn9P`F8K>#|KyL -zvNIq5edoW=*9ias000000000000000004h~OjYTIzFFb@N2Sca_2mHo00000 -z0000000000000000000000000006+hr_#3n>$d_pp8w_Rtxtd2Ks$eM#VVNY{*fU7 -z00000000000000000000000000000000000fPYHXW(t8%b~FE;|8Qr6r2lVyc>n+a -z0000000000000000I(cX-viIBU;gs_C;ymn_Wb(r_h0P1{l{m!E|2}Wc2$Nk_KcVA -z#O}ZUKb-^s0Pvs1j9}i*?zQy}N4WhhA#0BgKMN|ZkpI(frUC!}000000000000000 -z00000000000Q~ooA=UR_1fu??_h2yGAtA2vl)ji?000000000000000;C}=~m+96* -z6g+3}Kl{T%|0S5AfA6120{#zs_X6ESwLgx&4_Zo}yvn0cP!P~YkXJyUF*cTbMT`F;4#cXlEVdB{T^|J#o7PkZ*H -zC8Q-Jn7iH?e)E7KOVV=R_`Ca`FMQ_d9&>%c|0@d0Lmu*whdksV4|&K#9`cZfJmet{ -zdB{T^@{or-y!TON|FWz9XWut24|&K# -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 -zM&+hI-t9ACL!@}Z -z*8hYng#!oEePvnV!R#)Rt157C5ap`j%GJF(%4`=^q~F}f2A$e0GgI#j5fk<735{UT -z5W_rS>uol{t0882!q&TN!WfOP&lw_Qp#FaYR1E~GI0DpQDNt}C3e?uPKpn$C&5#0B -zjDf1fKo!RTH5dc66$5oF2B?)7s2NhA;7U=T;9(S~n___4Dgz}0_4@#oy%FTj%l?2! -z;B!Yc90ut%fyQJiMNQuP6uzP0If=g9kz(T(uEosgX~j4`cTx66(3Id-+|1_=Yd8!_ -z2Kbsri6u$Yq#d7Qq2M`V-HH^xX(l{OcPo^9Q>s`p24)QOHH{P72RGn53LYl;nsUYV -zRBFLU_@``NQ?l4T8Xl(jn#PFj$<+7o0{@GshQpvB!B;j|EEo*w|FhwHNj3aEVpitNY$!*Vb?aMZLOQi@l(jyhBa0MI@^tn=DL$ -zGekrRE6NkLrrL<*v~>huHiiQSlYM0)#e)O8Os<-}((TAAHY)2mZ7tVa)T>)= -zv1=Q+=HgymhsA!Wio3L>+p(g^*tUgRQB1yT>0{?Owd;$?b(TK%X{Xj_VX`&CH_i~T -zOwZn@A=Y@p)(jg#(B6Dc*gD2WJVRRt@~&YV5L0}vF`}5@Tsx5u&qfYJT7G{V>_ycVi&MWi8yyPy^j=Df)j#xRK1HlBhVJxp4 -zCpIT^nU-$}G!LMb*LOP>ZV5CeQJV&InU>cDf}_OdRBCxcw_|mYaZ?htDZR_ou_e%) -zLUq)4JFXNNJLADiOTW>}ad&XBND&rZ?^5736u6`*ab+mOPy4dp;E({0G* -z+wwTDBH7nALR>MBdbgq5F{jA5ZVNZ3xL3E&V*jv+JfQB?>57b-22tzkxDShab>CR* -zPZyE%EPX8L)ar`Kk1fmsji99s<80bQp2`aoe4m0!p0Ebi5vwAk+} -zBBxmT*aw~3w=K*pXGr*yp53Ss{z`k3DgZUa?H$TfqdCAO`TR=WpH%^um_fO^h -z`4xc5cY9NLY8VH&6dyH4m^Uvb_gT=}L -zU8Ycy&p%3R%sqY4bUb@?Aiau9s@>bi-lS*m)DYA8+@Ys0n(9=>x?=L%&rXMk0XE_h -zS}{~?tl?TL%(EKe`d_Yu6^S-NMJp!nk={{RtGgYqR|iT`sRd(BUo=f>2$UpJZ)UFU -zc05pQe6yZAS42JmuTDT -z=?w+f|FzioeFOJ;&gyPQdXX`A3zwcUt5=5~UBE@3(z8P~#ND2-b-0aqg0^N>0DqE= -z_!I42LR-gHfU-5hJ?j>_HK>vxF_sY>)G2h -z!ZK$_cu3FgvM^6*gbGjCkZKdAXoR<&A>m#<`zMXC))O{l+k{7G!#G|!o&zfqd~Jip -z6$83VQ|kjOlBlV5+^faCx>FYW!$qXR(#M`P+aE3_t(HDk>C_r545bk&Jz+z#O;}1B -zhE;&J(QZQq@4u@8_)~1cZjJCTZ5UGl+Vb6ofqdIA4!Bc%{#?FojOb3Le05x)nC!Fk -zvB^&DKntUGhJ;7;>_m-FN_$6D0BWq;JAkK#a-cB9N9Boy$z7)Xb%DZx)cyu;T2ZfV -zq{Tk1nA~mYV--%VPEB4e>eUezJ5x+vR*{#Bdv$`v{$vq3*V4!S*{MBbVdiOsUS~+i -zacZBjFh*xc*raF2TbO~)kZ`|KyGTvuSQz*Z?GC4QmxcM`&8I`ePlH#p3AAGR7AaA1 -z;#M0miq9Q)^rC4=k@0vPH^IW(N-Ofj#(~uFoJYGILyL@)ws0#|d-~YLPVF`ebBl&J -zH~31}J6g{^t`RZ?RLCh -zWL#CpyJI7#8DY28K~a}sCEd{s^5T8#{kuifU?8|N`rxVB?hQf7^rp()G8@Z -z@Jdmj;NnrB;EEWiTQN|t!~nGl1GNePRX0-#6kJpWN(Sn80P0Z))bt2Y&r5-V6H%Z} -z#0Bax1k}+Opr&J>;2Ke&rpEyFJO=6n2I{dGpk^STK92zkt`r4oItFS~3{WRzpk$za -zAE3@apw|2b)aNlkok2i-8yBem!a%(i1JoJ})ENxa8YxilN>QNT;!&XBiWsOnF;K6? -z0JR1KwFUzfQ$fK+WuRoBeg~k2K%mkhK-EZrf)i1oK8pv`uD>9lCd2@hhJk`>M1e|+ -z0jdTA^%(+cCv4=R3Tg?ipeDuu1y_m!m4<;D5Cha_GEg#5zYkEmVOw|i1x13G{`{$n -zrj%mi@oKKd!o2VizMZY3Q -zD^%pWX6C#zM2yk1hs?}}&JZzA&jvKaK-#;`6ShvY5mRXEtP0>taa$Fh2|f-0lGmb+Bf?Fg!kSyf!BimWyFv7b4$YBOVThJ@*Q_FIjR -zMjLM7mFZ$$7PX_g+i^l=v=5~0IbEhr2|i`En3qE>uj+P8RvDMqaFgK+Nh;&=YHndo -zx8p69aZ@I>yq0@Q-K(2rwlA#a7S?q;R;!F1HQZ`-uWqB+enmxIH8awpB5eXP%^oo8nDJ43=WJnJ0pfHWfujzJVtBv{9+)fpF(%i@X!>OHOW?puNgxmD&R~iBK^KZ8achTPYJe9}+ -zF3m>`61mJS6ImSy=83^n4shu{DoYHG5QEtq;Ie&Gvd9hUGIiAixGbuxn)|e&+p)PS -zz-3TfwcUE`x -zU>h-(R*VwUw>{qNP+9Cp&CI|4a3!orax13sxr3-B#bl?3m`^J<--7#4UrO(&r89eV -zXN!!JYPr{UJl^eiNo{n#+0LoS1!m@TXNb5%&tB3H<2_;P9X4VS?Ik^7>mr+wKpSr2 -zm1!Kv%k(J+hx_I%{E~;?Vace8wzZ~NsTa@HWXF>WwP5ljP^e02^%KcgxhJuoC=^E -z=r&B_l{sQ_PM2wFRbWLLHMOSOF+y#eTFt$xB2St7*zcWMg_&t`hJ-avt<}u9oFO4k -z&$elVLfWvP0<lic2WXoG@p%i@4L+t-#Xx(9Wcd^Le! -zy6DcLeAQe)MfRDQkTWDC>e*V2aI+`uoo*9`(B4~lDw6|+**+>sEF9Ej+FuhW%%b*J -zcRS9gjQeZ3Giq|AxsToM)b2Jjr<@@nSI@E*X1%$OwK}zenOSdPem3{9UZ-}hnc3$I -z2~+j#HyRe-VT;+&M-w6DfHex32y#Uv^%SNQridDm7`nt!lP%FC~GgZb_HQY?N;-Ad+ -z_f_NtGxI~so<8;`r}i#0^BPf~V2dHP^Ly2c2uky{m5>}+S71?}lCRKOrF?2)0bN=%^2^fvO -z8w(SM*oc+1Vi4andmI)Do)dj40T1!Z<}f4QMpV)YH9U;oQScBy=7WEV?Dbd!4@cUF -zCuv0v-!yj|CTc!@ECCPk+vejog0iu0>j1uNCL?gT#XgU8b@vfrA4mdnRR1qU`BZSv_~Ks8?5Ju^%iZU6wu;?dO2CPPUC8Y3sNO -zP!`$AF_;78Xd6dTmq}R{sLU73Q@c#chCpSqSUHRX<%vGmP_aCPYOC*dxQmST6soPR -z+u<%Ywl#2tMdW&QuP)zWFDxeaTl&~(PAzF+o-y~aPdc?-7G|7=xZe}DjL~8$*ZpVGa#{Ko&nWA3Z8jJl*G5Ldq$#8~*C3^NAjj+lS_NLneK_kp{ -zhJ-RbYtRUXG{Q5^kU;6#F&bgHC+runCXRiie+rf9HEH@|^zGR1X7%bUPVJ)_;#qjke-=?N8h!O> -zVa)612M&YERJUR@?_UegiTYZ@}|)bb1rD -zf$00O2jJGH$osLcz(e$Y>^(>1hv)Lc^WWv+c@x|dwf}|R9-iO(h4jh97WDA^b$HHy -zJUl-DH#|iip5Oh2w33?qIBM_i!<(Y^!b9}%d^y}A6?u66hcD2>^ZVc-dU$>h{8QxN -zIs9b!;W@lO^x^sacvn;jJVX!ACp|7dn~8LJRc=Ln~pLzgH4drZ&XLMxtl=qf0w50vcW9$2gd -z>??ZqAzGmnONP0wJI=M(&smrrn3?QWOcdLwNKG6<5##h)FhL6=c9X67vqaAo>jW2v?xz`m+yAEvEJvAi~{Ti2=eX$WHv5UT>> -zR<6*(obdoxiqDlxQEI?;>)CO%bxP3WR~h|F$xRwU*8{|cfVhiGH3Ol@Cfvj;M}-{q -zW_x`L^C)e&GicgTWZbcsY;^*|Y_}m(%-hbLurR;Sh9t3hYgqTPQ~PqMFuVseHwK#P -zxwl%G(H@{2=2K=+9ZLawm!3UL8^#4q9m|YUi^z;pVL}gB@qA!K4fkpb5N6th4SZWt -z$nkKC{b38^q77L=)4NNI@2W{}Com+t4HHH87H&=}5JuR9hxxXwkmJKv`_pD-zX!Bs -z_}a!$zGBkY2@K=ihDBmwRaiH$Q`?{s9_;~zHG#rLZl{I$hX+teK58hnUj^8&^z1C! -zd%IZJz@2GjGHCCFpovr&$)zOW1l|I-H&5hta!;Cpu-qn0<*6|tN4MGD-NG0>fEw@f -zCr}F(le?V2JHzcABvv+tb!VO0v!y~t52)N0sI23(t;}2x@Q?8Mvnl&Bz~<=LU9@+Y -z7|aPd7Pi_yH8ZRS__KWed@57~*aLc2M|CS)Tsp;qDp@SD7VsZJcV!EWkQ{`(laP#q4Kt^@75QSx_>Sw2nP&UU7Uo`Bv2pfQ&|VX0Z{*&G -zpXnz(JC;_gfx)^!`ws3`GxG_|9Pd^v5(}!rx|B|BorZX{2Ncu<3L3da3-g@^lqLDf -zhEh!`z@F2yGimGXVnGAf-pZuY)(JsVnaWtUlq_=sYk}LECm!6%m74*v+(u00%f^Hp -zqS-FCFqIxqHs0q-pp=Wr9Zq1K;kFJE%NxVG4yU%Gl*s4-<=X<~b=-TY->f6aK&}(?gD>t@aaU<~`alR?OSQO*S*zJU}_fryNZ! -zF9z)2^z0L~p-^nD4(n!hYCq5jYkNR*ZJ>EOcf|sP=WId}-!_<%7=G=iGlG5K7INhZSN#B_uS3?fWmW)zdprI=(QOyFmVVgiE*6PPJuB4g6um^=~IB|a9Z -zOlC+iIXN3)a&J6LPRvG_+$+TdE)vD$D})IQB213YMwr}-FgZ3`ipf_96PSrGfuAW_ -zncRyofgc1{CSS>z$e8p$CVzyOyc)seloXTOF(xzPVRAdhWTq68QwWpyFeay@nB0yr -znTargL4*m+jAC+1iplL5lbHw;7(|%BOc@gylm5nJ9mFJ3nY?M3}(LC?+SRn2g1k%s`mHAi@M@ -z%9zNQ^fxAkurBc*k;>$$7))@_1E -zL@JYQF__?<$;!Bx;GW4!DJF1{C?;PcOkfaWf_o+_F(%TU$;)3OOkgI)1ouoDJDZPCb(w;g9sCt -z8O7w76qBJC6WlX_L4*m+lrfPp>2FNnK9iRtmC4;PnBbnt1936IJ(CBdn7~D%nD7V_ -z7{r+1p2-6k6KT)nWgcMyGchK(XYv5XMA|di$IF<=nDjp;k3&rMMld-o#bhSNByP`S -zCdNeCGkNhe!sJVg$!RGjGchK(X99x=6POvr&p2>!|nBbnt1}P?Rktik?5hgH*F~L2P4Hy$?&*bHc2osozF~L2P4Hy$? -z&t%_4850?k{>NlE#H22Q$x$gL=?IfIiX2l8!KepDEfifkA``%#<;aG3jqi;69TFBbCW*QcT{)J(H4nn7oC1CM8l# -z;382>&LK=-5MlBr?wOPzOx}p;nVdtIz)XY*{7liFNeRLPeh}O -z#sv3F$}uJ}JrlQ#iHu4AV=^0JvLk}Y2`MId7?Zd?lRS(`OwZ&5!sH2z$q6YYc^DJi -zGl4;b3CxUQazctp9>xUsOkfaU0yAYyWK8-S6S&Xht4L+?L<}alXR;zLCb(y^LW&7o -zB#Oy-gb55{OmNR+1;!+%XL2540y8ltxM#8gV-nLdIWJ=(W77YaR6tDjM=&`f#iS5p -z61Qhkh%t%jnVdnG{D?6*BgLc;V}g4oFo-aLnNdv6NHHnInBblX3?fWmri_VOfDfzU=U-1dnT0_lbD{#C4>pg#F*foNhQW4 -zre|_V#ze-X|1rsgnAAov`AmvQD#Bz{+@47)!sPLop2=qjlhGKH&!m{7B1~4}o(T*h -zOkiddlh34>q#{h3ZCY>@SGA8|x$-NMh -zmm`>bDaB+m#w2dfWHQDirf2dc!elSTMv_0KdI2MW8F7Tzkk^?zM|u=XUxn8 -zw0EpnxQm-+2Er1XFo~x|ha8OA&a^NF+FKYjbrl)A7L$jZz&pq7%@(=sVO_6N+gmCm -z^Zvmh$2g09Tq`rh1N_5%{!D7YGQf`1v%6_;u2{JvtXuEYt}hkl^?=G_`fk9Jfu`#3~9i_tf9uV9f2sUs@kIw*X)t^plt2M-b-+l$; -z4)Em;r&849XCLeVM4FBG1D{*4{hFz6sj;q@e6*Cflg}MTEh!?0!1-Hj#N&MKr0v&C -zOO_aysL9S!;(55pFkfy4b^OfAudh}#hILPLYJb!a!P~EZrbJ)U5Nef*+zYQc!bUvIH%;As -z&9rKn@%tk3E*P9P`7oac(5j{E9=y{Gz7($C5Ig4E%tH? -zotv8G1Tf({>o!aFZ;=vwJULPpm$*nL0;vO5J;9YrCTQOii -z)U!|1)&)TmRb-?VllwKqnjRq51jI&;vjE~58j{NLUh-M -zb>DPq=V^rddVsqw;NHOn%#7Uw+H!nt1rxSRGxV(F20@f#6PVvl$5Y+k`uK{}?J%3|NPrHPMQqhp&S4 -zJ+7Z})2Ng)Yg8?k|Jnqa+VdULVyO%?gKQlj~tE1+qFuPK{)^K5xoH`=Kk -zT}n*mo9?n+Gp#B%u3AD~fY*H5Mr89%v#i%l->Zz@FD3t~Auhqp9ADFTDz^x*HF{P> -zTc-z2xy8oZCFF4p@l+2es16it<4P=mc)~`E=F3JwG^<^^ejVL#{^B(GNZqUT+j)u -zBi+`yqFBoXTL7`hMwobILdcQYVo$X&pLu|CfKNG`%2Jb`cLKuzx8W8suP&@>?bJS| -z5&p<4v#A}+$YB~`aSv$T5@>#&d&>-jhit-ZUYSpI6ajXxp8XSTm=iR06dOC1kXN0+ -zu+VKt6jyBJMp%Hb(k2Y$+lGf6uUhP{wlcXM&^FZ9mQKC9lr%VjVXE7ZFRs`X){Sv$ -z$CL__`L@v^$A@P7hb_!H4`|ExwIx%&#egOCY!_|F5#8Ivx<042uT)6v0fk!wg@Yq1GVL86H0@t%3^j27voVM)lhp{5wK16NMVRcvnCz8evRcMO#-#r-c^YEU6~W|5 -zDJCCdO!mdY-P-P*nY=B<1ZK*Z$e8puCNlwBbvS~_ -zBQcoZ%4Bz3OmJngTZ#!>B#Ox@gb55{OmJng8)FhvnXE#XJQ9Nmu1t1gOkygNRWc?r -zCjF1elMs_{BABd`VsZ#$61OrrgfWS!Ox7VxE@Dj9NijKuF~OC|At@#oF(&Jzm>j~G -z;L7BX6cd;!V4QF@ZgkYY|MI -zi@^j}CI{kTf-92)QcU0?QB2k#OkfaWf-92)7?YUFWDUaPxfo1vWpV&x5>uJ1kui}m -z>3>W%LrgA5Fj+6f#DOu1TbVd8CNY)CdW6Y!jLCW_CJu}Vu1p+KOs->0)=M#QU`%jj -z;*eqjGi6Lq?o`(BA8733&I2j5hm%V -zGO<-5OkfaICb#_sVUi@p1YR>znY>$tFo8i-nN0nQjERg%|6@{o6{P>s`5PwF^b$-y -zF(XXU<5ec_nGq&%9#tl{>JcV22or@~f(dO#m}H>Jq{S@7qy}MfhhBooVKc%6UNcge -zd|;Mh0yAYyWK8-S6WBAUi(sOP!30$%2VaPb393xqd_jr{TqKIg;|LQN#F(JU#P$Nl -zL|U2L_Bg^s6@v+?Ox}F~VYl-BTV2tu1xSglNOALbe{=LBTTmA%7m6; -z(tCQ#RO)`n8=v)Hzu%Way){`${0*=WwIwOCb%-$BgF(R62%1X -zGl4;j39d}`U`%2v6THu4Weg^`GTDPMiK$HFeI_y{Hvp5TASM?hm`L}TeDV>-ByMH$ -z5ym8@GQs;yzQdSE_nFWiVN7sk@{tsi?=U9PeI|!L!kFO7{L&g04i?=yJ`V6B9MOjboOnJLBO6s}C3kB14Ik5(qnOEH0qL@~kpOkfaU(vB;W=Mg3_h$|Dk&t#?) -z6L`&NW%4}21O{Xe$@>@+={}Rg?;uRzHKUcuJ5o$wri_V0vCy5g7=xgAjSk&Ca+;kVk#57&tyXkCb%+r4Pz2hnaKN0WK3=VCVz#P -zT#8^K-DmR2Cm55smB}X*fYtEV3IDyM1d=lns}JN`DkTQBgF(R62XMQ`%GXEVN!rAlNy8x -z45G^9Z+M?cx)c+5&1hv(gD`sHx;Ig`R(Tw4o7}d;nf!Vs}|;a4`@sBwGE}-RguX!a8rK -zc8o??%C`*)Ip(z5KQuG%dO%y2uPvYQ6#;g?o+W9+T+v+{))_mseHvkN4=Ah(6mI3R -zEkJnGCJf=J;Z(jFu>a7r!)WgmG#`~ -ztw6}I3HR{+bjrRIuygh7A=;ZCG})IKHx-fNONA*tAozSBSi^nV0))9X;Thha9CB=K -zv2V68muYWK&=gu?45`V)f_;EE(!QE4q80zO>MBUD38Xi2H5TT-n>v7EfLn2km|k|_ -zxAScIW@am#AL>@j6dND7aNW_;VsEi99$K+<)m6~AEznrUtt93E -z_D((f5v|a|;I2SP6*shnSqw90xD|uMk`))OJ6^KbUutEB!{8*hB3CTg!JT_(4q$D1 -zwt`k{T6Gn)R|VR)ax*Q=X?RkGTcHr!AHHzi@qVj)gPC~^21mLTbH(;r?$?Ls0QNaO -zd!4o>1Wmb%jkzkat`k_(+}2ygf_kp86%d1L#NB*ZddN}IYHv3)@6*(4sPc}3m`Vxh-BV1m{O_$dqU4n -zrmeRHO-i*j3vC!B=IspYCOWkf -zONCo|K;Di(UM+W`g?WlL%om%hxXCR*xWy(s&MQ+wj<;IuZ&{chX+vtz)Unvup&~!% -z1cq$4VVc<75Y}Do)MjV|72lQ?a*SxTziMWH6BurD8%B#Oc7}Bdr&dua6!2|%A;)>M -z{d@~Uc|hAZUt1!zZZWyf2@JE`h78f&7}kB`)P7ScWcL8~wt%~id%Bfb-~nwTeQi0E -zZy8{d^=vKe9UL^}FE!>Dlgmnl89ktIXP~f}yRQWZx7mazcq*0Jzl8ijBm9-85<`w@ -zE%s>^=9C9eDLyKfBGshO3B0Lp?_`my3+oPbYM;>vWDnpP0^BZcoSA9x0Dqd#KZ;sV -z4A{5z>>Ap8SI}fHGTIlDtVS^OfXdoH<#z6p1qeo)Fp&2Tp*E=idsffhL3D#%Z7Uo~HB1vrg>fS) -zM_Tc8?p4rO8))3leOEREu>aPx18Bv~V#!0tuRDge+Fvp=Z@|paZpB?$srF -zwaln2BC|?~i9MkF`9OIM*W3b#SvF!L?@9_eRFGl(`!2%46wjLVmj4?2ONz-`DA -zn|E@n%|N)|$AlbL%=RlS%wIh~Io{WnKuujtZg&F147XvB7|aPdWK7~y&TDZ`j35hgH*FoBs-Ok4;P7{r(;5hi6)OyEgTOk4;P -z7{r(;WlUsD`X7^Kh{@^*CbOiNbRbMzaWUyYn810A$t;A45@Rw;ib)5;1ZGAt>5yWg -z#F)&IV$y*yftgWEI;5B=WlUsD`oA(c2rCmYf(a$X#Dy{GiiZiDk7Cj##e~9`%te^M -zAi@M@MltC^n7|;$WG=#ll41f+iel1*Fo8jg$y^x|8I%6Uq#k1O=x>+^)1{bvjxbTi -z#pH8@37kim@Y4|{SqKx?bSWmEBTQgs6qC=Tm}DVL;Ag^>$>#_Ym>I?7b15cSGA1%6 -z{f|jGtW26Cm@JoKqQsbd6%P|QAI0P=DJIJiCcI?7loXSxGA1%6Hvkh@nYbgEtdnBWhB5gj9wu-; -zipe)pOx9scaL)t=5hgG*ipe(!6Bxvp;GW4kDJJlwC??+^OkfaWBKJ&WOl|-sJ0T{I -zMKFo!nVdwJP;oIii7IoNlm5p -z0#Ax!A|Om)5Mv_uOk_-M04A?POx8p&iRqb~MVR>GVsaK?0_QO%xM#8eV-nLdIg2oX -znNdv6N-UtqlN*2u -ztV~WsFnLUh$qtOk*YPlc^HEH`mSXZ4#sv3FU=U#fGozS%jWB^hj0x_UJSN2io)pF8 -zYlI05Voc55F=>XC$y*Uj9+YCT9Am=A!vxMpG2x|{ -zJcu#DJrfv2n83^^COpCf1~DeMXY!yF6L?Y-6CPm#gBTOJXCh;A12EYOF^TLmnJev? -zTsn;~>4=NTX@m)!$C%)r$t;YCv}eMfMwr0NC?=<+n9RbMNP8w1Pa{lVW)zdtQcPya -zn8=vi08C(IawUSvMkyv87?X?fFoE+?OfE_>*@!X0Jrfv2n83^^CKnMVFo-e1J(G=6 -zOyEgTOfDi!U=U*>_e^9=ZU82A5R=G0lS45*lcNZesc|tmiZFrm2ooFbnPebL+G2Vp -zM-e74Gm6PkDJB^R6Zn~M&*Uh=1ZGAtIV!~@L&ikLr2jEl0V|VNBbeMH#bheRR#pGR#i8~%9a6XEOTZ)MRV}g4oFo-aLnNdvK2oo5@ -znBbm?L5c}HDT;|3VFH5~6S-$1V{!v9*#R+$>@ztO(=$1NFj*HDlM@INIFB*GJ(DpQ -zlbD{#34{sEjAC*^ipdy^Nlee=1i}PnMlm@d#bk_(iHu4AW8#LD$%he4{w&309meE* -zJWSwx6qEB(O#X~9!95cgM3}(LC?@9-CNPLG!99~dOEG~bMKL*#Fo8jgiQF@hF}VSl -z?1z{{_L&@t>6x5CnE2viat2`n=P@R@XEG0C64Ns|gD`=aQB2NAF`0)kiRqb~L72eI -zC?;p5n9P$gkukXen83;;5W&PK#l(j(xfBl*I3LC2k`xmo#sv3FU=U#fGozSXLYTlH -z#sv3Fj8aVCNl{ELAxvNpV6wJroFDhnk)nizv=bk$gFmHkKKh>@u6xYUxyaLewMR{cI)NdWM82dRW=6T`lyU>_yZ^yoQtw^FyM|Dd3b1GN>@?b{2%0Fhky=JB -za02TTw{@f_?%;xEKo -zwXLPXC|)^&+My=@Q7R1R0nJ+j&0Dz1tw0!V6CUD~S=91nfE}%8_tJ(DK~u+4V@EN$ -zu@e}^xeW`&6;<4b79dQp2`l-w0rHpB$Nj~V!o7eva$kg-DN=6spZ;IJc;fmp9yf44 -z%FUNjZl+*vW}>fxgh9j&%#3pLCE^AKF*h^OS3ypZasy9_a`PqP1_m)VGyi9Q6=YaV -z=9dyvdVu(RK&;`o7C_9k5zp|hJc5Z*iV6HRpa>>p -zTufXD6F84CQ6fwTjEPc;i3?!@GozTe{tx!?bR8zJu3}P8V=@;pnME*xBEbYY -zRZQv$CQw97W)V#0(wM+QDkd-@NWlb(h{-G+6CIPz$K)fxWVM3HTpAOY2BcsT%ZN#g -zU;^ui$y|cTi-^fw8j~2o1UgkrVl*Z%A|`WbOkf(2f(dl0n8avIUeqzsG3k6v*1?;} -z1O=19G$!*A6BrS69VW1@VsebeWH7;`bvnTWiUbqrR53Y5Fo7b$qn^Ajemn#=^I0V$Zw&xpxa1QS>%m^5Q%@&Li4MU$C) -zMKFO*6_c-MOdcSZz;_zZG1&J4OaoFdfld{ZuV_pj&@s_5=>kmP&BUZ&GL6P0fSACD -zpzAP!brqA-G$zv!6U2>=u|PeL}Ow{Of;DZOaoFdfld{Z -zOEe~S9TOds&c~!TyqR?W36pk1|_KcO%=(T!j-m}Djwp-3=+ -zP6d;~PY5PZB$x~!nMtY}jR`!YU@`|r1Syz6kzg`N&rEboIv~EIwm?MU4RL^nG`FS+(2Wp1u=mULDyjd>nbLn)0o_Vn2^lmA`}TG -z(5YhbIl%;qhzZF|Qa8|;z(Xn~Fd|671d51>o|)*FbO9!R0Zf#0CWGnBWC2VAQZU() -z5tDBSCa{i}kjy0c1Y$yGCbPdGm_VnB$u~46Par0AW-kkVfQfR>WH6nXEP!c13MQo)F^LdNU>z|bnMu-sn9!NY -z>TZ-(3ng|Oh{&O5sCy8=u|N|Lok6NVnQ;L)N~pXcu2(rMg%FCKoK#~GZP(?F2Llk -zfQfR>WH6nXEP!c13MR)gVse3C0_%tg$xM>JKuqY&WcCGu33RHMT%a-e1!6*HCi7q# -zkb((xs+e4$G5Lj#iH=Fmz)nq1L5=@{|#pFvGlb;bx;5!WZ|mDF!YJFCvW{~r8T -z$A2!aX&x+Gp4SkTy}hH}TcpF=(&oCbi8C;4vwV0*^6-8k*WugVC^z&?G>qm7ie>&S -z3;&eIdsmyiuE1{BTcvQk(ry -ziS1AY`?NuPG{Ozy4pp+FLUR13XndF?>`9xMkclyh1rct1D!AGaSncvX)+lph6I>rI -zRxa~43*YXEcbC@fOq=(IO#6-E@Gjuy7I=5*r*PAY=4Lo@14D$a;|A7MZjRF2^dj6m -zfT;=;2{+KGa&we$14Y8keVD5BqPc;GRBm91kircV2{-pomw7p4`q98_XqNLfCi8X* -z*-n{R>Su;Vszz`*r855y3qQ=`oz!NpEwR;BuqzDAqmimXTx}(r6Oz3*MZLqM!+X-^ -zs*tJ5$P`4X#;1ZS9f6fD-;zeTYHXsa57$sG^Xn{po5$N-TDdcA-WxLQH8R7S<&`zb -zmD_~_Zkg%tXYP$OWOH>DGC#+{zwhymZ?o4`+PEV9l6tn%D9&h>3-=`pHwpKv@OJ;8OGtWe-dULhq?Dq!dc -z>nbMn#FG<~5ED#Qphz%*P8AcJcmhSl1XGnsG$!zniV03Ufg)luQ^!QV3bNC$f_&m# -zz(hHT@_;5)!HFlYX2b+1p1?X{f~m@rh>0du!HFl(sbWG;JgI*YG0~(dIPnBJRZQrK -zCs&@-G131atn>dN>@9dRxn03z1dYin5GhzX`DP$ZZ@r-}(qJb@x&f~m@E8WVU(#RMmwKoK#SrDLLF()pMOfQfPv -zn3S5EINyphz%*P8AcJcmhSl1T&L6XiVTC6%(9z0!73`&rEbox&V{+0TbmU -z$~jGDf)h{P%ZLe1Jb`t@1T&Lo5fe>jf)h`mQ^kaycvAl?Vxq}RaN-Gcs+iCdPp&+x -zW1?fy`IuaWHc(OJlCOGi~))5oTOddx}G?@ubJb_LX -z6MEuF{o{yc>nbMn#FG>A -z5EINyphz%*P8AcJcmhSl1T&L)G$!zniV03Ufg)m}XC^u(U4Y3Ez(hHTa!!+(;KY-w -z88N|$C$Nr~U}o|PVxq}RaN-Gcs+iCdPwHPmOf;DZPCS856%%^m$(2`hOms{-ACr;r -zW|E~~(u2mNKf$CfF=)%uGrMCR6Cl -z#E%nCpi{x*9nHj(5`qbQCz6?bj1y0wQ^Djz&BT)u9TOdsF2DrdOv)8ZZlW>SjhJMd -zcmnGxCYp&SHz6jNnLv?X0-Y)*IPnCEhzVvUH_@2DLn8WCfF9G$!{VCK)H5z`BZwX5z^(!~`=FC=yJdQ^f=)oX!OUbB -zjR`!YVuBM-pop00nTd``7hv)yz(hG`GL6nmj^M++X_)5bO9#tX0k%TWG0QtX~ZPs#1mLoG0{vs -znTeQSW&%Zm33RHM;KUOsA|{xb%%m}ahg3{(;t3QH6FoE0G3f$KJ_JmZb0*X1%;X48 -zJUN{a6P$Pg>xcF!AY`iH=DZVDctlqMS3~HJJ%cJju_92~IqLb%M#CF*8|2FnL>(nc&0|=u|P$ -zOgvdcFoExcnF&rjfld_@&BT*MIwm?MU4RL^nN%s57^a -z1d0R`=u|Pmi6>A*OfWOaqcMSpR7`N<2^0|%Ju}fU=>kmZ02Ae$39rdaaN>zKBPKZU -z1lAD~%uH4yCYsCyC!Rp3iiu|8$x6gTlbPVe6X;Yi(M&v9sbivJ()pNt4R0m|3MRQU -zCRW5Gpy|bmfEy5|6 -z?|F}Ro^*I)+ME+M)f$);&GO;R$-_0mVW&@Ol&g9ss)ln7B{Cni@P!`l)HZuVsjZ=s -z9cW-mo8^^TlPmWK2OKihIhzQ{-uY2)Pf6M- -z6gp+*X+JY6(vXu13eJGw_DyJ%8-^zu`g1K6?D~-Gofh>@l%)M>bI*{er%}A2SZJQ8$u%yHw^|Ec`%^^=2u$HEli^Ha%t#A8D4O+mq3K!V3;r -zyx%WQjns|h62&qfu<+|W)`e~M@kO@rW$ccS9G@PI_mv83gndp~e9kZSi*UnI!TX(o -z``x}-p7xt(|!oIY5Zpbv(C{AgXg}q5(i_qkf -z#rb}5eWaxuH@{5gD=qvgqiDrb)xn18igmUDU}a)xo+maIveong~b1M~Ap&LD1EB|Fr>dzIvSz<9%;DP# -ze{yIve}=T^-HX?Pzjg(F?ezUO6tklFlch!5ga`S#GC$kG`#t%wbywv@`;(_O3Nu~4 -z`{1Ej(ft0>DFMc#I0NsxedC~bYczk9bZW2gpFhu)`HwC9E1vv?ZT6fZTTU6fEhKxV -zN42FRfWvwS@^>q -zZ?1HBU)o#{G8Gt^Db4cXy~)E{1j!{c^Zm^FNJBTSpiJf~Ec^+Nw_lsRpxjna%GQTv -zZ&uVhSz5VGSmKtMv3};UNW-91FzOBzI(+*)-r;R_uENF@vus%Qj*WWnmZVK-^Zc+W -zU|`ln8v3MyZLUC@)0b|P3%Vr=hHwK*Wd5jyztLm8P0HP#HXjR{ZZ?QNYnF4jC3E)* -zCmg4xx&hpjN}12G@Un1_@q#vcpx72DXRn0h`21+Rr_{DnSm2b!r~TrnNJ~yCc*Gev;`U8! -zlv{=;TKaRT3f3Ny|%5x_l3N@>_ael^1PEF4`@837yRret;+cX6cmwD8U3eRZNc3nDo{$(J|?KOvVBx -z6$&P98k4;Qlc*&VCa|tx@~wr!`ndw^h4L1O}cQpF@pFo7b$WX)`XNd=7wJfva* -z!%q}Uphz%zcD9a*j!EZZ@&#ZrQ^DkQ8j~jpCW|v-@+83o))AA}2_~;1CNpVFz95(! -zL`=S*F}VdXnMq^v1;GS5RZPC1F}X#@M8~A_F*yjBJf&dr9*s#oV)ASzOkiEbLYZNy|{CQM*m#bhOoiI-sV0lt|$LSq7dQpKc!U;;(Nq<~=Z -z2#pCmq+$ZYPZUg`h?o@UnCO^vJ|^{m$t(pE&6~+n1d~-6F?ot$0_%tgzL^|EOlHxT -z)Duk3BPR7UCUX#zSu`f~1QX~~F{!69nWJN(W77GUoCi!^P%!z3#w3B5tj>f9tgD!; -zrZM>lF~K*J7idi2PpX*22qsWOOfWNffyM+LQZa$yCkiG|L`?L|M8~8HFgbQD*rQ3w -zOkUKynJgukjL(S4Qi2Jr6HH#fH&2@_aXF?oi@yqr9TOds&d1~Cd&yX^D|>gCg*5O7U-Dhm~=iS?SRP!1(P6+NeVH^c+LdYRZKMJ -zOoE6BzL{*GF@Zm+VseRK0!73GGm{N8Ch(Ao2@F3`Fo7asqGu*LCY_JTFFv^z>@h*f -zOa{|$CJXVLNzY7}%)@gguud=;MBYr=Hxf+7)0xRjpAby?5KK0FLSxdMU;>>aGpYWB -zU;>>ACeM9BW71v6M8~A_G3f)C6#sXUBToo`kcvk4uZ*Gd^0Jg -zF@Zm+VDfy3U;;&g$wbUdifK&XAqA6lF#JTp1d0Tcae8K=W6}kfd=8i>naN=K&14~- -zGbzo837#{7b;N|cnY8~BF`+Y)mp&($>_ALDr!lz^F`+Y)>dy%#(5YhbIgQDUIwm?M -zosY>5z+|a{$zNzpjv*!)&zZowiV1zr9Nm1QRGCCYYHlr7?kr -zR7_y_iGm3f5feQ#(J|=)Og;lll+0wm=FJ4pncSQa6Fg@E>jaa1_-3*bF`+Y)mp&ty -zR3avy(U=THOz6y{`ZIzFbgGzqMq@Hm$3(}Z^D(IeOpFR99vTxjVv_Nk39PG_(C19P -z^AJq-e)fOrVIE=$VO*Nf%&p1~5@Fll_`E -z6Fg_KJR>G}&IHyG6MQpy4KblJlb6mAOim&uXJ|}jASQHXQhkPC0-Y)*XJ|}j=$Po3 -zbUr300h8wxO#Vt^@*QH5@tg^)tC-N|OuqXoVuEib&(WB`pHwlqKrn$KVuG2;b2KLK -zkctTmKT$A&B4VOvCORfvfXS!Vf<1n(WF`-2-c0bE$?%Mr;5idmCz#xiZzfv_CWkbc -z$)^O9TM?5_X-xVNOrR4plTQgI(5YhbDUC@#9TOds&d20dz~mkUlRwayyo#7)JZA#y -zDkk(flkfgOFnIvqOzxpEfj_BY@+H9piUgB4Ff+M_#snTxF@fPH3MNn_nEaQXndq2w -z0Vbya6D2cwK=WpT=S&{ThzXuEfpx?L-%Ngkm}oMSQv{PgA||J3Om0U^G?~dMf(dl0 -zn4F?9xn0LZ$E5Qy`6FQRjDm@u#^fu+B;z>~SXVKj&zXGZM@;a|(FoQGy8+ -z5fjWzo}n>;hg3{p_=$oE6cH0WGtn{W0!&T-CQ4>9l8j~@Ii6%2SK`?<%6_XP*CS!C=bWA!QlcxcbM-@!|Ok?sMVv^yU -zi720mmJS=;w_CTPPcGL?Rd|2ZmAP$w*tNg!3m<(`G=G>>^UBxPf-XnElP`E8G0 -zm1{O7Yjz3C4i(7!Hx~X*Pks{=$tCsBsdDo*;RcGx4W=rO(%is9DmO45Md1dD$c>(= -z=-hMxH)nyHS+>*;p~s+*=xbg?m&sd_sf5tk@H7H^Jh!hTZB(t -zzF&Cq=Seltc#|t|lhgM(tY=5_^Q4;Xg6oZ0GC$hFzvjvR`mU>T&E90q7U3Vi*Q6?E -z2{+KGTvET`EX~bb$c-jd!HFl(sdA&4cygD{jm}NybMsH&=H>T9yC*;N@>Mx|PcnP6 -zu-WB%0v7I!=J%4aU%q%PSmF$nxP8+-`FBX!JA_Z&zP_-oVseqj% -zn3$&%OtJ_jCQYh>6HlO1#Y8jlB#U4I-w9I{oOlAADkhqVCs{fsIwqZu$tb|2T*0KA -z#sn5rOv0Hkfpry=FpWt$!GxVnFo7b$1UgkraN-FR2_|MtRmy2h;2{+goOl97g3050 -zs-k1k1(?9Z6VprulbJLoUl2@wml2aM2qv(On9L-YOh!yJsR~X!fld_@&BT+*h>0du -z!HFl(sbZp;crsbXM8~A_G5H-}vO>XR1&s+TsF-}42@_aXG5MCpWCda}hhPFlf(dl0 -znBc?{C?Y19s;ruT;1QRABCdUaTu#T9_ -zAeiJJCYn?QC!Rp3iiu|8Ne*J7NmX#-33RHMXeOTI=$Po3bUr2wU{a-EQbl6|3o0fJ -znJ|HM6_W-UlPbgnGZQEhOrTT61Sg(A5i!Bcq>9D_9#S#Ei6>A*O!Uk|$D|7|fr%$3 -zB{N|)nMpmtM9hduJ;4Ol5fjWz3J?=bW`Yw>pi{*}Gx4MVG0|iuIPnBJRZKJ!PYQHQ -zbWA!Q6A>`s6ihf86If6&iDkkB)>TYmG$tHkf|&^v2`12~VuBM-poo}YX2Q{!z(Xn~ -zIPnCEh>4z==$Lc?CNS~jqLP`!G?~dUg2~*Bm>eURz&gR?5@sd?2__dcnF&rjfld_@ -z&BT*|1QYm9n3>?j6X;Yi(M&uUsAHmI()pOo1xywzm@K9-fdv(luQFi*>nbK+(U>eI -zn8YwMfg-^KI#o;_tgD!ur!iTDm|$iCMS=-*s+i!!6DT4kn3=4iF@c9vOwN<7 -z!B9j@^vp!Zqzf>Ci60dM!HFl(sbZp;crsqcM8~A_F?kU%VHHeR8WUJhF%dIi0_!R!B8>@)m|$iCMS=-* -zs+i!!6DT4kn3=FNCh(Ao2~IqLB4VOvCORfvfC)@Ixu|3&F->N2j$qQ75tDNS6Ie$~ -zFf*Btm}oK+oOlAADkhqVC-V^#O=f}nbLfXiU~4CYYH(kzfLyDkeDb1d50WW+v-tOyD6E6P$PgMZ`qUOms{-ACrH< -z#FGU|W-_17Op>1vOa^Dd1RB*ti?B{GS%{fQPlCw;Iy3nJC!Rp3f=OC4@uVlg1ill= -zOqy}x33Mu${97~eq^FLFj!EZZG8ix^RWK=~F@XgIlOIEwFoAUilWQRwlTw1oe9TOs -zNHBp;1(W~a#1kkIOcr8hQc7b24=I?m;lvXt5=`dlnTd``7hnPtPZlVd$$UC9Nq$Z+ -z*`E=U&j}{5j+kI(ax-E=XC^=3#1rULG0{vsxfwB`Gm~bVcmka&CYp&SH|v<_m~=iS -z`vH^X3MR{GOkhF985fjWzphz%*P8AcJcmhSl1T&N6G$!zniV03U -zfg)m}XC^u(U4RKpJXxS*CiCgcB>5S^X!OY|#8WVU(#RMmwKoK#~GZP(?F2DpPo-9x@llgRJk~~8&IhPTW -zGXxV@M@%p?nT43pnaK}0@dP?mOf(ZuW+5hYX3~rkPoPu9L^JVZmX3*zN#|p74lr4( -zV6v9R1Qt|GE@Z+4)>TX{(3q@6OfWNnBEbYYRZMW=2^0|%%uLqOn7~6SCOGi~iinAx -zndq2w0VXi<k+rv#H}88P{kU;^s|lOSd${Rt*VG?@ubJb_LX6V1ev{sa^F -zPMDeC#1rULG0{vs>91p=W77GUOan~rRWP}i#sn5rOuo#739PG_d`V++FTo^$nF$mL -zCeW#3f)h`mNH7UvW^yl$2|T1?f)h`mNHF -zf(fi6CYYJzBPN>61Sg(Ar;3SY;z>SYqRC8f;t6!Bm}n-R>gCOGi~iiinjCRQ2~cu2(rC!RnNG0`&<9g|F$ -zw8&?o4-J08`i<|~cUR$5g|C;aIRAd)@PhwY@a-38E9|4Mj@tA11OJ(D=0amSUJ#8B -zl-BKT3SM*uF1me#J@K0bxovB*ZI5uo(a!T0evK!7w;;D|O1AA1HaLBk8q@K?(fBke -z`(M!u_N-S{C9}5*J%V#u&BY;8v5}b`$+=edp`5)bnY~LW3Cw9VJHw`>2Il9HoI%{S -zN_MD$`Aoc=&L0-dpDES+CwjqNUT!NdWy3~h57cjo=8u$WQqc?cM!FK*h3;*Aq{NvWOa_z80Z8rC21^Wy<@3-*Pp8OQl -zyC-Ugaw|&M*Wvj)Ec~B6`RAcNK2h6~`~HJAoyg@BwVJcS -zrfmjhX|-I{D^WFq%PD1#hf_>HKXXr{Dm!Mct+3S=vn!0uU6HB@TvZX96HYOc{mhC; -zRaVSiRc@;)WgCplz-qZ_c%rI5*HF=F=0YaU$jq;nt0pEIx^V?%?A}m{S?*_sM;b=N -z>;6dI52u)Eer8Rip%2$m-fB*TOev$-ty(S^k|^lQ4XkK2mxfHGMsa$iU|h_;x5&1) -zjCF@nqQx(cjuedK_Lj2W8O2_af}t_{;u7293ihE;N_^Na&W;p}=jw}E&9lO$_YC5* -z)p9|fM8PPozO>bRHEil{5KAI;ePi}16}BnG?7iWXIMXjaAF1mRv%g(td%J}78pYgd -zxo%{lZV>l&Wvh8?$TZd{-V&)B6SJ=>wyi2>&xcat3x07>q;7c3o+z;;Dp;FAG*!!W -zgA;WVx$#A<=00K54uiO~TIPBsS_VsPqqy%*<(@CS)uUh7YCAe(vPzC$6L3}jA -z4dM<}wwgzUOrwnA{SUM;uuO0ZK5kA9X -z;Vqv0LaFB8Cob5Jm)VY&u{_{YK%#aW_vTB>n}QFz0uMTU5l?yl^$=Q -zba+!!aHT7-(&>vfroDrr-l@{z9Zf;W9msX~wtKuo1$pJ3v1$sMuM;p`DzESIKQtozPyStqqYTUcko^)WNaEq&*zsJIV;jv~5@`0MM&m=J -zb$gnEzjp+F@A5s}n2z5Sjb};gb_phDJ1<)Jxt{nGL0-2bxo*F(z~S59n2ryR#%D=w -zo1211T!AA_-<8I6yiYWKtJJnl*x+vG7h3qBC;yYj*2+2mdi&e_AyW3WuP@lMifvit -z>`?>ruMaM#^Ls_}CrQ~YUth3qtFUb=W|tb7J0m$0xbh-)=%oYg{Ld`>=brpi@EK$R -z*TnZ-&Rk4__4Ke?dU{pFK+UBYg6#o&cLtT -zz7cEcQ_LbilNYJY<=%YR+7$fK75LKWYleDnKT{E@?Z>UyU~LM%>j=E-@;wXn7yQhi -zNbS|PKa@{xOP<;*{Kw(@80riB%!Wu+x0pSr%$8HaZVRWFp?<~~sT#oLRJNKYhfI@= -z%)i;wINfjk;$o+t8x-m1G%b7wjh*Z7WX}=Eon8o!=~j1@#m3(LEPR-cDO+- -ztCkD;B?`uHi;G*$4~0!%8N}*HLC=`IzRXr%!oC+yiR1j@ua@ijC+fy>iDK3kPKgWr;)V#T5icrwDjfz<*nu`A=4G3*eB95G-h94Vq0IqnnNj(@r!dKE#qVMRFN%J -z#s&@InrgYFPoiZMm-W)qO~D>VX4$ez*iDySZ|85Y@D5M@Xem2=_JVy|k!@QU>%91S -zJ0G&}^k5WE{y*+s+cDSi<)@p1E?2GFr-hLs^;j3v(dxu56 -zGo{0un}Ua3fx}Lp>D34(lhe{$tUA=l-rXiR%&M7{l_ -zl{HPl1J1w!w{K))+B-Sw&5>5_6{3!I{(TGog2y{wkfn`DX{S)=^qp-?d;3Sd`I5A~ -zDJZxD>m0t{H>SO#qTacZv_)uhweuS+eA;8}Cdj!vlet@k-tKn(MhoxsSVv2_`!e5)GM*1MzDK2mg7Q}6|6;03pD -zzQ;OEkfS@2(fz_8M?1g8!k2pD(*?P3bF!@um)b4tbG7r!E&O+$crQUN+?6ccCfx7# -z&GN+WkP3GQXWi|5e+$3c6CWnX!k(nCS@5}h*2Z+aFdFYI3A>tttDS+>Zr|OF>G;%W -ze1atG7bZB``5hL%(i5K{$m=#I*VPEWceeBYwD6-m@yXJ+iH?++l3?Uc7CFTf5Q_WCAIBs3Z@-_w9D7+N_~p?r1dGj -z$dmss+gdrNS0ZNwmsQFhy>zghA7bHu>B)~kJvWilo7+~-{@uX56v^q%mA|s4DR`4J -zaFg428+^vYer9$gXFPZOr8P~#Wv;+7r|%o6kMlE+M{=$NK9pUQXwaissLiPHhqXb7XF-`NxpyMgGb2(pE@rPSvelNcZ-!FLGk#`Fq-rErTgrZKWU?YvLu2-;5?fUTTNO$% -zReq)*QZ=4yC~7qqgiUn@W>vLZ)hAIkifbrsHMfLK0}V`Rq@i!jUQl5xC}tOjQ_L(s -zvo_MuBWABFv(=TbZyTAh)pEngM8hDiuCmoUK4cniWNwW#jEUK~VjEY^#zHCPML#n* -z(l9(`Zz-|0RIuv}jJaBF7@TOB$PFxNHTMjgwiv`Gs^x-SiGmT_z*6>DI3@P=i$9AL -zWXJ4#D{Om<+2uy@&Pc%oZgCMiJe(3I`NbzA1z9os;&R*KQuZsOIG|cC7@jET&(&A7 -zn%9O*YmMT(YPn!yqOKb^rHtJjN{P$-;;=~Fh?sp!sclLnn;%Mvi~M3*VbdQC;xiGhH+QI<{ii{E -zxmxDBC%B;;TheO&UD(7J#Ht84FlJ{fZLuPDZa5`Q@r$b>T%VXdR&I-xvaLq3XSLii -zB+=5Bn_tmtejsFez$nhDmRrUpT6%DSGL{deM5|vM8)+FCvj<9Tfl79wL9DEnTlyth -z#&GM4Tg~RM>5@Twv085FnP?f#rApXfI3-T>i{?nq-?n@xXa8{Ye{=eBS?MR5f}0(I -z%`V>)p8OyBtd( -zZ#91rGJRoWY6f3U=TDC2=SYk83SYi5z193o*z`XJrVZ*nqxm;Wr?v_+?bBP$kA_T- -z8kzT@es?s#k96wCqZjPom)O3qU|%*c7ok2en!ixW+t?J$b_KGXzE2y|-o8=qZBpKL -zp~l_L53}&U_IO7Ka^Bu#-WK7M%lEv;J5M^iQOI+(^NTF}DUUZ>kPp`+4{sL^yM4Kh -zY40sj??~zJ-lm}B2uLp9y2iA3LDbt_TDeomb++>-Ec`7V@9l!Ta(i;+K4FQYo&T+c -zf5hW0kXCMK3PxRlsMD8hOnZAqy*EqJR-w?{&QG=QK96^-AWQp_(k5Y@tDQGl_=_Iz -zU`g8D6l`+_+T6bGjcMx*QR@&XcTZDryCbmO9E -zkkfapF&*z4jZciUOp^+0nu7bBfqib@@Wym}QZzn7D%>lab@<-%#K%d6`(k~4tI -zk}XZa5=WrK2cf4e`FYqln9_6RQc3}e_7HZawZobRB% -zD_OHmSZ1HyYJM(cdd|pvy#I1Ke?c_AyR>MhFl_zoR`af~=^g{~CDg}6^Y4-t{X2ZY -z{$`o&%@X!cM&iwhn`O>K*)GKY@7qNFOJkZWR -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 -z`((GyknsYu;U}(jTvraAqpyw2NZPaD5 -z&E)nnx#O<#6m>af8ySTmXSjPg-ErApGkvu`xl2~=xV)^5x~jaH+>I%BOu|S}S1-4b -zyZ&VAW`DWkD%ljdyNtf6T<*9UGu<%=qgienoZxzK#V=eqaPkdyXJyv0h6|*mf<@ki?PuF4!6I`-* -zvtL{uY3Y>;{@xY%z0>#4M!BU&;-_o=SUxPr2S(#lq;)&e<||6Z#Fa0iY! -ze0-zaGBD9Ho=X+U{2LY?ZpD<^wxrGWut_#B8~<`y&YAvat2*@6k3Y9f>Fm>JVdUs6tP#gsG5z-S|vF3Z#{ -ze{#p2{wZ>aEIl$t?zp2o-Ek>qGd%)>+_@}Mm;9wWuJmsvcgV`r#2C5bit;vcC#FnI -zz>qtxTux=WPC -z#-xm3QZbug0!4xebgGzyX-vupCh(oqHxnolOrTT8M8~9)|Cwv&lYoixX7VcyCNl{p -zlQLp5lVCE5#soe@#pDZu2^0~NnFNzbh{;SElP?G+(21DLB$!M>OlH!Ue4%5aW77GU -zd=8krt6=gijmeXU$(&4>Jc*dhp)vWEVDc-(tCYYH(kzfLyDkd=+lWN2SGZQEhOrTT8M8~AFF!`V*($d -zVse^b0!73GGm|?I6HR7vnqUH*hzVvUcOWL3%;dC=iH=Fv5tEFW -z$+L)wCNnutFnI?tIZtEqEMkJ02^0w?(5Yf_p2p-^!~`=FC=yJdQ^!Qdq_Z)Bb0*&@ -zZzj)aFu}}ZTt-YVGZ{x?0w1Dca*|*IMZ^R%lW~ZNCNnunFo90Q1T&Lyh>0dMIjLi! -zW77GU{1q_qDVT^fCXXW~88ef|5fe>jA`(oVLrg>(lgAMg%uJw2Fo8}L6OqQ`al`~O -z6DSf)pi{?0$E33{fpaF`DQ_nK)?k8}$-Io1U}iFp#soe@#pE2p1d50WW+w9x6HR7v -zj$i_vhzVvU^AHnFW^zu)M8~A_G5G;7Iig^4iN@p=#3W;8@(N<2$xJR0O#Y3ST%s{~ -z1u?zm_z(q?L!S^#phz&8jG0Lfg2^O0GkNtBf(djIOyE1InMn_V349TfnH>B?$3(}Z -z^D)^9m^gpJVDh^VjY$c?wn`lhnLsU#YCzwDH -zF~Q8_Cd7o!OkVw*U;>?p31%iYAtrQYa`1B<6CIPz$K*4>=lY0=82#v{uhzVvUP$ZZ@r;160#^gc7 -z1TzyT5=@{|$3(}ZvoV2lCa)@QCSPbU!OUc4Mocg>nMq>;AEIJ%hF}6k!~`>wnTQFU -znY?<2U;>?p31%iU5feHyIe13LM8~A_G5K%6EUtV;$aRUsYjSRm?sXmaSu>*1M(XrnLF)u<0X%xH?kTClyS( -z0!gPY)hKh_65J4Oe2L5-v+y^2;W25|E$Wqy=}|D7kEBdyz;Hm?bp))>XRo8@);lWiM?1uowMjdIJF -zL`xR8zFg+lSokZRc%L?Vs?3%uVS`3-Vzb<~JK45F=<$a+GQaUp%IK}gWjUu;B4-4b -zRmvWH=%CE>^)o+<@i~LMp -zq&Am(^PW{{^D|-7{}`CI$Yp9!9sEsoGD_W#9dl5jIMvUrj@0(yzF)j5ZT>N2`q9XA -zZ0H`>Sv6RssUV1rOXer@W1wWN3_{%D{QsJ>$BVSVu>>=IW%SB4lnYGcw_d{)s@P+h6J8BJFa;pjgE? -zrnOM!yRG~{)_b*7xg%+*51E&i8Sl9ySJuWW8-!&}*?5P~Xb87vF)jHrf85GH!g?2V -zJD5B>Q)D_+W?XYgma5}YoglbmtnI@4Ztfx0cAM0+HE9_WGCxx$ -zK6puPs*X3+2`{_2f40jx{bM;}n6m{k|Am#mm9@?6cAPD=pDi^FEfWha$;)=cm+cky -zJ7w{1pEx(%GAR+b*Xh64%~i0roNmX_eEZR2Q#2^s7Da6RrN}N}flC%w`^2%~mdr%p -zxXXXs!%c3NTgJp%hBC1dlRYTgW<_jMrO3XdWl+#Os9e1IlAOCYo?9(6xVe?>GBYX0 -z^kWVc$^1Q5{!=zOOv>FOoO5v(*=WCRhpEVJDlk14lA{@sXtpHO3Y5{y8TYU3w!R+G1cDZw4 -ztaB{mFO>N%D?gHrUMqF)NLpSDnJs0a@siwK8}Duqwm4<+E}u9n+&Pg+!Sz2liVN(;C8lzC -zPOhW><;tXGPRRU5nekuqFI>KG>yDL4%fCbBA!WvbaN`a2KRBk9*r(;2e)Z||^5qMJ -z>VI$?DY73aFuhuCY?^=J^8IvotxQ@b1kDr5jnl)8x7PpQSe0*IRc!hKzNy}~RsVzI -z+XDNyC8o#Aj9zP;&KVWU8Nw_rk@*{~ -z{Hv@jOKNIJTIL1K^UB4WF3C;x@uuy9j>-QcOmbv?>skd9AC1YUO$3vpsW5@(Dkev1 -zOyDIdCN_cz3<)NmG!aaW5=>x-nAiv=J{lAFri#f?f(Z-}6Pu2Sj!F74$puW#DVVIG -zF*$^o97u)9A;jbWjma8kyOGG$scT6HF!tX-wdxj){&* -zx-o&yCpe`zqmWO6bkCYVf4(wM+YR7^GyOkjwZU@|$0m}rv827<}IG?-vAIfIJCOZix@J%(D?4&V)lR73kCTYgx|3GJQtAfc3G$xxcnY@w;6L_vBlUHa=;3X<1 -zYY8SWB$zym$>bG+2@ElrtRmRFlao1QQryGFhu*qGOVNOlATmA1auvqA__6 -zF-e(Bo=V(msM@&}Hm^_D=U^01*#sp64nCO_K8x!bE -zPAHh1*IPg3079#6*)!^gRiM2@DA)-(xc2 -z2_`VaWP*Dpr)W&zn`$!Q2_`VaWTNkx=$P~ZCW`@+j}=TbdnPX;CMlE2i-?IPnc$wu -z6Nrgs&*VkK1e3{&G$v0VCYn8y7ZDRoCNI*Mz)2kw9g}op0-ebZ3MM~lFu`OJNQnt1 -zlK_ngyhOzW_e@}jm|!vqASRk*f_o-EYB0fM5w8 -z@0pz1N-)Vtl}z5)N-%-vB$?cRdnWw|CI))XgxyLo8A_6gdn=7eKZ40Dde7vr{) -zL6V8jNicySNhUYqo=G*034BvYCP$qF6Bv?YGDF`p(J|=-Os)n@{-R()@0pzX17eaY -znY{4_#Dq>JH{hO00b)Y$nXrFAOh__u|AEG&05PHWOiug(F(Jw1*dJ(2;G~X;j!C*P -zfzG5x!Q@>HCM20Ozn&5kl1z@gPGbTuQ8B?i6Br^UB$@bLM@;BsawG1UysN>4B$K1B -zBPMh*nW68Q=$P~ZCZhn8KP#BfdnTuL5lre*CX-zR6L^lv1oup?K}_g96LuHDWDh2j -zT{I@wASU#l$%$PA6Zoc@Om@+jz)2kw9g}op0-Z^*f{B~PWDh12HWeoDTumk{jS0L& -z#RT_EU`Q~j!(_q|Okjw~1ouqbG$!y(HJPvk6BuGL(f3SrOnL#6Ie^JW3MTZP$*JcN -zla$HidBjAMOmNR+1!6+)nXu0zCYVf~r!iT9n9zGBC!R-4Fqu40V*)32Oms}rjR|xn -z? -zVh6zlzNsdY9W*9zQpZHcB+ZyS3!TX{1(T;~OzyyB@=_{H;JKPiUZOF9m#CQFo(T*I -zCQC4xyhJd8Atn>tGkKcE1iq;zla~l4FvMi?v)eNf<&PqTqsI^K)90Pff4WoQ%lF?` -z{`c|qv75UGnKm8XVC6el@1Sl+XOX?Lz~nDCPQ4^cd-PvY|G(*%)ZYl)oKd);H&ISK -zi`=BlF3%!2n(Ts`D0d?_^d<`XEOLX{xr}bY_|G(+RlV_n-Iihg$iG~}@F20o9V0Q7*+`vmz -zZg3L?hR6+O7aww?$u78w@`;8U%q~9UMw4BBUYjV%LYdbw`5D}JG667AZakSuZ=#&q -zOE5W;GP~?0n80()F1U#@7crqXQP{l%lMgYw?4>c8i;kRIDg~1_X-q!E?DASFOyIeiU0$OxftRS5;3f(T2_|PSySzp)fgxrW+(dbk -z#st2pW|!9pCNRY8^7Gn6(J}d%T%UC-V4~c3GLzm!IrRc!k}{dRfS72K32vf1jF`}y -zDC`S}2_};lXiOePOz2IN6E7epm`q-vF@cjhCORhR#spfGZxu|w*I%$pFAax$%V4Y@$>X -zOtMoZlWKwqJSWM7#Z8n9f{9nNiBe54F<>&OrZLGNnDClSlxl(rd{a#()ifq>QpZHc -zB+Z!o23nO&1(P}&69Xm_cPdQaxtdJeG$!y81rrW8QD8_g$;M>jCYZpGB$HQh6Qz#E -z1iq;z6F0#Gh9sFB{dsMo=$QOWFqsCJC^w#PnoX3a5tEe3aS#G0|+I)DcYJn`$ztqcMS#Iwm?M>Ba;) -zlL`fsW*QSOCX?n=n80&2nKaXwz)Mt2a1#ZF1e0b=Cd~vB7-BNPO_XLD6Zoc@OqvNM -zFvMi?^V&qwG5MKbk^`71H=b~sO_V0YBxN#bLQFKt1UFGC5fjZON)uv&$)t(Kq!KaF -zY@#$FCYVf`XiVUwj){&*x-o&yq*cL0(qMwgL`aDVCKG|i1YV+If}1EXL`*Q52#AR$ -zncyahq`?G}iGY}BlF83&6Gg}5XM)Laz(l$6gwt%I)Dlc8QznyIf(bmwWP+P0S%`^d -z6Q!15V#8!oOJkCSm}oXpY6&LrO*NU+(wM+W9TOdsG-DEm&Ll^{q>0AFhRNjRRG7eX -zHJQ9jV*)QxF~Lm~7!ph>F`2wfFo7W^6Wl~;qA`JQs>$SKf(Z;Unf$yqQFKgxCYa0s -zOq3f>IL)5Pe#9hYGTD!qXp#x;nJhz0G6 -zM8_oEm_TRJqF@ryV1miycuGt#nH;AvftRS5;GPK#5fe-%#}N}vGQmBQhz1i(CdUyI -zO)}BwdnOG8lPD&W1{#xG -z#6+`a(m*hQZ>q_pfyM+*>X_)5q#G0HOc(_dfyN|?$%IRV2|QPm2}ffBFHteUJrfub -zOe9Pu9Ki&Jm`rfbM4&N&Z>q_JBbdMtlZn1(qGQqvm@EQJlp9Yt&7R3W@hIgFTS -zk_qmaY(`8pdnShw6HF$DX-qaFCYn8y!-xqclfyJ7a8k!a$0XgDKxfjaVA8F@1e3|> -zl$c;LIZa~%FHteUJrfurCYVf4BPN<;f_o<28cZ;moJLGE$wc2X(J|=-O!{AxGd@>t -zJlUYxGucKk$x4|_wh>I=IY}l~+%p+SFtKU&OtukBCSo$#Mq@INV6suOXR?i80^d}V -z$u=4jIH_ZzW0Gb}=0j&PT*0K4#$+NU6IUus;JKPiTr?)|5(SeDxMu=Gf=L!86Boe* -zh9sG+#XXZ+8WZ@YnoL{-6Bv?YvR>aa(J|=-Os)k?lp9YrX!cB=LQGO7lcx|9I+<8; -z&!hw~(d?N#g_vM6d5XrQ1ToRJ?1h*Ir|lgvsPpf(Z;Unc$wu -z%QPnNO*NUkN-%*TCKG+nM8~8TFqsFKC^w#L(CnEUKul65lLLr}CYj)#$!f$zvuAPu -zF~MYVfW~AsVxrkIIe?g8GC4qF0w;A$bWGBX33MiB6-+K@Fu`PUA|)o6Ois|4z)Mt2 -zaL)vWhzTZ>6Nrf>nc$wu1q~*cOimysnq;Eyndq4G0wzNN6XnK}4VpcZ8iL8Pl*y!q -zU;@uEnc$wuSj0rLXHr8jxet>`4UNfI#6+`aQbRC-Z>q_phQb7V9T;mJ%d`~AeB8>9 -zV7=E$(vGC%P{?d5GaB_@Qh!O#t%>K>3+J5NF*Z6$%H1c-bjo7!|Egb7@0%_2TW5S^ -z-d1M(8~g|Vidg1V%z#4EJMf?J!9L?J!Xc_?UpsN8r8hJ+jVJFvoM935`-!C$FD`?ONijWERQvOH;7 -z8#4d1%-9WoG5W?DM=`4kOb6hbYIcFYQl<89^GvtG5VOnjq(yf5zjtvzw#yZLVii|1 -znFTWcu9d%r_1++5*Cs9Rh0N2+jK8`hXV=8D>xDB;?oHM^Ny^?QWIJVJvClXyTrnXL -zXm&Fyxy=Gj||Of5m#yCC8nAvNzwS~`Q~&T?b_aO;(cK$gp&<>98c%dJ<% -zT8A+?r7}O(%I{~rnNnqa(y~5iUSDopcuB6@7nimQxo+;xcDZ#ztaSjx6zjjFUj8}! -zlKMMOm=lYBfha25TXm0i+H*1rY2|@FO -za^v)H2}O0w$CUueHfB$10uF*(y|)iUXLth`NU=6 -zmJx}-XCD6oCs)tf#&kQ@m)O_mo9+wAwuuqjLMgH>X;~ODpDYtMgj)tB0&%xL?&1>d -zGSerkoiAZ`D@we4N`7x((*ybe0`btGr?r8%x^uaU~;bplLG{k#*~;GAec1L -zn7~U^OjZ$0V2GF;Aeb~FCI@ItRuN3@)nIafVA6<~9H22-rDI|l6EZ(jCO&vcZmNzq -z)d?@VxPP|GIsIcfW0Jk>~@?jw4W_C4J{K3F3HPw#FyDnhq-9XhJg8i}`jVWxH=bK9G`P8y?J_ed#`OEStToyI -zlZb-JdK!}!#N=QqOj;0=gES`V2_~N*ChKWTS`d?i1d|pTlg|*7^)x0eh{-{MNehk1 -zXF4Wwj{Xl}>Hdc>-yE6Wx?aI#0gcI*m`v(ZVFJ(9WKvIK0xwZ9SxGQ~A;Bbq$)uiO -z0z*tDD+wkGXiVUnYBH%On7|N|$x0m)9TUr4A@j#&;-*XT=56uKy9Kk06Wis^fw9i9 -zjK5IkyR7_3HhQhpy(4LPF=V!siN;HEcWu18LD=Gy#k+jstZ?TE8k3_0lP@uu9HlWij+oeJOpX#v;G60{ -zgdL?ZIj&=(V -zA(%X(!32}ZA;d(JOxEa_=$ND*6FXq?m4eAe8WTTak}{e25fe=^*+?*nBPJVZO#Fxm -zCKEr6NgOfRNMqthOfZ@FX-wieCORhR$D|56lgSDuBWO$(VlvsD3KMv)CX?+nCh!sk -zla2=nCNLzJ?$M8_okn3Mu0p`S46 -zu+o@#2qw8HlZl650?$b@X}1zg8VDv)D~*YVV6qUCiHF9dfnf5TmBz$FFoAEX$;3lr -z(x79aW6}$lKxcAD!Q@U2CYVf~Nr?$2lV@m5;3X<14-!mZh?rn9c?L0|lgU3HB$(W( -z!32}ZGl&VDOkxk}nCO_KAConJ$rlPH>u5}lAtou4$uY!)PA2W^2qxzclXWyE#}E@t -zCdX(@&LJl2XiSbFCYVf)(U_dmG0`#U1x%nbF)5hLq%k>($z)F|OyIeiO!m;2z)Mt2 -zRuD{JNH7sFnd~8$zz~zk3WCW@8WZ@YnoRZ(Okjw~WQC52j!F74F#;y73MQ2_CSHPx -zkTRKg2`2CylSw7PghNa!X-vEXlarWCyfh{pVp2(C;w6~CH`Qd~r7_`jOms|o0Tbv< -z+7wJSXfVNKaxf((m`o1Rn7~U^OjZ+2V2GGtGC7EtXp+flg2@IACYVePA|{$-vRcPP -z$0YrjJPMe!DVS`aF*%8tq)a9!5fe=^*+4MqKuk8!n4CmRFqxdBG3h`|Hqe-yL`*Q5 -zoTM@7&@s_5Nk1l+pfg#dU^0cq#E!{iXDUqKxtdIN(wM+YR7`Ns1cn5Y&6rGf5=>x- -z$prUIrqGzcH`QdalVAcvOeXrCiH=DxU~(5=@~MJ}X3yjmg30ET$>bG+2|UMSf_o;1 -z5fjax$twgCJ0_D?XiN?xCYn8yR|qEXO*NUkLSu4R$3(}Z7cha&#IImt)?k9kXp#x;nV2=0U^00QG0`Lwea}S4q!%#R2$+1SV4~SG -zc?&T~nM~e7Of<;^_e{P*Of-8YZy_d_Ox~g~`3f=7?3uiUm|!w_i^k+D9TOdsUcdx8 -zlP48S7SovYU^3a43KMv)CX;c@EM3YSPJrf<1Uckfwn0&2ZqS-SEASNl3NdPg?Boo{-Ng^hi -zJ(B=pg2^O6W0FKnGyCX-zR6BuGL!9A0!X-wdo -zYBJeHFo7W^6MfG_$D|i9DFaNx3MTZP$rCKWq&8(TVF@Pi9Fqy|nYa)Wde6kl5=?et -zGGS>`{>8O -z_ip`{)a$=jIIX`5@{hjbvyp7yY*(I@4c-O`KH*0wJ_ZQ{5UGcgd!Zjmr -zmiZg3Jj)ugq`JlDe+;Z}`d7HQ-~Q>WY*-L6jF9RUp8qlMjm!Uyhr5C`{MYX<%1d^{ -zm+Tdu9(J?LzhvbfWDP&Sa9e!IZsBeh7lxC=BZe8$lAF)}82H5FpX=oIvW8E8e^EZO -zH-4sCcyq+fGQZBs|BE$z0K?t!Gd04)9_}_cIZOW~^*KYBr6n?dqm_S^wPi_74N1$q -zpm|=oc+(}hsXpGcUAW+u#oK)16XBLV%#0$LFShExq@MqdjSlK|B#P{b0#l$|oO(&_ -z-V^WMDfHV5t;)3uH=}57N-?|aKyE|_YnUWu>=UkmgS)K!FImI)gD=W;)$zJI!R_MO -zul-0i42&42OLaN#{uo%{@qgpw-iG0nh+(m`WUDZ`VYbW{S@}P+hQAKJC@-mtFR2xt -z-Zxw3ud?#bvW84)$)a}&CUBBqQa_tuGMHcjKL}#-u8xVm)|mFS#y|cNFi~zinL=-( -zJn<62q=d>Yh{-PrCi~{on0!JoxfU_`gvR8T1e3k<2_`Tkn7~ODlTT<&en~KCm`^Z) -zA;APr>X_)5r1`eSz0j(76imuBm|%8!HYFx=2_`qtn0OGAGXxVDA|`VQCO04^b7@S@ -z5KQ1CVltOtasy&Am&W9bj){&*`Z2KrCd!Q`Q|L{UCwz!W%4A|iOcv0XLhP>NxCtCR^{&sCJ$*a!DRA6N=)VvOm3ku`8#5Aj$i^q#AF`90w;A$bWGBW$*-X^8KYn_gvR80OeWQ-FoA<=XL1FN -z$r!}s9fAoA2_|=9XL1F>`dO#G0`zeKPE+hiE`t~ -zVa+Crn_x0MWilxunB1l5OhN>cF^EZs#-xZ~@@wo&U`Q~5lPV@58j~V|$(`7lz>r`9 -zCv{A8Owx@BbSBRznEXnE2_}=LQ(}Uh$#pa)&mbm$C78evF~QE{I>bcNnf#St0w)m@ -z>`bmhOf;RzUv*4$Owy0ZgMf*0Ba;)lY10QZlp1J1(Qi#N=&dbxr)Z*9>nB5 -zf(Z-}6YNZ`LQFKB$$JD7IEk2GXL1!{qUlWD(=pL8Nk1mP0Zfz|PY!D~QJM)RFQ-f< -zzd=kiok=UfZhzWKkFeI43Nfnb;8k653CfJ$4kYEBQbxd?j(v1mpCZ8&p -ztkqzG$)qVICfJ$Gr!n~yF*!>xfgxgooymN}MAMm^C78fT!~{E&`G|?8GdZhcqGOVN -zOsW7A<;Ii4nmrQ%F-e(Bst^-RXVOM6`4ll}qcN#MOt3S7A;APrs+hFVm{cJq*qOkP -zU;-y~Oms}rjLApPnaoo#nLuN*29rr`Doo&@+L;WaF`0*${E1)!LxRaU>`aCcOg`3h -zCVwKBz)6D1S?o-P5lr9*!OrAQIwm?M>Br>PfQfSB$zjc&$;$+j)hUz7uL&j}YdVup -z2`2LplTT?(eoZj>2s;xP5=`Kvipi%mCch?_oWsrph6EEhsbivJl5R|(GdZSU@;ePC -zm`wJk!~{E&n`lgqAtoOZOkjwZU}tg@Vxs9xJ|vjHNyG#@lba9|O=t340w+~WzNRsG0x`kP1cn3?IH_ZzW0Gb}Zi3EasDjA= -z8k2FDOtz)M1P-d5Nk1Bsp#+nbKN3t}NHCd+ok>4}$t=1v@&A!v0w)P3Gq5x1M=*gO -zgmfmy{-|T3W0HPM3NFeSZ!0&Rm^FJQE`rI}l*y!kU^0vDOil+0CPN7(CxbL51q73u -zurq-n!30h!n7kFFF)1LJ%*4(Fh6EEhsbivJl5R|(GufkHQmnxQlgU#lF~QE{8XA*5 -zh{<0FCNM-yurs*^F`+vX|6d3ua1t@W&g2@zgzij^{YA$_$0YrjtN=`u8&AxdJ(D*O -zla$G11!6*XCZ|6qnCwAJKBqBRftX-t0z-lcoK!LSoW^7YVuGCs3<)N1QpZHcB;A-m -zXL5&v$ut_1=P;SO#FW)n7~QI1Ur+_hzZ@9 -z9Q(75iH=G7F}WKsQEogjYxYcDRWSMS#oyU~*{^@!KEHT=-8#*+3dduK64_}xw_PZh -znIrRMRzAoYhDjNFF8`AHyOA5ZRXH6d+}wfOglTT>MsBcGfg#}rPO995X>RUDZm?B> -zA>js2>fGquq?;RPRX+U4EW5b84?mI(vm=JVQbwInJ!78C|INx@$r}F8+>3HXO+2Gs -zc-P6je)*Tw!$I{Q!sgQ4z)O^0Qs43s;Rc4t4Yn$CksG>I@#Bpra1yz}R%I@7L$@l& -z^czofZhC>6hk={(|LUA7W%$nj80hEmS35Z;Yxo=hZ -zK1573H=aCr|VVXKlsFyS?=3f_1ECkZC-GpW~SWe`l@2f@kGa@7ci*=Od<*<5gHSCpklHh6(*I4iKbP-8&AB5 -ziRQ+WO2hhP>NxCtCR>h`ZV$)zUhhUPG5)*7y -zvS>`;B`PL(;|UBA6Kqwo5ED(Sf;XPPNyG$Ol`O!OkQXG0}7;c;gA2L`<+V$wf>wor!+q -ziH=DxV6qu7`AWg$D;g7cpkk7;Gue!oXgU+T@g$0vXl^{&jF@0&0z-lcoK!K<+<3AX -zF~QCRh6EEhsbivJl4eZSL1!{i!DJ$h$$IQe2ByLU4yv8WKpGQxiHZr{cmhL$$p-99 -z1``Y)tFoBaQCYl>hRwE|Z -znZS@>0w;A$bWGBX33Mj+DVW@+!2~;#u_-aZ&SWf&3A{wb1aCZnA!34^$ymfh)0yCn -zCvXxm!OmnXVxs9x^czofOnL#6djXSH1(Q}96L_FvlCm?o7ctRvCV1n?eTa$X#*=#y -z6YNZ2NHBquDkhp6Pwquburq-n!30j~nCO_K8x!bEzEm*zQiBP0CJRzxf}P0%8WVVl -ziV5C$0znhqndmp3=$P~ZCXWCnZ3-rBG$!ys#Uy2C -z@(5z0=}hp(lP?hy&5b9IAST$Ez>r`9Csj-|H=aC#m|$lDLxKsM)G^U9Ni!z@g3e^2 -zg2_S}lNfd;BT``k2i4AG1dR#2M8yPeJb@v>qysyX5d@R(G@S|FcmgL0Ch#+Ba;)6T5{ -zb|#Av6HRBL-*}>9(hHbu0ZhJDF!`Fs1RkiEr0h(#ASRm51aCa)K}<9^o@_x(urq-n -z!30jKm}qW1*@Bp0X97cl37ph1(J@IgCX=8u8Kht`h{j|xb|!sOVFCx$&ZIAm3A{wX -zguxq6U`Q~Tf}KfUg2`06GkFqkJb{x06Zo0b&ZIBF1bz_GnQYQ;Jkc@f1x)fU${CLZ -zf5N0HNMiyI6ilY1>`d|rCR6FoWDDMSGKgSe*W7rLPcWH;oe2yHCU8>0u -z_?gts1cn3?IH_ZzW0G!6pflO2V6sz#33et|r^Ez1ldEY=;3X<1c;g8S5fki8u0~Ag -z&g4nF@dQpHCfJ!=jhN7#$tL~A6CIOYz+^dK^0|V^=QJkpK*c0wXR;hIp*xc;c;m@V -z#6)xB$#TR5I};cZOyH!7iRQ+W<%kJ(CNLzJz)2mG{~u!_fBf2_>$Yv{)91>)>*+fc -z4o>{?&iKT{cJ9`Z(&payi&PGOk(ApW7Sp#q{K%54gBqxN=xPd0|5a|hBAoee_6J9C -zfxWoIR1VL7<1@|=XHI6`yQMN|nG-Und2eB5((><+c}SVDAl%r_ -z{@|EaVxN|8`qjQB**Mo{d^p_r4f})RNRjDzMSfN;gAL?GMc&-QTH -z?Q%tCtYSD*QEJKw%HHV_?^vn1K51csW~SV@=#t#LFJ8G-$Z~Tf?Q-k*SnCx`PO;3d -zw(=KP?|^PcOOd^$z;v|SIPsEPxhGz^Q;2wE;~<~0G~7CbVM=6vrj_Sd@5F8gQ)=(b -zGc5|q-fnknWC5&~+;tHQQI^1$qBCy}(-|yiv+vS$gv6c+xXo<-dlx;I2 -zw#m}6eM!s2pm}1sI6d4lArUz4^dEO~>)Yj)$+4FHOsq)eO;)~*wT+Y_dyA&l_I;wYb39%hCylS^fOjFo?ejb7F5I8F)3}fv -z9UY0zm4xb~#TYV+Wg-)1`X>S#-2M$N?#p(W85Cp2F>Qr1-(%$mvC*rg%{!8oeIdAP -z;re#DGwuIh8T@ -zi|xgQrck+YFT7+-EORLH-s06s%R@o)L*>R(Fq|4|?88heGVN|SARAZsjHAPim!AK@ -zF|E)(t<-cQ443$f+2O`4=E$w9la{q1^FPas-77E1jeTQ{qnK3%rUUTJu|DIy;l|kW -zKR8yE+P}>+-3r5*KI4XP;~?hSMXQsRAA;r|%8h+5$=SQ&**k;`k8B*}GnR)dhB29? -zGC$hNKh1it>UK1i*c8UCjymj -zf2E6yw96HPVin_<)5k9 -zwB*bDaV!4_>s{3CVDjutk?ByGam^)Js*X!_g5Z*kkNS)w!>wZyfz2-eW)HWR_0H;c -zbQan>OHKWQvh5cU+m%w*-lU~4Xf7-lXNPkpB?2W*e~FtbZMKb>@EB{y4meK84T5MlhX!^8V9Ck@=+8uAI5mtL-agtBGKb$i%5xC&-k9Bf2 -ztZh`cV@8R6M!xBekZhX}vE3>y+m^H#LS}E7SQ%~^mV>$I^S8?_BV#R7naO!Fzun3gveDVyj>-A< -z$;GA*%EX5*$+_F&xx0lsU9z~=Cr$`6W0^yRrhk-+1H#OxL|~@NKhwh*+GQp)#tdgn -zrKX#Ma&&qmI#v?ula@z==10rLMVDk@UwrdcVTzk8ZI?U8$2zC>4kix)Cg=Z^IhYx+ -zctg^XA2jEe8)t_ze|#G;q3)qWOx{LJ4$_!xAej6eG1)+4@-|{}kYMsQjmh5;lMOT` -zZzCoL2_|pTn7~OL6CIN@NBkGy-;1wTFd0K*au>OWPTG+Q6L_v-vV+D1UZP^MoL~Y& -zg2|oF6HImxOkjwZEGL+Zp)rAPs+jB`n7|M*S*~NEW0L-R=zay5e4=2omd4~Ig2|mJ -zlgUd26L^lvWG%tu8N_5Qjmb*{le;jPyhLO23}UjD#^fb}34BvcCNI&Lz)2kw9g}op -z0{>q8ih{{K8cZ;mJev{|OeW9Ln7~U^OjZ$0V2GGtGIj@^GA|~r;Onit5CKDfx$)||PdKwcS -zVuH!UM`Hpfbxd?j(v1oHckI_Fn9QRw`52SQ-c*>tb2XXlr7?k*sFF`29+n9QRwfp4nGWG}%4hL}uN>X_)5q#u*t0Vba*nAm7cUL%;COPNewBbdN* -zOeQvh$uY#lMq~0C!Q^91Ca=+$979ZOG$yYROyHYpGI@>01WxLh=$ND%6X;C-p+7gAz^$>aqZ6L^V=$r^$Q3=tDdCNCf+nq;zuV6sVr2_};l5ED%@S)*g3W0HPM -z9tTXmQZU&_V{!^HNtsMeAtst+vXNkN5i!|FV{!^H!DMoZ#^fSmvXRE*6k>wO-_@w=2;G1ePanqQX_)5q#G0HOpFR91{xC{lSy4FOyIeiOzLP%;3X<1D+neqB$#lROzH?GFvMiC -zf?#5xF@bNY$)t{80z*tDD|AeBOwx}@1z^&uV4~SGX(pI(DU(Sv!33UTGQm9)FJhwE -zGifH6@R&@RX-vF`iDu8FnP39nRFg?FjR~C8G0`zeHzv@Thzce)4JMdOno?qd$)t(K -z1YV+If_o+~L`*Q5G$AIMWP*DpHVr12OqviAO)}B_zn7}vHWKv5ofgvUnea}S4 -zq!%z*3YdJVV4~SGd6{6cA!RaonP39XF`3|=$w9J60w;A$bWGBX33MiJDVW@+!32}Z{*;(tGTBdK0xwZ9!95cgA|{wj_9G^m -zWP*Dp_h~S}WU?PI(IgXn&qT+h7cf~5n0%>VqS-S!j+mrOCdUyIO)|kflP?hy&7R3| -z!~~PcaT=2^5fjax$#KL4lgV)!6F8}3qGOV7OrSG)RKa8+jmdYIOd3*Q0?*ZC(m-PZ -zFHteUJrfubOgb=`G!RT+h{*)^Ocv6Zz&F)o(m*hQAtn=j&qT+h7cemaCZd9gX3vBp -zm~^B}CLF;8o?|k>J(H7&iDu7)Bba=L$%LaZIff9!32}ZVZ=m}O!Pey -z9g|+b@NCOwFWX3yj_VuH!! -zG>r+I)G^U9Ni!z5L1!{j!DJAP$y7`x+frcy&(&nIjm89CqF}NG_e@|&FqwkMWE;T* -zh9sFhj(aA9XiVUnYBJeIFo7XSCQs^nCORg)fJxy+IpaUUpD@{?*)wqwOs1qvCN6>r -zJSWNIG2AoRNieZ%_Doy^lc|_YTr?&-2__EBo{5WK0^d}ViHpVrPU@KGn4}vM=uGx0 -zn3QTT!DRAON=z`BJVj#yFHteUJrfurCYVf~LQLpn@;L69lxi@+WbzbZLMM|a^*s|E -zlU~4NC1CQof{A9&vw;zj#`+uHw+;)83`-d22^tirYWM#eLA8j1GxJZ{EI!@toCHo5Q$Edx*IwITb%waZqC9+Zx-b4?eXqCLciPQc3JvPJ>c)> -z;{LerqlEEFpRp{QIgA;Qng#?D#(bag>Tt#QHtKSRD!HOxtYS3NSkPrT5;CtUGyX1IF@k9< -zHD#6=i>u^{A+d@HOhtYd^=s?f9IZw6)&f&YC}EuJGn&E`BikIUrS_aW)9`ZRwN>PH -zhc3(6p!saMacGs?Iy%;x!L*c^)&~>D`+UZQ;npc_)bFjYl3NGFS~D4@u*=dGGA}AK -z-c=>H4vn==WIFRrPlghguXkv33@@?|FEDKnCB!RzVp%w67&E-I%W`edd~LaSLshC@ -zT;FARCTM=9T)e7E&dH2*j+DB`F-r@(ET4wV^UB0uSIId;V>uIAqk>yw@i#2)9gbbHwuOu_DvSGI2wd+%hQEGLDHAc3FBt=0Rm*ewEA& -zjxpnz$@!+zP(qyJ6CVmQ{n{LditL99Os|yVFR%|K!~s6BILr)bbC^o(rhJpJT+FGG -znaMGxKhsv!WqB)Teyd!ZTqQH(V$4XUt<*F!m=Ftn;;8oWeYrXPO#Hh}ZkXHQ~+yZH_04?N1h(z78eCkv{RR -zaOY4aQPO2`1kH|e*E>Qg?HWD?^(lbQr%YJn#BvcEKdc^Pn8>=g?D5}3|UfLgRtVZ1zne~LV@{+h+(Ew -z*Y){%$9tvrX?dn0@E?T5|F8^Nu6M_9KO+ -ze@;Ev!w<9ads)L6>CBIxpTB$;3jFzhS@}t<;U6nE$&Eu}jT4z~^G%P#pMS#2|Hyj# -z2;`QB9{w6D?`FN@rR;`|z!Il_iJQB-J?Whv@eY%+_XuZP-1n@vpVYjogItD^^kzrA -zSyFR@Q0eU9o2>jY*1JHEo43cC_Xv`!hq~sWBar3sH#xbN+mqf25$~;1<+hH%GPi%3 -zi~EfA4j0I6C_VfLE8oC+$4JuNj)36w3vO;hd(yiw;vFPOyE~|R9t2t18JG461D!qm -zHY=ac+GY!KR&_k9PN;Qp|J9znd>u+hpv2>U-^snf+9pX^`-JIEZg+dqHacRPD>YSj -z1YUOglldmu&8=-u+Hxbdfl|}%j=*Y{f3=6ZwLNK@8L>@~n)V4}ojrVwl`m#(a|C%= -zb$nT!u;10ge{1D4S=%&eSxraaUXTAXC)d)Rv`voK7DztqZ~Wo<(RIZ_vo -z)C$KvJ^W-Ve~7h>lOpvUfwG*cP$&eL6CE6 -z#()3$yko!7p)s*nL9I*cQ*&Efg%8(`9jm%*)G+zYS-OU}{QDqsokb -zzWzeeFgjwGE7g7f=kwH^C@`NMF^rY!5`RALcrV}nUa{%lhoA4^|6}E^U=3GGOD_HS -z{N<~IUVOfXf6&VRAJ*{Rm`!ry=vZS0bEL$y7XG}?%2%<51kA~$DDdZRvhuI7hA&}0 -zIo8;p`Sytw9f5~k{)au>ZLHxtn5+MfTbE@($XruqTwWztToJ3dipeZAy%$Othxm-Y -z3Rh&brMeX*VVveOt_oKSXmeB)+bar9t>wnyRdU6cSjAALwWRCv+m*mdr-nS%V*peZXLvQ7I#?^L35&9>{BJ@Tp7z5%nUE-qV7d$bJXYA>x)dDU_!L| -z#PQ*ru}poT>F?#@72%vwZH}b{_N67Jdx8nLKInEfY6<5IZ*wdywV%y1%?l;On|$KB -zaL%AM$Jt{0*+SFBaC^nOxju`5 -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 -z0fnY_EYJ7wS6cZ$u!b@3upFail12C5xBrJm -zVXW{ObHWvqnby26OHRn#Qf6FVMJ{#hvUG;b!^@0?;nu-zj+_#EPQGbrC}EuEGj0mE -z_G_c=KCO~l$HrPmFfFBBmdQc${rKV;rsCO%L_Uw)bp2m8cdhI2C79Q7sk`h3&Ma`BdM&J<>8o@q=d -zAztSb9}MRVXoG7V6WfJkvFX!bLag$M!@@aZ+8k#K>}N|%n}P}PexG<-IAn566XF)1*f-2v+2)vBV4qxK -zDlHSst7K+ajG4q7%ImURA2PpECaw)L1DQj`rhk-)k5|b|-xxEBF%@)Ko(q|cWnx8` -z8Q$hFmD=0#OgD!T;tZd-KFkbibF>xP+X_uxp1m?!hQES8Y@>oW1tD!H?N -ztaA*LC@=*=32~}Vw1hMNcI1Sd@gLs}O>$+0flwSwEjjfeTKea4%@nLRMy9iD$M&w -z4A)9$b_jC=^Sdm+3z~mdZafb2g%QIb>C6wGoTqLIhWXTp;dUu|Yeyi%?ay#=@3tqs -zgCpJ>r0iOu&eL=G4pc$Tu8(JL7tXl3hgt7!Qu9_J+ug%2vGQkFZ-yW@*TtJ_g=P*=|CSFj*U4RL9ku-VUu;VG(n6OnJeDso -z{~zVcX)Ish9i)6Yh2;y()$%1mmoG3^%a;f#U(A~FB|^#7>ukn#ooyjs54=<)^r -zyk5TOFYiP7vht_$C7>x^>Ph+HPg%a)jOEMwbol~vwS0M>lrLXt%9r;^`SLZE -zFB9qV1^&ERzQCN6FYxEp@&)E<`LdEOUtq46FM9dXJLSt)P`+$b%9pq3@+E-f3(Ws# -z`SKYlU*H{BzI;Z?m#?vWxsNVi;Loe&%Y9hB*y!>F=4$z3qsteVtL2N0lrI}K<%>-( -zU-a^&*UFcLP`(^e%9nF=`SK{1FXvK~FJEK%0`DN@%U4*wz+5d~*3jk4LM&g_kn-g_ -zP5H8hlrJ#H@?{MvUtq45FNf&z1?GDBqL(kdRK9HN2=qIxlrLXv%9pQ5`SMlD^2Ltj -z%SO6N`J6*oOTrFR=lk(*W -zP5AHheYRY5?&fPlcbkL0?5MifUO2??WKG;t==Bi`<2r%AK8%+Zln -zntfjs43e;AVQCWR!_r}CXxe3PLBT{j_Sm@0a&uWBKy3w0x<;<;z@JzO3cTmzQYy0&`rx -zcxm|pb94Dp&zCPSSIZZ*d`VC9 -z%a?WBGEJFJHp6e1Z8tEnkwf -ze1Uu5^5r5eUtn%7U(WL73(U>s%UN8$%$1feXL0%Bm6k7Oarpv2Z!TYE^W_Wtyjs4f -z{MLd2{&!b94D3HD6$^mM?1glAh&D5|%GsWBC&1%NIe*7nuL^@+FGP7q|y4 -zU!u5t5wv`9^5qNsyt#aF((*-WzQEjEzDUg%n48NNYQA`-<%?>*sO3xAmM^2`jsNdt -z=I^}wnnuREE(*50(J%g<%&v1}7uxQMWL)%qa^BgNTxz^dDY@P*4u9L@pZ_p(29pQB -z66QO|y!)HH-zF)|c%QyacqbVziV@j<(fHlF#+xpao9yD?ckkl6Va4L6a8ujk#tSf# -zw;oN3FGm{5X8zG+_`6-BJv(yjy9;e)A~))7_->o|>vZR{ZQH&aN&h||e8)`ul@fnW -zd=&JWE1K~8=fgoSek!JI+mYn4uY~%`P5tGTp1<6#uKV2E@haD)&T{8_*b8HSQjUMQ -zb-c&wg|YMSFSlNG{4Y0{8-KYCti!+D+Lf^v#$Hp0f4Q|U`~HQod87DWZt(NQUv4kM -z9RG5IpEv$;dkW^pUv5{qSZ8@Q%++6R>MytS{N>iJ^gDgteBS|<$vlddpFiDz3Hy2FS~5Pe)ulM*+VmDegCnF_vco5 -z>$3h-x+1u`isT{b20U`(%UnR*2}-K(tS!HlrzcK8+LqBm -z|CvkYuaosPwM%&IqdoQ<`|I_hsY~qA+scFfDiQ4#h>neDUE9L5szQG)_aAE%T94*S -zZ(p|es25E=V@*TjbJFmYnNj1DcDD>Lv+;}5pG_wldHz?G&w -z;`_H_CfK(yTJYt|!s2azZTN0~{xVtd{oBiu-@mK8g})pVKZPN_fA?~Nz3i_AU+pj0 -zyJW@pFE2~rtI7p?H>QYsUHV*K&B%ne+bB=B(e{OP!hKiFeMS7z%l$?4=|J>~NLH`5 -zaDGK7zsk>FU)CtHdNyZWsg2DS`fVe$wZ@GU2^F&vSdO{eybp?ijoDR{!8HszkJZAUZBm+r2IPX;lc` -zTjq23PIzbLduC?apQ;z`0WtRj@!0&N^MQH?d;}v>+qo^=S{Z7s@V7Mz?XqU=YHeVS -z(BF3H@KXQyh$TtqyY-G+3!)FVh!KlhrEkUr?Bkh}N$y>@N?&TQPl2BNE;( -zMtQy%Z9iNmn(mD?b&m&ECY|5bIp8gSk@Hu#g$GrH237fQZ4~EI{mHTpLxnys+d$_> -z{F7x1@%xuUmRWtW49<=3U*5cof3gg2V*LNobf1{~{+lr{#7~wj!0%t)vkX6321ES* -z<&_hY-@oPWNBomz@J!?XmFD(k_{lODVyNjhG5P&VF6Z&vI%duF`m_<>^Ig6_cby1J#pzBL -z=;RhrwxG34VFIrv_eUGW`A*H}`)HwDp?~Yr;ma5C#G<5gTfM_s5Vf_4#FEy;n&8}W -z5q&&x=}rDxTei@{F5Tid^NeTWI16DGyU?>`k& -zPM8!Y>1CKd_8}$<@%xuI_&6rzgh_Fd-W_|t4>5sfnwa=FCUB*~L}8NR?_YMfTj=xN -zG%y)2VS?Yk9J0|86a4<=%^Nu;a1#@gsfY;-2^0MO#h5I*OX%~iH!!)HW0FhBWRVpn -zaBe1(MH~~jiHXSs!~}+jNe(5GMTiLuDVa<_Os?jbz%$KcvIsGOAtjRu3KNA%>M{8# -zU}C(dzx#BK$#%pf$1<60M@-%%?VveC|$uS8KCX`G9 -z9Fsc2WG2TXK$uW632;o{N`;BSB-NO}&SZjt$z2?iw<(#dvcd$;&1ABQV*)oZF`0yz -zzz{Kci;~GI!~}+vOeP^FcX3SMnPxIsg_yvQlF1~6iNYlHnEVnj`P9I~%`w@7n7n0~ -zO!goqa8Aj@jhO5sOxzrkJ&4KMluY(;O!g5bZjQ+w!~~vcCX+oJ6Sz`gqA*D{Ca^R4 -zy@AQo5+;;PHd|ss$z(If1a4wtG7T|-Az?zvWHVtRC6j50$q)rZ7>M -zq#l!B114V@n9Syw94AaHlgV+yL`o*J5tIKROlEUTjuR%7OpbF*{)aG`%`rJnm{2k~ -z&M|>26($Ok6k{?Pb|yUyOs?RV+(^k}ffXijZYGlj922;SfytWjhzSf4lN%_REI>?P -zh{Lk}ljV~Ulb=eMP%>FZnDAt>da}YqVUl`G -zCIcp)T}mcvq@KwE!o)I}93V`1GFe7FllKS{sb_M4Frj2}fMfC=VIuWR4iF}kOb&2N -z;7Wyw!X(w0z|N%5z~sjqlPXFkE37bqb2FK&;F!QoOiZX}0z<^4l9I^^!~}+vOsHq_ -zV~z#lSCQGa^ -zfpasNEa8~IO-xLvX97dSWFjS#C5Q2@JCkP&Ozz{D{E?E$8Y@iT+)O5GI3{ot6BFv0zz{L{ -z10|C+hzSfSnNZKFL -zaue)Kt~4;|z%l7f$z;A2CU9;hlldGIxQT(uW7IQ&A!5>tlF59;1csPQ9;Tj22aX9m -z(@ZAw5fd0+Vw)H7Lxm^>== -zOezqQ-jqx#I3|k_lgFi=Nd;m8&oq-s1;+%g{6S)poc8IUb#IKi?6ND~x%5SavuDiz -zJ~Y!4t{>T0b}o=B^j4SN-B)vCJiaLD+*0qb7uakqBEF3azokWRn86E#N>vWC@>^$D7(B$-0K_cL%-&Rj+&My^jR+bufCej3GeyQ -zp7S~OP@!#bi-@mOFRA|_eeq->aASP&FEc3F;?z>u;FHBoNjn7}j5?6Mp&fgxp=A7&FpVe)VO`K%`Z -z6XS~~k4a6G-H6FL%j~inF@bZ+F4RQXPMAndl--EQdde=lIVRf)6RC-^8!>@rn%QMH -z#{{lan5cgdmg;{I23wW)4NN9Wm{2k)wZw#yNh!w!Zen6WO%xasCX`G{2@@%qP!nac -zgb5{+Qo=+^CO^z3io)dI9Fu1O6XS~~k4a6GqlAfNGC4|^NXdknDF02ENKKTZgb5{+ -zqa2g}CQPIz%2C3ElF3ny30$c#QJAC{lkKooxy``j8ji`&D48s_!UWFEWU`oJ0yi-+ -zp(Y9p5tAnt#353`A)F!?vfS1L>tCaJ~*b|%veOzz>Bd_u`&wG}3CZYGn}922;Si3v4PV2GG}Ovz+5Vgf@- -zCe%c^hhqZIG?U3{!~}+vOn#V66otvZIVR%(6XS~~k4a6Gy@<)jmdRu%3fgvW7_o<0;6~_dgX(p3} -zhzSfanVkM%Hc=EN|K^zF11827PtHh9lq$qzm}N4lLQLQslgWG3L|KKHd>}PZst}XA -zDVbDpOjaQ#A4yG=D#QeyX(p2@jtN|;Fj1JK8WY%=lp2`)r-TV5ll7LEP%>H1F@c+y -zm{89IhJ*TH{o}#Q5UL8L4M-kT9`K -zCI<-%ViPSSWNSIJEImj{jkT8*YCI<-a*QyMk_q)p{z8~YJ(FXE -z2_=(b9FxBgCQ{Gj7-2%mG?U3LjtN|;Fj1JK -z8WY%=95pccF9{P$Ca+s!LdoQHjtShv#Dsb#FeFSUnY>PzNXdkHCjTX2LdoQH!bD0Y -zs%N4wNdqRc02AYjCugLd$zj68GMOAEOr&H&J(JG~6RBr%m@uJaa+qWCIbkC8Ob!z! -zluQnDOyEj|iNYk+n842DMFW$ca7@loGFfYd37nhBWG%-8Zen6WJrfurCjX#hvKBFc -zAte*)nf!!f0?#y)$y&q&hLlWH&qQI82231)iSfmgGg8k)M@;@-va-1-cdL}wz0?#y)iOw;BD-|XRlT>2@JCh3rCND{tP%_zOi3uf> -zZ5$K0iHQmIOkhZuP%_y@m`KTldL}PPm{2m=Mwm#+MDY23Tn7}iQWU_Z2 -zVgf@y85!q7VMvS_RvB2Ki~i7%h@eGg5Uh)WWD3&0^7qaV#wmw -zA*+L@%KZm?HP^+5tPKt+7q+~B?dC{PzqW97d8oS5U+k+Hk?=N*@-&RL*Vc)edt)`- -zV36nj5atvc?F#k4xX+tI3ELuTDB=);VSt -zs+ZJ9uWu0}R<({;5L{E~pVTO{>zcK8+LqBm|Cvkw#Mg9He8kG&nF{|oUsJn;*FO3O -z^^*F_&xtO-eB;tLQQ&|0*>#TWLfc)DjN|azGs?4gw7mlUH|`49u8m~$(H7_0e_v?p -z5XsmNzdbpgynK5hoMU$R@%W^3XuV^9f$cBw+tax@qpx-{b9~bI_j<>b1-6_>i4T5z -z@;x_a+aHGCfnfpLvyqa@d7K;g?dj88(p}qe=lGrW0`~Fr`9H&9qSw&3vJi8h#{+5hb#!LsPs>46h+rH7q!z$MhpE3 -zm;SM@=BoIRmBCXL{(tyt+9kY2qdi4A_L6#0(NZgbO+r)saSEM9RPTZ7nZd^&{^m@mi3v7u65;tYYO*wH>#<_7NouVT2j|%_A -zMp1NGbJ5jWMvlV*5wn0s(Mwl?YPT=(x@YrGyXdC$OPGRNcnanYHg)k{aOkUxbg*(K%K-K0ZmV}V -z3!=6bkyz52SQDIEE~1YIqIX8l5764Og&ub4USH;@o`A`33`{0+OqL-gD=d@AGQ4ajtM-|{1;(9!~}-) -zFT#oyCJGbh$&C -z#4?#|Buu1aG8HkINSI9Jm~13WD4A^Jm`o&0rgBU+5+;;PHgZfRDohk6X~1N-(C3{r -zF!_Uo2_=&wmY7g7Il?i4o0yo)LQG&tm{2k~LYPR&WENub2MH5OCPxSpDVfYtm?%tA -zkI9vQ$y){{6F4S|5R*qNlgT2)1kNd$Oh8O}5hfEjCW{c0M=6;s;+XUzOeSzl79l3^ -zOf#7*;+XVOm?%tAkI8GWGr8HoWF5!kQA#G;tuTReGns7Xn7~a;Or|3yFhooqp=7ch -zF@Yf^lj(@bI*tiE(@ZAY5fd0vGMTP0QJAD2liL83QwAneI3}+VCYH(MHNr$nCQ}fT -zCkT@%9Fx}w6G|qpaZH{dOr~&5UL#B>nY_j^c|u{LFi8U@urt|VVDhnq2_=(&B_@#iHXTf!~}+f2_=&NVIn1ynTW~95+;;P0)&Z_OlB%f6eg+1q#t1Nj)BP}j>#&- -z_@6=L!MC6iSglVOC(B#y}{!~~vcCX-bhlVJ)Ig-IGP -zft|?|1Cs+BlMg7F?6JZG&dp@9hhqXaF)?u?CNM-yPEj)1gP6dOl8GBJIlwW2XPU`m -z4`KpCN+xcFiNYlHnA{JToG~zÝUm{=y0&4h`ROr{|w&k`onI3}A36G|qVIVR5% -zCet`3n+X$2CYw1X&niq5CTYL~b|zmNnEXS+gp$c|OH3%49Osz8O-xK?BPK8;OemQg -zCrqSdG8-}ZhlB|wljDSmluTwTOcW-m$D|`*^5!K>{8GJFp+vD>j)FeWU`Jh;mO2DJ(EWW6RBsijxeEQvW{c&2w@`iOx6)5luXuf -zOde5~C`{6T3G7Tt3`|Z*m{2k~V2KGOlLH(RxQU4g^-N$$m{2k~K$!4kvYUD)rzA`$ -znH(TYcrw|mdL{~!G+>een4B~)k$NU85R+=lWU>M=fpbbG)H4}Em`FX76^Ka2r -zv1Kw@f|$TLB@^nI^e0TDp2-r##7)U$3CE;AVIuWRmLMkZOf#7*;h6MSm?%tAk4Xe} -zCRqk1WgHVXC6k?2n83N2Om=ci;3g&})H8u0Vp2@WWG7+*LrNypGb!Vkz%$KcvJ)|Z -zAte*lGf|kN0h8MSlMf6`q@KwJ!o)I}Y#>aeWI{cYafFG~Guc3xP%_!TF&RggNIjDc -zgb5{+4IGnk3KNA%8Zd#KNv(lNOu~ec$stQjD487Mn7~a;OsHo9L&AiT$sxi-N+#4Z -ziAk7HGC4$;NXbO?OcW+*z+@m`@~(l2)H7Lwn8YoU$r{82&MBEt&twE)BK1txASO+e -zOxAErMi3@a&twf^0?#y)$r_Hy2!)BlBn_Cr&O|dX335!DD4F=JFoAP3nfN&-a1#>~ -z>Y2b0F^N+$@gpWMq+~)plOV?go@pi%KVkwyN+zmjqA*DVCJzE89~qcPJ(I13iDfd` -zN|;E=gnA}(2otGivh{mR#NF;550C%RWtVk$d-eC9Q!u})u)Zx{l)KNY-wr>V=ear8 -z{(e)buyqO89*LB6(RRQ;>-0Lu^g>&3&NrfDP;<%U+LY1uQut??8nE?=l+;nsJx3-A*s@C{|V6alyh6ijfL>k(+h38a;=2ZB<^wso8 -zc+cl~&ga_O>V^BVnEOZZ{)>{%h4qfyf@nb`>#DZ!lB!UCx&PHhk=3O+tG~87+dio< -zdS4`KkT!Od(3iXPhkfp03Gdi!&)7WsCk4@8wTQC$t!2xDQ!7MtMj(1!B&%;*_?wE* -zH&y^F?oW6_qdcL}cD*3#ZV_`9w$51@{IWtsJ%MQF$oZby%Q-^-$fe)uYsyS` -zU(WTsJjOnkxMW4HI0m9 -z?16(Zp2ef=*EekvwjT#Fc_XW0JM=~l-T=3?N_T=T*Uxo8)0=Az=GP-Gb -zI(#~)&M~ymwkPq8$QaO^(OEmW7d{=UY_|n$(<4Qlw30mg*9Ep0BSn|Dg@;szhE(`ZHHxB+%|#hnQLeqAUet7o -z)!Y)VUYvB+);qKUo4rL;FKw+}8|+{1U(zTVu4rz!R?Es3`c9WV)mL+W!dpAaQ#;ze -zx4`CZ5ycBzi&q9?6~g8T*g8iVdTLsZ(9gK^JA5^n39pvx(Z<*xtP?f2#%lV;)Ph54qCT7``dNGeP7JoA>My^(pgpKs49$J8_DXU -zti+agBHYaOvH -z*u6qTCj_EBBic3Ez+9pK(WUqHHQki(Zpra%$+u4{h&~z7x@%j;*!$LrrW;~Sz2d=D -zNvEyOVJnPgMYMr!;aTOOS(W~$8ih8XS?jEQktcMIOaIQ-ba{NvvZQluonvibw0Db` -zv!Zp*lHk@V5$zg?J{mdSMGNH%eYi_M>}wjB@P@{CULIv1To}EzMI=_WCKd!wREp^E -zK=g&k`Sxw$xs{>075=Y$O+6CcwmeT;uKn`<8-?wSPE++!zRaiFpA%gcw02n$Oy=6( -zgoCF8wkskT2j*Y!F3#~R&bLn}u>CTU(Op|S#@-XoM+a;-MKX@gzu?Ww_T=T+>kDix -zoxTwn?VB@tYbT4xC!PE29nTclK8InC=8VDG&74NPv7 -zFeyb$UbV!e6ft>~W0FspOh!y#NSKr&Ca)4EJekazjF{w0m{2l#l`!GSWcp- -zia92`5tA}XCc8N%I|-9wj>&Gs1fFRolieH>xKd%FFiABgkW8i;nA|O4Ldm4m5)(=$ -zr5ux~gvnII1crnOC6iLZL`o)85tFGBCX`G{2@@%qOjVdDOj3`@QNU!Dfr+#;fddm0 -z%VcttFp-kUEX3p+!ekc5b=<)w$b2FJN=9u&$OeP>EFhoqAqGYldF@Yf^lL?4PAC3t;(@Z9d5fd0v -zGMS(-QJAD2lO2G`^h=l=mUbp^U|{l;Wir`;n7}zDlj(@b2Et@I$7Ba$GLDkT4vxtN -z!elzfWCvmb&oq@2_=&fj>#_wlPQP^3<(oT -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 -zN@n^mc&CiKqpeZI`!*AKzRQHZ4-r -zzAao_87i*u#~MXZ=jNimT0^eT6E3}zujcxA@uH-2b-iP3f$e84qIgMb@tWYca$$Qk -zV9Sg&^w(;$g?`ATKkut~FyYlkd9=~?Ed{n|Eh4_4HNGMktPr*r0=6EJhTd)AITfKf -zRsM&3HFqYw=W{*h$JpD~3HOg;?yKYdS0$afb&lM^=v|Sl>)OKk<)Qpae_^A@>ffBz -zNn4#~|6@V)*O9EtwXvgx{;*4b-{R!7x$lpUo1b)M);nqnqQ#NgPHo{&D?^`F -z_|G?r+RK}3dulUt?3?O^yKBsy8ILVVI?vWS9w>-D)*@nyTVtz(t>ykuqp0oCTsv4B -zI7;XXU3#vs>8^x#V76yqp8ef|=rb*1#QfF~%Y%(YDpnr@6I7A2kA -z>K)F4sI5gLmb50;1m~8E=;MLtosshcw6<)ahh4hYm-)s|&WSGfee{=%E3}SVrzM@) -zb&l*p+g*{2m$qK;E*|AsJlbCIO{uWC0=8=-8GW?Hx%S@|+B!rsp4ocAo0sFs%eNQ8 -z`OgEkdmdcnJ6v}Z?-eRrX)?8R?HNuTDD?%IxR(~{19b&h_8wp$`4 -zFK)fyos#XDl4t)6p80&h);&`4+|~=;uX8+K=i6T_uzd+v_Gm5{tYwT6`U01pICBwvLgao^9bF6`>(j{vnN` -zD5JTkn^rW&o>eDmZi&_OiC3>qI<-27R%m;$MO3eCEuI(bU+K?p6b;ulH+0al@`OIs -zrGMkA>6q}=j`q~%*!LFN2DFIcm951~gRv@M>m0C+i8NfPY579G!=?LuH3Je}ZH(vq -zDEou;qNZ=GW_UclFqo(mwvhpwHR_FD63q1#>h7e057cx+|T -z`CXmkyTa(@En>v7))9+>-K#{jXCPV_(XP@4juCoqm%iTDbWOs$CEv3p+di!@dVfS4 -zq}fN=`__x5Ua_WO@!*1_(^l_@7DTm(*1jz~t1>jJ!hg0=oFDuz#$>qA=bbY!xgcS( -z2{AcgiOD9!?)VX_G^IYF3g;+V`vOfE>6Y(h*<5GI>ACbJbL3X{}h -z((at-a^#Imm^j9BOy(mdeKuNQG9NL4bHwDA;}MgNh{;pqIVSTFlfD}flldHzj);kK -zJjY}{Vgk=JF`3UXfh!dz3X>EklmEC!=<~W7m@MX)^rd7{VTB2to5`etV*)oZFmbpL -z6Br^UeJGh!ASN)xWb&j7FMOJSlgNj)Yv04DDlm`vuFyh@l@ -zCX-hQ6P`?dIT4Juh8eM -zG%z_SVM57dza=J=O!jk3;3g&}GY}IP5+;;P_7f&NnLIfIF*zw=Ldj%5VZxJ%eTKqB -zVUl`GdI2WCF)*3PF^_UC;Og=O)naVLKB}^=nNhx6>C6lR$ -z$rQq5D#xUhFrj2p$}yQjm`vrEloBSCOiDQ>aHYaTVUlW0U}y4yfyvhrCX`H$T4F-U -za837k_hnShvN5GE5iCW{dh8zqy)9Fq*fWCF)zF=7JGG?U3O!it~ -z0_SEj*~>A3o0ynT&jf~u$)}V|_97-Qq+~)plUj}mJkv}jdl3^DQZi9J6NO0{Fc|@u -zoG~zwdL~;46U$_>g)otl3H3}g!bIwsY#~f2nQY;hXoQK>Guc9zP%_!VF@Y-;CJK{O -zV*)#qCIgf65+;;PLYA0NG6``^;3g&})H8u0VM56yM3_j)gnB0DB}^!pga{KUnW&zL -z!XyotbOKD?yoAY@QqN=|Vsfu#GFgb2z&R$9-%`({8)9-+>X|G=Oomf3S;#TzhM0UM -z^-LBbCh$x%nJna(z?BLUg-MDrnE^YK0R|?kIVQs?nN(R}0_SEjsp6QxO$3 -z5tDlp2>Q`#4?$z -zCro%U`7QNK#u6q{&tyGeLdj%3$7C#FBK1tx6DE{Q)^kkYN`;BSB-NO}&SaB;$!Q4_ -zN+t&_F`;B~kYfTjF)^W@2@DAnN+t&h6P`>yqn^oW2@^^t2MH6NOukS(6NO0{FzExB -zoHQ_zdL}ColS7utWF=w(=afvSXL37XBK1sGA|{6^nXKfP+)kKCJ(HD)2|UwGCM!86 -zaHYaTVUlW0U}y4_fyrKu$ze(+HCC9wxtUCAI3{ot6BFv0zz{JxM9HKEF@Yf^6Y81l -z<(R-T&16!8n81*diRzgsOwxeKy@1JS0~4udvWYOUOeUKM6DgTc&txWHBK1r*5hj#O -zHgQa55++j5WD{XR$z&791g=z=C`?j~3G7VH8kjUom{2k~W{C+UlVcncxQU4g^-N$$ -zm{2k~Mwm#+gnA~;5+;;Pju9qOGEqGfg-IGP=?<8@ZD1nxOqL=h&s!#wrHBcfQ!=5R -z$w0zH>X|G>OkSX5vXo;okT8*YCQA_$c&3?5mU2wsN`;BSB*mEg1$HJ67?^C~n7lyA -zWS12taBe1(T^tj*iHQmIOkjwZJWt7F7h(cKN+#4Z*}^e_XPU`m7h(cKN+zmjqA*DV -zCU*cP9~hWOJ(Jf76U$`sI$ep8iJdT!dM2+ECX`HG=a|5i -z3KNA%sxg6`$uR?yFCzcK8+LqBm -z|Cvkw#Mg9He8kG&nF{|oUsJn;*FM@~&#}K=FPgfRzZ -zOX}gb$9PFS{0^8esXxrQf!`kECG}s;Dfb`rHC-1Uu{L-|xrpWkqBlpher;iYdB|Vscl(+~B)ngY -z@_aGcez;CF-TSY7N&R1j3VojE!%JU0d60AS?M8e_{aPz-;M~kEYdJS?6O)@sSZjnK -za?`pIUsAsoxq%^Nmq}P_e2{Yk&or~kTI2?XlwBsNTI0X6*4Q-i{|-zXfJxNA#LY3$ -z5tG(3D@=661kMQ)H)0YZOxzq39WnW~3^CC;CLzMa%`wpt6L_YHiOw;BD-|XRlT>Gy -zyM;dQI|GxKB}_^YlWmrmlp-eEI3{ot6O(C(2@DC7Qp98%VN%L5nTD9WEMZcLm~10V -zN;xLe6ebFj)OY0P0w!M>n9Sywgb5SNWD+J!q+~K1F=-=AW^+u!gb5{+Fvp~gFqzFU -z2@@uiOu`%!xKd%FFi9~c*WD%bd7TYR+H*{LU^0o%v%&<$3o@peL=6Q$-3^AEJI9_3*FiAZo+2=%;U)Np2fPvu7n9DllUu^m|!yb`W21|+{DCWGGYQl!UU5^%PWKl -zPbT+IMoe-gOfZ==ze1SsWb)u-g^9u>^_WZmOnz%%GJ|8Xk1(-HCV$^YnDAtB-wed$ -zZNg**$7CO2g306$`#2_V6DBh_Ci@5zOeW{{aZKP!g^9u>)tJD}WQ>8yjU1D;luVXc -zVFKr7GFiqkft#3^Ohimzh?uOQWU>q~fgvT6iHOOK920n^nM{@;CNQLAGErfoFiAZo -zg@8%Kz@(UC;zLZ1O@aZIWRlVXmE4>5sfn#sh+ -zF@Y-;CJK{OV*)#qcMVJ?NtjSF*=UIgC6kRD6S#?q$yCGyhJ*|Or&HoRbiqqNj)ad04ARsn9Sms93f0BlgSanL`o*J5R*R=CbKvuM+g&2CPz3X -ze#h7e{oyn~RCcQZ(k5e*PWQ7Two5^Gm#{_O-Vln|S -zfgxh@7$uWMhzSfSnM^=TdUH(RnPxIsgqXmPlF0;xiNYlHm^=)ad~9Gconx{cF?q}~ -znQTW);GB}lbi`ymVKSX#vK=vboRZ0Qj>&q$WID%WJ7NOQG?U48jtN|;Fj1JK8WY%= -z>@qOcS{L`o)85R;!tm{2l#jWCgt$rOc& -z!X)*WOb1M21}3~`axp-dSSFJIVIn0H>Y02(nDCxSV}LNBWD?+*d_tJ;p2>v(VM56y -zz%hX<6($OkRAT}=lW7JfcXLcWqGYnl3KKXtlgTQM3EafQgnA}0L`=?5GFgR~z>ty& -z^-S*On7}j5WU>k|fgvRm)iY6;qydvB0h3P+OnA@a;vU50jAb&}gP6cMB@^nI93)J5 -z&!lk=V)79slRX@hgMBWGB9~g!i18^W=l*c -znQZ2mz)eg{sAmF0!i18^X2L{DCe$-|PQrwe$!5YtN+zmjqA*DVCNBaeUmBS3p2@}I -zgo$M`IZl{J$%J|)=Li$tGif|dm{2k~&M`ShnDCy-h2w+?C6nVE6Sz`gqA*D@CjSLH -zlfDKfT{$LqQZiX!g$bOS$z%b?1a4wra)Np$Fhor5pk%TDF@Yf_lcUr#>B=#IXPU`m -z0b&9}OeP`KGf|kN0h2tyr2Y~nC#0T9C1P@iWiqKmOyC@o$r0+AtVB$XNj;NF#NX}p`Ch$x%nN)I2;7Wyw!X(w0z|Q1#1CvK3OemSGv&4jw$vTb++{DC$ -zdL}R=OemSGBTRTQIZ8c~Ma)2=5 -z$>a$2Ogty&^-KnEOyHSjGFgI{z>t!O>X|4^(tycWz~mDH6RBsi6ET@(nM`&fCU8#4gnA~M -z2otGivJ)|xP03^@$7B;>BK1smA|~)mGnwq8t1<@BH+U0HGJ1RqWRQNw=6k5k-Ekm>C+N1TNsZ*@!mUwV+(s{Vv@j^k=-Xela -zTZ3zZgUbC&8^!r6n$KUWJ(w-@T`ql^uj&4TH#Eu<8g17LqV5(kXJPA{mBBA7MAQ?A -zc8;9yslA*d^p9NnoxY~bg!koK&&y-%BkM%dt+A%Q@x(+GRjjj+Pv{o+(R#*A^H;SU(%|%_chJ2xqaOpu`&7g$0VT>nhl)YP_ -z?Zy^SysEW$L9nb+*zOM4o{KcJYYUI742`Ssf9k90mhjf*d1`a*&Gn+DeXQojczjWC -zM3u1h4cKgvhHh=)U{z>NxqoY;Xz1G9FhDz>ZGX95G>r_{Mn)P2w}m^EhdNdIvl~U$ -zwar-_v~GF!x9f!azL>j1y#Ml~v#QQfRT#ZClGR6BoooMNVYEYwC|lNAwkUW@m55#w -zi2gj1)lC~aM(F)qda2LdC*eJv?>U`qf39A*2gTeE#mCJH_Nf%n8v@aZk=hPz;SH6c -z4Hf>c8%1rq=GtD`-W+>Py>NGnxo?k;Tbgt>)jI|hMDruHSGI-ktqL6~_wQ{KwcVO) -z2Wriugucb4+kNig@z}zo(^K#Gt{^(MMU0r&I$~L{dxeNj2t<2Ev}?41xkCS=OYiM# -zx+&q^lH=KuZ=Y5WeKMkT*S3tY_pK96H^iEH#e=JoPFtPBRv68SXan2Av&uuWD*aD2 -z3T;5M)>-=^Pv{<({++Ms^7x!(N$1)+$J)YZ?-ns4A*EBHU4UO@<=nIka?c2h0D?@WD{9pN+dL+DU -zd7idh`{lDX3ELZIr|P48ng28MoanNkwabd&f(rld4xbj89b%a`#k*){FNSlfLT{D( -z_xUofi+5QYyrJB`49bQ=Wxg}>oLI5Eb;aV~#INoZ`h70_ -zh%fU?7_M!7WL~gWrGGSBIW(4eW&DvjXD^1=RfN`6`LBWD&9Tgk_#>->AAf$Y&;u_0 -zSH8@)ndii*d9A0G1&3AmKZGCZ8q3U#pL+i6#qfcu(6itNC$!$dcfSDq*`aV0$=H)TJ%_NLA=mx&MH#=DPTh -zwZS3f{uPa)=*s4zep*qs(5qc~v9D%Cyn24pnN{zoEwIgO5!DM@t5*i&6~gv%z}7y} -zaJ80|BlLG%`Ypbi+Y;WaTu;^*`|Wk2=H^&UM!a}+Fjg*XPX%lbL>dOQg-4W!MpXJA -z^VQs)@M_r}EzkZ%ov3*rR?|5iU!HV^>Kvg$+u%q;-?nfv*KnPgxxlw -zgh`gdL?x5dCzGv!$ut9#yE!HwAtv8iV)7AU0_TLu-H6G9gvs3;laCM+xYESrBaX>~ -zgvs3;laCM+xYESrBaX>~3KNA%8Zd!m@|}Un%N&z$36rm^FoAOuldm`?FB2xi5fd09 -zCUB*R$ybO83<;Crh{?+w6Zjz$ldljH7!oGK6($Ok)MGOLg16&K<1b+{@-Bu+@(skK -zhZQFO`vzhH=ZMKq?m|r3BPI{t#V~1k12KUs4NU(22FIj5Vgmn6_^-JxzJZv)l?Emk -z-r$(DSC}YFQjf_XNG3}SOmaCUJrI-gbyk?bxq-<)>NqC3h{?!%5EB?8CUB*JNumxh -zfgxh@lY0=8T#gC+kby~S9by7Q#N?rS6ebFj)MN50U^3ajgzrp}?;$2@EiriyF@bZ! -zgmxx35+;0S(()c+0#}-tyvH%Qkuc#qlZ)>mCUB*R$$K1=8xd!FlSv$t -zwS>uUtuTRe6O-R^OePT~v@?MrVggs1nEVzofgxc+JCjKq6Zjz$liwmHFeFUW&O~97 -z227R%CKC-z_|7Ex8^q*sOH6))n7}zjH6O#yH -z0z<-tb|ydLn7|L2m_!g07!oFGXQD7k116<_$y5UqzB5UFh?sn2iOGkE37iuqv@^Mz -zFyT9smJbmVxYESrLypPagbCl7T>KC*fh$c+KIE9(tuRrTqyZC1CVw(8d5&Z95n=MV -z6((?QV)8l1~>V*)>9V)8L!0z<^)gxZ-XOwxc!31DLMOv2L6

6}TViqwF@bZ!gmxyG -zgo(5>IfaCShr3 -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 -zcZXE(>k-#E#6Rl -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 -zzCc|IU-qx1!-!7Vdr -zFWh{o(!!V7S>a0*hc8#;3|}g6__8nS<_pxd@Z})6`7)jkU+T%t7pUvui;oUppst56 -zK017Xx*onjT?=2Tvcear8{vx)zVuJ{@;rnuw`k$Zm2~(rn}jb=|4I0AfZTk6zk$P- -zz2xQ#)b;S?1v-3zx*oo~fWw!HtndZuTKH0(6~4TH!U#Kcj1FI*u7@wj=7pUvuOA8KP -zd|Ba33l3lWBz##+hcB>S4_}~;!xz}Ehc8gq!j}VCH(#J`gfB+;(m&yg55kwI7QV#k -z@THoBFHrw!_|k^M7x)__d}+hsi=TuqwRHFb`}Odp7Kbl;vu?gXT?=0hW!-#%x)#3d -zCpTZBbokO>+RR}M<~zsUy7saG1BR^s_Pxy;;s3ex -zKcVm9vuazO{ih!>1A|PdTr)f!&i9Al`^$V_YPZ`|?P@Gx=R{FpQY`E9{_5dv8M`TJ -zYqT&MI?&-Asou|E2x=VF3{KWebGN&>)YV+cCL<`YJl6Xa45`?Qn2kYZiri{Shb3=F@(VNL -zsC8npcNhk{HG%>+!~(Na^-#t>IAR-YRW9p51qV{SANLm?h$Hiiq`~ -z!8-?ayH{7ZR+q6aMv*f=*86o#=`BA}Mg^7IWb?>$_#uDjyhk_^N9M7~-mm?!BcsSU -zKIUAYuGx{X|14_z!lL}51FhMf>iq_W&>Bb0LzB&uxwp%a*y#}AA5xYF -zdp{-1Ew4agwL|=rPmJhxFRyehFK54uqC{S-_tTh?&5xAnLFInAb4)sX&L4s=FY}3s -z-R`YbuC1l4J&F?3V~J&I_x6l^Wz+^=l9fA$rNbFtDB~3dENDSRYj4v|Hg8>^zPzmM}e`kgwo`mtr`AeT(Zg@Cz>5DN? -z#9#Jb*Mu&`GH+d=zJLLnba)=lT>3O76!9R8^-V}|JH&tEi&l2KO(iZ<1zQ(Ef%&oC -zuf<69Uc@{RWJbs}6Vl;T-cZ(OWQF`Vsu`cG8Nt<5A#tulgs+sVhYx1#=7`N~W#)CD -z!wsp!J0;bJnB~FVuP$@u3M5uJ#N&KmM7P^q=`xqIEm0K6i}ij*R$Ajn%=930zuY<| -z9gg`!@R4#pFtOXsRk^rQmW`so^jKh-s&3ENmq%^z(Pg=HSUTM83w3*iOdOd9B+cWv -z(Pc>d$RWZWi{#E3 -z>9EZcg83JG!rbi+mAXQe><m|iI^{qcQo0V6r(ECa|t!vYE!@J%Y(=7!xRB -zOuiwQY{r;Ckzn!~#^gO36WF9uF358kiU-lfFNh -zJOP;eT*E}5G5Jq|i8B`_u&!g`q%jdNCVwF(6DVR#{*z$h#F#)4WAbNmG7)G@V3UrC -z6Jr8JjLBb&lZk;zKVb4DV6v$9Wb&7+lgUPm$ul`I*@!WLb%F^wnY=+T$vT;A#F#uo -zFxg0B@&>^q>twPKV*;HzCL3u?-Y_sRFzI_t{sEZ$n}*2;G$#Kdm^_vX6Ij8J!JtiXnlQInxFOA7AjL9lTE=*uu!{k;6jfodyGLf82polTq -zg)v#}z?eW0V={r9OuRHEut~$@XAX=B6fq_fjgyIiNk3rn8DOGiCKKtC$sG@3Oe%6> -z@*u_p)(Ix$Wb!=0gg%+9dJtn$K`?oc#^iZ|34JoT{XvWgbn2KqNMrK6fr)`h-(#{5 -zFj=Qz@&_7|PY5QDa!q0!4B%S%)#Xl3=oq -z#$+GH1b!1anXJQ@K&Ot$IvSIG1||k3eUHhlfXSU2CcmRG`FDcJrd*i7x{k>v8k65) -zOkN}>6DVR#{+(d531b39jL8e+Wb!*26WF9vFMq#rOj37BY^$%|Ph -zlZP-S59Y+=A&d#E6HLg-fk{7L^6|y+ptrQlrTFiD2>ojY%EG1b!1anLL0ofleKh2WU*{3``76`W};O0h3i4CU4T1yhJd`dCvsa -zbxgAEnY@WHxr>}kpolSfiC{wRnLrU^awj>Nyh&pMn{-UbJrgKmOztvHCI%+`fXNBK -zM9WO>$~u{ldnR}1#Dv^4fpvljIhiyPOtMZUtdj}3X9Ar%CRz7P -z8VyVgO!^*^-vK6@G)$UlOk{#d&U+@Xu49sQ&!m}PLQW=7#F)qg6LQZ4iUbpKGHIqU -zflWFl2`0wL#K5E6&t!26&!jddCgh$8tP@Pg$>eo{N!H1P+%u^qm}K2Ed7WUAbuuCMOrTT8BjowU -zCVh{|-vE;>8YUqclMaGO&U+@Xu49sQ&m=@JAtw_kVoW*+Cgh$86bUBeWD=q=flWFl -z2`0wL#K5E6nmvCQu}p7$*}0lYYSD7+|7hChumQOvpWx>vCd3?wP{c_0A -zK?6$WpZSK2ROp?p(9@79RepW-qf357^?OqFholJ}Vb__HsAznwXo0%wg_euq7kr@? -zyux3hm=`OWqpqrx?%cQtiHjX#kS}7F{D@W^N}bpyE%XVu!KOvAqLJ!}rk0E0cf6r@ -z{K5<q3+BlX5d>ihO1^}lQbZkD>zd!#`dmLl;(hjpls@(ekMl)0tM$-$g)el4SNIIp^J7JG)%x9%Z{t!V -zPIZW{@J07L^&_fpNY(F@{`}BVBtGL1|HT&#R9C&yb}>A`8=Bx3u7u8OV@1={Rd2Li -z4BzPq-RTqV=8L$eenhKwrdI8jzJlM>;SfjhMYGitFST6^FZ74r@d&?%&grqDW$KCN -z+b)KG;S2r3E1czv?s)1)bYj2pk$Pj|N#9O9x#=V-T07=l#myI4#{7u#52W&UNIQJO -zT3EO-Ry0J-fA#3aaG5t$<`?GkMc1kMd!!f;r>B33j(t^f7Wi(#K9DunkuQ1_iWn2<)G;}VF@Yk+~aJ!xn9HMdKwd0&@uTU7bdW- -zWAX)!$@K)2g%}ekVoab@$K(r)2^0w?3o$0w)0n^}9g{CGCQu}pEHp4NFzI_tz6DH{ -zXqYUaG5Ho_awI1v-(pN)onW#AWAZ4$WC@MQw-^)X)G_&%#^h0g$r2iqZ!sp&sblgj -zjme`1CI%*bkIA!u$xIECnKUM_pkwlBE=*uu$K+EQlbHmQ1sD@3Voab@$K+Ft2^0w? -z3os@#X-r^~j>)GO6DSf)78sZqnDjj+3SeT^Ffr4ZC>WDxb7G=kOkka0V#b)*2qtD4 -z69r=eojN88jfst5Vx}=sFecEcW1`TQ*bGbzO!^*^3xLTA4U-i#Ca|Dm@?|beU|q-L -zOB$0E1d~M=6DVR#pi{@>ONmYIB? -zm6?2pF}aWvlkYGluud=`naOhmldR0-JB$f*>X>{-WAYrqBr7xd4r2nHIws%Im^^1- -zVqntunB)N_12s$r(wM-4hRJ;&=E4NlHB5f~A&tpEjERY4CQ!tfK&OVuogZRMpolS< -zLNb$qG$yb~!(`2e7!xRBOePtbiGfMqV`7P13=f*DWhN#%Gr1>%G0Dq?2{h^fJgj3( -zrjX2}6k{@(&P?u&U`(J>!^9S$F)78Ez;D8t$=wl*33O_hSR*thr3NMjCVh`d9bj^~ -zhRNkLCa|Dm@>woSU|q-LGa8f22__^nfg;8PI(1Aw!ncVXY#-uJMCf{I8V4Yw>GLr`gCUj86|=+rU!hQ{Op -zf(f0O-2Dy41Uhw0zM(OBz`(@7r0+4Q1Wd+jn2e_}fdw6tPjX=b>pCW%(3p%Tn2^i_ -ziWn2<)G_%4V**8j3CT>x)0n^}9g|NmCQu}p7@3KINk3pB114H#VxlvXdt{7BWll_F -zj0vn0Oh{&8C795e$-Oeh1Uhw0WEvAI!Gz9C?v^no(5Yi0)0kKdObkr=9+P8$$pQ_N -z1vDnGpks0}7bdW-V{($lWC6j1WF}C=m_VnF$w`a}6bU9IGg&}m0-JP9PGU@;NH8%n -z69bcez~n4oqGcu~Iy1TFEXL$mPE5{XOkka0LNb#l2qtu9a_?D;33Te1oTV{&f?z^t -zCU>93m_VnF$ypkcCk#vsO!^*^Ie^Is4U-WxCa|Dm@^LOqU|q-LV;YkY7?VblnLrU^ -z0-ZW0A7f0Qh%xyU$xKGjn7}3-laDbbP{f$LWMn1=CjEfPR~N&BUe+>`#;nZbD~!pU -zoS1xtF@bfA$*)Leax2E<<*dx)D~t(r>X>{*V{$9T1b!3AOuoXHK&Ot$S2QNK8kiWE -z^gSkT0w&jLm|RO^0t-4OCvsr|>pCVUXiTmpn2^i_iWn2<)G;}MF@Yk%gk&by(wM*| -z9g`Cn6DSf)jLgKqq#rPe0VY~z(wLQ*#4sjr=ENk1F@bf03CTX^i6Odd8cF)-+*{n83P@$#EK!X#^9J -znLrU^0-ZW0$1x^QB$$xQWEzbLY|=3~jxm8E!NkZ+3{3g~lhc5SmYFnWWhSRFCL3~M -zavEa->jV>$ncPP($;wPlV@#k^$K*7P$$bQqtjy#z#soTbOit67+-G27VAA)Pd=Hr1 -zq+xOsjR`F1n4HRm39RdwoT4$giC{u96DVR#pi{@>6vhOK1QU{(+(csnn{-T0VN9S% -zFflR{1CxHhBa8_YF(wSjO!8<@1=L@_4NsbdnQF{#9uz;7a%NfcuOojN8_8k0%`69bdJ$D|Q3 -znWJGchsFdJbWA?ag$bZ>X@9NG1)*c -z$;wR5U`(J>$K(u+$p!-x1CzeTqy{iCX_%O3OkhFB$XEU_vqzC}K>Y -zQ^({O#srE46Ox&jXiQ*}j>$2M2^0w?MrLAQ(g&C%+z%x$A2DjkfNg6Z`8I2=!rP-$ -z)6+YJo5rf$4N}H~6njuvDVsb^7uxi9M+khopQDVoHO|<#Nr`bhzFVs`m-&_`r?b?#2>VV+H$W1O*ny0;ANq -z`=t|J;h%h9ka~D;#@-mQHCh={2RdAzI=ovt>=z2+sAgiaW+c~Ig~VcqDDi=r-R{ZIM^E$O)k96EGjNqMDbh}rVxmH)PcSVqMZp>Mr -zHXW26@*w55pmLpTo}Lb$_k_;-glFT(JS*8efSXsr?vEhnf|zrJx~4v3{~}`h!m8wV -zpf&qaYwDzX{DL`-nkOfl$8c{~BXP7tY~Y;})!2cI{r-sUeyg&i1H}%eV%w#sd`P)I -zs5~k+595-RNZjfW(|lq;x4W>yRanOEiK4{tSmGMBc(-)WkCYKX!hfaBf -zclpE&wfK;9y+_y|N8E@cH;rRUkr;4@PCikrO4~E`rBU1a7G-k>l6Iz~{ZhLZDO-ce -zV7YS~x4aCApE|^=`NXx|?&amK<<;yB5tNt{OPJIx4bnLeQtl5b%jC|P>F^3qXoXL> -zgHJ5#c5f|pZLMU#i=f1^SYnvky)R=AM{LL|e8(rocDvJ+u5>v&@bGJh`A~gGEa8hD -z=YB-_J5u@e(hjfiU#%^uXh^K+N;SWx?P9phANtrM{0Cn&L(M-VUEvY-!uo_*(L%NU -z&bEtTpD*O|3UR)uiu)1O?@QI!N$Z%UNW9S@{wH5#gW{pos%_E)pHKmv3t~kh)KzQR -zE{0$5hF!R%B9FHAr9Gy%dQ-hgi!OZRLJMC$^HdVMxWo%s(1%}50*Qj%MOZ9%l -zj0iHf$~F1v@G5`kghzOX56n>K9+KvIg!(wD8Ii1+#?_P}@vuYO#0QGi!`m}UXbd?V& -zR|b^_WpiFS{FX2DmRI;2?;P6gZmDp!l(Fwdk#kJUdA-`SCu9FHY8z=$%H-zZ>F{KK -z=w*-aW*jw-N;c2n-Y!96qeHCWoo02-&Wzm|wIwXdmJSr#mWu6_mUxAhIBL#IHk-K3 -z`c;vf0M%x-sEwQG3^JJzbq?m$}(q_*sk-tZx1QBZkO?i`d3+k7FLS5WxG=x%qY -z(iJLae~6;Q;8HWFDA-- -z8WR}cpkZRpiOErn39MsG7l8`8pRSu&!hBHI2z?jES-sV**8t33Te1e2p=I -zBF02sj4@eFV*;CWOuojLKoMhdda;3tfl1$E@-kquLBnJrjR_2J&@gGviOClj6Idsh -zEX0`1BbY3tG5G>x0-ZW0U(lG$BbY3tF@XUN8Ya-GWAX)!$vguS1CxHh1WqO~4U^3@ -zCd~wsZ*yS+>pCXi(wJ-}m@L7VKoMgCojNApVoab&Fj;~z*-T>sn{-UR#h5^mV6w!( -z#K5HQF*yjBtk*DEKw|;}95hV0oS1xyF@bf0$pVZ?A;Dw;jmf7N6X?`2`IN?_kYKWa -z#smg9XqZ5!j>)GqCWQtj1}1%vi3%qZNyCJtG2sX%N-j)bUB^VBF<}WNW{e3GF(%Nd -zW1?V8phz$=V@y~Y6WF98J!Jtl7eCL1+OvN97G;GkjBnG=&QF($B1 -zFd>=Aa)L=#X7VM*1Uhw0zN9f(PB6*JOkjY6h6!})n0!fNvfRMLz@#5Afs;wMhRIeM -zlTL!kceyZubsdxMXiT;eOh{$|MT`k_>X>|oF@Yk%gk&aLX-r^~j>&fz6DSf)jLgKq -zq#rQZe!-ph$l6{^meQHYIT+xeVKO=wCf|IBF@bfA$zqb3491w4>C8m_5Mu(J8Ya;X -zX-o!VOyD<-x)i{lg#iv4CeW#2a^^!Clfeci1}1%vNdcTpc59fF)0m9Ln6yT6VFK$K -zCSOHpOv*7POG#z|MT`k_YM8_#7!xRBOcs;Oq@2bCHfflgj$llnh%s4WWF`hC{ea2y -zfXRazCUjjV>$ -znM@>@(3y$+3C09Ebxb~?F_}m(p)-@SFu*~>1Uhw0KA|z0XkcPs()XA&!O7$;4U@ZQ -zOjZ+2 -z$Cw03W-=0E(wvo8J!Jtk}5 -zWb(3x$zI5+WAZbM$@?TTfg;8PI(1CG!k9o2V-h5p$jV>$nG_LBvNDqs7!&B! -zF*!kFQbaJx%1mH@gN6xo>X@9MF)1=IF)--|OyFd4TEoOiWAZk^B$f*kSl2O$(U>?1 -zCL}X~BE|$dbxdLy6DSf)NM_=sF@a4wCNYc&6bU9qW@2E{512FnCfYrd_p>q+7~r5` -zvNV*;HzCdX+^rV~uEG7}i!pkV@?Iwr?yOr{%{7?|`u -zCNVgfyr*GuKaI&|g30Mzn83P@$!Qvs`w1o_Gl3$;1Uhw0PGd}$P16BogR -zWF}C=m_VnF$vKP(6bU9IGjY+Fz$P7&a~KmS5=@ND#K5E8#8I1~_P#yq*)2&oL&jPB0;v$<+jt -ztjy$dj0tq=n0!uSay7vuD>H!s4jLxVsblgvjmgypCI%+`fC-#TPHC8Iq%nD&U~(oG -zCa|t!a)!oaBf*4ZCQ!tfK&Ot$8H@=O2__^n*+^pon{-UhU`(J$FflR{1CxHhWIte{ -z-7|SQD>H!s4jLwGPE3wrOkka0LNb#n1e2`HTI(1Br(U?pjm}F%pFu*~>1Uhw0 -zj?tJ*F);bRgvo{9+~>Mw(BOdsE}NP)QQ^!t?XyA3`=N;KkX4!3fwt7Aw(OSP@FQhpQ2CkMna_o) -zkhs(#zRxELyWOE`*VYntmQ}gB19cxrb?=Zq@F8VsPkawd)~XO$>Q42>nOQl+|#{r#xzX^X;kAZbrZIwZ~X2z%nFb9l0ID!058 -ziNAG-8~Mad-R@9{D^$UX7RA|tw(Lx8*)N^*BE=O{hRL1dxvgbL{L&%bz$c2j-CN6D -zTdUcX5tO((mYDLtK2rZ0aHHKsc{(dqArnv9a&ki^p1?ZchNLP>2{&1(3YmBUojNyJ -z6Hk^BZn9DpGVugDb#AgIo-8%E`9H)>de8q~FoCm6yN1crG$w5XlbjPzU|q)~YvRe% -z1QU{~KoMgCojN9D;t3Q9CL~pPn#Ke+>6nm-Cr~7q7^#YZNk3q+2QblYqI6}YDrDlx -z@|>8Ei6^j*G3g+w%2lP869bdJ -zKbdTSlgS$zCU?-7EGL-coOlB3Iwn~YPwv2&bdgjAiWn2<)G;9wPoRh~=^&}f9W*Ae -zNymgtJb@y{BxR&31}6Q0$*%wt?IucBR;ofKo`iB@LMEQTI>CgbDmM^JvQiZ?@dP?` -zOtL1P+(0nNN>#|j6X?`2$(nd_gMo>GNk3o$CzEp;CXdmWga{@%C!WB%j!D+Ulg9`q -zBvpYT#soTbOvuC&C=yIas`40(32f3aArnuaNH8%{6$6ugz~m5MqTNL4%1Twp#FMQ# -zF(DIAV4Yw>Qk7W*ldM#QOgw>39h0nyC$k79S*Z${cmka|CRr0tW*L|mnDjj+-EcDb -zK*PjNW3rWCl5^q-tm~L$O+2v^Oh{$|MT`k_>X?v;Cr~7qkj%tRV*;CWOvuC&C=yJJ -z%*4Q?A29h1V4~eb>B`DX$i$O$PE5$e6Idshkj!Ky!6Yj)ArnuaQ^zE0;>k*aNmgb; -zCZ0g2j!D+Ula&T01}6Q037kwa8YXTUlQh93=fo3O*D=YOc;Y6Qkjw;%7!&B!F(DIA -zphz$wnTeam1UBiIkclTyB$ybPiGfMqW3qPJ1$W*I?Iy}tIx|^8CY}t=g~^R%;t8x{ -zOh)0%BsBnIGMdgz7L$o5(5YdvfS!2LG5})&zX@k1Hih5n}?K8YabL;t3QnCZlj> -zk}jb!flV4FOUT3%C}K>;7@3KINk3rnOTa|Ci87YXOjeMICp&XuLMEQTI>7{ICaKE^ -zCUj=9m`pr@P8}0^;z`S81QR+lxtUBnfleJ0dg93sml>ECnDhfCa5DKw!(=Uu$xebv -z&WR_mu46(^JUPCWV1hG~b5O*XK&OrgnRo(4f(gz{(ralGg(X~or#F#**jtQA~0!4xe&P>ve)0n^}9TPI~1d0R` -zBQr5D=?6@90Vdi#lS5gV37L2@J0~V&;t8x{Ob(FDWH`p8AuBT>6HlO1$Aq4E(lQ)l -z0>6o5CS>9Xbn2MU6Hk5^ZeU_y()XBD!O7%#4U=1FOlA{Ia!x#fbsZCW;>qz_FeZmc -zW&%Zw33Te1kclTy#F!i)naM3QCa_7zgiJhvBF5yPk(n5n^aCa@0Vdi#lS5gV37L4} -z&xr|{cmnGL6Ox%+Lomt8OvuC&=+rTxC!VxiLomt8OvuC&=+rTxC!YLpje&`QNk3o$ -zCzGg#iG#+(PcX?j@dVa&Oz4Rx#~lO{l9@meV*;HzCS>9X6bU9IGjY(Ez$P6NGVuh8 -z1QR1OF)--|Ob!4h+C7s)S(yo$c(OhxCS>9XtP@N~W-^svl9ic|i6_vhV?s|nX_-ne -z$;wQ~#1rV$F*#0sz3Ydm1||k3eUHg;IGOxG!{lBXll26XoD)xAUB`r;cyjz+f(gk? -zpolSnP8}06@dSzl6Ox(SOJf3?bWF&^6DSf)jLgKqq#rQ(HDIFMGdYx%nUIMmf60jn -znRo*01QU{(+(;O*$rI;t3Q9 -zCPrprVA2nm?6~00`?Yq@S -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 -zX^7X)5 -z?IXDEQX-OoDN)JTyGY)Sc-}r~xRc2Dd*$&VGHzDm9+#7*beLL%!YLGTLiM-J(=ZCn-34f>4*Xb5U@X?vQ_NB$PrDg1$0TR6?9G$9cJ(x6K -z7cgB{B^yHBc?tjL4&Uc4;n4``o*wHS%xzoFJ{us>h2iLErMEF@{vu%dqDmguMS2_J -zy>-%dw{UBObWe_TkK?lb_F&RHc=1!dAx`17r%n;W$gtsRCA(hQwRsT{$6Lf-@rKa4 -zb0oVdp1oUo!zKKjH{7B$?vSq7w1|j5vWV~Th7;?~k;cY&W4+{Z3sYc|*D*fURQ-J3Lb2TeJZ -zOi8GHWWt~4_O&>K=OUziOsxGfuC0)Whb`hgyvL~2>`t0D22HU_#@0oY9dTu!w8SZ# -zj*#}OSbHwVl@PJhB2MQ$b9(LF#kTG;c3UN5?jpV8V(sI&?s6gywun1<>-b)KPMIyI -zh%KqoG5P-hlevJ&{uCx}t1+2`n9R?F$t1*Nz8aIaDJJ(JCU2`TnS_|krAWVwCkAYok{<9CK~~hr&5@lQe(0RFk1~n!hQ%qnb#RR@n`k%S(pqRiH!GGrZSjR-i -zr2jEt0h8aRF!?}@$vng)V`efBG0|iuA5cvGf|z`u#$+C1f|&^vDJHNojmZaUOy(gb -zn3+J4Vgf65Oms~88OrVIEU}mxjG0|iu -zpHWO;C1Qe^$tJ`^lbL*`W1?fy|ClTVOb(?mc~_0ebi^cMW-=Wy(PSp?QcP@!$-8Py -zrXwbpnLv?Z0xQ#)ysO4!I%0yE2^1+Nuu{iF$E3e8u_n!fds3Z=O@j$$CZ>#-U}j=c -zV*;C`F_9@IP((~HGch41n#@F|n7~TJ1Tzy8Vxq}RWE~S7lm5qK8({Km3X>1jm@Gp~ -zGG->r5ED&i@*%~f4>9>rjma{^1TzyTQcPfF8j}yzm@Gp~Ff)N7#ROLBnCO`FHzu0_ -zlT>HYr@;g>lkFKX!OUd48WY$gjmZ}j6DT4kn3-%xOf;Fv7Zej%iI`w!vK=weWF}we -znCO`FKPE%ZlHC97xQNLwUsGc;m|~KjF*6xVF}X~gnLP9w#bgA<C6O*6cbpfW1?fy&zRh3Nty?bOLZnA)R@e`%%mt2Cetx9 -zDN1ASUX}HJQm96q7lK$s1}+Mo~(WDJIWgW^xCROs+vpGG->%ASRm3SCYYIQKuk25Ntj{+ -zD-jdSOg11Un#?4uW1?fy|ClTUOb(W-=8q(PSp?P)yb%Chw>*nTnWT -zW&%Zu39L+G@{SslsfYOhnT(jcuEr#bVq(I~1d0?BSeeG; -zbu}hg6chMP>C6O*6cbqa{|Y8VbEiV=!Suxn7q3<5nU>fs+%zuiS*FzNkn&uFxzfw5 -z3AGPP_*-1Q7N>AFLfVJK+9z;r#q5hg;>ihn<|;LNljc~^lwZk|huTLa{7c+E$sq_4 -z(w-A*&*!=eiFni^nt0D*McJJ+Zwu-#ssBIdCG~%XNtEkSy~|`ZH)c##N;7d|!c?VH -z%?)gl<|atFfgCV*9FuJs%{V -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 -z^h^~qxt6r&#@cf@uDr**G+;TCdrq+}r;IJB -zlq+kAaZJp38P`9DUTx1B0v7X}mZwO;wbka0wZ{Zy&#R0(^oN*+>6+Q!G)Msjn@dd#;6Ot)9b3u;N* -zWwEv)+>6UuPaq-Jc;&oM+oTTrizT)f%h_p_a#<~D8x?Dt%55y_G2a(7eO4(yQcK!~ -z#@Z%wv10Zw!Gt{BE1N=X<2vlIa$9~OJ0h5nXL{vTA#NC#U)p1SH(+|VN*+~9xCt>X -zn|r2=U0*5R8{)=t&y@F=CkITEtK?a=gqs@UvN*Psl>-Tx^U66PZeoYMquAC_#y%QI -z$gEdh8scVfOAC9<D&npws0P`@E;7^7tGm)>v+|KSZol*aE~ -zKVvT~ww0E#Rj>zd5iNXlMkqJ2`#5Rb8EJtu6Kt5o#7e#V~IAFnthEpP}2 -zW}Hkgv%So^Q1e&2kCPLP@e}pZ%kWii3Yc!HV&;XK`=Gu%eqz7$t+P+OU=fG#p35at -zuqR${Kx%Xdu1L}|CG5FTDcITRuWtf*Q6fpt%&_MYrRG4Vzs2EeaS7`p -zNzYATPnJ^CAgy%viJw@+MZ9OOL~8cNYYs_E9Kyj!(lasaS*R$xI{lK%Cpm@ANYXPR -z?3trnycVTTTxJnpIbk@-) -z9=C{(@z!O^${n5lNiN?cr|@#W)bVxXQg(B_g -z^v`qq1c%_^qj?gM4#uUO(k54*c%Mc5jE|0$h_pX0?Ug#+!iY#RIx`%-MA>?v(|^?A -zJL(eFN0QN-!qF^cYlCER_KC7ZT+B!3N@VNa_|`+xGKX*|l8jCaM;9u+yE^@^x_qxX -zg>NFs=!kH1j?!BvZFl#Hw^~F$Z+NYI3(5VDJJsR@&)BnyY+0r3>y^xZ4xLRJhJ_7R -zDcRk@GxoYNTU`;ms*1TWlsla(Eo3jbwWUw|kwtuuH=KYya$~tUTw=H6vft2So*yvH -zuVQ`=TPzA2#wv|{!87)^OKfkKv!g1RH=uq=*f3wI_%?XPKC9F=tAu?Y_Pf*~{)RW? -zDiw*~8T+v!+p$vi-^*J1M0?Qm?L -zO-OTzP=~#`&{n;iZ4M-uwO%GSRGrIJm-Lw1gC=7ov!a$%kB(JO_?Rl~G;app3k2w}F#j2PQq4rBU -z>|C*pD`VL}f?>SO;!t~jhrPSd*1eqdRWh4vN&ARc`(&=Wq{o~Hnub=&g|);uGG?5@ -z)9^sr^?yUfrMP_m9Gf3P3f@DEwarmWj_cc -zqIhkawIZDR@hSui1w -z^~!gI+D3D+vL3T7V6s)o%W6s6j2JhF%U|AO-WxFOt&%SZahG=3^Gj^`rg0rb -zJ?2M)rk+Z9Tc~?bhkfaC+tOn8P%t4+^vZXKy2o_bmzLXnh3s`zvZ0oA=f%2*bH36Z -z^EUz0H&yb8Q1>Mr_HD(sZDp)EkdPU#yg1aI-(gP_+7ioIf2F*+mUNGZbx-E9zI&k4 -zKVyb<0`jvLk(Bz#?AH8?IHd_eyWLg^|4B -z%Q;&}?x=1D$@C%ja?m_DZJf&a+9w@UUUF(%Aj}8T;F1wzrGehhXbpSj6vm -z!(gT2yZ6u7XBFFKm9e+M*1xle5AcTbbGDG?A+hEO+_7Tz1^D|LETWe;bj;a8x~~fx -zmMSN9NDHZA&{uz>ems}$^&PPqHTY>U{)dnQPv -z^+3FJm(=PKY9dL`lCWpE(%R7JuW|Zn+`^Jb(lamYnXa@RlJXpVV!cHy<2~~wQnM>w -z(#9Q`Bvz>k7`xfyU-ddov)OY%ybNkjggd>rpbyC>6 -zNNL&K=|Ai8oplQ5dFx<_tlSr0xksAh?h|KO#ACd5szg>EjIZ1&-QyCfBT1_iH8qJuQ>X|7cJsO-g>h{!aL*P2I&!}&=E;m$AzueDdD}H -z{mj{3jnBCXpo#@g;TA9d2PEAH7ytvR69o?h{8_ -z#Ql79f<&YPacP$%xCCn?8C?>N4p*dxPX8vSZcg}mWE>$i~HVX@pxxvUcQ -z^;@6n6USS`U-5v2u25CG*aQXOo7BVZ%b@#J8WGv9B$) -ztu0|ch5atGh)?r|$;yeur)TV671_QjWzPo^%yus`I8;5p!=77g%PnK!j=EY>JtkIt -z8P{CcW1bZ>9jjzEgsO*g&86&DmCR$cq0%CGy6WGyjHh#9lFrZRR-rTo*7aV*zV -z-eaB^FiotIuc{@+sWD>~x1yB&IFOKQz4Dllabk!4RI%+;8M`HrkbmZtZwVP^aB~ZL -z%%g**{gv|STGBQw)^;g3x1`7XLC|EVlq*7Q*&X&5%WN+evDRQhUgDLvhS~;m8<+Q( -zp9+|ss*)$wlD6DfTMoCeyvKZVz;tt!JTKHXt-~HGvc*c-zCc3W?v)3JxbYqK{9;>v -z8CzZ{SJe`3OpLpXd#13*JSS*+zEa*0;)Zk2l(Jt}%8%6&Zg7mdgky_)%)bqqm`b@i -z#N~9@*>YP)A-g!3kmq{kjUjGChrOfJ)=|RtRLMhYN%#0z_egGOS&#Y7fa%UEd0{Q- -zzAV-~g!3(D#Xv%~dgW=M?nxbXUy03E&d#Wm%WFyZs95(@Zd*~0*&H-|Q7J!KOS*@~ -zx+ijpV%8r_$TPgMIh6bN{l`i6cW?hs?no{xxw_N8%i-JQ67J^>-%Z{^a)-onCvbJW -zt2_P0Zr>XY;SapwG9~+vbcI9MXFi!=uJSSugmS;yf1ETn#vALUWDy(mKiMZvv4~Id -zhEHINX|dc9+}nxOo&GPKzAxRvFy8Qw$y-SC$XN3fZr1tLo&G0Wz9*c*zhJ*?FH;d} -z&gPE6SNX`{`^Y8KnolNVzeVig4MUX^-@SdtzP8x5wv4^^)hGMJ-&@27c|#xUH#F8f -zk^8EcJr19Li$(k^Z(kN3=$NNZiZwMkMOeWGL$ -zxAGUSKJE19xqNv};hjj*Gb-%4MyaXq^tZTuD;>gN-jgelnx=ToZYk{Q6CbgNao#gj -zQTBEEmpFY(+`_y_(qjmFrYXw7PXAViZ>vjyyH6#e?2aq@rCw*Bn6!w4dF$m8$=egp -zJ0R6N1ZN~^of5X*sO0VJ^q0AOWlkZ;TgNDQ`=xiB!ha)4>yWVZ3Z-RFr+>EF_nbp` -zfw$&Kq~&0|Wv8^x)hFI-5kKXvVTvE3pXdFxz>tlS%4c}QC15Sk)M>%_2ip%UKJ>3_xLd&MclB1!9r -zuyu|Su9F^d_lZj_qK~)EkVyDYe8~=JtgBBfv50T-(UHoM#!ml1r|+O!m>5Y$uL?&m -zRhBeKryar{`RHZJl0%*Tc@Ez^mvDO|8C?*LW-C&oBslxTs70K{M`ue!s*6iaQm3O& -z{EJ1j@zG_<)*YSx=`P=Nr|@nh866dlUZZTS@AMya`%Dhuw|q2LB3ql{TX##JyZXdO -zEn*KJ9jf&1>+~;k`j)wc>mtdhAsn5i^d9W=Z+G~%y96^IT`ZB_-SOW2(vV*od(4CV -zsT|XMD#48RGL@m+FGT&ne8n!I66zK&GbNNeiK{DN|53#Z3+4XTbDT8pi8mgQ -zT(Cz~&=jncZ{-cW%odV6G?qJ&d%L%$)4$s7`_du&8Me5^%ltCbJcyfhp{CP6!Rede -z7OsN&U0!BEsQH5DIH}kfuV|3&ata}+=Xsfxq2^A{and_E);yhCTgXoJxAciWwumQr -z!w1Y3(wrM>&f(U=SAE#wd)OuXj5qW^eMGEzGWS(UkNJGilvT+T)spIwvFa&YZV_7= -zOfd7k%tN8-AszPS<+kQxR(-i+Fu`PbnbJ`8s1AE|nXS5rt*&B>wWK;fRy~w!U*2PG -z3z*ufnEYB&JvmlAj%zPxa{>vb#LHY6YM;_!Hx}89rR=Fdg4yC_Mu#q572IQfF=*OY -z$=p{<+Q-J)r*m8(n;%RtbG*#@PT%DOFQg2CAOS$_R2s){*hO{I%Le_nu^#pRq~A?9Ef&x4l@%8mi=iTGEymYa7nJSlVNb229Z^d3dPpk`DXE -zV%x?t_P#(uzQ-#s3bo~T*kgsZ*mCwSmGY)q(l#R2Hkpf+^qBjCrV*8LQ7z#{#<(e5 -zei2(9Ovv-S@_e=@$(Vmf6@MmZ_4B -zwS>!$aYMO|);*ouR>;l>CgeF@d3~rmtHZvn)V8gJ{UVr<$9d&D -zL*1jfL|Kp79x&Ofm>rwXCJldI{72^UQ0{k69Vgkl;@OSTE~oJKFHREe1ZLF -z_yS)g9lm^{4qq;8qTvgCPC9(~i#mLPx*oph;mg2;FWVt}xiuBO%ut6f1j84o|1f-c -zlZG#_2Zk?uY50=B@CCM@;Y$+37pSMhmp9en3)Iu$%bV)(K2V1*P}jp3 -zJ$xCM@Wl_|%NMEeWwSbbv19lG^&f^W8)^6gdtmtT84X{yWB3AF(C`JePKPg>F?`vm -z4qu?24qrB^! -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 -zurp~MZ^R<6A3ZVbS9f9 -zCJ_xL*qKO(iKa8zq+_CE(*Ky$1176dn5M16xu`{VxV=@IXS*6CLo?-%@neI&L)tJCa9TOdse#T@qbS6)xFnLmq2|P%5CeLNU -z1fHimljqc!z$R%-Hc(8UNHJN1oyl_)6DVS5vVmgqq#6_W%yeh+9K{5R*qLn5G0`#U -ze@qSoCTmletW{$I57L-q>`V?LCYsJ`V@;G5INCvQ~}BVZ;PG -zlf!CEV5N?Uj!A!G0-ed4~%(dSHbOa=gxo#*XYKTge=RA}Z*;6VzLi5WYSofH#zPCJu3an58I -z#bkwM&SWRWWCC_3JJpyBqnO;TnKRi*F@euacP2a4n7~RM6CIO&#$*C?CVNtt>``L^ -z57M29GZQB8Jl&Z%)tJC0DNHJG&IF1SlZn`wI4LGjq@BqfIA^j)jR|~ax-)T7OrS_R -zliTz;6CINQz~phjBsFJJp_wy*2Wd<)b|#M_ChE@QPMkAYj+kiXOddx}urqmFjmdJv -zL^EgdIAVgG$>VBFV5N?Uj!A!G0-ecQDNNqdV1k{=OBpf2&g3OECa_5w6Pz=FB4UD_ -z$xDcdx-+>0=S<$xV1k{=ONfcOGr3KlGtn^_08APHlhm9^g=WqK9;7h&b;i!5fnoyB -zu`|IrldBLD&74UC#pDU>Od8afT!olu=1dwWCh(c*&ZI$&39QsH(J|>~OrC(wy7cyZ2&(odB3u;VYlQbqcX97iv$*-|9d4XaAMeIy)&g6G$OyD!qoyiLn -z6DVS5qR*M=m<#|WM*x%5oJoad&IBH$G0E7O96?Mpoe9pFJb;*J=1h(tCfJ!AQDgD| -zVxpNdIf9sAXL3Z139QsH(J|?7OrSIQR|=DVX)wXg8M4vO!F&O|%>Hw3}oJoad&IBH$Fu6NpXHrKof#=wn -z;GD^&h>2#-q>f^87j`CfYD_LgOf+*Qbrci$%yef`r^WX_)5^fM-RL1*%t6ehn> -zV*(G-oyoCGn85RNXL3x932c(a1m{ekNHMt^JCkD+6DVS5f^#OnQDXw1neI%EQB0tS -zorykYqGK`um^1?>sX3Dh&7285NMn+*GigRlG@S{~nfwGX(af1NBPQ6HG^;WB31Xs| -zGigRlurp~^V*)F6Oms~88x!bELMco_8ceV=Y0HQSb|!6VOkk5VCOBsTMZ^R@C|y6AuV`t4`nKcw{+Z{K=;ArUXPhz{N`Mae#T`hvgM;VX6t -zmH$3Tet4VElcz8EuWpR|ZS_B4j#TWASL~HO -zg6}lOA|Buk6O|KBpT6LK+2MQHB|Hc#Zw?zqC?}4bzTkh@>3i5M+`=0+FF8j}?2Vr| -zBxO4YQ{-i4hN`C|{EZG@qf1!Ldv5HtHy7HPm$SzL#B)Q~Ge#-cFP(4--}0UzO6$I) -zxjA5Ju3~b#NNZ!fwO(p<3waSzJuy~2nrkm3;u4D}@t*0u_V#j{v5?KFVy^5WH3#A~ -zyQCHuVHSFsEur=y3I9r$Z>3ZCg!kn1+S^KPZ6$0hNIXNso+}k)kF>;1n8{v-3AN`W -z{F2+Z)gc^>koM8B_Gw&q5xXr&JTtYc(rBE&c( -zW}Lt^6%#RN5$E&PYn8mc(mQTp6mPwv*S@0IwxW!^J3y=jVQZe!a!^|5Ao7pB^0gu3 -zw1oex!*|vtJQg9w8L_rO+}!2t{s6Jg4_ikmD;tyM4+5qSs^si0va%t*vQE0kEf^!D -zZBndlEcaqL5pyhJ6K|cUgbyUm_XSM%RmqFGNcdnpyizz -z;G=_j?fJ`X`NizsAc>9)N3T|v)Jq55L>}dpZwqnR3I82#-)V>NM?QL)vgD97&mruO -z5N=eAo6508MD$ohD<55=NIR3}#X-}bD&>t`MA{vf_Dh{kB5(7`Lqpx;xuwNKeAgn* -z;iK2|+LxBtmX@>E1xR#OIGU?$ZIV8B5cxi@d~>LKdcwcV;albs?&PDl{%`Mc_y~TL -zb)~M@-g=H??}}$PO1qrG-~WAz7>0!nS1H-epI`77yM1psgg@|x%arUx(iIM2A3UEB -zHY`vYpZNTO-{tbToI->*lx;mn8XMw`b<*nR7ZdSDi}+{WV1nYIc*PEBf=gHqE9Zv| -zqm+u4&oB6&aQdEb3ztH1R@jiMR5VE+{cbT4y%w>SH*DK_j-1#LKe10*;1o{6AB_$h -z49bbapI`95?DjqE5T1tOji?Q@HX_)Cj;f%gpRwdXFkvrFKs>X;o?NA- -zNeVj%bDx*FIn+Kq;a}qLEpZ8V@ScUecCN_Am9iZH;<-8O8KEc*NwY6t@>MZ2LhX|i -z{$8iA*DVZ=5aalmaU_>hM#PyG(aBqO`198eIL^Q`Qm -z6Wy^_+)hLU!bD&dT350fjspw~tcO7v1SiP@#)+g?&EVP^;|Wv*O*CUmVDMRY!P(Ac -zc9og%5J>K~F1vsCb$7k_tM@e1BvC7U}*baNuQ -zQySbvkbwn7Q3hrnM>~Q%Od1ALG9ea!Hd&~G&LnL-vG!nCr -z(v}xP<`+$JZYPoI5>lLrn6uon+1S -z#G3WeJ{OUv`Q=rSu3o92*%dH5eX=JuDCr24+XJQizr!TfI~u!INp6(VrTJ(p -z=h#EPV6t>Fi^+!+lQ9`F`H*4)=M~W=}R$z--MWa -zNHKw%8YUmInDjL;F)+zKCR5?R7jIWFsbDb~gP4RfVFKqGCSewn3W~|n+bAY5q?o`> -z4U;g%1cnroM{c8-RIr%9hcryW6cZRyOqSecU}9jBeN3JQOde4&naX1FImKjmMod1Z -zn7}z=GL>R-Jz_GI#pH8}3Eb2$`JBb%dc4U-cT6Br^U(|EvVTuWyBPLTQCL4OjhK4E5!tch)JP=iGfM>G1&u{EKxDh?M#kSOipCPVDJF1J!=#O30z7F -zOg^QUz)cO4PgzXH8<-fFWFM2CA(_0VVq#`7c?vO+GhqVf8YVJ}i5W4$oe2ynCU8^3 -zM5dU)5HZ1>iJ8R&KBQqHQ%qopm>4?~1CwsR#RSd~6Wp0xjhL`Iliz+uF@c*JCZDmGT#cBpJComkMlpe#8YZ8y -zm|SgOVqnq@m_Rc5NX29!i^(R$s1BH#JPYqnN-DF~Ob5 -zLKYMFkcP>36cZRCCdSUhz@!^6*#elTJ(E%F&cyr)#iTqVCZAAD;2bf*oyjo7gx#6^ -z_7jQ;+|)4ngvDeSV#4lBe*X!@1a4}We8OTf%)rFJB>R}uK{9cvn3z~h$`O-DCQRU5 -z!z99DVnR%CX97ct3Eb2$iBL>nh?wBc#Kd9(AJQ<1P)uNmm>4?~1CwsR|+7nf#z)@)(QBVZ`KACQRU5!{ii;$zzBK?o41vF@c*JCZ{MSFhopnXYv?} -z34BPy*McvNiBZ|qyjF@~xF@bZ6$qTqM89*^<(Cth< -zqL{!<4U>;pOa@R);5XsUcc|le<_!zz=t$UzNVPKkYcjS*qIoZbORQcU0+F~Ob5O^AtZXL6Kc0yi~Gjgj-8H1SUb|yzCCU8^3l0F)%+afjgMxOhWv;SBtccS7cOOx*ZL!`rW4aGWW%pQ+^g -zgoyX5sCTH6zdda!51GqN+>}W5m8syorocRx@7{J&ofog}D>RhzXR5fTBGo;G>M|nE -zvx-MO-khYPy4+q}%D0-hL7k*|Yod9RRO2SxI6ucns)wY4iaU_k -zZDI55D(;?6qHIbi^-{9Q_kKHR9TIPyAPg!Z;ySBX?6FNwItCTn2bJ?5SIK|qBzfx+ -zd0V9lCy}jwd32<3q)=bV|J@{C7AYK-3SRFFT<`YX)J_U>%5V2h!wT)C7 -z>(iE1A@eGed}k+V+?iOgRvPK@mA8|Y(eakcgh}N@Tx=E3cx-)=j)P_PgC)GzBEAFhRww3o92n#tjydjed+cM -zY$w97xG+HAD~MQN6}_HVo+9l?TV{mJGfeWNP9oJOqzzJsi^#M6^3##79>VN0B34?( -zPd%{#NyqGR`|MKwt1yZ6iN+=>Yc@${H<8EsZ^Y~ek+bf?Yime(v{?ToHzq_K8LO02AkW{48l09dEcym^f)^+VXkG -z{JDv%gW>RaLyoY&f?sxYH{llextWoM_g}u?SX^XZT*mLN;?BZ{`otS@g~bI+)0Puq -z^Bq;(moOX{Zx}0_DdwMo@0{c3o{3cVNCk6TfgGprqjpk#S-koRA-9x2946k&qTcJ2 -z{7q@g{;+v*756}-da%$?$>&ya<(;H?W1@Mx)Z9e4YCl&PsU9b^77?-0DlYJNrzah) -z#rD>6zAHq$bE4j!O3fB2&q=sNer`mh^@>!m(HUrT`$o2t*5UEi9HFIxUmhafNm1`O -zrDkW^GA?8uXX0*%w2nyyrKW)7@~vnmt>faYy@jqaBATt@X^(e^qHIfBQXzB7B=_hf -zd0P^B8>PN(A`kV;RguEWg+Y}>9A*`t_1LaRI_fLz^~L-mlYD!maJ(?Th#wIqw&79R -zRHbo!+Hzmm{7sd-I#Sp>6R};0w#S_OxClQ)T -zJe&y=IM*{fQh;@@#>OE4aKB6BPKNz6F8@sG-EPprkKDGlSvK5q!}@(VKHf@n80tsWKu&h -zftwm8H7q901||k3*~g?6Fey|qX=E{}K}?op!UWDWOqQ^iG$JOLOkhYcsXR{Y0w#l0Olnz7@(`1SnJ|HK4U>f| -zCbbk38zvJNQcUs?lZ6x$7*b4XFqzb{n81fLOcqj1U`R26?=+H$kxa6kOuo4k?Deg> -zGqLHC$uf#bV@6DtQB2^RVp4<2UlVvO>2Ph`+n=qLyqnN-=4U=Uo -zCI<{m3{0|*Nef^yNyTIri^&4SWN{`;;9SFGF^kDA!~~NG3@IiH5R=6e6Br^Um`rxD -zn81fLOcqm2V2GF)$;3z|-H=R90w(It#HLFo%PA(&jF>E^n7}z=g306%VxmhX%PA&N -z#AG>($sxoG3f$K -zW~-R&V=-BSm}Kmkz`2Hru4l3jF~MX4LyE~7!~}aLFhoo+ne1aRfe&ezV9x}Gh>4L* -zjAYUc$>e*$MBSOhbjbvJCdrJLV9x~35fe-%?;|FN%k=r1eo+zFH(8$ -zRZN~`F{waIGWJa1T*E}yGkF#QFkU|*<`X3dnQLRVuC#rI7dt{nY@9Ru*swbdnQK^6J5{b4a9^^CM&RK -z0yi~GbUl+d3``76vX9Apz+{Aq$yOGV>k*TTJrg+BFwyl)wo**?U^0Or#pHU#1bZeh -zq?j~fGTF*v0w2;a!JY{WDJJlpMlvyyNw$+o1Tax|CVOs3H1Tn#$2@DYvOeVWoOyENrCfGB9A!1@A6C;^)Lozu9n5a9G -zJ-TFqJ(IH;F~Ob*oFgWfOx{6EbjbvJCT9^7UC-nl#6*`&uxA1{HB59plXnbE3{0|* -z$t1vJpo+;R7L$>PNyeTDoNJiqdM2AFCJ$mVfg#0YBw~U+6BtrV7GN^j#9{&;(lEiE -z2@EMF@SR37F_KBPlgZbYg1ru@JCg@>$pm{QyE0;eJrg*mm@L3#vY%oCLrf;vGuefh -z=z1pmDJJlnFqvS_1a4}W=z1pm4NMG7vX99@z@$LMq=Cice#9hW&jijjOmsby2E+uD -z2@EMF_ai3QGl3yug2|+T#RNX2VS+sq7$PP{GBJ`#HzboNV506!9@Hfh?3sL<5fkj0 -zz&T=q$)p7_(Ipe?nS6_w=z1nCh>0$lV9x|@YMAJHCM^ag|8Fo!z4CzlSG{`o>~YoT -zU*4tg%X<|*Kl01JJ7y&N@vFvnk_B~%1+~&HH<5Gv^1Mh(j&QJoh=o?M#bXM1;3#=jCGv1!rRKqXn1wtOEle{Yh9 -zbdu!OL~@h#jN3Q2opg2S)=pQY(QOT*5*1tW4h(oR7 -zpFIV?9ea-C)F*N_NFTX;fAAFCsno5Nt~oS?h`+LmpLq)AjXg)|>JoLelFRKI4G+0K -zS};XSc6cJE)O(B4 -zyg6;@3Y!O2aix*g{;6P|JJ8tVJJ3#AFORogDYO(3ahFxR-{UP*YBr=T%fse)6=&}x -z%G!joMVjgKec4W0`@~yw1)-FP9aeF?$9qH4(N$vas^Fil;w+s+*_=>zN`0G%T;!Lp -ziWH7c1#6oEwJzU6kL~uPqrS*qU&gyb#CBWMcDa(bO*-QA{p7LrQX03UEzgI{&zs~c -zI!R+)qOn#w;P#DaCxs*8g#(4-6-2zlD!${fjZZp`SK22P@dHirHJxO^_QZnqQo59g -z`>o<)kL`}6<6x2fU>WbNl50B2f(?lU+oW%uL|)^U`$k%Z3Cl}}c-$&Z^4JQJj^(BH -z<(2%b5V745wT)7u^-`jV$Y#GhC(<$@6&&0Y80_+uwi97=T)0daSI&PLBC*?}vCEX1 -zTho?TL*`da@|cJ)QrKI{|7eo?bP{PxLfRJ{%AE(A(=F-&5EqOnQJ -zn$2m;zr*GURdQvdYd|VE#~paT$tSjxu0ipxaYCwyh_6^hizhZiNp4769APu5;?^EI -zOLG5m@I=8-CFj()mxAk?0_$DAhdc#;eDEB}S(nJ!DwVVp5;0^ICwmHRR&q8=AGv+~ -zJp~Uxc#hOe5LdaR<=Q!rDh3x9hl_^>PRu+#V5^5djnaJ1kSrB43#Qt$_N -zV0e>nqo=_1;5jmHdt%;t>A6FNM0~_5{=-vH4#Ta9d7Gqr-M-u4=A>xBIAz}V-(Ct% -zZ3;|v`F`UmSoPpJa&&#-Xr1&X{HA|d#Vb7pOJTSvakO6gxykn)+?)_Cn5*QkO}UyjFnP0~?aVy~{? -zt3$+_ANA%b%{!!;Cc@44bCV*~V^cw;DWJG~YuZWmgm`NYp|Fgv4-xN_sCR%;Q9SLQf -zw8llaTm9V1NNYc#tDK0>SjDu*)+6Z{RAwJk!fyx@TmPu-MkTLSs&x~&zhC}Uq%bEH -ztZ)a8H2L1}*sfIac1qVb`L?!`!U6HZF~a;}BEDu7mw9Y6mBw{x%e1ihtt$D^PSUs` -z(YQ@I>m>4@{Bo~I%TQrb2@wxl#fhHSTmzHLm@EZMcK?D&T!+atipi{um`tOX%wjQt -zhiI65Nil&TVls_lG7B-8#$xg%#RP65CetV;vk;SMEGAzXm>8I3ACm-N5>PQY&0=Cl -zOlD-l#EzKEU@eHHF_}Rzfg!~NZW@>vm}EJb -zv_F)#^qi$8lW{C2Pfn(o^vi_F6O$<>{a8%kAsQwhQcPe-F%c$HO!`qwR!?Rz`H*4) -zHz_9Yo3v!ok75Ep1e3{!1||k3*~erDVB%IW3A30~QcQ%~GGS6lFCQOzhCev9=PEbttA|@wTOqL=h(4U-crCQA{M=@b(f -zQcU2cfr)`hwlR4)ZRz>0noM{dCb%;hl@Sx%nT%pFfrn_A9HyAS5HZ1>$tc7`w=+3R -zF@c+i3GPfrAtt(=$zcN%1C#7y;sZ>)DkiNgCLCgtac9CICc2$TE5(FIOj=n?IK%{Z -zCNQL!z)cO4Ru&TuF~OY)3@IjX)4;^QB-@xQ0Zi0n(x$@%cP2A3VuCx987wC75Dk;# -z6cZRCCb%=1ftcuaCdVlza1$}XoyiQuM7J|JZeU_yl6_1%0F!rBOxjpXoNJlW$l|?xC0@aAyKT -ziV57*F!_eX$rlDD1}53ZR}W515E5CNhhO1u@CEGqE5hx}AwkF?kv>ky%VEhzagYU`R26n;IrEi-`p>!JP>V -zDJF2!z{J2L+n7MlrpVKSKROpf+o -zF@cAun9TlwVgf^o$soEj`DYJ`$>r?MWZDN56Szq+f#0O=OiuQon7|LAJCj)-7?>EC -zWFM1tXG!iKnts9L&Jcsi{}fS724&ir{7^(Oxt!gZObJm;dQ(hhgcwZ1MHG|4bZ2rH -zh7=RHsbVrW#9(r+h++c2N!^+J2t$eq+%zyTFv&J1&@<_$CX)?1Oz6%ea#co5=+5Nm -zRV*g(5Dk;hC?+sOOz6(!pI0F!?9OD`XA~2-iI~ux$;qn_6Lx1Z>oWrr1C#7y@*!aI -z7ZsE5SWF&5Ofv0Ees~BmVRt4|zN46IKuo@4F?k3vp*xeqFr=8kO%0RpSWF&5Oz6(! -zM;KB};HH6zfl0P8fu6}`HJOy^Frhn>$k2?K(4EQAp)4lw5Dk-0C?+sOOz6(!pF+;Ij3Ei0-oy=ka5796=MlpdQVnTN&|D24Nusf4!$0#On6EUGXlarGX6Lx1Z>zILw -zfl2l;`5R#JR~3^}EGBsTcHPe8BZ>*!q?o{O(sm~ODJJkkaA)$7fr)`h_Az-DF!?VPldoA!enl~< -z&$u)B6~$z`ZfEi}#pGJVH92`1;~zLog%Wqo_~D4MLkP~p(=`d?nGaA^6g6DvE1NN4Y~iqCkwbCZri -zMfO2u{Du&*O^(|7D|vNNt&_-q@XP%pg~L<93TL3g?VIAU-K^womX5f61KLU9uz2AB -zVSWV>Z?cN7d2D$~F)?BH!tk{}gHIAxtVGV!2g3?6D0< -zIwqCdCzbMFgo&+B)HYFBut~b#P2@bkydcstI2HWX9hlzatM}MOBpu5u?8}S!2gAfR -zHfo!tMAxM)v%=Xg>fZB{Mag9>xtc{%&bjYJ`J01 -zsFLsMBr`W9X4XqzHu>K2#I96k?v!q6B67K3o){6vq=LStfY0T#d15n@jSjPOL8xZ=UyT7Ddj(`+)cRte(qP1+?p3II5t(-Hx=^>P2BB~ -z-0?zr5kCyhuk&+{L~<9uaKTYtZZ9w8!zOM!JY+;Xcc5^1{Nl9bv5@&O6ZakrC&U|i -z2ouZrtrfco_pqNE9%)$p!Ue~~Qv1Y8{w5gC^KotsU9y>7xB4a;vF9KPF0%M -zr!CcCb88hRM5=qIf;Fx{jnfxxC)NGp)uV*gQX(d;VqcHm)U` -ziJBeKf+oWK+Rqh4TJwaKVj>>0icfgFvy%>?$S#!ed#kvmokUrmQ0gSfNw_Ed+>l7? -zh*WTmGqA?(o8$4`nslT#CzQ=n(oN(Zez_=8*gqBQ>kia5`J5ix=%iy%rMDBQD=#9^0Kt? -z@9@}eNji>~+K*TA1FPhcPO@NQV!?K4R}+!%^~+NuEmx+3_csOZcloM4w!)<2V6pvR -zIUfrV+w7>Vw-VhVO?MJ`iC-QWX~|6m4><#e+`e(`q-8|BWuOqR;O!w|yEST?phS13 -zE&W2~ekS?qPBL?QV&-~jhs(F9od{RPg~u5lfHEN&Us?Jk`BJi -z&X@2nhDj_Z8p~ItTFK`o@*uxFKOziF1y{HO9ZkM>+leqFE=&++7x6>FBsMG>o1&~) -zpSIi+Hh)zmuj(Xg)+N?#mCR0`+)lds#=Axefl?x#w~9kNv1^s&#yejQvPoy?y^YkWBv<{@)CP_1#g1$-}<@RBDv#)!=sm{ -zEmOkgH>$XQh0l`Qe(~Hh=}X0Vu{B)IqAqPw&#}fhpV{9I!XSzME+K3 -zo|ACP{M?vG^+=(ils{wQ`b4USrGoj+K)&0T-%hG?Po&aM7-BWy(5+8`m{v| -znFSL!yOT8UOw_EE@?5@(cG5aJ-g=o(SWd(xR`IOI+b8L0DYLhf@CQxY*iKTjEm5;s -zin#kJ2gzU -zQ%qopm@G0dF)+zKCcgtrzEv@?v6#G0F*(wh36s|;CUB0J*eE7%ASN~zlh-LGpEgoV -zUS~0R12M6&n7mFgf$!8Xd7Z@sZW@>v$t2s!WEv6I{$0i7F&!qDOkU222_}=5Sxn#| -z8YW9ACNM-yFqyoJnCOzpQi{oAI!rK`yo{LWlF3p769bd%WAaD9GSWMuifr)`hmNEIwWFoE| -zp<*(C#pDJ|ChId{0_R#XSzEOk5NbIH$?vB`d{bE5&4wmBqwG -zF}VSgiHpT#E5+m$D~pMXVglc(B@-8m3EVU=F)+zCCa^PkUd7}t9VVDep38^{CX?q_ -zOyD6JCXY}|V2GGtGIC77?>ECWFM190Fx6cCXce1 -zyos1(OeSw4CTuc!=~0Tw=ZMLpEGBOvCYVg#WHI?1F?p258@@(_wpQipi3U$>adV1kN#;ETfq0MogBmm>i&(EX8DUfW>4tVzP|I -zb1=$qB?n*E2bUm|!wF#9{(B4NMG7vW*GsOjfCw+`(ezVi{CO={_@v)e^gP7=gCO(P@e5aO7d@Lq#)4;^Q -zB-@z4&g7hm$x}K^Fq!PjhzTZ>eJm#M5DgRTnZOV+!DO-zG0`Ox?3p~J!vvGbKEyKumN!llKu5OeXKMm|Q?ibUl;z -z5fe-%@3WY|O#>4HlPqI$Gwe(Ts+ja)F&Tx)WL+jq;9N^4>sUD@NCyNQ(G%ztR$u=gi -zGuftMQm(@UlgYCgF~MZ=EQ<*|M8gDoCNM-yFqu4yn6Sy@0qmKS>oCD&@+@M)CKKN1 -znHZRK111jxCf});=z1n^ASM};$s33Xn@oO(J(I(TiLPhz24aHA+!-$ElXYvMO -zg306!78AH>U}9jBZA@Ti@@o~7i7X~BVlvs92@^QilF3#U6L^S*3HD52NHN)k$z&_V -z1csPQuxB!n#RR@nOD0<>CNRWgV)RT5Ou7M+djXS(iixgg@*2ftSH@)W8pQ<8F_~b` -zWItk}>zTYpF?kV_$!jbo`wB0sF*C)VS>qI -zcScMwne1jUfrn_AV9x}GhzTZ>-H3@UnPAUku?`bVCc6<6T{1CxCI%+mfXU;4$te{R -zUC-nl#3W-fc?U7kB@^tKoIy--ndGvVz;|lN -zWD~^%hL}vU+%xGSyIVG2H+g7}9_!y&e)7;;@IU|OpVR6q6+GUVNk?muy|s*Q2@&t~ -zsCTf^ye)0%3Yoi1T<=Kh&{Qzb8OU?{u5Tx;SHxQ{7YZwhIMOQa@_2KVn)tAr1jxCxy^*=GEa`u|OT -zq<$W7^R>#2u8Fdra&v#i?6RM71Lv4su!+)u+~}Gp`zbdZW|#deHx0;*u8Fdras%I~ -zWtaUdHw|Y=*Mw-n1m)h6c+J=!o)i)>Ybw0tWR6!ht0>UxK*8`W?iCYtF*xB`?j65_KmlW6k1A&n6Qe2 -zJ>F{-WnXyX+Umt*#(;@)jDo4yEGs-y6mzzZ6VIU&raW^ -zc2eCVUOiOEEg|AZR`D8-_eLeZHf=c^HczbL?&>7@n-cl;($Oa0n;!3#O8!nMzlm_= -zer{r1?m~~B*7Q`fDc4bo5Neg14YoZ*an80^x$>bo5NsEDr -zfk`)D0$Y`siix1Z1e3|$jF@0D*~?-A5798eCJGD@6HF$15ffc9!6u5J!vvGbUc^L~ -zOqLp$7?@-qlQn>e`os1x9h1oh -ziU|y9GC6@wltC;e@SR#R*+4OYAx$Q24;h#km}DQ53cy5t1V6U9w2nVvD3xG5%Z -zPLs)Z*hHzPn4Hu#QQQ=h8JJAmEGG37lkas+6gR~LzEevkZWfbz0}}(2ZomX~CVNy& -z=Ib!QWb%AQOfZ=|&td`((J;X#3JehwOeW7GCTub}flZY8I!rK`Jdc>L$)xQO0}}(2 -z>|?S7Fj3!la$46!c?&Vgm`vV6OxR@d9X3&pBPO~g%3FvDCX=^VOpYTax+cn7hzTZ> -zw^&S$8<-fFbOR=^GkH+OWD<+X+n7wYWx@o`wPdo5#RMLrVS-H*7*b3QVKUi9F@Yf_ -z6KtYPVljd5)RM_IiU|xcnLKP@VqlVeOzsCv)Hj}-)-_SQ6q7?4lZlsN0_T`au!(XI -zG0`ATRZN!aFu`Q9CnF}9 -zO!lytz(X`lu!#ag!~~Pc9>heKOt6WvT!#rJlRb!uE}1MbFflO6J|<59Ch8kcPV1T| -z?;<7{lgYb?i7uI76D5wA=$a_+A|{wj-eoa~BPO~g%DadOCX;trOyUM61}53ZY6jOeUK%VFKq`GTF>x0uRwJ!6pg}DJD-~GTBTqfgvUnY@&=~F@f*YlF4R@ -z2@ElrEHp4NFv&h9cLOHs8&6K_dM2+@OrFS?OkSm!z&R!p?3wIEOmsbyS1Be>VlsJ^ -z#bhsHqU)KwN-=@&)RM`oEGBymObkrA0TbAnysKiu>oCD&@?u6zFqyo_Vge7*Fu|S) -z3=tDdCNCl;x@3Yq6JCc2CX*Kt6J0VfdL{-Y-GIpoz(jrH$!T5B?$U+SxnAjGTE64 -z6FAqB$xap%c!-7x_Do<%F-c%D*-0^hAtn>-napM}f$!9k$xez13^AD)Jre_yZotG0 -zn5b_&Ij!rNh!m4V#$+N=OyC@o3HD3^h>5OeB2rAwV=@t0Oah3Bu4f`rOyE1UWFoSd -z1Pn|JOu7LR*qK~ZF?m{t2_}p@B*+$RAz@!^6DLzMX{;0n3WDeUi -zxzt248JsDZ{M1A-fpeNnZpWU<28zinwrA4bL@^mclgSTFEG8Q$CUe=I$%Q7034EuT -zOwKj2m~1dGF)--{OkiiSS;eGOhY3w4%AYf0LX*jvKeL#?Lo`gVX97dSgeH^DKO-h= -zGPwhLCZ#$|Xflca88Km#$!w!%Vqnq@m@EWL)Hj~YVS6T*{(_ifN+v)31u|+pfQkCXlR0e9J1*&Hsk944{5TVLLnl$TCzSP)O5Vn_Wkc9pS|wLS3NKFuYu$m0Cf~E|q%bF5m?zX1^NURK?UBOq!u%p4 -zZncVcd2CaYj`_v*`Q`jKRr2ai(zq_sxK&!>B=Vzv`N~M)s8sN*GjP`J>*KLqopekp -zu}`Yte;p#Wo1(Tc%7PtfOF_t7V3PAAEqSTnw@ra>T|S|mw2Y6p^c0qt@q0qVHZ5u! -zs6^}1mXjg#Ns~OdlSH>BqMM{A+`ifEq-9jRWrz^3Bw}x?xWN+}nskh-u#YR|D^2p0 -zPBL>xV&*#OZWobn^2^I2LSJETIsapo{8U8fnF`+G3f$uKebG*YK5-#e;7fTqOk#bb -zvFjCSQ`+)&*!*Ob%y$xLb3)oFjc@X8ZYN#+<6WbL*~LVB)haIa#O_Es0!8*f8824J -zwobBULt@P~>9mu`cE8*&(ltzYx`c>dS;bpDv4W)I=~DaCmHgZgiQN#5jZ%{JQo4!A -z7QZ|m6N@q%M|+ -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 -zHM{Vx>9#8a>{YI++MOOaEKiN*Gb<^1RS -z8ZV0fu!>iB3MMM^x+13>`z!4Gi}_`*G+q=}Tg6UKL2u>g|3pqX7MIu;SMU$O=U=yq -zk9rC&-nWW0^o}=-5a6%Y!{_g`itl*}CP?Jy&P4uNDaUnDEU}6odA$9V{JM@{oikA9 -z_6=`Od#{UnuTb*qrK3&0H$C1fmHeF@!ThE`zRNeSJ?)(u_2wwebyBnQqNrHKJdgK! -zi8OCYG}lW?(?wCTifcUHIZDmij$ocEkmvLrX-|6xM7=jDHMJeVMt5LAlW&*Dn=6r; -z`b5nJDeAf?K4BFT9&c|&+0qf5=?u(t`)+AZdkdo8v5K;zBe*mAq}z5vT8` -z_Oz{6)OL;1xUnO6y*qHA$@iMamM4+M9f`(u(h}E2@d2xN!ebjOk;ZL_#?2DE-=RHi -zyEf@RopxOmpR|hSJ+a{&#wy7j9l>Xs -z0?)X77Ef%3M3Ng4$!$`vJExtu^n7J^pqJD4!B@vp+)zJP70JC^NS!-&%F(CNzNv`6 -z`jy=m#VV^9@~H24NSE_}tK$A=>DhEauV}$FN?qr%Q;zZqdwDT$GI4&G&x{uIRq8Gr -zJLNcBVn1BLKeli8Me(mz@sFN@Im*2M96RNhSZ1GC!f%B~UuPBn%TsV-+A7j;WxS!6 -z055rf&qu7{ZJvTS%m>FC#tVy!_%ZPL-&n5Mx_`WSv;c2;2&cFye(teIb+0x@Lz%sygx_!C#zd+| -z3Js -z@`FMtuGG(68)+Tg<|r(-7nbwKLn&^RpBory9WJz#oVOedo0nH{53VMygX68^1$Y}u -zIK|!I=axoV`?NWPa=TE`@@acz!xkv(3< -zzgs1*SWQ~`#al)R@zV2_i(zxWD!F(y5&Fl4(E_{>C7hC{_~pkULa#Q*-ZJ~%68=?_ -zJSHNH6!w<#KZa9sAHQ545eBq5_zF8;%)_f5Ruf@dT<9&dm7TY|9WuXdlEpf2>+Xa&zLjdBUb*exXSY{_?&Da_W?$yvSZ&#y<-m -z{md%f=qboo>Jl)ov>z_wr@XS~qWC+j_?@TVOL)YncWzyF1b_P&o6J(T<{9l;!DAjj>y -z#^b$FBKft6{2kJ~riBx*KFdG3qi^;YqK$2&$MH9HbD -z>!bxP-~H`rZ(-CsNU7P@5sW$mQMYff$9t_rl#K~xyCgMT6n$24g~vNfBFegivQ>h& -z2eqfYL!#bW6=icrFzF8TZSt*aPuqq@ZIhL}^-`_tqPWm1{>@{%Od@$(6M37Y3b${H -z$9A)lw^=&kz9Qsm}m+lT)wB<)3&+MSPy09 -zmX6?HXJD|~cdaLOqeN!bCT8xC?ryp$K5rH8^TcjbW^Rzaboo|!Vs}bJTAPrzNVhmI -zieFg80#7Vok!m}FK6hY6lW$LZIyN#Io32P3I)WXpK!?)@uSSu`nk|Vn8>R8?i{cGd -z@l{W3j6~M#NUT{WnO#1vJsm5I#s(>CwsizgI|HZPz9F92wGv5gOeD8U?>Ai(MXR{d -z6PqQGxX-~(7L}RxqIsf_Sl%vm|)LvI`@_9>f$XsmVCP%uy8n}w&UK!8r -zC2acB!j52xGf?98P4*PrtRzPXn@ah=Szfv*_P2^#JOy9FN5{l-`v~RbeAxWbMX}u~ -zj`kFsh55jE?pWdQQwuwSKez%vIDP-)Dfn>UD$+1C-q2r|_{_qN;B!rZ=Ul!=ZatRb -z9`|!Ok%r;I{xu6bg7>-uUpM*uFrVq?)3te -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 -zWQ)$#@AO8Ih0Q@*^1<%>+^%Ne$O -zNmBU&b1Yxrqp0Nz%+>Pc6kEQ)oR=@Wd}*KZ#R=uh9Ho32!( -zyimSKO8KJMdGRRKCDmEng(Ie1W-IzDQWUq%`G=gyoB@DPJTk -zU*Pp>`C?_u7kE7{UwHY_KIKc79(nNlSoil+b%%3Z**E>zHs+TxxLtW^wU~0Bk=3tL -za=smt6RH2ck}SXEk^j*;NBs^m>p$Ag_??ty#yogbKBIn7jPse;oVJv@Y$-37Zzi1Fd%}JN*xN)Gr5HtSzZGm2dHrcRVP+*?Kqr_W;>@ -z$EkmQlV8dyrrv3OU9D(V{~_sZejUHgPrlY8H@D8=zq#?>+}h_iw~oh>rVrO&{>|;t -zT=qA&E>m%5dA;6mZnLZLH@B`+nVsbcFjsza>oyg4mf%>LO- -zF8<~={0qI`+`3Q3FN}qk;%{zUC*v2!!d&^yZO|9&Z*DMGesdf31^(vN=@sS+V>7?N -z-`qOC!hB)uurKg8H+a4Bo15bb_BS_pJ^#&(|K`?Czqw6owRY^h_wpCUZaBt#VeFvq -z@XuyC@74Rl*bni~W(I%9{@D!7l|P#q{vH0=OsBof7smGg4*zTh-dg#ynfn*Be>MZJ -zSN?3K6z2G6Gw^!l&t~p`x$-+%zg5i6^5Zb)e>TJaY^HtwZ03rysqDr5FaO!h&D+>N -zo7wpCKff^c;r@DmHZ$f^{IeN&DgN2a5SS}}HnZvFe|}-?UGNt8XEX46<M -zrq>c?XSo>W%Ad{jS;FirFNL}CXEQyQ;LdX1*UT5j_Fckvmif+dd+jXu51)2+?Ol?{ -z*erJHp2K`$?A-?Zvzgu{dOORTs{Z+fvG>4B@y}*9R{iq}W0%8R`LmgxCCtupo&o=C -zrf&)EEax3#zA!eU1b3EUj(;`-A4T0+hPm=*GqYUmpUuFW|Je-xvl+cVoB2xKdcWhg -zPMte;xMG;*hKhInZ|zGK%GLJcn?y^UERFO@4}@F#CIdgz`QZyPU9mxJ&UJ;3b$MoM -zNREw+#AZg@Hl(a`LKgVKzi>E85ymF-Q -zQ=a)r_?fePrl-Tj9g=~JT7O23=i?^1xJ$fvu#lN=J`$4MT_WylqT|a`*8L&NGK1;< -zaB*LuvdEliFcqAa4{S~x*eM>UmQBSzQ%<-zOK8ZIy;U~vBA0two3kO$(NJJ+3Cix- -z5qHOE$u@CBjci)#GYtwi3{D2BYW!7oo*_+g!@zh$hEQKdItwlHWUs~M{lVq#7me;nS(8Ca(kOK}FOS%k7_nLG -zRwqmSeUc%Z(_83MBzp(gywAGqgWH_D3LU%h%u9{Z&EcHU!h&4$ppa}I7_m=|R&7jK -z7lte+3{qJ*r*kr}yw<r|dmOBj6J?G^` -zTM~X**oaO?DIo~W9r9S6naeG267aysU -zr7WLh4h#K~f#y2@=xWbaS8PC=b5@~aR-XCpkQ^HxiQN)iyCG$r7_xW`lG7E-X>1h8%n@|AoDO}lK7@P4( -z%DO#dx!qv;_TSFRmA&JYqlEoE9!XiR4_W?XFqMQW$Nlw!bAN$jf4=$e@R_>#Ooidf -zp2D)ekEE>k2QBv-P4B|VtaxQ-;V1YYhk}+vM$_nU<@CQ^aQ>9<_^HU;H7L8Uh`9Sl -z$L~y83xbvcqiIsOcvLblzuG^))^ksjTs$IP+)bz~F#lvQJsB?UC=}0=z4L9}qb_$w -zo3psUQJimXFq-SR-v&twi4_e%z%b^a06o-Ho-fHr4Np(7{HydWgI -zhezDEL`ycLtP?_(g9ej5+|VrI( -z?P6h#EZKb0uyD>0VOPHSZ$_z0IA=gIFs{ZwuFi9Plbn+o&*>v9C^An8%Jy*)`;chW -zu9S66(6YuT-FjZG+LKtcUK~>EDQJ@GhsEo=2onlq?=qYBCzrizoAcm2$HBQ~w^15# -zUS6~#v1qG!vQCz|`J}>deNUmZQ1(u+c@MhmBio#%MUHr`d1gqq4~^KTMLET&7X(lSeHobn&^!3l=aP!WrabyKP>bW_7$0j -z8l-~rvbZ@R?i4-MvQ+Goa>7EE(3mTG_u9M#)x#5zXTZWBk> -z$kI}uG$`CMI2m}Y#{XKKXK0h$GBDnfAtbl{PcgX?FzKOSvYExCKVkBa9wzWy#pEFt -zlg)@p{>z973=xz5gvmpQ2@DaFxi2Fon^{cYMJgr_Ato?HOyFm7OgJX##^l>eflgbd -zUdAN9ip69lV)BeGCMyvWc#fFNtwK!xh?u~TFjk8?1egp{FxkmsauZ>)R1Xt)u41y3#bhU9 -z@(Cpq7$PP&5hhC!6Br^UA5${f$zlR8QZZSIn7|M*fuG5f2~Q^JP9`S-lbp-Rv9p-`88Ly+M9IXCn7~OD6FZB^pE)KR -zlk{Wq?|{k83MQ|zm^@0DtkA;*o~xLwU@>`>Frj1uL&W4!!ej+v0z<-tlF6$qCh#H^ -zlNE>w3<(pSOn5SBhh*{tV4`#;pJ$*#qS2@DaFt0F@c}SlL=2I=}so0OMy;>N@sF4 -zn@slD5R+|snC!G6Ch#0Fxr&lWEn)&gOePgJ#AF*{vdzX~Qj3_tXToH%+lH9HNd*)5 -zAXLEDa!fcT>Br<*z~mYQljm4WZX-+{*24sztC&2@V)7heLdgV%h{8E&9!5-HNSN?s!jnlmB$Mv}6Qwh`noTBqRv{)|=wh-8F@fiV2_=)a2@^J% -zRIEZwz939iv6#F~n6SxY_bS8$PO6x!VljD}W5O{>KPE=NWUzus1&hgbgvk;;OyIeS -z$r2Wm3dE$2k_ikElj{hRC5QE0GKG9 -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 -ze@Tt!yMkkKcHc<$jnN8I_)_4;f2W -zPs}eD@2T@lg_9E^*;&!~*6^jk@~)7^3jcnqZQ)Y@R|N$^Nw<5uYh5B -z;^;2%*J{rPaB@r}droxx`joY6$Wm@FJ#=0kzcDesLaeCq{MaNHcZwGe6e{P+-fwN* -z$u9Q|(eYcwqjjDPm;0(VXYpJ|aiO_5D7(i;+#{j~c8ev|vT1?OG$C9(G8u?g`=hm< -zwM}yIn0P}6A!nX>S5S6Oinx15ODa;q_FvYLYyv(YsDyd2$~h;9(q*2<=dKGW)OLwBL2K=#T(OVVI+o|i|g -zPmI_mcB_%4#XhNjIA^fXCtvpdyUjbmWxuA)xofUtSD|^SLAo!T(^uG4WF8ch?N>$Y -z1EWb#VghfXV)8X&0z<-N3Su&eFqy()@-<=tCkc}&h{+_vWD1MP*Bld$N%}GQ5it3y -zg2`zXliw32)Acay#cPPnZEQ`rYHz6iH^)PwyCd8yCiwV4mipj@_2@DaF%9{|Ao`}f{ -zH?f#}jF`Yl!~{N*noN2kCh$QhnS9JK;h3Z!lji`FKPs4f%VKgnVp2I(50l#wlNYA4 -zn0$+vj3rFIWih!OF?n$+Vgf_N1Wu}$e9K~TJ7NN#Nlhj&L`>i$$An{&ZcLT|CQ35d -zufb$8VsgDMCX*49>sd_TO;k*dA|@~-OeP~H*Apg_Sxk;1CUBB4nT(iRPnb+*F*(XH -z;h3Z!lWzeNpMpt*#bhO6GEEPYm4wMO7Ly2KvY#-Cu$ZhQOr{|wFhoq?q>4#|#bhO6 -zG7T|-Az}h2IVK#FbYrqKW$pNtl1!FqFrm(5xGpBtnG9z!fj3bx`3y0EAz?zD$#B9% -z)0upRn7~QGggTSqgo&mz`HW-2F-borZv!TORxmlqVsbxWqT89=Pnc*rlaq+aGQ#8} -zi^=_j33VngL`>kMipfb9lluu1>P%pWn7~Pn3CASen5+Oylw|Ug1{3N`ZqdbrI+I&i -zOyEsaOpYTaFeFTGSWKQI -zOmsVwCkYcxXYvDL@)Ke51B=O%gb8&fFhoq?q>9N8EGAD9Ce)e05HW$1921U7nlW)L -zPFXu5EB?8CdJg5bVW?=)pRBwAtrDVF@evd -zb|zgB6Zjz1nS8`C;h3Z!lM2A3R>361Vp4#Z6zg^-1&GPLn$9GIm}C+rAr_MY#N>C> -znZOV+fs-mGAr_MY!~{N*+L^!*F@cjD6OKu`F?kp;QIbie1{3N`#_D21oyk}h6L=F9 -zlP?hy7!oGbnT#b&G@Z$phzXn|OsF#%OPFXnlP@_Y9Fz28auhImTfyXe7L#R!iEd}I -zj4;u3Cf_3_m4wOnEGEkc6Y5N0h?u}h6_f8-OqLNQ)S18#F@cjD6OKu`F@Zf3w~|bX -zHJDImlBtUcbtaiCCh#UICPxqx7!oGbnPd_sn$F}1Vge@#6Y5Md2@_3ca)e{TF-bor -z2LO`;3MLIKCdGt_Zf84 -zq>;r$AWWz;fgxf7Cpjh@lXPPOdnR@zndGpTNYt71(Zl2J3!bH=Ve8n;0 -zn4}+*2w?KAg2^cslTyM&w=*dvOf;RzDa53nFge9yQc9RmX97dS1Wu}$oMJI4B}}L@ -zfgxf7Cpjh@lXPPOdnPd@nFtz8s58mZ#e_POEEW@Z6BU!s5fc~^Ce)c^5hj|>t -z37k|hkyuR3gb8&fFhoq?B*%nfl5R|3&m^WKlNJpo)S1lE#e_POSu7^-CMqW1ASN&* -zOsF%NMVM$hlW!0cI7ygLXEKX0(R3!?a7;KR>BpoEFgdJXa)!lZ9bux|nXDsBG@Z#A -z#H58VIm2SIjxeFl1crzSoK!J6!(y_IFrm%_hKLEA_Dn`9$)pd9$#m*W -zI_qIFjXIOgEGF5Q06Wjm7-A0j4j5;1|#q;@8q5fk_z*qNOA -zkYmCzNk1lA0F#=_n4Au>nB*fSIl7%mK4LPJ?My;J#H0^mA_ZAY@)471)S18#F@ci` -zCTD^yCi#d7d?vLsfgxf7Cpjh@lXPPOdnO~5WU@taHk$<-_-@FprIUmzwh -zBuuC?xtcIxJChS%ASQ5fO>)@5WcH -zy8J)ke@zz3)%N3?Qr5)Cf{w4MQN?%f62;4lYaPtMr -z4gBj-zN8-hAOF99Nj?1QQNE-e{te)l)Q7%6Zs6a5@+I{W{FA~jsfT|(%9qr`zXA12 -z>S2i7z)6*xFIaBiUyt%7_3)WgZeWPqz{&rk+{iVu>1v;8X}FfV!L$bS1#62NevNdImhb&nJQ&G5~XEHFO&M#JbJWX;#pLj!-(2^^AU$c2F -zF8B0kbW_T@F2uj2{$J?E6Wc1_X7A-Mso!;sx$$KBH2f;arMlcq!>@u|s^R7sa`PQ= -zbByI?8h#bzQsQPB^Hq>1z9VjqvD{3v5b}30&JMOKzjL8BGCOL@7LS0O95R-*0Ch#U|c7fY~l`bDq?bn9wzTjMNIBsF@ZNx -zF@f8F6ii@P+mqm{4b8XEA{{Q89trfD}w%NSIJ(Vkb;Aok;{Sfs=#@btZPg -zMAMl>I3^sE^kXs&FxjPG@)?WCNWw(7GZ{&kXgZV65R+2E1g;1|OhytW)S18#F@cjR -zCZDmGj3i8`Gl3yu0w*~p9FufoVozB+o>G!YsRk43Odin1ggTQ4SWMteR7~JDAO#Z` -z5+>A{JV2OeI+K%#37jNMs55zhFwt}-Cpjh@lk{Wq7+|tb!Q?oL$xOmTw=kMipg;nlbM7GbtW)GOyDHPgkzF!OjZLXN-~LSFrm)G -zp^FK1CJq)8coP*9xD80b1crnObtVqNMAMo4fSABZ!h|{#2VtV=On%^)a7@yVNngNZ -zlY+@dEGFF%6G68#>5iC`X*!dS5R)vz1g;1|Ou8c`k5Oj=L&OA5s+fGlV$vNkfzPCN -zCNM-y;3UU{W0Gb}nrta+$C*kp$zm~ioH~;tJxm^>&ZLON1l~l&1a1RTFo7XrB2Z^i -zgqW0RI+GA$0w)m@_)KbNQiPbm2cga+#4+KRq#u*J0F&nxOul3>xt1`|?M$vEOf;Rz -zmx#$e!UV1eLQJkDOsF$~Az}h2RZPBQF}ap7q0R(`hzXqJm~c$ejS1|T%v6%eJ`E<+ -znXJ&oggTQIEGFx+nEd{Of;Rz5yZqyn7|c5h{;gGggO%#A|`NB#pDQ!$xy4b@nDj$T;4`V62@DYvILR^Ln4}vM -z*fVh`$z&FbNh@_Gck5x2pw8rO787_A6%)7(NWlb#h)D}|CU+wy=QW+l3B&|WA|~*e -z)XwB?!~{MFbtWe`CLELWV`2eJUQ#gmip69iVWQiaOe9P+oyk{-iJvfmD}oS{iG&Gt -zCNM-y;G~MlS1cwI2@~o}V2GH&NsbA}B;A<6o{2+ACVmYj)S0Z-#e_PO)hs6PCMqUy -z8<2tt3<(qJOjZ*nn$F}DVge@#6Y5M>6DFF@9PsEGAqMZ&csQWXgZTK -zhzXn|OsF$)5+<6?N%O -zjV^n?HfOxR5zjYY49T$$k=PZ{8JknqtszU1K{AGg-pRo3I{#hOp68onAtNq~5ccJn -zR~V&R!oq05oGW{G*#4Eiq<$D|qI6fXOJ|mwe%PvnbM?6Ci>=DhT$USn6NQ^ua9@zZ -z4GfW+KG>@KJr}v@&9*92g2)Y=L~h_SDXq$>T;v8m2(~ISgO>uSe8*4u<_jU&-67(> -zB07F^%32<>6c|j#aB=TsprXz{zuNO$lU$q;FCHOO=9!lnO}B)LM+?QdvbVzKo$qo_ -zZgUprIf@I+4F;2NUOuoPabUYxQX`v6eWt8%@z7)-TH}w_dAhmWSMo2ZZ*!LBJ4%bp -zGlR1I+K7EzUgm7Y~aUcM&oR%twN<`{szdOLYA9 -zly!g5vfpSL9xfgtROWL`EIW+S!1MB=io~KV;)`{%l;M-+hwC$hgN3p;$L6hf*|XZ5 -z2a6n~x#p2ZY20}^vNI9cD8BoD117ME(p||en>3hUs}f$UiwU+WM;Ei0z?-O;(2XZB -zBuubX`TJtRgl$!((2XZ>k}$zm<LR2@}0m -z<;VVn3EQenq8m^02^03llTd%c1Y4COFhoq?q>2f9*5JcK#p2 -z()}O8hQTJvRwbF_YcRo9C2Y{e1Y4D(1{M=|6BQG>@dSp13AQSKHxMRlt1^XdJb{yh -z3AQSy41@{Ws>}>?OgJX#$K)Zv%d

$ZUxkkN$abJ5< -z^k(3wZ{KK%>RReaiB^vD6pISrno5>|N2FTDJBL4~9Sj;;Z8vpE)Je#*eenZcWrq8Q -zwKq!Xny6FA7Pa)EP>$P$2@Q(Jg1o+I)`9Nps`LAbfj%?i;WHiKG?i;Zldn?lhpA8s -zbybLRml)gGlf5^FCWqC7HE)Ph-^Ogq`0r2=qoQ!{JnpB@eWpN}!(%H|wISi#LLK!F -zl~0n^yh_gBNfkc^_b!!%wpR%2Dvl=8dj)45u19g#M7{J)?GCtKBq!7?6j~ZXqI`@k -zyA4&(%IW5?!k9rsA7dMF*|HP0tG-inG0Oq+b^G-4;j+W(tN6O&yvN4DZ9T@7d{Gci -z4#jH<%@ZT7eNGFPZYm{&M=?LgyXB^O8%1d~Upsp4#Fz+ae_vHr^v(9_lXaNpXfi#l -zx#y^>fN!m};@#4+s=1Hr3Eure!}6eHH*P4=Ork&QD$%~90GC#0X|<8og~iB*>-Wg> -z)2vU^;E-ssQC_$M^GfXg+!30w1m7v4z(w3C4Wdm6KY@wM(g~XeW|@3@dQ65xe2i5h -z30na^gYV#VklxvAvWLA7_R;0{bC11Ct2D;< -z2D1Wu2DPBw?D3NE{kH{K^%WtVLUQeu-%2W2yuPVZ^q$!({=nz7EWSWo*2}fU&uNMa -z!g7vu$%XXd>vBCE7n~;2V+}EJS8siKymE1Pqwck@7({jxUe)&pe0O5 -zOwl{?M3Y|%Zd@(ebGQWaz -zPoNp0#J*L6A9U2~vssX3TE&9hYI+pvr?aMkwW!#*pzwt4&|311AcCGX$Q|01C -zbjQd)y(vS+?%G`)ILNKj6WPKwftoP%!BmxvVXGiOIm`rnz@bHjRZyU -zdeKu;$@nXepr-zyMw$6X=>hhUo93}VF=*XW>4;}C5ono!fk0`sDM@hN#&2kTT|7k;`pwn=Ct`-8A6YwG7wcF6Q$@Sb8*XxQCtyi(*kD0xmh>jUoW@Plo9`9WJT -z7eO%WKjE_hvs_38=C+c=#{QbwWK9Y38Drjm__LstIDWNUbBk5Agi&+K1+6YrYfMu0 -z!kI~}fYqEV#q{{(i-ZZKfT>j`a}aE!S44ZmQ`4I>F4SQryl4dGIya^}wMR=%4+H=76;8dszWK(9KS{)U%g9#$9bTW=`>dyd`)J@p;}eZHkB*$Y&}$*B -z_9x$2J&ndt&xoW64ior=EJCm?ZzF(Iha{~tjfyniYPx$zlSqu=%WHc?aFh9f=xH)P -zP9?10u%h*W -zo75FO#|HKD($z}34sK*Es6kI-nY@QwNR+tS_Kj!==SF#0MAYe%N`7+zJ|m}PfE@)}){kOP+to$KJ&H5W&qglwI&mY9Y~MdW(|P#-S{6V|?cVy!nwlQEhcen(EN7 -zGUu%^Zls9&emnnDjAltZrVK;aety%{JK~>%*E2pZZ8bRUBK2|?>xd;PRqom32?Rnt -zdQ3YXCm}LQjni`7v|O)@c^L8>zwonP53?dtq`_jyd;5zk7O_y!)gz^VSrTX+4uZQ! -zmnHRkqtV@SNwC__wiRakK?o8<47i*=8YPON(?bZYbD$$IbR(~x!;){Y*GZNrQbF&G -z;ls#IP@kIi&{|D+>*y&S3b!EMz{Qts% -zn=6|WcBYeQauKPGE=7u8KKHanKWGU!>D-#J?J4JhI6wQARIJ=Fd_Kq96JsEk2Y96p -zX9F!A{O7TRwyo>FJEtK7apjvRTFV>+dvH-O=;7v*7MbTQ0=t&^R-JFuItMiO-pZ1z -z#Uh9yV{k9@gA&M1@`00u%N+vwBh7Wjb&NAvz`W4X|8^$Xz1;lfRiP1y8<*IOaNc(6 -zw5Ys@h~0dnJJ$&^d1RQ2>U_>BJ9%88`RuXb6=nb2Qm87Tomwqu3VO&)X3W{-@!pLS -z-8bbQPOB8Z`(ppgr3~~l#!5u}PQSli*W-hG7av39E*CAmrJDnQ&7FUpo%k#Hg2ANn -zPB|?XKHwzbgdKr@F!GoLYkL9S8yo@PVqO5=m(0-;o*$trvyPnaDQ{j#)YUk_c`j8E;@Mo;&IwV%Q;@Z1+IDqwvvvK54JVk?3Y(6 -zCtm>SML(LXXH&Y&ZhG_=B2!qO8s@d4UI2n(f399&+5BQQdc;kXz*)7WXV$f!d2As5 -zc+1^TzU9+jzBW#j3kH9H#NRTGX!ua|MY_&{NM*a_`wf;@Pq$%{KZev)%g8e8+17M7uz5F;0HhW!4H1$gCG3h2S511 -z4}S3fcg{v^-cYOdxBNXa^~SQ^wv<;!E@2zjrWKD -z_yKs9d}t)$IkaB5NS;LL+uZsAU%X(D37 -zJrAr9W|*bt>X4&LbPb@=3UK^2YshvGnGEH?rw$PFIoOAPnXBZ@G5kZj74`5J3orRw -zH20l)$W;HBc1wd7I>vw2%SMvX9{)XngWGug=L|G^WuN$#$Cq8_e@$kz -z>^5HiI)4$p$3Y*=@el0bJ6ND6&oTzP4;-I&Dh -zHRd{U=k9eMBR$kzQ?#D^iQpbx6gh&oj@f5&}fWGl`?74p%zXrPt -z%NQBf;x>uTT2;6;@TD5pOJ9s?u<49$F-B0t6cjRrCRp+PjJO}x8GYM*>dU$>u#_Zh -ze*QM%np=&!TTpM5JHfI`mp=?`AQ0~k@UQX{zm2)ul9#=9oR-5P#gpL|M8OtA{ItCz -zqkJX45`UP_b4PIV?T}fo`2YR4E2q$V5I!HIF~$#BL#@Yl5`einMP1_%6wQrpL3azO -z3kvds_ytj-h|_oyzVKkyH|#7fx@3X+mp4IqFQ7FowD4!EwJ;cB`uriZC5-z*En2F(Ob -zHDH}_ivcnmsc;>*3S5W(jvvkQ<3+=0f7IM^@i}WDy{$zCT0Yjc!@bK{$5qQp%T?>Xjw8@b -z;fzi1BIREAyM5dCbnV>ruhHE838RU&boKPMbm9F7ks>lgL`Ycn4W`WAq|M}bZ)k7O -zgz#iMQUDo`T(8P!i?Z|CBkvbKe)zcfC+LCP&Shj)duntVPc2pxt_aseLtm%s=5BZ* -z%FmgQP5O@;9q&JmJhGl^l*MPrVkzTA(_Q5{DaB;*SP;2YLp2%U2|yO*sRU6*>oy#HOdDr*N1v5G-wab82&1 -zx@DoAj9X~$;ijbd4;l?Jy2nT2bH~kORPzR}SfS}^`@iWwTRwtC+9R<@C`Z_~TsmI5lw=kdB%iL0hfC>Zj(ugV -zD6<8)>(fTl3_pboPNsJIT)TF=DEGw(a(DA!XMXd*kKZ_yI@CCHpB+W=B}I9a#VA80 -zAj%LFAGRO3@3d{Q?MDxx`_bKqJ6|U~rDC%~MMASfvpF(VX4Pr}G7C^|UZZNc;GPKV>+H&F!y=LOdVXOwfdYp3Jz6mv%2HcKX3x_`)W -zCuPTSM?hfHGYCZUl;K(;Q;?QO0S?*>o~l=Fg4;ZkmhboG--m{YyPOBLd7&MACs)?_0x9hIl4MDcMZ9d|2 -zCl)3i`$?%5;PYKDz@Y}R^O2{ye|nci)$ofP5}Wby!{LD0UM4{t*w`a(kB8o9tJn>K3p4~5Gh;S -zzsGf2GgjLyqNpR)o79oHyynbgmt@I4_%xrP>{fFq9?%a4v -z)P^J1M@qd0LrIajg1Il%HiV%7;?ks_#n|+|3X;yazwa2Uc9xJIbKkv&s4y=Vqq{Zz -zN5d`WcRG)QzXXF(5pQRzT^ro$^lD>VHH)$G{n92aP!BVxviVB^m@*_g9i4FM^tso4%b-YF$aT7Yu -z@4I&fA|PsYDI#gTPA -zDGMI8@4qn{IDAs^)z)^`J!K7j_C4qzW>BV-6xMOaSOEk@n>&{1CDF!H4yvAr_Yr|#*FkM>>XN{ -zHndla9B@lJI7Ro5co9~RnjWHkRI`iA9_i&CUkA+tnpb!cD+ -zDyXYF;vk37eG*6p=wi{D-ti^xIyJr9mU;s@Njg6%5Fmbv3D5FLwAYh}<7!1zK~7xHGjaLAf`xqc3AX~vAgP4x4pbz^ -zT0KFe)6^=)Pmw^tb?G^8)3hp?TQY3?5;C7vQMWg>vfau8hN~rzS1eJfP)`s_QB7-MYfPjt -zsg*y-bP!EgDjVfc?GDyf@Qr7M1Cvp8k+7}F|BFzwfU29@_Wf6+6lj4$aVzfb?(XjF -z7I$~sxD+W)ad#{3Y^1omySqE=yz!lT&XsrXeQ%76tc)ZpnJdYh^Y@=C)LH4oQ7an+ -zbb5}5N?*XMOLo8l(+giSOU@1f?S*X<*O$JIvHQmD!m$Q#I;c-6wmslO^FxWjm&jfS -z)Bb`!^T)u#ab=Q%Lo%1Hts|2ySf -zT|faNa0Wn;;Gw*72Q^y{;mf5Db7D>u7tq+is4ZVDx8L<`R)wg8ka4Ab0Mvi$D7;NI -zg#U6Ox}K1l8e!)CEbP47HL7i0FlXl`wVV)rFWt06bfOqD7Ay|S7SXh8v$oj8!XYRy -zW2YFhw!9@2J-;j6Ca{KMsh~6_ui)OlqBf?u&G018b$=E$A@52_SuB;7S?aLLw$?wW -z-Xy@w$~l#mfs=mhVkU`tIv9}Z)nMN=Wg|Z!ACf=jl15f}u5Dc4YsP>3&B@8-R^GgQ -z>LcR7dVHOY@kULAnR6Z+FUPb+)Ob|AS?gL{>3+aaT5IG>{Tu<>&3Lm{TgQfs09v8%{z%RMS2hcyCVC-WbF##sW|B&Wo049V!uD47!uCX|wPaC8CVrrfP>Hq}XpdJPB;O#XN);we -z*GwxP8D8nKXy`M!AgP5Uy%xUa>QgKXpN|VlZ^(jw`Efc>o0RJiakDx=+$!BllFQc0 -z7_|_}m1wnS4`?HXx%NV?x2~J++FXtQ9`)u6j^`CP){WvlI&9|A&(@K%mXM`$het;* -zKgO$lI^au|7(XW#(WPbQB2&U3W$g^M;J@-16xsU%i)_fTD00rhgCU-jMg@IgBz2rn -zWjbnc&LGv*-V*Nq*0hMn*LWk8&D>2-CsoIQ#~?{3A$2Y#&PBL_m>zP96#8yNiH-p0 -zw@r04htIdc`)*NYABTB=VmRY>7>n@qyG{fC%P(WX=iiONKj7-~!D%;6j&PRs}8KH9TJfmDlM?y%*e>UhcA*6aX? -z(GN!Z4Wrgx51a%;ys8v^qmPg}c1^ZaNWphVhRz`UUpzWq`mtxH{8;4A7`5!?#1_Lk -z3L1Q;;kA9(s9!4Cjq58zS;$iFTAXs@i_ys)u?*0WZx5)+PhZ8R8BLb^YeQryorQNg -zl2XS;t<1F4vfVH>LK6l)wj460ehyl>hD|QLCRpAdjxpSj7q5QZ^>Q82=W+f%)2K{T -zx4tWvDj(hNO?IQWPuMoBOfjYEY71eo+72-Km0EHDmfM9Pr_8&u#e0Ace|x_uCdIN` -zW+{qhMFhmymQhQoHdh>BggF6Cq7GASG}@9UstfMO2=9u+c2SGw?7*JK+Z$P5-@=_L&@O61NjKs>ac -z*MEW-jbu+bvz-D@O|x3CcepIF1gel&R=?=}79^e_Q6r15Y4k7nLlHLdEfUh-!@eKJr1G_GN*Y -zkI!HcfJp>kDwK6B(j3I5ZNPg559I*Z*+2@c#(e8pt5MYPUuNV06Z0@Uz$Af_lLMrT -z_T2(TOHk1A#>=o29~c<>`zl}2KES~Q2>RKn0GizI8yKMvK+73?GY2H^jwd^iLs -zf}kKDC`esLnSF$taPDp78^F|#b_=MEV*pG(g;7utE6o|O?D_0NISh>4kT`zv1{ON9 -zZCom}AZguip#Q~em;hmuao;z<{5SLhR1IdlSt&iJg3ip^7Ylm3AN)2T1EfroM1XraOooF_dmid;pJxkKN9;UjE6v|>>aX}zZ{=!r{f1Pg~eX)QycAzbb&stPjr^NoS%M!Z$D{m6JFI -z_D}xnuRMer&iQ=}t|?=$uGQ!03=V$rr51|eGZ|=QJfl?KHr^MTYK80)?Ewr2G%XZ1dnEQ~zVdl!0E7zM?h -zOG-Emd|@&dv^Hdj>wp6I8K0T6jGxcSSo6iL_Ho{<_9;JTEqG;*%f+wHRjd!-_lszI -zSRpGWGJXyn$j0d=ecg5&V$$K@W4KDRobg^&MfsySAr|vWIr}Q9cGi$*)mYkuxj?<& -ztm70VY3W`uV}l$MVX>l6I2SnJs*!FR&Y(8b+M+jCC>9$rrNLNFBioy5G{x5U!~DlP -z<8KWicIm41G$_P0JImX0xFd~1A5f=a)MX;ldncn|Rn)SlMCuoht!Q!d-D6hVj3VQC -z2iAhcL=b*Z=q5Y9gfj6y@58)D -zGS9ZWLWOB^k2h2P#B8F#$ZhJ-H){fd$r=bY8`!h2K?sz{EX1A6tY -zBPvvC~Qj0l|MTj5`| -z3$66N|NL6Sqw-#3SXS;Rr{#0*`U*Hutr;e+m(CyhFtY{p@ -z>X^IMxYaTWse6fj3wTc_Gry9PTR}hO=+<6Q&H5qVJ#J2osDQ}+o~pnrv5@4rJ6xA} -zB(*7(0Ab$WZKO{W#iF%V-(v@J!{ul#PIpZh@^z#^IAflf=P%BhPfYB%L25!JupGbj -z2hnRhH+Z02gU7EL8_&Qq*kewhZ6d3C5K2+4Cl~sC=ib6{btqKbU_Q=C>Pp8VX$aQ7 -zz&7l9`9Rp%H%FRx4;`nzEr`RypkoWK{xNUa$a0Z0J$;S0qG?@AaR~!pj`jHW5B~o+%W+saD^m -zRiSWh^Q%BIZ6miP;hpQE7dnyvCpsNzZa|{WWXlmdiB^``ikE@yR7%mjo=e?obh;1{ -zO68elv0gy&A4mcpOY>tMI@8=RuA0v9O(=N -z>Srcu-V15_e{~J0g0gFD{`K}TtD0)}JxZW5%ey|0eAQAKD}+-T!blPOE+M?gDcRFO -z_K{DTav%zUX47k}-B{H&T4Me5QPe5rclZ|B%`pjITAy<5E%3;qy80vN-H)V-8sftE -z`?5-Zhg)7O#vOGb-XMp9yDEQyEOMYKz=v5On7g0CZ)D2jrE1O -zFtao4xb7h?f?ig+LxBa*OItN2g!gR@xTpksok-bh+rMt#WkaA#?MXAr>~SM~ez@hue0LRbUdJLv$G -z$m)EY496<&x^0{O7ISeHW}9!DTsGu;e^lAkLZAolqvI%s3QFr&b>2j-ZkYcNpl!C< -z^6=V0v|sbH18hV}tk;qY)7DT{9bsqa_0|ozR?W(h>BMHxQ^U_EFZS8R{jZ$F1P*m{ -zeF^) -z;AfBZ&R1ciR;`RJ=Lj~cqVADx(cbFIP(_0;B<=cLvwGNePn~nMDDuqA!b*Uj-9A<+ -zk;1dih^`8bqvn;9>@Z~%w2@AY{K@W=dJ?e#+J|`;Xj(;O2hq+O(N~(Sqj5H7#w{Mb -z`;C~G?j)ZY8LRJtd6-(DtTmaW8%C`d$GntV5*_d>||r6e!XJC-pr3HX3M%QxFTg<90qQ=@g*vm2$iny~XOy^7n-yq$k&o -zzWVb;?zu+n<%<1@4eCWZ -z*ge0oJPogUbs<_uWJx=DOmWMuMPF61t=wAYyr3qBf!?>dxyHbr(d(RQdhtC$@e!wYR{RZUDm)pzHyX%%_j$GaO5 -zJonu9IUpH2jW3_lmI_rvKe2woZ#iVDp=0OsYO~X2ro#8xY5-0h?W-A*tIdYZXzX2n -z=J+qC@CSbQ5;X5GwC{tJ33rz8@RoZ8~nO;ZFti?P+5p@HXamqCKdWeIMk*TRfgw$|XNmV&LZYSqKzMHF6n*#D{cC3Ch#m^geO(%u#&R0G>JwJ7CSNgjp0g^d>*5PQL(t|(V&hFK#qxgGkSIUz6`%+R0 -zp2pz>*RE()$p;_BijK5+tdo%s0Yh*U!KI`OeyQA|Rcm-TV@m5Z!TC%y+rD01I@}lqsTp(FWu&5=4L{RUzEpG%FW|iAMv8)k;1MC4K}`Uc4Xuy28Q5rFCHZ(+P+**P&n@e-VJ`ABx>%5*T5If?Cs_>&r{7EzUvx*8u64NkDEt@EOd*|NR95 -zeI%Z(2IN+OkpH2A@NWi+?~_)%0sId}-#VaX`$6v2?UzTh)x~}+cQ>U8rQ@?5rKm;g -zsb0>RD?DV#ClD=SXcu)mwEt@Yu&zGyK-cFa5syV9PHg)fGq01u+ -ztP6fu=Mx(Oo=rFB9qvLN4>RuIH^yPS|EZb*6ELXn1EAX{KsMk2^k~U^Z8T3Bt*Ru< -zEc;#OJEQ#N67@d>ppk`wykAsXknPZFtRD^NOdeb16or}?a6DS&*M+UxRk4?#bHwbQ -zh(I!vz?YUoCi2&Gk!MeuP$<5@)(OiNWH*#45g!Re|0fvSLFJR-V|ao%F%S%Hpz_J! -zuj{@Hk(7Vb^6H^u*#ey-G7SWSOR0P^It@<|iHobTy?P>9wz4k}L6L}mci^CWbr#s7 -zW7(>{4Q4_``UwS10?7ZU@uZNvLR?nNnyT>@& -zhXvr<4fURbzO=tRAnBDut_7bW|C6;I0F&2S1gVay9J|!z8*3JjB3h^{{BNcfnqC0U -z_RuF;vx90VbfEkzU|C*SQG2F -zxu5MffDC}WJCK1;zy#{1GpeBHV>@j2M;|};Gi)`X?B~8&)J=QnGM}2gVh7tD^5aU& -zJw*PkyfoVo7`n?gyy!YGe)Rb(JN?oVLlE42KXU>JnAqq#*wr;VMqRj3<0|%ZJ1brg -zOyx~|HYr2Q{<-CBf84YHTs<>Y0k6C_3O5gzPq;q3mrw6}IJa)zd7@kh1t?(%reBu! -zgau8Ekgs!Gn!;vhcNHUMA9K{d`=^uqUk&L^-%a_I+nx1p4c -zm@`Vq(9Yf9Tt^9+>9({z@W5^bJ_2DMv+I~Il-BoL!XeB2$eHi=Ma#s6Y&DRC?e$vC -zfAKIPdW*0sq2MctN!{3*W(EJ+$bYb#OA$#}r>Dg}!hHuZ_Kf{oyMEID!aYFNG -z_C-*;V=cAOi;;=V8@0z*IKk|$133Ps*S`dbm2xva|KD%uU%@x7_PSP6Y)e0-gV-RN@w*xrHJV(f9yv%(<%X{ZqofDv_7 -zdX4Yjnom|v2&W%+^biV?O;Uw_gP1Vp0N8KOT+B|19b13qQP<|Km566fhcGrohsajD3@1)|tXmg^@$#;!H@5-A*U-PD-f!Lt -zM=&LA3U`xHrc6eK4fmo#`a!lzdxwrkXbQu3tzeZ=)Yp)imGml*W+@?mEaSicZ`4BO_j?_kWHYF -z!74rRt)oFI`_Bq2a&c!{Cqgi`aW8+ -zB}ckJv}zu$YcUsQFapzXlm=eKKmM=x>UKV)>2l=T+pQR9dcC-xcBrh$B#{#%a;Dl` -z`@ohEtTzQuT~~O}cx1F}{x7-@rmA9tvQ@)!efknrgH8?0)X9+{e@>K1w6);a&gU_K -z)VEd~QfxyU@)VX6BtHiOl0sdr%j}@mJbn`c6_jeaZ4Lo>gYE^qcs!$Aq`BY^ -zz?HpzRgts-ng~6hiEsu&GEy_d4GhPq(jYb5e@#sD5OSJEUReW}bSg9+*CRXku -zLCGQO&lE!9Z|GDPY)RS{O#7bIX3w>Yjtw1_hr&U@gI4=^bElH9ejRzKH}M7T93xc` -zgG)2I#O2>HKE^>1QeBLMvM7Zl!vRDd@(x5Dp7~Eruh2bIu8UQWK9pB -zw4?u?%)p*$-MS=@B68&>y|6fb(l*=8`XSg{>Cd>gd(!ms^4gtghnfIG<>*G65OBHE -zH-7cn^V-XIv9VTiR#wzc_uy)*smz&dTBp{m$C#2hbAG%mV=SVl{p{dq+%|3H>tpYG -zPfpk2`3zgNh8LYtSnern;^D+++_bolL9Q`crLWbgvCn#!#~CEY35&y< -z$Jr+aRQXJNA`|U~cdS?7ki9GUmpa3XqqE-@=2`Ac&i{zUk8hAf+P+j>5>Uyk)xS?r -zwU+TmHKicFK`t>b0a5?IVSEx8;rEHc*a!BQpaZ=Z?QiyWCX)d2zjDHV=g+@^d;tvT -zf9rs@j9wH~wO=mHUKBaJ5&!p7{~2h*BjGNwU(ugltoDa(bu3R_{#3%gO8zG -z8Lzsy%CLV;y+OYG2!VM959uodOhp~Q2~Yu5q63`HIzFBQqW^1t{KpL61}*693b^*Z -z1g@3TAlW^4;D66;|IIj7>{*0SxlP!j_a$ckpi#tUFwISme2sP>82%QxhW9s;+3ExZ -zFNu$U3(@xg3gTNpHMG^A>88*rlr9%YVMCY)v;l-yu*OrWPXyEKwP^(aS-gW3;Aq;a -zgFyK&KpET#I2UdYq8cc52++aXfa}Y2krpPS8!a3|M$=R2v{;E9^h0g8e21`a;dz4x -zZ(BZ%d|Wl;znLKJfc6u!GMRx>JnsO{9T4Q1t6I?Wj_(roU*q5w^SRuP1Od;pNnvG_ -zbX3#1A3CEHoa^-LOQ+?K_2h2&!!>i@J( -zJBhX98AY{$oJ|5yt^yLF;->N -zERuza_MOSwQvFE}=)Bk*ZJluoA1vWRfHc!L2x!l?!>naxRoI%({R3g$CnxK8sDHM{4 -zwTgSyA_bC$z?j#dq*pC6AYvE7`>K^+aD57vWnr2GaI;C@AmRYi3_y1a(7r(=0qi5d -z^%)|L(H}oBEd@b7F#`w;WjIkm$*;pVs@I7G#k1y4KW-?n9^Sy4KQ5nFk2}T+536)Ot-$F_T=1 -zF~YMYYhq(N+xzN7PECuo!pd_w@bg>eVuQ=G_Xb1POZ&?mt$GAgg4dPn^+x)l;D2_X -zD^E$Rfq!SAza3@s@xS_T4Der2@&9w!nq-sz}x -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 -z?Y7-d&i8#KFHHx{F>T^5 -zJBPSO?1{UVY4RdvlGuaj8gUA22R7;NvXd&=i(_n{=Z%Chmls+|g#-o542Vt{>b9Ca -zv~|-=YGn+ukE#+Kva!+y(@_t&N$u;Ti&9LD4Z7_58ARWgQlFK``9{#!!Tm8^(H8<- -zn*sCpLnkI91?~bNi*X6rvvNMd61$-&d?dN1K<`*#8x58ZaodpWTS83y>Ak8b^P7{> -z-e;{tJ*SS$AU -zrpxKSpKxK)V!Bv=4&*70o#CzEnnd@SMmI$m?W^P873pl8=5a^H$*8HD1*0Aap3U?M -z;YWXI3lX3vOOg*diuSmxb=Z{c4zBMjO?!{$dF0?T|bL`?w5&w=?5J09Tn*! -zc6j0xv~O4}!&%|8U)H&;FX7khUzYl+bc5|CBA0`>^c%j}x8l!=AR!7u>IsRd&6?gS78YiO*fYrmpV@S`2t=pt!iINo1n+gysUzxTr)g3-;BGhcCkB|FduYHchtz1p}JkM$1)+^})A7mQW@Wu_gqC0Pw_z96MS|u1= -zz&W}K9=$Me4)UB6x+1M|{6ejlf`r0AhDn9byGW{x%meA6F=5h@x3iQT -z2-82Z7fiOsU6NNoS6DYXT()Z{>@-O1>hJC_FEqK?8MYW;KPc|UpB -zS=g_9r9S?y@A0WcDvys6X)uTw)*r}~%aAz_j&p*{xccUkuTN}MhBUAuPyXC-9%(H> -z8!;O3g08>W``pOoR^)#Q*Eh4>h#;_+CU>Z(;Ayh=Rg}Cv6;v(B7|PJXqY&(3t~Hl~ -z#buYTAj1SL{^7quyLv$^)}9^IUSzcVY8!LagwY#El;}Rv$JxS#);OLfKI#Bk<@u;% -z6wkag*{43>4#p}{j@O)%JNEo!V8P1`5)Cy7Mzj=FopQ7p**i*tOR^Z$-t!W{z|9TD -z`u?#XN*nh5= -zv>xLfFQ!>#EcCCho!zOMw096utXAQ+F<=Mke;xQ`SsFTiTacUan}$M5Kx)@CBhVs8 -zZu>U50owLmM7XKBu^vU^EZtw`xqr+ul?2``7_$QsAgV52ow$br`+}SoOIYn98&$~>S -z4v7gUGJ-2O-zk|gzrM*)5m9@XQ{fX|$x-2~tn=8H%UoX{9XRs*5$Ei5Pl!h#bK_yn -z@;PxnS|)6kXb`I!i9eB%>7wwEf&13uptTalJ0>d&L)14y0<$ndZ@{P|jUDKhMn{k=~7@+_2e7(Y+<&_b6LfBQ2VrI7D1 -z^SQ>WcOq7f#Myd7zVKX?@CH2>$O==RjgVqd*N4Xc`bym}66flDl2O?X_k#Qu%oHKK -z$XZb+LPcWdExMob-KU1cg)|pI1uV7NYRHa6)j3d_;6Kb{>tZ?pFJ|fA(ejn^f -z>B^#S`UCrQ3}L;lut{`tiO`}0yP<8D`CL>j4yCkwjcj}6tBFpRUY$wIO_WQ~t6X2e -z586G?tf -zau;~N7n0KA8*bT=sVFj=32=zwC?@8vZIr=cVtQL-6p&v1H -zL}R39G2#h5zxEt=)uPJ@hv8n1lfy~!>hb5rw4XVj7SKkulieeFVmon)m*nwyMI|>w -z30st{%?OX#A9F=gDXIobKi7r!ji~_E@5*E`27COF6yg*l*b9op(+K8loutPQKX)sA -zio@PA8rZuD;9|s1;fzbn%`VxT#Xbdb*-%~GbD}e`Ff`=G7Dev`tP140BlH-ChT@G9jO!F~7!N`r8`eRG}yh@CsEIbVLXrE@)_ro)S^wCE1 -zJJaa5kQQGZGEDkM+dRz1(YwQdAkNv;ZE{1bx9UZhfFq^2cN&6+kHA2|Gvugbqv?Kbn>~Rp}(lZ-t)=TEY+Yj%`T-OWnZYA**v!t^IQ)3*cw8Ai^+#r -z>E0tM!h-Bnb@^n~pg)@J8Nz;YJXgbh8PA{D{7^gPwtCNJb>AL5XFMVMBgh9INBKT_ -zyvC+he@bUa#r}7|Is)!&kVfX=`^B13-a0ezH$m?78fNMWw2$5hE~5Q9nTOIQez2_R -zbvNg9vk9V%koRU!)zhOdEKum7rHO9bQ(e}DPsY}(6YuO; -zUhCvyN*uPN`Q<1lJ7A^;XJuKQ>e#WFW)_H|;ue9es_qtnjjqnA%!gnKyAWAzBW+S$ -zOU!6ny!55*HD2|RW(dl|K8~`1T;(FQnzejkXLE5{TzvOe+fb6mOz_)qTPUHokmKjcnP9!14}9 -z3nPa!#5UsS{&&YMDEO*cbU%X+N#ja^$ui4|>q7VnQ#FGXc8fL3H->0w=bbKgZU>KY=>$-0|7l+B|!Oxd9d{}aS -zlV8t9>>N{3-@P+^l_)7yoQ+y|R?I>7aC;la2p}n7itVgHaST -zoi8{9CpZLmcZcBa6hR7icZURbcMtBtr6>w_*TUTb6z-PH+NV!X@1E(I(|3LI{)%V4 -z$P<5?SPc_U+UuE#u^`Lt!Q0mLUM5_irmq_(RfJhU_@Vi;u@3*AicLy3Tl^wj{9k5G -znacR9%yPYaAp!`VNn-x7mPPu?GG)E=*y$hhwRKS6*g6#{qyI@S=OQXxmgq+fJ6%yQ*68B~4k5VY6Ts;RKaa1%n~C -zk4?iauy{~Nrs^?k`kE5HqUX2?v<{2#!L&^Urf3tI!^~2U)N!- -z6pnDi>Ioh&9O{h?w>3=u3J5AFd8LZukILSRAh6GJiGJTj=tOaF7C(ZJlAuT9R!gE! -zYp#s^Nu6>Qe~;SuLqx;C7Mu9|kKlr6VoiGwZc5+9>QOyOD&%4V3l%1efmJcAogl2e -zmmsVikbpE@y)&4ZDgJ8xo$s-)u=}r(8_pjn0-lT5j9SIcZm;(hP~^wT!3Opc+|`%W -zrGJEVW-wYJ=)I=JI8vH_CW!sV?w~IoXgh3UfNm}u65943!vliy`wPccv#EyECy2u` -zo`8v>KCPc0({GbtQe1kZ2|#bzD`|VDKu`Alao~ukbI#28AFnc9_(zY_PH*xoxMuRG -zW(CZa&vuZOfMdp9!H^VVqb<=x??-YTey_rf)fF(f`_abN-kN=z>5^Qm6TI{?yW)86 -zxa6I|?`4ok?!eBTZvi5!13}shI{)r`wKliMbYXCIJ`e0@aPRQ`Ztpu2;@v>FF1Tv2 -zwf?8_eNG|J)j81qWFQ_w@6uxDZ0`-ex7jbr7q0OSSV(F%>~87mzWu$A^G_BJ^47moaLQO7D8&<4KU-GzH%-S)q0 -zWXK~G?aV!ViYE(t-k0+hjMGJ?u328m}GhzC#~~|C(kni_BsufiWN2_`ILiwnEp2nZ76etz3Gs -zIlr<{aH`*~Vi)z(|ND)J@jUf@bEv$dafR!Vyf%}z8`S3RUDwfOK^ExoRMgEBFlY^W -z*?YO3mQ?X!xO(({)JL12?zz+ -zKSFQLBB3{(E}CnvKF*Gp`*fI1VDIC(E!95{2(HurSYw12<+)2xj)vmS30_2c>3vXY -z!*u+b?bax7f=E$ATMvKA>p^!AyHT^qG~VA<2{?{g_VdC^z% -z<)3n7eTaN+%M@^Rr1#cTiedyPPFUMD8;$bQpOG+}pze#lvr^-GCwH7L7J>0AKYCeq^{F7i@sH7R3BDaEXxQ;6*T7)qJM(Rj9$%V -z843?mD(sgG**o2oO*m;gj`xsH;5qhpL(k+R#r9@>i1rbHTd(<8{EmXzYbAJ$3{$7S -zaUVSMemXJPX5P*}>eCg(9W@C4AeHy{<-zd#6QiHml#4*N$P6bEue)KL+8@E!NF2BQxsasRx85W&Y*pNa&_~J(ot@ccGu4WnsNzV=sLQD8Op!0Q+~P-< -zTQmEe2R2+Y2-<|!{{4l1zg<>n7j5ny8|YjOhCg;7j4Lo}^GNt5)QpOKhkC4cZLe~8 -zSLWqVD{@Z6pT7v@{gttejdU&GkjStSf)Wltb1BYxk_9|a#a^)lxLPji-s3-U)H7ML -z3yuto)3&g?)bj=&p;uY`;#jBRFOWZI0-tLwXs$6&>PB07j7?&^Te6!-6!zMWw0LMS -z*g{YodL2~1p~9)9RrGD|{Hi=ofOnsdvjAZ?@7<>0QM=~6@XkL+{DK17%O*K5ePbF; -zM^R6{&t>+Jo?rZ8QO%%rx#CgHK;EZJTdcvUZb92O9mPHjX0pHY+iH*BLXdzRV=@3CSngmGV7Z2@j$>>`fVlus0_qoVfAuiFhK1dON7%0IV -zVoueezOU6It??fov9-wW2y^^`KQ(=Eo!npl#2sB`0h+_TFc(d6 -zJR8yfc>XizP*#z}R44~1uw}L2ghu^wh-p!6L{SAYEnsnbJ7YpV-$rl-DWh7z?C({bC70n?h@Os -zk43-g?q@4wH`7`{GcRqu!d^3)KlCHbqTn}9?+}5jN%9U%Mr3ckw+ye+`70Vt_}zZHH`UILl~fimbEPiX^1)l}E78Dx0C4Xk~@e*NXYHTOMyj` -zC(ZH2?ys>OAH$`v%-dc{X0{(V$=y14-8rt#xAQnM7!x~stggz#W;AGbjfWLW5(sT~ -zPq`F%8V0Blq7ypm_uXPztkD#iczX#A)YwW~UcJXk=g~;)y(ekYoM&VUn(MJ-H@n@5 -zEKgxPieGaEF4;T7LhhWyh5YprTK+l3QCw(8KZAt}&L7oGFifUFou}CE9zy@rIoNvC -zAv&ABZe+QPdVzU50oJWk7dUnlt*dJ@w<3=GoB2qaGw;)(TflV2QI7*iTBbs6Hh147 -zY!Zf)yEi84;$K2&Juu(}`+Uz|$d1=_c_3Iw;3GDWZ=orX=@b0%A)B2p40V}~t-)!X -zyrDOCMVZo=314aT)7~xSP)bx`yL!7(IoCpnzHK=hxvJrx2^ofE6BEnsop)NSm}j@{ -zyj`VdDsAs@H&E6;;t}DJoCAjoEPvbRTSi@6FWDJ?HeNWJnvRHf;9Knz?CD0mrmkKvR$=-e*_b90%y6}Ip8Sm2;z`hvT|CtS^D~%%n;dSnP1t^JkXP2o}WLvk{ -zo(9dRJGqvUP}sLSuM|*O%ber+-ST&n>`f9%k~gXja!g(SoW*@HJ_tlY>axcfxvgAS -zh%YLe>Gq%V)RHrti&Ynqb6sB6E#9R_H7F;N$^6GvjGxN4q-H9`MvPo<+Ss{cu+A%T -zE`q&4iEAaD!!}})%>`yE%T$eh^0Hwl)Y6>S^O1%Jh^UUDs`|x{;pI1+LZ(QR=O-DC -z`GW7#H;Sog*o^2nAxgQQ?XGC~n~?9|68$pJ+BoB?XV|GXf`95)q&EH&dTBdO+8H!J -zU@%ogX14Cl-!a_~PC==e4hq}QjWPW_T>9~h(XctKlAfcHxdt#V!Z1e>iwGOdi&Dur -zJ2Qq~owbsVy^=ggcWW$Z(thf6IKB(*k&uo9)?_x`ndlR13IlJs}6@S4#skK4%l!QGTnY@A*3hiC_ -z9Z;PfhLcAO7@}ED~t@{3;?6Jk? -zWqLB)y&xfECrWsX#UFr^*Gr`7I@)yGizfRpA2Fgt{JTDQW?4;nD_F|6R*q7B4$JLE -z9K}85aQ{!$5-5i}+;KqNh4;jOJ`Vlu9^GdsNdD=C`!GB9@?%Ql^OFty@A=%$K@GN& -zB5b~@eY;F9{}p5M5pWx2_}Q1AQTTh~E|jI8(8PAhq?|Ev1S9fK3i3e~)Ad{=vRD`T -zH#YnP2#!h8+=7% -zUvY5{=Q3>*mCU5xFNa@mpqFzQ-+N(^1j?D+eecDnnV?OK>rL&b -zpDCduWC$MlH^D-5fx!CzCs+hVb`j-7oZ>jXW9~!LaX4N=UpG~qQ|6>H_MK$n??>fl -z=#%>6^1HK(KUCo}akpmAE8l;T#_5YjwKOW$5pK6n!9em*C`#vMO<2h(YA>G8rPl>R -zcLoYw-9%+;BR#4W0&PhZLQU~L4tQtHc_Loz?mqySf6ALiuydzU%jz;7P`(dk>+iWm -z????bwRiGoYfB=-AM^Bb121cbd9nvZ1<7biCp7rO720^T6f{Gn6}&s^q@2RH#_{Sj -zcKj7OzoBfa6Sp5&ZPKHmqCW1um&D0`To -zQ|Dh>%D3vx-aAOGN3Zl0=|+V0To{<&|K1pSaVR|GznZzz4V3y1QX;b$kg3zB^8;AO -zY+kX@XSIzu9Y||$S`zwpl9?AmU-n*p+f+tM#blQJ@z5ck>G%3=K};z{ -zsp54R?6NnTErXo^r{Hkb&l|*|E9QJlsyS1(49D{B!LzV8jR2%^6e3{2$d@s6^`9ez -z!;7Uc7W*C$^N87^z`CFC^Dxu<(e4WT9;sot3X4CBIBN3^;U5MVa5+xa1?~qPe%e5C -zO+OWmUtX4XfW#dBApFZRIDF~_?cTSNv%OY0!t&FdDz7Z;@vHAR#b8w$>P -ztY8I-`F%1ME23Jm_$~t`ubvlwQvs@KnBF-rJ)qWqz&txIqj%g=7cbi&1YUSg-INPBDyPQfq;f3Lj|2Bw&iXr)Z@+~25+6_ -zs!`Ja0+V>HyQCTJ9qs-+4TjPIb3Kl5kutW6GzBDT_I~Q*US|Lyr&72BQ>Xo`6Rfr> -zr%qvDw25Tf45<2WYP$9iov#D~oxTlR+5&rzXj2R`7*?*kUiRC%-^@XE# -zW`KT1J!N8{fc&&AJkQU4eq2M?NG;KJ30TU;o?@%&bA#2Kheqyh`G*I>W5$Y2$HNFO>av(E1FU -z*AkV7ztJLj*KRd}|H9@^3{Cl~=d$xB2~IFDTIab8A4?{u6>~S2q||Lh>?9(|_xG@a -z$BIqZI#5s9wU#sLuSF4I? -z@mW!!yk2=KBSCOOYzBQyb9z@<2YG#rrxG{B+T~_Zjz18nc_d}ewS?+LU399g)u()$0&v>6tfw>2+0>k;@BSHP7r$r`){74)t>1FZpp5n1V5_FIO5rYD<3X)@wR4N>0piz -z@@A8;zPi@>ec=!J?fU3LdEP=)@eIC+$OX7^zxFKkA6QAe+qY2CVZxE-0krm^w9#uq -zE0iL~CG;$&o!_2x`>OB=$L_^8k$Ge+ekk)Q_hJ4Y0-~1>pQqBbYpXJCOVN{mfXwkZ -zph@yOfx<2@WFFVhVwmHFS5Y6a5H$>EK)_?BRbVo|La2+;-hRsX704xtZ?6p -zZNsL^bS)Ani<$)w#5_hZ(#uGH40ZXQAc29Cy-D4gr!G`)R+PFV>SUCGzIVt13DRWP -zAL~>mQ{po{u4fbXeO_|iceavz538AVs46?y6#Z}eg@bZ6&T -za%WfQ(WKpg(8(BL_;noN$Y){p8fz@7V6F5~LjU?Uhh-ys+U=Ej%S`O7yly?1P9`{_ -zoVFl^U52HIr39FhsfvsviL$Xf4XdGTbs@_X^)PCuq+ -zh3S(N8U5p`P*}oaxgC;l4a#dUV0(Ep>!9Hs%l)n@3rRqkYk>##OOL!3g{c{OFubB? -z-;p7i$1JRTWlb{(!pa01H*?MJ*rI!9THp5S2bimq!{VKT7}Gpk{z;ywJr_>iM~{Y2 -zXrnoPsGAv!D%g}mP3O+ORV*1qB9wh_u%!r%i1sYqL(9#gC#MP$-^Gh1CPG`MMK7J= -z{NrUNFdus31X`hcMC^y^rA855#0p1JDk)IGMscj!-H}qo4`LC>NV>JPF8&R5 -z`d0sV|HP4(X)Vg5XK95UTw<40!BSCK=VAooz2<~VvyFgj6Yl-y0g6q{J`$It31NB( -z$`K;WN)|SZ^b|@ZbtzMH%ob<#qUHHbbVwCuW}7%K(Pzt4pkSK90j5WaWb~4|)Vsvq -z$cB8wx-sVagMc(&F4*1t@E0n -z9T0M}F3n~a@TB4Ll^s+cM|H(%VWE2{HlZ78VvDo)eFEw<|hJd=;Ol##5P3JK9 -zK*y1^Rqa$FPN!xDDg%gw6%5oS&il1L!ejX0#=ik9Antr47KmjxEUgnyovZsB$+m^Z -zZUX&EZ4(#spE2u$vgz2 -zWPaXA^7YPK734_s({&tEP@oNYE5l82o2MMJCZV1@D8nuNeliG$a0#>6rw%%SH(wV% -zcH~ts5_=b6i_97west2jF&Si&8%}i&WCMcX+AFZ&3N>}Er8O&yCB%X~lA|*pPAZHx -zzI0fJ4KkrAGY_(tG{_()z)#0T-qIvTL%XAo!>NEgTXn|q_ggeOWWYeK;E$HuyzZ{+ -zzF!|&24XTj)~!U)je~6|KIuK-tfU@h_C^7&)AkQq=nl8_Z-X(VA{06O39LD(;-j866m##%2@@l -z3LvpH?h{!(ebjN4C1mwsWfEZVY@7`!(q@t>-BWJVjKTnBnFjyxYcwptwkwl#jG(Uy -zCL7@~Pskhng#F2P$4a+?yUZJXWn?{sM3lwAOclBC%?w2$#`F>c;3kdEm7RNj9lt9( -z=0-htA@B!J=z{CWC;Bd9X*gO%4I}5{@BI5||g -zF*fol(LD6k>v>5zxKtsS#8mA4LkSbdaL$HoY>rfnQsNqYrtB*{PAeEY=d4slX8Lwg -zlvDT6KDWHS2b=>m?N#SFIKFCP^=$#JL-;7_X5;2pLjQT|MA -z#vR{YxcASa7?#iE`i&G$wE28&h5Jp2$}Rj6*!CrLY^gw(XA_v(5*=ZgtQcKtAE(dX -z&-9Y}_%Bs5^@YpK?d+uhs0J$yP?uUNT%cST+FJbVwh1x+Z>og;zf>iO4hIYOcALV$ -zf2ooazuz6;=%2X8|68gA&cQofT=U=L%LKI0=_B)I%fs$>Hxt4*z=p|LQK@xQB*&HsfenYQ^iRdQJS -z|D{TPh~#%zH_dr1JP4aUi2PVGpZOXS`iB2MR0+|DhI2*m7Sd`762P;V#AJl)Y%=FP -z_<2WpsQ+h!BnOOa7KO;#vzR&=gf{9hJ*~vX!ySY~5)cFS`x=>-&%sx}?k(?b>S-Hv -z=AaT!h--;!tNM#}Q1A2V(mz3yiMvz)eAB{1yB~5O*Sfgh=}i-YQqz4*Vp`SL55pmVX7n5yuJbty -zC&$LL6h4%iQl7O8C0qN?-;5llaGoFRykEDv)R`*EOomw*$#PY&E6eJvhVMh{b5Mk& -zS80vpHU1U#Rf%)bG;~Au?k37)$aqjkOTLvB>_$m(w}R&Ncve6-fW2d$%+=qn2iyp0 -zE-Zk;!RT~f{+YZl44p<I}lFT+%wpp`B+`Y8Ce46f&dW -z|HYW2(t{62)^LBmu{Iqb^lqQHe9*Z#`QAobzCQ3U{~dd{2Q}OMfzY)Q6%FZ>+hpD7wZ6dEI&vrt*sDRtNvs2Ks2=g -zCk=2M)(8>6m0G7_`8(0(B1pH<{mVw;&S(Z9s1ULiJa#aS=vq->X5xj7r&LeAe-X?y -z##ZFJeRZ`JAQ4%WwpAMAxORBIhqw6k1;&~YZpZmK{bQlDHmZlF4&xR0H&ZwbqIS-> -zMS$kQm91K@aaPr1FcZ3RmvaSIW^?{1OG5VPTf8sl(E+SLV`Xu}%jBcAaDI?F7g>>q -zza&8^^B|AlPX|P>bk%({&KX|W7IUY~er8`Mx>us+*%w;qS4Bvqhij+&Kqdc*j$&PX -z+Ba*)`>pw*6E^gcEs6G%ZnGpbJCy_Gs(HAG~pMpb8Eo!gaK>uPqJkFl@7u -zdqlKb@HT&>UCiV=`AkEP(TZ>bB*-;TF8F=_fQEHd<pZT(S|M+95v_FVj(*~y{V(M}PgS_Oo)HzzPPt4q*P-kgr$pU#rwA>3sZvu!U(vl>m|Kj -z%nhc4*irjN<`DwA%kGH7R*CO#Z3UyIT -zWyx|(l`<_3fzl$apW<2ip{AO?atlx>CGI|=BocM0#BX8Jiu;-*G@oY(Udvav$x01G -zpq8{ScsSVP+GzNSZEogcQoince%tz7zIzdO+dZEJZyw&%>T#Q)t8V1>oZU#*GW0^? -zDR`t6HH1BRb-j<4NsSg;0jMCD##CibP-QI;6%+0uoTep!PA5zsku$L#;9F-NC91I> -zOc&$`i#5$TP9EzX(-Gj%tL8JQ&ak0Ex!jv$G0~^$Sqrj6yT4)gL}xY*#SiVry3;SK -zIkBL#t4<||@IZWwltLxvbtKg6-=>KY+424 -z`PoK!;@y;nwNsJQhl}Zb;bY0oQfRlKC1{|kq36~}e0sTQL%po;Hs@(c+~(G56~!b3 -zGYMWK$tTaF*9+EivG%DYHSV#=LrVQaRd@2PUao-;i~Vb(WuVdPdDz|DL9#O8Z^s=xbDHQ|V5Pvqwr -zt`m;cs-d&R=Rq1ggz`C-`OEPmbhQ=+KsS3;RTe@`LW1H#M1`bPh9aN`byF%ou6aim -zbTwekm(#?8XjxSjmZOOITjtDiwFsHc_(7|gW7UG}FO$-cBDMfs}&<$9KuWQ34rM0DA>*2@B&)mcJu!MP(jI>X(>bw) -z*M?)oAb=u$0}l~L(lkz_>mr%Emw?i^@4v#a45tsOk^2>3^2I$MxYpj_L#FxMs3F|I -z=x&P|8}_n6(wiispEgSTW+fbf$tdiZW>OVaY~i~Z)f1GK>k-ED_HK&q9lO;-5uXSS -z-B|r(yRzWcZ9dw*ld1kV=d%;udd*J$lEUoAUq}Xf8f!ELy;i8}Rn~WqK4o2AdK-Pe -z)w|>3j~yGk36N)1cOU${o%V-Pbji?Z!H)05!sbYIvYLOWnpAMNNxZ9U!c1|Ju8nSs -zU(ZNJ*^h4`^5eItV#-lEd%3%%l4In6<%;L!hpj5svBqiuTLX@{xAl_&v&TxG=kM~l -zRm+LAQ2pSheI_R2qL-+-T-RD1NAz58HX4W8?92(rauArBADZ|aKMfdb{`a{@AY*}m7 -zupvF}ldCS9IfXSV0<9O(WYiGO(o3475um+s0L?y5%Kur(E(v(^RX4+{!*Lk8;XC*F -zmo$N-fh+Gid;9pzo!iby^}wd8!;nGOPy1~B-t!?{2X#gO68^bHm6wklxY4U#{!AQ- -z-uK$MyIdmX%-$@((|(?n366Ih-XQYJ#Wrq$?vicm(Vg(MVcQBHJWv^e?67~e#5BmY -z{bGq4sn`vvB)t`my7#(`V7}uszcAwDx%zm5(LH5NK4OxUe~{)>@*X7|;>7Gsz;-C? -z@@3MC#8C!-xMtMdpqq>S!eH2Sp`+|{i6 -z&+CF5M$`m~t2bo#g!-M>p`A+Z-hR{V%jqB_;Rv1jvkQ7NB!7d)12nF=T)lDlG^m%& -z76?F7LF(RVovQuVij-DLc5b>|qu|u@37KI^_yu)mP0egsDP&V^kIxt#HU{t6HH1v{ -zRrvkF46_{co@4o#3NESFeXvpF_s3nd8h5Ta?0)B$@aHKy&(!I&u>V_M`C#Uj)3>?5 -z=G(T>tWah2h>)HYWPEeJdaxL%{I#s&lDu3r>!*rQmJ_|+`g!YvkA@!^t#hXU)t9uk -z!j^M72UZDV%mIHcm3s_*H%4_%6ti6K_lH+!egs%Ecvr~hYEwkO)Ibk3bKTCoKydTVR)~Mq@%B%d{k9{za6pEBQ57KYr{a}Y#UT#hZy`Z-;2(5oGGef-l -z)Akle9@OB=V1T7kQy19)4O?qxpu#p{*l6gfr})iJS8dA= -zwrdaH#vy67K;8I)0ny0BsZze-!Fd5ITkrna*zc`E5d)1r?_iNHD00+uZ06Ka@Rj4~ -z#nM;68Rg=@;Z8%kGaJYB+O2{=E<9{vn?RRMbHKbCYe%`#_w=cPyh@N?ZR=vW8m#h- -ze!ti-_ESdO;HjJf55CGBT_;tvi=lROV`(i~ak9K~=>#&8-k*CrTh>kA_ij0C{<|q} -zQ%+_H7V+8w*Ml{w;Z3=C|G_c;3vnL})(keNB4&^BG&#owWAr*?lu1?*mTw(pQ1tB= -z11tV8>o#@J%pqzfhL?dgX4TR?oV868SKFAo>4<&U2oo5D;hsF-_BCs -zwibbcpweC|uqsEK1tQr0n=kKPR>jv6Qt1)Pes4K3I2xXBqz+<|bU;=HXgi*IvV_~7 -zUGU|7{<)}!X2RIo=KgM$EfX13)KqRnbH?|nNPBr%Jx%;@!74YWO))ITNvCqi&)t#! -zt7+LU$hyn6c^Y73E#9m!%;E56Is}`jdlz7J=4th&?X>h*yz2KoaxG+4qn%1GeF<+V -zh)bzV(zXHxs@{QNpm>IoQEkdG8J-IxqO}83gXUsa1 -zzmtB`WZdFk;rA8jWSb1MD(U14q-_dn?BM*HvMBF-_w=^vw7>Wk-~iFj>PTY4Q_7T$ -zkh7|&kBgVptzdt2I`|?YEbQczHQC -z+$GX~5#c0-bgVfV3i{sJ?Av(@>w%|N9XL@qWO=&iExb_;}^8s@(N@uvLtpNiHt8&3FsJ(o`%4I!W5YRXKD(>Di^gjxmv0uA2~9RRr$KXEP=~3;D{r-qd`#_CS8J;7Z2y>Njm&IhCOlcB% -zX*ZJRTJ;%gUS8dLuG>_s*7k<;^XL8P(D_?{rLB{lTX}vSLtahY(g6Xjus7E_E@pSS -zwy$Gk?36xJj>VG802*TBcFNYh6l*9Lf+ZuQdk~>$hPeOKKZH~gZMNO}ZPF0vZ?iw> -z(#6HWWwP(Hu=DAKxJ{|PS*kdvUFi{nSgS1ul1#+CdXuAp?=O}m+y(0_hPdt?zWKRE -zX0qtO;$!pkn;*VxnTBe>EU7bC8rXmg+A94-uAFB6oQ*_7mXu@Xb%*z12XDlOCK4ie -zhRT8uqS(hrX!ce{tbr7CQAcs1hy8AcDX_)b#LH&M7ESY!Dfv2k%&ck(zS`J3Y5$kK -z-2!=<40)QNgq-VwD3`{%w950spObEe&zJapQMoR+F12_hGnjQTcigZtrcWS%3<+dy -z&$qq`_4gKBR47RFx-!aByUX-U;qLBSGNlE1OffCE -zMW>Yn&2n`IOGVQ)lUesu_OfEQVa-#-VR_~I9(&WoTpd!WzI^8GiHfVkM936R2l=*) -zc*XmN?KhBUraKYW8m>Y$3q3c`nT2KV%jL~atH6l8|1P2C7P_YL -zY_*wl3LAJhiNsXsTiw=cTYDYWRP@+A;!e;N$Oss0kYfb;qn$iPWHfyqSmSg&&h_!< -z|A(xvb?wLi%0PLqe9$`cxM*0f&QBqdN8;RC|Cpk;IvP8d6JESEIrlicRUCx2K7dCu -zEoWC##`A_HYDT&iz}Kc@405CGT#2QsNs}@YZ;$zWy|$&D+fGt%?EOPHHZh9KT*-E! -z!7+}$&4FZZO&=*dQ|V%*9Hqcb-=JEcA4nPP}N<8IvDAxbc$5uwQWgtH!RX% -zpAk(qD(&*c6=Vj!Ou1Fs%Z%~OLu8<~I0^Y$Id2E!RHu(ni0(ALDM0KaFg#$6@ByG# -zVh6sTBwO-0Gi$@yTO$hw{^Xf-On1ehIYn|065jqAwxz|nA$l{ge -z()mQfnENqjQ<_$Pu_y3gT!=G{{%Eu!NBWY?1 -zrau_uXbPcbk0)1XlhN$m^elgq(w1`50F~pU)&45@!e^HjntO%g^Z&8`e0xg+;m@)`8>pt5A|Z_NBh~@Se6{t -zt*+$^wk@PhC%=Eu9x`dpXBsw?`2{4atb<8-+c9t!XjGpxfLfqC@kb32m;=D^7+<8m -zrM3$!13f1N(2c3kNp0&clWMdR@5Mx7O5?h+eCkHs)a#~pTS%R*A?!iK(tsu)+p^eqamxnkI<19e7h0H2L1icDakm`J> -zpW7nygS>2kx)W?W6TKUp?FWCyJfbh{VDH4KyxbJ(18W_ovRnvWY3H2GIAZnjdPk;T -z529{9R~4y{T7{!b(=!)C=ZvE7nJ*rK4lbBMyR@A$ick+J&V1L2EiL0!?mP3Ysb3xr -zku#T42tWAHHY9B0e{G*;&v4gBErZ;|dn|x-eF4YPk?xDNj7E&VNoncYcxSY~-V36S -zwF}?4ieJ6@HUIGTQPX7-UYF1ks)qt0l<8egrvp~14!@}7(z4Q*BKHj+OzWb#=>r+3!ACjdupHykQSYeyeUJjNoK4l0($f -z&qeHNPO-B~XVx^AL#tDAzdCHEtm_*8wN|6e9s}YQhPI1sij=ol<>$aT!`Vh2FS3KL -zx3sfseB<8J$P4MJkQ(WSE0(poH;QmB#)*!{4e+=95U&lAHvL4KC)#4}GF-RgYt15C -z=-no-wL9~G1T{m1w-1s75&E_Qy}4o5G+tf<-`bYEd90UO5WknKP(iw!h)0I1DA2)k -zlxR*KD_$hJ19l_@M?|ehtH({c(##SWTOS;ksD9@Ysj^k9X-p`D_vKC}^8x04ayWMY -zUdP1C`OezLWy38!e0M%u4M%)PrZmE}`9uu4?M9WJi_-emqvTf90Fz0C)uqybdh}aP -zi>F)_9Zubkju{ -zRgJE4J|#aI{m7A;Dn|EpV>D=MLA8-7w7b?Vv9)pHD8Ry4ZHIQtl4|atfqK3LCeFjn -zMQqaN4d33Z`Mul5%S)hIn=k;>K0i=1>unMn`%rs;+Hi=h&H0;#2H4h;{MNVt=gjx` -zmv2fXH{VgiRsMFOBZ9c%=Cb=;x0$(ya!!WcO0Rx`T#>h79wW^rj@Qpm_sP#Mr{!>$0{?_w&)Z@ -zSW{Ui#eT$`_`{KK0ninuw|vn6`Pk@toI{c-Rk4u8CB(lJ^CFF11fl67N8&4t -zcqT9X`ZOVXbtTKI;mNZ_##a&oq5NN2x~3R_R1)py!osvs(7YKlgbxtDZfUDRC}b|>Vg`kL5-pRWHWXtQw%?|c6ezn{P2caFzGW1ui0rbX)&erwHFfOj5RaT -zt_^&)kAChgG|-2KNQJH`3fpTLoGtnJt)>CSf2G?ogHN+H(rZW2pg)m8MdiDv`{@0{ -zV#RZv_U?M!PW3*I_DtU3wTbgupZ(nn{f%lFS0&D&c)H9^7Vlp*?-b>v6J%_{oeLFp -zUF73_j$fOTYQ95S;aYzbRy6mQy=C-ds<>0=vKgMSb{wVlhK@dUmlq1(bh?~FUaGy? -z49Fe~j$Txz;`5cKALr!0$Uk7Av80Di;w4<^TOphbb5qO91$Q@qs?q$uWs>Y{LQ(6l -z6PVh65*DN=c}{qx8x?{FK;;(UMM182?7Zlmo`@+1+-GFH5bhL@4I%nfuoaMA?auCt -zhKAsTSUrVe7jth0tHFfEnA<++DrUfO1aOf&cBxHjqLDh&-&q>H$fx}z#1-N2b;)}u -zEA{m~x~SPQd(y11z2<6k4?8?xv@@-F-I%Q|`>Um4^L?dJog4u(c?308ka0f`C>-9* -zd`4Jz^VhuXn%jx(M(09;ND&Wf|2;=YOMSW#)3?7^6lWt^TYp?xzWTxzQBi~XTD)6* -zJw|}B-WZ0Tw=z^&m~Opj?2dd((_2ty+R^_h8`|vKq8Hepr_dT(Qcf8ifK=x3Ly -zmPx4Wk}LdZ^4XXw#P!rK(_&O#?%+?6*t`|;xK~`=>Tu!ouGC*-&RFyZ2zwqo6a})= -z#&@(vx6c+^*EQQ}>Vo-ksKHx(AB)q@lhFwBxk&OmovQ4e4co}+Xy{)o&#hNg(|?qA -zJ}NdvNg8koXJBQtL0nJ#2DA8#WH1>{B$ylkUHlm;%g$fUT^aKg(c7Vr6gzeT1<}y&8XW)NP$#>R$QMU6_fZ>95qz6e$G?|QzW&nfQOD)7-jhwb3$uFbZj=Or&-RDT^4du+D -zr8RwG9tZu+>wqJEY1Boc1c`F4>6CSDgPeiMMiyVPHM`i0aO5Sq?H^5qm?Wz&Yndsm3YeyBQ -zmF~yjqG;BMn2L~)-#?fyq`w+yk*v391l}d&FwhtL(Ep@WdHJOy4~ISclRbW+p>NB% -zWIj84ba^}0P4VP-dQzP-3jys^roC><^RdmhH@3x?Wsono7N1txUA0Y3>2j^E4Z)!u -zIrgrk58i~u=v_*YO;2*eS*AV%?#bz_Y-4g8To?+@CYYGHga?1ZDumOy7IAA^Cz`|noP;58*IWU5|A9WSlTRm0&&O*&(a5cJAZaR=~BG+0Lp^i@W+S^=~zmLz*7l3Ig0&v*zO> -zTH>jn%PI{SE3|xtrDXRY*WKT^3Ti=B=n=O5A6>kv#Qy16mj}^(h?NDf;sEGn81iur -zLgz0NuNJkQ?GS?}7RHuSd6o-QnKdDZ$$(}(7h -z)dqW=58tnAweoI!^jNyY@;0vhkqRc+p=u-8)$a4t$&+QR11F`%b-x*nu0BgmY|%$p -zH`}J?YF&DD2|Qt5`SYT@g|dCn%=7lo4>yKwJ9@06>Z?8%h1aA|Hr -z95e0C3?4CCe}8+Tlt1jc(xSf6x_Vqe;mdNhOo^W8Hly1owpr#?eAS+qOGX`#C3K!l -z=)bSp|Jhder`xmJ6zjB~36uTf$DLZsp2{4~dISIDp^JNNtD-KX*bJ8@e6vqU_tlW! -zt$8d6bv!_JOu9R;oPZ@@_2^yCJnv0chGfjd=$S9al{S2FJmV`&%X;Z>;cCeF*O`Wk -zlsgR=%~R6s$hgo3PkTf3tJ{v!kf`;K{5{)#uB!F;J430oM-`)XHf81oD;cjdv^^lU -zcI*eua^5e;6XZ?L1&^8LpW6sB)%EPnRxtaxa9=-v?`bK&rK^lE!wb*PqH11O7}cHc+qo})CbY)KCx2kXkgp)0dp~vmJq%it)py_SSM?ejb=B~tOIz~} -zm+PYLKF5E$o?~NQ*Ir;x?)Mn3vxIy&{@YRv)OX>9Gi?Il<)rH0vfW6g -zCig#PS7lwo7*u?J_J>7(oC>C2|`RM+4jN^<^!3zwKo{ -zEXxk_d~l5F{fCR^*&y2w+2ffuXzb@E=cUe&-L6Y3&OtuvHS#>yDVS>UVfRK~wTJF) -z7lWlvb-%XqQa?Y1Nnv(7H%rQ=>c7@U=gs7Gm!qeco!-rozRCKb`e==ryrFXR2(!(b -z_JVOdcsG{w{;tXX1EoO)FK}T7@ypipJcOxgW&Tm9jm>B}m-jyLEtI-)_HC}5(>Z9M -z%85T+4#wAonQ3>#UR=76|F6!4xrsk|V{O& -zPNw}$%gfFR*FwJ5#u$wJa-jZvXwsFqcjvJevR73e{_a-h6D@xXV|8s!4i(&tH&@x0f+w#Nt#stsFUtsR1lgHNT -z3BOWu0*y;D+S0=OPTYj{PnI`6_5Wl6NRNSs`f07)JA8E9z`wtET9kW|wEDbBL8Ies -zxfQnea^rIO?bhx)wR+1R^s(mz1Jm@-<610xzx>H(lAL`iHtOBY?p;}L^6nWfW5;u@ -zMIUgv*M0X%rGuXN8Q&AWRsRumm0LAK`UEMKqmjPzPBXW!46(D?8Nn*(+5@Up%C98L -zheuZ)_1b>aJCdj>JPPl&8*;t(YX2W+)JE6F{lA$W6P}fE)o73ZSHJUtHg($!lb(7h -z!bj3#RBd3JZQ^c(W=|tO(xC9em(d?R{sC9U)n|sK!c5CkscNQIQBzBs-Bn7(|J&m) -zr$enhITzn*>m_D-Y((9u&*FpjUr5YV)<+ -zAfKfCun{75WtEsPt`8@>bs&_PUbE-UD>tFb|)q7&A -zW*|Q~#Ud)EA8p^Cn?9>fw&)xvn$Nrcb?RntGs<0kJhM4$#M?&UXyTP@GEQ{Si^!qG -zY?)u)2=XSe_ib%7^f(1i(rTyI-ByDepH?EvPK~5n+lKi+PF*#Y-(ZbvWeW)pyX};d0jOr@doY`wd(E>E4gc{@uM-v#vemS*DNc{2cyswuZ-|Cr51@ -zxvJ*)_@okL^870gmHLpo+P^EAKD+YDqt@3mcbDNs`|8Y=Ix~mCyAB5@z}Djnu%W)* -zcl(X;2D8Z-MBbyTvd_;en@p$op6qfsX#JA)So>+WO5HuX?2IwLm9^H>3xlqb)YBaY -zp4qPdN6p-D`l_4nYRmTn_VW%66%ARe45uZpNd2|Yu{nR$`T|X@?~cVM0%7aN4YywE -z9=HvARH~3SGh^zMlKy9XhUSVc`vqQVYA#ITQ2sn?S7Y!Kv=1BI -zIUI4rV1jQ=kY8(yYUD_B=GBR>9Ud|VJ$GS_&g5flZ_0&LNjI53--llan+$TQnmPEa -zIq5OZ(MmYRGNP9`*Dt8bKeY8%4pMl6mGzw|YBV&Wk(oWyF$!&^B#1z!Dh5{p+t{7? -zz5lYu&-Z){udtofQf)Nss{h~Lwl`J`zM-v^h4}wO+aC45ZTqL1J8k=YYK{tRbB|jj -zE_ukU|7lQxp*Jm2)ryTFS -zqAq)nS@QY_v#G+Dim!BwKNH<_V|!*kFtTQ|x%&*8lP`&{%)=PLm?3!#gF*2|r5Df^ -zV!XMc1PfzKf=9%!Rx_Z$wIb=Ce){S6fE3tx&1%$8A|Eb}Io`OzY;w3Om8d8q3jf_Z -z%>DQ1Zy%IS=A6`8sp+^;RV?UR*|((^R) -zRM``6diYdFFriU?LylkZZYg@ab)5PLA^#QYvv$NW8rgfIUQs;^aap -zIClE`7_Q^JP-1$o&a;SFFM3y!l@v1PYPpifF~;FHF&Bpp1_4##_sKTzlbxS+_l@OF -zuM9sCH{3N_ku2!VMA7VLaO|Ad^`~1Lpw-kO6JYwBN{T4Kzh!GccEUbQJ)`XD`-~^z{fsArs#O~W8?xXE;_CwyxuzcMWGxh$5<{_j1JM7z# -ztJ&_jOwj5L=-bGyjka(ks8oQ{#xZw!WkvcvKC5-k{1Tudw6;?3v>mmG`sq0B@nf-4 -zl_Z0S9fvismi*W*foWLK$t1v04kbv$ctow}9@LUCfUx!spaCLI1 -zR;0Qc;kzTF(s-LH%yo-bzhs@Ph!D0~;THx#r$uE-l3WnryvYPB4N#+ccTs=kO95d_ycipAGxxP=(_`+N -zMF*|gZAO!cm|Ij(1vp-mt<5B8$GAXjLhp<&+n%DqiG5(_txdSzbRgAFZ$+ndMo;O1 -z#J}PEwyhp@qf74%ODCYkhq_A-zEyz|C4yT3^)%u@OXR#%)rtjHAzX40V6swe)u=N%vHH5Z3Q~Q@*CAJQja?m7wgB5_^qn -z>elUDpe8Sspp0`dz1Fn>zI@!S+G+F;R|5NCd^KD;_f>{l+CiG?rHsNh+3|(tlBZA3 -zq$YBCQspi$1R6x&* -zmo@q|lFUkJGBRjctL&JXp_`sp9p&%IYsQfVz9kl>v=4t1&UOqsK3$JOXlau{;lpn# -zb3l2{14+j_ufE^2w}!SC!&OxtN=gf9|27&(eU)#$*_z(i{n6p_04Vgy`2dak{Ji_% -zOyn&~*T%retAxh~q>;{+=V6r}CcE!P8oW2x)G!^f$ymr7>!xQ`-CTCxYJD8$f8I$E -z<+7Tq)>p~5S|)mFp72sNwQiF(YU>3F5UW5o8|aoi{vZN$wk6=cWy2tW01ucw)e?w7 -z!*cATU_koCdQ|)6B^&*PS?4E>!53|{*?K#FwUBgWj%3i1!H-WFYc&VruV_E8w8(jU -zS{qaDs?m2ykX6`;;R-V1PtY_fiHa!J{!YEVS6???^*Kjg(rsz^HRYx0MdxXt5n#8A -z5Z4tgObe$0)SLjQ3)MeL|4rr#Q$i(&0~tghXcf5ewpSzFx~SKznRD^s{`>v?r|M38 -z?R%B4ztEoYQp=(1QHUp0%l4@MH{?A_2Z268>iw~x|-6PL~m*xO8egREvkT_$BRn3rS11ipE_1GSRFLcFk(#aM_+|p$}T}*9Sz$&^<8>Ss7>B9Wpu-vidY=TOH%)Dl#x4-}V;P$ua -z{C};B-rm`C*2p%vqNlBWIrp~A-H1E43NYH%OLg-_g(ce_CU%Q)&z8I|Z#RjWn+1bn -zQ2mxfX-=ZlB_?3EIEYj-pd*nWF4pAqLuRG^pmBg@3Gn!Gs~EH|yoa`hq9O7CUjZNq -zw5ry;$e2GV^@kT-$PaIP=i*Rta&N+_o;$il%f4SOZ8Egv0p7Xt19Qowp!wR2+vRut -zZ>mBkFJu+*o;O~OdJJ4uX>;kKqGJ7#D=Hlcrp3#qZ#?EMx!GAyIyZLy -zLP)wV6@b64cJj!&^#x^v1kTx~m)a6JncGK{b3vsZc|f=X7M}#XeytMzV$T(71-=mhyf6UCb#W2^1HZd`axpddRBN~P -zt$o?PwB)!=PU*5*QEx~4ql?)+_HTlV+?VYymCZjLiQ_%Z Z1tvmwki7)c5z&zMVATre@0+C^R+aQ;+}=U4{e2+ -zoHQkOSM3nXfCv!9-B_FBA7HX8k5cd+J2?0UnfCoJH1WfRzQK3CzVSR=r!p$pu;PiZ -z`^J&XxW4Mmh8mQ^`hvsqnVPf4`A59EdL2M{9x9FludTjsHjLC@&T51V1>cRj+37Wt -zw-;wqM%|Dmnl8K={?eCo~_=WEf5D(%GK?;W1i -zT{6zE+MPfvN3|SDZ@lDm0yWs66W}ghO#0OKc=9zl8yR}fkuptxhg($rEfZCpAx{|) -zmFy|hR?W3~W%WJ(R06H;g%VL)wc_|U)zDU->>Sjw*WG>Z%3fM|w>q3!))1~==Gd$j -zY{sgbP{<>Zws#JNTSVPV8)yQt(N~kYFQ*e5aS^gjkEb`5H9{jmujJG8FMWAO8D`yRIEY{q)3$mf~kHSCr@rE;E{NB1;d -z4>2!ctl7Ep7A%$vHcCgbQQI;ZTj-W$?y~BWd2QOeTzz!ZSEOEMNRMm|WqUL`DATWJ -z!1MP>tFNznpWEQSui331&+5}kPu+}N&egp!W*^xjZ{s3^8hpVS2yV}i@s#WMt@N`=z0s$0?L?82EWaKOCG({t<)+Opf0P#v-tmrDvujoL&wml`sUE>9 -z?!LK8*&h{?C&<5bb4y-6L?my_r0bMK9Y#S!@~3#*$+D>AH%;(l6qh@Rj!H&_ilV%y -zM!X0cTZ6S^+J54pcZbwas+Ns#%kcV;G{(QwuV_uoa^9ecpZF0StdLGN(qG@U}8ABAa -zP{E?>3l7FGh@!#5B~PY^e@L#-(Qo-w@On5T<;~6 -z+8KKNEB2o?P9n=uc*33>+n!XE*Mw_k%KHuffSA0-Pgv5%iPQ37B5ukTcn@0b&x|OC -zN6Q68)tj+@qpgUh~oOBH2;hp(1#eMhbz4Hsv?y|U36xJO6 -z17qOi^Y6c9o)mCT*&C~N$VF*{3-5cQ4z6mvJ45WrCq@nv7#!WCO%Gq0K4 -z)4M3|={C8icZEn9<1jT~k#nGkTYnGncq`Q5wvgMRz&EQU+DI82$sH0mwRx{SH%UmL -zLHJ|^Qz?=@!-p6>^W;io2PEKRgCMQnWXun -z(kSqF18Iw7-OZf!9o!f1#}FgftERcHRA_Q78sV_9M(^sc1(bf@^-{-(+-KjRIR;FY -zEv>L5UjCZSGRxNMV`lun^YrIfwzQ9#@i|xY7%W?_qQ-|$QVv6jz9+ -zqjy(4MKANtV_I=sqlK$iF|ET27J4hek9wxJ&Z%?00cur0V3)YykD(Ar?A|%ltWBhFF!+^y>sZ&8; -z&0-<`j@~cV3ZMr%L;W2?amE{*$}>+P9-8QHs#jJc{nB|n#SzBv3I8ROD7o2rZHXGW -zWcLedaGf5H_3XsK1$2^Ur(8>Z}PR;3`iI`!(ToOQbz5NIc*dSTN@| -z^BGI}6z!rnJv(NYS?=mjuRD_&-;%9sXNBb&OwEoN##K;uCgT!zCXraK0iAEK(sm8k -z!wifGGR2iOGz?f2N@1+caAlmGp^cQQR|_?aIeo=oWOht6o<7*v4PhR2wF*ZE-lP@F -zNL^eJe^b2seR?s{UDj0<$6ni?o2{}F6m2ecz#>g5B7E3TS~b)^>v>mO8f8g0KV-z+ -zBqEplL_RlLMedExl1uK6_t{CQUzsf3l8}+-h4$?FAZuFjq>Vo&gfa;#2^n!V;iCkV -z;~U$G^@LVF&_S84}%mBl@ca; -z%4@TNMVyf#xhmmTdz&O9T)kjO3%UO5T$5n%`(qiYvw8s)XXXcIdx*MHg^H&OETt@M -zFj@Ex?&AfE`|JCY49(X|2}f>dBP%@H(O&~I;9Kt}pYwL~Am@0+$v?h#Vs+QfDI4bp -zdC|KnH#hvGj2(_BK}%n0X)aKZSMAV^C%M|IQMC@7bf*eePTe~)^%HcmTG&gn&VT5o -z;o!v4<=$JauG3xLpBor>um1Y}B!iHyEX@pZsKs_K;Xshe)<0~b;7ZW=Dt+}B+!051!vw-q87;k#jQM}Ur -z153Z@0!)6Aojt5-p09U}$Jgd6CC!IIQ4I-J!b9%*e9SDEp*)q{(l$;_2n -zEa~Hhfgwxr?Xv2qtM4sGlTWs8VPDCtDF!XA|toTD;BBX*Cj156F-IX>3d5 -z%9YwlKX%@$L9hUS@yKN<*H^#u+Q_F*%X}T4P2Xn+ZK?R0yH7T0fwDzpq-lafk*%_> -zG}9Jb$2*d~eG5Ekyk5B2n=vi1+}tfLf`+1#Rl+;nI!J^tlEQn1T -z{4^#9_6a|H+*P&3_gI;pYdFN#^f*{2vz)T|`l7Mazc9iLb&idPZPZQ90D7<#GkL%c -z6;-#$rzsbeAKrRqqH`yl7o8$sXRsJ&Z*Q_#fVoFyyd``%jv6e`neD}!0#4%fjDzzF -z(F~bgft}V{)mXq)caOb+|2({_@Q6F4%a@&>U!rn)+0^I?*YHZ8A3pZA{4dqKV<~|a -zChbNl-^PE{XXT%nAN*B+=2pzfzLvW9PbM+G*Ez?*A@1dhA~jnqh;6^{u&h~f&lZ0= -z;A*p0{nARu;~KhmRRy}xg{YQaC6Qr*^htfjx}_6!XPqkkmEv$9 -zQcQ5St^{Ng;~W4a5Ag|z0Ry(R(4$YqB;yl5eUxPIfVJ8Au9fLc?r3ENplI1K%_O|W -zk5JArfq(xwQMwdZpsK?8VtomBqQ~R?xHPTbeDeNk;KelQS4E-YHt7#mK5r^o-I~we -zH}7a8Ti_({2Fvx6Qm=#F}JLJ2h#Z -z9XHR`flj+bts)L7hBS#Pp|~fuib~@fQpr^R6A08a8czUtQ_Fgcg$g43&UI;Tv6X2$ -ze(m7cdUp(Cv$i7)QRmT?j5ekO$A}{NbV6l3_ZNxnZYAAhmCa~k=w(9&Yd -zXzW}bxT39w^D-1_F{a!Uz3(-=sd8ias)wp!qpKI0@v7Ls&{oohvFU^&x^pp25*q~; -zwVAuVpkx<@*jPZpz$Ug&mKrgi{cSyc>K}ZPzq)kkud!g)=kY!s#rR$<+wfd6xIv7i -z^5dR$ZG_si?VdcvbU0$+dJ>_&gnmSd~Vs?S7Azll%F?tDm&BXQ^G5 -zdIx7Uync!+;&?Wt4ixox7`_ofPJ*|)I>7ysdD7^%e%t1!eah+!>v~(Hs|Ob>y-scg -z>!NTEj%UNCZe0H>W^+&qB}&nhZ*C4-2-!0vA~Uo*ltdZOa92}&jz)4Bi=Eb&#`9?@k1@!6ml -zd{dy-zAlZpzgmEtNH&i8YM2_xNj64PQgl*;TaRQ{#N`9YZ!{^u`K+pAhs%uioe-*T}t?_~k}d -z=~^LD5ny`WXc!Sk$-H3zBNEjx*=1Vl -z@ucwRE6j(jTUI`}YG=mXjEv-$mfr%o5Aq{JEz2*cpGehE>iLMwk}Kgo9e4+Bf7(4$ -zw-WO0rHWgXyUMieQ5{K!$-2kLAzr%>X3~pGaaYN8X0UY9df-<>zI|ua*YJ-h59exR -z21`F#|F?Rc@_6D+hih5CNNexck}d}wF)Wimc5mroRUD?SEH-@js4e)$<%O2KoU!Xn#gqO!?)vf!^ABS2khjVx -zRrc=XqEy_aAa3QU{$u`@fNXcE-L{2s6~Xt0JV+Oy0a1i&d2B}H=v9#f&Wj39tBh<8 -zbsdpS3wC|8v}R7NBls@5h?ehc%?pmey6}&p*oAdMANz%Lz#SYW0_u9Exjg@fKZe^P7nG0S$ua -z1W<&l;{YFKjlen?grzw)i3ar;S&K9ZXzq~6MCyt8mZzCH{e9=73GC(Vucy2wHd=I6 -zydb*LPEB&*_v26GVMG#2hN7er%OUvZJ{HIZt{y -z1D}g7n@`y|M&}+Dl}UIp;NW<1Q~YPb#M$TcRk*>*sI)>0@f2Tly7m1A^0g+YU}T#L -znJ{w|bV%#BNd)nqsbgpRi<-Oi%044jL;y=X@Odf1Yr-1eJ@i*abj^Y0wLB%l%&Ge8 -z>_ad_BJ=$!rLZk}Y(e@u^%Nhrvnko5acl#`_zZ4b&u<&}3{;(2f!6MGYH9|Y9!}afsFK1i<11FC2rCaDlNq5-u1_qQY)!_8S}mHUL3CE?T4ErR5JRJ -z+x)PsKSQXhFhr1o!!SB;5zqE57O9`TG?N=$^UMgN8D+Qpx>6_EZXhW)JUCL6Jtp2X -z!h$vr&KUdw7q-|Y=&yEyBWrrv5MsB^=$Xs}k8`<^6_s~7V>-pu%A@niZm7p0DzVo! -zWm@^7oD=)c%oO2WjOG;fNh9j+zpRnkU&T>vfkrpqdj&{-C)tNFf8oZuU!Y0RrmWAEk#?4>7H%?6qQbA(7^kbL?v2MK1#l?usWA#*7?41Mjfz89m`PgkUT0oV9Tge9S|e#cRexQxtzO(i6^2e|LBjE${LN<0CS@R3Ht6?S67I -z7b0WbQ)${I1)q@~p_69M{U3ch>@!)Eqwg0H`G|oXwLgvG3*wY4NKGg6nlEZ24Md-w -zd%@36r9GAXTyAvox0M+?=G3pA!DH#qC2s?5YVqky_Kl$5!ng+Ke`7EED)mTDq>Z4I`&2svWaT6~|m&@H6EK=FEI8-a95FqsY9%%|QJzUQYu -znET7vTV0Y$r4v>*AXsPIsFMdMQ|$j+4sglKq?&lTL(L9+U+~)g6ujgH0b+}M`qcGQ+U5?Fg9X}Pep{Lcp>J;L)^ -zAO7-)eov?O-2Zfg|Hqob{9d-wh^uU&QBV{SSEM9Kt`z>VJA&f&@&$oDoU7RNd5p{a -zZS&u!Xs4w3osvJq{}S!u?_H6eQ2Gq|9r5M=@tt#<|ltXgu4>|av9y*HqiE~!#KC8MbylXU`` -z#ti&h?zXSI5?qY9N#AbLz$tu?#m?9RX-|yAy2O?3tq;c0Li5$AbqT4oP%P@MRFP@r -zfsz(7;Cw*zJR@00G^)MvzH{oT*FcGIng;O$*YZUYcyx!fs>;P>4!Q_;dx&|J-PhN@cRrs%>ZGM}ugg>^nRZ -zNCn{p-ncR`BfQ*7feL6twp)yqB(_Ct4q@4fomfX1F{=YI$`+cz`N^nJnqIUCohd>| -zxcFO41-S=i3m*)OjXx$^F*r(_7DenKY0-$tx&j+;i|q559Q24eLX+N39u~||d1!%a -zgm+k++2wpB2xMpZm;Dt -zLmxPrHoC6P-vT`p=502BZ~|YPRll#H58Mqsx<0f!*Ag(Ji@2z*5z!yxBKpXbr6ZWC -zHdYmGsst+G#sR}9%HBE((x{yEk*9DS-ODQr)!!oAqjpd?M__lD;x*+dOGm1UPp-7J -z0V>LrF8V?hj>rv1Qc*);!@|Sm--G=aTuJ#bbT&l7<$L4Uu47@t!aM^^FT^fEfV@ZT -z18t4K9y8(B(X5(c)(6s3qzf7#T!15iY!L2Avqb%w;qltMR1K1Btps==G~T+6h*S;} -zI}L?h@-=iF<(D!x1YqLW()S2F*OVoMnvm(K^$W*cDtTK1%3s{$0UKyNPZ9w$78aRQ -zzd&Malo3IYnqh%tmxSBF5(*yXCWFze&B&bvZp3k+KM$?fJHwqS?0y@=ny02y*kpa!=xnzds0vV?-YJ4ZK1-^pOAhDOG| -z!@DJj=|;~;1kexGHXphuM&C-1dni;)+!_&4SA+r=16N0?4XC)6*9?icdkJpE7mkPy -zG)u(${m@FJuqdPk2~@(FIa0)~%n*&h`YI6!M=~8G -z&kV(HEQveu0`yJkOK`R#9}OL>L?B$rbXu(f;s(tLZhXCz3y_ -zP{X8BNjp>ke`=8UTW0U@s_(by3Ror;G#WN6?2tUpU?Lfz+Ua;JP0@(xtqULt@Kde8 -zuos$~fmgG-uQ5KeVPD6rarI|fnQ%To>2cd!>;Js{y)PVm^M9e$wjd$btB;MT{F -zT=-urR_u>1fTXBCZ5%p_fiz0gaw)Ru_+4@muH__;P4zbPfm^{HGnfFnt+{~P-!hJ( -z_%utzPJSq&x1j{5K|-KM0N-?crxFhh?WjZmH^}rFM(3eC2N?BaZsbnj9a0QVda0(R($lLVX8YUGO3==~A -zI)Tw8dlZ5}hKK|e67B$*$41aYw^QrgNYS=CH4!i(#FJ5!-OUo*4SJ&=%D^}*%^>!)c1i;U{(z(!gu~P`sTquLAGp;F -zI(ZHTiP+Mek%<2Q;b<#DL9`z_hOtTCJ2n*l8?9NI!DlCI)8XGL5hhcX38U+736Sfs -z&?ex$KM?&5MS14}nAYaD8W_1XIh#SY5oTBff{3D=Z8t{;KdGrh1&~= -z3Nis8qA0e_@>V-Jh(<#i^G0c)LNWnCvkDlmM0o9#P?f$*r4>WSQVJCbLL}TgER!1X -zqa@yGkPZqrch5+~UWiE2icnCyli_RWP0pyHrA07AB)Eu(3<=YZeoVg0gw2l`D7D<9 -zrD-zwY=m&6*`Lfh;)f0~AQVFyE$Q57M=U}xvuYkdsYK}P@MzQ9-vz -zYHB@cw~NHzMtInmh@zyr0Cu&xJqBQx(IrO|g3SpavGyY(d&9)d`K-{pB!YeD)))=d -zWKM?x_QDaTDkhc02#rdr^upU^_`)Rgy&Wwz?j}TV_;(D9(5v7 -zOvicu^Jr8e2shAW#=xR^IvzVsvtplbmcZ|m?=qdlo-TR3t!BjsLSz14Ae>y7=6liz#5W>Zv`Ic^ldyFC5f54P8?7QSk@m?5GV|B -zs8)N>fi25c37x$3IevJwB%G!BX|;joI=&K~AUKwaTUiiCZlK -zBpVH$3)ewOBbjAw3q{I^mRA{e&}ryxks$Fa{ooTI`r`G2kyY#*$qAeeqHxQ~3|CL%y9L$S_GheEp7oKHVbz)Bj61X -zE%}^M!&OnC7#0$Epp&^tTx*crod^i%RthM^G%ZB`XNrLRH#)GT9u?Qgvuf+a(vT$K -z03%uS)f5^+RPmEEI+VZUG`i}Jkz%88uT^(@5k)xFpRQ8$d!DcAhD -zX(9UB6oGKqaxOdxP*5a6W67}pAX+-4A3>*)w?t5Q;DOHUEsJnx>M3!fd>#<}v1uXt -z$`k>*8%2#5>mFAm5e~vaEW#zQAV{Z+42#+vGs12QTHTLiO3iI%#L);!nAHZQM8!_Q -zZZxb-l6%-ykkCn8n%iQlmKmh5RLn@s -z6JQ{=GhmaKNsOftP-UwP8Kxq^T%e)W*s85U8Cz)J6wjG2wZ4H!8Q -z&(1zXL;yui3$904RD~FuYp&$f?M_N=D~mI;wk-gc8Lp}pikq+OFmok=h{y=c%WmaR -zl^#K-)e6PUm#@Vw=(1CQiAJXeqmDKXwQfv7U^66{(b;iSb|IdF@xMk<-NPlY5J;yu -zv=$*aOuz)TWTI)H`qi3$T;`BY+@&dkXg31|yTYHk}#AHs?>+c;Emnc=Ee0gaIGZ*)u>E8=muv(o8kfN+3_V1HU|Kqc|nb6-nz -zfgtY7K!Oy3(qw!cz|}M@L~BeD%;Eq^*V<;JXSj0$nBA;)9mp+RZLl{J2|mn@z6Y*t -zuI$ib90m=Sz^ovh;;32#N-ifa4Y;I74(kQ{fwgrRj -zNSaa`hq|}Sa8dd_)U1wocK5VoUB^%)7Byt{J?+uQ4ovUbpE -zO*4_;_>L?sv0E2}>2pEDA3(0u0!A|Vmt@0@v=>UM6IXcE+eDdLK-ANb7FCcba9xP$ -z_pF(Gel`2QKmUc`zYzRC2m!#(?p(eFPz$r`pEEoJMq64!n(tKr)_ogru`=QHt8s{? -z^}`Fine97&S`{rw_4NY)3n{zi_e|fIEi2|!HjZso_D!babxS*!L8)@ -z7YmTiWcz2xa>D_|$u1mg?7C -zp)27<{I1!9D=C+W*_=$9<@J{07bYc*`K=3$!x4u5rGChF2JD;zu#faDe%Jd>rcb3m -zl8e)hKwfvFwJs#Be0Jw>-l!w>wsEaS!?0FxvK}61-ukl=jW>T~&`})T8_AUY^ -zAXRY3JkDr1{EbnyZXUL%Rl?W`V_|%ISQu;AN5C6)E^#4=`eA_N(3xComV@1Fffw?` -z2EOEbJ01(l+W|$oZ`}{aE)offysz{W=^oTlfAeU<$f4h*+Cw&l}KMnsl=@u -zp{X0QH^+E0$}+H>tuRX=^p%w28P*TS;sdy#>$e)C)b{nM%6neOH|(d#YXR#K=*n`o -zq7V2-P{~%sHD*F+^^YTTVt6ykI)*=XV#?50QtHu@KZ5G$Wi*?ao**k{%Cl2L`CZ(4 -z{!7jY6n4vvH=}Gso>0zoMl2T6S5oG7^IvjQoDqvV!Ky7!?p$v+hQ5-rs{i*2mY6rA -zoQ9u6zl<=d -z#m$qHBFrff-Uf&mX`&TgajHO}mz|O+#qSyqr%a2VVzfyna@PoaX1*BOpg45{iQ1UF -z-J4a`r0B?Ivr=AkiWR#_Hc4O<#NBm+=OD}e5QW<;-sG7LsJ9q1o6dK`+$k?MVD5`h -z{+;)<{s>}j5wqq!>^f~#*1}`JaC3Qze`j@56wAD>6iOeKv$tzBbBy*yx(AC>LWUz; -zMncd=^DX;HN)a}2FsaxZXiWKvme^|M)y-kea`YYd7!B*`#J+62epsR`b#} -zn>^=Uv@S?pIj@9iM6W^mZ>@ySR4t@WDW_p4l^yc*XgW>^_N_*eZ2Ev>KTmycW>PGqWsXb5c5-SSj}_LBqKNiu8u|f8eag!`xR?`FD&c -zf+RvEJ=}uQ7z7WeE>-HkVw0lE8n+dF8Ycgdjdw5?9Zu;KRp4^el@!HX!NQq;wwsql -z5{lW>l@xWP9^^~v3$Pkb5G(KtY7W>E#A-S|m=WP!T&f6E0kIqA{xA-Md?T4q?A~b6 -zyGo>x%zBLSWNpK#*!6c){I2cORDqv3#VECV-8E%^nMF~WP#(w*6sM#yMNOUz82^qs -z!YZ7mnMTD#geEW~d29HAR+_ScOgGW2U}kY3$sQ$~ZUpkW-4kTFsD4Kx -z^q_IJAwoDLq3maIWBr6zz2*-r&0y*HvhOzxf%Vfa2vA|cs3bgvO%QZ?o_KY -za|C()0|t&wK7m(S`7@W~D*UpQaBSLMEf*T-!D5S4a$O+XPXgu<@TjVXe$b+4ii@Z&H8{(aik9YFNACieOB;Kte^ -zDLY{_y)UXUo6`6jxTNMC4qC{H-HYMoBa_M_;=d_yrwLb6@({Ht}$y8{m|n8^1N_0rJM5uf@(hl*vGBwux}AEm7r=1xS%UbkG!Ln -z?l%lz?(_10JG3!)*vAEn9~qOGwxe&Le-0mMgUl#Pc}*(UM6|3Q1)=pMk135X_8NpF -zPz9rSo#b??GArP-S$zj*c~y2P+7iP~N$`~z*SfV5>2StJ#6;kFVS*hmB(l)!|6uP- -zpqje&{cp9ctyZlA4#-eNZIvo@KrIN=3dB064p<~ftya*8s1OxGNLvRKgcPl|qJSn2 -zQ8cLvDuECc5huWC@MsuPL>Y2SKp_caI{&pzJSX`t?xpWOxsUta{w&s#_1oFuNY2@x -z^UaS9kKIrHHS;&bUTM-i@41g%wKaUF&!lEA=BT^P -zg31kA!SF@ummv*#J^J~CG&6eaD_PMXdPiKTojthda7}*`cq9Iv% -zH^FyfGJAF?rzH<8#ZR02DrgFy3+l!fU{Tpj^J1I#NU~p_^^}GeDV}T~g6kTR8i*_Qkk7Yw6^-T0;8zAu;gfukL~%KsRc-L} -zq1iV9L8pBt -zG4{T`z&3nShn^iDZhZx~`Ls}HuRAWcpXuGEow`VR-^0pW(#;jGU*%WgDDCW;$uIiX&A(#4wVb7! -zjpc)LW;nLMi@AEeEAvKlVrjWfrB|n1a(I0*^>FYi-n$wffUXqCQ%KO(F{hUAKDCSk~{B8(N2AzFGC)j#Kt6b2WWNggQ=Iu}E*Yzl*dE^Ub2|Y@EfcCY2a($P4FY -z>V31+X+ExFTk~5_K5JaXVbhGVs@sYo>?fCQ`<YGcq$< -zn)7+?y)*p$OG$BAS41`0u@f6BUL_lax*aveNj|Pmvd$V^*2*6NA%5BTq%~SmF_F{P -z&*So632uVvZRYL0)R{SkfSl$9REhyjEw~=-vF%xrqH-;3?ouKB{lR8TOqydlf`z@% -zhWq9+ -zpGm$7mpvPFn>m>`zs#28f2P}3k~XcOj%66xSSmB?M>gag_DibV=chPXui0?@B-I&e=~b0&(4v`n+Cnupwhq-)PJU!;7LjA(90X=j)7bYLv1>gHWEmlQZv -z4(>9+-Dg9*WkGHJ5!_|=lfS;p1h=0}t}4s9RRoq`;vD10VG -zb6%hFzJHXstgZUqGEfCpqcxT@zHx3SXI{mRmVpUp!98Y@&%WEGSRT0f{Ikk(?-Q~} -z;q&0nlGk6OaZV^F3wv{qc@f-WZh3u;;l0qf8-`(~^Y|s}FC?^{n-q@WJIxQKl3Ib4=q2%BrHn -zUtZqG*;{oekMwBiV>cgcEoXgFU2&zymhoFnDbo;hWX$UY;evV%xY731o@^GaDP&t- -z9qF_(9i#ZK;Mf1BBWWcrhn%c;DB$KZ%6uOz@8f;Il040l3~o9P|5c+gx+p8!HTYqmX0%ESj_a%%7wf;YF}KZaDKNDRtp#6HBq# -zkSTLH+hI~Y^+@hC6X>W<>))j4!rqYd4V7Y%Dk>)e0^*!s1 -zSe9<~!!qlQUnnOk?veHO`AR->wQ(GCRAL4)j3q6ou8V7yR5|CDh$3I0XW7Ba<2X~| -zdqlrJ>QqcBejgW}@u&5EGMe&m>mlpC -z=`t1#nMYgyI;dWX(#}SUEa~zuDF~{r=Sde@nMI+=_q?a&kCF_PN6a?+X3f=&laNmO -zuC|_Gcf^8W)b9)kN!w3I7kF#$L}%(0;xj@{6#J^n>DoqT4x6>QUjIzU3Aq$h{W7@U -z9A9cp^-h}WTFHbq)b01BkKJbV0O?7*UiieIpPf?_d7?SlCD?!fsWzZ)#Y3LFUITuO -zq9RdZkQ#TO9H-@AB^_ePpg%=vXD^mm{!33J`OMXSrM-SRo_M7BOfqk=yiOMuvUIZz -zmY8z^oSN8ps}G}Dx?A_6fs#=97H5y+ZEUtLV%bM}- -zv63}USFzh7F2^c#vcl)OTP@?PdO1(YK{+pi4Tk*O9Xh)D$crngr-@rnD_M&4iz*O- -zt}xA;{3O>6`F)0rmNb@&r?=_XH9tjMzYD%X(ks%8Cbvol?X9NamYae@esdcQ2bnWS -zy2Nkm!k^@5bu6$NuoMnHn78g$SW?k&?@`zl#kAVVIjgE`;wne)+x>+>X6TaOS4p^q;v=Etq4y3*2+7& -ztYwyrXy9}`z8HU++N7i^>Jwy -z5tiS3(44ZFQ&$mv*QcLyd5EDo<#_Y57~c!EOJ1)l>kpS8-+fA@Th`r6ryG&)yvdL&9a+u;8C7Cu68GKo>?#{0C~E!$}FbT63` -zC#kJ#&NLY4V_eIZw=$B|&vf+HL2q)}>nz@O?@?)kX{yoGZ=kE#DCp;OKJTymRPTr! -z^jM!67tYrTIY871DQ007X`l8McR%_Wtj9j1@dIroxODL?mO9zRuJz2?``)Ot5|#qwrD{x{6y4-ENevgHk+9>W*6 -z>2Dnw^?M`>@RhL&6I%M@i>Ia6F#y}p~u -z1?zKZmL)-M1$oDL?dt(e!;6$%Zr0_^8LZFeUSBqC3@_&DmPJ;r(KMBA=X$<=69}vj -zjXzu7(uuy1&s?n>_WG(ZM0+uh|H!u7;ccd~bhqw5RHYo3Ts|XX^w5i5^?Ua7?+#SS -z=lZxuNxge&9Ji4bUa-LtGE>O@{CK^{ETbt3R$2m<^#zG^Vo@<`WQdVl%*<8;!j>fcdHv -zsklEhH(Ba(+fO)oTV%CM!}KxHoEdpXjV{9~9$N0GaxP|(_PLZwS?*gUpXnlfoH44w -zn6QfYwKFny%ZVd -zh9JMjjDCB4TyLjct}rVdg{;@-m&-6kq08;3b@V{?A6qwgeIgn9$oWVf>E^f>DK}48 -z--Y5eHHd3laJ3=7;I88U3H#Zz6VG+C5w|yQpXnww -zB712o39|kMpGTJGx^5)a`foN!ZVx&)qL!k20Iij;Bqi -za68v~ze2}~-s$t8qe7craMzNt%k^fi6fE0!^okz_Qmo>Z#m*n -z-Rzj`d@6V1i&KTSGlH5o6lNfC)ys8H(i4}1VtDBP* -zLcMN6K5ewghkZgFL>cYkF{@hlaH;a;1^vCMi=|$stmYE0(6ZB~bVn{J`-G;mN``Ol -zm)@j7n;NH)8h@V}Uq`FH>^;<5ov_h+tKayxmk-6<*5(;s#HRcG!Nkh?Wi?W?&3hHX -zr<~ub4f`5{NP)UclPgv#sg28SGsIt4$*<6>YfgB_Ivx34UGwA9s%NEW({C;whb59p -zt(tcwKU1z}^x*8!jU6&WQ<}Lpk>$*y7SAnczCjuHqWNOU^0sGlN-IZu#QqSmtEeo@ -zSh|z>>hi*tQeJu8A*rgld2T*UtsSdrTW>bkC9!k*)rB#+k}tN@ZDj6r{T!t%Ic!*e -zIhs=>!B)rS5yHwqnyF9P3`PP@!lC^ymLxy8{T=sdt7#H!1D`G69wY28) -zUD>W@emx(3KDLTu*kRgs|HRygkestQXH2b2a>X}}Idr&&; -zfJjl4QMYi1&;7Qdro5xF43D}zby8@0TvbD8#ujys^kVv_8Fh`{84cgWh})L9#!FSh -z*;SKF<$d0}%nogBHU5Uhaorw0kF3Jkb3N`!4H%p$Lg%U)%4>%$FRkcZw{?7~*`lH5t)Yio+Qh^N0BM+asYStFc)t7y1iB=lV*#!pj;$)0tIYW|n%@+zz@Y -ztyxVmHUX&g~8q58_I6K1FH80xmnl9=YU&|QWVr~OF51+zw*>uxQ-LgOs>6#MeQ!6q;L -zA5C?)PA$;K_Zi|B6SkDLH37@?5b;jOs2cf8Ieu_*K@6%oO8H}caD -zyh6SU-7wdjmz?>k`HX(k0PXB3^R>SwUYV%Rm&wgDoRV17$<c4X4 -zzcNL%{`AAC?FFXB^Svjyei!{T|8!n{vNn|TV#~U`@zIj}&wk|8n_dc4S41kv=sCHXacfB{YoYo4B_yZlq|vaxw?ueoBikh=t4Zgxs0Mwh -zeH>S5ywXQkv(NCN$zEXe -zjZK>pd!(1p`)2Kw}s)>Wuq1&s`yOe58Ta!_)4L!{*&y*n; -z*H9c~Y-G27_sXQ)F|IMF%(v>~^_meeKAz2AJ*HQe7VTNQ&KR@l1xhQZo-xpGeq7~a -zSEebWX?%}88OY-iw`m^f35Ftd&}89RRdYyP?#;HBeev({_o=oy@V}=_|_3yV=w<&hNT)=Ehgl{pSj) -z@$U(HyR^OBx;0qw>bE>D;w{a%`&{Dj?0_(~A@SAsC-P#(>=RSH=2E4qVbPk3Y2H+m -zq;g49bbzLUTt)x>$McBv8vU9BDP+?tQ%|4KLWh+ZTkkDtN?=hg{D#yQ-=-FoUO=L* -z_>c-5*EgP3p|yvF!=2bZ8rN#W=*#X#uabJ<^*H@EuMF|wq`^#QhdgcDnol7z@{PWm!0`xe(KSgAEk=|JDvLyysYcgm%zhptbDg~ -zUxLDnPJIa^t)PZpZ}SfVMh2H`2uEyjv@v$0yM%uU1$E@C^W*~SdQMp_xYc_9MA~R2pvZNXoSD9 -z;CJ{K_^we$UVujU8_Ur@UC%rE4tM+jXas14ju(7r1ZV`XSi!LT=3+tFk9j@b0l!Fa -zruosHDc3bLtlbaukd}Wi((c3mg`ydibmoTw`=v9VUSdWSY!lL%9|qd}&U|`=Z88Wk -zeJ6gfvEH5e^q5}A{#Q=C|H8T2$e#IMdHBC@#WZ&6MIbSoJnB39D|G5bfJm_SI{hnj -z?pdmn9PR9{@GqQr|CK3F1|42QPzD`{1j?Y}OAgAQ1D8M*meuz}pcY7HC6 -z9bIOyf!xs@5$qXsct-?#1|2We|0zFO%6{=EcfsOK-HKi=em7v<$PeaEnbg#6&O(nt -zLqAGR&VT1%*2MXrOnp9J!293G%03)GB9UCL`ny~oI;7_P%!X(0UTT>V^6cA1e_pNo -zy*}mANmsMNMbrVP%0H<>*C*h*?V{Y -zw_g|k-jl}U{PW+rF1DZnDPaztLrj^X>^q| -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 -zu;JUWLCkpd4FJH)P0=A&5j*a|z*u -zgs2x9=Sp09`O?n0kQAJdkPsJFN~6yPrq2!Vw&e3o^^I{A=?$tCGfJzUz7nmv%DxmD -z6DtjUap+2(Kofht?YVKYQ_hta^Iv=)5|on{*HRaCETtCwRD -z!v5H8?BR`{sRe$|P!r9Ux=oi^cHlQnF!B8qM`)&3y&K6r*c1 -zE$(4Hk0L!y(_3yZUE*)Hb#rx9lxob6-Z_V|w8ogNJtNJ2FO4yNg3MKQCYrCht*4OY -z+7iwFQ8hgu6@AuXY8AF#@tJXH+UdM1ZQh@lsKylXX-SfA>99$UFf6*H?U+d9`>`kFCuS*u-oFC`itZG7+qVMkLj9YpK9c+laftweVDptqw6wZkn6T4 -zzYvap{)gadV}BZ<)(T`P1}v0EGJjz -z`{plSF(s~_Zl$T&H&A&${igb}^`+kFiB+XJPknTeTekSsvC?$2%y-N$3#K{Zg4ax>kSpWrnAmeu+=l^6AOC27M?6 -ztJ|whbyubuGM>dqiZGs(+U!qh4x}`TQPH$o{qiitNJfe<4~nboCFY-nbSERfxb8zG -zUgnIwTKy7P_99t!lVT(5F@gnf#eFv8COuo6L{noEzQAl1GA7+G7^l<7hvid$(AhScdo#Lq@$t!%yYvT -z=Y}xOxmL2nKUQV0lxYsso9VnTp)im_OH@npT~wMRKD~xd-(PR0KMWH_1X2_UYRS|@ -zt$vFvJ6fhmt2fgV!-V5`g2q4{O_8Y8$H}snMq$~EEMzJfxkN^`NKJ@VO7-@qcn9ie -z-T_RN6GJtilC5%7X}0s}m-%#Ey_wDl6S@Xcn1MPPGk~dbW~c@-RKppnAq&<9=m@p%dQshtZ -zOH@nZTvVDwKKi)cj9v*7*6;)axd!1to_IlmXhE_lZdfHdZGeigPR0n1!Wc1G$S^W; -zh>Qri2H{1nxFlIrvPUf`Nz!_GD82kdnCKHZdYz9VWF$apLL#{03CW@fd(@H%Nm|k8 -zO3@4vCK@S6@9@zxd{kL)MpMItbe;g^8iXiMykWN}ZaAZID5G)^qtb~{IiQkV>8N6? -zkZE%3&8Rj^=*<;)^8~qEgD{sTR__t1lhhJ*qE_Um)U%>6%~x5-b}}-Hj1)*sh?|tk -z38ZiWbTkf$>C>O#Gpv$r8X-qd^U(%AdZ^xva-`JKKuT$Vj#f%yia%zEhcd*2D%oNu -zm1d4ivn~qL1ZN>A8Oh)pgnlHZxIaTYj3IWYWQ(0ungue?@4t`4JReT_AoJWH^Q;18W0>$muHeI- -zQ+2d~0nGVM4Av-R>T2+;YqOBmWaL?o!v^74uK46$(MiY073}%WD$n^c&v2P%C77-c -z6At4FhJopm1DM55jN(au=3uGBl?jgNh?E)`K#AgBasy{F#FVkCM}+eERu%Gx|_U&DbLv%u!1Y -z?$!oRQU;Gx278IH;4yOg6Fxns-b`-`6FP7OrGXUpK#F?+B_mPf>srY^=cLM>Bg+Qg -zPvXi8)Y0hv%yYvS=Nu~8=bTlV6MXcp)P#6Rsc0Yt4WOVT9c{QjGkhq6HClwpKa-=G -zWCYZYdYFt{<{E^>TyefLBix0-`c#C;N6P7U`Dm`xgy^{9 -zd{;)eLnS-hS(QCsmK`q3rbJ=ctSqE28A+C!kOfkzH;Iz#ucPG#GEJW-<>Qrd9}y;Z -zlcVuuBwcDks8TAEL^1eN41p9w0L4I}^z_%!dImC`2Qi$TD%s8hRE#hgW4Vm6Eed1! -zXCWzMge)~79IiOdiD4Qg!o0lX=qWNXk&Kjb4Z;i((=<})HC2RpO^~Cld~`>>8NCrE -z+|L#4=Lu+mI@&3JW||`-ZEz(!%|*oslrh%GG@12g^lX^$B2N&>H3%bl;*vyB2}doN -zuv;toLaArS8008Sb2v)v8iaFs;t7eO2^_UVuv;sdq!f))io8UaXp9_{^HEW~ -z8P$gghjRsrK+3d0%CrE=G!o^qzm9e}kXbpHVVWSqL_TsfnU9w6Q9->KRfh?gTmh43 -z5E{5*HAfWZTFLhLSf%-1rdcG@Y>dJ*v$GH$8CfMYAvIF!LVwD_Kpl;}TN^V@8RMml -z86(2TYw5j8jsXofo -zRp6LHvyc!nQn5YNAmjuxiw81_hck-7^fw;t>8Yb-?A8W@cstd<%m -zoqY5n8A%``bI3>?S5QjQ(cDSQa|0OX94pzZ5psGqpRVDfiBc2dD5cT^Df9pxjZR{+ -z#wzujqp<7+S%`>?#E=oa)P%e*r4A3I(DtY$QxmlMbuvwMy%|NNRK;%5)MU|AP*2k8 -z*T^*I>do|vVZsO!z%) -zG7?8d%w*&psR{X6O6?gy=}FSj;{BPM^gw0$*GtVIG%@t4BD~fYwPzF`9O=INf -zQ$D({-i$s76W-+t?(z&mcdl5lS0qRf36j+k!5*z>s!{|lDPK9di;rF=BS~arJ{c({ -zBjcqew& -zK@1f3n0nDUi(M^BKDiWo}pHdS@ -zsR56;$9&}E+!*ilacG-*{nC6iE4?jvr2P_ -zPk&i&rtb+8j^+tYa0MrL2H}rf@xdg~!9=y>AV(WKLaARb%l<)@{jE%s!$+H?CghHk -zn(0r;4AjwRyS2gNmBBtr{SQ%Cw)OT>YC_~vDlI{j?^MY?H&B(mL6%LGWyeKf*)y|{ -zU1TJPYY--J#rcj5)_4)7kI6!&aRo^{!F;YkIG-oZAI4z0i!k};a#}mgnGMoo8Oknwn&O$u6f>k_& -zu!bv6=7<*TR!bJ_)q0IpdVQ(X{}_ca=42tK$;eu%32Bg0L;WeCffPxCT2hjr_3~DF -zeJaAdrpeJfK5DEtqrZd+d-DV|5@kq$jwaco6-`%)Mu{-d6ghf*b7mh;5w-6Hi~ -zkvc&wQ73CfpDIPuM3~4!j+*(XPHIAWNU8k-Dg6Q{{YW|*$Dirr$nY6l$@XzkY5ZlH -z)lrxxK1_IuD>%gygo4|}K&H=dhR={nwvVey^R-O#gG}>n6sFmng}9TEOsNT>OQ}K< -zg`J?5n4MIbK$&KZOtUNs(`?B?yvfK!|k_X8>0cTLgJw)4ch{3)||f|avU -z4Z>^FpFIotk~I+m}XCy -z@I9{Jz4$3QnoZOL&z2G<4B!b0xd!2zkSD@|iHKKkrXLCu{>T$N=Ng31dE#ZeMZUus -z=Y}%Q4Pvk+DD|;XSoY>DWE>eeBQ+sIxZ-7rqGcRW{?JPHx&Er`HL~nwQCK#Nb1=^R -z%{UhZ;@o{poI7S0=k6164t&~9oC9TRoQt=QbKqI6ac-7PoRizdIWXNC=fLzgaW2a) -z&Vgfk6X(M1;@o|kI439K9GGAe=dxg&gK@5l#kofy&YiWyx#f0o?ko}Kz^CoRIZ(F7 -zxs~>D?hz5^{v_huF8erlmWXp;`kOdMw~KS&n5=QGz&_5MCE{GXO`Kb9ALr;W&cQg> -zwc^~a*Ksbw66dPy;#>p~=OWsVa}h+G+h!N%z_Y%Ib9qFZtG17G5k#B=)2(r?z&_4Z -z5pk}`KF&oDaSlB3n>bfx7w5pU!8ixwTvv*7{Xv{_v&6YTyEx}Y#5wS3J8=$_-^4ko -zU7Q2YYK?Q8Fe1+R+r>FB{Y{*c5^-*~U7Q2Q^d`=6?cyAm{wB`(6LF4YALqcc!8ixI -zb6u%Bw;IH`Tb4MNVi)Ib5pfQD+D@DUWow)x*~dBXtkyW^W)tV0*u^<8-5Te>^fz(t -zf?b>g$7GFj9Q*FvEt@#^gotxsf=!&e0OK5tb6qUXm4P^S#uDe2*u}XsM4SVkwiD+- -z*&64__HnL^h;w`*&IQ`XxidtZ1JkW>Zm)fJ4jhv;&hhNy+!-Ryk!<4J61zCZf!#S6 -z=ek&&3j}d4$=aQ(w2gB~M0YN^{q7ui#GCG1lwF(y&-y0LiHJBSwTp9L`kU??m~M@8 -zJo`9TNyNE&yEq4?zv<3_Cw>#>D(&JNcs3a4V4Ukpac&}rbE_WI`tnQR_{WQB`ks`?^p-H;M|^iT<()x~jFL$_@r9#;vnz`+_u+DPZ{?l-kBpMd -zT=C{(f(pL-!sX4_okZ=Oc+o2!7W7V5&`jCV4@{C?JaNKN0hgaSRL^!GF%Nu287;*! -z2gx(1D93FV-Qfy0^D}2C&-`SjIY_Ao76tv-f}QzAdnQ42=9oZPk1g$?S~`$X_BAGy -zhY7v-nG^KvvRTYB5~a_gpjj>0x*ghedqt^7v7p6SL6c==P9{n4QE@O=u#BJSsb^=; -zWM&6YRQIt=A9-dErE<5(>lhXkniVueR_0)mh>nRxJb_C+RyI&o)|;UTq_FN|nI7^? -zSEZ6;ruDc_?LkI9X~7)#Y8`(O?cxen)?=PdD$nkWB!5gu4iifG^pBK|iK3gw1TXpY -z?t1oof9CwJDf^`uy_cLmPMNw(bdrZ5A7vr)WS+fEk~KVW?NLEaJ?7a@<>|^8{}rXT -z6r=Z-(6ZEdf82wd@4;hp|Oz0ja%;ckv -zN>Q?zHtjxj8W|bif{Bu}qU|Cz7ejoq5SC2Sjp5^u2}xnXB0l<|p6wIB^qEB|m15|7 -za&)vZW~YeC!;s-w$O@UJuSrtH6Z;+&aQNszJ)0HCWX+_|q!>C}j(RKgKbvWOQmSMT -z5+T#{G)c@{vH6&wTlGE6{rl+`gFcZtOh3}bes3o8y#UI!ML|s)YcYrJDu)4#oxMWM -zv}020%0)rTWe$BAJ4uxOi-K-|@efrF!x#Y{hMH+)DOI{CC`#twcBGA6=+7+tnsUD2 -z5EkT=6%-;bM#k~56MB?jkVZ;p{fJ#GDi0aHPde2r`{$9C4k}p)q!4&6M>Yq -z*AHPq!C66GG7W8dGd72#z4Mc35?3$}9PDJddvE0(#}cFD!ZGm$p1=tdKb5-=QQk=s -zz1lGu6Xt~pWBKlWdbYz?Ob36;&ih#A7xK&xl;aXa3CFOYO<6%7%9ai=N#-0A&*2Fs -z@iRYHj*A!F;R$-xV@vz1mVU@s8i)zUg$d8_GaZ#@lFc;F`&3VI(D)YYOp^A@c9D{c -z1^HwJv1Dc47@q!^FfdGblb`vap6waH^qfU0mSUOj$umbQ*Xl#U$Hn4=itpM{K) -zc@8s4P97DX0Wwv@mI`Zf6B%C7=5ao-dCBLXr?var#6$3?y~HUO_IUK#DjT) -z(e+sNAXWB9jPWE)=ny76z^6MXgOkiO`h6;$jCi$R!5pppC(%@{V17N8JxrDT9wR&e -z6NZNgReX9+JzM3^RDDg!B_l2^m^@J{j~8iq81haQGE>I*z$EF*6DJ=P@c8IZJ=>YY -zO#6!RsT4y8$t@fy`uD^7_vAEnJm*dnIzPsVk%b<#78~# -zZ1GH{IDpc4A47fQXb+`+x5)PxhJ<7y%zem}x2ZsVU^3-@v$o%ApSujp$W&Y=TwErgh|44)4427nTqe82 -zY-Pg5WfCyORwhzhCjAMSNNr`}4`l*n^7dtt0%S7EB9nc#GMP=tWOaKo0pnJgthSZO -zK0+o$G66+gCbJ2dtj1*miiAvvWHQQDCg5PLGP#Y*1QZFGOoB3jGI{$lc>-iI)glwy -zWWrgG%j8zOGFgwy1dJ0hA(F`jLMFD!Bw;-+lUsyL*4xVD0wI&BwlaBw%Or)6$rD?d -ztcEgyGI{$lAp@BVvdARCRwkbjGWnrBnSgPtOn$JHNdhht9+6By5tqqlgiLO82$^`=%A^dJ37L>dnXOEgK$$?9ynUHSflQ`YWRhwt -zlQ2RiYub|u7`Mt~jjc>l37HVd1QcP$p0&Z(k-8flNNK$YhtTOokFNS=pXUz_?W=D{W=63zx|%BAI|9 -zE|Z~zOjhDD0YzLUKM={}BU_n(gSE<}0GA0U;xf4bdnQmOogkBkMoIUZmY&HfyJWH! -zm&qUP%497r6EKd;|oWx}UibOJ5i_7E>LMCf%WpWaiNugcOkcnN-M1jlXB_R`qtxRH}OrT8OzDzy@GU;xS$@xvHTqXmEWYXPMCg5N#GD*FP -z%LEj0nT&!x6DX6nFOy&I8ztSxSb8P{ZIj7DVxP&5_GB`T*k=O9ahVJtlF2b#CZLEX -zlR3mblO4EBX4~yEIflz*v~ADixBIwEKE!2`a^F@aUqhKdnY?|O>;WpF$pjQ} -znT#T2LhLgEMO-HPh-5OrRwm$JtuncR%LEh&nZTY2lu0MZL6z@eOD4oVljH5m -zgxF^S#&MbKBa+E!TqdAMBoktv$#Fs^cKb|D6Ed;wnfxZhW%3On6Pc|{zJ)S@GI{$l -zxea78$s&_OwlY~w$fVtUCScqu6T5vThX|Pv$pjQ}nXD#cLhLgEMM5S-GMQv66L7Fr -zncTx=0*Zu8V9x}~q!VOP0c2w7ne4YqCd59IXYI;_*k=O937HVdB!`fRT{0o|nLHz8 -zVz)j16(F! -z37I^wmB}0^6DX6nFO$@$%OGO^odl1<3Ou4f|0WpbL3iQHBu>!3`aOy0gs)&iM0T4a)BE0ZaN -zOlly1zo`KJxPl?cJQF$c>F3H`@uKTI!3W?>9w~PppiDR- -zH%hoi#ayl+jPD+^t{F@CS(~s&^aHpC9)}61^W8UqV!SqiBN}j2umjBOFL$4)oU>1E -zl1h>F=FS+|TWx_5I_tZp8I5bT72j6{}V>6bJq)pf^dU|pqCfpV# -zY~{PZqnz`{O`~MMG4TMNU=)}+R_;DbIVb(5QS$9k@wZ&T623dbu^F4QT{|aH^Z*YT)2^hD^?Wde$XOs3&7iLsRlc#u^lRk%z*k&wwW -zC=)1?w=a`xMoITIU%Zydk6+lz{zU3tT4e<1$(Eg{@4k;W7a; -ztunc0E0gzenSf&=lF2n(CSayjCf96b@;;Oal*!wd$uJ<3K#NQQZDj%mtTK_dClfGk -zm5J0=CV{w2ew>2K1Qcf -z?aSmgkjW&AOeWdNxP$q9*CWnAb)>ve+##Sa^z$%j`?a2g;TV?XZRwio*nGih_ -zP{d^dW?E(P1eXaY5;7rrCTnbE0v=?Q$rD^Aph(CB_DrBmIzc9dKqi)+$&YqDlR{i3 -z-?b}~LR=UDF!mJ^h|!V>zNeeGI`RjOp0-tfN?@5M9*X@Arrfv -zNii-HFw-iNVq2L^C1hgPGbzSp0%lreQfw=esZb_RCU0LRPk>CeSY)!rRwiJ;DwE3g -zWCF&mGO4tc$reH;M9%~iahZUbR+&`dG66+GCPdF*w+gRC;C#AO1CgiK)11j?in -zWKv+1bg#AaOrG2IObT$BeA%u{3UHZ#aa<;KM9-uzE|Xfjo=E{N6EM>%lLA|r^u=WY -zj)~}*6yP!eGp#Zyu$4()C=)1?w=a_~flL-yWU|0kCSbrSlZWle1dLl{^3YZ$3vih{ -zCweBJh|2`bw94cmE)!71Wl~4%le@Mu -znE+)1W%BlAk^^M2!6K6lwlV<&R+*HyClfGkl}Wj+Og0cQA$lgDh|2`bw92F$mkB5m -zG9h{<8*F6)9%PkCIW7}WBxC}6CQv4wAd?~>6HCwJxn0ks2$xB8yD}-lWdgJ(D6_CSayjCPlU~aUo=4*E1=?WddeeWm04-6Bj5GD3iA@lV~6lszoMLTbY0X -zt4xsgWCF&mGC^!*LM3EE^h`hzmkF3@l?j5&1QZFG5IqyBtxUj!tTI7xnSdf86WB9> -zGU)`FlmeMpdM3~9dM2f~OxoI&NhvN9FiyyX=$ZHuGO_EKl;Sc0Gp#ZywUvo4Arrfv -zNhvN9Fw-iNQd^n$LYY9BynUIp0hz>EWD;j96EI+viK0E3fN`r#6t*&nBVi2|1iC=xOudM0tUG64^=%0z+71QZFGz@7<|$=jF7qN_$p_raE)iGyv=WZ6|* -zChxT;6EM-b10IayG8sbjOy0p|GT63fvivG86EM>v6Y5o4nY@F`1RN9IGg)#KmkF3@ -zkqP;#txVp5GJ!IA`!abC$YiEPCNphi0tPHH`R;yuG6CZjnS|W8mB~z8CJsc;1QcG6Ca+Oo*Pz2tp>dJ(K0PaG8LaR+-$gmB|P~Cbm73CAV;yfSFdA+_II) -z2q+UMleaIEoj@ilEizeYD-$qamC57wWCF&mGI?w(la+)_h@J^3;xYj>EOvHScz`2HrsK>;Cm|$iCMS=;u)G!eV -zCQw97Ff(!JF@Z}OCL+NEiinAsnV6Ui045&*CTeD4(Pt*Ne?TxfnHQ4}2qtijm|$kI -z5HZnbCO`RrU;-~SOg_+KvJf%RXC^=XfM5bIHB3IxW3tf1#KffkF*ymCJfLFofF2V# -z&@efh4-+`oFgdHo?u^~^YnMt!DGkJ?(GCMCOZxKx3oM7@4W+o#ECQlkNleY*a@KVF%Ej=b92`2DO -zn3=pqFoBmECU5C68EIl-V$%PZ%mz$uQZcznj|m)Tn0%ZM6FAo}`B;z1O$3u>%uJw2 -zFoBmECLa?_phz%z3Nw?N^q9aU4U>-vCQu}p{L0KsOic8ceD~3d%dgnBZP1|c2fp8= -zKo%<`KRxwW$QQT$wago>qv4ZhirqviAD6 -zRCu@4&@1CgYECjWMec19a(+c}MWmIY#UJ_BS8&bxOyN#p$Wu!c{t`FuXRTA^LTB>3 -zSh+u19^~vt&nVW#N$Y62aKG?YfcraZ9U?dWB>7$JvOx5*5O)=v&rMp3--J-=F_ -z@K3w>pRm@4?)ye*+>vSAFZ`u>iNgQO&0oY?FO^sQIQd;{Vkr8ApZg8GoR+lSAg^*H -zzl;4S82wRz6Itu(`@T_D?a!>*BYX_sG}_G{V6Btn(?5j;4*uvXLGFHdxh!cNE}y;w -zcA^BL4~DoKS?k98zEMu^$(%kU6#5maEJ9r>)=tgF8vW76Aa@TNzP{JjTsjx -z@Zw~6v^;mea5}*KlMN4%TleN%&2eY5gR)#uS{pO1yM@*eSJbK0PD-DWJ_pYv{ -zZ;LCQxk*ov+;UJ@>sO>7Mx<**+w^SgygzzA$UV}j*k+~M1~Kz0>HTrVvoPryDc3dT -zT<^!7?>nTz3rgL-Ox-Tw_7G?5RN5w|+r~1-Y7~Bqn{Q%0ljP)qoa@fG^G=7fN^fyFy(gihMkG^L$tAmmgCRv48If)h -znZj)BmQeIVKldt|njx1Q66X84{hbOkGR;h5=rV;5yLk_rDv^b4IoHyJ^L4wl{(>Ux -z$O!v|u7DzKiAY1m?(xj>a)p1_&Cg*|SNHmsS9q7#&7-p&7xwK}1AD6?v- -zFfqtg!pnt8>qvQ3-Kp~3sV!6Z -zRySYIhD+quZ8?`M;cT;0>n|v+J2I{N1v#KlTO!m@v3)#aD_8haZvIL(e08tSR^heP -z(DUL-cy=;uk?Wg;q+g-#j8MzO_L6tIL -z?8&*lNjOK@rE;-tL^d`#6n)aq9qm-wMyK0mFvm(2zS+&!vL2gUw2hznn)ccy=LIFXCzCuRjP)y0Swy;2 -zWTs|g2mR55LGE5Qb$zezaH;ojCH+ENNi9yMM$0Apg%1PVH*9K%EbPs>o{Br4a!8g7 -ziqM!5b_-mHo8GA~lhVv6rlVTnm$~^j*woBkUq_91c_}^4Azgk!*?b_gdAo2Vs7Q+< -z(k8KcNH&(M=pRg81WY_CCN@1Lu)smZWKCX7J|UREIbvcXnB0Mw*z}luLNI}s8YZ9U -zF}VXVvFR~^1r91E@KVF%6Fnw(n3$ND3;-t2DAeyCR57_hkI7ev$%pwcfpZO$5A~Sb -zfS4>Im_U(W0xva8J|vhx5iwarFu6gG30%@J`H)}&MZ{#0iHV6x|6}qdV6sugWT_q# -zSm2;y@>O0;&Jj%D95Go+FnI(qS*pk69Ki%$YM7kUWAX@MvQ&==EO1aUftMO4=k%C7 -zVq#)q(*Kyuh0df<#iT%wi3KtFLq1I4T*KrKdQ1ukCe*bA6DSf);H8Gi9|$H;B$)j8 -zT7pS|9uv5vVe$up2^0w?w_j^wVq((&m;}G|6};&F9usP@9urvLpkiXli%EiD0_Oyi -zA1@}DR1r*S7wa)e5KQ2uhDkz?Nfp5az6t+pE?D58VgfHUOcHubs!U8wOa=fG=uB3r -zn9SB=(u|nAmk$#-*D!fckI8Jr06bUBqQp4muf(aB6lj{g3v-Oz3B@L7J2qsWO -zOs+FAF)`_XOkM#@?pHA}WG1k{LB*swFD9Q6OyC?b!OUb0Vq(ZlJ|mdGOAV9H^q8zc -zObnR`EO1aUftMO4pXo7KV`5@r(*KyWLT55p#l)h=q!uwbnGX{<*DyJ$$Han|U}geE -zf(g9TFgZyufg)mpnTbV@30%@JIY}^qB4T1@CMG5WfJrN0Qm4pXc7h4K)G%q+V^WKl7%~%B;GkjxFEvcs^_bL}n3$Lh04C6x)T@}- -z^q90GCTH?t0_PegXY`oZ5EINyphz%*ml`H#2qsWOOfWOC=`n#z8YX85CQw97%*@2Z -zWB@P`0Fw4n>Sm2;y -z0xva8I`o(@CMG5({f|jKbS6bACS&xN*btMq^I-z#8YXY+F&RTJkuWoXBEbY+YM8uD -zFo7b$M8wQwj2;uXq+#+l!32r~lTXad#KdF(FnJy@x$k>SBtvEb3mjBTY=b -zJtp0V$w&DxfpZO$kMx)tAoQY(}Okjb7ib;1~OuitPz&T=qnaLK!#E_YMK`?=r8YW-pG1-Ec7%~%B -z;GkjxFEvcQ&||X2#Kgp;|1l|o&SaR1$xuBeV+bbgzt4vWoU538{ChnnLkT8JF*AW8 -z!318am?VEsFo7b$WHDwYL-m-zB^8rTeorugBEe*dnVFcF3;-s9Z+!*#t8*qx^_j^z -zSm2;yGA17;pT-F$a858;jG0LV!NjJ|OvE_B1YW9`B;tBZDhMXkGB#6+K&oP`ArDkkt!!{k#vCij|{n3(iGCN0pJT&ZF* -zNsq~D#N?fPn83M)$vb*XCLt!6nLv?X0xva8-XWMk5i!BcWRe~exTIn74#5P9h>4k* -zn3xOzCcgzt)H#!-`po1UEO1aUS)CUXkzfMnhzVvUw;?9_%tRCkCh$_jMATz)8)Bl* -zOwPgr2Ne@|sbM1OF}cme#KdF(FoDiwt%}JaJtk)mlMnJ?0_PegALubzgqUDv0!4xe -zywouHfM5be!~`>wMS4u&l7`6#1QRGCCT3=0Vln`j90yF)Ig_RO%;X#_a8NNhlNXb- -z1QR$%OfWOqgqY|v6Y(s;1YT;GoYiBp2{F-UCTC%RgNg~f)G#@#$7GXYT~zhRg&OIH;J+%Ztg!1QR$Xm_#r$xtU=cnA}V-fo~d3G80(fpke|qHB3I%V{)^J$-gHiz0cj@{lSo-g9lwQ756E;mcIY~ -z&tFSts};ZJ!yUrdfFj);ktT@D#Y}O9!hh-JC$Xt3dVPn>y@#vmb$00vkr~SzuA!&I -zmDFX))I?c0kaJOSC*_cAB2%1=ZSY4o1i3pq6=r&x8P0T6DZJOs_pzzL^5(rc*P*!c -zkVBeuLD}4x*}Pjg5>lj5{qsla>!5eJUFF8A=jIr4b2=Y4aISH4TF;FYxxrKgii8_@ -zsd00fa05l;22&NQo*THNadVn*14ZPWFlo$P8l+SJ8j9OOJ@m;B0JuFgicLz2B)Y1!=~@&=s_lP*TH^sVik+SI+f% -z!uhaWqAw`Io{VrvnCa*CbSm8=(%n;;xNVX -zH=Z2J%METkfpg>rQxy+#V@OqS;|aXfxG`)z@gO&bR0TJlz)OuA!^RVj$<4ndH`zV^ -z(U>HmcUhuhGF^|!dc-8}#uGT#FfnXAnU0uXsscrV3B1%W!Hp+SL`*PMnXbnKE@_zH -z#uF$aCT6N)Vln`j90N?$NtD+OsS0j9S)UgZ+;{@#hzX`DcOoW+R0TJlz)KAi!^V?4 -z5fekIf*ViZrG|-N;|ZK=m>4#mEJI8%Re>VG -z1YT;G;KmauA|{xsEYo8Gmo!Xp;|UZI6EjsYF&O|%qJW7yiSoK3Rl$uX>AaZW#uGS4 -zOfXgPA|{4Z1vj3+OAQml#uG1MVn|hR;|aXfFfnXA@tT;JnDjp;CD56SRWTW^$D|lB -z$-D6c&NWO78&8H4OdiHm1&Ra{c&TB68&9A}FloS4Ww;&_xTIl%8&9A}FnP#KRZL6< -z0F%(SzJmWzCs7_Yq$;@aq&P1oxbXze2__Ags?-on7(=Rp8&BY+hKXV0Ne#gSz6nzm -z+;{>nHB1Z}Pijm|OiTs<6X;BCQ8AgL$K)_#l6T_?oNJgEHlEBuOfWNnBEbY+YM9{0 -z6DT4kn3>GcV*-~nOmO1~6cH0MGchq408Cy5Ow>t~hYgttZag`h7Zcog0_TVcW+v+p -z6GLW#8&BY+hKXV0$vVWukeT4d6L_g%V%T`H&cwvTr2jDypfj1TVlqXK35}TK-FO1$ -z8YYH~CsPm;%uJw2FoBmECb;ngiiinjCR6m7z$Fb6+;{>-#Kg=@OiTsyp{CsBF~nF($@S)LaY+;{@# -z1d|JxncPY+={960xbXyDYM2-{p4>_>fp5ah1UH_*OAQml#*L8VuG0o6bUBqQo{r{oX!OUcV9uv5vVS*b^poo~5nTd(X -z0ATVuV4}{M^cXS|+;|eriwSN#fpf$JGn0*oi6Jw=jVJI@!^E)hWFul?$V_nK3B1%W -zF>E~9Xkubw(*KzBLT9o<#blNqlP!oz-i;@4u3=)>crpty!OR4T1QU3vVS*b^poo}Y -zW-?2U30%@J!Hp+SL`=-g#KdF(FyR3cbB)I%hIYpP8({jVD9%VRAigJb`n9$!L<9WJ(Dp -zWAvHHV%&HFFI7wy>NlR8DJ7V|H<8TbM%;J;FI7x#&~H5Xy41wP#AE<4fzG5%#pDt_ -zCOZ(5ycgG)!>g2^0|%Gcz$U830UJz(k!h8K=)oR^Y~yioBTM -z#uGS4Oh{&uu_Gq>%w#ccJb{-QCi;yhXY7cHJ~O!yH=e*t4HNywldtV2CMG5WfC+Ra -zcdM9OtHnHB9sy -zPtN=tG0|rxH{!+! -z#HrWTf4@}W_{-}5UO%U=DOV=_dU!UrHWWSY=Z<$OwsC3OEM{IQJu0DiCL}!z<+|-T -z*Ubs%`*!KU3rgL#Ox-@=_5j!3sk9ACw@qe_RVaM7n;*k^E|-%#bFOC-&O7bW?H82f -z?o9Ha@Q`1TZiz_q#kT28x=i7tZhi~vS=s9=F7*~y(tF}c>e^&#gj~`n91JMZ0}*MY -z$V|+}ZV5zh32}?q)HQO+9^u0fH>y)%CZw5>3|+18RyQAJQ$@0HFy~qtcP@2E^DZbt -zQ%2Y!bOjY@c|_VGb`N5fS1Npsn}3&0jqLR;uktRhpg&3|se)u`w!C?l;0!6!^oVq) -z*gZBII~R(s@NoGTN0;Qqz;EWpeMfoNHym8M8|p#qQzRSS}dN1-L=* -zAHzS5c$KyObX3 -zpn?<5E6r2W%@;AVi|@|4-itfmb5M;?oS1GdWR6zT_rd>l*F~rjvH7u`-}=^+de>Ca -z&)BK+aH$~OY+=?+zdPspEaAMtPJIZ)QR(LC%vWXfBk-FmBGhAI?VxO|Fc>WiaBp=g -zwHKvpFJ>$i^vQ%0z9<>KLY})T=Q^5juCY^hh_z#x<{H{!r>ZU}tvfTV2ZUC?Le)kn -zn^;@Sw3jM;i<_@w!%KR7?PcEfD!MzagjXcPgXQ|YLQz1W?u}5B#P*A`v6euzCB#kc -zRN5z|+Y6btYI=QK3C~N0i{<)5IahJqS?r+Zi0#v|F~J`dg4~8qrM)=aK9uRMRCuSG -zKgWj0$@2c3O9@1K16;0Cu?Gho{^`5DuUyUoCB}va%xn+OO -z^-bLQjYAqDwvErmCI_OEL)`36rS0N$+h}H9jlx^pd^78@$aPIQmnZJ@IHZybO5LGM -za;vZ;$gS>F+NP!33Yhg(3cudXr&-VNUSGP>n=Yr{a7Z&RD9Qbq -zWMgAP(Sv?2#HOb9`ig73hfC=>2_W2~P8qwnY -z&9}ajW!{rj^gp2ZXoMOfHjig!7u}b0?MpasvQr;FeqL!Foo=4N9G!Y!&UJOd`CB_x -zFE+3J&9}azRocv+lo9?ExI=3C!a72dCE=z_Qsz9bnQFV8)Yb5+HiRSs&QSUV#dTjh_g3UWW{RBDUTwZoX^ -zD*7us^@vzIn5nH)_*HKHG#f7L_0?8+Yb)q>2Q}t`(z-9xx=W}JDO7QUqQ%;A*_a%P -z7Wui|YscN_bi_e1lxSE$5n-a2~T$9}AlL%t+tR9o~1d{|}vR;o#1TlG5kI8z13B1%WS+B<=Vq#)q(*K>wy@1J76_W#c -zOco+0_vXU{&NWQ#)njsiVDc_@CQu}pEJRH1C73{wU~&pOlLLB8;F5;Py#x~|5=`JX -z&CbN^O!~Vs`2;YreUHhzhR(!8FnKvICLV$boD)n=VQ2Cp!32ufnRo~$FC!)%Jti*_ -zOyHZaGw~2i;H8F%M~}&iCMG5({g26)fXVeLCcoBW@&ID8E*~avu3@rHkIAnQ6YNZ& -zNHBQ-F4>fjRcc_M3 -zc0DE|2_`Lf<--KdRZO0_OOMHRg2^20OrS_G8A&iXd>6q4iUgA@u`}7O#{@2^m^^zI -z!32r~6ZlQDGch}p{_ac?-^GU9qGl#@^qt9bZi30ae3<;&O)!CTg2|QGnFI+YP$Zp6 -zi<@Awk6`k&TaQVQU;^JnI+G)Af(g7-F@X=k%p_=HVq((&nEVnjxkAO{2|Xq^Atpb| -zhY6f(nEXtS$rFePb|z3HnB0Vz{ET1%MZ^R`dwjCci~Y>h+kk5=`KmursMAn7~U7lX^WSttKWWCjF1e9|4oaDkd#@ -zOzuNW*5<M?0SOt3S7BEjT7#AGeO1d50Wb|x))OyH7+$y$O56cH1%Gch}p -z0q9IR024JcdBM<`Y#^BYEiWb;2qtijm|$ljASQ;+WCOwEZ-~hTJthKTV(3gZ5KQ2u -zhRFs!CW48HiAn!svIsC4tzxoUkI6K|B=4LFoNJgE=1g`IOx9s%0!4z!G{gkwOrS_G -zS&N;?ZapS&Ny7x^OrS_Gf!{Pc6SFhv@6P0p-^GS}sAeYX44nzinLLvh6Pz=FbAriQ -z>`a~~m_QLb6Pz=71~DW6YNZ$)MEmdG)!>L1d51>*_oJ~$pCaF -zp93apX0p!Enc$qsXL&KfITJWXOt3R~4KXovCOBvE8De6XGkFa$F?1$4X96!ZObl}- -zubG&bnDjp;n*fs;DkcZ@nB0JvjVdNb^q4$?nB<)^fpZNL -z!<@+x!~{DNC=yH_K}>MY1d50Wb|y#kn7}0s6Pz=FB4T28CT3?c0G-JffQg!!{MFEz -z;GD^~c`?B`6F5gquroP4<}oHO|rF)_@UoIp$roe9pFz)KAi!<@+p6B84Y{>Nk# -zU@}C-WSbt70)k0h-Z>LES24N6FlVxjU@`?e6DSf)3J4}N&Y3`wU@{pylWlrT;F5~T -zoj7L#MS=4;CNIUmiw&8tW+qegorw$QOm^kN5c?CT3^S-<^pFn5db_Q-;n2=S+^~#RTU};GAIcBz7jhC73`F -zI}@BUIf|GV=1hJ|FoAEv&IIR7;H8F%Vb0{YCMG5({g27}fXQ_#CeP?GS%aA5oil-R -z4HLth$uo!vb|z3Hn5;oeaLxpZhzWKk&*(9MOByCPX97jUnnocO;>B;aiS>Bd&El)V3c50*8K0F)i4Vr(X -z{@>`2)W38VxKUG;rwqLdPNIC3mm8c!fpg>rdza(LjiGnJNtCaU8^a{ZapcC(yWk`W -zywtccOrjkB58)=YGD1xe+b!9c5QqvPZf2*_J}KQkis`PVx5Sn30`rg5|2u6wu>v=R -zDmT0I+*pvCypt$!u5n|SMA=2Sp|E#>BH_k@+~6b%6bU!CWACy{&kbDCxWP#jC=zbq -zH~%Agmt2L3$$!qqlb2xQ38$til%aRQNtEWinBXJ|oD)oL$KK^A!32ufyWk{BGh$+x -zL^(<@fp5az1t(G9rG|-N66L6giP^jKfA10oOy;VXH0v>`MNINeqQJR^iD43@88N}$ -z1&RcdTEqk=QJ{#JVDHkb#{@2EnBXJ|6cLmEl-|X}2kmgLyyTAf=M#(Bnq6X -zn0#iKMA<3>X~1x&6~G5Mt)lhuex-boZV*Dx_mqWlsu!OjGV1e4W> -z2~MIw5i!Be{66ICIMBka5!$}l)sbON6M0wT3#KffkF}V{knXF>6UysQ= -z#3b(|3Y=@07$#Bn6HH#m&IF1ClX-{`ctg -zq`x~8*m$x*%}ic5bS5~7ax5<`ctgq`x~8*m%;V -zW+o3CIuo2TIh+?0oHK!Qg2_YJnY=(Sfg*M$IA?MgF)_@Uyg)F4Z^F(5=S<+GhKXU$ -z#WIg<{= -z#4u;_I$~nzOmNNwUTT;a=1g8UF)=aee@wi9$xIcKLwZb>BPMz0OyFF@#4u-ah+xu# -zoe2~PCd&~MoHKzU!6bv7$ss)^a7n`i=S-kTFoEARI}@`r>F>@2HlB2;nMseKGr>8N -zXkJWk&IHa0CK>EZc!CKOu`|IrlPF?hm^0xCCh$$znc$oWywor;%$e{eCMG8Rk4Yb3 -zvO>k=IXxy@5R<%fCUCA{Vwf{|4l%*b1d0TcErC$m<%PDl;oW=fpZm;8}xG~Uv4Fsj3b@N*H9#w -z3?-N>$2k)y5=_RD&Lp>0j|p5-FM^+- -zG08h;0_Peg`Z<#?_YzDFVP^tGg30BG3C@{7kzjHVJCnV7OyH7+3C@{7kzfM9X?7-N -zXVTxD32Z!>sb(gJ44nzinS}CUf^#NtPB1x$oe4`Yfg*M$IA;<CLfsaj7K!aMvavdUv@Xcq&W3HhzP2)NTNRy-E8*qI@K9OaE0hEj -zYMuE<>Lb!fk(ro{-4cl2654h53P0D)x3b|Px%FVqWs5s)4r<;7rL`&3xlG$3RHl7?&Q0nCK@_&PNavLuZ1M -zDDYClL_dkr6EQI{G3kFy)&VBdR7?)&FNWlLLB8;F5+3PNG1OVDgdKnV6Ui04A{U>BnrILFwsw<^t@`b6YFxiBd;3NtZ5fki8eyzs@E@_zHBnlJ}6SFfh -zF&O|%VB^UVH8c6h(3#*Q$~Sp2!ATT2M@+CYc@r@)bS5~7@(p65pF}zTCSqdfOmGqf -zUTT==CsBIdG%+zT>3>Y7044=0CfoIxj3Sr_c_&feT*c(LVG?CK!DIn;CQu}pj3Sss -zaS{cJ1e5vLnQYf%0+&=w-oQx|C=yH-n4O7<$pByi8&8~SX0kxvnZ$4sWq&?Q-o!~1 -zI479Q$Ic{3Fo7cJOaz=n*-tR}onaCsNHBqKBAv+zoJ4__DkktDIEfN8F)=aee@vbN -zOlGT?JfX+rX2c}#Bnq5sm>4EeoxDDNXChDnrH5EFf8 -zasnq&;H8F%VG`vP6B84Y{>Ov@Oe`uUje1P1h)Lc_6gbx~F-)Q~5=?mPOrS_Gu_7io -zi2_A}35T6YqaG8uq+x=SC{QGr@MdRXVln`jz{V4&nwjv1&IBh>!g(>lNfbCIm~hyc -zv=U69h@A;eqJ$9>!z4;8!34euI}@BlftMO4hDnrG6B84Y{>MZDOl&G9EqY8mh)Lc# -z6FAo}G0d5?AST$EK#^eLK}>MY1d50Wb|x))OyH7+3C@{75iv146BCmGzyvm)IMvLA -zH*_XAXOhZ`3C@|oIbwpHiGY|GIuo2TNg*bNITHafF?1$4X96!ZObl}-f{BTVN&jQA -z6fha1VzOJ0$#ldd@0S8Dz@%8kNOmNQRjl7uPoC%y0OuDc$;Rq&B#LfigOx{3D409$N!34euI}@BU -zftMO4hB*_?#Kgp;|1s$SOqQ#d9MNOqMNIO}nZUV*iDAy<2x5Yr2^0w?Uc?0FOrVIE -zU}thfj|p7TFu^$!C?Y0iXJTS90GPnWlXGfj^0lEe!8wz@yqMse37jJ)*qNL_Obnd~ -z&YAQfCWbka6NrhSGr>6%c&TAxm@_$HVq#*_|Co#eOopnMY|~>hoM5s!@03>ZA4jWHa -zsF}$ueP`msIg>s4FnJW`OyHbgG7~$K0Ko)`q%+x!b0&KTCciMunFI(X@J*yMc?{=F -z;H8QQdVxV;F5+3&Y3_FF)=$66O#eJ1U8^JD({*K`m%Di7y(ci|i)MF89uvk03!)Gb? -zTB_+PJLPClYDcGQXE4pBJ+9da=TSR#pIAGLX|AHbvQv*VD7AyrwG)`y@*Y=n!dYvl -zYQ@?y9lqKcZ+j_iOJu2e5o*0yJG{f!Ugd4Cpt~K^&<3S_e7b!EW2^3Qt&TfaJE%ns -zO8bm-`w*tBl0FvCQl1DkU2LD+;cKh#w$;$ZcB-a9X&;$xpT;m{JuW)o?66Z0Hz@5x -z)9sU(?s7Vs$WpT+luK+M*Wv4~@s25_hbFSpB@yW^(RL9trmDyFcHH^4LmJVb*e0fJ -zg-la5eXm{miD(7rN(~Wdv}l{u;X70AJyT6@ -zif5&tMx+}>+bm{YX^(4E!nxlr-P547U6gLSn3-46<9a{gwA!UrVq0N{?^w0>SQ+g} -zWTldbv{`H$%&f2MaXlM%KI@PsHz;kEblVtaeNB&RS=_nI@%`WA?(n6{yy+^sFP@bi -zi%5e-W_*XQxZGP@P1o2ZM}xwQPBSx@!=*j0ISJ*0vjklweUYf{C^CHrEks03M>!|W}RM0&RX=sDeJwDw%f>~bO -z56UlN4E#LyIAYL -zCT&tIL(-Os%&yJ%bj8X;(YO4Z&rbbBw2WnT)zA};Jl)6db@M-9t^b6p1!;?gsj8q8 -z&pqA8Pj&N8v(`_bK0V#NKyLizowL4^Ro;^o^gkTb_BrQs)=QJt3G%A%-Z|@=UFMx# -zMZX9Cy#M3oFJ`T?Y14^1~uV!kS;kHh^N-Ta%Zb(Wxxn=fL+R|-n& -zu1sr_Ap84x!Od@G!z<+atzEIAV6-T}o$AbmM<&Bp%k{gvVlAO)ou7M>4O;}IzA00` -zLr4bu_=ntlhW&mUN>{8T5G@ID^E-24Ycf1tmJfEtHv6NSgPfBMFBKGdM@HT+^alF) -zoSPradM*)^qMezd1Hx`U7wF7+rY1et%SGF|V%5QDb%0B-p3!pAe&JMr`$uQaGbHJ` -zOm5lP6}vJNecsRgmh}_~O3T4a%Qj(cu#dmP&40#v#tKTy{!Ggr;e3cI=*)R8O?oEC -zbqBg)Px_-z2DvqzInNDAPl5dXpRn)a+ugj4^~@8Lx;>e?L&6e2*VLKwOiFqd$;s_q -zvDbpp*8*I+Gv^te^vscyyM%{Aef)AaA7wqW1SNSWQ?gYU8|>pN-2B_@_kY8_D|Rpt -zJs9F9b>>o6BvTj5B~8MIe(qH^HA5~r)D@fWkIoNrH+SYz*CkVhvd}1Sfj&Ov=BKl% -zD+NW^l@XeRE`J~YhMV`YsTK0(tzEI1!RX8Y_ikq{H8PpHTHd_7D|RFlb^5ud*px+3 -zHaBH9?-0%f`}l|5d=Hx%D);W~imeDlSA@6)ow<}XnVK&59_)%e=8rxWS6RrCW#TKf3k -zx%pqP))n%qzl&#mvn#!`%jtd3we;~ -zADeET$*d`*r@{Rny7>=S>-$i*q?^YuYv5BK^hX~IazACQJy0K>Zl1z?Rng=6HsLI= -zQ)LZG?TB>kRK`+9S0%F4!U*+%SUaS{*IemsE~k$=sA*#DWTv@-{wk5B3L;dMSUa-A -zS6l6^Eu(84l&wLjEl$@CW!fuyTy1e@n}aHDP->^7YsWFLJSd)}Dk9Y7V*At%pRLSm -ztD?`uv(%;tHA-xs$h4LBxQ->9>+RH?4NCjibo)$(DW!`OS!zy%S|_#_boiJmFH=Ex -zB(l`F2z9I2K8oqC?s092JGVHfl?_V!th8+qGp4e~wIlA_;gH6Qwu?J_V=BC3YUs=3 -zS?LE6=_=7y#59%B_d2BOMcd2{-|ABD>Pq^T@vQW-h;*@NvoNbGdR%`@I2YNaA2ukq -zQEA(B=1f_SYg5Acja_9%3av8ojw -zrZDM>9#>z&IovLlH7Lx8G&7YcE~9G_S!rQJdO&1`bodTedJmV=FF2%WA~TseTtWXe -zk(CM}QkBSz?C{amUb>8?9Fna;VT#ktP^P1@$Mt&L`MN_YZcvyhX=WVLQA3Z5XQhgW -zbh+3)wZpf(%)7jb{wSW6HbtaSV)sNQTHfR06V8ox>COhFdu+OUCbOlKo|VW-b0X3@ -zvAdwdx24LvrGowQM&nJ -zX0~^2SL}&U^hbW~SFE)i>P6}1Va(AjYrA3}2cjQ`xY4ZjOQ?@bH&0{MJhHYc_DV4N -zN`U(x_?@v4>K3ti6!X<%YrA6q^hf_0-7Cxu^zoAMe>-}6yXD&QB8D1i{ -z?&yli!KfVIdfD(`L8;%HsoyCSh5Gm_-Td=xc$%QpAI#Km6JXg^XD)0@hR4YD`@3Sv -zKr|WR#Oi<))8F`$yl!iuPrSb_vxXZXxTrMlRYToC@{vBi;Ny)-zF1 -zS`K7dwhPY(x%)bEo|2?znB20jE4DTeT^r(V=*)TMCp|OemP5j1e;>cg%~!FWg@RJI -zJyX{xJQ?WYzjE^y)-zkK+tn4jJrw=K&$V^tJjF@RayhwGSQ6~xSG)N$tY?&i_$m$Rv>1f^tmrsSY- -zi@%TmrJKKvO)Zv7b_gE^xlL^9MnMs_W`w=M{6HW7zMHqQskySSyDP?pq8t3&vz@ur -zsMZ`N)Q@*k6Lt -zzXZ5{vDQCq+N3m(PdATXWllEt_wu33vt&#{q_j8L~PC;KdzkKmN~socrd`7h5F10aJ?eQ$dM5r-h?W7K0d%3s0nr7lzijGjr#oAent+dBACgE(dQ};F~ -z?H8rnFJ^2NJ+3ne=R7-gv)EqP;cKh*ww2NA6Ip6mgz}2*gBhl>$8|XFJnW#RG$`$s -zbo&^Fsp)Yok2{w;s0CvC^bTKlnYX)&&c?HpFCq;RZR0z9W6Hf_s_6>5WN%Pxqtmt- -zOjBu(>+*y%WS88cZ5Y#3MSp3Re$k-V2B&QknAPPyu3sjcx7np1i?%TxzST9}Go|#R -zL{_>cBHb_AhIjbRRC&)-(BC+uAq`5~_;lL{W?prV>*l!gW`}fLgVHu5-8O_dR!N8B -zS*boE6^U(=JAB6~yvJ(j>2|5QL1`PAZkxueFY9sLnQ(q?mmX?R+J>gvCNb%9`i(?Z -zni-LtV%xY5U%JLyTuKj5WTi_Z(%m9+5mQ{%<9avleAgk3Y*3hqX{L}lTuraDOLvIO -zSmtm|k84WYImIE(ZcvzMX{Laot7s{nm6(V$Mr0;+_&UnH9o6*1@vKBgq~#(ri&xiWFD!FjCuswEdkL%L7^HK-JLVa=4I$G`>&g`n9|7@pzAzJ>t>$uXmH`BONxD2j3 -z;!cNyS}aA(ux$75vkfnYap>7l{vzXbxxVtMhF&Lc~;NF4y -z#0d2xvH5>?9amNz%&gib{3yu%80z&Asz_|kKz&bU)gj?JKX(A?S4OC{V)IwKjw`1d -zGpBb8ufXr$5O?0-pyrFseNf+#IlW)_XP}S&&dm>D!_2Q#hPg!*6~ -zU+3nNYNe?h)h=H>@)kzBC!0AlD!0inaKoEkSN=XD)n0GF%|n?-S|*ef%eG -zehC|%Cn)uMGWCZ9*izS-3r|Xh7s>MWu9y&v3IVRGGZ!A749}6}UBc#2AHTxQpJ2nY -z1VuiSDcULw3-Xg>p-y@O+?;|C^hi#(J(4l$KqYmL}o6zmGre<{x1_E9APZU9ri* -z=;Q!*vNPuyne<#O*X{0#JsFDL?&q3Wk3~@Gnlg1eginHfJmcoOSE>gs_4hY#QY?Qz`k8gST=?C`XMF`_-hwLn4|eMBPo2+MFG^akkPEv%KI_|6 -z?cG&ID}L@J);dEjJS1H9=HedLgoN{PJN19yYGKkkS8m)b1Y?VPTnppQg%0XPs4q#T -zT%zT#M~^Fw`!kJugujHiix!;8QsoiqGO_tzM~^G3wr5r~3Qt5A_qg6mIIp%-tHfp* -z>P?wdJA{ux(m@cVZpoS)gL4E)aUq;-ybdYAAZ -z{Qe_x=OYekMT62jD_uK?u~hcBcEz2$9MlA{_TmnorNV2ep=Zal)J+lUYO%J6X)dGJ -zIH()M+L;}`+EQe%74ReEjZbWfdOl6Pj)wuIjhcu%>u}w+a#xZAV=uz>kR34Eo6WgYC_~w;)=T*_~$FtId -z5vfpYo5&n1?{S3_PLExxYf#$8rrTyR>r3hBiL7*GL|QAh6?FL4S9#Z0(4Qx=(%6V} -zi`X`bNmuu{ym6=3A+2ao+GeGhK}>OFk84ldxyK<*5SfcRe8m;s;u?BRJS*K4k**e* -zBIa-zz0M)sATl#Md~~UouB4xeXQed}$s#fqhOX#wNeSmtyR^DNVMe8y=}bpikL%%t -zv&SxN5xWO<_?B0CmzUFr5?N_dM7mAv9^K(vUgM3H(hD4twL$4FN_P)qqE$Vvuj9_I -z9nx^IdqRhAOSyMTHSLOLB`P8<6}yW&eA!ZOwvvw7rHu_r_waQ06sF)8Yr0}XPF&|L -zD5tl%p6TN+ar1uGI#n*roj&W^RqEYUNe7(I^zm^we=VDuC0ZskyDI2EJE)!1`JDB# -zq;;a)_}%HVzN#{BRTZ7EQx~89dR$8}TOd6R>B1>W6|v=+##_6a|VUf1LLZNhnGEm#)UQgtUsck_?Nk@k$0e-`o&RlqW -zGJLH(ce~IS?Bnlo^M7H(7YWMTeVMtt1j7#0KEBY+H?rZ0g3@{*)4E+~4RZCJxo}A` -zJWOug*A=S|MC(IbNoOuRKN+4Ww;mFT{C)gxH($+$7Ya)K_Dp@F&=Tn5&%61_?DtDh -zyJB^rXwuKU)|m?zC&SBSd8<$o?Bj27^B=O|QGy~jX5`(15bEP+y7?n)c#14Hb;Wx9 -z(cU2USZ6N0GU*v47wzqe4GTnvg}6&u&sBm_v^!IDP^k9z@sGQC2kTiZ7wr&E1-S=U -z&y9l8vNhAPSGY3J$G_+1uVy`S<(A!DvFAh4wSMlI&YWj*(z8Tv+0hj{AB>(4aNn|? -z!Gcn^H&eG$m>lZkXS?~MtY?~_)E&&!Z4+(}a|?4oBxtcT_h+a`!XfF1jD-EK7N#&-_NEd3W{(bBWxGAAm{1KrAm^iVY0BV -zE4CpJ-4NoIb>>p@lc|}qa7dWx@8kEl`5HF0P*65+&unfKjs*Jnzqf>j*`RCZw6uGylE0*&| -zb3twpeWF`Hw^VvTBQ#bE(P`{SW=dAOS -z)|qnSAz|X1OL|-*6V82h>Mu|qnY3OlugWCP`exVs-|z+MTKJOGhc8gq!j~ioU*PvK -zd`X(&iy6KQSoqQe;mavCe7RR2zD&pP<=%YZ%Q*~R;3^4UzQFJW>RR}6N*}%~#qi}6 -z318r!hvCa9628Dc55t#JBz%GUTKF5S!aeXX81B-;mbJ)Up9UpzQhdSOO%8!(Y)cy -z*BHJ;_2CQDweSV%TKKY2AHH}oeA!6C7kG!^%SIBuKpn%EjU;@5x)#1f_2CQD&G5wx -zUj`<8Spnh8EH!)?rw?Cz7`{OLe}^wSNcaL*F?@l#8oq47@MV@heEHX1Bz%Fo7QXDz -zhc8gq!WXEM@CE8x__Bk9FYx;qzChg!U(E1jV8WLg2wy^K_>$0vFNZLEN#qM(9>wql -zu9EP@hv5sBASOYvId#Bz$?)5Wf79gfBh}U*H`H -zU$$WQ0(BC;Jci*5)V1*CJ$?8Bbu)Z1! -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 -zbgGyfa6%!GY`}Ht^M&(16&)v^s -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 -z<1vAosF?2J0$>gNiGZC1y0wx0hlfw!onmv=v -zh{-3qlgVbp1kPzPp*@p32@}np$!5f4A5A8kc}(skOf-8Yn-LTEO?5Ka%wqzb0uzBr -zx-o&w(PZM%!vxON$;8ED0yj}Hp*<5QA|{{EWa2_hph%Mm?U{VUV*a5Nh@G72{1XSV4~SG*-4n_P9{4E6U}5odnQW>6V0BOrp2<$ageH@nJSNa7FcFxf8xzP(&MTPwU4sctCi`_Up~+-Fj|tpF#f0`uph%d| -zWU`+y(M%?^XYzLqCN!DsCrmVxiP$p{n6v^WJpq%i6-+dHCL0iw=X58N4TuSx(_}(> -zCPN4l&7R2y#N>IJOg8YC3?WQ3dnOwY6ZlPaGTFdm0-XXAfk~P%`72~5_b8bBmdE6I -znoK^>!vxON$>akb6S#?r3GJCc5ixm=CX){k6DZPTLVG5^VO9+RgD6V0BDKHV3q#F~+OkPni`GUvf3QZ=m9wucpAlUE57&7R47gb7V1@9~&Gr@%yDl5R{O -zGr6i@a!rE?O(uR_OlUIk^O(R*R7_~k1d4GKSwX`C=7flA$-5e7p)VfpeTpZl^tyc8Ezfzh~lHg_v~1$)t7_ -zk4ZbkQAiKiMdfg(;OchH{68Xgn)O=U9KTaB1N5hs(;V$bCNT})c0 -z?~DJcL#K9aa>wEa6+T_|{QL`_F1z>qisoM4%Tukg$!VJ$jjT;s>_PJ{rQz3`*_2iB -zDQ|dt*0AtgPqMso~VDewAazAI&tqI4jeEY6q)8f+blOd_6w5!B4Fu#q2Pp-KPpYTxo&_fw5bx*;ZYmM#`C*>078aW=J$u6!e9*%mNwGlcs! -zvz43TE7yB}SI5HLJmCjJEg6!pn8}l^@@LMbp$Uht#Qs{YX}BSLTQf^+i6_>0zpQ29 -z$)4~_p_cYZ|Le8B*K6FDoK3wFj%1NNSzv0Lv7H&e%3mbsIT~p)! -zuZj~ayF(=V)@VlAx7Ymnb-shu?msxQheR{Bd2gUdbcJo&7~fRkoi}hilkc|5e{^P>p|~wRW0kjWt-BC9$3?QcMrX|a_L~2#8sA%W -z?*3355y{Ss&ZzXB=|7&y9;^IX_bj<0c_fQ!0Cva_Sd9{={5|C2i3 -zbJgzOLUCXudvf&HTJJvxjA!zzR{5IK)h6M{EVO6ln<|3L)g|J(JvwT=cT*iRcJ&w^ -z2$f|d{WI!($Ew|*I9)@cqqccRRl7Geva+tRvcXbW9+UT2<#MNMN_5ZalqDxyCsYr@)?5Vj3M_t`QMeX0*K08>wc- -zr#!}cLk+`{{wdYIDYfodPS=ElL&~#DMW%}Z=DIiH>Ku)3Oj&#Zv(I209%>kv^e1Y3 -zi8^=NMwZh%meWP*QOx9Z -zcS-sO)cJl>?cUwU>buA4he&&KnOtR+%bd2H=98d?3oSbZ-kR>I`=R(Y+nsdvILwAem0 -z&s1Uvk85UAw#KKd_Rgwh;X6FxB_XMkw5!PUQ)&2>kkmHmA5-faQ{z6~$fS-jDN`~P -zn8HEU)G5+5GU}~JSw0JzUn&ionwfV)+`G*?tlGVyk+pP*wG5J`$}2*34F}jj!D7{h@}1?VfPwP)i@_wR|R@w#s)oo3ay**9z>fm6)anSkrBh -zrh(B!r8ia0!WK_>dMLB{4_6%>?_3(sSm$jwa1xVmw93`a>_O2C^LN+$`PIJsT6by1 -zNtQh^lHEO;vDtgD#{GYs+3lj6p7`#X|K=Ls&2{eE;e1piJ1e?rt9M@iNlbp%DnH@O -zesS&>uFgHxnZ07}6?SYx{Ma^cMm00$d5kxO$_6FX0~Tje9wCCo;r6{BP;6{E9)jT6f=2> -zRrWev!xD~$5_?XrsfWRMOEW9q5-(rl-BHVo6FkP}Lk;bc{@Jy@*){HSPFIhFqrS*q -zUto#_nX7%obxSn5&O4=!83%fd#!y3#q~BZTTUqV?T_bDg7HhacYRNOb7G$pB5!du+ -z)~b}HebBtNG(4x7Wvz*4ZStrENuJ&E7b-&Wca)!t1+eo7eO`8ME -zHZEf88lAlBqzgn3OA+3wP$>A{xAtunNViMvpF%Tv>JSHK;1UgkrLOdo0fr-E*{gcTim`vs=n2h5w -zIZT+G(8C1IRZLFsn2aM#CLktIL`lgWt5vxLcH9+U486X;Yi`JTt*S;Ay8kIDCl -z33RHMe9vR@tiVKIl738Pz+}=_!K5pX$q2&apdKc0u3~bK$D}J_^3GVq1d50WbgGyf -zL`SaB>kBD9xz#Q9g}w^@|c`KOh)Kpat1Mh -zbHwD=6A_aK5Rbc11~GvmVIndUfk`W1@)2NSQ!vqFCg%{7g}RuWLrmbDFrm!kNy0>v -znVdsRpi{-<9FNJ9go!3IIfs})r;5or9+M{pCIXXIzyv0f=M+rt;W7DOLhcKbc1d50WbgGz~LQJ4Ym{4YN50434q+)UkF@YjsA~F+!Nh@IT1z@s5!9tCK(DQ9eGSL36leQn83M;$pIddj);koG7~5wCeW#3asV-bB4Y9wWhNbYOyD9F -zlLLqe6cLlhMP?!}X$4GbuR1z@WWA1wQInYj5tB?^OoE6BoFgWWQD#zvn3QQUlOSRO -zohl|l9+M)(1fGd9lOSROohl|l9+M)0iNK^4FoDTrhJwim9+N7<A_=?LzsN6hY6gkn0(D+ -z(gQIGQ)U81!~{B3Ouj};poo}+C^PB7V*(ecn0$?xKoK!HCo&U(Nh@ITK47BknS?c& -z$yvlCM;DW`hzXn{CLzj9W+EmHn#|-ZVgj8iCTDp}W+Eo=Oq7|NMNFVm#pEoH$xMNX -zz@!y0fyrdHg2`welX}ABxE>~Ou3~bW$7D2NLYWB^5fkWCF*%NyK#?$^%w#l=30$ON -zavU*%B4Hvj6M;!9VDc$oqU@Q3HJQl;#H3yqlM9FmoD(LLnJgnrG?~c-!~{B3OfK-4 -zEF(-bnaKsj1UgkrF7TKv6PO50(vL|LCX*=&CPR5lB*Nr~9wu -z6Ut0Xgo!3I2_q)ZsbUi5F)^2#beSQF_}!62^0|%=u|L?e1(`m5iyxa -znMr#d6Szph%uy_WBLCj_uv1&6*JBF-WRJ`c$OzTCRBfe6w70>&nmy>v`tSqhUVIb7MeB$Sku@@QvZCItDa+)5 -zd9ooqx|w+^b -zd2XrkiBM)wsiMTxr_^`|&b!7k2TMgutSO5jXbzSdUkGK^)m(KPF0>!cH+_7=4rUzU -zF+Ls2l%ZH+ACYV7YB1KWzs#xz#i}|;BbHfHmZJglQG;<46#K@iGNj$brX^WBm~pnp -zI3-l|WzAK`!d&~pLeutA<7K$0W2`DuT4=MTEa!vfdrFO`px7-|b%XR{p6M0%&HFsY -z*F$A(lKzZZUq+4lU?VH*5G(61WfqtY2brrw#C2En~F=dt- -zi<;Sy3EUI&Y^s7Vhl{mxgk> -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 -zCKK8-G3#PNdnRyBn9yYM4q>91OlZ%kB9 -z0FxC8CZF+`{6LuK?wP>3iiu{=ZE>ba}JrgJ*Ch(hLG7*zWx+jyZU|SAe-DL|omX(M>7K -z#en&u!Pu*rMK{Ky72cI~?)w^9!@yWWFR7)3$!)FjYNxGt!qKDH-XqUcUIWaldCjb -z-pppNjnCffJy*lRD?Q;(q53}3vV10=w92EMw(NvsS%H07iRs<|v)vZ44U9%Az42-m -zHhaSNh3bbV{XMIFJ!{Hl4=?{_uspBh<9yI4zK$(L`EgRH4Xq-k_?<%X2yA3^i*(r`(r -zrEAiEU!CvEYPa0TT6)A@I;|j}I9naY4&2O2^&(70nz6xqu+H7ZnLW>Og>70F-?YVB -z+dP@cPOEHnW>1N33SPSApI7UfSL6N;{x{k)l07E6DSYXg|Ic;4zSZt^&TNC@3Y)Pd -zK4Xpdt@vanFR;pgb!HbqabtW&h4+y<_eAI%9myUVopI^XHUIc(-}qYhL(c5y9aq?~ -zHSuGcyq~}`{oN`Lab_=uVnzH|rT3rJ?k}KocqDszbkwSprDM=sQEHsq%toz=kJ{wj -zRO9}0BP(kcE9)y&()n_iXi+ -zS2N>Gk8yOU?1rR2TJ4M0x>q)`vf;6YHd0QZsWQM^<07uE(eh0x%gKQGq`}y&nU!yh -zmsfaa*ST4Mxq3ugqod^;QkGcIJhaqU5^Ct0^iQetd8^&-M%K_H)-Y6R$z}5Itg_kZ -znjDR;O<7(GnvES>70-IZ+o^_y=Xk=sLplAW9tBMPlU45HwB4F;ROZ_&i%s)O -z!%u{AdP+BCS^&x@=S{j;d?^TFv*n5!q?(A&3DdCuwZ=Y6ddN{zE -z?uaxEj;`FAvfLFg-(?7Ahg!0d{vWD+Kh(NkYGf_LVl8c@*9uMV1z6LBNK?0HVpGa; -zDPX>22={7ciH-3@h4=M3_w+{AGBDQCOX@giPRi1@^Si!wHSVw4pJ3TtBH6b`GuC_8 -z^cu_L-d6cn&g@W|D=ecjp0U<@u-5&IGka=u(<<-HJ;yTneyjYgGy7PZD{RxI_@?#V -z+B)|jxXH*!_JHW7X%8OPneMd8A33uxw7J5L -zZH*sW?R^d&W}_+`XF=ljJU=`_iRX6T7u>trN)9#LzkpKtIoHh+WmebYv>+p7$Vi@GWj=F`EjQ! -zCz|LbF!|qr$?D52^O@@Fm`n|DnEX#JV$x%x4kmxjMNGO+rCX)jkCc#|9 -zr02wcV{#aZhzWEmm`o3Fm|V$4OyHRmOn!nQVgj846M;#(F1lS`8-S5tAEr -zF&U4T+{j}BH&HS97BPV$VKN>uxsfm#&tvi}Vgj9n$#}%%M#5w~kIAjAn9LzeCLtzJL`sm -zgqT1lVKNRe=}nl7<1slTFcFxfACnru#HnBs;xQ>DOmg%vDJ4vDcuYcwNdaLJ;xQ>D -zOmYwtC?Y1%sbUi1F)1ZXau5?JA|}u&FcFxf8BeMk%F?z(nM`isG1*3$Nf$j#wo+!&g~tSLqGECoF@YjtQc0Of7sOJCh5oIO~B;$3MOZGOzuZaDs?lH`w^2Zn#|-3VsZ;%a)!s` -ze#B%eWhPKWOrTT6EX!bFpqL=clY!X(0DVkJx{Gl3#v0-Y)*5grpOVM3V+6cH2X6qpE1(v8Xdl%?$v -zWipws!GtoCLAsbwW-^G!1a6{Y@(p4FMZ$zKlR<=uCNud4F@a9Pgff#sgo!3I`9@$O -zFiAfq9|I;IDVUt&F?oV8(alVrAWSrw$vMPiK4Ef>$K(mZgfbH-A|}wOVsehhc{5N3og@VZsJSHy_Cc2r)%Y=z0Gx-5A`3qt41CPne -zgb8IPP()0iQ^n*59+Q^|6Ut1Wh?qd9z(in@W=!6NJ(Js%$)q2T$-|VHbkM_O7G)+K -zcue3XDkcXI6DT4kGbuCafS5d_$xIF)CeVqPz%!|tNe9FP9)vQJ0|FC)N%}F_2$<9= -zm;`xD3K5f;x|vBKV)BqCGYKLl{RopFk4Yh7GK(@3C?Y1%sbUi3F)2h$;F;9S1d50W -zbP7xaCh5im_DpV5CX=@{m{4YNt1c##ncT`_0yj}HIf|G-kuagmCNnvVm_R3CLYYZ_!bFpq92S@eOwy0Zhk(f*1(OCIlg9`X-OS`M!bFpq -zG$1CA5+)5iCXW#&l$k&gF@a7MlLj7>#|RV3OrVIEK&QY&V3KZ3V9(?OWimOd!GtoC -ziMp6jW-^h-1a6{YauP9tB4I+A$wb0LlbM`EOrVo6q0D3=VWP=QP6|u}Ch5oIZ-9wc -z!Q>*3$qR&uZf5cVVWP=QE+Qsp36qOFCNB^sl$k&gF@a7MlZ!kiFAye_nLrUSflh&m -zz$D$6z@EusWipw-V{)1@lkR$$oTAL6JC6z6M8)K5!~}|n$w|sgx+5khG?~fQhzWEe -zCh$yZX3`xofd`??cYzIuutWAYGUa#A-lc?dB%p~+0nA|?|Ele0V~ -z4Ba>1OcpDX$vzDxl$qSAiwR{W -zck-CPO;k*dBPLKJOeizClQ7X_CdUyI=p;-iGr5y6(PSpa1ttQM^kZ@!F!@x$o2Zx^K}?`Xm{4XigfP)$CPxqx=p;-iGZ{jdXfl%{ -z0uzBr`Z4(&FmWrGgn3M!CQNiQlcxz2O=c2COr9r9!aOEV6DE|IKoK#4P8E|dkIB=7 -z31ucwL`7inMJ0<0p_|p;_46` -zwJ~Mc9Wd`U7zc;S21r!}rXLN)j?HY(8}U8syrb%vG1Fr#3zhYd%1W4=WtDe0T>}!1 -zhGKg|o=FNa*RY7|zG(R>Z&occ-r_ON4>fd1`ghd&cGS2pH?oFyv4*}r$4Apt-2jXb6>cPx?32`DRqR-)dxK8L_e~ -zsVdL3&|thLR5na1%VqK=t31Q$8lP~K<=M-MObw+*shRCr9pAIjTVBJA%RI)Rp|XKV -zf3(IIt#fyBx^7B1a`Npt#ip47=DH)|8XPU(nzD=zm`59o*`bCk@sj%g4KJy`3fz3D -zaKnG`a^mAIi)1&YYc -zm6NP#y2p55sA_o9pHc10sCDNzva&(3vJL_h@x_z>+b^Cx0h=fTmD!~mkI7w>s=tNB5nbcIJ9by6xf~m^>uLLGy -zc1i#2QURFMT*u@K%@4unmrupJYK4LP4QWYp7CeW#1 -z;@5ofBp)$>XHruYC?Y1^1SaD1S?T|L))TOaGEkXJHfu1UROMz}Oej^kna2cfqGCc{ -zJb@x%LaEBlgbAOj?4vK9Kqp~BsmjfS37@L$|5jikFiAfqhXIq16-+c=JefzB=%y<3 -z2opY4`Ix?VvY9Z^eDP!+VM3`26cH2XR58(f@njxhLa7QA5tGdV6M;!9U;>*c?Rr(Spe5$hlkibM> -zl738f1129Tm}tIu@(5v~o2ooQnDD8}$MnUM2MH6+7f&7`Oej@>B4PraDkhpQo;*UB -zP^tn&#NyAL4k?DB>k9F0VcZ@ -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 -zkqS0B15Iw<C`aX}5 -z!r_U+DZ;rjB3`nHLp|23lw~{8=DlIlj}7vD9c0({Mh6zV1_`e(EUq^(20$)zV -zA6vu^Jn@`vJ6~br%Xrx+kLe)No}^SSZEzDg-!JnKVO%QM?hed!_;z{X6T0n-D{YHQ -z_oXZN4RJ5)HC7(m5;@{K6IZ!s+XZk-$ -z8nmX(SA|Sh89C4E7fEhjB6pZjU%~&Ef%{b?cc4)5XKUL0M9B1nk$W1}a}&8^go-MD -zUV9Vae&XkDisbhAF4<3)*iKjQ|AOLg{M?{O<9K1VWKEm*giSv(a38;Zku;7@G|mu? -z{mGg(-xxN%Xy9rhjTe2F?8ho>$IAGBz-Jof=PDzOBZbwctZDNDA=3j!?p4^CpJ*H` -zd<7rmWXN>V$jyv2cKI&ZzbdnRRmBet5$}~z?|5a-zO=a_WU4T7^CHzVQo*H;z*3j* -zz8I;_OH>aN8Y}p(4BW3H)dPj6pI2@~(AsJB2-cBaj3Vbfv*cW(z#>XXWTsoUW@6(g@Va0W|W6S3MZt3*Es{% -zxqUarNMUZGaEx$w6~7=vtk*@Yla;3ZY4f8Y)1yZD&JNOaFu81tG}+~=h>@15iIyS4 -z+zKMDwuoPOtV6r)C(3OnN_nqQ&g&q{_9mC@l0J14d6-|WjI@jtYAcC2*CL+qSf_W} -zYpZODV*ZXWu}+Cv7b(&0Qqo1_C4Twwh%g`(9P0{gG) -zTBWEyZGItaT5FIWhzMhaBUStqgIv);q#a3VpX758x!NxmMudE!t(b_1E#iZo_`+^` -zTZyf$g6|5E_>yRRpt5PVG}B4sRepI=r1OeY@TfCz)a{!RBb^fyojF3FlHV92@ww4> -zzOw0H+B_>{nq`!)k91B;1y4Bwr(C{`G18fz=o~Dh%86*Uh+lf*i~nbL{Ue02&m0~gr -zI}<2UOomfTHZP}`K#^iH6FZZwEGF=fiivGG#RQ5J6ZoBaXQFo|ecYM+GjusPXvuBg -zVKR&DOzakl$*yde{Ki5tfpv<>OzcdY6cZ@Y&SaB?VzP^3@+%9AiIZXipNV!Rk6S1v -zuv5hZJ_vRuP8|~+lfK8~AYgKhipdi!CRK>Z!`U!_bq$k;SxlZlOt3S7BE_T%F?pC` -z0!73GJCi3^OyD66lZPoLP()1h&P4A_`o1&y=VyS)LKPFXGqJCyn7o%2ll2r6SVv5- -zGkFOyVLOve>nSGhAtvitOkP4v*v{nf^%N7>sbR97#pER&6CIPj$K+nXWRi->9u|}9 -z5tEhKFoAUqla(wcdnhK)V`lQS3}!q?kYvJChoU$qR@{4U5T(6chMN -z*qPK&Okk&mNezq1i#jGcCVh{|M}Wx!6_Z0OCTkIsHQ6wMbq$j>EGCB#6YNZ&NHJN9 -zn5?0gKoK#)&g2k_2|T1>vW8*;MZ`q!O!UsAA3Bo@fQg!!JfG2-Y@nF@Ju4;~C?>Fu -zm|$me5;4i>Og2zV{*IVzU@!J;lU~oe2~vCQ}fT6%-RFQcO(PnbfnGz(X1)D<~#Vq?o|()H@Ts -zGwJKjknF(J|?JOhmw>K*gky#e_plR%gQm)-_C4vzRm@CfJ!kkz&Fj -zCaWnXP()0yGihWofrm6qR#Qx%h?wY|iQbv?LuV2NOw`Q8oY9%oQcUEmnAB2CU>z~R -z&ZGq~$>>aKDJC*vQp;k}f|z7}N4qgqUQV -zGl6vtlZ-i&{S=cgu`_`p#bgm;f^#NNq?mkxoymR{6L?6&1m{ekNHKxmsdpxNXVTZ5 -z$)|vcnwfl=(V5_!$!l3L!8sFHr!&3Bfs&gV`{-jB_TiPBB@6or#-b0!7-HbmN@KL5j)0Gv-X(6chMNv@=QL -zoC)kyF@X<)b0%&b6CIPj$K-jy4mt -zoCy>W6YNZ$Vljb-G)!>L1d51>-kIo~Nk4QZp93apW^xzXnGl>a`6w$UIA;RuhzWKk -zuOKFDXVQ&xCLbXt8FMDDASP^QlEyg`*r{QXF=z6Mj){&*-(zA1Os1%q>}4^z1u@Aw -zX9DXQCK+=kdnqPC>`b6YF}VdX!8sEsQcO-^XR?>Y1Rl~b!8sEsQcU1?>Ya(+ne=sM -z(h8WUnMp9CGr>6%F)JoGX9DXKlT+B4cqt}O#LfigOhm*aW6s1&F@ev7oe9pFz)lU5 -zj5!mpj){&*-(&J6V6sTXiLM#LoRoC&OJm}JbE97asAGl3$-WFumNb0$zkOt3RK -z%whr$X_(-g2^0|%y))4}lYZz-+5i(ZGYMvNCOBvEbyiGp&IHyG6YNZ0M@%w06Pz>o -z8ZpV3GkF~`$>>aQ&IER9m}JbEysl%SW77AS+y$77Q!&}aVloRc$vS5O>l!8*b0)he -zCU)#hphz*9g_z)+2^1+Nk7H-Di^T*U(lEg}6DU$l;CJesiQbv?b!YO)<=~*Snwi)$ -zIuo2Tc|I#9IA;Ru6qCoXGkJkx0!8dhaL(j;#3WFyD)w}>xz;?pFu -z=|FPRR>|b@aj|r~Fd84DY}(r%{K6Ud!tER9iC-g;?j6bQebOmMk0@Hijh^@&66xNW -z?A{|i?(}^bOUK7W<#?axcGdlH_bn=IoJ5 -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 -z<_MI!d^}R1<5W4=Sm9 -zwSP`iPNwhu`g!{I0AhajRr*hg)TP$8-E~K_V7PMT(wG0;ZEm{@|6Set5NZ3`u77jW -zzq$3#H@6X%_TZplYKk+siTUO>Gep0+4Qk5r&242d{pL2(!hCb9gu438ZLEcUa~pV$ -z`R0~mq2Jt~u6}d7+QEKvgSz_7ZHa^Z<_2~3o7-HdtKZy)-Nt-#TLg9eo16a4t$)6` -zZ9SXf-YEX=o7>N?WWTu$KGgfo?PpN`-Z!_=57TdM@H6N)w-FE1Z*EXmzq#G=TlSk9 -z)YWfpxBZrWa~m?B`Q~;V)KzMR&u6~5-Tqtp&28v>`pvDF{pL1ozW&W^lK#!DzrMNs -z@g&Ka`q}^Fju3{9UEdzu<_K(a`IdVMezpA3-W#}c*0%>s-GR3pzCU^jW+*uarK=sj -z-CNJ4IQ7fg>_46)4GqbLos!G#n+kRHZs9wizCGEnSNiMFg-B3hp;9rVD0A3v!jE`=yVEEbKC`3!DC7;JTqcI9hOxa%P7#fB3?# -z-phrdu6`$*_SpsdSEaVED*0a7RHMo1ki5Brm -zkM|0R%-Nruvt2sl@;&15-l;Tik>4uo-{UP*YPPr2>xI+a!BOuuin2p0 -za`%WgTSTA7J6$5mfuyok+T`kCZsBeZb~^*zZr{LI+InTwI$p`!*B;#I2<&wER(PyG -zkm&uwJ!04*&huDrQu205@49^>J=Uuw(zGMlv`;$j=n-GEi0eGoBBg0-JH3WGZ5LGbg9n^}18(1>SUP@fG=7Crv|swr;d{jspP>{TY!BY-2;A)Q{WzA6 -z&yU7)6sbY-IeWyoMV#)5Undc%J}K>&+8sUO>lV@Gi7!z$ZD|kAbOmNQeecE6@sZK^ -zjmoB-?ZKn&fXU%|))UW_$fo_tP1~g}Ts`71En=4^K3M7A-5y-x3@mZ`Zi%Ji1=09) -zrTaj8@Nq}rahK2Ri7%2!_x5D>UTM&fd0pm#+n);za{AsVIh(?(xW}z*50wqvFIi$<;q>T{z7`O4B+?_6N6 -ztcUujXhDH;W-`>PY+n`gw{L&0M|{X4Uhou*Q_f6(=K{TqJH?gwxvL`8Q`_vhCAQoO -z{;_~n}-h11*Y -z=SpnnD)?_hDfu^kc~GQfyfC-4tM}UaI?^&a(K16gQQT!N2%EeHxhB#wtj&I+!givJ -zkB3vth1^}{2ScU@jq<`e(vqKO87w5qyUeeLOs^Z|nUR($ZQ8x{#L*+#!=~W|xulK= -zBNDVNjd>NV)AuDgS~|o)!@%3rEWMzlT%uP`_Le5k|Jz`AQpK -z!gEHsu#O1%31P6%R^DZPEo6GlDCgG^VM;<6C$v@Z<3cI9%r9RP>73eTUtD5aT)}@7 -zO39D<X%PfXX8x8V6if6}HV~{FmXB -zJkBrQ8|fS+q$<12_K?YLSLn?H!BTO -zA{Us~YoIac$9g+2A=&D)dBdnLu$BX(QFVIJ>QO3jY;V4geB_AT*vZ;^`>$BqIwWenR>`Yx4_3MZ?>c-hd8{*(yo1tp4&R;JDNG507=2M4I*_o9d-C?jG@Wi+Ivwohh;R*Qc%XqSlehvWE8HGtR&> -zZeMOJZJiyp<|@nfOP@M=#1@Mvc&v*h65W!F?v@rhedl6n>!_%;K#A^b55DRSJm&Bn -ziKUqf?0dw`7BS_C&#EJxw?yLul%n13!LiQ3Shw#QPy7an6zxnF9gyyE^oUPc#GiWN -zw<$&2r4L=cM?LX7B_eG}O1q_-oju|Q7O}t+pQA`S+k-xLV8j2J*Jj3_yDp$oFTHnW_*HZ$=o``QfD)z@b7&(haswjE+#o4MjFeQjp@q2AYK -zDsE+8n}O%m*Jd_Do&K2&o>yO+c@XOAYcr$QFt5#Qgu4FPjQ-k8|GYM{?QoB{<;`>7 -zy*Bfo>}xZ_7tz;dp#HtrW~N@Cug$>EpnqtdaDl!yv;A=IYcr;wv#-s-^Xh9e>wZpO -zn;Efzd2QxysH?BdjN8DxHuEUd)z@Z5ZJ@8sym^j!ZDz~{{k0kWwVD2UZKim{qa^p% -z9pAk+Gvh7xwVCnswVB+vvb{D__FV64GfUxT(AQ>4pX+^X<}s+Nug#2F!MrwO96?{3 -z8MA`EHgnZk=CzrTE9h%8P^YiWj9o!rn}NFe+RTC->}xYn*TWY*eCem~WnFu4&`vdc -zDa#07KBnPIY1Z)NhZw%BW5XAyYvIc}8opeW5x%UW;S1EY@a6Yx_yTn;eEB^azCc|I -zU!bmrFFP~B7pUvuiypr8Px#`5@Wr5pFE_B^OBseQQ2&1TvYLi3@G~%cSxv(isB7WN -z(`@(xbuD~(nuaesGQtx*EQ`oe{pgtA{Uo_|k9T%O4?p`42UG`2!oitibRE -z>fZ}rc4GJfKZAxZJ1~5Kx)#2C%7!mc*TR=iY54M1M)>k64PV~Q2wy&>;R`&kg)jfX -zhA;5E9=_<|OaII)kN*(Dm$l!8FS|0rm*3Iwr9Nx;@^cJdK4ilesB7WNhctY7DQweSV%TKKY-4PT(Hhc9~g(m&zLTM)kdmm0qOlMP>X -zVfX^|?}sm6(C`I*28J(R(D3DL3}1f5hA;5E7QXxn!@Z}l|U!eZI@MRxPzQE6*;mdBEe1W -zFHqOQmnUiXQl1gMKwS-AsxrctCu#Unf#J&!+3=-O4`1}~rT@a0mmz%l{JZewK*r?D -z!!&$p$U6D*1com!v*8QWweSV%YWPx-5x%@k!*0$YzVuJ{QV!vZTMb`~Z1{2zCtslc{qUuMhA;3lFnoc!8opFv_;LdqzEoiN -z0(C8XIn9PIP}jnj(`@(xbuD~>x*EQ?Gs2hCdibJ;FZ~w2cp!ZFnHs({v*C*o!xyN3 -zFMO%Q@CAMb4PVMJe1WPgh -zHa2{L=e6(!>NI?T=e6(!>T3A1FJtlr>U#L1hcEpTzPKQK39I2tj16C^Fnodf_rsSq -z8ot2K!0@GwhA(amU+UQK1)kT!mpU50?9P~cfw~&L9L$(}fw~&L?8V8KFdM$?*C$`} -z@TLF4m(dWu>{P>-x7qMzDuyp_XA56eVfX?+gN83FF?@l#7QSRmzKq831t(wTWrQy{ -z`2uweUvTmT>RR}+lMP>>u7@vr_|i||3rxPetA;PDGQyWnX!x=+YxwdL3|}%PU!bmq -zFF5%!FC%=x$rq?=;mdJ0e1W_6z5;9ojx6|s`&JAw>?z&_Y(eah*%dyt)rA^L)v^kWIAt@$99nDo@BIM -zdd%%x93w4L5-sC|L=_PSTg2_2`1o#nex(hL!7$46I!MuhWYJdX9v6{s^kbF#E397@!j#uyc{O+VbS!Je^1 -z@4_Ixhc9dDLTyCN+kQ^AGq -zz^e}5i5O`alW55o62(M3Vi9?db&(R?o;KUUrXGX*cn2xkk}TRSjdc=vh5x%#%7y$g -zBL2-HPV&UB?Y18&wPjp_!A}X1_|?()L`B+{Hgh2p92OH1@>9VLj=%<&@4*-mrYD5q -zLR$q9Z59#kj8Qi2PMZ&gOb3nfqznjUPkdarJyl^#mGJ{t9wyuypQ#b% -z`fr)jVqQ8&v{U_a&tJ}R7#Xaqm&Qyye;H3HuU!9a@1L08TS&A^FicRSr!K=z?N4Us -zFZUkm4@G(w**gnK@1FqHf6E+F4i9O6VLpGk_YMpw(!*ijT}XQWV%AO1^e4>5VajIij5Oo~)E&ZoufKM=q1zlVZ}$ -ziT){i5E;ENhA=0Tr+W`p>d1Bh2I)O-?!QR) -z9=P10ofDHT`~M7+1AxgY6_a@^Cht*9evuWE_b4W?j+o4&n9M*-=CPQ(M=^n&8Yb_t -zn9M*-=CPQ(M=^n&8Yb_tn9R^I(J|?JO#a$LxHtZ!V)77+$uAHSIU6Rhu3;jxm^_4- -z6jDr}NHKw(8YVKu1d51BA;sh&787_#!$hW-KoK!1)G^U9>HE&)C}5%vy}Y-8#pEN3 -z$-lB<@)5-Z))A8h6q7pfWiUDV2E}A#HcXy-gJJ^f6q9RjrI-w& -zn9RPF!Q|;TC?>E|#pH=MSWE^{OyD!oKXd)=4T=fuR53a928+oc9TOdszQ<%DbS67g -zOiEcyMp8@~L)kEabrq8*Lo6nx6qD<3qnJREVgfr=OqxOz6DU$luDy+7Qp#ci52=_u -z6QY@)^YhiinAxndq4G115U_la(qaY-V!w -z9g4}1vSRWM#RS$76UaD1$71p$#3Ygp6IjuQ1h>4z==$P~aCiQ^Hitjp;7cw%F -zwI2$Igu3_>qi^)=o$qSg7K#^hsJ2gx`rkFsHV)A>; -zOqQ~kz(X1)A5%=ANHICCXC^u({eVd$V4}{MypWNZoS~S!m=%*V6cboSOfWNVnCO`F118X!L{v;_SWI3-OrqH^fpra& -zD2quAVuG0o6e%XKQ^O=mF@Yjtf|*GTiwQiWVG^a7KoK#~GZP(?e!yfuV4}{MypWNZ -zyh|}zmlczDDJHOvm|$j-hnQq!Cht;AV5f%3yDTPoh)G6f@-D>$c50Zs%VLtJW1?fy -z_n3SPorzz?WEqReI>hADY?#2hhRLTaCd&{L%uJw2F@c>LCZAGFpoo}YX0nXM1Rl~b -z`IKS;MZ`qUOms~80h1$ui8^QULPlotA;sh$Suy#LVgl=k31%imh)G6f@*%|pc50Y> -z$YN52m}F!oA5u(Ur-sRgEG9)dCORhlfC+Ra9V#Z9SWNzbn0%296IjYT~ijLhVHipim@n7mIhfpx?LGn4BOlZ?#deToU} -z)G&FU#pF7~BqK9-THfpra&&sj{? -zASRfZK#^hsJ2gx`r)}fQdS1vNj_#IY%-1JS!&WC?>Fum|$kI5HZQfOwLhEV5f%3ITn+J -zh)G6fa*kpGJ2gzsv6w8>G0`#U2TY(d`5zUN$5>20M@-tXVFK$KCT%Pxk0BBQtrMVgfrgOx|WO8A~yN&xD!D+Y}SnsbTUqi^_`xfZd}W6f2T?N6JnA(Pc87j=+j2b0k)(n6Q-?igvAmS`C&)K(C&)*>c6 -z*5TduM7b?d%D--uXLgY2-eh!_lynn$pkFSD2qRL#vF^YDhtKVaPwlqnSJ{pf^Vf$- -z{EBG&Hl=90^r6f5s3(4>B5g^Vr-V(<8sya-MB0{=8YG|77mpEPa6*_Qw3QO^yhXgj -z6Ti9J-d1L7tK!EQ65PrR_(9w@N|D)_HM -zB)&KrAFOommX2|dz8 -zdhZQ>;gbDyiS2X+|1T*1#?K9kG>#W$pIMhS?+KfJWZ*vj-9^$kI?*^oIQExyY4eR? -z(~AbKCenD_3zzK2Ds0Ef_q8AB$xGrseAY^*L$h`_X)qCpTgPaVRP8zwHk;X+Y -zT(W;vX8Wp&9~vUwE2G}=%A9>^b4AEhVdUmTs%NBvOC5owF5i7IQk|Em9wsza@Lw6Y -zUq`A33f1LATxt=|c)U5?_UZ~-bs67kQ6<~_;gda1@uxO_jyN2>zpjl6l*t -zoi5*s7%7~QC>$j0FDIhWB8ENI(MsN4>0PJqUmokAZu{Nkw!2IDr^3XV6SdA!ns!RZ -z-9#Skmwyr|9F+>LaR)9sd?#b1a9pBrmN2)N9~CCn2~q1jW!bj0`Nv_?2L}0(4zg@( -za@ii~ey6WBMp}j?S|$r8%81x$5yyC}*C^2)Y4hQ*=|O{he+P-~Ohyk#k2#2Zk6*qy -z(lT90ln^ms5jT6RcXiwIi*5Pk{H_p*-x`gNP>LF)15P6U!Y_}E2oqDmdz^uL+`a{# -z_)SXDF6l$JZ&Zv36B5Emfv+TDfkpIs;(3a6AZ=b0GA%O7b32H%KPhdO+Fe9m?3Xu3 -zItK`g%ZXTJ5#RH~M|Rs6SJ)Pp@gIdrd}uU2TiH}EncPI4?w22obdF60ziLI;?tw?JCyFNY4crSQ_vu9jC2l91=FrT+UXl`@+>J>ezSW2>9d#Y -zLrZK!EBH4J+&>?>NOA`yawiJ)XI7`p&ai2Pf%}h0?pUF|il1QM-huUziQH*I#rvz% -z%yq%fUb3Gqx1BEKUwZTq>Aj5}idDAR#r#Mk=X&TOX`Gs993spoWpKV*8}$TdK5 -zVxloeI9AE8d*l%5y+7#LOZL^pw$_29#XHT`(Sn2{CU`PyMg-r4@9cR3XN5K -zu7RuQAk90H&HJQg2jQyyTw$a-UuZ2RVv|K&=J77|6CIPj$K=<5$xIcKgDfU@A||V{VFK$K -zCaYLX4pL0MeU4%RMT*Ith{-C72^1+N-#kY#ImluH4{4aJqL@IDVgkQY$3*W;`nofb -z0h7Y-F!?s4GqF-k{+tyPE5!uXDJI`wXChKepopD`m16Q|#Kg*CB2rA?Ght_9rI^4@ -z4HGMiiKt_uW77ASTmnp%sF*y@V)7frWNkJ~U|qvxEsM$XhzWKkP^6gr1~FMnF@Yjt -zf}P3pEGF=fhRIrr2^0|%y))7O%+(Kn=K2yaS)^i;(V1+dm|V_^$wrC^tRp7anFJA& -zjLu{u#pE(#vXR9kh?rz_CL1Xxuv5ciBa2B;$3(}Z?=cw)m<;?5lRs@?F&RWLnX^0_ -zCa|tza^rFa6ZaO1$tc>Hh)|@M45FCKT~0B9BE=+!b|$B`u$aI@DkcTXDJD>)n85GU -zI}^P#>Eq7C5V{;3G+E6|MzNjAEf$K&wrrT(WTBYAI>jW1b|$YoC?-&(oyi;v#bg`B -zG~ikLi{4HH<` -zFnO58!H@<$yL9h1JtqyjLRpklI{#pG(lWMwu?U|qvxC5y>!ipgH=OrS_Hxf(H9Nil&U -z#iRi{lie&P@Q{YdN{R^-DJJkc_0B}^O!~Sri2x>QX0kV@F`b0xF@c9POx93Lpop00or&I=^h0NI -z0WeWBlf4<8$p(taU$bJefnoydhzWKke?m+$I+G0)lfNP+8(2*KgqUP>CL1Uwuv5ci -z1B=O@bWC(i`W}4x5O!UsAuRD{EF9!!bqh=;Q&ge{V&g99gnBbfVtW!*u -zVrTMuiU}04Gr>8NClM2N&gA&-DJJllurt9q6WFO?!p@nz_In)@9h1Jt!YWOODtX97Dl -zOxQV-*ZevrIwpOO$!fr4nu^Ij7L)miN!B?NSl2LN=Ss$vzencu2zp=S-kTF@fKycP4sg($}5Ir+|r?nS7AZnc$qs%ULnOITKi?n4H1R -zq?kN{nBbfV6cH2bOn%2=0uO1J;G78*5fi;L(L0lV -z=uExGCC8SGl88N -zChVNaYk$@;(J|?JOmYE}p(-ZZSWI##Ce2yrOkiEbuCh$A;&P4A_`nod-Uk(nsU(HMk*v>@6Ig^HLnEV0f -zOkka2G6y>o7sUjMv@>bOIg*u#6>ZI&qO;DAI_P;P8AdQAUJ2@(lOC7>3d8X -z0h8G(CQq`MEJaMR&Y8fvhDpYp$&-i)b|z4ym@Gw1aLxpZhzWKkPqLW6LmDPHX97jU -zMDI-W&ZHkYlg|MYH8Uw-I};J-OwMG*1m{d(9WlYqzL@6^gSlkfJv^3Ndt??9Ku*qK0)VloFY -z!8sEsQcRk$GihKkfrm6qaLxpZ6chNJdS{|{CVkzRv;rn-X5!80OmNPmIV&bOX9DXK -zlV`ZXZ1a@keWXzc~>zL@6^gSl6fJvc>NfV1n -z4PugY&IHyqOfu$7nh+E0OrS_HsX4(mw -z4KPtN6K_Umf^#NHR!nft1lAD~>`WxYB%?FIITHmj$(S>d5R;6~1m{d(r-n(!oQd>* -z2$M_CKVbXepuqzNTsigptF?Db*X~t-TNM)8l?qamgK$6fa|}UbZYn4_1CrY}Ge%k`C0a)bot6CN5b@rk -zA5#B+(;@Y(=SabFLFGnbxq*Kj>LK;;KmPX*sfTrqn+@zF3jFI)52=TL12g>GLy=q& -zij*7pH=rI;e_{ijM1dl5bGY|h;ZqXJ4LqcAvw=>cKoPk)Ok}%7{EesJu5Np7u`Rcp -zuMZLLtx@j?Wln?C;3V8H{M^V$^~6+gsWY(D?VIoM-lWXgC7p5ma$=-+n>t+oc~;|9{bqCx*8#2M2w6>vu;%TAyPMsTWt!vBtct+^nEujj&F+ -zsd=vVkownmQf{D#y~_$Z)|iLftYF6)cT#TPGhy$tf{r!9PK}!tY^t*Jl0CI6d1jaN -zjhk=-{ai_;dPFLi;|?@9d@hf7YPUVN%GOxS&khss6;bbP%AD=e8JF)7kM~Zcc}v=y -z8#Xl>xYZq`d0Vo%L27pTlo+WVoT#28w3ZSvY7vV(-kZDat!1{>Dt?TCE9)RNJCZf~ -zbWHwVzVW0GFu7aBVX}_JOFLCaYOYp3yPU{}9&qe+X*SCfJ$0%3=Z!X_(YfOrVIE=$(m -zJ51skoyjVSNl{izR#8k~onoS3XL5jI0!8dhR#8lf5R+9bCI=`c@R_hPSw%5{of;;q -zSWFJ+nCO`FJthKR!mF70SWG0u#F`BgSl2MIvY7ZNCUNXcphz*15ECoK1d0?B1v?WT -ziwQiWVPd72K#^h+*EG3f+MHmjJNVlnAPOg3i21lBc7HnNzU -zLQJqTfg;7E8!_2PF@Yjtf}P1J787_#!(=1H1d51>-kIo_^gSk_H!cSUEmSj;>1=1R -zaXH0gST;=7FQ=HmI>jUpJCm&x6DZQoq-HtAWEjQ7vYf?aE5!sp6YWekET@>jP8AdQ -zAUKJ#RmVifr0+2q1DKSlm^fKXc2Z1gEZH!Dbrq9!78VmH#bi2mCQzi9?4+2~S|}z^ -zq?qJkXX0crfrnH~tQLw16e%Xt_0B}cq#rQ(3t*yVCezu@WaGmWlgg}^JWMfxb;JZa -zlP3@pwlk@Dm|{|im^{p4@&sbSb|xDhrkKD^4U>miOrFp&(J|?JO!fmNt5i&0VljCa -zFVN%0l@*>6LFm@(Tq?jB>Oll}5 -zP^6eNVQ2CpiwQiWVNydefg;7^u-=*InDhfCX8{v6GdY~mnXI9htjUVW8j1<5BPQ6H -z970SoI+HaNlQoFR8Wxj7h)G6gvW8*;J2gz!u$UauG0`#UdrZy&CXcF^oMbV%h?r!Z -zGl6vtlZ-i&lZXj+CQzi9TtrN8&IF2x33etYSxn#|4HKL*fg)m}cP2U}{ea0^mxF^| -zRWp+ZGddHTGnt$f6Pz=Fb&AO{>`dw@CQ!uA1m{d9BPJPhCiN5(_)OTD;G7BU)G*1I -zGpW}x(J|?JOy&Y6KUOh0#$xgeVv=>v1lBc7GUiNz~R&ZH4B$>>aQ -z&g6c?BxBB`5i!Z=OmNNwc50Yp%$YRmnCO`FJtijr6RV0z3yaC8h)LEt6IjGtn{W2Ta}tOw`Qed`4%2b0!P3 -zVuEufuud_FVrR0SVgg0%OmNO*A!3p-XR@DS0-p&x6Pz=Fof;+?b0+(BOms~89+O(Y -zz~R&g2MUlF^yqoXKN|NyePX5yT{; -zGr>6%*r{QXF=ui_$3(}Z?=eXLCN>q50Emc8UpnCfb>_pF*yR5tW`02g~jAU#3bvS39M_FWXzeof|y`u0!50+ -zhlmNznLrUS!Or9r787_#!vyC{pop00or#V~KVWhiFi|s;*E2d3oHMyOD<(K+0_zkL -z2|JU$6cZ?7XM%GkHzOt)b0&K!Ch(cCGr>6%*r{QXF=w(@$3(}Z?=j&46Hdj%%VOd~ -zOtQ|Iz`BM>#+-?lV)8n6CQzi9_z)AEGl3$-M8eL*%VGi#X_(-g2^1+Nuctry!{TeV -zZXGaS{Jz>pS1~s#)Ska5IX$)Acl*Ih_OB{zUzPEf!o)iu>b+8#vmQ-S)y#TVW-CcZhgzjC!XjH3!n>xgpbBBUcb< -z%}WKNjzHAqdn`s;XC_()3PL%5Bt*OmqTW%8(vUW{g-mTmZd?aZ_9T^hX_MQxBt}}N -zBwEJ_omE5}Xc4!1tmC`wV=8T9O87FPd}{~EJCMxVDpk6Oe1l)ML<)xq`z!dr8RTC@ -z3J0cw*SP}MIeqWPNa4^#VXkm@8UIO`ScgTe*C|c)Y4a;#)1wCYp$^itE7^2Vn(Xk^ -z$4JYFM9WlRZV3^OS;W;I>+Rk46UDX@<-FG**L09&+mp-oN}oE3yvZ*Qi?mD-YD-b@|F-M3|Zoh6wo; -z{Cgo1|3Nf9L@C;nHop)uyWDB#;H!u@ -z-69_L#3y&#+bV5sCHybLBtA15U!rWRZPU^Euz^IU!-(z -zPn+#w6ESdGHe4jRe?0to!FVO-!nw=AZH~Y;mv6bJ;8%;jB{^G@IeVm1VF3|C7V%b3 -z!A(leF6k||Z-l2{<)Uv%!;WObKFL+LfQTN8Xz>&jDGlLsmxC)^ft60*XKiOm!PscQ -z%}Td;_>%o}neB8HKhnUxwc#RZ9Fb_8D$M@JnzZ>xVbl8t?i(l$N;FOsj+OE+zJ7>s -zd46tLq|tZylKohfZFMm}&Bz^xho&VOhYG6`aCK0~^tq8c0L4j(#!wDDEVj2@M5z?Vyr{a4LsF!BZ8AV3RBw$&y*!6qj*B -zR$X*O(L|??MvA-oh}q;x-Cb$2wj}etZf5x0pSjHQ*Dt+(-{*VHzxQXR?OxY4KVsocZqMv!bX(fIF=R>^82d#zZ*wAV -zm(b54ON)KdaItVSH>6bN|8C(&xUJW9+8au24HfJ%gY=+SIFxIsWJd*M>osBP$Y|5v -zwE6y^>3*Yht5}$y3ao7QuXK7JipYf%;)VUWv*j}XgoXdXZS5Idv@31i6Ey8HN+U1I -zi|P}Lb_mb8WGTldEf8CBxZ@QvUufZ5+}8X~`|(O!O%Xf6C|!S14)0Bbw+bhmvUHnI -zS}(TrP6gIG{p%gxHn(+Hr#)V7i=xEKWU0m{ -z<%`_dRG{7AZ+Ch7yJJ^(+UJ(o=2o!x1?AXH;n?`-hJ9)C^q^_FQ7RBS@=}5G&HnRF -z?_&|UV^X}MC%3VTeK9DmquyWMY(f#qO(reVFdpW#+ZaXU%3X -zu4w&c;hOccW&Ump|5taxg2%p>>+2KsI|Qf8I}U!x_2Ggs(fYQwOM$PN{a-n~vT#Ud -z?(#9e5gU7OQ~n!X9TYU}HZo7QUyvI|#~TN8Q@(>&2L(+x8JVeKqwvNL_M^qNqvh;B -z;LZ&`rk~h2f?E+?n>HT|nI1AQpTeC(;*I&-H}JpUj*#i3fmtgyzWj!ciH=G3F_{FI -z>{Kv$o5o}q!K7nGCQODAOfJr#F?pL{G8Zw~Nn#$-BTa!V#mrXwb| -z(3reWF!3WM&(oNg5R(-I6Br^Um`t9hF@cLzOjZy~V2GIL$wbGb8!)K>Oq68e*I;rR -z!DL-VOl~8XtfMi3AEILN1!AH}CN%_;^N2|ejmhhXi6)uU5KQ1s6_Xkolh<`jbWF03 -z$vnVhzk4IrFo7Y#qzjYDei{?FNX29s -z!32f`lTJOE=$Lc^Cf2mMXP1&pHfk^_B$${pVp2#jG1Hj94^c6Z2qvAHWMU`Xo)n4}Ps -z7imm3AttK`CNM-yFqynaV*(ecn5-h0zz{LflZlQ=H(;_3Fj108N`ndROzask!JUbn -z#sq$dipiIVi6)t>BbcNSlXWyE0mMX;Ox6)h;7%2jbu=ac9TOds>|@gNf}H!v=F6De -z^=Ar`|MVc349T=J`KkxOWH7xmnfYgeNpFJ5y3I5uJqae`7ZXfiNHFP7lF8c5G$wG7 -zf=T{jf(Z->CjIneqGOVMOvYK#=AQkPWYU|)WEk0*h((z&8A^60XNqV{;D;!f%ncGu -z`q9Z`qJ?0xgZi)l>Yhp3o*hM3UFWa1iv$(xAD8XA+|BPMh* -z$y-A(fjd=9*3g*zUdKeoB>R|L4VdgwF!>9O$#BFZ)6V3p;fM*nGnx4pf=MZ2vWv## -zYQ$tI!32f`lbx7McF~x?MJgss2_`TknC#G#iH=D(U{akn_uQ!@lTr;PWM?88GGan@ -zCT9#ZCh$X4Ohkgo4oxztCYU%7lWH0hH^Bt%#AH%UFo8Q&OsZ*2+&U&YCfUbi31D(S -z!Q=xPlNpFfrk%-GGY}JcXEO5xg2~&6$pIRZC5Q?3OkjwZU@|#CV*(ecm|)KYhKPxt -zOms}T0Tbw%>{OD;+Zs&B&P049BPL{La^?{l6Zj!2Cg%_nO)|lr$=?wZx@WTCkBEsT -znPATZ?o=_MdnT*?sAHmIl6_1@04CcNOx~g~89*>;$hb2ZKrq>>*_pgWFu4{n*-m3J -z0x`j!2@DA)m6%Mn)0n_TDkj)7fg!=9LQf_-Cf$Gu^h_$1WO6Ny$$s3K+?@%NeYi8Z -zo5lowh>FR_1d|F)GQpn7Q-}%OGuiN4f(hJ-$pm{QaHon1-7{JBTOAV}lk8(+1WcY) -zFgZhGawB4rac6QPVxrlZoFSOF5R+$VOpJ&L_Do=im|!w_mc|4wQZd1v2@DYvJ(=j3 -zbOR>PGpSUPiA#eC?o2EhF~OaQg~kMah>A%VG0`Lw?3siR6S`-z!H1Y=k_q-q;7%12 -zx@WS=r(>dHl6_2O0w#MEOx~d}8Hbo;+?k9+Of)-_cL*lS5R<($CNmKe?3uujVDc^| -zlf5)1aFL1$_Do<%FnLE$CORhFfC=FRl1e13( -z$pm{QuOcRN&t${z2qthRCKK$Lz?~{4bkAhf?{rLbOtO#3uK<%56ihy(F}WQv$+$DQ -z9Wl}DOg4y|bWFMd6X=<|t0a@J -zHJISe-DkkR<6HPL~p2@!u6S`-z;ZKN(CYfN*1nyKZp?fB){-k4~ -zW0HML1_CBq6-?fwG3i4vS(tHW(uZL3GtJKAO@hfN#AGXt$v}e1LF}2pkYI8HCX=l+ -zCUB90$zkl7z>r{ay`D^TOtO#30qB|Bpd^z~G$!}q&ZI08Cimjbq>RP{eu#=mh+uL( -zolIW9p2=>4$%~qviIZRgcamh%ggq0uQ^5rO7huoCsbivJl6_2m3Ya{tVDcV~$#sZH -z#+}J^h>2!r@*ctD8N}pi8k3(QCfGB9A!35bH7mRv&P3v6muV|r@6Taxxpq13<)~3~ -ziSlxjKV8ahd8tWe7W)uCAC}Vq|U?b0=}- -zaN~%O=_v#AUvSCWi|-(> -zFxjDCvV+D14pdB*WWof_RZN!9nCu{!ti)sjLxRb8!~~ltFeI3)!ep|8#sn@>F~KGZ -z3<)OiJN4IR>95bq^6Rq>Koez^l1x@=lF4d<$-#`6tR|SiIl*KVCX<&4CNRWgf=!fz -zh>50&@)E%W{w7Q&*hGOlRZKKZl$Uf&bWF03$wPq2a|$NU(U`!2iph#hn83M;$qE{i -z=MWQ2CNLzJJcO8F69tBd2_}>0XiVTD6%%Ztzz{LflZl>8x*?fB6J?c>Ojc@=Ne#i| -z^Ng6(5KQ14F~MYV0x{7f6KtY&@s_5$v!4`04Dns -zO!m>3z=4X%vP_u3xr)g$8k2nllM9$kU`Q~z12MrS3JeJ*-(oV^M`HpPshD6B1%?C@ -z_?>z((UVEGlL<6YzEzUR1x+%s5=>5J#KcN4fpdb%x0p=41QQryGQlRwNyJ3cMDY?# -z;BUfYf=v{-Q^iEnMDgmF=$K?5lP3U^BMK%*XiVTh#bi|`OyFF_WEG9c5yS+O2@DA) -zPar1PM1dh(lOC7$v!510h28XCR=Ds;6TCT -zmy0uD0_O@Qro}WSTL>m&Fqy!RVA7Xh@(?yrU`Q|-i^*gQjR{<&V8UV(1%?C@_?>z( -z(UVD*lgWe7L>a3jlQDEMdDucQsmp{3+^9ay1?L2lv6xI81QQsNWb#XFqSO&g%$g>O -zgJ1%G6GcdrGQpn7(Ttd2&jij1CeLFsd4*sCLrf;vGdYTwXnH2E -z5KQ22!eoLy6Sz~wMAI{QMaM+PB>R}G089=lm>i@rfddtjj6D-LS25A_Ob#L@m`q?u -zFj;|^V9x}GhzTZ>gES^^k%|fSOkjwZ=*dJ+Cf$%spl9;Dl1!e{BopkJe3KCq?3uth -zVuH!!Bx0gTCfGCi1~Jj}Oim&unq-1K6Sz~wMAI`lsbivJl6_2a0h2lflR6p`I8ZUk -z*fW816%$R*q>fnZTVYCYqi}i;jtoN%k=*1WXzfOd4oR;6TMBW6uQ6RZKKJlLmsxrDX -zNG8xTk(6ZesV13V&!i(GCfGB9bHoIbi61f1BopkJbRZ_0o{1kZ(IgY>nZTVYCYqj! -zU&lnpB>R{Q0Zg_jm~5jlfdd7Ta~XRkaIRo-Uehz#MliVzlL-t7CPN4&pJUGih6Iz@ -zm`t|On7~B}CT-X=fg!;Jey5&H^kkCdWbzsGOlB*|F~Ob*3=tDOndr&n -z|4TBFKM0qO95u3z9sCI*AK|da35n3a|d&Mzg(I&UmY}EZDicjF37og@!Wn~T{-)A1M|3; -z+mkClw=`{jDrkDj$UF<@x$)c~TzMrs^TYv}`I(RTiI{8K^Mn0#vF&s@`!5*&#>ey$ -z8;5gK!b{WU-67LY4a~>WF3638DQ>k`ohp|jb0Dk8TIi?>eZh7`&C77JhOw$A9Z4=J_{DQDj{NRM2U^R^`N -zb_*2_S+e+~abn>ZuA!9u+9>rA3rC~^*E{^zySz6=j*7jNmqO)HoA6&C&*x3zDl{dk$}cnRw{ac(r1U&_84l4E_svFoC9>eA+yL#9;*=^>FD${ns`#~P&a -zi?XmiA?y{r&9YSGlL|#HpKB|U`9l`|VR!7dPJ3Iit*x9*2IbhiaI9x^!!BWxLzb5L -zq)}qW=v3f{!+*r(9UGB5M#ejGIDZAZE-1&Qg=6{A4g1sP$wAX(qjZDVF+LSI)$Bjz -z^sbA@9r^K&$k@fwa?~c6fU{d{!>_+XH`Kt`c(}_xxb*TWsrF -z&c112{(1a@oZBm&JCdslSEtR6kZFm5c~Hz9%GFh}BMi)6;Cx^_cRW}Ad3D-s44Fa( -zrdG^d=J~;Xy3BUEgnjk(CYhP&V}2>-u7hEvZAuY4(8xHCUyvKe#T)x@Q`)N2=J$f8 -z_l!(E3`fQrbGV}w?CKLuGPB6X%n=(md4903D6*|6V-Fgb3vf~2cw;WN;*09E`SXzJ -z4g>Qc3U!OWD&Q+0!TNxh^`j -zE^R&ziubRe$bR}WNr{!$EN~9vtMv}*GA;l{CI0`uA@xmO&0#V+cPX0-IF$_f~J&F>Tyxd -z+m*=MF7$KB(r}+-5DN!$Ln>u{goS^~Z5`cdZ>X>}6tl~W((Pj5ByM35J1QhwM~1Dp -zM4Psz&G&~)pBSWCv9Nb4u+r&Y>F|CYkqi6B3&(P2OJ)8C3*Xmmy*j#Rd)mAwWV**7 -z{rsZ5Xh&kvKH-68Sz6$eriv|j-0@Aq?H%t@YY1QUO3^9 -zrS(2(sMs`$wM@$Y9Ob#I?2Wd=J5=?3kla(|khY*v4G$tzvCUB>U$x0fNLpmlpCfUd23&3Q( -zg2@{+CUL}MZ6-|MT*YK9jmaB`$svLX3<)N2#AGeO1cr#oA%e*pG$wG7ipg4n2@DaF -zLpmlpCfUd2?Ms1P?K3W8@|Y%>EFqZWXT)R)!353;ChIYo>?D}L5R=Igf=NDNvV_KD -zC&2{%CQK$v2qti+ipdfhlbt#yIwsl2J60vD;6tR|SikYED8Q%@#(GRbx_c^@#jMZrXqOjZy~ -z*o>I0Aeg{8VuH!!dBjAMOjZy~Sj1!njmh(fi6)t>Aeg|NDkdvvOrF;<(J{$BCT{>H -zYZXjhr!i?mOlmS=0_Q3wH8du#BPN(kU`Q}&LriK2CNM-yFqyngV*(ecnA8wVV2GIL -z$wW^k-H=S)1x%EkNm7$cmJv+mX2fI}!353;CJ9U?`w1p6#ALFJU@{jmSw>^BpI`!i -z6DE^o1QWPZ#bg_i61esX2Jx{RZOfjCOp9;iOB?p1QS1E -zVkMZskYJL)WWv*!z(p!1R)Pr(2`2D6^<<(alWZrGj{p;8XOh$;lT`$hjTtdnMKFPL -z!~~Pci-?IPnXDq1Y(z{}(U`o5m}rv8DuM~zsbaE<#^gmE6CIQ6W6}kfY*H`@(3qqU -zlXaOefpZm;bu=ac!~~NG3<)MF#AF@81crzSCX)b-30$ONvW{Q^L&QW+CVDc-elmIF -z&zAzdCMi3UVRSN?znEasI};{%Ehd=2Il*KoNhV#J2_`Tk$z;xAf=O?J$?c0NOfGCD -zn84pelF7Wq1QWPZ!36#g@-$a+vyO?5N%k@65115R#^gWEG$z{!CUY#AFoAOglRGRF -zCSNxbOoowU@*NBbCff)mb1eiD7!pi|l4O!@rZItw6in{45KLf5FoEBxClfuHWI35U -z@>jq_*_jNZlga$$1e4N?m@Frlz&T<Lrf;vGr1Nqp?fA5b`ebAZ^C4PJrlT7#f0veBzNhU=$K?5lS;tEs9@rzF>xU# -z8G9yhu3|#>Oulv#O!i|kfg!=fg_vN^1cn5YeV9z#G$wG7iV5~iU`Q~5->D}PJ(*-X -znS214C_9t=nq-1KlVuq(!JY}6BPN(k4j?9)WP&}DWrzvgGr4d8G0`Lw?3uuwDkgN# -zBzZu`M8_oin7j*^{7S*(k2EG$88BI`VB(`O`2;b^*fW816%)E=^0f~!!DIqMg2^X{3HD52h?rn9@zI#T -zMJguPGl3yuq9+qQnRG)kc?U32b|xQbk_q-qW@W?#dnRyBF!>OZ$zFm93^AEt&tw*2 -zLibEA>?N4M--O8odnRzFiV58_N$%A#(J{$BCaVCGhZIbHM`Q8_#3W94liH=G3 -zG5HoSc|yVDPc$aqBPJPpCUCA|LibF*{u5$?$pnT3lkX7|?3ut2F~MZ=CmIvDNW}zu -zCNM-y^kkwZlWs^RZ(a)YGATQg>2xv)V9#VwCQSZ>Jrg)5nB0uXWGlf0h9sE?*fSYK -zF!`gVXR?)G0)G=pCa17x0(UByz#oD=ldU=?Iwsl2WGrA(u3+M%G1)^f5i<5n;9SAv -zq^4)$B$!OcWCBBi$sU4ve1wawh8S{S(@vUHi{iRxVdFAUuogrb;kyF+UJ(r=9aP_h2&V@aBNC+ -zL!Dr9$3sf19Fk -z^EAy3{MVs;Nj>}@|Hofa59ca3@J^H~UsC@y{MVy=Nj>~GpnOUFcQ7Q}z<&eEm(=^0 -zlO_rbk(+~8zE?Q?G|dfMq;doAL{Yw^9)`%xL7kib_1`O;+L<VUsC_b -z=fKTvm%j>f`XTB|>H}*?t?~Vg+^iwBMmR@q4qf?@`mWcIn?rPVSwm`#?;|&B=vw1z -z$ju=-yR0F#Mz~YuW(}QPUemex-_MObB6I(DVZs0=xe6xrG$sXz$FR1-`*88N9Qn7}!~#M?wLIYuynA^t;HHNnJ#m{il493z;(--Q1VR!uO0J5@}o -zX-tmknCO^fKbc5?Nuh#C6OD-#F8x*?gg0VcB*Of<=4Ex{y~5tFq96F5gqFqsI5i6)t>C78qz -zleIJ^0%D>`CTj^MaHopNS{f5U$3({@`D}PJ(*$s34?mBz$NFoC}blZlmJ0(YvISZPeWIwm?M -z*~cUan9Nl$IYMJ%Lrhj>!UWD$OjgmD96?MlnZS@>Vna+;5lmo+m|!wFLSq6KshF%H -zn7|M*(UXauOu8YNdj)-rj+kIFIfa;LlF2%PNf%hB^ -zVxmbV>j)-rr;5os8k18xCORhB$7C2_(p$k~3yn#Cg2{%(nJ|HK1(PQh)0k`_m`uiG -z0z-mHe}c)z#RL-=5=D}PJ(*-Vnfx<&DbQ=4vNM@X -zClkAcV6rn4Ccm)|OyHbgG6|E3gJ1$fl1w&O2qrrTCXZWaOdJFg_?t*F*<>M@z?}*v -z@P}Zn(V=6aW0HML_5&u@DwsS)V^WEjWbB#1xr&LVXYv$cg2@Di1d~d{1bZehL`*Q5 -zJVj#y7pa(F&jf~uiJnaKWRm@4^3Trz6J=*InNB8l?3uiq5fkj0z&T=q$>deUgiaF~Ob*3<)OiJN0CuCzEU^6A>^`b|x=s -zk_q-qUe1UK_DtZMU~&YL$twgC7-BNPp2^FIiKb`r3c&>aCQK&SGl4r*Of)@{S9DBt -zOtO#3M}WyJ1(Sm`CaVyWj6D-LS25A_Ob#L@m`q?uFj<9|V9x}GhzTZ>gES^^k%|fS -zOkjwZ=*dJ+Cf$%s&H*OM&g4Z+GQpn7w;3_Po(Y^ICYVf4A|{$-f<2RO5fe?%jd9EMk(eX9DLcCYqi}9l^wm$pnT3ld*^i -z_Do<%Ffm~=siQH0i&RXoX97cl3H(kyndr$R+sWkPOMzael%0uLlT5H@@_a^2uxA42 -z1QQb`lcNL^7-BNPp2_owiKb_AlwbmX6DAYvnZTVYCYqkfQ5_QYmy1}Or(sMV9x~35fe-%Er^LGnPAUELQFJ0lNQ88lT5H@0(YvIXnH0sIwm?M -z*~erZU@}3$q=Cj{He!;oX9DLcCYqi}1Ht4=OeQcSn9N2@uxA28g2{PICJi(uaFL1$ -z_Do<%FoEBxClfuHWILIB3YaK6lP@*N1bZg0XT$`1CU8zLIgiQYIKc#lm`t!|@;YLo -z>6siSn84qJ$pm{QaHooire|_o$3({@`CF~lTe&jij@Of)@{!-xqc -z6BrUq9z#s9X97dS1e3{O8WXrk#RPjMFhorBWTGdNZb&BQ0TX3s@}(x3V9z9(5fkj0 -zz&T=q$;6MCXp#x`Op=I+rf1?uOf<;^dnRzFiixIY;@2_JG08qAlL3?d3MSiVOokCm -zIy3f6;9SAv2Tjjp8^L5gCKDJEOokCmQrI(rA;DxGCX;P6CUB90Nf-7^U`Q~5->D~) -zEGCnV`F}`=y+6x4VLh?t%1aem9{Bu3%@-$X-Z*xjaNqjZ{t%k{&ZWNBO3(bM|E%N! -zu_dR?e!RkVyqL9yQqmlsv_Wj?$<>r4&4+@fLq=&#t=y6uZyCbXR3^=L22FPwrJKc; -z32pXxu`OQCb_G+?CZE((OzJGS-xqTtDt` -zIs2_adZJe5dd9gC99xn!KOZtN2B}KqhP2t)N?ThIJ3Ew;run2Ak?Y@PZ!5R8m9j~r -z)Vo&h7#{B!z|E~ln(qsm?lVfWYUPfJ@s3`czl`OBDaq=SCWswl+U)*Po4=BsY>+Bz -z<&J^zj`7^a;-uLeGJR=~9;=l*ddE9Paj6nE5K2jteUe$s{oA&aa?XF={O{ZWT;KHK -z_Q2L=|5m4WvAf_u{U5#ZZimjr?ST@P|E*^4@7)CxqdEJ9Ynr{gCV!A(uJbX=#oTYU -zos{eA6ZJa;r^`DI=0Ec>KM`}gV7@I;zeo6L#15+Y4Mz)=l7wk(#Ln;A*->X7Ll2Bs6{y~739M$c>)Zn4iunjZ?9 -z9x^f~V18$~pnvqt4{x5ce^X-nrhafgGnl$Kib|lJ*P;dv1(Q -z-67Pwy7-Y6{%N;ov>;DyNKD-(oN;=8?e^RiJ+@hx>g?hdSokw;PmUlTt4|!;Aslmg -z^CD@_^Ij%1LW()6idnO2SbYCL6McCl%;!PI* -zyxTJ@8r{<#=ydoyUEZFNwDqd6b$B#yZ+l=zvww%vyTon1U6Av(B=U9(6^<@GWZ`GJ -ztv`w8?G)Z|c?Y_!*9dac_C(WO;icv--X1i`PVXyjYn~uC?MpOm5mq|8_=ha~=Wgpz -zL2lZUXxb@UaC!Si($=fP))CP~d)ougHT$1)dRIi!);q%1zR^Xyg$Ep6e5-{obX%th -z@}ixIMf-)@n!OE?v~^V2Ix8C9+8#LJ^q+8e~r|{xxAwy>DYDQ*y!k-2I0eI?;qT;iP1Ux+XFW@ -z`)_u7?}?;iw}fLk(aUdn=;C7*eu6u8y&wy9386t~Z|>sXu<$l_Y+iK3=JvoOr+<>e -z`)(v18yJq=6y30+J#fV3H#K{ocgJ!Cc|${D!#3f(vx|Ss!YAFAU-Qr&nCI}%b9tvn -z(y@YYY(lhiUwdFvvwxG*Yj($G3v%bSMCTr%*Kcl3ntRS~^7nFh|2+9@iW%->3}WtJ -zuCHuq50o_fOPpQ<%q>1h}sx_!;;v6qxT$)Yl11 -z?YAb)zY3auWn})e|3bQ8UbvuVbipoR^{0gi=htk732CVQu!- -zN?TzOJH*IbTPwGYi?{aS3d@t`vq95YBQvO0ZXFqK&EZ-q*qUI9dDzF?DYi~(vvWl@ -zu8ciwU{=-2t$pLIxg1xTG`EFJa}CUWwQ}pAcW22Ix*r5kJI!n}B4Kdzyi{n{WsE*AFW7M3N=&jd}+7^Ts* -za>uZ6%q$k>atlk7=1)SVSqAB6wQ}L0c;N)@Y;n^3Xvp-vLHdo@(xc5jt;{y9gxwQL -zNh5vI&&8I(ZT4xEw&O)?fl-=TE4SpuTl#Uw%ai6<&=fOD{lu0LZT6ZHTTKP~a4;o3 -z;FE3>Tk_lN@giHijD5o(t*wWo|&68^`4rvz4KgG}9;j -zO5}RA*$R6gH-3rnmASETZWsq|MG2;)QlE6K*fFlnKDXF5x19Ybn35j#NrS|Wk(|FIY34(w -zbq49-TDfCrykio#v51`zITrL;0E)V -z;evtD1)cAmvrj3tO{rvWns=~^f7ZhP!d*}pUGV*T=j=zzZAVMlf6PDF#Sgadd))=2 -zqGv9>ch0_|*tVja{T#0UZwo)sUGVJ&#=+u4ffd$R}1y1kJBWcgAVb9>`)IGu(hxgxZPp{~)UG0IX4*yh_cWNZ{a~o0`2ZMbe(}Vb2}W -z>MiYoMNa=Bhxb#rXNVwI?@3he6vD19eyD}t=k|<>M)$S{gl50s^sbGhJ$HsZ{iD&{ -z?STyr{|1+Lp4&5BkfS>j(fvZd<}QAVg)eqnX9#lM)V@YVUHmr|KG$uX5?xf+9(cgz|FqfL -z5=mS0!`8Xc@MhsQXBWTF!k=|p2MKbxJ`vs_oN#sV`4;}L+d4KHZfFlAn*9l?_2l+cWi1@*wG&Fy8LUKy@w*{*qCtawy3bJJ<#s-w>!LD?pRMj-mojN -zVY@KN)y3an;a_&g#tZU>eTfZQ1bB;3BpoXZ$A&~V>}e02clgh{yu;kFYX!M;d!lo% -zaH_eB=Pmp?ckE6Cv2jetyp0_tKg~&UT@f{kEjJIA|(1 -zGBd>7OMf^i=WI#j>=sHk-j>Yps;!SMqzgud3vP+l|NHZE_VRLDc_|w*GJ9cueYjvu -zv_AFuIs55i+v#%lU-J%i@&B>#ecT0CM;BcD{G5GCg>6bP`_uV{y7=W5{=eJ>r&m2n -z2c1J*ywAedx(iY;?-_3#!L2A^55o07vGBih7kmM8<=+D?t!WSZ+Ts7T%X^o*;5(QP -zi#JZ@a*LAYz9Cbcfmu>3SM`ZkjplMo+0&sEGtkHURIJKrvo}`Q8jIN#M&=H&Y7$pf -z#O8)l%oHE9LagfBX0Ix@Rh6=>MrKH@Ts10QHHd4iNSe8zi8C^DYvroR@zx$(VHw*H -zOfk!R%qX#Sbep}f)K*x@P79`(dwfiR*qX<+6erC!AyeGI*lOk0p7GWZ99O~~4yBl} -zK86unhqT$bN?S(}J2#YKru&$6Vrze{qdaL&1x+cV)T34|93C$mzzwNLnoEPGQlm6O -zES%V8Zz!@gl(DX0O0xK*abn>ZuA!9u+9>rA3rDos7nax-ROc)^{SOyhR0h5aMLQ1=6iysdyLX8wQ|eE -zcuOztcp2*nrle}0lqa@~X|o?MwH>cyCm5uPTDfIlyk$IBQ=BwE95Q`jkk;4AExqF{ -zqqukp`$i}wP4Y=5v1M4BJzi3|NOi8Ry -znk#aXxw%D2^RSR47D|hsXcZ}xdmL|;~g-p{8(mi5FPMh6dVe=QW>q05%PM>5G -zJ9=^(%aZ07gQgda(%4$LBRAeLgxgq|G|vy3<{PEyV#kCwd#c!$DrbA1I?%;$Hh*B+ -zVqpF@{X)86K)B$>XwD8{t9@qDe09)twUKed{MK;6;AqYs;Vp;vpYDQQ(fa?KK4&j4 -zv6WY_M)(-4!Ruciwe=;Cj;@PBj{oFDtBoI5$**n^u=#_ope|6<{< -za~J$$?4xqy;CSOi?&yD(wg-Oh^#9!972O4AVLm3_IFvgoFKrLp((J#*>HV3z;Cq;> -z|1hw$J@A^#|LbP&3+4|}%*{S#t=QO~`zE!tJ@9Xb|KBceuSnW+RoF8;I(2V*puX8( -z@ANKpdu|uxsaq0LcMA&~UHr!u{ua0AC()@pg)=U1j@xsMARpVFIJQ?f*4)J(v+&h! -z&z$J7E$xA7r@z|a4M)(PKN?15uYhui3l9?HM7+)q4}wTZJZP7r)ZNUvPW+ -z3Uc-CM0K68$mP8)lJ-msd-9{z``ZI^n*DQ}-h17iS%Mthnuyj5f}@LXxA2qPo*M)? -zT9=462%XK|Q<1c1a@aFJnzy+<(9h}b=kUH6Nm~bmtv5#Vb_hFMUHk|O|CHN0T9ES^ -z5_#K%cbwi|xvh6an>GvAJG=OwTKM>ux#9&M@@UUGEt|FH1m-PY>`xv4JE -z)F51F?&42c_$S=fdC^6i+XG{q{xJ^k=}6i-Fl@akx@bpx;5nE7fo5-`+nOuLiy9J( -zwh5m)yLisRcet&+qv2icf!iGZ+g#phk+iiSY@HAd?`sdNZ}zWudRe!1wjhVMCBl1z -zgrkd3S@_=W*j0i&XM1AKUSVIe*A+>}#)V_IN9Sy558UhY-|O&x;*JfD&eVQ+ijNVETl)4M8?j@=QC^^I=WEtni#yky~LyJOP?dBe`chW!G(%Q2FUjS9zR -zMLV~)2TnQtrySnzBI#KFaO{R?XPvOg)y2=Z@Bw$hpP5JH+<$sLFBl%pxzu{j-nZD+ -zx14>`!2FZHkS^#GF1Rk5)6sg)URPnOD`uA%ncKzONnCjmJ0j53#ouk=|LQI{13!cO -zYxAk5F8+Xpf6!f!fO-FT?pW@0S9N>fE0=#{vv<3@AjCX+h{3X4*%0G?`ZSc -z6tlp`OcfjRxT8N*w+B9U`agDfFT$McF4NWRf!CV-uQ|PIV7}hR3>6!{_nef^)FsX| -z2>)*O{t4#lKcuzUbIWYGC2U_VX1XIjLAJbcG -z9nKY&B+U&W(?SDtf34g)INmyuYbi>ar-e+%4UAQ6?bl{+DYvzhvhh%g>F;AI#nyow -zSCKTcK@)3aX4lHC`SI4?Tt`{b><^m!MrN|uI=0Q;QEKa`WP1lwQjt%(N-P}LW*<^) -z8&b}`ZIB+Rl?!{t3rBJdB}ua@WLjpB9uy0Qat)R2D1%g1D;Exo7mnu^7AMVevp-$V -z-fxs{t(6P&#1AA+Vo7^R7|a^cu`;V|xOB|9jXl1hBiHDb%SHv6<<+q81_ -z{a{M^wNJ_sTSjunOOj?!$YeE0i)!VTq4AbUTul)>A(WD?_em?omcDKFnsQrBDf>kz -zB@OjS_lhlpxOhd`pAG6MpXU-U{5Otbejw`XE>>V9Erv$sBy_KXaBZiyb-+8#LO^dED0qi#<>K|Z!SajZ_Lc6IS{ -zEWF_MOcLZ{`xDihg*>OXB9ivZ40{GftLxhXO%8vP%R45L_Dl(Ta--D^Lb$n$KVjk5 -zyFGISIl4I!-6hO%ct4D!J%hrYf@pL{dq8mcH#B>XMADwIVbAPnbequW?BX|B__W*F -zLy+@!CGxfl{ajuA)fV32wvLPD?Q0KIH2W)@USlL}y)|qd9L?J!yyNix%WdryZQ9jN -zHZv%z4v@fw}i|~NcTNO!L3&YkS(M5aO1D`tlpSrw5+}3LaIlMg)-YcAF -z?&6PI_!_tMPC*WDNrZO`>mA;hcW-ffX|YdCu;{oI2rNmv@#s_LJzGox+E%E`E@O-{X#r6l7skUT-q$1PSbjJ*H`=*bnCI-`@3Zh9xnqL_xwAgexkEVR>f$F`_!r%=vC+Gft -z{r<#)&B92hw+!Y>eauL)@!}gN=|IO^A`KFNR6$4W(HeP`Fp2UKk!pHX6 -zN%Q!iX}poSUTpl~jg#`3t%)=B!fP96C$GFJ_`3_~g0bO(+0irGgnw_EoizUtH2q*? -zde+KS!{b#0xZH}QxjbkpH!?HDs)=p(#v)r|8GAICVpjW@@nY2&uCbK;#>n&)t46fh -zt4eHD6>L>7#Z>v2La{2JYb{Ee3qz(B15;BgSM`rqjpbTPlje?)X^4R-6Px5V;&V-d$rkH%4{tq>~SMAp;m4k6K@^LwNxg}`9V{@k-0%^9p7f>ifvpu -z+ZIeQkNKEkV(X|jdq;__qk`RNV9d30>#%t1WNt`N(%d^_+Gdaz*UE)`;)SERA*Jlw -zp_DYhC*3U;=Cs)xDr^nK>@uTtyI44hTUf-73Z%ZTVt`<;!$s`SLuyd>-FV}zI^GX<;xeae5tv-e33QFm)FViC6#gc -z@+B@`zMz*cFjto^Uy$X?Ce8BY3$lE%B@N3LyRv+lPcL6&T)x2k$IF*@$?^q$1}Utq2-UzU;Oi(RvPS*9;v^yN#pEnm#AeBqVli$pJ90=RsUGA&7M1wfZ;E|=doeyQ>6m|hK3VX~>x8uDOIiI#W&3L}IgxgROiK*RgJSMb -zuC9_DVPO6u-y_)*U6a)U!1VR0@6ON1G&AhxZ{&6AKbOt_Ysch`vbyiL{~=~yFXIz3 -zfk#r0`DOJPO!+!V{<7-^<*~9ElKhyA&z0FDo%{y*6J?hvmwV+;x>k{gF=gp!{K`I4 -zp3lk;B|lPDH0jwV(@gRsvecAEN%mydi~1)w{gYewd~)m6)WvV^dG_*SGn?s8ZvAg1 -zkIlgRN1xor1<5Bj_!;Dr+lV0f0cS -z%tC!~dlcr%C$~Ws^2x2|S?aNwAr}3UoBqkIyFR%UUG=D(JLAdApWG(?mHy;bL_WFY -z{x#Dlx84V@JT|iceg^sE*6ZMv$7a^UT>0cSXgT%C&3G00D! -zH<*)8ZbO%oPi`<*KDo_$lK$idbN!Q>{>iPIKDn)F5A^D%eA`m*L)2q4lRhJl&Gb5y -z;jx*ei^*d%1J_WG%~Zf#d2D9r8uHl8mb27jGdXL>V>2*U9-F!5_w-{kFjpR%nfH78 -zu^E^vkIhVjx$>E;-)+=mGqYi?KQ^O3Hq$+i%@lu-V*Y&9<;P|o8BRYov+cl@$7X&3 -z^B+AnGk7U^YzBS?d2D9DQu5dg%$3JxrthL3n}NCV*vzfF$YV2oW>SyMTn}^Qv6=oe -zsmEsS*hL8{=S-#4BQqCDCUVdz5Xf^fN%;N^~*i24! -zrpIQA&tB;)PjSA-{>Zf&GaiIo#kfwv6()Fq_Yfj^4LuO -zLeg1=x$@Y|c#(c=2Il%>Gx}pQ-SgN?pIJ$B&us@Ucb4D$fa)v{TS*?9f%%Ufo0)ll -zJT?PAgFH5KEzFh2X8O+}o#n;!V>5kckfRe`xMAn{<|8t~@p~_8k4#49u0sX7bLF$7Z%3qB_f?&XLDvwjH86%M;I$$7bMq -z<*}JnkI;|J!1elLGx}pQ-SgPY@VCy{`wm`m`LUUuGpNq;UE9fHGj%gEb(V*d$7V*p -zML#wJbLFv_{I|$sGbIP8&hqHD$YV352d;FM%LmYp&A|1_V>26JP9B?q>y^i59)`K{ -z*v#N1)MGR2V6HD;^yN$UEMH1s`Es?ge0h>yzU;*13(SAKeEFCxU*Kop^5tW)d@04{ -z%iZ+y1+G_@FL&eeWi`Egfw{VTSxqlrV6HA-R+Ht+)tcqYYJK^lFJHQC`EnyHU!GN# -zFK6iGivgD}XEH5cN^$uDKZ7h^N^toCb9MQ$f?mGdh|8B1WclLIEMHcT_A3}yK; -zj$XdJjmsC9|9JVbj4WT^XW;T>8Ckx-TwT8GrI#--SC=n)$?|2pX88hhW%;sGvwYc0 -zmM?X&q8?`O-bhm+i28d0Sb& -z{9UtrSw)sFF#qxL8U`^JMt~*Q?8y$LZw@T(2)*^yN!8EnnU| -zXYadr@#W=9rDplEl`LP%GcI2S;PT~7dier#b@}opS-xDOS-!kUmM_=h@}&>Ge1YrL -zN!t&!?7VKq@E$$3z6$T9_~Jy(+AA-scyE)- -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 -zWscuzf -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 -zSnjXe`MsbQk)nY?CTVqlVaOs)V-cB+`X -z&tftfF-f~K8I72*JCpGH6qCh>$xarND-aXxnZS@@asZRbP8JjRkcJ8NOkhYcX*80F -zfyqU{1bQY1)MT<)hY9XX?nsLX?o94rF@cw8m_#Thjk;ulJ(HIZ6J5{b6^aR*#AJd! -z6F8}1qU)KwVqjuml6g#40w()aOg?2XnT437-I>fnOxT@C_*06>Da2$yi^)pF1bZeh -zL`*Q5>}N574{4ZS&jf~uiIGeUOfCW@&@(xpCX-V-OmJtiE-fawGg-%C0x!`pIfIz! -zk_q-q&LSqdp2;!9M3+pkX96cROmsbyV+JM$CYi@%3}CWV#pGQUlOYt7=CnJLAruq8 -zZfEi?#bg>{vX#YT3}S*k6BtrV?!siUmBj=;q+xzTYrF@ckqOt5DHCpAoTJ(Cv= -zObkpikI9{YNrQ^XNfwiQ#3b#`Bp)%+?MzNmOb#O^4J;;iA|}`~fgxgo$)thB1U{r; -zf;|%$A|^&MF)+CZm_X0uE;X4P)?tD>6MI@raA#s?F@cw8m_!j1T{6L*$(M+Uu4mGW -znCOxT_DtZUhKa6c(rjR2V3K)E<^U#pR7^f#F`0mvq}`cJKupfR@CV0l`tsQaN -zT1Br^xbPq1$#T+UKMhw0g)AnMd3Gcxu;;w2H`qjhA>{^srtwGWjXzSK;XhJugC@$?je%4tw=vpC%=h@s -zBO*DM@cr%fl=Ypk<|gHaU(6Mo%zuUl6XQ93_^qqp>Y$LtWipS8 -z#bhnTB#{=AwG3^3WOVzQaV1RkiE{CH0~OyIeSN&7u4CYvcHg_ulW -zNHG~kG5H5JQD8_hnTN?_Gm8m)NW~8I39+O)Elc!Wno?Aq^93qQH=10zcD8CPp&JbTWY^%5gQBNV;TF -zO)(MDVp2^pf#(#H1z>s3H1~I`V3JehwOeP0dOyENrCfG!Q -zA!1@A6C;^igk%Cul;dhLk#xyq4aKBAEhcLyCh#0F!DMnAG0`OxY@)OyCb}ldal}NI -zOt6UpCpAoTO_bvXCI%*%$7C{KvR%bwJBtZC&@fq=4ik8;VX~CPWIM&A7Ly4KDJGK< -z6KtZukYeJ%WU`&b1U{r;f=v_{QcU1y8p*^+CYeqq&_r>l$)r}7Ozx+cJf9Ym`za>y -zoMPg@Wb!h_1csPQu!-_KVxnuJyi75H?}W(&n<#Kn!$j9adD+0kz$EjSSOAk}R7{>> -zF@XmfCM(im0?#!}Rn80(y1e3{8#6*`&u!-^wVxnuJ97RlY$po7ya8koW -z*F-sLU}9jBc}x}nCVN#(_Oh730}Yeq=`exk8Ya4)$zF;{HzpGpQcM;gCfGB9A;qKz -zlgVBd6ZnvZ3HD52NHKw*X(SUPnPfVdK+mK{O(xyCWP&}Dx6)#QJrj6NG3mi%B2r9X -zh{*(dCT}4ox}J$hF@f)d$pm{Qa8koW*E10fObkpikI7?z$qOnbFR+-v0}Ye3Jrj7Y -zVWR7qynvWsGJzq*`*b;!D0drG)&U=OyIeO3EMMSzk_134U-8B -zDJGX9CfGB9A;n}nCX*d3Ch#E*6YQD5kYWNq(?}*pGRbr@fu6~BHJNPFB@^tKxYA;R -zJrj6NG1-pE#7i-OAtn>-nYa)Wwr5i7rI^5X!eoLy6F8}1!uCw=^BR~Km}DN4rGUw^ -zDkjgen7{)Kle9e(c&=f>_Dt44i>6Br^Um`t8!F@X2gzcH!_ZI^b1Cz{SG7>P^qGGaz#RMK`n56BQz;g`~wr8?_3&o@ylL-tdCL<9O -z?3uujVp4(0WDAQ4d`QCtdnPcXn8438l8KQ_GM!AIXHuailX6`$!Jf$zX)(c`2|TBm -zRA4gs6U79Em`t!|@&sbS_DpL3L@|NygvkVZCU8>2gzcH!_a_4r1Cz{SVggK_Rxx>+ -z#RMK`n56BQz;g`~wr8^bX~YDR2@EMFCd34LCNM-yFqu5fVgeu1Fu|S)3=tC}nHb6B -zeSQfb~W1AdWqU%2hzM)tOce~+WLJ?u$$+rxL`=xqz`L3MLK_&NBUCorl>*y7C(k2^;e?M^J(Bt2O_gNXOq#Q*Z4TqxGn)c4-NG&2{Bz^Zk&~MeC+now;XD0k6DNA}e}LiE -z#K}F$^tD+b*5-2w7g=W!=uI5=T`zR}~_@yr?f%IaDuIHxctx%@dXRHJt5+o5%mpLs_RnLQz6SKlX*x7sot5W-YPBe2y@y<%b0k}Fuu8hh{J4R -zz1KHdQFf=ST*$(i%yT=4QlC&ZO0{lczSeJE8)+HHca{U!~-3leT$?JjgHqCQ^`<43>KWA2bQCdF>OG+`ZBjO~TGLQZP7PFrHsrOvG1g -z;{9HGq0+c9Wt|na9I2F7b&$r*iN;;hSr?HX^~-%C%_I0}B}6=76Q_FZS9d$7l{%(X -zaQPu(pBlC2C`^G*3bx~>SD+0GVbdTvCoUz2P)B> -zDeLi&<+w?n9BCe#3?^KGgh%MxM)(nNeh@#YoQRj(M2|N%PARNUS+5LPt~AM4caXw8 -ziNej&X}7S>8@o}FHb~RmM4sxGS48;!$)Mm42reP!jSc8_wk~wEmT*VIBsMG>o32RP -zQ`WAqWq74r8tELA3{Lh0o^KLfZX=yTE4;>-YPxj5pHTDonzyj!};NP+T -zP`!t4IeT@`UV1}zBUK~fRfG7P -zaw1-46Ww0lI3=$>Wt|$bOf{LW?jU)45_y}YlWyTbukS|X&;}{bP0UmM<`t2u{>k7W -zci@mqP`thY-OiSUj+PRxIZS-RqQ2?Mq3tPaXV{WmX)cYl3`z!bJ%Pq1;iWdxGBn;Y -zk#8;{;y#;rr`K1YRBujMSBEX}O0%PbC>s*W4yn*3oNgm6{o^e;JYP!0cAGfa>$|es -z*;(S~Ea%o&nyno~*`84LN&}jRT;!L36)6~(3~p-*Y;y}sz4q(7oqLKLdlqt@5V6mW -z+J`E+yQB|X!oR%sK1$<`l=Z2Q|TK=C+Z}G4ak}e4v7eBxL#D#N+|Mt80x!`p`G#TwL&Rh*#pDshWG;)zHxv^%iI~i# -zm^^}*%w;k8#=ykDB=eXI223`on7qSc(vM=YINc4|-}R%I+``_FJ>wmU$!Nsn9Tt;* -z6q8%8qnN;uVge^MOx|HJ=|?ev@1!LY7*b5&q=AWnNro|b7XBUkE7fE&n#JTcdP8<( -zVLD81r8i`sT*zVqFVQdwQ%qn;F4mZVKMoNVge@-lQ|TVdl8d4EGAzWm>8I39+Rs9lR6cX6D%f|ASP*d -zCYK;4x}C`hipd>_$q5#dOAr&>nZS@@0w*<0POz96V=);@F*%iXXEKyx@~LiT@*c%x -z7Gm-qi^))m$!Xk~z>s1BCpApoV=);@F@f)-?Mz@uF@ci?CI%*%#svNy`}@>nGK$=!&FZf7D>OyDG9f;*GD5fk0cL^d!nFv&b7e*{dP -zS26jF#pFiBB<;@RM#Mz7Gx>~Sat<;1jK$$+re31}2%uq(5M?@d74qzRhCNhhj1nG9huxfXXO -zCFwAkjysbQ787`hib)_uF@Yh)WE$>FN+>4Rusf3@A&Lo{q?o{W(sm{#6chL&bZ2rr -zWME=ol6g$Z0Fx(FOg>^UxePH$yEC~AF=2NmuYE)@*@c*V#A0$8VuCvp7*b5&q=v~y -zEGCyBCb%VDJF1I!{mJylTnBX?o41vF@ci?CI%*%#sqpM}dW*sKD -zGr2u2Cb%=Xoy7!RqG1xDn7|M*!JWzNhzYwhITE3mz)8decP6(ZChX4Sc*MZOz$EjS -ztN={*tC)PsVlopkNxL(diI}iElh;0_n0$hme9B@n6EVS^2@EMFa8kqMQx=n%hzagY -zU`R26lLjURCYib9qCb%D!b|&vqO!5(v -zcUerbC?*2#OkhYcfs-00@3NR=QB2@FX*&}bQcU2afr)`hrZIt@iCIl1`79KUmD& -zXOeG-@RND2h={vv;?3UJ%x))F?BL2cxl-mkh_o>w?UdHIh`ib_Pm1tklfiaZpxq-3 -z^u{jjcFr$x%rEC|`(L{4;eYRs)c<}3aI-(q$0fWC|05g}&A&>?+9quhXA*IQO?=#& -zAAw(~J&CN%(z|ZqKfL)jDs>yA%iwq5H#YGjZ~jU6m8whBZIj#{VH~_f;|6|vngZXs -zg-2kB+{~nZy$gPO)IU-Wzl`*c)E_xXxq*|&%}mM-{Pw7Sq#nKqa&yw)CWG9hN;zMp -zT-`yIY)&lMC4K24a;;w;5NRICuP!0tDVsRWYtQd?t}b<~uHfc{i2cf_eXJ7QBPE)M -zZ1KwrBF$5h!C_5-VQ!(cjqu~*d_R6t8TVm`#IBFV`YDAwQ`VP5mX}TP_y|9SKUm8B -zV3PZH5NSt3+9FN&5IM&$S4H@2o~t0@1e%95bC|TR3cRj)&Z~k}H$juxgdTpZ3 -zn_sBZy%t4oPLcd!(fsL3-O(t^O*L{ehyE!@7$P^PC^u1-n`-1{4$UqwL~c$Q++^;? -zlh{p><}ChjIS~tNVzbvisoQzD!m+xDn_!Z!=pfPEiRdQj4L6bJ_~nNp&3%)>hundO -zTtchYKD^r*FLT68xt=hI^@_%Rr4(*SS+|ER6_v6n!VgUb>pg*6n}q)%m@H3Od&|#W -zz{IY@WCq0~H!UVJC?>fqCh!ss6SxgX#RP_k$qb4~E@Co+#pDBu37kYsW>8FW5tA7# -zCLb7>7?@=K9=c}0s1B -zC$;SIC5y=t#H4^?0z--koHVjarm~BHiFSR~@9zUl)MOIVVKR$iQkWK#Srn5(787`h -zh6&sTq+$X?#AFu5q!2Ng#bR=rVge@-lUWp#Ld0Yii^*vN69bdXW6}wj1XN7EVKJ#i -zOy;J;q!uxm%VP2k#UzH9z!gChlUl@NF2w|f6cae9Ve$=&NiAYBmtq1#iV2)FFflO6 -z@D162y(eYuJy%U86Ie{vUPmz*kPeeI*HKIcu$aJ0G)&+&AQclBQcPA~M==>dF2B+Oz`PBDS+q^;;-NHKwv1||k3na1Q^z(h?Z -z2XvU=&g6=;nBdOj3KkQ1iG~T>2BcyFL&OAkCRZRPx}C|#6cad!nBdOj3dBUWGx^xS -z#K0u;n4AJkj;NS?#bUA&F-f~KS&5kFb|zm@Ob#F>a77TsWF=yPI};dEOyH!3$yY2U -zD-jdinZS@@0w)bj3`{bO$+DES_fa*O+@-?=cP3-fVuCx9F)SwV5)Bi$4M@cVhKLF7 -zOvWH4x}C`hiV2)VOmJs11~Jj?Oimb>7?@-plf!_CPsOB##pF)JB<;@RPQ*mFGijli -z+=ZCH6+sk}I}sDynZS@@0w*<0T3Af(L`-mJ0z--koHQ^oFv&C~D*+QVnS8Co1a~HL -z(qe);lQ}FV@DdFZxD80f1crzS?o8$&Cc2%;DT)c4L`-mJG6yly?MzM?m>8I39+Nm= -za$LovmBr*C#3b#`M7J~f -z#K6SBB=eZG0wzaQOul9@S%a9Q-I=UGOmsVwuPG+S5fiu~h+?t^F~OY)3@IjXQp4nH -z7LzrI3GPf_NHKwv1||k3nZ^WqCS7VWap*9?oyp|1nBdN2GK&ekM8gDb15z=8A!33% -zlgWsQZfEi##RN_wCb%=1jF{+lCLbD@7?@-plK@~Ms+hT^5;4J@ -z$)$)1yEAcoWME=ol6g$t15Ey`V)9oOlck7B+MUT##Dv|MJn&bF$#%p9t_Y%-EJaLk -zX97ct37ph0`74XbQp5yzCNQL!z)1rW1CvZ+0zH$xYBH(NVS+o8k!dl(oykZR6L^V+ -z3ET#xVgf_N1a~GQ5fgT2vhIC~37kYsaAz_SF=2Nmj`s~r3`{bQi3c$8s+dGrOiYML -z+MS6BF=2Nm4@4*?6^IF35kxUDAttypfg!~NPHLD$SWHZa3GPf_NHKwv1||k3nZ^Wq -zCVSOn@}UkB+?mWsiwW*bX0VvROEgU2HXs!f7$PRPGns*yusf4=pHfWVBw~U)lNpE! -zyEAcoYG7hul6g%24w(E!#pDc&$peT<+MUS*hzYwhdEgAis2c5O*enDJIY9b|&vqOyDHN1iq8DGZ{=VfiHqPlXneF{(oW8{lXs{zvx-Yrpy4NY3|vI`1qibCi{G -zVUu|`ykvAdX9#~{!Tl-g10l-;Ci9yxoDy&7#ZO(x?Yy;-n3ws@qaqC*e>(4+TI!fu -z!Cei*MSgQ$q#>7o@rL_T*89Vje^i>gpE^q#ddC|^@+(TX{qQr#_|11l8sdLC?_5#g -z_`Zm{0fy84<~5Oqf&BOL?@w9Jhb-q!=H4A7Z$~0;ikW&K5z>Uc-Xt7vBmD3bSg^m|XxK~W(#yifE -zhB5JmVf>3Xtw>qNhb-ew<|`r%=bt|BTv6;;QO11*Kl35Kd03?3+|%cs-O}#Ma=j6&Eq3gWB7(r -z?t7EDf23+;GMMKILIMLonk&~L7Yv<&9? -zaw1N*iGtTRq1(w!S8S -zN^YIB%|+z@@XLcD1*4L|a#x_-Bh2vHuTgThOCNZI!EK~qWV~Q7zqp);SKGu_y!KqB -zu|8#;6|&4S$=7s{#yyF~&C*#nk#F?Nk4Bn%@zWL((ZJ;Y6O%ba-0-rB$rn0I4p2<| -zX)!rKG4ZpQz)LhtR#Qx1h?pFpnD`Ns11u)1DJEa&FgZXm@gpV&SWH$Mm>8I39+UBa -z$p2Ghh?rn9c@r_wC6l!jlXE&uFqyoGnCOzpS_2aUlgwk%A2506 -z0w!k -z{7fyGY+^BilLjURCK<-$ZrGWORWaGcVsb4e6L&gH;JKDe+$<*W5*3rTY!nk1QcR{} -zGI3K(U`Uh6F&o8X7mEq}Of8wXDJC$a$s}MiFflO6JSI~ClaEzQ?qxA~5-~}eOrAtc -z*ktmTdnqP2BPRErz^|Y8^GI^cF1YV+HvWj8?L&OA=$?J#-n@oxc=POaiM6Obkpi -zk4X+-aze#q8H-6B#Y9M(OzJ2m@EnuLGKxt)VzP|Iq>f@DVlt^?G08_vma&-BQB2@x -zYRROI#RN_om>8I38WY%=m{m-CEG8l*lSAn+f#+H>ImBWDFVQfmrkKExVj^HNIYcpm -zAtsY*iiwZK1b(KLOb$^@V2H`2+Q7uXB=eXQ04AqYOjfd(G$JNxlSw0DqDv+#DJFKr -zWF?D9BVvNdq>;tMj+m@uF=<3hFqt&6n7~N`69bb>V*)!9S;Zu#!vvFwlok_ACK8JY -zyhOuf4aEe8hzTYW2{F+nlQk5Rm<|(6CK6(zOD1a!Obkpik4ZLQ@}7#xQWleK6q7Y+ -zlgT!U2|UMSvXo*n0Wn$1VzP~5vKEucHWrf!h{;kGlWi0e_?cQV*~Vf5Ck;#tOfrng -z8Q7W3RWUihVzL&K$xG=lf#+H>d5OgYUZP=wJrfvGOx9pBd5K~ILrf;vGdaLw0zXqr -zCNEJ;V2H`Y=$ROpTm(#}0VbcQnCN;Y`w)|~$z&g5qDv;&Gr0>f(e+IBAtsni_OY1U -zg_!7iCi@T*OeXtSOyHz}iGfL`F@c@QQ5BP~b(ml>c_S?*m`vVaF@cw8m|)KYhKLC! -zlQ$3(T{6L*$=5neFqyo8nCOy;(K9hHxd@m{0!%(sG12u*>M17eX_HAk#RQ&XGQpn7 -zJj6uTGpVPT{1cN&J&Vaa#6;IKsi&C0&(xAhJ&OsPG%ztR$uuUgGkI9WOyDINCfGB9A;qK}lZikvfgvUn?3o;AF@c|{B@=;S0z*tDM$g2+QVhbeLc=c`Gd@m`vVcF@cw8m|)KYhKLC!leZ8PT{6L*NskT_OeSw3 -zCc0!|^h^v)E&?Wf&ylQuzkLCd$8b62nGB?uICMRejTDn9 -zm`paZm<*(tICVXfjT963nOZX0$YKH~4NMG7GK|TMurnF1VzQmZWC|t|S2|4Kxt2^^ -zEGF<06_dxXX97ct$z)6>E{X{ZX)^gE_Dr_3n844}l8K9A0z;Zi)*C$&1Cxt@$>o5_ -zM=B<|p2-u4N!n!c1Y*J_lSi;;Qh}K0dL~aGCYVf~U@@scOmsbyClC`%CQq=Kz)1rW -z1CvZ+0y~qvDkdN5Fu`Qy4g?fyqU{WHey%zKV&iXR?!G@_gE4vXf#0&oP-`&*VzPMAtLfNilf=lgUmN -zlPeJuUC(4E#RPt)mP~fCn7~N`69bb>V*)#q+f+0$lV9(?}#6;IK*^iiDGTF~!avx%%>zV9FOfZ@3XEA}31||k3nZ^WmCZDO8 -z{Gh`GlgY8Pm|!wF#$p05(J;ZD2@DYvOeV(=6J0XFp2-h7OfZ=oLriqZ|0PQTDV4yPE>t -zZsD=El<%gfy_b@^qdhpl6&TVCrPH1safnUa<&BM!h_pK)ZIa-2hqhF#Fd7@6NITnu -zYg~af9${WvDmFbDo2*ECrO8b_;&z)@;f>9ZNbROXZJqSIt4I97CXV&SrYf~t+k+NQ -z;F~7lXj>{aDH@xvT)5t$N4(7@e&&r0kw|x4qI;Y4mZwLYViRBR#>Oh$d)kAkra;Oq -z^!n^n(){)hE5#yj{(rAq$6W64!hs%fgiUv% -zZHYzo((O0S?Xq4Sw!Bhlu8uUEh54?;qV3Y>H_h#0{%-xTW8~zf#K}78_4#wVtY3vK -zH&mKW|8O>yKQ@{_S2?*^`f0)3u3xTqs3BD&;#GtAoboPfS;$gmGS7%qO>A{G6ge6e -zaxaFGY5s71tFx-aQB}@Wg_7nfzque%HHmL2>arGuEzOnY)iv~fhc0Vp*g~2Fr^(#6 -zhO~@`w+!M7%Db$KLzcxR^Q;=uGBMuLhi_iU9S$YUcE5Q-q-9L2v$@pKT)|DMG*{G+ -zmcj9s@jPGLW#z(_)=KlkHKe6)yk#`sS;7UvN%IuH*&1mX-s*$bWv`PMT4JjBOFX+!N -zF5|ukCFL5wJTy`;y488A#Br*eTNg^ocl+fVBL!3VX+>SuAz{m|N_klgY3>(qzJ#Av -z+GYJDY{{>b7e$)0TAhc>9fylKdpIc<`sLb4b8mk2!Y=E9kmZ0$9#cb_bK=d}{OXD> -z>%5R|ydq?;Ytr5BM{5x`H=LBG`Q_CS -zeqgJ!wan34%E4_YHKcPyymJsgzr4$OTgY;oNuE_hIw!_E`|yEVcE3C!(mAHp -z87OrGD!3_?azzd4931Z)&#y1;vRcEIZ!6`8Ye;9`c;{#yu0shYW^HZ~niBtRp#n;yI)Et+h+rgC(B8yG_EMz4;TBti94@O~Q_A -zKTZA;YqlOEb#;llZIas~jDz_te)BbvoF15OPSov^z6)H}#a#2S^%z;SJF#e!^yFLD -zby+_SSw1$I>&Bi<~=O~NzNT0uXUDq$Sp}?G8D-^u0%le0qm>bpwG+a}d{dVaYMMIw275_y}YlWyTbukS|X -z&;}{b-6Jlti6_0jEQuVdOB~uJ9r6gdZK+=_dT0+SO##I%)V8I33!J9C| -zTz4SXC4A79@(qsqu2!nIwFetLfhA4CKCdrFBGr2m)tjZLyGMM;CMLYTzKXJ=Jy_@p -z6ncc|Z7E-V)Hgv<>f3|0O@UgsVDb9qN<`V5P08{32B?m)Rq2z%{AmE2v@2QJ}XZ7F-7sQogfaZ7vf3QyprCIN1HkVs>F -zqH&|N(%mEe!6ts?wGWd>>+5AJIU>~jk%+EVr#qW1pE -zlAY3>t{$<)CKh<@(Nj<4~*KcRH9p@ -zhde#ve47~X+NVe)x;Ig{K^o@n5le02d*0X}rLe9&SnmqddxX(#so1Zhu}c))WSuH+F?Yq^${QkJR4OBObSj4sUFMQoEr&IN2ST -z>=Hg~OT`99V^=G++uDQAdjggw0d5bHNbR0P?Plp4caQk6P3-c<`YPQ!+Jg&RfdwAn -z+O||IKN_2$bl0~BA8QIc<`%5p*j$NpZ%%aYlKQ+kyUW_!+8F5L65hV{RMI@cZ?25w -z4CVVf?{5#5GzCiBLM6=q-?yT?c#PC-N!0C@-0%)l*b=TZ*F_E(zE -z!hA?HKVLbSfVp~mkhQS~ui@(X{EYMaQpfidT>ntgTw{XIEejnjC0uhjX`bXabCIgy -zt+e0ij0T&uI7*ilf%oeCw*>-^>+k(N<>b4i!=aM-fC(tKA9 -zX&Dx8nauM=+@x^Qe5K!fU!P+7Tz*e6x7;LOA1RpJ>Repp -zSiF#XDwLG(^~;w;3Uc_xrCru9!j@T;@+~!_U`V`R0)MKw%epRXIahh%c9d4I%Ttzr3 -z&+y9+MEE|f&Vvgb2TQn@P4f5%KZZY8%KZ>d%KiOvS%e?l>g38DTrp=h$ptlppA_f& -z@~sQItVctZqb7M$4dKVe`QdzP1vfmDluP~c<&n;Dt}vI8Eja=Ci5%|I9yP{#7LB-wnq|)}};OowUg%{HOS7@|U}|V7@1jwOM-CE&PW! -z|3;;5gLK(jGrO!$ge*^(%umBR@}l{rQAQP`+LNpHgUH% -zf3$M)=aXlCxkd;+|D#Qu=*|Bje;sKU5^tEme_zb~5kCK@P5jyG>m||KwtB?NY@*xi -z8>i&ew+9zB1s1u5+uKsU*-_t6C2yB>(k1-l_4QE>?P#a>2&H^^QD3fds9vgW>Jb}l -z;u5cKjzkV^P8`}LDXt#4Zp&FI2fe=D5~<#isNN#wdV0hwY~o8^-*|~s*C(nsN=w|r -zooy*!LDZM6RPSmJMqPoZM;PYyT`m!2OG4Q#NliVXU=!DPee)!uY)mLSrCOKpO6OPvFZYp}8$(pA@yvSE3uFIqn{Du}wVXwGWX< -zv@Q|dCcWY55hvNigI@bsCAz0Qm}m+l+`{^{l>Me?td~-_qdhpx6&U6b;BGpJ6mClt -z)=RfG^@vZ|#5=sP*-GJN>9ku|=Z)Pc5otq0+96GM^@yL?#C-3CTesSSf+w)1NjT7! -zij9fJ<|xwU_F%g^(C!j?ys_RAsojyN-6Bo)^oUp5#FxFX@e--6PtO|HSsZVfD7jx-W^D&aOF_E=XDhbT#vbw^SrIqI2M{z4IE -zk9e<5{4a0*3Hv(IFe=`V#lKk2-4CDl+r%1geiG*Nayt0DcFQBoC&e53^4~wYx;^-y -zEAXI4xY3*cPnc`}0Ikc~KWy1rX-XBn3aCCyI1+$&NrqScvQ;>a%NN-O2c8d5Mc -zUNDj0Q`BX>JZ$k)%C<xUqp`^_D<@u2d -zx72l6hleeDE9K=iq_bbV^Adi3X_xi0u;toH`Q}JxR;x2m?g$ifYr{!-o?muEI(zf$ -z7j{`+2w7e*$zy9sXHL8`n_pkiWxXk6xyf|lnz~kJve=O<<9dJdY>&8M?WY&6a-4fM -zl|Lw&f0dH8P1+Qk(Ph0fWVzI2_QHI2G=Hd)wM%-}CH%KHzmHP)?+?!Wa!DP$!)p_5 -z-uyzP?q46Aah_P{I8nmA_U*Gh;`KK1FW&rbCah!rK^lDieVh1eZ~i|ftRoFW;|&w} -z7av*P9=zQhxZNd0y!oeKuHI7TT;3j>*%X-R7H;w8pM!b-ctZ}q!m+$P__`=F)Hg!O+ua_lYYNo4g=Jpf^%A|Nu1EabCeHNwu2J%~ -zOD8=-me+TgL=J699NH}%YU&XW*~DtEuTVL(v7O%LnDPya`lc&~wzmfrPasvy5w|d) -zE#Kmz4?`{t^HU%2p!pgRk?}n(azf!$ZTH@*vzqE;SyuN7?sotKb-YXS03H5C$ -z-{`1smZEHG4@&NU-t%@l?}f>TgHG=oD+ -zj=hhX;IXx7CmawktsPq%(fjlK)Y!Sfdry)^0^RGahrM0jwaQ&@)%#Yb>R7d^Zq==N -zcGm9x!&9Gr`0i&vvmM&I-gCR^P6juZ2R2vwE~rmBFN-=aiVZ6Ee^};w)$1G*8?^Ie -z@ba?2yyrjQD^tqxs{G*w4WW?K(F(1Kig9n-&5@WvFwcYrbBz!>zo-|xb9@I -zUqzr_x$jVY(%CKQyfU_M^U2_@%D^pUzEZC<&CeDV#}{t&e_3%xb2+pY@420hCxcVU -z15+w}W9pO6^r&-iELw6h_&{0UfeN41>zwLm(T(xwc7MG5jFxa{9lQ+}``NTj@o78! -zC1t+K`eeg^Xv5X9Y3ol0Z>R{|Q0^0#I@Tu}+D98Mjrlj7434b~_{w}$-iASb<}Zo+ -z*ZWsioY8J~Xve(`z5L9-J?`J)KUwMPQlD(NB-(I6Z1s+l!Dq_?&sO-B)h8RSi8geK -zo!jboMvFMKsosV$eztl`eDzNM%rf83`eZ}jXv3sf>xPrTgB5{;<-T9)lMP*>4WnYM -zh5ogbXS7)kE$B^u=l1(p+W)+AZqxSJFTe40n(gkCV|_Q*@;`6V}oQ`ogl^_kU{wc-4BCp>A{?zAjxVJIOiKRsn1S!)}aXSwozmOrR5zq6|} -z$NEFA<>7Gtd9M8IQ})tYTWOvp?S65sW5Tka+A=1bKlp^FZnnEF$J$bxu&k+$%|F>(W@)-_;6G}wJS4Zv%XS6@zDb98mXIU%rA_Kx1{anR!tp5rnA|0zE+2M?C -zCp-)0x);p0-jo-ad_T(=+L+P7bu{~w{qv@qO_p^-tjTyaNv;ws@5y`5KTpF$! -zaKbZYwtGyD_0!r!i4t!+zQbKFDcSx40-BG*?(t_-^dx%SPrF3XEt6Lt+d;jw1At=ZP6Y7>zq)seKYE6rt{ -zbIKkG*{0@37TnKVJsMquT_Ff&RoU;E?Yx^ZH(k0w-!3ocrEccqZR(owCVyTWy4Yv$E -z;Ynn=6WP{aZe-Q{tffn1OMh3VhnAfTwm&$@-6_ku{=400w2K{DnKykvtb6j%PVRUZt -zqy6a6`gyBH#tI5g1{YQaqGi4V^~tKC(W)7-*gF5TiZj{`4(*t?s)wJ&isG@&et+c| -zZJ0xQ)?1~*m;co8mL-<1V--j=&c=$s1K=`tXhc8q&!k2&;zEIr= -zUjjUQd0Pr!sIG@EK`DF*@bD#o@a2>kz8qBHiwa-bE_~TY;fua|D0zn%zI5T?OY0qG -z;mdG@FB`@1h3ZE5LUlcSStErn8+rJ$7U4^8F?@Lh;S1Gy_~JqMLUkj2c~=ZysII~n -z6~44h`0@yaFSGRUWw;o=Fb5A`sQ&x#rILp)bPt3tRM*2755kw7V)(KK;S1G`@FgUM -zFH|?emyj5~P~8Y$sIG@Ev!w7Pq{0^!zO-5RawCN=qxA6Q2{C+m4&e*ce;2;2MfgJZ -z;Ni<72w$jfgfE|n;S1G`@Z}R8zRZ-umrr>3GD`|yKH=dD{k;*sj1t2a`g;|=sPLtY -z!k4eV@pL-7{9O3rk;0ePdHAx%G<^9C;mg-z_(F9feEFJ(FEgd^ -z?~U+<>O6d*zc<1cs_Ws)+2vyRLUk3ssPLt2!k2>-zS#BfWt{%P~8Y$_KM*P)s66l>U#LHRtjIJuEG~J -z`O-F%FW*u4@{1n6JSc`QL4+?<|6TZU7LzY@4<5e!ipdwM8{x}aV)#OJBYb&_hcAyv -z;S1IE@WmsAFK_YiWeviYU&QcbtqNaM_|kUa%N7b>^d&|~Y4W8v!WYxYmstp3wus>i -z)s66l>U#K+kiwTOJbXzad>Jl=FJ}?HP@RV_4B-pajqv4tF?^xA3SU(C(l+7CSqfh~ -zdiXL+3STh!LiOK=FE8=%h3nP?t#QF -z-_Ale(|ha>Y?blPWwSnR8NP-Y!0Njw-}#tSgmWfAt>nNf4xBj;JK -z93Np1G7R;5>RYwd>iRFY-VWihnfs`&|8nc$ -z;E&CmcT|{J?&(mE&8Wv_+Ul{H%!}`1Y2zO~_sea_$Ko%yO#aI)?PIfFZXI_2HnTjR -z?!kY#wcq{Q%<=49O -zf4NP1RQ%;eb@j_l{c>xgUvA4!2HSU@a&Bh1!(L%#dDvI{v6=RJO=gxC-N7H5>9$;W -zY-TRi^~Yv#h%TuYY9-C2*&9u#9GqaB*Ebm-=?y;GB`iPIsY<&8+7slR9_1`@P80YG -zV=opTo9R43y)ah2Ft)8;7<;kzP1b!t_}mL)dld*X%Ma!9$7Z@0n9VHDKKk1WV@G<$ -z$7ZOm|2x2Rs_T!6HDvjl0jiF!tRe!V6=2FXc1KRR7&$GZUWXkIm3M_+v98 -zsIEUY(`6EWVeB2^V>6v5@fXHYU4Lxmf+ON%GgQ|fn;CvYd~Am5`eQTwsIEUYvvIfZ -z!q~w_)MGR1v6(h|Z05gyOs3y)&$-8DuKuU^*vz{}e|ur9&k`eQT8 -z?hzlGp}$YXV>7Jx>+wfBc5dG;bNqo7#~+x&*Hau=ar{hia(3jIE{Wj&vcUcdAHDXk -z)l--0uFJO8)Uv86(W+jt{o9lFmReg&o~1*$u1_L3s5~&J(sy}1tGlSN?tE9qJf`(? -zX!N@BSV3{pzM|H)BF{3tnHB7epL-#b?}mC-H?Xm;lgpLEw3QC+q_?U|tEVN~O>g(l -zvkY%$vF-8L7Jq9ci?pkbWQH@kCW4(S1N63XuX8}Fr{_F(ai(=dh&eBcO3N@}d(%{?Jo}PbFcLBmhKlfTp-&Sj+my8L3)!r>7E3dWZH~uE{Hx2D<;LoB -zZ;^Gi%x2m_hql&RHLKOrGt=EO+q$uqImbuOy%p2HxtvArsg86FXIz*F&Mgl}FJ1O^ -zt7jQ%7gMTtF>Rui%kED8_C|jy -z@?A_>e6io;=lL!sD)PmC-R@5QwgBT%aTgPPrt!~Z&+}bOROE~OdfuJ1v+}^d%YA3- -zS$@05{64OY&9s{wn)v2eZ$tZ5 -zk2TwE&9XifVh!D+=UzEvds5ZJ#+PLJolnyYwr+ixFFgv -zA=W0CTtS!|*8Bb?A|_7)6SKvB6P^Sn;$pw9OE@OEz+{Pt$& -zV!z4Nz(ic^*KGyIq*lU&FZLT#4NSzvemz$xOzeF_wkL8Ui<{Y=4e@g?BKQ4V&oVkR -zX7qI(&0^Zu4(%GRb8M^U=o~k_SUES6)yx)diZ9&Z-&MvUf2od44A&@32D=ionHF?t -z9&dW)0K()$9h196Om=Wg-ZSk?c5qDSIy#fPI40wP$z38QJ2)oqqchndVlp0>+$CbN -zgJVLUX>=w#L`=pjOcW+B03YN!bD+WzcFO{EH`prGh4krer~0OFH+B1 -zIybiTa|Pxw?UX~KjY+ZAO-cK6A)7rnVrgcro8zq|{-Q>n4mLx+Y}RYCU1+F&`k_XR&h+I2u#qKybVmG&SVwG%24BdI!g(E5~H}9U>+hI3^>|nQRa- -z>B=$Ld54I}2961RrqP*f5HabhFj1JK9+Pa!OfJwd*(zc(0-Z^P876ey=u9d^Oz0*$ -zCM6Dz2^Bdem!dPN;FwU6cP85$9FwggCiIy`XHvm2p(5{0iX93Qg-Pl$xr{LRYEToyp@OCf5Oz#Udt;0~2&6kBgXGr!Y~N -zv;iiRnLMUr^09;oI+NE-F+peYnurPA#K2@Z$ApT&1f9uiz(nj!wk_wFd@Nyt&g3;< -zB6cRl%M~UHlhk8!5n*yj$7GR+NfF1S!n89f;+W8NbS8^9CRYHHMIt6e9Ft0PCPgA9 -zR{)bmA|^!~6Z%Y}Gbs`=xk6#0Flhr!C^N~^G4YC+RH8H4Z-xn7H#(F3A|`Yb1Cs)d -z2^Bde73fU%b4;j+&ZK~2;uSHW&onxd{Tvf2qBAK_m?%tAkI7`hi+Q9i0j0Oa=fGY0hLb$K)<_CYwb}1^^Rj&SW#kgg(>gOg4*{ -z3{aRTOj3`@2b7si&@p*h#N;k?CNG*{Lf4JX!UUbk0aHxSnH&%?p_>?( -zV9tb!zyzJi0bn9^CYUq%O2P!4$pK&@btY=gL}Ahfm<%CIKGHFf=1fXBCf}QOCM6sb -zx{l5Sb0${<6KT$*gk$nAbS5PtCRYO!Y0jjCV?v*4bS5PtCRZy=6eewe31udK(=qv{ -zh{?aunfS~wq3cFx;uA5Un;4j2&V-5_lkd@)_&6q1L}!9IlYfes&}SN*iH~DKMRX== -z&O~9-2AEt+n0%&VBF&jR3rtKqlV^d6)R|z;Q_C`?k1$z_z8bki}}Bx2GRok_VF -zCUo8COv*(}=q5TQH(<_$iX4**(V3KUOsL2^lj|{OvPr~*KGWz-$~h)f9s?$(oylXsMC?qi!<BuvnmylRRGI+IsLOz0*CCYUp!A}~Q`@+vS9JCo}%XYzrB -z2|ANkfr;3eEKqYM3X?X# -zb^{aB&SW<*kvbF1nJfk-(wxa|V1mwMw}{DNU=p9jw<^dh75G+#kIn`^uMA8q^X>4a -z-}ILzc6dkp@CN^DmuE0-xkLMJZ~8ncZi^o-^xs?QyY~8{EPb4MNqt5)*MhlByV9Y( -z>~#)`?I}sxC)L^}~;2S^{kldUNPHxdx$v)N1fAS -z(e+9D^pNeX+{nssO_xM4UJ;0w`x5oc)vnRi$2ByIY41C<5#EL?V$(J!?H`3~qjDqH -zH?wJl@oB~WV`aYAy$wTR({}pDma#}qb!24NH82tMl?8kiKBu=~TC3+oru#&;^^IEA -zFeTd1E9T#xw4bWAoyv=J2)Fb}1c#LehE@7TwFNhmn6~bdBewOqmj9yv@H;l9UF7OC -z$NDb)H{P|{a$PuWH2qI%uDfuy_0GJA$D2MR)_te{QaZTRp21 -zZ}vYvY7)~fa%fL_)6-(}_Z>MK{Jbpid4=zOIyobn-XV5)tAFCiNlZK9(5~{PJ0~`= -z!<*xWOZ@lJ7kS2^{neX3HFo%kBWHvEu23(jSML>0?W-W~C2qdaxmhWWHNFXM_ArEdND|+^uv%y7WfkhR*TR%C<(x*hz -zd&P?OesebXeR<&fN?%8B`knVSvH6?g^LO|kzicYgo_A=Az3C5AaeaLLHveDBePKG; -zGnzgoHvg$_L`?1lCQ~^kROFb@Nrj2Rq_O3E*Nk~g>+jH>@;0Q!Ru?Djt7>hl@*>ll -z+3KC~)^+}w6}}tmS -zWIo5_`NCWkpDR0JjyIVPil$wU#8!yFSj2}~w(OhyBfi6SP46($Ok)MHXWm_&6< -zR*0C?029;BqyU&q5iyB!OkM^iQ4x~@U^0bcLPd@Vois3sikK7tlPMe%DsoKdq{2jD -zl4?vQFm2u4Iwq4vOuj&8Qf!LJ1dhod5tF-t$%h;hDgu)U9Fsx7WP*svha3|+2}~w% -zOa=jy2_hyRDohk6smEj?Ve+MpiBrVn6^_a0rk%+`V3HwX@+HUQZea4Ih{-}=lEE>d -zBFBVI8kl@3VzLmJATyyN$AnHQOcW-m#)LAHpLI;`moPzRvd@HuBFBVIDohk6DaK?mWhMi4OwJcEnS{<{ -zqZuZ2(8x?Wi;@)Ziv$T6Xl1}0yNm@EY*$V{lnF`<(R6NO2tF`>-lHXW0zL`+^sXR_TC6J#d+L`-f2 -zCWkmCR0Jl-O!@&6DKk05F`<*d1er-cU?OEEhZH6Xlhk8!3t>{HV^SbuQpGWO&9pPQ -z1(-;gNgc=JHegaGVsZ;GL1scljtQMKFsTzUxdoUYGod2Kgib0<6eg+0gff$_bxf8^ -zn4mM+Yl;anlPMx5Ujvh)91|)66J#b+fQgiu9OanMNnnD^WC}2mGLxeU6NO3YF?oP6 -zIiX`B&6&IfOiVkI2Y`u`nVjI5d<{%ah?qP8OpuvSkz+z94NOjmm^=VXkeN`CV?rkt -zCJK`jWAc9~Gr2~`WQd5#edtWKm|;Q(jm)H%h{-j;TOr*@@ -zBZY~=B=wls2$P78i8N=TaZLVg+L_pZiIkZ{I3^DRlZc3k4VWM^p(4kGP8yg*L`-bJ -z1epmHIVN;cVWKceH71mqoYpaUM8X7}$#bTdATyaMVsaXoe8w@MA}~Q_G833cnaO7y -z6FLb@keSQ`CQ@ednZiV2l6p+m5+>j2m`HObL11FqnXCmSQfBfU$K*6H`A)=SEigf5 -zLPd@Vois4{PQ+v_FhOQQMUDxbRG27CQjEz(l$mtWF=;Pi(t~#<``4LaLI;h^tpN$N3~-Nd@z -zT6+$YvErP`+hrV+?xvl|Y>r8PF*C8%a!fjLOm43gF`3OVxd@pF6*(q!QpdznD`GO6 -zW6}?q2^BdebW&lWFiABgl$jLjm}E(q@Xloaqo$Z3Gr2^>q!5^V%rT)NFhOQ=2`~{e -z6YIwu6FLb@keOTpOvKFOrjHdS3X{}hawlQ(m5zxxXY%$xfQe~mawjkmGZWia9Fsy| -z@|B3moxlW{2^Bdebke}&D-n}BfeA7bDsoKdq{2jDl4?vSGs)30xm3htJ35oC922(e -z%VCedli99a*UJafG6muP+`-VS`aMl$zJL7ol6tze(YstAa+3pYKH%I?5!@hExd7aV -zsfzUj&JCReH%L`305@W)a?=Nj8^ulPxyd7L!vEbeJl6f@@Y!Jd%D{#)Uzs=kR=Q9U -z@4nuj)h~l-xel$?n|^+*`}W^nQlAHI#8kx==G^3fo3O}D9=JiOLPgFEoiw-!i`?Xa -z8>A{!5^-HZGi(k3zOzZ_a0Z~Ed1O{{xi -zynC_#JrNV6DicIZ=qCEclYDGEp&~FrsxkqXh^dMd8&BvYFhQy^0hoxX%1vtHiNd4} -zF!>u{@{NwkHzFo#^hD&06H -zPf4i?HlEN)jtPAyV|`XPjtPAcq$+CTiNd4}Fu9&E`CP~3a}g7|pkuOYvKc1Vb4;F+ -zQWb1G83|0JjVIT0OrAulLPd@Vois3!HlAG1F`@5d>|&%M$AnHQOcW-m#)MLp7j#Ts -zkT99ZF}czd6Qn9vikQ$%3{0@`go?lfsmhhWL`qe#@q|tS6Qn9v0uw1!Q5#PbCT)Pp -z-GoV0$0RCZLKh57rkG)JH!zV>6>L0t0hmY|PwoaLNL8rFF`<(NCep@}yMYN(6)JK} -z=%m6#VUlW0C{b4p(4kGPAW_kCMm|`X39*`bWGAjO!ASLbTY$) -z4jP$BClM36iGc|=o=}lvatkt(P8<`9l$l`T37zDa(04L2lTI8H`Xb0o)W#EqNgH62 -zLzskgOhO_ibV0}D7Sqfmhht)qG81e(NdqR*#*-Y5$<4@2sK_y)lLjWz#*-Y534JFc -zGod2Kgib0<6eg+0gff#-9g|WC6J#bMO))`cGE&5ZZen19jVDwDCdf=i0uw1S!NwCh -z2~3cgj07f9W}-HpC`{S_lO=@7*E%L&iT1ewVg5fi$JfeALAP!X6Q -zGZ_O+q|5{xPv|5tL1r=rm`It4+IXTcX#-4F5GKcUOpc3~&;@HuBFBVIDohk6sm6pd6PJ#OOTq-1$xu^FkeLh> -zF`=6nm|)`x6@dvdlcB&w%1p5FgiZnzWF|v_iIkbBjVB6|Ho(M6m_&3;A|fVq!N9~c -zGqC~_DKo*w6BjU%HlA342{IEZa!lx?fr+&7#0pH1nNX2qLMIg_3X@c0LYYa6j!BDz -z2{MxzrkEfznIU3AH!(25#uF+66J#bcfQgiuVB-m$1SZH#W&jf@Gf^8)6eewe$r{4s -zI~|knL`>*{fr)8mvIdw)nF%(Yv;Y%nFLGMO@yo;oHyMNBe~nRGD2gbo^+Ne2-Vx`~cS9X6g&kz+CinMntZ$y6~jIf0EQ -zbdqC2-^s{KI&e(ri}1|k3$^h?VbTVe%xPlXzp6clNw`+Tgf8fqOfk(&=5S1=ikZo` -z*m%;DV{%;Dcru4$G8vf(6*(q!QpY4BZ9JL7F`@5dWF}PPn9xauiNYk+m{4X?tYcCv -zVS>zLgefM-Oh$;9&`k_XuaF6Dxdw -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 -z42w3*jICbhA6CI4BdQ~Jg -zOlT5ii{87;kuc$@N;uaP6P~IZ&J{7Cn;4j2;|Udk2~Smi&IKl7sxk>1Pv|5t;i<~; -zTwo%mD$~`*6NO0|U~(s6^0bbLxbfuI@xa6^Rr!8AFcDLg3D|h@J}?nCo`l8&6P~IZ -zq9VtHP8yhq8&8_X0~4OA{6s~L37u4!C`?k_nb0K47QHihU&4f^D&c!fG2yAo;d?|( -z=q3gx*my!kV8T*1QcQR5HDsoKd -zq{2jDl4?w75@nv=nT!xI*@;x;Ix|d4kg8lKVnR1DFu}$XDsoJUk*ZwBG1(!dD%f~J -zCpjkcos3lFI*ti_5u_?=!WVTuVd6NiWi -z-Ne8I8&9YROpuv4fQgiuVB-m$1SZH#9Kb}%Ow`5`g-IJ=GJ!DJp<^O$Jo$A1Ffq+c -z1^^Q&Gr`7_yMT$f@gy_=m>@HuBFBVI8kmS1Pnre*6J#b-)tJyE%13%< -za+ib&GLu_PF+pZ>tB48R#J~g_PpAk?keS>HOr*>N8&BvYFhOQ=D=?8V6SeU~VbTVe -z{EaYqM#n_lc=GGjz{E5&xf+;AnF%(Y{0o?f8&5)40~2H>ROFb@Ndpsc<4M!izyz5I -z6*(q!QemPnNi`-kiSm)&nfyz_1ewW0rkEfzc}T>BZen19jVDwDCdf=40wz*sf{iD1 -z5||(}c?g(DnTgtXqA+O#Ou7*!8+1&>jVHf$I~kctHphg%2r?73@kC+L2AEt= -zm^`jyB5pkS^)g^$nweY%Or*>N8&949CgR4E&}F~`nF$p+CUnxkMBI4NbQv%~W|(mRtUButQ*EH=dinaN@i6S|3k2{xWk5ttw|Sqx01%mf=x=p-;f -zX0jNVNSTS+c%m?A15Bia2@_-{H=AOD%;aVf6S|3k2{xWk -z5ttw|xfz&9nF%(Y&`Dr|%;aWZB4s9OCRF5@&`E`f!X(w0(45IjdS~*5gb6Z} -z`%N)HW^%uX3EjlN1RGDN2uzTf+z(8o%mf=x=p-;fW^z9;kunpt@kC+L2AB*aOg8J7 -zh#OCSJ)dK8)HE|WpJQ@F%1p5FWD+nDH=cyf=a?KrW1}4~eLPd_rQDi26=9nCj -zG81e(p_3dF`c6h>@@I|-eGz0PYU7E*qzy2+jWF4zVf$#keU2d#Ds2QV1kV&R0Jl-O#TW?q|5{xPv|5tL1yw-U?OEE -zYU7E*qzy26m@s)($3)zC^6Rz0#56Ox7MMtx2{xWI0TXfKN$6T&g3N@991}WeU?Ofj -zX}T7eATyyN$AnHQOcW-m#)Rffe$qRWCJ7T{CXbk6g3RO*5fi$JfeALAP!X6QGkFA< -zNSO&Xp3q5Pg3RO*U?OEEYU7E*qzy3XM3}5UhsoR0#*_9OlQE{5NqdgTRbpoHDmI?< -z;F!E2Z9HkuF&T@@go+#!I;mq4ls2BU=a|rUGBOh?a!lx?!bD+`VoYwOIg|c+XVOE& -zWE?V+EHg~TA~VSnF`=92m;|u#go+%KG004^I3`z#naS(ectR&RCiI<*%p{9rLSKYu -zCU2>YC;zXQBtHB5jLX)qZ`ZER4r8OjeRmm~6>f+RPHgmD^VwC+Y)^4~&qn``6)bXX -zb>xw7O*_|^Y^LQnv_oEJw^q-X9QT+x)=xvs*(vHA8CzKBzon8z231EEhHH8yf?rk! -zrj+@Lz0SU^o)vT5D`s174>9N9sB?NOx;|;295>S>D+2LyU!tD5+BLfR -zxQ1pi?R|$f!rO2~Y})3e{iBd=RBq(@W;U%bKCRe)tjzbiw_!+Z+D`x2G8W0Hj*JYu -z1}1{OvVgC`=kzvAYxSJSbf3t!zER5>rbHWh#r)fo_EWXCQ+bgN;g&v$;IQ(*uu9*k -zde(ALW6Sxj8S|Ld-=RI_ZAgo)E>7B4)!J6&MW#2i)jQ*@>-;k-d^gs!mVu2eom^{j -zn6}EH{o-xt(&|ZMyAxT~U|wW+Gi%)*Z{6Z=PyYe0>v7b!KG*VJg+H>ij*V#-xjN0U -zzT1BfvvjStTo+C&C_n8foa-)}ZM`$ka&)|?Nb0qD5tF`?t&+;}Ehc}kCbB)ZlZtJ&)Sr%1WE)196Uw+y%a*liC -zJnNNIoL_Aj9WEW@df_%l(tdZy_H(YKweUw)dR}Ac1+FDo*4^}({i-dugiBYHpY|-7 -z=l&tndJPrFR$EqvOS`y!usV|V)3vtKd6x5<+32nD(VP6;E1BhjYD-=?|9n^4Jf>af -z&>r_zUDWC+o$D^0ZC#RQxh9-H%$1*MO$)KA3!_yNWBWHG?fD^FU9QCy&hL;27E}ZZ -z%6-v#mfxi@zrU+)4%1p4T4!(7C9#4{Nqcd~wjkGXQ!^{r94{#GFDzr0KUG`O!*zpP -zHM5y^z@a_ht(wv5ab>z)+17ozmSxQ>wjmxX^83q~<-ux8?{Hn;L~wO^V0EQ$rnhQb -zt0%D~9^2w?tz?mQ)sf6_M%P5Jb7f$2nXlaI9MJ0NInQ03X&n(_&WobX$+1Bj{U28N -z{^oUF8{4xkY401dJ&_w(+|2fDi0>)#zgX`3xt?WoXw2yAI-13_uN~SoUgy|W&(S&V -zqw}miawA#IY~iN(!X5ryWi0ZS>d3@!&5%U!ma@Pt6~270Go#h>%53*5Io5_+=A03A -zc8Eo{`lpn$$kOUazi>@jB6y%YaG=sRw4T-UZLI0xYMg6z*D~k0sB?HMx-)6-Qfupy -z7rCUFP1_Nlw!vRg;k&DzxrQ{l+Pn5;Gwmja_Jz0M{MfYZ{$u67CT~OgR*yB?ZOyVi -z6=DtDqYa~D{>^@0C5!Z|jw}efdL)7?D+4FXd~ek=SMNsGaMz4XYwr+ixFFgvA+~x$ -z(tcye_E~P^zGk+1eSGyczpdOCsb?*n8(aFh0&|#l%Axi4HjIe1Zc5sp3)$?s5lb^` -z-5hT%@vkjoksGTc>iW?Req?PeB7wPip!t)HuKj`jcKSvrQ({`S~uPfnIQXRbAmuHRg3nH)|V -z>N<4m;-q~-$o6Wk<-c=&WNBR*)B3v(-M%-+C! -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 -z*&<>>pK0_iPWwEOEUXeYjxK$=eVeI -zcr3azY41{N>yj6_q?t|I5udifU-HKrYaBtC=o?SgN|Pv$0Ta{STP~oxi3=BS~@qj^m7H~Fzu8>>+NkA5o_I)v_BWJ*>fY7X4bkn-df^cTgD*2jn3p{jtLdfnG`5Y6eg+1WD;SbZ#-Em -zO`_}uCZ?UqZeSvHCYVH7227+$l-VepJvtIGKv@f=Gdgv_!O1e}88V(T -zqp6N(CPqL&%a&;B(MVyIk51=g(pjYG*pfWo>*kz!?&nWw7p-3^Y;bihU#RQ5tncz*7msm{T&(tQ9*C{4Y#L47g0}}(2-p9lQn5Y|1p3~h# -zX+li0P9{x=iEc8%n07Ef|%%TqBJ2UIGHrDm{<%<3`}x>31lXs -ziixbl1SgZ`teD_r(#&E4AEIG`H&LL7nBZj6jF{*q6TFEc>oCE|q!}^MO(yFNObkqV -zACoD7iMsLRIo(Z^28zkqtdmIt#RSfAGQpcDOA!;@O_Tm4! -zch97bVscZ~$)t{A0_Sux`48SR8AUPa(cLqtqnNC~$)t|OWE91O=ck{XVS=G0)M79nfNItP^6Pd+PG(8V3Gq&<^U$@#*>Whp2-V{N!H2a1;m7%O#XxS -zOm0I=boWeNKumBld4a{`HpE1C&*TNf1SgXhSWIp+FflO60Va@{{6fX#v~rnfx9x(M=}CJre_y9AGjEFi|(2WOVmTc2G>7 -z%Q~6tpqRipP9}KIWCmiQyJxb4V&cZhWCx4M48%lt&twP11pZ8IGTFgmGQ+^cz@+yv -zxd55T3Kf%Iu$Z`UGI=u_CUCAzCU3Hsz=vp<;5`#4QcRx1$>dFn2^4WM!FwjZU@?I| -zQ=3fQq?kYvCllkIiGfKDFu4veQ8%7sboWeNLQJwwCNCi-y2%9Znb;8%-93|+5EGnC -zUSct^BPP0gCNCi-IGMb}Vq!NiF)+yiCXktgRZPz5Fu}>>y{wqvWbz)134Dl#3Ene- -zB4UD*$$N;2ZZg4pCg*gR;AHY1VxpT&jC&>qCON=l24JFYJjv+pnKV*NGFc~+Mv4iX -z<79&OOjaN!x_ccd7zNh6EN3dBTr&!mxJ0)M79nKZJPtS~S!Fv$TXkeRquOu{TC -z1Sb7c++vH=O>#+aBIi|9pNWDp(lL8J-n$4>VuO_6S=QTyX@aZZ3C+; -z#kHhnNU~-UmtSlxkESgPf|kc)HT~M$O=Yg866@>LmdUZ230zaD_3LQbGB9WCd&6b=jLEw&rTfv|3U#Fs0LCY1f)=6z{ -zbFs@@Zao=ETb>MBhQ(UPa?K@O_P3(8^;MR;Yf0kE;z{9sTXA2a83t4h1$9pjh*mHuw4x*ZKXHZ@eYo6BTP8PY6Wmb44 -zcP(iioNS)RB}=>PJyF}>D!I6pa6^*ZByL){1{u1k()$-&R -zH-XzxN#2%JUcI!%EBw)YGHn?Ww0tj?uRy&al~*Sn@(DlUO*bm_o1~c;bC><65!+9z -zEkA?Lm>V}0DD``#`!ATg>;#P-P -z#+&|Sf08r}NH&e`O!V`SpMu{BQlsd3en(OTmTO8tC{^Bl_ -zj_?70Xq`vc*PaPXhzFJ^2kJV)iZ7&ig>F93S0d|nrq*qh3j96dY=`&;ADAqWb$e6m -zHcP90!kz7zfH@u*p{(285srI9alZh|P$Z&kO(}aM$+c1qWJd&J`o(Zna_ -zD$@3ju;33p>JeUT&m<g8L#4?F=Z%%dZ -zlAiMl=h`!gQSroeO5W(pu6&>5{b$DCyBoXvd4&&mCft8;j}BU@V)?_lf#h6m+7c$0 -zM{Ji@TX^!IOp@tRf9Q}$_ziEGs^m3FGd;pi@{&OQ-nC+E+_X@s|F`|`-RDAX{0TSX -zo)&WMWrz4f-js6xB(b79^LWJec(vsZWUWm8p7~eQMm&PM+OmagON0~Y+jgc_Zk5K8 -zIqzr4*%d?MrmK~e+uzTGd*)QSUN5p9l9)8eM(O3Nl` -zVJ3X-diqz2{H^=6j};E2`k$(frarvo^qgGI^gXQ -z6^B^B2WCs;z_!$Z21)Vsh>}Cxzz1$p)@|wt7x+R2Ug2naCNMM}xLR4ay(7HOA6o4Z -zV1bH6)-|No)k$$*kNA{BO!0yKin6mKT<8rI`h{!TGXYaPFhx=Jc7!*0LK}R7jSno9 -zh*FnQc1zvf9x>w(`|{4qBvP<7Rj^0e?h(B08Rw+9^LnLVb4R$s7pm|IQQkRRDcCI? -z^$P!L&p7+VoimkvTRXzD{h>EJ!moH|fkgK0P3_w(t@ZVYcR9o_dFM!p?Ax8%w?q2I -zFAQwYI4_So$0)1!bcA2@gkJOsYuYo;8{*D^%IaOxo!%a?)ghXB=RAq5-jQ0}D8X`w -z_Kb5}+_^}JZ|MlX>kGZ>6_V{4=is<=juPJ{J>~BampjA|@0=l#cw?$?lQh!TBbGYE -z!+c_hQdr*+-s=tR^$X+LGl?tXiSdeV)lf(HT2JU&pKwciCb2M{$Wx?xN$~cF35Pg^ -zPt2Bxv@InyNFAOY@%IkV#V2l3Hf-t$PxpnUdxc}|nZ(d|;%a5X_Kxst{*cWhyu>H+ -zC9+2Dpc8FbkqQBC;vm<lPb`&4 -zcU`J`x72UI;x2pN{`*4k*Q)Qyw1xhy8s+E+mv}-YKA{Tgj-X{yEPn#GttqE(jKSpF4I-<7K0Cfz@HahF~DYqaT`jOnI$Vn(d#qL$dc-Ro;xBpAT}4llCi=^*-@gC;a$65|`pXTTSAV(P0(JG58+=vz -z%k62X8^7F)Uv9biX-a-8?=!Aa)ZyHzuX2a -zq`%ytuKseH_%Zv-t=}vE{pI%fW%QTZum_o6ZZ%L>sTuJg^ULi4sH?x+hCWDtxxrVZ -z!i;>-_~mB&a?9B-w=d4P2M&KEmA6&uH+V^xy*OekuC~mN<=^<5_etL7RNgMBWZ;r6 -zyEkgPugdbnSpGsV}!?_#++Rh2GFYzi+GB|YI4 -z&Om*7&|-@#RanntFqh@Yt3tOH&?iti>>RUY0I*p#T9Gq -z%W-90_Wcpt{%Xs_TGE=IY#qUIm0kAb5!>==%XP8VDQ)h~VpnImH62M?+(Efd%sjfy -zJ)*=lqQY8QC0ErF^YEm3D%VidWxpb7^H<4^n0XM_P;UK8mHgvcV(yzXkKtC8blG2s -z+U}^5e-JZ|XmhWsbe$}+E{dk*Yl8A4G4tRy_sMeC$x`dL)pEaD(mXoZJcOH9(Ph6S -zV!NeUURX<-rzV^Gac`Ab1Cg}6E+`konkTfm-zs&zRcW14C0Epv=Ap^v$=v$lF8ke4 -z+gDZcQ?;bIf3kTTmn^aVKAM)N2W4BVc~qM_S?QWqWE~t$%a;e``(oSxZd!Sl{aD0y -ztXdvgOSrK~E|1$^VST7dzAMI!1*!oyBEiVhou2^SZZev-O{TC72FRJBNoT4$;Az3YGdXADwX@DRUhuvHrI1a&BEwXvpIJKrZQ^{JNa(%bM=Z;04#sJ2`iYgz{Nx>U<<>EGTS@q$C_ -z#|JKx$lR@|xqGB~kKk+11SZ7;*DG^3cZ65^LMy!jyVtHg6X+KY%v26+?Fi5HhYomz -z1AL%BA_w-S4s4dz`Fh0F4l&LLMoQ$s?$m)DlHwNzwPymC#{*-Ob$dF(`#hn2K4EQp -zCU8SMFi^R;CACNV+#xRE1M?)ZZbxceqg3b-_O@pN$GG?i{Za -zG)PB1!f$!!RHdM?BRty^n(Y&AZqGOu#+`Y}#hqO};@=$NWZpSjBKx+b_BBY~czVS5 -z9pW>*^Co5WrjGCgUuc3?IMSYR4vjmnR#tEC2*2nL-RTjUcxS#uRyU+p*GZrIdPL44 -zcJddOc6Ef8ctcD4!o2p3(-e13QQ~_$!cTcZPx%BZ?_4U8cwH*KTS|F*#I!@~&nGUE -zNa5C0;T~zPNAS025|iSI>y^UI9pPJjpk;pEh+pxEkrI)1r=%THhhG@no=IFDPmEDE?CA)<<_W## -z6CP^MByNZ&1}Yaft@MbpLtM%y=1FA3j?{)m=_ZfR*q%v@izgN--CH`sANWEac!hto -zXA*hK4pOK%;AHkJZS{H2D*CVR` -z4)7Gz2Pg9j?kZAIcP4iBA|%d@^k*30h{xny%;HCo8w4R@O_;4>Wh#KZ)9| -zuClC*HO+;3LuzH6^ywgTm;G-M+uy1!gJMk!`1eW6)>O+L>FojLF8f_k+m}_A6nxde -zanl^7Wt;TGU~`xKnTYL~YRgTvq-jR7rVp22)@9!ov2ClijEU8ZZ*%9Dy7DWnvm$BB -z%|Xl6v6=#|so1)v+HymzW_p{urpQ%OW^Ib3Eo*|7{8&vsS5w+$Z;jf_RhCt?q-I#M -zW(wC@+-2vYw$3Wc##n2gHn+LVWiGKcMAMdWLCYPn*5Pe#bET`f$U3juVyY#r1qM@z -zw9B53+WJ??MYY5{Bx#<+jVQL3M$_{Ap!}nlxnG;Rq0H4#V)a+clVauxTtlh#FVVC- -zASjo`%tPDUt14Wpimi84%ZqD?d0NukpF3IBWq&7Pd#75ST1(6mljczz?6`}h<&vO0 -zGuAw*%{{N!HLu)yJd&252+Db}=CRycC0+JF)aI;`SJ#r}k;&%i-1;KxlxSL>9hBF` -zng_PI*O$B2ms-Dyrsa`A`PSIQC3jtRSH$M3mT#&h%`=i*A8uM%mwiXXwxe1e6XV9W -zxu=!7rd3+!MAGujLHX(!SHSHrwmwuX-w@-bx4ErFE^C?frAS&{6O{8~Ts~(l?Xt^J -z+tMm|RW0F$CAleFTXC2D>8P!%O5Paj?9=96Ugla}Vr`73<#9pzj#%gLHuv&MSE$H( -zUA1hgC7lJy&OuzLyvzQNi0vQM^59tKm^Syu64%BGt38sIEkSu{taDnMJ6+^Tms!JA -z@?*86b8xbAA~$fz+KzC)L5o}iORSsgUg;4pbBG?^G)c*ue&URKTajy9nbo`Hl^!wT -z5a;uzYm~el(jmVvgg4zk|4EWRG?_n{D<8VHBkc2qd|siQH&sAgO?5`D?Fj$b6Z*4H -z`0>FLY0I-gc?F-a$C@sC`F*ld{r9rLi@NMLM{GA&Ti(9+n~dp(xM`rWa+h@bz(rm5 -zUqx*XS6Sjvr~gbgXi=B_m5A+?YRijIH^og;lot4^Ul+N)F0;O0W$A$WsJQ7mrDaD) -z_}~6eo=4cyo(YVO2j(jm*QWM}_dCQt^ML^pnY$}Bcbl}*FD&E(*C=y$NG<*zG0!2^ -z^MSDvIj|>nV2cFXh1)ZM!gyeia$r|Sc%3)2&My?UX9Cy81JjiQjZ%T9N8IiZEBL?y -ziLBd_T30Xa^Y)0}IK&BjV3x9OTSs`cKNR-}@3vsnn@f05zCK07R -zrEHfZe~&obA-={3CMrrpN4VP)>h=lGwPyk=;?6!w!Oo8GAa7`pU$~riUL}!&?Wuyj -zQiZ2S{Ha5%=ADa`f;#D_Pk5Yn-YAiMn^OCBO0&H^;wKLAYTh|l*|)tT{DwcY)+4;q -zo^eiyJC`W?>N>*T_(I=!h3|N0Ux}>VnOeP7n&9sdXF0^zdFNz_tlpbiy;*{tknI_# -zIqn>xtlr%b{@fe-+%JsaomWUCzBLu!BfabC5#Mr%>v`ugiNrUj;=81$yh2-h#yKkP -zyiSSl=m@9$p^+Y;u04|&9Z$?xE-r=a5g%}ff8i4YBvQC5Rk%&M)h{gK6W1t(JET+o -z9&wmM+|4J(N<`X|lD0^KPjI$p5{2=^AVu2M5q{Jgdekp0YtJOEjVGonQlm88(de|3lx`NS+`!?upF%^y1J5#DRhB&Nj^%a!g;(oMb|@ivEe -znokUqNOygzd%N_3zek+m5P!iZCMw+x9pQ{8l<^6D4xUU~KK$cav4}VQ=tobI`~k`Q -z@!Y^t>%qELd&JQW@h80L2T(6a<`3ewm0SN*W%+R|zb{ul{Lzl^OmAqWU$_cBgZ@MF -zkViYh_xnQkdxbBcJ~e2$CzgNR@7^c%jj8UzTza=OcEHju`_QOuSC!?@fBYt6QvY#z -z!kIJfS@hqQp>B?wMkp(%oH^ruz0~!3rFC+ZxeEmRDJ-Ye~)UWX)8rsi@07 -zD{6ba%JOimW)Rm@ZvDE-@=PtM>6@$>!_|~@*_)!ankq|8tY$=;yQb3BT4Xgx)0TNb -z%lcT&;5K(_xvRC*3fs7AN$coj>k!Ud(Pdv1v8}4MEUG1~Q$CnA?_GJ;tCznXKD%8H_46RtR-Fcm!dXHm0T0! -zMzp!Dm9DlT>(Xdio)?tY$GE|5?zVDQTdB3HTJB#va}BWc+gl&8cxC$zakrLIt=bw-t3SxY*HCOao{8;iT__NeV#mHc!q>Fl5E -z9LJ?gtl?-{o)MJovHZ)nzEAQdsmmos-q#V{;t6f>3HS1*9}jtw=pI?{+_3sBQ*TnLdLA@?jzgznAw)tIlOk_rXlQCT$ -zH;qwNPCazSJ*(I?tK9lY$;&AtHRMUs)IZrYj{CaA`aV2wgfB+;lAG{lD}*nlYWQ-w -zE_`{IhA&XRG<^9b4PW3hFnoc!8ounn@Z~4E@a0n)zLaA4@;x?uDZ%gs>NI?T=e6(! -z>RR~nFdM!=-3VWd@Fh3lOBIAKSE=F4&)D$Ai{T5@F9~0^WB3A}LBp4=7`{MV3tw8; -z@TCO9m#Z**S;K}eP}jnjHEj3-buD~ZL&F#Nsu;ekF~S!ke92k(5{K|*{l)NQhc0{x -z((q+l*6<~Q;Y*wiU!bmqFL4^al<2}22Zk@}Y53yRg)i%A_yTndU)Iy`1?pP(5@f>{ -zs2kyn5x(Rmd^rT+%YAD2GM^1!c3}7d^-IH-qcnVh&%p5IC=Fi@WB4*j7rs0|!FHqOQ7pT+l1?pP(vWJE*@KrHxef*@5B9 -zkJ#{K8-_1Xr{T+X3}2wGg)gVr@CE8d_+o@Fxd~tX1mVj+)$rxVZ1{2*!xyMu8ooS6 -z!x#7r3|}6j;S1EY@Z}F|__7tlmw#gTa+VEWpss~4XW8%t>RR}6mWD6zRWW=yYlJUG -z_>!~mWebEa>XwSV_p;&302;p3-Yhp3||h?@MWeh -zd^t$Nmn(GP%Rw5x!1G%8GJp+V;CUl_F~XPJgfC?fzFeV(FJsv7r4etwK>gD2#Ye*z -z_zVnRpst25l^DM4)P*lm8opeC;Y%4CzRbk%1?n_>f#=93)HpngD2

<_BQ!mtLsi7`Oev6NF)hKEkjt -zY$+6B7@lA$!Ge!44ESTTdOKnhzgM(jt0C!uHDI2l1nc<#VHib) -z(QV9_Gg;2y-A##Reu?4)KSbR3X`{4F%9)F1byFD{rS09@2wt4lZ_fJ7ITAXo2=TP< -zhoXt~mmifYaD#+lwi3cHdIw7h5`6qw35&I;(SMJG*34Se&>E63EDRg>I`*KAA_zk! -zc3LLdogfT51Qdq#V~3@vgkgAsr34E;wEae-h%gLqcvlHwSQr+DofMTY99kV1o#^B~ -zl2{GN`&Y_ULKqf?g<&Tk5r(<&(Vrq_!$*6=fSdM)*-GfqAG8sc62LJ&2X_<{arR_S -zv=fwu9a<_4!%8eAgkcmdO9>Wyl!n1kjKVNU2^M^mhS~7(?voOUeLH0eeug;4g`i^z -z5}J#r-9|n7g9xc7Fxg75_Lh_@zzNo(hL*5M-Bi15>_rW&Aqm66uyL3vuWyXbp)4ADR+QAZlvI#AdskW+`F&LR|eS -zE>EQe0^mPG`YKn-YKyMkwwj_$Upt;iEJRs|v$xC4^z%k)?z%3IccuuQV8KUe -zm<=CoO2EiU!)zr;@X@9OI|B;C!Z6^#Rzett(kvx}VJLtRio@IBshMbRg3>SqWGSId -z30Re-1Peae8wPYR+GC43-1%W%+?4PuRXj<^Un0KUr`^D~;XhKpIRkPmCA@eWfn$ex -zSfy(Ls4IdtM9rz(VkSSZmQ)S?8oY++GT^&S@02t0UeA` -z9Nvx+t#;lOh8|%d31JvT%ThuZ1|C^T*g~tRC_`~v9*lsJ(~licf(0L?VR()O -zAEjYbHw!*W!$2xVC=PFfB4(o92};8bErnrNiKT=vjG|>JAq<0lEG2|tD1Z@)!`q;U -znP_hU3qDH2xIrxVC=J8uEchr513DO?IK1s4e6%S60fk|<62dTwmZgL+3_P-w5Qd=u -zMko$%gCb_4y$QlF1Y{|}f{)TLoX&!e(lDTd5sG^WK1#!E_-IoCR(%ODTqf{fzmR8$ -zM+ddZockfX5mJTTFTGIjVf1oov%0Aa{Sq14`~}yLi)KCkO)G8X3P6FS1PMOM73dwp -zFk6Y2AXf;(QSXkh8WQV)7hxC;38M)^sB*Jnb#lw2n?Pzv!Z2M3@8la1_{G#C0OuL8U}PQ+GC43-1%YN -z`-yH@rTDRepCT^%Y{|%_Gb4N?>wycZz|avpyHNx%^|0@o+O&L*x6ZFz -zfg8k9Lb(E^z*2$*A6i55UN<%Fb#Q{Eg!OZ9M^QV5Qs@V+PGBiv`$Am(DlSj7rvwW= -zTHe8lEcoch4mh0!A7L2K!3f3SZDH6;N(jTS5=#kT7*=H|Aq)eLEG2|tD1Z@)!`q;U -znP_hU3qDH2xIrxVC=J8uEchr513DO?IK1s4eDvrK1QdqZN(jR!T9y*RF!0DyLKubu -z7@;`44T_kF_9h6!5Rjz=3qDH2a5@V%TT;mOo&lKSd$`znDO9^2Zm}e=$TGR-` -zfDXn8=rI54!Mm)6|kd=VOSUj -z9N0<-!%&)~gfI*RFhX&78$2}=?M+Y`hJY+3SW9uGVK|)yA8kqiIvAn2m*Ar`%!ZHB -zFsv#Jvy~8rfk&1S!Y~xT2*u%T@YGDSH-VJ_g<;$vVVJE13qDH2fDT4`Y%zyBKTJQ- -zIjTb#MjvA-Aq)${77nrCLu*JcJci5Mzfv~jA>y4uE0dvoeKnG(4beMnj;9XWj^5mKf5u*Bn -z&;M7qm0-a~X_yTkrD2#}7-lO$f{z}AXJpg -zN4son_$XJrG`YfDX{aZJVYU*iMU60whJ?}T?I;tjop+5lJU&x|Gq5tCFf0s5Fj^m_ -zVFLwW7}dd2B9iyQ#P{r_hlg8B0+%HWvz5@M1iK-zmg2N^0Si7fB}nkmrUV;4O2cgU -zXm1$NLKtQ%Aq+zSj8Gg^4xXBc_9iF|LqL`iO2e=!O9^2ZHP2Fl1RtegHhh$Z+3-;s -zX2VCD62LD;C=PFfB4(o939RiI+ZW>MS8;iwJtbHfP#A_)Ss73mhSOOYP#6YuFhX&7 -z`$fU4jcDM$7kz -z`rEnwu5ty~$WlVN0$qrugmML-z*52nP)ruVHR0}~<_@h8_B_;G^Xo?8kzSmUk$0 -z7JQV3fnSVJ9Nvx+t#;lOhK1pXu3|MLVHicrQbHI89$8A*LaQ)r9Pe_QV!=mgm<=DL -zVK#h}hJjR!P#oTN88hZgmNO^~JG2yrVI`IltPCg&qoi3GP#6Y&F+y=+*vm?=;G;AQ -zs|v$xC4^x>fu)2n32#;X2XZJ -zE?~ij){ul@D1Z^(L)gOBrkQAO0t-G$!?;1hFk1!$v!(w3qBw+(H+epoKmj~x(&rG%DuASO$RD9DVD#LW%o -zcpEQ0Jlxqw3B$s0ScnLD$$}3pVX+o9G$mN@p(#OvkCu0A_|Vn``g0TL-7F=9VN?f8 -z31JwmpQVJ;*crCybMK|`hI@xQJ4|Vq-H=}FT{iRe!~DsD4^0WBVN^FuiKuK6&N1%4 -z6owrQNf;J}wJG5QB&>$Sf{!qaJBiWiZTA~SC?_y_ex?X#5Qc?eVK_ob@Ye;xFg(Xn -z!r2`ScXQo)DGWOlVC{&~8j?08fO(b@tfjcpFrb6cO?EjyOc-`lhtjapFfbXa1ZycS -z3`1!ad}s~ng~o73-%goA9wNRFbSy!_$Eau1Lu6=k`&gwdL$gc!IZ+1O4(E6qFFicm -z*+(f?fI}=LSc@9kLYD;}ni5*xp}JX0kl>>yFxl|Y6PQ>u3Bzn9Sn#1WB&A_^f~ACM -zOz<9f7q--K?km4?AP&y>)kKM;_mg!YDERhAOMF!0DyLKubu7@;`44T_kF_9n34Lt7Up4dYg` -zlwd8zg<%veMo)`3Qq2p)j_S~+1VTDX2^M^44T+TjX-Wvgz#~fuVHgTvgyNAqivfx` -z#)Y{o_~<7(+@Kd4!vV8n#|(amI8)G(iuG?s3M;(Zs6R!FGS%{qt%Py~S_4Z7)}lta -z0zDj~X)9Pg*lG4r%{AVL@?YJ4SGfW=h^52}ohzbp6$?HzC0L6Zni9e=@W@iaeIQ0z -z5@GK~RWM=y>h?<(e6+lKDVBFpxk?yDYi23If)A}B8AZH6oCuy{Dd9d4BU~Pg5cX~q -zZ-x6;w_ggwO2cRvp-QmeqcjYqS@02t0YZ#W9NrG&shcmoccuszAPft`!f=F=2+KpP -zh9nHbb1WsC-O+G2*S(j*utNd;La>^BKB}|E1GP8SOBHUq76^zFx<^9*adh`bd&=Z(! -zC6p^b0+tda_;@8(z+Dkiw^1a@fA!#9k`mfw!|h`!Aq=AwSW2+qLt7Up4Z{;GC4^xp -zfDwut-i2)@yYrH@wKu^k3)00Kza^31L_m -zwh+@O0`EN!tx(UExx%nRY1UF)d&96QYbj1^NWw5c!cu|-AEjZWV2q{;vGwTLQe0^m -z0xAu&m0-b#){wL}3{S9>FpUY`GraSVbF7AB6!F@XhJqZUmz7W&MxSIUp)`zAU@5_Z -z53M1w;6qb_1Rp&q!G@1ECD`!s!nz=_Z>LPb&k)DB5Ogd-LUYCNM#uur+kM}x3Q48S -z>ZUUEOJL|QcZGkcTL}_;l!ifXVVJFiHYL~%Nf;J}Eseq`0`H;9trP7|uzZf)!*Qdmmn972 -z2C| -zVK|)yAEjYH2O|`Rw>^Z9_J$##Fw9m$7)H^uln{o2N0t)8FciQD#o=vG#7wj|K^TUB -zEG1a*Q5uHRS@2OB26Qk&aWBC~X_yTkZA!qZFD{0g_$7)H{19>9r;XA!+3e)MH1>Y! -zg?bO8mrI+~O=aj8-_TC1#CrUjR@%xHxRWd;NbpgvP_6(b*-E^)xdO#&Q9>AoCs<0b -zo;wtV;c1LkZ@aq-#$MhC{0ZqZ6INC}sC0t0CFG5Q6~&+^D~b%M+tM -z+}XRrurMqPJE;y~SQxfc2NZGQnCK|(Y=ST>3=6|fszVqShAq_rMVvTB7&bhOW?A7( -zDpo_%-Y_uFQiAovlrW5cheU#a3rLjDr*?LO@W#)S+PHnR4XXr(Pf -z<4&@acwr5VZe(reMiGm*BTckBfusbhn`(In11MLpm0-b#){t0xOEe`&@bNrX2*W6@ -z|5%A2YvYUdLR_4{YDmH`oWfE<7)HutDIp9)0gO-_-gZVo7bmdbqcn^g#DWj4A!$b_l3V3HXPl1Pea2 -zhNLtMPq36=!ABTIL&E4`mw*w%76DPb74Bc%e#wH5_J$D%gkiQ4tPCg&13DPp#*8_W -zO@c(KWE)#gLU&u4Wql4OH&ixQFSPRCcpR9))21h!- -z4DC=ryKFEGO9|GZhL*6DE8q#15+wNO2~1#Kxq_{PmUmj-0h6IhuogAKFqFm!#Z8sF -zo_j6#Ec6T*qyAU7-xY?1VPG;;38i7S62dS%$5O(5AV$M!hH)n`TD|QtJcVJ00<0ZTT0_#N1TfE1g0&+m3}q#2^M^44M}Mjp72nKWtHN`3Vw>X?6V~!m(FyC -zKIIBPj-`Z$w-J{Yxrwn#`#B#8TA?r4Ypg6KoO#>k!A7L0uV}#}q#31Jv`WGNvGLjjCX9Nq>+%tU(=SnyFA#tmY@M`;*NXTe8l -z7|_88#o=ua;iCuPA)qkKRzes?(Xx~fhJi4w_4qeU3060y -zDWTt-VLz4RbiN|gfI*|vXl^pp#VlG4sU~}W}>|btPCg&;|2-C -zY$aImQ5ptxFxq2_Io$bS9z7{h=KhtkArBGn3|g5q)m^7gZ?GPCp_R4_4acyQcrgwA -zoPsfm0Hz-Hee+QyC6p_0gIG!^SD+MFO0eKVYe*h-Q$qx>7xJFg6PPAiL?uqxzk2Xe -z7W-B2K1B5IkgkdOv5sJgx&u!#d1Ou?(qcqHhk2WR1EEar(Vc-`d6o2q(ePMGkl>><%!ZHBFdIIeZAvVy6hBt*L&RmD -zEg8A=%yTk=DRF!sIOjRXxHOkk+N^FWL&E^9Zt9t#&E-Y*r*_#O3QGyrqDHv__{I1f -zo4ZG3;|=!?cXpUC3=XlB5QfDCIkNk^l>2F*H -zvW4YR)^mrn(w3qBCk-9WvXNdIMF7*tHji|SOLIvHi?ygxu7ClQE7(d1!(a+a2@-s? -zyhC>ohS^F8!@@8y8L9;9msVjIN@IlLrpm(>eeS*V-kBm?fG{i!1CyajXj6i%gfI-x -zv6P4iIZxRej+n+9-aIMq5AbSJ0&r6rW-Gy3iqjer3qCX@Nbu371Umx?!)*BI(H|rd -zVVJFiFboASLUB|%cxoovo1jez2*^@GX&6>zDIpA_=2=RR;G;CmhL6%P8$L?IZ1`wX -z0{F!U#o=vG#7wk1fwetj`$Am(DlSj7rvxhl3d67}D+79h;f(jMlnr@?cxTYcq^X`h -zuZ(Q^$@PMip&bh7|926lVJV^CoY7=hO0c@AmUqA}M$=Y2PC%h&z-X$_e56MorCfm< -z#8To#%oX^~QKkSEd}vCr_LgW$2*Y3&O9^jd(iDm?>`;J}0fk|}Sr}$3!GaI1AsI!& -zc;uazEG4{jc`!oQ*N)?hdnpV%6kzQw(HfE-{Q>4#O0bsV!Z4tN(M@(aKTH^QREN^A -z(l9U?sst+o3d2yE1s_^N5{97wM(3RcWn?RD3&X;&FzlpeSPe-ShUZvHIJ={^*l5@r -z?lAW#8`YV@os_o}*MAlYxUrVvwCx!dd}vB&QvxN;Qi22@{b!-<3@8i>!+--@2^M^4 -z4T+TjX-WvgPynOV+u*60Xm5fxB_JS6i5D;p|CS+rf{?#N{K&t^mj2Io%=7=%AQmdR -zZbKQ`p@4pKhG|$zXnBY7WGSIs0T8m35Qd=uMko$%gCb_4y$LM%{4eE-=idqzd}s+v -z%R3YmONnS4<94&c -zI8%hV!Y~SvrGzldZb+;QC=3HS7$cy={Hq7=vKo>n*JOwg)fasJzq+ji3qDH2Z1~W& -zXIL4K){ul@ls`)e5`6UN4?6=2!@@A&z*d3IccuuQV8KUem<=CoO2EiU!)zr;@bO?%BBO7o -zOd$^uUkEyuAmL+VDT7NW5?qDaWkVNYDZ%Qdw9+<;MC};&-(@Kg!O-qs9*hunhA7?& -z_pffhRIUJ$SW0Ml$4*$v6)1m}5+wL|kSokXKE_?BJAq)eLEG2|tD1Z@) -z!`q;UnP_i%*VYU*&F!0DyLKubu -z7@;`44W62b_9n10pfHRZ^x|PSV0P@7!4DB<3OZ7;{!Kml<6`aDtSnaxQhx&zQn8d^ -zJ^oEAZB{p>DZzT+g{B0ln`(K7IHFv^R^r9W710!xFbq$yln{oIx>-t)GN3=JAqm66 -zFczYrO0eKVYe-7NSRt{LFpUW-v1s-Ltd??mm@w>+N*ES~Ekz{^!xJneSnv^s(U34& -zz3sFg;Fd=>!R3k3o+-ivVOSUzh9i_j*rtsz99kV1o#+%!GMg`14axgg%2h%b7KVjk -zC-e}8x$x0XbZq$O(I3D~Khd$3VC{$s!@{t2TLX$XY1}p!1H!O@1C(a13xr`|*ixRX -zr8uo2h4I3W+47Z48QGiQt`g1s62%FAh`8_5MroUri{{f=iyB&KD_6i>EG43Gj7=AZ -zGrzlr1|!jptYu^riEg6Z3E?l^>8IO0>A$pYs^uLFpj^RLf(0L1Lt?>)ri3?%6M>j4 -zC4^xpfYDT;v(9C20_(rRp*197SQxhCMHYO7VJMB!c+WfV(Sz{lqQWp+32jQCXjw`K -z!@wg;31JutV1(lEHYj2y+M6H@LqL`iEcnpY1=^H=Cs;~&t9T>TyfEybAM2M^?G3|o -z+LT}`!GaI1A+g{?Q$iSq0vOTw;B5~#J%nKh$WlTWhE-Wg2*ZE^O9>Ku^dLMNK1#!E -z_-Ipt4Iiap;1?qlhqplyGtuq@*1Ev>=wYMY;13DP(vBezj{4iESdd^3hf_LHaBF~NDE$81Z^5M?r -zvf!iT9UDHhbpa~_(i)O5jOu17VFM`k;3f<^I3Wxx4WnU%Dj^KBm0-a~7)C?FX!W+u -zE&(Hi9Tvq~;r`X_m%^|xEDSp-A67#WhT%Du63*^u7*E}NDGWOl&`)%*5=#jde6%US -zhL6%P=!y}Fo3LeX&m{6;QM_de(tNu8PgNRL8n*aH7=|ZUO0Y7ZFbpPQw0c_@hPORb -zf|UVj4M|T*0P`#*SU*e&!zfyeo))jcBs}3>L+TTFuwTeS#G`}SWX^rXT&9!DV|7y* -z+Oyke4tL%fSf%}(kBn?m=a(0Gu6u@#UI}O3_OP4kkFP;MQi25^VHo(u -z7zO!pb5Ta-7?`*{y7*1g+Aq=B6vy@=Lht`mcBJiHQ254Ai+m}e2u*n7lzsJQ5t5$M`;-N#R$dWZBWEav^zm**rBD;Fs#HzRxq4%|EcNXtZf-j<=YyhG_JSNumxu)3*o1?Y#-dPk$9Y_t=EVTS^&2VQ6miM6*x -zQ$ou-c0&?|fk&1S(epG~;6^>cc*A3$M>vDhu+s2*znOV -z8{noi%vOR0AKJQrl>uo=2*XeSBN`vP4W62b_9iF|LqL`i!Z57LQbHI;&9jss!AEJB -z4IiapHhi=<%!ZHBFz|~Jio@HWh?!`20&87h`$Am(DlSj7rvxhl3d67}D+3C{a5^gk -z3d4X7Mko$%3&UPgLKudXSV{=PuqsOlVHkL1De+=q*soOaBq4u^_;#Om1LNYm!)2&v -z(?e+8RECD=tVPZLh@m4}Hk^AMFHMO%w|S&vT$)QNZB{qc@(u=IbyF?xP)V$AN^3~M -zFsg&4gz*Nd&;@k6G*=jQD4+-7(Z*Ry=s|cCElUX&d}s~HC<5=9|M15pb~!(crNnbS -z5;xbquj1k1&OTLX7=4nZgwimImZgN!FshrS1PMNR^oI=}ZA!4=qcqHhkJ2#kixG;$ -z+n|V<}mM_DS{`2VPP1U3{^sV!)zsl -zVR(+EL`29Lh(r6YZT}X;^6(nAE1kf20Hp -zKD35Jf{%MY(JiYKKUVNl#ATl?8M$<(3%p}3YLqKbFfue-2^VbcUc?}kwsM7X#edXI -zg<&Wy46~IGhM@pPC~kP?*+N&lY!Hy8gwimq%2GlY1{7FIkl^F5G^`&xklV>hu;8OK -z%!beZ#x9$+4ovWayuAMkM;Kd>ZyHYF_8!ODQbFqCG&=YIjiW$s_k -zUVibq7-t@SUF789Z|g3s_S3cu*%qu^dF|=R>D4|-J}cMX<(3Zqw2JSCEiY9olDuWh -zRRz}-xRx{1;!=gP^sn`C?sozPG%hdn5=Z))sH_L)6n?FcgtK8MOGdG^zzxR68 -zDa~{4YVqXqoqk7)KJoqf!G@zZ_HX>4_tXB*uK2n1zsIx7aR2v@YuDl8qGyZ{X4@q0G^cgOJz>8?Mh -zSLMle|FYY*e|ElA_eQhRY#etzZ~A}ot*m-}M!T;9a(CWcX-efgJ7+ff^v%WNKArxg -z#D+p2uWoqkcIv_x&J~`UG11)P8B@N$=E0eN%9JR$an70>zwiI7R*vSqTb#eV_SXD; -zyE_Gxdh>Lzvl|!rPg`HOYolL3@Am7zCsUvDJ-+>6olD0rJuMJBV14 -zPERh3=z6hzhLO`>o$8aUdbLrHYCmo@=fHt7JsY=f-Se{(sdsdpdwkEvNu}ydx;uK$ -z_pRO<*lq8rd?(gspHZw_I=|yBd*2?}Y{`j@U5jNn{n;Bo&#T$%!tC*Drfh$`;i7pp -za}{~8dQ6LTpPgQHsL=Ocyiu)g_h+kzl=-Gb&&nMdr90iP>aWKR6)HWp^t0lN??3tc -zP@fECe0}rRjT`!nwv4J#_vn+g2U851KPp}6G1F%y+0nJt@GXZH&1(|wTVF^q=ycZE -zhYCIG((KD?ZCea~Ki%o3!?(mu`0=78r3-x6H)iPFU3$KD-N&cXRIAzT+T{2d -zcUG@C^n8gz70$M<_htwvY1n@FmiRLgo-KNH)%WXfFI+x3=c^rhj>!3H#@*Mi -zzh2LG`i^?Xr#D}B_|G+e?H$lXC3}KqY`77_@5hIyHXh9~uG*ElWgBG9)URxhZ8;Jw7@DcV -zxNK{Vo*X#7dC|c3t!m9}uz6;utLbAVO`0=J!WGOP@D=rhVd@t;FtrJ=Ygnl|8Unk;9*L?D*$L9SU?9 -zR$y0$VatZSvhbB*CyVWx86#1muBmSvY}>3_!7p2E{c>KG7Fh~cu2SunZQEOHFSP5! -zogeM`sCtp2!>Wy}yfVwAX5XG_`%afj>GqU)yd>{W>k9Wg`r`)wdky*U?F+czv{fmdGHRbX{)pDOqAJ^E$N&H`1J->&fC&GZ3ZfAC?^%s#u{ -z>d+-`uchbj>}hfOhu?q6602X?Oi2>NiDDRcd}Hpf7S^A2^PlrAZ)~rcV#2A7Szj$W -zrP!beIifxw_$)J@UY?MnWS5FHi!6K4<>as5PaZlUN8b&Tvc6jQ){&CC2FD%K_Qa2W -z<$N|FL)itFcgO8sd;ZfE-wZ6;xk`g^Q{O+C{$_*EOMkfRmjjuH$^Iv=Pl^*bDa(gdHYFRls?XF78Jf&UTWGD%tCzYp -zJQri&?7n|=e>Y`?dmC~zU7NY!wbFZimJM9ix6$(9<%W;!)qCcjt7cD%9k{9A*h7U< -z+_?AFgk;Uj=UlYnY|8F4pJX`sqdLbXL*ySrz< -z-a6Nc6GNTdhy-yiuF6;RSdIxfdj4_lO!@WYo1DMaaMm}o->lhcSQPgSH*L=h%?*l;8oDT5wh?kfC+9gjZ|LDfJ{4E(Yu@Fxj>X$%yZ%+jqk9i0xHNkDwRDYJCzzXK -z?C};|8a#fZTFq>q;2Oh|A!4b#&~OR_4B(LEoxW1`&j>Rm5Sy3>tu`>en)@G -z{$$#d<7Zn9xH;g)rbN3MJ-s&M`}R3LJryI(j`_FhF^K{x&!lC5dHrOgIs+M1+) -z+cT?s6!+`a?Nre>D{hV1rP#Tu?|&VzuG0SUx2L?b=8v`vFNxeLEq_2K#UU+-Vmy+XsI -zpSNu`zs=}{(~maU-?US)>OYklyK;Bg(qE)Gp8S5g38jaAxxaG3ZQHhH-JWGf*6rD{ -z&B>Of%jGNsV!ij?iQMa|`j>2&w#}5B1vBR@n6*IWwUukN9+Rg?k%IFoSA4%kl@=X; -zSzEbn>yLiSx;b65fq?}R`AzS>Bh7{q@iU%(SgFsw)ECDd+R>`>>UcLkxmNYU&kKg+ -z9lN1cz~x?5dl#GfZK7NO18R`$Ub0T$cV)8~=SOzV*K}0LVZUXn-hNO~pRDOuCa!R@@rDFfc1*kc(WJH;%BNbCJjuiH -zQ&P@Z(Q?L)3w6@_72A|Iex17Cj2qJTn{{>m%9COGw#;c7wm6Vt@BJ%_##D&YyLQW4 -zJxd*WCvVT>x9`kEt`1mMy*x_(mCxw33j(@^xEZV`zGf2Yf-c7{U+w<`)`pvHP;;MS!zXj=Lf~P -zSY~zkA8zj`w>#eb-aUL4b~i?j_3YTWHFdA{c>42ueG{B6vGdP+9}ORIciuk>zpYhk -zfp5&x`y2Himm%=ZgdMxLrWrV+YtrrcN-iHdPD_{!*{a -z{YQVk`rC}((xpy(wccyFKmO{kT%{}2Og}d9owAG9*K8dtTTI`|f5&?|INhawe;s>t -z*Kbm@ooAcIYSMZ3f>9Yql)Zm==*q@p{Hne&^vI0_iJO1)v+tb(@dGXnnDffO^qDJk -zZtF8J{<}B-IeVkYm?D*`bZNEe>-7nmUp)GxWs_02l2sa-Edty&% -zUgUJ;EIr=rv1!Tnni+PstbL{%n{92?bSOon8Y8%!^| -z>FZGm=JdKhX7i+Gqqa5~7rV*jQL~C?NZK#(@i%)aO}a3&e6o4T6FjVt;e5Zp3hXU8 -zu-K+i#kO258&GV~f>FhGbjx%naD3tUUymwZt9te%Hyh@Ob@k!ji?i%q_PBn5!dn(+ -z9sYN>%5jo)f9FE#k2+qhzpHher&Ipj9lKbApL=!R8?(#ang{1sjCU(d%pGU_ZeH3~WNB3QpYLyP-x}5~K788wqfSLycJ}YnZ1(G&Q+`^vs*{+PAWr{| -z$Lk%sUu@gN96i4|J?DdN!(s(|{b#a4X{$Z0P&Gy5?t+-|@iU*QDYk5RefN&Qe_MAx -zaCTU$VX*>6G??}A>wTuT>2fq(hIRKonHzL__4OF%K6~@an=Q5nJo>}0-j?pyM<@OJ -z*}^BWN{`AGZ`YwS)W(glW`F>u!uWR|08}i`p<`j*0 -zr0DU=yiNI*=S+NlrBAMBThdMLpLx#1{1b-dPt`R;s(v{qR8G;ON#E0NCf&Y!>8KI; -zcf7ed>73*h_tanVXixV3;{sX@_#<_qD%(m|${#nNK-~3B<5XzY`D~S}bH{9Z>&qf{ -z3Zz)jDZ~B#aoQ&?zar7LTHm+&w^fs`&!;%_Ps^l%qgFmRy!o{ -zw9gN(qzbJ6PWc~?B`W#pH@<^5bey?r-L|i{q*(G{iXU~ -z(Bk;4fJ!3@R=Tw^#e#v2me(ttaOS=#sYVsb60ghpPjmWI{J2Th1I;rA9Q`{@^UiZ7 -z_gpiw#fVb-{`$RHmoJZ&Y~i$u`ToecEE` -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 -zvi3`V`udqvbzVLB?(KQsTF~ -znAmJdjvsn0Su=Cls3vi*Eu8(~wpim^pRLpT{6Fum>EV-m`Nv~&W5>v8rMo+a9;88Xh#>@&96E+L -zpYi*??>^_Z&u{NPso{Q}`(Eq5)^%NLNkruj#jT-+z-#R8$b?(WM;+~yo*i71VUx4^ -zKaGu$!r9}R63m97roGU-9*8vR;fA5YGA2y+B|0RHusgidCb*`4gPw90xjpol+oxYX -zYE(YxZU-Ot#EYya@oPQH5f9Hdp`$LpY%y_I@O|W1xg9F*+qNSvP^P^j=c{b-T_JO? -zuHt(N**T?LroLB~jhRxn+PS4-mRQnx0_K}}+{Tw467WVz;-^8mkR}IR5v-S%9@bwz -z3k(YoEm&IkTOs34$dNaP4KceboHc!#iWs!~R;l{Dl -zBj!K5-`(DlJ=k=-dUL&NM15e?krgj^9Y+iWE-5b62`-+nQY&;{S2xSsF3@yzqs_0q -zRuvoJt}4I_G_*N!Qar7`DR>2$GltTJXqPM}YMZv8wPSGEoJqS^YZw*-;(+W1+y~R|NweQZ#Q=_h<(;@sgK3_oB#Hu*qxS?nxCu_;-%tEV -zxBP7iiwd^KCsLBk8110yA5sf?_SBydXEw2eN?gH(Z+y!v?uG7n#txd7n(JjZCsN{0R2;+MR&Th*ARgsz4RPaYV{&ElMQPO67?pYDta(391Un#Jv%`93v69G=!C -z`pfh?8#1i4RA|55_W$Bq`2l*!r5I5PSbGBTcQh;j?0syVt;PfeCOI{23xoQ(8q+7j -zZ`EX*qwzx=xc$e;`qrsh?-0or2x(_R{o0$j)%Z1mdJ<||9r?B)11Y4#DsAKo^w -z!Z&3FsNfxa=8j9dXw*SsGWHzk&9e_S|SOO?r8v8^N%O -zgSq&C9GH^^aO|XfKpQhmH$I|Yfxa}*BGg%4x-B79H0(#W8Q}U!Bo*QHYSU*tqrCkF -zzTdQeX&n7dQdg|`%0TT|uGe29<3A3FG4Ps%4;ZMk(8EodK0jtok*8rW^?`A^Sm0os -zxETA4#Ic98RuRdKulJc#urxRzOFid^j|2D_9Tsvg_}PQ+LH#$|30ew2q>(&lmH3T_ -zFwVaVx&Nk|XgLMpPq?by5QkMkZnFmeT@U^S;}kLB{`X)1cWKD_*v5n#*G!!fcMx!i -z6)L1Dr%KvmK1LiCeQp1hVB6r{UMolypKgGLx^*h{X>3@iGat+FqoP#qK -zu5rY(zRAp~L(<8PO=qcdkJ0>Xyzg~;q?3M)C)nASGv%{^flK%5;IbB!Et1;(UyPSCD-ywUMuA)@6X)?<% -zq=+7qgv|u0JT@@@_9dgNZkdCNtYf|4;N0%#sgg#R5w6eRV-|2^4z2IRj2aWQH -zXHmf(@A->S#fsZaSO9S9N%N|u-Rtgzzyy&YRe*3AMP;Jh?C3{bJ;<>f-3v&uK`$ec -zHH-rG)C?KZMuHq0DAUmn(hE8P*cIgRo(Ha9vD}VEz#3{Zvh-!&NwBZSi9%NH=XSGs -zA%LiYasalNWb~eo9D4mgyS}WO9R0MaI9g!ht`D75JouV*2SseBlpCuL8kH})leHDX -zC{)#qo%~CQQ2@!S&C!36ch@}V1ynG_XSmT-cCnXlF%ds! -z9y)4ZhdiCJBUV;FpktE!r-DPZU-X{QJ}SYl9($~xuW%MsXB2vBt}t?{|J=uJRWQS$ -z)I_Xix-z;ZR`nu+yg$80X9UKVTeEzwB-Qc6fEa!uMavKnIjXg!g;=7m%ED*%+AT$@f1*bxXjiTG6|1 -zxxA$-(AO;{Tnn(eDyb8H6Bd{Df8OhVNTGkf`ZqU|T-ruwq?(7W?>B?p|NX|^BtK)= -zHz>J;x4=hv)C)B!qNRM3S*3)RiA0uME*cj6r2VU(9VJ52Ug!+6;(CIJ-O+=FRaF<-B3q_V(rW*(zpk*baojOQs#MdSjU0#1A)I8MAI~-1X -zg}2BXXa11@ULh!KR982da|h0_#;-+-cyld7ftT8+#;oG^4}lS0^nX{OwpLw!IE2nP -zz9R7WQ1l08mFSeDB$6%NTNB*%wtiAm%FTy!hm{aeUPI*Clc=r<&)6U5Wewl;p|~$+ -zK7=4?SW8jMVBr3)4+X&j@C0?omP=R$HG(%H>?9w1%W;3=NBX9Glnl=^I3lU*`%90; -zgXN@H;U3yg_+lw@THj4wu@@!))Ax#%c$Z1Gp)dwnpXUeE5AUSLP9oQ}nkrQEr;-dq -z-simWeUI(z`P1M$x*y4^&J`N$#uawz6m&>#Y=M0cI>PvY8S^~++ -zW&Og>gR|(vYILm6A;@;q>GF^h2x?XJ=`*}`#H>SUziovZm -z4S%}&5w+5W&B@e2F{A9u=1g$lBMb5wn+J6Czq9ll;bzYuiIgWF?EZlDV+8fQ7FEwbcx$U@M&gw;1lPkt -z#mC}WAa3H?W~cJ3+?mTeiQG4X2I1cJ_Rh!64iGeRxmos;9BPd;>I@4id+|T=asO!CRg)$V -zhil5=h+HepMRx}WKxT60hv=9n)mY_t)mU{kC3U5}31v(S7uLP9!fyk%>;gTuBiL!W -z5s-;a>$rnZdqRJ;^%ny7Tre7;x2sjXRr-h?r!{k{@oCK5AD?!OY>t&L1FvDPpKfWf -z5FUKQA{-G@JaM#-dhPH0g_))^6sN{>;A!vL(kCxn0;y0$l?8zSsiXGWXVM#<@SJsb -z%;|AG@Cz~6_k+NY1c!|GH6NeHwDwfr#u4T|pIzpOqmS`P94D=gtGPWr%PLgO%=Y$l4AbzRA-@74I@%AW)pt9e8BBU%#X#{$7iJJ)-8r#i{$L-USrx%_LNgv(4!;;?4#F~+>R-=)xgmGGau$g -z%a%)OXXjH(AZ|oQc55^hm)bM7=jPEr)!?mM7g7Oa#;RUqgXG!rZ1OgV#o-&T_wU#7 -z#r@Bhep`0MkzQ!k1cVCR5C9RLzOO%GS`a9x2hI_r-6^6UC*!jQ34asnrSyLB@lz(j -zV%|;Z@_br`1!d#?i-S2@jgqs;gnmGf5&-k0M}q&>(9y#$z0dt+F?g1}dSMx{+ -zuIJK6wnP#e|DYnl-m8%l;gwE?%`rW_M_OH9aZN6j{m?c)B~we$lVI3pS!YwD!=<0~ -z%G(}u+$OSXDGJ_$t}@nKVrW-4pozpjml(R&Tqg=$_nzc8C$F39?|+50$g7xSN-kgW -zIsev1ed|QcA2en+mdfPHv_F6rc&xGIS$7HXn{zb_rdhy9>7Rb2zR|UnI#Dii(!Noc+0UAd*NY(br)bE#S<^9(}ylqk2 -z_CHxu59fm|I(3&K$_Nb_M|g)fCTL_*5@zV`td6XHLUJK8Be4pV7_8;iFiP<+I`OGA -zyvo3+U$jVZJr(;GOoU_7B3_?Z5lw_}p7{CPi8s;k0=Ol*ml3SWc!floWzMJ4<}aq4 -zVs^@}ioX`*1F*#yNatLCXNrF@NDOKoV3cJ_QV|UahLzBNVHlc|cm*kOCUdu4{8m;P -zU-aQrI*`)onj$&4i!lQ84m$BGWF>pGm~Y3H!&UA_NG-?bd{GU;kh|`-8x^(JZ|Loi -z!ucU-NaJInA!dbfWxj0bp5sN%?&gm-nL(+&0LTYBa(T+Tswx%z*(S}n4`*6| -zqI}lW#ZSbFr#pUz0>MlEH%b>o3Fdu(`w#YM5~&NuChxhN9G_PP_-UfIPu`r6a-QZe -z>bzmmf>#Jc@Vxocb(8G;3TqLqx+>amwn?*V2mVT@eKs?U&2Jp1vsncX?QSRf6|*0v -z`W)av1Ujg^@z5W9p{OWN!6Exh(>l65BPJ(GHIrd;t4fXemflzuwEnsvoQlLCzZeObEG9W`&F_`Z56)281A+} -z%}f{|lwfGHHVHHsq=zZf<83$Ti)*;3=1eXa;Q4p>G8UtV6-S<%nLOv5H#o6O)j2Pd -zW}+A~*Q}c~)2K1Y2_No_KXdO@Vk1>o(zE1|Is?SXTvy+{%57Os_T|WG#R#RDWG;I$(m -zG(j(iGP+4f397}-Q{ArBP2ZSyY1)Kg4@_+2_-z{soFT3baGjgYMl#l{nD-SC--CEY -zLepFhSFQKkkkl3M$dbkpZZd9uXu*A2V1SWs-83*wiw7BfuCWH+DJrElC4S=h=ve59xcE%(6i*&WTo?X-0Oh0lozRs -z1AKUJ?I&WA>{?DekJGH+BE#h~G6**up@pCCqAk*|;h@=c8;*}Lt8LK=|pMV|dzf?jwK$h{2#EPE) -z*kVkib9F0jw8QZk6R*@zFOvXx@cqUttoq#<-PBi#CEJ7Q&(f=+_k@knPshr_70a+g%B>rfNESPbWSqns<3Ih#}~uI{cWA1 -zBMHmxB9-jQnz+_F$rf4NKdR6UZ{%K@@G3s04x(Fm!=s+Ktk9u;BVR6g&Ag=5C*59awy%FKViFKuwuI+79E(0)n0WT79=1P+0sPs7e{&bwR0Sc3(Va% -zYvz6po5wF29qnJ2lc(XzC9~|DvtRR3bA6jX)iD?hJZIpW*4;#hC%i3qG1jyS990V1YY7)5wDLBcMOf0$JYl;mG=pSRfZVr -z<)#Fb>Rb)m58`$|doO5aw*gg?87| -zKYyxMesK&x@!9W82y -zXQHn^zP!sAVQ`~mYjq?^)Ckz^c$%@CD@SxlZO1BCPUFm~Qzu=78`PHut3)XBC!MCaQs5v%aSf^y8;s5c3yAgEj1CB2 -zewlh6?y9}t4DzBT!deW-d92y+D*@;J$ySb;q0BVAq{*b7yLaV{KdU6X4{^*L*$80m -zR1g!4U^ihHIlhh^znQw+!Joj`4f6HK@f|NXTcnWcKeHm&#-PYe^DvQ@D79aJ58V&U -zVI(jYpy7LoYlZbP9Odwsk5Xse_kNCV%?qX>(Az$0BXWE^dt2T02lhdrPH?eKFy$o5 -za}r^S2*Hw)3UBI-Z&Ka24Fx7#wOv*Rg-ao2>!v(Y<8$8c;wH9fIcKMgl@ca1)%gW@ -zfl}Cqpq5x*L{o2kgxu8RAB;&o`L;{ZYBPINS%P^?u_N6Jq^>@(f4vtiZ+{eo=I-%T -z`1ab&>?JfU--%aVuF?G%D#p7^8Z}-`LUc`I#*&l%c;h5yN^JpYda@l&Pj!5L=vUq4 -zWYbH9RCo#q8K7&OIrapUX5K9SU=H)PS}og%60Y1&P2|-Coo>C6%`l$EG|t6y%=tAQ -zJJ}ne*3OvIRcbj7;nq_WYtxB10+ -zArey=%mRdPYQrA1KYz;KK>%Bf@f0Fo#@_hLpa8&xA^swTYSwC}@^5}{e_J;^VUT>O -z)iM`Ol#X`bQ)zB&BSY7)ILqQddOx5jJ{6V|rC&Epk`%c{Lwh$LG*IITc|7_SS>tNK -z6K7~uHM91U`|07ts0rr~G)-z|0`>Rm&mNu=>*|2_yVRpdNe50HJ}@_EMmrKJxdWws -z>*-HzA4)?2w*PG#3KNq7X&xBb*IkMw38tI`KE7-Oy3EB5L4%Z_eh9okb;%8=c9U3U -zo#0~V7r|Iebt{?4j^@w+g8SrSnrwbNk^>(XKOw3tg=kBX<)~;Km`UO&2K&;C=C!ow -zZCCmSBik~@LM606Mr(q-Ri`E5^W}BnV5BonekyJN_nn#KHdf(-P0pNAX$+&DrYIea -zTn!*|TS|*k5QF1I4{8$h472zpWvzYAa19&PMgOWA;^$}S -zP$pPg2;y#>Vt`Ur%~&e(is>-(8vc+sCL$5X>Qy`1kGRdedAannGu!)POW6dxyZjg~ -zskVJEEUZy0gYb2H&=%=j%@~Jn1PGiA)6|mU9mfRvc{X5PMV?5BH?|CzBBmq__!@b7 -z6XrcIFBj^I@@dDEGj9f6mU=Y3~&g_iCOntJfi4}5$w*#+uf -zHQqxfMRu9ax2FPIV{+jaKH(1=wC*pF>`Ol%z8vke8VkX1|E#u&o>28h;>5ct7l -zz}a)pfhGi*MgDG-N?x|};RW|RrWoy_wDWs92Zj;y&zC(MkbSGerzVXO1#d*5>kGCV -zKuj2$r;QL2Ht@bR#{|x{lg`2FQX%f!yMG9*xg!Py6j*5C%eATAl&Q|Zs6GHSWBiC@ -z!s^+zvrx}TH1@motAyDeMnlFVcF~Yv;Hcx>_mu_E48OltPdou`3eBt0D#?1-P?I&- -zTk7xXvPGfmSBX>AEr&k{EAJBv@wRO&$p)4g9n82ekW0x@eaQ3EsO>3C+%JFwjyz6!VBa(0p>bobVc -zk&AyRrk*q(WVC=Vt|G~LFJPodLT=_mYy#%u$#n4RZvJ0S4}n+59pv`As!+c)O!zW$ -zBY1DN4r6|e*-lmj_1n!Qo@i-{m|P1WqmebZkkZ0iT-BNl -z`SqU27JQ5dh?3`4rJwUa#Q?|F_%Ov)+@|fIgwPP^S;8YrddUNrPD69JTdR6aBi+ML03An2rFbK7PgbqTH$Kl?-&dUFmfaPCH3!Ef| -z>T_i6#WmRk&|Kg6P(TA)rf6Zz4$qOts;3tP^RcylUZ_*MDfZy*^*m;WcuvwhFe2(= -z;kQ!_*Yi@j?Cy=w*)(7`(0$%JN$%Mxoq&P%>KeK02SHz7)M6iCK6dw-aLDgm=j#w9 -zf+fO|Kb$J`asHU4;#%=|E+UQ*U>Jz+l| -zAI*m)KzyC6l;7N~+1|wib6{pc3y-mp7zd|Xb^YF(M7>uqkYVl6?`O{|5ctpg^(S5) -zc!odc)D@F21;A+*c@^;*RX}0ldYx?qpLn-}d}}E{hoOVQu-?rJ3C!+d_2(DCfp;`u -z#wM|rt?G9kwY~8X>aSATfMdDRzJnTdj3;AV{jLm8#ApR2=mZ*F8taR6`iJj67%M)b_>Xh -z{9Xo;D$Df=XX4Yho6t`;+SJZ1R99y)p;i}%?`B<=GmyI>1Q>XY|(KevmeB2$;T6dVVk -z76j)%w_O?ob_h%na|XaJq#2_r@2<0tr%213xskjY(IGW&&TN-3GmQzBmFWN?BIAq@ -zUkdTwlY=JpgWhyT*gwAVQXoe@$suy(=Ac%u<2;UA%fImfV+q8@-S(A1m@KTC)m?T< -zgydd^6&waZ`xV35xca3a0I9XUyr3(0 -z0A2mChAo0tDhjq=L#s<-A4+2{OF5}NMg}E#aB%+IWb;Vs<3tZ|d<>m> -z__9rwGWk;%Gh*i4A|{5MQA&0H6MK(my;YW!w?Srlpm0rGEAOXiCzF1-LR_@6{uO;?pvfWfu|*iN;``OGNWmYu_ysfYgo= -zDKpE_CJ(Wdn=I%07OHma)coXs%xxmgTX?~y758YYrrxQuA;!sPo)mRLnR=?#drUyI -z7Ybo_=tZ)6bqiAL80E8}{(4aHJk>W;Nl(ORQ~L-}5>&Rjz`8n$Meg{~F#Mp49&3dG -zR4-pWzk~1BO&SLp&JhwCHhOP=dh5N_*si>LI>~qE_wB@85C7QxGqABh$LO?CKSe58 -zu}GK~rcRUjG4c@{tCbu>oyUxz$s005U<<5ye=b*c@sZe?wP(;zPBV>|>(&!7+NK{@({8qi1p@cOg|wl-zi2)$R#*Lwt}!>= -zW769Qf%Ok_r!U;sH11q&7WX%>Vx2X!6C%6!K)&yhXUNM8$=ey*g3mX<{Xtq-j#2NU -z6+R`p9+2%*(tkMy~_R%7EXt>sTt=Q$X~AkL`C}UjdzY8JSg;*fDPcSlerj|wwj}nB -z1RB4~dSCR&jBF7 -zZb)b6{T6LTOrD$$@YrhjZYNTjIl>0rI$nerBAvTE`{5zw1t1|(x;UY{qD=-MLhExA -zN`-wbpR*ofdM$DPYzGC@Q~34(`n@z>gvE!hB!gxI!YIOmDh1a=`zzwdS^gAAE1x5V -z$cYeo#p&olRO!EvKg9nSWK3gBT0k-sA6R_pEOpmxgOQgJGXni}aLqm@WP`<*E^$=I -zsh6>zDTxiqbABLFDpS9I=mlgl#lLr>JIJUijeoCkB0aAGKE+0M|M;r15W?-fqp@DQ -zE`>v0DR$@%-c^2E6(gPF1)>w*j#EonCEe+Ul+YpBj27%)Ki)SprCVQ>S=FQ0gVOUw -z=S8`=U6Q-2KP&gpvT}WY_6ju!R+}H$o^L_W00}gC(?@2?Yq@``+PLryEa? -znJnW2i6I`j4GQO6Jtq=G!?3L&^#R6XWkx&@jWeNH>MkPv -za#CyxSqj?AQnIMFT@f!#w9u;bKrIMTSgXaM-B(Q25_`k*uK#d`*UbVzTTPJd0MH23 -zT^NAemc!@J4IGXMYscEH5b<-q=Kdcg6WaGbno6J~Ey&AEa-1Al8_eeVOWNfOzQ%DE -zXL3C_lgj-}^)25?Q1)w}|=1kVz%F7`Y=m)JT-%WMJ%g?Gw -z5UOMEQ|$s+<}pFvbDyLsE=wWOjGn^vZ;k)Lt!+=M^6?HjC0ikTSf#|gIh$S0!Zaq> -zS_ae?A^X@1g)lm@P7=rHbgCjAcA%ae{zjC@C!R#+;8<|m<%_Rw;D5lsHz5PzanT#w -z5_7X=YI~krF_(pQap*(vl#|&d9>csOot-Qt4@&g4qPU~K1q2((t2_-JDLCwS?1zvm -zE^Fq*iL|Q%@B&J{Tw728Y@(#AkIMCNlgE;j=#d$xpZ?1yq8H)T@%_XQRY_eX?uQ0v -zm(D97?Jy8Vdsx^;@le6!Ym7{X^^e;jcfPd~$LS0Rm=&|y;`mMeTs;qWeCReY{LI~#w_=e@yCQmJdOs)q}2d}G2;~jZo -zg4`1C7O2!_F5T7-qCV2CUu9qy&I-MZ;Dy)|LqtUgy*jk?AldX^u13{vFp>{CP3u*e -zuUB2eur^of_o>I8Tn77cI#_W(1>|=3q5XmDIIuGN-m0v>5G@S}hIMk>QF-klY6Q$! -zYPakuQckep=~I&ao>@C&{s$`SZS$wLh>q%06`yUNF70%*gHw71yW8ko*7bB({j9n! -zddazGDAkzeou!zlfid!QmfrZL5h7%&fP`BB-gGDmM3?@HfwT8DMRHb>(z$5zI(a`Q -z;jq{?xt(a31wndguR~QyX*})aX--{92Y(+UZ4{#cvUhaS{FVJ|%liY`u{v`Xim9nF -zSf#eVYlFh83U_04D4py6veB=4MjaCtE%+!l?nyJO-DJ(KtnHCcEJxteH^9p7Thf81 -zg~E5vvn!9GGW-n+egWKYF}g+;^`m+f_eUEqad)%^Hem*r&ms1crn9=bZ59wdp{u>s -z$8SJyw1sX6?|ncep4a#>(1`N*iZf5be?gW@pv7Mq3F(|$rnm(}%JGr;QsC1!v@DM@ -z1D8nehxdm&MH!-49i6WfGJ@D@z6JHt_<)B{Q=3UZy_M5hco-Q(<}AwfvEueA-%Fix -zqe?*@)F6Cae`f8JE)i`s$8UszUq<{>U<9h4XjIpB`RtJiZg=tNhq!o(2cs~NoMhpd -znxJ{?Qb{YGR%M#b$J{4&N|*;e^Vs2=KJ%>8V*5oCR07y|Cz!64Zewqd8BW|jW!!=C -z)gtiR`O6*f=N!ftt(NR84NZQ;&ATo!KSG1q^04V>q74er-#r;NZ#HZyT=aA+g2;kS;tep42x_}H7qim -zgCQ -z^sm12)AqEaQpK-37mq$Zy|BS~DFjao`xQ}d0F(IkP4ehI=~@u)mE@3PNbW4@3TXI+ -zHy&O~f8U2cS=IR&BAkr>9@{~lvus3Pq!wuvb_QNrFuPZt9U%5knn6uYDIa>7S9jhU -zKgp9Bptzw=U_Zv%?_Dsy>O9WvB?LGUKaRDUcDkcyqyqZ7<($N4ge^JO4a~jn#GuLc -zKC-Rj8Wvj`{@|z|f+l03>az09hQ(mP)IslE$~J2D;}N+@W$-H1?wl6J<QMl^g5%eEiYolYcIxSZH7ZAorZF*_)iNKj)v=DcQ`Ab -z3$F4Kh5E{Vwm6)zxbjiuvBe%MIIVS^3?2<#WUChRUl*-ciOP1LvA8m%eFFAhKX*_K -zorK(Ob%$^mjk>ITdVPoxdcORrdUsEZBMYWrHhRiS~Ejn!>A7H*00)f>vPW%zTKKa -z#^;|3?u!i}7V0qRFSVc&@9D5Qbqrdy&76w&cz555179(CSE9)V$i4GcV@A-4KD79+8ox -zqq8~wW2cn@|F{F}sODPiP$443B`UhGJ!Yl)B*W)+ktV=>+(6R-l|jv6Z{*}%d&b)p -zO1qP?SliO+k0J0b%^}JHrWSaaUytI^f6&vrHq92dajCg(+q9pqH7|zzrPzX-KI~SyTi7oK;rC} -zk?~PONke@c{?I7Up1=nwZceuKR%nzc_6`>)Xc?tEbZx*d>Wa$NuM-gyYX>hq&vu-Q -zY=)XS89v&2H;XJl2eQ*fGqT2?laF)L5E2hKTfQ8(*++k<(sBLRjr{|0X7>S%_wxBe -zkmk8@SJL}|@KZLX71m;0cR{5Vr8mz_tmk0O%^osUXg$jvf -z80EtY?*C}`MD-Odx5(wW+ypD1bO5Nkad7_^&w0dGRy9?8L -z+Ve)nkutm#}g%Z -zeFWWT9hymuc0uRouJwFV?Jd-kh7G-h0+W&aJ>0t$zTcMCgJk`uoi%l{($L%-*AF1k -zci@-)ud_%E1`(@1A9twy${ZhQ4XFLXH?^C*o$+S;@<`3T6 -zO!D@bWROxPwVNS*dno^Zbp?NN6Eg(GfiifsUx9h^QO)yFE|(kSHWY|wSpVlSCg4`N -zyy;rP_gEmF>#e0H|8^6K&FQDos)|hG6vQ*nSYsoQz_N -zwhd<`^)r+aoxCH8YqeaOeBs62wdWDcRG(k?V|gh_>eNg8jA10@3PG9Ev^f)}ZhBZ1 -z7>%6m;oe<}{6>=RVR@W;2>c!Y>k+Ngg@EpfQfV%uz!xeA$i*t@wKXAbMbR!G=i9r- -z3^%V-y(ViN5p}$^hinml7O#Nhsi{ce9{l5{QyOd`_{c#Dh07P%Qb?(DQvzZs~?q9w=^jV5L@8Ld%6O4WMaGd?~>MO63;q%bNwmy}YQ7n6W-7 -zA%h#tF4>0!A -zpU%h;Z@b?IaPaJ?k}?Y;xcdLyZ==M{{J+d!FwKXreI?ws -zzLW$hE)e}YEP91tDmlxp74o*I#xj}p)wbNt*UtN%RGO&sFtC&Vd%O~d+x83&hA>TbZuL7oDP6yuX4`Ad)=}QKQv8hwj65JNBSCX -z5jOe?;SG`)?NSV!4uJ83?#s1ziinc1_l5OWirVkq{KohZLw7no2Ic^@yvWt!(7DFK -z0hQ(r1J$#1e}aC8-hC+45wKVmIM}w#HB9hz!`Ly~iV%9!X_b;VBCuo2K8wBv|Jj)% -zXixzH6WM(-t1clb@s&7ipW*`Sl~rj-^fnW2o&N01=>uKh$B{m~=`%N#_z_j9hqvej -zvoqJ+uHOapbs{ui8Gfj1pZPj-!rNh>kx2et?uDO8e4RND>1UI~r6mxLJ)CBY1M&X- -zvYU{GGy1TgFST3u+ILMX+5C>Rj>AiY!VIa;`E+x8J1x?DM_8A1I&bPnoL}7n`5-KhJgW)SqSlJuZx2ORxp*=+xNOI!rGB9CWiz -zS{)xib3U;D2TT1H&HC3sFa(Z`M)>lU$Nv{iDMWO{7&gZVjO!7bMJ(@W#JX-@X!2nQ -zOC+8A*>I-T&0_mI5Y7OEtu7vL5Z~SQp@Ky)gos(tbKB>&nL5`|Y~!__0{^USll1jY -z)`~+W5fhmzpE1{;KH5Raw^(V`-*v1V09mZSZ){e4QAu*ar()0Hcx!D-)M&> -zqpR*fqK3^X;KG75hl^qIY-b1XV2#O)CdRCqmSOU|@!s$NBi4SubDqN8-_ty^yoT0v -z6kRc3o%4-6X_ZA+4_d(8hO)CIQLT02Ewaxu_^G(};;%oT%r{51@geRJOhf!l#f$^# -z$s~ME#z(br;WUw)tm -z=EF~ZZv_2U4~;j)|Jp+%3}n(<8d$3d6xeI~&s-th%(bFd*^nxg7dy^>o_xMlkSP@s -z8LFvH<9_3mhR-S#)-JYwre{?uq&)x7?>R#8_omBbG@g0*{U=Rklt$WKcndYx3rj4X -z7db%k<|96ziOuDjt;-~zFb@PJF|8ma1y_kkL}VraiEZS=3bmZe6I6J{Bl}Y=C&>BxZ|?p*QWSuN-AHZBIP!)G&|<1Rn>#w3Pj>F&ovm?U;(ZZjta -z3&BzLAC)K6Ce(OMoQ-cY@i-ZcOuX_m!7Bf+v>t?}M54H9JM%5nwZO{Ok@A1o^FyG? -zJa-(Awoi+n6yJZa&J65-$2uD=M|mUom)-dx_7DFas>5m=9%Yh<4M75%+lyTv`YeQ| -z#E$yspE&Q!w7j4B=TP>!+xTCO4XOR@oTBwtZ{s_s$B`-LdA4CJ5eVeKF`L+P -zjau@nzan5>t$R)nLOpyUXF#O*p?PsmI3rqkB=%4kI=5wB6J#gfLCRponqd8~3znzA -z@cvRe>iW#OnfsvY5p-`wcc@HGid86qbDEq{LIq+fDjdj69(S!QW2`mgZ2Z=zVl0@# -zLUiK`iy&ez`v@t7@4eLv;j~LAn=BoSxp#wL^G`p1Hv;^r^lTGn?ttu^(hm2zR7Z=J -zwXOLtM#{ABm1r>IKfNgS_4P42U=|kCRDl$uN(z!i_}S(U@cEg>_}1Gw{SKY##%)Qso>l( -z%*-~;ckA)CfB-Y3!H{vRyRNZ=nut%p=Ri)`7)= -z&$9!wN8&wi7Fw$MR|hi@WpM)I14&{`1DV!b>Pb4u4s~_kc-3DMzt(-7oII{>rE9Ij -zg|kCpUA;62jrluc5f4jpXb?W>S0yyU!a{O&JX563@kKql#aL%6v+%R^Gb)weOIcQ8`hC0Wa8(ukvtl(AYN@A~PAbk`u5}nR -zvl_k_b7`OIW)2g;#xzcGrg&SRe`tnfG^^l0CGVUMSa&`ZjeblL3-o5Qw>PsU~ -zeqlff(zr|x#Q`$r_CuGE13uoA?TjSsKusD7M6Dcatq<#w%>0yXb#{)#T5waZxx&ba -z*9!(UKKLXL&S6TOwzKtN+UMqW$M#;Z;B|m#MoCu;KJbxz=UQ*`_q#7MYd4MT@~f4z -z6twfd*GdBa=C^FmK2)%iwNI*e;ACcnOKNb}Gf{xnQU4mByl?T;!)1Kh@eq`c$+2T% -z0|jg*Bi4BIxz`AkR*1Js+Mp#?tOa9f7A?`#fVE8gnnKZ&(A3odoa75_v|z#c=EGXL(@KOKQvbv -zs>RLJe3di9<8oMU)_wRdf9I^ob(2qsJ&U2w4)7oO0kRmOI2f2f1kII9JK>(EWw2}c -zx#SE-XxU#F-<`n&x+Pr+D -zm1l;SDIPTf{f=R>-(A1TnG&3|_u-ij)SL-_-FSkLKk-NgwUbp03U7M++DMLE&0zOH -zQ`*F}JI&u0N^AM!;%ug^5`Z*C8$~6`6y&8lqUdtS& -zppk?ZSwlz%=nv5=EqLY+^QsL~;N?|l1}Ja96`MxLRw`~bQ$+ZI9<}Yxp=~ey7kSjL -z+KFB)FlNoEba&1D#or!(%P(lWgLAri5F6lj2%uc3fQ;GKfF5Ta2mNmC0}r)_*T~nl -zXpuECKwe)*H8qTfH5N%&WTW0I5tkgcfu*II+m##=@yZJ(4vV4C9gl!R=jaMR(M~;`;fVHLlGpOI_yUgwH*=w@TDO+3U;zQBE<)K-*d%Vb@Up3(3%ll -z8qbmMl3qA3*H{{r_~?WvJ$)G{7pJ4nnbl)&OiI|M;--HWg -zLFnn4Bw{^H@anf;7vACQ1;Vhh=P4-7qeh_@C*lY@S=F@3pVG)5Pq -z_B$-cF~H0S>Y!}%hg|tJk(u1woL&a;Oybgf06)@JXy#Yd`AU*n>zlMU9&ilX5n1bF?4$BKq!F>cmF> -zw7kX&=4?j`SRuvax*_#>us25mn8@ol{n?94HJhR3rq^-O4Q&eXb`kgM_!uhVBVVv4 -zq|#CUHgo*-`}JAcF=Ss8&=MA}ySNkcVR#F8H`N4~SwZ7NwfUbF#xb7hu=QqK!2KJ? -zu<`r8WiI7l3uk%$;=8XUh|FAmz)192`JXKVbTsVi7{kgpzUpXe*;P)M#2sEG&IE$t -zE-qH#F3H*EkW25zpN2ZBRm+)e3eGu?+l^Zx{CR!UQyb)-o0MI?hkCsU_s;xUL8tpK -z9t}&iaBc}VQ`Rn(l=Bm~)Cv0f*#zEU{^dkZHpeZ1**(E2u1l9^y40VRvG8B=+Zx#a -zdEN{0)w{6Hc-eXEYdl$ZW32sAbsq>i9~kS@CO`0j`A3raX742x$=sS_kAzB6G{iU0 -zyU?W!-@j#BDJX02mA}*Tj?%k6ID5~7ZJBC%G0Bwu<(`MeMo*ou?c8J)-2bsFd%;)< -zM;-D_TJ=pbW5$UteH>057Gg5*+0PA}Mx=yaBP+q9BZKElgP8W9W-STS-fQREg4MWT -z&`Td^T#SOi>U@0u8@(07@&c~wHL`^En|%X#Ci%`bVeB#Mwl$quxRV5ue2JT|XPkAJ -zZx($#_xfg~_EengAG;wKVZ*u~&|}B(pRlA8_)pQQs6el4m5*fZLziI&Wj|t;i6foq -zC4+phq8VD+d!fqlm}&jlPNUqZPfh8A6QA6EHAhe%-?$|kRxFmGTs4z7s@^i1)O+UO -zb=D;F5~#jLDS)SG@3!%2akH8ckwa<=r{I&FY}3qZz%owHk;+wU@hB_NhzAaqTi$4y -ztPe6=!pos~nlZR##+D|lkTp2}w6v&Ubad=?*axiI6nMKjeSeZ8WWZh9Zf0uE|Bfq^ -zSliyVwN=xVJx-gZBzdYi>IB8w25aRd4o4l{QWx_nuS3Ns)qry4psIe)_x2igZubT1 -zO5g}CZm^2MkYfKwpkSQC(BMtohpP;sh5`cK)iykUo^IScj2_ct4)_)%I|aRu4#rs? -zwJz!2o`Kc95GZ*oaOblZP5%s@9ox5}x9%HUR%A$g+G<~A5L!i_#D)gDxgLZqzG%U< -zp<+iye^X_Ki5jMBF*2)04Vd>N{)IlM7|Ah&8uJeX(AXzWYRc=&tE|3WcGHfJ^9A?B -z$;Ee;sJZCV$D)_}bKz~2Qs8I00({ydc#Socalkm4cS3sD$PW$0`@rMO;K+1-uhdpy^GPCLRIXcvf=mTQ3gO^?bgm43yslRT%HW$h71x1!&`{S2*-Z~w%+ -zCb$yyJaYe?ZqNIX&k6FIe`h&!A&gAH*^zzf-ucE(I -zTx^ocV*lpJ@pAs9ihE2yd_I`#D|+@P!X#>TUHXS&jVZhXRjM+}poCC3;8_XzFb6&( -zD=V_NA+=GvZ)jEAVqbAh)SzYEYIfz)+7TMy!G -zth{+|sp))!Fm+R^=fjW?puMe7BsI_2cJ*j`RYX(JJ6+0$g;wMggw0vq*)8c-7JB!! -z|Gmt;YsOlfrr!gmw?X))(&M8QXykc4%P6hNI1+5b2Wx3cd1Uyes6H-PE{UcIZd}w! -zokhYY%0v>va@L4}s0(e#S+0>I5h+gUz`R`giH<;eu|qf -zEgCRtv93Od$Vm|5^clQEC3Iy`Jhip-c8qRm5gQ=nysK$uEvKa|Jax4+vYd=i+j22C -zWu*~wAJBOoXJEo)f~f>jS{jKQ;wl_V%iU;6oj;B>-hBMpV122+J8pS5Lv{Yc1+R%z -z!;yFY4y*>5Aj5|3GMUu0b51Jn6X8gR_DgPfx2+d`YeQFFnsMN#UG}x#t$vJHQAh`v -zS;l`y)YcZ)2%5zheh)*puIJ%j-Y+B@jnNN$MxPeOC%@ygkYgbQ$0_&(jl-jdb2$g& -zJD(;R=75Al)(+{NXR+S1maI?TRkX^+=fkv{{~k00-Ag@}_hO5BT2?75v4k@Trd+l~ -znZ#v%wy(rGR)#V~kBZ_s6p4$6zy6TkbNFj%gl;HYQn4=J#-UTQqPHi@s++#*I&<&d -zIuu4lbIyB}Eh1kP4exg!7P&oH5*wDCL1dFaS!6elV25ND-ZtX%2-nGlw; -zbeY;qmt1^Niq4BZ6%_aRzhmduY-&pVNSy;e)u}j+Wtab*LZ}L%x~T-NyO%&^WLQmA -zdEU*>axQej+^CDY5sOu~`a5cfkq(!wgpe@xZ4UvRWu+$teJ&-=Dt@8$eeBcu)A7y6 -zd0n>4CYXHK;>`NEX;;8mU7+~I*7;s?7vRzs649fxn~m7gE_vI3{(T}GTR=$i`D?5b -zOq_@;4O;#l5s|8i($fx**FPJv^^&x>xy_jZzt2q|=|crkcT4s&z8%&rkqdOxxTzGgx+oV8P(EK6=ZYv#qeDIur}s`bXAgIH^$hf8rw@j;oRJ$x -z+wGc4FA3oG?ANXyqIaNr-Lx4QB%&~f3WZBb3Yv#M{cUoxfv9InAI^)4(AFRKWOP?ZD0N>)RZ8zC6Y_#0K14^XPaY -zz!>M_dR6mug9IevSk?0`*l112C4u=cF~g$0{n2-cyM=iTxh(qKJ2=wbyv<{|k@cja -zq9o8j^FD{mY#HEwiOsysT3y!`UToM&&OviVY)T7>*6!;GtIa8&-=`>Jxy5q6Q2rmi -z(13xgAbLnp*nE2|k9XJx-)6Wmc5cMv<=e;m0}{??mP`}P(<3?ZA|bWUwiZtQ9rZd& -zLq~bpHsiW87j+DP_ACdep1iJlyS$EN@8|-NMG&B$j?8+V7=`>X_Wg+Yk&jFW4#v`9 -z7L0~2=FPl5`IWy>)Y*CDZC-)$lV2|{Od?^i^lGcpGJ$f~3_a*OaLke+Nax9S)tgxc -zr@g*|T>7B^%g*dmgcJ~)UA?>L{mi4r)hap-_r9CWFsJVdrK!eT91r@>BgDS(jc1K;}m?C&kF0H5;}Rp0o=H@@+WZ+zn$-}uHizVVH3eB=M? -ze2A!T2y%-0W4hkA(xGhfL{B2iWAaSi<0$(~%Du*o*6*Wg{Hsya)|qr!>U!_s@L$73v-0c?z8~&(dBYuSLLWjR! -zMfA%<#LGO4<;P082y=n3NZ&0x4b8kkw_s)OJ`!A2d@bF=B2`Y+eAspke9JjkB{TU> -zR!?vgv`P(e(^(pXvAaABx~7Q?^TE0Vrz98b`A1TA?B-5|^AM^HkDs(ggv|9 -zJ0}xjBuAbv21`00>ngqK_|u)6N7uV{EG6q~&-WcIGA}T_g^0Yg3tO_6B>vnrd9~wo -zf}%^LZo^54!Q+2c^2@w=OlDedWWZA%RY6wM-J%)B%S4@7j?U|gFhrTVZIZJqyc`RQ -zs>>au#zob7xl+qCwO;O-<>->xx7hZ=MQD5NHU7fb{{D~ShUa#{-SFeU#S?(L&Mx?p -zM}#DEm9dO`}Z_{-;jbc05H(E%TmqRhWY_@ -zx;Y%xeIOk0;Rfu(C*UPO7r*k^`NNgZR2iW0h%(j5sP{J}+4nYc)5c{W+OTnG6Lq{b -z-%n0XYaG_jH|1icf@j&ScoE*(r%8t9Y<(+e8rnvkY#sCqkcrgX4PP?mZc=S$LTYhH -z(6}Hb+Hf&M{y4+%n4N5m5Ot(QVwa(PLbbJp -z(K-$~ARqJ$+hculL`bx?mFnl?7rlLZB7F171Y_b^h9A2%!%tX9&!{8k<0#v5J$0m9 -zq=*cfhnE4tq*`J=8VQx#LhG>v3kRR+hw(z9a*?I$t3|d@%m%C!a`q@L%!wM?#Pp_B -z7LhJE-@nU8a_oheBHP>icaR90(0qBj+}22#43+a?Gwy0f>_%I+RT4=Wy81PXh>xz{ -z*P9M0;g>L^s1_~Ga*^-_D8S|8xu9uyC0&2LbfiltKqN*x@FNP#&A1~c2ZinAe)jRB -zH9Pr4({495p>7b^QJXCz5!&@(McR>N)X>@7)*R7HA)Kf|AyWI@h=qMXbL>QT3AO7m -zA~bd`3{B^cY!;@=#$c$qt?RSSHv=0%BzPk*i4l#~+hBiKr*03T>lx15!v`G&c1Df? -za4a9nEve1nf~jyHK#FS-zNTXlzODDxchldb^^|Bw#K!y`tnU6y@zgW);o8FpDk*2W -z(C9#pY;gdlpeA6&{D<7dDbEEPxY|y?pgJx<#91cBV}bId@7ej-eoSy5J1w{`z#&-| -zcW^RVk1Vo$wSdyDy|ead)+rziJ#~;@r&w4Y;Y=Qq@%1Ck5@!U2XUJ$GB?`5kx;;p( -zZw32cbtkBdZTQNae9E8)!n#rdgOY*(j`I4(hejxlo!WER&;6^o*@v -zpD$uUi4+xP5lxvXyL~@AG~$AexV?qQnovYUY|w@`kk7Z}lI9W88?r_sF&Gf#ynV_cS<*A8<*Pl0I -zX-p>?w}J^JEfVwj2nJ~jhy+@Q5l|f{^ML3JH1j>UA+>GWCG(IU%|#1NPe&}UMsT3)5;oJz?>4 -z9a01xv@x@w6Nmp1A@@;Z8oq$8i$H0&Gr|geaY%$OX&&0LJe*c7Lu(~&a4TpAq*S6* -ztYLKh(GI<vO -z(cEYYX5p63Jo0NuJB_|Q9y{(5S+z;OgOF(-1E4^b0Lg?C4<6%JM{IReBV=`1PtM_A -zh#vGT)ON2vb4UsXYP%;f4oTZrZ;_%EcMWj0cj1z-*;vJ0V|;D*U}7gvDBz;3?oQBB -zS9e@uaAKWo41HmE#6l-o2%!^MN;|-;a}i|Hti*xtOmr2q^LEs)5epm7q~hd`VW#N$ -zMX|c5XlF94ExNsWdKLBEp9|l -z*nntzn&y9M!y85p@ -zGeEp4j;C8Ssb&iI#D{J>dWEy5c|)BmyoRI!*5UI6@6VdGo6#*{%C%Q&yb=}d=S4q2 -z{o@Oh%G1T4l0Wn{glav1G??Q`4h(Gw)ta-@&eD@MNlyT_+HT5(t7nUFWla*}l1jTq -zd&U+6m$_D_(@XCpbdQ})bS1xXZwUR;WvA`t9mCFzXK~gcuH*+I4WSBeBLyQOePhKN -zuH*;V4WSBiEJ10=F3vV*+tNXUq~Yp$qk`V -zuq)Ym4n^Q5IfvA0{IN-5rVHUi+lNH@WQoHp9u+uF@j*1Ne0F5%YdLjS(E8R3hj8K>Z0h<*V*vA#0g2` -zru821-x3%+(&L%*+_t5Om7W96T!4=w$^UG&h|hee0IXz_JglGbaF}tzsH;71#@%;xz4!#GPZ-wz)ql& -zQzbk=xm;p1Ecj+&O%6F2s?sKDf*ZPs?@qSU#UN*TvpWkW#m))Xx{7_#TG=9o$4wHu -zUY6n}v8p-akWKc7Mjj!gVSi|jVArlD2G-jGEAf+Ey>6oG8vuw;u2gb&HBwXE!h&hW9 -zkljKYUx)Q=&fh7+CmB9e#11UlwX1=XN^z68uGP?D82V#Dk#a#YT+iV}Ddb2~!#*LG -zwcd2l`sAjrX0%3jQC_kt_NuxBiP&kaq-zOmJ3WS-!=TBPNp|hGWWX3}EX=+i0gX~F -zhhM`6^AgXnrCX1OD@xzjVuef|P3eni^I4tKlQvPEz)@F2OJOn%1sJ=>FW|6-6DEjS -z#}qhBLlD&vtf2?LCSXq!T$Kvtl5vRP^qw*7m$jU6p{i?Mo!`4ixge_y8-r^i?x8SJ -zNx(TlGE4O}OLg`o@G#HmEta)E4!YGce)XzOI`C#VCC -zHM$@W{-?&gOJX$vBY>JLPNn1BC$tsZ8lH&lhT;`+Bf|D+X2zi@yh<lELGuAa;sA`k%k`QJ_+!l_b -zGEm^Fp-er~d1HQ-8-&xxk&7%)Br2?mYsAcVQvIv;;S>)Rju*D2O{JZuB4^AK6x1bV -z%#lt~9k(KbKZNZJKNCLO|16)s&ZYBd`{ME$V+RqDPnsma&9P+`Ja;im@&-$2_=_l@U*_lrZTx -zZQkxC-5Z@Bt)na<(LCx_fc8G;maRjbuC}ZUqE>0dobTPB_UI_uY%@VaaDHZS>)>gP -z|DMnM8mPi=(_s|jNt#*d+DyMfAW -z8IRQVl(uGM+5%=rW=Bi;AXYR1*v}yW`wxj}1`%5rT}SEyPt=FoDzE*E%uj54m0_Ie -zqbpV+O)b9u=7PE@363e$t@4b6R+r^}~+S2oaJsl!`ZtOa@dQho0+@nrQJ?ff$mhTo=WrlEF -zhgj~rfwFU0({T~z=GfRNjF=7^>`u_CxEZOfARvu-QS2TQpG}Y$DVX}u8bS|AUM-7D -zE%o7wi4#Wu+I#~*R -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 -z3j`oHY_VPzLrD~XOxOr+tCIKFDv7ih -zTKrncCJeWyYpCWEBU_{*zq09ql^I -zZO)Ym-2_v{0et>G8E*wI(Jav9wmmUxNZI<34+MjNQVhTJfXmoyt)IpCbK!UA8OT$k -zPY0dFr6QPkJRn+L4**RrV7Lq?Yy*2(XTRPnXD|O=spqx;d*AVmQwtmi;G(^8{2bzU -zo~h1l*?_Hp&*m;<^+@`n%2)%9t>5(>Q> -zbrS%F=|WTQ`$`*PpcYH|LF -z^kU7ZBAApEVJnJbAj-4#yTrKayG0lVt4+HSrulsn+EDuDw9_|{ -z4f6!!hU*1+;F#TKD_{-Tg?OQcQufT_ecS%B@{5(F@;aN!8ABJOkP{9dmyxu1`qQY% -z66OB2kV|buv7IpFTOvVxTv4d0qi3I@TqpgMUK_?bRoT&BNcFwAWmmGTYhR&s%clNw -z&+K5~&R~!d{8DR^VBZ{%@V5to-De1wQEd8xD!MLk=i|r{V_pqp{@!JLy0z!j!fBsoFkRRLq`6g7cx}E<*lBY -zVQ;HrXVe>`lJmW+GY_0`1Ae>Sc=191y+_U7{bAswY1VA8j)`XCA2Xq3>@E5_NbewS -z=xau~+>!cA{6~J?l%16f+{o~7fwu0=tj7xCMZWj-LOocvV!1uJ$;nU4Z(s%P#WAec -zV>?gNb@wvlhO+1qiE!3evK(li4l&OHLpK%^VS;s1?8u%%S~|oy9r)Ak -zGDPn5>C-AsjxqZU*(>q=i4Zw~Al+P7u(Gkgf1@0}H&O2a=M3`B_Xwv0``tf&&|-NE#Zdc&i9!oF_vBf9v&V9rIz+PeOu -zO5f?&d{xiJF5H*A&?Frfir~zsvZOIU3xBLT^P$F -zG^GOz4ap$*Vp2IG)`j(Y?EGRw|C~h;Y{?ckQUGR+lI3*i@B5PSmeWt$u%IT^%XO^5Nu$q)!^FK!Qfi?NBofx@rB7uRze5Vv**$&2MhMI*QJ -z@5kFLKq}>UyxsA2_@e?op&q73Z<3JXhV2?!z~H`BulTTSNG?Rx^gWEVw49zPryL6; -zNg!gNTG4Bj6G7OpSN9Ms0G!ecp8yZT)AHvR;c2L*8vjhl=FFb& -zOU6g@D2={9=6;J3A(2-JF%w|3D35UaBAo$>L6ofLHVJ=nAk^>vb_c{`TLeHFa$bnk@!V^%RY{L8Fz -z=y^}zo1w&E;B_zjOUflk6_$iBN*95Ibg}=|KSp0WUK&5A)hqYRJ7Sq!xx2h5Qga~SMvlKdLNAl{UWwLIuq2H^Tu-eqv)|KL`F-%u(U5N{C -z8K8Uy76Swav4aR@zTEZxu0K~JBsb=kz~seXkP-s78e9_f-IH^> -z;JhWQS`U%<_?NdbJ@C_~f8GT*p6}{f!rqPW2k>IhKVLtR+8v&BXpQpI -z2!49{R+4T#R2!{%g{`fDT(8So_j@@FJP$vQ$+Xy~NQ?R`Pdh!3ZqX4!9Fk&qqAf*~KzC2e8H0Lnt?=W)I~S9L#!yQ=>0h24#S#U!OsSQh#*N&Wr(j;*hX -zB+s0dx?DP*QCYk@=LQQ7ZN8c*Ym#cVa-?!K@?O1%yRc#q=TH0uI#-NHv>TlZXA# -z!$a8)gIard5%qZ>Y!5G@HV+<}%>L`mt%=S -zV8ngex+O62cT>A4FbPfUg`f8ChPTnMAOOxot^-OZ{_6;Or?d2T_+@WEUGYT@N%=_* -zNfup!=a0(8FG4%%@PDG>1*Ry{l;oYlRO>}aEu*BCoem%eD2#(l@_#!y4t?-kDZt&! -z)y1{_0pYi;oY`dHjm)t7UjpM-mMT+|2ymFdS|>Jk34H0?|CG1=R1g>VtoWBFN#fo4 -z!zhNMY-HHN-Y51mixYD4dZ&4jI~kwPA2t+A6f+c)J1T4TzVoY0g2GWm0vX@6Gx8}v -zNij)N415%mYjmvR*2k-?y@mLzFpmXvH!3Nu8*{ZoefqW5iG-=Eb7wY;=6>qpx_ms7 -zVB!)9`%{ZGx8M_pJ$*|zFnHnNlK#@er5MSgpS#H2^TO|LgaSbk#b8z8{wv -z6qe3tomf*=d|U4B4$iky8(q80Hdv0^Ox5Xx9+@OE#p2^D+X!DbW8PU;cCY!&KZ$t~ -zw<|c-OCmh!2#DK7OQrY(ons{ORsIr|PF}jSCJvFv168jN&+*!Vy)f4`QMdTSnf@_R|n_B3Dj -zGPN7dd5C<+TxZ?hnXq`ABB!pK7mLmTWU0vyr176|Vd?y9d;e=m)Fd5HrMQPrr|Xvv*xyd{=!4LXy}dsS;=&p5mwj-rWN{JdOcRQmTxZc9?8J8xPSiVg%~|Dw^R_BOf-6gn -zZq~%-Z<1+b8sp#j_xDpk6cxYd9kFsAPS~)HtW$Hys}ED=Rj(N7A(T_ZucvN*0^m9k -zxbvFF`-0{oj(`92x$plF2~vFaXTRgtX;4w<4-XX{Uift(Pwi?e*x4_(dE=1 -z8Y_=9eZk!;=(+S$jq2DJx7^IqFJr$BgcU^Ii;WDP@wC9#S$B<2HfpJfh6a39A9fw3 -zsjml-UAzo>KAchWL-&|GXPVgdD@^46)NFiLQUUCCeem81BeHzuRFtFM*1_OFyK9Q~ -z{Efl7fVL7;RBf3gGqJC*r(xYJJ^v=oe+?4w!I#$_I&MCHbVA|9In4@x+-Bo$r{5?!|YDvIlB5gEv#c*h_O^kHM@e6_AR?dh#2m -zjmUmK>B^5^;_tsd?jn9c-$&+%=DJp@o9m;3b=8=Tig2eH30Rd1)Ur`nM)kKXpZw_u -z3a2$E6;h4j&YirUo9Ui6b5&$gSWdOkDTfgcG;C6WdnQ*$%gP%ewa2nVUWPgCeJ#_t -z-~7{ckfJ_yreZqpb`PY&X&rMdE^XU}^fqnI@#Ek)42E;^7@aJ6jg0ICpJC=FN7qJC -z(k``C_H{jFGEdQ;_);vhB8KIg%*Q=|rg_8}MIAx2-TVtp^TMHK$um^%*(*?rId|>7 -zPF;4!t`4GB==S>f_KNu!|LI))1<|Gh0I@MJd~_p{J{Ayd!H5L@ -z)4Mu!=+GyPpvM7Cx6*CVgYHi*OA5kr-A?X;b%K}Ipr$ADid8E -p-2n*wJ^0U-v7>KuoPIQ2d!PBQ{|*1e0(@QdS=9&np+Egb{vR}l^_Bnt - -literal 0 -HcmV?d00001 - -diff --git a/dirsrvtests/tests/suites/clu/dsctl_dblib_test.py b/dirsrvtests/tests/suites/clu/dsctl_dblib_test.py -index 4d5a54eee..9fc9caa05 100644 ---- a/dirsrvtests/tests/suites/clu/dsctl_dblib_test.py -+++ b/dirsrvtests/tests/suites/clu/dsctl_dblib_test.py -@@ -11,7 +11,7 @@ import pytest - import ldap - import os - import time --from lib389._constants import DEFAULT_SUFFIX -+from lib389._constants import DEFAULT_SUFFIX, BDB_IMPL_STATUS - from lib389.backend import DatabaseConfig - from lib389.cli_ctl.dblib import ( - FakeArgs, -@@ -22,6 +22,7 @@ from lib389.idm.user import UserAccounts - from lib389.replica import ReplicationManager - from lib389.topologies import topology_m2 as topo_m2, topology_st as topo_st - from lib389.utils import check_plugin_strings -+from lib389.cli_ctl.dblib import get_bdb_impl_status - - - log = logging.getLogger(__name__) -@@ -92,6 +93,7 @@ def _check_db(inst, log, impl): - - - @pytest.mark.skipif(is_bdb_supported() is False, reason='This test requires bdb support') -+@pytest.mark.skipif(get_bdb_impl_status() == BDB_IMPL_STATUS.READ_ONLY, reason = 'Cannot read with read-only bdb') - def test_dblib_migration(init_user): - """ - Verify dsctl dblib xxxxxxx sub commands (migration between bdb and lmdb) -diff --git a/dirsrvtests/tests/suites/lib389/config_compare_test.py b/dirsrvtests/tests/suites/lib389/config_compare_test.py -index 3eb3d0ea4..fca33665f 100644 ---- a/dirsrvtests/tests/suites/lib389/config_compare_test.py -+++ b/dirsrvtests/tests/suites/lib389/config_compare_test.py -@@ -13,6 +13,8 @@ from contextlib import suppress - from lib389.topologies import topology_i2 - from lib389.config import Config - from lib389.dseldif import DSEldif -+from lib389.cli_ctl.dblib import get_bdb_impl_status -+from lib389._constants import BDB_IMPL_STATUS - - pytestmark = pytest.mark.tier1 - -@@ -47,7 +49,6 @@ def test_config_compare(topology_i2): - - assert Config.compare(st1_config, st2_config) - -- - @pytest.fixture(scope="function", params=db_types_and_states) - def set_db_type_and_state(topology_i2, request): - """ -@@ -72,6 +73,7 @@ def set_db_type_and_state(topology_i2, request): - return (dbtype,state) - - -+@pytest.mark.skipif(get_bdb_impl_status() == BDB_IMPL_STATUS.READ_ONLY, reason="This test cannot run if bdb is read-only") - def test_get_db_lib(request, topology_i2, set_db_type_and_state): - """ - Check that get_db_lib() returns the configured database type. -diff --git a/dirsrvtests/tests/suites/upgrade/upgrade_bdb2mdb_test.py b/dirsrvtests/tests/suites/upgrade/upgrade_bdb2mdb_test.py -new file mode 100644 -index 000000000..d9647b120 ---- /dev/null -+++ b/dirsrvtests/tests/suites/upgrade/upgrade_bdb2mdb_test.py -@@ -0,0 +1,278 @@ -+# --- BEGIN COPYRIGHT BLOCK --- -+# Copyright (C) 2025 Red Hat, Inc. -+# All rights reserved. -+# -+# License: GPL (version 3 or any later version). -+# See LICENSE for details. -+# --- END COPYRIGHT BLOCK --- -+# -+ -+import os -+import logging -+import pwd -+import pytest -+import re -+import socket -+import subprocess -+import tarfile -+import time -+from contextlib import suppress -+from itertools import permutations -+from lib389 import DirSrv -+from lib389._constants import * -+from lib389.cli_base import FakeArgs -+from lib389.cli_ctl.dblib import get_bdb_impl_status, dblib_bdb2mdb -+from lib389.config import Config -+from lib389.dseldif import DSEldif -+from lib389.idm.services import ServiceAccounts -+from lib389.nss_ssl import NssSsl -+from lib389.passwd import password_generate -+from lib389.replica import ReplicationManager, Replicas -+from lib389.topologies import topology_m2 as topo_m2 -+from lib389.utils import ( -+ get_default_db_lib, -+ escapeDNFiltValue, -+ resolve_selinux_path, -+ selinux_label_file, -+ selinux_label_port, -+ selinux_present, -+ ) -+from pathlib import Path -+ -+log = logging.getLogger(__name__) -+DEBUGGING = os.getenv("DEBUGGING", default=False) -+ -+# Environmaent variable used to generate the tarball -+GENTARBALL = "GENERATE_BDB_TARBALL" -+CURRENT_FILE = os.path.realpath(__file__) -+TARFILENAME = f'{Path(CURRENT_FILE).parents[2]}/data/bdb_instances/instances.tgz' -+ -+class MigrationHandler: -+ def __init__(self): -+ self.hostname = socket.gethostname() -+ self.uid = os.getuid() -+ self.gid = os.getgid() -+ self.idir = os.getenv("PREFIX", "/") -+ self.inst_list=[] -+ self.username = pwd.getpwuid(self.uid).pw_name -+ # Determine the instances names -+ with tarfile.open(name=TARFILENAME, mode='r:gz') as tar: -+ names = [] -+ for member in tar: -+ match = re.match('.*/slapd-([^/]*)/dse.ldif$',member.path) -+ if match and match.group(1) not in names: -+ names.append(match.group(1)) -+ self.names = names -+ log.info(f'MigrationHandler has following instances: {names}') -+ -+ -+ def replace_dse_line(self, line, old_hostname): -+ if old_hostname: -+ line = line.replace(old_hostname, self.hostname) -+ if self.idir != '/': -+ for name in ( '/etc/', '/var/l', '/run/', ): -+ line = line.replace(f' {name}', f' {self.idir}/{name}') -+ if line.startswith('nsslapd-localuser:'): -+ line = f'nsslapd-localuser: {self.username}\n' -+ return line -+ -+ def remap_dse(self, path): -+ old_hostname = None -+ tmppath = f'{path}.tmp' -+ with open(path, 'rt') as fin: -+ with open(tmppath, 'wt') as fout: -+ for line in fin: -+ match = re.match(r'nsslapd-localhost:\s*(\S*)',line) -+ if match: -+ old_hostname = match.group(1) -+ fout.write(self.replace_dse_line(line, old_hostname)) -+ os.remove(path) -+ os.rename(tmppath, path) -+ -+ def tar_filter(self, member, path): -+ fullpath = f'{path}/{member.path}' -+ # Do not try to overwrite existing files except dse.ldif -+ if os.path.exists(fullpath) and not member.path.endswith('/dse.ldif'): -+ return None -+ # use the current user credentials -+ member.uid = self.uid -+ member.gid = self.gid -+ # Security: reject tricky files that may be in tar ball -+ return tarfile.tar_filter(member, path) -+ -+ def relabel_selinux(self): -+ if not selinux_present(): -+ return -+ for inst in self.inst_list: -+ log.info("Performing SELinux labeling on instance {inst.serverid} ...") -+ dse = DSEldif(inst) -+ -+ selinux_attr_labels = { -+ (DN_CONFIG, 'nsslapd-bakdir'): 'dirsrv_var_lib_t', -+ (DN_CONFIG, 'nsslapd-certdir'): 'dirsrv_config_t', -+ (DN_CONFIG, 'nsslapd-ldifdir'): 'dirsrv_var_lib_t', -+ (DN_CONFIG, 'nsslapd-lockdir'): 'dirsrv_var_lock_t', -+ (DN_CONFIG, 'nsslapd-rundir'): 'dirsrv_var_run_t', -+ (DN_CONFIG, 'nsslapd-schemadir'): 'dirsrv_config_t', -+ (DN_CONFIG, 'nsslapd-tmpdir'): 'tmp_t', -+ (DN_CONFIG_LDBM, 'nsslapd-db-home-directory'): 'dirsrv_tmpfs_t', -+ (DN_CONFIG_LDBM, 'nsslapd-directory'): 'dirsrv_var_lib_t', -+ } -+ # Generates the path -> label dict -+ selinux_labels = { dse.get(pair[0], pair[1], single=True) : label for pair,label in selinux_attr_labels.items() } -+ log_dir = os.path.dirname(dse.get(DN_CONFIG, 'nsslapd-accesslog', single=True)) -+ selinux_attr_labels[log_dir] = 'dirsrv_var_log_t' -+ if os.path.isdir('/run/dirsrv'): -+ selinux_attr_labels['/run/dirsrv'] = 'dirsrv_var_run_t' -+ -+ for path, label in selinux_labels.items(): -+ with suppress(ValueError): -+ selinux_label_file(resolve_selinux_path(str(path)), label) -+ -+ for port_attr in ( 'nsslapd-port', 'nsslapd-securePort' ): -+ port = dse.get(DN_CONFIG, port_attr, single=True) -+ if port is None or port == '0': -+ continue -+ selinux_label_port(port) -+ -+ def dirsrv_instances(self, ignore_errors=False): -+ inst_list = [] -+ for name in self.names: -+ inst = DirSrv(verbose=DEBUGGING, external_log=log) -+ try: -+ inst.local_simple_allocate(name, binddn=DN_DM, password=PW_DM) -+ except FileNotFoundError as ex: -+ if ignore_errors is not True: -+ raise ex -+ continue -+ inst.setup_ldapi() -+ inst_list.append(inst) -+ nss = NssSsl(dirsrv=inst) -+ nss.openssl_rehash(nss._certdb) -+ return inst_list -+ -+ -+ def extract_instances(self): -+ with tarfile.open(name=TARFILENAME, mode='r:gz') as tar: -+ tar.extractall(path=self.idir, filter=self.tar_filter) -+ -+ # Fix the dse.ldif -+ for name in self.names: -+ self.remap_dse(f'{self.idir}/etc/dirsrv/slapd-{name}/dse.ldif') -+ -+ # Create missing directories -+ os.makedirs(f'{self.idir}/var/log/dirsrv/slapd-supplier1', mode=0o750, exist_ok=True) -+ os.makedirs(f'{self.idir}/var/log/dirsrv/slapd-supplier2', mode=0o750, exist_ok=True) -+ os.makedirs(f'{self.idir}/run/lock/dirsrv/slapd-supplier1', mode=0o750, exist_ok=True) -+ os.makedirs(f'{self.idir}/run/lock/dirsrv/slapd-supplier2', mode=0o750, exist_ok=True) -+ os.makedirs(f'{self.idir}/var/lib/dirsrv/slapd-supplier1/ldif', mode=0o750, exist_ok=True) -+ os.makedirs(f'{self.idir}/var/lib/dirsrv/slapd-supplier2/ldif', mode=0o750, exist_ok=True) -+ os.makedirs(f'{self.idir}/run/dirsrv', mode=0o770, exist_ok=True) -+ -+ # Generate DirSrv instances -+ self.inst_list = self.dirsrv_instances() -+ -+ # Relabel -+ if self.uid == 0: -+ self.relabel_selinux() -+ -+ -+ def remove_instances(self): -+ for inst in self.dirsrv_instances(ignore_errors=True): -+ inst.delete() -+ -+ -+ def migrate2mdb(self): -+ args = FakeArgs() -+ args.tmpdir = None -+ for inst in self.inst_list: -+ log.info(f'Migrating instance {inst.serverid} from bdb to mdb') -+ dblib_bdb2mdb(inst, log, args) -+ inst.start() -+ inst.open() -+ self.reset_agmt_passwords() -+ -+ -+ def reset_agmt_passwords(self): -+ pw = password_generate() -+ -+ for inst in self.inst_list: -+ # For some reason inst.sslport is None although nsslapd-securePort is defined -+ for service in ServiceAccounts(inst, DEFAULT_SUFFIX).list(): -+ service.replace('userPassword', pw) -+ replica = Replicas(inst).list()[0] -+ for agmt in replica.get_agreements().list(): -+ agmt.replace('nsds5ReplicaCredentials', pw) -+ del pw -+ -+ -+def strip_path(path): -+ return re.match(r'^/*([^/].*)$', path).group(1) -+ -+ -+@pytest.mark.skipif(get_default_db_lib() != "bdb", reason = f'Requires bdb mode') -+@pytest.mark.skipif(os.getenv(GENTARBALL) is None, reason = f'Requires setting {GENTARBALL} environment variable') -+def test_generate_tarball(topo_m2): -+ """Test Generate the tarball for test_upgradefrombdb -+ -+ :id: 0325c4fe-da66-11ef-98fc-482ae39447e5 -+ :setup: two suppliers -+ :steps: -+ 1. Check that replication is working -+ 2. Generaters the tarball -+ :expectedresults: -+ 1. Success -+ 2. Success -+ """ -+ idir = os.getenv("PREFIX", "/") -+ repl = ReplicationManager(DEFAULT_SUFFIX) -+ for i1,i2 in permutations(topo_m2, 2): -+ log.info(f'Testing replication {i1.serverid} --> {i2.serverid}') -+ repl.test_replication(i1, i2) -+ for inst in topo_m2: -+ inst.stop() -+ tardir = Path(TARFILENAME).parent -+ os.makedirs(tardir, mode = 0o755, exist_ok = True) -+ this_dir = os.getcwd() -+ with tarfile.open(name=TARFILENAME, mode='w:gz') as tar: -+ os.chdir(idir) -+ for inst in topo_m2: -+ name = inst.serverid -+ tar.add(strip_path(f'/etc/dirsrv/slapd-{name}')) -+ tar.add(strip_path(f'/var/lib/dirsrv/slapd-{name}/db')) -+ os.chdir(this_dir) -+ for inst in topo_m2: -+ inst.start() -+ -+ -+@pytest.mark.skipif(get_bdb_impl_status() != BDB_IMPL_STATUS.READ_ONLY, reason = 'Already tested through clu/dsctl_dblib_test.py:test_dblib_migration') -+def test_upgradefrombdb(): -+ """Test upgrade from bdb to mdb -+ -+ :id: f0f02d12-da4f-11ef-966f-482ae39447e5 -+ :setup: None -+ :steps: -+ 1. Extract bdb instances from the tar ball -+ 2. Migrate the instances to mdb -+ 3. Check that replication is still working -+ :expectedresults: -+ 1. Success -+ 2. Success -+ 3. Success -+ """ -+ -+ handler = MigrationHandler() -+ handler.remove_instances() -+ handler.extract_instances() -+ handler.migrate2mdb() -+ repl = ReplicationManager(DEFAULT_SUFFIX) -+ for i1,i2 in permutations(handler.inst_list, 2): -+ log.info(f'Testing replication {i1.serverid} --> {i2.serverid}') -+ repl.test_replication(i1, i2) -+ handler.remove_instances() -+ -+if __name__ == '__main__': -+ # Run isolated -+ # -s for DEBUG mode -+ pytest.main(["-s", CURRENT_FILE]) -+ -diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_bdbreader_db.h b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_bdbreader_db.h -new file mode 100644 -index 000000000..f50d961e9 ---- /dev/null -+++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_bdbreader_db.h -@@ -0,0 +1,289 @@ -+/** BEGIN COPYRIGHT BLOCK -+ * Copyright (C) 2024 Red Hat, Inc. -+ * All rights reserved. -+ * -+ * License: GPL (version 3 or any later version). -+ * See LICENSE for details. -+ * END COPYRIGHT BLOCK **/ -+ -+/* -+ * This file provides the part of the Berkeley Datatabase 5.3 API -+ * definition that are refered within 389-ds-base project -+ */ -+ -+#ifndef DB_H_ -+#define DB_H_ -+ -+/* Needed for configure */ -+#define DB_VERSION_MAJOR 5 -+#define DB_VERSION_MINOR 3 -+#define DB_VERSION_PATCH 280 -+ -+ -+#define DB_INIT_MPOOL 0x000001 -+#define DB_INIT_TXN 0x000002 -+#define DB_INIT_LOG 0x000004 -+#define DB_INIT_LOCK 0x000008 -+#define DB_REGION_INIT 0x000010 -+#define DB_FREE_SPACE 0x000020 -+#define DB_FREELIST_ONLY 0x000040 -+#define DB_TXN_NOWAIT 0x000080 -+#define DB_ARCH_ABS 0x000100 -+#define DB_ARCH_LOG 0x000200 -+#define DB_RDONLY 0x000400 -+#define DB_STAT_CLEAR 0x000800 -+ -+ -+ -+#define DB_DUP 0x000100 -+#define DB_DUPSORT 0x000200 -+#define DB_RECNUM 0x000400 -+#define DB_FORCE 0x000800 -+#define DB_SYSTEM_MEM 0x001000 -+#define DB_THREAD 0x002000 -+#define DB_CREATE 0x004000 -+#define DB_PRIVATE 0x008000 -+#define DB_MULTIPLE_KEY 0x010000 -+#define DB_MULTIPLE 0x020000 -+#define DB_RMW 0x040000 -+#define DB_RECOVER 0x080000 -+#define DB_TXN_WRITE_NOSYNC 0x100000 -+#define DB_AUTO_COMMIT 0x200000 -+#define DB_RECOVER_FATAL 0x400000 -+#define DB_LOCKDOWN 0x800000 -+#define DB_TRUNCATE 0x1000000 -+#define XDB_RECOVER 0x000000 -+ -+enum { -+ DB_FIRST = 1, -+ DB_CURRENT, -+ DB_GET_BOTH, -+ DB_GET_BOTH_RANGE, -+ DB_GET_RECNO, -+ DB_LAST, -+ DB_NEXT, -+ DB_NEXT_DUP, -+ DB_NEXT_NODUP, -+ DB_NODUPDATA, -+ DB_PREV, -+ DB_SET, -+ DB_SET_RANGE, -+ DB_SET_RECNO, -+ DB_UNKNOWN, -+ -+}; -+ -+ -+ -+#define OPEN_FLAGS_CLOSED 0x58585858 -+#define OPEN_FLAGS_OPEN 0xdbdbdbdb -+ -+#define DB_DBT_USERMEM 1 -+#define DB_DBT_MALLOC 2 -+#define DB_DBT_REALLOC 4 -+ -+#define DB_MULTIPLE_INIT(pointer, dbt) -+#define DB_MULTIPLE_NEXT(pointer, dbt, retdata, retdlen) -+#define DB_MULTIPLE_KEY_NEXT(pointer, dbt, retkey, retklen, retdata, retdlen) -+ -+typedef enum { -+ DB_SUCCESS, -+ DB_NOTFOUND, /* Should be 1 because btree_next returns 1 when there are no more records */ -+ DB_BUFFER_SMALL, -+ DB_KEYEXIST, -+ DB_RUNRECOVERY, -+ DB_NOTSUPPORTED, -+ DB_LOCK_DEADLOCK, -+ DB_OSERROR, -+} db_error_t; -+ -+enum { -+ DB_LOCK_DEFAULT, -+ DB_LOCK_NORUN, -+ DB_VERB_DEADLOCK, -+ DB_VERB_RECOVERY, -+ DB_VERB_WAITSFOR, -+}; -+ -+/* DB_LOCK_YOUNGEST mustt be a define because it is used in STRINGIFYDEFINE */ -+#define DB_LOCK_YOUNGEST 9 -+ -+typedef struct db DB; -+typedef struct db_env DB_ENV; -+typedef struct db_txn DB_TXN; -+typedef struct db_cursor DBC; -+ -+typedef enum { -+ DB_BTREE, -+ DB_HASH, -+ DB_RECNO, -+} DBTYPE; -+ -+typedef struct { -+ int compact_pages_free; -+} DB_COMPACT; -+ -+typedef struct { -+ int st_nactive; -+ int st_ncommits; -+ int st_naborts; -+ int st_region_wait; -+} DB_TXN_STAT; -+ -+typedef struct { -+ int st_maxnlocks; -+ int st_ndeadlocks; -+ int st_nlockers; -+ int st_region_wait; -+ int st_w_bytes; -+ int st_wc_bytes; -+ int st_wc_mbytes; -+ int st_w_mbytes; -+ -+} DB_LOG_STAT; -+ -+typedef struct { -+ int st_bytes; -+ int st_cache_hit; -+ int st_cache_miss; -+ int st_gbytes; -+ int st_hash_buckets; -+ int st_hash_longest; -+ int st_hash_searches; -+ int st_page_create; -+ int st_page_in; -+ int st_page_out; -+ int st_ro_evict; -+ int st_rw_evict; -+ int st_page_dirty; -+ int st_pagesize; -+ int st_page_clean; -+ int st_page_trickle; -+ int st_hash_examined; -+ int st_region_wait; -+ -+ -+} DB_MPOOL_STAT; -+ -+typedef struct { -+ int bt_ndata; -+} DB_BTREE_STAT; -+ -+typedef struct { -+ int st_nlocks; -+ int st_maxlocks; -+ int st_region_wait; -+ int st_ndeadlocks; -+ int st_maxnlocks; -+ int st_nlockers; -+ int st_lock_wait; -+ int st_nobjects; -+ int st_maxnobjects; -+ int st_nrequests; -+ -+} DB_LOCK_STAT; -+ -+typedef struct { -+ char *file_name; -+ int st_page_in; -+ int st_page_out; -+ int st_cache_hit; -+ int st_cache_miss; -+} DB_MPOOL_FSTAT; -+ -+typedef struct dbt { -+ u_int32_t flags; -+ u_int32_t size; -+ u_int32_t ulen; -+ void *data; -+} DBT; -+ -+ -+struct db_cursor { -+ DB *dbp; -+ int (*c_close)(DBC *); -+ int (*c_del)(DBC *, u_int32_t); -+ int (*c_get)(DBC *, DBT*, DBT*, u_int32_t); -+ int (*c_put)(DBC *, DBT*, DBT*, u_int32_t); -+ int (*c_count)(DBC *, void *, u_int32_t); -+ /* fields only used by the implementation */ -+ void *impl; -+}; -+ -+struct db_txn { -+ int (*id)(DB_TXN*); -+ int (*commit)(DB_TXN*, u_int32_t); -+ int (*abort)(DB_TXN*); -+}; -+ -+struct db_env { -+ int (*close)(DB_ENV*, int); -+ int (*lock_detect)(DB_ENV*, int, int, int*); -+ int (*open)(DB_ENV*, const char*, int, int); -+ int (*remove)(DB_ENV *, const char *, u_int32_t); -+ int (*set_flags)(DB_ENV*, u_int32_t, u_int32_t); -+ int (*set_verbose)(DB_ENV *, u_int32_t, int); -+ int (*txn_checkpoint)(const DB_ENV *, u_int32_t , u_int32_t , u_int32_t); -+ int (*txn_begin)(DB_ENV *, DB_TXN *, DB_TXN **, u_int32_t); -+ void (*get_open_flags)(DB_ENV*, u_int32_t*); -+ void (*mutex_set_tas_spins)(DB_ENV *, u_int32_t); -+ void (*set_alloc)(DB_ENV *, void *, void *, void*); -+ void (*set_cachesize)(DB_ENV *, u_int32_t , u_int32_t , int); -+ void (*set_data_dir)(DB_ENV *, const char *); -+ void (*set_errcall)(DB_ENV *, void (*)(const DB_ENV *, const char *, const char *)); -+ void (*set_errpfx)(DB_ENV *, const char *); -+ void (*set_lg_bsize)(DB_ENV *, long); -+ void (*set_lg_dir)(DB_ENV *, const char*); -+ void (*set_lg_max)(DB_ENV *, u_int32_t); -+ void (*set_lg_regionmax)(DB_ENV *, u_int32_t); -+ void (*set_lk_max_lockers)(DB_ENV *, u_int32_t); -+ void (*set_lk_max_locks)(DB_ENV *, u_int32_t); -+ void (*set_lk_max_objects)(DB_ENV *, u_int32_t); -+ void (*set_shm_key)(DB_ENV *, long); -+ void (*set_tx_max)(DB_ENV *, u_int32_t); -+ void (*log_flush)(DB_ENV *, u_int32_t); -+ int (*lock_stat)(DB_ENV *, DB_LOCK_STAT**, u_int32_t); -+ int (*log_archive)(DB_ENV *, void*, u_int32_t); -+ int (*memp_stat)(DB_ENV *, void*, void *, u_int32_t); -+ int (*memp_trickle)(DB_ENV *, u_int32_t, int*); -+ int (*dbrename)(DB_ENV *, DB_TXN *, const char *, const char *, const char *, u_int32_t); -+ int (*stat)(DB_ENV *, DB_TXN *, void *, u_int32_t); -+ int (*log_stat)(DB_ENV *, DB_LOG_STAT **, u_int32_t); -+ int (*txn_stat)(DB_ENV *, DB_TXN_STAT **, u_int32_t); -+ /* fields only used by the implementation */ -+ char *db_home; -+}; -+ -+struct db { -+ int (*close)(DB*, u_int32_t); -+ int (*compact)(DB*, DB_TXN*, DBT*, DBT*, void *, u_int32_t, DBT*); -+ int (*cursor)(DB*, DB_TXN*, DBC**, u_int32_t); -+ int (*del)(DB*, DB_TXN*, DBT*, u_int32_t); -+ int (*get)(DB*, DB_TXN*, DBT*, DBT*, u_int32_t); -+ int (*get_type)(DB *, DBTYPE *); -+ int (*open)(DB*, DB_TXN*, const char*, const char *, DBTYPE, u_int32_t, int); -+ int (*put)(DB*, DB_TXN*, DBT*, DBT*, u_int32_t); -+ int (*remove)(DB*, const char*, const char*, u_int32_t); -+ int (*rename)(DB*, const char*, const char*, const char*, u_int32_t); -+ int (*set_bt_compare)(DB*, int (*)(DB *, const DBT *, const DBT *)); -+ int (*set_dup_compare)(DB*, int (*)(DB *, const DBT *, const DBT *)); -+ int (*set_flags)(DB*, u_int32_t); -+ int (*set_pagesize)(DB *, u_int32_t); -+ int (*stat)(DB *, DB_TXN *, void *, u_int32_t); -+ int (*verify)(DB *, const char *, const char *, FILE *, u_int32_t); -+ void *app_private; -+ u_int32_t open_flags; -+ char *fname; -+ int pgsize; -+ /* fields only used by the implementation */ -+ void *impl; -+ DB_ENV *env; -+ DBC *cur; -+}; -+ -+char * db_version(int *major, int *minor, int *patch); -+int db_env_create(DB_ENV **, u_int32_t); -+int db_create(DB **, DB_ENV *, u_int32_t); -+char *db_strerror(int); -+ -+#endif /* DB_H_ */ -diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_bdbreader_glue.c b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_bdbreader_glue.c -new file mode 100644 -index 000000000..7e8e7861a ---- /dev/null -+++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_bdbreader_glue.c -@@ -0,0 +1,519 @@ -+/** BEGIN COPYRIGHT BLOCK -+ * Copyright (C) 2024 Red Hat, Inc. -+ * All rights reserved. -+ * -+ * License: GPL (version 3 or any later version). -+ * See LICENSE for details. -+ * END COPYRIGHT BLOCK **/ -+ -+#include "bdb_layer.h" -+#include -+ -+int db_close(DB *, u_int32_t); -+ -+/* -+ * This file contains the stub that transform usual bdb API (limited to the function 389-ds needs to export a db and a changelog -+ * to bdb_ro callbacks -+ */ -+ -+#undef slapi_log_err -+ -+#define LOGK(k) (((k)&&(k)->data && (k)->size) ? (k)->data : "") -+#define LOGN(v, names) (((v)> sizeof names/sizeof names[0]) ? "Unexpected value" : names[v]) -+ -+int db_cursor(DB *db, DB_TXN *txnid, DBC **cursorp, u_int32_t flags); -+int dbc_close(DBC *dbc); -+ -+void slapi_log_err(int loglvl, char *module, char *msg, ...) { -+#ifdef DEBUG -+ static FILE *fd = NULL; -+ va_list ap; -+ va_start(ap, msg); -+ if (fd == NULL) { -+ fd = fopen("/tmp/mylog", "w"); -+ } -+ fprintf(fd, "[%s]:%d ", module, loglvl); -+ vfprintf(fd, msg, ap); -+ fflush(fd); -+#endif -+} -+ -+/* -+ * Dump a memory buffer in hexa and ascii in error log -+ * -+ * addr - The memory buffer address. -+ * len - The memory buffer lenght. -+ */ -+void -+hexadump(char *msg, const void *addr, size_t offset, size_t len) -+{ -+#ifdef DEBUG -+#define HEXADUMP_TAB 4 -+/* 4 characters per bytes: 2 hexa digits, 1 space and the ascii */ -+#define HEXADUMP_BUF_SIZE (4*16+HEXADUMP_TAB) -+ char hexdigit[] = "0123456789ABCDEF"; -+ -+ const unsigned char *pt = addr; -+ char buff[HEXADUMP_BUF_SIZE+1]; -+ memset (buff, ' ', HEXADUMP_BUF_SIZE); -+ buff[HEXADUMP_BUF_SIZE] = '\0'; -+ while (len > 0) { -+ int dpl; -+ for (dpl = 0; dpl < 16 && len>0; dpl++, len--) { -+ buff[3*dpl] = hexdigit[((*pt) >> 4) & 0xf]; -+ buff[3*dpl+1] = hexdigit[(*pt) & 0xf]; -+ buff[3*16+HEXADUMP_TAB+dpl] = (*pt>=0x20 && *pt<0x7f) ? *pt : '.'; -+ pt++; -+ } -+ for (;dpl < 16; dpl++) { -+ buff[3*dpl] = ' '; -+ buff[3*dpl+1] = ' '; -+ buff[3*16+HEXADUMP_TAB+dpl] = ' '; -+ } -+ slapi_log_err(0, msg, "[0x%08lx] %s\n", offset, buff); -+ offset += 16; -+ } -+#endif -+} -+ -+char *db_version(int *major, int *minor, int *patch) -+{ -+ static char version[200]; -+ sprintf(version, "Read-Only Berkeley Database Stub %d.%d.%d", DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH); -+ if (major != NULL) { -+ *major = DB_VERSION_MAJOR; -+ } -+ if (minor != NULL) { -+ *minor = DB_VERSION_MINOR; -+ } -+ if (patch != NULL) { -+ *patch = DB_VERSION_PATCH; -+ } -+ return version; -+} -+ -+int nothing() -+{ -+ return DB_SUCCESS; -+} -+ -+/* -+ * Define libbdbreader callbacks -+ * Note: slapi_ch_calloc, slapi_ch_malloc, slapi_ch_realloc -+ * are not directly used because their prototype is -+ * slightl -+ * slapi_ch_calloc are slithly different -+ */ -+void* bdbreader_calloc(size_t nbelmt, size_t size) -+{ -+ return slapi_ch_calloc(nbelmt, size); -+} -+ -+/* -+ * Redefines all the callback because bdbreader_malloc and -+ * slapi_ch_malloc prototypes are slithly different -+ */ -+void* bdbreader_malloc(size_t size) -+{ -+ return slapi_ch_malloc(size); -+} -+ -+void* bdbreader_realloc(void* pt, size_t size) -+{ -+ return slapi_ch_realloc(pt, size); -+} -+ -+static void bdbreader_free(void **pt) -+{ -+ slapi_ch_free(pt); -+} -+ -+static void bdbreader_log(const char *msg, ...) -+{ -+ char buffer[512]; -+ va_list ap; -+ -+ va_start(ap, msg); -+ PR_vsnprintf(buffer, (sizeof buffer), msg, ap); -+ va_end(ap); -+ slapi_log_err(SLAPI_LOG_ERR, "libbdbreader", "%s", buffer); -+} -+ -+int dbenv_open(DB_ENV *dbenv, const char *db_home, int flags, int mode) -+{ -+ if (dbenv->db_home == NULL) { -+ /* If not set by dbenv->set_dir_lg() */ -+ dbenv->db_home = slapi_ch_strdup(db_home); -+ } -+ /* Initialize libbdbreader callbacks */ -+ bdbreader_set_calloc_cb(bdbreader_calloc); -+ bdbreader_set_malloc_cb(bdbreader_malloc); -+ bdbreader_set_realloc_cb(bdbreader_realloc); -+ bdbreader_set_free_cb(bdbreader_free); -+ bdbreader_set_log_cb(bdbreader_log); -+ return DB_SUCCESS; -+} -+ -+int dbenv_close(DB_ENV *dbenv, int flags) -+{ -+ slapi_ch_free_string(&dbenv->db_home); -+ slapi_ch_free((void**)&dbenv); -+ return DB_SUCCESS; -+} -+ -+char *db_strerror(int err) -+{ -+ switch (err) { -+ case DB_SUCCESS: -+ return (char*)"DB_SUCCESS"; -+ case DB_LOCK_DEADLOCK: -+ return (char*)"DB_LOCK_DEADLOCK"; -+ case DB_NOTFOUND: -+ return (char*)"DB_NOTFOUND"; -+ case DB_BUFFER_SMALL: -+ return (char*)"DB_BUFFER_SMALL"; -+ case DB_KEYEXIST: -+ return (char*)"DB_KEYEXIST"; -+ case DB_RUNRECOVERY: -+ return (char*)"DB_RUNRECOVERY"; -+ case DB_NOTSUPPORTED: -+ return (char*)"DB_NOTSUPPORTED"; -+ default: -+ return (char*)"Unknonwn error"; -+ } -+} -+ -+/* lg_dir is used to store the database directory */ -+static void -+db_set_lg_dir(DB_ENV *penv, const char *lg_dir) -+{ -+ penv->db_home = slapi_ch_strdup(lg_dir); -+} -+ -+int db_env_create(DB_ENV **penv, u_int32_t flags) -+{ -+ DB_ENV *env = (void*)slapi_ch_calloc(1, sizeof *env); -+ -+ env->close = dbenv_close; -+ env->lock_detect = (void*)nothing; -+ env->open = dbenv_open; -+ env->remove = (void*)nothing; -+ env->set_flags = (void*)nothing; -+ env->set_verbose = (void*)nothing; -+ env->txn_checkpoint = (void*)nothing; -+ env->txn_begin = (void*)nothing; -+ env->get_open_flags = (void*)nothing; -+ env->mutex_set_tas_spins = (void*)nothing; -+ env->set_alloc = (void*)nothing; -+ env->set_cachesize = (void*)nothing; -+ env->set_data_dir = (void*)nothing; -+ env->set_errcall = (void*)nothing; -+ env->set_errpfx = (void*)nothing; -+ env->set_lg_bsize = (void*)nothing; -+ env->set_lg_dir = db_set_lg_dir; -+ env->set_lg_max = (void*)nothing; -+ env->set_lg_regionmax = (void*)nothing; -+ env->set_lk_max_lockers = (void*)nothing; -+ env->set_lk_max_locks = (void*)nothing; -+ env->set_lk_max_objects = (void*)nothing; -+ env->set_shm_key = (void*)nothing; -+ env->set_tx_max = (void*)nothing; -+ env->log_flush = (void*)nothing; -+ env->lock_stat = (void*)nothing; -+ env->log_archive = (void*)nothing; -+ env->memp_stat = (void*)nothing; -+ env->memp_trickle = (void*)nothing; -+ env->dbrename = (void*)nothing; -+ env->stat = (void*)nothing; -+ env->log_stat = (void*)nothing; -+ env->txn_stat = (void*)nothing; -+ *penv = env; -+ return DB_SUCCESS; -+} -+ -+int db_open(DB *db, DB_TXN *txnid, const char *file, -+ const char *database, DBTYPE type, u_int32_t flags, int mode) -+{ -+ slapi_log_err(SLAPI_LOG_INFO, "bdb_ro", "%s: db=%p txnid=%p file=%s database=%s " -+ "type=0x%x flags=0x%x mode=0x%x\n", __FUNCTION__, db, -+ txnid, file, database, type, flags, mode); -+ if (*file == '/') { -+ db->fname = slapi_ch_strdup(file); -+ } else { -+ slapi_log_err(SLAPI_LOG_ERR, "bdb_ro", -+ "%s: db_home=%s\n", __FUNCTION__, db->env->db_home); -+ db->fname = slapi_ch_smprintf("%s/%s", db->env->db_home, file); -+ } -+ slapi_log_err(SLAPI_LOG_ERR, "bdb_ro", "%s: db->fname=%s\n", __FUNCTION__, db->fname); -+ db->impl = bdbreader_bdb_open(db->fname); -+ db->open_flags = OPEN_FLAGS_OPEN; -+ if (db->impl) { -+ if (db_cursor(db, NULL, &db->cur, 0) != DB_SUCCESS) { -+ slapi_log_err(SLAPI_LOG_ERR, "bdb_ro", -+ "%s: Failed to create cursor for %s database\n", -+ __FUNCTION__, db->fname); -+ db_close(db, flags); -+ return DB_OSERROR; -+ } -+ return DB_SUCCESS; -+ } -+ slapi_log_err(SLAPI_LOG_ERR, "bdb_ro", -+ "%s: Failed to open %s database\n", __FUNCTION__, db->fname); -+ return DB_OSERROR; -+} -+ -+int db_close(DB *db, u_int32_t flags) -+{ -+ bdbreader_bdb_close((struct bdb_db **)&db->impl); -+ db->impl = NULL; -+ db->open_flags = OPEN_FLAGS_CLOSED; -+ dbc_close(db->cur); -+ slapi_ch_free_string(&db->fname); -+ slapi_ch_free((void**)&db); -+ return DB_SUCCESS; -+} -+ -+int dbc_close(DBC *dbc) -+{ -+ slapi_log_err(SLAPI_LOG_INFO, "bdb_ro", "%s: dbc=%p dbc->impl=%p\n", __FUNCTION__, dbc, dbc->impl); -+ bdbreader_cur_close((struct bdb_cur **)&dbc->impl); -+ slapi_ch_free((void **)&dbc); -+ return DB_SUCCESS; -+} -+ -+int dbc_del(DBC *dbc, u_int32_t flags) -+{ -+ return DB_NOTSUPPORTED; -+} -+ -+int copy_val(const DBT *from, DBT *to) -+{ -+ switch (to->flags) { -+ case DB_DBT_MALLOC: -+ to->size = from->size; -+ if (from->data == NULL) { -+ to->data = NULL; -+ } else if (from->size > 0) { -+ to->data = slapi_ch_malloc(from->size); -+ memcpy(to->data, from->data, from->size); -+ } -+ return DB_SUCCESS; -+ case DB_DBT_REALLOC: -+ to->size = from->size; -+ if (from->data == NULL) { -+ to->data = NULL; -+ } else if (from->size > 0) { -+ to->data = slapi_ch_realloc(to->data, from->size); -+ memcpy(to->data, from->data, from->size); -+ } -+ return DB_SUCCESS; -+ case DB_DBT_USERMEM: -+ to->size = from->size; -+ if (from->size > to->ulen) { -+ return DB_BUFFER_SMALL; -+ } -+ memcpy(to->data, from->data, from->size); -+ return DB_SUCCESS; -+ } -+ return DB_NOTSUPPORTED; -+} -+ -+ -+int store_val(int rc, DBC *dbc, DBT *key, DBT *data) -+{ -+ DBT k1 = {0}; -+ DBT d1 = {0}; -+ -+ if (rc == DB_SUCCESS) { -+ rc = bdbreader_cur_getcurval(dbc->impl, &k1.data, &k1.size, &d1.data, &d1.size); -+ } -+ if (rc == DB_SUCCESS) { -+ rc = copy_val(&k1, key); -+ } -+ if (rc == DB_SUCCESS) { -+ rc = copy_val(&d1, data); -+ } -+ return rc; -+} -+ -+ -+int dbc_get(DBC *dbc, DBT *key, DBT *data, u_int32_t flags) -+{ -+ static const char *flagnames[] = { -+ "0", "DB_FIRST", "DB_CURRENT", "DB_GET_BOTH", "DB_GET_BOTH_RANGE", -+ "DB_GET_RECNO", "DB_LAST", "DB_NEXT", "DB_NEXT_DUP", "DB_NEXT_NODUP", -+ "DB_NODUPDATA", "DB_PREV", "DB_SET", "DB_SET_RANGE", "DB_SET_RECNO", -+ "DB_UNKNOWN" }; -+ static const char *errname[] = { -+ "DB_SUCCESS", "DB_NOTFOUND", "DB_BUFFER_SMALL", -+ "DB_KEYEXIST", "DB_RUNRECOVERY", "DB_NOTSUPPORTED", "DB_LOCK_DEADLOCK", "DB_OSERROR" }; -+ -+ slapi_log_err(SLAPI_LOG_ERR, "bdb_ro", "==> dbc_get(key=%s flags=%d:%s)\n", LOGK(key), flags, LOGN(flags, flagnames)); -+ -+ int rc = DB_NOTSUPPORTED; -+ DBT k1 = {0}; -+ DBT d1 = {0}; -+ -+ switch (flags) { -+ case DB_FIRST: -+ rc = bdbreader_cur_lookup_ge(dbc->impl, NULL, 0); -+ if (rc == DB_NOTFOUND) { -+ rc = bdbreader_cur_next(dbc->impl); -+ } -+ rc = store_val(rc, dbc, key, data); -+ break; -+ case DB_CURRENT: -+ rc = store_val(rc, dbc, key, data); -+ break; -+ case DB_GET_BOTH: -+ break; -+ case DB_GET_BOTH_RANGE: -+ break; -+ case DB_GET_RECNO: -+ break; -+ case DB_LAST: -+ rc = DB_SUCCESS; -+ while (rc == DB_SUCCESS) { -+ rc = bdbreader_cur_next(dbc->impl); -+ if (rc == DB_SUCCESS) { -+ rc = bdbreader_cur_getcurval(dbc->impl, &k1.data, &k1.size, &d1.data, &d1.size); -+ } -+ if (rc == DB_NOTFOUND) { -+ rc = copy_val(&k1, key) | copy_val(&d1, data); -+ break; -+ } -+ } -+ break; -+ case DB_NEXT: -+ rc = bdbreader_cur_next(dbc->impl); -+ rc = store_val(rc, dbc, key, data); -+ break; -+ case DB_NEXT_DUP: -+ rc = bdbreader_cur_next(dbc->impl); -+ if (rc == DB_SUCCESS) { -+ rc = bdbreader_cur_getcurval(dbc->impl, &k1.data, &k1.size, NULL, NULL); -+ if (rc == DB_SUCCESS) { -+ if (k1.size == key->size && memcmp(k1.data, key->data, k1.size) == 0) { -+ rc = store_val(rc, dbc, key, data); -+ } else { -+ rc = DB_NOTFOUND; -+ } -+ } -+ } -+ break; -+ case DB_NEXT_NODUP: -+ rc = DB_SUCCESS; -+ while (rc == DB_SUCCESS) { -+ rc = bdbreader_cur_next(dbc->impl); -+ if (rc == DB_SUCCESS) { -+ rc = bdbreader_cur_getcurval(dbc->impl, &k1.data, &k1.size, NULL, NULL); -+ } -+ if (k1.size != key->size || memcmp(k1.data, key->data, k1.size) != 0) { -+ rc = store_val(rc, dbc, key, data); -+ break; -+ } -+ } -+ break; -+ case DB_NODUPDATA: -+ break; -+ case DB_PREV: -+ break; -+ case 0: -+ /* _get_and_add_parent_rdns set the flags ==> probably a bug -+ * (according BDB C API) -+ * But lets assume it is a DB_SET -+ */ -+ case DB_SET: -+ rc = bdbreader_cur_lookup(dbc->impl, key->data, key->size); -+ rc = store_val(rc, dbc, key, data); -+ break; -+ case DB_SET_RANGE: -+ rc = bdbreader_cur_lookup_ge(dbc->impl, key->data, key->size); -+ rc = store_val(rc, dbc, key, data); -+ break; -+ case DB_SET_RECNO: -+ break; -+ } -+ -+ slapi_log_err(SLAPI_LOG_ERR, "bdb_ro", "==> dbc_get(flags=%d:%s) rc=%d:%s\n", -+ flags, LOGN(flags, flagnames), rc, LOGN(rc, errname)); -+ if (key && key->data && key->size) { -+ hexadump("Key", key->data, 0, key->size); -+ } -+ if (data && data->data && data->size) { -+ hexadump("Data", data->data, 0, data->size); -+ } -+ return rc; -+} -+ -+int dbc_put(DBC *dbc, DBT *key, DBT *data, u_int32_t flags) -+{ -+ return DB_NOTSUPPORTED; -+} -+ -+int dbc_count(DBC *dbc, void *countp, u_int32_t flags) -+{ -+ return DB_NOTSUPPORTED; -+} -+ -+int db_cursor(DB *db, DB_TXN *txnid, DBC **cursorp, u_int32_t flags) -+{ -+ DBC *dbc = (void*)slapi_ch_calloc(1, sizeof *dbc); -+ -+ *cursorp = dbc; -+ dbc->dbp = db; -+ -+ dbc->c_close = dbc_close; -+ dbc->c_del = dbc_del; -+ dbc->c_get = dbc_get; -+ dbc->c_put = dbc_put; -+ dbc->c_count = dbc_count; -+ dbc->impl = bdbreader_cur_open(db->impl); -+ -+ slapi_log_err(SLAPI_LOG_INFO, "bdb_ro", "%s: dbc=%p dbc->impl=%p\n", __FUNCTION__, dbc, dbc->impl); -+ return (db->impl == NULL) ? DB_OSERROR : DB_SUCCESS; -+} -+ -+int db_del(DB *db, DB_TXN *txnid, DBT *key, u_int32_t flags) -+{ -+ return DB_NOTSUPPORTED; -+} -+ -+int db_put(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags) -+{ -+ return DB_NOTSUPPORTED; -+} -+ -+int db_get(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags) -+{ -+ int rc = bdbreader_cur_lookup(db->cur->impl, key->data, key->size); -+ if (rc == DB_SUCCESS) { -+ rc = dbc_get(db->cur, key, data, flags); -+ } -+ return rc; -+} -+ -+int db_create(DB **pdb, DB_ENV *env, u_int32_t flags) -+{ -+ DB *db = (void*)slapi_ch_calloc(1, sizeof *db); -+ db->close = db_close; -+ db->compact = (void*)nothing; -+ db->cursor = db_cursor; -+ db->del = db_del; -+ db->get = db_get; -+ db->open = db_open; -+ db->put = db_put; -+ db->remove = (void*)nothing; -+ db->rename = (void*)nothing; -+ db->set_bt_compare = (void*)nothing; -+ db->set_dup_compare = (void*)nothing; -+ db->set_flags = (void*)nothing; -+ db->set_pagesize = (void*)nothing; -+ db->verify = (void*)nothing; -+ db->get_type = (void*)nothing; -+ db->stat = (void*)nothing; -+ db->env = env; -+ db->open_flags = OPEN_FLAGS_CLOSED; -+ *pdb = db; -+ return DB_SUCCESS; -+} -diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h -index 0be6cab49..24c4b0621 100644 ---- a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h -+++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h -@@ -10,7 +10,12 @@ - #include "../back-ldbm.h" - #include "../dblayer.h" - #include "../import.h" -+#ifdef WITH_LIBBDB_RO -+#include "bdb_bdbreader_db.h" -+#else - #include -+#endif -+ - - #define BDB_CONFIG(li) ((bdb_config *)(li)->li_dblayer_config) - -diff --git a/ldap/servers/slapd/back-ldbm/dbimpl.c b/ldap/servers/slapd/back-ldbm/dbimpl.c -index f3bf68a9f..f00779c3c 100644 ---- a/ldap/servers/slapd/back-ldbm/dbimpl.c -+++ b/ldap/servers/slapd/back-ldbm/dbimpl.c -@@ -454,6 +454,7 @@ int dblayer_private_open(const char *plgname, const char *dbfilename, int rw, Sl - li->li_plugin->plg_name = (char*) "back-ldbm-dbimpl"; - li->li_plugin->plg_libpath = (char*) "libback-ldbm"; - li->li_directory = get_li_directory(dbfilename); -+ li->li_flags = SLAPI_TASK_RUNNING_FROM_COMMANDLINE; - - /* Initialize database plugin */ - rc = dbimpl_setup(li, plgname); -@@ -541,6 +542,10 @@ dbi_dbslist_t *dblayer_list_dbs(const char *dbimpl_name, const char *dbhome) - li->li_plugin->plg_name = (char*) "back-ldbm-dbimpl"; - li->li_plugin->plg_libpath = (char*) "libback-ldbm"; - li->li_directory = slapi_ch_strdup(dbhome); -+ /* Set SLAPI_TASK_RUNNING_FROM_COMMANDLINE to tell that -+ * read-only bdb is usable with dbscan -+ */ -+ li->li_flags |= SLAPI_TASK_RUNNING_FROM_COMMANDLINE; - - /* Initialize database plugin */ - rc = dbimpl_setup(li, dbimpl_name); -diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c -index a47846c50..d45d5b0e4 100644 ---- a/ldap/servers/slapd/back-ldbm/dblayer.c -+++ b/ldap/servers/slapd/back-ldbm/dblayer.c -@@ -164,8 +164,21 @@ dblayer_init(struct ldbminfo *li) - return ret; - } - -- -- -+/* Check that export locking file is not set */ -+static bool -+not_exporting(void) -+{ -+ pid_t pid = getpid(); -+ struct stat astat; -+ bool res = true; -+ char *export_lock = slapi_ch_smprintf("%s/exports/%d", getFrontendConfig()->lockdir, pid); -+ if (stat(export_lock, &astat) == 0) { -+ res = false; -+ } -+ slapi_ch_free_string(&export_lock); -+ return res; -+} -+ - /* Get the db implementation plugin path (either libback-ldbm.so or libback-bdb.so) */ - char * - backend_implement_get_libpath(struct ldbminfo *li, const char *plgname) -@@ -177,6 +190,19 @@ backend_implement_get_libpath(struct ldbminfo *li, const char *plgname) - /* mdb ==> lets use default (libback-ldbm.so) */ - return li->li_plugin->plg_libpath; - } -+ if (PR_FindSymbolAndLibrary("bdbreader_bdb_open", &lib)) { -+ /* read-only bdb is used ==> should be using dbscan or ns-slapd db2ldif -+ * bdb_init is within libback-ldbm.so ==> lets use default (libback-ldbm.so) -+ */ -+ if (((li->li_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE) == 0) && not_exporting()) { -+ slapi_log_error(SLAPI_LOG_FATAL, "dblayer_setup", -+ "bdb implementation is no longer supported." -+ " Directory server cannot be started without migrating to lmdb first." -+ " To migrate, please run: dsctl instanceName dblib bdb2mdb\n"); -+ exit(1); -+ } -+ return li->li_plugin->plg_libpath; -+ } - if (PR_FindSymbolAndLibrary("bdb_init", &lib)) { - /* bdb_init is within libback-ldbm.so ==> lets use default (libback-ldbm.so) */ - return li->li_plugin->plg_libpath; -@@ -1462,9 +1488,9 @@ dblayer_is_lmdb(Slapi_Backend *be) - } - - /* -- * Iterate on the provided curor starting at startingkey (or first key if -+ * Iterate on the provided curor starting at startingkey (or first key if - * startingkey is NULL) and call action_cb for each records -- * -+ * - * action_cb callback returns: - * DBI_RC_SUCCESS to iterate on next entry - * DBI_RC_NOTFOUND to stop iteration with DBI_RC_SUCCESS code -diff --git a/ldap/servers/slapd/protect_db.c b/ldap/servers/slapd/protect_db.c -index eb61e0a23..6ea311b87 100644 ---- a/ldap/servers/slapd/protect_db.c -+++ b/ldap/servers/slapd/protect_db.c -@@ -424,6 +424,10 @@ add_new_slapd_process(int exec_mode, int r_flag, int skip_flag) - * but it in the importing dir so no other process can change - * things while we are doing ldif2db with the -r flag. */ - add_this_process_to(import_dir); -+ /* But also add the process in export_dir to differenciate -+ * from and import task -+ */ -+ add_this_process_to(export_dir); - result = 0; - } - } else { -diff --git a/lib/librobdb/COPYING b/lib/librobdb/COPYING -new file mode 100644 -index 000000000..ac042d4a4 ---- /dev/null -+++ b/lib/librobdb/COPYING -@@ -0,0 +1,8 @@ -+ -+The library code in -+https://github.com/389ds/389-ds-base/lib/librobdb is derivated from RPM project -+ https://github.com/rpm-software-management/rpm project -+As it is derivated from the RPM lib code, this code may be either distributed -+under the terms of the GNU General Public License (GPL) or under the GNU -+Library General Public License (LGPL). -+The complete text of both licenses are in COPYING.RPM, the RPM license file -diff --git a/lib/librobdb/COPYING.RPM b/lib/librobdb/COPYING.RPM -new file mode 100644 -index 000000000..f153e80b7 ---- /dev/null -+++ b/lib/librobdb/COPYING.RPM -@@ -0,0 +1,848 @@ -+libbdbro is derived from RPM lib -+(See https://github.com/rpm-software-management/rpm/) -+so the following RPM license apply by replacing "RPM" by "libbdbreader" -+ -+--------------------------------------------------------------------------- -+ -+ -+ -+RPM is covered under two separate licenses. -+ -+The entire code base may be distributed under the terms of the GNU General -+Public License (GPL), which appears immediately below. Alternatively, -+all of the source code in the lib and rpmio subdirectories of the RPM source -+code distribution as well as any code derived from that code may instead be -+distributed under the GNU Library General Public License (LGPL), at the -+choice of the distributor. The complete text of the LGPL appears -+at the bottom of this file. -+ -+This alternative is provided to enable applications to be linked against -+the RPM library (commonly called librpm) without forcing such applications -+to be distributed under the GPL. -+ -+Any questions regarding the licensing of RPM should be addressed to -+rpm-maint@lists.rpm.org -+ -+--------------------------------------------------------------------------- -+ -+ GNU GENERAL PUBLIC LICENSE -+ Version 2, June 1991 -+ -+ Copyright (C) 1989, 1991 Free Software Foundation, Inc., -+ -+ Everyone is permitted to copy and distribute verbatim copies -+ of this license document, but changing it is not allowed. -+ -+ Preamble -+ -+ The licenses for most software are designed to take away your -+freedom to share and change it. By contrast, the GNU General Public -+License is intended to guarantee your freedom to share and change free -+software--to make sure the software is free for all its users. This -+General Public License applies to most of the Free Software -+Foundation's software and to any other program whose authors commit to -+using it. (Some other Free Software Foundation software is covered by -+the GNU Lesser General Public License instead.) You can apply it to -+your programs, too. -+ -+ When we speak of free software, we are referring to freedom, not -+price. Our General Public Licenses are designed to make sure that you -+have the freedom to distribute copies of free software (and charge for -+this service if you wish), that you receive source code or can get it -+if you want it, that you can change the software or use pieces of it -+in new free programs; and that you know you can do these things. -+ -+ To protect your rights, we need to make restrictions that forbid -+anyone to deny you these rights or to ask you to surrender the rights. -+These restrictions translate to certain responsibilities for you if you -+distribute copies of the software, or if you modify it. -+ -+ For example, if you distribute copies of such a program, whether -+gratis or for a fee, you must give the recipients all the rights that -+you have. You must make sure that they, too, receive or can get the -+source code. And you must show them these terms so they know their -+rights. -+ -+ We protect your rights with two steps: (1) copyright the software, and -+(2) offer you this license which gives you legal permission to copy, -+distribute and/or modify the software. -+ -+ Also, for each author's protection and ours, we want to make certain -+that everyone understands that there is no warranty for this free -+software. If the software is modified by someone else and passed on, we -+want its recipients to know that what they have is not the original, so -+that any problems introduced by others will not reflect on the original -+authors' reputations. -+ -+ Finally, any free program is threatened constantly by software -+patents. We wish to avoid the danger that redistributors of a free -+program will individually obtain patent licenses, in effect making the -+program proprietary. To prevent this, we have made it clear that any -+patent must be licensed for everyone's free use or not licensed at all. -+ -+ The precise terms and conditions for copying, distribution and -+modification follow. -+ -+ GNU GENERAL PUBLIC LICENSE -+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -+ -+ 0. This License applies to any program or other work which contains -+a notice placed by the copyright holder saying it may be distributed -+under the terms of this General Public License. The "Program", below, -+refers to any such program or work, and a "work based on the Program" -+means either the Program or any derivative work under copyright law: -+that is to say, a work containing the Program or a portion of it, -+either verbatim or with modifications and/or translated into another -+language. (Hereinafter, translation is included without limitation in -+the term "modification".) Each licensee is addressed as "you". -+ -+Activities other than copying, distribution and modification are not -+covered by this License; they are outside its scope. The act of -+running the Program is not restricted, and the output from the Program -+is covered only if its contents constitute a work based on the -+Program (independent of having been made by running the Program). -+Whether that is true depends on what the Program does. -+ -+ 1. You may copy and distribute verbatim copies of the Program's -+source code as you receive it, in any medium, provided that you -+conspicuously and appropriately publish on each copy an appropriate -+copyright notice and disclaimer of warranty; keep intact all the -+notices that refer to this License and to the absence of any warranty; -+and give any other recipients of the Program a copy of this License -+along with the Program. -+ -+You may charge a fee for the physical act of transferring a copy, and -+you may at your option offer warranty protection in exchange for a fee. -+ -+ 2. You may modify your copy or copies of the Program or any portion -+of it, thus forming a work based on the Program, and copy and -+distribute such modifications or work under the terms of Section 1 -+above, provided that you also meet all of these conditions: -+ -+ a) You must cause the modified files to carry prominent notices -+ stating that you changed the files and the date of any change. -+ -+ b) You must cause any work that you distribute or publish, that in -+ whole or in part contains or is derived from the Program or any -+ part thereof, to be licensed as a whole at no charge to all third -+ parties under the terms of this License. -+ -+ c) If the modified program normally reads commands interactively -+ when run, you must cause it, when started running for such -+ interactive use in the most ordinary way, to print or display an -+ announcement including an appropriate copyright notice and a -+ notice that there is no warranty (or else, saying that you provide -+ a warranty) and that users may redistribute the program under -+ these conditions, and telling the user how to view a copy of this -+ License. (Exception: if the Program itself is interactive but -+ does not normally print such an announcement, your work based on -+ the Program is not required to print an announcement.) -+ -+These requirements apply to the modified work as a whole. If -+identifiable sections of that work are not derived from the Program, -+and can be reasonably considered independent and separate works in -+themselves, then this License, and its terms, do not apply to those -+sections when you distribute them as separate works. But when you -+distribute the same sections as part of a whole which is a work based -+on the Program, the distribution of the whole must be on the terms of -+this License, whose permissions for other licensees extend to the -+entire whole, and thus to each and every part regardless of who wrote it. -+ -+Thus, it is not the intent of this section to claim rights or contest -+your rights to work written entirely by you; rather, the intent is to -+exercise the right to control the distribution of derivative or -+collective works based on the Program. -+ -+In addition, mere aggregation of another work not based on the Program -+with the Program (or with a work based on the Program) on a volume of -+a storage or distribution medium does not bring the other work under -+the scope of this License. -+ -+ 3. You may copy and distribute the Program (or a work based on it, -+under Section 2) in object code or executable form under the terms of -+Sections 1 and 2 above provided that you also do one of the following: -+ -+ a) Accompany it with the complete corresponding machine-readable -+ source code, which must be distributed under the terms of Sections -+ 1 and 2 above on a medium customarily used for software interchange; or, -+ -+ b) Accompany it with a written offer, valid for at least three -+ years, to give any third party, for a charge no more than your -+ cost of physically performing source distribution, a complete -+ machine-readable copy of the corresponding source code, to be -+ distributed under the terms of Sections 1 and 2 above on a medium -+ customarily used for software interchange; or, -+ -+ c) Accompany it with the information you received as to the offer -+ to distribute corresponding source code. (This alternative is -+ allowed only for noncommercial distribution and only if you -+ received the program in object code or executable form with such -+ an offer, in accord with Subsection b above.) -+ -+The source code for a work means the preferred form of the work for -+making modifications to it. For an executable work, complete source -+code means all the source code for all modules it contains, plus any -+associated interface definition files, plus the scripts used to -+control compilation and installation of the executable. However, as a -+special exception, the source code distributed need not include -+anything that is normally distributed (in either source or binary -+form) with the major components (compiler, kernel, and so on) of the -+operating system on which the executable runs, unless that component -+itself accompanies the executable. -+ -+If distribution of executable or object code is made by offering -+access to copy from a designated place, then offering equivalent -+access to copy the source code from the same place counts as -+distribution of the source code, even though third parties are not -+compelled to copy the source along with the object code. -+ -+ 4. You may not copy, modify, sublicense, or distribute the Program -+except as expressly provided under this License. Any attempt -+otherwise to copy, modify, sublicense or distribute the Program is -+void, and will automatically terminate your rights under this License. -+However, parties who have received copies, or rights, from you under -+this License will not have their licenses terminated so long as such -+parties remain in full compliance. -+ -+ 5. You are not required to accept this License, since you have not -+signed it. However, nothing else grants you permission to modify or -+distribute the Program or its derivative works. These actions are -+prohibited by law if you do not accept this License. Therefore, by -+modifying or distributing the Program (or any work based on the -+Program), you indicate your acceptance of this License to do so, and -+all its terms and conditions for copying, distributing or modifying -+the Program or works based on it. -+ -+ 6. Each time you redistribute the Program (or any work based on the -+Program), the recipient automatically receives a license from the -+original licensor to copy, distribute or modify the Program subject to -+these terms and conditions. You may not impose any further -+restrictions on the recipients' exercise of the rights granted herein. -+You are not responsible for enforcing compliance by third parties to -+this License. -+ -+ 7. If, as a consequence of a court judgment or allegation of patent -+infringement or for any other reason (not limited to patent issues), -+conditions are imposed on you (whether by court order, agreement or -+otherwise) that contradict the conditions of this License, they do not -+excuse you from the conditions of this License. If you cannot -+distribute so as to satisfy simultaneously your obligations under this -+License and any other pertinent obligations, then as a consequence you -+may not distribute the Program at all. For example, if a patent -+license would not permit royalty-free redistribution of the Program by -+all those who receive copies directly or indirectly through you, then -+the only way you could satisfy both it and this License would be to -+refrain entirely from distribution of the Program. -+ -+If any portion of this section is held invalid or unenforceable under -+any particular circumstance, the balance of the section is intended to -+apply and the section as a whole is intended to apply in other -+circumstances. -+ -+It is not the purpose of this section to induce you to infringe any -+patents or other property right claims or to contest validity of any -+such claims; this section has the sole purpose of protecting the -+integrity of the free software distribution system, which is -+implemented by public license practices. Many people have made -+generous contributions to the wide range of software distributed -+through that system in reliance on consistent application of that -+system; it is up to the author/donor to decide if he or she is willing -+to distribute software through any other system and a licensee cannot -+impose that choice. -+ -+This section is intended to make thoroughly clear what is believed to -+be a consequence of the rest of this License. -+ -+ 8. If the distribution and/or use of the Program is restricted in -+certain countries either by patents or by copyrighted interfaces, the -+original copyright holder who places the Program under this License -+may add an explicit geographical distribution limitation excluding -+those countries, so that distribution is permitted only in or among -+countries not thus excluded. In such case, this License incorporates -+the limitation as if written in the body of this License. -+ -+ 9. The Free Software Foundation may publish revised and/or new versions -+of the General Public License from time to time. Such new versions will -+be similar in spirit to the present version, but may differ in detail to -+address new problems or concerns. -+ -+Each version is given a distinguishing version number. If the Program -+specifies a version number of this License which applies to it and "any -+later version", you have the option of following the terms and conditions -+either of that version or of any later version published by the Free -+Software Foundation. If the Program does not specify a version number of -+this License, you may choose any version ever published by the Free Software -+Foundation. -+ -+ 10. If you wish to incorporate parts of the Program into other free -+programs whose distribution conditions are different, write to the author -+to ask for permission. For software which is copyrighted by the Free -+Software Foundation, write to the Free Software Foundation; we sometimes -+make exceptions for this. Our decision will be guided by the two goals -+of preserving the free status of all derivatives of our free software and -+of promoting the sharing and reuse of software generally. -+ -+ NO WARRANTY -+ -+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -+REPAIR OR CORRECTION. -+ -+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -+POSSIBILITY OF SUCH DAMAGES. -+ -+ END OF TERMS AND CONDITIONS -+ -+ How to Apply These Terms to Your New Programs -+ -+ If you develop a new program, and you want it to be of the greatest -+possible use to the public, the best way to achieve this is to make it -+free software which everyone can redistribute and change under these terms. -+ -+ To do so, attach the following notices to the program. It is safest -+to attach them to the start of each source file to most effectively -+convey the exclusion of warranty; and each file should have at least -+the "copyright" line and a pointer to where the full notice is found. -+ -+ -+ Copyright (C) -+ -+ 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 . -+ -+Also add information on how to contact you by electronic and paper mail. -+ -+If the program is interactive, make it output a short notice like this -+when it starts in an interactive mode: -+ -+ Gnomovision version 69, Copyright (C) year name of author -+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. -+ This is free software, and you are welcome to redistribute it -+ under certain conditions; type `show c' for details. -+ -+The hypothetical commands `show w' and `show c' should show the appropriate -+parts of the General Public License. Of course, the commands you use may -+be called something other than `show w' and `show c'; they could even be -+mouse-clicks or menu items--whatever suits your program. -+ -+You should also get your employer (if you work as a programmer) or your -+school, if any, to sign a "copyright disclaimer" for the program, if -+necessary. Here is a sample; alter the names: -+ -+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program -+ `Gnomovision' (which makes passes at compilers) written by James Hacker. -+ -+ , 1 April 1989 -+ Moe Ghoul, President of Vice -+ -+This General Public License does not permit incorporating your program into -+proprietary programs. If your program is a subroutine library, you may -+consider it more useful to permit linking proprietary applications with the -+library. If this is what you want to do, use the GNU Lesser General -+Public License instead of this License. -+ -+--------------------------------------------------------------------------- -+ -+ GNU LIBRARY GENERAL PUBLIC LICENSE -+ Version 2, June 1991 -+ -+ Copyright (C) 1991 Free Software Foundation, Inc. -+ -+ Everyone is permitted to copy and distribute verbatim copies -+ of this license document, but changing it is not allowed. -+ -+[This is the first released version of the library GPL. It is -+ numbered 2 because it goes with version 2 of the ordinary GPL.] -+ -+ Preamble -+ -+ The licenses for most software are designed to take away your -+freedom to share and change it. By contrast, the GNU General Public -+Licenses are intended to guarantee your freedom to share and change -+free software--to make sure the software is free for all its users. -+ -+ This license, the Library General Public License, applies to some -+specially designated Free Software Foundation software, and to any -+other libraries whose authors decide to use it. You can use it for -+your libraries, too. -+ -+ When we speak of free software, we are referring to freedom, not -+price. Our General Public Licenses are designed to make sure that you -+have the freedom to distribute copies of free software (and charge for -+this service if you wish), that you receive source code or can get it -+if you want it, that you can change the software or use pieces of it -+in new free programs; and that you know you can do these things. -+ -+ To protect your rights, we need to make restrictions that forbid -+anyone to deny you these rights or to ask you to surrender the rights. -+These restrictions translate to certain responsibilities for you if -+you distribute copies of the library, or if you modify it. -+ -+ For example, if you distribute copies of the library, whether gratis -+or for a fee, you must give the recipients all the rights that we gave -+you. You must make sure that they, too, receive or can get the source -+code. If you link a program with the library, you must provide -+complete object files to the recipients so that they can relink them -+with the library, after making changes to the library and recompiling -+it. And you must show them these terms so they know their rights. -+ -+ Our method of protecting your rights has two steps: (1) copyright -+the library, and (2) offer you this license which gives you legal -+permission to copy, distribute and/or modify the library. -+ -+ Also, for each distributor's protection, we want to make certain -+that everyone understands that there is no warranty for this free -+library. If the library is modified by someone else and passed on, we -+want its recipients to know that what they have is not the original -+version, so that any problems introduced by others will not reflect on -+the original authors' reputations. -+ -+ Finally, any free program is threatened constantly by software -+patents. We wish to avoid the danger that companies distributing free -+software will individually obtain patent licenses, thus in effect -+transforming the program into proprietary software. To prevent this, -+we have made it clear that any patent must be licensed for everyone's -+free use or not licensed at all. -+ -+ Most GNU software, including some libraries, is covered by the ordinary -+GNU General Public License, which was designed for utility programs. This -+license, the GNU Library General Public License, applies to certain -+designated libraries. This license is quite different from the ordinary -+one; be sure to read it in full, and don't assume that anything in it is -+the same as in the ordinary license. -+ -+ The reason we have a separate public license for some libraries is that -+they blur the distinction we usually make between modifying or adding to a -+program and simply using it. Linking a program with a library, without -+changing the library, is in some sense simply using the library, and is -+analogous to running a utility program or application program. However, in -+a textual and legal sense, the linked executable is a combined work, a -+derivative of the original library, and the ordinary General Public License -+treats it as such. -+ -+ Because of this blurred distinction, using the ordinary General -+Public License for libraries did not effectively promote software -+sharing, because most developers did not use the libraries. We -+concluded that weaker conditions might promote sharing better. -+ -+ However, unrestricted linking of non-free programs would deprive the -+users of those programs of all benefit from the free status of the -+libraries themselves. This Library General Public License is intended to -+permit developers of non-free programs to use free libraries, while -+preserving your freedom as a user of such programs to change the free -+libraries that are incorporated in them. (We have not seen how to achieve -+this as regards changes in header files, but we have achieved it as regards -+changes in the actual functions of the Library.) The hope is that this -+will lead to faster development of free libraries. -+ -+ The precise terms and conditions for copying, distribution and -+modification follow. Pay close attention to the difference between a -+"work based on the library" and a "work that uses the library". The -+former contains code derived from the library, while the latter only -+works together with the library. -+ -+ Note that it is possible for a library to be covered by the ordinary -+General Public License rather than by this special one. -+ -+ GNU LIBRARY GENERAL PUBLIC LICENSE -+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -+ -+ 0. This License Agreement applies to any software library which -+contains a notice placed by the copyright holder or other authorized -+party saying it may be distributed under the terms of this Library -+General Public License (also called "this License"). Each licensee is -+addressed as "you". -+ -+ A "library" means a collection of software functions and/or data -+prepared so as to be conveniently linked with application programs -+(which use some of those functions and data) to form executables. -+ -+ The "Library", below, refers to any such software library or work -+which has been distributed under these terms. A "work based on the -+Library" means either the Library or any derivative work under -+copyright law: that is to say, a work containing the Library or a -+portion of it, either verbatim or with modifications and/or translated -+straightforwardly into another language. (Hereinafter, translation is -+included without limitation in the term "modification".) -+ -+ "Source code" for a work means the preferred form of the work for -+making modifications to it. For a library, complete source code means -+all the source code for all modules it contains, plus any associated -+interface definition files, plus the scripts used to control compilation -+and installation of the library. -+ -+ Activities other than copying, distribution and modification are not -+covered by this License; they are outside its scope. The act of -+running a program using the Library is not restricted, and output from -+such a program is covered only if its contents constitute a work based -+on the Library (independent of the use of the Library in a tool for -+writing it). Whether that is true depends on what the Library does -+and what the program that uses the Library does. -+ -+ 1. You may copy and distribute verbatim copies of the Library's -+complete source code as you receive it, in any medium, provided that -+you conspicuously and appropriately publish on each copy an -+appropriate copyright notice and disclaimer of warranty; keep intact -+all the notices that refer to this License and to the absence of any -+warranty; and distribute a copy of this License along with the -+Library. -+ -+ You may charge a fee for the physical act of transferring a copy, -+and you may at your option offer warranty protection in exchange for a -+fee. -+ -+ 2. You may modify your copy or copies of the Library or any portion -+of it, thus forming a work based on the Library, and copy and -+distribute such modifications or work under the terms of Section 1 -+above, provided that you also meet all of these conditions: -+ -+ a) The modified work must itself be a software library. -+ -+ b) You must cause the files modified to carry prominent notices -+ stating that you changed the files and the date of any change. -+ -+ c) You must cause the whole of the work to be licensed at no -+ charge to all third parties under the terms of this License. -+ -+ d) If a facility in the modified Library refers to a function or a -+ table of data to be supplied by an application program that uses -+ the facility, other than as an argument passed when the facility -+ is invoked, then you must make a good faith effort to ensure that, -+ in the event an application does not supply such function or -+ table, the facility still operates, and performs whatever part of -+ its purpose remains meaningful. -+ -+ (For example, a function in a library to compute square roots has -+ a purpose that is entirely well-defined independent of the -+ application. Therefore, Subsection 2d requires that any -+ application-supplied function or table used by this function must -+ be optional: if the application does not supply it, the square -+ root function must still compute square roots.) -+ -+These requirements apply to the modified work as a whole. If -+identifiable sections of that work are not derived from the Library, -+and can be reasonably considered independent and separate works in -+themselves, then this License, and its terms, do not apply to those -+sections when you distribute them as separate works. But when you -+distribute the same sections as part of a whole which is a work based -+on the Library, the distribution of the whole must be on the terms of -+this License, whose permissions for other licensees extend to the -+entire whole, and thus to each and every part regardless of who wrote -+it. -+ -+Thus, it is not the intent of this section to claim rights or contest -+your rights to work written entirely by you; rather, the intent is to -+exercise the right to control the distribution of derivative or -+collective works based on the Library. -+ -+In addition, mere aggregation of another work not based on the Library -+with the Library (or with a work based on the Library) on a volume of -+a storage or distribution medium does not bring the other work under -+the scope of this License. -+ -+ 3. You may opt to apply the terms of the ordinary GNU General Public -+License instead of this License to a given copy of the Library. To do -+this, you must alter all the notices that refer to this License, so -+that they refer to the ordinary GNU General Public License, version 2, -+instead of to this License. (If a newer version than version 2 of the -+ordinary GNU General Public License has appeared, then you can specify -+that version instead if you wish.) Do not make any other change in -+these notices. -+ -+ Once this change is made in a given copy, it is irreversible for -+that copy, so the ordinary GNU General Public License applies to all -+subsequent copies and derivative works made from that copy. -+ -+ This option is useful when you wish to copy part of the code of -+the Library into a program that is not a library. -+ -+ 4. You may copy and distribute the Library (or a portion or -+derivative of it, under Section 2) in object code or executable form -+under the terms of Sections 1 and 2 above provided that you accompany -+it with the complete corresponding machine-readable source code, which -+must be distributed under the terms of Sections 1 and 2 above on a -+medium customarily used for software interchange. -+ -+ If distribution of object code is made by offering access to copy -+from a designated place, then offering equivalent access to copy the -+source code from the same place satisfies the requirement to -+distribute the source code, even though third parties are not -+compelled to copy the source along with the object code. -+ -+ 5. A program that contains no derivative of any portion of the -+Library, but is designed to work with the Library by being compiled or -+linked with it, is called a "work that uses the Library". Such a -+work, in isolation, is not a derivative work of the Library, and -+therefore falls outside the scope of this License. -+ -+ However, linking a "work that uses the Library" with the Library -+creates an executable that is a derivative of the Library (because it -+contains portions of the Library), rather than a "work that uses the -+library". The executable is therefore covered by this License. -+Section 6 states terms for distribution of such executables. -+ -+ When a "work that uses the Library" uses material from a header file -+that is part of the Library, the object code for the work may be a -+derivative work of the Library even though the source code is not. -+Whether this is true is especially significant if the work can be -+linked without the Library, or if the work is itself a library. The -+threshold for this to be true is not precisely defined by law. -+ -+ If such an object file uses only numerical parameters, data -+structure layouts and accessors, and small macros and small inline -+functions (ten lines or less in length), then the use of the object -+file is unrestricted, regardless of whether it is legally a derivative -+work. (Executables containing this object code plus portions of the -+Library will still fall under Section 6.) -+ -+ Otherwise, if the work is a derivative of the Library, you may -+distribute the object code for the work under the terms of Section 6. -+Any executables containing that work also fall under Section 6, -+whether or not they are linked directly with the Library itself. -+ -+ 6. As an exception to the Sections above, you may also compile or -+link a "work that uses the Library" with the Library to produce a -+work containing portions of the Library, and distribute that work -+under terms of your choice, provided that the terms permit -+modification of the work for the customer's own use and reverse -+engineering for debugging such modifications. -+ -+ You must give prominent notice with each copy of the work that the -+Library is used in it and that the Library and its use are covered by -+this License. You must supply a copy of this License. If the work -+during execution displays copyright notices, you must include the -+copyright notice for the Library among them, as well as a reference -+directing the user to the copy of this License. Also, you must do one -+of these things: -+ -+ a) Accompany the work with the complete corresponding -+ machine-readable source code for the Library including whatever -+ changes were used in the work (which must be distributed under -+ Sections 1 and 2 above); and, if the work is an executable linked -+ with the Library, with the complete machine-readable "work that -+ uses the Library", as object code and/or source code, so that the -+ user can modify the Library and then relink to produce a modified -+ executable containing the modified Library. (It is understood -+ that the user who changes the contents of definitions files in the -+ Library will not necessarily be able to recompile the application -+ to use the modified definitions.) -+ -+ b) Accompany the work with a written offer, valid for at -+ least three years, to give the same user the materials -+ specified in Subsection 6a, above, for a charge no more -+ than the cost of performing this distribution. -+ -+ c) If distribution of the work is made by offering access to copy -+ from a designated place, offer equivalent access to copy the above -+ specified materials from the same place. -+ -+ d) Verify that the user has already received a copy of these -+ materials or that you have already sent this user a copy. -+ -+ For an executable, the required form of the "work that uses the -+Library" must include any data and utility programs needed for -+reproducing the executable from it. However, as a special exception, -+the source code distributed need not include anything that is normally -+distributed (in either source or binary form) with the major -+components (compiler, kernel, and so on) of the operating system on -+which the executable runs, unless that component itself accompanies -+the executable. -+ -+ It may happen that this requirement contradicts the license -+restrictions of other proprietary libraries that do not normally -+accompany the operating system. Such a contradiction means you cannot -+use both them and the Library together in an executable that you -+distribute. -+ -+ 7. You may place library facilities that are a work based on the -+Library side-by-side in a single library together with other library -+facilities not covered by this License, and distribute such a combined -+library, provided that the separate distribution of the work based on -+the Library and of the other library facilities is otherwise -+permitted, and provided that you do these two things: -+ -+ a) Accompany the combined library with a copy of the same work -+ based on the Library, uncombined with any other library -+ facilities. This must be distributed under the terms of the -+ Sections above. -+ -+ b) Give prominent notice with the combined library of the fact -+ that part of it is a work based on the Library, and explaining -+ where to find the accompanying uncombined form of the same work. -+ -+ 8. You may not copy, modify, sublicense, link with, or distribute -+the Library except as expressly provided under this License. Any -+attempt otherwise to copy, modify, sublicense, link with, or -+distribute the Library is void, and will automatically terminate your -+rights under this License. However, parties who have received copies, -+or rights, from you under this License will not have their licenses -+terminated so long as such parties remain in full compliance. -+ -+ 9. You are not required to accept this License, since you have not -+signed it. However, nothing else grants you permission to modify or -+distribute the Library or its derivative works. These actions are -+prohibited by law if you do not accept this License. Therefore, by -+modifying or distributing the Library (or any work based on the -+Library), you indicate your acceptance of this License to do so, and -+all its terms and conditions for copying, distributing or modifying -+the Library or works based on it. -+ -+ 10. Each time you redistribute the Library (or any work based on the -+Library), the recipient automatically receives a license from the -+original licensor to copy, distribute, link with or modify the Library -+subject to these terms and conditions. You may not impose any further -+restrictions on the recipients' exercise of the rights granted herein. -+You are not responsible for enforcing compliance by third parties to -+this License. -+ -+ 11. If, as a consequence of a court judgment or allegation of patent -+infringement or for any other reason (not limited to patent issues), -+conditions are imposed on you (whether by court order, agreement or -+otherwise) that contradict the conditions of this License, they do not -+excuse you from the conditions of this License. If you cannot -+distribute so as to satisfy simultaneously your obligations under this -+License and any other pertinent obligations, then as a consequence you -+may not distribute the Library at all. For example, if a patent -+license would not permit royalty-free redistribution of the Library by -+all those who receive copies directly or indirectly through you, then -+the only way you could satisfy both it and this License would be to -+refrain entirely from distribution of the Library. -+ -+If any portion of this section is held invalid or unenforceable under any -+particular circumstance, the balance of the section is intended to apply, -+and the section as a whole is intended to apply in other circumstances. -+ -+It is not the purpose of this section to induce you to infringe any -+patents or other property right claims or to contest validity of any -+such claims; this section has the sole purpose of protecting the -+integrity of the free software distribution system which is -+implemented by public license practices. Many people have made -+generous contributions to the wide range of software distributed -+through that system in reliance on consistent application of that -+system; it is up to the author/donor to decide if he or she is willing -+to distribute software through any other system and a licensee cannot -+impose that choice. -+ -+This section is intended to make thoroughly clear what is believed to -+be a consequence of the rest of this License. -+ -+ 12. If the distribution and/or use of the Library is restricted in -+certain countries either by patents or by copyrighted interfaces, the -+original copyright holder who places the Library under this License may add -+an explicit geographical distribution limitation excluding those countries, -+so that distribution is permitted only in or among countries not thus -+excluded. In such case, this License incorporates the limitation as if -+written in the body of this License. -+ -+ 13. The Free Software Foundation may publish revised and/or new -+versions of the Library General Public License from time to time. -+Such new versions will be similar in spirit to the present version, -+but may differ in detail to address new problems or concerns. -+ -+Each version is given a distinguishing version number. If the Library -+specifies a version number of this License which applies to it and -+"any later version", you have the option of following the terms and -+conditions either of that version or of any later version published by -+the Free Software Foundation. If the Library does not specify a -+license version number, you may choose any version ever published by -+the Free Software Foundation. -+ -+ 14. If you wish to incorporate parts of the Library into other free -+programs whose distribution conditions are incompatible with these, -+write to the author to ask for permission. For software which is -+copyrighted by the Free Software Foundation, write to the Free -+Software Foundation; we sometimes make exceptions for this. Our -+decision will be guided by the two goals of preserving the free status -+of all derivatives of our free software and of promoting the sharing -+and reuse of software generally. -+ -+ NO WARRANTY -+ -+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. -+ -+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -+DAMAGES. -+ -+ END OF TERMS AND CONDITIONS -+ -+ How to Apply These Terms to Your New Libraries -+ -+ If you develop a new library, and you want it to be of the greatest -+possible use to the public, we recommend making it free software that -+everyone can redistribute and change. You can do so by permitting -+redistribution under these terms (or, alternatively, under the terms of the -+ordinary General Public License). -+ -+ To apply these terms, attach the following notices to the library. It is -+safest to attach them to the start of each source file to most effectively -+convey the exclusion of warranty; and each file should have at least the -+"copyright" line and a pointer to where the full notice is found. -+ -+ -+ Copyright (C) -+ -+ This library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Library General Public -+ License as published by the Free Software Foundation; either -+ version 2 of the License, or (at your option) any later version. -+ -+ This library 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 -+ Library General Public License for more details. -+ -+ You should have received a copy of the GNU Library General Public -+ License along with this library; if not, see . -+ -+Also add information on how to contact you by electronic and paper mail. -+ -+You should also get your employer (if you work as a programmer) or your -+school, if any, to sign a "copyright disclaimer" for the library, if -+necessary. Here is a sample; alter the names: -+ -+ Yoyodyne, Inc., hereby disclaims all copyright interest in the -+ library `Frob' (a library for tweaking knobs) written by James Random Hacker. -+ -+ , 1 April 1990 -+ Moe Ghoul, President of Vice -+ -+That's all there is to it! -diff --git a/lib/librobdb/README.md b/lib/librobdb/README.md -new file mode 100644 -index 000000000..a79bca9ea ---- /dev/null -+++ b/lib/librobdb/README.md -@@ -0,0 +1,30 @@ -+# DESCRIPTION -+ -+This project provides basic functions to walk/lookup Berkeley Database records. -+It is derived from [GitHub - rpm-software-management/rpm: The RPM package manager](https://github.com/rpm-software-management/rpm/) project. -+It reuse a single file: https://github.com/rpm-software-management/rpm/blob/master/lib/backend/bdb_ro.cc -+ -+renamed as a C file, suppressed librpm adherences and adding back a simple -+interface to be able to use the relevant functions. -+ -+# Build -+ -+make clean rpmbuild lint -+ -+# Example -+ -+See test/test.c (Using a 389ds entries database as example, It shows how to dump the database and look for records) -+ -+# Running tests -+ -+dnf install -y dist/RPMS/*/*.rpm -+make test -+ -+or -+ -+make localtest -+ -+ -+# LICENSE -+ -+Same as lib part for rpm: GPLv2 or alternatively LGPL (See COPYING and COPYING.RPM for full details) -diff --git a/lib/librobdb/lib/bdb_ro.c b/lib/librobdb/lib/bdb_ro.c -new file mode 100644 -index 000000000..db10cc812 ---- /dev/null -+++ b/lib/librobdb/lib/bdb_ro.c -@@ -0,0 +1,713 @@ -+/* Part of this file content is derivated from: -+ * https://github.com/rpm-software-management/rpm/blob/master/lib/backend/bdb_ro.cc -+ * Commit: a45134e7d428ad4f40e629408f24de9a6b955200 -+ * i.e: -+ * git clone https://github.com/rpm-software-management/rpm.git -+ * git switch --detach a45134e7d428ad4f40e629408f24de9a6b955200 -+ * lib/backend/bdb_ro.cc -+ */ -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "robdb.h" -+ -+static void* (*bdbreader_calloc_cb)(size_t, size_t); -+static void* (*bdbreader_malloc_cb)(size_t); -+static void* (*bdbreader_realloc_cb)(void*, size_t); -+static void (*bdbreader_free_cb)(void **); -+static void (*bdbreader_log_cb)(const char*, ...); -+ -+#define NEW(structname) bdbreader_calloc_cb(1, sizeof (struct structname)) -+#define DELETE(var) free(var) -+#define free(var) bdbreader_free_cb((void**)&var) -+#define xmalloc(size) bdbreader_malloc_cb(size) -+#define xrealloc(ptr, size) bdbreader_realloc_cb((void*)(ptr),(size)) -+ -+#define rpmlog(level, ...) bdbreader_log_cb("bdbro", __VA_ARGS__) -+ -+ -+/* Note: the only changes in the following copied code is to convert back -+ * the C++ statments to C: -+ * new xxx is replaced by NEW(xxx) -+ * delete xxx is replaced by DELETE(xxx) -+ */ -+/************************************************************************/ -+/************** Start of code copied from librpm ************************/ -+/************************************************************************/ -+ -+#define BDB_HASH 0 -+#define BDB_BTREE 1 -+ -+union _dbswap { -+ unsigned int ui; -+ unsigned char uc[4]; -+}; -+ -+#define _DBSWAP(_a) \ -+\ -+ { unsigned char _b, *_c = (_a).uc; \ -+ _b = _c[3]; _c[3] = _c[0]; _c[0] = _b; \ -+ _b = _c[2]; _c[2] = _c[1]; _c[1] = _b; \ -+\ -+ } -+ -+struct dbiCursor_s; -+ -+struct bdb_kv { -+ unsigned char *kv; -+ unsigned int len; -+}; -+ -+struct bdb_db { -+ int fd; /* file descriptor of database */ -+ int type; /* BDB_HASH / BDB_BTREE */ -+ unsigned int pagesize; -+ unsigned int lastpage; -+ int swapped; /* different endianess? */ -+ /* btree */ -+ unsigned int root; /* root page of the b-tree */ -+ /* hash */ -+ unsigned int maxbucket; -+ unsigned int highmask; -+ unsigned int lowmask; -+ unsigned int spares[32]; /* spare pages for each splitpoint */ -+}; -+ -+struct bdb_cur { -+ struct bdb_db *db; -+ -+ struct bdb_kv key; /* key and value from the db entry */ -+ struct bdb_kv val; -+ -+ unsigned char *page; /* the page we're looking at */ -+ -+ unsigned char *ovpage; -+ struct bdb_kv keyov; /* space to store oversized keys/values */ -+ struct bdb_kv valov; -+ -+ int state; /* 1: onpage, -1: error */ -+ int idx; /* entry index */ -+ int numidx; /* number of entries on the page */ -+ int islookup; /* we're doing a lookup operation */ -+ -+ /* hash */ -+ unsigned int bucket; /* current bucket */ -+}; -+ -+ -+static void swap16(unsigned char *p) -+{ -+ int a = p[0]; -+ p[0] = p[1]; -+ p[1] = a; -+} -+ -+static void swap32(unsigned char *p) -+{ -+ int a = p[0]; -+ p[0] = p[3]; -+ p[3] = a; -+ a = p[1]; -+ p[1] = p[2]; -+ p[2] = a; -+} -+ -+static void swap32_2(unsigned char *p) -+{ -+ swap32(p); -+ swap32(p + 4); -+} -+ -+static void bdb_swapmetapage(struct bdb_db *db, unsigned char *page) -+{ -+ int i, maxi = db->type == BDB_HASH ? 224 : 92; -+ for (i = 8; i < maxi; i += 4) -+ swap32((unsigned char *)(page + i)); -+ swap32((unsigned char *)(page + 24)); -+} -+ -+static void bdb_swappage(struct bdb_db *db, unsigned char *page) -+{ -+ unsigned int pagesize = db->pagesize; -+ int type, i, nent, off; -+ swap32(page + 8); /* page number */ -+ swap32_2(page + 12); /* prev/next page */ -+ swap16(page + 20); /* nitems */ -+ swap16(page + 22); /* highfree */ -+ -+ type = page[25]; -+ if (type != 2 && type != 13 && type != 3 && type != 5) -+ return; -+ nent = *(uint16_t *)(page + 20); -+ if (nent > (pagesize - 26) / 2) -+ nent = (pagesize - 26) / 2; -+ for (i = 0; i < nent; i++) { -+ int minoff = 26 + nent * 2; -+ swap16(page + 26 + i * 2); /* offset */ -+ off = *(uint16_t *)(page + 26 + i * 2); -+ if (off < minoff || off >= pagesize) -+ continue; -+ if (type == 2 || type == 13) { /* hash */ -+ if (page[off] == 3 && off + 12 <= pagesize) -+ swap32_2(page + off + 4); /* page no/length */ -+ } else if (type == 3) { /* btree internal */ -+ if (off + 12 > pagesize) -+ continue; -+ swap16(page + off); /* length */ -+ swap32_2(page + off + 4); /* page no/num recs */ -+ if (page[off + 2] == 3 && off + 24 <= pagesize) -+ swap32_2(page + off + 16); /* with overflow page/length */ -+ } else if (type == 5) { /* btree leaf */ -+ if (off + 3 <= pagesize && page[off + 2] == 1) -+ swap16(page + off); /* length */ -+ else if (off + 12 <= pagesize && page[off + 2] == 3) -+ swap32_2(page + off + 4); /* overflow page/length */ -+ } -+ } -+} -+ -+static int bdb_getpage(struct bdb_db *db, unsigned char *page, unsigned int pageno) -+{ -+ if (!pageno || pageno > db->lastpage) -+ return -1; -+ if (pread(db->fd, page, db->pagesize, (off_t)pageno * db->pagesize) != db->pagesize) { -+ rpmlog(RPMLOG_ERR, "pread: %s\n", strerror(errno)); -+ return -1; -+ } -+ if (db->swapped) -+ bdb_swappage(db, page); -+ if (pageno != *(uint32_t *)(page + 8)) -+ return -1; -+ return 0; -+} -+ -+static void bdb_close(struct bdb_db *db) -+{ -+ if (db->fd >= 0) -+ close(db->fd); -+ DELETE(db); -+} -+ -+static struct bdb_db *bdb_open(const char *name) -+{ -+ uint32_t meta[512 / 4]; -+ int i, fd; -+ struct bdb_db *db; -+ -+ fd = open(name, O_RDONLY); -+ if (fd == -1) { -+ return NULL; -+ } -+ db = NEW(bdb_db); -+ db->fd = fd; -+ if (pread(fd, meta, 512, 0) != 512) { -+ rpmlog(RPMLOG_ERR, "%s: pread: %s\n", name, strerror(errno)); -+ bdb_close(db); -+ return NULL; -+ } -+ if (meta[3] == 0x00061561 || meta[3] == 0x61150600) { -+ db->type = BDB_HASH; -+ db->swapped = meta[3] == 0x61150600; -+ } else if (meta[3] == 0x00053162 || meta[3] == 0x62310500) { -+ db->type = BDB_BTREE; -+ db->swapped = meta[3] == 0x62310500; -+ } else { -+ rpmlog(RPMLOG_ERR, "%s: not a berkeley db hash/btree database\n", name); -+ bdb_close(db); -+ return NULL; -+ } -+ if (db->swapped) -+ bdb_swapmetapage(db, (unsigned char *)meta); -+ db->pagesize = meta[5]; -+ db->lastpage = meta[8]; -+ if (db->type == BDB_HASH) { -+ if (meta[4] < 8 || meta[4] > 10) { -+ rpmlog(RPMLOG_ERR, "%s: unsupported hash version %d\n", name, meta[4]); -+ bdb_close(db); -+ return NULL; -+ } -+ db->maxbucket = meta[18]; -+ db->highmask = meta[19]; -+ db->lowmask = meta[20]; -+ for (i = 0; i < 32; i++) -+ db->spares[i] = meta[24 + i]; -+ } -+ if (db->type == BDB_BTREE) { -+ if (meta[4] < 9 || meta[4] > 10) { -+ rpmlog(RPMLOG_ERR, "%s: unsupported btree version %d\n", name, meta[4]); -+ bdb_close(db); -+ return NULL; -+ } -+ db->root = meta[22]; -+ } -+ return db; -+} -+ -+ -+/****** overflow handling ******/ -+ -+static int ovfl_get(struct bdb_cur *cur, struct bdb_kv *kv, struct bdb_kv *ov, uint32_t *pagenolen) -+{ -+ unsigned int pageno = pagenolen[0]; -+ unsigned int len = pagenolen[1]; -+ unsigned int plen; -+ unsigned char *p; -+ -+ if (len == 0) -+ return -1; -+ if (len > ov->len) { -+ if (ov->kv) -+ ov->kv = xrealloc(ov->kv, len); -+ else -+ ov->kv = (unsigned char *)xmalloc(len); -+ ov->len = len; -+ } -+ if (!cur->ovpage) -+ cur->ovpage = (unsigned char *)xmalloc(cur->db->pagesize); -+ p = ov->kv; -+ while (len > 0) { -+ if (bdb_getpage(cur->db, cur->ovpage, pageno)) -+ return -1; -+ if (cur->ovpage[25] != 7) -+ return -1; -+ plen = *(uint16_t *)(cur->ovpage + 22); -+ if (plen + 26 > cur->db->pagesize || plen > len) -+ return -1; -+ memcpy(p, cur->ovpage + 26, plen); -+ p += plen; -+ len -= plen; -+ pageno = *(uint32_t *)(cur->ovpage + 16); -+ } -+ if (kv) { -+ kv->kv = ov->kv; -+ kv->len = pagenolen[1]; -+ } -+ return 0; -+} -+ -+ -+/****** hash implementation ******/ -+ -+static int hash_bucket_to_page(struct bdb_db *db, unsigned int bucket) -+{ -+ unsigned int b; -+ int i = 0; -+ for (b = bucket; b; b >>= 1) -+ i++; -+ return bucket + db->spares[i]; -+} -+ -+static int hash_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl) -+{ -+ uint32_t bucket; -+ unsigned int pg, i; -+ cur->state = -1; -+ for (bucket = 0, i = 0; i < keyl; i++) -+ bucket = (bucket * 16777619) ^ key[i]; -+ bucket &= cur->db->highmask; -+ if (bucket > cur->db->maxbucket) -+ bucket &= cur->db->lowmask; -+ cur->bucket = bucket; -+ pg = hash_bucket_to_page(cur->db, bucket); -+ if (bdb_getpage(cur->db, cur->page, pg)) -+ return -1; -+ if (cur->page[25] != 8 && cur->page[25] != 13 && cur->page[25] != 2) -+ return -1; -+ cur->idx = (unsigned int)-2; -+ cur->numidx = *(uint16_t *)(cur->page + 20); -+ cur->state = 1; -+ return 0; -+} -+ -+static int hash_getkv(struct bdb_cur *cur, struct bdb_kv *kv, struct bdb_kv *ov, int off, int len) -+{ -+ if (len <= 0 || off + len > cur->db->pagesize) -+ return -1; -+ if (cur->page[off] == 1) { -+ kv->kv = cur->page + off + 1; -+ kv->len = len - 1; -+ } else if (cur->page[off] == 3) { -+ uint32_t ovlpage[2]; -+ if (len != 12) -+ return -1; -+ memcpy(ovlpage, cur->page + off + 4, 8); /* off is unaligned */ -+ if (ovfl_get(cur, kv, ov, ovlpage)) -+ return -1; -+ } else { -+ return -1; -+ } -+ return 0; -+} -+ -+static int hash_next(struct bdb_cur *cur) -+{ -+ int pagesize = cur->db->pagesize; -+ int koff, klen, voff, vlen; -+ if (!cur->state && hash_lookup(cur, 0, 0)) -+ return -1; -+ cur->idx += 2; -+ for (;;) { -+ if (cur->idx + 1 >= cur->numidx) { -+ unsigned int pg; -+ cur->idx = cur->numidx = 0; -+ pg = *(uint32_t *)(cur->page + 16); -+ if (!pg) { -+ if (cur->islookup || cur->bucket >= cur->db->maxbucket) -+ return 1; -+ pg = hash_bucket_to_page(cur->db, ++cur->bucket); -+ } -+ if (bdb_getpage(cur->db, cur->page, pg)) -+ return -1; -+ if (cur->page[25] != 8 && cur->page[25] != 13 && cur->page[25] != 2) -+ return -1; -+ cur->numidx = *(uint16_t *)(cur->page + 20); -+ continue; -+ } -+ koff = *(uint16_t *)(cur->page + 26 + 2 * cur->idx); -+ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx); -+ if (koff >= pagesize || voff >= pagesize) -+ return -1; -+ if (cur->idx == 0) -+ klen = pagesize - koff; -+ else -+ klen = *(uint16_t *)(cur->page + 24 + 2 * cur->idx) - koff; -+ vlen = koff - voff; -+ if (hash_getkv(cur, &cur->key, &cur->keyov, koff, klen)) -+ return -1; -+ if (!cur->islookup && hash_getkv(cur, &cur->val, &cur->valov, voff, vlen)) -+ return -1; -+ return 0; -+ } -+} -+ -+static int hash_getval(struct bdb_cur *cur) -+{ -+ int koff, voff; -+ if (cur->state != 1 || cur->idx + 1 >= cur->numidx) -+ return -1; -+ koff = *(uint16_t *)(cur->page + 26 + 2 * cur->idx); -+ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx); -+ return hash_getkv(cur, &cur->val, &cur->valov, voff, koff - voff); -+} -+ -+ -+/****** btree implementation ******/ -+ -+static int btree_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keylen) -+{ -+ int pagesize = cur->db->pagesize; -+ int off, lastoff, idx, numidx; -+ unsigned int pg; -+ unsigned char *ekey; -+ unsigned int ekeylen; -+ int cmp; -+ -+ cur->state = -1; -+ pg = cur->db->root; -+ for (;;) { -+ if (bdb_getpage(cur->db, cur->page, pg)) -+ return -1; -+ if (cur->page[25] == 5) -+ break; /* found leaf page */ -+ if (cur->page[25] != 3) -+ return -1; -+ numidx = *(uint16_t *)(cur->page + 20); -+ if (!numidx) -+ return -1; -+ for (lastoff = 0, idx = 0; idx < numidx; idx++, lastoff = off) { -+ off = *(uint16_t *)(cur->page + 26 + 2 * idx); -+ if ((off & 3) != 0 || off + 3 > pagesize) -+ return -1; -+ ekeylen = *(uint16_t *)(cur->page + off); -+ if (off + 12 + ekeylen > pagesize) -+ return -1; -+ if (!keylen) { -+ lastoff = off; -+ break; -+ } -+ if (idx == 0) -+ continue; -+ ekey = cur->page + off + 12; -+ if ((cur->page[off + 2] & 0x7f) == 3) { -+ if (ekeylen != 12) -+ return -1; -+ if (ovfl_get(cur, 0, &cur->keyov, (uint32_t *)(ekey + 4))) -+ return -1; -+ ekeylen = *(uint32_t *)(ekey + 8); -+ ekey = cur->keyov.kv; -+ } else if ((cur->page[off + 2] & 0x7f) != 1) { -+ return -1; -+ } -+ cmp = memcmp(ekey, key, keylen < ekeylen ? keylen : ekeylen); -+ if (cmp > 0 || (cmp == 0 && ekeylen > keylen)) -+ break; -+ } -+ pg = *(uint32_t *)(cur->page + lastoff + 4); -+ } -+ cur->idx = (unsigned int)-2; -+ cur->numidx = *(uint16_t *)(cur->page + 20); -+ cur->state = 1; -+ return 0; -+} -+ -+static int btree_getkv(struct bdb_cur *cur, struct bdb_kv *kv, struct bdb_kv *ov, int off) -+{ -+ if ((off & 3) != 0) -+ return -1; -+ if (cur->page[off + 2] == 1) { -+ int len = *(uint16_t *)(cur->page + off); -+ if (off + 3 + len > cur->db->pagesize) -+ return -1; -+ kv->kv = cur->page + off + 3; -+ kv->len = len; -+ } else if (cur->page[off + 2] == 3) { -+ if (off + 12 > cur->db->pagesize) -+ return -1; -+ if (ovfl_get(cur, kv, ov, (uint32_t *)(cur->page + off + 4))) -+ return -1; -+ } else { -+ return -1; -+ } -+ return 0; -+} -+ -+static int btree_next(struct bdb_cur *cur) -+{ -+ int pagesize = cur->db->pagesize; -+ int koff, voff; -+ if (!cur->state && btree_lookup(cur, 0, 0)) -+ return -1; -+ cur->idx += 2; -+ for (;;) { -+ if (cur->idx + 1 >= cur->numidx) { -+ unsigned int pg; -+ cur->idx = cur->numidx = 0; -+ pg = *(uint32_t *)(cur->page + 16); -+ if (cur->islookup || !pg) -+ return 1; -+ if (bdb_getpage(cur->db, cur->page, pg)) -+ return -1; -+ if (cur->page[25] != 5) -+ return -1; -+ cur->numidx = *(uint16_t *)(cur->page + 20); -+ continue; -+ } -+ koff = *(uint16_t *)(cur->page + 26 + 2 * cur->idx); -+ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx); -+ if (koff + 3 > pagesize || voff + 3 > pagesize) -+ return -1; -+ if ((cur->page[koff + 2] & 0x80) != 0 || (cur->page[voff + 2] & 0x80) != 0) -+ continue; /* ignore deleted */ -+ if (btree_getkv(cur, &cur->key, &cur->keyov, koff)) -+ return -1; -+ if (!cur->islookup && btree_getkv(cur, &cur->val, &cur->valov, voff)) -+ return -1; -+ return 0; -+ } -+} -+ -+static int btree_getval(struct bdb_cur *cur) -+{ -+ int voff; -+ if (cur->state != 1 || cur->idx + 1 >= cur->numidx) -+ return -1; -+ voff = *(uint16_t *)(cur->page + 28 + 2 * cur->idx); -+ return btree_getkv(cur, &cur->val, &cur->valov, voff); -+} -+ -+ -+/****** cursor functions ******/ -+ -+static struct bdb_cur *cur_open(struct bdb_db *db) -+{ -+ struct bdb_cur *cur = NEW(bdb_cur); -+ cur->db = db; -+ cur->page = (unsigned char *)xmalloc(db->pagesize); -+ return cur; -+} -+ -+static void cur_close(struct bdb_cur *cur) -+{ -+ if (cur->page) -+ free(cur->page); -+ if (cur->ovpage) -+ free(cur->ovpage); -+ if (cur->keyov.kv) -+ free(cur->keyov.kv); -+ if (cur->valov.kv) -+ free(cur->valov.kv); -+ DELETE(cur); -+} -+ -+static int cur_next(struct bdb_cur *cur) -+{ -+ if (cur->state < 0) -+ return -1; -+ if (cur->db->type == BDB_HASH) -+ return hash_next(cur); -+ if (cur->db->type == BDB_BTREE) -+ return btree_next(cur); -+ return -1; -+} -+ -+static int cur_getval(struct bdb_cur *cur) -+{ -+ if (cur->state < 0) -+ return -1; -+ if (cur->db->type == BDB_HASH) -+ return hash_getval(cur); -+ if (cur->db->type == BDB_BTREE) -+ return btree_getval(cur); -+ return -1; -+} -+ -+static int cur_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl) -+{ -+ int r = -1; -+ if (cur->db->type == BDB_HASH) -+ r = hash_lookup(cur, key, keyl); -+ if (cur->db->type == BDB_BTREE) -+ r = btree_lookup(cur, key, keyl); -+ if (r != 0) -+ return r; -+ cur->islookup = 1; -+ while ((r = cur_next(cur)) == 0) -+ if (keyl == cur->key.len && !memcmp(key, cur->key.kv, keyl)) -+ break; -+ cur->islookup = 0; -+ if (r == 0) -+ r = cur_getval(cur); -+ return r; -+} -+ -+static int cur_lookup_ge(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl) -+{ -+ int r = -1; -+ if (cur->db->type == BDB_BTREE) -+ r = btree_lookup(cur, key, keyl); -+ if (r != 0) -+ return r; -+ cur->islookup = 1; -+ while ((r = cur_next(cur)) == 0) { -+ unsigned int ekeyl = cur->key.len; -+ int cmp = memcmp(cur->key.kv, key, keyl < ekeyl ? keyl : ekeyl); -+ if (cmp > 0 || (cmp == 0 && ekeyl >= keyl)) -+ break; -+ } -+ cur->islookup = 0; -+ if (r == 0) -+ r = cur_getval(cur); -+ else if (r == 1) -+ r = cur_next(cur); -+ return r; -+} -+ -+/************************************************************************/ -+/************** End of code copied from librpm **************************/ -+/************************************************************************/ -+ -+static int cur_getcurval(struct bdb_cur *cur, void **keyv, unsigned int *keyl, void **datav, unsigned int *datal) -+{ -+ int ret = cur_getval(cur); -+ if (keyv) { -+ *keyv = cur->key.kv; -+ } -+ if (keyl) { -+ *keyl = cur->key.len; -+ } -+ if (datav) { -+ *datav = cur->val.kv; -+ } -+ if (datal) { -+ *datal = cur->val.len; -+ } -+ return ret; -+} -+ -+/************************************************************************/ -+/********** exported symbols - see description in bdbreader.h ***********/ -+/************************************************************************/ -+ -+struct bdb_db *bdbreader_bdb_open(const char *name) -+{ -+ return bdb_open(name); -+} -+ -+void bdbreader_bdb_close(struct bdb_db **db) -+{ -+ if (*db) { -+ bdb_close(*db); -+ *db = NULL; -+ } -+} -+ -+struct bdb_cur *bdbreader_cur_open(struct bdb_db *db) -+{ -+ return cur_open(db); -+} -+ -+void bdbreader_cur_close(struct bdb_cur **cur) -+{ -+ if (*cur) { -+ cur_close(*cur); -+ *cur = NULL; -+ } -+} -+ -+int bdbreader_cur_next(struct bdb_cur *cur) -+{ -+ return cur_next(cur); -+} -+ -+int bdbreader_cur_getval(struct bdb_cur *cur) -+{ -+ return cur_getval(cur); -+} -+ -+int bdbreader_cur_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl) -+{ -+ return cur_lookup(cur, key, keyl); -+} -+ -+int bdbreader_cur_lookup_ge(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl) -+{ -+ return cur_lookup_ge(cur, key, keyl); -+} -+ -+int bdbreader_cur_getcurval(struct bdb_cur *cur, void **keyv, unsigned int *keyl, void **datav, unsigned int *datal) -+{ -+ return cur_getcurval(cur, keyv, keyl, datav, datal); -+} -+ -+void bdbreader_set_calloc_cb(void* (*calloc_cb)(size_t, size_t)) -+{ -+ bdbreader_calloc_cb = calloc_cb; -+} -+ -+void bdbreader_set_malloc_cb(void* (*malloc_cb)(size_t)) -+{ -+ bdbreader_malloc_cb = malloc_cb; -+} -+ -+void bdbreader_set_realloc_cb(void* (*realloc_cb)(void*, size_t)) -+{ -+ bdbreader_realloc_cb = realloc_cb; -+} -+ -+void bdbreader_set_free_cb(void (*free_cb)(void **)) -+{ -+ bdbreader_free_cb = free_cb; -+} -+ -+void bdbreader_set_log_cb(void (*log_cb)(const char*, ...)) -+{ -+ bdbreader_log_cb = log_cb; -+} -+ -diff --git a/lib/librobdb/lib/robdb.h b/lib/librobdb/lib/robdb.h -new file mode 100644 -index 000000000..2c1a663bf ---- /dev/null -+++ b/lib/librobdb/lib/robdb.h -@@ -0,0 +1,51 @@ -+/* -+ * License: GPL (version 2 or any later version) or LGPL (version 2.1 or any later version). -+ */ -+ -+struct bdb_db; -+struct bdb_cur; -+ -+ -+/* Callbacks - All callbacks must be set before used any other functions */ -+ -+/* Set callback for the calloc function */ -+void bdbreader_set_calloc_cb(void* (*calloc_cb)(size_t, size_t)); -+ -+/* Set callback for the malloc function */ -+void bdbreader_set_malloc_cb(void* (*malloc_cb)(size_t)); -+ -+/* Set callback for the realloc function */ -+void bdbreader_set_realloc_cb(void* (*realloc_cb)(void*, size_t)); -+ -+/* Set callback for the free function */ -+void bdbreader_set_free_cb(void (*free_cb)(void **)); -+ -+/* Set callback for the log function */ -+void bdbreader_set_log_cb(void (*log_cb)(const char*, ...)); -+ -+/* Open a database instance and get a db handler */ -+struct bdb_db *bdbreader_bdb_open(const char *name); -+ -+/* Close a db handler */ -+void bdbreader_bdb_close(struct bdb_db **db); -+ -+/* Create a cursor on a db */ -+struct bdb_cur *bdbreader_cur_open(struct bdb_db *db); -+ -+/* Close a cusrsor */ -+void bdbreader_cur_close(struct bdb_cur **cur); -+ -+/* Move cursor to next item. returns -1 if no more records */ -+int bdbreader_cur_next(struct bdb_cur *cur); -+ -+/* Get cursor current status. returns -1 if no more records */ -+int bdbreader_cur_getval(struct bdb_cur *cur); -+ -+/* Position the cursor on the key. return -1 if not found */ -+int bdbreader_cur_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl); -+ -+/* Position the cursor on smallest key >= key. return -1 if not found */ -+int bdbreader_cur_lookup_ge(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl); -+ -+/* Get cursor current key/data pair. returns -1 if no more records */ -+int bdbreader_cur_getcurval(struct bdb_cur *cur, void **keyv, unsigned int *keyl, void **datav, unsigned int *datal); -diff --git a/lib/librobdb/robdb.spec b/lib/librobdb/robdb.spec -new file mode 100644 -index 000000000..8d3a27e0f ---- /dev/null -+++ b/lib/librobdb/robdb.spec -@@ -0,0 +1,67 @@ -+Name: robdb -+Version: 1.1 -+Release: %{autorelease -n %{?dist}} -+Summary: Provide basic functions to search and read Berkeley Database records -+ -+License: GPL-2.0-or-later OR LGPL-2.1-or-later -+URL: https://github.com/389ds/389-ds-base/tree/main/lib/librobdb -+Source0: %{name}-%{version}.tar.bz2 -+ -+BuildRequires: gcc -+# Requires: -+ -+%description -+ -+ -+%package devel -+Summary: Development files for %{name} -+License: GPL-2.0-or-later OR LGPL-2.1-or-later -+Requires: %{name}-libs%{?_isa} = %{version}-%{release} -+ -+%description devel -+The %{name}-devel package contains the library and the header file for -+developing applications that use %{name}: A library derived from -+rpm lib project (https://github.com/rpm-software-management) that -+provides some basic functions to search and read Berkeley Database records -+ -+ -+%package libs -+Summary: Library for %{name} -+License: GPL-2.0-or-later OR LGPL-2.1-or-later -+ -+%description libs -+The %{name}-lib package contains a library derived from rpm lib -+project (https://github.com/rpm-software-management) that provides -+some basic functions to search and read Berkeley Database records -+ -+ -+%prep -+%autosetup -+ -+%build -+%make_build -+ -+%install -+%make_install -+ -+%{?ldconfig_scriptlets} -+ -+%check -+make localtest -+ -+ -+%files libs -+%license COPYING COPYING.RPM -+%doc %{_defaultdocdir}/%{name}-libs/README.md -+%{_libdir}/*.so.* -+ -+%files devel -+%license COPYING COPYING.RPM -+%doc %{_defaultdocdir}/%{name}-devel/README.md -+%{_libdir}/*.so -+%{_includedir}/* -+ -+ -+%changelog -+%autochangelog -+ -diff --git a/lib/librobdb/tests/test.c b/lib/librobdb/tests/test.c -new file mode 100644 -index 000000000..92cf35e8d ---- /dev/null -+++ b/lib/librobdb/tests/test.c -@@ -0,0 +1,175 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+typedef struct { -+ void *data; -+ unsigned int len; -+} DATA; -+ -+ -+void print_record(const DATA *key, const DATA *data) -+{ -+ unsigned int id = 0; -+ if (4 == key->len) { -+ unsigned char *pt = key->data; -+ /* In test.db the key is a big endian 4 bytes integer */ -+ id = pt[3] + (pt[2] << 8) + (pt[1] << 16) + (pt[0] << 24); -+ printf("Key: %3d Data:\n%s\n", id, (char*)data->data); -+ } else { -+ printf("ERROR: Unexpected record key size\n"); -+ } -+} -+ -+void mylog(const char *msg, ...) -+{ -+ va_list ap; -+ va_start(ap, msg); -+ printf("bdbreader:" ); -+ vprintf(msg, ap); -+ va_end(ap); -+} -+ -+void myfree(void **data) -+{ -+ if (*data) { -+ free(*data); -+ *data = NULL; -+ } -+} -+ -+int main() -+{ -+ struct bdb_db *db = NULL; -+ struct bdb_cur *cur = NULL; -+ DATA key = {0}; -+ DATA data = {0}; -+ int rc = 0; -+ char keybuff[6]; -+ int fail = 0; -+ int count = 0; -+ int expected_count = 14; -+ -+ printf("HERE[%d]\n",__LINE__); -+ -+ /* Initialize all callbacks */ -+ bdbreader_set_calloc_cb(calloc); -+ bdbreader_set_malloc_cb(malloc); -+ bdbreader_set_realloc_cb(realloc); -+ bdbreader_set_free_cb(myfree); -+ bdbreader_set_log_cb(mylog); -+ -+ db = bdbreader_bdb_open("test.db"); -+ if (db == NULL) { -+ perror("Failed to open test.db"); -+ exit(1); -+ } -+ cur = bdbreader_cur_open(db); -+ if (cur == NULL) { -+ perror("Failed to open cursor"); -+ exit(1); -+ } -+ -+ printf(" ********* Dump the dtabase content: *******\n"); -+ -+ do { -+ rc = bdbreader_cur_next(cur); -+ if (rc !=0) { -+ break; -+ } -+ rc = bdbreader_cur_getcurval(cur, &key.data, &key.len, &data.data, &data.len); -+ if (rc == 0) { -+ print_record(&key, &data); -+ count++; -+ } -+ } while (rc == 0); -+ -+ printf("Found %d/%d records\n\n", count, expected_count); -+ if (count != expected_count) { -+ fail = 1; -+ } -+ -+ printf(" ********* Test lookup: *******\n"); -+ -+ keybuff[0] = 0; -+ keybuff[1] = 0; -+ keybuff[2] = 0; -+ keybuff[3] = 7; -+ keybuff[4] = '@'; -+ key.data = keybuff; -+ key.len = 5; -+ -+ printf(" Looking for key == 7@ ... Should not find it.\n"); -+ rc = bdbreader_cur_lookup(cur, key.data, key.len); -+ if (rc == 0) { -+ printf("ERROR: key == 7@ unexpectedly found.\n"); -+ fail = 1; -+ } else { -+ printf("OK: key == 7@ is not found (as expected).\n"); -+ } -+ -+ printf(" Looking for key >= 7@ ... Should not find record with key == 8.\n"); -+ rc = bdbreader_cur_lookup_ge(cur, key.data, key.len); -+ if (rc == 0) { -+ rc = bdbreader_cur_getcurval(cur, &key.data, &key.len, &data.data, &data.len); -+ if (rc != 0) { -+ printf("ERROR: key >= 7@ : unable to get the record.\n"); -+ fail = 1; -+ } else { -+ char *ptid = key.data; -+ if (ptid[3] != 8) { -+ printf("ERROR: key >= 7@ : found record %d instead of 8.\n", ptid[3]); -+ fail = 1; -+ } else { -+ printf("OK: key >= 7@ : found record 8 (as expected).\n"); -+ } -+ } -+ } else { -+ printf("ERROR: key >= 7@ is not found.\n"); -+ fail = 1; -+ } -+ -+ key.data = keybuff; -+ key.len = 4; -+ printf(" Looking for key == 7 ... Should find it.\n"); -+ rc = bdbreader_cur_lookup(cur, key.data, key.len); -+ if (rc == 0) { -+ rc = bdbreader_cur_getcurval(cur, &key.data, &key.len, &data.data, &data.len); -+ if (rc != 0) { -+ printf("ERROR: key == 7 : unable to get the record.\n"); -+ fail = 1; -+ } else { -+ char *ptid = key.data; -+ if (ptid[3] != 7) { -+ printf("ERROR: key == 7 : found record %d instead of 7.\n", ptid[3]); -+ fail = 1; -+ } else { -+ printf("OK: key == 7 : found record 7 (as expected).\n"); -+ } -+ } -+ } else { -+ printf("ERROR: key == 7 is not found.\n"); -+ fail = 1; -+ } -+ -+ bdbreader_cur_close(&cur); -+ bdbreader_bdb_close(&db); -+ printf("TEST: %s\n", fail ? "FAIL":"PASS"); -+ -+ return fail; -+} -+ -+#if 0 -+/* Get cursor current status. returns -1 if no more records */ -+int bdbreader_cur_getval(struct bdb_cur *cur); -+ -+/* Position the cursor on the key. return -1 if not found */ -+int bdbreader_cur_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl); -+ -+/* Position the cursor on smallest key >= key. return -1 if not found */ -+int bdbreader_cur_lookup_ge(struct bdb_cur *cur, const unsigned char *key, unsigned int keyl); -+#endif -+ -diff --git a/lib/librobdb/tests/test.db b/lib/librobdb/tests/test.db -new file mode 100644 -index 0000000000000000000000000000000000000000..abefbce1c3f909ae58a5ddf50cfbd16484332fc0 -GIT binary patch -literal 24576 -zcmeHO&u`<#6{gqw%d^`J7D>8?H0Xm4g#~ykOY%BiE`+AY21(KGk7B!*y*MLsEKfqt -zFf*jRE__&^L7P7y#~ym?DgQ`LIR?lf|3HsL(My10W+;(EQnKVafdb8U5@~WY^L_8V -zdGC$9=6T+K{<7{V47*pn4fO#$&wTK_OZqQ1KK|p?we{~k@5>j-*58hcC&r)D>udHa -z4h{|u4h{|u4h{|u4h{|u4h{|u4h{|u4h{|u4h{}KAk;biSKqH&=k>qvKDxSg<-fmt -zh+he@7#vlpTG9%wd=RMTc6!Ly?OnHcjNPo -zR~!Gn_OELnT{S-+aOeLH4h{~hjlZs~iIDjaut6q?*iQsK!YSDo1c!(ZKPEx?UWBFe -zA?1mEV5=>s|R)T@x(jakwvtB&kjG|Eo!P;APgNx40(# -zMomf!UPP0hd1=K@w0WLfs2cf@%dA6paUFV1I+&%-qk!>=o8G4t{&5&ncA@l}5to_$ -z?Zw&eHnFc)ItTfN`y1YI!M%?8V@tiD?ZFyziTNKMEYAOSh5zze=TKn0Cm>H&HMmd* -zFw0s|6Kil!#_7X?>CoBPMgut45SiJ -zo9J5N#N<;VB(H2KO#U_qc*ZJe7n4uKsOfpF>-d#S<%W78`ukNT{E);Po~zk}R3;HV -zF$r*SJ0c?-Rc?a1R-=^-V6SQsd+3nIWRgew&^f}QL*gVoK@lHO_Uw>Ekq@0AWt{^Y -zNrEP;`vVU?@gWr%S!%Ni<}<6E!mQpYo0Vk_CiwC^1Ft9J#;&e;k8)e$*+3F;M1yLr -zQ?n#4Mwrn*lRkFTeh;2p){3w#;&eF0Z{V59#m-5&-u`8S -zFPHsO`K$5N=TtlIWD~FZwQ_m{CATj*?QDG_N)w<$zT{%PEyb1UeQpCGAc9bUxX{N6_hX0=8Jjt%Fm2SyfRj -z9V_9wsv80o=o@44ROPC=86He}4vL6aH_37F$$9;T -z@s^qL-C2|uz3GN<76xknDJ@-HmZ+N*zY)lR;nCV_su3&C9L-k(Q`)Ac~-!)8MDvlj$o4THqXA6#M~=qjCC`f^c~jpiGcsv`s9E271mUh -zdrcqP==4!lF=v>*wfv$eNzA(q>=q|K4Yp#JB$-KWCKWA$n5dVEs#9G}>Q{APZJ;9( -zaQ!V-0jnO<`!0e~xpN9Jrg}UkpUK0g*)XEP?}>ieE`!upN+RAPBBcj3z$r0ijbPe# -ztc&-&#+k=7)bOCRpSK!nHjX;^6DD&W$321Znx3jt3@&s^Y17bZBd`m)aylhRbN~q! -zDa8?(7JMal$ji23q6j+bttoktHM5jNBst`am^Ou)Y|Mu=($ki#8dMOpHc#!+G;hJQ -zt-F+wbkc2UPt^s1Dp>Uj^{kj8?_AR8^&(JZYF(OHE3U4vQg}-Qre!pB4Qd72sODM$ -zf}+^AQ(u$hsgbPX+}ZtRq(+;f^Vq}f#zfUjCru`8r{i`N0(H5F!#BG7n0N%*o~9aG -zU4&m*=2S5<1m<{qFbN*hO>82MPQ*dy2E=wC1a|tprA@F}nw0dJ-H2Ahne$;M%sj%F -zn5GJ(;1IKs@g`j#Au!DN}IVH4fwm%#Kz!A%`=`mZ*e -I{>y>?0qjf_ZvX%Q - -literal 0 -HcmV?d00001 - -diff --git a/m4/db.m4 b/m4/db.m4 -index e8d54747b..f487ba2cc 100644 ---- a/m4/db.m4 -+++ b/m4/db.m4 -@@ -1,5 +1,5 @@ - # BEGIN COPYRIGHT BLOCK --# Copyright (C) 2022 Red Hat, Inc. -+# Copyright (C) 2024 Red Hat, Inc. - # All rights reserved. - # - # License: GPL (version 3 or any later version). -@@ -68,10 +68,37 @@ AC_ARG_WITH(db-lib, AS_HELP_STRING([--with-db-lib=PATH],[Berkeley DB library dir - ], - AC_MSG_RESULT(no)) - -+# check for --with-libbdb-ro -+AC_MSG_CHECKING(for --with-libbdb-ro) -+AC_ARG_WITH(libbdb-ro, AS_HELP_STRING([--with-libbdb-ro],[Use a read-only Berkeley Database shared library (default: use standard or bundled libbdb)]), -+[ -+ if test "$withval" = "yes"; then -+ with_libbdb_ro=yes -+ AC_MSG_RESULT(yes) -+ AC_SUBST(with_libbdb_ro) -+ else -+ with_libbdb_ro=no -+ AC_MSG_RESULT(no) -+ fi -+], -+[ -+ with_libbdb_ro=yes -+ AC_MSG_RESULT(yes) -+ AC_SUBST(with_libbdb_ro) -+]) -+AM_CONDITIONAL([WITH_LIBBDB_RO],[test "$with_libbdb_ro" != no]) -+ - dnl - check in system locations -+db_bdb_srcdir="ldap/servers/slapd/back-ldbm/db-bdb" - if test -z "$db_inc"; then - AC_MSG_CHECKING(for db.h) -- if test -f "/usr/include/db4/db.h"; then -+ if test "$with_libbdb_ro" = yes; then -+ AC_MSG_RESULT([using lib/librobdb/lib/robdb.h]) -+ db_incdir="lib/librobdb/lib" -+ db_inc="-Ilib/librobdb/lib" -+ db_libdir="" -+ db_lib="-lrobdb" -+ elif test -f "/usr/include/db4/db.h"; then - AC_MSG_RESULT([using /usr/include/db4/db.h]) - db_incdir="/usr/include/db4" - db_inc="-I/usr/include/db4" -@@ -96,9 +123,15 @@ if test -z "$db_inc"; then - fi - - dnl figure out which version of db we're using from the header file -+if test "$with_libbdb_ro" = yes; then -+db_ver_maj=5 -+db_ver_min=3 -+db_ver_pat=0 -+else - db_ver_maj=`grep DB_VERSION_MAJOR $db_incdir/db.h | awk '{print $3}'` - db_ver_min=`grep DB_VERSION_MINOR $db_incdir/db.h | awk '{print $3}'` - db_ver_pat=`grep DB_VERSION_PATCH $db_incdir/db.h | awk '{print $3}'` -+fi - - dnl Ensure that we have libdb at least 4.7, older versions aren't supported - if test ${db_ver_maj} -lt 4; then -@@ -111,12 +144,14 @@ dnl libname is libdb-maj.min e.g. libdb-4.2 - db_libver=${db_ver_maj}.${db_ver_min} - dnl make sure the lib is available - dnl use true so libdb won't be added to LIBS -+if test "$with_libbdb_ro" != yes; then - save_ldflags="$LDFLAGS" - LDFLAGS="$db_lib $LDFLAGS" - AC_CHECK_LIB([db-$db_libver], [db_create], [true], - [AC_MSG_ERROR([$db_incdir/db.h is version $db_libver but libdb-$db_libver not found])], - [$LIBNSL]) - LDFLAGS="$save_ldflags" -+fi - - # if DB is not found yet, try pkg-config - -@@ -133,7 +168,8 @@ else - db_bindir=/usr/bin - fi - -- -+AC_SUBST(db_bdb_srcdir) -+AC_SUBST(db_bdbro_srcdir) - AC_SUBST(db_inc) - AC_SUBST(db_incdir) - AC_SUBST(db_lib) -diff --git a/rpm.mk b/rpm.mk -index bc58e856f..f91011814 100644 ---- a/rpm.mk -+++ b/rpm.mk -@@ -26,6 +26,11 @@ RPMBUILD_OPTIONS += $(if $(filter 1, $(BUNDLE_LIBDB)),--with bundle_libdb,--with - LIBDB_URL ?= $(shell rpmspec $(RPMBUILD_OPTIONS) -P $(RPMBUILD)/SPECS/389-ds-base.spec | awk '/^Source4:/ {print $$2}') - LIBDB_TARBALL ?= $(shell basename "$(LIBDB_URL)") - -+# Check if BUNDLE_BDBREADERS is enabled. -+BUNDLE_BDBREADERS = $(shell ./rpm/is-robdb-used $(BUNDLE_LIBDB)) -+RPMBUILD_OPTIONS += $(if $(filter 1, $(BUNDLE_BDBREADERS)),--with libbdb_ro,--without libbdb_ro) -+ -+ - # Some sanitizers are supported only by clang - CLANG_ON = 0 - RPMBUILD_OPTIONS += $(if $(filter 1, $(CLANG_ON)),--with clang,--without clang) -@@ -111,7 +116,7 @@ endif - fi ; \ - if [ $(BUNDLE_LIBDB) -eq 1 ]; then \ - curl -LO $(LIBDB_URL) ; \ -- fi -+ fi ; - - rpmroot: - rm -rf $(RPMBUILD) -@@ -149,6 +154,7 @@ srpms: rpmroot srpmdistdir download-cargo-dependencies tarballs rpmbuildprep - python3 rpm/bundle-rust-npm.py $(CARGO_PATH) $(NODE_MODULES_PATH) $(RPMBUILD)/SPECS/$(PACKAGE).spec -f - rpmbuild --define "_topdir $(RPMBUILD)" -bs $(RPMBUILD)/SPECS/$(PACKAGE).spec $(RPMBUILD_OPTIONS) - cp $(RPMBUILD)/SRPMS/*.src.rpm dist/srpms/ -+ @echo RPMBUILD=$(RPMBUILD) - rm -rf $(RPMBUILD) - - srpm: srpms -@@ -164,8 +170,22 @@ rpms: rpmroot srpmdistdir rpmdistdir tarballs rpmbuildprep - rpmbuild --define "_topdir $(RPMBUILD)" -ba $(RPMBUILD)/SPECS/$(PACKAGE).spec $(RPMBUILD_OPTIONS) - cp $(RPMBUILD)/RPMS/*/*.rpm dist/rpms/ - cp $(RPMBUILD)/SRPMS/*.src.rpm dist/srpms/ -+ @echo RPMBUILD=$(RPMBUILD) - rm -rf $(RPMBUILD) - - rpm: rpms - - patch_rpms: | patch rpms -+ -+debug: -+ @echo BUNDLE_JEMALLOC=$(BUNDLE_JEMALLOC) -+ @echo BUNDLE_LIBDB=$(BUNDLE_LIBDB) -+ @echo BUNDLE_BDBREADERS=$(BUNDLE_BDBREADERS) -+ @echo CLANG_ON=$(CLANG_ON) -+ @echo ASAN_ON=$(ASAN_ON) -+ @echo MSAN_ON=$(MSAN_ON) -+ @echo TSAN_ON=$(TSAN_ON) -+ @echo UBSAN_ON=$(UBSAN_ON) -+ @echo COCKPIT_ON=$(COCKPIT_ON) -+ @echo JEMALLOC_URL=$(JEMALLOC_URL) -+ @echo LIBDB_URL=$(LIBDB_URL) -diff --git a/rpm/389-ds-base.spec.in b/rpm/389-ds-base.spec.in -index 2f1df63c9..ac749213b 100644 ---- a/rpm/389-ds-base.spec.in -+++ b/rpm/389-ds-base.spec.in -@@ -26,6 +26,12 @@ - %bcond repl_reports 1 - %endif - -+%if 0%{?fedora} >= 43 -+%bcond libbdb_ro 1 -+%else -+%bcond libbdb_ro 0 -+%endif -+ - # This is used in certain builds to help us know if it has extra features. - %global variant base - %global prerel __VERSION_PREREL__%{nil} -@@ -112,9 +118,11 @@ BuildRequires: libtsan - BuildRequires: libubsan - %endif - %endif -+%if %{without libbdb_ro} - %if %{without bundle_libdb} - BuildRequires: libdb-devel - %endif -+%endif - - # The following are needed to build the snmp ldap-agent - BuildRequires: net-snmp-devel -@@ -173,16 +181,22 @@ Requires: cyrus-sasl-md5 - # This is optionally supported by us, as we use it in our tests - Requires: cyrus-sasl-plain - # this is needed for backldbm -+%if %{with libbdb_ro} -+Requires: %{name}-robdb-libs = %{version}-%{release} -+%else - %if %{without bundle_libdb} - Requires: libdb - %endif -+%endif - Requires: lmdb - # This picks up libperl.so as a Requires, so we add this versioned one - Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) - # Needed by logconv.pl -+%if %{without libbdb_ro} - %if %{without bundle_libdb} - Requires: perl-DB_File - %endif -+%endif - Requires: perl-Archive-Tar - %if 0%{?fedora} >= 33 || 0%{?rhel} >= 9 - Requires: perl-debugger -@@ -217,6 +231,17 @@ isn't what you want. Please contact support immediately. - Please see http://seclists.org/oss-sec/2016/q1/363 for more information. - %endif - -+%if %{with libbdb_ro} -+%package robdb-libs -+Summary: Read-only Berkeley Database Library -+License: GPL-2.0-or-later OR LGPL-2.1-or-later -+ -+%description robdb-libs -+The %{name}-robdb-lib package contains a library derived from rpm -+project (https://github.com/rpm-software-management/rpm) that provides -+some basic functions to search and read Berkeley Database records -+%endif -+ - - %package libs - Summary: Core libraries for 389 Directory Server (%{variant}) -@@ -431,6 +456,11 @@ popd - autoreconf -fiv - - %configure \ -+%if %{with libbdb_ro} -+ --with-libbdb-ro \ -+%else -+ --without-libbdb-ro \ -+%endif - %if %{with bundle_libdb} - --with-bundle-libdb=%{_builddir}/%{libdb_base_version}/BUILD/%{libdb_base_dir}/dist/dist-tls \ - %endif -@@ -531,6 +561,21 @@ cp -pa $libdbbuilddir/dist/dist-tls/.libs/%{libdb_bundle_name} $RPM_BUILD_ROOT%{ - popd - %endif - -+%if %{with libbdb_ro} -+pushd lib/librobdb -+cp -pa COPYING %{_builddir}/%{name}-%{version}/COPYING.librobdb -+cp -pa COPYING.RPM %{_builddir}/%{name}-%{version}/COPYING.RPM -+install -m 0755 -d %{buildroot}/%{_libdir} -+install -m 0755 -d %{buildroot}/%{_docdir}/%{name}-robdb-libs -+install -m 0755 -d %{buildroot}/%{_licensedir}/%{name} -+install -m 0755 -d %{buildroot}/%{_licensedir}/%{name}-robdb-libs -+install -m 0644 $PWD/README.md %{buildroot}/%{_docdir}/%{name}-robdb-libs/README.md -+install -m 0644 $PWD/COPYING %{buildroot}/%{_licensedir}/%{name}-robdb-libs/COPYING -+install -m 0644 $PWD/COPYING.RPM %{buildroot}/%{_licensedir}/%{name}-robdb-libs/COPYING.RPM -+install -m 0644 $PWD/COPYING %{buildroot}/%{_licensedir}/%{name}/COPYING.librobdb -+install -m 0644 $PWD/COPYING.RPM %{buildroot}/%{_licensedir}/%{name}/COPYING.RPM -+popd -+%endif - - %check - # This checks the code, if it fails it prints why, then re-raises the fail to shortcircuit the rpm build. -@@ -700,6 +745,9 @@ fi - %exclude %{_libdir}/%{pkgname}/lib/libjemalloc_pic.a - %exclude %{_libdir}/%{pkgname}/lib/pkgconfig - %endif -+%if %{with libbdb_ro} -+%exclude %{_libdir}/%{pkgname}/librobdb.so -+%endif - - %files devel - %doc LICENSE LICENSE.GPLv3+ LICENSE.openssl README.devel -@@ -773,6 +821,17 @@ fi - %doc README.md - %endif - -+%if %{with libbdb_ro} -+%files robdb-libs -+%license COPYING.librobdb COPYING.RPM -+%doc %{_defaultdocdir}/%{name}-robdb-libs/README.md -+%{_libdir}/%{pkgname}/librobdb.so -+%{_licensedir}/%{name}-robdb-libs/COPYING -+%{_licensedir}/%{name}/COPYING.RPM -+%{_licensedir}/%{name}/COPYING.librobdb -+ -+%endif -+ - %changelog - %autochangelog - -diff --git a/rpm/is-robdb-used b/rpm/is-robdb-used -new file mode 100755 -index 000000000..3cb006d5a ---- /dev/null -+++ b/rpm/is-robdb-used -@@ -0,0 +1,45 @@ -+#!/usr/bin/python3 -+ -+# Determine if Read Only Berkeley Database is needed. -+# -+# argv[1] is BUNDLE_LIBDB -+import os -+import sys -+import re -+from contextlib import suppress -+ -+ -+def rc(val): -+ if (val): -+ print("1") -+ else: -+ print("0") -+ sys.exit(0) -+ -+def checkVersion(path, version, result): -+ with suppress(FileNotFoundError): -+ with open(path, 'rt') as fd: -+ line = fd.readline().lower() -+ print(f'MYDBG: line={line}') -+ match = re.match(r'.* release (\d+) ', line) -+ print(f'MYDBG: match={match}') -+ if match and int(match.group(1)) >= version: -+ rc(result) -+ -+# Not needed if bundled libdb is available (Typically on RHEL) -+with suppress(IndexError): -+ if sys.argv[1] == "1": -+ rc(False) -+ -+# Regular bdb is not installed ==> lets use Read Only Berkeley Database -+if not os.path.isfile('/usr/include/db.h'): -+ rc(True) -+ -+if os.getenv("WITH_ROBDB") is not None: -+ rc(True) -+ -+if os.getenv("WITHOUT_ROBDB") is not None: -+ rc(False) -+ -+checkVersion('/etc/fedora-release', 43, True) -+rc(False) -diff --git a/src/lib389/lib389/cli_ctl/dblib.py b/src/lib389/lib389/cli_ctl/dblib.py -index 71724a85e..d4005de82 100644 ---- a/src/lib389/lib389/cli_ctl/dblib.py -+++ b/src/lib389/lib389/cli_ctl/dblib.py -@@ -24,6 +24,7 @@ from lib389.cli_base import CustomHelpFormatter - from lib389._constants import DEFAULT_LMDB_SIZE, BDB_IMPL_STATUS, DN_CONFIG, DBSCAN - from lib389.dseldif import DSEldif - from lib389.utils import parse_size, format_size, check_plugin_strings, find_plugin_path -+from lib389.paths import Paths - from pathlib import Path - - -@@ -136,19 +137,23 @@ class DbscanHelper: - - - def get_bdb_impl_status(): -+ p = Paths() -+ p._read_defaults() -+ libdir = f"{p._config['slapd']['lib_dir']}/dirsrv" -+ robdb = glob.glob(f'{libdir}/librobdb.so*') -+ has_robdb = len(robdb) > 0 - backldbm = 'libback-ldbm' - bundledbdb_plugin = 'libback-bdb' -- robdb_symbol = 'bdbro_getcb_vector' - libdb = 'libdb-' -- plgstrs = check_plugin_strings(backldbm, [bundledbdb_plugin, robdb_symbol, libdb]) -+ plgstrs = check_plugin_strings(backldbm, [bundledbdb_plugin, libdb]) -+ if has_robdb is True: -+ # read-only bdb build -+ return BDB_IMPL_STATUS.READ_ONLY - if plgstrs[bundledbdb_plugin] is True: - # bundled bdb build - if find_plugin_path(bundledbdb_plugin): - return BDB_IMPL_STATUS.BUNDLED - return BDB_IMPL_STATUS.NONE -- if plgstrs[robdb_symbol] is True: -- # read-only bdb build -- return BDB_IMPL_STATUS.READ_ONLY - if plgstrs[libdb] is True: - # standard bdb package build - return BDB_IMPL_STATUS.STANDARD -@@ -445,6 +450,9 @@ def dblib_bdb2mdb(inst, log, args): - log.info(f"Backends exportation {progress*100/total_dbsize:2f}% ({bename})") - log.debug(f"inst.db2ldif({bename}, None, None, {encrypt}, True, {be['ldifname']})") - inst.db2ldif(bename, None, None, encrypt, True, be['ldifname'], False) -+ if not os.path.isfile(be['ldifname']): -+ raise RuntimeError(f"Failed to export backend {bename} into {be['ldifname']}.") -+ - be['cl5'] = export_changelog(be, 'bdb') - progress += be['dbsize'] - log.info("Backends exportation 100%") -diff --git a/src/lib389/lib389/topologies.py b/src/lib389/lib389/topologies.py -index eda0fd8ba..e7445245e 100644 ---- a/src/lib389/lib389/topologies.py -+++ b/src/lib389/lib389/topologies.py -@@ -22,6 +22,7 @@ from lib389.replica import Agreements, ReplicationManager, Replicas - from lib389.nss_ssl import NssSsl - from lib389._constants import * - from lib389.cli_base import LogCapture -+from lib389.cli_ctl.dblib import get_bdb_impl_status - - TLS_HOSTNAME_CHECK = os.getenv('TLS_HOSTNAME_CHECK', default=True) - HAPROXY_TRUSTED_IP = os.getenv('HAPROXY_TRUSTED_IP', default='') --- -2.49.0 - diff --git a/0018-Issue-6663-Fix-NULL-subsystem-crash-in-JSON-error-lo.patch b/0018-Issue-6663-Fix-NULL-subsystem-crash-in-JSON-error-lo.patch deleted file mode 100644 index c705ee7..0000000 --- a/0018-Issue-6663-Fix-NULL-subsystem-crash-in-JSON-error-lo.patch +++ /dev/null @@ -1,380 +0,0 @@ -From 697f0ed364b8649141adc283a6a45702d815421e Mon Sep 17 00:00:00 2001 -From: Akshay Adhikari -Date: Mon, 28 Jul 2025 18:14:15 +0530 -Subject: [PATCH] Issue 6663 - Fix NULL subsystem crash in JSON error logging - (#6883) - -Description: Fixes crash in JSON error logging when subsystem is NULL. -Parametrized test case for better debugging. - -Relates: https://github.com/389ds/389-ds-base/issues/6663 - -Reviewed by: @mreynolds389 ---- - .../tests/suites/clu/dsconf_logging.py | 168 ------------------ - .../tests/suites/clu/dsconf_logging_test.py | 164 +++++++++++++++++ - ldap/servers/slapd/log.c | 2 +- - 3 files changed, 165 insertions(+), 169 deletions(-) - delete mode 100644 dirsrvtests/tests/suites/clu/dsconf_logging.py - create mode 100644 dirsrvtests/tests/suites/clu/dsconf_logging_test.py - -diff --git a/dirsrvtests/tests/suites/clu/dsconf_logging.py b/dirsrvtests/tests/suites/clu/dsconf_logging.py -deleted file mode 100644 -index 1c2f7fc2e..000000000 ---- a/dirsrvtests/tests/suites/clu/dsconf_logging.py -+++ /dev/null -@@ -1,168 +0,0 @@ --# --- BEGIN COPYRIGHT BLOCK --- --# Copyright (C) 2025 Red Hat, Inc. --# All rights reserved. --# --# License: GPL (version 3 or any later version). --# See LICENSE for details. --# --- END COPYRIGHT BLOCK --- --# --import json --import subprocess --import logging --import pytest --from lib389._constants import DN_DM --from lib389.topologies import topology_st as topo -- --pytestmark = pytest.mark.tier1 -- --log = logging.getLogger(__name__) -- --SETTINGS = [ -- ('logging-enabled', None), -- ('logging-disabled', None), -- ('mode', '700'), -- ('compress-enabled', None), -- ('compress-disabled', None), -- ('buffering-enabled', None), -- ('buffering-disabled', None), -- ('max-logs', '4'), -- ('max-logsize', '7'), -- ('rotation-interval', '2'), -- ('rotation-interval-unit', 'week'), -- ('rotation-tod-enabled', None), -- ('rotation-tod-disabled', None), -- ('rotation-tod-hour', '12'), -- ('rotation-tod-minute', '20'), -- ('deletion-interval', '3'), -- ('deletion-interval-unit', 'day'), -- ('max-disk-space', '20'), -- ('free-disk-space', '2'), --] -- --DEFAULT_TIME_FORMAT = "%FT%TZ" -- -- --def execute_dsconf_command(dsconf_cmd, subcommands): -- """Execute dsconf command and return output and return code""" -- -- cmdline = dsconf_cmd + subcommands -- proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE) -- out, _ = proc.communicate() -- return out.decode('utf-8'), proc.returncode -- -- --def get_dsconf_base_cmd(topo): -- """Return base dsconf command list""" -- return ['/usr/sbin/dsconf', topo.standalone.serverid, -- '-j', '-D', DN_DM, '-w', 'password', 'logging'] -- -- --def test_log_settings(topo): -- """Test each log setting can be set successfully -- -- :id: b800fd03-37f5-4e74-9af8-eeb07030eb52 -- :setup: Standalone DS instance -- :steps: -- 1. Test each log's settings -- :expectedresults: -- 1. Success -- """ -- -- dsconf_cmd = get_dsconf_base_cmd(topo) -- for log_type in ['access', 'audit', 'auditfail', 'error', 'security']: -- # Test "get" command -- output, rc = execute_dsconf_command(dsconf_cmd, [log_type, 'get']) -- assert rc == 0 -- json_result = json.loads(output) -- default_location = json_result['Log name and location'] -- -- # Log location -- output, rc = execute_dsconf_command(dsconf_cmd, [log_type, 'set', -- 'location', -- f'/tmp/{log_type}']) -- assert rc == 0 -- output, rc = execute_dsconf_command(dsconf_cmd, [log_type, 'set', -- 'location', -- default_location]) -- assert rc == 0 -- -- # Log levels -- if log_type == "access": -- # List levels -- output, rc = execute_dsconf_command(dsconf_cmd, -- [log_type, 'list-levels']) -- assert rc == 0 -- -- # Set levels -- output, rc = execute_dsconf_command(dsconf_cmd, -- [log_type, 'set', 'level', -- 'internal']) -- assert rc == 0 -- output, rc = execute_dsconf_command(dsconf_cmd, -- [log_type, 'set', 'level', -- 'internal', 'entry']) -- assert rc == 0 -- output, rc = execute_dsconf_command(dsconf_cmd, -- [log_type, 'set', 'level', -- 'internal', 'default']) -- assert rc == 0 -- -- if log_type == "error": -- # List levels -- output, rc = execute_dsconf_command(dsconf_cmd, -- [log_type, 'list-levels']) -- assert rc == 0 -- -- # Set levels -- output, rc = execute_dsconf_command(dsconf_cmd, -- [log_type, 'set', 'level', -- 'plugin', 'replication']) -- assert rc == 0 -- output, rc = execute_dsconf_command(dsconf_cmd, -- [log_type, 'set', 'level', -- 'default']) -- assert rc == 0 -- -- # Log formats -- if log_type in ["access", "audit", "error"]: -- output, rc = execute_dsconf_command(dsconf_cmd, -- [log_type, 'set', -- 'time-format', '%D']) -- assert rc == 0 -- output, rc = execute_dsconf_command(dsconf_cmd, -- [log_type, 'set', -- 'time-format', -- DEFAULT_TIME_FORMAT]) -- assert rc == 0 -- -- output, rc = execute_dsconf_command(dsconf_cmd, -- [log_type, 'set', -- 'log-format', -- 'json']) -- assert rc == 0 -- output, rc = execute_dsconf_command(dsconf_cmd, -- [log_type, 'set', -- 'log-format', -- 'default']) -- assert rc == 0 -- -- # Audit log display attrs -- if log_type == "audit": -- output, rc = execute_dsconf_command(dsconf_cmd, -- [log_type, 'set', -- 'display-attrs', 'cn']) -- assert rc == 0 -- -- # Common settings -- for attr, value in SETTINGS: -- if log_type == "auditfail" and attr.startswith("buffer"): -- # auditfail doesn't have a buffering settings -- continue -- -- if value is None: -- output, rc = execute_dsconf_command(dsconf_cmd, [log_type, -- 'set', attr]) -- else: -- output, rc = execute_dsconf_command(dsconf_cmd, [log_type, -- 'set', attr, value]) -- assert rc == 0 -diff --git a/dirsrvtests/tests/suites/clu/dsconf_logging_test.py b/dirsrvtests/tests/suites/clu/dsconf_logging_test.py -new file mode 100644 -index 000000000..ca3f71997 ---- /dev/null -+++ b/dirsrvtests/tests/suites/clu/dsconf_logging_test.py -@@ -0,0 +1,164 @@ -+# --- BEGIN COPYRIGHT BLOCK --- -+# Copyright (C) 2025 Red Hat, Inc. -+# All rights reserved. -+# -+# License: GPL (version 3 or any later version). -+# See LICENSE for details. -+# --- END COPYRIGHT BLOCK --- -+# -+import json -+import subprocess -+import logging -+import pytest -+from lib389._constants import DN_DM -+from lib389.topologies import topology_st as topo -+ -+pytestmark = pytest.mark.tier1 -+ -+log = logging.getLogger(__name__) -+ -+SETTINGS = [ -+ ('logging-enabled', None), -+ ('logging-disabled', None), -+ ('mode', '700'), -+ ('compress-enabled', None), -+ ('compress-disabled', None), -+ ('buffering-enabled', None), -+ ('buffering-disabled', None), -+ ('max-logs', '4'), -+ ('max-logsize', '7'), -+ ('rotation-interval', '2'), -+ ('rotation-interval-unit', 'week'), -+ ('rotation-tod-enabled', None), -+ ('rotation-tod-disabled', None), -+ ('rotation-tod-hour', '12'), -+ ('rotation-tod-minute', '20'), -+ ('deletion-interval', '3'), -+ ('deletion-interval-unit', 'day'), -+ ('max-disk-space', '20'), -+ ('free-disk-space', '2'), -+] -+ -+DEFAULT_TIME_FORMAT = "%FT%TZ" -+ -+ -+def execute_dsconf_command(dsconf_cmd, subcommands): -+ """Execute dsconf command and return output and return code""" -+ -+ cmdline = dsconf_cmd + subcommands -+ proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE) -+ out, err = proc.communicate() -+ -+ if proc.returncode != 0 and err: -+ log.error(f"Command failed: {' '.join(cmdline)}") -+ log.error(f"Stderr: {err.decode('utf-8')}") -+ -+ return out.decode('utf-8'), proc.returncode -+ -+ -+def get_dsconf_base_cmd(topo): -+ """Return base dsconf command list""" -+ return ['/usr/sbin/dsconf', topo.standalone.serverid, -+ '-j', '-D', DN_DM, '-w', 'password', 'logging'] -+ -+ -+@pytest.mark.parametrize("log_type", ['access', 'audit', 'auditfail', 'error', 'security']) -+def test_log_settings(topo, log_type): -+ """Test each log setting can be set successfully -+ -+ :id: b800fd03-37f5-4e74-9af8-eeb07030eb52 -+ :setup: Standalone DS instance -+ :steps: -+ 1. Test each log's settings -+ :expectedresults: -+ 1. Success -+ """ -+ -+ dsconf_cmd = get_dsconf_base_cmd(topo) -+ -+ output, rc = execute_dsconf_command(dsconf_cmd, [log_type, 'get']) -+ assert rc == 0 -+ json_result = json.loads(output) -+ default_location = json_result['Log name and location'] -+ -+ output, rc = execute_dsconf_command(dsconf_cmd, [log_type, 'set', -+ 'location', -+ f'/tmp/{log_type}']) -+ assert rc == 0 -+ output, rc = execute_dsconf_command(dsconf_cmd, [log_type, 'set', -+ 'location', -+ default_location]) -+ assert rc == 0 -+ -+ if log_type == "access": -+ output, rc = execute_dsconf_command(dsconf_cmd, -+ [log_type, 'list-levels']) -+ assert rc == 0 -+ -+ output, rc = execute_dsconf_command(dsconf_cmd, -+ [log_type, 'set', 'level', -+ 'internal']) -+ assert rc == 0 -+ output, rc = execute_dsconf_command(dsconf_cmd, -+ [log_type, 'set', 'level', -+ 'internal', 'entry']) -+ assert rc == 0 -+ output, rc = execute_dsconf_command(dsconf_cmd, -+ [log_type, 'set', 'level', -+ 'internal', 'default']) -+ assert rc == 0 -+ -+ if log_type == "error": -+ output, rc = execute_dsconf_command(dsconf_cmd, -+ [log_type, 'list-levels']) -+ assert rc == 0 -+ -+ output, rc = execute_dsconf_command(dsconf_cmd, -+ [log_type, 'set', 'level', -+ 'plugin', 'replication']) -+ assert rc == 0 -+ output, rc = execute_dsconf_command(dsconf_cmd, -+ [log_type, 'set', 'level', -+ 'default']) -+ assert rc == 0 -+ -+ if log_type in ["access", "audit", "error"]: -+ output, rc = execute_dsconf_command(dsconf_cmd, -+ [log_type, 'set', -+ 'time-format', '%D']) -+ assert rc == 0 -+ output, rc = execute_dsconf_command(dsconf_cmd, -+ [log_type, 'set', -+ 'time-format', -+ DEFAULT_TIME_FORMAT]) -+ assert rc == 0 -+ -+ output, rc = execute_dsconf_command(dsconf_cmd, -+ [log_type, 'set', -+ 'log-format', -+ 'json']) -+ assert rc == 0, f"Failed to set {log_type} log-format to json: {output}" -+ -+ output, rc = execute_dsconf_command(dsconf_cmd, -+ [log_type, 'set', -+ 'log-format', -+ 'default']) -+ assert rc == 0, f"Failed to set {log_type} log-format to default: {output}" -+ -+ if log_type == "audit": -+ output, rc = execute_dsconf_command(dsconf_cmd, -+ [log_type, 'set', -+ 'display-attrs', 'cn']) -+ assert rc == 0 -+ -+ for attr, value in SETTINGS: -+ if log_type == "auditfail" and attr.startswith("buffer"): -+ continue -+ -+ if value is None: -+ output, rc = execute_dsconf_command(dsconf_cmd, [log_type, -+ 'set', attr]) -+ else: -+ output, rc = execute_dsconf_command(dsconf_cmd, [log_type, -+ 'set', attr, value]) -+ assert rc == 0 -diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c -index 06792a55a..91ba23047 100644 ---- a/ldap/servers/slapd/log.c -+++ b/ldap/servers/slapd/log.c -@@ -2949,7 +2949,7 @@ vslapd_log_error( - json_obj = json_object_new_object(); - json_object_object_add(json_obj, "local_time", json_object_new_string(local_time)); - json_object_object_add(json_obj, "severity", json_object_new_string(get_log_sev_name(sev_level, sev_name))); -- json_object_object_add(json_obj, "subsystem", json_object_new_string(subsystem)); -+ json_object_object_add(json_obj, "subsystem", json_object_new_string(subsystem ? subsystem : "")); - json_object_object_add(json_obj, "msg", json_object_new_string(vbuf)); - - PR_snprintf(buffer, sizeof(buffer), "%s\n", --- -2.49.0 - diff --git a/0019-Issue-6895-Crash-if-repl-keep-alive-entry-can-not-be.patch b/0019-Issue-6895-Crash-if-repl-keep-alive-entry-can-not-be.patch deleted file mode 100644 index f761b14..0000000 --- a/0019-Issue-6895-Crash-if-repl-keep-alive-entry-can-not-be.patch +++ /dev/null @@ -1,98 +0,0 @@ -From d3eee2527912785505feba9bedb6d0ae988c69e5 Mon Sep 17 00:00:00 2001 -From: Mark Reynolds -Date: Wed, 23 Jul 2025 19:35:32 -0400 -Subject: [PATCH] Issue 6895 - Crash if repl keep alive entry can not be - created - -Description: - -Heap use after free when logging that the replicaton keep-alive entry can not -be created. slapi_add_internal_pb() frees the slapi entry, then -we try and get the dn from the entry and we get a use-after-free crash. - -Relates: https://github.com/389ds/389-ds-base/issues/6895 - -Reviewed by: spichugi(Thanks!) ---- - ldap/servers/plugins/chainingdb/cb_config.c | 3 +-- - ldap/servers/plugins/posix-winsync/posix-winsync.c | 1 - - ldap/servers/plugins/replication/repl5_init.c | 3 --- - ldap/servers/plugins/replication/repl5_replica.c | 8 ++++---- - 4 files changed, 5 insertions(+), 10 deletions(-) - -diff --git a/ldap/servers/plugins/chainingdb/cb_config.c b/ldap/servers/plugins/chainingdb/cb_config.c -index 40a7088d7..24fa1bcb3 100644 ---- a/ldap/servers/plugins/chainingdb/cb_config.c -+++ b/ldap/servers/plugins/chainingdb/cb_config.c -@@ -44,8 +44,7 @@ cb_config_add_dse_entries(cb_backend *cb, char **entries, char *string1, char *s - slapi_pblock_get(util_pb, SLAPI_PLUGIN_INTOP_RESULT, &res); - if (LDAP_SUCCESS != res && LDAP_ALREADY_EXISTS != res) { - slapi_log_err(SLAPI_LOG_ERR, CB_PLUGIN_SUBSYSTEM, -- "cb_config_add_dse_entries - Unable to add config entry (%s) to the DSE: %s\n", -- slapi_entry_get_dn(e), -+ "cb_config_add_dse_entries - Unable to add config entry to the DSE: %s\n", - ldap_err2string(res)); - rc = res; - slapi_pblock_destroy(util_pb); -diff --git a/ldap/servers/plugins/posix-winsync/posix-winsync.c b/ldap/servers/plugins/posix-winsync/posix-winsync.c -index 51a55b643..3a002bb70 100644 ---- a/ldap/servers/plugins/posix-winsync/posix-winsync.c -+++ b/ldap/servers/plugins/posix-winsync/posix-winsync.c -@@ -1626,7 +1626,6 @@ posix_winsync_end_update_cb(void *cbdata __attribute__((unused)), - "posix_winsync_end_update_cb: " - "add task entry\n"); - } -- /* slapi_entry_free(e_task); */ - slapi_pblock_destroy(pb); - pb = NULL; - posix_winsync_config_reset_MOFTaskCreated(); -diff --git a/ldap/servers/plugins/replication/repl5_init.c b/ldap/servers/plugins/replication/repl5_init.c -index 8bc0b5372..5047fb8dc 100644 ---- a/ldap/servers/plugins/replication/repl5_init.c -+++ b/ldap/servers/plugins/replication/repl5_init.c -@@ -682,7 +682,6 @@ create_repl_schema_policy(void) - repl_schema_top, - ldap_err2string(return_value)); - rc = -1; -- slapi_entry_free(e); /* The entry was not consumed */ - goto done; - } - slapi_pblock_destroy(pb); -@@ -703,7 +702,6 @@ create_repl_schema_policy(void) - repl_schema_supplier, - ldap_err2string(return_value)); - rc = -1; -- slapi_entry_free(e); /* The entry was not consumed */ - goto done; - } - slapi_pblock_destroy(pb); -@@ -724,7 +722,6 @@ create_repl_schema_policy(void) - repl_schema_consumer, - ldap_err2string(return_value)); - rc = -1; -- slapi_entry_free(e); /* The entry was not consumed */ - goto done; - } - slapi_pblock_destroy(pb); -diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c -index 59062b46b..a97c807e9 100644 ---- a/ldap/servers/plugins/replication/repl5_replica.c -+++ b/ldap/servers/plugins/replication/repl5_replica.c -@@ -465,10 +465,10 @@ replica_subentry_create(const char *repl_root, ReplicaId rid) - if (return_value != LDAP_SUCCESS && - return_value != LDAP_ALREADY_EXISTS && - return_value != LDAP_REFERRAL /* CONSUMER */) { -- slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_subentry_create - Unable to " -- "create replication keep alive entry %s: error %d - %s\n", -- slapi_entry_get_dn_const(e), -- return_value, ldap_err2string(return_value)); -+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_subentry_create - " -+ "Unable to create replication keep alive entry 'cn=%s %d,%s': error %d - %s\n", -+ KEEP_ALIVE_ENTRY, rid, repl_root, -+ return_value, ldap_err2string(return_value)); - rc = -1; - goto done; - } --- -2.49.0 - diff --git a/0020-Issue-6884-Mask-password-hashes-in-audit-logs-6885.patch b/0020-Issue-6884-Mask-password-hashes-in-audit-logs-6885.patch deleted file mode 100644 index 41cd894..0000000 --- a/0020-Issue-6884-Mask-password-hashes-in-audit-logs-6885.patch +++ /dev/null @@ -1,814 +0,0 @@ -From e430e1849d40387714fd4c91613eb4bb11f211bb Mon Sep 17 00:00:00 2001 -From: Simon Pichugin -Date: Mon, 28 Jul 2025 15:41:29 -0700 -Subject: [PATCH] Issue 6884 - Mask password hashes in audit logs (#6885) - -Description: Fix the audit log functionality to mask password hash values for -userPassword, nsslapd-rootpw, nsmultiplexorcredentials, nsds5ReplicaCredentials, -and nsds5ReplicaBootstrapCredentials attributes in ADD and MODIFY operations. -Update auditlog.c to detect password attributes and replace their values with -asterisks (**********************) in both LDIF and JSON audit log formats. -Add a comprehensive test suite audit_password_masking_test.py to verify -password masking works correctly across all log formats and operation types. - -Fixes: https://github.com/389ds/389-ds-base/issues/6884 - -Reviewed by: @mreynolds389, @vashirov (Thanks!!) ---- - .../logging/audit_password_masking_test.py | 501 ++++++++++++++++++ - ldap/servers/slapd/auditlog.c | 170 +++++- - ldap/servers/slapd/slapi-private.h | 1 + - src/lib389/lib389/chaining.py | 3 +- - 4 files changed, 652 insertions(+), 23 deletions(-) - create mode 100644 dirsrvtests/tests/suites/logging/audit_password_masking_test.py - -diff --git a/dirsrvtests/tests/suites/logging/audit_password_masking_test.py b/dirsrvtests/tests/suites/logging/audit_password_masking_test.py -new file mode 100644 -index 000000000..3b6a54849 ---- /dev/null -+++ b/dirsrvtests/tests/suites/logging/audit_password_masking_test.py -@@ -0,0 +1,501 @@ -+# --- BEGIN COPYRIGHT BLOCK --- -+# Copyright (C) 2025 Red Hat, Inc. -+# All rights reserved. -+# -+# License: GPL (version 3 or any later version). -+# See LICENSE for details. -+# --- END COPYRIGHT BLOCK --- -+# -+import logging -+import pytest -+import os -+import re -+import time -+import ldap -+from lib389._constants import DEFAULT_SUFFIX, DN_DM, PW_DM -+from lib389.topologies import topology_m2 as topo -+from lib389.idm.user import UserAccounts -+from lib389.dirsrv_log import DirsrvAuditJSONLog -+from lib389.plugins import ChainingBackendPlugin -+from lib389.chaining import ChainingLinks -+from lib389.agreement import Agreements -+from lib389.replica import ReplicationManager, Replicas -+from lib389.idm.directorymanager import DirectoryManager -+ -+log = logging.getLogger(__name__) -+ -+MASKED_PASSWORD = "**********************" -+TEST_PASSWORD = "MySecret123" -+TEST_PASSWORD_2 = "NewPassword789" -+TEST_PASSWORD_3 = "NewPassword101" -+ -+ -+def setup_audit_logging(inst, log_format='default', display_attrs=None): -+ """Configure audit logging settings""" -+ inst.config.replace('nsslapd-auditlog-logbuffering', 'off') -+ inst.config.replace('nsslapd-auditlog-logging-enabled', 'on') -+ inst.config.replace('nsslapd-auditlog-log-format', log_format) -+ -+ if display_attrs is not None: -+ inst.config.replace('nsslapd-auditlog-display-attrs', display_attrs) -+ -+ inst.deleteAuditLogs() -+ -+ -+def check_password_masked(inst, log_format, expected_password, actual_password): -+ """Helper function to check password masking in audit logs""" -+ -+ time.sleep(1) # Allow log to flush -+ -+ # List of all password/credential attributes that should be masked -+ password_attributes = [ -+ 'userPassword', -+ 'nsslapd-rootpw', -+ 'nsmultiplexorcredentials', -+ 'nsDS5ReplicaCredentials', -+ 'nsDS5ReplicaBootstrapCredentials' -+ ] -+ -+ # Get password schemes to check for hash leakage -+ user_password_scheme = inst.config.get_attr_val_utf8('passwordStorageScheme') -+ root_password_scheme = inst.config.get_attr_val_utf8('nsslapd-rootpwstoragescheme') -+ -+ if log_format == 'json': -+ # Check JSON format logs -+ audit_log = DirsrvAuditJSONLog(inst) -+ log_lines = audit_log.readlines() -+ -+ found_masked = False -+ found_actual = False -+ found_hashed = False -+ -+ for line in log_lines: -+ # Check if any password attribute is present in the line -+ for attr in password_attributes: -+ if attr in line: -+ if expected_password in line: -+ found_masked = True -+ if actual_password in line: -+ found_actual = True -+ # Check for password scheme indicators (hashed passwords) -+ if user_password_scheme and f'{{{user_password_scheme}}}' in line: -+ found_hashed = True -+ if root_password_scheme and f'{{{root_password_scheme}}}' in line: -+ found_hashed = True -+ break # Found a password attribute, no need to check others for this line -+ -+ else: -+ # Check LDIF format logs -+ found_masked = False -+ found_actual = False -+ found_hashed = False -+ -+ # Check each password attribute for masked password -+ for attr in password_attributes: -+ if inst.ds_audit_log.match(f"{attr}: {re.escape(expected_password)}"): -+ found_masked = True -+ if inst.ds_audit_log.match(f"{attr}: {actual_password}"): -+ found_actual = True -+ -+ # Check for hashed passwords in LDIF format -+ if user_password_scheme: -+ if inst.ds_audit_log.match(f"userPassword: {{{user_password_scheme}}}"): -+ found_hashed = True -+ if root_password_scheme: -+ if inst.ds_audit_log.match(f"nsslapd-rootpw: {{{root_password_scheme}}}"): -+ found_hashed = True -+ -+ # Delete audit logs to avoid interference with other tests -+ # We need to reset the root password to default as deleteAuditLogs() -+ # opens a new connection with the default password -+ dm = DirectoryManager(inst) -+ dm.change_password(PW_DM) -+ inst.deleteAuditLogs() -+ -+ return found_masked, found_actual, found_hashed -+ -+ -+@pytest.mark.parametrize("log_format,display_attrs", [ -+ ("default", None), -+ ("default", "*"), -+ ("default", "userPassword"), -+ ("json", None), -+ ("json", "*"), -+ ("json", "userPassword") -+]) -+def test_password_masking_add_operation(topo, log_format, display_attrs): -+ """Test password masking in ADD operations -+ -+ :id: 4358bd75-bcc7-401c-b492-d3209b10412d -+ :parametrized: yes -+ :setup: Standalone Instance -+ :steps: -+ 1. Configure audit logging format -+ 2. Add user with password -+ 3. Check that password is masked in audit log -+ 4. Verify actual password does not appear in log -+ :expectedresults: -+ 1. Success -+ 2. Success -+ 3. Password should be masked with asterisks -+ 4. Actual password should not be found in log -+ """ -+ inst = topo.ms['supplier1'] -+ setup_audit_logging(inst, log_format, display_attrs) -+ -+ users = UserAccounts(inst, DEFAULT_SUFFIX) -+ user = None -+ -+ try: -+ user = users.create(properties={ -+ 'uid': 'test_add_pwd_mask', -+ 'cn': 'Test Add User', -+ 'sn': 'User', -+ 'uidNumber': '1000', -+ 'gidNumber': '1000', -+ 'homeDirectory': '/home/test_add', -+ 'userPassword': TEST_PASSWORD -+ }) -+ -+ found_masked, found_actual, found_hashed = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD) -+ -+ assert found_masked, f"Masked password not found in {log_format} ADD operation" -+ assert not found_actual, f"Actual password found in {log_format} ADD log (should be masked)" -+ assert not found_hashed, f"Hashed password found in {log_format} ADD log (should be masked)" -+ -+ finally: -+ if user is not None: -+ try: -+ user.delete() -+ except: -+ pass -+ -+ -+@pytest.mark.parametrize("log_format,display_attrs", [ -+ ("default", None), -+ ("default", "*"), -+ ("default", "userPassword"), -+ ("json", None), -+ ("json", "*"), -+ ("json", "userPassword") -+]) -+def test_password_masking_modify_operation(topo, log_format, display_attrs): -+ """Test password masking in MODIFY operations -+ -+ :id: e6963aa9-7609-419c-aae2-1d517aa434bd -+ :parametrized: yes -+ :setup: Standalone Instance -+ :steps: -+ 1. Configure audit logging format -+ 2. Add user without password -+ 3. Add password via MODIFY operation -+ 4. Check that password is masked in audit log -+ 5. Modify password to new value -+ 6. Check that new password is also masked -+ 7. Verify actual passwords do not appear in log -+ :expectedresults: -+ 1. Success -+ 2. Success -+ 3. Success -+ 4. Password should be masked with asterisks -+ 5. Success -+ 6. New password should be masked with asterisks -+ 7. No actual password values should be found in log -+ """ -+ inst = topo.ms['supplier1'] -+ setup_audit_logging(inst, log_format, display_attrs) -+ -+ users = UserAccounts(inst, DEFAULT_SUFFIX) -+ user = None -+ -+ try: -+ user = users.create(properties={ -+ 'uid': 'test_modify_pwd_mask', -+ 'cn': 'Test Modify User', -+ 'sn': 'User', -+ 'uidNumber': '2000', -+ 'gidNumber': '2000', -+ 'homeDirectory': '/home/test_modify' -+ }) -+ -+ user.replace('userPassword', TEST_PASSWORD) -+ -+ found_masked, found_actual, found_hashed = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD) -+ assert found_masked, f"Masked password not found in {log_format} MODIFY operation (first password)" -+ assert not found_actual, f"Actual password found in {log_format} MODIFY log (should be masked)" -+ assert not found_hashed, f"Hashed password found in {log_format} MODIFY log (should be masked)" -+ -+ user.replace('userPassword', TEST_PASSWORD_2) -+ -+ found_masked_2, found_actual_2, found_hashed_2 = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD_2) -+ assert found_masked_2, f"Masked password not found in {log_format} MODIFY operation (second password)" -+ assert not found_actual_2, f"Second actual password found in {log_format} MODIFY log (should be masked)" -+ assert not found_hashed_2, f"Second hashed password found in {log_format} MODIFY log (should be masked)" -+ -+ finally: -+ if user is not None: -+ try: -+ user.delete() -+ except: -+ pass -+ -+ -+@pytest.mark.parametrize("log_format,display_attrs", [ -+ ("default", None), -+ ("default", "*"), -+ ("default", "nsslapd-rootpw"), -+ ("json", None), -+ ("json", "*"), -+ ("json", "nsslapd-rootpw") -+]) -+def test_password_masking_rootpw_modify_operation(topo, log_format, display_attrs): -+ """Test password masking for nsslapd-rootpw MODIFY operations -+ -+ :id: ec8c9fd4-56ba-4663-ab65-58efb3b445e4 -+ :parametrized: yes -+ :setup: Standalone Instance -+ :steps: -+ 1. Configure audit logging format -+ 2. Modify nsslapd-rootpw in configuration -+ 3. Check that root password is masked in audit log -+ 4. Modify root password to new value -+ 5. Check that new root password is also masked -+ 6. Verify actual root passwords do not appear in log -+ :expectedresults: -+ 1. Success -+ 2. Success -+ 3. Root password should be masked with asterisks -+ 4. Success -+ 5. New root password should be masked with asterisks -+ 6. No actual root password values should be found in log -+ """ -+ inst = topo.ms['supplier1'] -+ setup_audit_logging(inst, log_format, display_attrs) -+ dm = DirectoryManager(inst) -+ -+ try: -+ dm.change_password(TEST_PASSWORD) -+ dm.rebind(TEST_PASSWORD) -+ -+ found_masked, found_actual, found_hashed = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD) -+ assert found_masked, f"Masked root password not found in {log_format} MODIFY operation (first root password)" -+ assert not found_actual, f"Actual root password found in {log_format} MODIFY log (should be masked)" -+ assert not found_hashed, f"Hashed root password found in {log_format} MODIFY log (should be masked)" -+ -+ dm.change_password(TEST_PASSWORD_2) -+ dm.rebind(TEST_PASSWORD_2) -+ -+ found_masked_2, found_actual_2, found_hashed_2 = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD_2) -+ assert found_masked_2, f"Masked root password not found in {log_format} MODIFY operation (second root password)" -+ assert not found_actual_2, f"Second actual root password found in {log_format} MODIFY log (should be masked)" -+ assert not found_hashed_2, f"Second hashed root password found in {log_format} MODIFY log (should be masked)" -+ -+ finally: -+ dm.change_password(PW_DM) -+ dm.rebind(PW_DM) -+ -+ -+@pytest.mark.parametrize("log_format,display_attrs", [ -+ ("default", None), -+ ("default", "*"), -+ ("default", "nsmultiplexorcredentials"), -+ ("json", None), -+ ("json", "*"), -+ ("json", "nsmultiplexorcredentials") -+]) -+def test_password_masking_multiplexor_credentials(topo, log_format, display_attrs): -+ """Test password masking for nsmultiplexorcredentials in chaining/multiplexor configurations -+ -+ :id: 161a9498-b248-4926-90be-a696a36ed36e -+ :parametrized: yes -+ :setup: Standalone Instance -+ :steps: -+ 1. Configure audit logging format -+ 2. Create a chaining backend configuration entry with nsmultiplexorcredentials -+ 3. Check that multiplexor credentials are masked in audit log -+ 4. Modify the credentials -+ 5. Check that updated credentials are also masked -+ 6. Verify actual credentials do not appear in log -+ :expectedresults: -+ 1. Success -+ 2. Success -+ 3. Multiplexor credentials should be masked with asterisks -+ 4. Success -+ 5. Updated credentials should be masked with asterisks -+ 6. No actual credential values should be found in log -+ """ -+ inst = topo.ms['supplier1'] -+ setup_audit_logging(inst, log_format, display_attrs) -+ -+ # Enable chaining plugin and create chaining link -+ chain_plugin = ChainingBackendPlugin(inst) -+ chain_plugin.enable() -+ -+ chains = ChainingLinks(inst) -+ chain = None -+ -+ try: -+ # Create chaining link with multiplexor credentials -+ chain = chains.create(properties={ -+ 'cn': 'testchain', -+ 'nsfarmserverurl': 'ldap://localhost:389/', -+ 'nsslapd-suffix': 'dc=example,dc=com', -+ 'nsmultiplexorbinddn': 'cn=manager', -+ 'nsmultiplexorcredentials': TEST_PASSWORD, -+ 'nsCheckLocalACI': 'on', -+ 'nsConnectionLife': '30', -+ }) -+ -+ found_masked, found_actual, found_hashed = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD) -+ assert found_masked, f"Masked multiplexor credentials not found in {log_format} ADD operation" -+ assert not found_actual, f"Actual multiplexor credentials found in {log_format} ADD log (should be masked)" -+ assert not found_hashed, f"Hashed multiplexor credentials found in {log_format} ADD log (should be masked)" -+ -+ # Modify the credentials -+ chain.replace('nsmultiplexorcredentials', TEST_PASSWORD_2) -+ -+ found_masked_2, found_actual_2, found_hashed_2 = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD_2) -+ assert found_masked_2, f"Masked multiplexor credentials not found in {log_format} MODIFY operation" -+ assert not found_actual_2, f"Actual multiplexor credentials found in {log_format} MODIFY log (should be masked)" -+ assert not found_hashed_2, f"Hashed multiplexor credentials found in {log_format} MODIFY log (should be masked)" -+ -+ finally: -+ chain_plugin.disable() -+ if chain is not None: -+ inst.delete_branch_s(chain.dn, ldap.SCOPE_ONELEVEL) -+ chain.delete() -+ -+ -+@pytest.mark.parametrize("log_format,display_attrs", [ -+ ("default", None), -+ ("default", "*"), -+ ("default", "nsDS5ReplicaCredentials"), -+ ("json", None), -+ ("json", "*"), -+ ("json", "nsDS5ReplicaCredentials") -+]) -+def test_password_masking_replica_credentials(topo, log_format, display_attrs): -+ """Test password masking for nsDS5ReplicaCredentials in replication agreements -+ -+ :id: 7bf9e612-1b7c-49af-9fc0-de4c7df84b2a -+ :parametrized: yes -+ :setup: Standalone Instance -+ :steps: -+ 1. Configure audit logging format -+ 2. Create a replication agreement entry with nsDS5ReplicaCredentials -+ 3. Check that replica credentials are masked in audit log -+ 4. Modify the credentials -+ 5. Check that updated credentials are also masked -+ 6. Verify actual credentials do not appear in log -+ :expectedresults: -+ 1. Success -+ 2. Success -+ 3. Replica credentials should be masked with asterisks -+ 4. Success -+ 5. Updated credentials should be masked with asterisks -+ 6. No actual credential values should be found in log -+ """ -+ inst = topo.ms['supplier2'] -+ setup_audit_logging(inst, log_format, display_attrs) -+ agmt = None -+ -+ try: -+ replicas = Replicas(inst) -+ replica = replicas.get(DEFAULT_SUFFIX) -+ agmts = replica.get_agreements() -+ agmt = agmts.create(properties={ -+ 'cn': 'testagmt', -+ 'nsDS5ReplicaHost': 'localhost', -+ 'nsDS5ReplicaPort': '389', -+ 'nsDS5ReplicaBindDN': 'cn=replication manager,cn=config', -+ 'nsDS5ReplicaCredentials': TEST_PASSWORD, -+ 'nsDS5ReplicaRoot': DEFAULT_SUFFIX -+ }) -+ -+ found_masked, found_actual, found_hashed = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD) -+ assert found_masked, f"Masked replica credentials not found in {log_format} ADD operation" -+ assert not found_actual, f"Actual replica credentials found in {log_format} ADD log (should be masked)" -+ assert not found_hashed, f"Hashed replica credentials found in {log_format} ADD log (should be masked)" -+ -+ # Modify the credentials -+ agmt.replace('nsDS5ReplicaCredentials', TEST_PASSWORD_2) -+ -+ found_masked_2, found_actual_2, found_hashed_2 = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD_2) -+ assert found_masked_2, f"Masked replica credentials not found in {log_format} MODIFY operation" -+ assert not found_actual_2, f"Actual replica credentials found in {log_format} MODIFY log (should be masked)" -+ assert not found_hashed_2, f"Hashed replica credentials found in {log_format} MODIFY log (should be masked)" -+ -+ finally: -+ if agmt is not None: -+ agmt.delete() -+ -+ -+@pytest.mark.parametrize("log_format,display_attrs", [ -+ ("default", None), -+ ("default", "*"), -+ ("default", "nsDS5ReplicaBootstrapCredentials"), -+ ("json", None), -+ ("json", "*"), -+ ("json", "nsDS5ReplicaBootstrapCredentials") -+]) -+def test_password_masking_bootstrap_credentials(topo, log_format, display_attrs): -+ """Test password masking for nsDS5ReplicaCredentials and nsDS5ReplicaBootstrapCredentials in replication agreements -+ -+ :id: 248bd418-ffa4-4733-963d-2314c60b7c5b -+ :parametrized: yes -+ :setup: Standalone Instance -+ :steps: -+ 1. Configure audit logging format -+ 2. Create a replication agreement entry with both nsDS5ReplicaCredentials and nsDS5ReplicaBootstrapCredentials -+ 3. Check that both credentials are masked in audit log -+ 4. Modify both credentials -+ 5. Check that both updated credentials are also masked -+ 6. Verify actual credentials do not appear in log -+ :expectedresults: -+ 1. Success -+ 2. Success -+ 3. Both credentials should be masked with asterisks -+ 4. Success -+ 5. Both updated credentials should be masked with asterisks -+ 6. No actual credential values should be found in log -+ """ -+ inst = topo.ms['supplier2'] -+ setup_audit_logging(inst, log_format, display_attrs) -+ agmt = None -+ -+ try: -+ replicas = Replicas(inst) -+ replica = replicas.get(DEFAULT_SUFFIX) -+ agmts = replica.get_agreements() -+ agmt = agmts.create(properties={ -+ 'cn': 'testbootstrapagmt', -+ 'nsDS5ReplicaHost': 'localhost', -+ 'nsDS5ReplicaPort': '389', -+ 'nsDS5ReplicaBindDN': 'cn=replication manager,cn=config', -+ 'nsDS5ReplicaCredentials': TEST_PASSWORD, -+ 'nsDS5replicabootstrapbinddn': 'cn=bootstrap manager,cn=config', -+ 'nsDS5ReplicaBootstrapCredentials': TEST_PASSWORD_2, -+ 'nsDS5ReplicaRoot': DEFAULT_SUFFIX -+ }) -+ -+ found_masked_bootstrap, found_actual_bootstrap, found_hashed_bootstrap = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD_2) -+ assert found_masked_bootstrap, f"Masked bootstrap credentials not found in {log_format} ADD operation" -+ assert not found_actual_bootstrap, f"Actual bootstrap credentials found in {log_format} ADD log (should be masked)" -+ assert not found_hashed_bootstrap, f"Hashed bootstrap credentials found in {log_format} ADD log (should be masked)" -+ -+ agmt.replace('nsDS5ReplicaBootstrapCredentials', TEST_PASSWORD_3) -+ -+ found_masked_bootstrap_2, found_actual_bootstrap_2, found_hashed_bootstrap_2 = check_password_masked(inst, log_format, MASKED_PASSWORD, TEST_PASSWORD_3) -+ assert found_masked_bootstrap_2, f"Masked bootstrap credentials not found in {log_format} MODIFY operation" -+ assert not found_actual_bootstrap_2, f"Actual bootstrap credentials found in {log_format} MODIFY log (should be masked)" -+ assert not found_hashed_bootstrap_2, f"Hashed bootstrap credentials found in {log_format} MODIFY log (should be masked)" -+ -+ finally: -+ if agmt is not None: -+ agmt.delete() -+ -+ -+ -+if __name__ == '__main__': -+ CURRENT_FILE = os.path.realpath(__file__) -+ pytest.main(["-s", CURRENT_FILE]) -\ No newline at end of file -diff --git a/ldap/servers/slapd/auditlog.c b/ldap/servers/slapd/auditlog.c -index 1121aef35..7b591e072 100644 ---- a/ldap/servers/slapd/auditlog.c -+++ b/ldap/servers/slapd/auditlog.c -@@ -39,6 +39,89 @@ static void write_audit_file(Slapi_PBlock *pb, Slapi_Entry *entry, int logtype, - - static const char *modrdn_changes[4]; - -+/* Helper function to check if an attribute is a password that needs masking */ -+static int -+is_password_attribute(const char *attr_name) -+{ -+ return (strcasecmp(attr_name, SLAPI_USERPWD_ATTR) == 0 || -+ strcasecmp(attr_name, CONFIG_ROOTPW_ATTRIBUTE) == 0 || -+ strcasecmp(attr_name, SLAPI_MB_CREDENTIALS) == 0 || -+ strcasecmp(attr_name, SLAPI_REP_CREDENTIALS) == 0 || -+ strcasecmp(attr_name, SLAPI_REP_BOOTSTRAP_CREDENTIALS) == 0); -+} -+ -+/* Helper function to create a masked string representation of an entry */ -+static char * -+create_masked_entry_string(Slapi_Entry *original_entry, int *len) -+{ -+ Slapi_Attr *attr = NULL; -+ char *entry_str = NULL; -+ char *current_pos = NULL; -+ char *line_start = NULL; -+ char *next_line = NULL; -+ char *colon_pos = NULL; -+ int has_password_attrs = 0; -+ -+ if (original_entry == NULL) { -+ return NULL; -+ } -+ -+ /* Single pass through attributes to check for password attributes */ -+ for (slapi_entry_first_attr(original_entry, &attr); attr != NULL; -+ slapi_entry_next_attr(original_entry, attr, &attr)) { -+ -+ char *attr_name = NULL; -+ slapi_attr_get_type(attr, &attr_name); -+ -+ if (is_password_attribute(attr_name)) { -+ has_password_attrs = 1; -+ break; -+ } -+ } -+ -+ /* If no password attributes, return original string - no masking needed */ -+ entry_str = slapi_entry2str(original_entry, len); -+ if (!has_password_attrs) { -+ return entry_str; -+ } -+ -+ /* Process the string in-place, replacing password values */ -+ current_pos = entry_str; -+ while ((line_start = current_pos) != NULL && *line_start != '\0') { -+ /* Find the end of current line */ -+ next_line = strchr(line_start, '\n'); -+ if (next_line != NULL) { -+ *next_line = '\0'; /* Temporarily terminate line */ -+ current_pos = next_line + 1; -+ } else { -+ current_pos = NULL; /* Last line */ -+ } -+ -+ /* Find the colon that separates attribute name from value */ -+ colon_pos = strchr(line_start, ':'); -+ if (colon_pos != NULL) { -+ char saved_colon = *colon_pos; -+ *colon_pos = '\0'; /* Temporarily null-terminate attribute name */ -+ -+ /* Check if this is a password attribute that needs masking */ -+ if (is_password_attribute(line_start)) { -+ strcpy(colon_pos + 1, " **********************"); -+ } -+ -+ *colon_pos = saved_colon; /* Restore colon */ -+ } -+ -+ /* Restore newline if it was there */ -+ if (next_line != NULL) { -+ *next_line = '\n'; -+ } -+ } -+ -+ /* Update length since we may have shortened the string */ -+ *len = strlen(entry_str); -+ return entry_str; /* Return the modified original string */ -+} -+ - void - write_audit_log_entry(Slapi_PBlock *pb) - { -@@ -282,10 +365,31 @@ add_entry_attrs_ext(Slapi_Entry *entry, lenstr *l, PRBool use_json, json_object - { - slapi_entry_attr_find(entry, req_attr, &entry_attr); - if (entry_attr) { -- if (use_json) { -- log_entry_attr_json(entry_attr, req_attr, id_list); -+ if (strcmp(req_attr, PSEUDO_ATTR_UNHASHEDUSERPASSWORD) == 0) { -+ /* Do not write the unhashed clear-text password */ -+ continue; -+ } -+ -+ /* Check if this is a password attribute that needs masking */ -+ if (is_password_attribute(req_attr)) { -+ /* userpassword/rootdn password - mask the value */ -+ if (use_json) { -+ json_object *secret_obj = json_object_new_object(); -+ json_object_object_add(secret_obj, req_attr, -+ json_object_new_string("**********************")); -+ json_object_array_add(id_list, secret_obj); -+ } else { -+ addlenstr(l, "#"); -+ addlenstr(l, req_attr); -+ addlenstr(l, ": **********************\n"); -+ } - } else { -- log_entry_attr(entry_attr, req_attr, l); -+ /* Regular attribute - log normally */ -+ if (use_json) { -+ log_entry_attr_json(entry_attr, req_attr, id_list); -+ } else { -+ log_entry_attr(entry_attr, req_attr, l); -+ } - } - } - } -@@ -300,9 +404,7 @@ add_entry_attrs_ext(Slapi_Entry *entry, lenstr *l, PRBool use_json, json_object - continue; - } - -- if (strcasecmp(attr, SLAPI_USERPWD_ATTR) == 0 || -- strcasecmp(attr, CONFIG_ROOTPW_ATTRIBUTE) == 0) -- { -+ if (is_password_attribute(attr)) { - /* userpassword/rootdn password - mask the value */ - if (use_json) { - json_object *secret_obj = json_object_new_object(); -@@ -312,7 +414,7 @@ add_entry_attrs_ext(Slapi_Entry *entry, lenstr *l, PRBool use_json, json_object - } else { - addlenstr(l, "#"); - addlenstr(l, attr); -- addlenstr(l, ": ****************************\n"); -+ addlenstr(l, ": **********************\n"); - } - continue; - } -@@ -481,6 +583,9 @@ write_audit_file_json(Slapi_PBlock *pb, Slapi_Entry *entry, int logtype, - } - } - -+ /* Check if this is a password attribute that needs masking */ -+ int is_password_attr = is_password_attribute(mods[j]->mod_type); -+ - mod = json_object_new_object(); - switch (operationtype) { - case LDAP_MOD_ADD: -@@ -505,7 +610,12 @@ write_audit_file_json(Slapi_PBlock *pb, Slapi_Entry *entry, int logtype, - json_object *val_list = NULL; - val_list = json_object_new_array(); - for (size_t i = 0; mods[j]->mod_bvalues != NULL && mods[j]->mod_bvalues[i] != NULL; i++) { -- json_object_array_add(val_list, json_object_new_string(mods[j]->mod_bvalues[i]->bv_val)); -+ if (is_password_attr) { -+ /* Mask password values */ -+ json_object_array_add(val_list, json_object_new_string("**********************")); -+ } else { -+ json_object_array_add(val_list, json_object_new_string(mods[j]->mod_bvalues[i]->bv_val)); -+ } - } - json_object_object_add(mod, "values", val_list); - } -@@ -517,8 +627,11 @@ write_audit_file_json(Slapi_PBlock *pb, Slapi_Entry *entry, int logtype, - } - case SLAPI_OPERATION_ADD: { - int len; -+ - e = change; -- tmp = slapi_entry2str(e, &len); -+ -+ /* Create a masked string representation for password attributes */ -+ tmp = create_masked_entry_string(e, &len); - tmpsave = tmp; - while ((tmp = strchr(tmp, '\n')) != NULL) { - tmp++; -@@ -665,6 +778,10 @@ write_audit_file( - break; - } - } -+ -+ /* Check if this is a password attribute that needs masking */ -+ int is_password_attr = is_password_attribute(mods[j]->mod_type); -+ - switch (operationtype) { - case LDAP_MOD_ADD: - addlenstr(l, "add: "); -@@ -689,18 +806,27 @@ write_audit_file( - break; - } - if (operationtype != LDAP_MOD_IGNORE) { -- for (i = 0; mods[j]->mod_bvalues != NULL && mods[j]->mod_bvalues[i] != NULL; i++) { -- char *buf, *bufp; -- len = strlen(mods[j]->mod_type); -- len = LDIF_SIZE_NEEDED(len, mods[j]->mod_bvalues[i]->bv_len) + 1; -- buf = slapi_ch_malloc(len); -- bufp = buf; -- slapi_ldif_put_type_and_value_with_options(&bufp, mods[j]->mod_type, -- mods[j]->mod_bvalues[i]->bv_val, -- mods[j]->mod_bvalues[i]->bv_len, 0); -- *bufp = '\0'; -- addlenstr(l, buf); -- slapi_ch_free((void **)&buf); -+ if (is_password_attr) { -+ /* Add masked password */ -+ for (i = 0; mods[j]->mod_bvalues != NULL && mods[j]->mod_bvalues[i] != NULL; i++) { -+ addlenstr(l, mods[j]->mod_type); -+ addlenstr(l, ": **********************\n"); -+ } -+ } else { -+ /* Add actual values for non-password attributes */ -+ for (i = 0; mods[j]->mod_bvalues != NULL && mods[j]->mod_bvalues[i] != NULL; i++) { -+ char *buf, *bufp; -+ len = strlen(mods[j]->mod_type); -+ len = LDIF_SIZE_NEEDED(len, mods[j]->mod_bvalues[i]->bv_len) + 1; -+ buf = slapi_ch_malloc(len); -+ bufp = buf; -+ slapi_ldif_put_type_and_value_with_options(&bufp, mods[j]->mod_type, -+ mods[j]->mod_bvalues[i]->bv_val, -+ mods[j]->mod_bvalues[i]->bv_len, 0); -+ *bufp = '\0'; -+ addlenstr(l, buf); -+ slapi_ch_free((void **)&buf); -+ } - } - } - addlenstr(l, "-\n"); -@@ -711,7 +837,7 @@ write_audit_file( - e = change; - addlenstr(l, attr_changetype); - addlenstr(l, ": add\n"); -- tmp = slapi_entry2str(e, &len); -+ tmp = create_masked_entry_string(e, &len); - tmpsave = tmp; - while ((tmp = strchr(tmp, '\n')) != NULL) { - tmp++; -diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h -index e9abf8b75..02f22fd2d 100644 ---- a/ldap/servers/slapd/slapi-private.h -+++ b/ldap/servers/slapd/slapi-private.h -@@ -848,6 +848,7 @@ void task_cleanup(void); - /* for reversible encyrption */ - #define SLAPI_MB_CREDENTIALS "nsmultiplexorcredentials" - #define SLAPI_REP_CREDENTIALS "nsds5ReplicaCredentials" -+#define SLAPI_REP_BOOTSTRAP_CREDENTIALS "nsds5ReplicaBootstrapCredentials" - int pw_rever_encode(Slapi_Value **vals, char *attr_name); - int pw_rever_decode(char *cipher, char **plain, const char *attr_name); - -diff --git a/src/lib389/lib389/chaining.py b/src/lib389/lib389/chaining.py -index 533b83ebf..33ae78c8b 100644 ---- a/src/lib389/lib389/chaining.py -+++ b/src/lib389/lib389/chaining.py -@@ -134,7 +134,7 @@ class ChainingLink(DSLdapObject): - """ - - # Create chaining entry -- super(ChainingLink, self).create(rdn, properties, basedn) -+ link = super(ChainingLink, self).create(rdn, properties, basedn) - - # Create mapping tree entry - dn_comps = ldap.explode_dn(properties['nsslapd-suffix'][0]) -@@ -149,6 +149,7 @@ class ChainingLink(DSLdapObject): - self._mts.ensure_state(properties=mt_properties) - except ldap.ALREADY_EXISTS: - pass -+ return link - - - class ChainingLinks(DSLdapObjects): --- -2.49.0 - diff --git a/0021-Issue-6778-Memory-leak-in-roles_cache_create_object_.patch b/0021-Issue-6778-Memory-leak-in-roles_cache_create_object_.patch deleted file mode 100644 index dab3729..0000000 --- a/0021-Issue-6778-Memory-leak-in-roles_cache_create_object_.patch +++ /dev/null @@ -1,262 +0,0 @@ -From 572fe6c91fda1c2cfd3afee894c922edccf9c1f1 Mon Sep 17 00:00:00 2001 -From: Viktor Ashirov -Date: Wed, 16 Jul 2025 11:22:30 +0200 -Subject: [PATCH] Issue 6778 - Memory leak in - roles_cache_create_object_from_entry part 2 - -Bug Description: -Everytime a role with scope DN is processed, we leak rolescopeDN. - -Fix Description: -* Initialize all pointer variables to NULL -* Add additional NULL checks -* Free rolescopeDN -* Move test_rewriter_with_invalid_filter before the DB contains 90k entries -* Use task.wait() for import task completion instead of parsing logs, -increase the timeout - -Fixes: https://github.com/389ds/389-ds-base/issues/6778 - -Reviewed by: @progier389 (Thanks!) ---- - dirsrvtests/tests/suites/roles/basic_test.py | 164 +++++++++---------- - ldap/servers/plugins/roles/roles_cache.c | 10 +- - 2 files changed, 82 insertions(+), 92 deletions(-) - -diff --git a/dirsrvtests/tests/suites/roles/basic_test.py b/dirsrvtests/tests/suites/roles/basic_test.py -index d92d6f0c3..ec208bae9 100644 ---- a/dirsrvtests/tests/suites/roles/basic_test.py -+++ b/dirsrvtests/tests/suites/roles/basic_test.py -@@ -510,6 +510,76 @@ def test_vattr_on_managed_role(topo, request): - - request.addfinalizer(fin) - -+def test_rewriter_with_invalid_filter(topo, request): -+ """Test that server does not crash when having -+ invalid filter in filtered role -+ -+ :id: 5013b0b2-0af6-11f0-8684-482ae39447e5 -+ :setup: standalone server -+ :steps: -+ 1. Setup filtered role with good filter -+ 2. Setup nsrole rewriter -+ 3. Restart the server -+ 4. Search for entries -+ 5. Setup filtered role with bad filter -+ 6. Search for entries -+ :expectedresults: -+ 1. Operation should succeed -+ 2. Operation should succeed -+ 3. Operation should succeed -+ 4. Operation should succeed -+ 5. Operation should succeed -+ 6. Operation should succeed -+ """ -+ inst = topo.standalone -+ entries = [] -+ -+ def fin(): -+ inst.start() -+ for entry in entries: -+ entry.delete() -+ request.addfinalizer(fin) -+ -+ # Setup filtered role -+ roles = FilteredRoles(inst, f'ou=people,{DEFAULT_SUFFIX}') -+ filter_ko = '(&((objectClass=top)(objectClass=nsPerson))' -+ filter_ok = '(&(objectClass=top)(objectClass=nsPerson))' -+ role_properties = { -+ 'cn': 'TestFilteredRole', -+ 'nsRoleFilter': filter_ok, -+ 'description': 'Test good filter', -+ } -+ role = roles.create(properties=role_properties) -+ entries.append(role) -+ -+ # Setup nsrole rewriter -+ rewriters = Rewriters(inst) -+ rewriter_properties = { -+ "cn": "nsrole", -+ "nsslapd-libpath": 'libroles-plugin', -+ "nsslapd-filterrewriter": 'role_nsRole_filter_rewriter', -+ } -+ rewriter = rewriters.ensure_state(properties=rewriter_properties) -+ entries.append(rewriter) -+ -+ # Restart thge instance -+ inst.restart() -+ -+ # Search for entries -+ entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, "(nsrole=%s)" % role.dn) -+ -+ # Set bad filter -+ role_properties = { -+ 'cn': 'TestFilteredRole', -+ 'nsRoleFilter': filter_ko, -+ 'description': 'Test bad filter', -+ } -+ role.ensure_state(properties=role_properties) -+ -+ # Search for entries -+ entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, "(nsrole=%s)" % role.dn) -+ -+ - def test_managed_and_filtered_role_rewrite(topo, request): - """Test that filter components containing 'nsrole=xxx' - are reworked if xxx is either a filtered role or a managed -@@ -581,17 +651,11 @@ def test_managed_and_filtered_role_rewrite(topo, request): - PARENT="ou=people,%s" % DEFAULT_SUFFIX - dbgen_users(topo.standalone, 90000, import_ldif, DEFAULT_SUFFIX, entry_name=RDN, generic=True, parent=PARENT) - -- # online import -+ # Online import - import_task = ImportTask(topo.standalone) - import_task.import_suffix_from_ldif(ldiffile=import_ldif, suffix=DEFAULT_SUFFIX) -- # Check for up to 200sec that the completion -- for i in range(1, 20): -- if len(topo.standalone.ds_error_log.match('.*import userRoot: Import complete. Processed 9000.*')) > 0: -- break -- time.sleep(10) -- import_complete = topo.standalone.ds_error_log.match('.*import userRoot: Import complete. Processed 9000.*') -- assert (len(import_complete) == 1) -- -+ import_task.wait(timeout=400) -+ assert import_task.get_exit_code() == 0 - # Restart server - topo.standalone.restart() - -@@ -715,17 +779,11 @@ def test_not_such_entry_role_rewrite(topo, request): - PARENT="ou=people,%s" % DEFAULT_SUFFIX - dbgen_users(topo.standalone, 91000, import_ldif, DEFAULT_SUFFIX, entry_name=RDN, generic=True, parent=PARENT) - -- # online import -+ # Online import - import_task = ImportTask(topo.standalone) - import_task.import_suffix_from_ldif(ldiffile=import_ldif, suffix=DEFAULT_SUFFIX) -- # Check for up to 200sec that the completion -- for i in range(1, 20): -- if len(topo.standalone.ds_error_log.match('.*import userRoot: Import complete. Processed 9100.*')) > 0: -- break -- time.sleep(10) -- import_complete = topo.standalone.ds_error_log.match('.*import userRoot: Import complete. Processed 9100.*') -- assert (len(import_complete) == 1) -- -+ import_task.wait(timeout=400) -+ assert import_task.get_exit_code() == 0 - # Restart server - topo.standalone.restart() - -@@ -769,76 +827,6 @@ def test_not_such_entry_role_rewrite(topo, request): - request.addfinalizer(fin) - - --def test_rewriter_with_invalid_filter(topo, request): -- """Test that server does not crash when having -- invalid filter in filtered role -- -- :id: 5013b0b2-0af6-11f0-8684-482ae39447e5 -- :setup: standalone server -- :steps: -- 1. Setup filtered role with good filter -- 2. Setup nsrole rewriter -- 3. Restart the server -- 4. Search for entries -- 5. Setup filtered role with bad filter -- 6. Search for entries -- :expectedresults: -- 1. Operation should succeed -- 2. Operation should succeed -- 3. Operation should succeed -- 4. Operation should succeed -- 5. Operation should succeed -- 6. Operation should succeed -- """ -- inst = topo.standalone -- entries = [] -- -- def fin(): -- inst.start() -- for entry in entries: -- entry.delete() -- request.addfinalizer(fin) -- -- # Setup filtered role -- roles = FilteredRoles(inst, f'ou=people,{DEFAULT_SUFFIX}') -- filter_ko = '(&((objectClass=top)(objectClass=nsPerson))' -- filter_ok = '(&(objectClass=top)(objectClass=nsPerson))' -- role_properties = { -- 'cn': 'TestFilteredRole', -- 'nsRoleFilter': filter_ok, -- 'description': 'Test good filter', -- } -- role = roles.create(properties=role_properties) -- entries.append(role) -- -- # Setup nsrole rewriter -- rewriters = Rewriters(inst) -- rewriter_properties = { -- "cn": "nsrole", -- "nsslapd-libpath": 'libroles-plugin', -- "nsslapd-filterrewriter": 'role_nsRole_filter_rewriter', -- } -- rewriter = rewriters.ensure_state(properties=rewriter_properties) -- entries.append(rewriter) -- -- # Restart thge instance -- inst.restart() -- -- # Search for entries -- entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, "(nsrole=%s)" % role.dn) -- -- # Set bad filter -- role_properties = { -- 'cn': 'TestFilteredRole', -- 'nsRoleFilter': filter_ko, -- 'description': 'Test bad filter', -- } -- role.ensure_state(properties=role_properties) -- -- # Search for entries -- entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, "(nsrole=%s)" % role.dn) -- -- - if __name__ == "__main__": - CURRENT_FILE = os.path.realpath(__file__) - pytest.main("-s -v %s" % CURRENT_FILE) -diff --git a/ldap/servers/plugins/roles/roles_cache.c b/ldap/servers/plugins/roles/roles_cache.c -index 3e1c5b429..05cabc3a3 100644 ---- a/ldap/servers/plugins/roles/roles_cache.c -+++ b/ldap/servers/plugins/roles/roles_cache.c -@@ -1117,16 +1117,17 @@ roles_cache_create_object_from_entry(Slapi_Entry *role_entry, role_object **resu - - rolescopeDN = slapi_entry_attr_get_charptr(role_entry, ROLE_SCOPE_DN); - if (rolescopeDN) { -- Slapi_DN *rolescopeSDN; -- Slapi_DN *top_rolescopeSDN, *top_this_roleSDN; -+ Slapi_DN *rolescopeSDN = NULL; -+ Slapi_DN *top_rolescopeSDN = NULL; -+ Slapi_DN *top_this_roleSDN = NULL; - - /* Before accepting to use this scope, first check if it belongs to the same suffix */ - rolescopeSDN = slapi_sdn_new_dn_byref(rolescopeDN); -- if ((strlen((char *)slapi_sdn_get_ndn(rolescopeSDN)) > 0) && -+ if (rolescopeSDN && (strlen((char *)slapi_sdn_get_ndn(rolescopeSDN)) > 0) && - (slapi_dn_syntax_check(NULL, (char *)slapi_sdn_get_ndn(rolescopeSDN), 1) == 0)) { - top_rolescopeSDN = roles_cache_get_top_suffix(rolescopeSDN); - top_this_roleSDN = roles_cache_get_top_suffix(this_role->dn); -- if (slapi_sdn_compare(top_rolescopeSDN, top_this_roleSDN) == 0) { -+ if (top_rolescopeSDN && top_this_roleSDN && slapi_sdn_compare(top_rolescopeSDN, top_this_roleSDN) == 0) { - /* rolescopeDN belongs to the same suffix as the role, we can use this scope */ - this_role->rolescopedn = rolescopeSDN; - } else { -@@ -1148,6 +1149,7 @@ roles_cache_create_object_from_entry(Slapi_Entry *role_entry, role_object **resu - rolescopeDN); - slapi_sdn_free(&rolescopeSDN); - } -+ slapi_ch_free_string(&rolescopeDN); - } - - /* Depending upon role type, pull out the remaining information we need */ --- -2.49.0 - diff --git a/0022-Issue-6901-Update-changelog-trimming-logging-fix-tes.patch b/0022-Issue-6901-Update-changelog-trimming-logging-fix-tes.patch deleted file mode 100644 index b1adff0..0000000 --- a/0022-Issue-6901-Update-changelog-trimming-logging-fix-tes.patch +++ /dev/null @@ -1,64 +0,0 @@ -From dbaf0ccfb54be40e2854e3979bb4460e26851b5a Mon Sep 17 00:00:00 2001 -From: Viktor Ashirov -Date: Mon, 28 Jul 2025 13:16:10 +0200 -Subject: [PATCH] Issue 6901 - Update changelog trimming logging - fix tests - -Description: -Update changelog_trimming_test for the new error message. - -Fixes: https://github.com/389ds/389-ds-base/issues/6901 - -Reviewed by: @progier389, @aadhikar (Thanks!) ---- - .../suites/replication/changelog_trimming_test.py | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/dirsrvtests/tests/suites/replication/changelog_trimming_test.py b/dirsrvtests/tests/suites/replication/changelog_trimming_test.py -index 2d70d328e..27d19e8fd 100644 ---- a/dirsrvtests/tests/suites/replication/changelog_trimming_test.py -+++ b/dirsrvtests/tests/suites/replication/changelog_trimming_test.py -@@ -110,7 +110,7 @@ def test_max_age(topo, setup_max_age): - do_mods(supplier, 10) - - time.sleep(1) # Trimming should not have occurred -- if supplier.searchErrorsLog("Trimmed") is True: -+ if supplier.searchErrorsLog("trimmed") is True: - log.fatal('Trimming event unexpectedly occurred') - assert False - -@@ -120,12 +120,12 @@ def test_max_age(topo, setup_max_age): - cl.set_trim_interval('5') - - time.sleep(3) # Trimming should not have occurred -- if supplier.searchErrorsLog("Trimmed") is True: -+ if supplier.searchErrorsLog("trimmed") is True: - log.fatal('Trimming event unexpectedly occurred') - assert False - - time.sleep(3) # Trimming should have occurred -- if supplier.searchErrorsLog("Trimmed") is False: -+ if supplier.searchErrorsLog("trimmed") is False: - log.fatal('Trimming event did not occur') - assert False - -@@ -159,7 +159,7 @@ def test_max_entries(topo, setup_max_entries): - do_mods(supplier, 10) - - time.sleep(1) # Trimming should have occurred -- if supplier.searchErrorsLog("Trimmed") is True: -+ if supplier.searchErrorsLog("trimmed") is True: - log.fatal('Trimming event unexpectedly occurred') - assert False - -@@ -169,7 +169,7 @@ def test_max_entries(topo, setup_max_entries): - cl.set_trim_interval('5') - - time.sleep(6) # Trimming should have occurred -- if supplier.searchErrorsLog("Trimmed") is False: -+ if supplier.searchErrorsLog("trimmed") is False: - log.fatal('Trimming event did not occur') - assert False - --- -2.49.0 - diff --git a/0023-Issue-6181-RFE-Allow-system-to-manage-uid-gid-at-sta.patch b/0023-Issue-6181-RFE-Allow-system-to-manage-uid-gid-at-sta.patch deleted file mode 100644 index 1d9b8b5..0000000 --- a/0023-Issue-6181-RFE-Allow-system-to-manage-uid-gid-at-sta.patch +++ /dev/null @@ -1,32 +0,0 @@ -From b34cec9c719c6dcb5f3ff24b9fd9e20eb233eadf Mon Sep 17 00:00:00 2001 -From: Viktor Ashirov -Date: Mon, 28 Jul 2025 13:18:26 +0200 -Subject: [PATCH] Issue 6181 - RFE - Allow system to manage uid/gid at startup - -Description: -Expand CapabilityBoundingSet to include CAP_FOWNER - -Relates: https://github.com/389ds/389-ds-base/issues/6181 -Relates: https://github.com/389ds/389-ds-base/issues/6906 - -Reviewed by: @progier389 (Thanks!) ---- - wrappers/systemd.template.service.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/wrappers/systemd.template.service.in b/wrappers/systemd.template.service.in -index ada608c86..8d2b96c7e 100644 ---- a/wrappers/systemd.template.service.in -+++ b/wrappers/systemd.template.service.in -@@ -29,7 +29,7 @@ MemoryAccounting=yes - - # Allow non-root instances to bind to low ports. - AmbientCapabilities=CAP_NET_BIND_SERVICE --CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETUID CAP_SETGID CAP_DAC_OVERRIDE CAP_CHOWN -+CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETUID CAP_SETGID CAP_DAC_OVERRIDE CAP_CHOWN CAP_FOWNER - - PrivateTmp=on - # https://en.opensuse.org/openSUSE:Security_Features#Systemd_hardening_effort --- -2.49.0 - diff --git a/0024-Issue-6468-CLI-Fix-default-error-log-level.patch b/0024-Issue-6468-CLI-Fix-default-error-log-level.patch deleted file mode 100644 index d79aa08..0000000 --- a/0024-Issue-6468-CLI-Fix-default-error-log-level.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 403077fd337a6221e95f704b4fcd70fe09d1d7e3 Mon Sep 17 00:00:00 2001 -From: Viktor Ashirov -Date: Tue, 29 Jul 2025 08:00:00 +0200 -Subject: [PATCH] Issue 6468 - CLI - Fix default error log level - -Description: -Default error log level is 16384 - -Relates: https://github.com/389ds/389-ds-base/issues/6468 - -Reviewed by: @droideck (Thanks!) ---- - src/lib389/lib389/cli_conf/logging.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/lib389/lib389/cli_conf/logging.py b/src/lib389/lib389/cli_conf/logging.py -index 124556f1f..d9ae1ab16 100644 ---- a/src/lib389/lib389/cli_conf/logging.py -+++ b/src/lib389/lib389/cli_conf/logging.py -@@ -44,7 +44,7 @@ ERROR_LEVELS = { - + "methods used for a SASL bind" - }, - "default": { -- "level": 6384, -+ "level": 16384, - "desc": "Default logging level" - }, - "filter": { --- -2.49.0 - diff --git a/0025-Issue-6768-ns-slapd-crashes-when-a-referral-is-added.patch b/0025-Issue-6768-ns-slapd-crashes-when-a-referral-is-added.patch deleted file mode 100644 index ba3b8a8..0000000 --- a/0025-Issue-6768-ns-slapd-crashes-when-a-referral-is-added.patch +++ /dev/null @@ -1,97 +0,0 @@ -From ec7c5a58c7decf94ba5011656c68597778f6059c Mon Sep 17 00:00:00 2001 -From: James Chapman -Date: Fri, 1 Aug 2025 13:27:02 +0100 -Subject: [PATCH] Issue 6768 - ns-slapd crashes when a referral is added - (#6780) - -Bug description: When a paged result search is successfully run on a referred -suffix, we retrieve the search result set from the pblock and try to release -it. In this case the search result set is NULL, which triggers a SEGV during -the release. - -Fix description: If the search result code is LDAP_REFERRAL, skip deletion of -the search result set. Added test case. - -Fixes: https://github.com/389ds/389-ds-base/issues/6768 - -Reviewed by: @tbordaz, @progier389 (Thank you) ---- - .../paged_results/paged_results_test.py | 46 +++++++++++++++++++ - ldap/servers/slapd/opshared.c | 4 +- - 2 files changed, 49 insertions(+), 1 deletion(-) - -diff --git a/dirsrvtests/tests/suites/paged_results/paged_results_test.py b/dirsrvtests/tests/suites/paged_results/paged_results_test.py -index fca48db0f..1bb94b53a 100644 ---- a/dirsrvtests/tests/suites/paged_results/paged_results_test.py -+++ b/dirsrvtests/tests/suites/paged_results/paged_results_test.py -@@ -1271,6 +1271,52 @@ def test_search_stress_abandon(create_40k_users, create_user): - paged_search(conn, create_40k_users.suffix, [req_ctrl], search_flt, searchreq_attrlist, abandon_rate=abandon_rate) - - -+def test_search_referral(topology_st): -+ """Test a paged search on a referred suffix doesnt crash the server. -+ -+ :id: c788bdbf-965b-4f12-ac24-d4d695e2cce2 -+ -+ :setup: Standalone instance -+ -+ :steps: -+ 1. Configure a default referral. -+ 2. Create a paged result search control. -+ 3. Paged result search on referral suffix (doesnt exist on the instance, triggering a referral). -+ 4. Check the server is still running. -+ 5. Remove referral. -+ -+ :expectedresults: -+ 1. Referral sucessfully set. -+ 2. Control created. -+ 3. Search returns ldap.REFERRAL (10). -+ 4. Server still running. -+ 5. Referral removed. -+ """ -+ -+ page_size = 5 -+ SEARCH_SUFFIX = "dc=referme,dc=com" -+ REFERRAL = "ldap://localhost.localdomain:389/o%3dnetscaperoot" -+ -+ log.info('Configuring referral') -+ topology_st.standalone.config.set('nsslapd-referral', REFERRAL) -+ referral = topology_st.standalone.config.get_attr_val_utf8('nsslapd-referral') -+ assert (referral == REFERRAL) -+ -+ log.info('Create paged result search control') -+ req_ctrl = SimplePagedResultsControl(True, size=page_size, cookie='') -+ -+ log.info('Perform a paged result search on referred suffix, no chase') -+ with pytest.raises(ldap.REFERRAL): -+ topology_st.standalone.search_ext_s(SEARCH_SUFFIX, ldap.SCOPE_SUBTREE, serverctrls=[req_ctrl]) -+ -+ log.info('Confirm instance is still running') -+ assert (topology_st.standalone.status()) -+ -+ log.info('Remove referral') -+ topology_st.standalone.config.remove_all('nsslapd-referral') -+ referral = topology_st.standalone.config.get_attr_val_utf8('nsslapd-referral') -+ assert (referral == None) -+ - if __name__ == '__main__': - # Run isolated - # -s for DEBUG mode -diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c -index 545518748..a5cddfd23 100644 ---- a/ldap/servers/slapd/opshared.c -+++ b/ldap/servers/slapd/opshared.c -@@ -910,7 +910,9 @@ op_shared_search(Slapi_PBlock *pb, int send_result) - /* Free the results if not "no_such_object" */ - void *sr = NULL; - slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr); -- be->be_search_results_release(&sr); -+ if (be->be_search_results_release != NULL) { -+ be->be_search_results_release(&sr); -+ } - } - pagedresults_set_search_result(pb_conn, operation, NULL, 1, pr_idx); - rc = pagedresults_set_current_be(pb_conn, NULL, pr_idx, 1); --- -2.49.0 - diff --git a/0026-Issue-6430-Fix-build-with-bundled-libdb.patch b/0026-Issue-6430-Fix-build-with-bundled-libdb.patch deleted file mode 100644 index b1c5fb8..0000000 --- a/0026-Issue-6430-Fix-build-with-bundled-libdb.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 8d0320144a3996c63e50a8e3792e8c1de3dcd76b Mon Sep 17 00:00:00 2001 -From: Yaakov Selkowitz -Date: Wed, 20 Aug 2025 17:43:30 -0400 -Subject: [PATCH] Issue 6430 - Fix build with bundled libdb - -Description: -The libbdb_ro change (#6431) added a `WITH_LIBBDB_RO` automake conditional -and a `db_bdb_srcdir` autoconf substitution which must also be defined when -building --with-bundle-libdb. - -Related: https://github.com/389ds/389-ds-base/pull/6431 ---- - m4/bundle_libdb.m4 | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/m4/bundle_libdb.m4 b/m4/bundle_libdb.m4 -index 3ae3beb49..a182378f1 100644 ---- a/m4/bundle_libdb.m4 -+++ b/m4/bundle_libdb.m4 -@@ -27,7 +27,10 @@ else - AC_MSG_RESULT([libdb-${db_ver_maj}.${db_ver_min}-389ds.so]) - fi - -+db_bdb_srcdir="ldap/servers/slapd/back-ldbm/db-bdb" - -+AM_CONDITIONAL([WITH_LIBBDB_RO],[false]) -+AC_SUBST(db_bdb_srcdir) - AC_SUBST(db_inc) - AC_SUBST(db_lib) - AC_SUBST(db_libver) --- -2.50.1 - diff --git a/389-ds-base.spec b/389-ds-base.spec index 87d27e5..df9cf96 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -75,7 +75,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (%{variant}) Name: 389-ds-base -Version: 3.1.3 +Version: 3.2.0 Release: %{autorelease -n %{?with_asan:-e asan}}%{?dist} License: GPL-3.0-or-later WITH GPL-3.0-389-ds-base-exception AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR LGPL-2.1-or-later OR MIT) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-3.0 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0 AND Zlib URL: https://www.port389.org @@ -220,7 +220,7 @@ Provides: bundled(npm(argparse)) = 2.0.1 Provides: bundled(npm(attr-accept)) = 2.2.4 Provides: bundled(npm(autolinker)) = 3.16.2 Provides: bundled(npm(balanced-match)) = 1.0.2 -Provides: bundled(npm(brace-expansion)) = 1.1.11 +Provides: bundled(npm(brace-expansion)) = 1.1.12 Provides: bundled(npm(callsites)) = 3.1.0 Provides: bundled(npm(chalk)) = 4.1.2 Provides: bundled(npm(color-convert)) = 2.0.1 @@ -289,7 +289,7 @@ Provides: bundled(npm(isexe)) = 2.0.0 Provides: bundled(npm(js-sha1)) = 0.7.0 Provides: bundled(npm(js-sha256)) = 0.11.0 Provides: bundled(npm(js-tokens)) = 4.0.0 -Provides: bundled(npm(js-yaml)) = 4.1.0 +Provides: bundled(npm(js-yaml)) = 4.1.1 Provides: bundled(npm(json-buffer)) = 3.0.1 Provides: bundled(npm(json-schema-traverse)) = 0.4.1 Provides: bundled(npm(json-stable-stringify-without-jsonify)) = 1.0.1 @@ -510,37 +510,6 @@ Source4: 389-ds-base.sysusers Source5: https://fedorapeople.org/groups/389ds/libdb-5.3.28-59.tar.bz2 %endif -Patch: 0001-Issue-6782-Improve-paged-result-locking.patch -Patch: 0002-Issue-6822-Backend-creation-cleanup-and-Database-UI-.patch -Patch: 0003-Issue-6753-Add-add_exclude_subtree-and-remove_exclud.patch -Patch: 0004-Issue-6857-uiduniq-allow-specifying-match-rules-in-t.patch -Patch: 0005-Issue-6756-CLI-UI-Properly-handle-disabled-NDN-cache.patch -Patch: 0006-Issue-6854-Refactor-for-improved-data-management-685.patch -Patch: 0007-Issue-6850-AddressSanitizer-memory-leak-in-mdb_init.patch -Patch: 0008-Issue-6848-AddressSanitizer-leak-in-do_search.patch -Patch: 0009-Issue-6865-AddressSanitizer-leak-in-agmt_update_init.patch -Patch: 0010-Issue-6868-UI-schema-attribute-table-expansion-break.patch -Patch: 0011-Issue-6859-str2filter-is-not-fully-applying-matching.patch -Patch: 0012-Issue-6872-compressed-log-rotation-creates-files-wit.patch -Patch: 0013-Issue-6888-Missing-access-JSON-logging-for-TLS-Clien.patch -Patch: 0014-Issue-6772-dsconf-Replicas-with-the-consumer-role-al.patch -Patch: 0015-Issue-6893-Log-user-that-is-updated-during-password-.patch -Patch: 0016-Issue-6901-Update-changelog-trimming-logging.patch -Patch: 0017-Issue-6430-implement-read-only-bdb-6431.patch -Patch: 0018-Issue-6663-Fix-NULL-subsystem-crash-in-JSON-error-lo.patch -Patch: 0019-Issue-6895-Crash-if-repl-keep-alive-entry-can-not-be.patch -Patch: 0020-Issue-6884-Mask-password-hashes-in-audit-logs-6885.patch -Patch: 0021-Issue-6778-Memory-leak-in-roles_cache_create_object_.patch -Patch: 0022-Issue-6901-Update-changelog-trimming-logging-fix-tes.patch -Patch: 0023-Issue-6181-RFE-Allow-system-to-manage-uid-gid-at-sta.patch -Patch: 0024-Issue-6468-CLI-Fix-default-error-log-level.patch -Patch: 0025-Issue-6768-ns-slapd-crashes-when-a-referral-is-added.patch -Patch: 0026-Issue-6430-Fix-build-with-bundled-libdb.patch - -# For ELN -Patch: 0001-Issue-5120-Fix-compilation-error.patch -Patch: 0001-Issue-6929-Compilation-failure-with-rust-1.89-on-Fed.patch - %description 389 Directory Server is an LDAPv3 compliant server. The base package includes the LDAP server and command line utilities for server administration. @@ -553,7 +522,8 @@ Please see http://seclists.org/oss-sec/2016/q1/363 for more information. %if %{with libbdb_ro} %package robdb-libs Summary: Read-only Berkeley Database Library -License: GPL-3.0-or-later WITH GPL-3.0-389-ds-base-exception AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR LGPL-2.1-or-later OR MIT) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-3.0 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0 AND Zlib +# IMPORTANT - Check if it looks right. Additionally, compare with the original line. Then, remove this comment and # FIXME - part. +# FIXME - License: GPL-3.0-or-later WITH GPL-3.0-389-ds-base-exception AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR LGPL-2.1-or-later OR MIT) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-3.0 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0 AND Zlib %description robdb-libs The %{name}-robdb-lib package contains a library derived from rpm @@ -1113,4 +1083,174 @@ exit 0 %endif %changelog +* Tue Dec 16 2025 Mark Reynolds - 2.4.4 +- Issue 7147 - entrycache_eviction_test is failing (#7148) +- Issue 1793 - RFE - Dynamic lists - UI and CLI updates +- Issue 7119 - Fix DNA shared config replication test (#7143) +- Issue 7081 - Repl Log Analysis - Implement data sampling with performance and timezone fixes (#7086) +- Issue 1793 - RFE - Implement dynamic lists +- Issue 7112 - dsctrl dblib bdb2mdb core dumps and won't allow conversion (#7144) +- Issue 7053 - Remove memberof_del_dn_from_groups from MemberOf plugin (#7064) +- Issue 7138 - test_cleanallruv_repl does not restart supplier3 (#7139) +- Issue 6753 - Port ticket47921 test to indirect_cos_test using DSLdapObject (#7134) +- Issue 7128 - memory corruption in alias entry plugin (#7131) +- Issue 7091 - Duplicate local password policy entries listed (#7092) +- Issue 7124 - BDB cursor race condition with transaction isolation (#7125) +- Issue 6951 - Dynamic Certificate refresh phase 1 - Search support (#7117) +- Issue 7132 - Keep alive entry updated too soon after an offline import (#7133) +- Issue 7135 - Not enough space for tests on GH runner (#7136) +- Issue 7121 - LeakSanitizer: various leaks during replication (#7122) +- Issue 7115 - LeakSanitizer: leak in `slapd_bind_local_user()` (#7116) +- Issue 7109 - AddressSanitizer: SEGV ldap/servers/slapd/csnset.c:302 in csnset_dup (#7114) +- Issue 7119 - Harden DNA plugin locking for shared server list operations (#7120) +- Issue 7084 - UI - schema - sorting attributes breaks expanded row +- Issue 6753 - Port ticket47910 test to logconv_test using DSLdapObject (#7098) +- Issue 6753 - Port ticket47920 test to ldap_controls_test using DSLdapObject (#7103) +- Issue 7007 - Improve paged result search locking +- Issue 7041 - Add WebUI test for group member management (#7111) +- Issue 3555 - UI - Fix audit issue with npm - glob (#7107) +- Issue 7089 - Fix dsconf certificate list (#7090) +- Issue 7076, 6992, 6784, 6214 - Fix CI test failures (#7077) +- Bump js-yaml from 4.1.0 to 4.1.1 in /src/cockpit/389-console (#7097) +- Issue 7069 - Fix error reporting in HAProxy trusted IP parsing (#7094) +- Issue 7049 - RetroCL plugin generates invalid LDIF +- Issue 7055 - Online initialization of consumers fails with error -23 (#7075) +- Issue 6753 - Remove ticket 47900 test (#7087) +- Issue 6753 - Port ticket 49008 test (#7080) +- Issue 7042 - Enable global_backend_lock when memberofallbackend is enabled (#7043) +- Issue 7078 - audit json logging does not encode binary values +- Issue 7069 - Add Subnet/CIDR Support for HAProxy Trusted IPs (#7070) +- Issue 7056 - DSBLE0007 doesn't generate remediation steps for missing indexes +- Issue 6660 - CLI, UI - Improve replication log analyzer usability (#7062) +- Issue 7065 - A search filter containing a non normalized DN assertion does not return matching entries (#7068) +- Issue 7071 - search filter (&(cn:dn:=groups)) no longer returns results +- Issue 7073 - Add NDN cache size configuration and enforcement tests (#7074) +- Issue 6753 - Removing ticket 47871 test and porting to DSLdapObject (#7045) +- Issue 7041 - CLI/UI - memberOf - no way to add/remove specific group filters +- Issue 6753 - Port ticket 48228 test (#7067) +- Issue 7029 - Add test case to measure ndn cache performance impact (#7030) +- Issue 7061 - CLI/UI - Improve error messages for dsconf localpwp list +- Issue 7059 - UI - unable to upload pem file +- Issue 7032 - The new ipahealthcheck test ipahealthcheck.ds.backends.BackendsCheck raises CRITICAL issue (#7036) +- Issue 7047 - MemberOf plugin logs null attribute name on fixup task completion (#7048) +- Issue 7044 - RFE - index sudoHost by default (#7046) +- Issue 6846 - Attribute uniqueness is not enforced with modrdn (#7026) +- Issue 6784 - Support of Entry cache pinned entries (#6785) +- Issue 6979 - Improve the way to detect asynchronous operations in the access logs (#6980) +- Issue 6753 - Port ticket 47931 test (#7038) +- Issue 7035 - RFE - memberOf - adding scoping for specific groups +- CLI/UI - Add option to delete all replication conflict entries +- Issue 7033 - lib389 - basic plugin status not in JSON +- Issue 7023 - UI - if first instance that is loaded is stopped it breaks parts of the UI +- Issue 6753 - Removing ticket 47714 test and porting to DSLdapObject (#6946) +- Issue 7027 - 389-ds-base OpenScanHub Leaks Detected (#7028) +- Issue 6753 - Removing ticket 47676 test and porting to DSLdapObject (#6938) +- Issue 6966 - On large DB, unlimited IDL scan limit reduce the SRCH performance (#6967) +- Issue 6660 - UI - Improve replication log analysis charts and usability (#6968) +- Issue 6753 - Removing ticket 47653MMR test and porting to DSLdapObject (#6926) +- Issue 7021 - Units for changing MDB max size are not consistent across different tools (#7022) +- Issue 6753 - Removing ticket 49463 test and porting to DSLdapObject (#6899) +- Issue 6954 - do not delete referrals on chain_on_update backend +- Issue 6982 - UI - MemberOf shared config does not validate DN properly (#6983) +- Issue 6740 - Fix FIPS mode test failures in syncrepl, mapping tree, and resource limits (#6993) +- Issue 7018 - BUG - prevent stack depth being hit (#7019) +- Issue 7014 - memberOf - ignored deferred updates with LMDB +- Issue 7002 - restore is failing. (#7003) +- Issue 6758 - Fix WebUI monitoring test failure due to FormSelect component deprecation (#7004) +- Issue 6753 - Removing ticket 47869 test and porting to DSLdapObject (#7001) +- Issue 6753 - Port ticket 49073 test (#7005) +- Issue 7016 - fix NULL deref in send_referrals_from_entry() (#7017) +- Issue 6753 - Port ticket 47815 test (#7000) +- Issue 7010 - Fix certdir underflow in slapd_nss_init() (#7011) +- Issue 7012 - improve dscrl dbverify result when backend does not exists (#7013) +- Issue 6753 - Removing ticket 477828 test and porting to DSLdapObject (#6989) +- Issue 6753 - Removing ticket 47721 test and porting to DSLdapObject (#6973) +- Issue 6992 - Improve handling of mismatched ldif import (#6999) +- Issue 6997 - Logic error in get_bdb_impl_status prevents bdb2mdb execution (#6998) +- Issue 6810 - Deprecate PAM PTA plugin configuration attributes in base entry - fix memleak (#6988) +- Issue 6971 - bundle-rust-npm.py: TypeError: argument of type 'NoneType' is not iterable (#6972) +- Fix overflow in certmap filter/DN buffers (#6995) +- Issue 6753 - Port ticket 49386 test (#6987) +- Issue 6753 - Removing ticket 47787 test and porting to DSLdapObject (#6976) +- Issue 6753 - Port ticket 49072 test (#6984) +- Issue 6990 - UI - Replace deprecated Select components with new TypeaheadSelect (#6996) +- Issue 6990 - UI - Fix typeahead Select fields losing values on Enter keypress (#6991) +- Issue 6887 - Enhance logconv.py to add support for JSON access logs (#6889) +- Issue 6985 - Some logconv CI tests fail with BDB (#6986) +- Issue 6891 - JSON logging - add wrapper function that checks for NULL +- Issue 4835 - dsconf display an incomplete help with changelog setting (#6769) +- Issue 6753 - Port ticket 47963 & 49184 tests (#6970) +- Issue 6753 - Port ticket 47829 & 47833 tests +- Issue 6977 - UI - Show error message when trying to use unavailable ports (#6978) +- Issue 6956 - More UI fixes +- Issue 6626 - Fix version +- Issue 6900 - Rename test files for proper pytest discovery (#6909) +- Issue 6947 - Revise time skew check in healthcheck tool and add option to exclude checks +- Issue 6805 - RFE - Multiple backend entry cache tuning +- Issue 6753 - Port and fix ticket 47823 tests +- Issue 6843 - Add CI tests for logconv.py (#6856) +- Issue 6933 - When deferred memberof update is enabled after the server crashed it should not launch memberof fixup task by default (#6935) +- UI - update Radio handlers and LDAP entries last modified time +- Issue 6810 - Deprecate PAM PTA plugin configuration attributes in base entry (#6832) +- Issue 6660 - UI - Fix minor typo (#6955) +- Issue 6753 - Port ticket 47808 test +- Issue 6910 - Fix latest coverity issues +- Issue 6753 - Removing ticket 50232 test and porting to DSLdapObject (#6861) +- Issue 6919 - numSubordinates/tombstoneNumSubordinates are inconsisten… (#6920) +- Issue 6430 - Fix build with bundled libdb +- Issue 6342 - buffer owerflow in the function parseVariant (#6927) +- Issue 6940 - dsconf monitor server fails with ldapi:// due to absent server ID (#6941) +- Issue 6936 - Make user/subtree policy creation idempotent (#6937) +- Migrate from PR_Poll to epoll and timerfd. (#6924) +- Issue 6928 - The parentId attribute is indexed with improper matching rule +- Issue 6753 - Removing ticket 49540 test and porting to DSLdapObject (#6877) +- Issue 6904 - Fix config_test.py::test_lmdb_config +- Issue 5120 - Fix compilation error +- Issue 6929 - Compilation failure with rust-1.89 on Fedora ELN +- Issue 6922 - AddressSanitizer: leaks found by acl test suite +- Issue 6519 - Add basic dsidm account tests +- Issue 6753 - Port ticket test 47573 +- Issue 6875 - Fix dsidm tests +- Issues 6913, 6886, 6250 - Adjust xfail marks (#6914) +- Issue 6768 - ns-slapd crashes when a referral is added (#6780) +- Issue 6468 - CLI - Fix default error log level +- Issue 6181 - RFE - Allow system to manage uid/gid at startup +- Issue 6901 - Update changelog trimming logging - fix tests +- Issue 6778 - Memory leak in roles_cache_create_object_from_entry part 2 +- Issue 6897 - Fix disk monitoring test failures and improve test maintainability (#6898) +- Issue 6884 - Mask password hashes in audit logs (#6885) +- Issue 6594 - Add test for numSubordinates replication consistency with tombstones (#6862) +- Issue 6250 - Add test for entryUSN overflow on failed add operations (#6821) +- Issue 6895 - Crash if repl keep alive entry can not be created +- Issue 6663 - Fix NULL subsystem crash in JSON error logging (#6883) +- Issue 6430 - implement read-only bdb (#6431) +- Issue 6901 - Update changelog trimming logging +- Issue 6880 - Fix ds_logs test suite failure +- Issue 6352 - Fix DeprecationWarning +- Issue 6800 - Rerun the check in verbose mode on failure +- Issue 6893 - Log user that is updated during password modify extended operation +- Issue 6772 - dsconf - Replicas with the "consumer" role allow for viewing and modification of their changelog. (#6773) +- Issue 6829 - Update parametrized docstring for tests +- Issue 6888 - Missing access JSON logging for TLS/Client auth +- Issue 6878 - Prevent repeated disconnect logs during shutdown (#6879) +- Issue 6872 - compressed log rotation creates files with world readable permission +- Issue 6859 - str2filter is not fully applying matching rules +- Issue 5733 - Remove outdated Dockerfiles +- Issue 6800 - Check for minimal supported Python version +- Issue 6868 - UI - schema attribute table expansion break after moving to a new page +- Issue 6865 - AddressSanitizer: leak in agmt_update_init_status +- Issue 6848 - AddressSanitizer: leak in do_search +- Issue 6850 - AddressSanitizer: memory leak in mdb_init +- Issue 6854 - Refactor for improved data management (#6855) +- Issue 6756 - CLI, UI - Properly handle disabled NDN cache (#6757) +- Issue 6857 - uiduniq: allow specifying match rules in the filter +- Issue 6852 - Move ds* CLI tools back to /sbin +- Issue 6753 - Port ticket tests 48294 & 48295 +- Issue 6753 - Add 'add_exclude_subtree' and 'remove_exclude_subtree' methods to Attribute uniqueness plugin +- Issue 6841 - Cancel Actions when PR is updated +- Issue 6838 - lib389/replica.py is using nonexistent datetime.UTC in Python 3.9 +- Issue 6822 - Backend creation cleanup and Database UI tab error handling (#6823) +- Issue 6782 - Improve paged result locking +- Issue 6829 - Update parametrized docstring for tests + %autochangelog diff --git a/sources b/sources index 6ab8ee9..a1d9669 100644 --- a/sources +++ b/sources @@ -1,3 +1,2 @@ +SHA512 (389-ds-base-3.2.0.tar.bz2) = 9b26db52c401237dfb1a4d05629d9f7336f656f9f9f251f76d19b76e8c7a174a32a306277b695e7f1b358557b63eaa2589699c4cb7619c661799000834d293f9 SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 -SHA512 (389-ds-base-3.1.3.tar.bz2) = bd15c29dba5209ed828a2534e51fd000fdd5d32862fd07ea73339e73489b3c79f1991c91592c75dbb67384c696a03c82378f156bbea594e2e17421c95ca4c6be -SHA512 (libdb-5.3.28-59.tar.bz2) = 731a434fa2e6487ebb05c458b0437456eb9f7991284beb08cb3e21931e23bdeddddbc95bfabe3a2f9f029fe69cd33a2d4f0f5ce6a9811e9c3b940cb6fde4bf79 From 0e19d9ccb9b00aa819445d0ad7167fdfefee5587 Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Wed, 24 Dec 2025 00:59:03 -0500 Subject: [PATCH 121/125] Restore libdb in sources --- sources | 1 + 1 file changed, 1 insertion(+) diff --git a/sources b/sources index a1d9669..ec0ac34 100644 --- a/sources +++ b/sources @@ -1,2 +1,3 @@ SHA512 (389-ds-base-3.2.0.tar.bz2) = 9b26db52c401237dfb1a4d05629d9f7336f656f9f9f251f76d19b76e8c7a174a32a306277b695e7f1b358557b63eaa2589699c4cb7619c661799000834d293f9 SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 +SHA512 (libdb-5.3.28-59.tar.bz2) = 731a434fa2e6487ebb05c458b0437456eb9f7991284beb08cb3e21931e23bdeddddbc95bfabe3a2f9f029fe69cd33a2d4f0f5ce6a9811e9c3b940cb6fde4bf79 From 6a9fe72ef898f6d6500c6bfb816134f125849e99 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Fri, 9 Jan 2026 18:41:53 +0100 Subject: [PATCH 122/125] Fix broken FreeIPA upgrade and replication issues - Resolves: rhbz#2424132 Upgrade from freeipa-4.12.5-3 and 390-ds-base-3.1.3-10 to latest rawhide fails - Fix jemalloc compilation issue with GCC 15 - Issue 7096 - During replication online total init the function idl_id_is_in_idlist is not scaling with large database - Issue 7118 - Revise paged result search locking - Issue 7108 - Fix shutdown crash in entry cache destruction Use correct tarball from upstream. --- ...g-replication-online-total-init-the-.patch | 318 ++++++++ ...e-Revise-paged-result-search-locking.patch | 765 ++++++++++++++++++ ...hutdown-crash-in-entry-cache-destruc.patch | 183 +++++ ...-ordering-mismatch-after-upgrade-717.patch | 215 +++++ 389-ds-base.spec | 179 +--- jemalloc-5.3.0_throw_bad_alloc.patch | 41 + sources | 2 +- 7 files changed, 1531 insertions(+), 172 deletions(-) create mode 100644 0001-Issue-7096-During-replication-online-total-init-the-.patch create mode 100644 0002-Issue-Revise-paged-result-search-locking.patch create mode 100644 0003-Issue-7108-Fix-shutdown-crash-in-entry-cache-destruc.patch create mode 100644 0004-Issue-7172-Index-ordering-mismatch-after-upgrade-717.patch create mode 100644 jemalloc-5.3.0_throw_bad_alloc.patch diff --git a/0001-Issue-7096-During-replication-online-total-init-the-.patch b/0001-Issue-7096-During-replication-online-total-init-the-.patch new file mode 100644 index 0000000..a5792b6 --- /dev/null +++ b/0001-Issue-7096-During-replication-online-total-init-the-.patch @@ -0,0 +1,318 @@ +From 1c9c535888b9a850095794787d67900b04924a76 Mon Sep 17 00:00:00 2001 +From: tbordaz +Date: Wed, 7 Jan 2026 11:21:12 +0100 +Subject: [PATCH] Issue 7096 - During replication online total init the + function idl_id_is_in_idlist is not scaling with large database (#7145) + +Bug description: + During a online total initialization, the supplier sorts + the candidate list of entries so that the parents are sent before + children entries. + With large DB the ID array used for the sorting is not + scaling. It takes so long to build the candidate list that + the connection gets closed + +Fix description: + Instead of using an ID array, uses a list of ID ranges + +fixes: #7096 + +Reviewed by: Mark Reynolds, Pierre Rogier (Thanks !!) +--- + ldap/servers/slapd/back-ldbm/back-ldbm.h | 12 ++ + ldap/servers/slapd/back-ldbm/idl_common.c | 163 ++++++++++++++++++ + ldap/servers/slapd/back-ldbm/idl_new.c | 30 ++-- + .../servers/slapd/back-ldbm/proto-back-ldbm.h | 3 + + 4 files changed, 189 insertions(+), 19 deletions(-) + +diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h +index 1bc36720d..b187c26bc 100644 +--- a/ldap/servers/slapd/back-ldbm/back-ldbm.h ++++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h +@@ -282,6 +282,18 @@ typedef struct _idlist_set + #define INDIRECT_BLOCK(idl) ((idl)->b_nids == INDBLOCK) + #define IDL_NIDS(idl) (idl ? (idl)->b_nids : (NIDS)0) + ++/* ++ * used by the supplier during online total init ++ * it stores the ranges of ID that are already present ++ * in the candidate list ('parentid>=1') ++ */ ++typedef struct IdRange { ++ ID first; ++ ID last; ++ struct IdRange *next; ++} IdRange_t; ++ ++ + typedef size_t idl_iterator; + + /* small hashtable implementation used in the entry cache -- the table +diff --git a/ldap/servers/slapd/back-ldbm/idl_common.c b/ldap/servers/slapd/back-ldbm/idl_common.c +index fcb0ece4b..fdc9b4e67 100644 +--- a/ldap/servers/slapd/back-ldbm/idl_common.c ++++ b/ldap/servers/slapd/back-ldbm/idl_common.c +@@ -172,6 +172,169 @@ idl_min(IDList *a, IDList *b) + return (a->b_nids > b->b_nids ? b : a); + } + ++/* ++ * This is a faster version of idl_id_is_in_idlist. ++ * idl_id_is_in_idlist uses an array of ID so lookup is expensive ++ * idl_id_is_in_idlist_ranges uses a list of ranges of ID lookup is faster ++ * returns ++ * 1: 'id' is present in idrange_list ++ * 0: 'id' is not present in idrange_list ++ */ ++int ++idl_id_is_in_idlist_ranges(IDList *idl, IdRange_t *idrange_list, ID id) ++{ ++ IdRange_t *range = idrange_list; ++ int found = 0; ++ ++ if (NULL == idl || NOID == id) { ++ return 0; /* not in the list */ ++ } ++ if (ALLIDS(idl)) { ++ return 1; /* in the list */ ++ } ++ ++ for(;range; range = range->next) { ++ if (id > range->last) { ++ /* check if it belongs to the next range */ ++ continue; ++ } ++ if (id >= range->first) { ++ /* It belongs to that range [first..last ] */ ++ found = 1; ++ break; ++ } else { ++ /* this range is after id */ ++ break; ++ } ++ } ++ return found; ++} ++ ++/* This function is used during the online total initialisation ++ * (see next function) ++ * It frees all ranges of ID in the list ++ */ ++void idrange_free(IdRange_t **head) ++{ ++ IdRange_t *curr, *sav; ++ ++ if ((head == NULL) || (*head == NULL)) { ++ return; ++ } ++ curr = *head; ++ sav = NULL; ++ for (; curr;) { ++ sav = curr; ++ curr = curr->next; ++ slapi_ch_free((void *) &sav); ++ } ++ if (sav) { ++ slapi_ch_free((void *) &sav); ++ } ++ *head = NULL; ++} ++ ++/* This function is used during the online total initialisation ++ * Because a MODRDN can move entries under a parent that ++ * has a higher ID we need to sort the IDList so that parents ++ * are sent, to the consumer, before the children are sent. ++ * The sorting with a simple IDlist does not scale instead ++ * a list of IDs ranges is much faster. ++ * In that list we only ADD/lookup ID. ++ */ ++IdRange_t *idrange_add_id(IdRange_t **head, ID id) ++{ ++ if (head == NULL) { ++ slapi_log_err(SLAPI_LOG_ERR, "idrange_add_id", ++ "Can not add ID %d in non defined list\n", id); ++ return NULL; ++ } ++ ++ if (*head == NULL) { ++ /* This is the first range */ ++ IdRange_t *new_range = (IdRange_t *)slapi_ch_malloc(sizeof(IdRange_t)); ++ new_range->first = id; ++ new_range->last = id; ++ new_range->next = NULL; ++ *head = new_range; ++ return *head; ++ } ++ ++ IdRange_t *curr = *head, *prev = NULL; ++ ++ /* First, find if id already falls within any existing range, or it is adjacent to any */ ++ while (curr) { ++ if (id >= curr->first && id <= curr->last) { ++ /* inside a range, nothing to do */ ++ return curr; ++ } ++ ++ if (id == curr->last + 1) { ++ /* Extend this range upwards */ ++ curr->last = id; ++ ++ /* Check for possible merge with next range */ ++ IdRange_t *next = curr->next; ++ if (next && curr->last + 1 >= next->first) { ++ slapi_log_err(SLAPI_LOG_REPL, "idrange_add_id", ++ "(id=%d) merge current with next range [%d..%d]\n", id, curr->first, curr->last); ++ curr->last = (next->last > curr->last) ? next->last : curr->last; ++ curr->next = next->next; ++ slapi_ch_free((void*) &next); ++ } else { ++ slapi_log_err(SLAPI_LOG_REPL, "idrange_add_id", ++ "(id=%d) extend forward current range [%d..%d]\n", id, curr->first, curr->last); ++ } ++ return curr; ++ } ++ ++ if (id + 1 == curr->first) { ++ /* Extend this range downwards */ ++ curr->first = id; ++ ++ /* Check for possible merge with previous range */ ++ if (prev && prev->last + 1 >= curr->first) { ++ prev->last = curr->last; ++ prev->next = curr->next; ++ slapi_ch_free((void *) &curr); ++ slapi_log_err(SLAPI_LOG_REPL, "idrange_add_id", ++ "(id=%d) merge current with previous range [%d..%d]\n", id, prev->first, prev->last); ++ return prev; ++ } else { ++ slapi_log_err(SLAPI_LOG_REPL, "idrange_add_id", ++ "(id=%d) extend backward current range [%d..%d]\n", id, curr->first, curr->last); ++ return curr; ++ } ++ } ++ ++ /* If id is before the current range, break so we can insert before */ ++ if (id < curr->first) { ++ break; ++ } ++ ++ prev = curr; ++ curr = curr->next; ++ } ++ /* Need to insert a new standalone IdRange */ ++ IdRange_t *new_range = (IdRange_t *)slapi_ch_malloc(sizeof(IdRange_t)); ++ new_range->first = id; ++ new_range->last = id; ++ new_range->next = curr; ++ ++ if (prev) { ++ slapi_log_err(SLAPI_LOG_REPL, "idrange_add_id", ++ "(id=%d) add new range [%d..%d]\n", id, new_range->first, new_range->last); ++ prev->next = new_range; ++ } else { ++ /* Insert at head */ ++ slapi_log_err(SLAPI_LOG_REPL, "idrange_add_id", ++ "(id=%d) head range [%d..%d]\n", id, new_range->first, new_range->last); ++ *head = new_range; ++ } ++ return *head; ++} ++ ++ + int + idl_id_is_in_idlist(IDList *idl, ID id) + { +diff --git a/ldap/servers/slapd/back-ldbm/idl_new.c b/ldap/servers/slapd/back-ldbm/idl_new.c +index 5fbcaff2e..2d978353f 100644 +--- a/ldap/servers/slapd/back-ldbm/idl_new.c ++++ b/ldap/servers/slapd/back-ldbm/idl_new.c +@@ -417,7 +417,6 @@ idl_new_range_fetch( + { + int ret = 0; + int ret2 = 0; +- int idl_rc = 0; + dbi_cursor_t cursor = {0}; + IDList *idl = NULL; + dbi_val_t cur_key = {0}; +@@ -436,6 +435,7 @@ idl_new_range_fetch( + size_t leftoverlen = 32; + size_t leftovercnt = 0; + char *index_id = get_index_name(be, db, ai); ++ IdRange_t *idrange_list = NULL; + + + if (NULL == flag_err) { +@@ -578,10 +578,12 @@ idl_new_range_fetch( + * found entry is the one from the suffix + */ + suffix = key; +- idl_rc = idl_append_extend(&idl, id); +- } else if ((key == suffix) || idl_id_is_in_idlist(idl, key)) { ++ idl_append_extend(&idl, id); ++ idrange_add_id(&idrange_list, id); ++ } else if ((key == suffix) || idl_id_is_in_idlist_ranges(idl, idrange_list, key)) { + /* the parent is the suffix or already in idl. */ +- idl_rc = idl_append_extend(&idl, id); ++ idl_append_extend(&idl, id); ++ idrange_add_id(&idrange_list, id); + } else { + /* Otherwise, keep the {key,id} in leftover array */ + if (!leftover) { +@@ -596,13 +598,7 @@ idl_new_range_fetch( + leftovercnt++; + } + } else { +- idl_rc = idl_append_extend(&idl, id); +- } +- if (idl_rc) { +- slapi_log_err(SLAPI_LOG_ERR, "idl_new_range_fetch", +- "Unable to extend id list (err=%d)\n", idl_rc); +- idl_free(&idl); +- goto error; ++ idl_append_extend(&idl, id); + } + + count++; +@@ -695,21 +691,17 @@ error: + + while(remaining > 0) { + for (size_t i = 0; i < leftovercnt; i++) { +- if (leftover[i].key > 0 && idl_id_is_in_idlist(idl, leftover[i].key) != 0) { ++ if (leftover[i].key > 0 && idl_id_is_in_idlist_ranges(idl, idrange_list, leftover[i].key) != 0) { + /* if the leftover key has its parent in the idl */ +- idl_rc = idl_append_extend(&idl, leftover[i].id); +- if (idl_rc) { +- slapi_log_err(SLAPI_LOG_ERR, "idl_new_range_fetch", +- "Unable to extend id list (err=%d)\n", idl_rc); +- idl_free(&idl); +- return NULL; +- } ++ idl_append_extend(&idl, leftover[i].id); ++ idrange_add_id(&idrange_list, leftover[i].id); + leftover[i].key = 0; + remaining--; + } + } + } + slapi_ch_free((void **)&leftover); ++ idrange_free(&idrange_list); + } + slapi_log_err(SLAPI_LOG_FILTER, "idl_new_range_fetch", + "Found %d candidates; error code is: %d\n", +diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h +index 91d61098a..30a7aa11f 100644 +--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h ++++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h +@@ -217,6 +217,9 @@ ID idl_firstid(IDList *idl); + ID idl_nextid(IDList *idl, ID id); + int idl_init_private(backend *be, struct attrinfo *a); + int idl_release_private(struct attrinfo *a); ++IdRange_t *idrange_add_id(IdRange_t **head, ID id); ++void idrange_free(IdRange_t **head); ++int idl_id_is_in_idlist_ranges(IDList *idl, IdRange_t *idrange_list, ID id); + int idl_id_is_in_idlist(IDList *idl, ID id); + + idl_iterator idl_iterator_init(const IDList *idl); +-- +2.52.0 + diff --git a/0002-Issue-Revise-paged-result-search-locking.patch b/0002-Issue-Revise-paged-result-search-locking.patch new file mode 100644 index 0000000..e27ced3 --- /dev/null +++ b/0002-Issue-Revise-paged-result-search-locking.patch @@ -0,0 +1,765 @@ +From 446bc42e7b64a8496c2c3fe486f86bba318bed5e Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Wed, 7 Jan 2026 16:55:27 -0500 +Subject: [PATCH] Issue - Revise paged result search locking + +Description: + +Move to a single lock approach verses having two locks. This will impact +concurrency when multiple async paged result searches are done on the same +connection, but it simplifies the code and avoids race conditions and +deadlocks. + +Relates: https://github.com/389ds/389-ds-base/issues/7118 + +Reviewed by: progier & tbordaz (Thanks!!) +--- + ldap/servers/slapd/abandon.c | 2 +- + ldap/servers/slapd/opshared.c | 60 ++++---- + ldap/servers/slapd/pagedresults.c | 228 +++++++++++++++++++----------- + ldap/servers/slapd/proto-slap.h | 26 ++-- + ldap/servers/slapd/slap.h | 5 +- + 5 files changed, 187 insertions(+), 134 deletions(-) + +diff --git a/ldap/servers/slapd/abandon.c b/ldap/servers/slapd/abandon.c +index 6024fcd31..1f47c531c 100644 +--- a/ldap/servers/slapd/abandon.c ++++ b/ldap/servers/slapd/abandon.c +@@ -179,7 +179,7 @@ do_abandon(Slapi_PBlock *pb) + logpb.tv_sec = -1; + logpb.tv_nsec = -1; + +- if (0 == pagedresults_free_one_msgid(pb_conn, id, pageresult_lock_get_addr(pb_conn))) { ++ if (0 == pagedresults_free_one_msgid(pb_conn, id, PR_NOT_LOCKED)) { + if (log_format != LOG_FORMAT_DEFAULT) { + /* JSON logging */ + logpb.target_op = "Simple Paged Results"; +diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c +index a5cddfd23..bf800f7dc 100644 +--- a/ldap/servers/slapd/opshared.c ++++ b/ldap/servers/slapd/opshared.c +@@ -572,8 +572,8 @@ op_shared_search(Slapi_PBlock *pb, int send_result) + be = be_list[index]; + } + } +- pr_search_result = pagedresults_get_search_result(pb_conn, operation, 0 /*not locked*/, pr_idx); +- estimate = pagedresults_get_search_result_set_size_estimate(pb_conn, operation, pr_idx); ++ pr_search_result = pagedresults_get_search_result(pb_conn, operation, PR_NOT_LOCKED, pr_idx); ++ estimate = pagedresults_get_search_result_set_size_estimate(pb_conn, operation, PR_NOT_LOCKED, pr_idx); + /* Set operation note flags as required. */ + if (pagedresults_get_unindexed(pb_conn, operation, pr_idx)) { + slapi_pblock_set_flag_operation_notes(pb, SLAPI_OP_NOTE_UNINDEXED); +@@ -619,14 +619,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result) + int32_t tlimit; + slapi_pblock_get(pb, SLAPI_SEARCH_TIMELIMIT, &tlimit); + pagedresults_set_timelimit(pb_conn, operation, (time_t)tlimit, pr_idx); +- /* When using this mutex in conjunction with the main paged +- * result lock, you must do so in this order: +- * +- * --> pagedresults_lock() +- * --> pagedresults_mutex +- * <-- pagedresults_mutex +- * <-- pagedresults_unlock() +- */ ++ /* IMPORTANT: Never acquire pagedresults_mutex when holding c_mutex. */ + pagedresults_mutex = pageresult_lock_get_addr(pb_conn); + } + +@@ -743,17 +736,15 @@ op_shared_search(Slapi_PBlock *pb, int send_result) + if (op_is_pagedresults(operation) && pr_search_result) { + void *sr = NULL; + /* PAGED RESULTS and already have the search results from the prev op */ +- pagedresults_lock(pb_conn, pr_idx); + /* + * In async paged result case, the search result might be released + * by other theads. We need to double check it in the locked region. + */ + pthread_mutex_lock(pagedresults_mutex); +- pr_search_result = pagedresults_get_search_result(pb_conn, operation, 1 /*locked*/, pr_idx); ++ pr_search_result = pagedresults_get_search_result(pb_conn, operation, PR_LOCKED, pr_idx); + if (pr_search_result) { +- if (pagedresults_is_abandoned_or_notavailable(pb_conn, 1 /*locked*/, pr_idx)) { ++ if (pagedresults_is_abandoned_or_notavailable(pb_conn, PR_LOCKED, pr_idx)) { + pthread_mutex_unlock(pagedresults_mutex); +- pagedresults_unlock(pb_conn, pr_idx); + /* Previous operation was abandoned and the simplepaged object is not in use. */ + send_ldap_result(pb, 0, NULL, "Simple Paged Results Search abandoned", 0, NULL); + rc = LDAP_SUCCESS; +@@ -764,14 +755,13 @@ op_shared_search(Slapi_PBlock *pb, int send_result) + + /* search result could be reset in the backend/dse */ + slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr); +- pagedresults_set_search_result(pb_conn, operation, sr, 1 /*locked*/, pr_idx); ++ pagedresults_set_search_result(pb_conn, operation, sr, PR_LOCKED, pr_idx); + } + } else { + pr_stat = PAGEDRESULTS_SEARCH_END; + rc = LDAP_SUCCESS; + } + pthread_mutex_unlock(pagedresults_mutex); +- pagedresults_unlock(pb_conn, pr_idx); + + if ((PAGEDRESULTS_SEARCH_END == pr_stat) || (0 == pnentries)) { + /* no more entries to send in the backend */ +@@ -789,22 +779,22 @@ op_shared_search(Slapi_PBlock *pb, int send_result) + } + pagedresults_set_response_control(pb, 0, estimate, + curr_search_count, pr_idx); +- if (pagedresults_get_with_sort(pb_conn, operation, pr_idx)) { ++ if (pagedresults_get_with_sort(pb_conn, operation, PR_NOT_LOCKED, pr_idx)) { + sort_make_sort_response_control(pb, CONN_GET_SORT_RESULT_CODE, NULL); + } + pagedresults_set_search_result_set_size_estimate(pb_conn, + operation, +- estimate, pr_idx); ++ estimate, PR_NOT_LOCKED, pr_idx); + if (PAGEDRESULTS_SEARCH_END == pr_stat) { +- pagedresults_lock(pb_conn, pr_idx); ++ pthread_mutex_lock(pagedresults_mutex); + slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET, NULL); +- if (!pagedresults_is_abandoned_or_notavailable(pb_conn, 0 /*not locked*/, pr_idx)) { +- pagedresults_free_one(pb_conn, operation, pr_idx); ++ if (!pagedresults_is_abandoned_or_notavailable(pb_conn, PR_LOCKED, pr_idx)) { ++ pagedresults_free_one(pb_conn, operation, PR_LOCKED, pr_idx); + } +- pagedresults_unlock(pb_conn, pr_idx); ++ pthread_mutex_unlock(pagedresults_mutex); + if (next_be) { + /* no more entries, but at least another backend */ +- if (pagedresults_set_current_be(pb_conn, next_be, pr_idx, 0) < 0) { ++ if (pagedresults_set_current_be(pb_conn, next_be, pr_idx, PR_NOT_LOCKED) < 0) { + goto free_and_return; + } + } +@@ -915,7 +905,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result) + } + } + pagedresults_set_search_result(pb_conn, operation, NULL, 1, pr_idx); +- rc = pagedresults_set_current_be(pb_conn, NULL, pr_idx, 1); ++ rc = pagedresults_set_current_be(pb_conn, NULL, pr_idx, PR_LOCKED); + pthread_mutex_unlock(pagedresults_mutex); + #pragma GCC diagnostic pop + } +@@ -954,7 +944,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result) + pthread_mutex_lock(pagedresults_mutex); + pagedresults_set_search_result(pb_conn, operation, NULL, 1, pr_idx); + be->be_search_results_release(&sr); +- rc = pagedresults_set_current_be(pb_conn, next_be, pr_idx, 1); ++ rc = pagedresults_set_current_be(pb_conn, next_be, pr_idx, PR_LOCKED); + pthread_mutex_unlock(pagedresults_mutex); + pr_stat = PAGEDRESULTS_SEARCH_END; /* make sure stat is SEARCH_END */ + if (NULL == next_be) { +@@ -967,23 +957,23 @@ op_shared_search(Slapi_PBlock *pb, int send_result) + } else { + curr_search_count = pnentries; + slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate); +- pagedresults_lock(pb_conn, pr_idx); +- if ((pagedresults_set_current_be(pb_conn, be, pr_idx, 0) < 0) || +- (pagedresults_set_search_result(pb_conn, operation, sr, 0, pr_idx) < 0) || +- (pagedresults_set_search_result_count(pb_conn, operation, curr_search_count, pr_idx) < 0) || +- (pagedresults_set_search_result_set_size_estimate(pb_conn, operation, estimate, pr_idx) < 0) || +- (pagedresults_set_with_sort(pb_conn, operation, with_sort, pr_idx) < 0)) { +- pagedresults_unlock(pb_conn, pr_idx); ++ pthread_mutex_lock(pagedresults_mutex); ++ if ((pagedresults_set_current_be(pb_conn, be, pr_idx, PR_LOCKED) < 0) || ++ (pagedresults_set_search_result(pb_conn, operation, sr, PR_LOCKED, pr_idx) < 0) || ++ (pagedresults_set_search_result_count(pb_conn, operation, curr_search_count, PR_LOCKED, pr_idx) < 0) || ++ (pagedresults_set_search_result_set_size_estimate(pb_conn, operation, estimate, PR_LOCKED, pr_idx) < 0) || ++ (pagedresults_set_with_sort(pb_conn, operation, with_sort, PR_LOCKED, pr_idx) < 0)) { ++ pthread_mutex_unlock(pagedresults_mutex); + cache_return_target_entry(pb, be, operation); + goto free_and_return; + } +- pagedresults_unlock(pb_conn, pr_idx); ++ pthread_mutex_unlock(pagedresults_mutex); + } + slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET, NULL); + next_be = NULL; /* to break the loop */ + if (operation->o_status & SLAPI_OP_STATUS_ABANDONED) { + /* It turned out this search was abandoned. */ +- pagedresults_free_one_msgid(pb_conn, operation->o_msgid, pagedresults_mutex); ++ pagedresults_free_one_msgid(pb_conn, operation->o_msgid, PR_NOT_LOCKED); + /* paged-results-request was abandoned; making an empty cookie. */ + pagedresults_set_response_control(pb, 0, estimate, -1, pr_idx); + send_ldap_result(pb, 0, NULL, "Simple Paged Results Search abandoned", 0, NULL); +@@ -993,7 +983,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result) + } + pagedresults_set_response_control(pb, 0, estimate, curr_search_count, pr_idx); + if (curr_search_count == -1) { +- pagedresults_free_one(pb_conn, operation, pr_idx); ++ pagedresults_free_one(pb_conn, operation, PR_NOT_LOCKED, pr_idx); + } + } + +diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c +index 941ab97e3..0d6c4a1aa 100644 +--- a/ldap/servers/slapd/pagedresults.c ++++ b/ldap/servers/slapd/pagedresults.c +@@ -34,9 +34,9 @@ pageresult_lock_cleanup() + slapi_ch_free((void**)&lock_hash); + } + +-/* Beware to the lock order with c_mutex: +- * c_mutex is sometime locked while holding pageresult_lock +- * ==> Do not lock pageresult_lock when holing c_mutex ++/* Lock ordering constraint with c_mutex: ++ * c_mutex is sometimes locked while holding pageresult_lock. ++ * Therefore: DO NOT acquire pageresult_lock when holding c_mutex. + */ + pthread_mutex_t * + pageresult_lock_get_addr(Connection *conn) +@@ -44,7 +44,11 @@ pageresult_lock_get_addr(Connection *conn) + return &lock_hash[(((size_t)conn)/sizeof (Connection))%LOCK_HASH_SIZE]; + } + +-/* helper function to clean up one prp slot */ ++/* helper function to clean up one prp slot ++ * ++ * NOTE: This function must be called while holding the pageresult_lock ++ * (via pageresult_lock_get_addr(conn)) to ensure thread-safe cleanup. ++ */ + static void + _pr_cleanup_one_slot(PagedResults *prp) + { +@@ -56,7 +60,7 @@ _pr_cleanup_one_slot(PagedResults *prp) + prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set)); + } + +- /* clean up the slot except the mutex */ ++ /* clean up the slot */ + prp->pr_current_be = NULL; + prp->pr_search_result_set = NULL; + prp->pr_search_result_count = 0; +@@ -136,6 +140,8 @@ pagedresults_parse_control_value(Slapi_PBlock *pb, + return LDAP_UNWILLING_TO_PERFORM; + } + ++ /* Acquire hash-based lock for paged results list access ++ * IMPORTANT: Never acquire this lock when holding c_mutex */ + pthread_mutex_lock(pageresult_lock_get_addr(conn)); + /* the ber encoding is no longer needed */ + ber_free(ber, 1); +@@ -184,10 +190,6 @@ pagedresults_parse_control_value(Slapi_PBlock *pb, + goto bail; + } + +- if ((*index > -1) && (*index < conn->c_pagedresults.prl_maxlen) && +- !conn->c_pagedresults.prl_list[*index].pr_mutex) { +- conn->c_pagedresults.prl_list[*index].pr_mutex = PR_NewLock(); +- } + conn->c_pagedresults.prl_count++; + } else { + /* Repeated paged results request. +@@ -327,8 +329,14 @@ bailout: + "<= idx=%d\n", index); + } + ++/* ++ * Free one paged result entry by index. ++ * ++ * Locking: If locked=0, acquires pageresult_lock. If locked=1, assumes ++ * caller already holds pageresult_lock. Never call when holding c_mutex. ++ */ + int +-pagedresults_free_one(Connection *conn, Operation *op, int index) ++pagedresults_free_one(Connection *conn, Operation *op, bool locked, int index) + { + int rc = -1; + +@@ -338,7 +346,9 @@ pagedresults_free_one(Connection *conn, Operation *op, int index) + slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_free_one", + "=> idx=%d\n", index); + if (conn && (index > -1)) { +- pthread_mutex_lock(pageresult_lock_get_addr(conn)); ++ if (!locked) { ++ pthread_mutex_lock(pageresult_lock_get_addr(conn)); ++ } + if (conn->c_pagedresults.prl_count <= 0) { + slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_free_one", + "conn=%" PRIu64 " paged requests list count is %d\n", +@@ -349,7 +359,9 @@ pagedresults_free_one(Connection *conn, Operation *op, int index) + conn->c_pagedresults.prl_count--; + rc = 0; + } +- pthread_mutex_unlock(pageresult_lock_get_addr(conn)); ++ if (!locked) { ++ pthread_mutex_unlock(pageresult_lock_get_addr(conn)); ++ } + } + + slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_free_one", "<= %d\n", rc); +@@ -357,21 +369,28 @@ pagedresults_free_one(Connection *conn, Operation *op, int index) + } + + /* +- * Used for abandoning - pageresult_lock_get_addr(conn) is already locked in do_abandone. ++ * Free one paged result entry by message ID. ++ * ++ * Locking: If locked=0, acquires pageresult_lock. If locked=1, assumes ++ * caller already holds pageresult_lock. Never call when holding c_mutex. + */ + int +-pagedresults_free_one_msgid(Connection *conn, ber_int_t msgid, pthread_mutex_t *mutex) ++pagedresults_free_one_msgid(Connection *conn, ber_int_t msgid, bool locked) + { + int rc = -1; + int i; ++ pthread_mutex_t *lock = NULL; + + if (conn && (msgid > -1)) { + if (conn->c_pagedresults.prl_maxlen <= 0) { + ; /* Not a paged result. */ + } else { + slapi_log_err(SLAPI_LOG_TRACE, +- "pagedresults_free_one_msgid_nolock", "=> msgid=%d\n", msgid); +- pthread_mutex_lock(mutex); ++ "pagedresults_free_one_msgid", "=> msgid=%d\n", msgid); ++ lock = pageresult_lock_get_addr(conn); ++ if (!locked) { ++ pthread_mutex_lock(lock); ++ } + for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) { + if (conn->c_pagedresults.prl_list[i].pr_msgid == msgid) { + PagedResults *prp = conn->c_pagedresults.prl_list + i; +@@ -390,9 +409,11 @@ pagedresults_free_one_msgid(Connection *conn, ber_int_t msgid, pthread_mutex_t * + break; + } + } +- pthread_mutex_unlock(mutex); ++ if (!locked) { ++ pthread_mutex_unlock(lock); ++ } + slapi_log_err(SLAPI_LOG_TRACE, +- "pagedresults_free_one_msgid_nolock", "<= %d\n", rc); ++ "pagedresults_free_one_msgid", "<= %d\n", rc); + } + } + +@@ -418,29 +439,43 @@ pagedresults_get_current_be(Connection *conn, int index) + return be; + } + ++/* ++ * Set current backend for a paged result entry. ++ * ++ * Locking: If locked=false, acquires pageresult_lock. If locked=true, assumes ++ * caller already holds pageresult_lock. Never call when holding c_mutex. ++ */ + int +-pagedresults_set_current_be(Connection *conn, Slapi_Backend *be, int index, int nolock) ++pagedresults_set_current_be(Connection *conn, Slapi_Backend *be, int index, bool locked) + { + int rc = -1; + slapi_log_err(SLAPI_LOG_TRACE, + "pagedresults_set_current_be", "=> idx=%d\n", index); + if (conn && (index > -1)) { +- if (!nolock) ++ if (!locked) { + pthread_mutex_lock(pageresult_lock_get_addr(conn)); ++ } + if (index < conn->c_pagedresults.prl_maxlen) { + conn->c_pagedresults.prl_list[index].pr_current_be = be; + } + rc = 0; +- if (!nolock) ++ if (!locked) { + pthread_mutex_unlock(pageresult_lock_get_addr(conn)); ++ } + } + slapi_log_err(SLAPI_LOG_TRACE, + "pagedresults_set_current_be", "<= %d\n", rc); + return rc; + } + ++/* ++ * Get search result set for a paged result entry. ++ * ++ * Locking: If locked=0, acquires pageresult_lock. If locked=1, assumes ++ * caller already holds pageresult_lock. Never call when holding c_mutex. ++ */ + void * +-pagedresults_get_search_result(Connection *conn, Operation *op, int locked, int index) ++pagedresults_get_search_result(Connection *conn, Operation *op, bool locked, int index) + { + void *sr = NULL; + if (!op_is_pagedresults(op)) { +@@ -465,8 +500,14 @@ pagedresults_get_search_result(Connection *conn, Operation *op, int locked, int + return sr; + } + ++/* ++ * Set search result set for a paged result entry. ++ * ++ * Locking: If locked=0, acquires pageresult_lock. If locked=1, assumes ++ * caller already holds pageresult_lock. Never call when holding c_mutex. ++ */ + int +-pagedresults_set_search_result(Connection *conn, Operation *op, void *sr, int locked, int index) ++pagedresults_set_search_result(Connection *conn, Operation *op, void *sr, bool locked, int index) + { + int rc = -1; + if (!op_is_pagedresults(op)) { +@@ -494,8 +535,14 @@ pagedresults_set_search_result(Connection *conn, Operation *op, void *sr, int lo + return rc; + } + ++/* ++ * Get search result count for a paged result entry. ++ * ++ * Locking: If locked=0, acquires pageresult_lock. If locked=1, assumes ++ * caller already holds pageresult_lock. Never call when holding c_mutex. ++ */ + int +-pagedresults_get_search_result_count(Connection *conn, Operation *op, int index) ++pagedresults_get_search_result_count(Connection *conn, Operation *op, bool locked, int index) + { + int count = 0; + if (!op_is_pagedresults(op)) { +@@ -504,19 +551,29 @@ pagedresults_get_search_result_count(Connection *conn, Operation *op, int index) + slapi_log_err(SLAPI_LOG_TRACE, + "pagedresults_get_search_result_count", "=> idx=%d\n", index); + if (conn && (index > -1)) { +- pthread_mutex_lock(pageresult_lock_get_addr(conn)); ++ if (!locked) { ++ pthread_mutex_lock(pageresult_lock_get_addr(conn)); ++ } + if (index < conn->c_pagedresults.prl_maxlen) { + count = conn->c_pagedresults.prl_list[index].pr_search_result_count; + } +- pthread_mutex_unlock(pageresult_lock_get_addr(conn)); ++ if (!locked) { ++ pthread_mutex_unlock(pageresult_lock_get_addr(conn)); ++ } + } + slapi_log_err(SLAPI_LOG_TRACE, + "pagedresults_get_search_result_count", "<= %d\n", count); + return count; + } + ++/* ++ * Set search result count for a paged result entry. ++ * ++ * Locking: If locked=0, acquires pageresult_lock. If locked=1, assumes ++ * caller already holds pageresult_lock. Never call when holding c_mutex. ++ */ + int +-pagedresults_set_search_result_count(Connection *conn, Operation *op, int count, int index) ++pagedresults_set_search_result_count(Connection *conn, Operation *op, int count, bool locked, int index) + { + int rc = -1; + if (!op_is_pagedresults(op)) { +@@ -525,11 +582,15 @@ pagedresults_set_search_result_count(Connection *conn, Operation *op, int count, + slapi_log_err(SLAPI_LOG_TRACE, + "pagedresults_set_search_result_count", "=> idx=%d\n", index); + if (conn && (index > -1)) { +- pthread_mutex_lock(pageresult_lock_get_addr(conn)); ++ if (!locked) { ++ pthread_mutex_lock(pageresult_lock_get_addr(conn)); ++ } + if (index < conn->c_pagedresults.prl_maxlen) { + conn->c_pagedresults.prl_list[index].pr_search_result_count = count; + } +- pthread_mutex_unlock(pageresult_lock_get_addr(conn)); ++ if (!locked) { ++ pthread_mutex_unlock(pageresult_lock_get_addr(conn)); ++ } + rc = 0; + } + slapi_log_err(SLAPI_LOG_TRACE, +@@ -537,9 +598,16 @@ pagedresults_set_search_result_count(Connection *conn, Operation *op, int count, + return rc; + } + ++/* ++ * Get search result set size estimate for a paged result entry. ++ * ++ * Locking: If locked=0, acquires pageresult_lock. If locked=1, assumes ++ * caller already holds pageresult_lock. Never call when holding c_mutex. ++ */ + int + pagedresults_get_search_result_set_size_estimate(Connection *conn, + Operation *op, ++ bool locked, + int index) + { + int count = 0; +@@ -550,11 +618,15 @@ pagedresults_get_search_result_set_size_estimate(Connection *conn, + "pagedresults_get_search_result_set_size_estimate", + "=> idx=%d\n", index); + if (conn && (index > -1)) { +- pthread_mutex_lock(pageresult_lock_get_addr(conn)); ++ if (!locked) { ++ pthread_mutex_lock(pageresult_lock_get_addr(conn)); ++ } + if (index < conn->c_pagedresults.prl_maxlen) { + count = conn->c_pagedresults.prl_list[index].pr_search_result_set_size_estimate; + } +- pthread_mutex_unlock(pageresult_lock_get_addr(conn)); ++ if (!locked) { ++ pthread_mutex_unlock(pageresult_lock_get_addr(conn)); ++ } + } + slapi_log_err(SLAPI_LOG_TRACE, + "pagedresults_get_search_result_set_size_estimate", "<= %d\n", +@@ -562,10 +634,17 @@ pagedresults_get_search_result_set_size_estimate(Connection *conn, + return count; + } + ++/* ++ * Set search result set size estimate for a paged result entry. ++ * ++ * Locking: If locked=0, acquires pageresult_lock. If locked=1, assumes ++ * caller already holds pageresult_lock. Never call when holding c_mutex. ++ */ + int + pagedresults_set_search_result_set_size_estimate(Connection *conn, + Operation *op, + int count, ++ bool locked, + int index) + { + int rc = -1; +@@ -576,11 +655,15 @@ pagedresults_set_search_result_set_size_estimate(Connection *conn, + "pagedresults_set_search_result_set_size_estimate", + "=> idx=%d\n", index); + if (conn && (index > -1)) { +- pthread_mutex_lock(pageresult_lock_get_addr(conn)); ++ if (!locked) { ++ pthread_mutex_lock(pageresult_lock_get_addr(conn)); ++ } + if (index < conn->c_pagedresults.prl_maxlen) { + conn->c_pagedresults.prl_list[index].pr_search_result_set_size_estimate = count; + } +- pthread_mutex_unlock(pageresult_lock_get_addr(conn)); ++ if (!locked) { ++ pthread_mutex_unlock(pageresult_lock_get_addr(conn)); ++ } + rc = 0; + } + slapi_log_err(SLAPI_LOG_TRACE, +@@ -589,8 +672,14 @@ pagedresults_set_search_result_set_size_estimate(Connection *conn, + return rc; + } + ++/* ++ * Get with_sort flag for a paged result entry. ++ * ++ * Locking: If locked=0, acquires pageresult_lock. If locked=1, assumes ++ * caller already holds pageresult_lock. Never call when holding c_mutex. ++ */ + int +-pagedresults_get_with_sort(Connection *conn, Operation *op, int index) ++pagedresults_get_with_sort(Connection *conn, Operation *op, bool locked, int index) + { + int flags = 0; + if (!op_is_pagedresults(op)) { +@@ -599,19 +688,29 @@ pagedresults_get_with_sort(Connection *conn, Operation *op, int index) + slapi_log_err(SLAPI_LOG_TRACE, + "pagedresults_get_with_sort", "=> idx=%d\n", index); + if (conn && (index > -1)) { +- pthread_mutex_lock(pageresult_lock_get_addr(conn)); ++ if (!locked) { ++ pthread_mutex_lock(pageresult_lock_get_addr(conn)); ++ } + if (index < conn->c_pagedresults.prl_maxlen) { + flags = conn->c_pagedresults.prl_list[index].pr_flags & CONN_FLAG_PAGEDRESULTS_WITH_SORT; + } +- pthread_mutex_unlock(pageresult_lock_get_addr(conn)); ++ if (!locked) { ++ pthread_mutex_unlock(pageresult_lock_get_addr(conn)); ++ } + } + slapi_log_err(SLAPI_LOG_TRACE, + "pagedresults_get_with_sort", "<= %d\n", flags); + return flags; + } + ++/* ++ * Set with_sort flag for a paged result entry. ++ * ++ * Locking: If locked=0, acquires pageresult_lock. If locked=1, assumes ++ * caller already holds pageresult_lock. Never call when holding c_mutex. ++ */ + int +-pagedresults_set_with_sort(Connection *conn, Operation *op, int flags, int index) ++pagedresults_set_with_sort(Connection *conn, Operation *op, int flags, bool locked, int index) + { + int rc = -1; + if (!op_is_pagedresults(op)) { +@@ -620,14 +719,18 @@ pagedresults_set_with_sort(Connection *conn, Operation *op, int flags, int index + slapi_log_err(SLAPI_LOG_TRACE, + "pagedresults_set_with_sort", "=> idx=%d\n", index); + if (conn && (index > -1)) { +- pthread_mutex_lock(pageresult_lock_get_addr(conn)); ++ if (!locked) { ++ pthread_mutex_lock(pageresult_lock_get_addr(conn)); ++ } + if (index < conn->c_pagedresults.prl_maxlen) { + if (flags & OP_FLAG_SERVER_SIDE_SORTING) { + conn->c_pagedresults.prl_list[index].pr_flags |= + CONN_FLAG_PAGEDRESULTS_WITH_SORT; + } + } +- pthread_mutex_unlock(pageresult_lock_get_addr(conn)); ++ if (!locked) { ++ pthread_mutex_unlock(pageresult_lock_get_addr(conn)); ++ } + rc = 0; + } + slapi_log_err(SLAPI_LOG_TRACE, "pagedresults_set_with_sort", "<= %d\n", rc); +@@ -802,10 +905,6 @@ pagedresults_cleanup(Connection *conn, int needlock) + rc = 1; + } + prp->pr_current_be = NULL; +- if (prp->pr_mutex) { +- PR_DestroyLock(prp->pr_mutex); +- prp->pr_mutex = NULL; +- } + memset(prp, '\0', sizeof(PagedResults)); + } + conn->c_pagedresults.prl_count = 0; +@@ -840,10 +939,6 @@ pagedresults_cleanup_all(Connection *conn, int needlock) + i < conn->c_pagedresults.prl_maxlen; + i++) { + prp = conn->c_pagedresults.prl_list + i; +- if (prp->pr_mutex) { +- PR_DestroyLock(prp->pr_mutex); +- prp->pr_mutex = NULL; +- } + if (prp->pr_current_be && prp->pr_search_result_set && + prp->pr_current_be->be_search_results_release) { + prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set)); +@@ -1010,43 +1105,8 @@ op_set_pagedresults(Operation *op) + op->o_flags |= OP_FLAG_PAGED_RESULTS; + } + +-/* +- * pagedresults_lock/unlock -- introduced to protect search results for the +- * asynchronous searches. Do not call these functions while the PR conn lock +- * is held (e.g. pageresult_lock_get_addr(conn)) +- */ +-void +-pagedresults_lock(Connection *conn, int index) +-{ +- PagedResults *prp; +- if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) { +- return; +- } +- pthread_mutex_lock(pageresult_lock_get_addr(conn)); +- prp = conn->c_pagedresults.prl_list + index; +- if (prp->pr_mutex) { +- PR_Lock(prp->pr_mutex); +- } +- pthread_mutex_unlock(pageresult_lock_get_addr(conn)); +-} +- +-void +-pagedresults_unlock(Connection *conn, int index) +-{ +- PagedResults *prp; +- if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) { +- return; +- } +- pthread_mutex_lock(pageresult_lock_get_addr(conn)); +- prp = conn->c_pagedresults.prl_list + index; +- if (prp->pr_mutex) { +- PR_Unlock(prp->pr_mutex); +- } +- pthread_mutex_unlock(pageresult_lock_get_addr(conn)); +-} +- + int +-pagedresults_is_abandoned_or_notavailable(Connection *conn, int locked, int index) ++pagedresults_is_abandoned_or_notavailable(Connection *conn, bool locked, int index) + { + PagedResults *prp; + int32_t result; +@@ -1066,7 +1126,7 @@ pagedresults_is_abandoned_or_notavailable(Connection *conn, int locked, int inde + } + + int +-pagedresults_set_search_result_pb(Slapi_PBlock *pb, void *sr, int locked) ++pagedresults_set_search_result_pb(Slapi_PBlock *pb, void *sr, bool locked) + { + int rc = -1; + Connection *conn = NULL; +diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h +index 765c12bf5..455d6d718 100644 +--- a/ldap/servers/slapd/proto-slap.h ++++ b/ldap/servers/slapd/proto-slap.h +@@ -1614,20 +1614,22 @@ pthread_mutex_t *pageresult_lock_get_addr(Connection *conn); + int pagedresults_parse_control_value(Slapi_PBlock *pb, struct berval *psbvp, ber_int_t *pagesize, int *index, Slapi_Backend *be); + void pagedresults_set_response_control(Slapi_PBlock *pb, int iscritical, ber_int_t estimate, int curr_search_count, int index); + Slapi_Backend *pagedresults_get_current_be(Connection *conn, int index); +-int pagedresults_set_current_be(Connection *conn, Slapi_Backend *be, int index, int nolock); +-void *pagedresults_get_search_result(Connection *conn, Operation *op, int locked, int index); +-int pagedresults_set_search_result(Connection *conn, Operation *op, void *sr, int locked, int index); +-int pagedresults_get_search_result_count(Connection *conn, Operation *op, int index); +-int pagedresults_set_search_result_count(Connection *conn, Operation *op, int cnt, int index); ++int pagedresults_set_current_be(Connection *conn, Slapi_Backend *be, int index, bool locked); ++void *pagedresults_get_search_result(Connection *conn, Operation *op, bool locked, int index); ++int pagedresults_set_search_result(Connection *conn, Operation *op, void *sr, bool locked, int index); ++int pagedresults_get_search_result_count(Connection *conn, Operation *op, bool locked, int index); ++int pagedresults_set_search_result_count(Connection *conn, Operation *op, int cnt, bool locked, int index); + int pagedresults_get_search_result_set_size_estimate(Connection *conn, + Operation *op, ++ bool locked, + int index); + int pagedresults_set_search_result_set_size_estimate(Connection *conn, + Operation *op, + int cnt, ++ bool locked, + int index); +-int pagedresults_get_with_sort(Connection *conn, Operation *op, int index); +-int pagedresults_set_with_sort(Connection *conn, Operation *op, int flags, int index); ++int pagedresults_get_with_sort(Connection *conn, Operation *op, bool locked, int index); ++int pagedresults_set_with_sort(Connection *conn, Operation *op, int flags, bool locked, int index); + int pagedresults_get_unindexed(Connection *conn, Operation *op, int index); + int pagedresults_set_unindexed(Connection *conn, Operation *op, int index); + int pagedresults_get_sort_result_code(Connection *conn, Operation *op, int index); +@@ -1639,15 +1641,13 @@ int pagedresults_cleanup(Connection *conn, int needlock); + int pagedresults_is_timedout_nolock(Connection *conn); + int pagedresults_reset_timedout_nolock(Connection *conn); + int pagedresults_in_use_nolock(Connection *conn); +-int pagedresults_free_one(Connection *conn, Operation *op, int index); +-int pagedresults_free_one_msgid(Connection *conn, ber_int_t msgid, pthread_mutex_t *mutex); ++int pagedresults_free_one(Connection *conn, Operation *op, bool locked, int index); ++int pagedresults_free_one_msgid(Connection *conn, ber_int_t msgid, bool locked); + int op_is_pagedresults(Operation *op); + int pagedresults_cleanup_all(Connection *conn, int needlock); + void op_set_pagedresults(Operation *op); +-void pagedresults_lock(Connection *conn, int index); +-void pagedresults_unlock(Connection *conn, int index); +-int pagedresults_is_abandoned_or_notavailable(Connection *conn, int locked, int index); +-int pagedresults_set_search_result_pb(Slapi_PBlock *pb, void *sr, int locked); ++int pagedresults_is_abandoned_or_notavailable(Connection *conn, bool locked, int index); ++int pagedresults_set_search_result_pb(Slapi_PBlock *pb, void *sr, bool locked); + + /* + * sort.c +diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h +index 11c5602e3..d494931c2 100644 +--- a/ldap/servers/slapd/slap.h ++++ b/ldap/servers/slapd/slap.h +@@ -89,6 +89,10 @@ static char ptokPBE[34] = "Internal (Software) Token "; + #include + #include /* For timespec definitions */ + ++/* Macros for paged results lock parameter */ ++#define PR_LOCKED true ++#define PR_NOT_LOCKED false ++ + /* Provides our int types and platform specific requirements. */ + #include + +@@ -1669,7 +1673,6 @@ typedef struct _paged_results + struct timespec pr_timelimit_hr; /* expiry time of this request rel to clock monotonic */ + int pr_flags; + ber_int_t pr_msgid; /* msgid of the request; to abandon */ +- PRLock *pr_mutex; /* protect each conn structure */ + } PagedResults; + + /* array of simple paged structure stashed in connection */ +-- +2.52.0 + diff --git a/0003-Issue-7108-Fix-shutdown-crash-in-entry-cache-destruc.patch b/0003-Issue-7108-Fix-shutdown-crash-in-entry-cache-destruc.patch new file mode 100644 index 0000000..bb2127c --- /dev/null +++ b/0003-Issue-7108-Fix-shutdown-crash-in-entry-cache-destruc.patch @@ -0,0 +1,183 @@ +From 4936f953fa3b0726c2b178f135cd78dcac7463ba Mon Sep 17 00:00:00 2001 +From: Simon Pichugin +Date: Thu, 8 Jan 2026 10:02:39 -0800 +Subject: [PATCH] Issue 7108 - Fix shutdown crash in entry cache destruction + (#7163) + +Description: The entry cache could experience LRU list corruption when +using pinned entries, leading to crashes during cache flush operations. + +In entrycache_add_int(), when returning an existing cached entry, the +code checked the wrong entry's state before calling lru_delete(). It +checked the new entry 'e' but operated on the existing entry 'my_alt', +causing lru_delete() to be called on entries not in the LRU list. This +is fixed by checking my_alt's refcnt and pinned state instead. + +In flush_hash(), pinned_remove() and lru_delete() were both called on +pinned entries. Since pinned entries are in the pinned list, calling +lru_delete() afterwards corrupted the list. This is fixed by calling +either pinned_remove() or lru_delete() based on the entry's state. + +A NULL check is added in entrycache_flush() and dncache_flush() to +gracefully handle corrupted LRU lists and prevent crashes when +traversing backwards through the list encounters an unexpected NULL. + +Entry pointers are now always cleared after lru_delete() removal to +prevent stale pointer issues in non-debug builds. + +Fixes: https://github.com/389ds/389-ds-base/issues/7108 + +Reviewed by: @progier389, @vashirov (Thanks!!) +--- + ldap/servers/slapd/back-ldbm/cache.c | 48 +++++++++++++++++++++++++--- + 1 file changed, 43 insertions(+), 5 deletions(-) + +diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c +index 2e4126134..a87f30687 100644 +--- a/ldap/servers/slapd/back-ldbm/cache.c ++++ b/ldap/servers/slapd/back-ldbm/cache.c +@@ -458,11 +458,13 @@ static void + lru_delete(struct cache *cache, void *ptr) + { + struct backcommon *e; ++ + if (NULL == ptr) { + LOG("=> lru_delete\n<= lru_delete (null entry)\n"); + return; + } + e = (struct backcommon *)ptr; ++ + #ifdef LDAP_CACHE_DEBUG_LRU + pinned_verify(cache, __LINE__); + lru_verify(cache, e, 1); +@@ -475,8 +477,9 @@ lru_delete(struct cache *cache, void *ptr) + e->ep_lrunext->ep_lruprev = e->ep_lruprev; + else + cache->c_lrutail = e->ep_lruprev; +-#ifdef LDAP_CACHE_DEBUG_LRU ++ /* Always clear pointers after removal to prevent stale pointer issues */ + e->ep_lrunext = e->ep_lruprev = NULL; ++#ifdef LDAP_CACHE_DEBUG_LRU + lru_verify(cache, e, 0); + #endif + } +@@ -633,9 +636,14 @@ flush_hash(struct cache *cache, struct timespec *start_time, int32_t type) + if (entry->ep_refcnt == 0) { + entry->ep_refcnt++; + if (entry->ep_state & ENTRY_STATE_PINNED) { ++ /* Entry is in pinned list, not LRU - remove from pinned only. ++ * pinned_remove clears lru pointers and won't add to LRU since refcnt > 0. ++ */ + pinned_remove(cache, laste); ++ } else { ++ /* Entry is in LRU list - remove from LRU */ ++ lru_delete(cache, laste); + } +- lru_delete(cache, laste); + if (type == ENTRY_CACHE) { + entrycache_remove_int(cache, laste); + entrycache_return(cache, (struct backentry **)&laste, PR_TRUE); +@@ -679,9 +687,14 @@ flush_hash(struct cache *cache, struct timespec *start_time, int32_t type) + if (entry->ep_refcnt == 0) { + entry->ep_refcnt++; + if (entry->ep_state & ENTRY_STATE_PINNED) { ++ /* Entry is in pinned list, not LRU - remove from pinned only. ++ * pinned_remove clears lru pointers and won't add to LRU since refcnt > 0. ++ */ + pinned_remove(cache, laste); ++ } else { ++ /* Entry is in LRU list - remove from LRU */ ++ lru_delete(cache, laste); + } +- lru_delete(cache, laste); + entrycache_remove_int(cache, laste); + entrycache_return(cache, (struct backentry **)&laste, PR_TRUE); + } else { +@@ -772,6 +785,11 @@ entrycache_flush(struct cache *cache) + } else { + e = BACK_LRU_PREV(e, struct backentry *); + } ++ if (e == NULL) { ++ slapi_log_err(SLAPI_LOG_WARNING, "entrycache_flush", ++ "Unexpected NULL entry while flushing cache - LRU list may be corrupted\n"); ++ break; ++ } + ASSERT(e->ep_refcnt == 0); + e->ep_refcnt++; + if (entrycache_remove_int(cache, e) < 0) { +@@ -1160,6 +1178,7 @@ pinned_remove(struct cache *cache, void *ptr) + { + struct backentry *e = (struct backentry *)ptr; + ASSERT(e->ep_state & ENTRY_STATE_PINNED); ++ + cache->c_pinned_ctx->npinned--; + cache->c_pinned_ctx->size -= e->ep_size; + e->ep_state &= ~ENTRY_STATE_PINNED; +@@ -1172,13 +1191,23 @@ pinned_remove(struct cache *cache, void *ptr) + cache->c_pinned_ctx->head = cache->c_pinned_ctx->tail = NULL; + } else { + cache->c_pinned_ctx->head = BACK_LRU_NEXT(e, struct backentry *); ++ /* Update new head's prev pointer to NULL */ ++ if (cache->c_pinned_ctx->head) { ++ cache->c_pinned_ctx->head->ep_lruprev = NULL; ++ } + } + } else if (cache->c_pinned_ctx->tail == e) { + cache->c_pinned_ctx->tail = BACK_LRU_PREV(e, struct backentry *); ++ /* Update new tail's next pointer to NULL */ ++ if (cache->c_pinned_ctx->tail) { ++ cache->c_pinned_ctx->tail->ep_lrunext = NULL; ++ } + } else { ++ /* Middle of list: update both neighbors to point to each other */ + BACK_LRU_PREV(e, struct backentry *)->ep_lrunext = BACK_LRU_NEXT(e, struct backcommon *); + BACK_LRU_NEXT(e, struct backentry *)->ep_lruprev = BACK_LRU_PREV(e, struct backcommon *); + } ++ /* Clear the removed entry's pointers */ + e->ep_lrunext = e->ep_lruprev = NULL; + if (e->ep_refcnt == 0) { + lru_add(cache, ptr); +@@ -1245,6 +1274,7 @@ pinned_add(struct cache *cache, void *ptr) + return false; + } + /* Now it is time to insert the entry in the pinned list */ ++ + cache->c_pinned_ctx->npinned++; + cache->c_pinned_ctx->size += e->ep_size; + e->ep_state |= ENTRY_STATE_PINNED; +@@ -1754,7 +1784,7 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state, struct b + * 3) ep_state: 0 && state: 0 + * ==> increase the refcnt + */ +- if (e->ep_refcnt == 0) ++ if (e->ep_refcnt == 0 && (e->ep_state & ENTRY_STATE_PINNED) == 0) + lru_delete(cache, (void *)e); + e->ep_refcnt++; + e->ep_state &= ~ENTRY_STATE_UNAVAILABLE; +@@ -1781,7 +1811,7 @@ entrycache_add_int(struct cache *cache, struct backentry *e, int state, struct b + } else { + if (alt) { + *alt = my_alt; +- if (e->ep_refcnt == 0 && (e->ep_state & ENTRY_STATE_PINNED) == 0) ++ if (my_alt->ep_refcnt == 0 && (my_alt->ep_state & ENTRY_STATE_PINNED) == 0) + lru_delete(cache, (void *)*alt); + (*alt)->ep_refcnt++; + LOG("the entry %s already exists. returning existing entry %s (state: 0x%x)\n", +@@ -2379,6 +2409,14 @@ dncache_flush(struct cache *cache) + } else { + dn = BACK_LRU_PREV(dn, struct backdn *); + } ++ if (dn == NULL) { ++ /* Safety check: we should normally exit via the CACHE_LRU_HEAD check. ++ * If we get here, c_lruhead may be NULL or the LRU list is corrupted. ++ */ ++ slapi_log_err(SLAPI_LOG_WARNING, "dncache_flush", ++ "Unexpected NULL entry while flushing cache - LRU list may be corrupted\n"); ++ break; ++ } + ASSERT(dn->ep_refcnt == 0); + dn->ep_refcnt++; + if (dncache_remove_int(cache, dn) < 0) { +-- +2.52.0 + diff --git a/0004-Issue-7172-Index-ordering-mismatch-after-upgrade-717.patch b/0004-Issue-7172-Index-ordering-mismatch-after-upgrade-717.patch new file mode 100644 index 0000000..2ea800b --- /dev/null +++ b/0004-Issue-7172-Index-ordering-mismatch-after-upgrade-717.patch @@ -0,0 +1,215 @@ +From 742c12e0247ab64e87da000a4de2f3e5c99044ab Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +Date: Fri, 9 Jan 2026 11:39:50 +0100 +Subject: [PATCH] Issue 7172 - Index ordering mismatch after upgrade (#7173) + +Bug Description: +Commit daf731f55071d45eaf403a52b63d35f4e699ff28 introduced a regression. +After upgrading to a version that adds `integerOrderingMatch` matching +rule to `parentid` and `ancestorid` indexes, searches may return empty +or incorrect results. + +This happens because the existing index data was created with +lexicographic ordering, but the new compare function expects integer +ordering. Index lookups fail because the compare function doesn't match +the data ordering. +The root cause is that `ldbm_instance_create_default_indexes()` calls +`attr_index_config()` unconditionally for `parentid` and `ancestorid` +indexes, which triggers `ainfo_dup()` to overwrite `ai_key_cmp_fn` on +existing indexes. This breaks indexes that were created without the +`integerOrderingMatch` matching rule. + +Fix Description: +* Call `attr_index_config()` for `parentid` and `ancestorid` indexes +only if index config doesn't exist. + +* Add `upgrade_check_id_index_matching_rule()` that logs an error on +server startup if `parentid` or `ancestorid` indexes are missing the +integerOrderingMatch matching rule, advising administrators to reindex. + +Fixes: https://github.com/389ds/389-ds-base/issues/7172 + +Reviewed by: @tbordaz, @progier389, @droideck (Thanks!) +--- + ldap/servers/slapd/back-ldbm/instance.c | 25 ++++-- + ldap/servers/slapd/upgrade.c | 107 +++++++++++++++++++++++- + 2 files changed, 123 insertions(+), 9 deletions(-) + +diff --git a/ldap/servers/slapd/back-ldbm/instance.c b/ldap/servers/slapd/back-ldbm/instance.c +index cb002c379..71bf0f6fa 100644 +--- a/ldap/servers/slapd/back-ldbm/instance.c ++++ b/ldap/servers/slapd/back-ldbm/instance.c +@@ -190,6 +190,7 @@ ldbm_instance_create_default_indexes(backend *be) + char *ancestorid_indexes_limit = NULL; + char *parentid_indexes_limit = NULL; + struct attrinfo *ai = NULL; ++ struct attrinfo *index_already_configured = NULL; + struct index_idlistsizeinfo *iter; + int cookie; + int limit; +@@ -248,10 +249,14 @@ ldbm_instance_create_default_indexes(backend *be) + ldbm_instance_config_add_index_entry(inst, e, flags); + slapi_entry_free(e); + +- e = ldbm_instance_init_config_entry(LDBM_PARENTID_STR, "eq", 0, 0, 0, "integerOrderingMatch", parentid_indexes_limit); +- ldbm_instance_config_add_index_entry(inst, e, flags); +- attr_index_config(be, "ldbm index init", 0, e, 1, 0, NULL); +- slapi_entry_free(e); ++ ainfo_get(be, (char *)LDBM_PARENTID_STR, &ai); ++ index_already_configured = ai; ++ if (!index_already_configured) { ++ e = ldbm_instance_init_config_entry(LDBM_PARENTID_STR, "eq", 0, 0, 0, "integerOrderingMatch", parentid_indexes_limit); ++ ldbm_instance_config_add_index_entry(inst, e, flags); ++ attr_index_config(be, "ldbm index init", 0, e, 1, 0, NULL); ++ slapi_entry_free(e); ++ } + + e = ldbm_instance_init_config_entry("objectclass", "eq", 0, 0, 0, 0, 0); + ldbm_instance_config_add_index_entry(inst, e, flags); +@@ -288,10 +293,14 @@ ldbm_instance_create_default_indexes(backend *be) + * ancestorid is special, there is actually no such attr type + * but we still want to use the attr index file APIs. + */ +- e = ldbm_instance_init_config_entry(LDBM_ANCESTORID_STR, "eq", 0, 0, 0, "integerOrderingMatch", ancestorid_indexes_limit); +- ldbm_instance_config_add_index_entry(inst, e, flags); +- attr_index_config(be, "ldbm index init", 0, e, 1, 0, NULL); +- slapi_entry_free(e); ++ ainfo_get(be, (char *)LDBM_ANCESTORID_STR, &ai); ++ index_already_configured = ai; ++ if (!index_already_configured) { ++ e = ldbm_instance_init_config_entry(LDBM_ANCESTORID_STR, "eq", 0, 0, 0, "integerOrderingMatch", ancestorid_indexes_limit); ++ ldbm_instance_config_add_index_entry(inst, e, flags); ++ attr_index_config(be, "ldbm index init", 0, e, 1, 0, NULL); ++ slapi_entry_free(e); ++ } + + slapi_ch_free_string(&ancestorid_indexes_limit); + slapi_ch_free_string(&parentid_indexes_limit); +diff --git a/ldap/servers/slapd/upgrade.c b/ldap/servers/slapd/upgrade.c +index 858392564..b02e37ed6 100644 +--- a/ldap/servers/slapd/upgrade.c ++++ b/ldap/servers/slapd/upgrade.c +@@ -330,6 +330,107 @@ upgrade_remove_subtree_rename(void) + return UPGRADE_SUCCESS; + } + ++/* ++ * Check if parentid/ancestorid indexes are missing the integerOrderingMatch ++ * matching rule. ++ * ++ * This function logs a warning if we detect this condition, advising ++ * the administrator to reindex the affected attributes. ++ */ ++static upgrade_status ++upgrade_check_id_index_matching_rule(void) ++{ ++ struct slapi_pblock *pb = slapi_pblock_new(); ++ Slapi_Entry **backends = NULL; ++ const char *be_base_dn = "cn=ldbm database,cn=plugins,cn=config"; ++ const char *be_filter = "(objectclass=nsBackendInstance)"; ++ const char *attrs_to_check[] = {"parentid", "ancestorid", NULL}; ++ upgrade_status uresult = UPGRADE_SUCCESS; ++ ++ /* Search for all backend instances */ ++ slapi_search_internal_set_pb( ++ pb, be_base_dn, ++ LDAP_SCOPE_ONELEVEL, ++ be_filter, NULL, 0, NULL, NULL, ++ plugin_get_default_component_id(), 0); ++ slapi_search_internal_pb(pb); ++ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &backends); ++ ++ if (backends) { ++ for (size_t be_idx = 0; backends[be_idx] != NULL; be_idx++) { ++ const char *be_name = slapi_entry_attr_get_ref(backends[be_idx], "cn"); ++ if (!be_name) { ++ continue; ++ } ++ ++ /* Check each attribute that should have integerOrderingMatch */ ++ for (size_t attr_idx = 0; attrs_to_check[attr_idx] != NULL; attr_idx++) { ++ const char *attr_name = attrs_to_check[attr_idx]; ++ struct slapi_pblock *idx_pb = slapi_pblock_new(); ++ Slapi_Entry **idx_entries = NULL; ++ char *idx_dn = slapi_create_dn_string("cn=%s,cn=index,cn=%s,%s", ++ attr_name, be_name, be_base_dn); ++ char *idx_filter = "(objectclass=nsIndex)"; ++ PRBool has_matching_rule = PR_FALSE; ++ ++ if (!idx_dn) { ++ slapi_pblock_destroy(idx_pb); ++ continue; ++ } ++ ++ slapi_search_internal_set_pb( ++ idx_pb, idx_dn, ++ LDAP_SCOPE_BASE, ++ idx_filter, NULL, 0, NULL, NULL, ++ plugin_get_default_component_id(), 0); ++ slapi_search_internal_pb(idx_pb); ++ slapi_pblock_get(idx_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &idx_entries); ++ ++ if (idx_entries && idx_entries[0]) { ++ /* Index exists, check if it has integerOrderingMatch */ ++ Slapi_Attr *mr_attr = NULL; ++ if (slapi_entry_attr_find(idx_entries[0], "nsMatchingRule", &mr_attr) == 0) { ++ Slapi_Value *sval = NULL; ++ int idx; ++ for (idx = slapi_attr_first_value(mr_attr, &sval); ++ idx != -1; ++ idx = slapi_attr_next_value(mr_attr, idx, &sval)) { ++ const struct berval *bval = slapi_value_get_berval(sval); ++ if (bval && bval->bv_val && ++ strcasecmp(bval->bv_val, "integerOrderingMatch") == 0) { ++ has_matching_rule = PR_TRUE; ++ break; ++ } ++ } ++ } ++ ++ if (!has_matching_rule) { ++ /* Index exists but doesn't have integerOrderingMatch, log a warning */ ++ slapi_log_err(SLAPI_LOG_ERR, "upgrade_check_id_index_matching_rule", ++ "Index '%s' in backend '%s' is missing 'nsMatchingRule: integerOrderingMatch'. " ++ "Incorrectly configured system indexes can lead to poor search performance, replication issues, and other operational problems. " ++ "To fix this, add the matching rule and reindex: " ++ "dsconf backend index set --add-mr integerOrderingMatch --attr %s %s && " ++ "dsconf backend index reindex --attr %s %s. " ++ "WARNING: Reindexing can be resource-intensive and may impact server performance on a live system. " ++ "Consider scheduling reindexing during maintenance windows or periods of low activity.\n", ++ attr_name, be_name, attr_name, be_name, attr_name, be_name); ++ } ++ } ++ ++ slapi_ch_free_string(&idx_dn); ++ slapi_free_search_results_internal(idx_pb); ++ slapi_pblock_destroy(idx_pb); ++ } ++ } ++ } ++ ++ slapi_free_search_results_internal(pb); ++ slapi_pblock_destroy(pb); ++ ++ return uresult; ++} ++ + /* + * Upgrade the base config of the PAM PTA plugin. + * +@@ -547,7 +648,11 @@ upgrade_server(void) + if (upgrade_pam_pta_default_config() != UPGRADE_SUCCESS) { + return UPGRADE_FAILURE; + } +- ++ ++ if (upgrade_check_id_index_matching_rule() != UPGRADE_SUCCESS) { ++ return UPGRADE_FAILURE; ++ } ++ + return UPGRADE_SUCCESS; + } + +-- +2.52.0 + diff --git a/389-ds-base.spec b/389-ds-base.spec index df9cf96..fbf685d 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -500,16 +500,22 @@ Requires: python3-file-magic # Picks up our systemd deps. %{?systemd_requires} -Source0: %{name}-%{version}.tar.bz2 +Source0: https://github.com/389ds/%{name}/releases/download/%{name}-%{version}/%{name}-%{version}.tar.bz2 Source2: %{name}-devel.README %if %{with bundle_jemalloc} Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download/%{jemalloc_ver}/%{jemalloc_name}-%{jemalloc_ver}.tar.bz2 +Source6: jemalloc-5.3.0_throw_bad_alloc.patch %endif Source4: 389-ds-base.sysusers %if %{with bundle_libdb} Source5: https://fedorapeople.org/groups/389ds/libdb-5.3.28-59.tar.bz2 %endif +Patch: 0001-Issue-7096-During-replication-online-total-init-the-.patch +Patch: 0002-Issue-Revise-paged-result-search-locking.patch +Patch: 0003-Issue-7108-Fix-shutdown-crash-in-entry-cache-destruc.patch +Patch: 0004-Issue-7172-Index-ordering-mismatch-after-upgrade-717.patch + %description 389 Directory Server is an LDAPv3 compliant server. The base package includes the LDAP server and command line utilities for server administration. @@ -706,6 +712,7 @@ COCKPIT_FLAGS="--disable-cockpit" # Build jemalloc pushd ../%{jemalloc_name}-%{jemalloc_ver} +patch -p1 -F3 < %{SOURCE6} %configure \ --libdir=%{_libdir}/%{pkgname}/lib \ --bindir=%{_libdir}/%{pkgname}/bin \ @@ -1083,174 +1090,4 @@ exit 0 %endif %changelog -* Tue Dec 16 2025 Mark Reynolds - 2.4.4 -- Issue 7147 - entrycache_eviction_test is failing (#7148) -- Issue 1793 - RFE - Dynamic lists - UI and CLI updates -- Issue 7119 - Fix DNA shared config replication test (#7143) -- Issue 7081 - Repl Log Analysis - Implement data sampling with performance and timezone fixes (#7086) -- Issue 1793 - RFE - Implement dynamic lists -- Issue 7112 - dsctrl dblib bdb2mdb core dumps and won't allow conversion (#7144) -- Issue 7053 - Remove memberof_del_dn_from_groups from MemberOf plugin (#7064) -- Issue 7138 - test_cleanallruv_repl does not restart supplier3 (#7139) -- Issue 6753 - Port ticket47921 test to indirect_cos_test using DSLdapObject (#7134) -- Issue 7128 - memory corruption in alias entry plugin (#7131) -- Issue 7091 - Duplicate local password policy entries listed (#7092) -- Issue 7124 - BDB cursor race condition with transaction isolation (#7125) -- Issue 6951 - Dynamic Certificate refresh phase 1 - Search support (#7117) -- Issue 7132 - Keep alive entry updated too soon after an offline import (#7133) -- Issue 7135 - Not enough space for tests on GH runner (#7136) -- Issue 7121 - LeakSanitizer: various leaks during replication (#7122) -- Issue 7115 - LeakSanitizer: leak in `slapd_bind_local_user()` (#7116) -- Issue 7109 - AddressSanitizer: SEGV ldap/servers/slapd/csnset.c:302 in csnset_dup (#7114) -- Issue 7119 - Harden DNA plugin locking for shared server list operations (#7120) -- Issue 7084 - UI - schema - sorting attributes breaks expanded row -- Issue 6753 - Port ticket47910 test to logconv_test using DSLdapObject (#7098) -- Issue 6753 - Port ticket47920 test to ldap_controls_test using DSLdapObject (#7103) -- Issue 7007 - Improve paged result search locking -- Issue 7041 - Add WebUI test for group member management (#7111) -- Issue 3555 - UI - Fix audit issue with npm - glob (#7107) -- Issue 7089 - Fix dsconf certificate list (#7090) -- Issue 7076, 6992, 6784, 6214 - Fix CI test failures (#7077) -- Bump js-yaml from 4.1.0 to 4.1.1 in /src/cockpit/389-console (#7097) -- Issue 7069 - Fix error reporting in HAProxy trusted IP parsing (#7094) -- Issue 7049 - RetroCL plugin generates invalid LDIF -- Issue 7055 - Online initialization of consumers fails with error -23 (#7075) -- Issue 6753 - Remove ticket 47900 test (#7087) -- Issue 6753 - Port ticket 49008 test (#7080) -- Issue 7042 - Enable global_backend_lock when memberofallbackend is enabled (#7043) -- Issue 7078 - audit json logging does not encode binary values -- Issue 7069 - Add Subnet/CIDR Support for HAProxy Trusted IPs (#7070) -- Issue 7056 - DSBLE0007 doesn't generate remediation steps for missing indexes -- Issue 6660 - CLI, UI - Improve replication log analyzer usability (#7062) -- Issue 7065 - A search filter containing a non normalized DN assertion does not return matching entries (#7068) -- Issue 7071 - search filter (&(cn:dn:=groups)) no longer returns results -- Issue 7073 - Add NDN cache size configuration and enforcement tests (#7074) -- Issue 6753 - Removing ticket 47871 test and porting to DSLdapObject (#7045) -- Issue 7041 - CLI/UI - memberOf - no way to add/remove specific group filters -- Issue 6753 - Port ticket 48228 test (#7067) -- Issue 7029 - Add test case to measure ndn cache performance impact (#7030) -- Issue 7061 - CLI/UI - Improve error messages for dsconf localpwp list -- Issue 7059 - UI - unable to upload pem file -- Issue 7032 - The new ipahealthcheck test ipahealthcheck.ds.backends.BackendsCheck raises CRITICAL issue (#7036) -- Issue 7047 - MemberOf plugin logs null attribute name on fixup task completion (#7048) -- Issue 7044 - RFE - index sudoHost by default (#7046) -- Issue 6846 - Attribute uniqueness is not enforced with modrdn (#7026) -- Issue 6784 - Support of Entry cache pinned entries (#6785) -- Issue 6979 - Improve the way to detect asynchronous operations in the access logs (#6980) -- Issue 6753 - Port ticket 47931 test (#7038) -- Issue 7035 - RFE - memberOf - adding scoping for specific groups -- CLI/UI - Add option to delete all replication conflict entries -- Issue 7033 - lib389 - basic plugin status not in JSON -- Issue 7023 - UI - if first instance that is loaded is stopped it breaks parts of the UI -- Issue 6753 - Removing ticket 47714 test and porting to DSLdapObject (#6946) -- Issue 7027 - 389-ds-base OpenScanHub Leaks Detected (#7028) -- Issue 6753 - Removing ticket 47676 test and porting to DSLdapObject (#6938) -- Issue 6966 - On large DB, unlimited IDL scan limit reduce the SRCH performance (#6967) -- Issue 6660 - UI - Improve replication log analysis charts and usability (#6968) -- Issue 6753 - Removing ticket 47653MMR test and porting to DSLdapObject (#6926) -- Issue 7021 - Units for changing MDB max size are not consistent across different tools (#7022) -- Issue 6753 - Removing ticket 49463 test and porting to DSLdapObject (#6899) -- Issue 6954 - do not delete referrals on chain_on_update backend -- Issue 6982 - UI - MemberOf shared config does not validate DN properly (#6983) -- Issue 6740 - Fix FIPS mode test failures in syncrepl, mapping tree, and resource limits (#6993) -- Issue 7018 - BUG - prevent stack depth being hit (#7019) -- Issue 7014 - memberOf - ignored deferred updates with LMDB -- Issue 7002 - restore is failing. (#7003) -- Issue 6758 - Fix WebUI monitoring test failure due to FormSelect component deprecation (#7004) -- Issue 6753 - Removing ticket 47869 test and porting to DSLdapObject (#7001) -- Issue 6753 - Port ticket 49073 test (#7005) -- Issue 7016 - fix NULL deref in send_referrals_from_entry() (#7017) -- Issue 6753 - Port ticket 47815 test (#7000) -- Issue 7010 - Fix certdir underflow in slapd_nss_init() (#7011) -- Issue 7012 - improve dscrl dbverify result when backend does not exists (#7013) -- Issue 6753 - Removing ticket 477828 test and porting to DSLdapObject (#6989) -- Issue 6753 - Removing ticket 47721 test and porting to DSLdapObject (#6973) -- Issue 6992 - Improve handling of mismatched ldif import (#6999) -- Issue 6997 - Logic error in get_bdb_impl_status prevents bdb2mdb execution (#6998) -- Issue 6810 - Deprecate PAM PTA plugin configuration attributes in base entry - fix memleak (#6988) -- Issue 6971 - bundle-rust-npm.py: TypeError: argument of type 'NoneType' is not iterable (#6972) -- Fix overflow in certmap filter/DN buffers (#6995) -- Issue 6753 - Port ticket 49386 test (#6987) -- Issue 6753 - Removing ticket 47787 test and porting to DSLdapObject (#6976) -- Issue 6753 - Port ticket 49072 test (#6984) -- Issue 6990 - UI - Replace deprecated Select components with new TypeaheadSelect (#6996) -- Issue 6990 - UI - Fix typeahead Select fields losing values on Enter keypress (#6991) -- Issue 6887 - Enhance logconv.py to add support for JSON access logs (#6889) -- Issue 6985 - Some logconv CI tests fail with BDB (#6986) -- Issue 6891 - JSON logging - add wrapper function that checks for NULL -- Issue 4835 - dsconf display an incomplete help with changelog setting (#6769) -- Issue 6753 - Port ticket 47963 & 49184 tests (#6970) -- Issue 6753 - Port ticket 47829 & 47833 tests -- Issue 6977 - UI - Show error message when trying to use unavailable ports (#6978) -- Issue 6956 - More UI fixes -- Issue 6626 - Fix version -- Issue 6900 - Rename test files for proper pytest discovery (#6909) -- Issue 6947 - Revise time skew check in healthcheck tool and add option to exclude checks -- Issue 6805 - RFE - Multiple backend entry cache tuning -- Issue 6753 - Port and fix ticket 47823 tests -- Issue 6843 - Add CI tests for logconv.py (#6856) -- Issue 6933 - When deferred memberof update is enabled after the server crashed it should not launch memberof fixup task by default (#6935) -- UI - update Radio handlers and LDAP entries last modified time -- Issue 6810 - Deprecate PAM PTA plugin configuration attributes in base entry (#6832) -- Issue 6660 - UI - Fix minor typo (#6955) -- Issue 6753 - Port ticket 47808 test -- Issue 6910 - Fix latest coverity issues -- Issue 6753 - Removing ticket 50232 test and porting to DSLdapObject (#6861) -- Issue 6919 - numSubordinates/tombstoneNumSubordinates are inconsisten… (#6920) -- Issue 6430 - Fix build with bundled libdb -- Issue 6342 - buffer owerflow in the function parseVariant (#6927) -- Issue 6940 - dsconf monitor server fails with ldapi:// due to absent server ID (#6941) -- Issue 6936 - Make user/subtree policy creation idempotent (#6937) -- Migrate from PR_Poll to epoll and timerfd. (#6924) -- Issue 6928 - The parentId attribute is indexed with improper matching rule -- Issue 6753 - Removing ticket 49540 test and porting to DSLdapObject (#6877) -- Issue 6904 - Fix config_test.py::test_lmdb_config -- Issue 5120 - Fix compilation error -- Issue 6929 - Compilation failure with rust-1.89 on Fedora ELN -- Issue 6922 - AddressSanitizer: leaks found by acl test suite -- Issue 6519 - Add basic dsidm account tests -- Issue 6753 - Port ticket test 47573 -- Issue 6875 - Fix dsidm tests -- Issues 6913, 6886, 6250 - Adjust xfail marks (#6914) -- Issue 6768 - ns-slapd crashes when a referral is added (#6780) -- Issue 6468 - CLI - Fix default error log level -- Issue 6181 - RFE - Allow system to manage uid/gid at startup -- Issue 6901 - Update changelog trimming logging - fix tests -- Issue 6778 - Memory leak in roles_cache_create_object_from_entry part 2 -- Issue 6897 - Fix disk monitoring test failures and improve test maintainability (#6898) -- Issue 6884 - Mask password hashes in audit logs (#6885) -- Issue 6594 - Add test for numSubordinates replication consistency with tombstones (#6862) -- Issue 6250 - Add test for entryUSN overflow on failed add operations (#6821) -- Issue 6895 - Crash if repl keep alive entry can not be created -- Issue 6663 - Fix NULL subsystem crash in JSON error logging (#6883) -- Issue 6430 - implement read-only bdb (#6431) -- Issue 6901 - Update changelog trimming logging -- Issue 6880 - Fix ds_logs test suite failure -- Issue 6352 - Fix DeprecationWarning -- Issue 6800 - Rerun the check in verbose mode on failure -- Issue 6893 - Log user that is updated during password modify extended operation -- Issue 6772 - dsconf - Replicas with the "consumer" role allow for viewing and modification of their changelog. (#6773) -- Issue 6829 - Update parametrized docstring for tests -- Issue 6888 - Missing access JSON logging for TLS/Client auth -- Issue 6878 - Prevent repeated disconnect logs during shutdown (#6879) -- Issue 6872 - compressed log rotation creates files with world readable permission -- Issue 6859 - str2filter is not fully applying matching rules -- Issue 5733 - Remove outdated Dockerfiles -- Issue 6800 - Check for minimal supported Python version -- Issue 6868 - UI - schema attribute table expansion break after moving to a new page -- Issue 6865 - AddressSanitizer: leak in agmt_update_init_status -- Issue 6848 - AddressSanitizer: leak in do_search -- Issue 6850 - AddressSanitizer: memory leak in mdb_init -- Issue 6854 - Refactor for improved data management (#6855) -- Issue 6756 - CLI, UI - Properly handle disabled NDN cache (#6757) -- Issue 6857 - uiduniq: allow specifying match rules in the filter -- Issue 6852 - Move ds* CLI tools back to /sbin -- Issue 6753 - Port ticket tests 48294 & 48295 -- Issue 6753 - Add 'add_exclude_subtree' and 'remove_exclude_subtree' methods to Attribute uniqueness plugin -- Issue 6841 - Cancel Actions when PR is updated -- Issue 6838 - lib389/replica.py is using nonexistent datetime.UTC in Python 3.9 -- Issue 6822 - Backend creation cleanup and Database UI tab error handling (#6823) -- Issue 6782 - Improve paged result locking -- Issue 6829 - Update parametrized docstring for tests - %autochangelog diff --git a/jemalloc-5.3.0_throw_bad_alloc.patch b/jemalloc-5.3.0_throw_bad_alloc.patch new file mode 100644 index 0000000..94e4d36 --- /dev/null +++ b/jemalloc-5.3.0_throw_bad_alloc.patch @@ -0,0 +1,41 @@ +#commit 3de0c24859f4413bf03448249078169bb50bda0f +#Author: divanorama +#Date: Thu Sep 29 23:35:59 2022 +0200 +# +# Disable builtin malloc in tests +# +# With `--with-jemalloc-prefix=` and without `-fno-builtin` or `-O1` both clang and gcc may optimize out `malloc` calls +# whose result is unused. Comparing result to NULL also doesn't necessarily count as being used. +# +# This won't be a problem in most client programs as this only concerns really unused pointers, but in +# tests it's important to actually execute allocations. +# `-fno-builtin` should disable this optimization for both gcc and clang, and applying it only to tests code shouldn't hopefully be an issue. +# Another alternative is to force "use" of result but that'd require more changes and may miss some other optimization-related issues. +# +# This should resolve https://github.com/jemalloc/jemalloc/issues/2091 +# +#diff --git a/Makefile.in b/Makefile.in +#index 6809fb29..a964f07e 100644 +#--- a/Makefile.in +#+++ b/Makefile.in +#@@ -458,6 +458,8 @@ $(TESTS_OBJS): $(objroot)test/%.$(O): $(srcroot)test/%.c +# $(TESTS_CPP_OBJS): $(objroot)test/%.$(O): $(srcroot)test/%.cpp +# $(TESTS_OBJS): CPPFLAGS += -I$(srcroot)test/include -I$(objroot)test/include +# $(TESTS_CPP_OBJS): CPPFLAGS += -I$(srcroot)test/include -I$(objroot)test/include +#+$(TESTS_OBJS): CFLAGS += -fno-builtin +#+$(TESTS_CPP_OBJS): CPPFLAGS += -fno-builtin +# ifneq ($(IMPORTLIB),$(SO)) +# $(CPP_OBJS) $(C_SYM_OBJS) $(C_OBJS) $(C_JET_SYM_OBJS) $(C_JET_OBJS): CPPFLAGS += -DDLLEXPORT +# endif +diff --git a/src/jemalloc_cpp.cpp b/src/jemalloc_cpp.cpp +index fffd6aee..5a682991 100644 +--- a/src/jemalloc_cpp.cpp ++++ b/src/jemalloc_cpp.cpp +@@ -93,7 +93,7 @@ handleOOM(std::size_t size, bool nothrow) { + } + + if (ptr == nullptr && !nothrow) +- std::__throw_bad_alloc(); ++ throw std::bad_alloc(); + return ptr; + } diff --git a/sources b/sources index ec0ac34..7004305 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (389-ds-base-3.2.0.tar.bz2) = 9b26db52c401237dfb1a4d05629d9f7336f656f9f9f251f76d19b76e8c7a174a32a306277b695e7f1b358557b63eaa2589699c4cb7619c661799000834d293f9 SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1 SHA512 (libdb-5.3.28-59.tar.bz2) = 731a434fa2e6487ebb05c458b0437456eb9f7991284beb08cb3e21931e23bdeddddbc95bfabe3a2f9f029fe69cd33a2d4f0f5ce6a9811e9c3b940cb6fde4bf79 +SHA512 (389-ds-base-3.2.0.tar.bz2) = 9ff6aa56b30863c619f4f324344dca72cc883236bfe8d94520e8469d9e306f54b373ee2504eda18dcb0ecda33f915a3e64a6f3cdaa93a69b74d901caa48545e1 From e3abfab8ae611ba8a25d46709cecf9e26e61aa4c Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Fri, 9 Jan 2026 19:42:11 +0100 Subject: [PATCH 123/125] Correct License: string for robdb-libs --- 389-ds-base.spec | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/389-ds-base.spec b/389-ds-base.spec index fbf685d..3f6554c 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -528,8 +528,7 @@ Please see http://seclists.org/oss-sec/2016/q1/363 for more information. %if %{with libbdb_ro} %package robdb-libs Summary: Read-only Berkeley Database Library -# IMPORTANT - Check if it looks right. Additionally, compare with the original line. Then, remove this comment and # FIXME - part. -# FIXME - License: GPL-3.0-or-later WITH GPL-3.0-389-ds-base-exception AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR LGPL-2.1-or-later OR MIT) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-3.0 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0 AND Zlib +License: GPL-2.0-or-later OR LGPL-2.1-or-later %description robdb-libs The %{name}-robdb-lib package contains a library derived from rpm From 26f66fc9f3ac81a70c890c354759932f0b7781f2 Mon Sep 17 00:00:00 2001 From: Viktor Ashirov Date: Mon, 12 Jan 2026 12:18:28 +0100 Subject: [PATCH 124/125] Fix broken FreeIPA upgrade and replication issues - Resolves: rhbz#2424132 Upgrade from freeipa-4.12.5-3 and 390-ds-base-3.1.3-10 to latest rawhide fails --- ...ndex-ordering-mismatch-after-upgrade.patch | 67 +++++++++++++++++++ 389-ds-base.spec | 1 + 2 files changed, 68 insertions(+) create mode 100644 0005-Issue-7172-2nd-Index-ordering-mismatch-after-upgrade.patch diff --git a/0005-Issue-7172-2nd-Index-ordering-mismatch-after-upgrade.patch b/0005-Issue-7172-2nd-Index-ordering-mismatch-after-upgrade.patch new file mode 100644 index 0000000..591d144 --- /dev/null +++ b/0005-Issue-7172-2nd-Index-ordering-mismatch-after-upgrade.patch @@ -0,0 +1,67 @@ +From f5de84e309d5a4435198c9cc9b31b5722979f1ff Mon Sep 17 00:00:00 2001 +From: Viktor Ashirov +Date: Mon, 12 Jan 2026 10:58:02 +0100 +Subject: [PATCH 5/5] Issue 7172 - (2nd) Index ordering mismatch after upgrade + (#7180) + +Commit 742c12e0247ab64e87da000a4de2f3e5c99044ab introduced a regression +where the check to skip creating parentid/ancestorid indexes if they +already exist was incorrect. +The `ainfo_get()` function falls back to returning +LDBM_PSEUDO_ATTR_DEFAULT attrinfo when the requested attribute is not +found. +Since LDBM_PSEUDO_ATTR_DEFAULT is created before the ancestorid check, +`ainfo_get()` returns LDBM_PSEUDO_ATTR_DEFAULT instead of NULL, causing +the ancestorid index creation to be skipped entirely. + +When operations later try to use the ancestorid index, they fall back to +LDBM_PSEUDO_ATTR_DEFAULT, and attempting to open the .default dbi +mid-transaction fails with MDB_NOTFOUND (-30798). + +Fix Description: +Instead of just checking if `ainfo_get()` returns non-NULL, verify that +the returned attrinfo is actually for the requested attribute. + +Fixes: https://github.com/389ds/389-ds-base/issues/7172 + +Reviewed by: @tbordaz (Thanks!) +--- + ldap/servers/slapd/back-ldbm/instance.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/ldap/servers/slapd/back-ldbm/instance.c b/ldap/servers/slapd/back-ldbm/instance.c +index 71bf0f6fa..2a6e8cbb8 100644 +--- a/ldap/servers/slapd/back-ldbm/instance.c ++++ b/ldap/servers/slapd/back-ldbm/instance.c +@@ -190,7 +190,7 @@ ldbm_instance_create_default_indexes(backend *be) + char *ancestorid_indexes_limit = NULL; + char *parentid_indexes_limit = NULL; + struct attrinfo *ai = NULL; +- struct attrinfo *index_already_configured = NULL; ++ int index_already_configured = 0; + struct index_idlistsizeinfo *iter; + int cookie; + int limit; +@@ -250,7 +250,8 @@ ldbm_instance_create_default_indexes(backend *be) + slapi_entry_free(e); + + ainfo_get(be, (char *)LDBM_PARENTID_STR, &ai); +- index_already_configured = ai; ++ /* Check if the attrinfo is actually for parentid, not a fallback to .default */ ++ index_already_configured = (ai != NULL && strcmp(ai->ai_type, LDBM_PARENTID_STR) == 0); + if (!index_already_configured) { + e = ldbm_instance_init_config_entry(LDBM_PARENTID_STR, "eq", 0, 0, 0, "integerOrderingMatch", parentid_indexes_limit); + ldbm_instance_config_add_index_entry(inst, e, flags); +@@ -294,7 +295,8 @@ ldbm_instance_create_default_indexes(backend *be) + * but we still want to use the attr index file APIs. + */ + ainfo_get(be, (char *)LDBM_ANCESTORID_STR, &ai); +- index_already_configured = ai; ++ /* Check if the attrinfo is actually for ancestorid, not a fallback to .default */ ++ index_already_configured = (ai != NULL && strcmp(ai->ai_type, LDBM_ANCESTORID_STR) == 0); + if (!index_already_configured) { + e = ldbm_instance_init_config_entry(LDBM_ANCESTORID_STR, "eq", 0, 0, 0, "integerOrderingMatch", ancestorid_indexes_limit); + ldbm_instance_config_add_index_entry(inst, e, flags); +-- +2.52.0 + diff --git a/389-ds-base.spec b/389-ds-base.spec index 3f6554c..e864a88 100644 --- a/389-ds-base.spec +++ b/389-ds-base.spec @@ -515,6 +515,7 @@ Patch: 0001-Issue-7096-During-replication-online-total-init-the-.patc Patch: 0002-Issue-Revise-paged-result-search-locking.patch Patch: 0003-Issue-7108-Fix-shutdown-crash-in-entry-cache-destruc.patch Patch: 0004-Issue-7172-Index-ordering-mismatch-after-upgrade-717.patch +Patch: 0005-Issue-7172-2nd-Index-ordering-mismatch-after-upgrade.patch %description 389 Directory Server is an LDAPv3 compliant server. The base package includes From cd5135cf3ae298b3ccbf044f2eed924c170ba339 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 16 Jan 2026 02:25:37 +0000 Subject: [PATCH 125/125] Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild

R5;4?6MIYPr1KZY;k+3;m2-h8RX@THy&U!bmq -zFHoo93)HpnrJjZ_@KrHQweV#) -z8@|BvM)+ccFS!X{K7#P&0X2MCpbKB{<_pv>4PV}%;R}2QhA&W8!NI?T=e6(!>RR}syZHijBYZK!m)wLeKZNk*8Z~@*kquvdi{T5@ -zF9~0cV)z1|LBp4iFnoc!7QP&3!{jnW_t4@aD_o7{2Uf!xyM);S1Dh_yTn;eA!FG7x=0ezChgwUySf2H{r`Y -z5WWa%_#)HrB{O4f^75g>2lUx=@7up!uiH}bZr7A_op8e_C2zv93*jyPP>DzQ$>S%8 -zX?)zYSYcoCKl<2(@JwH5rdRkF&hz4?xeB}two+Bm5dVr^HRml$J5aE`*=(h2Wi+yy>>7-;$Qysg@nm -zzx~A0H)tu2)eK38^ZX%rhaVr9)a}l%bTt)OXGKY1d|dZ(f91fYj6FYUYpSxWIZqC3 -zNnLycxuCR@n*Pa}aa?N&5#tWAkPlqj?QSh~!7hv{OX+#CZfk1Y9%-M4Sndc~7R6ep -zro*c}A$YexA24^jn~Pn|<6@FIZCITQl}oqqe)NMXqUO)*TU&m><9R_Hk*im&lI?<)JZd -zY&v|aH>7*Nk}#~DaAT6(P|jLGM3X~=*Y_#X-i&=|#J03ro_C%|4JoNk>hKYHdGO-v -z$hhTYM67g($N0q1ZujzX*YZ;9=_pAIj9+}cl4SD}c}h^eJJvZe9X{(1!Q1=z#JFzv -z#tPTQVyit$5>w)dWlHzvjD1Da25%#abq-F4Grmy9EA)B%Br)B4&pWc4H&xy9Ey>%H -z%G)BrJ7eJB`nYL;k~dkt5H9hCO8f%*N-{W~88?kp>Zi&V!ah&P=Mx;fX~R9=lKRc5 -z`d!lfN6bY0!XaMIn;wPYj#Pc4G}a?*h0ZZ?(*kAXSouQud0*&xukb%m92kd}#cY#q -zKV~N4Vuu*yP1bw9B`X_K@XCIl@O^k_QQS04X(^B|gx~gt-u4Sqp*SZF?^bG%{{4}e -zh<|X1&+?`f-R}G%SALmwTZ9DW$1lF9U#j;K%i}@I&{)mbba4Nu6Kw@-Z{A2oh);~TVbo^>E}s&cPhR^O8JT0Hz*g!xFPBANPh_4a>*wqb-Slk -zy7m`Y=R`?jd|bEwLXkFQ>=UE5m#XA7=ZUl>b@3hjLZY2;{gd1{uC0WKUpd5OeB#<} -zcU!3ow#8J*rRT|pt*H%rq}Mz|z9T3vigiv+hi#q^Y`@?W=5BYW*cB?b{v$#X%i|Yc -z(J$TPCGtZ-d19Kpz`2IWITn*=5tF496DU$lpi{%- -z9K{5Rh{;ll$+Ijb@Q{YdIf@As5tF3`CI%+Gj>%6xyb$g;d;UdCX3b|XdGSMv$&EMzhHm|_B*8YUmJn9M{>7P6RpOfi8@4U>;qOlBIG7?|`vCc6NW`&CTtXEA{T -z4U;djVFKqGCSS0a+>e+np_o9CVgj8SCSOoYpoo|(p_tsyVge6on0!Gofg)nE#K6SB -zr1vrT2ryZoVzPk6(|h++cghzVvUV-XWJGkN(ViV1XTn0&-yG8QpmGn1cv -zL@|L*4U>;pOvW0R7?|`vCN~2nx2u@k&SC-w8YZ!9n83M)NsPthcEkiT6DU$lpi{#n -zMlpdRVuG2;?JOqnkcLT&Vgg0P#K=qxOmcw93BW|nOlGl}$%`i_CZA-*0#UX`z@vr-n%ji^*KXM3k(n5n -z&Wg!ViV2(}CYYHNASSxZ$tl1@%}id`WhSR6CV$I{$tj8noFgWfnG_-> -zy3FJh#RNJvOir41R -znwhN8WhMtHCX=&ba*$#I=Mfp3iwPWPn0%QH -z6FAo}`I5zCEnyu3^&3Vsa;9f|&^vDJIaVVbV%5fg)mpnaQ0j -zCh(AkNh`$!iinAknHZSl0F#q|iJF|`wJtL` -zOfk73D<+32CU8zM`7357BPk}|=rWVT6cgywFgeU(GLm8f-w895!xR(f)G#^BVlvXe -z#K5HYF}VRSxmCsFRu&UD&@lNd8zykBVe%P^$*mNVuQ4-$BEk4E -zZe=lnhcrw+qnJREV)8#mW@2EH15AzsCTeE#wJtL`PBD2uD<;P&CUB0JU}kbHVxr4T -zj#EsaQ^Vvqi^;W!i7qoaPBDQ_4U^+6Cf6F6{QnV?74M{eGGI`@K1K82Wp^qhA9>`f -zo`y`Z{PVx|RW|I**c&6Z#%g)od9tBCwPCyTnxDwSg7Ph~&O9zuLBypF@jX5oG0CTQr%mm4}3&k8kC=ob@oq(pYw&D^9twq#Hem}y4;m6wf6n@%f#~G -zjp{Dc>EDvPEvdYEX^U6*<1;6SX+Yd`rIOcl>_WK2A3Ed_e#4ulDtV34OpmY=&d0`0 -z3zhokk6j4+d?BA#Xy;88)4%=iuDZW2Ama57@prt*2F1qI%1zQ(pHK#!3*x4s%F2Dm -zE`*==hMxBeZ5 -z3*oo@p(i}T&!IRmZd$6e)JgyTW&shOb%+=EK%Z`Rewi!3#JVj?0z=|~tCYFhrFuWH -z3=LXtj@9I)!z=xv7LV{YADF7lZItGEg!*<;Gc;K+n2R3Ky=BTZ? -z%Ci1EIZ&56uv=2R#IiAH=^twy&6!Jxc+?@z<^xxEyUnF8bES1&gal^A1Nq9j1}W|# -zmb-(NWwF-j>2RSZROl0K9PPaQ*;!0LnT~)H}Jc;i}#T%uO9wHY9<;!E-q;z<%C$!fmJisTe -z?{@Dma_uj(z8N8j#qq>&rEs@&$}4=!C;BPU&W!z~i0!3nIsZJ7>QmBoN$?9(+6gx< -z$qnP$Du}quA^x6EOz(ELRl+N^rh9}P?WA)^vU3u*yqJh@I>d+g#0}lm0*vEFt1)hj<;IFm<~(mbx}pT319!Vop3UQR!}wG9Dt^ -zgYt@4{$=8K?tv$qsl2UHzrUJ^c$q`=@TN&h-fOVH!4oR+302RWB$w_GdRe{@p6LzE -z^b1$PIbBirKV~An>=1v*o1U_L``-^eABQ-AH(jo*{F!_qJk}q2-Xr`HIw!|X -zHz+HADqjfS?hD=S6=J+;mF-)ya(8Ow4(U_)PQxAI9^N!gY56%UaPWlQ_6d(b=d!qI -zu+s91d?EaVH}r&GxREzKX8V@3>`1jVN_ie)DGpjLkJU^{hwD9|dY^DVAGp5T-Bjdi -zDzm;GA%Vs5z;I>mZmGp9{F@K-Qx5FR*qb7@rfN(6d2*mWbzr-6z%LZElbUhKnqgdP -z1rZA!qQnQLce`6FUFIU|h-%9f=gGP~sdZbVeLiAY6tp}UYwec~ul9vjdxg*Wz=&>l -zbGfUz)S8TvK>v8)3Psr}75a%~V$foVwT?)KC4XpxM|iEBv<^$QPT@L>tsA2xFe4sV -zp%iS&*!xFqbyf1c=SjhqR6)J8-7Ea5otXP2&11QS5+X(&;sV}zjZy%M>4c%Yb7r@D -zRf%g=h4qdIan6l93zU6(rL`U+e?KT+6EjaqhrjWJzVQjqv=j4;WOE;GUYT`wgg6(( -zokNw?^%?u|i0yc_oOhnA-j!OtO}f)BnA=J7gk-mT8VW>lq8146IUsP+oipJ -zA`cD9H^;cVbof?(=#)ozhfhpZ3LB+sJ;LsG!VOJwlR0ZK5d#j<$tMaGX>-QDG-`XV -zN?w1SNOdV`x76V!^2VU-<`X%`3vMXfXQPjCQDgNV1a{*$#+>X -zIY%*pbHrpR#pF4}WGRcuIf@B%YM7j3F?kL#S;}Gp3mjBTpi{%-9E-_w1||k3y+4`c -z!DP};#iTEb$v}!p&4<}AfpZm;+dpJ6=}R%0IGbhb;Gkjxohl}GMOaLV4NMG7a)1d; -zCM7B+m$R5`Lrgx-h6$W&n0(A)ayeqMkYWNwiV1XTn0!nzfg)nEkYaK -z1d52sLIV>6litVVH-O0_Dke)F@a7ElP_3I?lUkkFzJ0v>R~dOsbVsQ#iSfD`6wGEaIRtU5sS$f -z!~`=FC{j$IQ^VvViU|}E6UlL{VFC4SWJ!}CMU9C0_PegCs<4tASRfZK#^hsof;-5C?-%uOfWN9z+wUqX_%a# -zm_QLRF)|YalN@03JHX^o6%#fyvB3fd6_X=bF*!pqfpf$JGn2;=6E-vX!5NAPbZVHK -zVKI3eF<~>4dtiZsiV1XTn4DoTdECInz@+yvSqYQLSQV3@EGDxMlSA1sfpZO$Lo6mk -zDJCyrW&%Zu33O_h9HN*&kz(>Q%uI%|n7~6CCWj~{P^6f=Xk;b^CON?5mw?H`7cqHB -zmzlr<2Njc9Suy#PVglzBlb>N`ax=xGNtc;?N-=>>4UB=F@bZ$1T&L| -z5ffcz5~r9zr-n(K#pGecM3`(q$&Fz(K`iO;$`kr5V3Gq&U^00^#pDJSldlnzQ`sQ_gNg}sYM7j5F?q(o#K5HYF_{aKNuG+yKo*mH#N=Q$ -zOyFF@SCYYJzvzWj`8YV|5CQw97jLgKq -zBnOxr08G?-CKg?00t*~eOlq=X(n>LbbHoHQlN!WCmzlIuOrTT4q?N^_1~JiPCa}Ok -z#RNJvOj=n?Y79&aOmct;OeX78Ow24Mt%%9VY?#2ghRI156Ek9hnF$mrCeW#2a*|>K -zMZ^R%6ElkmJfvZAl41fy#Kg!<3`}x>i3FIa_e?Ch%mfxVsF<{7#iWg50_TVcW+ohB -zqRUL$C??RUVbaE8!XYNQ%mfxVsF*;fhDjTX31?tpVAA`Ttb@s -zIM*;a%wjTvVj^Q^0!4}mbZVF!rkFsHViLp5WCV)|JfvZAm|_A&ipl3jW@2EH15Dlk -zOw@ZOvMw`$1r91E=B$`}MlpeNib)JJlT{RxR$XTD8N~!THB3HZFk(vCjVv;`n>*ZH&-rT3p=snC%h4>fmuK()jbAETk -z{MRpcrQ+M9r~Jb5cG5gC**uC%RuZwlL#*Qyqr2VHDqPcwt(DdCg7c(sZ>n&!bgPfZ -zR|n;XW85Haf4TLqRq``2u5UVgtuJ(~S2*5IxPeJ7pR<-)V&W%1v`tZoZ=2z&Ub*smglfMwhC5MY(}ajhnAn -zZq_3=x>V&W$_;dC+JIuc30HaQzbulo)m6M74DQq -zdWn2rP#zQG#&gq3iTD?XIF3(T+3nt6;@V$feW*&lE5?oF_E%abMo402JTX?0_GIjq -zh|N+hn`7LxbofzE=uw|=cRS&xB)P#{TR9P34zVZqFR52xb}3Z3nZ|O%Avak!p1`@r -zjc((~G~@;Kmc^)G*O)Jh2*> -z7?||_?4rQzvO&dUIg3drVv=>^37l(~=r*1#M@%qPfg;5OIyFpi;|UZI6HHZ>vzWj` -z8YZ~$1d51>k*XM&Ca*U52=`ZjvG&)NHJMrq$&m`Il#pGoqOOT>P?iT -zY^rh=H=c~hhRGMW@dVB(CW|puDW#a0*;FNl8&9B9#U!fRcv4C+f$v09l{2{U1Ugkr -zzSM0zDK#)LFv$TXFqu@Sm|VeP(twy`-FO1$8Ya4pCs!aQn5saLVgj8SCb;ngiiioO -zDp#4M^7?|V$liva+>P?iTY-Vy6H=ZTjZVv=>^37l(~ -z=r*2=LrgF;fg;5OIyFpi;|UZI6Uk(n5nwI}j5#Gl}8G6X?`1(QQ1r12JJUlQX#S1UfZLbQ@3ZFfcJN -z$pI!XnXFYYS;S&;5;4iT@dVB_OmrJh79l2>nLv?Z0-YKrxbXyvhzVvUi&#wHAq^AU -zcmhSl#K=qxOmcw9`+$jh6J;rznViLqCnvLFf*ViZ95KPnCk;#tOnM)a)i9Y%P%#ECy37PO -zoj>&6o}*D%p-Jeh)+U}geEiV1XTnBc|} -zC?Y19nM`3Zfrm6qaN`LS5fdXbF)+yiCT{^I>OGV9beRcmJXxO=6Wn+L=ZFbrCU+wy -zy37POog2^0|%BQr5D$pI!Iz(l=g@}4d; -z!Hp-$teD`&6F5gqFf(x>Cc4Z7H=aPJhKX+Di3>5&WhS`s1UfZLbQ@1x1||k3y^l#D -zOeP~$Oa`-G)!>g -z2^1+NPZ^nsfk_T9@qgzY_;>Z5$dfQlQ}FV`w^3@8&BX|!$i07WDa72 -znF$mrCeW#2f*Vhuh?rnzGKa+k9?~$ujVDk?N33O_h -z=r*2M3``76a)1d;CXcF^EM+liLrk)6Jb`l!6Wzv>rHBb;CQzi9K&OTYZaje^VuG2; -zQWg_XF)|YalN@03d%#4!XY#ZzGr^4~ZCNqFjVEx9m|$k|G-9I5OmO1~ -zbZVIBHl93^37l(~=r*2= -zqL_4HW&%Zu33O_h;KmauQcTWcW-^M!1Rl~b!Hp+Sq?n|P%*4PX2bjDGn5g$mx^$Td -zZai6@6%*We0_PNy^O%|3MltEsWhS`s1UfZLbQ@1@qnN;V!psCWoyuI9 -zoE~@Hq^#Z~P4E$UW>CIA);u5`e$f|t(JOr2PMZ5Ao5yl*l~@B&;v5lo&Qn(J$k-E6 -z+mtG~BGx=K9bV!Oz3UO)YA4MjlFie&WYPcGm(*|AM=T${rgC$ej+>LjG$3xeQpszD -zzf%6tA&>AI-ZWLoYm{bsgq?7%aq}6w69xYE>`K*dlkSJV1J^sm-|;3J6p@>gl$+1! -zP8292H;aiFbcnUQX(Rl_*pzD7DJ}F0C*UEC8~7{b4?W=#ehx+CW-$?;b%+=EK%Z`R -zewi!3#JVj?0z=|~tCYFhrFuWH3=LXtj@9I)!z=xv7LV{YADF7lZItGEg!*<;Gc;K< -znX4%#;sJ-ajt>+n2R3Ky=BTZ?%Ci1EIZ&56uv=2R#IiAH=^twy&6!Jxc+?@z<^xxE -zyUnF8bES1&gal^A1Nq9j1}W|#mb-(NWwF-j>2RSZROl0K8nU9c58K}?I|rr}E7Zt0L$_$P1br__IOoNhdUbL3_r5npzQKjckM -zU5DH(B;tP@;sD-sxw0~LoNhdUPK}%6?8cMpkeh`pH?S{AU9bh68aKz;jVIUrf0P>% -zA%QvZz(hr9kh(p@Vh>tY#9C*h!-G7bK|Z0lotP&j%>%d*<<`Ry;=DfY9H12J%Gmu8 -zo4;C~6f;lY8cMBysg?(vC;N7$_8FLLmtOM|d00@sCDxh8g(`@+)FHmdC#H3~LzS+L -zMb;VB@|^Redrzu+i}Zny$V-Fr)3MI}>F{&D&~skl9G@7~?M|1w(xukE8(t-r56`NY -zJjP-YLQG&q&?T6_xrWJCEGCa3CQB$LP^6eZr#8EMMKOUQVzPu{@)(N=JfvX)D}q!^ -zpoo|(F)%SO5#Mx(5Alf`y4|57SE$S?R>{uuWJ6tQ!*1!Um&mT5JUG@lhTB*|#M2J( -zIzD0Qc5f_oZLGAeh>*mbcw(Z`-5_N=M79Uz6|sCzBVh7?ipc^N6W9i%VzMzSCdViy -zaE_QPpqR`+Oct=19HW>(r-sQf7Lyr>$pRJ=*aoCx0-YKr$5>2e7?>EC^!`7Db;D%x -zfr^Qp#bhI50xN4kEVrMadhcrxJMUaXK -z6cH1%fr)`h?_=@{z~mtnlSM2hunkDXB%KwL(-adpM@$w`OjaN!i&#ufQ%s;!!{juJ -z$qK||5sL|I15z=8P7RaOEG8=qObkqNfC)?{85I*Zi%A+WffYfQU;^hFCg)g8+=$6i -ziU|}cCeW#2a*kpGMZ{z&#l+2G0uO1Jz=|Lh6DT4kOASm6OnM!YdpCXO9ys;hi -z&tP&BYy(m;>7Nag>p!HJz&XWa`27E3lIlY-88M&1Wbua-6X;YiS@0o)$;mzx6ZlTU -z|GP*2M%V_VVgj8iCO3S@VDgVX1||k3y^qNtm`pZb#N?kvEGGRaCT3U>bO|PKu41w< -z!eDZ=h+;B|W+rE$NHKv<6_dgU#RQ5Jli@ToNf)u0z(Xn~OJGHiiU|}cCL@i^#K0s6 -znEV7Vc~HfK%}j2BZ9pm}by+d_m|_CwhzZS1QkNknY-Y0fV~PoMYM6Y?VsaT`!e%Bn -z!Zsik6X?`1`IyDzG6NF>lN?|IlgU99lY3cA>JSrH5p)SAaIRtU1&hhOhzZS1&O(u5 -z0-YKrUr0xN=4OrVIE7@3KINe(dC37FikV!~!7H^DX_6_e7e -zn0!Prfpf%!W+ti8hzXmSEdGdM0-YKrAF-H>Moieu8Lffk_T9c^NQSt75`tCO5%0AQh9tSur_5F@bZ$gk~nG`G^UdnJhj* -zF@a7ElM^f^^AQs^Gr1AA0jZckr-sQ17L)k~CI%)szyv0fKdG4fh{fbEVgf6IF2MxO -zHB8R1nEVJap_$29C{j$IQ^Vv8#RQ6o3C&E>KVmU~hcrxJMUaXK6cH06Gchp90VZ1k -zllv}W(x}T!U>lH%$rV{KIYcpmbBf6x%uI$*Od52V$svjfbZVF!Vlf#)F@f(ioMtAl -z4M@cVIyFoVv6u`oFflOceM~A~GWn^B$@f@Hu0Tv+MbIUfz`2IWrz|GlqnI>eW&%Zu -z33O_hd`dBaBE@76W+vZbF@c9POkhQjiU|}cCVP#{#K0s6nEVVdQSX^F>M|492Bc!* -z&x%P4#RSd~6U|KxQHlwiBPN)cOhQa_naNR#33O_h9Az4OkhROC78guhRNqFCO -zFf)N7#RNJvOg^WWKoK#)%;bkGCh(Ak39JZGF@YjtVq_);CON?5=YWZN&!kb8nZPz6 -z6_dYY#pD#l1kMo?%uKFFOmvyaDT)bnYM7j2F}WTw(PbvE4M@cVIyFpAv6x(MU}9jB -z1598t`Im~xk6BFqf|$UHpi3};a}ATTEG9ojOfWNnBElH%33O_h9Aq&WU|?ck()*aqhRI}?ib)xZ$vDIW -zRs>yw37l(~L|IJAC?>aIW&%Zu33O_hL@6dvq?mjkGm|nF6L?6&1Xcv8m_U(Ya;uS< -z7?|V$lji{w^`6OXy37Q&0jZe0kQI|pC?;@@m|$jdC1Rq>Og^EQK&OVuCoCpcA||@b -z1hxUGm_Vn7$tNr(R~ncYnB)Kxm`pxVF?o>1yw37l(~e92<+AYy`<2^1+N -z(5YeaCB+1ah{^wB@9x8!DD(aCAJ?PEV`W_)OJRKiN@*KcOOGH_MPNBGEyT0c~z4o`)oIlPv-uK*hI`rX{&wP6Kjd~_e$T5M7BupS8D1`|OB23ht -ziHgYpVDcNlBz4YYv7%=JX+SAVmS@D|y)-5;k1#Y2b`8WUJ4Ve&~D6BtC8pq|O2a!lYN2@{A2N?`(n2otquqGB=tnCt^gQs+z-D|#l7 -z29(0&$bL -zCMqTafC*G4;S?qna!fu(m_S6(|A7h2OPGY@m{cH4P|pMg)0n_Y36oG76BtC8pq@#E -z922-m!UQ6MQkcLX!sMT8k8sH{%66K7ds{(mJDQ@o0$W2F@8<MSp -z#7&2sn_+2g;A0w=?y5juP>LH^DRI*w=VsVH6F1_LQge^^)b`j@J3WDeVkzM&9dz!K -zkyh)2B6a#ns^Hl1ygs{iE@54upRN9p`X$`zbJh{orUm*jABmCM0+AnI^1PTdlzxPj -zF6D~OS#$cmmRA_dp_cNmMQe7{I>;KDCsM?dRN`3Vx=Xg_lZHJXVSAQxw+sL`>!Ege -zImOK*a&GQM++<8Vfq97=dE&|YkEFRdgSsj(nC1pnO5C8t6BtZ$<40YUN95eVMG`kC -z@dO6b+?@Vr>Zmfq4lNdE&|YPa{lFR|N*s -zn7~R26O?!Yg9sDURe4&D30x#$f)Y<)5MlDq)KyV2ac5coH89x?n50gkoKbXDP~r)m -z5fhYn0`mwH)K!^)Fi~_>P~r)!lrWJeo}8M1Fi~_>P~r)!lrWJeo^(%8F;OwO_L%Tc -znb0Xr*2poz5hfWEPheicM4ou^{u+b{>Z-tC8WUJ4VS*A*U=U$~x+-hrn7~C6CMfX) -z1`#IzOkEWflYbdZ_5&uVlPG5tT@{pgaycU=DDed55hkdsav#D((N#f-C$Lh&M4otZ -z>OO>tqN{=uPhh2li9GS7`#u#D6_WwL1S*p&DNMG?F}aK|$(VQo^AaZV#FO{8B1}+M -z1qRcYz)A@dlz0Mz2ouy**(%2bE|M@oi6=0KF!^Wds;HR!%V6@{75fcqQYTRg*t8Chm-hCorGFr9OyHsvCaoy(1P0TX6sSED_4mC7;P<^=0!&gTQ3~Zflana%WM@W9 -zP~r*9BTP`w%4hNyfwzn3ph7B%VBuFhM;N7))aVDnLyOjJy+Jtp-~nUE<=mdP>EAxttRp1{0>i6Zf28NvkhOkgmL -z39OVbL5U|Yh%iAtlVx&D;35eVlz0Mz2otquqGB=tn7j;_q)ws~%6ld!QR2ym88JbL -zCoqpNK|Pb7Axz{w6BkN6ft3;_io}zjAxz{wlXp?#39OVbQ6!%HOvOaSWB@RM%H*pQ -zCeO+-`4C}}G4TZEB}^2FC(j~GP|pMg)0n_Y2@{lf0)q$>)H8WjjtN{OVS*A*U=U%V -z_Dobv1^|<4z$A6fgi`cOP~u5mModuR3CyQ4c?0!KhNLlRR`g6z;t8yjFi|9)3`t`G -z9~0`Cpu`hcDPf{WJQ<>5qGEFGFHw3}ITK3JGeLH?rVS;)l(-0<#o(W1kft3;_io}y?2opum1SOupN(mE1;>k1>6BUyIzyvCjPg0mX -zCCB7A!X#tj3Cv5FC=ySeLYSbQ2@Iw&ft3;_DDeaa5hkc-@{}ACxJbeTC7!?_!bI(v -zsF(}@Cc6NW)HxGM(KA7bC+3Wppu`iHN0^|V$#{f`qGy5%m?#oYW+F@!Jrk680xKm<6p1G@RZLV&1^^SNOnOt8*yNZ*5GENDPheic -zM3H!6LztkR2@Iw&ft3;_DDeaa5hkc-Vv}P67fG0)#1j}qn5aDy6_WwLWcwBS4Z+ko -zlTC`A2}(T4&WH(0Jc0Q%CQqZD$&G1DHY$21DDebVN|-1TPi{UDwAC)Oyk2@^%)$^0}Xn^4aL2Gf|pN(mE`cmjiI -zOrAzPllgK?;35eVlz0MzX-q6?&qT#!05I7Ln552`Y*O@0P~u5rModuR3Ctr*P|svC -z!bH(CL5U}@Qo=-$crqDbqUf2R#1mL4VWLPpnXF=>Vln`jKxJ|&g~@t3CXEP_jEN^O -zFJYocJXw!0K|K=~Ok)BoB}`D_2@E1kP|sw&922-m!UQFrz#zgz?U|^U3;-rO0h81@ -zlTC`A2}(RE&xi?1Jb`(H3F?`QMwlpiCMfX)R!W#C5>G}WOcXs6lz0LwB}^2FC!@rX6hg@2|xbH$+#AvaXn`|KzNA{KmlX -z$(LTQP8!^2G3%02eUJFMBlh|p&-hnbYQ7dfxheX|SZmP(B6Z|RYW=a}_x9P{_Y>}i -z^v&uYsb9iv>k()EDmL?Z&xnH}XLNBR&sl$B&6z7wUp`6Qax8L3pS|fpqG`VVpZbr~ -zw?gd_O>whX&P^xcCSxWF%uC!TGEp`oZctYR2GiWYN{Jhki2{R&8`M?VEawI;lDI*c -zC@_e)DHbX5BkanO(rrEBv|q)hJ?|NEP%JgNN=Kes@e}K)xgzz&lhluo9lxW`UiTnT -zH($SQN$KiyD@IuB7U)NPBp$ylaQw%YUVkxZSn(0IVrgm7xfMD6-ltw+o;uW0_O-Yo -zJGx?!^^dt*KMExW6 -z{~~`^*a6(6PNH-xx+*B~WL8FQP~r*9r@8qCbyY^Bxrr*eDk$*;R!ZC`5>G~?xq*)f -zbyZN}39OX3Q6!#>xGeT%MeDMxUo8-+A3aI^`q=TC`|P9U6Qfj2sF#nKNB7xJ%_mMh -zpvTXO=7|CGoJ(cD@{B$ta<{p-$IrR{z294Zh^ar=^3~U(`$tjtkFCuQ>W`ll&BFuc -z{7Yqyq#<$^%U;6GKj$9Y@11d&X?>-o`D@WVJnGJ|M(-D?rY9-=F>~>y!1knpIE($O -zV6qu%m!=dZi{zNhLYQPsJb`%$6Gh_5qBJJmsH*~lX-r_Hgb7MKfx$E;-=MC_A~_~- -zk%S3KJb}S9Cc-@`Ce#a0QV$<9|E$lx@Bw1sJpIQ@xQZTe-*d5jFL>4;6uGBe+=O#Q -zWBR@PL54rva>Ft6t$p_V2Z{Xodfi8&IX7S)cd2Z5(vbHNmba9fcFsM%-+TTQ=KP@+ -z>(`=tV$^+|b>l<&#*akv-2wB^OM%}c4V@oholCh9J!0U6SfJXo`EbkZuSNHmf1N)C -z*#MZNPNH-xx+*B~q&*`hDDed55hkdsQh+c~bX8E|39OVbQ6!!eAWRfp6_j`aD -z)K#&_F@cLDOi -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 -zk1#=%Nxd8sSgB&7Vsfo9fy$&a -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 -z^SHQsV8eyw9!*gye_}CR -zU6(yy@8Nz%GWGdU_nL4&_cxMgUJ@|B$0n#cZM=+janndbmSvy@#7aGBMbfs-XIHM9vbMXnib<4XTUHe83-k6PhQza@#LC4tBv*#xy$8=pzLxLlH1lpnR0nW&F-MAK56 -zXk8!1Hq^ytw)Z3>zhjxx`B5uoqAu&Yy#-T45g&_zu5$JTpRazTwDB{s45u`rfZ7qh+N;%+D7hCTH{?MjnFWl*6l3qrDC`L6y`Cy+>KhUciWbx-e$X -zkM_2)n7xn@`xb;TLtU)T)02!evdoROvA))xr1`Nh20s8!y0}-^1T{$;AHODGety%; -zZtu3(!i(74`q=nOji(dTL0x?O5f}F+$)%HBn2o -z#ICY{*~Maq8)DxKq9m-krB*01ny42}hTj$U -zy;DIwtR)uqExg#zJwXx+v4HtEEVg{x$6Lgr6=7_7Lu?-p8=7?SeJw7o2R1yl#KXNv -zGV7;Bi!Q^4Cu)Tvvx)lb`wf{2>Rv5zYIVTe0yo1Kgv|R{?DF>;8p7D+hFIC3VZ$4A -z@v>ts&POt%ufTnsWtq`=QTH#y{oId9B7b$j{2H5}NL{?_h>LrhWa{%6vFv08HA+h~ -zud<2mWnnC@Ay!7ZxYtQ$WnR>6Gf_p_ZtwZ&A#*c}nH#$7&C5NUhh)y@Mcv!N{oIWt -zv2j(ve3(s8yL9out1j*c88Dql-%Tx}EGE5cZLLo9HlCu#0vnby3hyDHqz -zjUb8Ws(|?@i_L22vPYMBxE7MxoX3a(rh=NSC8DbXW{OQvj4mEH>f%n4aYLd`aNAAP -z_1bRli0ProD=apsAvW{Xo@C@BmKl*3wZff_B#E5Wfygm7K^@k`XC85JZ;{OIJVu;( -zvVyurOEj&riPmLdY)V6HCh6i{Bbh~cQLD{F-L38Ro}M0xyuo4{8oKOF%RL-TGN<#R -zR=Cp}NJ76V5IMvqsGYjF=T#R+l5s;ronYN!qVlwaezi@st_WkL4KdG=o@6AzGA(&g -zE8OXDk_fE|M2@gnaYL6qw9LablZ+*g5j{)=HA_o`RtF+2Y=Uan#XUz|97Dzp@jAh3 -zH&KJM-QJ1QLy?0lmemlm!JVFEnTdJPUbxd+NMiQtKm0hdW9#bMm6STf+U^7?S9J+r?4ZZtpg|hufqjs#e>? -z-cFX;RvL)JNhS$Dd_G{ABHd)%AWjWMj+wH -zF23(o7xyZ>l1$)dVUI^iVxc}@-UoYpTrU*qO;mW$KYahf9;>zSeQp=`H0&XJ3vGry -zf+TTjdBEHSdt9y)itHxph8ruC0K*>hbn&t`T-+CA+@Px!+)tP&65cZxgv>9q*oXD8 -zvX-8t`3lRdoEmjM9`5I~B+usWYQ5cKV -z$I2)d*GI+;*|mb(Xrgv$yS+0CLgu|J)(G#JS9&;}WLl?2-Rr{r+)9$zs1KMM*#xyw -z7Z0?!xEL8X%&HaKYfV&>mWZygiEdpOYp;(5ntPJwILpMQM%^1s6r=6-#tK5_11y%P -z@3KcrJzSDxMoeYInQvB5+qFc_nn2_~*#tFL7oYiti~F368y3_G)+bEVVR+A65Q;ci -z?1TE)%$A;Ha?$H1{MUF_sagMy(r6RJ*p@D-?tx`&ler -z-(?S#dboa)nK+dZZEsdk4lOZzO(60To1hlx;2~Hi5-Va%Hw -z?S+4UO}coW-b7t!i1p14_j8kU@xJ9Is-&UI-cMFg-uhTyxry?^e;%%&C@oP1FTXI1 -zU9Tmo%57rNn-x^ImZ&lW%uB-kToy?TFNhZXv8^d?C`q*9)U7&Vc<;uG{oF?+F?@Nz -z{3(ldRCR6i6%aS>4|E -zb3^7Ji+x!a8!y7D!P@w~H(lIA7dCg<7q0PecaY5F{?^M$^V=*lxiDHZ&qU>Vqwk9Q -zUaz2D(-8|V!-g)BSXde`_rZqir-sb$v)J8rv3*xy!>ixGu;D4p!%ZL=etNWsgPXw{ -zgrdbJYRmTruv@nqa!t{2=Z -zO_W>L?LD6xGKW|!QWq=p_9V^QS!TxcsC#L+pL?GqHZBX8KV}ouDQ!IPu8SK@GOg1Y -zG4Of?)vO~nF1Ly9jbW^_E*3c1lQcV6X7lu@d%1~ff;ZH;Av4Ef?eLx%^KcVMCN@3l -zE)Dl{T_h1*9xz{E6I8!89`L%j>&UoaP`zMXVxqR|h@53M(fVWS9(ZZOF#n$CzbU#p<@>WHRgfyg-)J6ac;$+)<2WZbZ! -zUa+n-Q73fW-qX3ENRY)Y*2QLedyo)KXx$jbxVo6b3>8yEY=3^nK2KSLo&kj -zs1@!sL=vIpfk+pdpc2}+$Lr#*C*y{!dZBlTiE`+O*~@HV?~`F{PhHFgclrX$?4KU( -zg**M2BxWxUL_TA&Gw_Dm;Ngan3^tt+ZLd{O4LX8Z7KnVpVpLts#<;j_GH%#ZFZ8Z7 -zQEj?zZ&z+85@NCLx|j{_bUVw;nI7$hJNhY9H^E}|sf^gSHjLS)MSCx@3Cde5^l~g_&x`iP*#u>; -z6?#{gC<@+<=Z4Jpo2X5?ZtsotLa*LLb?b=X@T1{i1@#A#sTunz)WFX*5yMvp%*UQ< -ziW}xO2t|*WD5H)TUi_x)9rW-2r*Gi9;Hs++vEZs_wDIw6F7B5k^Zukyw}?d#gt1%d -zWBZ~XaMhCN14519|L*wBVp*%PqGA(F^n88Cm#Ca62L@v^sF -z+%mAZL2y4}qSon%{8F3f-Wta8YGY+@^(4(C%d9Mjy0s>1g^p-m88G*68wDG`OE^ZOYY%XBL09irlbwqTfO>`4sjHrzTPPjOX -zj2nms!M)f-Rq49DvAmF3WU)cDUG|(+9_|5>8Bq|m{yf~z9VCgIm4V1#*#vdFHa_!h -z7q=8FZV;@Gn5eZnBB#_QTDOL=DYdbgZ}lW2ud>Xdf~Zw%qL%B3rj>z64~uQ6?Xowm -z_He67=5zrg&OBN{;X0zJG!XfYO;AI%anGABZXQ_NAXpzZQ97uL^Fooou~=zs%=30n -zGV(ghv=l_GaHnpP(3b`xeQbit*2X<=xwwTSV<})n4_QH#>xj@wn`kA%SY>U@bHc^x -z$+)4iL9i}1QG~ABE98YDNfyhh?Xu5a<>BU%%*29dFWl*2l9;_R5P{F>6m8u0wu@U1 -z7B>jJkC>xgWw3&1uhvAB>Ii0KAkxcXn`*o4%xVu;PBL8u -zjA%PrK~?GqrZf)7 -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 -zXqqh}!|>8-`gljM$S4Ffm3n9U9DnF$ -z-ZBg?uBID1g84?_yr#0;**@DJ8p#X8@XBhsy(2i=D0FEm4bJuw|LmLjiNo-$YTD5e -zyxl0A)x=jhiTnJsNAmlJ;ft&3qaDG!jlyS|_!=iM$Isl%W5e*mYPz8#m}e9|(ZtJ~ -z#B4t^lJ6RZZ>px-I)bx|LP!(Gwr<$>)tsB~Nj3ByU+@E?uvZhmtcmZ`#7)k`bbr-E -z{^U)#cNp#+f_q2c-odz`hQ3fkU#O-pIOvicbV&_eQcagQXzvc%TSI%RX|IE}@1QAP -zkTVL6n&O}OtFrkUYv^uYFmALgaVBo{4^uFt#`E)s;)fmdUA~~xXn8|ZyxEyO#lI_?e}5?crGp;q -z3+^yl4rz*?aW>xJUpSthJQUySpmTk}TBGH4O|jM4IN852n?EuX|JXr~^95ftT8?On -zacAS5{!`=m^+WL!4*FhS@OMT_i>A2J**L|2Dx2qr;+Gxt4Zh&7jh2I&wqH2Q@9^i3 -z=SL64cRJ`heZk)vEw5?XDxBq${rTB^{ZRZv2R+Ic{Eg87M$2(c -zo7LGl*}pNHZykzvI_Mlc>D*`Jfm?;eVO;Gl2u -z1z#`+vM -zKI3e^!>=FD7YxN49CV&9SZ5So*Hl`a?UVibY`$eE&N=98UvQUEIHIYbLS2&5u{@L05{-O982R+6Y+-Vd@P5fCWai^ad&tpSz%0UI!!)OU=iZN%l`h#5kLH_^#gWO4!_^WQ_=M2LqRnvPq -zf>VsbMWZmrD15AmuXZNx^H+`Jw~gbsjpDcE@Y`^%Rj -z9RB^m_?I>Gx4z)tjh0_)ijB_3ss4o%_{oFuy*2coe8ImMEx*weuX8p|^DoTdj||2? -zuA#%eV2{yKqbXkNY|Qnan!v9gjGw5XKl25@FgJs96vL%-(>eqpq{plN%;Sw795pTpM=#y_l~zw!nDX0%jm+8%e7 -z=lYu`@GA%7$7|?Me8Edb%PvjZdS`i_zd46LKNyeH(7nE3pV6{i(`IybPW5k`z|Rw%Jnx*;1>)2y>nKczbS`5Js7`O -zLtpj+rT<2_`=GW)&ErW5chK~4xy+)x% -zQ@PgJp6d@y;4Opkwi>$A7mON(-I~e`&h|WiD2EpY)i^}b-6(ejuxQQ)td#NSv=Px1x-tSSEEN1vY&tLa-if=i5+uQkPwIJ0N?hmYZF -zvhdq?&?7s7KQ~(bqAAuovy1$@M)U9ne+PY6M{t$V@{Oi=ku$s4ziSNteinYq4tj7$ -z@FAn+3r+FE&c=KE3rF*lv+(6R=-iIrqejamP4Pl!;|%}8G5nD%{O%p}xQ^f>MhmYg -z);SxC{HI3q>$7lt2YqixaE;L-Xo?p*8;kv?#_)U=K6D3tLr3sIqvdl=+s~cl_xSTi -z^P{tH-46QBj^Hw*C9G+C#92PWpFf7L&%*O|(4#tnTBGGFO`FzPUgU2c&9BVD%{%C# -zj$oP564kUVa+VkSo5%3yv+(R4^ze@0e52({P20oH&U^eDNAokX@bVpWen)Vn(Gt>*= -zEgiv!jly3vm0IVlB7f6peo+>_VF!J8M{u=K_(oH?$T_Rn-!z6lorRCtK@aT+&NB*M -zXeu9ew%_B|kLC-q@X{T0UPo|+QMjb3Tmgh1fT1mjlSTUM$0>z;;qi?Tm8Gn^7Dt_w>#*i -zzTh#V#ic2>IkRu~?;6LyKLlUvpr7#t-!WR=)f8`YHvZJVa4bK02!4x$e%Kd$)o6KJ -zQ@q95c$%ayH)TKQ)$LKLo$qL9g}&-!NKQHN}Lp@pk{I -zaXdc+#~t(*U+`U{<)o(A?kxYQKYuJgdI&z$LC^CA4;d|QY1)42EWgd4KaQ^-g6kag -zI$!W@qlMPAZFQF4>Te#)uN;EsIp`I>;Oj<<>_f}0(*)fe;_EsUmZ -zo3rz${*7b#8AI@F2fff2JYuw*(6nuFcHZXSIF4@}f|on!jlN*3(bBGIt8#YU>W_}) -zHxI#QIcU8v*kZJ_Y1#;9=k5OJI6gK6CmeK@FL=^u@oL)a&RIY8=Zxh?48aFE=()b& -zL8I`drt+80S-1If#__v{;0qk|T3_%jqwtQVa;tOJt^TI5{GuWF6bHTB7kteqxHOeE -z=d9cPP2>2}L+}j_8utZhqwub#a+|aLr+)odzF-JG#zE_RLDDF^t*PANY`@K~AIG;0 -z!Al*q*%x#h1&^k(%GrLaKQxxN48e;Xbh$6sY!q5Gm4vhXc7JFbFATve9W>z!GDhK~ -zrqb>te(Ik+mY+BT&vMWUe8Iy;;Vn)4mrmj~|Lk%6{vr5c2fe`;JYf`QO?<19xYf^$ -z<*^}np@S~<1&3md$S)!*83!CvWDHWBKGy_~ZmW -z`C~pgo==YElN0&mNdDvy+~A-$`GUXF#5X##$MPqK;ujqB14hB2DgF=t@VlP=`(?Y) -z@?VDzs3=S&ePhw$UCOb_8>Te{ayPk~+_bhhXo}96Q?xb9v9*h{yi#*pPjK?{#Ctg -z(?RR%Q$vO4y}7&8;4yaMZ0UCSRK0D>L96}LP|^99a(BHSJod*EXVbRJFV@>`Iyk!O -z)P}7Z9X`<=G2Cw^H1dNdNX+J_b1NI+%CUVZ@c;6=;~9a -z3(wz~yXzOhW4}Fdwqm>dTD{GGaMXV4bkX_qxw}3I9{cRX*_7?_3-z%Z54Nm2Rabbv -zBzIRRc)u%2Lp5K$ZYdm<2pEz5! -zU4Fej=07-TKXsw#{HM9Qrh~^Woj9Ak-T3?Zz>Np(t4>uGp3lqO)f+r^;>6j4?Z!XU -z2W~lNUvsLm==^Z*u9t(y-am0RYrFBQ`oN}x_SL5j6`tRiyX(o|u{TegE!%FKst;^A -zXt$p_RCNBe++808k9~6DZ2ETN#rnWa2gg^PB8BIr++E?|v56CBi?8AGrD8`07)<@VuP6D;7L9dE#v4cH_1BfdAmQ{S+@cZ{+Su -z1dmOhIGeiNc%eRV*?UJ_=&UD?Z)Z)#Fm3?_EX1;&cBnp>!aYY#EG++ -z+l>?TiJJ~iuR682@ch22^ZN?Uug%@{c<|WkC(c^78{zGSf4dRiZrHXP6ZMJ7`owsB -zV!A%jTc3EjKJjFI;)D7`xIPiT657?)liZzLSP!>OKD+b({jY85vFYjNcdohl_*Yh+ -z={4rV4Y*dF?lfxQK73A{?l2a@ZMaXJ?lP9beoRR_aXFtjXosHewWN_7=?i+g&yqr} -zqlzB%S~AF2>F@NQ&yq}<==XJx*OE?dp-lJqEUDxx^ym6XuO*Xwjs8(T=?f3F$wqoiKj#f+ -zl5O-e{hZIAM4U9J7km9_W93641O#9KtJRQBy$f9>%<#K=bLF9+jEM>q!yj=+mNqO*h_?{9Pk&>Ys3zg0zM(XaNU1Q0%aw^iDF^-rpHU`;rA+t{KA=ntN%`Onuhb4{GvOJ0RjD1(QeXg=C}V?KHavw-DPzN020V)QDq}-h -z9squ*jE!i?(1Ybl>!6kePvE0U>#&v%593y)bx6yFXYp;Nbwo>rVO*n34Qe@{At+PB -zS|&V(4=PhbT0T67pDR-%auRf4hGHF*XMln|igj2{gYTnPu@1>I;ph00VjYoFpdS|~ -zql0ob{1l&1Mu+7Lcm(fMMu+4)IELqy(GfWrf>@%o49Zz>7#~(zE; -zdc{`zhj;!LVCoQ<{vwzzeem8#&nKR@Pw$_;GJ5XY_oc%D+@iD$$+>V8-%?seg98!=L01lKClgGLTKjn665!$u}Nj{B79AtN82$ID92titJaG?}Hl -zETv=?b+UA~rGm_$b6L=3DJP|LI}5rkRV0lTFptYpMrPBSn8$6YBs1wUcG6|Bk_vi1 -zJL$GmlN6f8YFyz`Qb@07HSTZ)$)=0hVOO}El+%0IVRyKSWY99U!xb(gCG=Ld!yT?9 -zd2}^9=L%a%75xr7=MGnsWSY*3UH(#1Ks~J3?XMtNw1ypU`O8Te-N6pH{Z%BL7PHMR -ze;FyJo7rZ!zmnwA26o2fw~|V_o1Jm{t4S)&Weu))DJh~GSc5xWL2_svJL-y;6D!@x -zj=JMjB$HOM-L7~Uu~5QxyW^E4pEk0KuDF#{)4lAXJ6_F`Xe!Hf*-H5=>SnoaTLqs% -z=d&S~t(=$AJJ^uhR>jk35!>LhmGRm1X12j?tK>833U=CMv+@eMi=B4cs(A{{VRf!p -zDKDhWtj-;);Mug69dX6Vc{y!mN8GV0o5f(MJZfhbTrn%JqHXMg -zJ66q;X(p?51xk4V^|4BKpn_-7h3t?kP|nNfUF?uMP{q@!g%MYvj2BZsBkn*Y&!slT -zT>&evqyfg=foh&g^I4-SQOb+x4Xn|fsNgwtDLd{;lyfV+j~#a>s(2=?W_w+UGH#)_ -zvAym@CC{hp*d+c1Cl0q*X8rUD2GNbPd$wi_x53 -z=~|e9^P-_{X*n#yXf)I#t$|X!JsJv1D`6GB7Y+4FYatB_qs`sYGPnvKiZ=I1t6?^7 -ziZ%zO2Dk>_h&K01jW83JM<=?a6>v2^6P@Uh>`;LZL??oh4X(wHqZ7T-I!M9nXl=Jv -z5A$#!THB+ofmv4 -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 -zZ~uL<(D^&ZKh4|KzWT+;fA=BmkKK -zv{3*OfXo1r1Rw#(3?Nwm5`fGAsuF+%ATxlr2|xmn89-|VAOXk>pnU?60AvPGvH&Ci -znE~V!fCL~jfRZk+`zyN?GfCWP_!qm?@QVK5y&e1~vjiYpi%)y0QwI=t7E;Dj-w_X4~0GvF%K3JNu7qXNA0$KFy9h6D8bEKVo|wi2}ZmKF;m?aeHqWyY}H=IT`(O2{uUpR%V -zr$5yXd&3!IEB(EG*cVPFUiyf>!y8T~Tj+1~9lmfX*+`G+=e*%evWXh*NCC -z`-^SEds;v4O=R#E`jLLzmq_M5`nbN=n@Hz=`mVm$mq_I|(C76_-b5z9jb72y7X>d> -zLp!D@IfK#+h+wCZGc2XS_t2%}3`sNLXZWI$Ga{uxAI?)kgHks91fxo5SjvEdc)JoB -zlJem1@I56oA|*pN7AnnyQWpFeA5xl!rF8fqZc>_uq+Ix0d_!p-ky2q0mn##4QV#qL -zKBG(wOPTN^d_b8PlJen~_^~oEq9s8mW-GOW+6;)|fKofGrNKkEUa1|@X2LW0s!}_m -zrN96#QN{+fY%Ro -z>yVZU&*Ixk>xh;L!(#2dskQevmW#FbV(q<&wfB*kV(q9Qy=@ubKnHtn`KtoWbhP6z1 -z3?EdchO~Tm4nJ3>M&u;uzzoGYD9-=|dlc)ioCe=VuVNjNXTs0%CB-@-r$9e0P(}yk -zZ1^cYp^Og88Sn_+sf-TEd2kHRE2ATFG6bhH#}aIVk7A5qwse9F{ZT5bjYXhva-Xj-M)%BSsQ*VV+_iG-iN`!-{>_NP{2X -zM#Vm4%!FUyYl?luNP!Sa%J`s>4P&S&vP)hHd+}4%-fqkRH|DAKPGb?=fy1i3!?+4=#*M1I%eWeL;cM!6 -zyD<-%QBub{jU~{EnmXQLEPxi2)$uMvf;KeNwsvDK_^?Vfcevx%e=iPq=zqOmBwl&C -zdH?zSZ7;lc*X8~EAM?&m_RALF_-SM^Bv->F%!}Cjj9G93ha>g@qZHo9jS+jlF&o~* -z*CO_iQ30Qz6dCU`3Sk1Z$oPO!4pS&c#`}#Dm_#Eo9x|$68ml60eMSMijE|WbO$}l+ -z{nd`9m2{F_aKwtZM90|$XUxLa(rH%d2+ZPhX)mjE24?eR^ksI)5h&z~>67e`Gf=`; -z(+?PN1PXW!4Kv~l6!QieXWS7e;&n8}xHDkkjWod;9f?_dJ{@6=rW*CV+r?o;6i4&_ -z<7mDgx2bJiMjZt39d)|hm=8DLT6Mb9sD=CRId!_jSO~Y_K6SdwSPJ_w<<~EX-?P8s -z-!oqW93641O#9KtJRQ -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 -zUO;`U(jBPaS#%*gfMoL=c#n1S=6p>An8 -zEW&6s)FZ8dQoKDH3Q8+s6}}e@^-60Y4GW{q-O@6+3LlC#_eiT@Hg1YG2c-tM2H%J_ -z_eza06PHIPx}_CxH9ixa=#lJDfe%C{f|3oc#gC&Cz0x{J!R%;lw^k4Ha3EUSqpgBM -zTpz6sYS+MWd^K9zt6dA(xFkB(tu2Qo_*8VPM_U8scyDwpsI7!G_+fOcS6d4iSRQTd -z)|SBnd^FnHqpgM#+!}2SY7MXw-;TESYK@SGYob%#+6s^mqEkJZ9jfrb=u}X%!CL%0 -zI@PPKgJjHzTD#?Xn2SA8YmdAN3eX$12IXsD8NL*?_R7~n7A}a6cFW6QF+LF;?UC0& -z8QvKk4azHFHJ*=-_R4D^9ZRAu-SRT1!H1(QJ@RTO#x2p7pxgir_*S%~S8jw{Tp6A0 -zmRCR>J{z6vk?l~4d!my;*#?dHX>_tzUI(d|7qxdA^)MfYqxK$S6%^sds6A+011s>g -zsJ+*?7IILEj&~c&p%%61c#p9LtSCpvgT_j*qY)kNHP%8VRz=&ojb*S9AB(p27^}g8 -z+oEkjqXBIAPPDDpXoP%R8=dYpR=`qxE;`*~*r6KtMW=&?4c6i1=yb32_qG3gMNeGOE$TiZr6hzOCI?)EzmtpmMroOdXw()SaJ!a%k+~?mK^d; -zdcS_sW63AqrCEASQ+NisonEikc)~Nu19Y)|xG9`X?xpwWhdtpu@*pkKcQl2w$er|7 -zeTOHUOZL#!`njfX4w311^mCqYKG{dp_2MS~46>bi^kR>HCb^&1=m(no+2kI&LqFj0 -z=aKKwVtsRyKa1?3oAu2ee=gZg8}u_x{v5KC?$*zE{P|=r&D9&4;xot{bc5dDiO(dv -zXq|qvDV|MQ=}!HqC!R;zXr;cpDV{~{qD0^AiRY34ZPYI|#dFAgbgzEV6VE66X{w&v -zWShaiPThL0$2OCHi_X`FnrzwpZhD74%CVzm|>PMPl+5BGGsvq&h^7w<)s_$%yW$`;{ -zi@wtn%jJ8hUBA#2%i%I@(=T{p`FtPE)GM0;Gx&Du(&0Fbx`f*PpkGIikeQ#4Di{C|W)AxE3xjaDE>6e-kIs87lU%%u@D!?Ve9`U*Sj2p5ti^r!5wGh9N} -z(BHEij&K24Kp$Z{oZ(`!lKz&RbA*eCM31p^&aj27rJu24hkq8COM|S~>7PxO(Ua_e -z!(T`i)5Gk5(_cbX({pUI!(TvZ=mECb=`SV?^b9-W@E4IfdX$}U`Yoi9USti9_$)G? -z4zUJjd^TA@PqU+rcp<5!N7zwkyoA{41-9D}FCYu)A-3BYFD5q1*+oaZh%BYY*+pmE -zLe|ksEZ1S1#plp2mg}_5=JoUh8*4GvoYzl#2VZE)I(`8D)S -zcG_Vp;#bpOu+vVPg)$d}MDcElMg;cMs=+v$iE -z@C9^~?R3V9`ARy;E;wRET%zObf-`2}Yw0wrbOdJcxwMy6Is>!$GWs$*#b -z$QdZ%tLX=fI06N{hK3n&28wwDjWg~D6!AJ5W84|A@J5r*o|+glkM_+*nlh5$xgWzcH*<@WQV*E -z2<}lQyX2*?7e7_)?ZzB%W1ed7G#0@fIIP+`jH}>g+^E{SjH_W6zNU`18}pzUC3U>h -zSOTr6spB2S0%$>59q%$EXhTD7`(i@SFGUCvA;?q+8WADrOS<>|3kpHWA_R#LWF`d7 -z7a>T5ATuFop$I`D1epmzuZs{QLXepdbejl4A_SQULC=X0Btnpx6G7hoPl``|#3w%{ -zKKc1muQ=%;PI^3vk11`#MmmIXo6waEB@Q4UimN5=b&61eiavsK^x`=q3#_PSr}{Ld?fV$}~iZon`8+vuQCjbdRW&m9$00}^50R4jiBmkKKv`7FFfXo2; -zi2x)3nE`aS03-mJ0fYjO0AvPGsQ@GZnE`ZA01|-A0Q#x`BmkKK^cw+405St;l>j6F -znE~{70+0Y?2GF+!AOXk>pg##f0+1O%X#$V{WCl>T03-mJ0n{V_2|#85{Yn55fXo28 -zN&pgo%mDha0QBVnG_~%7Pk)v+VRpN{MBiW|noPi)Ec+S*M9hr5x+Uvd%Bh -zqf!q4;#Vo&B9?W2nU-}uR0oDS(KxDj1yPM35wd<$PxL+#Q$xDMy3p-yQD+>KE+)FCZ^ -zuj1`$s7sRI+xVW^+%C<9CM;B&JEg_&4SYy#?vQHW7TlyZcS&_X@eOsNU78PH!R6{i -zr&J5y#Anor4rw8L4IfY^x}>G>UHn+BZP(_23$xYQPHhp~jst3KhjtZg!u4uxmv%Kg -zfUl}!?bZ>v-7+I(@lxT)L4e=IH^6PJ&fxqR$8aru}CL8d}bl?Xv11epmz -zsUif45M(92*RO~WBtlTzfKdh?;I>FxzflZvd?(TtGAbc~Ya`QrMiIP@ -z&qbyO3@dzu`y$i*h6Ucm%aQ4jQ4L9th!7+~keLwlj0iy+ag93FsnvpvpiXsY3t<~R -zs7`fhOJN^=u3FpWIpD+$)!Hd9g6-I&T07*c;3o8{)-L&KxF26qN89Cja6K+iM?2*u -za1TDAj&{gjj$7!zAwrM{L1seGKZp}SA_SQVL6sr|i4bHa1Z9d4Btnpx5VTQ*AQ6Jh -zgrKj95F|p7nGkeLgdh=u%!HtiMF2V?Nw~ -zYt`vaqZaPN=hW#AVqLeQ1{#`GT_ -zxpL|K{ztBao7>y6SdA-ON($-qti~O#AlY;=JM0RVlX7|wJM0cukqlbKcDTZ2q=eqe -zcDTcpB#*9U=UibcsiNOu=iK3Hl1$TCvCCgd3aEz_yZsd;i`K9ME`K>GqdV9Ex4(*{ -z(_*&SF*^xvaqzFC|5E18Z={D@YElV@F-_ -za$==B*->}Aie%DCCZdp;C=^NhLZVP&UF?^a_D>(bbm7YL!%Np1HIDEsGLQDN8fSPm -zSx#SJhaKTUvV{JW9d?FG$Qt^4w!;xFAPeXtY=<*kOjgq0vU84b5s~OIcFq~LkhSzP -zR_yT4B6Dew6+8X2$ufG99dP&y$zpn#9dPrq=BAcXB_?_ -zQb&)nGfuySG}4Q#!4aQD=F=h8;Ec~EE9hx<)DbTvwe$!(>Wr5VJH5bmJK_c6>DtuO -zb@uJzyuEnMYU1g7_KTPEiGz0N>0V13xskr0r~51^Rfy~Z0(Bb(?edW|ofLe|rt>W97I -z46>E}UO(&$ClfDyMBm{Jr;{!8xB3oWIF)Rq$MkdFa3{-`BTXTdQ?B-^=A@7FY0G} -z@g(A=LwbWZoqUcN@q$>qU}EvY -zjcH%d({(jTq2h^}&!#uC4Q^W{pGjA+(=MBpSI}MTwA)tAQ)mvWbHz$|A#G-L?pOuS -zrnT&dD^||SX)8P8j#cptYGpfJu`*slTi8x_tdi$ZJG1+$~I-C8}&!+~gRkG2X5aecHl -zs9gig@zrQ;uXZhD+A8!> -zdf>AwXMXUNUpM^zs{H>Spp^<};(flE_xbmW_xa*|zM1#=h2nj_c%N_PeSVF2pZ}M7 -zpMT|p4{!L$avki(x75jYc|L5wmFi@tTnjt#S#`2Q -zUI+yDsFPjtQrL^1s`hqc4!AK-wRake;0_#C?H$Hda5HXH?On#zunS*P$J>p0(2SBg -z-f1j>R@Bt-4r2kdpsbE}84|Rip|-UfbHRsIs<~wiKNRukFY{{l@&_+|@UQnhAHMd3 -zD^I`QGMv~FY3Y}X;S9bNX$i@da1mEVCi~3^DUE5GOt16BQuum0 -zrXTUfGWb?Hr62LdlDU_T>N~x$biRd7>N|b0RKAgp>leJSOumgy>lb{1B<`fWdZjmz -z#&4o8>y^Gh3csE{sUPwNGWf0Z1O1RMkjyCUs7=Ne8tn0b*C!YBS{;E~pJ> -zlWQtL*%06wc5r+M(6$;JTklH0>-Jjx{`U6n8-{*<(b6CAS#|dQ?tPx~$;oYh^EaW7 -z|6<;4Eg%b^how5LC1f=`&juXUBC-rLHsG|Dl8x{V^Ej-9!5J&z -zYvF71CiEjW<5*Z63o9`e_LtA$SXg7XH=auTz>VF$crv*Zjv8mY@pN(noHx$+Yzf=} -zeMYX=mclQCUmLkTTN3{UM2vB-Esb9d?-}DhTOx0Uhm7rBTPpt+{KnYsvnBIy!c)d^ -zuPvQl2cH_peX#`Yf}qjhjivA_;A`_H^z9=!78b|CN{odyvT!UcetlEo>zm<5JomtJ -z51Dh1N<8<#a}Swwk0W^Qf#)7F=N_jq1mU@d%(==kba$%G)l5QHH}<^rr3#t?)d -zNG1ejVhF+zBol(xVFK1lceIVF;25LA4lyFa*hjpl2`yVF;25LFX|9VF;25 -zL7!s?!Vn}Af^skfeZe80&XV+Xu~!v{>xW?E~g|x=y^R+lS08 -zG+QY8bicWl){CeQTO3&p)YDhJ-_Qr@#N=kf5hg`&NtTo`K_=12cXM(@wV$1a@+O%2QU1j -z=Ck=dpZt~5%*StKK|MR#-GM5e2}{`lSD=EI!)@$F -z+!d(g)evCZ9jN8Wkk6W2b7frW6D~I{!(RPG_Ua2CyfXLs+kv$GbDz(5efv9>x7x(Pk&qbb3JS(Pqche0o%z)n+Hn2R6orsvQXzjp_&f -zKQo4obUpa;pO$VqeDBmlpZ9isxjtfFhTksxVt&K4wh8sv{O`|ikIYZMJs+F@=&E<0 -zZ53BV+WOQ6x?8*vneA2=)9qqIWVTnWr=8+RWVT0LN{QGLne9_o(Y@kq#NKT#pl*>D -zvG>g$aIgngtiGaGTmn? -zv`d(gu5NQ7^@*BDms~A)2?xpGAek%SHKWNlm&9A(=f+X*TpDkKkBppy=ntj4dp$~~2ntj~Np-+idHT$HQM1w-nrpL@IIwhjo^n{s4_X|~<9yjyov@o^l -zNi&fSi5jhI%#^w|vbqSbjo`HriEAS_mf$k{i(H25Z3Ai}{VGT9+c9!u+1k5nm2JWe1#rQoad3V8jt9g7=k1Q -z$*eBK5QHH}CIl5>2*MB~@&3?rw_pgu5F`_VmSYIQ5F`_VuEY?8AxP%^p~o-;VF;25 -zLEpp>gds>O1mTS!3_(&Ms2D>Kh9H>`REi-8Ly$}ex(h=Ph9H>`v`v`^gf0l3_&s>=$|nJVF;25L099AAPhk=A?Ozc7=kba$%LRn3_%!zWJ1tR3_%!z -zWI|9Kh9C?*1Vn+86k84Hmi@2MghTO=`bZh5I$!ugUD!QgOeA`!$*U+9kMO!~L4feytVv -zYq(#N*{@CEe(kHVU;DC-@_6G$9OZ$dJS0YW{Npj4>54O5C1$!_Jy+|$a4tOmyW{hL -z`5QjH;nZJ0YL-E61gDYevF4EPz(Ql7*_uUehntK6k2Q~c7YYqevo(|40+$;ek2RM7 -ztTB!?TeHbsaJO;HW6dYugG{5YIg~+m!o^0NCzM0(f#t@*=1>;76Yek$dO~^RJ}5WZ -zn?sr8R=CD!_k?oE9@u1@Yz}1;749`odP4c+en>Se&HfB>6L<`Z$Dc#)hB{+kvp^4q#{P|=r6HCG|%SknYds|2U_=R{JmWTb}#F{5D8r -zsV-|7DF7!+bz7@Q1}tO)E^7rTgPYiZ+gd|Xppbc7)^bt;motysT1|3b4LjztR+1{X -zn;mmoYe^DhvN~6&j1|=%3Q;l^A}mBQg~*GA2n&%+A=-|G2n&%+A=;0H2n&(Ss~tzM5Md#bDMWW+ -zA;Ll=Q;2?xSB3DZkknP7YP>3hSA}G*3Z-KR!Vn}Af_7jC!Vn}Af(V8n3_&s>Xc|Kh -zh9H>`bQVJph9H>`^d}5K7=oli&=7w02fz9w@ztMS)M5z25F`s0u^Smox-DuuILicQ1Rh)KlO7AEyd+ -z##_`K^K~}|uIjkuf#-ies#em|Vo!K>M72^b&W2}$YAro4^1}9Evw;3uOoZ*DW*L1? -z>#az8@{|e)Nx@!}p`{{b-5zqc@J= -zp$8s%NE~{6Ckqcf@X$l%&|^Iwdf=gl%%Mj)9(v%Rhs>eJQ+VishaNJA9v@%`!b1<4 -zLyuQ61Yro02|?Fk2*MB~6M}v}Ckz-C -zuRn!c4#y0O&!0pthJ(gFuRo1k11F7rK7S(dz&@kZ>rW-EaKdQy`IE_ZIBcBo`qK%4 -zGsX#DJb}1j+-UU1Q^=KY+-UU0lSm63G7fv=X`~HK8;5=IMB>BUncVJd5|8Qem|o(T -z{?7@xJHy?X%)}B1^CDkFKVR#He0B7~M#V#3g$DKy*D_D_+s-hoW0( -zmRO-r^+(sz72NYp~#5O0P%g3)SvR%{NR8pdOKsbl&}@t7Wu>1B@T -zAKi(AJH8BqJ5JBvy(j;w8<%Ayr0ja4^FPiM+V$+<@*6MtZA`qOwN0wYbX;uEX2;ZQ -zdPp46W+&8idO+;aX2;chdQ_a%W+%-A+9&cf`QYL?p2%#Ux{B@3AqYc|ObANH5QHH}CIn4l2*MB~ -z6M}w%AqYc|ObFVFAqYc|%$xP!!w`faNG1gR>nMgG3_&s>C>KKzh9H>`WXBMMAxI_! -z`bU%h53_&s>=r0(8Fa$}3AiNQTAxJ6&&DKnE3tVn^Jl0$Su*NvnY|SQj!QI9&k2Rls4>FCq -z=1>ON2^Sl6o=^_C2bLQLn?qUTPPoH3=n3VK`=H!tZw_UWTj3g`-4n_sdtj4svN@DZ -zRJhkT=?UeN`yth^H2X8iP2e#s9)AwG8|sXG&HgNM2ecdeJpMd#FIbG$W`8DWhgPH2 -zSjbz+o*S -z%RplTPHQRI2=6eD!&*o#f*&xC(`q5>fw5x_YcW{~Pq1T7tCehlk6E1~R6rKN2&;33 -zO2}GxnH_Y5ipUE189V3R=yhb^0x&5l*lZ4u3Ie -zfWz#B({CkBaE3KH;ssSqTj3n5b_5FeLKtGz&OixY123@yjzAG#4nJiFoPkol2|i%N5h&z!5Msm` -zu<%BRGwui!^9G19?hIIY6U?zD$6Ntl43n%$=ES4N^@n-4wTu*ilclNEYyI=WIksm}~5c3LIw(Pst}8{Hy4(f@nT -z>om80MFG8wfT$v6QKJYPwJi>Xn1)Mp`Jm -zdgXw+o~{uu>Xk$47MdxR===NCwRE|7Oy57KZl>kpR(=0~x`A#I@9X=A)U7mClKa-n9@g6i)lJkQuF~5E)JEDU-q72=x`5t6KnSRWuY=dvQO8^nuZN$rqt3ZfZikQ9 -zUdLP^UkX2Ad!2I@ZiBbkdBQk^uAqu7MDc6d+s!As{J0 -zxCTN%Qh;y`gn(oKEy6Vr0+IrRYaj$91qjzb2uKPLu7MDc3?LoXKnO?*5Uzm`kQ5+X -z10f(OK)41%Kr(=K;u;76Nddw&5CW0{glixKBn1f9KnO?%(7U(>LO@c0a1DfjqyXU> -z2mwg}!Zi>Ak^xkNYaj$911Raw^IGRx)z*J(&!JxPAxdDMBL`Y>8m%oe@f`?h$ -z{wk6Qb!?x@UqQ;Do$Yh`Ye*_sSgXrlPAt&MTHXF?k_(OOgv(z^s$n-f;r7>(WXNTW -zu6P+KhV87;9j_wU(7+D6;uWM4I@w`&yoRJhHT%*Gp_;3uXT*l^?66u)kBcMW*-^EU -zo)&w;vm>gNa&b018&qrQd65^k51R$_*J2`UA2rM9dtyh}K4O;8--uVk_MllsKNU)N -zde|(YGa?$E9yKfIDWQg^N6b<>E6nh8(5#{7L`}GB*es+kiAQDLes*MjjDUz02;1$B -zSCf2bVrN|ON>U4Z*%^1dmM1_m%XQhxcmcRsuG?0{Ghi_rciAd<8Qjdq-L@K@0>x~* -z%T~@y;7YdLZL8)vu#O#f*(!Mz>|)2=wpyM9*{s18E8|7b!W!JMDxL-P?2s!~!7HGH -z9s0@w8o^&61SBzk!7+lrKnO?%(8c%*gn*;~;V%#Zk^%HG{sMhT0B!r=?2XB32?+^z -z{pkNp5Blrupw8JNN6#C{_qpO)+oYOI$HfM1c1+Ethr|(Wc0x_32gDw2c3jP;N5xrf -zcG66seIie@kC_=XA|^EZgqcDg5<4{exS2zr60d6ZNi&HCg`!Q5nOSs7M78M&GmY*S -zsy01t=Fw?kYSWWuA{`PnTGyBD -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 -z`#k -zE@&_gH^;L`2Xq>TJ@Gu!1=Ysx=6EK#4T!PZ6VD|9Xfn<;$Fs?|VXtw<6VE3PK(dkB -zY|G#`g4@XT*mC%HV6idYY|G-e!_CIH$Ck&x3&qCvW?Lq|1+Fx5{#Acx-#ON|4~fh>Lp+-4l`1oHU3 -zU^Pf{Ad|O)-yohqF5e9{gEt4Vc_#!6?g`}cy^wD-HP2=6o8eNU$upP3cfl&-X!Bea -z?|^R`M?G_SybEfLz0Gr({5H73*z1|gb5gK&kjN0bt3h!?`yL8XfRSu6?%hm|7wKZPC+jw%&Yh@Ii!h*C;_E8YzU -zgGvqkS5Xvh8CDAE{}2y`TSk>~`oF~$;g%7_LjRX|J=_vhs_DOowc(jzrI`M+crrXQ -zs#MZHiF?8`BZ`&&UVIXs2`aVpFCr^kKO8NfFNo1_{b;m|zAG*X*N;R?=ZdJu5bcPYp+l>8pZ09FS@Tp+5mR=BP -z;mTpPfIcqPwWWWN6ZrX8}Vw` -z9yF`yr$Px&51U1FMnuEYqhnl<#Cs0nusn}zfx@o2bf)GVhT -zi0i{$Bc_GM#arR7pjl1l#Mbb+VY8UNCY}kO8#OEGN8_%evFai^`6Z-n>Qc89HyUjz@a -z?M|D8uZQ2T;|^OfUkOjK<4&8EZ-Gx)gCkbJ7eSCUIAbMzEzGb(j#v?20aNUdGgits -z!ztG3h!yfBu%C50V-~&vX4z>+te7h>%}zUGR=yR^v1&)4fG>n0R_zRw@HOxfJKzWu -z@#XMScEA}Z<(uFGMjU}cUI!sYoB<1OggE1lKrwHC7~{@>l{dj0YjVsL@Wn96nw)bb -zd>y>TjymRwcs=}_9d*u?ayxv)_B!SY`BL}^+v}XOa2veM&O7Fc`6_spop;Vz`8G&= -zbLae!vVb~7QY5=qSw?RZy^-u55;)O`CTUkWEAr?h~y~+xDyU-)S -z9%Tu=TI`Gj`xJ$KSG*f(=~fofW>FMr=~b4~Tf~ErmL8>!eoI^tY3WlMD2Uf1Gu_H! -z`c1JmGSjQn)4Rlzk(nN4DZNhI6Pf8#R?+W?Pa^f*(FN2cvLf}p(Pea}7>)e*mMdYz5mLFphOHo7=k2@&BBW@1Yro0_^gIwDTW{nK{6reRSZEG -zf@DGv!4QNYNG1eP3_)L#k3)S$Ll9sH!Vn}Af&|_O!Vn~NBPba|5QZR`5VRCS5QZR` -z5VQ(I5QZR`5cC#?APhk=A!sj#APhk=A?R}qK^TH$UJd&f3_%!zq(Tth2*MB~6M|MJ -zU30Vs-vxAOM5m^C0 -zV+Wm~QnDHT$l4vDLb3#Y#M+%93)uj_V<#PA$NtNF$3E?*|B^fQ^Sfqlxaz`3&%QtZ{`{GD-+KmMI{feW(&2MAVq(O^D3cf$ -zVq(O^D3ci7PvA?3U&Kp?4{VI3SFTP-NVsw4u74jW^l$&1K0Q=p6w|NGd(k)jE52Bd -zFV;)ESpN({AOs`>=ywPR0m%T`gn$r`44|hG5CW0` -zbT0xzKr(g}8?$>75)%H@{_o?1rcdAY*Z=pNu6{pZSHCk>MG~k*T&1@SsExEyyrH)ZsZBIj -zY|v->)pfK%9MNY7RXeQ~d-T}>)kd4dS$%d$-A0o|o^J0qSJTB}Lbnf^8)>oFq1y+{ -z^>m$hRkshBTWGdW^yz+cEv*+(eR|N`Oe=+|PY;+Is9l))^pLrgri&WAtKVEhm&$yJ -z!?@=!4~V2lcCWIG-Y9w_**(fd^fKX!WcMj6>375nkzlv7h<-yXiUfO=74&wYM}j@d -z5_+}R8430&3jMBlH`3CrETqk%DALlaET^}K2O}*#N*(={xFXWhr!-IyuSaIOmBsX% -zVr^umSE;9Wi6bs*0s7qu;>U*Qh=uR;jsqcwiM6VE+ -zMC$vZE9pJrmB>_gbP>HotcXnYMpw`~#p98wp6C*Kt++EX)fZLhed5DNM|X4~^@@r} -zM{jgFy;VFC>F9~p(W}I@k&eD-1KlIujGXF@F8-n>m|t*zZ2(=CaA6ztuvDkDgsg_= -z*?_}ZM3#ZZ2AtMXvJu{49*4D%Tm(O09;ekp)&pb59M)p85}shkoK`E@0w1$F2Tput -z+nqKGUk|@w#~rp}z7n2d$DKAS-vXbq21l%bFM=RzaK=jbTA0_`CX@u81@-KZD^|fP -zpo1N9$7*;QRI*N2telrZ8|!q(s(BvR*=bj-lGi{NJME6u@ -zCM;zKT!9K+4!5xb?m!Js1uG-2KsmR7pAmPUn&*OzaaW*{S3`htcc7LhLq2PA&6V+D -znHj>jry?L{+(K-?*%?Q?n5=@M?2I#RCEMUU%XQca_yXu-xlUUNUk$%z;|^O9Uj`92 -z?zENijqo1Z?ywc|i{QU4pgIJEfF!1v-)=!b2uKD{BLYG|GJtXs5CW0`)PR5xkPM(| -z1cZQO05u^X1SA6}837?689<8>5CW0`RE&TSkPM)82nYem0Ln%{2uKD{Jpw{NGJq-( -z5CW0`WJf>E{+AQ?az2nYem09uBCz5qbG -z)ciHw%N$9mOK<-72}1wxKd&vBo`2@zGY2o-_e|iEhxN8Wb<@{kj?i;!{xol-Hd`~u -zjo>s=J=PrZ9av}#G+VRC?QoMZ;IZbB??R#BX|`sPTi|lTC@%VGd-B4%jYxZZ6JD}az=ke!}d%p57Zlnnqyh~PUtWWd186|KBzQ0n`4>$R%kOiJ+WNA -z2kge_=2$jYq02b!iRJVAA>F8M4rK6~z-Lr@0y+F{SZW+-4rK8=;5OrcCy>YQ1*<`t -z1DU)X{08v^a`|qs8N4}=%{w7ra8Dqg?}dD$sd+Ag-wc;Z4Lf`9xAR)|uu?#u6TRW= -zQKgLjLAb)%BT5N1#0%l!%7kTpF$4@N0kaH#LjSVL@A}e74L?FL8XTN -zt0)S$3@e57e~1UeEu%^~{omq>aLb5dq5n&~9&QOL)%0J)+VISFFpy+1eIF)7m*dNAC4B#7sP0|el%J}-xZgH>qnv`^mXw{xIP%IqMwKr -z;i=(h5q(8G9-bPFR?rW{o#CmGXeoVDd>EbzMr-Kjq9WWe94(|Tibuj7qtSBuzPL8r -zF%q@VH^iIaj$pK!o)w$Jr-q}&^i@H_r$(cd)D-uHPmM&a^eypu_*5`jOD~ADaOJRC -zK%WOJ6YAOAl -zct5;9sMgTWL}|EfSS_T-#KYmXQMH_&6jz1YMpO$uA>IhL1=VVLMr;Vr4y(oVxHuA? -z9aSsoX|X3fJEB@C7iYt>LA92i7kOd(uvtKVEhfVDQL~J`Cw7GGBW4Nxjd(R|51Li< -zQ=x>Xhs`27BckEyQL}=c5^8vQ#4M$=!VFIb%^G@6)P%c+%|iN;cr@HKYL?Rv#P#8> -z5z|8B;;nF3(5$9&Vr%%^uvtuB6VHUtjhdD8BXNKD+=ywVZ;K1zb3wC~CM^BMyxUqp -z7T`3hzx6Po8Ft7KE8;6)iXC#sO8I6u#X23aLcRp{vrcEs!Z*MyJMD-Sa|Nc^X=lvJ -zx57DA?Fba`g)qdboq-a*23}$Z9DyRf9Dd3UI0L186MVpkBT&feAjF6>VBw7rXWS7e -z<_!>I+!?U)CYWPQj=2K97$#YhbFPH1gV)$m$6OJwho7^f&bd-Y -zc0}xb=1RItyc(JAHW$$rp+u&8%@wpmL?hEZ<`UW_)W~$7sn9NAM!LGqh14f%B3-@a -za(bJ1G}6^$)=|H>KGM}^Hqd~0D{`*eTud(&TO;Rs&3gK6@l51gkGYiIAnuQx>oZr; -z2Sn13U$~G@9MEH=daWtsGI-ud^;wh1H$XE6yw)^wHN0aC_^gSf8Gc}Ryw+6mEntSn -zXH6#GgeQz+UTZqJ4n8)H`9cZA1tUhCH{izg5_j2n&KcnY}^ -zjvI}>coJ!WL&jlmJdL!$Y2&ajo=ALfz}W4LrxHJKW4AA!OfH3^#u;xso!kKDjWa%5 -z0(U^4k?Xak@XO%WMy}76#J>R%W87;?<5$Cb#<FG=43dG7kA-iQEhOjZSYY -zm0tz3MyD^9%y+=FaoQV8=hwqICjVAA03cnIwGn#yJNxTJq -zZXET_rSUfS$T;eoOXNQIiLuu^m&*O{wz1bYm&`APXN~jTxpaO5%p0j2$IsW&Zjq#A -zk0}{6EPA!<2_=PoU%0gFaV3ZTLcE}5Pbx`tSS-?lV@ekN2cc`h2_=pGQ0&x#<4PX= -zm3UVRPAZACUleIAV@f9dd-0&wGNGi>zY|wzE#pcq{iS$aYnfD%>6lon&5SA8^dH5O -z+RTKKPJb-!(PqY#eELt~6K!TPnm~I+mR3I&&7is%)#@jrDfB^ciB>-z&7n_I|VW*;*%XhckC_6akEJ|uQ%_Hi?ZJ|$k&?2~2^ -z4GKk@9y7D(l!$866J{FSFH~)M+{~lX!qlcG%|tpRYP7B~Gn4*QJgRj~n5i@*uGhN8 -z&0HE2Z)shVW-^@=TeWjzW;Xq~ct$%nVW!ici2Jp3<7Pg6R$S1szms-u8ziz+m$i%( -zfRm-VtyLrg7P0}CwSttvO>DqztsyB;$UH7RAzDc%Sa)3n8od{BAHOf_PP8Oq#WAWKDWPyq=JRDy8PwD0{FS5{cC!<1e=SLdT-NA{myu%F&KlkEDv}Ki?650dK`Nn>9d^fSNIF!r -z-L7~!u>xVc-SKLY4^8ZhD_%)zVJ|!5j@R-8NM^Y%TNy6^H_LU~s(1!0X5%hf1uuh} -z*|^(Q!&9J`ZFkwqc?n#}w!3ZBJO|dX<1SkzuYz6dxZ76ClOUTlxMF3z2wGT!J683z -zn8x{sm1iFiNqTm_vYIXsy?XYbvXK@Dm!3VKtf#BR3wrjDvV~@dMS8GbSxc7*T@MZ_ -zn`xQYsRsv?4RoV;R}T&;TWN|Y(p&nKHS{9!px!d5Y@#LN3cY1OX{77L>w3$O(nNE_ -zT79NpSw~ljC-s>@#ZIflJ^IXmVxwEcC;H5gvW+H*EWN%zx|%K$qk8>dbR#Vim+18a -z(e-q#ctx)tif*Arv{=nx>bCx -zpBjp8qlqF-uk2S>(}iMCuN+i2(n8_YD+ko|bd7jXuN+dh&`hyJ-`}sUrOU-*`u;(6 -zGc6al>iY-O4Rn)uU*A8ZZl$TBRB!87*U&ogbqYb7Fa&)8L(9KLA?Q;KK^TH$LXZ_h -z&{8*7lp3-TSlSz*Q)2Q`q%jj -zYvxbSe|zm8j^h6QYqq~H$NfF-?eX_qe}*RPP!zH&Ls&Uhf((8>vmarFRXP -zO*CI@)z9^t>*y-+jDBv=w9{H~zkY7Ow9#$if_`pDd9D@r_qe~8`Knz9?(cDbFSEao -zKY5k^FB*iR#L+A*WL9WhYFqk -z{m*a8`eD)8(_7$E*5HU0@I?@04bE5zU;A~rlK<#Ucw~=9_7bxhw!DN#_IPA3ab*A9 -z9^9$nPEBT~R)jk>+^Naz)GWAD!=0MUPOSrXYXA3lYPNj-J;*j1nqwJ!C$tz}r`ZfP -zJhI0ldzmBqZ{v|Y9@)zr*}sJ$2t$xe2>K@sK^TH$LeRf3a|uW36dy53kt9VVF~)rmmu?5$E%;?r^E5n -z;jGC$SH-ho6+7yhtKgOJZFbZ>SHshxmhE-Tm2)fH!1lW5s(C(aW9MCSmAn=nVCUU) -zZwnNJ4>75S*fM;G{Vg71=KPOm`*O79ZC|tR -zXBOnl*V1m0q-BpO88j?>q|(0=S7C>a4EAQ?c#2nYem0Ln%{2uKD{B?3Y~GJw(%5CW0`WJN#-NCr?o -z0zyDCfNBvC0+Imq{R9MrfMfs_ARq)J11JLlAs`t*We5lX$pA`0KnO?%PzeJ18vr{0 -z!S8E+G2lo@NI3gs=j@SFxBc4)p^m5iZIsaO?f;zkeny|Vm8ObPy{%teL+ixDdfTA7 -ziCV-}dfR~7NE^i)dfSlNM03RkeYRg+M;pWueRfc_(`vCtpB+$bv`L)RXNS~nG+E^7 -z_I`6UT`VSa`=Ggz7KoZccHjI{J9 -zb@W@}ibzYJ(m+AH9+~M@7SnHvwUL=#rJmj;o{Y@&C`;*e;-1J%pR$U6Pka)o?~X2@ -z2{2$-y#5q&IUF-AK7SIq7!Dfyy#6$D4V*Og`TU8*1N)3tuRoQv!U?0*=T9cv;jnSS -z>rW>H&KM_r@dVEs4DZ=CVj61W5Uj9jlRgoME7~@`B -z8owIeGsbjSYfMfvWAs_@K184^VLO?Qr6a<8TWB{oM -z2m#3eszE>qNCwdL2nYem0NRRx5ReR@`w -zvc-v|mWbpGhSpLMsbHopv(?UO#GDXaOB+$?DcveM6>t2 -z6g*vK -z5Xe1{E0EEIQ0|TF0iQ+!ITv{YIgNyJUt|s(=_rBG9l3xcI!b8tLUv#%T`w?tA}&}; -z*9(n4$O`zj>0?;59AQm7~0CHym`Y!CZk(&h+TfV_oq7m>P8Q^X#C%e(HT!$0p&?;4K{- -ztM7yQgEBfePTv=e0FCs)SiLg}1al<`fIn4(}(!#|7TaVexQJMjg$2y -zhJ%ar=2)3CF&ONoH^<4`h;YzOC&$X12tTlyPL7kg5+R_OZjP0?5W(OC-5e+55K-VA -z9TMBphZq1V=#aRUzQjn-M4yOlaVCPmLHa~oiyILMUecMdElxxLsG&3CT3iV}K=ixV -z78hbDsHfk>wQz_S&_&zF^828#Kpt%$$M1`Vf%9}lEZ-Ro0$REvj_-!Tz#}>#mhXfH -zf=zTn9N!g<0=Ma=SiTDy0*=v5aeNN?X9nmI3lIyC2`A9FUs!-xfJ_1CAqx--kSPGM -z8HfeQB!Jiq!~$drK-bs|!~$dzKx_tL0Wt|7HUqH$nFJ7)MGY|`qNdU1Khy}PC-qV)?}6e#5#=qB_d*lE -zWy)JBH$!8=UaCeSw?xyxQ>sQP?}@}fNf8pc1xf}j6d{$HqXeL*kVI~U2wo3dC~*yRh?VKcQ|InNrZaIV^}lGh8a#{#uo1+OtR>5i8<2IV{H`)Q#mlJNP|5s&1_0S-~ARL)}=xbA&(QH|oYJT@RRxZPh{LI%}xGrRtzc -zT`#y1k5dO#=z7DW_?kMXN@oU3aiF@cTxSap-~;NqN}VO#ju)%zDs&DI;^*qRDqT-l -zh&|P5@R-vM&GyRO+nYPP|&( -zQK55$r}0O1M-|xv=3q-Tx16+wYFw!1R+7Eo1}sr?E6CpP2)?A|R*`0~1pBM2%Sl_f -zAMa6DSCW=+8=kMOt{@%YDf~oTT}AeU1=vlUQcl{y-FS;SrINIOoADHNN(E^TPvAT1 -zlq%93R^U)|YdL8L58{*R)=JU}*5DQD)(X-Q*5mi;)+(k4%)<`q$a2OSYH_7HvXbcq -zH{nEeWChb39>X`(kyVTtEW*n>m{A+5n4Yi*`=}M= -zj1An2cd8YYj0IHUnQBD^V-NNCfm%_;n8PX@t?n#m?BF4MTHRU6SixGnR^3^_IKl?} -zNo_}Yb;f|6w1t4Zx+Zr -z2@jA;Zx+gY2n*m!CktdAgeypo&h@CKQ5vry(sm;-w{M9|_+xPSyY -zMA+g**nwdBgrLQf;DU7egs{bjumaw6rl7@x-~fWo6t;L1jv$JDCurdkz95T!Cv5RW -zJ%BlFFW|eQK0rv@3;ABi8VsN-1bk2A4(8GoLcR~`1zhL^0pA1l1(WCmA>SMI1|#Vv -z0iTP!z;e3jpLbrc%Hn-CHq+SU^M=8%aIVI#kQWB~V1dT2fHw*b!{;=1MZD3_8u!?CccOl1$*NWn#O$INH_!^)if6JBB2+~&@>kC_;56SqiHPS#XvJ`s|m{24TJr0 -zsV1mU7Y3d2I89K2ZWJ7WuW5pcbfcjy4%F1;>qfvpd_YrIsEdG}c(JCgKo<%l@N-RF -zkuDlqVoyz4zHT`5$J;e&g}QL)hNo-N3Unbb6yMjR73rd&1CG#iE -z!K*bL1v);A#ve5uMYe -z!FMz%MPwAT$Dx|md~zfV#wRtcg=8f3#w#?f1tcFv;rE)>A~FV=V+T!SJ~Ipsz?GWF -zLM9Bl;6zPi0W%7Y#5XjNMa*buhj|)9J~ILaVV%ZM$V5OcCN+ivCKN_uMq?;qqM;S` -z(J1nn;V{6IiRH2JFS;oU5yzVN2Efq^PKa9^2nFz_GDR&m!~#H2nc^0ELJp#+ccK?R0z^_TMS43#0tNL_tan6fffeN~l3SzMKuURw<-O4|5J1(4 -zxxzd6zACLu=MCTE2vtY1&IR7UP}NbY<3a|nR&|uC#0iz=m*^nmSniYldqbcN0Mjw+>$^oH+nsH(M? -zbb(Fyq^h-)!iy0Sq6Q5RfmNH!U3a?dlmM|RHhCit~%NSqSn9%!E;9_rK{b;(Y~Uv6wXHd103`4V -zZEGGm6lUS~+Q@axS5Sx@w2`^YAUGFSY9n))fp8K|)JEnpL*R0JLu**a^oQ}7r#0j< -zfiMm0w1ynUAEsbZYsh1GP=Oh(Vja^DO0kbtk;@E*3-C^@B8TyVGCWhO$YX+`96!)@ -zu44wkBpj{n%w>Y$QhZw5nZpFYS$M6sGmjYxv$5Ini=P~cSdc?mNI1QSufbW$Ldr2C -z#sD={AmLaNQ^BuPft1se5P=PpSi-R&CIgxhOF8DmcyNTeDB)NUGr()=qEy*~5P%ZO -zPonHaOaxacKdI7;7zg%KyCq6XVmf$6?UpKg5)!bDN|h)rh$-M6l`2)56N%sy)h=AVCF5mdyAAXWsKB7%Ha5yXlh6P6~Z%vlk{iXanK*TqU%5yXlhQ$$cA -zD}q=NWQqu?VMP!tf=m%X@E;LD-7S8#KCiOZe(L_z-O>M-ne3gO-wS;W&QtbMz8M+= -zv{Z$JZ;7UYM^uHB-xGA!oY?`k1# -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 -zNP!!sfl+G$((m)55mB*xjHg!rBqX03g -z&ttTG>8||G)BM*;jCODqogQc8!h?9N^zT@ba2IcAo!LL6zAIbxvGajc2D$tFBBk(m%P?2slw8ep%x_sRT7>EyO>I!uc -z&=W7#*a_vHa5_$u$}QnYx~70x0#4A)adHO;@pE-um98f&#OG+Ss!YTw;CT`QKm{EV -z$H~(ThV$`uZCZ}b4=$%`igd2<4!*BSE7N(y_c%h;QT!ipL6N@bYrs(%`k-OpJbh8a -z&EYu^qhT*lf+ZSm0nY|41am1rZG4=vlxI&wz$17Bm8xkJC@V-W_!|4Gs*6cySVkpC -ze5gu+%sL%BcEM(gLba;EzgKnIp*H+p -zV|TCkZ8!CAD_#Yfph8_3oJ4Pql{piG!ESnUoXm{~2kmrntjvk<1DomOIGHOE0-EXO -zSeXmq4sTP<0(k@+N!64vL%;%UU4_m8F8}*}L{25oj2H+90UCR%)5>)=(EabLVl`#V -zXw%wV|G@GZJRtjyuL -z5N>b@ctll5`8|;cY@&$2W}cPNL@qNCOrnTFCIiS+)uqfhAX6JW(J0WOGPt2kyhm&B -zLH3{bcrX%hj6(TjD6FPYE;9uzr%)lY0?1Vc7eru2B6ozRFe8@x!cIDB9TNu})e3hs -z8dRwiebHR(BQ^Gd0d!Qs=aFhVCC1*c0PhqVz2H+iSYR~!+fEQh3>vBWd@>v=>H1tI -z83a-Fg-j+`s!Azg62MZmf{P;Y1F_Ku8tH=qV^7$OqeVt1SVd>$GLt|Wl~u?r2eVWu -zWlTJnrS9}Z5ui=g>4xO^j<(YWIey+R!bm}k`t!uLTDmKjk%1JdtB?$WZFIU&?~NQl -zB>hrgw1NnK66vkbEc{8L=MYz_!nz%aXz&N^8Y}BV^aBO7Yn-evF$m7VrP@f>f4G8L -zppLXBg27&Gq&eD#ZwTa}@IHR7iu`{xO8<)cQ({e-fK#D!f|u}iRasn1Ut%O^qEE!O -zIHObehR~#D*P1GF5VWI+V$vP{is#T3v792F4`BvHU;teqQ09}P;BdT=-mQukD+_tv -zXe#i)Bj{9hqlE8(Rst6)LBzK~V(hOqxFbKz6Z0)lD&|S$7H~h-iR7-Zj!qED?O_^C -z6p<0IgGTE}OSlb_f2|ct!1J{R4-||^G2aTMV^S)&f{`>TU`Sw8RhKa{fl+PnMdsK? -zWb6Zr=q91j8cOM?LS`9AQYoC#q|fUdm_^{GDy5j225zbqKBzw!s!Ay*ZQyP^Q>5>W -z;_()(!UF~2nPR;eO2adyMoYLEKM)z+pq{SJV+im{t?)&Gz*m)0!3cq`y3-v6;ApYl -z5-q^dQlkYtflrH!uJ90jP-wJ=OX;k?X8ygRyVjBBumZ0Y8C^bai|F(~L-AU%-U2Pf -zCpDekC=|5PFJtvChzGJ&trbiXP*7b3%u=AB3;xV!k0th4`ZC9o|Bmh=o-h0p+p2#2k-%PU8T+v -zZpY`SnnIl$yiM2SFyp}jbtLz5zkN-fjt5uc=i0P&x_=8qCmSAk!FZQ8V77Hdvw)SSRFrqj#8$<(s4NfUl`8VEn-`8kI9{K(DFJV?u#m -zYcNMOm=VbNP(d|`HM(6PpwW1f&VjrO~3`YO^DI#LHE#(uDh$|`4EK&>Vvj~NMSwVh^YI+&&Dv_&oWj=Iwl>G5fy-Uk`+ -z+E{&0Bmps+P8;M8s_CwBh65Tjt+@;zq|jZJf4@>IhI%P62EZu%Nnqr|dMpTi^k>Zf -z;?0j5m#Tv*naTg~Qw>fbGYXubYATuDV1Xvm4&B3xwRL%n*Wb4d6==(1IVC(>Vic5M -zPim)tDD6?+0h<#CtZ$@~* -zmB0o&(-k7VE#VAld`T5AQRebo2~P;XTsl?NC{h;ixF`%fq7!2IPG}(DsH@AFIY6m0 -z^hJGvQf=@;u6U2e;Ea;7PQtfGAy_Atd&6f~CzYFj9wBRRLPG#wU0uP<2YQvk6?p-@ -z+Te}6F(Z<5pn*nz?ITjqsEAn$994=wNQiwTd`C0@`-qM1@G>2h!;A$<>gp=8C)`U% -z<&pj10y?UQSp~|d`gMOBN2_o`BfwB~N+pvD4yhEb$QB$@E4&dGPthn`Pzrt^F*-mw -zU0=jxfjTN{9T@^0>8yNaE~r&?_C=ncR^91^IQWjH(;3O|X^Gwe@$qS~@vlW}r=>>o -z&!cTSolp`ERkxNi3qXUa(-paa26byGBL}Tix>RqD5`ls0$|3nMhJG1mYfLk7YinkZlvgWD95$FM%&-}-=tU)W=bJ(j-Au@uA}OYE`qWi(|9t0`Gc`DHZa -zANEhX)s02G7-)uVH9`5hVX!|g)!6-y7t(t*K{>jCa3UV34a(CEff@Lkwr-uSKOBbx -zwRO3=K)4tm(AMSX{NXULS6x@Y0I)z6>4K)=8msRBVb>!AK#*OYq@1SbHX1E0r&7FHMfd1gC*Es -zZLmi307q-+g?8gTDnoD7j&-qoSF{=H1o9BL28jmns4VALvlpgim&Fb;#Ouuq(E5WGx9RWddp -zNu#j+yzM%wg7E-$bW|A=4sL2w@)-+IMhC~~`=TIiF -zdS_IP9|(-0P)^mCF;U=^Hl=_u2X%B-F*5-8YCC(Oz4(r*vp0H*Psi%rkP@F37(-wt -zJ{@NahOelDQezbKrP5>dPN)j66?|T%9i#2EK!@;2Ri{0g0vfb`w`78G1O~dRgmi=r -zR96K#6s|wWYD!j9ej!a+$!bbgQ+^pu8Omx(R#Sc%O?i^ll&lZc%Qv515N>)j{PtYpB73&rkKyemqVURHEw(Z{cgIpfa5o -ze1ij3b;UYocnu#=)s^Zz;d8uLRae66jTYg>>PTJCfohd&Jw}k8q2Ldf!5vMHYSrCD66nKU&X&PgdB|JMK -z6fVR6_l_c-fbW4WVqTnlFdU3|LU}k0q7uY%KUhZ*6{IIjqlhvl0^FvFD#j9wq?$zX -z0dN{71$-`Q!epF02!>-)D364Z6e?kOK&~}dp&7uaF*u?w>=SGJ3KmgO<)jakQcVTlCbrbgj_-eNbkq9>XI;;CSx>4c=cSc&}iCHygaaOz?gaz!u`zLfn@r#3|T9 -z99xL{LWMXx)(5aY;LG@chGpzCCiWTAmwCoi#unn(LfjWA#C=n^qv?OQGnYT~@tGg@ -zZdW)~iVg2$Vt)IWpZ$RI{_-^xQgy1vyrU`d#_9minnatc-oDlRlP`X*{gl%Z)cy(8 -zRQpQ1e13I5#JQfu3Ht4(;adLeS&j&r5d@W&bvwD^L7QXM^0`CtG!k2!3?{u5* -z%B-)Mwj_tabn%*19UWWty%_y2GkHVTA7O8=O{$#Q;7BgDy5sINVc2hLw;B$K9ixM; -zaixu|YplGVXCFJ=Yk>P%Yss)&r}A(9yQi+1*?Om*3!dJL -z)P2KnrgeVWnQX`*xomRp{XZN$_r&&U -z`=dsE&~452H_m0_$^%1xy!%3PyKGC)j30laa=UDAG{ppTKbe&KsLv>G0hT-|hN|%F?Deq|6u^Y)D-#kc^u+fBwYji|5yW_+g8U%bZEKHo0W@ -zT-v?+g?#MmrgQx@g4=UPnk6mYIm$L+Y+2H{9e0Ng_Ukt?sK@pKaiKKScB%8dL7EBR -z_P%}n)XO|V -zU9ZY#sz>9w!y^t0S|8uNetrJzX^Wn%;*?(>)0p^b+ty7p=0A{49BByHRX*kl-sZl2 -z`@NWuMN3u)o}S6^mxLsaFD`aC)b_)oNBPCY7k>LVyux{VXhnJXp|(-}8oK!Ir3AsF -zk*!bXO*Hrf)SSw>v-aBQ3A^k*1s}^Yge}Q_|77rqyjfw}GRppJ3)YXm{4slC#)Oi9 -znHd4fv!_yJqaT+D8=2oM<_bUtG`({ORig4dts-Okt)zBs4Ack(xMccjIZ?e`*hyx_=?x|HcZ -zZ;f?IofnYrzqexixR;TE{lZU8n|j`9?0$Qfxtm712&B7r5Bzge>@S;_9r3VtnRx4% -ze_`eL(pMX5Ce3I%x81V8|ENyN;;PMnxtolyB!<{a1@9c^&6s-QE%jm7_1_=gEh+l( -zI7!d5gmXFu#3_u$W0E06!#y?1gy)wpT@wFPRarK+yrgVtU#^R5 -z_tL21@O?fauj!84s~RgC#~*A9^Y;%tId%zHxpJk5Y548O5Y>c7=MP*NdvElKr&~v? -z_eIAx9osnK*zMb!%=>?z^p$+$!#T&yh?P?hJ$@0Jlst6Qf`h+jRgLVh_=|0S|BCCA -zx;{Nhzfe%_ -z#aZv#^Cz6k|33ex>${w;+C&*keoPPY5BwTCZ3uX9GI3W=uZ1$P!2e0Q>{NT`kko9) -zO{=EfjsOJ%2JYN=xFP=9qNmG*+WYONM~^!C^7P)ER -zx;jOT=yzg5Uio+5UnsX+wr#-nkjll*J{xX_=NG<9xZHeJo -zkfWY0eNc5}M_1UTnO;BDh(aq%7kl~oOp58>fAo>HV2(i0wRPW~gy#XFB@4ZLTULrT -zZOy;by&@pt4G6frrez`c#r(qASJtn)e;n}G?Q-^`^5N8=xsM#L-puB<&z_bwMmzd@ -zv-X$YJH-D{d-B`g1?6FQs_?u+^nGFEFWNmmtA77!K=;+B)Zwmh@2JPt!Nb;ExO(D@ -z%ff(D>4(1^v-#&x_kF3`PMvtswn9#wn_HtE75)0a?>9ZJ9ZBNNd9-nRLGz8$CiiXY -zU8^^5rjOo<3-Mp_=JA;l$^03Ti62j|jsETTw$Y8N-1JMQjU#v4R(pAdh7Y-UFJtP# -zh*Kp2{(cMmdTl(E_4UW#NiIi6JeqUcC1X1wkkp*HmJ<_RJNlf)GoSBhXJ1wk?@-qq -z9TG~V7hc?xI6gkXy0K~RnfT6=&iks4ygsqr3Z8v@{PpY;%Xc>0eeY83#6K`|>Q`?w -zMtq<6a)(RfhaLL8)5B}z#|rJaOwz$AHBT}tZ|}G@LUL)3f5Lqkb>!;3{bO^EJ$i9I -zX!c{8oAkJ$;%RJm#*daRtA4k1`JG)YMLvGQZ%N?c;n)haK -z_wh}6(Irn71qOVuh}F)mx!jd4kFMR~9cGNiR}$ezZ?*fJq#xZY-@cC4d)XF#S9-;_ -zdgKD8Kx4JV)%w|_Uuuuu>s}U^bi}LMWy(+8^Gm!Q*!cW>q^omZ_N~)1U)4I!E0Pz7 -z*QYML8`sqym%8eO?zdm$FGqXNUN|*Twlcr++uE=aW@+|Qj^~PnM)?Q&Rm}9(HmZv- -zp6yip#>vaE^|{*;n{jH|_CH>ouDUtqn(d2@( -zew@Wn8Fqc2k5&G>;qB~h<=WZd9!DC^KWO-qD&NO(*cIa<6 -zR?OM9@wV~t$)CF=dY9!7(Tyu}*Zg_&<*YYFKYx5BkC-q#q3GfQhsGUSw{2d(@u~T^ -zowCa2R?(-W??c09wLOl4kFsQ(4`0=|R)4n|Z_D0!Q!O1-;~%hggyP51U3<&l6fC*Y -z^}smDBm1$^VQKm6WdYRl%3Dta=SQSm+Pk~g(Z^d~2J35oZg?_0;u>{$fPC}iSA%XJ -zO*&9@^Y%W$`Hkj&TQd7g``o?0%w473 -z_OIXGr(X6cTL1R>KAExm`Gil|YpdrkrYG4l2ksq|7(9>FB^)}bxpphCH85Q_`M{bD -zZ+_jqSUElAPwm4=WjwpTOB$9Eqjr|I@_N+ZipW0~f3wNFttIKB} -zdbWP9jJM-D%-Y_ed+?R_5;Tn1>(%?FzexIU*^bm2}?acRZ)h0Y!yerOJR9md%|plWT_ -z_dg$XIQ23xWTc`^ZF#Ae-xEofHYSXb2Xx(ylqR?mgOGKzyedJnY*E;r-^$3Wi}XRPlkoTJgHQuI7si+t*Hs`PBSo-=3V0uaj;i -z2+lj`Mq0UDw(ya9PhEK-ShC}1w*jA`wq~DnUxwYfqb}ve9J4xoYFxL`{QYck?RJm5 -zM}9up5*#|RuJe(ncM=Q}0<(QFc9X+g5aZ(&Jt9k!K6Q_=P{!D=zzZ-?}x| -zKlJ&}a8k>iJgXD&zHKnQ<81o#6))}`&z?Acu}IKzyu5IOO;qHC1$(5KOMd=g!nq4C -zNF+S(Kk#Hidh6+U!_KVgfdP)sf6}(y{po>rZp5V|e9w^Dcs?=0;a>as1J{n!&G_Zk -zy$070Ka6#ZTK}F}9iCKKv-+F96LvmX_S5Wdik3Xt`sljDG=6AT?d^>-Jr?Ec*|_T5 -z@2U;a0g07i8|B?sj&Is}=C$vNQ8^;@@CPe?up%QuV=kz>z}wM+is1} -z+ezu};$F4g-8VTVqTdM3+84!=oZ$x&%ogMic*wP|d~@07r-qR5Dcvi6PJ9s-)ocT# -z0o2n`jp6%3(>n`|&+bMI*34>q|8f8{cHBCyXt?vppihfB9beQ_Yw0kKj2Y&a^~*2c -z_47EQwd(!sp1SkG*|{Ho_Z_ik!sYzRoQ~m(qCOfuA_t~Uo}x@7EZ;G;J8mtV_~(TO -z=9bcTC1aA9w%L<^TG#V6O=uq;Q&cgxPRQS^|IWwzmeq>dQDNH73tMgS22{VtBO^{t -zX!vw>gRuX3^ZGOEesjoEtnds8jm|uC_v~QvOPRHO+jcMQ+%xvbgqKw -z22_P@keqI)P&%x7x&Dup&pgIHGTXd*>Wz@Y=l8aI|M~ptb=SpfoR=3=wj9=Ix;u}( -zedG16yJ=wkzD+xJ$up+ar0m@7F!bh*wF9EpkDD*J<80IU&;h=7QF`(_x+-J*}mLred4?T^K3hwsL -zD4g;A_-XPBoteGIMV;!*e6cT8HFks@_c;+Q -zd0_dft~zvk5A3IoU_bY8GJSSma)TH -zba$|YF!xcPf8?(C`9FW?9_#f|J|gg4^qW`nepKveySmaUJ7B>4vv7Uh<$&>ZEB|b} -zI%pa7sQbyvyu)W2g5S1yzm|{KGbHR(+tsPfZ?80LS~j0?FFmD@^-jr3YJc=8@zU{~ -z0dFEba%%U7-*`3e`13z%yAma1ZVsqQTGhTjW9gbJAHItl>HOx;#7jT!&3Jp{-Qezb -zZCAslKd`*K_usqS{?F_0o0xZz9xk3+qbS5lcbFebX -zq2JSH%`v+t9{lyLxAtEjY$2PnEoHZO^TgyQ$vbD9n%Ew^c~7$E^hI+o{^6Q3dC1pC -zW)_6E%QmM?U~U}!H8tR;7n7Gy*fuyd^v=|2b0=3MhTNG_JF7nB-Th|YLtAF1%bMGh -z70CyQ%(YE}L!P$u-XGfV{BwKPfu#Kr`=09p -z>kjOaE#iFOH)O2deE3Ymw#~Qdmh5+*I%QdE0k#ba`hGBf@3s6u@qzCT?npj0sl8(J -zmMPC=`&aB<!|NPZdt57aB*_VKhY$2i=HHnydE``1-v1J|#DUMB-dG#xGV#e_1ElGiR*?lrL*1d|kv?JkD18lneKE3YiZ$3?a -zeI{YQ`KH5{{4V;d9^EPxebUzvt!49~BtQZ!MHuda3Zd0_Q*T -zSTw+#|4LUI5;!<>{OToZrigyOlK+#$e#FG1&Lcf9q*gAx6Lw(ihtnIc4S)G*tmftE -zy#bp<cdTA%){6Rp*DZiBK^qso%sDyAv;Sn>Kzq3O$?&wiJ+Cw9!jG5B=N -zSi4bO>$81dzOp*+_&9rE;->{x4=z4*nRu(P{jp-qg9V*$0!BaHb!REJ>*m_WH&Inq -zq+zHc!?*qWmbzy#&)k|0T6H?#*N+?XU_s-Xf*rR;Jsx=H=Dn&xVcFO29om|GfB6RO -zj&4!D*Ro%a?g&4>_wl#yk2ZwA@=h?GI@fQrAh6xPrZ1=3bzi~xiE}>dn0bX>>8lbS -zJQ?`fcXz+en%kFauPEf-bZ1P7QfH>dc-B1bO!+1|ZGr0hFQne_sc)F!_FC}&rF-}EEbiOE{Yfuy?pAE3)jET|8D(xw--aJz20{p -zmK)D5dr&gFjkD&I_N&q!uLVB_A5JSgH8EOn|6)gOKnQ4xUs;iO`NP1X`o)zqUhu|D -zJ!5vU(R=fwrr(x?)8lpaH=D=1KfN`3V$;@5`)qFBIsU!&haHu-Ztef{%kgX9)$Ci~ -zKV{;c4P5`^kz!dED -zVQ$^cpsdZz-J;0tD-I2u^3eEyv3D*|Rh9YsZ*pdAvZS)SIW+*6YG|@3YVIKHtyx+3()c&7K8=p>s@RE+-wf@ -zUE@3Wv-`iUyz^@Li6#Br($>b7ZaP`;e!i#si)U6(9kRY_jE}>Dy}R~3yK&YV1HXO# -z`4N6*ew%G=yDah5TnKETS<~&gy<`7#XvzKZgq!(SuDmt>^a{J4&(0n;r$xxinomkw -zj{Epz(&c4~#ymHF$D9DoQ>{y{ti9hg`ogV?NuC8O@_w*i|JsgOua~{+n!9cBm6J!0 -z#&2G?Y+29M+Vi=q?tidlN%ZE&@7~yYBy?%$Tb6@YJ%46->n>fEEXn(_)!KqPj_xxK -z4b+sRU39Ums(Aa}^@}m5(t?g?*O$4c1BSl2`V%>EY3nms!1*{F3IG?bDVec{yfH3+Vo3@brKA4YEA)?`1Xtr_Xk8vu5M^ -z(-9q>>E5l)x@kvKKK!@6&6w}j4qWHCVD^EMf)CxNhMxCyaoM|T@4xP!2;bepuFcf+ -zH4{Ixw%Xw1z5mryn}bOhrF+i)qd1#_SLbP@)K8MHjnG*)2gp;%Kc4qO5!>WY?YSXw`ZwC -zjCtAupXsTu?X?cMm7_iMOtRKzdRV3AazSXq9INWP_NeCe?SGGooz~em#iHu@{kI(>L;jI8>8$;_voovy -z-oI0`;I(<0p2_jnBjP$;8Q0_E;=@;FUs>zv?(I5%x96dx;(*7~*F1jw_}!ChkH(*h -z`RZ_Z@5mPyEVxsZGOjrP&ttvpvzAu66nK54ZNA~j=y`kl4ec>QJL|h8Lq`?#9n$F& -zt3~SrZoJTGMDUOdvzsHvtiR^D=kBSkKYEUyF>>{}WpO)P&b4Vhr$uaj@R;4D>qe~) -z8Tii0X}%w9>U?GCk-2*Z4jk0!+!K*ok1YLu>B%Fx1?S(NJ}BVq$Q5bpr?prWn`5E% -z?-tz3VNPCVoXtP`emc7JgA0B=obSDRYsWmzxC?V1UE4B8zS;g-xArOfww~N^ZC_zZc*dB7e`;rXhNMIXOxk9% -z-p9J%ST9X{Md;j!3kj9|KPi8GT4vDuyZ7JSbTV?-mBnF;gYR9ucr>iJ(+4m29RKd+ -zLmv$b%UrnYjWu0U`j6YO>d^VXLtihiII&?+iKAQEsMtQk7Vj#H?3?McckI|t&P+*f -z5uCbz*L}ya1CqY=_Ij_S&8o5wb`M;8_Uy}M-uu6MGX0w4-jY+}L%-ghz3Tq^rQ2Q} -zrhPs4`kJHr=T6N|JQ*3hzq7;Idv9eYt#nKX5AIlW>&8X9Eu|NW_k9_h^N4MbciG)j -zS6f<_23v#=9GTww+|*^UK0A|oS+(k6@tDn|o-+r%=G)KaHQ&qrr{el&kDeBPb<2!qEOKF!|~?=|ePoNw=U|NcnKx5dRpTL*sEzC-2lv@0P!?ap<-wPo3j -zc`Xlm{!}#Km%=&Qa@NNjulgYNYWe2d;nxep&)peq)2`}9<&s|E9lY0tT)EcVx^??E -zPF|ZCutPh3*NdmePFU?+b#+%+pEKDRSv$u%#DB8sRLI=S`Af{t4r*`bzh}##LZ5}M -z2RyCEmwU}j-MV{jC+Cru1K)Ex>f-gy_R1mc2L8RD#W0JLf8KH;uTQ7z$Horq-p?Y_ -zZh3oque3Ppq@sRfMrQ0u99QlUJ?j@==O?#q%f5KL&{6F<)Yzy=Hgp@v@-voi*+Izia8O)!cLm -zw~IgA|K3-X2QyNB=-=a)T<3K$$pTwoN;K>YH(aZ>Bi|9S9-!?)IalHn*AAMBBW`FO~$w -z=Qz(-hr_NG7xO<{IK^gXx15SgHX)P4yfX7GAF2J{ -z3q|jGO^iP4bG|wRglAhW(v0=!cr+`_3lwZm} -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 -z>vZ_3E86470~}7L|J!az_J$sGQCir~!o1?S -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 -ze9F|o<&1LojC$@VfHK9x9 -zXFGPLC%nBPz%_HzyvWQ^okB9bgR{%NjnA%}`eXX3$*U?8DmB?(d0kC)oUwPNUqJOO -zL-qecZKnq=ZTSR*ZJ<$xLuX1(Jy$?oR4Uw1n5?Cz~cz7JiQ8~XilYnxT;K7FIhkh}XA7tFHkzp9=2nUQI}&21ll -z`|go@w?3UZ%h7Yts&!}lH~Y4@ay5PXiaGyS;9}Wl-TG54eHVvax$j@_?$}}d)^zG{ -za?0l3`zt=}*C)`wZ`<~p3X;ALy>TPd^R+(Tjoh;N&$gQ%Uwq`u{bME9FU?!fEvWta -z4l&P0O%Dp|e7WFwLiK8v_(i2U{_=+N;E_WztHsVLJyrO4d{uUITFAnjvZ7SSdwyQ- -zsg8jQ59bbO*EPl_VL-cdpNQN6?Iy>Cc5v5b+z+Wr(p22so9g&u#^u=OwzaqDJnqbM -zt=HUcy*WRvc8C0+O_^h=x+rzks8Bnvz~yI) -zc4UsKTf!HL-t`MuS@E~j%%_SjPw>6(RDEyt{LsHgog5p{@Gsuj5C*t$zA7;qlm-hiCZ?>&#;J_eyRVyQ9~R -zCj#H?P+b*6lZGcf7F*bBLW|hAUK9QjoA%C>K`RdaB^uj5p}w6)ZSp>|bXNKPjI8SC -z$QfDZGO|`=R6n$`iX8h~VteF=}dg!n}5M%0IR6$Eef$isPc=%W+6^vN(Y9Howj}J?BawEOQ#lAon7HO -z%6@wXvoStp7Y1~yTKV?96sNLG|EfF8|CepD;r?H~KqCvtm4B0stbnY5u^y8mmLfK? -zQHX`aLSmstJkV&XdiVrm1#WbGq=;n&8a2toCy0f_LJxOHqkk(F5(_nIl7~+a3yFmu -z?vO_RRxBhIYSbhTpCA?z3q9N+jsC4zNG#N-Ngh5yEM#g6&OE -z+VT`_Rk21}nbX)GwT4b?^i1_9Xbt-G`o|b_(b^^)W5~4__UVS4N#|R!l+gVggVZzR -z`b~GHdP-;wbfo(At^YZVIo{w2T9chgrx006XmvivWY^D9f(0L%5-j-8lwiS!rUVH- -zJ~Smr@X@f8V8JJar34E;G$jPXXm~6o1j9%%EF}cPPyizohqsNqZxRecK$a3L_|O`X -zq+xi1rG%tm;ESb%sWB-S1}5v2kTlFzf(0L1Ltni4Gd(3DUb6TD}tjW(7Nf?+6t -z5sgomr^-Zi69mI31(p(mVOW)=1PeZbVL%6?I<_c>>px8K2CC42V+@$fx)qnbVJwhr -zO0boXG>k%LDM5mdJfg#`zF?TGgkV@O3{2K3A!(Scgs$RBl`EUPI!j{c1cN84JHKF9 -zFbquADZ#oGr!^#188Et2$J$@`U#jVM^k2H){b6OQva$>s(y*jqz=5rVU>HiXln@L<0gO-_-Ud&ViRvau8is%@ -zB_s{Qsw^c~@R3akKnJ5bwkU_|KTI|yYO8|pI@7-lOW7={8Ep*X4>JXI#Do50F|f?+HWD+3CK;dH?; -zTL}_;Bn^Y!f?>82f?;+;5)2E5bsB}D2)u_X*PW<#g3jltJsb -zQbI6{>SifHf{&zOHhg4Lf(;+plwiY09?=267@;`44T>le)lOhNtWr6AuqrD93WniyH5o8rQ?ox*zeW6lHh#$1^QvwtmCwV<8V#YEGqBz}q?NW98U|n~ -zp~lcC0$kHWP04x}mDNpYN|3s#+}^={k}KFsu;4>$NG$l!ln@M~xv-QF3_}5oP~4z) -z-uUgWU|2A$Vpa1NkECIE4kHvtV>KF{ -zraM!;YY_~y?+aM)ku(e=%ccZd2@-r{Q=$p*iR{$zv6|mRT&n4J^k2%-BlY2o4Q740 -zy{pp)BMQeL^%~Z+{!dv6%k)>uRYGzF3X!FR8TQF=QB?QB;5=#leFs#Z_LNE+GvXl@E -zLjjCX9Nq>+l!@vlu;3$U7z@OLkECHZodq9B!+;J(C=PEM2_Jdb0RaWWY$XK4C|Z^h -zf??p1rG#J@3Sfld@HQx-OjI{PFbn}%O0eJ~X&6pt!AH_Cpo0;Ln+QIVhS~6uO$k_4 -zFw9m$Fbq7hln@L<0gO-_-Ud&ViRvb>GN51>3nUn3D`7Z%%oommq2?vxTiUCSwJ1|p -zJ1Q&7(1MiT`U9z0O0Zu4rj@qghF1OomQrL7^)yQf)_aFEB}m;=Ztq|}$rWrRBv*ib -zEF}cPXw57o1jA4OBNT_XK@nx5x(R||2*^@`1s_Sna5@VFKugyQfvc&bcPH-VJ_1;bb%!7y717JMWP13DPhu|+vt|6#0M -z@`rq+al|z8aD7S$hSA4ZN(hDp!#dT+f)A}Bk>Den5^VTL8fL>s_J#pBNyBU<1jA4O -zBNRuKgQvX(RL(8doLdtctb -zY+B&$NQxp&2QD&R7HKZo?JUCaLIYShd60DmV -zTEb#=Q<@TTdj}}6lpw)J-oRwTM{e)XCk4Z7C0OvGH6%q5RH3q+1)f4Ol@nM>2!^2m -zMk5zWcYRqIP%sRo1;cD5Snv@H13DN@3?E6uXtRQ0wi1G2!LSa#6h+`Yg?Bm=)lOhF -zB-Iy!C2#Bt8a%PlGu4~GdeSNnJ786L=FCHhcgyKq-KlsdFImV#5raMzTPY8wu!#YlsO$m5{rG#J@o?|IdA9BXB_jklp -zykW|d@*YgdrUc+7X_&19>sDMa4Cr7qF??iGLTv^#TR8WH>UW4Axuw1OSPP}Ha2jR7 -z^emL*iaMz<>d~oDA@xp>Tv2OExxGV8vXqcqA-O__LoE2v5|&^X3SiV(QH3JPM0FEb -z@R8d)HhgF=L9sF*ts%+n9crGXgwdGMM<-T8QWQZIB5diq5JM*zJP}J`*aZlNu|O;( -zBn`ufEG1a*p*18Hd}vCL;3KX%vbg@E)pMccR(}I-jHVa4eMW -zWeJ9{KrAH$!|)tS3BfR`o23K^K9Yvn@R3akHhg4LLM42B?p^qz<|X2sHYH$H!7y71!7%X1QbI5c1u#N!cpE%bCaRlYUF -zuy5~hMD=SPk}I%$7}c$ka=8A(Bo{X*)ksHPlaK$)^$|E4J+xdQBEDZ%Qd -zf?-rQ#wK7uS^Wk(uV7d(T;El!hQxvots$}g6%I`a!7%X1QbI5c1u#N!M2rTTjNw0J -z!AEx4ut0)gwh}D(&>9je1JaaG0TcyT27!vDgkhg -zDMS{01jA4oqvAbOxx!POB{6h@!4uV;p9LRD!)*A-rUaZWX_&192|n`b54wY3n5~4Q -zVRl0j3=4*J8ik?=yoV~+ov3z#&gZB-91Ep;S%P6K5K9TcFg(XnLNJW#W+_2}kECHX -zd}LFC4IkN*PzN9X!In?e{3hZ&ALm7X!m(H-)Wbv4lJa>fjxk`aynzYPSxU&OKd?7T -z33=FoLT4#Kf{*+vVm5r__Kpo7xxHh;3H`m3&ettq+vLn1s_SnfDT3|4sRO?A9>~s0R_WsB?QALT9y)mVc?Oa -zgkTs7V1(lEHYlP@R5w8|3;|h6u;3$U7*1!wN768$gAt0G2tJaA+3=A~30PGy%vM4$ -z3_P-w5DY^Bj8Gij22YiV>LwVJ0d4MG_@d?=;;*$%ox7DZ;Unb@%({ibsBV=ESX_DL -zTw4+b8M;aDE17=HYCOSu{hOwQD+AJ$ -z5DWv4EG0 -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 -zZtvJi7?H*RT&2$HV8MshkQ7CJ -zYmj@&K_O%=M(eM7Y$$u0K3x);5ddf#ITvr_!_2~2)rPTgWFkD-Gf?>h1 -zU|0`51jB-1o$7!hdK}Z#h9npk3=4+!l#gIoFsxG@P(+Vo1j7nXmF;wOqOcm0JfZ{U -zSxU$wIyjxBgwe&NuO?+vqP99%@R1kc+3=A!B@BblWdD|btbU33^9uX+4u3NOD9Yzy -zWpN*+k1>W#V7+%pD{WRcr76L>si7&s>ZUX$SlyJSgn_lG{+}GMlpw)J-oOOC1;cD5 -z1j7gfEG1a*5ex&r7)_i31;cFkNE&9tN768$AQ)yVAsB`N7@;_-96VJfs+%Bb7y`1C -zU}ZqTFq|$JW-CF0kECHXd?XE{PYQVCEG6U-9YP9A -z38gV14Czp$$xq!`4M|bNWLH|p35+IIf(0LW^#=xE!ACYFPzo&g(C!OZ@S!O|f{*;l -zKz0Tc3=4*VNwyM#VJOW~LNE*kFhX&78$4Aes+;i8G;FqT?hDoL5I=HDd-bsv#(X4e -zzfp1pR)wX6NNCUX~K9ZYmf?rD8Ou -z4jSydg5lcgcxbLL0zPtk$A%BBA+a)`U>KfY!H3q61jA4Oqj7A65tQB}7)F<7DZ$Es -zf?q^5`tmDFfduC1SVGaC9XK^1q#()WeVZkskS*L{T -z4YQRH48wCQB@97dlZdQ%qiKihJ4`Sv7#0lcsSZ{{V!=n!Fjf+yuD6Ybr(n2N0eN8! -zR$?i^f)8zb=3zUcKKCwsQS%b<*IK8}-R?9g0o5sv(Zr?AT1HyJl3h0B7M2nZGqh3m -zW0kh#3V4F01PMO!TYuQyR4|MiT^4)V8KT)j1-K~$SwgR{MK9=_|fnFw#k2F!AIV}L}CyOvz3rd36wue -z2@-td4NP_h6b!TBBWaioA4$W&FGeU1Z-XMrM70xG_XVmi#L%x|@I-Y=NE(KfSV~A5 -zM$xjAU}ZqTFrb4`9b1&c^&ch}uB{Fhd?XFC;Uj4n)h!riDE|jlwf5*!7!XI7-lO$f{*MC8v-8(|CWEOeu?<=3j6jBM~r&vD9@bh6vv3dF;O=a -zLmOgf<3u;|aD7WHFTx{2vXo%KhnBD;SHKf2B?QAz03#GPQA1+g)W|Ly7D#UI*h;YA -zLu*K^Eq&>9j6 -zKC&snhL5CSHhg4n7;t+?8ulM-`BcqsBF^)1Ui2p%fTckZ7!cdU(28o3E8riN5)U!7 -zI?F0oT6Y-hT~x^xP@1KL0y}umI3xUqJW|49-PA~~fB{(Wkz9f55Dc@GAi+m&@6a6t -z!)zr4!|aA67#0lcGzvu#cn?*sJ5lWfozGEwI2KCxvIN6eAeIt>VR(+EgkTue%~FB{ -zA4$V(_{gRN8$Plr!G@3Q4FkUzp*Xw^iYOD+PLRFfS}j=_P%sRuvNE7x7&XtzfP!J* -z7b6shw*|u{QbI5cE3uRi48y7{B?QC3BTEUvFciQD#o=vGM46~=0t-HphOs~__(&Rt -z(^>G5Gz{oqgyQhFk?@hdVF;)n!#4LWd{Ofb@z+|X&fQ9IfU-2ImPFpbtWzALD)kHz -zU3S@O;h^8p%74+fi4-yYn$>uM^$U1uN=UANl~_tht^o2_N(hFb07fVdZyVR|Y4DNT -zJ1h_jKD36!%78Q_Sn#1K!ODO%B}nj*+dI%((lA>I!7#fa35Jo)SV{@Q{yG3f_RrdvI<8Khpp09z0y% -zTo!y}Q-Td2*_42%1;cD5Q~*UC+yuk5oDd948b-sYQ$qHJ*-EhBLu*KiA}T2hA@v@{ -zQbK7=I^NcMA&p*X-2{xrpQ+v%1jB-19jgk4;R%)!Ecgh90XK}g-WCkQ+eRuOFRVd8 -zmJ%%Z{2%NMhuSuOwE8XLH>*PYcKyf5+BEWTeMDd_BQ0UEw)kmE{0|x0NQknOkX(W4 -zW+_2}k4A3q>UL2D!)zs3@S!y%dDsC@u#_;ipTV-q?U!I!S+g2ZWS32L*>tKyFbq$y -zlwf5*!7$*4QPcFT+r{77Y@{g>B -zWcn-RDj^sa3=4+!&_giHg^&ERP&RzzMR>qX9?`LtVC{$sh6TgA+Zs?rPvcg3GawjN -z-~gpr_XUDs!LUwwvTns`4e2*tC}h_8N=g~2o4``SM3?vAw`$-=rciDuzaBV^rD-oTD!G -zJa||GKLSnA!J6_>k}IGZO9{EXgFjhHu)3*W7|_9J3gRdytv(s6A({S4>o|eY#7eN> -zBe!>K_{i-YNNl7`vvku(ge3WnKA2!?@2mJ)(tD1Z@)!`tAgGEvJSX0kFk^x3=4*JIK+Yvtsx19p#Vmm -z6;&vrOjI|41s_SnZ1~9DFr2P04cipmd9&sv;uG3EPq!{mUMf|V1|8V2+EG3aE358s -zeTT{Kz=ZxRC0MV2(-M|GLmTE(eMZyB?VTc^(S1`nlj7c5ys#3M?&p{YKJu%Gv63wK -z&=Qv1-k}e(ln@M~I#^1W4r91d!Eik#c7BXExu -zMVM12s-0lEGu68m7JOuv4NEN;W-GzUfP!H_2V*^SD1U3jPgxDgm}`0{vLF7pO;$oM -zENK{+tW$!O0cj0MFpTnNDM5mdya>;RkECJ1P0}!12^M^44T+TjX-Wu&p#VlSK6o2E -zRVJ#NAZZu^vXl@E!>TML1jDF#mJ%fRNE&9tN767GKJti;4IfFvz%NE94sU}Z%0#sj -zSoa00FT~KVV(>(DO6bdgyKI|3TKy97n^hrxyRJ7`W_&x=ej{rcC0D>l7)@7tb)LYe -z&aaI+QJpVp8h4Z{;GB_s_)0gO;w;a#H}B@dk-n-b86rG%tm -zSe2y&3qG`lq$mRKDOGM{b+eQp!ACYFU;q|;X!ixI3`kRg1s|Fcl7>+oEF}cPPyizo -zH&H{9O$phQ(6N$W7@lA$!ODPwVc-#?uD229l!KID`vTMvCr`l(>JRsq?RfPYv@{I6g*x>Lu;YJL-Osixo2f1&V|wyU}dO;E(j -z+Wjt#v6hjRuw<7F%g0iJwYNkoZOIkz1WSnq(eXQqH2IH401@B0A*9Ofo!s8(nDT!m -zSEx@8|1Bk0@S!!N2GOB9nCZ$ZZ(!2lBmd4BaARda+I@jw7}dd2LNJW#U@0MK7z$v7 -z;_$YST~szDARtQ#7JO(8Nj4?m36>J3DqaN+fP!GSRtedZkWC4l>JSXW6D%cI@DU87 -zAz{?@HX@8NQSAi98%Ce0-WdeLf?*v~vfv|W7)lF<*-F%hoGEs(>o|e29z=~lzhGD} -zEEv{PRIG+17>4IqO6XfrqlqaPu2q1wBT8#X@`w(YXDPwj5fuyrIv9<|n9dml!?o4X -za2hr*y7OkuJH#ind!BAxVRR1>L&L}zb?m5Qa%H0031aAn85*}dO_o<){h@bLTEb%8 -z)JU#?Cs^>IB`gyFw_&ERlu+Fd8os;-f7-y0)V7`nPs+QgkvA~eH#LG`_+M`C*h(~r -z4r4MJszWebt3<=McanwyQR9_h?JWt0+3=y=7qH+%Ye<4&D1Z^(GZ7~Q!vHNy3BfR| -z%2GnoFrdIvf&?G=4|A~LBbyRz_(&RN!$;CE@QV?O!`q;UGEwaW)_sBM3o-Po7(7v( -z608g;7=~3@8Bj0`r?WDkU>MNB2*u%T!LW&x5DddgEF}cPuqsOl!7%X1QbI5c1u#N! -zcpDT^CaRmjf{&zOED#Gml7`{*hT)U2so5W@-y(iN8$V?1dF9!B(+fuVJglsdrB_$6 -z@-I8sO2`|SuqsOl*4~ny(pDVv|JyHFkcS;$qT~v;5|S%W{wyUL&K1VPM=*?rgwX_= -zB1F`-1Xe>b{gu{n0;A6NP$;5Erfz~@STGDs)+xctfP!Ht&4LfDAsLMseRN_ep^}37 -zE)ON~+k^&w^t-=p@*f4mf?>h1p7LQeBo=%G!&pg-y59bcr%n8$V7OKR*&BwHSW2+q -zBWV~=5Dc@GXewou;!=Q)E3J!b7#p3aZi1v?Ny9px6AZ%>EF}cP@El7Cl@yds2~f~b -zC0H4d){s~arf5pA;6qbF9?>Csv6N66lfh-GFHP#4K`>m~kR%PG53rOF45KDlO0eKV -zYe+2k(3B7iLjjCB?L?u7GEv=x2H_LgspDfczlpe1)9>iNRGzWH3t=TJF*G2@Qo{IfmfO2pQCRSi+dCu%!7y71 -z!LVRhr%@=1z4IqN(hEg-7F_{9jt;cdaN -ziIflw!%8eA1jDc@O9{a+@W@g^FboASLUDK-6j3Iso4|sPq+u)&3qF#D;dB;!Bn<;P -z7@;`4Z6thTZx{kLgyDou&HhmR67dV#_#tEO%Nv+YZE=c=e|H8kG!(%2J8?|$$A%1T -znvXKc|n!3 -z(l8r7l7@j_j8Gij21S&KYA3Mn3shf-pr6AfDT3| -z4sQ#FO{9ci7*=8_AsB{LSxN|ofk&1Sf?+6t5sJgxpolV2-2@hVBn@MMSn!cF45zc; -zBWW1W!3f3SZ6o0$d&3Y=Fw9m$FpQ#QDbWCiC;PYjWA#hKpI6wocleuWC}MgD)p$?d -zz(j;(DIu@^0CFrPSX=xJl{RPsZYxTV!c7{V4Du79pzxUM=dHZGY;P78)>?Z<+T?6RS{1;cD51jC>oO9{a+6u=0@ -z;cbLDWum$Xf?){AQbI5ctFn|}!AH_Cpo38zTa?4~A0}zIwmMkwku=PPk8Dbyx&^~* -zB?QAz03#Gfl_Sh46V*)+3`0Pc608g;7>3gY!)zr;@R3)4*zl1wj6NwCW-B2W77Xh& -z3Pllk54_WzsCI(R=cqj#3#EHmtPCg^hSGvzwi1G2R5wcr5_}{LqdPo^VY7vEU#NbE -z_>o)MtBp#&Rs?*|&`q@L1BaP@&1x>1_4+qW3CR^G -zT9y*5ZYmfCCon!(<;vnVjmYxMxmG~IF#N+(f(0L1Ltni7Ix;E|<-U>FKugyM)8 -zpolV2-2@hVWS0#KBp7BZ!GaI1A+a(bO$icwWS0%}77VkM5DW{3b)u1A7@lA$p{ux3 -z{W$_=ly0q+zsXmJ%%ZNE!xyF#`8kQPhqy -zQSAiNovGfnNE((jtYbHp_y~r9d5ma$SW%E6p7z$uSHTqQbI6{ -zl4dDEf{#WpT-Op<@S)uou%5KilwiS!ri47~Kx<|xp)@8`p%Od6Q*Q6#k=2k?UxsSYTj$1#Fog{O_&R_K$8)sW;79Wc*QLifRx|6t3fYJL-Oo{#gQKj~X<)i%-V -z9Mxx16se8?^2`|mvXo$T)Bl>Gkra(HnnwPevm&6;-9kB&;@;Zl60*xy3pZ9bm4D~V -z?xuoal(cTH5Dde6rcy#M3G#f?>82B>2ehz+}Tm(lGj@ -zV3@6hU|2A$(HgZhS^F8hEd%tB}nj*G>q;b -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 -zNDLNZa2nn%nl!v^ -zstzS=5|(^Q!?ZNx={AgQO)$>xHsDObkkT+UVUaksCP&=A -z$){uDKH*+HAq{h5Wsyk3X?W3-mVC4gNs>>G{@C&<4cqeRY#6zfhHVmQ7y^tCr_1r_ -zm^e4V%7AH@1u6~OB+&40-+%c2^M{Dv`u^p|U-{L^8)mYz);6T|+@aRm74(l)(0rdG -z9e=wLt&e@Wy<@E`5|Vs+0+a4Y!!`*^KH7#vu1LcciIZnE)+!BeNOXHgcCtv6hS8%% -z!jg}+AzAX#NTgv1Fpe-Zo;Dg~j!?!mE9P4A>6DEHvgD)P7nFwSB#T5EraLSWYt%QR -z$uW1-#_cbi;-6`l&C4Q@hV2chG>i!>5|Vs+^v9M@Y1o!eY1o!eX&C)7LY&&hB4gt0 -zgwpVarIi8GFr``=wnagM&};1&9?V@rZ@#nOx{ -zvTAMxU9Q-zlyb#ZUzU8dgw^dG%CktMVF)lnoXmXW)^EwDQ#KZ;+dG?tB_C}=vNE7X -zLXuCPIb-iMY?DaCX?T&H(l9k)kysKRT|Q#%VoBCcSUqv>_0w<~Mw43-9ZJ|FEcuj% -zu^;2Iw$m`ReI$u~J0E}+i8M^9S|rjidbCKSVF)lnoZ7}BW8&NdOFr6tL5C77wMC+{ -zVVcS!ajNFM)bnY0(;Xd3bSSat4l4tuVMtr@NyBVNj1V7P-q|p|JB~zY7=RXupQwi4 -z{QC2^FCHTP;Oy0>pZV&zDjWTLM;}YAZ7rjgu&kRJjl@s1pzo}`JIe5we_ABU6|9Oy -zLXuB^irC&w(=fr$l8?3_S!YWc2}?d2iBTJL;Z?Z{wNgiG=2|4uFa#J6S)FTEvNTM2 -zTO`sj__Nc5xxH$E1LKB8l5wn&VPi3qT; -z$idH9SsT(IaTsvqi#^PZ~y#jH3$)TL*6#KZb^1 -zdH>=2&mSUw>-(1P8T -zh8IoS?Hx5?kysKRVe43XobHu&YN9mEhG&sT!)bV@<-A*Q?Y=;gk4Iujd~|sl#&^e& -z=+PelS|qF^er-eQP=cDUNSsb%ywmO0TpHexurgquIola94b#$=e6$V8l8;6r4MTvD -z+M~;l%$R8yfEI}kB`8&kL>fj4770l{9ZJ~pDGl55DGl55DGj4vMu=0}SY%9`onYM; -zOuvz}Kg#Nfb0n+`n1(4;D+8usD*Yk@zW@Alk6ipE;&0x3?cE3XPb|XGzNnxF%L8*gFl|B+_siMw43-)~$FNhBPC@N0%R%R>x(hd!?P4NW*CuO>Rl_ -zAiPZ?4O4R#iCxJJiSDTHps$YFIPCI$m!;t}oQC&whqWPD@+l3ol8npRK3bk>ctgPY -zWk_v9>QDmBTO_O#(KL*77?0Q3;uWk7Y59Fd*cw05;*G4GuzKR$>z9U0!)UTYi64oC -zB_C}=lH}7zba%?2! -z4qHB@VOu_>VOu^ON}yjxh*R5GWK5i$(An^YrIi8GFr{i`z%)$HTNyA7qhCgdQ`>3y -zL?qHMrDTyv!<4E;A`PQQi$ofR03*byZ7eb-&P}l7QyON0Ecuj%sdP&|rD3GQ2ytrr -zNcnU&48XIqAAa}zbB|p7CE{=1eC^!_9O6BJxh2k6K}#gc6?e4u$#gkh^iA)#d&?C_ -zpB9xW1S7y^tCr?#=km^e2f -z4Fk|3Vaca7Or=}$DGehXMu?wCKBZw>J{?L>s%h9Jk%rNuMIsGDfDz)B^Zb+7VI%Q*hyS=kXSQ${;kkT+UVUb9~5MYEj -z5#z{hq(cb+S|m!tl&VF-l8?3_4Ieb8Z=z@4u`=iA{G{@+l45^65~5?oPut -zi8KrWMu^kpgt;+sZbBLcphd#UfN7XYPs26|Nj{wo+wv(5vrndBn?xE;!;6h#5TW+) -z-E!jWgvIxny_|(wzAY;QreR2@VVlI+U!Hv8*2P~U{_c}!KYeF>zf-l|ws#m${QCX5 -z3EXIrupa-`TDx39O;{wP-L%^~oLjE2Nt7$}T*1b)>JO|;1bk~lvOZ}|!)!>5qxR_X -ziPgVyuCyVgVHU_Dk%rNuMIsHO42y&$pVF``pHA6q`E)2@%cnGqeii`)ED~v$Qng5=Vf1K` -zNW&0dggCX0MaIOr36^|H!z_>`pVBauZpo)KjC2?wPHi74pU#E>n1*cge{bQ9ik#pr`_ -z1xBz)Si5PrcSyn7P17)*V1)RIcGGU}Z25G`MyaM@n?xE$j~0nE3;{-nQ``7-Oq`ow -zWxzDd0;OS_ge9NSFw$Y1bIZ7V|7AUax#^BH%syt3NW*D(;UP;t+J=;dA;7p;(P5D> -zac+VopVF``pU#G<^wO|R;%Lq6vy-(U4I*?QVQb$TSvz6%M3!XT8%V<}kVT?2OeI<* -z(l9-5k&xumM|8G)O2f8%O2f8%IvYm6j1Z@`vB;P>JE1hZVQFQ+G)$>l888iRd;X)B -z9=z}TA>tQ*`0%}t{$4@jMvFuRZMU{{Q&X-WPcY8LhS6N(l@_m1t|(XR)vMauH -z$A3NepO$<&Wuv7#l(0!y8Bn_~NW;{GMdENF?mIr&8kzB6;a>gvX}GgtG%065Z9_`K -zNWmf@$)`tuZ26Riky~llCSl2^G>m>3(LF1QMaIP038mo;%hE8VWRXb2G_6G<4P!rx -zL>h(wBgCm~EHWm}O|axs8fJkk`Sb)Pm2SzWG>mi@Ax>={DW47{wgCU~i{%ED~v$?zTus@+l45^65~*mQRNgwtV`C4*fDh -zoZ7}BW8&|h(sEulq?cym{L_p{PNqc -zUc7jQ__MQ*AARh5Z5hiI>N1{p;n~psX?5Si9<%*KY$HdtQX?Wv_G)yU3BrN%q -zhUxiE*=!PN7y^tCCv0JnF>!8!C7;qT3zUX!5^0#8w@66x>CqqTorY}^X*dm|$t?-% -zRy++uni1lo%MVPeqmg5@{H{SR^F*bSPnGz|Mwk`DhzbX_)S?NLU##4YMIJjxNM^2Ss3Z -zx&QYQXG8kiAAbI`^QVZPI{WLdfAhcIGFH&EHsc*Ddzyb*t$m`mcexL)_|hpzbjpTt -zEE3jDO}T>lw{B|EFw$X!IGLH=853tGq~Q%qOFrG+QL1U!CXt4*pG6`KLx2(D)b^1Z -zQW^%JMIsGTsul@LKBZx#!+2u(^kIiBpVF``pAIFELK?P7q+tj!LYywgr(@#W1Sf5^31pkkW7(UThSD2(?F-FDK4USbU$^%UP)9+e*VM -zkVPU5Q*#!HG)#9}BqaHihHd$DC}GQ|Ly2?w{Q1czZe9E(;_p6r_S1LHyk9G;pety0 -zJDY^HoA#MAd4h4dqHK#};_QT;z}$3)byJguZTXZd==n5klSso5V1zhbe&mLfh5=}i -zu+Em!Fs+b=Z4#1vI%TuvQyONUOv5&bG@OPP8^s_(?cuxS#Mudp?=yQj3$=V(Rt8MN -zkWRxki8M@iTO=g;l!nBA0N -zK7HnF%coN|q>zSf5@{F$j1Z^G@#&a2H^It)X_y7FGGH2}($la_LXuBu7<;E-n?xG6 -zH>5P2h8G*fAVTfY<;#h)6BgfR_Hq_#`L@z93uKW9ZJ~p -z=}^L!Pan~tUq*;i+gM~woSo34KO2@-228`0s+9rLFgr{NQkNW+wp -zMIsGTssf3>{o&_7JAa7ysk6WS`ZxbLe>~e-#&U(Yj2q4O3wGPvigJZbqFez1Mu^kp -zY>Q*!+=Mg?K#PR1o2KEN5Bt(EJ#Uea86tX3s(lGmE8n#JT^68Wf{W79^Ruqej -ziL(>>uw%nA4O2=Mi8M^pS|rji_OnQ&VF)lnoZ7}BW8&NdOFpGx7RZuMXTwywC7;qT -z(qV)+wSA;~I+Orl8n#KKVVc$=k%rNuMIsGDfDz)tC -zL>i`4EfSV|O2bHp@x=1!l+Bh;Y1o!eA9f&xG;EVd!w_JEI9-lU$Hch_Rt8MNERdA} -z(=e5uhHVm(d`iREI}O_;(y+ZDrQtNZ*eC`OYL6~oPMn>v_&&3jvrx;om4;a$i$ofx -z<}4CvnC`YnNb)HS+w$p9!j?~m61IH$hz|WSLY&&hB4gt0gdSMiu(UE@8m3gO448)h -z^NTlLf9m`h;{W;b?2B6uRnWT@v|77@wp-h}sVP^GCm3gA!;QhCT#<%%t11m|!}{6L -zp`BM+#C~f-O2d%0NbFnDqbns1r{Ph(7jZ2Or(trtOu~{+8m6Tgmn*sm2J_p9v>{pY -z>6DF@wlZL+Y&4aX0k!*rG)#9`Bt~t}h4aFtx^`b74Q~io|8q8NLrTLGvPB{dqYR6L -zB%dDrVRtAE+axUcXd6;z!_L;$*ceCo)~MMhXTVbsRaue9?DX&C+% -zi8M^5TO_Oun1+!K)`oPIc03zaC7&l22#DwtPy%6nz@DNl5bP -zP~!jI{QC2^FCHTP;Oy0>pZRKI{tCK+UbNgG!nVTQ!*b&6gvIxny_|(wzO8Zv3uKY7 -zZfeRE)N~rQNl5Z3SJ?9D_KpoN4cjEra2j506oUx0hwqjXXD2Ma&+O$a)bedv888h) -zIt|+-(lFg^k&xt58fJG$!#0UDoQBclmW1_5YZ`_$Bg99Smxl4(aU^;W9)K1J>$yX1 -zL$WfUMj{QPM~g%nh5#eP)9_D(L>i`4EfSV|v<+zxAp(ppKeDDR5|VsAu}E|%K}feq -zbSOd7S|m!t=+PpPh9STRacUcjjEQp-Ecx^i9Sda1r$dQX-hcT1^M{Dv`u^p|U-{EE -zm{rgi!6H#X+pTTwrrqALi!#n_mgDmMmvwu$=?+UiBY^X&8VOiPA8oYLQ68^t?qvl21=y+VUw4+wv(5+w$p90{t>VoZ7}BW8&2reS*C%7AGY{W3zF+D^kKB9VqEC5uEFrc^BwX&60PB+@Vh7$Ht=W05g& -zZh|GB(l85T$)_|-rCahT4I>>!h*R4~%BQno0H$G^L>i`PEfQ%MJz6BvFa#JOPHkh6 -zF>&35_n&|6k&C}X{LP!Mz54*ySj$+hVEGs!e&jOVUj07o*sv^DP!kpjYd7uo4k@Hz -zn?xFh03*atv>{pY>6DEHO2amZG>jB15|Vs6WwSG28n)$A8n)%rp#=J6ggCX0MaIP0 -z2^~soSeAw -zX)O|I7(H4f(l7)VAx>>$kuh=Agg?IY;C<&$5x@Auhwpv#`*Dr6jO7ZJk8#y1%`9#o -zc5GUrT!9fR64q|o?Hy7`!#0U2wT_M&7U%6<-h|U|8s06BG`!uA`l~-S2}?fOhBSz* -zQ7iP;%(Y1Dw)TqsVC|b;J#p2KKfbFapFZqh>n{!4Buc~dyhY-+FHUH*^EaJ_OT(jj -zFFavwNNG3?qsc7^OFn5B(u@!vvGdq%LVMtpf(l9k`k&rTAhY~o^l22*amXEd}^${K2VUe&h -zU>asaVjNwF?~V;|qc)CyrJYwu!z_?R!pea6xQ2iC{Bw_7{3YUV-hA!d2X1$VwT$J8 -za>b50-|T<*HFmjj1>IqhxKw+$;UD+UBQIaJ1aB)1+a$^r_J(AgEp>Z`bQt$pWK5i$ -zkcKzik%rSSn%t7G&X%+dDGg&ki$ofR03*Z~y>sY>l!nvrqLk7wHDQskGGH1;kBrOO -zK2(!w7)@?T^yrUG!jeyE7%8M-n?xFh03*bgJ{=S1CZypsyeK8>R$SYV(l9-5k&xu` -zNrw`p;UDR~pfn6=i-aW~Z9^JF=)wat)TPTT5@{F$jBI?=_K_=D8U~<6!jeyi610LP -zpEQhg7$JTl`J6Tlzwqr>FJ3%E{Mp&Zk3RO#@#eK<)LOfOrqC=BKZ$}KpP>Aw&zy&G -ztWV#20+Up4k?53-tZ9+B-6eOZ;}ri)!<+7~|Vhb5nG?`-*Wdq?}HVVgu6h5#eP>2ku{m^e2f4Fk|3VP(KHOr@t`n}j5vK6AF^ -zQyONUOv5&bG@OPP8^s_(?cuxS#Mudp?=yQj3$=V(Rt8MNkWRxki8M@iTO=g;l!ncxv^h(9~~_|eC{zjJ4=pou#c -z32QgKmkXLT+iZO03U)b*gtVJ>%0?ku@+nu8E0BXt!jg}cu&kRJjYJxT0OPW@@#&a2 -zHz5rJ&>~S9PQ#0yOvBWKMPf;Oboqgr9G9K$m3C^vl22*amQRNg6mn_UCLzhELkT+r -zrr|V<9BdM47}6GrGz>%sCD37LBzbSs5@5)AMQACXt3AzzFdZZAg}UO2aHr -z8n#KKVWeP@kmS>$1h*4u*d~#N(=eLclCW;Y(=enNAwIf%#M;G@tevoW;@s<};WUgU -zw>+ccGx0W}h7n3}UlOj>ZgoYU}zKz|XQqOnN)_iOmiPd;($;x7?@_sO%L -zzO&nMqB&6N6Q#M;Zeb`~k=N`@#qk6l&qmNw@OXAe_?sq@n -ztKHshs96~>4O5g>228_t2GnkJE%}s&sR_o>g-34~+gD(u_UQ5>Uq1~4&?1qBDOHPv -zbt|5Rkq+aD<1o&| -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 -z>qImSBOS)$HMV#KYeQOopAojkkFa}zB2 -z^yrU$Q&KXwL8!)X{f*d)?0q%9I@7y^tCr?&Cwm^e3~Gz>tCM28ZT -zszt(*PlpmnhjGp=i<@K6U*ll -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 -zJEUQoL>f-RXmU%!`YoI^3~5G)k1j6_ -zL1~!X!6K1{kI?X+pM2uh#a|-+?vrOfeP>N`SbM7e_Yv`D03 -zTG}EpA(T0}rQuC?Sn??i+wv(5+wv(5qhCgdQ`!W68cxHzMPqG9Rt8MN^t_b; -z(=hsFgm@Z0F$qgPrC~}n4cjErFjBBcq+tj!LY&$@^1dJq1JELohACBxge9NSFw$W> -zv3zS)c}#rIit4Xbm_>z6B7Ad5t~g7ULS -zq+uG}A|c7=p2!u8M_ZN~#-=+g`E+{+e@i~y-r4f$!w&Sz2ytqg2s0+mPUs2DG`w3h -z)`paZXyT*`emH8?2VpI!)bW8s?zW_+w|M{HVI2U+J-cU9G-h&y88+iiQU#7 -z+sWd)U;Uo0{p$7q_2AdHJ{?Nf^0^n%@ZbLM^PinR -zMEum*Uw{3Ze=H93uMQs8ZdyTC(Cl_L32Qg)_KrNkxLi@T#W8Vqf_0-i{YKXQD61#V -zkx0Xol10M0sks+&#k!(T!}PpGV%<8h-O^DjmM;x&s9EwU4O5h9*d}4gr!s#{aP=W=rGGJ%Jw1SlZwGAl^(;XIxQ5$sOk(#uRXVNeW -zWRXb2w1Pz<4ci-%lmUAJ)0R(Z*p^Re*p^Re82vIroZ7}BW8&!zk$VaumnfqoewPHmSfPDCON -zQ%V+zG)$>lB&-aWhS4u$8kR^{@+l45@+l1?g*0rFkmS>c9d-sx!)X{f*d)?0q%9I@ -z7y^tCr?&Cwm^e3~Gz>tCgmo)k8m7`M`E)3ObQmFiBKeetZTXajDb+M=lSsqp(ISzC -zA;1W6Y8#)9iE|UI448&lpfqfgu;f!3MmmghZW)*FzpMw=Hr%eZHuE-&BNc@Wtqhok>3J&yreXBU2ytpV4WEca8m5#i -z5^0!HwMe94^k|Vt!w_JEIJJ#M#>BY^mV8RXERZFi(lC{7$)_}obQmE{Z67J0&V~V) -zhHVmQn5MNzq+#@Ekx0W3V1ziejYY=9xd~|)fEEc$KBZwQ-I7mf80j!V{6zA(`_u57 -zUw{7g#Y4m&oW1(=GhYp$*MqE};bW1gpdr8r@e{SSwVQUz#sZZqY!a4y$`we5@x=1E -z`*X$G-$+Trpt4A$;WWI^m-XDCwjrfq2rw>IbXa6eoSR_Dr!;KKr&Bg6y)|||7g9u$n*xL6-)=pSGktJF82GTGKWRWNhQ;8OdG)&K1BqaHCC}GQ|G;GVKG;GVK -zvtjhh2yto~i;Ri06H3DymR1H#!<4F(0n;!&Z)LzVjD8s*PHm^*6Ol;6l#)dv4O6NX -zi8PEJEfQ%M0*nx+wz0^VI5)wPPidG1vgC8ur{P!LfB63Mhlt<${^iGC`BRVn%>G$k -ztF=*=ElT} -z3GYAu+#?r%iTIm0Uwij~b=Ul#cf?<=VEGtVFUj@me0%k~z1yHFS5OlciE;%!X_2sY -z(=?2J8Pl*t!jez7ceZ>wWkU*S*d`&#r_Y@2448(~FmkX-q+v)~B+@Vh7$Ht=NLi|MXDGl55DGgJqY1k%_hS8%%A`L@;5#rP~J{=S1 -zCRiCT4YNRL*d}4gr!?6{ -zWK5i!V9BR6Y|G~^KO27G>(Af5c!v0cvsa&f=3i`?oIVfDltUukDT8cxG$c&8<9 -zC$}`b?GDC0obEt2`A=&@I{iC!Nu=R4oQC(DNMS`E)jn-1>;lCSje3rr|Wa -zJl257o{f9=X5f!6J$T>wQ^YU+@ZozO{eImw=Vq>;0cnw#TE?+ij(*_nVYb_4((T;_ -zO1F2^ghirULHAiCEcuixP%7hopN=*f*Q}bGhSTtFrKI8QhGd;BrC~NCOFr6$bf{%1 -zsl9TxNbI)u+}3dIo4)?P?*BorebN7D^68Y#&VW6ENzs>vZ4x(GZgJk#)oz}b3a -z{~a5WB_EB%f5np$zkB|D^t>&?EI-r?GMc>b6Ks -z2<5tky1c06iVc)BOru*Q$`y2v_&&3jvrx;om4;a$i$ofx -z<}4CvnC`YnNb)HS+w$p9!j?~m61IFg8%Dp35T~}W$e1`g!8#?Mej{stl+_dGNLU## -z4O6OC228_Lx|IRbFw$X!IJKRIPedXOQ%V+zG)$>lB+@W?v`D032rxpN+QuSd;(z|1 -z7ry=K#fyiCKRf&Q(Z~L|_+ubOB9VqERf|L#rqL}Dl6?Bi*_Kaf*p^Re*p^R+ -z66lu^;?y=4853tGbSSZ5X=T7POsQHKFb&i5Rt8MN=$8@V)OH#^5s5TRDOn`aFr{jd -zNWNNb(OAp?6{t)qtKYaM!M}MEGZEG33 -zy~8*av`xa=O}o8g7iFB=EXU>hFY7bsO?RZ>as`^)lK8LqUmPsn)3q&~hT&t8NW&0d -zg!oLIUNbihr{P6;q+x2pB4K5~G>je@m$iNEcE0F?E9Z{dxbnXq{M9s^h8N{$$wxb$ -zu`-}WA`Me>7Ky`!ICAgRN=?HX0{wp%sT7Mu8fI&@NLcdGHl#s>+8ePGpMq?1f<vyWodYW%92k{ -zN>GWGd`iRgyd|H~F#2VLIJJF~WpA92hSTtFRaqNS8m4J25@{GcS|o1v>5am@dcs|- -z;lDij#I1|JMEu<+&wl#OXo596m$i)L3d)d?#z9eQR_EHecX2`Qy`{a1nzfsDdq??M -zyJ@#~RC*e=NnELpA!)ul6+a>8G`yjfhAA40L>i_&EfQ%M5n3eDFa#JOPHkh6F>!8! -zC7;qT3uMWsG)$#i^65|l=`cc^+CEY~{nZ};reT{z8m4J25@{GcS|rji1Q;PsZDWx! -zac)8y2B1a4l22)vO1I=w8b&&d5I>Q8O2f8%I+UPP)38k<4WmbkL>h(wBgCm~d^#r1 -zO|UXx8fJmguuZ~}PiYwGFwVJUT)zLZo|M>hM;c}yvq+@jX$}AK+pk`{c!v11vyUHr -z?E5wStS@7^VtN_rtQ9)GnA@M5*rF;|*d%WIVr_9Qer;;sW#x);#i-tkqA6Ew_W|o~ -z-Dn9b4X5G7Mlp!2-47`Ky&J}M0^^Mn=O$S4DGgHq-QL+G(l9-5k&xumXU^OKr(v5! -z8cxG#a!bOx6;H#EW`y|Y@?~tEop8EW+Np^&oQBb4hY~*$i8Kspi^Q(vj&<)H#!SN- -z0@epp+J;mbMs5}f>sDMlCAZ|Gk&xump@f|QI~%s;qisliL`Qd6B+@Y5VUf5qz}}H% -zkN@YWjZ;Q!F9W9GG`uX;((tw>Ecuj%sX0c7v#}m6&(*K=w?F*+XXj55KXvxkU;pNR -z=iW%ScPx}eV)ZieMzA@zFZ<59tk#}>BR9U&?F7czAM}RT@52r%#Uf$trrqAr3YL7j -zy~7@i5MOKA(Olz|7O#+oH!LmrbbCjsreT{z8b)pwiJN_Tqj0aDkcQLnsNM@tSQ}Cr -zPQz$&OTv;*8iq6@#IN224*2RJ*DO~5s_$yar!;KKr$Y(K+sc3)N}vozh*R4f=#7c9 -z6RZts`i-ppQC3f!BawzFC5uF9n5MNzq+xpAA|c7ACopaKl!k5jl!k5jl!nnSBgCm~ -zEHWm}PACm;SXvn{4O6OC228{Byp;jdF#2VLIJKRIPedXOQ%V+zG)$?kCGqDcpSX4L -zmx#an!W6X?Vl3 -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 -zsVP@b^l8{8akEcv6z}t>iIOh -z>5dL12fkq7Ktl-dToF#x*PETJq^5IuwJwpvx5$+?GVS!X{ze)RZgO!x@*gy~l!AyYZ^8j@r2LzaIS6 -zG@ORh@SgUuHl#F6%~>S&t?1G6Ov4)jeb_-MStKm^Xg9jn*^)-Wl8;70l21=y+8MA@ -zHZo?XY&MBB%+_p?NW&0dggCX0PshZ$2^~rR&?1qBDOHPvC7;qT(qWu)%eZ|1W!8Pc -zHQ#bH{ED}CdF~Zo+W*sCzI@+YOFpGxTRt61P}6DHCNUwDIk~0bjVID@X_yUTOQN%3 -zn}j7FZ9^JFCM^rdy_Z=e#>TX$?Y(d0#&^1%ztEGv39W}YbUIpIQRN#I1Qu8EeY$l -zaI_7{%77Y)G)&D|BqlAmUe0NFL%=!_)i$KkFq*eWq+z0$MM9EKhZ1%M>}=SUkG3I| -zhUpHAgp~o)FdGu%=t6wAKKHV<(Z`!t7`1WqEA6~OhY~E1MZ(H}X_!K`GGH1;I*btC -zRnrk)wKk+<-qSF``0?-f0k8kBcTAl7rzM}#Fr}J?Z4zmip0`Ly^0_+>CI0q@pa1Oq -zDdMNj{`%|R{O>6OxV4Ps3JRH##z9eJ@-cCCLb+nYvRpwaStQC8G_6G<4P!rxL>h(w -zBgCm~EHWm}O|azC?Hvnb$){5`D&3M#X&C7+LY&$@Qa*Rb?cFJ$q+v?QB9Vq^T8l&) -z#sn6LGz@M(=l;wf|UW&FbkB1_mlYZlTX~b_)Em!ee&$5?@X5N)fHbsV+4yt -z1--wZ2mGsxbLCg9-L%^~7Km|fvmBT2zpMx0H{D^$r(9vnr&Bh%I}O_;(l7)VAx@VQ -z=ElUi327LB7Kzd@rD~B#!}PpGLXuA(cG&VM4cqc54cqeRPy+ojLY&&hB4gt0gbpP( -zEUgTfhACAm1Eyhm-pYV!82vIroZ3#qCnAxCDJ6?U8m3e&5@{GcS|rji1Q;PsZDWx! -zac+VopVBZ3WXY#AOr=}$DGehXMu=0}N6M$OVF0FKn?xF>X)O|I7(H4f(l7)VA^!jV -z@{QM@x_F5A%d;R_EH4?8A-?pK=A=ZIQ5c -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 -zijln+>0vdbdCxkflTzCg&_A!Z6isDIvip -zH*CYFO$i%5ZA#eiX>S<(GNL%S4Mj%aY=E^(K7Aqkew4if=ajHKU>GJ1QbshJk{mgan`NIot5b4cqX^4cqW(Qv&=lqByw?MMmIkK${XPEiDfi -zhDlY+1BPL0-tvH982mD#IJq5$PozW`CY3BD!Z4|7DG`RjqoqU`Mgc|?C%2)<2%HPB -z;FB9>f-LythRJjbKDl9_!-(SK_L1;uZx{i?u&qQGrf4lC!Z3KWlnBEpz=-1HHWV3w -za{*x(0WBpg_}sm2_?dry`_jcT#D72g^KX9p#uuYitK|{)Y~W4QsNTw&s^T^v0Gl+>x15Y -zrj5hGa2O858zphm#90l=f=?J`CK;Exeaqw?_TyDNy_q~yKZfBj9ENw)Oc-8Q2jdQ% -zriilvDyt!#{z_dX!f+T4!#h9{hF$pd=#LGbZqWg^ZqeCFbc>EQVkrTRc^_sJiflOC -znOAeeD=l-wq>`mX7^Y|~B`o;lhCwQ07?zZ<;FBA+;dA#sfl1>VReof3hhYS?l#t+a -z7jH^@_3=XwoIgc;{p`z^U;W34Zv|S@n6Ds_87UlKeKeX{-nG2j%qq)aS&N!{1yBgX -zwi00&1sGBML=DM;Ps=+dC=A<5gkhjyDIvk3INpb&;_CBiTYFrqkB4o^qmT!7^P!!Q$MdB8ACriWo$2?;*A -zVdx!(Z6(66-H^g?7+y4rp$NH0l`jKl0~YTydpHxdysR+H1X)UiVRFt=A`DaAmJ$+t -za>F)!+LW;2bJuQ4{PpRlu3dZ+@eiLp|M`0ZA?QVB9_U-FZdyV!K~^`tYZLm|l)Wv} -zt!~;qXXc6#|3Ypb37>og0)}B*i7-sjT1tdr@MtL!hEaeK#mQ|bG6LrU!Y~3_N?7p8 -z4U_2>d~(A;hY`h31fSfn4WBk8NYyZGD-njlqoqU`Mgc|?C%5702%HPBJYX1Rg2J$^ -zgax16FwkL~W6L;v_hEfW%BniTFn!EYA`FM&1&1v7XbmY0qX6S#Mh8Vk;9P(OpWLtw -zpZ12y^xUwm#L<}9MJKBv4MnIz%+{_8**9SCK&E8B3kbtZkflU!m`t>k2*cF8rGx~Z -zyY?2{GjG3j{o*0wZ_d8H_SkD8kCqZ)7zG$noZN;YBXBOjf=_Ok39{gm -z8z$2&_~eFx4kL<_+egCZuH9u@{7;{u)4}?LVN%IbA`FwYmJ(r@^0$--!zjRr;^a0I -z8G&;F7JPEUOppbi+%TDL!6!EibQn>b+&&UMxnTqh!?qG(n4-0m2*cpfQX&ka03(W% -z+fZZ#&IN>F1hkZ};FB9B(=GVqhJg+vik}ERxnUbVZAy@;VR%!CuReb0f%Aumub+MS -z@~i*qX2;op-H9QWuUJFw4A`AoX{)sJ6_kRdM7{zA7*QNpA6YXNeDW1ckOd#DA%$Uz -z%2LAmE1WP49vMd!9*M~?ybv%qOioxzSn$yrlH~z4CBiUxw3Gj6OQv$bbDPh4!Ye>0aa>7!=f=?KxAu$dMK$VZ( -z1v=O5t>Mzx%YS>|Nj(qP-Z1kUhHWJ*4;Y4l4&%X?8E0CY!D>j$_qi0Ui)*?x_VVA( -zoM|K0@_=F3hEHyoL=MBY5)yoR0uz%ShHWKs!*)Xo!(n*QD25{B9#y^!oDH~mpFe!~ -z_`~N95x?`}YfrxZ`^8(&o{_n`&&x}$#BXBk#42R*(qzS|8qO$I^hGFn!!AEOIVHgD%XZsDswWDKM@abj;j=}PP -z-RvNzbHlb0S5ah8iVGq6ud>TlLz=#jE3b4Nz&QIsuQ-1gCQ~dW!Z0;yDG`Q&f~CY& -z6bZvn!Po`N{zq~|BgSFEZd47bY$Cf7<> -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 -z__VyU;nVUC=rE!_|gan^_MZN+! -z*h=IpP})+$f=@R)z%L`XXGW==5jY#r&5o6pxnWYtQo@2yyKK~a7`BxN!zjRr;wNfI -z7JS;2V1mN1twb0G3YHQQeA<+-JzyBN;gcJ-;nSuB_+>Fc$ZkXz3ysgTQ -zrN_vPqtCQ)1`9s9VK8qk#kGbMhQsj4-c@TJikuccZAxHG!?3MH7`7XdwIixEq}(t$ -zVJWfcHIKExw{#z=A%)>E3?|n~7;gBhj~{yA{3+t=XJ5Yj>OU^3u!LSI&@LO8w3ILs -z`r@K3hn24&CoCl-__VyUyJ@>@bZZMfVc3R`){v}4O&BI87)KStyJJ^+QbTHa#{^kQ -zgkifOSspM9106;hA2UkrjKJ9dt07Ha$i5$C@4z`FEcoPxN!2iHD-njNc}ociK5a_S -z$HK6!L>LakU~;X5R$gS)k*#HlekKA@yT7!Jcf6MS;RC~d(f41-@r -z6dzSSczU3nJ>8i$E+7nt;V`^W5;rTgn;q-wVBDe8Es{qMU#Y7^7!Jc>cn3Yg -zunV6agty_--y;Dx>&BFJ_uYbzrbPFgX(N^r;F$Lzx1q?*1;pf!x#5+TxnWYtQX&jf -zw3ZSUe6)sS!ADaf45I+!Y`+FMieKvp~wiF4ag0zw9E~YN|qA2VT#sL!t#J& -z82mEMQg#&AIMd<`VK@wL=0q4?HzaFEGz`;_Ecj>*>1v*mJUfBAJ-||8v$S_Lf$i6H -z>8qFjcJ||sx3b{VriASQ+ms;bbHlb0H+gYFqMcuK7|sok?7bkS)sU>Eco??fqpb@p -z_-G9&45I)exrf?IlN+Wxgkf8W -zFdT-#Km_~eFj!@$8-A`GLnr9>D; -z0Y(%jx8dmsoC~l#U>IhCa>KR~7JS;206L6wY#E2|KCDfNRds}6`k19e7!Jb=4q5Qg -z8d4ZW0mj9Q4vLJxxd013xnUbV?G2OZxnWz0qcO9KPF6!2icp1^tz8$gZ@}JxOv!#1 -z5Qdo`ONrbtnP@2yhN*c=2?;*kqO;+X8@Az-8@A!o-Z1!OL~(K(ij2V7fV;#E|N8B> -zuAe_c{Ht%yzP|R@`1tvXbs|{Pn6IFs7*YKA(p#T_akg@=xBzQWldpii7JTv*l!CRW -z$yY!RMieKv?-yTj(>O^=gke(2QX&jfw3ZTK7*1G9NbqTw&4y2I*oIGT*oIGT82mD# -zIJpf)M&N9KwLLR^A^U!my#wczusmQGCRHsD7>3Do%L9gCpu>pbLB-mJ(qY1sGAB+=e0}a4x`tPi~kAvfz^&CetnW~r6a -zJT0MD3iJ=ZV3(zY^~L^LXN%KQ~v=%jCmWY)Ui^jEt6tc)jC -zA`FvCmJ(r@qP3I=!$84OLV`~iw&9Z-w&9Z-w&9Z-2EU9bPHsby5jY!=8(wK?dB8AC -zs#+c}3{&%#2MojDml4Iu?J#^ICBiVNWGNAbNmWaUFbp0oCBiTYFrqlQ4Mj%aT!00i -z+%OYl!6!FNrd#mI4FerU6eqWjgwNfwH~jjCk3W3=5b--dzV_tnf9cVm@dddgg0;7# -zmG*s}(6`jFq(r^~Hd;#LE8vi&M7{z}SV~Cnxm$b%^8Vk?EF~=Xw7j$7)AEk$u;A13 -z4*W8rIJu358G*9_*1BN&LiYVAdk4-b5r#=6O9{&ZhG8;24BJXb@W~C^@W~D17{aiv -zL>Laki$*aNA@|_jGH^Cv@jkPMGf~USvOHiIM(HqYD-njNZc7OXKDlAKLm0M|2*Y6* -zOsx=TVh7^Xwa2VbJLaQMy6+aPtdQt*b{dzRQ^9E0`cliF`%AVo`nh3Ub0yVyXD3^07`^Ov%0hdk4;) -z--1ueI~zXT>>$%y-q}h>@VPsdcf(?zm$alr7|soECYrXlq^%3Wa2Q_TaVWCL?cDI- -z-BPkSsd@qv0WBrE=S-?vN?1#AtsxCX$h{4Rc*Lug631K9yro2&5>$t!#OW}`m9BHbYDmlX -z3BxFUA|=AG-H>v_q^hNa1)nesei=^;pWLtwpWLtlpFh3w=!54^5x?})Cm($J$6Kpo -zydN_=YUrriX_u{CwnZvg-L&N$O6MzVC2l3>Nr@STR|>SeqYqn3gkf5DG!<*e9 -zH=G;J4Ug8gSsh_`T^)=&bix>Hs<+RpRzo`dmAXoV;V`@?9}7NhN}#j_pKf-5Uq%!k -zRoNW^MieKv!|)xhgase1Az9BIYD!q} -z(Udq<$__XH1xpDDK0W#ay>r915@DD=X(?gBCk%sMMsUxJQadAXHsEw;+PIeXhS@8z -zlxS0eq_>pF4O7yV5)ypwitnoWpBG4hBOqR3WwQ(r${y#U?~xXQGoHtiCWHYZkSBBlnBG*oTY>XpD+w`7*7nJ -z+^`Lw+^`Lw_J)B%7`BxN!zjRr;#4_29f5NJmIn;OOpxUP!!Vg1hHWJz_~eG6cNn&n -z2*Y+m3d3P|vr$-&fA>$DvHRB3vRXqrA%=hV?{8nac!>D#XMg_9Z~u2A_Xg}}D;vK( -z_|+1cM`SG}?&pNweC*g#qDOxye@h7oK6k}mc5H%HQo@2yzJlqq;Bz1QcndB9UHbi*)p_OmFl5BfGPWc%ga -z{_2*O_Mq&QZ)L$JH*CWvH%$JAVOt3aK5a_So5HZIgyjLlunnKwF!*IeaV!S4GXiG= -z+LTyn8HPzEONlT{(OOF6hM}LOL>NW^MieKvp~wiF3$WnRrUVmY!6!FNrd#mI4FerU -z6eqWjgio6i2pEQKCBiU8Ybgh|GG;qh6Hb5SR -z!*CehD2bbeVl^ZSK3YSP;M1mr4WIUgft%$4yF~{)bHlb0VHgD%QJgA=rz3DKAUBMF -zmJ(r@RJD`{!_>T`gan`5unnKwunnKPzzzTH>8Gw;d=v2xpFRKidqa^`?n$L>b<+~M -zgr?isN?6^rT{fV@xSUbi;s~4#u=X3LFJ#}3vUlK|5@DEBvXrnEHFtrpSd^!wL>NYC -zO9=@+E$?jjd~(A; -zhY`ie?IYpS-Y^1&VOxnXOwn3OgkkV#DG`QIfDy&XZ74DV=K{ho0$NH~@W~C6=@xu) -z!$5}-#ZLsEJKqgI^Y3q8x_E~8?`MDh&2N8PP}VB#5}HJ_l(=sbnr>&8w$)ABWrMvI -zeDW1GeDW3Gml4Iu?b|3d8_=UaD=ot?sbnb;hACQ03Cjb9Verd1OW9Fe<4lV)gyAr} -znG<1n-H@!W91FuVBnv)TL%N!$B+pLZZV#}O*evZ`OGne7`Bzj4O8=$5)yoJ!_Yen+e(DtFbpQwO5}!ZC6ArOrj48k -z!(kXqu9Z01ExNBhe&~Vor--kgefjdM{}`pWejmn-bR6k^@T( -zSK13D@)hKqrNmP4QRT-H^K@t0$cZoE}<}D>8_~eFd_~eFd_~eFd -z__Qejei>1m+=e0}a5li&o|(RoeLu?Hfpbb&9xx1(s+I=~!(_VU0mCrRVMK9qI}D#l -zi7-qmSxSUqQq@u-41-5Yi7<=;j3`cSLy-|U7hu6BH_QZC@W~C6=@xu)!$5}-#mVg> -z;d96D4gdA&r>|btxqvW? -zfR++rm{hftu;7y$20Dy$Y#E2|J}fu9styZ2xnUbVZAwtxVc1q845I)eic{s7xe+)Q -z5QY)ZQo{0pVVF!0!?qFlLhix4W#DYU;(cZhXQGyu -zWqH6bjM8D)Rw4{j-Ifv(d~(BdhcIj_alc~tnYZ7%e(@0TH)mg8d+fi+JnV>6+9fnf -zTT0xo3BCA#YB&1#w_`D2-D%BN;IJ5nr@bluaX%h;I0kT89Tt3A-l23Dww16JH9h(R -zbQpJ0WCYFzSPg0VLiUC8-hp#Ugkk!mr9>DG!;6}<;G;Dp2|n$z+3?8?+wkepAK;c7 -zwv`COD8Pu~R5?5yfpYLL&4BJYC;V=v)*GjZ0VJopz -zd{p^?Zgm`Xx-)I$L>LakU~;X5^*=JThGcm_O^Gl}&RI%qLT*5G1APa*8irR2oE@az -z9{O7iDK`w}EhWM*>1`VSW4WMdpE^D?#Ck!UzP-y6^3mkti7e&Fgb1QE#-!R4kLGzzseC#bRokEl_Oe$GQgkg%-QX&jP0!s-AK4I8~Pj1+TPj1+T -zPi`3eGNL%S4Mj%aY(RU%D=jS#7=}qz%LCrw82-bDk3W3=5b--dzV_tnzu!{FTV9$i -z;%yixp<$z?#C@93)HCw-=+8|htZv%!4kj{gOT(MlN+Y@g<)HX -zFdT*#jbbQ5?!mid;B3I+eP$15qL!CsdB8A?(qY(EA`DaAmJ$+t?rb;w>$l&!e*O&c -zuf93^`r2b7i*EtCRod1xcC&*-W~6XH)Gd>H*pKb9t+dQnkUy3Z7JS-e0}5f-Rw4|e -z03(W@s3BSKX?e#4g<)HXFbotdB_#OV*~`1FJ93f|VK_GoCf7>zAiS-FwGoTbFB8NFq45Bo6;uN1KU7*cCUZAyT7 -zO9^W!9)^Jqnc$Nf -zM(HqYD{*Q}hG8(-ro_*r#3^pk-T3Z{cP}0y{^;zDXP^6aWbrK?;V|2s^zeTB2?jFmv{SNTV6u^W8SLe -z9TQ|JVZkR1lm8Zcw1#BCM^i$APfuXl@W~C+9K*1!L>RUkQW!=7MieKv;pqsR3$Q$3 -z7-oXPu&qQGrsgdrB>3cpp?4Uzl?cOO7)-8}Xj8&gVyXD3@&n!KIP7$1+Q^A89EQQ< -zT8VDa*-C_Aa?Vm>6LJHh8|XXe)sY*A9lq#5+_LL(Kv=#Ij_PKeCBPcwY(#%EG4?xK_Xj9LakU~;X5wGnTc;e!lh`+z_=KGIqPyQ0Rgx2EZzYJpkOJn6&<&| -zJM%p8sSY`2kMp<7hR3v&xF45yXu8>PEhTcp6uPB^1fL%Lp-?RN^aLi&*Mg6>F31g2 -z9hMT72MohBB*syN@NUx>%)dHv!6!Ft!zVXP(uZMN2?;)JO4uGS42NOhU@H-ZQQA@>45I)eij&*$ -zbOg=?Qq@wzf=`jc1?x50KdW -zNG0^Tw5@5>O8fpx=yBVGIa@bA#@#hKI^<^ZZ!Za6wYq7`J7&^?PrGcCLcYRQ;xM-C -z!6B<54MnIzc(=zjT^f7&Z<&YbcMZc#kflTzCMhi?!Z77;DIvk9n;kZMa>F)!a>F)! -z+GPX3j3`cSLy-|U8;~1bX=!=DFifgi9xx13^Ogq;!{C<@#mVh3d?F>nFsWoI5r#=s -zONlTH9xWxpFbXiDIJpf)M&Mk41)tn76J)_BH%z8m@W~AW9Yz!D;0Y(%jx1q=goC^rU2xuu`!RHQk!+(0^(Ff0;B7W(oPd@nck2^B5 -zgkCAocVNOUO9|_{ZnV<2x~Zmwb*EKRLV{1rJG+~<%ZBm04}HbRu1&LRDG`Qg&6X0o -zW)zBS&hx~pRzn(!P=yoMbZPA6zhxe#-_=^wgkh$_f=_Okq_^Oc8wNUzC{Au44Yx47 -z(lQK_N|q8~n4-0m2*cpfQX&ka03(W%+fZZ#&IMTT$qh3>7JPEUWV!{P+%V8#L~(Na -zNcgljjDTU-Rw4{jw3ZTK7(7}^gkcn5L~(K(ij2UyfG~`JmJ$|xa>Hc01)tn7&|yUJ -z6Tv4pY{REb2~sr-+e(CC@MtM<-(mQFUVPz+i*F+S{>Gc{KeFrNTcvGHW4?l!WTbFF -z6m4+?&IWYPd8MVbsL5B5sup}&-cj>m*j6G8qW~j{Q{_iCq%e$tmJ(r@RJD`{!$84O -zLV{1bY&Lvy!!~?!!!~@{lmNesC{Auekr6l>(5A#nOUna>VN%udfMJ-Lw>)4N2EU9b -zPHuJyOr9^I+nzWR# -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 -zu;8OLq@l=#d(&6!^Qj~y -zEcmp%V^YJgt%T(P!!Xcc48xKVVVKpFr9>DG!wY;_OL46sN$}~OvkjlzunnI!C4gIQ -z*j6G8qW~j{Q|0h<1kMFm9xx0uLAhaDi7-sfTS`dq$qhsAFl;LkhQlzJTr1J0gssF< -z@loXmy47*m>CUu~6JaMOLEG0G}Hz2x!zJp#JxpCOxyABJ(VfYjn -z{@uU7ed*#M;=iB$`8U7)-^Ig#+cLg{UMbL55tAO468Q=sXDMNI({|Zt+>A?DQ#&JY -zHelq&(P!E?L%t$ku}De_KH7exwZ*R~5r)Y*ONmX$ZL_r-6x=@`4CjVN_FnXk-0-@5 -z!mzD`1fT9XQ_{I%TZ!&DV}Jxkr^R17`yk?=yQi6ScgoFw6v5N?7p8 -z4U^Mh*j7SLaki$*aNA@|_jGH^Cv@jkPMGf~USvOHiIM(HqY -zD-njNZc7OXKDlAKLm0M|2*Y6*Os1m+=e0}a5f+}ywcM0fMJ+a%?;a1D; -z0Y(%jw~uT{VHg1|CBiVNYAIpCCpQdq7*7nJHYIHM3F8Fl;L!!6!Eiy~D7rL>RUkQWy@yi$*aNA@`{AW#DYU;(cZh -zXQGyu6^5B0ONsje!+(4FscRSCMEt{N&wu{jZCSQ0`Ag`P0@hcKmC%%S-+^f>VLkAo -zIjo_`Rx};)s-?s+*Tn2^{j8V&cKb1VylQpRcG+-n_l2+6nzGAREhSpsp|quh1fO=< -z>_tr&4#U8~R>Fdhwl1(dpr%9^MghiUZo|_NI2Vu`MnFpm%L8iLGi^$c6P6NTnAU75 -zF-gJw;W=_+;+Q>RE%@YyZ4VfRN$=dSt%L-hHYIEi7>2_zaIlpK!zgVj5r$EK5yi=E -zcsc^-0&>F$XerUA1gUB%VZoC{Av} -z(-AlqkQ+uoONlT{s#;1|@W~AW9mYAfjKg;yW~~b@dCO7odtBb_v0Gl+{poH$d{?Xm -zpWLtwpF8P+wXZ&Y=z;U6h_9c0`SPp(7(0KLrs3tk-IcFb)=mkXub}kSN?3bK`3jV_ -zx~b-{B>1$;X2U060o<%b&7I^c_HzN25-so0-%=tBqW~j{Q|0h<1kMHIh7r(G!h%m2 -zCetnWXzPO9F!-{R7`bsGOb)t+;gtgYeTC=5u1s|;;4MoVk@x=L&oU@b& -z!zjRb&gczeU7YMT4 -zhGfA{gkf^dQsUH@48vfuz2Topi7<@PmJ$|xa>L-4 -z5!^GQP-FxW@YkoGx_0qR#6NuY{O9lOdAPOEZF$E;SxQ`;5Laf*_5iE2ha$J9?)D4W -z_tm`vnUei3pyeIi+ET)Tk9OO~>ZY0!7JM`%Ecj?jNbu=FcpE<5?4S*XVOxnXjPZww18plN$y)jB{)mhwnbjS{GdMmd6qE$isIj5r*kw -zmJ(q&3@@tBf{)gaB>1!`VZ$dkY{RF$Vc?bLL&4BJYC;V=v)*GjZ0VJopzd{p^?Zgm`Xx-)I$L>LakU~;X*^aE?p -zy#3boi-(B6Is5wBWB*0ak-8fRH(o8FR|@oX6Xb-Y#B@U6_Lw}S!IiE9EQe(+YBVMC -z6+qNdVh2Q*8M!BWZ#isNZqJ|TmXmtlb<-}J4WBSfB8OpH2?;*!vO({bceWCi2MohD -zd~(C!ml4IW7}U-PoDIkgue1!qq>`mX7^Y|~C33^i&r%``qW~j{liN^a1kMFm@M%+m -z39{gm8z$2&_~eFx4kL<_+egBuO$h`H!?qG(n4-0m2*cpfQX&ka03(W%+fZZ#&IN>F -z1hkZ};FB9B(=GVqhJg+vik}ERxnUbVZAy@;Vc1q841-5YiF+QyUw!=01LqGBUqAcu -zUOu2K!*{< -z$?c=zW;LYKUuhWLn04!~aI}Wh@{XdllnBG%(NY2k@jlFG7(S5_xnWYtQo@3d){y$M -zP;$aj!t#J&m`1^PDoonz0t-HEO3)|6u&spU0mCp2i7_`UDG`Qq!(ei)gyjLXh7^Xu -zqosrdpC0|O;gcH%ZnwF64s5WFpScSC_bt@Hw^ENQ=;#xLO@H2{w$PKwUh|M -z;L%cI4#U5G`>pHe&k+CWo3pR4J;t?>1=QPM{0OidmbIuUp_x?1OD6ZQc6DbY^zM|s -z?Ndogw7f%UO9=};`3lM>4BJXb@M)LLhEF#;u!CXPRw4|C;YFhuijaHoZW%Zmuy~)@ -z!6a$d&4$-v~_{? -z+@aQxtQ}EJ2@5`&5<4I|EX*#-UKwC1v21)-UdX-ydj~E$?-l0{!?|G^##)Iv4Bz|Au5OYQiu%!ML;-hq~2aa;1h8hAAIQi7<@Ywv@0uU>F8EjK^baaR#d) -zE#GHU`S?hS3)wed@4&h9Tkz>-hYg?HFqs~PZ6zf5v?*bGz%U$!frG6?7)EJJi7<=; -zj3`cS!_yHs7myo9KuZa0DV`f9(=GV4DFJjCQT#;k$qn1^$qkdLVc1q841-5Yi7<=; -zj3`cS!_yHs7hrk7Fw6vnVOt3cKDl9_!#Ky5aro}T?uc7-uYdUX!{-kXzw_g3Prm+_ -ziKi>9(k`LN7)yzJJE2hz@LuK-Bqj0{h;Aui!KYm|%Ey9Fz5?hlqWC_*+AH>s@D+Pq -z>6#OaGso-^Yr&`G9jO|IZ6(4mg>ES!!Ka%Ywg(KuHhgl!Hhgl!;Fl4_$!#by0%rqq -z!z(Rw!=#d>L~fX(wUn?tU>F9!jI)#-#Wl{fI71i?!<#t~hSv>g?puGlMYqVKUBp3N -zaVf4fq+2ikmd|ngk6}0rhvBWr2*cpTQo@2y7^b8d$4YF*E?gEna$|e#9Qvx|0oxnK -zC0R@H_J&FNHYIE&B=~fT4&sMlTZwxc!ymr*!V?$YMEw1YH{X8*9MFQ$cAM*#O1p$c -zbW4eQJE2i;Tgooe+fpK5fzp-|5`6L%l#d0UmUr}43qCFHZ1}Xx27Vb)oZN;YBXBmr -z+Hah`kbOVO-hp#Ugke(2QX&jfw3ZT<2MohNhjETAwh2d3oSn$aW+wjQ^Q{7?M -zRw4|e03(W1<(RnUZ&VOxnX9EKN-VkkoH -z!MkPPY{24uW)EkgmX~FDz%Y!`Vc1q83{%~f5)yoJ!*qu*Y%39l!!Vd!D`DN33d1PP -zh~lHlZ+FAL`|gW(FP$AQZ_N~| -zv`>Gf>+5Gcu@did+=@< -zI2*8dpV`BisO4o@9xx1}bQrdk2*XsjrGx~Z+%VlC4BJYC;V=v)*GgDBqG1@N8Bu&x -zd2Sfq9jC6J$xJb#M#rJp|e;L|@&MAA6rUHp>y&$JO>!Kb}pO1e!6TM5ephGC$? -zxPgxG+aq4J8qzV>bSaT9|Lws_gyHsv!DMduXHvp~kJgYR`1ByW4WHaFC7m0#mBIKg!;L -zb4s+lBb6*AEco>351Af@Z6zf5w7j$7)AA0-5Qc3f!f+T~G>V}Jxd-o-fwKXN_nAGM -ziCSKk&Q -z_N9x5i2r`}=imJHf5*<;@{C){^s3A}u(V6)68hkTp3FIGp_{J&8I}?fe7fgs!>8pP -zaI@gk^3I0Ogu|L^NY2_zaIlpK!zgVj -z5r$EK5yi=Ecsc^-0&>F$XenVW#dE`Cx&@y$C4deiik}ERxnUbVxnWW@4BJYCVen`v -z5r$EK5yi=Ecsc^-0xS<0hMAx+Y%5{GCpQdq80XkB4&Qy)FMf;e(^npS@cbd-mwx)> -zgHQjt#}(fST&uK8Xfno9Vq+SQY@r)T^NT0+pzWTYN>U3cbQli9n^|Qwq%a(Y7x=Q^qcxr915?j$RyfW`j#!qZjgyG!q -zX8u?WDK|`cT1tdrKxiouhEaeK#mVi7*0U|vf=_Ok39{gm8>SR2__Q|+G8j>u+&&UM -zJqVA0Vc1q83{$k05@8rTT1tdr6ktSgavO?_z`1}hjDVIB7JPnrH~hD!pSpJOO~gNZ -z_WbAX&1Pf?y;7im_yxNxCHDVr?MaAQrEPUnO$lp@UsFPYPs=;Io3_h_@w4C)hG|G) -z*j6G8qW~j{Q|0h<1kMFmi<&UZ1chN+i7-sfTS`dq$qhsAFl;LkhQlzJTr1J0gssF< -z@loXmy47*m>CUu~6Ja##5!hQsiV -z>aZG;1)nx0m`TQEZXXTLFuYR0dOkpFNNq}hc}odvM>Grr9meA^wm5^;ke2T=%+~lw -ziwoH|VDG@W^XG3qey -zU`l9PiOIIUzuS;XJ71Bn_?fzC7)I$ZY%39lQGgM}2k-W8J=<2Q?Xn@DrG&M`ABHJ~ -zFl;Na6&(Xjy!!!2I^>v9vAZuIH=G+@q(>MgCoCnxFga%_u@CwVvV$Wx4m*6;VPQB7 -zhv6O75r)^*!MH=G!;ut*SJfAW!*Ceh0g^Brh8NX=B0DnX(1sL-!*CehQ9fZf3@@q! -zMRsIN7#=)5XwRny;fH`0e7Z$PNn1n@2|mC0AJ|d*J5%aj*rxg+pOD -zH$1ZUf|yoA$_?8MDGZ05)9-kV56l(%RAD~Qo@2y -zz5?hl?g5l>%wDm-tgjfgzyC!aa?Bn|Snz3iXTzuE9qAp0Z6zf5^dP+L0mE<@1`f6o -zVHl+?CBiTYFrqlQ4NphlTtIFZ0WBr0rFd?bOt;|ErUcMoMDY{BCpT=vCpS#0hGAQY -zFbp0oCBiTYFrqlQ4NphlT!7^P!!Q#RhHWJ*_~eFx4&xkK#^JjU>lWRrI>Io0%u*r@ -zhv5Z>Ecj>*DGZ|k<6=e!MMmIUfCZo2unnJIcyIWbx8J&c@euJhXJ21??7uX#{nPO1 -z)ZPA8B{WlEDUq+ROS|PAP0Uh4f=@R)Z206WZ20`bzGCrL;@g}2=Brjivf$G$8~9}e -z_lL|r#2F_&Kbf`AJ^hugub=V6N?0B+43nxBe8MoL5Qc3fB>043dQ%v-l?cOjLkh!T -zc+n_^BIF)bz6_iVSiH~d;Y`%>vcfPEWGNAb$vI1jFidq@N=Wd@4cqW(Q^JN%n-VsB -z+8YMHj3`cSLy-|U8_?eHN=wTFhGA0G@_=EOnzuY)7zV$LC{AvN;S(tlhDjw$i7-s6 -zT1tdr@MtMc4vQ=gwQyl+ctmwy_eC^5C -ze}71s9&!x0p~W$Gx7eK$8c{4I?#+b0B&BZ2uFW4UCGr&%x}}5!pL~T4pO$xk%7V`? -z>nr$lRW -zhR9*qRw4}B4JizV;YFhuijaF$`7&@eVDUb)hci*j%L>CxkflTzCg&_A!Z6isDIvip -zH*CYFO$i%5ZA#eiX>S<(GNL%S4Mj%aY=E^(K7Aqkew4if=ajHKU>GJZUF4;E)BMmUkqw)lFO80UbsZ -zC%5M@wm5^;ke2Ur{FScHz_|Dv$DTh7lS-BnVVI(|lnBE>!BXOA%nYD&rSiI9`97n{ -zcU{Q70ec57KIj$ax8Rc-w&9Z-CetnW!KVk|Z4VfRZTRGdZTPe)0e%@#oZN;Y -zBXBmLO^KD3xnWYtQX)4@(OODa9xx1pU&dL=j^Y|;TAU#ahvChf2*c}!w8uZ@xbfW= -z?_NAa{L$GP&p!945I)eij&*$bOg=?$_nnLA3px@`9s9-{P^0Fum9zsJFO)&rEM*0N@z-( -z5yeN_8deDgKwJ9S6#=I^)5Zl@-L&N$^J{g}mUkqw)lFO80UbsZC%5-x*Y3lthIGkW -z9(U149==P7Fia|0N`zsG)>0x2Q{9#l5`4PnY{MrvY{MrvY{Mrv41O6=oZN;YBXBk# -zH@wo)@_=EORJA-{7^dbe4;Y5QFC&VR+hO=bN`zrj$x0x2gGWn=FpL6> -zC{Auekr6l-5QY)ZQo@4IFX)CpeDQ@RF20HQ`x|e*|HxdzjXW)(R|=dBMGh2l*I^~} -zy0rKBZtcS!Ft$qD>ZY0!)}2;O2?;(e@2DgTKJBt${4Drr4Jiy$9hMSdnCh^U*lD(o -zHE|<1jy}`I8N#sLkixLtkaEM6w55aupWLtwpWLtwpWLtwpWHC`Wkhju8;Xp;*?`>e -zO3U0ZsbndU8>VP2B`gmZhQTl6EM-S=jWaFI5Qf9>W=@3RbwjdtM8hx*$%2p8kgnz_ -z$+Hu<+XE~mHcNX~6WD%Dm%e)WZ)ZRLcqGEuQbK}HyKFXma>F)!a>F)!a>L-45yi=EC^7f-Lyt -zhRJjbKDl9_!-(SK_L1;uZx{i?u&qQGrf4lC!Z3KWlnBEpz=-1HHWV3wa{*x(0WBpg -z`22Ei_)o7q`r!Ff#4r8y$p@eQaWdgXo|e!n1^Oyta>7!gzjFq1mJ-&T)_etYWjs~i -z55x5RF#IzqVZldpSk|IOQz8t5M@xw?i~@`(zNE+qoC~l#V9PruC=A<5Sn$yr(oh65 -zbYSt`c9^Av1fS0=C9J)r?m3fl_ueiWl$xzcONrbtQ(-A_@RTnWaA9~y&4ghx#Ztn8 -zkG3wz4U-d=5|#%H!!#tuVTP#kvB|p&h*t!R+_)-mF2I6MZkW~|hHWJ*4;Y4l4&xkK -z#^JjUvl`MRZ+RS%k34*r5@DD=X(*NrF!g!rSo44cqW(Qv$fidsO){a5iA^KC_22QOnB;!%UE+ -zL>MOLEG5D))om#u!6!Ft!>3IN8$NAH*zoDmAMneF;^a0I8G*9_*4_8%3)%Oh>>W6# -zgyjLlFsW*Jz%WdvTOKeB106;bC%41!iIfP#q>`mX7$#LMCBiUxw3Gq{22(#}`V?=2-H_~a{W__VwOZugq67@nWn=Yx_`I|D2w -zEcj>*$-2|3DG`QIfN?tcFRzZ=F#1?ZSnz3=jZz51wh|J2a>F)!a>JO!Fl;LkhQsip -zQ4B@MJ$SbaoDEpK&+Oq$)bg?{4;Y3~It<%Ngkh@NQbK}HZkX;6hHWLna2N)YYbDwn -zwv|{aKB_!74DXIpqJL9|fR++HDM6}QN`&DsyxAyn!*mBriQI5*c(l${^@U+_!ctSZl(!II`ir;lhB7;>H1SK -zo>&R1n|8Cq?xrp8D1|U=D}Yi -z&{D!$isy#ObPGOhN&p>36h9Gsa>F)!a>Jx*7`BxN!{E_UA`GJdBZ`yT@N@*u1y~+1 -z3^PGt*jB=VPi`3KFwU`M9KQRoZqco(BMj5WEG5El7+!G5f{)ga!Y~RjE@pI4WCYFy -zSn$aW+wf^`m`u+N+e#dbnO$_U8q!dND#UEH?x5@9$DZ#IfHCFqlu5|#%H!!)EeC2S=|W5NO~D6+qs -zT%5sbNXz#bRetc5uFt@@_#DTc--1t@5~OMvwv`COK*3VtXw2-QUl?9hM;OixgUPiL -z)>2$+NEUoFB`o-8N`zq)V5IRaYG-G^p}2MggyAr}NTo1LPFPBWVRFt=;xbG=^Y3q8 -zx_E~8?`MDh&2N9)0mcE|UF5uxuh6G4UqSjYQaB)LuROguQMdoN<)!0K+M_==Wwjhu -zyKMLtONo|ukib&nW|iDhFsJzOm+%#rQ5GRd+1p|zB`o-KvxAwm;L|;4YQ}<3%R8XM -zh~nh-ZIqe~2*WEa!!W62DG`P#T1$yA4E-!6!Y~RjqByw?MMmIUfCZo2FcW0KCpS!{ -zTky#Z106;bC%2D;Pu~cSfMM8HA`DZsmJ(qYJX%VGVH99QadI1qjKH~oFpPkf5*B=N -z!(_SzpWHCeVMOs0!6!Ft!>3INQZ)?QN`ztXXekkfQGgM}$!&N#0_OrO4;Y4-pnD6$ -zUw!=01Lsc>UqAcuZ|%H2 -z`m<_$`3lm*Qo@3d){v|}E7Oz+!{E_UA`GJdBZ{+nfFdJsF2I6M%R4404BJXr@X;EQ -zC(?(8&;V=v)*GjZ0VJl(5 -zCpQe-7?-(ylcxv%ICA6YGi{t942R(`yipRv`DhI(43l$~61!&fmdQQr$1uE7peH5B -zA4`ecFs<2A!h%n382mDVduEi{8G*9_r#sWewd96#!;7S};G^x5cZ-gawv>?I^NZY~ -z`|HzBUAy=u;vYVH{`2>Sbc-U`i`Uj|A8Q)5(#}_qKb8_lrSxV%FDOyVj%L9gC@XI($*->2MOp7yw -z;V`_J6JdDWkhb8`S;FBAsJA`3di7*_7!Q@&A -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 -zaLpMUe) -zACJcIh2qw2A8Q)5(#}@^QA>$Y;tNid+=@9Od -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 -z4YQRX!AEJB4IiaprD4E?gY!{ -z*gYIK%6eI>MU8R=lxD$4xdNURhS^Gx;G^Xox`QyxRzetNHzZ+L7`8MDqX@i*Dz{Fw -zJHhffb`QsmvR;-jj2pyKLKueUSV{=PsBV@LB={%|v*Dvn2{wGRDZz%19{mA+F+y>8 -z8x%1U?M`6*`fmF|T>UC8Pqe25D+3C{uqrD93d3+ZD+3C{fDT3|4sQ#?UQ$9BhLu=K -z2*a={O9^2Zcw{Ld3_}5oP#oR{Ma)Ed6Ik$38paJ`!AEHrPG`YKX&BJK2*u%T58UMKgibkY3s!JKPo0 -zss1b_^qVv86-$ZeYRBmDEZJq20*@<%&?qu@*J7(sp)7wY)>y@=yuo3JAzjf(0Mt3U)Wu@(%dL -z2*tewA9k)lX`Aoi`Sp{OV8KVrJ6Kg1W-FoP9q__Zf&?F77>z<0W-B2K3&X%ZaOdLoidW -zU@P&m<_eTH@)2}$JId3PV8MshkXVZvni9e=6u{`^>JWy37nTyjFhI^yLKp@VSW1xK -zqcqHhk2WRP@X@9O8$L?Iz%NE94sU}ZW}@8*taX9y3vu8uPW3|VK|)yAEjYH2O|`Rw>^Z9_J$##Fw9m$7)H^uln{o2N0t&VCx(B^kUl}kUm||w -zUt~*vBNFV0!Z*zZD!M#Dh7OgAwZ$((!;~1IxEI{(@W1!Y6rp^SD}Wc45-j*=c?To2 -zx~Z0TfDT3|?sDfvahWq&&cJF&*3XIdLR_8T@P7KVjkCzZr%NG$j$4dYH?w0hfPcnZS~1z3Nf -ziPn&`DFMv0lwj?M3d4X7M$a*3IRmR9SwF{wE%TKu7vky!mnYggztXVMFfgf2iT_9m -z7JO(8i3A`0M8}4Yo|HgIvoauUT@bPq&*R<6Lk -zVkz-*8rtkvn8Jik?t7Z0gqC;U1WO4Le3UCtR4n)?SAb+J_;7QDFzl~gHq&v1VJLtR -zjn7MkA`G(|k}wRbvXo$DK>gSO=wS3Re3XXS@KG9O!$)ZtP!NXMN(jSH03#Gfm4l~d -zqP+=9!w`_A1Sq;b46~IGhJ|5ZGE@mY2+vj`Sn+__v10~5 -zM4Tz;NX7a$_2`ct{RvwODOW%NjN!!b#!KZ2zRvNYxl`srX -zu#{lIM;HckF^gtz5xYf&?G!vauI6!muz5IIxuvhM_b| -z31JutV1(lEHh5|#+MA#>3;|h6u=bXehT(J;e6-63=wO86UV@L(FdIHf!?3C_%vM4e -z1|C^T2*XeSBNT_X!BaEQ-UL<#6ozqwgkiQ4Echr513DP(vBezj{4o9I?5GZ57=4VT -zgfJ`&TR6mm53L~y!%zUD<&GMPn2Gi#u;8OK%!ZHlhT(LjVYU(;W5yYsSPjW2f+|GV -za&{rEPH=f5Zi#CbAPnOMv6N66h7(yz2*ap(mJ%fRFn^*;?As|*@H50QE(9G*kkEJ# -z)$S>dLll>xLra_0O=W15HbyA!H6wfPOn^{`Cs^H7%R6>A)$$HTW_45j*a7HZgyQhF -z$6cD$ki37Tq2Cpwmz5BPVI`IltPCg&qZEW;wh|=xFqe1US-=4f?1sdGkJ2y_gD}ii -zLKp^gSV{=PPyizohqoi~+TH|V7y`1C5Qbq@mJ%%ZXj1~v!Dx>y=5XhSX;Z>c9W3}L -z4YT2+O$k)DFw9m$7={8Ep*X4>Va`mnH$fPNfGj0g8BiF8(}iKS5+wL&ZWrG#TMLgkjV?O9>Kul!n>x(JmVs -zK1#!E_$UnnzZju7ybX$&iFPNj)&;gN#MQ6j@?I|HVOWW!gfI-NvXl^pfk&1S!Y~xT2*u%TP{d5MH-QBorD5D47JQV3;dB;! -zl!gHvj8Gij_7FbW8-{?wFk1;>7)8rcLKp@fSxUTo7;fU1C{FN0#C@MOO50?!p1^b{ -zzZV%Wp^{kLR2T+yFhX&g>~ek> -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 -zKw%ir!RQU*n3D#djMb35f2EajSgw& -z{H$)OPX=v6K*op#Vk?Zxl)b24KO5wk}W_M$xjAP#Q*cu#|{Yg{I2Q&2=ws -z3d0TowJ8Dru#{lIht`l-8IYy~3qCX@Sn#1KAq+zSjA(pbYDg^jXm1!dNEl`-Aq)cw -zEG0EaHsl%Nok1&;rh4iqqvzC+ -z>0mC@TjaS>yyd)HBOmT;t_-bQfzk_ALO*t}m0)#KTEa4lxW_K%hq07+&PU?ry7yH) -zJlxr*3d6#%Fzlo{SPh8!muzb3_B?wVOSWp -zR0kAs;uvAr@YJn6AN`ROBOnVt`iTxD&031a!@{to -zI-rOX#|XoQr)B|RPZU-|V*QZ?JqVBct3NlvR>I@ra#oY9?HQwpC1Ng_NOdU~b^=9i&ygIG$i7ByZsG?Y-TU@O7urpgt78%AN6qy+0PKMKQa -z_|O`XcG-}uSV|agcsB#;H)nPR)bj47Ti(GFO2cd=l!j3qEG0~1LKT8{o^B-=Z+LvB -z2xnj|#f4!QK${Y5C0H4d){t26p(#OvkJ2!@gD}iiLKqf?BP1Ule1u^rjnQ}yRjxGb -z9VN6k3@fpe(53{e%2GmU7Y-Im+PXy0^aZ@Nj3J%Ic>2%^3zzu3#&nT!HFlDM5k{?`I#Q -z2)u{YgMRGrjuP5sgOylHureU6A+g{?Q-YNNX-WvgPynN;!bls3ZgEa&7~O%Tgwimq -z%2GlY1{7FIxW^X5E?gdrfRa-hh7v6JXj1~7W5Gvh7}d>!kJ2#kixG;$+n|VUC8Pqe3mFbpfPln{ndv@9irVbnZJ2@-sihS~5@8fL>sX_yTkrD5O~BNT_X -zK@l_2?gXV_hnB1iC=A1@tPCg&qvlx|P#6Y&F+y>8TNw6|62dU7#8TpA!EnIr*fE12 -zBF+?aq+

NB6F8}2!rpjt?k2(nTa}+-h?soBG2xiV>Bj^%QMM|{F2#nlNE+JPGwcOm*cpDW2^sRk43OzzXgggTS^SWMteR7~i`6BrUE)S28zm}oi^y72@~5+>A{ -z+((#bI+K$e6OKvxG5I}U@~VOfd*jJ(HxnkhoypCFiKa858&Cd5n6NjVgl;BGs55~f -zVge^sOxPPw&fQFyP-g-|#N=-r6OKtcU;>*cpDW4aZyHRfGkHQ66Y5N!U@?I=Q8A$# -zPhd!xP-pT4VWR0w=*AN`NtjS)@&sX`=}dm$m~c$ek4aC!WTS!!d*jJ(T@aH6x}8ZE -z#NA{JWQBqIup9_1Wpnr)R{a?m}oka?>QzMlk{V9Jz!FyV8Y&b^4nm-M7J{; -zOqggo6T0zaAz{MacoG^+m{4Z|L&OA5s+h1ho}3#@m{4Z|L&Rhu$An|j4w%56$(u?t -zS*XE;I+J^KF`>@nUKSI06BQG>@dSp133Vp-5+<6?gl;^6lY|L%CifC1n$DzwW5O{> -zKPD>ylPU!h_QsRnrV=K)oykNIujToCU8>4guU_P+*HDZ -zIujToCMP&19Fumy1olkcRFcUF4JOo?l<8tZokN%}Dv4w!6FFkx>z`K>o%a!j`~>5Z6tt?5kY#*-<8347y7 -zs5fGAoH`R2A|`NB#e}`_I~5GJ~v$qj^wrZb@%Pu?L+*c(qmHxMS&nZOV+fs-mG?2RYqZXisk -zGl3yu@(#y@W6}P#Ng#e_PO2U$$u -zO;k+i#uFG4Ce)ccNSJ6k6T0yPP7)^6nLJ3CXgU*#W5O{>KPFECCa)=&us5Fkb}M0` -z+nL--m}oi^y7A;3VZz>c61tTzq0R(`hzXojF=1~!Id>~zLY)Z=5tDNq6OKtcU;=w4 -zKP$=PoCXu>OrFxkggTR_SWMteR7~i`6BrUE)R{a*m|$npB7YspA2_T>hYlZo_x*S8 -zGM6g6Tl&lNw(jONqr;VJ4_|QZ&vWcAF#rARUfHzPXX+NN93U*KTAi}K60+QHFrB<` -zR<7(5ugnsDg8v(D30V#qOpk;sR~)|J{HcI{N&UDQ&zDVdPSpLOK8iVxUdAVw9qH2#gq}o&7B-i(d*AEjW(e7J!bPxaM}NF_>%grz|Drs+2QA+lO}k+@C|=o1_^HtRB>YSZ|B`z9 -zz-ZOZlyzayvd}0^4d-Mf1Iw%Z%WFONH_168<2l`hV+FGJNt^eA%ib}%Xj{sw+AiTji%?y&&rj9?G03{|qr4h<&Msw~mPWEEm^M1#p*#N;i) -zWG{=!D#YXnVX}(F8d4({cWCBCPWEo+y95I0* -zVM58|6&4eCk&4N3!~}+f2~Q?GnY2SPflZW`lw|Ui1`}#k{-BG=BZ$dQ8cZme93o6K -z$>b5lksYOyHo3 -z$wMqA<%r4eD4D8E&9zslDh?v07@CX`GnSxn$X -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 -zf{P+dL}&8yc$nag#$Y1mOmIH4v)g*@OYTu -zg)x}iHfMs@$6zucXL8sN6SwG0aM2HwJP{^h&IA|zF!6}aQ* -zHEmY)8?KzeYL+mtMWhG%T=|z>q1OlZgB4~UxBUz!?;c1R?mBB`&swY*$TyJKKM<`O -zE+(s?&$ZyPE8}|9Q{1ht5ND1-RzTKxj{4M-dTC&lPwT@@qccSFtH8`N*uulkZw -z`jf(Sbw%W#)~lcEP72l)y;m_({sPpzutEJxyq?sb6ss#LAs4!j`qU4eQP1yA8nWK3 -zK1UeN6_MZI;`3+JA>GZBb(sJsQ5>38>(!swulkx}`kQCyPW&fMqBt~fu2=8uZoX>0 -zS$(3&a6(0Xjn66kjJmkHIa0UnY{f|VW~kY`LH!QiGp)ZlRCfiR$h%PU?gn*wceB@e -zv-*n4aHWKlL0|h_m)j>_pLb}aya;NFHmDbNm(CdOTFtPl+pG^GUujBzX}GSrh`h31 -zy{Ef0SXWx;v#s7?JO4&|)L?aKk)c#Y_H0nc3ciyEZk((GJ1stS+8H(3T^c{!b=|_I -zFxL7v+7kw=bBYZ)1i9AXYoC6(ed+a`H6!KO4$Z0c>Wc23@Zqk@ZR};U^#=0w1o!tO -z=yV0-F^8```f_{L_3QN`<-9|azh1pg@LjLFalHu)GS;)m*Aw60lc9@M`fN2jY{VNC -z_YGFZ5{B3!^8NMPQ-Uw0=0?f^P;B;bJI-*^x^t3sO)B!M4P01vPQq~4Y%@FCVx5b8 -zIZ6FFvAVS-h-`TEhOk@9Du=GhJ0a=~}>$c-)gKysV42>Cju^>>8nvWtAS -zZ98mN-l&ibR-Y;~oGKvOH*hI}Z%gBiEe+r^i;oLG!xeXTMCx`G`)t`eY^UC+NFA)+ -zRbuE@l6ekah5T|w?)A$iaHGw~tvJK&?bZbicg3}_ac1lL$fpbI*G<)>smKoPE_6cWAb+=Qeli;&jJKNcnoMNbrH$8{iPIGCr>K442cbOVja6pRIL=t?Uig -zlEG@8Fbp>UcbkvPKf_gZ4+QD*3w^ed9kvhOa77MQ=NB3BRpcdy&n3I;%Dhh30gc7S -zrJmu+x(DKhyPOtw1!Fz(hAVNfx~kYvMUdqVpDXpUEARSX%}Du5ho);iSJ^!fG2AuM -z#*Ub+LEhi{vi_KVT76e{(%)XaSuG(zfXT=gY|^e0Wx)d8GDacCZ0ul{Lw -zQk<@?giKhk{vBSA>`$7mD|#0vQ5+h_dNtLZ^wq03tIri0&J~bvd0z3UXPi<0tUJkr -zizS9kB^kLv-DbGzYo6BM9Hz@;w~v&61T`ORP#?s_DgDh+x)a6Z6Yf`h>Mdu~%etFK -zUcFhpO=;LxNWQXOeHCvc>u*ldZL{MfibJz>z4~KZjP7qv)mRZZlwH#L$htYdUJPaoUXZqOj@rl5_~6X -zZ=5^?PBK1q=^1rScWIigN9nU2-C^7EM*EV%>K?+-Q$!9xU;B#7?ZMY~?guGmpL**V -zbz*nV)Zwn9X7;GXnv8rsQ~GkL-ssS*S9xs9a-qJt=VC_@P;dDu$n9~kSdbfz{LtaaNq{016qrZOFP3=zu{60 -zR`V(YUqZ&O=Tw4^uDwBjPcZ4jFv%T-N$Yr+RQh2ubX%BI`eB0CMVPeuVRBZ4N$Yr+ -z;3Uc@Ool|5;3SG4CTB&Mw2p^Kr5`4E&oP)(j)%!v2__Ou?mSH5F-$^7VNx?5CJ}y^ -z&^U?m4=};&qcGWnlPG?e)c9eN@o#>Z;G!QU5q_9d{oD@|T=c^v{onjBsTmIwywNC3 -z3^<803KLxP!vr5wf{6r^JM2vU3U76VthoRGz$9b5GpXL;he^ZjVDkJ9KTPntA13Ld -zGco&Nf{T7Pz+d?KPVF-tI!U~=bS -zastis%NfbX!UJzj-Iul&y#SfDMewZ8=oe3`bVKPUA$zy();G!QUuZqs(z<8M8 -zjmBVtlPIGw!9_nz@G&K4A~};g?M%8cOh%uX9G~D!cKTuR`fXvd(+?B8?uW^%qBD8Z -z4-;Gzoe55&jKbt~5hgf^;)ltbewg5M5}nCTKTPnRV=&n{9wu)}Fp*$#=V5XQ!({O& -zOkNoelkFl*a1!MoV1n1jV1kn!bEf?xafz;b`d6z`(c8MB1}YQ^2&Ia;El#$ -zf|DqtFu_F;CXzFeoXPj#OuoP{8GUAQe1bF4`eAbIwlLB9VS?91n265gT@fY|oC!{% -zjKbua2osz{@x$a@5hfFyiPjGjyyqB9wBup&t^^YaCU+ht3ouNgM`2Po9wu@TCOC=m -z4=};&V=%!<6hBPr{4gmOoe3`bVImh{@~9ssxafz8Msy~1<6(j~8iNT=qKv`>7yU57 -z$CR9jYxi -ziwF~(MDfGqgdZmOoJ42xgdZk&&oP)hF&-u-B$!Arx$`iwVVGo%!lZdTOw=Mwa1!Mo -zV1n1jV1kn -zNuTIUaM2HwToEQ){V>5rKTMpWGie$R6THzFOmGrq6ehUnhY3EWOvsrW6Ja7c6I}GeL@&Zb%$eY# -z2ouqn92*Z4ywMm;#GDB(iZGF!iR4Va2WR5MFd2Pj(l^1Gh&dDQZDAtjOz^r06VaKl -zB1|SY6ESDv6=5tDCaeS#2_|!(z?^7yU3o|UK$URbs|h|n=`@d -zV=$SJGkHmbiResl(GQb#B22`b2`-8-5uM3P<6(j~8iR?LGr>g>CXzFeoXPj#Og_gj -z8GUB5a=bI~i8+%?w}pwAGr{X3OhjjLT7=1XXEG?}OfHEqnUFI%Ey85HGZ_(cCV0;= -zm`uo-oR(lB!Q{@vq#VOUJ_?h@@i18+!sNC&6TChKlLLXiI_97i7=UvGimq31fP@WOvIcC-g68l6LKc)5=ITKtI -zVInyb$(ei)&V8GUBbHNlyPITO!qVIt;C@VW>S(V5sqm`rdcV$Q@P!em0u#4f^Q -zf-@0wCV0;=m`uo-*d>@qFuC(ES&3m1KMIqE@i55{VRGA?30@zA$%LFqgC8cTg>CXzFeoXPj#OnNa)MxU8fPjDt;&ZO_QFcEVmcwK~v=uA3Am`rdc -zV$P&bgvo@QNv8;t3C={!nczLgU@{?R(ka2@Ujim0+xve1)n3M1RndCQyrHf3;Q8e* -z-J5ju_jSKNz37svVBXfchvy|F%~hSBe17?*?;d=7?s-_aXSw&^*Lc4;U2dz=Z$Eb0 -zd-DqeH+Ze(rwcqQ+CQv_@7ul?dds7Y&WcAN*=RiL+cHDYtTDQ`qzJ>@+l+ThI>jAi -z?3==?d>!);yD5V2n2m;P9fYStfvf|Be%B;Wu@#c7M)&0z!Z7zT -z?l5ED9nN=Tp&=Vjcsk}FD@*iM_eayVVM1S(CJb{mjCa{IiZe6zxQHsBZWdw>hx5Am -zXvp>z;Tc#9$vMWezQHAkJsS;NzkuZH_~i=3?wtf&6!eyFH#%KULh_o?J-84J*^V2X -zu4{~aZ{*;Ji(|aYGAOQ&@pSEtrfq#DH<(7L3!t~W#pujhh^(_B7xq;TXWo64eKDMG -zo`3h%A={q`PxC#<`b$E8V)g!;BUw6VI1vf5b`|{ITmH4tnNx|vHYX8j<*JZ{F6v*l_xz8V+{M|4YOL&^Iku^2(v9rGO>4Ijd(GBL} -zy;@DqtnHBO4C9-#@ar!KPxBmPEyEjvY{Y8gK~^O`@J*xBb(pccV}Q$A`){7EZzEWB -z4P%d*{k!LVrS~E>DuOSag{*D(?IcChwl4{N^H28Q9BKarG&Dznb_)NHZANGNlaSO$ -z@TCfTG=tIE{yZd;jAwly7qRYW(Eb?omU|;uE|k#cPovZ)7*E%{2v*(9*wdp1M_hkm -zy!0$&Eit+2`N(>b(3eJob{cxibBxaR$06BaJnK7|CTNaC@B@XA)Zv$@f@Z+zrWc_h -z+aTfTxeHnAiN5NbDBAV`q0fl~?N2~&`9-6%eGeqFjc0v3rwf`>M)%G%VOZVDc5bXs?Fe@=&AG^)6!%$K~gtft^fojf6fnYH+0DDQJj| -z1Qk1=xBPvhv*I~OE|Bp9&p^@^#^>CFtS=CK)lE^fO>J`1*=We-AUp#!BrC)C9DHHq -znw+jvjNKVGI8yN>G_Z*jXD9lqS-GJ3%IHqXptvETuexfopveg5bM8h%wgZG`U;`vy -z!n%F{u`41$#WRrHXgupXnj&aEHM$4yM? -zGtpOlDvGxC5c*S*gCiBYpy5B59k2(5FQYj<}wK -zhN?u0JHU9l&c@Oo(-U&hn645ND)zAe1Mc$cM8+`Ei@Z_MC`>vhIExD;8- -z@rRUy*pDN49scb4j82!Au`9y)=E=e^cY^V*jsaO8o%lCT*T^$-M=$HYJp6la`9~&a -zRuLrUn%t{(bFU8Bx(QG7Y-Byt^4MA5YPq2K+T=bznNoki*cZw8=B3CwAFqIUh_%K6 -z*U>c#`>M%QLBq*-T@@rZFF5zSPp5*0ZPCE>0bbk|Pupe?dY-~ReB5>I!UuoXL%9g=$T;LVY&YG_EB1ls?I-$0a%RsV^x9}MG5 -z1^iRa8J+FVK{8Wu?s;G7BE+ti@uh=!Vcdo7#;?6$tokNnpBGl;(^WzPFQ?S!7*Cfw -zp0-68-SmCPx|-;#E{&sY^9X(ZRAHEVpYRO)1d>O>`GKE8vee{0nM|n%7*E&EFjjq$ -zvG0^s`AYK;n;s8b2N?VHuqt0^E@H3C_<>(QZ~1`9*-k(*)^yglbE=?eGP!q7q12x; -zp01-ZR{b4g-x5~k>sf@@Ei%4m85*)JAv^<*KyqCK-?Ib_*>)42o)yR%NAy+eVrbh# -zgkBd1+SfpDIcajXmqC&@o%LN$5H$HF_w^)USnXlF*AppjF`*xb9UO6e&UmlODYcLB -zbcKhp+_Qu}7Hj4v6NrJ`}&JS#X-g1k{=^9|{&Pkx+LFg^73}?AALeFAx{(FyEvxbkJPi$1Qz-7wjQzE+Dql_xVqcT-1Nh$e -zsmbX&&DdAOgNkD4EnjSMR&0XgY5cS9LG0BqJ|`Cq+4c~gfo+g1m+?6((U46>cslMw -z)*_;>Iy;WGWfJ=A*ujyC&Crk?4=RcvnPocb+ma+`+D+~)iNY{t -zI{a_HnDFS9AnUV)et4QN%&j9l1J6RTE3C>lPyr3c;(-f)c3m=-^ALJ624vyud=24g -zo<^x({2jiqU!3-xW|hgk`sHcg4XeLpysHx^^?AnraOMZk`=LwIl1d{r2 -zUZ;Kx^V{TXS3**jxb>`W-c&(TXL8S*La812?HrV`>TekPYJ4hxzpR(xAF_z>lrBM5 -zyU9JT1s^@1@RY7V)+nN{nokupUKwAC8=fJP(^bRR(_=vU!_ZsaY;v}*hGaYz-BZwz -zKZW8fgg!r+Qui?SlQO)$W&!Nwu#Vp#0`$LuZ4#EB#Qf# -z(09ZRj&cYb%XqrzFjjquvD30DUr!!l -z2gCS*2O(L7udF4A9hC7sSnt7vXW(a$48`RYh}BF2u5*k%Tvp}Fc>uBXVSElgtw#w@ -z&T?dJF}mrc$f`EFQxYide=(k}Vj0V|6M7b_6fs^pA6ava?i74sv=W|yO^~dNsPg43 -zL98>w1QuIUdI6EJfD2 -zL|^sVSladkp|8TNv%q)<=OgPSlly3bFwFg)@g7a0xW8b^O`>f}3H?QU!D^tPYC6TK -z3H`|QtO9I86XFOe-WGr``v40j;96OWhVD!{DyBZ-pdIT_c3GNEvxc%C-legZQ(&^I2H?BKZE2-+*ECZhT$0$w}9xY9!?Q7*Gz7JKf6l8Ghl$E -z+~i(8X>i2#Ff?R_^UbqXUH%`Qu90uc-*a^x{GWtAGx}|pZD>wBZJSEyPsD(%p5tE( -zTpIaq~=Zm$LiMNCF0SiAXlRZFE;nO8Kiow6`0A0qL_u@KOQ^m1gKV|1TP6o%D2<2@;-xR>xPAfC2`6Z)K(!IAb2(2x@c+E+nx -zErxrtpt)#r?@SPe)fX7=&Lm3hVmw`!!&q)3q0djF)V=tnj8zXY_GOs)3lY0a#`i2m -zRt1K8EN#;gdR_eBNP7u148(wTHT0IVCTIIPNL~u#d$20Eo1E?CkQ~N1o-AlC$@rZ6 -z(2(t#$?2+N?3x%*f#0Ob4K(G#t-a<-tw&`r|TGFcj8upWxOeJiu)U5cg7EnxJ-<9 -z@IGXX#20rAZ98IgAH}W2hlFQf6(nCWxsOf}hPiIWdo-EiUdLO-)3!@S_uz75olf*s -zUyPw`n+g3ze1$YJ-lK^W_XXqWx+-J27D8W@L~*xpZyv^Szh&&n`0{)Ju`h@59r$*( -zjqr3VN7f`le+s{uQfN382P)P=Z+V5uSwTY5WpZDhOmQDD_9ZgDV<{T4WfPu`9Aw=^ -z^i}VQr)_D3zCQ+3;1Ahua#pN^qygU?{Q3Nm_JNO6 -zzV-QyZCw*OG+czu&&cvHE+VF#JPZT0hpc^h3SBfA}DOtd>^7@a^s|-^Y#YM`~#$H|!t4eBb8ydq2SK-^q`4 -z>yX^=fAd?%|F7Nfx0ha1{w740^+?4hr=Mw@eX)!h`S4bHo#MOB712raw)~}UWU$<~ -z_fG{yQSwzUp1!v7s~{dwyFR&DzIVvCZb&}2`83Hb>EH6pte?I8oa3=`YntzU0yIPZvMa!Rb -zp82_@_+o4F-&$-A-xplsH4LfBCkrqUy@&EhjG=ufFxXbE@ygS6_@gJ@ER?ue7>{ -zXS{dois8!X?(*u9Z#+Hay5p}tb@RI;$Jf33=Ob|~OP{{7VAHT6`>kt9o+HPPKYL~I -zl_cB1x9_*GS;wo7JW~CY>yMtjWckfsefAaf-TL>vSHANMU-RAnSMN}{@6kt{SNdLu -z|6!^=zb2x(OQ?RHztQ#lhs#1ozQ|vE>l=Bq!c+0HuP^og{<$lsAA0#hwfoS8=h3=7 -zuUMZyylT&%zjfjx{Qj?s&DQ7LC->~R_Q$_8_`0io_NbA)YL(~c%8}s*>6;^;zBKY~ -z9H+VY?`PcKrfszOp7p-xKEM6V^DWiG|K3sU_Vzaa`CHos`kTJ$V@Lk;|Gcr|)Rph( -z=Z^de+JouO8U0M*ZPkJZL2Gnggcl;&GNvV(e%IU*L3b8-mLNWkeGguUVDlLL9KmhW -z>_tiYGz3aAY92*NHJS}5$)tH2HSg1`Ld{0a6R5dHvl;QR>@(0FL0>VegK2MpX9X&) -zbq+&A5FKA&nZx~r1q~szj#10$ -z0meH^xURAV3n>M*1R+IbixiF)*rp3dRW_NhrNEXXY*E=_g;$NvPhmwgyBk)-vvJTh -ziG2vVVps)qMX_4wieuBEE0WbfS1h{%8p7!+vvY5nB%!{ba+*-D@?;`5hE+4UA@odhZWL`R@Z_MTdZ!B-Lg}rHceda(I(uPiG^=O4 -z3c+b|K7g7UoI`LZh|Vae3=w7*cxIxtM(2lcD2#r|oGYU@nsa06;{}z=gcT;|HP{-= -zz5-ii?B{SOgnpLEmDArb-b~@F(fK^e-sdbp*+%DMD7(h_Fv>PLpFyYgIai}oM(0j+ -zs>ZnmoiaITv}>QU80|7TA4j`toSV=tlXExf-{*V?^&6d9)L-M&pnj8cFRF@VLt)+| -zRt587*qJadirotH;@CIP8c;i(TN((7Iea- -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 -z(!TlYpIS8bYlHs&TZC@>W_gZ45*2i$Vdhenv8 -zMt24Xy7C{=FJX{=2}1zCgyH;FUxVT;T2A(Tv2_g%q12D6=C5(KS`Uqy0 -zw1kkWsW;(?;+Al73-vWTQPL7j7E`alZN)7zaufAA+*Z;ONR_^nYKEo7Y8hEd^}x~+btt)( -z>VQ4P>Ijmg24GJK7euP4CYV#qg^?Sni!i5z3nAA~r(j1h7fzN@{jj5i3nojbV^I3z -zhyVPKA66B6WxSf|gH^U_ZLY+;~V41>Qhy=ElQ{aPV*FF>_;+A`bi~`qJEZL=g;X -z(G>HVLyAc7KhcZkHHQ^4@JsZtc}LIE0v`b=VpKUPZLo)nttaXVIY9bwnEkYEZa2^^kTF -zFr#{N>S1jdcmWlgQ=7Cg;4SolIrWG(1ROxK&8>&DQQ%GVnz{9`HXOWy9yhl(Y2(1V -z=&HH(h&CA1p=5K}A#Ef$fnGM39oEV~GumV>YtqJo4)mG1?1(lLG@&Kt-b31Ga0Yjsd69$L72v -z?hw$36lVJ&cNAzxRjste&HrtQ5gFypIHyaMQBf;zFRkPu+TLxN? -z#%ySE$AV7eG#ie%L%|WW!aQ`y9Sv;gta<3LI|3X>d(A^l?s(9JM$FOcBZpQ}!46r0 -zd>T2KA{;W6dhJ(B9%OijG-1f&K1a0 -z$r;qsj&mw`1{p#{Ix-7drjb*qRgO$m%M3D#n(H`G(2_!?P)|5cs9Ms=aB8|^TS3co -zGMU=!*rsYpBjc#0jw=N%sbo5}$8kl~l0gPjGDlK@dK#HP6*-br>KSAtmFZ|MP^Xa7 -zscnvCl{%f2QAv){0`+tRk>+= -z47J#Cu^=~P+Xu -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 -zo#E#ON*dCVwlh%BHLGQ}usiY%vB -z$}Xd2~7Wt|%)DT%jtE9~sYKp9+wbC?(8Y4?-jns{y=7^2f%ZO3m -z5LrmwvcRZUI+FHlyw@I&q^TT9`%xPXslp*u3PY++O2Q*)cqC2bNZMM2AcPo45)g2q8!Xf-Y)B2to)_fS|`_Ap{`= -zsX)-l2tf!zDiD-`5QGq<0zv%;CkO~BqA_O4>sX$OJLJ&fb3Iq)z1pR|S&|eF`94Ry_u;c$}q|lG2j|@E- -z`9s&%SFP9o4}S)okH2;JTc`3{cRT*p;cuPFZ(TC}*8PM1*8LBE2Azik8FAA?Wz%CV -z-pqlU9x9t2*S~lol{lc0Su|@LIS-y=7PmEqoCQJFqFLj~Mer_baa*HFCEUqen$V81Zz6<*|cBY -z6RhddEwo2&4c2t($#hV@5v=LfV`-;c8yxGcOGTND3X2k>F5wB%1D*1;P4`h}xPy9@q5$<(huxnaJ(W%}iR}vHo>tXLIb0H!Pq| -z8E@n@>C5Tma-Wgcs4t=COU=k@)>qM+9$9UO1PVC((D#-A-v8ux$Uvy9C(r)(d-H068MZAafhNrIrvzK -z7K#&FV1$*pLos3_46uV*C|+!X33kvOiWVC5vN|nf5nEx5)wx5lVlxb}NiCEhE`@0} -z>GnnmC+uhWnm10I4==HNw>L(d4L@NAG;h4P7(QeN+}>#60zV^~*CIw|Zq!rPUKSM< -z_3S-w9;zGr&wpd7>jTTOL@9*1aCkFC352+CdaYtTO!4)OsWh<|y7_vgx2IR%ovE;< -zkpl2Sq?$o;)NB=h+TV8d(S}JlpBXA}7Nz?{RoC$O`D^Jx)&!IUUA%wZoH6 -zilB#AJ3ZN?6h`@|!;?u$V33bGJyxhOH#zL-VhP;MH#zOu;#7E@A92_-#VUA`A932P;tcqV -zmpDRcViEXwi8GWX*1!lq=m=$ql`y~$Izu^P9Zc{#M<`t^g6cD}xVL(a&;X4opq!bXo -z17Sca0qOV-gaIi9gzrEYkWxVS4ukwp<^-<81h95=(H>d)VD^` -z=}Ynfr3s#Yd<^F=;QR%J`3rAfIkVrkfI4K1k@=jpAl=6}?%$Vhl8xi|9tV(imtmSJLa`BgR0Zxs+~` -z*BJxNrj6b%KQ?L`%!O2wxkhc1xq@CL?=xx}%_6#0ZZm3|%@VpxzGX}_n2T|Or_uz^ -zA3lp?^1k0=@~R=sh}#=0HbIC9&6^+yOflh}iV_vj&DLvEN>{o3r4{e=#XEf!?)3fB -zY#jUgUygk(6j2b%lgsUMMH*D_<_9Xg1;PSWPRhOWL^gOhsqp5DWUzBl?#&bV;N_yiTPR{7m9HRW5jyi^^3l?;r#r1gSvK(+EL$m5a(%E`LP`LI_g1 -z)AuiJ2tf!zDiD-}5QGq`lG -zz}IHWp}&>y1$;hR0sV{22voJ&(&?|{U4g20+dTRQxg}85X3M7kDqjm!`E2?0&vH#* -zq}7&5e=VN~jI`VG=)cLE10!uVEB&4PG%(_`71F=T#6WSYnMR+N?SbNUb1r>PZVVK+ -znOXET`AVSJXU?ae%9VkERx^XXA|DA1w41r~V|iU*pv}yoZ^@4X13t5Wej#%MwXJ44 -zeNo;QsBJgr(GTRdKy90uP2Z4j1!{d}K0PMa1twbY5v2AAdI66F;gO&V;5Tf&dn!g$ -z!K3W3HWe>w;E(LEdn#JE;X$@ro3aQGyu)_8r((sq@C-YyO(lr!FvE^p|8Oy$N|fu2 -zi6*m{>XI50jpj0Xsl45oXf{{VJLDHeUW1O8_f9uOis=pVX=A!EvW#w*cNo*nk=1mM -zJdrnn1z|xd+Zl0qGd=!@Dg208W;Nk<25x64Y-glp;dTaYXDDoEESQVi8MvLHu$|$! -z5w|mNJ40nVBMrARa63a~J7eMF_<=Ki;H>b0bNS^+iAaen=+*K8qrNdxL_P9SqrN#( -zLcQ{BW4a--n4T-o{C}s!n7s%=2ti5^)Qk{>5TpV@IS4`DcL+NE;4Sr!MaM=(MIHL} -zp}!p_^!6PxdVTO~oxw0`|4b@zKqIqg);Mw=JjX0TSUDo2ZMw3do -zlesjjg7I>Kzx&1L@BRtIdHGe$W -z1|PA0w?CR_a4*}T`7LBCyvcUB{jp>-JjKQ}e*(D_K4;@@PZV)N3(M9#apZg$X4!5} -z3^^P6S&!z4Cl|vw>v4Oci3@sIwdS#qY8YkJZci-P1cPi;^CS=gN7<-597QUila*@W -zIC23TVWsYH45@;HY)}iwlNy+0gYIxNapP~C+HYJp282gGzWR|5OKSrLgaN4p)QSON -zKq>+4#egs%m4G@hAPh()pe76m15yd79RtFER07(E0bxKY0d-+O7?4UpjTjIHq!LgY -z2802r1k{27VL&PYbz(pmkV-(!7!U@e5|9rA!hlo)!t+2FkWxT+9tZbk^7?4sxcpeA?QVIyq17Sc)0pWQd3`i*;JP(8c -zDFuY*fiNJYfbcvJ2BZ`ao(IB!lmf!@Kp2oxKzJVLdmhl}%>84{gL7v^MLqWPTZih# -zCLjHe8A5B#Lv<6o{v~SOLTLtvx+3wkSL(r`&PWO!l9Aw0cO;tbmj%K4j>v44Ayxkz -zJyZDYx-rTYMHWH}&vtsU$jLCwdmNq&vI6>fkJFPwPKR+`?eL_NBIx1OPER%|g;750 -z@MMw_804c)kCm*4qrB7+P9uwzNr!UrAU3{ngS`JgkLL&{*1?{tLIzyG(6 -z?fIGmO2>fsPG>lq*g^24j&LSf4Tt$rXV^+Mz;T}Ju&0Ry(9Dya_AGG{yudph_6)Hc -z4BqLq=ZMqbeZI+IPZvwzZobKB&lab`>->nro+(zrll+L&ZWU+1XS~D_N)wB~$4i`{ -zEU^Yg_(4Y~L#%`We$W}p5$j-r*EvGzVkz|UI%g*HVn7&>N0i4fVE^9IYIGGJsT9e52 -za1$GLSyRamVKytO^v@z!z}c+G<)1@th83*8(w|7KgKJs8%b!AShk0yArGGZL3NB_l -zT>fOT3r=U_mHs56!)3ecxpt#MwUa -zKK)d#3=FiI8T1wTNMNAd%%va8>jDF9W)6KzejFI^nFaIofD|F}W@<(fa+rd42ETku7d?2q?PovMteSy4oeJ*`hYJt2qJ&SVrVj$0_&!?ZrrGeg7J%he19}4ug -z>$&tJc~zjdP0yik$`1m)KD~f`E^`7kt$I2gmiGi|+Vy#KTy722wCUM&RK5|Y@#*>W -zs9YNuYt=L95qT&u)~@H#Nx3U9)}~vjkjDaJKE040mnng=)<_zCL3Rbo+9Px6`*L%j -ztSyp7Uze{2%6yUe^fPG-47Elw=!i4}L+xLCKwnOP!GJIzw%$DzBdXw0c37K=7d7xl -zcGx`?E!^-R+pSGmga_VXyWLZ<;#_!!9oME3#CDirmX%*lfWd$;psyUzmlI$xAPnd$ -z2lV9x7z_vl`pN-)IROR(!hpVVKwnOP!GJKJuN=^q6JRhP4CpHd^yLH?3AR-?`msa* -zF+S+ae*1urn=g{V&PBO5PvnD_iwbX{h=o+XzI$A{9398+_(tg_+be3Gy=i6&rLzm0GKHomu -zIyzTg(dTQit)-{Q_xgPMZD-OrnbB9Z*LE^pBJb*}+GjhRX2~smRV}tsda8V_uWG+- -zJ)I-h^o{JbokCa1C;CSA*~;jAd2`=Li_K2Yke~LA?6+;8F*32Qc&~X9T_oH4iuakP -z(G0nVlRSG&(Vo#x1GeYGuSDP1ey>Z{#vuBRz-UEjoB^Au{6v~OacSw;)w -z?R^t1rk$QCzv!FTZ*HK`GQKZwuYM9;DEIZ{?bA=A=~C;g(O7ucPziReilJ`dWIr{GhLQzkVjQ$eg~Kz52Kkj(?R337);G3a-#}w!N?+OD -z$Vqgu?CLAq7dee)%FTUcEs;~{De~36vi*@WXp*$`4egDrp~ced8`>9HNAslKH`EeY -zOUq=WZ)ktyOqw7I`s(*aPNvJ`1AX=TBBxWUytJ>rB~nW5^6kF*{gL%FRi4>5y*F|S -zT`iyPo8A{GqlNO0zUh{Too6uM-KsBp&d6LOaC}pFSo+MHSJK3nqlS+0&GApeN&mvdC -zCRXYS&mp%!2^*{oCz4vIV}q`63aN*DwzD!kn_LZq?R15ci5J$hqm|(#as%vUM_u7m -zvIk;Wa;1HixC|;-vdcb4+z5+VXQe$+Tmx6KPM1AJ+zOd&Q>A^j_yJtNHo5G{0^k&O -zq|%-wu7_LL5tltx{1B2@No8o3xB{wJi7PZm+ziF+U}Y##TnDx6pevLjZihTpR~ecu -zu7Vm?=L#i@T~Nj*D?>>_hk7>Y3Z;rWAc5sqdS{8t!Oikr-Z|nXSjG-idK1O9a5X#N -z@}`K}z{*IacedC89!6Z=WU&+MOjLT4L>+jUaCuY3Zb)V8E2n0OE8$$W-ZeEx+yblF -z;mWB*Q42S)!>*|mQ4fV|cjeSGUP}K%l-oGLL>JFAdbU -zMY3sFz8$FdMe^yCJToxe8p));kxvJv+ar1OkMfSdbX&wq-;pN*)4oU{jmmy}rox&= -z7ChVNEAX;7;yxTC>Ti!1=Jlnn_l{<9yg@ -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 -zXD*jDnE;&3hAXW}Utl#BN -zA-BUkwxiNNn_LAKvmGvfGT8;Ev++uQ64Bu{HtzDLk~_e{vMW8a$mQT-*)Go -zo=Q(5xfXV?9+xMD+y>dKy3#Y7?0{-k?eZj(olwd~D?Lf14tBCpmnW6%hGbS+8JZd=$i^t#q-{}lz6FUfg)Dg}k -ztKl#|>I_@S1~|@>9riS_0GfHS)1D7l0LTO?V_;`sklqJ@{2tViuWr&q9zz;e@Ibt15 -z@H$5*T`YxOUgr#Di?uMuCmo?oVS^z)=?q!LnJ~@s9o{st5cczYr#DNS3@`Bm4sV87 -z0YBjfoZcL9I(*29!<#OOz|V=(n=MKq%!R|7DM}#3h0|*l>tTwocTA;;#n8>wE*@*b -zugmZ~TID@D4!;emJ9ZueBII2WE_$F->hu^ncZ -zrFAcU$ci7bDtySAHV;2!#Sd8(K4e{xh`VOEYo@Ymb|LPX;jWp=uGuvRK?p%A5X8T2 -z5HvIK&}#kYhCRpk%*^bx-1z7MS}qff;wE!By+XDd#f|0?xGjr%$^5ejO -z&n%!{$lO3}tC>z;l=lT{+s%3O1Gz0w+h%6dH{@G^TA!IukI8j`iB^0xDLtA_{fkJFPwPKR+`?eL_NBIx1OPER%|g;750@MMw_ -z804c)kCm*4qrB7+P9uwzNr!UrAU3{ngS`JgkLL&{*1?{tLI(WsS-`U?EU -z9*tVXsDJh1x9azdjk`Tj#0f1dTl2(`^I@1}yFD@FZ0Kh_nkSxI4CAcF?TIEX=wa2G -z$3m)MlvTSuv1AhrvQf>GKnNUVqwa7Nsen#as)ggo1#pCwy2CM~3J$VCEgVm3V3G~G -z!_mb3ZQ9WP4&J)a+KfhxMy+DhRy1lfY89g{K%+*ZRx#=yqEVw!s~B}08Z{cVic!x- -z2*SgPDu)#_5P}ebR3K;xLJ%HSR5`48Rue)HLXZLk{Zke~5JHd&1kFPTLI_fUpqmkb -z5Q0=7C<`G7AxH&+Rv-i+1gSvK7K9*#AQcGuF+vbRkP-ypi6Dd^B?!tv2>J#gXy)DD -z6$iq)^@1p-|!Nj&tQk7+?prP`ua%6YSu3@zCN~`)5*#0~(n{v&ND0 -z;5lY-TVu#s5M(WyHJ)4q@3I!RHJVhyoy?_KE#yMr%;mPml5^m3Hmq3_$R+Rz8+QAn -zNIA5zBF!I1w!q7*$nB3I8{uKruleK2Hu#A3yZzBbgL~Ny&2J%F;Z3%~?T;m!;VCw* -z`4h;cfTv!C2ED9K3t7Zg7-MzrP^{PtLu^tDC5TI5noYXBQNjuPS-$3t6X(NAEZ^;o -z5og0s*a6KOFD`};*#WmVTDZW^h~~A3Y6vsp_Qr}$5Mn~}CI|vkOt`0_L)sVL%v=N0jUJkf&pPbDgkw3Kp2opK+PBs2BZ>@4+Fx0 -zR06{DKp2oxKzJSq15ycSIi3f?fRqBl^FSDoQb2ef2m?|I2+spyKuQ7Oc_0i(DIh!# -zgaIi9gy(@UAf#Nr5p_m^m59NwnsO1MM -zLIolo@_1c&Xr9P{8eUfs$`>h6#wW`|d7=R7`D8_?P((ul&oB4R73tvS`4!&zVm2(} -z2g<#QTjW#V);PMpSx(<&3ESN@+9r)PFXzh?jI -zgVy8E%*@c={{jaqvZGo!fozB4?5NuwB^=Pqk~MprI1gT6$!>d$I13EcsoCSjMesiB -zblamvCEU$6X?Baa5MF1S-1b;;4m`<@X!Zng34F$mxI#=&mb$|Vczfb=a6;q5#QnP -zr<0{{FW=$xXOp$?CLeeBGl>nJ;^R)gm7EEm^K6GFjVy!~p6&Exk&|JV_c%NmWCir| -z9;YXVoDSo>+TlqjMbN{mot|t`3Zs0~;mIT=Fvv%p9xGW7M|r6uoJJNyCogq|v&boM -zgbzBx8Kf8v@kHB6^lwWcZqFE9o_|&+s+cmePyl6^5_bW}~;t_l&9r+d^6?GmNSx -z+Y0&vd6!YuXe*)@$}L7!v#o@Je9ahXuq~$N$Th}DldYIuFP|_*8g0wyCGuutq}jHb -z{!o5u6gQX)Xt_)@ikr;k^a|N-6gQen=oY!rC~h`a(VOKf#z2F)h;EcCje#a}CB05Q -zVhl8zOX)UwoiWgC+UV`_W23ggTu3#UYt%NGE9h17KBKnLETUWGHlw!LETOyPTgF6# -zxfqAxD-FZHaQFlc3f`%OEyM$Y?R1A@$+>{PXQBrF$PT-wqJF-DWK9!eRJI!|>0`$6@&2;4u8}flc8~YK0 -zf)gEP5;Y|aPIQ?G^Z|K$aH7*prBBN*f)m|(6m698!MqNA77faM!MrX#j@~J?U|y#_ -zhdwS}4CZy~F|K)}v{Q%n8s%($gW^nS0s+!EjI_tIwN!Flk(MIS$8Cc`lKy5)DcOf1JVo*bw%Q7 -zuhfG>oskqeBqPD0?npGb_EyarDMAq3H%$OnS;T@efQ%S(gxosnc3l5Yp= -zyCbo*Tb>!5?uaDON9EJO>8?lueNf&JobHUI(r4s}U=o{;5QGq<0znppAcPkn^kR9H(c7%s=xy=?qozS$NN2u}0WHRWoZ)O@2f>dz!kJ_>U_k$! -zLqk8!#DFj$1#JB3DHsq2q!LgP2802r1XPRxVL&PYNsLgaN4p -zvN-^=nqQkyM{GWmQU$!D8S|0EX$e66+&`Y*CC -z;A^+#QYo(p_}Xka^tbZ8fX`Fz(ni+pN}?dQDOl!^JJ$z -zOPmBR@J@$4Lo5e_cRKAk;xu@lZ*thv#S*xiZ*tnR#i{T*KjN@widFC=KjO4o#ToD! -zFL8v@#Gdcr7_(DnVL*Y2b~BGg#vi7|?(H`SYoBF(3>` -z;rsbh<1io$NF|^w3-PfK&pC!GJIzm4GrZAPh()phOG^15ybn -z7X!k8R04{}fG{AHfO0S(3`ixQ6b$I^7SPQ7W6jBPqoSf7+wt!MgzEnH^q{)2W5+5| -zfv -zx|IrfEHLKN3+Zv05-4kpq|p~-SD>stGMBzDHwVhvB3blx`D&od7nx5#leWN6Yb1k? -zNHZ|h9?7K>QV$HZMRMqvj0A>!kpem`3j+16k#zc!d_ZYT-ur)=2`07L(s0ZEzuIxt -z)97<@Um&ktpG)7BS|G1Y&!Swu7|8SK^XVsYX`r`N&!8{MhXTFrdM^D)UKQwV({t#X -z@`FIHPcNXK%bY;X_cEYQFd+J>{Qr1NVL*ZD_DCN6qr4+9-4?OZcjSq{v@cRfqcZUc -zgaN5cdd=9goHrc!QcIQ{uR&0hUvS|so3tJ$ZYPP66KzM2-j -zl$Odj`fB#;>uD6^vAW98Y;hITusT;LS?q!`Hdz@;5<1kgNmnRU+yMzJztTHPTn=uQ -z@AA$OH^DM?pwgQtu7#`F0hc#L+y+)gD!sGC4)8GI@+OO&U}vJznZf= -zC5ang4?FIfN+p4#f0tJXXgQVpZ5+U?TYpqV9W -z_Be4Kyugy(_84&%7_3vX$BT>p7kl^O9Y=K~`d{x?>tQ|HQtRQD{E}71&$iW;-4Cl3 -zENsAFcR-X$0AoP7NMM@=E4I~YJ#5R8CNM?=ilC}%3=J@3+>SJHIw}qs6 -zcolhdTUc6x-=P=uo;GO?euL)dJ?+wByp1AyPe_`N-=v%Lp0Fh0ee|B*)F#cwjZ~mF -zwM&ce7J5K$3Q5&?Ep64C!cr{)y{3=0NptZETCR__OEq{WJ*|(1qy=~b-K~#?rKR{i -z`b@8Bi_StXW$88T(S>*u9oB0?(RsL)Ht99t=n}k}UeSl!qH}N)E!KzIql@tldQu+_ -zMd#!7bca41j!L+fKGs{>qO;LYWqM0{bP?W4kLWF-Xf-Cm!v=;BBxAcj&=v>@F -zb^1hmv<4MIeIgWHfIDcfJ`s*C#r^b^?r2kHp@-6RN4v5RzfE1bBc#m3tI4lB!pai- -zF1@4=wkdP)a+d1J9vI1-A*~oa8;=&5LH!|L-II*6-h>UkD8!(x2 -zBd!kfGMr0&5m%SF1`BCR#MNo8#1(Wl;_5cnp^c=-NQb!`YbY8S=`!okK}uw#(_D=% -zG9x41=6X!0%1CR6xeOQ3qmkAwb1m9wN2ImWT!l`0JJQ;1)?*&6k4$!$D{v`2ADQej -zU06l?Ba@w`6F1PM$Yi&~(nLTaAS(g+ML;4TD*??H0f~UD1azwiNCadhpb`;~2*^r6 -z+eJVkAS(f_76FNXtORtg2uK8EC7@gpkO;_1KwCsWA|NXPNg^N-kd=TG5s(PTNg4dvnY9*HeT3_wSR`;Fr_q9=zi3 -zSACjtS0Z*&iPn5X$;4yykk;I%q~cN9t~K{6Ie3EJ(3<;|WbCEY+V~O0hR5kyZM;uO -z$052`8}C)}@FabqjrW@g7^Ym!b;Qg-o%%FapP7OW(iY9tYi8p!bXIfqn@QM1k~VV0 -z%)()cY9oDS8V-`8jr5wiI6|g2(r+eWH&tq_N6buof*#dc`^;1vpdDIkubG1}dRuGl -zH!OD<#HA*GLCr%%H%S*-8kkOsFc&7)Y$1AD3wd#I%B7AphC`twZ?hxfJ3f? -z`;GIyfhsu>QjKD7V5Xc84MwpqP%dXewQtfhg=2wjElapDxLtzMvm7xlg|L3k>hig^9-14^m?6T -zd?ws%^!l8YJOv7k&0c3IFM?}~%|2%Z&xRGo8L!j9%i$j5jL%uclfY*D2ZLaE8aRyI -z-dHIwfo5a3FIK^G!DU?V#vHs7T8#_7SQSr%bfdx>oXPW{(WvkR%Xua&FowLrGF}S1 -zj3HmJlBa^*kiEfDUJL<4_5~|=4mb_&4LW!Q1P$&BR`F!WGwQwZnY<9LH0piva&CjA -z#z}9yj62{iCU -zx(sJgd&Jfyt-%@Ojo3P+m3SGw5V3Vj>o9}nM0z@;<+zX{k)AH84rkI$k)BRzHLjue -zB0b&GdQ72$NK=Qj4Cm1Uk)|$bEf&$%NK>b@3Rlu=k*02`9~sp*QY!2;S8sp*Wa#O3r#q^3K%4zp-+ -zWVj=`92e7*k>Rdr9hT7@k>SqhYOJG=Bg5U%^_WIwk(Q3=GMrD3L|VF{Yq5l`kF<0~ -zSK(@UE7H;(t;bxdi%fJxSD-`~ndpkTu#)yhCOV@|Tu)y`Cc2{=Fp<(Cjt=EAoK0O3 -zN0+h&^T{7^bSf)x8NC#7bSvvHljcVTJCxK -zl}aN2(I~1vyg5QYP5sq0OWkPCkiP{UmfB#?mcIkDS?5N3mV6t0n{_tWbLIOWpEYc> -zXUez0)vTexo+AS+W2ZOTZStM)U3R*`o+p0~GFkP;feiU3xSUlt3}nl9!yZMlNGq1oo^V(llMa^E8ZB$kiQKL -zthgbNEq@oP+0l)GEctfW$&NMza^?G>m~Gn_$dq@&Hny!HkR$JbRqWixfKA>Fd)T># -zK%Tr0a@eYkV;S>d;b7O;kEVr!?b2QD9ym1QoCw9EX~AUl2^4Il8TVg3#zS0D#w4MIcm>A -zsQ~{6Mbw_dQW+B6r1l(=O7I`(J+-Gts>FY$0=4O&l#l-pJ)kxnmP+w|(pI(UkW`F+ -zPp_#>JyHe!6D?Oq4@!mjcl5M6dRTJcujp=d^pIr7U(jdjXpdBdzosm;=3sONzCef7 -zn#0kV_#SOiYYs(=@HKixt?7xD<7c#39X=Q>z*p!=b@*_!3_qqj)Zs(X5`2q3R)>3{ -zmG~8vsVxVi`S=n&qP854mf{C=z1ngpT8wYdTWU*Bv;x1NI(6dU?`_J=o>ys5)}kEW-&>)R9AG -z367Jgj`Wz7I7yXi>p?RgU#3Sb&FdWa>uH~ThCB;GMykhNBwq$UGdkV&0(l{5MyJPK -zBCmmWjRv)}hI -z*d3T5&xTH;*b^v{m%(Y{s5?*~FM?ynQBR;mUJK`qZSFw6Tn$H!ZJt1}yb8`4=iGrp -zxfV_s=R5(sTn`tGRqnAF@?7XOR(ZyX&%vBy1@FE4;0 -zV~=O7Sat$8F1p7G<)v`axab+P%NttMpz?T+R1`7mhg_QZ<$Y8W>zxMPJ}f)V3_CuZmCVbZ8@2WRlv -z&}~$Bf<=58ylf1)g9UsMJYfuZf+c({d}zq-U_P&g0Yml#i}@-TGq^ig$ZH{Ha8JmhE`yW=zXTbhk7M-D05P?`5E31C{8_?aCtDNe}7GA*C9((RRH#tkmKj -zdP5&?Q|97kTCI<_D>b;Ap4G=g$^w+>UVS{QEX95Fh3;xIXQ7XBbyvH&5O1bF-4!zD -z;We~HcZJO*cn_V`N7~Fe*hG>((rzxs7K-X4A#*-9lcJA=O$l4c)LYxk+1N;xdTYD6 -z2zSw=dTYq6#sKZmTf=582I*~mvdx@}SJHZYvfZq~yXbj+GGs2m8)?5j88(;V0ZO{z -zXP5G1H-yAU*Wb%X*B(~ukEQUfFv@BhV@Z4y4720@SQ@_`CfM=DSR(hsAlvParSk1C -z&UQD(lKB=GVHfS$$(Xi8sMh?4&=Q -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 -z32a8KH#U%s4MDtIoqj0@hF -zgI7YUalsd>;)#%MRCt3kc|J566~16O&x8fWkT+PyOJSEWfa=Uj{!jI^FgHc_C;!El;T|iHYv8zX!ZTJPyWoPc$32!W#L<#CF8;O0W(2tSrTS^o8zfGiRZXa&=d` -zxe#xrKHU{E=ixQ9MR$eGC3p{=)koUQIoL#!KGJS3#ukd|BO!A>Hj|={giQ%s$<$lh -z%-PsTmAW-?y!Is_j%<&AEL9EwXL}mQlI1JmB)jMzOP6niDR!~ZnZVr;W;uRm3cm_o -zWI2t_B>oN1S+C!j#=i;gv))E$BHsuPvdw;HD!&$9XPX!az6~R-TqiA-wxw!cVjG>Z-EhZ -z!5>TKJ7AJsXbdKB4|KB%e=vn#4KK5b#$Xb^9G+l9{$Luv4nAZl!NU$qNy6yj(_9E*iG3URa|j%5OZ1O!<* -zdbUSEkbod75L6~0NI;Mk2wEi|NE|)0a`fyD0YL(Stb88*_X2_h1X=k!`me$Qf&>Iv -zfgrnpAOS&EAgEG6kbod75VTJ~kbod75R@h$NI;Mk2+9!!?S -zAZYrrk?CsVz_c-aVY+4OFHinCZPl83r5yYldQEHUmy+=aE!RemNH+WtJ*|!QN$L0l -zx?3CVmGbZ>^qDr=A5Fk^%F=3%L^Ci#hqao%XbL_+o3xtVXf{4guV^*>(Ih-fi?!h+ -z(JXwDp45i>qG|XD-JuQlMspGAV{N!UnuuLgrnMZ2X5!=Yh}O~5TiZ0+=^zNKs57N1A|2^>~jd0HG+6o(bB -zfmd05V?2pB!Bgy{Kc2>$;S+YUF`md9;W4()A5Y~0c!%w4j3@Ie;S`(l$J6k>vSjM{=xv-023|Cw)~T+V_;#xd_enOp|98^?SDm2w)C8aurMrE&>eXYBM1RLHro -z);RASaLAQ#zj59-P$efqs!{9>%#`z?!6^0x%H>R`Hja7&WpXL(G>-ZLm2xT+8{52r -zQn?tm8QXk;3ONT>8RxtKhg<=BjB~y~m7EMY#wzdFOt}y?8>@U{<+2TGjT7FnGT8yU -zjT64HN;w@W3}Mukj5<{qwJ>TcM%^TgS{StzquwrzS{StzqdqQ-S{StzqkijK;;U8h -z)#@VLMUU#OA+s6-v_o$Vo3$9ExAn<3b1q&<>-EWYvj*>?=k>{uxd3mZ{rY6sT#5%M -z>2CxC{ih&k`rTht-ucsngoL)*Xa3bxp;*;k_my-RylC{godtX$=ti%{S;E)A`^ILs -zGoR0c2aU}hXE9$1uN!CF&O*Kfo-xjNoOZqrJ~wLJu^D_0^cc0CSP@?iqsDP}tbi|u -zVdJ
JFG!r1MO<@5P4XzcdHiur07H!iqigOoK47q~^d=Wfh40(bjd@X!v$nIc1uZ96b_5_RhDi|}kJ6OnTA!cw-(9Y{2Zq&Qu -zGx%KSH>`bF|JJ)=G6M`5dpu*svJ<#*(LGiuFNKrFMbDUB-T+fZj@vnd&w{X#<8c;o -z5m3C4FNIUalqYWI8zAwm_eDS=pd!8kUNug-;|071o-$5);w9V#pBVex@qE4j9y9iN -z;>Fwv?-*16I-t5=ihx8wRswoY1SA5o5|CH}iGVBxB-TJ8AS(f(SObZGECnRiKq4SZ -z0f{w`2*^@EVhtn$vJ%i1q2BQvI0RR0)hktS%IKC1q2BQvI0SC1q2BQvI0T(2nhN^hoI?u -z&e$3zPaU{)YHIpS=1=|`ZyEbQpwJ&S3Qa$EF*9=Mll7P0xitO3nzvmca~@tpTXa|0 -zT!Qz|S$(92oGNZ6FHl}x?0&76&mRH?UG0;0bYKqP?3 -z3J`r$oD>p3WCe)+dWHZZ0Yp}SC|>}P03s_ubdvxg0Yp}Ss9FG#03s_u)FgoD4;_g9 -zd#|2dVS7Ho&tr&X0Nl97r`~gW}mZyXTu8P -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 -z53HW*`aV=$R-h8W}iU^W&%S0&kHw -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 -zpH?R_&i;Coo5!9fCw)D^%`=cK -zXF(nP6Dw6$cz3m%8MN0EoCha0R~D{k6*=-^*r&PD@Mf(kELGrscClMZ#w+M)b+k)L -z#~bJ~)sY~thg6o+q0E4==1Ah-WfghyZ18EWMEo|(={7ggmUiR>AGWO52W -z&CYb01tfKv%jpAma4iJf!D_fi8_B|9Z6povXR?j&VR9b-9w}`~A~?OV891nplwz~m -zoWhSYp2jb*+AcGf%nl_JnzRucj%Xw4xRY@k-^X|!znd!COb=DIE2)s@i)TQ;H(=v8 -zv-(`ViMD&lRTT5^it54_G)1%!=1uS*P=fF}=tP%&b)>O=4yF1Kn -zwAvFdgF&se0-b7WA=a{!seGKBOy=9^?M}0v-tJZ$Q00!#hAL020{gYe6ueR!4x1}z -zeYa_&d)@JBxX}||1ukte4e!z>b5Umd@^~Jb%HRs^Z#Q?*{*aOfr@V0oobmU?9V7-gN_u^haN&^MNhkFrjmJyD(qSF;A6 -zJy~7?-({zL0}1jRxSUn{29kzy>*^tmjv2d@Bc0zz^WDKT*yVNR<1?zuf%m9`Df~IM -zxl74{YqS-OPw|REQt3=hSxBQ*q(MN1<$fQp=b?gY)@FqMw4A^i!Ok7S%cf2 -zDHnmkPP^?kxg0)a)$V}|xd497j=7%*Z^;`GAHJex>~$7lq3THE -z-=QrX<~-WcrKG@I&6SGRXpU5V8@=Rqmf#%P5;lQe@;EColMN;EhuP*1a|xa8GRtYc -zCn&*#+F%mDmi~?v`vOTrsdY79&s6mUa))y8b9FFHPKBfFP3<1{haE~CNc0PKzdGEm -zq`?YpxGS25pKButcpZ~7cmtEO`JE(%%&jDam0TF`1ydp5b=q-Q9Vx>WbugWuU~)RY -z$j)?|X;k74&IOw`l8J-bNGdikp2c@Fp383{v(4N>54mGSIHHa?uvKkN<0lzU=Toe< -z+f1a&4s$kbcgHV-es_E!oM827{C#%3Ln($U-SK&Fr6*Q~PiU=axJzqJ=J&AUo#y@Y -zh9{l`OTF;|n9y2FF`$koa6j$nR0`oKPplNjwAN&FYU4?~nVrnxF1EYVlzE~mNrB0UMC+hhBV(&emno75@ -z;c+ZjD2fH?qmCjVMS4d>MMXfQN|oM&^bRTtB5jlo(xo>kArJ_Rv`DX^g(M=<5+Jk? -zNC^4X%>D1&JIyoyy?6e#zJHyyvKA*N+e0MJv!A`6{k|s$G2{W-H<;Lg<**gLh2XFi -zwuP;0WI@kn6|%f1X@Is5W45sO9K!1vqC%GTq+cu8Wd{8W(9ihW{S5px*a3hYz~9~h -z@UBur2E3k^pY%L8;1yPW%+oac*o$&bPm2Ms@Nx!E#q49@!r#JgFXUuJh6x{n8!mj# -ziVPRt2fwlKCQCg`_@ErOr~d-u0DHE$iq8R0M3y`&96P{$(3E!}CQSG=ylH@YKc;dZ -zPbG=jRC$4-nzYaKlIOz#8`Y%!rox_n158hZdEwtK9J(%j82({^>FJ8hLQHu1ad`GX -z`ZpNSg)mj0^PYSvK4P91vN(@m_y^LDVlFS-Qk6aguN*k7;=|!tpeoG_UmMVPvckB~ -z_Z)KG(@w=l%5(mj^bxp6b{Zq*)I$DsyRh=JaMpz@0}rzWUz9V#-4~n((it!k3j$ds -z&-<9u_sj8l4rhC)%!l>uH$Ckso|SgQRMJy&Ae{wsaG>|u%Jl`|XDgNqwyHiyJd>{b -zuzPxBHE_WNvl>|8^#i5{F{lC4{TPLX@)s*|3+3SuB~R&Vuy5d;*~W)48Uq+cjL?A4 -zvlaaXNa%|9!WmT`22Y>sumkYC0n9-RW&pDvBet;eVnu0TB^)B_$#RYSohOS5>|1zv -zcEAC+T6W2cm8%Op;gE}-C0POA!uhfTj>1s`icA>s0mWk&j)ja+h>&N$DvTMAa$KA;F*>czy$9dKrmxC2M|XvXBM!}R$LaaPa%Sy#Oq`pPogS} -z3C@y5Jr0k}LNjBK13}+n3I>GRmkF=&DUTIaPw>`6C9Ua628K+uyvix=Sj_?9)mY$QyJuJM8FOJ>;V4$ -z4&Wr%0e~IA-`)W%g@U6daMbj-kD5Y0fTJdG)bzKHnwr5z6Kpj9{zg+7Y&5|}^KWl7 -zNu2IW|GA-ITrLqz?A+GsE-fcRIn65|6vU_Q4n)WPCaoF&ZnPosk$6t%=SLBP}=?LZWA=}9oh%>*=F4l}*F -z342&o>K$8>pP4sK4YUxXeW6nMb!(`oy3A;#TY1r1v%HfIy`*2dNokP2ZT(}N7QRr? -z+{ezqp~FMHkSNpF+^9OR(Qp-OfYc(BOy5pCqy;VDMj=9UfuVe;6}qy$oTqE!=K0sR -zzh{lO@drOTpAO6PXHj&P8^4)v_%MG?;k4+5ELXdm;uVh;)iUz^4&IIQJ1pJf5Wv%N -z-izltLoZh+cSlV6)>)skK7@{fsJjytuN_|NwDN_C5G!kt -zhm7JjSMcde3i_8ZO -zwQ1d@!am8l+X_w*c7`t|mU-;gW!_Hmb(zEn%#ROUoxAJwW3e~c-pQsCC0Q#`dShA1 -z9(Pf=WMbxVJ)+U#*cGXy$Ju*{)Bwwq5d68ETLfxPoDj`EDLeMd%PB-BvH3s8Cv9u26cN2I=+)IPwyjT8^0ujw*a -z=igjzcOh|2t~pPvO)F$PT;}ax`fg^z(r3cAwq!rucT1Ot`K%W1gv`4Oi^TO1u`n0Y -zpz7+-7znKanX;4(4sOuaLO}U%i!lNXe5;F<&;!YUNkF(4w -zqBB;PG((3Li;k2$j-ObX=_)&Y8b91F6+nOB@dC{;TH}+;b#Zva>T_`w&uD>V=ZExH -zvb_bLpUmlKdx&k9pJApKjZlhwS8qGWu{8+r(02;TE2`LQS)GjOOs&%b;%Jw7>D>#H -zCfYWzB0dw;wc)y3F2a>e5_$eT0!u+Q$+7_T1Wc3Zqy=+Jy0#YPx$lYhH -zkBX91-QgDikRp>>W*D)xZ5>+ -z55Kk%V}{cuYS%tbSyJ`aGwkVmN~4m=q|p*$R?||C^L$8=!$waJ)83dmm9DN~wvjUN -zSwePo!uQi@&i-cME)sWYU-Ow})(QUcs?gS*$wv_K;V)qmB?3sj)AA-~(o8Ym`FzUa -z+B84UuvQQr;w(qyRXyc&d-&{5FkjX58k$zYBBZ?0tE}-}(&Tt*u-8&Z*{a#?mU}|N -z7lmp+|7Z}A7;?^`{Dj3NqTczBk~u0hGhLq=grBE;Tfs;rB3xZ3w!(JG9fe@9*=ClJ -zY;Bm{a$m@8OfOn#*k+>;J^8*iZ|(dU+XvFM2zrOT4eVP6J@J@*&EI~D)ZiZRjx|}G -z`9$T5=nVKSkWG*N@a*I7hVI!$%Eg~?df`RS9a>NJrRs=K7<}$C&pX`@Zm3Y1NIj-m -z62e9F$?jsT+pQ6xjiqUJ3H8$FI{QSDE#0)-#_AMDyQJt>gx$s!ZPOH2S?r0I;U%v) -zrJAR;j9n_iH$<82$)XPQh74OR^lrgDV<%}EWT9}0M90+8?=tXwADR1rJ6lw}^I9D4 -z1+?z$0Rr(cPe$W@CasMS+7WlZns}}@ulEThkCHnT+kCiKd=GBY=hn;oo|v0j&9KC91NQg~~Lw~YAC;allZ9~0>1njMMA(0;9l -zoT4is-UEHoDe``Cwh9C-5;wAqC!JYFId4|#U`gBwnH5!*$If}0VSglv|Io=U3q3xo -zwr8IXeuT&Xo@H+4*UKuU%17(aSxN=M@|)0(HA)dY -z5Tl8a!_>x~=0`tZMcF{sYvU>JT=-9-Y;Ib5wZv@W57;ejeVP1{^99@K^k$Cl=B4G^ -zHQ&$ijb7@}yc{*wKHv7D%_Zg`PaKC1uc>{MguYtrOEbG<*UJ(&I1&jZq)Rji#>BK< -za}bp$qZ3xJBvCHaRe$+cWrVxv9dZbj-zWl0G&b(q>o3)7ZqSQQ$i6(mB&<)vYQ1e{ -ze&>*i!s|9`+ooAa+VHDnnhB -zUv%{`kPKwdDu;^aIsFqcEVb+&M+54 -zo<@l6oWR|u&CHOTH{*9{CV9~LG5^@e$@XUajD3jEo5L5c8+)i6u`hSohWKmSYR*7K -zrb3p{6-K43n|J6kbC;)J0mjvwxRQc7gpuxby=O{`xKZa9RBu-&{oKWA$w_$T-D|_m -zK>`j*4rD1CfiCU6$@uBJb@`=vIWCfKBk_0!L~sM_ChbCYMf0fTJ687lH*OwrmUfOM -z6JKp5Z#l>MT;A6U#S+Qht8cv7iKKQa`xw>9=Q+QHhNM#bTxKKH -zI3DM@t4c#Q*L!E=xRmL^+8Zb;6+}$TQvUMcHP`Tp1F1v1I<4M}_IOwc%v@ty;wE|> -zg8U|rn-BoIz+mEvK+hsHd3%W0z0w*>ct+sX^6m*+L1$3QoqCfFAH8R}+O~_)pH0hp -zNgt_pylsBvO(C`J#|f{=WHYT;(wKR~gPd=V)n2A5PIGdKIKehDkSU)OV)W&f=%qvc -z=}}(8p<|uC_0e+d6+gspVyHuZvIN>=FFI~OSK2gH(=DLcqoQM? -zXwkv@*0&{-8A%ijC7R+zxk=ffxYKllnv_&|iw!orz0|!>as`m*<@aG4u$z2V!hig> -zxK^~CUbj&QdcNHvv({O&hx*Gp4U^4J&KW%G9O_8&?f7C$C-^sajkJCu&eXk)k{o^MLa|r}|x=XJehBE@e&z=}|eGpS;8b -zcA;E6_4eG;aE`Qoqq>{-XN?h~F`rQ?*0=@R|?y{yZJ`D~887VMX00Ui=10frz(}f7~=itkWG7fA}tz -z$xAs01wSzA7>in|J#AnZWNzfT;~$A!kmBLQ2X5+8s~Z$!x-3Z{OQZSzJWpdQ@&2|2 -z)h+s#TjN~b1>M?~UJa6jn>Fiav0YaE`aA(O>*I(7
Rd2I%@(JQdsI(=1q)(5|19 -zt4nPhp03qPs^`+{o11S%&2whB$4~Yq==*dxaX2|Xmp1aa6Or4s;;@rSl#w^F(Jbj+ -zelM+vLrm}34r~V+wr=bt7%SimV{_ZB=AR&cc!Jc7o+)T*n1IMPTYS@dTF*PJV29Kp -z$Bqpue4m`YQfyg*nJISINpl*K`7c+Ee2bbWk#OM$61%U${yYVd3 -zyYYDkn|6-wz;@;fzW3Cf^x$QiJ>IXCVt70-_^zo6b*`WXb38Ek6-GJS^20!C^_lVk -zNs`WZSL2%&rb)kxuc^IS{FTtg5cN-utTwI9X-QQp37<9|)G|c*gg^1)FOffEKbLo7 -zjv9kYOzAq8nKU$cHNlVnPvCUp{Oil%D4Ov)@t6{eh5C;Q&o%dL9Pi@o8JlX(bK_|- -z7LS)A;?^#rIt|z#3FsBERZ%-5nd*Q2k3qL9x_(N;s=acdD9aBuBf+7!J%u>1)Vd{ZP{E>3TD~Z-XIjb&mOi5%m -z^2wUifgbgTo7<>Vx1PEmeRkg}d&+zvT{V)=7Zdr48#DX9IQF$6YamYxa^J>r?6JW< -z!LyZ%jv7Hx9e#(0LzV_?gQ9T5aQiu?o|QV$M%DQ{CuT032^V2BKUpbYsnIsN%Jcf% -zYsK^A7yaTrS4;02zJ4#D!iJCx_ShZWKCPWm_ew@A!;U?xvL{Y%Q3a` -z2onnvTN7s!`<@8($nFRE* -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 -z7#jrX7@FLzZ5ZEbFt^v!4=REk& -z_`viQv&(4r_>SdETkN&us`hb1k=#CW@m2#7)wy$jHZG31k+bWHe{x{7d*Rf5>D*8v -zy@dF<)cuLy;hQjq%<$Epdbfcm{)Zz9>Nt5g=f8D6Qs(4q^4JEwalFF>b!V}#=xJqr -z+7Qa7l0`zcI83ID+3tm8k9J@Nv`xIUWyzaG!jDUH`6RPJ$^=9nw^S*+H1|rNq4(rm -zA&33Cu}6eU7C*|$JK>?CZ7fpqoxw5ZRLO4ZO1Qd-RDnT2nm74CgNuKH*SmIfah0Tk -zp)%!3NlAP9a`glyIOUQ=bO -z-b_$V8x>-4393wlTd5=Z^-^6u*0F3&QM~3|o3;%(%02#`ldn3| -zwnMa}+e#3cPzV+CCy`bxlPSR&4~$s02GhQwWjS?xz`= -zSdwnCf4aRin}MN*Z9sG@#AN|{%GUj1Z=xCg=;_ljDfzmtg1ujAQ%x_vC3}?Hz2ALQsHQ$Drr1dsc)D*i#L;uba$=HSrIn9w8 -zMq?6(hQ#hCzc=_1`yypm-Yv_cWcr<4q2hgIHVx|iId@%IEvNGIWXZKp4jj8P{-&0xsS<5&rj3k+0_Vzk`^jQmW)`pYhtS=-3+Y -ziA7Y2$rLIlid`8AW9(63jv}V!?`?@E#HTIWG}&RW=Z=a)>$;$_0!_iptA0nsxqS_{ -z8gBD$OY3wWtB2?9sqZ|kxTMPRnJs}Lg(vcn-Vkx8l29(B119Teg|kePVtF5m<%55W -zyghTyVcS{81VZGOxv%IKCXsnBx7XVv#eYkZ%PNiZgs`n-IpdO`4^s<@eVShyRXP>5 -z?_qsPz3jn>hjvuCBH160_J$NON+j6+G|jI*_AeWEr+)O=v(hW-{wl$?kV;wCYsqAH -zNAmaxRJ?VB*F+M_>k+8zxQCq#LAH)`namjJ&aHb}xMeORv?93-dBQ?OLcXV4Z`0+( -z_QdvB*+U|tns0QNpPvzVy_WQGTits1qS)RWx>6Yic7gQl6M1sNRM2<}|VycXR~<*3QbZx4A(}%~E64k3V34M?hsxx?R<59Zq7Vj^d76 -zLvP*To4t=K$c0)7kgk4J4XK_znP&reS~8ya9acZJ-1uz5Za2SPOKnEsIg8Trh;0xf -zvOFf$Z$EcJIzC9wyM#RdgWusl)wkD|!^ddyaDUzgLGCca(u5d(Y|GKR1k%;(8=+&! -z?S^Q|S^AHZv$JV6q^oC`oEwzF)_F&fqAo|xcyqmVsCcW=?qg=Wt;?CJYYuzW7Yw3T -z5FyI@HYAGoQz8tuDq<~MFS8TNel7;08h`SieITnl{M>T(NZQjUJD0jcE)Pe|*G4zZ -z7%FDBo~wu(oUBaP`Kn>2mmalV_i5w!9%FJy)%C$X!DL^Llz-F%scYPmrE!CN6*||_ -zqf8ysqZB(#Z>5BP_s6q?pOU?M@@UsW@o3lO`*9UDW_-DjSYiA0s6K9H6TVz^27NxO -z;C_*xW-ndz0q8@%+_ZHZs`KnLF5^czcJyvPuXB3T&E|z?qn)eU^Y?X`V`N=+M{_4j -z+MvhUU^FK(GTLDlrk!OiIeLi%;D8iG}H|RW62!whB5(O3ciZAS$u1;=B>}95A){&IYe2eTaPa{KC7R%cEDRp^r_Yr-*Bkb>^MSeu%BaU -z6G&s?mK)>r;Uq+tjN}=a9x92njFJfB7~>o}tHvJAInQCo3FDCBwB~vCt3SxEex0f* -zXHGVw3NMuThJ%AyE%e=Y@`x-6K|V#~TNe#!mX8tz#?`$KNB2FPEHDPhl8)q58a?#KwIW7bg+}NkNfi -zDT_P$9=H7U&HA1+mhRG#SVViB7tc%Xf-7i2ac^f=XM>{XWCF)i%*zu*w)$^N7x3M; -zt1ikWjy~}SQ;4_k|KU{U>x+E*Mrtl^xrBN@&1Z=`6nQAER`~r*^Jh5+*B>|^b$*)V -zF!;@4D4T}1kM=2}tjllPz0s{`#?I*i>Gxjpu(*`YsJ}5Nboq=<5z0|1ohkIED3;j7-cwZ**CqAt<_{Mc -zi5VPgwdOY#zU0*InQg>hdPd#CA}}SuGN9>Hng>@4jI%mcb$eb1d2Y9J#O-hqJrGKF -zBd*RXW62iu8QhL>z!{$KRl~WxajZtS;Zo7KM?e7bT;T3VSwWxj4n9sfEU+6-Ut -z=8cuL{jv0&T>8wQtHM;!HkBoaoNb)Bvmjo-{dBuGXpBr-*yF|0*ATFkAV>u*d#s=F -zLxnEgu|LBb>ULS%fomoG{Oq!RL$J_7m@BL`i^H|N>7+hfZS0xm{QVrXvqtcYdqe%8 -zoQ^zqX?S{Pri7f}G{tdTNhi`E$II2+?II-vHnFmqxNJ_Y^p`hkoM?J&c!cA_?0ar= -zSA7E1UxqA3Lp`4-3^FYoB9y5{+!Kh?IxW8AsbtVMC(NYpZq;{?BmG!31r@!ThtIwt -z5kA)9DV%mC{+NZFsrp6ro%bev*2SIf{ORUQN85b`?bY~xC{j!6LsISDEC!|aF)863 -zxL72lnPDwk{)pisY0mWhsIKW%e@~Cm7HmPnoPXn_EY|o#(z`682&L+G$*GMhYgt*3LHugF$ahp^k=Su(a=W#?L=Guu}NtaYE)R3-8w!-uV{( -z7HCzXx;)TH0>GSAJ?+K>2ii&-wbEd-adU+-KPz -z!=T7z$HDP|<)`Dkkb1pV(j1zGnvyaunJ6+>t`9n`^VVw2v))V*F-X;xIE7eo#Nyo> -zCxoy=2Z*Dzl@lc8hm7*|1D)w-UPa#{w@;E8?@8lPABGSUzE2%;J)}4WY^^8_Y61y! -zw{qoa%i_!3)xtP3uTa$>=aVu5@dIyU(_NE=AiXjlBc~71Pd|;q##*{ROpZvOL{tPg -zapLaZ9X8hF56-LSfj|z2vocg1Tn?S~FA2ENG}>t5`nG|!yzC~Ox6Gn|7wsG=G|8TLFv1Xde|HAvVakA}y&eCAwhlV&}c=Jz>e -zK3uQ@H3qk+q0D!ThSZ(#mQTn!y#)yw4_1Od-pnRne)BO{mUR7m#$f@c2)h{RXDF!X -z2?>YZ%fRj@%nYEu}uB?`HWHLdJfpsu{2z@^@q#UNAHxtn@ -zZ8uu1LKyfE%D~_hFt@{&VQ$N3QWx4g9-^Ow4jD40YMsN58!E#pC!Gxl(F>IGRh46s -zR%r4r#(wW$IJK8niNjXc3s78o2TSCOK54h5Pzlm(T0?w -zI;Z?j@&&$?#g?Q;k-~@_88@w^{;&!}t+~C@186%~8z-y3dM>XLc4cmbZNqH;%EX$?^PmDd-tg5=8J#o7_wYe+$kTz_ -zDkbzaY|+f|;Q0y>CFbcdO&m^n?-6kh_eN&*8d2uCTE--K5yBUFT>D_dMyO9y -zf!Rb4VyW%efDPNx3ZK?n1w4u@O2g*ou?;CS;|a{}a!cc^&Y(I*md)1!0pF-XhuiGx -zjZc+CAM&!XDl;ZJ*BChsI#sn12I2UGy|}%$325|!v@U}HLb}bE)-TVHb1-LY8A_Qg -zGI!gpGGHZ|I#LtvA(-C=NX}GzvoY%;a>56?)K-Et5=vqkvTB|;>P6j!T3)@K-(BQ> -zk?ozgubZ;MUN+fhcFv3{7XDhRQTx3{;B?x-?kgwM8O`_<6AdT)GSyjpBD%Ir&r4HK -zs7)oa4f1Z3-nT-k~L%7Et_z4C$ -z`_{w6)TrjSk`zZA)xr-xU$!RSMXW&t3%!TyyDcuzXSe)eqkHao)&7M)2<6Wytdr*A -zmr4mkaqJ2Y1wkX}CqNS<;AX -z%;0a{V;-PzHDVxuf#6I$j$KGEt{>YVRh#?Gjz`>EpDMaAs88$N^U>)a?K5?h8jDRY -zMu}q_9}8#5xJ!jV-%J=bS86LI_|em|NK2if%~kH}n-R7po)_ptuXQT8>bK`AM+4Mi -zcn(h-NhNcC3w?5qSox1@Y?#j4wYJEC7+Q8s*1Ob{Gor^SA@}4tsb6M`y -zDd;zMY24CWv?ftf#+Z3C#4R*1+r2Z#J7TXVi=P&%-k!Q+>v-_w$(xW5-&a4HV2|s0 -z!|?7*$EB2_{e?L}FnGP70mXd9(jX>S@w8SCRd09v0JKMWH&y8YAt}v1M=fGu?ArVs -z*X8#+d-w{ZCS#_wgd8VLJBE3rh)I2Ax3dLzD&4ib!W%vq&>E*a?!U_$7(jW5ZXvjM -z7N-XmBiw{0RnVbGr2XL*?~p^gwwBJ3ccW_yA9jB~6ftc)9*LANj?u4y;(aZ5uexn6 -zceOb6EUj>er;Qm-HForDO4_R7-fjnJZ3e(c-};PkrZ0psWg0hfc)|rk9kTrca!=C2 -z0xbgtx=WR-(ImT$(dK$yA|x)I9!O0xGjQH899OfVTM)VZ`+hKcpV=F-iCa7uyzUk_ -z#xiOJgS_7?=ZWPr5Z$v6ygd1A*j(0Mm_+GJ@Tct7&me~d=goyH-YTzSyDBdb5rLnh -z1`tS6P -z373{-hBW)nK&6Fk&9z{o!f)%|1kFS{t|T~n%|Lz3f@h&nbwYtwO%r^5uYId4dWaO6 -zvc5Qmd)S@X{64Wh{?5(*yV%?5b-r^W2_>iwP6LthW;d5v8oqlzCW)Z3<+~EylSfDx -zQ6KAj>x|&w3878aAKO`)*eGg6hh)M(z4omSN56Q;E1FVGP3>B`gxhQ3V*k4(~z -zLBG%DQ*lJk{`p6|A>VIpbdI505v$AD*k?1k$oZ9`8C||$3BR|FN(reUZ}Hnzi|Gap -z8*ar`&B8dp-lFuesQ`Z-#qBu{71@-SU>h!Ov)Af&I-TzMjj31i#Zz=EPaPY4r8leF+O4=XDC)Cs*$JG(_wQbjPX|(C_BE{-h)w&ceu5eMx -z&fYXqEk8yzd1X*mx!G>phxHac+J}In6-3OO#P%?khhV)F6}EQLcd5q^s=`gmjf$0n -zYizBV3463pRBC>rtmN)?Xmc_ba_H%_OvkMdC(F7f&P=q&ca-gZrM)to@3gCOWssr{ -z(qW1+^u=FEdUre^f6c#oLQ!V?NwbM5cObo;dvt>~?Qa&Pfvp&%O^K7pa=|jt-2{?o(8<*_A5GCq^oY!pm5Cyp_f5oM{N=J8!=K -z=VOmpGwdg(6xFZ9Je^%MbG%80M3!r!^=L`;2b|!PXP%CYT{iX2h!WZT+!Qf$XeIh$ -z2G#@Tld-oo+^?AKD>o-|;GdWJ{>~76%sHG;ZGQ&W0h -z+}d2Gg6xI@JC*G%-^>QgFC&UZ4Z+g42hDePJ_Rz1C5G1@_q8F+RHtzM1UltEX6+d}v?#w}|Gx8Bx4J67?Ch;rY(9@{uM)Yj%;9_Zexe -zq(7|+DJehLL7DR04%+U;LQo*IZxT|u^*?X>*$NJ;eMEW!{_+~Q3!w3Dul>8~J -z1>E7^{p)Y=U};6BADN4Y&5Z18xJtOeE}zbKfkdtDk6U|jaK6)*BGn(a_Suy=#z2Oe -zOP7?%m=0~9@7%t(6eq9MflRW^M$>v$3E^<3-fo1rEhExrdyT3?P$VJDR~p%= -zP101~1YGhYGf#?~*~P6HT>2_4G&0l;L82&D%KKrX{H&IJPyg$G@y5~zzzQJ -zQxNy!YGETrYH%5>GSFvz`1;bW$}vxC^<%168`+zENqZ49hxXjBkUnKlgSQ7*cql8X -zFrMAT&>{w9e+ssMj%H&uA1A+HQKHLd(kJ(HsOCYtMM&1zIi7ySTH;_(?3DlZs9gwU -zB2(#<2iLRj@4VR*93hf2C&#Kws?c0zXZBhugL8L+5^4Wst#M2Qfs{ -z;=MhtjUC&F4goS^Y{g+X( -za6ZK5$YNSq7B^E+kVm%SVp`CvGU8O+9i}F)=@xaQlr+_-><1>nS?4N~?i-u|68pXn -zwUoOZHu2rb5CYRzxjc`*`Y2{jTxxxX;kis{cz>8!V0k8$lgO@FjKGZp1_ -z$8IjV+okXH;*Q77S)Fvjq2_NrZd!EK=ZFTB8(u;5n7kJ5PZk`?3(PxXtv)Dm;s#xP -z-k;@lf~S}PKk9CRqta!YlJ4Hqi|91Lp<{EeI-`{kb}|OL*l``g6rYU2lnKk2LF?86 -zPhc6W!T{UF!)dlz)-$-5G}z7}6wGS&@r+K&{@&=;`IarH|HZd%c|P8+A`V^fad5iA -z$3XauXx*_1yiz^9q3#&5V>9R*l5;_7<6#fNSbVsGp-f}BdfB!n27B>ybl+X`t$RWg -z{L@?WxATUk>^;N9wTUp3Sr-H75>w2XJ*UBRE+N|JQ!HD9;hrrqQzSEbr7NI!Yi^H< -zHdm%57{sK1{JuY3j#c9jZb>jNqb$8)#JQYTUa!Osj`}q9x_YN1p{Iiq9lc)ELnR(4 -zv(pOONl1t*(2_9Dv0XYAij{ZY{McR*xcDVy{e^$QYi4tYS{BTfy=&gdcu$rzCm|%b#9qro1sZ-6~!%o5G3joz1iq -zkxrjWe5>iPkv}|Ao0So|91fmEKB!B@Ria-LN -zq!|IUi2$-SXcGa_477=W`d82<0-_l>GXScHK${4VW}r<3*uR1{5pYoil+FJF4!;%y -ziUBAFz#s(B18`>WRgV4qDmXI$&;w8mfM^EJ3;^0=Iyf@`thvCM!Pm;6f23+~H4zZg -zz?lJ1wgzVgfJG6wv=k^?gG)<+Xa>#W=qiO)m -zOaJ}{`=etpFM)XpuonXe0B4zhNUdL;1ed%6RFR;44Ma0=mI<7y!TnDFGy`Xue^dqi -z>Lh4igZA}bNXB1}0hhf0npA)E6c}c}8UHI-1;qdq17HyTAu|7U5)=bq5(2{vuqgRj -z0N5D-XbspId`$-a0bo!JzRIzGOiRCB()_otf;Q2=WaZC<3ABm6rUXCV#0I=g4v-#z -zcSZov15gZrXa?Fuf0m(tIS+OQKr{naIRd9@@SbV^V$?6x`t<=Y%mC8;*MSO(0VoE* -zAp8v`fBO^^17H#Y!wjJI|2j}Xo9Hjd&3}*duU-LMO$5jT@XiPTMGNIoKHhGY#wv0E!~8GXScH{;!&4{z_$j;Ro0m097sE%m9!FU}pe!20&^87yzzv -z{8v`~B|ZQ90oWM;(G2VifKxR%Gx!y${+(d|JO(=hfNTwR24H9K7n1SUW5CU@Kr{oF -zmj05G|Lg$#$`3#uf=f$*vNgE0^q-Z_pB{iV5m2`NAKFBJ;j0e7tvEoR2Uw&6r9IHT -z2B=Vf@)N*2wg55>xEJ~>Q2f&v(6RV)S^nospko1mQqZyZbAtWzC19BSg17(V0JN|F -zg4_UBHUC|}|FB5?lQ#kkvtRJ`pB#W<0L(p54E_w9|Ic|)41l=@472}41Aaj-CQox(_i|k1F%T_?FaCi&jTz{!6Nl9h$BD@Sfu`rSHC+0 -z&N2Z66kO#9L^H5R1sV(=Hz{numu1*czd -z^}jp-?d!iFH-91B0wDdXR{&?3fGh!LnE*u*ILrJx$9{ShoMi$i2Pg(WGy`Xuz^NLX -zWdhI)oMnEs9Qrv`gWp&U$TVP>0pjp$0iYOwVgL+60F;7a@Kuie{3>V@0q6lJ20%0e -zX9fW6F}Sb=fMY*bWWX>3NcUd{Dkuh^82lw1ehsUj7yy$H7-nB9`~gu4b_RbzZvK0u -zfAtFB%m9!F;LHG^C<12&U+36QuYxlJ06hT30ElMb%m6r5gEIpFnt?Neua-kUr|SRN -z%-}D5)d9FkAMhgqi&Wsu2iR@>cLCrkM?ifBzlsP5rQjV~07(emu?0wfkNK*s`zW}ssMoT@>`0;Ii&@n^*sXkP=M6chtc41fpf -z0D1t50T9hV`})r^^e^W@F#w_&xXKaG%mnX@0912?A^PLWLvi0_jWcQpq(S@ -zSP}{G0oo@(fZGvh=?Mtr8;CL_OGXOq$Py$y0D(624w9FqWbOwLK!-*HGBzL_XalEl -zx`c?V%!=C@{~5Wms_XLeqGF95O`iNNV}4`KxuPR-%X`zz%pf|VCo_YjnVG?-=4V5; -z%?z?BGC+=|$jo4iU7x-e6NOrfiHc@s1})WQ20=41(MBWm>3cEJ!rCKYwyS^{FoOnR -z_yIF$5*i?X(*2vpzzm9J-_Fcn?NtZj>$GlL-qW9Lc`xCxUeDbCEx@ac8 -zuBDXt`jk<(KZ~zJttA#kGx2pxwfH({CcZvter|u3SbRT;#U>l942lO<2FU{(TO!A? -zGDw7ni(L!O7hkR1LWkP -z0dlFe0rE@dv-v?xRBA0IDw>Ijq9YO$bw?y7+7@XsQ4#E=z$-sOt;Iw|GXvyQYcWyL -z?AzJ$Ze`GT-yp<$tqj&)bwHOk{tTbKr%QC{r4xMf2l4d@qc%P_%%TmQfvQQ}w&j;c -zW|>>y{P;aHXc9KeUh(#p4>q>64M{AR!HcH9`2#ax1`BdO*SsBmOSokQ%pedrG!$wKA|WD6P)|X3!*L2FxIdR0R#QO`%_aC^KLNg}^Rg22Da{zzlXX -ztzot#`de_dGO#jOko&oY8GIz+>Z=Z%%PiHROLU1Yxv`}eYi?{QqPVeT!EP3iwxh=R -zr&yZBT|IY5-f98S2qDbIogl%wseB>}}v$SCr -zVmt#?Ow{WZhhdq)%%X*-W|`p!%%EuI`mS8RiiwJ5Vxm-QF;O-}Vxm%OGlOi3#6+dm -zVxpp%Ti&ZF@-o1rncYOy6p4w7W?lx^Qtf4c*%XP1LaoI_Vxk2xo@>NJMKdu`OZCGq -z**EPgUtw0;y1Gd5buQR`*F`h&bxXDQI-4SiMKnd?>s}!@%o2xF0W)9*4Z`pPW-xN>_>>tigWXJP -zm`z%rC}jrBptL>>C1_kb}o -zXc965X21;049pD5O|rnuVD4AU49aT`C#(`?`w9$@vngT*1ylp%B;mJU26w#bfG*Wi -zN_<`RZkp5z$!Cf2F$==*cg?5a2U2(VwO1=&GRF(OtZ`;QZz;1 -z!Yp&9f|Wt=z|5dX;F_FlSzMD-G;>YPtkZ|K{Q3K$(cEJcxuagSOqgEn%P>~Qf+H#(9G5PV>@(|>UVe<;2p0z -z5MSq?M3dUew=XVe)sR?}KR-5*6X{dId+5?Eewx(afhM&`ph<11)}#i_G^w*rdr4^o -z*Uuzum?aLU0%pJrmT)*(0y7vnc6@4<8Gc}8Fmmkpv|%=BeWH{ZFoOo+LnT%~C6a@B=G@=3&FE6@S1gGhhY{!suF;zziIQjpJ3W$ys2DYjPg%dewnL -z`jaysP1~0D^k-Y%OPc7?&;UO_a(!3L^qqeynmMFjU8F<$Ni*l4swt9K6wRD}YN>Yq -zDVrkkb*QzCEu9=T%o2xF0W)9*4Z`pPW-xN>_>>tigWXJPm`z%rC}jrBptL>VPiMrCNwB6tw+yXfSxFCUrsi -z63F`sY0u#%NW;_I>sX21+W>$7EH21zq!P)g4X -znuk^fq1NK-qM4YeIwJ9Pc0}UqY>Iw+`qP4-=g$lU%picu44A<}XFk_B3|ll~27^dH -zKVk;W!-iSN{R~uQzziCM%wT5G!qbM?QgXiqS259o-RwvD_zPwR$pZuAXo}1XW{w@6 -z8X#}lz_UFtgQA%&?=98tObeQs8I0}FQK}z*UJ&&BnW2Cg1WK6!GuW3Ac}@6%WB=p7 -z`j>zAyWjopcYpUE|J}d;H~-?_maNewy0oA?bB)9z`czG7(M*#%G>^}ZG^s^1v&>ni -zoy)9t=vdG&3%Q?x$_$vn5)LOzUEkb$WhM{IGNUOn%bYoO -zcq%4h1`BdO*D!-nYb%4InV4v7hmKNhmKih?6U{m;CR*r-ye2$4BDcIZ&AcYOrTPzl -z&L!@?f(CLTeJT(WH4m%|0>f4YBgc+Uz5gi|2UZ3}Gb;ltgJRJ_LBlNMeg-NtU4YR57Pn232EZEI{q>sN~fSf!qK#r!!0Qt^W9k|$c7NtYD{P+Jb>Q??h7PS4f -zGz{9IN$uu9Vi73Sq&5i~X5EPnSktl3BSfEh4@fBMVAFG-bs -z1}J|Ntxo_m17^Ssm_h8D`QZFhv&8wQ1-n^5+Kw9Uf2y9#Vc0~el|eG_v0)ay -z{|r>Si5Bc8fxN50%Al>vmiJiTni(_+#YD_tLGI_8hS}fL4DNi@fhINoTAI}KXH9C! -zio_!Q`6*$xuRvl^_RkCwrOY5n$PAc46DgR+3`(sXhAo;oq+hw3L;6WGx4gGh|5PRU -z8*>3OU$BiTUm4u}ssr(L$r@dv -zOLWOC?->lbOhkke~$-E>Vop6!R{-NSfoEoEXtoH7D+;hg~Vb( -z?&lh25Na*4NSaA3YAGeLD4IzuW}SZetBoy5GrJtCBifl*pk-Y8`T%wT`tF1}8t -ziLXPj_r=%DAQ9LF%zzm%12cn2p+2}Kr&(fVkSk;}gX&uBa!jU~8H8G!86?fj3~F&; -zWl%ITGia$66J=8*CJMC{6D_Pg5@x#!m;p0r5QZNxgC-#}UwatsI~YyX(qm|rbuE@G!tL9REw{(DUw)(T8po{ -zWonou4yOWUzziCM;RnoM~a!GlP_HF_D;PL5$}b -zGlOoK8fLBd16G*-twvgv&>R0x2LnP44A=!+|M;{hu;!z4UoeLYEsK>w(abeDvrbzX^s>M;IoT2InHjw0RR@~X{FB(&(#p3+{`TRG-?7Uv{n;+Z -zLa8n98|?b@y~LtcQ_P@fCb6iclwFQVGrJs5RQcv-iAB*&V$o9VV&B{BI-#6dW~jAY -zjy>dQn4LoI?$6AC88isP512s{j~Ot7-Arqk-E9D;&}9b9ptL>bA_ddzCJMDSKu($&AfK-TuK#IeP&6|@ -zPAwM`70tXEwmKpMxO)IA)oV<5(Fa&8!Sss=e}~76)#5FR8XNh>plCvpOOxgN2rOg#5e-BM+$)3a_I@CkBEU`$Y^;&2J -zikmg!>xDLWwHaK1{EZqLTapAewiHUuGH+4q{7V~KHf`X!n_&h;Gb;ltgJRJ_LBp&= -zg8{3|fEnyYDKlsiS{Z~Nm}NE(8)lQ%CrX(CGiVS-*TM{%gv@{$>}FcStQCL2Dl=dP -zrS)0B44Q<@fEgr_s-R&uX?>!U888E8-~!EyG1-lO+T~b8vCDD6Zf-&A{l2uDsCq72 -z-V>$HKP4fV0W)YK1=DPKFSUO2miPMM*Mi->|IC9QHzs=Hs}AgPY}IgmSNXGDj&v!B -zR0ZPeSC_o~!N!)NnHyVLs-1tj&90LcwqX`>KLhp0ZBo+%UJIDPDIjlrW(G~dPjGt0 -z)q8$0%UrOV6Is21;@wXr7Rdv*yhl^yFl_Vi*M!-=0<+9o9*eINrOY5n$PAc46DgR+ -z3_`7~42ouMd2gxq%8#I#n-NmW#YAGF1u>p$%nYg{vdgih+AZ%vGrJtKDH0Qji5A3o -zt`QSuQzRyuJ0dfK;MjqIVxmxMF;US>Ow>{>CJLH~iBhfK8WX+oRR?C7`6tn&w({j# -zXkUTEBK_I9%tEQeB1!06X8AKSD4IzuYAI!xW714wQA;U_MbS)R(NZn3$fn5or%>y+ -zCKlCdeJT)N2TGX%Gw6|h_yIF0nu)JdvzbBB%*_ZHX4>U=()?_EZkUDK&p>4c%%DNI -z1Ekb$86*!3kfSLwGnhGccq%4h1`BdO*D!-nYb%4I -znV4v7hmKPH`169G=g$lU%zzm%12IvlwXLPe5?f1a{raPBEq&{&4(JkHO4-Q*x -z!Ghe+HOwH?+RC74CMFu&p`%pWdE^HDV< -z7U|C=EOQT&kETa6V7yDj%%3wn-(5wlsE$>A$Ti#2pZFx_c+45epZDmk2`|y=+c`u7OE!f@r -z&uaaH#zb#_)d5|iOT88=Y5F>k;?SjOX_UY}FYqd&B7wvr%=t-TaY3pZ|CCsiY)dTW -z9{8|z=3KjPz-(UuGhhY@!YUA7CkdGWGw7}=n8pl3t;N?#Gci#$QR3^OnfN-j{0EJ% -zyAe8}pIwfj)(*o~N91DP=!jhG8yq_>OB!aa_ybm%K^p@z2%s{9CSk+uwEwvKvz5Vu -z-BivKFt7jI%piFnCW@v=Oq4Ve6O}zMgQA(3sHOVDAG@pRpBeslm;p0bko&pDE$^{b -zUI4b3AKJxVo`n8S%LUE -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 -z7yCBNTJ~m!{ts -zWbe`Wr!r^fpMn7ge%SIJJ5S6qqX&L4%ba!kDAhmh5c>RiX21*)Og!gzTR#B?sAOXUG8#h -znmPZJ{_Oly`m^&-CFjmREwsTc=nci~ANlR+PumZN|8D)!Z`sxCD{z-%(ae_jf~)gS -zO+vdIL#-tiMKfF8TdHk&51NUIvR|^XrE{c)S>kXiU#r`uA0mzcCjugF-1Y -zUWtwF!i1A!wmRU42%N#`d`H@*>@=$zTYAwFr?u9-+GRrKr7GD?5#MjXg -ziLbjO5)-{h^416Obq6IOYYs5rFGcnPrD&PDp -zCQ2TPiAt@-L?_M9?ayMOQfo0$(M(Jf9g&!*J0daBhC;u7FD5FQiHTaO#YCSN^-8Vt -z4`QNdio`@>q6IOYYs5rFGcnPHFkk;uOq4wQI%1-Cd)0x&BFyAE!nbI85GUL -zM5*Fd237_OVm#Ma8Ep4LFOM2#t@s00nE^9s5Wb@E_6KIrBy5;P?>__8${@VP%3!jA -zX8<#UCZUL5oXX#YnX-H&p>4c%%DLSe!vWxgv{WR?!Owq=?7*|H2XRR$nW>6 -z1GCI9=SN%K=Tz|U)GV`v!;LNJ&u(lvwc=Z!-Plqzb7M=XwfEB9q}JJ&HnxOXODu|J -zHny}>JO30kv$5q?7j*We#NyjXEE4Hcft5k=z{((b;AVu#ajXoIW>yBHPCp(lvH7V= -z@;BxJX21-(=LtVx2FzeV?&lgYQA#y4sHEt(8DqPjS{bBUFoQs;l|l2688Cy=`Yd1u -zq1I*wMKd#lY?;gqie_KOF2^vGnF?Z};(?Vx^1#X{%N5NUO?K88rOIAVy%IkNS_MC -z*9&&D2jl(UN-Vl5GRq9LmRK~?%rYk@c={_dUAlPOG -zMKimJ62M}jCSk*@oAUvy%zzm*2qz~nGgxAv0dn{OGboyw8DyAgW>7RUGnm?;qn0ns -z4Bqoq2NH|=lW0;Gly8Cg;lSfBh_BP1oy!b=7GKXCJ3O_^G5nbs6wSofE!A#$51NUu -z$9Cu_)sH_f2zvg^P{0fVrObdCbZi!Wzzm9J%wQ1d=SR$-XePdn<*}O)nr7nb=!o2m -z&@{8-fEhFinE^A{&9sIYGguJxSY?mDU~6f>m>Dz)nZbTDc+XcIh_B=C -z@gTkq**l#4Twwkle_l9>v*+h+Y)KMGEEZbWy&wz>ODwv7)uaYcHK|22yBzIuEEX*k -zG|WQoXP`0zX0RKj%%Djqu?Rmf%WNJt%tG#GpfUqy&>)Pig&8ynnE^A{&9sJD$o&jd -zX21+e>$89vGzpmjGe{y;LBlNMeg-NtU -zFeAH(LaiN!jfIB`G*_hhr-iCi{Gq_h0Lu^DjF5i744A=!+|M;G(42Jo*teG%yz8qD -zT;COc4~a#|p2Q-p)Ae0VGfiq(r^G^Hu_DHEjl?2prb#WeHp}d$$oZ$}i)?HunmPY8 -zhY5#p*(*PSW^Q?pj>s+VO*1i(m}sHri5eSQY6)v&OEyJjnbj1TWfslMGFz&DUnTh) -za{)6blrjTmP+Fe_%%Et-3`*(E43cJM2DL&qGboyQUmBG8d>cGYpy412WdH?Z0 -zA5~?+9HWLVeFM6bM5=;@S>kXi(4-d4m_b2Qle*v*4YQE@8K}&F8H_@|@{}1g3B}jp -z2NH|sVZ$useg-NtUY8NPt7zJ`-WOu85GT& -ze@e9$6BW(uCd#JB0J)o@hFQq{3{+;o3>t*t2j9OLyz{FLG^wRpbcrsN>}0|BuS?TL&GftA667|%8Ca_pw4Vb+R2 -zV3ip#g9c&v0W)Y4Hq5dqnF_27!fUJyCL4GLFf$lAc6@4Pzzi1Tey(YlOX-MC}jrBpg|aZzzmv%5{vKy -zW>7S97&ey24#Nh=jvZOUEaZL$Dl=dPOE{dc$_$!>4YO|l2dr8dEZEI{q>sPgFl_R` -z%pjT~hhb-q9iBQ2J2}De4)&j_WU!KzM^6iK8%Q62!TG1=LH8W3$Ae&788nB)M4{GJ -z22H|-*^(r0!PUy3oyf{yaspf4ml((ln8AYF&oxU(+tm65Dl=dPfxsD`%pf^-EMNxA -zU^mlt2>l95!wla0RR=Ei&A*C^ebb-4q_kwkOG;Dx#MhNCn`IWw%ra{!WtN#VGs~=| -zD4NvP`i1|60`k5Bv&`nfLh6uuJQSE^Hc=!Nq1I-Z&C-Th>+yh9X3$n;mN_|rS>_T0 -znE^9cko&o232Bqu&sb#!%pedrm;p0bko&ntOf+)r -z_>>tigPBDOPa9^F)+b7t0W)9*b`$mB&TgV2irqvDcC&!A9W@5X)pOZenkcokG#SVY -zm_ZXMm}YBfsr9_I^u1qo;9}qUd)U}gvga}FcS>@6Pfie6^G3~uTBU0*VTCLuFm26vI_R&m4Zld>;h -z^0I~*Fau^_fZS6%ccv9l43N`++?iIhGv}X*X3jsAT08%gG_$qzYAJB>jg>*s%=xF5 -z>JNY1y}FqHM;wNY*8Mv-gZF>cfhINGQlM2L0@EWCjazKi4$Ow&1t)Ju|qW{uh2ACYmA23^okl -z^m}H&448pkjjGlIca8qeAbgpRSgHUTR(F>in -zKUf)rTALXZ%?yyQwfW*31LUHamjMnU{ru=J55H{dc>dQb1*^xK*F`h&^_4bXd?UV2nu)JB -z6#Di1sY(4*^;-Uh56plW#6pZ2l-6efGf0{-gHm*6&^$ED47E1PESfnCTOE;E=0eNV -zFnde8{)%2^zzj<3vw#^i3C%LY4{U5{9yZKADfV$t1$#3Hb&N!?)A$@dMj%f52~nV)JjsqGWY;1rNIJ~M+8Ms0j%2F&0@*5CHI -zVYUUorSF*mGk7C1KjE1fG})K|GuX|vhS`$nZ^4xrFoP3Wf7@qf&?ICA%;0V8I{B{} -zW}8C408wVZ3{JrI#?Q>4NyrSC!EUBC%$7ud3$9iMRt9hNfY<+!88iu*0W)|d%v(P+ -z%r=F70iw)+8N3ylpZ-H;&?ICA%wRXu8fHtPzXew-11p0QS%2H-@7WAK%c~CD8s(-4I{EfMQ88CzWLDY<~-A}Cy7VIX0ysN;?2+fkuF4fGSc;IG) -zXx+c(S>}GDdHw|(Tf!=sLDB4q8KhLZGc9OlW{`?*Wl%ITGl-7p$pATNCMIgB{`-HZ -zBq@JmE@&Vp(x(C|gXV#i!3NUCMAGANo^8Dz_1Wl%Kx8?FpK%c~AFsbS6! -zHny}sn`MS@*w~UZv$3W8+4-lU*$1=CQfrAt(aigwaw%n&Su``tjE?Ao#3E@Xv5;6S -z^gL1H{8Op5!?4*D+45d$ZI)Ry6BD&m|GrA{H|7FnP$*>v%%HSB3z$LCj2V>Dn;9g{ -z%nWLUY-Uh2Gc#zZ{_w}nJNsvb{~ZJ5?Axsj$`5`W0QMe_tPB?HrhvS!z%Iukftf*~ -z)Go&)p_r%)gBdV`1u>p$#6(3iD}!pN#6&a44o|HNLajGrqR;cH15IlDJ>2qMviIR{ -zc@$^2@qhdUx)eOv)TQ|EvNwG#u(74UtVz|Rc49CKwk9=c#tcf-nL+c=U5=sFW|>7Z -z=bx%0a{ehhBIlo?BXa(!X(lH6v`*cSZL`d5ip(-gt<5qw*!AgqF;O)|Vxpp%S!Ojw -zVxpv(nCL{6Z+;dN70qmUZ>hHB{WiN!DCc6|P;1xZR2nNL%Jr))??p2)(Wxrm{46HQ -zrbtXwYAq%@X?|{h788|Pi;0S6Vxnq_#6(FmG0}!XzkV+!Dw_T6VxrIUsskHa%A6$@ -zY0eUhTuMnS+MhcZTY=(cjrh9kpBW@d#n;;edwJ9_`_yqRVDhp?le%Cx3FLhR5{nnG -zZ+>unS2RTuizcDNu$St8VHnJyX!f^DEcRK<>3_bhvMIwW1y%+{Gb@7xvz0-!v|)Cs -z?+eKMRKpCIL4z -z-<9o{l|i*kRt7Jf&*lf$ca>V(*itmJv89?K8(WfQW(M0L{rt!*vuI{xOG~wlEt|d2 -z3j@VOq1Iv|G0}n;&oyGAqM4ZJRg$+ph>4PiVxm%OG0{usv-v?xRBA0IDw>Ijq9YO$ -zbw?y7+7@XsQ4#E=z+u=>YcWyL%=xEO>y4P`bG_<7lbU}LO{ymK)db)8!7MXrrb#XL -zG|O!IX;MS2HK|22P3l{l)co((3mnqljFlx8Z3EA38Z%%93vxf#*w_-Xy^&a~YkgKS -zgBhY$1`C$J4445ku(74WOdDI0B{sHH%VK6wG_$d#Rmd -zD4LlWR7WHx%8tl2IkQfC|IM-mEyH37u -zn630Bn>AJj3wD!0-c=wbI>r0#&j!fR6y4rh`q^G}ph=Cthg;qkMA0m>x=6Fk^k=io -zlWy_mXS2+rnOSD3wI=l@wa&iOq=s7GZc^hvN&`48UcoOL4z>-fEhIFm;p1`&9sKued>RKTW0W;n!#s#)qz=N#dez11=ZRoI~OW+{ZG2| -zmFiNG=bnPls%_{I#F -z!EUC#sP+Qh-crL1m_ccM7FZcH_m}}QNFr51!|W{{@QPk$zzmpyE$_CxrxIs@E$^?k -zvh~51_e%F|c~3ubGeW4fE$>M)Ti$EkU}aD=v*o>|+LrgtUg(8^VxmxM1LTFZ$19vZ -z%Lit_3>t*t2h5G+3# -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 -zCMS5bnhl_pF -zy$89v6wR1HDZPy?Ni*?vt&q(!i)J>q -zv{c*Jl1-8LI@DTx{dL9HiRiZ!h>2?HU}cazu;o2N95GSaO~PznftYAv?NLD9SKu&g -zk-z{sQEGskBs4Q9t6&DqU_p%M8Y_dMnUz5`RAvS<#|}@e3_`8V42ouE1})WQ20=52 -zVY6j2GcYq)5aYS#`-+J^|Emt@5?yN9$qu0HFa2>U(4>a!X;KrS4(VrX#|)Uk0+Fg_ -zl=1}-Mh!Dy2D?!zu_&4`17@(BW?%M@ei+9BXdZawN3<;8)ym*Yyz0QY%#t;_M3+i-vf#VYrOCyUPTK_%i>X8P -zUb-a`elBo+#4R&m21_`cEP)xk&}sVvGhhb0nbt5H5ZI5H0W%nde&s1MXr?g(X0XDg -zv8G|xia%hL888E8V3ui?Im__MQy2RVM)Um0Vc21se|+RHZ2FPIu%Xs2_Dz}@AlJIV -z%AjcGFl}I2AAhX3!uEKVSwU$Bs{#0W;Xmw1(NF^@&nu -zzzj<3vw#^i37NsV8GMOX9f+^v@9`kMUQoUT=C=uN|A?2ArawEES^jL6xlOQ-kIXX7 -zG8g22u3-kD)@GSWGqcPWN#6P(u_&6EWzIVNZ>^fnc#3Iz%EVEmtC8V9A?!M2= -zfEhFh!wC<l$ -z|3bC)0rUFLtqhU}Rt7Uftqc}O_-n#!Ux8WX!rG&Nysv;6G!MGx*u?`Y11p0DVKhZn -z22H|-S?lqDRWVUpm6btQ1v6+8iiw!Pg51wF4YNt>6Q#_683Y1nd>)=MgC-#}U{n8AYF&o#`TNyrSC!OWtCrwy}7>l3BS;43nNFY>AbM{zRW7GHONuupdA -zQp--xQpML{pqkWXsU|i2fEg6co|r+&xs5GFGlyZbDRN^=(aeo4(Gfk_<(M>c7&ba0 -zF9U3v+45fNSBGJfX12VST8poXW)8!qT8oK_W@ZMteiajSQ`9i)=6t{^GhhY{!teuT -z&?Gc72tQy3MKd#l3^UCPie_d8Q#*7Nax;T$irn&EYVBr(Y>Hf*$DVdH+PGS6*Fy5MPV0n@GVlx4eg1i?5SrVxlW; -zzW7FbT{IJ4r$i)Lb?YKp`}Ni#9gl{Q~|BPJ@EiHTaOznfi-m-M(`%Z`8AO%!TvH&G4F -z#6-D%wVSADCMHT17ZYVu^rd2=FZ8MdiA9*RyByn`B^Kq+5{smn#G?FJVo@}cSfpA@ -zEQ)3}w&YSuV$n@e!z`C$Qvowz1`WdS17L%+=Lkd#jJE3>NHWL2d)-<1g6dm@IJ^Hku+cgPCK8r@to5 -z_7&Ljo(+{P@1qkKAg?fx88Cwdxu0v8L8!HrLD9?rIn~STwUTNVT@hF`FVQgHmf7 -zTe2y#v8B}7F2|yojV;v_+2xot6BAWaBql1F+1S!j?Jmb`io`^r)?y+t(SjJyHDaQo -znV6`h+F{tBnV2Y>A~Dgz+M{5$uYegag9Kp}FoPtanL)Mg%%EsyW)RC`w<&keWoA$f -zm6<`(%*>!x$YusbvoAF>_)@Pra1+i`a~%+U-1;w -zb@;RRdW&73zW2(H@MmUFG!tL9RJ+SDXePeShDu@~u~-n}xyJQfC(X~s=Z0A;{(x0x -zzziCMTj2coJu_$$Hq5dqnF_27!fUJyCL4GLFf$lA_8gGUEzRDiVxsVx!#lATHg$TPS4)NkV483|=(-%^#RSsI`?r(#*=B -z)~{lsqL~45O1PM)Xl8(19g&$q(#)3k=!k52Z<^Wip6gdJQ8qCbL# -zDSvkUsc7c>Q>nEr?@2R>MKwj@>!O+SPc7BXKV?&7mKka-vG^(yiv;qn0xJV6gNAuH -zj++tY35%6Md5v4%Tg9ymie^>@spVD%%`_{6Xo{>1sw4U$v&^=P1+Z_{SQ%8;VrGy$ -zurjbRC^yLhyBs$~`dQ$u42ot}1})WQ20=5s99ya%f8H(k^Zy7l2$V7dX3)#i@B?O0 -zG-C#{P9G9|W)L(J6UFlQJ9*{D7kt$LU7|}ZJ9Md)XO^blp8mA^H{yRGfxNFke4RuQ -zU(XP=v1K9ckXT48c3TBA2(^}26wRy*QmrKxMKg&-YPpp`H$@Gzkoy^^%zzm*2*VGU -zL6fjy7QO!rRI|(lyV;NQ@fXBI$pbM_G(~Pkm^pTMDkfqE3vxf#FoRHQD}$n$m}qQ= -zj#6!7OVCVAH0$*Dvauzpvag_FmN=XWm;p0b=*;IDW-xN>__Sdbz5fhUG0}qE%qZUd -zR7{jS5EDgHBqnMeiiw!Pg51wF%plbIdsrF#5C7_4{@w3>_q*Ty-GBUd|Nh_ni+{VI -zEqj^(x>FxrmRZ4|jV-C=&Oa5+m_Z6TGgw%AgqknlaH?Sj%pgHn17RUGia&)eU;>I%mvJ#P|6IL -zL1}#!FoU8QGbp7uKu($&AXi-K{8Q1)`=45>z5gkjA_L@5>tFxpvqJ~}_fP$Q)BHdB -zR3NdaE>@G;%9jSaufQxb{aIpBD3w?w37G*i*f%PDl2|NAwfH*Q;Qcrpe}Ne=g9Kp} -zSQ(5QV+I|niLc8ET -zR7YfH5FOEzm?&vxX3$do_ilL)rWqiITHEEAG_%XG)Y>k`qM2QexqcNB70tZ=DMNiR -zQFTOOqUeY|xEUd7CML@DtC%R8B3nyKt-tx*ME~r+|8M{K;Y|ns{Qvq7|MGwRFaHmT -zMg7Gk7UjFCK;Vqe -z!&7F^BxDB6U^mkmX07-GR+#}aSdjakzxbd28%?SvHANu{G^vB;JwI~Gd+h*o{wdwtjV+}8e -z$PAbPGcYqSGblI70yBfTUokT%ukkX#UNne_ie_d8E!AcQ$uuj2Xo}1Xx@BsZB@U+o -zX21*@gy9FwVC2~GDKlUOyP4K7o3uVr$_$u6X?+%a>t=BAssl}G{>8nDC}KOWA`0(6 -z=6bu8X9nuGu1gN-H_aT<4-$A|^+JbimRWNa=bvV;IouYxg0vkq-bLE0rPgAiqM4W|)!NLUXeK7ArbtYbG!qlm`c+I+G!qlGR6GBaO_43{q1Mhn -z)!e}Hs}3}&n$$sX79Y_iy0lN14)>`%{=EA) -z=Kojxx(MgDmWi*E2X;Bm5Pc9|H~s8#jIKp|oit+x)v}1Mi)P~M?3Anwie`2>R!3xI -zkTertM@M9rW7Eto$6UYK<(N&8U5=&JVxnw{#6;B;+2vR?6BAWaBqmCliHWKy5)&28 -z#6&ICb~$EKWS3*8wE=R^&KhQk!>NE7FoOnR_yIE*Id*)?44A=grZvnatxuFP17=WK -zp9RdINyrSCK@zD78fLBdTUfn()q!1(3%Y2RV+`_r -z%`{DFsI~aIo1%um*`T;P8QImL6?q?T;EmpFTO6d7GEdL#Mf6n!O+Xx~1CnU6;JNpqco(IwJ9P(oB4vxtf=hc2m?#+!ZKp)-VHR&>##ya2R%*U@wmv -zX4hTF9p6|PEZEI{q>sNKCVBz;<_EhRqbU*-%^W*C^=8;G24+w+6BD&mi;03}VxqAf -zI!d+IgeTJ)W{Jb8fEh4@24SF-8H^k|K6Nuf_yIF0nwc5I^4OO5;MlPvYnX-H&p>4c -z%wP$J6IPi)ldxenHU5cGD}x2Q*^l(`7t9Qj2cL0faQ&(Sx|DwpO{yk!wDz^9ZGS6J -z+^o^0c5@)H2&`&Sw+Z(0sA1Nf=zvvC>Vn;@DQPaZg= -zUnq4*e=wToM-Ibo+raZ9W>7R^2Gz3I<(M?H%dyrCRt7~gyBu4p?Q+bfNK6!JEhgGt -z7{5Gfm?aLU0%pJr8icQCy#0Y0j2t^YWd_V(H`5wslh!9nnE^A{kofiQnL(3~88Cx& -zMr~9!%v$jWtTF>;zzhtK4Uo44c>Q|=i(X+5Z<7)}T9TycxD=_TU1| -z;(?VxGSJGPdKxQ(qM4O}l|iwn3&cdB*5C4$_vdcL*3#y|XY1QfEg6c -zn8B>m%%C`SENGa8+|NL@G6*NIG6*Ml`YSV-Id**N&b06YD}!d*KCMrbGK0UJ8Qgl+ -zf$O{a@8Mi#`ml_%$E0DzlyKBDQcK? -zb3R~|88CweVfX70tv%E!7Xd -zWZ$%}fEnC2gWIn<(4;QtqW988pQ=e+P`(wUy}d?aaa;CIP20u3;jI#jW*{?Q1`BdO -z*D!-KVLlb<=g$(0qM3~?*(^ycie?gvS*N`WaG@izu_Zd9CmUOmW;V9m=z`Am+s2k` -zivGjy&U^-{_&WW-F2_QtU5?38yByD@|N5WIplHSnYK3fOaLudBZ_Errt<4OIW_CHY -zRNLhkG;=dTbwp+cNi#EpT)&zbT(v+~-*n!&0>#Z5X21*@gx9b<`^Eryn_w@G8fMv) -zOa)d33wE;~>EkbmiC)0I`N7N}nj$gL%(25$G0|-&xc#aF7yE9@(d#3+M3)wnXRe`3 -zw{_`tiKR&`nu)JpC3)+E#G+^>zMggZ&_X``yj$+){}E>JN%wCemKiXEh0c7gVFpDr -zW-#kCGgu;F!|b-oFW~b~!wi_g5)LOnUhhf7HtPDnu9iKMLR(1a-VwnLmXb?_L -z@bp(^aFbf+Uorz`u$yW7wEi5BH~z^Cm_ccM7FZeFqSpDB%zzmrk*c6!c7eM4{>coO -z0W)wjLTpz0;F_FfiJKA5`=1;CbTdND&TM&4rrBB=YHiDV(#&q6Tk?GRrIkU^>@#gG -z-FVf3Cbj<_uJ20s)TEw@+|AFLR849VDVU~7)ub-8p>vHb@3$5DRkk&$MYGS;q@Lhb -zVv%ma4445kFv~2pc70c~q#ExO2je@c|v^4=_Mn0;#V7chBQV`Wf1mz6=H -zlo?#{>gpT29K#Qo0W(+-z7Auf7gb1$2XePkUdT6D-<_Be51N_(nyN0lLzAK7fIgwAih3f -z)a}pW>*^xK*F`h&b+s%G=_k#^*Bc7``n{Dw(M){ZQZ2sz#Hd$loqw>)G1OXoy}9Ig -zWnjbX0(JNOlNm6BPhfjR-F+XJL9>n-FoWGpYna`q{uj7q2F&12>A$XL22Da{zznXL -zbLTe=vrBznK<1|!X21-XfdR4s^1Z@*U2lM#)?OjI;;{^@2%wE3z7x!cCvsj(WQkZajvnkWn88mpEk^Hcb^OR -zJk)4XHK`54@B?PhBs9xp2D_QoFk99An}}rw%%HSB3z$KZkQp$8BvKVL%x|8(T`PZEQ)J+1OI+1}lT2nT;*g5s8VC -zW;V7|M`VDUH1lTIT)(>5x0|Ac-g^Oxn>A(z)pId}M5*0G+XQ=g)G%A=OEzn)3>NGr -zfxNH41)48l-~8bGQ#3_lq9)<53A23#-{j0-^Hm4p>uouDeMFb&(t`5LHFRmSJ$+tf -zX;O=3;_FvQ-ufW1D4IzuW}SWzUvIMOgmn$Gkoy^^%zzmz;qVlbm!FwIlhBs;@B{Jn -z6|b(oX_$rF&p>4c%%DMd4a>7{m_d_}88Cz0Olz2h+|NK|2F&1G+28O_X3!*L2F&0M -z)H?r98fGE)Gfmzgwk{^?wpum7n@Et)z1 -z)KdN7kGB*&|GV`9X21*<Y)NE!@G;z`(s;Rg=GjvPBaZJ6D}-s+dkfEhFhCntDv%liu1m;p1` -z&9o(?t)TIC4KrW{rS(~0Ww61nlkb@UGe{y;LBs46a(91b2F!pNI1C%}X@_AKSYm7G -zN%M32v#q5yJF~SknfCs>iH27lh_CbS;k|U}p59AWYrzNar7QRR%fl~KlD{z*NG!si -z%`$tj7#N!o*iR)E3wE<0w}JHW7c{BKgZFPz&$XW!Bo7{UVSHx5;VCm<1_{C{urg?- -zHOyL%2dtW9cH3oT5PrZ6nuHCrizes3e_9z>88iqdC$P(LiE_+<8SG}-64LH7fK&7` -z17=WKp9NM1%|K?r43bDy&@ej__XSv<)i48Qzzoa`GL1DeXsQ0gpZ9ZV{DpJvzE|tB -zo*6U`43KAtS{WqGT$7WNEi;3nnXRSSvKS!O0^HWpRBOA5vMGA^-9*!?4m7Fx_i&eE -zx~KShLHSmY_VyaLyf3uD3FLhR5{u-4bD7me+VY+xwBRBT8pp6*9&4i*NCr+X5#CXYBwVU&E7x0zQ8RrU?KmRnn>fk|Q5wdr -zc?nvH#WulS9x;PU^=AfGM5=EZX0LdA%Lit_4DQC{C1{yJbB`HZsy{QhB2sc?nu(&?ICAm+H?9u836MG|WCJ`vN8}YnTBuxEqs~pk)SEyt?{^8CYIky9nyadT4ulu?#ARLXqiEi -zkQrR6KQp)@Qhn1fyCLxl;QUy_48FJ-jITQIUb_B!*z(@0;k|S(3b*yaE$^z(aeo4E!A#p37WaF<*Eg`{Kg^ug|$b*Y*zs@ -zU$43>t*Y;DR>y|C1S9sy{O*UR@P*&+!Ii -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 -zWkz;wWl$urNI>6jAU0SxgiQ4>3_V -zfj3q!(UKW3g9W*tYnVZ(wV0@ACML=zN=#HV6BErkZDY$yQzRxTwH6a)%jBAzQft@b -z6wT}=s-{Rxlr(cQLN!HZ21PUPe`=}r{-i2Hzb;8E+J1v+UPTlXkys?nBo?)ll2{bYBo?XV5{sgl>$|EW -zl2|0oY;1{+$Sv89Rmt*tL -zE$^Y$b~zT!9EPoq$jo4&Wonp3XFda!88Cy=`Yd1uO+s7V!w+nEZyq+xLhfgvG6QDN -zAPhfX22Da{zzlXXtzi~&KLeE+FoV+iEMNvrLT11Wl1Nq1Fblb#fyxY+0W+|*bY(;x -zYCcZ|?t9e%U7|~Li7tJ9U7A(v!7Ouyhx>ZaxkG(q2Fzdugi#~0XqHMW!VkHAQBbMKia& -zw^Y03J)0siQK+?;NKCXK#&eCBsAwi8YN>Y1d(ccwluePCXkqP9Fxywa446TJunL$# -zlF-bcT6bnpG&3`Z8w61^nMvjV;BoLjf}gwYIS(X=YkXiUftf)xMFz+-#|}@;48jkXLD9_2 -zprzW(AZTW0Ft$TSseb%JOLU1YdF4l& -zv+KK(D7L((Kil#?ETWE&#MkLZ;_K*I#MenPiA61?Bo;+8@pVhJ_&S>+yBtHU#n%gK -zkA&H-0%pJr8ie5o%%Dlg44A=grZvo%!GfU2Dtr6|yBq_?%%Dlg4445kFf%YSC^yLh -zGlRKbF*7KyvE{uN4Pv6AnVCULwV6RO&B`E}A~S<-nHpw^!>NE7FoOnR_yIE*Id*)? -z44A=grZvnqwf^o`9X#0O*ncpIg~XzSEeo8>+*GY+W7VV<%_J7-t(w%L*$;j$Gj;k9 -zE<2>3Olz2h+|NK|2F##A7${{1O+tx9SOPOBnz`6Fmd7sk4UQd~vW8j6{R~uQzzmjf -zIAN6;GzlAK(fiLpwK7<+oBc>1f5FWN$pbTkXo}p7Fmvqi)XabxEXe&_!wf>Ltqh80 -zW(H$Bbd+i{gP@t1Xx3>l(LzV`ASNoc{>#HJRg%9k7nm7@A20)Eu)lAAax+3%Lc=VZ -zlBvMTAe_L;AR)>On8EjL2KT?}z%B0!ka%3smh#7`K$ALp|M6+t-@HV -zkH27-WAeZ*$7qV|a-2DKcxsm;Ggy%OxrP~pT3ZrJHX=Z@jQvHWN=Mr~cK?6CFJ{5?Gng><}fnh6ykz>cFw!FvUz{;R#W@TVy -zP%K&~XqbiE&p>4c%wRW4nL(4VVKz1XiBczB-xk&Gw3ul -znD+Kvj)~7>0W)9*yHUyvl5EU?8I;y%0W%1-{)%@Kz2#L0HnyZWf3UHoWW_GWitSwA -zRpxACOVZ57mQ-uAOtZ`dF`jEA7TFY;WtLh?ERu&3i&AT|%%YjZqMD+wII$@Be=M-& -zy%ykB2HCP$8NASG`$NO5^?1Olm?#z=Vxj?@%wV9_`J;weH|GOZ9fn=7n{AbCj4%AR -zRtD#gzwuAA%xH?N44P?fMwp!7(EvF(cC-p+a6_I?_1nszXl8(%O_7+WXeK5~wH6a~ -zQ`9g!6ZZvJp4Bh|X3!uEKVSyuq`LLbhFSFfGf>4u3wE;~>EkbmiEaV^>`O6GG(}>f -znPZ2iKWeAeszCP8Y7R{W0x+%}6UrH=`rRbLT -zlIq8wt7O*te98HbZ`G6QC?(3#IQ%%Esymf2Fx41#86nXx?nV3wIQbIbefM(9Ms -z9fr-O$YI#IBYJWe_LNb#KRXOtYHgNTG&3`(rpPQaX(lGxQ0Uk1#Y9CjGlQ1u4}a_> -zZvV{izhi(LtvfSd2Bq~`zzm9J%wQ1d=SR$-d1!zfYHeoF{ZhlM6@S1gGhhY{!teuT -z&?ICA%wRXu8fKH$CrX*YXETF0z3Sl6EHeU;5C3SEnX=+y-v#AcK-!KPhxE(-ZEQ)D -z+Srl|w6UdnOlH6g7Q}e2v9YCSW|mnEm09M@vBOj6pF*uA7DY3&%$8~!TY_fJKV{2g -zmbnl_CCqjeFau`LAPhfX22Db<%7Ty -zac7weBK=%rW{^#hnL(+wnL+Z+miJO?Ti%OiW(L(1nHeO_%nWM%DkdtLnHjWH+wz`G -zk(emdT1+G+S`g#8Mod&R6BD&mKm3w?)4qZq)C}JEssl~xf-e5H!2EFF@fRc(>CawL -z8bFm;%p5yBb+K=FtHh#cCb4L#mRJPM>~b92p`%nk{=6XQ`7=WSGYFJ217^^%S@;1n -zD4H>YL8PA_F@vI+U5>Fl{vf_inu)KYBl2e0rkP!i(Gfk_<(M?H%Q4m3%pjX0GlOV~ -z%nXudVxm%OF;UUX%%G*(%pjYhA9Q2O!m{;ajhJX*?U69sRlp3GL4z>-fEhFinL!u> -zGboyw8N~9~%pf>+Y|R>GA@?&-nE^9c!r_EfX3!*TnB7sN~%X{*` -zmiK6i%nW9Z9iEyQgex$EqM4aNOSLWUK{GRhu^l=}wQF*cX$`Z);Z(p3m_dUuP|6HO -zjvb$x8H67&gQA(4K`f7Lc@K^qJFe#zD77+Ju$wm^ -z{jIM$aD7+*JzU=v=Ir{e1yS^p(vmf^%=Blo%vh|MWhTwcGE1#BsYNrh%$91i%v=tN -zuS2aR77J^SgxRhFX21*@gy9Fwph?IKn89wQHO!d7f}qDLd;EpB#Mc!Kofe3Rk|koI -z8KPpMGe(`V>(ggj-oq-a42ouAqLykgQP9km_f%^!Q7ypja*U41F2|;smjSj^Km4)~ -z_2kbC1!AHADl=dP3!V8~^V^e{sM@ZES-1ZKR;>&s8+djIW)LW422H|-+0c&kBQa5U -zjhJY%foA}Joo4XnR~^tLx->VSD^E44W&aY3^k<1h`txJMEZWc+sG8L702;`N^r=9T -z+KyvmOLQ$?XOp@RBfQoygX94-D7F5lKm55$@;By!Pk?Q9 -z#n)B_yP4K7+vN?+fEg^v{anKgnuN@N8O$tNc-k;y1`C4T%i!%F5fcSanL(3~88Cwd -zxu0tqX3St)#|MdDf5Z%Ch%y6aFb{`Uo*Ez*&76Nq&9+(QmqY;v!OCTF10p5 -z&Zfw1%B9w>$tjw-Ca0RBuktqKx4-JZEHnS&Zft4QaAQmQv-mpvSz;lvSP( -ziBd69vs6qJ-oOl)!GajiHDaQonV4v5hmJxnCQ2UK*ivdOCd#JB#+FiRF;US>OcWiF -zn5a7t)6;QaVKGiVYv%+5Of1z4Wd -zSQ#wX&3>ehzhGla^1%70Xo{>1W{w@6{+ck`S0E-z_p!@ybOJMj6$UZ`X0Rala}6^H -zwYD-Sn%U);YAq%znmyX(SXwS75)&40hhb-q9iG}vRBA0I%BDz6 -zRBCNzP&5-0m0Ft_B+bM`)f9<|ie_(!iFUl|K$F^k4^3*irzUkl`4*72qef!U{@g%L -zq)!Fn>#~3Gb)r;!J#y^$v|-kIJYZFm+E!(k>g6-fEhFinE^A{&9sKur1gnX -zX21+e>$89vGzpmjGe{y;LBp&Sf50j;UW!6?o#iDs=3U6PtS -z_}-G#YhpZqsh3$a)5|QkUb0lS=-j+1X5{FX& -zGhhY{!teuTFmmj?s!SAqzzm9J23xY2s%KC%bIbdb4&6(&!Iom0!In~MJ%db&^bAU^ -z^$dz;dIl}k|5PFQ8*>0ND3me-W>8w60nDIi#tcg7HIS2L8pyRn)-x!YX&|>$e`O8i -z&8H5Ouk$aid>#8J=Q7)zm9KLvrF@%zzmzWae{>n-NBiomU%XU8xzcs%NlZ -zH#3U2SCxs92Oa~Ar06Rv6YV~AK$qxJib4iRQad?teODN`Bvq2SAjWfyibc`P`KM`{ -zb{2AjEy+WJEv425TQVs!@?L7KVo@|xv51W5YpYlk -z>H8&RqN15=a$2fglXI90Jupz2DAZb+=zYsXyH6e5NKzM+?}6TrJb&L0Di-O_Di$Ri -zDi+C76$=%M1-YMNm_ewuibc{)#iBAO6^o*oip8wc23v|_=KvLpP-_*7PMMaF*7^An -zVwnLmXb^@UC|@@NnE^A{W?IASQ0NyR$_$vnHbj}h0@IiQGuUR@p4KNy?F{S;D)G+% -zJA-B^GhhZuqzY)5wc-z0Wd_WE8JH&O9kOYnB8q9E!D#N6OcR+V+P9m8*U2h9M7^plE`)W{-@yeG|!yq8)lUl+}cyth<4 -zq@PKVUS_DZk@w!5G|Uo*Qvfqy1`WdS178>u@pc*>~jpP50Zweoe*%wgD; -zYKLKiX198o2MYc8y(!14#@^`}lv@Ao?&k{0-chFR`VrvPQ51-sct`uGca2FU|GgGh?>3}%jM^m -zj$sC&)^-L(v+t^WJ!U?KtI9-0Gi9P#r%gE?v+K!H!z|=}1}ZaP21_`6ipk5*%%Dlw -zFpJ!O2C6dAg5B&Ref$MwqU3=xQ6xpmL^H=utI9;oU_tKZ7-kS^ZD&w4QzjbIp|e!q -z{$iKLXMeL(gEEW=6Nox4B -z@^#V7U5;hWDi)Okt5{5xgnJ=ZvFN0z)O-PlQw%d;1`WdS1LfS43|ll)zMj&dd#S$pupsF9GeZC~U!WEc7(M->vrP}*XK{Hd1V>)z}YEzEMw1!#Ya0*}s%%DLSC}jpC -z$Mg)+2~K%CGYFdL8N~M3`%f!OYnUYtrvPTa43=;>VU-z-96PTz%%;RYQEF$fU^k0M -ze~+gQZXLx*`*##)a^`#0`14;Ev?YIL2-uSyy0ifEidogAMfrLWrk9x<(#s5#>Sey< -z)#W#Onc)YL)S{VQW=pkRX3$J8^F<1D`HhOjv?sVHVZ$tOI0Y~RX3!uEKVSwU$Ih!p -z-Y?bv!XB7G(M&Hhw#Ryzm!!Jj*!dqDW+C@8P?-TUSi<2|aQ^lsGiVYv%%;RYQEF$f -zU^n|nAAdp5AbFr?5J{1q!OXGKs-8jk0W&C?=^3lp;i^bE#y=q%Mn-jit!v&7*P -zzzmo{gD_Ca3`UOW8Ke_9|5O}12Q`>?zAj%AwK_RdMm_d_}88CxwrZvo#ME?k`b_R9^3vxflFoPx`GhhZYixyTJ -zW`{z*08wVZ3>H8bG0dPz$PAdlHq#nrOQL@SS33hcgVOp8U=cxm_M3+)_ -zGJr18rOH7wz?5U>2Mx2s1atwS%zzmzfG}d1L6h)%Nm5hvj{=xM(agoZsn*UvbyC(a -z3%Q?x$_$u6gYeJ>?*Cn8&?Ib_E$sk~;HrGRU^n|nAAiBczR3d@`$kgaV&9o#r&SmG -z9@@aYJuri!nQL-ds$J|GG;^`l2Pzif2h3pP*m;#1FoOlTpJN(klh!9nnE^8h1kU(8tuliqAv0hG+e~Yi -zwc-z0Wd_V(LGI@mX3!*L2Fze)(ZXuOY|{EfDKlUO%)m3@-8=J4coD@j;R|-NfV7Pm -z*W^^rbz|hcQ2O_q4;7NXF$dTg*cp_YWI$kSMqsbn8MIYtAO}j7iJEE5fEh4@y9K%Z -z1MCdm>8S%1iv=*KSd^@&SfoFHC%UvyH#mxMF0*LnTxO}Y^G`?Y`t<$xaxOC^`6xie -zqG;y)Q%kk;Plp71AfAfFCsn?hI641Rg+bSMWidl9vuLK5`6$UpAM`RaDN-gXwN@s2 -z$b1ezC=-=hD-#vXl!+=SQYK28DH9!w^!<`DQPE79sHIw&=r9+0V4yNlsI@YYGSPw< -z&oRnGMKfihM@c^VpiGoJR3<95RwjDLd=5V-6O~#k6BW&ri6SFXChCkxndn%gm5GXA -z4*||Ug<5|lWuo_b>OjRJ&DmhfqdFXYP_bx#E@4@~;S}?g=u(>Sae#`&g9#sgP_ZbM -zs8}2m>@f{K2H1NnF#~3hAglmpkW^#_%-})O-~2)Oy3|_vx@e|+T?v&b$E2C^b!oXN -z$D)}j$CheSj+rc(atyULob5EGzpmjGe{y;K*OvRf50j;U5{~mgoDJv=#y;D@N2!GbgEOU1LDb?D@d(q5|Et$efQZp%9 -zNm3V}co@SBm_dTD0+_)u!5)?xW}W^IShX`)u$u((R)CTBN3b7$@cvUIMS7V{LN~Td -zPH^|H%zzm@q#bYnU}sP?QzpuM$w+|znyumJOlG36Lpi=9EU)XrdXf>TBR_NNLNtYl@$lwq#$ni`nKDsqUX_WGW-Ftm@AuS!US`RjUS?Y7og`I~+U6)pt&&FuIR6v| -zDoIV6Nm5I#^)icQD@kg}{T!fT!3;v{6Q#^x=GbY~U`wR#%%FLwml{R~uQzziCM;Rnp1N!T!p+?3{r1!bb-fu2Dm -zMao1o$4;xtM9g48?&lb05Nd5_P&88}8q=Y(R67hCG*c#;b^6rab^a-t)-X#PP65n- -z88iq3rOaUD*m<>K7Po3 -z;&2T3`^|@Oeg3ysR$bo}Jg_rp9xNek1&!BZR4h6vQn84nNcsAJT~EGe2FzeV?&p|> -z*;B~9`ZF_N27$mCpQlx3(8OZ~%wU^o4YOApz*Fcl17@%w_j3$0Xc965W-zm8VYOlQ -zOxzb>`7DMRFau_wXD|HcgaCQI3|r=Tirg)ckw6*f-r%`FcV5R*?4g7&o>oq`?W~ -zy#N)9;w+O7ROEj -z%%IfT&R|TqPOEkXrPg)^MKe2tsvs#7CCyyyTS<|@mZF)SK}+?=zw{Qje`fgaC=*5Y -z&J37AX?+GTgQ6KT7)1Jhi5WBxHIPHC^$a>+YM8a+4_IXe%%DLSe!vWxgv@{$Y%{H4 -zHfepLlo>FC()tWw22Da{zzmW|6;LpH&!-Mt?7N_g%Gb)*C2SdBt)iQfAO3RIvy@U)z}YCVIXnKIF=)5=5(8IfypA|vwTN7KwTIW5(m{3xcmCZ_~jnMj!^ -zbDjuLCQ6zq6SY+TP$BsnbHE?o4Bqvr14(Mhp1T~=I`7=&7^37Z$I4Khe_EiKUS_Ga -zB(<5Qml7RU*b+S)=bwUO=Zvgj7IHrWl^HODB^*vzWd=>chS`+(Cra%M7VKsp>EkaLY)KwC -z{}f4)p25tq)2g09_yIF0n&}y|RD1s^Xr^Z{rbB0`cK#`u)-X#PP65n-88iq3rOaUD -zn4Up8!6|QN20=4DgV-MH8LTj^VU{?Y0)BThc;BZE=+Z)d(Dpawpy{5H)CJ{R@z{+R -zuY+dF*O@G-Sd1IN^J>E^aX1Aq17^@53_oB7 -zBgd4l(+QNXi(||n_Qq!+|J&Wq3xdA#OGh!vM9g48?&lcipTZLC42ouYnMVr!_&qZy -znz`6_)@gU9tz=WT4YQE@8K}&F8LZ%Nj9~^%!iHJo{xeXOi5Bc;M)B^d26A|f^G}%( -z=^2bhbHA!g#0(bXevV-Vq1JW=MKfihRBJnfqM0($tkcRw3mH+AiQf6C14-(_pG1-> -zNtL83Uso3CUAkn+AO0z#g(Pu~asH`j=KND_)|9Vjj-6JWe+soW@?JD^{;8$f`KO?n -z^G}&FDPPwHT=_cdILg?3{r1!bb- -zfopOiDN-hyId)oACYqe!{D}7t6|#`_Ofh-}qZ4>0Je}Z9&mdD4W{@;v2BS_hgG#v0 -z0d@u<*vdpjGd+XKh?I#IlA?y$l$Iw-m5JI9m_Y!Q88iuq|>Loof#z4O3gQc$_$u6gD_BPXV5HV2FzfaX$`Y2KVSxXX7Jum9o*_= -zMs@sSy*@D%3Ko|nsb&8LTN0%PTgv_owxo3%Y)OCidp*`W_kv(J$8X+=UjRQl~Cy!B+c{;YKN?6P&Css -zNVV28D4ID8oBLNigHDPXW}Tc5SY-yxpg|aZ@cWvT~0 -z0l%*N{+Q@q* -zMMmC3t(C8Phu$zt98LkufEhFh!w;Cj$g%S(GhhbWOlz1;TAwIo2F#$eJ_DFRlaLuO -zgCtS~G|XD@2dpv!X21+IkTsA~i8DY0c`%y$B@JW^k9IKRTYZ`yV*zj_zTWIB@dLZBPmk8o;h|}{Uu?x7oe9p7|s2X -zUgqco?s8mVATwYF3vxflFoRHQJAp5VZ$tP{~4%u2H`b!29pik1DF{!2_1%I1`BdO$281B?q{Gf -z17;8iobh>DWd=<`X21-#nRX1b_kZfZyL2ncx4`^x;PDsS@}BOjS!|Kdj8Q#e#C(w|i<%AbwAr$4J$gg>iTB+XPTYAdB;Q8ZJrXsI^x -zo=K6xmQZUW?+bg6gxOXAGhhY{!teuT&?ICA%wU^o4Krr2An38n9)H36PXS|Q&?ICA -z%zzo_8R!|5n`D5V!JMz?8I;#}46rv1%0xvoJ%g5NJ%ePLok1i;dIp^`HOvx+Qvfqy -z1`WdS17yr#p>q4b{aafNs(S=sI|eC-oH1@5{FX& -zGhhY{!teuTFmmj?$_$vnHq#nrlh!9nnE^8>tvy -zZ$Mj*2f^0MESed4Pn0SXH3^l8!V;JPGguJgIYybNXr@dwr9)>SS0+jxDif7jD-&f> -zWU!^w+RX?>Gi9R4h?I#sBXToBB}K|aMKfihmTJ>PnG`7#MN*_pq)fCR#&e7^QPE79 -zsHOVmL*`9;0nC6IEXe&Fa{%Pe^3;LBmiS|w{#1_Q%;v0OQL^We(l%BVi=vr|MXI%m -zMKev3DoITuRY1e66@S1gGhhY_nfV;U44Q<@fEmmzT3BtEOUrc6{xkup)yOqr;q+WDtUid>Tu -zYVG{f!rmicwiUn(m_dUu{D2uW37G*i*k)S8j2SEldhD{tUvN!M!1(tvgU|HTfh2W7 -zwf1Bu-BXgt%Mz)G$jNP65n-88isP517HovGXc3U;zzj5yqb1=nzy+3QAP+`!zodbzfxK@w3A4Qb -z(?ppRnIE4;amLiJ5mIb?6K-xyk-|pPyn4>cZ -zGzh~Fm_f6S88CxwrZvo7r~VhXWd_Wkv_1ovL6eXf -zFoPsg1vJbq^?d=EpJJE+GhhZr-lHYqV&4Up7DWd=<`X21-#nbt5n6#4~-GK067!DoBwK>51O*^MnJE6Ud?e#+NXn^wL~_jdj% -z4Al9jq}l)bOTug~fEh4@()tWw21!C@zzmv5!8B$NYOQ=-G;M^mjxpFW>9k&EaqJwRml2v@=+95oW*)n1N}cO5HV(lO=ivu|qaZlr+;b -zsLg?$LD5VDxuyE|Xdr*Srw){_^DnM^9p?N|`MPpoJzfRs -zR|hi#X3!uEKVSw;JcBKh6P(^{z5S^|cD%;RuFC()tWw22Da{zzmW|70@ti#UHTB4445k -z&_I4m1Nk#PbwHQs5?!K8Z_=gB*5bv#u6*73!CnqJq^I{wlGNsbyBxzXR4kgMDi)XO -z&kTxJF9I57t@s00nE^9+H6|}n$_$!>%-~Y}nZXMp)i({ZN$V4(%zzoZ8k3ixWd=<` -zW^k$g%-{u)>YIjHEB=60X21+yjmb;UGJ_@|Gq_ZLX7GYY^-aTU()vUxGhha<#^fbv -znL(3~8CI -zF?k7EX3!*L2AAs33|%ZOoyddcLGeZC~Uqj-DOV}Qv6j{#m_^2I-T -z3@~}KR;+>e@dx%tG#GpfUqyP+Fe>%%DlwFq;zp -zM5&#@g56vI`Ex#X;FkCPd;G`SZRNT6i(dRAU7|}XI2>aPwlqr{W|4-@K$WC+a-d>y -zss0zZWd=>chFNE#16C!eofKUrsTU~T{zro?$peEeb4FyarM$*r*vSU&9fBDY%?!4* -zR2ytbrr8-p)?{a3XRsi~bBr=k(aia$mg<`i!}j?-mY4xESdjZUrh&YLRXc<58asm- -zpQlwjgC-#}U!;MS2Fk -z2XB}q4yOQSzziCM;Rj#d3_j~q2Xtux5~Hdtl+7ZBF43iuoecQ$y0j1c=f9wrnLKd* -zsd(Tn$LFNF@{h{bRa#TNE}AJ{SIXip$E2CN9Iwgq(=Y7|ie}2!E!E1`&q(!@U=N>_ -zuS2bsuX~5yFnh$?TRt!YX3!uEKVSyUJ!ZfRwwcy2dy5A=qL&#kgVOp8UX21-R -zNEOg9`=sm(n7oW(2F!pNXdr7KrxIs?267sZ2C@cn6DgSH{8Om426EC&1Np^P;NlxQ -zgQA%Ra%#CUQPJ#=_ZZ;ked>TN(WR7~44_NjpDxwT>(v1UTWY7~UAk0jcR4ok8fLBd -z16G*Wnd^Y7cL)6Y-!HF7XNAO$v-p-(MF1^e| -zDKluYF#~3hM5=&>*^=lV!Ic>>gS~BmCqI@L$PAdlHq(}ncBu6URA#^on1S<8(USOh -zdQ>FTe6!T4f!sXY5c+h2Tcf2-0%f8^sWMTs)XpH>f*HKl3_kBu2YQ+P_b}K}25PV+ -zWY1tr=cy_dMKeiisn_W -zG}AyXwbnpRnzFhMKcZLmTE7Ta~6l$%3+&lD!S>kXCU77Ke4Pkw}2D_!YXlc>RG|`l-obwoEqN3UJGSTOL>OlEA{~mgo>7II-3(B{Gw718oSkzun#UfFv -zV$lq2n01~wU{x=3!EO@BdjXQv&Ga%OBXUhn(@ZZjGNL=Z%%quKW~#L^Q6@#oM3EFJ6D7@*iAt^Y -z42ouMd2gw9%X=n8?o11{Rwi25dnC-Z0+<0aXb^@UFoPx`GhhbWOlz1ig9Sm4UH143 -z8pr`-X3!-3Lz%&6f9gPzIx5orDqW&W3(7Oc{GoJdp?&`97!`}6nZcG+Yv-Sucn!0V -z`x&T`)Nle*j_nQ1ph?&;n=_JFRlZ)Zn+3UTupj@3!ItEK!Insh47Lme`)$ejCuXo9 -z_j3$02(`8|D4IF{bes!4NVU5hgJ#M^vraqz^uVR@L&Gd_I0Y~RX0U|A38l@xh5wvBG=?J&0LeyQvK(@<`#D^;0cgF`%?!uDi;0MQn3hsRKNtgqL~|8l0zyMO+4qHLakLS7VPHL`o4h7Pch7Z88isP517Fd -zMjd=+2FzfaX$`X@_$__U446S_eFiXtCL1$g21%p}XqYXD{t;Z60W)9*|M>gOha-l( -z)A!7P8Ei9cPwNxO%zzm%17;BY>5m3mnk5>@3wE=Bw2c^drd7^m$}v%DXOIlMZJ0&w -zKLb?*dBJWH$Xfw+25nW&Kg9-D&!9=DOvDTpO6xO#86?e^K`FgnX7lh<`MPBNZ2@)$=@zcZ2|r*4%{|xT -zWZrIPP=3G+Lahz96wO@hn|YKe$D)~weOs#UzT99-BKl1Mb_U4eXok4TY&cM!~ -z68{XaGYGY|Gbozb8DyGdXHYb=Gia%{Gf1X2%tG#Gpngd+_ySKI(53m$eO_(*i!^jL -zP`%6rC{lN2qRhFJiIjS*FessNCUalS_3(gA`RqHYYpV0nVvxYER_+u93Y2FzeV?&p{W@)k<-4FJ<1WXbnVv!BOL_)lI&@k!Cy>ZE!1a;TRX -zszsN+CtX_b!MDViax9uT|1_khze%<8Psu$=YN)k}MJGiKv&7*Pzzmo{gE0Jn8H^k| -zuQCH>u+6lF*`)P}Qf9ymO6xO#88iu*0W(MGQ0ZmP96PQ4aSrLH=)NsL#iD4Y -zm)TOSmznfaz7Dn4%Umc#CCs)0m;p0r5QZNxgC-#}UHs@~P-|tPqM2T1OSN8R(Ck((v(#EI^SDa-u+%V198LkufEhFhAJKUI -z12Y&oc3w5u5~({gIAGV4?;B>5)+b7t0W)Y2J_Y2J&&;4n$PAdlHq#nrt@s00nE^An -zrth!%k{L7!nE^9+6{)TTH_RrjPn0qPX21+g6Rl1YeW9lg=n`F`OLS>jm$D`K<^bjE -z&JXr-P)X_n%qzzEr!Wi^i)N{cMfe0WD4IE>-%@?&F2_p88fGE)GfW(stYk< -z-Hh<1o;pym=)bs;_Y@8li}Ys|i}Gh9@9EDf7U9n-7D+P|i`q)5SQO1vELy6Kyk}Bm -zuqD*m$os88iu*0W)9* -zdIow1LQk+u=w{ih_M_n&4G -zc(Hn+Tw<^#rTWKTD1Ad{WXdtsTA8S5<}SzF`&~skNR#(M-=EGNK!!rAaeAgUE=!OwZuUJ$0aBk$-U& -zi!x^wi!^8D>)cAIShPPMZn9Po*fGl2W&g||QL231OjEuNKVSyTU_p%M80G7tneufe -zMatL7L*?sIYvt=qikyEcwRZlgXr_D}8PS(1Ul)+K0_+Uz3=-xQU}w-IY?!qk4_H+u -zTG)FekhcPye`+UkO-`ildIn8G?>|jWaHoMB96MVDGYGY|Gboz5Kr{0tJAdIqJ|dIq^e)-x!z)-x!Y=^0c~q)e1F`$Lq8zT8s>j^gxAjV{rpa`z5UzK$$X -z`MPLkLkrC+`G|lu3O0D%WlV*AbrPj(sMKe8vRBL6TqM4pS -z?q8LOIw@+H1|H}%} -zHew{H=?4z!7fKz{PX;mrX3$wxFpU|6S{rOhni*`V(uIme(ac~=YPnu!(ac~=Wkht!Yn^fHSFdYQ>g -zy-dB#eY;7R?FBFcX0VM?W{@Og2F!pNC|@gIzk}Vh+@>B60m?+mMB6A;CTf=IWkyn@ -zm)SgQm`z%rC}jrBpg|Zp4KrvGG6QC?&9sJDEB=60X21+e>ob5EGzpmjGe{y;K*Ma( -z`a~%+UMy{q^7d=}&+9)4%&a -z?*7;R{(t|U`~TDYKYa?2q_%4QZGri*9UFhajV+lcn{o`{a7cgV*lG2bgxOwzBvq0+ -z3jN9|Ge{CL17@(qrHOCMAk^BPQcLmLiyr-6%a$G2oC(O12m;p0r5QZNx -zgC?QDmhb~+P&D)8M{JKh`4JpDXJietkoy^^%zzmz;c&t#GiVYv%C9AjrNIl-yDd;3#`Y&wpf!3n1$TWKxGEZUomTY>!Vj21(M->vrCQG*Xr^Z{rbB0`)-y<^HOvx+Qvfq4Gq`x_K$2Sj -zhe=WwlrIf-FTlCXg_=kKc`v}od-I^}Z;J<#)Y1FTt9qHC){@jFVZ*HTc)+S8wXI6| -zI;?^jGzpmjGgy%OIi_JYX?>!U88CxD;Ed1HDl=#jG6QC?&9sJDEB=60X21*<$P0GUa@$Zm{t*r2%DLQ`mMCQg -z#{~Ori5W11CQ>lXE$^k)&Oa5+jFvt~^3eyQrAagApIWMasF3`PIe-~3gS|r3Ze -z)O1f3i&>OzPcPq;MyIyAavyu0aW9QX|S?lqDRlUr%DkJZc -z6PR*bVjweM1`BdO$1EXjlKUB}%zzmL0%v?OgPC9ttIU8IY%^^`=pS%6eP9O6U_tKZ -z7-gc7W9L<7zzk*cu&UQ9Dh6l$$!P&E72pZvId>cAtV -ztr~Yfm$2k-%mH+XE-fg}9HW;RS)`Hoq8T%ob=r&7#j$fh!z|=}2C5`AoZy>JQa?Hj -z+Z55uOdcp-mtZSjC)2!G9Z8Y$b<#}vx>6QXjzu#sR<~4pu{x6?Wuj1PWuk?>N5X6? -zfEh4@24VOCGiVYr17@(zw1ycoSP=BsWskq0fgCVq22Da{zzmpyo`If0xk(1-8O-^L -zo!;MS2Ef%Jkx?1G+T-ALe4;79~@TAxftd^7f~N -zsFh^&DCU<0@?L-`$E1Ra#Su6kzBlEVBvi3bvDmf>W)NzvVo@}+Gia$+u?U)d>xcB6 -ze@YVE*%>4W>Gp8Uw1%ab2dI&?49Hy;)R -zJ%45hUuAzziCM;Rnp1xyKBc!8X$x -zW^eI;NAxlSW>8w60nDID$PAc45~%_jW}lRO0h5<8%zzm%gMS!#Pac?ZETWilOauC+ -zryS1|@%~frz|P=BlJ(*nI|Dm|a+3^bn7stvE55Naurp{721-At8C-elK$04N4|h2( -zNT4LO2E5$mn9}Gj$0#Y>e*C8jS#aPfM#Z8~s$!9Tzzmo{XH~&8W-#gW`3`nwkTsEg -z9FD)h446TJumbE1Mvk3UnE^8>t7K!rrw&vs -z!kkqs+MGQ_)T-fKx?-A<_wr{`jte!Bg4texTi)9bx-gbVp8_PQ3wE;!^Z3_QEIKJt -zu?V$Ru_&6USX4&D44A<}MiMc4nPb9rUM)3Wz~L0b446TKF#N#IVC2|&)y{w!Y%{H4 -zHfepLlo>FC()tWw22Da{zzmW|70@ti#UHTB4445kaLaqNB+eJ{gqm+wij;|(hkIH- -z*ueb~GiV+dd5@IE&Y)RpXAo||42ot(OEYCLO;j{9TAE3b(b7zcjFy&Kf4`wwQo3{r_RKrgds_D$c|a!(QE>*9f( -zLGr+3faA8{RK)r5*9ytsm;;Ve?gIEy05f0)fxsD`r&T?JCR@X-^?1OlGEr^7HINgf -z%%DkV$}#+a88CwdF`i>Ikc(y-$WuCW7IF>bVG*ga|MJitx%?!3=7O8w)G;>J5 -zrTXsYQuF+cIe-~3g9W*tWArk^512vGj2X;2?J>aO*g2qK7IHrW)y^QCz|J6?z?9<> -z0~=;@MiQ&a*9&&DrnrswgWu81Oe#1G8%dF#!4bPYeeW@5@<5p=k|JfInPaC_Wg=#puR4j^SuJ3x3t{m_dW^B`lwP!wi~) -z%zzneGp%7ZX?>!U88CzA%KnCbWCl$_X21;IK&|KhO2e!bf50j;UdS|Z5DVn(^r_|atIY~3u@ga5-GzgMvc*}GA( -zpi9M~g#hO=!(Jt+og7F~L#?YM3PsrvPTa3>t*t2h3pP*m;#1FoSKTHOwZhPn0qPW>8w6 -z0nDID$PAc45~%_jX07-GR+#}a_)5*-@TmhgwzO*e`LFwb*6|niWM@#M`z5+Wmm20X -zL?x+7vs+23BsEyHz(ZybYHj4bXm<1Q9dI~dRmGxNs$!vHu^{(zOv7v?FFA~{GYGFS -z*fQhuw8{*Q3HGqW4445kF!ElhyNi93B}U$jyqB9~z%L22y#PIfhs@{j12ZU;GJ_-` -zGhhbHK$)oOIC=)nl7&)F>hTbuOmv(JJuE2`MN;JaQ?s;T_K3H)e9$wfoXcU@L@6_9 -z?lA*qkVLA0hS^&@;1RvdfEjc~5-4Q`O~P-|3=W?v>8SRq>(=U0yBuz-C#?zbQgp(MC}X~tjGILkrde( -z6wO?dlPL=`D4J;?r&`+?RLcuw=vq|d{rObdCGzee9^4T}cph?IK -zn87yF8fLBd16G*-M&?ICA%-{{wdj798%qFc*lrjTmzzj?|#@x(DQ;y9N -zhhZ1&W&vp%F-G1i=Q8r1D0LV%8R%w&@&jhT3>L(Ajxq9HG&AyE36+uenPaC_j{$~S -zD-#vXjFz@k8+i|!xfvl-CeuU8aHgNx$86?eAEGmVSq!!IoELy5nEHWuF8w60nDID$PAc45~%_j -zX07-GR+#}aUIOW -zt{QZyMA3`YGeq?=)BYu?>7J$>i)LP|ZmGWexzs#=V-8>j%wR$8=NN-6;Rnp1XvPd? -zoj#pTVg^C8Z?R%=!3@33;DN)iNdkvqBVRG)xUj3RGq}{|OR07kcHR~!6D>&f?N19) -zS#25uT$2+hHS%6LmzxnTr2pkVGJ~R-p1~l}_e;#6axP_}Ox=}!l6nmP-uAzziCM;Rnp1xyKBc!8X$xW^eI;NAxlSW>8w60nDID -z$PAc45~%_jW}lRO0h5<8%zzm%15=Kd?c$fT&_FJtXdtHnX&`GL@7qnnY%jnx(M$Ee -z_=Xu2jF~}_kQp!oW}r-@Oq6bN88AL|V6Y`+Mfv(gCGf>J%Gcq~23ua}(u;2zW-o#F -zif@#!yK?7{{!3Us`-T}b<(L68cp>hu{ib2|3h93dT4uluUX9613^Ri!Av0hG+e~Yi -zU6J?&aQ+s<44ACurok7veG*L^nYjO?=_CP#kqEKto -zM7=|Am_6d{EgzTxGiVToA25UF9y4GD+e~Yiy~P6_(aQ{8n8Ezifr`b8|HCf6QLzZw -zyHT-t)Ssgdbg5{jVv*h|N$uo7k{W8QVo`fR?>}9pKrh7G`%gu)8}HJUTD!631+Ol@ -zG1yXSZLpCjoo^$cF{>hc>s -zgHmffgG`DXhAp*r7`AApXYfLsFTT+;NSf&xR8pi&R5a5wXsLeZ!?5wxfh0BmB$Ctx -z(%zznO(B}33*f5*4K2gdHm_ccM1~7vr -zAv0hGNu&yBn6=^$SY-yxfEk!_jF!Yl4diBt2J&Du_e-W6tHW!`F`1@;9BQqBoHR4# -zSo;P$gQA%Ra!d6)PdUE)4>AL0upswy%r7r-^{(I887$aM0eLULXlb*gx42uhU8EPZCAzer3v-M^`k5R!q+c1WBsF=cd|hg-d|fnCv8bd-`8sK)Vi6gU -z@^#Wo`MRZA`8ty#Q;wn5&Ode8uwj-soC5SRE9YVciBe`Ta_qdy446R@sR9~ilh!9n -znE^BCj3iLX44Q<@fEjEvtzp)RKVX#^FoV+i3}6OLLT11Wl1LTMFq^bKQOXRM0W&a7 -z)V(v)L`4+SL<@GafV7PmqotK|dH*RDDqnE^9k2FgUr -zMCm3OuvZ0Ikm?^k`+s3!54sWazUQCvsRL7v_2)F@nD%eVu|!Atx@cy~F>_44%%Yhj -zRg&5{Xfmx~)|u#lRc62p8iavTX3!)w*b;tVScx>FoU9*!Isz_e>B*V -zIhVnf$cPNKG|lu3u4F;a^;^#%lOjEXQfobf=cKywk9r1?6d7zun&}x-Qlv~&G}AL^ -zseaGFmaG3YX21*<g3*~D^BQT -zCJ*#7OR)7ai)PB#l@#e^Ce2hVDrHf=E}AJ{w^Zw8W>RG2J=9wHy7%u5v&7*Pzzmo{ -zgE0Jn8H^k|uQCH>u+6lF*`)P}Qf9ymO6xO#88iu*0W(M7Sp#|BZW3mD0iOJLs{22a_3y;5jcPQo*6U=nE^96kofiQ -z8)lQ%CrX(CGk66Wuj7^(GzpmjGuUQY!>kp5z$!Cf1_u(q{yj5j5;6m3u+FH1$cEXZ -z^@&nuzzmpy!Ita8EKkW{u%(D%uw}t+7Lc|P^S8U7H~#IF|FWJz@W9TXGcr2^JA-nQ -z3}~3O9uHWxGiX0x27yv$&?ICA%zzmfd9P_-7icC+oPUZftP3=gW-idIl*P{A3C&iX -zI-pBW{tvtQnJ&?#lAR2oOGPv1pE`wfv2QX>#Uj+&`KKxjdjIKqBJ@PU^)icQH{O4$ -zq{xjePZ)Lmv%!{9YlAICGv({Zh;EdxlV-|92MYc8y)seKO!>O@ugXM4Gi9R6hzzzQ -z&0OD=`&VV6PKrv+7jQVmFau`LAPhgyGZ;B`Uez-QKVSw$Gd+V(JK+P_)-x!Y=^0Gv -z(7jaOd{_|l{Fxzu88Cwdxu0VufDPDNU9vM+u$u+B4Wy61VB|enV&wfO7y9jcJ%gEJ -zr`2B)W_tk|$eB<%|1>&*2J%w|E?7DY3IEiKi~KLyPUwxpKpWgh234@(WR#Niac446TK@DYvIKQM!lW9L=9 -z%v%%HSB1DHY4j2SS4ZJId@TRUWfEk!ejVOy#lhRvkN -zlw-)b^G^$-GYPY;0A|1p8ie5o%%Dlg44A<-(;8;XU_sCiOQ8$@u8VyG#>}8e$PAbP -zGtfY;YNwt-vcv_Nk+oDrHe7Dw^pTv{dUEuQK$jkL>G(s#Ed6l`kfcgd8-xQsPfN^T?U3~hie?(fE!75FGAYtC2({KT&@)&N<2l9!nng1`gO+MNgP@r* -zQ6@#oL<@V5g4tdGGhhY@!U|vpNkTn?O5K@3(d?UPATK_3pnP54u6!K@ksIaf1=aYW -z_jCO-!+*zMOJ$LInPvaXfEg5vI^dUt*t*t2h5;J$PAdlHq#nr%wR##W0yVt -zf?M7L#>}8e$PAbPGte{8GblI706l{_U(qutuQ5&3n+9c~qM4pSOSPUsGR@8)k|I5W -zPMI2JiNh&?88CweVfev2nZfE)2ae*z-{a1dMnuW-1oto~9g|Y)0Ng -zttF{NGZl->V&5rA9sWDY*UHxmazDo~17@%w_j8QFmPx0*|5O}12Pj{cRNwwoA+y%! -zDl=dP%;00G`H+*ZEZG?p&2E`NDLpf2mNv{n?q{GX6UDYbnW+7M88iv)3?g-B2F8x{({E -zupswy3^NF|wlgT2ISf0dLuaXWGeXcznP}GO(@|ArqGVdbEO9smFau`LAPkf;gOOv( -zMCk;~pg498XqZh}pD1Mp%wP$JlOHgHGYOZUI&iTsU255h!k~&p3Kw1KdarubOfUKVSw$Gv(_nS}0!^%^ZfE(xH2)zWJ~q==n2405f0)3vxfl -zOaL3Ox4L9!uwXX}avMk=f5DVvvc!~QBt@niXO5j#O*w`uFoU9*oKmPyGJpiH!2H~UB*e?iY6d7w-bNs*qx%(3&{BVo1|;5Ow%m_gA@FLTyuz04&NHq1iqXP`0zX0U|A$r6}Bldxg7R1P|Vt1{7o -z-RvWM`~|(t}mZ26c0Zz17;8i -zobkyFl4IupX21-#nRcw>Yaom;X21*<f1C<#tg9afp -zm|3*2YG)9Bzzm9JrX1()u_?#m*g2qK7IHrW)y|+ZGG@RGW)>~1Hq2J?lEWA~g9W=; -zQ``Xi@sF5tOdhxyA(A3DBMb!lZOP3Dhcs@;qbH2Wrc2CsPPK*b`= -z*}2R%=NlD^Dk=Q^=0k<#Z_EKI76DY{>nJ~mv&{eS*IVMTX -za>c2*tYR_P!2MFgY|{EfDKlUO4Z=VvGiVa3ScD}ogQA%!$80uw46tbCW`sDS( -zk@HWb*2+Yg6gmG?YHiA~XlBZ>k|I-%Ni$Q9l@uux70on|TdLiRkV%m;QK+>tkuuSO -z7|$`vL`5@YqLykGXa>!ci83itCR*5g6wLMlm;p0L5LN&)ND}H9RO-$Qie}$H&)`*0 -z9VlOyw<}*qLBt{b71j7*Au7dZ2++%{EK)DC?4KDhgJMw!xUpr@X*aeM$Ibz+?+Ufn -z%Pg9?u_d)!FSBT7}E+}8YY%joIOZ#*0wi4-6z_uaKiUG_y0Pl*P^< -zX{LN#TL(LXqM4mROSPRrCPgmx4YfAqIF@41s|~Zn;S|6Om_dUu{D2vZ96PTv17@(z -zw1(NF^@&nuzzj<3Gk_U137G*iNFr50!>kp5z$!Cf2FySMSpzwhI0H102cx-P(m>Wg -zZXyNKOcRA#Z#R%%_tb$y`tkSpXym&6+94vR6rJGEI_NYHiA~XeLRm -zq-Z-yUHC5~khcO1w$x6|&LC0hFl>{sVb*#)U{x=3VegSZ-U?s_?L;p2jnrK)vq|V; -z-^mH?{*@UpgN2MFV(bixW_AXdFWDIs&0Or8YOQCGNs*pGskNR#CPjJ%rPg`|MKe8v -zN{W<;l4i<8l@uux70uj?&{FMYgiMO`3_`7yiIj;J#CVQTCMudK6SY*|e8{|MFMt^^ -zgIVrh`P6|Vb^gCoFSBLOBc&lqr}v~iQkqO#LfYF6RK+54U}lgIHQ2J?2a?qA17^@n -z+YtH%h%y6aumHk{QNC`LG6QC?&9sKulIS17)y}}qptL>%m_d_}88Cw+QUx^34uyUJ -zqRfC96aqVd88iu*0W;WUTElEf^pD_bXJBWrAop_&GiVYr176; -zU;%^?!wi~)%zzneGp%8^B>G2iwKK3YD6P)`X3!*L2FxIdQ~?dML!n=QC^LBNQwI*| -zmwP&-AF_8EsxR87F3bULY)SERV@n;JbYn}h)Kf%JT4M%DGiFdJtcpd^%wgD;YB#oI -zQlw%LYVG_}Y&=}-yCBtfKQBZ@Vm1DPTi(MDm;o~=tfNayqy^&(;8+W -z_cKtL0W)Y221=PhldxfyJJcyanP|ao_K`mRf}TP0K+hnOB0YndW2aROxE-mcTl&>p`RK8A{DPOl#|40NUZcC$GH1!q%Pj9d2b8dE -zx+h)w#&v15<=<9smyi~j=m1w0i)LxVOp>~S<&79gYPbb6XcB(aN$LtYm_ezv!ItEK -z!ImK%y3gBx{Ix>zH|Bs+^MZK7S9{wX&H%0xvoPkv-l^!J+&3xb|MGXyXLX0RalbIb&=0eh=Ub_NS}vmm#D -z^zj#ryeCVHyhl>x{L{>_)2fm8a0O;iG&4=qQf=ftXlCSnOoz@=ef!gbpy$sF0n8v! -z$_$u6>`j@$dsL8=i6)(P{%L_`dIqsQ-g_qe4No1YSk#|H#Uf-+#iH$1l3FxVu}A|| -zv1q1AQbVm(EILnZn6=^$SY-yxpg|aZzzmv%%zzneGp%7ZX?>!U88Cy=`V3$OO+seC -z43bC{&@gMoAF#>{m;o~|@}6BHj{&w+|M{=`TpE92PwNL8xL;xh%>yIvGeqqSl4hnH -zhv~!nB|U?pnZcG!SsaF~4YVyt@KS3#gG`FN|5R%2Fl^DxXlW%yMoW`s -z&OcRBq)b#aGg{hG{r1DKZ+YrKlA3=KN$P^~HS>GFbo?VK7VXas%7`9YsDY1$_$u6gE0Jn88iu* -z0W;WUTElG8`a~%+U{}c=2QUqe|AW}EZX^} -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 -zX21+ap -z9&Bt^gqP9{h76u*_hf(Atun0W(;T`#EM$ -z>l3KVfEfe=XMCPk?F^cw%zzneGp%9Pia%hL88Cwdxu0X0L6eXfFoT&z3#$#YN$V4( -z%zzm%1EZzg%F{qDqP(_&y!X_B!It`aNK(`OJw=qwPQA>|5B74UowLxAv0hGNu&yBn6=^$SY-yx;JLED;UAenlaLuOgEvs?`M=UI -zo3uVr$_$tRGtkR?SscCm#$nhZieBb|-MqlnyME(lgvz>bsvy&GR?r -z0A>(CeWe-fK6RjC5r2<6DSTxO4EK02nwiL~byth<; -z{7dIe{WHUVhZ!(~1-YMNT7R^2D45xgW}jZpkWqrKLgdyAe_L?Ae`XNGvUFpGXoul4L`6mXr?V8 -zZ3T_jW0(OmXb^@U*clwK>&f@bfEjEvtzq^QajZ888E8@ZH^vu=~`3qd0S$@l;%P6esN8jV;ft_^B;Fe0F0?`m-Bb%D`RU^+2b? -z4{mI!p1$)>MKdGsl@z(LC23~L@mQqqmsBi@W=7sys-1s2%!M8psC*r2ZLp;)hYhnw -zyuIZEGhhY{!teuT(A;AN%wU^o4YRj+z$1E@0W&DA&j4o7BxDB6Ac<4~4YNn1Kee268HK252Cs0cjv>AUBbMY3@u5wbnpRnrR@v*a}>HV`oq_(?CuwS0*Z& -zxhAJFqVKJNy#3SxU7|}ZJC}a{;$Km|4rwyjQad&0pJJ!x{8Mo3oE$XFTJZ<0N>Z7@ -z5)LP4aX1Aq17^@543sj1kz?moJ%jKAW>7TKGl=c6oUWl;zR7o#ufr;sL6eXfFoOlTpJN(k -zlh!9nnL+Pcn86HDW{@;fzRvxtok7velw&6I%0!iOc^Nj<+RLz+6nPo8)LPFVlOh-U -zmRg%~EShN`S5l;boHR4#SV@sGQPIqlV@tIu$4rX!3_`7yiIj;J#CVQTCMudK6SY*| -ze8{|MFMt^^g9W*tV;aa?D77;Pudy?j@p)Q(&CcK*o;pyz&OeFrby~Obb!Cyt*XiC4 -z>CZbgK_)OQt^iXW>7$72FxI|KDSbOnMpIf%u;$4i{_z`_fYHCR4h{W -zuLjr|gdZ>iW>8w60nDIiX0YX|JU{)C88i>|GDEEmwp7mL{8MB^Zg~%mooiGLvuEPI -z0Ly1F%zzmz;c&t#Gk8v_Yya3V>-2xXs-3}t-RvWM`~^LOYruc@r7}?@Mao1o$4;v* -z(43s$_8-iE8Ke?tfSp0n%r!YLf{R;rfbnX~BxG#JIj|V8D6F`KRQ8k@r$-6Pui=vr|MN75oyD}-VGYGX-zV7XL!z^()1uz3<&>##yUX21-RNEOg9YsDY1$_$tRGw}Y?vj)UfPG}$(Q8bVT -zqq$$wK-NIsx0{67UVvNPuNuJ9FPTBXm>DDqnE^9k2FgUrM4#N`J)Sx+*pjlMeBEV3 -zl>)><4tnkp5z$!Cf1_u(q{yj5j5;6m3u+FH1$cEXZ^@&nuzzmpy!Ioz; -zELS;Uu%(D%uw}t+7Lc|PN -zapc%}wPDtkngOeJ2A^!@(O)h;*cnVtaQCmwU?AATl5299!Ghe+F?(A70L8-(%-~Y` -zFPy;nrx~BGGK2Sd>Oe0u|0H^u3(9we>MzOv=5JIi%KiM(4mwTea2%#AHA)oyGFni*`#lu0jhp%9fY+X`R?%%DLS -ze!vWxgnF6b2h5;oX38;(nR*6AGd+XMm-GxWDbh12wbnDpq{v~|QfobfqM4pSB}IA$ -zNi#izN{W<;ie`ESE!BDknG`7#g<2~UDHAP-@f@Q}R5Vj2YN@{Yka^Qyz}I31@AK4w -z^7SlA?s9BVqDyosS=0f_*Of&oUnkR)uS>9%uZw2N*QM6V*GV(w>q?50uZw2N*Dck` -z*O?T3EftFeykC#8GbkR|87$b%0lMDld*$m+in>dZNS^|j0W)Y2M(VDYIdbg0+AwQ9 -z9&{pLx$H@uY<+#K^I|F90Aop|364EBQpRvjem_Z8?u -z0f*BEX21*<O`a~%+U8S&Q -zE%o=1q^AA5%Q2gsdYPRc?B$?|Qb}t2vtDNSfr>@5RK+6vfEg6c9EQ!UlqtuenM3-S -z6n#I3^cRw!>oF=8rPhlTi~5-%pn;r7p91U*4zT~^dpm;xpQj}|gOOwBRXYPagAE(F -z|92Z^lh!9nnE^8>tJjIvocn6NOqU6BW%| -zlT#UyGErtk%0z=m-!CZ>by8GnzJS9ih8Zw}24VPtp25hm^J>GaD>VaF?F<&|W*_O} -zFDMfw5B_C<@Ov!j86*$%3<{-s21!LdgV702?cE=Lt&seUIiPcnMEVq9XV4j$X`&gT -zb_V4&%0vr!``ynAQJwi5|A?JI0Cmj_-tDOaNoxE(?j)&_)bQSg^iz_W{;Xm#_~vQJ -zU`sRYmxS3~fQm(K)>JIY512uckQp$81-YMNm_ewuUS`qEjV&$JZfpsfnR1+U`gCu> -z?N8fsKmSLVL7^RE$^8WDHD}iD-%6rK8GJPkV~yKkc(y-$dwdnAScZ< -zkdH^$nv(FeLjmy$>oaEPuW -z)V=O|Nvb5ZdnkcYNouo>88CxwrZvo7r~VhXWd_Wkv_1ovL6eXfFoPsg1vJbq^?d=E -zpJJE+GhhY=TMV|O5@&$Hmb4y&Ee2bfNWnCZ0ft%|Y)P6KY_X7G+r9VlOya426#4t#nO -zd*uAA2rH{}>8Z$F{j8T+l{<&@lcjo@kwr3tq!}})9QXT3QZum{1Ki~pYOQ=-G}Fth -zj7a%9Ga`36&N_V>JGuLLl=A$63}6NURA#^o7BcfWMlZ8y#td4jnL*IZ#lF`Im`^0! -z#lD$Px!AYVTF>AKqpp9}Gng}?8$E-hnVvx##y&@*VVF#~3>&9sKulIS17l^HOD()tWoFoXAe -z>OlEA|0K%SM}qhGz4Ep4brUI=X5>AZjmpJZ<$ZxAMoZIojFwhs%WcZZG}A<()(fMh -z@A=e$>$~Fb;V#FNJ=b?V?8uHkxV|elYp(Aq_mrd_6YQ}j(t_SlJpK`PIkq2c*Cb{h -zC|^H-{rH3Ob!06DTbiW}vjKsDwKI6Zs~6ue17@(zw1(MB;JxA-X21*<6LZ3Cy5ioM!N@PaU|+vHl*)*9#h{d>#I5%CX&huR5J5Rlcsh -zATvmm>SZ=dnE^9MB2_@ctQCL2Dl=dPosk4enL(3~88CxwrZvnatxuFP17=WKp8?FE -zNyrSCK@zC~8fLBd16G*wZju3}93yo%@}4yFGHj(Rb_PW=(?l)RAOEr~_w#>*88Cwdxu0V^6CRbK -z@4yV+_o)NAM3-jGSy`n^bSa5c0m|2vLP}DDX1B`Mm18>pR5bJcQ%m*T&!y)18*>0N -zUf1J%yJ&R_|LlOHgHCSk)YlaeXmJ1Ado -z?;Gq4n8AYF&oOoelM~#0WCqOO9i&>BC}?(LXHZ)1F2_un+~rtm?fg^G%*cC7^^d>q -z@3O~VsMNk-9s$Zku`SR*p7D8FRVFH$=^13oVrS4yYnX-H&p>4c%%DLSe!vWxgblM! -z&IhdO87$b%KGMfu_`~lE-ubBm6^k(EI~9vb^X}!)A^lO5PQ_&vi(;B{nXy@ONIz-j -z{8Op5B(-SfkbXuq-W3>k)A;%MS2EB -zGd+WrYCVHYij;{WDN-g1Bpm>t!w!$P;E;0nC6IGzh~Fm_d_}88CxwrZvo%!GfUg -z6ir><6)T~00g}|Rf9Ic~Z0BO% -zrkO+f(>Cosg>*>2nCARbskQS@nH1?|R#N2rQ_)N>v!(i%qgQA%Ra%_)p^bC?_dIptH=@}%=^bBf; -z{73H@y!%rJbcrr4?8PGHm&!8RAID#iq%J650eLS##iB@{e4Qv&u}BiCSd30^I-T_A -zzg9^8#vITlv>*vWK!fXY^k;LPen65gG!3@GLvR{29*>k6BW&ze`=|A{wb3p=bu8Ym5G#z -z7Q}dtQ6?&yDHF9+JO30kQzpu!NSSD1?@=(@3t$G!AVF9G%pggqXHcm-Gbozr8N~MZ -zkAD8?{hvCZOLQq^Cj;~{D~r_2Ec@5Xtc{*tX3|VAvnqFbnME_b%$91s%uI^(GDEHP -zG8gt93A3#LX21*@gy9Fwph?IKn87yF8fMI3LD0KbbNnL?!v>6*L6eXfFau_wXP{?L -zZju52vLLrRNs+;p<6P*sC4()6QiCnYQf9ymn1P*vok6-u25cofD^mT#LR2dL5WozI -z2d0VAE$j>;bvI3vG&4<9O0R)jG&4=qQf-=ON{7xQ{5^XH@Bh?+yBx!uKRTCLIj}?e -z3##Feelbn?y8K!BI+>FC()tWw21PSwP)e_S -zoitOvt{t-Sbt)yy1N-+Oe1Z79|yn7N!5k -zA^ogxD_?hhu!OWuMvo9HNtL8F2*VE~sm(x1YWM*&D4ID8n=>y4TZ(30tUkWPeo2|AXr^b-QtkZHVJ`H* -zKxLv(Yh@y3q6IOYW0Z-CX39j5l6>?*nJ9UvOjK&EO!ScX9DYzHDz#Q7Dw-)1MMk7d -z)ESX7(XmJ?6BWT80vv`7wN@r7ni(xkwN@r7nwchgl;ooiLz(DvJar&RJ^V}j_7~F2 -zTu{CR=7$51zo24~{;XnA{;Xm#a_qF~UAiM%W(Es3a38}ALahz9JkaU*gNj9{wTea2 -zOvNHKTg9SireZOO^!?IMvH1VlyYjdi^S;es>}$vp*>{pHTQzo}>_U<~M3y9J8eq -z`u?Xb(F|w?669VS!!1YP2Q&jjGnxUEZJGh18Mhq8I$fBz^Ubh`Y20!|YR#DeOqn<{ -zKx)mI0iqda23V^3W>}OIab^J2nll4LGd>K9rJ4`J0-AAVfTh~57gBS04{-p^0HBm+ -zKr_I-O5g`H14J{Lfmo-FWSkjD;30+?kb5yuX$CX{r1daBz8QR%R~@i@4SywUUyEhW -zE}!jd=+A6lW95S|Q!Ie9Oz6*?Wg?W)3?KdDivrJS<@nKjNk-czhRXi17F> -z397;4yAad3@{SCgEANnLY+oa_=E^&w8Qa%bs(E}D?1?~_DHcF8pcz0Aq5zr!Bq3*+ -zphD&>6Vi;cOjIGWeT`_wStgch&N5+A^j~XVO8~f}7`BNJ4_FyUup4P$`>SDmS{}W7EI6#KE7%Ky$)~pO*Qp5o=Qftl( -z5Y0FTx{WD3shnlz{M7U(R{eX#TL{q~eYY!d;s=FC7s?Ezt?Pyo$a{-WV`cjq$et0~ -z*U&xLu|PCq`x<&HlT;?D62w>>!}c|*1$lgzxS3EW)&A^Qh-t>-yI@kp0S{OiNU$5}c>61nY!ktZh+B>brEC*n?$Hcr29QW7fMx*H -znr$LPGq#Cfn#48{q8ZynSgQG&aKtpWiI7^eO@uNcwuwMSWW{tNVvt!2sJ1>v#63d=HI~LGAx!3|SR6hSCMXF0lh>}o|$&KNbBk}{90nGr* -zz1R%L+>2w_zLuM@(+m*7J_gVX -zfNawY5Y0Ht6zgP&nS@D?b3uSQ$XKpcx>Vu`>81$?`t1GC(;OABM$J&4*#- -z66`nP@nKk`)_fRNTzGJ`REkt9zm*Ur-@42~`DoFAktC{jcg0Og*IsFiAy3VUh}Yz?FBT)=W|n&A8==k|H@t -zD*SWO184>ar8EPY0n&OHKr=uzqZ!Z)6s8$h-ckL^#TG;}9^Zwfnu{$kDf;iUuO*;c -zY78p_!~<3a66{7Y-u_Y~X9f~#4+vz10%!&_0}Mit+jGkilMurU>#+c=Nk}uG87Ry&3^T0w0<6*uXa*AG -zUK~R+z$By@{QoqA@Aj$#&N9WK#3U7q5+BkBqQv97BqaxukS0n)#aLyM$|O}14n>y0 -zBo#A|NhYaWw>XvSl5K1#B@4?Hss(u~LCV5u&JLf}2b -z0W<@ef#QuQF~$_W%E~~V%Y6Etl>ve=+eDCu{}nU%ey=)UlFB3%xjPO>MZyA=M;t(1 -z`rp(gNS;3vz!O`Bx5Y2c@ -z4wh=Z@&nL}Z6aYhR3z1Qy(9=ayp14$W&lu1GoTsZ@)Y<1%>dDiW*`vh50_{Lh-RD_ -zfbv+znE|93pML@w5g&%dG~<>d$cX&8O$2H7-`R4Mf^Nw%oEZQfurk0r-~bt9EvyU> -z%~%;g&E_@{qS=3?GWd?KI$)9t%$Z3lHfJWOz?_Y^*aB(B#TMkxTx@|f<17=YHD{TK -zW?XE6r4&0Bh-RE+!cvMI3!D^TnBfkx0IM_ungIqO@B^9wCL!C`zz=8!h-PeGvwe+N -zBq0F949LA0s5Aqbfx;-I8DJ7(n28d9h*DMt66{8CqzmuBhhZTP_%JL;ia0Y6bFA)bm<|<5H6MnBOv5mPI1~lY3}^-zgaD;910lzXu5xAo -z{D5YFXvUcVD3AFtEZ|sCMuuSqx!<6;X+ -zin!PUX~xACkP&f~32DZ~7A)0VY=KD;+eAREIm^WLJBAs=p(uchEhy)r89i_2Li -z&JPsJK_N<+q+);O@m;_V*s;JYWyb>e0nGr>jL$#8Qi|`TLp1xZyq8V_wEsj5&vFDj -z;L1Dj8lL6I%0NQm4`Wyv0NG|`fSJb10H`%914J`c23V^7fB8=+zToen8PE(Q$h|m* -zWwp|X9iHM -zd1e}9DYqPvmVdqFi2lT%4ZuK#NEZdLGLT?5666-7J;FQi%rrLbbAT-7Sm9N^ -z3{d0*cK^;Z)4uDg4ya4iC84!Tx=LO8f2d24Ie#*MNh-)9x!8he#^;})mUFQM(Ts~N -zP`TN@#(5Ej8IXH1P-zA<0}Mjo2Q&jrLJTvI`-_3f_O%4NQ5@;QJFtBXdBFBHNQ&6L -z7IUodD%(Uf0||03j-eREl0=_ -zZaJd*m0OO8W?Xp}B`ZaF4BJGAW^5CI;+1V8OfyyntPF6@gP6uP5m0Nki4e`$CW30s -zHW8v3w~4S+^OzjSGz>E!_hO)aWd`5(RR`=?fZvBdI~MF%Kv94J>{y6p&z~I&R7bI6 -zfoaB$1yXBnIZ8-_r65g#7@7gi0L#4?sN8bI4CG=9NZn}$n1?h2pw?e?ETFjm*#NG* -z(+niYy*P$uKr@ga_u?3u0T6GR0iqdanPQzTd^(9M?|^2UWr}sW@Fm`yWkRN5m_Zzh -z0%!&_0}MidQksE~V?|dn%s}oh1}fV`66{8CqzmuBnE~Vh+e9EK;>wp|+eE^2s7R{WCIU2Ln@FtFY!gYyh -zG-LZ3r7WCfBAUtAz801Rg^#MrmZK1O4{-p^fMy^;?!_^z3_$8mGe9(>8Hjb7W`HqSl4{N}A=4xw4Jf_i{bm95K*{IBruu}m$*$N9%~tKn+Vd3 -z17xJ!+$MrF`@09o-}zMsoMj?&X2$}WGoQ;u=FAgYAkFyv6D+HEd>8g-32C4ND9Vjt -z`x>_m*}evTz{M8%1p9ai!%RwEA~%NZYYBEEL2d!kg?HfdPanZ9_XAhnK~ltyg_vW7 -zSGn>o*9JZ|mrJ1#32BcghV5&i6R>>^oq#U`1Wq91%K#C_Xa+)&rWr`!SWyfs10dLJ -z6Je&YO#}p+Z6ZW7&J18u#F+u28P9SQRjx%so@;bZf}q3O2m)vZGy@58FOCrbOn^P9 -zmpC(!U^f!v79d@C2hI#2OE@zCNfBoTVvZGF<;(!M0?h!?jH{(ss(EG_pcz+7h3Qa{ -zRP&e|$TSQyh(l4pzs?N4_p1(=q$2lZk}5&@pus8@z~?ey*N=-W$e-Di># -zGe8*;ABM$J&4*zD&G^a>m=v*1#5R!xF&4-C%i2WW{Z$9lCF&BC9T>oscO+c@GF_5T -zdHv}awy(vN8fTfn`wL0P_BBvzwyzP**uIA9&h|B;8Qa%Tt=YcDITD5$kb5yuX$CX{ -z3_{=sGy_aRp5+MqfM$Sb#^;|vc`V~B6Xsl;WrB>zjtBcfnsH_TG9rJ@G9k@4Gk|K% -znE_0SI5Plh&F7yW%{VhaYRxtgq8VofSgN`54wE9biGW(OO(dcAfG|@ifM!55z#s&E -zKr_H3q#4i*6lNNR8O=a~po1z~cn2Pn17J)uz$E-z&EUJg>VUIMv1D+TiM+ok011nN -z?nzzxAJZkF&Hlx!c9M_=GEo6s*|ESZ#V})%`aQ7!**%%00=J+UU=seVN$O|d{f~X7 -z86dUhL;8>hd>B@c4t>bmmEWQecn@&^QgZ}z5I{4a82|)|@mYA4l>wp|+e9$4;qhIV -zX&7ce?!`c*8PE(c2!S8a3@`~X%y4opz$zD8B-oAONEhCLl>y`dSKdKV#Fck3$BJqX -z2s6b3*d`Jf&4){D6A7K5@KIH^iBM8RGoTqrkb7|q%>bx1D+5F`KL3QJn$JH0n(@pu -zu}*VlfYPC&01PvTLs0a{-W{uZ8WXA%?Ug49U -z3hRPcS=hdY{>=6@+t+|aVvZGFW&4`#YYB2Mj-eRqyhEB9@sxL@*11OaPzbz-IDqYI094L0u^#}8i4lmevNDihHxlF) -zAYFI|ZaG38uuTM#BF+rN94oxaHWBaxngOC2+eBEZx#b9G#x{{K9V(J)yIv9m9o|L| -zKr;X+r5Vr+aCr*+fM$SbMl%qI^oL6{14J{<3_y9znE|F5X9gf6;>ie@X6|;9kR}C< -z-;SXf&yaQ(jkOyoNfux9SA~DAbud+=spj)ffM#qHiFKN7A_*B0SKdKJ#FckUGp?3msaAUlOI*bQFpweA -zMFDIRVIHtD02pRvAmmul)xYn|w7=t32TW3#q)JLd#T6kE7R9WSy7WJ#OA?&+uf*`V -zOvDlX-8E2WOlw!vM(Try~VyWg?jxZ_u`#Kg95dBwT -zSQ#K5uriQfH-8CxlK&J>Y{5wp+eARE`N|K-H<|&>0I-N=fXh>))@&0Ynz2oU5-PTd -zAkEk<b%65uzE}L|CfXCW1*3+eAREx$=(dcMLO#Ls0gI%AmmulRhj|K -zKw+j~n2EF=qLgMpGeBAo184@AgfxTyKW6Z^yy}1*3+fV<9hd=7m;V3g5+uxD4Ztvi -zI1~jiNoA7CB$bOTTx|Kv3jOI1a?25BO?>`|i!Hws<`Z-N+y|cJ2-KR3Es$nhY!Q|P -zc7?C%D}_SfJ;VVt1De5~l>V>dX$CX{334xv;laL8s%ZwOQ^e!Dz9G+_3pQt&h-N(4 -zSFF>8XRz~N-#?J*bAo;Rj9~`kUJO)L1}Nv^0Qn;n<$j{Xa)*14Z{q`y%?x81Db&xiI@I8%>a{-WQVK+gi!F#_MFE^;$}`R1zGsq(nZ_g)s5RTy -zAL%6j1BMw^d;wPfMMS!O@wI1HW92}KembfrdJ&>Nrk@>CaDsX4>KRvOY(2Rjs^B-3}lFOQNTxC -zf&%uJ131eRFre@flT;?DCohXFJLOhTFg%>WV!1z?zA#TQ_eW+E;p+DPUn1M7@3{S7#2%45B3E# -zv-`W+*An3T7h~8aLOft)z{)_Jj!3x5$^g-fl>w4)wuvy)SQ!AdW@UhA#>xOoH7f%^ -zGgbyLDdGT`17rzeERNwe5l)IQ%&_7Muu3za8DJ0sKcE?45@MLaq(l_J$^du`D+7@Y -zd;l=bK*+J8tAEqVy97A@#Td>EkXnD38T?(ZI$*~F{XVEm)FmdV{+wlE9&pPM5rwl% -zY&R0*7DG|~P5As1%x;;aB9wBmMLxlPyF@df8A#}Qh+}95K&`ph0%^v@mXDGw?*rS{ -zh-PdPiFMkaZ6dks`iymKUjwz~EEA_pl92W}>i*nkngPuKgAn)uXPKCFGy|G}!c4<3 -z`*Z651#W2uGy|mdFo0%&Nk}uG89*YT01UG)^<4roe~+OV&93X>{1mFK8fh8Ou -zL+jxHnFD0S?FPb3u>fup!K8@WLM%1!a+3Y=QRA#g@;S6W{#I -zjs>C_7h8}yvwi(dYW?v`wy%L&bFl@Na!Aep2)RG~Bh7$jfI$fSfU`_YJemQ`Kw+j~ -znEh!3_#C=41DXNSdKf@6z$By@&c=EE6g*4B#vi -zy3gM;%aow$e>sM4h6OxeW$?!g>svpvGGJw(aN31o_D$?b{gRadHVK*mfHBPg^NnUe -zGoTr;GT_QPauXQ9m3L6ra669VSld1>;CHz?qkR{j+0ba3l>xRY4v;}!L^D7%<2Df#a+(3683)L)ZeV2~ -zOoxiDVweHB7Xy`M@V{XOf8VPPs7ur(EITj*P)v5jqQosnEJ{pLAw-#^LYmPGXa*99 -zgkoq0K(M*x2s?LtFC9{A&N30rxaEkYTKO$fb9fJN0L_4AfaPB72Q&kk0bmi$KrF*j -zuF?z;&A8==w45vNm}y*W0cy>~7DO|yykn{6mLs4U7h7QM%f%L4zhjs|9Et*H1~dZ< -zLf{8910lzXu5#ra_yNrT(ToFR(8-i>%Ms>WJSIn!4t{XaGNI;qb -zFw#SgK2*5O@!9 -z0L_4Apm-xnj4_3;vNDihHxS4Q1#p`Pv*f!=^}oOj{?1n&FiB;SirgIs@c1rZ;GAV5 -zn(_H3=$>3`K{Vs>T~N!Jq%ujBAjaYt&N6XQgkgpiUw~Db0nGq|5cmPj0Fw~I4CMY| -zpt3RmUc<^jWCI@nOf$eF3!qGoTp&1d8!lc$H>=Nk}uG87Ry& -z3^O42VxZCtXa*AGUK~R+z$By@&eEtcjHQU$Ns+gpToPdihh+{PU9Ss5Uj -z@hnG>5pkA@X~s4YmTI+^Xxs_!Ar8PmhDa9$urk0rU}YeNDBDC5iUU>#tPB*k3Zaxs -z03nE>8PE)n*24hK3=qwDOb)DH*(Sm~#4rPLF9s^jfM$R}2>gI%fJw;80QdpT0MU#y -z1I`Q(izEbKm;t#L1C?e#Gf)_%Gy_aR3^S1Xi-F3@K!V*Uj&$K2{sk-V%Q29Fp@^x# -zSAKw`$j7#1Z(Y+oaq@nwKm -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 -zngPu~g4~N^Xa<;sGy|G}m_-tty| -z&I}OEI6y`j5oZQ4BjPFVpR4jWKXZVLlOm+%5^yMrp&8H&FbIJkaDXi2SkYAsv(Gz| -zfBG{kgKt~R=f1SK_b=J8z)WM3$|RLZDi>Q&*22XW -z$PzBLe377h`6CxwAkDbgf>IV%24C^&t8Z8t0JUaifM~|W7L*ZjmI*T=F1CEF&0l=O -z#TJ|tAvKqPLs1OPfM$R}2>gJHEkceJUBxi_att5=nZL)dGWgP5zVMpD7m+KDbm1M? -zCW1U*o9Js;{^1+8iNqW$yqXGOrdR+^d56}+nSsy=c(AV&2GR`vApKuwFf;>5Gn&C? -zMZh;dvob(5V`TuWfA-_L(f>{uY-VEY>SGdmVvxbc@ivSR^h#*PJ2Yj!NY;?-B*aFz+wnn^06 -z89NpzBVxw_W<=~*e67u2e8Y|fPKuD4OTeKhhGsxBz#s&Ez%551$BM3EnEjzCBLS9w -zh+$>$rMZ0JHJoLNY~TZcX$F5J)wh1+$p|z9334xv!7%$K_N0DEGx&!3f8hsg6Nw>8 -zGx(PJfAJ;FfM!55-~btw&>SE`mT-XlMS}9>j~pOFnsI>qWrFfWzQW3Yl>t;@7{E5s -zSG@Y_8&(EDtvNG51vm%DP^~#YMl>_x0QoCz{^FZlqkAaii$C#af20}wE6qUOs}5w; -zCF;_j)rha-sY|d}vqQon0f(X(CaFwPAqY_blT;zcimqaq;kJYTtL#{O!(YB|944tE -zCn!8z%dQs+k$`kj43F>n0+V0<$i)^3JrM;#i2gWdnF6EvaEY@_kQ8y2328<%_)7i1 -z_=aYHXvX8auvE*ID^^bx1D+5R~ -zRtBsL0E=Ko#L56_IV%H1Gai$JG9u0lAkDbt2-TVcWSkT!oSBP(N;9AtU=RX7-~bu3 -z6vGU6Y6Mv2%s_(OD2{aD9XLRSJYbs$Bt>i!i8)qymD@xjC$Rg6J`5}WRR>H`1;+pJ -z61NctnI~F)2V#h+hNPoD*_BEmz7hAAYbLCxbF7%OsY!iW`h;1Uai6n@zIEHN^L^HOD -zK1s5?4{Q@b9gfk+xiR6nk+eC<99|O4M -z2-KQwB1AJj{{+>VZ6ZW7KL7MdlI4A1n+PXG7-m53#XzMQ&SVl39~ZciLH9L#wLBqzjs(O%Lyo$)1?y;XK%ws&g4!V`7}{7(6gpXX_yoax>CR^8*RA3vzu -zWynJlw-I*chO+mG3r~z!)2RPAST-=*N6-Iq|3Q5o*YDAPOw+@0%SM+tQF>MX{vjDZ -z4ldE>@S(16`WEEPo7p)$+~Q5$`Nr-t=i^&jCxk}6TW2!$@aB+T2hN)R?%u%t>Sl}P -z{4#&CTj(i`x>K(>teNpVFLP|mhv`O>CIU-H`aa -zEW7g=9sQ$YWxecVE-eNeQuRI=nNUhU#bZGF)?JNLAHR>hA2;u+dyq}^mK6V2=>tZ@ -znRp*kjaM^xd&=9@@ls-1P}!j_K9@Yh67RkkCEJ}>_vpNtqi4;0mpv&x{cUJL#%?Fi -zg1oRy@9=lwrGv)l8(Qd{h|msoPI7;!A69pk%bGO>`)pmBX-*!LD7)C+=Hi*1O)Tme -zEDd^L-9OG#x!sNRTc#`uOi$3vaZMhy&dH{GVAihu@h82~T57fq3EVNkJaXkRo66Bk -zFKX2B3Uu#K?8E;p39y&B6a+Of*gro_-+$?#i@oE5N*U}wZT{}31&`bKj;UVVs;0sI -z--3(XOub*u;n=|~&&nsp573&QDtlDTZCIH=i;KPE?q!EAH9sA;bN1Y%!8_{oj2Wz4 -zN$17H#Z`{vJXCIa^X!}K%?GVAZ*Meoo@20OzGcGRd9JF@+s7&Azug^^ck#{mu6`|S -z_GaBxIlH2BWzG8zwtFg74~p=36J%WdKzaN4xU{*dOXDqbRo~rdeI>_TyWwMXJ*XPNa$G3-64Kx-un8=99ks3uUL9UwJ29oUosssd?N=%fJvplQhyRG5 -zr(M=Re$sBRSKrCg&Mz8tv2Q~aqhFeqb2RT*ad7pI{}`4bZHKq8?yBRrRcqr#OMmaV -zYqqzrkMA+=!2Gd!3lC~WA2n)kctYPI+_sLHThB5b^B);a&z+@`TiIx6fNdSC{sto# -z#prf*&GBq<>`<_N*u?yp55M2~nGYUae!MF+{nGs@tL7gw@!y_ubV2Ol!zShKHw{R8 -zU9YpPQ~kj*oo&xl#~;>jH&j)5z=MfV9j%IAkGUCU*u$%SC0WK^_vSZChcw@#W}Vz^ -zpL+Mec=dol%bbMJx9ZU?rkxz?cG7Kbo1vyVkGc(X8ME8T;l%}whpk37AF}mv%9*F5 -z%&xpD5&B}9PfUwZt*2hgOD-2W-Z$j(tnj&F0_?Us4$`OV0&XF|qWO}Vsf -zWB8o8t(-@gZVe9~?{IU5rOBa~9XdF_FD{Ufcs+`~c)!q@Sy9aw3 -z+?^Sl{bY&xB*W?6bN8NowkN{>O~!+f{f9>H4Q_F<=0@$bj!S!H>h8K>*G1blaj;WI -z(NagwMPrn?s&D# -z?VCHI@Ry#Tt(K^BJTYV5KD)4YA3)x7&YrUevpUAUQ|@=7UV!K8fq~@`dL};^P;j7% -zVPlol7>(&~es+F#=xtg~i3Am;RLk_0*1=Bw%wFxOR&&NlU5!o=?_U_XRI1j+DCf0N -z^!YaRo2WRJPE3rnKHU8M`z%*gwX!#3&9CV{Rga17-2b#ur~RH0{afiIM5#VEt8E*h -zA?sW}VSsPf9rGv3mTBs=wJA7fQ0e{np8dPlzrI@I__*!b^_5 -zS>Jh9JFQ=&q4KVI2jVXJhB%&hkYJ^i8W8KJ>8ozwpZp@ybf#hKn>R`6Ns*>em7cF& -zv2;ek<|Fa3`OZV<1i4n9SUymB(jdn`+ZIka!BOjE*-6H-q@Bi1#?<|dfIppma$#JK=c-HvTE9>Se -zdsQyx-*~L*ldjd8Q37jO`keKStj6}tZ?)5CEzSr>?q1w9Lo>tyr;YV(b9O>pc_{6rSO?Om3;ko$m=-Bq7=XD8ijrg%k -zbNh;Owzmr&s_H&;NN9-KSg(|8z0d5M7k{>=W=g>L6ZQOTkIs8yd2QkJ1Lxl!>Tem{ -z*KMrnoY`GwUwd_D%84jE!%!?dnTt`np}Bji397+Qud8Xt~*|Tyk^f% -zXCHh0+|uue@r&3!7v7#WGxF``GJHu}6}zX#Zx(~~KxZG{nl9P3R9s9dIJDEBJ)UIo_CHSyo<8Z@EOFnV9 -zgz?;+BaWq>+Fdz{?6ruu -zI$K+o7isL?y6;r`_~?#)YW^`RB5OP4`Z0 -zp8EbtA6ZE4#usaD44i6T&2GD$?cDb}U-$1Y=47X^N^Z3^T_d$zFCEhyy{ApzJqOm; -zaNS*ZhU(07t?ynRb-{SBTjyMd($aF?KG5>)Ic|^7 -z%Qf%DyuWrg?8wuW&-+{2bdQ?mFjC`-%sw2F{p+pHS3K|EzkE6A*8R?h+r+M^=2acT+Gfo_F&74qgdc{EHez6Pl -z6BqZldKTL#E@NBjUBAOxo$~L;$In|ezo&JNMShDHgnN(5d*}H!e(T$u9j-fU+SNZ8 -z*17+@f-C!`#lE;1`7*b0qV;8$1f>fy?HJjHC8xDh>&&^|Q>k2n=1$wayS3~>JqCIB -z1*-0y+I!Wrscp(Ct@T%P3esP1=yLbvu>mgDy?c)D>esqsxdg*)wiEVg*m1>{dv;uEc&u%Uwmb6td`njcMecyMT -zGW@H=<^(tlaI4e3!#Ynml6YY -z5;IC`WyWc52t1#an-RP7^iR(pg;#dd>E2u`D`rlk!CmwmudT3;_gy$Iz)~q|hEli8 -zr`~xT>Q8+dvu{X~OBy-}SNEi^v5q$~9b2vP!Uyg2n(WO=wr-?hG=5xl$FyWCZ^uq1 -zjbw4rp_K#QijT~k9;rz!coJ)WVZX8Aqre8alOTl{(^t^6c7`)OcXpM2~4&6iMFKT$$S_i+bGfigM -ztXhz-y34?v^8+SUbzBf{)5E86V(OMdW>0N$`o1oBocZ`^uh+iw!e0;UntEP!x{~Gl -zyLK1b)Nicf7}#~bZ;!JreH+JJec^a^&BZ5c{c_`b?KWJY(y8!&toJjeoFNNzje1^h -zYdBRUN^|pD3zLv;X>rz#R=xJg8JyOjvPH%8t%ZNRL2mq}d-Hdd -zzLnM>Zb{D@`!j|#*=rG*AJMnIk8y13wW)ip< -zr_c9J$$b~I|h0g)lHW@v<_O75)u3Ul}9y`*}tVU -z4aU9c?CG8}%d2->_O<~=RosV_2~?ip5HL0R-R*LvKAM;FqSn<5EMsE|3&-?~A8pSx -z9lyWI#?&Pa0sGTV)V<|4e(Ldw(S`2zlrERh^UWKpN^SZo -zmkIRMDCVo7xw!ZHM;6cA{d$-*-e#?_@zRS&6I%^gICoZZuGTN^7Bl)d2CFW9*f_09 -z+>)MGt@jLe$k0o@ePqFdY+Z}1Q};SMo(T+cO$)NFIp25c>EW-@P1~m6xrXNag+2RrtzWsS){p58HzuDn -z=+>g!(U6ysp>upocrRYrLnFV;9&ekRY<<)9YUZZ0JdcX0i`yseeYe5-tg=d0+U=)R -z{nE1ax>WF%{j}J`#V%uqOv`Un*ZM}Y9ZwnLuASo*cWy&s;I#L738g1!n~ZebVA!Y4 -z#u>h6Gm@V_dG_Rsq-}_o_CgcmU;T$@cX3rZpX-uk^L*^0GxK{+Joz>$d8t>-v#cXS -zLtMhbj?A8V@_h6ohlPi=#!Tok+SJWmcbn^x@g_UQw7xdDUCS{hDT7YbE%6;)qiP|9RWh%KO_M-{3j8 -z`SIr!r{?G9M>H6`LwjD1%De;J@>|S^p7?l+F@{TKy+bXYBGVYQz(l@KxZnG~9cRubJxb|>-$c(tusIw#HEi`|B -z-uPW*lgYuZR}N^qo28WP9-?2Tw&CbHhNENV?$NSYJUaD`|Dg*7`x9&}%(M;{_AH8x -zT-tN7&4mWC)OG${Q$m~TUV3x%>h3`wQD4(q_xbHr9!<;Lvj;mCTLXHSLoP -z7Yz3*|L{z6>y(SV7wwyW(MtJfuG+1|)mqiF)a@2CuK6pUs*A%Step4RZ+!gzb>--t -zDSnI6r`ugQ&J63+YX&jnS6?p^=xc0kXnU!$|KbM+=3lyU -z(D%}L(qX2-w%>|#k1peP?bP!g*Rqpq;M$yUQ-8<7(`RJux*7TG!g!O%9vzcI -z-`sq^^xeb6pw=4}Uzl~f)C12QV|qLeKUCMfXHvyEkr9u(&dqz6KFv+jr2Nj_3!HT) -z&G4I&ko)VRlpjX6cx|n`=T&rp|6T9X`A0f;ban0+aWX7WgL8857hNedWUF)6gC(-blf#&@{9Ve{;mhV(=LvwGu~t2v_*%;wAxVlej2La`Kdl;mA4@ -z_3Mu_eEI6v9j5)Z&Ye)*xzgOnS7s)wEl-JEvOiL*<=(|lkM+=Mo0u0CVKH*v*=9Dj -zu@Qj&-W!G~?*ZPh= -z;XO0TCFoAv9qqIttY^mSY-juUbqB2$##=4*YFE61i(Lo*%o`f@FShl|Y@T6a;kWpH -z&+tkK(JrOsX7G5bZzGB@3-^E>1ho+mT -z${uKETUw{g?-_Hk{i{gjd6`QFyni2&7@yQxLq*jncjImE*g>av8s+ZVr(3qX&gA5w -zW@l3(-1ZgEyx1t${n#oOtAw#VmvpUPIp*;@qmg}d5>DQ#5%IPlc$w^coBI1hItLsW -z(Bo43UrW2+SUe@~ZKy0`aM}~qS9LDlyQDO=i~s!bsoNs-*1J5inp&-L)s2CDUgeIp -zm{OsH^H$plE?WNS+r4e)w7D?0YkhasO8!l(4y@BWZulZVd5*=R`K5b=+FaCly#4h^ -z{Q{#*zmi%EStMPQR43UdJ;JjGx`|+KF{C%h%mBEMM>P>9{7zz+aZo(%Hpxh -zR2`3>w)AK;fZ6Hy>g~oEFGykW=omi@Wkl}7am<~ -zpF2%ivyu4#jSY((lTzPP4^q>y4-8z(C -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 -zjqek!8M5E8Ww%}Z -zJh!*D?mBQpy`AgF>?#%Mv2sS;hF*~&mnWC(vd{TRuQ_}AzByd$&dpJMN?W;j%}TpD -zV`}-4-QPXbsN*)P=77N`&bSQGx%E>Cr@NE&I@PUMY2+~T^L^{ZnKjw%RIk~>U7`2P -zuOA+t@}k#|<%aJoS-E}0tNEAXJbNc4RlGjUW?18O4YeW;X^ahVtLaq1Jv?!4vp&76 -zlpUz&Rq3Jrii5kC`re$>G4t3ljqxK#RO~YH-RvrRCaozyNU!~&>tUx1_w+6~+T9?! -z-&5nmO$HAbxuxN_ZpD7_>YMV@iME%!)n0x)`EBHdlq1jjYTl1;Uw6y9mSH8$rY!Y( -zv#g89m2pS)jDBlPv~Rj+MDC^&w}K+7n_TQRt{}v8|1p<+ncZ!Mc{V)$*89=pYR|_E -zHs2OLN4;C*qb-m0cjp{UBW_K;G#*Yj1T_1R?o3HQntoOEq -zts7+Z3+vn@;^eGj*^Sn3@A^~Hw%HvkH|XcT!}`dCagRpaS^SGv_>lJ3cl}s<#K2O; -z?2?MP>Opg?oc2&6e#ZQ!9Bp8^!K0p-uvOb@BNa=WS%^8 -z=A5(F*=y~!&&xQ852g%b*J=w6PueTpFKKRO(4I=AL~TW!ep*!B^qzn2z<%~Z>=zAa -zsZ{gjZw&t_*6#-nco&yvz>iI1o_Ps*rSr_j)1>aMo!Pu`&U#lxJA088760p_4=^@K -zX|(9yUaG>d=%N_Kw)?q`bkZ%LPwj~M)~ltKLG7+s;K0Pb<6ist&Z`koxU`?hHlA@o -zmVA`Mn=Xmg~e>}FE$7;Z)q^vud36ApVxnF*x -zkZX?iAW_seYP?0{AP38K={PBTXH6z?@4Zypa2>!H8RukAS%JHyux-MWJ+*Ok{K>>W -z9K_=YSULzy?v8w=MqvBg1JXtJKdH<#Q%_7l5LZzUn)x_PE$LiD;dsP_p574*>B -zMrnVeTIsb$??vA+dXWNfAGQZQ_AI1`ATVebNcGHFHGro@p_Mzwn{Gq*+`UHXL3C>vmYeak -z@$D4w;M**~FhdZ;#O1;Ha{8GeN>q$QAhgyHQP^IobDI$64n{K8)Qz5N!LI~eB| -zi5i#9DOiyR$R3Ef{j(N8gI5dclObk)FNfRhI}+?tH#{E(lDcAkU0lrcHeDs8<#y3q -zjt}?R`8n1a?QlL=enh%Vc~YKUo{N{6yY^QeR_rIRfnITPsI0s*ldE8`%)&{di=9rD -zxv&rPL%Fd3nhTcH3w-WCv9OH)GvmJjDj9F_F%{(49y -zLp7#rFhZ>)mha~{-e7mfeBy^A*HVfG9&Yw}l+Y_acHHJdROPoHbz8%Mu~1S2BF1h? -z0~xyPmA2%)RX7gP!;X@EUA}%DW1!V`PFZpb+h4r_Xn%l_j)jwDXBPv4^SrIxU>~V0 -z|Dl9t>!i-}J>Oog9p(dAW5&_^?K!69_r4}?Z$)JuHsA$_JkBqMG7Pp@sPhCol9vLMIrD%cWD7g%xL=?Z$Ob;7m{s7kj1-%YAwpH+gL -z37x+F!CTqRvRGlI;M*9K@H8Em-H^4o+>m`Xxq;p^lAg8oqLDq=Fq4D*X7`?*d-~>r -z#Y;Z71zS2xF(AiW?N;*e7kAF)kaqc|fT4UxTv)yjPA^HOi7WdikBhhi;TE>^Rw#tg -zMdQLqxe?R0CMygTe!hYYKzrc&*I2}UNF%k=f}xAOiILaB` -zd`!C2U8^ua>1i*q?@QqukD&)5el(j|^S@>>QMzb~?T=0(s6c-qWf^qw!Iv=_l-Okz -z6T1H77psHSNkS3@55KG|!IpZLDYfWNA=)oYh}zAXlzpSy{rP{ym1%kKuwNcbYGtGz -zBEfLUj2HA?l(gJ1ut9Cmx+3YeweLa_(d;WPU;;)@3V?dBIu;<_)s<@|1CL+xmxW=bmvfDlBTvK;78DqLEudN^olP~ -z)HMsw+W9P&7yf?K?Da9Yj~mDy*bV~9FXzAE>vQ0A{z^wm-5iPEXz0JD8;$OFMS&TL -zrG!Uc7l}VRhxjRsO;a~;-yQHAYwZ#Q^k!g?2n1b10W6-tyhvD5hfirSOw?IQql0Os -zmnr{Mu#Dm0q;?;|%c0mH{VTn^r!j7E2{Vi1a|-ee0eu}ijSU$NE8M__$~2gKwvd)i -zrinA4_S>hb_sMvH`BOhlN(dDfLS#GQWNmD50~@kzi(t$Dd#jWD>?!iM!L;@r*YDXpBVBWlJH8>Xoe -zr5b#JZZ$&{9PU6i1)X;v9}ODWb;syCDLoqZ -zY%=K^2%?m}UYA_PaQEUBp8f3Cb2wn77t;O@W5}j#s^Bcp?-+Z!0bh6dP4MH?;XC+_D6<_K#bU6e -z+TRA)v<0$Sk10Cf6j+ap{asVo&}I)Vw^Y`EXTQ&}c@PPo8&UR^E%s^wLc`MV|8^0% -zd^RrMNEWOL$3}X5CJrKz9)+9<8N2w5`M%&Db>_`XjUE)ZKAEA14|<-Q-Nn>Mq#%r4 -z$lGj=*Q-3GDkScHocS*)_P)tws9UU%1FX1vJ+w!h`bx2`XYRdXF^U}~5RV&n9k_6L -z0l4ayoi;w(=K!3_t*Y%+i89Z!y0t7>e^w8x<8^Z!;d^AuJ#*B^J#$RSJ?l1%8cEh(FaX2MD -zSB7CD(hX@&cMf|tUH<|p+JWnlJ4w9wU{ooU4w)*RjV;_QI0J5cTzF;q>>s48|1OI| -z@683&yB_~qOZ9%*YxFvZZp{sZz)#erMAgvbp6_g*2lq>UBzNH4v|lcnbV#K`HfT($ -z1ktVS+2@yXK6v?RVZ)0C&Ca2XO<$6El|HgdI?3dlaP0vtid@3ChArBOD@vF8=x(lLm`1||6q3iKPLl$CJ*;LFC -z(D{W*!#_D^R|1GZ-^!)Vg*#Du5qtd64>MKEZUcv{Yudc11Z7bbH719`g}S?Y4%2_- -zq)>HbNjD^Led)gQTqX5RF19%kTe$nsVj+X=i7|XZT-06!fh}#I=Og~|O4!y?_aFW& -z3N`>MMu^2~Jben^e2mr%>#{nKATG>R$E6<#rf>JZ^d;nX3A^*;e}mh7_z_%EAITLC -zxive^%ON$tHU2OP9x@=OI=mX+Q^_ -zYTx;xajs4bIu3c^BmmYRpxSrhwCHXgEkF27{Jncg^}SifLF_9MLKGJ!INn6aF$SykjAVBn@xw431X)W=IBEnAvTq -zQIaIK6nup>)t3kMv#HxsKn=_`{V9;taySo6YizBD3wbXZO=_%YE`}OdjA~ykrl6h~ -zEGA8~lplytV$CGAT3T7qiaud}C#lO@1_Hu%tifp52bD)Zz>hwVGqzMLWa{hEkg$d) -z%~sEZ+dISY8e%d1rCP{sGn>?!M;ZnR70W^!E045BF|2B>N%ic7H`{XNQERl*m;mz$U!NQ|2V)C&51TG@CE8Q}UJwwm7lBXv20}Fqr%a!1wRJ#k -zjfA@?=j9sJyyxqGFRWaF7x-xZR^v%}+Tq+V+_G^l3tgjXcb(R6UWt^CgsN>k$A|hl -zL`aWlcd#DjVD7RCUTyTgP84|_L8llNs;E5kuE5nNY7GilW5-#&aIe95zhImWlv~aq -zi;d`ri{Nmk8UGp)(!k=qTeR%sS61TO5ZqOCip=#3xJ~nsV)JLb_4$*6LXr};(~MsV -z_kYrh{nJL -zQ9uC*T`Y8c`iyDQul~&LU&tAOgXq=@_z~p~lG~{H4kS9)#g2c(`MK^K{h>tH6n#s| -z{q3TF^7Kk*!*7%EkH?F|h&xh903*bwgEwfD$0&h(`9`J0vihik7o=-Rye~&2Nm_rb -zGWW6UtK-2d`1?Myr*2*cS@QnP=z+qiFqjtm1gMXQI4?YuG~D};bogmDiMvEc8iwCD -zcE`_wg|!1O?&Qjr4Q+mu@O@!){(#Dl*w@?cjSV!0T9ej8*O%Ug&zx|>TaS+ac%|M^ -z_1gVe32jggo7Fo1UNFIjeGQTaWTWSaC@Pzdo7ElPcGt6k6vxf3Mpr0-r1g<_c=``T -zl<@aGW-d?zk6{L1xfMy)ZcD#OBw&L9XIw`PxBCr4PUA_bd#RX+a7UaoW-N3P<`=A^ -za?|n^fb5!x2$x6! -zgB+EsP7zrYKQCtX*63DO|jxVOm;kv}0kVH|PzZBl(lF*=hPEMbh1=!fpgA`TY4_K8S8@ -zNldo!UE6gz`hO$yS$sj`9%qLt+VoK%vg7V@&je_$G+OU1A@;}X==6l9$8nsk8sp%} -zqd56_KH=+|lc)6$bJ^wX^5w0!FW;d@N-E(LzwuG0?_jQ?j}VqtBuY;D>8ZN?b5Kqv -z#Ge5te%sR(c05DjzLCYcI%ZUV|$IqS#borr1;l2Ip#y`=^|nFHA((+ -zWIsUKTnGtm!nb@BxNzPLCKsa>!Y7z*n9}fM_ibigVPgk -zv`qg4!p$Z9;v?4oXt@VuL$9r1!JSizHWuZXNEt-mL4Go+&Nh1LEsghIWZQp%gX|wA -zD|^flP*Tvh=_T{&T({>$iM&}^LD-BjFM>)fL -zhaLXIa9CV{Y4j~U{Ig%05QlMs)9*0Vw<*yj@qhz4;?J?6OyS}eL~7A`yfs>sGRN!P -z0TATG=GyWvM(~p19HDd2@}fox=AWDL_WT8t(N4s$HFR;ZTZn07SnnxYZC;9`Dj@`R2{=*~_OKGf- -zbx`!(pDFoeGX%(TQTmWTX8TA|MIi(fXHZ}o-D;Vc0(8s;-!f5QocZ-mnM(j>$btfv -z7xys#9nZ0>Us!fiZbisCD(9M4#4p|j;YE9g^9ay5YpgVI+BnKB$igMBhnogLSF*8m -zu{i{P^oz$vs+RZbqx-`eJCE#N(Fcq;IL11Ox4pOipVVucRUU+(3_allT@^VawplU$ -z+%yBO)+U9oOc6%(!t~STzPycH*OD2j%8Eoi3oGvR1tMsfCRg4Ai-&jOPx$`1Bf5eO -zoImE{uQQOp{xw4h -z?)&+HaS(KMK(ME2_JqhjT)eB{NH{w+ym8cV!7;kBdE?E1B*b}r7qw6y_M3nehi?X2 -z-3>FUP-yTP|HW6E&yV;wYC!5;G@GH7qYn@SJ9VbN^&ruAj2V23g`5>)0m`CW>fKbA -ztDDdazG2N+co<`1sFL#gYnGC~`|Hr+k~M!NqSZU3GP+F%%Vlo9!*6lZbaZ;P@QI=% -z<&XvfRh!)-5)S|s|{ZT`{h%8IKh>S;}$gGhuCsaJ{tqvW%)ToG{J6b}*n1f-? -z4k~->TgUx37hr#F^nCgyZ`qEZagNH&OW?O^)l -z)d!p?WN2e&+#S!K?DrVH;`zK?4HI8Yo<%j*8@{_T`ik1)MyI=IBw}%{jIkhu6Cgu> -zGY47F)d*7>uwI>>B|pvew=h>chV*gM{$jG(z`k -zsht_y5D$S`=q_znM0M**-OU&O8GSUuBIrJHxd)a1^*OzLg&LfsToBz_DEmS-;0Nf6 -zFP1J=;g{veDJ%vm{P6h>GSr%~&XC_p1l6Fq`ZjeaWR57LznY-i`|udUIC~Pdty9l< -zz37@l@cj%2sn}a)8%1>x3c_{-1ZDP?xoorIE{p`b&`@VY%GNnE9ogUpHdw0mg(M}+ -z^T7p(bAL^&t!m#YQex08ShTYeH~Jat&@5>OX^)i7clh0j)^03@)BUhhdwa4;W68#=3#j)e>&syX0$LRJ#L<-0+V4t)$HE^9j3g0VnJT5 -z^2v+oSbYxC!9}Lx-Pl~JVq)K1yN%emhKu(HpQpRH3&2G@=RK!MFU%>$)yQzUZV4#I -z>-QRd0kDt=Hv-LI8N+Fl8HeL2$)*5MlM_H76G1ywAJ8GH8b0mt@PV(7p4j4RC~0`} -zK(Nm*e|^_zXmXd;e$sQ|rVR#+(xn{mp4z}XT2KIEP|XA>2J{~B$1^uXLpcK^-!8t# -zo|!;zdmUp8`@l1dY{t# -zxd&o;lBVFG&N!z>j2&bg;A%G-$@1^LnmvPi`EL~ZuZ}H#4424C -zYO6g+UOZL!+44wV>$u6T4JuA8J;~h|Pb==YT_|)`WKWK*fG4f=CVAe7GB>F)1{1Yt -z=q!7@s>BWj^vP~`gG$id?tJU;q1uf{I<0SF`3J0}A_hVmR!nw%w7Tw`v&~W4XJSuK -z^0D2-yHRXWqIc6r%X<4J?+gB?GaMJGUD-jBQFg%T=S$2BA1#{tGo>9P5U-mQ9%lQ{ -znbK-wwnn5QC_8E09bq-hwuvvJ#qWj0G>DP>c6QlmrH$JWx2E_-|* -zYb$F2>VWc^u1DX^OH_-SBi8AK=|?|CX>BYMBU7AGQe8jtqaZyC>x3ty$vf5@lx;5dWm{H&|wJn&48dDTRxwibzqh3Z<}MBHx50NlaKXV_To6+%by11T)zWnbZ(_ -zzeU8B>|^;EhIN7%&>1Wjs?)i7VjJTgH~lJVnZ%@z1k!P*#nNm{36IaB0FAqxUb!-+ -zXO^Fz-JHUSv@ruL5!AdKU?zJE3UkKlT55P|huJIl0ivm(fQ|`O#oJqT=qK3vz5 -zd`+301Xr|X<@V~|kzvEfto=2qgJI)EWyyybe-`ZB&cI;QQT1d4vs(T_FR!*2KmZ68 -zrcG~57sS7MWs6lUHl6loz1}{=G-01!iH0bLbb4V>fu~(bPGeNF_OUz8GRBk@=c*Cz -zt%;a-XKksld2IF3u9i3O^H*o`!TYZ0lfChz -z&7;!7hoz+E?1v~lln=JuAJ}`{q`;5hrdVr#D|ka+KjkWC$hz*AYrT(-O5&z)KM@}n -zs4RKyhg8q)yAm#vB|jJ5gpk -z=%}i(V+RnH1qqJ`Zs*MNAG-XW~^slxGiqw|4tm2os-g5$tvqW79Io6)2vR6`DPoJn#UgqW>_=PskOOyTWJ~|rtyx| -zxr_KsYwV$(N$kuaOvz;0Y63c9)#YFETF7xJHb%E!96fO}U)sksBEvGr$bA!7$G_v? -zMpOhKGd3n39hA*D8#^c2_xN7gd(P(2sPmJXP(0VqYnr`u;8Sfo;Ev#nU9gE57X64z -zh!Hr%4wRrTR?02@Q48>9-JMO(>wUiJRBH_T`HgQLR^M9l8FkZ-ml5nc%=u)j?3A$< -z@TyPm1&Y^OwDfBkwgBGK*%ErRT`~3^wY?A9!%TS7;GVo1u$waPho6!Z%L6ifT9w6-)P)+s`~ah+KKH -zu~aB#fcv2~OS7A@C+cPJ&He7jmb3dDnYfe_pDV3j(&hLgZnsQBls(JE`0CdavU^U;s* -zW(v^k`kIHVYvw60mmT`__(N%{dMmvxJSs*M1HY6d9Q?J(=#BQv5*r%8ozwFj@5zvg -z9P+|X*?vR%jZ0D7UD)zqAQysVJj8nx70LnsBg0X!7R$!cx+|b&2NEp?+z@)R!6L0q -z>@M%bUqD_1|Lht3Ak5E|P@mO1@`NZJ@Q)>%DV@JRZjJ6jwh*#v;O11bMXbhQXdg -zmVt36tk9L)RfgQDbXq;}x2|hBX}|Zw58iMU9!n{Cz+Jz7LsyCI6EZP6`SO0asthK9oQZ -z@93{MX%|QfIn^7fbsv9`|3}6o!e*L8HhK80tfWzV=Dq}5xI2bRy}1yF$Ea*et?-Ms -z;PCQJ76XsEZK@wlezX|&VGq)W=v_XR+83WmD*Fy4v{UW7moS0`%y)IlU%!4=GEJR% -zLCc1IeIjvX6vG_QFt&l&KA@iAXvGN!44X-O6#UkG>%ucwpZCo(nteZ8{{dTG5}xx= -zkwdt~k(?KYk*;pEga-*&zQ^|Y91p@`P0j^#FjBkdw#>q-;$t+EhVnEr_V7-Fl+U!mVU5c(=8+Lgbr%XSsXgD^8 -zsvkf9MpaVp1yTHgUt96f#To?P888z$40W)GYXLeEQ=B4H8F>l$!!RRI#6T|%7NWOo -z7YM5GA_tc|Rl+MX_==x)y31J(`p>L!o171xYvJc0g`BVRwL!f$>)0wLVwD-drj>Ht%t%d9Z4<_*t{tpY4aaQNlqaJx6THA2ou80Y9v+PCUP$om-v -z4$_$x2}-Tg5p*4e@1i*TN^-c}YNp^Hr;}W)HQ{v|bz*Ze5{?AnfZ!D&29G_#~OAEd1gWT~9{r -zsvT$D_dxp>6k6r01%m)c?$WzR=CKD{EU8c6FSc7o;j#?-&R?ICUU|LYU|z-9$45!1 -zt1BTep7cB{;!4F3?Xx{$@*u)(nekV_G7EmJ%swASF8~nfu=s-(Io?AK@OKkZ$^;<` -zKUQpXX>6r2QVeK$P!a5j*#toe9D^RNRLGE?SwS1vLCDI?>OB97FrhQh2jz5cBl=M) -z|NMu_Vkcl3yO>%h$<;t`&C`mLy;N*K`v+L=$1U|gpUEc5wR^1WLe5bP4nTTr5V=o8 -zi>67sd*Qy1i1i;hY|#Su;i-arPlEvP1 -z^O8)PYS#D&*xcpy+!oCE1n;Ev^VA%%I1PV#&@dH$Rs1(Y?|@ES@mYG4jG_1$J4~DT -zM51E6&dVC@@fSj~VB5r`vnWdMKtga4!wE`>6HpEYbW5Y~XvkqEt)Pu=I1DBS{r -zGkJ~A=R$ta?i0&w|9H*l=?^1X^z*|wQt_cURL(IZ=msS2AO_)@4(G?8pr=vn;nF1S -zcfa;*YGzIlD;?)h^2J_=QalBvOE@|bDaFuEy8L0|QOk9-NT{C1NdMl367R4Vy~Jd& -z38CdXL!}&3Un0bSDJ_3IJ~M{7)|9C6{N~QFd_Rs)-krFMuJsC2=xg*~KWlcvmsfG@ -zhm$oYWJCOMkpA2p?O1_{82dX1Q9*b{#cP_1#xc7QA@}X8IEPOKvwF4TL$?3UL7&TV -z{t3JHkzRCuJ@Y>URFV8@9)oJub@RVk!Yb2PLwx_X;)t+!#F-T6%fDb}s(5QM@Qjr1 -zfnW=}ofz8nL1*9>k;}#v0qkg^|IuIVuVB~03Xc7=If89hxKY>xwIa{=Jh*&$!dK~c -z=#29zZF-ify;W4I5?^0Tog7U@B>nn*t9iKGO6`X)7r-cY-L80uwp7D7{Bz(?>L@%S -z!>QXrwACmqGOR&z1M>sFugT_yZOP%XNHq4rM{9?gs~_1sP7W3A>>W%l-}3@xrYVlZTfrbhl?mAv5W!M~$T< -zR}c9R3FD#BW#`+cwBB~zwx>c$1Ie?7-F3`W{jaSutTUzK@|DCFidP}q9Cv;iKw>8) -z%%Qx~Kk<^y|8KLmm5J5=a(jcT0=o`cQ&#(4-f7KDjokvpBwznOEZR~zmeDvS$-0f`r~F0Vmqrnx11lT0KOE?z2zZ=JpX1?$`n=bmyG -zc`fceX1Ko%^Yp@T1#GC`#Pj+Km^d}AHuU;L5IPLGl|So73|8Gtl02?)hx$!<$KTFtdx|aM0|~bCC>RO -z)j|I0$ZTE)%^lSfuO9QrL!Ope$5yZ)!3EDu{>ra_8}xeDX%~8ttq2j@PWQwl|+ -zQ+>vbYI9`il5ns4=jm7b25dNZt-5iTRK8jNE+G%iySQ2yXgN!lmDvg^IT&uU?|Xhj -zGD=e_RU9#;qz{Qij<-sAJ~#7Qe>uyru%&jE(qftPTz2>X=+Avw#|$l}S{f{<_i(5C -zkWlK;$n~-?PuASxOb%%EuW|Ba=fD1iiG?9Iwu}VA{%`L{dILfU)Cf%?&0UWB_)6b) -z?`^UL6(ngZH1VWK$k({+K$O*45gyg~Za;vt_T$B@M~dk)Wjsr&isN1oABXTO9b9jY@WV%-NtpQ)sVyK&1}78j4m(~)K6>8Lc+78UN#imKFvqm3E6ZI=df29*|H(_v)XENxp -zD2Ch_U|hkpU4zw0YJ;Q1z)~-$1u@I1UA)>pIktIu)s7bGDcA~@QOA)ePLY;l#j+Gj -zez=p#n3b&=7{gO$DVU(BYJ3KG5}iv{UZG29?QU~v8gGfcWSw?>+fed*?0{ZeM?1&xBG;3()ZtWd;#aT4 -zD#+D~WyX7U;*j`VWUqbIm<<##MAe2#)TlVc-FLcKQBHgDain0!&@$1>Si?1+A&fuk -zNA(=G!!G;2uozC`Xdad=em~IY3rKf#WFlvvgK}x`o1`Y<7n}EG@0*KM(;->OB29w5 -z^GlKRSbJNUDW@?-VYL+Xqo$M71sDAZr^&sN+b3ea{7UKy>J^?pMJ#<-|-%CJdQzx6%QxxYWf0^O3xArMZH*D|*H*M_p4AEBPPM3cHhskK_C9 -zvh)A$G%iC3k0FGApji<&Uy<2@o)!mWOE4paxS!akz{aod>plz5jP-urO|emQ43=k3 -z;Pb|KEhr8eyQG(pk&wW*5UT!3t=L~|Y -zOu}ey9p`>iyws90SDJi!s~bcNJj|%!4|6;CQ>1BC8aupSv-jTLv^4YrN62BJadh4& -zfvz<(;nr8-3xVw6|60!n>M)@>zsCOCty^iQkzM&X1lyIUbfU?3 -zd802jGoh;~BxJ_rb_5vHTxUI3=>H|(`LTjM6Q_pu+n*M>T(M7b9=YKoW{cP~a_K}? -z6U?>w#hQ2M&&1w@)*k}MuiEu_R(5kB7Qus?7^2@8BEZR3NnRzfPgjD=PCqA+ILEK% -zVHQp_)8+hd#m>tj5oCqG#-Ssp_#N~@)hwqo^tvx~C46TG2D=Vc%2cgj=6h|6AKw+Y509kz`#ZHQmW`_$1zSj@ZeB -z$EqjL<-y<-y#;+)*U2=xmOixm>zklXr!f)j4|(HrV674F4i_4X+$qQq4t+sNC{MU8 -ze@sCHaKrH9H`bNj?Jg)$M4Pj=ajSHU(@_g!%fC+h_JU3#=pEo{M@2yeg7BpmrcbeG -ze*p@e66*;3O_3JT8F@d~2`!PEC}$y@sNJUZVwI_$abg -z7``)XM(E}xc)@gg>x64K6pUn$y5qyv9|~+K1!ArFnS)1=o-$z|zcoIL77^fvdSX(? -zis*r*CiNheDd{l;hC%C2)IGcP7I-!xZrlYBBF@d4*dKhS#lqq!Kyj*HUzE -zjd>c_u$)GEvF-ox48x4PbNx -zm>h!@iC(e?n(zbt3v{GoW!pAnE>Y%UjI$!rd)IZh&-&i422M^A;t#6 -zpqh;B2g)l{HFF>snPhxK3{M>}J9lfcwP96MUJ+$wZg}{f4eApm?*0zMTH_ch1Pi@c -zVEotZ(c%dd)Tbl~gx_c@?%$O!|7MaWW{wLb4gUZSmUv*^k%GU6o7K2f=ogdXwhRX& -zpQ~L{1ubmJ7+B*5HvD;_tvIOhpxOyoai8Cb|74(rF+uefsIpZ^_?yX^z-ekncEOD` -z&wDZN6aWzq8yjPPQ&s~G>S#}e$z4r9?O^hUGG(Gjb5Mx3V%iUC>EEc0fOn(ek~0Ue -zV8L;oJU{)52)x$_FbCFV)irxva|g{UybKI;X;+ii#4RT=0nTz|I#?$7r064!F-zTMOfkCl?HF5!xrj-fiZxlv5A? -zFc?hF>#=7$i6jXFWoVG`bA3(fz)@A~`uUt%heC?JkG>p_k(|2v8$LAHP&ZlN7!pmX -z?jDn$orguNuO3n+RACz=8|ui!iE74SU}YW?Kfr>|beYj_g}|&a*f|}a(CrG^xRRi> -z9eR`;F|79%*i||t9s^2u2JCwPEtf -z*qiX%J!cPO(bWP@><=MAQH}8P)N5X4dEmJxe&Upn^Y^=ELIJAFipncKta*RkV|3o( -zpXqIV7D8LA5C9&|dn%Ym@6(6&So?L$T1GSdyyf7?+o7Y=VPQZ5x=VmqYh0y8u=n?s -zC8AUWVVc9m40tiHqz)q0zSef3c~BoVabAiCmP-26A7~xRKhE3 -zPG1z%;n%)bJBGk~XxTBKU3%|;`H-n1_-L1&_YOzGuA~wk@(UjOPod}ZK|WPts8v4u -z(A5-K?e$oa{$Q}4Lnl)}!@}}&l2(ZBkG$6xS%dO^ePOgU{#2L%OX#wenm-iKmDz+& -z)x?R7<<}LAY-?_{Q9UKXIc*Ci4d<->imwmi;(sf6U#lAfg%^K{DPv&|Y@PZgfAm{I -z=izcqrfrH80~(b^3W=9G)0r@#mq+6bR((`fUQuIZzK!Ax0`;j8=LLk4h7%Yogq*AI -zokiH(+Gd6|hpNh{D4RaIYWE$GXV#m;9`>EwrezjBu`(BRXdw8gnV%*$??h8N+5G?Y?>i6vyV#k*q`sYvZICQ0t5twEYF|d2Q63a!c9vLAaFg -z7U01xz7mR0e#KxGm&Xf|UQtu5SuG#SO`cPSjU{T3orT+;qm$W?jq -zhROb~rMBWeL3Z(NS*}R*n!13z=4t}DM=+je!kG5t&a+h+WfZW1Gm2pWcfM`!)coyq -zAy2nLV7*ZZyfQJuhRmy-kR{1r$5YtmU2&!|Cf0Y1gRQC=@K+D5Woc=I}F!M?*vxX&g%&IEpUVbQmz-H&2gE6JvjO=6QqSj1)R{0Le33owZf4$5((yZyzAQKQMYXb&*7>%!l|}P@ -ziKzB5Bmtim479)8cCqaxkb2{zGds%Xll(+#VJa3{V;8!p&MQDu>`?RWLY~)|bn}&k -zjA4GJOH88Q`mCTw48`?{RMAh#LgBeOPHQ$>pD((v-btR#?D|=bgLjag;=2qblv6%= -zUgn~4U44T`Iq8W{f)l=+W4^ncYJTU}!6og;Wss>7Zu?b9z_!0R9)}P6`eZ9t(8!YN -zfLDwsaR9Km61!J5D?yo1qK!rv1FHC)?z= -zM;^g?UD?2fugzBEHM{SW1&jYWrFe0U0C@0d|1bxry<$uFL$PtBA)cm_$VefIJLBhq -zAC&sN48ws*@cOP)JHNd>DG5Q1pP*6wl*R`-Of;#@0)*_%86KOLWd{u)OIe4spVcZSbouCgmqs( -z0$jqhwKT94(RbW`kw1vPL-zzr{ls_Qn{Udk3P(eFI76=E1ElAQh;Pq${Gukm{f+#& -zQ@d~M<&gEV&WpHBxbr9mF`O;D6<;a2AJJ)?{^_Bow}@)z3uDFf2goy8smCqjrZ|hM -z*3!!Ts--`6hX -zKl_ThU(0F#C0NcgM(D-+6W;mey|Ezqvyr_ooZijcAJq{4Xad8UkN=b=)qI3W#kj}0 -zobYQ|<37{;rxYmQ(69ZZUx9M})6>!05xUOEa;1>}@7s-3Q-3~Yb~@jNeUAA3OJ_ZM -zl?9*Vv6Tg1e-P(PQG_VRry5WlkI~-k-)~!zxwBU2qzVKx`XL{5Sao0f>#;!ws+(% -z4xS8WMX7l_!+52A(dKxXb)_xrU@7llK5X>Mrqz5s}bXM046w+vG5Tk}fq(Kcb? -zj*tcU{1eVtZGPoXiUWfpyf+hTTY6XfzX60u0M|E8`$|6P?n%PqWMSg-*0%^|IGXg* -zga+>k9gdeeuF~ubuV4WF;ew6L2i1guc`1yU7^J1e5|F!_jjLQr~=FW@2}?ipSL9%H&No3+uSI7 -z_dnVq;&@U5bzcT7-{XfQTz{xZ?v<{E#+4@Hd_T9hZGw&_1HxLM8U!`GAx?s%)on4A -zNiq*3H6INxKS7V5U7M{lxKHQy9L4F1qfNWp?HCIdgPb4#0*Q~$yeGSBFOtPzkM2Ba -z_bf|^>$Y`lIB?x5{f;d#bZ-7Ib$;AV>dPaSB$nJ4MmaC*&u8e+>_iR1o95Nsj@~g` -zOr)60L!zXV7U_+&V*Kogo`Ld1DWhmB_7=9ZBj>j6^K1)v=IclAHznMYBa2kLT0C6> -zlSWyw8qJmWEos5HkbOGs2rGyrc8X%C2;|K}@(mN55-h@!3gs4a_ -zks1;p5ikToAP`7G2uaRD=l!3rXRY($taX;ZPb^lR{p@{T_ul({uAMy1w|+@JFB0$d -zH()qm^lV%!)%wcj@9aOerS-xq0DT&t9yVV={2q6*_P+eHvX5g1)424ipU$oR5mXci -zzVYAH-!JU3^Fg<^&ErHn57s$1J|_-zthsKeX5EvK)l$56L+cs^FqhU-YkNWm{J-CzJH-SYF4xd`+7gZY&K(ouM~&J4Pu`Z4h@ynOF+Ee>s-=GX|GZd@ -zY9#UE|Iv!0ByXib+saH%+yb -z4{rJO=R0WDv4y@}JMA -zeti&bR>lcvmf4;ARqW9bAR5zWyEJDK@n81W6C7Li=nLy=Qh -z!6ato>dr1o$X$V7$|1=xF87P21ejMQFMXhy{?;BM^eHQIwc_1Z5}nyIdZB>-JSHy< -zEwbkhPHqIWzmH4Gp${`CoG0f69?fCOv1bk{&41~>v9;{~x5w-U|CN9t&cd6xX+?!S -z#h{lNqo#h_7j?nqvTo0HM;?zc-=Tk9z7+AaXFY!QV`wGss02_nj`0+*9`EsGy^jZH -z-Jo%=dqulY2ee~zIPuM8T!q~!^t|s@*?_S$~2870izIIyNJYUf+ddUs=$$O-1zjLh6No-vJI3wJT8swAD -z2cc4Ri9KCp4FaJHW*V`tUmGai>l;X;%lG|^J}1-wcr=G8-G}dCJUXinFv~-HosMy$ -zSzo8`Lta`n9kYF7YhP@IO1FF@tX!~t+vbrii71$C!iM|I@tRp7TQ=nB@_n8$^=3KxQ;R6cmV}rT -z?zbtX%D?VHduE~PrTNFFx@ -z;{T`qAbt7Sy@(4z)9Mw0)|v2R$dv|!>dz*%fmeEc(N#m))pYbd(f+D~^jYTdDjow~ -zhpUw4A8)5yCSz~oyt+EBx}&P4`Il%~7C_&greWX<-I2%98C&Aj|GS%9*K-OHr_Fb- -zrlX(B@V`cCXDk@hE~wOQzLDl9PIb*`a^L8V$@8y8oakxS?C6%}_P_fOEX}{hJTplQ -z7%|fQK01NdRQd9*;kYTea%q0zbeBLR*UmJ8E!jAF!GfC8A@YBsc_9(Uh3?NN*|Ob7 -zGT|XHmxkn*>$J+vz_x61WJ>71alBOLLAt|2#Tn3ER-LXbiEjhGR6)0VGzT|fWVg>! -zpHv^fhYqhiH6*{>^3Q$E^26~NTL9Pky|Uq_pgD^#y8zR-ZFvh{G&13*oFk7-2XP;U -z7E~W7EDixRyMOb793$!SsiB#$Ee}FX0c_&*p$ZWvdUD&}N8bJ4b;D~uBu-m!4!>1@B|4XlcMbdrvqmNkq`y{xgJ#R4hA>F8r -zlmUSmDu(kx?RjmtDiALR4>cF-dEB>g-ur$gTwTM0g!okSXrJavi@a^i)8sy`m4s)w -z-HuAkMwI!X-={<|x?oV!;XKG!E(rN~T=4%^PNtHV%w?ggrTH?4-6URx7kG3blQJ4Tv*%sY -z`d2-B0dNKw4&A>yu=`KLtt)Lu65V?)+iSdX -zJ^X&dd&qV%n#O3;1nv?XWcN*>LN7sg*I2;-VPB*UIC9Z&8HfHtQ -z{rc>^*^^UyU-*p>z~hMf;ru=IW5y4TslJwaUi|CrQ+FfM%}+;N{{7c~2zTzy2dMr2 -z>#;YVdoN!#Hwd^~dATyos#-^?ar~Ezs|HS$S6vOnfBA*Sf`V>nLLwv`e~;1S6L(-} -zH{%G4FNUxQ6%5(|0#t&GP8Aen&IFu3^=*b6Pg6tO%t=l!$qHPdILqDSHIlBYjnbe(p -zVO}i$Zbn7Yyp^I+2|*1wszo1))po_drOC8xd$&sj|895xz=V+6ub|0#>MP-XQAri6E3pfFFJUS7z8+w|aL9sze*W2EIc-bl&x>N-`P}dqJ}| -z=oOU5u)4F|79I!64NV$~AAT@DIBF)foy$>+vCOmb^DxPth8U_Dl`MHh85I%19Onr` -zc^TCS$MMukmI)yhzRAOrd_@~F@Oz+auQ$x3ib{>mgjxx{*4KQ{o1{BY_<@?kknYqE -zXwe57EZ)h0J>06223=PMx^dfg?;n5(sclDT+xPJUL8eJz_rtDHQjLvVRS%;t -z(%JAL^qxWQM*WBuy)?VLy08B6t*01lPgODz-NPz$aE$u$WpW&g6pa__O#mc$I30-A4TA$_6@c -z+{da&?IOHrKs3p=(|vM+BL*dCF0?K@J)Uc>+x@%vlUO~XV(IFZ^a6^ybG$(ZQ|bEB -z)uE-+zsYgBhkOR>nK&eq(f8XK<%j7t$dgyJTY1dnp9dvH5Qd7#lCcVSR?_(D!Q!Zq -ziX@|?OUH0Iv85@h#p`Qaf4#0^pAYr^#nN#}+GG*ht(qtL*T+^=wu+(0N^R^M$V|IL -z4}`D4!u~s2u#y|vFW;pyH&0LmQ(u1w#e+8HG%I4q3LNum3%g=ITNw%FO=xy{%rrk; -zVkow+;=|0sr-p?_6kx(y)lv7RW@}45R^~5+-Wa87JotkNwvzZ3W|cQPJer%nR|Df^kish#3YR -zK5gS?PoJx()eXD{&cTf63kW7xU1`zUKx#2Xl`2~+KlN@49_@dde{=MycR&+!_vVH` -z(n92N5^`pS@L>L^YXdH*@iBXLbK&BP34GI=R4LMNejV6GJHD-(dz?S`J`HcXhnvQJ -z0gdQB&TdZ!jpZqU4eN+4US4~|XeFUHWzm=J4x<(S{o_>slaT`Fg)eU@N8_){e4KMj -zs@2qW3e9?F*JXM<7F*UHzkd5*rde?LGYy0*3L6CM&xUPn8jtw2 -z*GKH$&!62QsWNX~OyVcfo5yG05%bieL))Me24L2M8>-WUV8&{G08KMAurb@YqjFz- -zLveXj9PZlM-vyhAhbvzub~1*@(TX-DWA -zJXaHhLvYtrL)hhP#I^dAtI;JheM2p%O)@`h(%e9l(UZrH6~(Ut?B(eqL`M$9PA_te -zC@M9b7UntO`Ye9jf~gzWi}#bIpMGLN(l*hoW7x -zV+v8vH|F3`zU$qyM~9XJhm9@;5_1!$ib*qNkCSt30;AR(@6)jAw~4@mU&(eCPu -zg^H`%6x1sak&!=$DaR>fGi3~RMB}N*s_7URp*A= -zH3}Lbvit>V3%!k^db|qV7C=U*!4{xV-!?X-HA)uj5mJ>zo968|bR`8Z@aXeJ^#bMw -zJHVk%{!+U;&-Nm>)Oy$P>_SSk|H4$;+NuV!i}k6Y9DFAV->2DvZXKB0i=5%MwV)~c -zLRX7-%Bf-pjDLFY6T4&9`|W3Gmnph18|EUh3s(dw2f#8a05G$PY&?szqCL@pGXEA+ -zFhv5Sy!v;q1lySFaTkds8s`<$y#i-dT)Ufy5xXD0g;5dZwm}TvSySGj -zqBdRFIVzkHYv%r8YxO#uq@5WW!kcJ2l)UD?0t#EtmJJ+i%3c63QNCS^K8&sQe3}<= -zo2%z;jx5y~Oq99no_8UsW0F1U5%c6XUi&ff0Y@jfh!a -zQm_}nS<%#^nC%tleUm(HzIB9I(0$IsyG0B9R#_;zUno-LFjmmz1Zrj58rYF39vT7F -z`yM{`=l&tR(fJ?9Wvd~{(534%kgJYQyF8TIsGL;GzYT)$qZ -ze~+HZ&?GfS+=cTH6(gqog((Y7Ldjn!@HUFdL*4GxI>#6rMcPAmMjL&Z?Pb)QWB_5L -z0x^WdxP|hBe3>?7RJTL(2+^+(MG9Aw?*Rk$k{x5yE9C -zc@4C5)m70`22-RFG%=;Z5iX;GWSUCd_&{%5PyA+t)xSBnJ%LHI5`m92Ve%m4b>D~# -zh0VWNLxbxnqey#=@J?S}X5(QJx7e$_ktz=wL1I^t+s3}kq%!Kl;Z0d~MX{`Z^4;zt -ziPB#EyA$S#_)BmItaf&n2sAyMC~oCTu|_Bf+E|nDW*h0#_gvB|W%jJGIYkJNB_fy* -z>&rZ_X6BxyX;V;XAQln+HTPTEdj#@`KGBwxd -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 -zvYgYXT9!=)QSu$s -zC}$<~YrnqUtJaewUr}L5l$$&6@^a-~Z?~h7U3WzO=!9XngP-T^-b*i{+rEmiv9r?% -z*=0M7!sTC3n^Fh?Ud_&&vS!muPJ_{c$G@*R{b$4d;?&f0W0o||nUrp@Ht -z#@Wc1F0Dlwt+7s-YeQs9s+g4CYL~?>Z1EZxByr(xg -zX;{)FdE9?09}ir=J6DbZSj^=(`7Qgq7KP*j@tV?ZIgqa%vB~=e_5s2uAS(dO2rFx -zS5>|vDLEQhw39}?E(%4NB-J`K!c(FpNn-6=`Tj*&t-;n+NzjhkZuS$y`v`sdNS&0#A}>*W~zRPucF{vccDlSn3w=n0g18cdPjnSG?sif46f{e9k%FLBC5FX93W$J=+|KvRC2KS{E6uE^69$ -zqP*7?-7ST!N_507p6;=o7;l%9&-Vf{2R_&zK8^|{Io4m*rf{V(;@dMH6u$rK#qG=7 -zwBhry0-m_#>~4P7VIlmpq^;4KRZuz}u_vzbn)rAAgqqsTmT@m1Gt2G~)w6P9>8#zY -z+dCIq9s4t^v#M5or=Wg+sAZp<-D4dhC}09DHm`^mg4)ix -z8`*)KS~`Q?n=hPmvsdYS&6JFLwW~>``}%(U+xqJe>B=?SALW&;J9Nhe0rY-1u)_RK -z6#mnDNCkGBs-BIpUknZObx7)VOgQk&ekktPR!W$V+4WC2jX=O-mTvlrS{1c6+F$y( -z0zM&k)T4I3IRu+t>1tXpbFtt)=d`|F93YI$>c8>Osz`|ad^i`Cb_D=tc#N}K3h#DN -z@|-p_G`U|3O#8vFP^dsl3xx&l;98uGo_Vk4=Qh8j)@gb}jBoyOg5kRQ`<0!Ce>635 -zW#Br~{9XCDn1k1It -z{N()P==tYGROOE3Ck_puL1RdV8>9|!evCGMR7Af0)BnCO -z_9u#;hgQcXxs!ZA -z;VNC45?acx({oz0ru$rM#J!LtutVd8^-a~Mal%80^Ic#4AJlpH3C6ZYnHYtkyMLc{ -zqH6do9$S|`Zf^ueI)yX3)(bB1`7BN3+qIS3YXpybkj{)YMG+C#&>Tf*V625%ev`4V -z_Z^7vX@n~@kv$V(&7o?}dCie;(x|TL!hSJCi6-1^H|1O -zy3{ahmiMlfn-v@iY6eW`funV2v+Z{`?ANi) -zF5vC?mBby(^ZAATn-K;n*mE+`2V?4p-X&n-@g-P1Yp)RHkN5zBdL17-S>ttl?5P4^ -zYN9~l1d2}IALM#|(BwVk=84yy-HgDuSzgHJUfl>3DOhSTXZY*2Jc(F)SIO7aFJBtB -z+F1Jo-KU1H>HjIYHdD6Me`DI?r#Yy~(OXd}@bKZDYUg^_qv8a$+E_|ul|)?YjMjpk -zXrxw%3HZ(AR`N-GBl8QYUPG(nHb%`!K1rDEzwv!v=)&GaBl-N!Ke_%6&|X&R$|gFc -z8N${(Wn@-SJKo?MpyLAjb4NYVaJ?rB>vN#j6fjxRQ;a>Q=fe9KI0qAknVTvhMa169 -z=Rq@fHW$Pg*6x)F?K__?;uP09db&H=f5q6=5W^ffISK9O!)IKSony6uk&At!#we)< -zgqnpN@tD82KnCPse{CNbAZh*+U>**_q5~b|S>E3NtUfc -zGAeq2Ln&aV>rvdcnXx8e$I}0K;TDLqFnAF+SJ~}6!kg$m#Jgt@G36XpDBHP~(&m!; -zz4lp?Sd4I&9OfZT+q=jeK4wC56R4G}OdTjoCRSTmtmiL+m -zH%!ept;g#sS=?}>BYhj&Jt_IW8m-?;Hy4CJZA0K$-ayBpBD?M2J1F7UYs1}(e&D{sW1@$t?C6}x@#REJZmZ^tvpi)BS8qNQ9tjZmZ+3=$s8PxXz+P}kvK -zM#y*9QJY~|x_f_B@bV6Ow}3vh?@sSf^)2{jJuA#Z@1uW`-8x8Qfuor7$B?bY$RHW7 -zAp7m^b;eN;E}!o~qLt&U2wMkF@w=hyU(@zCm`{;ZPEq7u>Nj(W{LR(6f$83Q7TWg) -z*MC@)x{ftqkeGLiDa57@mzWo%&Q2669;h3@?yPia{fB> -zvWqZCvdjKx;slj^=y_Y_E+}HeyB}tuXhj(Ct3$^KW*MF;#wZ8pc)15p$BLGJKZ

R5;4?6MIYPr1KZY;k+3;m2-h8RX@THy&U!bmq +zFHoo93)HpnrJjZ_@KrHQweV#) +z8@|BvM)+ccFS!X{K7#P&0X2MCpbKB{<_pv>4PV}%;R}2QhA&W8!NI?T=e6(!>RR}syZHijBYZK!m)wLeKZNk*8Z~@*kquvdi{T5@ +zF9~0cV)z1|LBp4iFnoc!7QP&3!{jnW_t4@aD_o7{2Uf!xyM);S1Dh_yTn;eA!FG7x=0ezChgwUySf2H{r`Y +z5WWa%_#)HrB{O4f^75g>2lUx=@7up!uiH}bZr7A_op8e_C2zv93*jyPP>DzQ$>S%8 +zX?)zYSYcoCKl<2(@JwH5rdRkF&hz4?xeB}two+Bm5dVr^HRml$J5aE`*=(h2Wi+yy>>7-;$Qysg@nm +zzx~A0H)tu2)eK38^ZX%rhaVr9)a}l%bTt)OXGKY1d|dZ(f91fYj6FYUYpSxWIZqC3 +zNnLycxuCR@n*Pa}aa?N&5#tWAkPlqj?QSh~!7hv{OX+#CZfk1Y9%-M4Sndc~7R6ep +zro*c}A$YexA24^jn~Pn|<6@FIZCITQl}oqqe)NMXqUO)*TU&m><9R_Hk*im&lI?<)JZd +zY&v|aH>7*Nk}#~DaAT6(P|jLGM3X~=*Y_#X-i&=|#J03ro_C%|4JoNk>hKYHdGO-v +z$hhTYM67g($N0q1ZujzX*YZ;9=_pAIj9+}cl4SD}c}h^eJJvZe9X{(1!Q1=z#JFzv +z#tPTQVyit$5>w)dWlHzvjD1Da25%#abq-F4Grmy9EA)B%Br)B4&pWc4H&xy9Ey>%H +z%G)BrJ7eJB`nYL;k~dkt5H9hCO8f%*N-{W~88?kp>Zi&V!ah&P=Mx;fX~R9=lKRc5 +z`d!lfN6bY0!XaMIn;wPYj#Pc4G}a?*h0ZZ?(*kAXSouQud0*&xukb%m92kd}#cY#q +zKV~N4Vuu*yP1bw9B`X_K@XCIl@O^k_QQS04X(^B|gx~gt-u4Sqp*SZF?^bG%{{4}e +zh<|X1&+?`f-R}G%SALmwTZ9DW$1lF9U#j;K%i}@I&{)mbba4Nu6Kw@-Z{A2oh);~TVbo^>E}s&cPhR^O8JT0Hz*g!xFPBANPh_4a>*wqb-Slk +zy7m`Y=R`?jd|bEwLXkFQ>=UE5m#XA7=ZUl>b@3hjLZY2;{gd1{uC0WKUpd5OeB#<} +zcU!3ow#8J*rRT|pt*H%rq}Mz|z9T3vigiv+hi#q^Y`@?W=5BYW*cB?b{v$#X%i|Yc +z(J$TPCGtZ-d19Kpz`2IWITn*=5tF496DU$lpi{%- +z9K{5Rh{;ll$+Ijb@Q{YdIf@As5tF3`CI%+Gj>%6xyb$g;d;UdCX3b|XdGSMv$&EMzhHm|_B*8YUmJn9M{>7P6RpOfi8@4U>;qOlBIG7?|`vCc6NW`&CTtXEA{T +z4U;djVFKqGCSS0a+>e+np_o9CVgj8SCSOoYpoo|(p_tsyVge6on0!Gofg)nE#K6SB +zr1vrT2ryZoVzPk6(|h++cghzVvUV-XWJGkN(ViV1XTn0&-yG8QpmGn1cv +zL@|L*4U>;pOvW0R7?|`vCN~2nx2u@k&SC-w8YZ!9n83M)NsPthcEkiT6DU$lpi{#n +zMlpdRVuG2;?JOqnkcLT&Vgg0P#K=qxOmcw93BW|nOlGl}$%`i_CZA-*0#UX`z@vr-n%ji^*KXM3k(n5n +z&Wg!ViV2(}CYYHNASSxZ$tl1@%}id`WhSR6CV$I{$tj8noFgWfnG_-> +zy3FJh#RNJvOir41R +znwhN8WhMtHCX=&ba*$#I=Mfp3iwPWPn0%QH +z6FAo}`I5zCEnyu3^&3Vsa;9f|&^vDJIaVVbV%5fg)mpnaQ0j +zCh(AkNh`$!iinAknHZSl0F#q|iJF|`wJtL` +zOfk73D<+32CU8zM`7357BPk}|=rWVT6cgywFgeU(GLm8f-w895!xR(f)G#^BVlvXe +z#K5HYF}VRSxmCsFRu&UD&@lNd8zykBVe%P^$*mNVuQ4-$BEk4E +zZe=lnhcrw+qnJREV)8#mW@2EH15AzsCTeE#wJtL`PBD2uD<;P&CUB0JU}kbHVxr4T +zj#EsaQ^Vvqi^;W!i7qoaPBDQ_4U^+6Cf6F6{QnV?74M{eGGI`@K1K82Wp^qhA9>`f +zo`y`Z{PVx|RW|I**c&6Z#%g)od9tBCwPCyTnxDwSg7Ph~&O9zuLBypF@jX5oG0CTQr%mm4}3&k8kC=ob@oq(pYw&D^9twq#Hem}y4;m6wf6n@%f#~G +zjp{Dc>EDvPEvdYEX^U6*<1;6SX+Yd`rIOcl>_WK2A3Ed_e#4ulDtV34OpmY=&d0`0 +z3zhokk6j4+d?BA#Xy;88)4%=iuDZW2Ama57@prt*2F1qI%1zQ(pHK#!3*x4s%F2Dm +zE`*==hMxBeZ5 +z3*oo@p(i}T&!IRmZd$6e)JgyTW&shOb%+=EK%Z`Rewi!3#JVj?0z=|~tCYFhrFuWH +z3=LXtj@9I)!z=xv7LV{YADF7lZItGEg!*<;Gc;K+n2R3Ky=BTZ? +z%Ci1EIZ&56uv=2R#IiAH=^twy&6!Jxc+?@z<^xxEyUnF8bES1&gal^A1Nq9j1}W|# +zmb-(NWwF-j>2RSZROl0K9PPaQ*;!0LnT~)H}Jc;i}#T%uO9wHY9<;!E-q;z<%C$!fmJisTe +z?{@Dma_uj(z8N8j#qq>&rEs@&$}4=!C;BPU&W!z~i0!3nIsZJ7>QmBoN$?9(+6gx< +z$qnP$Du}quA^x6EOz(ELRl+N^rh9}P?WA)^vU3u*yqJh@I>d+g#0}lm0*vEFt1)hj<;IFm<~(mbx}pT319!Vop3UQR!}wG9Dt^ +zgYt@4{$=8K?tv$qsl2UHzrUJ^c$q`=@TN&h-fOVH!4oR+302RWB$w_GdRe{@p6LzE +z^b1$PIbBirKV~An>=1v*o1U_L``-^eABQ-AH(jo*{F!_qJk}q2-Xr`HIw!|X +zHz+HADqjfS?hD=S6=J+;mF-)ya(8Ow4(U_)PQxAI9^N!gY56%UaPWlQ_6d(b=d!qI +zu+s91d?EaVH}r&GxREzKX8V@3>`1jVN_ie)DGpjLkJU^{hwD9|dY^DVAGp5T-Bjdi +zDzm;GA%Vs5z;I>mZmGp9{F@K-Qx5FR*qb7@rfN(6d2*mWbzr-6z%LZElbUhKnqgdP +z1rZA!qQnQLce`6FUFIU|h-%9f=gGP~sdZbVeLiAY6tp}UYwec~ul9vjdxg*Wz=&>l +zbGfUz)S8TvK>v8)3Psr}75a%~V$foVwT?)KC4XpxM|iEBv<^$QPT@L>tsA2xFe4sV +zp%iS&*!xFqbyf1c=SjhqR6)J8-7Ea5otXP2&11QS5+X(&;sV}zjZy%M>4c%Yb7r@D +zRf%g=h4qdIan6l93zU6(rL`U+e?KT+6EjaqhrjWJzVQjqv=j4;WOE;GUYT`wgg6(( +zokNw?^%?u|i0yc_oOhnA-j!OtO}f)BnA=J7gk-mT8VW>lq8146IUsP+oipJ +zA`cD9H^;cVbof?(=#)ozhfhpZ3LB+sJ;LsG!VOJwlR0ZK5d#j<$tMaGX>-QDG-`XV +zN?w1SNOdV`x76V!^2VU-<`X%`3vMXfXQPjCQDgNV1a{*$#+>X +zIY%*pbHrpR#pF4}WGRcuIf@B%YM7j3F?kL#S;}Gp3mjBTpi{%-9E-_w1||k3y+4`c +z!DP};#iTEb$v}!p&4<}AfpZm;+dpJ6=}R%0IGbhb;Gkjxohl}GMOaLV4NMG7a)1d; +zCM7B+m$R5`Lrgx-h6$W&n0(A)ayeqMkYWNwiV1XTn0!nzfg)nEkYaK +z1d52sLIV>6litVVH-O0_Dke)F@a7ElP_3I?lUkkFzJ0v>R~dOsbVsQ#iSfD`6wGEaIRtU5sS$f +z!~`=FC{j$IQ^VvViU|}E6UlL{VFC4SWJ!}CMU9C0_PegCs<4tASRfZK#^hsof;-5C?-%uOfWN9z+wUqX_%a# +zm_QLRF)|YalN@03JHX^o6%#fyvB3fd6_X=bF*!pqfpf$JGn2;=6E-vX!5NAPbZVHK +zVKI3eF<~>4dtiZsiV1XTn4DoTdECInz@+yvSqYQLSQV3@EGDxMlSA1sfpZO$Lo6mk +zDJCyrW&%Zu33O_h9HN*&kz(>Q%uI%|n7~6CCWj~{P^6f=Xk;b^CON?5mw?H`7cqHB +zmzlr<2Njc9Suy#PVglzBlb>N`ax=xGNtc;?N-=>>4UB=F@bZ$1T&L| +z5ffcz5~r9zr-n(K#pGecM3`(q$&Fz(K`iO;$`kr5V3Gq&U^00^#pDJSldlnzQ`sQ_gNg}sYM7j5F?q(o#K5HYF_{aKNuG+yKo*mH#N=Q$ +zOyFF@SCYYJzvzWj`8YV|5CQw97jLgKq +zBnOxr08G?-CKg?00t*~eOlq=X(n>LbbHoHQlN!WCmzlIuOrTT4q?N^_1~JiPCa}Ok +z#RNJvOj=n?Y79&aOmct;OeX78Ow24Mt%%9VY?#2ghRI156Ek9hnF$mrCeW#2a*|>K +zMZ^R%6ElkmJfvZAl41fy#Kg!<3`}x>i3FIa_e?Ch%mfxVsF<{7#iWg50_TVcW+ohB +zqRUL$C??RUVbaE8!XYNQ%mfxVsF*;fhDjTX31?tpVAA`Ttb@s +zIM*;a%wjTvVj^Q^0!4}mbZVF!rkFsHViLp5WCV)|JfvZAm|_A&ipl3jW@2EH15Dlk +zOw@ZOvMw`$1r91E=B$`}MlpeNib)JJlT{RxR$XTD8N~!THB3HZFk(vCjVv;`n>*ZH&-rT3p=snC%h4>fmuK()jbAETk +z{MRpcrQ+M9r~Jb5cG5gC**uC%RuZwlL#*Qyqr2VHDqPcwt(DdCg7c(sZ>n&!bgPfZ +zR|n;XW85Haf4TLqRq``2u5UVgtuJ(~S2*5IxPeJ7pR<-)V&W%1v`tZoZ=2z&Ub*smglfMwhC5MY(}ajhnAn +zZq_3=x>V&W$_;dC+JIuc30HaQzbulo)m6M74DQq +zdWn2rP#zQG#&gq3iTD?XIF3(T+3nt6;@V$feW*&lE5?oF_E%abMo402JTX?0_GIjq +zh|N+hn`7LxbofzE=uw|=cRS&xB)P#{TR9P34zVZqFR52xb}3Z3nZ|O%Avak!p1`@r +zjc((~G~@;Kmc^)G*O)Jh2*> +z7?||_?4rQzvO&dUIg3drVv=>^37l(~=r*1#M@%qPfg;5OIyFpi;|UZI6HHZ>vzWj` +z8YZ~$1d51>k*XM&Ca*U52=`ZjvG&)NHJMrq$&m`Il#pGoqOOT>P?iT +zY^rh=H=c~hhRGMW@dVB(CW|puDW#a0*;FNl8&9B9#U!fRcv4C+f$v09l{2{U1Ugkr +zzSM0zDK#)LFv$TXFqu@Sm|VeP(twy`-FO1$8Ya4pCs!aQn5saLVgj8SCb;ngiiioO +zDp#4M^7?|V$liva+>P?iTY-Vy6H=ZTjZVv=>^37l(~ +z=r*2=LrgF;fg;5OIyFpi;|UZI6Uk(n5nwI}j5#Gl}8G6X?`1(QQ1r12JJUlQX#S1UfZLbQ@3ZFfcJN +z$pI!XnXFYYS;S&;5;4iT@dVB_OmrJh79l2>nLv?Z0-YKrxbXyvhzVvUi&#wHAq^AU +zcmhSl#K=qxOmcw9`+$jh6J;rznViLqCnvLFf*ViZ95KPnCk;#tOnM)a)i9Y%P%#ECy37PO +zoj>&6o}*D%p-Jeh)+U}geEiV1XTnBc|} +zC?Y19nM`3Zfrm6qaN`LS5fdXbF)+yiCT{^I>OGV9beRcmJXxO=6Wn+L=ZFbrCU+wy +zy37POog2^0|%BQr5D$pI!Iz(l=g@}4d; +z!Hp-$teD`&6F5gqFf(x>Cc4Z7H=aPJhKX+Di3>5&WhS`s1UfZLbQ@1x1||k3y^l#D +zOeP~$Oa`-G)!>g +z2^1+NPZ^nsfk_T9@qgzY_;>Z5$dfQlQ}FV`w^3@8&BX|!$i07WDa72 +znF$mrCeW#2f*Vhuh?rnzGKa+k9?~$ujVDk?N33O_h +z=r*2M3``76a)1d;CXcF^EM+liLrk)6Jb`l!6Wzv>rHBb;CQzi9K&OTYZaje^VuG2; +zQWg_XF)|YalN@03d%#4!XY#ZzGr^4~ZCNqFjVEx9m|$k|G-9I5OmO1~ +zbZVIBHl93^37l(~=r*2= +zqL_4HW&%Zu33O_h;KmauQcTWcW-^M!1Rl~b!Hp+Sq?n|P%*4PX2bjDGn5g$mx^$Td +zZai6@6%*We0_PNy^O%|3MltEsWhS`s1UfZLbQ@1@qnN;V!psCWoyuI9 +zoE~@Hq^#Z~P4E$UW>CIA);u5`e$f|t(JOr2PMZ5Ao5yl*l~@B&;v5lo&Qn(J$k-E6 +z+mtG~BGx=K9bV!Oz3UO)YA4MjlFie&WYPcGm(*|AM=T${rgC$ej+>LjG$3xeQpszD +zzf%6tA&>AI-ZWLoYm{bsgq?7%aq}6w69xYE>`K*dlkSJV1J^sm-|;3J6p@>gl$+1! +zP8292H;aiFbcnUQX(Rl_*pzD7DJ}F0C*UEC8~7{b4?W=#ehx+CW-$?;b%+=EK%Z`R +zewi!3#JVj?0z=|~tCYFhrFuWH3=LXtj@9I)!z=xv7LV{YADF7lZItGEg!*<;Gc;K< +znX4%#;sJ-ajt>+n2R3Ky=BTZ?%Ci1EIZ&56uv=2R#IiAH=^twy&6!Jxc+?@z<^xxE +zyUnF8bES1&gal^A1Nq9j1}W|#mb-(NWwF-j>2RSZROl0K8nU9c58K}?I|rr}E7Zt0L$_$P1br__IOoNhdUbL3_r5npzQKjckM +zU5DH(B;tP@;sD-sxw0~LoNhdUPK}%6?8cMpkeh`pH?S{AU9bh68aKz;jVIUrf0P>% +zA%QvZz(hr9kh(p@Vh>tY#9C*h!-G7bK|Z0lotP&j%>%d*<<`Ry;=DfY9H12J%Gmu8 +zo4;C~6f;lY8cMBysg?(vC;N7$_8FLLmtOM|d00@sCDxh8g(`@+)FHmdC#H3~LzS+L +zMb;VB@|^Redrzu+i}Zny$V-Fr)3MI}>F{&D&~skl9G@7~?M|1w(xukE8(t-r56`NY +zJjP-YLQG&q&?T6_xrWJCEGCa3CQB$LP^6eZr#8EMMKOUQVzPu{@)(N=JfvX)D}q!^ +zpoo|(F)%SO5#Mx(5Alf`y4|57SE$S?R>{uuWJ6tQ!*1!Um&mT5JUG@lhTB*|#M2J( +zIzD0Qc5f_oZLGAeh>*mbcw(Z`-5_N=M79Uz6|sCzBVh7?ipc^N6W9i%VzMzSCdViy +zaE_QPpqR`+Oct=19HW>(r-sQf7Lyr>$pRJ=*aoCx0-YKr$5>2e7?>EC^!`7Db;D%x +zfr^Qp#bhI50xN4kEVrMadhcrxJMUaXK +z6cH1%fr)`h?_=@{z~mtnlSM2hunkDXB%KwL(-adpM@$w`OjaN!i&#ufQ%s;!!{juJ +z$qK||5sL|I15z=8P7RaOEG8=qObkqNfC)?{85I*Zi%A+WffYfQU;^hFCg)g8+=$6i +ziU|}cCeW#2a*kpGMZ{z&#l+2G0uO1Jz=|Lh6DT4kOASm6OnM!YdpCXO9ys;hi +z&tP&BYy(m;>7Nag>p!HJz&XWa`27E3lIlY-88M&1Wbua-6X;YiS@0o)$;mzx6ZlTU +z|GP*2M%V_VVgj8iCO3S@VDgVX1||k3y^qNtm`pZb#N?kvEGGRaCT3U>bO|PKu41w< +z!eDZ=h+;B|W+rE$NHKv<6_dgU#RQ5Jli@ToNf)u0z(Xn~OJGHiiU|}cCL@i^#K0s6 +znEV7Vc~HfK%}j2BZ9pm}by+d_m|_CwhzZS1QkNknY-Y0fV~PoMYM6Y?VsaT`!e%Bn +z!Zsik6X?`1`IyDzG6NF>lN?|IlgU99lY3cA>JSrH5p)SAaIRtU1&hhOhzZS1&O(u5 +z0-YKrUr0xN=4OrVIE7@3KINe(dC37FikV!~!7H^DX_6_e7e +zn0!Prfpf%!W+ti8hzXmSEdGdM0-YKrAF-H>Moieu8Lffk_T9c^NQSt75`tCO5%0AQh9tSur_5F@bZ$gk~nG`G^UdnJhj* +zF@a7ElM^f^^AQs^Gr1AA0jZckr-sQ17L)k~CI%)szyv0fKdG4fh{fbEVgf6IF2MxO +zHB8R1nEVJap_$29C{j$IQ^Vv8#RQ6o3C&E>KVmU~hcrxJMUaXK6cH06Gchp90VZ1k +zllv}W(x}T!U>lH%$rV{KIYcpmbBf6x%uI$*Od52V$svjfbZVF!Vlf#)F@f(ioMtAl +z4M@cVIyFoVv6u`oFflOceM~A~GWn^B$@f@Hu0Tv+MbIUfz`2IWrz|GlqnI>eW&%Zu +z33O_hd`dBaBE@76W+vZbF@c9POkhQjiU|}cCVP#{#K0s6nEVVdQSX^F>M|492Bc!* +z&x%P4#RSd~6U|KxQHlwiBPN)cOhQa_naNR#33O_h9Az4OkhROC78guhRNqFCO +zFf)N7#RNJvOg^WWKoK#)%;bkGCh(Ak39JZGF@YjtVq_);CON?5=YWZN&!kb8nZPz6 +z6_dYY#pD#l1kMo?%uKFFOmvyaDT)bnYM7j2F}WTw(PbvE4M@cVIyFpAv6x(MU}9jB +z1598t`Im~xk6BFqf|$UHpi3};a}ATTEG9ojOfWNnBElH%33O_h9Aq&WU|?ck()*aqhRI}?ib)xZ$vDIW +zRs>yw37l(~L|IJAC?>aIW&%Zu33O_hL@6dvq?mjkGm|nF6L?6&1Xcv8m_U(Ya;uS< +z7?|V$lji{w^`6OXy37Q&0jZe0kQI|pC?;@@m|$jdC1Rq>Og^EQK&OVuCoCpcA||@b +z1hxUGm_Vn7$tNr(R~ncYnB)Kxm`pxVF?o>1yw37l(~e92<+AYy`<2^1+N +z(5YeaCB+1ah{^wB@9x8!DD(aCAJ?PEV`W_)OJRKiN@*KcOOGH_MPNBGEyT0c~z4o`)oIlPv-uK*hI`rX{&wP6Kjd~_e$T5M7BupS8D1`|OB23ht +ziHgYpVDcNlBz4YYv7%=JX+SAVmS@D|y)-5;k1#Y2b`8WUJ4Ve&~D6BtC8pq|O2a!lYN2@{A2N?`(n2otquqGB=tnCt^gQs+z-D|#l7 +z29(0&$bL +zCMqTafC*G4;S?qna!fu(m_S6(|A7h2OPGY@m{cH4P|pMg)0n_Y36oG76BtC8pq@#E +z922-m!UQ6MQkcLX!sMT8k8sH{%66K7ds{(mJDQ@o0$W2F@8<MSp +z#7&2sn_+2g;A0w=?y5juP>LH^DRI*w=VsVH6F1_LQge^^)b`j@J3WDeVkzM&9dz!K +zkyh)2B6a#ns^Hl1ygs{iE@54upRN9p`X$`zbJh{orUm*jABmCM0+AnI^1PTdlzxPj +zF6D~OS#$cmmRA_dp_cNmMQe7{I>;KDCsM?dRN`3Vx=Xg_lZHJXVSAQxw+sL`>!Ege +zImOK*a&GQM++<8Vfq97=dE&|YkEFRdgSsj(nC1pnO5C8t6BtZ$<40YUN95eVMG`kC +z@dO6b+?@Vr>Zmfq4lNdE&|YPa{lFR|N*s +zn7~R26O?!Yg9sDURe4&D30x#$f)Y<)5MlDq)KyV2ac5coH89x?n50gkoKbXDP~r)m +z5fhYn0`mwH)K!^)Fi~_>P~r)!lrWJeo}8M1Fi~_>P~r)!lrWJeo^(%8F;OwO_L%Tc +znb0Xr*2poz5hfWEPheicM4ou^{u+b{>Z-tC8WUJ4VS*A*U=U$~x+-hrn7~C6CMfX) +z1`#IzOkEWflYbdZ_5&uVlPG5tT@{pgaycU=DDed55hkdsav#D((N#f-C$Lh&M4otZ +z>OO>tqN{=uPhh2li9GS7`#u#D6_WwL1S*p&DNMG?F}aK|$(VQo^AaZV#FO{8B1}+M +z1qRcYz)A@dlz0Mz2ouy**(%2bE|M@oi6=0KF!^Wds;HR!%V6@{75fcqQYTRg*t8Chm-hCorGFr9OyHsvCaoy(1P0TX6sSED_4mC7;P<^=0!&gTQ3~Zflana%WM@W9 +zP~r*9BTP`w%4hNyfwzn3ph7B%VBuFhM;N7))aVDnLyOjJy+Jtp-~nUE<=mdP>EAxttRp1{0>i6Zf28NvkhOkgmL +z39OVbL5U|Yh%iAtlVx&D;35eVlz0Mz2otquqGB=tn7j;_q)ws~%6ld!QR2ym88JbL +zCoqpNK|Pb7Axz{w6BkN6ft3;_io}zjAxz{wlXp?#39OVbQ6!%HOvOaSWB@RM%H*pQ +zCeO+-`4C}}G4TZEB}^2FC(j~GP|pMg)0n_Y2@{lf0)q$>)H8WjjtN{OVS*A*U=U%V +z_Dobv1^|<4z$A6fgi`cOP~u5mModuR3CyQ4c?0!KhNLlRR`g6z;t8yjFi|9)3`t`G +z9~0`Cpu`hcDPf{WJQ<>5qGEFGFHw3}ITK3JGeLH?rVS;)l(-0<#o(W1kft3;_io}y?2opum1SOupN(mE1;>k1>6BUyIzyvCjPg0mX +zCCB7A!X#tj3Cv5FC=ySeLYSbQ2@Iw&ft3;_DDeaa5hkc-@{}ACxJbeTC7!?_!bI(v +zsF(}@Cc6NW)HxGM(KA7bC+3Wppu`iHN0^|V$#{f`qGy5%m?#oYW+F@!Jrk680xKm<6p1G@RZLV&1^^SNOnOt8*yNZ*5GENDPheic +zM3H!6LztkR2@Iw&ft3;_DDeaa5hkc-Vv}P67fG0)#1j}qn5aDy6_WwLWcwBS4Z+ko +zlTC`A2}(T4&WH(0Jc0Q%CQqZD$&G1DHY$21DDebVN|-1TPi{UDwAC)Oyk2@^%)$^0}Xn^4aL2Gf|pN(mE`cmjiI +zOrAzPllgK?;35eVlz0MzX-q6?&qT#!05I7Ln552`Y*O@0P~u5rModuR3Ctr*P|svC +z!bH(CL5U}@Qo=-$crqDbqUf2R#1mL4VWLPpnXF=>Vln`jKxJ|&g~@t3CXEP_jEN^O +zFJYocJXw!0K|K=~Ok)BoB}`D_2@E1kP|sw&922-m!UQFrz#zgz?U|^U3;-rO0h81@ +zlTC`A2}(RE&xi?1Jb`(H3F?`QMwlpiCMfX)R!W#C5>G}WOcXs6lz0LwB}^2FC!@rX6hg@2|xbH$+#AvaXn`|KzNA{KmlX +z$(LTQP8!^2G3%02eUJFMBlh|p&-hnbYQ7dfxheX|SZmP(B6Z|RYW=a}_x9P{_Y>}i +z^v&uYsb9iv>k()EDmL?Z&xnH}XLNBR&sl$B&6z7wUp`6Qax8L3pS|fpqG`VVpZbr~ +zw?gd_O>whX&P^xcCSxWF%uC!TGEp`oZctYR2GiWYN{Jhki2{R&8`M?VEawI;lDI*c +zC@_e)DHbX5BkanO(rrEBv|q)hJ?|NEP%JgNN=Kes@e}K)xgzz&lhluo9lxW`UiTnT +zH($SQN$KiyD@IuB7U)NPBp$ylaQw%YUVkxZSn(0IVrgm7xfMD6-ltw+o;uW0_O-Yo +zJGx?!^^dt*KMExW6 +z{~~`^*a6(6PNH-xx+*B~WL8FQP~r*9r@8qCbyY^Bxrr*eDk$*;R!ZC`5>G~?xq*)f +zbyZN}39OX3Q6!#>xGeT%MeDMxUo8-+A3aI^`q=TC`|P9U6Qfj2sF#nKNB7xJ%_mMh +zpvTXO=7|CGoJ(cD@{B$ta<{p-$IrR{z294Zh^ar=^3~U(`$tjtkFCuQ>W`ll&BFuc +z{7Yqyq#<$^%U;6GKj$9Y@11d&X?>-o`D@WVJnGJ|M(-D?rY9-=F>~>y!1knpIE($O +zV6qu%m!=dZi{zNhLYQPsJb`%$6Gh_5qBJJmsH*~lX-r_Hgb7MKfx$E;-=MC_A~_~- +zk%S3KJb}S9Cc-@`Ce#a0QV$<9|E$lx@Bw1sJpIQ@xQZTe-*d5jFL>4;6uGBe+=O#Q +zWBR@PL54rva>Ft6t$p_V2Z{Xodfi8&IX7S)cd2Z5(vbHNmba9fcFsM%-+TTQ=KP@+ +z>(`=tV$^+|b>l<&#*akv-2wB^OM%}c4V@oholCh9J!0U6SfJXo`EbkZuSNHmf1N)C +z*#MZNPNH-xx+*B~q&*`hDDed55hkdsQh+c~bX8E|39OVbQ6!!eAWRfp6_j`aD +z)K#&_F@cLDOi +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 +zk1#=%Nxd8sSgB&7Vsfo9fy$&a +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 +z^SHQsV8eyw9!*gye_}CR +zU6(yy@8Nz%GWGdU_nL4&_cxMgUJ@|B$0n#cZM=+janndbmSvy@#7aGBMbfs-XIHM9vbMXnib<4XTUHe83-k6PhQza@#LC4tBv*#xy$8=pzLxLlH1lpnR0nW&F-MAK56 +zXk8!1Hq^ytw)Z3>zhjxx`B5uoqAu&Yy#-T45g&_zu5$JTpRazTwDB{s45u`rfZ7qh+N;%+D7hCTH{?MjnFWl*6l3qrDC`L6y`Cy+>KhUciWbx-e$X +zkM_2)n7xn@`xb;TLtU)T)02!evdoROvA))xr1`Nh20s8!y0}-^1T{$;AHODGety%; +zZtu3(!i(74`q=nOji(dTL0x?O5f}F+$)%HBn2o +z#ICY{*~Maq8)DxKq9m-krB*01ny42}hTj$U +zy;DIwtR)uqExg#zJwXx+v4HtEEVg{x$6Lgr6=7_7Lu?-p8=7?SeJw7o2R1yl#KXNv +zGV7;Bi!Q^4Cu)Tvvx)lb`wf{2>Rv5zYIVTe0yo1Kgv|R{?DF>;8p7D+hFIC3VZ$4A +z@v>ts&POt%ufTnsWtq`=QTH#y{oId9B7b$j{2H5}NL{?_h>LrhWa{%6vFv08HA+h~ +zud<2mWnnC@Ay!7ZxYtQ$WnR>6Gf_p_ZtwZ&A#*c}nH#$7&C5NUhh)y@Mcv!N{oIWt +zv2j(ve3(s8yL9out1j*c88Dql-%Tx}EGE5cZLLo9HlCu#0vnby3hyDHqz +zjUb8Ws(|?@i_L22vPYMBxE7MxoX3a(rh=NSC8DbXW{OQvj4mEH>f%n4aYLd`aNAAP +z_1bRli0ProD=apsAvW{Xo@C@BmKl*3wZff_B#E5Wfygm7K^@k`XC85JZ;{OIJVu;( +zvVyurOEj&riPmLdY)V6HCh6i{Bbh~cQLD{F-L38Ro}M0xyuo4{8oKOF%RL-TGN<#R +zR=Cp}NJ76V5IMvqsGYjF=T#R+l5s;ronYN!qVlwaezi@st_WkL4KdG=o@6AzGA(&g +zE8OXDk_fE|M2@gnaYL6qw9LablZ+*g5j{)=HA_o`RtF+2Y=Uan#XUz|97Dzp@jAh3 +zH&KJM-QJ1QLy?0lmemlm!JVFEnTdJPUbxd+NMiQtKm0hdW9#bMm6STf+U^7?S9J+r?4ZZtpg|hufqjs#e>? +z-cFX;RvL)JNhS$Dd_G{ABHd)%AWjWMj+wH +zF23(o7xyZ>l1$)dVUI^iVxc}@-UoYpTrU*qO;mW$KYahf9;>zSeQp=`H0&XJ3vGry +zf+TTjdBEHSdt9y)itHxph8ruC0K*>hbn&t`T-+CA+@Px!+)tP&65cZxgv>9q*oXD8 +zvX-8t`3lRdoEmjM9`5I~B+usWYQ5cKV +z$I2)d*GI+;*|mb(Xrgv$yS+0CLgu|J)(G#JS9&;}WLl?2-Rr{r+)9$zs1KMM*#xyw +z7Z0?!xEL8X%&HaKYfV&>mWZygiEdpOYp;(5ntPJwILpMQM%^1s6r=6-#tK5_11y%P +z@3KcrJzSDxMoeYInQvB5+qFc_nn2_~*#tFL7oYiti~F368y3_G)+bEVVR+A65Q;ci +z?1TE)%$A;Ha?$H1{MUF_sagMy(r6RJ*p@D-?tx`&ler +z-(?S#dboa)nK+dZZEsdk4lOZzO(60To1hlx;2~Hi5-Va%Hw +z?S+4UO}coW-b7t!i1p14_j8kU@xJ9Is-&UI-cMFg-uhTyxry?^e;%%&C@oP1FTXI1 +zU9Tmo%57rNn-x^ImZ&lW%uB-kToy?TFNhZXv8^d?C`q*9)U7&Vc<;uG{oF?+F?@Nz +z{3(ldRCR6i6%aS>4|E +zb3^7Ji+x!a8!y7D!P@w~H(lIA7dCg<7q0PecaY5F{?^M$^V=*lxiDHZ&qU>Vqwk9Q +zUaz2D(-8|V!-g)BSXde`_rZqir-sb$v)J8rv3*xy!>ixGu;D4p!%ZL=etNWsgPXw{ +zgrdbJYRmTruv@nqa!t{2=Z +zO_W>L?LD6xGKW|!QWq=p_9V^QS!TxcsC#L+pL?GqHZBX8KV}ouDQ!IPu8SK@GOg1Y +zG4Of?)vO~nF1Ly9jbW^_E*3c1lQcV6X7lu@d%1~ff;ZH;Av4Ef?eLx%^KcVMCN@3l +zE)Dl{T_h1*9xz{E6I8!89`L%j>&UoaP`zMXVxqR|h@53M(fVWS9(ZZOF#n$CzbU#p<@>WHRgfyg-)J6ac;$+)<2WZbZ! +zUa+n-Q73fW-qX3ENRY)Y*2QLedyo)KXx$jbxVo6b3>8yEY=3^nK2KSLo&kj +zs1@!sL=vIpfk+pdpc2}+$Lr#*C*y{!dZBlTiE`+O*~@HV?~`F{PhHFgclrX$?4KU( +zg**M2BxWxUL_TA&Gw_Dm;Ngan3^tt+ZLd{O4LX8Z7KnVpVpLts#<;j_GH%#ZFZ8Z7 +zQEj?zZ&z+85@NCLx|j{_bUVw;nI7$hJNhY9H^E}|sf^gSHjLS)MSCx@3Cde5^l~g_&x`iP*#u>; +z6?#{gC<@+<=Z4Jpo2X5?ZtsotLa*LLb?b=X@T1{i1@#A#sTunz)WFX*5yMvp%*UQ< +ziW}xO2t|*WD5H)TUi_x)9rW-2r*Gi9;Hs++vEZs_wDIw6F7B5k^Zukyw}?d#gt1%d +zWBZ~XaMhCN14519|L*wBVp*%PqGA(F^n88Cm#Ca62L@v^sF +z+%mAZL2y4}qSon%{8F3f-Wta8YGY+@^(4(C%d9Mjy0s>1g^p-m88G*68wDG`OE^ZOYY%XBL09irlbwqTfO>`4sjHrzTPPjOX +zj2nms!M)f-Rq49DvAmF3WU)cDUG|(+9_|5>8Bq|m{yf~z9VCgIm4V1#*#vdFHa_!h +z7q=8FZV;@Gn5eZnBB#_QTDOL=DYdbgZ}lW2ud>Xdf~Zw%qL%B3rj>z64~uQ6?Xowm +z_He67=5zrg&OBN{;X0zJG!XfYO;AI%anGABZXQ_NAXpzZQ97uL^Fooou~=zs%=30n +zGV(ghv=l_GaHnpP(3b`xeQbit*2X<=xwwTSV<})n4_QH#>xj@wn`kA%SY>U@bHc^x +z$+)4iL9i}1QG~ABE98YDNfyhh?Xu5a<>BU%%*29dFWl*2l9;_R5P{F>6m8u0wu@U1 +z7B>jJkC>xgWw3&1uhvAB>Ii0KAkxcXn`*o4%xVu;PBL8u +zjA%PrK~?GqrZf)7 +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 +zXqqh}!|>8-`gljM$S4Ffm3n9U9DnF$ +z-ZBg?uBID1g84?_yr#0;**@DJ8p#X8@XBhsy(2i=D0FEm4bJuw|LmLjiNo-$YTD5e +zyxl0A)x=jhiTnJsNAmlJ;ft&3qaDG!jlyS|_!=iM$Isl%W5e*mYPz8#m}e9|(ZtJ~ +z#B4t^lJ6RZZ>px-I)bx|LP!(Gwr<$>)tsB~Nj3ByU+@E?uvZhmtcmZ`#7)k`bbr-E +z{^U)#cNp#+f_q2c-odz`hQ3fkU#O-pIOvicbV&_eQcagQXzvc%TSI%RX|IE}@1QAP +zkTVL6n&O}OtFrkUYv^uYFmALgaVBo{4^uFt#`E)s;)fmdUA~~xXn8|ZyxEyO#lI_?e}5?crGp;q +z3+^yl4rz*?aW>xJUpSthJQUySpmTk}TBGH4O|jM4IN852n?EuX|JXr~^95ftT8?On +zacAS5{!`=m^+WL!4*FhS@OMT_i>A2J**L|2Dx2qr;+Gxt4Zh&7jh2I&wqH2Q@9^i3 +z=SL64cRJ`heZk)vEw5?XDxBq${rTB^{ZRZv2R+Ic{Eg87M$2(c +zo7LGl*}pNHZykzvI_Mlc>D*`Jfm?;eVO;Gl2u +z1z#`+vM +zKI3e^!>=FD7YxN49CV&9SZ5So*Hl`a?UVibY`$eE&N=98UvQUEIHIYbLS2&5u{@L05{-O982R+6Y+-Vd@P5fCWai^ad&tpSz%0UI!!)OU=iZN%l`h#5kLH_^#gWO4!_^WQ_=M2LqRnvPq +zf>VsbMWZmrD15AmuXZNx^H+`Jw~gbsjpDcE@Y`^%Rj +z9RB^m_?I>Gx4z)tjh0_)ijB_3ss4o%_{oFuy*2coe8ImMEx*weuX8p|^DoTdj||2? +zuA#%eV2{yKqbXkNY|Qnan!v9gjGw5XKl25@FgJs96vL%-(>eqpq{plN%;Sw795pTpM=#y_l~zw!nDX0%jm+8%e7 +z=lYu`@GA%7$7|?Me8Edb%PvjZdS`i_zd46LKNyeH(7nE3pV6{i(`IybPW5k`z|Rw%Jnx*;1>)2y>nKczbS`5Js7`O +zLtpj+rT<2_`=GW)&ErW5chK~4xy+)x% +zQ@PgJp6d@y;4Opkwi>$A7mON(-I~e`&h|WiD2EpY)i^}b-6(ejuxQQ)td#NSv=Px1x-tSSEEN1vY&tLa-if=i5+uQkPwIJ0N?hmYZF +zvhdq?&?7s7KQ~(bqAAuovy1$@M)U9ne+PY6M{t$V@{Oi=ku$s4ziSNteinYq4tj7$ +z@FAn+3r+FE&c=KE3rF*lv+(6R=-iIrqejamP4Pl!;|%}8G5nD%{O%p}xQ^f>MhmYg +z);SxC{HI3q>$7lt2YqixaE;L-Xo?p*8;kv?#_)U=K6D3tLr3sIqvdl=+s~cl_xSTi +z^P{tH-46QBj^Hw*C9G+C#92PWpFf7L&%*O|(4#tnTBGGFO`FzPUgU2c&9BVD%{%C# +zj$oP564kUVa+VkSo5%3yv+(R4^ze@0e52({P20oH&U^eDNAokX@bVpWen)Vn(Gt>*= +zEgiv!jly3vm0IVlB7f6peo+>_VF!J8M{u=K_(oH?$T_Rn-!z6lorRCtK@aT+&NB*M +zXeu9ew%_B|kLC-q@X{T0UPo|+QMjb3Tmgh1fT1mjlSTUM$0>z;;qi?Tm8Gn^7Dt_w>#*i +zzTh#V#ic2>IkRu~?;6LyKLlUvpr7#t-!WR=)f8`YHvZJVa4bK02!4x$e%Kd$)o6KJ +zQ@q95c$%ayH)TKQ)$LKLo$qL9g}&-!NKQHN}Lp@pk{I +zaXdc+#~t(*U+`U{<)o(A?kxYQKYuJgdI&z$LC^CA4;d|QY1)42EWgd4KaQ^-g6kag +zI$!W@qlMPAZFQF4>Te#)uN;EsIp`I>;Oj<<>_f}0(*)fe;_EsUmZ +zo3rz${*7b#8AI@F2fff2JYuw*(6nuFcHZXSIF4@}f|on!jlN*3(bBGIt8#YU>W_}) +zHxI#QIcU8v*kZJ_Y1#;9=k5OJI6gK6CmeK@FL=^u@oL)a&RIY8=Zxh?48aFE=()b& +zL8I`drt+80S-1If#__v{;0qk|T3_%jqwtQVa;tOJt^TI5{GuWF6bHTB7kteqxHOeE +z=d9cPP2>2}L+}j_8utZhqwub#a+|aLr+)odzF-JG#zE_RLDDF^t*PANY`@K~AIG;0 +z!Al*q*%x#h1&^k(%GrLaKQxxN48e;Xbh$6sY!q5Gm4vhXc7JFbFATve9W>z!GDhK~ +zrqb>te(Ik+mY+BT&vMWUe8Iy;;Vn)4mrmj~|Lk%6{vr5c2fe`;JYf`QO?<19xYf^$ +z<*^}np@S~<1&3md$S)!*83!CvWDHWBKGy_~ZmW +z`C~pgo==YElN0&mNdDvy+~A-$`GUXF#5X##$MPqK;ujqB14hB2DgF=t@VlP=`(?Y) +z@?VDzs3=S&ePhw$UCOb_8>Te{ayPk~+_bhhXo}96Q?xb9v9*h{yi#*pPjK?{#Ctg +z(?RR%Q$vO4y}7&8;4yaMZ0UCSRK0D>L96}LP|^99a(BHSJod*EXVbRJFV@>`Iyk!O +z)P}7Z9X`<=G2Cw^H1dNdNX+J_b1NI+%CUVZ@c;6=;~9a +z3(wz~yXzOhW4}Fdwqm>dTD{GGaMXV4bkX_qxw}3I9{cRX*_7?_3-z%Z54Nm2Rabbv +zBzIRRc)u%2Lp5K$ZYdm<2pEz5! +zU4Fej=07-TKXsw#{HM9Qrh~^Woj9Ak-T3?Zz>Np(t4>uGp3lqO)f+r^;>6j4?Z!XU +z2W~lNUvsLm==^Z*u9t(y-am0RYrFBQ`oN}x_SL5j6`tRiyX(o|u{TegE!%FKst;^A +zXt$p_RCNBe++808k9~6DZ2ETN#rnWa2gg^PB8BIr++E?|v56CBi?8AGrD8`07)<@VuP6D;7L9dE#v4cH_1BfdAmQ{S+@cZ{+Su +z1dmOhIGeiNc%eRV*?UJ_=&UD?Z)Z)#Fm3?_EX1;&cBnp>!aYY#EG++ +z+l>?TiJJ~iuR682@ch22^ZN?Uug%@{c<|WkC(c^78{zGSf4dRiZrHXP6ZMJ7`owsB +zV!A%jTc3EjKJjFI;)D7`xIPiT657?)liZzLSP!>OKD+b({jY85vFYjNcdohl_*Yh+ +z={4rV4Y*dF?lfxQK73A{?l2a@ZMaXJ?lP9beoRR_aXFtjXosHewWN_7=?i+g&yqr} +zqlzB%S~AF2>F@NQ&yq}<==XJx*OE?dp-lJqEUDxx^ym6XuO*Xwjs8(T=?f3F$wqoiKj#f+ +zl5O-e{hZIAM4U9J7km9_W93641O#9KtJRQBy$f9>%<#K=bLF9+jEM>q!yj=+mNqO*h_?{9Pk&>Ys3zg0zM(XaNU1Q0%aw^iDF^-rpHU`;rA+t{KA=ntN%`Onuhb4{GvOJ0RjD1(QeXg=C}V?KHavw-DPzN020V)QDq}-h +z9squ*jE!i?(1Ybl>!6kePvE0U>#&v%593y)bx6yFXYp;Nbwo>rVO*n34Qe@{At+PB +zS|&V(4=PhbT0T67pDR-%auRf4hGHF*XMln|igj2{gYTnPu@1>I;ph00VjYoFpdS|~ +zql0ob{1l&1Mu+7Lcm(fMMu+4)IELqy(GfWrf>@%o49Zz>7#~(zE; +zdc{`zhj;!LVCoQ<{vwzzeem8#&nKR@Pw$_;GJ5XY_oc%D+@iD$$+>V8-%?seg98!=L01lKClgGLTKjn665!$u}Nj{B79AtN82$ID92titJaG?}Hl +zETv=?b+UA~rGm_$b6L=3DJP|LI}5rkRV0lTFptYpMrPBSn8$6YBs1wUcG6|Bk_vi1 +zJL$GmlN6f8YFyz`Qb@07HSTZ)$)=0hVOO}El+%0IVRyKSWY99U!xb(gCG=Ld!yT?9 +zd2}^9=L%a%75xr7=MGnsWSY*3UH(#1Ks~J3?XMtNw1ypU`O8Te-N6pH{Z%BL7PHMR +ze;FyJo7rZ!zmnwA26o2fw~|V_o1Jm{t4S)&Weu))DJh~GSc5xWL2_svJL-y;6D!@x +zj=JMjB$HOM-L7~Uu~5QxyW^E4pEk0KuDF#{)4lAXJ6_F`Xe!Hf*-H5=>SnoaTLqs% +z=d&S~t(=$AJJ^uhR>jk35!>LhmGRm1X12j?tK>833U=CMv+@eMi=B4cs(A{{VRf!p +zDKDhWtj-;);Mug69dX6Vc{y!mN8GV0o5f(MJZfhbTrn%JqHXMg +zJ66q;X(p?51xk4V^|4BKpn_-7h3t?kP|nNfUF?uMP{q@!g%MYvj2BZsBkn*Y&!slT +zT>&evqyfg=foh&g^I4-SQOb+x4Xn|fsNgwtDLd{;lyfV+j~#a>s(2=?W_w+UGH#)_ +zvAym@CC{hp*d+c1Cl0q*X8rUD2GNbPd$wi_x53 +z=~|e9^P-_{X*n#yXf)I#t$|X!JsJv1D`6GB7Y+4FYatB_qs`sYGPnvKiZ=I1t6?^7 +ziZ%zO2Dk>_h&K01jW83JM<=?a6>v2^6P@Uh>`;LZL??oh4X(wHqZ7T-I!M9nXl=Jv +z5A$#!THB+ofmv4 +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 +zZ~uL<(D^&ZKh4|KzWT+;fA=BmkKK +zv{3*OfXo1r1Rw#(3?Nwm5`fGAsuF+%ATxlr2|xmn89-|VAOXk>pnU?60AvPGvH&Ci +znE~V!fCL~jfRZk+`zyN?GfCWP_!qm?@QVK5y&e1~vjiYpi%)y0QwI=t7E;Dj-w_X4~0GvF%K3JNu7qXNA0$KFy9h6D8bEKVo|wi2}ZmKF;m?aeHqWyY}H=IT`(O2{uUpR%V +zr$5yXd&3!IEB(EG*cVPFUiyf>!y8T~Tj+1~9lmfX*+`G+=e*%evWXh*NCC +z`-^SEds;v4O=R#E`jLLzmq_M5`nbN=n@Hz=`mVm$mq_I|(C76_-b5z9jb72y7X>d> +zLp!D@IfK#+h+wCZGc2XS_t2%}3`sNLXZWI$Ga{uxAI?)kgHks91fxo5SjvEdc)JoB +zlJem1@I56oA|*pN7AnnyQWpFeA5xl!rF8fqZc>_uq+Ix0d_!p-ky2q0mn##4QV#qL +zKBG(wOPTN^d_b8PlJen~_^~oEq9s8mW-GOW+6;)|fKofGrNKkEUa1|@X2LW0s!}_m +zrN96#QN{+fY%Ro +z>yVZU&*Ixk>xh;L!(#2dskQevmW#FbV(q<&wfB*kV(q9Qy=@ubKnHtn`KtoWbhP6z1 +z3?EdchO~Tm4nJ3>M&u;uzzoGYD9-=|dlc)ioCe=VuVNjNXTs0%CB-@-r$9e0P(}yk +zZ1^cYp^Og88Sn_+sf-TEd2kHRE2ATFG6bhH#}aIVk7A5qwse9F{ZT5bjYXhva-Xj-M)%BSsQ*VV+_iG-iN`!-{>_NP{2X +zM#Vm4%!FUyYl?luNP!Sa%J`s>4P&S&vP)hHd+}4%-fqkRH|DAKPGb?=fy1i3!?+4=#*M1I%eWeL;cM!6 +zyD<-%QBub{jU~{EnmXQLEPxi2)$uMvf;KeNwsvDK_^?Vfcevx%e=iPq=zqOmBwl&C +zdH?zSZ7;lc*X8~EAM?&m_RALF_-SM^Bv->F%!}Cjj9G93ha>g@qZHo9jS+jlF&o~* +z*CO_iQ30Qz6dCU`3Sk1Z$oPO!4pS&c#`}#Dm_#Eo9x|$68ml60eMSMijE|WbO$}l+ +z{nd`9m2{F_aKwtZM90|$XUxLa(rH%d2+ZPhX)mjE24?eR^ksI)5h&z~>67e`Gf=`; +z(+?PN1PXW!4Kv~l6!QieXWS7e;&n8}xHDkkjWod;9f?_dJ{@6=rW*CV+r?o;6i4&_ +z<7mDgx2bJiMjZt39d)|hm=8DLT6Mb9sD=CRId!_jSO~Y_K6SdwSPJ_w<<~EX-?P8s +z-!oqW93641O#9KtJRQ +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 +zUO;`U(jBPaS#%*gfMoL=c#n1S=6p>An8 +zEW&6s)FZ8dQoKDH3Q8+s6}}e@^-60Y4GW{q-O@6+3LlC#_eiT@Hg1YG2c-tM2H%J_ +z_eza06PHIPx}_CxH9ixa=#lJDfe%C{f|3oc#gC&Cz0x{J!R%;lw^k4Ha3EUSqpgBM +zTpz6sYS+MWd^K9zt6dA(xFkB(tu2Qo_*8VPM_U8scyDwpsI7!G_+fOcS6d4iSRQTd +z)|SBnd^FnHqpgM#+!}2SY7MXw-;TESYK@SGYob%#+6s^mqEkJZ9jfrb=u}X%!CL%0 +zI@PPKgJjHzTD#?Xn2SA8YmdAN3eX$12IXsD8NL*?_R7~n7A}a6cFW6QF+LF;?UC0& +z8QvKk4azHFHJ*=-_R4D^9ZRAu-SRT1!H1(QJ@RTO#x2p7pxgir_*S%~S8jw{Tp6A0 +zmRCR>J{z6vk?l~4d!my;*#?dHX>_tzUI(d|7qxdA^)MfYqxK$S6%^sds6A+011s>g +zsJ+*?7IILEj&~c&p%%61c#p9LtSCpvgT_j*qY)kNHP%8VRz=&ojb*S9AB(p27^}g8 +z+oEkjqXBIAPPDDpXoP%R8=dYpR=`qxE;`*~*r6KtMW=&?4c6i1=yb32_qG3gMNeGOE$TiZr6hzOCI?)EzmtpmMroOdXw()SaJ!a%k+~?mK^d; +zdcS_sW63AqrCEASQ+NisonEikc)~Nu19Y)|xG9`X?xpwWhdtpu@*pkKcQl2w$er|7 +zeTOHUOZL#!`njfX4w311^mCqYKG{dp_2MS~46>bi^kR>HCb^&1=m(no+2kI&LqFj0 +z=aKKwVtsRyKa1?3oAu2ee=gZg8}u_x{v5KC?$*zE{P|=r&D9&4;xot{bc5dDiO(dv +zXq|qvDV|MQ=}!HqC!R;zXr;cpDV{~{qD0^AiRY34ZPYI|#dFAgbgzEV6VE66X{w&v +zWShaiPThL0$2OCHi_X`FnrzwpZhD74%CVzm|>PMPl+5BGGsvq&h^7w<)s_$%yW$`;{ +zi@wtn%jJ8hUBA#2%i%I@(=T{p`FtPE)GM0;Gx&Du(&0Fbx`f*PpkGIikeQ#4Di{C|W)AxE3xjaDE>6e-kIs87lU%%u@D!?Ve9`U*Sj2p5ti^r!5wGh9N} +z(BHEij&K24Kp$Z{oZ(`!lKz&RbA*eCM31p^&aj27rJu24hkq8COM|S~>7PxO(Ua_e +z!(T`i)5Gk5(_cbX({pUI!(TvZ=mECb=`SV?^b9-W@E4IfdX$}U`Yoi9USti9_$)G? +z4zUJjd^TA@PqU+rcp<5!N7zwkyoA{41-9D}FCYu)A-3BYFD5q1*+oaZh%BYY*+pmE +zLe|ksEZ1S1#plp2mg}_5=JoUh8*4GvoYzl#2VZE)I(`8D)S +zcG_Vp;#bpOu+vVPg)$d}MDcElMg;cMs=+v$iE +z@C9^~?R3V9`ARy;E;wRET%zObf-`2}Yw0wrbOdJcxwMy6Is>!$GWs$*#b +z$QdZ%tLX=fI06N{hK3n&28wwDjWg~D6!AJ5W84|A@J5r*o|+glkM_+*nlh5$xgWzcH*<@WQV*E +z2<}lQyX2*?7e7_)?ZzB%W1ed7G#0@fIIP+`jH}>g+^E{SjH_W6zNU`18}pzUC3U>h +zSOTr6spB2S0%$>59q%$EXhTD7`(i@SFGUCvA;?q+8WADrOS<>|3kpHWA_R#LWF`d7 +z7a>T5ATuFop$I`D1epmzuZs{QLXepdbejl4A_SQULC=X0Btnpx6G7hoPl``|#3w%{ +zKKc1muQ=%;PI^3vk11`#MmmIXo6waEB@Q4UimN5=b&61eiavsK^x`=q3#_PSr}{Ld?fV$}~iZon`8+vuQCjbdRW&m9$00}^50R4jiBmkKKv`7FFfXo2; +zi2x)3nE`aS03-mJ0fYjO0AvPGsQ@GZnE`ZA01|-A0Q#x`BmkKK^cw+405St;l>j6F +znE~{70+0Y?2GF+!AOXk>pg##f0+1O%X#$V{WCl>T03-mJ0n{V_2|#85{Yn55fXo28 +zN&pgo%mDha0QBVnG_~%7Pk)v+VRpN{MBiW|noPi)Ec+S*M9hr5x+Uvd%Bh +zqf!q4;#Vo&B9?W2nU-}uR0oDS(KxDj1yPM35wd<$PxL+#Q$xDMy3p-yQD+>KE+)FCZ^ +zuj1`$s7sRI+xVW^+%C<9CM;B&JEg_&4SYy#?vQHW7TlyZcS&_X@eOsNU78PH!R6{i +zr&J5y#Anor4rw8L4IfY^x}>G>UHn+BZP(_23$xYQPHhp~jst3KhjtZg!u4uxmv%Kg +zfUl}!?bZ>v-7+I(@lxT)L4e=IH^6PJ&fxqR$8aru}CL8d}bl?Xv11epmz +zsUif45M(92*RO~WBtlTzfKdh?;I>FxzflZvd?(TtGAbc~Ya`QrMiIP@ +z&qbyO3@dzu`y$i*h6Ucm%aQ4jQ4L9th!7+~keLwlj0iy+ag93FsnvpvpiXsY3t<~R +zs7`fhOJN^=u3FpWIpD+$)!Hd9g6-I&T07*c;3o8{)-L&KxF26qN89Cja6K+iM?2*u +za1TDAj&{gjj$7!zAwrM{L1seGKZp}SA_SQVL6sr|i4bHa1Z9d4Btnpx5VTQ*AQ6Jh +zgrKj95F|p7nGkeLgdh=u%!HtiMF2V?Nw~ +zYt`vaqZaPN=hW#AVqLeQ1{#`GT_ +zxpL|K{ztBao7>y6SdA-ON($-qti~O#AlY;=JM0RVlX7|wJM0cukqlbKcDTZ2q=eqe +zcDTcpB#*9U=UibcsiNOu=iK3Hl1$TCvCCgd3aEz_yZsd;i`K9ME`K>GqdV9Ex4(*{ +z(_*&SF*^xvaqzFC|5E18Z={D@YElV@F-_ +za$==B*->}Aie%DCCZdp;C=^NhLZVP&UF?^a_D>(bbm7YL!%Np1HIDEsGLQDN8fSPm +zSx#SJhaKTUvV{JW9d?FG$Qt^4w!;xFAPeXtY=<*kOjgq0vU84b5s~OIcFq~LkhSzP +zR_yT4B6Dew6+8X2$ufG99dP&y$zpn#9dPrq=BAcXB_?_ +zQb&)nGfuySG}4Q#!4aQD=F=h8;Ec~EE9hx<)DbTvwe$!(>Wr5VJH5bmJK_c6>DtuO +zb@uJzyuEnMYU1g7_KTPEiGz0N>0V13xskr0r~51^Rfy~Z0(Bb(?edW|ofLe|rt>W97I +z46>E}UO(&$ClfDyMBm{Jr;{!8xB3oWIF)Rq$MkdFa3{-`BTXTdQ?B-^=A@7FY0G} +z@g(A=LwbWZoqUcN@q$>qU}EvY +zjcH%d({(jTq2h^}&!#uC4Q^W{pGjA+(=MBpSI}MTwA)tAQ)mvWbHz$|A#G-L?pOuS +zrnT&dD^||SX)8P8j#cptYGpfJu`*slTi8x_tdi$ZJG1+$~I-C8}&!+~gRkG2X5aecHl +zs9gig@zrQ;uXZhD+A8!> +zdf>AwXMXUNUpM^zs{H>Spp^<};(flE_xbmW_xa*|zM1#=h2nj_c%N_PeSVF2pZ}M7 +zpMT|p4{!L$avki(x75jYc|L5wmFi@tTnjt#S#`2Q +zUI+yDsFPjtQrL^1s`hqc4!AK-wRake;0_#C?H$Hda5HXH?On#zunS*P$J>p0(2SBg +z-f1j>R@Bt-4r2kdpsbE}84|Rip|-UfbHRsIs<~wiKNRukFY{{l@&_+|@UQnhAHMd3 +zD^I`QGMv~FY3Y}X;S9bNX$i@da1mEVCi~3^DUE5GOt16BQuum0 +zrXTUfGWb?Hr62LdlDU_T>N~x$biRd7>N|b0RKAgp>leJSOumgy>lb{1B<`fWdZjmz +z#&4o8>y^Gh3csE{sUPwNGWf0Z1O1RMkjyCUs7=Ne8tn0b*C!YBS{;E~pJ> +zlWQtL*%06wc5r+M(6$;JTklH0>-Jjx{`U6n8-{*<(b6CAS#|dQ?tPx~$;oYh^EaW7 +z|6<;4Eg%b^how5LC1f=`&juXUBC-rLHsG|Dl8x{V^Ej-9!5J&z +zYvF71CiEjW<5*Z63o9`e_LtA$SXg7XH=auTz>VF$crv*Zjv8mY@pN(noHx$+Yzf=} +zeMYX=mclQCUmLkTTN3{UM2vB-Esb9d?-}DhTOx0Uhm7rBTPpt+{KnYsvnBIy!c)d^ +zuPvQl2cH_peX#`Yf}qjhjivA_;A`_H^z9=!78b|CN{odyvT!UcetlEo>zm<5JomtJ +z51Dh1N<8<#a}Swwk0W^Qf#)7F=N_jq1mU@d%(==kba$%G)l5QHH}<^rr3#t?)d +zNG1ejVhF+zBol(xVFK1lceIVF;25LA4lyFa*hjpl2`yVF;25LFX|9VF;25 +zL7!s?!Vn}Af^skfeZe80&XV+Xu~!v{>xW?E~g|x=y^R+lS08 +zG+QY8bicWl){CeQTO3&p)YDhJ-_Qr@#N=kf5hg`&NtTo`K_=12cXM(@wV$1a@+O%2QU1j +z=Ck=dpZt~5%*StKK|MR#-GM5e2}{`lSD=EI!)@$F +z+!d(g)evCZ9jN8Wkk6W2b7frW6D~I{!(RPG_Ua2CyfXLs+kv$GbDz(5efv9>x7x(Pk&qbb3JS(Pqche0o%z)n+Hn2R6orsvQXzjp_&f +zKQo4obUpa;pO$VqeDBmlpZ9isxjtfFhTksxVt&K4wh8sv{O`|ikIYZMJs+F@=&E<0 +zZ53BV+WOQ6x?8*vneA2=)9qqIWVTnWr=8+RWVT0LN{QGLne9_o(Y@kq#NKT#pl*>D +zvG>g$aIgngtiGaGTmn? +zv`d(gu5NQ7^@*BDms~A)2?xpGAek%SHKWNlm&9A(=f+X*TpDkKkBppy=ntj4dp$~~2ntj~Np-+idHT$HQM1w-nrpL@IIwhjo^n{s4_X|~<9yjyov@o^l +zNi&fSi5jhI%#^w|vbqSbjo`HriEAS_mf$k{i(H25Z3Ai}{VGT9+c9!u+1k5nm2JWe1#rQoad3V8jt9g7=k1Q +z$*eBK5QHH}CIl5>2*MB~@&3?rw_pgu5F`_VmSYIQ5F`_VuEY?8AxP%^p~o-;VF;25 +zLEpp>gds>O1mTS!3_(&Ms2D>Kh9H>`REi-8Ly$}ex(h=Ph9H>`v`v`^gf0l3_&s>=$|nJVF;25L099AAPhk=A?Ozc7=kba$%LRn3_%!zWJ1tR3_%!z +zWI|9Kh9C?*1Vn+86k84Hmi@2MghTO=`bZh5I$!ugUD!QgOeA`!$*U+9kMO!~L4feytVv +zYq(#N*{@CEe(kHVU;DC-@_6G$9OZ$dJS0YW{Npj4>54O5C1$!_Jy+|$a4tOmyW{hL +z`5QjH;nZJ0YL-E61gDYevF4EPz(Ql7*_uUehntK6k2Q~c7YYqevo(|40+$;ek2RM7 +ztTB!?TeHbsaJO;HW6dYugG{5YIg~+m!o^0NCzM0(f#t@*=1>;76Yek$dO~^RJ}5WZ +zn?sr8R=CD!_k?oE9@u1@Yz}1;749`odP4c+en>Se&HfB>6L<`Z$Dc#)hB{+kvp^4q#{P|=r6HCG|%SknYds|2U_=R{JmWTb}#F{5D8r +zsV-|7DF7!+bz7@Q1}tO)E^7rTgPYiZ+gd|Xppbc7)^bt;motysT1|3b4LjztR+1{X +zn;mmoYe^DhvN~6&j1|=%3Q;l^A}mBQg~*GA2n&%+A=-|G2n&%+A=;0H2n&(Ss~tzM5Md#bDMWW+ +zA;Ll=Q;2?xSB3DZkknP7YP>3hSA}G*3Z-KR!Vn}Af_7jC!Vn}Af(V8n3_&s>Xc|Kh +zh9H>`bQVJph9H>`^d}5K7=oli&=7w02fz9w@ztMS)M5z25F`s0u^Smox-DuuILicQ1Rh)KlO7AEyd+ +z##_`K^K~}|uIjkuf#-ies#em|Vo!K>M72^b&W2}$YAro4^1}9Evw;3uOoZ*DW*L1? +z>#az8@{|e)Nx@!}p`{{b-5zqc@J= +zp$8s%NE~{6Ckqcf@X$l%&|^Iwdf=gl%%Mj)9(v%Rhs>eJQ+VishaNJA9v@%`!b1<4 +zLyuQ61Yro02|?Fk2*MB~6M}v}Ckz-C +zuRn!c4#y0O&!0pthJ(gFuRo1k11F7rK7S(dz&@kZ>rW-EaKdQy`IE_ZIBcBo`qK%4 +zGsX#DJb}1j+-UU1Q^=KY+-UU0lSm63G7fv=X`~HK8;5=IMB>BUncVJd5|8Qem|o(T +z{?7@xJHy?X%)}B1^CDkFKVR#He0B7~M#V#3g$DKy*D_D_+s-hoW0( +zmRO-r^+(sz72NYp~#5O0P%g3)SvR%{NR8pdOKsbl&}@t7Wu>1B@T +zAKi(AJH8BqJ5JBvy(j;w8<%Ayr0ja4^FPiM+V$+<@*6MtZA`qOwN0wYbX;uEX2;ZQ +zdPp46W+&8idO+;aX2;chdQ_a%W+%-A+9&cf`QYL?p2%#Ux{B@3AqYc|ObANH5QHH}CIn4l2*MB~ +z6M}w%AqYc|ObFVFAqYc|%$xP!!w`faNG1gR>nMgG3_&s>C>KKzh9H>`WXBMMAxI_! +z`bU%h53_&s>=r0(8Fa$}3AiNQTAxJ6&&DKnE3tVn^Jl0$Su*NvnY|SQj!QI9&k2Rls4>FCq +z=1>ON2^Sl6o=^_C2bLQLn?qUTPPoH3=n3VK`=H!tZw_UWTj3g`-4n_sdtj4svN@DZ +zRJhkT=?UeN`yth^H2X8iP2e#s9)AwG8|sXG&HgNM2ecdeJpMd#FIbG$W`8DWhgPH2 +zSjbz+o*S +z%RplTPHQRI2=6eD!&*o#f*&xC(`q5>fw5x_YcW{~Pq1T7tCehlk6E1~R6rKN2&;33 +zO2}GxnH_Y5ipUE189V3R=yhb^0x&5l*lZ4u3Ie +zfWz#B({CkBaE3KH;ssSqTj3n5b_5FeLKtGz&OixY123@yjzAG#4nJiFoPkol2|i%N5h&z!5Msm` +zu<%BRGwui!^9G19?hIIY6U?zD$6Ntl43n%$=ES4N^@n-4wTu*ilclNEYyI=WIksm}~5c3LIw(Pst}8{Hy4(f@nT +z>om80MFG8wfT$v6QKJYPwJi>Xn1)Mp`Jm +zdgXw+o~{uu>Xk$47MdxR===NCwRE|7Oy57KZl>kpR(=0~x`A#I@9X=A)U7mClKa-n9@g6i)lJkQuF~5E)JEDU-q72=x`5t6KnSRWuY=dvQO8^nuZN$rqt3ZfZikQ9 +zUdLP^UkX2Ad!2I@ZiBbkdBQk^uAqu7MDc6d+s!As{J0 +zxCTN%Qh;y`gn(oKEy6Vr0+IrRYaj$91qjzb2uKPLu7MDc3?LoXKnO?*5Uzm`kQ5+X +z10f(OK)41%Kr(=K;u;76Nddw&5CW0{glixKBn1f9KnO?%(7U(>LO@c0a1DfjqyXU> +z2mwg}!Zi>Ak^xkNYaj$911Raw^IGRx)z*J(&!JxPAxdDMBL`Y>8m%oe@f`?h$ +z{wk6Qb!?x@UqQ;Do$Yh`Ye*_sSgXrlPAt&MTHXF?k_(OOgv(z^s$n-f;r7>(WXNTW +zu6P+KhV87;9j_wU(7+D6;uWM4I@w`&yoRJhHT%*Gp_;3uXT*l^?66u)kBcMW*-^EU +zo)&w;vm>gNa&b018&qrQd65^k51R$_*J2`UA2rM9dtyh}K4O;8--uVk_MllsKNU)N +zde|(YGa?$E9yKfIDWQg^N6b<>E6nh8(5#{7L`}GB*es+kiAQDLes*MjjDUz02;1$B +zSCf2bVrN|ON>U4Z*%^1dmM1_m%XQhxcmcRsuG?0{Ghi_rciAd<8Qjdq-L@K@0>x~* +z%T~@y;7YdLZL8)vu#O#f*(!Mz>|)2=wpyM9*{s18E8|7b!W!JMDxL-P?2s!~!7HGH +z9s0@w8o^&61SBzk!7+lrKnO?%(8c%*gn*;~;V%#Zk^%HG{sMhT0B!r=?2XB32?+^z +z{pkNp5Blrupw8JNN6#C{_qpO)+oYOI$HfM1c1+Ethr|(Wc0x_32gDw2c3jP;N5xrf +zcG66seIie@kC_=XA|^EZgqcDg5<4{exS2zr60d6ZNi&HCg`!Q5nOSs7M78M&GmY*S +zsy01t=Fw?kYSWWuA{`PnTGyBD +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 +z`#k +zE@&_gH^;L`2Xq>TJ@Gu!1=Ysx=6EK#4T!PZ6VD|9Xfn<;$Fs?|VXtw<6VE3PK(dkB +zY|G#`g4@XT*mC%HV6idYY|G-e!_CIH$Ck&x3&qCvW?Lq|1+Fx5{#Acx-#ON|4~fh>Lp+-4l`1oHU3 +zU^Pf{Ad|O)-yohqF5e9{gEt4Vc_#!6?g`}cy^wD-HP2=6o8eNU$upP3cfl&-X!Bea +z?|^R`M?G_SybEfLz0Gr({5H73*z1|gb5gK&kjN0bt3h!?`yL8XfRSu6?%hm|7wKZPC+jw%&Yh@Ii!h*C;_E8YzU +zgGvqkS5Xvh8CDAE{}2y`TSk>~`oF~$;g%7_LjRX|J=_vhs_DOowc(jzrI`M+crrXQ +zs#MZHiF?8`BZ`&&UVIXs2`aVpFCr^kKO8NfFNo1_{b;m|zAG*X*N;R?=ZdJu5bcPYp+l>8pZ09FS@Tp+5mR=BP +z;mTpPfIcqPwWWWN6ZrX8}Vw` +z9yF`yr$Px&51U1FMnuEYqhnl<#Cs0nusn}zfx@o2bf)GVhT +zi0i{$Bc_GM#arR7pjl1l#Mbb+VY8UNCY}kO8#OEGN8_%evFai^`6Z-n>Qc89HyUjz@a +z?M|D8uZQ2T;|^OfUkOjK<4&8EZ-Gx)gCkbJ7eSCUIAbMzEzGb(j#v?20aNUdGgits +z!ztG3h!yfBu%C50V-~&vX4z>+te7h>%}zUGR=yR^v1&)4fG>n0R_zRw@HOxfJKzWu +z@#XMScEA}Z<(uFGMjU}cUI!sYoB<1OggE1lKrwHC7~{@>l{dj0YjVsL@Wn96nw)bb +zd>y>TjymRwcs=}_9d*u?ayxv)_B!SY`BL}^+v}XOa2veM&O7Fc`6_spop;Vz`8G&= +zbLae!vVb~7QY5=qSw?RZy^-u55;)O`CTUkWEAr?h~y~+xDyU-)S +z9%Tu=TI`Gj`xJ$KSG*f(=~fofW>FMr=~b4~Tf~ErmL8>!eoI^tY3WlMD2Uf1Gu_H! +z`c1JmGSjQn)4Rlzk(nN4DZNhI6Pf8#R?+W?Pa^f*(FN2cvLf}p(Pea}7>)e*mMdYz5mLFphOHo7=k2@&BBW@1Yro0_^gIwDTW{nK{6reRSZEG +zf@DGv!4QNYNG1eP3_)L#k3)S$Ll9sH!Vn}Af&|_O!Vn~NBPba|5QZR`5VRCS5QZR` +z5VQ(I5QZR`5cC#?APhk=A!sj#APhk=A?R}qK^TH$UJd&f3_%!zq(Tth2*MB~6M|MJ +zU30Vs-vxAOM5m^C0 +zV+Wm~QnDHT$l4vDLb3#Y#M+%93)uj_V<#PA$NtNF$3E?*|B^fQ^Sfqlxaz`3&%QtZ{`{GD-+KmMI{feW(&2MAVq(O^D3cf$ +zVq(O^D3ci7PvA?3U&Kp?4{VI3SFTP-NVsw4u74jW^l$&1K0Q=p6w|NGd(k)jE52Bd +zFV;)ESpN({AOs`>=ywPR0m%T`gn$r`44|hG5CW0` +zbT0xzKr(g}8?$>75)%H@{_o?1rcdAY*Z=pNu6{pZSHCk>MG~k*T&1@SsExEyyrH)ZsZBIj +zY|v->)pfK%9MNY7RXeQ~d-T}>)kd4dS$%d$-A0o|o^J0qSJTB}Lbnf^8)>oFq1y+{ +z^>m$hRkshBTWGdW^yz+cEv*+(eR|N`Oe=+|PY;+Is9l))^pLrgri&WAtKVEhm&$yJ +z!?@=!4~V2lcCWIG-Y9w_**(fd^fKX!WcMj6>375nkzlv7h<-yXiUfO=74&wYM}j@d +z5_+}R8430&3jMBlH`3CrETqk%DALlaET^}K2O}*#N*(={xFXWhr!-IyuSaIOmBsX% +zVr^umSE;9Wi6bs*0s7qu;>U*Qh=uR;jsqcwiM6VE+ +zMC$vZE9pJrmB>_gbP>HotcXnYMpw`~#p98wp6C*Kt++EX)fZLhed5DNM|X4~^@@r} +zM{jgFy;VFC>F9~p(W}I@k&eD-1KlIujGXF@F8-n>m|t*zZ2(=CaA6ztuvDkDgsg_= +z*?_}ZM3#ZZ2AtMXvJu{49*4D%Tm(O09;ekp)&pb59M)p85}shkoK`E@0w1$F2Tput +z+nqKGUk|@w#~rp}z7n2d$DKAS-vXbq21l%bFM=RzaK=jbTA0_`CX@u81@-KZD^|fP +zpo1N9$7*;QRI*N2telrZ8|!q(s(BvR*=bj-lGi{NJME6u@ +zCM;zKT!9K+4!5xb?m!Js1uG-2KsmR7pAmPUn&*OzaaW*{S3`htcc7LhLq2PA&6V+D +znHj>jry?L{+(K-?*%?Q?n5=@M?2I#RCEMUU%XQca_yXu-xlUUNUk$%z;|^O9Uj`92 +z?zENijqo1Z?ywc|i{QU4pgIJEfF!1v-)=!b2uKD{BLYG|GJtXs5CW0`)PR5xkPM(| +z1cZQO05u^X1SA6}837?689<8>5CW0`RE&TSkPM)82nYem0Ln%{2uKD{Jpw{NGJq-( +z5CW0`WJf>E{+AQ?az2nYem09uBCz5qbG +z)ciHw%N$9mOK<-72}1wxKd&vBo`2@zGY2o-_e|iEhxN8Wb<@{kj?i;!{xol-Hd`~u +zjo>s=J=PrZ9av}#G+VRC?QoMZ;IZbB??R#BX|`sPTi|lTC@%VGd-B4%jYxZZ6JD}az=ke!}d%p57Zlnnqyh~PUtWWd186|KBzQ0n`4>$R%kOiJ+WNA +z2kge_=2$jYq02b!iRJVAA>F8M4rK6~z-Lr@0y+F{SZW+-4rK8=;5OrcCy>YQ1*<`t +z1DU)X{08v^a`|qs8N4}=%{w7ra8Dqg?}dD$sd+Ag-wc;Z4Lf`9xAR)|uu?#u6TRW= +zQKgLjLAb)%BT5N1#0%l!%7kTpF$4@N0kaH#LjSVL@A}e74L?FL8XTN +zt0)S$3@e57e~1UeEu%^~{omq>aLb5dq5n&~9&QOL)%0J)+VISFFpy+1eIF)7m*dNAC4B#7sP0|el%J}-xZgH>qnv`^mXw{xIP%IqMwKr +z;i=(h5q(8G9-bPFR?rW{o#CmGXeoVDd>EbzMr-Kjq9WWe94(|Tibuj7qtSBuzPL8r +zF%q@VH^iIaj$pK!o)w$Jr-q}&^i@H_r$(cd)D-uHPmM&a^eypu_*5`jOD~ADaOJRC +zK%WOJ6YAOAl +zct5;9sMgTWL}|EfSS_T-#KYmXQMH_&6jz1YMpO$uA>IhL1=VVLMr;Vr4y(oVxHuA? +z9aSsoX|X3fJEB@C7iYt>LA92i7kOd(uvtKVEhfVDQL~J`Cw7GGBW4Nxjd(R|51Li< +zQ=x>Xhs`27BckEyQL}=c5^8vQ#4M$=!VFIb%^G@6)P%c+%|iN;cr@HKYL?Rv#P#8> +z5z|8B;;nF3(5$9&Vr%%^uvtuB6VHUtjhdD8BXNKD+=ywVZ;K1zb3wC~CM^BMyxUqp +z7T`3hzx6Po8Ft7KE8;6)iXC#sO8I6u#X23aLcRp{vrcEs!Z*MyJMD-Sa|Nc^X=lvJ +zx57DA?Fba`g)qdboq-a*23}$Z9DyRf9Dd3UI0L186MVpkBT&feAjF6>VBw7rXWS7e +z<_!>I+!?U)CYWPQj=2K97$#YhbFPH1gV)$m$6OJwho7^f&bd-Y +zc0}xb=1RItyc(JAHW$$rp+u&8%@wpmL?hEZ<`UW_)W~$7sn9NAM!LGqh14f%B3-@a +za(bJ1G}6^$)=|H>KGM}^Hqd~0D{`*eTud(&TO;Rs&3gK6@l51gkGYiIAnuQx>oZr; +z2Sn13U$~G@9MEH=daWtsGI-ud^;wh1H$XE6yw)^wHN0aC_^gSf8Gc}Ryw+6mEntSn +zXH6#GgeQz+UTZqJ4n8)H`9cZA1tUhCH{izg5_j2n&KcnY}^ +zjvI}>coJ!WL&jlmJdL!$Y2&ajo=ALfz}W4LrxHJKW4AA!OfH3^#u;xso!kKDjWa%5 +z0(U^4k?Xak@XO%WMy}76#J>R%W87;?<5$Cb#<FG=43dG7kA-iQEhOjZSYY +zm0tz3MyD^9%y+=FaoQV8=hwqICjVAA03cnIwGn#yJNxTJq +zZXET_rSUfS$T;eoOXNQIiLuu^m&*O{wz1bYm&`APXN~jTxpaO5%p0j2$IsW&Zjq#A +zk0}{6EPA!<2_=PoU%0gFaV3ZTLcE}5Pbx`tSS-?lV@ekN2cc`h2_=pGQ0&x#<4PX= +zm3UVRPAZACUleIAV@f9dd-0&wGNGi>zY|wzE#pcq{iS$aYnfD%>6lon&5SA8^dH5O +z+RTKKPJb-!(PqY#eELt~6K!TPnm~I+mR3I&&7is%)#@jrDfB^ciB>-z&7n_I|VW*;*%XhckC_6akEJ|uQ%_Hi?ZJ|$k&?2~2^ +z4GKk@9y7D(l!$866J{FSFH~)M+{~lX!qlcG%|tpRYP7B~Gn4*QJgRj~n5i@*uGhN8 +z&0HE2Z)shVW-^@=TeWjzW;Xq~ct$%nVW!ici2Jp3<7Pg6R$S1szms-u8ziz+m$i%( +zfRm-VtyLrg7P0}CwSttvO>DqztsyB;$UH7RAzDc%Sa)3n8od{BAHOf_PP8Oq#WAWKDWPyq=JRDy8PwD0{FS5{cC!<1e=SLdT-NA{myu%F&KlkEDv}Ki?650dK`Nn>9d^fSNIF!r +z-L7~!u>xVc-SKLY4^8ZhD_%)zVJ|!5j@R-8NM^Y%TNy6^H_LU~s(1!0X5%hf1uuh} +z*|^(Q!&9J`ZFkwqc?n#}w!3ZBJO|dX<1SkzuYz6dxZ76ClOUTlxMF3z2wGT!J683z +zn8x{sm1iFiNqTm_vYIXsy?XYbvXK@Dm!3VKtf#BR3wrjDvV~@dMS8GbSxc7*T@MZ_ +zn`xQYsRsv?4RoV;R}T&;TWN|Y(p&nKHS{9!px!d5Y@#LN3cY1OX{77L>w3$O(nNE_ +zT79NpSw~ljC-s>@#ZIflJ^IXmVxwEcC;H5gvW+H*EWN%zx|%K$qk8>dbR#Vim+18a +z(e-q#ctx)tif*Arv{=nx>bCx +zpBjp8qlqF-uk2S>(}iMCuN+i2(n8_YD+ko|bd7jXuN+dh&`hyJ-`}sUrOU-*`u;(6 +zGc6al>iY-O4Rn)uU*A8ZZl$TBRB!87*U&ogbqYb7Fa&)8L(9KLA?Q;KK^TH$LXZ_h +z&{8*7lp3-TSlSz*Q)2Q`q%jj +zYvxbSe|zm8j^h6QYqq~H$NfF-?eX_qe}*RPP!zH&Ls&Uhf((8>vmarFRXP +zO*CI@)z9^t>*y-+jDBv=w9{H~zkY7Ow9#$if_`pDd9D@r_qe~8`Knz9?(cDbFSEao +zKY5k^FB*iR#L+A*WL9WhYFqk +z{m*a8`eD)8(_7$E*5HU0@I?@04bE5zU;A~rlK<#Ucw~=9_7bxhw!DN#_IPA3ab*A9 +z9^9$nPEBT~R)jk>+^Naz)GWAD!=0MUPOSrXYXA3lYPNj-J;*j1nqwJ!C$tz}r`ZfP +zJhI0ldzmBqZ{v|Y9@)zr*}sJ$2t$xe2>K@sK^TH$LeRf3a|uW36dy53kt9VVF~)rmmu?5$E%;?r^E5n +z;jGC$SH-ho6+7yhtKgOJZFbZ>SHshxmhE-Tm2)fH!1lW5s(C(aW9MCSmAn=nVCUU) +zZwnNJ4>75S*fM;G{Vg71=KPOm`*O79ZC|tR +zXBOnl*V1m0q-BpO88j?>q|(0=S7C>a4EAQ?c#2nYem0Ln%{2uKD{B?3Y~GJw(%5CW0`WJN#-NCr?o +z0zyDCfNBvC0+Imq{R9MrfMfs_ARq)J11JLlAs`t*We5lX$pA`0KnO?%PzeJ18vr{0 +z!S8E+G2lo@NI3gs=j@SFxBc4)p^m5iZIsaO?f;zkeny|Vm8ObPy{%teL+ixDdfTA7 +ziCV-}dfR~7NE^i)dfSlNM03RkeYRg+M;pWueRfc_(`vCtpB+$bv`L)RXNS~nG+E^7 +z_I`6UT`VSa`=Ggz7KoZccHjI{J9 +zb@W@}ibzYJ(m+AH9+~M@7SnHvwUL=#rJmj;o{Y@&C`;*e;-1J%pR$U6Pka)o?~X2@ +z2{2$-y#5q&IUF-AK7SIq7!Dfyy#6$D4V*Og`TU8*1N)3tuRoQv!U?0*=T9cv;jnSS +z>rW>H&KM_r@dVEs4DZ=CVj61W5Uj9jlRgoME7~@`B +z8owIeGsbjSYfMfvWAs_@K184^VLO?Qr6a<8TWB{oM +z2m#3eszE>qNCwdL2nYem0NRRx5ReR@`w +zvc-v|mWbpGhSpLMsbHopv(?UO#GDXaOB+$?DcveM6>t2 +z6g*vK +z5Xe1{E0EEIQ0|TF0iQ+!ITv{YIgNyJUt|s(=_rBG9l3xcI!b8tLUv#%T`w?tA}&}; +z*9(n4$O`zj>0?;59AQm7~0CHym`Y!CZk(&h+TfV_oq7m>P8Q^X#C%e(HT!$0p&?;4K{- +ztM7yQgEBfePTv=e0FCs)SiLg}1al<`fIn4(}(!#|7TaVexQJMjg$2y +zhJ%ar=2)3CF&ONoH^<4`h;YzOC&$X12tTlyPL7kg5+R_OZjP0?5W(OC-5e+55K-VA +z9TMBphZq1V=#aRUzQjn-M4yOlaVCPmLHa~oiyILMUecMdElxxLsG&3CT3iV}K=ixV +z78hbDsHfk>wQz_S&_&zF^828#Kpt%$$M1`Vf%9}lEZ-Ro0$REvj_-!Tz#}>#mhXfH +zf=zTn9N!g<0=Ma=SiTDy0*=v5aeNN?X9nmI3lIyC2`A9FUs!-xfJ_1CAqx--kSPGM +z8HfeQB!Jiq!~$drK-bs|!~$dzKx_tL0Wt|7HUqH$nFJ7)MGY|`qNdU1Khy}PC-qV)?}6e#5#=qB_d*lE +zWy)JBH$!8=UaCeSw?xyxQ>sQP?}@}fNf8pc1xf}j6d{$HqXeL*kVI~U2wo3dC~*yRh?VKcQ|InNrZaIV^}lGh8a#{#uo1+OtR>5i8<2IV{H`)Q#mlJNP|5s&1_0S-~ARL)}=xbA&(QH|oYJT@RRxZPh{LI%}xGrRtzc +zT`#y1k5dO#=z7DW_?kMXN@oU3aiF@cTxSap-~;NqN}VO#ju)%zDs&DI;^*qRDqT-l +zh&|P5@R-vM&GyRO+nYPP|&( +zQK55$r}0O1M-|xv=3q-Tx16+wYFw!1R+7Eo1}sr?E6CpP2)?A|R*`0~1pBM2%Sl_f +zAMa6DSCW=+8=kMOt{@%YDf~oTT}AeU1=vlUQcl{y-FS;SrINIOoADHNN(E^TPvAT1 +zlq%93R^U)|YdL8L58{*R)=JU}*5DQD)(X-Q*5mi;)+(k4%)<`q$a2OSYH_7HvXbcq +zH{nEeWChb39>X`(kyVTtEW*n>m{A+5n4Yi*`=}M= +zj1An2cd8YYj0IHUnQBD^V-NNCfm%_;n8PX@t?n#m?BF4MTHRU6SixGnR^3^_IKl?} +zNo_}Yb;f|6w1t4Zx+Zr +z2@jA;Zx+gY2n*m!CktdAgeypo&h@CKQ5vry(sm;-w{M9|_+xPSyY +zMA+g**nwdBgrLQf;DU7egs{bjumaw6rl7@x-~fWo6t;L1jv$JDCurdkz95T!Cv5RW +zJ%BlFFW|eQK0rv@3;ABi8VsN-1bk2A4(8GoLcR~`1zhL^0pA1l1(WCmA>SMI1|#Vv +z0iTP!z;e3jpLbrc%Hn-CHq+SU^M=8%aIVI#kQWB~V1dT2fHw*b!{;=1MZD3_8u!?CccOl1$*NWn#O$INH_!^)if6JBB2+~&@>kC_;56SqiHPS#XvJ`s|m{24TJr0 +zsV1mU7Y3d2I89K2ZWJ7WuW5pcbfcjy4%F1;>qfvpd_YrIsEdG}c(JCgKo<%l@N-RF +zkuDlqVoyz4zHT`5$J;e&g}QL)hNo-N3Unbb6yMjR73rd&1CG#iE +z!K*bL1v);A#ve5uMYe +z!FMz%MPwAT$Dx|md~zfV#wRtcg=8f3#w#?f1tcFv;rE)>A~FV=V+T!SJ~Ipsz?GWF +zLM9Bl;6zPi0W%7Y#5XjNMa*buhj|)9J~ILaVV%ZM$V5OcCN+ivCKN_uMq?;qqM;S` +z(J1nn;V{6IiRH2JFS;oU5yzVN2Efq^PKa9^2nFz_GDR&m!~#H2nc^0ELJp#+ccK?R0z^_TMS43#0tNL_tan6fffeN~l3SzMKuURw<-O4|5J1(4 +zxxzd6zACLu=MCTE2vtY1&IR7UP}NbY<3a|nR&|uC#0iz=m*^nmSniYldqbcN0Mjw+>$^oH+nsH(M? +zbb(Fyq^h-)!iy0Sq6Q5RfmNH!U3a?dlmM|RHhCit~%NSqSn9%!E;9_rK{b;(Y~Uv6wXHd103`4V +zZEGGm6lUS~+Q@axS5Sx@w2`^YAUGFSY9n))fp8K|)JEnpL*R0JLu**a^oQ}7r#0j< +zfiMm0w1ynUAEsbZYsh1GP=Oh(Vja^DO0kbtk;@E*3-C^@B8TyVGCWhO$YX+`96!)@ +zu44wkBpj{n%w>Y$QhZw5nZpFYS$M6sGmjYxv$5Ini=P~cSdc?mNI1QSufbW$Ldr2C +z#sD={AmLaNQ^BuPft1se5P=PpSi-R&CIgxhOF8DmcyNTeDB)NUGr()=qEy*~5P%ZO +zPonHaOaxacKdI7;7zg%KyCq6XVmf$6?UpKg5)!bDN|h)rh$-M6l`2)56N%sy)h=AVCF5mdyAAXWsKB7%Ha5yXlh6P6~Z%vlk{iXanK*TqU%5yXlhQ$$cA +zD}q=NWQqu?VMP!tf=m%X@E;LD-7S8#KCiOZe(L_z-O>M-ne3gO-wS;W&QtbMz8M+= +zv{Z$JZ;7UYM^uHB-xGA!oY?`k1# +z8XLMEbgt=cs2n<)`7dAY%WjPNKV{_@oXtAw|BBtv|Fn)8TxK0L>!?j=R>V2~?)Qvs +zR%DwM|38`)U06rWI%-oKHHUT7tfMx?Q7>g3HS4HNan#YQqh=koDULdeb=0h*HpNkY +zWJM4wf=p>v{GAm+tOzni1i7zcMG)JpXhO5%us*B^VnvV%BIuhwtO#O7kO?B_%r~qE +zVnvWCBB&oLf>;q`iU<<2BIt{YpyS=&l8&L@^yty!%$9rqYN}AHW0WeO?|-L<^|L>) +zlNs2_3?@uw_>~2S1;`YDoLGQZfJ^~s0}BufkSPF7U;$zQG6f)-1&9U66o7`a0I>j> +z0?-i_AQm7~09wWZ!~$drK(ASVSb$6c$c6=o1;`YDN?3qcfJ^~sEDI0|kSPFNWdULV +zG6kT)EI=$krU0~`1&9U66o3}70I>j>0?;!SAQm7~0Prv_ +z1;`YD?y&%|0GR?%I13O9kSPG2VgX_SG6kSjEI=$krU3K@3lIyCDF9ip0I>j>0#E@9 +z5DSng0Et)Q`LO`80GR^NZWf>~4Un;Rxx&({SFGEhA5Q$M@j>rr +zeyi-B6?IiaxFr3yM_pY>TEcC3zPh@CbbzPu6LobJ*%KCEH+4!mX#;oTE$Wm?(gJSA +zQ`9LHq&+-=@2FF%NOM?$L)ES2q#ZnnPpVrhNh?@`SEySnNJm(Y->X}zm>w_>JE$Ye +z8EdG;mFmb!rWf3V6V;IwOmBD$-%v+ZF=ns~^VEiN#unCLo!U^zSi)*dstpy412kYp +zZKz^;!XoUWR+KX~rcCQR+?$=&$xiDuWm;!AJFSzQ)@jPLPFr?b=a>G}@$LURjl$c^ +zPU~c+b(%7*v+i)Wkkg0w3gplhah$%yFmRSGh~+pFgMgYYh~u~sVc=Jq-QNrHX!|&R +zUo;Gyrz>Ll&S((O(iL%hHxvdQ(Fw79Co~Xjq7&lyu4ojvO*h5zUCLdfbJ_j9 +z?Ec=tZ~@+_Rpc;!P=;q}6?sfBl;a25&UMTHn1rLXow-a9T#8R?J9C%-I18`UcIGid +zVKz4V{w%w{m)+lM!v5Z=W$fA(c5RCZYg-OGup)>RL8geHC{_fqBFGdGWXXykRs@++ +zG^=1m5G#UA5kb|g2>Rk{TmD;#piou>u_DM65wwIAL97TeMFia~WknDxf=m%X_N)kE +zMUW{XD3TRHtOzni1UaxGh!sJmh@cu)1buN4biaGXr)j@_>TKy++C6Ke_pARl%^fRd +zv&|j<3C$hdH!FO9Z=3n;AFA$I{4n!ZO(MP>S^}0+O=7+yS_AB;V3FP$%>nULuvp(4 +zWq=^+ph$0v7K1eEpjhvKRs$}TF4Ehe`5=W#7whfO3J^)X6zS~{2^7>zvEC7_1y+=| +zNN$a011aS#miI=>Kmb)ElG~z1U;$MlmOG$TfI|@?xeZDMGKvt(?NKJ+Q%EGYL+Lz}3ZmN`G(g|L~ +zTU05fqz7!rQ&cG>q$_O3cT_25q&IwrLshNCqzi1qCsnPbBp1HKD^#r|BnKk=Ue#Jg +z`ob>kpo%PJ`oQzJQWaUsxWh*{Q59Lj^o6(a4OL_r;|1Shp2|?nIKxJ)QyEGbPuPJ; +zm7#=jgRPiR8Oj(R*ol2qieknIUdB63a?}deQL~QP*cXiiH|hFVqcaKuhv@n^qZ^6@ +zujs5;qZ0}MwRBdT(G~GQ8{HLabU{Nw1Kky8zMv99`m$@TqY2vVV%~H!}!A#Oll2z3=b+WqgAY9`avo7(JD-G)GyAn&5CTZq6y84 +zcdJ-O%{pom9QC(7SVzq|Y7-pwFJG~answBsIO=|^qh=koDUSL)D}q=NWJHX +zCbEDT1xMl=n#dw%G_=D!jUk^I0fVqkV<==IAQzJwLje;CBQc{f6fx1z3j1gj`OI(_ +zU{Y2Z&SoVxE18m&9tOzn?!p96&1hFE>6cO}8IV*x#5oC%8viMgbsPkr2 +zw$t+lt_tojS1CWK(u^1f_EWnhN=sroct-7(Dti(Vu#HNUC@qL7 +z;2xDKRhkot;1ty^QCbl*!5>t+RMvxt0|k_;MAnO#04`FlQkfYs7VM@rOJtVBG|*0M +zmdbh(Vz8M?mdGrKWYA0{OJ(Ln0ysf6OJr6A0p3x~(v}{C5L8ehl9pb?B+x{KNL$Q^ +zcyN$9A!)HBQou{S8$%yA^v02|6rq_igHfU%UHSlOG% +z0E4OBBBd>{7%ZZ8i7RhXgRFF(1i)HpiCJ3RLMKU`g +z9b{6?Vwoe61?;I1QHwP(7bH+2;+EdTau7_N5VhD6X&{|CA#QOX6u_Ix6tUNPldkt^ +z?Dd|#-kWm0Z#lwlasf4TW?YLa!3T(b7u(`O3&lxP#er +zfso@v^a4(_Sitch`hp3xSjh1vdV}HgMFEFPc!6c~MIpzRFatKUpFrtOID@gYpHS&V +z*n+|IZh_L1@C1wK-9n`gVF^6wRDsfia0AomRH4$FZ~)brH90#=Hud +zW4>rn?80%c>hlKW_qE=&LEz%*>gsCYVqv7VUhNn3%Zro7Je{#GAg)ewI9ki&cE1A`RulhW$noBnc=h&8L6=cw4$T(nc3hi6_v|O099&*7jnTnMaI6L$L%XT +z(Mas3QMjSyc&AivjqLtq^fiYL78;#lJDw>q+Cmw9FxKb^Tj=_~reX8x`T`~$yizGR +zNP!!sfl+G$((m)55mB*xjHg!rBqX03g +z&ttTG>8||G)BM*;jCODqogQc8!h?9N^zT@ba2IcAo!LL6zAIbxvGajc2D$tFBBk(m%P?2slw8ep%x_sRT7>EyO>I!uc +z&=W7#*a_vHa5_$u$}QnYx~70x0#4A)adHO;@pE-um98f&#OG+Ss!YTw;CT`QKm{EV +z$H~(ThV$`uZCZ}b4=$%`igd2<4!*BSE7N(y_c%h;QT!ipL6N@bYrs(%`k-OpJbh8a +z&EYu^qhT*lf+ZSm0nY|41am1rZG4=vlxI&wz$17Bm8xkJC@V-W_!|4Gs*6cySVkpC +ze5gu+%sL%BcEM(gLba;EzgKnIp*H+p +zV|TCkZ8!CAD_#Yfph8_3oJ4Pql{piG!ESnUoXm{~2kmrntjvk<1DomOIGHOE0-EXO +zSeXmq4sTP<0(k@+N!64vL%;%UU4_m8F8}*}L{25oj2H+90UCR%)5>)=(EabLVl`#V +zXw%wV|G@GZJRtjyuL +z5N>b@ctll5`8|;cY@&$2W}cPNL@qNCOrnTFCIiS+)uqfhAX6JW(J0WOGPt2kyhm&B +zLH3{bcrX%hj6(TjD6FPYE;9uzr%)lY0?1Vc7eru2B6ozRFe8@x!cIDB9TNu})e3hs +z8dRwiebHR(BQ^Gd0d!Qs=aFhVCC1*c0PhqVz2H+iSYR~!+fEQh3>vBWd@>v=>H1tI +z83a-Fg-j+`s!Azg62MZmf{P;Y1F_Ku8tH=qV^7$OqeVt1SVd>$GLt|Wl~u?r2eVWu +zWlTJnrS9}Z5ui=g>4xO^j<(YWIey+R!bm}k`t!uLTDmKjk%1JdtB?$WZFIU&?~NQl +zB>hrgw1NnK66vkbEc{8L=MYz_!nz%aXz&N^8Y}BV^aBO7Yn-evF$m7VrP@f>f4G8L +zppLXBg27&Gq&eD#ZwTa}@IHR7iu`{xO8<)cQ({e-fK#D!f|u}iRasn1Ut%O^qEE!O +zIHObehR~#D*P1GF5VWI+V$vP{is#T3v792F4`BvHU;teqQ09}P;BdT=-mQukD+_tv +zXe#i)Bj{9hqlE8(Rst6)LBzK~V(hOqxFbKz6Z0)lD&|S$7H~h-iR7-Zj!qED?O_^C +z6p<0IgGTE}OSlb_f2|ct!1J{R4-||^G2aTMV^S)&f{`>TU`Sw8RhKa{fl+PnMdsK? +zWb6Zr=q91j8cOM?LS`9AQYoC#q|fUdm_^{GDy5j225zbqKBzw!s!Ay*ZQyP^Q>5>W +z;_()(!UF~2nPR;eO2adyMoYLEKM)z+pq{SJV+im{t?)&Gz*m)0!3cq`y3-v6;ApYl +z5-q^dQlkYtflrH!uJ90jP-wJ=OX;k?X8ygRyVjBBumZ0Y8C^bai|F(~L-AU%-U2Pf +zCpDekC=|5PFJtvChzGJ&trbiXP*7b3%u=AB3;xV!k0th4`ZC9o|Bmh=o-h0p+p2#2k-%PU8T+v +zZpY`SnnIl$yiM2SFyp}jbtLz5zkN-fjt5uc=i0P&x_=8qCmSAk!FZQ8V77Hdvw)SSRFrqj#8$<(s4NfUl`8VEn-`8kI9{K(DFJV?u#m +zYcNMOm=VbNP(d|`HM(6PpwW1f&VjrO~3`YO^DI#LHE#(uDh$|`4EK&>Vvj~NMSwVh^YI+&&Dv_&oWj=Iwl>G5fy-Uk`+ +z+E{&0Bmps+P8;M8s_CwBh65Tjt+@;zq|jZJf4@>IhI%P62EZu%Nnqr|dMpTi^k>Zf +z;?0j5m#Tv*naTg~Qw>fbGYXubYATuDV1Xvm4&B3xwRL%n*Wb4d6==(1IVC(>Vic5M +zPim)tDD6?+0h<#CtZ$@~* +zmB0o&(-k7VE#VAld`T5AQRebo2~P;XTsl?NC{h;ixF`%fq7!2IPG}(DsH@AFIY6m0 +z^hJGvQf=@;u6U2e;Ea;7PQtfGAy_Atd&6f~CzYFj9wBRRLPG#wU0uP<2YQvk6?p-@ +z+Te}6F(Z<5pn*nz?ITjqsEAn$994=wNQiwTd`C0@`-qM1@G>2h!;A$<>gp=8C)`U% +z<&pj10y?UQSp~|d`gMOBN2_o`BfwB~N+pvD4yhEb$QB$@E4&dGPthn`Pzrt^F*-mw +zU0=jxfjTN{9T@^0>8yNaE~r&?_C=ncR^91^IQWjH(;3O|X^Gwe@$qS~@vlW}r=>>o +z&!cTSolp`ERkxNi3qXUa(-paa26byGBL}Tix>RqD5`ls0$|3nMhJG1mYfLk7YinkZlvgWD95$FM%&-}-=tU)W=bJ(j-Au@uA}OYE`qWi(|9t0`Gc`DHZa +zANEhX)s02G7-)uVH9`5hVX!|g)!6-y7t(t*K{>jCa3UV34a(CEff@Lkwr-uSKOBbx +zwRO3=K)4tm(AMSX{NXULS6x@Y0I)z6>4K)=8msRBVb>!AK#*OYq@1SbHX1E0r&7FHMfd1gC*Es +zZLmi307q-+g?8gTDnoD7j&-qoSF{=H1o9BL28jmns4VALvlpgim&Fb;#Ouuq(E5WGx9RWddp +zNu#j+yzM%wg7E-$bW|A=4sL2w@)-+IMhC~~`=TIiF +zdS_IP9|(-0P)^mCF;U=^Hl=_u2X%B-F*5-8YCC(Oz4(r*vp0H*Psi%rkP@F37(-wt +zJ{@NahOelDQezbKrP5>dPN)j66?|T%9i#2EK!@;2Ri{0g0vfb`w`78G1O~dRgmi=r +zR96K#6s|wWYD!j9ej!a+$!bbgQ+^pu8Omx(R#Sc%O?i^ll&lZc%Qv515N>)j{PtYpB73&rkKyemqVURHEw(Z{cgIpfa5o +ze1ij3b;UYocnu#=)s^Zz;d8uLRae66jTYg>>PTJCfohd&Jw}k8q2Ldf!5vMHYSrCD66nKU&X&PgdB|JMK +z6fVR6_l_c-fbW4WVqTnlFdU3|LU}k0q7uY%KUhZ*6{IIjqlhvl0^FvFD#j9wq?$zX +z0dN{71$-`Q!epF02!>-)D364Z6e?kOK&~}dp&7uaF*u?w>=SGJ3KmgO<)jakQcVTlCbrbgj_-eNbkq9>XI;;CSx>4c=cSc&}iCHygaaOz?gaz!u`zLfn@r#3|T9 +z99xL{LWMXx)(5aY;LG@chGpzCCiWTAmwCoi#unn(LfjWA#C=n^qv?OQGnYT~@tGg@ +zZdW)~iVg2$Vt)IWpZ$RI{_-^xQgy1vyrU`d#_9minnatc-oDlRlP`X*{gl%Z)cy(8 +zRQpQ1e13I5#JQfu3Ht4(;adLeS&j&r5d@W&bvwD^L7QXM^0`CtG!k2!3?{u5* +z%B-)Mwj_tabn%*19UWWty%_y2GkHVTA7O8=O{$#Q;7BgDy5sINVc2hLw;B$K9ixM; +zaixu|YplGVXCFJ=Yk>P%Yss)&r}A(9yQi+1*?Om*3!dJL +z)P2KnrgeVWnQX`*xomRp{XZN$_r&&U +z`=dsE&~452H_m0_$^%1xy!%3PyKGC)j30laa=UDAG{ppTKbe&KsLv>G0hT-|hN|%F?Deq|6u^Y)D-#kc^u+fBwYji|5yW_+g8U%bZEKHo0W@ +zT-v?+g?#MmrgQx@g4=UPnk6mYIm$L+Y+2H{9e0Ng_Ukt?sK@pKaiKKScB%8dL7EBR +z_P%}n)XO|V +zU9ZY#sz>9w!y^t0S|8uNetrJzX^Wn%;*?(>)0p^b+ty7p=0A{49BByHRX*kl-sZl2 +z`@NWuMN3u)o}S6^mxLsaFD`aC)b_)oNBPCY7k>LVyux{VXhnJXp|(-}8oK!Ir3AsF +zk*!bXO*Hrf)SSw>v-aBQ3A^k*1s}^Yge}Q_|77rqyjfw}GRppJ3)YXm{4slC#)Oi9 +znHd4fv!_yJqaT+D8=2oM<_bUtG`({ORig4dts-Okt)zBs4Ack(xMccjIZ?e`*hyx_=?x|HcZ +zZ;f?IofnYrzqexixR;TE{lZU8n|j`9?0$Qfxtm712&B7r5Bzge>@S;_9r3VtnRx4% +ze_`eL(pMX5Ce3I%x81V8|ENyN;;PMnxtolyB!<{a1@9c^&6s-QE%jm7_1_=gEh+l( +zI7!d5gmXFu#3_u$W0E06!#y?1gy)wpT@wFPRarK+yrgVtU#^R5 +z_tL21@O?fauj!84s~RgC#~*A9^Y;%tId%zHxpJk5Y548O5Y>c7=MP*NdvElKr&~v? +z_eIAx9osnK*zMb!%=>?z^p$+$!#T&yh?P?hJ$@0Jlst6Qf`h+jRgLVh_=|0S|BCCA +zx;{Nhzfe%_ +z#aZv#^Cz6k|33ex>${w;+C&*keoPPY5BwTCZ3uX9GI3W=uZ1$P!2e0Q>{NT`kko9) +zO{=EfjsOJ%2JYN=xFP=9qNmG*+WYONM~^!C^7P)ER +zx;jOT=yzg5Uio+5UnsX+wr#-nkjll*J{xX_=NG<9xZHeJo +zkfWY0eNc5}M_1UTnO;BDh(aq%7kl~oOp58>fAo>HV2(i0wRPW~gy#XFB@4ZLTULrT +zZOy;by&@pt4G6frrez`c#r(qASJtn)e;n}G?Q-^`^5N8=xsM#L-puB<&z_bwMmzd@ +zv-X$YJH-D{d-B`g1?6FQs_?u+^nGFEFWNmmtA77!K=;+B)Zwmh@2JPt!Nb;ExO(D@ +z%ff(D>4(1^v-#&x_kF3`PMvtswn9#wn_HtE75)0a?>9ZJ9ZBNNd9-nRLGz8$CiiXY +zU8^^5rjOo<3-Mp_=JA;l$^03Ti62j|jsETTw$Y8N-1JMQjU#v4R(pAdh7Y-UFJtP# +zh*Kp2{(cMmdTl(E_4UW#NiIi6JeqUcC1X1wkkp*HmJ<_RJNlf)GoSBhXJ1wk?@-qq +z9TG~V7hc?xI6gkXy0K~RnfT6=&iks4ygsqr3Z8v@{PpY;%Xc>0eeY83#6K`|>Q`?w +zMtq<6a)(RfhaLL8)5B}z#|rJaOwz$AHBT}tZ|}G@LUL)3f5Lqkb>!;3{bO^EJ$i9I +zX!c{8oAkJ$;%RJm#*daRtA4k1`JG)YMLvGQZ%N?c;n)haK +z_wh}6(Irn71qOVuh}F)mx!jd4kFMR~9cGNiR}$ezZ?*fJq#xZY-@cC4d)XF#S9-;_ +zdgKD8Kx4JV)%w|_Uuuuu>s}U^bi}LMWy(+8^Gm!Q*!cW>q^omZ_N~)1U)4I!E0Pz7 +z*QYML8`sqym%8eO?zdm$FGqXNUN|*Twlcr++uE=aW@+|Qj^~PnM)?Q&Rm}9(HmZv- +zp6yip#>vaE^|{*;n{jH|_CH>ouDUtqn(d2@( +zew@Wn8Fqc2k5&G>;qB~h<=WZd9!DC^KWO-qD&NO(*cIa<6 +zR?OM9@wV~t$)CF=dY9!7(Tyu}*Zg_&<*YYFKYx5BkC-q#q3GfQhsGUSw{2d(@u~T^ +zowCa2R?(-W??c09wLOl4kFsQ(4`0=|R)4n|Z_D0!Q!O1-;~%hggyP51U3<&l6fC*Y +z^}smDBm1$^VQKm6WdYRl%3Dta=SQSm+Pk~g(Z^d~2J35oZg?_0;u>{$fPC}iSA%XJ +zO*&9@^Y%W$`Hkj&TQd7g``o?0%w473 +z_OIXGr(X6cTL1R>KAExm`Gil|YpdrkrYG4l2ksq|7(9>FB^)}bxpphCH85Q_`M{bD +zZ+_jqSUElAPwm4=WjwpTOB$9Eqjr|I@_N+ZipW0~f3wNFttIKB} +zdbWP9jJM-D%-Y_ed+?R_5;Tn1>(%?FzexIU*^bm2}?acRZ)h0Y!yerOJR9md%|plWT_ +z_dg$XIQ23xWTc`^ZF#Ae-xEofHYSXb2Xx(ylqR?mgOGKzyedJnY*E;r-^$3Wi}XRPlkoTJgHQuI7si+t*Hs`PBSo-=3V0uaj;i +z2+lj`Mq0UDw(ya9PhEK-ShC}1w*jA`wq~DnUxwYfqb}ve9J4xoYFxL`{QYck?RJm5 +zM}9up5*#|RuJe(ncM=Q}0<(QFc9X+g5aZ(&Jt9k!K6Q_=P{!D=zzZ-?}x| +zKlJ&}a8k>iJgXD&zHKnQ<81o#6))}`&z?Acu}IKzyu5IOO;qHC1$(5KOMd=g!nq4C +zNF+S(Kk#Hidh6+U!_KVgfdP)sf6}(y{po>rZp5V|e9w^Dcs?=0;a>as1J{n!&G_Zk +zy$070Ka6#ZTK}F}9iCKKv-+F96LvmX_S5Wdik3Xt`sljDG=6AT?d^>-Jr?Ec*|_T5 +z@2U;a0g07i8|B?sj&Is}=C$vNQ8^;@@CPe?up%QuV=kz>z}wM+is1} +z+ezu};$F4g-8VTVqTdM3+84!=oZ$x&%ogMic*wP|d~@07r-qR5Dcvi6PJ9s-)ocT# +z0o2n`jp6%3(>n`|&+bMI*34>q|8f8{cHBCyXt?vppihfB9beQ_Yw0kKj2Y&a^~*2c +z_47EQwd(!sp1SkG*|{Ho_Z_ik!sYzRoQ~m(qCOfuA_t~Uo}x@7EZ;G;J8mtV_~(TO +z=9bcTC1aA9w%L<^TG#V6O=uq;Q&cgxPRQS^|IWwzmeq>dQDNH73tMgS22{VtBO^{t +zX!vw>gRuX3^ZGOEesjoEtnds8jm|uC_v~QvOPRHO+jcMQ+%xvbgqKw +z22_P@keqI)P&%x7x&Dup&pgIHGTXd*>Wz@Y=l8aI|M~ptb=SpfoR=3=wj9=Ix;u}( +zedG16yJ=wkzD+xJ$up+ar0m@7F!bh*wF9EpkDD*J<80IU&;h=7QF`(_x+-J*}mLred4?T^K3hwsL +zD4g;A_-XPBoteGIMV;!*e6cT8HFks@_c;+Q +zd0_dft~zvk5A3IoU_bY8GJSSma)TH +zba$|YF!xcPf8?(C`9FW?9_#f|J|gg4^qW`nepKveySmaUJ7B>4vv7Uh<$&>ZEB|b} +zI%pa7sQbyvyu)W2g5S1yzm|{KGbHR(+tsPfZ?80LS~j0?FFmD@^-jr3YJc=8@zU{~ +z0dFEba%%U7-*`3e`13z%yAma1ZVsqQTGhTjW9gbJAHItl>HOx;#7jT!&3Jp{-Qezb +zZCAslKd`*K_usqS{?F_0o0xZz9xk3+qbS5lcbFebX +zq2JSH%`v+t9{lyLxAtEjY$2PnEoHZO^TgyQ$vbD9n%Ew^c~7$E^hI+o{^6Q3dC1pC +zW)_6E%QmM?U~U}!H8tR;7n7Gy*fuyd^v=|2b0=3MhTNG_JF7nB-Th|YLtAF1%bMGh +z70CyQ%(YE}L!P$u-XGfV{BwKPfu#Kr`=09p +z>kjOaE#iFOH)O2deE3Ymw#~Qdmh5+*I%QdE0k#ba`hGBf@3s6u@qzCT?npj0sl8(J +zmMPC=`&aB<!|NPZdt57aB*_VKhY$2i=HHnydE``1-v1J|#DUMB-dG#xGV#e_1ElGiR*?lrL*1d|kv?JkD18lneKE3YiZ$3?a +zeI{YQ`KH5{{4V;d9^EPxebUzvt!49~BtQZ!MHuda3Zd0_Q*T +zSTw+#|4LUI5;!<>{OToZrigyOlK+#$e#FG1&Lcf9q*gAx6Lw(ihtnIc4S)G*tmftE +zy#bp<cdTA%){6Rp*DZiBK^qso%sDyAv;Sn>Kzq3O$?&wiJ+Cw9!jG5B=N +zSi4bO>$81dzOp*+_&9rE;->{x4=z4*nRu(P{jp-qg9V*$0!BaHb!REJ>*m_WH&Inq +zq+zHc!?*qWmbzy#&)k|0T6H?#*N+?XU_s-Xf*rR;Jsx=H=Dn&xVcFO29om|GfB6RO +zj&4!D*Ro%a?g&4>_wl#yk2ZwA@=h?GI@fQrAh6xPrZ1=3bzi~xiE}>dn0bX>>8lbS +zJQ?`fcXz+en%kFauPEf-bZ1P7QfH>dc-B1bO!+1|ZGr0hFQne_sc)F!_FC}&rF-}EEbiOE{Yfuy?pAE3)jET|8D(xw--aJz20{p +zmK)D5dr&gFjkD&I_N&q!uLVB_A5JSgH8EOn|6)gOKnQ4xUs;iO`NP1X`o)zqUhu|D +zJ!5vU(R=fwrr(x?)8lpaH=D=1KfN`3V$;@5`)qFBIsU!&haHu-Ztef{%kgX9)$Ci~ +zKV{;c4P5`^kz!dED +zVQ$^cpsdZz-J;0tD-I2u^3eEyv3D*|Rh9YsZ*pdAvZS)SIW+*6YG|@3YVIKHtyx+3()c&7K8=p>s@RE+-wf@ +zUE@3Wv-`iUyz^@Li6#Br($>b7ZaP`;e!i#si)U6(9kRY_jE}>Dy}R~3yK&YV1HXO# +z`4N6*ew%G=yDah5TnKETS<~&gy<`7#XvzKZgq!(SuDmt>^a{J4&(0n;r$xxinomkw +zj{Epz(&c4~#ymHF$D9DoQ>{y{ti9hg`ogV?NuC8O@_w*i|JsgOua~{+n!9cBm6J!0 +z#&2G?Y+29M+Vi=q?tidlN%ZE&@7~yYBy?%$Tb6@YJ%46->n>fEEXn(_)!KqPj_xxK +z4b+sRU39Ums(Aa}^@}m5(t?g?*O$4c1BSl2`V%>EY3nms!1*{F3IG?bDVec{yfH3+Vo3@brKA4YEA)?`1Xtr_Xk8vu5M^ +z(-9q>>E5l)x@kvKKK!@6&6w}j4qWHCVD^EMf)CxNhMxCyaoM|T@4xP!2;bepuFcf+ +zH4{Ixw%Xw1z5mryn}bOhrF+i)qd1#_SLbP@)K8MHjnG*)2gp;%Kc4qO5!>WY?YSXw`ZwC +zjCtAupXsTu?X?cMm7_iMOtRKzdRV3AazSXq9INWP_NeCe?SGGooz~em#iHu@{kI(>L;jI8>8$;_voovy +z-oI0`;I(<0p2_jnBjP$;8Q0_E;=@;FUs>zv?(I5%x96dx;(*7~*F1jw_}!ChkH(*h +z`RZ_Z@5mPyEVxsZGOjrP&ttvpvzAu66nK54ZNA~j=y`kl4ec>QJL|h8Lq`?#9n$F& +zt3~SrZoJTGMDUOdvzsHvtiR^D=kBSkKYEUyF>>{}WpO)P&b4Vhr$uaj@R;4D>qe~) +z8Tii0X}%w9>U?GCk-2*Z4jk0!+!K*ok1YLu>B%Fx1?S(NJ}BVq$Q5bpr?prWn`5E% +z?-tz3VNPCVoXtP`emc7JgA0B=obSDRYsWmzxC?V1UE4B8zS;g-xArOfww~N^ZC_zZc*dB7e`;rXhNMIXOxk9% +z-p9J%ST9X{Md;j!3kj9|KPi8GT4vDuyZ7JSbTV?-mBnF;gYR9ucr>iJ(+4m29RKd+ +zLmv$b%UrnYjWu0U`j6YO>d^VXLtihiII&?+iKAQEsMtQk7Vj#H?3?McckI|t&P+*f +z5uCbz*L}ya1CqY=_Ij_S&8o5wb`M;8_Uy}M-uu6MGX0w4-jY+}L%-ghz3Tq^rQ2Q} +zrhPs4`kJHr=T6N|JQ*3hzq7;Idv9eYt#nKX5AIlW>&8X9Eu|NW_k9_h^N4MbciG)j +zS6f<_23v#=9GTww+|*^UK0A|oS+(k6@tDn|o-+r%=G)KaHQ&qrr{el&kDeBPb<2!qEOKF!|~?=|ePoNw=U|NcnKx5dRpTL*sEzC-2lv@0P!?ap<-wPo3j +zc`Xlm{!}#Km%=&Qa@NNjulgYNYWe2d;nxep&)peq)2`}9<&s|E9lY0tT)EcVx^??E +zPF|ZCutPh3*NdmePFU?+b#+%+pEKDRSv$u%#DB8sRLI=S`Af{t4r*`bzh}##LZ5}M +z2RyCEmwU}j-MV{jC+Cru1K)Ex>f-gy_R1mc2L8RD#W0JLf8KH;uTQ7z$Horq-p?Y_ +zZh3oque3Ppq@sRfMrQ0u99QlUJ?j@==O?#q%f5KL&{6F<)Yzy=Hgp@v@-voi*+Izia8O)!cLm +zw~IgA|K3-X2QyNB=-=a)T<3K$$pTwoN;K>YH(aZ>Bi|9S9-!?)IalHn*AAMBBW`FO~$w +z=Qz(-hr_NG7xO<{IK^gXx15SgHX)P4yfX7GAF2J{ +z3q|jGO^iP4bG|wRglAhW(v0=!cr+`_3lwZm} +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 +z>vZ_3E86470~}7L|J!az_J$sGQCir~!o1?S +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 +ze9F|o<&1LojC$@VfHK9x9 +zXFGPLC%nBPz%_HzyvWQ^okB9bgR{%NjnA%}`eXX3$*U?8DmB?(d0kC)oUwPNUqJOO +zL-qecZKnq=ZTSR*ZJ<$xLuX1(Jy$?oR4Uw1n5?Cz~cz7JiQ8~XilYnxT;K7FIhkh}XA7tFHkzp9=2nUQI}&21ll +z`|go@w?3UZ%h7Yts&!}lH~Y4@ay5PXiaGyS;9}Wl-TG54eHVvax$j@_?$}}d)^zG{ +za?0l3`zt=}*C)`wZ`<~p3X;ALy>TPd^R+(Tjoh;N&$gQ%Uwq`u{bME9FU?!fEvWta +z4l&P0O%Dp|e7WFwLiK8v_(i2U{_=+N;E_WztHsVLJyrO4d{uUITFAnjvZ7SSdwyQ- +zsg8jQ59bbO*EPl_VL-cdpNQN6?Iy>Cc5v5b+z+Wr(p22so9g&u#^u=OwzaqDJnqbM +zt=HUcy*WRvc8C0+O_^h=x+rzks8Bnvz~yI) +zc4UsKTf!HL-t`MuS@E~j%%_SjPw>6(RDEyt{LsHgog5p{@Gsuj5C*t$zA7;qlm-hiCZ?>&#;J_eyRVyQ9~R +zCj#H?P+b*6lZGcf7F*bBLW|hAUK9QjoA%C>K`RdaB^uj5p}w6)ZSp>|bXNKPjI8SC +z$QfDZGO|`=R6n$`iX8h~VteF=}dg!n}5M%0IR6$Eef$isPc=%W+6^vN(Y9Howj}J?BawEOQ#lAon7HO +z%6@wXvoStp7Y1~yTKV?96sNLG|EfF8|CepD;r?H~KqCvtm4B0stbnY5u^y8mmLfK? +zQHX`aLSmstJkV&XdiVrm1#WbGq=;n&8a2toCy0f_LJxOHqkk(F5(_nIl7~+a3yFmu +z?vO_RRxBhIYSbhTpCA?z3q9N+jsC4zNG#N-Ngh5yEM#g6&OE +z+VT`_Rk21}nbX)GwT4b?^i1_9Xbt-G`o|b_(b^^)W5~4__UVS4N#|R!l+gVggVZzR +z`b~GHdP-;wbfo(At^YZVIo{w2T9chgrx006XmvivWY^D9f(0L%5-j-8lwiS!rUVH- +zJ~Smr@X@f8V8JJar34E;G$jPXXm~6o1j9%%EF}cPPyizohqsNqZxRecK$a3L_|O`X +zq+xi1rG%tm;ESb%sWB-S1}5v2kTlFzf(0L1Ltni4Gd(3DUb6TD}tjW(7Nf?+6t +z5sgomr^-Zi69mI31(p(mVOW)=1PeZbVL%6?I<_c>>px8K2CC42V+@$fx)qnbVJwhr +zO0boXG>k%LDM5mdJfg#`zF?TGgkV@O3{2K3A!(Scgs$RBl`EUPI!j{c1cN84JHKF9 +zFbquADZ#oGr!^#188Et2$J$@`U#jVM^k2H){b6OQva$>s(y*jqz=5rVU>HiXln@L<0gO-_-Ud&ViRvau8is%@ +zB_s{Qsw^c~@R3akKnJ5bwkU_|KTI|yYO8|pI@7-lOW7={8Ep*X4>JXI#Do50F|f?+HWD+3CK;dH?; +zTL}_;Bn^Y!f?>82f?;+;5)2E5bsB}D2)u_X*PW<#g3jltJsb +zQbI6{>SifHf{&zOHhg4Lf(;+plwiY09?=267@;`44T>le)lOhNtWr6AuqrD93WniyH5o8rQ?ox*zeW6lHh#$1^QvwtmCwV<8V#YEGqBz}q?NW98U|n~ +zp~lcC0$kHWP04x}mDNpYN|3s#+}^={k}KFsu;4>$NG$l!ln@M~xv-QF3_}5oP~4z) +z-uUgWU|2A$Vpa1NkECIE4kHvtV>KF{ +zraM!;YY_~y?+aM)ku(e=%ccZd2@-r{Q=$p*iR{$zv6|mRT&n4J^k2%-BlY2o4Q740 +zy{pp)BMQeL^%~Z+{!dv6%k)>uRYGzF3X!FR8TQF=QB?QB;5=#leFs#Z_LNE+GvXl@E +zLjjCX9Nq>+l!@vlu;3$U7z@OLkECHZodq9B!+;J(C=PEM2_Jdb0RaWWY$XK4C|Z^h +zf??p1rG#J@3Sfld@HQx-OjI{PFbn}%O0eJ~X&6pt!AH_Cpo0;Ln+QIVhS~6uO$k_4 +zFw9m$Fbq7hln@L<0gO-_-Ud&ViRvb>GN51>3nUn3D`7Z%%oommq2?vxTiUCSwJ1|p +zJ1Q&7(1MiT`U9z0O0Zu4rj@qghF1OomQrL7^)yQf)_aFEB}m;=Ztq|}$rWrRBv*ib +zEF}cPXw57o1jA4OBNT_XK@nx5x(R||2*^@`1s_Sna5@VFKugyQfvc&bcPH-VJ_1;bb%!7y717JMWP13DPhu|+vt|6#0M +z@`rq+al|z8aD7S$hSA4ZN(hDp!#dT+f)A}Bk>Den5^VTL8fL>s_J#pBNyBU<1jA4O +zBNRuKgQvX(RL(8doLdtctb +zY+B&$NQxp&2QD&R7HKZo?JUCaLIYShd60DmV +zTEb#=Q<@TTdj}}6lpw)J-oRwTM{e)XCk4Z7C0OvGH6%q5RH3q+1)f4Ol@nM>2!^2m +zMk5zWcYRqIP%sRo1;cD5Snv@H13DN@3?E6uXtRQ0wi1G2!LSa#6h+`Yg?Bm=)lOhF +zB-Iy!C2#Bt8a%PlGu4~GdeSNnJ786L=FCHhcgyKq-KlsdFImV#5raMzTPY8wu!#YlsO$m5{rG#J@o?|IdA9BXB_jklp +zykW|d@*YgdrUc+7X_&19>sDMa4Cr7qF??iGLTv^#TR8WH>UW4Axuw1OSPP}Ha2jR7 +z^emL*iaMz<>d~oDA@xp>Tv2OExxGV8vXqcqA-O__LoE2v5|&^X3SiV(QH3JPM0FEb +z@R8d)HhgF=L9sF*ts%+n9crGXgwdGMM<-T8QWQZIB5diq5JM*zJP}J`*aZlNu|O;( +zBn`ufEG1a*p*18Hd}vCL;3KX%vbg@E)pMccR(}I-jHVa4eMW +zWeJ9{KrAH$!|)tS3BfR`o23K^K9Yvn@R3akHhg4LLM42B?p^qz<|X2sHYH$H!7y71!7%X1QbI5c1u#N!cpE%bCaRlYUF +zuy5~hMD=SPk}I%$7}c$ka=8A(Bo{X*)ksHPlaK$)^$|E4J+xdQBEDZ%Qd +zf?-rQ#wK7uS^Wk(uV7d(T;El!hQxvots$}g6%I`a!7%X1QbI5c1u#N!M2rTTjNw0J +z!AEx4ut0)gwh}D(&>9je1JaaG0TcyT27!vDgkhg +zDMS{01jA4oqvAbOxx!POB{6h@!4uV;p9LRD!)*A-rUaZWX_&192|n`b54wY3n5~4Q +zVRl0j3=4*J8ik?=yoV~+ov3z#&gZB-91Ep;S%P6K5K9TcFg(XnLNJW#W+_2}kECHX +zd}LFC4IkN*PzN9X!In?e{3hZ&ALm7X!m(H-)Wbv4lJa>fjxk`aynzYPSxU&OKd?7T +z33=FoLT4#Kf{*+vVm5r__Kpo7xxHh;3H`m3&ettq+vLn1s_SnfDT3|4sRO?A9>~s0R_WsB?QALT9y)mVc?Oa +zgkTs7V1(lEHYlP@R5w8|3;|h6u;3$U7*1!wN768$gAt0G2tJaA+3=A~30PGy%vM4$ +z3_P-w5DY^Bj8Gij22YiV>LwVJ0d4MG_@d?=;;*$%ox7DZ;Unb@%({ibsBV=ESX_DL +zTw4+b8M;aDE17=HYCOSu{hOwQD+AJ$ +z5DWv4EG0 +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 +zZtvJi7?H*RT&2$HV8MshkQ7CJ +zYmj@&K_O%=M(eM7Y$$u0K3x);5ddf#ITvr_!_2~2)rPTgWFkD-Gf?>h1 +zU|0`51jB-1o$7!hdK}Z#h9npk3=4+!l#gIoFsxG@P(+Vo1j7nXmF;wOqOcm0JfZ{U +zSxU$wIyjxBgwe&NuO?+vqP99%@R1kc+3=A!B@BblWdD|btbU33^9uX+4u3NOD9Yzy +zWpN*+k1>W#V7+%pD{WRcr76L>si7&s>ZUX$SlyJSgn_lG{+}GMlpw)J-oOOC1;cD5 +z1j7gfEG1a*5ex&r7)_i31;cFkNE&9tN768$AQ)yVAsB`N7@;_-96VJfs+%Bb7y`1C +zU}ZqTFq|$JW-CF0kECHXd?XE{PYQVCEG6U-9YP9A +z38gV14Czp$$xq!`4M|bNWLH|p35+IIf(0LW^#=xE!ACYFPzo&g(C!OZ@S!O|f{*;l +zKz0Tc3=4*VNwyM#VJOW~LNE*kFhX&78$4Aes+;i8G;FqT?hDoL5I=HDd-bsv#(X4e +zzfp1pR)wX6NNCUX~K9ZYmf?rD8Ou +z4jSydg5lcgcxbLL0zPtk$A%BBA+a)`U>KfY!H3q61jA4Oqj7A65tQB}7)F<7DZ$Es +zf?q^5`tmDFfduC1SVGaC9XK^1q#()WeVZkskS*L{T +z4YQRH48wCQB@97dlZdQ%qiKihJ4`Sv7#0lcsSZ{{V!=n!Fjf+yuD6Ybr(n2N0eN8! +zR$?i^f)8zb=3zUcKKCwsQS%b<*IK8}-R?9g0o5sv(Zr?AT1HyJl3h0B7M2nZGqh3m +zW0kh#3V4F01PMO!TYuQyR4|MiT^4)V8KT)j1-K~$SwgR{MK9=_|fnFw#k2F!AIV}L}CyOvz3rd36wue +z2@-td4NP_h6b!TBBWaioA4$W&FGeU1Z-XMrM70xG_XVmi#L%x|@I-Y=NE(KfSV~A5 +zM$xjAU}ZqTFrb4`9b1&c^&ch}uB{Fhd?XFC;Uj4n)h!riDE|jlwf5*!7!XI7-lO$f{*MC8v-8(|CWEOeu?<=3j6jBM~r&vD9@bh6vv3dF;O=a +zLmOgf<3u;|aD7WHFTx{2vXo%KhnBD;SHKf2B?QAz03#GPQA1+g)W|Ly7D#UI*h;YA +zLu*K^Eq&>9j6 +zKC&snhL5CSHhg4n7;t+?8ulM-`BcqsBF^)1Ui2p%fTckZ7!cdU(28o3E8riN5)U!7 +zI?F0oT6Y-hT~x^xP@1KL0y}umI3xUqJW|49-PA~~fB{(Wkz9f55Dc@GAi+m&@6a6t +z!)zr4!|aA67#0lcGzvu#cn?*sJ5lWfozGEwI2KCxvIN6eAeIt>VR(+EgkTue%~FB{ +zA4$V(_{gRN8$Plr!G@3Q4FkUzp*Xw^iYOD+PLRFfS}j=_P%sRuvNE7x7&XtzfP!J* +z7b6shw*|u{QbI5cE3uRi48y7{B?QC3BTEUvFciQD#o=vGM46~=0t-HphOs~__(&Rt +z(^>G5Gz{oqgyQhFk?@hdVF;)n!#4LWd{Ofb@z+|X&fQ9IfU-2ImPFpbtWzALD)kHz +zU3S@O;h^8p%74+fi4-yYn$>uM^$U1uN=UANl~_tht^o2_N(hFb07fVdZyVR|Y4DNT +zJ1h_jKD36!%78Q_Sn#1K!ODO%B}nj*+dI%((lA>I!7#fa35Jo)SV{@Q{yG3f_RrdvI<8Khpp09z0y% +zTo!y}Q-Td2*_42%1;cD5Q~*UC+yuk5oDd948b-sYQ$qHJ*-EhBLu*KiA}T2hA@v@{ +zQbK7=I^NcMA&p*X-2{xrpQ+v%1jB-19jgk4;R%)!Ecgh90XK}g-WCkQ+eRuOFRVd8 +zmJ%%Z{2%NMhuSuOwE8XLH>*PYcKyf5+BEWTeMDd_BQ0UEw)kmE{0|x0NQknOkX(W4 +zW+_2}k4A3q>UL2D!)zs3@S!y%dDsC@u#_;ipTV-q?U!I!S+g2ZWS32L*>tKyFbq$y +zlwf5*!7$*4QPcFT+r{77Y@{g>B +zWcn-RDj^sa3=4+!&_giHg^&ERP&RzzMR>qX9?`LtVC{$sh6TgA+Zs?rPvcg3GawjN +z-~gpr_XUDs!LUwwvTns`4e2*tC}h_8N=g~2o4``SM3?vAw`$-=rciDuzaBV^rD-oTD!G +zJa||GKLSnA!J6_>k}IGZO9{EXgFjhHu)3*W7|_9J3gRdytv(s6A({S4>o|eY#7eN> +zBe!>K_{i-YNNl7`vvku(ge3WnKA2!?@2mJ)(tD1Z@)!`tAgGEvJSX0kFk^x3=4*JIK+Yvtsx19p#Vmm +z6;&vrOjI|41s_SnZ1~9DFr2P04cipmd9&sv;uG3EPq!{mUMf|V1|8V2+EG3aE358s +zeTT{Kz=ZxRC0MV2(-M|GLmTE(eMZyB?VTc^(S1`nlj7c5ys#3M?&p{YKJu%Gv63wK +z&=Qv1-k}e(ln@M~I#^1W4r91d!Eik#c7BXExu +zMVM12s-0lEGu68m7JOuv4NEN;W-GzUfP!H_2V*^SD1U3jPgxDgm}`0{vLF7pO;$oM +zENK{+tW$!O0cj0MFpTnNDM5mdya>;RkECJ1P0}!12^M^44T+TjX-Wu&p#VlSK6o2E +zRVJ#NAZZu^vXl@E!>TML1jDF#mJ%fRNE&9tN767GKJti;4IfFvz%NE94sU}Z%0#sj +zSoa00FT~KVV(>(DO6bdgyKI|3TKy97n^hrxyRJ7`W_&x=ej{rcC0D>l7)@7tb)LYe +z&aaI+QJpVp8h4Z{;GB_s_)0gO;w;a#H}B@dk-n-b86rG%tm +zSe2y&3qG`lq$mRKDOGM{b+eQp!ACYFU;q|;X!ixI3`kRg1s|Fcl7>+oEF}cPPyizo +zH&H{9O$phQ(6N$W7@lA$!ODPwVc-#?uD229l!KID`vTMvCr`l(>JRsq?RfPYv@{I6g*x>Lu;YJL-Osixo2f1&V|wyU}dO;E(j +z+Wjt#v6hjRuw<7F%g0iJwYNkoZOIkz1WSnq(eXQqH2IH401@B0A*9Ofo!s8(nDT!m +zSEx@8|1Bk0@S!!N2GOB9nCZ$ZZ(!2lBmd4BaARda+I@jw7}dd2LNJW#U@0MK7z$v7 +z;_$YST~szDARtQ#7JO(8Nj4?m36>J3DqaN+fP!GSRtedZkWC4l>JSXW6D%cI@DU87 +zAz{?@HX@8NQSAi98%Ce0-WdeLf?*v~vfv|W7)lF<*-F%hoGEs(>o|e29z=~lzhGD} +zEEv{PRIG+17>4IqO6XfrqlqaPu2q1wBT8#X@`w(YXDPwj5fuyrIv9<|n9dml!?o4X +za2hr*y7OkuJH#ind!BAxVRR1>L&L}zb?m5Qa%H0031aAn85*}dO_o<){h@bLTEb%8 +z)JU#?Cs^>IB`gyFw_&ERlu+Fd8os;-f7-y0)V7`nPs+QgkvA~eH#LG`_+M`C*h(~r +z4r4MJszWebt3<=McanwyQR9_h?JWt0+3=y=7qH+%Ye<4&D1Z^(GZ7~Q!vHNy3BfR| +z%2GnoFrdIvf&?G=4|A~LBbyRz_(&RN!$;CE@QV?O!`q;UGEwaW)_sBM3o-Po7(7v( +z608g;7=~3@8Bj0`r?WDkU>MNB2*u%T!LW&x5DddgEF}cPuqsOl!7%X1QbI5c1u#N! +zcpDT^CaRmjf{&zOED#Gml7`{*hT)U2so5W@-y(iN8$V?1dF9!B(+fuVJglsdrB_$6 +z@-I8sO2`|SuqsOl*4~ny(pDVv|JyHFkcS;$qT~v;5|S%W{wyUL&K1VPM=*?rgwX_= +zB1F`-1Xe>b{gu{n0;A6NP$;5Erfz~@STGDs)+xctfP!Ht&4LfDAsLMseRN_ep^}37 +zE)ON~+k^&w^t-=p@*f4mf?>h1p7LQeBo=%G!&pg-y59bcr%n8$V7OKR*&BwHSW2+q +zBWV~=5Dc@GXewou;!=Q)E3J!b7#p3aZi1v?Ny9px6AZ%>EF}cP@El7Cl@yds2~f~b +zC0H4d){s~arf5pA;6qbF9?>Csv6N66lfh-GFHP#4K`>m~kR%PG53rOF45KDlO0eKV +zYe+2k(3B7iLjjCB?L?u7GEv=x2H_LgspDfczlpe1)9>iNRGzWH3t=TJF*G2@Qo{IfmfO2pQCRSi+dCu%!7y71 +z!LVRhr%@=1z4IqN(hEg-7F_{9jt;cdaN +ziIflw!%8eA1jDc@O9{a+@W@g^FboASLUDK-6j3Iso4|sPq+u)&3qF#D;dB;!Bn<;P +z7@;`4Z6thTZx{kLgyDou&HhmR67dV#_#tEO%Nv+YZE=c=e|H8kG!(%2J8?|$$A%1T +znvXKc|n!3 +z(l8r7l7@j_j8Gij21S&KYA3Mn3shf-pr6AfDT3| +z4sQ#FO{9ci7*=8_AsB{LSxN|ofk&1Sf?+6t5sJgxpolV2-2@hVBn@MMSn!cF45zc; +zBWW1W!3f3SZ6o0$d&3Y=Fw9m$FpQ#QDbWCiC;PYjWA#hKpI6wocleuWC}MgD)p$?d +zz(j;(DIu@^0CFrPSX=xJl{RPsZYxTV!c7{V4Du79pzxUM=dHZGY;P78)>?Z<+T?6RS{1;cD51jC>oO9{a+6u=0@ +z;cbLDWum$Xf?){AQbI5ctFn|}!AH_Cpo38zTa?4~A0}zIwmMkwku=PPk8Dbyx&^~* +zB?QAz03#Gfl_Sh46V*)+3`0Pc608g;7>3gY!)zr;@R3)4*zl1wj6NwCW-B2W77Xh& +z3Pllk54_WzsCI(R=cqj#3#EHmtPCg^hSGvzwi1G2R5wcr5_}{LqdPo^VY7vEU#NbE +z_>o)MtBp#&Rs?*|&`q@L1BaP@&1x>1_4+qW3CR^G +zT9y*5ZYmfCCon!(<;vnVjmYxMxmG~IF#N+(f(0L1Ltni7Ix;E|<-U>FKugyM)8 +zpolV2-2@hVWS0#KBp7BZ!GaI1A+a(bO$icwWS0%}77VkM5DW{3b)u1A7@lA$p{ux3 +z{W$_=ly0q+zsXmJ%%ZNE!xyF#`8kQPhqy +zQSAiNovGfnNE((jtYbHp_y~r9d5ma$SW%E6p7z$uSHTqQbI6{ +zl4dDEf{#WpT-Op<@S)uou%5KilwiS!ri47~Kx<|xp)@8`p%Od6Q*Q6#k=2k?UxsSYTj$1#Fog{O_&R_K$8)sW;79Wc*QLifRx|6t3fYJL-Oo{#gQKj~X<)i%-V +z9Mxx16se8?^2`|mvXo$T)Bl>Gkra(HnnwPevm&6;-9kB&;@;Zl60*xy3pZ9bm4D~V +z?xuoal(cTH5Dde6rcy#M3G#f?>82B>2ehz+}Tm(lGj@ +zV3@6hU|2A$(HgZhS^F8hEd%tB}nj*G>q;b +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 +zNDLNZa2nn%nl!v^ +zstzS=5|(^Q!?ZNx={AgQO)$>xHsDObkkT+UVUaksCP&=A +z$){uDKH*+HAq{h5Wsyk3X?W3-mVC4gNs>>G{@C&<4cqeRY#6zfhHVmQ7y^tCr_1r_ +zm^e4V%7AH@1u6~OB+&40-+%c2^M{Dv`u^p|U-{L^8)mYz);6T|+@aRm74(l)(0rdG +z9e=wLt&e@Wy<@E`5|Vs+0+a4Y!!`*^KH7#vu1LcciIZnE)+!BeNOXHgcCtv6hS8%% +z!jg}+AzAX#NTgv1Fpe-Zo;Dg~j!?!mE9P4A>6DEHvgD)P7nFwSB#T5EraLSWYt%QR +z$uW1-#_cbi;-6`l&C4Q@hV2chG>i!>5|Vs+^v9M@Y1o!eY1o!eX&C)7LY&&hB4gt0 +zgwpVarIi8GFr``=wnagM&};1&9?V@rZ@#nOx{ +zvTAMxU9Q-zlyb#ZUzU8dgw^dG%CktMVF)lnoXmXW)^EwDQ#KZ;+dG?tB_C}=vNE7X +zLXuCPIb-iMY?DaCX?T&H(l9k)kysKRT|Q#%VoBCcSUqv>_0w<~Mw43-9ZJ|FEcuj% +zu^;2Iw$m`ReI$u~J0E}+i8M^9S|rjidbCKSVF)lnoZ7}BW8&NdOFr6tL5C77wMC+{ +zVVcS!ajNFM)bnY0(;Xd3bSSat4l4tuVMtr@NyBVNj1V7P-q|p|JB~zY7=RXupQwi4 +z{QC2^FCHTP;Oy0>pZV&zDjWTLM;}YAZ7rjgu&kRJjl@s1pzo}`JIe5we_ABU6|9Oy +zLXuB^irC&w(=fr$l8?3_S!YWc2}?d2iBTJL;Z?Z{wNgiG=2|4uFa#J6S)FTEvNTM2 +zTO`sj__Nc5xxH$E1LKB8l5wn&VPi3qT; +z$idH9SsT(IaTsvqi#^PZ~y#jH3$)TL*6#KZb^1 +zdH>=2&mSUw>-(1P8T +zh8IoS?Hx5?kysKRVe43XobHu&YN9mEhG&sT!)bV@<-A*Q?Y=;gk4Iujd~|sl#&^e& +z=+PelS|qF^er-eQP=cDUNSsb%ywmO0TpHexurgquIola94b#$=e6$V8l8;6r4MTvD +z+M~;l%$R8yfEI}kB`8&kL>fj4770l{9ZJ~pDGl55DGl55DGj4vMu=0}SY%9`onYM; +zOuvz}Kg#Nfb0n+`n1(4;D+8usD*Yk@zW@Alk6ipE;&0x3?cE3XPb|XGzNnxF%L8*gFl|B+_siMw43-)~$FNhBPC@N0%R%R>x(hd!?P4NW*CuO>Rl_ +zAiPZ?4O4R#iCxJJiSDTHps$YFIPCI$m!;t}oQC&whqWPD@+l3ol8npRK3bk>ctgPY +zWk_v9>QDmBTO_O#(KL*77?0Q3;uWk7Y59Fd*cw05;*G4GuzKR$>z9U0!)UTYi64oC +zB_C}=lH}7zba%?2! +z4qHB@VOu_>VOu^ON}yjxh*R5GWK5i$(An^YrIi8GFr{i`z%)$HTNyA7qhCgdQ`>3y +zL?qHMrDTyv!<4E;A`PQQi$ofR03*byZ7eb-&P}l7QyON0Ecuj%sdP&|rD3GQ2ytrr +zNcnU&48XIqAAa}zbB|p7CE{=1eC^!_9O6BJxh2k6K}#gc6?e4u$#gkh^iA)#d&?C_ +zpB9xW1S7y^tCr?#=km^e2f +z4Fk|3Vaca7Or=}$DGehXMu?wCKBZw>J{?L>s%h9Jk%rNuMIsGDfDz)B^Zb+7VI%Q*hyS=kXSQ${;kkT+UVUb9~5MYEj +z5#z{hq(cb+S|m!tl&VF-l8?3_4Ieb8Z=z@4u`=iA{G{@+l45^65~5?oPut +zi8KrWMu^kpgt;+sZbBLcphd#UfN7XYPs26|Nj{wo+wv(5vrndBn?xE;!;6h#5TW+) +z-E!jWgvIxny_|(wzAY;QreR2@VVlI+U!Hv8*2P~U{_c}!KYeF>zf-l|ws#m${QCX5 +z3EXIrupa-`TDx39O;{wP-L%^~oLjE2Nt7$}T*1b)>JO|;1bk~lvOZ}|!)!>5qxR_X +ziPgVyuCyVgVHU_Dk%rNuMIsHO42y&$pVF``pHA6q`E)2@%cnGqeii`)ED~v$Qng5=Vf1K` +zNW&0dggCX0MaIOr36^|H!z_>`pVBauZpo)KjC2?wPHi74pU#E>n1*cge{bQ9ik#pr`_ +z1xBz)Si5PrcSyn7P17)*V1)RIcGGU}Z25G`MyaM@n?xE$j~0nE3;{-nQ``7-Oq`ow +zWxzDd0;OS_ge9NSFw$Y1bIZ7V|7AUax#^BH%syt3NW*D(;UP;t+J=;dA;7p;(P5D> +zac+VopVF``pU#G<^wO|R;%Lq6vy-(U4I*?QVQb$TSvz6%M3!XT8%V<}kVT?2OeI<* +z(l9-5k&xumM|8G)O2f8%O2f8%IvYm6j1Z@`vB;P>JE1hZVQFQ+G)$>l888iRd;X)B +z9=z}TA>tQ*`0%}t{$4@jMvFuRZMU{{Q&X-WPcY8LhS6N(l@_m1t|(XR)vMauH +z$A3NepO$<&Wuv7#l(0!y8Bn_~NW;{GMdENF?mIr&8kzB6;a>gvX}GgtG%065Z9_`K +zNWmf@$)`tuZ26Riky~llCSl2^G>m>3(LF1QMaIP038mo;%hE8VWRXb2G_6G<4P!rx +zL>h(wBgCm~EHWm}O|axs8fJkk`Sb)Pm2SzWG>mi@Ax>={DW47{wgCU~i{%ED~v$?zTus@+l45^65~*mQRNgwtV`C4*fDh +zoZ7}BW8&|h(sEulq?cym{L_p{PNqc +zUc7jQ__MQ*AARh5Z5hiI>N1{p;n~psX?5Si9<%*KY$HdtQX?Wv_G)yU3BrN%q +zhUxiE*=!PN7y^tCCv0JnF>!8!C7;qT3zUX!5^0#8w@66x>CqqTorY}^X*dm|$t?-% +zRy++uni1lo%MVPeqmg5@{H{SR^F*bSPnGz|Mwk`DhzbX_)S?NLU##4YMIJjxNM^2Ss3Z +zx&QYQXG8kiAAbI`^QVZPI{WLdfAhcIGFH&EHsc*Ddzyb*t$m`mcexL)_|hpzbjpTt +zEE3jDO}T>lw{B|EFw$X!IGLH=853tGq~Q%qOFrG+QL1U!CXt4*pG6`KLx2(D)b^1Z +zQW^%JMIsGTsul@LKBZx#!+2u(^kIiBpVF``pAIFELK?P7q+tj!LYywgr(@#W1Sf5^31pkkW7(UThSD2(?F-FDK4USbU$^%UP)9+e*VM +zkVPU5Q*#!HG)#9}BqaHihHd$DC}GQ|Ly2?w{Q1czZe9E(;_p6r_S1LHyk9G;pety0 +zJDY^HoA#MAd4h4dqHK#};_QT;z}$3)byJguZTXZd==n5klSso5V1zhbe&mLfh5=}i +zu+Em!Fs+b=Z4#1vI%TuvQyONUOv5&bG@OPP8^s_(?cuxS#Mudp?=yQj3$=V(Rt8MN +zkWRxki8M@iTO=g;l!nBA0N +zK7HnF%coN|q>zSf5@{F$j1Z^G@#&a2H^It)X_y7FGGH2}($la_LXuBu7<;E-n?xG6 +zH>5P2h8G*fAVTfY<;#h)6BgfR_Hq_#`L@z93uKW9ZJ~p +z=}^L!Pan~tUq*;i+gM~woSo34KO2@-228`0s+9rLFgr{NQkNW+wp +zMIsGTssf3>{o&_7JAa7ysk6WS`ZxbLe>~e-#&U(Yj2q4O3wGPvigJZbqFez1Mu^kp +zY>Q*!+=Mg?K#PR1o2KEN5Bt(EJ#Uea86tX3s(lGmE8n#JT^68Wf{W79^Ruqej +ziL(>>uw%nA4O2=Mi8M^pS|rji_OnQ&VF)lnoZ7}BW8&NdOFpGx7RZuMXTwywC7;qT +z(qV)+wSA;~I+Orl8n#KKVVc$=k%rNuMIsGDfDz)tC +zL>i`4EfSV|O2bHp@x=1!l+Bh;Y1o!eA9f&xG;EVd!w_JEI9-lU$Hch_Rt8MNERdA} +z(=e5uhHVm(d`iREI}O_;(y+ZDrQtNZ*eC`OYL6~oPMn>v_&&3jvrx;om4;a$i$ofx +z<}4CvnC`YnNb)HS+w$p9!j?~m61IH$hz|WSLY&&hB4gt0gdSMiu(UE@8m3gO448)h +z^NTlLf9m`h;{W;b?2B6uRnWT@v|77@wp-h}sVP^GCm3gA!;QhCT#<%%t11m|!}{6L +zp`BM+#C~f-O2d%0NbFnDqbns1r{Ph(7jZ2Or(trtOu~{+8m6Tgmn*sm2J_p9v>{pY +z>6DF@wlZL+Y&4aX0k!*rG)#9`Bt~t}h4aFtx^`b74Q~io|8q8NLrTLGvPB{dqYR6L +zB%dDrVRtAE+axUcXd6;z!_L;$*ceCo)~MMhXTVbsRaue9?DX&C+% +zi8M^5TO_Oun1+!K)`oPIc03zaC7&l22#DwtPy%6nz@DNl5bP +zP~!jI{QC2^FCHTP;Oy0>pZRKI{tCK+UbNgG!nVTQ!*b&6gvIxny_|(wzO8Zv3uKY7 +zZfeRE)N~rQNl5Z3SJ?9D_KpoN4cjEra2j506oUx0hwqjXXD2Ma&+O$a)bedv888h) +zIt|+-(lFg^k&xt58fJG$!#0UDoQBclmW1_5YZ`_$Bg99Smxl4(aU^;W9)K1J>$yX1 +zL$WfUMj{QPM~g%nh5#eP)9_D(L>i`4EfSV|v<+zxAp(ppKeDDR5|VsAu}E|%K}feq +zbSOd7S|m!t=+PpPh9STRacUcjjEQp-Ecx^i9Sda1r$dQX-hcT1^M{Dv`u^p|U-{EE +zm{rgi!6H#X+pTTwrrqALi!#n_mgDmMmvwu$=?+UiBY^X&8VOiPA8oYLQ68^t?qvl21=y+VUw4+wv(5+w$p90{t>VoZ7}BW8&2reS*C%7AGY{W3zF+D^kKB9VqEC5uEFrc^BwX&60PB+@Vh7$Ht=W05g& +zZh|GB(l85T$)_|-rCahT4I>>!h*R4~%BQno0H$G^L>i`PEfQ%MJz6BvFa#JOPHkh6 +zF>&35_n&|6k&C}X{LP!Mz54*ySj$+hVEGs!e&jOVUj07o*sv^DP!kpjYd7uo4k@Hz +zn?xFh03*atv>{pY>6DEHO2amZG>jB15|Vs6WwSG28n)$A8n)%rp#=J6ggCX0MaIP0 +z2^~soSeAw +zX)O|I7(H4f(l7)VAx>>$kuh=Agg?IY;C<&$5x@Auhwpv#`*Dr6jO7ZJk8#y1%`9#o +zc5GUrT!9fR64q|o?Hy7`!#0U2wT_M&7U%6<-h|U|8s06BG`!uA`l~-S2}?fOhBSz* +zQ7iP;%(Y1Dw)TqsVC|b;J#p2KKfbFapFZqh>n{!4Buc~dyhY-+FHUH*^EaJ_OT(jj +zFFavwNNG3?qsc7^OFn5B(u@!vvGdq%LVMtpf(l9k`k&rTAhY~o^l22*amXEd}^${K2VUe&h +zU>asaVjNwF?~V;|qc)CyrJYwu!z_?R!pea6xQ2iC{Bw_7{3YUV-hA!d2X1$VwT$J8 +za>b50-|T<*HFmjj1>IqhxKw+$;UD+UBQIaJ1aB)1+a$^r_J(AgEp>Z`bQt$pWK5i$ +zkcKzik%rSSn%t7G&X%+dDGg&ki$ofR03*Z~y>sY>l!nvrqLk7wHDQskGGH1;kBrOO +zK2(!w7)@?T^yrUG!jeyE7%8M-n?xFh03*bgJ{=S1CZypsyeK8>R$SYV(l9-5k&xu` +zNrw`p;UDR~pfn6=i-aW~Z9^JF=)wat)TPTT5@{F$jBI?=_K_=D8U~<6!jeyi610LP +zpEQhg7$JTl`J6Tlzwqr>FJ3%E{Mp&Zk3RO#@#eK<)LOfOrqC=BKZ$}KpP>Aw&zy&G +ztWV#20+Up4k?53-tZ9+B-6eOZ;}ri)!<+7~|Vhb5nG?`-*Wdq?}HVVgu6h5#eP>2ku{m^e2f4Fk|3VP(KHOr@t`n}j5vK6AF^ +zQyONUOv5&bG@OPP8^s_(?cuxS#Mudp?=yQj3$=V(Rt8MNkWRxki8M@iTO=g;l!ncxv^h(9~~_|eC{zjJ4=pou#c +z32QgKmkXLT+iZO03U)b*gtVJ>%0?ku@+nu8E0BXt!jg}cu&kRJjYJxT0OPW@@#&a2 +zHz5rJ&>~S9PQ#0yOvBWKMPf;Oboqgr9G9K$m3C^vl22*amQRNg6mn_UCLzhELkT+r +zrr|V<9BdM47}6GrGz>%sCD37LBzbSs5@5)AMQACXt3AzzFdZZAg}UO2aHr +z8n#KKVWeP@kmS>$1h*4u*d~#N(=eLclCW;Y(=enNAwIf%#M;G@tevoW;@s<};WUgU +zw>+ccGx0W}h7n3}UlOj>ZgoYU}zKz|XQqOnN)_iOmiPd;($;x7?@_sO%L +zzO&nMqB&6N6Q#M;Zeb`~k=N`@#qk6l&qmNw@OXAe_?sq@n +ztKHshs96~>4O5g>228_t2GnkJE%}s&sR_o>g-34~+gD(u_UQ5>Uq1~4&?1qBDOHPv +zbt|5Rkq+aD<1o&| +zA<3sSjJ?yaO(G538&Voh!;6h#5TW+y^5w+Y35)MDdpQfWd|PRl1+qw_VQS7Ik%sAR +zi-aVfdpHgM@{QM@x_F5A%d;<($zCXt5i4Ji$$;l)NVh){cU +z`EugygvIxny_|(wzO6LO0$C)|Fg0h9NW*luMM9EKY1o!ehZ44YI+U>G(~}bDml5LB +zHWnEZXD9Te#D=An0n;$0YGuGQOwU^xFb$($Mu=0}Y4}7W(lDiDkx0Xo>ZwTl?GHcy +z+4)1nPo4es*T4BkkN)flqZRbFwg3D7wl?o{yOQM!o5YehiefVu0faZQc0#vz8&sBj +zy1kCkP)+zb)8(I6Kte!YW!peYYm{PSeU>c^*`wA9`-PS&Mm$>|E^zq5|6&N9YqSv?N +zQyON0(y&b;4I>4Mge0Gyz+`tw!#0UDoQBclmV|XHo`xaK2=US7%h)_S;dHOGQxj=8 +z4Wr2|i9VvUNu*(F&LXiZxntdXhcQQOobpBglZI(IjYMe}&7X$EFWz|lsq<%u|L4oI +zFK#_FUfkYIJ7qiVGG3vv{s!h2igmW6B`j+<)kxgd{t36}^X0Qh+!+NZ6B-ir9rU9} +zB)Yw0RV)&x*-ft~nlzk-NA+%;Vr@vv?{gBPrQzFHE%}s&Db+M=ld$Ad8pachY<#RJ +z5oS!BolqLyuuQ|0l0_m7)3g?eG>rW$5@{F$j1Z@`vB;P>H^GumX_y7Fmi@Ax>={DWA@U0hoqu5^0#GwMe94^k|Vt!w_JEIJJ#M#>BY^X&8VO2}?euVJh8{ +zPiYwGFhcx9@+l45^65~5Qcc4)i8PEJEfQ%M0*nx+w(;qhc-@3IzyAE~i-(9mID7T! +zXTG|0jkS#B3YL%Yx>Xv#tueE>edfGr3G1e&T!C@Q6*h@9j2RhSB7fgp~o)Fr*nFKDvAa{Kb;2ov?c1-0NHNDGl55>B9~x-O7L+N+2CZh*R4{ +zm@#p7g0&${zmc^+%Ib-8B+@XYWRWNh)3g?eG)&K1BqaItnX@gQ(y%R`(y%R`(lGjE +zggCX0MaIP038mo;ODhAWVM^7?fN7YXw=!TFM!$>@r?%7ZiAbbjO35OThACBxL>fkq +z7KtZ+gM~woSR_Dr!>q0S@O9@)9@?rKYaiBL&R@=|MKIn{OR&X;T1GSut-$U +zc57R^X}5RmqKtE!<+yzRWu3BZy2FxBxx$vuJ(?@7Xz4Tz6pKU}h5#eP>2ku{m^e2f +z4Fk|3Q5vRHEfSV|O2bHpan3E{^8J^UhD*b{<&lQB8&dz@MVo{rA8kV#MAoPkdTZud +zBz9YS#eT5%O|PD~>c=17)sjz#5_SgcP=ZP?4cjDc`{IN~JAcz@xHLSf_rjRghGgA} +zr(s(@+I@i~A8kWQ!w_Jk_6S=XZH|d^6D;|ZhFPFAY?CMr)AJSyNj{}v?45>f5@|RM +zqsc9a(y&cpNqltqfoXMIc8XVe|M}-0x%f-O-@N(SyALdCB@3Odyyk%nn>i-aVfZtraQbjoJSrw==9`ILsy +zFC)aMZ7eb-&Q2%|Z&+FxFbz|xRt8MN^t_b;(=hsFggCXGhEGHy4O2=Mi8M^9S|rji +zdbCKSVF)lnoZ7}BW8&NdOFpGx7RZuMX_!j4rD0n>rC~h52ytrriredP +z&8oT9eZji#e!%-bGL$NlbG@OPP`m&xo)HbBsU2;dmoZ_Dri6!x?)OXPPKiw>g&P_1o&| +zA<3t+VOu_>VfM*1d^!@pd;YmcF8&hnH*dc7?gLlK!P-qL=+iADuY`oQ5wbr;yd_bt +zut{90jsx#xb}s9bZPVRp7`a&_$`x!Q7Kt>Rh8G*fAVTfY<;#h)6BgfR_Hq_#`L-z-@K7RDEe|~b+L~9w#6)Yd)zEv6%XD4)fw`mD$H|_Qg<5;_Cw|De>8n#KK +zVF)lnoGxFTE5qq;G)zldBqaItnX@gQ(y%R`(y%R`4kgepBgCm~ +zEHWm}PUui#!_vxtX_!*AGGH2}=dBEwhS4u0#HsBxd?FHQm{PJxq+v?cB9VsCqeUVO +zLx2(D)HW6w6Xzya@+l3oK$d(;!&JH@pVBbWVT3rfeWZLk8wOw+wn?O6n${wbhS8%% +zA`L@;5#rP~78w)gCZu5iS|lv_+=FTOqn94M@BAU+7k~Khy^sEWb;VoD*zFz0si18V +z)^6JE9lI#w+-5m0-+x)3Id8fn4VNp>y+=I7w%MD{Ie@i~vhGfY{Bawz7z)0;aBFw5da>X`f$)`gJ7AOtdB+@YL +zZ;_DX(`U{YIStz+(r_9^lUov{VVlH~_~`NxYZpthcEak3bFZI<(=eLclIU#MCXt4z +zIg7-k1=q`Y)W*a$E9R!*G@OR_G>Ww$S@P*nf|X=k*7nizOv4)j*8eeH+mJexK=T#} +z>qImSBOS)$HMV#KYeQOopAojkkFa}zB2 +z^yrU$Q&KXwL8!)X{f*d)?0q%9I@7y^tCr?&Cwm^e3~Gz>tCM28ZT +zszt(*PlpmnhjGp=i<@K6U*ll +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 +zJEUQoL>f-RXmU%!`YoI^3~5G)k1j6_ +zL1~!X!6K1{kI?X+pM2uh#a|-+?vrOfeP>N`SbM7e_Yv`D03 +zTG}EpA(T0}rQuC?Sn??i+wv(5+wv(5qhCgdQ`!W68cxHzMPqG9Rt8MN^t_b; +z(=hsFgm@Z0F$qgPrC~}n4cjErFjBBcq+tj!LY&$@^1dJq1JELohACBxge9NSFw$W> +zv3zS)c}#rIit4Xbm_>z6B7Ad5t~g7ULS +zq+uG}A|c7=p2!u8M_ZN~#-=+g`E+{+e@i~y-r4f$!w&Sz2ytqg2s0+mPUs2DG`w3h +z)`paZXyT*`emH8?2VpI!)bW8s?zW_+w|M{HVI2U+J-cU9G-h&y88+iiQU#7 +z+sWd)U;Uo0{p$7q_2AdHJ{?Nf^0^n%@ZbLM^PinR +zMEum*Uw{3Ze=H93uMQs8ZdyTC(Cl_L32Qg)_KrNkxLi@T#W8Vqf_0-i{YKXQD61#V +zkx0Xol10M0sks+&#k!(T!}PpGV%<8h-O^DjmM;x&s9EwU4O5h9*d}4gr!s#{aP=W=rGGJ%Jw1SlZwGAl^(;XIxQ5$sOk(#uRXVNeW +zWRXb2w1Pz<4ci-%lmUAJ)0R(Z*p^Re*p^Re82vIroZ7}BW8&!zk$VaumnfqoewPHmSfPDCON +zQ%V+zG)$>lB&-aWhS4u$8kR^{@+l45@+l1?g*0rFkmS>c9d-sx!)X{f*d)?0q%9I@ +z7y^tCr?&Cwm^e3~Gz>tCgmo)k8m7`M`E)3ObQmFiBKeetZTXajDb+M=lSsqp(ISzC +zA;1W6Y8#)9iE|UI448&lpfqfgu;f!3MmmghZW)*FzpMw=Hr%eZHuE-&BNc@Wtqhok>3J&yreXBU2ytpV4WEca8m5#i +z5^0!HwMe94^k|Vt!w_JEIJJ#M#>BY^mV8RXERZFi(lC{7$)_}obQmE{Z67J0&V~V) +zhHVmQn5MNzq+#@Ekx0W3V1ziejYY=9xd~|)fEEc$KBZwQ-I7mf80j!V{6zA(`_u57 +zUw{7g#Y4m&oW1(=GhYp$*MqE};bW1gpdr8r@e{SSwVQUz#sZZqY!a4y$`we5@x=1E +z`*X$G-$+Trpt4A$;WWI^m-XDCwjrfq2rw>IbXa6eoSR_Dr!;KKr&Bg6y)|||7g9u$n*xL6-)=pSGktJF82GTGKWRWNhQ;8OdG)&K1BqaHCC}GQ|G;GVKG;GVK +zvtjhh2yto~i;Ri06H3DymR1H#!<4F(0n;!&Z)LzVjD8s*PHm^*6Ol;6l#)dv4O6NX +zi8PEJEfQ%M0*nx+wz0^VI5)wPPidG1vgC8ur{P!LfB63Mhlt<${^iGC`BRVn%>G$k +ztF=*=ElT} +z3GYAu+#?r%iTIm0Uwij~b=Ul#cf?<=VEGtVFUj@me0%k~z1yHFS5OlciE;%!X_2sY +z(=?2J8Pl*t!jez7ceZ>wWkU*S*d`&#r_Y@2448(~FmkX-q+v)~B+@Vh7$Ht=NLi|MXDGl55DGgJqY1k%_hS8%%A`L@;5#rP~J{=S1 +zCRiCT4YNRL*d}4gr!?6{ +zWK5i!V9BR6Y|G~^KO27G>(Af5c!v0cvsa&f=3i`?oIVfDltUukDT8cxG$c&8<9 +zC$}`b?GDC0obEt2`A=&@I{iC!Nu=R4oQC(DNMS`E)jn-1>;lCSje3rr|Wa +zJl257o{f9=X5f!6J$T>wQ^YU+@ZozO{eImw=Vq>;0cnw#TE?+ij(*_nVYb_4((T;_ +zO1F2^ghirULHAiCEcuixP%7hopN=*f*Q}bGhSTtFrKI8QhGd;BrC~NCOFr6$bf{%1 +zsl9TxNbI)u+}3dIo4)?P?*BorebN7D^68Y#&VW6ENzs>vZ4x(GZgJk#)oz}b3a +z{~a5WB_EB%f5np$zkB|D^t>&?EI-r?GMc>b6Ks +z2<5tky1c06iVc)BOru*Q$`y2v_&&3jvrx;om4;a$i$ofx +z<}4CvnC`YnNb)HS+w$p9!j?~m61IFg8%Dp35T~}W$e1`g!8#?Mej{stl+_dGNLU## +z4O6OC228_Lx|IRbFw$X!IJKRIPedXOQ%V+zG)$>lB+@W?v`D032rxpN+QuSd;(z|1 +z7ry=K#fyiCKRf&Q(Z~L|_+ubOB9VqERf|L#rqL}Dl6?Bi*_Kaf*p^Re*p^R+ +z66lu^;?y=4853tGbSSZ5X=T7POsQHKFb&i5Rt8MN=$8@V)OH#^5s5TRDOn`aFr{jd +zNWNNb(OAp?6{t)qtKYaM!M}MEGZEG33 +zy~8*av`xa=O}o8g7iFB=EXU>hFY7bsO?RZ>as`^)lK8LqUmPsn)3q&~hT&t8NW&0d +zg!oLIUNbihr{P6;q+x2pB4K5~G>je@m$iNEcE0F?E9Z{dxbnXq{M9s^h8N{$$wxb$ +zu`-}WA`Me>7Ky`!ICAgRN=?HX0{wp%sT7Mu8fI&@NLcdGHl#s>+8ePGpMq?1f<vyWodYW%92k{ +zN>GWGd`iRgyd|H~F#2VLIJJF~WpA92hSTtFRaqNS8m4J25@{GcS|o1v>5am@dcs|- +z;lDij#I1|JMEu<+&wl#OXo596m$i)L3d)d?#z9eQR_EHecX2`Qy`{a1nzfsDdq??M +zyJ@#~RC*e=NnELpA!)ul6+a>8G`yjfhAA40L>i_&EfQ%M5n3eDFa#JOPHkh6F>!8! +zC7;qT3uMWsG)$#i^65|l=`cc^+CEY~{nZ};reT{z8m4J25@{GcS|rji1Q;PsZDWx! +zac)8y2B1a4l22)vO1I=w8b&&d5I>Q8O2f8%I+UPP)38k<4WmbkL>h(wBgCm~d^#r1 +zO|UXx8fJmguuZ~}PiYwGFwVJUT)zLZo|M>hM;c}yvq+@jX$}AK+pk`{c!v11vyUHr +z?E5wStS@7^VtN_rtQ9)GnA@M5*rF;|*d%WIVr_9Qer;;sW#x);#i-tkqA6Ew_W|o~ +z-Dn9b4X5G7Mlp!2-47`Ky&J}M0^^Mn=O$S4DGgHq-QL+G(l9-5k&xumXU^OKr(v5! +z8cxG#a!bOx6;H#EW`y|Y@?~tEop8EW+Np^&oQBb4hY~*$i8Kspi^Q(vj&<)H#!SN- +z0@epp+J;mbMs5}f>sDMlCAZ|Gk&xump@f|QI~%s;qisliL`Qd6B+@Y5VUf5qz}}H% +zkN@YWjZ;Q!F9W9GG`uX;((tw>Ecuj%sX0c7v#}m6&(*K=w?F*+XXj55KXvxkU;pNR +z=iW%ScPx}eV)ZieMzA@zFZ<59tk#}>BR9U&?F7czAM}RT@52r%#Uf$trrqAr3YL7j +zy~7@i5MOKA(Olz|7O#+oH!LmrbbCjsreT{z8b)pwiJN_Tqj0aDkcQLnsNM@tSQ}Cr +zPQz$&OTv;*8iq6@#IN224*2RJ*DO~5s_$yar!;KKr$Y(K+sc3)N}vozh*R4f=#7c9 +z6RZts`i-ppQC3f!BawzFC5uF9n5MNzq+xpAA|c7ACopaKl!k5jl!k5jl!nnSBgCm~ +zEHWm}PACm;SXvn{4O6OC228{Byp;jdF#2VLIJKRIPedXOQ%V+zG)$?kCGqDcpSX4L +zmx#an!W6X?Vl3 +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 +zsVP@b^l8{8akEcv6z}t>iIOh +z>5dL12fkq7Ktl-dToF#x*PETJq^5IuwJwpvx5$+?GVS!X{ze)RZgO!x@*gy~l!AyYZ^8j@r2LzaIS6 +zG@ORh@SgUuHl#F6%~>S&t?1G6Ov4)jeb_-MStKm^Xg9jn*^)-Wl8;70l21=y+8MA@ +zHZo?XY&MBB%+_p?NW&0dggCX0PshZ$2^~rR&?1qBDOHPvC7;qT(qWu)%eZ|1W!8Pc +zHQ#bH{ED}CdF~Zo+W*sCzI@+YOFpGxTRt61P}6DHCNUwDIk~0bjVID@X_yUTOQN%3 +zn}j7FZ9^JFCM^rdy_Z=e#>TX$?Y(d0#&^1%ztEGv39W}YbUIpIQRN#I1Qu8EeY$l +zaI_7{%77Y)G)&D|BqlAmUe0NFL%=!_)i$KkFq*eWq+z0$MM9EKhZ1%M>}=SUkG3I| +zhUpHAgp~o)FdGu%=t6wAKKHV<(Z`!t7`1WqEA6~OhY~E1MZ(H}X_!K`GGH1;I*btC +zRnrk)wKk+<-qSF``0?-f0k8kBcTAl7rzM}#Fr}J?Z4zmip0`Ly^0_+>CI0q@pa1Oq +zDdMNj{`%|R{O>6OxV4Ps3JRH##z9eJ@-cCCLb+nYvRpwaStQC8G_6G<4P!rxL>h(w +zBgCm~EHWm}O|azC?Hvnb$){5`D&3M#X&C7+LY&$@Qa*Rb?cFJ$q+v?QB9Vq^T8l&) +z#sn6LGz@M(=l;wf|UW&FbkB1_mlYZlTX~b_)Em!ee&$5?@X5N)fHbsV+4yt +z1--wZ2mGsxbLCg9-L%^~7Km|fvmBT2zpMx0H{D^$r(9vnr&Bh%I}O_;(l7)VAx@VQ +z=ElUi327LB7Kzd@rD~B#!}PpGLXuA(cG&VM4cqc54cqeRPy+ojLY&&hB4gt0gbpP( +zEUgTfhACAm1Eyhm-pYV!82vIroZ3#qCnAxCDJ6?U8m3e&5@{GcS|rji1Q;PsZDWx! +zac+VopVBZ3WXY#AOr=}$DGehXMu=0}N6M$OVF0FKn?xF>X)O|I7(H4f(l7)VA^!jV +z@{QM@x_F5A%d;R_EH4?8A-?pK=A=ZIQ5c +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 +zijln+>0vdbdCxkflTzCg&_A!Z6isDIvip +zH*CYFO$i%5ZA#eiX>S<(GNL%S4Mj%aY=E^(K7Aqkew4if=ajHKU>GJ1QbshJk{mgan`NIot5b4cqX^4cqW(Qv&=lqByw?MMmIkK${XPEiDfi +zhDlY+1BPL0-tvH982mD#IJq5$PozW`CY3BD!Z4|7DG`RjqoqU`Mgc|?C%2)<2%HPB +z;FB9>f-LythRJjbKDl9_!-(SK_L1;uZx{i?u&qQGrf4lC!Z3KWlnBEpz=-1HHWV3w +za{*x(0WBpg_}sm2_?dry`_jcT#D72g^KX9p#uuYitK|{)Y~W4QsNTw&s^T^v0Gl+>x15Y +zrj5hGa2O858zphm#90l=f=?J`CK;Exeaqw?_TyDNy_q~yKZfBj9ENw)Oc-8Q2jdQ% +zriilvDyt!#{z_dX!f+T4!#h9{hF$pd=#LGbZqWg^ZqeCFbc>EQVkrTRc^_sJiflOC +znOAeeD=l-wq>`mX7^Y|~B`o;lhCwQ07?zZ<;FBA+;dA#sfl1>VReof3hhYS?l#t+a +z7jH^@_3=XwoIgc;{p`z^U;W34Zv|S@n6Ds_87UlKeKeX{-nG2j%qq)aS&N!{1yBgX +zwi00&1sGBML=DM;Ps=+dC=A<5gkhjyDIvk3INpb&;_CBiTYFrqkB4o^qmT!7^P!!Q$MdB8ACriWo$2?;*A +zVdx!(Z6(66-H^g?7+y4rp$NH0l`jKl0~YTydpHxdysR+H1X)UiVRFt=A`DaAmJ$+t +za>F)!+LW;2bJuQ4{PpRlu3dZ+@eiLp|M`0ZA?QVB9_U-FZdyV!K~^`tYZLm|l)Wv} +zt!~;qXXc6#|3Ypb37>og0)}B*i7-sjT1tdr@MtL!hEaeK#mQ|bG6LrU!Y~3_N?7p8 +z4U_2>d~(A;hY`h31fSfn4WBk8NYyZGD-njlqoqU`Mgc|?C%5702%HPBJYX1Rg2J$^ +zgax16FwkL~W6L;v_hEfW%BniTFn!EYA`FM&1&1v7XbmY0qX6S#Mh8Vk;9P(OpWLtw +zpZ12y^xUwm#L<}9MJKBv4MnIz%+{_8**9SCK&E8B3kbtZkflU!m`t>k2*cF8rGx~Z +zyY?2{GjG3j{o*0wZ_d8H_SkD8kCqZ)7zG$noZN;YBXBOjf=_Ok39{gm +z8z$2&_~eFx4kL<_+egCZuH9u@{7;{u)4}?LVN%IbA`FwYmJ(r@^0$--!zjRr;^a0I +z8G&;F7JPEUOppbi+%TDL!6!EibQn>b+&&UMxnTqh!?qG(n4-0m2*cpfQX&ka03(W% +z+fZZ#&IN>F1hkZ};FB9B(=GVqhJg+vik}ERxnUbVZAy@;VR%!CuReb0f%Aumub+MS +z@~i*qX2;op-H9QWuUJFw4A`AoX{)sJ6_kRdM7{zA7*QNpA6YXNeDW1ckOd#DA%$Uz +z%2LAmE1WP49vMd!9*M~?ybv%qOioxzSn$yrlH~z4CBiUxw3Gj6OQv$bbDPh4!Ye>0aa>7!=f=?KxAu$dMK$VZ( +z1v=O5t>Mzx%YS>|Nj(qP-Z1kUhHWJ*4;Y4l4&%X?8E0CY!D>j$_qi0Ui)*?x_VVA( +zoM|K0@_=F3hEHyoL=MBY5)yoR0uz%ShHWKs!*)Xo!(n*QD25{B9#y^!oDH~mpFe!~ +z_`~N95x?`}YfrxZ`^8(&o{_n`&&x}$#BXBk#42R*(qzS|8qO$I^hGFn!!AEOIVHgD%XZsDswWDKM@abj;j=}PP +z-RvNzbHlb0S5ah8iVGq6ud>TlLz=#jE3b4Nz&QIsuQ-1gCQ~dW!Z0;yDG`Q&f~CY& +z6bZvn!Po`N{zq~|BgSFEZd47bY$Cf7<> +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 +z__VyU;nVUC=rE!_|gan^_MZN+! +z*h=IpP})+$f=@R)z%L`XXGW==5jY#r&5o6pxnWYtQo@2yyKK~a7`BxN!zjRr;wNfI +z7JS;2V1mN1twb0G3YHQQeA<+-JzyBN;gcJ-;nSuB_+>Fc$ZkXz3ysgTQ +zrN_vPqtCQ)1`9s9VK8qk#kGbMhQsj4-c@TJikuccZAxHG!?3MH7`7XdwIixEq}(t$ +zVJWfcHIKExw{#z=A%)>E3?|n~7;gBhj~{yA{3+t=XJ5Yj>OU^3u!LSI&@LO8w3ILs +z`r@K3hn24&CoCl-__VyUyJ@>@bZZMfVc3R`){v}4O&BI87)KStyJJ^+QbTHa#{^kQ +zgkifOSspM9106;hA2UkrjKJ9dt07Ha$i5$C@4z`FEcoPxN!2iHD-njNc}ociK5a_S +z$HK6!L>LakU~;X5R$gS)k*#HlekKA@yT7!Jcf6MS;RC~d(f41-@r +z6dzSSczU3nJ>8i$E+7nt;V`^W5;rTgn;q-wVBDe8Es{qMU#Y7^7!Jc>cn3Yg +zunV6agty_--y;Dx>&BFJ_uYbzrbPFgX(N^r;F$Lzx1q?*1;pf!x#5+TxnWYtQX&jf +zw3ZSUe6)sS!ADaf45I+!Y`+FMieKvp~wiF4ag0zw9E~YN|qA2VT#sL!t#J& +z82mEMQg#&AIMd<`VK@wL=0q4?HzaFEGz`;_Ecj>*>1v*mJUfBAJ-||8v$S_Lf$i6H +z>8qFjcJ||sx3b{VriASQ+ms;bbHlb0H+gYFqMcuK7|sok?7bkS)sU>Eco??fqpb@p +z_-G9&45I)exrf?IlN+Wxgkf8W +zFdT-#Km_~eFj!@$8-A`GLnr9>D; +z0Y(%jx8dmsoC~l#U>IhCa>KR~7JS;206L6wY#E2|KCDfNRds}6`k19e7!Jb=4q5Qg +z8d4ZW0mj9Q4vLJxxd013xnUbV?G2OZxnWz0qcO9KPF6!2icp1^tz8$gZ@}JxOv!#1 +z5Qdo`ONrbtnP@2yhN*c=2?;*kqO;+X8@Az-8@A!o-Z1!OL~(K(ij2V7fV;#E|N8B> +zuAe_c{Ht%yzP|R@`1tvXbs|{Pn6IFs7*YKA(p#T_akg@=xBzQWldpii7JTv*l!CRW +z$yY!RMieKv?-yTj(>O^=gke(2QX&jfw3ZTK7*1G9NbqTw&4y2I*oIGT*oIGT82mD# +zIJpf)M&N9KwLLR^A^U!my#wczusmQGCRHsD7>3Do%L9gCpu>pbLB-mJ(qY1sGAB+=e0}a4x`tPi~kAvfz^&CetnW~r6a +zJT0MD3iJ=ZV3(zY^~L^LXN%KQ~v=%jCmWY)Ui^jEt6tc)jC +zA`FvCmJ(r@qP3I=!$84OLV`~iw&9Z-w&9Z-w&9Z-2EU9bPHsby5jY!=8(wK?dB8AC +zs#+c}3{&%#2MojDml4Iu?J#^ICBiVNWGNAbNmWaUFbp0oCBiTYFrqlQ4Mj%aT!00i +z+%OYl!6!FNrd#mI4FerU6eqWjgwNfwH~jjCk3W3=5b--dzV_tnf9cVm@dddgg0;7# +zmG*s}(6`jFq(r^~Hd;#LE8vi&M7{z}SV~Cnxm$b%^8Vk?EF~=Xw7j$7)AEk$u;A13 +z4*W8rIJu358G*9_*1BN&LiYVAdk4-b5r#=6O9{&ZhG8;24BJXb@W~C^@W~D17{aiv +zL>Laki$*aNA@|_jGH^Cv@jkPMGf~USvOHiIM(HqYD-njNZc7OXKDlAKLm0M|2*Y6* +zOsx=TVh7^Xwa2VbJLaQMy6+aPtdQt*b{dzRQ^9E0`cliF`%AVo`nh3Ub0yVyXD3^07`^Ov%0hdk4;) +z--1ueI~zXT>>$%y-q}h>@VPsdcf(?zm$alr7|soECYrXlq^%3Wa2Q_TaVWCL?cDI- +z-BPkSsd@qv0WBrE=S-?vN?1#AtsxCX$h{4Rc*Lug631K9yro2&5>$t!#OW}`m9BHbYDmlX +z3BxFUA|=AG-H>v_q^hNa1)nesei=^;pWLtwpWLtlpFh3w=!54^5x?})Cm($J$6Kpo +zydN_=YUrriX_u{CwnZvg-L&N$O6MzVC2l3>Nr@STR|>SeqYqn3gkf5DG!<*e9 +zH=G;J4Ug8gSsh_`T^)=&bix>Hs<+RpRzo`dmAXoV;V`@?9}7NhN}#j_pKf-5Uq%!k +zRoNW^MieKv!|)xhgase1Az9BIYD!q} +z(Udq<$__XH1xpDDK0W#ay>r915@DD=X(?gBCk%sMMsUxJQadAXHsEw;+PIeXhS@8z +zlxS0eq_>pF4O7yV5)ypwitnoWpBG4hBOqR3WwQ(r${y#U?~xXQGoHtiCWHYZkSBBlnBG*oTY>XpD+w`7*7nJ +z+^`Lw+^`Lw_J)B%7`BxN!zjRr;#4_29f5NJmIn;OOpxUP!!Vg1hHWJz_~eG6cNn&n +z2*Y+m3d3P|vr$-&fA>$DvHRB3vRXqrA%=hV?{8nac!>D#XMg_9Z~u2A_Xg}}D;vK( +z_|+1cM`SG}?&pNweC*g#qDOxye@h7oK6k}mc5H%HQo@2yzJlqq;Bz1QcndB9UHbi*)p_OmFl5BfGPWc%ga +z{_2*O_Mq&QZ)L$JH*CWvH%$JAVOt3aK5a_So5HZIgyjLlunnKwF!*IeaV!S4GXiG= +z+LTyn8HPzEONlT{(OOF6hM}LOL>NW^MieKvp~wiF3$WnRrUVmY!6!FNrd#mI4FerU +z6eqWjgio6i2pEQKCBiU8Ybgh|GG;qh6Hb5SR +z!*CehD2bbeVl^ZSK3YSP;M1mr4WIUgft%$4yF~{)bHlb0VHgD%QJgA=rz3DKAUBMF +zmJ(r@RJD`{!_>T`gan`5unnKwunnKPzzzTH>8Gw;d=v2xpFRKidqa^`?n$L>b<+~M +zgr?isN?6^rT{fV@xSUbi;s~4#u=X3LFJ#}3vUlK|5@DEBvXrnEHFtrpSd^!wL>NYC +zO9=@+E$?jjd~(A; +zhY`ie?IYpS-Y^1&VOxnXOwn3OgkkV#DG`QIfDy&XZ74DV=K{ho0$NH~@W~C6=@xu) +z!$5}-#ZLsEJKqgI^Y3q8x_E~8?`MDh&2N8PP}VB#5}HJ_l(=sbnr>&8w$)ABWrMvI +zeDW1GeDW3Gml4Iu?b|3d8_=UaD=ot?sbnb;hACQ03Cjb9Verd1OW9Fe<4lV)gyAr} +znG<1n-H@!W91FuVBnv)TL%N!$B+pLZZV#}O*evZ`OGne7`Bzj4O8=$5)yoJ!_Yen+e(DtFbpQwO5}!ZC6ArOrj48k +z!(kXqu9Z01ExNBhe&~Vor--kgefjdM{}`pWejmn-bR6k^@T( +zSK13D@)hKqrNmP4QRT-H^K@t0$cZoE}<}D>8_~eFd_~eFd_~eFd +z__Qejei>1m+=e0}a5li&o|(RoeLu?Hfpbb&9xx1(s+I=~!(_VU0mCrRVMK9qI}D#l +zi7-qmSxSUqQq@u-41-5Yi7<=;j3`cSLy-|U7hu6BH_QZC@W~C6=@xu)!$5}-#mVg> +z;d96D4gdA&r>|btxqvW? +zfR++rm{hftu;7y$20Dy$Y#E2|J}fu9styZ2xnUbVZAwtxVc1q845I)eic{s7xe+)Q +z5QY)ZQo{0pVVF!0!?qFlLhix4W#DYU;(cZhXQGyu +zWqH6bjM8D)Rw4{j-Ifv(d~(BdhcIj_alc~tnYZ7%e(@0TH)mg8d+fi+JnV>6+9fnf +zTT0xo3BCA#YB&1#w_`D2-D%BN;IJ5nr@bluaX%h;I0kT89Tt3A-l23Dww16JH9h(R +zbQpJ0WCYFzSPg0VLiUC8-hp#Ugkk!mr9>DG!;6}<;G;Dp2|n$z+3?8?+wkepAK;c7 +zwv`COD8Pu~R5?5yfpYLL&4BJYC;V=v)*GjZ0VJopz +zd{p^?Zgm`Xx-)I$L>LakU~;X5^*=JThGcm_O^Gl}&RI%qLT*5G1APa*8irR2oE@az +z9{O7iDK`w}EhWM*>1`VSW4WMdpE^D?#Ck!UzP-y6^3mkti7e&Fgb1QE#-!R4kLGzzseC#bRokEl_Oe$GQgkg%-QX&jP0!s-AK4I8~Pj1+TPj1+T +zPi`3eGNL%S4Mj%aY(RU%D=jS#7=}qz%LCrw82-bDk3W3=5b--dzV_tnzu!{FTV9$i +z;%yixp<$z?#C@93)HCw-=+8|htZv%!4kj{gOT(MlN+Y@g<)HX +zFdT*#jbbQ5?!mid;B3I+eP$15qL!CsdB8A?(qY(EA`DaAmJ$+t?rb;w>$l&!e*O&c +zuf93^`r2b7i*EtCRod1xcC&*-W~6XH)Gd>H*pKb9t+dQnkUy3Z7JS-e0}5f-Rw4|e +z03(W@s3BSKX?e#4g<)HXFbotdB_#OV*~`1FJ93f|VK_GoCf7>zAiS-FwGoTbFB8NFq45Bo6;uN1KU7*cCUZAyT7 +zO9^W!9)^Jqnc$Nf +zM(HqYD{*Q}hG8(-ro_*r#3^pk-T3Z{cP}0y{^;zDXP^6aWbrK?;V|2s^zeTB2?jFmv{SNTV6u^W8SLe +z9TQ|JVZkR1lm8Zcw1#BCM^i$APfuXl@W~C+9K*1!L>RUkQW!=7MieKv;pqsR3$Q$3 +z7-oXPu&qQGrsgdrB>3cpp?4Uzl?cOO7)-8}Xj8&gVyXD3@&n!KIP7$1+Q^A89EQQ< +zT8VDa*-C_Aa?Vm>6LJHh8|XXe)sY*A9lq#5+_LL(Kv=#Ij_PKeCBPcwY(#%EG4?xK_Xj9LakU~;X5wGnTc;e!lh`+z_=KGIqPyQ0Rgx2EZzYJpkOJn6&<&| +zJM%p8sSY`2kMp<7hR3v&xF45yXu8>PEhTcp6uPB^1fL%Lp-?RN^aLi&*Mg6>F31g2 +z9hMT72MohBB*syN@NUx>%)dHv!6!Ft!zVXP(uZMN2?;)JO4uGS42NOhU@H-ZQQA@>45I)eij&*$ +zbOg=?Qq@wzf=`jc1?x50KdW +zNG0^Tw5@5>O8fpx=yBVGIa@bA#@#hKI^<^ZZ!Za6wYq7`J7&^?PrGcCLcYRQ;xM-C +z!6B<54MnIzc(=zjT^f7&Z<&YbcMZc#kflTzCMhi?!Z77;DIvk9n;kZMa>F)!a>F)! +z+GPX3j3`cSLy-|U8;~1bX=!=DFifgi9xx13^Ogq;!{C<@#mVh3d?F>nFsWoI5r#=s +zONlTH9xWxpFbXiDIJpf)M&Mk41)tn76J)_BH%z8m@W~AW9Yz!D;0Y(%jx1q=goC^rU2xuu`!RHQk!+(0^(Ff0;B7W(oPd@nck2^B5 +zgkCAocVNOUO9|_{ZnV<2x~Zmwb*EKRLV{1rJG+~<%ZBm04}HbRu1&LRDG`Qg&6X0o +zW)zBS&hx~pRzn(!P=yoMbZPA6zhxe#-_=^wgkh$_f=_Okq_^Oc8wNUzC{Au44Yx47 +z(lQK_N|q8~n4-0m2*cpfQX&ka03(W%+fZZ#&IMTT$qh3>7JPEUWV!{P+%V8#L~(Na +zNcgljjDTU-Rw4{jw3ZTK7(7}^gkcn5L~(K(ij2UyfG~`JmJ$|xa>Hc01)tn7&|yUJ +z6Tv4pY{REb2~sr-+e(CC@MtM<-(mQFUVPz+i*F+S{>Gc{KeFrNTcvGHW4?l!WTbFF +z6m4+?&IWYPd8MVbsL5B5sup}&-cj>m*j6G8qW~j{Q{_iCq%e$tmJ(r@RJD`{!$84O +zLV{1bY&Lvy!!~?!!!~@{lmNesC{Auekr6l>(5A#nOUna>VN%udfMJ-Lw>)4N2EU9b +zPHuJyOr9^I+nzWR# +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 +zu;8OLq@l=#d(&6!^Qj~y +zEcmp%V^YJgt%T(P!!Xcc48xKVVVKpFr9>DG!wY;_OL46sN$}~OvkjlzunnI!C4gIQ +z*j6G8qW~j{Q|0h<1kMFm9xx0uLAhaDi7-sfTS`dq$qhsAFl;LkhQlzJTr1J0gssF< +z@loXmy47*m>CUu~6JaMOLEG0G}Hz2x!zJp#JxpCOxyABJ(VfYjn +z{@uU7ed*#M;=iB$`8U7)-^Ig#+cLg{UMbL55tAO468Q=sXDMNI({|Zt+>A?DQ#&JY +zHelq&(P!E?L%t$ku}De_KH7exwZ*R~5r)Y*ONmX$ZL_r-6x=@`4CjVN_FnXk-0-@5 +z!mzD`1fT9XQ_{I%TZ!&DV}Jxkr^R17`yk?=yQi6ScgoFw6v5N?7p8 +z4U^Mh*j7SLaki$*aNA@|_jGH^Cv@jkPMGf~USvOHiIM(HqY +zD-njNZc7OXKDlAKLm0M|2*Y6*Os1m+=e0}a5f+}ywcM0fMJ+a%?;a1D; +z0Y(%jw~uT{VHg1|CBiVNYAIpCCpQdq7*7nJHYIHM3F8Fl;L!!6!Eiy~D7rL>RUkQWy@yi$*aNA@`{AW#DYU;(cZh +zXQGyu6^5B0ONsje!+(4FscRSCMEt{N&wu{jZCSQ0`Ag`P0@hcKmC%%S-+^f>VLkAo +zIjo_`Rx};)s-?s+*Tn2^{j8V&cKb1VylQpRcG+-n_l2+6nzGAREhSpsp|quh1fO=< +z>_tr&4#U8~R>Fdhwl1(dpr%9^MghiUZo|_NI2Vu`MnFpm%L8iLGi^$c6P6NTnAU75 +zF-gJw;W=_+;+Q>RE%@YyZ4VfRN$=dSt%L-hHYIEi7>2_zaIlpK!zgVj5r$EK5yi=E +zcsc^-0&>F$XerUA1gUB%VZoC{Av} +z(-AlqkQ+uoONlT{s#;1|@W~AW9mYAfjKg;yW~~b@dCO7odtBb_v0Gl+{poH$d{?Xm +zpWLtwpF8P+wXZ&Y=z;U6h_9c0`SPp(7(0KLrs3tk-IcFb)=mkXub}kSN?3bK`3jV_ +zx~b-{B>1$;X2U060o<%b&7I^c_HzN25-so0-%=tBqW~j{Q|0h<1kMHIh7r(G!h%m2 +zCetnWXzPO9F!-{R7`bsGOb)t+;gtgYeTC=5u1s|;;4MoVk@x=L&oU@b& +z!zjRb&gczeU7YMT4 +zhGfA{gkf^dQsUH@48vfuz2Topi7<@PmJ$|xa>L-4 +z5!^GQP-FxW@YkoGx_0qR#6NuY{O9lOdAPOEZF$E;SxQ`;5Laf*_5iE2ha$J9?)D4W +z_tm`vnUei3pyeIi+ET)Tk9OO~>ZY0!7JM`%Ecj?jNbu=FcpE<5?4S*XVOxnXjPZww18plN$y)jB{)mhwnbjS{GdMmd6qE$isIj5r*kw +zmJ(q&3@@tBf{)gaB>1!`VZ$dkY{RF$Vc?bLL&4BJYC;V=v)*GjZ0VJopzd{p^?Zgm`Xx-)I$L>LakU~;X*^aE?p +zy#3boi-(B6Is5wBWB*0ak-8fRH(o8FR|@oX6Xb-Y#B@U6_Lw}S!IiE9EQe(+YBVMC +z6+qNdVh2Q*8M!BWZ#isNZqJ|TmXmtlb<-}J4WBSfB8OpH2?;*!vO({bceWCi2MohD +zd~(C!ml4IW7}U-PoDIkgue1!qq>`mX7^Y|~C33^i&r%``qW~j{liN^a1kMFm@M%+m +z39{gm8z$2&_~eFx4kL<_+egBuO$h`H!?qG(n4-0m2*cpfQX&ka03(W%+fZZ#&IN>F +z1hkZ};FB9B(=GVqhJg+vik}ERxnUbVZAy@;Vc1q841-5YiF+QyUw!=01LqGBUqAcu +zUOu2K!*{< +z$?c=zW;LYKUuhWLn04!~aI}Wh@{XdllnBG%(NY2k@jlFG7(S5_xnWYtQo@3d){y$M +zP;$aj!t#J&m`1^PDoonz0t-HEO3)|6u&spU0mCp2i7_`UDG`Qq!(ei)gyjLXh7^Xu +zqosrdpC0|O;gcH%ZnwF64s5WFpScSC_bt@Hw^ENQ=;#xLO@H2{w$PKwUh|M +z;L%cI4#U5G`>pHe&k+CWo3pR4J;t?>1=QPM{0OidmbIuUp_x?1OD6ZQc6DbY^zM|s +z?Ndogw7f%UO9=};`3lM>4BJXb@M)LLhEF#;u!CXPRw4|C;YFhuijaHoZW%Zmuy~)@ +z!6a$d&4$-v~_{? +z+@aQxtQ}EJ2@5`&5<4I|EX*#-UKwC1v21)-UdX-ydj~E$?-l0{!?|G^##)Iv4Bz|Au5OYQiu%!ML;-hq~2aa;1h8hAAIQi7<@Ywv@0uU>F8EjK^baaR#d) +zE#GHU`S?hS3)wed@4&h9Tkz>-hYg?HFqs~PZ6zf5v?*bGz%U$!frG6?7)EJJi7<=; +zj3`cS!_yHs7myo9KuZa0DV`f9(=GV4DFJjCQT#;k$qn1^$qkdLVc1q841-5Yi7<=; +zj3`cS!_yHs7hrk7Fw6vnVOt3cKDl9_!#Ky5aro}T?uc7-uYdUX!{-kXzw_g3Prm+_ +ziKi>9(k`LN7)yzJJE2hz@LuK-Bqj0{h;Aui!KYm|%Ey9Fz5?hlqWC_*+AH>s@D+Pq +z>6#OaGso-^Yr&`G9jO|IZ6(4mg>ES!!Ka%Ywg(KuHhgl!Hhgl!;Fl4_$!#by0%rqq +z!z(Rw!=#d>L~fX(wUn?tU>F9!jI)#-#Wl{fI71i?!<#t~hSv>g?puGlMYqVKUBp3N +zaVf4fq+2ikmd|ngk6}0rhvBWr2*cpTQo@2y7^b8d$4YF*E?gEna$|e#9Qvx|0oxnK +zC0R@H_J&FNHYIE&B=~fT4&sMlTZwxc!ymr*!V?$YMEw1YH{X8*9MFQ$cAM*#O1p$c +zbW4eQJE2i;Tgooe+fpK5fzp-|5`6L%l#d0UmUr}43qCFHZ1}Xx27Vb)oZN;YBXBmr +z+Hah`kbOVO-hp#Ugke(2QX&jfw3ZT<2MohNhjETAwh2d3oSn$aW+wjQ^Q{7?M +zRw4|e03(W1<(RnUZ&VOxnX9EKN-VkkoH +z!MkPPY{24uW)EkgmX~FDz%Y!`Vc1q83{%~f5)yoJ!*qu*Y%39l!!Vd!D`DN33d1PP +zh~lHlZ+FAL`|gW(FP$AQZ_N~| +zv`>Gf>+5Gcu@did+=@< +zI2*8dpV`BisO4o@9xx1}bQrdk2*XsjrGx~Z+%VlC4BJYC;V=v)*GgDBqG1@N8Bu&x +zd2Sfq9jC6J$xJb#M#rJp|e;L|@&MAA6rUHp>y&$JO>!Kb}pO1e!6TM5ephGC$? +zxPgxG+aq4J8qzV>bSaT9|Lws_gyHsv!DMduXHvp~kJgYR`1ByW4WHaFC7m0#mBIKg!;L +zb4s+lBb6*AEco>351Af@Z6zf5w7j$7)AA0-5Qc3f!f+T~G>V}Jxd-o-fwKXN_nAGM +ziCSKk&Q +z_N9x5i2r`}=imJHf5*<;@{C){^s3A}u(V6)68hkTp3FIGp_{J&8I}?fe7fgs!>8pP +zaI@gk^3I0Ogu|L^NY2_zaIlpK!zgVj +z5r$EK5yi=Ecsc^-0&>F$XenVW#dE`Cx&@y$C4deiik}ERxnUbVxnWW@4BJYCVen`v +z5r$EK5yi=Ecsc^-0xS<0hMAx+Y%5{GCpQdq80XkB4&Qy)FMf;e(^npS@cbd-mwx)> +zgHQjt#}(fST&uK8Xfno9Vq+SQY@r)T^NT0+pzWTYN>U3cbQli9n^|Qwq%a(Y7x=Q^qcxr915?j$RyfW`j#!qZjgyG!q +zX8u?WDK|`cT1tdrKxiouhEaeK#mVi7*0U|vf=_Ok39{gm8>SR2__Q|+G8j>u+&&UM +zJqVA0Vc1q83{$k05@8rTT1tdr6ktSgavO?_z`1}hjDVIB7JPnrH~hD!pSpJOO~gNZ +z_WbAX&1Pf?y;7im_yxNxCHDVr?MaAQrEPUnO$lp@UsFPYPs=;Io3_h_@w4C)hG|G) +z*j6G8qW~j{Q|0h<1kMFmi<&UZ1chN+i7-sfTS`dq$qhsAFl;LkhQlzJTr1J0gssF< +z@loXmy47*m>CUu~6Ja##5!hQsiV +z>aZG;1)nx0m`TQEZXXTLFuYR0dOkpFNNq}hc}odvM>Grr9meA^wm5^;ke2T=%+~lw +ziwoH|VDG@W^XG3qey +zU`l9PiOIIUzuS;XJ71Bn_?fzC7)I$ZY%39lQGgM}2k-W8J=<2Q?Xn@DrG&M`ABHJ~ +zFl;Na6&(Xjy!!!2I^>v9vAZuIH=G+@q(>MgCoCnxFga%_u@CwVvV$Wx4m*6;VPQB7 +zhv6O75r)^*!MH=G!;ut*SJfAW!*Ceh0g^Brh8NX=B0DnX(1sL-!*CehQ9fZf3@@q! +zMRsIN7#=)5XwRny;fH`0e7Z$PNn1n@2|mC0AJ|d*J5%aj*rxg+pOD +zH$1ZUf|yoA$_?8MDGZ05)9-kV56l(%RAD~Qo@2y +zz5?hl?g5l>%wDm-tgjfgzyC!aa?Bn|Snz3iXTzuE9qAp0Z6zf5^dP+L0mE<@1`f6o +zVHl+?CBiTYFrqlQ4NphlTtIFZ0WBr0rFd?bOt;|ErUcMoMDY{BCpT=vCpS#0hGAQY +zFbp0oCBiTYFrqlQ4NphlT!7^P!!Q#RhHWJ*_~eFx4&xkK#^JjU>lWRrI>Io0%u*r@ +zhv5Z>Ecj>*DGZ|k<6=e!MMmIUfCZo2unnJIcyIWbx8J&c@euJhXJ21??7uX#{nPO1 +z)ZPA8B{WlEDUq+ROS|PAP0Uh4f=@R)Z206WZ20`bzGCrL;@g}2=Brjivf$G$8~9}e +z_lL|r#2F_&Kbf`AJ^hugub=V6N?0B+43nxBe8MoL5Qc3fB>043dQ%v-l?cOjLkh!T +zc+n_^BIF)bz6_iVSiH~d;Y`%>vcfPEWGNAb$vI1jFidq@N=Wd@4cqW(Q^JN%n-VsB +z+8YMHj3`cSLy-|U8_?eHN=wTFhGA0G@_=EOnzuY)7zV$LC{AvN;S(tlhDjw$i7-s6 +zT1tdr@MtMc4vQ=gwQyl+ctmwy_eC^5C +ze}71s9&!x0p~W$Gx7eK$8c{4I?#+b0B&BZ2uFW4UCGr&%x}}5!pL~T4pO$xk%7V`? +z>nr$lRW +zhR9*qRw4}B4JizV;YFhuijaF$`7&@eVDUb)hci*j%L>CxkflTzCg&_A!Z6isDIvip +zH*CYFO$i%5ZA#eiX>S<(GNL%S4Mj%aY=E^(K7Aqkew4if=ajHKU>GJZUF4;E)BMmUkqw)lFO80UbsZ +zC%5M@wm5^;ke2Ur{FScHz_|Dv$DTh7lS-BnVVI(|lnBE>!BXOA%nYD&rSiI9`97n{ +zcU{Q70ec57KIj$ax8Rc-w&9Z-CetnW!KVk|Z4VfRZTRGdZTPe)0e%@#oZN;Y +zBXBmLO^KD3xnWYtQX)4@(OODa9xx1pU&dL=j^Y|;TAU#ahvChf2*c}!w8uZ@xbfW= +z?_NAa{L$GP&p!945I)eij&*$bOg=?$_nnLA3px@`9s9-{P^0Fum9zsJFO)&rEM*0N@z-( +z5yeN_8deDgKwJ9S6#=I^)5Zl@-L&N$^J{g}mUkqw)lFO80UbsZC%5-x*Y3lthIGkW +z9(U149==P7Fia|0N`zsG)>0x2Q{9#l5`4PnY{MrvY{MrvY{Mrv41O6=oZN;YBXBk# +zH@wo)@_=EORJA-{7^dbe4;Y5QFC&VR+hO=bN`zrj$x0x2gGWn=FpL6> +zC{Auekr6l-5QY)ZQo@4IFX)CpeDQ@RF20HQ`x|e*|HxdzjXW)(R|=dBMGh2l*I^~} +zy0rKBZtcS!Ft$qD>ZY0!)}2;O2?;(e@2DgTKJBt${4Drr4Jiy$9hMSdnCh^U*lD(o +zHE|<1jy}`I8N#sLkixLtkaEM6w55aupWLtwpWLtwpWLtwpWHC`Wkhju8;Xp;*?`>e +zO3U0ZsbndU8>VP2B`gmZhQTl6EM-S=jWaFI5Qf9>W=@3RbwjdtM8hx*$%2p8kgnz_ +z$+Hu<+XE~mHcNX~6WD%Dm%e)WZ)ZRLcqGEuQbK}HyKFXma>F)!a>F)!a>L-45yi=EC^7f-Lyt +zhRJjbKDl9_!-(SK_L1;uZx{i?u&qQGrf4lC!Z3KWlnBEpz=-1HHWV3wa{*x(0WBpg +z`22Ei_)o7q`r!Ff#4r8y$p@eQaWdgXo|e!n1^Oyta>7!gzjFq1mJ-&T)_etYWjs~i +z55x5RF#IzqVZldpSk|IOQz8t5M@xw?i~@`(zNE+qoC~l#V9PruC=A<5Sn$yr(oh65 +zbYSt`c9^Av1fS0=C9J)r?m3fl_ueiWl$xzcONrbtQ(-A_@RTnWaA9~y&4ghx#Ztn8 +zkG3wz4U-d=5|#%H!!#tuVTP#kvB|p&h*t!R+_)-mF2I6MZkW~|hHWJ*4;Y4l4&xkK +z#^JjUvl`MRZ+RS%k34*r5@DD=X(*NrF!g!rSo44cqW(Qv$fidsO){a5iA^KC_22QOnB;!%UE+ +zL>MOLEG5D))om#u!6!Ft!>3IN8$NAH*zoDmAMneF;^a0I8G*9_*4_8%3)%Oh>>W6# +zgyjLlFsW*Jz%WdvTOKeB106;bC%41!iIfP#q>`mX7$#LMCBiUxw3Gq{22(#}`V?=2-H_~a{W__VwOZugq67@nWn=Yx_`I|D2w +zEcj>*$-2|3DG`QIfN?tcFRzZ=F#1?ZSnz3=jZz51wh|J2a>F)!a>JO!Fl;LkhQsip +zQ4B@MJ$SbaoDEpK&+Oq$)bg?{4;Y3~It<%Ngkh@NQbK}HZkX;6hHWLna2N)YYbDwn +zwv|{aKB_!74DXIpqJL9|fR++HDM6}QN`&DsyxAyn!*mBriQI5*c(l${^@U+_!ctSZl(!II`ir;lhB7;>H1SK +zo>&R1n|8Cq?xrp8D1|U=D}Yi +z&{D!$isy#ObPGOhN&p>36h9Gsa>F)!a>Jx*7`BxN!{E_UA`GJdBZ`yT@N@*u1y~+1 +z3^PGt*jB=VPi`3KFwU`M9KQRoZqco(BMj5WEG5El7+!G5f{)ga!Y~RjE@pI4WCYFy +zSn$aW+wf^`m`u+N+e#dbnO$_U8q!dND#UEH?x5@9$DZ#IfHCFqlu5|#%H!!)EeC2S=|W5NO~D6+qs +zT%5sbNXz#bRetc5uFt@@_#DTc--1t@5~OMvwv`COK*3VtXw2-QUl?9hM;OixgUPiL +z)>2$+NEUoFB`o-8N`zq)V5IRaYG-G^p}2MggyAr}NTo1LPFPBWVRFt=;xbG=^Y3q8 +zx_E~8?`MDh&2N9)0mcE|UF5uxuh6G4UqSjYQaB)LuROguQMdoN<)!0K+M_==Wwjhu +zyKMLtONo|ukib&nW|iDhFsJzOm+%#rQ5GRd+1p|zB`o-KvxAwm;L|;4YQ}<3%R8XM +zh~nh-ZIqe~2*WEa!!W62DG`P#T1$yA4E-!6!Y~RjqByw?MMmIUfCZo2FcW0KCpS!{ +zTky#Z106;bC%2D;Pu~cSfMM8HA`DZsmJ(qYJX%VGVH99QadI1qjKH~oFpPkf5*B=N +z!(_SzpWHCeVMOs0!6!Ft!>3INQZ)?QN`ztXXekkfQGgM}$!&N#0_OrO4;Y4-pnD6$ +zUw!=01Lsc>UqAcuZ|%H2 +z`m<_$`3lm*Qo@3d){v|}E7Oz+!{E_UA`GJdBZ{+nfFdJsF2I6M%R4404BJXr@X;EQ +zC(?(8&;V=v)*GjZ0VJl(5 +zCpQe-7?-(ylcxv%ICA6YGi{t942R(`yipRv`DhI(43l$~61!&fmdQQr$1uE7peH5B +zA4`ecFs<2A!h%n382mDVduEi{8G*9_r#sWewd96#!;7S};G^x5cZ-gawv>?I^NZY~ +z`|HzBUAy=u;vYVH{`2>Sbc-U`i`Uj|A8Q)5(#}_qKb8_lrSxV%FDOyVj%L9gC@XI($*->2MOp7yw +z;V`_J6JdDWkhb8`S;FBAsJA`3di7*_7!Q@&A +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 +zaLpMUe) +zACJcIh2qw2A8Q)5(#}@^QA>$Y;tNid+=@9Od +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 +z4YQRX!AEJB4IiaprD4E?gY!{ +z*gYIK%6eI>MU8R=lxD$4xdNURhS^Gx;G^Xox`QyxRzetNHzZ+L7`8MDqX@i*Dz{Fw +zJHhffb`QsmvR;-jj2pyKLKueUSV{=PsBV@LB={%|v*Dvn2{wGRDZz%19{mA+F+y>8 +z8x%1U?M`6*`fmF|T>UC8Pqe25D+3C{uqrD93d3+ZD+3C{fDT3|4sQ#?UQ$9BhLu=K +z2*a={O9^2Zcw{Ld3_}5oP#oR{Ma)Ed6Ik$38paJ`!AEHrPG`YKX&BJK2*u%T58UMKgibkY3s!JKPo0 +zss1b_^qVv86-$ZeYRBmDEZJq20*@<%&?qu@*J7(sp)7wY)>y@=yuo3JAzjf(0Mt3U)Wu@(%dL +z2*tewA9k)lX`Aoi`Sp{OV8KVrJ6Kg1W-FoP9q__Zf&?F77>z<0W-B2K3&X%ZaOdLoidW +zU@P&m<_eTH@)2}$JId3PV8MshkXVZvni9e=6u{`^>JWy37nTyjFhI^yLKp@VSW1xK +zqcqHhk2WRP@X@9O8$L?Iz%NE94sU}ZW}@8*taX9y3vu8uPW3|VK|)yAEjYH2O|`Rw>^Z9_J$##Fw9m$7)H^uln{o2N0t&VCx(B^kUl}kUm||w +zUt~*vBNFV0!Z*zZD!M#Dh7OgAwZ$((!;~1IxEI{(@W1!Y6rp^SD}Wc45-j*=c?To2 +zx~Z0TfDT3|?sDfvahWq&&cJF&*3XIdLR_8T@P7KVjkCzZr%NG$j$4dYH?w0hfPcnZS~1z3Nf +ziPn&`DFMv0lwj?M3d4X7M$a*3IRmR9SwF{wE%TKu7vky!mnYggztXVMFfgf2iT_9m +z7JO(8i3A`0M8}4Yo|HgIvoauUT@bPq&*R<6Lk +zVkz-*8rtkvn8Jik?t7Z0gqC;U1WO4Le3UCtR4n)?SAb+J_;7QDFzl~gHq&v1VJLtR +zjn7MkA`G(|k}wRbvXo$DK>gSO=wS3Re3XXS@KG9O!$)ZtP!NXMN(jSH03#Gfm4l~d +zqP+=9!w`_A1Sq;b46~IGhJ|5ZGE@mY2+vj`Sn+__v10~5 +zM4Tz;NX7a$_2`ct{RvwODOW%NjN!!b#!KZ2zRvNYxl`srX +zu#{lIM;HckF^gtz5xYf&?G!vauI6!muz5IIxuvhM_b| +z31JutV1(lEHh5|#+MA#>3;|h6u=bXehT(J;e6-63=wO86UV@L(FdIHf!?3C_%vM4e +z1|C^T2*XeSBNT_X!BaEQ-UL<#6ozqwgkiQ4Echr513DP(vBezj{4o9I?5GZ57=4VT +zgfJ`&TR6mm53L~y!%zUD<&GMPn2Gi#u;8OK%!ZHlhT(LjVYU(;W5yYsSPjW2f+|GV +za&{rEPH=f5Zi#CbAPnOMv6N66h7(yz2*ap(mJ%fRFn^*;?As|*@H50QE(9G*kkEJ# +z)$S>dLll>xLra_0O=W15HbyA!H6wfPOn^{`Cs^H7%R6>A)$$HTW_45j*a7HZgyQhF +z$6cD$ki37Tq2Cpwmz5BPVI`IltPCg&qZEW;wh|=xFqe1US-=4f?1sdGkJ2y_gD}ii +zLKp^gSV{=PPyizohqoi~+TH|V7y`1C5Qbq@mJ%%ZXj1~v!Dx>y=5XhSX;Z>c9W3}L +z4YT2+O$k)DFw9m$7={8Ep*X4>Va`mnH$fPNfGj0g8BiF8(}iKS5+wL&ZWrG#TMLgkjV?O9>Kul!n>x(JmVs +zK1#!E_$UnnzZju7ybX$&iFPNj)&;gN#MQ6j@?I|HVOWW!gfI-NvXl^pfk&1S!Y~xT2*u%TP{d5MH-QBorD5D47JQV3;dB;! +zl!gHvj8Gij_7FbW8-{?wFk1;>7)8rcLKp@fSxUTo7;fU1C{FN0#C@MOO50?!p1^b{ +zzZV%Wp^{kLR2T+yFhX&g>~ek> +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 +zKw%ir!RQU*n3D#djMb35f2EajSgw& +z{H$)OPX=v6K*op#Vk?Zxl)b24KO5wk}W_M$xjAP#Q*cu#|{Yg{I2Q&2=ws +z3d0TowJ8Dru#{lIht`l-8IYy~3qCX@Sn#1KAq+zSjA(pbYDg^jXm1!dNEl`-Aq)cw +zEG0EaHsl%Nok1&;rh4iqqvzC+ +z>0mC@TjaS>yyd)HBOmT;t_-bQfzk_ALO*t}m0)#KTEa4lxW_K%hq07+&PU?ry7yH) +zJlxr*3d6#%Fzlo{SPh8!muzb3_B?wVOSWp +zR0kAs;uvAr@YJn6AN`ROBOnVt`iTxD&031a!@{to +zI-rOX#|XoQr)B|RPZU-|V*QZ?JqVBct3NlvR>I@ra#oY9?HQwpC1Ng_NOdU~b^=9i&ygIG$i7ByZsG?Y-TU@O7urpgt78%AN6qy+0PKMKQa +z_|O`XcG-}uSV|agcsB#;H)nPR)bj47Ti(GFO2cd=l!j3qEG0~1LKT8{o^B-=Z+LvB +z2xnj|#f4!QK${Y5C0H4d){t26p(#OvkJ2!@gD}iiLKqf?BP1Ule1u^rjnQ}yRjxGb +z9VN6k3@fpe(53{e%2GmU7Y-Im+PXy0^aZ@Nj3J%Ic>2%^3zzu3#&nT!HFlDM5k{?`I#Q +z2)u{YgMRGrjuP5sgOylHureU6A+g{?Q-YNNX-WvgPynN;!bls3ZgEa&7~O%Tgwimq +z%2GlY1{7FIxW^X5E?gdrfRa-hh7v6JXj1~7W5Gvh7}d>!kJ2#kixG;$+n|VUC8Pqe3mFbpfPln{ndv@9irVbnZJ2@-sihS~5@8fL>sX_yTkrD5O~BNT_X +zK@l_2?gXV_hnB1iC=A1@tPCg&qvlx|P#6Y&F+y>8TNw6|62dU7#8TpA!EnIr*fE12 +zBF+?aq+